@agent-native/core 0.7.51 → 0.7.53
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/a2a/artifact-response.d.ts.map +1 -1
- package/dist/a2a/artifact-response.js +109 -5
- package/dist/a2a/artifact-response.js.map +1 -1
- package/dist/a2a/server.d.ts.map +1 -1
- package/dist/a2a/server.js +11 -0
- package/dist/a2a/server.js.map +1 -1
- package/dist/cli/templates-meta.d.ts.map +1 -1
- package/dist/cli/templates-meta.js +1 -0
- package/dist/cli/templates-meta.js.map +1 -1
- package/dist/client/settings/VoiceTranscriptionSection.d.ts.map +1 -1
- package/dist/client/settings/VoiceTranscriptionSection.js +54 -13
- package/dist/client/settings/VoiceTranscriptionSection.js.map +1 -1
- package/dist/deploy/workspace-deploy.js +32 -3
- package/dist/deploy/workspace-deploy.js.map +1 -1
- package/dist/integrations/plugin.d.ts.map +1 -1
- package/dist/integrations/plugin.js +2 -1
- package/dist/integrations/plugin.js.map +1 -1
- package/dist/integrations/webhook-handler.d.ts.map +1 -1
- package/dist/integrations/webhook-handler.js +10 -0
- package/dist/integrations/webhook-handler.js.map +1 -1
- package/dist/onboarding/plugin.d.ts.map +1 -1
- package/dist/onboarding/plugin.js +2 -1
- package/dist/onboarding/plugin.js.map +1 -1
- package/dist/org/plugin.d.ts.map +1 -1
- package/dist/org/plugin.js +2 -1
- package/dist/org/plugin.js.map +1 -1
- package/dist/scripts/call-agent.js +2 -2
- package/dist/scripts/call-agent.js.map +1 -1
- package/dist/server/action-routes.d.ts.map +1 -1
- package/dist/server/action-routes.js +5 -11
- package/dist/server/action-routes.js.map +1 -1
- package/dist/server/agent-chat-plugin.d.ts.map +1 -1
- package/dist/server/agent-chat-plugin.js +2 -1
- package/dist/server/agent-chat-plugin.js.map +1 -1
- package/dist/server/auth-plugin.d.ts.map +1 -1
- package/dist/server/auth-plugin.js +2 -1
- package/dist/server/auth-plugin.js.map +1 -1
- package/dist/server/auth.d.ts.map +1 -1
- package/dist/server/auth.js +7 -12
- package/dist/server/auth.js.map +1 -1
- package/dist/server/core-routes-plugin.d.ts.map +1 -1
- package/dist/server/core-routes-plugin.js +9 -29
- package/dist/server/core-routes-plugin.js.map +1 -1
- package/dist/server/cors-origins.d.ts +10 -0
- package/dist/server/cors-origins.d.ts.map +1 -0
- package/dist/server/cors-origins.js +34 -0
- package/dist/server/cors-origins.js.map +1 -0
- package/dist/server/create-server.d.ts.map +1 -1
- package/dist/server/create-server.js +10 -29
- package/dist/server/create-server.js.map +1 -1
- package/dist/server/framework-request-handler.d.ts +11 -0
- package/dist/server/framework-request-handler.d.ts.map +1 -1
- package/dist/server/framework-request-handler.js +24 -1
- package/dist/server/framework-request-handler.js.map +1 -1
- package/dist/server/resources-plugin.d.ts.map +1 -1
- package/dist/server/resources-plugin.js +2 -1
- package/dist/server/resources-plugin.js.map +1 -1
- package/dist/terminal/terminal-plugin.d.ts.map +1 -1
- package/dist/terminal/terminal-plugin.js +2 -1
- package/dist/terminal/terminal-plugin.js.map +1 -1
- package/docs/content/a2a-protocol.md +93 -14
- package/docs/content/agent-mentions.md +2 -2
- package/docs/content/agent-teams.md +2 -2
- package/docs/content/client.md +1 -1
- package/docs/content/cloneable-saas.md +13 -13
- package/docs/content/creating-templates.md +253 -211
- package/docs/content/dispatch.md +94 -0
- package/docs/content/faq.md +2 -2
- package/docs/content/frames.md +1 -1
- package/docs/content/getting-started.md +9 -1
- package/docs/content/key-concepts.md +17 -1
- package/docs/content/messaging.md +56 -19
- package/docs/content/multi-app-workspace.md +10 -2
- package/docs/content/notifications.md +1 -1
- package/docs/content/observability.md +184 -0
- package/docs/content/onboarding.md +7 -2
- package/docs/content/server.md +117 -133
- package/docs/content/skills-guide.md +3 -3
- package/docs/content/template-analytics.md +8 -6
- package/docs/content/template-design.md +25 -27
- package/docs/content/template-dispatch.md +3 -1
- package/docs/content/template-forms.md +26 -21
- package/docs/content/template-mail.md +4 -0
- package/docs/content/template-video.md +4 -4
- package/docs/content/tools.md +95 -1
- package/docs/content/tracking.md +1 -1
- package/docs/content/what-is-agent-native.md +4 -2
- package/docs/content/workspace-management.md +5 -5
- package/docs/content/workspace.md +39 -30
- package/package.json +1 -1
|
@@ -10,9 +10,10 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
10
10
|
*/
|
|
11
11
|
import { useCallback, useEffect, useState } from "react";
|
|
12
12
|
import { agentNativePath } from "../api-path.js";
|
|
13
|
-
import { IconCheck, IconExternalLink, IconLoader2, IconMicrophone, } from "@tabler/icons-react";
|
|
13
|
+
import { IconCheck, IconChevronDown, IconChevronRight, IconExternalLink, IconLoader2, IconMicrophone, } from "@tabler/icons-react";
|
|
14
14
|
import { useBuilderStatus } from "./useBuilderStatus.js";
|
|
15
15
|
const PREFS_URL = agentNativePath("/_agent-native/application-state/voice-transcription-prefs");
|
|
16
|
+
const CLEANUP_PREFS_URL = agentNativePath("/_agent-native/application-state/voice-cleanup-prefs");
|
|
16
17
|
const SECRETS_URL = agentNativePath("/_agent-native/secrets");
|
|
17
18
|
const PROVIDER_STATUS_URL = agentNativePath("/_agent-native/voice-providers/status");
|
|
18
19
|
const DEFAULT_PROVIDER = "browser";
|
|
@@ -33,7 +34,45 @@ export function VoiceTranscriptionSection() {
|
|
|
33
34
|
const [groqConfigured, setGroqConfigured] = useState(null);
|
|
34
35
|
const [saving, setSaving] = useState(false);
|
|
35
36
|
const [saveError, setSaveError] = useState(null);
|
|
37
|
+
const [showAdvanced, setShowAdvanced] = useState(false);
|
|
38
|
+
const [cleanupEnabled, setCleanupEnabled] = useState(null);
|
|
36
39
|
const { status: builderStatus } = useBuilderStatus();
|
|
40
|
+
// Read cleanup pref (default: true if Builder is connected).
|
|
41
|
+
useEffect(() => {
|
|
42
|
+
let cancelled = false;
|
|
43
|
+
fetch(CLEANUP_PREFS_URL)
|
|
44
|
+
.then((r) => (r.ok ? r.json() : null))
|
|
45
|
+
.then((body) => {
|
|
46
|
+
if (cancelled)
|
|
47
|
+
return;
|
|
48
|
+
const stored = body?.enabled ??
|
|
49
|
+
body?.value?.enabled;
|
|
50
|
+
if (typeof stored === "boolean")
|
|
51
|
+
setCleanupEnabled(stored);
|
|
52
|
+
else
|
|
53
|
+
setCleanupEnabled(null); // resolve once builderStatus arrives
|
|
54
|
+
})
|
|
55
|
+
.catch(() => !cancelled && setCleanupEnabled(null));
|
|
56
|
+
return () => {
|
|
57
|
+
cancelled = true;
|
|
58
|
+
};
|
|
59
|
+
}, []);
|
|
60
|
+
useEffect(() => {
|
|
61
|
+
if (cleanupEnabled !== null)
|
|
62
|
+
return;
|
|
63
|
+
if (builderStatus?.configured !== undefined) {
|
|
64
|
+
setCleanupEnabled(!!builderStatus.configured);
|
|
65
|
+
}
|
|
66
|
+
}, [builderStatus?.configured, cleanupEnabled]);
|
|
67
|
+
const toggleCleanup = (next) => {
|
|
68
|
+
const previous = cleanupEnabled;
|
|
69
|
+
setCleanupEnabled(next);
|
|
70
|
+
fetch(CLEANUP_PREFS_URL, {
|
|
71
|
+
method: "PUT",
|
|
72
|
+
headers: { "Content-Type": "application/json" },
|
|
73
|
+
body: JSON.stringify({ enabled: next }),
|
|
74
|
+
}).catch(() => setCleanupEnabled(previous));
|
|
75
|
+
};
|
|
37
76
|
useEffect(() => {
|
|
38
77
|
let cancelled = false;
|
|
39
78
|
fetch(PREFS_URL)
|
|
@@ -149,22 +188,24 @@ export function VoiceTranscriptionSection() {
|
|
|
149
188
|
return;
|
|
150
189
|
window.location.hash = `#secrets:${key}`;
|
|
151
190
|
};
|
|
152
|
-
return (_jsxs("div", { className: "space-y-2", children: [_jsx(ProviderOption, { id: "
|
|
153
|
-
e.stopPropagation();
|
|
154
|
-
focusKey("OPENAI_API_KEY");
|
|
155
|
-
}, className: "inline-flex items-center gap-1 rounded border border-border px-2 py-0.5 text-[10px] text-muted-foreground hover:text-foreground hover:bg-accent/40", children: ["Add key", _jsx(IconExternalLink, { size: 10 })] })) }), _jsx(ProviderOption, { id: "builder-gemini", selected: provider === "builder-gemini", onSelect: () => choose("builder-gemini"), disabled: !builderStatus?.configured, title: "Builder.io", subtitle: builderStatus?.configured
|
|
191
|
+
return (_jsxs("div", { className: "space-y-2", children: [_jsx(ProviderOption, { id: "builder-gemini", selected: provider === "builder-gemini", onSelect: () => choose("builder-gemini"), disabled: !builderStatus?.configured, title: "Builder.io Connect (recommended)", subtitle: builderStatus?.configured
|
|
156
192
|
? "Fast Gemini Flash-Lite transcription and cleanup through Builder.io. No Google key needed."
|
|
157
|
-
: "
|
|
193
|
+
: "One-click connect — uses Gemini Flash-Lite without a Google key.", rightSlot: builderStatus?.configured ? (_jsxs("span", { className: "flex items-center gap-1 text-[10px] text-green-500", children: [_jsx(IconCheck, { size: 10 }), "Connected"] })) : (_jsxs("button", { type: "button", onClick: (e) => {
|
|
158
194
|
e.stopPropagation();
|
|
159
195
|
const url = new URL(agentNativePath("/_agent-native/builder/connect"), window.location.origin).href;
|
|
160
196
|
window.open(url, "_blank", "noopener,noreferrer,width=600,height=700");
|
|
161
|
-
}, className: "inline-flex items-center gap-1 rounded border border-border px-2 py-0.5 text-[10px] text-muted-foreground hover:text-foreground hover:bg-accent/40", children: ["Connect Builder.io", _jsx(IconExternalLink, { size: 10 })] })) }),
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
197
|
+
}, className: "inline-flex items-center gap-1 rounded border border-border px-2 py-0.5 text-[10px] text-muted-foreground hover:text-foreground hover:bg-accent/40", children: ["Connect Builder.io", _jsx(IconExternalLink, { size: 10 })] })) }), _jsxs("div", { className: "flex items-start justify-between gap-3 rounded-md border border-border bg-accent/30 px-2.5 py-2", children: [_jsxs("div", { className: "min-w-0", children: [_jsx("div", { className: "text-[11px] font-medium text-foreground", children: "Cleanup transcripts with AI" }), _jsx("p", { className: "text-[10px] text-muted-foreground mt-0.5", children: "Polish punctuation, casing, and remove filler words after each recording." })] }), _jsx("button", { type: "button", role: "switch", "aria-checked": !!cleanupEnabled, onClick: () => toggleCleanup(!cleanupEnabled), className: `relative inline-flex h-4 w-7 shrink-0 cursor-pointer items-center rounded-full transition-colors ${cleanupEnabled
|
|
198
|
+
? "bg-[#625DF5]"
|
|
199
|
+
: "bg-muted-foreground/30 hover:bg-muted-foreground/50"}`, children: _jsx("span", { className: `inline-block h-3 w-3 transform rounded-full bg-background transition-transform ${cleanupEnabled ? "translate-x-3.5" : "translate-x-0.5"}` }) })] }), _jsxs("div", { className: "rounded-md border border-border bg-background", children: [_jsxs("button", { type: "button", onClick: () => setShowAdvanced((v) => !v), className: "w-full flex items-center justify-between gap-2 px-2.5 py-2 cursor-pointer", children: [_jsxs("span", { className: "text-[11px] font-medium text-foreground inline-flex items-center gap-1", children: [showAdvanced ? (_jsx(IconChevronDown, { size: 12 })) : (_jsx(IconChevronRight, { size: 12 })), "Add API keys"] }), _jsx("span", { className: "text-[10px] text-muted-foreground", children: "OpenAI \u00B7 Gemini \u00B7 Groq \u00B7 browser" })] }), showAdvanced && (_jsxs("div", { className: "px-2 pb-2 space-y-2", children: [_jsx(ProviderOption, { id: "openai", selected: provider === "openai", onSelect: () => choose("openai"), title: "OpenAI Whisper", subtitle: "Best quality. Requires an OpenAI API key.", rightSlot: openAiConfigured === null ? null : openAiConfigured ? (_jsxs("span", { className: "flex items-center gap-1 text-[10px] text-green-500", children: [_jsx(IconCheck, { size: 10 }), "Key set"] })) : (_jsxs("button", { type: "button", onClick: (e) => {
|
|
200
|
+
e.stopPropagation();
|
|
201
|
+
focusKey("OPENAI_API_KEY");
|
|
202
|
+
}, className: "inline-flex items-center gap-1 rounded border border-border px-2 py-0.5 text-[10px] text-muted-foreground hover:text-foreground hover:bg-accent/40", children: ["Add key", _jsx(IconExternalLink, { size: 10 })] })) }), _jsx(ProviderOption, { id: "gemini", selected: provider === "gemini", onSelect: () => choose("gemini"), title: "Google Gemini", subtitle: "Fast transcription via Gemini Flash Lite. Requires a Gemini API key.", rightSlot: geminiConfigured === null ? null : geminiConfigured ? (_jsxs("span", { className: "flex items-center gap-1 text-[10px] text-green-500", children: [_jsx(IconCheck, { size: 10 }), "Key set"] })) : (_jsxs("button", { type: "button", onClick: (e) => {
|
|
203
|
+
e.stopPropagation();
|
|
204
|
+
focusKey("GEMINI_API_KEY");
|
|
205
|
+
}, className: "inline-flex items-center gap-1 rounded border border-border px-2 py-0.5 text-[10px] text-muted-foreground hover:text-foreground hover:bg-accent/40", children: ["Add key", _jsx(IconExternalLink, { size: 10 })] })) }), _jsx(ProviderOption, { id: "groq", selected: provider === "groq", onSelect: () => choose("groq"), title: "Groq Whisper", subtitle: "Fastest Whisper inference. Requires a Groq API key.", rightSlot: groqConfigured === null ? null : groqConfigured ? (_jsxs("span", { className: "flex items-center gap-1 text-[10px] text-green-500", children: [_jsx(IconCheck, { size: 10 }), "Key set"] })) : (_jsxs("button", { type: "button", onClick: (e) => {
|
|
206
|
+
e.stopPropagation();
|
|
207
|
+
focusKey("GROQ_API_KEY");
|
|
208
|
+
}, className: "inline-flex items-center gap-1 rounded border border-border px-2 py-0.5 text-[10px] text-muted-foreground hover:text-foreground hover:bg-accent/40", children: ["Add key", _jsx(IconExternalLink, { size: 10 })] })) }), _jsx(ProviderOption, { id: "browser", selected: provider === "browser", onSelect: () => choose("browser"), title: "Native browser", subtitle: "Free built-in speech recognition. No key required." })] }))] }), provider !== "browser" && (_jsxs("div", { className: "rounded-md border border-border bg-accent/20 px-2.5 py-2", children: [_jsx("label", { htmlFor: "voice-transcription-instructions", className: "block text-[10px] font-medium text-foreground", children: "Custom instructions" }), _jsx("textarea", { id: "voice-transcription-instructions", value: instructions, onChange: (event) => updateInstructions(event.target.value), placeholder: "Names, casing, punctuation, style, or terms to preserve.", className: "mt-1 min-h-16 w-full resize-y rounded border border-border bg-background px-2 py-1.5 text-[11px] text-foreground outline-none placeholder:text-muted-foreground/50 focus:ring-1 focus:ring-accent" }), _jsx("p", { className: "mt-1 text-[10px] text-muted-foreground", children: "Included with LLM-based transcription and cleanup." })] })), saving && _jsx("p", { className: "text-[10px] text-muted-foreground", children: "Saving\u2026" }), saveError && !saving && (_jsx("p", { className: "text-[10px] text-red-500", role: "alert", children: saveError }))] }));
|
|
168
209
|
}
|
|
169
210
|
function ProviderOption({ id, selected, disabled, onSelect, title, subtitle, rightSlot, }) {
|
|
170
211
|
const select = () => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"VoiceTranscriptionSection.js","sourceRoot":"","sources":["../../../src/client/settings/VoiceTranscriptionSection.tsx"],"names":[],"mappings":"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","sourcesContent":["/**\n * <VoiceTranscriptionSection /> — provider picker for composer voice input.\n *\n * Writes the selection to application_state under `voice-transcription-prefs`\n * so the composer's `useVoiceDictation` hook picks it up on next record.\n *\n * Provider status comes from `/_agent-native/voice-providers/status`, which\n * mirrors the server transcription route's key/env resolution.\n */\n\nimport React, { useCallback, useEffect, useState } from \"react\";\nimport { agentNativePath } from \"../api-path.js\";\nimport {\n IconCheck,\n IconExternalLink,\n IconLoader2,\n IconMicrophone,\n} from \"@tabler/icons-react\";\nimport { useBuilderStatus } from \"./useBuilderStatus.js\";\n\ntype Provider =\n | \"openai\"\n | \"builder-gemini\"\n | \"builder\"\n | \"browser\"\n | \"gemini\"\n | \"groq\";\n\ninterface Prefs {\n provider: Provider;\n instructions?: string;\n}\n\ninterface SecretStatus {\n key: string;\n status: \"set\" | \"unset\" | \"invalid\";\n}\n\ninterface ProviderStatus {\n builder: boolean;\n gemini: boolean;\n openai: boolean;\n groq: boolean;\n browser: true;\n}\n\nconst PREFS_URL = agentNativePath(\n \"/_agent-native/application-state/voice-transcription-prefs\",\n);\nconst SECRETS_URL = agentNativePath(\"/_agent-native/secrets\");\nconst PROVIDER_STATUS_URL = agentNativePath(\n \"/_agent-native/voice-providers/status\",\n);\nconst DEFAULT_PROVIDER: Provider = \"browser\";\n\nfunction isProvider(value: unknown): value is Provider {\n return (\n value === \"openai\" ||\n value === \"builder-gemini\" ||\n value === \"builder\" ||\n value === \"browser\" ||\n value === \"gemini\" ||\n value === \"groq\"\n );\n}\n\nexport function VoiceTranscriptionSection() {\n const [provider, setProvider] = useState<Provider | null>(null);\n const [instructions, setInstructions] = useState(\"\");\n const [hasStoredProvider, setHasStoredProvider] = useState(false);\n const [openAiConfigured, setOpenAiConfigured] = useState<boolean | null>(\n null,\n );\n const [geminiConfigured, setGeminiConfigured] = useState<boolean | null>(\n null,\n );\n const [groqConfigured, setGroqConfigured] = useState<boolean | null>(null);\n const [saving, setSaving] = useState(false);\n const [saveError, setSaveError] = useState<string | null>(null);\n const { status: builderStatus } = useBuilderStatus();\n\n useEffect(() => {\n let cancelled = false;\n fetch(PREFS_URL)\n .then((r) => (r.ok ? r.json() : null))\n .then((body: Prefs | { value?: Prefs } | null) => {\n if (cancelled) return;\n const p =\n (body as Prefs | null)?.provider ??\n (body as { value?: Prefs } | null)?.value?.provider;\n const savedInstructions =\n (body as Prefs | null)?.instructions ??\n (body as { value?: Prefs } | null)?.value?.instructions;\n setHasStoredProvider(isProvider(p));\n setProvider(\n isProvider(p)\n ? p === \"builder\"\n ? \"builder-gemini\"\n : p\n : DEFAULT_PROVIDER,\n );\n if (typeof savedInstructions === \"string\") {\n setInstructions(savedInstructions);\n }\n })\n .catch(() => !cancelled && setProvider(DEFAULT_PROVIDER));\n return () => {\n cancelled = true;\n };\n }, []);\n\n useEffect(() => {\n if (hasStoredProvider || provider === null) return;\n if (builderStatus?.configured) setProvider(\"builder-gemini\");\n }, [builderStatus?.configured, hasStoredProvider, provider]);\n\n useEffect(() => {\n let cancelled = false;\n fetch(PROVIDER_STATUS_URL)\n .then((r) => (r.ok ? r.json() : null))\n .then((status: ProviderStatus | null) => {\n if (cancelled) return;\n if (status) {\n setOpenAiConfigured(status.openai);\n setGeminiConfigured(status.gemini);\n setGroqConfigured(status.groq);\n return;\n }\n return fetch(SECRETS_URL)\n .then((r) => (r.ok ? r.json() : []))\n .then((list: SecretStatus[]) => {\n if (cancelled) return;\n const find = (key: string) =>\n Array.isArray(list) ? list.find((s) => s.key === key) : null;\n setOpenAiConfigured(find(\"OPENAI_API_KEY\")?.status === \"set\");\n setGeminiConfigured(find(\"GEMINI_API_KEY\")?.status === \"set\");\n setGroqConfigured(find(\"GROQ_API_KEY\")?.status === \"set\");\n });\n })\n .catch(() => {\n if (!cancelled) {\n setOpenAiConfigured(false);\n setGeminiConfigured(false);\n setGroqConfigured(false);\n }\n });\n return () => {\n cancelled = true;\n };\n }, []);\n\n const persist = useCallback(\n async (\n nextProvider: Provider,\n nextInstructions: string,\n previous: { provider: Provider | null; instructions: string },\n ) => {\n setSaving(true);\n setSaveError(null);\n try {\n const res = await fetch(PREFS_URL, {\n method: \"PUT\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({\n provider: nextProvider,\n instructions: nextInstructions.trim(),\n }),\n });\n if (!res.ok) {\n throw new Error(`HTTP ${res.status}`);\n }\n } catch (err) {\n // Revert the optimistic update so the UI matches server state.\n setProvider(previous.provider);\n setInstructions(previous.instructions);\n setSaveError(\n `Couldn't save: ${(err as Error)?.message ?? \"network error\"}. Try again.`,\n );\n } finally {\n setSaving(false);\n }\n },\n [],\n );\n\n const choose = (next: Provider) => {\n if (next === provider) return;\n const previous = { provider, instructions };\n setHasStoredProvider(true);\n setProvider(next);\n void persist(next, instructions, previous);\n };\n\n const updateInstructions = (next: string) => {\n const previous = { provider, instructions };\n setInstructions(next);\n if (provider) void persist(provider, next, previous);\n };\n\n if (provider === null) {\n return (\n <div className=\"flex items-center gap-1.5 text-[10px] text-muted-foreground\">\n <IconLoader2 size={10} className=\"animate-spin\" />\n Loading…\n </div>\n );\n }\n\n const focusKey = (key: string) => {\n if (typeof window === \"undefined\") return;\n window.location.hash = `#secrets:${key}`;\n };\n\n return (\n <div className=\"space-y-2\">\n <ProviderOption\n id=\"openai\"\n selected={provider === \"openai\"}\n onSelect={() => choose(\"openai\")}\n title=\"OpenAI Whisper\"\n subtitle=\"Best quality. Requires an OpenAI API key.\"\n rightSlot={\n openAiConfigured === null ? null : openAiConfigured ? (\n <span className=\"flex items-center gap-1 text-[10px] text-green-500\">\n <IconCheck size={10} />\n Key set\n </span>\n ) : (\n <button\n type=\"button\"\n onClick={(e) => {\n e.stopPropagation();\n focusKey(\"OPENAI_API_KEY\");\n }}\n className=\"inline-flex items-center gap-1 rounded border border-border px-2 py-0.5 text-[10px] text-muted-foreground hover:text-foreground hover:bg-accent/40\"\n >\n Add key\n <IconExternalLink size={10} />\n </button>\n )\n }\n />\n\n <ProviderOption\n id=\"builder-gemini\"\n selected={provider === \"builder-gemini\"}\n onSelect={() => choose(\"builder-gemini\")}\n disabled={!builderStatus?.configured}\n title=\"Builder.io\"\n subtitle={\n builderStatus?.configured\n ? \"Fast Gemini Flash-Lite transcription and cleanup through Builder.io. No Google key needed.\"\n : \"Connect Builder.io to use Gemini Flash-Lite without a Google key.\"\n }\n rightSlot={\n builderStatus?.configured ? (\n <span className=\"flex items-center gap-1 text-[10px] text-green-500\">\n <IconCheck size={10} />\n Connected\n </span>\n ) : (\n <button\n type=\"button\"\n onClick={(e) => {\n e.stopPropagation();\n const url = new URL(\n agentNativePath(\"/_agent-native/builder/connect\"),\n window.location.origin,\n ).href;\n window.open(\n url,\n \"_blank\",\n \"noopener,noreferrer,width=600,height=700\",\n );\n }}\n className=\"inline-flex items-center gap-1 rounded border border-border px-2 py-0.5 text-[10px] text-muted-foreground hover:text-foreground hover:bg-accent/40\"\n >\n Connect Builder.io\n <IconExternalLink size={10} />\n </button>\n )\n }\n />\n\n <ProviderOption\n id=\"gemini\"\n selected={provider === \"gemini\"}\n onSelect={() => choose(\"gemini\")}\n title=\"Google Gemini\"\n subtitle=\"Fast transcription via Gemini Flash Lite. Requires a Gemini API key.\"\n rightSlot={\n geminiConfigured === null ? null : geminiConfigured ? (\n <span className=\"flex items-center gap-1 text-[10px] text-green-500\">\n <IconCheck size={10} />\n Key set\n </span>\n ) : (\n <button\n type=\"button\"\n onClick={(e) => {\n e.stopPropagation();\n focusKey(\"GEMINI_API_KEY\");\n }}\n className=\"inline-flex items-center gap-1 rounded border border-border px-2 py-0.5 text-[10px] text-muted-foreground hover:text-foreground hover:bg-accent/40\"\n >\n Add key\n <IconExternalLink size={10} />\n </button>\n )\n }\n />\n\n <ProviderOption\n id=\"groq\"\n selected={provider === \"groq\"}\n onSelect={() => choose(\"groq\")}\n title=\"Groq Whisper\"\n subtitle=\"Fastest Whisper inference. Requires a Groq API key.\"\n rightSlot={\n groqConfigured === null ? null : groqConfigured ? (\n <span className=\"flex items-center gap-1 text-[10px] text-green-500\">\n <IconCheck size={10} />\n Key set\n </span>\n ) : (\n <button\n type=\"button\"\n onClick={(e) => {\n e.stopPropagation();\n focusKey(\"GROQ_API_KEY\");\n }}\n className=\"inline-flex items-center gap-1 rounded border border-border px-2 py-0.5 text-[10px] text-muted-foreground hover:text-foreground hover:bg-accent/40\"\n >\n Add key\n <IconExternalLink size={10} />\n </button>\n )\n }\n />\n\n <ProviderOption\n id=\"browser\"\n selected={provider === \"browser\"}\n onSelect={() => choose(\"browser\")}\n title=\"Native browser\"\n subtitle=\"Free built-in speech recognition. No key required.\"\n />\n\n {provider !== \"browser\" && (\n <div className=\"rounded-md border border-border bg-accent/20 px-2.5 py-2\">\n <label\n htmlFor=\"voice-transcription-instructions\"\n className=\"block text-[10px] font-medium text-foreground\"\n >\n Custom instructions\n </label>\n <textarea\n id=\"voice-transcription-instructions\"\n value={instructions}\n onChange={(event) => updateInstructions(event.target.value)}\n placeholder=\"Names, casing, punctuation, style, or terms to preserve.\"\n className=\"mt-1 min-h-16 w-full resize-y rounded border border-border bg-background px-2 py-1.5 text-[11px] text-foreground outline-none placeholder:text-muted-foreground/50 focus:ring-1 focus:ring-accent\"\n />\n <p className=\"mt-1 text-[10px] text-muted-foreground\">\n Included with LLM-based transcription and cleanup.\n </p>\n </div>\n )}\n\n {saving && <p className=\"text-[10px] text-muted-foreground\">Saving…</p>}\n {saveError && !saving && (\n <p className=\"text-[10px] text-red-500\" role=\"alert\">\n {saveError}\n </p>\n )}\n </div>\n );\n}\n\ninterface ProviderOptionProps {\n id: string;\n selected: boolean;\n disabled?: boolean;\n onSelect: () => void;\n title: string;\n subtitle?: React.ReactNode;\n rightSlot?: React.ReactNode;\n}\n\nfunction ProviderOption({\n id,\n selected,\n disabled,\n onSelect,\n title,\n subtitle,\n rightSlot,\n}: ProviderOptionProps) {\n const select = () => {\n if (!disabled) onSelect();\n };\n\n const onKeyDown = (event: React.KeyboardEvent<HTMLDivElement>) => {\n if (disabled) return;\n if (event.key === \"Enter\" || event.key === \" \") {\n event.preventDefault();\n onSelect();\n }\n };\n\n return (\n <div\n role=\"button\"\n tabIndex={disabled ? -1 : 0}\n onClick={select}\n onKeyDown={onKeyDown}\n aria-pressed={selected}\n aria-disabled={disabled || undefined}\n className={`w-full text-left rounded-md border px-2.5 py-2 flex items-start gap-2 ${\n selected\n ? \"border-[#625DF5] bg-[#625DF5]/10\"\n : \"border-border bg-accent/30 hover:bg-accent/50\"\n } ${disabled ? \"opacity-60 cursor-not-allowed\" : \"\"}`}\n >\n <span\n className={`mt-[2px] shrink-0 flex h-3.5 w-3.5 items-center justify-center rounded-full border ${\n selected\n ? \"border-[#625DF5] bg-[#625DF5]\"\n : \"border-muted-foreground/40 bg-background\"\n }`}\n >\n {selected && (\n <span className=\"h-1.5 w-1.5 rounded-full bg-background\" />\n )}\n </span>\n <div className=\"min-w-0 flex-1\">\n <div className=\"flex items-center justify-between gap-2\">\n <div className=\"text-[11px] font-medium text-foreground\">{title}</div>\n {rightSlot && <div className=\"shrink-0\">{rightSlot}</div>}\n </div>\n {subtitle && (\n <p className=\"text-[10px] text-muted-foreground mt-0.5\">{subtitle}</p>\n )}\n </div>\n </div>\n );\n}\n\nexport function VoiceTranscriptionIcon() {\n return <IconMicrophone size={14} />;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"VoiceTranscriptionSection.js","sourceRoot":"","sources":["../../../src/client/settings/VoiceTranscriptionSection.tsx"],"names":[],"mappings":"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","sourcesContent":["/**\n * <VoiceTranscriptionSection /> — provider picker for composer voice input.\n *\n * Writes the selection to application_state under `voice-transcription-prefs`\n * so the composer's `useVoiceDictation` hook picks it up on next record.\n *\n * Provider status comes from `/_agent-native/voice-providers/status`, which\n * mirrors the server transcription route's key/env resolution.\n */\n\nimport React, { useCallback, useEffect, useState } from \"react\";\nimport { agentNativePath } from \"../api-path.js\";\nimport {\n IconCheck,\n IconChevronDown,\n IconChevronRight,\n IconExternalLink,\n IconLoader2,\n IconMicrophone,\n} from \"@tabler/icons-react\";\nimport { useBuilderStatus } from \"./useBuilderStatus.js\";\n\ntype Provider =\n | \"openai\"\n | \"builder-gemini\"\n | \"builder\"\n | \"browser\"\n | \"gemini\"\n | \"groq\";\n\ninterface Prefs {\n provider: Provider;\n instructions?: string;\n}\n\ninterface SecretStatus {\n key: string;\n status: \"set\" | \"unset\" | \"invalid\";\n}\n\ninterface ProviderStatus {\n builder: boolean;\n gemini: boolean;\n openai: boolean;\n groq: boolean;\n browser: true;\n}\n\nconst PREFS_URL = agentNativePath(\n \"/_agent-native/application-state/voice-transcription-prefs\",\n);\nconst CLEANUP_PREFS_URL = agentNativePath(\n \"/_agent-native/application-state/voice-cleanup-prefs\",\n);\nconst SECRETS_URL = agentNativePath(\"/_agent-native/secrets\");\nconst PROVIDER_STATUS_URL = agentNativePath(\n \"/_agent-native/voice-providers/status\",\n);\nconst DEFAULT_PROVIDER: Provider = \"browser\";\n\nfunction isProvider(value: unknown): value is Provider {\n return (\n value === \"openai\" ||\n value === \"builder-gemini\" ||\n value === \"builder\" ||\n value === \"browser\" ||\n value === \"gemini\" ||\n value === \"groq\"\n );\n}\n\nexport function VoiceTranscriptionSection() {\n const [provider, setProvider] = useState<Provider | null>(null);\n const [instructions, setInstructions] = useState(\"\");\n const [hasStoredProvider, setHasStoredProvider] = useState(false);\n const [openAiConfigured, setOpenAiConfigured] = useState<boolean | null>(\n null,\n );\n const [geminiConfigured, setGeminiConfigured] = useState<boolean | null>(\n null,\n );\n const [groqConfigured, setGroqConfigured] = useState<boolean | null>(null);\n const [saving, setSaving] = useState(false);\n const [saveError, setSaveError] = useState<string | null>(null);\n const [showAdvanced, setShowAdvanced] = useState(false);\n const [cleanupEnabled, setCleanupEnabled] = useState<boolean | null>(null);\n const { status: builderStatus } = useBuilderStatus();\n\n // Read cleanup pref (default: true if Builder is connected).\n useEffect(() => {\n let cancelled = false;\n fetch(CLEANUP_PREFS_URL)\n .then((r) => (r.ok ? r.json() : null))\n .then(\n (\n body:\n | { enabled?: boolean }\n | { value?: { enabled?: boolean } }\n | null,\n ) => {\n if (cancelled) return;\n const stored =\n (body as { enabled?: boolean } | null)?.enabled ??\n (body as { value?: { enabled?: boolean } } | null)?.value?.enabled;\n if (typeof stored === \"boolean\") setCleanupEnabled(stored);\n else setCleanupEnabled(null); // resolve once builderStatus arrives\n },\n )\n .catch(() => !cancelled && setCleanupEnabled(null));\n return () => {\n cancelled = true;\n };\n }, []);\n\n useEffect(() => {\n if (cleanupEnabled !== null) return;\n if (builderStatus?.configured !== undefined) {\n setCleanupEnabled(!!builderStatus.configured);\n }\n }, [builderStatus?.configured, cleanupEnabled]);\n\n const toggleCleanup = (next: boolean) => {\n const previous = cleanupEnabled;\n setCleanupEnabled(next);\n fetch(CLEANUP_PREFS_URL, {\n method: \"PUT\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({ enabled: next }),\n }).catch(() => setCleanupEnabled(previous));\n };\n\n useEffect(() => {\n let cancelled = false;\n fetch(PREFS_URL)\n .then((r) => (r.ok ? r.json() : null))\n .then((body: Prefs | { value?: Prefs } | null) => {\n if (cancelled) return;\n const p =\n (body as Prefs | null)?.provider ??\n (body as { value?: Prefs } | null)?.value?.provider;\n const savedInstructions =\n (body as Prefs | null)?.instructions ??\n (body as { value?: Prefs } | null)?.value?.instructions;\n setHasStoredProvider(isProvider(p));\n setProvider(\n isProvider(p)\n ? p === \"builder\"\n ? \"builder-gemini\"\n : p\n : DEFAULT_PROVIDER,\n );\n if (typeof savedInstructions === \"string\") {\n setInstructions(savedInstructions);\n }\n })\n .catch(() => !cancelled && setProvider(DEFAULT_PROVIDER));\n return () => {\n cancelled = true;\n };\n }, []);\n\n useEffect(() => {\n if (hasStoredProvider || provider === null) return;\n if (builderStatus?.configured) setProvider(\"builder-gemini\");\n }, [builderStatus?.configured, hasStoredProvider, provider]);\n\n useEffect(() => {\n let cancelled = false;\n fetch(PROVIDER_STATUS_URL)\n .then((r) => (r.ok ? r.json() : null))\n .then((status: ProviderStatus | null) => {\n if (cancelled) return;\n if (status) {\n setOpenAiConfigured(status.openai);\n setGeminiConfigured(status.gemini);\n setGroqConfigured(status.groq);\n return;\n }\n return fetch(SECRETS_URL)\n .then((r) => (r.ok ? r.json() : []))\n .then((list: SecretStatus[]) => {\n if (cancelled) return;\n const find = (key: string) =>\n Array.isArray(list) ? list.find((s) => s.key === key) : null;\n setOpenAiConfigured(find(\"OPENAI_API_KEY\")?.status === \"set\");\n setGeminiConfigured(find(\"GEMINI_API_KEY\")?.status === \"set\");\n setGroqConfigured(find(\"GROQ_API_KEY\")?.status === \"set\");\n });\n })\n .catch(() => {\n if (!cancelled) {\n setOpenAiConfigured(false);\n setGeminiConfigured(false);\n setGroqConfigured(false);\n }\n });\n return () => {\n cancelled = true;\n };\n }, []);\n\n const persist = useCallback(\n async (\n nextProvider: Provider,\n nextInstructions: string,\n previous: { provider: Provider | null; instructions: string },\n ) => {\n setSaving(true);\n setSaveError(null);\n try {\n const res = await fetch(PREFS_URL, {\n method: \"PUT\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({\n provider: nextProvider,\n instructions: nextInstructions.trim(),\n }),\n });\n if (!res.ok) {\n throw new Error(`HTTP ${res.status}`);\n }\n } catch (err) {\n // Revert the optimistic update so the UI matches server state.\n setProvider(previous.provider);\n setInstructions(previous.instructions);\n setSaveError(\n `Couldn't save: ${(err as Error)?.message ?? \"network error\"}. Try again.`,\n );\n } finally {\n setSaving(false);\n }\n },\n [],\n );\n\n const choose = (next: Provider) => {\n if (next === provider) return;\n const previous = { provider, instructions };\n setHasStoredProvider(true);\n setProvider(next);\n void persist(next, instructions, previous);\n };\n\n const updateInstructions = (next: string) => {\n const previous = { provider, instructions };\n setInstructions(next);\n if (provider) void persist(provider, next, previous);\n };\n\n if (provider === null) {\n return (\n <div className=\"flex items-center gap-1.5 text-[10px] text-muted-foreground\">\n <IconLoader2 size={10} className=\"animate-spin\" />\n Loading…\n </div>\n );\n }\n\n const focusKey = (key: string) => {\n if (typeof window === \"undefined\") return;\n window.location.hash = `#secrets:${key}`;\n };\n\n return (\n <div className=\"space-y-2\">\n <ProviderOption\n id=\"builder-gemini\"\n selected={provider === \"builder-gemini\"}\n onSelect={() => choose(\"builder-gemini\")}\n disabled={!builderStatus?.configured}\n title=\"Builder.io Connect (recommended)\"\n subtitle={\n builderStatus?.configured\n ? \"Fast Gemini Flash-Lite transcription and cleanup through Builder.io. No Google key needed.\"\n : \"One-click connect — uses Gemini Flash-Lite without a Google key.\"\n }\n rightSlot={\n builderStatus?.configured ? (\n <span className=\"flex items-center gap-1 text-[10px] text-green-500\">\n <IconCheck size={10} />\n Connected\n </span>\n ) : (\n <button\n type=\"button\"\n onClick={(e) => {\n e.stopPropagation();\n const url = new URL(\n agentNativePath(\"/_agent-native/builder/connect\"),\n window.location.origin,\n ).href;\n window.open(\n url,\n \"_blank\",\n \"noopener,noreferrer,width=600,height=700\",\n );\n }}\n className=\"inline-flex items-center gap-1 rounded border border-border px-2 py-0.5 text-[10px] text-muted-foreground hover:text-foreground hover:bg-accent/40\"\n >\n Connect Builder.io\n <IconExternalLink size={10} />\n </button>\n )\n }\n />\n\n {/* Cleanup-with-AI toggle — defaults to on if Builder is connected. */}\n <div className=\"flex items-start justify-between gap-3 rounded-md border border-border bg-accent/30 px-2.5 py-2\">\n <div className=\"min-w-0\">\n <div className=\"text-[11px] font-medium text-foreground\">\n Cleanup transcripts with AI\n </div>\n <p className=\"text-[10px] text-muted-foreground mt-0.5\">\n Polish punctuation, casing, and remove filler words after each\n recording.\n </p>\n </div>\n <button\n type=\"button\"\n role=\"switch\"\n aria-checked={!!cleanupEnabled}\n onClick={() => toggleCleanup(!cleanupEnabled)}\n className={`relative inline-flex h-4 w-7 shrink-0 cursor-pointer items-center rounded-full transition-colors ${\n cleanupEnabled\n ? \"bg-[#625DF5]\"\n : \"bg-muted-foreground/30 hover:bg-muted-foreground/50\"\n }`}\n >\n <span\n className={`inline-block h-3 w-3 transform rounded-full bg-background transition-transform ${\n cleanupEnabled ? \"translate-x-3.5\" : \"translate-x-0.5\"\n }`}\n />\n </button>\n </div>\n\n {/* Single \"Add API keys\" disclosure — collapses BYOK rows + browser. */}\n <div className=\"rounded-md border border-border bg-background\">\n <button\n type=\"button\"\n onClick={() => setShowAdvanced((v) => !v)}\n className=\"w-full flex items-center justify-between gap-2 px-2.5 py-2 cursor-pointer\"\n >\n <span className=\"text-[11px] font-medium text-foreground inline-flex items-center gap-1\">\n {showAdvanced ? (\n <IconChevronDown size={12} />\n ) : (\n <IconChevronRight size={12} />\n )}\n Add API keys\n </span>\n <span className=\"text-[10px] text-muted-foreground\">\n OpenAI · Gemini · Groq · browser\n </span>\n </button>\n\n {showAdvanced && (\n <div className=\"px-2 pb-2 space-y-2\">\n <ProviderOption\n id=\"openai\"\n selected={provider === \"openai\"}\n onSelect={() => choose(\"openai\")}\n title=\"OpenAI Whisper\"\n subtitle=\"Best quality. Requires an OpenAI API key.\"\n rightSlot={\n openAiConfigured === null ? null : openAiConfigured ? (\n <span className=\"flex items-center gap-1 text-[10px] text-green-500\">\n <IconCheck size={10} />\n Key set\n </span>\n ) : (\n <button\n type=\"button\"\n onClick={(e) => {\n e.stopPropagation();\n focusKey(\"OPENAI_API_KEY\");\n }}\n className=\"inline-flex items-center gap-1 rounded border border-border px-2 py-0.5 text-[10px] text-muted-foreground hover:text-foreground hover:bg-accent/40\"\n >\n Add key\n <IconExternalLink size={10} />\n </button>\n )\n }\n />\n\n <ProviderOption\n id=\"gemini\"\n selected={provider === \"gemini\"}\n onSelect={() => choose(\"gemini\")}\n title=\"Google Gemini\"\n subtitle=\"Fast transcription via Gemini Flash Lite. Requires a Gemini API key.\"\n rightSlot={\n geminiConfigured === null ? null : geminiConfigured ? (\n <span className=\"flex items-center gap-1 text-[10px] text-green-500\">\n <IconCheck size={10} />\n Key set\n </span>\n ) : (\n <button\n type=\"button\"\n onClick={(e) => {\n e.stopPropagation();\n focusKey(\"GEMINI_API_KEY\");\n }}\n className=\"inline-flex items-center gap-1 rounded border border-border px-2 py-0.5 text-[10px] text-muted-foreground hover:text-foreground hover:bg-accent/40\"\n >\n Add key\n <IconExternalLink size={10} />\n </button>\n )\n }\n />\n\n <ProviderOption\n id=\"groq\"\n selected={provider === \"groq\"}\n onSelect={() => choose(\"groq\")}\n title=\"Groq Whisper\"\n subtitle=\"Fastest Whisper inference. Requires a Groq API key.\"\n rightSlot={\n groqConfigured === null ? null : groqConfigured ? (\n <span className=\"flex items-center gap-1 text-[10px] text-green-500\">\n <IconCheck size={10} />\n Key set\n </span>\n ) : (\n <button\n type=\"button\"\n onClick={(e) => {\n e.stopPropagation();\n focusKey(\"GROQ_API_KEY\");\n }}\n className=\"inline-flex items-center gap-1 rounded border border-border px-2 py-0.5 text-[10px] text-muted-foreground hover:text-foreground hover:bg-accent/40\"\n >\n Add key\n <IconExternalLink size={10} />\n </button>\n )\n }\n />\n\n <ProviderOption\n id=\"browser\"\n selected={provider === \"browser\"}\n onSelect={() => choose(\"browser\")}\n title=\"Native browser\"\n subtitle=\"Free built-in speech recognition. No key required.\"\n />\n </div>\n )}\n </div>\n\n {provider !== \"browser\" && (\n <div className=\"rounded-md border border-border bg-accent/20 px-2.5 py-2\">\n <label\n htmlFor=\"voice-transcription-instructions\"\n className=\"block text-[10px] font-medium text-foreground\"\n >\n Custom instructions\n </label>\n <textarea\n id=\"voice-transcription-instructions\"\n value={instructions}\n onChange={(event) => updateInstructions(event.target.value)}\n placeholder=\"Names, casing, punctuation, style, or terms to preserve.\"\n className=\"mt-1 min-h-16 w-full resize-y rounded border border-border bg-background px-2 py-1.5 text-[11px] text-foreground outline-none placeholder:text-muted-foreground/50 focus:ring-1 focus:ring-accent\"\n />\n <p className=\"mt-1 text-[10px] text-muted-foreground\">\n Included with LLM-based transcription and cleanup.\n </p>\n </div>\n )}\n\n {saving && <p className=\"text-[10px] text-muted-foreground\">Saving…</p>}\n {saveError && !saving && (\n <p className=\"text-[10px] text-red-500\" role=\"alert\">\n {saveError}\n </p>\n )}\n </div>\n );\n}\n\ninterface ProviderOptionProps {\n id: string;\n selected: boolean;\n disabled?: boolean;\n onSelect: () => void;\n title: string;\n subtitle?: React.ReactNode;\n rightSlot?: React.ReactNode;\n}\n\nfunction ProviderOption({\n id,\n selected,\n disabled,\n onSelect,\n title,\n subtitle,\n rightSlot,\n}: ProviderOptionProps) {\n const select = () => {\n if (!disabled) onSelect();\n };\n\n const onKeyDown = (event: React.KeyboardEvent<HTMLDivElement>) => {\n if (disabled) return;\n if (event.key === \"Enter\" || event.key === \" \") {\n event.preventDefault();\n onSelect();\n }\n };\n\n return (\n <div\n role=\"button\"\n tabIndex={disabled ? -1 : 0}\n onClick={select}\n onKeyDown={onKeyDown}\n aria-pressed={selected}\n aria-disabled={disabled || undefined}\n className={`w-full text-left rounded-md border px-2.5 py-2 flex items-start gap-2 ${\n selected\n ? \"border-[#625DF5] bg-[#625DF5]/10\"\n : \"border-border bg-accent/30 hover:bg-accent/50\"\n } ${disabled ? \"opacity-60 cursor-not-allowed\" : \"\"}`}\n >\n <span\n className={`mt-[2px] shrink-0 flex h-3.5 w-3.5 items-center justify-center rounded-full border ${\n selected\n ? \"border-[#625DF5] bg-[#625DF5]\"\n : \"border-muted-foreground/40 bg-background\"\n }`}\n >\n {selected && (\n <span className=\"h-1.5 w-1.5 rounded-full bg-background\" />\n )}\n </span>\n <div className=\"min-w-0 flex-1\">\n <div className=\"flex items-center justify-between gap-2\">\n <div className=\"text-[11px] font-medium text-foreground\">{title}</div>\n {rightSlot && <div className=\"shrink-0\">{rightSlot}</div>}\n </div>\n {subtitle && (\n <p className=\"text-[10px] text-muted-foreground mt-0.5\">{subtitle}</p>\n )}\n </div>\n </div>\n );\n}\n\nexport function VoiceTranscriptionIcon() {\n return <IconMicrophone size={14} />;\n}\n"]}
|
|
@@ -158,12 +158,18 @@ function moveAppBuildIntoDist(workspaceRoot, app, distDir, preset, workspaceApps
|
|
|
158
158
|
* the workspace dist root so each app is reachable under /<app>/*.
|
|
159
159
|
*/
|
|
160
160
|
function writeCloudflareRoutingManifest(distDir, apps) {
|
|
161
|
+
const dispatchFaviconAsset = apps.includes("dispatch")
|
|
162
|
+
? dispatchRootFaviconAsset(distDir)
|
|
163
|
+
: null;
|
|
161
164
|
// _routes.json tells Cloudflare which paths are dynamic (Functions) vs
|
|
162
165
|
// static. Mark /<app>/* as include so every app's worker handles its
|
|
163
166
|
// subtree.
|
|
164
167
|
const include = apps.map((a) => `/${a}/*`).concat(["/"]);
|
|
165
168
|
if (apps.includes("dispatch")) {
|
|
166
169
|
include.push("/_agent-native/*");
|
|
170
|
+
include.push("/.well-known/*");
|
|
171
|
+
if (dispatchFaviconAsset)
|
|
172
|
+
include.push("/favicon.ico");
|
|
167
173
|
}
|
|
168
174
|
const routes = {
|
|
169
175
|
version: 1,
|
|
@@ -180,7 +186,11 @@ function writeCloudflareRoutingManifest(distDir, apps) {
|
|
|
180
186
|
.map((a) => ` if (pathname === "/${a}" || pathname.startsWith("/${a}/")) return ${moduleIdent(a)}.fetch(request, env, ctx);`)
|
|
181
187
|
.join("\n");
|
|
182
188
|
const dispatchRootFrameworkRoutes = apps.includes("dispatch")
|
|
183
|
-
? ` if (pathname === "/_agent-native" || pathname.startsWith("/_agent-native/")) return ${moduleIdent("dispatch")}.fetch(request, env, ctx);
|
|
189
|
+
? ` if (pathname === "/_agent-native" || pathname.startsWith("/_agent-native/") || pathname === "/.well-known" || pathname.startsWith("/.well-known/")) return ${moduleIdent("dispatch")}.fetch(request, env, ctx);
|
|
190
|
+
`
|
|
191
|
+
: "";
|
|
192
|
+
const dispatchRootFaviconRoute = dispatchFaviconAsset
|
|
193
|
+
? ` if (pathname === "/favicon.ico") return Response.redirect(new URL("/dispatch/${dispatchFaviconAsset}", request.url).toString(), 302);
|
|
184
194
|
`
|
|
185
195
|
: "";
|
|
186
196
|
const worker = `${imports}
|
|
@@ -188,7 +198,7 @@ function writeCloudflareRoutingManifest(distDir, apps) {
|
|
|
188
198
|
export default {
|
|
189
199
|
async fetch(request, env, ctx) {
|
|
190
200
|
const { pathname } = new URL(request.url);
|
|
191
|
-
${dispatchRootFrameworkRoutes}${dispatch}
|
|
201
|
+
${dispatchRootFrameworkRoutes}${dispatchRootFaviconRoute}${dispatch}
|
|
192
202
|
if (pathname === "/") {
|
|
193
203
|
return Response.redirect(new URL("${cloudflareRootRedirectPath(apps)}", request.url).toString(), 302);
|
|
194
204
|
}
|
|
@@ -208,6 +218,11 @@ function writeNetlifyRedirects(distDir, apps) {
|
|
|
208
218
|
];
|
|
209
219
|
if (apps.includes("dispatch")) {
|
|
210
220
|
lines.push("/_agent-native/* /.netlify/functions/dispatch-server 200");
|
|
221
|
+
lines.push("/.well-known/* /.netlify/functions/dispatch-server 200");
|
|
222
|
+
const faviconAsset = dispatchRootFaviconAsset(distDir);
|
|
223
|
+
if (faviconAsset) {
|
|
224
|
+
lines.push(`/favicon.ico /dispatch/${faviconAsset} 302`);
|
|
225
|
+
}
|
|
211
226
|
}
|
|
212
227
|
for (const app of apps) {
|
|
213
228
|
lines.push(...netlifyAssetRedirectsFor(app, distDir));
|
|
@@ -235,6 +250,20 @@ function netlifyAssetRedirectsFor(app, distDir) {
|
|
|
235
250
|
}),
|
|
236
251
|
];
|
|
237
252
|
}
|
|
253
|
+
function dispatchRootFaviconAsset(distDir) {
|
|
254
|
+
for (const asset of ["favicon.ico", "favicon.svg", "favicon.png"]) {
|
|
255
|
+
if (workspaceAppAssetExists(distDir, "dispatch", asset))
|
|
256
|
+
return asset;
|
|
257
|
+
}
|
|
258
|
+
return null;
|
|
259
|
+
}
|
|
260
|
+
function workspaceAppAssetExists(distDir, app, asset) {
|
|
261
|
+
return [
|
|
262
|
+
path.join(distDir, NETLIFY_WORKSPACE_STATIC_DIR, app, asset),
|
|
263
|
+
path.join(distDir, app, app, asset),
|
|
264
|
+
path.join(distDir, app, asset),
|
|
265
|
+
].some((candidate) => fs.existsSync(candidate));
|
|
266
|
+
}
|
|
238
267
|
const DISPATCH_WORKSPACE_ROOT_REDIRECTS = [
|
|
239
268
|
["overview", "overview"],
|
|
240
269
|
["login", "login"],
|
|
@@ -282,7 +311,7 @@ function patchNetlifyFunctionEntry(functionDir, app, workspaceApps, staticDir) {
|
|
|
282
311
|
return;
|
|
283
312
|
const basePath = `/${app}`;
|
|
284
313
|
const pathConfig = app === "dispatch"
|
|
285
|
-
? ["/_agent-native/*", `${basePath}/*`]
|
|
314
|
+
? ["/_agent-native/*", "/.well-known/*", `${basePath}/*`]
|
|
286
315
|
: [basePath, `${basePath}/*`];
|
|
287
316
|
const normalizeBasePathHelper = app === "dispatch"
|
|
288
317
|
? ""
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"workspace-deploy.js","sourceRoot":"","sources":["../../src/deploy/workspace-deploy.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * `agent-native deploy` — build and deploy every app in a workspace to a\n * single origin. Each app is served from `/<app-name>/*`, so:\n *\n * https://your-agents.com/mail/* → apps/mail\n * https://your-agents.com/calendar/* → apps/calendar\n *\n * Benefits of same-origin deploy:\n * - Shared auth cookie → log in once, every app is signed in\n * - Cross-app A2A is a same-origin fetch (no CORS, no JWT for siblings)\n * - One DNS record, one TLS cert, one CDN cache\n *\n * Per-app independent deploy is still supported — just cd into the app and\n * run `agent-native build` as before. This orchestrator is for teams that\n * want the whole workspace behind one domain.\n */\nimport { execFileSync } from \"child_process\";\nimport fs from \"fs\";\nimport path from \"path\";\nimport { findWorkspaceRoot } from \"../scripts/utils.js\";\n\nexport type WorkspaceDeployPreset = \"cloudflare_pages\" | \"netlify\";\n\nconst NETLIFY_WORKSPACE_STATIC_DIR = \"_workspace_static\";\nconst NETLIFY_PUBLIC_ASSET_EXTENSIONS = new Set([\n \"avif\",\n \"css\",\n \"gif\",\n \"ico\",\n \"jpeg\",\n \"jpg\",\n \"js\",\n \"json\",\n \"map\",\n \"mp4\",\n \"pdf\",\n \"png\",\n \"svg\",\n \"txt\",\n \"wasm\",\n \"webm\",\n \"webmanifest\",\n \"webp\",\n \"xml\",\n]);\nconst WORKSPACE_APPS_ENV_KEY = \"AGENT_NATIVE_WORKSPACE_APPS_JSON\";\nconst WORKSPACE_APPS_MANIFEST_DIR = \".agent-native\";\nconst WORKSPACE_APPS_MANIFEST_FILE = \"workspace-apps.json\";\n\ninterface WorkspaceAppManifestEntry {\n id: string;\n name: string;\n description: string;\n path: string;\n url?: string;\n isDispatch: boolean;\n}\n\nexport interface WorkspaceDeployOptions {\n args?: string[];\n /** Override the workspace root (defaults to walking up from cwd). */\n workspaceRoot?: string;\n /** Only build — don't invoke the deploy platform CLI. */\n buildOnly?: boolean;\n /** Target preset. Defaults to `cloudflare_pages`. */\n preset?: WorkspaceDeployPreset;\n /** @internal Override process execution in tests. */\n execFile?: typeof execFileSync;\n}\n\nexport async function runWorkspaceDeploy(\n opts: WorkspaceDeployOptions = {},\n): Promise<void> {\n const workspaceRoot =\n opts.workspaceRoot ?? findWorkspaceRoot(process.cwd()) ?? process.cwd();\n const appsDir = path.join(workspaceRoot, \"apps\");\n if (!fs.existsSync(appsDir)) {\n throw new Error(\n `No apps/ directory found at ${workspaceRoot}. Run this inside an agent-native workspace.`,\n );\n }\n\n const rawArgs = opts.args ?? [];\n const args = new Set(rawArgs);\n const buildOnly = opts.buildOnly ?? args.has(\"--build-only\");\n\n const apps = fs\n .readdirSync(appsDir, { withFileTypes: true })\n .filter((e) => e.isDirectory())\n .map((e) => e.name)\n .filter((n) => fs.existsSync(path.join(appsDir, n, \"package.json\")))\n .sort(compareWorkspaceAppIds);\n\n if (apps.length === 0) {\n throw new Error(\n `Workspace has no apps. Run \\`agent-native add-app\\` to add one.`,\n );\n }\n assertNoReservedWorkspaceAppIds(apps);\n const workspaceApps = readWorkspaceAppManifest(workspaceRoot, apps);\n\n const preset = resolvePreset(opts.preset, rawArgs);\n assertWorkspaceDeployProductionEnv({ buildOnly, preset });\n const distDir = path.join(workspaceRoot, \"dist\");\n fs.rmSync(distDir, { recursive: true, force: true });\n fs.mkdirSync(distDir, { recursive: true });\n\n if (preset === \"netlify\") {\n const functionsDir = netlifyFunctionsDir(workspaceRoot);\n fs.rmSync(functionsDir, { recursive: true, force: true });\n fs.mkdirSync(functionsDir, { recursive: true });\n }\n\n console.log(\n `[workspace-deploy] Building ${apps.length} app(s) for preset=${preset}`,\n );\n\n const execFile = opts.execFile ?? execFileSync;\n for (const app of apps) {\n buildOneApp(workspaceRoot, app, preset, execFile, workspaceApps);\n moveAppBuildIntoDist(workspaceRoot, app, distDir, preset, workspaceApps);\n }\n writeWorkspaceAppManifests(\n workspaceRoot,\n distDir,\n apps,\n workspaceApps,\n preset,\n );\n\n if (preset === \"netlify\") {\n writeNetlifyRedirects(distDir, apps);\n } else {\n writeCloudflareRoutingManifest(distDir, apps);\n }\n\n if (buildOnly) {\n console.log(\n `\\n[workspace-deploy] Build complete at ${distDir}. Skipping publish (--build-only).`,\n );\n return;\n }\n\n console.log(`\\n[workspace-deploy] Build complete. Publish with:\\n`);\n console.log(` cd ${path.relative(process.cwd(), workspaceRoot) || \".\"}`);\n if (preset === \"netlify\") {\n console.log(\n ` netlify deploy --prod --dir=dist --functions=.netlify/functions-internal\\n`,\n );\n } else {\n console.log(` wrangler pages deploy dist\\n`);\n }\n console.log(\n `All apps live at https://<origin>/<app-name>/*. Log in once on any app\\nand the session is shared across the workspace.`,\n );\n}\n\nfunction buildOneApp(\n workspaceRoot: string,\n app: string,\n preset: WorkspaceDeployPreset,\n execFile: typeof execFileSync,\n workspaceApps: WorkspaceAppManifestEntry[],\n): void {\n const appDir = path.join(workspaceRoot, \"apps\", app);\n const env: NodeJS.ProcessEnv = {\n ...process.env,\n NITRO_PRESET: preset,\n APP_BASE_PATH: `/${app}`,\n VITE_APP_BASE_PATH: `/${app}`,\n [WORKSPACE_APPS_ENV_KEY]: JSON.stringify(workspaceApps),\n };\n\n if (preset === \"netlify\" && appUsesNetlifyUnpooledDatabaseUrl(appDir)) {\n env.DATABASE_URL =\n process.env.NETLIFY_DATABASE_URL_UNPOOLED ??\n process.env.DATABASE_URL ??\n env.DATABASE_URL;\n }\n\n console.log(\n `[workspace-deploy] Building ${app} (base=/${app}, preset=${preset})`,\n );\n\n cleanAppBuildOutputs(appDir);\n\n execFile(\"pnpm\", [\"--filter\", app, \"build\"], {\n cwd: workspaceRoot,\n env,\n stdio: \"inherit\",\n });\n}\n\nfunction moveAppBuildIntoDist(\n workspaceRoot: string,\n app: string,\n distDir: string,\n preset: WorkspaceDeployPreset,\n workspaceApps: WorkspaceAppManifestEntry[],\n): void {\n const appDir = path.join(workspaceRoot, \"apps\", app);\n // Resolve the per-app build output: prefer dist/ (standard), fall back to\n // .output/ (Nitro's default). The Cloudflare preset emits into dist/\n // containing the worker + assets.\n const candidates = [\"dist\", \".output\"];\n const src = candidates\n .map((c) => path.join(appDir, c))\n .find((p) => fs.existsSync(p));\n if (!src) {\n throw new Error(\n `Expected ${candidates.join(\" or \")} under ${appDir} but none existed. Check the app's build script.`,\n );\n }\n if (preset === \"netlify\") {\n const mountedSrc = path.join(src, app);\n const staticSrc = fs.existsSync(mountedSrc) ? mountedSrc : src;\n const target = path.join(distDir, NETLIFY_WORKSPACE_STATIC_DIR, app);\n fs.mkdirSync(target, { recursive: true });\n copyDir(staticSrc, target);\n // Nitro/Vite mounted builds can contain a nested copy of public assets at\n // dist/<app>/<app>/...; the workspace root already supplies the outer\n // mount path, so keeping it would publish duplicate /<app>/<app> URLs.\n fs.rmSync(path.join(target, app), { recursive: true, force: true });\n copyNetlifyFunctionIntoWorkspace(workspaceRoot, app, workspaceApps, target);\n } else {\n const target = path.join(distDir, app);\n fs.mkdirSync(target, { recursive: true });\n copyDir(src, target);\n }\n}\n\n/**\n * Write the Cloudflare Pages `_routes.json` and a dispatcher `_worker.js` at\n * the workspace dist root so each app is reachable under /<app>/*.\n */\nfunction writeCloudflareRoutingManifest(distDir: string, apps: string[]): void {\n // _routes.json tells Cloudflare which paths are dynamic (Functions) vs\n // static. Mark /<app>/* as include so every app's worker handles its\n // subtree.\n const include = apps.map((a) => `/${a}/*`).concat([\"/\"]);\n if (apps.includes(\"dispatch\")) {\n include.push(\"/_agent-native/*\");\n }\n const routes = {\n version: 1,\n include,\n exclude: [],\n };\n fs.writeFileSync(\n path.join(distDir, \"_routes.json\"),\n JSON.stringify(routes, null, 2) + \"\\n\",\n );\n\n // Dispatcher worker: inspects the path and forwards to the matching\n // per-app worker.\n const imports = apps\n .map((a) => `import ${moduleIdent(a)} from \"./${a}/_worker.js\";`)\n .join(\"\\n\");\n const dispatch = apps\n .map(\n (a) =>\n ` if (pathname === \"/${a}\" || pathname.startsWith(\"/${a}/\")) return ${moduleIdent(a)}.fetch(request, env, ctx);`,\n )\n .join(\"\\n\");\n const dispatchRootFrameworkRoutes = apps.includes(\"dispatch\")\n ? ` if (pathname === \"/_agent-native\" || pathname.startsWith(\"/_agent-native/\")) return ${moduleIdent(\"dispatch\")}.fetch(request, env, ctx);\n`\n : \"\";\n\n const worker = `${imports}\n\nexport default {\n async fetch(request, env, ctx) {\n const { pathname } = new URL(request.url);\n${dispatchRootFrameworkRoutes}${dispatch}\n if (pathname === \"/\") {\n return Response.redirect(new URL(\"${cloudflareRootRedirectPath(apps)}\", request.url).toString(), 302);\n }\n return new Response(\"Not found\", { status: 404 });\n },\n};\n`;\n fs.writeFileSync(path.join(distDir, \"_worker.js\"), worker);\n}\n\nfunction cloudflareRootRedirectPath(apps: string[]): string {\n return apps.includes(\"dispatch\") ? \"/dispatch/overview\" : `/${apps[0]}/`;\n}\n\nfunction writeNetlifyRedirects(distDir: string, apps: string[]): void {\n const lines: string[] = [\n \"# Generated by agent-native deploy --preset netlify\",\n \"# Static app assets are stored under a safe namespace; dynamic app routes are handled by function route config.\",\n ];\n\n if (apps.includes(\"dispatch\")) {\n lines.push(\"/_agent-native/* /.netlify/functions/dispatch-server 200\");\n }\n\n for (const app of apps) {\n lines.push(...netlifyAssetRedirectsFor(app, distDir));\n }\n\n if (apps.includes(\"dispatch\")) {\n lines.push(\"/ /dispatch/overview 302\");\n lines.push(\"/dispatch /dispatch/overview 302\");\n for (const [from, to] of DISPATCH_WORKSPACE_ROOT_REDIRECTS) {\n lines.push(`/${from} /dispatch/${to} 302`);\n }\n } else {\n lines.push(`/ /${apps[0]}/ 302`);\n }\n\n fs.writeFileSync(path.join(distDir, \"_redirects\"), lines.join(\"\\n\") + \"\\n\");\n}\n\nfunction netlifyAssetRedirectsFor(app: string, distDir: string): string[] {\n const from = `/${app}`;\n const to = `/${NETLIFY_WORKSPACE_STATIC_DIR}/${app}`;\n return [\n `${from}/assets/* ${to}/assets/:splat 200`,\n ...netlifyPublicRootAssetPaths(\n app,\n path.join(distDir, NETLIFY_WORKSPACE_STATIC_DIR, app),\n ).map((assetPath) => {\n const assetName = assetPath.slice(from.length + 1);\n return `${assetPath} ${to}/${assetName} 200`;\n }),\n ];\n}\n\nconst DISPATCH_WORKSPACE_ROOT_REDIRECTS = [\n [\"overview\", \"overview\"],\n [\"login\", \"login\"],\n [\"signup\", \"signup\"],\n [\"apps\", \"apps\"],\n [\"apps/new-app\", \"new-app\"],\n [\"new-app\", \"new-app\"],\n [\"vault\", \"vault\"],\n [\"integrations\", \"integrations\"],\n [\"agents\", \"agents\"],\n [\"workspace\", \"workspace\"],\n [\"messaging\", \"messaging\"],\n [\"destinations\", \"destinations\"],\n [\"identities\", \"identities\"],\n [\"approvals\", \"approvals\"],\n [\"audit\", \"audit\"],\n [\"team\", \"team\"],\n];\n\nconst RESERVED_WORKSPACE_APP_IDS = new Set([\n \"_agent-native\",\n \"_workspace_static\",\n \"netlify\",\n ...DISPATCH_WORKSPACE_ROOT_REDIRECTS.map(([from]) => from),\n]);\n\nfunction assertNoReservedWorkspaceAppIds(apps: string[]): void {\n const conflicts = apps.filter(\n (app) => app !== \"dispatch\" && RESERVED_WORKSPACE_APP_IDS.has(app),\n );\n if (conflicts.length === 0) return;\n throw new Error(\n `Workspace app id ${conflicts.map((id) => `\"${id}\"`).join(\", \")} conflicts with reserved workspace routes. Choose a different app id.`,\n );\n}\n\nfunction copyNetlifyFunctionIntoWorkspace(\n workspaceRoot: string,\n app: string,\n workspaceApps: WorkspaceAppManifestEntry[],\n staticDir: string,\n): void {\n const appDir = path.join(workspaceRoot, \"apps\", app);\n const src = path.join(appDir, \".netlify\", \"functions-internal\", \"server\");\n if (!fs.existsSync(src)) {\n throw new Error(\n `Expected Netlify function at ${src} after building ${app}. Check the app's build script and NITRO_PRESET.`,\n );\n }\n\n const dest = path.join(netlifyFunctionsDir(workspaceRoot), `${app}-server`);\n fs.rmSync(dest, { recursive: true, force: true });\n copyDir(src, dest);\n patchNetlifyFunctionEntry(dest, app, workspaceApps, staticDir);\n}\n\nfunction patchNetlifyFunctionEntry(\n functionDir: string,\n app: string,\n workspaceApps: WorkspaceAppManifestEntry[],\n staticDir: string,\n): void {\n const serverPath = path.join(functionDir, \"server.mjs\");\n if (!fs.existsSync(serverPath)) return;\n\n const basePath = `/${app}`;\n const pathConfig =\n app === \"dispatch\"\n ? [\"/_agent-native/*\", `${basePath}/*`]\n : [basePath, `${basePath}/*`];\n const normalizeBasePathHelper =\n app === \"dispatch\"\n ? \"\"\n : `\nfunction normalizeBasePathArgs(args) {\n const request = args[0];\n if (!request || typeof request.url !== \"string\" || typeof Request !== \"function\") {\n return args;\n }\n const url = new URL(request.url);\n if (url.pathname === basePath || url.pathname === \\`\\${basePath}/\\`) {\n url.pathname = \\`\\${basePath}//\\`;\n return [new Request(url, request), ...args.slice(1)];\n }\n return args;\n}\n`;\n const handlerArgs =\n app === \"dispatch\" ? \"...args\" : \"...normalizeBasePathArgs(args)\";\n const server = `const basePath = ${JSON.stringify(basePath)};\n\nfunction setBasePathEnv() {\n const processRef = globalThis.process ??= { env: {} };\n processRef.env ??= {};\n Object.assign(processRef.env, {\n APP_BASE_PATH: basePath,\n VITE_APP_BASE_PATH: basePath,\n ${JSON.stringify(WORKSPACE_APPS_ENV_KEY)}: ${JSON.stringify(JSON.stringify(workspaceApps))},\n });\n}\n\nsetBasePathEnv();\n${normalizeBasePathHelper}\n\nlet cachedHandler;\n\nexport default async function handler(...args) {\n setBasePathEnv();\n cachedHandler ??= (await import(\"./main.mjs\")).default;\n return cachedHandler(${handlerArgs});\n}\n\nexport const config = {\n name: ${JSON.stringify(`${app} server handler`)},\n generator: \"agent-native workspace deploy\",\n path: ${JSON.stringify(pathConfig)},\n nodeBundler: \"none\",\n includedFiles: [\"**\"],\n excludedPath: ${JSON.stringify(\n netlifyFunctionExcludedPaths(app, staticDir),\n null,\n 2,\n )\n .split(\"\\n\")\n .join(\"\\n \")},\n preferStatic: false,\n};\n`;\n fs.rmSync(serverPath, { force: true });\n fs.writeFileSync(path.join(functionDir, `${app}-server.mjs`), server);\n}\n\nfunction netlifyFunctionExcludedPaths(\n app: string,\n staticDir: string,\n): string[] {\n return [\n \"/.netlify/*\",\n `/${app}/assets/*`,\n ...netlifyPublicRootAssetPaths(app, staticDir),\n ];\n}\n\nfunction netlifyPublicRootAssetPaths(app: string, staticDir: string): string[] {\n if (!fs.existsSync(staticDir)) return [];\n return fs\n .readdirSync(staticDir, { withFileTypes: true })\n .filter((entry) => entry.isFile())\n .map((entry) => entry.name)\n .filter((name) => {\n const ext = path.extname(name).slice(1).toLowerCase();\n return NETLIFY_PUBLIC_ASSET_EXTENSIONS.has(ext);\n })\n .sort()\n .map((name) => `/${app}/${encodeURI(name)}`);\n}\n\nfunction netlifyFunctionsDir(workspaceRoot: string): string {\n return path.join(workspaceRoot, \".netlify\", \"functions-internal\");\n}\n\nfunction cleanAppBuildOutputs(appDir: string): void {\n for (const name of [\"dist\", \".output\", \"build\"]) {\n fs.rmSync(path.join(appDir, name), { recursive: true, force: true });\n }\n fs.rmSync(path.join(appDir, \".netlify\", \"functions-internal\"), {\n recursive: true,\n force: true,\n });\n}\n\nfunction appUsesNetlifyUnpooledDatabaseUrl(appDir: string): boolean {\n const netlifyPath = path.join(appDir, \"netlify.toml\");\n if (!fs.existsSync(netlifyPath)) return false;\n try {\n return fs\n .readFileSync(netlifyPath, \"utf-8\")\n .includes(\"NETLIFY_DATABASE_URL_UNPOOLED\");\n } catch {\n return false;\n }\n}\n\nfunction writeWorkspaceAppManifests(\n workspaceRoot: string,\n distDir: string,\n apps: string[],\n workspaceApps: WorkspaceAppManifestEntry[],\n preset: WorkspaceDeployPreset,\n): void {\n const manifest = JSON.stringify(\n {\n version: 1,\n apps: workspaceApps,\n },\n null,\n 2,\n );\n\n const targets =\n preset === \"netlify\"\n ? apps.map((app) =>\n path.join(\n netlifyFunctionsDir(workspaceRoot),\n `${app}-server`,\n WORKSPACE_APPS_MANIFEST_DIR,\n WORKSPACE_APPS_MANIFEST_FILE,\n ),\n )\n : apps.map((app) =>\n path.join(\n distDir,\n app,\n WORKSPACE_APPS_MANIFEST_DIR,\n WORKSPACE_APPS_MANIFEST_FILE,\n ),\n );\n\n for (const target of targets) {\n fs.mkdirSync(path.dirname(target), { recursive: true });\n fs.writeFileSync(target, `${manifest}\\n`);\n }\n}\n\nfunction readWorkspaceAppManifest(\n workspaceRoot: string,\n apps: string[],\n): WorkspaceAppManifestEntry[] {\n const explicitApps = readExistingWorkspaceAppManifest(workspaceRoot);\n\n return apps\n .map((app) => {\n const appDir = path.join(workspaceRoot, \"apps\", app);\n const pkg = readPackageJson(path.join(appDir, \"package.json\"));\n const appPath = `/${app}`;\n const explicit = explicitApps.get(app);\n const url =\n normalizeWorkspaceAppUrl(explicit?.url) ?? workspaceAppUrl(appPath);\n return {\n id: app,\n name: pkg?.displayName || titleCase(app),\n description: pkg?.description || \"\",\n path: appPath,\n ...(url ? { url } : {}),\n isDispatch: app === \"dispatch\",\n };\n })\n .sort((a, b) => {\n if (a.id === \"dispatch\") return -1;\n if (b.id === \"dispatch\") return 1;\n return a.name.localeCompare(b.name);\n });\n}\n\nfunction readExistingWorkspaceAppManifest(\n workspaceRoot: string,\n): Map<string, { url?: string }> {\n const fromEnv = parseWorkspaceAppsJson(process.env[WORKSPACE_APPS_ENV_KEY]);\n const fromFile =\n readWorkspaceAppsFromFile(\n path.join(\n workspaceRoot,\n WORKSPACE_APPS_MANIFEST_DIR,\n WORKSPACE_APPS_MANIFEST_FILE,\n ),\n ) ??\n readWorkspaceAppsFromFile(\n path.join(workspaceRoot, WORKSPACE_APPS_MANIFEST_FILE),\n );\n const apps = fromEnv ?? fromFile ?? [];\n return new Map(apps.map((app) => [app.id, app]));\n}\n\nfunction parseWorkspaceAppsJson(\n raw: string | undefined,\n): Array<{ id: string; url?: string }> | null {\n if (!raw) return null;\n try {\n return parseWorkspaceAppsManifest(JSON.parse(raw));\n } catch {\n return null;\n }\n}\n\nfunction readWorkspaceAppsFromFile(\n file: string,\n): Array<{ id: string; url?: string }> | null {\n if (!fs.existsSync(file)) return null;\n return parseWorkspaceAppsManifest(readPackageJson(file));\n}\n\nfunction parseWorkspaceAppsManifest(\n parsed: any,\n): Array<{ id: string; url?: string }> | 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) => {\n if (!entry || typeof entry !== \"object\") return null;\n const id = typeof entry.id === \"string\" ? entry.id.trim() : \"\";\n if (!id) return null;\n const url = normalizeWorkspaceAppUrl(entry.url);\n return {\n id,\n ...(url ? { url } : {}),\n };\n })\n .filter((app): app is { id: string; url?: string } => !!app);\n\n return apps.length ? apps : null;\n}\n\nfunction workspaceBaseUrl(): string | null {\n return (\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 );\n}\n\nfunction workspaceAppUrl(appPath: string): string | undefined {\n const base = workspaceBaseUrl();\n if (!base) return undefined;\n try {\n return new URL(appPath, `${base.replace(/\\/$/, \"\")}/`).toString();\n } catch {\n return undefined;\n }\n}\n\nfunction normalizeWorkspaceAppUrl(value: unknown): string | undefined {\n if (typeof value !== \"string\" || !value.trim()) return undefined;\n try {\n return new URL(value.trim()).toString().replace(/\\/$/, \"\");\n } catch {\n return undefined;\n }\n}\n\nfunction readPackageJson(file: string): Record<string, any> | null {\n try {\n return JSON.parse(fs.readFileSync(file, \"utf8\"));\n } catch {\n return null;\n }\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 parsePresetArg(args: string[]): WorkspaceDeployPreset | null {\n for (let i = 0; i < args.length; i++) {\n const arg = args[i];\n if (arg === \"--preset\" && args[i + 1]) {\n return normalizePreset(args[i + 1]);\n }\n if (arg.startsWith(\"--preset=\")) {\n return normalizePreset(arg.slice(\"--preset=\".length));\n }\n }\n return null;\n}\n\nfunction resolvePreset(\n optionPreset: WorkspaceDeployPreset | undefined,\n args: string[],\n): WorkspaceDeployPreset {\n return (\n optionPreset ??\n parsePresetArg(args) ??\n normalizePreset(process.env.NITRO_PRESET) ??\n \"cloudflare_pages\"\n );\n}\n\nfunction assertWorkspaceDeployProductionEnv(opts: {\n buildOnly: boolean;\n preset: WorkspaceDeployPreset;\n}): void {\n if (!isProductionWorkspaceDeploy(opts)) return;\n if (process.env.A2A_SECRET?.trim()) return;\n throw new Error(\n [\n \"A2A_SECRET is required for production workspace deploys.\",\n \"Workspace Slack, webhook, and cross-app A2A work resumes through signed background processors; without A2A_SECRET those production routes return 503.\",\n 'Set A2A_SECRET in your deploy provider (for example: netlify env:set A2A_SECRET \"$(openssl rand -hex 32)\") and redeploy.',\n \"For local artifact checks, run agent-native deploy --build-only outside the deploy provider environment.\",\n ].join(\" \"),\n );\n}\n\nfunction isProductionWorkspaceDeploy(opts: {\n buildOnly: boolean;\n preset: WorkspaceDeployPreset;\n}): boolean {\n if (!opts.buildOnly) return true;\n if (\n opts.preset === \"netlify\" &&\n process.env.NETLIFY === \"true\" &&\n process.env.NETLIFY_LOCAL !== \"true\"\n ) {\n return true;\n }\n if (opts.preset === \"cloudflare_pages\" && process.env.CF_PAGES === \"1\") {\n return true;\n }\n return false;\n}\n\nfunction normalizePreset(\n value: string | undefined,\n): WorkspaceDeployPreset | null {\n if (!value) return null;\n if (value === \"cloudflare_pages\" || value === \"cloudflare-pages\") {\n return \"cloudflare_pages\";\n }\n if (value === \"netlify\") return \"netlify\";\n throw new Error(\n `Unsupported workspace deploy preset \"${value}\". Supported presets: cloudflare_pages, netlify.`,\n );\n}\n\nfunction moduleIdent(app: string): string {\n return \"app_\" + app.replace(/[^a-zA-Z0-9_]/g, \"_\");\n}\n\nfunction compareWorkspaceAppIds(a: string, b: string): number {\n if (a === \"dispatch\") return -1;\n if (b === \"dispatch\") return 1;\n return a.localeCompare(b);\n}\n\nfunction copyDir(src: string, dest: string): void {\n fs.mkdirSync(dest, { recursive: true });\n for (const entry of fs.readdirSync(src, { withFileTypes: true })) {\n const s = path.join(src, entry.name);\n const d = path.join(dest, entry.name);\n if (entry.isSymbolicLink()) {\n try {\n const target = fs.readlinkSync(s);\n fs.symlinkSync(target, d);\n } catch {\n fs.copyFileSync(s, d);\n }\n } else if (entry.isDirectory()) {\n copyDir(s, d);\n } else {\n fs.copyFileSync(s, d);\n }\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"workspace-deploy.js","sourceRoot":"","sources":["../../src/deploy/workspace-deploy.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * `agent-native deploy` — build and deploy every app in a workspace to a\n * single origin. Each app is served from `/<app-name>/*`, so:\n *\n * https://your-agents.com/mail/* → apps/mail\n * https://your-agents.com/calendar/* → apps/calendar\n *\n * Benefits of same-origin deploy:\n * - Shared auth cookie → log in once, every app is signed in\n * - Cross-app A2A is a same-origin fetch (no CORS, no JWT for siblings)\n * - One DNS record, one TLS cert, one CDN cache\n *\n * Per-app independent deploy is still supported — just cd into the app and\n * run `agent-native build` as before. This orchestrator is for teams that\n * want the whole workspace behind one domain.\n */\nimport { execFileSync } from \"child_process\";\nimport fs from \"fs\";\nimport path from \"path\";\nimport { findWorkspaceRoot } from \"../scripts/utils.js\";\n\nexport type WorkspaceDeployPreset = \"cloudflare_pages\" | \"netlify\";\n\nconst NETLIFY_WORKSPACE_STATIC_DIR = \"_workspace_static\";\nconst NETLIFY_PUBLIC_ASSET_EXTENSIONS = new Set([\n \"avif\",\n \"css\",\n \"gif\",\n \"ico\",\n \"jpeg\",\n \"jpg\",\n \"js\",\n \"json\",\n \"map\",\n \"mp4\",\n \"pdf\",\n \"png\",\n \"svg\",\n \"txt\",\n \"wasm\",\n \"webm\",\n \"webmanifest\",\n \"webp\",\n \"xml\",\n]);\nconst WORKSPACE_APPS_ENV_KEY = \"AGENT_NATIVE_WORKSPACE_APPS_JSON\";\nconst WORKSPACE_APPS_MANIFEST_DIR = \".agent-native\";\nconst WORKSPACE_APPS_MANIFEST_FILE = \"workspace-apps.json\";\n\ninterface WorkspaceAppManifestEntry {\n id: string;\n name: string;\n description: string;\n path: string;\n url?: string;\n isDispatch: boolean;\n}\n\nexport interface WorkspaceDeployOptions {\n args?: string[];\n /** Override the workspace root (defaults to walking up from cwd). */\n workspaceRoot?: string;\n /** Only build — don't invoke the deploy platform CLI. */\n buildOnly?: boolean;\n /** Target preset. Defaults to `cloudflare_pages`. */\n preset?: WorkspaceDeployPreset;\n /** @internal Override process execution in tests. */\n execFile?: typeof execFileSync;\n}\n\nexport async function runWorkspaceDeploy(\n opts: WorkspaceDeployOptions = {},\n): Promise<void> {\n const workspaceRoot =\n opts.workspaceRoot ?? findWorkspaceRoot(process.cwd()) ?? process.cwd();\n const appsDir = path.join(workspaceRoot, \"apps\");\n if (!fs.existsSync(appsDir)) {\n throw new Error(\n `No apps/ directory found at ${workspaceRoot}. Run this inside an agent-native workspace.`,\n );\n }\n\n const rawArgs = opts.args ?? [];\n const args = new Set(rawArgs);\n const buildOnly = opts.buildOnly ?? args.has(\"--build-only\");\n\n const apps = fs\n .readdirSync(appsDir, { withFileTypes: true })\n .filter((e) => e.isDirectory())\n .map((e) => e.name)\n .filter((n) => fs.existsSync(path.join(appsDir, n, \"package.json\")))\n .sort(compareWorkspaceAppIds);\n\n if (apps.length === 0) {\n throw new Error(\n `Workspace has no apps. Run \\`agent-native add-app\\` to add one.`,\n );\n }\n assertNoReservedWorkspaceAppIds(apps);\n const workspaceApps = readWorkspaceAppManifest(workspaceRoot, apps);\n\n const preset = resolvePreset(opts.preset, rawArgs);\n assertWorkspaceDeployProductionEnv({ buildOnly, preset });\n const distDir = path.join(workspaceRoot, \"dist\");\n fs.rmSync(distDir, { recursive: true, force: true });\n fs.mkdirSync(distDir, { recursive: true });\n\n if (preset === \"netlify\") {\n const functionsDir = netlifyFunctionsDir(workspaceRoot);\n fs.rmSync(functionsDir, { recursive: true, force: true });\n fs.mkdirSync(functionsDir, { recursive: true });\n }\n\n console.log(\n `[workspace-deploy] Building ${apps.length} app(s) for preset=${preset}`,\n );\n\n const execFile = opts.execFile ?? execFileSync;\n for (const app of apps) {\n buildOneApp(workspaceRoot, app, preset, execFile, workspaceApps);\n moveAppBuildIntoDist(workspaceRoot, app, distDir, preset, workspaceApps);\n }\n writeWorkspaceAppManifests(\n workspaceRoot,\n distDir,\n apps,\n workspaceApps,\n preset,\n );\n\n if (preset === \"netlify\") {\n writeNetlifyRedirects(distDir, apps);\n } else {\n writeCloudflareRoutingManifest(distDir, apps);\n }\n\n if (buildOnly) {\n console.log(\n `\\n[workspace-deploy] Build complete at ${distDir}. Skipping publish (--build-only).`,\n );\n return;\n }\n\n console.log(`\\n[workspace-deploy] Build complete. Publish with:\\n`);\n console.log(` cd ${path.relative(process.cwd(), workspaceRoot) || \".\"}`);\n if (preset === \"netlify\") {\n console.log(\n ` netlify deploy --prod --dir=dist --functions=.netlify/functions-internal\\n`,\n );\n } else {\n console.log(` wrangler pages deploy dist\\n`);\n }\n console.log(\n `All apps live at https://<origin>/<app-name>/*. Log in once on any app\\nand the session is shared across the workspace.`,\n );\n}\n\nfunction buildOneApp(\n workspaceRoot: string,\n app: string,\n preset: WorkspaceDeployPreset,\n execFile: typeof execFileSync,\n workspaceApps: WorkspaceAppManifestEntry[],\n): void {\n const appDir = path.join(workspaceRoot, \"apps\", app);\n const env: NodeJS.ProcessEnv = {\n ...process.env,\n NITRO_PRESET: preset,\n APP_BASE_PATH: `/${app}`,\n VITE_APP_BASE_PATH: `/${app}`,\n [WORKSPACE_APPS_ENV_KEY]: JSON.stringify(workspaceApps),\n };\n\n if (preset === \"netlify\" && appUsesNetlifyUnpooledDatabaseUrl(appDir)) {\n env.DATABASE_URL =\n process.env.NETLIFY_DATABASE_URL_UNPOOLED ??\n process.env.DATABASE_URL ??\n env.DATABASE_URL;\n }\n\n console.log(\n `[workspace-deploy] Building ${app} (base=/${app}, preset=${preset})`,\n );\n\n cleanAppBuildOutputs(appDir);\n\n execFile(\"pnpm\", [\"--filter\", app, \"build\"], {\n cwd: workspaceRoot,\n env,\n stdio: \"inherit\",\n });\n}\n\nfunction moveAppBuildIntoDist(\n workspaceRoot: string,\n app: string,\n distDir: string,\n preset: WorkspaceDeployPreset,\n workspaceApps: WorkspaceAppManifestEntry[],\n): void {\n const appDir = path.join(workspaceRoot, \"apps\", app);\n // Resolve the per-app build output: prefer dist/ (standard), fall back to\n // .output/ (Nitro's default). The Cloudflare preset emits into dist/\n // containing the worker + assets.\n const candidates = [\"dist\", \".output\"];\n const src = candidates\n .map((c) => path.join(appDir, c))\n .find((p) => fs.existsSync(p));\n if (!src) {\n throw new Error(\n `Expected ${candidates.join(\" or \")} under ${appDir} but none existed. Check the app's build script.`,\n );\n }\n if (preset === \"netlify\") {\n const mountedSrc = path.join(src, app);\n const staticSrc = fs.existsSync(mountedSrc) ? mountedSrc : src;\n const target = path.join(distDir, NETLIFY_WORKSPACE_STATIC_DIR, app);\n fs.mkdirSync(target, { recursive: true });\n copyDir(staticSrc, target);\n // Nitro/Vite mounted builds can contain a nested copy of public assets at\n // dist/<app>/<app>/...; the workspace root already supplies the outer\n // mount path, so keeping it would publish duplicate /<app>/<app> URLs.\n fs.rmSync(path.join(target, app), { recursive: true, force: true });\n copyNetlifyFunctionIntoWorkspace(workspaceRoot, app, workspaceApps, target);\n } else {\n const target = path.join(distDir, app);\n fs.mkdirSync(target, { recursive: true });\n copyDir(src, target);\n }\n}\n\n/**\n * Write the Cloudflare Pages `_routes.json` and a dispatcher `_worker.js` at\n * the workspace dist root so each app is reachable under /<app>/*.\n */\nfunction writeCloudflareRoutingManifest(distDir: string, apps: string[]): void {\n const dispatchFaviconAsset = apps.includes(\"dispatch\")\n ? dispatchRootFaviconAsset(distDir)\n : null;\n // _routes.json tells Cloudflare which paths are dynamic (Functions) vs\n // static. Mark /<app>/* as include so every app's worker handles its\n // subtree.\n const include = apps.map((a) => `/${a}/*`).concat([\"/\"]);\n if (apps.includes(\"dispatch\")) {\n include.push(\"/_agent-native/*\");\n include.push(\"/.well-known/*\");\n if (dispatchFaviconAsset) include.push(\"/favicon.ico\");\n }\n const routes = {\n version: 1,\n include,\n exclude: [],\n };\n fs.writeFileSync(\n path.join(distDir, \"_routes.json\"),\n JSON.stringify(routes, null, 2) + \"\\n\",\n );\n\n // Dispatcher worker: inspects the path and forwards to the matching\n // per-app worker.\n const imports = apps\n .map((a) => `import ${moduleIdent(a)} from \"./${a}/_worker.js\";`)\n .join(\"\\n\");\n const dispatch = apps\n .map(\n (a) =>\n ` if (pathname === \"/${a}\" || pathname.startsWith(\"/${a}/\")) return ${moduleIdent(a)}.fetch(request, env, ctx);`,\n )\n .join(\"\\n\");\n const dispatchRootFrameworkRoutes = apps.includes(\"dispatch\")\n ? ` if (pathname === \"/_agent-native\" || pathname.startsWith(\"/_agent-native/\") || pathname === \"/.well-known\" || pathname.startsWith(\"/.well-known/\")) return ${moduleIdent(\"dispatch\")}.fetch(request, env, ctx);\n`\n : \"\";\n const dispatchRootFaviconRoute = dispatchFaviconAsset\n ? ` if (pathname === \"/favicon.ico\") return Response.redirect(new URL(\"/dispatch/${dispatchFaviconAsset}\", request.url).toString(), 302);\n`\n : \"\";\n\n const worker = `${imports}\n\nexport default {\n async fetch(request, env, ctx) {\n const { pathname } = new URL(request.url);\n${dispatchRootFrameworkRoutes}${dispatchRootFaviconRoute}${dispatch}\n if (pathname === \"/\") {\n return Response.redirect(new URL(\"${cloudflareRootRedirectPath(apps)}\", request.url).toString(), 302);\n }\n return new Response(\"Not found\", { status: 404 });\n },\n};\n`;\n fs.writeFileSync(path.join(distDir, \"_worker.js\"), worker);\n}\n\nfunction cloudflareRootRedirectPath(apps: string[]): string {\n return apps.includes(\"dispatch\") ? \"/dispatch/overview\" : `/${apps[0]}/`;\n}\n\nfunction writeNetlifyRedirects(distDir: string, apps: string[]): void {\n const lines: string[] = [\n \"# Generated by agent-native deploy --preset netlify\",\n \"# Static app assets are stored under a safe namespace; dynamic app routes are handled by function route config.\",\n ];\n\n if (apps.includes(\"dispatch\")) {\n lines.push(\"/_agent-native/* /.netlify/functions/dispatch-server 200\");\n lines.push(\"/.well-known/* /.netlify/functions/dispatch-server 200\");\n const faviconAsset = dispatchRootFaviconAsset(distDir);\n if (faviconAsset) {\n lines.push(`/favicon.ico /dispatch/${faviconAsset} 302`);\n }\n }\n\n for (const app of apps) {\n lines.push(...netlifyAssetRedirectsFor(app, distDir));\n }\n\n if (apps.includes(\"dispatch\")) {\n lines.push(\"/ /dispatch/overview 302\");\n lines.push(\"/dispatch /dispatch/overview 302\");\n for (const [from, to] of DISPATCH_WORKSPACE_ROOT_REDIRECTS) {\n lines.push(`/${from} /dispatch/${to} 302`);\n }\n } else {\n lines.push(`/ /${apps[0]}/ 302`);\n }\n\n fs.writeFileSync(path.join(distDir, \"_redirects\"), lines.join(\"\\n\") + \"\\n\");\n}\n\nfunction netlifyAssetRedirectsFor(app: string, distDir: string): string[] {\n const from = `/${app}`;\n const to = `/${NETLIFY_WORKSPACE_STATIC_DIR}/${app}`;\n return [\n `${from}/assets/* ${to}/assets/:splat 200`,\n ...netlifyPublicRootAssetPaths(\n app,\n path.join(distDir, NETLIFY_WORKSPACE_STATIC_DIR, app),\n ).map((assetPath) => {\n const assetName = assetPath.slice(from.length + 1);\n return `${assetPath} ${to}/${assetName} 200`;\n }),\n ];\n}\n\nfunction dispatchRootFaviconAsset(distDir: string): string | null {\n for (const asset of [\"favicon.ico\", \"favicon.svg\", \"favicon.png\"]) {\n if (workspaceAppAssetExists(distDir, \"dispatch\", asset)) return asset;\n }\n return null;\n}\n\nfunction workspaceAppAssetExists(\n distDir: string,\n app: string,\n asset: string,\n): boolean {\n return [\n path.join(distDir, NETLIFY_WORKSPACE_STATIC_DIR, app, asset),\n path.join(distDir, app, app, asset),\n path.join(distDir, app, asset),\n ].some((candidate) => fs.existsSync(candidate));\n}\n\nconst DISPATCH_WORKSPACE_ROOT_REDIRECTS = [\n [\"overview\", \"overview\"],\n [\"login\", \"login\"],\n [\"signup\", \"signup\"],\n [\"apps\", \"apps\"],\n [\"apps/new-app\", \"new-app\"],\n [\"new-app\", \"new-app\"],\n [\"vault\", \"vault\"],\n [\"integrations\", \"integrations\"],\n [\"agents\", \"agents\"],\n [\"workspace\", \"workspace\"],\n [\"messaging\", \"messaging\"],\n [\"destinations\", \"destinations\"],\n [\"identities\", \"identities\"],\n [\"approvals\", \"approvals\"],\n [\"audit\", \"audit\"],\n [\"team\", \"team\"],\n];\n\nconst RESERVED_WORKSPACE_APP_IDS = new Set([\n \"_agent-native\",\n \"_workspace_static\",\n \"netlify\",\n ...DISPATCH_WORKSPACE_ROOT_REDIRECTS.map(([from]) => from),\n]);\n\nfunction assertNoReservedWorkspaceAppIds(apps: string[]): void {\n const conflicts = apps.filter(\n (app) => app !== \"dispatch\" && RESERVED_WORKSPACE_APP_IDS.has(app),\n );\n if (conflicts.length === 0) return;\n throw new Error(\n `Workspace app id ${conflicts.map((id) => `\"${id}\"`).join(\", \")} conflicts with reserved workspace routes. Choose a different app id.`,\n );\n}\n\nfunction copyNetlifyFunctionIntoWorkspace(\n workspaceRoot: string,\n app: string,\n workspaceApps: WorkspaceAppManifestEntry[],\n staticDir: string,\n): void {\n const appDir = path.join(workspaceRoot, \"apps\", app);\n const src = path.join(appDir, \".netlify\", \"functions-internal\", \"server\");\n if (!fs.existsSync(src)) {\n throw new Error(\n `Expected Netlify function at ${src} after building ${app}. Check the app's build script and NITRO_PRESET.`,\n );\n }\n\n const dest = path.join(netlifyFunctionsDir(workspaceRoot), `${app}-server`);\n fs.rmSync(dest, { recursive: true, force: true });\n copyDir(src, dest);\n patchNetlifyFunctionEntry(dest, app, workspaceApps, staticDir);\n}\n\nfunction patchNetlifyFunctionEntry(\n functionDir: string,\n app: string,\n workspaceApps: WorkspaceAppManifestEntry[],\n staticDir: string,\n): void {\n const serverPath = path.join(functionDir, \"server.mjs\");\n if (!fs.existsSync(serverPath)) return;\n\n const basePath = `/${app}`;\n const pathConfig =\n app === \"dispatch\"\n ? [\"/_agent-native/*\", \"/.well-known/*\", `${basePath}/*`]\n : [basePath, `${basePath}/*`];\n const normalizeBasePathHelper =\n app === \"dispatch\"\n ? \"\"\n : `\nfunction normalizeBasePathArgs(args) {\n const request = args[0];\n if (!request || typeof request.url !== \"string\" || typeof Request !== \"function\") {\n return args;\n }\n const url = new URL(request.url);\n if (url.pathname === basePath || url.pathname === \\`\\${basePath}/\\`) {\n url.pathname = \\`\\${basePath}//\\`;\n return [new Request(url, request), ...args.slice(1)];\n }\n return args;\n}\n`;\n const handlerArgs =\n app === \"dispatch\" ? \"...args\" : \"...normalizeBasePathArgs(args)\";\n const server = `const basePath = ${JSON.stringify(basePath)};\n\nfunction setBasePathEnv() {\n const processRef = globalThis.process ??= { env: {} };\n processRef.env ??= {};\n Object.assign(processRef.env, {\n APP_BASE_PATH: basePath,\n VITE_APP_BASE_PATH: basePath,\n ${JSON.stringify(WORKSPACE_APPS_ENV_KEY)}: ${JSON.stringify(JSON.stringify(workspaceApps))},\n });\n}\n\nsetBasePathEnv();\n${normalizeBasePathHelper}\n\nlet cachedHandler;\n\nexport default async function handler(...args) {\n setBasePathEnv();\n cachedHandler ??= (await import(\"./main.mjs\")).default;\n return cachedHandler(${handlerArgs});\n}\n\nexport const config = {\n name: ${JSON.stringify(`${app} server handler`)},\n generator: \"agent-native workspace deploy\",\n path: ${JSON.stringify(pathConfig)},\n nodeBundler: \"none\",\n includedFiles: [\"**\"],\n excludedPath: ${JSON.stringify(\n netlifyFunctionExcludedPaths(app, staticDir),\n null,\n 2,\n )\n .split(\"\\n\")\n .join(\"\\n \")},\n preferStatic: false,\n};\n`;\n fs.rmSync(serverPath, { force: true });\n fs.writeFileSync(path.join(functionDir, `${app}-server.mjs`), server);\n}\n\nfunction netlifyFunctionExcludedPaths(\n app: string,\n staticDir: string,\n): string[] {\n return [\n \"/.netlify/*\",\n `/${app}/assets/*`,\n ...netlifyPublicRootAssetPaths(app, staticDir),\n ];\n}\n\nfunction netlifyPublicRootAssetPaths(app: string, staticDir: string): string[] {\n if (!fs.existsSync(staticDir)) return [];\n return fs\n .readdirSync(staticDir, { withFileTypes: true })\n .filter((entry) => entry.isFile())\n .map((entry) => entry.name)\n .filter((name) => {\n const ext = path.extname(name).slice(1).toLowerCase();\n return NETLIFY_PUBLIC_ASSET_EXTENSIONS.has(ext);\n })\n .sort()\n .map((name) => `/${app}/${encodeURI(name)}`);\n}\n\nfunction netlifyFunctionsDir(workspaceRoot: string): string {\n return path.join(workspaceRoot, \".netlify\", \"functions-internal\");\n}\n\nfunction cleanAppBuildOutputs(appDir: string): void {\n for (const name of [\"dist\", \".output\", \"build\"]) {\n fs.rmSync(path.join(appDir, name), { recursive: true, force: true });\n }\n fs.rmSync(path.join(appDir, \".netlify\", \"functions-internal\"), {\n recursive: true,\n force: true,\n });\n}\n\nfunction appUsesNetlifyUnpooledDatabaseUrl(appDir: string): boolean {\n const netlifyPath = path.join(appDir, \"netlify.toml\");\n if (!fs.existsSync(netlifyPath)) return false;\n try {\n return fs\n .readFileSync(netlifyPath, \"utf-8\")\n .includes(\"NETLIFY_DATABASE_URL_UNPOOLED\");\n } catch {\n return false;\n }\n}\n\nfunction writeWorkspaceAppManifests(\n workspaceRoot: string,\n distDir: string,\n apps: string[],\n workspaceApps: WorkspaceAppManifestEntry[],\n preset: WorkspaceDeployPreset,\n): void {\n const manifest = JSON.stringify(\n {\n version: 1,\n apps: workspaceApps,\n },\n null,\n 2,\n );\n\n const targets =\n preset === \"netlify\"\n ? apps.map((app) =>\n path.join(\n netlifyFunctionsDir(workspaceRoot),\n `${app}-server`,\n WORKSPACE_APPS_MANIFEST_DIR,\n WORKSPACE_APPS_MANIFEST_FILE,\n ),\n )\n : apps.map((app) =>\n path.join(\n distDir,\n app,\n WORKSPACE_APPS_MANIFEST_DIR,\n WORKSPACE_APPS_MANIFEST_FILE,\n ),\n );\n\n for (const target of targets) {\n fs.mkdirSync(path.dirname(target), { recursive: true });\n fs.writeFileSync(target, `${manifest}\\n`);\n }\n}\n\nfunction readWorkspaceAppManifest(\n workspaceRoot: string,\n apps: string[],\n): WorkspaceAppManifestEntry[] {\n const explicitApps = readExistingWorkspaceAppManifest(workspaceRoot);\n\n return apps\n .map((app) => {\n const appDir = path.join(workspaceRoot, \"apps\", app);\n const pkg = readPackageJson(path.join(appDir, \"package.json\"));\n const appPath = `/${app}`;\n const explicit = explicitApps.get(app);\n const url =\n normalizeWorkspaceAppUrl(explicit?.url) ?? workspaceAppUrl(appPath);\n return {\n id: app,\n name: pkg?.displayName || titleCase(app),\n description: pkg?.description || \"\",\n path: appPath,\n ...(url ? { url } : {}),\n isDispatch: app === \"dispatch\",\n };\n })\n .sort((a, b) => {\n if (a.id === \"dispatch\") return -1;\n if (b.id === \"dispatch\") return 1;\n return a.name.localeCompare(b.name);\n });\n}\n\nfunction readExistingWorkspaceAppManifest(\n workspaceRoot: string,\n): Map<string, { url?: string }> {\n const fromEnv = parseWorkspaceAppsJson(process.env[WORKSPACE_APPS_ENV_KEY]);\n const fromFile =\n readWorkspaceAppsFromFile(\n path.join(\n workspaceRoot,\n WORKSPACE_APPS_MANIFEST_DIR,\n WORKSPACE_APPS_MANIFEST_FILE,\n ),\n ) ??\n readWorkspaceAppsFromFile(\n path.join(workspaceRoot, WORKSPACE_APPS_MANIFEST_FILE),\n );\n const apps = fromEnv ?? fromFile ?? [];\n return new Map(apps.map((app) => [app.id, app]));\n}\n\nfunction parseWorkspaceAppsJson(\n raw: string | undefined,\n): Array<{ id: string; url?: string }> | null {\n if (!raw) return null;\n try {\n return parseWorkspaceAppsManifest(JSON.parse(raw));\n } catch {\n return null;\n }\n}\n\nfunction readWorkspaceAppsFromFile(\n file: string,\n): Array<{ id: string; url?: string }> | null {\n if (!fs.existsSync(file)) return null;\n return parseWorkspaceAppsManifest(readPackageJson(file));\n}\n\nfunction parseWorkspaceAppsManifest(\n parsed: any,\n): Array<{ id: string; url?: string }> | 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) => {\n if (!entry || typeof entry !== \"object\") return null;\n const id = typeof entry.id === \"string\" ? entry.id.trim() : \"\";\n if (!id) return null;\n const url = normalizeWorkspaceAppUrl(entry.url);\n return {\n id,\n ...(url ? { url } : {}),\n };\n })\n .filter((app): app is { id: string; url?: string } => !!app);\n\n return apps.length ? apps : null;\n}\n\nfunction workspaceBaseUrl(): string | null {\n return (\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 );\n}\n\nfunction workspaceAppUrl(appPath: string): string | undefined {\n const base = workspaceBaseUrl();\n if (!base) return undefined;\n try {\n return new URL(appPath, `${base.replace(/\\/$/, \"\")}/`).toString();\n } catch {\n return undefined;\n }\n}\n\nfunction normalizeWorkspaceAppUrl(value: unknown): string | undefined {\n if (typeof value !== \"string\" || !value.trim()) return undefined;\n try {\n return new URL(value.trim()).toString().replace(/\\/$/, \"\");\n } catch {\n return undefined;\n }\n}\n\nfunction readPackageJson(file: string): Record<string, any> | null {\n try {\n return JSON.parse(fs.readFileSync(file, \"utf8\"));\n } catch {\n return null;\n }\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 parsePresetArg(args: string[]): WorkspaceDeployPreset | null {\n for (let i = 0; i < args.length; i++) {\n const arg = args[i];\n if (arg === \"--preset\" && args[i + 1]) {\n return normalizePreset(args[i + 1]);\n }\n if (arg.startsWith(\"--preset=\")) {\n return normalizePreset(arg.slice(\"--preset=\".length));\n }\n }\n return null;\n}\n\nfunction resolvePreset(\n optionPreset: WorkspaceDeployPreset | undefined,\n args: string[],\n): WorkspaceDeployPreset {\n return (\n optionPreset ??\n parsePresetArg(args) ??\n normalizePreset(process.env.NITRO_PRESET) ??\n \"cloudflare_pages\"\n );\n}\n\nfunction assertWorkspaceDeployProductionEnv(opts: {\n buildOnly: boolean;\n preset: WorkspaceDeployPreset;\n}): void {\n if (!isProductionWorkspaceDeploy(opts)) return;\n if (process.env.A2A_SECRET?.trim()) return;\n throw new Error(\n [\n \"A2A_SECRET is required for production workspace deploys.\",\n \"Workspace Slack, webhook, and cross-app A2A work resumes through signed background processors; without A2A_SECRET those production routes return 503.\",\n 'Set A2A_SECRET in your deploy provider (for example: netlify env:set A2A_SECRET \"$(openssl rand -hex 32)\") and redeploy.',\n \"For local artifact checks, run agent-native deploy --build-only outside the deploy provider environment.\",\n ].join(\" \"),\n );\n}\n\nfunction isProductionWorkspaceDeploy(opts: {\n buildOnly: boolean;\n preset: WorkspaceDeployPreset;\n}): boolean {\n if (!opts.buildOnly) return true;\n if (\n opts.preset === \"netlify\" &&\n process.env.NETLIFY === \"true\" &&\n process.env.NETLIFY_LOCAL !== \"true\"\n ) {\n return true;\n }\n if (opts.preset === \"cloudflare_pages\" && process.env.CF_PAGES === \"1\") {\n return true;\n }\n return false;\n}\n\nfunction normalizePreset(\n value: string | undefined,\n): WorkspaceDeployPreset | null {\n if (!value) return null;\n if (value === \"cloudflare_pages\" || value === \"cloudflare-pages\") {\n return \"cloudflare_pages\";\n }\n if (value === \"netlify\") return \"netlify\";\n throw new Error(\n `Unsupported workspace deploy preset \"${value}\". Supported presets: cloudflare_pages, netlify.`,\n );\n}\n\nfunction moduleIdent(app: string): string {\n return \"app_\" + app.replace(/[^a-zA-Z0-9_]/g, \"_\");\n}\n\nfunction compareWorkspaceAppIds(a: string, b: string): number {\n if (a === \"dispatch\") return -1;\n if (b === \"dispatch\") return 1;\n return a.localeCompare(b);\n}\n\nfunction copyDir(src: string, dest: string): void {\n fs.mkdirSync(dest, { recursive: true });\n for (const entry of fs.readdirSync(src, { withFileTypes: true })) {\n const s = path.join(src, entry.name);\n const d = path.join(dest, entry.name);\n if (entry.isSymbolicLink()) {\n try {\n const target = fs.readlinkSync(s);\n fs.symlinkSync(target, d);\n } catch {\n fs.copyFileSync(s, d);\n }\n } else if (entry.isDirectory()) {\n copyDir(s, d);\n } else {\n fs.copyFileSync(s, d);\n }\n }\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../../src/integrations/plugin.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../../src/integrations/plugin.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAEV,yBAAyB,EAE1B,MAAM,YAAY,CAAC;AAiCpB,KAAK,cAAc,GAAG,CAAC,QAAQ,EAAE,GAAG,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;AAyH9D;;;;;;;;;;GAUG;AACH,wBAAgB,wBAAwB,CACtC,OAAO,CAAC,EAAE,yBAAyB,GAClC,cAAc,CA8iBhB;AAED;;GAEG;AACH,eAAO,MAAM,yBAAyB,gBAA6B,CAAC"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { defineEventHandler, setResponseStatus, getMethod } from "h3";
|
|
2
2
|
import { createRemoteJWKSet, jwtVerify } from "jose";
|
|
3
3
|
import { FRAMEWORK_ROUTE_PREFIX } from "../server/core-routes-plugin.js";
|
|
4
|
-
import { getH3App } from "../server/framework-request-handler.js";
|
|
4
|
+
import { getH3App, markDefaultPluginProvided, } from "../server/framework-request-handler.js";
|
|
5
5
|
import { handleWebhook, processIntegrationTask } from "./webhook-handler.js";
|
|
6
6
|
import { DEFAULT_MODEL } from "../agent/default-model.js";
|
|
7
7
|
import { claimPendingTask, markTaskCompleted, markTaskFailed, } from "./pending-tasks-store.js";
|
|
@@ -138,6 +138,7 @@ If a task requires many steps, summarize what you did rather than streaming ever
|
|
|
138
138
|
*/
|
|
139
139
|
export function createIntegrationsPlugin(options) {
|
|
140
140
|
return async (nitroApp) => {
|
|
141
|
+
markDefaultPluginProvided(nitroApp, "integrations");
|
|
141
142
|
const adapters = options?.adapters ?? getDefaultAdapters();
|
|
142
143
|
const adapterMap = new Map();
|
|
143
144
|
for (const adapter of adapters) {
|