@xopcai/xopc 0.0.85 → 0.0.87
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/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/routing-integration.js +1 -0
- package/dist/extensions/telegram/src/routing-integration.js.map +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 +2 -2
- 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/delivery-to.js +2 -2
- package/dist/extensions/weixin/src/delivery-to.js.map +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/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.map +1 -1
- package/dist/gateway/static/root/assets/agents-BEAbXpuP.js +222 -0
- package/dist/gateway/static/root/assets/{apps-page-D7v7649T.js → apps-page-Dg8R-Szf.js} +1 -1
- package/dist/gateway/static/root/assets/{channels-settings-nCaMb0a7.js → channels-settings-yohw9YSu.js} +1 -1
- package/dist/gateway/static/root/assets/{channels-status-swr-C1gZBcJV.js → channels-status-swr-BSHqqCF1.js} +1 -1
- package/dist/gateway/static/root/assets/{cron-api-CoYK0hlm.js → cron-api-0h_QT8U3.js} +1 -1
- package/dist/gateway/static/root/assets/{cron-page-DeGo-Vjc.js → cron-page-BkfKFfFk.js} +1 -1
- package/dist/gateway/static/root/assets/{dist-DaK4dsss.js → dist-Cmjp2APP.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-debug-page-BZngZWbO.js → extension-debug-page-CFa9z_1N.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-page-D6JSyV27.js → extension-page-BI8eaTPq.js} +1 -1
- package/dist/gateway/static/root/assets/extension-settings-page-x4BB7q1X.js +1 -0
- package/dist/gateway/static/root/assets/{fetch-B2MYHbWg.js → fetch-DRqwef_Q.js} +1 -1
- package/dist/gateway/static/root/assets/{field-primitives-Zzl22MvN.js → field-primitives-BiNHBo2Y.js} +1 -1
- package/dist/gateway/static/root/assets/{heartbeat-config-api-BtIcpG0O.js → heartbeat-config-api-ZRb8qhuz.js} +1 -1
- package/dist/gateway/static/root/assets/{index-D4vM3-P7.js → index-Cu7bKuUi.js} +96 -94
- package/dist/gateway/static/root/assets/index-a5gWIdZQ.css +1 -0
- package/dist/gateway/static/root/assets/{logs-page-_d4UJ-qQ.js → logs-page-BFZ8GgCv.js} +1 -1
- package/dist/gateway/static/root/assets/{sessions-page-5N4aF2Wk.js → sessions-page-CD7AfB-2.js} +1 -1
- package/dist/gateway/static/root/assets/settings-form-section-DiqqVs6m.js +1 -0
- package/dist/gateway/static/root/assets/settings-page-BBOjEQW3.js +3 -0
- package/dist/gateway/static/root/assets/{share-preview-page-D4EG_vM1.js → share-preview-page-n1Gprylk.js} +1 -1
- package/dist/gateway/static/root/assets/{skills-page-sPAXhh8w.js → skills-page-CcN_gj--.js} +1 -1
- package/dist/gateway/static/root/assets/{theme-store-DryYl3qD.js → theme-store-CZOh1nT3.js} +1 -1
- package/dist/gateway/static/root/assets/url-Dd8Q7kZZ.js +3 -0
- package/dist/gateway/static/root/assets/{utils-CYO9eTCM.js → utils-CkWBfxs4.js} +1 -1
- package/dist/gateway/static/root/assets/{voice-api-key-field-Ds51havm.js → voice-api-key-field-O6awz9hi.js} +1 -1
- package/dist/gateway/static/root/index.html +5 -5
- package/dist/package.js +1 -1
- 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/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/persistent-goal-apis.d.ts +0 -2
- package/dist/src/agent/goals/persistent-goal-service.js +0 -1
- package/dist/src/agent/goals/persistent-goal-service.js.map +1 -1
- 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/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 +6 -4
- package/dist/src/agent/inbound/turn-dispatcher.js.map +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/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/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/service/build-direct-message-content.js +1 -1
- 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 +34 -4
- package/dist/src/agent/service/process-direct-streaming.js.map +1 -1
- package/dist/src/agent/service/webchat-tts.js +1 -1
- 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 +21 -1
- package/dist/src/agent/service.js.map +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/factory.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/shell.js +0 -13
- package/dist/src/agent/tools/shell.js.map +1 -1
- package/dist/src/agent/tools/workflow-tool.js +10 -4
- package/dist/src/agent/tools/workflow-tool.js.map +1 -1
- package/dist/src/agent/workflow/builtins/audit-repo.d.ts +5 -1
- package/dist/src/agent/workflow/builtins/audit-repo.js +52 -11
- package/dist/src/agent/workflow/builtins/audit-repo.js.map +1 -1
- package/dist/src/agent/workflow/builtins/debug-incident.d.ts +13 -0
- package/dist/src/agent/workflow/builtins/debug-incident.js +155 -0
- package/dist/src/agent/workflow/builtins/debug-incident.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 +6 -1
- package/dist/src/agent/workflow/builtins/multi-perspective-review.js +66 -30
- package/dist/src/agent/workflow/builtins/multi-perspective-review.js.map +1 -1
- package/dist/src/agent/workflow/builtins/pr-review.d.ts +12 -0
- package/dist/src/agent/workflow/builtins/pr-review.js +156 -0
- package/dist/src/agent/workflow/builtins/pr-review.js.map +1 -0
- package/dist/src/agent/workflow/builtins/research.d.ts +5 -1
- package/dist/src/agent/workflow/builtins/research.js +37 -6
- package/dist/src/agent/workflow/builtins/research.js.map +1 -1
- package/dist/src/agent/workflow/catalog.d.ts +5 -0
- package/dist/src/agent/workflow/catalog.js +6 -2
- package/dist/src/agent/workflow/catalog.js.map +1 -1
- package/dist/src/agent/workflow/channel-capability.d.ts +3 -3
- package/dist/src/agent/workflow/index.d.ts +1 -1
- 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/parser.js +13 -1
- package/dist/src/agent/workflow/parser.js.map +1 -1
- package/dist/src/agent/workflow/runtime.d.ts +3 -0
- package/dist/src/agent/workflow/runtime.js +76 -3
- package/dist/src/agent/workflow/runtime.js.map +1 -1
- package/dist/src/agent/workflow/types.d.ts +11 -1
- 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 +38 -85
- 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 +2 -55
- package/dist/src/browser/providers/cloakbrowser.js.map +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/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 +6 -6
- package/dist/src/channels/pairing/pairing-store.js.map +1 -1
- 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/builtins/workflow.js +7 -2
- package/dist/src/chat-commands/builtins/workflow.js.map +1 -1
- package/dist/src/chat-commands/context.d.ts +3 -0
- package/dist/src/chat-commands/context.js +21 -3
- 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/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 +22 -21
- package/dist/src/cli/commands/image.js.map +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/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 +5 -27
- package/dist/src/config/agent-profile.js.map +1 -1
- package/dist/src/config/index.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/schema.d.ts +201 -217
- package/dist/src/config/schema.js +54 -39
- package/dist/src/config/schema.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/daemon/install-plan.js +25 -1
- 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 +5 -12
- package/dist/src/daemon/launchd.js.map +1 -1
- package/dist/src/daemon/schtasks.d.ts +25 -0
- package/dist/src/daemon/schtasks.js +166 -46
- 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 +18 -3
- 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/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.js +10 -2
- package/dist/src/gateway/agents-admin.js.map +1 -1
- package/dist/src/gateway/heartbeat/service.js +1 -1
- 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 +18 -10
- package/dist/src/gateway/hono/lib/agent-model.js +24 -35
- package/dist/src/gateway/hono/lib/agent-model.js.map +1 -1
- package/dist/src/gateway/hono/lib/config-payload.js +1 -1
- package/dist/src/gateway/hono/lib/config-payload.js.map +1 -1
- package/dist/src/gateway/hono/lib/safe-voice-config.js +14 -53
- package/dist/src/gateway/hono/lib/safe-voice-config.js.map +1 -1
- package/dist/src/gateway/hono/routes/config-patch/agents.js +17 -5
- 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/goals.js +1 -1
- package/dist/src/gateway/hono/routes/goals.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 +14 -12
- 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/sse.js +16 -33
- package/dist/src/gateway/hono/sse.js.map +1 -1
- package/dist/src/gateway/lock.js +10 -10
- 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/run-gateway-agent.js +27 -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 +0 -2
- package/dist/src/gateway/service.js +2 -7
- 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/infra/gateway-processes.js +2 -2
- package/dist/src/infra/gateway-processes.js.map +1 -1
- 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-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/mcp/channel-bridge.js +1 -1
- 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 +1 -1
- 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/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/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/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/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 +57 -6
- 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-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/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/components/chat-log.js +3 -3
- package/dist/src/tui/components/chat-log.js.map +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-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 +1 -21
- package/dist/src/tui/tui-keybindings-file.js.map +1 -1
- 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.js +52 -47
- package/dist/src/tui/tui.js.map +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/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/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/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/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/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/package.json +1 -4
- package/dist/gateway/static/root/assets/agents-D3_-kNlZ.js +0 -222
- package/dist/gateway/static/root/assets/extension-settings-page-8PZcmWI7.js +0 -1
- package/dist/gateway/static/root/assets/index-ew_2L2We.css +0 -1
- package/dist/gateway/static/root/assets/settings-form-section-D_tgb8r2.js +0 -1
- package/dist/gateway/static/root/assets/settings-page-C18xBt4X.js +0 -3
- package/dist/gateway/static/root/assets/url-BwNL6Rgk.js +0 -3
- 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,155 @@
|
|
|
1
|
+
//#region src/agent/workflow/builtins/debug-incident.ts
|
|
2
|
+
/**
|
|
3
|
+
* Built-in workflow: `debug_incident`
|
|
4
|
+
*
|
|
5
|
+
* Triage an error, stack trace, or log snippet. Parses the signal, fans out
|
|
6
|
+
* parallel hypotheses (config, race, dependency, data, environment), then
|
|
7
|
+
* ranks likely root causes with verification steps.
|
|
8
|
+
*
|
|
9
|
+
* Args:
|
|
10
|
+
* - error: error message or stack trace
|
|
11
|
+
* - logs: optional log excerpt
|
|
12
|
+
* - context: optional extra context (what changed, when it started)
|
|
13
|
+
*/
|
|
14
|
+
const DEBUG_INCIDENT_SCRIPT = `export const meta = {
|
|
15
|
+
name: 'debug_incident',
|
|
16
|
+
description: 'Triage an error or log snippet with parallel hypotheses and ranked root-cause analysis.',
|
|
17
|
+
whenToUse: 'User reports a bug, crash, error message, or unexpected behavior and wants systematic triage.',
|
|
18
|
+
tags: ['debug', 'incident', 'troubleshooting'],
|
|
19
|
+
estimatedAgents: { min: 7, max: 7 },
|
|
20
|
+
phases: [
|
|
21
|
+
{ title: 'Triage' },
|
|
22
|
+
{ title: 'Hypotheses' },
|
|
23
|
+
{ title: 'Rank' },
|
|
24
|
+
],
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
const READ_TOOLS = ['read_file', 'grep', 'find', 'list_dir', 'shell']
|
|
28
|
+
|
|
29
|
+
const error = args && typeof args === 'object' && args.error
|
|
30
|
+
? String(args.error)
|
|
31
|
+
: 'Infer the primary error from the most recent user message or conversation context.'
|
|
32
|
+
|
|
33
|
+
const logs = args && typeof args === 'object' && args.logs
|
|
34
|
+
? String(args.logs)
|
|
35
|
+
: ''
|
|
36
|
+
|
|
37
|
+
const context = args && typeof args === 'object' && args.context
|
|
38
|
+
? String(args.context)
|
|
39
|
+
: ''
|
|
40
|
+
|
|
41
|
+
phase('Triage')
|
|
42
|
+
const triage = await agent(
|
|
43
|
+
'Parse this incident signal. Extract: error type, likely subsystem, affected files/modules if identifiable, and 2–3 key facts from logs.\\n\\n' +
|
|
44
|
+
'ERROR:\\n' + error + '\\n\\n' +
|
|
45
|
+
(logs ? 'LOGS:\\n' + logs + '\\n\\n' : '') +
|
|
46
|
+
(context ? 'CONTEXT:\\n' + context + '\\n\\n' : '') +
|
|
47
|
+
'Use read/grep tools to locate relevant code if the workspace may contain the failing path.',
|
|
48
|
+
{
|
|
49
|
+
label: 'incident triage',
|
|
50
|
+
toolset: READ_TOOLS,
|
|
51
|
+
schema: {
|
|
52
|
+
type: 'object',
|
|
53
|
+
properties: {
|
|
54
|
+
errorType: { type: 'string' },
|
|
55
|
+
subsystem: { type: 'string' },
|
|
56
|
+
affectedPaths: { type: 'array', items: { type: 'string' } },
|
|
57
|
+
keyFacts: { type: 'array', items: { type: 'string' } },
|
|
58
|
+
},
|
|
59
|
+
required: ['errorType', 'keyFacts'],
|
|
60
|
+
},
|
|
61
|
+
},
|
|
62
|
+
)
|
|
63
|
+
|
|
64
|
+
const HYPOTHESES = [
|
|
65
|
+
{ key: 'config', angle: 'Misconfiguration, missing env vars, wrong defaults, feature flags, stale config cache.' },
|
|
66
|
+
{ key: 'race', angle: 'Concurrency, timing, ordering, partial failure under load, missing locks or awaits.' },
|
|
67
|
+
{ key: 'dependency', angle: 'Version mismatch, breaking upstream change, network/API failure, timeout, auth expiry.' },
|
|
68
|
+
{ key: 'data', angle: 'Bad input, schema drift, null/empty edge case, corrupt state, migration gap.' },
|
|
69
|
+
{ key: 'environment', angle: 'OS, permissions, disk, memory, container/network isolation, platform-specific behavior.' },
|
|
70
|
+
]
|
|
71
|
+
|
|
72
|
+
phase('Hypotheses')
|
|
73
|
+
const hypothesisReports = await parallel(
|
|
74
|
+
HYPOTHESES.map((h) => () =>
|
|
75
|
+
agent(
|
|
76
|
+
'Evaluate whether this hypothesis explains the incident. Search the codebase for supporting or refuting evidence.\\n\\n' +
|
|
77
|
+
'HYPOTHESIS: ' + h.key + ' — ' + h.angle + '\\n\\n' +
|
|
78
|
+
'TRIAGE:\\n' + JSON.stringify(triage, null, 2) + '\\n\\n' +
|
|
79
|
+
'ERROR:\\n' + error + '\\n\\n' +
|
|
80
|
+
(logs ? 'LOGS:\\n' + logs + '\\n\\n' : '') +
|
|
81
|
+
'Return: likelihood (low/med/high), evidence (file paths + brief notes), and one verification step.',
|
|
82
|
+
{
|
|
83
|
+
label: h.key + ' hypothesis',
|
|
84
|
+
toolset: READ_TOOLS,
|
|
85
|
+
schema: {
|
|
86
|
+
type: 'object',
|
|
87
|
+
properties: {
|
|
88
|
+
likelihood: { type: 'string', enum: ['low', 'med', 'high'] },
|
|
89
|
+
evidence: {
|
|
90
|
+
type: 'array',
|
|
91
|
+
items: {
|
|
92
|
+
type: 'object',
|
|
93
|
+
properties: {
|
|
94
|
+
path: { type: 'string' },
|
|
95
|
+
note: { type: 'string' },
|
|
96
|
+
},
|
|
97
|
+
required: ['path', 'note'],
|
|
98
|
+
},
|
|
99
|
+
},
|
|
100
|
+
verificationStep: { type: 'string' },
|
|
101
|
+
},
|
|
102
|
+
required: ['likelihood', 'evidence', 'verificationStep'],
|
|
103
|
+
},
|
|
104
|
+
},
|
|
105
|
+
),
|
|
106
|
+
),
|
|
107
|
+
)
|
|
108
|
+
|
|
109
|
+
phase('Rank')
|
|
110
|
+
const live = hypothesisReports.filter(Boolean)
|
|
111
|
+
const byHypothesis = {}
|
|
112
|
+
for (let i = 0; i < HYPOTHESES.length; i++) {
|
|
113
|
+
byHypothesis[HYPOTHESES[i].key] = live[i] ?? null
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
const ranking = await agent(
|
|
117
|
+
'Rank root causes by likelihood. Pick the top 3 with confidence and concrete next steps to confirm or fix.\\n\\n' +
|
|
118
|
+
JSON.stringify({ triage, byHypothesis }, null, 2),
|
|
119
|
+
{
|
|
120
|
+
label: 'root cause ranking',
|
|
121
|
+
schema: {
|
|
122
|
+
type: 'object',
|
|
123
|
+
properties: {
|
|
124
|
+
topCauses: {
|
|
125
|
+
type: 'array',
|
|
126
|
+
items: {
|
|
127
|
+
type: 'object',
|
|
128
|
+
properties: {
|
|
129
|
+
hypothesis: { type: 'string' },
|
|
130
|
+
likelihood: { type: 'string', enum: ['low', 'med', 'high'] },
|
|
131
|
+
summary: { type: 'string' },
|
|
132
|
+
nextStep: { type: 'string' },
|
|
133
|
+
},
|
|
134
|
+
required: ['hypothesis', 'likelihood', 'summary', 'nextStep'],
|
|
135
|
+
},
|
|
136
|
+
},
|
|
137
|
+
immediateActions: { type: 'array', items: { type: 'string' } },
|
|
138
|
+
summary: { type: 'string' },
|
|
139
|
+
},
|
|
140
|
+
required: ['topCauses', 'summary'],
|
|
141
|
+
},
|
|
142
|
+
},
|
|
143
|
+
)
|
|
144
|
+
|
|
145
|
+
return {
|
|
146
|
+
ok: true,
|
|
147
|
+
triage,
|
|
148
|
+
...(ranking ?? { topCauses: [], summary: 'ranking failed', immediateActions: [] }),
|
|
149
|
+
byHypothesis,
|
|
150
|
+
}
|
|
151
|
+
`;
|
|
152
|
+
//#endregion
|
|
153
|
+
export { DEBUG_INCIDENT_SCRIPT };
|
|
154
|
+
|
|
155
|
+
//# sourceMappingURL=debug-incident.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"debug-incident.js","names":[],"sources":["../../../../../src/agent/workflow/builtins/debug-incident.ts"],"sourcesContent":["/**\n * Built-in workflow: `debug_incident`\n *\n * Triage an error, stack trace, or log snippet. Parses the signal, fans out\n * parallel hypotheses (config, race, dependency, data, environment), then\n * ranks likely root causes with verification steps.\n *\n * Args:\n * - error: error message or stack trace\n * - logs: optional log excerpt\n * - context: optional extra context (what changed, when it started)\n */\n\nexport const DEBUG_INCIDENT_SCRIPT = `export const meta = {\n name: 'debug_incident',\n description: 'Triage an error or log snippet with parallel hypotheses and ranked root-cause analysis.',\n whenToUse: 'User reports a bug, crash, error message, or unexpected behavior and wants systematic triage.',\n tags: ['debug', 'incident', 'troubleshooting'],\n estimatedAgents: { min: 7, max: 7 },\n phases: [\n { title: 'Triage' },\n { title: 'Hypotheses' },\n { title: 'Rank' },\n ],\n}\n\nconst READ_TOOLS = ['read_file', 'grep', 'find', 'list_dir', 'shell']\n\nconst error = args && typeof args === 'object' && args.error\n ? String(args.error)\n : 'Infer the primary error from the most recent user message or conversation context.'\n\nconst logs = args && typeof args === 'object' && args.logs\n ? String(args.logs)\n : ''\n\nconst context = args && typeof args === 'object' && args.context\n ? String(args.context)\n : ''\n\nphase('Triage')\nconst triage = await agent(\n 'Parse this incident signal. Extract: error type, likely subsystem, affected files/modules if identifiable, and 2–3 key facts from logs.\\\\n\\\\n' +\n 'ERROR:\\\\n' + error + '\\\\n\\\\n' +\n (logs ? 'LOGS:\\\\n' + logs + '\\\\n\\\\n' : '') +\n (context ? 'CONTEXT:\\\\n' + context + '\\\\n\\\\n' : '') +\n 'Use read/grep tools to locate relevant code if the workspace may contain the failing path.',\n {\n label: 'incident triage',\n toolset: READ_TOOLS,\n schema: {\n type: 'object',\n properties: {\n errorType: { type: 'string' },\n subsystem: { type: 'string' },\n affectedPaths: { type: 'array', items: { type: 'string' } },\n keyFacts: { type: 'array', items: { type: 'string' } },\n },\n required: ['errorType', 'keyFacts'],\n },\n },\n)\n\nconst HYPOTHESES = [\n { key: 'config', angle: 'Misconfiguration, missing env vars, wrong defaults, feature flags, stale config cache.' },\n { key: 'race', angle: 'Concurrency, timing, ordering, partial failure under load, missing locks or awaits.' },\n { key: 'dependency', angle: 'Version mismatch, breaking upstream change, network/API failure, timeout, auth expiry.' },\n { key: 'data', angle: 'Bad input, schema drift, null/empty edge case, corrupt state, migration gap.' },\n { key: 'environment', angle: 'OS, permissions, disk, memory, container/network isolation, platform-specific behavior.' },\n]\n\nphase('Hypotheses')\nconst hypothesisReports = await parallel(\n HYPOTHESES.map((h) => () =>\n agent(\n 'Evaluate whether this hypothesis explains the incident. Search the codebase for supporting or refuting evidence.\\\\n\\\\n' +\n 'HYPOTHESIS: ' + h.key + ' — ' + h.angle + '\\\\n\\\\n' +\n 'TRIAGE:\\\\n' + JSON.stringify(triage, null, 2) + '\\\\n\\\\n' +\n 'ERROR:\\\\n' + error + '\\\\n\\\\n' +\n (logs ? 'LOGS:\\\\n' + logs + '\\\\n\\\\n' : '') +\n 'Return: likelihood (low/med/high), evidence (file paths + brief notes), and one verification step.',\n {\n label: h.key + ' hypothesis',\n toolset: READ_TOOLS,\n schema: {\n type: 'object',\n properties: {\n likelihood: { type: 'string', enum: ['low', 'med', 'high'] },\n evidence: {\n type: 'array',\n items: {\n type: 'object',\n properties: {\n path: { type: 'string' },\n note: { type: 'string' },\n },\n required: ['path', 'note'],\n },\n },\n verificationStep: { type: 'string' },\n },\n required: ['likelihood', 'evidence', 'verificationStep'],\n },\n },\n ),\n ),\n)\n\nphase('Rank')\nconst live = hypothesisReports.filter(Boolean)\nconst byHypothesis = {}\nfor (let i = 0; i < HYPOTHESES.length; i++) {\n byHypothesis[HYPOTHESES[i].key] = live[i] ?? null\n}\n\nconst ranking = await agent(\n 'Rank root causes by likelihood. Pick the top 3 with confidence and concrete next steps to confirm or fix.\\\\n\\\\n' +\n JSON.stringify({ triage, byHypothesis }, null, 2),\n {\n label: 'root cause ranking',\n schema: {\n type: 'object',\n properties: {\n topCauses: {\n type: 'array',\n items: {\n type: 'object',\n properties: {\n hypothesis: { type: 'string' },\n likelihood: { type: 'string', enum: ['low', 'med', 'high'] },\n summary: { type: 'string' },\n nextStep: { type: 'string' },\n },\n required: ['hypothesis', 'likelihood', 'summary', 'nextStep'],\n },\n },\n immediateActions: { type: 'array', items: { type: 'string' } },\n summary: { type: 'string' },\n },\n required: ['topCauses', 'summary'],\n },\n },\n)\n\nreturn {\n ok: true,\n triage,\n ...(ranking ?? { topCauses: [], summary: 'ranking failed', immediateActions: [] }),\n byHypothesis,\n}\n`\n"],"mappings":";;;;;;;;;;;;;AAaA,MAAa,wBAAwB"}
|
|
@@ -5,11 +5,13 @@
|
|
|
5
5
|
* not authority.
|
|
6
6
|
*/
|
|
7
7
|
import { AUDIT_REPO_SCRIPT } from './audit-repo.js';
|
|
8
|
+
import { DEBUG_INCIDENT_SCRIPT } from './debug-incident.js';
|
|
8
9
|
import { MULTI_PERSPECTIVE_REVIEW_SCRIPT } from './multi-perspective-review.js';
|
|
10
|
+
import { PR_REVIEW_SCRIPT } from './pr-review.js';
|
|
9
11
|
import { RESEARCH_SCRIPT } from './research.js';
|
|
10
12
|
export interface BuiltinWorkflow {
|
|
11
13
|
name: string;
|
|
12
14
|
script: string;
|
|
13
15
|
}
|
|
14
16
|
export declare const BUILTIN_WORKFLOWS: readonly BuiltinWorkflow[];
|
|
15
|
-
export { AUDIT_REPO_SCRIPT, MULTI_PERSPECTIVE_REVIEW_SCRIPT, RESEARCH_SCRIPT };
|
|
17
|
+
export { AUDIT_REPO_SCRIPT, DEBUG_INCIDENT_SCRIPT, MULTI_PERSPECTIVE_REVIEW_SCRIPT, PR_REVIEW_SCRIPT, RESEARCH_SCRIPT, };
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { AUDIT_REPO_SCRIPT } from "./audit-repo.js";
|
|
2
|
+
import { DEBUG_INCIDENT_SCRIPT } from "./debug-incident.js";
|
|
2
3
|
import { MULTI_PERSPECTIVE_REVIEW_SCRIPT } from "./multi-perspective-review.js";
|
|
4
|
+
import { PR_REVIEW_SCRIPT } from "./pr-review.js";
|
|
3
5
|
import { RESEARCH_SCRIPT } from "./research.js";
|
|
4
6
|
//#region src/agent/workflow/builtins/index.ts
|
|
5
7
|
/**
|
|
@@ -13,16 +15,24 @@ const BUILTIN_WORKFLOWS = Object.freeze([
|
|
|
13
15
|
name: "audit_repo",
|
|
14
16
|
script: AUDIT_REPO_SCRIPT
|
|
15
17
|
},
|
|
18
|
+
{
|
|
19
|
+
name: "debug_incident",
|
|
20
|
+
script: DEBUG_INCIDENT_SCRIPT
|
|
21
|
+
},
|
|
16
22
|
{
|
|
17
23
|
name: "multi_perspective_review",
|
|
18
24
|
script: MULTI_PERSPECTIVE_REVIEW_SCRIPT
|
|
19
25
|
},
|
|
26
|
+
{
|
|
27
|
+
name: "pr_review",
|
|
28
|
+
script: PR_REVIEW_SCRIPT
|
|
29
|
+
},
|
|
20
30
|
{
|
|
21
31
|
name: "research",
|
|
22
32
|
script: RESEARCH_SCRIPT
|
|
23
33
|
}
|
|
24
34
|
]);
|
|
25
35
|
//#endregion
|
|
26
|
-
export { AUDIT_REPO_SCRIPT, BUILTIN_WORKFLOWS, MULTI_PERSPECTIVE_REVIEW_SCRIPT, RESEARCH_SCRIPT };
|
|
36
|
+
export { AUDIT_REPO_SCRIPT, BUILTIN_WORKFLOWS, DEBUG_INCIDENT_SCRIPT, MULTI_PERSPECTIVE_REVIEW_SCRIPT, PR_REVIEW_SCRIPT, RESEARCH_SCRIPT };
|
|
27
37
|
|
|
28
38
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":[],"sources":["../../../../../src/agent/workflow/builtins/index.ts"],"sourcesContent":["/**\n * Bundled workflow templates. These are shipped with xopc and discoverable\n * via the catalog alongside user workflows in `~/.xopc/workflows/`. A user\n * workflow with the same `name` always wins — built-ins are starting points,\n * not authority.\n */\n\nimport { AUDIT_REPO_SCRIPT } from './audit-repo.js';\nimport { MULTI_PERSPECTIVE_REVIEW_SCRIPT } from './multi-perspective-review.js';\nimport { RESEARCH_SCRIPT } from './research.js';\n\nexport interface BuiltinWorkflow {\n name: string;\n script: string;\n}\n\nexport const BUILTIN_WORKFLOWS: readonly BuiltinWorkflow[] = Object.freeze([\n { name: 'audit_repo', script: AUDIT_REPO_SCRIPT },\n { name: 'multi_perspective_review', script: MULTI_PERSPECTIVE_REVIEW_SCRIPT },\n { name: 'research', script: RESEARCH_SCRIPT },\n]);\n\nexport {
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../../../../../src/agent/workflow/builtins/index.ts"],"sourcesContent":["/**\n * Bundled workflow templates. These are shipped with xopc and discoverable\n * via the catalog alongside user workflows in `~/.xopc/workflows/`. A user\n * workflow with the same `name` always wins — built-ins are starting points,\n * not authority.\n */\n\nimport { AUDIT_REPO_SCRIPT } from './audit-repo.js';\nimport { DEBUG_INCIDENT_SCRIPT } from './debug-incident.js';\nimport { MULTI_PERSPECTIVE_REVIEW_SCRIPT } from './multi-perspective-review.js';\nimport { PR_REVIEW_SCRIPT } from './pr-review.js';\nimport { RESEARCH_SCRIPT } from './research.js';\n\nexport interface BuiltinWorkflow {\n name: string;\n script: string;\n}\n\nexport const BUILTIN_WORKFLOWS: readonly BuiltinWorkflow[] = Object.freeze([\n { name: 'audit_repo', script: AUDIT_REPO_SCRIPT },\n { name: 'debug_incident', script: DEBUG_INCIDENT_SCRIPT },\n { name: 'multi_perspective_review', script: MULTI_PERSPECTIVE_REVIEW_SCRIPT },\n { name: 'pr_review', script: PR_REVIEW_SCRIPT },\n { name: 'research', script: RESEARCH_SCRIPT },\n]);\n\nexport {\n AUDIT_REPO_SCRIPT,\n DEBUG_INCIDENT_SCRIPT,\n MULTI_PERSPECTIVE_REVIEW_SCRIPT,\n PR_REVIEW_SCRIPT,\n RESEARCH_SCRIPT,\n};\n"],"mappings":";;;;;;;;;;;;AAkBA,MAAa,oBAAgD,OAAO,OAAO;CACzE;EAAE,MAAM;EAAc,QAAQ;EAAmB;CACjD;EAAE,MAAM;EAAkB,QAAQ;EAAuB;CACzD;EAAE,MAAM;EAA4B,QAAQ;EAAiC;CAC7E;EAAE,MAAM;EAAa,QAAQ;EAAkB;CAC/C;EAAE,MAAM;EAAY,QAAQ;EAAiB;CAC9C,CAAC"}
|
|
@@ -5,5 +5,10 @@
|
|
|
5
5
|
* several independent perspectives, then asks an adversarial judge to decide
|
|
6
6
|
* what would actually break in practice. Useful for sanity-checking decisions
|
|
7
7
|
* before they ship.
|
|
8
|
+
*
|
|
9
|
+
* Args:
|
|
10
|
+
* - target: what to review
|
|
11
|
+
* - lenses: optional array of { name, angle } to override default lenses
|
|
12
|
+
* - skipAdversarial: when true, skip the adversarial judge phase
|
|
8
13
|
*/
|
|
9
|
-
export declare const MULTI_PERSPECTIVE_REVIEW_SCRIPT = "export const meta = {\n name: 'multi_perspective_review',\n description: 'Review a target from N independent perspectives, then adversarially judge what would actually break.',\n whenToUse: 'User wants a stress-test of a design, plan, PR, or proposal before committing to it.',\n phases: [\n { title: 'Lenses' },\n { title: 'Adversarial' },\n { title: 'Synthesize' },\n ],\n}\n\nconst target = args && typeof args === 'object' && args.target\n ? String(args.target)\n : 'No explicit target was provided. Treat the currently focused file or recent context as the target.'\n\nconst
|
|
14
|
+
export declare const MULTI_PERSPECTIVE_REVIEW_SCRIPT = "export const meta = {\n name: 'multi_perspective_review',\n description: 'Review a target from N independent perspectives, then adversarially judge what would actually break.',\n whenToUse: 'User wants a stress-test of a design, plan, PR, or proposal before committing to it.',\n tags: ['review', 'planning', 'decision'],\n estimatedAgents: { min: 5, max: 6 },\n phases: [\n { title: 'Lenses' },\n { title: 'Adversarial' },\n { title: 'Synthesize' },\n ],\n}\n\nconst READ_ONLY_TOOLS = ['read_file', 'grep', 'find', 'list_dir']\n\nconst target = args && typeof args === 'object' && args.target\n ? String(args.target)\n : 'No explicit target was provided. Treat the currently focused file or recent context as the target.'\n\nconst skipAdversarial = Boolean(args && typeof args === 'object' && args.skipAdversarial)\n\nconst DEFAULT_LENSES = [\n { name: 'User', angle: 'How a real user experiences this. Friction, confusion, surprise paths, accessibility.' },\n { name: 'Operator', angle: 'How an on-call engineer experiences this in production. Failure modes, observability, rollback.' },\n { name: 'Skeptic', angle: 'Hidden assumptions. What is being implied but not stated. What would break under load or weird input.' },\n { name: 'Maintainer', angle: 'Six-month-later view. Clarity, naming, layering, ease of changing nearby code.' },\n]\n\nlet lenses = DEFAULT_LENSES\nif (args && typeof args === 'object' && Array.isArray(args.lenses) && args.lenses.length) {\n lenses = args.lenses\n .filter((l) => l && typeof l === 'object' && l.name && l.angle)\n .map((l) => ({ name: String(l.name), angle: String(l.angle) }))\n if (!lenses.length) lenses = DEFAULT_LENSES\n}\n\nphase('Lenses')\nconst lensViews = await parallel(\n lenses.map((l) => () =>\n agent(\n 'Review the following target through the ' + l.name + ' lens.\\n' +\n 'Lens focus: ' + l.angle + '\\n\\n' +\n 'TARGET:\\n' + target + '\\n\\n' +\n 'Return 3\u20137 concrete observations. Each entry: title (5\u201310 words), why-it-matters (1 sentence), risk (low/med/high).',\n {\n label: l.name + ' lens',\n toolset: READ_ONLY_TOOLS,\n schema: {\n type: 'object',\n properties: {\n observations: {\n type: 'array',\n items: {\n type: 'object',\n properties: {\n title: { type: 'string' },\n why: { type: 'string' },\n risk: { type: 'string', enum: ['low', 'med', 'high'] },\n },\n required: ['title', 'why', 'risk'],\n },\n },\n },\n required: ['observations'],\n },\n },\n ),\n ),\n)\n\nconst valid = lensViews.filter(Boolean)\nconst allObs = valid.flatMap((v, i) =>\n (v?.observations ?? []).map((o) => ({ lens: lenses[i].name, ...o })),\n)\n\nlet verdict = null\nif (!skipAdversarial) {\n phase('Adversarial')\n verdict = await agent(\n 'You are an adversarial judge. Given these multi-lens observations of a target, decide which would actually cause real harm if shipped as-is. ' +\n 'Default to realRisk=false unless an observation has clear, mechanism-level evidence. ' +\n 'Rate evidenceStrength as weak | moderate | strong.\\n\\n' +\n JSON.stringify(allObs, null, 2),\n {\n label: 'adversarial verdict',\n schema: {\n type: 'object',\n properties: {\n verdicts: {\n type: 'array',\n items: {\n type: 'object',\n properties: {\n title: { type: 'string' },\n lens: { type: 'string' },\n realRisk: { type: 'boolean' },\n evidenceStrength: { type: 'string', enum: ['weak', 'moderate', 'strong'] },\n reason: { type: 'string' },\n },\n required: ['title', 'lens', 'realRisk', 'evidenceStrength', 'reason'],\n },\n },\n },\n required: ['verdicts'],\n },\n },\n )\n}\n\nphase('Synthesize')\nconst confirmed = (verdict?.verdicts ?? []).filter((v) => v.realRisk)\nconst goNoGo = skipAdversarial\n ? (allObs.some((o) => o.risk === 'high') ? 'fix_first' : 'ship')\n : confirmed.some((v) => v.evidenceStrength === 'strong')\n ? 'fix_first'\n : confirmed.length\n ? 'fix_first'\n : 'ship'\n\nreturn {\n ok: true,\n target,\n lenses: lenses.map((l) => l.name),\n skipAdversarial,\n observationCount: allObs.length,\n confirmedRiskCount: confirmed.length,\n goNoGo,\n topRisks: confirmed.slice(0, 10),\n allVerdicts: verdict?.verdicts ?? [],\n}\n";
|
|
@@ -6,11 +6,18 @@
|
|
|
6
6
|
* several independent perspectives, then asks an adversarial judge to decide
|
|
7
7
|
* what would actually break in practice. Useful for sanity-checking decisions
|
|
8
8
|
* before they ship.
|
|
9
|
+
*
|
|
10
|
+
* Args:
|
|
11
|
+
* - target: what to review
|
|
12
|
+
* - lenses: optional array of { name, angle } to override default lenses
|
|
13
|
+
* - skipAdversarial: when true, skip the adversarial judge phase
|
|
9
14
|
*/
|
|
10
15
|
const MULTI_PERSPECTIVE_REVIEW_SCRIPT = `export const meta = {
|
|
11
16
|
name: 'multi_perspective_review',
|
|
12
17
|
description: 'Review a target from N independent perspectives, then adversarially judge what would actually break.',
|
|
13
18
|
whenToUse: 'User wants a stress-test of a design, plan, PR, or proposal before committing to it.',
|
|
19
|
+
tags: ['review', 'planning', 'decision'],
|
|
20
|
+
estimatedAgents: { min: 5, max: 6 },
|
|
14
21
|
phases: [
|
|
15
22
|
{ title: 'Lenses' },
|
|
16
23
|
{ title: 'Adversarial' },
|
|
@@ -18,20 +25,32 @@ const MULTI_PERSPECTIVE_REVIEW_SCRIPT = `export const meta = {
|
|
|
18
25
|
],
|
|
19
26
|
}
|
|
20
27
|
|
|
28
|
+
const READ_ONLY_TOOLS = ['read_file', 'grep', 'find', 'list_dir']
|
|
29
|
+
|
|
21
30
|
const target = args && typeof args === 'object' && args.target
|
|
22
31
|
? String(args.target)
|
|
23
32
|
: 'No explicit target was provided. Treat the currently focused file or recent context as the target.'
|
|
24
33
|
|
|
25
|
-
const
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
{ name: '
|
|
29
|
-
{ name: '
|
|
34
|
+
const skipAdversarial = Boolean(args && typeof args === 'object' && args.skipAdversarial)
|
|
35
|
+
|
|
36
|
+
const DEFAULT_LENSES = [
|
|
37
|
+
{ name: 'User', angle: 'How a real user experiences this. Friction, confusion, surprise paths, accessibility.' },
|
|
38
|
+
{ name: 'Operator', angle: 'How an on-call engineer experiences this in production. Failure modes, observability, rollback.' },
|
|
39
|
+
{ name: 'Skeptic', angle: 'Hidden assumptions. What is being implied but not stated. What would break under load or weird input.' },
|
|
40
|
+
{ name: 'Maintainer', angle: 'Six-month-later view. Clarity, naming, layering, ease of changing nearby code.' },
|
|
30
41
|
]
|
|
31
42
|
|
|
43
|
+
let lenses = DEFAULT_LENSES
|
|
44
|
+
if (args && typeof args === 'object' && Array.isArray(args.lenses) && args.lenses.length) {
|
|
45
|
+
lenses = args.lenses
|
|
46
|
+
.filter((l) => l && typeof l === 'object' && l.name && l.angle)
|
|
47
|
+
.map((l) => ({ name: String(l.name), angle: String(l.angle) }))
|
|
48
|
+
if (!lenses.length) lenses = DEFAULT_LENSES
|
|
49
|
+
}
|
|
50
|
+
|
|
32
51
|
phase('Lenses')
|
|
33
52
|
const lensViews = await parallel(
|
|
34
|
-
|
|
53
|
+
lenses.map((l) => () =>
|
|
35
54
|
agent(
|
|
36
55
|
'Review the following target through the ' + l.name + ' lens.\\n' +
|
|
37
56
|
'Lens focus: ' + l.angle + '\\n\\n' +
|
|
@@ -39,6 +58,7 @@ const lensViews = await parallel(
|
|
|
39
58
|
'Return 3–7 concrete observations. Each entry: title (5–10 words), why-it-matters (1 sentence), risk (low/med/high).',
|
|
40
59
|
{
|
|
41
60
|
label: l.name + ' lens',
|
|
61
|
+
toolset: READ_ONLY_TOOLS,
|
|
42
62
|
schema: {
|
|
43
63
|
type: 'object',
|
|
44
64
|
properties: {
|
|
@@ -62,47 +82,63 @@ const lensViews = await parallel(
|
|
|
62
82
|
),
|
|
63
83
|
)
|
|
64
84
|
|
|
65
|
-
phase('Adversarial')
|
|
66
85
|
const valid = lensViews.filter(Boolean)
|
|
67
86
|
const allObs = valid.flatMap((v, i) =>
|
|
68
|
-
(v?.observations ?? []).map((o) => ({ lens:
|
|
87
|
+
(v?.observations ?? []).map((o) => ({ lens: lenses[i].name, ...o })),
|
|
69
88
|
)
|
|
70
89
|
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
90
|
+
let verdict = null
|
|
91
|
+
if (!skipAdversarial) {
|
|
92
|
+
phase('Adversarial')
|
|
93
|
+
verdict = await agent(
|
|
94
|
+
'You are an adversarial judge. Given these multi-lens observations of a target, decide which would actually cause real harm if shipped as-is. ' +
|
|
95
|
+
'Default to realRisk=false unless an observation has clear, mechanism-level evidence. ' +
|
|
96
|
+
'Rate evidenceStrength as weak | moderate | strong.\\n\\n' +
|
|
97
|
+
JSON.stringify(allObs, null, 2),
|
|
98
|
+
{
|
|
99
|
+
label: 'adversarial verdict',
|
|
100
|
+
schema: {
|
|
101
|
+
type: 'object',
|
|
102
|
+
properties: {
|
|
103
|
+
verdicts: {
|
|
104
|
+
type: 'array',
|
|
105
|
+
items: {
|
|
106
|
+
type: 'object',
|
|
107
|
+
properties: {
|
|
108
|
+
title: { type: 'string' },
|
|
109
|
+
lens: { type: 'string' },
|
|
110
|
+
realRisk: { type: 'boolean' },
|
|
111
|
+
evidenceStrength: { type: 'string', enum: ['weak', 'moderate', 'strong'] },
|
|
112
|
+
reason: { type: 'string' },
|
|
113
|
+
},
|
|
114
|
+
required: ['title', 'lens', 'realRisk', 'evidenceStrength', 'reason'],
|
|
89
115
|
},
|
|
90
|
-
required: ['title', 'lens', 'realRisk', 'reason'],
|
|
91
116
|
},
|
|
92
117
|
},
|
|
118
|
+
required: ['verdicts'],
|
|
93
119
|
},
|
|
94
|
-
required: ['verdicts'],
|
|
95
120
|
},
|
|
96
|
-
|
|
97
|
-
|
|
121
|
+
)
|
|
122
|
+
}
|
|
98
123
|
|
|
99
124
|
phase('Synthesize')
|
|
100
125
|
const confirmed = (verdict?.verdicts ?? []).filter((v) => v.realRisk)
|
|
126
|
+
const goNoGo = skipAdversarial
|
|
127
|
+
? (allObs.some((o) => o.risk === 'high') ? 'fix_first' : 'ship')
|
|
128
|
+
: confirmed.some((v) => v.evidenceStrength === 'strong')
|
|
129
|
+
? 'fix_first'
|
|
130
|
+
: confirmed.length
|
|
131
|
+
? 'fix_first'
|
|
132
|
+
: 'ship'
|
|
133
|
+
|
|
101
134
|
return {
|
|
102
135
|
ok: true,
|
|
103
136
|
target,
|
|
137
|
+
lenses: lenses.map((l) => l.name),
|
|
138
|
+
skipAdversarial,
|
|
104
139
|
observationCount: allObs.length,
|
|
105
140
|
confirmedRiskCount: confirmed.length,
|
|
141
|
+
goNoGo,
|
|
106
142
|
topRisks: confirmed.slice(0, 10),
|
|
107
143
|
allVerdicts: verdict?.verdicts ?? [],
|
|
108
144
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"multi-perspective-review.js","names":[],"sources":["../../../../../src/agent/workflow/builtins/multi-perspective-review.ts"],"sourcesContent":["/**\n * Built-in workflow: `multi_perspective_review`\n *\n * Reviews a target (file, PR, design doc, plan — passed via args.target) from\n * several independent perspectives, then asks an adversarial judge to decide\n * what would actually break in practice. Useful for sanity-checking decisions\n * before they ship.\n */\n\nexport const MULTI_PERSPECTIVE_REVIEW_SCRIPT = `export const meta = {\n name: 'multi_perspective_review',\n description: 'Review a target from N independent perspectives, then adversarially judge what would actually break.',\n whenToUse: 'User wants a stress-test of a design, plan, PR, or proposal before committing to it.',\n phases: [\n { title: 'Lenses' },\n { title: 'Adversarial' },\n { title: 'Synthesize' },\n ],\n}\n\nconst target = args && typeof args === 'object' && args.target\n ? String(args.target)\n : 'No explicit target was provided. Treat the currently focused file or recent context as the target.'\n\nconst
|
|
1
|
+
{"version":3,"file":"multi-perspective-review.js","names":[],"sources":["../../../../../src/agent/workflow/builtins/multi-perspective-review.ts"],"sourcesContent":["/**\n * Built-in workflow: `multi_perspective_review`\n *\n * Reviews a target (file, PR, design doc, plan — passed via args.target) from\n * several independent perspectives, then asks an adversarial judge to decide\n * what would actually break in practice. Useful for sanity-checking decisions\n * before they ship.\n *\n * Args:\n * - target: what to review\n * - lenses: optional array of { name, angle } to override default lenses\n * - skipAdversarial: when true, skip the adversarial judge phase\n */\n\nexport const MULTI_PERSPECTIVE_REVIEW_SCRIPT = `export const meta = {\n name: 'multi_perspective_review',\n description: 'Review a target from N independent perspectives, then adversarially judge what would actually break.',\n whenToUse: 'User wants a stress-test of a design, plan, PR, or proposal before committing to it.',\n tags: ['review', 'planning', 'decision'],\n estimatedAgents: { min: 5, max: 6 },\n phases: [\n { title: 'Lenses' },\n { title: 'Adversarial' },\n { title: 'Synthesize' },\n ],\n}\n\nconst READ_ONLY_TOOLS = ['read_file', 'grep', 'find', 'list_dir']\n\nconst target = args && typeof args === 'object' && args.target\n ? String(args.target)\n : 'No explicit target was provided. Treat the currently focused file or recent context as the target.'\n\nconst skipAdversarial = Boolean(args && typeof args === 'object' && args.skipAdversarial)\n\nconst DEFAULT_LENSES = [\n { name: 'User', angle: 'How a real user experiences this. Friction, confusion, surprise paths, accessibility.' },\n { name: 'Operator', angle: 'How an on-call engineer experiences this in production. Failure modes, observability, rollback.' },\n { name: 'Skeptic', angle: 'Hidden assumptions. What is being implied but not stated. What would break under load or weird input.' },\n { name: 'Maintainer', angle: 'Six-month-later view. Clarity, naming, layering, ease of changing nearby code.' },\n]\n\nlet lenses = DEFAULT_LENSES\nif (args && typeof args === 'object' && Array.isArray(args.lenses) && args.lenses.length) {\n lenses = args.lenses\n .filter((l) => l && typeof l === 'object' && l.name && l.angle)\n .map((l) => ({ name: String(l.name), angle: String(l.angle) }))\n if (!lenses.length) lenses = DEFAULT_LENSES\n}\n\nphase('Lenses')\nconst lensViews = await parallel(\n lenses.map((l) => () =>\n agent(\n 'Review the following target through the ' + l.name + ' lens.\\\\n' +\n 'Lens focus: ' + l.angle + '\\\\n\\\\n' +\n 'TARGET:\\\\n' + target + '\\\\n\\\\n' +\n 'Return 3–7 concrete observations. Each entry: title (5–10 words), why-it-matters (1 sentence), risk (low/med/high).',\n {\n label: l.name + ' lens',\n toolset: READ_ONLY_TOOLS,\n schema: {\n type: 'object',\n properties: {\n observations: {\n type: 'array',\n items: {\n type: 'object',\n properties: {\n title: { type: 'string' },\n why: { type: 'string' },\n risk: { type: 'string', enum: ['low', 'med', 'high'] },\n },\n required: ['title', 'why', 'risk'],\n },\n },\n },\n required: ['observations'],\n },\n },\n ),\n ),\n)\n\nconst valid = lensViews.filter(Boolean)\nconst allObs = valid.flatMap((v, i) =>\n (v?.observations ?? []).map((o) => ({ lens: lenses[i].name, ...o })),\n)\n\nlet verdict = null\nif (!skipAdversarial) {\n phase('Adversarial')\n verdict = await agent(\n 'You are an adversarial judge. Given these multi-lens observations of a target, decide which would actually cause real harm if shipped as-is. ' +\n 'Default to realRisk=false unless an observation has clear, mechanism-level evidence. ' +\n 'Rate evidenceStrength as weak | moderate | strong.\\\\n\\\\n' +\n JSON.stringify(allObs, null, 2),\n {\n label: 'adversarial verdict',\n schema: {\n type: 'object',\n properties: {\n verdicts: {\n type: 'array',\n items: {\n type: 'object',\n properties: {\n title: { type: 'string' },\n lens: { type: 'string' },\n realRisk: { type: 'boolean' },\n evidenceStrength: { type: 'string', enum: ['weak', 'moderate', 'strong'] },\n reason: { type: 'string' },\n },\n required: ['title', 'lens', 'realRisk', 'evidenceStrength', 'reason'],\n },\n },\n },\n required: ['verdicts'],\n },\n },\n )\n}\n\nphase('Synthesize')\nconst confirmed = (verdict?.verdicts ?? []).filter((v) => v.realRisk)\nconst goNoGo = skipAdversarial\n ? (allObs.some((o) => o.risk === 'high') ? 'fix_first' : 'ship')\n : confirmed.some((v) => v.evidenceStrength === 'strong')\n ? 'fix_first'\n : confirmed.length\n ? 'fix_first'\n : 'ship'\n\nreturn {\n ok: true,\n target,\n lenses: lenses.map((l) => l.name),\n skipAdversarial,\n observationCount: allObs.length,\n confirmedRiskCount: confirmed.length,\n goNoGo,\n topRisks: confirmed.slice(0, 10),\n allVerdicts: verdict?.verdicts ?? [],\n}\n`\n"],"mappings":";;;;;;;;;;;;;;AAcA,MAAa,kCAAkC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Built-in workflow: `pr_review`
|
|
3
|
+
*
|
|
4
|
+
* Focused review of a PR, diff, or commit range — lighter than full repo audit.
|
|
5
|
+
* Parallel reviewers cover correctness, security, tests, API compat, and perf;
|
|
6
|
+
* final phase produces a ship/block verdict with blockers vs suggestions.
|
|
7
|
+
*
|
|
8
|
+
* Args:
|
|
9
|
+
* - target: PR description, diff, commit range, or file list
|
|
10
|
+
* - diff: alias for target
|
|
11
|
+
*/
|
|
12
|
+
export declare const PR_REVIEW_SCRIPT = "export const meta = {\n name: 'pr_review',\n description: 'Review a PR/diff/commit range with parallel focused reviewers and a ship/block verdict.',\n whenToUse: 'User asks to review a PR, diff, specific changes, or commit range (not the whole repo).',\n tags: ['code-review', 'pr'],\n estimatedAgents: { min: 7, max: 7 },\n phases: [\n { title: 'Scope' },\n { title: 'Review' },\n { title: 'Verdict' },\n ],\n}\n\nconst READ_ONLY_TOOLS = ['read_file', 'grep', 'find', 'list_dir', 'shell']\n\nconst target = args && typeof args === 'object'\n ? String(args.target ?? args.diff ?? '')\n : ''\nconst reviewTarget = target.trim()\n ? target\n : 'Recent changes in the working tree or the diff/context from the current conversation.'\n\nconst REVIEWERS = [\n { key: 'correctness', focus: 'Logic bugs, edge cases, error handling, null safety, race conditions in changed code.' },\n { key: 'security', focus: 'Auth/authz regressions, input validation, secret exposure, injection, unsafe deserialization in the diff.' },\n { key: 'tests', focus: 'Missing tests for changed behavior, brittle assertions, untested edge cases introduced by this change.' },\n { key: 'api_compat', focus: 'Breaking public API changes, schema migrations, backward compatibility, deprecation handling.' },\n { key: 'perf', focus: 'Regressions in hot paths, accidental N+1, sync I/O, unbounded loops or allocations in changed code.' },\n]\n\nphase('Scope')\nconst scope = await agent(\n 'Identify what changed for this review target. List changed files, blast radius (what depends on them), and the apparent intent of the change. Be concise.\\n\\nTARGET:\\n' +\n reviewTarget,\n {\n label: 'change scope',\n toolset: READ_ONLY_TOOLS,\n schema: {\n type: 'object',\n properties: {\n changedFiles: { type: 'array', items: { type: 'string' } },\n intent: { type: 'string' },\n blastRadius: { type: 'string' },\n },\n required: ['changedFiles', 'intent'],\n },\n },\n)\n\nphase('Review')\nconst reviews = await parallel(\n REVIEWERS.map((r) => () =>\n agent(\n 'Review these changes through the ' + r.key + ' lens.\\n' +\n 'Focus: ' + r.focus + '\\n\\n' +\n 'TARGET:\\n' + reviewTarget + '\\n\\n' +\n 'SCOPE:\\n' + JSON.stringify(scope, null, 2) + '\\n\\n' +\n 'Return findings: file, severity (low/med/high/blocker), title, fix suggestion. Blocker = must fix before merge.',\n {\n label: r.key,\n toolset: READ_ONLY_TOOLS,\n schema: {\n type: 'object',\n properties: {\n findings: {\n type: 'array',\n items: {\n type: 'object',\n properties: {\n file: { type: 'string' },\n severity: { type: 'string', enum: ['low', 'med', 'high', 'blocker'] },\n title: { type: 'string' },\n fix: { type: 'string' },\n },\n required: ['file', 'severity', 'title', 'fix'],\n },\n },\n },\n required: ['findings'],\n },\n },\n ),\n ),\n)\n\nphase('Verdict')\nconst live = reviews.filter(Boolean)\nconst byReviewer = {}\nfor (let i = 0; i < REVIEWERS.length; i++) {\n byReviewer[REVIEWERS[i].key] = live[i]?.findings ?? []\n}\n\nconst verdict = await agent(\n 'Synthesize a PR review verdict. Separate blockers from suggestions. Deduplicate. Recommend ship | fix_first | block.\\n\\n' +\n JSON.stringify(byReviewer, null, 2),\n {\n label: 'verdict',\n schema: {\n type: 'object',\n properties: {\n recommendation: { type: 'string', enum: ['ship', 'fix_first', 'block'] },\n summary: { type: 'string' },\n blockers: {\n type: 'array',\n items: {\n type: 'object',\n properties: {\n file: { type: 'string' },\n title: { type: 'string' },\n fix: { type: 'string' },\n },\n required: ['file', 'title'],\n },\n },\n suggestions: {\n type: 'array',\n items: {\n type: 'object',\n properties: {\n file: { type: 'string' },\n severity: { type: 'string' },\n title: { type: 'string' },\n },\n required: ['file', 'title'],\n },\n },\n },\n required: ['recommendation', 'summary', 'blockers'],\n },\n },\n)\n\nreturn {\n ok: true,\n target: reviewTarget,\n scope,\n ...(verdict ?? { recommendation: 'fix_first', summary: 'verdict failed', blockers: [], suggestions: [] }),\n byReviewer,\n}\n";
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
//#region src/agent/workflow/builtins/pr-review.ts
|
|
2
|
+
/**
|
|
3
|
+
* Built-in workflow: `pr_review`
|
|
4
|
+
*
|
|
5
|
+
* Focused review of a PR, diff, or commit range — lighter than full repo audit.
|
|
6
|
+
* Parallel reviewers cover correctness, security, tests, API compat, and perf;
|
|
7
|
+
* final phase produces a ship/block verdict with blockers vs suggestions.
|
|
8
|
+
*
|
|
9
|
+
* Args:
|
|
10
|
+
* - target: PR description, diff, commit range, or file list
|
|
11
|
+
* - diff: alias for target
|
|
12
|
+
*/
|
|
13
|
+
const PR_REVIEW_SCRIPT = `export const meta = {
|
|
14
|
+
name: 'pr_review',
|
|
15
|
+
description: 'Review a PR/diff/commit range with parallel focused reviewers and a ship/block verdict.',
|
|
16
|
+
whenToUse: 'User asks to review a PR, diff, specific changes, or commit range (not the whole repo).',
|
|
17
|
+
tags: ['code-review', 'pr'],
|
|
18
|
+
estimatedAgents: { min: 7, max: 7 },
|
|
19
|
+
phases: [
|
|
20
|
+
{ title: 'Scope' },
|
|
21
|
+
{ title: 'Review' },
|
|
22
|
+
{ title: 'Verdict' },
|
|
23
|
+
],
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
const READ_ONLY_TOOLS = ['read_file', 'grep', 'find', 'list_dir', 'shell']
|
|
27
|
+
|
|
28
|
+
const target = args && typeof args === 'object'
|
|
29
|
+
? String(args.target ?? args.diff ?? '')
|
|
30
|
+
: ''
|
|
31
|
+
const reviewTarget = target.trim()
|
|
32
|
+
? target
|
|
33
|
+
: 'Recent changes in the working tree or the diff/context from the current conversation.'
|
|
34
|
+
|
|
35
|
+
const REVIEWERS = [
|
|
36
|
+
{ key: 'correctness', focus: 'Logic bugs, edge cases, error handling, null safety, race conditions in changed code.' },
|
|
37
|
+
{ key: 'security', focus: 'Auth/authz regressions, input validation, secret exposure, injection, unsafe deserialization in the diff.' },
|
|
38
|
+
{ key: 'tests', focus: 'Missing tests for changed behavior, brittle assertions, untested edge cases introduced by this change.' },
|
|
39
|
+
{ key: 'api_compat', focus: 'Breaking public API changes, schema migrations, backward compatibility, deprecation handling.' },
|
|
40
|
+
{ key: 'perf', focus: 'Regressions in hot paths, accidental N+1, sync I/O, unbounded loops or allocations in changed code.' },
|
|
41
|
+
]
|
|
42
|
+
|
|
43
|
+
phase('Scope')
|
|
44
|
+
const scope = await agent(
|
|
45
|
+
'Identify what changed for this review target. List changed files, blast radius (what depends on them), and the apparent intent of the change. Be concise.\\n\\nTARGET:\\n' +
|
|
46
|
+
reviewTarget,
|
|
47
|
+
{
|
|
48
|
+
label: 'change scope',
|
|
49
|
+
toolset: READ_ONLY_TOOLS,
|
|
50
|
+
schema: {
|
|
51
|
+
type: 'object',
|
|
52
|
+
properties: {
|
|
53
|
+
changedFiles: { type: 'array', items: { type: 'string' } },
|
|
54
|
+
intent: { type: 'string' },
|
|
55
|
+
blastRadius: { type: 'string' },
|
|
56
|
+
},
|
|
57
|
+
required: ['changedFiles', 'intent'],
|
|
58
|
+
},
|
|
59
|
+
},
|
|
60
|
+
)
|
|
61
|
+
|
|
62
|
+
phase('Review')
|
|
63
|
+
const reviews = await parallel(
|
|
64
|
+
REVIEWERS.map((r) => () =>
|
|
65
|
+
agent(
|
|
66
|
+
'Review these changes through the ' + r.key + ' lens.\\n' +
|
|
67
|
+
'Focus: ' + r.focus + '\\n\\n' +
|
|
68
|
+
'TARGET:\\n' + reviewTarget + '\\n\\n' +
|
|
69
|
+
'SCOPE:\\n' + JSON.stringify(scope, null, 2) + '\\n\\n' +
|
|
70
|
+
'Return findings: file, severity (low/med/high/blocker), title, fix suggestion. Blocker = must fix before merge.',
|
|
71
|
+
{
|
|
72
|
+
label: r.key,
|
|
73
|
+
toolset: READ_ONLY_TOOLS,
|
|
74
|
+
schema: {
|
|
75
|
+
type: 'object',
|
|
76
|
+
properties: {
|
|
77
|
+
findings: {
|
|
78
|
+
type: 'array',
|
|
79
|
+
items: {
|
|
80
|
+
type: 'object',
|
|
81
|
+
properties: {
|
|
82
|
+
file: { type: 'string' },
|
|
83
|
+
severity: { type: 'string', enum: ['low', 'med', 'high', 'blocker'] },
|
|
84
|
+
title: { type: 'string' },
|
|
85
|
+
fix: { type: 'string' },
|
|
86
|
+
},
|
|
87
|
+
required: ['file', 'severity', 'title', 'fix'],
|
|
88
|
+
},
|
|
89
|
+
},
|
|
90
|
+
},
|
|
91
|
+
required: ['findings'],
|
|
92
|
+
},
|
|
93
|
+
},
|
|
94
|
+
),
|
|
95
|
+
),
|
|
96
|
+
)
|
|
97
|
+
|
|
98
|
+
phase('Verdict')
|
|
99
|
+
const live = reviews.filter(Boolean)
|
|
100
|
+
const byReviewer = {}
|
|
101
|
+
for (let i = 0; i < REVIEWERS.length; i++) {
|
|
102
|
+
byReviewer[REVIEWERS[i].key] = live[i]?.findings ?? []
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
const verdict = await agent(
|
|
106
|
+
'Synthesize a PR review verdict. Separate blockers from suggestions. Deduplicate. Recommend ship | fix_first | block.\\n\\n' +
|
|
107
|
+
JSON.stringify(byReviewer, null, 2),
|
|
108
|
+
{
|
|
109
|
+
label: 'verdict',
|
|
110
|
+
schema: {
|
|
111
|
+
type: 'object',
|
|
112
|
+
properties: {
|
|
113
|
+
recommendation: { type: 'string', enum: ['ship', 'fix_first', 'block'] },
|
|
114
|
+
summary: { type: 'string' },
|
|
115
|
+
blockers: {
|
|
116
|
+
type: 'array',
|
|
117
|
+
items: {
|
|
118
|
+
type: 'object',
|
|
119
|
+
properties: {
|
|
120
|
+
file: { type: 'string' },
|
|
121
|
+
title: { type: 'string' },
|
|
122
|
+
fix: { type: 'string' },
|
|
123
|
+
},
|
|
124
|
+
required: ['file', 'title'],
|
|
125
|
+
},
|
|
126
|
+
},
|
|
127
|
+
suggestions: {
|
|
128
|
+
type: 'array',
|
|
129
|
+
items: {
|
|
130
|
+
type: 'object',
|
|
131
|
+
properties: {
|
|
132
|
+
file: { type: 'string' },
|
|
133
|
+
severity: { type: 'string' },
|
|
134
|
+
title: { type: 'string' },
|
|
135
|
+
},
|
|
136
|
+
required: ['file', 'title'],
|
|
137
|
+
},
|
|
138
|
+
},
|
|
139
|
+
},
|
|
140
|
+
required: ['recommendation', 'summary', 'blockers'],
|
|
141
|
+
},
|
|
142
|
+
},
|
|
143
|
+
)
|
|
144
|
+
|
|
145
|
+
return {
|
|
146
|
+
ok: true,
|
|
147
|
+
target: reviewTarget,
|
|
148
|
+
scope,
|
|
149
|
+
...(verdict ?? { recommendation: 'fix_first', summary: 'verdict failed', blockers: [], suggestions: [] }),
|
|
150
|
+
byReviewer,
|
|
151
|
+
}
|
|
152
|
+
`;
|
|
153
|
+
//#endregion
|
|
154
|
+
export { PR_REVIEW_SCRIPT };
|
|
155
|
+
|
|
156
|
+
//# sourceMappingURL=pr-review.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pr-review.js","names":[],"sources":["../../../../../src/agent/workflow/builtins/pr-review.ts"],"sourcesContent":["/**\n * Built-in workflow: `pr_review`\n *\n * Focused review of a PR, diff, or commit range — lighter than full repo audit.\n * Parallel reviewers cover correctness, security, tests, API compat, and perf;\n * final phase produces a ship/block verdict with blockers vs suggestions.\n *\n * Args:\n * - target: PR description, diff, commit range, or file list\n * - diff: alias for target\n */\n\nexport const PR_REVIEW_SCRIPT = `export const meta = {\n name: 'pr_review',\n description: 'Review a PR/diff/commit range with parallel focused reviewers and a ship/block verdict.',\n whenToUse: 'User asks to review a PR, diff, specific changes, or commit range (not the whole repo).',\n tags: ['code-review', 'pr'],\n estimatedAgents: { min: 7, max: 7 },\n phases: [\n { title: 'Scope' },\n { title: 'Review' },\n { title: 'Verdict' },\n ],\n}\n\nconst READ_ONLY_TOOLS = ['read_file', 'grep', 'find', 'list_dir', 'shell']\n\nconst target = args && typeof args === 'object'\n ? String(args.target ?? args.diff ?? '')\n : ''\nconst reviewTarget = target.trim()\n ? target\n : 'Recent changes in the working tree or the diff/context from the current conversation.'\n\nconst REVIEWERS = [\n { key: 'correctness', focus: 'Logic bugs, edge cases, error handling, null safety, race conditions in changed code.' },\n { key: 'security', focus: 'Auth/authz regressions, input validation, secret exposure, injection, unsafe deserialization in the diff.' },\n { key: 'tests', focus: 'Missing tests for changed behavior, brittle assertions, untested edge cases introduced by this change.' },\n { key: 'api_compat', focus: 'Breaking public API changes, schema migrations, backward compatibility, deprecation handling.' },\n { key: 'perf', focus: 'Regressions in hot paths, accidental N+1, sync I/O, unbounded loops or allocations in changed code.' },\n]\n\nphase('Scope')\nconst scope = await agent(\n 'Identify what changed for this review target. List changed files, blast radius (what depends on them), and the apparent intent of the change. Be concise.\\\\n\\\\nTARGET:\\\\n' +\n reviewTarget,\n {\n label: 'change scope',\n toolset: READ_ONLY_TOOLS,\n schema: {\n type: 'object',\n properties: {\n changedFiles: { type: 'array', items: { type: 'string' } },\n intent: { type: 'string' },\n blastRadius: { type: 'string' },\n },\n required: ['changedFiles', 'intent'],\n },\n },\n)\n\nphase('Review')\nconst reviews = await parallel(\n REVIEWERS.map((r) => () =>\n agent(\n 'Review these changes through the ' + r.key + ' lens.\\\\n' +\n 'Focus: ' + r.focus + '\\\\n\\\\n' +\n 'TARGET:\\\\n' + reviewTarget + '\\\\n\\\\n' +\n 'SCOPE:\\\\n' + JSON.stringify(scope, null, 2) + '\\\\n\\\\n' +\n 'Return findings: file, severity (low/med/high/blocker), title, fix suggestion. Blocker = must fix before merge.',\n {\n label: r.key,\n toolset: READ_ONLY_TOOLS,\n schema: {\n type: 'object',\n properties: {\n findings: {\n type: 'array',\n items: {\n type: 'object',\n properties: {\n file: { type: 'string' },\n severity: { type: 'string', enum: ['low', 'med', 'high', 'blocker'] },\n title: { type: 'string' },\n fix: { type: 'string' },\n },\n required: ['file', 'severity', 'title', 'fix'],\n },\n },\n },\n required: ['findings'],\n },\n },\n ),\n ),\n)\n\nphase('Verdict')\nconst live = reviews.filter(Boolean)\nconst byReviewer = {}\nfor (let i = 0; i < REVIEWERS.length; i++) {\n byReviewer[REVIEWERS[i].key] = live[i]?.findings ?? []\n}\n\nconst verdict = await agent(\n 'Synthesize a PR review verdict. Separate blockers from suggestions. Deduplicate. Recommend ship | fix_first | block.\\\\n\\\\n' +\n JSON.stringify(byReviewer, null, 2),\n {\n label: 'verdict',\n schema: {\n type: 'object',\n properties: {\n recommendation: { type: 'string', enum: ['ship', 'fix_first', 'block'] },\n summary: { type: 'string' },\n blockers: {\n type: 'array',\n items: {\n type: 'object',\n properties: {\n file: { type: 'string' },\n title: { type: 'string' },\n fix: { type: 'string' },\n },\n required: ['file', 'title'],\n },\n },\n suggestions: {\n type: 'array',\n items: {\n type: 'object',\n properties: {\n file: { type: 'string' },\n severity: { type: 'string' },\n title: { type: 'string' },\n },\n required: ['file', 'title'],\n },\n },\n },\n required: ['recommendation', 'summary', 'blockers'],\n },\n },\n)\n\nreturn {\n ok: true,\n target: reviewTarget,\n scope,\n ...(verdict ?? { recommendation: 'fix_first', summary: 'verdict failed', blockers: [], suggestions: [] }),\n byReviewer,\n}\n`\n"],"mappings":";;;;;;;;;;;;AAYA,MAAa,mBAAmB"}
|