@agent-native/core 0.37.3 → 0.38.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 +19 -6
- package/dist/action.d.ts +60 -2
- package/dist/action.d.ts.map +1 -1
- package/dist/action.js +6 -2
- package/dist/action.js.map +1 -1
- package/dist/agent/production-agent.d.ts +12 -6
- package/dist/agent/production-agent.d.ts.map +1 -1
- package/dist/agent/production-agent.js +161 -11
- package/dist/agent/production-agent.js.map +1 -1
- package/dist/agent/types.d.ts +2 -0
- package/dist/agent/types.d.ts.map +1 -1
- package/dist/agent/types.js.map +1 -1
- package/dist/catalog.json +2 -2
- package/dist/cli/connect.d.ts.map +1 -1
- package/dist/cli/connect.js +15 -0
- package/dist/cli/connect.js.map +1 -1
- package/dist/cli/index.js +10 -6
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/plan-publish-store.d.ts +52 -0
- package/dist/cli/plan-publish-store.d.ts.map +1 -0
- package/dist/cli/plan-publish-store.js +103 -0
- package/dist/cli/plan-publish-store.js.map +1 -0
- package/dist/cli/skills.d.ts +29 -4
- package/dist/cli/skills.d.ts.map +1 -1
- package/dist/cli/skills.js +851 -275
- package/dist/cli/skills.js.map +1 -1
- package/dist/cli/templates-meta.js +12 -12
- package/dist/cli/templates-meta.js.map +1 -1
- package/dist/client/AssistantChat.d.ts +3 -1
- package/dist/client/AssistantChat.d.ts.map +1 -1
- package/dist/client/AssistantChat.js +65 -15
- package/dist/client/AssistantChat.js.map +1 -1
- package/dist/client/MultiTabAssistantChat.d.ts.map +1 -1
- package/dist/client/MultiTabAssistantChat.js +20 -2
- package/dist/client/MultiTabAssistantChat.js.map +1 -1
- package/dist/client/agent-chat-adapter.d.ts.map +1 -1
- package/dist/client/agent-chat-adapter.js +12 -0
- package/dist/client/agent-chat-adapter.js.map +1 -1
- package/dist/client/agent-engine-key.d.ts +24 -0
- package/dist/client/agent-engine-key.d.ts.map +1 -0
- package/dist/client/agent-engine-key.js +49 -0
- package/dist/client/agent-engine-key.js.map +1 -0
- package/dist/client/analytics.d.ts.map +1 -1
- package/dist/client/analytics.js +34 -0
- package/dist/client/analytics.js.map +1 -1
- package/dist/client/blocks/BlockView.d.ts +26 -0
- package/dist/client/blocks/BlockView.d.ts.map +1 -0
- package/dist/client/blocks/BlockView.js +24 -0
- package/dist/client/blocks/BlockView.js.map +1 -0
- package/dist/client/blocks/SchemaBlockEditor.d.ts +25 -0
- package/dist/client/blocks/SchemaBlockEditor.d.ts.map +1 -0
- package/dist/client/blocks/SchemaBlockEditor.js +72 -0
- package/dist/client/blocks/SchemaBlockEditor.js.map +1 -0
- package/dist/client/blocks/agent.d.ts +30 -0
- package/dist/client/blocks/agent.d.ts.map +1 -0
- package/dist/client/blocks/agent.js +61 -0
- package/dist/client/blocks/agent.js.map +1 -0
- package/dist/client/blocks/index.d.ts +34 -0
- package/dist/client/blocks/index.d.ts.map +1 -0
- package/dist/client/blocks/index.js +42 -0
- package/dist/client/blocks/index.js.map +1 -0
- package/dist/client/blocks/library/checklist.config.d.ts +36 -0
- package/dist/client/blocks/library/checklist.config.d.ts.map +1 -0
- package/dist/client/blocks/library/checklist.config.js +25 -0
- package/dist/client/blocks/library/checklist.config.js.map +1 -0
- package/dist/client/blocks/library/checklist.d.ts +26 -0
- package/dist/client/blocks/library/checklist.d.ts.map +1 -0
- package/dist/client/blocks/library/checklist.js +76 -0
- package/dist/client/blocks/library/checklist.js.map +1 -0
- package/dist/client/blocks/library/code-tabs.config.d.ts +36 -0
- package/dist/client/blocks/library/code-tabs.config.d.ts.map +1 -0
- package/dist/client/blocks/library/code-tabs.config.js +30 -0
- package/dist/client/blocks/library/code-tabs.config.js.map +1 -0
- package/dist/client/blocks/library/code-tabs.d.ts +3 -0
- package/dist/client/blocks/library/code-tabs.d.ts.map +1 -0
- package/dist/client/blocks/library/code-tabs.js +165 -0
- package/dist/client/blocks/library/code-tabs.js.map +1 -0
- package/dist/client/blocks/library/html.config.d.ts +37 -0
- package/dist/client/blocks/library/html.config.d.ts.map +1 -0
- package/dist/client/blocks/library/html.config.js +46 -0
- package/dist/client/blocks/library/html.config.js.map +1 -0
- package/dist/client/blocks/library/html.d.ts +21 -0
- package/dist/client/blocks/library/html.d.ts.map +1 -0
- package/dist/client/blocks/library/html.js +69 -0
- package/dist/client/blocks/library/html.js.map +1 -0
- package/dist/client/blocks/library/table.config.d.ts +30 -0
- package/dist/client/blocks/library/table.config.d.ts.map +1 -0
- package/dist/client/blocks/library/table.config.js +22 -0
- package/dist/client/blocks/library/table.config.js.map +1 -0
- package/dist/client/blocks/library/table.d.ts +8 -0
- package/dist/client/blocks/library/table.d.ts.map +1 -0
- package/dist/client/blocks/library/table.js +107 -0
- package/dist/client/blocks/library/table.js.map +1 -0
- package/dist/client/blocks/library/tabs.config.d.ts +56 -0
- package/dist/client/blocks/library/tabs.config.d.ts.map +1 -0
- package/dist/client/blocks/library/tabs.config.js +36 -0
- package/dist/client/blocks/library/tabs.config.js.map +1 -0
- package/dist/client/blocks/library/tabs.d.ts +20 -0
- package/dist/client/blocks/library/tabs.d.ts.map +1 -0
- package/dist/client/blocks/library/tabs.js +123 -0
- package/dist/client/blocks/library/tabs.js.map +1 -0
- package/dist/client/blocks/mdx.d.ts +74 -0
- package/dist/client/blocks/mdx.d.ts.map +1 -0
- package/dist/client/blocks/mdx.js +205 -0
- package/dist/client/blocks/mdx.js.map +1 -0
- package/dist/client/blocks/provider.d.ts +25 -0
- package/dist/client/blocks/provider.d.ts.map +1 -0
- package/dist/client/blocks/provider.js +19 -0
- package/dist/client/blocks/provider.js.map +1 -0
- package/dist/client/blocks/registry.d.ts +24 -0
- package/dist/client/blocks/registry.d.ts.map +1 -0
- package/dist/client/blocks/registry.js +50 -0
- package/dist/client/blocks/registry.js.map +1 -0
- package/dist/client/blocks/schema-form/introspect.d.ts +31 -0
- package/dist/client/blocks/schema-form/introspect.d.ts.map +1 -0
- package/dist/client/blocks/schema-form/introspect.js +164 -0
- package/dist/client/blocks/schema-form/introspect.js.map +1 -0
- package/dist/client/blocks/server.d.ts +22 -0
- package/dist/client/blocks/server.d.ts.map +1 -0
- package/dist/client/blocks/server.js +25 -0
- package/dist/client/blocks/server.js.map +1 -0
- package/dist/client/blocks/types.d.ts +212 -0
- package/dist/client/blocks/types.d.ts.map +1 -0
- package/dist/client/blocks/types.js +5 -0
- package/dist/client/blocks/types.js.map +1 -0
- package/dist/client/composer/ComposerPlusMenu.js +10 -1
- package/dist/client/composer/ComposerPlusMenu.js.map +1 -1
- package/dist/client/guided-questions.d.ts +68 -0
- package/dist/client/guided-questions.d.ts.map +1 -1
- package/dist/client/guided-questions.js +158 -3
- package/dist/client/guided-questions.js.map +1 -1
- package/dist/client/index.d.ts +5 -1
- package/dist/client/index.d.ts.map +1 -1
- package/dist/client/index.js +15 -1
- package/dist/client/index.js.map +1 -1
- package/dist/client/rich-markdown-editor/BubbleToolbar.d.ts +37 -0
- package/dist/client/rich-markdown-editor/BubbleToolbar.d.ts.map +1 -0
- package/dist/client/rich-markdown-editor/BubbleToolbar.js +161 -0
- package/dist/client/rich-markdown-editor/BubbleToolbar.js.map +1 -0
- package/dist/client/rich-markdown-editor/ImageExtension.d.ts +63 -0
- package/dist/client/rich-markdown-editor/ImageExtension.d.ts.map +1 -0
- package/dist/client/rich-markdown-editor/ImageExtension.js +242 -0
- package/dist/client/rich-markdown-editor/ImageExtension.js.map +1 -0
- package/dist/client/rich-markdown-editor/RichMarkdownEditor.d.ts +51 -0
- package/dist/client/rich-markdown-editor/RichMarkdownEditor.d.ts.map +1 -0
- package/dist/client/rich-markdown-editor/RichMarkdownEditor.js +37 -0
- package/dist/client/rich-markdown-editor/RichMarkdownEditor.js.map +1 -0
- package/dist/client/rich-markdown-editor/SharedRichEditor.d.ts +61 -0
- package/dist/client/rich-markdown-editor/SharedRichEditor.d.ts.map +1 -0
- package/dist/client/rich-markdown-editor/SharedRichEditor.js +121 -0
- package/dist/client/rich-markdown-editor/SharedRichEditor.js.map +1 -0
- package/dist/client/rich-markdown-editor/SlashCommandMenu.d.ts +36 -0
- package/dist/client/rich-markdown-editor/SlashCommandMenu.d.ts.map +1 -0
- package/dist/client/rich-markdown-editor/SlashCommandMenu.js +193 -0
- package/dist/client/rich-markdown-editor/SlashCommandMenu.js.map +1 -0
- package/dist/client/rich-markdown-editor/extensions.d.ts +166 -0
- package/dist/client/rich-markdown-editor/extensions.d.ts.map +1 -0
- package/dist/client/rich-markdown-editor/extensions.js +222 -0
- package/dist/client/rich-markdown-editor/extensions.js.map +1 -0
- package/dist/client/rich-markdown-editor/index.d.ts +9 -0
- package/dist/client/rich-markdown-editor/index.d.ts.map +1 -0
- package/dist/client/rich-markdown-editor/index.js +9 -0
- package/dist/client/rich-markdown-editor/index.js.map +1 -0
- package/dist/client/rich-markdown-editor/uploadEditorImage.d.ts +18 -0
- package/dist/client/rich-markdown-editor/uploadEditorImage.d.ts.map +1 -0
- package/dist/client/rich-markdown-editor/uploadEditorImage.js +57 -0
- package/dist/client/rich-markdown-editor/uploadEditorImage.js.map +1 -0
- package/dist/client/rich-markdown-editor/useCollabReconcile.d.ts +91 -0
- package/dist/client/rich-markdown-editor/useCollabReconcile.d.ts.map +1 -0
- package/dist/client/rich-markdown-editor/useCollabReconcile.js +342 -0
- package/dist/client/rich-markdown-editor/useCollabReconcile.js.map +1 -0
- package/dist/client/track.d.ts +25 -0
- package/dist/client/track.d.ts.map +1 -0
- package/dist/client/track.js +53 -0
- package/dist/client/track.js.map +1 -0
- package/dist/client/use-action.d.ts.map +1 -1
- package/dist/client/use-action.js +6 -0
- package/dist/client/use-action.js.map +1 -1
- package/dist/client/use-session.d.ts +3 -2
- package/dist/client/use-session.d.ts.map +1 -1
- package/dist/client/use-session.js +3 -2
- package/dist/client/use-session.js.map +1 -1
- package/dist/deploy/build.d.ts +5 -0
- package/dist/deploy/build.d.ts.map +1 -1
- package/dist/deploy/build.js +67 -1
- package/dist/deploy/build.js.map +1 -1
- package/dist/extensions/schema.d.ts +1 -1
- package/dist/mcp/build-server.d.ts.map +1 -1
- package/dist/mcp/build-server.js +9 -2
- package/dist/mcp/build-server.js.map +1 -1
- package/dist/mcp/server.d.ts +1 -1
- package/dist/mcp/server.d.ts.map +1 -1
- package/dist/mcp/server.js +35 -2
- package/dist/mcp/server.js.map +1 -1
- package/dist/provider-api/index.d.ts +1 -1
- package/dist/provider-api/index.d.ts.map +1 -1
- package/dist/scripts/docs/search.d.ts.map +1 -1
- package/dist/scripts/docs/search.js +5 -2
- package/dist/scripts/docs/search.js.map +1 -1
- package/dist/scripts/runner.d.ts.map +1 -1
- package/dist/scripts/runner.js +16 -3
- package/dist/scripts/runner.js.map +1 -1
- package/dist/server/action-discovery.d.ts.map +1 -1
- package/dist/server/action-discovery.js +2 -0
- package/dist/server/action-discovery.js.map +1 -1
- package/dist/server/action-routes.d.ts.map +1 -1
- package/dist/server/action-routes.js +30 -4
- package/dist/server/action-routes.js.map +1 -1
- package/dist/server/agent-chat-plugin.d.ts.map +1 -1
- package/dist/server/agent-chat-plugin.js +65 -19
- package/dist/server/agent-chat-plugin.js.map +1 -1
- package/dist/server/agent-teams.d.ts.map +1 -1
- package/dist/server/agent-teams.js +8 -1
- package/dist/server/agent-teams.js.map +1 -1
- package/dist/server/agents-bundle.d.ts +27 -1
- package/dist/server/agents-bundle.d.ts.map +1 -1
- package/dist/server/agents-bundle.js +41 -3
- package/dist/server/agents-bundle.js.map +1 -1
- package/dist/server/auth.d.ts.map +1 -1
- package/dist/server/auth.js +76 -3
- package/dist/server/auth.js.map +1 -1
- package/dist/server/core-routes-plugin.d.ts.map +1 -1
- package/dist/server/core-routes-plugin.js +60 -0
- package/dist/server/core-routes-plugin.js.map +1 -1
- package/dist/server/onboarding-html.d.ts.map +1 -1
- package/dist/server/onboarding-html.js +160 -22
- package/dist/server/onboarding-html.js.map +1 -1
- package/dist/server/sentry.d.ts.map +1 -1
- package/dist/server/sentry.js +6 -0
- package/dist/server/sentry.js.map +1 -1
- package/dist/server/social-og-image.d.ts +2 -1
- package/dist/server/social-og-image.d.ts.map +1 -1
- package/dist/server/social-og-image.js +24 -4
- package/dist/server/social-og-image.js.map +1 -1
- package/dist/sharing/schema.d.ts +1 -1
- package/dist/styles/agent-native.css +1 -0
- package/dist/styles/rich-markdown-editor.css +439 -0
- package/dist/templates/default/.agents/skills/actions/SKILL.md +4 -1
- package/dist/templates/default/.agents/skills/security/SKILL.md +13 -4
- package/dist/templates/default/.agents/skills/storing-data/SKILL.md +15 -3
- package/dist/templates/default/AGENTS.md +1 -0
- package/dist/templates/default/DEVELOPING.md +2 -0
- package/dist/templates/workspace-core/.agents/skills/a2a-protocol/SKILL.md +10 -3
- package/dist/templates/workspace-core/.agents/skills/actions/SKILL.md +98 -10
- package/dist/templates/workspace-core/.agents/skills/adding-a-feature/SKILL.md +45 -3
- package/dist/templates/workspace-core/.agents/skills/address-feedback/SKILL.md +2 -0
- package/dist/templates/workspace-core/.agents/skills/authentication/SKILL.md +37 -4
- package/dist/templates/workspace-core/.agents/skills/automations/SKILL.md +9 -4
- package/dist/templates/workspace-core/.agents/skills/capture-learnings/SKILL.md +2 -0
- package/dist/templates/workspace-core/.agents/skills/client-methods/SKILL.md +106 -0
- package/dist/templates/workspace-core/.agents/skills/client-methods/references/legacy-client-fetch-audit-2026-06-03.md +53 -0
- package/dist/templates/workspace-core/.agents/skills/client-side-routing/SKILL.md +2 -0
- package/dist/templates/workspace-core/.agents/skills/context-awareness/SKILL.md +62 -61
- package/dist/templates/workspace-core/.agents/skills/context-xray/SKILL.md +47 -0
- package/dist/templates/workspace-core/.agents/skills/create-skill/SKILL.md +28 -0
- package/dist/templates/workspace-core/.agents/skills/delegate-to-agent/SKILL.md +52 -1
- package/dist/templates/workspace-core/.agents/skills/extension-points/SKILL.md +2 -0
- package/dist/templates/workspace-core/.agents/skills/extensions/SKILL.md +95 -433
- package/dist/templates/workspace-core/.agents/skills/extensions/references/api.md +285 -0
- package/dist/templates/workspace-core/.agents/skills/extensions/references/examples.md +259 -0
- package/dist/templates/workspace-core/.agents/skills/external-agents/SKILL.md +398 -0
- package/dist/templates/workspace-core/.agents/skills/external-agents/references/mcp-apps-embedding.md +157 -0
- package/dist/templates/workspace-core/.agents/skills/frontend-design/SKILL.md +17 -0
- package/dist/templates/workspace-core/.agents/skills/integration-webhooks/SKILL.md +13 -2
- package/dist/templates/workspace-core/.agents/skills/mvp-followup/SKILL.md +51 -0
- package/dist/templates/workspace-core/.agents/skills/observability/SKILL.md +14 -4
- package/dist/templates/workspace-core/.agents/skills/onboarding/SKILL.md +13 -1
- package/dist/templates/workspace-core/.agents/skills/portability/SKILL.md +27 -5
- package/dist/templates/workspace-core/.agents/skills/qa/SKILL.md +24 -8
- package/dist/templates/workspace-core/.agents/skills/real-time-collab/SKILL.md +53 -7
- package/dist/templates/workspace-core/.agents/skills/real-time-sync/SKILL.md +43 -10
- package/dist/templates/workspace-core/.agents/skills/recurring-jobs/SKILL.md +2 -0
- package/dist/templates/workspace-core/.agents/skills/secrets/SKILL.md +43 -14
- package/dist/templates/workspace-core/.agents/skills/security/SKILL.md +50 -1
- package/dist/templates/workspace-core/.agents/skills/self-modifying-code/SKILL.md +4 -2
- package/dist/templates/workspace-core/.agents/skills/server-plugins/SKILL.md +11 -1
- package/dist/templates/workspace-core/.agents/skills/shadcn-ui/SKILL.md +15 -0
- package/dist/templates/workspace-core/.agents/skills/sharing/SKILL.md +5 -1
- package/dist/templates/workspace-core/.agents/skills/storing-data/SKILL.md +48 -19
- package/dist/templates/workspace-core/.agents/skills/tracking/SKILL.md +7 -3
- package/dist/templates/workspace-core/.agents/skills/voice-transcription/SKILL.md +13 -6
- package/dist/templates/workspace-core/.agents/skills/writing-agent-instructions/SKILL.md +236 -0
- package/dist/templates/workspace-core/AGENTS.md +5 -1
- package/dist/templates/workspace-root/AGENTS.md +5 -2
- package/dist/tracking/route.d.ts +43 -0
- package/dist/tracking/route.d.ts.map +1 -0
- package/dist/tracking/route.js +85 -0
- package/dist/tracking/route.js.map +1 -0
- package/dist/vite/client.d.ts.map +1 -1
- package/dist/vite/client.js +15 -0
- package/dist/vite/client.js.map +1 -1
- package/docs/content/a2a-protocol.md +18 -4
- package/docs/content/actions.md +87 -0
- package/docs/content/agent-mentions.md +2 -1
- package/docs/content/authentication.md +2 -1
- package/docs/content/client.md +64 -13
- package/docs/content/cloneable-saas.md +1 -1
- package/docs/content/code-agents-ui.md +17 -11
- package/docs/content/context-awareness.md +23 -28
- package/docs/content/creating-templates.md +1 -1
- package/docs/content/drop-in-agent.md +2 -0
- package/docs/content/getting-started.md +2 -2
- package/docs/content/key-concepts.md +2 -2
- package/docs/content/messaging.md +57 -15
- package/docs/content/migration-workbench.md +1 -1
- package/docs/content/multi-app-workspace.md +1 -1
- package/docs/content/multi-tenancy.md +17 -15
- package/docs/content/real-time-collaboration.md +1 -1
- package/docs/content/recurring-jobs.md +1 -1
- package/docs/content/security.md +2 -2
- package/docs/content/server.md +4 -4
- package/docs/content/skills-guide.md +30 -0
- package/docs/content/template-analytics.md +2 -2
- package/docs/content/template-assets.md +17 -1
- package/docs/content/template-brain.md +2 -2
- package/docs/content/template-calendar.md +1 -1
- package/docs/content/template-clips.md +3 -3
- package/docs/content/template-content.md +2 -2
- package/docs/content/template-design.md +2 -2
- package/docs/content/template-dispatch.md +3 -3
- package/docs/content/template-forms.md +14 -2
- package/docs/content/template-mail.md +1 -3
- package/docs/content/template-plan.md +118 -0
- package/docs/content/template-slides.md +5 -4
- package/docs/content/template-starter.md +4 -4
- package/docs/content/template-videos.md +6 -11
- package/docs/content/tracking.md +21 -1
- package/docs/content/visual-plans.md +72 -0
- package/docs/content/workspace.md +9 -9
- package/package.json +26 -11
- package/src/templates/default/.agents/skills/actions/SKILL.md +4 -1
- package/src/templates/default/.agents/skills/security/SKILL.md +13 -4
- package/src/templates/default/.agents/skills/storing-data/SKILL.md +15 -3
- package/src/templates/default/AGENTS.md +1 -0
- package/src/templates/default/DEVELOPING.md +2 -0
- package/src/templates/workspace-core/.agents/skills/a2a-protocol/SKILL.md +10 -3
- package/src/templates/workspace-core/.agents/skills/actions/SKILL.md +98 -10
- package/src/templates/workspace-core/.agents/skills/adding-a-feature/SKILL.md +45 -3
- package/src/templates/workspace-core/.agents/skills/address-feedback/SKILL.md +2 -0
- package/src/templates/workspace-core/.agents/skills/authentication/SKILL.md +37 -4
- package/src/templates/workspace-core/.agents/skills/automations/SKILL.md +9 -4
- package/src/templates/workspace-core/.agents/skills/capture-learnings/SKILL.md +2 -0
- package/src/templates/workspace-core/.agents/skills/client-methods/SKILL.md +106 -0
- package/src/templates/workspace-core/.agents/skills/client-methods/references/legacy-client-fetch-audit-2026-06-03.md +53 -0
- package/src/templates/workspace-core/.agents/skills/client-side-routing/SKILL.md +2 -0
- package/src/templates/workspace-core/.agents/skills/context-awareness/SKILL.md +62 -61
- package/src/templates/workspace-core/.agents/skills/context-xray/SKILL.md +47 -0
- package/src/templates/workspace-core/.agents/skills/create-skill/SKILL.md +28 -0
- package/src/templates/workspace-core/.agents/skills/delegate-to-agent/SKILL.md +52 -1
- package/src/templates/workspace-core/.agents/skills/extension-points/SKILL.md +2 -0
- package/src/templates/workspace-core/.agents/skills/extensions/SKILL.md +95 -433
- package/src/templates/workspace-core/.agents/skills/extensions/references/api.md +285 -0
- package/src/templates/workspace-core/.agents/skills/extensions/references/examples.md +259 -0
- package/src/templates/workspace-core/.agents/skills/external-agents/SKILL.md +398 -0
- package/src/templates/workspace-core/.agents/skills/external-agents/references/mcp-apps-embedding.md +157 -0
- package/src/templates/workspace-core/.agents/skills/frontend-design/SKILL.md +17 -0
- package/src/templates/workspace-core/.agents/skills/integration-webhooks/SKILL.md +13 -2
- package/src/templates/workspace-core/.agents/skills/mvp-followup/SKILL.md +51 -0
- package/src/templates/workspace-core/.agents/skills/observability/SKILL.md +14 -4
- package/src/templates/workspace-core/.agents/skills/onboarding/SKILL.md +13 -1
- package/src/templates/workspace-core/.agents/skills/portability/SKILL.md +27 -5
- package/src/templates/workspace-core/.agents/skills/qa/SKILL.md +24 -8
- package/src/templates/workspace-core/.agents/skills/real-time-collab/SKILL.md +53 -7
- package/src/templates/workspace-core/.agents/skills/real-time-sync/SKILL.md +43 -10
- package/src/templates/workspace-core/.agents/skills/recurring-jobs/SKILL.md +2 -0
- package/src/templates/workspace-core/.agents/skills/secrets/SKILL.md +43 -14
- package/src/templates/workspace-core/.agents/skills/security/SKILL.md +50 -1
- package/src/templates/workspace-core/.agents/skills/self-modifying-code/SKILL.md +4 -2
- package/src/templates/workspace-core/.agents/skills/server-plugins/SKILL.md +11 -1
- package/src/templates/workspace-core/.agents/skills/shadcn-ui/SKILL.md +15 -0
- package/src/templates/workspace-core/.agents/skills/sharing/SKILL.md +5 -1
- package/src/templates/workspace-core/.agents/skills/storing-data/SKILL.md +48 -19
- package/src/templates/workspace-core/.agents/skills/tracking/SKILL.md +7 -3
- package/src/templates/workspace-core/.agents/skills/voice-transcription/SKILL.md +13 -6
- package/src/templates/workspace-core/.agents/skills/writing-agent-instructions/SKILL.md +236 -0
- package/src/templates/workspace-core/AGENTS.md +5 -1
- package/src/templates/workspace-root/AGENTS.md +5 -2
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: mvp-followup
|
|
3
|
+
description: >-
|
|
4
|
+
Use when asking what to do next after a feature pass while avoiding bloat and
|
|
5
|
+
checking for unfinished MVP work.
|
|
6
|
+
metadata:
|
|
7
|
+
internal: true
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
# MVP Follow-Up
|
|
11
|
+
|
|
12
|
+
## Rule
|
|
13
|
+
|
|
14
|
+
Recommend or execute only closeout work that makes the current MVP more real,
|
|
15
|
+
verified, documented, or shippable. Do not propose new product scope unless
|
|
16
|
+
there is a clear blocker to the MVP working for real users.
|
|
17
|
+
|
|
18
|
+
## Workflow
|
|
19
|
+
|
|
20
|
+
1. Identify the current feature or thread outcome.
|
|
21
|
+
2. Check for unfinished work in this order:
|
|
22
|
+
- failing or skipped verification
|
|
23
|
+
- unreviewed real-data pilot results
|
|
24
|
+
- pending review/proposals/approval queues
|
|
25
|
+
- docs that no longer match behavior
|
|
26
|
+
- unrelated dirty files that block full prep/ship hygiene
|
|
27
|
+
3. Recommend the smallest next batch that closes those gaps.
|
|
28
|
+
4. Explicitly skip tempting bloat: new integrations, dashboards, settings,
|
|
29
|
+
abstractions, or extra UI unless they directly unblock real use.
|
|
30
|
+
5. If the user says "do it", run the closeout work in parallel where safe and
|
|
31
|
+
keep edits minimal.
|
|
32
|
+
|
|
33
|
+
## Output Shape
|
|
34
|
+
|
|
35
|
+
Lead with the concrete next step. Keep the list short. Separate:
|
|
36
|
+
|
|
37
|
+
- **Do now**: validation, real pilot, docs, or bug fixes.
|
|
38
|
+
- **Defer**: useful ideas that should wait for real user feedback.
|
|
39
|
+
- **Blocker**: any specific user/manual action needed.
|
|
40
|
+
|
|
41
|
+
## Verification Bias
|
|
42
|
+
|
|
43
|
+
Prefer non-mutating checks when the worktree has unrelated dirty files. Use full
|
|
44
|
+
`pnpm prep` only when it will not rewrite someone else's concurrent work.
|
|
45
|
+
|
|
46
|
+
## Related Skills
|
|
47
|
+
|
|
48
|
+
- `qa`
|
|
49
|
+
- `ship`
|
|
50
|
+
- `adding-a-feature`
|
|
51
|
+
- `capture-learnings`
|
|
@@ -4,6 +4,8 @@ description: >-
|
|
|
4
4
|
Agent observability, evals, feedback, and experiments. Use when adding
|
|
5
5
|
observability dashboards, configuring trace capture, setting up evals,
|
|
6
6
|
creating A/B experiments, or collecting user feedback on agent responses.
|
|
7
|
+
metadata:
|
|
8
|
+
internal: true
|
|
7
9
|
---
|
|
8
10
|
|
|
9
11
|
# Agent Observability
|
|
@@ -78,17 +80,25 @@ const criteria: EvalCriteria = {
|
|
|
78
80
|
A/B testing with sticky user-level assignment:
|
|
79
81
|
|
|
80
82
|
```ts
|
|
81
|
-
import {
|
|
83
|
+
import { insertExperiment, updateExperiment } from "@agent-native/core/observability";
|
|
82
84
|
|
|
83
|
-
const exp =
|
|
85
|
+
const exp = {
|
|
86
|
+
id: crypto.randomUUID(),
|
|
84
87
|
name: "sonnet-vs-haiku",
|
|
88
|
+
status: "draft" as const,
|
|
85
89
|
variants: [
|
|
86
90
|
{ id: "control", weight: 50, config: { model: "claude-sonnet-4-6" } },
|
|
87
91
|
{ id: "treatment", weight: 50, config: { model: "claude-haiku-4-5-20251001" } },
|
|
88
92
|
],
|
|
89
93
|
metrics: ["cost", "latency", "satisfaction"],
|
|
90
|
-
|
|
91
|
-
|
|
94
|
+
assignmentLevel: "user" as const,
|
|
95
|
+
startedAt: null,
|
|
96
|
+
endedAt: null,
|
|
97
|
+
createdAt: Date.now(),
|
|
98
|
+
};
|
|
99
|
+
await insertExperiment(exp);
|
|
100
|
+
// Move it to "running" when ready to start collecting assignments.
|
|
101
|
+
await updateExperiment(exp.id, { status: "running" });
|
|
92
102
|
```
|
|
93
103
|
|
|
94
104
|
The agent loop reads active experiments via `resolveActiveExperimentConfig()` and applies the variant's `model` override automatically. Assignment uses consistent hashing — same user always gets the same variant.
|
|
@@ -4,6 +4,8 @@ description: >-
|
|
|
4
4
|
How to register user-facing setup steps (API keys, OAuth, connecting
|
|
5
5
|
third-party services) for the sidebar setup checklist. Use when adding a
|
|
6
6
|
feature that needs initial user configuration.
|
|
7
|
+
metadata:
|
|
8
|
+
internal: true
|
|
7
9
|
---
|
|
8
10
|
|
|
9
11
|
# Onboarding Steps
|
|
@@ -12,10 +14,19 @@ description: >-
|
|
|
12
14
|
|
|
13
15
|
If a feature requires user-facing setup (API keys, OAuth, connecting a third-party service), register an onboarding step so it appears in the agent sidebar's setup checklist.
|
|
14
16
|
|
|
17
|
+
Onboarding must point users to a secure credential path; it must never encode
|
|
18
|
+
the credential value in source, docs, fixtures, prompts, or generated content.
|
|
19
|
+
For API keys and service tokens, prefer `registerRequiredSecret()` from the
|
|
20
|
+
`secrets` skill so the settings UI, encrypted storage, validation, and
|
|
21
|
+
onboarding checklist stay in one place. For OAuth, check the scoped OAuth token
|
|
22
|
+
store. Use deployment env vars only for deploy-level configuration, not
|
|
23
|
+
per-user credentials.
|
|
24
|
+
|
|
15
25
|
## Registering a Step
|
|
16
26
|
|
|
17
27
|
```ts
|
|
18
28
|
import { registerOnboardingStep } from "@agent-native/core/onboarding";
|
|
29
|
+
import { hasOAuthTokens } from "@agent-native/core/oauth-tokens";
|
|
19
30
|
|
|
20
31
|
registerOnboardingStep({
|
|
21
32
|
id: "gmail",
|
|
@@ -31,7 +42,8 @@ registerOnboardingStep({
|
|
|
31
42
|
payload: { url: "/_agent-native/google/auth-url" },
|
|
32
43
|
},
|
|
33
44
|
],
|
|
34
|
-
isComplete: () =>
|
|
45
|
+
isComplete: async (ctx) =>
|
|
46
|
+
ctx?.userEmail ? hasOAuthTokens("google", ctx.userEmail) : false,
|
|
35
47
|
});
|
|
36
48
|
```
|
|
37
49
|
|
|
@@ -4,17 +4,19 @@ description: >-
|
|
|
4
4
|
How to keep template code database-agnostic and hosting-agnostic. Use when
|
|
5
5
|
defining schemas, writing raw SQL, creating server routes, or anything that
|
|
6
6
|
could leak a SQLite-only, Postgres-only, or Node-only assumption.
|
|
7
|
+
metadata:
|
|
8
|
+
internal: true
|
|
7
9
|
---
|
|
8
10
|
|
|
9
11
|
# Portability
|
|
10
12
|
|
|
11
13
|
## Rule
|
|
12
14
|
|
|
13
|
-
**Never write code that only works on one database or one hosting platform.** Templates must run on
|
|
15
|
+
**Never write code that only works on one database or one hosting platform.** Templates must run on portable SQL backends (SQLite, Postgres, D1, Turso/libSQL, Supabase, Neon, managed platform SQL environments when available) and any Nitro deploy target (Node, Cloudflare, Netlify, Vercel, Deno, Lambda, Bun) without code changes.
|
|
14
16
|
|
|
15
17
|
## Database Agnostic
|
|
16
18
|
|
|
17
|
-
Use the dialect-agnostic schema helpers from `@agent-native/core/db/schema
|
|
19
|
+
Use the dialect-agnostic schema helpers from `@agent-native/core/db/schema` for schemas and Drizzle's query builder for reads/writes:
|
|
18
20
|
|
|
19
21
|
```ts
|
|
20
22
|
import {
|
|
@@ -47,6 +49,20 @@ export const meals = table("meals", {
|
|
|
47
49
|
|
|
48
50
|
**Never import from `drizzle-orm/sqlite-core` or `drizzle-orm/pg-core` directly in template code.** Always use `@agent-native/core/db/schema` instead.
|
|
49
51
|
|
|
52
|
+
Use Drizzle's portable query DSL for app code:
|
|
53
|
+
|
|
54
|
+
```ts
|
|
55
|
+
import { and, desc, eq } from "drizzle-orm";
|
|
56
|
+
|
|
57
|
+
const rows = await db
|
|
58
|
+
.select()
|
|
59
|
+
.from(meals)
|
|
60
|
+
.where(and(eq(meals.ownerEmail, userEmail), eq(meals.archived, false)))
|
|
61
|
+
.orderBy(desc(meals.createdAt));
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
Avoid `db.execute(...)`, `getDbExec()`, and handwritten SQL in actions, handlers, and stores when Drizzle can express the query. Raw SQL should be limited to additive migrations, health checks, carefully reviewed advanced queries, or one-off maintenance scripts. For timestamps in Drizzle schemas, use `.default(now())`; for migration SQL, use `runMigrations()` so framework-supported compatibility rewrites and dialect-gated statements stay centralized.
|
|
65
|
+
|
|
50
66
|
### Raw SQL helpers
|
|
51
67
|
|
|
52
68
|
- `getDbExec()` — auto-converts `?` params to `$1` for Postgres
|
|
@@ -55,7 +71,11 @@ export const meals = table("meals", {
|
|
|
55
71
|
|
|
56
72
|
### Never
|
|
57
73
|
|
|
58
|
-
Never write SQLite-only syntax: `INSERT OR REPLACE`, `AUTOINCREMENT`, `datetime('now')`. When writing docs, say "SQL database" — not "SQLite".
|
|
74
|
+
Never write SQLite-only syntax in product code or docs examples: `INSERT OR REPLACE`, `AUTOINCREMENT`, `datetime('now')`. When writing docs, say "SQL database" — not "SQLite".
|
|
75
|
+
|
|
76
|
+
Never write Postgres-only syntax in shared app code either: `ILIKE`, `::type` casts, `jsonb_*`, `RETURNING` assumptions, serial/identity syntax, `ON CONFLICT` upserts, or `ALTER ... TYPE` unless the code is inside a dialect-gated migration block. Prefer Drizzle APIs or framework helpers.
|
|
77
|
+
|
|
78
|
+
When giving deployment guidance, be precise about durability: local SQLite is the development fallback, while production needs a persistent `DATABASE_URL`. Do not steer users to Turso as the only path; it is one option among Neon, Supabase, Turso/libSQL, plain Postgres, durable SQLite, D1 bindings, and managed platform SQL environments when available.
|
|
59
79
|
|
|
60
80
|
## Hosting Agnostic
|
|
61
81
|
|
|
@@ -65,9 +85,11 @@ The server runs on **Nitro** with **H3** as the HTTP framework. Templates must b
|
|
|
65
85
|
|
|
66
86
|
All server code uses H3/Nitro: `defineEventHandler`, `readBody`, `getMethod`, `setResponseHeader`, etc. Express is not a dependency. If you see Express types or patterns anywhere, replace them with H3 equivalents.
|
|
67
87
|
|
|
68
|
-
### No platform-specific config in
|
|
88
|
+
### No platform-specific config in scaffolded template source
|
|
89
|
+
|
|
90
|
+
Files like `netlify.toml`, `wrangler.toml`, `vercel.json`, and `netlify/functions/` must NOT appear in the CLI scaffold source (`packages/core/src/templates/`) — apps generated for users stay hosting-agnostic, with platform configuration living in CI/hosting dashboards.
|
|
69
91
|
|
|
70
|
-
|
|
92
|
+
**Exception:** this monorepo's own first-party deployed apps (`templates/*/netlify.toml`, the root `wrangler-*.toml` files) are deployment artifacts of _this_ repo (mail.agent-native.com, etc.) and are expected to exist. Do not delete them as if they were accidental cruft — the rule above is about what gets scaffolded into a new app, not about this repo's deploy configs.
|
|
71
93
|
|
|
72
94
|
### No Node APIs in server routes/plugins
|
|
73
95
|
|
|
@@ -5,6 +5,8 @@ description: >-
|
|
|
5
5
|
apps end-to-end, finding and fixing bugs, or running a QA sweep. Invoke as
|
|
6
6
|
/qa with optional --apps and --focus args.
|
|
7
7
|
user-invocable: true
|
|
8
|
+
metadata:
|
|
9
|
+
internal: true
|
|
8
10
|
---
|
|
9
11
|
|
|
10
12
|
# QA Testing
|
|
@@ -19,6 +21,15 @@ Autonomous QA testing that spins up template apps, tests them with Playwright in
|
|
|
19
21
|
/qa --focus "test form submission and compose" # prioritize specific flows
|
|
20
22
|
```
|
|
21
23
|
|
|
24
|
+
## Browser MCP Readiness
|
|
25
|
+
|
|
26
|
+
QA can use the framework's built-in browser MCP capabilities instead of a hand-written `mcp.config.json`. The built-ins are off by default and are toggled through `/_agent-native/mcp/builtin`.
|
|
27
|
+
|
|
28
|
+
- Prefer `browser-playwright` for automated QA sweeps: it runs `npx -y @playwright/mcp@0.0.75`.
|
|
29
|
+
- Use `browser-chrome-devtools` only when the test specifically needs to attach to a live Chrome session. It runs `npx -y chrome-devtools-mcp@0.26.0 --autoConnect --no-usage-statistics` and requires Chrome 144+ with remote debugging enabled. Do not assume it signs into the user's Chrome profile.
|
|
30
|
+
- Browser built-ins are exclusive per scope: enabling Chrome disables Playwright and enabling Playwright disables Chrome.
|
|
31
|
+
- `computer-use` runs `npx -y computer-use-mcp@1.8.0` and is macOS-only.
|
|
32
|
+
|
|
22
33
|
**Args:**
|
|
23
34
|
|
|
24
35
|
- `--apps` — comma-separated app names (default: `mail,calendar,content,forms`)
|
|
@@ -39,14 +50,16 @@ Parse the user's invocation to determine:
|
|
|
39
50
|
|
|
40
51
|
For each app, check if required credentials exist:
|
|
41
52
|
|
|
42
|
-
| App | Check
|
|
43
|
-
|
|
44
|
-
| forms | No credentials needed
|
|
45
|
-
| content | No credentials needed (Notion is opt-in)
|
|
46
|
-
| calendar | `templates/calendar/.env` has GOOGLE_CLIENT_ID | Partially — local events work, Google sync won't |
|
|
47
|
-
| mail | `templates/mail/.env` has GOOGLE_CLIENT_ID | Partially — UI renders, Gmail features won't |
|
|
53
|
+
| App | Check | Can test without? |
|
|
54
|
+
| -------- | -------------------------------------------------------- | ----------------- |
|
|
55
|
+
| forms | No credentials needed | Yes |
|
|
56
|
+
| content | No credentials needed (Notion is opt-in) | Yes |
|
|
57
|
+
| calendar | `templates/calendar/.env` has `GOOGLE_CLIENT_ID` present | Partially — local events work, Google sync won't |
|
|
58
|
+
| mail | `templates/mail/.env` has `GOOGLE_CLIENT_ID` present | Partially — UI renders, Gmail features won't |
|
|
48
59
|
|
|
49
|
-
Read each app's `.env` file (if it exists) to check
|
|
60
|
+
Read each app's `.env` file (if it exists) only to check whether required names
|
|
61
|
+
are present. Never print, copy, summarize, paste, or pass `.env` values into
|
|
62
|
+
tester prompts, reports, screenshots, logs, or chat. If credentials are missing:
|
|
50
63
|
|
|
51
64
|
- Still test the app — many features work without external APIs
|
|
52
65
|
- Include in the tester's instructions: "No Google credentials found. Test local features. Flag any feature that crashes without credentials as 'needs credentials' rather than a bug."
|
|
@@ -79,7 +92,8 @@ For each app, read these files to understand what to test:
|
|
|
79
92
|
|
|
80
93
|
1. `templates/<app>/app/routes/` or `templates/<app>/app/routes.ts` — discover all pages
|
|
81
94
|
2. `templates/<app>/CLAUDE.md` — features, API routes, data model
|
|
82
|
-
3. `templates/<app>/
|
|
95
|
+
3. `templates/<app>/actions/` — domain operations the UI and agent share
|
|
96
|
+
4. `templates/<app>/server/routes/api/` — route-only endpoints such as uploads, streaming, webhooks, and OAuth callbacks
|
|
83
97
|
|
|
84
98
|
Combine with any `--focus` guidance to produce a test plan. The test plan is a numbered list of user-facing flows to verify. Example:
|
|
85
99
|
|
|
@@ -311,3 +325,5 @@ This is a known issue. The tester should:
|
|
|
311
325
|
3. Check the server plugin that loads credentials
|
|
312
326
|
4. Try to fix the credential detection logic
|
|
313
327
|
5. If unfixable, report as "needs review" with details about what the app expects vs. what's configured
|
|
328
|
+
|
|
329
|
+
Only report variable names and presence/absence. Do not include secret values.
|
|
@@ -4,6 +4,8 @@ description: >-
|
|
|
4
4
|
Multi-user collaborative editing with Yjs CRDT and live cursors. Use when
|
|
5
5
|
adding real-time collaborative editing to a template, debugging sync issues,
|
|
6
6
|
or understanding how the agent and humans edit documents simultaneously.
|
|
7
|
+
metadata:
|
|
8
|
+
internal: true
|
|
7
9
|
---
|
|
8
10
|
|
|
9
11
|
# Real-Time Collaboration
|
|
@@ -23,11 +25,55 @@ Collaborative editing uses Yjs CRDT via TipTap. The agent and human users are eq
|
|
|
23
25
|
## Agent + Human Editing
|
|
24
26
|
|
|
25
27
|
1. **Human edits** → TipTap → ySyncPlugin → Y.XmlFragment → `POST /_agent-native/collab/:docId/update`
|
|
26
|
-
2. **Agent edits** → `
|
|
28
|
+
2. **Agent edits** → action edits canonical SQL content + bumps `updatedAt` → change-sync refetch → the open editor reconciles the new content into the live Y.Doc (see below) → poll update → all clients
|
|
27
29
|
|
|
28
|
-
Both produce
|
|
30
|
+
Both produce Yjs operations that merge cleanly. Agent edits appear without destroying cursor position, selection, or undo history.
|
|
29
31
|
|
|
30
|
-
The
|
|
32
|
+
This is how content (documents) and slides now work. The agent does **not** push edits into Yjs in-process, and it does **not** call any `findCollabOrigin()` / localhost probe — that approach silently no-op'd on serverless (the action runs in a different process), so agent edits didn't show up live until the user navigated away and back. Nor does it search-and-replace inside existing Y.XmlText nodes, which could never create new block structure (lists, headings, tables). The peer-editor model below replaces both.
|
|
33
|
+
|
|
34
|
+
## Agent Edits As A Real-Time Peer Editor
|
|
35
|
+
|
|
36
|
+
The agent edits documents the same way a human collaborator does: its change lands in the shared Y.Doc, propagates to every connected client, and persists. It gets there without any in-process Yjs push from the action.
|
|
37
|
+
|
|
38
|
+
**SQL is the durable source of truth for document body content.** The agent action edits the canonical content (e.g. `documents.content`) and bumps `updatedAt`. That's the whole server side — no localhost calls, no Yjs mutation from the action.
|
|
39
|
+
|
|
40
|
+
**The open editor reconciles authoritative external content into the live Y.Doc.** The action's `updatedAt` bump flows through the change-sync system (see `real-time-sync`), which refetches the record. The editor applies the new content through its real markdown/HTML pipeline via `setContent`, so new block structure (lists, headings, tables) renders correctly and merges with concurrent human edits through the Yjs CRDT diff. The result: the agent's edit propagates to every connected client and persists, exactly like a human collaborator's edit.
|
|
41
|
+
|
|
42
|
+
### The `updatedAt` gate
|
|
43
|
+
|
|
44
|
+
The editor only adopts content that is genuinely **newer** than what it already reflects. An older-or-equal `updatedAt` is a lagging poll or a stale snapshot and is **ignored**.
|
|
45
|
+
|
|
46
|
+
```ts
|
|
47
|
+
// Pseudocode in the editor's reconcile effect
|
|
48
|
+
if (loaded.updatedAt > lastAppliedUpdatedAt.current) {
|
|
49
|
+
applyAuthoritativeContent(loaded.content); // adopt
|
|
50
|
+
lastAppliedUpdatedAt.current = loaded.updatedAt;
|
|
51
|
+
}
|
|
52
|
+
// else: lagging poll / stale snapshot → ignore
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
**Why:** without the gate, a slightly-behind poll response re-applies old content right after the agent's edit, so the edit "reverts on the next poll" / "doesn't show until refresh" — the whack-a-mole we kept hitting. A **fresh mount or doc-switch has no baseline**, so it always adopts whatever content it loaded — which is why a manual refresh is always correct.
|
|
56
|
+
|
|
57
|
+
### Lead-client election
|
|
58
|
+
|
|
59
|
+
Exactly ONE connected client applies an authoritative snapshot into the shared Y.Doc; the rest receive it through normal Yjs sync. The lead is the present client with the lowest Yjs `clientID`, decided by the core helper:
|
|
60
|
+
|
|
61
|
+
```ts
|
|
62
|
+
import { isReconcileLeadClient } from "@agent-native/core/client";
|
|
63
|
+
|
|
64
|
+
if (
|
|
65
|
+
loaded.updatedAt > lastAppliedUpdatedAt.current &&
|
|
66
|
+
isReconcileLeadClient(provider.awareness, ydoc.clientID)
|
|
67
|
+
) {
|
|
68
|
+
applyAuthoritativeContent(loaded.content);
|
|
69
|
+
}
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
**Why:** if every open editor independently diffed the same snapshot into the CRDT, each would insert the changed region at the same position, duplicating it N times (concurrent inserts → duplicated text). Electing one lead avoids that. The agent's awareness id (`AGENT_CLIENT_ID`, max int) can never win, and a client editing alone is always the lead. The election is deterministic across clients with no coordination round-trip.
|
|
73
|
+
|
|
74
|
+
### v1 limitation
|
|
75
|
+
|
|
76
|
+
A full-content reconcile is **last-writer-wins for the rare case** where a human has unsaved edits in the exact region the agent simultaneously rewrites — the agent's snapshot can clobber that in-flight human edit. Inline and structural edits in **different** regions merge fine through the CRDT; only same-region simultaneous rewrites are at risk.
|
|
31
77
|
|
|
32
78
|
## Enabling Collaboration
|
|
33
79
|
|
|
@@ -101,12 +147,12 @@ optimizeDeps: {
|
|
|
101
147
|
## Common Pitfalls
|
|
102
148
|
|
|
103
149
|
- **Don't pass `content` as a TipTap prop** when Collaboration is enabled — Yjs owns the content. Set initial content via the Y.Doc instead.
|
|
104
|
-
- **Don't
|
|
150
|
+
- **Don't call `editor.setContent()` ad hoc for agent edits.** The only sanctioned `setContent` is the editor's reconcile path described above — gated by `updatedAt` and guarded by `isReconcileLeadClient`. Calling it from elsewhere (e.g. on every poll, or from every client) re-applies stale content or duplicates the changed region across the CRDT.
|
|
105
151
|
- **Add packages to `optimizeDeps`** — Vite won't pre-bundle Yjs packages correctly otherwise, causing runtime errors in dev.
|
|
106
152
|
- **One `Y.Doc` per document** — Don't create multiple Y.Doc instances for the same document ID. Use the `useCollaborativeDoc` hook which caches by ID.
|
|
107
153
|
|
|
108
154
|
## Related Skills
|
|
109
155
|
|
|
110
|
-
- `real-time-sync` —
|
|
111
|
-
- `storing-data` — The `_collab_docs` table where Yjs state is persisted
|
|
112
|
-
- `self-modifying-code` — Agent edits to collaborative documents
|
|
156
|
+
- `real-time-sync` — The change-sync system that delivers the `updatedAt` bump driving editor reconciliation; also `useReconciledState` for non-collaborative "copy a server value into local edit state" surfaces
|
|
157
|
+
- `storing-data` — The `_collab_docs` table where Yjs state is persisted; SQL holds the canonical document body that the editor reconciles from
|
|
158
|
+
- `self-modifying-code` — Agent edits to collaborative documents edit canonical SQL content, not raw Yjs
|
|
@@ -4,6 +4,8 @@ description: >-
|
|
|
4
4
|
How to keep the UI in sync with agent changes via SSE plus polling fallback.
|
|
5
5
|
Use when wiring query invalidation for new data models, debugging UI not
|
|
6
6
|
updating, or understanding jitter prevention.
|
|
7
|
+
metadata:
|
|
8
|
+
internal: true
|
|
7
9
|
---
|
|
8
10
|
|
|
9
11
|
# Real-Time Sync
|
|
@@ -20,7 +22,7 @@ The agent modifies data in SQL, but the UI runs in the browser. SSE bridges same
|
|
|
20
22
|
|
|
21
23
|
1. **Server** increments a version counter on every database write. In-process events stream through the authenticated `/_agent-native/events` endpoint.
|
|
22
24
|
|
|
23
|
-
2. **Client** listens for
|
|
25
|
+
2. **Client** listens for sync events and updates per-source change counters:
|
|
24
26
|
|
|
25
27
|
```ts
|
|
26
28
|
import { useDbSync } from "@agent-native/core";
|
|
@@ -47,9 +49,9 @@ The agent modifies data in SQL, but the UI runs in the browser. SSE bridges same
|
|
|
47
49
|
|
|
48
50
|
For list/sidebar queries, use the same pattern — pass the counter into the queryKey of every list query you want to keep fresh.
|
|
49
51
|
|
|
50
|
-
|
|
52
|
+
4. **Fallback** polling calls `/_agent-native/poll?since=N`. It runs every 2 seconds until SSE is connected, then relaxes to 15 seconds. If SSE is disabled or unavailable, polling continues at the normal cadence.
|
|
51
53
|
|
|
52
|
-
|
|
54
|
+
5. When the agent writes to the database, the version increments, SSE/polling detects it, and React Query refetches the affected queries.
|
|
53
55
|
|
|
54
56
|
## Don't
|
|
55
57
|
|
|
@@ -132,9 +134,9 @@ The `use-navigation-state.ts` hook sends the same `TAB_ID` in the `X-Request-Sou
|
|
|
132
134
|
|
|
133
135
|
Without jitter prevention, a cycle occurs: the UI writes state, sync detects the change, the UI refetches and re-renders, potentially overwriting what the user is actively editing. With `ignoreSource`, the UI only reacts to changes from other sources (agent scripts, other browser tabs, other users).
|
|
134
136
|
|
|
135
|
-
## Action Routes and
|
|
137
|
+
## Action Routes and Live Sync
|
|
136
138
|
|
|
137
|
-
|
|
139
|
+
Actions work with the same sync system. When a mutating action writes to the database, the version counter increments and `useDbSync` picks up the change. Frontend mutations via `useActionMutation` automatically invalidate `["action"]` query keys on success, triggering refetches of `useActionQuery` hooks. Client components should call actions through those hooks, not with raw action-route fetches.
|
|
138
140
|
|
|
139
141
|
For custom apps, the best out-of-the-box path is:
|
|
140
142
|
|
|
@@ -146,14 +148,13 @@ This avoids duplicate `/api/*` JSON CRUD routes and makes agent-created records
|
|
|
146
148
|
|
|
147
149
|
### Auto-emit on mutating actions
|
|
148
150
|
|
|
149
|
-
The framework emits a
|
|
151
|
+
The framework emits a change event with `source: "action"` whenever any non-read-only action runs to completion — whether called via HTTP (`/_agent-native/actions/:name`) or as an agent tool call. Read-only actions (`http: { method: "GET" }` or explicit `readOnly: true`) are skipped.
|
|
150
152
|
|
|
151
153
|
This means UIs don't need the agent to remember to call `refresh-screen` after every mutation. A listener like this (used in the `macros` template) will refresh after any mutating agent call:
|
|
152
154
|
|
|
153
155
|
```ts
|
|
154
156
|
useDbSync({
|
|
155
157
|
queryClient,
|
|
156
|
-
queryKeys: [],
|
|
157
158
|
ignoreSource: TAB_ID,
|
|
158
159
|
onEvent: (data) => {
|
|
159
160
|
if (data.requestSource === TAB_ID) return;
|
|
@@ -165,9 +166,41 @@ useDbSync({
|
|
|
165
166
|
|
|
166
167
|
`refresh-screen` remains available for unusual cases — e.g. the agent mutated data via a path the framework can't see (external system the app mirrors), or the agent wants to pass a `scope` hint for narrower invalidation.
|
|
167
168
|
|
|
169
|
+
## Keeping Stateful Components In Sync
|
|
170
|
+
|
|
171
|
+
The `useChangeVersion` / `useActionQuery` pattern above keeps the **query layer** fresh. But components that copy a server value into local React state still go stale on agent edits — refetching the query updates the prop, yet the local copy never re-adopts it. This is a recurring bug.
|
|
172
|
+
|
|
173
|
+
**Never do this** for a value the agent can mutate:
|
|
174
|
+
|
|
175
|
+
```ts
|
|
176
|
+
// BUG: `title` is captured once and never re-reads the prop.
|
|
177
|
+
const [title, setTitle] = useState(props.title);
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
When the agent renames the record, the query refetches, `props.title` updates, but the input still shows the stale value until the component remounts.
|
|
181
|
+
|
|
182
|
+
**Derived-state surfaces (form fields, inline editors, popovers): use `useReconciledState`.** It re-adopts the authoritative external value when it changes, except while the user is actively editing that field — so agent mutations show up live without clobbering in-progress typing:
|
|
183
|
+
|
|
184
|
+
```ts
|
|
185
|
+
import { useReconciledState } from "@agent-native/core/client";
|
|
186
|
+
|
|
187
|
+
// `active` = true while the user is editing this field (focused / dirty).
|
|
188
|
+
const [title, setTitle] = useReconciledState(props.title, { active: isEditing });
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
**Collaborative rich-text editors are different** — they don't copy a value into `useState`. They reconcile authoritative SQL content into a shared Y.Doc under an `updatedAt` gate with lead-client election. See `real-time-collab` → "Agent edits as a real-time peer editor". Don't reach for `useReconciledState` for a Yjs-backed editor.
|
|
192
|
+
|
|
193
|
+
| Surface | Keep it fresh with |
|
|
194
|
+
| ------- | ------------------ |
|
|
195
|
+
| React Query reads | `useChangeVersion` / `useActionQuery` (above) |
|
|
196
|
+
| Local edit state copied from a server value (inputs, popovers, inline editors) | `useReconciledState(externalValue, { active })` |
|
|
197
|
+
| Collaborative rich-text editor (Yjs) | `updatedAt`-gated reconcile + `isReconcileLeadClient` — see `real-time-collab` |
|
|
198
|
+
|
|
168
199
|
## Related Skills
|
|
169
200
|
|
|
170
|
-
- **storing-data** — Application-state and settings are
|
|
201
|
+
- **storing-data** — Application-state and settings are data stores that sync through change events
|
|
171
202
|
- **context-awareness** — Navigation state writes use jitter prevention to avoid overwriting active edits
|
|
172
|
-
- **actions** —
|
|
173
|
-
- **
|
|
203
|
+
- **actions** — Mutating actions trigger change events
|
|
204
|
+
- **client-methods** — Route details belong in helpers/hooks, not components
|
|
205
|
+
- **self-modifying-code** — Agent code edits trigger change events; rapid edits can cause event storms
|
|
206
|
+
- **real-time-collab** — Collaborative editors reconcile agent edits into a shared Y.Doc, driven by the same change-sync `updatedAt` bump
|
|
@@ -4,6 +4,8 @@ description: >-
|
|
|
4
4
|
Scheduled tasks the agent runs on a cron schedule. Use when a user asks for
|
|
5
5
|
something recurring ("every morning", "daily", "weekly"), when creating or
|
|
6
6
|
updating jobs, or when debugging the job scheduler.
|
|
7
|
+
metadata:
|
|
8
|
+
internal: true
|
|
7
9
|
---
|
|
8
10
|
|
|
9
11
|
# Recurring Jobs
|
|
@@ -5,10 +5,24 @@ description: >-
|
|
|
5
5
|
they appear in the agent sidebar settings UI and the onboarding checklist.
|
|
6
6
|
Use for any third-party API key (OpenAI, Stripe, Twilio, etc.) and for
|
|
7
7
|
surfacing OAuth connections in the unified settings UI.
|
|
8
|
+
metadata:
|
|
9
|
+
internal: true
|
|
8
10
|
---
|
|
9
11
|
|
|
10
12
|
# Secrets Registry
|
|
11
13
|
|
|
14
|
+
## Non-negotiable rule
|
|
15
|
+
|
|
16
|
+
Never hardcode credential values. Source, docs, tests, fixtures, prompts, seed
|
|
17
|
+
data, and generated extension/app content may mention credential **names** such
|
|
18
|
+
as `OPENAI_API_KEY`, but must not contain real API keys, tokens, webhook URLs,
|
|
19
|
+
signing secrets, OAuth refresh tokens, or private Builder/customer data.
|
|
20
|
+
|
|
21
|
+
Secret values are supplied at runtime through deployment configuration, the
|
|
22
|
+
encrypted `app_secrets` vault, `saveCredential` / `resolveCredential`, OAuth, or
|
|
23
|
+
`${keys.NAME}` substitution. Examples must use obvious placeholders such as
|
|
24
|
+
`<OPENAI_API_KEY>` or `${keys.SLACK_WEBHOOK}`, not real-looking copied values.
|
|
25
|
+
|
|
12
26
|
## When to use
|
|
13
27
|
|
|
14
28
|
Use this for any external credential your template needs: API keys, service
|
|
@@ -96,25 +110,24 @@ row is written — status is derived from `hasOAuthTokens("google")`.
|
|
|
96
110
|
## Reading a secret from an action
|
|
97
111
|
|
|
98
112
|
```ts
|
|
113
|
+
import { z } from "zod";
|
|
99
114
|
import { defineAction } from "@agent-native/core";
|
|
100
115
|
import { readAppSecret } from "@agent-native/core/secrets";
|
|
101
|
-
import {
|
|
116
|
+
import { getRequestUserEmail } from "@agent-native/core/server";
|
|
102
117
|
|
|
103
118
|
export default defineAction({
|
|
104
|
-
name: "transcribe-audio",
|
|
105
119
|
description: "Transcribe an audio file with Whisper",
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
const
|
|
109
|
-
if (!
|
|
120
|
+
schema: z.object({ fileUrl: z.string() }),
|
|
121
|
+
run: async ({ fileUrl }) => {
|
|
122
|
+
const email = await getRequestUserEmail();
|
|
123
|
+
if (!email) throw new Error("Not signed in");
|
|
110
124
|
|
|
111
125
|
const stored = await readAppSecret({
|
|
112
126
|
key: "OPENAI_API_KEY",
|
|
113
127
|
scope: "user",
|
|
114
|
-
scopeId:
|
|
128
|
+
scopeId: email,
|
|
115
129
|
});
|
|
116
|
-
|
|
117
|
-
const apiKey = process.env.OPENAI_API_KEY ?? stored?.value;
|
|
130
|
+
const apiKey = stored?.value;
|
|
118
131
|
if (!apiKey) {
|
|
119
132
|
throw new Error(
|
|
120
133
|
"OPENAI_API_KEY is not set. Configure it in the sidebar settings.",
|
|
@@ -130,8 +143,10 @@ Rules:
|
|
|
130
143
|
|
|
131
144
|
- **Never log the value.** The read layer enforces this server-side; your
|
|
132
145
|
code must do the same.
|
|
133
|
-
- **
|
|
134
|
-
|
|
146
|
+
- **Use env vars only for deploy-level secrets.** If a credential is
|
|
147
|
+
user-scoped, org-scoped, or workspace-scoped, read the scoped vault/credential
|
|
148
|
+
store. Do not add a `process.env` fallback that makes every user inherit one
|
|
149
|
+
deployment's key.
|
|
135
150
|
- **Scope matches the registration.** `scope: "user"` → pass the user email.
|
|
136
151
|
`scope: "workspace"` → pass the active `orgId` from
|
|
137
152
|
`getOrgContext(event).orgId`.
|
|
@@ -187,7 +202,7 @@ with any URL.
|
|
|
187
202
|
POST /_agent-native/secrets/adhoc
|
|
188
203
|
{
|
|
189
204
|
"name": "SLACK_WEBHOOK",
|
|
190
|
-
"value": "
|
|
205
|
+
"value": "<SLACK_WEBHOOK_URL_FROM_SETTINGS>",
|
|
191
206
|
"urlAllowlist": ["https://hooks.slack.com"]
|
|
192
207
|
}
|
|
193
208
|
```
|
|
@@ -208,12 +223,12 @@ import {
|
|
|
208
223
|
const { resolved, usedKeys } = await resolveKeyReferences(
|
|
209
224
|
"Bearer ${keys.API_TOKEN}",
|
|
210
225
|
"user",
|
|
211
|
-
"
|
|
226
|
+
"user@example.com",
|
|
212
227
|
);
|
|
213
228
|
|
|
214
229
|
// Validate a URL against a key's allowlist
|
|
215
230
|
const allowed = validateUrlAllowlist(
|
|
216
|
-
"https://hooks.slack.com/services
|
|
231
|
+
"https://hooks.slack.com/services/<WORKSPACE>/<CHANNEL>/<SECRET>",
|
|
217
232
|
["https://hooks.slack.com"],
|
|
218
233
|
);
|
|
219
234
|
```
|
|
@@ -222,6 +237,20 @@ Key resolution falls back from user scope to workspace scope, so users can
|
|
|
222
237
|
override shared keys without breaking automations that reference workspace
|
|
223
238
|
defaults.
|
|
224
239
|
|
|
240
|
+
## Dispatch Vault Access
|
|
241
|
+
|
|
242
|
+
Dispatch workspaces have a vault access policy for workspace app credentials:
|
|
243
|
+
|
|
244
|
+
- `all-apps` is the default. Every saved Dispatch vault key is available to
|
|
245
|
+
every workspace app; `sync-vault-to-app` pushes all vault keys to the target
|
|
246
|
+
app.
|
|
247
|
+
- `manual` requires explicit per-app grants. Use
|
|
248
|
+
`create-vault-grant` / `grant-vault-secrets-to-app`, then
|
|
249
|
+
`sync-vault-to-app`.
|
|
250
|
+
|
|
251
|
+
Use `get-vault-access-settings` before deciding whether to create grants, and
|
|
252
|
+
use `set-vault-access-settings` only when the user asks to change the policy.
|
|
253
|
+
|
|
225
254
|
### Key Files (ad-hoc)
|
|
226
255
|
|
|
227
256
|
| File | Purpose |
|