@agent-native/core 0.121.2 → 0.122.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 +139 -0
- package/corpus/core/docs/content/actions.mdx +2 -2
- package/corpus/core/docs/content/agent-surfaces.mdx +1 -1
- package/corpus/core/docs/content/authentication.mdx +2 -0
- package/corpus/core/docs/content/deployment.mdx +36 -0
- package/corpus/core/docs/content/http-api.mdx +266 -0
- package/corpus/core/docs/content/syncing-template-changes.mdx +159 -0
- package/corpus/core/package.json +2 -1
- package/corpus/core/src/a2a/activity.ts +38 -27
- package/corpus/core/src/agent/engine/builder-engine.ts +35 -4
- package/corpus/core/src/agent/run-manager.ts +20 -1
- package/corpus/core/src/agent/run-store.ts +4 -1
- package/corpus/core/src/agent/types.ts +28 -8
- package/corpus/core/src/chat-threads/store.ts +45 -0
- package/corpus/core/src/checkpoints/index.ts +2 -0
- package/corpus/core/src/checkpoints/route-match.ts +13 -0
- package/corpus/core/src/cli/create.ts +105 -17
- package/corpus/core/src/cli/index.ts +20 -0
- package/corpus/core/src/cli/template-baseline.ts +410 -0
- package/corpus/core/src/cli/template-sync.ts +1004 -0
- package/corpus/core/src/cli/templates-meta.ts +1 -0
- package/corpus/core/src/client/AssistantChat.tsx +38 -12
- package/corpus/core/src/client/NewWorkspaceAppFlow.tsx +75 -10
- package/corpus/core/src/client/chat/message-components.tsx +127 -66
- package/corpus/core/src/client/chat/tool-call-display.tsx +29 -5
- package/corpus/core/src/client/error-format.ts +18 -0
- package/corpus/core/src/client/org/OrgSwitcher.tsx +30 -8
- package/corpus/core/src/client/org/TeamPage.tsx +7 -6
- package/corpus/core/src/client/sse-event-processor.ts +3 -0
- package/corpus/core/src/data-widgets/index.ts +41 -0
- package/corpus/core/src/deploy/build.ts +11 -9
- package/corpus/core/src/integrations/webhook-handler.ts +63 -9
- package/corpus/core/src/org/auto-join-domain.ts +4 -3
- package/corpus/core/src/org/context.ts +108 -39
- package/corpus/core/src/org/index.ts +5 -0
- package/corpus/core/src/org/service-identity.ts +60 -0
- package/corpus/core/src/provider-api/index.ts +22 -1
- package/corpus/core/src/scripts/docs/search.ts +12 -1
- package/corpus/core/src/server/agent-chat/context-tools.ts +9 -4
- package/corpus/core/src/server/agent-chat/framework-prompts.ts +38 -66
- package/corpus/core/src/server/agent-chat-plugin.ts +17 -10
- package/corpus/core/src/server/agents-bundle.ts +84 -5
- package/corpus/core/src/server/auth.ts +4 -3
- package/corpus/core/src/server/builder-browser.ts +47 -19
- package/corpus/core/src/server/core-routes-plugin.ts +2 -2
- package/corpus/core/src/server/credential-provider.ts +209 -68
- package/corpus/core/src/server/index.ts +3 -0
- package/corpus/core/src/server/prompts/framework-core-compact.ts +6 -13
- package/corpus/core/src/server/prompts/framework-core.ts +9 -21
- package/corpus/core/src/server/prompts/index.ts +0 -1
- package/corpus/core/src/server/prompts/shared-rules.ts +19 -11
- package/corpus/core/src/server/ssr-handler.ts +13 -2
- package/corpus/core/src/settings/user-settings.ts +13 -1
- package/corpus/core/src/shared/cache-control.ts +141 -0
- package/corpus/core/src/templates/chat/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
- package/corpus/core/src/templates/chat/_gitignore +1 -0
- package/corpus/core/src/templates/default/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
- package/corpus/core/src/templates/headless/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
- package/corpus/core/src/templates/workspace-core/.agents/skills/performance/SKILL.md +19 -0
- package/corpus/core/src/templates/workspace-core/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
- package/corpus/core/src/templates/workspace-core/.agents/skills/visual-answer/SKILL.md +1 -0
- package/corpus/core/src/vite/agents-bundle-plugin.ts +7 -6
- package/corpus/core/src/vite/client.ts +5 -0
- package/corpus/templates/analytics/.agents/skills/adhoc-analysis/SKILL.md +4 -5
- package/corpus/templates/analytics/.agents/skills/admin-surfaces/SKILL.md +55 -0
- package/corpus/templates/analytics/.agents/skills/dashboard-management/SKILL.md +10 -0
- package/corpus/templates/analytics/.agents/skills/dashboard-management/references/template-catalog-and-demo.md +62 -0
- package/corpus/templates/analytics/.agents/skills/dashboard-ops/SKILL.md +85 -0
- package/corpus/templates/analytics/.agents/skills/data-querying/SKILL.md +27 -2
- package/corpus/templates/analytics/.agents/skills/data-querying/references/inline-chart-embeds.md +139 -0
- package/corpus/templates/analytics/.agents/skills/monitoring/SKILL.md +77 -0
- package/corpus/templates/analytics/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
- package/corpus/templates/analytics/AGENTS.md +91 -563
- package/corpus/templates/analytics/_gitignore +1 -0
- package/corpus/templates/analytics/actions/bigquery.ts +12 -4
- package/corpus/templates/analytics/actions/generate-chart.ts +5 -5
- package/corpus/templates/analytics/app/components/dashboard/SqlChart.tsx +30 -1
- package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/DashboardFilterBar.tsx +3 -0
- package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/SqlChartCard.tsx +1 -1
- package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/index.tsx +1 -0
- package/corpus/templates/analytics/changelog/2026-07-24-analytics-finds-saved-dashboards-and-queries-far-more-reliab.md +6 -0
- package/corpus/templates/analytics/changelog/2026-07-24-notion-access-errors-now-explain-that-a-page-needs-sharing-w.md +6 -0
- package/corpus/templates/analytics/server/lib/agent-chat-plan-mode.ts +7 -0
- package/corpus/templates/analytics/server/lib/analytics-query-catalog.ts +191 -30
- package/corpus/templates/analytics/server/lib/bigquery.ts +11 -1
- package/corpus/templates/analytics/server/lib/notion.ts +15 -4
- package/corpus/templates/analytics/server/plugins/agent-chat.ts +10 -0
- package/corpus/templates/assets/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
- package/corpus/templates/brain/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
- package/corpus/templates/brain/_gitignore +1 -0
- package/corpus/templates/calendar/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
- package/corpus/templates/calendar/_gitignore +1 -0
- package/corpus/templates/chat/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
- package/corpus/templates/chat/_gitignore +1 -0
- package/corpus/templates/clips/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
- package/corpus/templates/clips/.agents/skills/video-sharing/SKILL.md +34 -0
- package/corpus/templates/clips/AGENTS.md +5 -4
- package/corpus/templates/clips/_gitignore +1 -0
- package/corpus/templates/clips/actions/cleanup-transcript.ts +5 -0
- package/corpus/templates/clips/actions/get-recording-insights.ts +44 -8
- package/corpus/templates/clips/actions/get-recording-player-data.ts +39 -70
- package/corpus/templates/clips/actions/list-clip-views.ts +2 -4
- package/corpus/templates/clips/actions/list-recordings.ts +69 -19
- package/corpus/templates/clips/actions/list-viewers.ts +5 -2
- package/corpus/templates/clips/actions/regenerate-summary.ts +5 -1
- package/corpus/templates/clips/actions/request-transcript.ts +28 -1
- package/corpus/templates/clips/app/components/editor/stitch-manager.tsx +21 -1
- package/corpus/templates/clips/app/components/meetings/quick-ask-sidebar.tsx +14 -1
- package/corpus/templates/clips/app/components/player/insights-panel.tsx +8 -20
- package/corpus/templates/clips/app/components/player/recording-views-badge.tsx +335 -0
- package/corpus/templates/clips/app/components/player/video-player.tsx +13 -8
- package/corpus/templates/clips/app/components/sharing/share-ui.tsx +2 -1
- package/corpus/templates/clips/app/i18n/en-US.ts +13 -2
- package/corpus/templates/clips/app/lib/capture-permissions.ts +110 -0
- package/corpus/templates/clips/app/lib/recording-link.ts +32 -0
- package/corpus/templates/clips/app/routes/_app.meetings.$meetingId.tsx +27 -0
- package/corpus/templates/clips/app/routes/r.$recordingId.tsx +46 -15
- package/corpus/templates/clips/app/routes/record.tsx +77 -31
- package/corpus/templates/clips/app/routes/share.$shareId.tsx +42 -31
- package/corpus/templates/clips/changelog/2026-07-24-clip-pages-now-show-a-view-count-with-viewer-avatars-next-to.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-24-clip-summaries-read-like-a-description-you-d-write-yourself-.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-24-clip-view-counts-now-separate-human-views-from-agent-views-s.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-24-clips-actions-can-now-be-called-by-org-service-tokens-so-ext.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-24-clips-no-longer-briefly-shows-a-dock-icon-while-launching.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-24-fixed-owner-and-editor-share-links-redirecting-to-the-record.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-24-meeting-and-note-recordings-now-start-as-a-compact-pill-on-t.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-24-new-clips-now-copy-a-shareable-link-instead-of-the-owner-onl.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-24-opening-a-share-link-as-the-clip-s-owner-now-goes-straight-t.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-24-permissions-and-rewind-controls-now-use-compact-consistent-h.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-24-quitting-the-desktop-app-no-longer-shows-a-false-macos-crash.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-24-screen-recording-permission-errors-now-name-the-exact-app-to.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-24-the-desktop-app-now-copies-a-new-clip-s-share-link-to-your-c.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-24-the-recording-toolbar-now-stays-above-other-apps-including-o.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-24-transcript-captions-now-use-real-speech-timings-instead-of-a.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-24-video-playback-no-longer-stutters-and-replays-the-last-momen.md +6 -0
- package/corpus/templates/clips/chrome-extension/src/background.ts +17 -1
- package/corpus/templates/clips/desktop/package.json +2 -0
- package/corpus/templates/clips/desktop/src/app.tsx +89 -0
- package/corpus/templates/clips/desktop/src/hooks/useMeetingTranscription.ts +9 -3
- package/corpus/templates/clips/desktop/src/lib/audio-meter.ts +51 -0
- package/corpus/templates/clips/desktop/src/lib/native-notification.ts +44 -0
- package/corpus/templates/clips/desktop/src/lib/recording-link.ts +67 -0
- package/corpus/templates/clips/desktop/src/overlays/live-audio-bars.tsx +35 -35
- package/corpus/templates/clips/desktop/src/overlays/live-transcript.tsx +3 -2
- package/corpus/templates/clips/desktop/src/overlays/recording-pill.tsx +47 -46
- package/corpus/templates/clips/desktop/src/styles.css +127 -78
- package/corpus/templates/clips/desktop/src-tauri/Cargo.toml +7 -0
- package/corpus/templates/clips/desktop/src-tauri/Info.plist +6 -0
- package/corpus/templates/clips/desktop/src-tauri/capabilities/default.json +1 -0
- package/corpus/templates/clips/desktop/src-tauri/src/clips/mod.rs +7 -3
- package/corpus/templates/clips/desktop/src-tauri/src/lib.rs +4 -1
- package/corpus/templates/clips/desktop/src-tauri/src/main.rs +8 -0
- package/corpus/templates/clips/desktop/src-tauri/src/recording_indicator.rs +21 -10
- package/corpus/templates/clips/desktop/src-tauri/src/util.rs +40 -0
- package/corpus/templates/clips/server/db/schema.ts +25 -0
- package/corpus/templates/clips/server/lib/agent-views.ts +145 -0
- package/corpus/templates/clips/server/lib/public-agent-context.ts +7 -0
- package/corpus/templates/clips/server/lib/recording-share-grant.ts +79 -0
- package/corpus/templates/clips/server/lib/recordings.ts +51 -3
- package/corpus/templates/clips/server/plugins/db.ts +23 -0
- package/corpus/templates/clips/server/routes/api/public-recording.get.ts +49 -17
- package/corpus/templates/clips/shared/recording-link.ts +43 -0
- package/corpus/templates/clips/shared/share-attribution.ts +4 -0
- package/corpus/templates/clips/shared/share-dashboard-redirect.ts +42 -0
- package/corpus/templates/clips/shared/view-analytics.ts +26 -0
- package/corpus/templates/content/.agents/skills/content/SKILL.md +5 -0
- package/corpus/templates/content/.agents/skills/content/references/local-file-mode.md +135 -0
- package/corpus/templates/content/.agents/skills/document-editing/SKILL.md +12 -0
- package/corpus/templates/content/.agents/skills/document-editing/references/databases.md +238 -0
- package/corpus/templates/content/.agents/skills/document-editing/references/document-behavior.md +91 -0
- package/corpus/templates/content/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
- package/corpus/templates/content/AGENTS.md +62 -583
- package/corpus/templates/content/_gitignore +1 -0
- package/corpus/templates/design/.agents/skills/creative-context/SKILL.md +11 -0
- package/corpus/templates/design/.agents/skills/design-generation/SKILL.md +50 -8
- package/corpus/templates/design/.agents/skills/design-generation/references/code-layers.md +81 -0
- package/corpus/templates/design/.agents/skills/design-generation/references/code-workspace.md +42 -0
- package/corpus/templates/design/.agents/skills/design-generation/references/editor-extensions.md +34 -0
- package/corpus/templates/design/.agents/skills/responsive-breakpoints/SKILL.md +4 -1
- package/corpus/templates/design/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
- package/corpus/templates/design/.agents/skills/visual-edit/SKILL.md +17 -0
- package/corpus/templates/design/.generated/bridge/editor-chrome.generated.ts +8196 -0
- package/corpus/templates/design/.generated/bridge/embedded-wheel.generated.ts +265 -0
- package/corpus/templates/design/.generated/bridge/hit-test.generated.ts +642 -0
- package/corpus/templates/design/.generated/bridge/motion-preview.generated.ts +571 -0
- package/corpus/templates/design/.generated/bridge/nav.generated.ts +91 -0
- package/corpus/templates/design/.generated/bridge/sample.generated.ts +23 -0
- package/corpus/templates/design/.generated/bridge/shader-fill-preview.generated.ts +263 -0
- package/corpus/templates/design/.generated/bridge/shader-runtime.generated.ts +518 -0
- package/corpus/templates/design/.generated/bridge/tweak.generated.ts +20 -0
- package/corpus/templates/design/.generated/bridge/zoom.generated.ts +32 -0
- package/corpus/templates/design/AGENTS.md +88 -503
- package/corpus/templates/design/_gitignore +1 -0
- package/corpus/templates/dispatch/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
- package/corpus/templates/dispatch/_gitignore +1 -0
- package/corpus/templates/dispatch/changelog/2026-07-24-signing-in-now-puts-you-in-your-companys-workspace.md +6 -0
- package/corpus/templates/forms/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
- package/corpus/templates/forms/_gitignore +1 -0
- package/corpus/templates/forms/server/lib/public-form-ssr.ts +2 -2
- package/corpus/templates/macros/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
- package/corpus/templates/macros/_gitignore +1 -0
- package/corpus/templates/mail/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
- package/corpus/templates/mail/_gitignore +1 -0
- package/corpus/templates/plan/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
- package/corpus/templates/plan/_gitignore +1 -0
- package/corpus/templates/slides/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
- package/corpus/templates/slides/_gitignore +1 -0
- package/corpus/templates/slides/server/plugins/db.ts +4 -0
- package/corpus/templates/tasks/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
- package/corpus/templates/tasks/AGENTS.md +1 -1
- package/corpus/templates/tasks/_gitignore +1 -0
- package/dist/a2a/activity.d.ts +4 -1
- package/dist/a2a/activity.d.ts.map +1 -1
- package/dist/a2a/activity.js +27 -16
- package/dist/a2a/activity.js.map +1 -1
- package/dist/agent/engine/builder-engine.d.ts +1 -0
- package/dist/agent/engine/builder-engine.d.ts.map +1 -1
- package/dist/agent/engine/builder-engine.js +31 -4
- package/dist/agent/engine/builder-engine.js.map +1 -1
- package/dist/agent/run-manager.d.ts.map +1 -1
- package/dist/agent/run-manager.js +18 -1
- package/dist/agent/run-manager.js.map +1 -1
- package/dist/agent/run-store.d.ts +1 -0
- package/dist/agent/run-store.d.ts.map +1 -1
- package/dist/agent/run-store.js +2 -1
- package/dist/agent/run-store.js.map +1 -1
- package/dist/agent/types.d.ts +12 -1
- package/dist/agent/types.d.ts.map +1 -1
- package/dist/agent/types.js +21 -1
- package/dist/agent/types.js.map +1 -1
- package/dist/chat-threads/store.d.ts +10 -0
- package/dist/chat-threads/store.d.ts.map +1 -1
- package/dist/chat-threads/store.js +41 -0
- package/dist/chat-threads/store.js.map +1 -1
- package/dist/checkpoints/index.d.ts +1 -0
- package/dist/checkpoints/index.d.ts.map +1 -1
- package/dist/checkpoints/index.js +1 -0
- package/dist/checkpoints/index.js.map +1 -1
- package/dist/checkpoints/route-match.d.ts +8 -0
- package/dist/checkpoints/route-match.d.ts.map +1 -0
- package/dist/checkpoints/route-match.js +13 -0
- package/dist/checkpoints/route-match.js.map +1 -0
- package/dist/cli/create.d.ts +35 -4
- package/dist/cli/create.d.ts.map +1 -1
- package/dist/cli/create.js +69 -19
- package/dist/cli/create.js.map +1 -1
- package/dist/cli/index.js +19 -0
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/template-baseline.d.ts +54 -0
- package/dist/cli/template-baseline.d.ts.map +1 -0
- package/dist/cli/template-baseline.js +334 -0
- package/dist/cli/template-baseline.js.map +1 -0
- package/dist/cli/template-sync.d.ts +57 -0
- package/dist/cli/template-sync.d.ts.map +1 -0
- package/dist/cli/template-sync.js +787 -0
- package/dist/cli/template-sync.js.map +1 -0
- package/dist/cli/templates-meta.d.ts.map +1 -1
- package/dist/cli/templates-meta.js +1 -0
- package/dist/cli/templates-meta.js.map +1 -1
- package/dist/client/AssistantChat.d.ts +2 -1
- package/dist/client/AssistantChat.d.ts.map +1 -1
- package/dist/client/AssistantChat.js +38 -10
- package/dist/client/AssistantChat.js.map +1 -1
- package/dist/client/NewWorkspaceAppFlow.d.ts.map +1 -1
- package/dist/client/NewWorkspaceAppFlow.js +32 -2
- package/dist/client/NewWorkspaceAppFlow.js.map +1 -1
- package/dist/client/chat/message-components.d.ts +20 -0
- package/dist/client/chat/message-components.d.ts.map +1 -1
- package/dist/client/chat/message-components.js +81 -46
- package/dist/client/chat/message-components.js.map +1 -1
- package/dist/client/chat/tool-call-display.d.ts.map +1 -1
- package/dist/client/chat/tool-call-display.js +14 -6
- package/dist/client/chat/tool-call-display.js.map +1 -1
- package/dist/client/error-format.d.ts.map +1 -1
- package/dist/client/error-format.js +13 -0
- package/dist/client/error-format.js.map +1 -1
- package/dist/client/org/OrgSwitcher.d.ts +8 -1
- package/dist/client/org/OrgSwitcher.d.ts.map +1 -1
- package/dist/client/org/OrgSwitcher.js +3 -2
- package/dist/client/org/OrgSwitcher.js.map +1 -1
- package/dist/client/org/TeamPage.d.ts.map +1 -1
- package/dist/client/org/TeamPage.js +1 -1
- package/dist/client/org/TeamPage.js.map +1 -1
- package/dist/client/sse-event-processor.d.ts.map +1 -1
- package/dist/client/sse-event-processor.js +3 -0
- package/dist/client/sse-event-processor.js.map +1 -1
- package/dist/collab/awareness.d.ts +2 -2
- package/dist/collab/awareness.d.ts.map +1 -1
- package/dist/data-widgets/index.d.ts +3 -0
- package/dist/data-widgets/index.d.ts.map +1 -1
- package/dist/data-widgets/index.js +33 -0
- package/dist/data-widgets/index.js.map +1 -1
- package/dist/deploy/build.d.ts.map +1 -1
- package/dist/deploy/build.js +11 -7
- package/dist/deploy/build.js.map +1 -1
- package/dist/eject/provider-api-definitions.d.ts +1 -0
- package/dist/eject/provider-api-definitions.d.ts.map +1 -1
- package/dist/integrations/webhook-handler.d.ts.map +1 -1
- package/dist/integrations/webhook-handler.js +46 -9
- package/dist/integrations/webhook-handler.js.map +1 -1
- package/dist/org/auto-join-domain.d.ts +3 -2
- package/dist/org/auto-join-domain.d.ts.map +1 -1
- package/dist/org/auto-join-domain.js +1 -1
- package/dist/org/auto-join-domain.js.map +1 -1
- package/dist/org/context.d.ts.map +1 -1
- package/dist/org/context.js +84 -28
- package/dist/org/context.js.map +1 -1
- package/dist/org/index.d.ts +1 -0
- package/dist/org/index.d.ts.map +1 -1
- package/dist/org/index.js +1 -0
- package/dist/org/index.js.map +1 -1
- package/dist/org/service-identity.d.ts +43 -0
- package/dist/org/service-identity.d.ts.map +1 -0
- package/dist/org/service-identity.js +34 -0
- package/dist/org/service-identity.js.map +1 -0
- package/dist/provider-api/actions/custom-provider-registration.d.ts +14 -14
- package/dist/provider-api/actions/provider-api.d.ts +13 -11
- package/dist/provider-api/actions/provider-api.d.ts.map +1 -1
- package/dist/provider-api/index.d.ts +4 -0
- package/dist/provider-api/index.d.ts.map +1 -1
- package/dist/provider-api/index.js +17 -1
- package/dist/provider-api/index.js.map +1 -1
- package/dist/resources/handlers.d.ts +1 -1
- package/dist/scripts/docs/search.d.ts.map +1 -1
- package/dist/scripts/docs/search.js +12 -1
- package/dist/scripts/docs/search.js.map +1 -1
- package/dist/server/agent-chat/context-tools.d.ts.map +1 -1
- package/dist/server/agent-chat/context-tools.js +3 -3
- package/dist/server/agent-chat/context-tools.js.map +1 -1
- package/dist/server/agent-chat/framework-prompts.d.ts +8 -3
- package/dist/server/agent-chat/framework-prompts.d.ts.map +1 -1
- package/dist/server/agent-chat/framework-prompts.js +33 -62
- package/dist/server/agent-chat/framework-prompts.js.map +1 -1
- package/dist/server/agent-chat-plugin.d.ts.map +1 -1
- package/dist/server/agent-chat-plugin.js +16 -10
- package/dist/server/agent-chat-plugin.js.map +1 -1
- package/dist/server/agents-bundle.d.ts +18 -0
- package/dist/server/agents-bundle.d.ts.map +1 -1
- package/dist/server/agents-bundle.js +70 -4
- package/dist/server/agents-bundle.js.map +1 -1
- package/dist/server/auth.d.ts.map +1 -1
- package/dist/server/auth.js +4 -3
- package/dist/server/auth.js.map +1 -1
- package/dist/server/builder-browser.d.ts.map +1 -1
- package/dist/server/builder-browser.js +43 -19
- package/dist/server/builder-browser.js.map +1 -1
- package/dist/server/core-routes-plugin.js +2 -2
- package/dist/server/core-routes-plugin.js.map +1 -1
- package/dist/server/credential-provider.d.ts +38 -2
- package/dist/server/credential-provider.d.ts.map +1 -1
- package/dist/server/credential-provider.js +142 -64
- package/dist/server/credential-provider.js.map +1 -1
- package/dist/server/index.d.ts +1 -1
- package/dist/server/index.d.ts.map +1 -1
- package/dist/server/index.js +1 -1
- package/dist/server/index.js.map +1 -1
- package/dist/server/prompts/framework-core-compact.d.ts +1 -1
- package/dist/server/prompts/framework-core-compact.d.ts.map +1 -1
- package/dist/server/prompts/framework-core-compact.js +7 -13
- package/dist/server/prompts/framework-core-compact.js.map +1 -1
- package/dist/server/prompts/framework-core.d.ts +1 -1
- package/dist/server/prompts/framework-core.d.ts.map +1 -1
- package/dist/server/prompts/framework-core.js +10 -21
- package/dist/server/prompts/framework-core.js.map +1 -1
- package/dist/server/prompts/index.d.ts +1 -1
- package/dist/server/prompts/index.d.ts.map +1 -1
- package/dist/server/prompts/index.js +1 -1
- package/dist/server/prompts/index.js.map +1 -1
- package/dist/server/prompts/shared-rules.d.ts +16 -10
- package/dist/server/prompts/shared-rules.d.ts.map +1 -1
- package/dist/server/prompts/shared-rules.js +19 -10
- package/dist/server/prompts/shared-rules.js.map +1 -1
- package/dist/server/ssr-handler.d.ts +1 -1
- package/dist/server/ssr-handler.d.ts.map +1 -1
- package/dist/server/ssr-handler.js +10 -3
- package/dist/server/ssr-handler.js.map +1 -1
- package/dist/settings/user-settings.d.ts.map +1 -1
- package/dist/settings/user-settings.js +13 -1
- package/dist/settings/user-settings.js.map +1 -1
- package/dist/shared/cache-control.d.ts +52 -0
- package/dist/shared/cache-control.d.ts.map +1 -1
- package/dist/shared/cache-control.js +107 -0
- package/dist/shared/cache-control.js.map +1 -1
- package/dist/templates/chat/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
- package/dist/templates/chat/_gitignore +1 -0
- package/dist/templates/default/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
- package/dist/templates/headless/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
- package/dist/templates/workspace-core/.agents/skills/performance/SKILL.md +19 -0
- package/dist/templates/workspace-core/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
- package/dist/templates/workspace-core/.agents/skills/visual-answer/SKILL.md +1 -0
- package/dist/vite/agents-bundle-plugin.d.ts.map +1 -1
- package/dist/vite/agents-bundle-plugin.js +8 -7
- package/dist/vite/agents-bundle-plugin.js.map +1 -1
- package/dist/vite/client.d.ts.map +1 -1
- package/dist/vite/client.js +2 -0
- package/dist/vite/client.js.map +1 -1
- package/docs/content/actions.mdx +2 -2
- package/docs/content/agent-surfaces.mdx +1 -1
- package/docs/content/authentication.mdx +2 -0
- package/docs/content/deployment.mdx +36 -0
- package/docs/content/http-api.mdx +266 -0
- package/docs/content/syncing-template-changes.mdx +159 -0
- package/package.json +4 -3
- package/src/a2a/activity.ts +38 -27
- package/src/agent/engine/builder-engine.ts +35 -4
- package/src/agent/run-manager.ts +20 -1
- package/src/agent/run-store.ts +4 -1
- package/src/agent/types.ts +28 -8
- package/src/chat-threads/store.ts +45 -0
- package/src/checkpoints/index.ts +2 -0
- package/src/checkpoints/route-match.ts +13 -0
- package/src/cli/create.ts +105 -17
- package/src/cli/index.ts +20 -0
- package/src/cli/template-baseline.ts +410 -0
- package/src/cli/template-sync.ts +1004 -0
- package/src/cli/templates-meta.ts +1 -0
- package/src/client/AssistantChat.tsx +38 -12
- package/src/client/NewWorkspaceAppFlow.tsx +75 -10
- package/src/client/chat/message-components.tsx +127 -66
- package/src/client/chat/tool-call-display.tsx +29 -5
- package/src/client/error-format.ts +18 -0
- package/src/client/org/OrgSwitcher.tsx +30 -8
- package/src/client/org/TeamPage.tsx +7 -6
- package/src/client/sse-event-processor.ts +3 -0
- package/src/data-widgets/index.ts +41 -0
- package/src/deploy/build.ts +11 -9
- package/src/integrations/webhook-handler.ts +63 -9
- package/src/org/auto-join-domain.ts +4 -3
- package/src/org/context.ts +108 -39
- package/src/org/index.ts +5 -0
- package/src/org/service-identity.ts +60 -0
- package/src/provider-api/index.ts +22 -1
- package/src/scripts/docs/search.ts +12 -1
- package/src/server/__snapshots__/agent-chat-plugin.surface.spec.ts.snap +25 -36
- package/src/server/agent-chat/context-tools.ts +9 -4
- package/src/server/agent-chat/framework-prompts.ts +38 -66
- package/src/server/agent-chat-plugin.ts +17 -10
- package/src/server/agents-bundle.ts +84 -5
- package/src/server/auth.ts +4 -3
- package/src/server/builder-browser.ts +47 -19
- package/src/server/core-routes-plugin.ts +2 -2
- package/src/server/credential-provider.ts +209 -68
- package/src/server/index.ts +3 -0
- package/src/server/prompts/framework-core-compact.ts +6 -13
- package/src/server/prompts/framework-core.ts +9 -21
- package/src/server/prompts/index.ts +0 -1
- package/src/server/prompts/shared-rules.ts +19 -11
- package/src/server/ssr-handler.ts +13 -2
- package/src/settings/user-settings.ts +13 -1
- package/src/shared/cache-control.ts +141 -0
- package/src/templates/chat/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
- package/src/templates/chat/_gitignore +1 -0
- package/src/templates/default/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
- package/src/templates/headless/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
- package/src/templates/workspace-core/.agents/skills/performance/SKILL.md +19 -0
- package/src/templates/workspace-core/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
- package/src/templates/workspace-core/.agents/skills/visual-answer/SKILL.md +1 -0
- package/src/vite/agents-bundle-plugin.ts +7 -6
- package/src/vite/client.ts +5 -0
|
@@ -0,0 +1,787 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `agent-native template` — pull later upstream template changes into an app
|
|
3
|
+
* that was generated from a first-party template.
|
|
4
|
+
*
|
|
5
|
+
* The model is a real 3-way merge:
|
|
6
|
+
*
|
|
7
|
+
* base = the pristine upstream tree the app was generated from
|
|
8
|
+
* (stored as a git ref, see template-baseline.ts)
|
|
9
|
+
* theirs = the same template re-materialized at a newer ref, through the
|
|
10
|
+
* exact transform pipeline `create` runs
|
|
11
|
+
* ours = the app's working tree
|
|
12
|
+
*
|
|
13
|
+
* Materialization fidelity is the whole feature: any divergence from what
|
|
14
|
+
* `create` produced turns into phantom conflicts on every sync, so this file
|
|
15
|
+
* reuses `create.ts`'s own transforms rather than reimplementing them.
|
|
16
|
+
*/
|
|
17
|
+
import { spawnSync } from "node:child_process";
|
|
18
|
+
import fs from "node:fs";
|
|
19
|
+
import os from "node:os";
|
|
20
|
+
import path from "node:path";
|
|
21
|
+
import { detectWorkspace, _REPO, _TEMPLATES_DIR, _appTitleForScaffold, _copyDir, _downloadGitHubSubdir, _findLocalTemplate, _fixPackageJsonName, _fixWebManifestName, _getCoreDependencyVersion, _getCorePackageVersion, _getDispatchDependencyVersion, _getGitHubTemplateRefCandidates, _getToolkitDependencyVersion, _localTemplateSourceKind, _normalizeTemplateName, _postProcessStandalone, _renameGitignore, _replacePlaceholders, _rewriteNetlifyToml, _rewriteTrackingAppId, _shouldSkipScaffoldEntry, _templateSourceName, } from "./create.js";
|
|
22
|
+
import { appDirtyPaths, baselineDescription, baselineExists, clearBaseline, materializeBaseline, promoteBaseline, resolveBaselineStore, writeBaseline, } from "./template-baseline.js";
|
|
23
|
+
import { workspacifyApp } from "./workspacify.js";
|
|
24
|
+
const defaultIO = {
|
|
25
|
+
out: (message) => console.log(message),
|
|
26
|
+
err: (message) => console.error(message),
|
|
27
|
+
};
|
|
28
|
+
const CONFLICT_MARKER = "<<<<<<<";
|
|
29
|
+
/** Never merged: user secrets, lockfiles, generated output, personal memory. */
|
|
30
|
+
const NEVER_TOUCH_NAMES = new Set([
|
|
31
|
+
".git",
|
|
32
|
+
"learnings.md",
|
|
33
|
+
"pnpm-lock.yaml",
|
|
34
|
+
"package-lock.json",
|
|
35
|
+
"yarn.lock",
|
|
36
|
+
"bun.lockb",
|
|
37
|
+
]);
|
|
38
|
+
/* ─────────────────────────────────────────────────────────────────────────
|
|
39
|
+
* Materialization
|
|
40
|
+
* ───────────────────────────────────────────────────────────────────────── */
|
|
41
|
+
/**
|
|
42
|
+
* Reproduce, in a temp directory, the exact bytes `create` would have written
|
|
43
|
+
* for this (template, ref, app name, shape, workspace scope).
|
|
44
|
+
*/
|
|
45
|
+
export async function materializeTemplate(opts) {
|
|
46
|
+
const dest = opts.destDir ?? fs.mkdtempSync(path.join(os.tmpdir(), "an-template-new-"));
|
|
47
|
+
fs.mkdirSync(dest, { recursive: true });
|
|
48
|
+
const resolved = _normalizeTemplateName(opts.template);
|
|
49
|
+
const sourceTemplate = _templateSourceName(resolved);
|
|
50
|
+
const fallbackRef = _getGitHubTemplateRefCandidates()[0];
|
|
51
|
+
let usedRef;
|
|
52
|
+
let source;
|
|
53
|
+
if (opts.ref === null || resolved === "headless") {
|
|
54
|
+
const local = _findLocalTemplate(resolved === "headless" ? "headless" : sourceTemplate);
|
|
55
|
+
if (!local) {
|
|
56
|
+
throw new Error(`No local copy of the "${resolved}" template is available. Pass --to <ref> to fetch it from GitHub.`);
|
|
57
|
+
}
|
|
58
|
+
_copyDir(local, dest);
|
|
59
|
+
usedRef = opts.ref ?? fallbackRef ?? "unknown";
|
|
60
|
+
source = _localTemplateSourceKind(local);
|
|
61
|
+
}
|
|
62
|
+
else {
|
|
63
|
+
usedRef = await _downloadGitHubSubdir(_REPO, `${_TEMPLATES_DIR}/${sourceTemplate}`, dest, [opts.ref]);
|
|
64
|
+
source = "github";
|
|
65
|
+
}
|
|
66
|
+
const provenance = { templateRef: usedRef, templateSource: source };
|
|
67
|
+
if (opts.shape === "workspace") {
|
|
68
|
+
if (!opts.workspaceRoot || !opts.workspaceCoreName) {
|
|
69
|
+
throw new Error("Workspace apps need a workspace root and shared package name to materialize.");
|
|
70
|
+
}
|
|
71
|
+
_replacePlaceholders(dest, opts.appName, _appTitleForScaffold(opts.appName), path.basename(opts.workspaceRoot));
|
|
72
|
+
_rewriteTrackingAppId(dest, opts.appName, opts.template);
|
|
73
|
+
workspacifyApp({
|
|
74
|
+
appDir: dest,
|
|
75
|
+
appName: opts.appName,
|
|
76
|
+
templateName: opts.template,
|
|
77
|
+
workspaceRoot: opts.workspaceRoot,
|
|
78
|
+
workspaceCoreName: opts.workspaceCoreName,
|
|
79
|
+
coreDependencyVersion: _getCoreDependencyVersion(),
|
|
80
|
+
dispatchDependencyVersion: _getDispatchDependencyVersion(),
|
|
81
|
+
toolkitDependencyVersion: _getToolkitDependencyVersion(),
|
|
82
|
+
});
|
|
83
|
+
_fixPackageJsonName(dest, opts.appName, opts.template, {
|
|
84
|
+
...provenance,
|
|
85
|
+
shape: "workspace",
|
|
86
|
+
});
|
|
87
|
+
_fixWebManifestName(dest, opts.appName, opts.template);
|
|
88
|
+
_rewriteNetlifyToml(dest, opts.appName, "workspace");
|
|
89
|
+
_renameGitignore(dest);
|
|
90
|
+
}
|
|
91
|
+
else {
|
|
92
|
+
_postProcessStandalone(opts.appName, dest, opts.template, provenance);
|
|
93
|
+
}
|
|
94
|
+
return { dir: dest, ref: usedRef, source };
|
|
95
|
+
}
|
|
96
|
+
/* ─────────────────────────────────────────────────────────────────────────
|
|
97
|
+
* Merge
|
|
98
|
+
* ───────────────────────────────────────────────────────────────────────── */
|
|
99
|
+
export function isMergeExcluded(rel) {
|
|
100
|
+
const segments = rel.split("/");
|
|
101
|
+
if (segments[0] === "changelog")
|
|
102
|
+
return true;
|
|
103
|
+
for (const name of segments) {
|
|
104
|
+
if (!name || name === "." || name === "..")
|
|
105
|
+
return true;
|
|
106
|
+
if (NEVER_TOUCH_NAMES.has(name))
|
|
107
|
+
return true;
|
|
108
|
+
if (name.startsWith(".env"))
|
|
109
|
+
return true;
|
|
110
|
+
if (_shouldSkipScaffoldEntry(name))
|
|
111
|
+
return true;
|
|
112
|
+
}
|
|
113
|
+
return false;
|
|
114
|
+
}
|
|
115
|
+
export function listMergeableFiles(root) {
|
|
116
|
+
const found = new Set();
|
|
117
|
+
const walk = (dir, prefix) => {
|
|
118
|
+
let entries;
|
|
119
|
+
try {
|
|
120
|
+
entries = fs.readdirSync(dir, { withFileTypes: true });
|
|
121
|
+
}
|
|
122
|
+
catch {
|
|
123
|
+
return;
|
|
124
|
+
}
|
|
125
|
+
for (const entry of entries) {
|
|
126
|
+
const rel = prefix ? `${prefix}/${entry.name}` : entry.name;
|
|
127
|
+
if (isMergeExcluded(rel))
|
|
128
|
+
continue;
|
|
129
|
+
if (entry.isSymbolicLink())
|
|
130
|
+
continue;
|
|
131
|
+
if (entry.isDirectory())
|
|
132
|
+
walk(path.join(dir, entry.name), rel);
|
|
133
|
+
else if (entry.isFile())
|
|
134
|
+
found.add(rel);
|
|
135
|
+
}
|
|
136
|
+
};
|
|
137
|
+
walk(root, "");
|
|
138
|
+
return found;
|
|
139
|
+
}
|
|
140
|
+
export function mergeTemplateTrees(appDir, baseDir, theirsDir, options = {}) {
|
|
141
|
+
const result = {
|
|
142
|
+
added: [],
|
|
143
|
+
updated: [],
|
|
144
|
+
deleted: [],
|
|
145
|
+
conflicted: [],
|
|
146
|
+
manual: [],
|
|
147
|
+
keptLocal: [],
|
|
148
|
+
};
|
|
149
|
+
const paths = new Set([
|
|
150
|
+
...listMergeableFiles(baseDir),
|
|
151
|
+
...listMergeableFiles(theirsDir),
|
|
152
|
+
...listMergeableFiles(appDir),
|
|
153
|
+
]);
|
|
154
|
+
for (const rel of Array.from(paths).sort()) {
|
|
155
|
+
const oursPath = path.join(appDir, rel);
|
|
156
|
+
if (isLocalSymlink(oursPath)) {
|
|
157
|
+
result.manual.push(`${rel} (local symlink)`);
|
|
158
|
+
continue;
|
|
159
|
+
}
|
|
160
|
+
const base = readFileOrNull(path.join(baseDir, rel));
|
|
161
|
+
const theirs = readFileOrNull(path.join(theirsDir, rel));
|
|
162
|
+
const ours = readFileOrNull(oursPath);
|
|
163
|
+
if (equalBuffers(base, theirs))
|
|
164
|
+
continue;
|
|
165
|
+
if (theirs === null) {
|
|
166
|
+
if (ours === null)
|
|
167
|
+
continue;
|
|
168
|
+
if (equalBuffers(ours, base)) {
|
|
169
|
+
if (!options.dryRun)
|
|
170
|
+
removeFile(oursPath);
|
|
171
|
+
result.deleted.push(rel);
|
|
172
|
+
}
|
|
173
|
+
else {
|
|
174
|
+
result.keptLocal.push(rel);
|
|
175
|
+
}
|
|
176
|
+
continue;
|
|
177
|
+
}
|
|
178
|
+
if (ours === null) {
|
|
179
|
+
if (base === null) {
|
|
180
|
+
if (!options.dryRun)
|
|
181
|
+
writeFile(oursPath, theirs);
|
|
182
|
+
result.added.push(rel);
|
|
183
|
+
}
|
|
184
|
+
else {
|
|
185
|
+
result.manual.push(`${rel} (deleted locally, changed upstream)`);
|
|
186
|
+
}
|
|
187
|
+
continue;
|
|
188
|
+
}
|
|
189
|
+
if (equalBuffers(ours, theirs))
|
|
190
|
+
continue;
|
|
191
|
+
if (equalBuffers(ours, base)) {
|
|
192
|
+
if (!options.dryRun)
|
|
193
|
+
writeFile(oursPath, theirs);
|
|
194
|
+
result.updated.push(rel);
|
|
195
|
+
continue;
|
|
196
|
+
}
|
|
197
|
+
if (!isTextBuffer(ours) || !isTextBuffer(theirs) || !isTextBuffer(base)) {
|
|
198
|
+
result.manual.push(`${rel} (binary changed on both sides)`);
|
|
199
|
+
continue;
|
|
200
|
+
}
|
|
201
|
+
const merged = gitMergeFile(ours, base ?? Buffer.alloc(0), theirs);
|
|
202
|
+
if (!merged) {
|
|
203
|
+
result.manual.push(`${rel} (merge failed)`);
|
|
204
|
+
continue;
|
|
205
|
+
}
|
|
206
|
+
if (!options.dryRun)
|
|
207
|
+
writeFile(oursPath, merged.content);
|
|
208
|
+
if (merged.conflicts > 0)
|
|
209
|
+
result.conflicted.push(rel);
|
|
210
|
+
else
|
|
211
|
+
result.updated.push(rel);
|
|
212
|
+
}
|
|
213
|
+
return result;
|
|
214
|
+
}
|
|
215
|
+
function gitMergeFile(ours, base, theirs) {
|
|
216
|
+
const dir = fs.mkdtempSync(path.join(os.tmpdir(), "an-template-merge-"));
|
|
217
|
+
try {
|
|
218
|
+
const oursFile = path.join(dir, "ours");
|
|
219
|
+
const baseFile = path.join(dir, "base");
|
|
220
|
+
const theirsFile = path.join(dir, "theirs");
|
|
221
|
+
fs.writeFileSync(oursFile, ours);
|
|
222
|
+
fs.writeFileSync(baseFile, base);
|
|
223
|
+
fs.writeFileSync(theirsFile, theirs);
|
|
224
|
+
const res = spawnSync("git", [
|
|
225
|
+
"merge-file",
|
|
226
|
+
"-p",
|
|
227
|
+
"-L",
|
|
228
|
+
"ours",
|
|
229
|
+
"-L",
|
|
230
|
+
"base",
|
|
231
|
+
"-L",
|
|
232
|
+
"theirs",
|
|
233
|
+
oursFile,
|
|
234
|
+
baseFile,
|
|
235
|
+
theirsFile,
|
|
236
|
+
], { maxBuffer: 64 * 1024 * 1024 });
|
|
237
|
+
if (res.status === null || res.status < 0)
|
|
238
|
+
return null;
|
|
239
|
+
return { content: res.stdout, conflicts: res.status };
|
|
240
|
+
}
|
|
241
|
+
finally {
|
|
242
|
+
fs.rmSync(dir, { recursive: true, force: true });
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
/* ─────────────────────────────────────────────────────────────────────────
|
|
246
|
+
* Target resolution
|
|
247
|
+
* ───────────────────────────────────────────────────────────────────────── */
|
|
248
|
+
export function readProvenance(appDir) {
|
|
249
|
+
const pkg = readJson(path.join(appDir, "package.json"));
|
|
250
|
+
const scaffold = pkg?.["agent-native"]?.scaffold;
|
|
251
|
+
if (!scaffold || typeof scaffold !== "object")
|
|
252
|
+
return {};
|
|
253
|
+
return scaffold;
|
|
254
|
+
}
|
|
255
|
+
export function resolveTargets(cwd, appArg) {
|
|
256
|
+
const workspace = detectWorkspace(cwd);
|
|
257
|
+
if (appArg) {
|
|
258
|
+
const candidates = [path.resolve(cwd, appArg)];
|
|
259
|
+
if (workspace)
|
|
260
|
+
candidates.push(path.join(workspace.workspaceRoot, "apps", appArg));
|
|
261
|
+
for (const candidate of candidates) {
|
|
262
|
+
if (fs.existsSync(path.join(candidate, "package.json"))) {
|
|
263
|
+
return [toTarget(candidate)];
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
throw new Error(`No app found for "${appArg}".`);
|
|
267
|
+
}
|
|
268
|
+
const appDir = findAppDir(cwd);
|
|
269
|
+
if (appDir)
|
|
270
|
+
return [toTarget(appDir)];
|
|
271
|
+
if (workspace && path.resolve(cwd) === workspace.workspaceRoot) {
|
|
272
|
+
const appsDir = path.join(workspace.workspaceRoot, "apps");
|
|
273
|
+
if (fs.existsSync(appsDir)) {
|
|
274
|
+
const targets = fs
|
|
275
|
+
.readdirSync(appsDir, { withFileTypes: true })
|
|
276
|
+
.filter((entry) => entry.isDirectory())
|
|
277
|
+
.map((entry) => path.join(appsDir, entry.name))
|
|
278
|
+
.filter((dir) => fs.existsSync(path.join(dir, "package.json")))
|
|
279
|
+
.map((dir) => toTarget(dir));
|
|
280
|
+
if (targets.length > 0)
|
|
281
|
+
return targets;
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
throw new Error("No Agent Native app found. Run from an app directory, or pass an app name from a workspace root.");
|
|
285
|
+
}
|
|
286
|
+
function toTarget(appDir) {
|
|
287
|
+
const resolved = path.resolve(appDir);
|
|
288
|
+
const provenance = readProvenance(resolved);
|
|
289
|
+
const workspace = detectWorkspace(resolved);
|
|
290
|
+
const insideWorkspaceApps = !!workspace &&
|
|
291
|
+
path.dirname(resolved) === path.join(workspace.workspaceRoot, "apps");
|
|
292
|
+
const shape = provenance.shape ?? (insideWorkspaceApps ? "workspace" : "standalone");
|
|
293
|
+
return {
|
|
294
|
+
appDir: resolved,
|
|
295
|
+
appName: readAppName(resolved),
|
|
296
|
+
shape,
|
|
297
|
+
workspaceRoot: workspace?.workspaceRoot,
|
|
298
|
+
workspaceCoreName: workspace?.workspaceCoreName,
|
|
299
|
+
provenance,
|
|
300
|
+
};
|
|
301
|
+
}
|
|
302
|
+
function readAppName(appDir) {
|
|
303
|
+
const pkg = readJson(path.join(appDir, "package.json"));
|
|
304
|
+
const name = typeof pkg?.name === "string" ? pkg.name : "";
|
|
305
|
+
return name || path.basename(appDir);
|
|
306
|
+
}
|
|
307
|
+
function findAppDir(cwd) {
|
|
308
|
+
let dir = path.resolve(cwd);
|
|
309
|
+
for (let i = 0; i < 20; i++) {
|
|
310
|
+
const pkg = readJson(path.join(dir, "package.json"));
|
|
311
|
+
if (pkg) {
|
|
312
|
+
const agentNative = pkg["agent-native"];
|
|
313
|
+
if (agentNative?.workspaceCore)
|
|
314
|
+
return null;
|
|
315
|
+
const deps = (pkg.dependencies ?? {});
|
|
316
|
+
const devDeps = (pkg.devDependencies ?? {});
|
|
317
|
+
if (agentNative?.scaffold ||
|
|
318
|
+
deps["@agent-native/core"] ||
|
|
319
|
+
devDeps["@agent-native/core"]) {
|
|
320
|
+
return dir;
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
const parent = path.dirname(dir);
|
|
324
|
+
if (parent === dir)
|
|
325
|
+
break;
|
|
326
|
+
dir = parent;
|
|
327
|
+
}
|
|
328
|
+
return null;
|
|
329
|
+
}
|
|
330
|
+
/* ─────────────────────────────────────────────────────────────────────────
|
|
331
|
+
* Commands
|
|
332
|
+
* ───────────────────────────────────────────────────────────────────────── */
|
|
333
|
+
export async function runTemplate(args, io = defaultIO) {
|
|
334
|
+
const command = args[0];
|
|
335
|
+
if (!command ||
|
|
336
|
+
command === "help" ||
|
|
337
|
+
command === "--help" ||
|
|
338
|
+
command === "-h") {
|
|
339
|
+
io.out(templateUsage());
|
|
340
|
+
return command ? 0 : 1;
|
|
341
|
+
}
|
|
342
|
+
const rest = args.slice(1);
|
|
343
|
+
const appArg = positionalArgs(rest)[0];
|
|
344
|
+
const flags = {
|
|
345
|
+
to: flagValue(rest, "--to"),
|
|
346
|
+
ref: flagValue(rest, "--ref"),
|
|
347
|
+
template: flagValue(rest, "--template"),
|
|
348
|
+
dryRun: rest.includes("--dry-run"),
|
|
349
|
+
force: rest.includes("--force"),
|
|
350
|
+
};
|
|
351
|
+
let targets;
|
|
352
|
+
try {
|
|
353
|
+
targets = resolveTargets(process.cwd(), appArg);
|
|
354
|
+
}
|
|
355
|
+
catch (err) {
|
|
356
|
+
io.err(err instanceof Error ? err.message : String(err));
|
|
357
|
+
return 1;
|
|
358
|
+
}
|
|
359
|
+
let exitCode = 0;
|
|
360
|
+
for (const target of targets) {
|
|
361
|
+
try {
|
|
362
|
+
const code = await runForTarget(command, target, flags, io);
|
|
363
|
+
if (code !== 0)
|
|
364
|
+
exitCode = code;
|
|
365
|
+
}
|
|
366
|
+
catch (err) {
|
|
367
|
+
io.err(`${target.appName}: ${err instanceof Error ? err.message : String(err)}`);
|
|
368
|
+
exitCode = 1;
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
return exitCode;
|
|
372
|
+
}
|
|
373
|
+
async function runForTarget(command, target, flags, io) {
|
|
374
|
+
switch (command) {
|
|
375
|
+
case "status":
|
|
376
|
+
return statusCommand(target, flags, io);
|
|
377
|
+
case "diff":
|
|
378
|
+
return diffCommand(target, flags, io);
|
|
379
|
+
case "sync":
|
|
380
|
+
return syncCommand(target, flags, io);
|
|
381
|
+
case "baseline":
|
|
382
|
+
return baselineCommand(target, flags, io);
|
|
383
|
+
case "accept":
|
|
384
|
+
return acceptCommand(target, io);
|
|
385
|
+
default:
|
|
386
|
+
io.err(`Unknown template command "${command}".`);
|
|
387
|
+
io.err(templateUsage());
|
|
388
|
+
return 1;
|
|
389
|
+
}
|
|
390
|
+
}
|
|
391
|
+
function templateName(target, flags) {
|
|
392
|
+
const name = flags.template ?? target.provenance.template;
|
|
393
|
+
if (!name) {
|
|
394
|
+
throw new Error(`${target.appName} has no recorded template. Pass --template <name> to record one.`);
|
|
395
|
+
}
|
|
396
|
+
return name;
|
|
397
|
+
}
|
|
398
|
+
async function statusCommand(target, flags, io) {
|
|
399
|
+
const store = resolveBaselineStore(target.appDir);
|
|
400
|
+
const latest = _getGitHubTemplateRefCandidates()[0] ?? "(unknown)";
|
|
401
|
+
const lines = [
|
|
402
|
+
`${target.appName} (${target.shape})`,
|
|
403
|
+
` template: ${target.provenance.template ?? "(unrecorded)"}`,
|
|
404
|
+
` recorded ref: ${target.provenance.templateRef ?? "(unrecorded)"}`,
|
|
405
|
+
` recorded source:${target.provenance.templateSource ? ` ${target.provenance.templateSource}` : " (unrecorded)"}`,
|
|
406
|
+
` latest ref: ${flags.to ?? latest}`,
|
|
407
|
+
` baseline: ${baselineDescription(store, "baseline") ?? "missing — run `agent-native template baseline`"}`,
|
|
408
|
+
];
|
|
409
|
+
const pending = baselineDescription(store, "pending");
|
|
410
|
+
if (pending)
|
|
411
|
+
lines.push(` pending accept: ${pending}`);
|
|
412
|
+
const baseDir = materializeBaseline(store, "baseline");
|
|
413
|
+
if (baseDir) {
|
|
414
|
+
try {
|
|
415
|
+
const local = countLocallyModified(target.appDir, baseDir);
|
|
416
|
+
lines.push(` locally modified files: ${local}`);
|
|
417
|
+
const targetRef = flags.to ?? target.provenance.templateRef ?? latest;
|
|
418
|
+
const theirs = await materializeForTarget(target, flags, targetRef);
|
|
419
|
+
try {
|
|
420
|
+
const changed = countUpstreamChanged(baseDir, theirs.dir);
|
|
421
|
+
lines.push(` upstream-changed files: ${changed} (at ${theirs.ref})`);
|
|
422
|
+
}
|
|
423
|
+
finally {
|
|
424
|
+
fs.rmSync(theirs.dir, { recursive: true, force: true });
|
|
425
|
+
}
|
|
426
|
+
}
|
|
427
|
+
catch (err) {
|
|
428
|
+
lines.push(` upstream-changed files: unavailable (${err instanceof Error ? err.message.split("\n")[0] : String(err)})`);
|
|
429
|
+
}
|
|
430
|
+
finally {
|
|
431
|
+
fs.rmSync(baseDir, { recursive: true, force: true });
|
|
432
|
+
}
|
|
433
|
+
}
|
|
434
|
+
io.out(lines.join("\n"));
|
|
435
|
+
return 0;
|
|
436
|
+
}
|
|
437
|
+
async function diffCommand(target, flags, io) {
|
|
438
|
+
const store = resolveBaselineStore(target.appDir);
|
|
439
|
+
const baseDir = materializeBaseline(store, "baseline");
|
|
440
|
+
if (!baseDir) {
|
|
441
|
+
io.err(`${target.appName}: no baseline recorded. Run \`agent-native template baseline ${target.appName}\` first.`);
|
|
442
|
+
return 1;
|
|
443
|
+
}
|
|
444
|
+
const theirs = await materializeForTarget(target, flags, flags.to ?? _getGitHubTemplateRefCandidates()[0] ?? null);
|
|
445
|
+
try {
|
|
446
|
+
io.out(renderTreeDiff(baseDir, theirs.dir));
|
|
447
|
+
return 0;
|
|
448
|
+
}
|
|
449
|
+
finally {
|
|
450
|
+
fs.rmSync(baseDir, { recursive: true, force: true });
|
|
451
|
+
fs.rmSync(theirs.dir, { recursive: true, force: true });
|
|
452
|
+
}
|
|
453
|
+
}
|
|
454
|
+
async function syncCommand(target, flags, io) {
|
|
455
|
+
const store = resolveBaselineStore(target.appDir);
|
|
456
|
+
const baseDir = materializeBaseline(store, "baseline");
|
|
457
|
+
if (!baseDir) {
|
|
458
|
+
io.err(`${target.appName}: no baseline recorded. Run \`agent-native template baseline ${target.appName}\` first.`);
|
|
459
|
+
return 1;
|
|
460
|
+
}
|
|
461
|
+
const dirty = appDirtyPaths(store);
|
|
462
|
+
if (dirty.length > 0 && !flags.force && !flags.dryRun) {
|
|
463
|
+
fs.rmSync(baseDir, { recursive: true, force: true });
|
|
464
|
+
io.err("Sync refused because the app directory has uncommitted changes. Review this diff and preserve your edits before syncing, or pass --force.");
|
|
465
|
+
for (const line of dirty.slice(0, 20))
|
|
466
|
+
io.err(` ${line}`);
|
|
467
|
+
if (dirty.length > 20)
|
|
468
|
+
io.err(` … ${dirty.length - 20} more`);
|
|
469
|
+
return 1;
|
|
470
|
+
}
|
|
471
|
+
const theirs = await materializeForTarget(target, flags, flags.to ?? _getGitHubTemplateRefCandidates()[0] ?? null);
|
|
472
|
+
try {
|
|
473
|
+
const result = mergeTemplateTrees(target.appDir, baseDir, theirs.dir, {
|
|
474
|
+
dryRun: flags.dryRun,
|
|
475
|
+
});
|
|
476
|
+
io.out(formatMergeResult(target, theirs.ref, result, flags.dryRun));
|
|
477
|
+
if (flags.dryRun)
|
|
478
|
+
return 0;
|
|
479
|
+
const meta = {
|
|
480
|
+
template: templateName(target, flags),
|
|
481
|
+
templateRef: theirs.ref,
|
|
482
|
+
coreVersion: _getCorePackageVersion(),
|
|
483
|
+
};
|
|
484
|
+
if (result.conflicted.length === 0 && result.manual.length === 0) {
|
|
485
|
+
const written = writeBaseline(store, theirs.dir, "baseline", meta);
|
|
486
|
+
clearBaseline(store, "pending");
|
|
487
|
+
io.out(`Baseline advanced to ${written.location}.`);
|
|
488
|
+
reportRefspecs(written.configuredRefspecs, io);
|
|
489
|
+
return 0;
|
|
490
|
+
}
|
|
491
|
+
const written = writeBaseline(store, theirs.dir, "pending", meta);
|
|
492
|
+
reportRefspecs(written.configuredRefspecs, io);
|
|
493
|
+
io.out("");
|
|
494
|
+
io.out(`Baseline not advanced — resolve the items above, then run:\n agent-native template accept ${target.appName}`);
|
|
495
|
+
return 1;
|
|
496
|
+
}
|
|
497
|
+
finally {
|
|
498
|
+
fs.rmSync(baseDir, { recursive: true, force: true });
|
|
499
|
+
fs.rmSync(theirs.dir, { recursive: true, force: true });
|
|
500
|
+
}
|
|
501
|
+
}
|
|
502
|
+
async function baselineCommand(target, flags, io) {
|
|
503
|
+
const store = resolveBaselineStore(target.appDir);
|
|
504
|
+
const name = templateName(target, flags);
|
|
505
|
+
const ref = flags.ref ??
|
|
506
|
+
target.provenance.templateRef ??
|
|
507
|
+
_getGitHubTemplateRefCandidates()[0] ??
|
|
508
|
+
null;
|
|
509
|
+
const materialized = await materializeTemplate({
|
|
510
|
+
appName: target.appName,
|
|
511
|
+
template: name,
|
|
512
|
+
ref: useLocalTemplate(target, ref) ? null : ref,
|
|
513
|
+
shape: target.shape,
|
|
514
|
+
workspaceRoot: target.workspaceRoot,
|
|
515
|
+
workspaceCoreName: target.workspaceCoreName,
|
|
516
|
+
});
|
|
517
|
+
try {
|
|
518
|
+
const written = writeBaseline(store, materialized.dir, "baseline", {
|
|
519
|
+
template: name,
|
|
520
|
+
templateRef: materialized.ref,
|
|
521
|
+
coreVersion: _getCorePackageVersion(),
|
|
522
|
+
});
|
|
523
|
+
backfillProvenance(target, name, materialized);
|
|
524
|
+
io.out(`${target.appName}: baseline recorded at ${written.location} (${name} @ ${materialized.ref}).`);
|
|
525
|
+
reportRefspecs(written.configuredRefspecs, io);
|
|
526
|
+
return 0;
|
|
527
|
+
}
|
|
528
|
+
finally {
|
|
529
|
+
fs.rmSync(materialized.dir, { recursive: true, force: true });
|
|
530
|
+
}
|
|
531
|
+
}
|
|
532
|
+
function acceptCommand(target, io) {
|
|
533
|
+
const store = resolveBaselineStore(target.appDir);
|
|
534
|
+
if (!baselineExists(store, "pending")) {
|
|
535
|
+
io.err(`${target.appName}: nothing to accept — no pending sync recorded.`);
|
|
536
|
+
return 1;
|
|
537
|
+
}
|
|
538
|
+
const markers = findConflictMarkers(target.appDir);
|
|
539
|
+
if (markers.length > 0) {
|
|
540
|
+
io.err(`${target.appName}: accept refused because conflict markers remain. Resolve them first:`);
|
|
541
|
+
for (const file of markers.slice(0, 20))
|
|
542
|
+
io.err(` ${file}`);
|
|
543
|
+
if (markers.length > 20)
|
|
544
|
+
io.err(` … ${markers.length - 20} more`);
|
|
545
|
+
return 1;
|
|
546
|
+
}
|
|
547
|
+
promoteBaseline(store, "pending", "baseline");
|
|
548
|
+
io.out(`${target.appName}: baseline advanced to the last synced template tree.`);
|
|
549
|
+
return 0;
|
|
550
|
+
}
|
|
551
|
+
/* ─────────────────────────────────────────────────────────────────────────
|
|
552
|
+
* Helpers
|
|
553
|
+
* ───────────────────────────────────────────────────────────────────────── */
|
|
554
|
+
function useLocalTemplate(target, ref) {
|
|
555
|
+
if (!ref)
|
|
556
|
+
return true;
|
|
557
|
+
const source = target.provenance.templateSource;
|
|
558
|
+
if (source !== "bundled" && source !== "local-checkout")
|
|
559
|
+
return false;
|
|
560
|
+
return ref === target.provenance.templateRef;
|
|
561
|
+
}
|
|
562
|
+
async function materializeForTarget(target, flags, ref) {
|
|
563
|
+
return materializeTemplate({
|
|
564
|
+
appName: target.appName,
|
|
565
|
+
template: templateName(target, flags),
|
|
566
|
+
ref: useLocalTemplate(target, ref) ? null : ref,
|
|
567
|
+
shape: target.shape,
|
|
568
|
+
workspaceRoot: target.workspaceRoot,
|
|
569
|
+
workspaceCoreName: target.workspaceCoreName,
|
|
570
|
+
});
|
|
571
|
+
}
|
|
572
|
+
function backfillProvenance(target, template, materialized) {
|
|
573
|
+
const pkgPath = path.join(target.appDir, "package.json");
|
|
574
|
+
const pkg = readJson(pkgPath);
|
|
575
|
+
if (!pkg)
|
|
576
|
+
return;
|
|
577
|
+
const agentNative = pkg["agent-native"] && typeof pkg["agent-native"] === "object"
|
|
578
|
+
? pkg["agent-native"]
|
|
579
|
+
: {};
|
|
580
|
+
const scaffold = agentNative.scaffold && typeof agentNative.scaffold === "object"
|
|
581
|
+
? agentNative.scaffold
|
|
582
|
+
: {};
|
|
583
|
+
agentNative.scaffold = {
|
|
584
|
+
...scaffold,
|
|
585
|
+
template: scaffold.template ?? template,
|
|
586
|
+
templateRef: materialized.ref,
|
|
587
|
+
templateSource: materialized.source,
|
|
588
|
+
coreVersion: _getCorePackageVersion(),
|
|
589
|
+
shape: target.shape,
|
|
590
|
+
};
|
|
591
|
+
pkg["agent-native"] = agentNative;
|
|
592
|
+
fs.writeFileSync(pkgPath, `${JSON.stringify(pkg, null, 2)}\n`);
|
|
593
|
+
}
|
|
594
|
+
function countLocallyModified(appDir, baseDir) {
|
|
595
|
+
let count = 0;
|
|
596
|
+
for (const rel of listMergeableFiles(baseDir)) {
|
|
597
|
+
const base = readFileOrNull(path.join(baseDir, rel));
|
|
598
|
+
const ours = readFileOrNull(path.join(appDir, rel));
|
|
599
|
+
if (!equalBuffers(base, ours))
|
|
600
|
+
count++;
|
|
601
|
+
}
|
|
602
|
+
return count;
|
|
603
|
+
}
|
|
604
|
+
function countUpstreamChanged(baseDir, theirsDir) {
|
|
605
|
+
const paths = new Set([
|
|
606
|
+
...listMergeableFiles(baseDir),
|
|
607
|
+
...listMergeableFiles(theirsDir),
|
|
608
|
+
]);
|
|
609
|
+
let count = 0;
|
|
610
|
+
for (const rel of paths) {
|
|
611
|
+
const base = readFileOrNull(path.join(baseDir, rel));
|
|
612
|
+
const theirs = readFileOrNull(path.join(theirsDir, rel));
|
|
613
|
+
if (!equalBuffers(base, theirs))
|
|
614
|
+
count++;
|
|
615
|
+
}
|
|
616
|
+
return count;
|
|
617
|
+
}
|
|
618
|
+
function renderTreeDiff(baseDir, theirsDir) {
|
|
619
|
+
const staging = fs.mkdtempSync(path.join(os.tmpdir(), "an-template-diff-"));
|
|
620
|
+
try {
|
|
621
|
+
const a = path.join(staging, "a");
|
|
622
|
+
const b = path.join(staging, "b");
|
|
623
|
+
copyMergeable(baseDir, a);
|
|
624
|
+
copyMergeable(theirsDir, b);
|
|
625
|
+
const res = spawnSync("git", [
|
|
626
|
+
"diff",
|
|
627
|
+
"--no-index",
|
|
628
|
+
"--src-prefix=upstream-base/",
|
|
629
|
+
"--dst-prefix=upstream-new/",
|
|
630
|
+
"--",
|
|
631
|
+
"a",
|
|
632
|
+
"b",
|
|
633
|
+
], { cwd: staging, encoding: "utf-8", maxBuffer: 128 * 1024 * 1024 });
|
|
634
|
+
const output = (res.stdout ?? "").toString();
|
|
635
|
+
// Only the staging dir names leak into headers; content lines cannot
|
|
636
|
+
// contain the prefixed form, so this rewrite is safe.
|
|
637
|
+
return output.trim()
|
|
638
|
+
? output
|
|
639
|
+
.replaceAll("upstream-base/a/", "upstream-base/")
|
|
640
|
+
.replaceAll("upstream-new/b/", "upstream-new/")
|
|
641
|
+
: "No upstream changes.";
|
|
642
|
+
}
|
|
643
|
+
finally {
|
|
644
|
+
fs.rmSync(staging, { recursive: true, force: true });
|
|
645
|
+
}
|
|
646
|
+
}
|
|
647
|
+
function copyMergeable(from, to) {
|
|
648
|
+
fs.mkdirSync(to, { recursive: true });
|
|
649
|
+
for (const rel of listMergeableFiles(from)) {
|
|
650
|
+
const dest = path.join(to, rel);
|
|
651
|
+
fs.mkdirSync(path.dirname(dest), { recursive: true });
|
|
652
|
+
fs.copyFileSync(path.join(from, rel), dest);
|
|
653
|
+
}
|
|
654
|
+
}
|
|
655
|
+
function findConflictMarkers(appDir) {
|
|
656
|
+
const hits = [];
|
|
657
|
+
for (const rel of listMergeableFiles(appDir)) {
|
|
658
|
+
const buf = readFileOrNull(path.join(appDir, rel));
|
|
659
|
+
if (!buf || !isTextBuffer(buf))
|
|
660
|
+
continue;
|
|
661
|
+
if (buf.toString("utf-8").includes(`${CONFLICT_MARKER} `))
|
|
662
|
+
hits.push(rel);
|
|
663
|
+
}
|
|
664
|
+
return hits;
|
|
665
|
+
}
|
|
666
|
+
function formatMergeResult(target, ref, result, dryRun) {
|
|
667
|
+
const lines = [
|
|
668
|
+
`${target.appName}: ${dryRun ? "would sync" : "synced"} template at ${ref}`,
|
|
669
|
+
` added: ${result.added.length}`,
|
|
670
|
+
` updated: ${result.updated.length}`,
|
|
671
|
+
` deleted: ${result.deleted.length}`,
|
|
672
|
+
` conflicted: ${result.conflicted.length}`,
|
|
673
|
+
];
|
|
674
|
+
for (const [label, items] of [
|
|
675
|
+
["added", result.added],
|
|
676
|
+
["updated", result.updated],
|
|
677
|
+
["deleted", result.deleted],
|
|
678
|
+
["conflicted", result.conflicted],
|
|
679
|
+
["manual", result.manual],
|
|
680
|
+
["kept local (deleted upstream)", result.keptLocal],
|
|
681
|
+
]) {
|
|
682
|
+
if (items.length === 0)
|
|
683
|
+
continue;
|
|
684
|
+
lines.push(` ${label}:`);
|
|
685
|
+
for (const item of items)
|
|
686
|
+
lines.push(` ${item}`);
|
|
687
|
+
}
|
|
688
|
+
return lines.join("\n");
|
|
689
|
+
}
|
|
690
|
+
function reportRefspecs(configured, io) {
|
|
691
|
+
if (configured.length === 0)
|
|
692
|
+
return;
|
|
693
|
+
io.out(`Configured ${configured.join(" and ")} to carry refs/agent-native/* so the baseline survives clone and push.`);
|
|
694
|
+
}
|
|
695
|
+
const VALUE_FLAGS = new Set(["--to", "--ref", "--template"]);
|
|
696
|
+
/** A flag's value must never be mistaken for the [app] positional. */
|
|
697
|
+
function positionalArgs(args) {
|
|
698
|
+
const out = [];
|
|
699
|
+
for (let i = 0; i < args.length; i++) {
|
|
700
|
+
const arg = args[i];
|
|
701
|
+
if (arg.startsWith("-")) {
|
|
702
|
+
if (VALUE_FLAGS.has(arg))
|
|
703
|
+
i++;
|
|
704
|
+
continue;
|
|
705
|
+
}
|
|
706
|
+
out.push(arg);
|
|
707
|
+
}
|
|
708
|
+
return out;
|
|
709
|
+
}
|
|
710
|
+
function flagValue(args, flag) {
|
|
711
|
+
const index = args.indexOf(flag);
|
|
712
|
+
if (index >= 0 && args[index + 1])
|
|
713
|
+
return args[index + 1];
|
|
714
|
+
const inline = args.find((arg) => arg.startsWith(`${flag}=`));
|
|
715
|
+
return inline?.slice(flag.length + 1);
|
|
716
|
+
}
|
|
717
|
+
function readJson(file) {
|
|
718
|
+
try {
|
|
719
|
+
return JSON.parse(fs.readFileSync(file, "utf-8"));
|
|
720
|
+
}
|
|
721
|
+
catch {
|
|
722
|
+
return null;
|
|
723
|
+
}
|
|
724
|
+
}
|
|
725
|
+
function readFileOrNull(file) {
|
|
726
|
+
try {
|
|
727
|
+
const stat = fs.lstatSync(file);
|
|
728
|
+
if (!stat.isFile())
|
|
729
|
+
return null;
|
|
730
|
+
return fs.readFileSync(file);
|
|
731
|
+
}
|
|
732
|
+
catch {
|
|
733
|
+
return null;
|
|
734
|
+
}
|
|
735
|
+
}
|
|
736
|
+
function isLocalSymlink(file) {
|
|
737
|
+
try {
|
|
738
|
+
return fs.lstatSync(file).isSymbolicLink();
|
|
739
|
+
}
|
|
740
|
+
catch {
|
|
741
|
+
return false;
|
|
742
|
+
}
|
|
743
|
+
}
|
|
744
|
+
function writeFile(file, content) {
|
|
745
|
+
fs.mkdirSync(path.dirname(file), { recursive: true });
|
|
746
|
+
fs.writeFileSync(file, content);
|
|
747
|
+
}
|
|
748
|
+
function removeFile(file) {
|
|
749
|
+
fs.rmSync(file, { force: true });
|
|
750
|
+
}
|
|
751
|
+
function equalBuffers(a, b) {
|
|
752
|
+
if (a === null || b === null)
|
|
753
|
+
return a === b;
|
|
754
|
+
return a.equals(b);
|
|
755
|
+
}
|
|
756
|
+
function isTextBuffer(buf) {
|
|
757
|
+
if (buf === null)
|
|
758
|
+
return true;
|
|
759
|
+
const isUtf8 = Buffer
|
|
760
|
+
.isUtf8;
|
|
761
|
+
if (isUtf8)
|
|
762
|
+
return isUtf8(buf) && !buf.includes(0);
|
|
763
|
+
return !buf.includes(0);
|
|
764
|
+
}
|
|
765
|
+
function templateUsage() {
|
|
766
|
+
return [
|
|
767
|
+
"agent-native template <command> [app] [options]",
|
|
768
|
+
"",
|
|
769
|
+
"Pull later upstream first-party template changes into a generated app",
|
|
770
|
+
"with a real 3-way merge against the tree it was scaffolded from.",
|
|
771
|
+
"",
|
|
772
|
+
"Commands:",
|
|
773
|
+
" status [app] Recorded ref, latest ref, baseline health, change counts",
|
|
774
|
+
" diff [app] [--to <ref>] Unified diff of what upstream changed (read-only)",
|
|
775
|
+
" sync [app] [--to <ref>] 3-way merge upstream changes into the app",
|
|
776
|
+
" [--dry-run] [--force]",
|
|
777
|
+
" baseline [app] Record a baseline for an app scaffolded before",
|
|
778
|
+
" provenance existed [--ref <ref>] [--template <name>]",
|
|
779
|
+
" accept [app] Advance the baseline after resolving conflicts",
|
|
780
|
+
"",
|
|
781
|
+
"With no [app], operates on the current app, or on every app in a workspace",
|
|
782
|
+
"when run from the workspace root. --to defaults to the ref matching the",
|
|
783
|
+
"installed @agent-native/core, so `agent-native upgrade` then",
|
|
784
|
+
"`agent-native template sync` is the coherent story.",
|
|
785
|
+
].join("\n");
|
|
786
|
+
}
|
|
787
|
+
//# sourceMappingURL=template-sync.js.map
|