@zhushanwen/subagent-core 0.2.0 → 0.5.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +45 -2
- package/agents/analyst.md +60 -0
- package/agents/coder.md +69 -0
- package/agents/debugger.md +66 -0
- package/agents/doc-reviewer.md +49 -0
- package/agents/explorer.md +63 -0
- package/agents/general-purpose.md +32 -0
- package/agents/orchestrator.md +61 -0
- package/agents/planner.md +53 -0
- package/agents/researcher.md +67 -0
- package/agents/reviewer.md +73 -0
- package/dist/chunk-43ONBFZX.js +240 -0
- package/dist/chunk-APZY4IME.js +27 -0
- package/dist/chunk-V3VHZ2VX.js +59 -0
- package/dist/execution/engine/engines/zcode/constants.cjs +62 -9
- package/dist/execution/engine/engines/zcode/constants.d.cts +116 -12
- package/dist/execution/engine/engines/zcode/constants.d.ts +116 -12
- package/dist/execution/engine/engines/zcode/constants.js +39 -7
- package/dist/execution/engine/engines/zcode/reader.d.cts +2 -1
- package/dist/execution/engine/engines/zcode/reader.d.ts +2 -1
- package/dist/execution/engine/engines/zcode/reader.js +4 -234
- package/dist/execution/engine/paths.js +7 -19
- package/dist/index.cjs +18234 -1277
- package/dist/index.d.cts +5646 -673
- package/dist/index.d.ts +5646 -673
- package/dist/index.js +17828 -1277
- package/dist/{types-BxyAidGf.d.cts → types-Dv4QhSJ_.d.cts} +678 -112
- package/dist/{types-BxyAidGf.d.ts → types-Dv4QhSJ_.d.ts} +678 -112
- package/package.json +7 -4
- package/src/__tests__/agent-opts-resolver-schema-prompt.test.ts +0 -1
- package/src/__tests__/append-system-prompt-assembly.test.ts +8 -7
- package/src/__tests__/fr4-get-state-handshake.test.ts +2 -2
- package/src/__tests__/m2-append-content-probe.test.ts +0 -1
- package/src/__tests__/manifest-store.test.ts +10 -9
- package/src/__tests__/record-store-cache.test.ts +0 -2
- package/src/__tests__/record-store-index.test.ts +1 -2
- package/src/__tests__/review-fix-loop-script.test.ts +93 -3
- package/src/__tests__/review-fix-loop-utils.test.ts +31 -10
- package/src/__tests__/robustness-low-batch1.test.ts +6 -5
- package/src/__tests__/robustness-medium-batch1.test.ts +2 -2
- package/src/__tests__/robustness-medium-batch2.test.ts +17 -6
- package/src/__tests__/robustness-medium-batch4.test.ts +2 -2
- package/src/__tests__/session-runner.test.ts +1 -1
- package/src/__tests__/smoke.test.ts +9 -2
- package/src/core/__tests__/host-services.test.ts +2 -2
- package/src/core/__tests__/logger.test.ts +1 -1
- package/src/core/error-message.ts +9 -0
- package/src/core/host-services.ts +21 -5
- package/src/core/notify-ports.ts +18 -5
- package/src/execution/__tests__/agent-profile.test.ts +232 -0
- package/src/execution/__tests__/agent-registry.test.ts +370 -0
- package/src/execution/__tests__/agent-result-mapper.test.ts +18 -2
- package/src/execution/__tests__/agents-assembly.test.ts +219 -0
- package/src/execution/__tests__/ask-user-transit-e2e.test.ts +6 -6
- package/src/execution/__tests__/chat-engine-routing.test.ts +136 -30
- package/src/execution/__tests__/chatmode-first-round-closure-spawn.test.ts +5 -4
- package/src/execution/__tests__/cold-resurrect.test.ts +283 -0
- package/src/execution/__tests__/create-concurrency-pool.test.ts +194 -0
- package/src/execution/__tests__/delivery-methods.test.ts +77 -62
- package/src/execution/__tests__/descendant-sweep-guards.test.ts +220 -0
- package/src/execution/__tests__/descendant-sweep.test.ts +269 -0
- package/src/execution/__tests__/dialog-queue.test.ts +199 -1
- package/src/execution/__tests__/engine-model-validation.test.ts +741 -0
- package/src/execution/__tests__/epipe-fallback.test.ts +31 -24
- package/src/execution/__tests__/execute-and-await-worktree.test.ts +21 -91
- package/src/execution/__tests__/execute-nesting.test.ts +34 -188
- package/src/execution/__tests__/execution-record.test.ts +217 -60
- package/src/execution/__tests__/execution-runtime-face.test.ts +272 -0
- package/src/execution/__tests__/explicit-agent-ref-guard.test.ts +3 -3
- package/src/execution/__tests__/finalize-record.test.ts +278 -16
- package/src/execution/__tests__/gc-timer.test.ts +57 -2
- package/src/execution/__tests__/get-record-for-action-restart.test.ts +14 -12
- package/src/execution/__tests__/get-state-handshake.test.ts +127 -0
- package/src/execution/__tests__/helpers/mock-extension-api.ts +1 -1
- package/src/execution/__tests__/helpers/session-runner-mocks.ts +113 -0
- package/src/execution/__tests__/helpers/spawn-mock.ts +150 -3
- package/src/execution/__tests__/helpers/subagent-service-mocks.ts +137 -0
- package/src/execution/__tests__/keep-alive-no-progress.test.ts +280 -0
- package/src/execution/__tests__/kill-all-escalation.test.ts +196 -0
- package/src/execution/__tests__/lifecycle-manager-idle-timer-identity.test.ts +117 -0
- package/src/execution/__tests__/lifecycle-manager.test.ts +39 -0
- package/src/execution/__tests__/lifecycle-predicates.test.ts +1 -2
- package/src/execution/__tests__/manifest-parentid.test.ts +4 -4
- package/src/execution/__tests__/manifest-store-tmp-recovery.test.ts +99 -0
- package/src/execution/__tests__/max-turns-to-watchdog-ms.test.ts +113 -0
- package/src/execution/__tests__/model-resolver.test.ts +2 -2
- package/src/execution/__tests__/nested-visibility-env-propagation.test.ts +23 -121
- package/src/execution/__tests__/nested-visibility.test.ts +2 -0
- package/src/execution/__tests__/notify-ledger.test.ts +1249 -0
- package/src/execution/__tests__/output-collector.test.ts +117 -6
- package/src/execution/__tests__/pi-invocation.test.ts +1 -1
- package/src/execution/__tests__/record-store-orphan-revive.test.ts +159 -0
- package/src/execution/__tests__/record-store.test.ts +89 -5
- package/src/execution/__tests__/records-cwd-isolation.test.ts +2 -2
- package/src/execution/__tests__/recursive-visibility-baseline.test.ts +29 -132
- package/src/execution/__tests__/recursive-visibility-env.test.ts +55 -179
- package/src/execution/__tests__/rpc-mode.test.ts +2 -2
- package/src/execution/__tests__/run-and-finalize-anchoring.test.ts +387 -0
- package/src/execution/__tests__/run-and-finalize-chatmode.test.ts +19 -9
- package/src/execution/__tests__/run-spawn-chatmode-settled.test.ts +5 -4
- package/src/execution/__tests__/run-spawn-edges.test.ts +418 -26
- package/src/execution/__tests__/run-spawn-integration.test.ts +3 -3
- package/src/execution/__tests__/run-spawn-resume.test.ts +2 -2
- package/src/execution/__tests__/run-spawn-rpc-mode.test.ts +2 -2
- package/src/execution/__tests__/run-spawn-stdout-callback-throw.test.ts +16 -8
- package/src/execution/__tests__/service-kill-escalation.test.ts +91 -0
- package/src/execution/__tests__/session-context-resolver.test.ts +0 -2
- package/src/execution/__tests__/session-file-gc.test.ts +35 -0
- package/src/execution/__tests__/session-pending.test.ts +471 -0
- package/src/execution/__tests__/session-reconstructor.test.ts +366 -15
- package/src/execution/__tests__/session-runner-branch-cache-lru.test.ts +110 -0
- package/src/execution/__tests__/session-runner-close-prune.test.ts +181 -0
- package/src/execution/__tests__/session-runner-dispatch.test.ts +489 -0
- package/src/execution/__tests__/session-runner-epipe.test.ts +4 -3
- package/src/execution/__tests__/session-runner-heartbeat-idle-fallback.test.ts +227 -0
- package/src/execution/__tests__/session-runner-lifecycle-helpers.test.ts +290 -0
- package/src/execution/__tests__/session-runner-schema-env.test.ts +7 -5
- package/src/execution/__tests__/settled-watchdog.test.ts +524 -0
- package/src/execution/__tests__/spawn-args.test.ts +11 -10
- package/src/execution/__tests__/spawn-event-adapter-rpc.test.ts +26 -23
- package/src/execution/__tests__/spawn-event-adapter.test.ts +1 -1
- package/src/execution/__tests__/spawn-worktree-guidance.test.ts +5 -4
- package/src/execution/__tests__/spawned-children.test.ts +155 -11
- package/src/execution/__tests__/start-sync-model-guard.test.ts +4 -4
- package/src/execution/__tests__/stdin-writer.test.ts +6 -4
- package/src/execution/__tests__/stream-sink-retirement.test.ts +6 -6
- package/src/execution/__tests__/subagent-actions-core.test.ts +1017 -0
- package/src/execution/__tests__/subagent-service-message-close.test.ts +99 -35
- package/src/execution/__tests__/subagent-service-multiproc-guard.test.ts +174 -0
- package/src/execution/__tests__/subagent-service-notify-gate.test.ts +271 -0
- package/src/execution/__tests__/subagent-service-parent-guard.test.ts +33 -29
- package/src/execution/__tests__/subagent-service-recovery-bounds.test.ts +341 -0
- package/src/execution/__tests__/subagent-service.test.ts +37 -30
- package/src/execution/__tests__/subprocess-agent-runner-routing.test.ts +88 -12
- package/src/execution/__tests__/subprocess-agent-runner-timeout.test.ts +75 -0
- package/src/execution/__tests__/subprocess-agent-runner.test.ts +22 -20
- package/src/execution/__tests__/temp-prompt.test.ts +1 -1
- package/src/execution/__tests__/timeout-integration.test.ts +13 -12
- package/src/execution/__tests__/turn-limiter-semantics.test.ts +1 -1
- package/src/execution/__tests__/turn-limiter.test.ts +1 -1
- package/src/execution/__tests__/ui-request-handler-factory.test.ts +107 -7
- package/src/execution/__tests__/ui-request-handler.test.ts +4 -3
- package/src/execution/__tests__/ui-request-queue.test.ts +167 -2
- package/src/execution/__tests__/worktree-git-ops.test.ts +571 -0
- package/src/execution/__tests__/worktree-manager.test.ts +14 -5
- package/src/execution/__tests__/worktree-pid-registration.integration.test.ts +4 -3
- package/src/execution/__tests__/worktree-reconcile-aging.test.ts +204 -0
- package/src/execution/agent-registry.ts +298 -30
- package/src/execution/agent-result-mapper.ts +3 -0
- package/src/execution/agents-assembly.ts +88 -0
- package/src/execution/cold-resurrect.ts +199 -0
- package/src/execution/concurrency-pool.ts +71 -9
- package/src/execution/dialog-queue.ts +101 -3
- package/src/execution/engine/__tests__/common/capability-gate.test.ts +91 -0
- package/src/execution/engine/__tests__/common/data-dir.test.ts +1 -1
- package/src/execution/engine/__tests__/common/journal-wiring.test.ts +84 -0
- package/src/execution/engine/__tests__/common/kill-chain.test.ts +34 -7
- package/src/execution/engine/__tests__/common/persona-router.test.ts +4 -5
- package/src/execution/engine/__tests__/common/pool-manager.test.ts +211 -51
- package/src/execution/engine/__tests__/common/session-view-service-zcode-dbpath.test.ts +149 -0
- package/src/execution/engine/__tests__/common/session-view-service.test.ts +499 -0
- package/src/execution/engine/__tests__/conformance/contract.abort.test.ts +56 -99
- package/src/execution/engine/__tests__/conformance/contract.agent-events.test.ts +88 -15
- package/src/execution/engine/__tests__/conformance/engine-conformance.live.test.ts +33 -7
- package/src/execution/engine/__tests__/conformance/golden-replay.pi.test.ts +1 -1
- package/src/execution/engine/__tests__/conformance/golden-replay.zcode.test.ts +75 -54
- package/src/execution/engine/__tests__/conformance/zcode-appserver-harness.ts +128 -0
- package/src/execution/engine/__tests__/engine-discovery.test.ts +15 -3
- package/src/execution/engine/__tests__/model-prompt.test.ts +15 -3
- package/src/execution/engine/__tests__/registry.test.ts +94 -3
- package/src/execution/engine/__tests__/routing.test.ts +115 -6
- package/src/execution/engine/common/capability-gate.ts +92 -0
- package/src/execution/engine/common/journal-wiring.ts +97 -0
- package/src/execution/engine/common/kill-chain.ts +42 -10
- package/src/execution/engine/common/nesting-guard.ts +66 -0
- package/src/execution/engine/common/persona-router.ts +18 -8
- package/src/execution/engine/common/pool-manager.ts +332 -78
- package/src/execution/engine/common/session-view-service.ts +506 -0
- package/src/execution/engine/common/session-view-types.ts +125 -0
- package/src/execution/engine/engine-discovery.ts +12 -16
- package/src/execution/engine/engines/pi/__tests__/pi-engine.test.ts +174 -28
- package/src/execution/engine/engines/pi/__tests__/spawn-opts-direct.test.ts +257 -0
- package/src/execution/{argv-mirror.ts → engine/engines/pi/argv-mirror.ts} +43 -21
- package/src/execution/{get-state-handshake.ts → engine/engines/pi/get-state-handshake.ts} +86 -11
- package/src/execution/{output-collector.ts → engine/engines/pi/output-collector.ts} +108 -19
- package/src/execution/engine/engines/pi/pi-engine.ts +434 -38
- package/src/execution/{pi-invocation.ts → engine/engines/pi/pi-invocation.ts} +2 -2
- package/src/execution/engine/engines/pi/reader.ts +11 -0
- package/src/execution/engine/engines/pi/registration.ts +4 -2
- package/src/execution/engine/engines/pi/session-runner.ts +2840 -0
- package/src/execution/{spawn-event-adapter.ts → engine/engines/pi/spawn-event-adapter.ts} +75 -34
- package/src/execution/{stdin-writer.ts → engine/engines/pi/stdin-writer.ts} +10 -9
- package/src/execution/{temp-prompt.ts → engine/engines/pi/temp-prompt.ts} +2 -2
- package/src/execution/{turn-limiter.ts → engine/engines/pi/turn-limiter.ts} +1 -1
- package/src/execution/engine/engines/zcode/__tests__/__fixtures__/fake-appserver.mjs +301 -0
- package/src/execution/engine/engines/zcode/__tests__/__fixtures__/zcode-golden-appserver.json +36 -0
- package/src/execution/engine/engines/zcode/__tests__/appserver-launcher.test.ts +321 -0
- package/src/execution/engine/engines/zcode/__tests__/connection.test.ts +473 -0
- package/src/execution/engine/engines/zcode/__tests__/parser.test.ts +7 -210
- package/src/execution/engine/engines/zcode/__tests__/preparer.test.ts +6 -110
- package/src/execution/engine/engines/zcode/__tests__/session-channel-dispose-harvest.test.ts +247 -0
- package/src/execution/engine/engines/zcode/__tests__/session-channel-turn-timers.test.ts +451 -0
- package/src/execution/engine/engines/zcode/__tests__/session-channel.test.ts +792 -0
- package/src/execution/engine/engines/zcode/__tests__/zcode-engine-appserver.test.ts +782 -0
- package/src/execution/engine/engines/zcode/__tests__/zcode-engine-degrade.test.ts +168 -0
- package/src/execution/engine/engines/zcode/__tests__/zcode-engine-dispose.test.ts +210 -0
- package/src/execution/engine/engines/zcode/__tests__/zcode-engine-retry.test.ts +353 -0
- package/src/execution/engine/engines/zcode/__tests__/zcode-engine-status.test.ts +282 -0
- package/src/execution/engine/engines/zcode/__tests__/zcode-engine-timeout.test.ts +372 -0
- package/src/execution/engine/engines/zcode/__tests__/zcode-engine.live.test.ts +65 -47
- package/src/execution/engine/engines/zcode/appserver-launcher.ts +167 -0
- package/src/execution/engine/engines/zcode/connection.ts +598 -0
- package/src/execution/engine/engines/zcode/constants.ts +147 -14
- package/src/execution/engine/engines/zcode/golden-sample.ts +42 -34
- package/src/execution/engine/engines/zcode/parser.ts +12 -346
- package/src/execution/engine/engines/zcode/preparer.ts +22 -150
- package/src/execution/engine/engines/zcode/session-channel.ts +968 -0
- package/src/execution/engine/engines/zcode/zcode-engine.ts +1023 -250
- package/src/execution/engine/host-task-spec.ts +32 -36
- package/src/execution/engine/model-validation.ts +177 -0
- package/src/execution/engine/port.ts +65 -7
- package/src/execution/engine/registry.ts +53 -0
- package/src/execution/engine/routing.ts +75 -1
- package/src/execution/engine/types.ts +30 -103
- package/src/execution/execution-record.ts +222 -144
- package/src/execution/finalize-record.ts +181 -85
- package/src/execution/idle-gc.ts +28 -0
- package/src/execution/lifecycle-manager.ts +27 -3
- package/src/execution/lifecycle-predicates.ts +1 -1
- package/src/execution/manifest-store.ts +53 -62
- package/src/execution/notifier.ts +10 -10
- package/src/execution/notify-host.ts +212 -0
- package/src/execution/notify-ledger.ts +117 -16
- package/src/execution/record-entry.ts +8 -2
- package/src/execution/record-store.ts +148 -88
- package/src/execution/round-settlement.ts +93 -0
- package/src/execution/session-file-gc.ts +96 -62
- package/src/execution/session-pending.ts +213 -62
- package/src/execution/session-reconstructor.ts +256 -143
- package/src/execution/sessions-index.ts +127 -102
- package/src/execution/settled-watchdog.ts +311 -0
- package/src/execution/subagent-actions-core.ts +686 -0
- package/src/execution/subagent-service.ts +1106 -907
- package/src/execution/subprocess-agent-runner.ts +144 -97
- package/src/execution/types.ts +9 -0
- package/src/execution/ui-request-handler-factory.ts +126 -75
- package/src/execution/ui-request-queue.ts +50 -19
- package/src/execution/worktree-git-ops.ts +397 -0
- package/src/execution/worktree-manager.ts +72 -10
- package/src/execution/worktree-registry.ts +6 -12
- package/src/index.ts +542 -9
- package/src/orchestration/__tests__/__fixtures__/worker-template.snapshot.txt +42 -3
- package/src/orchestration/__tests__/agent-call-catch-fallback.test.ts +3 -5
- package/src/orchestration/__tests__/agent-call-stream.test.ts +2 -2
- package/src/orchestration/__tests__/args-meta.test.ts +358 -0
- package/src/orchestration/__tests__/args-validator.test.ts +14 -0
- package/src/orchestration/__tests__/error-recovery-rebuild-failure.test.ts +312 -0
- package/src/orchestration/__tests__/error-recovery-terminal-hardening.test.ts +384 -0
- package/src/orchestration/__tests__/execute-agent-call.test.ts +151 -11
- package/src/orchestration/__tests__/file-run-store-prune.test.ts +168 -0
- package/src/orchestration/__tests__/file-run-store-throttle.test.ts +168 -0
- package/src/orchestration/__tests__/file-run-store.test.ts +390 -0
- package/src/orchestration/__tests__/helpers/flush-microtasks.ts +13 -0
- package/src/orchestration/__tests__/launcher-nested-workflow.test.ts +34 -0
- package/src/orchestration/__tests__/lifecycle-abort-broadcast-signal.test.ts +357 -0
- package/src/orchestration/__tests__/lifecycle-recover-crashed.test.ts +289 -0
- package/src/orchestration/__tests__/lifecycle-runid-injection.test.ts +3 -3
- package/src/orchestration/__tests__/lifecycle.test.ts +84 -5
- package/src/orchestration/__tests__/non-cloneable-return-e2e.test.ts +1 -1
- package/src/orchestration/__tests__/run-snapshot.test.ts +356 -0
- package/src/orchestration/__tests__/script-generate.test.ts +314 -0
- package/src/orchestration/__tests__/script-lint.test.ts +17 -0
- package/src/orchestration/__tests__/test-mocks.ts +2 -0
- package/src/orchestration/__tests__/worker-exit-without-result.test.ts +7 -6
- package/src/orchestration/__tests__/worker-message-pump-finalize-run.test.ts +229 -0
- package/src/orchestration/__tests__/{error-recovery-handlers.test.ts → worker-message-pump-handlers.test.ts} +28 -27
- package/src/orchestration/__tests__/{error-recovery-postmessage-defense.test.ts → worker-message-pump-postmessage-defense.test.ts} +8 -8
- package/src/orchestration/__tests__/{error-recovery-serialize-failed-result.test.ts → worker-message-pump-serialize-failed-result.test.ts} +2 -2
- package/src/orchestration/__tests__/{error-recovery-workflow-call.test.ts → worker-message-pump-workflow-call.test.ts} +1 -1
- package/src/orchestration/__tests__/worker-pending-timeout-abort.test.ts +275 -0
- package/src/orchestration/__tests__/worker-script-builder-runtime.test.ts +78 -1
- package/src/orchestration/__tests__/worker-script-builder.test.ts +1 -1
- package/src/orchestration/__tests__/workflow-files.test.ts +186 -0
- package/src/orchestration/__tests__/workflow-nesting-e2e.test.ts +1 -1
- package/src/orchestration/__tests__/workflow-run-summary.test.ts +119 -0
- package/src/orchestration/__tests__/workflow-script-registry-impl.test.ts +124 -0
- package/src/orchestration/agent-opts-resolver.ts +8 -8
- package/src/orchestration/args-meta.ts +198 -0
- package/src/orchestration/args-validator.ts +53 -31
- package/src/orchestration/execute-agent-call.ts +25 -79
- package/src/orchestration/file-run-store.ts +327 -0
- package/src/orchestration/launcher.ts +160 -104
- package/src/orchestration/lifecycle.ts +371 -97
- package/src/orchestration/models/agent-call.ts +7 -7
- package/src/orchestration/models/budget.ts +5 -5
- package/src/orchestration/models/ports.ts +4 -4
- package/src/orchestration/models/run-runtime.ts +15 -15
- package/src/orchestration/models/trace.ts +9 -9
- package/src/orchestration/models/types.ts +111 -22
- package/src/orchestration/models/workflow-run.ts +28 -28
- package/src/orchestration/models/workflow-script.ts +4 -4
- package/src/orchestration/run-snapshot.ts +266 -0
- package/src/orchestration/script-generate.ts +154 -0
- package/src/orchestration/script-lint.ts +123 -90
- package/src/orchestration/worker-handle.ts +10 -10
- package/src/orchestration/worker-host.ts +10 -10
- package/src/orchestration/{error-recovery.ts → worker-message-pump.ts} +498 -221
- package/src/orchestration/worker-script-builder.ts +401 -346
- package/src/orchestration/workflow-files.ts +37 -11
- package/src/orchestration/workflow-run-summary.ts +69 -0
- package/src/orchestration/workflow-script-registry-impl.ts +31 -9
- package/src/shared/__tests__/agent-ref.test.ts +209 -2
- package/src/shared/__tests__/atomic-write.test.ts +267 -0
- package/src/shared/__tests__/bounded-serialize.test.ts +236 -0
- package/src/shared/__tests__/injection-render.test.ts +518 -0
- package/src/shared/__tests__/meta-parser.test.ts +151 -0
- package/src/shared/__tests__/resource-discovery-host-roots.test.ts +474 -0
- package/src/shared/__tests__/resource-discovery.test.ts +261 -217
- package/src/shared/agent-ref.ts +143 -2
- package/src/shared/atomic-write.ts +323 -0
- package/src/shared/bounded-serialize.ts +154 -0
- package/src/shared/injection-render.ts +279 -0
- package/src/shared/meta-parser.ts +182 -68
- package/src/shared/model-ref.ts +15 -2
- package/src/shared/resource-discovery.ts +97 -204
- package/src/shared/resource-meta.ts +14 -0
- package/src/shared/schema-jsonify.ts +1 -1
- package/src/shared/xml-injection.ts +9 -9
- package/workflows/README.md +9 -9
- package/workflows/chain.js +4 -2
- package/workflows/map-reduce.js +5 -3
- package/workflows/parallel.js +5 -3
- package/workflows/review-fix-loop-utils.cjs +165 -92
- package/workflows/review-fix-loop-utils.d.cts +287 -0
- package/workflows/review-fix-loop.js +18 -7
- package/workflows/scatter-gather.js +4 -2
- package/dist/chunk-3VOERJPJ.js +0 -22
- package/src/execution/__tests__/execute-options-mapper.test.ts +0 -200
- package/src/execution/engine/engines/pi/__tests__/task-spec-mapper.test.ts +0 -164
- package/src/execution/engine/engines/pi/task-spec-mapper.ts +0 -100
- package/src/execution/engine/engines/zcode/__tests__/__fixtures__/zcode-golden-spawn.json +0 -39
- package/src/execution/engine/engines/zcode/__tests__/launcher.test.ts +0 -150
- package/src/execution/engine/engines/zcode/__tests__/zcode-engine.test.ts +0 -580
- package/src/execution/engine/engines/zcode/launcher.ts +0 -161
- package/src/execution/execute-options-mapper.ts +0 -115
- package/src/execution/session-runner.ts +0 -1789
- package/src/shared/__tests__/resource-discovery-manifest-cache.test.ts +0 -288
|
@@ -10,10 +10,10 @@
|
|
|
10
10
|
// 4. manifest 路径存在性校验:声明的路径不存在 → 该包发现失败,不 fallback
|
|
11
11
|
// 5. 废弃 discovery.json:扫描路径完全由代码内推导,无外部依赖
|
|
12
12
|
//
|
|
13
|
-
// 优先级(低→高):user .pi/agent → user .agents → npm global → npm dev → project .pi → project .pi/.tmp(仅workflow) → project .agents
|
|
13
|
+
// 优先级(低→高):user .pi/agent → user .agents → npm global → npm dev → ext-paths(XYZ_EXTENSION_PATHS/dev-link) → project .pi → project .pi/.tmp(仅workflow) → project-host(宿主注入槽) → project .agents
|
|
14
14
|
|
|
15
15
|
import * as fsSync from "node:fs";
|
|
16
|
-
import { access, readdir, readFile, stat } from "node:fs/promises";
|
|
16
|
+
import { access, readdir, readFile, realpath, stat } from "node:fs/promises";
|
|
17
17
|
import { homedir } from "node:os";
|
|
18
18
|
import { delimiter, join, resolve } from "node:path";
|
|
19
19
|
|
|
@@ -56,7 +56,19 @@ export interface DiscoveredResource {
|
|
|
56
56
|
}
|
|
57
57
|
|
|
58
58
|
/** 资源来源层级 */
|
|
59
|
-
export type ResourceSource =
|
|
59
|
+
export type ResourceSource =
|
|
60
|
+
| "user-pi"
|
|
61
|
+
| "user-agents"
|
|
62
|
+
| "npm"
|
|
63
|
+
| "npm-dev"
|
|
64
|
+
| "user-extension-paths"
|
|
65
|
+
| "project-pi"
|
|
66
|
+
| "project-pi-tmp"
|
|
67
|
+
// project-host(W2②):宿主注入的项目级根(如 zsw 的 <ws>/.zcode/agents)。
|
|
68
|
+
// 序位刻意压在 project-agents 之下——zsw 现语义项目 .agents > .zcode,
|
|
69
|
+
// project-host 承接 zcode 项目根,project-agents 仍是项目级最高逃生门。
|
|
70
|
+
| "project-host"
|
|
71
|
+
| "project-agents";
|
|
60
72
|
|
|
61
73
|
/** 扫描配置 */
|
|
62
74
|
export interface ScanConfig {
|
|
@@ -65,8 +77,14 @@ export interface ScanConfig {
|
|
|
65
77
|
/** 项目根目录(findWorkspaceRoot 推导结果) */
|
|
66
78
|
workspaceRoot: string;
|
|
67
79
|
/** 宿主注入的发现根(DiscoveryRoot.dir 已含 kind 末级目录与安装布局,
|
|
68
|
-
* source 为宿主语义标签——pi 壳 = user-pi/npm/npm-dev
|
|
69
|
-
*
|
|
80
|
+
* source 为宿主语义标签——pi 壳 = user-pi/npm/npm-dev 三根,zsw 壳可另注入
|
|
81
|
+
* project-host 等)。buildScanTargets 按标签填充对应槽位,宿主未提供某标签
|
|
82
|
+
* 根时该槽位条目整体缺席。
|
|
83
|
+
* 同标签多根语义(W2④):同标签多条目依注入序全部保留、同序位依次扫描——
|
|
84
|
+
* 宿主(zsw)把「目录 symlink 展开目标 + 本体根」按注入序注入同标签,core
|
|
85
|
+
* 合并 last-writer-wins 下靠后者胜,本体根必须注入在展开目标之后(本体胜,
|
|
86
|
+
* 红线 2)。user-agents/project-agents 硬编码槽与同标签注入合并时硬编码根
|
|
87
|
+
* 自动后置(同为「本体在后」语义)。 */
|
|
70
88
|
hostRoots: DiscoveryRoot[];
|
|
71
89
|
/** 是否包含 tmp 源(仅 workflow 用 .pi/workflows/.tmp/) */
|
|
72
90
|
includeTmp?: boolean;
|
|
@@ -82,11 +100,12 @@ const MACHINE_SOURCES: ReadonlySet<ResourceSource> = new Set<ResourceSource>([
|
|
|
82
100
|
"user-extension-paths",
|
|
83
101
|
"project-pi",
|
|
84
102
|
"project-pi-tmp",
|
|
103
|
+
"project-host",
|
|
85
104
|
"project-agents",
|
|
86
105
|
]);
|
|
87
106
|
|
|
88
107
|
/** 判断 source 是否属于机器源(安装拓扑常态,同名重复降 debug)。
|
|
89
|
-
* 导出仅为测试穷举断言用(封闭
|
|
108
|
+
* 导出仅为测试穷举断言用(封闭 9 值枚举 × 分级边界)。 */
|
|
90
109
|
export function isMachineSource(source: ResourceSource): boolean {
|
|
91
110
|
return MACHINE_SOURCES.has(source);
|
|
92
111
|
}
|
|
@@ -113,8 +132,8 @@ function isDirectChildOfWorkspaceRoot(dir: string, workspaceRoot: string): boole
|
|
|
113
132
|
// ── 统一 mtime 缓存层(m5 IF10)────────────────────────────────────
|
|
114
133
|
//
|
|
115
134
|
// 模块级 Map<path, { mtimeMs, content }>:mtime 判变缓存文件内容。
|
|
116
|
-
// - sync 实现(statSync/readFileSync):
|
|
117
|
-
//
|
|
135
|
+
// - sync 实现(statSync/readFileSync):getCachedFile 同步返回,供 async 发现流程
|
|
136
|
+
// 与 agent-registry loadByPath 在流程内同步读缓存
|
|
118
137
|
// - stat 失败/ENOENT → 驱逐条目(mtime 缓存下文件删除不自愈——A3 修复)
|
|
119
138
|
// - 已知局限(C3 记录):内容变 mtime 未变(cp -p/rsync -t 保留源 mtime、
|
|
120
139
|
// 2s 粒度文件系统)→ 漏判,invalidateCache/clearFileCache 兜底;
|
|
@@ -364,7 +383,7 @@ async function scanDirectory(dirPath: string, kind: ResourceKind): Promise<strin
|
|
|
364
383
|
/**
|
|
365
384
|
* 读取 package.json 的 pi.{kind} manifest(pi.agents / pi.workflows)。
|
|
366
385
|
* 返回 undefined 表示无 manifest 声明(无 pi / pi[kind] 非数组 / 解析失败)。
|
|
367
|
-
* 内部走 manifestCache
|
|
386
|
+
* 内部走 manifestCache(失败语义见声明处)。
|
|
368
387
|
*/
|
|
369
388
|
async function readPackageManifest(pkgDir: string, kind: ResourceKind): Promise<string[] | undefined> {
|
|
370
389
|
const pkgJsonPath = resolve(pkgDir, "package.json");
|
|
@@ -458,9 +477,9 @@ async function scanNpmDir(
|
|
|
458
477
|
}
|
|
459
478
|
|
|
460
479
|
// [perf] 包级并行(swf-perf-impl cleanup TC2/IF2):entries.map + Promise.all,
|
|
461
|
-
// perEntry.flat() 按原 readdir 序 concat
|
|
480
|
+
// perEntry.flat() 按原 readdir 序 concat——输出序与 readdir 包序一致。
|
|
462
481
|
// 不加新增 catch:每包失败面由 processPackage 内部既有 catch 承担,未捕获异常
|
|
463
|
-
//
|
|
482
|
+
// 经 Promise.all 以首个 reject 整体向上抛。
|
|
464
483
|
const perEntry = await Promise.all(
|
|
465
484
|
entries.map(async (entry): Promise<DiscoveredResource[]> => {
|
|
466
485
|
const entryPath = resolve(nodeModulesDir, entry);
|
|
@@ -518,38 +537,44 @@ function readExtensionPaths(): string[] {
|
|
|
518
537
|
* 构建所有扫描源(按优先级低→高排列)。
|
|
519
538
|
*
|
|
520
539
|
* agent 和 workflow 共享相同的前缀体系。宿主注入根(config.hostRoots)按 source
|
|
521
|
-
*
|
|
540
|
+
* 标签填充槽位条目——标签字面是 core 编排的槽位键(同时是 ResourceSource
|
|
522
541
|
* 枚举成员,报告输出与历史值逐字一致);宿主未提供某标签根时该条目跳过(该源在
|
|
523
542
|
* 遮蔽序中自然缺席),其余条目(core 自建:homedir/env/workspaceRoot 推导)留原位
|
|
524
543
|
* 原序,遮蔽优先级语义与注入化前逐字一致。
|
|
544
|
+
*
|
|
545
|
+
* 同标签多根(W2④,Map→列表):同标签多条目依注入序全部保留、同序位依次扫描
|
|
546
|
+
* (旧实现 Map(source→dir) 同标签靠后者整体覆盖,多根语义缺失)。硬编码槽
|
|
547
|
+
* (user-agents/project-agents)与 hostRoots 同标签注入合并——硬编码根(本体根)
|
|
548
|
+
* 排在注入条目之后:core 合并 last-writer-wins 靠后者胜,本体在后 = 本体胜(红线 2
|
|
549
|
+
* 「注入/合并序语义」)。pi 单条目形态(每标签恰好一条或无注入)下 targets 序与
|
|
550
|
+
* 旧实现逐项一致(回归红线,见 __tests__ pi 单条目形态快照用例)。
|
|
525
551
|
*/
|
|
526
552
|
function buildScanTargets(config: ScanConfig): ScanTarget[] {
|
|
527
553
|
const { kind, workspaceRoot, hostRoots, includeTmp } = config;
|
|
528
554
|
const home = homedir();
|
|
529
555
|
|
|
530
|
-
//
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
)
|
|
556
|
+
// 同标签多条目依注入序全部保留(W2④ 列表语义):宿主把「展开目标 + 本体根」
|
|
557
|
+
// 按注入序注入同标签,core 同序位依次扫描;本体靠后 → last-writer-wins 本体胜。
|
|
558
|
+
const hostDirsBySource = new Map<string, string[]>();
|
|
559
|
+
for (const root of hostRoots) {
|
|
560
|
+
const list = hostDirsBySource.get(root.source);
|
|
561
|
+
if (list) list.push(root.dir);
|
|
562
|
+
else hostDirsBySource.set(root.source, [root.dir]);
|
|
563
|
+
}
|
|
564
|
+
const hostTargets = (source: ResourceSource): ScanTarget[] =>
|
|
565
|
+
(hostDirsBySource.get(source) ?? []).map((dir) => ({ dir, source, enabled: true }));
|
|
534
566
|
|
|
535
567
|
const targets: ScanTarget[] = [];
|
|
536
568
|
// 1. user .pi/agent/{kind}/(宿主注入,pi 壳 source "user-pi")
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
// 2. user .agents/{kind}/(core 自建:homedir 推导,非宿主依赖)
|
|
569
|
+
targets.push(...hostTargets("user-pi"));
|
|
570
|
+
// 2. user .agents/{kind}/(硬编码根 = homedir 推导 + 宿主可选注入合并,硬编码
|
|
571
|
+
// 本体根后置 → 注入的展开目标在前、本体在后,last-writer-wins 本体胜)
|
|
572
|
+
targets.push(...hostTargets("user-agents"));
|
|
542
573
|
targets.push({ dir: join(home, ".agents", kind), source: "user-agents", enabled: true });
|
|
543
574
|
// 3. npm global: <agentDir>/npm/node_modules/*/<pkg>/(宿主注入,pi 壳 source "npm")
|
|
544
|
-
|
|
545
|
-
if (npmDir !== undefined) {
|
|
546
|
-
targets.push({ dir: npmDir, source: "npm", enabled: true });
|
|
547
|
-
}
|
|
575
|
+
targets.push(...hostTargets("npm"));
|
|
548
576
|
// 4. npm dev symlink: <agentDir>/extensions/*/<pkg>/(宿主注入,pi 壳 source "npm-dev")
|
|
549
|
-
|
|
550
|
-
if (npmDevDir !== undefined) {
|
|
551
|
-
targets.push({ dir: npmDevDir, source: "npm-dev", enabled: true });
|
|
552
|
-
}
|
|
577
|
+
targets.push(...hostTargets("npm-dev"));
|
|
553
578
|
// user extension paths (XYZ_EXTENSION_PATHS, dev-link): each path is a package dir,
|
|
554
579
|
// 走 processPackage 读 pi.{kind} manifest 或扫 {kind}/ 目录。优先级高于 npm/npm-dev
|
|
555
580
|
// (dev-link 是开发版 override),低于 project(项目正式资源优先)。
|
|
@@ -568,7 +593,13 @@ function buildScanTargets(config: ScanConfig): ScanTarget[] {
|
|
|
568
593
|
});
|
|
569
594
|
}
|
|
570
595
|
|
|
571
|
-
//
|
|
596
|
+
// 6.5 project host 根(宿主注入,W2②):承接宿主自有项目级布局(如 zsw 的
|
|
597
|
+
// <ws>/.zcode/agents)。序位在 project-agents 之下(.agents 是项目级最高
|
|
598
|
+
// 逃生门);未注入该标签时槽位缺席(与 user-pi/npm/npm-dev 同语义)。
|
|
599
|
+
targets.push(...hostTargets("project-host"));
|
|
600
|
+
|
|
601
|
+
// 7. project .agents/{kind}/(硬编码根 + 宿主可选注入合并,本体根后置同槽 2)
|
|
602
|
+
targets.push(...hostTargets("project-agents"));
|
|
572
603
|
targets.push({
|
|
573
604
|
dir: join(workspaceRoot, ".agents", kind),
|
|
574
605
|
source: "project-agents",
|
|
@@ -586,8 +617,14 @@ function buildScanTargets(config: ScanConfig): ScanTarget[] {
|
|
|
586
617
|
* 按优先级低→高扫描所有源,同名资源靠后覆盖靠前(last-writer-wins)。
|
|
587
618
|
* npm/dev 包内:有 manifest 只走 manifest(路径不存在则失败),无 manifest 扫约定目录。
|
|
588
619
|
*
|
|
620
|
+
* realpath 归一去重(W2①,仅 async 链):多个不同名 symlink 指向同一物理文件时
|
|
621
|
+
* (多链同文件),stem 去重防不住——清单按物理文件归一只留一条(首遇者,位置
|
|
622
|
+
* 固定语义与 stem 合并一致);同 stem 不同物理文件的遮蔽语义不受影响(仍按
|
|
623
|
+
* last-writer-wins 覆盖)。realpath 解析失败(扫描后竞态删除/ELOOP 深链)回退
|
|
624
|
+
* 原 path,属预期失败不抛。
|
|
625
|
+
*
|
|
589
626
|
* Throws on unrecoverable scan errors——未捕获异常向上抛(Promise.all 首个 reject
|
|
590
|
-
*
|
|
627
|
+
* 即整体拒绝,见实现内 [perf] 注释)。
|
|
591
628
|
* 预期失败不抛:目录不存在/不可读返回空列表,manifest 声明路径缺失以 available=false 返回。
|
|
592
629
|
*
|
|
593
630
|
* @returns 去重后的资源列表(按优先级合并,高优先级覆盖低优先级同名)
|
|
@@ -597,11 +634,10 @@ export async function discoverResources(config: ScanConfig): Promise<DiscoveredR
|
|
|
597
634
|
|
|
598
635
|
// [perf] 源级并行(swf-perf-impl cleanup TC2/IF2):targets.map + Promise.all,
|
|
599
636
|
// Promise.all 对 map 数组保序——allBySource 顺序 = targets 优先级序(低→高),
|
|
600
|
-
//
|
|
637
|
+
// 下方合并去重按该顺序 last-writer-wins。
|
|
601
638
|
// 不加新增 catch:每源预期失败路径由内部既有 catch 面承担(scanDirectory access
|
|
602
|
-
// catch / scanNpmDir readdir catch / processPackage 全链 catch
|
|
603
|
-
//
|
|
604
|
-
// 启动、以首个 reject 拒绝——两版对调用方同为 discoverResources 抛出,各源只读无副作用)。
|
|
639
|
+
// catch / scanNpmDir readdir catch / processPackage 全链 catch);未捕获异常经
|
|
640
|
+
// Promise.all 以首个 reject 整体向上拒绝(各源只读无副作用)。
|
|
605
641
|
const allBySource: Array<{ source: ResourceSource; resources: DiscoveredResource[] }> = await Promise.all(
|
|
606
642
|
targets.map(async (target) => {
|
|
607
643
|
if (target.source === "npm" || target.source === "npm-dev") {
|
|
@@ -624,13 +660,35 @@ export async function discoverResources(config: ScanConfig): Promise<DiscoveredR
|
|
|
624
660
|
}),
|
|
625
661
|
);
|
|
626
662
|
|
|
663
|
+
// [W2①] realpath 归一键(仅 async 链):与 allBySource 同构的二维数组(源序×
|
|
664
|
+
// 源内资源序)。源级并行解析(每资源一次 realpath,资源量级为个位/十位数);
|
|
665
|
+
// 失败回退原 path——扫描与 realpath 之间竞态删除/ELOOP 属预期失败,不抛
|
|
666
|
+
// (对齐 scanDirectory 的 stat().catch 吞错面)。
|
|
667
|
+
const realpathKeys: string[][] = await Promise.all(
|
|
668
|
+
allBySource.map(async ({ resources }) =>
|
|
669
|
+
Promise.all(resources.map((r) => realpath(r.path).catch(() => r.path))),
|
|
670
|
+
),
|
|
671
|
+
);
|
|
672
|
+
|
|
627
673
|
// 按优先级合并:targets 数组顺序即优先级(低→高),高优先级后写覆盖
|
|
628
674
|
// 用文件名 stem 作为去重 key(与旧逻辑一致:同名资源高优先级覆盖)
|
|
629
675
|
const merged = new Map<string, DiscoveredResource>();
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
676
|
+
// realpath → 已入清单 stem key:多链同文件(不同名 symlink 指向同一物理文件)
|
|
677
|
+
// 时后到链 skip——清单按物理文件只留一条,不计入遮蔽(同一文件无遮蔽语义)。
|
|
678
|
+
const realpathOwner = new Map<string, string>();
|
|
679
|
+
|
|
680
|
+
for (let si = 0; si < allBySource.length; si++) {
|
|
681
|
+
const { resources } = allBySource[si]!;
|
|
682
|
+
for (let ri = 0; ri < resources.length; ri++) {
|
|
683
|
+
const r = resources[ri]!;
|
|
633
684
|
const key = stem(r.path);
|
|
685
|
+
const rp = realpathKeys[si]![ri]!;
|
|
686
|
+
// 同物理文件已以另一 stem 入清单 → 多链重复,跳过(不影响 stem 遮蔽语义:
|
|
687
|
+
// 同 stem 不同物理文件仍走下方 last-writer-wins)
|
|
688
|
+
const owner = realpathOwner.get(rp);
|
|
689
|
+
if (owner !== undefined && owner !== key) {
|
|
690
|
+
continue;
|
|
691
|
+
}
|
|
634
692
|
const existing = merged.get(key);
|
|
635
693
|
// available=false 的占位不覆盖已有的 available=true
|
|
636
694
|
if (!r.available && existing) {
|
|
@@ -661,175 +719,10 @@ export async function discoverResources(config: ScanConfig): Promise<DiscoveredR
|
|
|
661
719
|
}
|
|
662
720
|
}
|
|
663
721
|
merged.set(key, r);
|
|
722
|
+
realpathOwner.set(rp, key);
|
|
664
723
|
}
|
|
665
724
|
}
|
|
666
725
|
|
|
667
726
|
return Array.from(merged.values());
|
|
668
727
|
}
|
|
669
728
|
|
|
670
|
-
/**
|
|
671
|
-
* 同步版:扫描单个目录下的资源文件路径(供 agent-registry 的 mtime 缓存模式使用)。
|
|
672
|
-
*
|
|
673
|
-
* agent .md 发现需要 mtime 缓存(hot-reload),不能走 async 全量扫描。
|
|
674
|
-
* 此函数提供目录级同步扫描,npm/dev 包内发现仍需 async(agent-registry 用 builtin 兜底)。
|
|
675
|
-
*/
|
|
676
|
-
export function scanDirectorySync(dirPath: string, kind: ResourceKind): string[] {
|
|
677
|
-
try {
|
|
678
|
-
fsSync.accessSync(dirPath);
|
|
679
|
-
} catch {
|
|
680
|
-
return [];
|
|
681
|
-
}
|
|
682
|
-
|
|
683
|
-
let entries: string[];
|
|
684
|
-
try {
|
|
685
|
-
entries = fsSync.readdirSync(dirPath);
|
|
686
|
-
} catch {
|
|
687
|
-
return [];
|
|
688
|
-
}
|
|
689
|
-
|
|
690
|
-
const files: string[] = [];
|
|
691
|
-
for (const entry of entries) {
|
|
692
|
-
if (!isTargetFile(entry, kind)) continue;
|
|
693
|
-
files.push(resolve(dirPath, entry));
|
|
694
|
-
}
|
|
695
|
-
return files;
|
|
696
|
-
}
|
|
697
|
-
|
|
698
|
-
/**
|
|
699
|
-
* 同步版:读取 package.json 的 pi.{kind} manifest。
|
|
700
|
-
* 供 agent-registry 同步路径使用。与 async 版共享 manifestCache(双读者同一 Map)。
|
|
701
|
-
*/
|
|
702
|
-
export function readPackageManifestSync(pkgDir: string, kind: ResourceKind): string[] | undefined {
|
|
703
|
-
const pkgJsonPath = resolve(pkgDir, "package.json");
|
|
704
|
-
let mtimeMs: number;
|
|
705
|
-
try {
|
|
706
|
-
mtimeMs = fsSync.statSync(pkgJsonPath).mtimeMs;
|
|
707
|
-
} catch {
|
|
708
|
-
// stat 失败:文件不存在/不可 stat → 驱逐条目(对齐 getCachedFile 语义)
|
|
709
|
-
manifestCache.delete(pkgJsonPath);
|
|
710
|
-
return undefined;
|
|
711
|
-
}
|
|
712
|
-
const entry = manifestCache.get(pkgJsonPath);
|
|
713
|
-
if (entry && entry.mtimeMs === mtimeMs) return piToManifest(entry.pi, kind);
|
|
714
|
-
let pi: Record<string, unknown> | undefined;
|
|
715
|
-
try {
|
|
716
|
-
const content = fsSync.readFileSync(pkgJsonPath, "utf-8");
|
|
717
|
-
pi = parsePiField(content);
|
|
718
|
-
} catch {
|
|
719
|
-
// read 失败或坏 JSON → 不缓存不驱逐已有好条目,下次调用重试
|
|
720
|
-
return undefined;
|
|
721
|
-
}
|
|
722
|
-
manifestCache.set(pkgJsonPath, { mtimeMs, pi });
|
|
723
|
-
return piToManifest(pi, kind);
|
|
724
|
-
}
|
|
725
|
-
|
|
726
|
-
/**
|
|
727
|
-
* 同步版:处理单个 npm/dev 包。
|
|
728
|
-
* 供 agent-registry 同步路径使用。
|
|
729
|
-
*/
|
|
730
|
-
export function processPackageSync(pkgDir: string, kind: ResourceKind): DiscoveredResource[] {
|
|
731
|
-
const manifestPaths = readPackageManifestSync(pkgDir, kind);
|
|
732
|
-
|
|
733
|
-
if (manifestPaths && manifestPaths.length > 0) {
|
|
734
|
-
const results: DiscoveredResource[] = [];
|
|
735
|
-
|
|
736
|
-
for (const relPath of manifestPaths) {
|
|
737
|
-
const absPath = resolve(pkgDir, relPath);
|
|
738
|
-
let fileStat: fsSync.Stats | null;
|
|
739
|
-
try {
|
|
740
|
-
fileStat = fsSync.statSync(absPath);
|
|
741
|
-
} catch {
|
|
742
|
-
fileStat = null;
|
|
743
|
-
}
|
|
744
|
-
if (!fileStat) {
|
|
745
|
-
results.push({ path: absPath, source: "npm", available: false });
|
|
746
|
-
continue;
|
|
747
|
-
}
|
|
748
|
-
|
|
749
|
-
if (fileStat.isDirectory()) {
|
|
750
|
-
const files = scanDirectorySync(absPath, kind);
|
|
751
|
-
for (const f of files) {
|
|
752
|
-
results.push({ path: f, source: "npm", available: true });
|
|
753
|
-
}
|
|
754
|
-
} else if (fileStat.isFile()) {
|
|
755
|
-
results.push({ path: absPath, source: "npm", available: true });
|
|
756
|
-
}
|
|
757
|
-
}
|
|
758
|
-
|
|
759
|
-
return results;
|
|
760
|
-
}
|
|
761
|
-
|
|
762
|
-
// 无 manifest:扫约定目录
|
|
763
|
-
const conventionDir = resolve(pkgDir, kind);
|
|
764
|
-
const files = scanDirectorySync(conventionDir, kind);
|
|
765
|
-
return files.map((f) => ({ path: f, source: "npm", available: true }));
|
|
766
|
-
}
|
|
767
|
-
|
|
768
|
-
/**
|
|
769
|
-
* 同步版:扫描 npm node_modules 目录。
|
|
770
|
-
* 供 agent-registry 同步路径使用。
|
|
771
|
-
*/
|
|
772
|
-
export function scanNpmDirSync(nodeModulesDir: string, kind: ResourceKind): DiscoveredResource[] {
|
|
773
|
-
let entries: string[];
|
|
774
|
-
try {
|
|
775
|
-
entries = fsSync.readdirSync(nodeModulesDir);
|
|
776
|
-
} catch {
|
|
777
|
-
return [];
|
|
778
|
-
}
|
|
779
|
-
|
|
780
|
-
const results: DiscoveredResource[] = [];
|
|
781
|
-
for (const entry of entries) {
|
|
782
|
-
const entryPath = resolve(nodeModulesDir, entry);
|
|
783
|
-
|
|
784
|
-
if (entry.startsWith("@")) {
|
|
785
|
-
let scopedEntries: string[];
|
|
786
|
-
try {
|
|
787
|
-
scopedEntries = fsSync.readdirSync(entryPath);
|
|
788
|
-
} catch {
|
|
789
|
-
continue;
|
|
790
|
-
}
|
|
791
|
-
for (const scopedPkg of scopedEntries) {
|
|
792
|
-
const scopedPkgDir = resolve(entryPath, scopedPkg);
|
|
793
|
-
results.push(...processPackageSync(scopedPkgDir, kind));
|
|
794
|
-
}
|
|
795
|
-
} else {
|
|
796
|
-
results.push(...processPackageSync(entryPath, kind));
|
|
797
|
-
}
|
|
798
|
-
}
|
|
799
|
-
return results;
|
|
800
|
-
}
|
|
801
|
-
|
|
802
|
-
/**
|
|
803
|
-
* 同步版:发现所有资源(agent-registry 专用,支持 mtime 缓存的 hot-reload)。
|
|
804
|
-
*
|
|
805
|
-
* 与 discoverResources 对应的同步实现,扫描相同的源。
|
|
806
|
-
* 返回所有源的资源(未去重,调用方按需处理优先级)。
|
|
807
|
-
*/
|
|
808
|
-
export function discoverResourcesSync(config: ScanConfig): DiscoveredResource[] {
|
|
809
|
-
const targets = buildScanTargets(config);
|
|
810
|
-
const all: DiscoveredResource[] = [];
|
|
811
|
-
|
|
812
|
-
for (const target of targets) {
|
|
813
|
-
if (target.source === "npm" || target.source === "npm-dev") {
|
|
814
|
-
const resources = scanNpmDirSync(target.dir, config.kind);
|
|
815
|
-
all.push(...resources.map((r) => ({ ...r, source: target.source })));
|
|
816
|
-
} else if (target.source === "user-extension-paths") {
|
|
817
|
-
// XYZ_EXTENSION_PATHS(dev-link):每个 dir 是单个包目录
|
|
818
|
-
const resources = processPackageSync(target.dir, config.kind);
|
|
819
|
-
all.push(...resources.map((r) => ({ ...r, source: target.source })));
|
|
820
|
-
} else {
|
|
821
|
-
const files = scanDirectorySync(target.dir, config.kind);
|
|
822
|
-
all.push(...files.map((f) => ({ path: f, source: target.source, available: true })));
|
|
823
|
-
}
|
|
824
|
-
}
|
|
825
|
-
|
|
826
|
-
// 按优先级合并(targets 顺序 = 优先级低→高)
|
|
827
|
-
const merged = new Map<string, DiscoveredResource>();
|
|
828
|
-
for (const r of all) {
|
|
829
|
-
const key = stem(r.path);
|
|
830
|
-
if (!r.available && merged.has(key)) continue;
|
|
831
|
-
merged.set(key, r);
|
|
832
|
-
}
|
|
833
|
-
|
|
834
|
-
return Array.from(merged.values());
|
|
835
|
-
}
|
|
@@ -59,6 +59,20 @@ export interface AgentMeta extends ResourceMetaBase {
|
|
|
59
59
|
* 与 model 字段同风格——路由字段(不进 system prompt),执行侧(P4 路由层)消费。
|
|
60
60
|
*/
|
|
61
61
|
engine?: string;
|
|
62
|
+
/**
|
|
63
|
+
* 执行预算:turn 上限(sink 设计 D3 新增可选执行字段之一)。
|
|
64
|
+
* 消费优先级:显式参数 > 本字段 > 缺省——pi 工具参数 maxTurns 语义不变(本字段
|
|
65
|
+
* 对 pi 是清单元数据),zsw 决策链 timeoutMs > profile.maxTurns > 缺省。
|
|
66
|
+
*/
|
|
67
|
+
maxTurns?: number;
|
|
68
|
+
/** tool denylist(D3 可选执行字段):spawn 侧剔除,与 tools allowlist 正交。 */
|
|
69
|
+
disallowedTools?: string[];
|
|
70
|
+
/**
|
|
71
|
+
* agent 声明依赖的 skill 名清单(D3 可选执行字段)。注意与本文件头注
|
|
72
|
+
* 「skills 归 pi core」的 skills(资源种类)不同物:此处是 agent frontmatter 的
|
|
73
|
+
* 执行配置字段,不是 ResourceKind。
|
|
74
|
+
*/
|
|
75
|
+
skills?: string[];
|
|
62
76
|
}
|
|
63
77
|
|
|
64
78
|
/** 判别联合(kind 判别)。 */
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
*
|
|
4
4
|
* 同一 schema 对象引用的重复 JSON.stringify 消除:resolver(compact,instruction
|
|
5
5
|
* 与 schemaEnv 复用同串,formatSchemaInstruction 现居 resolver)在单次 agent call
|
|
6
|
-
* 内对同一 schema 对象各 stringify 一次;
|
|
6
|
+
* 内对同一 schema 对象各 stringify 一次;worker-message-pump 重试路径再加一次。本
|
|
7
7
|
* helper 用 WeakMap 按对象引用缓存两种格式,命中返回缓存串。
|
|
8
8
|
*
|
|
9
9
|
* 返回值与直接 JSON.stringify 逐字节一致(compact = JSON.stringify(x)、
|
|
@@ -9,12 +9,12 @@
|
|
|
9
9
|
* XML 结构——全部字段过一遍转义防注入段破碎)。
|
|
10
10
|
*/
|
|
11
11
|
export function escapeXml(str: string): string {
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
12
|
+
return str
|
|
13
|
+
.replace(/&/g, "&")
|
|
14
|
+
.replace(/</g, "<")
|
|
15
|
+
.replace(/>/g, ">")
|
|
16
|
+
.replace(/"/g, """)
|
|
17
|
+
.replace(/'/g, "'");
|
|
18
18
|
}
|
|
19
19
|
|
|
20
20
|
/**
|
|
@@ -29,7 +29,7 @@ export function renderXmlSection(section: {
|
|
|
29
29
|
guide: string;
|
|
30
30
|
items: string[];
|
|
31
31
|
}): string {
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
32
|
+
if (section.items.length === 0) return "";
|
|
33
|
+
const lines = [`\n\n<${section.tag}>`, section.guide, ...section.items, `</${section.tag}>`];
|
|
34
|
+
return lines.join("\n");
|
|
35
35
|
}
|
package/workflows/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# 内置通用编排 Workflow
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
5 个开箱即用的通用 subagent 编排 workflow,覆盖日常常见的多 agent 协作模式。每个脚本用 `agent()`/`parallel()` 自包含实现,`workflow run <name>` 直接执行,无需额外定义子 workflow。
|
|
4
4
|
|
|
5
5
|
## 文件清单
|
|
6
6
|
|
|
@@ -56,26 +56,26 @@ workflow run map-reduce --args itemsJson=/path/to/items.json --args operation=".
|
|
|
56
56
|
|
|
57
57
|
```
|
|
58
58
|
workflow run review-fix-loop --args targetType=git-diff target=main \
|
|
59
|
-
--args
|
|
59
|
+
--args fallowScan=true --args batch1=/path/to/reviewer.md --args autoCommit=true
|
|
60
60
|
workflow run review-fix-loop --args targetType=file target=/path/to/doc.md \
|
|
61
|
-
--args batch1
|
|
61
|
+
--args batch1=/path/to/doc-reviewer.md
|
|
62
62
|
```
|
|
63
63
|
|
|
64
64
|
- `targetType` 枚举:`git-diff`(target=base ref)/ `file`(target=路径)/ `dir`(target=目录)/ `text`(target=自由描述)
|
|
65
65
|
- `batch1..batchN`:批串行,批内并行 review → aggregate → fix → 重审直到 clean;批次用于前置依赖(如 `fallow-scan` 静态分析先行,后续审查才有意义)
|
|
66
66
|
- 批内某 agent 无 must-fix 后后续轮跳过(`skipCleanAgents` 默认 true + `recheckAfterFix` 默认 false):clean agent 下轮跳过不重派;显式传 `recheckAfterFix=true` 启用强回归模式——fix 后重派全批,clean agent 走限定 prompt(只审 modifiedFiles ∪ 自检关联点,不诱导全量重扫)
|
|
67
|
-
- agent
|
|
68
|
-
- `fixAgent`(可选):fix 阶段加载指定 agent
|
|
67
|
+
- agent 项仅支持 .md 文件绝对路径(如 `batch1=/path/to/reviewer.md`,`~/` 前缀可展开;内置角色取 <available_subagents> 注入的 <location> 路径,名字只是展示标签,裸名会被拒);`fallow-scan` 静态分析不走 agent 项——由独立参数 `fallowScan=true` 前置插入首批(不占 batchN);**内置 `doc-reviewer`**(文档场景推荐:`targetType=file/dir` + `batch1=<doc-reviewer.md 的注入路径>`,四遍审查方法论:事实锚点核实/逻辑断言验证/落地清单完备性/边界与迁移;不写文件,报告经 schema 返回由 workflow 落盘)
|
|
68
|
+
- `fixAgent`(可选):fix 阶段加载指定 agent(.md 绝对路径,值语义同 batchN 的 agent 项);代码场景可在该 agent.md 内写 verify 命令(typecheck/test 实测)当轮拦截编译类回归。⚠️ agent.md 内写的 verify 命令**必须确认能在目标项目可运行**(target 的包管理器/目录结构未知),否则命令失败会误报 fix 状态
|
|
69
69
|
- `maxFixAttempts`(可选,默认 2):needs-redesign 阈值。问题经 maxFixAttempts 次修复仍未收敛(regressed)→ 终止该批,terminated="needs-redesign"(结构性问题需人工介入,非继续补丁能解决)
|
|
70
70
|
- `convergeNewIssues`(可选,默认 1)+ `convergeRounds`(可选,默认 2):新发现率收敛阈值。连续 convergeRounds 轮新发现问题 ≤ convergeNewIssues **且**无 open/regressed 活跃条目 → terminated="converged"(推进下一批)。收敛不等于问题全清——需同时满足无活跃条目才终止
|
|
71
71
|
- ⚠️ **fix 阶段会修改文件;`autoCommit` 默认 false(不 commit)**,需要提交时显式 `autoCommit=true`
|
|
72
72
|
|
|
73
73
|
## 编排 API
|
|
74
74
|
|
|
75
|
-
这些 workflow 内部使用的编排函数(`agent()` / `parallel()` / `pipeline()` / `workflow()`)由 worker 线程注入,完整 API 参考见
|
|
75
|
+
这些 workflow 内部使用的编排函数(`agent()` / `parallel()` / `pipeline()` / `workflow()`)由 worker 线程注入,完整 API 参考见 workflow-script-format SKILL.md——该文档位于 pi 侧 subagent-workflow extension 内(`extensions/universal/subagent-workflow/skills/workflow-script-format/SKILL.md`,相对 pi extension 包根解析),**不是本包资产**,本包内无对应路径。
|
|
76
76
|
|
|
77
77
|
## 相关文档
|
|
78
78
|
|
|
79
|
-
-
|
|
80
|
-
- `docs/extensions/adr/pi-ext-030-subagents-workflow-merge.md
|
|
81
|
-
- `docs/extensions/adr/pi-ext-032-builtin-orchestration-workflows.md
|
|
79
|
+
- workflow-script-format SKILL.md(位于 pi 侧 subagent-workflow extension,`extensions/universal/subagent-workflow/skills/workflow-script-format/`,非本包资产)— workflow script 完整 API(agent/parallel/pipeline/workflow 签名、$ARGS/$BUDGET、lint 规则)
|
|
80
|
+
- `docs/extensions/adr/pi-ext-030-subagents-workflow-merge.md`(位于 workspace 仓根,非本包内路径)— 合并决策(决策 3 分层配额 + workflow 嵌套)
|
|
81
|
+
- `docs/extensions/adr/pi-ext-032-builtin-orchestration-workflows.md`(位于 workspace 仓根,非本包内路径)— 从"参考模板"改为"内置通用编排 workflow"的决策
|
package/workflows/chain.js
CHANGED
|
@@ -4,7 +4,8 @@
|
|
|
4
4
|
// 适用于需要"先分析、再变换、最后综合"的多阶段任务。
|
|
5
5
|
//
|
|
6
6
|
// 用法:
|
|
7
|
-
// workflow run chain --args task="把这段需求文档拆成技术任务:..."
|
|
7
|
+
// workflow run chain --args task="把这段需求文档拆成技术任务:..."(pi 宿主语法)
|
|
8
|
+
// zsw workflow --workflow chain --task "<任务书>" --workdir <绝对路径>(zsw 宿主直参语法;`zsw` 为 CLI 简写,实际执行以 SessionStart 注入段的 node "<绝对路径>/bin/zsw.js" 形态为准;per-workflow 参数用 zsw 专属 flag,语义见 @pi-meta parameters)
|
|
8
9
|
//
|
|
9
10
|
// ⚠️ lintScript 约束(本脚本已遵守):
|
|
10
11
|
// - 含 agent() 入口
|
|
@@ -25,7 +26,8 @@ usage: |
|
|
|
25
26
|
## 使用说明
|
|
26
27
|
- 顺序三步链:analyze(提取要点)→ transform(产出方案)→ synthesize(合成结论)
|
|
27
28
|
- agents:逗号分隔的 agent .md 绝对路径,按顺序对应三步(少于 3 个尾部用默认执行者)
|
|
28
|
-
-
|
|
29
|
+
- 示例(pi 宿主语法):workflow run chain --args task="<任务描述>" agents="/path/analyzer.md,/path/planner.md"
|
|
30
|
+
- 示例(zsw 宿主直参语法;`zsw` 为 CLI 简写,实际以注入段 node "<绝对路径>/bin/zsw.js" 形态为准):zsw workflow --workflow chain --task "<任务描述>" --workdir <绝对路径>(per-workflow 参数用 zsw 专属 flag,语义见 @pi-meta parameters)
|
|
29
31
|
*/
|
|
30
32
|
|
|
31
33
|
// ── 入参($ARGS)──────────────────────────────────────────────────
|
package/workflows/map-reduce.js
CHANGED
|
@@ -8,8 +8,9 @@
|
|
|
8
8
|
// map-reduce 强调对"已知 items 数组"的变换+聚合(items 已有,map 变换、reduce 归约)。
|
|
9
9
|
//
|
|
10
10
|
// 用法:
|
|
11
|
-
// workflow run map-reduce --args 'items=["file1.ts","file2.ts","file3.ts"]' --args operation="审查代码风格"
|
|
12
|
-
// workflow run map-reduce --args itemsJson=/path/to/items.json --args operation="..."
|
|
11
|
+
// workflow run map-reduce --args 'items=["file1.ts","file2.ts","file3.ts"]' --args operation="审查代码风格"(pi 宿主语法)
|
|
12
|
+
// workflow run map-reduce --args itemsJson=/path/to/items.json --args operation="..."(pi 宿主语法)
|
|
13
|
+
// zsw workflow --workflow map-reduce --task "<任务书>" --workdir <绝对路径>(zsw 宿主直参语法;`zsw` 为 CLI 简写,实际执行以 SessionStart 注入段的 node "<绝对路径>/bin/zsw.js" 形态为准;per-workflow 参数用 zsw 专属 flag,语义见 @pi-meta parameters)
|
|
13
14
|
//
|
|
14
15
|
// ⚠️ lintScript 约束(本脚本已遵守):含 parallel() 入口(兼 agent 嵌套),禁止 bare IIFE
|
|
15
16
|
|
|
@@ -32,7 +33,8 @@ usage: |
|
|
|
32
33
|
## 使用说明
|
|
33
34
|
- items 与 itemsJson 至少一个:items 直接传字符串数组,itemsJson 传文件路径(内容为 JSON 数组)
|
|
34
35
|
- agents:逗号分隔的 agent .md 绝对路径,按顺序对应 map/reduce 两段
|
|
35
|
-
-
|
|
36
|
+
- 示例(pi 宿主语法):workflow run map-reduce --args operation="<对每个 item 做什么>" itemsJson="/path/items.json" agents="/path/mapper.md,/path/reducer.md"
|
|
37
|
+
- 示例(zsw 宿主直参语法;`zsw` 为 CLI 简写,实际以注入段 node "<绝对路径>/bin/zsw.js" 形态为准):zsw workflow --workflow map-reduce --task "<任务书>" --workdir <绝对路径>(per-workflow 参数用 zsw 专属 flag,语义见 @pi-meta parameters)
|
|
36
38
|
*/
|
|
37
39
|
|
|
38
40
|
const fs = require("fs");
|
package/workflows/parallel.js
CHANGED
|
@@ -4,8 +4,9 @@
|
|
|
4
4
|
// 适用于需要多维度评估(安全/性能/可维护性等)的场景。
|
|
5
5
|
//
|
|
6
6
|
// 用法:
|
|
7
|
-
// workflow run parallel --args target="src/auth/login.ts"
|
|
8
|
-
// workflow run parallel --args target="..." --args 'perspectives=["security","readability"]'
|
|
7
|
+
// workflow run parallel --args target="src/auth/login.ts"(pi 宿主语法)
|
|
8
|
+
// workflow run parallel --args target="..." --args 'perspectives=["security","readability"]'(pi 宿主语法)
|
|
9
|
+
// zsw workflow --workflow parallel --task "<分析目标>" --workdir <绝对路径>(zsw 宿主直参语法;`zsw` 为 CLI 简写,实际执行以 SessionStart 注入段的 node "<绝对路径>/bin/zsw.js" 形态为准;per-workflow 参数用 zsw 专属 flag,语义见 @pi-meta parameters)
|
|
9
10
|
//
|
|
10
11
|
// ⚠️ 分层配额规则(来源:ADR-030 决策 3):
|
|
11
12
|
// - 全局并发上限 maxConcurrent = 6
|
|
@@ -29,7 +30,8 @@ usage: |
|
|
|
29
30
|
## 使用说明
|
|
30
31
|
- 多视角并行分析后聚合;perspectives 缺省用 3 个默认视角
|
|
31
32
|
- agents:逗号分隔的 agent .md 绝对路径;1 个应用于所有视角,N 个一一对应视角数
|
|
32
|
-
-
|
|
33
|
+
- 示例(pi 宿主语法):workflow run parallel --args target="<分析目标>" agents="/path/analyst.md"
|
|
34
|
+
- 示例(zsw 宿主直参语法;`zsw` 为 CLI 简写,实际以注入段 node "<绝对路径>/bin/zsw.js" 形态为准):zsw workflow --workflow parallel --task "<分析目标>" --workdir <绝对路径>(per-workflow 参数用 zsw 专属 flag,语义见 @pi-meta parameters)
|
|
33
35
|
*/
|
|
34
36
|
|
|
35
37
|
// ── 入参($ARGS)──────────────────────────────────────────────────
|