@agent-native/core 0.145.4 → 0.145.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/corpus/README.md +1 -1
- package/corpus/templates/analytics/.agents/skills/actions/SKILL.md +18 -0
- package/corpus/templates/analytics/.agents/skills/agent-native-toolkit/SKILL.md +5 -0
- package/corpus/templates/analytics/.agents/skills/dashboard-management/SKILL.md +17 -1
- package/corpus/templates/analytics/.agents/skills/delegate-to-agent/SKILL.md +45 -47
- package/corpus/templates/analytics/.agents/skills/frontend-design/SKILL.md +1 -0
- package/corpus/templates/analytics/.agents/skills/gong/SKILL.md +22 -3
- package/corpus/templates/analytics/.agents/skills/turn-into-app/SKILL.md +76 -23
- package/corpus/templates/analytics/.agents/skills/turn-into-app/agents/openai.yaml +2 -2
- package/corpus/templates/analytics/.agents/skills/turn-into-app/references/fresh-project.md +64 -0
- package/corpus/templates/analytics/AGENTS.md +2 -1
- package/corpus/templates/analytics/actions/account-deep-dive.ts +83 -47
- package/corpus/templates/analytics/actions/create-dashboard-folder.ts +27 -0
- package/corpus/templates/analytics/actions/gong-calls.ts +3 -3
- package/corpus/templates/analytics/actions/list-dashboard-folders.ts +26 -0
- package/corpus/templates/analytics/actions/list-sql-dashboards.ts +1 -0
- package/corpus/templates/analytics/actions/set-dashboard-folder.ts +26 -0
- package/corpus/templates/analytics/app/components/ProviderCorpusJobNotifier.tsx +18 -3
- package/corpus/templates/analytics/app/components/layout/CommandPalette.tsx +6 -4
- package/corpus/templates/analytics/app/components/layout/Header.tsx +1 -0
- package/corpus/templates/analytics/app/components/layout/NewDashboardDialog.tsx +12 -2
- package/corpus/templates/analytics/app/components/layout/Sidebar.tsx +35 -20
- package/corpus/templates/analytics/app/global.css +17 -0
- package/corpus/templates/analytics/app/hooks/use-dashboard-revisions.ts +29 -15
- package/corpus/templates/analytics/app/hooks/use-dashboard-views.ts +15 -3
- package/corpus/templates/analytics/app/i18n-data.ts +296 -0
- package/corpus/templates/analytics/app/lib/prefetch-keys.ts +23 -2
- package/corpus/templates/analytics/app/pages/DashboardOverview.tsx +642 -0
- package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/index.tsx +66 -31
- package/corpus/templates/analytics/app/root.tsx +4 -0
- package/corpus/templates/analytics/app/routes/dashboards._index.tsx +5 -1
- package/corpus/templates/analytics/changelog/2026-08-07-added-a-dashboards-overview-with-personal-and-shared-folders.md +6 -0
- package/corpus/templates/analytics/changelog/2026-08-07-analytics-tracking-and-chat-startup-no-longer-emit-avoidable.md +6 -0
- package/corpus/templates/analytics/changelog/2026-08-07-dashboard-panels-now-load-custom-api-data-programs-reliably.md +6 -0
- package/corpus/templates/analytics/changelog/2026-08-07-gong-searches-conserve-api-quota-and-report-incomplete-coverage.md +6 -0
- package/corpus/templates/analytics/changelog/2026-08-07-searchable-dashboards-make-personal-and-shared-folders-easie.md +6 -0
- package/corpus/templates/analytics/netlify.toml +3 -0
- package/corpus/templates/analytics/scripts/emit-netlify-dashboard-report-cron.ts +112 -0
- package/corpus/templates/analytics/server/db/index.ts +12 -0
- package/corpus/templates/analytics/server/db/schema.ts +14 -0
- package/corpus/templates/analytics/server/jobs/analytics-rollup-backfill.ts +4 -0
- package/corpus/templates/analytics/server/lib/agent-chat-plan-mode.ts +1 -0
- package/corpus/templates/analytics/server/lib/analytics-query-catalog.ts +85 -15
- package/corpus/templates/analytics/server/lib/dashboard-folders-store.ts +168 -0
- package/corpus/templates/analytics/server/lib/dashboard-panel-query.ts +9 -4
- package/corpus/templates/analytics/server/lib/dashboards-store.ts +116 -1
- package/corpus/templates/analytics/server/lib/first-party-analytics-rollups.ts +4 -8
- package/corpus/templates/analytics/server/lib/gong.ts +139 -78
- package/corpus/templates/analytics/server/plugins/db.ts +55 -15
- package/corpus/templates/analytics/server/plugins/session-replay-retention-jobs.ts +6 -2
- package/corpus/templates/analytics/server/routes/api/session-replay/retention.post.ts +65 -0
- package/corpus/templates/assets/.agents/skills/actions/SKILL.md +18 -0
- package/corpus/templates/assets/.agents/skills/agent-native-toolkit/SKILL.md +5 -0
- package/corpus/templates/assets/.agents/skills/delegate-to-agent/SKILL.md +45 -47
- package/corpus/templates/assets/.agents/skills/frontend-design/SKILL.md +1 -0
- package/corpus/templates/assets/.agents/skills/turn-into-app/SKILL.md +76 -23
- package/corpus/templates/assets/.agents/skills/turn-into-app/agents/openai.yaml +2 -2
- package/corpus/templates/assets/.agents/skills/turn-into-app/references/fresh-project.md +64 -0
- package/corpus/templates/brain/.agents/skills/actions/SKILL.md +18 -0
- package/corpus/templates/brain/.agents/skills/agent-native-toolkit/SKILL.md +5 -0
- package/corpus/templates/brain/.agents/skills/delegate-to-agent/SKILL.md +45 -47
- package/corpus/templates/brain/.agents/skills/frontend-design/SKILL.md +1 -0
- package/corpus/templates/brain/.agents/skills/turn-into-app/SKILL.md +76 -23
- package/corpus/templates/brain/.agents/skills/turn-into-app/agents/openai.yaml +2 -2
- package/corpus/templates/brain/.agents/skills/turn-into-app/references/fresh-project.md +64 -0
- package/corpus/templates/calendar/.agents/skills/actions/SKILL.md +18 -0
- package/corpus/templates/calendar/.agents/skills/agent-native-toolkit/SKILL.md +5 -0
- package/corpus/templates/calendar/.agents/skills/delegate-to-agent/SKILL.md +45 -47
- package/corpus/templates/calendar/.agents/skills/frontend-design/SKILL.md +1 -0
- package/corpus/templates/calendar/.agents/skills/turn-into-app/SKILL.md +76 -23
- package/corpus/templates/calendar/.agents/skills/turn-into-app/agents/openai.yaml +2 -2
- package/corpus/templates/calendar/.agents/skills/turn-into-app/references/fresh-project.md +64 -0
- package/corpus/templates/chat/.agents/skills/actions/SKILL.md +18 -0
- package/corpus/templates/chat/.agents/skills/agent-native-toolkit/SKILL.md +5 -0
- package/corpus/templates/chat/.agents/skills/delegate-to-agent/SKILL.md +45 -47
- package/corpus/templates/chat/.agents/skills/frontend-design/SKILL.md +1 -0
- package/corpus/templates/chat/.agents/skills/turn-into-app/SKILL.md +76 -23
- package/corpus/templates/chat/.agents/skills/turn-into-app/agents/openai.yaml +2 -2
- package/corpus/templates/chat/.agents/skills/turn-into-app/references/fresh-project.md +64 -0
- package/corpus/templates/chat/.env.example +3 -0
- package/corpus/templates/chat/AGENTS.md +4 -0
- package/corpus/templates/clips/.agents/skills/actions/SKILL.md +18 -0
- package/corpus/templates/clips/.agents/skills/agent-native-toolkit/SKILL.md +5 -0
- package/corpus/templates/clips/.agents/skills/delegate-to-agent/SKILL.md +45 -47
- package/corpus/templates/clips/.agents/skills/frontend-design/SKILL.md +1 -0
- package/corpus/templates/clips/.agents/skills/turn-into-app/SKILL.md +76 -23
- package/corpus/templates/clips/.agents/skills/turn-into-app/agents/openai.yaml +2 -2
- package/corpus/templates/clips/.agents/skills/turn-into-app/references/fresh-project.md +64 -0
- package/corpus/templates/clips/actions/lib/audio-only-transcription.ts +4 -0
- package/corpus/templates/clips/actions/request-transcript.ts +52 -3
- package/corpus/templates/clips/app/components/editor/editor-layout.tsx +8 -3
- package/corpus/templates/clips/app/components/editor/waveform.tsx +2 -1
- package/corpus/templates/clips/app/components/library/search-bar.tsx +1 -1
- package/corpus/templates/clips/app/components/recorder/recorder-engine.ts +3 -10
- package/corpus/templates/clips/app/global.css +9 -0
- package/corpus/templates/clips/app/routes/r.$recordingId.tsx +1 -0
- package/corpus/templates/clips/changelog/2026-08-07-screen-recordings-now-capture-tab-and-system-audio-even-when.md +6 -0
- package/corpus/templates/clips/changelog/2026-08-07-transcription-now-retries-transient-cloud-failures-automatic.md +6 -0
- package/corpus/templates/clips/desktop/src-tauri/src/silence_detector.rs +10 -11
- package/corpus/templates/clips/server/db/schema.ts +7 -0
- package/corpus/templates/clips/server/plugins/db.ts +8 -0
- package/corpus/templates/clips/shared/recording-capture.ts +38 -0
- package/corpus/templates/clips/shared/transcript-failure.ts +89 -0
- package/corpus/templates/content/.agents/skills/actions/SKILL.md +18 -0
- package/corpus/templates/content/.agents/skills/agent-native-toolkit/SKILL.md +5 -0
- package/corpus/templates/content/.agents/skills/delegate-to-agent/SKILL.md +45 -47
- package/corpus/templates/content/.agents/skills/frontend-design/SKILL.md +1 -0
- package/corpus/templates/content/.agents/skills/turn-into-app/SKILL.md +76 -23
- package/corpus/templates/content/.agents/skills/turn-into-app/agents/openai.yaml +2 -2
- package/corpus/templates/content/.agents/skills/turn-into-app/references/fresh-project.md +64 -0
- package/corpus/templates/content/.env.example +9 -3
- package/corpus/templates/content/app/components/sidebar/DocumentSidebar.tsx +1 -0
- package/corpus/templates/content/changelog/2026-08-07-collapsed-sidebar-utility-buttons-stay-anchored-at-the-botto.md +6 -0
- package/corpus/templates/crm/.agents/skills/agent-native-toolkit/SKILL.md +5 -0
- package/corpus/templates/crm/.agents/skills/turn-into-app/SKILL.md +76 -23
- package/corpus/templates/crm/.agents/skills/turn-into-app/agents/openai.yaml +2 -2
- package/corpus/templates/crm/.agents/skills/turn-into-app/references/fresh-project.md +64 -0
- package/corpus/templates/design/.agents/skills/actions/SKILL.md +18 -0
- package/corpus/templates/design/.agents/skills/agent-native-toolkit/SKILL.md +5 -0
- package/corpus/templates/design/.agents/skills/delegate-to-agent/SKILL.md +45 -47
- package/corpus/templates/design/.agents/skills/frontend-design/SKILL.md +1 -0
- package/corpus/templates/design/.agents/skills/turn-into-app/SKILL.md +76 -23
- package/corpus/templates/design/.agents/skills/turn-into-app/agents/openai.yaml +2 -2
- package/corpus/templates/design/.agents/skills/turn-into-app/references/fresh-project.md +64 -0
- package/corpus/templates/design/actions/view-screen.ts +1 -0
- package/corpus/templates/design/app/hooks/useDesignHotkeys.ts +14 -1
- package/corpus/templates/design/changelog/2026-08-07-cmd-c-now-copies-selected-text-in-the-agent-panel-instead-of.md +6 -0
- package/corpus/templates/design/changelog/2026-08-07-real-time-voice-can-now-read-the-current-selection-and-edit-.md +6 -0
- package/corpus/templates/design/server/lib/reprompt-action-guard.ts +7 -3
- package/corpus/templates/dispatch/.agents/skills/actions/SKILL.md +18 -0
- package/corpus/templates/dispatch/.agents/skills/agent-native-toolkit/SKILL.md +5 -0
- package/corpus/templates/dispatch/.agents/skills/delegate-to-agent/SKILL.md +45 -47
- package/corpus/templates/dispatch/.agents/skills/frontend-design/SKILL.md +1 -0
- package/corpus/templates/dispatch/.agents/skills/turn-into-app/SKILL.md +76 -23
- package/corpus/templates/dispatch/.agents/skills/turn-into-app/agents/openai.yaml +2 -2
- package/corpus/templates/dispatch/.agents/skills/turn-into-app/references/fresh-project.md +64 -0
- package/corpus/templates/factory/.agents/skills/actions/SKILL.md +18 -0
- package/corpus/templates/factory/.agents/skills/agent-native-toolkit/SKILL.md +5 -0
- package/corpus/templates/factory/.agents/skills/delegate-to-agent/SKILL.md +45 -47
- package/corpus/templates/factory/.agents/skills/frontend-design/SKILL.md +1 -0
- package/corpus/templates/factory/.agents/skills/turn-into-app/SKILL.md +76 -23
- package/corpus/templates/factory/.agents/skills/turn-into-app/agents/openai.yaml +2 -2
- package/corpus/templates/factory/.agents/skills/turn-into-app/references/fresh-project.md +64 -0
- package/corpus/templates/factory/actions/babysit-agent-native-pull-request.ts +279 -0
- package/corpus/templates/factory/actions/get-factory-automation-health.ts +23 -4
- package/corpus/templates/factory/app/components/factory/FactoryCanvas.tsx +1 -1
- package/corpus/templates/factory/app/routes/factory.tsx +21 -3
- package/corpus/templates/factory/changelog/2026-08-07-factory-can-keep-builder-bot-pull-requests-moving-by-request.md +6 -0
- package/corpus/templates/factory/server/lib/require-factory-automation.ts +1 -0
- package/corpus/templates/factory/server/plugins/agent-chat.ts +4 -1
- package/corpus/templates/factory/server/plugins/factory-scheduler-job.ts +81 -12
- package/corpus/templates/factory/server/triage/github-client.ts +31 -0
- package/corpus/templates/factory/server/triage/pr-babysit.ts +75 -1
- package/corpus/templates/forms/.agents/skills/actions/SKILL.md +18 -0
- package/corpus/templates/forms/.agents/skills/agent-native-toolkit/SKILL.md +5 -0
- package/corpus/templates/forms/.agents/skills/delegate-to-agent/SKILL.md +45 -47
- package/corpus/templates/forms/.agents/skills/frontend-design/SKILL.md +1 -0
- package/corpus/templates/forms/.agents/skills/turn-into-app/SKILL.md +76 -23
- package/corpus/templates/forms/.agents/skills/turn-into-app/agents/openai.yaml +2 -2
- package/corpus/templates/forms/.agents/skills/turn-into-app/references/fresh-project.md +64 -0
- package/corpus/templates/macros/.agents/skills/agent-native-toolkit/SKILL.md +5 -0
- package/corpus/templates/macros/.agents/skills/frontend-design/SKILL.md +1 -0
- package/corpus/templates/macros/.agents/skills/turn-into-app/SKILL.md +76 -23
- package/corpus/templates/macros/.agents/skills/turn-into-app/agents/openai.yaml +2 -2
- package/corpus/templates/macros/.agents/skills/turn-into-app/references/fresh-project.md +64 -0
- package/corpus/templates/mail/.agents/skills/actions/SKILL.md +18 -0
- package/corpus/templates/mail/.agents/skills/agent-native-toolkit/SKILL.md +5 -0
- package/corpus/templates/mail/.agents/skills/delegate-to-agent/SKILL.md +45 -47
- package/corpus/templates/mail/.agents/skills/frontend-design/SKILL.md +1 -0
- package/corpus/templates/mail/.agents/skills/turn-into-app/SKILL.md +76 -23
- package/corpus/templates/mail/.agents/skills/turn-into-app/agents/openai.yaml +2 -2
- package/corpus/templates/mail/.agents/skills/turn-into-app/references/fresh-project.md +64 -0
- package/corpus/templates/plan/.agents/skills/actions/SKILL.md +18 -0
- package/corpus/templates/plan/.agents/skills/agent-native-toolkit/SKILL.md +5 -0
- package/corpus/templates/plan/.agents/skills/delegate-to-agent/SKILL.md +45 -47
- package/corpus/templates/plan/.agents/skills/frontend-design/SKILL.md +1 -0
- package/corpus/templates/plan/.agents/skills/turn-into-app/SKILL.md +76 -23
- package/corpus/templates/plan/.agents/skills/turn-into-app/agents/openai.yaml +2 -2
- package/corpus/templates/plan/.agents/skills/turn-into-app/references/fresh-project.md +64 -0
- package/corpus/templates/plan/app/pages/PlansPage.tsx +2 -1
- package/corpus/templates/plan/changelog/2026-08-07-inline-help-icons-now-stay-visually-balanced-with-nearby-tex.md +6 -0
- package/corpus/templates/slides/.agents/skills/actions/SKILL.md +18 -0
- package/corpus/templates/slides/.agents/skills/agent-native-toolkit/SKILL.md +5 -0
- package/corpus/templates/slides/.agents/skills/delegate-to-agent/SKILL.md +45 -47
- package/corpus/templates/slides/.agents/skills/frontend-design/SKILL.md +1 -0
- package/corpus/templates/slides/.agents/skills/turn-into-app/SKILL.md +76 -23
- package/corpus/templates/slides/.agents/skills/turn-into-app/agents/openai.yaml +2 -2
- package/corpus/templates/slides/.agents/skills/turn-into-app/references/fresh-project.md +64 -0
- package/corpus/templates/slides/.env.example +5 -0
- package/corpus/templates/slides/changelog/2026-08-07-fixed-generated-slides-briefly-disappearing-while-they-are-b.md +6 -0
- package/corpus/templates/slides/server/plugins/collab.ts +20 -8
- package/corpus/templates/tasks/.agents/skills/actions/SKILL.md +18 -0
- package/corpus/templates/tasks/.agents/skills/agent-native-toolkit/SKILL.md +5 -0
- package/corpus/templates/tasks/.agents/skills/delegate-to-agent/SKILL.md +45 -47
- package/corpus/templates/tasks/.agents/skills/frontend-design/SKILL.md +1 -0
- package/corpus/templates/tasks/.agents/skills/turn-into-app/SKILL.md +76 -23
- package/corpus/templates/tasks/.agents/skills/turn-into-app/agents/openai.yaml +2 -2
- package/corpus/templates/tasks/.agents/skills/turn-into-app/references/fresh-project.md +64 -0
- package/corpus/templates/tasks/.env.example +3 -0
- package/dist/agent/production-agent.js +24 -3
- package/dist/client/AgentPanel.d.ts +6 -0
- package/dist/client/AgentPanel.js +176 -30
- package/dist/client/AssistantChat.d.ts +2 -0
- package/dist/client/AssistantChat.js +4 -1
- package/dist/client/ConnectBuilderCard.js +6 -11
- package/dist/client/MultiTabAssistantChat.js +1 -1
- package/dist/client/RuntimeConfigNotice.d.ts +1 -0
- package/dist/client/RuntimeConfigNotice.js +94 -0
- package/dist/client/agent-chat/index.d.ts +1 -1
- package/dist/client/agent-chat/index.js +1 -1
- package/dist/client/agent-chat-adapter.js +85 -4
- package/dist/client/agent-page/AgentTabsPage.js +1 -1
- package/dist/client/agent-sidebar-state.d.ts +6 -0
- package/dist/client/agent-sidebar-state.js +25 -0
- package/dist/client/app-providers.js +2 -1
- package/dist/client/assistant-ui-recovery.js +1 -1
- package/dist/client/chat/index.d.ts +1 -1
- package/dist/client/chat/index.js +1 -1
- package/dist/client/chat/markdown-renderer.d.ts +2 -1
- package/dist/client/chat/markdown-renderer.js +48 -2
- package/dist/client/chat/message-components.d.ts +6 -0
- package/dist/client/chat/message-components.js +182 -53
- package/dist/client/chat/tool-call-display.d.ts +16 -4
- package/dist/client/chat/tool-call-display.js +225 -18
- package/dist/client/extensions/ExtensionsSidebarSection.js +1 -1
- package/dist/client/frame-protocol.d.ts +4 -0
- package/dist/client/i18n.js +9 -0
- package/dist/client/integrations/IntegrationsPanel.js +2 -5
- package/dist/client/onboarding/FirstRunOnboarding.js +2 -3
- package/dist/client/org/TeamPage.js +49 -6
- package/dist/client/org/hooks.d.ts +7 -2
- package/dist/client/org/hooks.js +11 -4
- package/dist/client/resources/McpConnectionSuggestion.js +2 -3
- package/dist/client/resources/McpIntegrationDialog.js +2 -16
- package/dist/client/resources/McpIntegrationLogo.d.ts +11 -0
- package/dist/client/resources/McpIntegrationLogo.js +14 -0
- package/dist/client/resources/ResourceTree.js +1 -1
- package/dist/client/resources/mcp-integration-logos.d.ts +1 -0
- package/dist/client/resources/mcp-integration-logos.js +47 -18
- package/dist/client/settings/useBuilderStatus.js +6 -0
- package/dist/client/ui/index.d.ts +1 -0
- package/dist/client/ui/index.js +1 -0
- package/dist/collab/struct-routes.d.ts +1 -1
- package/dist/config.d.ts +26 -3
- package/dist/config.js +106 -14
- package/dist/db/ddl-guard.d.ts +15 -2
- package/dist/db/ddl-guard.js +53 -5
- package/dist/jobs/scheduler.js +7 -0
- package/dist/localization/default-messages.d.ts +17 -0
- package/dist/localization/default-messages.js +17 -0
- package/dist/mcp/oauth-client-metadata.js +5 -1
- package/dist/mcp/oauth-route.d.ts +5 -4
- package/dist/mcp/oauth-route.js +25 -9
- package/dist/mcp/server.d.ts +1 -1
- package/dist/mcp/server.js +9 -10
- package/dist/notifications/routes.d.ts +3 -3
- package/dist/org/handlers.d.ts +1 -0
- package/dist/org/handlers.js +17 -2
- package/dist/provider-api/actions/custom-provider-registration.d.ts +9 -9
- package/dist/provider-api/actions/provider-api.d.ts +7 -7
- package/dist/provider-api/corpus-jobs.d.ts +12 -2
- package/dist/provider-api/corpus-jobs.js +31 -1
- package/dist/provider-api/index.d.ts +2 -0
- package/dist/provider-api/index.js +7 -1
- package/dist/secrets/routes.d.ts +6 -6
- package/dist/server/agent-chat/recurring-jobs-runtime.d.ts +1 -1
- package/dist/server/agent-chat/recurring-jobs-runtime.js +14 -2
- package/dist/server/agent-chat/script-entries.js +12 -1
- package/dist/server/agent-chat-plugin.js +2 -2
- package/dist/server/auth.d.ts +1 -0
- package/dist/server/auth.js +85 -1
- package/dist/server/better-auth-instance.d.ts +9 -0
- package/dist/server/better-auth-instance.js +25 -11
- package/dist/server/core-routes-plugin.d.ts +7 -0
- package/dist/server/core-routes-plugin.js +51 -5
- package/dist/server/create-server.js +23 -2
- package/dist/server/db-pressure.d.ts +38 -0
- package/dist/server/db-pressure.js +147 -0
- package/dist/server/index.d.ts +1 -0
- package/dist/server/index.js +1 -0
- package/dist/server/legacy-auth-migration.d.ts +10 -0
- package/dist/server/legacy-auth-migration.js +37 -0
- package/dist/server/onboarding-html.js +206 -2
- package/dist/server/poll.d.ts +26 -0
- package/dist/server/poll.js +108 -13
- package/dist/server/realtime-voice.d.ts +2 -1
- package/dist/server/realtime-voice.js +38 -56
- package/dist/server/short-lived-token.d.ts +43 -0
- package/dist/server/short-lived-token.js +74 -0
- package/dist/server/ssr-handler.js +4 -1
- package/dist/shared/index.d.ts +1 -0
- package/dist/shared/index.js +1 -0
- package/dist/shared/runtime-config.d.ts +44 -0
- package/dist/shared/runtime-config.js +284 -0
- package/dist/styles/agent-native.css +48 -1
- package/dist/templates/chat/.agents/skills/actions/SKILL.md +18 -0
- package/dist/templates/chat/.agents/skills/agent-native-toolkit/SKILL.md +5 -0
- package/dist/templates/chat/.agents/skills/delegate-to-agent/SKILL.md +45 -47
- package/dist/templates/chat/.agents/skills/frontend-design/SKILL.md +1 -0
- package/dist/templates/chat/.agents/skills/turn-into-app/SKILL.md +76 -23
- package/dist/templates/chat/.agents/skills/turn-into-app/agents/openai.yaml +2 -2
- package/dist/templates/chat/.agents/skills/turn-into-app/references/fresh-project.md +64 -0
- package/dist/templates/chat/.env.example +3 -0
- package/dist/templates/chat/AGENTS.md +4 -0
- package/dist/templates/default/.agents/skills/actions/SKILL.md +18 -0
- package/dist/templates/default/.agents/skills/agent-native-toolkit/SKILL.md +5 -0
- package/dist/templates/default/.agents/skills/delegate-to-agent/SKILL.md +45 -47
- package/dist/templates/default/.agents/skills/frontend-design/SKILL.md +1 -0
- package/dist/templates/default/.agents/skills/turn-into-app/SKILL.md +76 -23
- package/dist/templates/default/.agents/skills/turn-into-app/agents/openai.yaml +2 -2
- package/dist/templates/default/.agents/skills/turn-into-app/references/fresh-project.md +64 -0
- package/dist/templates/default/AGENTS.md +6 -1
- package/dist/templates/default/app/i18n/ar-SA.ts +6 -0
- package/dist/templates/default/app/i18n/de-DE.ts +6 -0
- package/dist/templates/default/app/i18n/en-US.ts +6 -0
- package/dist/templates/default/app/i18n/es-ES.ts +6 -0
- package/dist/templates/default/app/i18n/fr-FR.ts +6 -0
- package/dist/templates/default/app/i18n/hi-IN.ts +6 -0
- package/dist/templates/default/app/i18n/ja-JP.ts +6 -0
- package/dist/templates/default/app/i18n/ko-KR.ts +6 -0
- package/dist/templates/default/app/i18n/pt-BR.ts +6 -0
- package/dist/templates/default/app/i18n/zh-CN.ts +6 -0
- package/dist/templates/default/app/i18n/zh-TW.ts +6 -0
- package/dist/templates/headless/.agents/skills/actions/SKILL.md +18 -0
- package/dist/templates/headless/.agents/skills/agent-native-toolkit/SKILL.md +5 -0
- package/dist/templates/headless/.agents/skills/turn-into-app/SKILL.md +76 -23
- package/dist/templates/headless/.agents/skills/turn-into-app/agents/openai.yaml +2 -2
- package/dist/templates/headless/.agents/skills/turn-into-app/references/fresh-project.md +64 -0
- package/dist/templates/workspace-core/.agents/skills/actions/SKILL.md +18 -0
- package/dist/templates/workspace-core/.agents/skills/agent-native-toolkit/SKILL.md +5 -0
- package/dist/templates/workspace-core/.agents/skills/delegate-to-agent/SKILL.md +45 -47
- package/dist/templates/workspace-core/.agents/skills/frontend-design/SKILL.md +1 -0
- package/dist/templates/workspace-core/.agents/skills/turn-into-app/SKILL.md +76 -23
- package/dist/templates/workspace-core/.agents/skills/turn-into-app/agents/openai.yaml +2 -2
- package/dist/templates/workspace-core/.agents/skills/turn-into-app/references/fresh-project.md +64 -0
- package/dist/templates/workspace-core/.agents/skills/workspace-conventions/SKILL.md +4 -0
- package/dist/templates/workspace-core/.agents/skills/writing-agent-instructions/SKILL.md +8 -0
- package/dist/templates/workspace-core/AGENTS.md +7 -2
- package/dist/templates/workspace-root/AGENTS.md +5 -0
- package/dist/vite/client.d.ts +3 -3
- package/dist/vite/client.js +47 -1
- package/dist/vite/index.d.ts +1 -1
- package/docs/content/agent-native-config.mdx +240 -139
- package/docs/content/authentication.mdx +17 -0
- package/docs/content/deployment.mdx +19 -14
- package/docs/content/drop-in-agent.mdx +19 -2
- package/docs/content/environment-variables.mdx +63 -38
- package/docs/content/getting-started-actions.mdx +15 -6
- package/docs/content/getting-started-database.mdx +14 -10
- package/docs/content/getting-started-pages.mdx +32 -35
- package/docs/content/getting-started.mdx +7 -6
- package/package.json +2 -2
- package/src/templates/chat/.agents/skills/actions/SKILL.md +18 -0
- package/src/templates/chat/.agents/skills/agent-native-toolkit/SKILL.md +5 -0
- package/src/templates/chat/.agents/skills/delegate-to-agent/SKILL.md +45 -47
- package/src/templates/chat/.agents/skills/frontend-design/SKILL.md +1 -0
- package/src/templates/chat/.agents/skills/turn-into-app/SKILL.md +76 -23
- package/src/templates/chat/.agents/skills/turn-into-app/agents/openai.yaml +2 -2
- package/src/templates/chat/.agents/skills/turn-into-app/references/fresh-project.md +64 -0
- package/src/templates/chat/.env.example +3 -0
- package/src/templates/chat/AGENTS.md +4 -0
- package/src/templates/default/.agents/skills/actions/SKILL.md +18 -0
- package/src/templates/default/.agents/skills/agent-native-toolkit/SKILL.md +5 -0
- package/src/templates/default/.agents/skills/delegate-to-agent/SKILL.md +45 -47
- package/src/templates/default/.agents/skills/frontend-design/SKILL.md +1 -0
- package/src/templates/default/.agents/skills/turn-into-app/SKILL.md +76 -23
- package/src/templates/default/.agents/skills/turn-into-app/agents/openai.yaml +2 -2
- package/src/templates/default/.agents/skills/turn-into-app/references/fresh-project.md +64 -0
- package/src/templates/default/AGENTS.md +6 -1
- package/src/templates/default/app/i18n/ar-SA.ts +6 -0
- package/src/templates/default/app/i18n/de-DE.ts +6 -0
- package/src/templates/default/app/i18n/en-US.ts +6 -0
- package/src/templates/default/app/i18n/es-ES.ts +6 -0
- package/src/templates/default/app/i18n/fr-FR.ts +6 -0
- package/src/templates/default/app/i18n/hi-IN.ts +6 -0
- package/src/templates/default/app/i18n/ja-JP.ts +6 -0
- package/src/templates/default/app/i18n/ko-KR.ts +6 -0
- package/src/templates/default/app/i18n/pt-BR.ts +6 -0
- package/src/templates/default/app/i18n/zh-CN.ts +6 -0
- package/src/templates/default/app/i18n/zh-TW.ts +6 -0
- package/src/templates/headless/.agents/skills/actions/SKILL.md +18 -0
- package/src/templates/headless/.agents/skills/agent-native-toolkit/SKILL.md +5 -0
- package/src/templates/headless/.agents/skills/turn-into-app/SKILL.md +76 -23
- package/src/templates/headless/.agents/skills/turn-into-app/agents/openai.yaml +2 -2
- package/src/templates/headless/.agents/skills/turn-into-app/references/fresh-project.md +64 -0
- package/src/templates/workspace-core/.agents/skills/actions/SKILL.md +18 -0
- package/src/templates/workspace-core/.agents/skills/agent-native-toolkit/SKILL.md +5 -0
- package/src/templates/workspace-core/.agents/skills/delegate-to-agent/SKILL.md +45 -47
- package/src/templates/workspace-core/.agents/skills/frontend-design/SKILL.md +1 -0
- package/src/templates/workspace-core/.agents/skills/turn-into-app/SKILL.md +76 -23
- package/src/templates/workspace-core/.agents/skills/turn-into-app/agents/openai.yaml +2 -2
- package/src/templates/workspace-core/.agents/skills/turn-into-app/references/fresh-project.md +64 -0
- package/src/templates/workspace-core/.agents/skills/workspace-conventions/SKILL.md +4 -0
- package/src/templates/workspace-core/.agents/skills/writing-agent-instructions/SKILL.md +8 -0
- package/src/templates/workspace-core/AGENTS.md +7 -2
- package/src/templates/workspace-root/AGENTS.md +5 -0
- package/corpus/templates/dispatch/app/routes/admin.apps.$appId.tsx +0 -1
- package/corpus/templates/dispatch/app/routes/admin.apps.tsx +0 -1
|
@@ -0,0 +1,279 @@
|
|
|
1
|
+
import { defineAction } from "@agent-native/core/action";
|
|
2
|
+
import { and, eq } from "drizzle-orm";
|
|
3
|
+
import { z } from "zod";
|
|
4
|
+
|
|
5
|
+
import { resolveConnectorSecret } from "../server/connectors/credentials.js";
|
|
6
|
+
import { getDb } from "../server/db/index.js";
|
|
7
|
+
import { triageConfig, triageItems } from "../server/db/schema.js";
|
|
8
|
+
import { requireFactoryAutomation } from "../server/lib/require-factory-automation.js";
|
|
9
|
+
import {
|
|
10
|
+
requireWorkspaceMember,
|
|
11
|
+
workspaceMemberIdentityFromContext,
|
|
12
|
+
} from "../server/lib/require-workspace-member.js";
|
|
13
|
+
import { createAiServicesGitReadClient } from "../server/triage/ai-services-git.js";
|
|
14
|
+
import { createGitHubClient } from "../server/triage/github-client.js";
|
|
15
|
+
import {
|
|
16
|
+
metadataString,
|
|
17
|
+
parseTriageMetadata,
|
|
18
|
+
serializeTriageMetadata,
|
|
19
|
+
} from "../server/triage/metadata.js";
|
|
20
|
+
import {
|
|
21
|
+
babysitFingerprint,
|
|
22
|
+
DEFAULT_BABYSIT_BOT_AUTHORS,
|
|
23
|
+
reconcileBabysitState,
|
|
24
|
+
shouldBabysitBuilderBotPullRequest,
|
|
25
|
+
} from "../server/triage/pr-babysit.js";
|
|
26
|
+
import { detectOwnerOwnedArea } from "../server/triage/pr-policy.js";
|
|
27
|
+
|
|
28
|
+
const QUIET_PERIOD_MS = 20 * 60_000;
|
|
29
|
+
const MIN_COMMENT_INTERVAL_MS = 90_000;
|
|
30
|
+
const BUILDER_BOT_REQUEST =
|
|
31
|
+
"@builderio-bot look at latest PR feedback and fix anything you agree with. Be skeptical. Reply to every comment (directly on the comment thread of each comment) if you fixed it or not and why. then check back every 2 minutes on a loop and see if any new feedback posted, until at least 20 minutes go by without any new feedback posted we want to address, including making sure CI passes too and no merge conflicts (make sure code is mergeable)";
|
|
32
|
+
|
|
33
|
+
function requiredAiServicesEnv(
|
|
34
|
+
name: "BUILDER_AI_SERVICES_URL" | "BUILDER_PROJECT_ID",
|
|
35
|
+
): string {
|
|
36
|
+
const value =
|
|
37
|
+
name === "BUILDER_AI_SERVICES_URL"
|
|
38
|
+
? process.env.BUILDER_AI_SERVICES_URL // guard:allow-env-credential - non-secret deployment endpoint
|
|
39
|
+
: process.env.BUILDER_PROJECT_ID; // guard:allow-env-credential - non-secret deployment project id
|
|
40
|
+
if (!value) throw new Error(`${name} is required for PR babysitting.`);
|
|
41
|
+
return value;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
function parseTimestamp(value: string | undefined): number | null {
|
|
45
|
+
if (!value) return null;
|
|
46
|
+
const parsed = Date.parse(value);
|
|
47
|
+
return Number.isFinite(parsed) ? parsed : null;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
function repositoryRef(value: string): { owner: string; repo: string } {
|
|
51
|
+
const match = /^([^/\s]+)\/([^/\s]+)$/.exec(value.trim());
|
|
52
|
+
if (!match)
|
|
53
|
+
throw new Error("Repository must use the owner/repository format.");
|
|
54
|
+
return { owner: match[1], repo: match[2] };
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
async function updateBabysitMetadata(
|
|
58
|
+
itemId: string,
|
|
59
|
+
orgId: string,
|
|
60
|
+
patch: Record<string, unknown>,
|
|
61
|
+
): Promise<void> {
|
|
62
|
+
const db = getDb();
|
|
63
|
+
const item = (
|
|
64
|
+
await db
|
|
65
|
+
.select({ metadataJson: triageItems.metadataJson })
|
|
66
|
+
.from(triageItems)
|
|
67
|
+
.where(and(eq(triageItems.id, itemId), eq(triageItems.orgId, orgId)))
|
|
68
|
+
.limit(1)
|
|
69
|
+
)[0];
|
|
70
|
+
if (!item) throw new Error("Factory item disappeared during PR babysitting.");
|
|
71
|
+
const metadata = parseTriageMetadata(item.metadataJson);
|
|
72
|
+
Object.assign(metadata, patch);
|
|
73
|
+
await db
|
|
74
|
+
.update(triageItems)
|
|
75
|
+
.set({
|
|
76
|
+
metadataJson: serializeTriageMetadata(metadata),
|
|
77
|
+
updatedAt: new Date().toISOString(),
|
|
78
|
+
})
|
|
79
|
+
.where(and(eq(triageItems.id, itemId), eq(triageItems.orgId, orgId)));
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
export default defineAction({
|
|
83
|
+
description:
|
|
84
|
+
"Watch one builder-io-bot pull request, post the bounded feedback-fix request when CI, mergeability, or review feedback needs work, and stop after 20 quiet minutes. The action never merges or approves.",
|
|
85
|
+
schema: z.object({
|
|
86
|
+
itemId: z.string().min(1),
|
|
87
|
+
}),
|
|
88
|
+
http: false,
|
|
89
|
+
run: async ({ itemId }, context) => {
|
|
90
|
+
const { userEmail, orgId } = await requireWorkspaceMember(
|
|
91
|
+
workspaceMemberIdentityFromContext(context),
|
|
92
|
+
);
|
|
93
|
+
await requireFactoryAutomation(context, { userEmail, orgId }, "prBabysit");
|
|
94
|
+
|
|
95
|
+
const db = getDb();
|
|
96
|
+
const item = (
|
|
97
|
+
await db
|
|
98
|
+
.select()
|
|
99
|
+
.from(triageItems)
|
|
100
|
+
.where(and(eq(triageItems.id, itemId), eq(triageItems.orgId, orgId)))
|
|
101
|
+
.limit(1)
|
|
102
|
+
)[0];
|
|
103
|
+
if (!item) throw new Error("Factory item not found for PR babysitting.");
|
|
104
|
+
if (
|
|
105
|
+
item.source !== "github" ||
|
|
106
|
+
!item.repository ||
|
|
107
|
+
!item.pullRequestNumber
|
|
108
|
+
) {
|
|
109
|
+
return {
|
|
110
|
+
ok: true,
|
|
111
|
+
action: "skipped",
|
|
112
|
+
reason: "Item is not a pull request.",
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
const configuredRepository = (
|
|
117
|
+
await db
|
|
118
|
+
.select({ repository: triageConfig.repository })
|
|
119
|
+
.from(triageConfig)
|
|
120
|
+
.where(and(eq(triageConfig.id, orgId), eq(triageConfig.orgId, orgId)))
|
|
121
|
+
.limit(1)
|
|
122
|
+
)[0]?.repository;
|
|
123
|
+
if (
|
|
124
|
+
!configuredRepository ||
|
|
125
|
+
configuredRepository.trim() !== item.repository.trim()
|
|
126
|
+
) {
|
|
127
|
+
throw new Error(
|
|
128
|
+
"PR babysitting is restricted to the configured Factory repository.",
|
|
129
|
+
);
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
const repository = repositoryRef(item.repository);
|
|
133
|
+
const github = createGitHubClient({ ownerEmail: userEmail, orgId });
|
|
134
|
+
const pullRequest = await github.getPullRequestSummary(
|
|
135
|
+
repository,
|
|
136
|
+
item.pullRequestNumber,
|
|
137
|
+
);
|
|
138
|
+
if (pullRequest.state !== "open" || pullRequest.draft) {
|
|
139
|
+
await updateBabysitMetadata(itemId, orgId, {
|
|
140
|
+
prBabysitState: "closed-or-draft",
|
|
141
|
+
prBabysitLastCheckedAt: new Date().toISOString(),
|
|
142
|
+
});
|
|
143
|
+
return { ok: true, action: "skipped", reason: "PR is closed or draft." };
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
const ownerOwnedArea = detectOwnerOwnedArea([
|
|
147
|
+
item.repository,
|
|
148
|
+
pullRequest.title,
|
|
149
|
+
pullRequest.body,
|
|
150
|
+
]);
|
|
151
|
+
if (ownerOwnedArea) {
|
|
152
|
+
await updateBabysitMetadata(itemId, orgId, {
|
|
153
|
+
prBabysitState: "owner-managed",
|
|
154
|
+
prBabysitOwnerArea: ownerOwnedArea,
|
|
155
|
+
prBabysitLastCheckedAt: new Date().toISOString(),
|
|
156
|
+
});
|
|
157
|
+
return {
|
|
158
|
+
ok: true,
|
|
159
|
+
action: "skipped",
|
|
160
|
+
reason: `${ownerOwnedArea} is owner-managed.`,
|
|
161
|
+
};
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
const privateKey = await resolveConnectorSecret(
|
|
165
|
+
"BUILDER_PRIVATE_KEY",
|
|
166
|
+
userEmail,
|
|
167
|
+
{ orgId },
|
|
168
|
+
);
|
|
169
|
+
if (!privateKey) {
|
|
170
|
+
throw new Error(
|
|
171
|
+
"BUILDER_PRIVATE_KEY is required to read PR feedback for babysitting.",
|
|
172
|
+
);
|
|
173
|
+
}
|
|
174
|
+
const snapshot = await createAiServicesGitReadClient({
|
|
175
|
+
baseUrl: requiredAiServicesEnv("BUILDER_AI_SERVICES_URL"),
|
|
176
|
+
authorization: `Bearer ${privateKey.startsWith("bpk-") ? privateKey : `bpk-${privateKey}`}`,
|
|
177
|
+
}).fetchPullRequest({
|
|
178
|
+
projectId: requiredAiServicesEnv("BUILDER_PROJECT_ID"),
|
|
179
|
+
repo: item.repository,
|
|
180
|
+
pullRequestNumber: item.pullRequestNumber,
|
|
181
|
+
});
|
|
182
|
+
if (snapshot.headSha !== pullRequest.headSha) {
|
|
183
|
+
throw new Error(
|
|
184
|
+
`PR evidence is stale: GitHub reports ${pullRequest.headSha}, ai-services reports ${snapshot.headSha}.`,
|
|
185
|
+
);
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
const proposal = reconcileBabysitState({
|
|
189
|
+
comments: snapshot.comments,
|
|
190
|
+
checks: snapshot.checks,
|
|
191
|
+
commentsTruncated: snapshot.commentsTruncated,
|
|
192
|
+
botAuthors: [...DEFAULT_BABYSIT_BOT_AUTHORS],
|
|
193
|
+
});
|
|
194
|
+
const unresolvedReviewState = snapshot.reviews.some(
|
|
195
|
+
(review) =>
|
|
196
|
+
review.state === "changes_requested" || review.state === "pending",
|
|
197
|
+
);
|
|
198
|
+
const signal = {
|
|
199
|
+
...proposal,
|
|
200
|
+
isClean: proposal.isClean && !unresolvedReviewState,
|
|
201
|
+
};
|
|
202
|
+
const needsBabysit = shouldBabysitBuilderBotPullRequest({
|
|
203
|
+
author: pullRequest.userLogin,
|
|
204
|
+
mergeable: pullRequest.mergeable,
|
|
205
|
+
mergeableState: pullRequest.mergeableState,
|
|
206
|
+
snapshot: signal,
|
|
207
|
+
});
|
|
208
|
+
const now = new Date();
|
|
209
|
+
const nowIso = now.toISOString();
|
|
210
|
+
const metadata = parseTriageMetadata(item.metadataJson);
|
|
211
|
+
const fingerprint = babysitFingerprint({
|
|
212
|
+
headSha: snapshot.headSha,
|
|
213
|
+
mergeable: pullRequest.mergeable,
|
|
214
|
+
mergeableState: pullRequest.mergeableState,
|
|
215
|
+
snapshot: signal,
|
|
216
|
+
reviewStates: snapshot.reviews.map((review) => review.state),
|
|
217
|
+
});
|
|
218
|
+
const previousFingerprint = metadataString(
|
|
219
|
+
metadata,
|
|
220
|
+
"prBabysitFingerprint",
|
|
221
|
+
);
|
|
222
|
+
const previousState = metadataString(metadata, "prBabysitState");
|
|
223
|
+
if (!needsBabysit) {
|
|
224
|
+
await updateBabysitMetadata(itemId, orgId, {
|
|
225
|
+
prBabysitState: "clean",
|
|
226
|
+
prBabysitLastCheckedAt: nowIso,
|
|
227
|
+
prBabysitFingerprint: fingerprint,
|
|
228
|
+
});
|
|
229
|
+
return { ok: true, action: "clean" };
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
const quietSince =
|
|
233
|
+
previousFingerprint === fingerprint && previousState !== "clean"
|
|
234
|
+
? (parseTimestamp(metadataString(metadata, "prBabysitQuietSinceAt")) ??
|
|
235
|
+
now.getTime())
|
|
236
|
+
: now.getTime();
|
|
237
|
+
const lastCommentAt = parseTimestamp(
|
|
238
|
+
metadataString(metadata, "prBabysitLastCommentAt"),
|
|
239
|
+
);
|
|
240
|
+
const quietForMs = now.getTime() - quietSince;
|
|
241
|
+
const shouldPost =
|
|
242
|
+
previousFingerprint !== fingerprint &&
|
|
243
|
+
(lastCommentAt === null ||
|
|
244
|
+
now.getTime() - lastCommentAt >= MIN_COMMENT_INTERVAL_MS);
|
|
245
|
+
if (!shouldPost || quietForMs >= QUIET_PERIOD_MS) {
|
|
246
|
+
await updateBabysitMetadata(itemId, orgId, {
|
|
247
|
+
prBabysitState: quietForMs >= QUIET_PERIOD_MS ? "quiet" : "waiting",
|
|
248
|
+
prBabysitFingerprint: fingerprint,
|
|
249
|
+
prBabysitQuietSinceAt: new Date(quietSince).toISOString(),
|
|
250
|
+
prBabysitLastCheckedAt: nowIso,
|
|
251
|
+
});
|
|
252
|
+
return {
|
|
253
|
+
ok: true,
|
|
254
|
+
action: quietForMs >= QUIET_PERIOD_MS ? "quiet" : "waiting",
|
|
255
|
+
quietForMinutes: Math.floor(Math.max(0, quietForMs) / 60_000),
|
|
256
|
+
};
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
const comment = await github.createIssueComment(
|
|
260
|
+
repository,
|
|
261
|
+
item.pullRequestNumber,
|
|
262
|
+
BUILDER_BOT_REQUEST,
|
|
263
|
+
);
|
|
264
|
+
await updateBabysitMetadata(itemId, orgId, {
|
|
265
|
+
prBabysitState: "active",
|
|
266
|
+
prBabysitFingerprint: fingerprint,
|
|
267
|
+
prBabysitQuietSinceAt: new Date(quietSince).toISOString(),
|
|
268
|
+
prBabysitLastCheckedAt: nowIso,
|
|
269
|
+
prBabysitLastCommentAt: nowIso,
|
|
270
|
+
prBabysitLastCommentUrl: comment.htmlUrl,
|
|
271
|
+
});
|
|
272
|
+
return {
|
|
273
|
+
ok: true,
|
|
274
|
+
action: "commented",
|
|
275
|
+
commentUrl: comment.htmlUrl,
|
|
276
|
+
quietForMinutes: Math.floor(Math.max(0, quietForMs) / 60_000),
|
|
277
|
+
};
|
|
278
|
+
},
|
|
279
|
+
});
|
|
@@ -19,10 +19,27 @@ export default defineAction({
|
|
|
19
19
|
const { orgId } = await requireWorkspaceMember(
|
|
20
20
|
workspaceMemberIdentityFromContext(context),
|
|
21
21
|
);
|
|
22
|
-
const
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
22
|
+
const [organizationHealth, globalHealth] = await Promise.all([
|
|
23
|
+
getAutomationSchedulerHealth({
|
|
24
|
+
appId: "factory",
|
|
25
|
+
orgId,
|
|
26
|
+
}),
|
|
27
|
+
getAutomationSchedulerHealth({ appId: "factory", orgId: null }),
|
|
28
|
+
]);
|
|
29
|
+
const health =
|
|
30
|
+
[organizationHealth, globalHealth]
|
|
31
|
+
.filter(
|
|
32
|
+
(candidate): candidate is NonNullable<typeof candidate> =>
|
|
33
|
+
candidate !== null && candidate.lastCheckedAt !== null,
|
|
34
|
+
)
|
|
35
|
+
.sort(
|
|
36
|
+
(left, right) =>
|
|
37
|
+
(right.lastCheckedAt ?? 0) - (left.lastCheckedAt ?? 0),
|
|
38
|
+
)[0] ??
|
|
39
|
+
organizationHealth ??
|
|
40
|
+
globalHealth;
|
|
41
|
+
const healthScope =
|
|
42
|
+
health?.orgId === orgId ? ("organization" as const) : ("global" as const);
|
|
26
43
|
if (!health?.lastCheckedAt) {
|
|
27
44
|
return {
|
|
28
45
|
status: "no-data" as const,
|
|
@@ -30,6 +47,7 @@ export default defineAction({
|
|
|
30
47
|
lastDispatchedAt: health?.lastDispatchedAt ?? null,
|
|
31
48
|
lastError: health?.lastError ?? null,
|
|
32
49
|
runtime: health?.runtime ?? null,
|
|
50
|
+
scope: healthScope,
|
|
33
51
|
staleAfterMs: STALE_AFTER_MS,
|
|
34
52
|
};
|
|
35
53
|
}
|
|
@@ -44,6 +62,7 @@ export default defineAction({
|
|
|
44
62
|
lastDispatchedAt: health.lastDispatchedAt,
|
|
45
63
|
lastError: health.lastError,
|
|
46
64
|
runtime: health.runtime,
|
|
65
|
+
scope: healthScope,
|
|
47
66
|
staleAfterMs: STALE_AFTER_MS,
|
|
48
67
|
};
|
|
49
68
|
},
|
|
@@ -258,7 +258,10 @@ export default function FactoryRoute() {
|
|
|
258
258
|
|
|
259
259
|
function updateGraph(next: FactoryCanvasGraph) {
|
|
260
260
|
setDraftGraph(next);
|
|
261
|
-
setDirty(
|
|
261
|
+
setDirty(
|
|
262
|
+
!graphData?.graph ||
|
|
263
|
+
JSON.stringify(next) !== JSON.stringify(graphData.graph),
|
|
264
|
+
);
|
|
262
265
|
}
|
|
263
266
|
|
|
264
267
|
function addNode() {
|
|
@@ -645,14 +648,29 @@ function AutomationsView({
|
|
|
645
648
|
|
|
646
649
|
useEffect(() => {
|
|
647
650
|
if (!selected) {
|
|
648
|
-
setDraft(null);
|
|
651
|
+
setDraft((current) => (current === null ? current : null));
|
|
649
652
|
return;
|
|
650
653
|
}
|
|
651
654
|
if (selected.id !== selectedId) {
|
|
652
655
|
selectAutomation(selected.id);
|
|
653
656
|
return;
|
|
654
657
|
}
|
|
655
|
-
|
|
658
|
+
const nextDraft = draftForAutomation(selected);
|
|
659
|
+
setDraft((current) => {
|
|
660
|
+
if (
|
|
661
|
+
current &&
|
|
662
|
+
current.id === nextDraft.id &&
|
|
663
|
+
current.name === nextDraft.name &&
|
|
664
|
+
current.prompt === nextDraft.prompt &&
|
|
665
|
+
current.body === nextDraft.body &&
|
|
666
|
+
current.model === nextDraft.model &&
|
|
667
|
+
current.schedule === nextDraft.schedule &&
|
|
668
|
+
current.enabled === nextDraft.enabled
|
|
669
|
+
) {
|
|
670
|
+
return current;
|
|
671
|
+
}
|
|
672
|
+
return nextDraft;
|
|
673
|
+
});
|
|
656
674
|
}, [selected, selectedId]);
|
|
657
675
|
|
|
658
676
|
async function saveAutomation() {
|
|
@@ -24,6 +24,7 @@ const INITIAL_TOOL_NAMES = [
|
|
|
24
24
|
"start-builder-for-item",
|
|
25
25
|
"govern-agent-native-pull-request",
|
|
26
26
|
"babysit-pull-request",
|
|
27
|
+
"babysit-agent-native-pull-request",
|
|
27
28
|
"approve-factory-item",
|
|
28
29
|
"list-triage-rules",
|
|
29
30
|
"get-triage-config",
|
|
@@ -70,7 +71,9 @@ BuilderIO author, a clear bug, passing CI, and handled review feedback. Auto-mer
|
|
|
70
71
|
also requires a verified Factory Builder run. When a user says to do a review-gated
|
|
71
72
|
item now, use the explicit approval action, which records the approver and applies
|
|
72
73
|
the rule's configured executor policy. Keep Slack replies concise and link to the
|
|
73
|
-
Factory item when a review is needed
|
|
74
|
+
Factory item when a review is needed. The scheduled builder-io-bot PR babysitter
|
|
75
|
+
posts its exact feedback-fix request through GitHub, persists a 20-minute quiet
|
|
76
|
+
window, and never approves or merges.`,
|
|
74
77
|
} satisfies AgentChatPluginOptions;
|
|
75
78
|
|
|
76
79
|
export default createAgentChatPlugin(options);
|
|
@@ -5,6 +5,7 @@ import {
|
|
|
5
5
|
organizationResourceOwner,
|
|
6
6
|
resourceGetByPath,
|
|
7
7
|
resourcePut,
|
|
8
|
+
resourcePutIfCurrent,
|
|
8
9
|
WORKSPACE_OWNER,
|
|
9
10
|
} from "@agent-native/core/resources";
|
|
10
11
|
import {
|
|
@@ -264,6 +265,30 @@ fully owned by their product owners. Auto-merge is limited to PRs with a
|
|
|
264
265
|
verified Factory Builder run; all other PRs can at most pass the approval
|
|
265
266
|
policy. Do not call GitHub write actions directly or claim a merge unless the
|
|
266
267
|
governance action confirms it.
|
|
268
|
+
`,
|
|
269
|
+
},
|
|
270
|
+
{
|
|
271
|
+
name: "factory-pr-babysit",
|
|
272
|
+
schedule: "*/2 * * * *",
|
|
273
|
+
body: `
|
|
274
|
+
# Factory builder-io-bot PR babysitting
|
|
275
|
+
|
|
276
|
+
Read the Factory configuration. When GitHub polling is enabled and a repository
|
|
277
|
+
is configured, call poll-github-sources with includeIssues false and
|
|
278
|
+
includePullRequests true. List a bounded page of open github pull-request items.
|
|
279
|
+
|
|
280
|
+
For each item, call babysit-agent-native-pull-request. That action fetches fresh
|
|
281
|
+
GitHub and ai-services evidence and is the only place allowed to decide whether
|
|
282
|
+
to post the bounded @builderio-bot feedback-fix request. It only acts on open
|
|
283
|
+
non-draft PRs authored by builder-io-bot (including GitHub's bot login variants),
|
|
284
|
+
and skips owner-managed Clips, Design, and Content work. It persists the latest
|
|
285
|
+
feedback fingerprint and quiet window, so repeated scheduler ticks do not spam
|
|
286
|
+
comments. A changed commit, new unresolved feedback, failing or pending CI, or
|
|
287
|
+
merge conflict starts a new bounded request; twenty minutes without new work to
|
|
288
|
+
address ends that babysitting window. The action never approves or merges.
|
|
289
|
+
|
|
290
|
+
Preserve action errors and never claim that Builder fixed a PR unless fresh
|
|
291
|
+
evidence confirms the resulting state.
|
|
267
292
|
`,
|
|
268
293
|
},
|
|
269
294
|
];
|
|
@@ -274,6 +299,19 @@ function workspaceOwnerEmail(): string | undefined {
|
|
|
274
299
|
return email;
|
|
275
300
|
}
|
|
276
301
|
|
|
302
|
+
function defaultRepository(): string | null {
|
|
303
|
+
const repository = process.env.FACTORY_DEFAULT_REPOSITORY?.trim(); // guard:allow-env-credential - repository configuration, not a credential
|
|
304
|
+
if (!repository || /[\r\n]/.test(repository)) return null;
|
|
305
|
+
return repository;
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
function defaultGithubPollingEnabled(): 0 | 1 {
|
|
309
|
+
return process.env.FACTORY_ENABLE_GITHUB_POLLING?.trim().toLowerCase() === // guard:allow-env-credential - deployment feature flag, not a credential
|
|
310
|
+
"true"
|
|
311
|
+
? 1
|
|
312
|
+
: 0;
|
|
313
|
+
}
|
|
314
|
+
|
|
277
315
|
function setFrontmatterField(
|
|
278
316
|
content: string,
|
|
279
317
|
key: string,
|
|
@@ -327,16 +365,47 @@ async function ensureOrganizationAutomations(
|
|
|
327
365
|
orgId: string,
|
|
328
366
|
): Promise<void> {
|
|
329
367
|
const owner = organizationResourceOwner(orgId);
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
368
|
+
await Promise.all(
|
|
369
|
+
AUTOMATION_SEEDS.map(async (seed) => {
|
|
370
|
+
const path = `jobs/${seed.name}.md`;
|
|
371
|
+
const existing = await resourceGetByPath(owner, path);
|
|
372
|
+
if (!existing) {
|
|
373
|
+
await resourcePut(
|
|
374
|
+
owner,
|
|
375
|
+
path,
|
|
376
|
+
automationContent(ownerEmail, orgId, seed),
|
|
377
|
+
"text/markdown",
|
|
378
|
+
);
|
|
379
|
+
return;
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
// Earlier Factory versions created these rows without the metadata the
|
|
383
|
+
// list and action guards use. Patch only identity metadata and keep the
|
|
384
|
+
// user's prompt, model, schedule, and enabled state intact.
|
|
385
|
+
let repaired = existing.content;
|
|
386
|
+
repaired = setFrontmatterField(repaired, "triggerType", "schedule");
|
|
387
|
+
repaired = setFrontmatterField(repaired, "domain", "factory");
|
|
388
|
+
repaired = setFrontmatterField(repaired, "orgId", orgId);
|
|
389
|
+
repaired = setFrontmatterField(repaired, "createdBy", ownerEmail);
|
|
390
|
+
repaired = setFrontmatterField(repaired, "runAs", "creator");
|
|
391
|
+
if (repaired === existing.content) return;
|
|
392
|
+
|
|
393
|
+
const updated = await resourcePutIfCurrent({
|
|
394
|
+
owner,
|
|
395
|
+
path,
|
|
396
|
+
content: repaired,
|
|
397
|
+
mimeType: "text/markdown",
|
|
398
|
+
expectedId: existing.id,
|
|
399
|
+
expectedUpdatedAt: existing.updatedAt,
|
|
400
|
+
expectedContent: existing.content,
|
|
401
|
+
});
|
|
402
|
+
if (!updated) {
|
|
403
|
+
console.warn(
|
|
404
|
+
`[factory-scheduler-job] skipped metadata repair for ${path}: the resource changed concurrently`,
|
|
405
|
+
);
|
|
406
|
+
}
|
|
407
|
+
}),
|
|
408
|
+
);
|
|
340
409
|
}
|
|
341
410
|
|
|
342
411
|
async function ensureDefaultTriageConfig(
|
|
@@ -359,11 +428,11 @@ async function ensureDefaultTriageConfig(
|
|
|
359
428
|
slackChannelId: DEFAULT_SLACK_CHANNEL_ID,
|
|
360
429
|
slackChannelName: DEFAULT_SLACK_CHANNEL_NAME,
|
|
361
430
|
pollingEnabled: 1,
|
|
362
|
-
githubPollingEnabled:
|
|
431
|
+
githubPollingEnabled: defaultGithubPollingEnabled(),
|
|
363
432
|
sentryPollingEnabled: 0,
|
|
364
433
|
lastSlackTs: null,
|
|
365
434
|
slackHistoryCursor: null,
|
|
366
|
-
repository:
|
|
435
|
+
repository: defaultRepository(),
|
|
367
436
|
sentryOrgSlug: null,
|
|
368
437
|
sentryProjectSlug: null,
|
|
369
438
|
sentryEnvironment: null,
|
|
@@ -73,6 +73,11 @@ export interface GitHubMergeResult {
|
|
|
73
73
|
message: string;
|
|
74
74
|
}
|
|
75
75
|
|
|
76
|
+
export interface GitHubComment {
|
|
77
|
+
id: number;
|
|
78
|
+
htmlUrl: string;
|
|
79
|
+
}
|
|
80
|
+
|
|
76
81
|
interface JsonResponse {
|
|
77
82
|
ok: boolean;
|
|
78
83
|
status: number;
|
|
@@ -361,6 +366,32 @@ export function createGitHubClient(options: GitHubClientOptions) {
|
|
|
361
366
|
};
|
|
362
367
|
},
|
|
363
368
|
|
|
369
|
+
async createIssueComment(
|
|
370
|
+
repository: GitHubRepositoryRef,
|
|
371
|
+
issueNumber: number,
|
|
372
|
+
body: string,
|
|
373
|
+
): Promise<GitHubComment> {
|
|
374
|
+
if (!Number.isInteger(issueNumber) || issueNumber < 1) {
|
|
375
|
+
throw new Error("GitHub issue number must be a positive integer");
|
|
376
|
+
}
|
|
377
|
+
const trimmedBody = body.trim();
|
|
378
|
+
if (!trimmedBody) throw new Error("GitHub comment body is required");
|
|
379
|
+
const item = record(
|
|
380
|
+
await request<unknown>(
|
|
381
|
+
`${repositoryPath(repository)}/issues/${issueNumber}/comments`,
|
|
382
|
+
{
|
|
383
|
+
method: "POST",
|
|
384
|
+
headers: { "Content-Type": "application/json" },
|
|
385
|
+
body: JSON.stringify({ body: trimmedBody.slice(0, 65_536) }),
|
|
386
|
+
},
|
|
387
|
+
),
|
|
388
|
+
);
|
|
389
|
+
return {
|
|
390
|
+
id: requiredNumber(item.id, "comment id"),
|
|
391
|
+
htmlUrl: requiredString(item.html_url, "comment URL"),
|
|
392
|
+
};
|
|
393
|
+
},
|
|
394
|
+
|
|
364
395
|
async mergePullRequest(
|
|
365
396
|
repository: GitHubRepositoryRef,
|
|
366
397
|
pullRequestNumber: number,
|
|
@@ -1,5 +1,24 @@
|
|
|
1
1
|
import type { PullRequestCheckObservation } from "./pr-monitor.js";
|
|
2
2
|
|
|
3
|
+
export const BUILDER_BOT_LOGINS = new Set([
|
|
4
|
+
"builder-io-bot",
|
|
5
|
+
"builder-io-bot[bot]",
|
|
6
|
+
"builderio-bot",
|
|
7
|
+
"builderio-bot[bot]",
|
|
8
|
+
"builderio[bot]",
|
|
9
|
+
]);
|
|
10
|
+
|
|
11
|
+
export const DEFAULT_BABYSIT_BOT_AUTHORS = [
|
|
12
|
+
"builder-io-bot",
|
|
13
|
+
"builder-io-bot[bot]",
|
|
14
|
+
"builderio-bot",
|
|
15
|
+
"builderio-bot[bot]",
|
|
16
|
+
"builderio[bot]",
|
|
17
|
+
"github-actions",
|
|
18
|
+
"github-actions[bot]",
|
|
19
|
+
"dependabot[bot]",
|
|
20
|
+
] as const;
|
|
21
|
+
|
|
3
22
|
export interface ReviewCommentObservation {
|
|
4
23
|
id: string;
|
|
5
24
|
author: string;
|
|
@@ -30,6 +49,61 @@ export interface BabysitProposal {
|
|
|
30
49
|
isClean: boolean;
|
|
31
50
|
}
|
|
32
51
|
|
|
52
|
+
export interface BuilderBotBabysitSignal {
|
|
53
|
+
author: string;
|
|
54
|
+
mergeable: boolean | null;
|
|
55
|
+
mergeableState: string | null;
|
|
56
|
+
snapshot: BabysitProposal;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
export function isBuilderBotLogin(login: string): boolean {
|
|
60
|
+
return BUILDER_BOT_LOGINS.has(login.trim().toLowerCase());
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
export function hasMergeConflict(input: {
|
|
64
|
+
mergeable: boolean | null;
|
|
65
|
+
mergeableState: string | null;
|
|
66
|
+
}): boolean {
|
|
67
|
+
return (
|
|
68
|
+
input.mergeable === false ||
|
|
69
|
+
input.mergeableState === "dirty" ||
|
|
70
|
+
input.mergeableState === "conflicting"
|
|
71
|
+
);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
export function shouldBabysitBuilderBotPullRequest(
|
|
75
|
+
input: BuilderBotBabysitSignal,
|
|
76
|
+
): boolean {
|
|
77
|
+
return (
|
|
78
|
+
isBuilderBotLogin(input.author) &&
|
|
79
|
+
(hasMergeConflict(input) || !input.snapshot.isClean)
|
|
80
|
+
);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
export function babysitFingerprint(input: {
|
|
84
|
+
headSha: string;
|
|
85
|
+
mergeable: boolean | null;
|
|
86
|
+
mergeableState: string | null;
|
|
87
|
+
snapshot: BabysitProposal;
|
|
88
|
+
reviewStates?: readonly string[];
|
|
89
|
+
}): string {
|
|
90
|
+
return JSON.stringify({
|
|
91
|
+
headSha: input.headSha,
|
|
92
|
+
mergeable: input.mergeable,
|
|
93
|
+
mergeableState: input.mergeableState,
|
|
94
|
+
unansweredComments: input.snapshot.unansweredComments.map((comment) => ({
|
|
95
|
+
id: comment.id,
|
|
96
|
+
body: comment.body,
|
|
97
|
+
isResolved: comment.isResolved ?? null,
|
|
98
|
+
})),
|
|
99
|
+
failingChecks: input.snapshot.failingChecks.map((check) => check.name),
|
|
100
|
+
pendingChecks: input.snapshot.pendingChecks.map((check) => check.name),
|
|
101
|
+
missingChangesetPackages: input.snapshot.missingChangesetPackages,
|
|
102
|
+
commentsTruncated: input.snapshot.commentsTruncated,
|
|
103
|
+
reviewStates: input.reviewStates ?? [],
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
|
|
33
107
|
const MISSING_CHANGESET_LINE = /^MISSING_CHANGESET_PACKAGES:\s*(.*)$/m;
|
|
34
108
|
|
|
35
109
|
function parseMissingChangesetPackages(log: string | undefined): string[] {
|
|
@@ -71,7 +145,7 @@ export function reconcileBabysitState(input: BabysitInput): BabysitProposal {
|
|
|
71
145
|
!botAuthors.has(comment.author),
|
|
72
146
|
);
|
|
73
147
|
const failingChecks = input.checks.filter(
|
|
74
|
-
(check) => check.state === "failed",
|
|
148
|
+
(check) => check.state === "failed" || check.state === "cancelled",
|
|
75
149
|
);
|
|
76
150
|
const pendingChecks = input.checks.filter(
|
|
77
151
|
(check) => check.state === "queued" || check.state === "in_progress",
|