@agent-native/core 0.146.8 → 0.148.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 +1 -1
- package/corpus/templates/analytics/.agents/skills/frontend-design/SKILL.md +115 -68
- package/corpus/templates/analytics/.agents/skills/turn-into-app/SKILL.md +18 -6
- package/corpus/templates/analytics/.agents/skills/turn-into-app/references/fresh-project.md +8 -1
- package/corpus/templates/analytics/DEVELOPING.md +50 -3
- package/corpus/templates/analytics/actions/purge-first-party-analytics-postgres.ts +190 -0
- package/corpus/templates/analytics/app/i18n/index.ts +14 -29
- package/corpus/templates/analytics/app/i18n-data.ts +10 -10
- package/corpus/templates/analytics/app/pages/Settings.tsx +5 -21
- package/corpus/templates/analytics/app/pages/sessions/SessionsPage.tsx +1 -3
- package/corpus/templates/analytics/app/routes/status.$slug.tsx +4 -2
- package/corpus/templates/analytics/scripts/first-party-analytics-bigquery-backfill.ts +253 -24
- package/corpus/templates/analytics/server/db/schema.ts +23 -0
- package/corpus/templates/analytics/server/handlers/first-party-analytics.ts +3 -1
- package/corpus/templates/analytics/server/jobs/analytics-bigquery-backfill.ts +1 -1
- package/corpus/templates/analytics/server/lib/first-party-analytics-backend.ts +113 -13
- package/corpus/templates/analytics/server/lib/first-party-analytics-purge.ts +140 -0
- package/corpus/templates/analytics/server/lib/first-party-analytics-volume.ts +207 -0
- package/corpus/templates/analytics/server/lib/first-party-analytics.ts +40 -9
- package/corpus/templates/analytics/server/lib/gcloud.ts +148 -20
- package/corpus/templates/analytics/server/plugins/db.ts +42 -0
- package/corpus/templates/assets/.agents/skills/frontend-design/SKILL.md +115 -68
- package/corpus/templates/assets/.agents/skills/turn-into-app/SKILL.md +18 -6
- package/corpus/templates/assets/.agents/skills/turn-into-app/references/fresh-project.md +8 -1
- package/corpus/templates/assets/app/i18n/index.ts +14 -29
- package/corpus/templates/brain/.agents/skills/adding-a-feature/SKILL.md +9 -0
- package/corpus/templates/brain/.agents/skills/frontend-design/SKILL.md +115 -68
- package/corpus/templates/brain/.agents/skills/turn-into-app/SKILL.md +18 -6
- package/corpus/templates/brain/.agents/skills/turn-into-app/references/fresh-project.md +8 -1
- package/corpus/templates/brain/app/i18n/index.ts +14 -29
- package/corpus/templates/calendar/.agents/skills/frontend-design/SKILL.md +115 -68
- package/corpus/templates/calendar/.agents/skills/turn-into-app/SKILL.md +18 -6
- package/corpus/templates/calendar/.agents/skills/turn-into-app/references/fresh-project.md +8 -1
- package/corpus/templates/chat/.agents/skills/adding-a-feature/SKILL.md +9 -0
- package/corpus/templates/chat/.agents/skills/frontend-design/SKILL.md +115 -68
- package/corpus/templates/chat/.agents/skills/turn-into-app/SKILL.md +18 -6
- package/corpus/templates/chat/.agents/skills/turn-into-app/references/fresh-project.md +8 -1
- package/corpus/templates/chat/app/i18n/index.ts +14 -29
- package/corpus/templates/clips/.agents/skills/frontend-design/SKILL.md +115 -68
- package/corpus/templates/clips/.agents/skills/turn-into-app/SKILL.md +18 -6
- package/corpus/templates/clips/.agents/skills/turn-into-app/references/fresh-project.md +8 -1
- package/corpus/templates/clips/app/components/player/transcript-panel.tsx +2 -7
- package/corpus/templates/clips/app/components/recorder/storage-setup-card.tsx +18 -13
- package/corpus/templates/clips/app/components/settings/ai-setup-section.tsx +87 -370
- package/corpus/templates/clips/app/components/settings/slack-section.tsx +59 -101
- package/corpus/templates/clips/app/components/settings/video-storage-section.tsx +136 -213
- package/corpus/templates/clips/app/i18n/en-US.ts +11 -8
- package/corpus/templates/clips/app/routes/r.$recordingId.tsx +16 -4
- package/corpus/templates/clips/app/routes/share.meeting.$meetingId.tsx +14 -5
- package/corpus/templates/clips/desktop/src/app.tsx +1 -1
- package/corpus/templates/clips/package.json +1 -0
- package/corpus/templates/clips/react-router.config.ts +7 -0
- package/corpus/templates/clips/server/plugins/auth.ts +6 -1
- package/corpus/templates/clips/shared/prerendered-public-paths.ts +21 -0
- package/corpus/templates/clips/shared/share-meta.ts +8 -3
- package/corpus/templates/content/.agents/skills/frontend-design/SKILL.md +115 -68
- package/corpus/templates/content/.agents/skills/turn-into-app/SKILL.md +18 -6
- package/corpus/templates/content/.agents/skills/turn-into-app/references/fresh-project.md +8 -1
- package/corpus/templates/content/app/i18n/index.ts +14 -29
- package/corpus/templates/crm/.agents/skills/turn-into-app/SKILL.md +18 -6
- package/corpus/templates/crm/.agents/skills/turn-into-app/references/fresh-project.md +8 -1
- package/corpus/templates/crm/app/i18n/index.ts +14 -29
- package/corpus/templates/design/.agents/skills/frontend-design/SKILL.md +115 -68
- package/corpus/templates/design/.agents/skills/turn-into-app/SKILL.md +18 -6
- package/corpus/templates/design/.agents/skills/turn-into-app/references/fresh-project.md +8 -1
- package/corpus/templates/design/actions/analyze-brand-assets.ts +15 -15
- package/corpus/templates/design/actions/import-code.ts +2 -43
- package/corpus/templates/design/app/i18n/index.ts +14 -29
- package/corpus/templates/dispatch/.agents/skills/frontend-design/SKILL.md +115 -68
- package/corpus/templates/dispatch/.agents/skills/turn-into-app/SKILL.md +18 -6
- package/corpus/templates/dispatch/.agents/skills/turn-into-app/references/fresh-project.md +8 -1
- package/corpus/templates/dispatch/app/chat-first-pages.ts +747 -0
- package/corpus/templates/dispatch/app/i18n-data.ts +182 -1
- package/corpus/templates/dispatch/app/routes/settings.tsx +62 -1
- package/corpus/templates/dispatch/changelog/2026-08-08-chat-first-navigation-keeps-conversations-central-while-open.md +6 -0
- package/corpus/templates/factory/.agents/skills/adding-a-feature/SKILL.md +9 -0
- package/corpus/templates/factory/.agents/skills/frontend-design/SKILL.md +115 -68
- package/corpus/templates/factory/.agents/skills/turn-into-app/SKILL.md +18 -6
- package/corpus/templates/factory/.agents/skills/turn-into-app/references/fresh-project.md +8 -1
- package/corpus/templates/factory/AGENTS.md +40 -49
- package/corpus/templates/factory/actions/babysit-agent-native-pull-request.ts +66 -0
- package/corpus/templates/factory/actions/evaluate-triage-item.ts +37 -0
- package/corpus/templates/factory/actions/get-slack-feedback-context.ts +20 -0
- package/corpus/templates/factory/actions/get-triage-item.ts +25 -4
- package/corpus/templates/factory/actions/govern-agent-native-pull-request.ts +55 -0
- package/corpus/templates/factory/actions/ingest-github-observation.ts +21 -0
- package/corpus/templates/factory/actions/list-factory-audit.ts +118 -0
- package/corpus/templates/factory/actions/list-factory-automations.ts +2 -1
- package/corpus/templates/factory/actions/list-triage-items.ts +24 -2
- package/corpus/templates/factory/actions/poll-github-sources.ts +60 -0
- package/corpus/templates/factory/actions/poll-sentry-errors.ts +39 -0
- package/corpus/templates/factory/actions/poll-slack-channel.ts +45 -1
- package/corpus/templates/factory/actions/run-factory-automation.ts +1 -1
- package/corpus/templates/factory/actions/save-factory-automation.ts +2 -2
- package/corpus/templates/factory/actions/start-builder-for-item.ts +51 -0
- package/corpus/templates/factory/app/components/factory/FactoryAuditView.tsx +685 -0
- package/corpus/templates/factory/app/hooks/use-navigation-state.ts +6 -0
- package/corpus/templates/factory/app/i18n/en-US.ts +25 -0
- package/corpus/templates/factory/app/routes/factory.tsx +203 -118
- package/corpus/templates/factory/changelog/2026-08-08-scheduler-health-moves-to-settings.md +6 -0
- package/corpus/templates/factory/server/db/schema.ts +37 -0
- package/corpus/templates/factory/server/lib/require-factory-automation.ts +5 -1
- package/corpus/templates/factory/server/plugins/factory-migrations.ts +29 -0
- package/corpus/templates/factory/server/triage/audit.ts +79 -0
- package/corpus/templates/forms/.agents/skills/frontend-design/SKILL.md +115 -68
- package/corpus/templates/forms/.agents/skills/turn-into-app/SKILL.md +18 -6
- package/corpus/templates/forms/.agents/skills/turn-into-app/references/fresh-project.md +8 -1
- package/corpus/templates/forms/app/i18n/index.ts +14 -29
- package/corpus/templates/macros/.agents/skills/frontend-design/SKILL.md +115 -68
- package/corpus/templates/macros/.agents/skills/turn-into-app/SKILL.md +18 -6
- package/corpus/templates/macros/.agents/skills/turn-into-app/references/fresh-project.md +8 -1
- package/corpus/templates/macros/app/i18n/index.ts +14 -29
- package/corpus/templates/mail/.agents/skills/frontend-design/SKILL.md +115 -68
- package/corpus/templates/mail/.agents/skills/turn-into-app/SKILL.md +18 -6
- package/corpus/templates/mail/.agents/skills/turn-into-app/references/fresh-project.md +8 -1
- package/corpus/templates/mail/app/i18n/index.ts +14 -29
- package/corpus/templates/plan/.agents/skills/adding-a-feature/SKILL.md +9 -0
- package/corpus/templates/plan/.agents/skills/frontend-design/SKILL.md +115 -68
- package/corpus/templates/plan/.agents/skills/turn-into-app/SKILL.md +18 -6
- package/corpus/templates/plan/.agents/skills/turn-into-app/references/fresh-project.md +8 -1
- package/corpus/templates/plan/app/components/plan/wireframe/Wireframe.tsx +7 -7
- package/corpus/templates/plan/app/i18n/index.ts +14 -29
- package/corpus/templates/plan/app/lib/plan-document-title.ts +3 -1
- package/corpus/templates/plan/app/root.tsx +1 -0
- package/corpus/templates/slides/.agents/skills/frontend-design/SKILL.md +115 -68
- package/corpus/templates/slides/.agents/skills/turn-into-app/SKILL.md +18 -6
- package/corpus/templates/slides/.agents/skills/turn-into-app/references/fresh-project.md +8 -1
- package/corpus/templates/slides/actions/analyze-brand-assets.ts +15 -15
- package/corpus/templates/slides/actions/import-code.ts +2 -43
- package/corpus/templates/slides/app/i18n/index.ts +14 -29
- package/corpus/templates/slides/server/routes/api/preview-images.get.ts +4 -1
- package/corpus/templates/tasks/.agents/skills/adding-a-feature/SKILL.md +9 -0
- package/corpus/templates/tasks/.agents/skills/frontend-design/SKILL.md +115 -68
- package/corpus/templates/tasks/.agents/skills/turn-into-app/SKILL.md +18 -6
- package/corpus/templates/tasks/.agents/skills/turn-into-app/references/fresh-project.md +8 -1
- package/corpus/templates/tasks/app/components/layout/HeaderActions.tsx +1 -84
- package/corpus/templates/tasks/app/hooks/use-mobile.tsx +1 -21
- package/corpus/templates/tasks/app/i18n/index.ts +14 -29
- package/dist/agent/engine/ai-sdk-engine.js +2 -1
- package/dist/agent/engine/builder-engine.d.ts +11 -1
- package/dist/agent/engine/builder-engine.js +11 -4
- package/dist/agent/engine/openai-compatible-endpoint.d.ts +2 -0
- package/dist/agent/engine/openai-compatible-endpoint.js +5 -1
- package/dist/agent/engine/provider-endpoint-validation.d.ts +9 -0
- package/dist/agent/engine/provider-endpoint-validation.js +26 -0
- package/dist/agent/engine/provider-env-vars.d.ts +1 -1
- package/dist/agent/engine/provider-env-vars.js +1 -1
- package/dist/agent/engine/registry.d.ts +8 -6
- package/dist/agent/engine/registry.js +37 -24
- package/dist/agent/tool-search.d.ts +1 -0
- package/dist/agent/tool-search.js +17 -1
- package/dist/automations/service.js +4 -10
- package/dist/brand-kit/brand-signals.d.ts +13 -0
- package/dist/brand-kit/brand-signals.js +15 -0
- package/dist/brand-kit/index.d.ts +2 -2
- package/dist/brand-kit/index.js +1 -1
- package/dist/chat-threads/store.d.ts +2 -0
- package/dist/chat-threads/store.js +1 -1
- package/dist/cli/agent-plugin.d.ts +5 -2
- package/dist/cli/agent-plugin.js +17 -9
- package/dist/cli/code-agent-executor.js +25 -5
- package/dist/cli/code-agent-mcp-config.d.ts +21 -0
- package/dist/cli/code-agent-mcp-config.js +103 -0
- package/dist/cli/plan-blocks.d.ts +3 -18
- package/dist/cli/plan-blocks.js +2 -95
- package/dist/cli/plan-publish-store.d.ts +2 -61
- package/dist/cli/plan-publish-store.js +2 -127
- package/dist/cli/skills-content/connection.d.ts +1 -1
- package/dist/cli/skills-content/connection.js +1 -52
- package/dist/cli/skills-content/visual-recap-skill.d.ts +1 -1
- package/dist/cli/skills-content/visual-recap-skill.js +1 -553
- package/dist/client/NewWorkspaceAppFlow.js +4 -1
- package/dist/client/agent-chat/index.d.ts +4 -1
- package/dist/client/agent-chat/index.js +4 -1
- package/dist/client/agent-engine-key.d.ts +14 -4
- package/dist/client/agent-engine-key.js +51 -5
- package/dist/client/agent-page/AgentTabsPage.d.ts +1 -0
- package/dist/client/agent-page/AgentTabsPage.js +4 -3
- package/dist/client/agent-provider-catalog.d.ts +20 -0
- package/dist/client/agent-provider-catalog.js +100 -0
- package/dist/client/app-providers.d.ts +3 -1
- package/dist/client/app-providers.js +50 -5
- package/dist/client/blocks/index.d.ts +1 -0
- package/dist/client/blocks/index.js +1 -0
- package/dist/client/chat/run-recovery.js +4 -48
- package/dist/client/chat/runtime.js +63 -0
- package/dist/client/chat-first/agents-pane.d.ts +2 -0
- package/dist/client/chat-first/agents-pane.js +6 -0
- package/dist/client/chat-first/app-pane.d.ts +2 -0
- package/dist/client/chat-first/app-pane.js +6 -0
- package/dist/client/chat-first/apps-rail.d.ts +2 -0
- package/dist/client/chat-first/apps-rail.js +103 -0
- package/dist/client/chat-first/browser-pane.d.ts +2 -0
- package/dist/client/chat-first/browser-pane.js +64 -0
- package/dist/client/chat-first/chat-history.d.ts +12 -0
- package/dist/client/chat-first/chat-history.js +10 -0
- package/dist/client/chat-first/copy.d.ts +2 -0
- package/dist/client/chat-first/copy.js +117 -0
- package/dist/client/chat-first/index.d.ts +13 -0
- package/dist/client/chat-first/index.js +12 -0
- package/dist/client/chat-first/primary-nav.d.ts +8 -0
- package/dist/client/chat-first/primary-nav.js +6 -0
- package/dist/client/chat-first/session-watch-pane.d.ts +2 -0
- package/dist/client/chat-first/session-watch-pane.js +9 -0
- package/dist/client/chat-first/surface-panel.d.ts +9 -0
- package/dist/client/chat-first/surface-panel.js +9 -0
- package/dist/client/chat-first/surface-tabs.d.ts +9 -0
- package/dist/client/chat-first/surface-tabs.js +74 -0
- package/dist/client/chat-first/types.d.ts +74 -0
- package/dist/client/chat-first/types.js +1 -0
- package/dist/client/chat-first-agent-activity.d.ts +11 -0
- package/dist/client/chat-first-agent-activity.js +51 -0
- package/dist/client/chat-first-surface-panel-toggle.d.ts +5 -0
- package/dist/client/chat-first-surface-panel-toggle.js +6 -0
- package/dist/client/chat-first.d.ts +208 -0
- package/dist/client/chat-first.js +817 -0
- package/dist/client/extensions/ExtensionViewer.js +8 -1
- package/dist/client/i18n.d.ts +14 -0
- package/dist/client/i18n.js +18 -0
- package/dist/client/resources/McpIntegrationDialog.js +3 -2
- package/dist/client/resources/McpServerDetail.js +6 -11
- package/dist/client/resources/index.d.ts +1 -0
- package/dist/client/resources/index.js +1 -0
- package/dist/client/resources/use-mcp-servers.d.ts +20 -0
- package/dist/client/resources/use-mcp-servers.js +82 -46
- package/dist/client/settings/ProviderSetupForm.d.ts +21 -0
- package/dist/client/settings/ProviderSetupForm.js +145 -0
- package/dist/client/settings/SettingsPanel.js +52 -49
- package/dist/client/settings/index.d.ts +3 -0
- package/dist/client/settings/index.js +3 -0
- package/dist/coding-tools/run-code.d.ts +5 -0
- package/dist/coding-tools/run-code.js +196 -36
- package/dist/coding-tools/tool-orchestration.d.ts +10 -0
- package/dist/coding-tools/tool-orchestration.js +107 -0
- package/dist/collab/routes.d.ts +1 -1
- package/dist/collab/struct-routes.d.ts +1 -1
- package/dist/jobs/background-automation-runner.js +19 -2
- package/dist/jobs/frontmatter.d.ts +9 -0
- package/dist/jobs/frontmatter.js +16 -0
- package/dist/jobs/scheduler-health.d.ts +20 -0
- package/dist/jobs/scheduler-health.js +86 -1
- package/dist/jobs/scheduler.js +46 -9
- package/dist/jobs/tools.d.ts +1 -1
- package/dist/jobs/tools.js +2 -7
- package/dist/localization/default-messages.d.ts +20 -0
- package/dist/localization/default-messages.js +25 -5
- package/dist/mcp-client/routes.d.ts +3 -0
- package/dist/mcp-client/routes.js +14 -0
- package/dist/notifications/routes.d.ts +1 -1
- package/dist/observability/routes.d.ts +3 -3
- package/dist/onboarding/app-profile.js +1 -1
- package/dist/provider-api/actions/custom-provider-registration.d.ts +8 -8
- package/dist/provider-api/actions/provider-api.d.ts +11 -11
- package/dist/scripts/agent-engines/test-agent-engine.js +34 -10
- package/dist/secrets/routes.d.ts +6 -6
- package/dist/server/agent-chat/run-code-tools.d.ts +1 -1
- package/dist/server/agent-chat/run-code-tools.js +3 -1
- package/dist/server/agent-chat-plugin.js +6 -6
- package/dist/server/agent-engine-api-key-route.js +43 -12
- package/dist/server/agents-bundle.d.ts +2 -0
- package/dist/server/agents-bundle.js +32 -2
- package/dist/server/auth.js +21 -5
- package/dist/server/credential-provider.d.ts +8 -2
- package/dist/server/credential-provider.js +14 -9
- package/dist/server/design-token-utils.d.ts +18 -0
- package/dist/server/design-token-utils.js +31 -0
- package/dist/server/onboarding-html.js +22 -2
- package/dist/server/transcribe-voice.d.ts +1 -1
- package/dist/shared/chat-first-app-creation.d.ts +19 -0
- package/dist/shared/chat-first-app-creation.js +75 -0
- package/dist/shared/document-title.d.ts +7 -0
- package/dist/shared/document-title.js +29 -0
- package/dist/shared/index.d.ts +2 -0
- package/dist/shared/index.js +2 -0
- package/dist/styles/chat-history-list.css +16 -0
- package/dist/templates/chat/.agents/skills/adding-a-feature/SKILL.md +9 -0
- package/dist/templates/chat/.agents/skills/frontend-design/SKILL.md +115 -68
- package/dist/templates/chat/.agents/skills/turn-into-app/SKILL.md +18 -6
- package/dist/templates/chat/.agents/skills/turn-into-app/references/fresh-project.md +8 -1
- package/dist/templates/chat/app/i18n/index.ts +14 -29
- package/dist/templates/default/.agents/skills/adding-a-feature/SKILL.md +9 -0
- package/dist/templates/default/.agents/skills/frontend-design/SKILL.md +115 -68
- package/dist/templates/default/.agents/skills/turn-into-app/SKILL.md +18 -6
- package/dist/templates/default/.agents/skills/turn-into-app/references/fresh-project.md +8 -1
- package/dist/templates/default/app/i18n/index.ts +14 -29
- package/dist/templates/default/react-router.config.ts +18 -0
- package/dist/templates/headless/.agents/skills/turn-into-app/SKILL.md +18 -6
- package/dist/templates/headless/.agents/skills/turn-into-app/references/fresh-project.md +8 -1
- package/dist/templates/workspace-core/.agents/skills/adding-a-feature/SKILL.md +9 -0
- package/dist/templates/workspace-core/.agents/skills/address-feedback/SKILL.md +22 -9
- package/dist/templates/workspace-core/.agents/skills/frontend-design/SKILL.md +115 -68
- package/dist/templates/workspace-core/.agents/skills/turn-into-app/SKILL.md +18 -6
- package/dist/templates/workspace-core/.agents/skills/turn-into-app/references/fresh-project.md +8 -1
- package/dist/templates/workspace-core/.agents/skills/workspace-conventions/SKILL.md +7 -0
- package/dist/triggers/dispatcher.js +1 -8
- package/docs/content/environment-variables.mdx +39 -38
- package/package.json +5 -4
- package/src/templates/chat/.agents/skills/adding-a-feature/SKILL.md +9 -0
- package/src/templates/chat/.agents/skills/frontend-design/SKILL.md +115 -68
- package/src/templates/chat/.agents/skills/turn-into-app/SKILL.md +18 -6
- package/src/templates/chat/.agents/skills/turn-into-app/references/fresh-project.md +8 -1
- package/src/templates/chat/app/i18n/index.ts +14 -29
- package/src/templates/default/.agents/skills/adding-a-feature/SKILL.md +9 -0
- package/src/templates/default/.agents/skills/frontend-design/SKILL.md +115 -68
- package/src/templates/default/.agents/skills/turn-into-app/SKILL.md +18 -6
- package/src/templates/default/.agents/skills/turn-into-app/references/fresh-project.md +8 -1
- package/src/templates/default/app/i18n/index.ts +14 -29
- package/src/templates/default/react-router.config.ts +18 -0
- package/src/templates/headless/.agents/skills/turn-into-app/SKILL.md +18 -6
- package/src/templates/headless/.agents/skills/turn-into-app/references/fresh-project.md +8 -1
- package/src/templates/workspace-core/.agents/skills/adding-a-feature/SKILL.md +9 -0
- package/src/templates/workspace-core/.agents/skills/address-feedback/SKILL.md +22 -9
- package/src/templates/workspace-core/.agents/skills/frontend-design/SKILL.md +115 -68
- package/src/templates/workspace-core/.agents/skills/turn-into-app/SKILL.md +18 -6
- package/src/templates/workspace-core/.agents/skills/turn-into-app/references/fresh-project.md +8 -1
- package/src/templates/workspace-core/.agents/skills/workspace-conventions/SKILL.md +7 -0
- package/corpus/templates/plan/app/components/plan/wireframe/sanitize-html.ts +0 -343
|
@@ -75,14 +75,16 @@ export declare function resolveDelegatedRunModel(engine: ModelResolvableEngine,
|
|
|
75
75
|
* verbatim instead of normalized against the built-in catalog.
|
|
76
76
|
*
|
|
77
77
|
* `normalizeModelForEngine` honors a live engine's `preserveCustomModels`, but
|
|
78
|
-
* that flag is only set on an AI SDK engine INSTANCE when the
|
|
79
|
-
* is pointed at an OpenAI-compatible gateway (a custom
|
|
80
|
-
* Cloud or LiteLLM), whose model IDs are not in the
|
|
78
|
+
* that flag is only set on an AI SDK engine INSTANCE when the provider is
|
|
79
|
+
* Ollama, or when OpenAI is pointed at an OpenAI-compatible gateway (a custom
|
|
80
|
+
* base URL — e.g. Ollama Cloud or LiteLLM), whose model IDs are not in the
|
|
81
|
+
* built-in catalogs.
|
|
81
82
|
* The static registry entry the settings actions pass to
|
|
82
83
|
* `normalizeModelForEngine` cannot carry that runtime flag, so this async
|
|
83
|
-
* helper reproduces the same decision
|
|
84
|
-
*
|
|
85
|
-
* returns false so an unknown/invalid model
|
|
84
|
+
* helper reproduces the same decision from the request's stored/deploy config.
|
|
85
|
+
* Ollama always returns true because its local model inventory is user-defined;
|
|
86
|
+
* first-party OpenAI (no gateway) returns false so an unknown/invalid model
|
|
87
|
+
* still normalizes to a supported one.
|
|
86
88
|
*/
|
|
87
89
|
export declare function resolveEnginePreservesCustomModels(entry: Pick<AgentEngineEntry, "name">): Promise<boolean>;
|
|
88
90
|
/**
|
|
@@ -11,7 +11,8 @@ import { createRequire } from "node:module";
|
|
|
11
11
|
import { assertCredentialStoreReadable, canUseDeployCredentialFallbackForRequest, getBuilderCredentialAuthFailure, getProviderCredentialAuthFailure, readDeployCredentialEnv, resolveBuilderCredentialsDetailed, resolveSecret, } from "../../server/credential-provider.js";
|
|
12
12
|
import { getSetting } from "../../settings/store.js";
|
|
13
13
|
import { getAgentAppModelDefaultForCurrentRequest } from "../app-model-defaults.js";
|
|
14
|
-
import {
|
|
14
|
+
import { OLLAMA_BASE_URL_ENV_VAR, OPENAI_BASE_URL_ENV_VAR, } from "./openai-compatible-endpoint.js";
|
|
15
|
+
import { validateProviderBaseUrl } from "./provider-endpoint-validation.js";
|
|
15
16
|
const require = createRequire(import.meta.url);
|
|
16
17
|
const _registry = new Map();
|
|
17
18
|
const _packageAvailabilityCache = new Map();
|
|
@@ -234,20 +235,24 @@ export function resolveDelegatedRunModel(engine, options) {
|
|
|
234
235
|
* verbatim instead of normalized against the built-in catalog.
|
|
235
236
|
*
|
|
236
237
|
* `normalizeModelForEngine` honors a live engine's `preserveCustomModels`, but
|
|
237
|
-
* that flag is only set on an AI SDK engine INSTANCE when the
|
|
238
|
-
* is pointed at an OpenAI-compatible gateway (a custom
|
|
239
|
-
* Cloud or LiteLLM), whose model IDs are not in the
|
|
238
|
+
* that flag is only set on an AI SDK engine INSTANCE when the provider is
|
|
239
|
+
* Ollama, or when OpenAI is pointed at an OpenAI-compatible gateway (a custom
|
|
240
|
+
* base URL — e.g. Ollama Cloud or LiteLLM), whose model IDs are not in the
|
|
241
|
+
* built-in catalogs.
|
|
240
242
|
* The static registry entry the settings actions pass to
|
|
241
243
|
* `normalizeModelForEngine` cannot carry that runtime flag, so this async
|
|
242
|
-
* helper reproduces the same decision
|
|
243
|
-
*
|
|
244
|
-
* returns false so an unknown/invalid model
|
|
244
|
+
* helper reproduces the same decision from the request's stored/deploy config.
|
|
245
|
+
* Ollama always returns true because its local model inventory is user-defined;
|
|
246
|
+
* first-party OpenAI (no gateway) returns false so an unknown/invalid model
|
|
247
|
+
* still normalizes to a supported one.
|
|
245
248
|
*/
|
|
246
249
|
export async function resolveEnginePreservesCustomModels(entry) {
|
|
250
|
+
if (entry.name === "ai-sdk:ollama")
|
|
251
|
+
return true;
|
|
247
252
|
if (entry.name !== "ai-sdk:openai")
|
|
248
253
|
return false;
|
|
249
254
|
try {
|
|
250
|
-
return Boolean(await
|
|
255
|
+
return Boolean(await resolveProviderBaseUrl(OPENAI_BASE_URL_ENV_VAR));
|
|
251
256
|
}
|
|
252
257
|
catch {
|
|
253
258
|
return false;
|
|
@@ -493,19 +498,22 @@ function engineCreateConfig(entry, apiKey, extra) {
|
|
|
493
498
|
...(extra ?? {}),
|
|
494
499
|
};
|
|
495
500
|
}
|
|
496
|
-
async function
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
501
|
+
async function resolveProviderBaseUrl(envVar) {
|
|
502
|
+
const raw = await resolveSecret(envVar);
|
|
503
|
+
if (!raw && canUseDeployCredentialFallbackForRequest(envVar)) {
|
|
504
|
+
const deployValue = readDeployCredentialEnv(envVar);
|
|
505
|
+
if (!deployValue)
|
|
506
|
+
return undefined;
|
|
507
|
+
return validateProviderBaseUrl(deployValue, {
|
|
508
|
+
allowPrivate: true,
|
|
509
|
+
});
|
|
510
|
+
}
|
|
511
|
+
return raw
|
|
512
|
+
? validateProviderBaseUrl(raw, {
|
|
513
|
+
allowLocalOllama: envVar === OLLAMA_BASE_URL_ENV_VAR &&
|
|
514
|
+
process.env.NODE_ENV === "development",
|
|
515
|
+
})
|
|
516
|
+
: undefined;
|
|
509
517
|
}
|
|
510
518
|
/**
|
|
511
519
|
* A Builder connection we could not read is not a missing connection. Throwing
|
|
@@ -609,12 +617,17 @@ async function engineCreateConfigForEntry(entry, apiKey, extra, preferResolvedCr
|
|
|
609
617
|
: undefined;
|
|
610
618
|
}
|
|
611
619
|
}
|
|
612
|
-
if (entry.name === "ai-sdk:openai") {
|
|
620
|
+
if (entry.name === "ai-sdk:openai" || entry.name === "ai-sdk:ollama") {
|
|
613
621
|
if (typeof safeExtra.baseURL === "string" && safeExtra.baseUrl == null) {
|
|
614
|
-
safeExtra.baseUrl =
|
|
622
|
+
safeExtra.baseUrl = await validateProviderBaseUrl(safeExtra.baseURL, {
|
|
623
|
+
allowLocalOllama: entry.name === "ai-sdk:ollama" &&
|
|
624
|
+
process.env.NODE_ENV === "development",
|
|
625
|
+
});
|
|
615
626
|
}
|
|
616
627
|
if (safeExtra.baseUrl == null) {
|
|
617
|
-
const baseUrl = await
|
|
628
|
+
const baseUrl = await resolveProviderBaseUrl(entry.name === "ai-sdk:ollama"
|
|
629
|
+
? OLLAMA_BASE_URL_ENV_VAR
|
|
630
|
+
: OPENAI_BASE_URL_ENV_VAR);
|
|
618
631
|
if (baseUrl)
|
|
619
632
|
safeExtra.baseUrl = baseUrl;
|
|
620
633
|
}
|
|
@@ -23,6 +23,10 @@ export function createToolSearchEntry(getRegistry, options = {}) {
|
|
|
23
23
|
type: "boolean",
|
|
24
24
|
description: "When true, include each matching tool's full input schema. Default false.",
|
|
25
25
|
},
|
|
26
|
+
readOnlyOnly: {
|
|
27
|
+
type: "boolean",
|
|
28
|
+
description: "When true, return tools whose current policy is read-only or can classify the supplied arguments as read-only. The bounded orchestration host rechecks conditional policies before every call.",
|
|
29
|
+
},
|
|
26
30
|
},
|
|
27
31
|
},
|
|
28
32
|
},
|
|
@@ -44,11 +48,13 @@ export function searchToolRegistry(registry, args = {}, options = {}) {
|
|
|
44
48
|
// actually needs. A query switches to ranked search with parameter details.
|
|
45
49
|
const listAll = query.length === 0;
|
|
46
50
|
const includeSchemas = !listAll && parseBoolean(args.includeSchemas);
|
|
51
|
+
const readOnlyOnly = parseBoolean(args.readOnlyOnly);
|
|
47
52
|
const limit = parseLimit(args.limit, options.defaultLimit ?? DEFAULT_LIMIT, options.maxLimit ?? MAX_LIMIT);
|
|
48
53
|
const cacheKey = normalizeToolSearchCacheKey({
|
|
49
54
|
query,
|
|
50
55
|
limit,
|
|
51
56
|
includeSchemas,
|
|
57
|
+
readOnlyOnly,
|
|
52
58
|
});
|
|
53
59
|
const runCtx = getRequestRunContext();
|
|
54
60
|
const priorSearch = includeSchemas
|
|
@@ -83,13 +89,22 @@ export function searchToolRegistry(registry, args = {}, options = {}) {
|
|
|
83
89
|
if (name.startsWith("mcp__") && !isMcpToolAllowedForRequest(name)) {
|
|
84
90
|
continue;
|
|
85
91
|
}
|
|
86
|
-
totalTools++;
|
|
87
92
|
const description = normalizeWhitespace(entry.tool.description ?? "");
|
|
88
93
|
const parsedMcp = parseMcpToolName(name);
|
|
89
94
|
const kind = parsedMcp ? "mcp" : "action";
|
|
90
95
|
const source = parsedMcp?.serverId;
|
|
91
96
|
const callable = entry.allowInPlanMode !== false;
|
|
92
97
|
const planAvailability = getPlanAvailability(name, entry);
|
|
98
|
+
// Conditional policies still need discovery: MCP tools and provider/web
|
|
99
|
+
// actions classify the arguments at call time. Bash is marked conditional
|
|
100
|
+
// for Plan mode, but the orchestration bridge intentionally does not expose
|
|
101
|
+
// shell execution, so do not advertise it as a child-call candidate.
|
|
102
|
+
if (readOnlyOnly &&
|
|
103
|
+
planAvailability !== "read" &&
|
|
104
|
+
(planAvailability !== "conditional" || name === "bash")) {
|
|
105
|
+
continue;
|
|
106
|
+
}
|
|
107
|
+
totalTools++;
|
|
93
108
|
if (listAll) {
|
|
94
109
|
candidates.push({
|
|
95
110
|
name,
|
|
@@ -181,6 +196,7 @@ function normalizeToolSearchCacheKey(options) {
|
|
|
181
196
|
query: options.query.trim().toLowerCase(),
|
|
182
197
|
limit: options.limit,
|
|
183
198
|
includeSchemas: options.includeSchemas,
|
|
199
|
+
readOnlyOnly: options.readOnlyOnly,
|
|
184
200
|
});
|
|
185
201
|
}
|
|
186
202
|
function rememberToolSearchResult(cacheKey, result) {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { getDbExec } from "../db/client.js";
|
|
2
2
|
import { isValidCron, isValidTimezone, nextOccurrence } from "../jobs/cron.js";
|
|
3
|
-
import { buildJobResourceContent, normalizeJobMcpTools, parseJobResource, } from "../jobs/frontmatter.js";
|
|
3
|
+
import { buildJobResourceContent, jobBelongsToApp, normalizeJobMcpTools, parseJobResource, } from "../jobs/frontmatter.js";
|
|
4
4
|
import { deleteAutomationRuns } from "../jobs/run-history.js";
|
|
5
5
|
import { resolveUserSchedulingTimezone } from "../localization/user-timezone.js";
|
|
6
6
|
import { organizationIdFromResourceOwner, organizationResourceOwner, resourceDelete, resourceGetByPath, resourceList, resourcePut, } from "../resources/store.js";
|
|
@@ -60,12 +60,6 @@ async function requireOrganizationMembership(actor) {
|
|
|
60
60
|
function isOrganizationAdmin(membership) {
|
|
61
61
|
return membership.role === "owner" || membership.role === "admin";
|
|
62
62
|
}
|
|
63
|
-
function automationBelongsToApp(meta, appId) {
|
|
64
|
-
const ownerAppId = meta.appId?.trim();
|
|
65
|
-
if (!ownerAppId || !appId?.trim())
|
|
66
|
-
return true;
|
|
67
|
-
return ownerAppId === appId.trim();
|
|
68
|
-
}
|
|
69
63
|
async function mutationAccess(actorInput, resource, meta) {
|
|
70
64
|
const actor = normalizeActor(actorInput);
|
|
71
65
|
const resourceOrgId = organizationIdFromResourceOwner(resource.owner);
|
|
@@ -94,7 +88,7 @@ async function mutationAccess(actorInput, resource, meta) {
|
|
|
94
88
|
export async function canUpdateAutomationResource(actorInput, resource) {
|
|
95
89
|
const { meta } = parseJobResource(resource.content);
|
|
96
90
|
const actor = normalizeActor(actorInput);
|
|
97
|
-
if (!
|
|
91
|
+
if (!jobBelongsToApp(meta, actor.appId))
|
|
98
92
|
return false;
|
|
99
93
|
return (await mutationAccess(actor, resource, meta)).canUpdate;
|
|
100
94
|
}
|
|
@@ -124,7 +118,7 @@ async function readDefinition(actorInput, scope, name) {
|
|
|
124
118
|
throw httpError(`Automation "${automationName(path)}" not found.`, 404);
|
|
125
119
|
}
|
|
126
120
|
const definition = assertExplicitAutomation(resource);
|
|
127
|
-
if (!
|
|
121
|
+
if (!jobBelongsToApp(definition.meta, actor.appId)) {
|
|
128
122
|
throw httpError(`Automation "${automationName(path)}" not found.`, 404);
|
|
129
123
|
}
|
|
130
124
|
const access = await mutationAccess(actor, resource, definition.meta);
|
|
@@ -154,7 +148,7 @@ export async function listAutomationDefinitions(actorInput, scope) {
|
|
|
154
148
|
const parsed = parseJobResource(resource.content);
|
|
155
149
|
if (parsed.classification.kind !== "automation")
|
|
156
150
|
continue;
|
|
157
|
-
if (!
|
|
151
|
+
if (!jobBelongsToApp(parsed.meta, actor.appId))
|
|
158
152
|
continue;
|
|
159
153
|
const isCreator = parsed.meta.createdBy?.trim().toLowerCase() === actor.userEmail;
|
|
160
154
|
automations.push({
|
|
@@ -7,6 +7,19 @@
|
|
|
7
7
|
* thin action wrapper.
|
|
8
8
|
*/
|
|
9
9
|
import type { BrandWebsiteSignals } from "./types.js";
|
|
10
|
+
export interface BrandAnalysisResult {
|
|
11
|
+
companyName?: string;
|
|
12
|
+
brandNotes?: string;
|
|
13
|
+
existingDesignSystem?: unknown;
|
|
14
|
+
websiteAnalysis?: unknown;
|
|
15
|
+
}
|
|
16
|
+
/** Assemble brand-analysis data without performing template or network work. */
|
|
17
|
+
export declare function buildBrandAnalysisResult(input: {
|
|
18
|
+
companyName?: string;
|
|
19
|
+
brandNotes?: string;
|
|
20
|
+
existingDesignSystem?: unknown;
|
|
21
|
+
websiteAnalysis?: unknown;
|
|
22
|
+
}): BrandAnalysisResult;
|
|
10
23
|
/**
|
|
11
24
|
* Normalize a user-supplied brand website URL: add an `https://` scheme when
|
|
12
25
|
* missing and reject anything that isn't http(s). Throws on empty input or an
|
|
@@ -7,6 +7,21 @@
|
|
|
7
7
|
* thin action wrapper.
|
|
8
8
|
*/
|
|
9
9
|
import { ssrfSafeFetch } from "../extensions/url-safety.js";
|
|
10
|
+
/** Assemble brand-analysis data without performing template or network work. */
|
|
11
|
+
export function buildBrandAnalysisResult(input) {
|
|
12
|
+
const result = {};
|
|
13
|
+
if (input.companyName)
|
|
14
|
+
result.companyName = input.companyName;
|
|
15
|
+
if (input.brandNotes)
|
|
16
|
+
result.brandNotes = input.brandNotes;
|
|
17
|
+
if (input.existingDesignSystem !== undefined) {
|
|
18
|
+
result.existingDesignSystem = input.existingDesignSystem;
|
|
19
|
+
}
|
|
20
|
+
if (input.websiteAnalysis !== undefined) {
|
|
21
|
+
result.websiteAnalysis = input.websiteAnalysis;
|
|
22
|
+
}
|
|
23
|
+
return result;
|
|
24
|
+
}
|
|
10
25
|
/**
|
|
11
26
|
* Normalize a user-supplied brand website URL: add an `https://` scheme when
|
|
12
27
|
* missing and reject anything that isn't http(s). Throws on empty input or an
|
|
@@ -17,5 +17,5 @@
|
|
|
17
17
|
export * from "./types.js";
|
|
18
18
|
export * from "./brand-signals.js";
|
|
19
19
|
export * from "./tokens.js";
|
|
20
|
-
export { extractDesignTokensFromUrl, validateUrl, parseOwnerRepo, fetchGitHubJson, fetchGitHubJsonResult, fetchGitHubRaw, parseTailwindConfig, parseCss, detectStylingFramework, createCodeAnalysisState, analyzeCodeFile, analyzeCssFile, analyzeTailwindConfig, analyzeJsonTheme, analyzePackageJson, analyzeThemeSourceFile, addFont, extractCssVars, extractCodeColors, extractCodeFonts, extractDocumentColors, extractDocumentFonts, classifyFile, suggestionsForType, unique, MAX_FILES, MAX_FILE_SIZE, FETCH_TIMEOUT, ROOT_PATTERNS, SECONDARY_PATHS, CODE_MAX_FILES, CODE_MAX_TOTAL_BYTES, } from "../server/design-token-utils.js";
|
|
21
|
-
export type { ContentType, ParsedCss, ParsedTailwindConfig, CodeAnalysisState, UrlExtractionResult, GitHubFetchOptions, GitHubJsonResult, } from "../server/design-token-utils.js";
|
|
20
|
+
export { extractDesignTokensFromUrl, validateUrl, parseOwnerRepo, fetchGitHubJson, fetchGitHubJsonResult, fetchGitHubRaw, parseTailwindConfig, parseCss, detectStylingFramework, createCodeAnalysisState, analyzeCodeFile, analyzeCodeFiles, analyzeCssFile, analyzeTailwindConfig, analyzeJsonTheme, analyzePackageJson, analyzeThemeSourceFile, addFont, extractCssVars, extractCodeColors, extractCodeFonts, extractDocumentColors, extractDocumentFonts, classifyFile, suggestionsForType, unique, MAX_FILES, MAX_FILE_SIZE, FETCH_TIMEOUT, ROOT_PATTERNS, SECONDARY_PATHS, CODE_MAX_FILES, CODE_MAX_TOTAL_BYTES, } from "../server/design-token-utils.js";
|
|
21
|
+
export type { ContentType, ParsedCss, ParsedTailwindConfig, CodeAnalysisState, CodeAnalysisFile, CodeAnalysisResult, UrlExtractionResult, GitHubFetchOptions, GitHubJsonResult, } from "../server/design-token-utils.js";
|
package/dist/brand-kit/index.js
CHANGED
|
@@ -27,7 +27,7 @@ parseOwnerRepo, fetchGitHubJson, fetchGitHubJsonResult, fetchGitHubRaw,
|
|
|
27
27
|
// Tailwind / CSS parsing
|
|
28
28
|
parseTailwindConfig, parseCss, detectStylingFramework,
|
|
29
29
|
// Code-file analysis
|
|
30
|
-
createCodeAnalysisState, analyzeCodeFile, analyzeCssFile, analyzeTailwindConfig, analyzeJsonTheme, analyzePackageJson, analyzeThemeSourceFile, addFont, extractCssVars, extractCodeColors, extractCodeFonts,
|
|
30
|
+
createCodeAnalysisState, analyzeCodeFile, analyzeCodeFiles, analyzeCssFile, analyzeTailwindConfig, analyzeJsonTheme, analyzePackageJson, analyzeThemeSourceFile, addFont, extractCssVars, extractCodeColors, extractCodeFonts,
|
|
31
31
|
// Document analysis
|
|
32
32
|
extractDocumentColors, extractDocumentFonts, classifyFile, suggestionsForType, unique,
|
|
33
33
|
// Constants
|
|
@@ -73,6 +73,8 @@ export declare function createThread(ownerEmail: string, opts?: {
|
|
|
73
73
|
title?: string;
|
|
74
74
|
scope?: ChatThreadScope | null;
|
|
75
75
|
source?: ChatThreadSource | null;
|
|
76
|
+
/** Explicit owner organization for durable/background callers. */
|
|
77
|
+
orgId?: string | null;
|
|
76
78
|
}): Promise<ChatThread>;
|
|
77
79
|
export declare function registerChatThreadsShareable(): void;
|
|
78
80
|
export declare function ensureChatThreadTables(): Promise<void>;
|
|
@@ -367,7 +367,7 @@ export async function createThread(ownerEmail, opts) {
|
|
|
367
367
|
const title = opts?.title ?? "";
|
|
368
368
|
const scope = opts?.scope ?? null;
|
|
369
369
|
const source = opts?.source ?? null;
|
|
370
|
-
const orgId = getRequestOrgId() ?? null;
|
|
370
|
+
const orgId = opts?.orgId ?? getRequestOrgId() ?? null;
|
|
371
371
|
await client.execute({
|
|
372
372
|
sql: `INSERT INTO chat_threads (id, owner_email, title, preview, thread_data, message_count, created_at, updated_at, scope_type, scope_id, scope_label, source_platform, source_app_id, source_url, org_id, visibility) VALUES (?, ?, ?, '', '{}', 0, ?, ?, ?, ?, ?, ?, ?, ?, ?, 'private')`,
|
|
373
373
|
args: [
|
|
@@ -2,8 +2,9 @@
|
|
|
2
2
|
* Import and validate the portable Agent Plugin format.
|
|
3
3
|
*
|
|
4
4
|
* The importer intentionally handles only local plugin directories. Skills are
|
|
5
|
-
* copied as inert files
|
|
6
|
-
*
|
|
5
|
+
* copied as inert files into the workspace's agent-visible `.agents/skills`
|
|
6
|
+
* tree, and remote Streamable HTTP MCP entries are translated to the
|
|
7
|
+
* Agent-Native `mcp.config.json` shape without copying package headers.
|
|
7
8
|
* A plugin package is not a credential store and this command never executes
|
|
8
9
|
* a plugin's scripts or stdio servers.
|
|
9
10
|
*/
|
|
@@ -62,6 +63,8 @@ export interface LoadedAgentPlugin {
|
|
|
62
63
|
}
|
|
63
64
|
export interface AgentPluginImportOptions {
|
|
64
65
|
targetDir?: string;
|
|
66
|
+
/** Optional skills root used by hosts whose agent cwd is a child workspace. */
|
|
67
|
+
skillsTargetDir?: string;
|
|
65
68
|
force?: boolean;
|
|
66
69
|
dryRun?: boolean;
|
|
67
70
|
}
|
package/dist/cli/agent-plugin.js
CHANGED
|
@@ -2,8 +2,9 @@
|
|
|
2
2
|
* Import and validate the portable Agent Plugin format.
|
|
3
3
|
*
|
|
4
4
|
* The importer intentionally handles only local plugin directories. Skills are
|
|
5
|
-
* copied as inert files
|
|
6
|
-
*
|
|
5
|
+
* copied as inert files into the workspace's agent-visible `.agents/skills`
|
|
6
|
+
* tree, and remote Streamable HTTP MCP entries are translated to the
|
|
7
|
+
* Agent-Native `mcp.config.json` shape without copying package headers.
|
|
7
8
|
* A plugin package is not a credential store and this command never executes
|
|
8
9
|
* a plugin's scripts or stdio servers.
|
|
9
10
|
*/
|
|
@@ -42,7 +43,7 @@ Usage:
|
|
|
42
43
|
Commands:
|
|
43
44
|
import Import a standard Agent Plugin's Skills and remote MCP servers into an Agent-Native workspace.
|
|
44
45
|
|
|
45
|
-
The importer copies Skills into a namespaced skills/<plugin>/<skill> path and
|
|
46
|
+
The importer copies Skills into a namespaced .agents/skills/<plugin>/<skill> path and
|
|
46
47
|
maps Streamable HTTP MCP servers into mcp.config.json. Package headers are
|
|
47
48
|
never imported as credentials; configure authentication through the app's
|
|
48
49
|
normal Connections flow. Stdio and SSE servers are reported and skipped.`;
|
|
@@ -691,10 +692,10 @@ function planMcpServers(plugin, existing, force) {
|
|
|
691
692
|
}
|
|
692
693
|
return planned;
|
|
693
694
|
}
|
|
694
|
-
function planSkills(plugin,
|
|
695
|
+
function planSkills(plugin, skillsRoot, force) {
|
|
695
696
|
return plugin.skills.map((skill) => {
|
|
696
|
-
const destination = path.join(
|
|
697
|
-
assertPathInside(
|
|
697
|
+
const destination = path.join(skillsRoot, skill.name);
|
|
698
|
+
assertPathInside(skillsRoot, destination, "Imported skill destination");
|
|
698
699
|
assertPathOutside(plugin.rootDir, destination, "Imported skill destination");
|
|
699
700
|
assertNoSymlinkInExistingPath(path.dirname(destination), "Imported skill destination");
|
|
700
701
|
if (!pathExists(destination)) {
|
|
@@ -878,12 +879,19 @@ export function importAgentPlugin(input, options = {}) {
|
|
|
878
879
|
}
|
|
879
880
|
assertNoSymlinkInExistingPath(targetDir, "Agent-Native import target");
|
|
880
881
|
const slug = pluginSlug(plugin.manifest.name);
|
|
881
|
-
const
|
|
882
|
+
const skillsTargetDir = canonicalPathForComparison(options.skillsTargetDir ?? path.join(targetDir, ".agents", "skills"));
|
|
883
|
+
if (pathExists(skillsTargetDir) &&
|
|
884
|
+
!fs.statSync(skillsTargetDir).isDirectory()) {
|
|
885
|
+
throw new Error(`Agent-Native skills target must be a directory: ${skillsTargetDir}`);
|
|
886
|
+
}
|
|
887
|
+
assertPathOutside(plugin.rootDir, skillsTargetDir, "Imported skills target");
|
|
888
|
+
assertNoSymlinkInExistingPath(skillsTargetDir, "Imported skills target");
|
|
889
|
+
const skillsRoot = path.join(skillsTargetDir, slug);
|
|
882
890
|
const metadataFile = path.join(targetDir, ".agent-native", "plugins", `${slug}.json`);
|
|
883
891
|
const mcpFile = path.join(targetDir, "mcp.config.json");
|
|
884
|
-
assertPathInside(targetDir, skillsRoot, "Imported skills root");
|
|
885
892
|
assertPathInside(targetDir, metadataFile, "Imported metadata path");
|
|
886
893
|
assertPathInside(targetDir, mcpFile, "Imported MCP config path");
|
|
894
|
+
assertPathInside(skillsTargetDir, skillsRoot, "Imported skills root");
|
|
887
895
|
assertPathOutside(plugin.rootDir, skillsRoot, "Imported skills root");
|
|
888
896
|
assertPathOutside(plugin.rootDir, metadataFile, "Imported metadata path");
|
|
889
897
|
assertPathOutside(plugin.rootDir, mcpFile, "Imported MCP config path");
|
|
@@ -892,7 +900,7 @@ export function importAgentPlugin(input, options = {}) {
|
|
|
892
900
|
const force = options.force ?? false;
|
|
893
901
|
const dryRun = options.dryRun ?? false;
|
|
894
902
|
const existingMcp = readExistingMcpConfig(mcpFile);
|
|
895
|
-
const skillPlans = planSkills(plugin,
|
|
903
|
+
const skillPlans = planSkills(plugin, skillsRoot, force);
|
|
896
904
|
const mcpPlans = planMcpServers(plugin, existingMcp, force);
|
|
897
905
|
const existingMetadata = readExistingMetadata(metadataFile);
|
|
898
906
|
const metadataIsSame = metadataMatches(existingMetadata, plugin);
|
|
@@ -14,6 +14,7 @@ import { readAgentsBundleFromFs, generateDevelopmentSkillsPromptBlock, } from ".
|
|
|
14
14
|
import { getAmbientOrgId, getAmbientUserEmail, runWithRequestContext, } from "../server/request-context.js";
|
|
15
15
|
import { isReasoningEffort, } from "../shared/reasoning-effort.js";
|
|
16
16
|
import { createAgentNativeConfigContext, loadResolvedAgentNativeConfig, } from "../vite/agent-native-config-loader.js";
|
|
17
|
+
import { codexMcpConfigArgs, mergeCodeAgentMcpConfig, restrictCodeAgentMcpConfig, } from "./code-agent-mcp-config.js";
|
|
17
18
|
import { createCodeAgentOutputSmoother } from "./code-agent-output-smoother.js";
|
|
18
19
|
import { addCodeAgentCommandToAllowlist, appendCodeAgentTranscriptEvent, dequeueCodeAgentFollowUp, getCodeAgentRunRecord, isCodeAgentCommandAllowed, listCodeAgentTranscriptEvents, updateCodeAgentRunRecord, } from "./code-agent-runs.js";
|
|
19
20
|
const DEFAULT_COMMAND_TIMEOUT_MS = 120_000;
|
|
@@ -443,20 +444,26 @@ async function executeCodexCliRun(options) {
|
|
|
443
444
|
const model = normalizeCodexCliModel(options.model);
|
|
444
445
|
const streamToolOutputToStdout = options.streamToolOutputToStdout ??
|
|
445
446
|
process.env.AGENT_NATIVE_CODE_AGENT_STRUCTURED_STDOUT !== "1";
|
|
447
|
+
const additionalSkillsRoot = process.env.AGENT_NATIVE_CODE_AGENT_SKILLS_ROOT?.trim();
|
|
446
448
|
const args = [
|
|
449
|
+
...codexMcpConfigArgs(),
|
|
447
450
|
"--ask-for-approval",
|
|
448
451
|
"never",
|
|
449
|
-
"
|
|
452
|
+
"--sandbox",
|
|
453
|
+
codexSandboxForPermissionMode(options.permissionMode),
|
|
450
454
|
"--cd",
|
|
451
455
|
cwd,
|
|
456
|
+
"exec",
|
|
452
457
|
"--color",
|
|
453
458
|
"never",
|
|
454
459
|
"--skip-git-repo-check",
|
|
455
|
-
"--
|
|
456
|
-
codexSandboxForPermissionMode(options.permissionMode),
|
|
460
|
+
"--ignore-user-config",
|
|
457
461
|
"--output-last-message",
|
|
458
462
|
outputPath,
|
|
459
463
|
];
|
|
464
|
+
if (additionalSkillsRoot && fs.existsSync(additionalSkillsRoot)) {
|
|
465
|
+
args.splice(args.indexOf("--output-last-message"), 0, "--add-dir", additionalSkillsRoot);
|
|
466
|
+
}
|
|
460
467
|
if (model)
|
|
461
468
|
args.push("--model", model);
|
|
462
469
|
args.push("-");
|
|
@@ -663,9 +670,15 @@ function buildCodexCliPrompt(run, prompt) {
|
|
|
663
670
|
const modeInstruction = mode === "Plan"
|
|
664
671
|
? "Inspect and explain only. Do not edit files or run mutating commands."
|
|
665
672
|
: "Edit and verify as needed. Do not create, switch, reset, rebase, or stash git branches.";
|
|
673
|
+
const additionalSkillsRoot = process.env.AGENT_NATIVE_CODE_AGENT_SKILLS_ROOT?.trim();
|
|
666
674
|
return [
|
|
667
675
|
`You are running from Agent-Native Code in ${run.cwd || process.cwd()}.`,
|
|
668
676
|
"Follow the repository AGENTS.md and any relevant skill instructions.",
|
|
677
|
+
...(additionalSkillsRoot
|
|
678
|
+
? [
|
|
679
|
+
`Additional installed Agent Plugin skills are available under ${additionalSkillsRoot}. Read any relevant SKILL.md files before acting.`,
|
|
680
|
+
]
|
|
681
|
+
: []),
|
|
669
682
|
`Run mode: ${mode} (${permissionMode}). ${modeInstruction}`,
|
|
670
683
|
"",
|
|
671
684
|
"# User request",
|
|
@@ -933,9 +946,12 @@ async function startCodeAgentMcpManager(runId) {
|
|
|
933
946
|
});
|
|
934
947
|
return null;
|
|
935
948
|
});
|
|
936
|
-
|
|
949
|
+
const effectiveConfig = restrictCodeAgentMcpConfig(mergeCodeAgentMcpConfig(config));
|
|
950
|
+
if (!effectiveConfig ||
|
|
951
|
+
Object.keys(effectiveConfig.servers ?? {}).length === 0) {
|
|
937
952
|
return null;
|
|
938
|
-
|
|
953
|
+
}
|
|
954
|
+
const manager = new McpClientManager(effectiveConfig);
|
|
939
955
|
await manager.start().catch((err) => {
|
|
940
956
|
const message = err instanceof Error ? err.message : String(err);
|
|
941
957
|
appendCodeAgentTranscriptEvent({
|
|
@@ -1299,6 +1315,10 @@ export async function buildCodeAgentSystemPrompt(cwd, permissionMode) {
|
|
|
1299
1315
|
const appConfig = await loadResolvedAgentNativeConfig(cwd, createAgentNativeConfigContext("serve", "development"));
|
|
1300
1316
|
const bundle = readAgentsBundleFromFs(cwd, null, {
|
|
1301
1317
|
instructions: appConfig.instructions,
|
|
1318
|
+
additionalSkillDirs: (process.env.AGENT_NATIVE_CODE_AGENT_SKILLS_ROOT ?? "")
|
|
1319
|
+
.split(path.delimiter)
|
|
1320
|
+
.map((value) => value.trim())
|
|
1321
|
+
.filter(Boolean),
|
|
1302
1322
|
});
|
|
1303
1323
|
// If the bundle has no AGENTS.md, try CLAUDE.md as a fallback — many repos
|
|
1304
1324
|
// use that name for agent instructions (e.g. Claude Code projects).
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { McpConfig } from "../mcp-client/config.js";
|
|
2
|
+
/**
|
|
3
|
+
* Keep a desktop coding run on the app registry's MCP servers. The normal
|
|
4
|
+
* server-side manager merges persisted MCP settings for web requests, but a
|
|
5
|
+
* local shell must not inherit arbitrary user MCP servers when the desktop
|
|
6
|
+
* host has supplied an explicit workspace allowlist.
|
|
7
|
+
*/
|
|
8
|
+
export declare function restrictCodeAgentMcpConfig(config: McpConfig | null, environment?: NodeJS.ProcessEnv): McpConfig | null;
|
|
9
|
+
/**
|
|
10
|
+
* Add host-provided app/plugin servers to the normal merged config. The
|
|
11
|
+
* filesystem and environment layers have different precedence rules, so the
|
|
12
|
+
* child process combines them explicitly instead of silently dropping one.
|
|
13
|
+
*/
|
|
14
|
+
export declare function mergeCodeAgentMcpConfig(config: McpConfig | null, environment?: NodeJS.ProcessEnv): McpConfig | null;
|
|
15
|
+
/**
|
|
16
|
+
* Convert the host-scoped HTTP MCP config into Codex CLI's `-c` overrides.
|
|
17
|
+
* The caller adds `--ignore-user-config` in the `exec` segment so a local
|
|
18
|
+
* coding session receives the workspace apps, not the user's global MCP
|
|
19
|
+
* catalog.
|
|
20
|
+
*/
|
|
21
|
+
export declare function codexMcpConfigArgs(environment?: NodeJS.ProcessEnv): string[];
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
const DESKTOP_MCP_ALLOWLIST_ENV = "AGENT_NATIVE_CODE_AGENT_MCP_SERVER_ALLOWLIST";
|
|
2
|
+
function parseServerAllowlist(raw) {
|
|
3
|
+
if (raw === undefined)
|
|
4
|
+
return null;
|
|
5
|
+
return new Set(raw
|
|
6
|
+
.split(",")
|
|
7
|
+
.map((value) => value.trim())
|
|
8
|
+
.filter(Boolean));
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Keep a desktop coding run on the app registry's MCP servers. The normal
|
|
12
|
+
* server-side manager merges persisted MCP settings for web requests, but a
|
|
13
|
+
* local shell must not inherit arbitrary user MCP servers when the desktop
|
|
14
|
+
* host has supplied an explicit workspace allowlist.
|
|
15
|
+
*/
|
|
16
|
+
export function restrictCodeAgentMcpConfig(config, environment = process.env) {
|
|
17
|
+
const allowlist = parseServerAllowlist(environment[DESKTOP_MCP_ALLOWLIST_ENV]);
|
|
18
|
+
if (!allowlist || !config)
|
|
19
|
+
return config;
|
|
20
|
+
const servers = Object.fromEntries(Object.entries(config.servers).filter(([id]) => allowlist.has(id)));
|
|
21
|
+
return { ...config, servers };
|
|
22
|
+
}
|
|
23
|
+
function codexConfigKey(serverId) {
|
|
24
|
+
const normalized = serverId.replace(/[^A-Za-z0-9_-]/g, "_");
|
|
25
|
+
return normalized || "workspace";
|
|
26
|
+
}
|
|
27
|
+
function tomlString(value) {
|
|
28
|
+
return JSON.stringify(value);
|
|
29
|
+
}
|
|
30
|
+
function tomlInlineTable(headers) {
|
|
31
|
+
return `{${Object.entries(headers)
|
|
32
|
+
.map(([key, value]) => `${tomlString(key)}=${tomlString(value)}`)
|
|
33
|
+
.join(",")}}`;
|
|
34
|
+
}
|
|
35
|
+
function parseMcpServers(environment) {
|
|
36
|
+
const raw = environment.MCP_SERVERS?.trim();
|
|
37
|
+
if (!raw)
|
|
38
|
+
return {};
|
|
39
|
+
let parsed;
|
|
40
|
+
try {
|
|
41
|
+
parsed = JSON.parse(raw);
|
|
42
|
+
}
|
|
43
|
+
catch {
|
|
44
|
+
throw new Error("MCP_SERVERS is not valid JSON.");
|
|
45
|
+
}
|
|
46
|
+
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
47
|
+
throw new Error("MCP_SERVERS must contain a servers object.");
|
|
48
|
+
}
|
|
49
|
+
const serverMap = "servers" in parsed &&
|
|
50
|
+
parsed.servers &&
|
|
51
|
+
typeof parsed.servers === "object" &&
|
|
52
|
+
!Array.isArray(parsed.servers)
|
|
53
|
+
? parsed.servers
|
|
54
|
+
: parsed;
|
|
55
|
+
return Object.fromEntries(Object.entries(serverMap).map(([id, value]) => {
|
|
56
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
57
|
+
throw new Error(`MCP_SERVERS entry ${id} is invalid.`);
|
|
58
|
+
}
|
|
59
|
+
return [id, value];
|
|
60
|
+
}));
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Add host-provided app/plugin servers to the normal merged config. The
|
|
64
|
+
* filesystem and environment layers have different precedence rules, so the
|
|
65
|
+
* child process combines them explicitly instead of silently dropping one.
|
|
66
|
+
*/
|
|
67
|
+
export function mergeCodeAgentMcpConfig(config, environment = process.env) {
|
|
68
|
+
const environmentServers = parseMcpServers(environment);
|
|
69
|
+
if (Object.keys(environmentServers).length === 0)
|
|
70
|
+
return config;
|
|
71
|
+
return {
|
|
72
|
+
...(config ?? { servers: {} }),
|
|
73
|
+
servers: {
|
|
74
|
+
...(config?.servers ?? {}),
|
|
75
|
+
...environmentServers,
|
|
76
|
+
},
|
|
77
|
+
source: config?.source
|
|
78
|
+
? `${config.source}+desktop-environment`
|
|
79
|
+
: "env:MCP_SERVERS",
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Convert the host-scoped HTTP MCP config into Codex CLI's `-c` overrides.
|
|
84
|
+
* The caller adds `--ignore-user-config` in the `exec` segment so a local
|
|
85
|
+
* coding session receives the workspace apps, not the user's global MCP
|
|
86
|
+
* catalog.
|
|
87
|
+
*/
|
|
88
|
+
export function codexMcpConfigArgs(environment = process.env) {
|
|
89
|
+
const servers = parseMcpServers(environment);
|
|
90
|
+
if (Object.keys(servers).length === 0)
|
|
91
|
+
return [];
|
|
92
|
+
const args = [];
|
|
93
|
+
for (const [serverId, server] of Object.entries(servers)) {
|
|
94
|
+
if (server.type !== "http" || !server.url)
|
|
95
|
+
continue;
|
|
96
|
+
const key = codexConfigKey(serverId);
|
|
97
|
+
args.push("-c", `mcp_servers.${tomlString(key)}.url=${tomlString(server.url)}`);
|
|
98
|
+
if (server.headers && Object.keys(server.headers).length > 0) {
|
|
99
|
+
args.push("-c", `mcp_servers.${tomlString(key)}.http_headers=${tomlInlineTable(server.headers)}`);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
return args;
|
|
103
|
+
}
|
|
@@ -1,18 +1,3 @@
|
|
|
1
|
-
export
|
|
2
|
-
export
|
|
3
|
-
export type FetchPlanBlockCatalogInput
|
|
4
|
-
appUrl?: string;
|
|
5
|
-
out?: string;
|
|
6
|
-
format?: PlanBlockFormat;
|
|
7
|
-
fetchFn?: typeof fetch;
|
|
8
|
-
};
|
|
9
|
-
export type FetchPlanBlockCatalogResult = {
|
|
10
|
-
ok: true;
|
|
11
|
-
out: string;
|
|
12
|
-
count?: number;
|
|
13
|
-
format: PlanBlockFormat;
|
|
14
|
-
};
|
|
15
|
-
export declare function planActionEndpoint(appUrl: string, action: string): string;
|
|
16
|
-
export declare function normalizePlanBlockFormat(value: string | undefined): PlanBlockFormat;
|
|
17
|
-
export declare function defaultPlanBlocksOut(format: PlanBlockFormat): string;
|
|
18
|
-
export declare function fetchPlanBlockCatalog(input: FetchPlanBlockCatalogInput): Promise<FetchPlanBlockCatalogResult>;
|
|
1
|
+
/** Compatibility re-export for the canonical recap CLI implementation. */
|
|
2
|
+
export { DEFAULT_PLAN_APP_URL, defaultPlanBlocksOut, fetchPlanBlockCatalog, normalizePlanBlockFormat, planActionEndpoint, } from "@agent-native/recap-cli";
|
|
3
|
+
export type { FetchPlanBlockCatalogInput, FetchPlanBlockCatalogResult, PlanBlockFormat, } from "@agent-native/recap-cli";
|