@agent-native/core 0.39.1 → 0.40.0
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/README.md +1 -1
- package/dist/action.js +12 -0
- package/dist/action.js.map +1 -1
- package/dist/cli/create.d.ts.map +1 -1
- package/dist/cli/create.js +5 -1
- package/dist/cli/create.js.map +1 -1
- package/dist/cli/index.js +1 -1
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/skills.d.ts +6 -6
- package/dist/cli/skills.d.ts.map +1 -1
- package/dist/cli/skills.js +936 -1167
- package/dist/cli/skills.js.map +1 -1
- package/dist/client/MultiTabAssistantChat.d.ts.map +1 -1
- package/dist/client/MultiTabAssistantChat.js +2 -5
- package/dist/client/MultiTabAssistantChat.js.map +1 -1
- package/dist/client/NewWorkspaceAppFlow.js +1 -1
- package/dist/client/NewWorkspaceAppFlow.js.map +1 -1
- package/dist/client/blocks/AiEditableField.d.ts +8 -0
- package/dist/client/blocks/AiEditableField.d.ts.map +1 -0
- package/dist/client/blocks/AiEditableField.js +10 -0
- package/dist/client/blocks/AiEditableField.js.map +1 -0
- package/dist/client/blocks/BlockView.d.ts +3 -3
- package/dist/client/blocks/BlockView.d.ts.map +1 -1
- package/dist/client/blocks/BlockView.js +15 -3
- package/dist/client/blocks/BlockView.js.map +1 -1
- package/dist/client/blocks/SchemaBlockEditor.js +2 -2
- package/dist/client/blocks/SchemaBlockEditor.js.map +1 -1
- package/dist/client/blocks/index.d.ts +5 -2
- package/dist/client/blocks/index.d.ts.map +1 -1
- package/dist/client/blocks/index.js +6 -3
- package/dist/client/blocks/index.js.map +1 -1
- package/dist/client/blocks/library/ApiEndpointBlock.d.ts.map +1 -1
- package/dist/client/blocks/library/ApiEndpointBlock.js +20 -6
- package/dist/client/blocks/library/ApiEndpointBlock.js.map +1 -1
- package/dist/client/blocks/library/DiffBlock.d.ts +29 -0
- package/dist/client/blocks/library/DiffBlock.d.ts.map +1 -1
- package/dist/client/blocks/library/DiffBlock.js +190 -30
- package/dist/client/blocks/library/DiffBlock.js.map +1 -1
- package/dist/client/blocks/library/FileTreeBlock.d.ts.map +1 -1
- package/dist/client/blocks/library/FileTreeBlock.js +46 -7
- package/dist/client/blocks/library/FileTreeBlock.js.map +1 -1
- package/dist/client/blocks/library/HighlightedCode.d.ts +10 -0
- package/dist/client/blocks/library/HighlightedCode.d.ts.map +1 -0
- package/dist/client/blocks/library/HighlightedCode.js +92 -0
- package/dist/client/blocks/library/HighlightedCode.js.map +1 -0
- package/dist/client/blocks/library/JsonExplorerBlock.d.ts +9 -4
- package/dist/client/blocks/library/JsonExplorerBlock.d.ts.map +1 -1
- package/dist/client/blocks/library/JsonExplorerBlock.js +66 -30
- package/dist/client/blocks/library/JsonExplorerBlock.js.map +1 -1
- package/dist/client/blocks/library/MermaidBlock.d.ts.map +1 -1
- package/dist/client/blocks/library/MermaidBlock.js +73 -44
- package/dist/client/blocks/library/MermaidBlock.js.map +1 -1
- package/dist/client/blocks/library/OpenApiSpecBlock.d.ts.map +1 -1
- package/dist/client/blocks/library/OpenApiSpecBlock.js +3 -2
- package/dist/client/blocks/library/OpenApiSpecBlock.js.map +1 -1
- package/dist/client/blocks/library/checklist.d.ts.map +1 -1
- package/dist/client/blocks/library/checklist.js +1 -0
- package/dist/client/blocks/library/checklist.js.map +1 -1
- package/dist/client/blocks/library/code-tabs.d.ts.map +1 -1
- package/dist/client/blocks/library/code-tabs.js +183 -102
- package/dist/client/blocks/library/code-tabs.js.map +1 -1
- package/dist/client/blocks/library/columns.config.d.ts +60 -0
- package/dist/client/blocks/library/columns.config.d.ts.map +1 -0
- package/dist/client/blocks/library/columns.config.js +37 -0
- package/dist/client/blocks/library/columns.config.js.map +1 -0
- package/dist/client/blocks/library/columns.d.ts +25 -0
- package/dist/client/blocks/library/columns.d.ts.map +1 -0
- package/dist/client/blocks/library/columns.js +199 -0
- package/dist/client/blocks/library/columns.js.map +1 -0
- package/dist/client/blocks/library/dev-doc-ui.d.ts +2 -1
- package/dist/client/blocks/library/dev-doc-ui.d.ts.map +1 -1
- package/dist/client/blocks/library/dev-doc-ui.js +2 -1
- package/dist/client/blocks/library/dev-doc-ui.js.map +1 -1
- package/dist/client/blocks/library/html.d.ts +1 -1
- package/dist/client/blocks/library/html.d.ts.map +1 -1
- package/dist/client/blocks/library/html.js +34 -4
- package/dist/client/blocks/library/html.js.map +1 -1
- package/dist/client/blocks/library/json-explorer.config.d.ts +3 -1
- package/dist/client/blocks/library/json-explorer.config.d.ts.map +1 -1
- package/dist/client/blocks/library/json-explorer.config.js +30 -1
- package/dist/client/blocks/library/json-explorer.config.js.map +1 -1
- package/dist/client/blocks/library/server-specs.d.ts.map +1 -1
- package/dist/client/blocks/library/server-specs.js +13 -3
- package/dist/client/blocks/library/server-specs.js.map +1 -1
- package/dist/client/blocks/library/specs.d.ts +4 -4
- package/dist/client/blocks/library/specs.d.ts.map +1 -1
- package/dist/client/blocks/library/specs.js +21 -16
- package/dist/client/blocks/library/specs.js.map +1 -1
- package/dist/client/blocks/library/table.config.d.ts +3 -0
- package/dist/client/blocks/library/table.config.d.ts.map +1 -1
- package/dist/client/blocks/library/table.config.js +13 -1
- package/dist/client/blocks/library/table.config.js.map +1 -1
- package/dist/client/blocks/library/table.d.ts.map +1 -1
- package/dist/client/blocks/library/table.js +90 -9
- package/dist/client/blocks/library/table.js.map +1 -1
- package/dist/client/blocks/library/tabs.config.d.ts +16 -8
- package/dist/client/blocks/library/tabs.config.d.ts.map +1 -1
- package/dist/client/blocks/library/tabs.config.js +10 -4
- package/dist/client/blocks/library/tabs.config.js.map +1 -1
- package/dist/client/blocks/library/tabs.d.ts.map +1 -1
- package/dist/client/blocks/library/tabs.js +146 -21
- package/dist/client/blocks/library/tabs.js.map +1 -1
- package/dist/client/blocks/server.d.ts +2 -1
- package/dist/client/blocks/server.d.ts.map +1 -1
- package/dist/client/blocks/server.js +1 -0
- package/dist/client/blocks/server.js.map +1 -1
- package/dist/client/blocks/types.d.ts +99 -9
- package/dist/client/blocks/types.d.ts.map +1 -1
- package/dist/client/blocks/types.js.map +1 -1
- package/dist/client/index.d.ts +1 -1
- package/dist/client/index.d.ts.map +1 -1
- package/dist/client/index.js +2 -2
- package/dist/client/index.js.map +1 -1
- package/dist/client/rich-markdown-editor/BubbleToolbar.d.ts.map +1 -1
- package/dist/client/rich-markdown-editor/BubbleToolbar.js +13 -3
- package/dist/client/rich-markdown-editor/BubbleToolbar.js.map +1 -1
- package/dist/client/rich-markdown-editor/DragHandle.d.ts +49 -4
- package/dist/client/rich-markdown-editor/DragHandle.d.ts.map +1 -1
- package/dist/client/rich-markdown-editor/DragHandle.js +656 -88
- package/dist/client/rich-markdown-editor/DragHandle.js.map +1 -1
- package/dist/client/rich-markdown-editor/RegistryBlockNode.d.ts +10 -1
- package/dist/client/rich-markdown-editor/RegistryBlockNode.d.ts.map +1 -1
- package/dist/client/rich-markdown-editor/RegistryBlockNode.js +180 -15
- package/dist/client/rich-markdown-editor/RegistryBlockNode.js.map +1 -1
- package/dist/client/rich-markdown-editor/SharedRichEditor.d.ts +2 -1
- package/dist/client/rich-markdown-editor/SharedRichEditor.d.ts.map +1 -1
- package/dist/client/rich-markdown-editor/SharedRichEditor.js +3 -1
- package/dist/client/rich-markdown-editor/SharedRichEditor.js.map +1 -1
- package/dist/client/rich-markdown-editor/SlashCommandMenu.d.ts +5 -0
- package/dist/client/rich-markdown-editor/SlashCommandMenu.d.ts.map +1 -1
- package/dist/client/rich-markdown-editor/SlashCommandMenu.js +33 -5
- package/dist/client/rich-markdown-editor/SlashCommandMenu.js.map +1 -1
- package/dist/client/rich-markdown-editor/index.d.ts +3 -3
- package/dist/client/rich-markdown-editor/index.d.ts.map +1 -1
- package/dist/client/rich-markdown-editor/index.js +2 -2
- package/dist/client/rich-markdown-editor/index.js.map +1 -1
- package/dist/client/rich-markdown-editor/registrySlashCommands.d.ts +14 -0
- package/dist/client/rich-markdown-editor/registrySlashCommands.d.ts.map +1 -1
- package/dist/client/rich-markdown-editor/registrySlashCommands.js +38 -0
- package/dist/client/rich-markdown-editor/registrySlashCommands.js.map +1 -1
- package/dist/client/rich-markdown-editor/useCollabReconcile.d.ts +1 -0
- package/dist/client/rich-markdown-editor/useCollabReconcile.d.ts.map +1 -1
- package/dist/client/rich-markdown-editor/useCollabReconcile.js +4 -0
- package/dist/client/rich-markdown-editor/useCollabReconcile.js.map +1 -1
- package/dist/client/settings/SettingsPanel.d.ts.map +1 -1
- package/dist/client/settings/SettingsPanel.js +11 -19
- package/dist/client/settings/SettingsPanel.js.map +1 -1
- package/dist/client/use-chat-models.d.ts.map +1 -1
- package/dist/client/use-chat-models.js +2 -5
- package/dist/client/use-chat-models.js.map +1 -1
- package/dist/db/client.d.ts.map +1 -1
- package/dist/db/client.js +17 -1
- package/dist/db/client.js.map +1 -1
- package/dist/deploy/build.d.ts.map +1 -1
- package/dist/deploy/build.js +2 -1
- package/dist/deploy/build.js.map +1 -1
- package/dist/deploy/route-discovery.d.ts +29 -0
- package/dist/deploy/route-discovery.d.ts.map +1 -1
- package/dist/deploy/route-discovery.js +158 -11
- package/dist/deploy/route-discovery.js.map +1 -1
- package/dist/server/auth.d.ts +2 -0
- package/dist/server/auth.d.ts.map +1 -1
- package/dist/server/auth.js +9 -0
- package/dist/server/auth.js.map +1 -1
- package/dist/sharing/access.d.ts +4 -2
- package/dist/sharing/access.d.ts.map +1 -1
- package/dist/sharing/access.js +8 -3
- package/dist/sharing/access.js.map +1 -1
- package/dist/sharing/actions/set-resource-visibility.d.ts.map +1 -1
- package/dist/sharing/actions/set-resource-visibility.js +2 -3
- package/dist/sharing/actions/set-resource-visibility.js.map +1 -1
- package/dist/sharing/registry.d.ts +13 -0
- package/dist/sharing/registry.d.ts.map +1 -1
- package/dist/sharing/registry.js.map +1 -1
- package/dist/styles/rich-markdown-editor.css +15 -0
- package/dist/templates/default/.agents/skills/actions/SKILL.md +96 -11
- package/dist/templates/default/.agents/skills/adding-a-feature/SKILL.md +126 -26
- package/dist/templates/default/.agents/skills/capture-learnings/SKILL.md +56 -30
- package/dist/templates/default/.agents/skills/create-skill/SKILL.md +28 -0
- package/dist/templates/default/.agents/skills/delegate-to-agent/SKILL.md +75 -5
- package/dist/templates/default/.agents/skills/frontend-design/SKILL.md +17 -0
- package/dist/templates/default/.agents/skills/real-time-collab/SKILL.md +99 -124
- package/dist/templates/default/.agents/skills/real-time-sync/SKILL.md +43 -10
- package/dist/templates/default/.agents/skills/security/SKILL.md +162 -144
- package/dist/templates/default/.agents/skills/self-modifying-code/SKILL.md +5 -3
- package/dist/templates/default/.agents/skills/shadcn-ui/SKILL.md +15 -0
- package/dist/templates/default/.agents/skills/storing-data/SKILL.md +116 -83
- package/dist/templates/default/DEVELOPING.md +10 -13
- package/dist/templates/workspace-core/.agents/skills/client-methods/references/legacy-client-fetch-audit-2026-06-03.md +9 -0
- package/dist/templates/workspace-core/.agents/skills/writing-agent-instructions/SKILL.md +27 -0
- package/docs/content/template-plan.md +5 -3
- package/docs/content/visual-plans.md +5 -2
- package/package.json +16 -1
- package/src/templates/default/.agents/skills/actions/SKILL.md +96 -11
- package/src/templates/default/.agents/skills/adding-a-feature/SKILL.md +126 -26
- package/src/templates/default/.agents/skills/capture-learnings/SKILL.md +56 -30
- package/src/templates/default/.agents/skills/create-skill/SKILL.md +28 -0
- package/src/templates/default/.agents/skills/delegate-to-agent/SKILL.md +75 -5
- package/src/templates/default/.agents/skills/frontend-design/SKILL.md +17 -0
- package/src/templates/default/.agents/skills/real-time-collab/SKILL.md +99 -124
- package/src/templates/default/.agents/skills/real-time-sync/SKILL.md +43 -10
- package/src/templates/default/.agents/skills/security/SKILL.md +162 -144
- package/src/templates/default/.agents/skills/self-modifying-code/SKILL.md +5 -3
- package/src/templates/default/.agents/skills/shadcn-ui/SKILL.md +15 -0
- package/src/templates/default/.agents/skills/storing-data/SKILL.md +116 -83
- package/src/templates/default/DEVELOPING.md +10 -13
- package/src/templates/workspace-core/.agents/skills/client-methods/references/legacy-client-fetch-audit-2026-06-03.md +9 -0
- package/src/templates/workspace-core/.agents/skills/writing-agent-instructions/SKILL.md +27 -0
|
@@ -73,7 +73,7 @@ function buildNewWorkspaceAppPrompt(input) {
|
|
|
73
73
|
`If you use the starter template, treat it as scaffolding only: the finished app must use the requested app's real name, home screen, navigation, package metadata, and manifest, and it must not leave visible "Starter", "Blank app", or "New app" UI behind.`,
|
|
74
74
|
`Use the workspace app layout: create it under apps/${input.appId}, mount it at /${input.appId}, keep it on the shared workspace database/hosting model, and avoid table-name collisions by namespacing any new domain tables to the app.`,
|
|
75
75
|
`Important routing rule: from outside the app, link to /${input.appId}; inside apps/${input.appId}, React Router routes are app-local. Use <Link to="/review"> and navigate("/review"), not "/${input.appId}/review"; APP_BASE_PATH supplies the mounted prefix, and hardcoding it causes doubled URLs like /${input.appId}/${input.appId}/review.`,
|
|
76
|
-
`Action-backed UI is mandatory for normal CRUD. Define reads/writes in actions/ with defineAction, expose read actions with http: { method: "GET" }, and call them from React with useActionQuery/useActionMutation. Do not create duplicate JSON CRUD routes under /api/* for data the agent can mutate; those bypass the action cache contract and make agent-created records invisible until reload. If a rare raw fetch is unavoidable, include useChangeVersions(["action", <domain-source>]) in the query key and wrap framework URLs with
|
|
76
|
+
`Action-backed UI is mandatory for normal CRUD. Define reads/writes in actions/ with defineAction, expose read actions with http: { method: "GET" }, and call them from React with useActionQuery/useActionMutation or a named helper that uses callAction. Do not create duplicate JSON CRUD routes under /api/* for data the agent can mutate; those bypass the action cache contract and make agent-created records invisible until reload. If a rare raw non-action fetch is unavoidable, include useChangeVersions(["action", <domain-source>]) in the query key and wrap framework URLs with named client helpers so mounted apps call the right URL.`,
|
|
77
77
|
`If the user's prompt mentions sibling apps like Mail, Calendar, Assets, Brain, Dispatch, or other templates, treat them as existing workspace neighbors or integrations. Do not scaffold those sibling apps inside apps/${input.appId} unless the user explicitly asks to create them too.`,
|
|
78
78
|
`Do not satisfy this by adding a route, page, component, or file inside apps/starter or another existing app unless the user explicitly asks to modify that existing app.`,
|
|
79
79
|
`Use relative workspace links like /${input.appId}. Do not hardcode localhost, 127.0.0.1, 8080, 8100, or any dev port; the active workspace gateway/browser origin owns the port.`,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"NewWorkspaceAppFlow.js","sourceRoot":"","sources":["../../src/client/NewWorkspaceAppFlow.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,SAAS,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AACrD,OAAO,EACL,gBAAgB,EAChB,QAAQ,EACR,SAAS,EACT,eAAe,EACf,YAAY,EACZ,OAAO,GACR,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,eAAe,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC7D,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAClD,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAC/C,OAAO,EAAE,gCAAgC,EAAE,MAAM,+BAA+B,CAAC;AACjF,OAAO,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AA4B9D,SAAS,OAAO,CAAC,KAAa;IAC5B,OAAO,KAAK;SACT,WAAW,EAAE;SACb,OAAO,CAAC,aAAa,EAAE,GAAG,CAAC;SAC3B,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC;SACvB,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC;SACvB,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;AAClB,CAAC;AAED,SAAS,eAAe,CAAC,MAAc;IACrC,MAAM,OAAO,GAAG,MAAM;SACnB,OAAO,CAAC,sDAAsD,EAAE,GAAG,CAAC;SACpE,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC;SACpB,IAAI,EAAE,CAAC;IACV,OAAO,OAAO,CAAC,OAAO,IAAI,SAAS,CAAC,IAAI,SAAS,CAAC;AACpD,CAAC;AAED,SAAS,SAAS,CAAC,QAAuB,EAAE,MAAc;IACxD,MAAM,IAAI,GAAG,0BAA0B,MAAM,EAAE,CAAC;IAChD,IAAI,QAAQ,KAAK,IAAI;QAAE,OAAO,eAAe,CAAC,IAAI,CAAC,CAAC;IACpD,MAAM,UAAU,GAAG,QAAQ,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;IAChD,OAAO,GAAG,UAAU,GAAG,IAAI,EAAE,CAAC;AAChC,CAAC;AAED,SAAS,uBAAuB,CAAC,SAAkB;IACjD,IAAI,SAAS,KAAK,UAAU;QAAE,OAAO,IAAI,CAAC;IAC1C,MAAM,IAAI,GAAG,WAAW,EAAE,CAAC;IAC3B,IAAI,IAAI,KAAK,WAAW;QAAE,OAAO,IAAI,CAAC;IACtC,OAAO,WAAW,CAAC;AACrB,CAAC;AAED,KAAK,UAAU,SAAS,CAAC,GAAW,EAAE,IAAkB;IACtD,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;IACnC,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,CAAC;IAChD,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;QACZ,MAAM,IAAI,KAAK,CACb,IAAI,EAAE,KAAK,IAAI,IAAI,EAAE,OAAO,IAAI,kBAAkB,GAAG,CAAC,MAAM,EAAE,CAC/D,CAAC;IACJ,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,SAAS,0BAA0B,CAAC,KAMnC;IACC,MAAM,OAAO,GAAG,KAAK,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC9C,MAAM,YAAY,GAChB,KAAK,CAAC,eAAe,KAAK,UAAU;QAClC,CAAC,CAAC,kIAAkI;QACpI,CAAC,CAAC,OAAO;YACP,CAAC,CAAC,qDAAqD,OAAO,EAAE;YAChE,CAAC,CAAC,wDAAwD,CAAC;IACjE,MAAM,YAAY,GAAG,KAAK,CAAC,iBAAiB,CAAC,MAAM;QACjD,CAAC,CAAC,KAAK,CAAC,iBAAiB;aACpB,GAAG,CACF,CAAC,QAAQ,EAAE,EAAE,CACX,KAAK,QAAQ,CAAC,IAAI,KAAK,QAAQ,CAAC,IAAI,KAAK,QAAQ,CAAC,IAAI,GAAG,CAC5D;aACA,IAAI,CAAC,IAAI,CAAC;QACf,CAAC,CAAC,MAAM,CAAC;IAEX,OAAO;QACL,kDAAkD;QAClD,iFAAiF;QACjF,EAAE;QACF,uBAAuB,KAAK,CAAC,KAAK,4CAA4C;QAC9E,gBAAgB,KAAK,CAAC,MAAM,CAAC,IAAI,EAAE,EAAE;QACrC,uGAAuG,KAAK,CAAC,KAAK,uEAAuE;QACzL,4RAA4R;QAC5R,YAAY;QACZ,yDAAyD,YAAY,EAAE;QACvE,2NAA2N;QAC3N,EAAE;QACF,0LAA0L;QAC1L,gQAAgQ;QAChQ,sDAAsD,KAAK,CAAC,KAAK,kBAAkB,KAAK,CAAC,KAAK,4IAA4I;QAC1O,0DAA0D,KAAK,CAAC,KAAK,iBAAiB,KAAK,CAAC,KAAK,+FAA+F,KAAK,CAAC,KAAK,oGAAoG,KAAK,CAAC,KAAK,IAAI,KAAK,CAAC,KAAK,UAAU;QACnV,smBAAsmB;QACtmB,2NAA2N,KAAK,CAAC,KAAK,sDAAsD;QAC5R,0KAA0K;QAC1K,sCAAsC,KAAK,CAAC,KAAK,iIAAiI;QAClL,qJAAqJ;QACrJ,oGAAoG;QACpG,KAAK,CAAC,eAAe,KAAK,UAAU;YAClC,CAAC,CAAC,iJAAiJ;YACnJ,CAAC,CAAC,OAAO;gBACP,CAAC,CAAC,0EAA0E,KAAK,CAAC,KAAK,gIAAgI;gBACvN,CAAC,CAAC,kEAAkE;QACxE,KAAK,CAAC,iBAAiB,CAAC,MAAM;YAC5B,CAAC,CAAC,mFAAmF,KAAK,CAAC,KAAK,iEAAiE;YACjK,CAAC,CAAC,yFAAyF;QAC7F,EAAE;QACF,gDAAgD;QAChD,iBAAiB,KAAK,CAAC,KAAK,kMAAkM;QAC9N,4JAA4J;QAC5J,sQAAsQ;QACtQ,sJAAsJ;QACtJ,wFAAwF,KAAK,CAAC,KAAK,GAAG;KACvG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACf,CAAC;AAED,MAAM,UAAU,mBAAmB,CAAC,EAClC,SAAS,GAAG,SAAS,EACrB,SAAS,GAAG,EAAE,EACd,gBAAgB,GACS;IACzB,MAAM,CAAC,iBAAiB,EAAE,oBAAoB,CAAC,GAAG,QAAQ,CAAW,EAAE,CAAC,CAAC;IACzE,MAAM,CAAC,mBAAmB,EAAE,sBAAsB,CAAC,GAAG,QAAQ,CAAW,EAAE,CAAC,CAAC;IAC7E,MAAM,CAAC,OAAO,EAAE,UAAU,CAAC,GAAG,QAAQ,CAAsB,EAAE,CAAC,CAAC;IAChE,MAAM,CAAC,SAAS,EAAE,YAAY,CAAC,GAAG,QAAQ,CAA4B,EAAE,CAAC,CAAC;IAC1E,MAAM,CAAC,eAAe,EAAE,kBAAkB,CAAC,GACzC,QAAQ,CAAkB,UAAU,CAAC,CAAC;IACxC,MAAM,CAAC,YAAY,EAAE,eAAe,CAAC,GAAG,QAAQ,CAAgB,IAAI,CAAC,CAAC;IACtE,MAAM,CAAC,cAAc,EAAE,iBAAiB,CAAC,GAAG,QAAQ,CAAgB,IAAI,CAAC,CAAC;IAC1E,MAAM,CAAC,aAAa,EAAE,gBAAgB,CAAC,GAAG,QAAQ,CAAgB,IAAI,CAAC,CAAC;IACxE,MAAM,CAAC,SAAS,EAAE,YAAY,CAAC,GAAG,QAAQ,CAAgB,IAAI,CAAC,CAAC;IAChE,MAAM,CAAC,YAAY,EAAE,eAAe,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;IACxD,MAAM,EAAE,SAAS,EAAE,GAAG,UAAU,EAAE,CAAC;IAEnC,MAAM,yBAAyB,GAC7B,gBAAgB,KAAK,SAAS;QAC5B,CAAC,CAAC,uBAAuB,CAAC,SAAS,CAAC;QACpC,CAAC,CAAC,gBAAgB,CAAC;IAEvB,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,SAAS,GAAG,KAAK,CAAC;QACtB,MAAM,UAAU,GAAG,SAAS,CAC1B,yBAAyB,EACzB,2BAA2B,CAC5B,CAAC;QACF,MAAM,cAAc,GAAG,SAAS,CAC9B,yBAAyB,EACzB,2BAA2B,CAC5B,CAAC;QACF,MAAM,YAAY,GAAG,SAAS,CAC5B,yBAAyB,EACzB,iCAAiC,CAClC,CAAC;QAEF,SAAS,CAAC,UAAU,CAAC;aAClB,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE;YACb,IAAI,SAAS;gBAAE,OAAO;YACtB,UAAU,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;YAC5C,eAAe,CAAC,IAAI,CAAC,CAAC;QACxB,CAAC,CAAC;aACD,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;YACb,IAAI,SAAS;gBAAE,OAAO;YACtB,UAAU,CAAC,EAAE,CAAC,CAAC;YACf,eAAe,CAAC,GAAG,EAAE,OAAO,IAAI,8BAA8B,CAAC,CAAC;QAClE,CAAC,CAAC,CAAC;QAEL,SAAS,CAAC,cAAc,CAAC;aACtB,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE;YACb,IAAI,SAAS;gBAAE,OAAO;YACtB,kBAAkB,CAAC,IAAI,EAAE,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC;QACtE,CAAC,CAAC;aACD,KAAK,CAAC,GAAG,EAAE;YACV,IAAI,SAAS;gBAAE,OAAO;YACtB,kBAAkB,CAAC,QAAQ,CAAC,CAAC;QAC/B,CAAC,CAAC,CAAC;QAEL,SAAS,CAAC,YAAY,CAAC;aACpB,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE;YACb,IAAI,SAAS;gBAAE,OAAO;YACtB,YAAY,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;YAC9C,iBAAiB,CAAC,IAAI,CAAC,CAAC;QAC1B,CAAC,CAAC;aACD,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;YACb,IAAI,SAAS;gBAAE,OAAO;YACtB,YAAY,CAAC,EAAE,CAAC,CAAC;YACjB,iBAAiB,CAAC,GAAG,EAAE,OAAO,IAAI,mCAAmC,CAAC,CAAC;QACzE,CAAC,CAAC,CAAC;QAEL,OAAO,GAAG,EAAE;YACV,SAAS,GAAG,IAAI,CAAC;QACnB,CAAC,CAAC;IACJ,CAAC,EAAE,CAAC,yBAAyB,CAAC,CAAC,CAAC;IAEhC,MAAM,eAAe,GAAG,OAAO,CAC7B,GAAG,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,iBAAiB,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,EACvE,CAAC,OAAO,EAAE,iBAAiB,CAAC,CAC7B,CAAC;IACF,MAAM,iBAAiB,GAAG,OAAO,CAC/B,GAAG,EAAE,CACH,SAAS,CAAC,MAAM,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,mBAAmB,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,EAC3E,CAAC,SAAS,EAAE,mBAAmB,CAAC,CACjC,CAAC;IACF,MAAM,mBAAmB,GACvB,eAAe,KAAK,UAAU;QAC5B,CAAC,CAAC,mBAAmB;QACrB,CAAC,CAAC,iBAAiB,CAAC,MAAM,KAAK,CAAC;YAC9B,CAAC,CAAC,kBAAkB;YACpB,CAAC,CAAC,GAAG,iBAAiB,CAAC,MAAM,OAAO,iBAAiB,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,WAAW,CAAC;IAC/F,MAAM,qBAAqB,GACzB,mBAAmB,CAAC,MAAM,KAAK,CAAC;QAC9B,CAAC,CAAC,uBAAuB;QACzB,CAAC,CAAC,GAAG,mBAAmB,CAAC,MAAM,YAAY,mBAAmB,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,WAAW,CAAC;IAEtG,KAAK,UAAU,MAAM,CAAC,SAAiB;QACrC,MAAM,MAAM,GAAG,SAAS,CAAC,IAAI,EAAE,CAAC;QAChC,IAAI,CAAC,MAAM,IAAI,YAAY;YAAE,OAAO;QACpC,MAAM,KAAK,GAAG,eAAe,CAAC,MAAM,CAAC,CAAC;QACtC,MAAM,eAAe,GAAG,gCAAgC,CAAC,KAAK,CAAC,CAAC;QAChE,IAAI,eAAe,EAAE,CAAC;YACpB,gBAAgB,CAAC,eAAe,CAAC,CAAC;YAClC,OAAO;QACT,CAAC;QAED,MAAM,OAAO,GAAG,0BAA0B,CAAC;YACzC,KAAK;YACL,MAAM;YACN,YAAY,EACV,eAAe,KAAK,QAAQ;gBAC1B,CAAC,CAAC,eAAe,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,aAAa,CAAC;gBAC7C,CAAC,CAAC,EAAE;YACR,iBAAiB;YACjB,eAAe;SAChB,CAAC,CAAC;QACH,eAAe,CAAC,IAAI,CAAC,CAAC;QACtB,gBAAgB,CAAC,IAAI,CAAC,CAAC;QACvB,YAAY,CAAC,IAAI,CAAC,CAAC;QAEnB,IAAI,CAAC;YACH,IAAI,gBAAgB,EAAE,EAAE,CAAC;gBACvB,eAAe,CAAC,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC;gBACzD,gBAAgB,CAAC,uBAAuB,CAAC,CAAC;YAC5C,CAAC;iBAAM,IAAI,SAAS,EAAE,CAAC;gBACrB,eAAe,CAAC,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;gBACvE,gBAAgB,CAAC,0BAA0B,CAAC,CAAC;YAC/C,CAAC;iBAAM,CAAC;gBACN,MAAM,MAAM,GAAG,MAAM,SAAS,CAC5B,SAAS,CAAC,yBAAyB,EAAE,8BAA8B,CAAC,EACpE;oBACE,MAAM,EAAE,MAAM;oBACd,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE;oBAC/C,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;wBACnB,MAAM;wBACN,KAAK;wBACL,SAAS,EAAE,eAAe,KAAK,QAAQ,CAAC,CAAC,CAAC,iBAAiB,CAAC,CAAC,CAAC,EAAE;wBAChE,WAAW,EAAE,mBAAmB;qBACjC,CAAC;iBACH,CACF,CAAC;gBACF,IAAI,MAAM,EAAE,IAAI,KAAK,SAAS,EAAE,CAAC;oBAC/B,YAAY,CAAC,MAAM,EAAE,GAAG,IAAI,IAAI,CAAC,CAAC;oBAClC,gBAAgB,CAAC,yBAAyB,CAAC,CAAC;gBAC9C,CAAC;qBAAM,CAAC;oBACN,gBAAgB,CACd,MAAM,EAAE,OAAO;wBACb,6GAA6G,CAChH,CAAC;gBACJ,CAAC;YACH,CAAC;QACH,CAAC;QAAC,OAAO,GAAQ,EAAE,CAAC;YAClB,gBAAgB,CAAC,GAAG,EAAE,OAAO,IAAI,mCAAmC,CAAC,CAAC;QACxE,CAAC;gBAAS,CAAC;YACT,eAAe,CAAC,KAAK,CAAC,CAAC;QACzB,CAAC;IACH,CAAC;IAED,SAAS,YAAY,CAAC,EAAU;QAC9B,oBAAoB,CAAC,CAAC,OAAO,EAAE,EAAE,CAC/B,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC;YAClB,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,QAAQ,KAAK,EAAE,CAAC;YAC/C,CAAC,CAAC,CAAC,GAAG,OAAO,EAAE,EAAE,CAAC,CACrB,CAAC;IACJ,CAAC;IAED,SAAS,cAAc,CAAC,EAAU;QAChC,sBAAsB,CAAC,CAAC,OAAO,EAAE,EAAE,CACjC,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC;YAClB,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,QAAQ,KAAK,EAAE,CAAC;YAC/C,CAAC,CAAC,CAAC,GAAG,OAAO,EAAE,EAAE,CAAC,CACrB,CAAC;IACJ,CAAC;IAED,OAAO,CACL,kBACE,SAAS,EAAE,0DAA0D,SAAS,EAAE,YAEhF,eAAK,SAAS,EAAC,+CAA+C,aAC5D,eAAK,SAAS,EAAC,qBAAqB,aAClC,KAAC,cAAc,IACb,SAAS,QACT,QAAQ,EAAE,YAAY,EACtB,WAAW,EAAC,yDAAyD,EACrE,UAAU,EAAC,kBAAkB,EAC7B,qBAAqB,QACrB,QAAQ,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,GAChC,EAED,aAAa,CAAC,CAAC,CAAC,CACf,eAAK,SAAS,EAAC,qFAAqF,aACjG,aAAa,EACb,SAAS,CAAC,CAAC,CAAC,CACX,aACE,IAAI,EAAE,SAAS,EACf,MAAM,EAAC,QAAQ,EACf,GAAG,EAAC,YAAY,EAChB,SAAS,EAAC,2EAA2E,6BAEzE,KAAC,gBAAgB,IAAC,SAAS,EAAC,SAAS,GAAG,IAClD,CACL,CAAC,CAAC,CAAC,IAAI,IACJ,CACP,CAAC,CAAC,CAAC,IAAI,IACJ,EAEN,iBAAO,SAAS,EAAC,yDAAyD,aACxE,cAAK,SAAS,EAAC,kCAAkC,YAC/C,eAAK,SAAS,EAAC,yCAAyC,aACtD,eAAK,SAAS,EAAC,6CAA6C,aAC1D,KAAC,OAAO,IAAC,SAAS,EAAC,SAAS,GAAG,qBAE3B,EACN,eAAM,SAAS,EAAC,sGAAsG,YACnH,mBAAmB,GACf,IACH,GACF,EACN,cAAK,SAAS,EAAC,6CAA6C,YACzD,eAAe,KAAK,UAAU,CAAC,CAAC,CAAC,CAChC,YAAG,SAAS,EAAC,uFAAuF,yEAEhG,CACL,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CACjB,YAAG,SAAS,EAAC,uFAAuF,YACjG,YAAY,GACX,CACL,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,CACzB,YAAG,SAAS,EAAC,uFAAuF,kDAEhG,CACL,CAAC,CAAC,CAAC,CACF,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE;gCACrB,MAAM,QAAQ,GAAG,iBAAiB,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;gCACvD,OAAO,CACL,eAEE,SAAS,EAAE,8CACT,QAAQ;wCACN,CAAC,CAAC,kGAAkG;wCACpG,CAAC,CAAC,oGACN,EAAE,aAEF,kBACE,IAAI,EAAC,QAAQ,kBACC,QAAQ,EACtB,OAAO,EAAE,GAAG,EAAE,CAAC,YAAY,CAAC,MAAM,CAAC,EAAE,CAAC,EACtC,SAAS,EAAC,wJAAwJ,aAElK,eACE,SAAS,EAAE,sFACT,QAAQ;wDACN,CAAC,CAAC,8CAA8C;wDAChD,CAAC,CAAC,oFACN,EAAE,YAED,QAAQ,CAAC,CAAC,CAAC,KAAC,SAAS,IAAC,SAAS,EAAC,SAAS,GAAG,CAAC,CAAC,CAAC,IAAI,GAC/C,EACP,gBAAM,SAAS,EAAC,gBAAgB,aAC9B,eAAM,SAAS,EAAC,4BAA4B,YACzC,MAAM,CAAC,aAAa,GAChB,EACP,eAAM,SAAS,EAAC,iDAAiD,YAC9D,QAAQ;gEACP,CAAC,CAAC,gCAAgC;gEAClC,CAAC,CAAC,kBAAkB,GACjB,IACF,IACA,EACT,mBAAS,SAAS,EAAC,4GAA4G,aAC7H,mBAAS,SAAS,EAAC,+HAA+H,aAChJ,KAAC,eAAe,IAAC,SAAS,EAAC,4DAA4D,GAAG,eAElF,EACV,eAAK,SAAS,EAAC,8BAA8B,aAC3C,eAAK,SAAS,EAAC,UAAU,2BACZ,MAAM,CAAC,QAAQ,IAAI,eAAe,IACzC,EACN,eAAK,SAAS,EAAC,UAAU,uBAAQ,MAAM,CAAC,IAAI,IAAO,IAC/C,IACE,KA5CL,MAAM,CAAC,EAAE,CA6CV,CACP,CAAC;4BACJ,CAAC,CAAC,CACH,GACG,EAEN,cAAK,SAAS,EAAC,kCAAkC,YAC/C,eAAK,SAAS,EAAC,yCAAyC,aACtD,eAAK,SAAS,EAAC,6CAA6C,aAC1D,KAAC,QAAQ,IAAC,SAAS,EAAC,SAAS,GAAG,sBAE5B,EACN,eAAM,SAAS,EAAC,sGAAsG,YACnH,qBAAqB,GACjB,IACH,GACF,EACN,cAAK,SAAS,EAAC,6CAA6C,YACzD,cAAc,CAAC,CAAC,CAAC,CAChB,YAAG,SAAS,EAAC,uFAAuF,YACjG,cAAc,GACb,CACL,CAAC,CAAC,CAAC,SAAS,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,CAC3B,YAAG,SAAS,EAAC,uFAAuF,sDAEhG,CACL,CAAC,CAAC,CAAC,CACF,SAAS,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,EAAE;gCACzB,MAAM,QAAQ,GAAG,mBAAmB,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;gCAC3D,OAAO,CACL,eAEE,SAAS,EAAE,8CACT,QAAQ;wCACN,CAAC,CAAC,kGAAkG;wCACpG,CAAC,CAAC,oGACN,EAAE,aAEF,kBACE,IAAI,EAAC,QAAQ,kBACC,QAAQ,EACtB,OAAO,EAAE,GAAG,EAAE,CAAC,cAAc,CAAC,QAAQ,CAAC,EAAE,CAAC,EAC1C,SAAS,EAAC,wJAAwJ,aAElK,eACE,SAAS,EAAE,sFACT,QAAQ;wDACN,CAAC,CAAC,8CAA8C;wDAChD,CAAC,CAAC,oFACN,EAAE,YAED,QAAQ,CAAC,CAAC,CAAC,KAAC,SAAS,IAAC,SAAS,EAAC,SAAS,GAAG,CAAC,CAAC,CAAC,IAAI,GAC/C,EACP,gBAAM,SAAS,EAAC,gBAAgB,aAC9B,gBAAM,SAAS,EAAC,mCAAmC,aACjD,KAAC,YAAY,IAAC,SAAS,EAAC,+CAA+C,GAAG,EAC1E,eAAM,SAAS,EAAC,4BAA4B,YACzC,QAAQ,CAAC,IAAI,GACT,IACF,EACP,gBAAM,SAAS,EAAC,iDAAiD,aAC9D,QAAQ,CAAC,IAAI,cAAK,QAAQ,CAAC,IAAI,IAC3B,IACF,IACA,EACT,mBAAS,SAAS,EAAC,4GAA4G,aAC7H,mBAAS,SAAS,EAAC,+HAA+H,aAChJ,KAAC,eAAe,IAAC,SAAS,EAAC,4DAA4D,GAAG,eAElF,EACV,eAAK,SAAS,EAAC,8BAA8B,aAC3C,eAAK,SAAS,EAAC,UAAU,uBAChB,GAAG,EACT,QAAQ,CAAC,KAAK,KAAK,KAAK;oEACvB,CAAC,CAAC,UAAU;oEACZ,CAAC,CAAC,eAAe,IACf,EACL,QAAQ,CAAC,WAAW,CAAC,CAAC,CAAC,CACtB,cAAK,SAAS,EAAC,cAAc,YAC1B,QAAQ,CAAC,WAAW,GACjB,CACP,CAAC,CAAC,CAAC,IAAI,IACJ,IACE,KApDL,QAAQ,CAAC,EAAE,CAqDZ,CACP,CAAC;4BACJ,CAAC,CAAC,CACH,GACG,IACA,IACJ,GACE,CACX,CAAC;AACJ,CAAC","sourcesContent":["import { useEffect, useMemo, useState } from \"react\";\nimport {\n IconArrowUpRight,\n IconBook,\n IconCheck,\n IconChevronDown,\n IconFileText,\n IconKey,\n} from \"@tabler/icons-react\";\nimport { agentNativePath, appBasePath } from \"./api-path.js\";\nimport { sendToAgentChat } from \"./agent-chat.js\";\nimport { isInBuilderFrame } from \"./builder-frame.js\";\nimport { useDevMode } from \"./use-dev-mode.js\";\nimport { getWorkspaceAppIdValidationError } from \"../shared/workspace-app-id.js\";\nimport { PromptComposer } from \"./composer/PromptComposer.js\";\n\nexport interface VaultSecretOption {\n id: string;\n name: string;\n credentialKey: string;\n provider?: string | null;\n description?: string | null;\n}\n\nexport interface WorkspaceResourceOption {\n id: string;\n kind: \"skill\" | \"instruction\" | \"agent\" | \"knowledge\";\n name: string;\n description?: string | null;\n path: string;\n scope: \"all\" | \"selected\";\n updatedAt?: number;\n}\n\ntype VaultAccessMode = \"all-apps\" | \"manual\";\n\nexport interface NewWorkspaceAppFlowProps {\n sourceApp?: string;\n className?: string;\n dispatchBasePath?: string | null;\n}\n\nfunction slugify(value: string): string {\n return value\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, \"-\")\n .replace(/^-+|-+$/g, \"\")\n .replace(/^[^a-z]+/, \"\")\n .slice(0, 48);\n}\n\nfunction titleFromPrompt(prompt: string): string {\n const cleaned = prompt\n .replace(/\\b(build|create|make|an?|the|app|tool|dashboard)\\b/gi, \" \")\n .replace(/\\s+/g, \" \")\n .trim();\n return slugify(cleaned || \"new-app\") || \"new-app\";\n}\n\nfunction actionUrl(basePath: string | null, action: string): string {\n const path = `/_agent-native/actions/${action}`;\n if (basePath === null) return agentNativePath(path);\n const normalized = basePath.replace(/\\/+$/, \"\");\n return `${normalized}${path}`;\n}\n\nfunction defaultDispatchBasePath(sourceApp?: string): string | null {\n if (sourceApp === \"dispatch\") return null;\n const base = appBasePath();\n if (base === \"/dispatch\") return null;\n return \"/dispatch\";\n}\n\nasync function fetchJson(url: string, init?: RequestInit): Promise<any> {\n const res = await fetch(url, init);\n const data = await res.json().catch(() => null);\n if (!res.ok) {\n throw new Error(\n data?.error || data?.message || `Request failed ${res.status}`,\n );\n }\n return data;\n}\n\nfunction buildNewWorkspaceAppPrompt(input: {\n appId: string;\n prompt: string;\n selectedKeys: string[];\n selectedResources: WorkspaceResourceOption[];\n vaultAccessMode: VaultAccessMode;\n}): string {\n const keyList = input.selectedKeys.join(\", \");\n const grantRequest =\n input.vaultAccessMode === \"all-apps\"\n ? `Dispatch vault access: all saved vault keys are available to every workspace app by default. No per-app vault grants are needed.`\n : keyList\n ? `Requested Dispatch vault key grants for this app: ${keyList}`\n : `Requested Dispatch vault key grants for this app: none`;\n const resourceList = input.selectedResources.length\n ? input.selectedResources\n .map(\n (resource) =>\n `- ${resource.name} (${resource.kind}, ${resource.path})`,\n )\n .join(\"\\n\")\n : \"none\";\n\n return [\n `Create a new agent-native app in this workspace.`,\n `This is a new workspace app request, not a feature request for the current app.`,\n ``,\n `Suggested app name: ${input.appId} (you may adjust the slug if it conflicts)`,\n `User prompt: ${input.prompt.trim()}`,\n `Generate a concise one-sentence app description from the user prompt before coding; save it in apps/${input.appId}/package.json \"description\" so Dispatch and A2A can describe the app.`,\n `If the user mentions a product or company such as Granola, Loom, Superhuman, Linear, or Notion, treat it as product inspiration unless they explicitly ask to connect to that service. Do not invent or require third-party API keys like GRANOLA_API_KEY just because a product is named.`,\n grantRequest,\n `Requested Dispatch workspace resources for this app:\\n${resourceList}`,\n `Dispatch workspace resources with scope=all are inherited workspace context. Do not copy or sync them into the new app; every workspace app reads them at runtime and may override with app shared or personal resources.`,\n ``,\n `Pick a starter template that fits the user's prompt — analytics, assets, brain, calendar, content, design, dispatch, forms, mail, slides, clips, or starter when none of the others fit.`,\n `If you use the starter template, treat it as scaffolding only: the finished app must use the requested app's real name, home screen, navigation, package metadata, and manifest, and it must not leave visible \"Starter\", \"Blank app\", or \"New app\" UI behind.`,\n `Use the workspace app layout: create it under apps/${input.appId}, mount it at /${input.appId}, keep it on the shared workspace database/hosting model, and avoid table-name collisions by namespacing any new domain tables to the app.`,\n `Important routing rule: from outside the app, link to /${input.appId}; inside apps/${input.appId}, React Router routes are app-local. Use <Link to=\"/review\"> and navigate(\"/review\"), not \"/${input.appId}/review\"; APP_BASE_PATH supplies the mounted prefix, and hardcoding it causes doubled URLs like /${input.appId}/${input.appId}/review.`,\n `Action-backed UI is mandatory for normal CRUD. Define reads/writes in actions/ with defineAction, expose read actions with http: { method: \"GET\" }, and call them from React with useActionQuery/useActionMutation. Do not create duplicate JSON CRUD routes under /api/* for data the agent can mutate; those bypass the action cache contract and make agent-created records invisible until reload. If a rare raw fetch is unavoidable, include useChangeVersions([\"action\", <domain-source>]) in the query key and wrap framework URLs with agentNativePath(\"/_agent-native/actions/<name>\") so mounted apps call the right URL.`,\n `If the user's prompt mentions sibling apps like Mail, Calendar, Assets, Brain, Dispatch, or other templates, treat them as existing workspace neighbors or integrations. Do not scaffold those sibling apps inside apps/${input.appId} unless the user explicitly asks to create them too.`,\n `Do not satisfy this by adding a route, page, component, or file inside apps/starter or another existing app unless the user explicitly asks to modify that existing app.`,\n `Use relative workspace links like /${input.appId}. Do not hardcode localhost, 127.0.0.1, 8080, 8100, or any dev port; the active workspace gateway/browser origin owns the port.`,\n `Use the framework/template UI stack: shadcn/ui components and @tabler/icons-react. Do not add lucide-react or another icon library for standard UI.`,\n `Ensure the React Router client entry preserves APP_BASE_PATH/VITE_APP_BASE_PATH via appBasePath().`,\n input.vaultAccessMode === \"all-apps\"\n ? `Do not create per-app Dispatch vault grants unless the workspace switches vault access to manual or the user explicitly asks for manual grants.`\n : keyList\n ? `After the app exists, grant the selected Dispatch vault keys to appId \"${input.appId}\" and sync them once the app server is available. Treat these as requested grants, not active grants before creation succeeds.`\n : `Do not grant any Dispatch vault keys unless the user asks later.`,\n input.selectedResources.length\n ? `After the app exists, grant the selected Dispatch workspace resources to appId \"${input.appId}\". Do not sync all-app workspace resources; they are inherited.`\n : `Do not grant any selected-only Dispatch workspace resources unless the user asks later.`,\n ``,\n `App readiness requirements before handing off:`,\n `- Ensure apps/${input.appId}/package.json exists with displayName/name and a concise description so Dispatch and the workspace gateway discover it from the filesystem. There is no separate workspace app registry to edit.`,\n `- Update the app manifest/package/deploy metadata needed by the existing workspace deployment model; do not leave the app relying only on local discovery.`,\n `- Verify the app's agent card/A2A metadata is ready so Dispatch can discover and delegate to the app after deployment. Every sibling workspace app is available over A2A by default through call-agent, with names and descriptions from the workspace app registry.`,\n `- Include a final verification note covering filesystem discovery, manifest/deploy metadata, relative same-origin routing, and agent-card readiness.`,\n `When it is ready, start or update the workspace dev server and navigate the user to /${input.appId}.`,\n ].join(\"\\n\");\n}\n\nexport function NewWorkspaceAppFlow({\n sourceApp = \"starter\",\n className = \"\",\n dispatchBasePath,\n}: NewWorkspaceAppFlowProps) {\n const [selectedSecretIds, setSelectedSecretIds] = useState<string[]>([]);\n const [selectedResourceIds, setSelectedResourceIds] = useState<string[]>([]);\n const [secrets, setSecrets] = useState<VaultSecretOption[]>([]);\n const [resources, setResources] = useState<WorkspaceResourceOption[]>([]);\n const [vaultAccessMode, setVaultAccessMode] =\n useState<VaultAccessMode>(\"all-apps\");\n const [secretsError, setSecretsError] = useState<string | null>(null);\n const [resourcesError, setResourcesError] = useState<string | null>(null);\n const [statusMessage, setStatusMessage] = useState<string | null>(null);\n const [branchUrl, setBranchUrl] = useState<string | null>(null);\n const [isSubmitting, setIsSubmitting] = useState(false);\n const { isDevMode } = useDevMode();\n\n const effectiveDispatchBasePath =\n dispatchBasePath === undefined\n ? defaultDispatchBasePath(sourceApp)\n : dispatchBasePath;\n\n useEffect(() => {\n let cancelled = false;\n const secretsUrl = actionUrl(\n effectiveDispatchBasePath,\n \"list-vault-secret-options\",\n );\n const vaultAccessUrl = actionUrl(\n effectiveDispatchBasePath,\n \"get-vault-access-settings\",\n );\n const resourcesUrl = actionUrl(\n effectiveDispatchBasePath,\n \"list-workspace-resource-options\",\n );\n\n fetchJson(secretsUrl)\n .then((data) => {\n if (cancelled) return;\n setSecrets(Array.isArray(data) ? data : []);\n setSecretsError(null);\n })\n .catch((err) => {\n if (cancelled) return;\n setSecrets([]);\n setSecretsError(err?.message || \"Could not load Dispatch keys\");\n });\n\n fetchJson(vaultAccessUrl)\n .then((data) => {\n if (cancelled) return;\n setVaultAccessMode(data?.mode === \"manual\" ? \"manual\" : \"all-apps\");\n })\n .catch(() => {\n if (cancelled) return;\n setVaultAccessMode(\"manual\");\n });\n\n fetchJson(resourcesUrl)\n .then((data) => {\n if (cancelled) return;\n setResources(Array.isArray(data) ? data : []);\n setResourcesError(null);\n })\n .catch((err) => {\n if (cancelled) return;\n setResources([]);\n setResourcesError(err?.message || \"Could not load Dispatch resources\");\n });\n\n return () => {\n cancelled = true;\n };\n }, [effectiveDispatchBasePath]);\n\n const selectedSecrets = useMemo(\n () => secrets.filter((secret) => selectedSecretIds.includes(secret.id)),\n [secrets, selectedSecretIds],\n );\n const selectedResources = useMemo(\n () =>\n resources.filter((resource) => selectedResourceIds.includes(resource.id)),\n [resources, selectedResourceIds],\n );\n const selectedSecretLabel =\n vaultAccessMode === \"all-apps\"\n ? \"All keys included\"\n : selectedSecretIds.length === 0\n ? \"No keys selected\"\n : `${selectedSecretIds.length} key${selectedSecretIds.length === 1 ? \"\" : \"s\"} selected`;\n const selectedResourceLabel =\n selectedResourceIds.length === 0\n ? \"No resources selected\"\n : `${selectedResourceIds.length} resource${selectedResourceIds.length === 1 ? \"\" : \"s\"} selected`;\n\n async function submit(rawPrompt: string) {\n const prompt = rawPrompt.trim();\n if (!prompt || isSubmitting) return;\n const appId = titleFromPrompt(prompt);\n const validationError = getWorkspaceAppIdValidationError(appId);\n if (validationError) {\n setStatusMessage(validationError);\n return;\n }\n\n const message = buildNewWorkspaceAppPrompt({\n appId,\n prompt,\n selectedKeys:\n vaultAccessMode === \"manual\"\n ? selectedSecrets.map((s) => s.credentialKey)\n : [],\n selectedResources,\n vaultAccessMode,\n });\n setIsSubmitting(true);\n setStatusMessage(null);\n setBranchUrl(null);\n\n try {\n if (isInBuilderFrame()) {\n sendToAgentChat({ message, submit: true, type: \"code\" });\n setStatusMessage(\"Sent to Builder chat.\");\n } else if (isDevMode) {\n sendToAgentChat({ message, submit: true, type: \"code\", newTab: true });\n setStatusMessage(\"Sent to the local agent.\");\n } else {\n const result = await fetchJson(\n actionUrl(effectiveDispatchBasePath, \"start-workspace-app-creation\"),\n {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({\n prompt,\n appId,\n secretIds: vaultAccessMode === \"manual\" ? selectedSecretIds : [],\n resourceIds: selectedResourceIds,\n }),\n },\n );\n if (result?.mode === \"builder\") {\n setBranchUrl(result?.url || null);\n setStatusMessage(\"Builder branch created.\");\n } else {\n setStatusMessage(\n result?.message ||\n \"Builder app creation is coming soon here. Open this workspace in Builder to create an app from this prompt.\",\n );\n }\n }\n } catch (err: any) {\n setStatusMessage(err?.message || \"Could not start the new app flow.\");\n } finally {\n setIsSubmitting(false);\n }\n }\n\n function toggleSecret(id: string) {\n setSelectedSecretIds((current) =>\n current.includes(id)\n ? current.filter((existing) => existing !== id)\n : [...current, id],\n );\n }\n\n function toggleResource(id: string) {\n setSelectedResourceIds((current) =>\n current.includes(id)\n ? current.filter((existing) => existing !== id)\n : [...current, id],\n );\n }\n\n return (\n <section\n className={`mx-auto flex w-full max-w-5xl flex-col gap-5 px-4 py-6 ${className}`}\n >\n <div className=\"grid gap-5 lg:grid-cols-[minmax(0,1fr)_320px]\">\n <div className=\"flex flex-col gap-3\">\n <PromptComposer\n autoFocus\n disabled={isSubmitting}\n placeholder=\"Describe the app your teammate should be able to use...\"\n draftScope=\"dispatch:new-app\"\n preserveDraftOnSubmit\n onSubmit={(text) => submit(text)}\n />\n\n {statusMessage ? (\n <div className=\"rounded-md border border-border bg-muted/40 px-3 py-2 text-sm text-muted-foreground\">\n {statusMessage}\n {branchUrl ? (\n <a\n href={branchUrl}\n target=\"_blank\"\n rel=\"noreferrer\"\n className=\"ml-2 inline-flex items-center gap-1 font-medium text-foreground underline\"\n >\n Open branch <IconArrowUpRight className=\"h-3 w-3\" />\n </a>\n ) : null}\n </div>\n ) : null}\n </div>\n\n <aside className=\"overflow-hidden rounded-lg border border-border bg-card\">\n <div className=\"border-b border-border px-4 py-3\">\n <div className=\"flex items-center justify-between gap-3\">\n <div className=\"flex items-center gap-2 text-sm font-medium\">\n <IconKey className=\"h-4 w-4\" />\n Dispatch keys\n </div>\n <span className=\"shrink-0 rounded border border-border bg-background/40 px-2 py-0.5 text-[11px] text-muted-foreground\">\n {selectedSecretLabel}\n </span>\n </div>\n </div>\n <div className=\"max-h-[220px] space-y-2 overflow-y-auto p-3\">\n {vaultAccessMode === \"all-apps\" ? (\n <p className=\"rounded-md border border-dashed border-border px-3 py-3 text-xs text-muted-foreground\">\n Every saved Dispatch vault key is available to new apps.\n </p>\n ) : secretsError ? (\n <p className=\"rounded-md border border-dashed border-border px-3 py-3 text-xs text-muted-foreground\">\n {secretsError}\n </p>\n ) : secrets.length === 0 ? (\n <p className=\"rounded-md border border-dashed border-border px-3 py-3 text-xs text-muted-foreground\">\n No Dispatch vault keys found yet.\n </p>\n ) : (\n secrets.map((secret) => {\n const selected = selectedSecretIds.includes(secret.id);\n return (\n <div\n key={secret.id}\n className={`group rounded-md border text-sm transition ${\n selected\n ? \"border-primary/45 bg-primary/5 text-foreground shadow-[inset_0_0_0_1px_hsl(var(--primary)/0.08)]\"\n : \"border-border bg-background/25 text-foreground hover:border-muted-foreground/40 hover:bg-accent/35\"\n }`}\n >\n <button\n type=\"button\"\n aria-pressed={selected}\n onClick={() => toggleSecret(secret.id)}\n className=\"flex w-full cursor-pointer items-start gap-3 rounded-md px-3 py-2 text-left focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring/30\"\n >\n <span\n className={`mt-0.5 flex h-4 w-4 shrink-0 items-center justify-center rounded border transition ${\n selected\n ? \"border-primary/60 bg-primary/10 text-primary\"\n : \"border-muted-foreground/35 text-transparent group-hover:border-muted-foreground/60\"\n }`}\n >\n {selected ? <IconCheck className=\"h-3 w-3\" /> : null}\n </span>\n <span className=\"min-w-0 flex-1\">\n <span className=\"block truncate font-medium\">\n {secret.credentialKey}\n </span>\n <span className=\"block truncate text-xs text-muted-foreground/70\">\n {selected\n ? \"Will be requested for this app\"\n : \"Click to request\"}\n </span>\n </span>\n </button>\n <details className=\"group/details border-t border-border/60 px-3 py-1.5 text-xs text-muted-foreground/75 open:bg-background/10\">\n <summary className=\"flex cursor-pointer list-none items-center gap-1.5 text-[11px] hover:text-muted-foreground [&::-webkit-details-marker]:hidden\">\n <IconChevronDown className=\"h-3 w-3 transition-transform group-open/details:rotate-180\" />\n Details\n </summary>\n <div className=\"mt-1.5 space-y-1 pb-0.5 pl-4\">\n <div className=\"truncate\">\n Provider: {secret.provider || \"Not specified\"}\n </div>\n <div className=\"truncate\">Name: {secret.name}</div>\n </div>\n </details>\n </div>\n );\n })\n )}\n </div>\n\n <div className=\"border-y border-border px-4 py-3\">\n <div className=\"flex items-center justify-between gap-3\">\n <div className=\"flex items-center gap-2 text-sm font-medium\">\n <IconBook className=\"h-4 w-4\" />\n Resource packs\n </div>\n <span className=\"shrink-0 rounded border border-border bg-background/40 px-2 py-0.5 text-[11px] text-muted-foreground\">\n {selectedResourceLabel}\n </span>\n </div>\n </div>\n <div className=\"max-h-[220px] space-y-2 overflow-y-auto p-3\">\n {resourcesError ? (\n <p className=\"rounded-md border border-dashed border-border px-3 py-3 text-xs text-muted-foreground\">\n {resourcesError}\n </p>\n ) : resources.length === 0 ? (\n <p className=\"rounded-md border border-dashed border-border px-3 py-3 text-xs text-muted-foreground\">\n No Dispatch resource packs found yet.\n </p>\n ) : (\n resources.map((resource) => {\n const selected = selectedResourceIds.includes(resource.id);\n return (\n <div\n key={resource.id}\n className={`group rounded-md border text-sm transition ${\n selected\n ? \"border-primary/45 bg-primary/5 text-foreground shadow-[inset_0_0_0_1px_hsl(var(--primary)/0.08)]\"\n : \"border-border bg-background/25 text-foreground hover:border-muted-foreground/40 hover:bg-accent/35\"\n }`}\n >\n <button\n type=\"button\"\n aria-pressed={selected}\n onClick={() => toggleResource(resource.id)}\n className=\"flex w-full cursor-pointer items-start gap-3 rounded-md px-3 py-2 text-left focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring/30\"\n >\n <span\n className={`mt-0.5 flex h-4 w-4 shrink-0 items-center justify-center rounded border transition ${\n selected\n ? \"border-primary/60 bg-primary/10 text-primary\"\n : \"border-muted-foreground/35 text-transparent group-hover:border-muted-foreground/60\"\n }`}\n >\n {selected ? <IconCheck className=\"h-3 w-3\" /> : null}\n </span>\n <span className=\"min-w-0 flex-1\">\n <span className=\"flex min-w-0 items-center gap-1.5\">\n <IconFileText className=\"h-3.5 w-3.5 shrink-0 text-muted-foreground/70\" />\n <span className=\"block truncate font-medium\">\n {resource.name}\n </span>\n </span>\n <span className=\"block truncate text-xs text-muted-foreground/70\">\n {resource.kind} · {resource.path}\n </span>\n </span>\n </button>\n <details className=\"group/details border-t border-border/60 px-3 py-1.5 text-xs text-muted-foreground/75 open:bg-background/10\">\n <summary className=\"flex cursor-pointer list-none items-center gap-1.5 text-[11px] hover:text-muted-foreground [&::-webkit-details-marker]:hidden\">\n <IconChevronDown className=\"h-3 w-3 transition-transform group-open/details:rotate-180\" />\n Details\n </summary>\n <div className=\"mt-1.5 space-y-1 pb-0.5 pl-4\">\n <div className=\"truncate\">\n Scope:{\" \"}\n {resource.scope === \"all\"\n ? \"All apps\"\n : \"Selected apps\"}\n </div>\n {resource.description ? (\n <div className=\"line-clamp-2\">\n {resource.description}\n </div>\n ) : null}\n </div>\n </details>\n </div>\n );\n })\n )}\n </div>\n </aside>\n </div>\n </section>\n );\n}\n"]}
|
|
1
|
+
{"version":3,"file":"NewWorkspaceAppFlow.js","sourceRoot":"","sources":["../../src/client/NewWorkspaceAppFlow.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,SAAS,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AACrD,OAAO,EACL,gBAAgB,EAChB,QAAQ,EACR,SAAS,EACT,eAAe,EACf,YAAY,EACZ,OAAO,GACR,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,eAAe,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC7D,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAClD,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAC/C,OAAO,EAAE,gCAAgC,EAAE,MAAM,+BAA+B,CAAC;AACjF,OAAO,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AA4B9D,SAAS,OAAO,CAAC,KAAa;IAC5B,OAAO,KAAK;SACT,WAAW,EAAE;SACb,OAAO,CAAC,aAAa,EAAE,GAAG,CAAC;SAC3B,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC;SACvB,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC;SACvB,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;AAClB,CAAC;AAED,SAAS,eAAe,CAAC,MAAc;IACrC,MAAM,OAAO,GAAG,MAAM;SACnB,OAAO,CAAC,sDAAsD,EAAE,GAAG,CAAC;SACpE,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC;SACpB,IAAI,EAAE,CAAC;IACV,OAAO,OAAO,CAAC,OAAO,IAAI,SAAS,CAAC,IAAI,SAAS,CAAC;AACpD,CAAC;AAED,SAAS,SAAS,CAAC,QAAuB,EAAE,MAAc;IACxD,MAAM,IAAI,GAAG,0BAA0B,MAAM,EAAE,CAAC;IAChD,IAAI,QAAQ,KAAK,IAAI;QAAE,OAAO,eAAe,CAAC,IAAI,CAAC,CAAC;IACpD,MAAM,UAAU,GAAG,QAAQ,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;IAChD,OAAO,GAAG,UAAU,GAAG,IAAI,EAAE,CAAC;AAChC,CAAC;AAED,SAAS,uBAAuB,CAAC,SAAkB;IACjD,IAAI,SAAS,KAAK,UAAU;QAAE,OAAO,IAAI,CAAC;IAC1C,MAAM,IAAI,GAAG,WAAW,EAAE,CAAC;IAC3B,IAAI,IAAI,KAAK,WAAW;QAAE,OAAO,IAAI,CAAC;IACtC,OAAO,WAAW,CAAC;AACrB,CAAC;AAED,KAAK,UAAU,SAAS,CAAC,GAAW,EAAE,IAAkB;IACtD,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;IACnC,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,CAAC;IAChD,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;QACZ,MAAM,IAAI,KAAK,CACb,IAAI,EAAE,KAAK,IAAI,IAAI,EAAE,OAAO,IAAI,kBAAkB,GAAG,CAAC,MAAM,EAAE,CAC/D,CAAC;IACJ,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,SAAS,0BAA0B,CAAC,KAMnC;IACC,MAAM,OAAO,GAAG,KAAK,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC9C,MAAM,YAAY,GAChB,KAAK,CAAC,eAAe,KAAK,UAAU;QAClC,CAAC,CAAC,kIAAkI;QACpI,CAAC,CAAC,OAAO;YACP,CAAC,CAAC,qDAAqD,OAAO,EAAE;YAChE,CAAC,CAAC,wDAAwD,CAAC;IACjE,MAAM,YAAY,GAAG,KAAK,CAAC,iBAAiB,CAAC,MAAM;QACjD,CAAC,CAAC,KAAK,CAAC,iBAAiB;aACpB,GAAG,CACF,CAAC,QAAQ,EAAE,EAAE,CACX,KAAK,QAAQ,CAAC,IAAI,KAAK,QAAQ,CAAC,IAAI,KAAK,QAAQ,CAAC,IAAI,GAAG,CAC5D;aACA,IAAI,CAAC,IAAI,CAAC;QACf,CAAC,CAAC,MAAM,CAAC;IAEX,OAAO;QACL,kDAAkD;QAClD,iFAAiF;QACjF,EAAE;QACF,uBAAuB,KAAK,CAAC,KAAK,4CAA4C;QAC9E,gBAAgB,KAAK,CAAC,MAAM,CAAC,IAAI,EAAE,EAAE;QACrC,uGAAuG,KAAK,CAAC,KAAK,uEAAuE;QACzL,4RAA4R;QAC5R,YAAY;QACZ,yDAAyD,YAAY,EAAE;QACvE,2NAA2N;QAC3N,EAAE;QACF,0LAA0L;QAC1L,gQAAgQ;QAChQ,sDAAsD,KAAK,CAAC,KAAK,kBAAkB,KAAK,CAAC,KAAK,4IAA4I;QAC1O,0DAA0D,KAAK,CAAC,KAAK,iBAAiB,KAAK,CAAC,KAAK,+FAA+F,KAAK,CAAC,KAAK,oGAAoG,KAAK,CAAC,KAAK,IAAI,KAAK,CAAC,KAAK,UAAU;QACnV,4nBAA4nB;QAC5nB,2NAA2N,KAAK,CAAC,KAAK,sDAAsD;QAC5R,0KAA0K;QAC1K,sCAAsC,KAAK,CAAC,KAAK,iIAAiI;QAClL,qJAAqJ;QACrJ,oGAAoG;QACpG,KAAK,CAAC,eAAe,KAAK,UAAU;YAClC,CAAC,CAAC,iJAAiJ;YACnJ,CAAC,CAAC,OAAO;gBACP,CAAC,CAAC,0EAA0E,KAAK,CAAC,KAAK,gIAAgI;gBACvN,CAAC,CAAC,kEAAkE;QACxE,KAAK,CAAC,iBAAiB,CAAC,MAAM;YAC5B,CAAC,CAAC,mFAAmF,KAAK,CAAC,KAAK,iEAAiE;YACjK,CAAC,CAAC,yFAAyF;QAC7F,EAAE;QACF,gDAAgD;QAChD,iBAAiB,KAAK,CAAC,KAAK,kMAAkM;QAC9N,4JAA4J;QAC5J,sQAAsQ;QACtQ,sJAAsJ;QACtJ,wFAAwF,KAAK,CAAC,KAAK,GAAG;KACvG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACf,CAAC;AAED,MAAM,UAAU,mBAAmB,CAAC,EAClC,SAAS,GAAG,SAAS,EACrB,SAAS,GAAG,EAAE,EACd,gBAAgB,GACS;IACzB,MAAM,CAAC,iBAAiB,EAAE,oBAAoB,CAAC,GAAG,QAAQ,CAAW,EAAE,CAAC,CAAC;IACzE,MAAM,CAAC,mBAAmB,EAAE,sBAAsB,CAAC,GAAG,QAAQ,CAAW,EAAE,CAAC,CAAC;IAC7E,MAAM,CAAC,OAAO,EAAE,UAAU,CAAC,GAAG,QAAQ,CAAsB,EAAE,CAAC,CAAC;IAChE,MAAM,CAAC,SAAS,EAAE,YAAY,CAAC,GAAG,QAAQ,CAA4B,EAAE,CAAC,CAAC;IAC1E,MAAM,CAAC,eAAe,EAAE,kBAAkB,CAAC,GACzC,QAAQ,CAAkB,UAAU,CAAC,CAAC;IACxC,MAAM,CAAC,YAAY,EAAE,eAAe,CAAC,GAAG,QAAQ,CAAgB,IAAI,CAAC,CAAC;IACtE,MAAM,CAAC,cAAc,EAAE,iBAAiB,CAAC,GAAG,QAAQ,CAAgB,IAAI,CAAC,CAAC;IAC1E,MAAM,CAAC,aAAa,EAAE,gBAAgB,CAAC,GAAG,QAAQ,CAAgB,IAAI,CAAC,CAAC;IACxE,MAAM,CAAC,SAAS,EAAE,YAAY,CAAC,GAAG,QAAQ,CAAgB,IAAI,CAAC,CAAC;IAChE,MAAM,CAAC,YAAY,EAAE,eAAe,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;IACxD,MAAM,EAAE,SAAS,EAAE,GAAG,UAAU,EAAE,CAAC;IAEnC,MAAM,yBAAyB,GAC7B,gBAAgB,KAAK,SAAS;QAC5B,CAAC,CAAC,uBAAuB,CAAC,SAAS,CAAC;QACpC,CAAC,CAAC,gBAAgB,CAAC;IAEvB,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,SAAS,GAAG,KAAK,CAAC;QACtB,MAAM,UAAU,GAAG,SAAS,CAC1B,yBAAyB,EACzB,2BAA2B,CAC5B,CAAC;QACF,MAAM,cAAc,GAAG,SAAS,CAC9B,yBAAyB,EACzB,2BAA2B,CAC5B,CAAC;QACF,MAAM,YAAY,GAAG,SAAS,CAC5B,yBAAyB,EACzB,iCAAiC,CAClC,CAAC;QAEF,SAAS,CAAC,UAAU,CAAC;aAClB,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE;YACb,IAAI,SAAS;gBAAE,OAAO;YACtB,UAAU,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;YAC5C,eAAe,CAAC,IAAI,CAAC,CAAC;QACxB,CAAC,CAAC;aACD,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;YACb,IAAI,SAAS;gBAAE,OAAO;YACtB,UAAU,CAAC,EAAE,CAAC,CAAC;YACf,eAAe,CAAC,GAAG,EAAE,OAAO,IAAI,8BAA8B,CAAC,CAAC;QAClE,CAAC,CAAC,CAAC;QAEL,SAAS,CAAC,cAAc,CAAC;aACtB,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE;YACb,IAAI,SAAS;gBAAE,OAAO;YACtB,kBAAkB,CAAC,IAAI,EAAE,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC;QACtE,CAAC,CAAC;aACD,KAAK,CAAC,GAAG,EAAE;YACV,IAAI,SAAS;gBAAE,OAAO;YACtB,kBAAkB,CAAC,QAAQ,CAAC,CAAC;QAC/B,CAAC,CAAC,CAAC;QAEL,SAAS,CAAC,YAAY,CAAC;aACpB,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE;YACb,IAAI,SAAS;gBAAE,OAAO;YACtB,YAAY,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;YAC9C,iBAAiB,CAAC,IAAI,CAAC,CAAC;QAC1B,CAAC,CAAC;aACD,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;YACb,IAAI,SAAS;gBAAE,OAAO;YACtB,YAAY,CAAC,EAAE,CAAC,CAAC;YACjB,iBAAiB,CAAC,GAAG,EAAE,OAAO,IAAI,mCAAmC,CAAC,CAAC;QACzE,CAAC,CAAC,CAAC;QAEL,OAAO,GAAG,EAAE;YACV,SAAS,GAAG,IAAI,CAAC;QACnB,CAAC,CAAC;IACJ,CAAC,EAAE,CAAC,yBAAyB,CAAC,CAAC,CAAC;IAEhC,MAAM,eAAe,GAAG,OAAO,CAC7B,GAAG,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,iBAAiB,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,EACvE,CAAC,OAAO,EAAE,iBAAiB,CAAC,CAC7B,CAAC;IACF,MAAM,iBAAiB,GAAG,OAAO,CAC/B,GAAG,EAAE,CACH,SAAS,CAAC,MAAM,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,mBAAmB,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,EAC3E,CAAC,SAAS,EAAE,mBAAmB,CAAC,CACjC,CAAC;IACF,MAAM,mBAAmB,GACvB,eAAe,KAAK,UAAU;QAC5B,CAAC,CAAC,mBAAmB;QACrB,CAAC,CAAC,iBAAiB,CAAC,MAAM,KAAK,CAAC;YAC9B,CAAC,CAAC,kBAAkB;YACpB,CAAC,CAAC,GAAG,iBAAiB,CAAC,MAAM,OAAO,iBAAiB,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,WAAW,CAAC;IAC/F,MAAM,qBAAqB,GACzB,mBAAmB,CAAC,MAAM,KAAK,CAAC;QAC9B,CAAC,CAAC,uBAAuB;QACzB,CAAC,CAAC,GAAG,mBAAmB,CAAC,MAAM,YAAY,mBAAmB,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,WAAW,CAAC;IAEtG,KAAK,UAAU,MAAM,CAAC,SAAiB;QACrC,MAAM,MAAM,GAAG,SAAS,CAAC,IAAI,EAAE,CAAC;QAChC,IAAI,CAAC,MAAM,IAAI,YAAY;YAAE,OAAO;QACpC,MAAM,KAAK,GAAG,eAAe,CAAC,MAAM,CAAC,CAAC;QACtC,MAAM,eAAe,GAAG,gCAAgC,CAAC,KAAK,CAAC,CAAC;QAChE,IAAI,eAAe,EAAE,CAAC;YACpB,gBAAgB,CAAC,eAAe,CAAC,CAAC;YAClC,OAAO;QACT,CAAC;QAED,MAAM,OAAO,GAAG,0BAA0B,CAAC;YACzC,KAAK;YACL,MAAM;YACN,YAAY,EACV,eAAe,KAAK,QAAQ;gBAC1B,CAAC,CAAC,eAAe,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,aAAa,CAAC;gBAC7C,CAAC,CAAC,EAAE;YACR,iBAAiB;YACjB,eAAe;SAChB,CAAC,CAAC;QACH,eAAe,CAAC,IAAI,CAAC,CAAC;QACtB,gBAAgB,CAAC,IAAI,CAAC,CAAC;QACvB,YAAY,CAAC,IAAI,CAAC,CAAC;QAEnB,IAAI,CAAC;YACH,IAAI,gBAAgB,EAAE,EAAE,CAAC;gBACvB,eAAe,CAAC,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC;gBACzD,gBAAgB,CAAC,uBAAuB,CAAC,CAAC;YAC5C,CAAC;iBAAM,IAAI,SAAS,EAAE,CAAC;gBACrB,eAAe,CAAC,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;gBACvE,gBAAgB,CAAC,0BAA0B,CAAC,CAAC;YAC/C,CAAC;iBAAM,CAAC;gBACN,MAAM,MAAM,GAAG,MAAM,SAAS,CAC5B,SAAS,CAAC,yBAAyB,EAAE,8BAA8B,CAAC,EACpE;oBACE,MAAM,EAAE,MAAM;oBACd,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE;oBAC/C,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;wBACnB,MAAM;wBACN,KAAK;wBACL,SAAS,EAAE,eAAe,KAAK,QAAQ,CAAC,CAAC,CAAC,iBAAiB,CAAC,CAAC,CAAC,EAAE;wBAChE,WAAW,EAAE,mBAAmB;qBACjC,CAAC;iBACH,CACF,CAAC;gBACF,IAAI,MAAM,EAAE,IAAI,KAAK,SAAS,EAAE,CAAC;oBAC/B,YAAY,CAAC,MAAM,EAAE,GAAG,IAAI,IAAI,CAAC,CAAC;oBAClC,gBAAgB,CAAC,yBAAyB,CAAC,CAAC;gBAC9C,CAAC;qBAAM,CAAC;oBACN,gBAAgB,CACd,MAAM,EAAE,OAAO;wBACb,6GAA6G,CAChH,CAAC;gBACJ,CAAC;YACH,CAAC;QACH,CAAC;QAAC,OAAO,GAAQ,EAAE,CAAC;YAClB,gBAAgB,CAAC,GAAG,EAAE,OAAO,IAAI,mCAAmC,CAAC,CAAC;QACxE,CAAC;gBAAS,CAAC;YACT,eAAe,CAAC,KAAK,CAAC,CAAC;QACzB,CAAC;IACH,CAAC;IAED,SAAS,YAAY,CAAC,EAAU;QAC9B,oBAAoB,CAAC,CAAC,OAAO,EAAE,EAAE,CAC/B,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC;YAClB,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,QAAQ,KAAK,EAAE,CAAC;YAC/C,CAAC,CAAC,CAAC,GAAG,OAAO,EAAE,EAAE,CAAC,CACrB,CAAC;IACJ,CAAC;IAED,SAAS,cAAc,CAAC,EAAU;QAChC,sBAAsB,CAAC,CAAC,OAAO,EAAE,EAAE,CACjC,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC;YAClB,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,QAAQ,KAAK,EAAE,CAAC;YAC/C,CAAC,CAAC,CAAC,GAAG,OAAO,EAAE,EAAE,CAAC,CACrB,CAAC;IACJ,CAAC;IAED,OAAO,CACL,kBACE,SAAS,EAAE,0DAA0D,SAAS,EAAE,YAEhF,eAAK,SAAS,EAAC,+CAA+C,aAC5D,eAAK,SAAS,EAAC,qBAAqB,aAClC,KAAC,cAAc,IACb,SAAS,QACT,QAAQ,EAAE,YAAY,EACtB,WAAW,EAAC,yDAAyD,EACrE,UAAU,EAAC,kBAAkB,EAC7B,qBAAqB,QACrB,QAAQ,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,GAChC,EAED,aAAa,CAAC,CAAC,CAAC,CACf,eAAK,SAAS,EAAC,qFAAqF,aACjG,aAAa,EACb,SAAS,CAAC,CAAC,CAAC,CACX,aACE,IAAI,EAAE,SAAS,EACf,MAAM,EAAC,QAAQ,EACf,GAAG,EAAC,YAAY,EAChB,SAAS,EAAC,2EAA2E,6BAEzE,KAAC,gBAAgB,IAAC,SAAS,EAAC,SAAS,GAAG,IAClD,CACL,CAAC,CAAC,CAAC,IAAI,IACJ,CACP,CAAC,CAAC,CAAC,IAAI,IACJ,EAEN,iBAAO,SAAS,EAAC,yDAAyD,aACxE,cAAK,SAAS,EAAC,kCAAkC,YAC/C,eAAK,SAAS,EAAC,yCAAyC,aACtD,eAAK,SAAS,EAAC,6CAA6C,aAC1D,KAAC,OAAO,IAAC,SAAS,EAAC,SAAS,GAAG,qBAE3B,EACN,eAAM,SAAS,EAAC,sGAAsG,YACnH,mBAAmB,GACf,IACH,GACF,EACN,cAAK,SAAS,EAAC,6CAA6C,YACzD,eAAe,KAAK,UAAU,CAAC,CAAC,CAAC,CAChC,YAAG,SAAS,EAAC,uFAAuF,yEAEhG,CACL,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CACjB,YAAG,SAAS,EAAC,uFAAuF,YACjG,YAAY,GACX,CACL,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,CACzB,YAAG,SAAS,EAAC,uFAAuF,kDAEhG,CACL,CAAC,CAAC,CAAC,CACF,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE;gCACrB,MAAM,QAAQ,GAAG,iBAAiB,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;gCACvD,OAAO,CACL,eAEE,SAAS,EAAE,8CACT,QAAQ;wCACN,CAAC,CAAC,kGAAkG;wCACpG,CAAC,CAAC,oGACN,EAAE,aAEF,kBACE,IAAI,EAAC,QAAQ,kBACC,QAAQ,EACtB,OAAO,EAAE,GAAG,EAAE,CAAC,YAAY,CAAC,MAAM,CAAC,EAAE,CAAC,EACtC,SAAS,EAAC,wJAAwJ,aAElK,eACE,SAAS,EAAE,sFACT,QAAQ;wDACN,CAAC,CAAC,8CAA8C;wDAChD,CAAC,CAAC,oFACN,EAAE,YAED,QAAQ,CAAC,CAAC,CAAC,KAAC,SAAS,IAAC,SAAS,EAAC,SAAS,GAAG,CAAC,CAAC,CAAC,IAAI,GAC/C,EACP,gBAAM,SAAS,EAAC,gBAAgB,aAC9B,eAAM,SAAS,EAAC,4BAA4B,YACzC,MAAM,CAAC,aAAa,GAChB,EACP,eAAM,SAAS,EAAC,iDAAiD,YAC9D,QAAQ;gEACP,CAAC,CAAC,gCAAgC;gEAClC,CAAC,CAAC,kBAAkB,GACjB,IACF,IACA,EACT,mBAAS,SAAS,EAAC,4GAA4G,aAC7H,mBAAS,SAAS,EAAC,+HAA+H,aAChJ,KAAC,eAAe,IAAC,SAAS,EAAC,4DAA4D,GAAG,eAElF,EACV,eAAK,SAAS,EAAC,8BAA8B,aAC3C,eAAK,SAAS,EAAC,UAAU,2BACZ,MAAM,CAAC,QAAQ,IAAI,eAAe,IACzC,EACN,eAAK,SAAS,EAAC,UAAU,uBAAQ,MAAM,CAAC,IAAI,IAAO,IAC/C,IACE,KA5CL,MAAM,CAAC,EAAE,CA6CV,CACP,CAAC;4BACJ,CAAC,CAAC,CACH,GACG,EAEN,cAAK,SAAS,EAAC,kCAAkC,YAC/C,eAAK,SAAS,EAAC,yCAAyC,aACtD,eAAK,SAAS,EAAC,6CAA6C,aAC1D,KAAC,QAAQ,IAAC,SAAS,EAAC,SAAS,GAAG,sBAE5B,EACN,eAAM,SAAS,EAAC,sGAAsG,YACnH,qBAAqB,GACjB,IACH,GACF,EACN,cAAK,SAAS,EAAC,6CAA6C,YACzD,cAAc,CAAC,CAAC,CAAC,CAChB,YAAG,SAAS,EAAC,uFAAuF,YACjG,cAAc,GACb,CACL,CAAC,CAAC,CAAC,SAAS,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,CAC3B,YAAG,SAAS,EAAC,uFAAuF,sDAEhG,CACL,CAAC,CAAC,CAAC,CACF,SAAS,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,EAAE;gCACzB,MAAM,QAAQ,GAAG,mBAAmB,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;gCAC3D,OAAO,CACL,eAEE,SAAS,EAAE,8CACT,QAAQ;wCACN,CAAC,CAAC,kGAAkG;wCACpG,CAAC,CAAC,oGACN,EAAE,aAEF,kBACE,IAAI,EAAC,QAAQ,kBACC,QAAQ,EACtB,OAAO,EAAE,GAAG,EAAE,CAAC,cAAc,CAAC,QAAQ,CAAC,EAAE,CAAC,EAC1C,SAAS,EAAC,wJAAwJ,aAElK,eACE,SAAS,EAAE,sFACT,QAAQ;wDACN,CAAC,CAAC,8CAA8C;wDAChD,CAAC,CAAC,oFACN,EAAE,YAED,QAAQ,CAAC,CAAC,CAAC,KAAC,SAAS,IAAC,SAAS,EAAC,SAAS,GAAG,CAAC,CAAC,CAAC,IAAI,GAC/C,EACP,gBAAM,SAAS,EAAC,gBAAgB,aAC9B,gBAAM,SAAS,EAAC,mCAAmC,aACjD,KAAC,YAAY,IAAC,SAAS,EAAC,+CAA+C,GAAG,EAC1E,eAAM,SAAS,EAAC,4BAA4B,YACzC,QAAQ,CAAC,IAAI,GACT,IACF,EACP,gBAAM,SAAS,EAAC,iDAAiD,aAC9D,QAAQ,CAAC,IAAI,cAAK,QAAQ,CAAC,IAAI,IAC3B,IACF,IACA,EACT,mBAAS,SAAS,EAAC,4GAA4G,aAC7H,mBAAS,SAAS,EAAC,+HAA+H,aAChJ,KAAC,eAAe,IAAC,SAAS,EAAC,4DAA4D,GAAG,eAElF,EACV,eAAK,SAAS,EAAC,8BAA8B,aAC3C,eAAK,SAAS,EAAC,UAAU,uBAChB,GAAG,EACT,QAAQ,CAAC,KAAK,KAAK,KAAK;oEACvB,CAAC,CAAC,UAAU;oEACZ,CAAC,CAAC,eAAe,IACf,EACL,QAAQ,CAAC,WAAW,CAAC,CAAC,CAAC,CACtB,cAAK,SAAS,EAAC,cAAc,YAC1B,QAAQ,CAAC,WAAW,GACjB,CACP,CAAC,CAAC,CAAC,IAAI,IACJ,IACE,KApDL,QAAQ,CAAC,EAAE,CAqDZ,CACP,CAAC;4BACJ,CAAC,CAAC,CACH,GACG,IACA,IACJ,GACE,CACX,CAAC;AACJ,CAAC","sourcesContent":["import { useEffect, useMemo, useState } from \"react\";\nimport {\n IconArrowUpRight,\n IconBook,\n IconCheck,\n IconChevronDown,\n IconFileText,\n IconKey,\n} from \"@tabler/icons-react\";\nimport { agentNativePath, appBasePath } from \"./api-path.js\";\nimport { sendToAgentChat } from \"./agent-chat.js\";\nimport { isInBuilderFrame } from \"./builder-frame.js\";\nimport { useDevMode } from \"./use-dev-mode.js\";\nimport { getWorkspaceAppIdValidationError } from \"../shared/workspace-app-id.js\";\nimport { PromptComposer } from \"./composer/PromptComposer.js\";\n\nexport interface VaultSecretOption {\n id: string;\n name: string;\n credentialKey: string;\n provider?: string | null;\n description?: string | null;\n}\n\nexport interface WorkspaceResourceOption {\n id: string;\n kind: \"skill\" | \"instruction\" | \"agent\" | \"knowledge\";\n name: string;\n description?: string | null;\n path: string;\n scope: \"all\" | \"selected\";\n updatedAt?: number;\n}\n\ntype VaultAccessMode = \"all-apps\" | \"manual\";\n\nexport interface NewWorkspaceAppFlowProps {\n sourceApp?: string;\n className?: string;\n dispatchBasePath?: string | null;\n}\n\nfunction slugify(value: string): string {\n return value\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, \"-\")\n .replace(/^-+|-+$/g, \"\")\n .replace(/^[^a-z]+/, \"\")\n .slice(0, 48);\n}\n\nfunction titleFromPrompt(prompt: string): string {\n const cleaned = prompt\n .replace(/\\b(build|create|make|an?|the|app|tool|dashboard)\\b/gi, \" \")\n .replace(/\\s+/g, \" \")\n .trim();\n return slugify(cleaned || \"new-app\") || \"new-app\";\n}\n\nfunction actionUrl(basePath: string | null, action: string): string {\n const path = `/_agent-native/actions/${action}`;\n if (basePath === null) return agentNativePath(path);\n const normalized = basePath.replace(/\\/+$/, \"\");\n return `${normalized}${path}`;\n}\n\nfunction defaultDispatchBasePath(sourceApp?: string): string | null {\n if (sourceApp === \"dispatch\") return null;\n const base = appBasePath();\n if (base === \"/dispatch\") return null;\n return \"/dispatch\";\n}\n\nasync function fetchJson(url: string, init?: RequestInit): Promise<any> {\n const res = await fetch(url, init);\n const data = await res.json().catch(() => null);\n if (!res.ok) {\n throw new Error(\n data?.error || data?.message || `Request failed ${res.status}`,\n );\n }\n return data;\n}\n\nfunction buildNewWorkspaceAppPrompt(input: {\n appId: string;\n prompt: string;\n selectedKeys: string[];\n selectedResources: WorkspaceResourceOption[];\n vaultAccessMode: VaultAccessMode;\n}): string {\n const keyList = input.selectedKeys.join(\", \");\n const grantRequest =\n input.vaultAccessMode === \"all-apps\"\n ? `Dispatch vault access: all saved vault keys are available to every workspace app by default. No per-app vault grants are needed.`\n : keyList\n ? `Requested Dispatch vault key grants for this app: ${keyList}`\n : `Requested Dispatch vault key grants for this app: none`;\n const resourceList = input.selectedResources.length\n ? input.selectedResources\n .map(\n (resource) =>\n `- ${resource.name} (${resource.kind}, ${resource.path})`,\n )\n .join(\"\\n\")\n : \"none\";\n\n return [\n `Create a new agent-native app in this workspace.`,\n `This is a new workspace app request, not a feature request for the current app.`,\n ``,\n `Suggested app name: ${input.appId} (you may adjust the slug if it conflicts)`,\n `User prompt: ${input.prompt.trim()}`,\n `Generate a concise one-sentence app description from the user prompt before coding; save it in apps/${input.appId}/package.json \"description\" so Dispatch and A2A can describe the app.`,\n `If the user mentions a product or company such as Granola, Loom, Superhuman, Linear, or Notion, treat it as product inspiration unless they explicitly ask to connect to that service. Do not invent or require third-party API keys like GRANOLA_API_KEY just because a product is named.`,\n grantRequest,\n `Requested Dispatch workspace resources for this app:\\n${resourceList}`,\n `Dispatch workspace resources with scope=all are inherited workspace context. Do not copy or sync them into the new app; every workspace app reads them at runtime and may override with app shared or personal resources.`,\n ``,\n `Pick a starter template that fits the user's prompt — analytics, assets, brain, calendar, content, design, dispatch, forms, mail, slides, clips, or starter when none of the others fit.`,\n `If you use the starter template, treat it as scaffolding only: the finished app must use the requested app's real name, home screen, navigation, package metadata, and manifest, and it must not leave visible \"Starter\", \"Blank app\", or \"New app\" UI behind.`,\n `Use the workspace app layout: create it under apps/${input.appId}, mount it at /${input.appId}, keep it on the shared workspace database/hosting model, and avoid table-name collisions by namespacing any new domain tables to the app.`,\n `Important routing rule: from outside the app, link to /${input.appId}; inside apps/${input.appId}, React Router routes are app-local. Use <Link to=\"/review\"> and navigate(\"/review\"), not \"/${input.appId}/review\"; APP_BASE_PATH supplies the mounted prefix, and hardcoding it causes doubled URLs like /${input.appId}/${input.appId}/review.`,\n `Action-backed UI is mandatory for normal CRUD. Define reads/writes in actions/ with defineAction, expose read actions with http: { method: \"GET\" }, and call them from React with useActionQuery/useActionMutation or a named helper that uses callAction. Do not create duplicate JSON CRUD routes under /api/* for data the agent can mutate; those bypass the action cache contract and make agent-created records invisible until reload. If a rare raw non-action fetch is unavoidable, include useChangeVersions([\"action\", <domain-source>]) in the query key and wrap framework URLs with named client helpers so mounted apps call the right URL.`,\n `If the user's prompt mentions sibling apps like Mail, Calendar, Assets, Brain, Dispatch, or other templates, treat them as existing workspace neighbors or integrations. Do not scaffold those sibling apps inside apps/${input.appId} unless the user explicitly asks to create them too.`,\n `Do not satisfy this by adding a route, page, component, or file inside apps/starter or another existing app unless the user explicitly asks to modify that existing app.`,\n `Use relative workspace links like /${input.appId}. Do not hardcode localhost, 127.0.0.1, 8080, 8100, or any dev port; the active workspace gateway/browser origin owns the port.`,\n `Use the framework/template UI stack: shadcn/ui components and @tabler/icons-react. Do not add lucide-react or another icon library for standard UI.`,\n `Ensure the React Router client entry preserves APP_BASE_PATH/VITE_APP_BASE_PATH via appBasePath().`,\n input.vaultAccessMode === \"all-apps\"\n ? `Do not create per-app Dispatch vault grants unless the workspace switches vault access to manual or the user explicitly asks for manual grants.`\n : keyList\n ? `After the app exists, grant the selected Dispatch vault keys to appId \"${input.appId}\" and sync them once the app server is available. Treat these as requested grants, not active grants before creation succeeds.`\n : `Do not grant any Dispatch vault keys unless the user asks later.`,\n input.selectedResources.length\n ? `After the app exists, grant the selected Dispatch workspace resources to appId \"${input.appId}\". Do not sync all-app workspace resources; they are inherited.`\n : `Do not grant any selected-only Dispatch workspace resources unless the user asks later.`,\n ``,\n `App readiness requirements before handing off:`,\n `- Ensure apps/${input.appId}/package.json exists with displayName/name and a concise description so Dispatch and the workspace gateway discover it from the filesystem. There is no separate workspace app registry to edit.`,\n `- Update the app manifest/package/deploy metadata needed by the existing workspace deployment model; do not leave the app relying only on local discovery.`,\n `- Verify the app's agent card/A2A metadata is ready so Dispatch can discover and delegate to the app after deployment. Every sibling workspace app is available over A2A by default through call-agent, with names and descriptions from the workspace app registry.`,\n `- Include a final verification note covering filesystem discovery, manifest/deploy metadata, relative same-origin routing, and agent-card readiness.`,\n `When it is ready, start or update the workspace dev server and navigate the user to /${input.appId}.`,\n ].join(\"\\n\");\n}\n\nexport function NewWorkspaceAppFlow({\n sourceApp = \"starter\",\n className = \"\",\n dispatchBasePath,\n}: NewWorkspaceAppFlowProps) {\n const [selectedSecretIds, setSelectedSecretIds] = useState<string[]>([]);\n const [selectedResourceIds, setSelectedResourceIds] = useState<string[]>([]);\n const [secrets, setSecrets] = useState<VaultSecretOption[]>([]);\n const [resources, setResources] = useState<WorkspaceResourceOption[]>([]);\n const [vaultAccessMode, setVaultAccessMode] =\n useState<VaultAccessMode>(\"all-apps\");\n const [secretsError, setSecretsError] = useState<string | null>(null);\n const [resourcesError, setResourcesError] = useState<string | null>(null);\n const [statusMessage, setStatusMessage] = useState<string | null>(null);\n const [branchUrl, setBranchUrl] = useState<string | null>(null);\n const [isSubmitting, setIsSubmitting] = useState(false);\n const { isDevMode } = useDevMode();\n\n const effectiveDispatchBasePath =\n dispatchBasePath === undefined\n ? defaultDispatchBasePath(sourceApp)\n : dispatchBasePath;\n\n useEffect(() => {\n let cancelled = false;\n const secretsUrl = actionUrl(\n effectiveDispatchBasePath,\n \"list-vault-secret-options\",\n );\n const vaultAccessUrl = actionUrl(\n effectiveDispatchBasePath,\n \"get-vault-access-settings\",\n );\n const resourcesUrl = actionUrl(\n effectiveDispatchBasePath,\n \"list-workspace-resource-options\",\n );\n\n fetchJson(secretsUrl)\n .then((data) => {\n if (cancelled) return;\n setSecrets(Array.isArray(data) ? data : []);\n setSecretsError(null);\n })\n .catch((err) => {\n if (cancelled) return;\n setSecrets([]);\n setSecretsError(err?.message || \"Could not load Dispatch keys\");\n });\n\n fetchJson(vaultAccessUrl)\n .then((data) => {\n if (cancelled) return;\n setVaultAccessMode(data?.mode === \"manual\" ? \"manual\" : \"all-apps\");\n })\n .catch(() => {\n if (cancelled) return;\n setVaultAccessMode(\"manual\");\n });\n\n fetchJson(resourcesUrl)\n .then((data) => {\n if (cancelled) return;\n setResources(Array.isArray(data) ? data : []);\n setResourcesError(null);\n })\n .catch((err) => {\n if (cancelled) return;\n setResources([]);\n setResourcesError(err?.message || \"Could not load Dispatch resources\");\n });\n\n return () => {\n cancelled = true;\n };\n }, [effectiveDispatchBasePath]);\n\n const selectedSecrets = useMemo(\n () => secrets.filter((secret) => selectedSecretIds.includes(secret.id)),\n [secrets, selectedSecretIds],\n );\n const selectedResources = useMemo(\n () =>\n resources.filter((resource) => selectedResourceIds.includes(resource.id)),\n [resources, selectedResourceIds],\n );\n const selectedSecretLabel =\n vaultAccessMode === \"all-apps\"\n ? \"All keys included\"\n : selectedSecretIds.length === 0\n ? \"No keys selected\"\n : `${selectedSecretIds.length} key${selectedSecretIds.length === 1 ? \"\" : \"s\"} selected`;\n const selectedResourceLabel =\n selectedResourceIds.length === 0\n ? \"No resources selected\"\n : `${selectedResourceIds.length} resource${selectedResourceIds.length === 1 ? \"\" : \"s\"} selected`;\n\n async function submit(rawPrompt: string) {\n const prompt = rawPrompt.trim();\n if (!prompt || isSubmitting) return;\n const appId = titleFromPrompt(prompt);\n const validationError = getWorkspaceAppIdValidationError(appId);\n if (validationError) {\n setStatusMessage(validationError);\n return;\n }\n\n const message = buildNewWorkspaceAppPrompt({\n appId,\n prompt,\n selectedKeys:\n vaultAccessMode === \"manual\"\n ? selectedSecrets.map((s) => s.credentialKey)\n : [],\n selectedResources,\n vaultAccessMode,\n });\n setIsSubmitting(true);\n setStatusMessage(null);\n setBranchUrl(null);\n\n try {\n if (isInBuilderFrame()) {\n sendToAgentChat({ message, submit: true, type: \"code\" });\n setStatusMessage(\"Sent to Builder chat.\");\n } else if (isDevMode) {\n sendToAgentChat({ message, submit: true, type: \"code\", newTab: true });\n setStatusMessage(\"Sent to the local agent.\");\n } else {\n const result = await fetchJson(\n actionUrl(effectiveDispatchBasePath, \"start-workspace-app-creation\"),\n {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({\n prompt,\n appId,\n secretIds: vaultAccessMode === \"manual\" ? selectedSecretIds : [],\n resourceIds: selectedResourceIds,\n }),\n },\n );\n if (result?.mode === \"builder\") {\n setBranchUrl(result?.url || null);\n setStatusMessage(\"Builder branch created.\");\n } else {\n setStatusMessage(\n result?.message ||\n \"Builder app creation is coming soon here. Open this workspace in Builder to create an app from this prompt.\",\n );\n }\n }\n } catch (err: any) {\n setStatusMessage(err?.message || \"Could not start the new app flow.\");\n } finally {\n setIsSubmitting(false);\n }\n }\n\n function toggleSecret(id: string) {\n setSelectedSecretIds((current) =>\n current.includes(id)\n ? current.filter((existing) => existing !== id)\n : [...current, id],\n );\n }\n\n function toggleResource(id: string) {\n setSelectedResourceIds((current) =>\n current.includes(id)\n ? current.filter((existing) => existing !== id)\n : [...current, id],\n );\n }\n\n return (\n <section\n className={`mx-auto flex w-full max-w-5xl flex-col gap-5 px-4 py-6 ${className}`}\n >\n <div className=\"grid gap-5 lg:grid-cols-[minmax(0,1fr)_320px]\">\n <div className=\"flex flex-col gap-3\">\n <PromptComposer\n autoFocus\n disabled={isSubmitting}\n placeholder=\"Describe the app your teammate should be able to use...\"\n draftScope=\"dispatch:new-app\"\n preserveDraftOnSubmit\n onSubmit={(text) => submit(text)}\n />\n\n {statusMessage ? (\n <div className=\"rounded-md border border-border bg-muted/40 px-3 py-2 text-sm text-muted-foreground\">\n {statusMessage}\n {branchUrl ? (\n <a\n href={branchUrl}\n target=\"_blank\"\n rel=\"noreferrer\"\n className=\"ml-2 inline-flex items-center gap-1 font-medium text-foreground underline\"\n >\n Open branch <IconArrowUpRight className=\"h-3 w-3\" />\n </a>\n ) : null}\n </div>\n ) : null}\n </div>\n\n <aside className=\"overflow-hidden rounded-lg border border-border bg-card\">\n <div className=\"border-b border-border px-4 py-3\">\n <div className=\"flex items-center justify-between gap-3\">\n <div className=\"flex items-center gap-2 text-sm font-medium\">\n <IconKey className=\"h-4 w-4\" />\n Dispatch keys\n </div>\n <span className=\"shrink-0 rounded border border-border bg-background/40 px-2 py-0.5 text-[11px] text-muted-foreground\">\n {selectedSecretLabel}\n </span>\n </div>\n </div>\n <div className=\"max-h-[220px] space-y-2 overflow-y-auto p-3\">\n {vaultAccessMode === \"all-apps\" ? (\n <p className=\"rounded-md border border-dashed border-border px-3 py-3 text-xs text-muted-foreground\">\n Every saved Dispatch vault key is available to new apps.\n </p>\n ) : secretsError ? (\n <p className=\"rounded-md border border-dashed border-border px-3 py-3 text-xs text-muted-foreground\">\n {secretsError}\n </p>\n ) : secrets.length === 0 ? (\n <p className=\"rounded-md border border-dashed border-border px-3 py-3 text-xs text-muted-foreground\">\n No Dispatch vault keys found yet.\n </p>\n ) : (\n secrets.map((secret) => {\n const selected = selectedSecretIds.includes(secret.id);\n return (\n <div\n key={secret.id}\n className={`group rounded-md border text-sm transition ${\n selected\n ? \"border-primary/45 bg-primary/5 text-foreground shadow-[inset_0_0_0_1px_hsl(var(--primary)/0.08)]\"\n : \"border-border bg-background/25 text-foreground hover:border-muted-foreground/40 hover:bg-accent/35\"\n }`}\n >\n <button\n type=\"button\"\n aria-pressed={selected}\n onClick={() => toggleSecret(secret.id)}\n className=\"flex w-full cursor-pointer items-start gap-3 rounded-md px-3 py-2 text-left focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring/30\"\n >\n <span\n className={`mt-0.5 flex h-4 w-4 shrink-0 items-center justify-center rounded border transition ${\n selected\n ? \"border-primary/60 bg-primary/10 text-primary\"\n : \"border-muted-foreground/35 text-transparent group-hover:border-muted-foreground/60\"\n }`}\n >\n {selected ? <IconCheck className=\"h-3 w-3\" /> : null}\n </span>\n <span className=\"min-w-0 flex-1\">\n <span className=\"block truncate font-medium\">\n {secret.credentialKey}\n </span>\n <span className=\"block truncate text-xs text-muted-foreground/70\">\n {selected\n ? \"Will be requested for this app\"\n : \"Click to request\"}\n </span>\n </span>\n </button>\n <details className=\"group/details border-t border-border/60 px-3 py-1.5 text-xs text-muted-foreground/75 open:bg-background/10\">\n <summary className=\"flex cursor-pointer list-none items-center gap-1.5 text-[11px] hover:text-muted-foreground [&::-webkit-details-marker]:hidden\">\n <IconChevronDown className=\"h-3 w-3 transition-transform group-open/details:rotate-180\" />\n Details\n </summary>\n <div className=\"mt-1.5 space-y-1 pb-0.5 pl-4\">\n <div className=\"truncate\">\n Provider: {secret.provider || \"Not specified\"}\n </div>\n <div className=\"truncate\">Name: {secret.name}</div>\n </div>\n </details>\n </div>\n );\n })\n )}\n </div>\n\n <div className=\"border-y border-border px-4 py-3\">\n <div className=\"flex items-center justify-between gap-3\">\n <div className=\"flex items-center gap-2 text-sm font-medium\">\n <IconBook className=\"h-4 w-4\" />\n Resource packs\n </div>\n <span className=\"shrink-0 rounded border border-border bg-background/40 px-2 py-0.5 text-[11px] text-muted-foreground\">\n {selectedResourceLabel}\n </span>\n </div>\n </div>\n <div className=\"max-h-[220px] space-y-2 overflow-y-auto p-3\">\n {resourcesError ? (\n <p className=\"rounded-md border border-dashed border-border px-3 py-3 text-xs text-muted-foreground\">\n {resourcesError}\n </p>\n ) : resources.length === 0 ? (\n <p className=\"rounded-md border border-dashed border-border px-3 py-3 text-xs text-muted-foreground\">\n No Dispatch resource packs found yet.\n </p>\n ) : (\n resources.map((resource) => {\n const selected = selectedResourceIds.includes(resource.id);\n return (\n <div\n key={resource.id}\n className={`group rounded-md border text-sm transition ${\n selected\n ? \"border-primary/45 bg-primary/5 text-foreground shadow-[inset_0_0_0_1px_hsl(var(--primary)/0.08)]\"\n : \"border-border bg-background/25 text-foreground hover:border-muted-foreground/40 hover:bg-accent/35\"\n }`}\n >\n <button\n type=\"button\"\n aria-pressed={selected}\n onClick={() => toggleResource(resource.id)}\n className=\"flex w-full cursor-pointer items-start gap-3 rounded-md px-3 py-2 text-left focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring/30\"\n >\n <span\n className={`mt-0.5 flex h-4 w-4 shrink-0 items-center justify-center rounded border transition ${\n selected\n ? \"border-primary/60 bg-primary/10 text-primary\"\n : \"border-muted-foreground/35 text-transparent group-hover:border-muted-foreground/60\"\n }`}\n >\n {selected ? <IconCheck className=\"h-3 w-3\" /> : null}\n </span>\n <span className=\"min-w-0 flex-1\">\n <span className=\"flex min-w-0 items-center gap-1.5\">\n <IconFileText className=\"h-3.5 w-3.5 shrink-0 text-muted-foreground/70\" />\n <span className=\"block truncate font-medium\">\n {resource.name}\n </span>\n </span>\n <span className=\"block truncate text-xs text-muted-foreground/70\">\n {resource.kind} · {resource.path}\n </span>\n </span>\n </button>\n <details className=\"group/details border-t border-border/60 px-3 py-1.5 text-xs text-muted-foreground/75 open:bg-background/10\">\n <summary className=\"flex cursor-pointer list-none items-center gap-1.5 text-[11px] hover:text-muted-foreground [&::-webkit-details-marker]:hidden\">\n <IconChevronDown className=\"h-3 w-3 transition-transform group-open/details:rotate-180\" />\n Details\n </summary>\n <div className=\"mt-1.5 space-y-1 pb-0.5 pl-4\">\n <div className=\"truncate\">\n Scope:{\" \"}\n {resource.scope === \"all\"\n ? \"All apps\"\n : \"Selected apps\"}\n </div>\n {resource.description ? (\n <div className=\"line-clamp-2\">\n {resource.description}\n </div>\n ) : null}\n </div>\n </details>\n </div>\n );\n })\n )}\n </div>\n </aside>\n </div>\n </section>\n );\n}\n"]}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { BlockAiFieldActionProps, BlockRenderContext } from "./types.js";
|
|
2
|
+
export declare function AiEditableFieldLabel({ htmlFor, label, ctx, action, }: {
|
|
3
|
+
htmlFor: string;
|
|
4
|
+
label: string;
|
|
5
|
+
ctx: BlockRenderContext;
|
|
6
|
+
action?: Omit<BlockAiFieldActionProps, "fieldLabel">;
|
|
7
|
+
}): import("react/jsx-runtime").JSX.Element;
|
|
8
|
+
//# sourceMappingURL=AiEditableField.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AiEditableField.d.ts","sourceRoot":"","sources":["../../../src/client/blocks/AiEditableField.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,uBAAuB,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAE9E,wBAAgB,oBAAoB,CAAC,EACnC,OAAO,EACP,KAAK,EACL,GAAG,EACH,MAAM,GACP,EAAE;IACD,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,kBAAkB,CAAC;IACxB,MAAM,CAAC,EAAE,IAAI,CAAC,uBAAuB,EAAE,YAAY,CAAC,CAAC;CACtD,2CAiBA"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
export function AiEditableFieldLabel({ htmlFor, label, ctx, action, }) {
|
|
3
|
+
return (_jsxs("div", { className: "sticky top-0 z-10 flex items-center justify-between gap-3 bg-background/95 py-1 backdrop-blur supports-[backdrop-filter]:bg-background/80", children: [_jsx("label", { htmlFor: htmlFor, className: "text-xs font-semibold text-muted-foreground", children: label }), action
|
|
4
|
+
? ctx.renderAiFieldAction?.({
|
|
5
|
+
...action,
|
|
6
|
+
fieldLabel: label,
|
|
7
|
+
})
|
|
8
|
+
: null] }));
|
|
9
|
+
}
|
|
10
|
+
//# sourceMappingURL=AiEditableField.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AiEditableField.js","sourceRoot":"","sources":["../../../src/client/blocks/AiEditableField.tsx"],"names":[],"mappings":";AAEA,MAAM,UAAU,oBAAoB,CAAC,EACnC,OAAO,EACP,KAAK,EACL,GAAG,EACH,MAAM,GAMP;IACC,OAAO,CACL,eAAK,SAAS,EAAC,2IAA2I,aACxJ,gBACE,OAAO,EAAE,OAAO,EAChB,SAAS,EAAC,6CAA6C,YAEtD,KAAK,GACA,EACP,MAAM;gBACL,CAAC,CAAC,GAAG,CAAC,mBAAmB,EAAE,CAAC;oBACxB,GAAG,MAAM;oBACT,UAAU,EAAE,KAAK;iBAClB,CAAC;gBACJ,CAAC,CAAC,IAAI,IACJ,CACP,CAAC;AACJ,CAAC","sourcesContent":["import type { BlockAiFieldActionProps, BlockRenderContext } from \"./types.js\";\n\nexport function AiEditableFieldLabel({\n htmlFor,\n label,\n ctx,\n action,\n}: {\n htmlFor: string;\n label: string;\n ctx: BlockRenderContext;\n action?: Omit<BlockAiFieldActionProps, \"fieldLabel\">;\n}) {\n return (\n <div className=\"sticky top-0 z-10 flex items-center justify-between gap-3 bg-background/95 py-1 backdrop-blur supports-[backdrop-filter]:bg-background/80\">\n <label\n htmlFor={htmlFor}\n className=\"text-xs font-semibold text-muted-foreground\"\n >\n {label}\n </label>\n {action\n ? ctx.renderAiFieldAction?.({\n ...action,\n fieldLabel: label,\n })\n : null}\n </div>\n );\n}\n"]}
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import type { BlockSpec, BlockRenderContext } from "./types.js";
|
|
1
|
+
import type { BlockDataChangeMeta, BlockSpec, BlockRenderContext } from "./types.js";
|
|
2
2
|
/**
|
|
3
3
|
* Resolve a spec's effective edit surface. Defaults to `"inline"` when the block
|
|
4
4
|
* ships a custom `Edit` (its author built direct-manipulation editing), else
|
|
5
5
|
* `"panel"` — an auto-form block is a property form, which reads best behind a
|
|
6
6
|
* corner edit button. An explicit `spec.editSurface` always wins.
|
|
7
7
|
*/
|
|
8
|
-
export declare function blockEditSurface(spec: BlockSpec<any>): "inline" | "panel";
|
|
8
|
+
export declare function blockEditSurface(spec: BlockSpec<any>): "inline" | "panel" | "container";
|
|
9
9
|
/**
|
|
10
10
|
* Render one registered block. In read mode (or when the spec is inline-only and
|
|
11
11
|
* not editing) it renders the spec's `Read`. In edit mode for a `block`-placed
|
|
@@ -29,7 +29,7 @@ export declare function BlockView({ spec, block, editing, editable, onChange, ct
|
|
|
29
29
|
/** Whether this specific block allows editing (block.editable !== false). */
|
|
30
30
|
editable?: boolean;
|
|
31
31
|
/** Commit a new `data` value for the block. */
|
|
32
|
-
onChange?: (nextData: unknown) => void;
|
|
32
|
+
onChange?: (nextData: unknown, meta?: BlockDataChangeMeta) => void;
|
|
33
33
|
ctx: BlockRenderContext;
|
|
34
34
|
}): import("react/jsx-runtime").JSX.Element;
|
|
35
35
|
//# sourceMappingURL=BlockView.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BlockView.d.ts","sourceRoot":"","sources":["../../../src/client/blocks/BlockView.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"BlockView.d.ts","sourceRoot":"","sources":["../../../src/client/blocks/BlockView.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,mBAAmB,EACnB,SAAS,EACT,kBAAkB,EACnB,MAAM,YAAY,CAAC;AAGpB;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAC9B,IAAI,EAAE,SAAS,CAAC,GAAG,CAAC,GACnB,QAAQ,GAAG,OAAO,GAAG,WAAW,CAElC;AAED;;;;;;;;;GASG;AACH,wBAAgB,SAAS,CAAC,EACxB,IAAI,EACJ,KAAK,EACL,OAAO,EACP,QAAe,EACf,QAAQ,EACR,GAAG,GACJ,EAAE;IACD,IAAI,EAAE,SAAS,CAAC,GAAG,CAAC,CAAC;IACrB,KAAK,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,OAAO,CAAA;KAAE,CAAC;IACvE,yDAAyD;IACzD,OAAO,EAAE,OAAO,CAAC;IACjB,6EAA6E;IAC7E,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,+CAA+C;IAC/C,QAAQ,CAAC,EAAE,CAAC,QAAQ,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE,mBAAmB,KAAK,IAAI,CAAC;IACnE,GAAG,EAAE,kBAAkB,CAAC;CACzB,2CA0FA"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useState } from "react";
|
|
2
3
|
import { IconPencil } from "@tabler/icons-react";
|
|
3
4
|
import { SchemaBlockEditor } from "./SchemaBlockEditor.js";
|
|
4
5
|
/**
|
|
@@ -21,21 +22,32 @@ export function blockEditSurface(spec) {
|
|
|
21
22
|
* recognizes a block type — the legacy switch handles unregistered types.
|
|
22
23
|
*/
|
|
23
24
|
export function BlockView({ spec, block, editing, editable = true, onChange, ctx, }) {
|
|
25
|
+
const [panelHovered, setPanelHovered] = useState(false);
|
|
24
26
|
const Read = spec.Read;
|
|
25
27
|
const readNode = (_jsx(Read, { data: block.data, blockId: block.id, title: block.title, summary: block.summary, ctx: ctx }));
|
|
26
28
|
const canEdit = editing && editable && spec.placement.includes("block") && !!onChange;
|
|
27
29
|
if (!canEdit)
|
|
28
30
|
return readNode;
|
|
29
|
-
const commit = (nextData) => onChange?.(nextData);
|
|
31
|
+
const commit = (nextData, meta) => onChange?.(nextData, meta);
|
|
32
|
+
const updatePanelHover = (event) => {
|
|
33
|
+
const target = event.target;
|
|
34
|
+
setPanelHovered(target instanceof HTMLElement &&
|
|
35
|
+
target.closest(".an-block-panel") === event.currentTarget);
|
|
36
|
+
};
|
|
30
37
|
const Edit = spec.Edit;
|
|
31
38
|
const formNode = Edit ? (_jsx(Edit, { data: block.data, onChange: commit, editable: true, blockId: block.id, title: block.title, summary: block.summary, ctx: ctx })) : (_jsx(SchemaBlockEditor, { data: block.data, onChange: commit, schema: spec.schema, editable: true, blockId: block.id, ctx: ctx }));
|
|
32
39
|
// Panel mode: show the rendered block with a corner edit button that opens the
|
|
33
40
|
// form in the app-provided panel (popover). Falls back to inline editing when
|
|
34
41
|
// the app hasn't wired `renderEditSurface`.
|
|
35
42
|
if (blockEditSurface(spec) === "panel" && ctx.renderEditSurface) {
|
|
36
|
-
return (_jsxs("div", { className: "an-block-panel
|
|
43
|
+
return (_jsxs("div", { className: "an-block-panel relative", onMouseEnter: updatePanelHover, onMouseMove: updatePanelHover, onMouseLeave: () => setPanelHovered(false), children: [readNode, _jsx("div", { className: "an-block-panel__edit absolute right-2 top-2 z-10", children: ctx.renderEditSurface({
|
|
37
44
|
title: spec.label,
|
|
38
|
-
|
|
45
|
+
blockId: block.id,
|
|
46
|
+
blockType: spec.type,
|
|
47
|
+
blockTitle: block.title,
|
|
48
|
+
blockSummary: block.summary,
|
|
49
|
+
blockData: block.data,
|
|
50
|
+
trigger: (_jsx("button", { type: "button", "data-plan-interactive": true, "aria-label": `Edit ${spec.label}`, className: "an-block-edit-trigger flex size-7 items-center justify-center rounded-md text-muted-foreground opacity-0 transition-[color,opacity] hover:text-foreground focus-visible:opacity-100 focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring data-[visible=true]:opacity-100", "data-visible": panelHovered, children: _jsx(IconPencil, { className: "size-4" }) })),
|
|
39
51
|
children: formNode,
|
|
40
52
|
}) })] }));
|
|
41
53
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BlockView.js","sourceRoot":"","sources":["../../../src/client/blocks/BlockView.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"BlockView.js","sourceRoot":"","sources":["../../../src/client/blocks/BlockView.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,QAAQ,EAAsC,MAAM,OAAO,CAAC;AACrE,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAMjD,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAE3D;;;;;GAKG;AACH,MAAM,UAAU,gBAAgB,CAC9B,IAAoB;IAEpB,OAAO,IAAI,CAAC,WAAW,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC;AAC9D,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,UAAU,SAAS,CAAC,EACxB,IAAI,EACJ,KAAK,EACL,OAAO,EACP,QAAQ,GAAG,IAAI,EACf,QAAQ,EACR,GAAG,GAWJ;IACC,MAAM,CAAC,YAAY,EAAE,eAAe,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;IACxD,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC;IACvB,MAAM,QAAQ,GAAG,CACf,KAAC,IAAI,IACH,IAAI,EAAE,KAAK,CAAC,IAAI,EAChB,OAAO,EAAE,KAAK,CAAC,EAAE,EACjB,KAAK,EAAE,KAAK,CAAC,KAAK,EAClB,OAAO,EAAE,KAAK,CAAC,OAAO,EACtB,GAAG,EAAE,GAAG,GACR,CACH,CAAC;IAEF,MAAM,OAAO,GACX,OAAO,IAAI,QAAQ,IAAI,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC;IAExE,IAAI,CAAC,OAAO;QAAE,OAAO,QAAQ,CAAC;IAE9B,MAAM,MAAM,GAAG,CAAC,QAAiB,EAAE,IAA0B,EAAE,EAAE,CAC/D,QAAQ,EAAE,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;IAC7B,MAAM,gBAAgB,GAAG,CAAC,KAAmC,EAAE,EAAE;QAC/D,MAAM,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC;QAC5B,eAAe,CACb,MAAM,YAAY,WAAW;YAC3B,MAAM,CAAC,OAAO,CAAC,iBAAiB,CAAC,KAAK,KAAK,CAAC,aAAa,CAC5D,CAAC;IACJ,CAAC,CAAC;IAEF,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC;IACvB,MAAM,QAAQ,GAAG,IAAI,CAAC,CAAC,CAAC,CACtB,KAAC,IAAI,IACH,IAAI,EAAE,KAAK,CAAC,IAAI,EAChB,QAAQ,EAAE,MAAM,EAChB,QAAQ,QACR,OAAO,EAAE,KAAK,CAAC,EAAE,EACjB,KAAK,EAAE,KAAK,CAAC,KAAK,EAClB,OAAO,EAAE,KAAK,CAAC,OAAO,EACtB,GAAG,EAAE,GAAG,GACR,CACH,CAAC,CAAC,CAAC,CACF,KAAC,iBAAiB,IAChB,IAAI,EAAE,KAAK,CAAC,IAAI,EAChB,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,IAAI,CAAC,MAAM,EACnB,QAAQ,QACR,OAAO,EAAE,KAAK,CAAC,EAAE,EACjB,GAAG,EAAE,GAAG,GACR,CACH,CAAC;IAEF,+EAA+E;IAC/E,8EAA8E;IAC9E,4CAA4C;IAC5C,IAAI,gBAAgB,CAAC,IAAI,CAAC,KAAK,OAAO,IAAI,GAAG,CAAC,iBAAiB,EAAE,CAAC;QAChE,OAAO,CACL,eACE,SAAS,EAAC,yBAAyB,EACnC,YAAY,EAAE,gBAAgB,EAC9B,WAAW,EAAE,gBAAgB,EAC7B,YAAY,EAAE,GAAG,EAAE,CAAC,eAAe,CAAC,KAAK,CAAC,aAEzC,QAAQ,EACT,cAAK,SAAS,EAAC,kDAAkD,YAC9D,GAAG,CAAC,iBAAiB,CAAC;wBACrB,KAAK,EAAE,IAAI,CAAC,KAAK;wBACjB,OAAO,EAAE,KAAK,CAAC,EAAE;wBACjB,SAAS,EAAE,IAAI,CAAC,IAAI;wBACpB,UAAU,EAAE,KAAK,CAAC,KAAK;wBACvB,YAAY,EAAE,KAAK,CAAC,OAAO;wBAC3B,SAAS,EAAE,KAAK,CAAC,IAAI;wBACrB,OAAO,EAAE,CACP,iBACE,IAAI,EAAC,QAAQ,+CAED,QAAQ,IAAI,CAAC,KAAK,EAAE,EAChC,SAAS,EAAC,6RAA6R,kBACzR,YAAY,YAE1B,KAAC,UAAU,IAAC,SAAS,EAAC,QAAQ,GAAG,GAC1B,CACV;wBACD,QAAQ,EAAE,QAAQ;qBACnB,CAAC,GACE,IACF,CACP,CAAC;IACJ,CAAC;IAED,qCAAqC;IACrC,OAAO,QAAQ,CAAC;AAClB,CAAC","sourcesContent":["import { useState, type MouseEvent as ReactMouseEvent } from \"react\";\nimport { IconPencil } from \"@tabler/icons-react\";\nimport type {\n BlockDataChangeMeta,\n BlockSpec,\n BlockRenderContext,\n} from \"./types.js\";\nimport { SchemaBlockEditor } from \"./SchemaBlockEditor.js\";\n\n/**\n * Resolve a spec's effective edit surface. Defaults to `\"inline\"` when the block\n * ships a custom `Edit` (its author built direct-manipulation editing), else\n * `\"panel\"` — an auto-form block is a property form, which reads best behind a\n * corner edit button. An explicit `spec.editSurface` always wins.\n */\nexport function blockEditSurface(\n spec: BlockSpec<any>,\n): \"inline\" | \"panel\" | \"container\" {\n return spec.editSurface ?? (spec.Edit ? \"inline\" : \"panel\");\n}\n\n/**\n * Render one registered block. In read mode (or when the spec is inline-only and\n * not editing) it renders the spec's `Read`. In edit mode for a `block`-placed\n * spec it renders the editor — either inline (the spec's `Edit` or the\n * schema-driven {@link SchemaBlockEditor}) or, for `editSurface: \"panel\"` blocks,\n * the rendered `Read` plus a corner edit button that opens that editor in the\n * app-provided panel ({@link BlockRenderContext.renderEditSurface}, e.g. a\n * popover). This is what the app renderer delegates to once the registry\n * recognizes a block type — the legacy switch handles unregistered types.\n */\nexport function BlockView({\n spec,\n block,\n editing,\n editable = true,\n onChange,\n ctx,\n}: {\n spec: BlockSpec<any>;\n block: { id: string; title?: string; summary?: string; data: unknown };\n /** Whether the document is in an editable/edit state. */\n editing: boolean;\n /** Whether this specific block allows editing (block.editable !== false). */\n editable?: boolean;\n /** Commit a new `data` value for the block. */\n onChange?: (nextData: unknown, meta?: BlockDataChangeMeta) => void;\n ctx: BlockRenderContext;\n}) {\n const [panelHovered, setPanelHovered] = useState(false);\n const Read = spec.Read;\n const readNode = (\n <Read\n data={block.data}\n blockId={block.id}\n title={block.title}\n summary={block.summary}\n ctx={ctx}\n />\n );\n\n const canEdit =\n editing && editable && spec.placement.includes(\"block\") && !!onChange;\n\n if (!canEdit) return readNode;\n\n const commit = (nextData: unknown, meta?: BlockDataChangeMeta) =>\n onChange?.(nextData, meta);\n const updatePanelHover = (event: ReactMouseEvent<HTMLElement>) => {\n const target = event.target;\n setPanelHovered(\n target instanceof HTMLElement &&\n target.closest(\".an-block-panel\") === event.currentTarget,\n );\n };\n\n const Edit = spec.Edit;\n const formNode = Edit ? (\n <Edit\n data={block.data}\n onChange={commit}\n editable\n blockId={block.id}\n title={block.title}\n summary={block.summary}\n ctx={ctx}\n />\n ) : (\n <SchemaBlockEditor\n data={block.data}\n onChange={commit}\n schema={spec.schema}\n editable\n blockId={block.id}\n ctx={ctx}\n />\n );\n\n // Panel mode: show the rendered block with a corner edit button that opens the\n // form in the app-provided panel (popover). Falls back to inline editing when\n // the app hasn't wired `renderEditSurface`.\n if (blockEditSurface(spec) === \"panel\" && ctx.renderEditSurface) {\n return (\n <div\n className=\"an-block-panel relative\"\n onMouseEnter={updatePanelHover}\n onMouseMove={updatePanelHover}\n onMouseLeave={() => setPanelHovered(false)}\n >\n {readNode}\n <div className=\"an-block-panel__edit absolute right-2 top-2 z-10\">\n {ctx.renderEditSurface({\n title: spec.label,\n blockId: block.id,\n blockType: spec.type,\n blockTitle: block.title,\n blockSummary: block.summary,\n blockData: block.data,\n trigger: (\n <button\n type=\"button\"\n data-plan-interactive\n aria-label={`Edit ${spec.label}`}\n className=\"an-block-edit-trigger flex size-7 items-center justify-center rounded-md text-muted-foreground opacity-0 transition-[color,opacity] hover:text-foreground focus-visible:opacity-100 focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring data-[visible=true]:opacity-100\"\n data-visible={panelHovered}\n >\n <IconPencil className=\"size-4\" />\n </button>\n ),\n children: formNode,\n })}\n </div>\n </div>\n );\n }\n\n // Inline mode (direct manipulation).\n return formNode;\n}\n"]}
|
|
@@ -31,8 +31,8 @@ export function SchemaBlockEditor({ data, onChange, schema, editable, blockId, c
|
|
|
31
31
|
const optional = fields.filter((field) => field.optional);
|
|
32
32
|
return (_jsxs("div", { className: "an-schema-block-editor flex flex-col gap-3", children: [required.map((field) => (_jsx(FieldControl, { field: field, value: data[field.key], onChange: (value) => setField(field.key, value), editable: editable, blockId: blockId, ctx: ctx }, field.key))), optional.length > 0 && (_jsx("div", { className: "flex flex-col gap-3", children: showOptional ? (optional.map((field) => (_jsx(FieldControl, { field: field, value: data[field.key], onChange: (value) => setField(field.key, value), editable: editable, blockId: blockId, ctx: ctx }, field.key)))) : (_jsx("button", { type: "button", "data-plan-interactive": true, className: "self-start text-sm text-muted-foreground underline-offset-2 hover:underline", onClick: () => setShowOptional(true), children: "More options" })) }))] }));
|
|
33
33
|
}
|
|
34
|
-
const inputClass = "flex h-9 w-full rounded-md border border-input bg-transparent px-3 py-1 text-sm
|
|
35
|
-
const textareaClass = "flex min-h-[80px] w-full rounded-md border border-input bg-transparent px-3 py-2 text-sm
|
|
34
|
+
const inputClass = "flex h-9 w-full rounded-md border border-input bg-transparent px-3 py-1 text-sm transition-colors placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50";
|
|
35
|
+
const textareaClass = "flex min-h-[80px] w-full rounded-md border border-input bg-transparent px-3 py-2 text-sm placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50";
|
|
36
36
|
function FieldLabel({ children }) {
|
|
37
37
|
return (_jsx("span", { className: "text-xs font-medium text-muted-foreground", children: children }));
|
|
38
38
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SchemaBlockEditor.js","sourceRoot":"","sources":["../../../src/client/blocks/SchemaBlockEditor.tsx"],"names":[],"mappings":"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","sourcesContent":["import { useMemo, useState } from \"react\";\nimport type { ZodType } from \"zod\";\nimport { IconPlus, IconTrash } from \"@tabler/icons-react\";\nimport { cn } from \"../utils.js\";\nimport type { BlockRenderContext } from \"./types.js\";\nimport { introspect, type FieldDescriptor } from \"./schema-form/introspect.js\";\n\n/**\n * Schema-driven auto-editor. When a {@link BlockSpec} omits `Edit`, the registry\n * renders this: it walks the block's zod `data` schema and renders one control\n * per field (string → input, longtext → textarea, number, boolean → toggle,\n * enum → native select, array → repeating rows, object → nested fieldset). A\n * `markdown()`-tagged string field defers to the app-provided inline rich\n * editor via `ctx.renderMarkdownEditor` so prose stays Notion-editable.\n *\n * It uses plain accessible native controls (not template shadcn primitives,\n * which core does not bundle) styled to match the shadcn look. Validation runs\n * the spec's own schema on every edit; the raw edit is kept in local state so a\n * transiently-invalid value (e.g. mid-typing) doesn't get rolled back, and only\n * valid data is committed upstream.\n */\nexport function SchemaBlockEditor<T>({\n data,\n onChange,\n schema,\n editable,\n blockId,\n ctx,\n}: {\n data: T;\n onChange: (next: T) => void;\n schema: ZodType<T>;\n editable: boolean;\n blockId?: string;\n ctx: BlockRenderContext;\n}) {\n const fields = useMemo(() => introspect(schema), [schema]);\n const [showOptional, setShowOptional] = useState(false);\n\n const setField = (key: string, value: unknown) => {\n const next = { ...(data as Record<string, unknown>), [key]: value } as T;\n const parsed = schema.safeParse(next);\n // Commit valid data; otherwise pass the raw edit through so the user can\n // keep typing — the upstream owner re-validates before persisting.\n onChange((parsed.success ? parsed.data : next) as T);\n };\n\n const required = fields.filter((field) => !field.optional);\n const optional = fields.filter((field) => field.optional);\n\n return (\n <div className=\"an-schema-block-editor flex flex-col gap-3\">\n {required.map((field) => (\n <FieldControl\n key={field.key}\n field={field}\n value={(data as Record<string, unknown>)[field.key]}\n onChange={(value) => setField(field.key, value)}\n editable={editable}\n blockId={blockId}\n ctx={ctx}\n />\n ))}\n {optional.length > 0 && (\n <div className=\"flex flex-col gap-3\">\n {showOptional ? (\n optional.map((field) => (\n <FieldControl\n key={field.key}\n field={field}\n value={(data as Record<string, unknown>)[field.key]}\n onChange={(value) => setField(field.key, value)}\n editable={editable}\n blockId={blockId}\n ctx={ctx}\n />\n ))\n ) : (\n <button\n type=\"button\"\n data-plan-interactive\n className=\"self-start text-sm text-muted-foreground underline-offset-2 hover:underline\"\n onClick={() => setShowOptional(true)}\n >\n More options\n </button>\n )}\n </div>\n )}\n </div>\n );\n}\n\nconst inputClass =\n \"flex h-9 w-full rounded-md border border-input bg-transparent px-3 py-1 text-sm shadow-sm transition-colors placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50\";\n\nconst textareaClass =\n \"flex min-h-[80px] w-full rounded-md border border-input bg-transparent px-3 py-2 text-sm shadow-sm placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50\";\n\nfunction FieldLabel({ children }: { children: React.ReactNode }) {\n return (\n <span className=\"text-xs font-medium text-muted-foreground\">\n {children}\n </span>\n );\n}\n\n/** A sensible empty value for a single field, used when adding array items. */\nfunction emptyForField(field: FieldDescriptor): unknown {\n switch (field.kind) {\n case \"text\":\n // A field literally named `id` gets a fresh stable id so new rows are\n // distinguishable without the user having to type one.\n return field.key === \"id\"\n ? `item-${Math.random().toString(36).slice(2, 10)}`\n : \"\";\n case \"longtext\":\n case \"markdown\":\n case \"richtext\":\n return \"\";\n case \"boolean\":\n return false;\n case \"enum\":\n return field.enumValues?.[0];\n case \"array\":\n return [];\n case \"object\":\n return emptyObjectFromFields(field.fields);\n case \"number\":\n default:\n // number → undefined (the input shows blank until the user types); any\n // unsupported kind also defaults to undefined.\n return undefined;\n }\n}\n\n/** Build an empty object value from a descriptor's child fields. */\nfunction emptyObjectFromFields(\n fields: FieldDescriptor[] | undefined,\n): Record<string, unknown> {\n const result: Record<string, unknown> = {};\n for (const child of fields ?? []) {\n result[child.key] = emptyForField(child);\n }\n return result;\n}\n\n/** A scalar element kind classified from an array's inner element schema. */\nfunction scalarKindFromInner(\n inner: FieldDescriptor[\"inner\"],\n): \"number\" | \"boolean\" | \"text\" {\n const type = (inner?._def as { type?: string } | undefined)?.type;\n if (type === \"number\" || type === \"bigint\") return \"number\";\n if (type === \"boolean\") return \"boolean\";\n return \"text\";\n}\n\n/** An empty value for a scalar array element of the given kind. */\nfunction emptyScalar(kind: \"number\" | \"boolean\" | \"text\"): unknown {\n if (kind === \"boolean\") return false;\n if (kind === \"number\") return undefined;\n return \"\";\n}\n\nfunction FieldControl({\n field,\n value,\n onChange,\n editable,\n blockId,\n ctx,\n}: {\n field: FieldDescriptor;\n value: unknown;\n onChange: (value: unknown) => void;\n editable: boolean;\n blockId?: string;\n ctx: BlockRenderContext;\n}) {\n if (field.kind === \"markdown\" || field.kind === \"richtext\") {\n const node = ctx.renderMarkdownEditor?.({\n value: typeof value === \"string\" ? value : \"\",\n onChange: (next) => onChange(next),\n editable,\n blockId,\n });\n return (\n <label className=\"flex flex-col gap-1.5\">\n <FieldLabel>{field.label}</FieldLabel>\n {node ?? (\n // Fallback when no app markdown editor is injected: a plain textarea.\n <textarea\n data-plan-interactive\n className={textareaClass}\n value={typeof value === \"string\" ? value : \"\"}\n disabled={!editable}\n onChange={(event) => onChange(event.target.value)}\n />\n )}\n </label>\n );\n }\n\n if (field.kind === \"boolean\") {\n return (\n <label className=\"flex items-center gap-2\">\n <input\n type=\"checkbox\"\n data-plan-interactive\n className=\"size-4 rounded border-input accent-primary\"\n checked={Boolean(value)}\n disabled={!editable}\n onChange={(event) => onChange(event.target.checked)}\n />\n <FieldLabel>{field.label}</FieldLabel>\n </label>\n );\n }\n\n if (field.kind === \"enum\") {\n const options = field.enumValues ?? [];\n return (\n <label className=\"flex flex-col gap-1.5\">\n <FieldLabel>{field.label}</FieldLabel>\n <select\n data-plan-interactive\n className={inputClass}\n value={typeof value === \"string\" ? value : \"\"}\n disabled={!editable}\n onChange={(event) => onChange(event.target.value || undefined)}\n >\n {field.optional && <option value=\"\">—</option>}\n {options.map((option) => (\n <option key={option} value={option}>\n {option}\n </option>\n ))}\n </select>\n </label>\n );\n }\n\n if (field.kind === \"number\") {\n return (\n <label className=\"flex flex-col gap-1.5\">\n <FieldLabel>{field.label}</FieldLabel>\n <input\n type=\"number\"\n data-plan-interactive\n className={inputClass}\n value={typeof value === \"number\" ? value : \"\"}\n disabled={!editable}\n onChange={(event) => {\n const raw = event.target.value;\n onChange(raw === \"\" ? undefined : Number(raw));\n }}\n />\n </label>\n );\n }\n\n if (field.kind === \"longtext\") {\n return (\n <label className=\"flex flex-col gap-1.5\">\n <FieldLabel>{field.label}</FieldLabel>\n <textarea\n data-plan-interactive\n className={textareaClass}\n value={typeof value === \"string\" ? value : \"\"}\n disabled={!editable}\n onChange={(event) => onChange(event.target.value)}\n />\n </label>\n );\n }\n\n if (field.kind === \"text\") {\n return (\n <label className=\"flex flex-col gap-1.5\">\n <FieldLabel>{field.label}</FieldLabel>\n <input\n type=\"text\"\n data-plan-interactive\n className={inputClass}\n value={typeof value === \"string\" ? value : \"\"}\n disabled={!editable}\n onChange={(event) => onChange(event.target.value)}\n />\n </label>\n );\n }\n\n if (field.kind === \"object\" && field.fields && field.fields.length > 0) {\n const objValue =\n value && typeof value === \"object\" && !Array.isArray(value)\n ? (value as Record<string, unknown>)\n : {};\n return (\n <div className=\"flex flex-col gap-3 rounded-md border border-input px-3 py-3\">\n <FieldLabel>{field.label}</FieldLabel>\n <div className=\"flex flex-col gap-3\">\n {field.fields.map((child) => (\n <FieldControl\n key={child.key}\n field={child}\n value={objValue[child.key]}\n onChange={(childVal) =>\n onChange({ ...objValue, [child.key]: childVal })\n }\n editable={editable}\n blockId={blockId}\n ctx={ctx}\n />\n ))}\n </div>\n </div>\n );\n }\n\n if (field.kind === \"array\") {\n const items = Array.isArray(value) ? (value as unknown[]) : [];\n const replaceItem = (index: number, next: unknown) => {\n const copy = items.slice();\n copy[index] = next;\n onChange(copy);\n };\n const removeItem = (index: number) => {\n onChange(items.filter((_, i) => i !== index));\n };\n const objectElement =\n Array.isArray(field.fields) && field.fields.length > 0;\n const scalarKind = objectElement ? null : scalarKindFromInner(field.inner);\n const addItem = () => {\n if (objectElement) {\n onChange([...items, emptyObjectFromFields(field.fields)]);\n } else {\n onChange([...items, emptyScalar(scalarKind ?? \"text\")]);\n }\n };\n return (\n <div className=\"flex flex-col gap-2\">\n <FieldLabel>{field.label}</FieldLabel>\n <div className=\"flex flex-col gap-2\">\n {items.map((item, index) => (\n <div\n key={index}\n className=\"flex items-start gap-2 rounded-md border border-input px-3 py-3\"\n >\n <div className=\"flex flex-1 flex-col gap-3\">\n {objectElement ? (\n field.fields!.map((child) => {\n const itemValue =\n item && typeof item === \"object\" && !Array.isArray(item)\n ? (item as Record<string, unknown>)\n : {};\n return (\n <FieldControl\n key={child.key}\n field={child}\n value={itemValue[child.key]}\n onChange={(childVal) =>\n replaceItem(index, {\n ...itemValue,\n [child.key]: childVal,\n })\n }\n editable={editable}\n blockId={blockId}\n ctx={ctx}\n />\n );\n })\n ) : scalarKind === \"boolean\" ? (\n <input\n type=\"checkbox\"\n data-plan-interactive\n className=\"size-4 self-start rounded border-input accent-primary\"\n checked={Boolean(item)}\n disabled={!editable}\n onChange={(event) =>\n replaceItem(index, event.target.checked)\n }\n />\n ) : scalarKind === \"number\" ? (\n <input\n type=\"number\"\n data-plan-interactive\n className={inputClass}\n value={typeof item === \"number\" ? item : \"\"}\n disabled={!editable}\n onChange={(event) => {\n const raw = event.target.value;\n replaceItem(index, raw === \"\" ? undefined : Number(raw));\n }}\n />\n ) : (\n <input\n type=\"text\"\n data-plan-interactive\n className={inputClass}\n value={typeof item === \"string\" ? item : \"\"}\n disabled={!editable}\n onChange={(event) => replaceItem(index, event.target.value)}\n />\n )}\n </div>\n {editable && (\n <button\n type=\"button\"\n data-plan-interactive\n aria-label=\"Remove item\"\n className=\"mt-0.5 inline-flex size-7 shrink-0 items-center justify-center rounded-md text-muted-foreground transition-colors hover:bg-muted hover:text-foreground\"\n onClick={() => removeItem(index)}\n >\n <IconTrash className=\"size-4\" />\n </button>\n )}\n </div>\n ))}\n </div>\n {editable && (\n <button\n type=\"button\"\n data-plan-interactive\n className=\"inline-flex items-center gap-1.5 self-start text-sm text-muted-foreground underline-offset-2 hover:text-foreground hover:underline\"\n onClick={addItem}\n >\n <IconPlus className=\"size-4\" />\n Add {field.label.replace(/s$/i, \"\").toLowerCase() || \"item\"}\n </button>\n )}\n </div>\n );\n }\n\n // Unsupported / structured-without-fields: the auto-editor cannot infer a\n // control. Blocks with these fields should ship a custom `Edit`. Surface a\n // hint in dev so the gap is visible.\n return (\n <div\n className={cn(\n \"rounded-md border border-dashed border-input px-3 py-2 text-xs text-muted-foreground\",\n )}\n >\n <FieldLabel>{field.label}</FieldLabel>\n <p className=\"mt-1\">\n This field ({field.kind}) needs a custom editor — define `Edit` on the\n block spec.\n </p>\n </div>\n );\n}\n"]}
|
|
1
|
+
{"version":3,"file":"SchemaBlockEditor.js","sourceRoot":"","sources":["../../../src/client/blocks/SchemaBlockEditor.tsx"],"names":[],"mappings":"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","sourcesContent":["import { useMemo, useState } from \"react\";\nimport type { ZodType } from \"zod\";\nimport { IconPlus, IconTrash } from \"@tabler/icons-react\";\nimport { cn } from \"../utils.js\";\nimport type { BlockRenderContext } from \"./types.js\";\nimport { introspect, type FieldDescriptor } from \"./schema-form/introspect.js\";\n\n/**\n * Schema-driven auto-editor. When a {@link BlockSpec} omits `Edit`, the registry\n * renders this: it walks the block's zod `data` schema and renders one control\n * per field (string → input, longtext → textarea, number, boolean → toggle,\n * enum → native select, array → repeating rows, object → nested fieldset). A\n * `markdown()`-tagged string field defers to the app-provided inline rich\n * editor via `ctx.renderMarkdownEditor` so prose stays Notion-editable.\n *\n * It uses plain accessible native controls (not template shadcn primitives,\n * which core does not bundle) styled to match the shadcn look. Validation runs\n * the spec's own schema on every edit; the raw edit is kept in local state so a\n * transiently-invalid value (e.g. mid-typing) doesn't get rolled back, and only\n * valid data is committed upstream.\n */\nexport function SchemaBlockEditor<T>({\n data,\n onChange,\n schema,\n editable,\n blockId,\n ctx,\n}: {\n data: T;\n onChange: (next: T) => void;\n schema: ZodType<T>;\n editable: boolean;\n blockId?: string;\n ctx: BlockRenderContext;\n}) {\n const fields = useMemo(() => introspect(schema), [schema]);\n const [showOptional, setShowOptional] = useState(false);\n\n const setField = (key: string, value: unknown) => {\n const next = { ...(data as Record<string, unknown>), [key]: value } as T;\n const parsed = schema.safeParse(next);\n // Commit valid data; otherwise pass the raw edit through so the user can\n // keep typing — the upstream owner re-validates before persisting.\n onChange((parsed.success ? parsed.data : next) as T);\n };\n\n const required = fields.filter((field) => !field.optional);\n const optional = fields.filter((field) => field.optional);\n\n return (\n <div className=\"an-schema-block-editor flex flex-col gap-3\">\n {required.map((field) => (\n <FieldControl\n key={field.key}\n field={field}\n value={(data as Record<string, unknown>)[field.key]}\n onChange={(value) => setField(field.key, value)}\n editable={editable}\n blockId={blockId}\n ctx={ctx}\n />\n ))}\n {optional.length > 0 && (\n <div className=\"flex flex-col gap-3\">\n {showOptional ? (\n optional.map((field) => (\n <FieldControl\n key={field.key}\n field={field}\n value={(data as Record<string, unknown>)[field.key]}\n onChange={(value) => setField(field.key, value)}\n editable={editable}\n blockId={blockId}\n ctx={ctx}\n />\n ))\n ) : (\n <button\n type=\"button\"\n data-plan-interactive\n className=\"self-start text-sm text-muted-foreground underline-offset-2 hover:underline\"\n onClick={() => setShowOptional(true)}\n >\n More options\n </button>\n )}\n </div>\n )}\n </div>\n );\n}\n\nconst inputClass =\n \"flex h-9 w-full rounded-md border border-input bg-transparent px-3 py-1 text-sm transition-colors placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50\";\n\nconst textareaClass =\n \"flex min-h-[80px] w-full rounded-md border border-input bg-transparent px-3 py-2 text-sm placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50\";\n\nfunction FieldLabel({ children }: { children: React.ReactNode }) {\n return (\n <span className=\"text-xs font-medium text-muted-foreground\">\n {children}\n </span>\n );\n}\n\n/** A sensible empty value for a single field, used when adding array items. */\nfunction emptyForField(field: FieldDescriptor): unknown {\n switch (field.kind) {\n case \"text\":\n // A field literally named `id` gets a fresh stable id so new rows are\n // distinguishable without the user having to type one.\n return field.key === \"id\"\n ? `item-${Math.random().toString(36).slice(2, 10)}`\n : \"\";\n case \"longtext\":\n case \"markdown\":\n case \"richtext\":\n return \"\";\n case \"boolean\":\n return false;\n case \"enum\":\n return field.enumValues?.[0];\n case \"array\":\n return [];\n case \"object\":\n return emptyObjectFromFields(field.fields);\n case \"number\":\n default:\n // number → undefined (the input shows blank until the user types); any\n // unsupported kind also defaults to undefined.\n return undefined;\n }\n}\n\n/** Build an empty object value from a descriptor's child fields. */\nfunction emptyObjectFromFields(\n fields: FieldDescriptor[] | undefined,\n): Record<string, unknown> {\n const result: Record<string, unknown> = {};\n for (const child of fields ?? []) {\n result[child.key] = emptyForField(child);\n }\n return result;\n}\n\n/** A scalar element kind classified from an array's inner element schema. */\nfunction scalarKindFromInner(\n inner: FieldDescriptor[\"inner\"],\n): \"number\" | \"boolean\" | \"text\" {\n const type = (inner?._def as { type?: string } | undefined)?.type;\n if (type === \"number\" || type === \"bigint\") return \"number\";\n if (type === \"boolean\") return \"boolean\";\n return \"text\";\n}\n\n/** An empty value for a scalar array element of the given kind. */\nfunction emptyScalar(kind: \"number\" | \"boolean\" | \"text\"): unknown {\n if (kind === \"boolean\") return false;\n if (kind === \"number\") return undefined;\n return \"\";\n}\n\nfunction FieldControl({\n field,\n value,\n onChange,\n editable,\n blockId,\n ctx,\n}: {\n field: FieldDescriptor;\n value: unknown;\n onChange: (value: unknown) => void;\n editable: boolean;\n blockId?: string;\n ctx: BlockRenderContext;\n}) {\n if (field.kind === \"markdown\" || field.kind === \"richtext\") {\n const node = ctx.renderMarkdownEditor?.({\n value: typeof value === \"string\" ? value : \"\",\n onChange: (next) => onChange(next),\n editable,\n blockId,\n });\n return (\n <label className=\"flex flex-col gap-1.5\">\n <FieldLabel>{field.label}</FieldLabel>\n {node ?? (\n // Fallback when no app markdown editor is injected: a plain textarea.\n <textarea\n data-plan-interactive\n className={textareaClass}\n value={typeof value === \"string\" ? value : \"\"}\n disabled={!editable}\n onChange={(event) => onChange(event.target.value)}\n />\n )}\n </label>\n );\n }\n\n if (field.kind === \"boolean\") {\n return (\n <label className=\"flex items-center gap-2\">\n <input\n type=\"checkbox\"\n data-plan-interactive\n className=\"size-4 rounded border-input accent-primary\"\n checked={Boolean(value)}\n disabled={!editable}\n onChange={(event) => onChange(event.target.checked)}\n />\n <FieldLabel>{field.label}</FieldLabel>\n </label>\n );\n }\n\n if (field.kind === \"enum\") {\n const options = field.enumValues ?? [];\n return (\n <label className=\"flex flex-col gap-1.5\">\n <FieldLabel>{field.label}</FieldLabel>\n <select\n data-plan-interactive\n className={inputClass}\n value={typeof value === \"string\" ? value : \"\"}\n disabled={!editable}\n onChange={(event) => onChange(event.target.value || undefined)}\n >\n {field.optional && <option value=\"\">—</option>}\n {options.map((option) => (\n <option key={option} value={option}>\n {option}\n </option>\n ))}\n </select>\n </label>\n );\n }\n\n if (field.kind === \"number\") {\n return (\n <label className=\"flex flex-col gap-1.5\">\n <FieldLabel>{field.label}</FieldLabel>\n <input\n type=\"number\"\n data-plan-interactive\n className={inputClass}\n value={typeof value === \"number\" ? value : \"\"}\n disabled={!editable}\n onChange={(event) => {\n const raw = event.target.value;\n onChange(raw === \"\" ? undefined : Number(raw));\n }}\n />\n </label>\n );\n }\n\n if (field.kind === \"longtext\") {\n return (\n <label className=\"flex flex-col gap-1.5\">\n <FieldLabel>{field.label}</FieldLabel>\n <textarea\n data-plan-interactive\n className={textareaClass}\n value={typeof value === \"string\" ? value : \"\"}\n disabled={!editable}\n onChange={(event) => onChange(event.target.value)}\n />\n </label>\n );\n }\n\n if (field.kind === \"text\") {\n return (\n <label className=\"flex flex-col gap-1.5\">\n <FieldLabel>{field.label}</FieldLabel>\n <input\n type=\"text\"\n data-plan-interactive\n className={inputClass}\n value={typeof value === \"string\" ? value : \"\"}\n disabled={!editable}\n onChange={(event) => onChange(event.target.value)}\n />\n </label>\n );\n }\n\n if (field.kind === \"object\" && field.fields && field.fields.length > 0) {\n const objValue =\n value && typeof value === \"object\" && !Array.isArray(value)\n ? (value as Record<string, unknown>)\n : {};\n return (\n <div className=\"flex flex-col gap-3 rounded-md border border-input px-3 py-3\">\n <FieldLabel>{field.label}</FieldLabel>\n <div className=\"flex flex-col gap-3\">\n {field.fields.map((child) => (\n <FieldControl\n key={child.key}\n field={child}\n value={objValue[child.key]}\n onChange={(childVal) =>\n onChange({ ...objValue, [child.key]: childVal })\n }\n editable={editable}\n blockId={blockId}\n ctx={ctx}\n />\n ))}\n </div>\n </div>\n );\n }\n\n if (field.kind === \"array\") {\n const items = Array.isArray(value) ? (value as unknown[]) : [];\n const replaceItem = (index: number, next: unknown) => {\n const copy = items.slice();\n copy[index] = next;\n onChange(copy);\n };\n const removeItem = (index: number) => {\n onChange(items.filter((_, i) => i !== index));\n };\n const objectElement =\n Array.isArray(field.fields) && field.fields.length > 0;\n const scalarKind = objectElement ? null : scalarKindFromInner(field.inner);\n const addItem = () => {\n if (objectElement) {\n onChange([...items, emptyObjectFromFields(field.fields)]);\n } else {\n onChange([...items, emptyScalar(scalarKind ?? \"text\")]);\n }\n };\n return (\n <div className=\"flex flex-col gap-2\">\n <FieldLabel>{field.label}</FieldLabel>\n <div className=\"flex flex-col gap-2\">\n {items.map((item, index) => (\n <div\n key={index}\n className=\"flex items-start gap-2 rounded-md border border-input px-3 py-3\"\n >\n <div className=\"flex flex-1 flex-col gap-3\">\n {objectElement ? (\n field.fields!.map((child) => {\n const itemValue =\n item && typeof item === \"object\" && !Array.isArray(item)\n ? (item as Record<string, unknown>)\n : {};\n return (\n <FieldControl\n key={child.key}\n field={child}\n value={itemValue[child.key]}\n onChange={(childVal) =>\n replaceItem(index, {\n ...itemValue,\n [child.key]: childVal,\n })\n }\n editable={editable}\n blockId={blockId}\n ctx={ctx}\n />\n );\n })\n ) : scalarKind === \"boolean\" ? (\n <input\n type=\"checkbox\"\n data-plan-interactive\n className=\"size-4 self-start rounded border-input accent-primary\"\n checked={Boolean(item)}\n disabled={!editable}\n onChange={(event) =>\n replaceItem(index, event.target.checked)\n }\n />\n ) : scalarKind === \"number\" ? (\n <input\n type=\"number\"\n data-plan-interactive\n className={inputClass}\n value={typeof item === \"number\" ? item : \"\"}\n disabled={!editable}\n onChange={(event) => {\n const raw = event.target.value;\n replaceItem(index, raw === \"\" ? undefined : Number(raw));\n }}\n />\n ) : (\n <input\n type=\"text\"\n data-plan-interactive\n className={inputClass}\n value={typeof item === \"string\" ? item : \"\"}\n disabled={!editable}\n onChange={(event) => replaceItem(index, event.target.value)}\n />\n )}\n </div>\n {editable && (\n <button\n type=\"button\"\n data-plan-interactive\n aria-label=\"Remove item\"\n className=\"mt-0.5 inline-flex size-7 shrink-0 items-center justify-center rounded-md text-muted-foreground transition-colors hover:bg-muted hover:text-foreground\"\n onClick={() => removeItem(index)}\n >\n <IconTrash className=\"size-4\" />\n </button>\n )}\n </div>\n ))}\n </div>\n {editable && (\n <button\n type=\"button\"\n data-plan-interactive\n className=\"inline-flex items-center gap-1.5 self-start text-sm text-muted-foreground underline-offset-2 hover:text-foreground hover:underline\"\n onClick={addItem}\n >\n <IconPlus className=\"size-4\" />\n Add {field.label.replace(/s$/i, \"\").toLowerCase() || \"item\"}\n </button>\n )}\n </div>\n );\n }\n\n // Unsupported / structured-without-fields: the auto-editor cannot infer a\n // control. Blocks with these fields should ship a custom `Edit`. Surface a\n // hint in dev so the gap is visible.\n return (\n <div\n className={cn(\n \"rounded-md border border-dashed border-input px-3 py-2 text-xs text-muted-foreground\",\n )}\n >\n <FieldLabel>{field.label}</FieldLabel>\n <p className=\"mt-1\">\n This field ({field.kind}) needs a custom editor — define `Edit` on the\n block spec.\n </p>\n </div>\n );\n}\n"]}
|
|
@@ -13,10 +13,11 @@
|
|
|
13
13
|
* This entry includes the React surface. For server/agent code that must stay
|
|
14
14
|
* React-free, import from `@agent-native/core/blocks/server`.
|
|
15
15
|
*/
|
|
16
|
-
export { defineBlock, type BlockSpec, type BlockPlacement, type BlockMdxConfig, type BlockAttrReader, type BlockRenderContext, type BlockReadProps, type BlockEditProps, type MdxAttrValue, type NestedBlock, } from "./types.js";
|
|
16
|
+
export { defineBlock, type BlockSpec, type BlockPlacement, type BlockMdxConfig, type BlockAttrReader, type BlockRenderContext, type BlockReadProps, type BlockEditProps, type MdxAttrValue, type NestedBlock, type BlockAiFieldActionProps, type BlockContainerRegion, type BlockContainerSpec, type BlockDataChangeMeta, } from "./types.js";
|
|
17
17
|
export { BlockRegistry, registerBlocks } from "./registry.js";
|
|
18
18
|
export { BlockRegistryProvider, useBlockRegistry, useOptionalBlockRegistry, } from "./provider.js";
|
|
19
19
|
export { BlockView, blockEditSurface } from "./BlockView.js";
|
|
20
|
+
export { AiEditableFieldLabel } from "./AiEditableField.js";
|
|
20
21
|
export { SchemaBlockEditor } from "./SchemaBlockEditor.js";
|
|
21
22
|
export { markdown, richtext, introspect, type FieldKind, type FieldDescriptor, } from "./schema-form/introspect.js";
|
|
22
23
|
export { prop, escapeAttr, jsonExpression, attributeValue, createAttrReader, serializeSpecBlock, parseSpecBlock, type MdxJsxNode, type MdxAttrNode, type SerializableBlock, type ParsedBlockBase, } from "./mdx.js";
|
|
@@ -31,7 +32,9 @@ export { codeTabsSchema, codeTabsMdx, type CodeTabsData, type CodeTabsTab, } fro
|
|
|
31
32
|
export { htmlBlock, HtmlReadBlock, HtmlEditBlock } from "./library/html.js";
|
|
32
33
|
export { htmlSchema, htmlMdx, type HtmlBlockData, } from "./library/html.config.js";
|
|
33
34
|
export { tabsBlock, TabsBlockReader, TabsBlockEditor } from "./library/tabs.js";
|
|
34
|
-
export { tabsSchema, tabsMdx, type TabsData, type TabsTab, } from "./library/tabs.config.js";
|
|
35
|
+
export { tabsSchema, tabsMdx, type TabsData, type TabsOrientation, type TabsTab, } from "./library/tabs.config.js";
|
|
36
|
+
export { columnsBlock, ColumnsBlockReader, ColumnsBlockEditor, } from "./library/columns.js";
|
|
37
|
+
export { columnsSchema, columnsMdx, type ColumnsData, type ColumnsColumn, } from "./library/columns.config.js";
|
|
35
38
|
export { MermaidRead, MermaidEdit } from "./library/MermaidBlock.js";
|
|
36
39
|
export { mermaidSchema, mermaidMdx, type MermaidData, } from "./library/mermaid.config.js";
|
|
37
40
|
export { ApiEndpointRead, ApiEndpointEdit, } from "./library/ApiEndpointBlock.js";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/client/blocks/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAGH,OAAO,EACL,WAAW,EACX,KAAK,SAAS,EACd,KAAK,cAAc,EACnB,KAAK,cAAc,EACnB,KAAK,eAAe,EACpB,KAAK,kBAAkB,EACvB,KAAK,cAAc,EACnB,KAAK,cAAc,EACnB,KAAK,YAAY,EACjB,KAAK,WAAW,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/client/blocks/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -20,6 +20,7 @@ export { BlockRegistry, registerBlocks } from "./registry.js";
|
|
|
20
20
|
export { BlockRegistryProvider, useBlockRegistry, useOptionalBlockRegistry, } from "./provider.js";
|
|
21
21
|
// Rendering
|
|
22
22
|
export { BlockView, blockEditSurface } from "./BlockView.js";
|
|
23
|
+
export { AiEditableFieldLabel } from "./AiEditableField.js";
|
|
23
24
|
export { SchemaBlockEditor } from "./SchemaBlockEditor.js";
|
|
24
25
|
// Schema-form helpers
|
|
25
26
|
export { markdown, richtext, introspect, } from "./schema-form/introspect.js";
|
|
@@ -28,9 +29,9 @@ export { prop, escapeAttr, jsonExpression, attributeValue, createAttrReader, ser
|
|
|
28
29
|
// Agent schema export
|
|
29
30
|
export { describeBlocksForAgent, renderBlockVocabularyReference, } from "./agent.js";
|
|
30
31
|
// Standard library registration. Apps call `registerLibraryBlocks(registry)` to
|
|
31
|
-
// register the whole standard library (the
|
|
32
|
-
//
|
|
33
|
-
//
|
|
32
|
+
// register the whole standard library (the pre-built specs + dev-doc specs) in
|
|
33
|
+
// one place, then register only their app-specific blocks on top.
|
|
34
|
+
// `libraryBlockSpecs` is the underlying ordered array.
|
|
34
35
|
export { libraryBlockSpecs, registerLibraryBlocks, } from "./library/specs.js";
|
|
35
36
|
// Standard block library (React specs). Apps register these in their browser
|
|
36
37
|
// registry alongside their own app-specific blocks.
|
|
@@ -44,6 +45,8 @@ export { htmlBlock, HtmlReadBlock, HtmlEditBlock } from "./library/html.js";
|
|
|
44
45
|
export { htmlSchema, htmlMdx, } from "./library/html.config.js";
|
|
45
46
|
export { tabsBlock, TabsBlockReader, TabsBlockEditor } from "./library/tabs.js";
|
|
46
47
|
export { tabsSchema, tabsMdx, } from "./library/tabs.config.js";
|
|
48
|
+
export { columnsBlock, ColumnsBlockReader, ColumnsBlockEditor, } from "./library/columns.js";
|
|
49
|
+
export { columnsSchema, columnsMdx, } from "./library/columns.config.js";
|
|
47
50
|
// Dev-doc block library (React `Read`/`Edit` renderers + their React-free
|
|
48
51
|
// schema/MDX config). Apps register these alongside their own blocks, supplying
|
|
49
52
|
// app-specific spec metadata (label/description/editSurface/empty) via
|