@agent-native/dispatch 0.2.14 → 0.2.16
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.
- package/dist/components/create-app-popover.d.ts.map +1 -1
- package/dist/components/create-app-popover.js +2 -1
- package/dist/components/create-app-popover.js.map +1 -1
- package/dist/server/lib/app-creation-store.d.ts.map +1 -1
- package/dist/server/lib/app-creation-store.js +29 -0
- package/dist/server/lib/app-creation-store.js.map +1 -1
- package/package.json +2 -2
- package/src/components/create-app-popover.tsx +2 -0
- package/src/server/lib/app-creation-store.spec.ts +51 -0
- package/src/server/lib/app-creation-store.ts +40 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"create-app-popover.d.ts","sourceRoot":"","sources":["../../src/components/create-app-popover.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAgC,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AA8CrE,UAAU,qBAAqB;IAC7B;;;OAGG;IACH,OAAO,CAAC,EAAE,SAAS,CAAC;IACpB;;OAEG;IACH,KAAK,CAAC,EAAE,OAAO,GAAG,QAAQ,GAAG,KAAK,CAAC;CACpC;
|
|
1
|
+
{"version":3,"file":"create-app-popover.d.ts","sourceRoot":"","sources":["../../src/components/create-app-popover.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAgC,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AA8CrE,UAAU,qBAAqB;IAC7B;;;OAGG;IACH,OAAO,CAAC,EAAE,SAAS,CAAC;IACpB;;OAEG;IACH,KAAK,CAAC,EAAE,OAAO,GAAG,QAAQ,GAAG,KAAK,CAAC;CACpC;AAkGD;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,EAC5B,OAAO,EACP,SAAc,GACf,EAAE;IACD,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,2CAiXA;AAED,wBAAgB,gBAAgB,CAAC,EAC/B,OAAO,EACP,KAAgB,GACjB,EAAE,qBAAqB,2CA0BvB"}
|
|
@@ -36,6 +36,7 @@ function buildAppCreationPrompt(input) {
|
|
|
36
36
|
``,
|
|
37
37
|
`Suggested app name: ${input.appId} (you may adjust the slug if it conflicts)`,
|
|
38
38
|
`User prompt: ${input.prompt.trim()}`,
|
|
39
|
+
`If the user mentions a product or company such as Granola, Loom, Superhuman, Linear, or Notion, treat it as product inspiration unless they explicitly ask to connect to that service. Do not invent or require third-party API keys like GRANOLA_API_KEY just because a product is named.`,
|
|
39
40
|
grantRequest,
|
|
40
41
|
`Requested Dispatch workspace resources for this app:\n${resourceList}`,
|
|
41
42
|
``,
|
|
@@ -211,7 +212,7 @@ export function CreateAppFlow({ onClose, className = "", }) {
|
|
|
211
212
|
}
|
|
212
213
|
}
|
|
213
214
|
const submitWithSelectedAccess = () => submit(prompt);
|
|
214
|
-
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) => {
|
|
215
|
+
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", preserveDraftOnSubmit: true, onSubmit: (text) => {
|
|
215
216
|
setPrompt(text);
|
|
216
217
|
submit(text);
|
|
217
218
|
} })] })) : (_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) => {
|
|
@@ -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 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 `Important routing rule: from outside the app, link to /${input.appId}; inside apps/${input.appId}, React Router routes are app-local. Use <Link to=\"/review\"> and navigate(\"/review\"), not \"/${input.appId}/review\"; APP_BASE_PATH supplies the mounted prefix, and hardcoding it causes doubled URLs like /${input.appId}/${input.appId}/review.`,\n `Prefer useActionQuery/useActionMutation for actions. If you must raw-fetch framework endpoints, wrap them with agentNativePath(\"/_agent-native/actions/<name>\") so mounted apps call the right URL.`,\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"]}
|
|
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 `If the user mentions a product or company such as Granola, Loom, Superhuman, Linear, or Notion, treat it as product inspiration unless they explicitly ask to connect to that service. Do not invent or require third-party API keys like GRANOLA_API_KEY just because a product is named.`,\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 `Important routing rule: from outside the app, link to /${input.appId}; inside apps/${input.appId}, React Router routes are app-local. Use <Link to=\"/review\"> and navigate(\"/review\"), not \"/${input.appId}/review\"; APP_BASE_PATH supplies the mounted prefix, and hardcoding it causes doubled URLs like /${input.appId}/${input.appId}/review.`,\n `Prefer useActionQuery/useActionMutation for actions. If you must raw-fetch framework endpoints, wrap them with agentNativePath(\"/_agent-native/actions/<name>\") so mounted apps call the right URL.`,\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 preserveDraftOnSubmit\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"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"app-creation-store.d.ts","sourceRoot":"","sources":["../../../src/server/lib/app-creation-store.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"app-creation-store.d.ts","sourceRoot":"","sources":["../../../src/server/lib/app-creation-store.ts"],"names":[],"mappings":"AAqCA,MAAM,WAAW,mBAAmB;IAClC,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IACnB,UAAU,EAAE,OAAO,CAAC;IACpB,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;IAC3B,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,cAAc,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,gBAAgB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAClC;AAED,MAAM,WAAW,wBAAwB;IACvC,iBAAiB,CAAC,EAAE,OAAO,CAAC;CAC7B;AAED,MAAM,WAAW,mBAAmB;IAClC,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,sBAAsB,EAAE,KAAK,GAAG,UAAU,GAAG,SAAS,GAAG,OAAO,CAAC;IACjE,mBAAmB,EAAE,MAAM,GAAG,IAAI,CAAC;IACnC,qBAAqB,EAAE,MAAM,GAAG,IAAI,CAAC;IACrC,uBAAuB,EAAE,OAAO,CAAC;CAClC;AAED,MAAM,WAAW,aAAa;IAC5B,sFAAsF;IACtF,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,qEAAqE;IACrE,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,wDAAwD;IACxD,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,uDAAuD;IACvD,QAAQ,EAAE,MAAM,CAAC;CAClB;AAwdD,wBAAgB,sBAAsB,IAAI,MAAM,GAAG,IAAI,CAOtD;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,IAAI,aAAa,CAiChD;AAED,wBAAsB,iBAAiB,CACrC,OAAO,GAAE,wBAA6B,GACrC,OAAO,CAAC,mBAAmB,EAAE,CAAC,CAoDhC;AAED,wBAAsB,sBAAsB,IAAI,OAAO,CAAC,mBAAmB,CAAC,CA6B3E;AAED,wBAAsB,sBAAsB,CAAC,KAAK,EAAE;IAClD,gBAAgB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAClC,GAAG,OAAO,CAAC,mBAAmB,CAAC,CAe/B;AA6QD,wBAAsB,yBAAyB,CAAC,KAAK,EAAE;IACrD,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;CACxB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgIA"}
|
|
@@ -12,6 +12,8 @@ import { grantWorkspaceResourcesToApp, listWorkspaceResourceOptions, } from "./w
|
|
|
12
12
|
const SETTINGS_KEY = "dispatch-app-creation-settings";
|
|
13
13
|
const WORKSPACE_APPS_ENV_KEY = "AGENT_NATIVE_WORKSPACE_APPS_JSON";
|
|
14
14
|
const WORKSPACE_APPS_MANIFEST_FILE = "workspace-apps.json";
|
|
15
|
+
const WORKSPACE_APPS_GATEWAY_PATH = "/_workspace/apps";
|
|
16
|
+
const WORKSPACE_APPS_GATEWAY_TIMEOUT_MS = 1_000;
|
|
15
17
|
const MAX_PENDING_APPS = 50;
|
|
16
18
|
const AGENT_CARD_PATH = "/.well-known/agent-card.json";
|
|
17
19
|
const AGENT_CARD_FETCH_TIMEOUT_MS = 1_500;
|
|
@@ -335,6 +337,28 @@ function readWorkspaceAppsFromEnv() {
|
|
|
335
337
|
return null;
|
|
336
338
|
}
|
|
337
339
|
}
|
|
340
|
+
async function readWorkspaceAppsFromGateway() {
|
|
341
|
+
const base = process.env.WORKSPACE_GATEWAY_URL;
|
|
342
|
+
if (!base)
|
|
343
|
+
return null;
|
|
344
|
+
const controller = new AbortController();
|
|
345
|
+
const timeout = setTimeout(() => controller.abort(), WORKSPACE_APPS_GATEWAY_TIMEOUT_MS);
|
|
346
|
+
try {
|
|
347
|
+
const response = await fetch(new URL(WORKSPACE_APPS_GATEWAY_PATH, `${base.replace(/\/$/, "")}/`), {
|
|
348
|
+
headers: { accept: "application/json" },
|
|
349
|
+
signal: controller.signal,
|
|
350
|
+
});
|
|
351
|
+
if (!response.ok)
|
|
352
|
+
return null;
|
|
353
|
+
return parseWorkspaceAppsManifest(await response.json().catch(() => null));
|
|
354
|
+
}
|
|
355
|
+
catch {
|
|
356
|
+
return null;
|
|
357
|
+
}
|
|
358
|
+
finally {
|
|
359
|
+
clearTimeout(timeout);
|
|
360
|
+
}
|
|
361
|
+
}
|
|
338
362
|
function workspaceAppsManifestCandidates() {
|
|
339
363
|
const candidates = [];
|
|
340
364
|
try {
|
|
@@ -436,6 +460,10 @@ export function getWorkspaceInfo() {
|
|
|
436
460
|
};
|
|
437
461
|
}
|
|
438
462
|
export async function listWorkspaceApps(options = {}) {
|
|
463
|
+
const gatewayApps = await readWorkspaceAppsFromGateway();
|
|
464
|
+
if (gatewayApps) {
|
|
465
|
+
return maybeIncludeAgentCards(await appendPendingWorkspaceApps(gatewayApps), options);
|
|
466
|
+
}
|
|
439
467
|
const workspaceRoot = findWorkspaceRoot();
|
|
440
468
|
const localFilesystemApps = workspaceRoot && isLocalAppCreationRuntime()
|
|
441
469
|
? readWorkspaceAppsFromFilesystem(workspaceRoot)
|
|
@@ -661,6 +689,7 @@ function buildWorkspaceAppPrompt(input) {
|
|
|
661
689
|
`App name: ${appId}`,
|
|
662
690
|
`Template to start from: ${input.template || "starter"}`,
|
|
663
691
|
`User prompt: ${input.prompt.trim()}`,
|
|
692
|
+
"If the user mentions a product or company such as Granola, Loom, Superhuman, Linear, or Notion, treat it as product inspiration unless they explicitly ask to connect to that service. Do not invent or require third-party API keys like GRANOLA_API_KEY just because a product is named.",
|
|
664
693
|
selectedKeys.length
|
|
665
694
|
? `Dispatch vault keys selected for this app: ${selectedKeys.join(", ")}`
|
|
666
695
|
: "Dispatch vault keys selected for this app: none",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"app-creation-store.js","sourceRoot":"","sources":["../../../src/server/lib/app-creation-store.ts"],"names":[],"mappings":"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","sourcesContent":["import fs from \"node:fs\";\nimport path from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport { getSetting, putSetting } from \"@agent-native/core/settings\";\nimport {\n getBuilderBranchProjectId,\n getRequestContext,\n isIntegrationCallerRequest,\n resolveBuilderBranchProjectId,\n resolveBuilderCredentials,\n runBuilderAgent,\n} from \"@agent-native/core/server\";\nimport { getDbExec } from \"@agent-native/core/db\";\nimport { assertValidWorkspaceAppId } from \"@agent-native/core/shared\";\nimport {\n currentOrgId,\n currentOwnerEmail,\n recordAudit,\n resolveLinkedOwner,\n} from \"./dispatch-store.js\";\nimport { identityKeyForIncoming } from \"./dispatch-integrations.js\";\nimport { createRequest, listSecrets } from \"./vault-store.js\";\nimport {\n grantWorkspaceResourcesToApp,\n listWorkspaceResourceOptions,\n type WorkspaceResourceOption,\n} from \"./workspace-resources-store.js\";\n\nconst SETTINGS_KEY = \"dispatch-app-creation-settings\";\nconst WORKSPACE_APPS_ENV_KEY = \"AGENT_NATIVE_WORKSPACE_APPS_JSON\";\nconst WORKSPACE_APPS_MANIFEST_FILE = \"workspace-apps.json\";\nconst MAX_PENDING_APPS = 50;\nconst AGENT_CARD_PATH = \"/.well-known/agent-card.json\";\nconst AGENT_CARD_FETCH_TIMEOUT_MS = 1_500;\n\nexport 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 createdAt?: string | null;\n agentCardUrl?: string | null;\n agentCardReachable?: boolean;\n a2aEndpointUrl?: string | null;\n agentName?: string | null;\n agentSkillsCount?: number | null;\n}\n\nexport interface ListWorkspaceAppsOptions {\n includeAgentCards?: boolean;\n}\n\nexport interface AppCreationSettings {\n builderProjectId: string | null;\n builderProjectIdSource: \"env\" | \"dispatch\" | \"default\" | \"unset\";\n envBuilderProjectId: string | null;\n savedBuilderProjectId: string | null;\n builderBranchingEnabled: boolean;\n}\n\nexport interface WorkspaceInfo {\n /** Slug from the workspace root package.json `name` (e.g. \"on-call-todo-manager\"). */\n name: string | null;\n /** Title-cased version for display (e.g. \"On Call Todo Manager\"). */\n displayName: string | null;\n /** Absolute path to the workspace root, if detected. */\n rootPath: string | null;\n /** Number of apps currently scaffolded under apps/. */\n appCount: number;\n}\n\ninterface PendingWorkspaceApp {\n id: string;\n name: string;\n description: string;\n path: string;\n builderUrl: string | null;\n branchName: string | null;\n projectId: string | null;\n createdAt: string;\n updatedAt: string;\n}\n\nfunction readJson(file: string): any {\n try {\n return JSON.parse(fs.readFileSync(file, \"utf8\"));\n } catch {\n return null;\n }\n}\n\nfunction findWorkspaceRoot(startDir = process.cwd()): string | null {\n let dir = path.resolve(startDir);\n for (let i = 0; i < 20; i++) {\n const pkg = readJson(path.join(dir, \"package.json\"));\n if (typeof pkg?.[\"agent-native\"]?.workspaceCore === \"string\") {\n return dir;\n }\n const parent = path.dirname(dir);\n if (parent === dir) break;\n dir = parent;\n }\n return null;\n}\n\nfunction titleCase(value: string): string {\n return value\n .split(/[-_\\s]+/)\n .filter(Boolean)\n .map((part) => part.charAt(0).toUpperCase() + part.slice(1))\n .join(\" \");\n}\n\nfunction scopedSettingsKey(): string {\n const orgId = currentOrgId();\n if (orgId) return `${SETTINGS_KEY}:org:${orgId}`;\n return `${SETTINGS_KEY}:user:${currentOwnerEmail()}`;\n}\n\nasync function readSettingsRecord(): Promise<Record<string, any>> {\n const raw = await getSetting(scopedSettingsKey()).catch(() => null);\n return raw && typeof raw === \"object\" && !Array.isArray(raw)\n ? (raw as Record<string, any>)\n : {};\n}\n\nfunction workspaceAppUrl(appPath: string): string | null {\n const base =\n process.env.WORKSPACE_GATEWAY_URL ||\n process.env.APP_URL ||\n process.env.URL ||\n process.env.DEPLOY_URL ||\n process.env.BETTER_AUTH_URL ||\n null;\n if (!base) return null;\n try {\n return new URL(appPath, `${base.replace(/\\/$/, \"\")}/`).toString();\n } catch {\n return null;\n }\n}\n\nfunction workspaceAppLink(\n appPath: string,\n explicitUrl?: unknown,\n): string | null {\n const urlValue = typeof explicitUrl === \"string\" ? explicitUrl.trim() : \"\";\n if (!urlValue) return workspaceAppUrl(appPath);\n if (urlValue.startsWith(\"/\")) return workspaceAppUrl(urlValue) ?? urlValue;\n try {\n return new URL(urlValue).toString();\n } catch {\n return urlValue;\n }\n}\n\nfunction parseWorkspaceAppsManifest(parsed: any): WorkspaceAppSummary[] | null {\n const rawApps = Array.isArray(parsed?.apps)\n ? parsed.apps\n : Array.isArray(parsed)\n ? parsed\n : null;\n if (!rawApps) return null;\n\n const apps = rawApps\n .map((entry): WorkspaceAppSummary | null => {\n if (!entry || typeof entry !== \"object\") return null;\n const id = typeof entry.id === \"string\" ? entry.id.trim() : \"\";\n const pathValue = typeof entry.path === \"string\" ? entry.path.trim() : \"\";\n if (!id || !pathValue.startsWith(\"/\")) return null;\n return {\n id,\n name:\n typeof entry.name === \"string\" && entry.name.trim()\n ? entry.name.trim()\n : titleCase(id),\n description:\n typeof entry.description === \"string\" ? entry.description : \"\",\n path: pathValue,\n url: workspaceAppLink(pathValue, entry.url),\n isDispatch:\n typeof entry.isDispatch === \"boolean\"\n ? entry.isDispatch\n : id === \"dispatch\",\n status: \"ready\",\n } satisfies WorkspaceAppSummary;\n })\n .filter((app): app is WorkspaceAppSummary => !!app)\n .sort(sortWorkspaceApps);\n\n return apps.length ? apps : null;\n}\n\nfunction sortWorkspaceApps(a: WorkspaceAppSummary, b: WorkspaceAppSummary) {\n if (a.id === \"dispatch\") return -1;\n if (b.id === \"dispatch\") return 1;\n if (a.status === \"pending\" && b.status !== \"pending\") return 1;\n if (a.status !== \"pending\" && b.status === \"pending\") return -1;\n return a.name.localeCompare(b.name);\n}\n\nfunction parsePendingWorkspaceApps(value: unknown): PendingWorkspaceApp[] {\n if (!Array.isArray(value)) return [];\n return value\n .map((entry) => {\n if (!entry || typeof entry !== \"object\") return null;\n const record = entry as Record<string, unknown>;\n const id = typeof record.id === \"string\" ? record.id.trim() : \"\";\n const pathValue =\n typeof record.path === \"string\" ? record.path.trim() : \"\";\n if (!id || !pathValue.startsWith(\"/\")) return null;\n const now = new Date().toISOString();\n return {\n id,\n name:\n typeof record.name === \"string\" && record.name.trim()\n ? record.name.trim()\n : titleCase(id),\n description:\n typeof record.description === \"string\"\n ? record.description\n : \"Builder is creating this app. The workspace path becomes live after the branch is merged and deployed.\",\n path: pathValue,\n builderUrl:\n typeof record.builderUrl === \"string\" && record.builderUrl.trim()\n ? record.builderUrl.trim()\n : null,\n branchName:\n typeof record.branchName === \"string\" && record.branchName.trim()\n ? record.branchName.trim()\n : null,\n projectId:\n typeof record.projectId === \"string\" && record.projectId.trim()\n ? record.projectId.trim()\n : null,\n createdAt:\n typeof record.createdAt === \"string\" && record.createdAt.trim()\n ? record.createdAt.trim()\n : now,\n updatedAt:\n typeof record.updatedAt === \"string\" && record.updatedAt.trim()\n ? record.updatedAt.trim()\n : now,\n } satisfies PendingWorkspaceApp;\n })\n .filter((app): app is PendingWorkspaceApp => !!app)\n .slice(0, MAX_PENDING_APPS);\n}\n\nasync function listPendingWorkspaceApps(): Promise<PendingWorkspaceApp[]> {\n const raw = await readSettingsRecord();\n return parsePendingWorkspaceApps(raw.pendingApps);\n}\n\nfunction pendingAppToSummary(app: PendingWorkspaceApp): WorkspaceAppSummary {\n return {\n id: app.id,\n name: app.name,\n description: app.description,\n path: app.path,\n url: app.builderUrl,\n isDispatch: false,\n status: \"pending\",\n statusLabel: \"Building in Builder\",\n builderUrl: app.builderUrl,\n branchName: app.branchName,\n createdAt: app.createdAt,\n };\n}\n\nasync function appendPendingWorkspaceApps(\n apps: WorkspaceAppSummary[],\n): Promise<WorkspaceAppSummary[]> {\n const readyIds = new Set(apps.map((app) => app.id));\n const pendingApps = (await listPendingWorkspaceApps())\n .filter((app) => !readyIds.has(app.id))\n .map(pendingAppToSummary);\n return [...apps, ...pendingApps].sort(sortWorkspaceApps);\n}\n\nfunction agentCardUrlForApp(appUrl: string | null): string | null {\n if (!appUrl) return null;\n const trimmed = appUrl.replace(/\\/+$/, \"\");\n if (!trimmed) return null;\n try {\n return new URL(`${trimmed}${AGENT_CARD_PATH}`).toString();\n } catch {\n return `${trimmed}${AGENT_CARD_PATH}`;\n }\n}\n\nfunction stringField(\n record: Record<string, unknown>,\n key: string,\n): string | null {\n const value = record[key];\n return typeof value === \"string\" && value.trim() ? value.trim() : null;\n}\n\nfunction numberOfSkills(card: Record<string, unknown>): number | null {\n return Array.isArray(card.skills) ? card.skills.length : null;\n}\n\nasync function fetchAgentCardMetadata(\n app: WorkspaceAppSummary,\n): Promise<\n Pick<\n WorkspaceAppSummary,\n | \"agentCardUrl\"\n | \"agentCardReachable\"\n | \"a2aEndpointUrl\"\n | \"agentName\"\n | \"agentSkillsCount\"\n >\n> {\n const agentCardUrl = agentCardUrlForApp(app.url);\n if (!agentCardUrl) {\n return {\n agentCardUrl: null,\n agentCardReachable: false,\n a2aEndpointUrl: null,\n agentName: null,\n agentSkillsCount: null,\n };\n }\n\n const controller = new AbortController();\n const timeout = setTimeout(\n () => controller.abort(),\n AGENT_CARD_FETCH_TIMEOUT_MS,\n );\n\n try {\n const response = await fetch(agentCardUrl, {\n headers: { accept: \"application/json\" },\n signal: controller.signal,\n });\n if (!response.ok) {\n return {\n agentCardUrl,\n agentCardReachable: false,\n a2aEndpointUrl: null,\n agentName: null,\n agentSkillsCount: null,\n };\n }\n\n const parsed = await response.json().catch(() => null);\n const card =\n parsed && typeof parsed === \"object\" && !Array.isArray(parsed)\n ? (parsed as Record<string, unknown>)\n : null;\n if (!card) {\n return {\n agentCardUrl,\n agentCardReachable: false,\n a2aEndpointUrl: null,\n agentName: null,\n agentSkillsCount: null,\n };\n }\n\n return {\n agentCardUrl,\n agentCardReachable: true,\n a2aEndpointUrl:\n stringField(card, \"url\") ?? stringField(card, \"endpointUrl\"),\n agentName: stringField(card, \"name\"),\n agentSkillsCount: numberOfSkills(card),\n };\n } catch {\n return {\n agentCardUrl,\n agentCardReachable: false,\n a2aEndpointUrl: null,\n agentName: null,\n agentSkillsCount: null,\n };\n } finally {\n clearTimeout(timeout);\n }\n}\n\nasync function maybeIncludeAgentCards(\n apps: WorkspaceAppSummary[],\n options: ListWorkspaceAppsOptions,\n): Promise<WorkspaceAppSummary[]> {\n if (!options.includeAgentCards) return apps;\n return Promise.all(\n apps.map(async (app) => {\n if (app.status === \"pending\") return app;\n const metadata = await fetchAgentCardMetadata(app);\n return { ...app, ...metadata };\n }),\n );\n}\n\nasync function recordPendingWorkspaceApp(input: {\n appId: string;\n projectId: string | null;\n branchName?: string | null;\n builderUrl?: string | null;\n}) {\n const now = new Date().toISOString();\n const raw = await readSettingsRecord();\n const pendingApps = parsePendingWorkspaceApps(raw.pendingApps);\n const existing = pendingApps.find((app) => app.id === input.appId);\n const next: PendingWorkspaceApp = {\n id: input.appId,\n name: titleCase(input.appId),\n description:\n \"Builder is creating this app. The workspace path becomes live after the branch is merged and deployed.\",\n path: `/${input.appId}`,\n builderUrl: input.builderUrl?.trim() || null,\n branchName: input.branchName?.trim() || null,\n projectId: input.projectId,\n createdAt: existing?.createdAt || now,\n updatedAt: now,\n };\n\n await putSetting(scopedSettingsKey(), {\n ...raw,\n pendingApps: [\n next,\n ...pendingApps.filter((app) => app.id !== input.appId),\n ].slice(0, MAX_PENDING_APPS),\n });\n\n await recordAudit({\n action: \"workspace-app.pending\",\n targetType: \"workspace-app\",\n targetId: input.appId,\n summary: \"Started Builder branch for workspace app creation\",\n metadata: {\n builderBranchUrlConfigured: !!next.builderUrl,\n branchName: next.branchName,\n projectIdConfigured: !!next.projectId,\n },\n });\n}\n\nfunction readWorkspaceAppsFromEnv(): WorkspaceAppSummary[] | null {\n const raw = process.env[WORKSPACE_APPS_ENV_KEY];\n if (!raw) return null;\n try {\n return parseWorkspaceAppsManifest(JSON.parse(raw));\n } catch {\n return null;\n }\n}\n\nfunction workspaceAppsManifestCandidates(): string[] {\n const candidates: string[] = [];\n try {\n candidates.push(\n path.join(process.cwd(), \".agent-native\", WORKSPACE_APPS_MANIFEST_FILE),\n path.join(process.cwd(), WORKSPACE_APPS_MANIFEST_FILE),\n );\n } catch {\n // Some edge runtimes do not expose process.cwd().\n }\n try {\n const moduleDir = path.dirname(fileURLToPath(import.meta.url));\n candidates.push(\n path.join(moduleDir, \".agent-native\", WORKSPACE_APPS_MANIFEST_FILE),\n path.join(moduleDir, WORKSPACE_APPS_MANIFEST_FILE),\n );\n } catch {\n // Some edge runtimes expose non-file module URLs. The env manifest still\n // works there, so skip file-relative candidates.\n }\n return candidates;\n}\n\nfunction readWorkspaceAppsFromManifestFile(): WorkspaceAppSummary[] | null {\n for (const file of workspaceAppsManifestCandidates()) {\n if (!fs.existsSync(file)) continue;\n const apps = parseWorkspaceAppsManifest(readJson(file));\n if (apps) return apps;\n }\n return null;\n}\n\nfunction readWorkspaceAppsFromFilesystem(\n workspaceRoot: string,\n): WorkspaceAppSummary[] | null {\n const appsDir = path.join(workspaceRoot, \"apps\");\n if (!fs.existsSync(appsDir)) return null;\n\n const apps = fs\n .readdirSync(appsDir, { withFileTypes: true })\n .filter((entry) => entry.isDirectory())\n .map((entry): WorkspaceAppSummary | null => {\n const appDir = path.join(appsDir, entry.name);\n const pkg = readJson(path.join(appDir, \"package.json\"));\n if (!pkg) return null;\n return {\n id: entry.name,\n name: pkg.displayName || titleCase(entry.name),\n description: pkg.description || \"\",\n path: `/${entry.name}`,\n url: workspaceAppUrl(`/${entry.name}`),\n isDispatch: entry.name === \"dispatch\",\n status: \"ready\",\n } satisfies WorkspaceAppSummary;\n })\n .filter((app): app is WorkspaceAppSummary => !!app)\n .sort(sortWorkspaceApps);\n\n return apps.length ? apps : null;\n}\n\nexport function getEnvBuilderProjectId(): string | null {\n return (\n process.env.DISPATCH_BUILDER_PROJECT_ID ||\n process.env.BUILDER_BRANCH_PROJECT_ID ||\n process.env.BUILDER_PROJECT_ID ||\n null\n );\n}\n\n/**\n * Read the workspace's identity from the workspace root's package.json. Used to\n * surface \"Workspace: <name>\" in the Dispatch UI so first-time users can see\n * the container their apps live inside (rather than only seeing app names like\n * \"starter\" / \"dispatch\" with no parent context).\n */\nexport function getWorkspaceInfo(): WorkspaceInfo {\n const rootPath = findWorkspaceRoot();\n if (!rootPath) {\n return { name: null, displayName: null, rootPath: null, appCount: 0 };\n }\n const pkg = readJson(path.join(rootPath, \"package.json\"));\n const rawName = typeof pkg?.name === \"string\" ? pkg.name.trim() : \"\";\n // Strip a leading \"@scope/\" if the workspace root happens to be scoped.\n const name = rawName.replace(/^@[^/]+\\//, \"\") || null;\n // Honor an explicit `displayName` in the workspace package.json before\n // falling back to a title-cased version of the slug. Users naming a\n // workspace \"On-Call Todo Manager\" via `displayName` should see that\n // exact label rather than `On Call Todo Manager`.\n const rawDisplay =\n typeof pkg?.displayName === \"string\" ? pkg.displayName.trim() : \"\";\n const displayName = rawDisplay || (name ? titleCase(name) : null);\n let appCount = 0;\n const appsDir = path.join(rootPath, \"apps\");\n if (fs.existsSync(appsDir)) {\n try {\n appCount = fs\n .readdirSync(appsDir, { withFileTypes: true })\n .filter((entry) => entry.isDirectory()).length;\n } catch {\n appCount = 0;\n }\n }\n return {\n name,\n displayName,\n rootPath,\n appCount,\n };\n}\n\nexport async function listWorkspaceApps(\n options: ListWorkspaceAppsOptions = {},\n): Promise<WorkspaceAppSummary[]> {\n const workspaceRoot = findWorkspaceRoot();\n const localFilesystemApps =\n workspaceRoot && isLocalAppCreationRuntime()\n ? readWorkspaceAppsFromFilesystem(workspaceRoot)\n : null;\n if (localFilesystemApps) {\n return maybeIncludeAgentCards(\n await appendPendingWorkspaceApps(localFilesystemApps),\n options,\n );\n }\n\n const manifestApps =\n readWorkspaceAppsFromEnv() ?? readWorkspaceAppsFromManifestFile();\n if (manifestApps) {\n return maybeIncludeAgentCards(\n await appendPendingWorkspaceApps(manifestApps),\n options,\n );\n }\n\n if (!workspaceRoot) {\n return maybeIncludeAgentCards(\n await appendPendingWorkspaceApps([\n {\n id: \"dispatch\",\n name: \"Dispatch\",\n description: \"Workspace control plane\",\n path: \"/dispatch\",\n url: workspaceAppUrl(\"/dispatch\"),\n isDispatch: true,\n status: \"ready\",\n },\n ]),\n options,\n );\n }\n\n const apps = readWorkspaceAppsFromFilesystem(workspaceRoot) ?? [];\n return maybeIncludeAgentCards(\n await appendPendingWorkspaceApps(apps),\n options,\n );\n}\n\nexport async function getAppCreationSettings(): Promise<AppCreationSettings> {\n const envBuilderProjectId = getEnvBuilderProjectId();\n const resolvedBuilderProjectId = await resolveBuilderBranchProjectId();\n const raw = await readSettingsRecord();\n const savedBuilderProjectId =\n typeof raw?.builderProjectId === \"string\" && raw.builderProjectId.trim()\n ? raw.builderProjectId.trim()\n : null;\n const builderProjectId = envBuilderProjectId || savedBuilderProjectId;\n const enableBuilder =\n process.env.ENABLE_BUILDER === \"true\" || process.env.ENABLE_BUILDER === \"1\";\n const effectiveBuilderProjectId =\n builderProjectId ||\n resolvedBuilderProjectId ||\n (enableBuilder ? getBuilderBranchProjectId() : null);\n\n return {\n builderProjectId: effectiveBuilderProjectId,\n builderProjectIdSource: envBuilderProjectId\n ? \"env\"\n : savedBuilderProjectId\n ? \"dispatch\"\n : effectiveBuilderProjectId\n ? \"default\"\n : \"unset\",\n envBuilderProjectId,\n savedBuilderProjectId,\n builderBranchingEnabled: !!effectiveBuilderProjectId,\n };\n}\n\nexport async function setAppCreationSettings(input: {\n builderProjectId?: string | null;\n}): Promise<AppCreationSettings> {\n await assertCanManageAppCreationSettings();\n const builderProjectId = input.builderProjectId?.trim() || null;\n const raw = await readSettingsRecord();\n await putSetting(scopedSettingsKey(), { ...raw, builderProjectId });\n await recordAudit({\n action: \"settings.updated\",\n targetType: \"dispatch-app-creation-settings\",\n targetId: SETTINGS_KEY,\n summary: builderProjectId\n ? \"Updated default Builder project for app creation\"\n : \"Cleared default Builder project for app creation\",\n metadata: { builderProjectIdConfigured: !!builderProjectId },\n });\n return getAppCreationSettings();\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, 64);\n}\n\nfunction isLocalAppCreationRuntime(): boolean {\n if (process.env.NODE_ENV === \"production\") return false;\n if (\n process.env.NETLIFY ||\n process.env.VERCEL ||\n process.env.CF_PAGES ||\n process.env.DEPLOY_URL ||\n process.env.URL ||\n process.env.RENDER ||\n process.env.FLY_APP_NAME\n ) {\n return false;\n }\n return true;\n}\n\nfunction isSyntheticIntegrationOwner(ownerEmail: string): boolean {\n return (\n ownerEmail.startsWith(\"integration@\") ||\n ownerEmail.endsWith(\"@integration.local\")\n );\n}\n\nasync function requestOwnerRole(): Promise<string | null> {\n const orgId = currentOrgId();\n const ownerEmail = currentOwnerEmail();\n if (!orgId) return null;\n try {\n const { rows } = await getDbExec().execute({\n sql: `SELECT role FROM org_members WHERE org_id = ? AND LOWER(email) = ? LIMIT 1`,\n args: [orgId, ownerEmail.toLowerCase()],\n });\n const role = (rows[0] as any)?.role;\n return typeof role === \"string\" ? role : null;\n } catch {\n return null;\n }\n}\n\nasync function assertCanManageAppCreationSettings(): Promise<void> {\n const orgId = currentOrgId();\n if (!orgId) return;\n const role = await requestOwnerRole();\n if (role !== \"owner\" && role !== \"admin\") {\n throw new Error(\n \"Only organization owners and admins can update app creation settings.\",\n );\n }\n}\n\nasync function isCurrentIntegrationExplicitlyLinked(): Promise<boolean> {\n const incoming = getRequestContext()?.integration?.incoming;\n if (!incoming) return true;\n const externalUserId = identityKeyForIncoming(incoming);\n const linkedOwner = await resolveLinkedOwner(\n incoming.platform,\n externalUserId,\n {\n allowAnyOrgFallback: true,\n },\n ).catch(() => null);\n return linkedOwner === currentOwnerEmail();\n}\n\nasync function defaultOwnerAppCreationAllowed(): Promise<boolean> {\n const defaultOwner = process.env.DISPATCH_DEFAULT_OWNER_EMAIL?.trim();\n if (!defaultOwner || defaultOwner !== currentOwnerEmail()) return false;\n if (await isCurrentIntegrationExplicitlyLinked()) return true;\n return (\n process.env.DISPATCH_ALLOW_DEFAULT_OWNER_APP_CREATION === \"true\" ||\n process.env.DISPATCH_ALLOW_DEFAULT_OWNER_APP_CREATION === \"1\" ||\n process.env.ENABLE_BUILDER === \"true\" ||\n process.env.ENABLE_BUILDER === \"1\"\n );\n}\n\nfunction normalizeBuilderRunString(value: unknown, fieldName: string): string {\n if (typeof value !== \"string\" || !value.trim()) {\n throw new Error(`Builder app creation returned a blank ${fieldName}`);\n }\n const trimmed = value.trim();\n if (/[\u0000-\u001f]/.test(trimmed)) {\n throw new Error(`Builder app creation returned a malformed ${fieldName}`);\n }\n return trimmed;\n}\n\nfunction normalizeBuilderRunUrl(value: unknown): string {\n const urlString = normalizeBuilderRunString(value, \"url\");\n let parsed: URL;\n try {\n parsed = new URL(urlString);\n } catch {\n throw new Error(\"Builder app creation returned a malformed url\");\n }\n if (parsed.protocol !== \"https:\" && parsed.protocol !== \"http:\") {\n throw new Error(\"Builder app creation returned a malformed url\");\n }\n if (\n parsed.hostname !== \"builder.io\" &&\n !parsed.hostname.endsWith(\".builder.io\")\n ) {\n throw new Error(\"Builder app creation returned a non-Builder url\");\n }\n return parsed.toString();\n}\n\nfunction normalizeBuilderRunResult(result: unknown): {\n branchName: string;\n url: string;\n status: string;\n} {\n const record =\n result && typeof result === \"object\" && !Array.isArray(result)\n ? (result as Record<string, unknown>)\n : {};\n return {\n branchName: normalizeBuilderRunString(record.branchName, \"branchName\"),\n url: normalizeBuilderRunUrl(record.url),\n status:\n typeof record.status === \"string\" && record.status.trim()\n ? record.status.trim()\n : \"processing\",\n };\n}\n\nasync function remoteAppCreationAuthorization(): Promise<\n { ok: true } | { ok: false; message: string }\n> {\n const ownerEmail = currentOwnerEmail();\n const isIntegrationCaller = isIntegrationCallerRequest();\n const defaultOwner = process.env.DISPATCH_DEFAULT_OWNER_EMAIL?.trim();\n if (isIntegrationCaller && defaultOwner && defaultOwner === ownerEmail) {\n if (await defaultOwnerAppCreationAllowed()) return { ok: true };\n return {\n ok: false,\n message:\n \"Messaging-triggered app creation is using the deployment default Dispatch owner. \" +\n \"Link the messaging identity to a Dispatch user with /link, start the app from Dispatch while signed in, or explicitly set ENABLE_BUILDER=true for this deployment.\",\n };\n }\n if (!isSyntheticIntegrationOwner(ownerEmail)) return { ok: true };\n\n const source = isIntegrationCaller\n ? \"Messaging-triggered\"\n : \"Synthetic integration\";\n return {\n ok: false,\n message:\n `${source} app creation needs a trusted Dispatch owner before Builder can start a branch. ` +\n \"Link the messaging identity to a Dispatch user with /link, start the app from Dispatch while signed in, or explicitly set ENABLE_BUILDER=true for this deployment.\",\n };\n}\n\nfunction buildWorkspaceAppPrompt(input: {\n prompt: string;\n appId?: string | null;\n template?: string | null;\n selectedKeys?: string[];\n selectedResources?: WorkspaceResourceOption[];\n}): { appId: string; prompt: string } {\n const appId =\n slugify(input.appId || \"\") ||\n slugify(\n input.prompt.replace(/\\b(build|create|make|an?|the|app|tool)\\b/gi, \" \"),\n ) ||\n \"new-app\";\n const selectedKeys = input.selectedKeys || [];\n const selectedResources = input.selectedResources || [];\n const resourceList = selectedResources.length\n ? selectedResources\n .map(\n (resource) =>\n `- ${resource.name} (${resource.kind}, ${resource.path})`,\n )\n .join(\"\\n\")\n : \"none\";\n return {\n appId,\n prompt: [\n \"Create a new agent-native app in this workspace.\",\n \"\",\n `App name: ${appId}`,\n `Template to start from: ${input.template || \"starter\"}`,\n `User prompt: ${input.prompt.trim()}`,\n selectedKeys.length\n ? `Dispatch vault keys selected for this app: ${selectedKeys.join(\", \")}`\n : \"Dispatch vault keys selected for this app: none\",\n `Dispatch workspace resources selected for this app:\\n${resourceList}`,\n \"\",\n `Use the workspace app layout: create it under apps/${appId}, mount it at /${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 `Important routing rule: from outside the app, link to /${appId}; inside apps/${appId}, React Router routes are app-local. Use <Link to=\"/review\"> and navigate(\"/review\"), not \"/${appId}/review\"; APP_BASE_PATH supplies the mounted prefix, and hardcoding it causes doubled URLs like /${appId}/${appId}/review.`,\n \"Existing first-party apps are neighbors, not implementation details for this app. If the user 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/${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 selectedKeys.length\n ? `Dispatch will create pending vault requests for the selected keys for appId \"${appId}\" after this app creation request is accepted. Do not grant or sync vault keys directly from the app-creation branch.`\n : \"Do not grant or request any Dispatch vault keys unless the user asks later.\",\n selectedResources.length\n ? `Dispatch will create workspace resource grants for the selected resources for appId \"${appId}\". After the app exists, sync workspace resources so the app receives those shared resources. Add a short note to apps/${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 \"Agent-native rules (these are the framework's contract — not optional):\",\n `- Persist ALL data in SQL via Drizzle. Add tables to apps/${appId}/server/db/schema.ts and migrations to apps/${appId}/server/plugins/db.ts. NEVER use localStorage, sessionStorage, IndexedDB, or in-memory state for anything the user expects to persist — agent and UI must read the same source of truth.`,\n `- Define every create/read/update/delete as an action in apps/${appId}/actions/ using defineAction. The agent calls these as tools and the frontend calls them via useActionQuery / useActionMutation. If you must raw-fetch framework action endpoints, use agentNativePath(\"/_agent-native/actions/<name>\") so mounted apps call the right URL. Don't add /api/* routes for CRUD.`,\n \"- Build the UI from shadcn/ui components in app/components/ui/ (Button, Input, Dialog, Popover, Card, etc.) and Tailwind utilities. Don't author bespoke CSS classes in global.css unless you genuinely need a primitive that shadcn doesn't ship.\",\n \"- Use Tabler Icons (@tabler/icons-react) for every icon. Never use emojis as icons.\",\n `- Expose what the user is looking at via application_state (navigation.view, selection, etc.) so the agent has live context. Mirror the patterns in templates/mail or templates/slides.`,\n \"- Optimistic UI for every mutation: update the React Query cache immediately, navigate immediately, run the mutation in the background, roll back on error. Don't await a server round-trip before re-rendering.\",\n \"\",\n \"Branch readiness requirements before handing off:\",\n \"- The CLI auto-fills package.json name and displayName from the app id; only edit the description / scripts / dependencies if the app actually needs more than the template provides.\",\n \"- Do not add or update workspace-apps.json or .agent-native/workspace-apps.json unless the app needs an explicit external URL override; the root deploy generates the workspace app registry from apps/* and deploy metadata.\",\n \"- Update pnpm-lock.yaml when adding or changing dependencies so Netlify can install the branch reliably.\",\n \"- Update the app manifest/package/deploy metadata needed by the existing workspace deployment model; do not leave the branch relying only on uncommitted local state.\",\n \"- Verify the app's agent card/A2A metadata is ready so Dispatch can discover and delegate to the app after deployment.\",\n \"- Include a final verification note covering the registry entry, manifest/deploy metadata, and agent-card readiness.\",\n `When it is ready, start or update the workspace dev server and navigate the user to /${appId}.`,\n ].join(\"\\n\"),\n };\n}\n\nasync function requestSelectedVaultKeys(input: {\n appId: string;\n selectedKeys: string[];\n}) {\n if (input.selectedKeys.length === 0) return;\n await Promise.allSettled(\n input.selectedKeys.map((credentialKey) =>\n Promise.resolve().then(() =>\n createRequest({\n appId: input.appId,\n credentialKey,\n reason: `Requested during workspace app creation for ${input.appId}.`,\n }),\n ),\n ),\n );\n}\n\nasync function selectedWorkspaceResourcesForIds(\n resourceIds: string[] | undefined,\n): Promise<WorkspaceResourceOption[]> {\n if (!resourceIds?.length) return [];\n const requested = new Set(resourceIds);\n const resources = await listWorkspaceResourceOptions();\n return resources.filter((resource) => requested.has(resource.id));\n}\n\nasync function grantSelectedWorkspaceResources(input: {\n appId: string;\n resourceIds: string[];\n}) {\n if (input.resourceIds.length === 0) return;\n await grantWorkspaceResourcesToApp(input);\n}\n\nexport async function startWorkspaceAppCreation(input: {\n prompt: string;\n appId?: string | null;\n template?: string | null;\n secretIds?: string[];\n resourceIds?: string[];\n}) {\n const initial = buildWorkspaceAppPrompt({\n prompt: input.prompt,\n appId: input.appId,\n template: input.template,\n });\n assertValidWorkspaceAppId(initial.appId);\n const isLocal = isLocalAppCreationRuntime();\n\n if (!isLocal) {\n const authorization = await remoteAppCreationAuthorization();\n if (authorization.ok === false) {\n return {\n mode: \"builder-unavailable\",\n appId: initial.appId,\n message: authorization.message,\n };\n }\n }\n\n const selectedKeys = input.secretIds?.length\n ? (await listSecrets())\n .filter((secret) => input.secretIds?.includes(secret.id))\n .map((secret) => secret.credentialKey)\n : [];\n const selectedResources = await selectedWorkspaceResourcesForIds(\n input.resourceIds,\n );\n const built = buildWorkspaceAppPrompt({\n prompt: input.prompt,\n appId: input.appId,\n template: input.template,\n selectedKeys,\n selectedResources,\n });\n const prompt = built.prompt;\n\n if (isLocal) {\n await requestSelectedVaultKeys({\n appId: built.appId,\n selectedKeys,\n });\n await grantSelectedWorkspaceResources({\n appId: built.appId,\n resourceIds: selectedResources.map((resource) => resource.id),\n });\n return {\n mode: \"local-agent\",\n appId: built.appId,\n prompt,\n message:\n \"Use the local code agent to create this app in the workspace, then open it from /dispatch/apps.\",\n };\n }\n\n const settings = await getAppCreationSettings();\n\n if (!settings.builderProjectId) {\n return {\n mode: \"coming-soon\",\n appId: built.appId,\n message:\n \"Builder app creation is coming soon here. Set a default Builder project in Dispatch or provide BUILDER_BRANCH_PROJECT_ID to enable branch creation.\",\n };\n }\n\n let result: {\n branchName: string;\n url: string;\n status: string;\n };\n try {\n const builderCreds = await resolveBuilderCredentials().catch(() => null);\n const builderUserId = builderCreds?.userId || undefined;\n result = normalizeBuilderRunResult(\n await runBuilderAgent({\n prompt,\n projectId: settings.builderProjectId,\n ...(builderUserId\n ? { userId: builderUserId }\n : { userEmail: currentOwnerEmail() }),\n }),\n );\n } catch (err) {\n const detail =\n err instanceof Error && err.message\n ? err.message\n : \"Builder could not start the app branch\";\n return {\n mode: \"builder-unavailable\",\n appId: built.appId,\n projectId: settings.builderProjectId,\n message:\n `Builder app creation is configured for project ${settings.builderProjectId}, ` +\n `but it could not start yet: ${detail}. Connect Builder for this user, ` +\n `link the messaging identity to that user, or configure deployment-managed Builder credentials for this workspace.`,\n };\n }\n\n await recordPendingWorkspaceApp({\n appId: built.appId,\n projectId: settings.builderProjectId,\n branchName: result.branchName,\n builderUrl: result.url,\n });\n\n await requestSelectedVaultKeys({\n appId: built.appId,\n selectedKeys,\n });\n await grantSelectedWorkspaceResources({\n appId: built.appId,\n resourceIds: selectedResources.map((resource) => resource.id),\n });\n\n return {\n mode: \"builder\",\n appId: built.appId,\n path: `/${built.appId}`,\n projectId: settings.builderProjectId,\n branchName: result.branchName,\n url: result.url,\n workspaceUrl: workspaceAppUrl(`/${built.appId}`),\n status: result.status,\n message:\n `Builder started a branch for /${built.appId}. Use the Builder branch URL to track creation now. ` +\n `The workspace path will be live after that branch is merged and the workspace deploy finishes, so it may 404 until then.`,\n };\n}\n"]}
|
|
1
|
+
{"version":3,"file":"app-creation-store.js","sourceRoot":"","sources":["../../../src/server/lib/app-creation-store.ts"],"names":[],"mappings":"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","sourcesContent":["import fs from \"node:fs\";\nimport path from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport { getSetting, putSetting } from \"@agent-native/core/settings\";\nimport {\n getBuilderBranchProjectId,\n getRequestContext,\n isIntegrationCallerRequest,\n resolveBuilderBranchProjectId,\n resolveBuilderCredentials,\n runBuilderAgent,\n} from \"@agent-native/core/server\";\nimport { getDbExec } from \"@agent-native/core/db\";\nimport { assertValidWorkspaceAppId } from \"@agent-native/core/shared\";\nimport {\n currentOrgId,\n currentOwnerEmail,\n recordAudit,\n resolveLinkedOwner,\n} from \"./dispatch-store.js\";\nimport { identityKeyForIncoming } from \"./dispatch-integrations.js\";\nimport { createRequest, listSecrets } from \"./vault-store.js\";\nimport {\n grantWorkspaceResourcesToApp,\n listWorkspaceResourceOptions,\n type WorkspaceResourceOption,\n} from \"./workspace-resources-store.js\";\n\nconst SETTINGS_KEY = \"dispatch-app-creation-settings\";\nconst WORKSPACE_APPS_ENV_KEY = \"AGENT_NATIVE_WORKSPACE_APPS_JSON\";\nconst WORKSPACE_APPS_MANIFEST_FILE = \"workspace-apps.json\";\nconst WORKSPACE_APPS_GATEWAY_PATH = \"/_workspace/apps\";\nconst WORKSPACE_APPS_GATEWAY_TIMEOUT_MS = 1_000;\nconst MAX_PENDING_APPS = 50;\nconst AGENT_CARD_PATH = \"/.well-known/agent-card.json\";\nconst AGENT_CARD_FETCH_TIMEOUT_MS = 1_500;\n\nexport 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 createdAt?: string | null;\n agentCardUrl?: string | null;\n agentCardReachable?: boolean;\n a2aEndpointUrl?: string | null;\n agentName?: string | null;\n agentSkillsCount?: number | null;\n}\n\nexport interface ListWorkspaceAppsOptions {\n includeAgentCards?: boolean;\n}\n\nexport interface AppCreationSettings {\n builderProjectId: string | null;\n builderProjectIdSource: \"env\" | \"dispatch\" | \"default\" | \"unset\";\n envBuilderProjectId: string | null;\n savedBuilderProjectId: string | null;\n builderBranchingEnabled: boolean;\n}\n\nexport interface WorkspaceInfo {\n /** Slug from the workspace root package.json `name` (e.g. \"on-call-todo-manager\"). */\n name: string | null;\n /** Title-cased version for display (e.g. \"On Call Todo Manager\"). */\n displayName: string | null;\n /** Absolute path to the workspace root, if detected. */\n rootPath: string | null;\n /** Number of apps currently scaffolded under apps/. */\n appCount: number;\n}\n\ninterface PendingWorkspaceApp {\n id: string;\n name: string;\n description: string;\n path: string;\n builderUrl: string | null;\n branchName: string | null;\n projectId: string | null;\n createdAt: string;\n updatedAt: string;\n}\n\nfunction readJson(file: string): any {\n try {\n return JSON.parse(fs.readFileSync(file, \"utf8\"));\n } catch {\n return null;\n }\n}\n\nfunction findWorkspaceRoot(startDir = process.cwd()): string | null {\n let dir = path.resolve(startDir);\n for (let i = 0; i < 20; i++) {\n const pkg = readJson(path.join(dir, \"package.json\"));\n if (typeof pkg?.[\"agent-native\"]?.workspaceCore === \"string\") {\n return dir;\n }\n const parent = path.dirname(dir);\n if (parent === dir) break;\n dir = parent;\n }\n return null;\n}\n\nfunction titleCase(value: string): string {\n return value\n .split(/[-_\\s]+/)\n .filter(Boolean)\n .map((part) => part.charAt(0).toUpperCase() + part.slice(1))\n .join(\" \");\n}\n\nfunction scopedSettingsKey(): string {\n const orgId = currentOrgId();\n if (orgId) return `${SETTINGS_KEY}:org:${orgId}`;\n return `${SETTINGS_KEY}:user:${currentOwnerEmail()}`;\n}\n\nasync function readSettingsRecord(): Promise<Record<string, any>> {\n const raw = await getSetting(scopedSettingsKey()).catch(() => null);\n return raw && typeof raw === \"object\" && !Array.isArray(raw)\n ? (raw as Record<string, any>)\n : {};\n}\n\nfunction workspaceAppUrl(appPath: string): string | null {\n const base =\n process.env.WORKSPACE_GATEWAY_URL ||\n process.env.APP_URL ||\n process.env.URL ||\n process.env.DEPLOY_URL ||\n process.env.BETTER_AUTH_URL ||\n null;\n if (!base) return null;\n try {\n return new URL(appPath, `${base.replace(/\\/$/, \"\")}/`).toString();\n } catch {\n return null;\n }\n}\n\nfunction workspaceAppLink(\n appPath: string,\n explicitUrl?: unknown,\n): string | null {\n const urlValue = typeof explicitUrl === \"string\" ? explicitUrl.trim() : \"\";\n if (!urlValue) return workspaceAppUrl(appPath);\n if (urlValue.startsWith(\"/\")) return workspaceAppUrl(urlValue) ?? urlValue;\n try {\n return new URL(urlValue).toString();\n } catch {\n return urlValue;\n }\n}\n\nfunction parseWorkspaceAppsManifest(parsed: any): WorkspaceAppSummary[] | null {\n const rawApps = Array.isArray(parsed?.apps)\n ? parsed.apps\n : Array.isArray(parsed)\n ? parsed\n : null;\n if (!rawApps) return null;\n\n const apps = rawApps\n .map((entry): WorkspaceAppSummary | null => {\n if (!entry || typeof entry !== \"object\") return null;\n const id = typeof entry.id === \"string\" ? entry.id.trim() : \"\";\n const pathValue = typeof entry.path === \"string\" ? entry.path.trim() : \"\";\n if (!id || !pathValue.startsWith(\"/\")) return null;\n return {\n id,\n name:\n typeof entry.name === \"string\" && entry.name.trim()\n ? entry.name.trim()\n : titleCase(id),\n description:\n typeof entry.description === \"string\" ? entry.description : \"\",\n path: pathValue,\n url: workspaceAppLink(pathValue, entry.url),\n isDispatch:\n typeof entry.isDispatch === \"boolean\"\n ? entry.isDispatch\n : id === \"dispatch\",\n status: \"ready\",\n } satisfies WorkspaceAppSummary;\n })\n .filter((app): app is WorkspaceAppSummary => !!app)\n .sort(sortWorkspaceApps);\n\n return apps.length ? apps : null;\n}\n\nfunction sortWorkspaceApps(a: WorkspaceAppSummary, b: WorkspaceAppSummary) {\n if (a.id === \"dispatch\") return -1;\n if (b.id === \"dispatch\") return 1;\n if (a.status === \"pending\" && b.status !== \"pending\") return 1;\n if (a.status !== \"pending\" && b.status === \"pending\") return -1;\n return a.name.localeCompare(b.name);\n}\n\nfunction parsePendingWorkspaceApps(value: unknown): PendingWorkspaceApp[] {\n if (!Array.isArray(value)) return [];\n return value\n .map((entry) => {\n if (!entry || typeof entry !== \"object\") return null;\n const record = entry as Record<string, unknown>;\n const id = typeof record.id === \"string\" ? record.id.trim() : \"\";\n const pathValue =\n typeof record.path === \"string\" ? record.path.trim() : \"\";\n if (!id || !pathValue.startsWith(\"/\")) return null;\n const now = new Date().toISOString();\n return {\n id,\n name:\n typeof record.name === \"string\" && record.name.trim()\n ? record.name.trim()\n : titleCase(id),\n description:\n typeof record.description === \"string\"\n ? record.description\n : \"Builder is creating this app. The workspace path becomes live after the branch is merged and deployed.\",\n path: pathValue,\n builderUrl:\n typeof record.builderUrl === \"string\" && record.builderUrl.trim()\n ? record.builderUrl.trim()\n : null,\n branchName:\n typeof record.branchName === \"string\" && record.branchName.trim()\n ? record.branchName.trim()\n : null,\n projectId:\n typeof record.projectId === \"string\" && record.projectId.trim()\n ? record.projectId.trim()\n : null,\n createdAt:\n typeof record.createdAt === \"string\" && record.createdAt.trim()\n ? record.createdAt.trim()\n : now,\n updatedAt:\n typeof record.updatedAt === \"string\" && record.updatedAt.trim()\n ? record.updatedAt.trim()\n : now,\n } satisfies PendingWorkspaceApp;\n })\n .filter((app): app is PendingWorkspaceApp => !!app)\n .slice(0, MAX_PENDING_APPS);\n}\n\nasync function listPendingWorkspaceApps(): Promise<PendingWorkspaceApp[]> {\n const raw = await readSettingsRecord();\n return parsePendingWorkspaceApps(raw.pendingApps);\n}\n\nfunction pendingAppToSummary(app: PendingWorkspaceApp): WorkspaceAppSummary {\n return {\n id: app.id,\n name: app.name,\n description: app.description,\n path: app.path,\n url: app.builderUrl,\n isDispatch: false,\n status: \"pending\",\n statusLabel: \"Building in Builder\",\n builderUrl: app.builderUrl,\n branchName: app.branchName,\n createdAt: app.createdAt,\n };\n}\n\nasync function appendPendingWorkspaceApps(\n apps: WorkspaceAppSummary[],\n): Promise<WorkspaceAppSummary[]> {\n const readyIds = new Set(apps.map((app) => app.id));\n const pendingApps = (await listPendingWorkspaceApps())\n .filter((app) => !readyIds.has(app.id))\n .map(pendingAppToSummary);\n return [...apps, ...pendingApps].sort(sortWorkspaceApps);\n}\n\nfunction agentCardUrlForApp(appUrl: string | null): string | null {\n if (!appUrl) return null;\n const trimmed = appUrl.replace(/\\/+$/, \"\");\n if (!trimmed) return null;\n try {\n return new URL(`${trimmed}${AGENT_CARD_PATH}`).toString();\n } catch {\n return `${trimmed}${AGENT_CARD_PATH}`;\n }\n}\n\nfunction stringField(\n record: Record<string, unknown>,\n key: string,\n): string | null {\n const value = record[key];\n return typeof value === \"string\" && value.trim() ? value.trim() : null;\n}\n\nfunction numberOfSkills(card: Record<string, unknown>): number | null {\n return Array.isArray(card.skills) ? card.skills.length : null;\n}\n\nasync function fetchAgentCardMetadata(\n app: WorkspaceAppSummary,\n): Promise<\n Pick<\n WorkspaceAppSummary,\n | \"agentCardUrl\"\n | \"agentCardReachable\"\n | \"a2aEndpointUrl\"\n | \"agentName\"\n | \"agentSkillsCount\"\n >\n> {\n const agentCardUrl = agentCardUrlForApp(app.url);\n if (!agentCardUrl) {\n return {\n agentCardUrl: null,\n agentCardReachable: false,\n a2aEndpointUrl: null,\n agentName: null,\n agentSkillsCount: null,\n };\n }\n\n const controller = new AbortController();\n const timeout = setTimeout(\n () => controller.abort(),\n AGENT_CARD_FETCH_TIMEOUT_MS,\n );\n\n try {\n const response = await fetch(agentCardUrl, {\n headers: { accept: \"application/json\" },\n signal: controller.signal,\n });\n if (!response.ok) {\n return {\n agentCardUrl,\n agentCardReachable: false,\n a2aEndpointUrl: null,\n agentName: null,\n agentSkillsCount: null,\n };\n }\n\n const parsed = await response.json().catch(() => null);\n const card =\n parsed && typeof parsed === \"object\" && !Array.isArray(parsed)\n ? (parsed as Record<string, unknown>)\n : null;\n if (!card) {\n return {\n agentCardUrl,\n agentCardReachable: false,\n a2aEndpointUrl: null,\n agentName: null,\n agentSkillsCount: null,\n };\n }\n\n return {\n agentCardUrl,\n agentCardReachable: true,\n a2aEndpointUrl:\n stringField(card, \"url\") ?? stringField(card, \"endpointUrl\"),\n agentName: stringField(card, \"name\"),\n agentSkillsCount: numberOfSkills(card),\n };\n } catch {\n return {\n agentCardUrl,\n agentCardReachable: false,\n a2aEndpointUrl: null,\n agentName: null,\n agentSkillsCount: null,\n };\n } finally {\n clearTimeout(timeout);\n }\n}\n\nasync function maybeIncludeAgentCards(\n apps: WorkspaceAppSummary[],\n options: ListWorkspaceAppsOptions,\n): Promise<WorkspaceAppSummary[]> {\n if (!options.includeAgentCards) return apps;\n return Promise.all(\n apps.map(async (app) => {\n if (app.status === \"pending\") return app;\n const metadata = await fetchAgentCardMetadata(app);\n return { ...app, ...metadata };\n }),\n );\n}\n\nasync function recordPendingWorkspaceApp(input: {\n appId: string;\n projectId: string | null;\n branchName?: string | null;\n builderUrl?: string | null;\n}) {\n const now = new Date().toISOString();\n const raw = await readSettingsRecord();\n const pendingApps = parsePendingWorkspaceApps(raw.pendingApps);\n const existing = pendingApps.find((app) => app.id === input.appId);\n const next: PendingWorkspaceApp = {\n id: input.appId,\n name: titleCase(input.appId),\n description:\n \"Builder is creating this app. The workspace path becomes live after the branch is merged and deployed.\",\n path: `/${input.appId}`,\n builderUrl: input.builderUrl?.trim() || null,\n branchName: input.branchName?.trim() || null,\n projectId: input.projectId,\n createdAt: existing?.createdAt || now,\n updatedAt: now,\n };\n\n await putSetting(scopedSettingsKey(), {\n ...raw,\n pendingApps: [\n next,\n ...pendingApps.filter((app) => app.id !== input.appId),\n ].slice(0, MAX_PENDING_APPS),\n });\n\n await recordAudit({\n action: \"workspace-app.pending\",\n targetType: \"workspace-app\",\n targetId: input.appId,\n summary: \"Started Builder branch for workspace app creation\",\n metadata: {\n builderBranchUrlConfigured: !!next.builderUrl,\n branchName: next.branchName,\n projectIdConfigured: !!next.projectId,\n },\n });\n}\n\nfunction readWorkspaceAppsFromEnv(): WorkspaceAppSummary[] | null {\n const raw = process.env[WORKSPACE_APPS_ENV_KEY];\n if (!raw) return null;\n try {\n return parseWorkspaceAppsManifest(JSON.parse(raw));\n } catch {\n return null;\n }\n}\n\nasync function readWorkspaceAppsFromGateway(): Promise<\n WorkspaceAppSummary[] | null\n> {\n const base = process.env.WORKSPACE_GATEWAY_URL;\n if (!base) return null;\n\n const controller = new AbortController();\n const timeout = setTimeout(\n () => controller.abort(),\n WORKSPACE_APPS_GATEWAY_TIMEOUT_MS,\n );\n\n try {\n const response = await fetch(\n new URL(WORKSPACE_APPS_GATEWAY_PATH, `${base.replace(/\\/$/, \"\")}/`),\n {\n headers: { accept: \"application/json\" },\n signal: controller.signal,\n },\n );\n if (!response.ok) return null;\n return parseWorkspaceAppsManifest(await response.json().catch(() => null));\n } catch {\n return null;\n } finally {\n clearTimeout(timeout);\n }\n}\n\nfunction workspaceAppsManifestCandidates(): string[] {\n const candidates: string[] = [];\n try {\n candidates.push(\n path.join(process.cwd(), \".agent-native\", WORKSPACE_APPS_MANIFEST_FILE),\n path.join(process.cwd(), WORKSPACE_APPS_MANIFEST_FILE),\n );\n } catch {\n // Some edge runtimes do not expose process.cwd().\n }\n try {\n const moduleDir = path.dirname(fileURLToPath(import.meta.url));\n candidates.push(\n path.join(moduleDir, \".agent-native\", WORKSPACE_APPS_MANIFEST_FILE),\n path.join(moduleDir, WORKSPACE_APPS_MANIFEST_FILE),\n );\n } catch {\n // Some edge runtimes expose non-file module URLs. The env manifest still\n // works there, so skip file-relative candidates.\n }\n return candidates;\n}\n\nfunction readWorkspaceAppsFromManifestFile(): WorkspaceAppSummary[] | null {\n for (const file of workspaceAppsManifestCandidates()) {\n if (!fs.existsSync(file)) continue;\n const apps = parseWorkspaceAppsManifest(readJson(file));\n if (apps) return apps;\n }\n return null;\n}\n\nfunction readWorkspaceAppsFromFilesystem(\n workspaceRoot: string,\n): WorkspaceAppSummary[] | null {\n const appsDir = path.join(workspaceRoot, \"apps\");\n if (!fs.existsSync(appsDir)) return null;\n\n const apps = fs\n .readdirSync(appsDir, { withFileTypes: true })\n .filter((entry) => entry.isDirectory())\n .map((entry): WorkspaceAppSummary | null => {\n const appDir = path.join(appsDir, entry.name);\n const pkg = readJson(path.join(appDir, \"package.json\"));\n if (!pkg) return null;\n return {\n id: entry.name,\n name: pkg.displayName || titleCase(entry.name),\n description: pkg.description || \"\",\n path: `/${entry.name}`,\n url: workspaceAppUrl(`/${entry.name}`),\n isDispatch: entry.name === \"dispatch\",\n status: \"ready\",\n } satisfies WorkspaceAppSummary;\n })\n .filter((app): app is WorkspaceAppSummary => !!app)\n .sort(sortWorkspaceApps);\n\n return apps.length ? apps : null;\n}\n\nexport function getEnvBuilderProjectId(): string | null {\n return (\n process.env.DISPATCH_BUILDER_PROJECT_ID ||\n process.env.BUILDER_BRANCH_PROJECT_ID ||\n process.env.BUILDER_PROJECT_ID ||\n null\n );\n}\n\n/**\n * Read the workspace's identity from the workspace root's package.json. Used to\n * surface \"Workspace: <name>\" in the Dispatch UI so first-time users can see\n * the container their apps live inside (rather than only seeing app names like\n * \"starter\" / \"dispatch\" with no parent context).\n */\nexport function getWorkspaceInfo(): WorkspaceInfo {\n const rootPath = findWorkspaceRoot();\n if (!rootPath) {\n return { name: null, displayName: null, rootPath: null, appCount: 0 };\n }\n const pkg = readJson(path.join(rootPath, \"package.json\"));\n const rawName = typeof pkg?.name === \"string\" ? pkg.name.trim() : \"\";\n // Strip a leading \"@scope/\" if the workspace root happens to be scoped.\n const name = rawName.replace(/^@[^/]+\\//, \"\") || null;\n // Honor an explicit `displayName` in the workspace package.json before\n // falling back to a title-cased version of the slug. Users naming a\n // workspace \"On-Call Todo Manager\" via `displayName` should see that\n // exact label rather than `On Call Todo Manager`.\n const rawDisplay =\n typeof pkg?.displayName === \"string\" ? pkg.displayName.trim() : \"\";\n const displayName = rawDisplay || (name ? titleCase(name) : null);\n let appCount = 0;\n const appsDir = path.join(rootPath, \"apps\");\n if (fs.existsSync(appsDir)) {\n try {\n appCount = fs\n .readdirSync(appsDir, { withFileTypes: true })\n .filter((entry) => entry.isDirectory()).length;\n } catch {\n appCount = 0;\n }\n }\n return {\n name,\n displayName,\n rootPath,\n appCount,\n };\n}\n\nexport async function listWorkspaceApps(\n options: ListWorkspaceAppsOptions = {},\n): Promise<WorkspaceAppSummary[]> {\n const gatewayApps = await readWorkspaceAppsFromGateway();\n if (gatewayApps) {\n return maybeIncludeAgentCards(\n await appendPendingWorkspaceApps(gatewayApps),\n options,\n );\n }\n\n const workspaceRoot = findWorkspaceRoot();\n const localFilesystemApps =\n workspaceRoot && isLocalAppCreationRuntime()\n ? readWorkspaceAppsFromFilesystem(workspaceRoot)\n : null;\n if (localFilesystemApps) {\n return maybeIncludeAgentCards(\n await appendPendingWorkspaceApps(localFilesystemApps),\n options,\n );\n }\n\n const manifestApps =\n readWorkspaceAppsFromEnv() ?? readWorkspaceAppsFromManifestFile();\n if (manifestApps) {\n return maybeIncludeAgentCards(\n await appendPendingWorkspaceApps(manifestApps),\n options,\n );\n }\n\n if (!workspaceRoot) {\n return maybeIncludeAgentCards(\n await appendPendingWorkspaceApps([\n {\n id: \"dispatch\",\n name: \"Dispatch\",\n description: \"Workspace control plane\",\n path: \"/dispatch\",\n url: workspaceAppUrl(\"/dispatch\"),\n isDispatch: true,\n status: \"ready\",\n },\n ]),\n options,\n );\n }\n\n const apps = readWorkspaceAppsFromFilesystem(workspaceRoot) ?? [];\n return maybeIncludeAgentCards(\n await appendPendingWorkspaceApps(apps),\n options,\n );\n}\n\nexport async function getAppCreationSettings(): Promise<AppCreationSettings> {\n const envBuilderProjectId = getEnvBuilderProjectId();\n const resolvedBuilderProjectId = await resolveBuilderBranchProjectId();\n const raw = await readSettingsRecord();\n const savedBuilderProjectId =\n typeof raw?.builderProjectId === \"string\" && raw.builderProjectId.trim()\n ? raw.builderProjectId.trim()\n : null;\n const builderProjectId = envBuilderProjectId || savedBuilderProjectId;\n const enableBuilder =\n process.env.ENABLE_BUILDER === \"true\" || process.env.ENABLE_BUILDER === \"1\";\n const effectiveBuilderProjectId =\n builderProjectId ||\n resolvedBuilderProjectId ||\n (enableBuilder ? getBuilderBranchProjectId() : null);\n\n return {\n builderProjectId: effectiveBuilderProjectId,\n builderProjectIdSource: envBuilderProjectId\n ? \"env\"\n : savedBuilderProjectId\n ? \"dispatch\"\n : effectiveBuilderProjectId\n ? \"default\"\n : \"unset\",\n envBuilderProjectId,\n savedBuilderProjectId,\n builderBranchingEnabled: !!effectiveBuilderProjectId,\n };\n}\n\nexport async function setAppCreationSettings(input: {\n builderProjectId?: string | null;\n}): Promise<AppCreationSettings> {\n await assertCanManageAppCreationSettings();\n const builderProjectId = input.builderProjectId?.trim() || null;\n const raw = await readSettingsRecord();\n await putSetting(scopedSettingsKey(), { ...raw, builderProjectId });\n await recordAudit({\n action: \"settings.updated\",\n targetType: \"dispatch-app-creation-settings\",\n targetId: SETTINGS_KEY,\n summary: builderProjectId\n ? \"Updated default Builder project for app creation\"\n : \"Cleared default Builder project for app creation\",\n metadata: { builderProjectIdConfigured: !!builderProjectId },\n });\n return getAppCreationSettings();\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, 64);\n}\n\nfunction isLocalAppCreationRuntime(): boolean {\n if (process.env.NODE_ENV === \"production\") return false;\n if (\n process.env.NETLIFY ||\n process.env.VERCEL ||\n process.env.CF_PAGES ||\n process.env.DEPLOY_URL ||\n process.env.URL ||\n process.env.RENDER ||\n process.env.FLY_APP_NAME\n ) {\n return false;\n }\n return true;\n}\n\nfunction isSyntheticIntegrationOwner(ownerEmail: string): boolean {\n return (\n ownerEmail.startsWith(\"integration@\") ||\n ownerEmail.endsWith(\"@integration.local\")\n );\n}\n\nasync function requestOwnerRole(): Promise<string | null> {\n const orgId = currentOrgId();\n const ownerEmail = currentOwnerEmail();\n if (!orgId) return null;\n try {\n const { rows } = await getDbExec().execute({\n sql: `SELECT role FROM org_members WHERE org_id = ? AND LOWER(email) = ? LIMIT 1`,\n args: [orgId, ownerEmail.toLowerCase()],\n });\n const role = (rows[0] as any)?.role;\n return typeof role === \"string\" ? role : null;\n } catch {\n return null;\n }\n}\n\nasync function assertCanManageAppCreationSettings(): Promise<void> {\n const orgId = currentOrgId();\n if (!orgId) return;\n const role = await requestOwnerRole();\n if (role !== \"owner\" && role !== \"admin\") {\n throw new Error(\n \"Only organization owners and admins can update app creation settings.\",\n );\n }\n}\n\nasync function isCurrentIntegrationExplicitlyLinked(): Promise<boolean> {\n const incoming = getRequestContext()?.integration?.incoming;\n if (!incoming) return true;\n const externalUserId = identityKeyForIncoming(incoming);\n const linkedOwner = await resolveLinkedOwner(\n incoming.platform,\n externalUserId,\n {\n allowAnyOrgFallback: true,\n },\n ).catch(() => null);\n return linkedOwner === currentOwnerEmail();\n}\n\nasync function defaultOwnerAppCreationAllowed(): Promise<boolean> {\n const defaultOwner = process.env.DISPATCH_DEFAULT_OWNER_EMAIL?.trim();\n if (!defaultOwner || defaultOwner !== currentOwnerEmail()) return false;\n if (await isCurrentIntegrationExplicitlyLinked()) return true;\n return (\n process.env.DISPATCH_ALLOW_DEFAULT_OWNER_APP_CREATION === \"true\" ||\n process.env.DISPATCH_ALLOW_DEFAULT_OWNER_APP_CREATION === \"1\" ||\n process.env.ENABLE_BUILDER === \"true\" ||\n process.env.ENABLE_BUILDER === \"1\"\n );\n}\n\nfunction normalizeBuilderRunString(value: unknown, fieldName: string): string {\n if (typeof value !== \"string\" || !value.trim()) {\n throw new Error(`Builder app creation returned a blank ${fieldName}`);\n }\n const trimmed = value.trim();\n if (/[\u0000-\u001f]/.test(trimmed)) {\n throw new Error(`Builder app creation returned a malformed ${fieldName}`);\n }\n return trimmed;\n}\n\nfunction normalizeBuilderRunUrl(value: unknown): string {\n const urlString = normalizeBuilderRunString(value, \"url\");\n let parsed: URL;\n try {\n parsed = new URL(urlString);\n } catch {\n throw new Error(\"Builder app creation returned a malformed url\");\n }\n if (parsed.protocol !== \"https:\" && parsed.protocol !== \"http:\") {\n throw new Error(\"Builder app creation returned a malformed url\");\n }\n if (\n parsed.hostname !== \"builder.io\" &&\n !parsed.hostname.endsWith(\".builder.io\")\n ) {\n throw new Error(\"Builder app creation returned a non-Builder url\");\n }\n return parsed.toString();\n}\n\nfunction normalizeBuilderRunResult(result: unknown): {\n branchName: string;\n url: string;\n status: string;\n} {\n const record =\n result && typeof result === \"object\" && !Array.isArray(result)\n ? (result as Record<string, unknown>)\n : {};\n return {\n branchName: normalizeBuilderRunString(record.branchName, \"branchName\"),\n url: normalizeBuilderRunUrl(record.url),\n status:\n typeof record.status === \"string\" && record.status.trim()\n ? record.status.trim()\n : \"processing\",\n };\n}\n\nasync function remoteAppCreationAuthorization(): Promise<\n { ok: true } | { ok: false; message: string }\n> {\n const ownerEmail = currentOwnerEmail();\n const isIntegrationCaller = isIntegrationCallerRequest();\n const defaultOwner = process.env.DISPATCH_DEFAULT_OWNER_EMAIL?.trim();\n if (isIntegrationCaller && defaultOwner && defaultOwner === ownerEmail) {\n if (await defaultOwnerAppCreationAllowed()) return { ok: true };\n return {\n ok: false,\n message:\n \"Messaging-triggered app creation is using the deployment default Dispatch owner. \" +\n \"Link the messaging identity to a Dispatch user with /link, start the app from Dispatch while signed in, or explicitly set ENABLE_BUILDER=true for this deployment.\",\n };\n }\n if (!isSyntheticIntegrationOwner(ownerEmail)) return { ok: true };\n\n const source = isIntegrationCaller\n ? \"Messaging-triggered\"\n : \"Synthetic integration\";\n return {\n ok: false,\n message:\n `${source} app creation needs a trusted Dispatch owner before Builder can start a branch. ` +\n \"Link the messaging identity to a Dispatch user with /link, start the app from Dispatch while signed in, or explicitly set ENABLE_BUILDER=true for this deployment.\",\n };\n}\n\nfunction buildWorkspaceAppPrompt(input: {\n prompt: string;\n appId?: string | null;\n template?: string | null;\n selectedKeys?: string[];\n selectedResources?: WorkspaceResourceOption[];\n}): { appId: string; prompt: string } {\n const appId =\n slugify(input.appId || \"\") ||\n slugify(\n input.prompt.replace(/\\b(build|create|make|an?|the|app|tool)\\b/gi, \" \"),\n ) ||\n \"new-app\";\n const selectedKeys = input.selectedKeys || [];\n const selectedResources = input.selectedResources || [];\n const resourceList = selectedResources.length\n ? selectedResources\n .map(\n (resource) =>\n `- ${resource.name} (${resource.kind}, ${resource.path})`,\n )\n .join(\"\\n\")\n : \"none\";\n return {\n appId,\n prompt: [\n \"Create a new agent-native app in this workspace.\",\n \"\",\n `App name: ${appId}`,\n `Template to start from: ${input.template || \"starter\"}`,\n `User prompt: ${input.prompt.trim()}`,\n \"If the user mentions a product or company such as Granola, Loom, Superhuman, Linear, or Notion, treat it as product inspiration unless they explicitly ask to connect to that service. Do not invent or require third-party API keys like GRANOLA_API_KEY just because a product is named.\",\n selectedKeys.length\n ? `Dispatch vault keys selected for this app: ${selectedKeys.join(\", \")}`\n : \"Dispatch vault keys selected for this app: none\",\n `Dispatch workspace resources selected for this app:\\n${resourceList}`,\n \"\",\n `Use the workspace app layout: create it under apps/${appId}, mount it at /${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 `Important routing rule: from outside the app, link to /${appId}; inside apps/${appId}, React Router routes are app-local. Use <Link to=\"/review\"> and navigate(\"/review\"), not \"/${appId}/review\"; APP_BASE_PATH supplies the mounted prefix, and hardcoding it causes doubled URLs like /${appId}/${appId}/review.`,\n \"Existing first-party apps are neighbors, not implementation details for this app. If the user 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/${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 selectedKeys.length\n ? `Dispatch will create pending vault requests for the selected keys for appId \"${appId}\" after this app creation request is accepted. Do not grant or sync vault keys directly from the app-creation branch.`\n : \"Do not grant or request any Dispatch vault keys unless the user asks later.\",\n selectedResources.length\n ? `Dispatch will create workspace resource grants for the selected resources for appId \"${appId}\". After the app exists, sync workspace resources so the app receives those shared resources. Add a short note to apps/${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 \"Agent-native rules (these are the framework's contract — not optional):\",\n `- Persist ALL data in SQL via Drizzle. Add tables to apps/${appId}/server/db/schema.ts and migrations to apps/${appId}/server/plugins/db.ts. NEVER use localStorage, sessionStorage, IndexedDB, or in-memory state for anything the user expects to persist — agent and UI must read the same source of truth.`,\n `- Define every create/read/update/delete as an action in apps/${appId}/actions/ using defineAction. The agent calls these as tools and the frontend calls them via useActionQuery / useActionMutation. If you must raw-fetch framework action endpoints, use agentNativePath(\"/_agent-native/actions/<name>\") so mounted apps call the right URL. Don't add /api/* routes for CRUD.`,\n \"- Build the UI from shadcn/ui components in app/components/ui/ (Button, Input, Dialog, Popover, Card, etc.) and Tailwind utilities. Don't author bespoke CSS classes in global.css unless you genuinely need a primitive that shadcn doesn't ship.\",\n \"- Use Tabler Icons (@tabler/icons-react) for every icon. Never use emojis as icons.\",\n `- Expose what the user is looking at via application_state (navigation.view, selection, etc.) so the agent has live context. Mirror the patterns in templates/mail or templates/slides.`,\n \"- Optimistic UI for every mutation: update the React Query cache immediately, navigate immediately, run the mutation in the background, roll back on error. Don't await a server round-trip before re-rendering.\",\n \"\",\n \"Branch readiness requirements before handing off:\",\n \"- The CLI auto-fills package.json name and displayName from the app id; only edit the description / scripts / dependencies if the app actually needs more than the template provides.\",\n \"- Do not add or update workspace-apps.json or .agent-native/workspace-apps.json unless the app needs an explicit external URL override; the root deploy generates the workspace app registry from apps/* and deploy metadata.\",\n \"- Update pnpm-lock.yaml when adding or changing dependencies so Netlify can install the branch reliably.\",\n \"- Update the app manifest/package/deploy metadata needed by the existing workspace deployment model; do not leave the branch relying only on uncommitted local state.\",\n \"- Verify the app's agent card/A2A metadata is ready so Dispatch can discover and delegate to the app after deployment.\",\n \"- Include a final verification note covering the registry entry, manifest/deploy metadata, and agent-card readiness.\",\n `When it is ready, start or update the workspace dev server and navigate the user to /${appId}.`,\n ].join(\"\\n\"),\n };\n}\n\nasync function requestSelectedVaultKeys(input: {\n appId: string;\n selectedKeys: string[];\n}) {\n if (input.selectedKeys.length === 0) return;\n await Promise.allSettled(\n input.selectedKeys.map((credentialKey) =>\n Promise.resolve().then(() =>\n createRequest({\n appId: input.appId,\n credentialKey,\n reason: `Requested during workspace app creation for ${input.appId}.`,\n }),\n ),\n ),\n );\n}\n\nasync function selectedWorkspaceResourcesForIds(\n resourceIds: string[] | undefined,\n): Promise<WorkspaceResourceOption[]> {\n if (!resourceIds?.length) return [];\n const requested = new Set(resourceIds);\n const resources = await listWorkspaceResourceOptions();\n return resources.filter((resource) => requested.has(resource.id));\n}\n\nasync function grantSelectedWorkspaceResources(input: {\n appId: string;\n resourceIds: string[];\n}) {\n if (input.resourceIds.length === 0) return;\n await grantWorkspaceResourcesToApp(input);\n}\n\nexport async function startWorkspaceAppCreation(input: {\n prompt: string;\n appId?: string | null;\n template?: string | null;\n secretIds?: string[];\n resourceIds?: string[];\n}) {\n const initial = buildWorkspaceAppPrompt({\n prompt: input.prompt,\n appId: input.appId,\n template: input.template,\n });\n assertValidWorkspaceAppId(initial.appId);\n const isLocal = isLocalAppCreationRuntime();\n\n if (!isLocal) {\n const authorization = await remoteAppCreationAuthorization();\n if (authorization.ok === false) {\n return {\n mode: \"builder-unavailable\",\n appId: initial.appId,\n message: authorization.message,\n };\n }\n }\n\n const selectedKeys = input.secretIds?.length\n ? (await listSecrets())\n .filter((secret) => input.secretIds?.includes(secret.id))\n .map((secret) => secret.credentialKey)\n : [];\n const selectedResources = await selectedWorkspaceResourcesForIds(\n input.resourceIds,\n );\n const built = buildWorkspaceAppPrompt({\n prompt: input.prompt,\n appId: input.appId,\n template: input.template,\n selectedKeys,\n selectedResources,\n });\n const prompt = built.prompt;\n\n if (isLocal) {\n await requestSelectedVaultKeys({\n appId: built.appId,\n selectedKeys,\n });\n await grantSelectedWorkspaceResources({\n appId: built.appId,\n resourceIds: selectedResources.map((resource) => resource.id),\n });\n return {\n mode: \"local-agent\",\n appId: built.appId,\n prompt,\n message:\n \"Use the local code agent to create this app in the workspace, then open it from /dispatch/apps.\",\n };\n }\n\n const settings = await getAppCreationSettings();\n\n if (!settings.builderProjectId) {\n return {\n mode: \"coming-soon\",\n appId: built.appId,\n message:\n \"Builder app creation is coming soon here. Set a default Builder project in Dispatch or provide BUILDER_BRANCH_PROJECT_ID to enable branch creation.\",\n };\n }\n\n let result: {\n branchName: string;\n url: string;\n status: string;\n };\n try {\n const builderCreds = await resolveBuilderCredentials().catch(() => null);\n const builderUserId = builderCreds?.userId || undefined;\n result = normalizeBuilderRunResult(\n await runBuilderAgent({\n prompt,\n projectId: settings.builderProjectId,\n ...(builderUserId\n ? { userId: builderUserId }\n : { userEmail: currentOwnerEmail() }),\n }),\n );\n } catch (err) {\n const detail =\n err instanceof Error && err.message\n ? err.message\n : \"Builder could not start the app branch\";\n return {\n mode: \"builder-unavailable\",\n appId: built.appId,\n projectId: settings.builderProjectId,\n message:\n `Builder app creation is configured for project ${settings.builderProjectId}, ` +\n `but it could not start yet: ${detail}. Connect Builder for this user, ` +\n `link the messaging identity to that user, or configure deployment-managed Builder credentials for this workspace.`,\n };\n }\n\n await recordPendingWorkspaceApp({\n appId: built.appId,\n projectId: settings.builderProjectId,\n branchName: result.branchName,\n builderUrl: result.url,\n });\n\n await requestSelectedVaultKeys({\n appId: built.appId,\n selectedKeys,\n });\n await grantSelectedWorkspaceResources({\n appId: built.appId,\n resourceIds: selectedResources.map((resource) => resource.id),\n });\n\n return {\n mode: \"builder\",\n appId: built.appId,\n path: `/${built.appId}`,\n projectId: settings.builderProjectId,\n branchName: result.branchName,\n url: result.url,\n workspaceUrl: workspaceAppUrl(`/${built.appId}`),\n status: result.status,\n message:\n `Builder started a branch for /${built.appId}. Use the Builder branch URL to track creation now. ` +\n `The workspace path will be live after that branch is merged and the workspace deploy finishes, so it may 404 until then.`,\n };\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@agent-native/dispatch",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.16",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Dispatch — workspace control plane for agent-native apps. Vault, integrations, destinations, scheduled jobs, and cross-app delegation, shipped as a single drop-in package.",
|
|
6
6
|
"license": "MIT",
|
|
@@ -96,7 +96,7 @@
|
|
|
96
96
|
"typescript": "^6.0.3",
|
|
97
97
|
"vite": "8.0.3",
|
|
98
98
|
"vitest": "^4.1.5",
|
|
99
|
-
"@agent-native/core": "0.12.
|
|
99
|
+
"@agent-native/core": "0.12.19"
|
|
100
100
|
},
|
|
101
101
|
"scripts": {
|
|
102
102
|
"build": "tsc && tsc-alias --resolve-full-paths",
|
|
@@ -98,6 +98,7 @@ function buildAppCreationPrompt(input: {
|
|
|
98
98
|
``,
|
|
99
99
|
`Suggested app name: ${input.appId} (you may adjust the slug if it conflicts)`,
|
|
100
100
|
`User prompt: ${input.prompt.trim()}`,
|
|
101
|
+
`If the user mentions a product or company such as Granola, Loom, Superhuman, Linear, or Notion, treat it as product inspiration unless they explicitly ask to connect to that service. Do not invent or require third-party API keys like GRANOLA_API_KEY just because a product is named.`,
|
|
101
102
|
grantRequest,
|
|
102
103
|
`Requested Dispatch workspace resources for this app:\n${resourceList}`,
|
|
103
104
|
``,
|
|
@@ -323,6 +324,7 @@ export function CreateAppFlow({
|
|
|
323
324
|
disabled={isSubmitting}
|
|
324
325
|
placeholder="Describe the app your teammate should be able to use..."
|
|
325
326
|
draftScope="dispatch:create-app"
|
|
327
|
+
preserveDraftOnSubmit
|
|
326
328
|
onSubmit={(text) => {
|
|
327
329
|
setPrompt(text);
|
|
328
330
|
submit(text);
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { afterEach, describe, expect, it, vi } from "vitest";
|
|
2
|
+
import { runWithRequestContext } from "@agent-native/core/server";
|
|
3
|
+
import { listWorkspaceApps } from "./app-creation-store.js";
|
|
4
|
+
|
|
5
|
+
const originalFetch = globalThis.fetch;
|
|
6
|
+
|
|
7
|
+
afterEach(() => {
|
|
8
|
+
vi.unstubAllEnvs();
|
|
9
|
+
vi.unstubAllGlobals();
|
|
10
|
+
globalThis.fetch = originalFetch;
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
describe("listWorkspaceApps", () => {
|
|
14
|
+
it("prefers the live workspace gateway manifest when available", async () => {
|
|
15
|
+
const fetchMock = vi.fn(async () => {
|
|
16
|
+
return new Response(
|
|
17
|
+
JSON.stringify({
|
|
18
|
+
apps: [
|
|
19
|
+
{
|
|
20
|
+
id: "dispatch",
|
|
21
|
+
name: "Agent-Native Dispatch",
|
|
22
|
+
path: "/dispatch",
|
|
23
|
+
},
|
|
24
|
+
{ id: "todo", name: "Todo", path: "/todo" },
|
|
25
|
+
],
|
|
26
|
+
}),
|
|
27
|
+
{ headers: { "content-type": "application/json" } },
|
|
28
|
+
);
|
|
29
|
+
});
|
|
30
|
+
vi.stubGlobal("fetch", fetchMock);
|
|
31
|
+
vi.stubEnv("WORKSPACE_GATEWAY_URL", "http://127.0.0.1:8080");
|
|
32
|
+
vi.stubEnv(
|
|
33
|
+
"AGENT_NATIVE_WORKSPACE_APPS_JSON",
|
|
34
|
+
JSON.stringify([{ id: "dispatch", name: "Dispatch", path: "/dispatch" }]),
|
|
35
|
+
);
|
|
36
|
+
|
|
37
|
+
const apps = await runWithRequestContext(
|
|
38
|
+
{ userEmail: "dev@example.test" },
|
|
39
|
+
() => listWorkspaceApps({ includeAgentCards: false }),
|
|
40
|
+
);
|
|
41
|
+
|
|
42
|
+
const [urlArg, init] = fetchMock.mock.calls[0] ?? [];
|
|
43
|
+
expect(String(urlArg)).toBe("http://127.0.0.1:8080/_workspace/apps");
|
|
44
|
+
expect(init).toEqual(
|
|
45
|
+
expect.objectContaining({
|
|
46
|
+
headers: { accept: "application/json" },
|
|
47
|
+
}),
|
|
48
|
+
);
|
|
49
|
+
expect(apps.map((app) => app.id)).toEqual(["dispatch", "todo"]);
|
|
50
|
+
});
|
|
51
|
+
});
|
|
@@ -29,6 +29,8 @@ import {
|
|
|
29
29
|
const SETTINGS_KEY = "dispatch-app-creation-settings";
|
|
30
30
|
const WORKSPACE_APPS_ENV_KEY = "AGENT_NATIVE_WORKSPACE_APPS_JSON";
|
|
31
31
|
const WORKSPACE_APPS_MANIFEST_FILE = "workspace-apps.json";
|
|
32
|
+
const WORKSPACE_APPS_GATEWAY_PATH = "/_workspace/apps";
|
|
33
|
+
const WORKSPACE_APPS_GATEWAY_TIMEOUT_MS = 1_000;
|
|
32
34
|
const MAX_PENDING_APPS = 50;
|
|
33
35
|
const AGENT_CARD_PATH = "/.well-known/agent-card.json";
|
|
34
36
|
const AGENT_CARD_FETCH_TIMEOUT_MS = 1_500;
|
|
@@ -455,6 +457,35 @@ function readWorkspaceAppsFromEnv(): WorkspaceAppSummary[] | null {
|
|
|
455
457
|
}
|
|
456
458
|
}
|
|
457
459
|
|
|
460
|
+
async function readWorkspaceAppsFromGateway(): Promise<
|
|
461
|
+
WorkspaceAppSummary[] | null
|
|
462
|
+
> {
|
|
463
|
+
const base = process.env.WORKSPACE_GATEWAY_URL;
|
|
464
|
+
if (!base) return null;
|
|
465
|
+
|
|
466
|
+
const controller = new AbortController();
|
|
467
|
+
const timeout = setTimeout(
|
|
468
|
+
() => controller.abort(),
|
|
469
|
+
WORKSPACE_APPS_GATEWAY_TIMEOUT_MS,
|
|
470
|
+
);
|
|
471
|
+
|
|
472
|
+
try {
|
|
473
|
+
const response = await fetch(
|
|
474
|
+
new URL(WORKSPACE_APPS_GATEWAY_PATH, `${base.replace(/\/$/, "")}/`),
|
|
475
|
+
{
|
|
476
|
+
headers: { accept: "application/json" },
|
|
477
|
+
signal: controller.signal,
|
|
478
|
+
},
|
|
479
|
+
);
|
|
480
|
+
if (!response.ok) return null;
|
|
481
|
+
return parseWorkspaceAppsManifest(await response.json().catch(() => null));
|
|
482
|
+
} catch {
|
|
483
|
+
return null;
|
|
484
|
+
} finally {
|
|
485
|
+
clearTimeout(timeout);
|
|
486
|
+
}
|
|
487
|
+
}
|
|
488
|
+
|
|
458
489
|
function workspaceAppsManifestCandidates(): string[] {
|
|
459
490
|
const candidates: string[] = [];
|
|
460
491
|
try {
|
|
@@ -569,6 +600,14 @@ export function getWorkspaceInfo(): WorkspaceInfo {
|
|
|
569
600
|
export async function listWorkspaceApps(
|
|
570
601
|
options: ListWorkspaceAppsOptions = {},
|
|
571
602
|
): Promise<WorkspaceAppSummary[]> {
|
|
603
|
+
const gatewayApps = await readWorkspaceAppsFromGateway();
|
|
604
|
+
if (gatewayApps) {
|
|
605
|
+
return maybeIncludeAgentCards(
|
|
606
|
+
await appendPendingWorkspaceApps(gatewayApps),
|
|
607
|
+
options,
|
|
608
|
+
);
|
|
609
|
+
}
|
|
610
|
+
|
|
572
611
|
const workspaceRoot = findWorkspaceRoot();
|
|
573
612
|
const localFilesystemApps =
|
|
574
613
|
workspaceRoot && isLocalAppCreationRuntime()
|
|
@@ -858,6 +897,7 @@ function buildWorkspaceAppPrompt(input: {
|
|
|
858
897
|
`App name: ${appId}`,
|
|
859
898
|
`Template to start from: ${input.template || "starter"}`,
|
|
860
899
|
`User prompt: ${input.prompt.trim()}`,
|
|
900
|
+
"If the user mentions a product or company such as Granola, Loom, Superhuman, Linear, or Notion, treat it as product inspiration unless they explicitly ask to connect to that service. Do not invent or require third-party API keys like GRANOLA_API_KEY just because a product is named.",
|
|
861
901
|
selectedKeys.length
|
|
862
902
|
? `Dispatch vault keys selected for this app: ${selectedKeys.join(", ")}`
|
|
863
903
|
: "Dispatch vault keys selected for this app: none",
|