Skip to content

Commit a440dec

Browse files
committed
Scope provider icons and extract Modal lifecycle backend
1 parent 603c1b9 commit a440dec

80 files changed

Lines changed: 1639 additions & 746 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

‎apps/app/.ladle/story-fixtures.ts‎

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -104,8 +104,10 @@ export function makeAttachmentsConfig(
104104
}
105105

106106
function storyProviderIcon(providerId: string, glyph: string) {
107-
return getProviderIconInfo(providerId, { logoUrl: null, icon: { glyph } })
108-
?.icon;
107+
return getProviderIconInfo("agent", providerId, {
108+
logoUrl: null,
109+
icon: { glyph },
110+
})?.icon;
109111
}
110112

111113
function makeStoryProvider(
@@ -327,6 +329,7 @@ export const STORY_ENVIRONMENT_PROVIDERS: readonly SystemEnvironmentProvider[] =
327329
machineProviderId: null,
328330
id: "project-checkout",
329331
displayName: "Project checkout",
332+
description: "Work in this project checkout.",
330333
icon: "Laptop",
331334
logoUrl: null,
332335
pluginId: "environment-project-checkout",
@@ -345,6 +348,7 @@ export const STORY_ENVIRONMENT_PROVIDERS: readonly SystemEnvironmentProvider[] =
345348
machineProviderId: null,
346349
id: "git-worktree",
347350
displayName: "Worktree",
351+
description: "Create an isolated Git worktree.",
348352
icon: "GitBranch",
349353
logoUrl: null,
350354
pluginId: "environment-git-worktree",
@@ -363,6 +367,7 @@ export const STORY_ENVIRONMENT_PROVIDERS: readonly SystemEnvironmentProvider[] =
363367
machineProviderId: null,
364368
id: "personal-workspace",
365369
displayName: "Personal workspace",
370+
description: "Create a personal directory without a project.",
366371
icon: "Folder",
367372
logoUrl: null,
368373
pluginId: "environment-personal-workspace",

‎apps/app/src/components/pickers/EnvironmentPicker.test.tsx‎

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ const checkoutProvider: SystemEnvironmentProvider = {
1717
machineProviderId: null,
1818
id: "project-checkout",
1919
displayName: "Project checkout",
20+
description: "Work in this project checkout.",
2021
icon: "Laptop",
2122
logoUrl: null,
2223
pluginId: "environment-project-checkout",
@@ -36,6 +37,7 @@ const branchProvider: SystemEnvironmentProvider = {
3637
machineProviderId: null,
3738
id: "branchy",
3839
displayName: "New branch workspace",
40+
description: "Prepare a workspace for this thread.",
3941
icon: "GitBranch",
4042
logoUrl: null,
4143
pluginId: "branchy",
@@ -55,6 +57,7 @@ const sandboxProvider: SystemEnvironmentProvider = {
5557
machineProviderId: null,
5658
id: "container",
5759
displayName: "Docker container",
60+
description: "Prepare a workspace for this thread.",
5861
icon: "Container",
5962
logoUrl: null,
6063
pluginId: "docker-sandbox",
@@ -78,6 +81,7 @@ const optionalInputsProvider: SystemEnvironmentProvider = {
7881
machineProviderId: null,
7982
id: "optional-sandbox",
8083
displayName: "Optional sandbox",
84+
description: "Prepare a workspace for this thread.",
8185
icon: "Container",
8286
logoUrl: null,
8387
pluginId: "optional-sandbox",
@@ -124,6 +128,37 @@ function renderPicker(ui: ReactElement) {
124128
}
125129

126130
describe("EnvironmentPickerUI", () => {
131+
it.each([
132+
null,
133+
{ status: "setup-required" as const, message: "Configure checkout access" },
134+
])(
135+
"shows the provider description unless setup guidance takes precedence (%j)",
136+
(availability) => {
137+
const provider = { ...checkoutProvider, availability };
138+
renderPicker(
139+
<EnvironmentPickerUI
140+
value="provider:project-checkout"
141+
sources={sources}
142+
host={host}
143+
isLocal
144+
providers={[provider]}
145+
onSelectProvider={vi.fn()}
146+
modal={false}
147+
/>,
148+
);
149+
fireEvent.pointerDown(
150+
screen.getByRole("button", { name: "Environment" }),
151+
{ button: 0 },
152+
);
153+
const item = screen.getByRole("menuitem", { name: /Project checkout/u });
154+
expect(item.textContent).toContain(
155+
availability?.message ?? provider.description,
156+
);
157+
if (availability !== null)
158+
expect(item.textContent).not.toContain(provider.description);
159+
},
160+
);
161+
127162
it("does not expose an ephemeral host through the single-machine fallback", () => {
128163
const ephemeralHost: Host = {
129164
...host,
@@ -294,6 +329,8 @@ describe("EnvironmentPickerUI", () => {
294329
...optionalInputsProvider,
295330
id: "personal-workspace",
296331
displayName: "Personal workspace",
332+
description: "Prepare a workspace for this thread.",
333+
icon: "Folder",
297334
requires: {
298335
projectCheckout: false,
299336
gitCheckout: false,
@@ -888,6 +925,8 @@ describe("EnvironmentPickerUI multi-machine menu", () => {
888925
...checkoutProvider,
889926
id: "host-sandbox",
890927
displayName: "Host sandbox",
928+
description: "Prepare a workspace for this thread.",
929+
icon: "Folder",
891930
requires: {
892931
...checkoutProvider.requires,
893932
projectCheckout: false,

‎apps/app/src/components/pickers/EnvironmentPicker.tsx‎

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,9 @@ function providerDescription(
120120
return provider.availability.message;
121121
}
122122
return (
123-
providerDisabledReason(provider, inputsControlProviderIds) ?? undefined
123+
providerDisabledReason(provider, inputsControlProviderIds) ??
124+
provider.description ??
125+
undefined
124126
);
125127
}
126128

‎apps/app/src/components/pickers/ReuseEnvironmentPicker.test.ts‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ const provider: SystemEnvironmentProvider = {
99
machineProviderId: null,
1010
id: "project-checkout",
1111
displayName: "Project checkout",
12+
description: "Prepare a workspace for this thread.",
1213
icon: "Laptop",
1314
logoUrl: null,
1415
pluginId: "environment-project-checkout",

‎apps/app/src/components/plugin/EnvironmentProviderIcon.test.tsx‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ const provider: SystemEnvironmentProvider = {
1818
machineAvailability: {},
1919
availability: null,
2020
displayName: "Worktree",
21+
description: "Prepare a workspace for this thread.",
2122
icon: "Folder",
2223
logoUrl: "/api/v1/system/providers/environment%3Aworktree/logo?h=hash",
2324
requires: {
@@ -46,6 +47,7 @@ it("renders an environment logo and reacts to React icon registration and remova
4647
...makePluginRegistrationSet(),
4748
providerIcons: [
4849
{
50+
providerKind: "environment",
4951
providerId: "git-worktree",
5052
icon: () => <svg data-test-environment-icon="" />,
5153
},

‎apps/app/src/components/plugin/EnvironmentProviderIcon.tsx‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ export function EnvironmentProviderIcon({
1010
provider: SystemEnvironmentProvider;
1111
className?: string;
1212
}) {
13-
const info = getProviderIconInfo(provider.id, {
13+
const info = getProviderIconInfo("environment", provider.id, {
1414
logoUrl: provider.logoUrl,
1515
displayName: provider.displayName,
1616
...(provider.icon === null ? {} : { icon: { glyph: provider.icon } }),

‎apps/app/src/components/plugin/MachineProviderIcon.tsx‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ export function MachineProviderIcon({
1616
provider: MachineProviderPresentation;
1717
className?: string;
1818
}) {
19-
const info = getProviderIconInfo(provider.id, {
19+
const info = getProviderIconInfo("machine", provider.id, {
2020
logoUrl: provider.logoUrl,
2121
displayName: provider.displayName,
2222
icon: { glyph: provider.icon },

‎apps/app/src/components/plugin/PluginNewThreadComposer.test.tsx‎

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -486,6 +486,7 @@ const CHECKOUT_PROVIDER: SystemEnvironmentProvider = {
486486
machineProviderId: null,
487487
id: "project-checkout",
488488
displayName: "Project checkout",
489+
description: "Prepare a workspace for this thread.",
489490
icon: "Laptop",
490491
logoUrl: null,
491492
pluginId: "environment-project-checkout",
@@ -508,6 +509,7 @@ const PERSONAL_WORKSPACE_PROVIDER: SystemEnvironmentProvider = {
508509
machineProviderId: null,
509510
id: "personal-workspace",
510511
displayName: "Personal workspace",
512+
description: "Prepare a workspace for this thread.",
511513
icon: "Folder",
512514
logoUrl: null,
513515
pluginId: "environment-personal-workspace",
@@ -527,6 +529,7 @@ const MANAGED_WORKTREE_SUGAR_PROVIDER: SystemEnvironmentProvider = {
527529
machineProviderId: null,
528530
id: "git-worktree",
529531
displayName: "Worktree",
532+
description: "Prepare a workspace for this thread.",
530533
icon: "GitBranch",
531534
logoUrl: null,
532535
pluginId: "environment-git-worktree",
@@ -1681,6 +1684,7 @@ const SANDBOX_PROVIDER: SystemEnvironmentProvider = {
16811684
machineProviderId: null,
16821685
id: "container",
16831686
displayName: "Docker container",
1687+
description: "Prepare a workspace for this thread.",
16841688
icon: "Container",
16851689
logoUrl: null,
16861690
pluginId: "docker-sandbox",
@@ -1704,6 +1708,7 @@ const OPTIONAL_INPUTS_PROVIDER: SystemEnvironmentProvider = {
17041708
machineProviderId: null,
17051709
id: "optional-sandbox",
17061710
displayName: "Optional sandbox",
1711+
description: "Prepare a workspace for this thread.",
17071712
icon: "Container",
17081713
logoUrl: null,
17091714
pluginId: "optional-sandbox",
@@ -1726,6 +1731,7 @@ const BRANCH_PROVIDER: SystemEnvironmentProvider = {
17261731
machineProviderId: null,
17271732
id: "branchy",
17281733
displayName: "New branch workspace",
1734+
description: "Prepare a workspace for this thread.",
17291735
icon: "GitBranch",
17301736
logoUrl: null,
17311737
pluginId: "branchy",
@@ -1745,6 +1751,7 @@ const HOST_PROVIDER: SystemEnvironmentProvider = {
17451751
machineProviderId: null,
17461752
id: "hosted",
17471753
displayName: "Machine sandbox",
1754+
description: "Prepare a workspace for this thread.",
17481755
icon: "Server",
17491756
logoUrl: null,
17501757
pluginId: "hosted",

‎apps/app/src/components/plugin/new-thread-environment-seed.test.ts‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ const ENVIRONMENT_PROVIDERS: SystemEnvironmentProvider[] = [
1919
machineProviderId: null,
2020
id: "branchy",
2121
displayName: "New branch workspace",
22+
description: "Prepare a workspace for this thread.",
2223
icon: "GitBranch",
2324
logoUrl: null,
2425
pluginId: "branchy",
@@ -37,6 +38,7 @@ const ENVIRONMENT_PROVIDERS: SystemEnvironmentProvider[] = [
3738
machineProviderId: null,
3839
id: "project-checkout",
3940
displayName: "Project checkout",
41+
description: "Prepare a workspace for this thread.",
4042
icon: "Laptop",
4143
logoUrl: null,
4244
pluginId: "environment-project-checkout",
@@ -58,6 +60,7 @@ const ENVIRONMENT_PROVIDERS: SystemEnvironmentProvider[] = [
5860
machineProviderId: null,
5961
id: "git-worktree",
6062
displayName: "Worktree",
63+
description: "Prepare a workspace for this thread.",
6164
icon: "GitBranch",
6265
logoUrl: null,
6366
pluginId: "environment-git-worktree",
@@ -76,6 +79,7 @@ const ENVIRONMENT_PROVIDERS: SystemEnvironmentProvider[] = [
7679
machineProviderId: null,
7780
id: "personal-workspace",
7881
displayName: "Personal workspace",
82+
description: "Prepare a workspace for this thread.",
7983
icon: "Folder",
8084
logoUrl: null,
8185
pluginId: "environment-personal-workspace",
@@ -94,6 +98,7 @@ const ENVIRONMENT_PROVIDERS: SystemEnvironmentProvider[] = [
9498
machineProviderId: null,
9599
id: "container",
96100
displayName: "Docker container",
101+
description: "Prepare a workspace for this thread.",
97102
icon: "Container",
98103
logoUrl: null,
99104
pluginId: "docker-sandbox",

‎apps/app/src/components/promptbox/NewThreadPromptBox.test.tsx‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ describe("ProjectlessMachineSlot", () => {
3232
machineProviderId: null,
3333
id: "personal-workspace",
3434
displayName: "Personal workspace",
35+
description: "Prepare a workspace for this thread.",
3536
icon: "Folder",
3637
logoUrl: null,
3738
pluginId: "environment-personal-workspace",
@@ -195,6 +196,7 @@ describe("EnvironmentSlot", () => {
195196
machineProviderId: null,
196197
id: "personal-workspace",
197198
displayName: "Personal workspace",
199+
description: "Prepare a workspace for this thread.",
198200
icon: "Folder",
199201
logoUrl: null,
200202
pluginId: "environment-personal-workspace",
@@ -214,6 +216,7 @@ describe("EnvironmentSlot", () => {
214216
machineProviderId: null,
215217
id: "modal-sandbox",
216218
displayName: "Modal sandbox",
219+
description: "Prepare a workspace for this thread.",
217220
icon: "Cloud",
218221
logoUrl: null,
219222
pluginId: "environment-modal-sandbox",

0 commit comments

Comments
 (0)