@agent-native/core 0.132.1 → 0.133.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/corpus/README.md +2 -2
- package/corpus/core/CHANGELOG.md +198 -0
- package/corpus/core/package.json +1 -1
- package/corpus/core/src/a2a/correlation.ts +11 -1
- package/corpus/core/src/a2a/types.ts +11 -3
- package/corpus/core/src/agent/engine/ai-sdk-engine.ts +33 -46
- package/corpus/core/src/agent/engine/builder-engine.ts +22 -10
- package/corpus/core/src/agent/engine/error-detail.ts +184 -3
- package/corpus/core/src/agent/engine/failure-taxonomy.ts +123 -0
- package/corpus/core/src/agent/engine/index.ts +8 -0
- package/corpus/core/src/agent/engine/registry.ts +92 -8
- package/corpus/core/src/agent/engine/translate-ai-sdk.ts +17 -2
- package/corpus/core/src/agent/production-agent.ts +13 -33
- package/corpus/core/src/agent/run-loop-with-resume.ts +1 -1
- package/corpus/core/src/agent/run-manager.ts +43 -14
- package/corpus/core/src/agent/run-store.ts +30 -3
- package/corpus/core/src/agent/thread-data-builder.ts +36 -4
- package/corpus/core/src/chat-threads/store.ts +42 -0
- package/corpus/core/src/cli/templates-meta.ts +13 -0
- package/corpus/core/src/cli/workspace-dev.ts +1 -0
- package/corpus/core/src/client/error-format.ts +12 -0
- package/corpus/core/src/client/use-chat-threads.ts +76 -16
- package/corpus/core/src/credentials/index.ts +51 -12
- package/corpus/core/src/extensions/url-safety.ts +46 -12
- package/corpus/core/src/integrations/adapters/slack.ts +32 -10
- package/corpus/core/src/integrations/google-docs-poller.ts +12 -1
- package/corpus/core/src/integrations/installations-store.ts +30 -0
- package/corpus/core/src/integrations/plugin.ts +5 -5
- package/corpus/core/src/integrations/types.ts +7 -0
- package/corpus/core/src/integrations/webhook-handler.ts +24 -1
- package/corpus/core/src/jobs/background-automation-runner.ts +38 -1
- package/corpus/core/src/provider-api/index.ts +8 -2
- package/corpus/core/src/scripts/call-agent.ts +6 -0
- package/corpus/core/src/server/agent-chat-plugin.ts +46 -10
- package/corpus/core/src/server/agent-discovery.ts +2 -0
- package/corpus/core/src/server/builder-design-systems.ts +21 -0
- package/corpus/core/src/server/credential-provider.ts +51 -12
- package/corpus/core/src/server/index.ts +1 -0
- package/corpus/core/src/server/onboarding-html.ts +37 -2
- package/corpus/core/src/shared/reasoning-effort.ts +1 -1
- package/corpus/core/src/templates/workspace-core/.agents/skills/a2a-protocol/SKILL.md +11 -0
- package/corpus/templates/analytics/app/components/layout/Sidebar.tsx +6 -2
- package/corpus/templates/assets/app/components/layout/Sidebar.tsx +39 -19
- package/corpus/templates/assets/changelog/2026-07-31-the-agent-native-logo-stays-visible-when-the-sidebar-is-coll.md +6 -0
- package/corpus/templates/brain/app/components/layout/Sidebar.tsx +30 -3
- package/corpus/templates/brain/changelog/2026-07-31-clicking-the-agent-native-logo-now-toggles-the-app-sidebar.md +6 -0
- package/corpus/templates/calendar/app/components/layout/AppLayout.tsx +1 -1
- package/corpus/templates/calendar/app/components/layout/Sidebar.tsx +54 -25
- package/corpus/templates/calendar/changelog/2026-07-31-the-agent-native-logo-stays-visible-when-the-sidebar-is-coll.md +6 -0
- package/corpus/templates/chat/app/components/layout/Sidebar.tsx +30 -3
- package/corpus/templates/chat/changelog/2026-07-31-clicking-the-agent-native-logo-now-toggles-the-app-sidebar.md +6 -0
- package/corpus/templates/clips/app/components/library/library-layout.tsx +37 -21
- package/corpus/templates/clips/changelog/2026-07-30-meeting-microphone-transcription-works-reliably-from-the-fir.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-31-the-agent-native-logo-stays-visible-when-the-sidebar-is-coll.md +6 -0
- package/corpus/templates/clips/desktop/src/hooks/useMediaDevices.ts +1 -1
- package/corpus/templates/clips/desktop/src/lib/media-capture-constraints.ts +1 -1
- package/corpus/templates/clips/desktop/src-tauri/src/native_screen/custom_capture.rs +13 -0
- package/corpus/templates/clips/desktop/src-tauri/src/native_screen.rs +2 -0
- package/corpus/templates/clips/desktop/src-tauri/src/system_audio.rs +25 -132
- package/corpus/templates/content/app/components/sidebar/DocumentSidebar.tsx +34 -17
- package/corpus/templates/content/changelog/2026-07-31-the-agent-native-logo-stays-visible-when-the-sidebar-is-coll.md +6 -0
- package/corpus/templates/design/.agents/skills/design-systems/SKILL.md +6 -2
- package/corpus/templates/design/.generated/bridge/editor-chrome.generated.ts +5 -0
- package/corpus/templates/design/actions/create-design-system.ts +1 -0
- package/corpus/templates/design/actions/set-default-design-system.ts +34 -26
- package/corpus/templates/design/app/components/design/KeyboardShortcutsPanel.tsx +5 -3
- package/corpus/templates/design/app/components/design/bridge/editor-chrome.bridge.ts +23 -0
- package/corpus/templates/design/app/components/design/keyboard-shortcuts.ts +3 -0
- package/corpus/templates/design/app/components/layout/Sidebar.tsx +21 -4
- package/corpus/templates/design/app/hooks/useDesignHotkeys.ts +11 -7
- package/corpus/templates/design/app/i18n-data.ts +39 -0
- package/corpus/templates/design/app/pages/DesignSystemSetup.tsx +229 -12
- package/corpus/templates/design/app/pages/DesignSystems.tsx +10 -4
- package/corpus/templates/design/changelog/2026-07-30-fixed-the-keyboard-shortcuts-panel-not-opening-with-ctrl-shi.md +6 -0
- package/corpus/templates/design/changelog/2026-07-31-clicking-the-agent-native-logo-now-toggles-the-app-sidebar.md +6 -0
- package/corpus/templates/design/changelog/2026-07-31-design-system-indexing-keeps-your-chosen-name-when-you-uploa.md +6 -0
- package/corpus/templates/design/server/lib/builder-design-system-proxy.ts +19 -4
- package/corpus/templates/dispatch/AGENTS.md +4 -0
- package/corpus/templates/factory/.agents/skills/actions/SKILL.md +562 -0
- package/corpus/templates/factory/.agents/skills/adding-a-feature/SKILL.md +198 -0
- package/corpus/templates/factory/.agents/skills/agent-native-docs/SKILL.md +115 -0
- package/corpus/templates/factory/.agents/skills/agent-native-toolkit/SKILL.md +182 -0
- package/corpus/templates/factory/.agents/skills/capture-learnings/SKILL.md +89 -0
- package/corpus/templates/factory/.agents/skills/create-skill/SKILL.md +221 -0
- package/corpus/templates/factory/.agents/skills/customizing-agent-native/SKILL.md +220 -0
- package/corpus/templates/factory/.agents/skills/delegate-to-agent/SKILL.md +263 -0
- package/corpus/templates/factory/.agents/skills/factory-graphs/SKILL.md +52 -0
- package/corpus/templates/factory/.agents/skills/feature-flags/SKILL.md +169 -0
- package/corpus/templates/factory/.agents/skills/frontend-design/SKILL.md +174 -0
- package/corpus/templates/factory/.agents/skills/real-time-sync/SKILL.md +232 -0
- package/corpus/templates/factory/.agents/skills/security/SKILL.md +324 -0
- package/corpus/templates/factory/.agents/skills/self-modifying-code/SKILL.md +119 -0
- package/corpus/templates/factory/.agents/skills/shadcn-ui/SKILL.md +123 -0
- package/corpus/templates/factory/.agents/skills/sharing/SKILL.md +232 -0
- package/corpus/templates/factory/.agents/skills/storing-data/SKILL.md +178 -0
- package/corpus/templates/factory/.agents/skills/upgrade-agent-native/SKILL.md +122 -0
- package/corpus/templates/factory/.env.example +24 -0
- package/corpus/templates/factory/.ignore +0 -0
- package/corpus/templates/factory/.oxfmtrc.json +8 -0
- package/corpus/templates/factory/AGENTS.md +90 -0
- package/corpus/templates/factory/CHANGELOG.md +10 -0
- package/corpus/templates/factory/DEVELOPING.md +185 -0
- package/corpus/templates/factory/README.md +64 -0
- package/corpus/templates/factory/_gitignore +42 -0
- package/corpus/templates/factory/actions/add-factory-comment.ts +55 -0
- package/corpus/templates/factory/actions/approve-factory-item.ts +214 -0
- package/corpus/templates/factory/actions/babysit-pull-request.ts +126 -0
- package/corpus/templates/factory/actions/evaluate-triage-item.ts +172 -0
- package/corpus/templates/factory/actions/get-factory-graph.ts +62 -0
- package/corpus/templates/factory/actions/get-triage-config.ts +42 -0
- package/corpus/templates/factory/actions/get-triage-item.ts +74 -0
- package/corpus/templates/factory/actions/hello.ts +13 -0
- package/corpus/templates/factory/actions/ingest-github-observation.ts +100 -0
- package/corpus/templates/factory/actions/list-factories.ts +40 -0
- package/corpus/templates/factory/actions/list-factory-comments.ts +40 -0
- package/corpus/templates/factory/actions/list-triage-items.ts +85 -0
- package/corpus/templates/factory/actions/list-triage-rules.ts +44 -0
- package/corpus/templates/factory/actions/navigate.ts +41 -0
- package/corpus/templates/factory/actions/poll-slack-channel.ts +118 -0
- package/corpus/templates/factory/actions/reconcile-triage-run.ts +179 -0
- package/corpus/templates/factory/actions/record-triage-feedback.ts +58 -0
- package/corpus/templates/factory/actions/run.ts +2 -0
- package/corpus/templates/factory/actions/save-factory-graph.ts +129 -0
- package/corpus/templates/factory/actions/save-triage-config.ts +67 -0
- package/corpus/templates/factory/actions/save-triage-rule.ts +89 -0
- package/corpus/templates/factory/actions/suggest-factory-rules.ts +70 -0
- package/corpus/templates/factory/actions/view-screen.ts +73 -0
- package/corpus/templates/factory/app/components/factory/FactoryCanvas.tsx +441 -0
- package/corpus/templates/factory/app/components/factory/FactoryInspector.tsx +388 -0
- package/corpus/templates/factory/app/components/layout/Header.tsx +60 -0
- package/corpus/templates/factory/app/components/layout/Layout.tsx +190 -0
- package/corpus/templates/factory/app/components/layout/Sidebar.tsx +538 -0
- package/corpus/templates/factory/app/components/triage/triage-status-pill.tsx +28 -0
- package/corpus/templates/factory/app/components/ui/button.tsx +1 -0
- package/corpus/templates/factory/app/components/ui/card.tsx +1 -0
- package/corpus/templates/factory/app/components/ui/dropdown-menu.tsx +1 -0
- package/corpus/templates/factory/app/components/ui/input.tsx +1 -0
- package/corpus/templates/factory/app/components/ui/label.tsx +1 -0
- package/corpus/templates/factory/app/components/ui/sheet.tsx +1 -0
- package/corpus/templates/factory/app/components/ui/textarea.tsx +1 -0
- package/corpus/templates/factory/app/components/ui/toolkit-provider.tsx +17 -0
- package/corpus/templates/factory/app/components/ui/tooltip.tsx +1 -0
- package/corpus/templates/factory/app/design-system.ts +3 -0
- package/corpus/templates/factory/app/entry.client.tsx +22 -0
- package/corpus/templates/factory/app/entry.server.tsx +10 -0
- package/corpus/templates/factory/app/global.css +93 -0
- package/corpus/templates/factory/app/hooks/use-navigation-state.ts +113 -0
- package/corpus/templates/factory/app/i18n/en-US.ts +211 -0
- package/corpus/templates/factory/app/i18n/index.ts +34 -0
- package/corpus/templates/factory/app/i18n-data.ts +556 -0
- package/corpus/templates/factory/app/lib/agent-page.tsx +49 -0
- package/corpus/templates/factory/app/lib/app-config.ts +11 -0
- package/corpus/templates/factory/app/lib/tab-id.ts +1 -0
- package/corpus/templates/factory/app/lib/utils.ts +1 -0
- package/corpus/templates/factory/app/root.tsx +175 -0
- package/corpus/templates/factory/app/routes/_index.tsx +94 -0
- package/corpus/templates/factory/app/routes/agent.tsx +24 -0
- package/corpus/templates/factory/app/routes/chat.$threadId.tsx +1 -0
- package/corpus/templates/factory/app/routes/database.tsx +17 -0
- package/corpus/templates/factory/app/routes/extensions.$id.$slug.tsx +2 -0
- package/corpus/templates/factory/app/routes/extensions.$id.tsx +11 -0
- package/corpus/templates/factory/app/routes/extensions._index.tsx +11 -0
- package/corpus/templates/factory/app/routes/extensions.tsx +5 -0
- package/corpus/templates/factory/app/routes/factory.tsx +1003 -0
- package/corpus/templates/factory/app/routes/observability.tsx +19 -0
- package/corpus/templates/factory/app/routes/settings.tsx +89 -0
- package/corpus/templates/factory/app/routes/team.tsx +11 -0
- package/corpus/templates/factory/app/routes.ts +4 -0
- package/corpus/templates/factory/app/vite-env.d.ts +6 -0
- package/corpus/templates/factory/changelog/2026-06-24-a-new-settings-page-gives-quick-access-to-language-workspace.md +6 -0
- package/corpus/templates/factory/changelog/2026-06-24-added-a-language-picker-and-localized-app-chrome-for-support.md +6 -0
- package/corpus/templates/factory/changelog/2026-06-27-traditional-chinese-copy-uses-taiwan-terminology.md +6 -0
- package/corpus/templates/factory/changelog/2026-06-28-left-sidebar-collapse-motion-and-footer-chrome-are-quieter.md +6 -0
- package/corpus/templates/factory/changelog/2026-06-29-chat-layouts-adapt-when-the-agent-sidebar-is-open.md +6 -0
- package/corpus/templates/factory/changelog/2026-07-08-settings-are-cleaner-and-searchable.md +5 -0
- package/corpus/templates/factory/changelog/2026-07-10-chat-now-makes-ai-connection-setup-clear-without-shifting-th.md +6 -0
- package/corpus/templates/factory/changelog/2026-07-13-a-full-agent-page-now-brings-context-files-connections-jobs-.md +6 -0
- package/corpus/templates/factory/changelog/2026-07-14-chat-opens-reliably-on-hosted-deployments-instead-of-failing.md +6 -0
- package/corpus/templates/factory/changelog/2026-07-14-fixed-chat-template-startup-with-older-core-versions.md +6 -0
- package/corpus/templates/factory/changelog/2026-07-15-chat-navigation-focuses-on-chat-and-agent.md +6 -0
- package/corpus/templates/factory/changelog/2026-07-17-the-agent-chat-sidebar-stays-closed-until-you-open-it-or-sta.md +6 -0
- package/corpus/templates/factory/changelog/2026-07-22-compact-sidebar-footer.md +6 -0
- package/corpus/templates/factory/changelog/2026-07-22-full-page-chat-keeps-the-active-conversation-when-moving-to-.md +6 -0
- package/corpus/templates/factory/changelog/2026-07-22-manage-agent-navigation-now-uses-the-connected-nodes-icon.md +6 -0
- package/corpus/templates/factory/changelog/2026-07-22-recent-chats-are-easier-to-scan-and-expand.md +6 -0
- package/corpus/templates/factory/changelog/2026-07-23-full-page-chat-is-better-centered-with-quieter-chat-history-.md +6 -0
- package/corpus/templates/factory/changelog/2026-07-24-borderless-secondary-surfaces.md +6 -0
- package/corpus/templates/factory/changelog/2026-07-24-sidebar-footer-controls-follow-a-consistent-order.md +6 -0
- package/corpus/templates/factory/changelog/2026-07-25-settings-navigation-now-keeps-manage-agent-as-a-dedicated-li.md +6 -0
- package/corpus/templates/factory/changelog/2026-07-29-sidebar-footers-now-keep-feedback-search-and-collapse-togeth.md +6 -0
- package/corpus/templates/factory/changelog/2026-07-31-added-an-inspectable-observe-only-factory-queue-for-slack-.md +6 -0
- package/corpus/templates/factory/changelog/2026-07-31-clicking-the-agent-native-logo-now-toggles-the-app-sidebar.md +6 -0
- package/corpus/templates/factory/components.json +20 -0
- package/corpus/templates/factory/data/sync-config.json +1 -0
- package/corpus/templates/factory/learnings.defaults.md +5 -0
- package/corpus/templates/factory/netlify.toml +10 -0
- package/corpus/templates/factory/package.json +105 -0
- package/corpus/templates/factory/public/agent-native-icon-dark.svg +10 -0
- package/corpus/templates/factory/public/agent-native-icon-light.svg +10 -0
- package/corpus/templates/factory/public/agent-native-logo-dark.svg +21 -0
- package/corpus/templates/factory/public/agent-native-logo-light.svg +21 -0
- package/corpus/templates/factory/public/favicon.svg +1 -0
- package/corpus/templates/factory/public/icon-180.svg +1 -0
- package/corpus/templates/factory/public/icon-192.svg +1 -0
- package/corpus/templates/factory/public/icon-512.svg +1 -0
- package/corpus/templates/factory/public/manifest.json +21 -0
- package/corpus/templates/factory/react-router.config.ts +7 -0
- package/corpus/templates/factory/server/connectors/credentials.ts +129 -0
- package/corpus/templates/factory/server/connectors/slack.ts +129 -0
- package/corpus/templates/factory/server/db/index.ts +6 -0
- package/corpus/templates/factory/server/db/schema.ts +193 -0
- package/corpus/templates/factory/server/factory-graph/contracts.ts +212 -0
- package/corpus/templates/factory/server/factory-graph/store.ts +121 -0
- package/corpus/templates/factory/server/lib/require-workspace-member.ts +55 -0
- package/corpus/templates/factory/server/middleware/auth.ts +15 -0
- package/corpus/templates/factory/server/plugins/agent-chat.ts +58 -0
- package/corpus/templates/factory/server/plugins/auth.ts +14 -0
- package/corpus/templates/factory/server/plugins/factory-migrations.ts +247 -0
- package/corpus/templates/factory/server/plugins/factory-scheduler-job.ts +116 -0
- package/corpus/templates/factory/server/plugins/integrations.ts +46 -0
- package/corpus/templates/factory/server/routes/[...page].get.ts +5 -0
- package/corpus/templates/factory/server/routes/_agent-native/factory/builder-callback.post.ts +116 -0
- package/corpus/templates/factory/server/triage/ai-services-git.ts +197 -0
- package/corpus/templates/factory/server/triage/builder-executor.ts +118 -0
- package/corpus/templates/factory/server/triage/contracts.ts +164 -0
- package/corpus/templates/factory/server/triage/github-ingestion.ts +35 -0
- package/corpus/templates/factory/server/triage/guards.ts +121 -0
- package/corpus/templates/factory/server/triage/ids.ts +27 -0
- package/corpus/templates/factory/server/triage/pr-babysit.ts +100 -0
- package/corpus/templates/factory/server/triage/pr-monitor.ts +220 -0
- package/corpus/templates/factory/server/triage/slack-client.ts +55 -0
- package/corpus/templates/factory/server/triage/slack-poller.ts +152 -0
- package/corpus/templates/factory/ssr-entry.ts +15 -0
- package/corpus/templates/factory/tsconfig.json +21 -0
- package/corpus/templates/factory/vite.config.ts +19 -0
- package/corpus/templates/forms/app/components/layout/Sidebar.tsx +55 -5
- package/corpus/templates/forms/changelog/2026-07-31-the-agent-native-logo-stays-visible-when-the-sidebar-is-coll.md +6 -0
- package/corpus/templates/macros/app/components/layout/AppLayout.tsx +6 -2
- package/corpus/templates/plan/app/components/layout/Sidebar.tsx +21 -6
- package/corpus/templates/plan/changelog/2026-07-31-clicking-the-agent-native-logo-now-toggles-the-app-sidebar.md +6 -0
- package/corpus/templates/slides/.agents/skills/create-deck/SKILL.md +12 -0
- package/corpus/templates/slides/.agents/skills/design-systems/SKILL.md +9 -0
- package/corpus/templates/slides/.agents/skills/slide-editing/SKILL.md +11 -0
- package/corpus/templates/slides/AGENTS.md +5 -6
- package/corpus/templates/slides/actions/_await-fit-check.ts +20 -10
- package/corpus/templates/slides/actions/add-slide.ts +17 -4
- package/corpus/templates/slides/actions/create-design-system.ts +16 -4
- package/corpus/templates/slides/actions/delete-design-system.ts +18 -2
- package/corpus/templates/slides/actions/get-layout-overflows.ts +88 -0
- package/corpus/templates/slides/actions/import-file.ts +1 -0
- package/corpus/templates/slides/actions/index-design-system-with-builder.ts +8 -0
- package/corpus/templates/slides/actions/patch-deck.ts +48 -16
- package/corpus/templates/slides/actions/set-default-design-system.ts +49 -19
- package/corpus/templates/slides/actions/update-slide.ts +13 -3
- package/corpus/templates/slides/actions/view-screen.ts +87 -10
- package/corpus/templates/slides/app/components/deck/SlideRenderer.tsx +155 -28
- package/corpus/templates/slides/app/components/design-system/DesignSystemCard.tsx +21 -17
- package/corpus/templates/slides/app/components/design-system/DesignSystemSetup.tsx +849 -341
- package/corpus/templates/slides/app/components/editor/EditorSidebar.tsx +102 -2
- package/corpus/templates/slides/app/components/editor/PromptDialog.tsx +13 -16
- package/corpus/templates/slides/app/components/editor/SlideEditor.tsx +60 -12
- package/corpus/templates/slides/app/components/editor/SlideOverflowWarning.tsx +11 -1
- package/corpus/templates/slides/app/components/layout/Sidebar.tsx +66 -19
- package/corpus/templates/slides/app/i18n/en-US.ts +23 -0
- package/corpus/templates/slides/app/lib/normalize-slide-padding.ts +8 -15
- package/corpus/templates/slides/app/pages/DeckEditor.tsx +4 -3
- package/corpus/templates/slides/app/pages/DesignSystems.tsx +4 -3
- package/corpus/templates/slides/app/pages/Index.tsx +1 -1
- package/corpus/templates/slides/changelog/2026-07-31-design-system-details-now-show-their-source-and-indexing-sta.md +6 -0
- package/corpus/templates/slides/changelog/2026-07-31-design-system-indexing-keeps-your-chosen-name-when-you-uploa.md +6 -0
- package/corpus/templates/slides/changelog/2026-07-31-design-system-setup-keeps-focus-rings-visible-and-uses-a-sim.md +6 -0
- package/corpus/templates/slides/changelog/2026-07-31-skip-prompt-is-now-available-in-the-new-deck-prompt-header.md +6 -0
- package/corpus/templates/slides/changelog/2026-07-31-slides-now-detect-real-text-and-box-overflow-across-the-deck.md +6 -0
- package/corpus/templates/slides/changelog/2026-07-31-the-agent-native-logo-stays-visible-when-the-sidebar-is-coll.md +6 -0
- package/corpus/templates/slides/server/handlers/design-systems.ts +1 -0
- package/corpus/templates/slides/server/handlers/index-design-system-sources.ts +1 -0
- package/corpus/templates/slides/server/lib/builder-design-system-proxy.ts +23 -4
- package/corpus/templates/slides/server/plugins/agent-chat.ts +5 -0
- package/corpus/templates/slides/server/plugins/creative-context.ts +16 -3
- package/corpus/templates/slides/server/workspace-defaults.ts +5 -1
- package/corpus/templates/slides/shared/slide-fit.ts +26 -0
- package/corpus/templates/tasks/app/components/layout/Sidebar.tsx +30 -3
- package/corpus/templates/tasks/changelog/2026-07-31-clicking-the-agent-native-logo-now-toggles-the-app-sidebar.md +6 -0
- package/dist/a2a/correlation.d.ts +4 -1
- package/dist/a2a/correlation.d.ts.map +1 -1
- package/dist/a2a/correlation.js +8 -1
- package/dist/a2a/correlation.js.map +1 -1
- package/dist/a2a/types.d.ts +11 -3
- package/dist/a2a/types.d.ts.map +1 -1
- package/dist/a2a/types.js.map +1 -1
- package/dist/agent/engine/ai-sdk-engine.d.ts.map +1 -1
- package/dist/agent/engine/ai-sdk-engine.js +27 -41
- package/dist/agent/engine/ai-sdk-engine.js.map +1 -1
- package/dist/agent/engine/builder-engine.d.ts.map +1 -1
- package/dist/agent/engine/builder-engine.js +18 -8
- package/dist/agent/engine/builder-engine.js.map +1 -1
- package/dist/agent/engine/error-detail.d.ts +61 -0
- package/dist/agent/engine/error-detail.d.ts.map +1 -1
- package/dist/agent/engine/error-detail.js +145 -3
- package/dist/agent/engine/error-detail.js.map +1 -1
- package/dist/agent/engine/failure-taxonomy.d.ts +24 -0
- package/dist/agent/engine/failure-taxonomy.d.ts.map +1 -0
- package/dist/agent/engine/failure-taxonomy.js +88 -0
- package/dist/agent/engine/failure-taxonomy.js.map +1 -0
- package/dist/agent/engine/index.d.ts +2 -1
- package/dist/agent/engine/index.d.ts.map +1 -1
- package/dist/agent/engine/index.js +2 -1
- package/dist/agent/engine/index.js.map +1 -1
- package/dist/agent/engine/registry.d.ts +16 -0
- package/dist/agent/engine/registry.d.ts.map +1 -1
- package/dist/agent/engine/registry.js +71 -6
- package/dist/agent/engine/registry.js.map +1 -1
- package/dist/agent/engine/translate-ai-sdk.d.ts.map +1 -1
- package/dist/agent/engine/translate-ai-sdk.js +14 -2
- package/dist/agent/engine/translate-ai-sdk.js.map +1 -1
- package/dist/agent/production-agent.d.ts.map +1 -1
- package/dist/agent/production-agent.js +13 -24
- package/dist/agent/production-agent.js.map +1 -1
- package/dist/agent/run-loop-with-resume.js +1 -1
- package/dist/agent/run-loop-with-resume.js.map +1 -1
- package/dist/agent/run-manager.d.ts.map +1 -1
- package/dist/agent/run-manager.js +39 -10
- package/dist/agent/run-manager.js.map +1 -1
- package/dist/agent/run-store.d.ts +10 -0
- package/dist/agent/run-store.d.ts.map +1 -1
- package/dist/agent/run-store.js +20 -3
- package/dist/agent/run-store.js.map +1 -1
- package/dist/agent/thread-data-builder.d.ts.map +1 -1
- package/dist/agent/thread-data-builder.js +28 -4
- package/dist/agent/thread-data-builder.js.map +1 -1
- package/dist/chat-threads/store.d.ts +13 -0
- package/dist/chat-threads/store.d.ts.map +1 -1
- package/dist/chat-threads/store.js +35 -0
- package/dist/chat-threads/store.js.map +1 -1
- package/dist/cli/templates-meta.d.ts.map +1 -1
- package/dist/cli/templates-meta.js +13 -0
- package/dist/cli/templates-meta.js.map +1 -1
- package/dist/cli/workspace-dev.d.ts.map +1 -1
- package/dist/cli/workspace-dev.js +1 -0
- package/dist/cli/workspace-dev.js.map +1 -1
- package/dist/client/error-format.d.ts.map +1 -1
- package/dist/client/error-format.js +10 -0
- package/dist/client/error-format.js.map +1 -1
- package/dist/client/use-chat-threads.d.ts.map +1 -1
- package/dist/client/use-chat-threads.js +66 -16
- package/dist/client/use-chat-threads.js.map +1 -1
- package/dist/collab/awareness.d.ts +2 -2
- package/dist/collab/awareness.d.ts.map +1 -1
- package/dist/collab/struct-routes.d.ts +1 -1
- package/dist/credentials/index.d.ts +9 -2
- package/dist/credentials/index.d.ts.map +1 -1
- package/dist/credentials/index.js +50 -8
- package/dist/credentials/index.js.map +1 -1
- package/dist/extensions/url-safety.d.ts.map +1 -1
- package/dist/extensions/url-safety.js +38 -12
- package/dist/extensions/url-safety.js.map +1 -1
- package/dist/integrations/adapters/slack.d.ts.map +1 -1
- package/dist/integrations/adapters/slack.js +25 -8
- package/dist/integrations/adapters/slack.js.map +1 -1
- package/dist/integrations/google-docs-poller.d.ts.map +1 -1
- package/dist/integrations/google-docs-poller.js +13 -1
- package/dist/integrations/google-docs-poller.js.map +1 -1
- package/dist/integrations/installations-store.d.ts +10 -0
- package/dist/integrations/installations-store.d.ts.map +1 -1
- package/dist/integrations/installations-store.js +24 -0
- package/dist/integrations/installations-store.js.map +1 -1
- package/dist/integrations/plugin.d.ts.map +1 -1
- package/dist/integrations/plugin.js +6 -5
- package/dist/integrations/plugin.js.map +1 -1
- package/dist/integrations/types.d.ts +7 -0
- package/dist/integrations/types.d.ts.map +1 -1
- package/dist/integrations/types.js.map +1 -1
- package/dist/integrations/webhook-handler.d.ts.map +1 -1
- package/dist/integrations/webhook-handler.js +16 -1
- package/dist/integrations/webhook-handler.js.map +1 -1
- package/dist/jobs/background-automation-runner.d.ts.map +1 -1
- package/dist/jobs/background-automation-runner.js +35 -2
- package/dist/jobs/background-automation-runner.js.map +1 -1
- package/dist/notifications/routes.d.ts +6 -6
- package/dist/observability/routes.d.ts +3 -3
- package/dist/provider-api/actions/custom-provider-registration.d.ts +14 -14
- package/dist/provider-api/actions/provider-api.d.ts +8 -8
- package/dist/provider-api/index.js +7 -3
- package/dist/provider-api/index.js.map +1 -1
- package/dist/scripts/call-agent.d.ts.map +1 -1
- package/dist/scripts/call-agent.js +6 -1
- package/dist/scripts/call-agent.js.map +1 -1
- package/dist/server/agent-chat-plugin.d.ts.map +1 -1
- package/dist/server/agent-chat-plugin.js +38 -9
- package/dist/server/agent-chat-plugin.js.map +1 -1
- package/dist/server/agent-discovery.d.ts +2 -0
- package/dist/server/agent-discovery.d.ts.map +1 -1
- package/dist/server/agent-discovery.js.map +1 -1
- package/dist/server/builder-design-systems.d.ts +4 -1
- package/dist/server/builder-design-systems.d.ts.map +1 -1
- package/dist/server/builder-design-systems.js +11 -1
- package/dist/server/builder-design-systems.js.map +1 -1
- package/dist/server/credential-provider.d.ts.map +1 -1
- package/dist/server/credential-provider.js +49 -12
- package/dist/server/credential-provider.js.map +1 -1
- package/dist/server/index.d.ts +1 -1
- package/dist/server/index.d.ts.map +1 -1
- package/dist/server/index.js.map +1 -1
- package/dist/server/onboarding-html.d.ts.map +1 -1
- package/dist/server/onboarding-html.js +37 -2
- package/dist/server/onboarding-html.js.map +1 -1
- package/dist/server/transcribe-voice.d.ts +1 -1
- package/dist/shared/reasoning-effort.d.ts +1 -0
- package/dist/shared/reasoning-effort.d.ts.map +1 -1
- package/dist/shared/reasoning-effort.js +1 -1
- package/dist/shared/reasoning-effort.js.map +1 -1
- package/dist/templates/chat/app/components/layout/Sidebar.tsx +30 -3
- package/dist/templates/chat/changelog/2026-07-31-clicking-the-agent-native-logo-now-toggles-the-app-sidebar.md +6 -0
- package/dist/templates/workspace-core/.agents/skills/a2a-protocol/SKILL.md +11 -0
- package/package.json +1 -1
- package/src/a2a/correlation.ts +11 -1
- package/src/a2a/types.ts +11 -3
- package/src/agent/engine/ai-sdk-engine.ts +33 -46
- package/src/agent/engine/builder-engine.ts +22 -10
- package/src/agent/engine/error-detail.ts +184 -3
- package/src/agent/engine/failure-taxonomy.ts +123 -0
- package/src/agent/engine/index.ts +8 -0
- package/src/agent/engine/registry.ts +92 -8
- package/src/agent/engine/translate-ai-sdk.ts +17 -2
- package/src/agent/production-agent.ts +13 -33
- package/src/agent/run-loop-with-resume.ts +1 -1
- package/src/agent/run-manager.ts +43 -14
- package/src/agent/run-store.ts +30 -3
- package/src/agent/thread-data-builder.ts +36 -4
- package/src/chat-threads/store.ts +42 -0
- package/src/cli/templates-meta.ts +13 -0
- package/src/cli/workspace-dev.ts +1 -0
- package/src/client/error-format.ts +12 -0
- package/src/client/use-chat-threads.ts +76 -16
- package/src/credentials/index.ts +51 -12
- package/src/extensions/url-safety.ts +46 -12
- package/src/integrations/adapters/slack.ts +32 -10
- package/src/integrations/google-docs-poller.ts +12 -1
- package/src/integrations/installations-store.ts +30 -0
- package/src/integrations/plugin.ts +5 -5
- package/src/integrations/types.ts +7 -0
- package/src/integrations/webhook-handler.ts +24 -1
- package/src/jobs/background-automation-runner.ts +38 -1
- package/src/provider-api/index.ts +8 -2
- package/src/scripts/call-agent.ts +6 -0
- package/src/server/agent-chat-plugin.ts +46 -10
- package/src/server/agent-discovery.ts +2 -0
- package/src/server/builder-design-systems.ts +21 -0
- package/src/server/credential-provider.ts +51 -12
- package/src/server/index.ts +1 -0
- package/src/server/onboarding-html.ts +37 -2
- package/src/shared/reasoning-effort.ts +1 -1
- package/src/templates/chat/app/components/layout/Sidebar.tsx +30 -3
- package/src/templates/chat/changelog/2026-07-31-clicking-the-agent-native-logo-now-toggles-the-app-sidebar.md +6 -0
- package/src/templates/workspace-core/.agents/skills/a2a-protocol/SKILL.md +11 -0
- package/corpus/templates/clips/desktop/src/lib/media-device-selection.ts +0 -157
|
@@ -0,0 +1,232 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: sharing
|
|
3
|
+
description: >-
|
|
4
|
+
Framework-level sharing and privacy for user-authored resources
|
|
5
|
+
(dashboards, documents, forms, decks, etc.). Use when making a resource
|
|
6
|
+
table ownable, wiring list/read/update access checks, or dropping the
|
|
7
|
+
standard share dialog into a template.
|
|
8
|
+
scope: dev
|
|
9
|
+
metadata:
|
|
10
|
+
internal: true
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
# Sharing — Private by Default, Explicit Share
|
|
14
|
+
|
|
15
|
+
## Rule
|
|
16
|
+
|
|
17
|
+
Any resource a user **creates** (dashboards, documents, forms, decks, compositions, booking links, issues, analyses) is **private to the creator** by default and visible to others only when they have been **explicitly shared** with or when the creator changes visibility to `org` or `public`.
|
|
18
|
+
|
|
19
|
+
This is the framework-level primitive. Every ownable resource gets it for free — same API, same UI, same skill.
|
|
20
|
+
|
|
21
|
+
## Concepts
|
|
22
|
+
|
|
23
|
+
### Three visibility levels
|
|
24
|
+
|
|
25
|
+
- **`private`** — owner + explicit share grants only. Default.
|
|
26
|
+
- **`org`** — owner + explicit grants + anyone in the same org (read-only).
|
|
27
|
+
- **`public`** — owner + explicit grants + **anyone with the link** (read-only). Public docs do NOT appear in other users' list/sidebar/search results — `accessFilter` omits them by default. They're reachable by id (`resolveAccess` admits them) so direct links and SSR routes like `/p/:id` keep working. If a list endpoint legitimately needs cross-user public discovery (a template gallery, etc.), pass `accessFilter(table, shares, ctx, minRole, { includePublic: true })`.
|
|
28
|
+
|
|
29
|
+
Visibility is coarse. Explicit share grants are fine-grained (per user or per org).
|
|
30
|
+
|
|
31
|
+
### Roles on a share grant
|
|
32
|
+
|
|
33
|
+
- **`viewer`** — read only.
|
|
34
|
+
- **`editor`** — read + write.
|
|
35
|
+
- **`admin`** — read + write + manage shares. Does NOT replace the single `owner_email` on the resource.
|
|
36
|
+
|
|
37
|
+
There are three role systems and they never imply one another. A share role answers "what may this person do to **one row**". An org role (`org_members.role`) answers "what may this person do to the **team**". An app role (`defineAppRoles`, see the `authentication` skill) answers "what may this person do inside **one app**". A share `admin` is not an app admin and neither is an org admin.
|
|
38
|
+
|
|
39
|
+
### Anonymous public URLs stay separate
|
|
40
|
+
|
|
41
|
+
Form "publish" slugs, booking-link slugs, any feature that exposes a URL to unauthenticated users — these are a different axis and are NOT controlled by the sharing system. Keep them alongside it.
|
|
42
|
+
|
|
43
|
+
## Make a resource ownable
|
|
44
|
+
|
|
45
|
+
In your template's `server/db/schema.ts`:
|
|
46
|
+
|
|
47
|
+
```ts
|
|
48
|
+
import {
|
|
49
|
+
table,
|
|
50
|
+
text,
|
|
51
|
+
integer,
|
|
52
|
+
now,
|
|
53
|
+
ownableColumns,
|
|
54
|
+
createSharesTable,
|
|
55
|
+
} from "@agent-native/core/db/schema";
|
|
56
|
+
|
|
57
|
+
export const decks = table("decks", {
|
|
58
|
+
id: text("id").primaryKey(),
|
|
59
|
+
title: text("title").notNull(),
|
|
60
|
+
data: text("data").notNull(),
|
|
61
|
+
createdAt: text("created_at").notNull().default(now()),
|
|
62
|
+
updatedAt: text("updated_at").notNull().default(now()),
|
|
63
|
+
...ownableColumns(), // adds owner_email, org_id, visibility
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
export const deckShares = createSharesTable("deck_shares");
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
Then register it **in `server/db/index.ts`** (not the schema file — keeps the schema file free of the `getDb` closure and avoids circular imports):
|
|
70
|
+
|
|
71
|
+
```ts
|
|
72
|
+
// server/db/index.ts
|
|
73
|
+
import * as schema from "./schema.js";
|
|
74
|
+
import { createGetDb } from "@agent-native/core/db";
|
|
75
|
+
import { registerShareableResource } from "@agent-native/core/sharing";
|
|
76
|
+
|
|
77
|
+
export const getDb = createGetDb(schema);
|
|
78
|
+
export { schema };
|
|
79
|
+
|
|
80
|
+
registerShareableResource({
|
|
81
|
+
type: "deck",
|
|
82
|
+
resourceTable: schema.decks,
|
|
83
|
+
sharesTable: schema.deckShares,
|
|
84
|
+
displayName: "Deck",
|
|
85
|
+
titleColumn: "title",
|
|
86
|
+
getResourcePath: (deck) => `/deck/${deck.id}`,
|
|
87
|
+
getDb,
|
|
88
|
+
});
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
The `type` string is the stable id the UI and actions use. `getDb` is required — the framework-level share actions use it to reach your template's DB.
|
|
92
|
+
|
|
93
|
+
### Restricting public visibility and cross-org user shares
|
|
94
|
+
|
|
95
|
+
Some resources should NOT be reachable by an arbitrary authenticated user even with the link, and should NOT be shareable to an email outside the org. Two optional registration flags lock these axes down:
|
|
96
|
+
|
|
97
|
+
```ts
|
|
98
|
+
registerShareableResource({
|
|
99
|
+
type: "extension",
|
|
100
|
+
// ...
|
|
101
|
+
allowPublic: false, // hides "Public" in the share dialog and rejects it server-side
|
|
102
|
+
requireOrgMemberForUserShares: true, // user shares must target an org member or pending invitee
|
|
103
|
+
});
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
- **`allowPublic: false`** — `set-resource-visibility('public')` throws `ForbiddenError`, `accessFilter` / `resolveAccess` treat any stored `'public'` row as private (defense in depth against bad data), and the share popover hides the "Public" option. `list-resource-shares` returns `policy.allowPublic: false` so the UI follows the server.
|
|
107
|
+
- **`requireOrgMemberForUserShares: true`** — `share-resource` looks up `principalId` in `org_members` and `org_invitations` (pending) for the resource's `orgId` and rejects user shares to anyone else. The same flag also pins `principalType: "org"` shares to the resource's own org — sharing to a *different* org would let that org's members run code in the viewer's auth context (same threat model as a public extension). (The flag name is kept for backward compatibility; treat it as "lock both user and org shares to the resource's org".)
|
|
108
|
+
|
|
109
|
+
Use both for resources that execute code or expose privileged data with the *viewer's* credentials. Extensions ship with both set: an extension's HTML calls actions / SQL / the secrets-injecting proxy as the viewer, so a public or cross-org-shared extension would let a stranger run arbitrary code with someone else's auth context. `scripts/guard-extension-no-public.mjs` (CI + `pnpm prep`) statically enforces that the extension registration keeps both flags set.
|
|
110
|
+
|
|
111
|
+
Defaults match historical behaviour: `allowPublic: true`, `requireOrgMemberForUserShares: false`. Resources that don't set the flags work as before.
|
|
112
|
+
|
|
113
|
+
## Filter list/read queries
|
|
114
|
+
|
|
115
|
+
```ts
|
|
116
|
+
import { accessFilter } from "@agent-native/core/sharing";
|
|
117
|
+
|
|
118
|
+
const rows = await db
|
|
119
|
+
.select()
|
|
120
|
+
.from(schema.decks)
|
|
121
|
+
.where(accessFilter(schema.decks, schema.deckShares));
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
`accessFilter` admits rows the current user owns, has been shared on, or that the user can reach via `org` visibility. `public` rows are NOT admitted by default — see the visibility section above for why and how to opt in.
|
|
125
|
+
|
|
126
|
+
## Guard write actions
|
|
127
|
+
|
|
128
|
+
```ts
|
|
129
|
+
import { assertAccess } from "@agent-native/core/sharing";
|
|
130
|
+
|
|
131
|
+
export default defineAction({
|
|
132
|
+
schema: z.object({ id: z.string(), title: z.string() }),
|
|
133
|
+
run: async (args) => {
|
|
134
|
+
await assertAccess("deck", args.id, "editor");
|
|
135
|
+
// ...proceed
|
|
136
|
+
},
|
|
137
|
+
});
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
For delete actions use `"admin"` (or fold in `"owner"` to require the real owner).
|
|
141
|
+
|
|
142
|
+
`authorize` is a different axis, not an alternative: it gates whether the caller may run the operation at all, while `assertAccess` scopes which row they may touch. A write action restricted to some teammates needs both — `authorize: appAccess.requireAny(...)` on the action, `assertAccess` inside `run`.
|
|
143
|
+
|
|
144
|
+
## Create actions must set owner
|
|
145
|
+
|
|
146
|
+
When inserting a new row, fill `ownerEmail` and `orgId` from the request context:
|
|
147
|
+
|
|
148
|
+
```ts
|
|
149
|
+
import {
|
|
150
|
+
getRequestUserEmail,
|
|
151
|
+
getRequestOrgId,
|
|
152
|
+
} from "@agent-native/core/server/request-context";
|
|
153
|
+
|
|
154
|
+
const ownerEmail = getRequestUserEmail();
|
|
155
|
+
// Never fall back to a sentinel like "local@localhost" — that pools every
|
|
156
|
+
// unauthenticated write into one shared tenant (see the 2026-04-29 leak and
|
|
157
|
+
// guard-no-localhost-fallback). Throw / 401 when there is no session instead.
|
|
158
|
+
if (!ownerEmail) throw new Error("Not authenticated");
|
|
159
|
+
|
|
160
|
+
await db.insert(schema.decks).values({
|
|
161
|
+
id: nanoid(),
|
|
162
|
+
title,
|
|
163
|
+
data,
|
|
164
|
+
ownerEmail,
|
|
165
|
+
orgId: getRequestOrgId(),
|
|
166
|
+
// visibility defaults to 'private'
|
|
167
|
+
// ...
|
|
168
|
+
});
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
## Drop in the share UI
|
|
172
|
+
|
|
173
|
+
```tsx
|
|
174
|
+
import { ShareButton } from "@agent-native/core/client/sharing";
|
|
175
|
+
|
|
176
|
+
// In the resource's header/toolbar:
|
|
177
|
+
<ShareButton
|
|
178
|
+
resourceType="deck"
|
|
179
|
+
resourceId={deck.id}
|
|
180
|
+
resourceTitle={deck.title}
|
|
181
|
+
/>;
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
For list views, show `<VisibilityBadge visibility={row.visibility} />` next to each resource.
|
|
185
|
+
|
|
186
|
+
## Actions available everywhere
|
|
187
|
+
|
|
188
|
+
The framework auto-mounts these actions in every template — no per-template boilerplate:
|
|
189
|
+
|
|
190
|
+
| Action | Args | Purpose |
|
|
191
|
+
| -------------------------- | ------------------------------------------------------------------------------ | ----------------------------------------- |
|
|
192
|
+
| `share-resource` | `resourceType, resourceId, principalType, principalId, role, notify?, resourceUrl?` | Grant a user or org access. `notify` defaults to true for individual user shares; `resourceUrl` can provide the direct app link used in the notification email. |
|
|
193
|
+
| `unshare-resource` | `resourceType, resourceId, principalType, principalId` | Revoke access. |
|
|
194
|
+
| `list-resource-shares` | `resourceType, resourceId` | Current visibility + all share grants. |
|
|
195
|
+
| `set-resource-visibility` | `resourceType, resourceId, visibility` | Change to `private` / `org` / `public`. |
|
|
196
|
+
|
|
197
|
+
Both the agent and the UI use these same actions. The agent calls them as tools;
|
|
198
|
+
UI code should use `ShareButton` / `ShareDialog` or the action client hooks
|
|
199
|
+
instead of hand-writing route calls.
|
|
200
|
+
|
|
201
|
+
## Migration pattern for existing tables
|
|
202
|
+
|
|
203
|
+
When retrofitting an existing resource table:
|
|
204
|
+
|
|
205
|
+
1. Add `owner_email`, `org_id`, `visibility` columns (defaults `'local@localhost'`, `NULL`, `'private'`).
|
|
206
|
+
2. Backfill `owner_email` from any prior creator trail; otherwise leave the default.
|
|
207
|
+
3. Add the companion `{type}_shares` table.
|
|
208
|
+
4. Register via `registerShareableResource`.
|
|
209
|
+
5. Update list/read actions to use `accessFilter`.
|
|
210
|
+
6. Update update/delete actions to `assertAccess` with the correct role.
|
|
211
|
+
7. Add `<ShareButton>` to the resource header.
|
|
212
|
+
8. Add `getResourcePath` in the registration so agent-triggered shares can email a direct link even when no UI supplied `resourceUrl`.
|
|
213
|
+
|
|
214
|
+
## Templates that opt out
|
|
215
|
+
|
|
216
|
+
Sharing doesn't apply to:
|
|
217
|
+
|
|
218
|
+
- **Personal-data apps** (mail, macros) — user-scoped by design.
|
|
219
|
+
- **External source-of-truth apps** (issues → Jira, recruiting → Greenhouse) — ACL lives in the upstream system.
|
|
220
|
+
- **Demo/boilerplate** (starter) — no resources.
|
|
221
|
+
|
|
222
|
+
For these, add a short note to the template's `AGENTS.md` explaining why.
|
|
223
|
+
|
|
224
|
+
## Analytics (follow-up)
|
|
225
|
+
|
|
226
|
+
Dashboards and analyses in the `analytics` template currently live in the settings KV store (`u:<email>:dashboard-*` keys), not SQL. Sharing requires either migrating them to SQL tables (then applying this skill) or extending the settings store with a parallel share overlay. This is a tracked follow-up — see the analytics template's `AGENTS.md`.
|
|
227
|
+
|
|
228
|
+
## Debugging
|
|
229
|
+
|
|
230
|
+
- `ForbiddenError` from an action means the current user isn't owner / hasn't been shared / can't meet the role bar.
|
|
231
|
+
- If the agent can't see a resource it just created, check that the insert actually set `owner_email` from the request context.
|
|
232
|
+
- If a share doesn't take effect in the UI, confirm the template's `list-*` action uses `accessFilter` — the share rows are there but nothing is reading them yet.
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: storing-data
|
|
3
|
+
description: >-
|
|
4
|
+
How to store application data in agent-native apps. All data lives in SQL.
|
|
5
|
+
Use when adding data models, deciding where to store data, or reading/writing
|
|
6
|
+
application data.
|
|
7
|
+
scope: dev
|
|
8
|
+
metadata:
|
|
9
|
+
internal: true
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
# Storing Data — SQL is the Source of Truth
|
|
13
|
+
|
|
14
|
+
## Rule
|
|
15
|
+
|
|
16
|
+
All application data lives in **SQL** (SQLite locally, persistent database in production). The agent and UI share the same database. SQL stores structured records, metadata, references, and searchable text — not large raw file payloads. Do not store durable app data in the filesystem unless the app is explicitly running a Local File Mode artifact flow described below.
|
|
17
|
+
|
|
18
|
+
Large binary or file-like payloads (images, video/audio, PDFs, ZIPs, screenshots, session replay chunks, thumbnails, generated assets, `data:` URLs, and base64 file bodies) must go through configured file/blob storage such as `uploadFile()` or `putPrivateBlob()`. Persist only the returned URL, asset id, or opaque blob handle in SQL. If storage is unavailable in hosted or persistent-database mode, fail closed with setup guidance instead of falling back to base64 in `application_state`, `settings`, `resources`, or app tables. Local SQLite-only dev fallbacks may exist for tiny assets, but they must be capped, documented as dev-only, and kept off hot list/read paths.
|
|
19
|
+
|
|
20
|
+
**Local File Mode exception:** some artifact apps (Content, Plans, Slides, Dashboards, Designs, etc.) can intentionally use repo files as the source of truth for the artifact itself. This must be explicit via `agent-native.json`, `AGENT_NATIVE_MODE=local-files`, or an app-owned local-file action helper. In that mode, the UI and agent still go through app actions, but those actions read/write scoped files through `@agent-native/core/local-artifacts` instead of SQL rows. App state, auth, settings, credentials, collaboration metadata, and hosted database mode remain SQL. File-to-database or file-to-provider synchronization is an explicit sync step, not an implicit side effect of editing.
|
|
21
|
+
|
|
22
|
+
When you add a data model, a list, or a read path, also follow the `performance` skill: project only the columns a list renders, index the columns hot queries filter/sort on, and avoid query waterfalls — so apps stay fast as data grows.
|
|
23
|
+
|
|
24
|
+
## How It Works
|
|
25
|
+
|
|
26
|
+
Agent-native apps use Drizzle ORM over the configured SQL backend. Local development works out of the box with a SQLite file at `data/app.db`; production and shared preview deploys need a persistent `DATABASE_URL` because container/serverless filesystems can reset. The code should behave the same across backends, but the local SQLite file is not durable once deployed.
|
|
27
|
+
|
|
28
|
+
For app code, use Drizzle's schema/query DSL by default. Raw SQL is an escape hatch for additive migrations, health checks, or one-off maintenance, not the normal way to build features.
|
|
29
|
+
|
|
30
|
+
### Naming migrations
|
|
31
|
+
|
|
32
|
+
When you add an entry to a `runMigrations([...])` list (`@agent-native/core/db`), always give it a unique `name:` slug (e.g. `name: "analytics-alert-rules-table"`) alongside its `version`. Never renumber or reuse version numbers on existing entries.
|
|
33
|
+
|
|
34
|
+
Why: version numbers alone are not a safe identity. Two branches that each independently extend the same migration list can ship different DDL under the same version numbers — whichever branch deploys first "claims" those version numbers in the bookkeeping table, and the other branch's DDL is silently treated as already applied even though it never ran. This exact collision took down analytics: parallel branches both extended their migration list through v75-v83 with different DDL, so `analytics_alert_rules`, `analytics_alert_incidents`, and `session_recordings.network_error_count` never made it to production despite the bookkeeping table showing every version as applied. A `name:` slug is tracked independently of version numbers, so it applies exactly once per database regardless of what any other branch already recorded.
|
|
35
|
+
|
|
36
|
+
Existing unnamed migrations don't need to be renamed retroactively (the two gating strategies coexist), but any new entry should always carry a name.
|
|
37
|
+
|
|
38
|
+
### Core SQL Stores (auto-created, available in all templates)
|
|
39
|
+
|
|
40
|
+
| Store | Purpose | Access |
|
|
41
|
+
| ------------------- | ---------------------------------------------------- | ------------------------------------------ |
|
|
42
|
+
| `application_state` | Ephemeral UI state (compose windows, navigation) | `readAppState()` / `writeAppState()` |
|
|
43
|
+
| `settings` | Persistent KV config (preferences, app settings) | `getSetting()` / `putSetting()` |
|
|
44
|
+
| `oauth_tokens` | OAuth credentials | `@agent-native/core/oauth-tokens` |
|
|
45
|
+
| `sessions` | Auth sessions | `@agent-native/core/server` |
|
|
46
|
+
|
|
47
|
+
### Domain Data (per-template)
|
|
48
|
+
|
|
49
|
+
Define schema with the framework Drizzle helpers in `server/db/schema.ts`. Get a database instance with `const db = getDb()` from `server/db/index.ts`. All queries are async.
|
|
50
|
+
|
|
51
|
+
```ts
|
|
52
|
+
import { eq } from "drizzle-orm";
|
|
53
|
+
import { table, text, integer, now } from "@agent-native/core/db/schema";
|
|
54
|
+
|
|
55
|
+
export const tasks = table("tasks", {
|
|
56
|
+
id: text("id").primaryKey(),
|
|
57
|
+
title: text("title").notNull(),
|
|
58
|
+
completed: integer("completed", { mode: "boolean" })
|
|
59
|
+
.notNull()
|
|
60
|
+
.default(false),
|
|
61
|
+
createdAt: text("created_at").notNull().default(now()),
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
const rows = await db.select().from(tasks).where(eq(tasks.id, taskId));
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
Never import `sqliteTable` / `pgTable` or column helpers from `drizzle-orm/sqlite-core` or `drizzle-orm/pg-core` in app templates. Use `@agent-native/core/db/schema` so the same schema can run against SQLite, Postgres, libSQL/Turso, D1, and other supported backends.
|
|
68
|
+
|
|
69
|
+
| Template | Tables |
|
|
70
|
+
| ------------ | --------------------------------------------- |
|
|
71
|
+
| **Mail** | emails, labels (+ Gmail API when connected) |
|
|
72
|
+
| **Calendar** | events, bookings |
|
|
73
|
+
| **Forms** | forms, responses |
|
|
74
|
+
| **Content** | documents |
|
|
75
|
+
| **Slides** | decks (JSON stored in SQL) |
|
|
76
|
+
| **Videos** | compositions in registry + localStorage |
|
|
77
|
+
|
|
78
|
+
### Agent Access
|
|
79
|
+
|
|
80
|
+
The agent uses app-specific actions to read/write the database. Core DB scripts are for inspection and maintenance, not for implementing normal product behavior:
|
|
81
|
+
|
|
82
|
+
- `pnpm action db-schema` — Show all tables, columns, types
|
|
83
|
+
- `pnpm action db-query --sql "SELECT * FROM forms"` — Run SELECT queries
|
|
84
|
+
- `pnpm action db-exec --sql "UPDATE ..."` — Last-resort ad-hoc maintenance for short columns, multi-column writes, or computed updates when no domain action exists. For several related writes, prefer `--statements '[{"sql":"...","args":[...]}]'` so they run sequentially in one transaction. Schema changes are blocked; use reviewed additive migrations/startup code instead.
|
|
85
|
+
- `pnpm action db-patch --table <t> --column <c> --where "<clause>" --find "<old>" --replace "<new>"` — **Surgical search/replace on a large text column.** Sends the diff instead of re-transmitting the whole value, so it's dramatically more token-efficient than `db-exec UPDATE` when editing multi-kilobyte documents, slide HTML, dashboard/form JSON, etc. Targets exactly one row per call — narrow `--where` by primary key. Supports `--edits '[{find,replace},...]'` for batch edits and `--all` to replace every occurrence.
|
|
86
|
+
- App-specific actions for domain operations — **always prefer these over raw SQL when one exists.** They encode business rules, power the client action hooks, and for editor-backed tables (documents, slides) also push live Yjs updates to open collaborative editors. `db-patch` is the generic fallback for tables without a dedicated edit action.
|
|
87
|
+
|
|
88
|
+
**For one-off maintenance, how to choose between `db-exec UPDATE` and `db-patch`:**
|
|
89
|
+
|
|
90
|
+
| Scenario | Use |
|
|
91
|
+
| -------------------------------------------------------------- | ------------ |
|
|
92
|
+
| `SET status = 'published'` on one row | `db-exec` |
|
|
93
|
+
| `SET calories = calories + 50` | `db-exec` |
|
|
94
|
+
| Updating several columns at once | `db-exec` |
|
|
95
|
+
| Inserting/updating several rows as one logical operation | `db-exec --statements` |
|
|
96
|
+
| Fixing a typo in a 50KB markdown document's `content` column | `db-patch` |
|
|
97
|
+
| Changing a single key in a dashboard's JSON blob | `db-patch` |
|
|
98
|
+
| Tweaking one paragraph of slide HTML stored in `decks.data` | `db-patch` |
|
|
99
|
+
| Any edit where you'd otherwise re-send thousands of characters | `db-patch` |
|
|
100
|
+
|
|
101
|
+
All of these honor the per-user / per-org data scoping — you can't read or write rows outside the current user's data, regardless of which tool you choose.
|
|
102
|
+
|
|
103
|
+
### Frontend Access
|
|
104
|
+
|
|
105
|
+
The frontend calls actions using React Query hooks from the client API. The framework owns the HTTP transport behind these hooks, so components should not call action routes with raw `fetch`.
|
|
106
|
+
|
|
107
|
+
```ts
|
|
108
|
+
import { useActionQuery, useActionMutation } from "@agent-native/core/client/hooks";
|
|
109
|
+
|
|
110
|
+
// Read data
|
|
111
|
+
const { data } = useActionQuery("list-meals", { date: "2025-01-01" });
|
|
112
|
+
|
|
113
|
+
// Write data
|
|
114
|
+
const { mutate } = useActionMutation("log-meal");
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
Actions are the **preferred way** for the frontend to access data. You rarely need custom `/api/` routes — only for file uploads, streaming, webhooks, or OAuth callbacks.
|
|
118
|
+
|
|
119
|
+
### Production / Cloud Deployment
|
|
120
|
+
|
|
121
|
+
Local SQLite works out of the box for development. To deploy to production or any environment where data must survive restarts:
|
|
122
|
+
|
|
123
|
+
1. Set `DATABASE_URL` to a persistent SQL database.
|
|
124
|
+
2. Set `DATABASE_AUTH_TOKEN` only when the provider requires a separate token, such as Turso/libSQL.
|
|
125
|
+
3. No code changes should be needed when the schema and queries stay portable.
|
|
126
|
+
|
|
127
|
+
Turso is one valid option, not the required option. Common choices include Neon or Supabase Postgres, Turso/libSQL, plain Postgres, durable SQLite, Cloudflare D1 bindings, and managed platform SQL environments when available.
|
|
128
|
+
|
|
129
|
+
### Real-time Sync
|
|
130
|
+
|
|
131
|
+
Polling streams database changes to the UI. When the agent writes to the database via scripts, the UI updates automatically via `useDbSync()` which invalidates React Query caches.
|
|
132
|
+
|
|
133
|
+
## Do
|
|
134
|
+
|
|
135
|
+
- Use Drizzle ORM for structured domain data (forms, bookings, documents)
|
|
136
|
+
- Use Drizzle query builder methods (`select`, `insert`, `update`, `delete`) and portable operators from `drizzle-orm` (`eq`, `and`, `or`, `inArray`, `desc`, etc.) for app reads/writes
|
|
137
|
+
- Use framework schema helpers from `@agent-native/core/db/schema`, not dialect-specific Drizzle imports
|
|
138
|
+
- Use the `settings` store for app configuration and user preferences
|
|
139
|
+
- Use `application-state` for ephemeral UI state that the agent and UI share
|
|
140
|
+
- Use `oauth-tokens` for OAuth credentials
|
|
141
|
+
- Use `uploadFile()` or `putPrivateBlob()` for large files/blob data and store only URLs, ids, or handles in SQL
|
|
142
|
+
- Use core DB scripts (`db-schema`, `db-query`, `db-exec`, `db-patch`) for ad-hoc database operations
|
|
143
|
+
- Use `db-exec --statements` instead of several separate `db-exec` calls for related writes; it is faster and rolls back the whole batch if one statement fails
|
|
144
|
+
- Reach for `db-patch` instead of `db-exec UPDATE` whenever you're making a small change to a large text/JSON column — it's much cheaper on tokens
|
|
145
|
+
|
|
146
|
+
## Don't
|
|
147
|
+
|
|
148
|
+
- Don't store structured app data as JSON files
|
|
149
|
+
- Don't store app state in localStorage, sessionStorage, or cookies (except for UI-only preferences like sidebar width)
|
|
150
|
+
- Don't keep state only in memory (server variables, global stores)
|
|
151
|
+
- Don't use Redis or any external state store for app data
|
|
152
|
+
- Don't store large files, base64 blobs, `data:` URLs, screenshots, videos, audio, PDFs, ZIPs, or session replay chunks directly in SQL rows, `application_state`, `settings`, or `resources`
|
|
153
|
+
- Don't implement product features with raw SQL or `getDbExec()` when Drizzle can express the query
|
|
154
|
+
- Don't write SQLite-only or Postgres-only SQL in app code
|
|
155
|
+
- Don't interpolate user input directly into SQL queries — use Drizzle ORM's query builder
|
|
156
|
+
|
|
157
|
+
## Security
|
|
158
|
+
|
|
159
|
+
- **SQL injection** — Use Drizzle ORM's query builder, never raw string interpolation for SQL queries
|
|
160
|
+
- **Validate before writing** — Check data shape before writing, especially for user-submitted data
|
|
161
|
+
|
|
162
|
+
## Application State and Context Awareness
|
|
163
|
+
|
|
164
|
+
When storing app-state, include **navigation state** — the agent needs to know what the user is looking at. The `application_state` table holds ephemeral UI state that both the agent and UI share. Key patterns:
|
|
165
|
+
|
|
166
|
+
- **`navigation` key** — the UI writes current view and selection on every route change. The agent reads this before acting.
|
|
167
|
+
- **`navigate` key** — the agent writes one-shot commands to navigate the UI. The UI processes and deletes them.
|
|
168
|
+
- **Domain-specific keys** (e.g., `compose-{id}`) — bidirectional state for features like email drafts.
|
|
169
|
+
|
|
170
|
+
When adding a new data model or feature, also consider what navigation and selection state needs to be exposed via application-state. See the **context-awareness** skill for the full pattern.
|
|
171
|
+
|
|
172
|
+
## Related Skills
|
|
173
|
+
|
|
174
|
+
- **context-awareness** — How to expose navigation and selection state via application-state
|
|
175
|
+
- **real-time-sync** — Set up polling so the UI updates when the database changes
|
|
176
|
+
- **actions** — Create actions with `defineAction` to query the database
|
|
177
|
+
- **client-methods** — Keep route details behind named client helpers/hooks
|
|
178
|
+
- **self-modifying-code** — The agent can also modify the app's source code
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: upgrade-agent-native
|
|
3
|
+
description: >-
|
|
4
|
+
Bring an older Agent Native app or workspace current. Use when updating
|
|
5
|
+
@agent-native/core, fixing a broken upgrade, or when tempted to patch or
|
|
6
|
+
override core/dispatch packages to make an old branch run.
|
|
7
|
+
scope: dev
|
|
8
|
+
metadata:
|
|
9
|
+
internal: true
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
# Upgrade Agent Native
|
|
13
|
+
|
|
14
|
+
## Rule
|
|
15
|
+
|
|
16
|
+
When an older Agent Native app/branch needs to run on current packages, use
|
|
17
|
+
`agent-native upgrade`. Never "fix" upgrade breakage with
|
|
18
|
+
`pnpm.overrides`, `patchedDependencies`, `resolutions`, local patches, or
|
|
19
|
+
edits under `node_modules/@agent-native/*` — especially not against
|
|
20
|
+
`@agent-native/core` or `@agent-native/dispatch`.
|
|
21
|
+
|
|
22
|
+
## Why
|
|
23
|
+
|
|
24
|
+
Agents often respond to a failed core bump by inventing framework patches and
|
|
25
|
+
dispatch behavior overrides. That hides the real app-level break, drifts from
|
|
26
|
+
upstream, and makes the next upgrade worse. The supported path is bump →
|
|
27
|
+
install → refresh scaffold skills → verify, then fix **app** code only.
|
|
28
|
+
|
|
29
|
+
## How
|
|
30
|
+
|
|
31
|
+
1. **Preview migration codemods first**
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
npx @agent-native/core@latest upgrade --codemods
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
Codemods are preview-by-default: read the diff before applying it. Do not
|
|
38
|
+
manually edit imports before running this command; the migration manifest is
|
|
39
|
+
the source of truth for renamed specifiers and symbols.
|
|
40
|
+
|
|
41
|
+
2. **Apply the reviewed codemods, then run the upgrade**
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
npx @agent-native/core@latest upgrade --codemods --yes
|
|
45
|
+
npx @agent-native/core@latest upgrade
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
Or from an already-installed CLI: `pnpm exec agent-native upgrade` /
|
|
49
|
+
`agent-native upgrade`.
|
|
50
|
+
|
|
51
|
+
What it does:
|
|
52
|
+
|
|
53
|
+
- Blocks (unless `--force`) when `@agent-native/*` overrides/patches exist
|
|
54
|
+
- Rewrites non-local `@agent-native/*` dependency pins to `latest`
|
|
55
|
+
- Runs the package manager install
|
|
56
|
+
- Runs `skills update scaffold --project`
|
|
57
|
+
- Runs `typecheck` when the project has that script
|
|
58
|
+
|
|
59
|
+
3. **Pull upstream template changes (optional, separate from the bump)**
|
|
60
|
+
|
|
61
|
+
`agent-native upgrade` moves package versions. It never touches files that
|
|
62
|
+
were copied out of a template at scaffold time, so template fixes and
|
|
63
|
+
improvements do not arrive with a bump.
|
|
64
|
+
|
|
65
|
+
```bash
|
|
66
|
+
agent-native template status # recorded ref vs latest, drift counts
|
|
67
|
+
agent-native template diff # what upstream changed, read-only
|
|
68
|
+
agent-native template sync # 3-way merge it into the app
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
`sync` defaults to the ref matching the installed `@agent-native/core`, so
|
|
72
|
+
run it after `upgrade`. It merges per file against a pristine baseline
|
|
73
|
+
stored in `refs/agent-native/template-baseline/<app-path>`; files upstream
|
|
74
|
+
did not touch are left alone, and real collisions get conflict markers.
|
|
75
|
+
After resolving markers, run `agent-native template accept` — the baseline
|
|
76
|
+
deliberately does not advance past an unresolved merge.
|
|
77
|
+
|
|
78
|
+
Apps scaffolded before provenance existed have no baseline. Create one
|
|
79
|
+
with `agent-native template baseline` before the first sync.
|
|
80
|
+
|
|
81
|
+
4. **If upgrade or typecheck fails**
|
|
82
|
+
|
|
83
|
+
- Read the concrete error
|
|
84
|
+
- Fix **app** source, actions, config, or env — not framework packages
|
|
85
|
+
- Re-run `agent-native upgrade` or `pnpm typecheck`
|
|
86
|
+
- Stop and ask the user if you cannot fix the app-level error
|
|
87
|
+
|
|
88
|
+
Intentional app-level UI customization is a separate workflow. Read
|
|
89
|
+
`customizing-agent-native` when the product needs to own a selectively
|
|
90
|
+
copied component; do not use that path to reproduce framework runtime
|
|
91
|
+
behavior or hide version skew.
|
|
92
|
+
|
|
93
|
+
5. **Dry-run / partial runs**
|
|
94
|
+
|
|
95
|
+
```bash
|
|
96
|
+
agent-native upgrade --dry-run
|
|
97
|
+
agent-native upgrade --skip-verify
|
|
98
|
+
agent-native upgrade --skip-install # package.json bumps only
|
|
99
|
+
agent-native doctor --only migration-manifest
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
`migration-manifest` has no opt-out. Run it in CI before upgrading to find
|
|
103
|
+
imports that will break, then use `npx @agent-native/core@latest upgrade --codemods`
|
|
104
|
+
to preview the supported rewrite.
|
|
105
|
+
|
|
106
|
+
## Don't
|
|
107
|
+
|
|
108
|
+
- Don't add `pnpm.overrides`, `overrides`, `resolutions`, or
|
|
109
|
+
`patchedDependencies` for any `@agent-native/*` package
|
|
110
|
+
- Don't edit `node_modules/@agent-native/core` or
|
|
111
|
+
`node_modules/@agent-native/dispatch`
|
|
112
|
+
- Don't invent local "dispatch behavior" shims to paper over version skew
|
|
113
|
+
- Don't keep iterating with more framework patches after a failed install
|
|
114
|
+
- Don't skip `skills update scaffold --project` after a core bump (the
|
|
115
|
+
upgrade command does this for you)
|
|
116
|
+
|
|
117
|
+
## Related Skills
|
|
118
|
+
|
|
119
|
+
- **self-modifying-code** — Tier 4: framework packages are off limits
|
|
120
|
+
- **agent-native-docs** — version-matched docs after the bump
|
|
121
|
+
- **customizing-agent-native** — intentional app-owned UI copies, not upgrade patches
|
|
122
|
+
- **portability** — keep app code provider-agnostic across upgrades
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# Custom health check message
|
|
2
|
+
PING_MESSAGE=pong
|
|
3
|
+
|
|
4
|
+
# Email stamped as the creator of the deployment-owned observation scheduler.
|
|
5
|
+
WORKSPACE_OWNER_EMAIL=
|
|
6
|
+
|
|
7
|
+
# Public URL used for signed Builder completion callbacks after an explicit
|
|
8
|
+
# approval. Keep this aligned with the deployed Netlify URL until a custom
|
|
9
|
+
# domain is explicitly approved and configured.
|
|
10
|
+
FACTORY_PUBLIC_URL=https://agent-native-factory.netlify.app
|
|
11
|
+
|
|
12
|
+
# Builder execution is approval-gated and optional. Configure these only when
|
|
13
|
+
# the workspace should be able to start an approved Builder run.
|
|
14
|
+
BUILDER_AI_SERVICES_URL=https://ai-services.internal.builder.io
|
|
15
|
+
BUILDER_PROJECT_ID=
|
|
16
|
+
|
|
17
|
+
# The Builder private key and callback secret are resolved through workspace
|
|
18
|
+
# credentials. These names are documented here for local/deployment fallback;
|
|
19
|
+
# do not commit their values.
|
|
20
|
+
BUILDER_PRIVATE_KEY=
|
|
21
|
+
FACTORY_BUILDER_WEBHOOK_SECRET=
|
|
22
|
+
|
|
23
|
+
# Skip login/signup (local dev / preview only)
|
|
24
|
+
# AUTH_DISABLED=true
|
|
File without changes
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
# Factory
|
|
2
|
+
|
|
3
|
+
Factory is the visual workspace for building agent factories from incoming work
|
|
4
|
+
to governed delivery. The map is the source of truth; Dispatch owns the shared
|
|
5
|
+
inbox and routing, while Factory owns graph versions, queue state, rules,
|
|
6
|
+
decisions, feedback, agent runs, and provider-action audit records.
|
|
7
|
+
|
|
8
|
+
Before building common workspace or agent UI, read `agent-native-toolkit`; use
|
|
9
|
+
`customizing-agent-native` for the configure → compose → eject → propose
|
|
10
|
+
ladder.
|
|
11
|
+
|
|
12
|
+
## Core rules
|
|
13
|
+
|
|
14
|
+
- Keep app state in SQL via Drizzle and scope every read/write by org and
|
|
15
|
+
authenticated member. Use actions as the UI, agent, CLI, MCP, and A2A surface.
|
|
16
|
+
- Keep migrations additive and portable. These tables intentionally use explicit
|
|
17
|
+
`ownerEmail`/`orgId` columns for org-visible data, not `ownableColumns()`;
|
|
18
|
+
do not call `accessFilter` on them without adding deliberate visibility data.
|
|
19
|
+
- Resolve Slack through `server/connectors/credentials.ts`, passing caller
|
|
20
|
+
identity at the entrypoint. The dependency guard does not inspect nested
|
|
21
|
+
connector code, so a new direct `process.env.SLACK_BOT_TOKEN` read is a bug.
|
|
22
|
+
- A missing callback, partial thread, unreadable provider response, or missed
|
|
23
|
+
reconciliation is not success. Preserve typed failure or
|
|
24
|
+
`reconciliation_required` state.
|
|
25
|
+
- Hard guards are code, not prompt text: auth, session, identity,
|
|
26
|
+
credentials/vault, migrations, payments, security, and publishable
|
|
27
|
+
`packages/*` changes always require human review.
|
|
28
|
+
- All work is deduped by Factory item and rule/run identity. Provider comment IDs
|
|
29
|
+
are not the idempotency boundary.
|
|
30
|
+
- Slack interaction uses the generic Agent-Native Slack adapter. Polling is for
|
|
31
|
+
observation; mentions are for explanation, rule tuning, and explicit approval.
|
|
32
|
+
- Reuse the existing ai-services GitHub read and Builder execution APIs. Do not
|
|
33
|
+
duplicate GitHub installation/webhook infrastructure in this template.
|
|
34
|
+
- Do not add CRUD routes under `server/routes/api/`; actions are the domain
|
|
35
|
+
surface. Provider callbacks are the only exception and must verify signatures.
|
|
36
|
+
- Factory graph edits create immutable blueprint versions. AI proposes a
|
|
37
|
+
complete graph with `source=ai`; a person reviews and publishes it through
|
|
38
|
+
the same action surface as manual edits. The current evaluator runs enabled
|
|
39
|
+
rules in parallel, so graph edges describe intended handoffs until a runtime
|
|
40
|
+
binding exists.
|
|
41
|
+
- A selected graph node or edge is part of `navigation` context. Read
|
|
42
|
+
`view-screen` before answering why a route exists or changing the selected
|
|
43
|
+
Factory.
|
|
44
|
+
|
|
45
|
+
## Application state
|
|
46
|
+
|
|
47
|
+
- `navigation.view`: `factory` when the visual workspace is open.
|
|
48
|
+
- `navigation.factoryId`: selected Factory id when present.
|
|
49
|
+
- `navigation.factoryTab`: `map` | `inbox` | `rules` | `settings`.
|
|
50
|
+
- `navigation.factoryNodeId` / `navigation.factoryEdgeId`: selected graph target.
|
|
51
|
+
|
|
52
|
+
## Action contract
|
|
53
|
+
|
|
54
|
+
| Action | Purpose |
|
|
55
|
+
| --- | --- |
|
|
56
|
+
| `list-triage-items` / `get-triage-item` | Inspect the queue and evidence. |
|
|
57
|
+
| `poll-slack-channel` | Observe Slack history; never writes to Slack. |
|
|
58
|
+
| `ingest-github-observation` | Store read-only PR evidence. |
|
|
59
|
+
| `list-triage-rules` / `save-triage-rule` | Tune prompt rules and guards. |
|
|
60
|
+
| `evaluate-triage-item` | Append a structured decision. |
|
|
61
|
+
| `record-triage-feedback` | Capture human correction for learning. |
|
|
62
|
+
| `approve-factory-item` | Explicitly authorize one bounded run. |
|
|
63
|
+
| `suggest-factory-rules` | Mine feedback and fast approvals into proposals. |
|
|
64
|
+
| `reconcile-triage-run` | Persist callback/provider reconciliation. |
|
|
65
|
+
| `list-factories` / `get-factory-graph` | Inspect Factory definitions, graph versions, and live evidence metrics. |
|
|
66
|
+
| `save-factory-graph` | Create or version a complete visual graph; never starts provider work. |
|
|
67
|
+
| `list-factory-comments` / `add-factory-comment` | Read or attach comments to a canvas, node, or edge. |
|
|
68
|
+
|
|
69
|
+
Rules start in shadow mode. Enabling a rule never bypasses hard guards or
|
|
70
|
+
creates an implicit approval. Slack "do it now" and the UI approval control
|
|
71
|
+
both call `approve-factory-item`, which records the approver before dispatch.
|
|
72
|
+
|
|
73
|
+
Use the visual editor for direct blueprint changes. Use the agent chat for
|
|
74
|
+
natural language design, explanations, and proposals; it must preserve a
|
|
75
|
+
complete graph and use `save-factory-graph` rather than describing an
|
|
76
|
+
unpersisted change. Rule or guard changes must go through the triage rule
|
|
77
|
+
actions, never through graph JSON.
|
|
78
|
+
|
|
79
|
+
## Scheduler identity
|
|
80
|
+
|
|
81
|
+
`WORKSPACE_OWNER_EMAIL` is read only at startup to stamp the deployment-owned
|
|
82
|
+
job's `createdBy`; it is never caller identity and must not enter request
|
|
83
|
+
authorization or credential resolution.
|
|
84
|
+
|
|
85
|
+
## Hosting
|
|
86
|
+
|
|
87
|
+
Production needs `DATABASE_URL`, `WORKSPACE_OWNER_EMAIL`, and
|
|
88
|
+
`FACTORY_PUBLIC_URL`. Builder execution additionally needs the service URL and
|
|
89
|
+
project ID plus workspace-resolved Builder credentials. Keep rules in shadow
|
|
90
|
+
mode and require an explicit approval for every provider run.
|