@xopcai/xopc 0.0.86 → 0.0.88
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/dist/browser-ext/manifest.json +1 -1
- package/dist/extensions/feishu/src/adapters/cli-login.js +3 -3
- package/dist/extensions/feishu/src/adapters/cli-login.js.map +1 -1
- package/dist/extensions/feishu/src/outbound/media-load.js +1 -1
- package/dist/extensions/feishu/src/workflow-progress.js +1 -1
- package/dist/extensions/telegram/src/delivery-chat-id.d.ts +1 -1
- package/dist/extensions/telegram/src/delivery-chat-id.js +1 -1
- package/dist/extensions/telegram/src/delivery-chat-id.js.map +1 -1
- package/dist/extensions/telegram/src/plugin.js +1 -1
- package/dist/extensions/telegram/src/routing-integration.js +3 -2
- package/dist/extensions/telegram/src/routing-integration.js.map +1 -1
- package/dist/extensions/telegram/src/workflow-progress.js +1 -1
- package/dist/extensions/telegram/xopc.extension.json +1 -1
- package/dist/extensions/weixin/src/__tests__/workflow-progress.test.js +2 -2
- package/dist/extensions/weixin/src/__tests__/workflow-progress.test.js.map +1 -1
- package/dist/extensions/weixin/src/api/api.js +3 -3
- package/dist/extensions/weixin/src/api/api.js.map +1 -1
- package/dist/extensions/weixin/src/auth/accounts.js +12 -12
- package/dist/extensions/weixin/src/auth/accounts.js.map +1 -1
- package/dist/extensions/weixin/src/cdn/upload.js +1 -1
- package/dist/extensions/weixin/src/delivery-to.js +2 -2
- package/dist/extensions/weixin/src/delivery-to.js.map +1 -1
- package/dist/extensions/weixin/src/media/data-url.js +1 -1
- package/dist/extensions/weixin/src/messaging/debug-mode.js +5 -5
- package/dist/extensions/weixin/src/messaging/debug-mode.js.map +1 -1
- package/dist/extensions/weixin/src/messaging/inbound.js +11 -11
- package/dist/extensions/weixin/src/messaging/inbound.js.map +1 -1
- package/dist/extensions/weixin/src/messaging/process-message.js +1 -1
- package/dist/extensions/weixin/src/plugin.js +1 -1
- package/dist/extensions/weixin/src/storage/sync-buf.js +4 -4
- package/dist/extensions/weixin/src/storage/sync-buf.js.map +1 -1
- package/dist/extensions/weixin/src/workflow-progress.d.ts +1 -1
- package/dist/extensions/weixin/src/workflow-progress.js +1 -1
- package/dist/extensions/weixin/src/workflow-progress.js.map +1 -1
- package/dist/gateway/static/root/assets/agents-CRxETUZx.js +222 -0
- package/dist/gateway/static/root/assets/{apps-page-DrfytjOb.js → apps-page-wKWf3l57.js} +1 -1
- package/dist/gateway/static/root/assets/channels-settings-DDbqVNkx.js +1 -0
- package/dist/gateway/static/root/assets/{channels-status-swr-Bs5kMCMI.js → channels-status-swr-DIsl75Y3.js} +1 -1
- package/dist/gateway/static/root/assets/copy-SxMW6Xpc.js +1 -0
- package/dist/gateway/static/root/assets/{cron-api-BuVcZ5zR.js → cron-api-N9hvuRrn.js} +1 -1
- package/dist/gateway/static/root/assets/{cron-page-BMrloeFH.js → cron-page-tlNGNxhP.js} +1 -1
- package/dist/gateway/static/root/assets/{dist-CKU1OOTf.js → dist-CJwfHYvT.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-debug-page-BdW_46sN.js → extension-debug-page-BVJohZoZ.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-page-DW47KI82.js → extension-page-BT2tmElC.js} +1 -1
- package/dist/gateway/static/root/assets/extension-settings-page-BSS47c2j.js +1 -0
- package/dist/gateway/static/root/assets/{fetch-B2MYHbWg.js → fetch-BaFNUtkE.js} +1 -1
- package/dist/gateway/static/root/assets/{field-primitives-DPG-oJmx.js → field-primitives-QwYEq6Hz.js} +1 -1
- package/dist/gateway/static/root/assets/{heartbeat-config-api-C8dNts9i.js → heartbeat-config-api-BVSidEDJ.js} +1 -1
- package/dist/gateway/static/root/assets/index-CqZzHNEg.css +1 -0
- package/dist/gateway/static/root/assets/{index-BmVYculr.js → index-qNrVJp-y.js} +97 -95
- package/dist/gateway/static/root/assets/{logs-page-sTsVWz0X.js → logs-page-DDonPVLn.js} +1 -1
- package/dist/gateway/static/root/assets/sessions-page-DKt-Wmib.js +1 -0
- package/dist/gateway/static/root/assets/{settings-form-section-DuvRQW--.js → settings-form-section-B8N3A3Zo.js} +1 -1
- package/dist/gateway/static/root/assets/settings-page-DcJjvvw4.js +3 -0
- package/dist/gateway/static/root/assets/{share-preview-page-BtG2kLDh.js → share-preview-page-Q7KqkO-u.js} +1 -1
- package/dist/gateway/static/root/assets/skills-page-DuJ4BTO3.js +2 -0
- package/dist/gateway/static/root/assets/{theme-store-DryYl3qD.js → theme-store-BbRc5ugR.js} +1 -1
- package/dist/gateway/static/root/assets/url-D6jvVYIA.js +7 -0
- package/dist/gateway/static/root/assets/{utils-BY7bU1DT.js → utils-CxDGduqK.js} +1 -1
- package/dist/gateway/static/root/assets/voice-api-key-field-CTyHz7L_.js +1 -0
- package/dist/gateway/static/root/assets/workflows-page-GacJ41Fv.js +27 -0
- package/dist/gateway/static/root/index.html +6 -5
- package/dist/package.js +1 -1
- package/dist/src/agent/agent-manager.js +7 -7
- package/dist/src/agent/agent-scope.d.ts +4 -0
- package/dist/src/agent/agent-scope.js +53 -10
- package/dist/src/agent/agent-scope.js.map +1 -1
- package/dist/src/agent/bootstrap/filter-bootstrap-files.js +2 -1
- package/dist/src/agent/bootstrap/filter-bootstrap-files.js.map +1 -1
- package/dist/src/agent/bootstrap/load-bootstrap-files.js +1 -1
- package/dist/src/agent/child-agent-factory.d.ts +15 -0
- package/dist/src/agent/child-agent-factory.js +35 -2
- package/dist/src/agent/child-agent-factory.js.map +1 -1
- package/dist/src/agent/client-error-format.d.ts +20 -0
- package/dist/src/agent/client-error-format.js +97 -0
- package/dist/src/agent/client-error-format.js.map +1 -0
- package/dist/src/agent/context/workspace-seed.js +2 -2
- package/dist/src/agent/embedded/run-turn.js +23 -4
- package/dist/src/agent/embedded/run-turn.js.map +1 -1
- package/dist/src/agent/embedded/session-tool-result-guard.js +2 -1
- package/dist/src/agent/embedded/session-tool-result-guard.js.map +1 -1
- package/dist/src/agent/embedded/tool-result-truncation.js +2 -1
- package/dist/src/agent/embedded/tool-result-truncation.js.map +1 -1
- package/dist/src/agent/fallback/candidates.js +2 -2
- package/dist/src/agent/fallback/candidates.js.map +1 -1
- package/dist/src/agent/goals/goal-locale.d.ts +1 -1
- package/dist/src/agent/goals/goal-run-store.js +4 -4
- package/dist/src/agent/goals/persistent-goal-apis.d.ts +0 -2
- package/dist/src/agent/goals/persistent-goal-service.js +1 -2
- package/dist/src/agent/goals/persistent-goal-service.js.map +1 -1
- package/dist/src/agent/goals/post-turn.js +2 -2
- package/dist/src/agent/image/generation/normalization.js +2 -12
- package/dist/src/agent/image/generation/normalization.js.map +1 -1
- package/dist/src/agent/image/generation/provider-registry.d.ts +4 -8
- package/dist/src/agent/image/generation/provider-registry.js.map +1 -1
- package/dist/src/agent/image/generation/runtime.d.ts +2 -2
- package/dist/src/agent/image/generation/runtime.js.map +1 -1
- package/dist/src/agent/image/generation/types.d.ts +0 -18
- package/dist/src/agent/image/image-helpers.js +6 -1
- package/dist/src/agent/image/image-helpers.js.map +1 -1
- package/dist/src/agent/image/index.d.ts +1 -1
- package/dist/src/agent/image/load-image-media.js +2 -2
- package/dist/src/agent/inbound/inbound-loop.d.ts +5 -0
- package/dist/src/agent/inbound/inbound-loop.js +41 -10
- package/dist/src/agent/inbound/inbound-loop.js.map +1 -1
- package/dist/src/agent/inbound/turn-dispatcher.d.ts +4 -0
- package/dist/src/agent/inbound/turn-dispatcher.js +7 -5
- package/dist/src/agent/inbound/turn-dispatcher.js.map +1 -1
- package/dist/src/agent/ipc/bus.js +1 -1
- package/dist/src/agent/ipc/inbox.js +2 -2
- package/dist/src/agent/ipc/socket.js +1 -1
- package/dist/src/agent/mcp/bundle-mcp-materialize.js +2 -1
- package/dist/src/agent/mcp/bundle-mcp-materialize.js.map +1 -1
- package/dist/src/agent/mcp/bundle-mcp-names.js +2 -1
- package/dist/src/agent/mcp/bundle-mcp-names.js.map +1 -1
- package/dist/src/agent/mcp/bundle-mcp-runtime.js +2 -1
- package/dist/src/agent/mcp/bundle-mcp-runtime.js.map +1 -1
- package/dist/src/agent/mcp/mcp-transport-config.js +2 -1
- package/dist/src/agent/mcp/mcp-transport-config.js.map +1 -1
- package/dist/src/agent/mcp/mcp-transport.js +2 -1
- package/dist/src/agent/mcp/mcp-transport.js.map +1 -1
- package/dist/src/agent/media-generation/runtime-shared.js +2 -9
- package/dist/src/agent/media-generation/runtime-shared.js.map +1 -1
- package/dist/src/agent/memory/builtin-memory-store.js +1 -1
- package/dist/src/agent/memory/dreaming/deep-promotion.js +1 -1
- package/dist/src/agent/memory/dreaming/events.js +1 -1
- package/dist/src/agent/memory/dreaming/last-run.js +1 -1
- package/dist/src/agent/memory/dreaming/light-sweep.js +1 -1
- package/dist/src/agent/memory/dreaming/preview.js +1 -1
- package/dist/src/agent/memory/dreaming/rem-patterns.js +1 -1
- package/dist/src/agent/memory/dreaming/short-term-store.js +1 -1
- package/dist/src/agent/memory/dreaming/utils.js +1 -1
- package/dist/src/agent/memory/plugin-discovery.js +1 -1
- package/dist/src/agent/messaging/command-handler.d.ts +6 -0
- package/dist/src/agent/messaging/command-handler.js +5 -0
- package/dist/src/agent/messaging/command-handler.js.map +1 -1
- package/dist/src/agent/models/manager.js +1 -1
- package/dist/src/agent/orchestration/llm-turn-retry.d.ts +2 -0
- package/dist/src/agent/orchestration/llm-turn-retry.js +9 -1
- package/dist/src/agent/orchestration/llm-turn-retry.js.map +1 -1
- package/dist/src/agent/prompt/safety.d.ts +0 -7
- package/dist/src/agent/prompt/safety.js +1 -20
- package/dist/src/agent/prompt/safety.js.map +1 -1
- package/dist/src/agent/prompt/service-prompt-builder.js +2 -2
- package/dist/src/agent/reply/post-compaction-context.js +1 -1
- package/dist/src/agent/reply/workspace-boundary-read.js +1 -1
- package/dist/src/agent/sandbox/path-policy.js +2 -2
- package/dist/src/agent/service/build-direct-message-content.js +2 -2
- package/dist/src/agent/service/build-direct-message-content.js.map +1 -1
- package/dist/src/agent/service/direct-turn-helpers.d.ts +3 -1
- package/dist/src/agent/service/direct-turn-helpers.js +6 -1
- package/dist/src/agent/service/direct-turn-helpers.js.map +1 -1
- package/dist/src/agent/service/process-direct-one-shot.d.ts +4 -0
- package/dist/src/agent/service/process-direct-one-shot.js +15 -2
- package/dist/src/agent/service/process-direct-one-shot.js.map +1 -1
- package/dist/src/agent/service/process-direct-streaming.d.ts +4 -0
- package/dist/src/agent/service/process-direct-streaming.js +53 -7
- package/dist/src/agent/service/process-direct-streaming.js.map +1 -1
- package/dist/src/agent/service/webchat-tts.d.ts +1 -2
- package/dist/src/agent/service/webchat-tts.js +2 -2
- package/dist/src/agent/service/webchat-tts.js.map +1 -1
- package/dist/src/agent/service.d.ts +8 -0
- package/dist/src/agent/service.js +25 -5
- package/dist/src/agent/service.js.map +1 -1
- package/dist/src/agent/session/session-inspector.js +1 -1
- package/dist/src/agent/skills/config.js +1 -1
- package/dist/src/agent/skills/hub-hash.js +2 -2
- package/dist/src/agent/skills/hub-lock.js +1 -1
- package/dist/src/agent/skills/hub-pull.js +2 -2
- package/dist/src/agent/skills/index.js +1 -1
- package/dist/src/agent/skills/managed-store.js +1 -1
- package/dist/src/agent/skills/scanner.js +1 -1
- package/dist/src/agent/skills/skill-manage-ops.js +1 -1
- package/dist/src/agent/skills/skill-manager.js +1 -1
- package/dist/src/agent/tools/create-share-tool.js +27 -20
- package/dist/src/agent/tools/create-share-tool.js.map +1 -1
- package/dist/src/agent/tools/dreaming-tool.js +1 -1
- package/dist/src/agent/tools/factory.js +2 -2
- package/dist/src/agent/tools/image-generate-tool.js +1 -1
- package/dist/src/agent/tools/index.d.ts +0 -1
- package/dist/src/agent/tools/index.js +4 -5
- package/dist/src/agent/tools/send-media.js +1 -1
- package/dist/src/agent/tools/shell.js +0 -13
- package/dist/src/agent/tools/shell.js.map +1 -1
- package/dist/src/agent/tools/skill-manage-tool.js +1 -1
- package/dist/src/agent/tools/workflow-tool.js +70 -16
- package/dist/src/agent/tools/workflow-tool.js.map +1 -1
- package/dist/src/agent/tools/write.js +1 -1
- package/dist/src/agent/workflow/agent-progress.d.ts +5 -0
- package/dist/src/agent/workflow/agent-progress.js +65 -0
- package/dist/src/agent/workflow/agent-progress.js.map +1 -0
- package/dist/src/agent/workflow/builtins/audit-repo.d.ts +1 -1
- package/dist/src/agent/workflow/builtins/audit-repo.js +14 -0
- package/dist/src/agent/workflow/builtins/audit-repo.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 +14 -0
- package/dist/src/agent/workflow/builtins/debug-incident.js.map +1 -1
- package/dist/src/agent/workflow/builtins/implementation-plan.d.ts +12 -0
- package/dist/src/agent/workflow/builtins/implementation-plan.js +175 -0
- package/dist/src/agent/workflow/builtins/implementation-plan.js.map +1 -0
- package/dist/src/agent/workflow/builtins/index.d.ts +3 -1
- package/dist/src/agent/workflow/builtins/index.js +11 -1
- package/dist/src/agent/workflow/builtins/index.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 +14 -0
- package/dist/src/agent/workflow/builtins/multi-perspective-review.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 +14 -0
- package/dist/src/agent/workflow/builtins/pr-review.js.map +1 -1
- package/dist/src/agent/workflow/builtins/release-check.d.ts +11 -0
- package/dist/src/agent/workflow/builtins/release-check.js +165 -0
- package/dist/src/agent/workflow/builtins/release-check.js.map +1 -0
- package/dist/src/agent/workflow/builtins/research.d.ts +1 -1
- package/dist/src/agent/workflow/builtins/research.js +14 -0
- package/dist/src/agent/workflow/builtins/research.js.map +1 -1
- package/dist/src/agent/workflow/catalog.js +1 -1
- package/dist/src/agent/workflow/channel-capability.d.ts +3 -3
- package/dist/src/agent/workflow/index.d.ts +2 -1
- package/dist/src/agent/workflow/index.js +3 -2
- package/dist/src/agent/workflow/lint.d.ts +38 -0
- package/dist/src/agent/workflow/lint.js +74 -0
- package/dist/src/agent/workflow/lint.js.map +1 -0
- package/dist/src/agent/workflow/meta-locale.d.ts +12 -0
- package/dist/src/agent/workflow/meta-locale.js +62 -0
- package/dist/src/agent/workflow/meta-locale.js.map +1 -0
- package/dist/src/agent/workflow/parser.js +7 -1
- package/dist/src/agent/workflow/parser.js.map +1 -1
- package/dist/src/agent/workflow/runtime.d.ts +4 -1
- package/dist/src/agent/workflow/runtime.js +88 -8
- package/dist/src/agent/workflow/runtime.js.map +1 -1
- package/dist/src/agent/workflow/snapshot.js +2 -12
- package/dist/src/agent/workflow/snapshot.js.map +1 -1
- package/dist/src/agent/workflow/step-labels.d.ts +8 -0
- package/dist/src/agent/workflow/step-labels.js +48 -0
- package/dist/src/agent/workflow/step-labels.js.map +1 -0
- package/dist/src/agent/workflow/subagent-runner.js +46 -1
- package/dist/src/agent/workflow/subagent-runner.js.map +1 -1
- package/dist/src/agent/workflow/types.d.ts +76 -1
- package/dist/src/auth/credentials.d.ts +5 -0
- package/dist/src/auth/credentials.js +12 -3
- package/dist/src/auth/credentials.js.map +1 -1
- package/dist/src/auth/profiles/store.js +1 -1
- package/dist/src/auth/sync-provider-auth.js +1 -1
- package/dist/src/browser/cache-dir-policy.js +1 -1
- package/dist/src/browser/cdp-local-launcher.js +2 -2
- package/dist/src/browser/index.js +4 -4
- package/dist/src/browser/manager.d.ts +1 -3
- package/dist/src/browser/manager.js +0 -6
- package/dist/src/browser/manager.js.map +1 -1
- package/dist/src/browser/providers/browser-ext-install.d.ts +4 -4
- package/dist/src/browser/providers/browser-ext-install.js +41 -88
- package/dist/src/browser/providers/browser-ext-install.js.map +1 -1
- package/dist/src/browser/providers/cloakbrowser.d.ts +0 -5
- package/dist/src/browser/providers/cloakbrowser.js +6 -59
- package/dist/src/browser/providers/cloakbrowser.js.map +1 -1
- package/dist/src/browser/providers/playwright-doctor.js +1 -1
- package/dist/src/browser/stealth.js +1 -1
- package/dist/src/channels/attachments/inbound-persist.js +1 -1
- package/dist/src/channels/attachments/outbound-tts-persist.js +1 -1
- package/dist/src/channels/attachments/voice-stt-webchat.js +10 -8
- package/dist/src/channels/attachments/voice-stt-webchat.js.map +1 -1
- package/dist/src/channels/outbound/persist-store.js +1 -1
- package/dist/src/channels/pairing/allow-from-file.js +9 -9
- package/dist/src/channels/pairing/allow-from-file.js.map +1 -1
- package/dist/src/channels/pairing/pairing-store.js +7 -7
- package/dist/src/channels/pairing/pairing-store.js.map +1 -1
- package/dist/src/chat-commands/builtins/config.js +2 -2
- package/dist/src/chat-commands/builtins/session.js +1 -1
- package/dist/src/chat-commands/builtins/session.js.map +1 -1
- package/dist/src/chat-commands/builtins/tts.js +2 -2
- package/dist/src/chat-commands/builtins/tts.js.map +1 -1
- package/dist/src/chat-commands/context.d.ts +3 -0
- package/dist/src/chat-commands/context.js +22 -4
- package/dist/src/chat-commands/context.js.map +1 -1
- package/dist/src/chat-commands/session-key.d.ts +4 -37
- package/dist/src/chat-commands/session-key.js +49 -85
- package/dist/src/chat-commands/session-key.js.map +1 -1
- package/dist/src/chat-commands/types.d.ts +2 -0
- package/dist/src/cli/commands/agent/interactive.js +2 -2
- package/dist/src/cli/commands/agent/interactive.js.map +1 -1
- package/dist/src/cli/commands/agent/sessions.js +2 -2
- package/dist/src/cli/commands/agent/sessions.js.map +1 -1
- package/dist/src/cli/commands/agent.js +4 -5
- package/dist/src/cli/commands/agent.js.map +1 -1
- package/dist/src/cli/commands/channels.js +1 -5
- package/dist/src/cli/commands/channels.js.map +1 -1
- package/dist/src/cli/commands/config.js +1 -1
- package/dist/src/cli/commands/doctor/checks/config-health.js +1 -1
- package/dist/src/cli/commands/doctor/checks/provider-auth.js +1 -1
- package/dist/src/cli/commands/doctor/checks/session-integrity.js +1 -1
- package/dist/src/cli/commands/doctor/checks/state-integrity.js +1 -1
- package/dist/src/cli/commands/doctor/checks/workspace-status.js +1 -1
- package/dist/src/cli/commands/extension-dev.js +1 -1
- package/dist/src/cli/commands/extension-marketplace.js +1 -1
- package/dist/src/cli/commands/extension-pack.js +1 -1
- package/dist/src/cli/commands/gateway/lifecycle-core.js +1 -1
- package/dist/src/cli/commands/gateway/lifecycle-core.js.map +1 -1
- package/dist/src/cli/commands/gateway/logs.d.ts +9 -0
- package/dist/src/cli/commands/gateway/logs.js +50 -17
- package/dist/src/cli/commands/gateway/logs.js.map +1 -1
- package/dist/src/cli/commands/image.js +23 -22
- package/dist/src/cli/commands/image.js.map +1 -1
- package/dist/src/cli/commands/init.js +4 -4
- package/dist/src/cli/commands/onboard.js +1 -1
- package/dist/src/cli/commands/session/utils.js +2 -2
- package/dist/src/cli/commands/session/utils.js.map +1 -1
- package/dist/src/cli/commands/update.js +26 -46
- package/dist/src/cli/commands/update.js.map +1 -1
- package/dist/src/cli/utils/init-workspace-core.js +2 -2
- package/dist/src/cli/utils/session.d.ts +0 -5
- package/dist/src/cli/utils/session.js +1 -6
- package/dist/src/cli/utils/session.js.map +1 -1
- package/dist/src/commands/agents.config.js +1 -1
- package/dist/src/commands/agents.config.js.map +1 -1
- package/dist/src/config/agent-profile.js +6 -28
- package/dist/src/config/agent-profile.js.map +1 -1
- package/dist/src/config/agent-typed-models.d.ts +18 -0
- package/dist/src/config/agent-typed-models.js +53 -0
- package/dist/src/config/agent-typed-models.js.map +1 -0
- package/dist/src/config/gateway-bind.js +1 -1
- package/dist/src/config/index.js +6 -6
- package/dist/src/config/loader.js +2 -2
- package/dist/src/config/model-input.js +2 -5
- package/dist/src/config/model-input.js.map +1 -1
- package/dist/src/config/models-json.js +2 -2
- package/dist/src/config/paths-state.js +1 -1
- package/dist/src/config/profile.js +2 -2
- package/dist/src/config/schema.d.ts +253 -217
- package/dist/src/config/schema.js +91 -40
- package/dist/src/config/schema.js.map +1 -1
- package/dist/src/config/voice.d.ts +3 -28
- package/dist/src/config/voice.js +27 -261
- package/dist/src/config/voice.js.map +1 -1
- package/dist/src/config/workspace-path-helpers.d.ts +1 -2
- package/dist/src/config/workspace-path-helpers.js.map +1 -1
- package/dist/src/config/workspace-path.js +1 -1
- package/dist/src/cron/executor.js +2 -2
- package/dist/src/cron/persistence.js +1 -1
- package/dist/src/cron/run-log-store.js +1 -1
- package/dist/src/daemon/constants.js +1 -1
- package/dist/src/daemon/install-plan.js +27 -3
- package/dist/src/daemon/install-plan.js.map +1 -1
- package/dist/src/daemon/launchd.d.ts +8 -0
- package/dist/src/daemon/launchd.js +7 -14
- package/dist/src/daemon/launchd.js.map +1 -1
- package/dist/src/daemon/schtasks.d.ts +25 -0
- package/dist/src/daemon/schtasks.js +168 -48
- package/dist/src/daemon/schtasks.js.map +1 -1
- package/dist/src/daemon/service.js +5 -4
- package/dist/src/daemon/service.js.map +1 -1
- package/dist/src/daemon/systemd.d.ts +6 -0
- package/dist/src/daemon/systemd.js +20 -5
- package/dist/src/daemon/systemd.js.map +1 -1
- package/dist/src/extensions/activation-context.js +0 -1
- package/dist/src/extensions/activation-context.js.map +1 -1
- package/dist/src/extensions/bundle-mcp.js +1 -1
- package/dist/src/extensions/discover-extensions.js +1 -1
- package/dist/src/extensions/health.js +1 -1
- package/dist/src/extensions/loader.js +1 -1
- package/dist/src/extensions/lockfile.js +2 -2
- package/dist/src/extensions/normalize-manifest.js +0 -1
- package/dist/src/extensions/normalize-manifest.js.map +1 -1
- package/dist/src/extensions/types/manifest.d.ts +0 -2
- package/dist/src/gateway/agent-builtin-tools.d.ts +1 -1
- package/dist/src/gateway/agent-builtin-tools.js +1 -0
- package/dist/src/gateway/agent-builtin-tools.js.map +1 -1
- package/dist/src/gateway/agents-admin.d.ts +9 -0
- package/dist/src/gateway/agents-admin.js +28 -4
- package/dist/src/gateway/agents-admin.js.map +1 -1
- package/dist/src/gateway/config-tools-web.js +3 -2
- package/dist/src/gateway/config-tools-web.js.map +1 -1
- package/dist/src/gateway/file-path-classifier.js +2 -2
- package/dist/src/gateway/heartbeat/service.js +2 -2
- package/dist/src/gateway/heartbeat/service.js.map +1 -1
- package/dist/src/gateway/hono/app.js +1 -1
- package/dist/src/gateway/hono/lib/agent-model.d.ts +25 -10
- package/dist/src/gateway/hono/lib/agent-model.js +60 -36
- package/dist/src/gateway/hono/lib/agent-model.js.map +1 -1
- package/dist/src/gateway/hono/lib/config-payload.js +29 -6
- package/dist/src/gateway/hono/lib/config-payload.js.map +1 -1
- package/dist/src/gateway/hono/lib/extension-store.js +2 -2
- package/dist/src/gateway/hono/lib/mask-secret-length.d.ts +6 -0
- package/dist/src/gateway/hono/lib/mask-secret-length.js +16 -0
- package/dist/src/gateway/hono/lib/mask-secret-length.js.map +1 -0
- package/dist/src/gateway/hono/lib/safe-providers-config.d.ts +1 -1
- package/dist/src/gateway/hono/lib/safe-providers-config.js +2 -1
- package/dist/src/gateway/hono/lib/safe-providers-config.js.map +1 -1
- package/dist/src/gateway/hono/lib/safe-voice-config.js +16 -54
- package/dist/src/gateway/hono/lib/safe-voice-config.js.map +1 -1
- package/dist/src/gateway/hono/lib/static-ui.js +2 -2
- package/dist/src/gateway/hono/oauth.js +1 -1
- package/dist/src/gateway/hono/routes/agents.js +2 -2
- package/dist/src/gateway/hono/routes/auth-registry-extensions.js +1 -1
- package/dist/src/gateway/hono/routes/config-patch/agents.js +25 -7
- package/dist/src/gateway/hono/routes/config-patch/agents.js.map +1 -1
- package/dist/src/gateway/hono/routes/config-patch/channels.js +0 -11
- package/dist/src/gateway/hono/routes/config-patch/channels.js.map +1 -1
- package/dist/src/gateway/hono/routes/config-patch/gateway.js +3 -2
- package/dist/src/gateway/hono/routes/config-patch/gateway.js.map +1 -1
- package/dist/src/gateway/hono/routes/config-patch/misc.js +8 -3
- package/dist/src/gateway/hono/routes/config-patch/misc.js.map +1 -1
- package/dist/src/gateway/hono/routes/config.js +59 -0
- package/dist/src/gateway/hono/routes/config.js.map +1 -1
- package/dist/src/gateway/hono/routes/dreaming.js +1 -1
- package/dist/src/gateway/hono/routes/goals.js +1 -1
- package/dist/src/gateway/hono/routes/goals.js.map +1 -1
- package/dist/src/gateway/hono/routes/host-fs.js +2 -2
- package/dist/src/gateway/hono/routes/lazy-bundles.js +8 -0
- package/dist/src/gateway/hono/routes/lazy-bundles.js.map +1 -1
- package/dist/src/gateway/hono/routes/models.js +75 -12
- package/dist/src/gateway/hono/routes/models.js.map +1 -1
- package/dist/src/gateway/hono/routes/sessions.js +28 -7
- package/dist/src/gateway/hono/routes/sessions.js.map +1 -1
- package/dist/src/gateway/hono/routes/shares.js +15 -13
- package/dist/src/gateway/hono/routes/shares.js.map +1 -1
- package/dist/src/gateway/hono/routes/tunnel.js +1 -1
- package/dist/src/gateway/hono/routes/update.js +4 -2
- package/dist/src/gateway/hono/routes/update.js.map +1 -1
- package/dist/src/gateway/hono/routes/voice.js +75 -0
- package/dist/src/gateway/hono/routes/voice.js.map +1 -1
- package/dist/src/gateway/hono/routes/workflows.d.ts +3 -0
- package/dist/src/gateway/hono/routes/workflows.js +347 -0
- package/dist/src/gateway/hono/routes/workflows.js.map +1 -0
- package/dist/src/gateway/hono/routes/workspace.js +4 -4
- package/dist/src/gateway/hono/sse.js +16 -33
- package/dist/src/gateway/hono/sse.js.map +1 -1
- package/dist/src/gateway/lock.js +11 -11
- package/dist/src/gateway/lock.js.map +1 -1
- package/dist/src/gateway/ports.js +6 -6
- package/dist/src/gateway/ports.js.map +1 -1
- package/dist/src/gateway/resolve-webchat-session-key.d.ts +19 -0
- package/dist/src/gateway/resolve-webchat-session-key.js +46 -0
- package/dist/src/gateway/resolve-webchat-session-key.js.map +1 -0
- package/dist/src/gateway/service/agent-runner.js +2 -2
- package/dist/src/gateway/service/marketplace-service.js +2 -2
- package/dist/src/gateway/service/run-gateway-agent.js +9 -11
- package/dist/src/gateway/service/run-gateway-agent.js.map +1 -1
- package/dist/src/gateway/service/sessions-api.d.ts +3 -0
- package/dist/src/gateway/service/sessions-api.js +8 -0
- package/dist/src/gateway/service/sessions-api.js.map +1 -1
- package/dist/src/gateway/service.d.ts +3 -2
- package/dist/src/gateway/service.js +9 -8
- package/dist/src/gateway/service.js.map +1 -1
- package/dist/src/gateway/session-reset-service.d.ts +20 -0
- package/dist/src/gateway/session-reset-service.js +54 -0
- package/dist/src/gateway/session-reset-service.js.map +1 -0
- package/dist/src/gateway/startup-readiness.d.ts +1 -1
- package/dist/src/gateway/startup-readiness.js +1 -0
- package/dist/src/gateway/startup-readiness.js.map +1 -1
- package/dist/src/gateway/workspace-fs-file-list.js +1 -1
- package/dist/src/heartbeat/index.js +1 -1
- package/dist/src/infra/gateway-processes.js +2 -2
- package/dist/src/infra/gateway-processes.js.map +1 -1
- package/dist/src/infra/restart.js +2 -2
- package/dist/src/infra/run-command.d.ts +16 -0
- package/dist/src/infra/run-command.js +67 -0
- package/dist/src/infra/run-command.js.map +1 -0
- package/dist/src/infra/update-check.js +1 -1
- package/dist/src/infra/update-global.d.ts +45 -0
- package/dist/src/infra/update-global.js +224 -0
- package/dist/src/infra/update-global.js.map +1 -0
- package/dist/src/infra/update-lock.js +3 -3
- package/dist/src/infra/update-runner.js +1 -1
- package/dist/src/infra/update-startup.js +2 -2
- package/dist/src/infra/write-file-atomic.js +2 -2
- package/dist/src/mcp/channel-shared.js +2 -1
- package/dist/src/mcp/channel-shared.js.map +1 -1
- package/dist/src/providers/auth-runtime/auth-profile-store.js +2 -2
- package/dist/src/providers/auth-runtime/auth-profile-store.js.map +1 -1
- package/dist/src/providers/auth-runtime/resolve-auth.js +1 -12
- package/dist/src/providers/auth-runtime/resolve-auth.js.map +1 -1
- package/dist/src/providers/auth-runtime/types.d.ts +6 -12
- package/dist/src/providers/index.js +2 -2
- package/dist/src/providers/model-registry.js +1 -1
- package/dist/src/routing/agent-session-key.d.ts +58 -0
- package/dist/src/routing/agent-session-key.js +164 -0
- package/dist/src/routing/agent-session-key.js.map +1 -0
- package/dist/src/routing/index.d.ts +1 -1
- package/dist/src/routing/index.js +4 -2
- package/dist/src/routing/index.js.map +1 -1
- package/dist/src/routing/resolve-route.d.ts +15 -0
- package/dist/src/routing/resolve-route.js +41 -20
- package/dist/src/routing/resolve-route.js.map +1 -1
- package/dist/src/routing/resolve-tui-session-key.d.ts +25 -0
- package/dist/src/routing/resolve-tui-session-key.js +54 -0
- package/dist/src/routing/resolve-tui-session-key.js.map +1 -0
- package/dist/src/routing/session-key-utils.d.ts +24 -0
- package/dist/src/routing/session-key-utils.js +92 -0
- package/dist/src/routing/session-key-utils.js.map +1 -0
- package/dist/src/routing/session-key.d.ts +19 -49
- package/dist/src/routing/session-key.js +143 -116
- package/dist/src/routing/session-key.js.map +1 -1
- package/dist/src/session/config-store.js +2 -2
- package/dist/src/session/index.d.ts +6 -0
- package/dist/src/session/index.js +7 -1
- package/dist/src/session/init-session-turn.d.ts +30 -0
- package/dist/src/session/init-session-turn.js +102 -0
- package/dist/src/session/init-session-turn.js.map +1 -0
- package/dist/src/session/lifecycle-timestamps.d.ts +8 -0
- package/dist/src/session/lifecycle-timestamps.js +16 -0
- package/dist/src/session/lifecycle-timestamps.js.map +1 -0
- package/dist/src/session/manager.d.ts +7 -1
- package/dist/src/session/manager.js +8 -1
- package/dist/src/session/manager.js.map +1 -1
- package/dist/src/session/parity/jsonl-transcript-io.js +2 -2
- package/dist/src/session/parity/sessions-json-file.js +1 -1
- package/dist/src/session/parity/transcript-file-lock.js +2 -2
- package/dist/src/session/parity/transcript-paths.js +2 -2
- package/dist/src/session/parity/transcript-paths.js.map +1 -1
- package/dist/src/session/parity/xopc-session-disk-entry.d.ts +6 -0
- package/dist/src/session/reset-policy.d.ts +32 -0
- package/dist/src/session/reset-policy.js +65 -0
- package/dist/src/session/reset-policy.js.map +1 -0
- package/dist/src/session/reset-triggers.d.ts +20 -0
- package/dist/src/session/reset-triggers.js +63 -0
- package/dist/src/session/reset-triggers.js.map +1 -0
- package/dist/src/session/reset-type.d.ts +12 -0
- package/dist/src/session/reset-type.js +25 -0
- package/dist/src/session/reset-type.js.map +1 -0
- package/dist/src/session/resolve-session.d.ts +30 -0
- package/dist/src/session/resolve-session.js +93 -0
- package/dist/src/session/resolve-session.js.map +1 -0
- package/dist/src/session/search-index-cache.js +1 -1
- package/dist/src/session/search-index.js +1 -1
- package/dist/src/session/session-title.js +3 -2
- package/dist/src/session/session-title.js.map +1 -1
- package/dist/src/session/store.d.ts +11 -4
- package/dist/src/session/store.js +62 -11
- package/dist/src/session/store.js.map +1 -1
- package/dist/src/session/transcript-events.js +2 -1
- package/dist/src/session/transcript-events.js.map +1 -1
- package/dist/src/share/share-auto.js +2 -2
- package/dist/src/share/share-store.js +3 -3
- package/dist/src/share/share-thumbnail.js +2 -2
- package/dist/src/share/share-url.d.ts +33 -0
- package/dist/src/share/share-url.js +56 -14
- package/dist/src/share/share-url.js.map +1 -1
- package/dist/src/share/share-zip.js +1 -1
- package/dist/src/share/site-share-store.js +3 -3
- package/dist/src/share/site-static-serve.js +1 -1
- package/dist/src/tui/backends/embedded-backend.js +4 -9
- package/dist/src/tui/backends/embedded-backend.js.map +1 -1
- package/dist/src/tui/backends/gateway-sse-backend.js +1 -1
- package/dist/src/tui/backends/gateway-sse-backend.js.map +1 -1
- package/dist/src/tui/clipboard-image.js +3 -3
- package/dist/src/tui/components/chat-log.js +3 -3
- package/dist/src/tui/components/chat-log.js.map +1 -1
- package/dist/src/tui/theme-manager.js +1 -1
- package/dist/src/tui/theme.d.ts +0 -2
- package/dist/src/tui/theme.js +1 -3
- package/dist/src/tui/theme.js.map +1 -1
- package/dist/src/tui/tui-agent-events.js +2 -1
- package/dist/src/tui/tui-agent-events.js.map +1 -1
- package/dist/src/tui/tui-commands.d.ts +3 -0
- package/dist/src/tui/tui-commands.js +45 -10
- package/dist/src/tui/tui-commands.js.map +1 -1
- package/dist/src/tui/tui-keybindings-file.js +2 -22
- package/dist/src/tui/tui-keybindings-file.js.map +1 -1
- package/dist/src/tui/tui-scoped-models.js +2 -2
- package/dist/src/tui/tui-session-actions.d.ts +28 -0
- package/dist/src/tui/tui-session-actions.js +88 -0
- package/dist/src/tui/tui-session-actions.js.map +1 -0
- package/dist/src/tui/tui-settings.js +1 -1
- package/dist/src/tui/tui.js +54 -49
- package/dist/src/tui/tui.js.map +1 -1
- package/dist/src/tunnel/frpc-binary.js +3 -3
- package/dist/src/tunnel/frpc-config.js +1 -1
- package/dist/src/tunnel/frpc-extract.js +1 -1
- package/dist/src/tunnel/tunnel-state.js +1 -1
- package/dist/src/utils/logger/audit.js +1 -1
- package/dist/src/utils/logger/log-store.js +1 -1
- package/dist/src/utils/logger/rotation.js +1 -1
- package/dist/src/utils/string-coerce.d.ts +2 -0
- package/dist/src/utils/string-coerce.js +10 -1
- package/dist/src/utils/string-coerce.js.map +1 -1
- package/dist/src/voice/metadata/builtin.d.ts +2 -0
- package/dist/src/voice/metadata/builtin.js +420 -0
- package/dist/src/voice/metadata/builtin.js.map +1 -0
- package/dist/src/voice/metadata/index.d.ts +4 -0
- package/dist/src/voice/metadata/index.js +3 -0
- package/dist/src/voice/metadata/registry.d.ts +5 -0
- package/dist/src/voice/metadata/registry.js +34 -0
- package/dist/src/voice/metadata/registry.js.map +1 -0
- package/dist/src/voice/metadata/types.d.ts +41 -0
- package/dist/src/voice/metadata/types.js +1 -0
- package/dist/src/voice/stt/config-slice.d.ts +2 -5
- package/dist/src/voice/stt/config-slice.js +5 -26
- package/dist/src/voice/stt/config-slice.js.map +1 -1
- package/dist/src/voice/stt/list-providers.d.ts +3 -3
- package/dist/src/voice/stt/list-providers.js +41 -6
- package/dist/src/voice/stt/list-providers.js.map +1 -1
- package/dist/src/voice/stt/types.d.ts +1 -18
- package/dist/src/voice/stt/types.js +4 -2
- package/dist/src/voice/stt/types.js.map +1 -1
- package/dist/src/voice/tts/audio.js +1 -1
- package/dist/src/voice/tts/config-slice.d.ts +3 -7
- package/dist/src/voice/tts/config-slice.js +7 -38
- package/dist/src/voice/tts/config-slice.js.map +1 -1
- package/dist/src/voice/tts/list-providers.d.ts +3 -3
- package/dist/src/voice/tts/list-providers.js +41 -6
- package/dist/src/voice/tts/list-providers.js.map +1 -1
- package/dist/src/voice/tts/merge-config.js +2 -48
- package/dist/src/voice/tts/merge-config.js.map +1 -1
- package/dist/src/voice/tts/providers/alibaba-speech.js +1 -1
- package/dist/src/voice/tts/providers/alibaba-speech.js.map +1 -1
- package/dist/src/voice/tts/providers/edge-speech.js +2 -2
- package/dist/src/voice/tts/types.d.ts +1 -29
- package/dist/src/voice/tts/types.js +19 -17
- package/dist/src/voice/tts/types.js.map +1 -1
- package/dist/src/workflows/domain/command.d.ts +18 -0
- package/dist/src/workflows/domain/command.js +1 -0
- package/dist/src/workflows/domain/definition.d.ts +62 -0
- package/dist/src/workflows/domain/definition.js +1 -0
- package/dist/src/workflows/domain/event.d.ts +67 -0
- package/dist/src/workflows/domain/event.js +1 -0
- package/dist/src/workflows/domain/index.d.ts +5 -0
- package/dist/src/workflows/domain/index.js +2 -0
- package/dist/src/workflows/domain/result.d.ts +65 -0
- package/dist/src/workflows/domain/result.js +1 -0
- package/dist/src/workflows/domain/run.d.ts +120 -0
- package/dist/src/workflows/domain/run.js +14 -0
- package/dist/src/workflows/domain/run.js.map +1 -0
- package/dist/src/workflows/engine/index.d.ts +2 -0
- package/dist/src/workflows/engine/index.js +3 -0
- package/dist/src/workflows/engine/projector.d.ts +3 -0
- package/dist/src/workflows/engine/projector.js +205 -0
- package/dist/src/workflows/engine/projector.js.map +1 -0
- package/dist/src/workflows/engine/workflow-engine.d.ts +31 -0
- package/dist/src/workflows/engine/workflow-engine.js +188 -0
- package/dist/src/workflows/engine/workflow-engine.js.map +1 -0
- package/dist/src/workflows/index.d.ts +6 -0
- package/dist/src/workflows/index.js +11 -0
- package/dist/src/workflows/runtime/index.d.ts +1 -0
- package/dist/src/workflows/runtime/index.js +4 -0
- package/dist/src/workflows/runtime/script-runtime.d.ts +3 -0
- package/dist/src/workflows/runtime/script-runtime.js +3 -0
- package/dist/src/workflows/store/event-store.d.ts +17 -0
- package/dist/src/workflows/store/event-store.js +83 -0
- package/dist/src/workflows/store/event-store.js.map +1 -0
- package/dist/src/workflows/store/paths.d.ts +7 -0
- package/dist/src/workflows/store/paths.js +26 -0
- package/dist/src/workflows/store/paths.js.map +1 -0
- package/dist/src/workflows/store/run-store.d.ts +13 -0
- package/dist/src/workflows/store/run-store.js +68 -0
- package/dist/src/workflows/store/run-store.js.map +1 -0
- package/package.json +5 -8
- package/dist/gateway/static/root/assets/agents-mS3_HpRI.js +0 -222
- package/dist/gateway/static/root/assets/channels-settings-BG6b9KrW.js +0 -1
- package/dist/gateway/static/root/assets/extension-settings-page-B-W4x2xP.js +0 -1
- package/dist/gateway/static/root/assets/index-ew_2L2We.css +0 -1
- package/dist/gateway/static/root/assets/sessions-page-FaG_Vlkb.js +0 -1
- package/dist/gateway/static/root/assets/settings-page-Bet1OerL.js +0 -3
- package/dist/gateway/static/root/assets/skills-page-DhUO235y.js +0 -2
- package/dist/gateway/static/root/assets/url-BwNL6Rgk.js +0 -3
- package/dist/gateway/static/root/assets/voice-api-key-field-CGEydndO.js +0 -1
- package/dist/src/agent/tools/browser-legacy-tools.d.ts +0 -17
- package/dist/src/agent/tools/browser-legacy-tools.js +0 -766
- package/dist/src/agent/tools/browser-legacy-tools.js.map +0 -1
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
//#region src/agent/workflow/builtins/release-check.ts
|
|
2
|
+
/**
|
|
3
|
+
* Built-in workflow: `release_check`
|
|
4
|
+
*
|
|
5
|
+
* Runs a release-readiness review for a finished change. It inspects the diff,
|
|
6
|
+
* validates risk areas in parallel, and produces a go/no-go checklist.
|
|
7
|
+
*
|
|
8
|
+
* Args:
|
|
9
|
+
* - target: release candidate, branch, commit range, or feature summary
|
|
10
|
+
* - checks: optional subset of check keys
|
|
11
|
+
*/
|
|
12
|
+
const RELEASE_CHECK_SCRIPT = `export const meta = {
|
|
13
|
+
name: 'release_check',
|
|
14
|
+
description: 'Assess whether a change is ready to release with parallel risk checks and a go/no-go verdict.',
|
|
15
|
+
whenToUse: 'User is near the end of implementation and wants a release-quality readiness check before shipping.',
|
|
16
|
+
examplePrompts: [
|
|
17
|
+
{ field: 'target', text: 'Is this repo ready to release v1.2?' },
|
|
18
|
+
{ field: 'target', text: 'Pre-release readiness check for the current branch' },
|
|
19
|
+
],
|
|
20
|
+
i18n: {
|
|
21
|
+
zh: {
|
|
22
|
+
description: '并行检查发布风险,判断变更是否达到可发布标准。',
|
|
23
|
+
whenToUse: '用户接近开发尾声,想在发布前做发布质量/就绪检查时。',
|
|
24
|
+
examplePrompts: [
|
|
25
|
+
{ field: 'target', text: '这个仓库是否准备好发布 v1.2?' },
|
|
26
|
+
{ field: 'target', text: '对当前分支做发布前就绪检查' },
|
|
27
|
+
],
|
|
28
|
+
},
|
|
29
|
+
},
|
|
30
|
+
tags: ['release', 'quality', 'validation'],
|
|
31
|
+
estimatedAgents: { min: 6, max: 7 },
|
|
32
|
+
phases: [
|
|
33
|
+
{ title: 'Scope' },
|
|
34
|
+
{ title: 'Checks' },
|
|
35
|
+
{ title: 'Verdict' },
|
|
36
|
+
],
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
const READ_ONLY_TOOLS = ['read_file', 'grep', 'find', 'list_dir', 'shell']
|
|
40
|
+
|
|
41
|
+
const target = args && typeof args === 'object' && args.target
|
|
42
|
+
? String(args.target)
|
|
43
|
+
: 'Current working tree or release candidate from the conversation context.'
|
|
44
|
+
|
|
45
|
+
const ALL_CHECKS = [
|
|
46
|
+
{ key: 'regression', focus: 'Behavior changes, compatibility breaks, edge cases, and accidental scope creep.' },
|
|
47
|
+
{ key: 'tests', focus: 'Relevant automated tests, missing regression cases, flaky or weak assertions, and manual coverage gaps.' },
|
|
48
|
+
{ key: 'build', focus: 'Typecheck, lint, build, packaging, lazy imports, generated assets, and dependency correctness.' },
|
|
49
|
+
{ key: 'security', focus: 'Secrets, auth/authz, input validation, unsafe shell/file/network access, and data exposure.' },
|
|
50
|
+
{ key: 'ops', focus: 'Logging, observability, migrations, persistence, rollback, failure modes, and supportability.' },
|
|
51
|
+
]
|
|
52
|
+
|
|
53
|
+
let checks = ALL_CHECKS
|
|
54
|
+
if (args && typeof args === 'object' && Array.isArray(args.checks) && args.checks.length) {
|
|
55
|
+
const selected = new Set(args.checks.map((check) => String(check)))
|
|
56
|
+
checks = ALL_CHECKS.filter((check) => selected.has(check.key))
|
|
57
|
+
if (!checks.length) checks = ALL_CHECKS
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
phase('Scope')
|
|
61
|
+
const scope = await agent(
|
|
62
|
+
'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' +
|
|
63
|
+
'TARGET:\\n' + target,
|
|
64
|
+
{
|
|
65
|
+
label: 'release scope',
|
|
66
|
+
toolset: READ_ONLY_TOOLS,
|
|
67
|
+
schema: {
|
|
68
|
+
type: 'object',
|
|
69
|
+
properties: {
|
|
70
|
+
changedAreas: { type: 'array', items: { type: 'string' } },
|
|
71
|
+
userVisibleChanges: { type: 'array', items: { type: 'string' } },
|
|
72
|
+
blastRadius: { type: 'string' },
|
|
73
|
+
},
|
|
74
|
+
required: ['changedAreas', 'blastRadius'],
|
|
75
|
+
},
|
|
76
|
+
},
|
|
77
|
+
)
|
|
78
|
+
|
|
79
|
+
phase('Checks')
|
|
80
|
+
const reports = await parallel(
|
|
81
|
+
checks.map((check) => () =>
|
|
82
|
+
agent(
|
|
83
|
+
'Run a release-readiness check through the ' + check.key + ' lens.\\n' +
|
|
84
|
+
'Focus: ' + check.focus + '\\n\\n' +
|
|
85
|
+
'TARGET:\\n' + target + '\\n\\n' +
|
|
86
|
+
'SCOPE:\\n' + JSON.stringify(scope, null, 2) + '\\n\\n' +
|
|
87
|
+
'Return blockers, warnings, evidence, and concrete fixes. Prefer specific files/commands over generic statements.',
|
|
88
|
+
{
|
|
89
|
+
label: check.key + ' check',
|
|
90
|
+
toolset: READ_ONLY_TOOLS,
|
|
91
|
+
schema: {
|
|
92
|
+
type: 'object',
|
|
93
|
+
properties: {
|
|
94
|
+
blockers: {
|
|
95
|
+
type: 'array',
|
|
96
|
+
items: {
|
|
97
|
+
type: 'object',
|
|
98
|
+
properties: {
|
|
99
|
+
title: { type: 'string' },
|
|
100
|
+
evidence: { type: 'string' },
|
|
101
|
+
fix: { type: 'string' },
|
|
102
|
+
},
|
|
103
|
+
required: ['title', 'evidence', 'fix'],
|
|
104
|
+
},
|
|
105
|
+
},
|
|
106
|
+
warnings: {
|
|
107
|
+
type: 'array',
|
|
108
|
+
items: {
|
|
109
|
+
type: 'object',
|
|
110
|
+
properties: {
|
|
111
|
+
title: { type: 'string' },
|
|
112
|
+
evidence: { type: 'string' },
|
|
113
|
+
fix: { type: 'string' },
|
|
114
|
+
},
|
|
115
|
+
required: ['title', 'evidence'],
|
|
116
|
+
},
|
|
117
|
+
},
|
|
118
|
+
recommendedCommands: { type: 'array', items: { type: 'string' } },
|
|
119
|
+
},
|
|
120
|
+
required: ['blockers', 'warnings'],
|
|
121
|
+
},
|
|
122
|
+
},
|
|
123
|
+
),
|
|
124
|
+
),
|
|
125
|
+
)
|
|
126
|
+
|
|
127
|
+
phase('Verdict')
|
|
128
|
+
const byCheck = {}
|
|
129
|
+
for (let i = 0; i < checks.length; i++) {
|
|
130
|
+
byCheck[checks[i].key] = reports[i] ?? { blockers: [], warnings: [], recommendedCommands: [] }
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
const verdict = await agent(
|
|
134
|
+
'Synthesize a release go/no-go verdict. Block if any credible blocker remains. If not blocked, distinguish ship_now from ship_after_checks. ' +
|
|
135
|
+
'Deduplicate issues and produce the shortest checklist that would make this release safe.\\n\\n' +
|
|
136
|
+
JSON.stringify({ target, scope, byCheck }, null, 2),
|
|
137
|
+
{
|
|
138
|
+
label: 'release verdict',
|
|
139
|
+
schema: {
|
|
140
|
+
type: 'object',
|
|
141
|
+
properties: {
|
|
142
|
+
recommendation: { type: 'string', enum: ['ship_now', 'ship_after_checks', 'block'] },
|
|
143
|
+
summary: { type: 'string' },
|
|
144
|
+
blockers: { type: 'array', items: { type: 'string' } },
|
|
145
|
+
finalChecklist: { type: 'array', items: { type: 'string' } },
|
|
146
|
+
commandsToRun: { type: 'array', items: { type: 'string' } },
|
|
147
|
+
},
|
|
148
|
+
required: ['recommendation', 'summary', 'blockers', 'finalChecklist'],
|
|
149
|
+
},
|
|
150
|
+
},
|
|
151
|
+
)
|
|
152
|
+
|
|
153
|
+
return {
|
|
154
|
+
ok: true,
|
|
155
|
+
target,
|
|
156
|
+
checks: checks.map((check) => check.key),
|
|
157
|
+
scope,
|
|
158
|
+
...(verdict ?? { recommendation: 'ship_after_checks', summary: 'verdict failed', blockers: [], finalChecklist: [] }),
|
|
159
|
+
byCheck,
|
|
160
|
+
}
|
|
161
|
+
`;
|
|
162
|
+
//#endregion
|
|
163
|
+
export { RELEASE_CHECK_SCRIPT };
|
|
164
|
+
|
|
165
|
+
//# sourceMappingURL=release-check.js.map
|
|
@@ -0,0 +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\nreturn {\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}\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 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 return { ok: false, reason: 'framing failed', question, depth }\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\nreturn {\n ok: true,\n question,\n depth,\n angleCount: angles.length,\n ...(synthesis ?? { executiveSummary: 'synthesis failed', topFindings: [], contradictions: [] }),\n}\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 return { ok: false, reason: 'framing failed', question, depth }\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\nreturn {\n ok: true,\n question,\n depth,\n angleCount: angles.length,\n ...(synthesis ?? { executiveSummary: 'synthesis failed', topFindings: [], contradictions: [] }),\n}\n";
|
|
@@ -15,6 +15,20 @@ const RESEARCH_SCRIPT = `export const meta = {
|
|
|
15
15
|
name: 'research',
|
|
16
16
|
description: 'Multi-angle research on a question with parallel exploration and a cited synthesis.',
|
|
17
17
|
whenToUse: 'User asks a non-trivial research question that benefits from multiple search angles or source reads.',
|
|
18
|
+
examplePrompts: [
|
|
19
|
+
{ field: 'question', text: 'Compare Bun vs Node startup performance' },
|
|
20
|
+
{ field: 'question', text: 'What are the trade-offs of SQLite vs Postgres for this app?' },
|
|
21
|
+
],
|
|
22
|
+
i18n: {
|
|
23
|
+
zh: {
|
|
24
|
+
description: '多角度并行调研一个问题,并产出带引用的综合报告。',
|
|
25
|
+
whenToUse: '用户提出需要多角度检索、阅读来源的非平凡调研问题时。',
|
|
26
|
+
examplePrompts: [
|
|
27
|
+
{ field: 'question', text: '比较 Bun 与 Node 的启动性能' },
|
|
28
|
+
{ field: 'question', text: '这个应用用 SQLite 还是 Postgres 各有什么权衡?' },
|
|
29
|
+
],
|
|
30
|
+
},
|
|
31
|
+
},
|
|
18
32
|
tags: ['research', 'investigation'],
|
|
19
33
|
estimatedAgents: { min: 4, max: 8 },
|
|
20
34
|
phases: [
|
|
@@ -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 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 return { ok: false, reason: 'framing failed', question, depth }\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\nreturn {\n ok: true,\n question,\n depth,\n angleCount: angles.length,\n ...(synthesis ?? { executiveSummary: 'synthesis failed', topFindings: [], contradictions: [] }),\n}\n`\n"],"mappings":";;;;;;;;;;;;;AAaA,MAAa,kBAAkB"}
|
|
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 return { ok: false, reason: 'framing failed', question, depth }\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\nreturn {\n ok: true,\n question,\n depth,\n angleCount: angles.length,\n ...(synthesis ?? { executiveSummary: 'synthesis failed', topFindings: [], contradictions: [] }),\n}\n`\n"],"mappings":";;;;;;;;;;;;;AAaA,MAAa,kBAAkB"}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { init_paths_state, resolveStateDir } from "../../config/paths-state.js";
|
|
2
2
|
import { BUILTIN_WORKFLOWS } from "./builtins/index.js";
|
|
3
3
|
import { parseWorkflowScript } from "./parser.js";
|
|
4
|
-
import { join } from "node:path";
|
|
5
4
|
import { existsSync, mkdirSync, readFileSync, readdirSync, statSync, unlinkSync, writeFileSync } from "node:fs";
|
|
5
|
+
import { join } from "node:path";
|
|
6
6
|
//#region src/agent/workflow/catalog.ts
|
|
7
7
|
/**
|
|
8
8
|
* Catalog for named workflows.
|
|
@@ -42,9 +42,9 @@ export interface WorkflowProgressPostInput {
|
|
|
42
42
|
* prefixes mid-run `append` messages with "▾ progress" so the user can tell
|
|
43
43
|
* them apart from the final summary).
|
|
44
44
|
*
|
|
45
|
-
* Optional
|
|
46
|
-
*
|
|
47
|
-
*
|
|
45
|
+
* Optional only to keep hand-rolled callers and unit-test stubs lean — the
|
|
46
|
+
* broker always provides it. Capabilities that consume the field should
|
|
47
|
+
* default to `'edit'` when missing.
|
|
48
48
|
*/
|
|
49
49
|
mode?: WorkflowProgressMode;
|
|
50
50
|
}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
export { applySubagentProgress } from './agent-progress.js';
|
|
1
2
|
export { BUILTIN_WORKFLOWS, type BuiltinWorkflow } from './builtins/index.js';
|
|
2
3
|
export { createWorkflowCatalog, defaultUserDir, type CatalogEntry, type LoadedWorkflow, type WorkflowCatalog, type WorkflowSource, } from './catalog.js';
|
|
3
4
|
export { getLastWorkflowMemory, _resetLastWorkflowMemoryForTests, type LastWorkflowEntry, type LastWorkflowMemory, } from './last-run-memory.js';
|
|
@@ -8,4 +9,4 @@ export { emptySnapshotFor, runWorkflow, type RunWorkflowDeps, } from './runtime.
|
|
|
8
9
|
export { createWorkflowSnapshot, previewValue, recomputeCounts, renderWorkflowText, type RenderOptions, } from './snapshot.js';
|
|
9
10
|
export { createStructuredOutputTool, STRUCTURED_OUTPUT_TOOL_NAME, type CreateStructuredOutputToolOptions, type StructuredOutputCapture, } from './structured-output-tool.js';
|
|
10
11
|
export { DelegateSubagentRunner, type DelegateSubagentRunnerDeps, } from './subagent-runner.js';
|
|
11
|
-
export type { AgentScriptOptions, JsonSchema, SubagentRunner, SubagentRunOptions, WorkflowAgentSnapshot, WorkflowAgentStatus, WorkflowMeta, WorkflowMetaEstimatedAgents, WorkflowMetaPhase, WorkflowRunOptions, WorkflowRunResult, WorkflowSnapshot, } from './types.js';
|
|
12
|
+
export type { AgentScriptOptions, JsonSchema, SubagentRunner, SubagentRunOptions, SubagentProgressEvent, WorkflowAgentSnapshot, WorkflowAgentStatus, WorkflowAgentStep, WorkflowMeta, WorkflowMetaEstimatedAgents, WorkflowMetaPhase, WorkflowRunOptions, WorkflowRunResult, WorkflowSnapshot, } from './types.js';
|
|
@@ -1,10 +1,11 @@
|
|
|
1
|
+
import { applySubagentProgress } from "./agent-progress.js";
|
|
1
2
|
import { BUILTIN_WORKFLOWS } from "./builtins/index.js";
|
|
2
3
|
import { parseWorkflowScript } from "./parser.js";
|
|
3
4
|
import { createWorkflowCatalog, defaultUserDir } from "./catalog.js";
|
|
4
5
|
import { _resetLastWorkflowMemoryForTests, getLastWorkflowMemory } from "./last-run-memory.js";
|
|
6
|
+
import { emptySnapshotFor, runWorkflow } from "./runtime.js";
|
|
5
7
|
import { createWorkflowSnapshot, previewValue, recomputeCounts, renderWorkflowText } from "./snapshot.js";
|
|
6
8
|
import { WorkflowProgressBroker, _resetWorkflowProgressBrokerForTests, getWorkflowProgressBroker } from "./progress-broker.js";
|
|
7
|
-
import { emptySnapshotFor, runWorkflow } from "./runtime.js";
|
|
8
9
|
import { STRUCTURED_OUTPUT_TOOL_NAME, createStructuredOutputTool } from "./structured-output-tool.js";
|
|
9
10
|
import { DelegateSubagentRunner } from "./subagent-runner.js";
|
|
10
|
-
export { BUILTIN_WORKFLOWS, DelegateSubagentRunner, STRUCTURED_OUTPUT_TOOL_NAME, WorkflowProgressBroker, _resetLastWorkflowMemoryForTests, _resetWorkflowProgressBrokerForTests, createStructuredOutputTool, createWorkflowCatalog, createWorkflowSnapshot, defaultUserDir, emptySnapshotFor, getLastWorkflowMemory, getWorkflowProgressBroker, parseWorkflowScript, previewValue, recomputeCounts, renderWorkflowText, runWorkflow };
|
|
11
|
+
export { BUILTIN_WORKFLOWS, DelegateSubagentRunner, STRUCTURED_OUTPUT_TOOL_NAME, WorkflowProgressBroker, _resetLastWorkflowMemoryForTests, _resetWorkflowProgressBrokerForTests, applySubagentProgress, createStructuredOutputTool, createWorkflowCatalog, createWorkflowSnapshot, defaultUserDir, emptySnapshotFor, getLastWorkflowMemory, getWorkflowProgressBroker, parseWorkflowScript, previewValue, recomputeCounts, renderWorkflowText, runWorkflow };
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Static lint for workflow scripts.
|
|
3
|
+
*
|
|
4
|
+
* Catches the single most common AI-authoring bug: calling `agent()`,
|
|
5
|
+
* `parallel()`, or `pipeline()` without `await` and then using the returned
|
|
6
|
+
* Promise as if it were a value. The runtime would throw a cryptic TypeError
|
|
7
|
+
* like `results.map is not a function`; this lint converts it into an
|
|
8
|
+
* actionable error before the script ever runs.
|
|
9
|
+
*
|
|
10
|
+
* Rules (per matching CallExpression):
|
|
11
|
+
* Allowed parents
|
|
12
|
+
* - AwaitExpression argument `await parallel(...)`
|
|
13
|
+
* - ReturnStatement argument `return agent(...)` (auto-unwraps)
|
|
14
|
+
* - ExpressionStatement fire-and-forget; pending agents drain
|
|
15
|
+
* - ArrowFunctionExpression expression body `() => agent(...)` (thunk for parallel/pipeline)
|
|
16
|
+
* Anything else (VariableDeclarator init, MemberExpression object, template
|
|
17
|
+
* interpolation, binary/logical operand, call argument, property/array
|
|
18
|
+
* element, ...) is rejected with a teaching message.
|
|
19
|
+
*
|
|
20
|
+
* Out of scope (handled by the runtime):
|
|
21
|
+
* - `parallel([agent(...), agent(...)])` (promises instead of thunks) — caught
|
|
22
|
+
* by the runtime's TypeError ("expects an array of functions, not promises").
|
|
23
|
+
* - Promise-as-value bugs that survive lint (dynamic indirection, late await).
|
|
24
|
+
*/
|
|
25
|
+
import type { Node } from 'acorn';
|
|
26
|
+
type AnyNode = Node & {
|
|
27
|
+
[key: string]: any;
|
|
28
|
+
start: number;
|
|
29
|
+
end: number;
|
|
30
|
+
loc?: {
|
|
31
|
+
start: {
|
|
32
|
+
line: number;
|
|
33
|
+
column: number;
|
|
34
|
+
};
|
|
35
|
+
};
|
|
36
|
+
};
|
|
37
|
+
export declare function lintAwaits(ast: AnyNode): void;
|
|
38
|
+
export {};
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
//#region src/agent/workflow/lint.ts
|
|
2
|
+
const LINT_TARGETS = new Set([
|
|
3
|
+
"agent",
|
|
4
|
+
"parallel",
|
|
5
|
+
"pipeline"
|
|
6
|
+
]);
|
|
7
|
+
function lintAwaits(ast) {
|
|
8
|
+
walk(ast, null, (node, parent) => {
|
|
9
|
+
if (!isLintTarget(node)) return;
|
|
10
|
+
if (isAcceptableParent(parent, node)) return;
|
|
11
|
+
const calleeName = node.callee.name;
|
|
12
|
+
const line = node.loc?.start.line ?? "?";
|
|
13
|
+
throw new Error(formatError(calleeName, line, parent));
|
|
14
|
+
});
|
|
15
|
+
}
|
|
16
|
+
function isLintTarget(node) {
|
|
17
|
+
if (node.type !== "CallExpression") return false;
|
|
18
|
+
const callee = node.callee;
|
|
19
|
+
if (!callee || callee.type !== "Identifier") return false;
|
|
20
|
+
return LINT_TARGETS.has(callee.name);
|
|
21
|
+
}
|
|
22
|
+
function isAcceptableParent(parent, call) {
|
|
23
|
+
if (!parent) return false;
|
|
24
|
+
switch (parent.type) {
|
|
25
|
+
case "AwaitExpression": return parent.argument === call;
|
|
26
|
+
case "ReturnStatement": return parent.argument === call;
|
|
27
|
+
case "ExpressionStatement": return parent.expression === call;
|
|
28
|
+
case "ArrowFunctionExpression": return parent.expression === true && parent.body === call;
|
|
29
|
+
default: return false;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
function formatError(name, line, parent) {
|
|
33
|
+
const ctx = parentContextHint(parent);
|
|
34
|
+
return [
|
|
35
|
+
`workflow lint error at line ${line}: \`${name}(...)\` returns a Promise but is used without 'await'${ctx ? ` (${ctx})` : ""}.`,
|
|
36
|
+
` ❌ const x = ${name}(...); x.map(...)`,
|
|
37
|
+
` ✅ const x = await ${name}(...); x.map(...)`,
|
|
38
|
+
`Workflow scripts run in an async IIFE — 'await' parallel()/pipeline()/agent() before using their results, or 'return' them directly.`
|
|
39
|
+
].join("\n");
|
|
40
|
+
}
|
|
41
|
+
function parentContextHint(parent) {
|
|
42
|
+
if (!parent) return "";
|
|
43
|
+
switch (parent.type) {
|
|
44
|
+
case "VariableDeclarator": return "assigned to variable";
|
|
45
|
+
case "AssignmentExpression": return "assigned via =";
|
|
46
|
+
case "MemberExpression": return "method/property access on Promise";
|
|
47
|
+
case "TemplateLiteral": return "interpolated in template string";
|
|
48
|
+
case "BinaryExpression":
|
|
49
|
+
case "LogicalExpression": return "used in expression";
|
|
50
|
+
case "ConditionalExpression": return "used as ternary operand";
|
|
51
|
+
case "CallExpression": return "passed as argument";
|
|
52
|
+
case "Property": return "used as object property value";
|
|
53
|
+
case "ArrayExpression": return "placed in array (use a thunk: () => call)";
|
|
54
|
+
case "SpreadElement": return "spread";
|
|
55
|
+
case "IfStatement":
|
|
56
|
+
case "WhileStatement":
|
|
57
|
+
case "DoWhileStatement":
|
|
58
|
+
case "ForStatement": return "used as condition";
|
|
59
|
+
default: return parent.type;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
function walk(node, parent, visit) {
|
|
63
|
+
visit(node, parent);
|
|
64
|
+
for (const value of Object.values(node)) if (Array.isArray(value)) {
|
|
65
|
+
for (const v of value) if (isAstNode(v)) walk(v, node, visit);
|
|
66
|
+
} else if (isAstNode(value)) walk(value, node, visit);
|
|
67
|
+
}
|
|
68
|
+
function isAstNode(value) {
|
|
69
|
+
return !!value && typeof value === "object" && typeof value.type === "string";
|
|
70
|
+
}
|
|
71
|
+
//#endregion
|
|
72
|
+
export { lintAwaits };
|
|
73
|
+
|
|
74
|
+
//# sourceMappingURL=lint.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lint.js","names":[],"sources":["../../../../src/agent/workflow/lint.ts"],"sourcesContent":["/**\n * Static lint for workflow scripts.\n *\n * Catches the single most common AI-authoring bug: calling `agent()`,\n * `parallel()`, or `pipeline()` without `await` and then using the returned\n * Promise as if it were a value. The runtime would throw a cryptic TypeError\n * like `results.map is not a function`; this lint converts it into an\n * actionable error before the script ever runs.\n *\n * Rules (per matching CallExpression):\n * Allowed parents\n * - AwaitExpression argument `await parallel(...)`\n * - ReturnStatement argument `return agent(...)` (auto-unwraps)\n * - ExpressionStatement fire-and-forget; pending agents drain\n * - ArrowFunctionExpression expression body `() => agent(...)` (thunk for parallel/pipeline)\n * Anything else (VariableDeclarator init, MemberExpression object, template\n * interpolation, binary/logical operand, call argument, property/array\n * element, ...) is rejected with a teaching message.\n *\n * Out of scope (handled by the runtime):\n * - `parallel([agent(...), agent(...)])` (promises instead of thunks) — caught\n * by the runtime's TypeError (\"expects an array of functions, not promises\").\n * - Promise-as-value bugs that survive lint (dynamic indirection, late await).\n */\n\nimport type { Node } from 'acorn';\n\ntype AnyNode = Node & {\n [key: string]: any;\n start: number;\n end: number;\n loc?: { start: { line: number; column: number } };\n};\n\nconst LINT_TARGETS = new Set(['agent', 'parallel', 'pipeline']);\n\nexport function lintAwaits(ast: AnyNode): void {\n walk(ast, null, (node, parent) => {\n if (!isLintTarget(node)) return;\n if (isAcceptableParent(parent, node)) return;\n const calleeName = (node.callee as AnyNode).name as string;\n const line = node.loc?.start.line ?? '?';\n throw new Error(formatError(calleeName, line, parent));\n });\n}\n\nfunction isLintTarget(node: AnyNode): boolean {\n if (node.type !== 'CallExpression') return false;\n const callee = node.callee as AnyNode | undefined;\n if (!callee || callee.type !== 'Identifier') return false;\n return LINT_TARGETS.has(callee.name);\n}\n\nfunction isAcceptableParent(parent: AnyNode | null, call: AnyNode): boolean {\n if (!parent) return false;\n switch (parent.type) {\n case 'AwaitExpression':\n return parent.argument === call;\n case 'ReturnStatement':\n return parent.argument === call;\n case 'ExpressionStatement':\n return parent.expression === call;\n case 'ArrowFunctionExpression':\n // `() => agent(...)` — thunk-style body that the runtime invokes/awaits.\n return parent.expression === true && parent.body === call;\n default:\n return false;\n }\n}\n\nfunction formatError(name: string, line: number | string, parent: AnyNode | null): string {\n const ctx = parentContextHint(parent);\n return [\n `workflow lint error at line ${line}: \\`${name}(...)\\` returns a Promise but is used without 'await'${ctx ? ` (${ctx})` : ''}.`,\n ` ❌ const x = ${name}(...); x.map(...)`,\n ` ✅ const x = await ${name}(...); x.map(...)`,\n `Workflow scripts run in an async IIFE — 'await' parallel()/pipeline()/agent() before using their results, or 'return' them directly.`,\n ].join('\\n');\n}\n\nfunction parentContextHint(parent: AnyNode | null): string {\n if (!parent) return '';\n switch (parent.type) {\n case 'VariableDeclarator':\n return 'assigned to variable';\n case 'AssignmentExpression':\n return 'assigned via =';\n case 'MemberExpression':\n return 'method/property access on Promise';\n case 'TemplateLiteral':\n return 'interpolated in template string';\n case 'BinaryExpression':\n case 'LogicalExpression':\n return 'used in expression';\n case 'ConditionalExpression':\n return 'used as ternary operand';\n case 'CallExpression':\n return 'passed as argument';\n case 'Property':\n return 'used as object property value';\n case 'ArrayExpression':\n return 'placed in array (use a thunk: () => ' + 'call)';\n case 'SpreadElement':\n return 'spread';\n case 'IfStatement':\n case 'WhileStatement':\n case 'DoWhileStatement':\n case 'ForStatement':\n return 'used as condition';\n default:\n return parent.type;\n }\n}\n\nfunction walk(\n node: AnyNode,\n parent: AnyNode | null,\n visit: (n: AnyNode, p: AnyNode | null) => void,\n): void {\n visit(node, parent);\n for (const value of Object.values(node)) {\n if (Array.isArray(value)) {\n for (const v of value) {\n if (isAstNode(v)) walk(v, node, visit);\n }\n } else if (isAstNode(value)) {\n walk(value, node, visit);\n }\n }\n}\n\nfunction isAstNode(value: unknown): value is AnyNode {\n return !!value && typeof value === 'object' && typeof (value as AnyNode).type === 'string';\n}\n"],"mappings":";AAkCA,MAAM,eAAe,IAAI,IAAI;CAAC;CAAS;CAAY;CAAW,CAAC;AAE/D,SAAgB,WAAW,KAAoB;AAC7C,MAAK,KAAK,OAAO,MAAM,WAAW;AAChC,MAAI,CAAC,aAAa,KAAK,CAAE;AACzB,MAAI,mBAAmB,QAAQ,KAAK,CAAE;EACtC,MAAM,aAAc,KAAK,OAAmB;EAC5C,MAAM,OAAO,KAAK,KAAK,MAAM,QAAQ;AACrC,QAAM,IAAI,MAAM,YAAY,YAAY,MAAM,OAAO,CAAC;GACtD;;AAGJ,SAAS,aAAa,MAAwB;AAC5C,KAAI,KAAK,SAAS,iBAAkB,QAAO;CAC3C,MAAM,SAAS,KAAK;AACpB,KAAI,CAAC,UAAU,OAAO,SAAS,aAAc,QAAO;AACpD,QAAO,aAAa,IAAI,OAAO,KAAK;;AAGtC,SAAS,mBAAmB,QAAwB,MAAwB;AAC1E,KAAI,CAAC,OAAQ,QAAO;AACpB,SAAQ,OAAO,MAAf;EACE,KAAK,kBACH,QAAO,OAAO,aAAa;EAC7B,KAAK,kBACH,QAAO,OAAO,aAAa;EAC7B,KAAK,sBACH,QAAO,OAAO,eAAe;EAC/B,KAAK,0BAEH,QAAO,OAAO,eAAe,QAAQ,OAAO,SAAS;EACvD,QACE,QAAO;;;AAIb,SAAS,YAAY,MAAc,MAAuB,QAAgC;CACxF,MAAM,MAAM,kBAAkB,OAAO;AACrC,QAAO;EACL,+BAA+B,KAAK,MAAM,KAAK,uDAAuD,MAAM,KAAK,IAAI,KAAK,GAAG;EAC7H,iBAAiB,KAAK;EACtB,uBAAuB,KAAK;EAC5B;EACD,CAAC,KAAK,KAAK;;AAGd,SAAS,kBAAkB,QAAgC;AACzD,KAAI,CAAC,OAAQ,QAAO;AACpB,SAAQ,OAAO,MAAf;EACE,KAAK,qBACH,QAAO;EACT,KAAK,uBACH,QAAO;EACT,KAAK,mBACH,QAAO;EACT,KAAK,kBACH,QAAO;EACT,KAAK;EACL,KAAK,oBACH,QAAO;EACT,KAAK,wBACH,QAAO;EACT,KAAK,iBACH,QAAO;EACT,KAAK,WACH,QAAO;EACT,KAAK,kBACH,QAAO;EACT,KAAK,gBACH,QAAO;EACT,KAAK;EACL,KAAK;EACL,KAAK;EACL,KAAK,eACH,QAAO;EACT,QACE,QAAO,OAAO;;;AAIpB,SAAS,KACP,MACA,QACA,OACM;AACN,OAAM,MAAM,OAAO;AACnB,MAAK,MAAM,SAAS,OAAO,OAAO,KAAK,CACrC,KAAI,MAAM,QAAQ,MAAM;OACjB,MAAM,KAAK,MACd,KAAI,UAAU,EAAE,CAAE,MAAK,GAAG,MAAM,MAAM;YAE/B,UAAU,MAAM,CACzB,MAAK,OAAO,MAAM,MAAM;;AAK9B,SAAS,UAAU,OAAkC;AACnD,QAAO,CAAC,CAAC,SAAS,OAAO,UAAU,YAAY,OAAQ,MAAkB,SAAS"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { WorkflowMeta, WorkflowMetaExamplePrompt, WorkflowMetaLocale } from './types.js';
|
|
2
|
+
export type WorkflowLocaleCode = 'en' | 'zh';
|
|
3
|
+
export declare function normalizeWorkflowLocale(language: string | undefined): WorkflowLocaleCode;
|
|
4
|
+
export interface WorkflowLocalizedCopy {
|
|
5
|
+
description: string;
|
|
6
|
+
whenToUse?: string;
|
|
7
|
+
examplePrompts: WorkflowMetaExamplePrompt[];
|
|
8
|
+
}
|
|
9
|
+
export declare function resolveWorkflowLocalizedCopy(meta: Pick<WorkflowMeta, 'description' | 'whenToUse' | 'examplePrompts' | 'i18n'>, locale: WorkflowLocaleCode): WorkflowLocalizedCopy;
|
|
10
|
+
export declare function validateExamplePrompts(value: unknown, path: string): WorkflowMetaExamplePrompt[] | undefined;
|
|
11
|
+
export declare function validateMetaLocale(value: unknown, path: string): WorkflowMetaLocale;
|
|
12
|
+
export declare function validateMetaI18n(value: unknown): Record<string, WorkflowMetaLocale> | undefined;
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
//#region src/agent/workflow/meta-locale.ts
|
|
2
|
+
function normalizeWorkflowLocale(language) {
|
|
3
|
+
return language === "zh" ? "zh" : "en";
|
|
4
|
+
}
|
|
5
|
+
function resolveWorkflowLocalizedCopy(meta, locale) {
|
|
6
|
+
const bundle = locale !== "en" ? meta.i18n?.[locale] : void 0;
|
|
7
|
+
const examplePrompts = bundle?.examplePrompts && bundle.examplePrompts.length > 0 ? bundle.examplePrompts : meta.examplePrompts ?? [];
|
|
8
|
+
return {
|
|
9
|
+
description: pickNonEmpty(bundle?.description, meta.description),
|
|
10
|
+
whenToUse: pickOptional(bundle?.whenToUse, meta.whenToUse),
|
|
11
|
+
examplePrompts
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
function pickNonEmpty(localized, fallback) {
|
|
15
|
+
const trimmed = localized?.trim();
|
|
16
|
+
return trimmed ? trimmed : fallback;
|
|
17
|
+
}
|
|
18
|
+
function pickOptional(localized, fallback) {
|
|
19
|
+
const trimmed = localized?.trim();
|
|
20
|
+
if (trimmed) return trimmed;
|
|
21
|
+
return fallback?.trim() || void 0;
|
|
22
|
+
}
|
|
23
|
+
function validateExamplePrompts(value, path) {
|
|
24
|
+
if (value === void 0) return void 0;
|
|
25
|
+
if (!Array.isArray(value)) throw new Error(`${path} must be an array`);
|
|
26
|
+
const prompts = [];
|
|
27
|
+
for (let index = 0; index < value.length; index++) {
|
|
28
|
+
const item = value[index];
|
|
29
|
+
if (!item || typeof item !== "object") throw new Error(`${path}[${index}] must be an object`);
|
|
30
|
+
const field = item.field;
|
|
31
|
+
const text = item.text;
|
|
32
|
+
if (typeof field !== "string" || !field.trim()) throw new Error(`${path}[${index}].field must be a non-empty string`);
|
|
33
|
+
if (typeof text !== "string" || !text.trim()) throw new Error(`${path}[${index}].text must be a non-empty string`);
|
|
34
|
+
prompts.push({
|
|
35
|
+
field: field.trim(),
|
|
36
|
+
text: text.trim()
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
return prompts;
|
|
40
|
+
}
|
|
41
|
+
function validateMetaLocale(value, path) {
|
|
42
|
+
if (!value || typeof value !== "object") throw new Error(`${path} must be an object`);
|
|
43
|
+
const record = value;
|
|
44
|
+
if (record.description !== void 0 && (typeof record.description !== "string" || !record.description.trim())) throw new Error(`${path}.description must be a non-empty string`);
|
|
45
|
+
if (record.whenToUse !== void 0 && typeof record.whenToUse !== "string") throw new Error(`${path}.whenToUse must be a string`);
|
|
46
|
+
validateExamplePrompts(record.examplePrompts, `${path}.examplePrompts`);
|
|
47
|
+
return record;
|
|
48
|
+
}
|
|
49
|
+
function validateMetaI18n(value) {
|
|
50
|
+
if (value === void 0) return void 0;
|
|
51
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) throw new Error("meta.i18n must be an object");
|
|
52
|
+
const locales = {};
|
|
53
|
+
for (const [locale, bundle] of Object.entries(value)) {
|
|
54
|
+
if (!/^[a-z]{2}(-[A-Za-z]{2})?$/.test(locale)) throw new Error(`meta.i18n key "${locale}" must be a language tag like "zh" or "en"`);
|
|
55
|
+
locales[locale] = validateMetaLocale(bundle, `meta.i18n.${locale}`);
|
|
56
|
+
}
|
|
57
|
+
return locales;
|
|
58
|
+
}
|
|
59
|
+
//#endregion
|
|
60
|
+
export { normalizeWorkflowLocale, resolveWorkflowLocalizedCopy, validateExamplePrompts, validateMetaI18n, validateMetaLocale };
|
|
61
|
+
|
|
62
|
+
//# sourceMappingURL=meta-locale.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"meta-locale.js","names":[],"sources":["../../../../src/agent/workflow/meta-locale.ts"],"sourcesContent":["import type { WorkflowMeta, WorkflowMetaExamplePrompt, WorkflowMetaLocale } from './types.js';\n\nexport type WorkflowLocaleCode = 'en' | 'zh';\n\nexport function normalizeWorkflowLocale(language: string | undefined): WorkflowLocaleCode {\n return language === 'zh' ? 'zh' : 'en';\n}\n\nexport interface WorkflowLocalizedCopy {\n description: string;\n whenToUse?: string;\n examplePrompts: WorkflowMetaExamplePrompt[];\n}\n\nexport function resolveWorkflowLocalizedCopy(\n meta: Pick<WorkflowMeta, 'description' | 'whenToUse' | 'examplePrompts' | 'i18n'>,\n locale: WorkflowLocaleCode,\n): WorkflowLocalizedCopy {\n const bundle = locale !== 'en' ? meta.i18n?.[locale] : undefined;\n const examplePrompts =\n bundle?.examplePrompts && bundle.examplePrompts.length > 0\n ? bundle.examplePrompts\n : (meta.examplePrompts ?? []);\n return {\n description: pickNonEmpty(bundle?.description, meta.description),\n whenToUse: pickOptional(bundle?.whenToUse, meta.whenToUse),\n examplePrompts,\n };\n}\n\nfunction pickNonEmpty(localized: string | undefined, fallback: string): string {\n const trimmed = localized?.trim();\n return trimmed ? trimmed : fallback;\n}\n\nfunction pickOptional(localized: string | undefined, fallback: string | undefined): string | undefined {\n const trimmed = localized?.trim();\n if (trimmed) return trimmed;\n const fb = fallback?.trim();\n return fb || undefined;\n}\n\nexport function validateExamplePrompts(value: unknown, path: string): WorkflowMetaExamplePrompt[] | undefined {\n if (value === undefined) return undefined;\n if (!Array.isArray(value)) {\n throw new Error(`${path} must be an array`);\n }\n const prompts: WorkflowMetaExamplePrompt[] = [];\n for (let index = 0; index < value.length; index++) {\n const item = value[index];\n if (!item || typeof item !== 'object') {\n throw new Error(`${path}[${index}] must be an object`);\n }\n const field = (item as WorkflowMetaExamplePrompt).field;\n const text = (item as WorkflowMetaExamplePrompt).text;\n if (typeof field !== 'string' || !field.trim()) {\n throw new Error(`${path}[${index}].field must be a non-empty string`);\n }\n if (typeof text !== 'string' || !text.trim()) {\n throw new Error(`${path}[${index}].text must be a non-empty string`);\n }\n prompts.push({ field: field.trim(), text: text.trim() });\n }\n return prompts;\n}\n\nexport function validateMetaLocale(value: unknown, path: string): WorkflowMetaLocale {\n if (!value || typeof value !== 'object') {\n throw new Error(`${path} must be an object`);\n }\n const record = value as WorkflowMetaLocale;\n if (record.description !== undefined && (typeof record.description !== 'string' || !record.description.trim())) {\n throw new Error(`${path}.description must be a non-empty string`);\n }\n if (record.whenToUse !== undefined && typeof record.whenToUse !== 'string') {\n throw new Error(`${path}.whenToUse must be a string`);\n }\n validateExamplePrompts(record.examplePrompts, `${path}.examplePrompts`);\n return record;\n}\n\nexport function validateMetaI18n(value: unknown): Record<string, WorkflowMetaLocale> | undefined {\n if (value === undefined) return undefined;\n if (!value || typeof value !== 'object' || Array.isArray(value)) {\n throw new Error('meta.i18n must be an object');\n }\n const locales: Record<string, WorkflowMetaLocale> = {};\n for (const [locale, bundle] of Object.entries(value as Record<string, unknown>)) {\n if (!/^[a-z]{2}(-[A-Za-z]{2})?$/.test(locale)) {\n throw new Error(`meta.i18n key \"${locale}\" must be a language tag like \"zh\" or \"en\"`);\n }\n locales[locale] = validateMetaLocale(bundle, `meta.i18n.${locale}`);\n }\n return locales;\n}\n"],"mappings":";AAIA,SAAgB,wBAAwB,UAAkD;AACxF,QAAO,aAAa,OAAO,OAAO;;AASpC,SAAgB,6BACd,MACA,QACuB;CACvB,MAAM,SAAS,WAAW,OAAO,KAAK,OAAO,UAAU,KAAA;CACvD,MAAM,iBACJ,QAAQ,kBAAkB,OAAO,eAAe,SAAS,IACrD,OAAO,iBACN,KAAK,kBAAkB,EAAE;AAChC,QAAO;EACL,aAAa,aAAa,QAAQ,aAAa,KAAK,YAAY;EAChE,WAAW,aAAa,QAAQ,WAAW,KAAK,UAAU;EAC1D;EACD;;AAGH,SAAS,aAAa,WAA+B,UAA0B;CAC7E,MAAM,UAAU,WAAW,MAAM;AACjC,QAAO,UAAU,UAAU;;AAG7B,SAAS,aAAa,WAA+B,UAAkD;CACrG,MAAM,UAAU,WAAW,MAAM;AACjC,KAAI,QAAS,QAAO;AAEpB,QADW,UAAU,MAAM,IACd,KAAA;;AAGf,SAAgB,uBAAuB,OAAgB,MAAuD;AAC5G,KAAI,UAAU,KAAA,EAAW,QAAO,KAAA;AAChC,KAAI,CAAC,MAAM,QAAQ,MAAM,CACvB,OAAM,IAAI,MAAM,GAAG,KAAK,mBAAmB;CAE7C,MAAM,UAAuC,EAAE;AAC/C,MAAK,IAAI,QAAQ,GAAG,QAAQ,MAAM,QAAQ,SAAS;EACjD,MAAM,OAAO,MAAM;AACnB,MAAI,CAAC,QAAQ,OAAO,SAAS,SAC3B,OAAM,IAAI,MAAM,GAAG,KAAK,GAAG,MAAM,qBAAqB;EAExD,MAAM,QAAS,KAAmC;EAClD,MAAM,OAAQ,KAAmC;AACjD,MAAI,OAAO,UAAU,YAAY,CAAC,MAAM,MAAM,CAC5C,OAAM,IAAI,MAAM,GAAG,KAAK,GAAG,MAAM,oCAAoC;AAEvE,MAAI,OAAO,SAAS,YAAY,CAAC,KAAK,MAAM,CAC1C,OAAM,IAAI,MAAM,GAAG,KAAK,GAAG,MAAM,mCAAmC;AAEtE,UAAQ,KAAK;GAAE,OAAO,MAAM,MAAM;GAAE,MAAM,KAAK,MAAM;GAAE,CAAC;;AAE1D,QAAO;;AAGT,SAAgB,mBAAmB,OAAgB,MAAkC;AACnF,KAAI,CAAC,SAAS,OAAO,UAAU,SAC7B,OAAM,IAAI,MAAM,GAAG,KAAK,oBAAoB;CAE9C,MAAM,SAAS;AACf,KAAI,OAAO,gBAAgB,KAAA,MAAc,OAAO,OAAO,gBAAgB,YAAY,CAAC,OAAO,YAAY,MAAM,EAC3G,OAAM,IAAI,MAAM,GAAG,KAAK,yCAAyC;AAEnE,KAAI,OAAO,cAAc,KAAA,KAAa,OAAO,OAAO,cAAc,SAChE,OAAM,IAAI,MAAM,GAAG,KAAK,6BAA6B;AAEvD,wBAAuB,OAAO,gBAAgB,GAAG,KAAK,iBAAiB;AACvE,QAAO;;AAGT,SAAgB,iBAAiB,OAAgE;AAC/F,KAAI,UAAU,KAAA,EAAW,QAAO,KAAA;AAChC,KAAI,CAAC,SAAS,OAAO,UAAU,YAAY,MAAM,QAAQ,MAAM,CAC7D,OAAM,IAAI,MAAM,8BAA8B;CAEhD,MAAM,UAA8C,EAAE;AACtD,MAAK,MAAM,CAAC,QAAQ,WAAW,OAAO,QAAQ,MAAiC,EAAE;AAC/E,MAAI,CAAC,4BAA4B,KAAK,OAAO,CAC3C,OAAM,IAAI,MAAM,kBAAkB,OAAO,4CAA4C;AAEvF,UAAQ,UAAU,mBAAmB,QAAQ,aAAa,SAAS;;AAErE,QAAO"}
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { lintAwaits } from "./lint.js";
|
|
2
|
+
import { validateExamplePrompts, validateMetaI18n } from "./meta-locale.js";
|
|
1
3
|
import { parse } from "acorn";
|
|
2
4
|
//#region src/agent/workflow/parser.ts
|
|
3
5
|
/**
|
|
@@ -23,7 +25,8 @@ function parseWorkflowScript(script) {
|
|
|
23
25
|
sourceType: "module",
|
|
24
26
|
allowAwaitOutsideFunction: true,
|
|
25
27
|
allowReturnOutsideFunction: true,
|
|
26
|
-
ranges: false
|
|
28
|
+
ranges: false,
|
|
29
|
+
locations: true
|
|
27
30
|
});
|
|
28
31
|
} catch (e) {
|
|
29
32
|
const msg = e instanceof Error ? e.message : String(e);
|
|
@@ -31,6 +34,7 @@ function parseWorkflowScript(script) {
|
|
|
31
34
|
}
|
|
32
35
|
assertDeterministicAst(ast);
|
|
33
36
|
assertNoDangerousImports(ast);
|
|
37
|
+
lintAwaits(ast);
|
|
34
38
|
const first = ast.body?.[0];
|
|
35
39
|
if (first?.type !== "ExportNamedDeclaration") throw new Error("`export const meta = { name, description }` must be the first statement in the script");
|
|
36
40
|
const declaration = first.declaration;
|
|
@@ -139,6 +143,8 @@ function validateMeta(meta) {
|
|
|
139
143
|
if (typeof est.min !== "number" || typeof est.max !== "number" || !Number.isFinite(est.min) || !Number.isFinite(est.max)) throw new Error("meta.estimatedAgents.min and .max must be finite numbers");
|
|
140
144
|
if (est.min < 1 || est.max < est.min) throw new Error("meta.estimatedAgents requires min >= 1 and max >= min");
|
|
141
145
|
}
|
|
146
|
+
validateExamplePrompts(value.examplePrompts, "meta.examplePrompts");
|
|
147
|
+
validateMetaI18n(value.i18n);
|
|
142
148
|
}
|
|
143
149
|
//#endregion
|
|
144
150
|
export { parseWorkflowScript };
|