@xopcai/xopc 0.0.114 → 0.0.116
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/README.md +5 -4
- package/README.zh-CN.md +5 -4
- package/dist/browser-ext/manifest.json +1 -1
- package/dist/extensions/telegram/xopc.extension.json +1 -1
- package/dist/gateway/static/root/assets/{agent-avatar-dicebear-Fp-p7bP1.js → agent-avatar-dicebear-CWM1UU5P.js} +1 -1
- package/dist/gateway/static/root/assets/agent-browser-settings-page-D1SyFYeh.js +6 -0
- package/dist/gateway/static/root/assets/agent-defaults-tabbed-page-C9YxgvuI.js +1 -0
- package/dist/gateway/static/root/assets/agents-CteVs3UO.js +71 -0
- package/dist/gateway/static/root/assets/app-management-settings-panel-yXSXY_bu.js +1 -0
- package/dist/gateway/static/root/assets/{appearance-settings-ycbdJRuZ.js → appearance-settings-DjY1P_ug.js} +1 -1
- package/dist/gateway/static/root/assets/apps-page-CVQ1M8Ax.js +1 -0
- package/dist/gateway/static/root/assets/{archive-plugin-CJzSADJo.js → archive-plugin-CytE5j-e.js} +1 -1
- package/dist/gateway/static/root/assets/{attachment-load-BTAB4zGS.js → attachment-load-BvvrN6rF.js} +1 -1
- package/dist/gateway/static/root/assets/{binary-plugins-DXR1-mct.js → binary-plugins-IBWSitnj.js} +1 -1
- package/dist/gateway/static/root/assets/{block-editor-CzQri9h2.js → block-editor-C-wDpsf-.js} +44 -44
- package/dist/gateway/static/root/assets/channels-settings-Cd3JbeQ1.js +1 -0
- package/dist/gateway/static/root/assets/{config-api-DRqjEvAx.js → config-api-C4RAtTKW.js} +1 -1
- package/dist/gateway/static/root/assets/connectors-page-MsMa5qBr.js +2 -0
- package/dist/gateway/static/root/assets/{cron-api-BXaZXv1o.js → cron-api-sJNMqB6P.js} +1 -1
- package/dist/gateway/static/root/assets/cron-page-D30CSwkn.js +3 -0
- package/dist/gateway/static/root/assets/dreaming-settings-6fCUWRQf.js +1 -0
- package/dist/gateway/static/root/assets/{extension-debug-page-DSkqMYo7.js → extension-debug-page-BAIyjDlq.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-page-h2dGDbMN.js → extension-page-DEhv2GpC.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-settings-page-hN99RhOi.js → extension-settings-page-DOuAxTDW.js} +1 -1
- package/dist/gateway/static/root/assets/{fetch-D9QqUtzZ.js → fetch-CTsREQIe.js} +1 -1
- package/dist/gateway/static/root/assets/{format-interval-label-D6E687rG.js → format-interval-label-D35Bfhtx.js} +1 -1
- package/dist/gateway/static/root/assets/{gateway-config-api-CLt_SKTC.js → gateway-config-api-C6989a-W.js} +1 -1
- package/dist/gateway/static/root/assets/gateway-settings-BpF26t91.js +1 -0
- package/dist/gateway/static/root/assets/{gateway-startup-retry-N7Z_sz7p.js → gateway-startup-retry-C1KAHrd2.js} +1 -1
- package/dist/gateway/static/root/assets/goal-detail-page-DOjhmRyf.js +1 -0
- package/dist/gateway/static/root/assets/goals-config-api-KnLGpu6h.js +1 -0
- package/dist/gateway/static/root/assets/goals-page-Xl9_wrFc.js +2 -0
- package/dist/gateway/static/root/assets/goals-settings-DtPtqZi8.js +1 -0
- package/dist/gateway/static/root/assets/{heartbeat-config-api-DGPadTw-.js → heartbeat-config-api-uKw1f0IG.js} +1 -1
- package/dist/gateway/static/root/assets/heartbeat-settings-DN9vEj9P.js +1 -0
- package/dist/gateway/static/root/assets/index-C8ytlAF2.js +122 -0
- package/dist/gateway/static/root/assets/index-CVpJW2NS.css +1 -0
- package/dist/gateway/static/root/assets/{interval-presets-CEklPQ_r.js → interval-presets-Dq0FXJ65.js} +1 -1
- package/dist/gateway/static/root/assets/{keyboard-shortcuts-settings-Ce_aQ8Iv.js → keyboard-shortcuts-settings-C9_t4m7t.js} +1 -1
- package/dist/gateway/static/root/assets/logs-page-SNkWzidV.js +2 -0
- package/dist/gateway/static/root/assets/{markdown-split-BMz3xPXO.js → markdown-split-Ca87W8-h.js} +1 -1
- package/dist/gateway/static/root/assets/{media-plugins-BalOSoz9.js → media-plugins-BAcUjPRJ.js} +1 -1
- package/dist/gateway/static/root/assets/messages-BqzIDrlr.js +3 -0
- package/dist/gateway/static/root/assets/models-hub-panel-BO4o-GmO.js +2 -0
- package/dist/gateway/static/root/assets/note-detail-page-DLV_XDmT.js +2 -0
- package/dist/gateway/static/root/assets/{note-image-lightbox-C5D1Q5mY.js → note-image-lightbox-hnSX5SSn.js} +1 -1
- package/dist/gateway/static/root/assets/notes-page-ycsDlkFA.js +1 -0
- package/dist/gateway/static/root/assets/{preview-open-alternatives-CYFR5U9l.js → preview-open-alternatives-CNgM20H5.js} +1 -1
- package/dist/gateway/static/root/assets/remote-access-hub-DQpnE8K9.js +1 -0
- package/dist/gateway/static/root/assets/{save-bar-controls-BQ79Z5IP.js → save-bar-controls-CcdjGcfT.js} +1 -1
- package/dist/gateway/static/root/assets/{schedule-field-Bgk6Emue.js → schedule-field-CYr39z76.js} +1 -1
- package/dist/gateway/static/root/assets/{schema-form-DzS36TMa.js → schema-form-BRAJgZQ2.js} +1 -1
- package/dist/gateway/static/root/assets/sessions-page-BZui7iAY.js +1 -0
- package/dist/gateway/static/root/assets/settings-advanced-gate-DEfzZ1ax.js +1 -0
- package/dist/gateway/static/root/assets/{settings-collapsible-section-CdjFnSAy.js → settings-collapsible-section-BhzjeGWi.js} +1 -1
- package/dist/gateway/static/root/assets/{settings-form-section-DZLy_exu.js → settings-form-section-Cz3Pcr9b.js} +1 -1
- package/dist/gateway/static/root/assets/settings-page-CLuSsu1-.js +1 -0
- package/dist/gateway/static/root/assets/setup-status-panel-Cq4qpXLi.js +1 -0
- package/dist/gateway/static/root/assets/{share-preview-page-_qRDr4g_.js → share-preview-page-DL4y9K5e.js} +1 -1
- package/dist/gateway/static/root/assets/shares-settings-B9F3HyYQ.js +1 -0
- package/dist/gateway/static/root/assets/skill-reload-api-Bp9UPPwm.js +1 -0
- package/dist/gateway/static/root/assets/skills-page-BIoBsfSV.js +2 -0
- package/dist/gateway/static/root/assets/system-settings-panel-FD2jxRZ3.js +1 -0
- package/dist/gateway/static/root/assets/use-agent-defaults-form-Cz2_pPzu.js +1 -0
- package/dist/gateway/static/root/assets/{use-channel-catalog-CbXq97rT.js → use-channel-catalog-BInPrfR5.js} +1 -1
- package/dist/gateway/static/root/assets/{use-settings-tab-guard-DwS3drWK.js → use-settings-tab-guard-nuHMmZQv.js} +1 -1
- package/dist/gateway/static/root/assets/voice-api-key-field-BUIrKb8s.js +1 -0
- package/dist/gateway/static/root/assets/{voice-player-store-DSuOd9zy.js → voice-player-store-1U3vFppm.js} +1 -1
- package/dist/gateway/static/root/assets/workflows-page-qE3SexnO.js +18 -0
- package/dist/gateway/static/root/index.html +5 -5
- package/dist/gateway/static/root/logo.svg +4 -3
- package/dist/package.js +1 -1
- package/dist/src/agent/embedded/session-tool-result-guard.js +8 -1
- package/dist/src/agent/embedded/session-tool-result-guard.js.map +1 -1
- package/dist/src/agent/goals/checklist-judge.d.ts +2 -0
- package/dist/src/agent/goals/checklist-judge.js +4 -3
- package/dist/src/agent/goals/checklist-judge.js.map +1 -1
- package/dist/src/agent/goals/evaluate-turn.d.ts +2 -1
- package/dist/src/agent/goals/evaluate-turn.js +2 -0
- package/dist/src/agent/goals/evaluate-turn.js.map +1 -1
- package/dist/src/agent/goals/post-turn.d.ts +6 -1
- package/dist/src/agent/goals/post-turn.js +20 -4
- package/dist/src/agent/goals/post-turn.js.map +1 -1
- package/dist/src/agent/image/understanding/pi-ai-provider.js +5 -2
- package/dist/src/agent/image/understanding/pi-ai-provider.js.map +1 -1
- package/dist/src/agent/image/understanding/provider-registry.d.ts +1 -0
- package/dist/src/agent/image/understanding/provider-registry.js +16 -2
- package/dist/src/agent/image/understanding/provider-registry.js.map +1 -1
- package/dist/src/agent/tools/composio-tool.d.ts +8 -0
- package/dist/src/agent/tools/composio-tool.js +46 -0
- package/dist/src/agent/tools/composio-tool.js.map +1 -0
- package/dist/src/agent/tools/factory.js +13 -8
- package/dist/src/agent/tools/factory.js.map +1 -1
- package/dist/src/agent/tools/index.d.ts +1 -0
- package/dist/src/agent/tools/index.js +2 -1
- package/dist/src/agent/workflow/builtins/audit-repo.d.ts +1 -1
- package/dist/src/agent/workflow/builtins/audit-repo.js +15 -2
- package/dist/src/agent/workflow/builtins/audit-repo.js.map +1 -1
- package/dist/src/agent/workflow/builtins/client-proposal.d.ts +1 -1
- package/dist/src/agent/workflow/builtins/client-proposal.js +10 -1
- package/dist/src/agent/workflow/builtins/client-proposal.js.map +1 -1
- package/dist/src/agent/workflow/builtins/competitor-scan.d.ts +1 -1
- package/dist/src/agent/workflow/builtins/competitor-scan.js +16 -2
- package/dist/src/agent/workflow/builtins/competitor-scan.js.map +1 -1
- package/dist/src/agent/workflow/builtins/content-draft.d.ts +1 -1
- package/dist/src/agent/workflow/builtins/content-draft.js +15 -2
- package/dist/src/agent/workflow/builtins/content-draft.js.map +1 -1
- package/dist/src/agent/workflow/builtins/content-repurpose.d.ts +1 -1
- package/dist/src/agent/workflow/builtins/content-repurpose.js +10 -1
- package/dist/src/agent/workflow/builtins/content-repurpose.js.map +1 -1
- package/dist/src/agent/workflow/builtins/debug-incident.d.ts +1 -1
- package/dist/src/agent/workflow/builtins/debug-incident.js +9 -1
- package/dist/src/agent/workflow/builtins/debug-incident.js.map +1 -1
- package/dist/src/agent/workflow/builtins/decision-compare.d.ts +1 -1
- package/dist/src/agent/workflow/builtins/decision-compare.js +16 -2
- package/dist/src/agent/workflow/builtins/decision-compare.js.map +1 -1
- package/dist/src/agent/workflow/builtins/implementation-plan.d.ts +1 -1
- package/dist/src/agent/workflow/builtins/implementation-plan.js +11 -1
- package/dist/src/agent/workflow/builtins/implementation-plan.js.map +1 -1
- package/dist/src/agent/workflow/builtins/inbox-triage.d.ts +1 -1
- package/dist/src/agent/workflow/builtins/inbox-triage.js +11 -1
- package/dist/src/agent/workflow/builtins/inbox-triage.js.map +1 -1
- package/dist/src/agent/workflow/builtins/meeting-prep.d.ts +1 -1
- package/dist/src/agent/workflow/builtins/meeting-prep.js +9 -1
- package/dist/src/agent/workflow/builtins/meeting-prep.js.map +1 -1
- package/dist/src/agent/workflow/builtins/multi-perspective-review.d.ts +1 -1
- package/dist/src/agent/workflow/builtins/multi-perspective-review.js +9 -1
- package/dist/src/agent/workflow/builtins/multi-perspective-review.js.map +1 -1
- package/dist/src/agent/workflow/builtins/offer-design.d.ts +1 -1
- package/dist/src/agent/workflow/builtins/offer-design.js +10 -1
- package/dist/src/agent/workflow/builtins/offer-design.js.map +1 -1
- package/dist/src/agent/workflow/builtins/pr-review.d.ts +1 -1
- package/dist/src/agent/workflow/builtins/pr-review.js +9 -1
- package/dist/src/agent/workflow/builtins/pr-review.js.map +1 -1
- package/dist/src/agent/workflow/builtins/release-check.d.ts +1 -1
- package/dist/src/agent/workflow/builtins/release-check.js +10 -1
- package/dist/src/agent/workflow/builtins/release-check.js.map +1 -1
- package/dist/src/agent/workflow/builtins/research.d.ts +1 -1
- package/dist/src/agent/workflow/builtins/research.js +16 -2
- package/dist/src/agent/workflow/builtins/research.js.map +1 -1
- package/dist/src/agent/workflow/builtins/weekly-review.d.ts +1 -1
- package/dist/src/agent/workflow/builtins/weekly-review.js +9 -1
- package/dist/src/agent/workflow/builtins/weekly-review.js.map +1 -1
- package/dist/src/agent/workflow/snapshot.d.ts +10 -0
- package/dist/src/agent/workflow/snapshot.js +136 -1
- package/dist/src/agent/workflow/snapshot.js.map +1 -1
- package/dist/src/channels/catalog/channel-catalog-service.d.ts +2 -1
- package/dist/src/channels/catalog/channel-catalog-service.js +133 -16
- package/dist/src/channels/catalog/channel-catalog-service.js.map +1 -1
- package/dist/src/channels/catalog/channel-catalog-types.d.ts +13 -0
- package/dist/src/cli/commands/doctor/checks/channel-config.js +14 -1
- package/dist/src/cli/commands/doctor/checks/channel-config.js.map +1 -1
- package/dist/src/cli/commands/doctor/checks/database-schema.js +1 -1
- package/dist/src/config/index.js +2 -2
- package/dist/src/config/schema.d.ts +15 -0
- package/dist/src/config/schema.js +12 -3
- package/dist/src/config/schema.js.map +1 -1
- package/dist/src/config/web-patch.d.ts +1 -0
- package/dist/src/config/web-patch.js +1 -0
- package/dist/src/config/web-patch.js.map +1 -1
- package/dist/src/connectors/composio-triggers.d.ts +10 -0
- package/dist/src/connectors/composio-triggers.js +32 -0
- package/dist/src/connectors/composio-triggers.js.map +1 -0
- package/dist/src/connectors/composio.d.ts +54 -0
- package/dist/src/connectors/composio.js +334 -0
- package/dist/src/connectors/composio.js.map +1 -0
- package/dist/src/connectors/health.js +16 -1
- package/dist/src/connectors/health.js.map +1 -1
- package/dist/src/connectors/install.d.ts +2 -1
- package/dist/src/connectors/install.js +50 -13
- package/dist/src/connectors/install.js.map +1 -1
- package/dist/src/connectors/instances.js +57 -6
- package/dist/src/connectors/instances.js.map +1 -1
- package/dist/src/connectors/lifecycle.d.ts +3 -0
- package/dist/src/connectors/lifecycle.js +23 -0
- package/dist/src/connectors/lifecycle.js.map +1 -0
- package/dist/src/connectors/materialize.js +2 -1
- package/dist/src/connectors/materialize.js.map +1 -1
- package/dist/src/connectors/providers.d.ts +1 -0
- package/dist/src/connectors/providers.js +10 -2
- package/dist/src/connectors/providers.js.map +1 -1
- package/dist/src/connectors/registries/modelscope.d.ts +2 -0
- package/dist/src/connectors/registries/modelscope.js +205 -0
- package/dist/src/connectors/registries/modelscope.js.map +1 -0
- package/dist/src/connectors/registries/official-mcp.d.ts +2 -0
- package/dist/src/connectors/registries/official-mcp.js +142 -0
- package/dist/src/connectors/registries/official-mcp.js.map +1 -0
- package/dist/src/connectors/registries/search.d.ts +12 -0
- package/dist/src/connectors/registries/search.js +89 -0
- package/dist/src/connectors/registries/search.js.map +1 -0
- package/dist/src/connectors/registries/smithery.d.ts +2 -0
- package/dist/src/connectors/registries/smithery.js +98 -0
- package/dist/src/connectors/registries/smithery.js.map +1 -0
- package/dist/src/connectors/registries/types.d.ts +20 -0
- package/dist/src/connectors/registries/types.js +1 -0
- package/dist/src/connectors/secret-store.js +4 -2
- package/dist/src/connectors/secret-store.js.map +1 -1
- package/dist/src/connectors/setup-secrets.d.ts +15 -0
- package/dist/src/connectors/setup-secrets.js +64 -0
- package/dist/src/connectors/setup-secrets.js.map +1 -0
- package/dist/src/connectors/supervisor.d.ts +15 -0
- package/dist/src/connectors/supervisor.js +73 -0
- package/dist/src/connectors/supervisor.js.map +1 -0
- package/dist/src/connectors/types.d.ts +27 -3
- package/dist/src/connectors/usage.js +6 -1
- package/dist/src/connectors/usage.js.map +1 -1
- package/dist/src/gateway/hono/app.js +5 -1
- package/dist/src/gateway/hono/app.js.map +1 -1
- package/dist/src/gateway/hono/lib/config-payload.d.ts +3 -1
- package/dist/src/gateway/hono/lib/config-payload.js +7 -4
- package/dist/src/gateway/hono/lib/config-payload.js.map +1 -1
- package/dist/src/gateway/hono/middleware/strict-rate-limit.d.ts +4 -0
- package/dist/src/gateway/hono/middleware/strict-rate-limit.js +19 -5
- package/dist/src/gateway/hono/middleware/strict-rate-limit.js.map +1 -1
- package/dist/src/gateway/hono/routes/channels.js +18 -14
- package/dist/src/gateway/hono/routes/channels.js.map +1 -1
- package/dist/src/gateway/hono/routes/connectors.js +230 -3
- package/dist/src/gateway/hono/routes/connectors.js.map +1 -1
- package/dist/src/gateway/hono/routes/deps.d.ts +1 -0
- package/dist/src/gateway/hono/routes/goals.js +52 -5
- package/dist/src/gateway/hono/routes/goals.js.map +1 -1
- package/dist/src/gateway/hono/routes/voice.js +14 -1
- package/dist/src/gateway/hono/routes/voice.js.map +1 -1
- package/dist/src/gateway/hono/sse.js.map +1 -1
- package/dist/src/gateway/rate-limit/buckets.d.ts +3 -0
- package/dist/src/gateway/rate-limit/buckets.js +12 -0
- package/dist/src/gateway/rate-limit/buckets.js.map +1 -1
- package/dist/src/gateway/service/agent-runner.d.ts +5 -12
- package/dist/src/gateway/service/agent-runner.js +8 -8
- package/dist/src/gateway/service/agent-runner.js.map +1 -1
- package/dist/src/gateway/service/run-gateway-agent.d.ts +2 -10
- package/dist/src/gateway/service/run-gateway-agent.js.map +1 -1
- package/dist/src/gateway/service.d.ts +1 -1
- package/dist/src/gateway/service.js +9 -4
- package/dist/src/gateway/service.js.map +1 -1
- package/dist/src/gateway/user-turn-input.d.ts +18 -0
- package/dist/src/gateway/user-turn-input.js +16 -0
- package/dist/src/gateway/user-turn-input.js.map +1 -0
- package/dist/src/goals/goal-queue-store.d.ts +2 -1
- package/dist/src/goals/goal-queue-store.js +2 -2
- package/dist/src/goals/goal-queue-store.js.map +1 -1
- package/dist/src/goals/goal-queue-types.d.ts +4 -3
- package/dist/src/goals/goal-runner.js +25 -3
- package/dist/src/goals/goal-runner.js.map +1 -1
- package/dist/src/goals/goal-service.d.ts +6 -1
- package/dist/src/goals/goal-service.js +9 -2
- package/dist/src/goals/goal-service.js.map +1 -1
- package/dist/src/goals/goal-store.d.ts +7 -1
- package/dist/src/goals/goal-store.js +42 -0
- package/dist/src/goals/goal-store.js.map +1 -1
- package/dist/src/goals/types.d.ts +10 -0
- package/dist/src/storage/sqlite/migrations/011_goal_context_messages.sql +8 -0
- package/dist/src/storage/sqlite/migrations/runner.d.ts +2 -2
- package/dist/src/storage/sqlite/migrations/runner.js +4 -4
- package/dist/src/storage/sqlite/migrations/runner.js.map +1 -1
- package/dist/src/storage/sqlite/migrations/runner.ts +2 -2
- package/dist/src/storage/sqlite/schema.js +3 -3
- package/dist/src/storage/sqlite/schema.sql +9 -0
- package/dist/src/tui/backends/embedded-backend.d.ts +8 -1
- package/dist/src/tui/backends/embedded-backend.js +73 -0
- package/dist/src/tui/backends/embedded-backend.js.map +1 -1
- package/dist/src/tui/backends/gateway-sse-backend.d.ts +2 -1
- package/dist/src/tui/backends/gateway-sse-backend.js +24 -0
- package/dist/src/tui/backends/gateway-sse-backend.js.map +1 -1
- package/dist/src/tui/components/chat-log.d.ts +2 -0
- package/dist/src/tui/components/chat-log.js +19 -0
- package/dist/src/tui/components/chat-log.js.map +1 -1
- package/dist/src/tui/extension-host/autocomplete.d.ts +3 -2
- package/dist/src/tui/extension-host/autocomplete.js +17 -3
- package/dist/src/tui/extension-host/autocomplete.js.map +1 -1
- package/dist/src/tui/extension-host/runtime.d.ts +5 -0
- package/dist/src/tui/extension-host/runtime.js +1 -1
- package/dist/src/tui/extension-host/runtime.js.map +1 -1
- package/dist/src/tui/tui-backend.d.ts +14 -0
- package/dist/src/tui/tui-commands.d.ts +16 -3
- package/dist/src/tui/tui-commands.js +47 -19
- package/dist/src/tui/tui-commands.js.map +1 -1
- package/dist/src/tui/tui-startup-text.js +1 -1
- package/dist/src/tui/tui-startup-text.js.map +1 -1
- package/dist/src/tui/tui.js +72 -1
- package/dist/src/tui/tui.js.map +1 -1
- package/dist/src/voice/tts/openai-compatible-speech.d.ts +1 -1
- package/dist/src/voice/tts/openai-compatible-speech.js.map +1 -1
- package/dist/src/voice/tts/providers/edge-speech.js +14 -2
- package/dist/src/voice/tts/providers/edge-speech.js.map +1 -1
- package/dist/src/voice/tts/speak-core.js +3 -3
- package/dist/src/voice/tts/speak-core.js.map +1 -1
- package/dist/src/voice/tts/speech-provider-types.d.ts +2 -2
- package/dist/src/voice/tts/types.js +1 -1
- package/dist/src/voice/tts/types.js.map +1 -1
- package/dist/src/workflows/domain/result.d.ts +0 -1
- package/dist/src/workflows/engine/workflow-engine.js +7 -23
- package/dist/src/workflows/engine/workflow-engine.js.map +1 -1
- package/package.json +2 -2
- package/dist/gateway/static/root/assets/agent-browser-settings-page-CWh7trjd.js +0 -6
- package/dist/gateway/static/root/assets/agent-defaults-tabbed-page-kC8OuLoj.js +0 -1
- package/dist/gateway/static/root/assets/agents-DJWG26Si.js +0 -71
- package/dist/gateway/static/root/assets/app-management-settings-panel-v24i25Oj.js +0 -1
- package/dist/gateway/static/root/assets/apps-page-0V3DXZ7J.js +0 -1
- package/dist/gateway/static/root/assets/channels-settings-CIKOkYdO.js +0 -1
- package/dist/gateway/static/root/assets/connectors-settings-ClrDS5jH.js +0 -2
- package/dist/gateway/static/root/assets/cron-page-Chi_4u4P.js +0 -3
- package/dist/gateway/static/root/assets/dreaming-settings-B0_rs2tj.js +0 -1
- package/dist/gateway/static/root/assets/gateway-settings-1PDi4lI0.js +0 -1
- package/dist/gateway/static/root/assets/goal-detail-page-D_wwXL-t.js +0 -1
- package/dist/gateway/static/root/assets/goals-page-DZ2toZ8y.js +0 -2
- package/dist/gateway/static/root/assets/goals-settings-LFlwtIKE.js +0 -1
- package/dist/gateway/static/root/assets/heartbeat-settings-BHHAs8ZX.js +0 -1
- package/dist/gateway/static/root/assets/index-DefIdW9q.js +0 -122
- package/dist/gateway/static/root/assets/index-DzmWBkq-.css +0 -1
- package/dist/gateway/static/root/assets/logs-page-j_D2QTuQ.js +0 -2
- package/dist/gateway/static/root/assets/messages-BN_WiUg0.js +0 -3
- package/dist/gateway/static/root/assets/models-hub-panel-CMH_TmZz.js +0 -2
- package/dist/gateway/static/root/assets/note-detail-page-O18BrQPq.js +0 -2
- package/dist/gateway/static/root/assets/notes-page-B_ZYCmY9.js +0 -1
- package/dist/gateway/static/root/assets/remote-access-hub-CwKgWixY.js +0 -1
- package/dist/gateway/static/root/assets/sessions-page-C4fcD-7B.js +0 -1
- package/dist/gateway/static/root/assets/settings-advanced-gate-Ad2OJ86w.js +0 -1
- package/dist/gateway/static/root/assets/settings-page-D2BMY5wo.js +0 -1
- package/dist/gateway/static/root/assets/setup-status-panel-aWwxl_E1.js +0 -1
- package/dist/gateway/static/root/assets/shares-settings-DUE83uIf.js +0 -1
- package/dist/gateway/static/root/assets/skill-reload-api-mWKJcrog.js +0 -1
- package/dist/gateway/static/root/assets/skills-page-0Sx1Q58n.js +0 -2
- package/dist/gateway/static/root/assets/system-settings-panel-hqaBF5aG.js +0 -1
- package/dist/gateway/static/root/assets/use-agent-defaults-form-zbVIQLOA.js +0 -1
- package/dist/gateway/static/root/assets/voice-api-key-field-D6HR0hR2.js +0 -1
- package/dist/gateway/static/root/assets/workflow-page.utils-C0Uq3xyq.js +0 -1
- package/dist/gateway/static/root/assets/workflows-page-DW0fmWhQ.js +0 -18
|
@@ -11,4 +11,4 @@
|
|
|
11
11
|
* - lenses: optional array of { name, angle } to override default lenses
|
|
12
12
|
* - skipAdversarial: when true, skip the adversarial judge phase
|
|
13
13
|
*/
|
|
14
|
-
export declare const MULTI_PERSPECTIVE_REVIEW_SCRIPT = "export const meta = {\n name: 'multi_perspective_review',\n description: 'Review a target from N independent perspectives, then adversarially judge what would actually break.',\n whenToUse: 'User wants a stress-test of a design, plan, PR, or proposal before committing to it.',\n examplePrompts: [\n { field: 'target', text: 'Stress-test this API redesign before we ship' },\n { field: 'target', text: 'Review the migration plan from multiple angles' },\n ],\n i18n: {\n zh: {\n description: '\u4ECE\u591A\u4E2A\u72EC\u7ACB\u89C6\u89D2\u8BC4\u5BA1\u76EE\u6807\uFF0C\u5E76\u7531\u5BF9\u6297\u6027\u8BC4\u5BA1\u5224\u65AD\u5B9E\u9645\u4F1A\u51FA\u4EC0\u4E48\u95EE\u9898\u3002',\n whenToUse: '\u7528\u6237\u60F3\u5728\u843D\u5730\u524D\u5BF9\u8BBE\u8BA1\u3001\u65B9\u6848\u3001PR \u6216\u63D0\u6848\u505A\u538B\u529B\u6D4B\u8BD5\u65F6\u3002',\n examplePrompts: [\n { field: 'target', text: '\u4E0A\u7EBF\u524D\u4ECE\u591A\u89D2\u5EA6\u538B\u529B\u6D4B\u8BD5\u8FD9\u4E2A API redesign' },\n { field: 'target', text: '\u4ECE\u591A\u4E2A\u89C6\u89D2\u8BC4\u5BA1\u8FD9\u4EFD\u8FC1\u79FB\u65B9\u6848' },\n ],\n },\n },\n tags: ['review', 'planning', 'decision'],\n estimatedAgents: { min: 5, max: 6 },\n phases: [\n { title: 'Lenses' },\n { title: 'Adversarial' },\n { title: 'Synthesize' },\n ],\n}\n\nconst READ_ONLY_TOOLS = ['read_file', 'grep', 'find', 'list_dir']\n\nconst target = args && typeof args === 'object' && args.target\n ? String(args.target)\n : 'No explicit target was provided. Treat the currently focused file or recent context as the target.'\n\nconst skipAdversarial = Boolean(args && typeof args === 'object' && args.skipAdversarial)\n\nconst DEFAULT_LENSES = [\n { name: 'User', angle: 'How a real user experiences this. Friction, confusion, surprise paths, accessibility.' },\n { name: 'Operator', angle: 'How an on-call engineer experiences this in production. Failure modes, observability, rollback.' },\n { name: 'Skeptic', angle: 'Hidden assumptions. What is being implied but not stated. What would break under load or weird input.' },\n { name: 'Maintainer', angle: 'Six-month-later view. Clarity, naming, layering, ease of changing nearby code.' },\n]\n\nlet lenses = DEFAULT_LENSES\nif (args && typeof args === 'object' && Array.isArray(args.lenses) && args.lenses.length) {\n lenses = args.lenses\n .filter((l) => l && typeof l === 'object' && l.name && l.angle)\n .map((l) => ({ name: String(l.name), angle: String(l.angle) }))\n if (!lenses.length) lenses = DEFAULT_LENSES\n}\n\nphase('Lenses')\nconst lensViews = await parallel(\n lenses.map((l) => () =>\n agent(\n 'Review the following target through the ' + l.name + ' lens.\\n' +\n 'Lens focus: ' + l.angle + '\\n\\n' +\n 'TARGET:\\n' + target + '\\n\\n' +\n 'Return 3\u20137 concrete observations. Each entry: title (5\u201310 words), why-it-matters (1 sentence), risk (low/med/high).',\n {\n label: l.name + ' lens',\n toolset: READ_ONLY_TOOLS,\n schema: {\n type: 'object',\n properties: {\n observations: {\n type: 'array',\n items: {\n type: 'object',\n properties: {\n title: { type: 'string' },\n why: { type: 'string' },\n risk: { type: 'string', enum: ['low', 'med', 'high'] },\n },\n required: ['title', 'why', 'risk'],\n },\n },\n },\n required: ['observations'],\n },\n },\n ),\n ),\n)\n\nconst valid = lensViews.filter(Boolean)\nconst allObs = valid.flatMap((v, i) =>\n (v?.observations ?? []).map((o) => ({ lens: lenses[i].name, ...o })),\n)\n\nlet verdict = null\nif (!skipAdversarial) {\n phase('Adversarial')\n verdict = await agent(\n 'You are an adversarial judge. Given these multi-lens observations of a target, decide which would actually cause real harm if shipped as-is. ' +\n 'Default to realRisk=false unless an observation has clear, mechanism-level evidence. ' +\n 'Rate evidenceStrength as weak | moderate | strong.\\n\\n' +\n JSON.stringify(allObs, null, 2),\n {\n label: 'adversarial verdict',\n schema: {\n type: 'object',\n properties: {\n verdicts: {\n type: 'array',\n items: {\n type: 'object',\n properties: {\n title: { type: 'string' },\n lens: { type: 'string' },\n realRisk: { type: 'boolean' },\n evidenceStrength: { type: 'string', enum: ['weak', 'moderate', 'strong'] },\n reason: { type: 'string' },\n },\n required: ['title', 'lens', 'realRisk', 'evidenceStrength', 'reason'],\n },\n },\n },\n required: ['verdicts'],\n },\n },\n )\n}\n\nphase('Synthesize')\nconst confirmed = (verdict?.verdicts ?? []).filter((v) => v.realRisk)\nconst goNoGo = skipAdversarial\n ? (allObs.some((o) => o.risk === 'high') ? 'fix_first' : 'ship')\n : confirmed.some((v) => v.evidenceStrength === 'strong')\n ? 'fix_first'\n : confirmed.length\n ? 'fix_first'\n : 'ship'\n\
|
|
14
|
+
export declare const MULTI_PERSPECTIVE_REVIEW_SCRIPT = "export const meta = {\n name: 'multi_perspective_review',\n description: 'Review a target from N independent perspectives, then adversarially judge what would actually break.',\n whenToUse: 'User wants a stress-test of a design, plan, PR, or proposal before committing to it.',\n examplePrompts: [\n { field: 'target', text: 'Stress-test this API redesign before we ship' },\n { field: 'target', text: 'Review the migration plan from multiple angles' },\n ],\n i18n: {\n zh: {\n description: '\u4ECE\u591A\u4E2A\u72EC\u7ACB\u89C6\u89D2\u8BC4\u5BA1\u76EE\u6807\uFF0C\u5E76\u7531\u5BF9\u6297\u6027\u8BC4\u5BA1\u5224\u65AD\u5B9E\u9645\u4F1A\u51FA\u4EC0\u4E48\u95EE\u9898\u3002',\n whenToUse: '\u7528\u6237\u60F3\u5728\u843D\u5730\u524D\u5BF9\u8BBE\u8BA1\u3001\u65B9\u6848\u3001PR \u6216\u63D0\u6848\u505A\u538B\u529B\u6D4B\u8BD5\u65F6\u3002',\n examplePrompts: [\n { field: 'target', text: '\u4E0A\u7EBF\u524D\u4ECE\u591A\u89D2\u5EA6\u538B\u529B\u6D4B\u8BD5\u8FD9\u4E2A API redesign' },\n { field: 'target', text: '\u4ECE\u591A\u4E2A\u89C6\u89D2\u8BC4\u5BA1\u8FD9\u4EFD\u8FC1\u79FB\u65B9\u6848' },\n ],\n },\n },\n tags: ['review', 'planning', 'decision'],\n estimatedAgents: { min: 5, max: 6 },\n phases: [\n { title: 'Lenses' },\n { title: 'Adversarial' },\n { title: 'Synthesize' },\n ],\n}\n\nconst READ_ONLY_TOOLS = ['read_file', 'grep', 'find', 'list_dir']\n\nconst target = args && typeof args === 'object' && args.target\n ? String(args.target)\n : 'No explicit target was provided. Treat the currently focused file or recent context as the target.'\n\nconst skipAdversarial = Boolean(args && typeof args === 'object' && args.skipAdversarial)\n\nconst DEFAULT_LENSES = [\n { name: 'User', angle: 'How a real user experiences this. Friction, confusion, surprise paths, accessibility.' },\n { name: 'Operator', angle: 'How an on-call engineer experiences this in production. Failure modes, observability, rollback.' },\n { name: 'Skeptic', angle: 'Hidden assumptions. What is being implied but not stated. What would break under load or weird input.' },\n { name: 'Maintainer', angle: 'Six-month-later view. Clarity, naming, layering, ease of changing nearby code.' },\n]\n\nlet lenses = DEFAULT_LENSES\nif (args && typeof args === 'object' && Array.isArray(args.lenses) && args.lenses.length) {\n lenses = args.lenses\n .filter((l) => l && typeof l === 'object' && l.name && l.angle)\n .map((l) => ({ name: String(l.name), angle: String(l.angle) }))\n if (!lenses.length) lenses = DEFAULT_LENSES\n}\n\nphase('Lenses')\nconst lensViews = await parallel(\n lenses.map((l) => () =>\n agent(\n 'Review the following target through the ' + l.name + ' lens.\\n' +\n 'Lens focus: ' + l.angle + '\\n\\n' +\n 'TARGET:\\n' + target + '\\n\\n' +\n 'Return 3\u20137 concrete observations. Each entry: title (5\u201310 words), why-it-matters (1 sentence), risk (low/med/high).',\n {\n label: l.name + ' lens',\n toolset: READ_ONLY_TOOLS,\n schema: {\n type: 'object',\n properties: {\n observations: {\n type: 'array',\n items: {\n type: 'object',\n properties: {\n title: { type: 'string' },\n why: { type: 'string' },\n risk: { type: 'string', enum: ['low', 'med', 'high'] },\n },\n required: ['title', 'why', 'risk'],\n },\n },\n },\n required: ['observations'],\n },\n },\n ),\n ),\n)\n\nconst valid = lensViews.filter(Boolean)\nconst allObs = valid.flatMap((v, i) =>\n (v?.observations ?? []).map((o) => ({ lens: lenses[i].name, ...o })),\n)\n\nlet verdict = null\nif (!skipAdversarial) {\n phase('Adversarial')\n verdict = await agent(\n 'You are an adversarial judge. Given these multi-lens observations of a target, decide which would actually cause real harm if shipped as-is. ' +\n 'Default to realRisk=false unless an observation has clear, mechanism-level evidence. ' +\n 'Rate evidenceStrength as weak | moderate | strong.\\n\\n' +\n JSON.stringify(allObs, null, 2),\n {\n label: 'adversarial verdict',\n schema: {\n type: 'object',\n properties: {\n verdicts: {\n type: 'array',\n items: {\n type: 'object',\n properties: {\n title: { type: 'string' },\n lens: { type: 'string' },\n realRisk: { type: 'boolean' },\n evidenceStrength: { type: 'string', enum: ['weak', 'moderate', 'strong'] },\n reason: { type: 'string' },\n },\n required: ['title', 'lens', 'realRisk', 'evidenceStrength', 'reason'],\n },\n },\n },\n required: ['verdicts'],\n },\n },\n )\n}\n\nphase('Synthesize')\nconst confirmed = (verdict?.verdicts ?? []).filter((v) => v.realRisk)\nconst goNoGo = skipAdversarial\n ? (allObs.some((o) => o.risk === 'high') ? 'fix_first' : 'ship')\n : confirmed.some((v) => v.evidenceStrength === 'strong')\n ? 'fix_first'\n : confirmed.length\n ? 'fix_first'\n : 'ship'\n\nconst output = {\n ok: true,\n target,\n lenses: lenses.map((l) => l.name),\n skipAdversarial,\n observationCount: allObs.length,\n confirmedRiskCount: confirmed.length,\n goNoGo,\n topRisks: confirmed.slice(0, 10),\n allVerdicts: verdict?.verdicts ?? [],\n}\nreturn {\n summary: output.goNoGo === 'ship' ? 'No confirmed blocking risks.' : 'Confirmed risks need attention before shipping.',\n sections: [\n { kind: 'risks', title: 'Top risks', items: output.topRisks.map((item) => ({ title: item.title, severity: item.evidenceStrength === 'strong' ? 'high' : 'medium', detail: item.reason })) },\n { kind: 'json', title: 'All verdicts', value: output.allVerdicts },\n ],\n structuredOutput: output,\n}\n";
|
|
@@ -145,7 +145,7 @@ const goNoGo = skipAdversarial
|
|
|
145
145
|
? 'fix_first'
|
|
146
146
|
: 'ship'
|
|
147
147
|
|
|
148
|
-
|
|
148
|
+
const output = {
|
|
149
149
|
ok: true,
|
|
150
150
|
target,
|
|
151
151
|
lenses: lenses.map((l) => l.name),
|
|
@@ -156,6 +156,14 @@ return {
|
|
|
156
156
|
topRisks: confirmed.slice(0, 10),
|
|
157
157
|
allVerdicts: verdict?.verdicts ?? [],
|
|
158
158
|
}
|
|
159
|
+
return {
|
|
160
|
+
summary: output.goNoGo === 'ship' ? 'No confirmed blocking risks.' : 'Confirmed risks need attention before shipping.',
|
|
161
|
+
sections: [
|
|
162
|
+
{ kind: 'risks', title: 'Top risks', items: output.topRisks.map((item) => ({ title: item.title, severity: item.evidenceStrength === 'strong' ? 'high' : 'medium', detail: item.reason })) },
|
|
163
|
+
{ kind: 'json', title: 'All verdicts', value: output.allVerdicts },
|
|
164
|
+
],
|
|
165
|
+
structuredOutput: output,
|
|
166
|
+
}
|
|
159
167
|
`;
|
|
160
168
|
//#endregion
|
|
161
169
|
export { MULTI_PERSPECTIVE_REVIEW_SCRIPT };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"multi-perspective-review.js","names":[],"sources":["../../../../../src/agent/workflow/builtins/multi-perspective-review.ts"],"sourcesContent":["/**\n * Built-in workflow: `multi_perspective_review`\n *\n * Reviews a target (file, PR, design doc, plan — passed via args.target) from\n * several independent perspectives, then asks an adversarial judge to decide\n * what would actually break in practice. Useful for sanity-checking decisions\n * before they ship.\n *\n * Args:\n * - target: what to review\n * - lenses: optional array of { name, angle } to override default lenses\n * - skipAdversarial: when true, skip the adversarial judge phase\n */\n\nexport const MULTI_PERSPECTIVE_REVIEW_SCRIPT = `export const meta = {\n name: 'multi_perspective_review',\n description: 'Review a target from N independent perspectives, then adversarially judge what would actually break.',\n whenToUse: 'User wants a stress-test of a design, plan, PR, or proposal before committing to it.',\n examplePrompts: [\n { field: 'target', text: 'Stress-test this API redesign before we ship' },\n { field: 'target', text: 'Review the migration plan from multiple angles' },\n ],\n i18n: {\n zh: {\n description: '从多个独立视角评审目标,并由对抗性评审判断实际会出什么问题。',\n whenToUse: '用户想在落地前对设计、方案、PR 或提案做压力测试时。',\n examplePrompts: [\n { field: 'target', text: '上线前从多角度压力测试这个 API redesign' },\n { field: 'target', text: '从多个视角评审这份迁移方案' },\n ],\n },\n },\n tags: ['review', 'planning', 'decision'],\n estimatedAgents: { min: 5, max: 6 },\n phases: [\n { title: 'Lenses' },\n { title: 'Adversarial' },\n { title: 'Synthesize' },\n ],\n}\n\nconst READ_ONLY_TOOLS = ['read_file', 'grep', 'find', 'list_dir']\n\nconst target = args && typeof args === 'object' && args.target\n ? String(args.target)\n : 'No explicit target was provided. Treat the currently focused file or recent context as the target.'\n\nconst skipAdversarial = Boolean(args && typeof args === 'object' && args.skipAdversarial)\n\nconst DEFAULT_LENSES = [\n { name: 'User', angle: 'How a real user experiences this. Friction, confusion, surprise paths, accessibility.' },\n { name: 'Operator', angle: 'How an on-call engineer experiences this in production. Failure modes, observability, rollback.' },\n { name: 'Skeptic', angle: 'Hidden assumptions. What is being implied but not stated. What would break under load or weird input.' },\n { name: 'Maintainer', angle: 'Six-month-later view. Clarity, naming, layering, ease of changing nearby code.' },\n]\n\nlet lenses = DEFAULT_LENSES\nif (args && typeof args === 'object' && Array.isArray(args.lenses) && args.lenses.length) {\n lenses = args.lenses\n .filter((l) => l && typeof l === 'object' && l.name && l.angle)\n .map((l) => ({ name: String(l.name), angle: String(l.angle) }))\n if (!lenses.length) lenses = DEFAULT_LENSES\n}\n\nphase('Lenses')\nconst lensViews = await parallel(\n lenses.map((l) => () =>\n agent(\n 'Review the following target through the ' + l.name + ' lens.\\\\n' +\n 'Lens focus: ' + l.angle + '\\\\n\\\\n' +\n 'TARGET:\\\\n' + target + '\\\\n\\\\n' +\n 'Return 3–7 concrete observations. Each entry: title (5–10 words), why-it-matters (1 sentence), risk (low/med/high).',\n {\n label: l.name + ' lens',\n toolset: READ_ONLY_TOOLS,\n schema: {\n type: 'object',\n properties: {\n observations: {\n type: 'array',\n items: {\n type: 'object',\n properties: {\n title: { type: 'string' },\n why: { type: 'string' },\n risk: { type: 'string', enum: ['low', 'med', 'high'] },\n },\n required: ['title', 'why', 'risk'],\n },\n },\n },\n required: ['observations'],\n },\n },\n ),\n ),\n)\n\nconst valid = lensViews.filter(Boolean)\nconst allObs = valid.flatMap((v, i) =>\n (v?.observations ?? []).map((o) => ({ lens: lenses[i].name, ...o })),\n)\n\nlet verdict = null\nif (!skipAdversarial) {\n phase('Adversarial')\n verdict = await agent(\n 'You are an adversarial judge. Given these multi-lens observations of a target, decide which would actually cause real harm if shipped as-is. ' +\n 'Default to realRisk=false unless an observation has clear, mechanism-level evidence. ' +\n 'Rate evidenceStrength as weak | moderate | strong.\\\\n\\\\n' +\n JSON.stringify(allObs, null, 2),\n {\n label: 'adversarial verdict',\n schema: {\n type: 'object',\n properties: {\n verdicts: {\n type: 'array',\n items: {\n type: 'object',\n properties: {\n title: { type: 'string' },\n lens: { type: 'string' },\n realRisk: { type: 'boolean' },\n evidenceStrength: { type: 'string', enum: ['weak', 'moderate', 'strong'] },\n reason: { type: 'string' },\n },\n required: ['title', 'lens', 'realRisk', 'evidenceStrength', 'reason'],\n },\n },\n },\n required: ['verdicts'],\n },\n },\n )\n}\n\nphase('Synthesize')\nconst confirmed = (verdict?.verdicts ?? []).filter((v) => v.realRisk)\nconst goNoGo = skipAdversarial\n ? (allObs.some((o) => o.risk === 'high') ? 'fix_first' : 'ship')\n : confirmed.some((v) => v.evidenceStrength === 'strong')\n ? 'fix_first'\n : confirmed.length\n ? 'fix_first'\n : 'ship'\n\
|
|
1
|
+
{"version":3,"file":"multi-perspective-review.js","names":[],"sources":["../../../../../src/agent/workflow/builtins/multi-perspective-review.ts"],"sourcesContent":["/**\n * Built-in workflow: `multi_perspective_review`\n *\n * Reviews a target (file, PR, design doc, plan — passed via args.target) from\n * several independent perspectives, then asks an adversarial judge to decide\n * what would actually break in practice. Useful for sanity-checking decisions\n * before they ship.\n *\n * Args:\n * - target: what to review\n * - lenses: optional array of { name, angle } to override default lenses\n * - skipAdversarial: when true, skip the adversarial judge phase\n */\n\nexport const MULTI_PERSPECTIVE_REVIEW_SCRIPT = `export const meta = {\n name: 'multi_perspective_review',\n description: 'Review a target from N independent perspectives, then adversarially judge what would actually break.',\n whenToUse: 'User wants a stress-test of a design, plan, PR, or proposal before committing to it.',\n examplePrompts: [\n { field: 'target', text: 'Stress-test this API redesign before we ship' },\n { field: 'target', text: 'Review the migration plan from multiple angles' },\n ],\n i18n: {\n zh: {\n description: '从多个独立视角评审目标,并由对抗性评审判断实际会出什么问题。',\n whenToUse: '用户想在落地前对设计、方案、PR 或提案做压力测试时。',\n examplePrompts: [\n { field: 'target', text: '上线前从多角度压力测试这个 API redesign' },\n { field: 'target', text: '从多个视角评审这份迁移方案' },\n ],\n },\n },\n tags: ['review', 'planning', 'decision'],\n estimatedAgents: { min: 5, max: 6 },\n phases: [\n { title: 'Lenses' },\n { title: 'Adversarial' },\n { title: 'Synthesize' },\n ],\n}\n\nconst READ_ONLY_TOOLS = ['read_file', 'grep', 'find', 'list_dir']\n\nconst target = args && typeof args === 'object' && args.target\n ? String(args.target)\n : 'No explicit target was provided. Treat the currently focused file or recent context as the target.'\n\nconst skipAdversarial = Boolean(args && typeof args === 'object' && args.skipAdversarial)\n\nconst DEFAULT_LENSES = [\n { name: 'User', angle: 'How a real user experiences this. Friction, confusion, surprise paths, accessibility.' },\n { name: 'Operator', angle: 'How an on-call engineer experiences this in production. Failure modes, observability, rollback.' },\n { name: 'Skeptic', angle: 'Hidden assumptions. What is being implied but not stated. What would break under load or weird input.' },\n { name: 'Maintainer', angle: 'Six-month-later view. Clarity, naming, layering, ease of changing nearby code.' },\n]\n\nlet lenses = DEFAULT_LENSES\nif (args && typeof args === 'object' && Array.isArray(args.lenses) && args.lenses.length) {\n lenses = args.lenses\n .filter((l) => l && typeof l === 'object' && l.name && l.angle)\n .map((l) => ({ name: String(l.name), angle: String(l.angle) }))\n if (!lenses.length) lenses = DEFAULT_LENSES\n}\n\nphase('Lenses')\nconst lensViews = await parallel(\n lenses.map((l) => () =>\n agent(\n 'Review the following target through the ' + l.name + ' lens.\\\\n' +\n 'Lens focus: ' + l.angle + '\\\\n\\\\n' +\n 'TARGET:\\\\n' + target + '\\\\n\\\\n' +\n 'Return 3–7 concrete observations. Each entry: title (5–10 words), why-it-matters (1 sentence), risk (low/med/high).',\n {\n label: l.name + ' lens',\n toolset: READ_ONLY_TOOLS,\n schema: {\n type: 'object',\n properties: {\n observations: {\n type: 'array',\n items: {\n type: 'object',\n properties: {\n title: { type: 'string' },\n why: { type: 'string' },\n risk: { type: 'string', enum: ['low', 'med', 'high'] },\n },\n required: ['title', 'why', 'risk'],\n },\n },\n },\n required: ['observations'],\n },\n },\n ),\n ),\n)\n\nconst valid = lensViews.filter(Boolean)\nconst allObs = valid.flatMap((v, i) =>\n (v?.observations ?? []).map((o) => ({ lens: lenses[i].name, ...o })),\n)\n\nlet verdict = null\nif (!skipAdversarial) {\n phase('Adversarial')\n verdict = await agent(\n 'You are an adversarial judge. Given these multi-lens observations of a target, decide which would actually cause real harm if shipped as-is. ' +\n 'Default to realRisk=false unless an observation has clear, mechanism-level evidence. ' +\n 'Rate evidenceStrength as weak | moderate | strong.\\\\n\\\\n' +\n JSON.stringify(allObs, null, 2),\n {\n label: 'adversarial verdict',\n schema: {\n type: 'object',\n properties: {\n verdicts: {\n type: 'array',\n items: {\n type: 'object',\n properties: {\n title: { type: 'string' },\n lens: { type: 'string' },\n realRisk: { type: 'boolean' },\n evidenceStrength: { type: 'string', enum: ['weak', 'moderate', 'strong'] },\n reason: { type: 'string' },\n },\n required: ['title', 'lens', 'realRisk', 'evidenceStrength', 'reason'],\n },\n },\n },\n required: ['verdicts'],\n },\n },\n )\n}\n\nphase('Synthesize')\nconst confirmed = (verdict?.verdicts ?? []).filter((v) => v.realRisk)\nconst goNoGo = skipAdversarial\n ? (allObs.some((o) => o.risk === 'high') ? 'fix_first' : 'ship')\n : confirmed.some((v) => v.evidenceStrength === 'strong')\n ? 'fix_first'\n : confirmed.length\n ? 'fix_first'\n : 'ship'\n\nconst output = {\n ok: true,\n target,\n lenses: lenses.map((l) => l.name),\n skipAdversarial,\n observationCount: allObs.length,\n confirmedRiskCount: confirmed.length,\n goNoGo,\n topRisks: confirmed.slice(0, 10),\n allVerdicts: verdict?.verdicts ?? [],\n}\nreturn {\n summary: output.goNoGo === 'ship' ? 'No confirmed blocking risks.' : 'Confirmed risks need attention before shipping.',\n sections: [\n { kind: 'risks', title: 'Top risks', items: output.topRisks.map((item) => ({ title: item.title, severity: item.evidenceStrength === 'strong' ? 'high' : 'medium', detail: item.reason })) },\n { kind: 'json', title: 'All verdicts', value: output.allVerdicts },\n ],\n structuredOutput: output,\n}\n`\n"],"mappings":";;;;;;;;;;;;;;AAcA,MAAa,kCAAkC"}
|
|
@@ -9,4 +9,4 @@
|
|
|
9
9
|
* - audience: target customers
|
|
10
10
|
* - constraints: time or revenue goals (optional)
|
|
11
11
|
*/
|
|
12
|
-
export declare const OFFER_DESIGN_SCRIPT = "export const meta = {\n name: 'offer_design',\n description: 'Package your skills into sellable offers with tiers, pricing, boundaries, and positioning.',\n whenToUse: 'Solo operator turning expertise into productized services or subscription offers.',\n examplePrompts: [\n { field: 'skills', text: 'Notion systems, light automations, async consulting for creators' },\n { field: 'audience', text: 'Solo creators doing $3k\u201315k/month' },\n ],\n i18n: {\n zh: {\n description: '\u5C06\u4E2A\u4EBA\u80FD\u529B\u6253\u5305\u4E3A\u53EF\u552E\u5356\u7684\u4EA7\u54C1/\u670D\u52A1\uFF1A\u5C42\u7EA7\u3001\u5B9A\u4EF7\u3001\u4EA4\u4ED8\u8FB9\u754C\u4E0E\u5B9A\u4F4D\u3002',\n whenToUse: '\u8D85\u7EA7\u4E2A\u4F53\u60F3\u628A\u4E13\u957F\u4EA7\u54C1\u5316\u3001\u8BBE\u8BA1\u62A5\u4EF7\u4E0E\u5957\u9910\u65F6\u3002',\n examplePrompts: [\n { field: 'skills', text: 'Notion \u7CFB\u7EDF\u642D\u5EFA\u3001\u8F7B\u91CF\u81EA\u52A8\u5316\u3001\u9762\u5411\u521B\u4F5C\u8005\u7684\u5F02\u6B65\u54A8\u8BE2' },\n { field: 'audience', text: '\u6708\u5165 2\u201310 \u4E07\u7684\u72EC\u7ACB\u521B\u4F5C\u8005' },\n ],\n },\n },\n tags: ['planning', 'architecture'],\n estimatedAgents: { min: 4, max: 5 },\n phases: [\n { title: 'Inventory' },\n { title: 'Package' },\n { title: 'Price' },\n { title: 'Position' },\n ],\n}\n\nconst skills = args && typeof args === 'object' && args.skills\n ? String(args.skills)\n : 'Infer your skills from the most recent user turn.'\n\nconst audience = args && typeof args === 'object' && args.audience\n ? String(args.audience)\n : 'Infer target audience from context.'\n\nconst constraints = args && typeof args === 'object' && args.constraints\n ? String(args.constraints)\n : ''\n\nphase('Inventory')\nconst inventory = await agent(\n 'Inventory sellable capabilities for a solo operator. Separate high-leverage repeatable work from custom work. Note time sinks to avoid.\\n\\n' +\n 'SKILLS:\\n' + skills + '\\nAUDIENCE:\\n' + audience +\n (constraints ? '\\nCONSTRAINTS:\\n' + constraints : ''),\n {\n label: 'inventory',\n schema: {\n type: 'object',\n properties: {\n coreCapabilities: { type: 'array', items: { type: 'string' } },\n repeatable: { type: 'array', items: { type: 'string' } },\n customOnly: { type: 'array', items: { type: 'string' } },\n avoid: { type: 'array', items: { type: 'string' } },\n },\n required: ['coreCapabilities', 'repeatable'],\n },\n },\n)\n\nphase('Package')\nconst packages = await agent(\n 'Design 2\u20133 offer tiers (e.g. starter / core / premium) with clear deliverables, boundaries, and who each tier is for. Fit solo capacity \u2014 no fake scale.\\n\\n' +\n JSON.stringify({ skills, audience, constraints, inventory }, null, 2),\n {\n label: 'package',\n schema: {\n type: 'object',\n properties: {\n tiers: {\n type: 'array',\n items: {\n type: 'object',\n properties: {\n name: { type: 'string' },\n forWho: { type: 'string' },\n deliverables: { type: 'array', items: { type: 'string' } },\n boundaries: { type: 'array', items: { type: 'string' } },\n timeCommitment: { type: 'string' },\n },\n required: ['name', 'deliverables', 'boundaries'],\n },\n },\n },\n required: ['tiers'],\n },\n },\n)\n\nphase('Price')\nconst pricing = await agent(\n 'Recommend pricing for each tier: price range, pricing model (fixed / retainer / subscription), rationale, and upsell path. Be realistic for solo operators.\\n\\n' +\n JSON.stringify({ audience, constraints, packages }, null, 2),\n {\n label: 'price',\n schema: {\n type: 'object',\n properties: {\n tiers: {\n type: 'array',\n items: {\n type: 'object',\n properties: {\n name: { type: 'string' },\n priceRange: { type: 'string' },\n model: { type: 'string' },\n rationale: { type: 'string' },\n },\n required: ['name', 'priceRange', 'model'],\n },\n },\n upsellPath: { type: 'string' },\n },\n required: ['tiers'],\n },\n },\n)\n\nphase('Position')\nconst positioning = await agent(\n 'Write positioning: one-line value prop, differentiation vs DIY and vs agencies, ideal customer profile, and launch checklist (first 3 steps).\\n\\n' +\n JSON.stringify({ inventory, packages, pricing }, null, 2),\n {\n label: 'position',\n schema: {\n type: 'object',\n properties: {\n valueProp: { type: 'string' },\n differentiation: { type: 'array', items: { type: 'string' } },\n idealCustomer: { type: 'string' },\n launchChecklist: { type: 'array', items: { type: 'string' } },\n },\n required: ['valueProp', 'idealCustomer', 'launchChecklist'],\n },\n },\n)\n\
|
|
12
|
+
export declare const OFFER_DESIGN_SCRIPT = "export const meta = {\n name: 'offer_design',\n description: 'Package your skills into sellable offers with tiers, pricing, boundaries, and positioning.',\n whenToUse: 'Solo operator turning expertise into productized services or subscription offers.',\n examplePrompts: [\n { field: 'skills', text: 'Notion systems, light automations, async consulting for creators' },\n { field: 'audience', text: 'Solo creators doing $3k\u201315k/month' },\n ],\n i18n: {\n zh: {\n description: '\u5C06\u4E2A\u4EBA\u80FD\u529B\u6253\u5305\u4E3A\u53EF\u552E\u5356\u7684\u4EA7\u54C1/\u670D\u52A1\uFF1A\u5C42\u7EA7\u3001\u5B9A\u4EF7\u3001\u4EA4\u4ED8\u8FB9\u754C\u4E0E\u5B9A\u4F4D\u3002',\n whenToUse: '\u8D85\u7EA7\u4E2A\u4F53\u60F3\u628A\u4E13\u957F\u4EA7\u54C1\u5316\u3001\u8BBE\u8BA1\u62A5\u4EF7\u4E0E\u5957\u9910\u65F6\u3002',\n examplePrompts: [\n { field: 'skills', text: 'Notion \u7CFB\u7EDF\u642D\u5EFA\u3001\u8F7B\u91CF\u81EA\u52A8\u5316\u3001\u9762\u5411\u521B\u4F5C\u8005\u7684\u5F02\u6B65\u54A8\u8BE2' },\n { field: 'audience', text: '\u6708\u5165 2\u201310 \u4E07\u7684\u72EC\u7ACB\u521B\u4F5C\u8005' },\n ],\n },\n },\n tags: ['planning', 'architecture'],\n estimatedAgents: { min: 4, max: 5 },\n phases: [\n { title: 'Inventory' },\n { title: 'Package' },\n { title: 'Price' },\n { title: 'Position' },\n ],\n}\n\nconst skills = args && typeof args === 'object' && args.skills\n ? String(args.skills)\n : 'Infer your skills from the most recent user turn.'\n\nconst audience = args && typeof args === 'object' && args.audience\n ? String(args.audience)\n : 'Infer target audience from context.'\n\nconst constraints = args && typeof args === 'object' && args.constraints\n ? String(args.constraints)\n : ''\n\nphase('Inventory')\nconst inventory = await agent(\n 'Inventory sellable capabilities for a solo operator. Separate high-leverage repeatable work from custom work. Note time sinks to avoid.\\n\\n' +\n 'SKILLS:\\n' + skills + '\\nAUDIENCE:\\n' + audience +\n (constraints ? '\\nCONSTRAINTS:\\n' + constraints : ''),\n {\n label: 'inventory',\n schema: {\n type: 'object',\n properties: {\n coreCapabilities: { type: 'array', items: { type: 'string' } },\n repeatable: { type: 'array', items: { type: 'string' } },\n customOnly: { type: 'array', items: { type: 'string' } },\n avoid: { type: 'array', items: { type: 'string' } },\n },\n required: ['coreCapabilities', 'repeatable'],\n },\n },\n)\n\nphase('Package')\nconst packages = await agent(\n 'Design 2\u20133 offer tiers (e.g. starter / core / premium) with clear deliverables, boundaries, and who each tier is for. Fit solo capacity \u2014 no fake scale.\\n\\n' +\n JSON.stringify({ skills, audience, constraints, inventory }, null, 2),\n {\n label: 'package',\n schema: {\n type: 'object',\n properties: {\n tiers: {\n type: 'array',\n items: {\n type: 'object',\n properties: {\n name: { type: 'string' },\n forWho: { type: 'string' },\n deliverables: { type: 'array', items: { type: 'string' } },\n boundaries: { type: 'array', items: { type: 'string' } },\n timeCommitment: { type: 'string' },\n },\n required: ['name', 'deliverables', 'boundaries'],\n },\n },\n },\n required: ['tiers'],\n },\n },\n)\n\nphase('Price')\nconst pricing = await agent(\n 'Recommend pricing for each tier: price range, pricing model (fixed / retainer / subscription), rationale, and upsell path. Be realistic for solo operators.\\n\\n' +\n JSON.stringify({ audience, constraints, packages }, null, 2),\n {\n label: 'price',\n schema: {\n type: 'object',\n properties: {\n tiers: {\n type: 'array',\n items: {\n type: 'object',\n properties: {\n name: { type: 'string' },\n priceRange: { type: 'string' },\n model: { type: 'string' },\n rationale: { type: 'string' },\n },\n required: ['name', 'priceRange', 'model'],\n },\n },\n upsellPath: { type: 'string' },\n },\n required: ['tiers'],\n },\n },\n)\n\nphase('Position')\nconst positioning = await agent(\n 'Write positioning: one-line value prop, differentiation vs DIY and vs agencies, ideal customer profile, and launch checklist (first 3 steps).\\n\\n' +\n JSON.stringify({ inventory, packages, pricing }, null, 2),\n {\n label: 'position',\n schema: {\n type: 'object',\n properties: {\n valueProp: { type: 'string' },\n differentiation: { type: 'array', items: { type: 'string' } },\n idealCustomer: { type: 'string' },\n launchChecklist: { type: 'array', items: { type: 'string' } },\n },\n required: ['valueProp', 'idealCustomer', 'launchChecklist'],\n },\n },\n)\n\nconst output = {\n ok: true,\n inventory,\n packages,\n pricing,\n ...(positioning ?? { valueProp: 'positioning failed', launchChecklist: [] }),\n}\nreturn {\n summary: output.valueProp,\n sections: [\n { kind: 'json', title: 'Packages', value: output.packages },\n { kind: 'json', title: 'Pricing', value: output.pricing },\n { kind: 'questions', title: 'Launch checklist', items: output.launchChecklist },\n ],\n structuredOutput: output,\n}\n";
|
|
@@ -147,13 +147,22 @@ const positioning = await agent(
|
|
|
147
147
|
},
|
|
148
148
|
)
|
|
149
149
|
|
|
150
|
-
|
|
150
|
+
const output = {
|
|
151
151
|
ok: true,
|
|
152
152
|
inventory,
|
|
153
153
|
packages,
|
|
154
154
|
pricing,
|
|
155
155
|
...(positioning ?? { valueProp: 'positioning failed', launchChecklist: [] }),
|
|
156
156
|
}
|
|
157
|
+
return {
|
|
158
|
+
summary: output.valueProp,
|
|
159
|
+
sections: [
|
|
160
|
+
{ kind: 'json', title: 'Packages', value: output.packages },
|
|
161
|
+
{ kind: 'json', title: 'Pricing', value: output.pricing },
|
|
162
|
+
{ kind: 'questions', title: 'Launch checklist', items: output.launchChecklist },
|
|
163
|
+
],
|
|
164
|
+
structuredOutput: output,
|
|
165
|
+
}
|
|
157
166
|
`;
|
|
158
167
|
//#endregion
|
|
159
168
|
export { OFFER_DESIGN_SCRIPT };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"offer-design.js","names":[],"sources":["../../../../../src/agent/workflow/builtins/offer-design.ts"],"sourcesContent":["/**\n * Built-in workflow: `offer_design`\n *\n * Package skills and time into sellable offers — tiers, pricing, delivery\n * boundaries, and positioning for solopreneurs.\n *\n * Args:\n * - skills: what you can do\n * - audience: target customers\n * - constraints: time or revenue goals (optional)\n */\n\nexport const OFFER_DESIGN_SCRIPT = `export const meta = {\n name: 'offer_design',\n description: 'Package your skills into sellable offers with tiers, pricing, boundaries, and positioning.',\n whenToUse: 'Solo operator turning expertise into productized services or subscription offers.',\n examplePrompts: [\n { field: 'skills', text: 'Notion systems, light automations, async consulting for creators' },\n { field: 'audience', text: 'Solo creators doing $3k–15k/month' },\n ],\n i18n: {\n zh: {\n description: '将个人能力打包为可售卖的产品/服务:层级、定价、交付边界与定位。',\n whenToUse: '超级个体想把专长产品化、设计报价与套餐时。',\n examplePrompts: [\n { field: 'skills', text: 'Notion 系统搭建、轻量自动化、面向创作者的异步咨询' },\n { field: 'audience', text: '月入 2–10 万的独立创作者' },\n ],\n },\n },\n tags: ['planning', 'architecture'],\n estimatedAgents: { min: 4, max: 5 },\n phases: [\n { title: 'Inventory' },\n { title: 'Package' },\n { title: 'Price' },\n { title: 'Position' },\n ],\n}\n\nconst skills = args && typeof args === 'object' && args.skills\n ? String(args.skills)\n : 'Infer your skills from the most recent user turn.'\n\nconst audience = args && typeof args === 'object' && args.audience\n ? String(args.audience)\n : 'Infer target audience from context.'\n\nconst constraints = args && typeof args === 'object' && args.constraints\n ? String(args.constraints)\n : ''\n\nphase('Inventory')\nconst inventory = await agent(\n 'Inventory sellable capabilities for a solo operator. Separate high-leverage repeatable work from custom work. Note time sinks to avoid.\\\\n\\\\n' +\n 'SKILLS:\\\\n' + skills + '\\\\nAUDIENCE:\\\\n' + audience +\n (constraints ? '\\\\nCONSTRAINTS:\\\\n' + constraints : ''),\n {\n label: 'inventory',\n schema: {\n type: 'object',\n properties: {\n coreCapabilities: { type: 'array', items: { type: 'string' } },\n repeatable: { type: 'array', items: { type: 'string' } },\n customOnly: { type: 'array', items: { type: 'string' } },\n avoid: { type: 'array', items: { type: 'string' } },\n },\n required: ['coreCapabilities', 'repeatable'],\n },\n },\n)\n\nphase('Package')\nconst packages = await agent(\n 'Design 2–3 offer tiers (e.g. starter / core / premium) with clear deliverables, boundaries, and who each tier is for. Fit solo capacity — no fake scale.\\\\n\\\\n' +\n JSON.stringify({ skills, audience, constraints, inventory }, null, 2),\n {\n label: 'package',\n schema: {\n type: 'object',\n properties: {\n tiers: {\n type: 'array',\n items: {\n type: 'object',\n properties: {\n name: { type: 'string' },\n forWho: { type: 'string' },\n deliverables: { type: 'array', items: { type: 'string' } },\n boundaries: { type: 'array', items: { type: 'string' } },\n timeCommitment: { type: 'string' },\n },\n required: ['name', 'deliverables', 'boundaries'],\n },\n },\n },\n required: ['tiers'],\n },\n },\n)\n\nphase('Price')\nconst pricing = await agent(\n 'Recommend pricing for each tier: price range, pricing model (fixed / retainer / subscription), rationale, and upsell path. Be realistic for solo operators.\\\\n\\\\n' +\n JSON.stringify({ audience, constraints, packages }, null, 2),\n {\n label: 'price',\n schema: {\n type: 'object',\n properties: {\n tiers: {\n type: 'array',\n items: {\n type: 'object',\n properties: {\n name: { type: 'string' },\n priceRange: { type: 'string' },\n model: { type: 'string' },\n rationale: { type: 'string' },\n },\n required: ['name', 'priceRange', 'model'],\n },\n },\n upsellPath: { type: 'string' },\n },\n required: ['tiers'],\n },\n },\n)\n\nphase('Position')\nconst positioning = await agent(\n 'Write positioning: one-line value prop, differentiation vs DIY and vs agencies, ideal customer profile, and launch checklist (first 3 steps).\\\\n\\\\n' +\n JSON.stringify({ inventory, packages, pricing }, null, 2),\n {\n label: 'position',\n schema: {\n type: 'object',\n properties: {\n valueProp: { type: 'string' },\n differentiation: { type: 'array', items: { type: 'string' } },\n idealCustomer: { type: 'string' },\n launchChecklist: { type: 'array', items: { type: 'string' } },\n },\n required: ['valueProp', 'idealCustomer', 'launchChecklist'],\n },\n },\n)\n\
|
|
1
|
+
{"version":3,"file":"offer-design.js","names":[],"sources":["../../../../../src/agent/workflow/builtins/offer-design.ts"],"sourcesContent":["/**\n * Built-in workflow: `offer_design`\n *\n * Package skills and time into sellable offers — tiers, pricing, delivery\n * boundaries, and positioning for solopreneurs.\n *\n * Args:\n * - skills: what you can do\n * - audience: target customers\n * - constraints: time or revenue goals (optional)\n */\n\nexport const OFFER_DESIGN_SCRIPT = `export const meta = {\n name: 'offer_design',\n description: 'Package your skills into sellable offers with tiers, pricing, boundaries, and positioning.',\n whenToUse: 'Solo operator turning expertise into productized services or subscription offers.',\n examplePrompts: [\n { field: 'skills', text: 'Notion systems, light automations, async consulting for creators' },\n { field: 'audience', text: 'Solo creators doing $3k–15k/month' },\n ],\n i18n: {\n zh: {\n description: '将个人能力打包为可售卖的产品/服务:层级、定价、交付边界与定位。',\n whenToUse: '超级个体想把专长产品化、设计报价与套餐时。',\n examplePrompts: [\n { field: 'skills', text: 'Notion 系统搭建、轻量自动化、面向创作者的异步咨询' },\n { field: 'audience', text: '月入 2–10 万的独立创作者' },\n ],\n },\n },\n tags: ['planning', 'architecture'],\n estimatedAgents: { min: 4, max: 5 },\n phases: [\n { title: 'Inventory' },\n { title: 'Package' },\n { title: 'Price' },\n { title: 'Position' },\n ],\n}\n\nconst skills = args && typeof args === 'object' && args.skills\n ? String(args.skills)\n : 'Infer your skills from the most recent user turn.'\n\nconst audience = args && typeof args === 'object' && args.audience\n ? String(args.audience)\n : 'Infer target audience from context.'\n\nconst constraints = args && typeof args === 'object' && args.constraints\n ? String(args.constraints)\n : ''\n\nphase('Inventory')\nconst inventory = await agent(\n 'Inventory sellable capabilities for a solo operator. Separate high-leverage repeatable work from custom work. Note time sinks to avoid.\\\\n\\\\n' +\n 'SKILLS:\\\\n' + skills + '\\\\nAUDIENCE:\\\\n' + audience +\n (constraints ? '\\\\nCONSTRAINTS:\\\\n' + constraints : ''),\n {\n label: 'inventory',\n schema: {\n type: 'object',\n properties: {\n coreCapabilities: { type: 'array', items: { type: 'string' } },\n repeatable: { type: 'array', items: { type: 'string' } },\n customOnly: { type: 'array', items: { type: 'string' } },\n avoid: { type: 'array', items: { type: 'string' } },\n },\n required: ['coreCapabilities', 'repeatable'],\n },\n },\n)\n\nphase('Package')\nconst packages = await agent(\n 'Design 2–3 offer tiers (e.g. starter / core / premium) with clear deliverables, boundaries, and who each tier is for. Fit solo capacity — no fake scale.\\\\n\\\\n' +\n JSON.stringify({ skills, audience, constraints, inventory }, null, 2),\n {\n label: 'package',\n schema: {\n type: 'object',\n properties: {\n tiers: {\n type: 'array',\n items: {\n type: 'object',\n properties: {\n name: { type: 'string' },\n forWho: { type: 'string' },\n deliverables: { type: 'array', items: { type: 'string' } },\n boundaries: { type: 'array', items: { type: 'string' } },\n timeCommitment: { type: 'string' },\n },\n required: ['name', 'deliverables', 'boundaries'],\n },\n },\n },\n required: ['tiers'],\n },\n },\n)\n\nphase('Price')\nconst pricing = await agent(\n 'Recommend pricing for each tier: price range, pricing model (fixed / retainer / subscription), rationale, and upsell path. Be realistic for solo operators.\\\\n\\\\n' +\n JSON.stringify({ audience, constraints, packages }, null, 2),\n {\n label: 'price',\n schema: {\n type: 'object',\n properties: {\n tiers: {\n type: 'array',\n items: {\n type: 'object',\n properties: {\n name: { type: 'string' },\n priceRange: { type: 'string' },\n model: { type: 'string' },\n rationale: { type: 'string' },\n },\n required: ['name', 'priceRange', 'model'],\n },\n },\n upsellPath: { type: 'string' },\n },\n required: ['tiers'],\n },\n },\n)\n\nphase('Position')\nconst positioning = await agent(\n 'Write positioning: one-line value prop, differentiation vs DIY and vs agencies, ideal customer profile, and launch checklist (first 3 steps).\\\\n\\\\n' +\n JSON.stringify({ inventory, packages, pricing }, null, 2),\n {\n label: 'position',\n schema: {\n type: 'object',\n properties: {\n valueProp: { type: 'string' },\n differentiation: { type: 'array', items: { type: 'string' } },\n idealCustomer: { type: 'string' },\n launchChecklist: { type: 'array', items: { type: 'string' } },\n },\n required: ['valueProp', 'idealCustomer', 'launchChecklist'],\n },\n },\n)\n\nconst output = {\n ok: true,\n inventory,\n packages,\n pricing,\n ...(positioning ?? { valueProp: 'positioning failed', launchChecklist: [] }),\n}\nreturn {\n summary: output.valueProp,\n sections: [\n { kind: 'json', title: 'Packages', value: output.packages },\n { kind: 'json', title: 'Pricing', value: output.pricing },\n { kind: 'questions', title: 'Launch checklist', items: output.launchChecklist },\n ],\n structuredOutput: output,\n}\n`\n"],"mappings":";;;;;;;;;;;;AAYA,MAAa,sBAAsB"}
|
|
@@ -9,4 +9,4 @@
|
|
|
9
9
|
* - target: PR description, diff, commit range, or file list
|
|
10
10
|
* - diff: alias for target
|
|
11
11
|
*/
|
|
12
|
-
export declare const PR_REVIEW_SCRIPT = "export const meta = {\n name: 'pr_review',\n description: 'Review a PR/diff/commit range with parallel focused reviewers and a ship/block verdict.',\n whenToUse: 'User asks to review a PR, diff, specific changes, or commit range (not the whole repo).',\n examplePrompts: [\n { field: 'target', text: 'Review the changes on this branch' },\n { field: 'target', text: 'Review PR #42 for ship/block verdict' },\n ],\n i18n: {\n zh: {\n description: '\u5E76\u884C\u805A\u7126\u5BA1\u67E5 PR\u3001diff \u6216\u63D0\u4EA4\u8303\u56F4\uFF0C\u5E76\u7ED9\u51FA\u53EF\u5408\u5E76/\u5E94\u62E6\u622A\u7684\u7ED3\u8BBA\u3002',\n whenToUse: '\u7528\u6237\u8981\u5BA1\u67E5 PR\u3001diff\u3001\u7279\u5B9A\u6539\u52A8\u6216\u63D0\u4EA4\u8303\u56F4\uFF08\u800C\u975E\u6574\u5E93\uFF09\u65F6\u3002',\n examplePrompts: [\n { field: 'target', text: '\u5BA1\u67E5\u5F53\u524D\u5206\u652F\u4E0A\u7684\u6539\u52A8' },\n { field: 'target', text: '\u5BA1\u67E5 PR #42\uFF0C\u7ED9\u51FA\u662F\u5426\u53EF\u5408\u5E76\u7684\u7ED3\u8BBA' },\n ],\n },\n },\n tags: ['code-review', 'pr'],\n estimatedAgents: { min: 7, max: 7 },\n phases: [\n { title: 'Scope' },\n { title: 'Review' },\n { title: 'Verdict' },\n ],\n}\n\nconst READ_ONLY_TOOLS = ['read_file', 'grep', 'find', 'list_dir', 'shell']\n\nconst target = args && typeof args === 'object'\n ? String(args.target ?? args.diff ?? '')\n : ''\nconst reviewTarget = target.trim()\n ? target\n : 'Recent changes in the working tree or the diff/context from the current conversation.'\n\nconst REVIEWERS = [\n { key: 'correctness', focus: 'Logic bugs, edge cases, error handling, null safety, race conditions in changed code.' },\n { key: 'security', focus: 'Auth/authz regressions, input validation, secret exposure, injection, unsafe deserialization in the diff.' },\n { key: 'tests', focus: 'Missing tests for changed behavior, brittle assertions, untested edge cases introduced by this change.' },\n { key: 'api_compat', focus: 'Breaking public API changes, schema migrations, backward compatibility, deprecation handling.' },\n { key: 'perf', focus: 'Regressions in hot paths, accidental N+1, sync I/O, unbounded loops or allocations in changed code.' },\n]\n\nphase('Scope')\nconst scope = await agent(\n 'Identify what changed for this review target. List changed files, blast radius (what depends on them), and the apparent intent of the change. Be concise.\\n\\nTARGET:\\n' +\n reviewTarget,\n {\n label: 'change scope',\n toolset: READ_ONLY_TOOLS,\n schema: {\n type: 'object',\n properties: {\n changedFiles: { type: 'array', items: { type: 'string' } },\n intent: { type: 'string' },\n blastRadius: { type: 'string' },\n },\n required: ['changedFiles', 'intent'],\n },\n },\n)\n\nphase('Review')\nconst reviews = await parallel(\n REVIEWERS.map((r) => () =>\n agent(\n 'Review these changes through the ' + r.key + ' lens.\\n' +\n 'Focus: ' + r.focus + '\\n\\n' +\n 'TARGET:\\n' + reviewTarget + '\\n\\n' +\n 'SCOPE:\\n' + JSON.stringify(scope, null, 2) + '\\n\\n' +\n 'Return findings: file, severity (low/med/high/blocker), title, fix suggestion. Blocker = must fix before merge.',\n {\n label: r.key,\n toolset: READ_ONLY_TOOLS,\n schema: {\n type: 'object',\n properties: {\n findings: {\n type: 'array',\n items: {\n type: 'object',\n properties: {\n file: { type: 'string' },\n severity: { type: 'string', enum: ['low', 'med', 'high', 'blocker'] },\n title: { type: 'string' },\n fix: { type: 'string' },\n },\n required: ['file', 'severity', 'title', 'fix'],\n },\n },\n },\n required: ['findings'],\n },\n },\n ),\n ),\n)\n\nphase('Verdict')\nconst live = reviews.filter(Boolean)\nconst byReviewer = {}\nfor (let i = 0; i < REVIEWERS.length; i++) {\n byReviewer[REVIEWERS[i].key] = live[i]?.findings ?? []\n}\n\nconst verdict = await agent(\n 'Synthesize a PR review verdict. Separate blockers from suggestions. Deduplicate. Recommend ship | fix_first | block.\\n\\n' +\n JSON.stringify(byReviewer, null, 2),\n {\n label: 'verdict',\n schema: {\n type: 'object',\n properties: {\n recommendation: { type: 'string', enum: ['ship', 'fix_first', 'block'] },\n summary: { type: 'string' },\n blockers: {\n type: 'array',\n items: {\n type: 'object',\n properties: {\n file: { type: 'string' },\n title: { type: 'string' },\n fix: { type: 'string' },\n },\n required: ['file', 'title'],\n },\n },\n suggestions: {\n type: 'array',\n items: {\n type: 'object',\n properties: {\n file: { type: 'string' },\n severity: { type: 'string' },\n title: { type: 'string' },\n },\n required: ['file', 'title'],\n },\n },\n },\n required: ['recommendation', 'summary', 'blockers'],\n },\n },\n)\n\
|
|
12
|
+
export declare const PR_REVIEW_SCRIPT = "export const meta = {\n name: 'pr_review',\n description: 'Review a PR/diff/commit range with parallel focused reviewers and a ship/block verdict.',\n whenToUse: 'User asks to review a PR, diff, specific changes, or commit range (not the whole repo).',\n examplePrompts: [\n { field: 'target', text: 'Review the changes on this branch' },\n { field: 'target', text: 'Review PR #42 for ship/block verdict' },\n ],\n i18n: {\n zh: {\n description: '\u5E76\u884C\u805A\u7126\u5BA1\u67E5 PR\u3001diff \u6216\u63D0\u4EA4\u8303\u56F4\uFF0C\u5E76\u7ED9\u51FA\u53EF\u5408\u5E76/\u5E94\u62E6\u622A\u7684\u7ED3\u8BBA\u3002',\n whenToUse: '\u7528\u6237\u8981\u5BA1\u67E5 PR\u3001diff\u3001\u7279\u5B9A\u6539\u52A8\u6216\u63D0\u4EA4\u8303\u56F4\uFF08\u800C\u975E\u6574\u5E93\uFF09\u65F6\u3002',\n examplePrompts: [\n { field: 'target', text: '\u5BA1\u67E5\u5F53\u524D\u5206\u652F\u4E0A\u7684\u6539\u52A8' },\n { field: 'target', text: '\u5BA1\u67E5 PR #42\uFF0C\u7ED9\u51FA\u662F\u5426\u53EF\u5408\u5E76\u7684\u7ED3\u8BBA' },\n ],\n },\n },\n tags: ['code-review', 'pr'],\n estimatedAgents: { min: 7, max: 7 },\n phases: [\n { title: 'Scope' },\n { title: 'Review' },\n { title: 'Verdict' },\n ],\n}\n\nconst READ_ONLY_TOOLS = ['read_file', 'grep', 'find', 'list_dir', 'shell']\n\nconst target = args && typeof args === 'object'\n ? String(args.target ?? args.diff ?? '')\n : ''\nconst reviewTarget = target.trim()\n ? target\n : 'Recent changes in the working tree or the diff/context from the current conversation.'\n\nconst REVIEWERS = [\n { key: 'correctness', focus: 'Logic bugs, edge cases, error handling, null safety, race conditions in changed code.' },\n { key: 'security', focus: 'Auth/authz regressions, input validation, secret exposure, injection, unsafe deserialization in the diff.' },\n { key: 'tests', focus: 'Missing tests for changed behavior, brittle assertions, untested edge cases introduced by this change.' },\n { key: 'api_compat', focus: 'Breaking public API changes, schema migrations, backward compatibility, deprecation handling.' },\n { key: 'perf', focus: 'Regressions in hot paths, accidental N+1, sync I/O, unbounded loops or allocations in changed code.' },\n]\n\nphase('Scope')\nconst scope = await agent(\n 'Identify what changed for this review target. List changed files, blast radius (what depends on them), and the apparent intent of the change. Be concise.\\n\\nTARGET:\\n' +\n reviewTarget,\n {\n label: 'change scope',\n toolset: READ_ONLY_TOOLS,\n schema: {\n type: 'object',\n properties: {\n changedFiles: { type: 'array', items: { type: 'string' } },\n intent: { type: 'string' },\n blastRadius: { type: 'string' },\n },\n required: ['changedFiles', 'intent'],\n },\n },\n)\n\nphase('Review')\nconst reviews = await parallel(\n REVIEWERS.map((r) => () =>\n agent(\n 'Review these changes through the ' + r.key + ' lens.\\n' +\n 'Focus: ' + r.focus + '\\n\\n' +\n 'TARGET:\\n' + reviewTarget + '\\n\\n' +\n 'SCOPE:\\n' + JSON.stringify(scope, null, 2) + '\\n\\n' +\n 'Return findings: file, severity (low/med/high/blocker), title, fix suggestion. Blocker = must fix before merge.',\n {\n label: r.key,\n toolset: READ_ONLY_TOOLS,\n schema: {\n type: 'object',\n properties: {\n findings: {\n type: 'array',\n items: {\n type: 'object',\n properties: {\n file: { type: 'string' },\n severity: { type: 'string', enum: ['low', 'med', 'high', 'blocker'] },\n title: { type: 'string' },\n fix: { type: 'string' },\n },\n required: ['file', 'severity', 'title', 'fix'],\n },\n },\n },\n required: ['findings'],\n },\n },\n ),\n ),\n)\n\nphase('Verdict')\nconst live = reviews.filter(Boolean)\nconst byReviewer = {}\nfor (let i = 0; i < REVIEWERS.length; i++) {\n byReviewer[REVIEWERS[i].key] = live[i]?.findings ?? []\n}\n\nconst verdict = await agent(\n 'Synthesize a PR review verdict. Separate blockers from suggestions. Deduplicate. Recommend ship | fix_first | block.\\n\\n' +\n JSON.stringify(byReviewer, null, 2),\n {\n label: 'verdict',\n schema: {\n type: 'object',\n properties: {\n recommendation: { type: 'string', enum: ['ship', 'fix_first', 'block'] },\n summary: { type: 'string' },\n blockers: {\n type: 'array',\n items: {\n type: 'object',\n properties: {\n file: { type: 'string' },\n title: { type: 'string' },\n fix: { type: 'string' },\n },\n required: ['file', 'title'],\n },\n },\n suggestions: {\n type: 'array',\n items: {\n type: 'object',\n properties: {\n file: { type: 'string' },\n severity: { type: 'string' },\n title: { type: 'string' },\n },\n required: ['file', 'title'],\n },\n },\n },\n required: ['recommendation', 'summary', 'blockers'],\n },\n },\n)\n\nconst output = {\n ok: true,\n target: reviewTarget,\n scope,\n ...(verdict ?? { recommendation: 'fix_first', summary: 'verdict failed', blockers: [], suggestions: [] }),\n byReviewer,\n}\nreturn {\n summary: output.summary,\n sections: [\n { kind: 'findings', title: 'Blockers', items: output.blockers.map((item) => ({ title: item.title, severity: 'high', file: item.file, detail: item.fix })) },\n { kind: 'findings', title: 'Suggestions', items: output.suggestions.map((item) => ({ title: item.title, severity: item.severity, file: item.file })) },\n ],\n structuredOutput: output,\n}\n";
|
|
@@ -156,13 +156,21 @@ const verdict = await agent(
|
|
|
156
156
|
},
|
|
157
157
|
)
|
|
158
158
|
|
|
159
|
-
|
|
159
|
+
const output = {
|
|
160
160
|
ok: true,
|
|
161
161
|
target: reviewTarget,
|
|
162
162
|
scope,
|
|
163
163
|
...(verdict ?? { recommendation: 'fix_first', summary: 'verdict failed', blockers: [], suggestions: [] }),
|
|
164
164
|
byReviewer,
|
|
165
165
|
}
|
|
166
|
+
return {
|
|
167
|
+
summary: output.summary,
|
|
168
|
+
sections: [
|
|
169
|
+
{ kind: 'findings', title: 'Blockers', items: output.blockers.map((item) => ({ title: item.title, severity: 'high', file: item.file, detail: item.fix })) },
|
|
170
|
+
{ kind: 'findings', title: 'Suggestions', items: output.suggestions.map((item) => ({ title: item.title, severity: item.severity, file: item.file })) },
|
|
171
|
+
],
|
|
172
|
+
structuredOutput: output,
|
|
173
|
+
}
|
|
166
174
|
`;
|
|
167
175
|
//#endregion
|
|
168
176
|
export { PR_REVIEW_SCRIPT };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pr-review.js","names":[],"sources":["../../../../../src/agent/workflow/builtins/pr-review.ts"],"sourcesContent":["/**\n * Built-in workflow: `pr_review`\n *\n * Focused review of a PR, diff, or commit range — lighter than full repo audit.\n * Parallel reviewers cover correctness, security, tests, API compat, and perf;\n * final phase produces a ship/block verdict with blockers vs suggestions.\n *\n * Args:\n * - target: PR description, diff, commit range, or file list\n * - diff: alias for target\n */\n\nexport const PR_REVIEW_SCRIPT = `export const meta = {\n name: 'pr_review',\n description: 'Review a PR/diff/commit range with parallel focused reviewers and a ship/block verdict.',\n whenToUse: 'User asks to review a PR, diff, specific changes, or commit range (not the whole repo).',\n examplePrompts: [\n { field: 'target', text: 'Review the changes on this branch' },\n { field: 'target', text: 'Review PR #42 for ship/block verdict' },\n ],\n i18n: {\n zh: {\n description: '并行聚焦审查 PR、diff 或提交范围,并给出可合并/应拦截的结论。',\n whenToUse: '用户要审查 PR、diff、特定改动或提交范围(而非整库)时。',\n examplePrompts: [\n { field: 'target', text: '审查当前分支上的改动' },\n { field: 'target', text: '审查 PR #42,给出是否可合并的结论' },\n ],\n },\n },\n tags: ['code-review', 'pr'],\n estimatedAgents: { min: 7, max: 7 },\n phases: [\n { title: 'Scope' },\n { title: 'Review' },\n { title: 'Verdict' },\n ],\n}\n\nconst READ_ONLY_TOOLS = ['read_file', 'grep', 'find', 'list_dir', 'shell']\n\nconst target = args && typeof args === 'object'\n ? String(args.target ?? args.diff ?? '')\n : ''\nconst reviewTarget = target.trim()\n ? target\n : 'Recent changes in the working tree or the diff/context from the current conversation.'\n\nconst REVIEWERS = [\n { key: 'correctness', focus: 'Logic bugs, edge cases, error handling, null safety, race conditions in changed code.' },\n { key: 'security', focus: 'Auth/authz regressions, input validation, secret exposure, injection, unsafe deserialization in the diff.' },\n { key: 'tests', focus: 'Missing tests for changed behavior, brittle assertions, untested edge cases introduced by this change.' },\n { key: 'api_compat', focus: 'Breaking public API changes, schema migrations, backward compatibility, deprecation handling.' },\n { key: 'perf', focus: 'Regressions in hot paths, accidental N+1, sync I/O, unbounded loops or allocations in changed code.' },\n]\n\nphase('Scope')\nconst scope = await agent(\n 'Identify what changed for this review target. List changed files, blast radius (what depends on them), and the apparent intent of the change. Be concise.\\\\n\\\\nTARGET:\\\\n' +\n reviewTarget,\n {\n label: 'change scope',\n toolset: READ_ONLY_TOOLS,\n schema: {\n type: 'object',\n properties: {\n changedFiles: { type: 'array', items: { type: 'string' } },\n intent: { type: 'string' },\n blastRadius: { type: 'string' },\n },\n required: ['changedFiles', 'intent'],\n },\n },\n)\n\nphase('Review')\nconst reviews = await parallel(\n REVIEWERS.map((r) => () =>\n agent(\n 'Review these changes through the ' + r.key + ' lens.\\\\n' +\n 'Focus: ' + r.focus + '\\\\n\\\\n' +\n 'TARGET:\\\\n' + reviewTarget + '\\\\n\\\\n' +\n 'SCOPE:\\\\n' + JSON.stringify(scope, null, 2) + '\\\\n\\\\n' +\n 'Return findings: file, severity (low/med/high/blocker), title, fix suggestion. Blocker = must fix before merge.',\n {\n label: r.key,\n toolset: READ_ONLY_TOOLS,\n schema: {\n type: 'object',\n properties: {\n findings: {\n type: 'array',\n items: {\n type: 'object',\n properties: {\n file: { type: 'string' },\n severity: { type: 'string', enum: ['low', 'med', 'high', 'blocker'] },\n title: { type: 'string' },\n fix: { type: 'string' },\n },\n required: ['file', 'severity', 'title', 'fix'],\n },\n },\n },\n required: ['findings'],\n },\n },\n ),\n ),\n)\n\nphase('Verdict')\nconst live = reviews.filter(Boolean)\nconst byReviewer = {}\nfor (let i = 0; i < REVIEWERS.length; i++) {\n byReviewer[REVIEWERS[i].key] = live[i]?.findings ?? []\n}\n\nconst verdict = await agent(\n 'Synthesize a PR review verdict. Separate blockers from suggestions. Deduplicate. Recommend ship | fix_first | block.\\\\n\\\\n' +\n JSON.stringify(byReviewer, null, 2),\n {\n label: 'verdict',\n schema: {\n type: 'object',\n properties: {\n recommendation: { type: 'string', enum: ['ship', 'fix_first', 'block'] },\n summary: { type: 'string' },\n blockers: {\n type: 'array',\n items: {\n type: 'object',\n properties: {\n file: { type: 'string' },\n title: { type: 'string' },\n fix: { type: 'string' },\n },\n required: ['file', 'title'],\n },\n },\n suggestions: {\n type: 'array',\n items: {\n type: 'object',\n properties: {\n file: { type: 'string' },\n severity: { type: 'string' },\n title: { type: 'string' },\n },\n required: ['file', 'title'],\n },\n },\n },\n required: ['recommendation', 'summary', 'blockers'],\n },\n },\n)\n\
|
|
1
|
+
{"version":3,"file":"pr-review.js","names":[],"sources":["../../../../../src/agent/workflow/builtins/pr-review.ts"],"sourcesContent":["/**\n * Built-in workflow: `pr_review`\n *\n * Focused review of a PR, diff, or commit range — lighter than full repo audit.\n * Parallel reviewers cover correctness, security, tests, API compat, and perf;\n * final phase produces a ship/block verdict with blockers vs suggestions.\n *\n * Args:\n * - target: PR description, diff, commit range, or file list\n * - diff: alias for target\n */\n\nexport const PR_REVIEW_SCRIPT = `export const meta = {\n name: 'pr_review',\n description: 'Review a PR/diff/commit range with parallel focused reviewers and a ship/block verdict.',\n whenToUse: 'User asks to review a PR, diff, specific changes, or commit range (not the whole repo).',\n examplePrompts: [\n { field: 'target', text: 'Review the changes on this branch' },\n { field: 'target', text: 'Review PR #42 for ship/block verdict' },\n ],\n i18n: {\n zh: {\n description: '并行聚焦审查 PR、diff 或提交范围,并给出可合并/应拦截的结论。',\n whenToUse: '用户要审查 PR、diff、特定改动或提交范围(而非整库)时。',\n examplePrompts: [\n { field: 'target', text: '审查当前分支上的改动' },\n { field: 'target', text: '审查 PR #42,给出是否可合并的结论' },\n ],\n },\n },\n tags: ['code-review', 'pr'],\n estimatedAgents: { min: 7, max: 7 },\n phases: [\n { title: 'Scope' },\n { title: 'Review' },\n { title: 'Verdict' },\n ],\n}\n\nconst READ_ONLY_TOOLS = ['read_file', 'grep', 'find', 'list_dir', 'shell']\n\nconst target = args && typeof args === 'object'\n ? String(args.target ?? args.diff ?? '')\n : ''\nconst reviewTarget = target.trim()\n ? target\n : 'Recent changes in the working tree or the diff/context from the current conversation.'\n\nconst REVIEWERS = [\n { key: 'correctness', focus: 'Logic bugs, edge cases, error handling, null safety, race conditions in changed code.' },\n { key: 'security', focus: 'Auth/authz regressions, input validation, secret exposure, injection, unsafe deserialization in the diff.' },\n { key: 'tests', focus: 'Missing tests for changed behavior, brittle assertions, untested edge cases introduced by this change.' },\n { key: 'api_compat', focus: 'Breaking public API changes, schema migrations, backward compatibility, deprecation handling.' },\n { key: 'perf', focus: 'Regressions in hot paths, accidental N+1, sync I/O, unbounded loops or allocations in changed code.' },\n]\n\nphase('Scope')\nconst scope = await agent(\n 'Identify what changed for this review target. List changed files, blast radius (what depends on them), and the apparent intent of the change. Be concise.\\\\n\\\\nTARGET:\\\\n' +\n reviewTarget,\n {\n label: 'change scope',\n toolset: READ_ONLY_TOOLS,\n schema: {\n type: 'object',\n properties: {\n changedFiles: { type: 'array', items: { type: 'string' } },\n intent: { type: 'string' },\n blastRadius: { type: 'string' },\n },\n required: ['changedFiles', 'intent'],\n },\n },\n)\n\nphase('Review')\nconst reviews = await parallel(\n REVIEWERS.map((r) => () =>\n agent(\n 'Review these changes through the ' + r.key + ' lens.\\\\n' +\n 'Focus: ' + r.focus + '\\\\n\\\\n' +\n 'TARGET:\\\\n' + reviewTarget + '\\\\n\\\\n' +\n 'SCOPE:\\\\n' + JSON.stringify(scope, null, 2) + '\\\\n\\\\n' +\n 'Return findings: file, severity (low/med/high/blocker), title, fix suggestion. Blocker = must fix before merge.',\n {\n label: r.key,\n toolset: READ_ONLY_TOOLS,\n schema: {\n type: 'object',\n properties: {\n findings: {\n type: 'array',\n items: {\n type: 'object',\n properties: {\n file: { type: 'string' },\n severity: { type: 'string', enum: ['low', 'med', 'high', 'blocker'] },\n title: { type: 'string' },\n fix: { type: 'string' },\n },\n required: ['file', 'severity', 'title', 'fix'],\n },\n },\n },\n required: ['findings'],\n },\n },\n ),\n ),\n)\n\nphase('Verdict')\nconst live = reviews.filter(Boolean)\nconst byReviewer = {}\nfor (let i = 0; i < REVIEWERS.length; i++) {\n byReviewer[REVIEWERS[i].key] = live[i]?.findings ?? []\n}\n\nconst verdict = await agent(\n 'Synthesize a PR review verdict. Separate blockers from suggestions. Deduplicate. Recommend ship | fix_first | block.\\\\n\\\\n' +\n JSON.stringify(byReviewer, null, 2),\n {\n label: 'verdict',\n schema: {\n type: 'object',\n properties: {\n recommendation: { type: 'string', enum: ['ship', 'fix_first', 'block'] },\n summary: { type: 'string' },\n blockers: {\n type: 'array',\n items: {\n type: 'object',\n properties: {\n file: { type: 'string' },\n title: { type: 'string' },\n fix: { type: 'string' },\n },\n required: ['file', 'title'],\n },\n },\n suggestions: {\n type: 'array',\n items: {\n type: 'object',\n properties: {\n file: { type: 'string' },\n severity: { type: 'string' },\n title: { type: 'string' },\n },\n required: ['file', 'title'],\n },\n },\n },\n required: ['recommendation', 'summary', 'blockers'],\n },\n },\n)\n\nconst output = {\n ok: true,\n target: reviewTarget,\n scope,\n ...(verdict ?? { recommendation: 'fix_first', summary: 'verdict failed', blockers: [], suggestions: [] }),\n byReviewer,\n}\nreturn {\n summary: output.summary,\n sections: [\n { kind: 'findings', title: 'Blockers', items: output.blockers.map((item) => ({ title: item.title, severity: 'high', file: item.file, detail: item.fix })) },\n { kind: 'findings', title: 'Suggestions', items: output.suggestions.map((item) => ({ title: item.title, severity: item.severity, file: item.file })) },\n ],\n structuredOutput: output,\n}\n`\n"],"mappings":";;;;;;;;;;;;AAYA,MAAa,mBAAmB"}
|
|
@@ -8,4 +8,4 @@
|
|
|
8
8
|
* - target: release candidate, branch, commit range, or feature summary
|
|
9
9
|
* - checks: optional subset of check keys
|
|
10
10
|
*/
|
|
11
|
-
export declare const RELEASE_CHECK_SCRIPT = "export const meta = {\n name: 'release_check',\n description: 'Assess whether a change is ready to release with parallel risk checks and a go/no-go verdict.',\n whenToUse: 'User is near the end of implementation and wants a release-quality readiness check before shipping.',\n examplePrompts: [\n { field: 'target', text: 'Is this repo ready to release v1.2?' },\n { field: 'target', text: 'Pre-release readiness check for the current branch' },\n ],\n i18n: {\n zh: {\n description: '\u5E76\u884C\u68C0\u67E5\u53D1\u5E03\u98CE\u9669\uFF0C\u5224\u65AD\u53D8\u66F4\u662F\u5426\u8FBE\u5230\u53EF\u53D1\u5E03\u6807\u51C6\u3002',\n whenToUse: '\u7528\u6237\u63A5\u8FD1\u5F00\u53D1\u5C3E\u58F0\uFF0C\u60F3\u5728\u53D1\u5E03\u524D\u505A\u53D1\u5E03\u8D28\u91CF/\u5C31\u7EEA\u68C0\u67E5\u65F6\u3002',\n examplePrompts: [\n { field: 'target', text: '\u8FD9\u4E2A\u4ED3\u5E93\u662F\u5426\u51C6\u5907\u597D\u53D1\u5E03 v1.2\uFF1F' },\n { field: 'target', text: '\u5BF9\u5F53\u524D\u5206\u652F\u505A\u53D1\u5E03\u524D\u5C31\u7EEA\u68C0\u67E5' },\n ],\n },\n },\n tags: ['release', 'quality', 'validation'],\n estimatedAgents: { min: 6, max: 7 },\n phases: [\n { title: 'Scope' },\n { title: 'Checks' },\n { title: 'Verdict' },\n ],\n}\n\nconst READ_ONLY_TOOLS = ['read_file', 'grep', 'find', 'list_dir', 'shell']\n\nconst target = args && typeof args === 'object' && args.target\n ? String(args.target)\n : 'Current working tree or release candidate from the conversation context.'\n\nconst ALL_CHECKS = [\n { key: 'regression', focus: 'Behavior changes, compatibility breaks, edge cases, and accidental scope creep.' },\n { key: 'tests', focus: 'Relevant automated tests, missing regression cases, flaky or weak assertions, and manual coverage gaps.' },\n { key: 'build', focus: 'Typecheck, lint, build, packaging, lazy imports, generated assets, and dependency correctness.' },\n { key: 'security', focus: 'Secrets, auth/authz, input validation, unsafe shell/file/network access, and data exposure.' },\n { key: 'ops', focus: 'Logging, observability, migrations, persistence, rollback, failure modes, and supportability.' },\n]\n\nlet checks = ALL_CHECKS\nif (args && typeof args === 'object' && Array.isArray(args.checks) && args.checks.length) {\n const selected = new Set(args.checks.map((check) => String(check)))\n checks = ALL_CHECKS.filter((check) => selected.has(check.key))\n if (!checks.length) checks = ALL_CHECKS\n}\n\nphase('Scope')\nconst scope = await agent(\n 'Identify the release candidate scope. Inspect the working tree or target if useful. Return changed areas, user-visible behavior, and likely blast radius.\\n\\n' +\n 'TARGET:\\n' + target,\n {\n label: 'release scope',\n toolset: READ_ONLY_TOOLS,\n schema: {\n type: 'object',\n properties: {\n changedAreas: { type: 'array', items: { type: 'string' } },\n userVisibleChanges: { type: 'array', items: { type: 'string' } },\n blastRadius: { type: 'string' },\n },\n required: ['changedAreas', 'blastRadius'],\n },\n },\n)\n\nphase('Checks')\nconst reports = await parallel(\n checks.map((check) => () =>\n agent(\n 'Run a release-readiness check through the ' + check.key + ' lens.\\n' +\n 'Focus: ' + check.focus + '\\n\\n' +\n 'TARGET:\\n' + target + '\\n\\n' +\n 'SCOPE:\\n' + JSON.stringify(scope, null, 2) + '\\n\\n' +\n 'Return blockers, warnings, evidence, and concrete fixes. Prefer specific files/commands over generic statements.',\n {\n label: check.key + ' check',\n toolset: READ_ONLY_TOOLS,\n schema: {\n type: 'object',\n properties: {\n blockers: {\n type: 'array',\n items: {\n type: 'object',\n properties: {\n title: { type: 'string' },\n evidence: { type: 'string' },\n fix: { type: 'string' },\n },\n required: ['title', 'evidence', 'fix'],\n },\n },\n warnings: {\n type: 'array',\n items: {\n type: 'object',\n properties: {\n title: { type: 'string' },\n evidence: { type: 'string' },\n fix: { type: 'string' },\n },\n required: ['title', 'evidence'],\n },\n },\n recommendedCommands: { type: 'array', items: { type: 'string' } },\n },\n required: ['blockers', 'warnings'],\n },\n },\n ),\n ),\n)\n\nphase('Verdict')\nconst byCheck = {}\nfor (let i = 0; i < checks.length; i++) {\n byCheck[checks[i].key] = reports[i] ?? { blockers: [], warnings: [], recommendedCommands: [] }\n}\n\nconst verdict = await agent(\n 'Synthesize a release go/no-go verdict. Block if any credible blocker remains. If not blocked, distinguish ship_now from ship_after_checks. ' +\n 'Deduplicate issues and produce the shortest checklist that would make this release safe.\\n\\n' +\n JSON.stringify({ target, scope, byCheck }, null, 2),\n {\n label: 'release verdict',\n schema: {\n type: 'object',\n properties: {\n recommendation: { type: 'string', enum: ['ship_now', 'ship_after_checks', 'block'] },\n summary: { type: 'string' },\n blockers: { type: 'array', items: { type: 'string' } },\n finalChecklist: { type: 'array', items: { type: 'string' } },\n commandsToRun: { type: 'array', items: { type: 'string' } },\n },\n required: ['recommendation', 'summary', 'blockers', 'finalChecklist'],\n },\n },\n)\n\
|
|
11
|
+
export declare const RELEASE_CHECK_SCRIPT = "export const meta = {\n name: 'release_check',\n description: 'Assess whether a change is ready to release with parallel risk checks and a go/no-go verdict.',\n whenToUse: 'User is near the end of implementation and wants a release-quality readiness check before shipping.',\n examplePrompts: [\n { field: 'target', text: 'Is this repo ready to release v1.2?' },\n { field: 'target', text: 'Pre-release readiness check for the current branch' },\n ],\n i18n: {\n zh: {\n description: '\u5E76\u884C\u68C0\u67E5\u53D1\u5E03\u98CE\u9669\uFF0C\u5224\u65AD\u53D8\u66F4\u662F\u5426\u8FBE\u5230\u53EF\u53D1\u5E03\u6807\u51C6\u3002',\n whenToUse: '\u7528\u6237\u63A5\u8FD1\u5F00\u53D1\u5C3E\u58F0\uFF0C\u60F3\u5728\u53D1\u5E03\u524D\u505A\u53D1\u5E03\u8D28\u91CF/\u5C31\u7EEA\u68C0\u67E5\u65F6\u3002',\n examplePrompts: [\n { field: 'target', text: '\u8FD9\u4E2A\u4ED3\u5E93\u662F\u5426\u51C6\u5907\u597D\u53D1\u5E03 v1.2\uFF1F' },\n { field: 'target', text: '\u5BF9\u5F53\u524D\u5206\u652F\u505A\u53D1\u5E03\u524D\u5C31\u7EEA\u68C0\u67E5' },\n ],\n },\n },\n tags: ['release', 'quality', 'validation'],\n estimatedAgents: { min: 6, max: 7 },\n phases: [\n { title: 'Scope' },\n { title: 'Checks' },\n { title: 'Verdict' },\n ],\n}\n\nconst READ_ONLY_TOOLS = ['read_file', 'grep', 'find', 'list_dir', 'shell']\n\nconst target = args && typeof args === 'object' && args.target\n ? String(args.target)\n : 'Current working tree or release candidate from the conversation context.'\n\nconst ALL_CHECKS = [\n { key: 'regression', focus: 'Behavior changes, compatibility breaks, edge cases, and accidental scope creep.' },\n { key: 'tests', focus: 'Relevant automated tests, missing regression cases, flaky or weak assertions, and manual coverage gaps.' },\n { key: 'build', focus: 'Typecheck, lint, build, packaging, lazy imports, generated assets, and dependency correctness.' },\n { key: 'security', focus: 'Secrets, auth/authz, input validation, unsafe shell/file/network access, and data exposure.' },\n { key: 'ops', focus: 'Logging, observability, migrations, persistence, rollback, failure modes, and supportability.' },\n]\n\nlet checks = ALL_CHECKS\nif (args && typeof args === 'object' && Array.isArray(args.checks) && args.checks.length) {\n const selected = new Set(args.checks.map((check) => String(check)))\n checks = ALL_CHECKS.filter((check) => selected.has(check.key))\n if (!checks.length) checks = ALL_CHECKS\n}\n\nphase('Scope')\nconst scope = await agent(\n 'Identify the release candidate scope. Inspect the working tree or target if useful. Return changed areas, user-visible behavior, and likely blast radius.\\n\\n' +\n 'TARGET:\\n' + target,\n {\n label: 'release scope',\n toolset: READ_ONLY_TOOLS,\n schema: {\n type: 'object',\n properties: {\n changedAreas: { type: 'array', items: { type: 'string' } },\n userVisibleChanges: { type: 'array', items: { type: 'string' } },\n blastRadius: { type: 'string' },\n },\n required: ['changedAreas', 'blastRadius'],\n },\n },\n)\n\nphase('Checks')\nconst reports = await parallel(\n checks.map((check) => () =>\n agent(\n 'Run a release-readiness check through the ' + check.key + ' lens.\\n' +\n 'Focus: ' + check.focus + '\\n\\n' +\n 'TARGET:\\n' + target + '\\n\\n' +\n 'SCOPE:\\n' + JSON.stringify(scope, null, 2) + '\\n\\n' +\n 'Return blockers, warnings, evidence, and concrete fixes. Prefer specific files/commands over generic statements.',\n {\n label: check.key + ' check',\n toolset: READ_ONLY_TOOLS,\n schema: {\n type: 'object',\n properties: {\n blockers: {\n type: 'array',\n items: {\n type: 'object',\n properties: {\n title: { type: 'string' },\n evidence: { type: 'string' },\n fix: { type: 'string' },\n },\n required: ['title', 'evidence', 'fix'],\n },\n },\n warnings: {\n type: 'array',\n items: {\n type: 'object',\n properties: {\n title: { type: 'string' },\n evidence: { type: 'string' },\n fix: { type: 'string' },\n },\n required: ['title', 'evidence'],\n },\n },\n recommendedCommands: { type: 'array', items: { type: 'string' } },\n },\n required: ['blockers', 'warnings'],\n },\n },\n ),\n ),\n)\n\nphase('Verdict')\nconst byCheck = {}\nfor (let i = 0; i < checks.length; i++) {\n byCheck[checks[i].key] = reports[i] ?? { blockers: [], warnings: [], recommendedCommands: [] }\n}\n\nconst verdict = await agent(\n 'Synthesize a release go/no-go verdict. Block if any credible blocker remains. If not blocked, distinguish ship_now from ship_after_checks. ' +\n 'Deduplicate issues and produce the shortest checklist that would make this release safe.\\n\\n' +\n JSON.stringify({ target, scope, byCheck }, null, 2),\n {\n label: 'release verdict',\n schema: {\n type: 'object',\n properties: {\n recommendation: { type: 'string', enum: ['ship_now', 'ship_after_checks', 'block'] },\n summary: { type: 'string' },\n blockers: { type: 'array', items: { type: 'string' } },\n finalChecklist: { type: 'array', items: { type: 'string' } },\n commandsToRun: { type: 'array', items: { type: 'string' } },\n },\n required: ['recommendation', 'summary', 'blockers', 'finalChecklist'],\n },\n },\n)\n\nconst output = {\n ok: true,\n target,\n checks: checks.map((check) => check.key),\n scope,\n ...(verdict ?? { recommendation: 'ship_after_checks', summary: 'verdict failed', blockers: [], finalChecklist: [] }),\n byCheck,\n}\nreturn {\n summary: output.summary,\n sections: [\n { kind: 'risks', title: 'Blockers', items: output.blockers.map((title) => ({ title, severity: 'high' })) },\n { kind: 'questions', title: 'Final checklist', items: output.finalChecklist },\n { kind: 'questions', title: 'Commands to run', items: output.commandsToRun ?? [] },\n ],\n structuredOutput: output,\n}\n";
|
|
@@ -150,7 +150,7 @@ const verdict = await agent(
|
|
|
150
150
|
},
|
|
151
151
|
)
|
|
152
152
|
|
|
153
|
-
|
|
153
|
+
const output = {
|
|
154
154
|
ok: true,
|
|
155
155
|
target,
|
|
156
156
|
checks: checks.map((check) => check.key),
|
|
@@ -158,6 +158,15 @@ return {
|
|
|
158
158
|
...(verdict ?? { recommendation: 'ship_after_checks', summary: 'verdict failed', blockers: [], finalChecklist: [] }),
|
|
159
159
|
byCheck,
|
|
160
160
|
}
|
|
161
|
+
return {
|
|
162
|
+
summary: output.summary,
|
|
163
|
+
sections: [
|
|
164
|
+
{ kind: 'risks', title: 'Blockers', items: output.blockers.map((title) => ({ title, severity: 'high' })) },
|
|
165
|
+
{ kind: 'questions', title: 'Final checklist', items: output.finalChecklist },
|
|
166
|
+
{ kind: 'questions', title: 'Commands to run', items: output.commandsToRun ?? [] },
|
|
167
|
+
],
|
|
168
|
+
structuredOutput: output,
|
|
169
|
+
}
|
|
161
170
|
`;
|
|
162
171
|
//#endregion
|
|
163
172
|
export { RELEASE_CHECK_SCRIPT };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"release-check.js","names":[],"sources":["../../../../../src/agent/workflow/builtins/release-check.ts"],"sourcesContent":["/**\n * Built-in workflow: `release_check`\n *\n * Runs a release-readiness review for a finished change. It inspects the diff,\n * validates risk areas in parallel, and produces a go/no-go checklist.\n *\n * Args:\n * - target: release candidate, branch, commit range, or feature summary\n * - checks: optional subset of check keys\n */\n\nexport const RELEASE_CHECK_SCRIPT = `export const meta = {\n name: 'release_check',\n description: 'Assess whether a change is ready to release with parallel risk checks and a go/no-go verdict.',\n whenToUse: 'User is near the end of implementation and wants a release-quality readiness check before shipping.',\n examplePrompts: [\n { field: 'target', text: 'Is this repo ready to release v1.2?' },\n { field: 'target', text: 'Pre-release readiness check for the current branch' },\n ],\n i18n: {\n zh: {\n description: '并行检查发布风险,判断变更是否达到可发布标准。',\n whenToUse: '用户接近开发尾声,想在发布前做发布质量/就绪检查时。',\n examplePrompts: [\n { field: 'target', text: '这个仓库是否准备好发布 v1.2?' },\n { field: 'target', text: '对当前分支做发布前就绪检查' },\n ],\n },\n },\n tags: ['release', 'quality', 'validation'],\n estimatedAgents: { min: 6, max: 7 },\n phases: [\n { title: 'Scope' },\n { title: 'Checks' },\n { title: 'Verdict' },\n ],\n}\n\nconst READ_ONLY_TOOLS = ['read_file', 'grep', 'find', 'list_dir', 'shell']\n\nconst target = args && typeof args === 'object' && args.target\n ? String(args.target)\n : 'Current working tree or release candidate from the conversation context.'\n\nconst ALL_CHECKS = [\n { key: 'regression', focus: 'Behavior changes, compatibility breaks, edge cases, and accidental scope creep.' },\n { key: 'tests', focus: 'Relevant automated tests, missing regression cases, flaky or weak assertions, and manual coverage gaps.' },\n { key: 'build', focus: 'Typecheck, lint, build, packaging, lazy imports, generated assets, and dependency correctness.' },\n { key: 'security', focus: 'Secrets, auth/authz, input validation, unsafe shell/file/network access, and data exposure.' },\n { key: 'ops', focus: 'Logging, observability, migrations, persistence, rollback, failure modes, and supportability.' },\n]\n\nlet checks = ALL_CHECKS\nif (args && typeof args === 'object' && Array.isArray(args.checks) && args.checks.length) {\n const selected = new Set(args.checks.map((check) => String(check)))\n checks = ALL_CHECKS.filter((check) => selected.has(check.key))\n if (!checks.length) checks = ALL_CHECKS\n}\n\nphase('Scope')\nconst scope = await agent(\n 'Identify the release candidate scope. Inspect the working tree or target if useful. Return changed areas, user-visible behavior, and likely blast radius.\\\\n\\\\n' +\n 'TARGET:\\\\n' + target,\n {\n label: 'release scope',\n toolset: READ_ONLY_TOOLS,\n schema: {\n type: 'object',\n properties: {\n changedAreas: { type: 'array', items: { type: 'string' } },\n userVisibleChanges: { type: 'array', items: { type: 'string' } },\n blastRadius: { type: 'string' },\n },\n required: ['changedAreas', 'blastRadius'],\n },\n },\n)\n\nphase('Checks')\nconst reports = await parallel(\n checks.map((check) => () =>\n agent(\n 'Run a release-readiness check through the ' + check.key + ' lens.\\\\n' +\n 'Focus: ' + check.focus + '\\\\n\\\\n' +\n 'TARGET:\\\\n' + target + '\\\\n\\\\n' +\n 'SCOPE:\\\\n' + JSON.stringify(scope, null, 2) + '\\\\n\\\\n' +\n 'Return blockers, warnings, evidence, and concrete fixes. Prefer specific files/commands over generic statements.',\n {\n label: check.key + ' check',\n toolset: READ_ONLY_TOOLS,\n schema: {\n type: 'object',\n properties: {\n blockers: {\n type: 'array',\n items: {\n type: 'object',\n properties: {\n title: { type: 'string' },\n evidence: { type: 'string' },\n fix: { type: 'string' },\n },\n required: ['title', 'evidence', 'fix'],\n },\n },\n warnings: {\n type: 'array',\n items: {\n type: 'object',\n properties: {\n title: { type: 'string' },\n evidence: { type: 'string' },\n fix: { type: 'string' },\n },\n required: ['title', 'evidence'],\n },\n },\n recommendedCommands: { type: 'array', items: { type: 'string' } },\n },\n required: ['blockers', 'warnings'],\n },\n },\n ),\n ),\n)\n\nphase('Verdict')\nconst byCheck = {}\nfor (let i = 0; i < checks.length; i++) {\n byCheck[checks[i].key] = reports[i] ?? { blockers: [], warnings: [], recommendedCommands: [] }\n}\n\nconst verdict = await agent(\n 'Synthesize a release go/no-go verdict. Block if any credible blocker remains. If not blocked, distinguish ship_now from ship_after_checks. ' +\n 'Deduplicate issues and produce the shortest checklist that would make this release safe.\\\\n\\\\n' +\n JSON.stringify({ target, scope, byCheck }, null, 2),\n {\n label: 'release verdict',\n schema: {\n type: 'object',\n properties: {\n recommendation: { type: 'string', enum: ['ship_now', 'ship_after_checks', 'block'] },\n summary: { type: 'string' },\n blockers: { type: 'array', items: { type: 'string' } },\n finalChecklist: { type: 'array', items: { type: 'string' } },\n commandsToRun: { type: 'array', items: { type: 'string' } },\n },\n required: ['recommendation', 'summary', 'blockers', 'finalChecklist'],\n },\n },\n)\n\
|
|
1
|
+
{"version":3,"file":"release-check.js","names":[],"sources":["../../../../../src/agent/workflow/builtins/release-check.ts"],"sourcesContent":["/**\n * Built-in workflow: `release_check`\n *\n * Runs a release-readiness review for a finished change. It inspects the diff,\n * validates risk areas in parallel, and produces a go/no-go checklist.\n *\n * Args:\n * - target: release candidate, branch, commit range, or feature summary\n * - checks: optional subset of check keys\n */\n\nexport const RELEASE_CHECK_SCRIPT = `export const meta = {\n name: 'release_check',\n description: 'Assess whether a change is ready to release with parallel risk checks and a go/no-go verdict.',\n whenToUse: 'User is near the end of implementation and wants a release-quality readiness check before shipping.',\n examplePrompts: [\n { field: 'target', text: 'Is this repo ready to release v1.2?' },\n { field: 'target', text: 'Pre-release readiness check for the current branch' },\n ],\n i18n: {\n zh: {\n description: '并行检查发布风险,判断变更是否达到可发布标准。',\n whenToUse: '用户接近开发尾声,想在发布前做发布质量/就绪检查时。',\n examplePrompts: [\n { field: 'target', text: '这个仓库是否准备好发布 v1.2?' },\n { field: 'target', text: '对当前分支做发布前就绪检查' },\n ],\n },\n },\n tags: ['release', 'quality', 'validation'],\n estimatedAgents: { min: 6, max: 7 },\n phases: [\n { title: 'Scope' },\n { title: 'Checks' },\n { title: 'Verdict' },\n ],\n}\n\nconst READ_ONLY_TOOLS = ['read_file', 'grep', 'find', 'list_dir', 'shell']\n\nconst target = args && typeof args === 'object' && args.target\n ? String(args.target)\n : 'Current working tree or release candidate from the conversation context.'\n\nconst ALL_CHECKS = [\n { key: 'regression', focus: 'Behavior changes, compatibility breaks, edge cases, and accidental scope creep.' },\n { key: 'tests', focus: 'Relevant automated tests, missing regression cases, flaky or weak assertions, and manual coverage gaps.' },\n { key: 'build', focus: 'Typecheck, lint, build, packaging, lazy imports, generated assets, and dependency correctness.' },\n { key: 'security', focus: 'Secrets, auth/authz, input validation, unsafe shell/file/network access, and data exposure.' },\n { key: 'ops', focus: 'Logging, observability, migrations, persistence, rollback, failure modes, and supportability.' },\n]\n\nlet checks = ALL_CHECKS\nif (args && typeof args === 'object' && Array.isArray(args.checks) && args.checks.length) {\n const selected = new Set(args.checks.map((check) => String(check)))\n checks = ALL_CHECKS.filter((check) => selected.has(check.key))\n if (!checks.length) checks = ALL_CHECKS\n}\n\nphase('Scope')\nconst scope = await agent(\n 'Identify the release candidate scope. Inspect the working tree or target if useful. Return changed areas, user-visible behavior, and likely blast radius.\\\\n\\\\n' +\n 'TARGET:\\\\n' + target,\n {\n label: 'release scope',\n toolset: READ_ONLY_TOOLS,\n schema: {\n type: 'object',\n properties: {\n changedAreas: { type: 'array', items: { type: 'string' } },\n userVisibleChanges: { type: 'array', items: { type: 'string' } },\n blastRadius: { type: 'string' },\n },\n required: ['changedAreas', 'blastRadius'],\n },\n },\n)\n\nphase('Checks')\nconst reports = await parallel(\n checks.map((check) => () =>\n agent(\n 'Run a release-readiness check through the ' + check.key + ' lens.\\\\n' +\n 'Focus: ' + check.focus + '\\\\n\\\\n' +\n 'TARGET:\\\\n' + target + '\\\\n\\\\n' +\n 'SCOPE:\\\\n' + JSON.stringify(scope, null, 2) + '\\\\n\\\\n' +\n 'Return blockers, warnings, evidence, and concrete fixes. Prefer specific files/commands over generic statements.',\n {\n label: check.key + ' check',\n toolset: READ_ONLY_TOOLS,\n schema: {\n type: 'object',\n properties: {\n blockers: {\n type: 'array',\n items: {\n type: 'object',\n properties: {\n title: { type: 'string' },\n evidence: { type: 'string' },\n fix: { type: 'string' },\n },\n required: ['title', 'evidence', 'fix'],\n },\n },\n warnings: {\n type: 'array',\n items: {\n type: 'object',\n properties: {\n title: { type: 'string' },\n evidence: { type: 'string' },\n fix: { type: 'string' },\n },\n required: ['title', 'evidence'],\n },\n },\n recommendedCommands: { type: 'array', items: { type: 'string' } },\n },\n required: ['blockers', 'warnings'],\n },\n },\n ),\n ),\n)\n\nphase('Verdict')\nconst byCheck = {}\nfor (let i = 0; i < checks.length; i++) {\n byCheck[checks[i].key] = reports[i] ?? { blockers: [], warnings: [], recommendedCommands: [] }\n}\n\nconst verdict = await agent(\n 'Synthesize a release go/no-go verdict. Block if any credible blocker remains. If not blocked, distinguish ship_now from ship_after_checks. ' +\n 'Deduplicate issues and produce the shortest checklist that would make this release safe.\\\\n\\\\n' +\n JSON.stringify({ target, scope, byCheck }, null, 2),\n {\n label: 'release verdict',\n schema: {\n type: 'object',\n properties: {\n recommendation: { type: 'string', enum: ['ship_now', 'ship_after_checks', 'block'] },\n summary: { type: 'string' },\n blockers: { type: 'array', items: { type: 'string' } },\n finalChecklist: { type: 'array', items: { type: 'string' } },\n commandsToRun: { type: 'array', items: { type: 'string' } },\n },\n required: ['recommendation', 'summary', 'blockers', 'finalChecklist'],\n },\n },\n)\n\nconst output = {\n ok: true,\n target,\n checks: checks.map((check) => check.key),\n scope,\n ...(verdict ?? { recommendation: 'ship_after_checks', summary: 'verdict failed', blockers: [], finalChecklist: [] }),\n byCheck,\n}\nreturn {\n summary: output.summary,\n sections: [\n { kind: 'risks', title: 'Blockers', items: output.blockers.map((title) => ({ title, severity: 'high' })) },\n { kind: 'questions', title: 'Final checklist', items: output.finalChecklist },\n { kind: 'questions', title: 'Commands to run', items: output.commandsToRun ?? [] },\n ],\n structuredOutput: output,\n}\n`\n"],"mappings":";;;;;;;;;;;AAWA,MAAa,uBAAuB"}
|
|
@@ -10,4 +10,4 @@
|
|
|
10
10
|
* - question: research question
|
|
11
11
|
* - depth: 'quick' (2 angles) | 'standard' (4) | 'deep' (6)
|
|
12
12
|
*/
|
|
13
|
-
export declare const RESEARCH_SCRIPT = "export const meta = {\n name: 'research',\n description: 'Multi-angle research on a question with parallel exploration and a cited synthesis.',\n whenToUse: 'User asks a non-trivial research question that benefits from multiple search angles or source reads.',\n examplePrompts: [\n { field: 'question', text: 'Compare Bun vs Node startup performance' },\n { field: 'question', text: 'What are the trade-offs of SQLite vs Postgres for this app?' },\n ],\n i18n: {\n zh: {\n description: '\u591A\u89D2\u5EA6\u5E76\u884C\u8C03\u7814\u4E00\u4E2A\u95EE\u9898\uFF0C\u5E76\u4EA7\u51FA\u5E26\u5F15\u7528\u7684\u7EFC\u5408\u62A5\u544A\u3002',\n whenToUse: '\u7528\u6237\u63D0\u51FA\u9700\u8981\u591A\u89D2\u5EA6\u68C0\u7D22\u3001\u9605\u8BFB\u6765\u6E90\u7684\u975E\u5E73\u51E1\u8C03\u7814\u95EE\u9898\u65F6\u3002',\n examplePrompts: [\n { field: 'question', text: '\u6BD4\u8F83 Bun \u4E0E Node \u7684\u542F\u52A8\u6027\u80FD' },\n { field: 'question', text: '\u8FD9\u4E2A\u5E94\u7528\u7528 SQLite \u8FD8\u662F Postgres \u5404\u6709\u4EC0\u4E48\u6743\u8861\uFF1F' },\n ],\n },\n },\n tags: ['research', 'investigation'],\n estimatedAgents: { min: 4, max: 8 },\n phases: [\n { title: 'Frame' },\n { title: 'Sweep' },\n { title: 'Synthesize' },\n ],\n}\n\nconst RESEARCH_TOOLS = ['web_search', 'web_fetch', 'read_file', 'grep', 'find', 'list_dir']\n\nconst question = args && typeof args === 'object' && args.question\n ? String(args.question)\n : 'No explicit question supplied; infer from the most recent user turn.'\n\nconst depth = args && typeof args === 'object' && args.depth\n ? String(args.depth)\n : 'standard'\nconst maxAngles = depth === 'quick' ? 2 : depth === 'deep' ? 6 : 4\n\nphase('Frame')\nconst frame = await agent(\n 'Frame this research question. Return exactly ' + maxAngles + ' distinct angles worth investigating, ' +\n 'each with the single most decisive sub-question. Be concrete.\\n\\nQUESTION:\\n' +\n question,\n {\n label: 'framing',\n schema: {\n type: 'object',\n properties: {\n angles: {\n type: 'array',\n items: {\n type: 'object',\n properties: {\n title: { type: 'string' },\n key_question: { type: 'string' },\n },\n required: ['title', 'key_question'],\n },\n },\n },\n required: ['angles'],\n },\n },\n)\n\nif (!frame || !frame.angles?.length) {\n
|
|
13
|
+
export declare const RESEARCH_SCRIPT = "export const meta = {\n name: 'research',\n description: 'Multi-angle research on a question with parallel exploration and a cited synthesis.',\n whenToUse: 'User asks a non-trivial research question that benefits from multiple search angles or source reads.',\n examplePrompts: [\n { field: 'question', text: 'Compare Bun vs Node startup performance' },\n { field: 'question', text: 'What are the trade-offs of SQLite vs Postgres for this app?' },\n ],\n i18n: {\n zh: {\n description: '\u591A\u89D2\u5EA6\u5E76\u884C\u8C03\u7814\u4E00\u4E2A\u95EE\u9898\uFF0C\u5E76\u4EA7\u51FA\u5E26\u5F15\u7528\u7684\u7EFC\u5408\u62A5\u544A\u3002',\n whenToUse: '\u7528\u6237\u63D0\u51FA\u9700\u8981\u591A\u89D2\u5EA6\u68C0\u7D22\u3001\u9605\u8BFB\u6765\u6E90\u7684\u975E\u5E73\u51E1\u8C03\u7814\u95EE\u9898\u65F6\u3002',\n examplePrompts: [\n { field: 'question', text: '\u6BD4\u8F83 Bun \u4E0E Node \u7684\u542F\u52A8\u6027\u80FD' },\n { field: 'question', text: '\u8FD9\u4E2A\u5E94\u7528\u7528 SQLite \u8FD8\u662F Postgres \u5404\u6709\u4EC0\u4E48\u6743\u8861\uFF1F' },\n ],\n },\n },\n tags: ['research', 'investigation'],\n estimatedAgents: { min: 4, max: 8 },\n phases: [\n { title: 'Frame' },\n { title: 'Sweep' },\n { title: 'Synthesize' },\n ],\n}\n\nconst RESEARCH_TOOLS = ['web_search', 'web_fetch', 'read_file', 'grep', 'find', 'list_dir']\n\nconst question = args && typeof args === 'object' && args.question\n ? String(args.question)\n : 'No explicit question supplied; infer from the most recent user turn.'\n\nconst depth = args && typeof args === 'object' && args.depth\n ? String(args.depth)\n : 'standard'\nconst maxAngles = depth === 'quick' ? 2 : depth === 'deep' ? 6 : 4\n\nphase('Frame')\nconst frame = await agent(\n 'Frame this research question. Return exactly ' + maxAngles + ' distinct angles worth investigating, ' +\n 'each with the single most decisive sub-question. Be concrete.\\n\\nQUESTION:\\n' +\n question,\n {\n label: 'framing',\n schema: {\n type: 'object',\n properties: {\n angles: {\n type: 'array',\n items: {\n type: 'object',\n properties: {\n title: { type: 'string' },\n key_question: { type: 'string' },\n },\n required: ['title', 'key_question'],\n },\n },\n },\n required: ['angles'],\n },\n },\n)\n\nif (!frame || !frame.angles?.length) {\n const output = { ok: false, reason: 'framing failed', question, depth }\n return {\n summary: output.reason,\n sections: [{ kind: 'json', title: 'Research framing', value: output }],\n structuredOutput: output,\n }\n}\n\nconst angles = frame.angles.slice(0, maxAngles)\n\nphase('Sweep')\nconst angleReports = await parallel(\n angles.map((a) => () =>\n agent(\n 'Investigate this angle. Use search and source-read tools liberally. Distinguish what you can confirm from what is conjecture.\\n\\n' +\n 'ANGLE: ' + a.title + '\\n' +\n 'KEY QUESTION: ' + a.key_question + '\\n\\n' +\n 'Return: 3\u20136 grounded findings (each with a 1-line claim and a source URL or file path), plus the strongest counter-evidence.',\n {\n label: a.title,\n toolset: RESEARCH_TOOLS,\n maxIterations: depth === 'deep' ? 40 : 30,\n schema: {\n type: 'object',\n properties: {\n findings: {\n type: 'array',\n items: {\n type: 'object',\n properties: {\n claim: { type: 'string' },\n source: { type: 'string' },\n confidence: { type: 'string', enum: ['low', 'med', 'high'] },\n },\n required: ['claim', 'source', 'confidence'],\n },\n },\n counterEvidence: { type: 'string' },\n },\n required: ['findings'],\n },\n },\n ),\n ),\n)\n\nphase('Synthesize')\nconst live = angleReports.filter(Boolean)\nconst synthesis = await agent(\n 'Synthesize a cited research report from these angle-level findings. Drop unsupported or duplicate claims. Use the highest-confidence source per claim. ' +\n 'Explicitly list contradictions where angles disagree. Return: an executive summary (max 5 sentences), top findings with inline source URLs, open questions, and contradictions.\\n\\n' +\n 'QUESTION:\\n' + question + '\\n\\n' +\n JSON.stringify({ angles, reports: live }, null, 2),\n {\n label: 'synthesis',\n schema: {\n type: 'object',\n properties: {\n executiveSummary: { type: 'string' },\n topFindings: {\n type: 'array',\n items: {\n type: 'object',\n properties: {\n claim: { type: 'string' },\n source: { type: 'string' },\n },\n required: ['claim', 'source'],\n },\n },\n openQuestions: { type: 'array', items: { type: 'string' } },\n contradictions: {\n type: 'array',\n items: {\n type: 'object',\n properties: {\n topic: { type: 'string' },\n sides: { type: 'array', items: { type: 'string' } },\n },\n required: ['topic', 'sides'],\n },\n },\n },\n required: ['executiveSummary', 'topFindings'],\n },\n },\n)\n\nconst output = {\n ok: true,\n question,\n depth,\n angleCount: angles.length,\n ...(synthesis ?? { executiveSummary: 'synthesis failed', topFindings: [], contradictions: [] }),\n}\nreturn {\n summary: output.executiveSummary,\n sections: [\n { kind: 'findings', title: 'Top findings', items: output.topFindings.map((item) => ({ title: item.claim, detail: item.source })) },\n { kind: 'questions', title: 'Open questions', items: output.openQuestions ?? [] },\n { kind: 'json', title: 'Contradictions', value: output.contradictions ?? [] },\n ],\n structuredOutput: output,\n}\n";
|
|
@@ -77,7 +77,12 @@ const frame = await agent(
|
|
|
77
77
|
)
|
|
78
78
|
|
|
79
79
|
if (!frame || !frame.angles?.length) {
|
|
80
|
-
|
|
80
|
+
const output = { ok: false, reason: 'framing failed', question, depth }
|
|
81
|
+
return {
|
|
82
|
+
summary: output.reason,
|
|
83
|
+
sections: [{ kind: 'json', title: 'Research framing', value: output }],
|
|
84
|
+
structuredOutput: output,
|
|
85
|
+
}
|
|
81
86
|
}
|
|
82
87
|
|
|
83
88
|
const angles = frame.angles.slice(0, maxAngles)
|
|
@@ -160,13 +165,22 @@ const synthesis = await agent(
|
|
|
160
165
|
},
|
|
161
166
|
)
|
|
162
167
|
|
|
163
|
-
|
|
168
|
+
const output = {
|
|
164
169
|
ok: true,
|
|
165
170
|
question,
|
|
166
171
|
depth,
|
|
167
172
|
angleCount: angles.length,
|
|
168
173
|
...(synthesis ?? { executiveSummary: 'synthesis failed', topFindings: [], contradictions: [] }),
|
|
169
174
|
}
|
|
175
|
+
return {
|
|
176
|
+
summary: output.executiveSummary,
|
|
177
|
+
sections: [
|
|
178
|
+
{ kind: 'findings', title: 'Top findings', items: output.topFindings.map((item) => ({ title: item.claim, detail: item.source })) },
|
|
179
|
+
{ kind: 'questions', title: 'Open questions', items: output.openQuestions ?? [] },
|
|
180
|
+
{ kind: 'json', title: 'Contradictions', value: output.contradictions ?? [] },
|
|
181
|
+
],
|
|
182
|
+
structuredOutput: output,
|
|
183
|
+
}
|
|
170
184
|
`;
|
|
171
185
|
//#endregion
|
|
172
186
|
export { RESEARCH_SCRIPT };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"research.js","names":[],"sources":["../../../../../src/agent/workflow/builtins/research.ts"],"sourcesContent":["/**\n * Built-in workflow: `research`\n *\n * Multi-modal research sweep on a question (args.question). Fans out search /\n * exploration / source-reading angles in parallel, then synthesises a cited\n * report. Each angle is its own subagent so source reading does not pollute the\n * parent context.\n *\n * Args:\n * - question: research question\n * - depth: 'quick' (2 angles) | 'standard' (4) | 'deep' (6)\n */\n\nexport const RESEARCH_SCRIPT = `export const meta = {\n name: 'research',\n description: 'Multi-angle research on a question with parallel exploration and a cited synthesis.',\n whenToUse: 'User asks a non-trivial research question that benefits from multiple search angles or source reads.',\n examplePrompts: [\n { field: 'question', text: 'Compare Bun vs Node startup performance' },\n { field: 'question', text: 'What are the trade-offs of SQLite vs Postgres for this app?' },\n ],\n i18n: {\n zh: {\n description: '多角度并行调研一个问题,并产出带引用的综合报告。',\n whenToUse: '用户提出需要多角度检索、阅读来源的非平凡调研问题时。',\n examplePrompts: [\n { field: 'question', text: '比较 Bun 与 Node 的启动性能' },\n { field: 'question', text: '这个应用用 SQLite 还是 Postgres 各有什么权衡?' },\n ],\n },\n },\n tags: ['research', 'investigation'],\n estimatedAgents: { min: 4, max: 8 },\n phases: [\n { title: 'Frame' },\n { title: 'Sweep' },\n { title: 'Synthesize' },\n ],\n}\n\nconst RESEARCH_TOOLS = ['web_search', 'web_fetch', 'read_file', 'grep', 'find', 'list_dir']\n\nconst question = args && typeof args === 'object' && args.question\n ? String(args.question)\n : 'No explicit question supplied; infer from the most recent user turn.'\n\nconst depth = args && typeof args === 'object' && args.depth\n ? String(args.depth)\n : 'standard'\nconst maxAngles = depth === 'quick' ? 2 : depth === 'deep' ? 6 : 4\n\nphase('Frame')\nconst frame = await agent(\n 'Frame this research question. Return exactly ' + maxAngles + ' distinct angles worth investigating, ' +\n 'each with the single most decisive sub-question. Be concrete.\\\\n\\\\nQUESTION:\\\\n' +\n question,\n {\n label: 'framing',\n schema: {\n type: 'object',\n properties: {\n angles: {\n type: 'array',\n items: {\n type: 'object',\n properties: {\n title: { type: 'string' },\n key_question: { type: 'string' },\n },\n required: ['title', 'key_question'],\n },\n },\n },\n required: ['angles'],\n },\n },\n)\n\nif (!frame || !frame.angles?.length) {\n
|
|
1
|
+
{"version":3,"file":"research.js","names":[],"sources":["../../../../../src/agent/workflow/builtins/research.ts"],"sourcesContent":["/**\n * Built-in workflow: `research`\n *\n * Multi-modal research sweep on a question (args.question). Fans out search /\n * exploration / source-reading angles in parallel, then synthesises a cited\n * report. Each angle is its own subagent so source reading does not pollute the\n * parent context.\n *\n * Args:\n * - question: research question\n * - depth: 'quick' (2 angles) | 'standard' (4) | 'deep' (6)\n */\n\nexport const RESEARCH_SCRIPT = `export const meta = {\n name: 'research',\n description: 'Multi-angle research on a question with parallel exploration and a cited synthesis.',\n whenToUse: 'User asks a non-trivial research question that benefits from multiple search angles or source reads.',\n examplePrompts: [\n { field: 'question', text: 'Compare Bun vs Node startup performance' },\n { field: 'question', text: 'What are the trade-offs of SQLite vs Postgres for this app?' },\n ],\n i18n: {\n zh: {\n description: '多角度并行调研一个问题,并产出带引用的综合报告。',\n whenToUse: '用户提出需要多角度检索、阅读来源的非平凡调研问题时。',\n examplePrompts: [\n { field: 'question', text: '比较 Bun 与 Node 的启动性能' },\n { field: 'question', text: '这个应用用 SQLite 还是 Postgres 各有什么权衡?' },\n ],\n },\n },\n tags: ['research', 'investigation'],\n estimatedAgents: { min: 4, max: 8 },\n phases: [\n { title: 'Frame' },\n { title: 'Sweep' },\n { title: 'Synthesize' },\n ],\n}\n\nconst RESEARCH_TOOLS = ['web_search', 'web_fetch', 'read_file', 'grep', 'find', 'list_dir']\n\nconst question = args && typeof args === 'object' && args.question\n ? String(args.question)\n : 'No explicit question supplied; infer from the most recent user turn.'\n\nconst depth = args && typeof args === 'object' && args.depth\n ? String(args.depth)\n : 'standard'\nconst maxAngles = depth === 'quick' ? 2 : depth === 'deep' ? 6 : 4\n\nphase('Frame')\nconst frame = await agent(\n 'Frame this research question. Return exactly ' + maxAngles + ' distinct angles worth investigating, ' +\n 'each with the single most decisive sub-question. Be concrete.\\\\n\\\\nQUESTION:\\\\n' +\n question,\n {\n label: 'framing',\n schema: {\n type: 'object',\n properties: {\n angles: {\n type: 'array',\n items: {\n type: 'object',\n properties: {\n title: { type: 'string' },\n key_question: { type: 'string' },\n },\n required: ['title', 'key_question'],\n },\n },\n },\n required: ['angles'],\n },\n },\n)\n\nif (!frame || !frame.angles?.length) {\n const output = { ok: false, reason: 'framing failed', question, depth }\n return {\n summary: output.reason,\n sections: [{ kind: 'json', title: 'Research framing', value: output }],\n structuredOutput: output,\n }\n}\n\nconst angles = frame.angles.slice(0, maxAngles)\n\nphase('Sweep')\nconst angleReports = await parallel(\n angles.map((a) => () =>\n agent(\n 'Investigate this angle. Use search and source-read tools liberally. Distinguish what you can confirm from what is conjecture.\\\\n\\\\n' +\n 'ANGLE: ' + a.title + '\\\\n' +\n 'KEY QUESTION: ' + a.key_question + '\\\\n\\\\n' +\n 'Return: 3–6 grounded findings (each with a 1-line claim and a source URL or file path), plus the strongest counter-evidence.',\n {\n label: a.title,\n toolset: RESEARCH_TOOLS,\n maxIterations: depth === 'deep' ? 40 : 30,\n schema: {\n type: 'object',\n properties: {\n findings: {\n type: 'array',\n items: {\n type: 'object',\n properties: {\n claim: { type: 'string' },\n source: { type: 'string' },\n confidence: { type: 'string', enum: ['low', 'med', 'high'] },\n },\n required: ['claim', 'source', 'confidence'],\n },\n },\n counterEvidence: { type: 'string' },\n },\n required: ['findings'],\n },\n },\n ),\n ),\n)\n\nphase('Synthesize')\nconst live = angleReports.filter(Boolean)\nconst synthesis = await agent(\n 'Synthesize a cited research report from these angle-level findings. Drop unsupported or duplicate claims. Use the highest-confidence source per claim. ' +\n 'Explicitly list contradictions where angles disagree. Return: an executive summary (max 5 sentences), top findings with inline source URLs, open questions, and contradictions.\\\\n\\\\n' +\n 'QUESTION:\\\\n' + question + '\\\\n\\\\n' +\n JSON.stringify({ angles, reports: live }, null, 2),\n {\n label: 'synthesis',\n schema: {\n type: 'object',\n properties: {\n executiveSummary: { type: 'string' },\n topFindings: {\n type: 'array',\n items: {\n type: 'object',\n properties: {\n claim: { type: 'string' },\n source: { type: 'string' },\n },\n required: ['claim', 'source'],\n },\n },\n openQuestions: { type: 'array', items: { type: 'string' } },\n contradictions: {\n type: 'array',\n items: {\n type: 'object',\n properties: {\n topic: { type: 'string' },\n sides: { type: 'array', items: { type: 'string' } },\n },\n required: ['topic', 'sides'],\n },\n },\n },\n required: ['executiveSummary', 'topFindings'],\n },\n },\n)\n\nconst output = {\n ok: true,\n question,\n depth,\n angleCount: angles.length,\n ...(synthesis ?? { executiveSummary: 'synthesis failed', topFindings: [], contradictions: [] }),\n}\nreturn {\n summary: output.executiveSummary,\n sections: [\n { kind: 'findings', title: 'Top findings', items: output.topFindings.map((item) => ({ title: item.claim, detail: item.source })) },\n { kind: 'questions', title: 'Open questions', items: output.openQuestions ?? [] },\n { kind: 'json', title: 'Contradictions', value: output.contradictions ?? [] },\n ],\n structuredOutput: output,\n}\n`\n"],"mappings":";;;;;;;;;;;;;AAaA,MAAa,kBAAkB"}
|
|
@@ -9,4 +9,4 @@
|
|
|
9
9
|
* - blockers: what stalled or frustrated progress
|
|
10
10
|
* - carryover: unfinished items (optional)
|
|
11
11
|
*/
|
|
12
|
-
export declare const WEEKLY_REVIEW_SCRIPT = "export const meta = {\n name: 'weekly_review',\n description: 'Review the week and produce 3\u20135 prioritized actions for next week.',\n whenToUse: 'Solo founder or super-individual doing a weekly retrospective and planning session.',\n examplePrompts: [\n { field: 'wins', text: 'Shipped landing page, got 2 demo calls, published one newsletter' },\n { field: 'blockers', text: 'Pricing still unclear, one client ghosted, distracted by side tasks' },\n ],\n i18n: {\n zh: {\n description: '\u590D\u76D8\u672C\u5468\u5E76\u4EA7\u51FA\u4E0B\u5468 3\u20135 \u9879\u4F18\u5148\u884C\u52A8\u3002',\n whenToUse: '\u4E00\u4EBA\u516C\u53F8\u6216\u8D85\u7EA7\u4E2A\u4F53\u505A\u5468\u590D\u76D8\u4E0E\u4E0B\u5468\u89C4\u5212\u65F6\u3002',\n examplePrompts: [\n { field: 'wins', text: '\u4E0A\u7EBF\u4E86\u843D\u5730\u9875\u3001\u62FF\u5230 2 \u4E2A demo\u3001\u53D1\u4E86\u4E00\u671F newsletter' },\n { field: 'blockers', text: '\u5B9A\u4EF7\u8FD8\u4E0D\u6E05\u6670\u3001\u4E00\u4E2A\u5BA2\u6237\u5931\u8054\u3001\u88AB\u6742\u4E8B\u5206\u5FC3' },\n ],\n },\n },\n tags: ['productivity', 'brainstorm'],\n estimatedAgents: { min: 3, max: 4 },\n phases: [\n { title: 'Collect' },\n { title: 'Analyze' },\n { title: 'Plan' },\n ],\n}\n\nconst wins = args && typeof args === 'object' && args.wins\n ? String(args.wins)\n : 'Infer wins from the most recent user turn.'\n\nconst blockers = args && typeof args === 'object' && args.blockers\n ? String(args.blockers)\n : 'None specified \u2014 infer from context if possible.'\n\nconst carryover = args && typeof args === 'object' && args.carryover\n ? String(args.carryover)\n : ''\n\nphase('Collect')\nconst collected = await agent(\n 'Normalize this weekly input into structured facts: wins, blockers, carryover, energy level signals, and revenue/impact signals if mentioned. Be concise.\\n\\n' +\n 'WINS:\\n' + wins + '\\nBLOCKERS:\\n' + blockers + '\\nCARRYOVER:\\n' + (carryover || '(none)'),\n {\n label: 'collect',\n schema: {\n type: 'object',\n properties: {\n wins: { type: 'array', items: { type: 'string' } },\n blockers: { type: 'array', items: { type: 'string' } },\n carryover: { type: 'array', items: { type: 'string' } },\n themes: { type: 'array', items: { type: 'string' } },\n },\n required: ['wins', 'blockers'],\n },\n },\n)\n\nphase('Analyze')\nconst analysis = await agent(\n 'Analyze this week for a solo operator. Identify patterns, root causes of blockers, what to stop doing, what to double down on, and one honest lesson.\\n\\n' +\n JSON.stringify(collected, null, 2),\n {\n label: 'analyze',\n schema: {\n type: 'object',\n properties: {\n patterns: { type: 'array', items: { type: 'string' } },\n rootCauses: { type: 'array', items: { type: 'string' } },\n stopDoing: { type: 'array', items: { type: 'string' } },\n doubleDown: { type: 'array', items: { type: 'string' } },\n lesson: { type: 'string' },\n },\n required: ['patterns', 'lesson'],\n },\n },\n)\n\nphase('Plan')\nconst plan = await agent(\n 'Produce next week plan for a solo founder: exactly 3\u20135 prioritized actions (each with why, estimated effort, and success signal), plus one optional stretch goal. Be realistic for ~20\u201330 focused hours.\\n\\n' +\n JSON.stringify({ collected, analysis }, null, 2),\n {\n label: 'plan',\n schema: {\n type: 'object',\n properties: {\n priorities: {\n type: 'array',\n items: {\n type: 'object',\n properties: {\n action: { type: 'string' },\n why: { type: 'string' },\n effort: { type: 'string', enum: ['low', 'med', 'high'] },\n successSignal: { type: 'string' },\n },\n required: ['action', 'why', 'successSignal'],\n },\n },\n stretchGoal: { type: 'string' },\n weeklyTheme: { type: 'string' },\n },\n required: ['priorities', 'weeklyTheme'],\n },\n },\n)\n\
|
|
12
|
+
export declare const WEEKLY_REVIEW_SCRIPT = "export const meta = {\n name: 'weekly_review',\n description: 'Review the week and produce 3\u20135 prioritized actions for next week.',\n whenToUse: 'Solo founder or super-individual doing a weekly retrospective and planning session.',\n examplePrompts: [\n { field: 'wins', text: 'Shipped landing page, got 2 demo calls, published one newsletter' },\n { field: 'blockers', text: 'Pricing still unclear, one client ghosted, distracted by side tasks' },\n ],\n i18n: {\n zh: {\n description: '\u590D\u76D8\u672C\u5468\u5E76\u4EA7\u51FA\u4E0B\u5468 3\u20135 \u9879\u4F18\u5148\u884C\u52A8\u3002',\n whenToUse: '\u4E00\u4EBA\u516C\u53F8\u6216\u8D85\u7EA7\u4E2A\u4F53\u505A\u5468\u590D\u76D8\u4E0E\u4E0B\u5468\u89C4\u5212\u65F6\u3002',\n examplePrompts: [\n { field: 'wins', text: '\u4E0A\u7EBF\u4E86\u843D\u5730\u9875\u3001\u62FF\u5230 2 \u4E2A demo\u3001\u53D1\u4E86\u4E00\u671F newsletter' },\n { field: 'blockers', text: '\u5B9A\u4EF7\u8FD8\u4E0D\u6E05\u6670\u3001\u4E00\u4E2A\u5BA2\u6237\u5931\u8054\u3001\u88AB\u6742\u4E8B\u5206\u5FC3' },\n ],\n },\n },\n tags: ['productivity', 'brainstorm'],\n estimatedAgents: { min: 3, max: 4 },\n phases: [\n { title: 'Collect' },\n { title: 'Analyze' },\n { title: 'Plan' },\n ],\n}\n\nconst wins = args && typeof args === 'object' && args.wins\n ? String(args.wins)\n : 'Infer wins from the most recent user turn.'\n\nconst blockers = args && typeof args === 'object' && args.blockers\n ? String(args.blockers)\n : 'None specified \u2014 infer from context if possible.'\n\nconst carryover = args && typeof args === 'object' && args.carryover\n ? String(args.carryover)\n : ''\n\nphase('Collect')\nconst collected = await agent(\n 'Normalize this weekly input into structured facts: wins, blockers, carryover, energy level signals, and revenue/impact signals if mentioned. Be concise.\\n\\n' +\n 'WINS:\\n' + wins + '\\nBLOCKERS:\\n' + blockers + '\\nCARRYOVER:\\n' + (carryover || '(none)'),\n {\n label: 'collect',\n schema: {\n type: 'object',\n properties: {\n wins: { type: 'array', items: { type: 'string' } },\n blockers: { type: 'array', items: { type: 'string' } },\n carryover: { type: 'array', items: { type: 'string' } },\n themes: { type: 'array', items: { type: 'string' } },\n },\n required: ['wins', 'blockers'],\n },\n },\n)\n\nphase('Analyze')\nconst analysis = await agent(\n 'Analyze this week for a solo operator. Identify patterns, root causes of blockers, what to stop doing, what to double down on, and one honest lesson.\\n\\n' +\n JSON.stringify(collected, null, 2),\n {\n label: 'analyze',\n schema: {\n type: 'object',\n properties: {\n patterns: { type: 'array', items: { type: 'string' } },\n rootCauses: { type: 'array', items: { type: 'string' } },\n stopDoing: { type: 'array', items: { type: 'string' } },\n doubleDown: { type: 'array', items: { type: 'string' } },\n lesson: { type: 'string' },\n },\n required: ['patterns', 'lesson'],\n },\n },\n)\n\nphase('Plan')\nconst plan = await agent(\n 'Produce next week plan for a solo founder: exactly 3\u20135 prioritized actions (each with why, estimated effort, and success signal), plus one optional stretch goal. Be realistic for ~20\u201330 focused hours.\\n\\n' +\n JSON.stringify({ collected, analysis }, null, 2),\n {\n label: 'plan',\n schema: {\n type: 'object',\n properties: {\n priorities: {\n type: 'array',\n items: {\n type: 'object',\n properties: {\n action: { type: 'string' },\n why: { type: 'string' },\n effort: { type: 'string', enum: ['low', 'med', 'high'] },\n successSignal: { type: 'string' },\n },\n required: ['action', 'why', 'successSignal'],\n },\n },\n stretchGoal: { type: 'string' },\n weeklyTheme: { type: 'string' },\n },\n required: ['priorities', 'weeklyTheme'],\n },\n },\n)\n\nconst output = {\n ok: true,\n collected,\n analysis,\n ...(plan ?? { priorities: [], weeklyTheme: 'planning failed' }),\n}\nreturn {\n summary: output.weeklyTheme,\n sections: [\n { kind: 'json', title: 'Priorities', value: output.priorities },\n { kind: 'json', title: 'Analysis', value: output.analysis },\n ],\n structuredOutput: output,\n}\n";
|
|
@@ -118,12 +118,20 @@ const plan = await agent(
|
|
|
118
118
|
},
|
|
119
119
|
)
|
|
120
120
|
|
|
121
|
-
|
|
121
|
+
const output = {
|
|
122
122
|
ok: true,
|
|
123
123
|
collected,
|
|
124
124
|
analysis,
|
|
125
125
|
...(plan ?? { priorities: [], weeklyTheme: 'planning failed' }),
|
|
126
126
|
}
|
|
127
|
+
return {
|
|
128
|
+
summary: output.weeklyTheme,
|
|
129
|
+
sections: [
|
|
130
|
+
{ kind: 'json', title: 'Priorities', value: output.priorities },
|
|
131
|
+
{ kind: 'json', title: 'Analysis', value: output.analysis },
|
|
132
|
+
],
|
|
133
|
+
structuredOutput: output,
|
|
134
|
+
}
|
|
127
135
|
`;
|
|
128
136
|
//#endregion
|
|
129
137
|
export { WEEKLY_REVIEW_SCRIPT };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"weekly-review.js","names":[],"sources":["../../../../../src/agent/workflow/builtins/weekly-review.ts"],"sourcesContent":["/**\n * Built-in workflow: `weekly_review`\n *\n * Weekly retrospective for solopreneurs — collect wins, blockers, and carryover,\n * then synthesize next-week priorities.\n *\n * Args:\n * - wins: what went well this week\n * - blockers: what stalled or frustrated progress\n * - carryover: unfinished items (optional)\n */\n\nexport const WEEKLY_REVIEW_SCRIPT = `export const meta = {\n name: 'weekly_review',\n description: 'Review the week and produce 3–5 prioritized actions for next week.',\n whenToUse: 'Solo founder or super-individual doing a weekly retrospective and planning session.',\n examplePrompts: [\n { field: 'wins', text: 'Shipped landing page, got 2 demo calls, published one newsletter' },\n { field: 'blockers', text: 'Pricing still unclear, one client ghosted, distracted by side tasks' },\n ],\n i18n: {\n zh: {\n description: '复盘本周并产出下周 3–5 项优先行动。',\n whenToUse: '一人公司或超级个体做周复盘与下周规划时。',\n examplePrompts: [\n { field: 'wins', text: '上线了落地页、拿到 2 个 demo、发了一期 newsletter' },\n { field: 'blockers', text: '定价还不清晰、一个客户失联、被杂事分心' },\n ],\n },\n },\n tags: ['productivity', 'brainstorm'],\n estimatedAgents: { min: 3, max: 4 },\n phases: [\n { title: 'Collect' },\n { title: 'Analyze' },\n { title: 'Plan' },\n ],\n}\n\nconst wins = args && typeof args === 'object' && args.wins\n ? String(args.wins)\n : 'Infer wins from the most recent user turn.'\n\nconst blockers = args && typeof args === 'object' && args.blockers\n ? String(args.blockers)\n : 'None specified — infer from context if possible.'\n\nconst carryover = args && typeof args === 'object' && args.carryover\n ? String(args.carryover)\n : ''\n\nphase('Collect')\nconst collected = await agent(\n 'Normalize this weekly input into structured facts: wins, blockers, carryover, energy level signals, and revenue/impact signals if mentioned. Be concise.\\\\n\\\\n' +\n 'WINS:\\\\n' + wins + '\\\\nBLOCKERS:\\\\n' + blockers + '\\\\nCARRYOVER:\\\\n' + (carryover || '(none)'),\n {\n label: 'collect',\n schema: {\n type: 'object',\n properties: {\n wins: { type: 'array', items: { type: 'string' } },\n blockers: { type: 'array', items: { type: 'string' } },\n carryover: { type: 'array', items: { type: 'string' } },\n themes: { type: 'array', items: { type: 'string' } },\n },\n required: ['wins', 'blockers'],\n },\n },\n)\n\nphase('Analyze')\nconst analysis = await agent(\n 'Analyze this week for a solo operator. Identify patterns, root causes of blockers, what to stop doing, what to double down on, and one honest lesson.\\\\n\\\\n' +\n JSON.stringify(collected, null, 2),\n {\n label: 'analyze',\n schema: {\n type: 'object',\n properties: {\n patterns: { type: 'array', items: { type: 'string' } },\n rootCauses: { type: 'array', items: { type: 'string' } },\n stopDoing: { type: 'array', items: { type: 'string' } },\n doubleDown: { type: 'array', items: { type: 'string' } },\n lesson: { type: 'string' },\n },\n required: ['patterns', 'lesson'],\n },\n },\n)\n\nphase('Plan')\nconst plan = await agent(\n 'Produce next week plan for a solo founder: exactly 3–5 prioritized actions (each with why, estimated effort, and success signal), plus one optional stretch goal. Be realistic for ~20–30 focused hours.\\\\n\\\\n' +\n JSON.stringify({ collected, analysis }, null, 2),\n {\n label: 'plan',\n schema: {\n type: 'object',\n properties: {\n priorities: {\n type: 'array',\n items: {\n type: 'object',\n properties: {\n action: { type: 'string' },\n why: { type: 'string' },\n effort: { type: 'string', enum: ['low', 'med', 'high'] },\n successSignal: { type: 'string' },\n },\n required: ['action', 'why', 'successSignal'],\n },\n },\n stretchGoal: { type: 'string' },\n weeklyTheme: { type: 'string' },\n },\n required: ['priorities', 'weeklyTheme'],\n },\n },\n)\n\
|
|
1
|
+
{"version":3,"file":"weekly-review.js","names":[],"sources":["../../../../../src/agent/workflow/builtins/weekly-review.ts"],"sourcesContent":["/**\n * Built-in workflow: `weekly_review`\n *\n * Weekly retrospective for solopreneurs — collect wins, blockers, and carryover,\n * then synthesize next-week priorities.\n *\n * Args:\n * - wins: what went well this week\n * - blockers: what stalled or frustrated progress\n * - carryover: unfinished items (optional)\n */\n\nexport const WEEKLY_REVIEW_SCRIPT = `export const meta = {\n name: 'weekly_review',\n description: 'Review the week and produce 3–5 prioritized actions for next week.',\n whenToUse: 'Solo founder or super-individual doing a weekly retrospective and planning session.',\n examplePrompts: [\n { field: 'wins', text: 'Shipped landing page, got 2 demo calls, published one newsletter' },\n { field: 'blockers', text: 'Pricing still unclear, one client ghosted, distracted by side tasks' },\n ],\n i18n: {\n zh: {\n description: '复盘本周并产出下周 3–5 项优先行动。',\n whenToUse: '一人公司或超级个体做周复盘与下周规划时。',\n examplePrompts: [\n { field: 'wins', text: '上线了落地页、拿到 2 个 demo、发了一期 newsletter' },\n { field: 'blockers', text: '定价还不清晰、一个客户失联、被杂事分心' },\n ],\n },\n },\n tags: ['productivity', 'brainstorm'],\n estimatedAgents: { min: 3, max: 4 },\n phases: [\n { title: 'Collect' },\n { title: 'Analyze' },\n { title: 'Plan' },\n ],\n}\n\nconst wins = args && typeof args === 'object' && args.wins\n ? String(args.wins)\n : 'Infer wins from the most recent user turn.'\n\nconst blockers = args && typeof args === 'object' && args.blockers\n ? String(args.blockers)\n : 'None specified — infer from context if possible.'\n\nconst carryover = args && typeof args === 'object' && args.carryover\n ? String(args.carryover)\n : ''\n\nphase('Collect')\nconst collected = await agent(\n 'Normalize this weekly input into structured facts: wins, blockers, carryover, energy level signals, and revenue/impact signals if mentioned. Be concise.\\\\n\\\\n' +\n 'WINS:\\\\n' + wins + '\\\\nBLOCKERS:\\\\n' + blockers + '\\\\nCARRYOVER:\\\\n' + (carryover || '(none)'),\n {\n label: 'collect',\n schema: {\n type: 'object',\n properties: {\n wins: { type: 'array', items: { type: 'string' } },\n blockers: { type: 'array', items: { type: 'string' } },\n carryover: { type: 'array', items: { type: 'string' } },\n themes: { type: 'array', items: { type: 'string' } },\n },\n required: ['wins', 'blockers'],\n },\n },\n)\n\nphase('Analyze')\nconst analysis = await agent(\n 'Analyze this week for a solo operator. Identify patterns, root causes of blockers, what to stop doing, what to double down on, and one honest lesson.\\\\n\\\\n' +\n JSON.stringify(collected, null, 2),\n {\n label: 'analyze',\n schema: {\n type: 'object',\n properties: {\n patterns: { type: 'array', items: { type: 'string' } },\n rootCauses: { type: 'array', items: { type: 'string' } },\n stopDoing: { type: 'array', items: { type: 'string' } },\n doubleDown: { type: 'array', items: { type: 'string' } },\n lesson: { type: 'string' },\n },\n required: ['patterns', 'lesson'],\n },\n },\n)\n\nphase('Plan')\nconst plan = await agent(\n 'Produce next week plan for a solo founder: exactly 3–5 prioritized actions (each with why, estimated effort, and success signal), plus one optional stretch goal. Be realistic for ~20–30 focused hours.\\\\n\\\\n' +\n JSON.stringify({ collected, analysis }, null, 2),\n {\n label: 'plan',\n schema: {\n type: 'object',\n properties: {\n priorities: {\n type: 'array',\n items: {\n type: 'object',\n properties: {\n action: { type: 'string' },\n why: { type: 'string' },\n effort: { type: 'string', enum: ['low', 'med', 'high'] },\n successSignal: { type: 'string' },\n },\n required: ['action', 'why', 'successSignal'],\n },\n },\n stretchGoal: { type: 'string' },\n weeklyTheme: { type: 'string' },\n },\n required: ['priorities', 'weeklyTheme'],\n },\n },\n)\n\nconst output = {\n ok: true,\n collected,\n analysis,\n ...(plan ?? { priorities: [], weeklyTheme: 'planning failed' }),\n}\nreturn {\n summary: output.weeklyTheme,\n sections: [\n { kind: 'json', title: 'Priorities', value: output.priorities },\n { kind: 'json', title: 'Analysis', value: output.analysis },\n ],\n structuredOutput: output,\n}\n`\n"],"mappings":";;;;;;;;;;;;AAYA,MAAa,uBAAuB"}
|