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
|
@@ -22,25 +22,25 @@
|
|
|
22
22
|
* `setResult()` reaches the main context.
|
|
23
23
|
*/
|
|
24
24
|
|
|
25
|
-
import {
|
|
26
|
-
import {
|
|
27
|
-
import {
|
|
28
|
-
import { mapConcurrent } from "./parallel-utils.ts";
|
|
29
|
-
import { Semaphore } from "./semaphore.ts";
|
|
30
|
-
import { executeWithRetry } from "./retry-executor.ts";
|
|
25
|
+
import { randomBytes } from "node:crypto";
|
|
26
|
+
import type { TSchema } from "@sinclair/typebox";
|
|
27
|
+
import type { AgentConfig } from "../agents/agent-config.ts";
|
|
31
28
|
import { allAgents, discoverAgents } from "../agents/discover-agents.ts";
|
|
32
29
|
import { writeArtifact } from "../state/artifact-store.ts";
|
|
33
30
|
import { appendEvent } from "../state/event-log.ts";
|
|
34
31
|
import { appendMailboxMessage, readMailbox } from "../state/mailbox.ts";
|
|
35
|
-
import { renderPlanTemplate } from "./plan-templates.ts";
|
|
36
|
-
import { prepareAgentWorktree, cleanupAgentWorktree } from "../worktree/worktree-manager.ts";
|
|
37
|
-
import { logInternalError } from "../utils/internal-error.ts";
|
|
38
|
-
import { randomBytes } from "node:crypto";
|
|
39
|
-
import type { TSchema } from "@sinclair/typebox";
|
|
40
|
-
import type { AgentConfig } from "../agents/agent-config.ts";
|
|
41
|
-
import type { TeamConfig } from "../teams/team-config.ts";
|
|
42
32
|
import type { TeamRunManifest } from "../state/types.ts";
|
|
33
|
+
import type { TeamConfig } from "../teams/team-config.ts";
|
|
34
|
+
import { logInternalError } from "../utils/internal-error.ts";
|
|
35
|
+
import { cleanupAgentWorktree, prepareAgentWorktree } from "../worktree/worktree-manager.ts";
|
|
36
|
+
import { runChildPi } from "./child-pi.ts";
|
|
43
37
|
import type { DwfCheckpointState } from "./dwf-state-store.ts";
|
|
38
|
+
import { mapConcurrent } from "./parallel-utils.ts";
|
|
39
|
+
import { parsePiJsonOutput } from "./pi-json-output.ts";
|
|
40
|
+
import { renderPlanTemplate } from "./plan-templates.ts";
|
|
41
|
+
import { extractStructuredResult } from "./result-extractor.ts";
|
|
42
|
+
import { executeWithRetry } from "./retry-executor.ts";
|
|
43
|
+
import { Semaphore } from "./semaphore.ts";
|
|
44
44
|
|
|
45
45
|
export interface AgentCallOpts {
|
|
46
46
|
prompt: string;
|
|
@@ -120,11 +120,31 @@ export interface WorkflowCtx {
|
|
|
120
120
|
...stages: Array<(previous: TResult, original: TItem, index: number) => Promise<TResult> | TResult>
|
|
121
121
|
): Promise<(TResult | null)[]>;
|
|
122
122
|
/** Run a reviewer agent over an artifact; parse {outcome, feedback}. §3.2. */
|
|
123
|
-
review(
|
|
123
|
+
review(
|
|
124
|
+
taskId: string,
|
|
125
|
+
reviewerRole?: string,
|
|
126
|
+
opts?: {
|
|
127
|
+
content?: string;
|
|
128
|
+
artifactPath?: string;
|
|
129
|
+
disableTools?: boolean;
|
|
130
|
+
},
|
|
131
|
+
): Promise<{
|
|
132
|
+
outcome: "accept" | "reject" | "changes_requested";
|
|
133
|
+
feedback: string;
|
|
134
|
+
}>;
|
|
124
135
|
/** Re-run a task with feedback (wraps executeWithRetry). */
|
|
125
136
|
retry(taskId: string, opts?: { feedback?: string }): Promise<AgentResult>;
|
|
126
137
|
/** Send a mailbox message to another agent/leader. */
|
|
127
|
-
mail(
|
|
138
|
+
mail(
|
|
139
|
+
to: string,
|
|
140
|
+
body: string,
|
|
141
|
+
opts?: {
|
|
142
|
+
kind?: string;
|
|
143
|
+
taskId?: string;
|
|
144
|
+
replyTo?: string;
|
|
145
|
+
replyDeadline?: number;
|
|
146
|
+
},
|
|
147
|
+
): string;
|
|
128
148
|
/** Block until N mailbox replies arrive or deadline. ~10 LOC net-new (report 05 §G.4). */
|
|
129
149
|
gatherReplies(messageIds: string[], deadlineMs: number): Promise<unknown[]>;
|
|
130
150
|
/** Render a built-in plan template (full-implementation / standard-review). */
|
|
@@ -235,7 +255,10 @@ export function makeWorkflowCtx(manifest: TeamRunManifest, opts: MakeWorkflowCtx
|
|
|
235
255
|
// The events log is the durable source of truth for phase boundaries.
|
|
236
256
|
// round-18 P2-3: hydrate phaseState from a resumed checkpoint (backward compatible when unset).
|
|
237
257
|
let phaseState: { currentPhase: string | undefined; phases: string[] } = opts.resumedState
|
|
238
|
-
? {
|
|
258
|
+
? {
|
|
259
|
+
currentPhase: opts.resumedState.currentPhase,
|
|
260
|
+
phases: [...opts.resumedState.phases],
|
|
261
|
+
}
|
|
239
262
|
: { currentPhase: undefined, phases: [] };
|
|
240
263
|
let phaseCapWarned = false;
|
|
241
264
|
// round-14 P1-2/P1-3/P1-5: closure-scoped runtime state shared by budget/log/args.
|
|
@@ -271,7 +294,12 @@ export function makeWorkflowCtx(manifest: TeamRunManifest, opts: MakeWorkflowCtx
|
|
|
271
294
|
// round-14 P1-2: budget check BEFORE spawning. When the per-workflow token
|
|
272
295
|
// budget is exhausted, reject the call without consuming a child worker.
|
|
273
296
|
if (budget.total !== null && budget.remaining() <= 0) {
|
|
274
|
-
return {
|
|
297
|
+
return {
|
|
298
|
+
ok: false,
|
|
299
|
+
text: "",
|
|
300
|
+
error: "workflow token budget exhausted",
|
|
301
|
+
durationMs: 0,
|
|
302
|
+
};
|
|
275
303
|
}
|
|
276
304
|
const agentConfig = resolveAgentForRole(call.role, {
|
|
277
305
|
explicitAgent: call.agent,
|
|
@@ -301,7 +329,10 @@ export function makeWorkflowCtx(manifest: TeamRunManifest, opts: MakeWorkflowCtx
|
|
|
301
329
|
systemPrompt: composeSchemaSystemPrompt(base, call.schema),
|
|
302
330
|
};
|
|
303
331
|
} else if (call.systemPrompt !== undefined) {
|
|
304
|
-
effectiveAgent = {
|
|
332
|
+
effectiveAgent = {
|
|
333
|
+
...effectiveAgent,
|
|
334
|
+
systemPrompt: call.systemPrompt,
|
|
335
|
+
};
|
|
305
336
|
}
|
|
306
337
|
const task = composeAgentTask(call);
|
|
307
338
|
|
|
@@ -311,10 +342,7 @@ export function makeWorkflowCtx(manifest: TeamRunManifest, opts: MakeWorkflowCtx
|
|
|
311
342
|
// when worktree creation is unavailable (no git repo, dirty leader).
|
|
312
343
|
let agentCwd = manifest.cwd;
|
|
313
344
|
if (call.worktree === true) {
|
|
314
|
-
const wt = prepareAgentWorktree(
|
|
315
|
-
manifest,
|
|
316
|
-
`dwf-agent-${Date.now()}-${randomBytes(4).toString("hex")}`,
|
|
317
|
-
);
|
|
345
|
+
const wt = prepareAgentWorktree(manifest, `dwf-agent-${Date.now()}-${randomBytes(4).toString("hex")}`);
|
|
318
346
|
if (wt?.worktreePath) {
|
|
319
347
|
agentCwd = wt.cwd;
|
|
320
348
|
worktreePath = wt.worktreePath;
|
|
@@ -339,7 +367,12 @@ export function makeWorkflowCtx(manifest: TeamRunManifest, opts: MakeWorkflowCtx
|
|
|
339
367
|
role: call.role ?? call.agent,
|
|
340
368
|
});
|
|
341
369
|
if (childResult.exitCode !== 0 || childResult.error) {
|
|
342
|
-
return {
|
|
370
|
+
return {
|
|
371
|
+
ok: false,
|
|
372
|
+
text: "",
|
|
373
|
+
error: childResult.error ?? `exit ${childResult.exitCode}`,
|
|
374
|
+
durationMs: Date.now() - started,
|
|
375
|
+
};
|
|
343
376
|
}
|
|
344
377
|
const parsed = parsePiJsonOutput(childResult.stdout);
|
|
345
378
|
// round-14 P1-2: accumulate this run's token usage into the workflow budget.
|
|
@@ -386,7 +419,12 @@ export function makeWorkflowCtx(manifest: TeamRunManifest, opts: MakeWorkflowCtx
|
|
|
386
419
|
};
|
|
387
420
|
} catch (error) {
|
|
388
421
|
logInternalError("dynamic-workflow-context.agent", error, `runId=${manifest.runId}`);
|
|
389
|
-
return {
|
|
422
|
+
return {
|
|
423
|
+
ok: false,
|
|
424
|
+
text: "",
|
|
425
|
+
error: error instanceof Error ? error.message : String(error),
|
|
426
|
+
durationMs: Date.now() - started,
|
|
427
|
+
};
|
|
390
428
|
} finally {
|
|
391
429
|
// round-17 P2-4: clean up the worktree after the agent completes (success
|
|
392
430
|
// OR failure). Captures the diff as an artifact before removal. Best-effort
|
|
@@ -452,7 +490,18 @@ export function makeWorkflowCtx(manifest: TeamRunManifest, opts: MakeWorkflowCtx
|
|
|
452
490
|
return value as TResult;
|
|
453
491
|
});
|
|
454
492
|
},
|
|
455
|
-
async review(
|
|
493
|
+
async review(
|
|
494
|
+
taskId: string,
|
|
495
|
+
reviewerRole = "reviewer",
|
|
496
|
+
reviewOpts?: {
|
|
497
|
+
content?: string;
|
|
498
|
+
artifactPath?: string;
|
|
499
|
+
disableTools?: boolean;
|
|
500
|
+
},
|
|
501
|
+
): Promise<{
|
|
502
|
+
outcome: "accept" | "reject" | "changes_requested";
|
|
503
|
+
feedback: string;
|
|
504
|
+
}> {
|
|
456
505
|
// review() is a VERDICT step: it must produce a parseable JSON {outcome, feedback}, not a
|
|
457
506
|
// free-form markdown review. The resolved reviewer agent (e.g. ~/.pi/agent/agents/reviewer.md)
|
|
458
507
|
// has tools (read/grep/bash) + a markdown-output system prompt. Without disableTools, the
|
|
@@ -470,13 +519,15 @@ export function makeWorkflowCtx(manifest: TeamRunManifest, opts: MakeWorkflowCtx
|
|
|
470
519
|
prompt: `You are reviewing the work for task '${taskId}'.${workContext}\n\nEvaluate the work and respond with ONLY a single JSON object, no prose, no markdown:\n{"outcome":"accept|reject|changes_requested","feedback":"<one-paragraph explanation>"}\n\n- "accept": work is complete and correct.\n- "reject": work is fundamentally wrong.\n- "changes_requested": work needs revision (explain what in feedback).`,
|
|
471
520
|
maxTurns: 3,
|
|
472
521
|
disableTools,
|
|
473
|
-
systemPrompt:
|
|
522
|
+
systemPrompt:
|
|
523
|
+
'You are a JSON verdict judge. You output ONLY a single JSON object with keys "outcome" (one of accept/reject/changes_requested) and "feedback" (a concise explanation). Never output prose, markdown, or code fences. Begin your response with { and end with }.',
|
|
474
524
|
});
|
|
475
525
|
const extracted = res.structured as { outcome?: string; feedback?: string } | undefined;
|
|
476
526
|
if (extracted && typeof extracted.outcome === "string" && typeof extracted.feedback === "string") {
|
|
477
|
-
const outcome =
|
|
478
|
-
|
|
479
|
-
|
|
527
|
+
const outcome =
|
|
528
|
+
extracted.outcome === "accept" || extracted.outcome === "reject" || extracted.outcome === "changes_requested"
|
|
529
|
+
? extracted.outcome
|
|
530
|
+
: "changes_requested";
|
|
480
531
|
return { outcome, feedback: extracted.feedback };
|
|
481
532
|
}
|
|
482
533
|
// Fallback (round-11 runtime): many models (e.g. MiniMax-M3) ignore JSON-output
|
|
@@ -491,13 +542,15 @@ export function makeWorkflowCtx(manifest: TeamRunManifest, opts: MakeWorkflowCtx
|
|
|
491
542
|
prompt: `Convert the following code review into a verdict JSON. Read the review and decide the outcome.\n\nREVIEW:\n"""\n${res.text.slice(0, 4000)}\n"""\n\nRespond with ONLY a JSON object:\n{"outcome":"accept|reject|changes_requested","feedback":"<concise summary>"}\n- accept: review found no real issues.\n- reject: review found critical/fundamental problems.\n- changes_requested: review found issues that need fixing.`,
|
|
492
543
|
maxTurns: 1,
|
|
493
544
|
disableTools: true,
|
|
494
|
-
systemPrompt:
|
|
545
|
+
systemPrompt:
|
|
546
|
+
"You output ONLY a single JSON object with keys outcome and feedback. Begin with { and end with }. Never output prose.",
|
|
495
547
|
});
|
|
496
548
|
const judged = judge.structured as { outcome?: string; feedback?: string } | undefined;
|
|
497
549
|
if (judged && typeof judged.outcome === "string" && typeof judged.feedback === "string") {
|
|
498
|
-
const outcome =
|
|
499
|
-
|
|
500
|
-
|
|
550
|
+
const outcome =
|
|
551
|
+
judged.outcome === "accept" || judged.outcome === "reject" || judged.outcome === "changes_requested"
|
|
552
|
+
? judged.outcome
|
|
553
|
+
: "changes_requested";
|
|
501
554
|
return { outcome, feedback: judged.feedback };
|
|
502
555
|
}
|
|
503
556
|
}
|
|
@@ -510,20 +563,41 @@ export function makeWorkflowCtx(manifest: TeamRunManifest, opts: MakeWorkflowCtx
|
|
|
510
563
|
// always the hardcoded 'changes_requested' default (e.g. correct code was
|
|
511
564
|
// misclassified as needing changes).
|
|
512
565
|
if (res.text.trim()) {
|
|
513
|
-
return {
|
|
566
|
+
return {
|
|
567
|
+
outcome: classifyReviewOutcome(res.text),
|
|
568
|
+
feedback: res.text,
|
|
569
|
+
};
|
|
514
570
|
}
|
|
515
|
-
return {
|
|
571
|
+
return {
|
|
572
|
+
outcome: "changes_requested",
|
|
573
|
+
feedback: res.text || "(reviewer produced no parseable verdict)",
|
|
574
|
+
};
|
|
516
575
|
},
|
|
517
576
|
async retry(taskId: string, retryOpts?: { feedback?: string }): Promise<AgentResult> {
|
|
518
577
|
return executeWithRetry(
|
|
519
|
-
async () =>
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
578
|
+
async () =>
|
|
579
|
+
ctx.agent({
|
|
580
|
+
role: "executor",
|
|
581
|
+
prompt: `Re-do task '${taskId}'.${retryOpts?.feedback ? ` Feedback: ${retryOpts.feedback}` : ""}`,
|
|
582
|
+
}),
|
|
583
|
+
{
|
|
584
|
+
maxAttempts: 3,
|
|
585
|
+
backoffMs: 0,
|
|
586
|
+
jitterRatio: 0,
|
|
587
|
+
exponentialFactor: 1,
|
|
588
|
+
},
|
|
524
589
|
);
|
|
525
590
|
},
|
|
526
|
-
mail(
|
|
591
|
+
mail(
|
|
592
|
+
to: string,
|
|
593
|
+
body: string,
|
|
594
|
+
mailOpts?: {
|
|
595
|
+
kind?: string;
|
|
596
|
+
taskId?: string;
|
|
597
|
+
replyTo?: string;
|
|
598
|
+
replyDeadline?: number;
|
|
599
|
+
},
|
|
600
|
+
): string {
|
|
527
601
|
const msg = appendMailboxMessage(manifest, {
|
|
528
602
|
direction: "outbox",
|
|
529
603
|
from: "dynamic-workflow",
|
|
@@ -577,7 +651,9 @@ export function makeWorkflowCtx(manifest: TeamRunManifest, opts: MakeWorkflowCtx
|
|
|
577
651
|
phaseCapWarned = true;
|
|
578
652
|
logInternalError(
|
|
579
653
|
"dynamic-workflow-context.phase-cap",
|
|
580
|
-
new Error(
|
|
654
|
+
new Error(
|
|
655
|
+
"Phase list cap of 100 reached; further phases still emit events but are not added to the in-memory phases[] list. Use the events log as the durable source of truth.",
|
|
656
|
+
),
|
|
581
657
|
`runId=${manifest.runId}`,
|
|
582
658
|
);
|
|
583
659
|
}
|
|
@@ -638,12 +714,26 @@ export function makeWorkflowCtx(manifest: TeamRunManifest, opts: MakeWorkflowCtx
|
|
|
638
714
|
|
|
639
715
|
/** Read the final result set by the script (runner-only; not part of the public ctx surface). */
|
|
640
716
|
export function getWorkflowFinalResult(ctx: WorkflowCtx): { artifactPath: string; meta?: Record<string, unknown> } | undefined {
|
|
641
|
-
return (
|
|
717
|
+
return (
|
|
718
|
+
ctx as unknown as {
|
|
719
|
+
__finalResult?: {
|
|
720
|
+
artifactPath: string;
|
|
721
|
+
meta?: Record<string, unknown>;
|
|
722
|
+
};
|
|
723
|
+
}
|
|
724
|
+
).__finalResult;
|
|
642
725
|
}
|
|
643
726
|
|
|
644
727
|
/** Read the in-memory phase state set by the script (runner-only; not part of the public ctx surface). */
|
|
645
728
|
export function getWorkflowPhaseState(ctx: WorkflowCtx): { currentPhase: string | undefined; phases: string[] } | undefined {
|
|
646
|
-
return (
|
|
729
|
+
return (
|
|
730
|
+
ctx as unknown as {
|
|
731
|
+
__phaseState?: {
|
|
732
|
+
currentPhase: string | undefined;
|
|
733
|
+
phases: string[];
|
|
734
|
+
};
|
|
735
|
+
}
|
|
736
|
+
).__phaseState;
|
|
647
737
|
}
|
|
648
738
|
|
|
649
739
|
/** Read the in-memory log buffer appended by ctx.log() (runner-only; not part of the public ctx surface).
|
|
@@ -753,22 +843,58 @@ export function classifyReviewOutcome(prose: string): "accept" | "reject" | "cha
|
|
|
753
843
|
const text = prose.toLowerCase();
|
|
754
844
|
// Strong negative signals → reject. These indicate fundamental/critical problems.
|
|
755
845
|
const rejectSignals = [
|
|
756
|
-
"\breject\b",
|
|
757
|
-
"
|
|
758
|
-
"
|
|
759
|
-
"
|
|
760
|
-
"
|
|
761
|
-
"
|
|
846
|
+
"\breject\b",
|
|
847
|
+
"fundamentally",
|
|
848
|
+
"completely broken",
|
|
849
|
+
"totally broken",
|
|
850
|
+
"critical bug",
|
|
851
|
+
"critical issue",
|
|
852
|
+
"critical flaw",
|
|
853
|
+
"security vulnerability",
|
|
854
|
+
"does not work",
|
|
855
|
+
"doesn't work",
|
|
856
|
+
"will not work",
|
|
857
|
+
"fails to",
|
|
858
|
+
"unacceptable",
|
|
859
|
+
"must not be merged",
|
|
860
|
+
"do not merge",
|
|
861
|
+
"wrong approach",
|
|
862
|
+
"logically incorrect",
|
|
863
|
+
"incorrectly implements",
|
|
864
|
+
"returns the opposite",
|
|
865
|
+
"subtraction instead of addition",
|
|
866
|
+
"opposite of its intended",
|
|
762
867
|
];
|
|
763
868
|
// Acceptance signals → accept. These indicate explicit approval with no real issues.
|
|
764
869
|
const acceptSignals = [
|
|
765
|
-
"\baccept\b",
|
|
766
|
-
"
|
|
767
|
-
"
|
|
768
|
-
"
|
|
769
|
-
"
|
|
770
|
-
"
|
|
771
|
-
"no
|
|
870
|
+
"\baccept\b",
|
|
871
|
+
"looks good",
|
|
872
|
+
"well done",
|
|
873
|
+
"no issues",
|
|
874
|
+
"no real issues",
|
|
875
|
+
"no problems",
|
|
876
|
+
"no concerns",
|
|
877
|
+
"nothing to change",
|
|
878
|
+
"ready to merge",
|
|
879
|
+
"lgtm",
|
|
880
|
+
"ship it",
|
|
881
|
+
"correctly implements",
|
|
882
|
+
"correctly returns",
|
|
883
|
+
"works as expected",
|
|
884
|
+
"works correctly",
|
|
885
|
+
"no bugs",
|
|
886
|
+
"no defects",
|
|
887
|
+
"meets all requirements",
|
|
888
|
+
"all requirements met",
|
|
889
|
+
"passes all",
|
|
890
|
+
"is correct",
|
|
891
|
+
"are correct",
|
|
892
|
+
"no changes needed",
|
|
893
|
+
"no changes required",
|
|
894
|
+
"no further changes",
|
|
895
|
+
"nothing more to",
|
|
896
|
+
"complete and correct",
|
|
897
|
+
"sound implementation",
|
|
772
898
|
];
|
|
773
899
|
const hasReject = rejectSignals.some((sig) => new RegExp(sig).test(text));
|
|
774
900
|
const hasAccept = acceptSignals.some((sig) => new RegExp(sig).test(text));
|
|
@@ -808,7 +934,9 @@ export function extractTextFallback(stdout: string): string {
|
|
|
808
934
|
try {
|
|
809
935
|
const obj = JSON.parse(lineTrim);
|
|
810
936
|
collect(obj);
|
|
811
|
-
} catch {
|
|
937
|
+
} catch {
|
|
938
|
+
/* skip */
|
|
939
|
+
}
|
|
812
940
|
}
|
|
813
941
|
// 2. If nothing from JSON, try plain text (longest non-empty line that's not JSON)
|
|
814
942
|
if (candidates.length === 0) {
|
|
@@ -19,16 +19,16 @@
|
|
|
19
19
|
|
|
20
20
|
import { readFileSync } from "node:fs";
|
|
21
21
|
import { join } from "node:path";
|
|
22
|
-
import { resolveRealContainedPath } from "../utils/safe-paths.ts";
|
|
23
|
-
import { appendEvent } from "../state/event-log.ts";
|
|
24
22
|
import { writeArtifact } from "../state/artifact-store.ts";
|
|
23
|
+
import { appendEvent } from "../state/event-log.ts";
|
|
24
|
+
import type { TeamRunManifest, TeamTaskState } from "../state/types.ts";
|
|
25
25
|
import { logInternalError } from "../utils/internal-error.ts";
|
|
26
|
-
import {
|
|
27
|
-
import {
|
|
28
|
-
import { assertDeterministicScript, isDeterminismCheckEnabled } from "./deterministic-ast.ts";
|
|
29
|
-
import { projectCrewRoot, userPiRoot, packageRoot } from "../utils/paths.ts";
|
|
26
|
+
import { packageRoot, projectCrewRoot, userPiRoot } from "../utils/paths.ts";
|
|
27
|
+
import { resolveRealContainedPath } from "../utils/safe-paths.ts";
|
|
30
28
|
import type { DynamicWorkflowConfig } from "../workflows/workflow-config.ts";
|
|
31
|
-
import
|
|
29
|
+
import { assertDeterministicScript, isDeterminismCheckEnabled } from "./deterministic-ast.ts";
|
|
30
|
+
import { DwfStore } from "./dwf-state-store.ts";
|
|
31
|
+
import { getWorkflowFinalResult, getWorkflowPhaseState, makeWorkflowCtx } from "./dynamic-workflow-context.ts";
|
|
32
32
|
|
|
33
33
|
export interface RunDynamicWorkflowInput {
|
|
34
34
|
manifest: TeamRunManifest;
|
|
@@ -84,11 +84,7 @@ function resolveScriptPath(workflow: DynamicWorkflowConfig, cwd: string): string
|
|
|
84
84
|
// Fix round-5 P1: the round-4 P2-5 fix over-corrected to a SINGLE base (crewRoot/workflows).
|
|
85
85
|
// But discoverWorkflows() reads from THREE dirs (builtin, user, project). Use the same bases
|
|
86
86
|
// so user/builtin dynamic workflows aren't rejected.
|
|
87
|
-
const allowedBases = [
|
|
88
|
-
join(projectCrewRoot(cwd), "workflows"),
|
|
89
|
-
join(userPiRoot(), "workflows"),
|
|
90
|
-
join(packageRoot(), "workflows"),
|
|
91
|
-
];
|
|
87
|
+
const allowedBases = [join(projectCrewRoot(cwd), "workflows"), join(userPiRoot(), "workflows"), join(packageRoot(), "workflows")];
|
|
92
88
|
for (const base of allowedBases) {
|
|
93
89
|
try {
|
|
94
90
|
const real = resolveRealContainedPath(base, workflow.filePath);
|
|
@@ -98,7 +94,9 @@ function resolveScriptPath(workflow: DynamicWorkflowConfig, cwd: string): string
|
|
|
98
94
|
}
|
|
99
95
|
}
|
|
100
96
|
// Not contained in any allowed base — refuse (do NOT fall back to the raw path).
|
|
101
|
-
throw new Error(
|
|
97
|
+
throw new Error(
|
|
98
|
+
`Dynamic workflow '${workflow.filePath}' is outside the allowed workflows directories (${allowedBases.join(", ")}). Refusing to load.`,
|
|
99
|
+
);
|
|
102
100
|
}
|
|
103
101
|
|
|
104
102
|
/**
|
|
@@ -121,7 +119,7 @@ async function loadWorkflowModule(scriptPath: string): Promise<DynamicWorkflowSc
|
|
|
121
119
|
// lazily so this module stays importable in environments without jiti (type-only consumers).
|
|
122
120
|
// Fix round-4: use createRequire(import.meta.url) so `require` works under the strip-types
|
|
123
121
|
// loader fallback (Node ≥ 22.6) where bare `require` is not defined in ESM scope.
|
|
124
|
-
|
|
122
|
+
// LAZY: defer dynamic import of node:module to its call site.
|
|
125
123
|
const { createRequire } = await import("node:module");
|
|
126
124
|
const require = createRequire(import.meta.url);
|
|
127
125
|
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
@@ -144,7 +142,11 @@ export async function runDynamicWorkflow(input: RunDynamicWorkflowInput): Promis
|
|
|
144
142
|
const eventsPath = manifest.eventsPath;
|
|
145
143
|
const scriptPath = resolveScriptPath(workflow, manifest.cwd);
|
|
146
144
|
|
|
147
|
-
appendEvent(eventsPath, {
|
|
145
|
+
appendEvent(eventsPath, {
|
|
146
|
+
type: "dwf.started",
|
|
147
|
+
runId: manifest.runId,
|
|
148
|
+
data: { workflow: workflow.name, script: scriptPath },
|
|
149
|
+
});
|
|
148
150
|
|
|
149
151
|
// round-18 P2-3: resume/checkpoint. Load any existing checkpoint for this run's stateRoot.
|
|
150
152
|
// stateRoot is already <crewRoot>/state/runs/<runId>, so the checkpoint lands at
|
|
@@ -156,7 +158,11 @@ export async function runDynamicWorkflow(input: RunDynamicWorkflowInput): Promis
|
|
|
156
158
|
appendEvent(eventsPath, {
|
|
157
159
|
type: "dwf.resumed",
|
|
158
160
|
runId: manifest.runId,
|
|
159
|
-
data: {
|
|
161
|
+
data: {
|
|
162
|
+
agentCount: resumedState.agentCount,
|
|
163
|
+
phases: resumedState.phases,
|
|
164
|
+
currentPhase: resumedState.currentPhase,
|
|
165
|
+
},
|
|
160
166
|
});
|
|
161
167
|
}
|
|
162
168
|
|
|
@@ -194,7 +200,11 @@ export async function runDynamicWorkflow(input: RunDynamicWorkflowInput): Promis
|
|
|
194
200
|
let timeoutHandle: NodeJS.Timeout | undefined;
|
|
195
201
|
const timeoutPromise = new Promise<never>((_, reject) => {
|
|
196
202
|
timeoutHandle = setTimeout(() => {
|
|
197
|
-
reject(
|
|
203
|
+
reject(
|
|
204
|
+
new Error(
|
|
205
|
+
`Dynamic workflow script timed out after ${SCRIPT_TIMEOUT_MS}ms. The script may have spawned a child process that did not exit. Check for spawn/exec calls without proper stdio handling.`,
|
|
206
|
+
),
|
|
207
|
+
);
|
|
198
208
|
}, SCRIPT_TIMEOUT_MS);
|
|
199
209
|
timeoutHandle.unref?.();
|
|
200
210
|
});
|
|
@@ -205,13 +215,21 @@ export async function runDynamicWorkflow(input: RunDynamicWorkflowInput): Promis
|
|
|
205
215
|
}
|
|
206
216
|
} catch (error) {
|
|
207
217
|
logInternalError("dynamic-workflow-runner.run", error, `runId=${manifest.runId}, workflow=${workflow.name}`);
|
|
208
|
-
appendEvent(eventsPath, {
|
|
218
|
+
appendEvent(eventsPath, {
|
|
219
|
+
type: "dwf.failed",
|
|
220
|
+
runId: manifest.runId,
|
|
221
|
+
data: {
|
|
222
|
+
error: error instanceof Error ? error.message : String(error),
|
|
223
|
+
},
|
|
224
|
+
});
|
|
209
225
|
// Re-throw so background-runner's error handling marks the run failed.
|
|
210
226
|
throw error;
|
|
211
227
|
}
|
|
212
228
|
|
|
213
229
|
const final = getWorkflowFinalResult(ctx);
|
|
214
|
-
const finalText = final
|
|
230
|
+
const finalText = final
|
|
231
|
+
? readFinalArtifact(final.artifactPath)
|
|
232
|
+
: `(dynamic workflow '${workflow.name}' completed without calling ctx.setResult())`;
|
|
215
233
|
|
|
216
234
|
// round-12 P0-4: fail fast on unawaited Promise returns BEFORE we try to
|
|
217
235
|
// write a 2 KB blob that contains a Promise reference. structuredClone on
|
|
@@ -240,7 +258,11 @@ export async function runDynamicWorkflow(input: RunDynamicWorkflowInput): Promis
|
|
|
240
258
|
phaseState.currentPhase = undefined;
|
|
241
259
|
}
|
|
242
260
|
|
|
243
|
-
appendEvent(eventsPath, {
|
|
261
|
+
appendEvent(eventsPath, {
|
|
262
|
+
type: "dwf.completed",
|
|
263
|
+
runId: manifest.runId,
|
|
264
|
+
data: { workflow: workflow.name, summaryArtifact: summary.path },
|
|
265
|
+
});
|
|
244
266
|
|
|
245
267
|
// round-18 P2-3: the run completed cleanly — delete the checkpoint so a fresh re-run
|
|
246
268
|
// (same runId) starts from scratch rather than resuming stale state.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { permissionForRole } from "./role-permission.ts";
|
|
2
1
|
import type { CrewRuntimeConfig } from "../config/config.ts";
|
|
3
2
|
import type { PolicyDecision, TeamRunManifest, TeamTaskState } from "../state/types.ts";
|
|
3
|
+
import { permissionForRole } from "./role-permission.ts";
|
|
4
4
|
|
|
5
5
|
export type EffectivenessGuardMode = "off" | "warn" | "block" | "fail";
|
|
6
6
|
export type WorkerExecutionState = "enabled" | "disabled/scaffold";
|
|
@@ -18,22 +18,30 @@ export interface RunEffectivenessSummary {
|
|
|
18
18
|
|
|
19
19
|
export function taskHasObservableWorkerActivity(task: TeamTaskState): boolean {
|
|
20
20
|
return Boolean(
|
|
21
|
-
(task.agentProgress?.toolCount ?? 0) > 0
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
21
|
+
(task.agentProgress?.toolCount ?? 0) > 0 ||
|
|
22
|
+
task.usage ||
|
|
23
|
+
task.transcriptArtifact ||
|
|
24
|
+
task.modelAttempts?.some((attempt) => attempt.success) ||
|
|
25
|
+
task.jsonEvents,
|
|
26
26
|
);
|
|
27
27
|
}
|
|
28
28
|
|
|
29
|
-
export function resolveEffectivenessGuardMode(
|
|
29
|
+
export function resolveEffectivenessGuardMode(
|
|
30
|
+
runtimeConfig: CrewRuntimeConfig | undefined,
|
|
31
|
+
manifest?: TeamRunManifest,
|
|
32
|
+
): EffectivenessGuardMode {
|
|
30
33
|
const configured = runtimeConfig?.effectivenessGuard;
|
|
31
34
|
if (configured === "off" || configured === "warn" || configured === "block" || configured === "fail") return configured;
|
|
32
35
|
if (manifest?.runtimeResolution?.safety === "explicit_dry_run") return "off";
|
|
33
36
|
return "warn";
|
|
34
37
|
}
|
|
35
38
|
|
|
36
|
-
export function evaluateRunEffectiveness(input: {
|
|
39
|
+
export function evaluateRunEffectiveness(input: {
|
|
40
|
+
manifest?: TeamRunManifest;
|
|
41
|
+
tasks: TeamTaskState[];
|
|
42
|
+
executeWorkers: boolean;
|
|
43
|
+
runtimeConfig?: CrewRuntimeConfig;
|
|
44
|
+
}): RunEffectivenessSummary {
|
|
37
45
|
const completedTasks = input.tasks.filter((task) => task.status === "completed");
|
|
38
46
|
const noObservedWorkTasks = completedTasks.filter((task) => !taskHasObservableWorkerActivity(task));
|
|
39
47
|
const needsAttentionTasks = input.tasks.filter((task) => task.agentProgress?.activityState === "needs_attention");
|
|
@@ -17,7 +17,7 @@ export abstract class CrewError extends Error {
|
|
|
17
17
|
abstract readonly code: string;
|
|
18
18
|
|
|
19
19
|
/** Returns the class name. Use `instanceof` for discrimination. */
|
|
20
|
-
toString(): string {
|
|
20
|
+
toString(): string {
|
|
21
21
|
return `[${this.constructor.name}] ${this.message}`;
|
|
22
22
|
}
|
|
23
23
|
}
|
|
@@ -123,11 +123,11 @@ export class CrewSessionError extends CrewError {
|
|
|
123
123
|
* Used by RunTracker and health monitoring for outcome classification.
|
|
124
124
|
*/
|
|
125
125
|
export type CrewRunOutcome =
|
|
126
|
-
| "ok"
|
|
126
|
+
| "ok" // Completed successfully
|
|
127
127
|
| "cancelled" // Explicitly cancelled by user or API
|
|
128
128
|
| "deadletter" // Agent encountered unrecoverable error
|
|
129
|
-
| "failed"
|
|
130
|
-
| "timeout"
|
|
129
|
+
| "failed" // Workflow step failed (gate error, etc.)
|
|
130
|
+
| "timeout" // Exceeded max duration
|
|
131
131
|
| "aborted"; // Operator interrupt (Esc, SIGINT)
|
|
132
132
|
|
|
133
133
|
/**
|
|
@@ -150,9 +150,7 @@ export function classifyError(error: unknown): CrewRunOutcome {
|
|
|
150
150
|
* (cancelled, aborted, or timed out) vs a genuine failure.
|
|
151
151
|
*/
|
|
152
152
|
export function isInterruptError(error: unknown): boolean {
|
|
153
|
-
return error instanceof CrewCancelledError
|
|
154
|
-
|| error instanceof CrewAbortError
|
|
155
|
-
|| error instanceof CrewTimeoutError;
|
|
153
|
+
return error instanceof CrewCancelledError || error instanceof CrewAbortError || error instanceof CrewTimeoutError;
|
|
156
154
|
}
|
|
157
155
|
|
|
158
156
|
/**
|
|
@@ -160,7 +158,5 @@ export function isInterruptError(error: unknown): boolean {
|
|
|
160
158
|
* rather than workflow logic or user action.
|
|
161
159
|
*/
|
|
162
160
|
export function isAgentError(error: unknown): boolean {
|
|
163
|
-
return error instanceof CrewDeadletterError
|
|
164
|
-
|
|
165
|
-
|| error instanceof CrewSessionError;
|
|
166
|
-
}
|
|
161
|
+
return error instanceof CrewDeadletterError || error instanceof CrewTurnLimitError || error instanceof CrewSessionError;
|
|
162
|
+
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { runEventBus } from "../ui/run-event-bus.ts";
|
|
2
|
-
import {
|
|
2
|
+
import { type SubprocessToolEvent, subprocessToolRegistry } from "./subprocess-tool-registry.ts";
|
|
3
3
|
|
|
4
4
|
export interface StreamBridgeEvent {
|
|
5
5
|
runId: string;
|
|
@@ -15,10 +15,16 @@ export interface StreamBridgeEvent {
|
|
|
15
15
|
|
|
16
16
|
const activeBridges = new Map<string, (event: StreamBridgeEvent) => void>();
|
|
17
17
|
|
|
18
|
-
export function registerStreamBridge(runId: string): {
|
|
18
|
+
export function registerStreamBridge(runId: string): {
|
|
19
|
+
handler: (event: StreamBridgeEvent) => void;
|
|
20
|
+
dispose: () => void;
|
|
21
|
+
} {
|
|
19
22
|
const existing = activeBridges.get(runId);
|
|
20
23
|
if (existing) {
|
|
21
|
-
return {
|
|
24
|
+
return {
|
|
25
|
+
handler: existing,
|
|
26
|
+
dispose: () => unregisterStreamBridge(runId),
|
|
27
|
+
};
|
|
22
28
|
}
|
|
23
29
|
|
|
24
30
|
const handler = (event: StreamBridgeEvent) => {
|