pi-crew 0.9.16 → 0.9.17
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/CHANGELOG.md +81 -0
- package/README.md +19 -0
- package/dist/build-meta.json +21790 -0
- package/dist/index.mjs +83070 -0
- package/dist/index.mjs.map +7 -0
- package/docs/A +358 -0
- package/docs/M-A +357 -0
- package/docs/REVIEW-FINDINGS-2026-06 +357 -0
- package/docs/Y +357 -0
- package/docs/a +357 -0
- package/docs/aA +358 -0
- package/docs/archive/README.md +91 -0
- package/docs/patterns/command-agent-skill.md +1 -1
- package/docs/skills/REFERENCE.md +0 -17
- package/docs//303/242mmaAAA/303/242 +357 -0
- package/index.bundle.ts +25 -0
- package/index.ts +95 -4
- package/package.json +15 -4
- package/skills/iterative-audit/SKILL.md +0 -1
- package/skills/widget-rendering/SKILL.md +17 -0
- package/src/adapters/claude-adapter.ts +1 -3
- package/src/adapters/export-util.ts +16 -16
- package/src/adapters/index.ts +5 -5
- package/src/agents/agent-config.ts +20 -14
- package/src/agents/agent-serializer.ts +1 -1
- package/src/agents/discover-agents.ts +83 -39
- package/src/benchmark/benchmark-runner.ts +51 -51
- package/src/benchmark/feedback-loop.ts +1 -1
- package/src/config/config.ts +166 -590
- package/src/config/defaults.ts +28 -2
- package/src/config/drift-detector.ts +11 -14
- package/src/config/markers.ts +201 -203
- package/src/config/resilient-parser.ts +14 -6
- package/src/config/role-tools.ts +3 -3
- package/src/config/suggestions.ts +5 -12
- package/src/config/types.ts +9 -25
- package/src/errors.ts +151 -157
- package/src/extension/action-suggestions.ts +54 -9
- package/src/extension/async-notifier.ts +43 -13
- package/src/extension/autonomous-policy.ts +77 -37
- package/src/extension/command-completions.ts +9 -8
- package/src/extension/context-status-injection.ts +14 -12
- package/src/extension/crew-autocomplete.ts +8 -16
- package/src/extension/crew-cleanup.ts +2 -1
- package/src/extension/crew-shortcuts.ts +9 -6
- package/src/extension/cross-extension-rpc.ts +136 -42
- package/src/extension/help.ts +1 -1
- package/src/extension/import-index.ts +10 -5
- package/src/extension/knowledge-injection.ts +88 -15
- package/src/extension/management.ts +89 -349
- package/src/extension/message-renderers.ts +3 -4
- package/src/extension/notification-router.ts +22 -5
- package/src/extension/notification-sink.ts +6 -3
- package/src/extension/pi-api.ts +17 -8
- package/src/extension/plan-orchestrate.ts +8 -27
- package/src/extension/project-init.ts +21 -6
- package/src/extension/register.ts +329 -975
- package/src/extension/registration/artifact-cleanup.ts +9 -4
- package/src/extension/registration/command-utils.ts +5 -1
- package/src/extension/registration/commands.ts +806 -314
- package/src/extension/registration/compaction-guard.ts +15 -15
- package/src/extension/registration/lifecycle.ts +259 -0
- package/src/extension/registration/observability.ts +293 -0
- package/src/extension/registration/subagent-helpers.ts +29 -7
- package/src/extension/registration/subagent-tools.ts +253 -44
- package/src/extension/registration/team-tool.ts +19 -84
- package/src/extension/registration/ui.ts +168 -0
- package/src/extension/registration/viewers.ts +64 -24
- package/src/extension/result-watcher.ts +18 -7
- package/src/extension/run-bundle-schema.ts +21 -6
- package/src/extension/run-export.ts +15 -6
- package/src/extension/run-import.ts +64 -29
- package/src/extension/run-index.ts +28 -9
- package/src/extension/run-maintenance.ts +32 -12
- package/src/extension/session-summary.ts +1 -1
- package/src/extension/team-manager-command.ts +64 -7
- package/src/extension/team-onboard.ts +151 -150
- package/src/extension/team-recommendation.ts +121 -21
- package/src/extension/team-tool/anchor.ts +31 -64
- package/src/extension/team-tool/api.ts +929 -141
- package/src/extension/team-tool/auto-summarize.ts +14 -26
- package/src/extension/team-tool/cache-control.ts +1 -5
- package/src/extension/team-tool/cancel.ts +138 -38
- package/src/extension/team-tool/chain-dispatch.ts +5 -13
- package/src/extension/team-tool/chain-executor.ts +29 -51
- package/src/extension/team-tool/config-patch.ts +1 -1
- package/src/extension/team-tool/context.ts +40 -20
- package/src/extension/team-tool/destructive-gate.ts +10 -5
- package/src/extension/team-tool/doctor.ts +170 -51
- package/src/extension/team-tool/explain.ts +228 -214
- package/src/extension/team-tool/failure-patterns.ts +3 -9
- package/src/extension/team-tool/goal-wrap.ts +71 -29
- package/src/extension/team-tool/goal.ts +185 -35
- package/src/extension/team-tool/handle-schedule.ts +34 -15
- package/src/extension/team-tool/handle-settings.ts +94 -56
- package/src/extension/team-tool/health-monitor.ts +27 -108
- package/src/extension/team-tool/inspect.ts +42 -9
- package/src/extension/team-tool/intent-policy.ts +4 -1
- package/src/extension/team-tool/lifecycle-actions.ts +244 -48
- package/src/extension/team-tool/orchestrate.ts +7 -18
- package/src/extension/team-tool/parallel-dispatch.ts +51 -29
- package/src/extension/team-tool/plan.ts +29 -5
- package/src/extension/team-tool/respond.ts +49 -16
- package/src/extension/team-tool/run-not-found.ts +3 -8
- package/src/extension/team-tool/run.ts +80 -317
- package/src/extension/team-tool/status.ts +135 -43
- package/src/extension/team-tool/workflow-manage.ts +92 -25
- package/src/extension/team-tool-types.ts +8 -1
- package/src/extension/team-tool.ts +142 -551
- package/src/extension/validate-resources.ts +39 -8
- package/src/hooks/registry.ts +66 -17
- package/src/hooks/types.ts +1 -1
- package/src/i18n.ts +25 -11
- package/src/observability/correlation.ts +17 -3
- package/src/observability/event-bus.ts +51 -56
- package/src/observability/event-to-metric.ts +117 -15
- package/src/observability/exporters/otlp-exporter.ts +56 -17
- package/src/observability/exporters/prometheus-exporter.ts +1 -1
- package/src/observability/metric-registry.ts +16 -4
- package/src/observability/metric-retention.ts +8 -2
- package/src/observability/metric-sink.ts +11 -3
- package/src/observability/metrics-primitives.ts +42 -9
- package/src/plugins/plugin-define.ts +2 -2
- package/src/plugins/plugin-registry.ts +25 -25
- package/src/plugins/plugins/index.ts +1 -1
- package/src/plugins/plugins/nextjs.ts +16 -16
- package/src/plugins/plugins/vite.ts +7 -11
- package/src/plugins/plugins/vitest.ts +6 -11
- package/src/runtime/adaptive-plan.ts +225 -40
- package/src/runtime/agent-control.ts +58 -15
- package/src/runtime/agent-memory.ts +15 -9
- package/src/runtime/agent-observability.ts +10 -2
- package/src/runtime/anchor-manager.ts +27 -25
- package/src/runtime/async-marker.ts +7 -1
- package/src/runtime/async-runner.ts +27 -23
- package/src/runtime/auto-summarize.ts +7 -13
- package/src/runtime/background-runner.ts +189 -251
- package/src/runtime/batch-barrier.ts +18 -16
- package/src/runtime/cancellation-token.ts +16 -6
- package/src/runtime/cancellation.ts +46 -8
- package/src/runtime/capability-inventory.ts +6 -4
- package/src/runtime/chain-parser.ts +44 -11
- package/src/runtime/chain-runner.ts +63 -69
- package/src/runtime/checkpoint.ts +12 -56
- package/src/runtime/child-pi.ts +343 -78
- package/src/runtime/coalesce-tasks.ts +268 -0
- package/src/runtime/code-summary.ts +71 -26
- package/src/runtime/compact-stages/index.ts +15 -5
- package/src/runtime/compact-stages/tail-capture-stage.ts +7 -2
- package/src/runtime/compact-stages/truncation-stage.ts +4 -1
- package/src/runtime/compaction-summary.ts +17 -10
- package/src/runtime/completion-guard.ts +33 -16
- package/src/runtime/crash-classification.ts +28 -7
- package/src/runtime/crash-recovery.ts +177 -37
- package/src/runtime/crew-agent-records.ts +145 -47
- package/src/runtime/crew-hooks.ts +9 -24
- package/src/runtime/cross-extension-rpc.ts +25 -23
- package/src/runtime/custom-tools/irc-tool.ts +43 -15
- package/src/runtime/custom-tools/submit-result-tool.ts +16 -5
- package/src/runtime/delivery-coordinator.ts +34 -7
- package/src/runtime/delta-conflict.ts +9 -21
- package/src/runtime/deterministic-ast.ts +1 -1
- package/src/runtime/diagnostic-export.ts +53 -20
- package/src/runtime/direct-run.ts +12 -2
- package/src/runtime/dwf-state-store.ts +1 -1
- package/src/runtime/dynamic-workflow-context.ts +186 -58
- package/src/runtime/dynamic-workflow-runner.ts +42 -20
- package/src/runtime/effectiveness.ts +16 -8
- package/src/runtime/errors/crew-errors.ts +7 -11
- package/src/runtime/event-stream-bridge.ts +9 -3
- package/src/runtime/foreground-control.ts +54 -14
- package/src/runtime/foreground-watchdog.ts +9 -6
- package/src/runtime/goal-achievement.ts +27 -10
- package/src/runtime/goal-evaluator.ts +54 -19
- package/src/runtime/goal-loop-runner.ts +280 -99
- package/src/runtime/goal-state-store.ts +27 -17
- package/src/runtime/green-contract.ts +11 -2
- package/src/runtime/group-join.ts +64 -31
- package/src/runtime/handoff-manager.ts +37 -42
- package/src/runtime/heartbeat-gradient.ts +10 -2
- package/src/runtime/heartbeat-watcher.ts +32 -6
- package/src/runtime/hidden-handoff.ts +12 -30
- package/src/runtime/important-line-classifier.ts +12 -2
- package/src/runtime/iteration-hooks.ts +25 -15
- package/src/runtime/live-agent-control.ts +55 -7
- package/src/runtime/live-agent-manager.ts +130 -27
- package/src/runtime/live-control-realtime.ts +23 -3
- package/src/runtime/live-irc.ts +4 -1
- package/src/runtime/live-session-health.ts +12 -4
- package/src/runtime/live-session-runtime.ts +379 -117
- package/src/runtime/manifest-cache.ts +28 -12
- package/src/runtime/mcp-proxy.ts +8 -16
- package/src/runtime/metric-parser.ts +1 -5
- package/src/runtime/model-fallback.ts +55 -18
- package/src/runtime/model-resolver.ts +2 -6
- package/src/runtime/model-scope.ts +19 -3
- package/src/runtime/notebook-helpers.ts +60 -62
- package/src/runtime/orphan-worker-registry.ts +37 -26
- package/src/runtime/output-validator.ts +18 -3
- package/src/runtime/overflow-recovery.ts +5 -4
- package/src/runtime/parallel-research.ts +29 -5
- package/src/runtime/parallel-utils.ts +9 -11
- package/src/runtime/path-overlap.ts +150 -0
- package/src/runtime/peer-dep.ts +12 -17
- package/src/runtime/per-write-validator.ts +1 -3
- package/src/runtime/phase-tracker.ts +342 -330
- package/src/runtime/pi-args.ts +26 -8
- package/src/runtime/pi-json-output.ts +1 -1
- package/src/runtime/pi-spawn.ts +30 -19
- package/src/runtime/pipeline-runner.ts +56 -55
- package/src/runtime/plan-templates.ts +5 -6
- package/src/runtime/policy-engine.ts +43 -7
- package/src/runtime/post-checks.ts +12 -4
- package/src/runtime/post-exit-stdio-guard.ts +2 -2
- package/src/runtime/process-lifecycle.ts +20 -10
- package/src/runtime/process-status.ts +16 -5
- package/src/runtime/progress-event-coalescer.ts +2 -1
- package/src/runtime/progress-tracker.ts +103 -103
- package/src/runtime/prose-compressor.ts +9 -11
- package/src/runtime/recovery-recipes.ts +118 -24
- package/src/runtime/replace.ts +25 -10
- package/src/runtime/resilient-edit.ts +10 -25
- package/src/runtime/result-extractor.ts +1 -2
- package/src/runtime/retry-executor.ts +20 -4
- package/src/runtime/retry-runner.ts +26 -50
- package/src/runtime/role-permission.ts +6 -1
- package/src/runtime/run-coalesced-task-group.ts +256 -0
- package/src/runtime/run-drift.ts +14 -15
- package/src/runtime/run-tracker.ts +6 -28
- package/src/runtime/runtime-policy.ts +1 -6
- package/src/runtime/runtime-resolver.ts +80 -15
- package/src/runtime/scheduler.ts +47 -18
- package/src/runtime/semaphore.ts +5 -7
- package/src/runtime/sensitive-paths.ts +2 -1
- package/src/runtime/session-usage.ts +1 -1
- package/src/runtime/settings-store.ts +16 -12
- package/src/runtime/sidechain-output.ts +6 -2
- package/src/runtime/single-agent-compose.ts +1 -4
- package/src/runtime/skill-effectiveness.ts +29 -97
- package/src/runtime/skill-instructions.ts +40 -83
- package/src/runtime/stale-reconciler.ts +73 -197
- package/src/runtime/stream-preview.ts +1 -1
- package/src/runtime/streaming-output.ts +1 -1
- package/src/runtime/subagent-manager.ts +44 -169
- package/src/runtime/subprocess-tool-registry.ts +4 -1
- package/src/runtime/supervisor-contact.ts +10 -5
- package/src/runtime/task-display.ts +19 -5
- package/src/runtime/task-graph-scheduler.ts +95 -21
- package/src/runtime/task-graph.ts +5 -11
- package/src/runtime/task-health.ts +54 -47
- package/src/runtime/task-id.ts +11 -18
- package/src/runtime/task-output-context.ts +265 -81
- package/src/runtime/task-packet.ts +12 -20
- package/src/runtime/task-quality.ts +6 -14
- package/src/runtime/task-runner/context-retrieval.ts +4 -13
- package/src/runtime/task-runner/live-executor.ts +114 -36
- package/src/runtime/task-runner/output-splitter.ts +152 -0
- package/src/runtime/task-runner/progress.ts +50 -12
- package/src/runtime/task-runner/prompt-builder.ts +31 -7
- package/src/runtime/task-runner/prompt-pipeline.ts +31 -7
- package/src/runtime/task-runner/result-utils.ts +3 -1
- package/src/runtime/task-runner/retrieval-orchestrator.ts +310 -0
- package/src/runtime/task-runner/run-projection.ts +27 -8
- package/src/runtime/task-runner/state-helpers.ts +29 -8
- package/src/runtime/task-runner/tail-read.ts +2 -6
- package/src/runtime/task-runner.ts +180 -326
- package/src/runtime/team-runner-artifacts.ts +13 -0
- package/src/runtime/team-runner.ts +456 -974
- package/src/runtime/tool-output-pruner.ts +6 -9
- package/src/runtime/tool-progress.ts +11 -21
- package/src/runtime/verification-gates.ts +33 -24
- package/src/runtime/verification-integrity.ts +1 -4
- package/src/runtime/verification-worktree.ts +62 -12
- package/src/runtime/worker-heartbeat.ts +5 -1
- package/src/runtime/worker-startup.ts +29 -5
- package/src/runtime/workflow-state.ts +17 -9
- package/src/runtime/workspace-lock.ts +30 -35
- package/src/runtime/workspace-tree.ts +20 -32
- package/src/runtime/yield-handler.ts +43 -9
- package/src/runtime/zombie-scanner.ts +5 -4
- package/src/schema/config-schema.ts +266 -172
- package/src/schema/team-tool-schema.ts +29 -74
- package/src/schema/validation-types.ts +25 -17
- package/src/skills/discover-skills.ts +35 -10
- package/src/skills/skill-templates.ts +109 -27
- package/src/skills/validate.ts +26 -8
- package/src/state/active-run-registry.ts +87 -28
- package/src/state/artifact-store.ts +9 -5
- package/src/state/atomic-write-v2.ts +85 -63
- package/src/state/atomic-write.ts +105 -26
- package/src/state/blob-store.ts +47 -20
- package/src/state/contracts.ts +20 -5
- package/src/state/crew-init.ts +5 -22
- package/src/state/decision-ledger.ts +19 -73
- package/src/state/event-log-rotation.ts +41 -15
- package/src/state/event-log.ts +168 -53
- package/src/state/event-reconstructor.ts +11 -1
- package/src/state/gitignore-manager.ts +2 -8
- package/src/state/health-store.ts +57 -57
- package/src/state/hook-instinct-bridge.ts +1 -1
- package/src/state/hook-integrations.ts +1 -1
- package/src/state/instinct-store.ts +17 -5
- package/src/state/jsonl-writer.ts +1 -1
- package/src/state/locks.ts +23 -9
- package/src/state/mailbox.ts +151 -28
- package/src/state/observation-store.ts +20 -14
- package/src/state/run-cache.ts +142 -135
- package/src/state/run-graph.ts +6 -15
- package/src/state/run-metrics.ts +5 -18
- package/src/state/schedule.ts +15 -9
- package/src/state/state-store.ts +129 -45
- package/src/state/task-claims.ts +12 -2
- package/src/state/tiered-eval.ts +52 -43
- package/src/state/types-eval.ts +2 -2
- package/src/state/types.ts +24 -20
- package/src/state/usage.ts +20 -4
- package/src/state/worker-atomic-writer.ts +6 -3
- package/src/subagents/index.ts +2 -2
- package/src/teams/discover-teams.ts +21 -6
- package/src/tools/safe-bash-extension.ts +5 -6
- package/src/tools/safe-bash.ts +10 -11
- package/src/types/new-api-types.ts +6 -10
- package/src/ui/agent-management-overlay.ts +52 -40
- package/src/ui/card-colors.ts +13 -4
- package/src/ui/crew-footer.ts +8 -7
- package/src/ui/crew-select-list.ts +1 -1
- package/src/ui/dashboard-panes/agents-pane.ts +41 -25
- package/src/ui/dashboard-panes/cancellation-pane.ts +1 -1
- package/src/ui/dashboard-panes/capability-pane.ts +32 -15
- package/src/ui/dashboard-panes/health-pane.ts +2 -1
- package/src/ui/dashboard-panes/metrics-pane.ts +4 -1
- package/src/ui/dashboard-panes/progress-pane.ts +12 -9
- package/src/ui/heartbeat-aggregator.ts +15 -4
- package/src/ui/keybinding-map.ts +40 -7
- package/src/ui/live-conversation-overlay.ts +36 -20
- package/src/ui/live-duration.ts +1 -4
- package/src/ui/live-run-sidebar.ts +88 -25
- package/src/ui/loaders.ts +2 -8
- package/src/ui/mascot.ts +20 -36
- package/src/ui/overlays/agent-picker-overlay.ts +11 -3
- package/src/ui/overlays/confirm-overlay.ts +4 -2
- package/src/ui/overlays/help-overlay.ts +25 -14
- package/src/ui/overlays/mailbox-compose-overlay.ts +48 -11
- package/src/ui/overlays/mailbox-compose-preview.ts +20 -5
- package/src/ui/overlays/mailbox-detail-overlay.ts +27 -6
- package/src/ui/pi-ui-compat.ts +7 -7
- package/src/ui/powerbar-publisher.ts +120 -42
- package/src/ui/render-diff.ts +10 -3
- package/src/ui/render-scheduler.ts +12 -4
- package/src/ui/run-action-dispatcher.ts +81 -18
- package/src/ui/run-dashboard.ts +172 -76
- package/src/ui/run-event-bus.ts +59 -37
- package/src/ui/run-snapshot-cache.ts +276 -86
- package/src/ui/settings-overlay.ts +361 -74
- package/src/ui/status-colors.ts +12 -1
- package/src/ui/syntax-highlight.ts +1 -1
- package/src/ui/theme-adapter.ts +16 -14
- package/src/ui/theme-discovery.ts +13 -2
- package/src/ui/tool-progress-formatter.ts +7 -7
- package/src/ui/tool-render.ts +128 -56
- package/src/ui/tool-renderers/brief-mode.ts +45 -27
- package/src/ui/tool-renderers/index.ts +109 -43
- package/src/ui/transcript-cache.ts +32 -6
- package/src/ui/transcript-entries.ts +25 -23
- package/src/ui/transcript-viewer.ts +78 -29
- package/src/ui/widget/index.ts +99 -40
- package/src/ui/widget/widget-formatters.ts +13 -6
- package/src/ui/widget/widget-model.ts +19 -8
- package/src/ui/widget/widget-renderer.ts +23 -13
- package/src/ui/widget/widget-types.ts +1 -1
- package/src/utils/bm25-search.ts +199 -199
- package/src/utils/conflict-detect.ts +22 -21
- package/src/utils/env-filter.ts +14 -7
- package/src/utils/file-coalescer.ts +5 -1
- package/src/utils/fingerprint.ts +3 -6
- package/src/utils/frontmatter.ts +3 -1
- package/src/utils/fs-watch.ts +2 -6
- package/src/utils/gh-protocol.ts +119 -44
- package/src/utils/git.ts +13 -15
- package/src/utils/guards.ts +2 -5
- package/src/utils/ids.ts +9 -2
- package/src/utils/incremental-reader.ts +14 -3
- package/src/utils/internal-error.ts +2 -1
- package/src/utils/names.ts +12 -3
- package/src/utils/paths.ts +49 -5
- package/src/utils/project-detector.ts +2 -2
- package/src/utils/redaction.ts +29 -19
- package/src/utils/resolve-shell.ts +9 -7
- package/src/utils/run-watcher-registry.ts +19 -31
- package/src/utils/safe-paths.ts +45 -24
- package/src/utils/scan-cache.ts +9 -2
- package/src/utils/session-utils.ts +2 -4
- package/src/utils/sleep.ts +12 -5
- package/src/utils/sse-parser.ts +5 -17
- package/src/utils/visual.ts +52 -32
- package/src/workflows/discover-workflows.ts +41 -109
- package/src/workflows/intermediate-store.ts +5 -21
- package/src/workflows/preflight-validator.ts +6 -33
- package/src/workflows/topology-analyzer.ts +5 -21
- package/src/workflows/workflow-config.ts +7 -6
- package/src/worktree/branch-freshness.ts +66 -8
- package/src/worktree/cleanup.ts +130 -20
- package/src/worktree/worktree-manager.ts +212 -69
- package/skills/artifact-analysis-loop/SKILL.md +0 -303
- package/skills/detection-pipeline-design/SKILL.md +0 -286
- package/skills/hunting-investigation-loop/SKILL.md +0 -402
- package/skills/incident-playbook-construction/SKILL.md +0 -384
- package/skills/security-review/SKILL.md +0 -561
- package/skills/threat-hypothesis-framework/SKILL.md +0 -176
- package/skills/ui-render-performance/SKILL.md +0 -58
- /package/docs/{followup-review-round3-2026-05-12.md → archive/followup-review-round3-2026-05-12.md} +0 -0
- /package/docs/{followup-review-round4-2026-05-13.md → archive/followup-review-round4-2026-05-13.md} +0 -0
- /package/docs/{pi-crew-bugs.md → archive/pi-crew-bugs.md} +0 -0
- /package/docs/{pi-crew-test-final.md → archive/pi-crew-test-final.md} +0 -0
- /package/docs/{pi-crew-test-results.md → archive/pi-crew-test-results.md} +0 -0
- /package/docs/{pi-crew-test-round2.md → archive/pi-crew-test-round2.md} +0 -0
- /package/docs/{pi-crew-test-round4.md → archive/pi-crew-test-round4.md} +0 -0
- /package/docs/{pi-crew-test-round5.md → archive/pi-crew-test-round5.md} +0 -0
- /package/docs/{pi-crew-test-round6.md → archive/pi-crew-test-round6.md} +0 -0
- /package/docs/{pi-crew-v0.5.10-audit-fix-plan.md → archive/pi-crew-v0.5.10-audit-fix-plan.md} +0 -0
- /package/docs/{pi-crew-v0.5.11-audit-fix-plan.md → archive/pi-crew-v0.5.11-audit-fix-plan.md} +0 -0
- /package/docs/{pi-crew-v0.5.12-audit-fix-plan.md → archive/pi-crew-v0.5.12-audit-fix-plan.md} +0 -0
- /package/docs/{pi-crew-v0.5.13-audit-fix-plan.md → archive/pi-crew-v0.5.13-audit-fix-plan.md} +0 -0
- /package/docs/{pi-crew-v0.5.14-audit-fix-plan.md → archive/pi-crew-v0.5.14-audit-fix-plan.md} +0 -0
- /package/docs/{pi-crew-v0.5.16-audit-fix-plan.md → archive/pi-crew-v0.5.16-audit-fix-plan.md} +0 -0
- /package/docs/{pi-crew-v0.5.17-audit-fix-plan.md → archive/pi-crew-v0.5.17-audit-fix-plan.md} +0 -0
- /package/docs/{pi-crew-v0.5.5-audit-fix-plan.md → archive/pi-crew-v0.5.5-audit-fix-plan.md} +0 -0
- /package/docs/{pi-crew-v0.5.9-audit-fix-plan.md → archive/pi-crew-v0.5.9-audit-fix-plan.md} +0 -0
- /package/docs/{pi-mono-opportunities.md → archive/pi-mono-opportunities.md} +0 -0
- /package/docs/{pi-mono-review.md → archive/pi-mono-review.md} +0 -0
- /package/docs/{pi-subagent4-comparison.md → archive/pi-subagent4-comparison.md} +0 -0
- /package/docs/{pi-subagents3-deep-analysis.md → archive/pi-subagents3-deep-analysis.md} +0 -0
|
@@ -39,13 +39,7 @@ export interface BatchSnapshot {
|
|
|
39
39
|
notified: boolean;
|
|
40
40
|
}
|
|
41
41
|
|
|
42
|
-
const TERMINAL_STATUSES = new Set([
|
|
43
|
-
"completed",
|
|
44
|
-
"failed",
|
|
45
|
-
"cancelled",
|
|
46
|
-
"error",
|
|
47
|
-
"stopped",
|
|
48
|
-
]);
|
|
42
|
+
const TERMINAL_STATUSES = new Set(["completed", "failed", "cancelled", "error", "stopped"]);
|
|
49
43
|
|
|
50
44
|
export function isTerminalStatus(status: string): boolean {
|
|
51
45
|
return TERMINAL_STATUSES.has(status);
|
|
@@ -65,7 +59,11 @@ export class BatchBarrier {
|
|
|
65
59
|
register(batchId: string, agentId: string, meta?: { description?: string; type?: string }): void {
|
|
66
60
|
let batch = this.batches.get(batchId);
|
|
67
61
|
if (!batch) {
|
|
68
|
-
batch = {
|
|
62
|
+
batch = {
|
|
63
|
+
members: new Map(),
|
|
64
|
+
terminal: new Map(),
|
|
65
|
+
notified: false,
|
|
66
|
+
};
|
|
69
67
|
this.batches.set(batchId, batch);
|
|
70
68
|
}
|
|
71
69
|
if (!batch.members.has(agentId)) {
|
|
@@ -87,7 +85,11 @@ export class BatchBarrier {
|
|
|
87
85
|
markTerminal(batchId: string, member: BatchMember): BatchSnapshot {
|
|
88
86
|
let batch = this.batches.get(batchId);
|
|
89
87
|
if (!batch) {
|
|
90
|
-
batch = {
|
|
88
|
+
batch = {
|
|
89
|
+
members: new Map(),
|
|
90
|
+
terminal: new Map(),
|
|
91
|
+
notified: false,
|
|
92
|
+
};
|
|
91
93
|
this.batches.set(batchId, batch);
|
|
92
94
|
}
|
|
93
95
|
// Ensure the member is known (auto-register for the defensive case).
|
|
@@ -97,11 +99,13 @@ export class BatchBarrier {
|
|
|
97
99
|
if (isTerminalStatus(member.status)) {
|
|
98
100
|
batch.terminal.set(member.id, { ...member });
|
|
99
101
|
const existing = batch.members.get(member.id);
|
|
100
|
-
if (existing)
|
|
102
|
+
if (existing)
|
|
103
|
+
batch.members.set(member.id, {
|
|
104
|
+
...existing,
|
|
105
|
+
status: member.status,
|
|
106
|
+
});
|
|
101
107
|
}
|
|
102
|
-
const allDone =
|
|
103
|
-
batch.members.size > 0 &&
|
|
104
|
-
[...batch.members.keys()].every((id) => batch.terminal.has(id));
|
|
108
|
+
const allDone = batch.members.size > 0 && [...batch.members.keys()].every((id) => batch.terminal.has(id));
|
|
105
109
|
return {
|
|
106
110
|
batchId,
|
|
107
111
|
members: [...batch.members.values()],
|
|
@@ -130,9 +134,7 @@ export class BatchBarrier {
|
|
|
130
134
|
batchId,
|
|
131
135
|
members: [...batch.members.values()],
|
|
132
136
|
terminal: [...batch.terminal.values()],
|
|
133
|
-
allDone:
|
|
134
|
-
batch.members.size > 0 &&
|
|
135
|
-
[...batch.members.keys()].every((id) => batch.terminal.has(id)),
|
|
137
|
+
allDone: batch.members.size > 0 && [...batch.members.keys()].every((id) => batch.terminal.has(id)),
|
|
136
138
|
notified: batch.notified,
|
|
137
139
|
};
|
|
138
140
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { type CancellationReason, CrewCancellationError, cancellationReasonFromUnknown } from "./cancellation.ts";
|
|
2
2
|
|
|
3
3
|
export interface CancellationTokenState {
|
|
4
4
|
aborted: boolean;
|
|
@@ -28,11 +28,21 @@ export class CancellationToken {
|
|
|
28
28
|
else if (options.signal) options.signal.addEventListener("abort", () => this.abort(options.signal?.reason), { once: true });
|
|
29
29
|
}
|
|
30
30
|
|
|
31
|
-
get signal(): AbortSignal {
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
get
|
|
35
|
-
|
|
31
|
+
get signal(): AbortSignal {
|
|
32
|
+
return this.#controller.signal;
|
|
33
|
+
}
|
|
34
|
+
get aborted(): boolean {
|
|
35
|
+
return this.#controller.signal.aborted;
|
|
36
|
+
}
|
|
37
|
+
get reason(): CancellationReason | undefined {
|
|
38
|
+
return this.#reason;
|
|
39
|
+
}
|
|
40
|
+
get lastHeartbeatAt(): string | undefined {
|
|
41
|
+
return this.#lastHeartbeatAt;
|
|
42
|
+
}
|
|
43
|
+
get lastHeartbeatStage(): string | undefined {
|
|
44
|
+
return this.#lastHeartbeatStage;
|
|
45
|
+
}
|
|
36
46
|
|
|
37
47
|
heartbeat(stage?: string): CancellationTokenState {
|
|
38
48
|
this.throwIfCancelled();
|
|
@@ -1,6 +1,13 @@
|
|
|
1
1
|
import type { OperationTerminalEvidence } from "../state/types.ts";
|
|
2
2
|
|
|
3
|
-
export type CancellationReasonCode =
|
|
3
|
+
export type CancellationReasonCode =
|
|
4
|
+
| "caller_cancelled"
|
|
5
|
+
| "leader_interrupted"
|
|
6
|
+
| "provider_timeout"
|
|
7
|
+
| "worker_timeout"
|
|
8
|
+
| "tool_timeout"
|
|
9
|
+
| "shutdown"
|
|
10
|
+
| "unknown";
|
|
4
11
|
|
|
5
12
|
export interface CancellationReason {
|
|
6
13
|
code: CancellationReasonCode;
|
|
@@ -13,10 +20,24 @@ export function buildSyntheticTerminalEvidence(
|
|
|
13
20
|
reason: CancellationReason,
|
|
14
21
|
startedAt?: string,
|
|
15
22
|
): OperationTerminalEvidence {
|
|
16
|
-
return {
|
|
23
|
+
return {
|
|
24
|
+
operation,
|
|
25
|
+
status: "cancelled",
|
|
26
|
+
startedAt,
|
|
27
|
+
finishedAt: new Date().toISOString(),
|
|
28
|
+
reason,
|
|
29
|
+
};
|
|
17
30
|
}
|
|
18
31
|
|
|
19
|
-
const KNOWN_CODES: ReadonlySet<string> = new Set([
|
|
32
|
+
const KNOWN_CODES: ReadonlySet<string> = new Set([
|
|
33
|
+
"caller_cancelled",
|
|
34
|
+
"leader_interrupted",
|
|
35
|
+
"provider_timeout",
|
|
36
|
+
"worker_timeout",
|
|
37
|
+
"tool_timeout",
|
|
38
|
+
"shutdown",
|
|
39
|
+
"unknown",
|
|
40
|
+
]);
|
|
20
41
|
|
|
21
42
|
export class CrewCancellationError extends Error {
|
|
22
43
|
readonly reason: CancellationReason;
|
|
@@ -30,18 +51,35 @@ export class CrewCancellationError extends Error {
|
|
|
30
51
|
|
|
31
52
|
function reasonFromString(value: string): CancellationReason {
|
|
32
53
|
const trimmed = value.trim();
|
|
33
|
-
if (KNOWN_CODES.has(trimmed))
|
|
34
|
-
|
|
54
|
+
if (KNOWN_CODES.has(trimmed))
|
|
55
|
+
return {
|
|
56
|
+
code: trimmed as CancellationReasonCode,
|
|
57
|
+
message: `Cancelled: ${trimmed}`,
|
|
58
|
+
};
|
|
59
|
+
return {
|
|
60
|
+
code: "caller_cancelled",
|
|
61
|
+
message: trimmed || "Cancelled by caller.",
|
|
62
|
+
};
|
|
35
63
|
}
|
|
36
64
|
|
|
37
65
|
export function cancellationReasonFromUnknown(value: unknown): CancellationReason {
|
|
38
66
|
if (value instanceof CrewCancellationError) return value.reason;
|
|
39
|
-
if (value instanceof Error)
|
|
67
|
+
if (value instanceof Error)
|
|
68
|
+
return {
|
|
69
|
+
code: "caller_cancelled",
|
|
70
|
+
message: value.message || "Cancelled by caller.",
|
|
71
|
+
cause: value,
|
|
72
|
+
};
|
|
40
73
|
if (typeof value === "string") return reasonFromString(value);
|
|
41
74
|
if (value && typeof value === "object" && !Array.isArray(value)) {
|
|
42
|
-
const record = value as {
|
|
75
|
+
const record = value as {
|
|
76
|
+
code?: unknown;
|
|
77
|
+
reason?: unknown;
|
|
78
|
+
message?: unknown;
|
|
79
|
+
cause?: unknown;
|
|
80
|
+
};
|
|
43
81
|
const rawCode = typeof record.code === "string" ? record.code : typeof record.reason === "string" ? record.reason : undefined;
|
|
44
|
-
const code = rawCode && KNOWN_CODES.has(rawCode) ? rawCode as CancellationReasonCode : "caller_cancelled";
|
|
82
|
+
const code = rawCode && KNOWN_CODES.has(rawCode) ? (rawCode as CancellationReasonCode) : "caller_cancelled";
|
|
45
83
|
const message = typeof record.message === "string" && record.message.trim() ? record.message.trim() : `Cancelled: ${code}`;
|
|
46
84
|
return { code, message, cause: record.cause ?? value };
|
|
47
85
|
}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import type { AgentConfig, ResourceSource } from "../agents/agent-config.ts";
|
|
2
2
|
import { discoverAgents } from "../agents/discover-agents.ts";
|
|
3
|
-
import {
|
|
4
|
-
import { discoverWorkflows } from "../workflows/discover-workflows.ts";
|
|
3
|
+
import type { PiTeamsConfig } from "../config/config.ts";
|
|
5
4
|
import { discoverSkills, getLastDiscoveryDiagnostics } from "../skills/discover-skills.ts";
|
|
6
5
|
import type { SkillValidationError } from "../skills/validate.ts";
|
|
7
|
-
import
|
|
6
|
+
import { discoverTeams } from "../teams/discover-teams.ts";
|
|
7
|
+
import { discoverWorkflows } from "../workflows/discover-workflows.ts";
|
|
8
8
|
|
|
9
9
|
export type CapabilityKind = "team" | "workflow" | "agent" | "skill" | "tool" | "runtime";
|
|
10
10
|
export type CapabilitySource = "builtin" | "project" | "user" | "package" | "git";
|
|
@@ -105,7 +105,9 @@ export function buildCapabilityInventory(cwd: string, config?: PiTeamsConfig): C
|
|
|
105
105
|
];
|
|
106
106
|
|
|
107
107
|
// Mark shadowed resources: project/user items with same kind:name as a builtin
|
|
108
|
-
const builtinNames = new Set(
|
|
108
|
+
const builtinNames = new Set(
|
|
109
|
+
items.filter((item) => item.source === "builtin" || item.source === "package").map((item) => `${item.kind}:${item.name}`),
|
|
110
|
+
);
|
|
109
111
|
for (const item of items) {
|
|
110
112
|
if (item.source !== "builtin" && item.source !== "package" && builtinNames.has(`${item.kind}:${item.name}`)) {
|
|
111
113
|
item.state = "shadowed";
|
|
@@ -48,19 +48,39 @@ function tokenize(input: string): Token[] {
|
|
|
48
48
|
|
|
49
49
|
while (i < input.length) {
|
|
50
50
|
// Skip whitespace
|
|
51
|
-
if (/\s/.test(input[i]!)) {
|
|
51
|
+
if (/\s/.test(input[i]!)) {
|
|
52
|
+
i++;
|
|
53
|
+
continue;
|
|
54
|
+
}
|
|
52
55
|
|
|
53
56
|
// Arrow ->
|
|
54
57
|
if (input[i] === "-" && input[i + 1] === ">") {
|
|
55
58
|
tokens.push({ type: "ARROW", value: "->" });
|
|
56
|
-
i += 2;
|
|
59
|
+
i += 2;
|
|
60
|
+
continue;
|
|
57
61
|
}
|
|
58
62
|
|
|
59
63
|
// Punctuation
|
|
60
|
-
if (input[i] === "(") {
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
+
if (input[i] === "(") {
|
|
65
|
+
tokens.push({ type: "LPAREN", value: "(" });
|
|
66
|
+
i++;
|
|
67
|
+
continue;
|
|
68
|
+
}
|
|
69
|
+
if (input[i] === ")") {
|
|
70
|
+
tokens.push({ type: "RPAREN", value: ")" });
|
|
71
|
+
i++;
|
|
72
|
+
continue;
|
|
73
|
+
}
|
|
74
|
+
if (input[i] === ",") {
|
|
75
|
+
tokens.push({ type: "COMMA", value: "," });
|
|
76
|
+
i++;
|
|
77
|
+
continue;
|
|
78
|
+
}
|
|
79
|
+
if (input[i] === ":") {
|
|
80
|
+
tokens.push({ type: "COLON", value: ":" });
|
|
81
|
+
i++;
|
|
82
|
+
continue;
|
|
83
|
+
}
|
|
64
84
|
|
|
65
85
|
// Quoted argument
|
|
66
86
|
if (input[i] === '"' || input[i] === "'") {
|
|
@@ -68,8 +88,12 @@ function tokenize(input: string): Token[] {
|
|
|
68
88
|
let str = "";
|
|
69
89
|
i++; // skip opening quote
|
|
70
90
|
while (i < input.length && input[i] !== quote) {
|
|
71
|
-
if (input[i] === "\\" && i + 1 < input.length) {
|
|
72
|
-
|
|
91
|
+
if (input[i] === "\\" && i + 1 < input.length) {
|
|
92
|
+
i++;
|
|
93
|
+
str += input[i];
|
|
94
|
+
} else {
|
|
95
|
+
str += input[i]!;
|
|
96
|
+
}
|
|
73
97
|
i++;
|
|
74
98
|
}
|
|
75
99
|
if (i >= input.length) throw new Error("Unclosed quoted string in chain DSL");
|
|
@@ -82,7 +106,10 @@ function tokenize(input: string): Token[] {
|
|
|
82
106
|
if (input[i] === "-" && input[i + 1] === "-") {
|
|
83
107
|
let flag = "";
|
|
84
108
|
i += 2;
|
|
85
|
-
while (i < input.length && /[a-zA-Z0-9_-]/.test(input[i]!)) {
|
|
109
|
+
while (i < input.length && /[a-zA-Z0-9_-]/.test(input[i]!)) {
|
|
110
|
+
flag += input[i];
|
|
111
|
+
i++;
|
|
112
|
+
}
|
|
86
113
|
tokens.push({ type: "FLAG", value: flag });
|
|
87
114
|
continue;
|
|
88
115
|
}
|
|
@@ -90,7 +117,10 @@ function tokenize(input: string): Token[] {
|
|
|
90
117
|
// Number
|
|
91
118
|
if (/[0-9]/.test(input[i]!)) {
|
|
92
119
|
let num = "";
|
|
93
|
-
while (i < input.length && /[0-9]/.test(input[i]!)) {
|
|
120
|
+
while (i < input.length && /[0-9]/.test(input[i]!)) {
|
|
121
|
+
num += input[i];
|
|
122
|
+
i++;
|
|
123
|
+
}
|
|
94
124
|
tokens.push({ type: "NUMBER", value: num });
|
|
95
125
|
continue;
|
|
96
126
|
}
|
|
@@ -98,7 +128,10 @@ function tokenize(input: string): Token[] {
|
|
|
98
128
|
// Name
|
|
99
129
|
if (/[a-zA-Z_]/.test(input[i]!)) {
|
|
100
130
|
let name = "";
|
|
101
|
-
while (i < input.length && /[a-zA-Z0-9_.-]/.test(input[i]!)) {
|
|
131
|
+
while (i < input.length && /[a-zA-Z0-9_.-]/.test(input[i]!)) {
|
|
132
|
+
name += input[i];
|
|
133
|
+
i++;
|
|
134
|
+
}
|
|
102
135
|
tokens.push({ type: "NAME", value: name });
|
|
103
136
|
continue;
|
|
104
137
|
}
|
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* ChainRunner - Execute sequential chains with `->` syntax support.
|
|
3
|
-
*
|
|
3
|
+
*
|
|
4
4
|
* Based on pi-boomerang's parseChain pattern:
|
|
5
5
|
* - Parses "teamA -> teamB -> teamC" syntax
|
|
6
6
|
* - Supports per-step overrides for model, skill, thinking
|
|
7
7
|
* - Accumulates handoffs between steps
|
|
8
8
|
* - Executes steps sequentially with context passing
|
|
9
|
-
*
|
|
9
|
+
*
|
|
10
10
|
* @see docs/pi-boomerang-integration-plan.md
|
|
11
11
|
*/
|
|
12
12
|
|
|
13
|
-
import type { HandoffSummary, HandoffManager, TaskPacket, TaskResult } from "./handoff-manager.ts";
|
|
14
|
-
import { parseChainDSL } from "./chain-parser.ts";
|
|
15
13
|
import type { ChainStep as DSLChainStep } from "./chain-parser.ts";
|
|
14
|
+
import { parseChainDSL } from "./chain-parser.ts";
|
|
15
|
+
import type { HandoffManager, HandoffSummary, TaskPacket, TaskResult } from "./handoff-manager.ts";
|
|
16
16
|
|
|
17
17
|
/**
|
|
18
18
|
* Single step in a chain.
|
|
@@ -109,32 +109,29 @@ export class ChainRunner {
|
|
|
109
109
|
private taskRunner: ChainTaskRunner;
|
|
110
110
|
private handoffManager: HandoffManager;
|
|
111
111
|
|
|
112
|
-
constructor(
|
|
113
|
-
taskRunner: ChainTaskRunner,
|
|
114
|
-
handoffManager: HandoffManager,
|
|
115
|
-
) {
|
|
112
|
+
constructor(taskRunner: ChainTaskRunner, handoffManager: HandoffManager) {
|
|
116
113
|
this.taskRunner = taskRunner;
|
|
117
114
|
this.handoffManager = handoffManager;
|
|
118
115
|
}
|
|
119
116
|
|
|
120
117
|
/**
|
|
121
118
|
* Parse chain syntax: step1 -> step2 -> step3
|
|
122
|
-
*
|
|
119
|
+
*
|
|
123
120
|
* Supports multiple syntaxes:
|
|
124
121
|
* - Team reference: @teamName
|
|
125
122
|
* - Workflow reference: workflow:name
|
|
126
123
|
* - Template reference: template:name
|
|
127
124
|
* - Inline goal: "goal description"
|
|
128
|
-
*
|
|
125
|
+
*
|
|
129
126
|
* @example
|
|
130
127
|
* parseChain("@research -> @implement -> @review")
|
|
131
128
|
* parseChain('"Research AI trends" -> "Analyze findings"')
|
|
132
129
|
* parseChain("@step1 --model claude-opus-3 -> @step2")
|
|
133
|
-
*
|
|
130
|
+
*
|
|
134
131
|
* Also supports DSL syntax from chain-parser for advanced constructs:
|
|
135
132
|
* parseChain("step1 -> parallel(step2, step3) -> step4")
|
|
136
133
|
* parseChain("step1:3 -> step2 --with-context -> step3")
|
|
137
|
-
*
|
|
134
|
+
*
|
|
138
135
|
* @param chainString - The chain string to parse
|
|
139
136
|
* @returns Parsed chain specification
|
|
140
137
|
*/
|
|
@@ -150,7 +147,7 @@ export class ChainRunner {
|
|
|
150
147
|
}
|
|
151
148
|
}
|
|
152
149
|
|
|
153
|
-
const stepStrings = chainString.split("->").map(s => s.trim());
|
|
150
|
+
const stepStrings = chainString.split("->").map((s) => s.trim());
|
|
154
151
|
|
|
155
152
|
const steps: ChainStep[] = stepStrings.map((step, index) => {
|
|
156
153
|
return this.parseStep(step, index);
|
|
@@ -174,17 +171,13 @@ export class ChainRunner {
|
|
|
174
171
|
/**
|
|
175
172
|
* Execute chain sequentially.
|
|
176
173
|
* Each step receives handoff from previous step.
|
|
177
|
-
*
|
|
174
|
+
*
|
|
178
175
|
* @param spec - Parsed chain specification
|
|
179
176
|
* @param initialContext - Initial context for the chain
|
|
180
177
|
* @param eventsPath - Optional event log path for events
|
|
181
178
|
* @returns Final chain result
|
|
182
179
|
*/
|
|
183
|
-
async runChain(
|
|
184
|
-
spec: ChainSpec,
|
|
185
|
-
initialContext: Record<string, unknown> = {},
|
|
186
|
-
eventsPath?: string
|
|
187
|
-
): Promise<ChainResult> {
|
|
180
|
+
async runChain(spec: ChainSpec, initialContext: Record<string, unknown> = {}, eventsPath?: string): Promise<ChainResult> {
|
|
188
181
|
const stepResults: ChainStepResult[] = [];
|
|
189
182
|
let accumulatedContext = { ...initialContext };
|
|
190
183
|
const startTime = Date.now();
|
|
@@ -200,10 +193,7 @@ export class ChainRunner {
|
|
|
200
193
|
const effectiveConfig = this.getEffectiveConfig(step, spec);
|
|
201
194
|
|
|
202
195
|
// Enrich context with previous handoffs
|
|
203
|
-
const stepContext = this.enrichContextFromHandoffs(
|
|
204
|
-
accumulatedContext,
|
|
205
|
-
stepResults
|
|
206
|
-
);
|
|
196
|
+
const stepContext = this.enrichContextFromHandoffs(accumulatedContext, stepResults);
|
|
207
197
|
|
|
208
198
|
// Execute step
|
|
209
199
|
const result = await this.executeStep(effectiveConfig, stepContext);
|
|
@@ -214,10 +204,7 @@ export class ChainRunner {
|
|
|
214
204
|
}
|
|
215
205
|
|
|
216
206
|
// Generate handoff for next step
|
|
217
|
-
const handoff = await this.handoffManager.generateSummary(
|
|
218
|
-
this.createMinimalPacket(step, i),
|
|
219
|
-
result
|
|
220
|
-
);
|
|
207
|
+
const handoff = await this.handoffManager.generateSummary(this.createMinimalPacket(step, i), result);
|
|
221
208
|
|
|
222
209
|
stepResults.push({
|
|
223
210
|
step: i + 1,
|
|
@@ -228,7 +215,9 @@ export class ChainRunner {
|
|
|
228
215
|
duration: Date.now() - stepStart,
|
|
229
216
|
});
|
|
230
217
|
|
|
231
|
-
if (handoff !== null) {
|
|
218
|
+
if (handoff !== null) {
|
|
219
|
+
allHandoffs.push(handoff);
|
|
220
|
+
}
|
|
232
221
|
|
|
233
222
|
// Update accumulated context on success
|
|
234
223
|
if (result.outcome === "success") {
|
|
@@ -246,7 +235,7 @@ export class ChainRunner {
|
|
|
246
235
|
|
|
247
236
|
// Emit progress event if eventsPath provided
|
|
248
237
|
if (eventsPath) {
|
|
249
|
-
|
|
238
|
+
// LAZY: defer dynamic import of ../state/event-log.ts to its call site.
|
|
250
239
|
const { appendEventAsync } = await import("../state/event-log.ts");
|
|
251
240
|
await appendEventAsync(eventsPath, {
|
|
252
241
|
type: "chain.step_completed",
|
|
@@ -260,7 +249,6 @@ export class ChainRunner {
|
|
|
260
249
|
},
|
|
261
250
|
});
|
|
262
251
|
}
|
|
263
|
-
|
|
264
252
|
} catch (error) {
|
|
265
253
|
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
266
254
|
|
|
@@ -282,7 +270,7 @@ export class ChainRunner {
|
|
|
282
270
|
return {
|
|
283
271
|
steps: stepResults,
|
|
284
272
|
totalDuration: Date.now() - startTime,
|
|
285
|
-
success: stepResults.every(s => s.outcome !== "failure"),
|
|
273
|
+
success: stepResults.every((s) => s.outcome !== "failure"),
|
|
286
274
|
totalTokens: totalTokens > 0 ? totalTokens : undefined,
|
|
287
275
|
totalHandoffs: allHandoffs,
|
|
288
276
|
};
|
|
@@ -306,9 +294,7 @@ export class ChainRunner {
|
|
|
306
294
|
const inlineMatch = step.match(/"([^"]{1,10000})"/);
|
|
307
295
|
|
|
308
296
|
const nameParts = step.split(/\s+/);
|
|
309
|
-
const name =
|
|
310
|
-
? nameParts[0]
|
|
311
|
-
: `step-${index}`;
|
|
297
|
+
const name = nameParts[0] && nameParts[0].length > 0 && nameParts[0].length <= 100 ? nameParts[0] : `step-${index}`;
|
|
312
298
|
|
|
313
299
|
const parsed: ChainStep = {
|
|
314
300
|
name,
|
|
@@ -366,9 +352,7 @@ export class ChainRunner {
|
|
|
366
352
|
* DSL features: parallel(...), :loopCount, --with-context flag
|
|
367
353
|
*/
|
|
368
354
|
private hasDSLConstructs(chainString: string): boolean {
|
|
369
|
-
return /\bparallel\s*\(/.test(chainString) ||
|
|
370
|
-
/\w+:\d+\b/.test(chainString) ||
|
|
371
|
-
/--with-context/.test(chainString);
|
|
355
|
+
return /\bparallel\s*\(/.test(chainString) || /\w+:\d+\b/.test(chainString) || /--with-context/.test(chainString);
|
|
372
356
|
}
|
|
373
357
|
|
|
374
358
|
/**
|
|
@@ -381,13 +365,22 @@ export class ChainRunner {
|
|
|
381
365
|
return {
|
|
382
366
|
name: dslStep.name,
|
|
383
367
|
context: {
|
|
384
|
-
parallel: dslStep.parallel.map(p => ({
|
|
368
|
+
parallel: dslStep.parallel.map((p) => ({
|
|
369
|
+
name: p.name,
|
|
370
|
+
loopCount: p.loopCount,
|
|
371
|
+
withContext: p.withContext,
|
|
372
|
+
args: p.args,
|
|
373
|
+
})),
|
|
385
374
|
},
|
|
386
375
|
loopCount: dslStep.loopCount,
|
|
387
376
|
};
|
|
388
377
|
}
|
|
389
378
|
const step: ChainStep = { name: dslStep.name };
|
|
390
|
-
if (dslStep.loopCount)
|
|
379
|
+
if (dslStep.loopCount)
|
|
380
|
+
step.context = {
|
|
381
|
+
...step.context,
|
|
382
|
+
loopCount: dslStep.loopCount,
|
|
383
|
+
};
|
|
391
384
|
if (dslStep.withContext) step.context = { ...step.context, withContext: true };
|
|
392
385
|
if (dslStep.args && dslStep.args.length > 0) step.context = { ...step.context, args: dslStep.args };
|
|
393
386
|
return step;
|
|
@@ -399,14 +392,20 @@ export class ChainRunner {
|
|
|
399
392
|
const globalThinking = this.extractGlobalFlag(chainString, "global-thinking") as "fast" | "standard" | "deep" | undefined;
|
|
400
393
|
const continueOnError = this.extractGlobalFlag(chainString, "continue-on-error") === "true";
|
|
401
394
|
|
|
402
|
-
return {
|
|
395
|
+
return {
|
|
396
|
+
steps,
|
|
397
|
+
globalModel,
|
|
398
|
+
globalSkill,
|
|
399
|
+
globalThinking,
|
|
400
|
+
continueOnError,
|
|
401
|
+
};
|
|
403
402
|
}
|
|
404
403
|
|
|
405
404
|
/**
|
|
406
405
|
* Sanitize identifier to prevent injection.
|
|
407
406
|
*/
|
|
408
407
|
private sanitizeIdentifier(value: string): string {
|
|
409
|
-
return value.replace(/[^a-zA-Z0-9_]/g,
|
|
408
|
+
return value.replace(/[^a-zA-Z0-9_]/g, "_").substring(0, 100);
|
|
410
409
|
}
|
|
411
410
|
|
|
412
411
|
/**
|
|
@@ -414,7 +413,7 @@ export class ChainRunner {
|
|
|
414
413
|
*/
|
|
415
414
|
private sanitizeInlineGoal(value: string): string {
|
|
416
415
|
// Remove control characters and limit length
|
|
417
|
-
return value.replace(/[\x00-\x1F\x7F]/g,
|
|
416
|
+
return value.replace(/[\x00-\x1F\x7F]/g, "").substring(0, 10000);
|
|
418
417
|
}
|
|
419
418
|
|
|
420
419
|
/**
|
|
@@ -444,7 +443,7 @@ export class ChainRunner {
|
|
|
444
443
|
*/
|
|
445
444
|
private extractFlag(input: string, flag: string): string | undefined {
|
|
446
445
|
// Escape regex special characters in flag name to prevent injection
|
|
447
|
-
const escapedFlag = flag.replace(/[.*+?^${}()|[\]\\]/g,
|
|
446
|
+
const escapedFlag = flag.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
448
447
|
const match = input.match(new RegExp(`--${escapedFlag}\\s+(\\S+)`));
|
|
449
448
|
return match?.[1];
|
|
450
449
|
}
|
|
@@ -456,13 +455,13 @@ export class ChainRunner {
|
|
|
456
455
|
*/
|
|
457
456
|
private extractGlobalFlag(input: string, flag: string): string | undefined {
|
|
458
457
|
// Escape regex special characters in flag name to prevent injection
|
|
459
|
-
const escapedFlag = flag.replace(/[.*+?^${}()|[\]\\]/g,
|
|
460
|
-
const patternEq =
|
|
461
|
-
const match = input.match(new RegExp(patternEq,
|
|
458
|
+
const escapedFlag = flag.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
459
|
+
const patternEq = "--" + escapedFlag + "=\\s*(\\S+)";
|
|
460
|
+
const match = input.match(new RegExp(patternEq, "i"));
|
|
462
461
|
if (match) return match[1];
|
|
463
462
|
|
|
464
|
-
const patternNoEq =
|
|
465
|
-
const matchNoEq = input.match(new RegExp(patternNoEq,
|
|
463
|
+
const patternNoEq = "--" + escapedFlag + "\\s+(\\S+)";
|
|
464
|
+
const matchNoEq = input.match(new RegExp(patternNoEq, "i"));
|
|
466
465
|
if (matchNoEq) return matchNoEq[1];
|
|
467
466
|
|
|
468
467
|
return undefined;
|
|
@@ -484,13 +483,8 @@ export class ChainRunner {
|
|
|
484
483
|
* Enrich context with previous handoffs.
|
|
485
484
|
* Limits history size to prevent memory leaks.
|
|
486
485
|
*/
|
|
487
|
-
private enrichContextFromHandoffs(
|
|
488
|
-
|
|
489
|
-
previousResults: ChainStepResult[]
|
|
490
|
-
): Record<string, unknown> {
|
|
491
|
-
const handoffs = previousResults
|
|
492
|
-
.filter(r => r.handoff)
|
|
493
|
-
.map(r => r.handoff!);
|
|
486
|
+
private enrichContextFromHandoffs(context: Record<string, unknown>, previousResults: ChainStepResult[]): Record<string, unknown> {
|
|
487
|
+
const handoffs = previousResults.filter((r) => r.handoff).map((r) => r.handoff!);
|
|
494
488
|
|
|
495
489
|
if (handoffs.length === 0) {
|
|
496
490
|
return context;
|
|
@@ -504,24 +498,28 @@ export class ChainRunner {
|
|
|
504
498
|
let limitedHandoffs = handoffs;
|
|
505
499
|
if (handoffs.length > ChainRunner.MAX_CHAIN_HISTORY_SIZE) {
|
|
506
500
|
const dropped = handoffs.length - ChainRunner.MAX_CHAIN_HISTORY_SIZE;
|
|
507
|
-
notes.push(
|
|
501
|
+
notes.push(
|
|
502
|
+
`[chain history limited to last ${ChainRunner.MAX_CHAIN_HISTORY_SIZE} entries; ${dropped} older entr${dropped === 1 ? "y" : "ies"} omitted]`,
|
|
503
|
+
);
|
|
508
504
|
limitedHandoffs = handoffs.slice(-ChainRunner.MAX_CHAIN_HISTORY_SIZE);
|
|
509
505
|
}
|
|
510
506
|
|
|
511
507
|
// Limit per-entry size to prevent memory issues from large artifacts.
|
|
512
|
-
const filteredHandoffs = limitedHandoffs.filter(h => {
|
|
508
|
+
const filteredHandoffs = limitedHandoffs.filter((h) => {
|
|
513
509
|
const size = JSON.stringify(h).length;
|
|
514
510
|
return size <= ChainRunner.MAX_HANDOFF_ENTRY_SIZE;
|
|
515
511
|
});
|
|
516
512
|
const oversizedDropped = limitedHandoffs.length - filteredHandoffs.length;
|
|
517
513
|
if (oversizedDropped > 0) {
|
|
518
|
-
notes.push(
|
|
514
|
+
notes.push(
|
|
515
|
+
`[${oversizedDropped} handoff entr${oversizedDropped === 1 ? "y" : "ies"} omitted (> ${ChainRunner.MAX_HANDOFF_ENTRY_SIZE} bytes each)]`,
|
|
516
|
+
);
|
|
519
517
|
}
|
|
520
518
|
|
|
521
519
|
// Track array-cap drops so capped lists do not vanish silently. Each field
|
|
522
520
|
// over its cap records the full count so a reader knows data was elided.
|
|
523
521
|
const arrayCapNotes: string[] = [];
|
|
524
|
-
const mapped = filteredHandoffs.map(h => {
|
|
522
|
+
const mapped = filteredHandoffs.map((h) => {
|
|
525
523
|
const over: string[] = [];
|
|
526
524
|
if (h.filesCreated && h.filesCreated.length > 50) over.push(`filesCreated=${h.filesCreated.length}`);
|
|
527
525
|
if (h.filesModified && h.filesModified.length > 50) over.push(`filesModified=${h.filesModified.length}`);
|
|
@@ -550,10 +548,7 @@ export class ChainRunner {
|
|
|
550
548
|
/**
|
|
551
549
|
* Execute a single step.
|
|
552
550
|
*/
|
|
553
|
-
private async executeStep(
|
|
554
|
-
config: ChainStep,
|
|
555
|
-
context: Record<string, unknown>
|
|
556
|
-
): Promise<TaskResult> {
|
|
551
|
+
private async executeStep(config: ChainStep, context: Record<string, unknown>): Promise<TaskResult> {
|
|
557
552
|
// Pass step config (team/workflow/model) into the packet context so the
|
|
558
553
|
// concrete ChainTaskRunner can resolve which team/workflow to run. Without
|
|
559
554
|
// this, a step parsed to a @teamName reference would lose its team because
|
|
@@ -592,10 +587,7 @@ export class ChainRunner {
|
|
|
592
587
|
/**
|
|
593
588
|
* Create a ChainRunner with default dependencies.
|
|
594
589
|
*/
|
|
595
|
-
export function createChainRunner(
|
|
596
|
-
taskRunner: ChainTaskRunner,
|
|
597
|
-
handoffManager: HandoffManager
|
|
598
|
-
): ChainRunner {
|
|
590
|
+
export function createChainRunner(taskRunner: ChainTaskRunner, handoffManager: HandoffManager): ChainRunner {
|
|
599
591
|
return new ChainRunner(taskRunner, handoffManager);
|
|
600
592
|
}
|
|
601
593
|
|
|
@@ -604,8 +596,10 @@ export function createChainRunner(
|
|
|
604
596
|
*/
|
|
605
597
|
export function parseChainString(chainString: string): ChainSpec {
|
|
606
598
|
const runner = new ChainRunner(
|
|
607
|
-
{
|
|
608
|
-
|
|
599
|
+
{
|
|
600
|
+
runTask: () => Promise.reject(new Error("Not initialized")),
|
|
601
|
+
} as ChainTaskRunner,
|
|
602
|
+
{} as HandoffManager,
|
|
609
603
|
);
|
|
610
604
|
return runner.parseChain(chainString);
|
|
611
605
|
}
|