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
|
@@ -15,14 +15,14 @@
|
|
|
15
15
|
// `__test__parseAdaptivePlan` and `__test__repairAdaptivePlan` are re-exported
|
|
16
16
|
// from team-runner.ts so existing test imports keep working.
|
|
17
17
|
import * as fs from "node:fs";
|
|
18
|
-
import { appendEvent } from "../state/event-log.ts";
|
|
19
18
|
import { writeArtifact } from "../state/artifact-store.ts";
|
|
19
|
+
import { appendEvent } from "../state/event-log.ts";
|
|
20
20
|
import { saveRunManifest } from "../state/state-store.ts";
|
|
21
|
+
import type { TeamRunManifest, TeamTaskState } from "../state/types.ts";
|
|
21
22
|
import type { TeamConfig } from "../teams/team-config.ts";
|
|
22
23
|
import type { WorkflowConfig, WorkflowStep } from "../workflows/workflow-config.ts";
|
|
23
|
-
import
|
|
24
|
+
import { getPlanTemplate, listPlanTemplates, renderPlanTemplate } from "./plan-templates.ts";
|
|
24
25
|
import { refreshTaskGraphQueues } from "./task-graph-scheduler.ts";
|
|
25
|
-
import { getPlanTemplate, renderPlanTemplate, listPlanTemplates } from "./plan-templates.ts";
|
|
26
26
|
|
|
27
27
|
export interface AdaptivePlanTask {
|
|
28
28
|
role: string;
|
|
@@ -42,7 +42,13 @@ export interface AdaptivePlan {
|
|
|
42
42
|
const MAX_ADAPTIVE_TASKS = 12;
|
|
43
43
|
|
|
44
44
|
export function slug(value: string): string {
|
|
45
|
-
return
|
|
45
|
+
return (
|
|
46
|
+
value
|
|
47
|
+
.toLowerCase()
|
|
48
|
+
.replace(/[^a-z0-9]+/g, "-")
|
|
49
|
+
.replace(/^-+|-+$/g, "")
|
|
50
|
+
.slice(0, 32) || "task"
|
|
51
|
+
);
|
|
46
52
|
}
|
|
47
53
|
|
|
48
54
|
/** Strip surrounding markdown code fences if present. */
|
|
@@ -81,11 +87,13 @@ export function parseAdaptivePlan(text: string, allowedRoles: string[]): Adaptiv
|
|
|
81
87
|
try {
|
|
82
88
|
const varsJson = text.slice(templateRefMatch[0].length).trim();
|
|
83
89
|
if (varsJson) variables = JSON.parse(varsJson);
|
|
84
|
-
} catch {
|
|
90
|
+
} catch {
|
|
91
|
+
/* use empty variables */
|
|
92
|
+
}
|
|
85
93
|
const rendered = renderPlanTemplate(templateRefMatch[1], variables);
|
|
86
94
|
if (rendered) {
|
|
87
95
|
// Convert RenderedPlan → AdaptivePlan
|
|
88
|
-
const phases: AdaptivePlanPhase[] = rendered.phases.map(phase => ({
|
|
96
|
+
const phases: AdaptivePlanPhase[] = rendered.phases.map((phase) => ({
|
|
89
97
|
name: phase.name,
|
|
90
98
|
tasks: [{ role: phase.role, task: phase.task }],
|
|
91
99
|
}));
|
|
@@ -97,9 +105,22 @@ export function parseAdaptivePlan(text: string, allowedRoles: string[]): Adaptiv
|
|
|
97
105
|
const raw = extractAdaptivePlanJson(text);
|
|
98
106
|
if (!raw) return undefined;
|
|
99
107
|
let parsed: unknown;
|
|
100
|
-
try {
|
|
108
|
+
try {
|
|
109
|
+
parsed = JSON.parse(raw);
|
|
110
|
+
} catch {
|
|
111
|
+
return undefined;
|
|
112
|
+
}
|
|
101
113
|
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) return undefined;
|
|
102
|
-
const phasesRaw = Array.isArray((parsed as { phases?: unknown }).phases)
|
|
114
|
+
const phasesRaw = Array.isArray((parsed as { phases?: unknown }).phases)
|
|
115
|
+
? (parsed as { phases: unknown[] }).phases
|
|
116
|
+
: Array.isArray((parsed as { tasks?: unknown }).tasks)
|
|
117
|
+
? [
|
|
118
|
+
{
|
|
119
|
+
name: "adaptive",
|
|
120
|
+
tasks: (parsed as { tasks: unknown[] }).tasks,
|
|
121
|
+
},
|
|
122
|
+
]
|
|
123
|
+
: undefined;
|
|
103
124
|
if (!phasesRaw) return undefined;
|
|
104
125
|
const allowed = new Set(allowedRoles);
|
|
105
126
|
const phases: AdaptivePlanPhase[] = [];
|
|
@@ -111,14 +132,25 @@ export function parseAdaptivePlan(text: string, allowedRoles: string[]): Adaptiv
|
|
|
111
132
|
const tasks: AdaptivePlanTask[] = [];
|
|
112
133
|
for (const taskRaw of phaseObj.tasks) {
|
|
113
134
|
if (!taskRaw || typeof taskRaw !== "object" || Array.isArray(taskRaw)) return undefined;
|
|
114
|
-
const taskObj = taskRaw as {
|
|
135
|
+
const taskObj = taskRaw as {
|
|
136
|
+
role?: unknown;
|
|
137
|
+
title?: unknown;
|
|
138
|
+
task?: unknown;
|
|
139
|
+
};
|
|
115
140
|
if (typeof taskObj.role !== "string" || !allowed.has(taskObj.role)) return undefined;
|
|
116
141
|
if (typeof taskObj.task !== "string" || !taskObj.task.trim()) return undefined;
|
|
117
142
|
if (total >= MAX_ADAPTIVE_TASKS) return undefined;
|
|
118
|
-
tasks.push({
|
|
143
|
+
tasks.push({
|
|
144
|
+
role: taskObj.role,
|
|
145
|
+
title: typeof taskObj.title === "string" ? taskObj.title : undefined,
|
|
146
|
+
task: taskObj.task.trim(),
|
|
147
|
+
});
|
|
119
148
|
total++;
|
|
120
149
|
}
|
|
121
|
-
phases.push({
|
|
150
|
+
phases.push({
|
|
151
|
+
name: typeof phaseObj.name === "string" && phaseObj.name.trim() ? phaseObj.name.trim() : `phase-${phaseIndex + 1}`,
|
|
152
|
+
tasks,
|
|
153
|
+
});
|
|
122
154
|
}
|
|
123
155
|
return phases.length ? { phases } : undefined;
|
|
124
156
|
}
|
|
@@ -154,7 +186,11 @@ function closeUnbalancedJson(raw: string): CloseUnbalancedJsonResult {
|
|
|
154
186
|
}
|
|
155
187
|
while (stack.length) result += stack.pop();
|
|
156
188
|
if (inString) {
|
|
157
|
-
return {
|
|
189
|
+
return {
|
|
190
|
+
text: result,
|
|
191
|
+
status: "unstable",
|
|
192
|
+
warning: "JSON string was truncated — values may be incorrect",
|
|
193
|
+
};
|
|
158
194
|
}
|
|
159
195
|
return { text: result, status: "repaired" };
|
|
160
196
|
}
|
|
@@ -240,7 +276,16 @@ export function repairAdaptivePlan(text: string, allowedRoles: string[]): { plan
|
|
|
240
276
|
salvageUsed = parsed !== undefined;
|
|
241
277
|
}
|
|
242
278
|
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) return { repaired: false, reason: "invalid-json" };
|
|
243
|
-
const phasesRaw = Array.isArray((parsed as { phases?: unknown }).phases)
|
|
279
|
+
const phasesRaw = Array.isArray((parsed as { phases?: unknown }).phases)
|
|
280
|
+
? (parsed as { phases: unknown[] }).phases
|
|
281
|
+
: Array.isArray((parsed as { tasks?: unknown }).tasks)
|
|
282
|
+
? [
|
|
283
|
+
{
|
|
284
|
+
name: "adaptive",
|
|
285
|
+
tasks: (parsed as { tasks: unknown[] }).tasks,
|
|
286
|
+
},
|
|
287
|
+
]
|
|
288
|
+
: undefined;
|
|
244
289
|
if (!phasesRaw) return { repaired: false, reason: "missing-phases" };
|
|
245
290
|
const allowed = new Set(allowedRoles);
|
|
246
291
|
const phases: AdaptivePlanPhase[] = [];
|
|
@@ -260,20 +305,38 @@ export function repairAdaptivePlan(text: string, allowedRoles: string[]): { plan
|
|
|
260
305
|
repaired = true;
|
|
261
306
|
continue;
|
|
262
307
|
}
|
|
263
|
-
const taskObj = taskRaw as {
|
|
308
|
+
const taskObj = taskRaw as {
|
|
309
|
+
role?: unknown;
|
|
310
|
+
title?: unknown;
|
|
311
|
+
task?: unknown;
|
|
312
|
+
};
|
|
264
313
|
const role = typeof taskObj.role === "string" ? adaptiveRoleAlias(taskObj.role, allowed) : undefined;
|
|
265
314
|
const taskText = typeof taskObj.task === "string" ? taskObj.task.trim() : "";
|
|
266
315
|
if (!role || !taskText) {
|
|
267
316
|
repaired = true;
|
|
268
317
|
continue;
|
|
269
318
|
}
|
|
270
|
-
tasks.push({
|
|
319
|
+
tasks.push({
|
|
320
|
+
role,
|
|
321
|
+
title: typeof taskObj.title === "string" ? taskObj.title : undefined,
|
|
322
|
+
task: taskText,
|
|
323
|
+
});
|
|
271
324
|
total++;
|
|
272
325
|
}
|
|
273
|
-
if (tasks.length)
|
|
326
|
+
if (tasks.length)
|
|
327
|
+
phases.push({
|
|
328
|
+
name: typeof phaseObj.name === "string" && phaseObj.name.trim() ? phaseObj.name.trim() : `phase-${phaseIndex + 1}`,
|
|
329
|
+
tasks,
|
|
330
|
+
});
|
|
274
331
|
if (total >= MAX_ADAPTIVE_TASKS) break;
|
|
275
332
|
}
|
|
276
|
-
return phases.length
|
|
333
|
+
return phases.length
|
|
334
|
+
? {
|
|
335
|
+
plan: { phases },
|
|
336
|
+
repaired: true,
|
|
337
|
+
reason: repaired ? "repaired" : "normalized",
|
|
338
|
+
}
|
|
339
|
+
: { repaired: false, reason: "empty-plan" };
|
|
277
340
|
}
|
|
278
341
|
|
|
279
342
|
function reconstructAdaptiveWorkflow(workflow: WorkflowConfig, tasks: TeamTaskState[]): WorkflowConfig {
|
|
@@ -281,7 +344,13 @@ function reconstructAdaptiveWorkflow(workflow: WorkflowConfig, tasks: TeamTaskSt
|
|
|
281
344
|
const steps: WorkflowStep[] = [];
|
|
282
345
|
for (const task of tasks) {
|
|
283
346
|
if (!task.stepId?.startsWith("adaptive-") || !task.adaptive?.task || existing.has(task.stepId)) continue;
|
|
284
|
-
steps.push({
|
|
347
|
+
steps.push({
|
|
348
|
+
id: task.stepId,
|
|
349
|
+
role: task.role,
|
|
350
|
+
dependsOn: task.graph?.dependencies ?? task.dependsOn,
|
|
351
|
+
parallelGroup: `adaptive-${slug(task.adaptive.phase)}`,
|
|
352
|
+
task: task.adaptive.task,
|
|
353
|
+
});
|
|
285
354
|
}
|
|
286
355
|
return steps.length ? { ...workflow, steps: [...workflow.steps, ...steps] } : workflow;
|
|
287
356
|
}
|
|
@@ -301,34 +370,110 @@ export interface InjectAdaptivePlanResult {
|
|
|
301
370
|
}
|
|
302
371
|
|
|
303
372
|
export function injectAdaptivePlanIfReady(input: InjectAdaptivePlanInput): InjectAdaptivePlanResult {
|
|
304
|
-
if (input.workflow.name !== "implementation")
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
373
|
+
if (input.workflow.name !== "implementation")
|
|
374
|
+
return {
|
|
375
|
+
tasks: input.tasks,
|
|
376
|
+
workflow: input.workflow,
|
|
377
|
+
injected: false,
|
|
378
|
+
missingPlan: false,
|
|
379
|
+
};
|
|
380
|
+
if (input.tasks.some((task) => task.stepId?.startsWith("adaptive-")))
|
|
381
|
+
return {
|
|
382
|
+
tasks: input.tasks,
|
|
383
|
+
workflow: reconstructAdaptiveWorkflow(input.workflow, input.tasks),
|
|
384
|
+
injected: false,
|
|
385
|
+
missingPlan: false,
|
|
386
|
+
};
|
|
387
|
+
const completedAssess = input.tasks.find(
|
|
388
|
+
(task) => task.stepId === "assess" && (task.status === "completed" || task.status === "needs_attention"),
|
|
389
|
+
);
|
|
390
|
+
if (!completedAssess)
|
|
391
|
+
return {
|
|
392
|
+
tasks: input.tasks,
|
|
393
|
+
workflow: input.workflow,
|
|
394
|
+
injected: false,
|
|
395
|
+
missingPlan: false,
|
|
396
|
+
};
|
|
308
397
|
if (!completedAssess.resultArtifact?.path) {
|
|
309
|
-
appendEvent(input.manifest.eventsPath, {
|
|
310
|
-
|
|
398
|
+
appendEvent(input.manifest.eventsPath, {
|
|
399
|
+
type: "adaptive.plan_missing",
|
|
400
|
+
runId: input.manifest.runId,
|
|
401
|
+
taskId: completedAssess.id,
|
|
402
|
+
message: "Adaptive planner result artifact is missing.",
|
|
403
|
+
});
|
|
404
|
+
return {
|
|
405
|
+
tasks: input.tasks,
|
|
406
|
+
workflow: input.workflow,
|
|
407
|
+
injected: false,
|
|
408
|
+
missingPlan: true,
|
|
409
|
+
};
|
|
311
410
|
}
|
|
312
411
|
const assessTask = completedAssess;
|
|
313
412
|
const resultPath = completedAssess.resultArtifact.path;
|
|
314
413
|
let text = "";
|
|
315
|
-
try {
|
|
316
|
-
|
|
317
|
-
|
|
414
|
+
try {
|
|
415
|
+
text = fs.readFileSync(resultPath, "utf-8");
|
|
416
|
+
} catch {
|
|
417
|
+
appendEvent(input.manifest.eventsPath, {
|
|
418
|
+
type: "adaptive.plan_missing",
|
|
419
|
+
runId: input.manifest.runId,
|
|
420
|
+
taskId: assessTask.id,
|
|
421
|
+
message: "Adaptive planner result artifact could not be read.",
|
|
422
|
+
});
|
|
423
|
+
return {
|
|
424
|
+
tasks: input.tasks,
|
|
425
|
+
workflow: input.workflow,
|
|
426
|
+
injected: false,
|
|
427
|
+
missingPlan: true,
|
|
428
|
+
};
|
|
318
429
|
}
|
|
319
430
|
const allowedRoles = input.team.roles.map((role) => role.name);
|
|
320
431
|
let plan = parseAdaptivePlan(text, allowedRoles);
|
|
321
432
|
if (!plan) {
|
|
322
|
-
const repair =
|
|
433
|
+
const repair =
|
|
434
|
+
process.env.PI_CREW_ADAPTIVE_REPAIR === "0" || process.env.PI_TEAMS_ADAPTIVE_REPAIR === "0"
|
|
435
|
+
? { repaired: false, reason: "disabled" }
|
|
436
|
+
: repairAdaptivePlan(text, allowedRoles);
|
|
323
437
|
if (repair.plan) {
|
|
324
438
|
plan = repair.plan;
|
|
325
|
-
const repairArtifact = writeArtifact(input.manifest.artifactsRoot, {
|
|
326
|
-
|
|
327
|
-
|
|
439
|
+
const repairArtifact = writeArtifact(input.manifest.artifactsRoot, {
|
|
440
|
+
kind: "metadata",
|
|
441
|
+
relativePath: "metadata/adaptive-repair.json",
|
|
442
|
+
producer: assessTask.id,
|
|
443
|
+
content: `${JSON.stringify({ reason: repair.reason, phases: repair.plan.phases.map((phase) => ({ name: phase.name, count: phase.tasks.length, roles: phase.tasks.map((task) => task.role) })) }, null, 2)}\n`,
|
|
444
|
+
});
|
|
445
|
+
saveRunManifest({
|
|
446
|
+
...input.manifest,
|
|
447
|
+
updatedAt: new Date().toISOString(),
|
|
448
|
+
artifacts: [...input.manifest.artifacts, repairArtifact],
|
|
449
|
+
});
|
|
450
|
+
appendEvent(input.manifest.eventsPath, {
|
|
451
|
+
type: "adaptive.plan_repaired",
|
|
452
|
+
runId: input.manifest.runId,
|
|
453
|
+
taskId: assessTask.id,
|
|
454
|
+
message: "Adaptive planner output was repaired before dynamic subagents were spawned.",
|
|
455
|
+
data: { reason: repair.reason },
|
|
456
|
+
});
|
|
328
457
|
} else {
|
|
329
|
-
appendEvent(input.manifest.eventsPath, {
|
|
330
|
-
|
|
331
|
-
|
|
458
|
+
appendEvent(input.manifest.eventsPath, {
|
|
459
|
+
type: "adaptive.plan_repair_failed",
|
|
460
|
+
runId: input.manifest.runId,
|
|
461
|
+
taskId: assessTask.id,
|
|
462
|
+
message: "Adaptive planner output could not be repaired.",
|
|
463
|
+
data: { reason: repair.reason },
|
|
464
|
+
});
|
|
465
|
+
appendEvent(input.manifest.eventsPath, {
|
|
466
|
+
type: "adaptive.plan_missing",
|
|
467
|
+
runId: input.manifest.runId,
|
|
468
|
+
taskId: assessTask.id,
|
|
469
|
+
message: "Adaptive planner did not produce a valid plan; no dynamic subagents were spawned.",
|
|
470
|
+
});
|
|
471
|
+
return {
|
|
472
|
+
tasks: input.tasks,
|
|
473
|
+
workflow: input.workflow,
|
|
474
|
+
injected: false,
|
|
475
|
+
missingPlan: true,
|
|
476
|
+
};
|
|
332
477
|
}
|
|
333
478
|
}
|
|
334
479
|
const steps: WorkflowStep[] = [];
|
|
@@ -341,7 +486,13 @@ export function injectAdaptivePlanIfReady(input: InjectAdaptivePlanInput): Injec
|
|
|
341
486
|
counter++;
|
|
342
487
|
const stepId = `adaptive-${phaseIndex + 1}-${taskIndex + 1}-${slug(planned.role)}`;
|
|
343
488
|
const taskId = `adaptive-${String(counter).padStart(2, "0")}-${slug(planned.role)}`;
|
|
344
|
-
steps.push({
|
|
489
|
+
steps.push({
|
|
490
|
+
id: stepId,
|
|
491
|
+
role: planned.role,
|
|
492
|
+
dependsOn: previousStepIds,
|
|
493
|
+
parallelGroup: `adaptive-${slug(phase.name)}`,
|
|
494
|
+
task: planned.task,
|
|
495
|
+
});
|
|
345
496
|
tasks.push({
|
|
346
497
|
id: taskId,
|
|
347
498
|
runId: input.manifest.runId,
|
|
@@ -353,21 +504,55 @@ export function injectAdaptivePlanIfReady(input: InjectAdaptivePlanInput): Injec
|
|
|
353
504
|
dependsOn: previousStepIds,
|
|
354
505
|
cwd: input.manifest.cwd,
|
|
355
506
|
adaptive: { phase: phase.name, task: planned.task },
|
|
356
|
-
graph: {
|
|
507
|
+
graph: {
|
|
508
|
+
taskId,
|
|
509
|
+
dependencies: previousStepIds,
|
|
510
|
+
children: [],
|
|
511
|
+
queue: "blocked",
|
|
512
|
+
},
|
|
357
513
|
});
|
|
358
514
|
currentStepIds.push(stepId);
|
|
359
515
|
}
|
|
360
516
|
previousStepIds = currentStepIds;
|
|
361
517
|
}
|
|
362
|
-
const dependencyTaskIdByStep = new Map<string, string>([
|
|
518
|
+
const dependencyTaskIdByStep = new Map<string, string>([
|
|
519
|
+
["assess", assessTask.id],
|
|
520
|
+
...tasks.map((task) => [task.stepId ?? task.id, task.id] as const),
|
|
521
|
+
]);
|
|
363
522
|
const withGraph = tasks.map((task) => ({
|
|
364
523
|
...task,
|
|
365
524
|
dependsOn: task.dependsOn.map((dep) => dependencyTaskIdByStep.get(dep) ?? dep),
|
|
366
|
-
graph: task.graph
|
|
525
|
+
graph: task.graph
|
|
526
|
+
? {
|
|
527
|
+
...task.graph,
|
|
528
|
+
dependencies: task.dependsOn.map((dep) => dependencyTaskIdByStep.get(dep) ?? dep),
|
|
529
|
+
queue: "blocked" as const,
|
|
530
|
+
}
|
|
531
|
+
: task.graph,
|
|
367
532
|
}));
|
|
368
533
|
const allTasks = refreshTaskGraphQueues([...input.tasks, ...withGraph]);
|
|
369
|
-
appendEvent(input.manifest.eventsPath, {
|
|
370
|
-
|
|
534
|
+
appendEvent(input.manifest.eventsPath, {
|
|
535
|
+
type: "adaptive.plan_injected",
|
|
536
|
+
runId: input.manifest.runId,
|
|
537
|
+
taskId: assessTask.id,
|
|
538
|
+
message: `Injected ${withGraph.length} adaptive subagent task(s) across ${plan.phases.length} phase(s).`,
|
|
539
|
+
data: {
|
|
540
|
+
phases: plan.phases.map((phase) => ({
|
|
541
|
+
name: phase.name,
|
|
542
|
+
count: phase.tasks.length,
|
|
543
|
+
roles: phase.tasks.map((task) => task.role),
|
|
544
|
+
})),
|
|
545
|
+
},
|
|
546
|
+
});
|
|
547
|
+
return {
|
|
548
|
+
tasks: allTasks,
|
|
549
|
+
workflow: {
|
|
550
|
+
...input.workflow,
|
|
551
|
+
steps: [...input.workflow.steps, ...steps],
|
|
552
|
+
},
|
|
553
|
+
injected: true,
|
|
554
|
+
missingPlan: false,
|
|
555
|
+
};
|
|
371
556
|
}
|
|
372
557
|
|
|
373
558
|
// Test compatibility: original team-runner.ts exposed these names. Keep
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
+
import { randomUUID } from "node:crypto";
|
|
1
2
|
import type { PiTeamsConfig } from "../config/config.ts";
|
|
2
|
-
import type {
|
|
3
|
+
import type { ControlReservation, TeamRunManifest } from "../state/types.ts";
|
|
3
4
|
import { appendTaskAttentionEvent } from "./attention-events.ts";
|
|
4
|
-
import type { CrewAgentRecord } from "./crew-agent-runtime.ts";
|
|
5
5
|
import { upsertCrewAgent } from "./crew-agent-records.ts";
|
|
6
|
-
import {
|
|
6
|
+
import type { CrewAgentRecord } from "./crew-agent-runtime.ts";
|
|
7
7
|
|
|
8
8
|
export interface CrewControlConfig {
|
|
9
9
|
enabled: boolean;
|
|
@@ -21,7 +21,16 @@ function positiveInt(value: unknown): number | undefined {
|
|
|
21
21
|
}
|
|
22
22
|
|
|
23
23
|
export function resolveCrewControlConfig(config: PiTeamsConfig | undefined): CrewControlConfig {
|
|
24
|
-
const raw = config as
|
|
24
|
+
const raw = config as
|
|
25
|
+
| (PiTeamsConfig & {
|
|
26
|
+
control?: {
|
|
27
|
+
enabled?: unknown;
|
|
28
|
+
needsAttentionAfterMs?: unknown;
|
|
29
|
+
consecutiveFailureThreshold?: unknown;
|
|
30
|
+
longRunningMinutes?: unknown;
|
|
31
|
+
};
|
|
32
|
+
})
|
|
33
|
+
| undefined;
|
|
25
34
|
return {
|
|
26
35
|
enabled: raw?.control?.enabled === false ? false : true,
|
|
27
36
|
needsAttentionAfterMs: positiveInt(raw?.control?.needsAttentionAfterMs) ?? DEFAULT_NEEDS_ATTENTION_MS,
|
|
@@ -47,7 +56,12 @@ export function formatActivityAge(agent: CrewAgentRecord, now = Date.now()): str
|
|
|
47
56
|
return agent.progress?.activityState === "needs_attention" ? `no activity for ${minutes}m` : `active ${minutes}m ago`;
|
|
48
57
|
}
|
|
49
58
|
|
|
50
|
-
export function applyAttentionState(
|
|
59
|
+
export function applyAttentionState(
|
|
60
|
+
manifest: TeamRunManifest,
|
|
61
|
+
agent: CrewAgentRecord,
|
|
62
|
+
config: CrewControlConfig,
|
|
63
|
+
now = Date.now(),
|
|
64
|
+
): CrewAgentRecord {
|
|
51
65
|
if (!config.enabled || agent.status !== "running") return agent;
|
|
52
66
|
const age = activityAgeMs(agent, now);
|
|
53
67
|
if (age === undefined || age <= config.needsAttentionAfterMs) return agent;
|
|
@@ -55,7 +69,11 @@ export function applyAttentionState(manifest: TeamRunManifest, agent: CrewAgentR
|
|
|
55
69
|
const updated: CrewAgentRecord = {
|
|
56
70
|
...agent,
|
|
57
71
|
progress: {
|
|
58
|
-
...(agent.progress ?? {
|
|
72
|
+
...(agent.progress ?? {
|
|
73
|
+
recentTools: [],
|
|
74
|
+
recentOutput: [],
|
|
75
|
+
toolCount: agent.toolUses ?? 0,
|
|
76
|
+
}),
|
|
59
77
|
activityState: "needs_attention",
|
|
60
78
|
},
|
|
61
79
|
};
|
|
@@ -64,7 +82,14 @@ export function applyAttentionState(manifest: TeamRunManifest, agent: CrewAgentR
|
|
|
64
82
|
manifest,
|
|
65
83
|
taskId: agent.taskId,
|
|
66
84
|
message: `${agent.agent} needs attention (no observed activity for ${Math.floor(age / 1000)}s).`,
|
|
67
|
-
data: {
|
|
85
|
+
data: {
|
|
86
|
+
activityState: "needs_attention",
|
|
87
|
+
reason: "idle",
|
|
88
|
+
elapsedMs: age,
|
|
89
|
+
taskId: agent.taskId,
|
|
90
|
+
agentName: agent.agent,
|
|
91
|
+
suggestedAction: "Check worker status, wait, steer, or cancel if needed.",
|
|
92
|
+
},
|
|
68
93
|
});
|
|
69
94
|
return updated;
|
|
70
95
|
}
|
|
@@ -92,7 +117,11 @@ function applyLongRunningCheck(
|
|
|
92
117
|
const updated: CrewAgentRecord = {
|
|
93
118
|
...agent,
|
|
94
119
|
progress: {
|
|
95
|
-
...(agent.progress ?? {
|
|
120
|
+
...(agent.progress ?? {
|
|
121
|
+
recentTools: [],
|
|
122
|
+
recentOutput: [],
|
|
123
|
+
toolCount: agent.toolUses ?? 0,
|
|
124
|
+
}),
|
|
96
125
|
activityState: "active_long_running",
|
|
97
126
|
},
|
|
98
127
|
};
|
|
@@ -101,7 +130,14 @@ function applyLongRunningCheck(
|
|
|
101
130
|
manifest,
|
|
102
131
|
taskId: agent.taskId,
|
|
103
132
|
message: `${agent.agent} has been running for ${Math.floor(runtimeMs / 60000)}m (threshold: ${config.longRunningMinutes}m).`,
|
|
104
|
-
data: {
|
|
133
|
+
data: {
|
|
134
|
+
activityState: "active_long_running",
|
|
135
|
+
reason: "idle",
|
|
136
|
+
elapsedMs: runtimeMs,
|
|
137
|
+
taskId: agent.taskId,
|
|
138
|
+
agentName: agent.agent,
|
|
139
|
+
suggestedAction: "Check worker progress, steer, or cancel if needed.",
|
|
140
|
+
},
|
|
105
141
|
});
|
|
106
142
|
return updated;
|
|
107
143
|
}
|
|
@@ -122,7 +158,11 @@ function trackConsecutiveToolFailure(
|
|
|
122
158
|
const updated: CrewAgentRecord = {
|
|
123
159
|
...agent,
|
|
124
160
|
progress: {
|
|
125
|
-
...(agent.progress ?? {
|
|
161
|
+
...(agent.progress ?? {
|
|
162
|
+
recentTools: [],
|
|
163
|
+
recentOutput: [],
|
|
164
|
+
toolCount: agent.toolUses ?? 0,
|
|
165
|
+
}),
|
|
126
166
|
consecutiveFailures: newFailures,
|
|
127
167
|
},
|
|
128
168
|
};
|
|
@@ -133,7 +173,13 @@ function trackConsecutiveToolFailure(
|
|
|
133
173
|
manifest,
|
|
134
174
|
taskId: agent.taskId,
|
|
135
175
|
message: `${agent.agent} has ${newFailures} consecutive tool failures (threshold: ${config.consecutiveFailureThreshold}). Last: ${toolName}${error ? ` - ${error.slice(0, 100)}` : ""}`,
|
|
136
|
-
data: {
|
|
176
|
+
data: {
|
|
177
|
+
activityState: "needs_attention",
|
|
178
|
+
reason: "tool_failures",
|
|
179
|
+
taskId: agent.taskId,
|
|
180
|
+
agentName: agent.agent,
|
|
181
|
+
suggestedAction: "Investigate tool failures, steer, or cancel if needed.",
|
|
182
|
+
},
|
|
137
183
|
});
|
|
138
184
|
} else {
|
|
139
185
|
upsertCrewAgent(manifest, updated);
|
|
@@ -143,10 +189,7 @@ function trackConsecutiveToolFailure(
|
|
|
143
189
|
}
|
|
144
190
|
|
|
145
191
|
/** @internal */
|
|
146
|
-
function resetConsecutiveToolFailures(
|
|
147
|
-
manifest: TeamRunManifest,
|
|
148
|
-
agent: CrewAgentRecord,
|
|
149
|
-
): void {
|
|
192
|
+
function resetConsecutiveToolFailures(manifest: TeamRunManifest, agent: CrewAgentRecord): void {
|
|
150
193
|
if (!agent.progress?.consecutiveFailures) return;
|
|
151
194
|
const updated: CrewAgentRecord = {
|
|
152
195
|
...agent,
|
|
@@ -61,15 +61,21 @@ export function buildMemoryBlock(agentName: string, scope: AgentMemoryScope, cwd
|
|
|
61
61
|
`# Agent Memory (${mode})`,
|
|
62
62
|
`Memory scope: ${scope}`,
|
|
63
63
|
`Memory directory: ${memoryDir}`,
|
|
64
|
-
writable
|
|
64
|
+
writable
|
|
65
|
+
? "Use this persistent directory to maintain useful long-term notes for this agent."
|
|
66
|
+
: "You may reference existing memory, but do not create or modify memory files.",
|
|
65
67
|
"",
|
|
66
68
|
existing ? `## Current MEMORY.md\n${existing}` : "No MEMORY.md exists yet.",
|
|
67
|
-
writable
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
69
|
+
writable
|
|
70
|
+
? [
|
|
71
|
+
"",
|
|
72
|
+
"## Memory Instructions",
|
|
73
|
+
"- Keep MEMORY.md concise (under 200 lines); store details in separate linked files.",
|
|
74
|
+
"- Reject stale memories; update or remove outdated notes.",
|
|
75
|
+
"- Use safe relative filenames inside the memory directory only.",
|
|
76
|
+
].join("\n")
|
|
77
|
+
: "",
|
|
78
|
+
]
|
|
79
|
+
.filter(Boolean)
|
|
80
|
+
.join("\n");
|
|
75
81
|
}
|
|
@@ -28,7 +28,12 @@ export function readTextTail(filePath: string, maxBytes = 64_000): TextTailResul
|
|
|
28
28
|
try {
|
|
29
29
|
const buffer = Buffer.alloc(bytesToRead);
|
|
30
30
|
fs.readSync(fd, buffer, 0, bytesToRead, stat.size - bytesToRead);
|
|
31
|
-
return {
|
|
31
|
+
return {
|
|
32
|
+
path: filePath,
|
|
33
|
+
text: buffer.toString("utf-8"),
|
|
34
|
+
bytes: stat.size,
|
|
35
|
+
truncated: stat.size > bytesToRead,
|
|
36
|
+
};
|
|
32
37
|
} finally {
|
|
33
38
|
fs.closeSync(fd);
|
|
34
39
|
}
|
|
@@ -85,7 +90,10 @@ function agentLine(manifest: TeamRunManifest, agent: CrewAgentRecord): string {
|
|
|
85
90
|
return `- ${statusGlyph(agent.status)} ${agent.taskId} ${agent.role} → ${agent.agent} · ${agent.status} · ${agent.runtime} · ${activityText(agent)}${outputWarning(manifest, agent)}${agent.error ? ` · error=${agent.error}` : ""}`;
|
|
86
91
|
}
|
|
87
92
|
|
|
88
|
-
export function buildAgentDashboard(manifest: TeamRunManifest): {
|
|
93
|
+
export function buildAgentDashboard(manifest: TeamRunManifest): {
|
|
94
|
+
text: string;
|
|
95
|
+
groups: Record<string, CrewAgentRecord[]>;
|
|
96
|
+
} {
|
|
89
97
|
const agents = readCrewAgents(manifest);
|
|
90
98
|
const groups: Record<string, CrewAgentRecord[]> = {
|
|
91
99
|
running: agents.filter((agent) => agent.status === "running"),
|