@zhushanwen/pi-subagent-workflow 8.6.0 → 8.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +5 -11
- package/package.json +13 -20
- package/relay/relay.mjs +1 -1
- package/skills/workflow-script-format/SKILL.md +32 -13
- package/src/host/__tests__/pi-host.test.ts +235 -0
- package/src/host/pi-host.ts +163 -0
- package/src/index.ts +141 -138
- package/src/injectors/__tests__/engine-awareness.test.ts +292 -0
- package/src/injectors/__tests__/engine-section-stability.test.ts +343 -0
- package/src/injectors/__tests__/model-list-injector.test.ts +18 -21
- package/src/injectors/__tests__/subagent-list-injector.test.ts +59 -19
- package/src/injectors/__tests__/workflow-list-injector.test.ts +31 -17
- package/src/injectors/engine-awareness.ts +119 -0
- package/src/injectors/model-list-injector.ts +15 -58
- package/src/injectors/subagent-list-injector.ts +56 -114
- package/src/injectors/workflow-list-injector.ts +37 -70
- package/src/interface/__tests__/detectors.test.ts +48 -37
- package/src/interface/__tests__/subagent-tool-path-guard.test.ts +2 -2
- package/src/interface/__tests__/subagent-tool-prompt.test.ts +6 -3
- package/src/interface/__tests__/tool-workflow-run-builtin-name.test.ts +216 -0
- package/src/interface/__tests__/tool-workflow-script-generate.test.ts +17 -6
- package/src/interface/__tests__/tool-workflow-throw-paths.test.ts +38 -2
- package/src/interface/bg-notify-render.ts +7 -17
- package/src/interface/command-actions.ts +5 -15
- package/src/interface/commands.ts +4 -4
- package/src/interface/format.ts +17 -6
- package/src/interface/gui-mappers.ts +18 -22
- package/src/interface/helpers.ts +9 -130
- package/src/interface/list-component.ts +5 -5
- package/src/interface/list-shared.ts +3 -3
- package/src/interface/list-view.ts +3 -3
- package/src/interface/subagent-actions.ts +66 -439
- package/src/interface/subagent-tool-schema.ts +21 -17
- package/src/interface/subagent-tool.ts +12 -7
- package/src/interface/subagents.ts +4 -4
- package/src/interface/tool-render.ts +37 -15
- package/src/interface/tool-workflow-script.ts +34 -76
- package/src/interface/tool-workflow.ts +57 -94
- package/src/interface/views/WorkflowsView.ts +8 -16
- package/src/interface/views/__tests__/WorkflowsView-signature.test.ts +3 -3
- package/src/interface/views/__tests__/detail-content-session-file.test.ts +2 -2
- package/src/interface/views/detail-content.ts +4 -4
- package/src/interface/views/format.ts +23 -62
- package/src/{orchestration/jsonl-run-store.ts → jsonl-run-store.ts} +137 -225
- package/agents/analyst.md +0 -61
- package/agents/coder.md +0 -70
- package/agents/debugger.md +0 -67
- package/agents/doc-reviewer.md +0 -50
- package/agents/explorer.md +0 -64
- package/agents/general-purpose.md +0 -32
- package/agents/orchestrator.md +0 -63
- package/agents/planner.md +0 -54
- package/agents/researcher.md +0 -65
- package/agents/reviewer.md +0 -74
- package/src/execution/__tests__/__fixtures__/notifier-golden-snapshots.json +0 -53
- package/src/execution/__tests__/__fixtures__/truncline.snapshot.json +0 -1
- package/src/execution/__tests__/agent-registry.test.ts +0 -363
- package/src/execution/__tests__/agent-result-mapper.test.ts +0 -150
- package/src/execution/__tests__/alive-store.test.ts +0 -147
- package/src/execution/__tests__/ask-user-transit-e2e.test.ts +0 -490
- package/src/execution/__tests__/before-agent-start-injection.test.ts +0 -132
- package/src/execution/__tests__/bg-notify-render.test.ts +0 -329
- package/src/execution/__tests__/channel-registry-handshake.test.ts +0 -243
- package/src/execution/__tests__/chat-engine-routing.test.ts +0 -601
- package/src/execution/__tests__/chatmode-first-round-closure-service.test.ts +0 -365
- package/src/execution/__tests__/chatmode-first-round-closure-spawn.test.ts +0 -190
- package/src/execution/__tests__/chatmode-round-notify-real-chain.test.ts +0 -215
- package/src/execution/__tests__/concurrency-pool.test.ts +0 -250
- package/src/execution/__tests__/config.test.ts +0 -110
- package/src/execution/__tests__/conversation-wiring.test.ts +0 -198
- package/src/execution/__tests__/crash-recovery.test.ts +0 -320
- package/src/execution/__tests__/delivery-methods.test.ts +0 -422
- package/src/execution/__tests__/dialog-queue.test.ts +0 -299
- package/src/execution/__tests__/epipe-fallback.test.ts +0 -241
- package/src/execution/__tests__/execute-and-await-worktree.test.ts +0 -243
- package/src/execution/__tests__/execute-nesting.test.ts +0 -323
- package/src/execution/__tests__/execute-options-mapper.test.ts +0 -200
- package/src/execution/__tests__/execution-record.test.ts +0 -1394
- package/src/execution/__tests__/explicit-agent-ref-guard.test.ts +0 -171
- package/src/execution/__tests__/finalize-record.test.ts +0 -368
- package/src/execution/__tests__/finalized-marker.test.ts +0 -82
- package/src/execution/__tests__/format-schema-instruction.test.ts +0 -169
- package/src/execution/__tests__/format.test.ts +0 -458
- package/src/execution/__tests__/gc-timer.test.ts +0 -184
- package/src/execution/__tests__/get-record-for-action-restart.test.ts +0 -254
- package/src/execution/__tests__/gui-mode-dispatch.test.ts +0 -59
- package/src/execution/__tests__/helpers/mock-extension-api.ts +0 -30
- package/src/execution/__tests__/helpers/spawn-mock.ts +0 -242
- package/src/execution/__tests__/host-mode.test.ts +0 -87
- package/src/execution/__tests__/index-session-start-identity.test.ts +0 -371
- package/src/execution/__tests__/index-session-start.test.ts +0 -672
- package/src/execution/__tests__/lifecycle-manager-lock.test.ts +0 -211
- package/src/execution/__tests__/lifecycle-manager.test.ts +0 -383
- package/src/execution/__tests__/lifecycle-predicates.test.ts +0 -116
- package/src/execution/__tests__/list-component.test.ts +0 -401
- package/src/execution/__tests__/list-fields.test.ts +0 -140
- package/src/execution/__tests__/manifest-parentid.test.ts +0 -117
- package/src/execution/__tests__/model-resolver.test.ts +0 -465
- package/src/execution/__tests__/nested-visibility-env-propagation.test.ts +0 -287
- package/src/execution/__tests__/nested-visibility.test.ts +0 -325
- package/src/execution/__tests__/notifier-flush.test.ts +0 -612
- package/src/execution/__tests__/notifier-golden-snapshot.test.ts +0 -261
- package/src/execution/__tests__/notify-ledger.test.ts +0 -826
- package/src/execution/__tests__/one-shot-upgrade.test.ts +0 -205
- package/src/execution/__tests__/output-collector.test.ts +0 -358
- package/src/execution/__tests__/parent-child-matrix.test.ts +0 -336
- package/src/execution/__tests__/path-encoding.test.ts +0 -104
- package/src/execution/__tests__/pi-invocation.test.ts +0 -134
- package/src/execution/__tests__/record-store.test.ts +0 -1057
- package/src/execution/__tests__/records-cwd-isolation.test.ts +0 -91
- package/src/execution/__tests__/recursive-visibility-baseline.test.ts +0 -339
- package/src/execution/__tests__/recursive-visibility-env.test.ts +0 -273
- package/src/execution/__tests__/relay-agent.test.ts +0 -448
- package/src/execution/__tests__/relay-env.test.ts +0 -42
- package/src/execution/__tests__/resource-policy.test.ts +0 -109
- package/src/execution/__tests__/rpc-mode.test.ts +0 -89
- package/src/execution/__tests__/run-and-finalize-chatmode.test.ts +0 -267
- package/src/execution/__tests__/run-spawn-chatmode-settled.test.ts +0 -253
- package/src/execution/__tests__/run-spawn-edges.test.ts +0 -687
- package/src/execution/__tests__/run-spawn-integration.test.ts +0 -933
- package/src/execution/__tests__/run-spawn-resume.test.ts +0 -322
- package/src/execution/__tests__/run-spawn-rpc-mode.test.ts +0 -196
- package/src/execution/__tests__/run-spawn-stdout-callback-throw.test.ts +0 -199
- package/src/execution/__tests__/sdk-contract.test.ts +0 -273
- package/src/execution/__tests__/session-context-resolver.test.ts +0 -167
- package/src/execution/__tests__/session-file-gc.test.ts +0 -293
- package/src/execution/__tests__/session-pending.test.ts +0 -197
- package/src/execution/__tests__/session-reconstructor.test.ts +0 -379
- package/src/execution/__tests__/session-runner-epipe.test.ts +0 -178
- package/src/execution/__tests__/session-runner-schema-env.test.ts +0 -350
- package/src/execution/__tests__/session-start-reaper.test.ts +0 -233
- package/src/execution/__tests__/spawn-args.test.ts +0 -445
- package/src/execution/__tests__/spawn-event-adapter-rpc.test.ts +0 -189
- package/src/execution/__tests__/spawn-event-adapter.test.ts +0 -167
- package/src/execution/__tests__/spawn-worktree-guidance.test.ts +0 -207
- package/src/execution/__tests__/spawned-children.test.ts +0 -92
- package/src/execution/__tests__/start-sync-model-guard.test.ts +0 -150
- package/src/execution/__tests__/startup-config-declaration.test.ts +0 -35
- package/src/execution/__tests__/status-refactor.test.ts +0 -345
- package/src/execution/__tests__/stdin-writer.test.ts +0 -463
- package/src/execution/__tests__/stream-sink-retirement.test.ts +0 -261
- package/src/execution/__tests__/subagent-service-abort.test.ts +0 -60
- package/src/execution/__tests__/subagent-service-message-close.test.ts +0 -629
- package/src/execution/__tests__/subagent-service-parent-guard.test.ts +0 -180
- package/src/execution/__tests__/subagent-service.test.ts +0 -788
- package/src/execution/__tests__/subprocess-agent-runner-routing.test.ts +0 -310
- package/src/execution/__tests__/subprocess-agent-runner.test.ts +0 -599
- package/src/execution/__tests__/temp-prompt.test.ts +0 -53
- package/src/execution/__tests__/timeout-integration.test.ts +0 -615
- package/src/execution/__tests__/tombstone-store.test.ts +0 -73
- package/src/execution/__tests__/tool-action.test.ts +0 -476
- package/src/execution/__tests__/truncline-snapshot.test.ts +0 -81
- package/src/execution/__tests__/turn-limiter-semantics.test.ts +0 -194
- package/src/execution/__tests__/turn-limiter.test.ts +0 -65
- package/src/execution/__tests__/ui-channels.test.ts +0 -187
- package/src/execution/__tests__/ui-interaction-model.test.ts +0 -67
- package/src/execution/__tests__/ui-request-handler-factory.test.ts +0 -370
- package/src/execution/__tests__/ui-request-handler.test.ts +0 -204
- package/src/execution/__tests__/ui-request-observability.test.ts +0 -114
- package/src/execution/__tests__/ui-request-queue.test.ts +0 -133
- package/src/execution/__tests__/worktree-manager.test.ts +0 -633
- package/src/execution/__tests__/worktree-pid-registration.integration.test.ts +0 -229
- package/src/execution/__tests__/worktree-reconcile.integration.test.ts +0 -181
- package/src/execution/__tests__/worktree-registry.test.ts +0 -199
- package/src/execution/agent-registry.ts +0 -199
- package/src/execution/agent-result-mapper.ts +0 -90
- package/src/execution/alive-store.ts +0 -92
- package/src/execution/argv-mirror.ts +0 -113
- package/src/execution/best-effort.ts +0 -38
- package/src/execution/channel-registry-access.ts +0 -144
- package/src/execution/concurrency-pool.ts +0 -116
- package/src/execution/config.ts +0 -96
- package/src/execution/dialog-queue.ts +0 -330
- package/src/execution/engine/__tests__/common/data-dir.test.ts +0 -53
- package/src/execution/engine/__tests__/common/errors.test.ts +0 -132
- package/src/execution/engine/__tests__/common/event-journal.test.ts +0 -177
- package/src/execution/engine/__tests__/common/kill-chain.test.ts +0 -192
- package/src/execution/engine/__tests__/common/nesting-guard.test.ts +0 -81
- package/src/execution/engine/__tests__/common/persona-router.test.ts +0 -123
- package/src/execution/engine/__tests__/common/pool-manager.test.ts +0 -154
- package/src/execution/engine/__tests__/common/schema-emulation.test.ts +0 -128
- package/src/execution/engine/__tests__/conformance/__fixtures__/pi-golden-events.json +0 -28
- package/src/execution/engine/__tests__/conformance/agent-event-invariants.ts +0 -141
- package/src/execution/engine/__tests__/conformance/contract.abort.test.ts +0 -109
- package/src/execution/engine/__tests__/conformance/contract.agent-events.test.ts +0 -101
- package/src/execution/engine/__tests__/conformance/contract.probe.test.ts +0 -77
- package/src/execution/engine/__tests__/conformance/contract.read-degradation.test.ts +0 -104
- package/src/execution/engine/__tests__/conformance/contract.relay.test.ts +0 -342
- package/src/execution/engine/__tests__/conformance/engine-conformance.live.test.ts +0 -201
- package/src/execution/engine/__tests__/conformance/golden-replay.pi.test.ts +0 -76
- package/src/execution/engine/__tests__/conformance/golden-replay.zcode.test.ts +0 -79
- package/src/execution/engine/__tests__/engine-discovery.test.ts +0 -87
- package/src/execution/engine/__tests__/engines-declaration.test.ts +0 -36
- package/src/execution/engine/__tests__/model-prompt.test.ts +0 -85
- package/src/execution/engine/__tests__/paths.test.ts +0 -39
- package/src/execution/engine/__tests__/registry.test.ts +0 -120
- package/src/execution/engine/__tests__/routing.test.ts +0 -231
- package/src/execution/engine/common/data-dir.ts +0 -62
- package/src/execution/engine/common/errors.ts +0 -183
- package/src/execution/engine/common/event-journal.ts +0 -254
- package/src/execution/engine/common/journal-replay.ts +0 -62
- package/src/execution/engine/common/kill-chain.ts +0 -221
- package/src/execution/engine/common/nesting-guard.ts +0 -50
- package/src/execution/engine/common/persona-router.ts +0 -108
- package/src/execution/engine/common/pool-manager.ts +0 -226
- package/src/execution/engine/common/schema-emulation.ts +0 -189
- package/src/execution/engine/common/session-view-projection.ts +0 -51
- package/src/execution/engine/engine-discovery.ts +0 -65
- package/src/execution/engine/engines/pi/__tests__/pi-engine.test.ts +0 -469
- package/src/execution/engine/engines/pi/__tests__/reader.test.ts +0 -155
- package/src/execution/engine/engines/pi/__tests__/task-spec-mapper.test.ts +0 -164
- package/src/execution/engine/engines/pi/pi-engine.ts +0 -415
- package/src/execution/engine/engines/pi/reader.ts +0 -48
- package/src/execution/engine/engines/pi/registration.ts +0 -35
- 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__/parser.test.ts +0 -246
- package/src/execution/engine/engines/zcode/__tests__/preparer.test.ts +0 -228
- package/src/execution/engine/engines/zcode/__tests__/reader.test.ts +0 -210
- package/src/execution/engine/engines/zcode/__tests__/registration.test.ts +0 -64
- package/src/execution/engine/engines/zcode/__tests__/zcode-engine.live.test.ts +0 -127
- package/src/execution/engine/engines/zcode/__tests__/zcode-engine.test.ts +0 -580
- package/src/execution/engine/engines/zcode/constants.ts +0 -43
- package/src/execution/engine/engines/zcode/golden-sample.ts +0 -39
- package/src/execution/engine/engines/zcode/launcher.ts +0 -161
- package/src/execution/engine/engines/zcode/parser.ts +0 -436
- package/src/execution/engine/engines/zcode/preparer.ts +0 -363
- package/src/execution/engine/engines/zcode/reader.ts +0 -381
- package/src/execution/engine/engines/zcode/registration.ts +0 -37
- package/src/execution/engine/engines/zcode/zcode-engine.ts +0 -658
- package/src/execution/engine/host-task-spec.ts +0 -47
- package/src/execution/engine/model-prompt.ts +0 -59
- package/src/execution/engine/paths.ts +0 -42
- package/src/execution/engine/port.ts +0 -153
- package/src/execution/engine/registry.ts +0 -123
- package/src/execution/engine/routing.ts +0 -218
- package/src/execution/engine/types.ts +0 -309
- package/src/execution/execute-options-mapper.ts +0 -112
- package/src/execution/execution-record.ts +0 -965
- package/src/execution/finalize-record.ts +0 -251
- package/src/execution/finalized-marker.ts +0 -51
- package/src/execution/get-state-handshake.ts +0 -104
- package/src/execution/host-mode.ts +0 -56
- package/src/execution/idle-gc.ts +0 -47
- package/src/execution/lifecycle-manager.ts +0 -513
- package/src/execution/lifecycle-predicates.ts +0 -65
- package/src/execution/manifest-store.ts +0 -256
- package/src/execution/model-config-service.ts +0 -219
- package/src/execution/model-resolver.ts +0 -248
- package/src/execution/notifier.ts +0 -330
- package/src/execution/notify-ledger.ts +0 -580
- package/src/execution/output-collector.ts +0 -228
- package/src/execution/path-encoding.ts +0 -60
- package/src/execution/pi-invocation.ts +0 -120
- package/src/execution/record-entry.ts +0 -132
- package/src/execution/record-store.ts +0 -1234
- package/src/execution/relay-env.ts +0 -37
- package/src/execution/session-context-resolver.ts +0 -64
- package/src/execution/session-file-gc.ts +0 -120
- package/src/execution/session-pending.ts +0 -164
- package/src/execution/session-reconstructor.ts +0 -678
- package/src/execution/session-runner.ts +0 -1781
- package/src/execution/sessions-index.ts +0 -304
- package/src/execution/spawn-event-adapter.ts +0 -363
- package/src/execution/stdin-writer.ts +0 -198
- package/src/execution/stream-sink.ts +0 -126
- package/src/execution/subagent-service.ts +0 -2141
- package/src/execution/subprocess-agent-runner.ts +0 -317
- package/src/execution/temp-prompt.ts +0 -62
- package/src/execution/tombstone-store.ts +0 -72
- package/src/execution/turn-limiter.ts +0 -102
- package/src/execution/types.ts +0 -973
- package/src/execution/ui-channels.ts +0 -216
- package/src/execution/ui-interaction-model.ts +0 -48
- package/src/execution/ui-request-handler-factory.ts +0 -212
- package/src/execution/ui-request-observability.ts +0 -81
- package/src/execution/ui-request-queue.ts +0 -184
- package/src/execution/worktree-manager.ts +0 -688
- package/src/execution/worktree-registry.ts +0 -222
- package/src/orchestration/__tests__/__fixtures__/worker-template.snapshot.txt +0 -349
- package/src/orchestration/__tests__/agent-call-catch-fallback.test.ts +0 -202
- package/src/orchestration/__tests__/agent-call-stream.test.ts +0 -152
- package/src/orchestration/__tests__/args-validator.test.ts +0 -143
- package/src/orchestration/__tests__/config-loader.test.ts +0 -503
- package/src/orchestration/__tests__/error-recovery-handlers.test.ts +0 -809
- package/src/orchestration/__tests__/error-recovery-postmessage-defense.test.ts +0 -405
- package/src/orchestration/__tests__/error-recovery-serialize-failed-result.test.ts +0 -56
- package/src/orchestration/__tests__/error-recovery-workflow-call.test.ts +0 -166
- package/src/orchestration/__tests__/execute-agent-call.test.ts +0 -451
- package/src/orchestration/__tests__/jsonl-run-store-corrupt-entry.test.ts +0 -150
- package/src/orchestration/__tests__/jsonl-run-store-loadall-sources.test.ts +0 -171
- package/src/orchestration/__tests__/jsonl-run-store-retention.test.ts +0 -202
- package/src/orchestration/__tests__/jsonl-run-store-session-file.test.ts +0 -1030
- package/src/orchestration/__tests__/launcher-nested-workflow.test.ts +0 -600
- package/src/orchestration/__tests__/lifecycle-runid-injection.test.ts +0 -96
- package/src/orchestration/__tests__/lifecycle.test.ts +0 -659
- package/src/orchestration/__tests__/non-cloneable-return-e2e.test.ts +0 -95
- package/src/orchestration/__tests__/review-fix-loop-e2e.test.ts +0 -2025
- package/src/orchestration/__tests__/script-lint.test.ts +0 -831
- package/src/orchestration/__tests__/skill-discovery.test.ts +0 -201
- package/src/orchestration/__tests__/test-mocks.ts +0 -197
- package/src/orchestration/__tests__/worker-exit-without-result.test.ts +0 -368
- package/src/orchestration/__tests__/worker-host.test.ts +0 -120
- package/src/orchestration/__tests__/worker-returnmeta-passthrough.test.ts +0 -164
- package/src/orchestration/__tests__/worker-script-builder-runtime.test.ts +0 -563
- package/src/orchestration/__tests__/worker-script-builder.test.ts +0 -309
- package/src/orchestration/__tests__/worker-script-template-snapshot.test.ts +0 -129
- package/src/orchestration/__tests__/workflow-nesting-e2e.test.ts +0 -317
- package/src/orchestration/__tests__/workflow-script-lint-memo.test.ts +0 -110
- package/src/orchestration/__tests__/workflows-e2e.test.ts +0 -537
- package/src/orchestration/agent-opts-resolver.ts +0 -174
- package/src/orchestration/args-validator.ts +0 -127
- package/src/orchestration/config-loader.ts +0 -315
- package/src/orchestration/error-recovery.ts +0 -1018
- package/src/orchestration/execute-agent-call.ts +0 -256
- package/src/orchestration/launcher.ts +0 -455
- package/src/orchestration/lifecycle.ts +0 -399
- package/src/orchestration/models/__tests__/budget.test.ts +0 -307
- package/src/orchestration/models/__tests__/trace.test.ts +0 -408
- package/src/orchestration/models/agent-call.ts +0 -83
- package/src/orchestration/models/budget.ts +0 -118
- package/src/orchestration/models/ports.ts +0 -164
- package/src/orchestration/models/run-runtime.ts +0 -104
- package/src/orchestration/models/run-spec.ts +0 -83
- package/src/orchestration/models/run-state.ts +0 -44
- package/src/orchestration/models/trace.ts +0 -183
- package/src/orchestration/models/types.ts +0 -301
- package/src/orchestration/models/workflow-run.ts +0 -254
- package/src/orchestration/models/workflow-script-registry.ts +0 -35
- package/src/orchestration/models/workflow-script.ts +0 -117
- package/src/orchestration/script-lint.ts +0 -766
- package/src/orchestration/skill-discovery.ts +0 -115
- package/src/orchestration/worker-handle.ts +0 -115
- package/src/orchestration/worker-host.ts +0 -98
- package/src/orchestration/worker-script-builder.ts +0 -421
- package/src/orchestration/workflow-files.ts +0 -85
- package/src/orchestration/workflow-script-registry-impl.ts +0 -133
- package/src/shared/__tests__/agent-ref.test.ts +0 -34
- package/src/shared/__tests__/meta-parser.test.ts +0 -304
- package/src/shared/__tests__/model-ref.test.ts +0 -306
- package/src/shared/__tests__/resource-discovery-manifest-cache.test.ts +0 -280
- package/src/shared/__tests__/resource-discovery.test.ts +0 -736
- package/src/shared/__tests__/resource-meta.test.ts +0 -51
- package/src/shared/__tests__/schema-jsonify.test.ts +0 -81
- package/src/shared/__tests__/timer-delay.test.ts +0 -61
- package/src/shared/agent-event.ts +0 -13
- package/src/shared/agent-ref.ts +0 -57
- package/src/shared/meta-parser.ts +0 -261
- package/src/shared/model-ref.ts +0 -286
- package/src/shared/resource-discovery.ts +0 -811
- package/src/shared/resource-meta.ts +0 -65
- package/src/shared/schema-env.ts +0 -44
- package/src/shared/schema-jsonify.ts +0 -58
- package/src/shared/timer-delay.ts +0 -54
- package/src/shared/xml-injection.ts +0 -35
- package/workflows/README.md +0 -81
- package/workflows/_shared/agent-refs.cjs +0 -40
- package/workflows/chain.js +0 -131
- package/workflows/map-reduce.js +0 -174
- package/workflows/parallel.js +0 -148
- package/workflows/review-fix-loop-utils.cjs +0 -1309
- package/workflows/review-fix-loop.js +0 -1404
- package/workflows/scatter-gather.js +0 -178
package/README.md
CHANGED
|
@@ -4,7 +4,7 @@ Pi 的 subagent + workflow 合并包:任务委派 + 多 agent 编排(chain /
|
|
|
4
4
|
|
|
5
5
|
## 内置 Agents
|
|
6
6
|
|
|
7
|
-
按「读/写 × 视角」正交切分,
|
|
7
|
+
按「读/写 × 视角」正交切分,10 个角色零重叠(C1 起随 `@zhushanwen/subagent-core` 的 `agents/` 资产分发,`<available_subagents>` 的 `<location>` 指向 core 包目录):
|
|
8
8
|
|
|
9
9
|
| Agent | 角色 | 读/写 |
|
|
10
10
|
|-------|------|-------|
|
|
@@ -12,6 +12,7 @@ Pi 的 subagent + workflow 合并包:任务委派 + 多 agent 编排(chain /
|
|
|
12
12
|
| `planner` | 复杂任务拆解为有序实施计划(合并需求澄清) | 只读产文档 |
|
|
13
13
|
| `coder` | 代码实现、修改、测试(唯一改代码的角色) | 可改 |
|
|
14
14
|
| `reviewer` | 代码审查与需求验收(含 git diff) | 只读 |
|
|
15
|
+
| `doc-reviewer` | 文档审查(四遍方法论,事实锚点核实;spec / 设计文档) | 只读 |
|
|
15
16
|
| `debugger` | 运行时故障诊断,钉根因 | 只读* |
|
|
16
17
|
| `analyst` | 深度项目分析,产出给人读的报告 | 只读 |
|
|
17
18
|
| `researcher` | 外部资料调研(依赖 tavily skill) | 只读 |
|
|
@@ -30,19 +31,12 @@ Pi 的 subagent + workflow 合并包:任务委派 + 多 agent 编排(chain /
|
|
|
30
31
|
|
|
31
32
|
## Orchestrator 协调器模式
|
|
32
33
|
|
|
33
|
-
|
|
34
|
+
orchestrator 是纯协调器角色:拆解任务 → 委派 subagent → 汇总结果,自身不做执行类工作。orchestrator agent 自身也可递归委派子 orchestrator,实现分层任务拆解(深度受 `Depth: N/10` 护栏保护)。
|
|
34
35
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
### 启动命令
|
|
36
|
+
**工具约束变化(C1/D-5)**:内置模板不再携带 `tools:` frontmatter 白名单,subagent 不再以 `--tools` 白名单启动——工具约束回归宿主默认工具面,orchestrator 靠角色职责(职责边界段)约束自身只做协调。想要白名单的用户在 `<workspace>/.agents/agents/` 放同名 `.md` 覆写(project 级源稳定遮蔽内置,是唯一逃生门),或沿用 pi CLI 的 `--tools` 白名单(临时验证):
|
|
38
37
|
|
|
39
38
|
```bash
|
|
40
|
-
# 方式一:CLI 工具白名单(临时验证最快)
|
|
41
39
|
pi --tools todo,goal_control,workflow,subagent,ask_user
|
|
42
|
-
|
|
43
|
-
# 方式二:白名单 + 注入 orchestrator 的 system prompt(推荐,主进程也具备协调器视角)
|
|
44
|
-
pi --tools todo,goal_control,workflow,subagent,ask_user \
|
|
45
|
-
--append-system-prompt "$(cat ~/.pi/agent/npm/node_modules/@zhushanwen/pi-subagent-workflow/agents/orchestrator.md)"
|
|
46
40
|
```
|
|
47
41
|
|
|
48
42
|
> **依赖**:需先安装本包及相关扩展
|
|
@@ -59,7 +53,7 @@ pi --tools todo,goal_control,workflow,subagent,ask_user \
|
|
|
59
53
|
|
|
60
54
|
## Workflow 生命周期(one-shot)
|
|
61
55
|
|
|
62
|
-
Workflow run 是一次性执行,状态机两态:`running → done`(`done` 唯一终态,reason 区分 completed / aborted / failed / budget_limited / time_limited)。`workflow` tool 仅 3 个 action:`run` / `status` / `abort`。
|
|
56
|
+
Workflow run 是一次性执行,状态机两态:`running → done`(`done` 唯一终态,reason 区分 completed / aborted / failed / budget_limited / time_limited)。`workflow` tool 仅 3 个 action:`run` / `status` / `abort`。run 的 `name` 接受 `<available_workflows>` 列出的 workflow 名(内置 chain / parallel / map-reduce / scatter-gather / review-fix-loop 或已保存脚本)或 `.js` 绝对路径。
|
|
63
57
|
|
|
64
58
|
Runs are one-shot: there is no pause/resume — to stop a run early use abort; for a fresh result start a new run.
|
|
65
59
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@zhushanwen/pi-subagent-workflow",
|
|
3
|
-
"version": "8.
|
|
3
|
+
"version": "8.8.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "index.ts",
|
|
6
6
|
"description": "Unified subagent execution and multi-agent workflow orchestration for Pi — spawned-process agent runtime with sync/background modes, stateful workflow management with persistence, state machine, and execution tracing.",
|
|
@@ -19,17 +19,14 @@
|
|
|
19
19
|
},
|
|
20
20
|
"files": [
|
|
21
21
|
"index.ts",
|
|
22
|
-
"agents/",
|
|
23
22
|
"skills/",
|
|
24
|
-
"workflows/",
|
|
25
23
|
"scripts/",
|
|
26
24
|
"relay/",
|
|
27
25
|
"src/index.ts",
|
|
28
|
-
"src/
|
|
26
|
+
"src/jsonl-run-store.ts",
|
|
27
|
+
"src/host/",
|
|
29
28
|
"src/injectors/",
|
|
30
|
-
"src/
|
|
31
|
-
"src/interface/",
|
|
32
|
-
"src/shared/"
|
|
29
|
+
"src/interface/"
|
|
33
30
|
],
|
|
34
31
|
"xyz-agent": {
|
|
35
32
|
"role": "universal",
|
|
@@ -53,26 +50,22 @@
|
|
|
53
50
|
],
|
|
54
51
|
"skills": [
|
|
55
52
|
"./skills"
|
|
56
|
-
],
|
|
57
|
-
"agents": [
|
|
58
|
-
"./agents"
|
|
59
53
|
]
|
|
60
54
|
},
|
|
61
55
|
"dependencies": {
|
|
62
|
-
"ajv": "^8.20.0",
|
|
63
|
-
"yaml": "^2.9.0",
|
|
64
|
-
"@xyz-agent/extension-protocol": "0.7.0",
|
|
65
56
|
"@xyz-agent/session-delivery": "0.3.0",
|
|
66
|
-
"@zhushanwen/pi-
|
|
67
|
-
"@zhushanwen/pi-
|
|
57
|
+
"@zhushanwen/pi-ext-guards": "0.2.0",
|
|
58
|
+
"@zhushanwen/pi-extension-logger": "0.4.0",
|
|
59
|
+
"@xyz-agent/extension-protocol": "0.8.0",
|
|
60
|
+
"@zhushanwen/subagent-core": "0.4.0"
|
|
68
61
|
},
|
|
69
62
|
"peerDependencies": {
|
|
70
|
-
"@earendil-works/pi-ai": "^0.84.
|
|
71
|
-
"@earendil-works/pi-coding-agent": "^0.84.
|
|
72
|
-
"@earendil-works/pi-tui": "^0.84.
|
|
63
|
+
"@earendil-works/pi-ai": "^0.84.4",
|
|
64
|
+
"@earendil-works/pi-coding-agent": "^0.84.4",
|
|
65
|
+
"@earendil-works/pi-tui": "^0.84.4",
|
|
73
66
|
"typebox": "*",
|
|
74
|
-
"@zhushanwen/pi-
|
|
75
|
-
"@zhushanwen/pi-
|
|
67
|
+
"@zhushanwen/pi-structured-output": "5.1.2",
|
|
68
|
+
"@zhushanwen/pi-pending-notifications": "0.5.2"
|
|
76
69
|
},
|
|
77
70
|
"peerDependenciesMeta": {
|
|
78
71
|
"@earendil-works/pi-coding-agent": {
|
package/relay/relay.mjs
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
* 通道,payload 一律 base64 封装保字节精确。
|
|
9
9
|
*
|
|
10
10
|
* ============================ 镜像常量表 ============================
|
|
11
|
-
* SSOT = src/execution/relay-env.ts(零依赖脚本不能 import workspace 包,只能内嵌镜像;
|
|
11
|
+
* SSOT = packages/subagent-core/src/execution/relay-env.ts(零依赖脚本不能 import workspace 包,只能内嵌镜像;
|
|
12
12
|
* 改名/改值必须双侧同步,一致性由 E-3 conformance relay 变体断言锁定——设计 §10-5):
|
|
13
13
|
*
|
|
14
14
|
* | relay-env.ts 常量 | 本文件常量 | 值 |
|
|
@@ -39,13 +39,22 @@ This is enforced by `lintScript`:
|
|
|
39
39
|
|
|
40
40
|
## Required: Meta Declaration
|
|
41
41
|
|
|
42
|
-
Every script MUST declare
|
|
42
|
+
Every script MUST declare its metadata as a `/* @pi-meta */` YAML block comment at the top level — NOT a `const meta` variable:
|
|
43
43
|
|
|
44
44
|
```javascript
|
|
45
|
-
|
|
45
|
+
/* @pi-meta
|
|
46
|
+
name: workflow-name
|
|
47
|
+
description: One-line description of what the workflow does
|
|
48
|
+
phases: ['phase1', 'phase2']
|
|
49
|
+
*/
|
|
46
50
|
```
|
|
47
51
|
|
|
48
|
-
`name` must match the filename stem. `phases` is for display only.
|
|
52
|
+
- `name` must match the filename stem. `phases` is for display only.
|
|
53
|
+
- Optional fields: `parameters` (JSON Schema for `$ARGS`) and `usage` (markdown).
|
|
54
|
+
- The YAML body starts on the line after `/* @pi-meta`; the closing `*/` must sit alone at column 0.
|
|
55
|
+
- `generate` round-trip-validates the YAML and reports line/col on error (common pitfall: patternProperties regex must use double backslash `\\d`, not `\d`).
|
|
56
|
+
|
|
57
|
+
> **Legacy `const meta = { ... }` (transition only):** `generate` still accepts a legacy top-level `const meta` during the transition window, but the core discovery chain does NOT recognize it (no legacy fallback) — such scripts stay invisible to discovery and get no metadata injection. Always use `/* @pi-meta */` for new scripts.
|
|
49
58
|
|
|
50
59
|
## [MANDATORY] Display: description + phase
|
|
51
60
|
|
|
@@ -59,11 +68,11 @@ TUI `/workflows` 视图按**运行时 `phase()` 调用**分组(非 `meta.phase
|
|
|
59
68
|
### Minimal 示例(三者齐备)
|
|
60
69
|
|
|
61
70
|
```javascript
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
71
|
+
/* @pi-meta
|
|
72
|
+
name: review-fix
|
|
73
|
+
description: review then fix
|
|
74
|
+
phases: ['review', 'fix']
|
|
75
|
+
*/
|
|
67
76
|
|
|
68
77
|
phase('review');
|
|
69
78
|
const r = await agent({ prompt: 'review diff', description: 'review-diff' });
|
|
@@ -79,11 +88,17 @@ return { done: true };
|
|
|
79
88
|
// ❌ agent() 无 description → TUI 显示 unnamed agent
|
|
80
89
|
await agent({ prompt: 'review diff' });
|
|
81
90
|
|
|
82
|
-
// ❌
|
|
83
|
-
|
|
91
|
+
// ❌ phases 用对象数组 → 引擎忽略,全部归入 (unnamed)
|
|
92
|
+
/* @pi-meta
|
|
93
|
+
name: x
|
|
94
|
+
phases: [{ title: 'review' }, { title: 'fix' }]
|
|
95
|
+
*/
|
|
84
96
|
|
|
85
97
|
// ❌ 声明了 phases 但从不 phase() 调用 → 运行时分组失效
|
|
86
|
-
|
|
98
|
+
/* @pi-meta
|
|
99
|
+
name: x
|
|
100
|
+
phases: ['review', 'fix']
|
|
101
|
+
*/
|
|
87
102
|
// ... 直接 await agent(...) 从不调 phase('review') / phase('fix')
|
|
88
103
|
```
|
|
89
104
|
|
|
@@ -201,7 +216,7 @@ const results = await parallel(
|
|
|
201
216
|
);
|
|
202
217
|
```
|
|
203
218
|
|
|
204
|
-
> 内置通用编排 workflow(chain / parallel / scatter-gather / map-reduce,可直接 `workflow run`,用 `agent()` 自包含实现)见 `extensions/universal/subagent-workflow/workflows/`。本段教 `workflow()` 嵌套 API,workflows 目录是开箱即用的通用编排工具(用 `agent()` 而非 `workflow()` 嵌套)。
|
|
219
|
+
> 内置通用编排 workflow(chain / parallel / scatter-gather / map-reduce / review-fix-loop,可直接 `workflow run`,用 `agent()` 自包含实现)见 `extensions/universal/subagent-workflow/workflows/`。本段教 `workflow()` 嵌套 API,workflows 目录是开箱即用的通用编排工具(用 `agent()` 而非 `workflow()` 嵌套)。
|
|
205
220
|
|
|
206
221
|
### Other globals
|
|
207
222
|
|
|
@@ -249,7 +264,11 @@ agent({ prompt: '...', description: 'review-business-logic' });
|
|
|
249
264
|
## Complete Example
|
|
250
265
|
|
|
251
266
|
```javascript
|
|
252
|
-
|
|
267
|
+
/* @pi-meta
|
|
268
|
+
name: review-fix-loop
|
|
269
|
+
description: "Loop: review → fix → commit until clean"
|
|
270
|
+
phases: ['review-fix']
|
|
271
|
+
*/
|
|
253
272
|
|
|
254
273
|
const MAX_ROUNDS = 10;
|
|
255
274
|
let round = 0;
|
|
@@ -0,0 +1,235 @@
|
|
|
1
|
+
// pi-host.test.ts —— pi 壳宿主实现与现行为等价(u0-wire 验收①)。
|
|
2
|
+
//
|
|
3
|
+
// 三视角:①使用者——discoveryRoots 各 kind 的根清单/顺序/source 标签与
|
|
4
|
+
// resource-discovery.ts buildScanTargets(user-pi/npm/npm-dev 段)、
|
|
5
|
+
// skill-discovery.ts resolveSkillPath(skills 两根)现推导逐项一致;
|
|
6
|
+
// ②构建者——dataRoot/log/countActiveFromEntries/createDelivery 四端口桥接形态;
|
|
7
|
+
// ③观察者——getAgentDir 每次现取(PI_CODING_AGENT_DIR 实例隔离切换后重取生效,
|
|
8
|
+
// 无模块级缓存)。
|
|
9
|
+
//
|
|
10
|
+
// mock 策略:pi SDK / pi 宿主协作件全部 vi.mock 工厂覆盖(vitest alias 的
|
|
11
|
+
// mocks/ 桩只供其他测试族用,本文件需要可控返回值)。pending-notifications
|
|
12
|
+
// mock 返回 {count: n} 形状直接验证「适配读 .count」;session-delivery mock
|
|
13
|
+
// 验证 createDelivery 透传(参数 + 返回句柄)。
|
|
14
|
+
|
|
15
|
+
import { join, dirname } from "node:path";
|
|
16
|
+
import { createRequire } from "node:module";
|
|
17
|
+
import { existsSync } from "node:fs";
|
|
18
|
+
|
|
19
|
+
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
|
|
20
|
+
|
|
21
|
+
// ── hoisted mocks(vi.mock 工厂 hoisting 不能引用外部 let/const) ──
|
|
22
|
+
|
|
23
|
+
const piCodingAgentMock = vi.hoisted(() => ({
|
|
24
|
+
// 与实装版 getAgentDir 的 env 契约一致(PI_CODING_AGENT_DIR 实例隔离优先),
|
|
25
|
+
// 使「env 切换后重取生效」可直接断言;缺省值仅作 fallback。
|
|
26
|
+
getAgentDir: vi.fn(() => process.env.PI_CODING_AGENT_DIR ?? "/mock/default/agent-dir"),
|
|
27
|
+
}));
|
|
28
|
+
|
|
29
|
+
const extensionLoggerMock = vi.hoisted(() => ({
|
|
30
|
+
getLogger: vi.fn(),
|
|
31
|
+
}));
|
|
32
|
+
|
|
33
|
+
const pendingNotificationsMock = vi.hoisted(() => ({
|
|
34
|
+
countActiveFromEntries: vi.fn(),
|
|
35
|
+
}));
|
|
36
|
+
|
|
37
|
+
const sessionDeliveryMock = vi.hoisted(() => ({
|
|
38
|
+
createDelivery: vi.fn(),
|
|
39
|
+
}));
|
|
40
|
+
|
|
41
|
+
vi.mock("@earendil-works/pi-coding-agent", () => piCodingAgentMock);
|
|
42
|
+
vi.mock("@zhushanwen/pi-extension-logger", () => extensionLoggerMock);
|
|
43
|
+
vi.mock("@zhushanwen/pi-pending-notifications", () => pendingNotificationsMock);
|
|
44
|
+
vi.mock("@xyz-agent/session-delivery", () => sessionDeliveryMock);
|
|
45
|
+
|
|
46
|
+
import { getAgentDir } from "@earendil-works/pi-coding-agent";
|
|
47
|
+
import { getLogger } from "@zhushanwen/pi-extension-logger";
|
|
48
|
+
import { countActiveFromEntries } from "@zhushanwen/pi-pending-notifications";
|
|
49
|
+
import { createDelivery } from "@xyz-agent/session-delivery";
|
|
50
|
+
|
|
51
|
+
import { createPiHostServices, createPiNotifyDomainPorts } from "../pi-host.ts";
|
|
52
|
+
|
|
53
|
+
beforeEach(() => {
|
|
54
|
+
vi.mocked(getAgentDir).mockClear();
|
|
55
|
+
vi.mocked(getLogger).mockReset();
|
|
56
|
+
vi.mocked(countActiveFromEntries).mockReset();
|
|
57
|
+
vi.mocked(createDelivery).mockReset();
|
|
58
|
+
delete process.env.PI_CODING_AGENT_DIR;
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
afterEach(() => {
|
|
62
|
+
vi.restoreAllMocks();
|
|
63
|
+
delete process.env.PI_CODING_AGENT_DIR;
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
describe("createPiHostServices.discoveryRoots(与现推导逐项一致)", () => {
|
|
67
|
+
// 基线锚点:resource-discovery.ts buildScanTargets(join(agentDir, kind) /
|
|
68
|
+
// join(agentDir, "npm", "node_modules") / join(agentDir, "extensions"))与
|
|
69
|
+
// skill-discovery.ts resolveSkillPath(join(getAgentDir(), "skills") +
|
|
70
|
+
// join(getAgentDir(), "npm/node_modules"))。根列表按优先级低→高排列(D2)。
|
|
71
|
+
const AGENT_DIR = "/fake/agent-dir";
|
|
72
|
+
|
|
73
|
+
function stubAgentDir(): void {
|
|
74
|
+
vi.mocked(getAgentDir).mockReturnValue(AGENT_DIR);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
it("agents 四根:user-pi → npm → npm-dev → core 包父目录(C5⑥,source npm 追加末位)", () => {
|
|
78
|
+
stubAgentDir();
|
|
79
|
+
const roots = createPiHostServices().discoveryRoots?.().agents;
|
|
80
|
+
|
|
81
|
+
// 期望的 core 注入根用与 pi-host.ts 相同的锚点解析(./workflows/* 子入口在
|
|
82
|
+
// workspace 与 npm dist 双形态同径;探针证据见 probe-c5.md P1/P3)
|
|
83
|
+
const require = createRequire(import.meta.url);
|
|
84
|
+
const anchor = require.resolve("@zhushanwen/subagent-core/workflows/README.md");
|
|
85
|
+
const coreParent = dirname(dirname(dirname(anchor)));
|
|
86
|
+
|
|
87
|
+
expect(roots).toEqual([
|
|
88
|
+
{ dir: join(AGENT_DIR, "agents"), source: "user-pi" },
|
|
89
|
+
{ dir: join(AGENT_DIR, "npm", "node_modules"), source: "npm" },
|
|
90
|
+
{ dir: join(AGENT_DIR, "extensions"), source: "npm-dev" },
|
|
91
|
+
// C5⑥:core 包一级父目录(npm 槽语义:一级子项 = 包目录,无 pi manifest 扫
|
|
92
|
+
// agents/ 约定目录);追加在既有 npm 根之后——同标签靠后者胜(新版遮蔽旧残留)
|
|
93
|
+
{ dir: coreParent, source: "npm" },
|
|
94
|
+
]);
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
it("agents 第 4 根指向 core 包的父目录(其下 subagent-core/agents/ 存在 10 内置角色)", () => {
|
|
98
|
+
stubAgentDir();
|
|
99
|
+
const roots = createPiHostServices().discoveryRoots?.().agents;
|
|
100
|
+
const coreRoot = roots?.[3];
|
|
101
|
+
|
|
102
|
+
expect(coreRoot?.source).toBe("npm");
|
|
103
|
+
// 便捷断言:core 包根(注入 dir 的子目录)下 agents/ 真实存在
|
|
104
|
+
expect(existsSync(join(coreRoot!.dir, "subagent-core", "agents"))).toBe(true);
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
it("workflows 三根:与 agents 同构,末级目录名切换为 workflows", () => {
|
|
108
|
+
stubAgentDir();
|
|
109
|
+
const roots = createPiHostServices().discoveryRoots?.().workflows;
|
|
110
|
+
|
|
111
|
+
expect(roots).toEqual([
|
|
112
|
+
{ dir: join(AGENT_DIR, "workflows"), source: "user-pi" },
|
|
113
|
+
{ dir: join(AGENT_DIR, "npm", "node_modules"), source: "npm" },
|
|
114
|
+
{ dir: join(AGENT_DIR, "extensions"), source: "npm-dev" },
|
|
115
|
+
]);
|
|
116
|
+
});
|
|
117
|
+
|
|
118
|
+
it("skills 两根:user-pi + npm,无 npm-dev(对齐 skill-discovery 现状)", () => {
|
|
119
|
+
stubAgentDir();
|
|
120
|
+
const roots = createPiHostServices().discoveryRoots?.().skills;
|
|
121
|
+
|
|
122
|
+
expect(roots).toEqual([
|
|
123
|
+
{ dir: join(AGENT_DIR, "skills"), source: "user-pi" },
|
|
124
|
+
{ dir: join(AGENT_DIR, "npm", "node_modules"), source: "npm" },
|
|
125
|
+
]);
|
|
126
|
+
});
|
|
127
|
+
|
|
128
|
+
it("每次调用现取 getAgentDir(agentDir 变更后根列表跟随,不缓存)", () => {
|
|
129
|
+
stubAgentDir();
|
|
130
|
+
const first = createPiHostServices().discoveryRoots?.().agents;
|
|
131
|
+
const secondCallDir = "/another/agent-dir";
|
|
132
|
+
vi.mocked(getAgentDir).mockReturnValue(secondCallDir);
|
|
133
|
+
const second = createPiHostServices().discoveryRoots?.().agents;
|
|
134
|
+
|
|
135
|
+
expect(second?.[0].dir).toBe(join(secondCallDir, "agents"));
|
|
136
|
+
expect(first?.[0].dir).not.toBe(second?.[0].dir);
|
|
137
|
+
});
|
|
138
|
+
});
|
|
139
|
+
|
|
140
|
+
describe("createPiHostServices.dataRoot(每次现取 getAgentDir)", () => {
|
|
141
|
+
it("返回 getAgentDir() 本身(env 覆盖段与 warn-once 留 core data-dir)", () => {
|
|
142
|
+
vi.mocked(getAgentDir).mockReturnValue("/data/root");
|
|
143
|
+
expect(createPiHostServices().dataRoot()).toBe("/data/root");
|
|
144
|
+
});
|
|
145
|
+
|
|
146
|
+
it("PI_CODING_AGENT_DIR 切换后重取生效(实例隔离,无模块级缓存)", () => {
|
|
147
|
+
// 恢复 mock 工厂的 env 语义实现(其他用例的 mockReturnValue 会覆盖它)
|
|
148
|
+
vi.mocked(getAgentDir).mockImplementation(
|
|
149
|
+
() => process.env.PI_CODING_AGENT_DIR ?? "/mock/default/agent-dir",
|
|
150
|
+
);
|
|
151
|
+
process.env.PI_CODING_AGENT_DIR = "/instance-a";
|
|
152
|
+
const host = createPiHostServices();
|
|
153
|
+
expect(host.dataRoot()).toBe("/instance-a");
|
|
154
|
+
|
|
155
|
+
process.env.PI_CODING_AGENT_DIR = "/instance-b";
|
|
156
|
+
expect(host.dataRoot()).toBe("/instance-b");
|
|
157
|
+
});
|
|
158
|
+
|
|
159
|
+
it("透传 getAgentDir 调用(不缓存结果、不吞调用)", () => {
|
|
160
|
+
vi.mocked(getAgentDir).mockReturnValue("/d1");
|
|
161
|
+
const host = createPiHostServices();
|
|
162
|
+
host.dataRoot();
|
|
163
|
+
host.dataRoot();
|
|
164
|
+
expect(vi.mocked(getAgentDir)).toHaveBeenCalledTimes(2);
|
|
165
|
+
});
|
|
166
|
+
});
|
|
167
|
+
|
|
168
|
+
describe("createPiHostServices.log(桥接 pi-extension-logger)", () => {
|
|
169
|
+
function stubLogger(): { debug: ReturnType<typeof vi.fn>; warn: ReturnType<typeof vi.fn>; error: ReturnType<typeof vi.fn> } {
|
|
170
|
+
const fake = { debug: vi.fn(), warn: vi.fn(), error: vi.fn() };
|
|
171
|
+
vi.mocked(getLogger).mockReturnValue(fake);
|
|
172
|
+
return fake;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
it("debug level → logger.debug,(message, data) 透传", () => {
|
|
176
|
+
const fake = stubLogger();
|
|
177
|
+
createPiHostServices().log("debug", "subagents", "d-msg", { k: 1 });
|
|
178
|
+
|
|
179
|
+
expect(vi.mocked(getLogger)).toHaveBeenCalledWith("subagents");
|
|
180
|
+
expect(fake.debug).toHaveBeenCalledWith("d-msg", { k: 1 });
|
|
181
|
+
expect(fake.warn).not.toHaveBeenCalled();
|
|
182
|
+
expect(fake.error).not.toHaveBeenCalled();
|
|
183
|
+
});
|
|
184
|
+
|
|
185
|
+
it("warn level → logger.warn;error level → logger.error", () => {
|
|
186
|
+
const fake = stubLogger();
|
|
187
|
+
const host = createPiHostServices();
|
|
188
|
+
|
|
189
|
+
host.log("warn", "comp-a", "w-msg");
|
|
190
|
+
host.log("error", "comp-b", "e-msg", { reason: "x" });
|
|
191
|
+
|
|
192
|
+
expect(fake.warn).toHaveBeenCalledWith("w-msg", undefined);
|
|
193
|
+
expect(fake.error).toHaveBeenCalledWith("e-msg", { reason: "x" });
|
|
194
|
+
expect(vi.mocked(getLogger)).toHaveBeenNthCalledWith(1, "comp-a");
|
|
195
|
+
expect(vi.mocked(getLogger)).toHaveBeenNthCalledWith(2, "comp-b");
|
|
196
|
+
});
|
|
197
|
+
});
|
|
198
|
+
|
|
199
|
+
describe("createPiNotifyDomainPorts.countActiveFromEntries(适配读 .count)", () => {
|
|
200
|
+
it("拆 CountActiveResult.count 为 number(core 端口契约),entries 透传", () => {
|
|
201
|
+
const entries: unknown[] = [{ customType: "pending:register" }];
|
|
202
|
+
vi.mocked(countActiveFromEntries).mockReturnValue({ count: 3, ids: ["a", "b", "c"], entries: [] });
|
|
203
|
+
|
|
204
|
+
const result = createPiNotifyDomainPorts().countActiveFromEntries?.(entries);
|
|
205
|
+
|
|
206
|
+
expect(result).toBe(3);
|
|
207
|
+
expect(vi.mocked(countActiveFromEntries)).toHaveBeenCalledWith(entries);
|
|
208
|
+
});
|
|
209
|
+
|
|
210
|
+
it("零活跃返回 0({count: 0} 形状)", () => {
|
|
211
|
+
vi.mocked(countActiveFromEntries).mockReturnValue({ count: 0, ids: [], entries: [] });
|
|
212
|
+
expect(createPiNotifyDomainPorts().countActiveFromEntries?.([])).toBe(0);
|
|
213
|
+
});
|
|
214
|
+
});
|
|
215
|
+
|
|
216
|
+
describe("createPiNotifyDomainPorts.createDelivery(透传 session-delivery)", () => {
|
|
217
|
+
it("参数透传 + 返回句柄透传(不经包装)", () => {
|
|
218
|
+
const fakePort = {
|
|
219
|
+
supportedPayloads: ["text"] as const,
|
|
220
|
+
isIdle: () => true,
|
|
221
|
+
hasPendingMessages: () => false,
|
|
222
|
+
send: () => undefined,
|
|
223
|
+
};
|
|
224
|
+
const fakeConfig = { intent: "after-run" as const };
|
|
225
|
+
const fakeHandle = { send: () => {}, flush: () => {}, dispose: () => {} };
|
|
226
|
+
vi.mocked(createDelivery).mockReturnValue(fakeHandle);
|
|
227
|
+
|
|
228
|
+
const result = createPiNotifyDomainPorts().createDelivery?.(fakePort, fakeConfig);
|
|
229
|
+
|
|
230
|
+
expect(vi.mocked(createDelivery)).toHaveBeenCalledTimes(1);
|
|
231
|
+
expect(vi.mocked(createDelivery).mock.calls[0][0]).toBe(fakePort);
|
|
232
|
+
expect(vi.mocked(createDelivery).mock.calls[0][1]).toBe(fakeConfig);
|
|
233
|
+
expect(result).toBe(fakeHandle);
|
|
234
|
+
});
|
|
235
|
+
});
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
// src/host/pi-host.ts
|
|
2
|
+
//
|
|
3
|
+
// pi 壳宿主实现(subagent-core 包抽离 u0-wire)。设计权威源:
|
|
4
|
+
// docs/design/subagent-core-package-extraction.md §3.3 D2(含计划期契约细化 3 条)。
|
|
5
|
+
//
|
|
6
|
+
// 本文件属壳侧(shell),不进 core 切面——对 pi SDK 与 pi 宿主协作件
|
|
7
|
+
// (@earendil-works/pi-coding-agent / @zhushanwen/pi-extension-logger /
|
|
8
|
+
// @zhushanwen/pi-pending-notifications / @xyz-agent/session-delivery)的运行时
|
|
9
|
+
// import 收敛在此层,core 闭包(D9 守卫对象)不得出现这些包。
|
|
10
|
+
//
|
|
11
|
+
// 端口语义:
|
|
12
|
+
// - dataRoot / discoveryRoots 每次调用现取 getAgentDir(),禁止模块级缓存:
|
|
13
|
+
// getAgentDir 尊重 PI_CODING_AGENT_DIR 实例隔离(xyz-agent 按 session dir
|
|
14
|
+
// 隔离 pi 实例),缓存会把后续切换实例的进程钉死在首个 agentDir。
|
|
15
|
+
// - discoveryRoots 的根清单/顺序/source 标签与 shared/resource-discovery.ts
|
|
16
|
+
// buildScanTargets、orchestration/skill-discovery.ts resolveSkillPath 的现推导
|
|
17
|
+
// 逐项一致(user-pi / npm / npm-dev 字面即现 ResourceSource 标签)。
|
|
18
|
+
// project/workspace 根不在壳侧提供——core 消费方按 workspaceRoot 自行推导
|
|
19
|
+
// (u0-data-discovery 波次接注入消费)。C5⑥ 起 agents kind 追加第 4 根:
|
|
20
|
+
// core 包一级父目录(source "npm")——core agents/ 资产进 pi 发现面,见
|
|
21
|
+
// corePackageNpmRoot 注释。
|
|
22
|
+
// - countActiveFromEntries 适配:pi 侧真函数返回 CountActiveResult 对象,core
|
|
23
|
+
// 端口契约是 number(core 消费面只读 .count,notify-ports.ts 契约注释)——
|
|
24
|
+
// foundation 单元登记给本单元的适配责任。
|
|
25
|
+
// - createDelivery 透传:@xyz-agent/session-delivery 的 createDelivery 与 core
|
|
26
|
+
// 的 Delivery* 结构化类型逐字段结构兼容(DeliveryHandle 的 sendChecked/depth
|
|
27
|
+
// 是结构超集成员,多不碍兼容)——结构兼容由本注入点 typecheck 守护,上游签名
|
|
28
|
+
// 漂移即红(notify-ports.ts「闭包红线」段)。
|
|
29
|
+
|
|
30
|
+
import { createRequire } from "node:module";
|
|
31
|
+
import { dirname, join } from "node:path";
|
|
32
|
+
|
|
33
|
+
import { getAgentDir } from "@earendil-works/pi-coding-agent";
|
|
34
|
+
import { getLogger } from "@zhushanwen/pi-extension-logger";
|
|
35
|
+
import { countActiveFromEntries } from "@zhushanwen/pi-pending-notifications";
|
|
36
|
+
import { createDelivery } from "@xyz-agent/session-delivery";
|
|
37
|
+
|
|
38
|
+
import type { DiscoveryRoot, HostServices } from "@zhushanwen/subagent-core/core/host-services.ts";
|
|
39
|
+
import type { LogLevel } from "@zhushanwen/subagent-core/core/logger.ts";
|
|
40
|
+
import type { NotifyDomainPorts } from "@zhushanwen/subagent-core/core/notify-ports.ts";
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* core 包(@zhushanwen/subagent-core)agents/ 资产进 pi 发现面的注入根(C5⑥,
|
|
44
|
+
* convergence §5.4 检查点 2;探针证据 docs/design/subagent-core-convergence.probe-c5.md)。
|
|
45
|
+
*
|
|
46
|
+
* 解析锚点 = `@zhushanwen/subagent-core/workflows/README.md`:`./workflows/*` 子入口
|
|
47
|
+
* 在 workspace TS 直引与 npm dist 两种发布形态下同径(publishConfig 保留该子入口),
|
|
48
|
+
* README.md 是两形态都必在的资产文件。core 包根 = 锚点上两级;npm 槽注入其一级
|
|
49
|
+
* 父目录——npm 槽语义:dir 下一级子项 = 包目录,core 无 pi manifest → 扫 agents/
|
|
50
|
+
* 约定目录命中 10 内置角色。
|
|
51
|
+
*
|
|
52
|
+
* 布局覆盖(探针 P2-P5 实测):dev workspace(core 在仓库 packages/ 下)与发布态
|
|
53
|
+
* 嵌套布局(core 在本包 node_modules 内)下这是唯一命中通路;发布态平铺布局
|
|
54
|
+
* (core 与本包同层)下既有 npm 根已命中,本注入是幂等兜底(重复发现被 core
|
|
55
|
+
* realpath 去重吸收)。
|
|
56
|
+
*
|
|
57
|
+
* 每次调用现解析(不 memo):发现调用点稀疏(session_start + 缓存 miss),解析
|
|
58
|
+
* 成本可忽略;失败(异常布局/解析器不可用)降级为不注入并 warn——绝不因资产
|
|
59
|
+
* 接线失败阻断发现主链。
|
|
60
|
+
*/
|
|
61
|
+
function corePackageNpmRoot(): string | undefined {
|
|
62
|
+
try {
|
|
63
|
+
// createRequire 锚定本模块(jiti 加载器下 import.meta.url 可用;不可用则随
|
|
64
|
+
// catch 降级)。require.resolve 沿 pi-sw 自身的依赖解析链——workspace 与发布态
|
|
65
|
+
// 都从本包出发命中 core。
|
|
66
|
+
const require = createRequire(import.meta.url);
|
|
67
|
+
const anchor = require.resolve("@zhushanwen/subagent-core/workflows/README.md");
|
|
68
|
+
return dirname(dirname(dirname(anchor)));
|
|
69
|
+
} catch (err) {
|
|
70
|
+
// getLogger 惰性调用(catch 是冷路径——测试环境对 pi-extension-logger 的
|
|
71
|
+
// module-level mock 可能返回 undefined,模块级持有会在 import 期踩 undefined)
|
|
72
|
+
getLogger("pi-host").warn(
|
|
73
|
+
"[pi-host] core 包 agents/ 注入根解析失败——10 内置角色可能不可发现",
|
|
74
|
+
{ reason: err instanceof Error ? err.message : String(err) },
|
|
75
|
+
);
|
|
76
|
+
return undefined;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/** agents/workflows 共享的 agentDir 派生根(末级目录名由 kind 决定)。
|
|
81
|
+
* 顺序与 source 标签逐项对齐 resource-discovery.ts buildScanTargets 的
|
|
82
|
+
* user-pi → npm → npm-dev 段(根列表按优先级低→高排列,D2 语义边界)。 */
|
|
83
|
+
function agentDirKindRoots(kind: "agents" | "workflows"): DiscoveryRoot[] {
|
|
84
|
+
const agentDir = getAgentDir();
|
|
85
|
+
const roots: DiscoveryRoot[] = [
|
|
86
|
+
// 1. user .pi/agent/<kind>/
|
|
87
|
+
{ dir: join(agentDir, kind), source: "user-pi" },
|
|
88
|
+
// 2. npm global: agentDir/npm/node_modules/*/<pkg>/
|
|
89
|
+
{ dir: join(agentDir, "npm", "node_modules"), source: "npm" },
|
|
90
|
+
// 3. npm dev symlink: agentDir/extensions/*/<pkg>/
|
|
91
|
+
{ dir: join(agentDir, "extensions"), source: "npm-dev" },
|
|
92
|
+
];
|
|
93
|
+
// 4. core 包根(C5⑥,仅 agents kind):追加在既有 npm 根之后——同标签多根依注入
|
|
94
|
+
// 序扫描 + last-writer-wins,core(随本包依赖分发的新模板)遮蔽同 agentDir 内
|
|
95
|
+
// 旧版残留副本;序位仍在 user 级之上、npm-dev/project 级之下(红线 1)。
|
|
96
|
+
// workflows kind 刻意不注入:<available_workflows> 的 <location> 是 CA2 快照
|
|
97
|
+
// 不豁免面(红线 8 豁免仅限 10 内置 agent 角色路径前缀),注入会翻转内置
|
|
98
|
+
// workflow 的胜出路径。
|
|
99
|
+
if (kind === "agents") {
|
|
100
|
+
const coreNpmRoot = corePackageNpmRoot();
|
|
101
|
+
if (coreNpmRoot !== undefined) {
|
|
102
|
+
roots.push({ dir: coreNpmRoot, source: "npm" });
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
return roots;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/** skills 的 agentDir 派生根。对齐 skill-discovery.ts resolveSkillPath 的两处
|
|
109
|
+
* 推导(<agentDir>/skills + <agentDir>/npm/node_modules)——现状无 npm-dev 根,
|
|
110
|
+
* 刻意不补(避免静默引入新发现源)。 */
|
|
111
|
+
function skillRoots(): DiscoveryRoot[] {
|
|
112
|
+
const agentDir = getAgentDir();
|
|
113
|
+
return [
|
|
114
|
+
{ dir: join(agentDir, "skills"), source: "user-pi" },
|
|
115
|
+
{ dir: join(agentDir, "npm", "node_modules"), source: "npm" },
|
|
116
|
+
];
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
/** pi 宿主 HostServices 实现(扩展初始化最早处经 configureCore 注入)。 */
|
|
120
|
+
export function createPiHostServices(): HostServices {
|
|
121
|
+
return {
|
|
122
|
+
// 每次现取 getAgentDir(实例隔离,见文件头);env 覆盖段与 warn-once 留 core
|
|
123
|
+
// data-dir.ts,壳只返回数据根本身(D2 计划期细化③分段归属)。
|
|
124
|
+
dataRoot(): string {
|
|
125
|
+
return getAgentDir();
|
|
126
|
+
},
|
|
127
|
+
|
|
128
|
+
// 桥接到 pi-extension-logger:component 即 extName(复用其 loggerCache 单例
|
|
129
|
+
// 与 appendEntry/文件日志通路),按 level 分派方法,(message, data) 透传。
|
|
130
|
+
log(level: LogLevel, component: string, message: string, data?: unknown): void {
|
|
131
|
+
const logger = getLogger(component);
|
|
132
|
+
if (level === "error") logger.error(message, data);
|
|
133
|
+
else if (level === "warn") logger.warn(message, data);
|
|
134
|
+
else logger.debug(message, data);
|
|
135
|
+
},
|
|
136
|
+
|
|
137
|
+
discoveryRoots(): {
|
|
138
|
+
agents?: DiscoveryRoot[];
|
|
139
|
+
skills?: DiscoveryRoot[];
|
|
140
|
+
workflows?: DiscoveryRoot[];
|
|
141
|
+
} {
|
|
142
|
+
return {
|
|
143
|
+
agents: agentDirKindRoots("agents"),
|
|
144
|
+
skills: skillRoots(),
|
|
145
|
+
workflows: agentDirKindRoots("workflows"),
|
|
146
|
+
};
|
|
147
|
+
},
|
|
148
|
+
};
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
/** pi 侧通知域窄端口实现(configureNotifyDomain 注入)。zsw 壳不注入本端口
|
|
152
|
+
* (其完成通知走 HostServices.notify,P2 落地)。 */
|
|
153
|
+
export function createPiNotifyDomainPorts(): NotifyDomainPorts {
|
|
154
|
+
return {
|
|
155
|
+
// pi 真函数返回 CountActiveResult,core 契约只读 .count——壳侧拆数值。
|
|
156
|
+
countActiveFromEntries(entries: unknown[]): number {
|
|
157
|
+
return countActiveFromEntries(entries).count;
|
|
158
|
+
},
|
|
159
|
+
|
|
160
|
+
// 投递内核工厂直传本体(结构兼容论证见文件头);不经包装避免多一层间接面。
|
|
161
|
+
createDelivery,
|
|
162
|
+
};
|
|
163
|
+
}
|