@agent-native/dispatch 0.2.11 → 0.2.13

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (84) hide show
  1. package/dist/actions/create-workspace-resource.js +4 -4
  2. package/dist/actions/create-workspace-resource.js.map +1 -1
  3. package/dist/actions/grant-workspace-resources-to-app.d.ts +3 -0
  4. package/dist/actions/grant-workspace-resources-to-app.d.ts.map +1 -0
  5. package/dist/actions/grant-workspace-resources-to-app.js +15 -0
  6. package/dist/actions/grant-workspace-resources-to-app.js.map +1 -0
  7. package/dist/actions/index.d.ts.map +1 -1
  8. package/dist/actions/index.js +4 -0
  9. package/dist/actions/index.js.map +1 -1
  10. package/dist/actions/list-workspace-resource-options.d.ts +3 -0
  11. package/dist/actions/list-workspace-resource-options.d.ts.map +1 -0
  12. package/dist/actions/list-workspace-resource-options.js +15 -0
  13. package/dist/actions/list-workspace-resource-options.js.map +1 -0
  14. package/dist/actions/list-workspace-resources.js +2 -2
  15. package/dist/actions/list-workspace-resources.js.map +1 -1
  16. package/dist/actions/start-workspace-app-creation.d.ts.map +1 -1
  17. package/dist/actions/start-workspace-app-creation.js +6 -1
  18. package/dist/actions/start-workspace-app-creation.js.map +1 -1
  19. package/dist/actions/view-screen.d.ts.map +1 -1
  20. package/dist/actions/view-screen.js +4 -0
  21. package/dist/actions/view-screen.js.map +1 -1
  22. package/dist/components/app-keys-popover.js +3 -3
  23. package/dist/components/app-keys-popover.js.map +1 -1
  24. package/dist/components/create-app-popover.d.ts +1 -1
  25. package/dist/components/create-app-popover.d.ts.map +1 -1
  26. package/dist/components/create-app-popover.js +66 -21
  27. package/dist/components/create-app-popover.js.map +1 -1
  28. package/dist/components/workspace-app-card.d.ts +6 -0
  29. package/dist/components/workspace-app-card.d.ts.map +1 -0
  30. package/dist/components/workspace-app-card.js +12 -0
  31. package/dist/components/workspace-app-card.js.map +1 -0
  32. package/dist/db/schema.js +2 -2
  33. package/dist/db/schema.js.map +1 -1
  34. package/dist/lib/workspace-apps.d.ts +15 -0
  35. package/dist/lib/workspace-apps.d.ts.map +1 -0
  36. package/dist/lib/workspace-apps.js +9 -0
  37. package/dist/lib/workspace-apps.js.map +1 -0
  38. package/dist/routes/pages/apps.$appId.d.ts.map +1 -1
  39. package/dist/routes/pages/apps.$appId.js +1 -5
  40. package/dist/routes/pages/apps.$appId.js.map +1 -1
  41. package/dist/routes/pages/apps.d.ts.map +1 -1
  42. package/dist/routes/pages/apps.js +3 -20
  43. package/dist/routes/pages/apps.js.map +1 -1
  44. package/dist/routes/pages/overview.d.ts.map +1 -1
  45. package/dist/routes/pages/overview.js +2 -20
  46. package/dist/routes/pages/overview.js.map +1 -1
  47. package/dist/routes/pages/workspace.d.ts.map +1 -1
  48. package/dist/routes/pages/workspace.js +17 -6
  49. package/dist/routes/pages/workspace.js.map +1 -1
  50. package/dist/server/lib/app-creation-store.d.ts +1 -0
  51. package/dist/server/lib/app-creation-store.d.ts.map +1 -1
  52. package/dist/server/lib/app-creation-store.js +36 -0
  53. package/dist/server/lib/app-creation-store.js.map +1 -1
  54. package/dist/server/lib/workspace-resources-store.d.ts +29 -1
  55. package/dist/server/lib/workspace-resources-store.d.ts.map +1 -1
  56. package/dist/server/lib/workspace-resources-store.js +46 -0
  57. package/dist/server/lib/workspace-resources-store.js.map +1 -1
  58. package/dist/server/plugins/agent-chat.d.ts.map +1 -1
  59. package/dist/server/plugins/agent-chat.js +1 -0
  60. package/dist/server/plugins/agent-chat.js.map +1 -1
  61. package/dist/server/plugins/integrations.d.ts.map +1 -1
  62. package/dist/server/plugins/integrations.js +2 -0
  63. package/dist/server/plugins/integrations.js.map +1 -1
  64. package/package.json +2 -2
  65. package/src/actions/create-workspace-resource.ts +4 -4
  66. package/src/actions/grant-workspace-resources-to-app.ts +16 -0
  67. package/src/actions/index.ts +4 -0
  68. package/src/actions/list-workspace-resource-options.ts +16 -0
  69. package/src/actions/list-workspace-resources.ts +2 -2
  70. package/src/actions/start-workspace-app-creation.ts +8 -1
  71. package/src/actions/view-screen.ts +4 -0
  72. package/src/components/app-keys-popover.tsx +3 -3
  73. package/src/components/create-app-popover.tsx +155 -22
  74. package/src/components/workspace-app-card.tsx +85 -0
  75. package/src/db/schema.ts +2 -2
  76. package/src/lib/workspace-apps.ts +21 -0
  77. package/src/routes/pages/apps.$appId.tsx +4 -17
  78. package/src/routes/pages/apps.tsx +6 -89
  79. package/src/routes/pages/overview.tsx +5 -84
  80. package/src/routes/pages/workspace.tsx +31 -5
  81. package/src/server/lib/app-creation-store.ts +52 -0
  82. package/src/server/lib/workspace-resources-store.ts +75 -1
  83. package/src/server/plugins/agent-chat.ts +1 -0
  84. package/src/server/plugins/integrations.ts +2 -0
@@ -2,7 +2,7 @@ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-run
2
2
  import { useEffect, useMemo, useState } from "react";
3
3
  import { PromptComposer, agentNativePath, appBasePath, isInBuilderFrame, sendToAgentChat, useDevMode, } from "@agent-native/core/client";
4
4
  import { getWorkspaceAppIdValidationError } from "@agent-native/core/shared";
5
- import { IconArrowLeft, IconArrowUpRight, IconCheck, IconChevronDown, IconKey, IconLoader2, IconPlus, } from "@tabler/icons-react";
5
+ import { IconArrowLeft, IconArrowUpRight, IconBook, IconCheck, IconChevronDown, IconFileText, IconKey, IconLoader2, IconPlus, } from "@tabler/icons-react";
6
6
  import { Popover, PopoverContent, PopoverTrigger, } from "../components/ui/popover.js";
7
7
  import { Button } from "../components/ui/button.js";
8
8
  function slugify(value) {
@@ -25,6 +25,11 @@ function buildAppCreationPrompt(input) {
25
25
  const grantRequest = keyList
26
26
  ? `Requested Dispatch vault key grants for this app: ${keyList}`
27
27
  : `Requested Dispatch vault key grants for this app: none`;
28
+ const resourceList = input.selectedResources.length
29
+ ? input.selectedResources
30
+ .map((resource) => `- ${resource.name} (${resource.kind}, ${resource.path})`)
31
+ .join("\n")
32
+ : "none";
28
33
  return [
29
34
  `Create a new agent-native app in this workspace.`,
30
35
  `This is a new workspace app request, not a feature request for the current app.`,
@@ -32,16 +37,22 @@ function buildAppCreationPrompt(input) {
32
37
  `Suggested app name: ${input.appId} (you may adjust the slug if it conflicts)`,
33
38
  `User prompt: ${input.prompt.trim()}`,
34
39
  grantRequest,
40
+ `Requested Dispatch workspace resources for this app:\n${resourceList}`,
35
41
  ``,
36
42
  `Pick a starter template that fits the user's prompt — analytics, calendar, content, design, dispatch, forms, mail, slides, clips, or starter when none of the others fit.`,
37
43
  `Use the workspace app layout: create it under apps/${input.appId}, mount it at /${input.appId}, keep it on the shared workspace database/hosting model, and avoid table-name collisions by namespacing any new domain tables to the app.`,
38
44
  `Use relative workspace links like /${input.appId}. Do not hardcode localhost, 127.0.0.1, 8080, 8100, or any dev port; the active workspace gateway/browser origin owns the port.`,
39
45
  `Use the framework/template UI stack: shadcn/ui components and @tabler/icons-react. Do not add lucide-react or another icon library for standard UI.`,
40
- `If the user's prompt mentions sibling apps like Mail, Calendar, Dispatch, or other templates, treat them as existing workspace neighbors or integrations. Do not scaffold those sibling apps inside apps/${input.appId} unless the user explicitly asks to create them too.`,
46
+ `Existing first-party apps are neighbors, not implementation details for this app. If the user's prompt mentions Mail, Calendar, Analytics, Dispatch, or other templates, treat them as existing hosted/connected apps that this app can link to or call through A2A/default connected agents. For example, Mail, Calendar, and Analytics already exist at https://mail.agent-native.com, https://calendar.agent-native.com, and https://analytics.agent-native.com.`,
47
+ `Do not clone first-party templates, create wrapper apps, or scaffold child apps/routes for Mail, Calendar, Analytics, etc. inside apps/${input.appId} just so this app can access them. If the request is a cross-app dashboard or overview, build only the new dashboard/overview app and delegate to the existing apps for domain work.`,
48
+ `Only create another first-party app copy when the user explicitly asks for a customized fork/copy of that app; otherwise keep using the hosted/shared app so improvements to the base template keep flowing to users.`,
41
49
  `Do not satisfy this by adding a route, page, component, or file inside apps/starter or another existing app unless the user explicitly asks to modify that existing app.`,
42
50
  keyList
43
51
  ? `After the app exists, grant the selected Dispatch vault keys to appId "${input.appId}" and sync them once the app server is available. Treat these as requested grants, not active grants before creation succeeds.`
44
52
  : `Do not grant any Dispatch vault keys unless the user asks later.`,
53
+ input.selectedResources.length
54
+ ? `After the app exists, grant the selected Dispatch workspace resources to appId "${input.appId}" and sync them once the app server is available. Add a short note to apps/${input.appId}/AGENTS.md telling the app agent to read relevant shared resources under context/ or the selected resource paths before doing GTM/domain work.`
55
+ : `Do not grant any Dispatch workspace resources unless the user asks later.`,
45
56
  ``,
46
57
  `App readiness requirements before handing off:`,
47
58
  `- Ensure apps/${input.appId}/package.json exists; Dispatch discovers workspace apps from apps/<app-id>/package.json, not a separate app registry.`,
@@ -73,7 +84,7 @@ function actionUrl(basePath, action) {
73
84
  return `${normalized}${path}`;
74
85
  }
75
86
  /**
76
- * Inline two-step app-creation flow: prompt → optional key picker → submit.
87
+ * Inline two-step app-creation flow: prompt → optional access picker → submit.
77
88
  * Used both in the popover form and in the dedicated `/new-app` page so the
78
89
  * same UX shows up everywhere a teammate kicks off a new workspace app.
79
90
  */
@@ -81,15 +92,17 @@ export function CreateAppFlow({ onClose, className = "", }) {
81
92
  const [step, setStep] = useState("prompt");
82
93
  const [prompt, setPrompt] = useState("");
83
94
  const [selectedSecretIds, setSelectedSecretIds] = useState([]);
95
+ const [selectedResourceIds, setSelectedResourceIds] = useState([]);
84
96
  const [secrets, setSecrets] = useState([]);
97
+ const [resources, setResources] = useState([]);
85
98
  const [secretsError, setSecretsError] = useState(null);
99
+ const [resourcesError, setResourcesError] = useState(null);
86
100
  const [statusMessage, setStatusMessage] = useState(null);
87
101
  const [branchUrl, setBranchUrl] = useState(null);
88
102
  const [isSubmitting, setIsSubmitting] = useState(false);
89
103
  const { isDevMode } = useDevMode();
90
104
  const basePath = useMemo(() => defaultDispatchBasePath(), []);
91
- // Fetch the vault keys eagerly so step 2 has them ready the moment the user
92
- // taps "Choose keys" — no spinner, no pause between steps.
105
+ // Fetch access options eagerly so step 2 has them ready immediately.
93
106
  useEffect(() => {
94
107
  let cancelled = false;
95
108
  fetchJson(actionUrl(basePath, "list-vault-secret-options"))
@@ -105,18 +118,39 @@ export function CreateAppFlow({ onClose, className = "", }) {
105
118
  setSecrets([]);
106
119
  setSecretsError(err?.message || "Could not load Dispatch keys");
107
120
  });
121
+ fetchJson(actionUrl(basePath, "list-workspace-resource-options"))
122
+ .then((data) => {
123
+ if (cancelled)
124
+ return;
125
+ setResources(Array.isArray(data) ? data : []);
126
+ setResourcesError(null);
127
+ })
128
+ .catch((err) => {
129
+ if (cancelled)
130
+ return;
131
+ setResources([]);
132
+ setResourcesError(err?.message || "Could not load Dispatch resources");
133
+ });
108
134
  return () => {
109
135
  cancelled = true;
110
136
  };
111
137
  }, [basePath]);
112
138
  const selectedSecrets = useMemo(() => secrets.filter((s) => selectedSecretIds.includes(s.id)), [secrets, selectedSecretIds]);
139
+ const selectedResources = useMemo(() => resources.filter((r) => selectedResourceIds.includes(r.id)), [resources, selectedResourceIds]);
113
140
  const selectedSecretLabel = selectedSecretIds.length === 0
114
141
  ? "no keys"
115
142
  : `${selectedSecretIds.length} key${selectedSecretIds.length === 1 ? "" : "s"}`;
143
+ const selectedResourceLabel = selectedResourceIds.length === 0
144
+ ? "no resources"
145
+ : `${selectedResourceIds.length} resource${selectedResourceIds.length === 1 ? "" : "s"}`;
146
+ const selectedAccessLabel = [selectedSecretLabel, selectedResourceLabel].join(" · ");
116
147
  function toggleSecret(id) {
117
148
  setSelectedSecretIds((cur) => cur.includes(id) ? cur.filter((x) => x !== id) : [...cur, id]);
118
149
  }
119
- async function submit(rawPrompt, selectedKeys) {
150
+ function toggleResource(id) {
151
+ setSelectedResourceIds((cur) => cur.includes(id) ? cur.filter((x) => x !== id) : [...cur, id]);
152
+ }
153
+ async function submit(rawPrompt) {
120
154
  const trimmed = rawPrompt.trim();
121
155
  if (!trimmed || isSubmitting)
122
156
  return;
@@ -129,7 +163,8 @@ export function CreateAppFlow({ onClose, className = "", }) {
129
163
  const message = buildAppCreationPrompt({
130
164
  appId,
131
165
  prompt: trimmed,
132
- selectedKeys,
166
+ selectedKeys: selectedSecrets.map((s) => s.credentialKey),
167
+ selectedResources,
133
168
  });
134
169
  setIsSubmitting(true);
135
170
  setStatusMessage(null);
@@ -152,7 +187,8 @@ export function CreateAppFlow({ onClose, className = "", }) {
152
187
  body: JSON.stringify({
153
188
  prompt: trimmed,
154
189
  appId,
155
- secretIds: selectedKeys.length > 0 ? selectedSecretIds : [],
190
+ secretIds: selectedSecretIds.length > 0 ? selectedSecretIds : [],
191
+ resourceIds: selectedResourceIds.length > 0 ? selectedResourceIds : [],
156
192
  }),
157
193
  });
158
194
  if (result?.mode === "builder") {
@@ -172,20 +208,29 @@ export function CreateAppFlow({ onClose, className = "", }) {
172
208
  setIsSubmitting(false);
173
209
  }
174
210
  }
175
- const submitWithSelectedKeys = () => submit(prompt, selectedSecrets.map((s) => s.credentialKey));
176
- return (_jsxs("div", { className: `flex flex-col gap-3 ${className}`, children: [step === "prompt" ? (_jsxs(_Fragment, { children: [_jsxs("div", { className: "flex items-center justify-between gap-2 px-1", children: [_jsx("p", { className: "text-sm font-semibold text-foreground", children: "Create app" }), _jsxs("button", { type: "button", onClick: () => setStep("keys"), className: "inline-flex cursor-pointer items-center gap-1 rounded-md border border-border bg-background/40 px-2 py-1 text-[11px] text-muted-foreground hover:text-foreground hover:bg-accent/50", children: [_jsx(IconKey, { size: 11 }), selectedSecretLabel] })] }), _jsx(PromptComposer, { autoFocus: true, disabled: isSubmitting, placeholder: "Describe the app your teammate should be able to use...", draftScope: "dispatch:create-app", onSubmit: (text) => {
211
+ const submitWithSelectedAccess = () => submit(prompt);
212
+ return (_jsxs("div", { className: `flex flex-col gap-3 ${className}`, children: [step === "prompt" ? (_jsxs(_Fragment, { children: [_jsxs("div", { className: "flex items-center justify-between gap-2 px-1", children: [_jsx("p", { className: "text-sm font-semibold text-foreground", children: "Create app" }), _jsxs("button", { type: "button", onClick: () => setStep("access"), className: "inline-flex cursor-pointer items-center gap-1 rounded-md border border-border bg-background/40 px-2 py-1 text-[11px] text-muted-foreground hover:text-foreground hover:bg-accent/50", children: [_jsx(IconKey, { size: 11 }), selectedAccessLabel] })] }), _jsx(PromptComposer, { autoFocus: true, disabled: isSubmitting, placeholder: "Describe the app your teammate should be able to use...", draftScope: "dispatch:create-app", onSubmit: (text) => {
177
213
  setPrompt(text);
178
- submit(text, selectedSecrets.map((s) => s.credentialKey));
179
- } })] })) : (_jsxs(_Fragment, { children: [_jsxs("div", { className: "flex items-center justify-between gap-2 px-1", children: [_jsxs("button", { type: "button", onClick: () => setStep("prompt"), className: "inline-flex cursor-pointer items-center gap-1 text-xs text-muted-foreground hover:text-foreground", children: [_jsx(IconArrowLeft, { size: 12 }), "Back"] }), _jsxs("span", { className: "text-[11px] text-muted-foreground/70", children: [selectedSecretLabel, " selected"] })] }), _jsx("div", { className: "max-h-[340px] space-y-2 overflow-y-auto rounded-md border border-border bg-card p-2", children: secretsError ? (_jsx("p", { className: "rounded-md border border-dashed border-border px-3 py-3 text-xs text-muted-foreground", children: secretsError })) : secrets.length === 0 ? (_jsx("p", { className: "rounded-md border border-dashed border-border px-3 py-3 text-xs text-muted-foreground", children: "No Dispatch vault keys found yet." })) : (secrets.map((secret) => {
180
- const selected = selectedSecretIds.includes(secret.id);
181
- return (_jsxs("div", { className: `group rounded-md border text-sm ${selected
182
- ? "border-primary/45 bg-primary/5"
183
- : "border-border hover:border-muted-foreground/40 hover:bg-accent/35"}`, children: [_jsxs("button", { type: "button", "aria-pressed": selected, onClick: () => toggleSecret(secret.id), className: "flex w-full cursor-pointer items-start gap-3 rounded-md px-3 py-2 text-left", children: [_jsx("span", { className: `mt-0.5 flex h-4 w-4 shrink-0 items-center justify-center rounded border ${selected
184
- ? "border-primary/60 bg-primary/10 text-primary"
185
- : "border-muted-foreground/35 text-transparent"}`, children: selected ? _jsx(IconCheck, { className: "h-3 w-3" }) : null }), _jsxs("span", { className: "min-w-0 flex-1", children: [_jsx("span", { className: "block truncate font-medium", children: secret.credentialKey }), _jsx("span", { className: "block truncate text-xs text-muted-foreground/70", children: selected
186
- ? "Will be requested for this app"
187
- : "Click to request" })] })] }), (secret.provider || secret.name) && (_jsxs("details", { className: "group/details border-t border-border/60 px-3 py-1.5 text-xs text-muted-foreground/75", children: [_jsxs("summary", { className: "flex cursor-pointer list-none items-center gap-1.5 text-[11px] hover:text-muted-foreground [&::-webkit-details-marker]:hidden", children: [_jsx(IconChevronDown, { className: "h-3 w-3 transition-transform group-open/details:rotate-180" }), "Details"] }), _jsxs("div", { className: "mt-1.5 space-y-1 pb-0.5 pl-4", children: [_jsxs("div", { className: "truncate", children: ["Provider: ", secret.provider || "Not specified"] }), _jsxs("div", { className: "truncate", children: ["Name: ", secret.name] })] })] }))] }, secret.id));
188
- })) }), _jsx("div", { className: "flex items-center justify-end gap-2", children: _jsxs(Button, { type: "button", size: "sm", onClick: submitWithSelectedKeys, disabled: !prompt.trim() || isSubmitting, children: [isSubmitting ? (_jsx(IconLoader2, { className: "h-3.5 w-3.5 animate-spin" })) : (_jsx(IconPlus, { className: "h-3.5 w-3.5" })), "Create app"] }) }), !prompt.trim() ? (_jsx("p", { className: "px-1 text-[11px] text-muted-foreground/70", children: "Add a prompt on the previous step before creating the app." })) : null] })), statusMessage ? (_jsxs("div", { className: "rounded-md border border-border bg-muted/40 px-3 py-2 text-xs text-muted-foreground", children: [statusMessage, branchUrl ? (_jsxs("a", { href: branchUrl, target: "_blank", rel: "noreferrer", className: "ml-2 inline-flex items-center gap-1 font-medium text-foreground underline", children: ["Open branch ", _jsx(IconArrowUpRight, { className: "h-3 w-3" })] })) : null] })) : null] }));
214
+ submit(text);
215
+ } })] })) : (_jsxs(_Fragment, { children: [_jsxs("div", { className: "flex items-center justify-between gap-2 px-1", children: [_jsxs("button", { type: "button", onClick: () => setStep("prompt"), className: "inline-flex cursor-pointer items-center gap-1 text-xs text-muted-foreground hover:text-foreground", children: [_jsx(IconArrowLeft, { size: 12 }), "Back"] }), _jsx("span", { className: "text-[11px] text-muted-foreground/70", children: selectedAccessLabel })] }), _jsxs("div", { className: "max-h-[180px] space-y-2 overflow-y-auto rounded-md border border-border bg-card p-2", children: [_jsxs("div", { className: "flex items-center gap-1.5 px-1 pb-1 text-[11px] font-medium text-muted-foreground", children: [_jsx(IconKey, { size: 12 }), "Dispatch keys"] }), secretsError ? (_jsx("p", { className: "rounded-md border border-dashed border-border px-3 py-3 text-xs text-muted-foreground", children: secretsError })) : secrets.length === 0 ? (_jsx("p", { className: "rounded-md border border-dashed border-border px-3 py-3 text-xs text-muted-foreground", children: "No Dispatch vault keys found yet." })) : (secrets.map((secret) => {
216
+ const selected = selectedSecretIds.includes(secret.id);
217
+ return (_jsxs("div", { className: `group rounded-md border text-sm ${selected
218
+ ? "border-primary/45 bg-primary/5"
219
+ : "border-border hover:border-muted-foreground/40 hover:bg-accent/35"}`, children: [_jsxs("button", { type: "button", "aria-pressed": selected, onClick: () => toggleSecret(secret.id), className: "flex w-full cursor-pointer items-start gap-3 rounded-md px-3 py-2 text-left", children: [_jsx("span", { className: `mt-0.5 flex h-4 w-4 shrink-0 items-center justify-center rounded border ${selected
220
+ ? "border-primary/60 bg-primary/10 text-primary"
221
+ : "border-muted-foreground/35 text-transparent"}`, children: selected ? _jsx(IconCheck, { className: "h-3 w-3" }) : null }), _jsxs("span", { className: "min-w-0 flex-1", children: [_jsx("span", { className: "block truncate font-medium", children: secret.credentialKey }), _jsx("span", { className: "block truncate text-xs text-muted-foreground/70", children: selected
222
+ ? "Will be requested for this app"
223
+ : "Click to request" })] })] }), (secret.provider || secret.name) && (_jsxs("details", { className: "group/details border-t border-border/60 px-3 py-1.5 text-xs text-muted-foreground/75", children: [_jsxs("summary", { className: "flex cursor-pointer list-none items-center gap-1.5 text-[11px] hover:text-muted-foreground [&::-webkit-details-marker]:hidden", children: [_jsx(IconChevronDown, { className: "h-3 w-3 transition-transform group-open/details:rotate-180" }), "Details"] }), _jsxs("div", { className: "mt-1.5 space-y-1 pb-0.5 pl-4", children: [_jsxs("div", { className: "truncate", children: ["Provider: ", secret.provider || "Not specified"] }), _jsxs("div", { className: "truncate", children: ["Name: ", secret.name] })] })] }))] }, secret.id));
224
+ }))] }), _jsxs("div", { className: "max-h-[180px] space-y-2 overflow-y-auto rounded-md border border-border bg-card p-2", children: [_jsxs("div", { className: "flex items-center gap-1.5 px-1 pb-1 text-[11px] font-medium text-muted-foreground", children: [_jsx(IconBook, { size: 12 }), "Resource packs"] }), resourcesError ? (_jsx("p", { className: "rounded-md border border-dashed border-border px-3 py-3 text-xs text-muted-foreground", children: resourcesError })) : resources.length === 0 ? (_jsx("p", { className: "rounded-md border border-dashed border-border px-3 py-3 text-xs text-muted-foreground", children: "No Dispatch resource packs found yet." })) : (resources.map((resource) => {
225
+ const selected = selectedResourceIds.includes(resource.id);
226
+ return (_jsxs("div", { className: `group rounded-md border text-sm ${selected
227
+ ? "border-primary/45 bg-primary/5"
228
+ : "border-border hover:border-muted-foreground/40 hover:bg-accent/35"}`, children: [_jsxs("button", { type: "button", "aria-pressed": selected, onClick: () => toggleResource(resource.id), className: "flex w-full cursor-pointer items-start gap-3 rounded-md px-3 py-2 text-left", children: [_jsx("span", { className: `mt-0.5 flex h-4 w-4 shrink-0 items-center justify-center rounded border ${selected
229
+ ? "border-primary/60 bg-primary/10 text-primary"
230
+ : "border-muted-foreground/35 text-transparent"}`, children: selected ? _jsx(IconCheck, { className: "h-3 w-3" }) : null }), _jsxs("span", { className: "min-w-0 flex-1", children: [_jsxs("span", { className: "flex min-w-0 items-center gap-1.5", children: [_jsx(IconFileText, { className: "h-3.5 w-3.5 shrink-0 text-muted-foreground/70" }), _jsx("span", { className: "block truncate font-medium", children: resource.name })] }), _jsxs("span", { className: "block truncate text-xs text-muted-foreground/70", children: [resource.kind, " \u00B7 ", resource.path] })] })] }), _jsxs("details", { className: "group/details border-t border-border/60 px-3 py-1.5 text-xs text-muted-foreground/75", children: [_jsxs("summary", { className: "flex cursor-pointer list-none items-center gap-1.5 text-[11px] hover:text-muted-foreground [&::-webkit-details-marker]:hidden", children: [_jsx(IconChevronDown, { className: "h-3 w-3 transition-transform group-open/details:rotate-180" }), "Details"] }), _jsxs("div", { className: "mt-1.5 space-y-1 pb-0.5 pl-4", children: [_jsxs("div", { className: "truncate", children: ["Scope:", " ", resource.scope === "all"
231
+ ? "All apps"
232
+ : "Selected apps"] }), resource.description ? (_jsx("div", { className: "line-clamp-2", children: resource.description })) : null] })] })] }, resource.id));
233
+ }))] }), _jsx("div", { className: "flex items-center justify-end gap-2", children: _jsxs(Button, { type: "button", size: "sm", onClick: submitWithSelectedAccess, disabled: !prompt.trim() || isSubmitting, children: [isSubmitting ? (_jsx(IconLoader2, { className: "h-3.5 w-3.5 animate-spin" })) : (_jsx(IconPlus, { className: "h-3.5 w-3.5" })), "Create app"] }) }), !prompt.trim() ? (_jsx("p", { className: "px-1 text-[11px] text-muted-foreground/70", children: "Add a prompt on the previous step before creating the app." })) : null] })), statusMessage ? (_jsxs("div", { className: "rounded-md border border-border bg-muted/40 px-3 py-2 text-xs text-muted-foreground", children: [statusMessage, branchUrl ? (_jsxs("a", { href: branchUrl, target: "_blank", rel: "noreferrer", className: "ml-2 inline-flex items-center gap-1 font-medium text-foreground underline", children: ["Open branch ", _jsx(IconArrowUpRight, { className: "h-3 w-3" })] })) : null] })) : null] }));
189
234
  }
190
235
  export function CreateAppPopover({ trigger, align = "center", }) {
191
236
  const [open, setOpen] = useState(false);
@@ -1 +1 @@
1
- {"version":3,"file":"create-app-popover.js","sourceRoot":"","sources":["../../src/components/create-app-popover.tsx"],"names":[],"mappings":"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","sourcesContent":["import { useEffect, useMemo, useState, type ReactNode } from \"react\";\nimport {\n PromptComposer,\n agentNativePath,\n appBasePath,\n isInBuilderFrame,\n sendToAgentChat,\n useDevMode,\n} from \"@agent-native/core/client\";\nimport { getWorkspaceAppIdValidationError } from \"@agent-native/core/shared\";\nimport {\n IconArrowLeft,\n IconArrowUpRight,\n IconCheck,\n IconChevronDown,\n IconKey,\n IconLoader2,\n IconPlus,\n} from \"@tabler/icons-react\";\nimport {\n Popover,\n PopoverContent,\n PopoverTrigger,\n} from \"@/components/ui/popover\";\nimport { Button } from \"@/components/ui/button\";\n\ninterface VaultSecretOption {\n id: string;\n name: string;\n credentialKey: string;\n provider?: string | null;\n description?: string | null;\n}\n\ninterface CreateAppPopoverProps {\n /**\n * Custom trigger element. Defaults to a dashed-border tile that matches the\n * apps grid empty state.\n */\n trigger?: ReactNode;\n /**\n * Override the popover alignment. Defaults to \"center\" with a 10px offset.\n */\n align?: \"start\" | \"center\" | \"end\";\n}\n\nfunction slugify(value: string): string {\n return value\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, \"-\")\n .replace(/^-+|-+$/g, \"\")\n .replace(/^[^a-z]+/, \"\")\n .slice(0, 48);\n}\n\nfunction titleFromPrompt(prompt: string): string {\n const cleaned = prompt\n .replace(/\\b(build|create|make|an?|the|app|tool|dashboard)\\b/gi, \" \")\n .replace(/\\s+/g, \" \")\n .trim();\n return slugify(cleaned || \"new-app\") || \"new-app\";\n}\n\nfunction buildAppCreationPrompt(input: {\n appId: string;\n prompt: string;\n selectedKeys: string[];\n}): string {\n const keyList = input.selectedKeys.join(\", \");\n const grantRequest = keyList\n ? `Requested Dispatch vault key grants for this app: ${keyList}`\n : `Requested Dispatch vault key grants for this app: none`;\n\n return [\n `Create a new agent-native app in this workspace.`,\n `This is a new workspace app request, not a feature request for the current app.`,\n ``,\n `Suggested app name: ${input.appId} (you may adjust the slug if it conflicts)`,\n `User prompt: ${input.prompt.trim()}`,\n grantRequest,\n ``,\n `Pick a starter template that fits the user's prompt — analytics, calendar, content, design, dispatch, forms, mail, slides, clips, or starter when none of the others fit.`,\n `Use the workspace app layout: create it under apps/${input.appId}, mount it at /${input.appId}, keep it on the shared workspace database/hosting model, and avoid table-name collisions by namespacing any new domain tables to the app.`,\n `Use relative workspace links like /${input.appId}. Do not hardcode localhost, 127.0.0.1, 8080, 8100, or any dev port; the active workspace gateway/browser origin owns the port.`,\n `Use the framework/template UI stack: shadcn/ui components and @tabler/icons-react. Do not add lucide-react or another icon library for standard UI.`,\n `If the user's prompt mentions sibling apps like Mail, Calendar, Dispatch, or other templates, treat them as existing workspace neighbors or integrations. Do not scaffold those sibling apps inside apps/${input.appId} unless the user explicitly asks to create them too.`,\n `Do not satisfy this by adding a route, page, component, or file inside apps/starter or another existing app unless the user explicitly asks to modify that existing app.`,\n keyList\n ? `After the app exists, grant the selected Dispatch vault keys to appId \"${input.appId}\" and sync them once the app server is available. Treat these as requested grants, not active grants before creation succeeds.`\n : `Do not grant any Dispatch vault keys unless the user asks later.`,\n ``,\n `App readiness requirements before handing off:`,\n `- Ensure apps/${input.appId}/package.json exists; Dispatch discovers workspace apps from apps/<app-id>/package.json, not a separate app registry.`,\n `- Update the app manifest/package/deploy metadata needed by the existing workspace deployment model.`,\n `- Ensure the React Router client entry preserves APP_BASE_PATH/VITE_APP_BASE_PATH via appBasePath() so /${input.appId} hydrates correctly.`,\n `- Verify the app's agent card/A2A metadata is ready so Dispatch can discover and delegate to the app after deployment.`,\n `When it is ready, start or update the workspace dev server and navigate the user to /${input.appId}.`,\n ].join(\"\\n\");\n}\n\nasync function fetchJson(url: string, init?: RequestInit): Promise<any> {\n const res = await fetch(url, init);\n const data = await res.json().catch(() => null);\n if (!res.ok) {\n throw new Error(\n data?.error || data?.message || `Request failed ${res.status}`,\n );\n }\n return data;\n}\n\nfunction defaultDispatchBasePath(): string | null {\n const base = appBasePath();\n if (base === \"/dispatch\") return null;\n return null;\n}\n\nfunction actionUrl(basePath: string | null, action: string): string {\n const path = `/_agent-native/actions/${action}`;\n if (basePath === null) return agentNativePath(path);\n const normalized = basePath.replace(/\\/+$/, \"\");\n return `${normalized}${path}`;\n}\n\n/**\n * Inline two-step app-creation flow: prompt → optional key picker → submit.\n * Used both in the popover form and in the dedicated `/new-app` page so the\n * same UX shows up everywhere a teammate kicks off a new workspace app.\n */\nexport function CreateAppFlow({\n onClose,\n className = \"\",\n}: {\n onClose?: () => void;\n className?: string;\n}) {\n const [step, setStep] = useState<\"prompt\" | \"keys\">(\"prompt\");\n const [prompt, setPrompt] = useState(\"\");\n const [selectedSecretIds, setSelectedSecretIds] = useState<string[]>([]);\n const [secrets, setSecrets] = useState<VaultSecretOption[]>([]);\n const [secretsError, setSecretsError] = useState<string | null>(null);\n const [statusMessage, setStatusMessage] = useState<string | null>(null);\n const [branchUrl, setBranchUrl] = useState<string | null>(null);\n const [isSubmitting, setIsSubmitting] = useState(false);\n const { isDevMode } = useDevMode();\n\n const basePath = useMemo(() => defaultDispatchBasePath(), []);\n\n // Fetch the vault keys eagerly so step 2 has them ready the moment the user\n // taps \"Choose keys\" — no spinner, no pause between steps.\n useEffect(() => {\n let cancelled = false;\n fetchJson(actionUrl(basePath, \"list-vault-secret-options\"))\n .then((data) => {\n if (cancelled) return;\n setSecrets(Array.isArray(data) ? data : []);\n setSecretsError(null);\n })\n .catch((err) => {\n if (cancelled) return;\n setSecrets([]);\n setSecretsError(err?.message || \"Could not load Dispatch keys\");\n });\n return () => {\n cancelled = true;\n };\n }, [basePath]);\n\n const selectedSecrets = useMemo(\n () => secrets.filter((s) => selectedSecretIds.includes(s.id)),\n [secrets, selectedSecretIds],\n );\n const selectedSecretLabel =\n selectedSecretIds.length === 0\n ? \"no keys\"\n : `${selectedSecretIds.length} key${selectedSecretIds.length === 1 ? \"\" : \"s\"}`;\n\n function toggleSecret(id: string) {\n setSelectedSecretIds((cur) =>\n cur.includes(id) ? cur.filter((x) => x !== id) : [...cur, id],\n );\n }\n\n async function submit(rawPrompt: string, selectedKeys: string[]) {\n const trimmed = rawPrompt.trim();\n if (!trimmed || isSubmitting) return;\n const appId = titleFromPrompt(trimmed);\n const validationError = getWorkspaceAppIdValidationError(appId);\n if (validationError) {\n setStatusMessage(validationError);\n return;\n }\n\n const message = buildAppCreationPrompt({\n appId,\n prompt: trimmed,\n selectedKeys,\n });\n setIsSubmitting(true);\n setStatusMessage(null);\n setBranchUrl(null);\n\n try {\n if (isInBuilderFrame()) {\n sendToAgentChat({ message, submit: true, type: \"code\" });\n setStatusMessage(\"Sent to Builder chat.\");\n onClose?.();\n } else if (isDevMode) {\n sendToAgentChat({ message, submit: true, type: \"code\", newTab: true });\n setStatusMessage(\"Sent to the local agent.\");\n onClose?.();\n } else {\n const result = await fetchJson(\n actionUrl(basePath, \"start-workspace-app-creation\"),\n {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({\n prompt: trimmed,\n appId,\n secretIds: selectedKeys.length > 0 ? selectedSecretIds : [],\n }),\n },\n );\n if (result?.mode === \"builder\") {\n setBranchUrl(result?.url || null);\n setStatusMessage(\"Builder branch created.\");\n } else {\n setStatusMessage(\n result?.message ||\n \"Builder app creation is coming soon. Open this workspace in Builder to create an app from this prompt.\",\n );\n }\n }\n } catch (err: any) {\n setStatusMessage(err?.message || \"Could not start the new app flow.\");\n } finally {\n setIsSubmitting(false);\n }\n }\n\n const submitWithSelectedKeys = () =>\n submit(\n prompt,\n selectedSecrets.map((s) => s.credentialKey),\n );\n\n return (\n <div className={`flex flex-col gap-3 ${className}`}>\n {step === \"prompt\" ? (\n <>\n <div className=\"flex items-center justify-between gap-2 px-1\">\n <p className=\"text-sm font-semibold text-foreground\">Create app</p>\n <button\n type=\"button\"\n onClick={() => setStep(\"keys\")}\n className=\"inline-flex cursor-pointer items-center gap-1 rounded-md border border-border bg-background/40 px-2 py-1 text-[11px] text-muted-foreground hover:text-foreground hover:bg-accent/50\"\n >\n <IconKey size={11} />\n {selectedSecretLabel}\n </button>\n </div>\n <PromptComposer\n autoFocus\n disabled={isSubmitting}\n placeholder=\"Describe the app your teammate should be able to use...\"\n draftScope=\"dispatch:create-app\"\n onSubmit={(text) => {\n setPrompt(text);\n submit(\n text,\n selectedSecrets.map((s) => s.credentialKey),\n );\n }}\n />\n </>\n ) : (\n <>\n <div className=\"flex items-center justify-between gap-2 px-1\">\n <button\n type=\"button\"\n onClick={() => setStep(\"prompt\")}\n className=\"inline-flex cursor-pointer items-center gap-1 text-xs text-muted-foreground hover:text-foreground\"\n >\n <IconArrowLeft size={12} />\n Back\n </button>\n <span className=\"text-[11px] text-muted-foreground/70\">\n {selectedSecretLabel} selected\n </span>\n </div>\n <div className=\"max-h-[340px] space-y-2 overflow-y-auto rounded-md border border-border bg-card p-2\">\n {secretsError ? (\n <p className=\"rounded-md border border-dashed border-border px-3 py-3 text-xs text-muted-foreground\">\n {secretsError}\n </p>\n ) : secrets.length === 0 ? (\n <p className=\"rounded-md border border-dashed border-border px-3 py-3 text-xs text-muted-foreground\">\n No Dispatch vault keys found yet.\n </p>\n ) : (\n secrets.map((secret) => {\n const selected = selectedSecretIds.includes(secret.id);\n return (\n <div\n key={secret.id}\n className={`group rounded-md border text-sm ${\n selected\n ? \"border-primary/45 bg-primary/5\"\n : \"border-border hover:border-muted-foreground/40 hover:bg-accent/35\"\n }`}\n >\n <button\n type=\"button\"\n aria-pressed={selected}\n onClick={() => toggleSecret(secret.id)}\n className=\"flex w-full cursor-pointer items-start gap-3 rounded-md px-3 py-2 text-left\"\n >\n <span\n className={`mt-0.5 flex h-4 w-4 shrink-0 items-center justify-center rounded border ${\n selected\n ? \"border-primary/60 bg-primary/10 text-primary\"\n : \"border-muted-foreground/35 text-transparent\"\n }`}\n >\n {selected ? <IconCheck className=\"h-3 w-3\" /> : null}\n </span>\n <span className=\"min-w-0 flex-1\">\n <span className=\"block truncate font-medium\">\n {secret.credentialKey}\n </span>\n <span className=\"block truncate text-xs text-muted-foreground/70\">\n {selected\n ? \"Will be requested for this app\"\n : \"Click to request\"}\n </span>\n </span>\n </button>\n {(secret.provider || secret.name) && (\n <details className=\"group/details border-t border-border/60 px-3 py-1.5 text-xs text-muted-foreground/75\">\n <summary className=\"flex cursor-pointer list-none items-center gap-1.5 text-[11px] hover:text-muted-foreground [&::-webkit-details-marker]:hidden\">\n <IconChevronDown className=\"h-3 w-3 transition-transform group-open/details:rotate-180\" />\n Details\n </summary>\n <div className=\"mt-1.5 space-y-1 pb-0.5 pl-4\">\n <div className=\"truncate\">\n Provider: {secret.provider || \"Not specified\"}\n </div>\n <div className=\"truncate\">Name: {secret.name}</div>\n </div>\n </details>\n )}\n </div>\n );\n })\n )}\n </div>\n <div className=\"flex items-center justify-end gap-2\">\n <Button\n type=\"button\"\n size=\"sm\"\n onClick={submitWithSelectedKeys}\n disabled={!prompt.trim() || isSubmitting}\n >\n {isSubmitting ? (\n <IconLoader2 className=\"h-3.5 w-3.5 animate-spin\" />\n ) : (\n <IconPlus className=\"h-3.5 w-3.5\" />\n )}\n Create app\n </Button>\n </div>\n {!prompt.trim() ? (\n <p className=\"px-1 text-[11px] text-muted-foreground/70\">\n Add a prompt on the previous step before creating the app.\n </p>\n ) : null}\n </>\n )}\n\n {statusMessage ? (\n <div className=\"rounded-md border border-border bg-muted/40 px-3 py-2 text-xs text-muted-foreground\">\n {statusMessage}\n {branchUrl ? (\n <a\n href={branchUrl}\n target=\"_blank\"\n rel=\"noreferrer\"\n className=\"ml-2 inline-flex items-center gap-1 font-medium text-foreground underline\"\n >\n Open branch <IconArrowUpRight className=\"h-3 w-3\" />\n </a>\n ) : null}\n </div>\n ) : null}\n </div>\n );\n}\n\nexport function CreateAppPopover({\n trigger,\n align = \"center\",\n}: CreateAppPopoverProps) {\n const [open, setOpen] = useState(false);\n return (\n <Popover open={open} onOpenChange={setOpen}>\n <PopoverTrigger asChild>\n {trigger ?? (\n <button\n type=\"button\"\n className=\"flex min-h-32 cursor-pointer items-center justify-center rounded-lg border border-dashed bg-card p-4 text-sm font-medium text-muted-foreground transition hover:border-foreground/30 hover:text-foreground\"\n >\n <span className=\"inline-flex items-center gap-2\">\n <IconPlus size={16} />\n Create app\n </span>\n </button>\n )}\n </PopoverTrigger>\n <PopoverContent\n align={align}\n sideOffset={10}\n className=\"w-[calc(100vw-2rem)] rounded-xl p-3 shadow-xl sm:w-[460px]\"\n >\n <CreateAppFlow onClose={() => setOpen(false)} />\n </PopoverContent>\n </Popover>\n );\n}\n"]}
1
+ {"version":3,"file":"create-app-popover.js","sourceRoot":"","sources":["../../src/components/create-app-popover.tsx"],"names":[],"mappings":"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","sourcesContent":["import { useEffect, useMemo, useState, type ReactNode } from \"react\";\nimport {\n PromptComposer,\n agentNativePath,\n appBasePath,\n isInBuilderFrame,\n sendToAgentChat,\n useDevMode,\n} from \"@agent-native/core/client\";\nimport { getWorkspaceAppIdValidationError } from \"@agent-native/core/shared\";\nimport {\n IconArrowLeft,\n IconArrowUpRight,\n IconBook,\n IconCheck,\n IconChevronDown,\n IconFileText,\n IconKey,\n IconLoader2,\n IconPlus,\n} from \"@tabler/icons-react\";\nimport {\n Popover,\n PopoverContent,\n PopoverTrigger,\n} from \"@/components/ui/popover\";\nimport { Button } from \"@/components/ui/button\";\n\ninterface VaultSecretOption {\n id: string;\n name: string;\n credentialKey: string;\n provider?: string | null;\n description?: string | null;\n}\n\ninterface WorkspaceResourceOption {\n id: string;\n kind: \"skill\" | \"instruction\" | \"agent\" | \"knowledge\";\n name: string;\n description?: string | null;\n path: string;\n scope: \"all\" | \"selected\";\n updatedAt?: number;\n}\n\ninterface CreateAppPopoverProps {\n /**\n * Custom trigger element. Defaults to a dashed-border tile that matches the\n * apps grid empty state.\n */\n trigger?: ReactNode;\n /**\n * Override the popover alignment. Defaults to \"center\" with a 10px offset.\n */\n align?: \"start\" | \"center\" | \"end\";\n}\n\nfunction slugify(value: string): string {\n return value\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, \"-\")\n .replace(/^-+|-+$/g, \"\")\n .replace(/^[^a-z]+/, \"\")\n .slice(0, 48);\n}\n\nfunction titleFromPrompt(prompt: string): string {\n const cleaned = prompt\n .replace(/\\b(build|create|make|an?|the|app|tool|dashboard)\\b/gi, \" \")\n .replace(/\\s+/g, \" \")\n .trim();\n return slugify(cleaned || \"new-app\") || \"new-app\";\n}\n\nfunction buildAppCreationPrompt(input: {\n appId: string;\n prompt: string;\n selectedKeys: string[];\n selectedResources: WorkspaceResourceOption[];\n}): string {\n const keyList = input.selectedKeys.join(\", \");\n const grantRequest = keyList\n ? `Requested Dispatch vault key grants for this app: ${keyList}`\n : `Requested Dispatch vault key grants for this app: none`;\n const resourceList = input.selectedResources.length\n ? input.selectedResources\n .map(\n (resource) =>\n `- ${resource.name} (${resource.kind}, ${resource.path})`,\n )\n .join(\"\\n\")\n : \"none\";\n\n return [\n `Create a new agent-native app in this workspace.`,\n `This is a new workspace app request, not a feature request for the current app.`,\n ``,\n `Suggested app name: ${input.appId} (you may adjust the slug if it conflicts)`,\n `User prompt: ${input.prompt.trim()}`,\n grantRequest,\n `Requested Dispatch workspace resources for this app:\\n${resourceList}`,\n ``,\n `Pick a starter template that fits the user's prompt — analytics, calendar, content, design, dispatch, forms, mail, slides, clips, or starter when none of the others fit.`,\n `Use the workspace app layout: create it under apps/${input.appId}, mount it at /${input.appId}, keep it on the shared workspace database/hosting model, and avoid table-name collisions by namespacing any new domain tables to the app.`,\n `Use relative workspace links like /${input.appId}. Do not hardcode localhost, 127.0.0.1, 8080, 8100, or any dev port; the active workspace gateway/browser origin owns the port.`,\n `Use the framework/template UI stack: shadcn/ui components and @tabler/icons-react. Do not add lucide-react or another icon library for standard UI.`,\n `Existing first-party apps are neighbors, not implementation details for this app. If the user's prompt mentions Mail, Calendar, Analytics, Dispatch, or other templates, treat them as existing hosted/connected apps that this app can link to or call through A2A/default connected agents. For example, Mail, Calendar, and Analytics already exist at https://mail.agent-native.com, https://calendar.agent-native.com, and https://analytics.agent-native.com.`,\n `Do not clone first-party templates, create wrapper apps, or scaffold child apps/routes for Mail, Calendar, Analytics, etc. inside apps/${input.appId} just so this app can access them. If the request is a cross-app dashboard or overview, build only the new dashboard/overview app and delegate to the existing apps for domain work.`,\n `Only create another first-party app copy when the user explicitly asks for a customized fork/copy of that app; otherwise keep using the hosted/shared app so improvements to the base template keep flowing to users.`,\n `Do not satisfy this by adding a route, page, component, or file inside apps/starter or another existing app unless the user explicitly asks to modify that existing app.`,\n keyList\n ? `After the app exists, grant the selected Dispatch vault keys to appId \"${input.appId}\" and sync them once the app server is available. Treat these as requested grants, not active grants before creation succeeds.`\n : `Do not grant any Dispatch vault keys unless the user asks later.`,\n input.selectedResources.length\n ? `After the app exists, grant the selected Dispatch workspace resources to appId \"${input.appId}\" and sync them once the app server is available. Add a short note to apps/${input.appId}/AGENTS.md telling the app agent to read relevant shared resources under context/ or the selected resource paths before doing GTM/domain work.`\n : `Do not grant any Dispatch workspace resources unless the user asks later.`,\n ``,\n `App readiness requirements before handing off:`,\n `- Ensure apps/${input.appId}/package.json exists; Dispatch discovers workspace apps from apps/<app-id>/package.json, not a separate app registry.`,\n `- Update the app manifest/package/deploy metadata needed by the existing workspace deployment model.`,\n `- Ensure the React Router client entry preserves APP_BASE_PATH/VITE_APP_BASE_PATH via appBasePath() so /${input.appId} hydrates correctly.`,\n `- Verify the app's agent card/A2A metadata is ready so Dispatch can discover and delegate to the app after deployment.`,\n `When it is ready, start or update the workspace dev server and navigate the user to /${input.appId}.`,\n ].join(\"\\n\");\n}\n\nasync function fetchJson(url: string, init?: RequestInit): Promise<any> {\n const res = await fetch(url, init);\n const data = await res.json().catch(() => null);\n if (!res.ok) {\n throw new Error(\n data?.error || data?.message || `Request failed ${res.status}`,\n );\n }\n return data;\n}\n\nfunction defaultDispatchBasePath(): string | null {\n const base = appBasePath();\n if (base === \"/dispatch\") return null;\n return null;\n}\n\nfunction actionUrl(basePath: string | null, action: string): string {\n const path = `/_agent-native/actions/${action}`;\n if (basePath === null) return agentNativePath(path);\n const normalized = basePath.replace(/\\/+$/, \"\");\n return `${normalized}${path}`;\n}\n\n/**\n * Inline two-step app-creation flow: prompt → optional access picker → submit.\n * Used both in the popover form and in the dedicated `/new-app` page so the\n * same UX shows up everywhere a teammate kicks off a new workspace app.\n */\nexport function CreateAppFlow({\n onClose,\n className = \"\",\n}: {\n onClose?: () => void;\n className?: string;\n}) {\n const [step, setStep] = useState<\"prompt\" | \"access\">(\"prompt\");\n const [prompt, setPrompt] = useState(\"\");\n const [selectedSecretIds, setSelectedSecretIds] = useState<string[]>([]);\n const [selectedResourceIds, setSelectedResourceIds] = useState<string[]>([]);\n const [secrets, setSecrets] = useState<VaultSecretOption[]>([]);\n const [resources, setResources] = useState<WorkspaceResourceOption[]>([]);\n const [secretsError, setSecretsError] = useState<string | null>(null);\n const [resourcesError, setResourcesError] = useState<string | null>(null);\n const [statusMessage, setStatusMessage] = useState<string | null>(null);\n const [branchUrl, setBranchUrl] = useState<string | null>(null);\n const [isSubmitting, setIsSubmitting] = useState(false);\n const { isDevMode } = useDevMode();\n\n const basePath = useMemo(() => defaultDispatchBasePath(), []);\n\n // Fetch access options eagerly so step 2 has them ready immediately.\n useEffect(() => {\n let cancelled = false;\n fetchJson(actionUrl(basePath, \"list-vault-secret-options\"))\n .then((data) => {\n if (cancelled) return;\n setSecrets(Array.isArray(data) ? data : []);\n setSecretsError(null);\n })\n .catch((err) => {\n if (cancelled) return;\n setSecrets([]);\n setSecretsError(err?.message || \"Could not load Dispatch keys\");\n });\n fetchJson(actionUrl(basePath, \"list-workspace-resource-options\"))\n .then((data) => {\n if (cancelled) return;\n setResources(Array.isArray(data) ? data : []);\n setResourcesError(null);\n })\n .catch((err) => {\n if (cancelled) return;\n setResources([]);\n setResourcesError(err?.message || \"Could not load Dispatch resources\");\n });\n return () => {\n cancelled = true;\n };\n }, [basePath]);\n\n const selectedSecrets = useMemo(\n () => secrets.filter((s) => selectedSecretIds.includes(s.id)),\n [secrets, selectedSecretIds],\n );\n const selectedResources = useMemo(\n () => resources.filter((r) => selectedResourceIds.includes(r.id)),\n [resources, selectedResourceIds],\n );\n const selectedSecretLabel =\n selectedSecretIds.length === 0\n ? \"no keys\"\n : `${selectedSecretIds.length} key${selectedSecretIds.length === 1 ? \"\" : \"s\"}`;\n const selectedResourceLabel =\n selectedResourceIds.length === 0\n ? \"no resources\"\n : `${selectedResourceIds.length} resource${selectedResourceIds.length === 1 ? \"\" : \"s\"}`;\n const selectedAccessLabel = [selectedSecretLabel, selectedResourceLabel].join(\n \" · \",\n );\n\n function toggleSecret(id: string) {\n setSelectedSecretIds((cur) =>\n cur.includes(id) ? cur.filter((x) => x !== id) : [...cur, id],\n );\n }\n\n function toggleResource(id: string) {\n setSelectedResourceIds((cur) =>\n cur.includes(id) ? cur.filter((x) => x !== id) : [...cur, id],\n );\n }\n\n async function submit(rawPrompt: string) {\n const trimmed = rawPrompt.trim();\n if (!trimmed || isSubmitting) return;\n const appId = titleFromPrompt(trimmed);\n const validationError = getWorkspaceAppIdValidationError(appId);\n if (validationError) {\n setStatusMessage(validationError);\n return;\n }\n\n const message = buildAppCreationPrompt({\n appId,\n prompt: trimmed,\n selectedKeys: selectedSecrets.map((s) => s.credentialKey),\n selectedResources,\n });\n setIsSubmitting(true);\n setStatusMessage(null);\n setBranchUrl(null);\n\n try {\n if (isInBuilderFrame()) {\n sendToAgentChat({ message, submit: true, type: \"code\" });\n setStatusMessage(\"Sent to Builder chat.\");\n onClose?.();\n } else if (isDevMode) {\n sendToAgentChat({ message, submit: true, type: \"code\", newTab: true });\n setStatusMessage(\"Sent to the local agent.\");\n onClose?.();\n } else {\n const result = await fetchJson(\n actionUrl(basePath, \"start-workspace-app-creation\"),\n {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({\n prompt: trimmed,\n appId,\n secretIds: selectedSecretIds.length > 0 ? selectedSecretIds : [],\n resourceIds:\n selectedResourceIds.length > 0 ? selectedResourceIds : [],\n }),\n },\n );\n if (result?.mode === \"builder\") {\n setBranchUrl(result?.url || null);\n setStatusMessage(\"Builder branch created.\");\n } else {\n setStatusMessage(\n result?.message ||\n \"Builder app creation is coming soon. Open this workspace in Builder to create an app from this prompt.\",\n );\n }\n }\n } catch (err: any) {\n setStatusMessage(err?.message || \"Could not start the new app flow.\");\n } finally {\n setIsSubmitting(false);\n }\n }\n\n const submitWithSelectedAccess = () => submit(prompt);\n\n return (\n <div className={`flex flex-col gap-3 ${className}`}>\n {step === \"prompt\" ? (\n <>\n <div className=\"flex items-center justify-between gap-2 px-1\">\n <p className=\"text-sm font-semibold text-foreground\">Create app</p>\n <button\n type=\"button\"\n onClick={() => setStep(\"access\")}\n className=\"inline-flex cursor-pointer items-center gap-1 rounded-md border border-border bg-background/40 px-2 py-1 text-[11px] text-muted-foreground hover:text-foreground hover:bg-accent/50\"\n >\n <IconKey size={11} />\n {selectedAccessLabel}\n </button>\n </div>\n <PromptComposer\n autoFocus\n disabled={isSubmitting}\n placeholder=\"Describe the app your teammate should be able to use...\"\n draftScope=\"dispatch:create-app\"\n onSubmit={(text) => {\n setPrompt(text);\n submit(text);\n }}\n />\n </>\n ) : (\n <>\n <div className=\"flex items-center justify-between gap-2 px-1\">\n <button\n type=\"button\"\n onClick={() => setStep(\"prompt\")}\n className=\"inline-flex cursor-pointer items-center gap-1 text-xs text-muted-foreground hover:text-foreground\"\n >\n <IconArrowLeft size={12} />\n Back\n </button>\n <span className=\"text-[11px] text-muted-foreground/70\">\n {selectedAccessLabel}\n </span>\n </div>\n <div className=\"max-h-[180px] space-y-2 overflow-y-auto rounded-md border border-border bg-card p-2\">\n <div className=\"flex items-center gap-1.5 px-1 pb-1 text-[11px] font-medium text-muted-foreground\">\n <IconKey size={12} />\n Dispatch keys\n </div>\n {secretsError ? (\n <p className=\"rounded-md border border-dashed border-border px-3 py-3 text-xs text-muted-foreground\">\n {secretsError}\n </p>\n ) : secrets.length === 0 ? (\n <p className=\"rounded-md border border-dashed border-border px-3 py-3 text-xs text-muted-foreground\">\n No Dispatch vault keys found yet.\n </p>\n ) : (\n secrets.map((secret) => {\n const selected = selectedSecretIds.includes(secret.id);\n return (\n <div\n key={secret.id}\n className={`group rounded-md border text-sm ${\n selected\n ? \"border-primary/45 bg-primary/5\"\n : \"border-border hover:border-muted-foreground/40 hover:bg-accent/35\"\n }`}\n >\n <button\n type=\"button\"\n aria-pressed={selected}\n onClick={() => toggleSecret(secret.id)}\n className=\"flex w-full cursor-pointer items-start gap-3 rounded-md px-3 py-2 text-left\"\n >\n <span\n className={`mt-0.5 flex h-4 w-4 shrink-0 items-center justify-center rounded border ${\n selected\n ? \"border-primary/60 bg-primary/10 text-primary\"\n : \"border-muted-foreground/35 text-transparent\"\n }`}\n >\n {selected ? <IconCheck className=\"h-3 w-3\" /> : null}\n </span>\n <span className=\"min-w-0 flex-1\">\n <span className=\"block truncate font-medium\">\n {secret.credentialKey}\n </span>\n <span className=\"block truncate text-xs text-muted-foreground/70\">\n {selected\n ? \"Will be requested for this app\"\n : \"Click to request\"}\n </span>\n </span>\n </button>\n {(secret.provider || secret.name) && (\n <details className=\"group/details border-t border-border/60 px-3 py-1.5 text-xs text-muted-foreground/75\">\n <summary className=\"flex cursor-pointer list-none items-center gap-1.5 text-[11px] hover:text-muted-foreground [&::-webkit-details-marker]:hidden\">\n <IconChevronDown className=\"h-3 w-3 transition-transform group-open/details:rotate-180\" />\n Details\n </summary>\n <div className=\"mt-1.5 space-y-1 pb-0.5 pl-4\">\n <div className=\"truncate\">\n Provider: {secret.provider || \"Not specified\"}\n </div>\n <div className=\"truncate\">Name: {secret.name}</div>\n </div>\n </details>\n )}\n </div>\n );\n })\n )}\n </div>\n <div className=\"max-h-[180px] space-y-2 overflow-y-auto rounded-md border border-border bg-card p-2\">\n <div className=\"flex items-center gap-1.5 px-1 pb-1 text-[11px] font-medium text-muted-foreground\">\n <IconBook size={12} />\n Resource packs\n </div>\n {resourcesError ? (\n <p className=\"rounded-md border border-dashed border-border px-3 py-3 text-xs text-muted-foreground\">\n {resourcesError}\n </p>\n ) : resources.length === 0 ? (\n <p className=\"rounded-md border border-dashed border-border px-3 py-3 text-xs text-muted-foreground\">\n No Dispatch resource packs found yet.\n </p>\n ) : (\n resources.map((resource) => {\n const selected = selectedResourceIds.includes(resource.id);\n return (\n <div\n key={resource.id}\n className={`group rounded-md border text-sm ${\n selected\n ? \"border-primary/45 bg-primary/5\"\n : \"border-border hover:border-muted-foreground/40 hover:bg-accent/35\"\n }`}\n >\n <button\n type=\"button\"\n aria-pressed={selected}\n onClick={() => toggleResource(resource.id)}\n className=\"flex w-full cursor-pointer items-start gap-3 rounded-md px-3 py-2 text-left\"\n >\n <span\n className={`mt-0.5 flex h-4 w-4 shrink-0 items-center justify-center rounded border ${\n selected\n ? \"border-primary/60 bg-primary/10 text-primary\"\n : \"border-muted-foreground/35 text-transparent\"\n }`}\n >\n {selected ? <IconCheck className=\"h-3 w-3\" /> : null}\n </span>\n <span className=\"min-w-0 flex-1\">\n <span className=\"flex min-w-0 items-center gap-1.5\">\n <IconFileText className=\"h-3.5 w-3.5 shrink-0 text-muted-foreground/70\" />\n <span className=\"block truncate font-medium\">\n {resource.name}\n </span>\n </span>\n <span className=\"block truncate text-xs text-muted-foreground/70\">\n {resource.kind} · {resource.path}\n </span>\n </span>\n </button>\n <details className=\"group/details border-t border-border/60 px-3 py-1.5 text-xs text-muted-foreground/75\">\n <summary className=\"flex cursor-pointer list-none items-center gap-1.5 text-[11px] hover:text-muted-foreground [&::-webkit-details-marker]:hidden\">\n <IconChevronDown className=\"h-3 w-3 transition-transform group-open/details:rotate-180\" />\n Details\n </summary>\n <div className=\"mt-1.5 space-y-1 pb-0.5 pl-4\">\n <div className=\"truncate\">\n Scope:{\" \"}\n {resource.scope === \"all\"\n ? \"All apps\"\n : \"Selected apps\"}\n </div>\n {resource.description ? (\n <div className=\"line-clamp-2\">\n {resource.description}\n </div>\n ) : null}\n </div>\n </details>\n </div>\n );\n })\n )}\n </div>\n <div className=\"flex items-center justify-end gap-2\">\n <Button\n type=\"button\"\n size=\"sm\"\n onClick={submitWithSelectedAccess}\n disabled={!prompt.trim() || isSubmitting}\n >\n {isSubmitting ? (\n <IconLoader2 className=\"h-3.5 w-3.5 animate-spin\" />\n ) : (\n <IconPlus className=\"h-3.5 w-3.5\" />\n )}\n Create app\n </Button>\n </div>\n {!prompt.trim() ? (\n <p className=\"px-1 text-[11px] text-muted-foreground/70\">\n Add a prompt on the previous step before creating the app.\n </p>\n ) : null}\n </>\n )}\n\n {statusMessage ? (\n <div className=\"rounded-md border border-border bg-muted/40 px-3 py-2 text-xs text-muted-foreground\">\n {statusMessage}\n {branchUrl ? (\n <a\n href={branchUrl}\n target=\"_blank\"\n rel=\"noreferrer\"\n className=\"ml-2 inline-flex items-center gap-1 font-medium text-foreground underline\"\n >\n Open branch <IconArrowUpRight className=\"h-3 w-3\" />\n </a>\n ) : null}\n </div>\n ) : null}\n </div>\n );\n}\n\nexport function CreateAppPopover({\n trigger,\n align = \"center\",\n}: CreateAppPopoverProps) {\n const [open, setOpen] = useState(false);\n return (\n <Popover open={open} onOpenChange={setOpen}>\n <PopoverTrigger asChild>\n {trigger ?? (\n <button\n type=\"button\"\n className=\"flex min-h-32 cursor-pointer items-center justify-center rounded-lg border border-dashed bg-card p-4 text-sm font-medium text-muted-foreground transition hover:border-foreground/30 hover:text-foreground\"\n >\n <span className=\"inline-flex items-center gap-2\">\n <IconPlus size={16} />\n Create app\n </span>\n </button>\n )}\n </PopoverTrigger>\n <PopoverContent\n align={align}\n sideOffset={10}\n className=\"w-[calc(100vw-2rem)] rounded-xl p-3 shadow-xl sm:w-[460px]\"\n >\n <CreateAppFlow onClose={() => setOpen(false)} />\n </PopoverContent>\n </Popover>\n );\n}\n"]}
@@ -0,0 +1,6 @@
1
+ import { type WorkspaceAppSummary } from "../lib/workspace-apps.js";
2
+ export declare function WorkspaceAppCard({ app, className, }: {
3
+ app: WorkspaceAppSummary;
4
+ className?: string;
5
+ }): import("react/jsx-runtime").JSX.Element;
6
+ //# sourceMappingURL=workspace-app-card.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"workspace-app-card.d.ts","sourceRoot":"","sources":["../../src/components/workspace-app-card.tsx"],"names":[],"mappings":"AAIA,OAAO,EAGL,KAAK,mBAAmB,EACzB,MAAM,sBAAsB,CAAC;AAE9B,wBAAgB,gBAAgB,CAAC,EAC/B,GAAG,EACH,SAAS,GACV,EAAE;IACD,GAAG,EAAE,mBAAmB,CAAC;IACzB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,2CAoEA"}
@@ -0,0 +1,12 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { IconArrowUpRight, IconClockHour4 } from "@tabler/icons-react";
3
+ import { AppKeysPopover } from "../components/app-keys-popover.js";
4
+ import { Badge } from "../components/ui/badge.js";
5
+ import { cn } from "../lib/utils.js";
6
+ import { isPendingBuilderHref, workspaceAppHref, } from "../lib/workspace-apps.js";
7
+ export function WorkspaceAppCard({ app, className, }) {
8
+ const href = workspaceAppHref(app);
9
+ const openInNewTab = isPendingBuilderHref(app);
10
+ return (_jsxs("div", { "aria-disabled": !href, className: cn("group relative rounded-lg border bg-card p-4 transition hover:border-foreground/30 aria-disabled:opacity-60", className), children: [href ? (_jsx("a", { href: href, target: openInNewTab ? "_blank" : undefined, rel: openInNewTab ? "noreferrer" : undefined, "aria-label": `Open ${app.name}`, className: "absolute inset-0 z-0 rounded-lg" })) : null, _jsxs("div", { className: "pointer-events-none relative z-10 flex h-full items-start justify-between gap-3", children: [_jsxs("div", { className: "min-w-0", children: [_jsxs("div", { className: "flex min-w-0 items-center gap-2", children: [_jsx("h3", { className: "truncate text-sm font-semibold text-foreground", children: app.name }), app.status === "pending" ? (_jsxs(Badge, { variant: "outline", className: "shrink-0 gap-1 border-amber-500/30 bg-amber-500/10 text-amber-700 dark:text-amber-300", children: [_jsx(IconClockHour4, { size: 12 }), "Building"] })) : null] }), _jsx("p", { className: "mt-1 truncate font-mono text-xs text-muted-foreground", children: app.path }), app.status === "pending" && app.branchName ? (_jsxs("p", { className: "mt-1 truncate text-xs text-muted-foreground", children: ["Branch: ", app.branchName] })) : null, app.description ? (_jsx("p", { className: "mt-2 line-clamp-2 text-xs leading-relaxed text-muted-foreground", children: app.description })) : null] }), _jsxs("div", { className: "flex shrink-0 items-center gap-1", children: [app.status === "ready" ? (_jsx("div", { className: "pointer-events-auto", children: _jsx(AppKeysPopover, { appId: app.id, appName: app.name }) })) : null, href ? (_jsx(IconArrowUpRight, { size: 16, className: "text-muted-foreground transition group-hover:text-foreground" })) : null] })] })] }));
11
+ }
12
+ //# sourceMappingURL=workspace-app-card.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"workspace-app-card.js","sourceRoot":"","sources":["../../src/components/workspace-app-card.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACvE,OAAO,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC;AAC/D,OAAO,EAAE,KAAK,EAAE,MAAM,uBAAuB,CAAC;AAC9C,OAAO,EAAE,EAAE,EAAE,MAAM,aAAa,CAAC;AACjC,OAAO,EACL,oBAAoB,EACpB,gBAAgB,GAEjB,MAAM,sBAAsB,CAAC;AAE9B,MAAM,UAAU,gBAAgB,CAAC,EAC/B,GAAG,EACH,SAAS,GAIV;IACC,MAAM,IAAI,GAAG,gBAAgB,CAAC,GAAG,CAAC,CAAC;IACnC,MAAM,YAAY,GAAG,oBAAoB,CAAC,GAAG,CAAC,CAAC;IAE/C,OAAO,CACL,gCACiB,CAAC,IAAI,EACpB,SAAS,EAAE,EAAE,CACX,6GAA6G,EAC7G,SAAS,CACV,aAEA,IAAI,CAAC,CAAC,CAAC,CACN,YACE,IAAI,EAAE,IAAI,EACV,MAAM,EAAE,YAAY,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,SAAS,EAC3C,GAAG,EAAE,YAAY,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,SAAS,gBAChC,QAAQ,GAAG,CAAC,IAAI,EAAE,EAC9B,SAAS,EAAC,iCAAiC,GAC3C,CACH,CAAC,CAAC,CAAC,IAAI,EAER,eAAK,SAAS,EAAC,iFAAiF,aAC9F,eAAK,SAAS,EAAC,SAAS,aACtB,eAAK,SAAS,EAAC,iCAAiC,aAC9C,aAAI,SAAS,EAAC,gDAAgD,YAC3D,GAAG,CAAC,IAAI,GACN,EACJ,GAAG,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,CAC1B,MAAC,KAAK,IACJ,OAAO,EAAC,SAAS,EACjB,SAAS,EAAC,uFAAuF,aAEjG,KAAC,cAAc,IAAC,IAAI,EAAE,EAAE,GAAI,gBAEtB,CACT,CAAC,CAAC,CAAC,IAAI,IACJ,EACN,YAAG,SAAS,EAAC,uDAAuD,YACjE,GAAG,CAAC,IAAI,GACP,EACH,GAAG,CAAC,MAAM,KAAK,SAAS,IAAI,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,CAC5C,aAAG,SAAS,EAAC,6CAA6C,yBAC/C,GAAG,CAAC,UAAU,IACrB,CACL,CAAC,CAAC,CAAC,IAAI,EACP,GAAG,CAAC,WAAW,CAAC,CAAC,CAAC,CACjB,YAAG,SAAS,EAAC,iEAAiE,YAC3E,GAAG,CAAC,WAAW,GACd,CACL,CAAC,CAAC,CAAC,IAAI,IACJ,EACN,eAAK,SAAS,EAAC,kCAAkC,aAC9C,GAAG,CAAC,MAAM,KAAK,OAAO,CAAC,CAAC,CAAC,CACxB,cAAK,SAAS,EAAC,qBAAqB,YAClC,KAAC,cAAc,IAAC,KAAK,EAAE,GAAG,CAAC,EAAE,EAAE,OAAO,EAAE,GAAG,CAAC,IAAI,GAAI,GAChD,CACP,CAAC,CAAC,CAAC,IAAI,EACP,IAAI,CAAC,CAAC,CAAC,CACN,KAAC,gBAAgB,IACf,IAAI,EAAE,EAAE,EACR,SAAS,EAAC,8DAA8D,GACxE,CACH,CAAC,CAAC,CAAC,IAAI,IACJ,IACF,IACF,CACP,CAAC;AACJ,CAAC","sourcesContent":["import { IconArrowUpRight, IconClockHour4 } from \"@tabler/icons-react\";\nimport { AppKeysPopover } from \"@/components/app-keys-popover\";\nimport { Badge } from \"@/components/ui/badge\";\nimport { cn } from \"@/lib/utils\";\nimport {\n isPendingBuilderHref,\n workspaceAppHref,\n type WorkspaceAppSummary,\n} from \"@/lib/workspace-apps\";\n\nexport function WorkspaceAppCard({\n app,\n className,\n}: {\n app: WorkspaceAppSummary;\n className?: string;\n}) {\n const href = workspaceAppHref(app);\n const openInNewTab = isPendingBuilderHref(app);\n\n return (\n <div\n aria-disabled={!href}\n className={cn(\n \"group relative rounded-lg border bg-card p-4 transition hover:border-foreground/30 aria-disabled:opacity-60\",\n className,\n )}\n >\n {href ? (\n <a\n href={href}\n target={openInNewTab ? \"_blank\" : undefined}\n rel={openInNewTab ? \"noreferrer\" : undefined}\n aria-label={`Open ${app.name}`}\n className=\"absolute inset-0 z-0 rounded-lg\"\n />\n ) : null}\n\n <div className=\"pointer-events-none relative z-10 flex h-full items-start justify-between gap-3\">\n <div className=\"min-w-0\">\n <div className=\"flex min-w-0 items-center gap-2\">\n <h3 className=\"truncate text-sm font-semibold text-foreground\">\n {app.name}\n </h3>\n {app.status === \"pending\" ? (\n <Badge\n variant=\"outline\"\n className=\"shrink-0 gap-1 border-amber-500/30 bg-amber-500/10 text-amber-700 dark:text-amber-300\"\n >\n <IconClockHour4 size={12} />\n Building\n </Badge>\n ) : null}\n </div>\n <p className=\"mt-1 truncate font-mono text-xs text-muted-foreground\">\n {app.path}\n </p>\n {app.status === \"pending\" && app.branchName ? (\n <p className=\"mt-1 truncate text-xs text-muted-foreground\">\n Branch: {app.branchName}\n </p>\n ) : null}\n {app.description ? (\n <p className=\"mt-2 line-clamp-2 text-xs leading-relaxed text-muted-foreground\">\n {app.description}\n </p>\n ) : null}\n </div>\n <div className=\"flex shrink-0 items-center gap-1\">\n {app.status === \"ready\" ? (\n <div className=\"pointer-events-auto\">\n <AppKeysPopover appId={app.id} appName={app.name} />\n </div>\n ) : null}\n {href ? (\n <IconArrowUpRight\n size={16}\n className=\"text-muted-foreground transition group-hover:text-foreground\"\n />\n ) : null}\n </div>\n </div>\n </div>\n );\n}\n"]}
package/dist/db/schema.js CHANGED
@@ -119,12 +119,12 @@ export const vaultAuditLog = table("vault_audit_log", {
119
119
  metadata: text("metadata"),
120
120
  createdAt: integer("created_at").notNull(),
121
121
  });
122
- // ─── Workspace Resources: shared skills, instructions, agents ──────
122
+ // ─── Workspace Resources: shared skills, instructions, agents, knowledge ──────
123
123
  export const workspaceResources = table("workspace_resources", {
124
124
  id: text("id").primaryKey(),
125
125
  ownerEmail: text("owner_email").notNull(),
126
126
  orgId: text("org_id"),
127
- kind: text("kind").notNull(), // "skill" | "instruction" | "agent"
127
+ kind: text("kind").notNull(), // "skill" | "instruction" | "agent" | "knowledge"
128
128
  name: text("name").notNull(),
129
129
  description: text("description"),
130
130
  path: text("path").notNull(), // resource path, e.g. "skills/designer.md"
@@ -1 +1 @@
1
- {"version":3,"file":"schema.js","sourceRoot":"","sources":["../../src/db/schema.ts"],"names":[],"mappings":"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","sourcesContent":["import { table, text, integer } from \"@agent-native/core/db/schema\";\n\nexport const dispatchDestinations = table(\"dispatch_destinations\", {\n id: text(\"id\").primaryKey(),\n ownerEmail: text(\"owner_email\").notNull(),\n orgId: text(\"org_id\"),\n name: text(\"name\").notNull(),\n platform: text(\"platform\").notNull(),\n destination: text(\"destination\").notNull(),\n threadRef: text(\"thread_ref\"),\n notes: text(\"notes\"),\n createdBy: text(\"created_by\").notNull(),\n createdAt: integer(\"created_at\").notNull(),\n updatedAt: integer(\"updated_at\").notNull(),\n});\n\nexport const dispatchIdentityLinks = table(\"dispatch_identity_links\", {\n id: text(\"id\").primaryKey(),\n ownerEmail: text(\"owner_email\").notNull(),\n orgId: text(\"org_id\"),\n platform: text(\"platform\").notNull(),\n externalUserId: text(\"external_user_id\").notNull(),\n externalUserName: text(\"external_user_name\"),\n linkedBy: text(\"linked_by\").notNull(),\n createdAt: integer(\"created_at\").notNull(),\n updatedAt: integer(\"updated_at\").notNull(),\n});\n\nexport const dispatchLinkTokens = table(\"dispatch_link_tokens\", {\n id: text(\"id\").primaryKey(),\n token: text(\"token\").notNull(),\n ownerEmail: text(\"owner_email\").notNull(),\n orgId: text(\"org_id\"),\n platform: text(\"platform\").notNull(),\n createdBy: text(\"created_by\").notNull(),\n expiresAt: integer(\"expires_at\").notNull(),\n claimedAt: integer(\"claimed_at\"),\n claimedByExternalUserId: text(\"claimed_by_external_user_id\"),\n claimedByExternalUserName: text(\"claimed_by_external_user_name\"),\n createdAt: integer(\"created_at\").notNull(),\n updatedAt: integer(\"updated_at\").notNull(),\n});\n\nexport const dispatchApprovalRequests = table(\"dispatch_approval_requests\", {\n id: text(\"id\").primaryKey(),\n ownerEmail: text(\"owner_email\").notNull(),\n orgId: text(\"org_id\"),\n changeType: text(\"change_type\").notNull(),\n targetType: text(\"target_type\").notNull(),\n targetId: text(\"target_id\"),\n status: text(\"status\").notNull(),\n summary: text(\"summary\").notNull(),\n payload: text(\"payload\").notNull(),\n beforeValue: text(\"before_value\"),\n afterValue: text(\"after_value\"),\n requestedBy: text(\"requested_by\").notNull(),\n reviewedBy: text(\"reviewed_by\"),\n reviewedAt: integer(\"reviewed_at\"),\n createdAt: integer(\"created_at\").notNull(),\n updatedAt: integer(\"updated_at\").notNull(),\n});\n\nexport const dispatchAuditEvents = table(\"dispatch_audit_events\", {\n id: text(\"id\").primaryKey(),\n ownerEmail: text(\"owner_email\").notNull(),\n orgId: text(\"org_id\"),\n actor: text(\"actor\").notNull(),\n action: text(\"action\").notNull(),\n targetType: text(\"target_type\").notNull(),\n targetId: text(\"target_id\"),\n summary: text(\"summary\").notNull(),\n metadata: text(\"metadata\"),\n createdAt: integer(\"created_at\").notNull(),\n});\n\n// ─── Vault: workspace-wide secret management ───────────────────────\n\nexport const vaultSecrets = table(\"vault_secrets\", {\n id: text(\"id\").primaryKey(),\n ownerEmail: text(\"owner_email\").notNull(),\n orgId: text(\"org_id\"),\n name: text(\"name\").notNull(),\n credentialKey: text(\"credential_key\").notNull(),\n value: text(\"value\").notNull(),\n provider: text(\"provider\"),\n description: text(\"description\"),\n createdBy: text(\"created_by\").notNull(),\n createdAt: integer(\"created_at\").notNull(),\n updatedAt: integer(\"updated_at\").notNull(),\n});\n\nexport const vaultGrants = table(\"vault_grants\", {\n id: text(\"id\").primaryKey(),\n ownerEmail: text(\"owner_email\").notNull(),\n orgId: text(\"org_id\"),\n secretId: text(\"secret_id\").notNull(),\n appId: text(\"app_id\").notNull(),\n grantedBy: text(\"granted_by\").notNull(),\n status: text(\"status\").notNull(),\n syncedAt: integer(\"synced_at\"),\n createdAt: integer(\"created_at\").notNull(),\n updatedAt: integer(\"updated_at\").notNull(),\n});\n\nexport const vaultRequests = table(\"vault_requests\", {\n id: text(\"id\").primaryKey(),\n ownerEmail: text(\"owner_email\").notNull(),\n orgId: text(\"org_id\"),\n credentialKey: text(\"credential_key\").notNull(),\n appId: text(\"app_id\").notNull(),\n reason: text(\"reason\"),\n requestedBy: text(\"requested_by\").notNull(),\n status: text(\"status\").notNull(),\n reviewedBy: text(\"reviewed_by\"),\n reviewedAt: integer(\"reviewed_at\"),\n createdAt: integer(\"created_at\").notNull(),\n updatedAt: integer(\"updated_at\").notNull(),\n});\n\nexport const vaultAuditLog = table(\"vault_audit_log\", {\n id: text(\"id\").primaryKey(),\n ownerEmail: text(\"owner_email\").notNull(),\n orgId: text(\"org_id\"),\n secretId: text(\"secret_id\"),\n appId: text(\"app_id\"),\n action: text(\"action\").notNull(),\n actor: text(\"actor\").notNull(),\n summary: text(\"summary\").notNull(),\n metadata: text(\"metadata\"),\n createdAt: integer(\"created_at\").notNull(),\n});\n\n// ─── Workspace Resources: shared skills, instructions, agents ──────\n\nexport const workspaceResources = table(\"workspace_resources\", {\n id: text(\"id\").primaryKey(),\n ownerEmail: text(\"owner_email\").notNull(),\n orgId: text(\"org_id\"),\n kind: text(\"kind\").notNull(), // \"skill\" | \"instruction\" | \"agent\"\n name: text(\"name\").notNull(),\n description: text(\"description\"),\n path: text(\"path\").notNull(), // resource path, e.g. \"skills/designer.md\"\n content: text(\"content\").notNull(),\n scope: text(\"scope\").notNull(), // \"all\" (push to all apps) | \"selected\" (grant per-app)\n createdBy: text(\"created_by\").notNull(),\n createdAt: integer(\"created_at\").notNull(),\n updatedAt: integer(\"updated_at\").notNull(),\n});\n\nexport const workspaceResourceGrants = table(\"workspace_resource_grants\", {\n id: text(\"id\").primaryKey(),\n ownerEmail: text(\"owner_email\").notNull(),\n orgId: text(\"org_id\"),\n resourceId: text(\"resource_id\").notNull(),\n appId: text(\"app_id\").notNull(),\n status: text(\"status\").notNull(), // \"active\" | \"revoked\"\n syncedAt: integer(\"synced_at\"),\n createdAt: integer(\"created_at\").notNull(),\n updatedAt: integer(\"updated_at\").notNull(),\n});\n"]}
1
+ {"version":3,"file":"schema.js","sourceRoot":"","sources":["../../src/db/schema.ts"],"names":[],"mappings":"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","sourcesContent":["import { table, text, integer } from \"@agent-native/core/db/schema\";\n\nexport const dispatchDestinations = table(\"dispatch_destinations\", {\n id: text(\"id\").primaryKey(),\n ownerEmail: text(\"owner_email\").notNull(),\n orgId: text(\"org_id\"),\n name: text(\"name\").notNull(),\n platform: text(\"platform\").notNull(),\n destination: text(\"destination\").notNull(),\n threadRef: text(\"thread_ref\"),\n notes: text(\"notes\"),\n createdBy: text(\"created_by\").notNull(),\n createdAt: integer(\"created_at\").notNull(),\n updatedAt: integer(\"updated_at\").notNull(),\n});\n\nexport const dispatchIdentityLinks = table(\"dispatch_identity_links\", {\n id: text(\"id\").primaryKey(),\n ownerEmail: text(\"owner_email\").notNull(),\n orgId: text(\"org_id\"),\n platform: text(\"platform\").notNull(),\n externalUserId: text(\"external_user_id\").notNull(),\n externalUserName: text(\"external_user_name\"),\n linkedBy: text(\"linked_by\").notNull(),\n createdAt: integer(\"created_at\").notNull(),\n updatedAt: integer(\"updated_at\").notNull(),\n});\n\nexport const dispatchLinkTokens = table(\"dispatch_link_tokens\", {\n id: text(\"id\").primaryKey(),\n token: text(\"token\").notNull(),\n ownerEmail: text(\"owner_email\").notNull(),\n orgId: text(\"org_id\"),\n platform: text(\"platform\").notNull(),\n createdBy: text(\"created_by\").notNull(),\n expiresAt: integer(\"expires_at\").notNull(),\n claimedAt: integer(\"claimed_at\"),\n claimedByExternalUserId: text(\"claimed_by_external_user_id\"),\n claimedByExternalUserName: text(\"claimed_by_external_user_name\"),\n createdAt: integer(\"created_at\").notNull(),\n updatedAt: integer(\"updated_at\").notNull(),\n});\n\nexport const dispatchApprovalRequests = table(\"dispatch_approval_requests\", {\n id: text(\"id\").primaryKey(),\n ownerEmail: text(\"owner_email\").notNull(),\n orgId: text(\"org_id\"),\n changeType: text(\"change_type\").notNull(),\n targetType: text(\"target_type\").notNull(),\n targetId: text(\"target_id\"),\n status: text(\"status\").notNull(),\n summary: text(\"summary\").notNull(),\n payload: text(\"payload\").notNull(),\n beforeValue: text(\"before_value\"),\n afterValue: text(\"after_value\"),\n requestedBy: text(\"requested_by\").notNull(),\n reviewedBy: text(\"reviewed_by\"),\n reviewedAt: integer(\"reviewed_at\"),\n createdAt: integer(\"created_at\").notNull(),\n updatedAt: integer(\"updated_at\").notNull(),\n});\n\nexport const dispatchAuditEvents = table(\"dispatch_audit_events\", {\n id: text(\"id\").primaryKey(),\n ownerEmail: text(\"owner_email\").notNull(),\n orgId: text(\"org_id\"),\n actor: text(\"actor\").notNull(),\n action: text(\"action\").notNull(),\n targetType: text(\"target_type\").notNull(),\n targetId: text(\"target_id\"),\n summary: text(\"summary\").notNull(),\n metadata: text(\"metadata\"),\n createdAt: integer(\"created_at\").notNull(),\n});\n\n// ─── Vault: workspace-wide secret management ───────────────────────\n\nexport const vaultSecrets = table(\"vault_secrets\", {\n id: text(\"id\").primaryKey(),\n ownerEmail: text(\"owner_email\").notNull(),\n orgId: text(\"org_id\"),\n name: text(\"name\").notNull(),\n credentialKey: text(\"credential_key\").notNull(),\n value: text(\"value\").notNull(),\n provider: text(\"provider\"),\n description: text(\"description\"),\n createdBy: text(\"created_by\").notNull(),\n createdAt: integer(\"created_at\").notNull(),\n updatedAt: integer(\"updated_at\").notNull(),\n});\n\nexport const vaultGrants = table(\"vault_grants\", {\n id: text(\"id\").primaryKey(),\n ownerEmail: text(\"owner_email\").notNull(),\n orgId: text(\"org_id\"),\n secretId: text(\"secret_id\").notNull(),\n appId: text(\"app_id\").notNull(),\n grantedBy: text(\"granted_by\").notNull(),\n status: text(\"status\").notNull(),\n syncedAt: integer(\"synced_at\"),\n createdAt: integer(\"created_at\").notNull(),\n updatedAt: integer(\"updated_at\").notNull(),\n});\n\nexport const vaultRequests = table(\"vault_requests\", {\n id: text(\"id\").primaryKey(),\n ownerEmail: text(\"owner_email\").notNull(),\n orgId: text(\"org_id\"),\n credentialKey: text(\"credential_key\").notNull(),\n appId: text(\"app_id\").notNull(),\n reason: text(\"reason\"),\n requestedBy: text(\"requested_by\").notNull(),\n status: text(\"status\").notNull(),\n reviewedBy: text(\"reviewed_by\"),\n reviewedAt: integer(\"reviewed_at\"),\n createdAt: integer(\"created_at\").notNull(),\n updatedAt: integer(\"updated_at\").notNull(),\n});\n\nexport const vaultAuditLog = table(\"vault_audit_log\", {\n id: text(\"id\").primaryKey(),\n ownerEmail: text(\"owner_email\").notNull(),\n orgId: text(\"org_id\"),\n secretId: text(\"secret_id\"),\n appId: text(\"app_id\"),\n action: text(\"action\").notNull(),\n actor: text(\"actor\").notNull(),\n summary: text(\"summary\").notNull(),\n metadata: text(\"metadata\"),\n createdAt: integer(\"created_at\").notNull(),\n});\n\n// ─── Workspace Resources: shared skills, instructions, agents, knowledge ──────\n\nexport const workspaceResources = table(\"workspace_resources\", {\n id: text(\"id\").primaryKey(),\n ownerEmail: text(\"owner_email\").notNull(),\n orgId: text(\"org_id\"),\n kind: text(\"kind\").notNull(), // \"skill\" | \"instruction\" | \"agent\" | \"knowledge\"\n name: text(\"name\").notNull(),\n description: text(\"description\"),\n path: text(\"path\").notNull(), // resource path, e.g. \"skills/designer.md\"\n content: text(\"content\").notNull(),\n scope: text(\"scope\").notNull(), // \"all\" (push to all apps) | \"selected\" (grant per-app)\n createdBy: text(\"created_by\").notNull(),\n createdAt: integer(\"created_at\").notNull(),\n updatedAt: integer(\"updated_at\").notNull(),\n});\n\nexport const workspaceResourceGrants = table(\"workspace_resource_grants\", {\n id: text(\"id\").primaryKey(),\n ownerEmail: text(\"owner_email\").notNull(),\n orgId: text(\"org_id\"),\n resourceId: text(\"resource_id\").notNull(),\n appId: text(\"app_id\").notNull(),\n status: text(\"status\").notNull(), // \"active\" | \"revoked\"\n syncedAt: integer(\"synced_at\"),\n createdAt: integer(\"created_at\").notNull(),\n updatedAt: integer(\"updated_at\").notNull(),\n});\n"]}
@@ -0,0 +1,15 @@
1
+ export interface WorkspaceAppSummary {
2
+ id: string;
3
+ name: string;
4
+ description?: string;
5
+ path: string;
6
+ url?: string | null;
7
+ isDispatch?: boolean;
8
+ status?: "ready" | "pending";
9
+ statusLabel?: string;
10
+ builderUrl?: string | null;
11
+ branchName?: string | null;
12
+ }
13
+ export declare function workspaceAppHref(app: WorkspaceAppSummary): string | null;
14
+ export declare function isPendingBuilderHref(app: WorkspaceAppSummary): boolean;
15
+ //# sourceMappingURL=workspace-apps.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"workspace-apps.d.ts","sourceRoot":"","sources":["../../src/lib/workspace-apps.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,mBAAmB;IAClC,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,MAAM,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IAC7B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC5B;AAED,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,mBAAmB,GAAG,MAAM,GAAG,IAAI,CAGxE;AAED,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,mBAAmB,GAAG,OAAO,CAEtE"}
@@ -0,0 +1,9 @@
1
+ export function workspaceAppHref(app) {
2
+ if (app.status === "pending")
3
+ return app.builderUrl || null;
4
+ return app.path || app.url || null;
5
+ }
6
+ export function isPendingBuilderHref(app) {
7
+ return app.status === "pending" && !!app.builderUrl;
8
+ }
9
+ //# sourceMappingURL=workspace-apps.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"workspace-apps.js","sourceRoot":"","sources":["../../src/lib/workspace-apps.ts"],"names":[],"mappings":"AAaA,MAAM,UAAU,gBAAgB,CAAC,GAAwB;IACvD,IAAI,GAAG,CAAC,MAAM,KAAK,SAAS;QAAE,OAAO,GAAG,CAAC,UAAU,IAAI,IAAI,CAAC;IAC5D,OAAO,GAAG,CAAC,IAAI,IAAI,GAAG,CAAC,GAAG,IAAI,IAAI,CAAC;AACrC,CAAC;AAED,MAAM,UAAU,oBAAoB,CAAC,GAAwB;IAC3D,OAAO,GAAG,CAAC,MAAM,KAAK,SAAS,IAAI,CAAC,CAAC,GAAG,CAAC,UAAU,CAAC;AACtD,CAAC","sourcesContent":["export interface WorkspaceAppSummary {\n id: string;\n name: string;\n description?: string;\n path: string;\n url?: string | null;\n isDispatch?: boolean;\n status?: \"ready\" | \"pending\";\n statusLabel?: string;\n builderUrl?: string | null;\n branchName?: string | null;\n}\n\nexport function workspaceAppHref(app: WorkspaceAppSummary): string | null {\n if (app.status === \"pending\") return app.builderUrl || null;\n return app.path || app.url || null;\n}\n\nexport function isPendingBuilderHref(app: WorkspaceAppSummary): boolean {\n return app.status === \"pending\" && !!app.builderUrl;\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"apps.$appId.d.ts","sourceRoot":"","sources":["../../../src/routes/pages/apps.$appId.tsx"],"names":[],"mappings":"AA6BA,wBAAgB,IAAI;;IAEnB;AAED,MAAM,CAAC,OAAO,UAAU,iBAAiB,4CAoGxC"}
1
+ {"version":3,"file":"apps.$appId.d.ts","sourceRoot":"","sources":["../../../src/routes/pages/apps.$appId.tsx"],"names":[],"mappings":"AAgBA,wBAAgB,IAAI;;IAEnB;AAED,MAAM,CAAC,OAAO,UAAU,iBAAiB,4CAoGxC"}
@@ -6,11 +6,7 @@ import { IconArrowLeft, IconArrowUpRight, IconClockHour4, } from "@tabler/icons-
6
6
  import { DispatchShell } from "../../components/dispatch-shell.js";
7
7
  import { Badge } from "../../components/ui/badge.js";
8
8
  import { Button } from "../../components/ui/button.js";
9
- function workspaceAppHref(app) {
10
- if (app.status === "pending")
11
- return app.builderUrl || null;
12
- return app.path || app.url || null;
13
- }
9
+ import { workspaceAppHref, } from "../../lib/workspace-apps.js";
14
10
  export function meta() {
15
11
  return [{ title: "Workspace app - Dispatch" }];
16
12
  }