@agent-native/core 0.128.4 → 0.129.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 +84 -0
- package/corpus/core/docs/content/template-design-collaboration-and-full-apps.mdx +3 -1
- package/corpus/core/package.json +6 -3
- package/corpus/core/src/a2a/client.ts +18 -4
- package/corpus/core/src/a2a/server.ts +19 -3
- package/corpus/core/src/a2a/types.ts +7 -0
- package/corpus/core/src/action.ts +43 -16
- package/corpus/core/src/agent/engine/ai-sdk-engine.ts +14 -10
- package/corpus/core/src/agent/production-agent.ts +41 -3
- package/corpus/core/src/agent/thread-data-builder.ts +5 -0
- package/corpus/core/src/chat-threads/migrations.ts +53 -0
- package/corpus/core/src/cli/create.ts +4 -0
- package/corpus/core/src/cli/skills-content/design-visual-edit-skill.ts +36 -16
- package/corpus/core/src/cli/skills.ts +16 -0
- package/corpus/core/src/client/AgentPanel.tsx +9 -5
- package/corpus/core/src/client/AssistantChat.tsx +138 -46
- package/corpus/core/src/client/MultiTabAssistantChat.tsx +16 -10
- package/corpus/core/src/client/agent-chat-adapter.ts +21 -3
- package/corpus/core/src/client/analytics.ts +159 -102
- package/corpus/core/src/client/chat/message-components.tsx +12 -5
- package/corpus/core/src/client/chat/runtime.ts +2 -1
- package/corpus/core/src/client/chat/tool-call-display.tsx +25 -2
- package/corpus/core/src/client/chat-model-groups.ts +3 -0
- package/corpus/core/src/client/client-status-requests.ts +161 -0
- package/corpus/core/src/client/settings/VoiceTranscriptionSection.tsx +2 -2
- package/corpus/core/src/client/sse-event-processor.ts +15 -3
- package/corpus/core/src/client/use-agent-engine-configured.ts +54 -50
- package/corpus/core/src/client/use-chat-models.ts +16 -11
- package/corpus/core/src/client/use-chat-threads.ts +32 -9
- package/corpus/core/src/client/use-session.ts +4 -5
- package/corpus/core/src/db/client.ts +83 -8
- package/corpus/core/src/db/ensure-additive-columns.ts +31 -20
- package/corpus/core/src/db/migrations.ts +22 -2
- package/corpus/core/src/mcp/approval-store.ts +99 -0
- package/corpus/core/src/mcp/build-server.ts +579 -303
- package/corpus/core/src/mcp/embed-app.ts +1 -1
- package/corpus/core/src/mcp/oauth-client-metadata.ts +380 -0
- package/corpus/core/src/mcp/oauth-route.ts +57 -52
- package/corpus/core/src/mcp/screen-memory-stdio.ts +400 -378
- package/corpus/core/src/mcp/server.ts +29 -145
- package/corpus/core/src/mcp/stdio.ts +72 -80
- package/corpus/core/src/mcp-client/manager.ts +6 -10
- package/corpus/core/src/mcp-client/oauth-client.ts +127 -36
- package/corpus/core/src/mcp-client/oauth-routes.ts +16 -6
- package/corpus/core/src/mcp-client/routes.ts +6 -5
- package/corpus/core/src/server/agent-capabilities.ts +20 -0
- package/corpus/core/src/server/agent-chat/action-filters-a2a.ts +27 -0
- package/corpus/core/src/server/agent-chat-plugin.ts +18 -0
- package/corpus/core/src/server/transcribe-voice.ts +14 -5
- package/corpus/core/src/templates/default/.agents/skills/security/SKILL.md +13 -2
- package/corpus/core/src/templates/workspace-core/.agents/skills/authentication/SKILL.md +5 -2
- package/corpus/core/src/templates/workspace-core/.agents/skills/external-agents/SKILL.md +18 -0
- package/corpus/core/src/templates/workspace-core/.agents/skills/security/SKILL.md +13 -2
- package/corpus/templates/analytics/.agents/skills/security/SKILL.md +13 -2
- package/corpus/templates/analytics/app/components/dashboard/DashboardPanelSkeleton.tsx +1 -10
- package/corpus/templates/analytics/app/global.css +0 -31
- package/corpus/templates/analytics/app/lib/sql-query.ts +46 -20
- package/corpus/templates/analytics/changelog/2026-07-28-analytics-dashboard-loading-states-now-use-a-simpler-standar.md +6 -0
- package/corpus/templates/analytics/changelog/2026-07-28-analytics-dashboards-now-load-first-party-charts-reliably-in.md +6 -0
- package/corpus/templates/analytics/server/lib/first-party-analytics-cache.ts +42 -16
- package/corpus/templates/analytics/server/lib/first-party-analytics.ts +4 -2
- package/corpus/templates/analytics/shared/sql-query-limits.ts +1 -0
- package/corpus/templates/assets/.agents/skills/security/SKILL.md +13 -2
- package/corpus/templates/brain/.agents/skills/security/SKILL.md +13 -2
- package/corpus/templates/calendar/.agents/skills/security/SKILL.md +13 -2
- package/corpus/templates/chat/.agents/skills/security/SKILL.md +13 -2
- package/corpus/templates/chat/README.md +0 -2
- package/corpus/templates/clips/.agents/skills/security/SKILL.md +13 -2
- package/corpus/templates/clips/app/components/player/player-controls.tsx +3 -6
- package/corpus/templates/clips/app/routes/r.$recordingId.tsx +6 -2
- package/corpus/templates/clips/app/routes/share.$shareId.tsx +3 -1
- package/corpus/templates/clips/changelog/2026-07-28-copied-share-links-no-longer-leave-an-unnecessary-confirmati.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-28-playback-skip-controls-no-longer-show-overlapping-numbers.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-28-public-clips-share-buttons-now-use-a-clean-text-only-label.md +6 -0
- package/corpus/templates/clips/desktop/src/app.tsx +14 -17
- package/corpus/templates/clips/desktop/src/overlays/live-audio-bars.tsx +3 -1
- package/corpus/templates/clips/desktop/src/styles.css +13 -10
- package/corpus/templates/clips/desktop/src-tauri/src/recording_indicator.rs +2 -2
- package/corpus/templates/clips/desktop/src-tauri/src/whisper_speech.rs +36 -0
- package/corpus/templates/content/.agents/skills/security/SKILL.md +13 -2
- package/corpus/templates/content/actions/_builder-cms-read-client.ts +155 -34
- package/corpus/templates/content/actions/_builder-docs-client.ts +151 -30
- package/corpus/templates/content/actions/stage-builder-source-bulk-update.ts +5 -2
- package/corpus/templates/content/app/root.tsx +35 -14
- package/corpus/templates/content/changelog/2026-07-28-builder-backed-files-media-fields-now-accept-direct-file-url.md +6 -0
- package/corpus/templates/content/changelog/2026-07-28-builder-content-reads-now-negotiate-the-newest-mcp-protocol-.md +6 -0
- package/corpus/templates/content/changelog/2026-07-28-public-content-pages-load-faster-before-the-optional-ask-sid.md +6 -0
- package/corpus/templates/design/.agents/skills/security/SKILL.md +13 -2
- package/corpus/templates/design/.agents/skills/visual-edit/SKILL.md +36 -16
- package/corpus/templates/design/.generated/bridge/editor-chrome.generated.ts +42 -3
- package/corpus/templates/design/actions/open-visual-edit.ts +2 -1
- package/corpus/templates/design/app/components/design/CanvasContextMenu.tsx +2 -2
- package/corpus/templates/design/app/components/design/DesignCanvas.tsx +14 -15
- package/corpus/templates/design/app/components/design/ResponsiveInteractBar.tsx +314 -0
- package/corpus/templates/design/app/components/design/bridge/editor-chrome.bridge.ts +88 -3
- package/corpus/templates/design/app/components/design/keyboard-shortcuts.ts +1 -1
- package/corpus/templates/design/app/hooks/useDesignHotkeys.ts +7 -6
- package/corpus/templates/design/app/i18n-data.ts +56 -11
- package/corpus/templates/design/app/i18n-responsive-interact.ts +183 -0
- package/corpus/templates/design/app/lib/agent-chat.ts +60 -0
- package/corpus/templates/design/app/pages/design-editor/responsive-interact.ts +89 -0
- package/corpus/templates/design/changelog/2026-07-28-design-edits-can-be-applied-through-the-host-coding-agent-fr.md +6 -0
- package/corpus/templates/design/changelog/2026-07-28-interact-mode-can-preview-designs-in-responsive-device-sizes.md +6 -0
- package/corpus/templates/design/changelog/2026-07-28-interact-mode-now-opens-a-full-screen-responsive-preview-wit.md +6 -0
- package/corpus/templates/design/changelog/2026-07-28-show-or-hide-design-editing-chrome-with-cmd-on-apple-devices.md +2 -2
- package/corpus/templates/design/changelog/2026-07-28-visual-edit-now-always-shows-the-live-running-app-in-the-can.md +6 -0
- package/corpus/templates/dispatch/.agents/skills/security/SKILL.md +13 -2
- package/corpus/templates/forms/.agents/skills/security/SKILL.md +13 -2
- package/corpus/templates/macros/.agents/skills/security/SKILL.md +13 -2
- package/corpus/templates/mail/.agents/skills/security/SKILL.md +13 -2
- package/corpus/templates/plan/.agents/skills/security/SKILL.md +13 -2
- package/corpus/templates/slides/.agents/skills/security/SKILL.md +13 -2
- package/corpus/templates/tasks/.agents/skills/security/SKILL.md +13 -2
- package/corpus/toolkit/CHANGELOG.md +13 -0
- package/corpus/toolkit/package.json +1 -1
- package/corpus/toolkit/src/chat-history.css +1 -2
- package/corpus/toolkit/src/composer/TiptapComposer.tsx +45 -0
- package/dist/a2a/client.d.ts +7 -0
- package/dist/a2a/client.d.ts.map +1 -1
- package/dist/a2a/client.js +8 -3
- package/dist/a2a/client.js.map +1 -1
- package/dist/a2a/server.d.ts.map +1 -1
- package/dist/a2a/server.js +18 -3
- package/dist/a2a/server.js.map +1 -1
- package/dist/a2a/types.d.ts +7 -0
- package/dist/a2a/types.d.ts.map +1 -1
- package/dist/a2a/types.js.map +1 -1
- package/dist/action.d.ts +15 -1
- package/dist/action.d.ts.map +1 -1
- package/dist/action.js +39 -16
- package/dist/action.js.map +1 -1
- package/dist/agent/engine/ai-sdk-engine.d.ts.map +1 -1
- package/dist/agent/engine/ai-sdk-engine.js +14 -10
- package/dist/agent/engine/ai-sdk-engine.js.map +1 -1
- package/dist/agent/production-agent.d.ts.map +1 -1
- package/dist/agent/production-agent.js +35 -7
- package/dist/agent/production-agent.js.map +1 -1
- package/dist/agent/thread-data-builder.d.ts +2 -0
- package/dist/agent/thread-data-builder.d.ts.map +1 -1
- package/dist/agent/thread-data-builder.js +3 -0
- package/dist/agent/thread-data-builder.js.map +1 -1
- package/dist/chat-threads/migrations.d.ts +21 -0
- package/dist/chat-threads/migrations.d.ts.map +1 -0
- package/dist/chat-threads/migrations.js +45 -0
- package/dist/chat-threads/migrations.js.map +1 -0
- package/dist/cli/create.d.ts.map +1 -1
- package/dist/cli/create.js +4 -0
- package/dist/cli/create.js.map +1 -1
- package/dist/cli/skills-content/design-visual-edit-skill.d.ts +1 -1
- package/dist/cli/skills-content/design-visual-edit-skill.d.ts.map +1 -1
- package/dist/cli/skills-content/design-visual-edit-skill.js +36 -16
- package/dist/cli/skills-content/design-visual-edit-skill.js.map +1 -1
- package/dist/cli/skills.d.ts.map +1 -1
- package/dist/cli/skills.js +15 -0
- package/dist/cli/skills.js.map +1 -1
- package/dist/client/AgentPanel.d.ts.map +1 -1
- package/dist/client/AgentPanel.js +6 -5
- package/dist/client/AgentPanel.js.map +1 -1
- package/dist/client/AssistantChat.d.ts +37 -0
- package/dist/client/AssistantChat.d.ts.map +1 -1
- package/dist/client/AssistantChat.js +41 -8
- package/dist/client/AssistantChat.js.map +1 -1
- package/dist/client/MultiTabAssistantChat.d.ts.map +1 -1
- package/dist/client/MultiTabAssistantChat.js +11 -10
- package/dist/client/MultiTabAssistantChat.js.map +1 -1
- package/dist/client/agent-chat-adapter.d.ts.map +1 -1
- package/dist/client/agent-chat-adapter.js +19 -3
- package/dist/client/agent-chat-adapter.js.map +1 -1
- package/dist/client/analytics.d.ts.map +1 -1
- package/dist/client/analytics.js +150 -101
- package/dist/client/analytics.js.map +1 -1
- package/dist/client/chat/message-components.d.ts +2 -1
- package/dist/client/chat/message-components.d.ts.map +1 -1
- package/dist/client/chat/message-components.js +11 -4
- package/dist/client/chat/message-components.js.map +1 -1
- package/dist/client/chat/runtime.d.ts.map +1 -1
- package/dist/client/chat/runtime.js +2 -1
- package/dist/client/chat/runtime.js.map +1 -1
- package/dist/client/chat/tool-call-display.d.ts +4 -1
- package/dist/client/chat/tool-call-display.d.ts.map +1 -1
- package/dist/client/chat/tool-call-display.js +14 -8
- package/dist/client/chat/tool-call-display.js.map +1 -1
- package/dist/client/chat-model-groups.d.ts.map +1 -1
- package/dist/client/chat-model-groups.js +3 -0
- package/dist/client/chat-model-groups.js.map +1 -1
- package/dist/client/client-status-requests.d.ts +14 -0
- package/dist/client/client-status-requests.d.ts.map +1 -0
- package/dist/client/client-status-requests.js +126 -0
- package/dist/client/client-status-requests.js.map +1 -0
- package/dist/client/settings/VoiceTranscriptionSection.js +1 -1
- package/dist/client/settings/VoiceTranscriptionSection.js.map +1 -1
- package/dist/client/sse-event-processor.d.ts +7 -0
- package/dist/client/sse-event-processor.d.ts.map +1 -1
- package/dist/client/sse-event-processor.js +8 -3
- package/dist/client/sse-event-processor.js.map +1 -1
- package/dist/client/use-agent-engine-configured.d.ts.map +1 -1
- package/dist/client/use-agent-engine-configured.js +29 -43
- package/dist/client/use-agent-engine-configured.js.map +1 -1
- package/dist/client/use-chat-models.d.ts.map +1 -1
- package/dist/client/use-chat-models.js +11 -11
- package/dist/client/use-chat-models.js.map +1 -1
- package/dist/client/use-chat-threads.d.ts.map +1 -1
- package/dist/client/use-chat-threads.js +23 -7
- package/dist/client/use-chat-threads.js.map +1 -1
- package/dist/client/use-session.d.ts.map +1 -1
- package/dist/client/use-session.js +4 -4
- package/dist/client/use-session.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/db/client.d.ts.map +1 -1
- package/dist/db/client.js +48 -4
- package/dist/db/client.js.map +1 -1
- package/dist/db/ensure-additive-columns.d.ts.map +1 -1
- package/dist/db/ensure-additive-columns.js +32 -21
- package/dist/db/ensure-additive-columns.js.map +1 -1
- package/dist/db/migrations.d.ts +9 -0
- package/dist/db/migrations.d.ts.map +1 -1
- package/dist/db/migrations.js +14 -3
- package/dist/db/migrations.js.map +1 -1
- package/dist/file-upload/actions/upload-image.d.ts +1 -1
- package/dist/mcp/approval-store.d.ts +16 -0
- package/dist/mcp/approval-store.d.ts.map +1 -0
- package/dist/mcp/approval-store.js +85 -0
- package/dist/mcp/approval-store.js.map +1 -0
- package/dist/mcp/build-server.d.ts +1 -34
- package/dist/mcp/build-server.d.ts.map +1 -1
- package/dist/mcp/build-server.js +220 -23
- package/dist/mcp/build-server.js.map +1 -1
- package/dist/mcp/embed-app.js +1 -1
- package/dist/mcp/embed-app.js.map +1 -1
- package/dist/mcp/oauth-client-metadata.d.ts +15 -0
- package/dist/mcp/oauth-client-metadata.d.ts.map +1 -0
- package/dist/mcp/oauth-client-metadata.js +297 -0
- package/dist/mcp/oauth-client-metadata.js.map +1 -0
- package/dist/mcp/oauth-route.d.ts.map +1 -1
- package/dist/mcp/oauth-route.js +39 -53
- package/dist/mcp/oauth-route.js.map +1 -1
- package/dist/mcp/screen-memory-stdio.d.ts.map +1 -1
- package/dist/mcp/screen-memory-stdio.js +304 -296
- package/dist/mcp/screen-memory-stdio.js.map +1 -1
- package/dist/mcp/server.d.ts +12 -25
- package/dist/mcp/server.d.ts.map +1 -1
- package/dist/mcp/server.js +24 -133
- package/dist/mcp/server.js.map +1 -1
- package/dist/mcp/stdio.d.ts.map +1 -1
- package/dist/mcp/stdio.js +36 -35
- package/dist/mcp/stdio.js.map +1 -1
- package/dist/mcp-client/manager.d.ts.map +1 -1
- package/dist/mcp-client/manager.js +6 -6
- package/dist/mcp-client/manager.js.map +1 -1
- package/dist/mcp-client/oauth-client.d.ts +13 -17
- package/dist/mcp-client/oauth-client.d.ts.map +1 -1
- package/dist/mcp-client/oauth-client.js +74 -16
- package/dist/mcp-client/oauth-client.js.map +1 -1
- package/dist/mcp-client/oauth-routes.d.ts +2 -2
- package/dist/mcp-client/oauth-routes.d.ts.map +1 -1
- package/dist/mcp-client/oauth-routes.js +16 -6
- package/dist/mcp-client/oauth-routes.js.map +1 -1
- package/dist/mcp-client/routes.js +5 -5
- package/dist/mcp-client/routes.js.map +1 -1
- package/dist/notifications/routes.d.ts +1 -1
- package/dist/observability/routes.d.ts +3 -3
- package/dist/progress/routes.d.ts +1 -1
- package/dist/provider-api/actions/custom-provider-registration.d.ts +14 -14
- package/dist/provider-api/actions/provider-api.d.ts +8 -8
- package/dist/resources/handlers.d.ts +1 -1
- package/dist/secrets/routes.d.ts +9 -9
- package/dist/server/agent-capabilities.d.ts.map +1 -1
- package/dist/server/agent-capabilities.js +21 -0
- package/dist/server/agent-capabilities.js.map +1 -1
- package/dist/server/agent-chat/action-filters-a2a.d.ts +14 -0
- package/dist/server/agent-chat/action-filters-a2a.d.ts.map +1 -1
- package/dist/server/agent-chat/action-filters-a2a.js +16 -0
- package/dist/server/agent-chat/action-filters-a2a.js.map +1 -1
- package/dist/server/agent-chat-plugin.d.ts.map +1 -1
- package/dist/server/agent-chat-plugin.js +11 -1
- package/dist/server/agent-chat-plugin.js.map +1 -1
- package/dist/server/realtime-token.d.ts +1 -1
- package/dist/server/transcribe-voice.d.ts +1 -1
- package/dist/server/transcribe-voice.js +12 -6
- package/dist/server/transcribe-voice.js.map +1 -1
- package/dist/templates/chat/.agents/skills/security/SKILL.md +13 -2
- package/dist/templates/chat/README.md +0 -2
- package/dist/templates/default/.agents/skills/security/SKILL.md +13 -2
- package/dist/templates/workspace-core/.agents/skills/authentication/SKILL.md +5 -2
- package/dist/templates/workspace-core/.agents/skills/external-agents/SKILL.md +18 -0
- package/dist/templates/workspace-core/.agents/skills/security/SKILL.md +13 -2
- package/docs/content/template-design-collaboration-and-full-apps.mdx +3 -1
- package/package.json +7 -4
- package/src/a2a/client.ts +18 -4
- package/src/a2a/server.ts +19 -3
- package/src/a2a/types.ts +7 -0
- package/src/action.ts +43 -16
- package/src/agent/engine/ai-sdk-engine.ts +14 -10
- package/src/agent/production-agent.ts +41 -3
- package/src/agent/thread-data-builder.ts +5 -0
- package/src/chat-threads/migrations.ts +53 -0
- package/src/cli/create.ts +4 -0
- package/src/cli/skills-content/design-visual-edit-skill.ts +36 -16
- package/src/cli/skills.ts +16 -0
- package/src/client/AgentPanel.tsx +9 -5
- package/src/client/AssistantChat.tsx +138 -46
- package/src/client/MultiTabAssistantChat.tsx +16 -10
- package/src/client/agent-chat-adapter.ts +21 -3
- package/src/client/analytics.ts +159 -102
- package/src/client/chat/message-components.tsx +12 -5
- package/src/client/chat/runtime.ts +2 -1
- package/src/client/chat/tool-call-display.tsx +25 -2
- package/src/client/chat-model-groups.ts +3 -0
- package/src/client/client-status-requests.ts +161 -0
- package/src/client/settings/VoiceTranscriptionSection.tsx +2 -2
- package/src/client/sse-event-processor.ts +15 -3
- package/src/client/use-agent-engine-configured.ts +54 -50
- package/src/client/use-chat-models.ts +16 -11
- package/src/client/use-chat-threads.ts +32 -9
- package/src/client/use-session.ts +4 -5
- package/src/db/client.ts +83 -8
- package/src/db/ensure-additive-columns.ts +31 -20
- package/src/db/migrations.ts +22 -2
- package/src/mcp/approval-store.ts +99 -0
- package/src/mcp/build-server.ts +579 -303
- package/src/mcp/embed-app.ts +1 -1
- package/src/mcp/oauth-client-metadata.ts +380 -0
- package/src/mcp/oauth-route.ts +57 -52
- package/src/mcp/screen-memory-stdio.ts +400 -378
- package/src/mcp/server.ts +29 -145
- package/src/mcp/stdio.ts +72 -80
- package/src/mcp-client/manager.ts +6 -10
- package/src/mcp-client/oauth-client.ts +127 -36
- package/src/mcp-client/oauth-routes.ts +16 -6
- package/src/mcp-client/routes.ts +6 -5
- package/src/server/agent-capabilities.ts +20 -0
- package/src/server/agent-chat/action-filters-a2a.ts +27 -0
- package/src/server/agent-chat-plugin.ts +18 -0
- package/src/server/transcribe-voice.ts +14 -5
- package/src/templates/chat/.agents/skills/security/SKILL.md +13 -2
- package/src/templates/chat/README.md +0 -2
- package/src/templates/default/.agents/skills/security/SKILL.md +13 -2
- package/src/templates/workspace-core/.agents/skills/authentication/SKILL.md +5 -2
- package/src/templates/workspace-core/.agents/skills/external-agents/SKILL.md +18 -0
- package/src/templates/workspace-core/.agents/skills/security/SKILL.md +13 -2
package/src/a2a/server.ts
CHANGED
|
@@ -222,7 +222,7 @@ export function mountA2A(
|
|
|
222
222
|
// /tmp/security-audit/12-mcp-a2a-agent.md.
|
|
223
223
|
getH3App(nitroApp).use(
|
|
224
224
|
"/.well-known/agent-card.json",
|
|
225
|
-
defineEventHandler((event) => {
|
|
225
|
+
defineEventHandler(async (event) => {
|
|
226
226
|
if (getMethod(event) !== "GET") {
|
|
227
227
|
setResponseStatus(event, 405);
|
|
228
228
|
return { error: "Method not allowed" };
|
|
@@ -233,10 +233,26 @@ export function mountA2A(
|
|
|
233
233
|
const host = getRequestHeader(event, "host") ?? "localhost";
|
|
234
234
|
const baseUrl = `${protocol}://${host}`;
|
|
235
235
|
|
|
236
|
-
|
|
236
|
+
// The anonymous card may only advertise actions safe to disclose
|
|
237
|
+
// publicly (`requiresAuth !== true`), but `actions/invoke` only ever
|
|
238
|
+
// runs the opposite set (`requiresAuth === true`). Those are disjoint,
|
|
239
|
+
// so an unauthenticated card said "no directly callable actions" about
|
|
240
|
+
// an app whose actions a verified sibling can call — and callers fell
|
|
241
|
+
// back to open-ended delegation. Show a verified caller what it can
|
|
242
|
+
// actually invoke; anonymous fetches keep the public list unchanged.
|
|
243
|
+
let skills = filterPublicAgentCardSkills(config);
|
|
244
|
+
if (config.authenticatedSkills?.length) {
|
|
245
|
+
const bearer = extractBearerToken(
|
|
246
|
+
getRequestHeader(event, "authorization"),
|
|
247
|
+
);
|
|
248
|
+
if (bearer) {
|
|
249
|
+
const payload = await verifyA2AToken(bearer, event);
|
|
250
|
+
if (payload.email) skills = config.authenticatedSkills;
|
|
251
|
+
}
|
|
252
|
+
}
|
|
237
253
|
|
|
238
254
|
return generateAgentCard(
|
|
239
|
-
{ ...config, skills
|
|
255
|
+
{ ...config, skills },
|
|
240
256
|
baseUrl,
|
|
241
257
|
`${routePrefix}/a2a`,
|
|
242
258
|
);
|
package/src/a2a/types.ts
CHANGED
|
@@ -225,6 +225,13 @@ export interface A2AConfig {
|
|
|
225
225
|
description: string;
|
|
226
226
|
version?: string;
|
|
227
227
|
skills: AgentSkill[];
|
|
228
|
+
/**
|
|
229
|
+
* Skills advertised only to a caller with a verified A2A identity — the set
|
|
230
|
+
* `actions/invoke` will actually run. Anonymous card fetches never see these.
|
|
231
|
+
* Without it the card advertises the public set, which is disjoint from the
|
|
232
|
+
* invocable set, so siblings are told nothing is directly callable.
|
|
233
|
+
*/
|
|
234
|
+
authenticatedSkills?: AgentSkill[];
|
|
228
235
|
/** If true, public agent-card discovery includes only explicit public-safe skills. */
|
|
229
236
|
publicSkillsOnly?: boolean;
|
|
230
237
|
handler?: A2AHandler;
|
package/src/action.ts
CHANGED
|
@@ -1370,6 +1370,45 @@ function coerceGatewayStringifiedArgs(
|
|
|
1370
1370
|
return out ?? args;
|
|
1371
1371
|
}
|
|
1372
1372
|
|
|
1373
|
+
/**
|
|
1374
|
+
* Compact signature of an action's parameters, e.g.
|
|
1375
|
+
* `{ deckId*: string, operation*: "edit"|"replace", slideId?: string }` where
|
|
1376
|
+
* `*` = required and `?` = optional.
|
|
1377
|
+
*
|
|
1378
|
+
* Enum values are spelled out because a rejected call is usually a wrong enum:
|
|
1379
|
+
* gateways that pre-fill optional fields reach for the first allowed value, and
|
|
1380
|
+
* a model that only learns "must be equal to one of the allowed values" re-sends
|
|
1381
|
+
* the same guess until the identical-error breaker kills the turn.
|
|
1382
|
+
*
|
|
1383
|
+
* Shared so the raw-JSON-schema tool path in the agent loop describes a
|
|
1384
|
+
* rejection the same way `wrapWithValidation` does for Zod actions.
|
|
1385
|
+
*/
|
|
1386
|
+
export function describeToolParameterSignature(
|
|
1387
|
+
parameters: ActionTool["parameters"] | undefined,
|
|
1388
|
+
only?: readonly string[],
|
|
1389
|
+
): string | null {
|
|
1390
|
+
const properties = parameters?.properties;
|
|
1391
|
+
if (!properties) return null;
|
|
1392
|
+
const required = new Set(parameters?.required ?? []);
|
|
1393
|
+
const keys = Object.keys(properties).filter(
|
|
1394
|
+
(key) => !only?.length || only.includes(key),
|
|
1395
|
+
);
|
|
1396
|
+
const sig = (keys.length ? keys : Object.keys(properties))
|
|
1397
|
+
.map((key) => {
|
|
1398
|
+
const spec = properties[key];
|
|
1399
|
+
const mark = required.has(key) ? "*" : "?";
|
|
1400
|
+
const type = Array.isArray(spec.enum)
|
|
1401
|
+
? spec.enum.map((value) => JSON.stringify(value)).join("|")
|
|
1402
|
+
: Array.isArray(spec.type)
|
|
1403
|
+
? spec.type.join("|")
|
|
1404
|
+
: (spec.type ?? "any");
|
|
1405
|
+
return `${key}${mark}: ${type}`;
|
|
1406
|
+
})
|
|
1407
|
+
.join(", ");
|
|
1408
|
+
if (!sig) return null;
|
|
1409
|
+
return `{ ${sig.length > 600 ? `${sig.slice(0, 600)}…` : sig} }`;
|
|
1410
|
+
}
|
|
1411
|
+
|
|
1373
1412
|
/**
|
|
1374
1413
|
* Wrap an action's run function with schema validation.
|
|
1375
1414
|
* Invalid inputs get a clear error message (including what was actually passed)
|
|
@@ -1427,22 +1466,10 @@ function wrapWithValidation(
|
|
|
1427
1466
|
received = String(args);
|
|
1428
1467
|
}
|
|
1429
1468
|
|
|
1430
|
-
|
|
1431
|
-
|
|
1432
|
-
|
|
1433
|
-
|
|
1434
|
-
if (toolParameters?.properties) {
|
|
1435
|
-
const required = new Set(toolParameters.required ?? []);
|
|
1436
|
-
const sig = Object.entries(toolParameters.properties)
|
|
1437
|
-
.map(([k, v]) => {
|
|
1438
|
-
const mark = required.has(k) ? "*" : "?";
|
|
1439
|
-
const type = (v as { type?: string }).type ?? "any";
|
|
1440
|
-
return `${k}${mark}: ${type}`;
|
|
1441
|
-
})
|
|
1442
|
-
.join(", ");
|
|
1443
|
-
if (sig)
|
|
1444
|
-
expected = ` Expected: { ${sig} } (where * = required, ? = optional).`;
|
|
1445
|
-
}
|
|
1469
|
+
const signature = describeToolParameterSignature(toolParameters);
|
|
1470
|
+
const expected = signature
|
|
1471
|
+
? ` Expected: ${signature} (where * = required, ? = optional).`
|
|
1472
|
+
: "";
|
|
1446
1473
|
|
|
1447
1474
|
throw new Error(
|
|
1448
1475
|
`Invalid action parameters — ${parts.join(". ")}. Received: ${received}.${expected}`,
|
|
@@ -360,18 +360,22 @@ class AISDKEngine implements AgentEngine {
|
|
|
360
360
|
// `createProviderModel` forces Chat Completions specifically when
|
|
361
361
|
// `this.baseUrl` is set (many OpenAI-compatible gateways/proxies
|
|
362
362
|
// don't implement Responses — see that comment). In that exact
|
|
363
|
-
// combination — forced Chat Completions AND tools present —
|
|
364
|
-
//
|
|
365
|
-
//
|
|
366
|
-
//
|
|
363
|
+
// combination — forced Chat Completions AND tools present — send
|
|
364
|
+
// `"none"` rather than our resolved effort; Responses-API calls (no
|
|
365
|
+
// baseUrl) are unaffected and keep full effort control.
|
|
366
|
+
//
|
|
367
|
+
// Omitting the field does NOT work: OpenAI then applies the model's
|
|
368
|
+
// own default effort, which is not "none", and rejects the request
|
|
369
|
+
// exactly the same way. Only the explicit "none" clears it — the
|
|
370
|
+
// error text spells this out ("or set reasoning_effort to 'none'").
|
|
367
371
|
const forcedChatCompletionsWithTools =
|
|
368
372
|
Boolean(this.baseUrl) && aiSdkTools !== undefined;
|
|
369
|
-
|
|
370
|
-
providerOpts.openai
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
}
|
|
373
|
+
providerOpts.openai = {
|
|
374
|
+
...((providerOpts.openai as object) ?? {}),
|
|
375
|
+
reasoningEffort: forcedChatCompletionsWithTools
|
|
376
|
+
? "none"
|
|
377
|
+
: reasoningEffort,
|
|
378
|
+
};
|
|
375
379
|
} else if (this.provider === "openrouter") {
|
|
376
380
|
providerOpts.openrouter = {
|
|
377
381
|
...((providerOpts.openrouter as object) ?? {}),
|
|
@@ -13,6 +13,7 @@ import type { EventHandler as H3EventHandler } from "h3";
|
|
|
13
13
|
import { parseA2AAgentActivityPart } from "../a2a/activity.js";
|
|
14
14
|
import type { Task } from "../a2a/types.js";
|
|
15
15
|
import {
|
|
16
|
+
describeToolParameterSignature,
|
|
16
17
|
isAgentActionStopError,
|
|
17
18
|
type ActionAutomationContext,
|
|
18
19
|
type ActionCaller,
|
|
@@ -3405,14 +3406,46 @@ function dedupeAssistantToolCallsById(
|
|
|
3405
3406
|
return deduped;
|
|
3406
3407
|
}
|
|
3407
3408
|
|
|
3409
|
+
/**
|
|
3410
|
+
* Property names an Ajv `errorsText` line blames, e.g.
|
|
3411
|
+
* `input/operations must be array; input must have required property 'id'`.
|
|
3412
|
+
*/
|
|
3413
|
+
function schemaErrorPropertyNames(error: string): string[] {
|
|
3414
|
+
const names = new Set<string>();
|
|
3415
|
+
for (const match of error.matchAll(/\binput\/([A-Za-z0-9_$-]+)/g)) {
|
|
3416
|
+
names.add(match[1]);
|
|
3417
|
+
}
|
|
3418
|
+
for (const match of error.matchAll(
|
|
3419
|
+
/must have required property '([^']+)'/g,
|
|
3420
|
+
)) {
|
|
3421
|
+
names.add(match[1]);
|
|
3422
|
+
}
|
|
3423
|
+
return [...names];
|
|
3424
|
+
}
|
|
3425
|
+
|
|
3426
|
+
/**
|
|
3427
|
+
* Raw-JSON-schema actions used to be told only that their arguments were wrong,
|
|
3428
|
+
* never what shape was expected — so a model re-sent the same guess until the
|
|
3429
|
+
* identical-error breaker ended the turn with the write never executed. Zod
|
|
3430
|
+
* actions have echoed the expected signature since `wrapWithValidation`; this
|
|
3431
|
+
* gives the raw path the same answer from the same helper.
|
|
3432
|
+
*/
|
|
3408
3433
|
function toolInputSchemaErrorResult(
|
|
3409
3434
|
toolName: string,
|
|
3410
3435
|
input: unknown,
|
|
3411
3436
|
error: string,
|
|
3437
|
+
parameters?: ActionTool["parameters"],
|
|
3412
3438
|
): string {
|
|
3439
|
+
const signature = describeToolParameterSignature(
|
|
3440
|
+
parameters,
|
|
3441
|
+
schemaErrorPropertyNames(error),
|
|
3442
|
+
);
|
|
3413
3443
|
return (
|
|
3414
3444
|
`Invalid action parameters for ${toolName}: ${sanitizeToolErrorText(error)}. ` +
|
|
3415
3445
|
`Received: ${stringifyToolInput(input)}. ` +
|
|
3446
|
+
(signature
|
|
3447
|
+
? `Expected: ${signature} (where * = required, ? = optional). `
|
|
3448
|
+
: "") +
|
|
3416
3449
|
"The tool was not executed; retry with arguments that match the tool schema."
|
|
3417
3450
|
);
|
|
3418
3451
|
}
|
|
@@ -4723,11 +4756,14 @@ export async function runAgentLoop(opts: {
|
|
|
4723
4756
|
const result =
|
|
4724
4757
|
`Stopped after ${count} identical errors from ${toolCall.name} with the same arguments. ` +
|
|
4725
4758
|
`Last error: ${sanitizedResult}`;
|
|
4759
|
+
// This message is streamed to the USER, not back to the model — the
|
|
4760
|
+
// model's copy is `result` above. Describe the failure and what they
|
|
4761
|
+
// can do; never instruct them to "fix the arguments".
|
|
4726
4762
|
requestedActionStop ??= {
|
|
4727
4763
|
message:
|
|
4728
|
-
`
|
|
4729
|
-
|
|
4730
|
-
|
|
4764
|
+
`I stopped because the ${toolCall.name} action failed ${count} times in a row the same way, ` +
|
|
4765
|
+
"so retrying it again would not have worked. Anything completed before this is saved. " +
|
|
4766
|
+
`Error: ${sanitizedResult}`,
|
|
4731
4767
|
errorCode: "repeated_identical_tool_error",
|
|
4732
4768
|
};
|
|
4733
4769
|
return result;
|
|
@@ -5114,6 +5150,7 @@ export async function runAgentLoop(opts: {
|
|
|
5114
5150
|
toolCall.name,
|
|
5115
5151
|
toolCallSchemaError.input,
|
|
5116
5152
|
toolCallSchemaError.error,
|
|
5153
|
+
actionEntry?.tool.parameters,
|
|
5117
5154
|
),
|
|
5118
5155
|
);
|
|
5119
5156
|
send({
|
|
@@ -5146,6 +5183,7 @@ export async function runAgentLoop(opts: {
|
|
|
5146
5183
|
toolCall.name,
|
|
5147
5184
|
toolCall.input,
|
|
5148
5185
|
rawToolInputError,
|
|
5186
|
+
actionEntry.tool.parameters,
|
|
5149
5187
|
),
|
|
5150
5188
|
);
|
|
5151
5189
|
send({
|
|
@@ -21,6 +21,8 @@ interface ContentPart {
|
|
|
21
21
|
args?: Record<string, string>;
|
|
22
22
|
result?: string;
|
|
23
23
|
isError?: boolean;
|
|
24
|
+
/** Mirrors the client ContentPart marker in client/sse-event-processor.ts. */
|
|
25
|
+
outcome?: "unknown";
|
|
24
26
|
completedSideEffect?: boolean;
|
|
25
27
|
mcpApp?: AgentMcpAppPayload;
|
|
26
28
|
chatUI?: ActionChatUIConfig;
|
|
@@ -385,6 +387,9 @@ function settleInterruptedToolCalls(content: ContentPart[]): void {
|
|
|
385
387
|
for (const part of content) {
|
|
386
388
|
if (part.type === "tool-call" && part.result === undefined) {
|
|
387
389
|
part.result = INTERRUPTED_TOOL_RESULT;
|
|
390
|
+
// Interrupted is not failed — never set `isError` here. The persisted
|
|
391
|
+
// turn must agree with the live client (client/sse-event-processor.ts).
|
|
392
|
+
part.outcome = "unknown";
|
|
388
393
|
}
|
|
389
394
|
}
|
|
390
395
|
}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { isServerlessRuntime } from "../db/client.js";
|
|
2
|
+
import type { MigrationEntry } from "../db/migrations.js";
|
|
3
|
+
import { runMigrations } from "../db/migrations.js";
|
|
4
|
+
import { repairLegacyChatThreadMessageCounts } from "./store.js";
|
|
5
|
+
|
|
6
|
+
export const CHAT_THREADS_MIGRATIONS_TABLE = "_chat_threads_migrations";
|
|
7
|
+
|
|
8
|
+
export const CHAT_THREADS_REPAIR_MESSAGE_COUNTS_MIGRATION =
|
|
9
|
+
"chat-threads-repair-legacy-message-counts";
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Rows written before `message_count` was maintained still carry 0, and both
|
|
13
|
+
* `listThreads` and `searchThreads` filter `message_count > 0` in SQL — so on a
|
|
14
|
+
* database that predates the column, threads that do have messages never appear
|
|
15
|
+
* in the sidebar. This entry is the only reachable caller of the repair; being
|
|
16
|
+
* name-tracked, the `thread_data` scan it performs runs once per database and
|
|
17
|
+
* is skipped entirely on every later boot.
|
|
18
|
+
*/
|
|
19
|
+
export const CHAT_THREADS_MIGRATIONS: MigrationEntry[] = [
|
|
20
|
+
{
|
|
21
|
+
version: 1,
|
|
22
|
+
name: CHAT_THREADS_REPAIR_MESSAGE_COUNTS_MIGRATION,
|
|
23
|
+
// Run-only: the count comes from `normalizeThreadRepository`, which dedupes
|
|
24
|
+
// and re-parents message entries. No portable SQL equivalent.
|
|
25
|
+
sql: {},
|
|
26
|
+
run: async () => {
|
|
27
|
+
const { scanned, updated } = await repairLegacyChatThreadMessageCounts();
|
|
28
|
+
if (scanned > 0) {
|
|
29
|
+
console.log(
|
|
30
|
+
`[chat-threads] repaired legacy message_count on ${updated} of ${scanned} scanned row(s)`,
|
|
31
|
+
);
|
|
32
|
+
}
|
|
33
|
+
},
|
|
34
|
+
},
|
|
35
|
+
];
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Apply data migrations only in a long-lived process. A serverless cold start
|
|
39
|
+
* must never launch the legacy blob scan: concurrent isolates would all race
|
|
40
|
+
* the same repair and exhaust the shared database even if route readiness does
|
|
41
|
+
* not await it. Operators can run the app in a long-lived maintenance process
|
|
42
|
+
* against the target database to apply the name-tracked repair once.
|
|
43
|
+
*/
|
|
44
|
+
export async function runChatThreadDataMigrations(
|
|
45
|
+
nitroApp: unknown,
|
|
46
|
+
): Promise<"applied" | "skipped-serverless"> {
|
|
47
|
+
if (isServerlessRuntime()) return "skipped-serverless";
|
|
48
|
+
const migrate = runMigrations(CHAT_THREADS_MIGRATIONS, {
|
|
49
|
+
table: CHAT_THREADS_MIGRATIONS_TABLE,
|
|
50
|
+
});
|
|
51
|
+
await migrate(nitroApp);
|
|
52
|
+
return "applied";
|
|
53
|
+
}
|
package/src/cli/create.ts
CHANGED
|
@@ -35,6 +35,10 @@ const REACT_ROUTER_BUILD_DEPENDENCIES = [
|
|
|
35
35
|
"vite",
|
|
36
36
|
] as const;
|
|
37
37
|
const MINIMUM_RELEASE_AGE_EXCLUDES = [
|
|
38
|
+
'"@modelcontextprotocol/client"',
|
|
39
|
+
'"@modelcontextprotocol/core"',
|
|
40
|
+
'"@modelcontextprotocol/node"',
|
|
41
|
+
'"@modelcontextprotocol/server"',
|
|
38
42
|
'"@typescript/*"',
|
|
39
43
|
'"@sentry/*"',
|
|
40
44
|
"fast-xml-parser",
|
|
@@ -27,10 +27,18 @@ exported instructions only, with no MCP connector registration.
|
|
|
27
27
|
|
|
28
28
|
## Put Design Beside The Chat
|
|
29
29
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
30
|
+
Prefer the interactive MCP App returned by \`open-visual-edit\` when the coding
|
|
31
|
+
host renders it. The user gets the Design canvas beside the conversation, and
|
|
32
|
+
**Apply design updates** can submit the bounded source-edit handoff back to the
|
|
33
|
+
current host conversation through the standard MCP Apps message bridge. The
|
|
34
|
+
host may ask the user to confirm the current conversation or choose a new one.
|
|
35
|
+
|
|
36
|
+
Otherwise, after \`open-visual-edit\` returns \`openUrl\`, open that URL in the
|
|
37
|
+
coding host's inline browser when one is available. This still keeps Design
|
|
38
|
+
beside the conversation, but an ordinary browser page has no trusted path into
|
|
39
|
+
the host's current composer. In that fallback surface, **Apply design updates**
|
|
40
|
+
uses Design's local agent; use **Copy prompt to your agent** to hand the same
|
|
41
|
+
structured edit batch to the coding agent.
|
|
34
42
|
|
|
35
43
|
- In Codex Desktop, use the in-app Browser tool to open \`openUrl\`. The built-in
|
|
36
44
|
browser is the right surface for localhost and public pages that should stay
|
|
@@ -42,14 +50,13 @@ screens as the agent, and iterate without switching apps.
|
|
|
42
50
|
sessions may not expose one. If the inline surface is unavailable or disabled,
|
|
43
51
|
return the normal **Open design** link instead of claiming it opened.
|
|
44
52
|
|
|
45
|
-
Prefer the
|
|
46
|
-
|
|
47
|
-
panes.
|
|
53
|
+
Prefer the MCP App surface for a connected Design plugin, then the host's
|
|
54
|
+
browser/preview tool as the universal fallback. Keep the canvas beside chat
|
|
55
|
+
when the host supports rearrangeable panes.
|
|
48
56
|
|
|
49
|
-
Inside Design, use **Show/Hide UI** from the \`Cmd+K\` menu or press
|
|
50
|
-
\`
|
|
51
|
-
|
|
52
|
-
Design's empty-canvas context menu.
|
|
57
|
+
Inside Design, use **Show/Hide UI** from the \`Cmd+K\` menu or press Figma's
|
|
58
|
+
\`Shift+\\\` shortcut to toggle all editing chrome so only the canvas remains.
|
|
59
|
+
The same action is available from Design's empty-canvas context menu.
|
|
53
60
|
|
|
54
61
|
## Core Model
|
|
55
62
|
|
|
@@ -57,8 +64,16 @@ Design's empty-canvas context menu.
|
|
|
57
64
|
- Each screen keeps URL metadata: \`connectionId\`, \`routeId\`, \`path\`,
|
|
58
65
|
\`url\`, \`bridgeUrl\`, title, and viewport size.
|
|
59
66
|
- Localhost Edit mode renders the running app through the local bridge as a live
|
|
60
|
-
iframe with the same editor bridge used by HTML designs. It is
|
|
61
|
-
static DOM snapshot.
|
|
67
|
+
iframe with the same editor bridge used by HTML designs. It is never a frozen
|
|
68
|
+
static DOM snapshot. Editing is direct DOM manipulation against that live
|
|
69
|
+
document; the parallel \`/snapshot\` fetch feeds the editable source model only
|
|
70
|
+
and must never be rendered in the frame.
|
|
71
|
+
- A viewer holding the connection's \`previewToken\` gets the proxied
|
|
72
|
+
\`/live-edit\` document with editor chrome. A viewer without one — a signed-out
|
|
73
|
+
session, a public link, or an inline browser with no cookies — gets the plain
|
|
74
|
+
dev-server URL: still live, but with no editor chrome, no layers, and no
|
|
75
|
+
editing. If the canvas looks right but selection and the layers panel do
|
|
76
|
+
nothing, the frame is unbridged; sign in rather than assuming Design is broken.
|
|
62
77
|
- The live editor is same-origin through the local bridge proxy. This boots
|
|
63
78
|
CSR apps and root-relative assets, but it is still a localhost editing proxy:
|
|
64
79
|
app-origin cookies, WebSockets/HMR, SSE, and non-GET app API calls may need a
|
|
@@ -336,9 +351,11 @@ Fallback, only when \`open-visual-edit\` is unavailable:
|
|
|
336
351
|
## Applying Visual Edits Back To Source
|
|
337
352
|
|
|
338
353
|
Canvas edits on a localhost screen do not write source as you make them. They
|
|
339
|
-
accumulate as pending edits and the editor shows an
|
|
340
|
-
button
|
|
341
|
-
prompt to the
|
|
354
|
+
accumulate as pending edits and the editor shows an **Apply design updates**
|
|
355
|
+
button on the canvas. In an MCP App, clicking it hands the bounded structured
|
|
356
|
+
prompt to the current host coding conversation. In an ordinary browser or
|
|
357
|
+
standalone Design page, it falls back to the local Design agent. The dropdown's
|
|
358
|
+
**Copy prompt to your agent** action is the universal manual fallback.
|
|
342
359
|
|
|
343
360
|
- Style, text, and drag/drop structure edits all collect into the same pending
|
|
344
361
|
batch, so the user can make several changes and apply once.
|
|
@@ -410,6 +427,9 @@ the connected app's text/code files through the bridge
|
|
|
410
427
|
- The Design editor opens in overview mode.
|
|
411
428
|
- Every requested screen renders the intended localhost URL, showing real app
|
|
412
429
|
content rather than an endless loading spinner.
|
|
430
|
+
- The screen iframe carries a \`src\`, not a \`srcdoc\`. A localhost screen with a
|
|
431
|
+
\`srcdoc\` is a bug, not a slow load — check it in the browser devtools before
|
|
432
|
+
reporting the canvas as working.
|
|
413
433
|
- Alt-dragging a screen copies the URL-backed frame, not an inline HTML clone.
|
|
414
434
|
- A query/path edit changes only the target screen's URL metadata and iframe.
|
|
415
435
|
- The Code tab shows a local-files root for the connection and opens its files.
|
package/src/cli/skills.ts
CHANGED
|
@@ -1173,6 +1173,7 @@ function writeSkillFolder(
|
|
|
1173
1173
|
`${JSON.stringify(metadata, null, 2)}\n`,
|
|
1174
1174
|
"utf-8",
|
|
1175
1175
|
);
|
|
1176
|
+
assertSkillFolderIsNotSymlink(dir);
|
|
1176
1177
|
fs.rmSync(dir, { recursive: true, force: true });
|
|
1177
1178
|
fs.renameSync(tempDir, dir);
|
|
1178
1179
|
} catch (error: any) {
|
|
@@ -1186,6 +1187,21 @@ function writeSkillFolder(
|
|
|
1186
1187
|
}
|
|
1187
1188
|
}
|
|
1188
1189
|
|
|
1190
|
+
function assertSkillFolderIsNotSymlink(dir: string): void {
|
|
1191
|
+
let stat: fs.Stats;
|
|
1192
|
+
try {
|
|
1193
|
+
stat = fs.lstatSync(dir);
|
|
1194
|
+
} catch (error: any) {
|
|
1195
|
+
if (error?.code === "ENOENT") return;
|
|
1196
|
+
throw error;
|
|
1197
|
+
}
|
|
1198
|
+
if (stat.isSymbolicLink()) {
|
|
1199
|
+
throw new Error(
|
|
1200
|
+
`Refusing to replace symlinked Agent Native skill folder ${dir}. Update the linked source or remove the symlink before installing.`,
|
|
1201
|
+
);
|
|
1202
|
+
}
|
|
1203
|
+
}
|
|
1204
|
+
|
|
1189
1205
|
function isJsonRecord(value: unknown): value is Record<string, unknown> {
|
|
1190
1206
|
return Boolean(value && typeof value === "object" && !Array.isArray(value));
|
|
1191
1207
|
}
|
|
@@ -95,6 +95,7 @@ import {
|
|
|
95
95
|
AGENT_CHAT_VIEW_TRANSITION_CLASS,
|
|
96
96
|
getAgentChatViewTransitionStyle,
|
|
97
97
|
} from "./chat-view-transition.js";
|
|
98
|
+
import { fetchBuilderStatus } from "./client-status-requests.js";
|
|
98
99
|
import { RealtimeVoiceModeProvider } from "./composer/index.js";
|
|
99
100
|
import {
|
|
100
101
|
getFramePostMessageTargetOrigin,
|
|
@@ -481,13 +482,16 @@ function useBuilderConnectUrl() {
|
|
|
481
482
|
// global), refresh fired again, and we'd loop forever.
|
|
482
483
|
let lastConfigured = false;
|
|
483
484
|
const refresh = () => {
|
|
484
|
-
|
|
485
|
-
|
|
485
|
+
fetchBuilderStatus<{
|
|
486
|
+
cliAuthUrl?: string;
|
|
487
|
+
connectUrl?: string;
|
|
488
|
+
configured?: boolean;
|
|
489
|
+
}>()
|
|
490
|
+
.then((result) => (result.state === "available" ? result.value : null))
|
|
486
491
|
.then((data) => {
|
|
487
492
|
if (cancelled || !data) return;
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
}
|
|
493
|
+
const nextConnectUrl = data.cliAuthUrl || data.connectUrl;
|
|
494
|
+
if (nextConnectUrl) setConnectUrl(nextConnectUrl);
|
|
491
495
|
const nextConfigured = !!data.configured;
|
|
492
496
|
setConfigured(nextConfigured);
|
|
493
497
|
if (nextConfigured && !lastConfigured) {
|