@agent-native/core 0.22.40 → 0.22.43

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.
@@ -1 +1 @@
1
- {"version":3,"file":"templates-meta.d.ts","sourceRoot":"","sources":["../../src/cli/templates-meta.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,MAAM,WAAW,YAAY;IAC3B,uDAAuD;IACvD,IAAI,EAAE,MAAM,CAAC;IACb,8BAA8B;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd,+CAA+C;IAC/C,IAAI,EAAE,MAAM,CAAC;IACb,oCAAoC;IACpC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,mDAAmD;IACnD,IAAI,EAAE,MAAM,CAAC;IACb,uBAAuB;IACvB,KAAK,EAAE,MAAM,CAAC;IACd,+CAA+C;IAC/C,QAAQ,EAAE,MAAM,CAAC;IACjB,6CAA6C;IAC7C,OAAO,EAAE,MAAM,CAAC;IAChB,2EAA2E;IAC3E,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,4EAA4E;IAC5E,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,6CAA6C;IAC7C,WAAW,CAAC,EAAE,KAAK,GAAG,MAAM,CAAC;IAC7B,uEAAuE;IACvE,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,8EAA8E;IAC9E,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,mEAAmE;IACnE,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,+EAA+E;IAC/E,gBAAgB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC5B,wEAAwE;IACxE,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAED,eAAO,MAAM,SAAS,EAAE,YAAY,EA+QnC,CAAC;AAEF,yEAAyE;AACzE,wBAAgB,gBAAgB,IAAI,YAAY,EAAE,CAEjD;AAED,gFAAgF;AAChF,wBAAgB,aAAa,IAAI,YAAY,EAAE,CAE9C;AAED,2DAA2D;AAC3D,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,YAAY,GAAG,SAAS,CAIlE;AAED,gEAAgE;AAChE,wBAAgB,gBAAgB,IAAI,MAAM,EAAE,CAE3C"}
1
+ {"version":3,"file":"templates-meta.d.ts","sourceRoot":"","sources":["../../src/cli/templates-meta.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,MAAM,WAAW,YAAY;IAC3B,uDAAuD;IACvD,IAAI,EAAE,MAAM,CAAC;IACb,8BAA8B;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd,+CAA+C;IAC/C,IAAI,EAAE,MAAM,CAAC;IACb,oCAAoC;IACpC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,mDAAmD;IACnD,IAAI,EAAE,MAAM,CAAC;IACb,uBAAuB;IACvB,KAAK,EAAE,MAAM,CAAC;IACd,+CAA+C;IAC/C,QAAQ,EAAE,MAAM,CAAC;IACjB,6CAA6C;IAC7C,OAAO,EAAE,MAAM,CAAC;IAChB,2EAA2E;IAC3E,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,4EAA4E;IAC5E,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,6CAA6C;IAC7C,WAAW,CAAC,EAAE,KAAK,GAAG,MAAM,CAAC;IAC7B,uEAAuE;IACvE,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,8EAA8E;IAC9E,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,mEAAmE;IACnE,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,+EAA+E;IAC/E,gBAAgB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC5B,wEAAwE;IACxE,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAED,eAAO,MAAM,SAAS,EAAE,YAAY,EA2RnC,CAAC;AAEF,yEAAyE;AACzE,wBAAgB,gBAAgB,IAAI,YAAY,EAAE,CAEjD;AAED,gFAAgF;AAChF,wBAAgB,aAAa,IAAI,YAAY,EAAE,CAE9C;AAED,2DAA2D;AAC3D,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,YAAY,GAAG,SAAS,CAIlE;AAED,gEAAgE;AAChE,wBAAgB,gBAAgB,IAAI,MAAM,EAAE,CAE3C"}
@@ -273,6 +273,18 @@ export const TEMPLATES = [
273
273
  defaultMode: "prod",
274
274
  hidden: true,
275
275
  },
276
+ {
277
+ name: "workbench",
278
+ label: "Workbench",
279
+ hint: "Visual command center for AI-assisted work — review PRs, monitor agent runs, build mini-tools",
280
+ icon: "LayoutDashboard",
281
+ color: "#475569",
282
+ colorRgb: "71 85 105",
283
+ devPort: 8104,
284
+ prodUrl: "https://workbench.agent-native.com",
285
+ defaultMode: "prod",
286
+ hidden: true,
287
+ },
276
288
  {
277
289
  name: "macros",
278
290
  label: "Macros",
@@ -1 +1 @@
1
- {"version":3,"file":"templates-meta.js","sourceRoot":"","sources":["../../src/cli/templates-meta.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * First-party template metadata used by the `agent-native` CLI.\n *\n * This file is intentionally inlined here (rather than imported from a\n * separate workspace package) so that the published `@agent-native/core`\n * has no `workspace:*` runtime dependencies. Without this inlining, `npx\n * @agent-native/core create ...` fails on a fresh machine with:\n *\n * npm error code EUNSUPPORTEDPROTOCOL\n * npm error Unsupported URL Type \"workspace:\": workspace:*\n *\n * Keep this list in sync with `packages/shared-app-config/templates.ts`,\n * which serves the same metadata to the desktop / mobile / frame packages\n * that always run inside the workspace. Duplication is intentional: the\n * CLI must remain installable outside the monorepo.\n */\n\nexport interface TemplateMeta {\n /** Directory name under templates/ and package name */\n name: string;\n /** Display name in pickers */\n label: string;\n /** One-line description shown in the picker */\n hint: string;\n /** Longer description (optional) */\n description?: string;\n /** Tabler icon name used in the desktop sidebar */\n icon: string;\n /** Hex accent color */\n color: string;\n /** CSS-safe RGB triplet (e.g. \"59 130 246\") */\n colorRgb: string;\n /** Dev server port for desktop `pnpm dev` */\n devPort: number;\n /** Production URL when running as a first-party app on agent-native.com */\n prodUrl?: string;\n /** Default URL path when deployed in a workspace (defaults to \"/<name>\") */\n prodPath?: string;\n /** Default mode when added to desktop app */\n defaultMode?: \"dev\" | \"prod\";\n /** Hide from pickers but still scaffoldable via explicit --template */\n hidden?: boolean;\n /** Include as a built-in connected A2A agent even when hidden from pickers */\n defaultAgent?: boolean;\n /** Always scaffold without prompting (e.g. starter as fallback) */\n alwaysAvailable?: boolean;\n /** Internal workspace packages this template depends on (e.g. \"scheduling\") */\n requiredPackages?: string[];\n /** Core app — featured in the CLI picker, homepage, and docs gallery */\n core?: boolean;\n}\n\nexport const TEMPLATES: TemplateMeta[] = [\n {\n name: \"calendar\",\n label: \"Calendar\",\n hint: \"Agent-native Google Calendar — manage events, sync, and public booking\",\n icon: \"CalendarDays\",\n color: \"#00B5FF\",\n colorRgb: \"0 181 255\",\n devPort: 8082,\n prodUrl: \"https://calendar.agent-native.com\",\n defaultMode: \"prod\",\n requiredPackages: [\"scheduling\"],\n core: true,\n },\n {\n name: \"content\",\n label: \"Content\",\n hint: \"Agent-native Notion/Google Docs — write and organize with agent assistance\",\n icon: \"FileText\",\n color: \"#10B981\",\n colorRgb: \"16 185 129\",\n devPort: 8083,\n prodUrl: \"https://content.agent-native.com\",\n defaultMode: \"prod\",\n core: true,\n },\n {\n name: \"slides\",\n label: \"Slides\",\n hint: \"Agent-native Google Slides — generate and edit React presentations\",\n icon: \"GalleryHorizontal\",\n color: \"#EC4899\",\n colorRgb: \"236 72 153\",\n devPort: 8086,\n prodUrl: \"https://slides.agent-native.com\",\n defaultMode: \"prod\",\n requiredPackages: [\"pinpoint\"],\n core: true,\n },\n {\n name: \"videos\",\n label: \"Video\",\n hint: \"Agent-native video editing with Remotion\",\n icon: \"Video\",\n color: \"#EF4444\",\n colorRgb: \"239 68 68\",\n devPort: 8087,\n prodUrl: \"https://videos.agent-native.com\",\n defaultMode: \"prod\",\n requiredPackages: [\"pinpoint\"],\n },\n {\n name: \"analytics\",\n label: \"Analytics\",\n hint: \"Agent-native Amplitude/Mixpanel — connect data sources, prompt for charts\",\n icon: \"BarChart2\",\n color: \"#F59E0B\",\n colorRgb: \"245 158 11\",\n devPort: 8088,\n prodUrl: \"https://analytics.agent-native.com\",\n defaultMode: \"prod\",\n core: true,\n },\n {\n name: \"mail\",\n label: \"Mail\",\n hint: \"Agent-native Superhuman — email client with keyboard shortcuts and AI triage\",\n icon: \"Mail\",\n color: \"#3B82F6\",\n colorRgb: \"59 130 246\",\n devPort: 8085,\n prodUrl: \"https://mail.agent-native.com\",\n defaultMode: \"prod\",\n core: true,\n },\n {\n name: \"dispatch\",\n label: \"Dispatch\",\n hint: \"Central Slack/Telegram router with jobs, memory, approvals, and A2A delegation\",\n icon: \"MessageCircle\",\n color: \"#14B8A6\",\n colorRgb: \"20 184 166\",\n devPort: 8092,\n prodUrl: \"https://dispatch.agent-native.com\",\n defaultMode: \"prod\",\n core: true,\n },\n {\n name: \"forms\",\n label: \"Forms\",\n hint: \"Agent-native form builder — create, edit, and manage forms\",\n icon: \"ClipboardList\",\n color: \"#06B6D4\",\n colorRgb: \"6 182 212\",\n devPort: 8084,\n prodUrl: \"https://forms.agent-native.com\",\n defaultMode: \"prod\",\n core: true,\n },\n {\n name: \"code\",\n label: \"Agent-Native Code\",\n hint: \"Hidden customizable Agent-Native Code UI for local coding sessions and slash commands\",\n icon: \"Code\",\n color: \"#71717A\",\n colorRgb: \"113 113 122\",\n devPort: 8103,\n defaultMode: \"dev\",\n hidden: true,\n },\n {\n name: \"migration\",\n label: \"Migration Goal Surface\",\n hint: \"Internal Agent-Native Code detail surface for /migrate assessment, approval, and verification\",\n icon: \"Route\",\n color: \"#0F766E\",\n colorRgb: \"15 118 110\",\n devPort: 8101,\n defaultMode: \"dev\",\n hidden: true,\n requiredPackages: [\"migrate\"],\n },\n {\n name: \"issues\",\n label: \"Issues\",\n hint: \"Agent-native Jira — project management and issue tracking\",\n icon: \"BrandJira\",\n color: \"#0EA5E9\",\n colorRgb: \"14 165 233\",\n devPort: 8091,\n prodUrl: \"https://issues.agent-native.com\",\n defaultMode: \"dev\",\n hidden: true,\n },\n {\n name: \"recruiting\",\n label: \"Recruiting\",\n hint: \"Agent-native Greenhouse — manage candidates and recruiting pipelines\",\n icon: \"Users\",\n color: \"#16A34A\",\n colorRgb: \"22 163 74\",\n devPort: 8090,\n prodUrl: \"https://recruiting.agent-native.com\",\n defaultMode: \"dev\",\n hidden: true,\n },\n {\n name: \"starter\",\n label: \"Starter\",\n hint: \"Minimal scaffold with the agent chat and core architecture wired up\",\n icon: \"Code\",\n color: \"#71717A\",\n colorRgb: \"113 113 122\",\n devPort: 8089,\n defaultMode: \"prod\",\n alwaysAvailable: true,\n core: true,\n hidden: true,\n },\n {\n name: \"clips\",\n label: \"Clips\",\n hint: \"Screen recording, meeting notes, and voice dictation — all with AI\",\n icon: \"ScreenShare\",\n color: \"#0EA5E9\",\n colorRgb: \"14 165 233\",\n devPort: 8094,\n prodUrl: \"https://clips.agent-native.com\",\n defaultMode: \"prod\",\n core: true,\n },\n {\n name: \"brain\",\n label: \"Brain\",\n hint: \"Cited company memory from Slack, meetings, transcripts, and decisions\",\n icon: \"Brain\",\n color: \"#8B5CF6\",\n colorRgb: \"139 92 246\",\n devPort: 8102,\n prodUrl: \"https://brain.agent-native.com\",\n defaultMode: \"prod\",\n defaultAgent: true,\n core: true,\n },\n {\n name: \"design\",\n label: \"Design\",\n hint: \"Agent-native design tool — create and edit visual designs with agent assistance\",\n icon: \"Brush\",\n color: \"#F472B6\",\n colorRgb: \"244 114 182\",\n devPort: 8099,\n prodUrl: \"https://design.agent-native.com\",\n defaultMode: \"prod\",\n requiredPackages: [\"pinpoint\"],\n core: true,\n },\n {\n name: \"images\",\n label: \"Images\",\n hint: \"Brand image libraries — generate on-brand heroes, diagrams, product shots, and slide art\",\n icon: \"Photo\",\n color: \"#0F766E\",\n colorRgb: \"15 118 110\",\n devPort: 8100,\n prodUrl: \"https://images.agent-native.com\",\n defaultMode: \"prod\",\n hidden: true,\n defaultAgent: true,\n },\n {\n name: \"calls\",\n label: \"Calls\",\n hint: \"Agent-native Gong — record, transcribe, and analyze sales calls\",\n icon: \"Phone\",\n color: \"#111111\",\n colorRgb: \"17 17 17\",\n devPort: 8095,\n prodUrl: \"https://calls.agent-native.com\",\n defaultMode: \"prod\",\n hidden: true,\n },\n {\n name: \"meeting-notes\",\n label: \"Meeting Notes\",\n hint: \"AI meeting notes — transcribe, enhance, and share meeting notes\",\n icon: \"Note\",\n color: \"#16A34A\",\n colorRgb: \"22 163 74\",\n devPort: 8096,\n prodUrl: \"https://meeting-notes.agent-native.com\",\n defaultMode: \"prod\",\n hidden: true,\n },\n {\n name: \"scheduling\",\n label: \"Scheduling\",\n hint: \"Full scheduling app — event types, team round-robin, routing forms, workflows\",\n icon: \"CalendarTime\",\n color: \"#0EA5E9\",\n colorRgb: \"14 165 233\",\n devPort: 8098,\n prodUrl: \"https://scheduling.agent-native.com\",\n defaultMode: \"prod\",\n requiredPackages: [\"scheduling\"],\n hidden: true,\n },\n {\n name: \"voice\",\n label: \"Voice\",\n hint: \"Voice dictation — speak to type anywhere with context-aware formatting\",\n icon: \"Microphone\",\n color: \"#0EA5E9\",\n colorRgb: \"14 165 233\",\n devPort: 8097,\n prodUrl: \"https://voice.agent-native.com\",\n defaultMode: \"prod\",\n hidden: true,\n },\n {\n name: \"macros\",\n label: \"Macros\",\n hint: \"Internal template — not shown in pickers\",\n icon: \"Code\",\n color: \"#71717A\",\n colorRgb: \"113 113 122\",\n devPort: 8093,\n prodUrl: \"https://macros.agent-native.com\",\n hidden: true,\n defaultMode: \"dev\",\n },\n];\n\n/** Return templates visible in user-facing pickers (excludes hidden). */\nexport function visibleTemplates(): TemplateMeta[] {\n return TEMPLATES.filter((t) => !t.hidden);\n}\n\n/** Return core templates — the featured set shown in CLI pickers by default. */\nexport function coreTemplates(): TemplateMeta[] {\n return TEMPLATES.filter((t) => t.core);\n}\n\n/** Lookup by name. Returns undefined for unknown names. */\nexport function getTemplate(name: string): TemplateMeta | undefined {\n // Tolerate the legacy \"video\" alias.\n if (name === \"video\") name = \"videos\";\n return TEMPLATES.find((t) => t.name === name);\n}\n\n/** Names of all templates (including hidden) for validation. */\nexport function allTemplateNames(): string[] {\n return TEMPLATES.map((t) => t.name);\n}\n"]}
1
+ {"version":3,"file":"templates-meta.js","sourceRoot":"","sources":["../../src/cli/templates-meta.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * First-party template metadata used by the `agent-native` CLI.\n *\n * This file is intentionally inlined here (rather than imported from a\n * separate workspace package) so that the published `@agent-native/core`\n * has no `workspace:*` runtime dependencies. Without this inlining, `npx\n * @agent-native/core create ...` fails on a fresh machine with:\n *\n * npm error code EUNSUPPORTEDPROTOCOL\n * npm error Unsupported URL Type \"workspace:\": workspace:*\n *\n * Keep this list in sync with `packages/shared-app-config/templates.ts`,\n * which serves the same metadata to the desktop / mobile / frame packages\n * that always run inside the workspace. Duplication is intentional: the\n * CLI must remain installable outside the monorepo.\n */\n\nexport interface TemplateMeta {\n /** Directory name under templates/ and package name */\n name: string;\n /** Display name in pickers */\n label: string;\n /** One-line description shown in the picker */\n hint: string;\n /** Longer description (optional) */\n description?: string;\n /** Tabler icon name used in the desktop sidebar */\n icon: string;\n /** Hex accent color */\n color: string;\n /** CSS-safe RGB triplet (e.g. \"59 130 246\") */\n colorRgb: string;\n /** Dev server port for desktop `pnpm dev` */\n devPort: number;\n /** Production URL when running as a first-party app on agent-native.com */\n prodUrl?: string;\n /** Default URL path when deployed in a workspace (defaults to \"/<name>\") */\n prodPath?: string;\n /** Default mode when added to desktop app */\n defaultMode?: \"dev\" | \"prod\";\n /** Hide from pickers but still scaffoldable via explicit --template */\n hidden?: boolean;\n /** Include as a built-in connected A2A agent even when hidden from pickers */\n defaultAgent?: boolean;\n /** Always scaffold without prompting (e.g. starter as fallback) */\n alwaysAvailable?: boolean;\n /** Internal workspace packages this template depends on (e.g. \"scheduling\") */\n requiredPackages?: string[];\n /** Core app — featured in the CLI picker, homepage, and docs gallery */\n core?: boolean;\n}\n\nexport const TEMPLATES: TemplateMeta[] = [\n {\n name: \"calendar\",\n label: \"Calendar\",\n hint: \"Agent-native Google Calendar — manage events, sync, and public booking\",\n icon: \"CalendarDays\",\n color: \"#00B5FF\",\n colorRgb: \"0 181 255\",\n devPort: 8082,\n prodUrl: \"https://calendar.agent-native.com\",\n defaultMode: \"prod\",\n requiredPackages: [\"scheduling\"],\n core: true,\n },\n {\n name: \"content\",\n label: \"Content\",\n hint: \"Agent-native Notion/Google Docs — write and organize with agent assistance\",\n icon: \"FileText\",\n color: \"#10B981\",\n colorRgb: \"16 185 129\",\n devPort: 8083,\n prodUrl: \"https://content.agent-native.com\",\n defaultMode: \"prod\",\n core: true,\n },\n {\n name: \"slides\",\n label: \"Slides\",\n hint: \"Agent-native Google Slides — generate and edit React presentations\",\n icon: \"GalleryHorizontal\",\n color: \"#EC4899\",\n colorRgb: \"236 72 153\",\n devPort: 8086,\n prodUrl: \"https://slides.agent-native.com\",\n defaultMode: \"prod\",\n requiredPackages: [\"pinpoint\"],\n core: true,\n },\n {\n name: \"videos\",\n label: \"Video\",\n hint: \"Agent-native video editing with Remotion\",\n icon: \"Video\",\n color: \"#EF4444\",\n colorRgb: \"239 68 68\",\n devPort: 8087,\n prodUrl: \"https://videos.agent-native.com\",\n defaultMode: \"prod\",\n requiredPackages: [\"pinpoint\"],\n },\n {\n name: \"analytics\",\n label: \"Analytics\",\n hint: \"Agent-native Amplitude/Mixpanel — connect data sources, prompt for charts\",\n icon: \"BarChart2\",\n color: \"#F59E0B\",\n colorRgb: \"245 158 11\",\n devPort: 8088,\n prodUrl: \"https://analytics.agent-native.com\",\n defaultMode: \"prod\",\n core: true,\n },\n {\n name: \"mail\",\n label: \"Mail\",\n hint: \"Agent-native Superhuman — email client with keyboard shortcuts and AI triage\",\n icon: \"Mail\",\n color: \"#3B82F6\",\n colorRgb: \"59 130 246\",\n devPort: 8085,\n prodUrl: \"https://mail.agent-native.com\",\n defaultMode: \"prod\",\n core: true,\n },\n {\n name: \"dispatch\",\n label: \"Dispatch\",\n hint: \"Central Slack/Telegram router with jobs, memory, approvals, and A2A delegation\",\n icon: \"MessageCircle\",\n color: \"#14B8A6\",\n colorRgb: \"20 184 166\",\n devPort: 8092,\n prodUrl: \"https://dispatch.agent-native.com\",\n defaultMode: \"prod\",\n core: true,\n },\n {\n name: \"forms\",\n label: \"Forms\",\n hint: \"Agent-native form builder — create, edit, and manage forms\",\n icon: \"ClipboardList\",\n color: \"#06B6D4\",\n colorRgb: \"6 182 212\",\n devPort: 8084,\n prodUrl: \"https://forms.agent-native.com\",\n defaultMode: \"prod\",\n core: true,\n },\n {\n name: \"code\",\n label: \"Agent-Native Code\",\n hint: \"Hidden customizable Agent-Native Code UI for local coding sessions and slash commands\",\n icon: \"Code\",\n color: \"#71717A\",\n colorRgb: \"113 113 122\",\n devPort: 8103,\n defaultMode: \"dev\",\n hidden: true,\n },\n {\n name: \"migration\",\n label: \"Migration Goal Surface\",\n hint: \"Internal Agent-Native Code detail surface for /migrate assessment, approval, and verification\",\n icon: \"Route\",\n color: \"#0F766E\",\n colorRgb: \"15 118 110\",\n devPort: 8101,\n defaultMode: \"dev\",\n hidden: true,\n requiredPackages: [\"migrate\"],\n },\n {\n name: \"issues\",\n label: \"Issues\",\n hint: \"Agent-native Jira — project management and issue tracking\",\n icon: \"BrandJira\",\n color: \"#0EA5E9\",\n colorRgb: \"14 165 233\",\n devPort: 8091,\n prodUrl: \"https://issues.agent-native.com\",\n defaultMode: \"dev\",\n hidden: true,\n },\n {\n name: \"recruiting\",\n label: \"Recruiting\",\n hint: \"Agent-native Greenhouse — manage candidates and recruiting pipelines\",\n icon: \"Users\",\n color: \"#16A34A\",\n colorRgb: \"22 163 74\",\n devPort: 8090,\n prodUrl: \"https://recruiting.agent-native.com\",\n defaultMode: \"dev\",\n hidden: true,\n },\n {\n name: \"starter\",\n label: \"Starter\",\n hint: \"Minimal scaffold with the agent chat and core architecture wired up\",\n icon: \"Code\",\n color: \"#71717A\",\n colorRgb: \"113 113 122\",\n devPort: 8089,\n defaultMode: \"prod\",\n alwaysAvailable: true,\n core: true,\n hidden: true,\n },\n {\n name: \"clips\",\n label: \"Clips\",\n hint: \"Screen recording, meeting notes, and voice dictation — all with AI\",\n icon: \"ScreenShare\",\n color: \"#0EA5E9\",\n colorRgb: \"14 165 233\",\n devPort: 8094,\n prodUrl: \"https://clips.agent-native.com\",\n defaultMode: \"prod\",\n core: true,\n },\n {\n name: \"brain\",\n label: \"Brain\",\n hint: \"Cited company memory from Slack, meetings, transcripts, and decisions\",\n icon: \"Brain\",\n color: \"#8B5CF6\",\n colorRgb: \"139 92 246\",\n devPort: 8102,\n prodUrl: \"https://brain.agent-native.com\",\n defaultMode: \"prod\",\n defaultAgent: true,\n core: true,\n },\n {\n name: \"design\",\n label: \"Design\",\n hint: \"Agent-native design tool — create and edit visual designs with agent assistance\",\n icon: \"Brush\",\n color: \"#F472B6\",\n colorRgb: \"244 114 182\",\n devPort: 8099,\n prodUrl: \"https://design.agent-native.com\",\n defaultMode: \"prod\",\n requiredPackages: [\"pinpoint\"],\n core: true,\n },\n {\n name: \"images\",\n label: \"Images\",\n hint: \"Brand image libraries — generate on-brand heroes, diagrams, product shots, and slide art\",\n icon: \"Photo\",\n color: \"#0F766E\",\n colorRgb: \"15 118 110\",\n devPort: 8100,\n prodUrl: \"https://images.agent-native.com\",\n defaultMode: \"prod\",\n hidden: true,\n defaultAgent: true,\n },\n {\n name: \"calls\",\n label: \"Calls\",\n hint: \"Agent-native Gong — record, transcribe, and analyze sales calls\",\n icon: \"Phone\",\n color: \"#111111\",\n colorRgb: \"17 17 17\",\n devPort: 8095,\n prodUrl: \"https://calls.agent-native.com\",\n defaultMode: \"prod\",\n hidden: true,\n },\n {\n name: \"meeting-notes\",\n label: \"Meeting Notes\",\n hint: \"AI meeting notes — transcribe, enhance, and share meeting notes\",\n icon: \"Note\",\n color: \"#16A34A\",\n colorRgb: \"22 163 74\",\n devPort: 8096,\n prodUrl: \"https://meeting-notes.agent-native.com\",\n defaultMode: \"prod\",\n hidden: true,\n },\n {\n name: \"scheduling\",\n label: \"Scheduling\",\n hint: \"Full scheduling app — event types, team round-robin, routing forms, workflows\",\n icon: \"CalendarTime\",\n color: \"#0EA5E9\",\n colorRgb: \"14 165 233\",\n devPort: 8098,\n prodUrl: \"https://scheduling.agent-native.com\",\n defaultMode: \"prod\",\n requiredPackages: [\"scheduling\"],\n hidden: true,\n },\n {\n name: \"voice\",\n label: \"Voice\",\n hint: \"Voice dictation — speak to type anywhere with context-aware formatting\",\n icon: \"Microphone\",\n color: \"#0EA5E9\",\n colorRgb: \"14 165 233\",\n devPort: 8097,\n prodUrl: \"https://voice.agent-native.com\",\n defaultMode: \"prod\",\n hidden: true,\n },\n {\n name: \"workbench\",\n label: \"Workbench\",\n hint: \"Visual command center for AI-assisted work — review PRs, monitor agent runs, build mini-tools\",\n icon: \"LayoutDashboard\",\n color: \"#475569\",\n colorRgb: \"71 85 105\",\n devPort: 8104,\n prodUrl: \"https://workbench.agent-native.com\",\n defaultMode: \"prod\",\n hidden: true,\n },\n {\n name: \"macros\",\n label: \"Macros\",\n hint: \"Internal template — not shown in pickers\",\n icon: \"Code\",\n color: \"#71717A\",\n colorRgb: \"113 113 122\",\n devPort: 8093,\n prodUrl: \"https://macros.agent-native.com\",\n hidden: true,\n defaultMode: \"dev\",\n },\n];\n\n/** Return templates visible in user-facing pickers (excludes hidden). */\nexport function visibleTemplates(): TemplateMeta[] {\n return TEMPLATES.filter((t) => !t.hidden);\n}\n\n/** Return core templates — the featured set shown in CLI pickers by default. */\nexport function coreTemplates(): TemplateMeta[] {\n return TEMPLATES.filter((t) => t.core);\n}\n\n/** Lookup by name. Returns undefined for unknown names. */\nexport function getTemplate(name: string): TemplateMeta | undefined {\n // Tolerate the legacy \"video\" alias.\n if (name === \"video\") name = \"videos\";\n return TEMPLATES.find((t) => t.name === name);\n}\n\n/** Names of all templates (including hidden) for validation. */\nexport function allTemplateNames(): string[] {\n return TEMPLATES.map((t) => t.name);\n}\n"]}
@@ -5,6 +5,7 @@ export { ExtensionsListPage } from "./ExtensionsListPage.js";
5
5
  export { ExtensionViewerPage } from "./ExtensionViewerPage.js";
6
6
  export { EmbeddedExtension, type EmbeddedExtensionProps, } from "./EmbeddedExtension.js";
7
7
  export { ExtensionSlot, type ExtensionSlotProps } from "./ExtensionSlot.js";
8
+ export { deleteOrHideExtension, hideExtensionForCurrentUser, invalidateExtensionRemoval, type ExtensionDeleteResult, type ExtensionDeleteTarget, } from "./delete-extension.js";
8
9
  export { EXTENSION_SLUG_MAX_LENGTH, extensionIdFromPathname, extensionNameToSlug, extensionPath, isExtensionPathname, } from "../../extensions/path.js";
9
10
  export { AgentNativeExtensionFrame, AgentNativeExtensionSlot, type AgentNativeExtensionFrameProps, type AgentNativeExtensionPermissionList, type AgentNativeExtensionSlotProps, type AgentNativeExtensionStorageScopeList, } from "./AgentNativeExtensionFrame.js";
10
11
  export { AGENT_NATIVE_EXTENSION_MESSAGE_TYPES, buildAgentNativeExtensionHtml, createHttpAgentNativeExtensionStorage, createLocalStorageAgentNativeExtensionStorage, getAgentNativeExtensionManifest, isAgentNativeExtensionAllowedInSlot, normalizeAgentNativeExtensionSandbox, type AgentNativeExtensionDefinition, type AgentNativeExtensionManifest, type AgentNativeExtensionMessageType, type AgentNativeExtensionStorage, type AgentNativeExtensionStorageContext, type AgentNativeExtensionStorageOptions, type AgentNativeExtensionStorageRow, type AgentNativeExtensionStorageScope, type BuildAgentNativeExtensionHtmlOptions, type CreateHttpAgentNativeExtensionStorageOptions, } from "./portable-extension.js";
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/client/extensions/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,wBAAwB,EAAE,MAAM,+BAA+B,CAAC;AACzE,OAAO,EACL,eAAe,EACf,KAAK,oBAAoB,GAC1B,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EACL,eAAe,EACf,KAAK,oBAAoB,GAC1B,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAC7D,OAAO,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAC/D,OAAO,EACL,iBAAiB,EACjB,KAAK,sBAAsB,GAC5B,MAAM,wBAAwB,CAAC;AAChC,OAAO,EAAE,aAAa,EAAE,KAAK,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAC5E,OAAO,EACL,yBAAyB,EACzB,uBAAuB,EACvB,mBAAmB,EACnB,aAAa,EACb,mBAAmB,GACpB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EACL,yBAAyB,EACzB,wBAAwB,EACxB,KAAK,8BAA8B,EACnC,KAAK,kCAAkC,EACvC,KAAK,6BAA6B,EAClC,KAAK,oCAAoC,GAC1C,MAAM,gCAAgC,CAAC;AACxC,OAAO,EACL,oCAAoC,EACpC,6BAA6B,EAC7B,qCAAqC,EACrC,6CAA6C,EAC7C,+BAA+B,EAC/B,mCAAmC,EACnC,oCAAoC,EACpC,KAAK,8BAA8B,EACnC,KAAK,4BAA4B,EACjC,KAAK,+BAA+B,EACpC,KAAK,2BAA2B,EAChC,KAAK,kCAAkC,EACvC,KAAK,kCAAkC,EACvC,KAAK,8BAA8B,EACnC,KAAK,gCAAgC,EACrC,KAAK,oCAAoC,EACzC,KAAK,4CAA4C,GAClD,MAAM,yBAAyB,CAAC;AAQjC,OAAO,EAAE,wBAAwB,IAAI,mBAAmB,EAAE,MAAM,+BAA+B,CAAC;AAChG,OAAO,EACL,eAAe,IAAI,UAAU,EAC7B,KAAK,oBAAoB,IAAI,eAAe,GAC7C,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EACL,eAAe,IAAI,UAAU,EAC7B,KAAK,oBAAoB,IAAI,eAAe,GAC7C,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAE,kBAAkB,IAAI,aAAa,EAAE,MAAM,yBAAyB,CAAC;AAC9E,OAAO,EAAE,mBAAmB,IAAI,cAAc,EAAE,MAAM,0BAA0B,CAAC;AACjF,OAAO,EACL,iBAAiB,IAAI,YAAY,EACjC,KAAK,sBAAsB,IAAI,iBAAiB,GACjD,MAAM,wBAAwB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/client/extensions/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,wBAAwB,EAAE,MAAM,+BAA+B,CAAC;AACzE,OAAO,EACL,eAAe,EACf,KAAK,oBAAoB,GAC1B,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EACL,eAAe,EACf,KAAK,oBAAoB,GAC1B,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAC7D,OAAO,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAC/D,OAAO,EACL,iBAAiB,EACjB,KAAK,sBAAsB,GAC5B,MAAM,wBAAwB,CAAC;AAChC,OAAO,EAAE,aAAa,EAAE,KAAK,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAC5E,OAAO,EACL,qBAAqB,EACrB,2BAA2B,EAC3B,0BAA0B,EAC1B,KAAK,qBAAqB,EAC1B,KAAK,qBAAqB,GAC3B,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EACL,yBAAyB,EACzB,uBAAuB,EACvB,mBAAmB,EACnB,aAAa,EACb,mBAAmB,GACpB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EACL,yBAAyB,EACzB,wBAAwB,EACxB,KAAK,8BAA8B,EACnC,KAAK,kCAAkC,EACvC,KAAK,6BAA6B,EAClC,KAAK,oCAAoC,GAC1C,MAAM,gCAAgC,CAAC;AACxC,OAAO,EACL,oCAAoC,EACpC,6BAA6B,EAC7B,qCAAqC,EACrC,6CAA6C,EAC7C,+BAA+B,EAC/B,mCAAmC,EACnC,oCAAoC,EACpC,KAAK,8BAA8B,EACnC,KAAK,4BAA4B,EACjC,KAAK,+BAA+B,EACpC,KAAK,2BAA2B,EAChC,KAAK,kCAAkC,EACvC,KAAK,kCAAkC,EACvC,KAAK,8BAA8B,EACnC,KAAK,gCAAgC,EACrC,KAAK,oCAAoC,EACzC,KAAK,4CAA4C,GAClD,MAAM,yBAAyB,CAAC;AAQjC,OAAO,EAAE,wBAAwB,IAAI,mBAAmB,EAAE,MAAM,+BAA+B,CAAC;AAChG,OAAO,EACL,eAAe,IAAI,UAAU,EAC7B,KAAK,oBAAoB,IAAI,eAAe,GAC7C,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EACL,eAAe,IAAI,UAAU,EAC7B,KAAK,oBAAoB,IAAI,eAAe,GAC7C,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAE,kBAAkB,IAAI,aAAa,EAAE,MAAM,yBAAyB,CAAC;AAC9E,OAAO,EAAE,mBAAmB,IAAI,cAAc,EAAE,MAAM,0BAA0B,CAAC;AACjF,OAAO,EACL,iBAAiB,IAAI,YAAY,EACjC,KAAK,sBAAsB,IAAI,iBAAiB,GACjD,MAAM,wBAAwB,CAAC"}
@@ -5,6 +5,7 @@ export { ExtensionsListPage } from "./ExtensionsListPage.js";
5
5
  export { ExtensionViewerPage } from "./ExtensionViewerPage.js";
6
6
  export { EmbeddedExtension, } from "./EmbeddedExtension.js";
7
7
  export { ExtensionSlot } from "./ExtensionSlot.js";
8
+ export { deleteOrHideExtension, hideExtensionForCurrentUser, invalidateExtensionRemoval, } from "./delete-extension.js";
8
9
  export { EXTENSION_SLUG_MAX_LENGTH, extensionIdFromPathname, extensionNameToSlug, extensionPath, isExtensionPathname, } from "../../extensions/path.js";
9
10
  export { AgentNativeExtensionFrame, AgentNativeExtensionSlot, } from "./AgentNativeExtensionFrame.js";
10
11
  export { AGENT_NATIVE_EXTENSION_MESSAGE_TYPES, buildAgentNativeExtensionHtml, createHttpAgentNativeExtensionStorage, createLocalStorageAgentNativeExtensionStorage, getAgentNativeExtensionManifest, isAgentNativeExtensionAllowedInSlot, normalizeAgentNativeExtensionSandbox, } from "./portable-extension.js";
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/client/extensions/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,wBAAwB,EAAE,MAAM,+BAA+B,CAAC;AACzE,OAAO,EACL,eAAe,GAEhB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EACL,eAAe,GAEhB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAC7D,OAAO,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAC/D,OAAO,EACL,iBAAiB,GAElB,MAAM,wBAAwB,CAAC;AAChC,OAAO,EAAE,aAAa,EAA2B,MAAM,oBAAoB,CAAC;AAC5E,OAAO,EACL,yBAAyB,EACzB,uBAAuB,EACvB,mBAAmB,EACnB,aAAa,EACb,mBAAmB,GACpB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EACL,yBAAyB,EACzB,wBAAwB,GAKzB,MAAM,gCAAgC,CAAC;AACxC,OAAO,EACL,oCAAoC,EACpC,6BAA6B,EAC7B,qCAAqC,EACrC,6CAA6C,EAC7C,+BAA+B,EAC/B,mCAAmC,EACnC,oCAAoC,GAWrC,MAAM,yBAAyB,CAAC;AAEjC,gFAAgF;AAChF,2EAA2E;AAC3E,uEAAuE;AACvE,6DAA6D;AAC7D,gFAAgF;AAEhF,OAAO,EAAE,wBAAwB,IAAI,mBAAmB,EAAE,MAAM,+BAA+B,CAAC;AAChG,OAAO,EACL,eAAe,IAAI,UAAU,GAE9B,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EACL,eAAe,IAAI,UAAU,GAE9B,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAE,kBAAkB,IAAI,aAAa,EAAE,MAAM,yBAAyB,CAAC;AAC9E,OAAO,EAAE,mBAAmB,IAAI,cAAc,EAAE,MAAM,0BAA0B,CAAC;AACjF,OAAO,EACL,iBAAiB,IAAI,YAAY,GAElC,MAAM,wBAAwB,CAAC","sourcesContent":["export { ExtensionsSidebarSection } from \"./ExtensionsSidebarSection.js\";\nexport {\n ExtensionViewer,\n type ExtensionViewerProps,\n} from \"./ExtensionViewer.js\";\nexport {\n ExtensionEditor,\n type ExtensionEditorProps,\n} from \"./ExtensionEditor.js\";\nexport { ExtensionsListPage } from \"./ExtensionsListPage.js\";\nexport { ExtensionViewerPage } from \"./ExtensionViewerPage.js\";\nexport {\n EmbeddedExtension,\n type EmbeddedExtensionProps,\n} from \"./EmbeddedExtension.js\";\nexport { ExtensionSlot, type ExtensionSlotProps } from \"./ExtensionSlot.js\";\nexport {\n EXTENSION_SLUG_MAX_LENGTH,\n extensionIdFromPathname,\n extensionNameToSlug,\n extensionPath,\n isExtensionPathname,\n} from \"../../extensions/path.js\";\nexport {\n AgentNativeExtensionFrame,\n AgentNativeExtensionSlot,\n type AgentNativeExtensionFrameProps,\n type AgentNativeExtensionPermissionList,\n type AgentNativeExtensionSlotProps,\n type AgentNativeExtensionStorageScopeList,\n} from \"./AgentNativeExtensionFrame.js\";\nexport {\n AGENT_NATIVE_EXTENSION_MESSAGE_TYPES,\n buildAgentNativeExtensionHtml,\n createHttpAgentNativeExtensionStorage,\n createLocalStorageAgentNativeExtensionStorage,\n getAgentNativeExtensionManifest,\n isAgentNativeExtensionAllowedInSlot,\n normalizeAgentNativeExtensionSandbox,\n type AgentNativeExtensionDefinition,\n type AgentNativeExtensionManifest,\n type AgentNativeExtensionMessageType,\n type AgentNativeExtensionStorage,\n type AgentNativeExtensionStorageContext,\n type AgentNativeExtensionStorageOptions,\n type AgentNativeExtensionStorageRow,\n type AgentNativeExtensionStorageScope,\n type BuildAgentNativeExtensionHtmlOptions,\n type CreateHttpAgentNativeExtensionStorageOptions,\n} from \"./portable-extension.js\";\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Legacy aliases — these names predate the Tools → Extensions rename. Keep\n// exporting them so deployed templates that haven't been updated still\n// resolve. Use the canonical `Extension*` names in new code.\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport { ExtensionsSidebarSection as ToolsSidebarSection } from \"./ExtensionsSidebarSection.js\";\nexport {\n ExtensionViewer as ToolViewer,\n type ExtensionViewerProps as ToolViewerProps,\n} from \"./ExtensionViewer.js\";\nexport {\n ExtensionEditor as ToolEditor,\n type ExtensionEditorProps as ToolEditorProps,\n} from \"./ExtensionEditor.js\";\nexport { ExtensionsListPage as ToolsListPage } from \"./ExtensionsListPage.js\";\nexport { ExtensionViewerPage as ToolViewerPage } from \"./ExtensionViewerPage.js\";\nexport {\n EmbeddedExtension as EmbeddedTool,\n type EmbeddedExtensionProps as EmbeddedToolProps,\n} from \"./EmbeddedExtension.js\";\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/client/extensions/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,wBAAwB,EAAE,MAAM,+BAA+B,CAAC;AACzE,OAAO,EACL,eAAe,GAEhB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EACL,eAAe,GAEhB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAC7D,OAAO,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAC/D,OAAO,EACL,iBAAiB,GAElB,MAAM,wBAAwB,CAAC;AAChC,OAAO,EAAE,aAAa,EAA2B,MAAM,oBAAoB,CAAC;AAC5E,OAAO,EACL,qBAAqB,EACrB,2BAA2B,EAC3B,0BAA0B,GAG3B,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EACL,yBAAyB,EACzB,uBAAuB,EACvB,mBAAmB,EACnB,aAAa,EACb,mBAAmB,GACpB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EACL,yBAAyB,EACzB,wBAAwB,GAKzB,MAAM,gCAAgC,CAAC;AACxC,OAAO,EACL,oCAAoC,EACpC,6BAA6B,EAC7B,qCAAqC,EACrC,6CAA6C,EAC7C,+BAA+B,EAC/B,mCAAmC,EACnC,oCAAoC,GAWrC,MAAM,yBAAyB,CAAC;AAEjC,gFAAgF;AAChF,2EAA2E;AAC3E,uEAAuE;AACvE,6DAA6D;AAC7D,gFAAgF;AAEhF,OAAO,EAAE,wBAAwB,IAAI,mBAAmB,EAAE,MAAM,+BAA+B,CAAC;AAChG,OAAO,EACL,eAAe,IAAI,UAAU,GAE9B,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EACL,eAAe,IAAI,UAAU,GAE9B,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAE,kBAAkB,IAAI,aAAa,EAAE,MAAM,yBAAyB,CAAC;AAC9E,OAAO,EAAE,mBAAmB,IAAI,cAAc,EAAE,MAAM,0BAA0B,CAAC;AACjF,OAAO,EACL,iBAAiB,IAAI,YAAY,GAElC,MAAM,wBAAwB,CAAC","sourcesContent":["export { ExtensionsSidebarSection } from \"./ExtensionsSidebarSection.js\";\nexport {\n ExtensionViewer,\n type ExtensionViewerProps,\n} from \"./ExtensionViewer.js\";\nexport {\n ExtensionEditor,\n type ExtensionEditorProps,\n} from \"./ExtensionEditor.js\";\nexport { ExtensionsListPage } from \"./ExtensionsListPage.js\";\nexport { ExtensionViewerPage } from \"./ExtensionViewerPage.js\";\nexport {\n EmbeddedExtension,\n type EmbeddedExtensionProps,\n} from \"./EmbeddedExtension.js\";\nexport { ExtensionSlot, type ExtensionSlotProps } from \"./ExtensionSlot.js\";\nexport {\n deleteOrHideExtension,\n hideExtensionForCurrentUser,\n invalidateExtensionRemoval,\n type ExtensionDeleteResult,\n type ExtensionDeleteTarget,\n} from \"./delete-extension.js\";\nexport {\n EXTENSION_SLUG_MAX_LENGTH,\n extensionIdFromPathname,\n extensionNameToSlug,\n extensionPath,\n isExtensionPathname,\n} from \"../../extensions/path.js\";\nexport {\n AgentNativeExtensionFrame,\n AgentNativeExtensionSlot,\n type AgentNativeExtensionFrameProps,\n type AgentNativeExtensionPermissionList,\n type AgentNativeExtensionSlotProps,\n type AgentNativeExtensionStorageScopeList,\n} from \"./AgentNativeExtensionFrame.js\";\nexport {\n AGENT_NATIVE_EXTENSION_MESSAGE_TYPES,\n buildAgentNativeExtensionHtml,\n createHttpAgentNativeExtensionStorage,\n createLocalStorageAgentNativeExtensionStorage,\n getAgentNativeExtensionManifest,\n isAgentNativeExtensionAllowedInSlot,\n normalizeAgentNativeExtensionSandbox,\n type AgentNativeExtensionDefinition,\n type AgentNativeExtensionManifest,\n type AgentNativeExtensionMessageType,\n type AgentNativeExtensionStorage,\n type AgentNativeExtensionStorageContext,\n type AgentNativeExtensionStorageOptions,\n type AgentNativeExtensionStorageRow,\n type AgentNativeExtensionStorageScope,\n type BuildAgentNativeExtensionHtmlOptions,\n type CreateHttpAgentNativeExtensionStorageOptions,\n} from \"./portable-extension.js\";\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Legacy aliases — these names predate the Tools → Extensions rename. Keep\n// exporting them so deployed templates that haven't been updated still\n// resolve. Use the canonical `Extension*` names in new code.\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport { ExtensionsSidebarSection as ToolsSidebarSection } from \"./ExtensionsSidebarSection.js\";\nexport {\n ExtensionViewer as ToolViewer,\n type ExtensionViewerProps as ToolViewerProps,\n} from \"./ExtensionViewer.js\";\nexport {\n ExtensionEditor as ToolEditor,\n type ExtensionEditorProps as ToolEditorProps,\n} from \"./ExtensionEditor.js\";\nexport { ExtensionsListPage as ToolsListPage } from \"./ExtensionsListPage.js\";\nexport { ExtensionViewerPage as ToolViewerPage } from \"./ExtensionViewerPage.js\";\nexport {\n EmbeddedExtension as EmbeddedTool,\n type EmbeddedExtensionProps as EmbeddedToolProps,\n} from \"./EmbeddedExtension.js\";\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"use-chat-threads.d.ts","sourceRoot":"","sources":["../../src/client/use-chat-threads.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,iBAAiB;IAChC,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,eAAe,GAAG,IAAI,CAAC;CAC/B;AAED,MAAM,WAAW,cAAc;IAC7B,EAAE,EAAE,MAAM,CAAC;IACX,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,eAAe,GAAG,IAAI,CAAC;CAC/B;AAED,MAAM,WAAW,kBAAkB;IACjC,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,MAAM,CAAC;CACtB;AA2CD,wBAAgB,cAAc,CAC5B,MAAM,SAA+C,EACrD,UAAU,CAAC,EAAE,MAAM,EACnB,KAAK,CAAC,EAAE,eAAe,GAAG,IAAI;;;;iCA2Rb,MAAM,KAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;uBAwCV,MAAM;uBAK/B,MAAM;6BA1BA,MAAM,KAAG,OAAO,CAAC,IAAI,CAAC;2BA4I3B,MAAM,mBACC,kBAAkB,GAAG,IAAI,KACzC,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;yBApFnB,MAAM,QACJ;QACJ,UAAU,EAAE,MAAM,CAAC;QACnB,KAAK,EAAE,MAAM,CAAC;QACd,OAAO,EAAE,MAAM,CAAC;QAChB,YAAY,CAAC,EAAE,MAAM,CAAC;KACvB;8BAmDc,MAAM,WAAW,MAAM,KAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;2BA2HnD,MAAM,KAAG,OAAO,CAAC,iBAAiB,EAAE,CAAC;;sBA7N9C,MAAM;EA+Pd"}
1
+ {"version":3,"file":"use-chat-threads.d.ts","sourceRoot":"","sources":["../../src/client/use-chat-threads.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,iBAAiB;IAChC,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,eAAe,GAAG,IAAI,CAAC;CAC/B;AAED,MAAM,WAAW,cAAc;IAC7B,EAAE,EAAE,MAAM,CAAC;IACX,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,eAAe,GAAG,IAAI,CAAC;CAC/B;AAED,MAAM,WAAW,kBAAkB;IACjC,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,MAAM,CAAC;CACtB;AA2CD,wBAAgB,cAAc,CAC5B,MAAM,SAA+C,EACrD,UAAU,CAAC,EAAE,MAAM,EACnB,KAAK,CAAC,EAAE,eAAe,GAAG,IAAI;;;;iCAmSb,MAAM,KAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;uBAwCV,MAAM;uBAK/B,MAAM;6BA1BA,MAAM,KAAG,OAAO,CAAC,IAAI,CAAC;2BA4I3B,MAAM,mBACC,kBAAkB,GAAG,IAAI,KACzC,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;yBApFnB,MAAM,QACJ;QACJ,UAAU,EAAE,MAAM,CAAC;QACnB,KAAK,EAAE,MAAM,CAAC;QACd,OAAO,EAAE,MAAM,CAAC;QAChB,YAAY,CAAC,EAAE,MAAM,CAAC;KACvB;8BAmDc,MAAM,WAAW,MAAM,KAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;2BA2HnD,MAAM,KAAG,OAAO,CAAC,iBAAiB,EAAE,CAAC;;sBA7N9C,MAAM;EA+Pd"}
@@ -93,15 +93,25 @@ export function useChatThreads(apiUrl = agentNativePath("/_agent-native/agent-ch
93
93
  const persistedKeyRef = useRef(activeThreadKey);
94
94
  useEffect(() => {
95
95
  if (persistedKeyRef.current !== activeThreadKey) {
96
- persistedKeyRef.current = activeThreadKey;
97
96
  const currentId = activeThreadIdRef.current;
98
97
  if (currentId) {
99
98
  const currentThreadScope = readKnownThreadScope(currentId);
100
- if (currentThreadScope !== undefined &&
101
- threadCanStayVisibleInScope(currentThreadScope, scopeRef.current)) {
99
+ // Thread metadata not yet loaded from the server — we can't tell
100
+ // whether the visible chat is general (stays) or scoped-elsewhere
101
+ // (swaps). Defer until `threads` resolves and this effect re-runs;
102
+ // we intentionally do NOT update `persistedKeyRef` so the next
103
+ // render gets another shot. Without this guard, navigating into a
104
+ // resource before `GET /threads` resolves silently dropped the
105
+ // active general chat the user was just in.
106
+ if (currentThreadScope === undefined) {
107
+ return;
108
+ }
109
+ if (threadCanStayVisibleInScope(currentThreadScope, scopeRef.current)) {
110
+ persistedKeyRef.current = activeThreadKey;
102
111
  return;
103
112
  }
104
113
  }
114
+ persistedKeyRef.current = activeThreadKey;
105
115
  try {
106
116
  setActiveThreadId(localStorage.getItem(activeThreadKey));
107
117
  }
@@ -1 +1 @@
1
- {"version":3,"file":"use-chat-threads.js","sourceRoot":"","sources":["../../src/client/use-chat-threads.ts"],"names":[],"mappings":"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","sourcesContent":["import { useState, useEffect, useCallback, useRef, useMemo } from \"react\";\nimport { agentNativePath } from \"./api-path.js\";\n\nexport interface ChatThreadScope {\n type: string;\n id: string;\n label?: string;\n}\n\nexport interface ChatThreadSummary {\n id: string;\n title: string;\n preview: string;\n messageCount: number;\n createdAt: number;\n updatedAt: number;\n scope: ChatThreadScope | null;\n}\n\nexport interface ChatThreadData {\n id: string;\n ownerEmail: string;\n title: string;\n preview: string;\n threadData: string;\n messageCount: number;\n createdAt: number;\n updatedAt: number;\n scope: ChatThreadScope | null;\n}\n\nexport interface ChatThreadSnapshot {\n threadData: string;\n title: string;\n preview: string;\n messageCount: number;\n}\n\ninterface ForkSnapshotWithScope extends ChatThreadSnapshot {\n scope: ChatThreadScope | null;\n}\n\nconst ACTIVE_THREAD_KEY = \"agent-chat-active-thread\";\n\nfunction scopeKeySegment(scope?: ChatThreadScope | null): string {\n if (!scope) return \"\";\n return `:scope:${scope.type}:${scope.id}`;\n}\n\nfunction activeThreadStorageKey(\n storageKey?: string,\n scope?: ChatThreadScope | null,\n): string {\n const scopePart = scopeKeySegment(scope);\n return storageKey\n ? `${ACTIVE_THREAD_KEY}:${storageKey}${scopePart}`\n : `${ACTIVE_THREAD_KEY}${scopePart}`;\n}\n\nfunction activeThreadSeenStorageKey(activeThreadKey: string): string {\n return `${activeThreadKey}:seen`;\n}\n\nfunction scopesMatch(\n a?: ChatThreadScope | null,\n b?: ChatThreadScope | null,\n): boolean {\n if (!a || !b) return false;\n return a.type === b.type && a.id === b.id;\n}\n\nfunction threadCanStayVisibleInScope(\n threadScope: ChatThreadScope | null,\n currentScope?: ChatThreadScope | null,\n): boolean {\n if (!threadScope) return true;\n return scopesMatch(threadScope, currentScope);\n}\n\nexport function useChatThreads(\n apiUrl = agentNativePath(\"/_agent-native/agent-chat\"),\n storageKey?: string,\n scope?: ChatThreadScope | null,\n) {\n // Each (storageKey, scope) pair gets its own active-thread localStorage key\n // for chats that belong to a resource. General chats keep using the unscoped\n // key even while the user is looking at a resource, so clicking into a deck,\n // design, form, etc. doesn't make a global conversation vanish.\n const activeThreadKey = useMemo(() => {\n return activeThreadStorageKey(storageKey, scope);\n }, [storageKey, scope?.type, scope?.id]);\n // Companion key recording when the saved active thread was last live in\n // this client. A revived orphan tab (id in localStorage but not on the\n // server and not created this session) must keep its real last-seen time\n // so the 12h stale-tab cleanup can age it out — stamping it `Date.now()`\n // on every mount (the old behaviour) reset the clock forever, so\n // abandoned empty tabs never got pruned.\n const activeThreadSeenKey = useMemo(\n () => activeThreadSeenStorageKey(activeThreadKey),\n [activeThreadKey],\n );\n const [threads, setThreads] = useState<ChatThreadSummary[]>([]);\n const threadsRef = useRef<ChatThreadSummary[]>(threads);\n threadsRef.current = threads;\n\n // IDs we generated client-side this session — consumers use this to know\n // whether to skip the per-thread restore skeleton, and we use it to\n // protect the optimistic-only thread from being yanked out of local\n // state when the server's threads list (which never sees it) loads.\n const newlyCreatedRef = useRef<Set<string>>(new Set());\n const optimisticThreadScopesRef = useRef<Map<string, ChatThreadScope | null>>(\n new Map(),\n );\n\n // Latest scope as a ref so `createThread` (a useCallback that we don't\n // want to depend on scope identity) reads the current value at call\n // time. The scope a new chat inherits is the one in effect when the +\n // button is clicked, not when the hook first mounted.\n const scopeRef = useRef<ChatThreadScope | null | undefined>(scope);\n scopeRef.current = scope;\n\n const readKnownThreadScope = useCallback(\n (id: string): ChatThreadScope | null | undefined => {\n const thread = threadsRef.current.find((t) => t.id === id);\n if (thread) return thread.scope ?? null;\n if (optimisticThreadScopesRef.current.has(id)) {\n return optimisticThreadScopesRef.current.get(id) ?? null;\n }\n return undefined;\n },\n [],\n );\n\n // Restore the saved active thread synchronously on mount so the chat shell\n // can paint immediately. We do NOT synthesize a fresh UUID here when no\n // saved id exists — that flow was creating empty `chat_threads` rows on\n // every page load via the optimistic POST, even if the user never chatted.\n // (Steve's account had 127 threads; 112 had message_count=0 and zero\n // agent_runs — pure ghosts.) When localStorage is empty, the initial\n // useEffect picks the most-recent server thread, or synthesizes a brand\n // new id only when there are no server threads at all.\n const [activeThreadId, setActiveThreadId] = useState<string | null>(() => {\n if (typeof window === \"undefined\") return null;\n try {\n return localStorage.getItem(activeThreadKey);\n } catch {\n return null;\n }\n });\n const [isLoading, setIsLoading] = useState(true);\n const fetchedRef = useRef(false);\n const activeThreadIdRef = useRef(activeThreadId);\n activeThreadIdRef.current = activeThreadId;\n\n // Persist active thread ID — and rehydrate on scope flips. When the user\n // navigates from deck A to deck B, `activeThreadKey` changes; we re-read B's\n // scoped thread only if the currently visible chat is itself scoped to a\n // different resource. Unscoped chats are global and stay visible.\n const persistedKeyRef = useRef(activeThreadKey);\n useEffect(() => {\n if (persistedKeyRef.current !== activeThreadKey) {\n persistedKeyRef.current = activeThreadKey;\n const currentId = activeThreadIdRef.current;\n if (currentId) {\n const currentThreadScope = readKnownThreadScope(currentId);\n if (\n currentThreadScope !== undefined &&\n threadCanStayVisibleInScope(currentThreadScope, scopeRef.current)\n ) {\n return;\n }\n }\n try {\n setActiveThreadId(localStorage.getItem(activeThreadKey));\n } catch {\n setActiveThreadId(null);\n }\n return;\n }\n try {\n if (activeThreadId) {\n const threadScope = readKnownThreadScope(activeThreadId);\n if (threadScope === undefined) return;\n const targetKey = activeThreadStorageKey(storageKey, threadScope);\n localStorage.setItem(targetKey, activeThreadId);\n localStorage.setItem(\n activeThreadSeenStorageKey(targetKey),\n String(Date.now()),\n );\n } else {\n localStorage.removeItem(activeThreadKey);\n localStorage.removeItem(activeThreadSeenKey);\n }\n } catch {}\n }, [\n activeThreadId,\n activeThreadKey,\n activeThreadSeenKey,\n readKnownThreadScope,\n storageKey,\n threads,\n ]);\n\n const fetchThreads = useCallback(async () => {\n try {\n const res = await fetch(`${apiUrl}/threads`);\n if (!res.ok) return;\n const data = await res.json();\n setThreads((prev) => {\n const loaded = (data.threads ?? []) as ChatThreadSummary[];\n const loadedIds = new Set(loaded.map((t) => t.id));\n // Preserve any optimistic threads we've created this session that\n // haven't shown up in the server list yet — the server only learns\n // about a thread when the user actually sends a message and the\n // agent run's `persistSubmittedUserMessage` writes the row.\n const optimisticOnly = prev.filter(\n (t) => newlyCreatedRef.current.has(t.id) && !loadedIds.has(t.id),\n );\n // Reconcile each server thread against our local copy. If the local\n // copy has a newer updatedAt or higher messageCount, keep those\n // fields — the server probably hasn't observed the user's latest\n // send yet, and naively replacing makes the recent-chats list\n // visibly jump back to older timestamps right after a send.\n const merged = loaded.map((server) => {\n const local = prev.find((t) => t.id === server.id);\n if (!local) return server;\n const next = { ...server };\n if (local.updatedAt > server.updatedAt) {\n next.updatedAt = local.updatedAt;\n }\n if (local.messageCount > server.messageCount) {\n next.messageCount = local.messageCount;\n if (local.preview) next.preview = local.preview;\n if (local.title) next.title = local.title;\n }\n // Preserve optimistic scope: when the server creates the row\n // on first message it does so without scope, and the next PUT\n // (saveThreadData) writes the local scope back. In the brief\n // window between those, the server list returns scope: null\n // while the user is clearly working inside a deck — keep the\n // local value so the tab bar doesn't blink unscoped.\n if (local.scope && !server.scope) {\n next.scope = local.scope;\n }\n return next;\n });\n return [...optimisticOnly, ...merged];\n });\n return data.threads as ChatThreadSummary[];\n } catch {\n return undefined;\n }\n }, [apiUrl]);\n\n // Add a client-generated thread to the local list optimistically.\n //\n // Critically, this does NOT `POST /threads` to the server — that path was\n // creating an empty row in `chat_threads` (message_count=0, no\n // agent_runs) on every page mount and every \"+\" click. The server\n // already creates the row idempotently the moment the user actually\n // sends their first message (`persistSubmittedUserMessage` →\n // `createThread`), so the client doesn't need to pre-create it. This\n // makes the threads table reflect real conversations only.\n const addOptimisticThread = useCallback(\n (\n id: string,\n threadScope: ChatThreadScope | null,\n // When reviving a tab the user left open in a prior session, pass the\n // persisted last-seen time so the 12h stale-tab cleanup can still age\n // it out. Omit for genuinely new tabs (defaults to now).\n seedAt?: number,\n ) => {\n const stamp =\n typeof seedAt === \"number\" && Number.isFinite(seedAt)\n ? seedAt\n : Date.now();\n const optimistic: ChatThreadSummary = {\n id,\n title: \"\",\n preview: \"\",\n messageCount: 0,\n createdAt: stamp,\n updatedAt: stamp,\n scope: threadScope,\n };\n optimisticThreadScopesRef.current.set(id, threadScope);\n setThreads((prev) =>\n prev.some((t) => t.id === id) ? prev : [optimistic, ...prev],\n );\n },\n [],\n );\n\n // Initial load: load threads from server, then reconcile against the\n // saved active thread.\n //\n // - savedId in loadedThreads → keep it (user's last conversation).\n // - savedId in newlyCreatedRef (we just created it this session) → keep\n // it; the server hasn't seen it yet because there's no POST anymore,\n // the row gets written when the user sends a message.\n // - savedId is set but neither on the server nor newly created here →\n // it's an empty tab the user left open. A never-messaged tab is never\n // POSTed (that was the 127-ghost-threads problem), and the only record\n // that it's a deliberately-open tab — newlyCreatedRef — is wiped by the\n // reload. So on refresh we can't tell it apart from a stale ghost.\n // Keep it exactly as the user left it: re-register it as an optimistic\n // empty tab rather than resurrecting an unrelated old conversation. The\n // composer is fully functional with this id (the server writes the row\n // on first message, same as any new tab), so there's no 404 to avoid.\n // This is what makes \"the state you left is the state you see on\n // refresh\" hold — stale (>12h) tabs are still cleared downstream.\n // - No savedId → synthesize a fresh local id (no POST; server creates the\n // row on first message). The server may contain chats from another\n // branch, preview, or project that shares the same user/database, so\n // auto-opening the latest server thread here leaks unrelated context into\n // a fresh surface. Existing threads remain available in History.\n useEffect(() => {\n if (fetchedRef.current) return;\n fetchedRef.current = true;\n\n (async () => {\n setIsLoading(true);\n const loadedThreads = await fetchThreads();\n const savedId = activeThreadIdRef.current;\n\n if (\n savedId &&\n !newlyCreatedRef.current.has(savedId) &&\n !(loadedThreads ?? []).some((t) => t.id === savedId)\n ) {\n // The tab the user left open isn't a server thread and we didn't\n // create it this session (newlyCreatedRef was wiped by the\n // reload). Treat it as the empty tab it is — keep its id and\n // surface it as an optimistic thread so the tab bar restores it\n // verbatim instead of yanking in the most-recent old chat.\n newlyCreatedRef.current.add(savedId);\n // Seed from the persisted last-seen time (not now) so a tab the\n // user abandoned >12h ago is correctly recognized as stale and\n // pruned by the downstream cleanup instead of living forever.\n let seenAt: number | undefined;\n try {\n const raw = localStorage.getItem(activeThreadSeenKey);\n const parsed = raw ? Number.parseInt(raw, 10) : NaN;\n if (Number.isFinite(parsed)) seenAt = parsed;\n } catch {\n // localStorage unavailable — fall back to now (current behaviour).\n }\n addOptimisticThread(savedId, scopeRef.current ?? null, seenAt);\n // activeThreadId already === savedId from the localStorage\n // initializer; nothing else to set.\n } else if (!savedId) {\n if (typeof crypto !== \"undefined\" && crypto.randomUUID) {\n // Brand new surface — synthesize a local id so the composer has a\n // target. No POST: the server creates the row on first send.\n const id = crypto.randomUUID();\n newlyCreatedRef.current.add(id);\n addOptimisticThread(id, scopeRef.current ?? null);\n setActiveThreadId(id);\n }\n }\n setIsLoading(false);\n })();\n }, [fetchThreads, addOptimisticThread]);\n\n const createThread = useCallback(\n (preferredId?: string): Promise<string | null> => {\n // Generate ID client-side for instant UI response. No POST — the\n // server creates the row when the user actually sends a message,\n // which prevents accumulation of empty thread rows when the user\n // clicks \"+\" but never chats.\n const id = preferredId || crypto.randomUUID();\n newlyCreatedRef.current.add(id);\n addOptimisticThread(id, scopeRef.current ?? null);\n setActiveThreadId(id);\n return Promise.resolve(id);\n },\n [addOptimisticThread],\n );\n\n // Drop a thread's scope so it becomes a general (cross-resource) chat.\n // This is the \"Detach from <deck>\" escape hatch in the UI. The PUT\n // also bumps the thread's updatedAt so it surfaces in the All Chats\n // list right away.\n const detachThread = useCallback(\n async (threadId: string): Promise<void> => {\n try {\n await fetch(`${apiUrl}/threads/${encodeURIComponent(threadId)}`, {\n method: \"PUT\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({ scope: null }),\n });\n setThreads((prev) =>\n prev.map((t) => (t.id === threadId ? { ...t, scope: null } : t)),\n );\n optimisticThreadScopesRef.current.set(threadId, null);\n } catch {}\n },\n [apiUrl],\n );\n\n const isNewThread = useCallback(\n (id: string) => newlyCreatedRef.current.has(id),\n [],\n );\n\n const switchThread = useCallback((id: string) => {\n setActiveThreadId(id);\n }, []);\n\n const removeThread = useCallback(\n async (id: string) => {\n try {\n await fetch(`${apiUrl}/threads/${encodeURIComponent(id)}`, {\n method: \"DELETE\",\n });\n } catch {}\n optimisticThreadScopesRef.current.delete(id);\n setThreads((prev) => {\n const next = prev.filter((t) => t.id !== id);\n if (id === activeThreadId) {\n // Switch to the next available thread, or create new if empty\n if (next.length > 0) {\n setActiveThreadId(next[0].id);\n } else {\n // Create a new thread\n createThread();\n }\n }\n return next;\n });\n },\n [apiUrl, activeThreadId, createThread],\n );\n\n // Ref to look up the latest scope of a known thread inside\n // saveThreadData without making the callback re-create on every\n // setThreads. The thread's scope is owned by createThread /\n // detachThread / fetchThreads — saveThreadData just mirrors it on\n // every save so the server eventually catches up after\n // persistSubmittedUserMessage creates the row sans scope.\n const saveThreadData = useCallback(\n async (\n id: string,\n data: {\n threadData: string;\n title: string;\n preview: string;\n messageCount?: number;\n },\n ) => {\n try {\n const localScope =\n threadsRef.current.find((t) => t.id === id)?.scope ?? null;\n await fetch(`${apiUrl}/threads/${encodeURIComponent(id)}`, {\n method: \"PUT\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({ ...data, scope: localScope }),\n });\n // Update local thread list metadata. If the thread isn't in our\n // local list yet (an optimistic-only thread that the server just\n // created via persistSubmittedUserMessage), add it so HistoryPopover\n // can show it once it has messages.\n setThreads((prev) => {\n const exists = prev.some((t) => t.id === id);\n if (exists) {\n return prev.map((t) =>\n t.id === id\n ? {\n ...t,\n title: data.title,\n preview: data.preview,\n ...(data.messageCount != null && {\n messageCount: data.messageCount,\n }),\n updatedAt: Date.now(),\n }\n : t,\n );\n }\n const now = Date.now();\n return [\n {\n id,\n title: data.title,\n preview: data.preview,\n messageCount: data.messageCount ?? 0,\n createdAt: now,\n updatedAt: now,\n scope: scopeRef.current ?? null,\n },\n ...prev,\n ];\n });\n } catch {}\n },\n [apiUrl],\n );\n\n const generateTitle = useCallback(\n async (threadId: string, message: string): Promise<string | null> => {\n try {\n const res = await fetch(`${apiUrl}/generate-title`, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({ message }),\n });\n if (!res.ok) return null;\n const data = await res.json();\n const title = data.title;\n if (!title) return null;\n // Update the title in local state\n setThreads((prev) =>\n prev.map((t) => (t.id === threadId ? { ...t, title } : t)),\n );\n return title;\n } catch {\n return null;\n }\n },\n [apiUrl],\n );\n\n const forkThread = useCallback(\n async (\n sourceId: string,\n sourceSnapshot?: ChatThreadSnapshot | null,\n ): Promise<string | null> => {\n const id = crypto.randomUUID();\n const fallbackForkFromSnapshot = async (\n source: ForkSnapshotWithScope,\n ): Promise<ChatThreadSummary | null> => {\n const title = source.title ? `${source.title} (fork)` : \"\";\n const createdAt = Date.now();\n const createRes = await fetch(`${apiUrl}/threads`, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({\n id,\n title,\n ...(source.scope ? { scope: source.scope } : {}),\n }),\n });\n if (!createRes.ok) return null;\n\n const saveRes = await fetch(\n `${apiUrl}/threads/${encodeURIComponent(id)}`,\n {\n method: \"PUT\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({\n threadData: source.threadData,\n title,\n preview: source.preview,\n messageCount: source.messageCount,\n scope: source.scope,\n }),\n },\n );\n if (!saveRes.ok) return null;\n\n return {\n id,\n title,\n preview: source.preview,\n messageCount: source.messageCount,\n createdAt,\n updatedAt: Date.now(),\n scope: source.scope,\n };\n };\n\n try {\n const localScope =\n threadsRef.current.find((t) => t.id === sourceId)?.scope ?? null;\n const source =\n sourceSnapshot && sourceSnapshot.messageCount > 0\n ? { ...sourceSnapshot, scope: localScope }\n : undefined;\n const res = await fetch(\n `${apiUrl}/threads/${encodeURIComponent(sourceId)}/fork`,\n {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({ id, ...(source ? { source } : {}) }),\n },\n );\n let thread: ChatThreadSummary | null = null;\n if (!res.ok) {\n // Surface failures so a click on the Fork button isn't a silent\n // no-op when the source thread can't be found or auth has lapsed.\n console.error(\n `[chat] fork failed for ${sourceId}: ${res.status} ${res.statusText}`,\n );\n if (source && (res.status === 404 || res.status === 405)) {\n thread = await fallbackForkFromSnapshot(source);\n }\n if (!thread) return null;\n } else {\n thread = await res.json();\n }\n setThreads((prev) => [\n {\n id: thread.id,\n title: thread.title,\n preview: thread.preview,\n messageCount: thread.messageCount,\n createdAt: thread.createdAt,\n updatedAt: thread.updatedAt,\n scope: thread.scope ?? null,\n },\n ...prev,\n ]);\n return thread.id;\n } catch (err) {\n console.error(`[chat] fork threw for ${sourceId}:`, err);\n return null;\n }\n },\n [apiUrl],\n );\n\n const searchThreads = useCallback(\n async (query: string): Promise<ChatThreadSummary[]> => {\n try {\n const res = await fetch(\n `${apiUrl}/threads?q=${encodeURIComponent(query)}`,\n );\n if (!res.ok) return [];\n const data = await res.json();\n return data.threads ?? [];\n } catch {\n return [];\n }\n },\n [apiUrl],\n );\n\n const refreshThreads = useCallback(() => {\n fetchThreads();\n }, [fetchThreads]);\n\n return {\n threads,\n activeThreadId,\n isLoading,\n createThread,\n switchThread,\n deleteThread: removeThread,\n detachThread,\n forkThread,\n saveThreadData,\n generateTitle,\n searchThreads,\n refreshThreads,\n isNewThread,\n };\n}\n"]}
1
+ {"version":3,"file":"use-chat-threads.js","sourceRoot":"","sources":["../../src/client/use-chat-threads.ts"],"names":[],"mappings":"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","sourcesContent":["import { useState, useEffect, useCallback, useRef, useMemo } from \"react\";\nimport { agentNativePath } from \"./api-path.js\";\n\nexport interface ChatThreadScope {\n type: string;\n id: string;\n label?: string;\n}\n\nexport interface ChatThreadSummary {\n id: string;\n title: string;\n preview: string;\n messageCount: number;\n createdAt: number;\n updatedAt: number;\n scope: ChatThreadScope | null;\n}\n\nexport interface ChatThreadData {\n id: string;\n ownerEmail: string;\n title: string;\n preview: string;\n threadData: string;\n messageCount: number;\n createdAt: number;\n updatedAt: number;\n scope: ChatThreadScope | null;\n}\n\nexport interface ChatThreadSnapshot {\n threadData: string;\n title: string;\n preview: string;\n messageCount: number;\n}\n\ninterface ForkSnapshotWithScope extends ChatThreadSnapshot {\n scope: ChatThreadScope | null;\n}\n\nconst ACTIVE_THREAD_KEY = \"agent-chat-active-thread\";\n\nfunction scopeKeySegment(scope?: ChatThreadScope | null): string {\n if (!scope) return \"\";\n return `:scope:${scope.type}:${scope.id}`;\n}\n\nfunction activeThreadStorageKey(\n storageKey?: string,\n scope?: ChatThreadScope | null,\n): string {\n const scopePart = scopeKeySegment(scope);\n return storageKey\n ? `${ACTIVE_THREAD_KEY}:${storageKey}${scopePart}`\n : `${ACTIVE_THREAD_KEY}${scopePart}`;\n}\n\nfunction activeThreadSeenStorageKey(activeThreadKey: string): string {\n return `${activeThreadKey}:seen`;\n}\n\nfunction scopesMatch(\n a?: ChatThreadScope | null,\n b?: ChatThreadScope | null,\n): boolean {\n if (!a || !b) return false;\n return a.type === b.type && a.id === b.id;\n}\n\nfunction threadCanStayVisibleInScope(\n threadScope: ChatThreadScope | null,\n currentScope?: ChatThreadScope | null,\n): boolean {\n if (!threadScope) return true;\n return scopesMatch(threadScope, currentScope);\n}\n\nexport function useChatThreads(\n apiUrl = agentNativePath(\"/_agent-native/agent-chat\"),\n storageKey?: string,\n scope?: ChatThreadScope | null,\n) {\n // Each (storageKey, scope) pair gets its own active-thread localStorage key\n // for chats that belong to a resource. General chats keep using the unscoped\n // key even while the user is looking at a resource, so clicking into a deck,\n // design, form, etc. doesn't make a global conversation vanish.\n const activeThreadKey = useMemo(() => {\n return activeThreadStorageKey(storageKey, scope);\n }, [storageKey, scope?.type, scope?.id]);\n // Companion key recording when the saved active thread was last live in\n // this client. A revived orphan tab (id in localStorage but not on the\n // server and not created this session) must keep its real last-seen time\n // so the 12h stale-tab cleanup can age it out — stamping it `Date.now()`\n // on every mount (the old behaviour) reset the clock forever, so\n // abandoned empty tabs never got pruned.\n const activeThreadSeenKey = useMemo(\n () => activeThreadSeenStorageKey(activeThreadKey),\n [activeThreadKey],\n );\n const [threads, setThreads] = useState<ChatThreadSummary[]>([]);\n const threadsRef = useRef<ChatThreadSummary[]>(threads);\n threadsRef.current = threads;\n\n // IDs we generated client-side this session — consumers use this to know\n // whether to skip the per-thread restore skeleton, and we use it to\n // protect the optimistic-only thread from being yanked out of local\n // state when the server's threads list (which never sees it) loads.\n const newlyCreatedRef = useRef<Set<string>>(new Set());\n const optimisticThreadScopesRef = useRef<Map<string, ChatThreadScope | null>>(\n new Map(),\n );\n\n // Latest scope as a ref so `createThread` (a useCallback that we don't\n // want to depend on scope identity) reads the current value at call\n // time. The scope a new chat inherits is the one in effect when the +\n // button is clicked, not when the hook first mounted.\n const scopeRef = useRef<ChatThreadScope | null | undefined>(scope);\n scopeRef.current = scope;\n\n const readKnownThreadScope = useCallback(\n (id: string): ChatThreadScope | null | undefined => {\n const thread = threadsRef.current.find((t) => t.id === id);\n if (thread) return thread.scope ?? null;\n if (optimisticThreadScopesRef.current.has(id)) {\n return optimisticThreadScopesRef.current.get(id) ?? null;\n }\n return undefined;\n },\n [],\n );\n\n // Restore the saved active thread synchronously on mount so the chat shell\n // can paint immediately. We do NOT synthesize a fresh UUID here when no\n // saved id exists — that flow was creating empty `chat_threads` rows on\n // every page load via the optimistic POST, even if the user never chatted.\n // (Steve's account had 127 threads; 112 had message_count=0 and zero\n // agent_runs — pure ghosts.) When localStorage is empty, the initial\n // useEffect picks the most-recent server thread, or synthesizes a brand\n // new id only when there are no server threads at all.\n const [activeThreadId, setActiveThreadId] = useState<string | null>(() => {\n if (typeof window === \"undefined\") return null;\n try {\n return localStorage.getItem(activeThreadKey);\n } catch {\n return null;\n }\n });\n const [isLoading, setIsLoading] = useState(true);\n const fetchedRef = useRef(false);\n const activeThreadIdRef = useRef(activeThreadId);\n activeThreadIdRef.current = activeThreadId;\n\n // Persist active thread ID — and rehydrate on scope flips. When the user\n // navigates from deck A to deck B, `activeThreadKey` changes; we re-read B's\n // scoped thread only if the currently visible chat is itself scoped to a\n // different resource. Unscoped chats are global and stay visible.\n const persistedKeyRef = useRef(activeThreadKey);\n useEffect(() => {\n if (persistedKeyRef.current !== activeThreadKey) {\n const currentId = activeThreadIdRef.current;\n if (currentId) {\n const currentThreadScope = readKnownThreadScope(currentId);\n // Thread metadata not yet loaded from the server — we can't tell\n // whether the visible chat is general (stays) or scoped-elsewhere\n // (swaps). Defer until `threads` resolves and this effect re-runs;\n // we intentionally do NOT update `persistedKeyRef` so the next\n // render gets another shot. Without this guard, navigating into a\n // resource before `GET /threads` resolves silently dropped the\n // active general chat the user was just in.\n if (currentThreadScope === undefined) {\n return;\n }\n if (threadCanStayVisibleInScope(currentThreadScope, scopeRef.current)) {\n persistedKeyRef.current = activeThreadKey;\n return;\n }\n }\n persistedKeyRef.current = activeThreadKey;\n try {\n setActiveThreadId(localStorage.getItem(activeThreadKey));\n } catch {\n setActiveThreadId(null);\n }\n return;\n }\n try {\n if (activeThreadId) {\n const threadScope = readKnownThreadScope(activeThreadId);\n if (threadScope === undefined) return;\n const targetKey = activeThreadStorageKey(storageKey, threadScope);\n localStorage.setItem(targetKey, activeThreadId);\n localStorage.setItem(\n activeThreadSeenStorageKey(targetKey),\n String(Date.now()),\n );\n } else {\n localStorage.removeItem(activeThreadKey);\n localStorage.removeItem(activeThreadSeenKey);\n }\n } catch {}\n }, [\n activeThreadId,\n activeThreadKey,\n activeThreadSeenKey,\n readKnownThreadScope,\n storageKey,\n threads,\n ]);\n\n const fetchThreads = useCallback(async () => {\n try {\n const res = await fetch(`${apiUrl}/threads`);\n if (!res.ok) return;\n const data = await res.json();\n setThreads((prev) => {\n const loaded = (data.threads ?? []) as ChatThreadSummary[];\n const loadedIds = new Set(loaded.map((t) => t.id));\n // Preserve any optimistic threads we've created this session that\n // haven't shown up in the server list yet — the server only learns\n // about a thread when the user actually sends a message and the\n // agent run's `persistSubmittedUserMessage` writes the row.\n const optimisticOnly = prev.filter(\n (t) => newlyCreatedRef.current.has(t.id) && !loadedIds.has(t.id),\n );\n // Reconcile each server thread against our local copy. If the local\n // copy has a newer updatedAt or higher messageCount, keep those\n // fields — the server probably hasn't observed the user's latest\n // send yet, and naively replacing makes the recent-chats list\n // visibly jump back to older timestamps right after a send.\n const merged = loaded.map((server) => {\n const local = prev.find((t) => t.id === server.id);\n if (!local) return server;\n const next = { ...server };\n if (local.updatedAt > server.updatedAt) {\n next.updatedAt = local.updatedAt;\n }\n if (local.messageCount > server.messageCount) {\n next.messageCount = local.messageCount;\n if (local.preview) next.preview = local.preview;\n if (local.title) next.title = local.title;\n }\n // Preserve optimistic scope: when the server creates the row\n // on first message it does so without scope, and the next PUT\n // (saveThreadData) writes the local scope back. In the brief\n // window between those, the server list returns scope: null\n // while the user is clearly working inside a deck — keep the\n // local value so the tab bar doesn't blink unscoped.\n if (local.scope && !server.scope) {\n next.scope = local.scope;\n }\n return next;\n });\n return [...optimisticOnly, ...merged];\n });\n return data.threads as ChatThreadSummary[];\n } catch {\n return undefined;\n }\n }, [apiUrl]);\n\n // Add a client-generated thread to the local list optimistically.\n //\n // Critically, this does NOT `POST /threads` to the server — that path was\n // creating an empty row in `chat_threads` (message_count=0, no\n // agent_runs) on every page mount and every \"+\" click. The server\n // already creates the row idempotently the moment the user actually\n // sends their first message (`persistSubmittedUserMessage` →\n // `createThread`), so the client doesn't need to pre-create it. This\n // makes the threads table reflect real conversations only.\n const addOptimisticThread = useCallback(\n (\n id: string,\n threadScope: ChatThreadScope | null,\n // When reviving a tab the user left open in a prior session, pass the\n // persisted last-seen time so the 12h stale-tab cleanup can still age\n // it out. Omit for genuinely new tabs (defaults to now).\n seedAt?: number,\n ) => {\n const stamp =\n typeof seedAt === \"number\" && Number.isFinite(seedAt)\n ? seedAt\n : Date.now();\n const optimistic: ChatThreadSummary = {\n id,\n title: \"\",\n preview: \"\",\n messageCount: 0,\n createdAt: stamp,\n updatedAt: stamp,\n scope: threadScope,\n };\n optimisticThreadScopesRef.current.set(id, threadScope);\n setThreads((prev) =>\n prev.some((t) => t.id === id) ? prev : [optimistic, ...prev],\n );\n },\n [],\n );\n\n // Initial load: load threads from server, then reconcile against the\n // saved active thread.\n //\n // - savedId in loadedThreads → keep it (user's last conversation).\n // - savedId in newlyCreatedRef (we just created it this session) → keep\n // it; the server hasn't seen it yet because there's no POST anymore,\n // the row gets written when the user sends a message.\n // - savedId is set but neither on the server nor newly created here →\n // it's an empty tab the user left open. A never-messaged tab is never\n // POSTed (that was the 127-ghost-threads problem), and the only record\n // that it's a deliberately-open tab — newlyCreatedRef — is wiped by the\n // reload. So on refresh we can't tell it apart from a stale ghost.\n // Keep it exactly as the user left it: re-register it as an optimistic\n // empty tab rather than resurrecting an unrelated old conversation. The\n // composer is fully functional with this id (the server writes the row\n // on first message, same as any new tab), so there's no 404 to avoid.\n // This is what makes \"the state you left is the state you see on\n // refresh\" hold — stale (>12h) tabs are still cleared downstream.\n // - No savedId → synthesize a fresh local id (no POST; server creates the\n // row on first message). The server may contain chats from another\n // branch, preview, or project that shares the same user/database, so\n // auto-opening the latest server thread here leaks unrelated context into\n // a fresh surface. Existing threads remain available in History.\n useEffect(() => {\n if (fetchedRef.current) return;\n fetchedRef.current = true;\n\n (async () => {\n setIsLoading(true);\n const loadedThreads = await fetchThreads();\n const savedId = activeThreadIdRef.current;\n\n if (\n savedId &&\n !newlyCreatedRef.current.has(savedId) &&\n !(loadedThreads ?? []).some((t) => t.id === savedId)\n ) {\n // The tab the user left open isn't a server thread and we didn't\n // create it this session (newlyCreatedRef was wiped by the\n // reload). Treat it as the empty tab it is — keep its id and\n // surface it as an optimistic thread so the tab bar restores it\n // verbatim instead of yanking in the most-recent old chat.\n newlyCreatedRef.current.add(savedId);\n // Seed from the persisted last-seen time (not now) so a tab the\n // user abandoned >12h ago is correctly recognized as stale and\n // pruned by the downstream cleanup instead of living forever.\n let seenAt: number | undefined;\n try {\n const raw = localStorage.getItem(activeThreadSeenKey);\n const parsed = raw ? Number.parseInt(raw, 10) : NaN;\n if (Number.isFinite(parsed)) seenAt = parsed;\n } catch {\n // localStorage unavailable — fall back to now (current behaviour).\n }\n addOptimisticThread(savedId, scopeRef.current ?? null, seenAt);\n // activeThreadId already === savedId from the localStorage\n // initializer; nothing else to set.\n } else if (!savedId) {\n if (typeof crypto !== \"undefined\" && crypto.randomUUID) {\n // Brand new surface — synthesize a local id so the composer has a\n // target. No POST: the server creates the row on first send.\n const id = crypto.randomUUID();\n newlyCreatedRef.current.add(id);\n addOptimisticThread(id, scopeRef.current ?? null);\n setActiveThreadId(id);\n }\n }\n setIsLoading(false);\n })();\n }, [fetchThreads, addOptimisticThread]);\n\n const createThread = useCallback(\n (preferredId?: string): Promise<string | null> => {\n // Generate ID client-side for instant UI response. No POST — the\n // server creates the row when the user actually sends a message,\n // which prevents accumulation of empty thread rows when the user\n // clicks \"+\" but never chats.\n const id = preferredId || crypto.randomUUID();\n newlyCreatedRef.current.add(id);\n addOptimisticThread(id, scopeRef.current ?? null);\n setActiveThreadId(id);\n return Promise.resolve(id);\n },\n [addOptimisticThread],\n );\n\n // Drop a thread's scope so it becomes a general (cross-resource) chat.\n // This is the \"Detach from <deck>\" escape hatch in the UI. The PUT\n // also bumps the thread's updatedAt so it surfaces in the All Chats\n // list right away.\n const detachThread = useCallback(\n async (threadId: string): Promise<void> => {\n try {\n await fetch(`${apiUrl}/threads/${encodeURIComponent(threadId)}`, {\n method: \"PUT\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({ scope: null }),\n });\n setThreads((prev) =>\n prev.map((t) => (t.id === threadId ? { ...t, scope: null } : t)),\n );\n optimisticThreadScopesRef.current.set(threadId, null);\n } catch {}\n },\n [apiUrl],\n );\n\n const isNewThread = useCallback(\n (id: string) => newlyCreatedRef.current.has(id),\n [],\n );\n\n const switchThread = useCallback((id: string) => {\n setActiveThreadId(id);\n }, []);\n\n const removeThread = useCallback(\n async (id: string) => {\n try {\n await fetch(`${apiUrl}/threads/${encodeURIComponent(id)}`, {\n method: \"DELETE\",\n });\n } catch {}\n optimisticThreadScopesRef.current.delete(id);\n setThreads((prev) => {\n const next = prev.filter((t) => t.id !== id);\n if (id === activeThreadId) {\n // Switch to the next available thread, or create new if empty\n if (next.length > 0) {\n setActiveThreadId(next[0].id);\n } else {\n // Create a new thread\n createThread();\n }\n }\n return next;\n });\n },\n [apiUrl, activeThreadId, createThread],\n );\n\n // Ref to look up the latest scope of a known thread inside\n // saveThreadData without making the callback re-create on every\n // setThreads. The thread's scope is owned by createThread /\n // detachThread / fetchThreads — saveThreadData just mirrors it on\n // every save so the server eventually catches up after\n // persistSubmittedUserMessage creates the row sans scope.\n const saveThreadData = useCallback(\n async (\n id: string,\n data: {\n threadData: string;\n title: string;\n preview: string;\n messageCount?: number;\n },\n ) => {\n try {\n const localScope =\n threadsRef.current.find((t) => t.id === id)?.scope ?? null;\n await fetch(`${apiUrl}/threads/${encodeURIComponent(id)}`, {\n method: \"PUT\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({ ...data, scope: localScope }),\n });\n // Update local thread list metadata. If the thread isn't in our\n // local list yet (an optimistic-only thread that the server just\n // created via persistSubmittedUserMessage), add it so HistoryPopover\n // can show it once it has messages.\n setThreads((prev) => {\n const exists = prev.some((t) => t.id === id);\n if (exists) {\n return prev.map((t) =>\n t.id === id\n ? {\n ...t,\n title: data.title,\n preview: data.preview,\n ...(data.messageCount != null && {\n messageCount: data.messageCount,\n }),\n updatedAt: Date.now(),\n }\n : t,\n );\n }\n const now = Date.now();\n return [\n {\n id,\n title: data.title,\n preview: data.preview,\n messageCount: data.messageCount ?? 0,\n createdAt: now,\n updatedAt: now,\n scope: scopeRef.current ?? null,\n },\n ...prev,\n ];\n });\n } catch {}\n },\n [apiUrl],\n );\n\n const generateTitle = useCallback(\n async (threadId: string, message: string): Promise<string | null> => {\n try {\n const res = await fetch(`${apiUrl}/generate-title`, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({ message }),\n });\n if (!res.ok) return null;\n const data = await res.json();\n const title = data.title;\n if (!title) return null;\n // Update the title in local state\n setThreads((prev) =>\n prev.map((t) => (t.id === threadId ? { ...t, title } : t)),\n );\n return title;\n } catch {\n return null;\n }\n },\n [apiUrl],\n );\n\n const forkThread = useCallback(\n async (\n sourceId: string,\n sourceSnapshot?: ChatThreadSnapshot | null,\n ): Promise<string | null> => {\n const id = crypto.randomUUID();\n const fallbackForkFromSnapshot = async (\n source: ForkSnapshotWithScope,\n ): Promise<ChatThreadSummary | null> => {\n const title = source.title ? `${source.title} (fork)` : \"\";\n const createdAt = Date.now();\n const createRes = await fetch(`${apiUrl}/threads`, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({\n id,\n title,\n ...(source.scope ? { scope: source.scope } : {}),\n }),\n });\n if (!createRes.ok) return null;\n\n const saveRes = await fetch(\n `${apiUrl}/threads/${encodeURIComponent(id)}`,\n {\n method: \"PUT\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({\n threadData: source.threadData,\n title,\n preview: source.preview,\n messageCount: source.messageCount,\n scope: source.scope,\n }),\n },\n );\n if (!saveRes.ok) return null;\n\n return {\n id,\n title,\n preview: source.preview,\n messageCount: source.messageCount,\n createdAt,\n updatedAt: Date.now(),\n scope: source.scope,\n };\n };\n\n try {\n const localScope =\n threadsRef.current.find((t) => t.id === sourceId)?.scope ?? null;\n const source =\n sourceSnapshot && sourceSnapshot.messageCount > 0\n ? { ...sourceSnapshot, scope: localScope }\n : undefined;\n const res = await fetch(\n `${apiUrl}/threads/${encodeURIComponent(sourceId)}/fork`,\n {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({ id, ...(source ? { source } : {}) }),\n },\n );\n let thread: ChatThreadSummary | null = null;\n if (!res.ok) {\n // Surface failures so a click on the Fork button isn't a silent\n // no-op when the source thread can't be found or auth has lapsed.\n console.error(\n `[chat] fork failed for ${sourceId}: ${res.status} ${res.statusText}`,\n );\n if (source && (res.status === 404 || res.status === 405)) {\n thread = await fallbackForkFromSnapshot(source);\n }\n if (!thread) return null;\n } else {\n thread = await res.json();\n }\n setThreads((prev) => [\n {\n id: thread.id,\n title: thread.title,\n preview: thread.preview,\n messageCount: thread.messageCount,\n createdAt: thread.createdAt,\n updatedAt: thread.updatedAt,\n scope: thread.scope ?? null,\n },\n ...prev,\n ]);\n return thread.id;\n } catch (err) {\n console.error(`[chat] fork threw for ${sourceId}:`, err);\n return null;\n }\n },\n [apiUrl],\n );\n\n const searchThreads = useCallback(\n async (query: string): Promise<ChatThreadSummary[]> => {\n try {\n const res = await fetch(\n `${apiUrl}/threads?q=${encodeURIComponent(query)}`,\n );\n if (!res.ok) return [];\n const data = await res.json();\n return data.threads ?? [];\n } catch {\n return [];\n }\n },\n [apiUrl],\n );\n\n const refreshThreads = useCallback(() => {\n fetchThreads();\n }, [fetchThreads]);\n\n return {\n threads,\n activeThreadId,\n isLoading,\n createThread,\n switchThread,\n deleteThread: removeThread,\n detachThread,\n forkThread,\n saveThreadData,\n generateTitle,\n searchThreads,\n refreshThreads,\n isNewThread,\n };\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"build-server.d.ts","sourceRoot":"","sources":["../../src/mcp/build-server.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"build-server.d.ts","sourceRoot":"","sources":["../../src/mcp/build-server.ts"],"names":[],"mappings":"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"}
@@ -181,6 +181,25 @@ function isEmbedStartUrl(value) {
181
181
  return value.includes("/_agent-native/embed/start");
182
182
  }
183
183
  }
184
+ function routePathFromOpenUrl(value) {
185
+ try {
186
+ const hasScheme = /^[a-z][a-z0-9+.-]*:\/\//i.test(value);
187
+ const url = hasScheme
188
+ ? new URL(value)
189
+ : new URL(value, "http://agent-native.invalid");
190
+ const route = `${url.pathname}${url.search}${url.hash}`;
191
+ if (!route.startsWith("/") || route.startsWith("//"))
192
+ return null;
193
+ if (route.startsWith("/\\"))
194
+ return null;
195
+ if (/^\/[a-z][a-z0-9+.-]*:/i.test(route))
196
+ return null;
197
+ return route;
198
+ }
199
+ catch {
200
+ return null;
201
+ }
202
+ }
184
203
  /**
185
204
  * Recursively redact embed-ticket-bearing URLs from any value before it gets
186
205
  * serialized into a model-visible text payload. Embed start URLs carry a
@@ -261,12 +280,10 @@ function mcpAppEmbedOpenLinkMeta(result, resource, meta) {
261
280
  const safeOpenUrl = explicitOpenUrl
262
281
  ? toAbsoluteOpenUrl(explicitOpenUrl, meta?.origin)
263
282
  : null;
264
- // Build a desktop deep-link (`agentnative://open?app=…&view=…`) so the
265
- // desktop app's URL-scheme handler routes the click instead of opening
266
- // the bare web URL in a system browser. The embed=true path's
267
- // `entry.link()` returns null (per `openAppTool`), so without this the
268
- // safe fallback was webUrl twice — the same bug embed=false avoids by
269
- // running through `buildLinkArtifacts` + `toDesktopOpenUrl`.
283
+ // Embed open links expose the safe browser target in `webUrl`, but the
284
+ // desktop URL must enter the app through the registered scheme so Electron
285
+ // can focus the right webview. Preserve the full route/query in the `to`
286
+ // param; focus ids are often only present on `url`, not `out.params`.
270
287
  const desktopDeepLinkUrl = (() => {
271
288
  if (!safeOpenUrl)
272
289
  return null;
@@ -275,20 +292,22 @@ function mcpAppEmbedOpenLinkMeta(result, resource, meta) {
275
292
  : undefined;
276
293
  if (!app)
277
294
  return safeOpenUrl;
295
+ if (isAgentNativeOpenDeepLink(safeOpenUrl)) {
296
+ return toDesktopOpenUrl(safeOpenUrl);
297
+ }
298
+ const targetRoute = routePathFromOpenUrl(safeOpenUrl);
299
+ if (!targetRoute)
300
+ return safeOpenUrl;
278
301
  const viewParam = typeof out.view === "string" && out.view.trim() ? out.view.trim() : "";
279
- const toParam = typeof out.path === "string" && out.path.trim()
280
- ? out.path.trim()
281
- : undefined;
282
302
  const params = out.params && typeof out.params === "object" && !Array.isArray(out.params)
283
303
  ? out.params
284
304
  : undefined;
285
- const deepLinkPath = buildDeepLink({
305
+ return toDesktopOpenUrl(buildDeepLink({
286
306
  app,
287
307
  view: viewParam,
288
- ...(toParam ? { to: toParam } : {}),
308
+ to: targetRoute,
289
309
  ...(params ? { params } : {}),
290
- });
291
- return toDesktopOpenUrl(deepLinkPath);
310
+ }));
292
311
  })();
293
312
  return {
294
313
  "agent-native/embedStart": {
@@ -875,9 +894,19 @@ export async function createMCPServerForRequest(config, identity, requestMeta) {
875
894
  : {}),
876
895
  ...(mcpAppResource ? openAiToolResultMeta(mcpAppResource) : {}),
877
896
  };
897
+ const toolUiMeta = metadataObject(entry.tool._meta?.ui);
898
+ const toolVisibility = toolUiMeta.visibility;
899
+ const isAppOnlyVisibility = Array.isArray(toolVisibility) &&
900
+ toolVisibility.length > 0 &&
901
+ toolVisibility.every((v) => v === "app");
878
902
  const structuredContent = mcpAppResource
879
903
  ? mcpAppStructuredContent(rawResult, responseMeta)
880
- : undefined;
904
+ : isAppOnlyVisibility &&
905
+ rawResult &&
906
+ typeof rawResult === "object" &&
907
+ !Array.isArray(rawResult)
908
+ ? rawResult
909
+ : undefined;
881
910
  const text = mcpAppResource
882
911
  ? conciseMcpAppToolText(name, resultForClient, structuredContent)
883
912
  : typeof resultForClient === "string"