@agent-native/core 0.102.1 → 0.103.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 +15 -0
- package/corpus/core/docs/content/local-file-mode.mdx +99 -489
- package/corpus/core/docs/content/locales/ar-SA/local-file-mode.mdx +35 -490
- package/corpus/core/docs/content/locales/ar-SA/template-content.mdx +10 -24
- package/corpus/core/docs/content/locales/de-DE/local-file-mode.mdx +37 -491
- package/corpus/core/docs/content/locales/de-DE/template-content.mdx +10 -24
- package/corpus/core/docs/content/locales/es-ES/local-file-mode.mdx +35 -493
- package/corpus/core/docs/content/locales/es-ES/template-content.mdx +10 -24
- package/corpus/core/docs/content/locales/fr-FR/local-file-mode.mdx +38 -491
- package/corpus/core/docs/content/locales/fr-FR/template-content.mdx +10 -24
- package/corpus/core/docs/content/locales/hi-IN/local-file-mode.mdx +33 -492
- package/corpus/core/docs/content/locales/hi-IN/template-content.mdx +10 -24
- package/corpus/core/docs/content/locales/ja-JP/local-file-mode.mdx +36 -492
- package/corpus/core/docs/content/locales/ja-JP/template-content.mdx +10 -24
- package/corpus/core/docs/content/locales/ko-KR/local-file-mode.mdx +35 -490
- package/corpus/core/docs/content/locales/ko-KR/template-content.mdx +10 -24
- package/corpus/core/docs/content/locales/pt-BR/local-file-mode.mdx +35 -493
- package/corpus/core/docs/content/locales/pt-BR/template-content.mdx +10 -24
- package/corpus/core/docs/content/locales/zh-CN/local-file-mode.mdx +31 -489
- package/corpus/core/docs/content/locales/zh-CN/template-content.mdx +9 -24
- package/corpus/core/docs/content/locales/zh-TW/local-file-mode.mdx +31 -489
- package/corpus/core/docs/content/locales/zh-TW/template-content.mdx +9 -24
- package/corpus/core/docs/content/template-content.mdx +26 -42
- package/corpus/core/package.json +1 -1
- package/corpus/core/src/cli/content-local.ts +86 -18
- package/corpus/core/src/cli/index.ts +2 -2
- package/corpus/core/src/cli/skills-content/content-skill.ts +36 -25
- package/corpus/core/src/cli/skills.ts +47 -13
- package/corpus/core/src/client/AgentPanel.tsx +7 -0
- package/corpus/core/src/client/AssistantChat.tsx +7 -0
- package/corpus/core/src/client/agent-chat-adapter.ts +7 -1
- package/corpus/core/src/client/chat/message-components.tsx +17 -3
- package/corpus/core/src/client/composer/ComposerPlusMenu.tsx +96 -6
- package/corpus/core/src/client/composer/asset-picker-url.ts +80 -0
- package/corpus/core/src/client/error-format.ts +24 -0
- package/corpus/core/src/client/resources/McpIntegrationDialog.tsx +8 -1
- package/corpus/core/src/local-artifacts/index.ts +65 -0
- package/corpus/templates/assets/app/components/library/GenerationPresetsPanel.tsx +325 -0
- package/corpus/templates/assets/app/hooks/use-navigation-state.ts +12 -0
- package/corpus/templates/assets/app/i18n/zh-TW.ts +21 -0
- package/corpus/templates/assets/app/i18n-data.ts +215 -0
- package/corpus/templates/assets/app/routes/brand-kits.$id.tsx +19 -479
- package/corpus/templates/assets/app/routes/brand-kits.$id_.presets.$presetId.tsx +1 -1
- package/corpus/templates/assets/app/routes/brand-kits.$id_.settings.tsx +446 -0
- package/corpus/templates/assets/app/routes/library.tsx +69 -0
- package/corpus/templates/assets/changelog/2026-07-15-fixed-top-level-image-picker-selections-returning-to-the-com.md +6 -0
- package/corpus/templates/clips/actions/disconnect-calendar.ts +57 -9
- package/corpus/templates/clips/actions/generate-workflow.ts +102 -59
- package/corpus/templates/clips/actions/get-recording-player-data.ts +64 -1
- package/corpus/templates/clips/actions/regenerate-summary.ts +7 -0
- package/corpus/templates/clips/actions/regenerate-title.ts +29 -11
- package/corpus/templates/clips/app/components/editor/editor-layout.tsx +34 -13
- package/corpus/templates/clips/app/components/editor/thumbnail-picker.tsx +87 -9
- package/corpus/templates/clips/app/components/editor/trim-handles.tsx +15 -0
- package/corpus/templates/clips/app/components/editor/waveform.tsx +21 -8
- package/corpus/templates/clips/app/components/library/folder-tree.tsx +52 -0
- package/corpus/templates/clips/app/components/player/settings-panel.tsx +116 -58
- package/corpus/templates/clips/app/components/player/share-dialog.tsx +43 -37
- package/corpus/templates/clips/app/components/player/video-player.tsx +50 -2
- package/corpus/templates/clips/app/components/recorder/microphone-visualizer.tsx +22 -3
- package/corpus/templates/clips/app/i18n/ar-SA.ts +5 -2
- package/corpus/templates/clips/app/i18n/de-DE.ts +6 -2
- package/corpus/templates/clips/app/i18n/en-US.ts +5 -2
- package/corpus/templates/clips/app/i18n/es-ES.ts +6 -2
- package/corpus/templates/clips/app/i18n/fr-FR.ts +5 -2
- package/corpus/templates/clips/app/i18n/hi-IN.ts +5 -2
- package/corpus/templates/clips/app/i18n/ja-JP.ts +6 -1
- package/corpus/templates/clips/app/i18n/ko-KR.ts +5 -2
- package/corpus/templates/clips/app/i18n/pt-BR.ts +6 -2
- package/corpus/templates/clips/app/i18n/zh-CN.ts +5 -2
- package/corpus/templates/clips/app/i18n/zh-TW.ts +5 -2
- package/corpus/templates/clips/app/lib/timestamp-mapping.ts +14 -0
- package/corpus/templates/clips/app/routes/_app.library._index.tsx +1 -2
- package/corpus/templates/clips/app/routes/_index.tsx +1 -2
- package/corpus/templates/clips/app/routes/r.$recordingId.tsx +98 -32
- package/corpus/templates/clips/app/routes/share.$shareId.tsx +4 -1
- package/corpus/templates/clips/changelog/2026-07-15-ai-workflow-generation-now-stays-visible-avoids-duplicate-re.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-15-clip-playback-and-cta-controls-remain-interactive-through-ed.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-15-clip-titles-no-longer-describe-the-product-as-a-loom-alterna.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-15-description-regeneration-now-opens-the-agent-chat-so-progres.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-15-direct-recording-urls-now-respect-share-link-and-password-ac.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-15-disconnecting-a-calendar-now-clears-unrecorded-synced-meetin.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-15-folders-now-expose-rename-and-delete-actions-directly-in-the.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-15-recording-pages-now-explain-sign-in-access-and-avoid-showing.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-15-the-clips-extension-quick-actions-toolbar-can-be-moved-out-o.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-15-the-editor-now-skips-cut-sections-during-preview-and-keeps-t.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-15-thumbnail-capture-now-updates-previews-while-scrubbing-and-l.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-15-windows-permission-links-open-the-matching-settings-page.md +6 -0
- package/corpus/templates/clips/chrome-extension/src/content-script.ts +117 -2
- package/corpus/templates/clips/chrome-extension/src/overlay.ts +27 -0
- package/corpus/templates/clips/desktop/src-tauri/tauri.conf.json +1 -1
- package/corpus/templates/clips/server/lib/calendar-event-meetings.ts +139 -101
- package/corpus/templates/clips/server/lib/recording-page-access.ts +35 -0
- package/corpus/templates/clips/server/lib/share-password.ts +6 -3
- package/corpus/templates/content/.agents/skills/content/SKILL.md +26 -39
- package/corpus/templates/content/AGENTS.md +25 -30
- package/corpus/templates/content/actions/_builder-docs-client.ts +23 -0
- package/corpus/templates/content/actions/_content-database-source-adapters.ts +21 -3
- package/corpus/templates/content/actions/_content-files.ts +338 -0
- package/corpus/templates/content/actions/_content-space-access.ts +135 -0
- package/corpus/templates/content/actions/_content-spaces.ts +640 -0
- package/corpus/templates/content/actions/_database-source-utils.ts +90 -7
- package/corpus/templates/content/actions/_database-utils.ts +7 -1
- package/corpus/templates/content/actions/_local-file-documents.ts +0 -9
- package/corpus/templates/content/actions/_local-folder-source.ts +53 -0
- package/corpus/templates/content/actions/_property-utils.ts +9 -4
- package/corpus/templates/content/actions/add-database-item.ts +108 -65
- package/corpus/templates/content/actions/backfill-content-files.ts +22 -0
- package/corpus/templates/content/actions/connect-local-folder-source.ts +221 -0
- package/corpus/templates/content/actions/create-content-database.ts +129 -3
- package/corpus/templates/content/actions/create-document.ts +65 -55
- package/corpus/templates/content/actions/create-inline-content-database.ts +6 -1
- package/corpus/templates/content/actions/delete-content-database.ts +3 -0
- package/corpus/templates/content/actions/delete-document.ts +7 -11
- package/corpus/templates/content/actions/disconnect-local-folder-source.ts +175 -0
- package/corpus/templates/content/actions/duplicate-database-item.ts +10 -0
- package/corpus/templates/content/actions/duplicate-database-items.ts +13 -0
- package/corpus/templates/content/actions/edit-document.ts +2 -28
- package/corpus/templates/content/actions/ensure-content-spaces.ts +26 -0
- package/corpus/templates/content/actions/export-content-source.ts +47 -9
- package/corpus/templates/content/actions/get-document.ts +0 -14
- package/corpus/templates/content/actions/import-content-source.ts +43 -3
- package/corpus/templates/content/actions/list-content-spaces.ts +103 -0
- package/corpus/templates/content/actions/list-documents.ts +12 -9
- package/corpus/templates/content/actions/move-document.ts +3 -14
- package/corpus/templates/content/actions/pull-document.ts +0 -23
- package/corpus/templates/content/actions/remove-local-file-source.ts +50 -29
- package/corpus/templates/content/actions/resolve-local-folder-conflict.ts +442 -0
- package/corpus/templates/content/actions/reveal-local-source-file.ts +6 -17
- package/corpus/templates/content/actions/search-documents.ts +0 -34
- package/corpus/templates/content/actions/share-local-file-document.ts +25 -1
- package/corpus/templates/content/actions/submit-content-database-form.ts +12 -0
- package/corpus/templates/content/actions/sync-local-folder-source.ts +731 -0
- package/corpus/templates/content/actions/sync-manifest-local-folder-source.ts +123 -0
- package/corpus/templates/content/actions/update-content-database-view.ts +10 -1
- package/corpus/templates/content/actions/update-document.ts +0 -15
- package/corpus/templates/content/actions/view-screen.ts +2 -50
- package/corpus/templates/content/app/components/editor/SlashCommandMenu.tsx +76 -62
- package/corpus/templates/content/app/components/editor/database/DatabaseView.tsx +70 -22
- package/corpus/templates/content/app/components/editor/database/grouping.ts +2 -1
- package/corpus/templates/content/app/components/editor/database/settings.tsx +23 -20
- package/corpus/templates/content/app/components/editor/database/shared.tsx +2 -0
- package/corpus/templates/content/app/components/editor/database/sidebar.tsx +330 -0
- package/corpus/templates/content/app/components/editor/database/types.ts +1 -0
- package/corpus/templates/content/app/components/editor/database/view-config.ts +3 -1
- package/corpus/templates/content/app/components/layout/Layout.tsx +25 -1
- package/corpus/templates/content/app/components/sidebar/DocumentSidebar.tsx +209 -113
- package/corpus/templates/content/app/components/sidebar/select-content-space.ts +31 -0
- package/corpus/templates/content/app/hooks/use-content-database.ts +16 -0
- package/corpus/templates/content/app/hooks/use-content-spaces.ts +39 -0
- package/corpus/templates/content/app/i18n/zh-TW.ts +11 -0
- package/corpus/templates/content/app/i18n-data.ts +75 -0
- package/corpus/templates/content/app/routes/_app.local-files.tsx +174 -65
- package/corpus/templates/content/changelog/2026-07-16-content-callouts-can-now-be-reviewed-and-published-to-builder.md +6 -0
- package/corpus/templates/content/changelog/2026-07-16-heading-5-and-heading-6-are-available-from-the-editor-slash-.md +6 -0
- package/corpus/templates/content/changelog/2026-07-16-organize-every-workspace-through-a-customizable-files-databa.md +6 -0
- package/corpus/templates/content/parity/matrix.md +2 -1
- package/corpus/templates/content/parity/matrix.ts +37 -1
- package/corpus/templates/content/scripts/dev-database.mjs +7 -5
- package/corpus/templates/content/server/db/schema.ts +113 -40
- package/corpus/templates/content/server/lib/document-context.ts +15 -1
- package/corpus/templates/content/server/lib/notion-sync.ts +6 -0
- package/corpus/templates/content/server/plugins/db.ts +153 -0
- package/corpus/templates/content/shared/api.ts +17 -3
- package/corpus/templates/content/shared/builder-mdx.ts +163 -16
- package/corpus/templates/design/.agents/skills/design-templates/SKILL.md +59 -0
- package/corpus/templates/design/AGENTS.md +6 -1
- package/corpus/templates/design/actions/create-design-from-template.ts +19 -7
- package/corpus/templates/design/actions/list-design-templates.ts +69 -21
- package/corpus/templates/design/actions/navigate.ts +2 -2
- package/corpus/templates/design/actions/view-screen.ts +15 -2
- package/corpus/templates/design/agent-native.app-skill.json +5 -0
- package/corpus/templates/design/app/components/design/design-canvas/external-preview.ts +7 -3
- package/corpus/templates/design/app/components/editor/PromptDialog.tsx +281 -56
- package/corpus/templates/design/app/components/templates/TemplatePreview.tsx +14 -2
- package/corpus/templates/design/app/hooks/use-navigation-state.ts +3 -2
- package/corpus/templates/design/app/i18n/zh-TW.ts +3 -3
- package/corpus/templates/design/app/i18n-data.ts +21 -2
- package/corpus/templates/design/app/i18n-template-feature.ts +218 -10
- package/corpus/templates/design/app/pages/Index.tsx +195 -24
- package/corpus/templates/design/app/pages/Templates.tsx +144 -55
- package/corpus/templates/design/app/pages/design-editor/generation-prompt-directives.ts +12 -1
- package/corpus/templates/design/changelog/2026-07-14-templates-now-appear-in-the-new-design-picker-with-previews-.md +6 -0
- package/corpus/templates/design/changelog/2026-07-15-prototype-print-and-download-buttons-now-work-in-preview.md +6 -0
- package/corpus/templates/design/changelog/2026-07-15-templates-now-open-immediately-after-copying-even-while-the-.md +6 -0
- package/corpus/templates/design/server/plugins/agent-chat.ts +1 -1
- package/corpus/templates/mail/AGENTS.md +23 -18
- package/corpus/templates/mail/actions/bulk-archive.ts +32 -28
- package/corpus/templates/mail/actions/mark-read.ts +131 -20
- package/corpus/templates/mail/actions/mark-thread-read.ts +1 -1
- package/corpus/templates/mail/actions/move-email.ts +30 -24
- package/corpus/templates/mail/actions/send-email.ts +73 -68
- package/corpus/templates/mail/changelog/2026-07-15-unread-inbox-cleanup-now-completes-reliably.md +6 -0
- package/corpus/templates/mail/server/handlers/emails.ts +218 -209
- package/corpus/templates/mail/server/lib/bulk-mark-read.ts +30 -0
- package/corpus/templates/mail/server/lib/email-state.ts +198 -113
- package/corpus/templates/mail/server/lib/google-auth.ts +218 -25
- package/corpus/templates/mail/server/lib/jobs.ts +69 -74
- package/corpus/templates/mail/server/lib/local-email-store.ts +265 -0
- package/corpus/templates/mail/server/plugins/agent-chat.ts +6 -0
- package/corpus/templates/slides/actions/extract-pdf.ts +1 -1
- package/corpus/templates/slides/actions/import-file.ts +4 -1
- package/corpus/templates/slides/app/components/editor/ImageGenPanel.tsx +1 -1
- package/corpus/templates/slides/app/components/editor/ImageSearchPanel.tsx +9 -12
- package/corpus/templates/slides/app/components/editor/SlideEditor.tsx +29 -21
- package/corpus/templates/slides/app/i18n/ar-SA.ts +1 -0
- package/corpus/templates/slides/app/i18n/de-DE.ts +1 -0
- package/corpus/templates/slides/app/i18n/en-US.ts +1 -0
- package/corpus/templates/slides/app/i18n/es-ES.ts +1 -0
- package/corpus/templates/slides/app/i18n/fr-FR.ts +1 -0
- package/corpus/templates/slides/app/i18n/hi-IN.ts +1 -0
- package/corpus/templates/slides/app/i18n/ja-JP.ts +1 -0
- package/corpus/templates/slides/app/i18n/ko-KR.ts +1 -0
- package/corpus/templates/slides/app/i18n/pt-BR.ts +1 -0
- package/corpus/templates/slides/app/i18n/zh-CN.ts +1 -0
- package/corpus/templates/slides/app/i18n/zh-TW.ts +1 -0
- package/corpus/templates/slides/changelog/2026-07-15-image-search-and-generation-controls-now-use-the-registered-.md +6 -0
- package/corpus/templates/slides/changelog/2026-07-15-pdf-deck-references-can-be-imported-for-slide-inspiration-ag.md +6 -0
- package/corpus/templates/slides/changelog/2026-07-15-stable-style-inspector-dock.md +6 -0
- package/dist/cli/content-local.d.ts +1 -0
- package/dist/cli/content-local.d.ts.map +1 -1
- package/dist/cli/content-local.js +75 -17
- package/dist/cli/content-local.js.map +1 -1
- package/dist/cli/index.js +2 -2
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/skills-content/content-skill.d.ts +1 -1
- package/dist/cli/skills-content/content-skill.d.ts.map +1 -1
- package/dist/cli/skills-content/content-skill.js +36 -25
- package/dist/cli/skills-content/content-skill.js.map +1 -1
- package/dist/cli/skills.d.ts.map +1 -1
- package/dist/cli/skills.js +47 -14
- package/dist/cli/skills.js.map +1 -1
- package/dist/client/AgentPanel.d.ts.map +1 -1
- package/dist/client/AgentPanel.js +5 -0
- package/dist/client/AgentPanel.js.map +1 -1
- package/dist/client/AssistantChat.d.ts.map +1 -1
- package/dist/client/AssistantChat.js +7 -0
- package/dist/client/AssistantChat.js.map +1 -1
- package/dist/client/agent-chat-adapter.d.ts.map +1 -1
- package/dist/client/agent-chat-adapter.js +8 -1
- package/dist/client/agent-chat-adapter.js.map +1 -1
- package/dist/client/chat/message-components.d.ts +4 -0
- package/dist/client/chat/message-components.d.ts.map +1 -1
- package/dist/client/chat/message-components.js +10 -3
- package/dist/client/chat/message-components.js.map +1 -1
- package/dist/client/composer/ComposerPlusMenu.d.ts.map +1 -1
- package/dist/client/composer/ComposerPlusMenu.js +58 -6
- package/dist/client/composer/ComposerPlusMenu.js.map +1 -1
- package/dist/client/composer/asset-picker-url.d.ts +16 -0
- package/dist/client/composer/asset-picker-url.d.ts.map +1 -0
- package/dist/client/composer/asset-picker-url.js +64 -0
- package/dist/client/composer/asset-picker-url.js.map +1 -0
- package/dist/client/error-format.d.ts.map +1 -1
- package/dist/client/error-format.js +17 -0
- package/dist/client/error-format.js.map +1 -1
- package/dist/client/resources/McpIntegrationDialog.d.ts.map +1 -1
- package/dist/client/resources/McpIntegrationDialog.js +6 -1
- package/dist/client/resources/McpIntegrationDialog.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/local-artifacts/index.d.ts +10 -0
- package/dist/local-artifacts/index.d.ts.map +1 -1
- package/dist/local-artifacts/index.js +39 -0
- package/dist/local-artifacts/index.js.map +1 -1
- package/dist/notifications/routes.d.ts +1 -1
- package/dist/provider-api/corpus-jobs.d.ts +2 -2
- package/dist/resources/handlers.d.ts +3 -3
- package/dist/server/agent-engine-api-key-route.d.ts +1 -1
- package/dist/server/transcribe-voice.d.ts +1 -1
- package/docs/content/local-file-mode.mdx +99 -489
- package/docs/content/locales/ar-SA/local-file-mode.mdx +35 -490
- package/docs/content/locales/ar-SA/template-content.mdx +10 -24
- package/docs/content/locales/de-DE/local-file-mode.mdx +37 -491
- package/docs/content/locales/de-DE/template-content.mdx +10 -24
- package/docs/content/locales/es-ES/local-file-mode.mdx +35 -493
- package/docs/content/locales/es-ES/template-content.mdx +10 -24
- package/docs/content/locales/fr-FR/local-file-mode.mdx +38 -491
- package/docs/content/locales/fr-FR/template-content.mdx +10 -24
- package/docs/content/locales/hi-IN/local-file-mode.mdx +33 -492
- package/docs/content/locales/hi-IN/template-content.mdx +10 -24
- package/docs/content/locales/ja-JP/local-file-mode.mdx +36 -492
- package/docs/content/locales/ja-JP/template-content.mdx +10 -24
- package/docs/content/locales/ko-KR/local-file-mode.mdx +35 -490
- package/docs/content/locales/ko-KR/template-content.mdx +10 -24
- package/docs/content/locales/pt-BR/local-file-mode.mdx +35 -493
- package/docs/content/locales/pt-BR/template-content.mdx +10 -24
- package/docs/content/locales/zh-CN/local-file-mode.mdx +31 -489
- package/docs/content/locales/zh-CN/template-content.mdx +9 -24
- package/docs/content/locales/zh-TW/local-file-mode.mdx +31 -489
- package/docs/content/locales/zh-TW/template-content.mdx +9 -24
- package/docs/content/template-content.mdx +26 -42
- package/package.json +1 -1
- package/corpus/templates/assets/app/components/library/EditLibraryDialog.tsx +0 -126
|
@@ -91,9 +91,8 @@ When you open the app, you'll see a page tree next to the editor. The agent alwa
|
|
|
91
91
|
- **Organize pages in a tree** — nest infinitely, drag to reorder, favorite pages you use often.
|
|
92
92
|
- **Search across everything** with full-text search across titles and content.
|
|
93
93
|
- **Edit local Markdown/MDX files like Obsidian.** Use the `/local-files` view
|
|
94
|
-
to
|
|
95
|
-
changes, and
|
|
96
|
-
the selected `.md` or `.mdx` file.
|
|
94
|
+
to connect a folder to a space's Files database, edit with your own tools,
|
|
95
|
+
sync changes, and review conflicts without leaving the database-backed app.
|
|
97
96
|
- **Generate rich interactive custom blocks.** Register local React components,
|
|
98
97
|
insert them as MDX, and let the agent create or update component files for
|
|
99
98
|
your docs.
|
|
@@ -136,31 +135,23 @@ as the review surface. The hosted app remains the source of truth for sharing,
|
|
|
136
135
|
comments, permissions, and live collaboration; the local folder is an explicit
|
|
137
136
|
sync surface.
|
|
138
137
|
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
database mode when you want hosted collaboration and SQL-backed sharing. See [Local File Mode](/docs/local-file-mode) for the
|
|
147
|
-
standalone repo layout, configuration, custom MDX components, local
|
|
148
|
-
`extensions/` widgets, and production safety guide.
|
|
138
|
+
Local folders now use the same database model as every other page. Each page
|
|
139
|
+
belongs to a space and its system Files database; a folder is a source adapter
|
|
140
|
+
on that database. You can attach a folder to an existing space or create a
|
|
141
|
+
private folder-backed space, then use database properties and saved sidebar
|
|
142
|
+
views on the imported pages. See [Local folder sources](/docs/local-file-mode)
|
|
143
|
+
for configuration, truth policies, conflicts, custom MDX components, and local
|
|
144
|
+
`extensions/` widgets.
|
|
149
145
|
|
|
150
|
-
To
|
|
146
|
+
To open Content for an existing repo:
|
|
151
147
|
|
|
152
148
|
```bash
|
|
153
|
-
npx @agent-native/core@latest
|
|
149
|
+
npx @agent-native/core@latest content .
|
|
154
150
|
```
|
|
155
151
|
|
|
156
|
-
The
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
local bridge is running, agents should use Content actions such as
|
|
160
|
-
`list-documents`, `get-document`, `edit-document`, `update-document`, and
|
|
161
|
-
`share-local-file-document` instead of raw filesystem writes. Without that local
|
|
162
|
-
bridge, the installed skill still gives the agent the repo-editing contract for
|
|
163
|
-
safe Markdown/MDX edits.
|
|
152
|
+
The CLI starts normal database-backed Content, registers an opaque local-folder
|
|
153
|
+
connection in `agent-native.json`, and opens the connection screen. It does not
|
|
154
|
+
set a local-mode environment variable.
|
|
164
155
|
|
|
165
156
|
## For developers
|
|
166
157
|
|
|
@@ -189,28 +180,21 @@ Open `http://localhost:8083` and create your first page. Then ask the agent to "
|
|
|
189
180
|
|
|
190
181
|
**Search and comments.** Full-text search, anchored comments, version history, and restore flows are built into the document surface.
|
|
191
182
|
|
|
192
|
-
**Sync surfaces.** Documents can sync with Notion or local Markdown/MDX folders,
|
|
183
|
+
**Sync surfaces.** Documents can sync with Notion or local Markdown/MDX folders, while SQL remains the canonical collaborative data model.
|
|
193
184
|
|
|
194
185
|
### Local file sync
|
|
195
186
|
|
|
196
187
|
The protected `/local-files` route uses the browser File System Access API, or a
|
|
197
|
-
guarded native folder bridge inside Agent Native Desktop, to
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
The bulk sync route calls:
|
|
208
|
-
|
|
209
|
-
- `export-content-source` — reads the accessible document tree and returns a
|
|
210
|
-
deterministic `content/` file bundle.
|
|
211
|
-
- `import-content-source` — validates files, creates new private documents,
|
|
212
|
-
updates documents where the caller has editor access, preserves version
|
|
213
|
-
history, and rejects invalid parent cycles.
|
|
188
|
+
guarded native folder bridge inside Agent Native Desktop, to connect a folder to
|
|
189
|
+
a Files database. SQL stores only an opaque connection ID, relative paths,
|
|
190
|
+
hashes, and source metadata. Sync materializes ordinary database pages and
|
|
191
|
+
records concurrent edits as reviewable change sets instead of silently
|
|
192
|
+
overwriting either side. Disconnecting preserves both database pages and files.
|
|
193
|
+
|
|
194
|
+
The folder workflow calls `connect-local-folder-source`,
|
|
195
|
+
`sync-local-folder-source`, `resolve-local-folder-conflict`, and
|
|
196
|
+
`disconnect-local-folder-source`. `export-content-source` can export one source
|
|
197
|
+
using its original relative paths.
|
|
214
198
|
|
|
215
199
|
The source format lives in `shared/content-source.ts`. Keep that file as the
|
|
216
200
|
single contract for filenames, frontmatter, parsing, and serialization.
|
|
@@ -674,6 +658,6 @@ The agent can make all of these changes itself — ask it to "add a tags column
|
|
|
674
658
|
|
|
675
659
|
- [**Templates**](/docs/cloneable-saas) — the clone-and-own model, and every other domain template to start from
|
|
676
660
|
- [**Getting Started**](/docs/getting-started) — the framework fundamentals: actions, application state, and live sync
|
|
677
|
-
- [**Local
|
|
661
|
+
- [**Local folder sources**](/docs/local-file-mode) — spaces, Files databases, folder adapters, migration, and safety
|
|
678
662
|
- [**Real-Time Collaboration**](/docs/real-time-collaboration) — the Yjs pipeline documents share with other collaborative surfaces
|
|
679
663
|
- [**Sharing**](/docs/sharing) — the share-grant model documents build on
|
package/corpus/core/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@agent-native/core",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.103.0",
|
|
4
4
|
"description": "Framework for agent-native application development — where AI agents and UI share SQL state, actions, and context",
|
|
5
5
|
"homepage": "https://github.com/BuilderIO/agent-native#readme",
|
|
6
6
|
"bugs": {
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { spawn } from "node:child_process";
|
|
2
|
+
import { createHash } from "node:crypto";
|
|
2
3
|
import fsSync from "node:fs";
|
|
3
4
|
import fs from "node:fs/promises";
|
|
4
5
|
import path from "node:path";
|
|
@@ -8,7 +9,7 @@ const CONTENT_APP_ID = "content";
|
|
|
8
9
|
const MANIFEST_FILE = "agent-native.json";
|
|
9
10
|
const DEFAULT_PORT = 8083;
|
|
10
11
|
const DEFAULT_PROFILE = "docs/no-bookkeeping";
|
|
11
|
-
const
|
|
12
|
+
const LOCAL_FOLDER_CONNECTION_PREFIX = "local-folder:";
|
|
12
13
|
|
|
13
14
|
export interface ContentLocalArgs {
|
|
14
15
|
target?: string;
|
|
@@ -25,6 +26,7 @@ export interface ContentLocalLaunchPlan {
|
|
|
25
26
|
manifestPath: string;
|
|
26
27
|
rootPath: string;
|
|
27
28
|
filePath?: string;
|
|
29
|
+
connectionId: string;
|
|
28
30
|
url: string;
|
|
29
31
|
command: string;
|
|
30
32
|
args: string[];
|
|
@@ -48,10 +50,18 @@ function titleFromPath(value: string) {
|
|
|
48
50
|
);
|
|
49
51
|
}
|
|
50
52
|
|
|
51
|
-
function
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
53
|
+
function localFolderConnectionId(absoluteRootPath: string) {
|
|
54
|
+
let canonicalRootPath = path.resolve(absoluteRootPath);
|
|
55
|
+
try {
|
|
56
|
+
canonicalRootPath = fsSync.realpathSync(canonicalRootPath);
|
|
57
|
+
} catch (error) {
|
|
58
|
+
if ((error as NodeJS.ErrnoException).code !== "ENOENT") throw error;
|
|
59
|
+
}
|
|
60
|
+
const digest = createHash("sha256")
|
|
61
|
+
.update(canonicalRootPath)
|
|
62
|
+
.digest("base64url")
|
|
63
|
+
.slice(0, 24);
|
|
64
|
+
return `${LOCAL_FOLDER_CONNECTION_PREFIX}${digest}`;
|
|
55
65
|
}
|
|
56
66
|
|
|
57
67
|
function isRecord(value: unknown): value is Record<string, unknown> {
|
|
@@ -134,6 +144,7 @@ function resolveTarget(target: string, cwd: string) {
|
|
|
134
144
|
|
|
135
145
|
return {
|
|
136
146
|
absoluteTarget,
|
|
147
|
+
absoluteRootPath: targetDirectory,
|
|
137
148
|
isFile: stat.isFile(),
|
|
138
149
|
workspaceRoot,
|
|
139
150
|
rootPath: normalizeSlash(rootPath),
|
|
@@ -161,8 +172,13 @@ async function readManifest(
|
|
|
161
172
|
|
|
162
173
|
function upsertContentManifest(
|
|
163
174
|
manifest: Record<string, unknown>,
|
|
175
|
+
workspaceRoot: string,
|
|
164
176
|
rootPath: string,
|
|
165
|
-
options: {
|
|
177
|
+
options: {
|
|
178
|
+
connectionId: string;
|
|
179
|
+
filePath?: string;
|
|
180
|
+
profile?: string;
|
|
181
|
+
},
|
|
166
182
|
) {
|
|
167
183
|
const next: Record<string, unknown> = {
|
|
168
184
|
...manifest,
|
|
@@ -192,18 +208,62 @@ function upsertContentManifest(
|
|
|
192
208
|
? existingRoot.extensions
|
|
193
209
|
: [".md", ".mdx"],
|
|
194
210
|
...(profile ? { profile } : {}),
|
|
195
|
-
...(include && rootIndex === -1
|
|
211
|
+
...(include && (rootIndex === -1 || Array.isArray(existingRoot?.include))
|
|
212
|
+
? {
|
|
213
|
+
include: Array.from(
|
|
214
|
+
new Set([
|
|
215
|
+
...(Array.isArray(existingRoot?.include)
|
|
216
|
+
? existingRoot.include.filter(
|
|
217
|
+
(value): value is string => typeof value === "string",
|
|
218
|
+
)
|
|
219
|
+
: []),
|
|
220
|
+
...include,
|
|
221
|
+
]),
|
|
222
|
+
),
|
|
223
|
+
}
|
|
224
|
+
: {}),
|
|
225
|
+
source: {
|
|
226
|
+
...(isRecord(existingRoot?.source) ? existingRoot.source : {}),
|
|
227
|
+
type: "local-folder",
|
|
228
|
+
connectionId: options.connectionId,
|
|
229
|
+
truthPolicy: "source_primary",
|
|
230
|
+
},
|
|
196
231
|
};
|
|
197
|
-
|
|
232
|
+
let roots =
|
|
198
233
|
rootIndex === -1
|
|
199
234
|
? [...existingRoots, root]
|
|
200
235
|
: existingRoots.map((entry, index) =>
|
|
201
236
|
index === rootIndex ? { ...entry, ...root } : entry,
|
|
202
237
|
);
|
|
203
238
|
|
|
239
|
+
if (existingContent.mode === "local-files") {
|
|
240
|
+
roots = roots.map((entry) => {
|
|
241
|
+
if (entry === root || typeof entry.path !== "string") return entry;
|
|
242
|
+
const existingSource = isRecord(entry.source) ? entry.source : {};
|
|
243
|
+
return {
|
|
244
|
+
...entry,
|
|
245
|
+
source: {
|
|
246
|
+
...existingSource,
|
|
247
|
+
type: "local-folder",
|
|
248
|
+
connectionId:
|
|
249
|
+
typeof existingSource.connectionId === "string" &&
|
|
250
|
+
existingSource.connectionId
|
|
251
|
+
? existingSource.connectionId
|
|
252
|
+
: localFolderConnectionId(
|
|
253
|
+
path.resolve(workspaceRoot, entry.path),
|
|
254
|
+
),
|
|
255
|
+
truthPolicy:
|
|
256
|
+
typeof existingSource.truthPolicy === "string"
|
|
257
|
+
? existingSource.truthPolicy
|
|
258
|
+
: "source_primary",
|
|
259
|
+
},
|
|
260
|
+
};
|
|
261
|
+
});
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
delete existingContent.mode;
|
|
204
265
|
apps[CONTENT_APP_ID] = {
|
|
205
266
|
...existingContent,
|
|
206
|
-
mode: "local-files",
|
|
207
267
|
roots,
|
|
208
268
|
hide: Array.isArray(existingContent.hide)
|
|
209
269
|
? existingContent.hide
|
|
@@ -234,9 +294,10 @@ export function findContentTemplateDir(cwd = process.cwd()) {
|
|
|
234
294
|
);
|
|
235
295
|
}
|
|
236
296
|
|
|
237
|
-
function launchUrl(port: number, filePath?: string) {
|
|
238
|
-
const
|
|
239
|
-
|
|
297
|
+
function launchUrl(port: number, connectionId: string, filePath?: string) {
|
|
298
|
+
const params = new URLSearchParams({ connectionId });
|
|
299
|
+
if (filePath) params.set("file", filePath);
|
|
300
|
+
return `http://127.0.0.1:${port}/local-files?${params.toString()}`;
|
|
240
301
|
}
|
|
241
302
|
|
|
242
303
|
export async function prepareContentLocalLaunch(options: {
|
|
@@ -249,10 +310,13 @@ export async function prepareContentLocalLaunch(options: {
|
|
|
249
310
|
const cwd = path.resolve(options.cwd ?? process.cwd());
|
|
250
311
|
const target = resolveTarget(options.target, cwd);
|
|
251
312
|
const manifestPath = path.join(target.workspaceRoot, MANIFEST_FILE);
|
|
313
|
+
const connectionId = localFolderConnectionId(target.absoluteRootPath);
|
|
252
314
|
const manifest = upsertContentManifest(
|
|
253
315
|
await readManifest(manifestPath),
|
|
316
|
+
target.workspaceRoot,
|
|
254
317
|
target.rootPath,
|
|
255
318
|
{
|
|
319
|
+
connectionId,
|
|
256
320
|
filePath: target.filePath,
|
|
257
321
|
profile: options.profile,
|
|
258
322
|
},
|
|
@@ -273,7 +337,8 @@ export async function prepareContentLocalLaunch(options: {
|
|
|
273
337
|
manifestPath,
|
|
274
338
|
rootPath: target.rootPath,
|
|
275
339
|
filePath: target.filePath,
|
|
276
|
-
|
|
340
|
+
connectionId,
|
|
341
|
+
url: launchUrl(options.port ?? DEFAULT_PORT, connectionId, target.filePath),
|
|
277
342
|
command: "corepack",
|
|
278
343
|
args: [
|
|
279
344
|
"pnpm",
|
|
@@ -287,7 +352,6 @@ export async function prepareContentLocalLaunch(options: {
|
|
|
287
352
|
"--strictPort",
|
|
288
353
|
],
|
|
289
354
|
env: {
|
|
290
|
-
AGENT_NATIVE_MODE: "local-files",
|
|
291
355
|
AGENT_NATIVE_MANIFEST_PATH: manifestPath,
|
|
292
356
|
},
|
|
293
357
|
manifest,
|
|
@@ -316,7 +380,7 @@ function printHelp() {
|
|
|
316
380
|
agent-native content <file-or-folder> [options]
|
|
317
381
|
|
|
318
382
|
Options:
|
|
319
|
-
--profile <name> Local
|
|
383
|
+
--profile <name> Local folder profile, for example docs/no-bookkeeping
|
|
320
384
|
--port <number> Dev server port (default ${DEFAULT_PORT})
|
|
321
385
|
--open Open the target in the browser (default)
|
|
322
386
|
--no-open Start the server without opening the browser
|
|
@@ -326,9 +390,13 @@ Options:
|
|
|
326
390
|
|
|
327
391
|
export async function runContentLocal(argv: string[]) {
|
|
328
392
|
const parsed = parseContentLocalArgs(argv);
|
|
329
|
-
if (parsed.help
|
|
393
|
+
if (parsed.help) {
|
|
394
|
+
printHelp();
|
|
395
|
+
return 0;
|
|
396
|
+
}
|
|
397
|
+
if (!parsed.target) {
|
|
330
398
|
printHelp();
|
|
331
|
-
return
|
|
399
|
+
return 1;
|
|
332
400
|
}
|
|
333
401
|
|
|
334
402
|
const plan = await prepareContentLocalLaunch({
|
|
@@ -343,7 +411,7 @@ export async function runContentLocal(argv: string[]) {
|
|
|
343
411
|
return 0;
|
|
344
412
|
}
|
|
345
413
|
|
|
346
|
-
console.log(`Content
|
|
414
|
+
console.log(`Content folder source: ${plan.rootPath}`);
|
|
347
415
|
console.log(`Manifest: ${plan.manifestPath}`);
|
|
348
416
|
console.log(`Opening: ${plan.url}`);
|
|
349
417
|
|
|
@@ -1098,8 +1098,8 @@ Usage:
|
|
|
1098
1098
|
--with-github-action also writes the PR Visual
|
|
1099
1099
|
Recap workflow into .github/workflows/.
|
|
1100
1100
|
agent-native content local-files <file-or-folder>
|
|
1101
|
-
|
|
1102
|
-
|
|
1101
|
+
Connect a local docs/content folder to normal
|
|
1102
|
+
database-backed Content. Use --no-open, --port N,
|
|
1103
1103
|
or --profile docs/no-bookkeeping as needed.
|
|
1104
1104
|
agent-native design connect Start a localhost Design bridge for a running
|
|
1105
1105
|
dev server. Use --url, --port, --root, or
|
|
@@ -2,8 +2,9 @@ export const CONTENT_SKILL_MD = `---
|
|
|
2
2
|
name: content
|
|
3
3
|
description: >-
|
|
4
4
|
Use Content for repo-backed Markdown/MDX docs, blogs, resources, rich
|
|
5
|
-
document editing, local components, shareable copies, and
|
|
6
|
-
|
|
5
|
+
document editing, local components, shareable copies, and database-backed
|
|
6
|
+
local-folder sources. Prefer Content actions over raw filesystem writes when
|
|
7
|
+
available.
|
|
7
8
|
metadata:
|
|
8
9
|
visibility: exported
|
|
9
10
|
---
|
|
@@ -14,21 +15,22 @@ Use the Content app when a workflow is about authoring, editing, reviewing, or
|
|
|
14
15
|
publishing Markdown/MDX documents: docs sites, blogs, resource libraries,
|
|
15
16
|
marketing pages, internal notes, and local MDX components. Content gives the
|
|
16
17
|
agent a document tree, a rich editor, normal document actions, and optional
|
|
17
|
-
local-
|
|
18
|
+
local-folder synchronization.
|
|
18
19
|
|
|
19
20
|
## Choose The Path
|
|
20
21
|
|
|
21
22
|
- Use Content actions when the Content MCP/action tools are available:
|
|
22
23
|
\`list-documents\`, \`search-documents\`, \`get-document\`,
|
|
23
24
|
\`pull-document\`, \`create-document\`, \`edit-document\`,
|
|
24
|
-
\`update-document\`, \`delete-document\`,
|
|
25
|
+
\`update-document\`, \`delete-document\`,
|
|
26
|
+
\`sync-manifest-local-folder-source\`, \`sync-local-folder-source\`,
|
|
25
27
|
\`list-local-component-files\`, and \`write-local-component-file\`.
|
|
26
28
|
- Use \`pull-document\` or \`get-document\` before editing a page. Use
|
|
27
29
|
\`edit-document\` for precise find/replace changes and \`update-document\`
|
|
28
30
|
for full rewrites or new content.
|
|
29
|
-
-
|
|
30
|
-
|
|
31
|
-
|
|
31
|
+
- Local folders declared in \`agent-native.json\` are sources for ordinary
|
|
32
|
+
SQL-backed Content pages. Use the trusted bridge's pull/check/push workflows to
|
|
33
|
+
synchronize them; normal document actions always operate on the database.
|
|
32
34
|
- If Content tools are not visible and no local Content app or Desktop bridge is
|
|
33
35
|
running, treat this skill as repo-editing guidance. Edit configured
|
|
34
36
|
\`.md\`/\`.mdx\` files directly, preserve frontmatter and MDX imports, and tell
|
|
@@ -40,16 +42,15 @@ Prefer JSON input for action calls:
|
|
|
40
42
|
|
|
41
43
|
\`\`\`bash
|
|
42
44
|
pnpm action list-documents
|
|
43
|
-
pnpm action get-document '{"id":"
|
|
44
|
-
pnpm action edit-document '{"id":"
|
|
45
|
-
pnpm action update-document '{"id":"
|
|
46
|
-
pnpm action share-local-file-document '{"id":"local-file:..."}'
|
|
45
|
+
pnpm action get-document '{"id":"document-id"}'
|
|
46
|
+
pnpm action edit-document '{"id":"document-id","find":"old copy","replace":"new copy"}'
|
|
47
|
+
pnpm action update-document '{"id":"document-id","content":"# Updated\\n\\nBody"}'
|
|
47
48
|
\`\`\`
|
|
48
49
|
|
|
49
50
|
Run \`refresh-list\` after create/update/delete operations when you need the
|
|
50
51
|
open Content UI sidebar to repaint immediately.
|
|
51
52
|
|
|
52
|
-
## Local
|
|
53
|
+
## Local Folder Sources
|
|
53
54
|
|
|
54
55
|
Install into an existing repo with:
|
|
55
56
|
|
|
@@ -58,20 +59,30 @@ npx @agent-native/core@latest skills add content --mode local-files --scope proj
|
|
|
58
59
|
\`\`\`
|
|
59
60
|
|
|
60
61
|
The installer copies this skill and writes or updates \`agent-native.json\` with
|
|
61
|
-
|
|
62
|
-
\`components/\` folder for local MDX components. A
|
|
62
|
+
database-backed local-folder sources for \`docs/\`, \`blog/\`, \`content/\`, and
|
|
63
|
+
\`resources/\`, plus a \`components/\` folder for local MDX components. A trusted
|
|
64
|
+
local bridge imports these files into the workspace's canonical Files database.
|
|
65
|
+
Run \`sync-manifest-local-folder-source\` with a root's generated
|
|
66
|
+
\`source.connectionId\`, or launch \`agent-native content local-files <target>\`,
|
|
67
|
+
to connect and pull it. A typical root looks like:
|
|
63
68
|
|
|
64
69
|
\`\`\`json
|
|
65
70
|
{
|
|
66
71
|
"version": 1,
|
|
67
72
|
"apps": {
|
|
68
73
|
"content": {
|
|
69
|
-
"mode": "local-files",
|
|
70
74
|
"roots": [
|
|
71
|
-
{
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
+
{
|
|
76
|
+
"name": "Docs",
|
|
77
|
+
"path": "docs",
|
|
78
|
+
"kind": "docs",
|
|
79
|
+
"extensions": [".md", ".mdx"],
|
|
80
|
+
"source": {
|
|
81
|
+
"type": "local-folder",
|
|
82
|
+
"connectionId": "local-folder:<opaque-id>",
|
|
83
|
+
"truthPolicy": "source_primary"
|
|
84
|
+
}
|
|
85
|
+
}
|
|
75
86
|
],
|
|
76
87
|
"components": "components",
|
|
77
88
|
"extensions": "extensions",
|
|
@@ -81,9 +92,9 @@ Content roots for \`docs/\`, \`blog/\`, \`content/\`, and \`resources/\`, plus a
|
|
|
81
92
|
}
|
|
82
93
|
\`\`\`
|
|
83
94
|
|
|
84
|
-
Local
|
|
85
|
-
Content app cannot read private repo files by itself. File access
|
|
86
|
-
local Content app, Agent Native Desktop, or another trusted
|
|
95
|
+
Local-folder synchronization does not make the host language model local, and
|
|
96
|
+
the hosted Content app cannot read private repo files by itself. File access
|
|
97
|
+
requires a local Content app, Agent Native Desktop, or another trusted bridge.
|
|
87
98
|
|
|
88
99
|
## MDX And Components
|
|
89
100
|
|
|
@@ -99,9 +110,9 @@ local Content app, Agent Native Desktop, or another trusted local bridge.
|
|
|
99
110
|
|
|
100
111
|
## Boundaries
|
|
101
112
|
|
|
102
|
-
-
|
|
103
|
-
|
|
104
|
-
|
|
113
|
+
- A database page and its source file can change independently. Use folder
|
|
114
|
+
check/pull/push and resolve reported conflicts rather than silently overwriting
|
|
115
|
+
either revision.
|
|
105
116
|
- Do not push/pull Notion, Builder.io, or other provider-backed content unless
|
|
106
117
|
the user explicitly asks for provider sync.
|
|
107
118
|
- Do not paste secrets, private provider data, or credential-looking values into
|
|
@@ -119,7 +119,7 @@ export const BUILT_IN_APP_SKILLS = {
|
|
|
119
119
|
id: "content",
|
|
120
120
|
displayName: "Content",
|
|
121
121
|
description:
|
|
122
|
-
"Edit docs, blogs, resources, and MDX content through the Content app, including
|
|
122
|
+
"Edit docs, blogs, resources, and MDX content through the Content app, including database-backed local-folder sources.",
|
|
123
123
|
hosted: {
|
|
124
124
|
url: "https://content.agent-native.com",
|
|
125
125
|
mcpUrl: "https://content.agent-native.com/mcp",
|
|
@@ -128,7 +128,7 @@ export const BUILT_IN_APP_SKILLS = {
|
|
|
128
128
|
auth: {
|
|
129
129
|
mode: "oauth",
|
|
130
130
|
setup:
|
|
131
|
-
"Authenticate with the Content MCP connector in the host app. Local
|
|
131
|
+
"Authenticate with the Content MCP connector in the host app. Local-folder synchronization requires a local Content app, Agent Native Desktop, or trusted local bridge for filesystem access.",
|
|
132
132
|
},
|
|
133
133
|
surfaces: [
|
|
134
134
|
{
|
|
@@ -941,15 +941,15 @@ function contentModeInstructionBlock(input: {
|
|
|
941
941
|
if (input.mode === "local-files") {
|
|
942
942
|
return `## Installed Mode
|
|
943
943
|
|
|
944
|
-
Default storage for this installation
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
944
|
+
Default storage for this installation is Content's SQL database. This repo's
|
|
945
|
+
\`agent-native.json\` declares \`docs/\`, \`blog/\`, \`content/\`, and
|
|
946
|
+
\`resources/\` as local-folder sources with opaque connection ids; it does not
|
|
947
|
+
select a separate application mode. A trusted local Content app or Agent Native
|
|
948
|
+
Desktop bridge imports those files into their workspace's canonical Files
|
|
949
|
+
database, after which normal Content document actions read and edit the SQL-backed
|
|
950
|
+
pages. Use \`sync-manifest-local-folder-source\` with each root's generated
|
|
951
|
+
connection id, or launch \`agent-native content local-files <target>\`, to connect
|
|
952
|
+
and pull it. The hosted Content app cannot read private repo files by itself.`;
|
|
953
953
|
}
|
|
954
954
|
if (input.mode === "self-hosted") {
|
|
955
955
|
return `## Installed Mode
|
|
@@ -1139,8 +1139,23 @@ function shouldWriteContentLocalFilesManifest(
|
|
|
1139
1139
|
return targetId === "content" && mode === "local-files";
|
|
1140
1140
|
}
|
|
1141
1141
|
|
|
1142
|
+
function contentLocalFolderConnectionId(baseDir: string, rootPath: string) {
|
|
1143
|
+
const absoluteRootPath = path.resolve(baseDir, rootPath);
|
|
1144
|
+
let canonicalRootPath = absoluteRootPath;
|
|
1145
|
+
try {
|
|
1146
|
+
canonicalRootPath = fs.realpathSync(absoluteRootPath);
|
|
1147
|
+
} catch (error: any) {
|
|
1148
|
+
if (error?.code !== "ENOENT") throw error;
|
|
1149
|
+
}
|
|
1150
|
+
return `local-folder:${createHash("sha256")
|
|
1151
|
+
.update(canonicalRootPath)
|
|
1152
|
+
.digest("base64url")
|
|
1153
|
+
.slice(0, 24)}`;
|
|
1154
|
+
}
|
|
1155
|
+
|
|
1142
1156
|
function mergeContentLocalFilesManifest(
|
|
1143
1157
|
existing: unknown,
|
|
1158
|
+
baseDir: string,
|
|
1144
1159
|
): Record<string, unknown> {
|
|
1145
1160
|
const manifest = isJsonRecord(existing) ? { ...existing } : {};
|
|
1146
1161
|
if (manifest.version === undefined) manifest.version = 1;
|
|
@@ -1148,10 +1163,29 @@ function mergeContentLocalFilesManifest(
|
|
|
1148
1163
|
const apps = isJsonRecord(manifest.apps) ? { ...manifest.apps } : {};
|
|
1149
1164
|
const contentApp = isJsonRecord(apps.content) ? { ...apps.content } : {};
|
|
1150
1165
|
const defaults = defaultContentLocalFilesAppConfig();
|
|
1151
|
-
contentApp.mode = "local-files";
|
|
1152
1166
|
if (!Array.isArray(contentApp.roots) || contentApp.roots.length === 0) {
|
|
1153
1167
|
contentApp.roots = defaults.roots;
|
|
1154
1168
|
}
|
|
1169
|
+
contentApp.roots = contentApp.roots.map((root: unknown) => {
|
|
1170
|
+
if (!isJsonRecord(root) || typeof root.path !== "string") return root;
|
|
1171
|
+
const source = isJsonRecord(root.source) ? root.source : {};
|
|
1172
|
+
return {
|
|
1173
|
+
...root,
|
|
1174
|
+
source: {
|
|
1175
|
+
...source,
|
|
1176
|
+
type: "local-folder",
|
|
1177
|
+
connectionId:
|
|
1178
|
+
typeof source.connectionId === "string" && source.connectionId
|
|
1179
|
+
? source.connectionId
|
|
1180
|
+
: contentLocalFolderConnectionId(baseDir, root.path),
|
|
1181
|
+
truthPolicy:
|
|
1182
|
+
typeof source.truthPolicy === "string"
|
|
1183
|
+
? source.truthPolicy
|
|
1184
|
+
: "source_primary",
|
|
1185
|
+
},
|
|
1186
|
+
};
|
|
1187
|
+
});
|
|
1188
|
+
delete contentApp.mode;
|
|
1155
1189
|
if (contentApp.components === undefined) {
|
|
1156
1190
|
contentApp.components = defaults.components;
|
|
1157
1191
|
}
|
|
@@ -1181,7 +1215,7 @@ function writeContentLocalFilesManifest(
|
|
|
1181
1215
|
);
|
|
1182
1216
|
}
|
|
1183
1217
|
}
|
|
1184
|
-
const manifest = mergeContentLocalFilesManifest(existing);
|
|
1218
|
+
const manifest = mergeContentLocalFilesManifest(existing, baseDir);
|
|
1185
1219
|
if (!options.dryRun) {
|
|
1186
1220
|
fs.writeFileSync(
|
|
1187
1221
|
manifestPath,
|
|
@@ -110,6 +110,7 @@ import type {
|
|
|
110
110
|
MultiTabAssistantChatHeaderProps,
|
|
111
111
|
MultiTabAssistantChatProps,
|
|
112
112
|
} from "./MultiTabAssistantChat.js";
|
|
113
|
+
import { recoverFromStaleChunkError } from "./route-chunk-recovery.js";
|
|
113
114
|
import { AgentNativeRouteWarmup } from "./route-warmup.js";
|
|
114
115
|
import { withBuilderConnectTrackingParams } from "./settings/useBuilderStatus.js";
|
|
115
116
|
import { useScreenRefreshKey } from "./use-db-sync.js";
|
|
@@ -2371,6 +2372,12 @@ class AgentPanelErrorBoundary extends React.Component<
|
|
|
2371
2372
|
}
|
|
2372
2373
|
|
|
2373
2374
|
componentDidCatch(error: Error, errorInfo: React.ErrorInfo) {
|
|
2375
|
+
if (recoverFromStaleChunkError(error)) {
|
|
2376
|
+
console.warn(
|
|
2377
|
+
"[agent-native] Recovering agent panel after stale chunk error",
|
|
2378
|
+
);
|
|
2379
|
+
return;
|
|
2380
|
+
}
|
|
2374
2381
|
const recoverableKind = assistantUiRecoverableRenderErrorKind(error);
|
|
2375
2382
|
if (recoverableKind) {
|
|
2376
2383
|
console.warn(
|
|
@@ -2354,6 +2354,11 @@ const AssistantChatInner = forwardRef<
|
|
|
2354
2354
|
} | null>(null);
|
|
2355
2355
|
const [authSessionAvailable, setAuthSessionAvailable] = useState(false);
|
|
2356
2356
|
const [queuedMessages, setQueuedMessages] = useState<QueuedMessage[]>([]);
|
|
2357
|
+
// The dequeue guard briefly stays locked after appending a queued turn so
|
|
2358
|
+
// the adapter has time to claim the run. Wake the effect when that guard
|
|
2359
|
+
// expires; otherwise a fast-completing turn can leave the remaining queue
|
|
2360
|
+
// pending with no state transition left to trigger another dequeue.
|
|
2361
|
+
const [queueWakeVersion, setQueueWakeVersion] = useState(0);
|
|
2357
2362
|
const queuedMessagesRef = useRef<QueuedMessage[]>([]);
|
|
2358
2363
|
const queueDirtyRef = useRef(false);
|
|
2359
2364
|
const queueMutationVersionRef = useRef(0);
|
|
@@ -4041,6 +4046,7 @@ const AssistantChatInner = forwardRef<
|
|
|
4041
4046
|
if (appended) {
|
|
4042
4047
|
window.setTimeout(() => {
|
|
4043
4048
|
dequeueInFlightRef.current = false;
|
|
4049
|
+
setQueueWakeVersion((version) => version + 1);
|
|
4044
4050
|
}, 500);
|
|
4045
4051
|
} else {
|
|
4046
4052
|
dequeueInFlightRef.current = false;
|
|
@@ -4062,6 +4068,7 @@ const AssistantChatInner = forwardRef<
|
|
|
4062
4068
|
applyLocalQueuedMessages,
|
|
4063
4069
|
isRestoring,
|
|
4064
4070
|
isRunning,
|
|
4071
|
+
queueWakeVersion,
|
|
4065
4072
|
queuedMessages,
|
|
4066
4073
|
threadId,
|
|
4067
4074
|
]);
|
|
@@ -3392,7 +3392,13 @@ export function createAgentChatAdapter(
|
|
|
3392
3392
|
text: formatChatErrorText(
|
|
3393
3393
|
message,
|
|
3394
3394
|
preservedError?.upgradeUrl,
|
|
3395
|
-
|
|
3395
|
+
// `message` is already user-facing here: either a
|
|
3396
|
+
// recovery-specific explanation from exhaustedRecoveryMessage
|
|
3397
|
+
// or a normalized gateway message from errorInfo. Passing
|
|
3398
|
+
// the fallback connection_error code back through the
|
|
3399
|
+
// formatter would replace the useful recovery guidance
|
|
3400
|
+
// with the generic interruption copy.
|
|
3401
|
+
preservedError ? errorCode : undefined,
|
|
3396
3402
|
),
|
|
3397
3403
|
});
|
|
3398
3404
|
yield {
|