pi-crew 0.9.16 → 0.9.18
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 +130 -0
- package/README.md +19 -0
- package/dist/build-meta.json +21784 -0
- package/dist/index.mjs +83169 -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/migration/atomic-write-v2-migration.md +297 -0
- package/docs/patterns/command-agent-skill.md +1 -1
- package/docs/perf/performance-review-2026-07.md +287 -0
- 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 +303 -591
- 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 +149 -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 +39 -24
- 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 +344 -79
- 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 +187 -59
- 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 +13 -31
- 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 +10 -18
- 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 +2 -6
- package/src/runtime/retry-executor.ts +20 -4
- package/src/runtime/retry-runner.ts +27 -51
- 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 +12 -19
- 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 +50 -14
- 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 +2 -7
- 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 +106 -27
- 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 +137 -47
- 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/terminal-status.ts +1 -3
- 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 +46 -29
- 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
|
@@ -1,18 +1,8 @@
|
|
|
1
1
|
import * as fs from "node:fs";
|
|
2
2
|
import * as path from "node:path";
|
|
3
3
|
import type { AgentConfig } from "../agents/agent-config.ts";
|
|
4
|
-
import {
|
|
5
|
-
|
|
6
|
-
discoverAgents,
|
|
7
|
-
listDynamicAgents,
|
|
8
|
-
registerDynamicAgent,
|
|
9
|
-
unregisterDynamicAgent,
|
|
10
|
-
} from "../agents/discover-agents.ts";
|
|
11
|
-
import {
|
|
12
|
-
loadConfig,
|
|
13
|
-
updateAutonomousConfig,
|
|
14
|
-
updateConfig,
|
|
15
|
-
} from "../config/config.ts";
|
|
4
|
+
import { allAgents, discoverAgents, listDynamicAgents, registerDynamicAgent, unregisterDynamicAgent } from "../agents/discover-agents.ts";
|
|
5
|
+
import { loadConfig, updateAutonomousConfig, updateConfig } from "../config/config.ts";
|
|
16
6
|
// Heavy runtime — lazy-loaded to avoid 1.4s import cost at extension registration.
|
|
17
7
|
// executeTeamRun is only called when a team run actually executes.
|
|
18
8
|
import type { executeTeamRun as _executeTeamRunFn } from "../runtime/team-runner.ts";
|
|
@@ -21,23 +11,11 @@ import { writeArtifact } from "../state/artifact-store.ts";
|
|
|
21
11
|
import { appendEvent, appendEventFireAndForget } from "../state/event-log.ts";
|
|
22
12
|
import { withRunLock } from "../state/locks.ts";
|
|
23
13
|
import { replayPendingMailboxMessages } from "../state/mailbox.ts";
|
|
24
|
-
import {
|
|
25
|
-
|
|
26
|
-
saveRunManifest,
|
|
27
|
-
saveRunTasks,
|
|
28
|
-
updateRunStatus,
|
|
29
|
-
} from "../state/state-store.ts";
|
|
30
|
-
import type {
|
|
31
|
-
ArtifactDescriptor,
|
|
32
|
-
TeamRunManifest,
|
|
33
|
-
TeamTaskState,
|
|
34
|
-
} from "../state/types.ts";
|
|
14
|
+
import { loadRunManifestById, saveRunManifest, saveRunTasks, updateRunStatus } from "../state/state-store.ts";
|
|
15
|
+
import type { ArtifactDescriptor, TeamRunManifest, TeamTaskState } from "../state/types.ts";
|
|
35
16
|
import { allTeams, discoverTeams } from "../teams/discover-teams.ts";
|
|
36
17
|
import { assertSafePathId } from "../utils/safe-paths.ts";
|
|
37
|
-
import {
|
|
38
|
-
allWorkflows,
|
|
39
|
-
discoverWorkflows,
|
|
40
|
-
} from "../workflows/discover-workflows.ts";
|
|
18
|
+
import { allWorkflows, discoverWorkflows } from "../workflows/discover-workflows.ts";
|
|
41
19
|
import { piTeamsHelp } from "./help.ts";
|
|
42
20
|
import { handleCreate, handleDelete, handleUpdate } from "./management.ts";
|
|
43
21
|
import { initializeProject } from "./project-init.ts";
|
|
@@ -45,16 +23,11 @@ import { listRuns } from "./run-index.ts";
|
|
|
45
23
|
import { formatRecommendation, recommendTeam } from "./team-recommendation.ts";
|
|
46
24
|
import { handleSettings } from "./team-tool/handle-settings.ts";
|
|
47
25
|
import type { PiTeamsToolResult } from "./tool-result.ts";
|
|
48
|
-
import {
|
|
49
|
-
formatValidationReport,
|
|
50
|
-
validateResources,
|
|
51
|
-
} from "./validate-resources.ts";
|
|
26
|
+
import { formatValidationReport, validateResources } from "./validate-resources.ts";
|
|
52
27
|
|
|
53
28
|
type ExecuteTeamRunFn = typeof _executeTeamRunFn;
|
|
54
29
|
let _cachedExecuteTeamRun: ExecuteTeamRunFn | undefined;
|
|
55
|
-
async function executeTeamRun(
|
|
56
|
-
...args: Parameters<ExecuteTeamRunFn>
|
|
57
|
-
): Promise<Awaited<ReturnType<ExecuteTeamRunFn>>> {
|
|
30
|
+
async function executeTeamRun(...args: Parameters<ExecuteTeamRunFn>): Promise<Awaited<ReturnType<ExecuteTeamRunFn>>> {
|
|
58
31
|
if (_cachedExecuteTeamRun === undefined) {
|
|
59
32
|
// LAZY: heavy runtime — defer 1.4s import cost until team run actually executes.
|
|
60
33
|
const mod = await import("../runtime/team-runner.ts");
|
|
@@ -65,33 +38,17 @@ async function executeTeamRun(
|
|
|
65
38
|
|
|
66
39
|
import { directTeamAndWorkflowFromRun } from "../runtime/direct-run.ts";
|
|
67
40
|
import { parsePiJsonOutput } from "../runtime/pi-json-output.ts";
|
|
68
|
-
import {
|
|
69
|
-
resolveCrewRuntime,
|
|
70
|
-
runtimeResolutionState,
|
|
71
|
-
} from "../runtime/runtime-resolver.ts";
|
|
41
|
+
import { resolveCrewRuntime, runtimeResolutionState } from "../runtime/runtime-resolver.ts";
|
|
72
42
|
import { handleApi } from "./team-tool/api.ts";
|
|
73
|
-
import {
|
|
74
|
-
|
|
75
|
-
configPatchFromConfig,
|
|
76
|
-
effectiveRunConfig,
|
|
77
|
-
formatAutonomyStatus,
|
|
78
|
-
} from "./team-tool/config-patch.ts";
|
|
79
|
-
import {
|
|
80
|
-
buildParentContext,
|
|
81
|
-
configRecord,
|
|
82
|
-
formatScoped,
|
|
83
|
-
result,
|
|
84
|
-
type TeamContext,
|
|
85
|
-
} from "./team-tool/context.ts";
|
|
43
|
+
import { autonomousPatchFromConfig, configPatchFromConfig, effectiveRunConfig, formatAutonomyStatus } from "./team-tool/config-patch.ts";
|
|
44
|
+
import { buildParentContext, configRecord, formatScoped, result, type TeamContext } from "./team-tool/context.ts";
|
|
86
45
|
// Lazy-loaded: run.ts pulls in spawnBackgroundTeamRun, resolveCrewRuntime, etc.
|
|
87
46
|
// Static import fails silently in some jiti contexts (child-process), leaving handleRun undefined.
|
|
88
47
|
import type { handleRun as _handleRunFn } from "./team-tool/run.ts";
|
|
89
48
|
|
|
90
49
|
type HandleRunFn = typeof _handleRunFn;
|
|
91
50
|
let _cachedHandleRun: HandleRunFn | undefined;
|
|
92
|
-
async function handleRun(
|
|
93
|
-
...args: Parameters<HandleRunFn>
|
|
94
|
-
): Promise<Awaited<ReturnType<HandleRunFn>>> {
|
|
51
|
+
async function handleRun(...args: Parameters<HandleRunFn>): Promise<Awaited<ReturnType<HandleRunFn>>> {
|
|
95
52
|
if (_cachedHandleRun === undefined) {
|
|
96
53
|
// LAZY: run.ts pulls in spawnBackgroundTeamRun + resolveCrewRuntime; also avoids jiti import race in child-process contexts.
|
|
97
54
|
const mod = await import("./team-tool/run.ts");
|
|
@@ -103,21 +60,13 @@ async function handleRun(
|
|
|
103
60
|
import { FileCheckpointStore } from "../runtime/checkpoint.ts";
|
|
104
61
|
import { waitForRun } from "../runtime/run-tracker.ts";
|
|
105
62
|
import { normalizeSkillOverride } from "../runtime/skill-instructions.ts";
|
|
106
|
-
import {
|
|
107
|
-
computeRunCacheKey,
|
|
108
|
-
getCachedRun,
|
|
109
|
-
getCacheStats,
|
|
110
|
-
} from "../state/run-cache.ts";
|
|
63
|
+
import { computeRunCacheKey, getCachedRun, getCacheStats } from "../state/run-cache.ts";
|
|
111
64
|
import { listRunGraphs, loadRunGraph } from "../state/run-graph.ts";
|
|
112
65
|
import { searchAgents, searchTeams } from "../utils/bm25-search.ts";
|
|
113
66
|
import { projectCrewRoot } from "../utils/paths.ts";
|
|
67
|
+
import { formatActionSuggestion } from "./action-suggestions.ts";
|
|
114
68
|
import { buildTeamOnboarding } from "./team-onboard.ts";
|
|
115
|
-
import {
|
|
116
|
-
handleAnchorAccumulate,
|
|
117
|
-
handleAnchorClear,
|
|
118
|
-
handleAnchorSet,
|
|
119
|
-
handleAnchorStatus,
|
|
120
|
-
} from "./team-tool/anchor.ts";
|
|
69
|
+
import { handleAnchorAccumulate, handleAnchorClear, handleAnchorSet, handleAnchorStatus } from "./team-tool/anchor.ts";
|
|
121
70
|
import {
|
|
122
71
|
createAutoSummarizeService,
|
|
123
72
|
handleAutoSummarizeConfig,
|
|
@@ -125,31 +74,14 @@ import {
|
|
|
125
74
|
handleAutoSummarizeOn,
|
|
126
75
|
handleAutoSummarizeStatus,
|
|
127
76
|
} from "./team-tool/auto-summarize.ts";
|
|
128
|
-
import {
|
|
129
|
-
import {
|
|
130
|
-
handleWorkflowCreate,
|
|
131
|
-
handleWorkflowGet,
|
|
132
|
-
handleWorkflowList,
|
|
133
|
-
handleWorkflowSave,
|
|
134
|
-
handleWorkflowDelete,
|
|
135
|
-
} from "./team-tool/workflow-manage.ts";
|
|
136
|
-
import {
|
|
137
|
-
type CacheControlDeps,
|
|
138
|
-
invalidateSnapshot,
|
|
139
|
-
} from "./team-tool/cache-control.ts";
|
|
77
|
+
import { type CacheControlDeps, invalidateSnapshot } from "./team-tool/cache-control.ts";
|
|
140
78
|
import { handleCancel, handleRetry } from "./team-tool/cancel.ts";
|
|
141
79
|
import { handleDoctor } from "./team-tool/doctor.ts";
|
|
142
80
|
import { handleExplain } from "./team-tool/explain.ts";
|
|
143
|
-
import {
|
|
144
|
-
|
|
145
|
-
handleSchedule,
|
|
146
|
-
} from "./team-tool/handle-schedule.ts";
|
|
81
|
+
import { handleGoal } from "./team-tool/goal.ts";
|
|
82
|
+
import { handleListScheduled, handleSchedule } from "./team-tool/handle-schedule.ts";
|
|
147
83
|
import { handleHealthMonitor } from "./team-tool/health-monitor.ts";
|
|
148
|
-
import {
|
|
149
|
-
handleArtifacts,
|
|
150
|
-
handleEvents,
|
|
151
|
-
handleSummary,
|
|
152
|
-
} from "./team-tool/inspect.ts";
|
|
84
|
+
import { handleArtifacts, handleEvents, handleSummary } from "./team-tool/inspect.ts";
|
|
153
85
|
import {
|
|
154
86
|
handleCleanup,
|
|
155
87
|
handleExport,
|
|
@@ -163,9 +95,15 @@ import { handleOrchestrate } from "./team-tool/orchestrate.ts";
|
|
|
163
95
|
import { handleParallel } from "./team-tool/parallel-dispatch.ts";
|
|
164
96
|
import { handlePlan } from "./team-tool/plan.ts";
|
|
165
97
|
import { handleRespond } from "./team-tool/respond.ts";
|
|
166
|
-
import { handleStatus } from "./team-tool/status.ts";
|
|
167
98
|
import { RUN_NOT_FOUND_HINT } from "./team-tool/run-not-found.ts";
|
|
168
|
-
import {
|
|
99
|
+
import { handleStatus } from "./team-tool/status.ts";
|
|
100
|
+
import {
|
|
101
|
+
handleWorkflowCreate,
|
|
102
|
+
handleWorkflowDelete,
|
|
103
|
+
handleWorkflowGet,
|
|
104
|
+
handleWorkflowList,
|
|
105
|
+
handleWorkflowSave,
|
|
106
|
+
} from "./team-tool/workflow-manage.ts";
|
|
169
107
|
|
|
170
108
|
export { handleApi } from "./team-tool/api.ts";
|
|
171
109
|
export { handleRetry } from "./team-tool/cancel.ts";
|
|
@@ -192,21 +130,14 @@ export { handleStatus } from "./team-tool/status.ts";
|
|
|
192
130
|
export type { TeamToolDetails } from "./team-tool-types.ts";
|
|
193
131
|
export { handleRun };
|
|
194
132
|
|
|
195
|
-
export function handleList(
|
|
196
|
-
params: TeamToolParamsValue,
|
|
197
|
-
ctx: TeamContext,
|
|
198
|
-
): PiTeamsToolResult {
|
|
133
|
+
export function handleList(params: TeamToolParamsValue, ctx: TeamContext): PiTeamsToolResult {
|
|
199
134
|
const resource = params.resource;
|
|
200
135
|
const blocks: string[] = [];
|
|
201
136
|
if (!resource || resource === "team") {
|
|
202
137
|
const teams = allTeams(discoverTeams(ctx.cwd));
|
|
203
138
|
blocks.push(
|
|
204
139
|
"Teams:",
|
|
205
|
-
...(teams.length
|
|
206
|
-
? teams.map((team) =>
|
|
207
|
-
formatScoped(team.name, team.source, team.description),
|
|
208
|
-
)
|
|
209
|
-
: ["- (none)"]),
|
|
140
|
+
...(teams.length ? teams.map((team) => formatScoped(team.name, team.source, team.description)) : ["- (none)"]),
|
|
210
141
|
);
|
|
211
142
|
}
|
|
212
143
|
if (!resource || resource === "workflow") {
|
|
@@ -215,13 +146,7 @@ export function handleList(
|
|
|
215
146
|
"",
|
|
216
147
|
"Workflows:",
|
|
217
148
|
...(workflows.length
|
|
218
|
-
? workflows.map((workflow) =>
|
|
219
|
-
formatScoped(
|
|
220
|
-
workflow.name,
|
|
221
|
-
workflow.source,
|
|
222
|
-
workflow.description,
|
|
223
|
-
),
|
|
224
|
-
)
|
|
149
|
+
? workflows.map((workflow) => formatScoped(workflow.name, workflow.source, workflow.description))
|
|
225
150
|
: ["- (none)"]),
|
|
226
151
|
);
|
|
227
152
|
}
|
|
@@ -230,15 +155,7 @@ export function handleList(
|
|
|
230
155
|
blocks.push(
|
|
231
156
|
"",
|
|
232
157
|
"Agents:",
|
|
233
|
-
...(agents.length
|
|
234
|
-
? agents.map((agent) =>
|
|
235
|
-
formatScoped(
|
|
236
|
-
agent.name,
|
|
237
|
-
agent.source,
|
|
238
|
-
agent.description,
|
|
239
|
-
),
|
|
240
|
-
)
|
|
241
|
-
: ["- (none)"]),
|
|
158
|
+
...(agents.length ? agents.map((agent) => formatScoped(agent.name, agent.source, agent.description)) : ["- (none)"]),
|
|
242
159
|
);
|
|
243
160
|
}
|
|
244
161
|
if (!resource) {
|
|
@@ -247,30 +164,17 @@ export function handleList(
|
|
|
247
164
|
"",
|
|
248
165
|
"Recent runs:",
|
|
249
166
|
...(runs.length
|
|
250
|
-
? runs.map(
|
|
251
|
-
(run) =>
|
|
252
|
-
`- ${run.runId} [${run.status}] ${run.team}/${run.workflow ?? "none"}: ${run.goal}`,
|
|
253
|
-
)
|
|
167
|
+
? runs.map((run) => `- ${run.runId} [${run.status}] ${run.team}/${run.workflow ?? "none"}: ${run.goal}`)
|
|
254
168
|
: ["- (none)"]),
|
|
255
169
|
);
|
|
256
170
|
}
|
|
257
171
|
return result(blocks.join("\n"), { action: "list", status: "ok" });
|
|
258
172
|
}
|
|
259
173
|
|
|
260
|
-
export function handleGet(
|
|
261
|
-
params: TeamToolParamsValue,
|
|
262
|
-
ctx: TeamContext,
|
|
263
|
-
): PiTeamsToolResult {
|
|
174
|
+
export function handleGet(params: TeamToolParamsValue, ctx: TeamContext): PiTeamsToolResult {
|
|
264
175
|
if (params.team) {
|
|
265
|
-
const team = allTeams(discoverTeams(ctx.cwd)).find(
|
|
266
|
-
|
|
267
|
-
);
|
|
268
|
-
if (!team)
|
|
269
|
-
return result(
|
|
270
|
-
`Team '${params.team}' not found.`,
|
|
271
|
-
{ action: "get", status: "error" },
|
|
272
|
-
true,
|
|
273
|
-
);
|
|
176
|
+
const team = allTeams(discoverTeams(ctx.cwd)).find((item) => item.name === params.team);
|
|
177
|
+
if (!team) return result(`Team '${params.team}' not found.`, { action: "get", status: "error" }, true);
|
|
274
178
|
const lines = [
|
|
275
179
|
`Team: ${team.name} (${team.source})`,
|
|
276
180
|
`Path: ${team.filePath}`,
|
|
@@ -279,66 +183,40 @@ export function handleGet(
|
|
|
279
183
|
`Workspace mode: ${team.workspaceMode ?? "single"}`,
|
|
280
184
|
"Roles:",
|
|
281
185
|
...(team.roles.length
|
|
282
|
-
? team.roles.map(
|
|
283
|
-
(role) =>
|
|
284
|
-
`- ${role.name} -> ${role.agent}${role.description ? `: ${role.description}` : ""}`,
|
|
285
|
-
)
|
|
186
|
+
? team.roles.map((role) => `- ${role.name} -> ${role.agent}${role.description ? `: ${role.description}` : ""}`)
|
|
286
187
|
: ["- (none)"]),
|
|
287
188
|
];
|
|
288
189
|
return result(lines.join("\n"), { action: "get", status: "ok" });
|
|
289
190
|
}
|
|
290
191
|
if (params.workflow) {
|
|
291
|
-
const workflow = allWorkflows(discoverWorkflows(ctx.cwd)).find(
|
|
292
|
-
|
|
293
|
-
);
|
|
294
|
-
if (!workflow)
|
|
295
|
-
return result(
|
|
296
|
-
`Workflow '${params.workflow}' not found.`,
|
|
297
|
-
{ action: "get", status: "error" },
|
|
298
|
-
true,
|
|
299
|
-
);
|
|
192
|
+
const workflow = allWorkflows(discoverWorkflows(ctx.cwd)).find((item) => item.name === params.workflow);
|
|
193
|
+
if (!workflow) return result(`Workflow '${params.workflow}' not found.`, { action: "get", status: "error" }, true);
|
|
300
194
|
const lines = [
|
|
301
195
|
`Workflow: ${workflow.name} (${workflow.source})`,
|
|
302
196
|
`Path: ${workflow.filePath}`,
|
|
303
197
|
`Description: ${workflow.description}`,
|
|
304
198
|
"Steps:",
|
|
305
199
|
...(workflow.steps.length
|
|
306
|
-
? workflow.steps.map(
|
|
307
|
-
(step) =>
|
|
308
|
-
`- ${step.id} [${step.role}] dependsOn=${step.dependsOn?.join(",") ?? "none"}`,
|
|
309
|
-
)
|
|
200
|
+
? workflow.steps.map((step) => `- ${step.id} [${step.role}] dependsOn=${step.dependsOn?.join(",") ?? "none"}`)
|
|
310
201
|
: ["- (none)"]),
|
|
311
202
|
];
|
|
312
203
|
return result(lines.join("\n"), { action: "get", status: "ok" });
|
|
313
204
|
}
|
|
314
205
|
if (params.agent) {
|
|
315
|
-
const agent = allAgents(discoverAgents(ctx.cwd)).find(
|
|
316
|
-
|
|
317
|
-
);
|
|
318
|
-
if (!agent)
|
|
319
|
-
return result(
|
|
320
|
-
`Agent '${params.agent}' not found.`,
|
|
321
|
-
{ action: "get", status: "error" },
|
|
322
|
-
true,
|
|
323
|
-
);
|
|
206
|
+
const agent = allAgents(discoverAgents(ctx.cwd)).find((item) => item.name === params.agent);
|
|
207
|
+
if (!agent) return result(`Agent '${params.agent}' not found.`, { action: "get", status: "error" }, true);
|
|
324
208
|
const lines = [
|
|
325
209
|
`Agent: ${agent.name} (${agent.source})`,
|
|
326
210
|
`Path: ${agent.filePath}`,
|
|
327
211
|
`Description: ${agent.description}`,
|
|
328
212
|
agent.model ? `Model: ${agent.model}` : undefined,
|
|
329
|
-
agent.skills?.length
|
|
330
|
-
? `Skills: ${agent.skills.join(", ")}`
|
|
331
|
-
: undefined,
|
|
213
|
+
agent.skills?.length ? `Skills: ${agent.skills.join(", ")}` : undefined,
|
|
332
214
|
"",
|
|
333
215
|
agent.systemPrompt || "(empty system prompt)",
|
|
334
216
|
].filter((line): line is string => line !== undefined);
|
|
335
217
|
return result(lines.join("\n"), { action: "get", status: "ok" });
|
|
336
218
|
}
|
|
337
|
-
return result(
|
|
338
|
-
"Specify team, workflow, or agent for get.",
|
|
339
|
-
{ action: "get", status: "error" },
|
|
340
|
-
true,
|
|
341
|
-
);
|
|
219
|
+
return result("Specify team, workflow, or agent for get.", { action: "get", status: "error" }, true);
|
|
342
220
|
}
|
|
343
221
|
|
|
344
222
|
function artifactKey(artifact: ArtifactDescriptor): string {
|
|
@@ -353,10 +231,7 @@ function recoverCheckpointedTasks(
|
|
|
353
231
|
let nextManifest = manifest;
|
|
354
232
|
const nextTasks = tasks.map((task) => {
|
|
355
233
|
if (task.status !== "running" || !task.checkpoint) return task;
|
|
356
|
-
if (
|
|
357
|
-
task.checkpoint.phase === "artifact-written" &&
|
|
358
|
-
task.resultArtifact
|
|
359
|
-
) {
|
|
234
|
+
if (task.checkpoint.phase === "artifact-written" && task.resultArtifact) {
|
|
360
235
|
recovered.push(task.id);
|
|
361
236
|
return {
|
|
362
237
|
...task,
|
|
@@ -368,28 +243,15 @@ function recoverCheckpointedTasks(
|
|
|
368
243
|
}
|
|
369
244
|
if (task.checkpoint.phase === "child-stdout-final") {
|
|
370
245
|
// transcripts are written with .attempt-${i}.jsonl suffix; find the most recent one
|
|
371
|
-
const transcriptsDir = path.join(
|
|
372
|
-
manifest.artifactsRoot,
|
|
373
|
-
"transcripts",
|
|
374
|
-
);
|
|
246
|
+
const transcriptsDir = path.join(manifest.artifactsRoot, "transcripts");
|
|
375
247
|
let transcriptPath: string | undefined;
|
|
376
248
|
if (fs.existsSync(transcriptsDir)) {
|
|
377
|
-
const files = fs
|
|
378
|
-
.readdirSync(transcriptsDir)
|
|
379
|
-
.filter(
|
|
380
|
-
(f) =>
|
|
381
|
-
f.startsWith(`${task.id}.attempt-`) &&
|
|
382
|
-
f.endsWith(".jsonl"),
|
|
383
|
-
);
|
|
249
|
+
const files = fs.readdirSync(transcriptsDir).filter((f) => f.startsWith(`${task.id}.attempt-`) && f.endsWith(".jsonl"));
|
|
384
250
|
if (files.length > 0) {
|
|
385
251
|
// Sort by attempt index descending to get the most recent
|
|
386
252
|
files.sort((a, b) => {
|
|
387
|
-
const idxA = parseInt(
|
|
388
|
-
|
|
389
|
-
);
|
|
390
|
-
const idxB = parseInt(
|
|
391
|
-
b.match(/\.attempt-(\d+)\./)?.[1] ?? "0",
|
|
392
|
-
);
|
|
253
|
+
const idxA = parseInt(a.match(/\.attempt-(\d+)\./)?.[1] ?? "0");
|
|
254
|
+
const idxB = parseInt(b.match(/\.attempt-(\d+)\./)?.[1] ?? "0");
|
|
393
255
|
return idxB - idxA;
|
|
394
256
|
});
|
|
395
257
|
transcriptPath = path.join(transcriptsDir, files[0]);
|
|
@@ -402,9 +264,7 @@ function recoverCheckpointedTasks(
|
|
|
402
264
|
const resultArtifact = writeArtifact(manifest.artifactsRoot, {
|
|
403
265
|
kind: "result",
|
|
404
266
|
relativePath: `results/${task.id}.txt`,
|
|
405
|
-
content:
|
|
406
|
-
parsed.finalText ??
|
|
407
|
-
"(recovered from completed child transcript)",
|
|
267
|
+
content: parsed.finalText ?? "(recovered from completed child transcript)",
|
|
408
268
|
producer: task.id,
|
|
409
269
|
});
|
|
410
270
|
const transcriptArtifact = writeArtifact(manifest.artifactsRoot, {
|
|
@@ -429,20 +289,12 @@ function recoverCheckpointedTasks(
|
|
|
429
289
|
return task;
|
|
430
290
|
});
|
|
431
291
|
if (recovered.length) {
|
|
432
|
-
const artifacts = new Map(
|
|
433
|
-
nextManifest.artifacts.map((artifact) => [
|
|
434
|
-
artifactKey(artifact),
|
|
435
|
-
artifact,
|
|
436
|
-
]),
|
|
437
|
-
);
|
|
292
|
+
const artifacts = new Map(nextManifest.artifacts.map((artifact) => [artifactKey(artifact), artifact]));
|
|
438
293
|
for (const task of nextTasks) {
|
|
439
294
|
if (!recovered.includes(task.id)) continue;
|
|
440
|
-
for (const artifact of [
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
task.logArtifact,
|
|
444
|
-
task.transcriptArtifact,
|
|
445
|
-
].filter(Boolean) as ArtifactDescriptor[])
|
|
295
|
+
for (const artifact of [task.promptArtifact, task.resultArtifact, task.logArtifact, task.transcriptArtifact].filter(
|
|
296
|
+
Boolean,
|
|
297
|
+
) as ArtifactDescriptor[])
|
|
446
298
|
artifacts.set(artifactKey(artifact), artifact);
|
|
447
299
|
}
|
|
448
300
|
nextManifest = {
|
|
@@ -456,70 +308,24 @@ function recoverCheckpointedTasks(
|
|
|
456
308
|
return { manifest: nextManifest, tasks: nextTasks, recovered };
|
|
457
309
|
}
|
|
458
310
|
|
|
459
|
-
export async function handleResume(
|
|
460
|
-
params:
|
|
461
|
-
ctx: TeamContext,
|
|
462
|
-
): Promise<PiTeamsToolResult> {
|
|
463
|
-
if (!params.runId)
|
|
464
|
-
return result(
|
|
465
|
-
"Resume requires runId.",
|
|
466
|
-
{ action: "resume", status: "error" },
|
|
467
|
-
true,
|
|
468
|
-
);
|
|
311
|
+
export async function handleResume(params: TeamToolParamsValue, ctx: TeamContext): Promise<PiTeamsToolResult> {
|
|
312
|
+
if (!params.runId) return result("Resume requires runId.", { action: "resume", status: "error" }, true);
|
|
469
313
|
const runCwd = locateRunCwd(params.runId, ctx.cwd);
|
|
470
|
-
if (!runCwd)
|
|
471
|
-
return result(
|
|
472
|
-
`Run '${params.runId}' not found.${RUN_NOT_FOUND_HINT}`,
|
|
473
|
-
{ action: "resume", status: "error" },
|
|
474
|
-
true,
|
|
475
|
-
);
|
|
314
|
+
if (!runCwd) return result(`Run '${params.runId}' not found.${RUN_NOT_FOUND_HINT}`, { action: "resume", status: "error" }, true);
|
|
476
315
|
const loaded = loadRunManifestById(runCwd, params.runId); // NOTE: no withRunLock - best-effort only; concurrent writes may cause inconsistency
|
|
477
|
-
if (!loaded)
|
|
478
|
-
return result(
|
|
479
|
-
`Run '${params.runId}' not found.${RUN_NOT_FOUND_HINT}`,
|
|
480
|
-
{ action: "resume", status: "error" },
|
|
481
|
-
true,
|
|
482
|
-
);
|
|
316
|
+
if (!loaded) return result(`Run '${params.runId}' not found.${RUN_NOT_FOUND_HINT}`, { action: "resume", status: "error" }, true);
|
|
483
317
|
if (!loaded.manifest.workflow)
|
|
484
|
-
return result(
|
|
485
|
-
`Run '${params.runId}' has no workflow to resume.`,
|
|
486
|
-
{ action: "resume", status: "error" },
|
|
487
|
-
true,
|
|
488
|
-
);
|
|
318
|
+
return result(`Run '${params.runId}' has no workflow to resume.`, { action: "resume", status: "error" }, true);
|
|
489
319
|
const agents = allAgents(discoverAgents(ctx.cwd));
|
|
490
|
-
const direct = directTeamAndWorkflowFromRun(
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
agents,
|
|
494
|
-
);
|
|
495
|
-
const team =
|
|
496
|
-
direct?.team ??
|
|
497
|
-
allTeams(discoverTeams(ctx.cwd)).find(
|
|
498
|
-
(candidate) => candidate.name === loaded.manifest.team,
|
|
499
|
-
);
|
|
500
|
-
if (!team)
|
|
501
|
-
return result(
|
|
502
|
-
`Team '${loaded.manifest.team}' not found.`,
|
|
503
|
-
{ action: "resume", status: "error" },
|
|
504
|
-
true,
|
|
505
|
-
);
|
|
320
|
+
const direct = directTeamAndWorkflowFromRun(loaded.manifest, loaded.tasks, agents);
|
|
321
|
+
const team = direct?.team ?? allTeams(discoverTeams(ctx.cwd)).find((candidate) => candidate.name === loaded.manifest.team);
|
|
322
|
+
if (!team) return result(`Team '${loaded.manifest.team}' not found.`, { action: "resume", status: "error" }, true);
|
|
506
323
|
const workflow =
|
|
507
|
-
direct?.workflow ??
|
|
508
|
-
|
|
509
|
-
(candidate) => candidate.name === loaded.manifest.workflow,
|
|
510
|
-
);
|
|
511
|
-
if (!workflow)
|
|
512
|
-
return result(
|
|
513
|
-
`Workflow '${loaded.manifest.workflow}' not found.`,
|
|
514
|
-
{ action: "resume", status: "error" },
|
|
515
|
-
true,
|
|
516
|
-
);
|
|
324
|
+
direct?.workflow ?? allWorkflows(discoverWorkflows(ctx.cwd)).find((candidate) => candidate.name === loaded.manifest.workflow);
|
|
325
|
+
if (!workflow) return result(`Workflow '${loaded.manifest.workflow}' not found.`, { action: "resume", status: "error" }, true);
|
|
517
326
|
return await withRunLock(loaded.manifest, async () => {
|
|
518
327
|
const loadedConfig = loadConfig(ctx.cwd);
|
|
519
|
-
const recovered = recoverCheckpointedTasks(
|
|
520
|
-
loaded.manifest,
|
|
521
|
-
loaded.tasks,
|
|
522
|
-
);
|
|
328
|
+
const recovered = recoverCheckpointedTasks(loaded.manifest, loaded.tasks);
|
|
523
329
|
const resumeManifest = recovered.manifest;
|
|
524
330
|
const executedConfig = {
|
|
525
331
|
...effectiveRunConfig(loadedConfig.config, params.config),
|
|
@@ -527,10 +333,7 @@ export async function handleResume(
|
|
|
527
333
|
// Preserve original manifest scaffold mode when resume has no explicit mode override
|
|
528
334
|
// AND workers are not explicitly disabled. If workers are disabled, let
|
|
529
335
|
// resolveCrewRuntime detect it and return blocked safety.
|
|
530
|
-
if (
|
|
531
|
-
!executedConfig.runtime?.mode &&
|
|
532
|
-
resumeManifest.runtimeResolution?.safety === "explicit_dry_run"
|
|
533
|
-
) {
|
|
336
|
+
if (!executedConfig.runtime?.mode && resumeManifest.runtimeResolution?.safety === "explicit_dry_run") {
|
|
534
337
|
const workersDisabled =
|
|
535
338
|
executedConfig.executeWorkers === false ||
|
|
536
339
|
process.env.PI_CREW_EXECUTE_WORKERS === "0" ||
|
|
@@ -556,16 +359,11 @@ export async function handleResume(
|
|
|
556
359
|
data: { runtimeResolution, action: "resume" },
|
|
557
360
|
});
|
|
558
361
|
if (runtime.safety === "blocked") {
|
|
559
|
-
const runningManifest = updateRunStatus(
|
|
560
|
-
runtimeManifest,
|
|
561
|
-
"running",
|
|
562
|
-
"Checking worker runtime availability before resume.",
|
|
563
|
-
);
|
|
362
|
+
const runningManifest = updateRunStatus(runtimeManifest, "running", "Checking worker runtime availability before resume.");
|
|
564
363
|
const blocked = updateRunStatus(
|
|
565
364
|
runningManifest,
|
|
566
365
|
"blocked",
|
|
567
|
-
runtime.reason ??
|
|
568
|
-
"Child worker execution is disabled; refusing to resume with no-op scaffold subagents.",
|
|
366
|
+
runtime.reason ?? "Child worker execution is disabled; refusing to resume with no-op scaffold subagents.",
|
|
569
367
|
);
|
|
570
368
|
appendEvent(blocked.eventsPath, {
|
|
571
369
|
type: "run.blocked",
|
|
@@ -592,10 +390,7 @@ export async function handleResume(
|
|
|
592
390
|
);
|
|
593
391
|
}
|
|
594
392
|
const resetTasks = recovered.tasks.map((task) =>
|
|
595
|
-
task.status === "failed" ||
|
|
596
|
-
task.status === "cancelled" ||
|
|
597
|
-
task.status === "skipped" ||
|
|
598
|
-
task.status === "running"
|
|
393
|
+
task.status === "failed" || task.status === "cancelled" || task.status === "skipped" || task.status === "running"
|
|
599
394
|
? {
|
|
600
395
|
...task,
|
|
601
396
|
status: "queued" as const,
|
|
@@ -630,15 +425,11 @@ export async function handleResume(
|
|
|
630
425
|
message: `Replayed ${replay.messages.length} pending inbox message(s).`,
|
|
631
426
|
data: {
|
|
632
427
|
messageIds: replay.messages.map((message) => message.id),
|
|
633
|
-
taskIds: replay.messages
|
|
634
|
-
.map((message) => message.taskId)
|
|
635
|
-
.filter(Boolean),
|
|
428
|
+
taskIds: replay.messages.map((message) => message.taskId).filter(Boolean),
|
|
636
429
|
},
|
|
637
430
|
});
|
|
638
431
|
const executeWorkers = runtime.kind !== "scaffold";
|
|
639
|
-
const resumeSkillOverride =
|
|
640
|
-
normalizeSkillOverride(params.skill) ??
|
|
641
|
-
runtimeManifest.skillOverride;
|
|
432
|
+
const resumeSkillOverride = normalizeSkillOverride(params.skill) ?? runtimeManifest.skillOverride;
|
|
642
433
|
const executed = await executeTeamRun({
|
|
643
434
|
manifest: runtimeManifest,
|
|
644
435
|
tasks: resetTasks,
|
|
@@ -677,39 +468,17 @@ export async function handleResume(
|
|
|
677
468
|
});
|
|
678
469
|
}
|
|
679
470
|
|
|
680
|
-
export function handleSteer(
|
|
681
|
-
params: TeamToolParamsValue,
|
|
682
|
-
ctx: TeamContext,
|
|
683
|
-
): PiTeamsToolResult {
|
|
471
|
+
export function handleSteer(params: TeamToolParamsValue, ctx: TeamContext): PiTeamsToolResult {
|
|
684
472
|
const { runId, taskId, message } = params;
|
|
685
473
|
if (!runId || !taskId || !message) {
|
|
686
|
-
return result(
|
|
687
|
-
"steer requires runId, taskId, and message",
|
|
688
|
-
{ action: "steer", status: "error" },
|
|
689
|
-
true,
|
|
690
|
-
);
|
|
474
|
+
return result("steer requires runId, taskId, and message", { action: "steer", status: "error" }, true);
|
|
691
475
|
}
|
|
692
476
|
const runCwd = locateRunCwd(runId, ctx.cwd);
|
|
693
|
-
if (!runCwd)
|
|
694
|
-
return result(
|
|
695
|
-
`Run '${runId}' not found`,
|
|
696
|
-
{ action: "steer", status: "error" },
|
|
697
|
-
true,
|
|
698
|
-
);
|
|
477
|
+
if (!runCwd) return result(`Run '${runId}' not found`, { action: "steer", status: "error" }, true);
|
|
699
478
|
const loaded = loadRunManifestById(runCwd, runId); // NOTE: no withRunLock - best-effort only; concurrent writes may cause inconsistency
|
|
700
|
-
if (!loaded)
|
|
701
|
-
return result(
|
|
702
|
-
`Run '${runId}' not found`,
|
|
703
|
-
{ action: "steer", status: "error" },
|
|
704
|
-
true,
|
|
705
|
-
);
|
|
479
|
+
if (!loaded) return result(`Run '${runId}' not found`, { action: "steer", status: "error" }, true);
|
|
706
480
|
const task = loaded.tasks.find((t) => t.id === taskId);
|
|
707
|
-
if (!task)
|
|
708
|
-
return result(
|
|
709
|
-
`Task '${taskId}' not found`,
|
|
710
|
-
{ action: "steer", status: "error" },
|
|
711
|
-
true,
|
|
712
|
-
);
|
|
481
|
+
if (!task) return result(`Task '${taskId}' not found`, { action: "steer", status: "error" }, true);
|
|
713
482
|
if (!task.pendingSteers) task.pendingSteers = [];
|
|
714
483
|
// HIGH-04: Cap pendingSteers array to prevent unbounded memory growth
|
|
715
484
|
const MAX_PENDING_STEERS = 100;
|
|
@@ -735,44 +504,24 @@ export function handleSteer(
|
|
|
735
504
|
taskId,
|
|
736
505
|
data: { message },
|
|
737
506
|
});
|
|
738
|
-
return result(
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
);
|
|
507
|
+
return result(`Steer queued for task '${taskId}'. It will be delivered when the task's session is ready.`, {
|
|
508
|
+
action: "steer",
|
|
509
|
+
status: "ok",
|
|
510
|
+
});
|
|
742
511
|
}
|
|
743
512
|
|
|
744
|
-
function cacheControlDepsFromContext(
|
|
745
|
-
ctx: TeamContext,
|
|
746
|
-
): CacheControlDeps | undefined {
|
|
513
|
+
function cacheControlDepsFromContext(ctx: TeamContext): CacheControlDeps | undefined {
|
|
747
514
|
if (!ctx.getRunSnapshotCache) return undefined;
|
|
748
515
|
return { getRunSnapshotCache: ctx.getRunSnapshotCache };
|
|
749
516
|
}
|
|
750
517
|
|
|
751
|
-
function handleInvalidate(
|
|
752
|
-
params: TeamToolParamsValue,
|
|
753
|
-
ctx: TeamContext,
|
|
754
|
-
): PiTeamsToolResult {
|
|
518
|
+
function handleInvalidate(params: TeamToolParamsValue, ctx: TeamContext): PiTeamsToolResult {
|
|
755
519
|
const runId = params.runId;
|
|
756
|
-
if (!runId)
|
|
757
|
-
return result(
|
|
758
|
-
"Invalidate requires runId.",
|
|
759
|
-
{ action: "invalidate", status: "error" },
|
|
760
|
-
true,
|
|
761
|
-
);
|
|
520
|
+
if (!runId) return result("Invalidate requires runId.", { action: "invalidate", status: "error" }, true);
|
|
762
521
|
const runCwd = locateRunCwd(runId, ctx.cwd);
|
|
763
|
-
if (!runCwd)
|
|
764
|
-
return result(
|
|
765
|
-
`Run '${runId}' not found.`,
|
|
766
|
-
{ action: "invalidate", status: "error" },
|
|
767
|
-
true,
|
|
768
|
-
);
|
|
522
|
+
if (!runCwd) return result(`Run '${runId}' not found.`, { action: "invalidate", status: "error" }, true);
|
|
769
523
|
const deps = cacheControlDepsFromContext(ctx);
|
|
770
|
-
if (!deps)
|
|
771
|
-
return result(
|
|
772
|
-
"Cache invalidation not available (no snapshot cache).",
|
|
773
|
-
{ action: "invalidate", status: "error" },
|
|
774
|
-
true,
|
|
775
|
-
);
|
|
524
|
+
if (!deps) return result("Cache invalidation not available (no snapshot cache).", { action: "invalidate", status: "error" }, true);
|
|
776
525
|
invalidateSnapshot(runId, runCwd, deps);
|
|
777
526
|
return result(`Cache invalidated for run ${runId}.`, {
|
|
778
527
|
action: "invalidate",
|
|
@@ -792,23 +541,9 @@ function handleInvalidate(
|
|
|
792
541
|
* (e.g. .crew, .pi, .tmp-crew-runs)
|
|
793
542
|
*/
|
|
794
543
|
const MAX_SCAN_ENTRIES = 1000;
|
|
795
|
-
const SKIP_SCAN_DIRS = new Set([
|
|
796
|
-
"node_modules",
|
|
797
|
-
".git",
|
|
798
|
-
".npm",
|
|
799
|
-
".cache",
|
|
800
|
-
".local",
|
|
801
|
-
"proc",
|
|
802
|
-
"sys",
|
|
803
|
-
"dev",
|
|
804
|
-
"Library",
|
|
805
|
-
"Applications",
|
|
806
|
-
]);
|
|
544
|
+
const SKIP_SCAN_DIRS = new Set(["node_modules", ".git", ".npm", ".cache", ".local", "proc", "sys", "dev", "Library", "Applications"]);
|
|
807
545
|
|
|
808
|
-
export function locateRunCwd(
|
|
809
|
-
runId: string,
|
|
810
|
-
baseCwd: string,
|
|
811
|
-
): string | undefined {
|
|
546
|
+
export function locateRunCwd(runId: string, baseCwd: string): string | undefined {
|
|
812
547
|
// Fast path: run is in the current CWD
|
|
813
548
|
if (loadRunManifestById(baseCwd, runId)) {
|
|
814
549
|
return baseCwd;
|
|
@@ -817,19 +552,13 @@ export function locateRunCwd(
|
|
|
817
552
|
// Scan immediate child directories, but with defensive bounds.
|
|
818
553
|
try {
|
|
819
554
|
const entries = fs.readdirSync(baseCwd, { withFileTypes: true });
|
|
820
|
-
const boundedEntries = entries.length > MAX_SCAN_ENTRIES
|
|
821
|
-
? entries.slice(0, MAX_SCAN_ENTRIES)
|
|
822
|
-
: entries;
|
|
555
|
+
const boundedEntries = entries.length > MAX_SCAN_ENTRIES ? entries.slice(0, MAX_SCAN_ENTRIES) : entries;
|
|
823
556
|
for (const entry of boundedEntries) {
|
|
824
557
|
if (!entry.isDirectory()) continue;
|
|
825
558
|
if (SKIP_SCAN_DIRS.has(entry.name)) continue;
|
|
826
559
|
// Skip hidden entries except well-known run-storage prefixes
|
|
827
560
|
if (entry.name.startsWith(".")) {
|
|
828
|
-
if (
|
|
829
|
-
!entry.name.startsWith(".crew") &&
|
|
830
|
-
!entry.name.startsWith(".pi") &&
|
|
831
|
-
!entry.name.startsWith(".tmp-crew")
|
|
832
|
-
) continue;
|
|
561
|
+
if (!entry.name.startsWith(".crew") && !entry.name.startsWith(".pi") && !entry.name.startsWith(".tmp-crew")) continue;
|
|
833
562
|
}
|
|
834
563
|
const candidate = path.join(baseCwd, entry.name);
|
|
835
564
|
if (loadRunManifestById(candidate, runId)) {
|
|
@@ -843,32 +572,20 @@ export function locateRunCwd(
|
|
|
843
572
|
return undefined;
|
|
844
573
|
}
|
|
845
574
|
|
|
846
|
-
async function handleWait(
|
|
847
|
-
params: TeamToolParamsValue,
|
|
848
|
-
ctx: TeamContext,
|
|
849
|
-
): Promise<PiTeamsToolResult> {
|
|
575
|
+
async function handleWait(params: TeamToolParamsValue, ctx: TeamContext): Promise<PiTeamsToolResult> {
|
|
850
576
|
const { runId } = params;
|
|
851
|
-
if (!runId)
|
|
852
|
-
return result(
|
|
853
|
-
"wait requires runId.",
|
|
854
|
-
{ action: "wait", status: "error" },
|
|
855
|
-
true,
|
|
856
|
-
);
|
|
577
|
+
if (!runId) return result("wait requires runId.", { action: "wait", status: "error" }, true);
|
|
857
578
|
|
|
858
579
|
const timeoutMs = Math.min(
|
|
859
580
|
Math.max(
|
|
860
|
-
typeof params.config?.timeoutMs === "number" &&
|
|
861
|
-
Number.isFinite(params.config.timeoutMs)
|
|
862
|
-
? params.config.timeoutMs
|
|
863
|
-
: 300_000,
|
|
581
|
+
typeof params.config?.timeoutMs === "number" && Number.isFinite(params.config.timeoutMs) ? params.config.timeoutMs : 300_000,
|
|
864
582
|
1_000, // minimum 1 s
|
|
865
583
|
),
|
|
866
584
|
3_600_000, // maximum 1 h
|
|
867
585
|
);
|
|
868
586
|
const pollIntervalMs = Math.max(
|
|
869
587
|
Math.min(
|
|
870
|
-
typeof params.config?.pollIntervalMs === "number" &&
|
|
871
|
-
Number.isFinite(params.config.pollIntervalMs)
|
|
588
|
+
typeof params.config?.pollIntervalMs === "number" && Number.isFinite(params.config.pollIntervalMs)
|
|
872
589
|
? params.config.pollIntervalMs
|
|
873
590
|
: 2000,
|
|
874
591
|
60_000, // maximum 60 s
|
|
@@ -879,11 +596,7 @@ async function handleWait(
|
|
|
879
596
|
// Resolve the run's CWD: try ctx.cwd first, then scan child dirs with .crew/
|
|
880
597
|
const runCwd = locateRunCwd(runId, ctx.cwd);
|
|
881
598
|
if (!runCwd) {
|
|
882
|
-
return result(
|
|
883
|
-
`Run '${runId}' not found in '${ctx.cwd}' or its subdirectories.`,
|
|
884
|
-
{ action: "wait", status: "error", runId },
|
|
885
|
-
true,
|
|
886
|
-
);
|
|
599
|
+
return result(`Run '${runId}' not found in '${ctx.cwd}' or its subdirectories.`, { action: "wait", status: "error", runId }, true);
|
|
887
600
|
}
|
|
888
601
|
|
|
889
602
|
try {
|
|
@@ -891,16 +604,9 @@ async function handleWait(
|
|
|
891
604
|
timeoutMs,
|
|
892
605
|
pollIntervalMs,
|
|
893
606
|
});
|
|
894
|
-
const taskSummary = tasks
|
|
895
|
-
.map((t) => ` ${t.id}: ${t.status}`)
|
|
896
|
-
.join("\n");
|
|
607
|
+
const taskSummary = tasks.map((t) => ` ${t.id}: ${t.status}`).join("\n");
|
|
897
608
|
return result(
|
|
898
|
-
[
|
|
899
|
-
`Run ${runId} finished: ${manifest.status}`,
|
|
900
|
-
`Summary: ${manifest.summary ?? "(none)"}`,
|
|
901
|
-
`Tasks:`,
|
|
902
|
-
taskSummary,
|
|
903
|
-
].join("\n"),
|
|
609
|
+
[`Run ${runId} finished: ${manifest.status}`, `Summary: ${manifest.summary ?? "(none)"}`, `Tasks:`, taskSummary].join("\n"),
|
|
904
610
|
{
|
|
905
611
|
action: "wait",
|
|
906
612
|
status: manifest.status === "failed" ? "error" : "ok",
|
|
@@ -910,18 +616,11 @@ async function handleWait(
|
|
|
910
616
|
);
|
|
911
617
|
} catch (err) {
|
|
912
618
|
const msg = err instanceof Error ? err.message : String(err);
|
|
913
|
-
return result(
|
|
914
|
-
`wait failed: ${msg}`,
|
|
915
|
-
{ action: "wait", status: "error", runId },
|
|
916
|
-
true,
|
|
917
|
-
);
|
|
619
|
+
return result(`wait failed: ${msg}`, { action: "wait", status: "error", runId }, true);
|
|
918
620
|
}
|
|
919
621
|
}
|
|
920
622
|
|
|
921
|
-
export async function handleTeamTool(
|
|
922
|
-
params: TeamToolParamsValue,
|
|
923
|
-
ctx: TeamContext,
|
|
924
|
-
): Promise<PiTeamsToolResult> {
|
|
623
|
+
export async function handleTeamTool(params: TeamToolParamsValue, ctx: TeamContext): Promise<PiTeamsToolResult> {
|
|
925
624
|
const action = params.action ?? "list";
|
|
926
625
|
switch (action as string) {
|
|
927
626
|
case "list":
|
|
@@ -931,9 +630,7 @@ export async function handleTeamTool(
|
|
|
931
630
|
case "init": {
|
|
932
631
|
const cfg = configRecord(params.config);
|
|
933
632
|
const ignoreMethod =
|
|
934
|
-
typeof cfg.ignoreMethod === "string" &&
|
|
935
|
-
(cfg.ignoreMethod === "gitignore" ||
|
|
936
|
-
cfg.ignoreMethod === "exclude")
|
|
633
|
+
typeof cfg.ignoreMethod === "string" && (cfg.ignoreMethod === "gitignore" || cfg.ignoreMethod === "exclude")
|
|
937
634
|
? cfg.ignoreMethod
|
|
938
635
|
: undefined;
|
|
939
636
|
const initialized = initializeProject(ctx.cwd, {
|
|
@@ -951,22 +648,11 @@ export async function handleTeamTool(
|
|
|
951
648
|
[
|
|
952
649
|
"Initialized pi-crew project layout.",
|
|
953
650
|
"Directories:",
|
|
954
|
-
...(initialized.createdDirs.length
|
|
955
|
-
? initialized.createdDirs.map(
|
|
956
|
-
(dir) => `- created ${dir}`,
|
|
957
|
-
)
|
|
958
|
-
: ["- already existed"]),
|
|
651
|
+
...(initialized.createdDirs.length ? initialized.createdDirs.map((dir) => `- created ${dir}`) : ["- already existed"]),
|
|
959
652
|
"Copied builtin files:",
|
|
960
|
-
...(initialized.copiedFiles.length
|
|
961
|
-
? initialized.copiedFiles.map((file) => `- ${file}`)
|
|
962
|
-
: ["- (none)"]),
|
|
653
|
+
...(initialized.copiedFiles.length ? initialized.copiedFiles.map((file) => `- ${file}`) : ["- (none)"]),
|
|
963
654
|
...(initialized.skippedFiles.length
|
|
964
|
-
? [
|
|
965
|
-
"Skipped existing files:",
|
|
966
|
-
...initialized.skippedFiles.map(
|
|
967
|
-
(file) => `- ${file}`,
|
|
968
|
-
),
|
|
969
|
-
]
|
|
655
|
+
? ["Skipped existing files:", ...initialized.skippedFiles.map((file) => `- ${file}`)]
|
|
970
656
|
: []),
|
|
971
657
|
`Config: ${initialized.configPath || "(none)"} (${initialized.configScope}${initialized.configCreated ? "; created" : initialized.configSkipped ? "; already existed" : "; unchanged"})`,
|
|
972
658
|
`Ignore: ${initialized.gitignorePath} (${initialized.gitignoreUpdated ? "updated" : "already configured"})`,
|
|
@@ -978,21 +664,12 @@ export async function handleTeamTool(
|
|
|
978
664
|
return result(piTeamsHelp(), { action: "help", status: "ok" });
|
|
979
665
|
case "recommend": {
|
|
980
666
|
const goal = params.goal ?? params.task;
|
|
981
|
-
if (!goal)
|
|
982
|
-
return result(
|
|
983
|
-
"Recommend requires goal or task.",
|
|
984
|
-
{ action: "recommend", status: "error" },
|
|
985
|
-
true,
|
|
986
|
-
);
|
|
667
|
+
if (!goal) return result("Recommend requires goal or task.", { action: "recommend", status: "error" }, true);
|
|
987
668
|
const loaded = loadConfig(ctx.cwd);
|
|
988
|
-
const recommendation = recommendTeam(
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
teams: allTeams(discoverTeams(ctx.cwd)),
|
|
993
|
-
agents: allAgents(discoverAgents(ctx.cwd)),
|
|
994
|
-
},
|
|
995
|
-
);
|
|
669
|
+
const recommendation = recommendTeam(goal, loaded.config.autonomous, {
|
|
670
|
+
teams: allTeams(discoverTeams(ctx.cwd)),
|
|
671
|
+
agents: allAgents(discoverAgents(ctx.cwd)),
|
|
672
|
+
});
|
|
996
673
|
return result(formatRecommendation(goal, recommendation), {
|
|
997
674
|
action: "recommend",
|
|
998
675
|
status: "ok",
|
|
@@ -1000,17 +677,11 @@ export async function handleTeamTool(
|
|
|
1000
677
|
}
|
|
1001
678
|
case "autonomy": {
|
|
1002
679
|
const patch = autonomousPatchFromConfig(params.config);
|
|
1003
|
-
const shouldUpdate = Object.values(patch).some(
|
|
1004
|
-
(value) => value !== undefined,
|
|
1005
|
-
);
|
|
680
|
+
const shouldUpdate = Object.values(patch).some((value) => value !== undefined);
|
|
1006
681
|
if (!shouldUpdate) {
|
|
1007
682
|
const loaded = loadConfig(ctx.cwd);
|
|
1008
683
|
return result(
|
|
1009
|
-
formatAutonomyStatus(
|
|
1010
|
-
loaded.config.autonomous,
|
|
1011
|
-
loaded.path,
|
|
1012
|
-
false,
|
|
1013
|
-
),
|
|
684
|
+
formatAutonomyStatus(loaded.config.autonomous, loaded.path, false),
|
|
1014
685
|
{
|
|
1015
686
|
action: "autonomy",
|
|
1016
687
|
status: loaded.error ? "error" : "ok",
|
|
@@ -1020,37 +691,21 @@ export async function handleTeamTool(
|
|
|
1020
691
|
}
|
|
1021
692
|
try {
|
|
1022
693
|
const saved = updateAutonomousConfig(patch);
|
|
1023
|
-
return result(
|
|
1024
|
-
formatAutonomyStatus(
|
|
1025
|
-
saved.config.autonomous,
|
|
1026
|
-
saved.path,
|
|
1027
|
-
true,
|
|
1028
|
-
),
|
|
1029
|
-
{ action: "autonomy", status: "ok" },
|
|
1030
|
-
);
|
|
694
|
+
return result(formatAutonomyStatus(saved.config.autonomous, saved.path, true), { action: "autonomy", status: "ok" });
|
|
1031
695
|
} catch (error) {
|
|
1032
|
-
const message =
|
|
1033
|
-
|
|
1034
|
-
return result(
|
|
1035
|
-
message,
|
|
1036
|
-
{ action: "autonomy", status: "error" },
|
|
1037
|
-
true,
|
|
1038
|
-
);
|
|
696
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
697
|
+
return result(message, { action: "autonomy", status: "error" }, true);
|
|
1039
698
|
}
|
|
1040
699
|
}
|
|
1041
700
|
case "config": {
|
|
1042
701
|
const patch = configPatchFromConfig(params.config);
|
|
1043
702
|
const cfg = configRecord(params.config);
|
|
1044
703
|
const unsetPaths = Array.isArray(cfg.unset)
|
|
1045
|
-
? cfg.unset.filter(
|
|
1046
|
-
(entry): entry is string => typeof entry === "string",
|
|
1047
|
-
)
|
|
704
|
+
? cfg.unset.filter((entry): entry is string => typeof entry === "string")
|
|
1048
705
|
: typeof cfg.unset === "string"
|
|
1049
706
|
? [cfg.unset]
|
|
1050
707
|
: [];
|
|
1051
|
-
const shouldUpdate =
|
|
1052
|
-
Object.values(patch).some((value) => value !== undefined) ||
|
|
1053
|
-
unsetPaths.length > 0;
|
|
708
|
+
const shouldUpdate = Object.values(patch).some((value) => value !== undefined) || unsetPaths.length > 0;
|
|
1054
709
|
if (shouldUpdate) {
|
|
1055
710
|
try {
|
|
1056
711
|
const saved = updateConfig(patch, {
|
|
@@ -1059,22 +714,14 @@ export async function handleTeamTool(
|
|
|
1059
714
|
unsetPaths,
|
|
1060
715
|
});
|
|
1061
716
|
return result(
|
|
1062
|
-
[
|
|
1063
|
-
"
|
|
1064
|
-
|
|
1065
|
-
"Effective config:",
|
|
1066
|
-
JSON.stringify(saved.config, null, 2),
|
|
1067
|
-
].join("\n"),
|
|
717
|
+
["Updated pi-crew config.", `Path: ${saved.path}`, "Effective config:", JSON.stringify(saved.config, null, 2)].join(
|
|
718
|
+
"\n",
|
|
719
|
+
),
|
|
1068
720
|
{ action: "config", status: "ok" },
|
|
1069
721
|
);
|
|
1070
722
|
} catch (error) {
|
|
1071
|
-
const message =
|
|
1072
|
-
|
|
1073
|
-
return result(
|
|
1074
|
-
message,
|
|
1075
|
-
{ action: "config", status: "error" },
|
|
1076
|
-
true,
|
|
1077
|
-
);
|
|
723
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
724
|
+
return result(message, { action: "config", status: "error" }, true);
|
|
1078
725
|
}
|
|
1079
726
|
}
|
|
1080
727
|
const loaded = loadConfig(ctx.cwd);
|
|
@@ -1086,22 +733,12 @@ export async function handleTeamTool(
|
|
|
1086
733
|
JSON.stringify(loaded.config, null, 2),
|
|
1087
734
|
"Schema: package export ./schema.json",
|
|
1088
735
|
];
|
|
1089
|
-
return result(
|
|
1090
|
-
lines.join("\n"),
|
|
1091
|
-
{ action: "config", status: loaded.error ? "error" : "ok" },
|
|
1092
|
-
Boolean(loaded.error),
|
|
1093
|
-
);
|
|
736
|
+
return result(lines.join("\n"), { action: "config", status: loaded.error ? "error" : "ok" }, Boolean(loaded.error));
|
|
1094
737
|
}
|
|
1095
738
|
case "validate": {
|
|
1096
739
|
const report = validateResources(ctx.cwd);
|
|
1097
|
-
const hasErrors = report.issues.some(
|
|
1098
|
-
|
|
1099
|
-
);
|
|
1100
|
-
return result(
|
|
1101
|
-
formatValidationReport(report),
|
|
1102
|
-
{ action: "validate", status: hasErrors ? "error" : "ok" },
|
|
1103
|
-
hasErrors,
|
|
1104
|
-
);
|
|
740
|
+
const hasErrors = report.issues.some((issue) => issue.level === "error");
|
|
741
|
+
return result(formatValidationReport(report), { action: "validate", status: hasErrors ? "error" : "ok" }, hasErrors);
|
|
1105
742
|
}
|
|
1106
743
|
case "doctor":
|
|
1107
744
|
return handleDoctor(ctx, params);
|
|
@@ -1166,29 +803,21 @@ export async function handleTeamTool(
|
|
|
1166
803
|
assertSafePathId("runId", params.runId);
|
|
1167
804
|
const graph = loadRunGraph(ctx.cwd, params.runId);
|
|
1168
805
|
return result(
|
|
1169
|
-
graph
|
|
1170
|
-
? JSON.stringify(graph, null, 2)
|
|
1171
|
-
: "No graph found for this run.",
|
|
806
|
+
graph ? JSON.stringify(graph, null, 2) : "No graph found for this run.",
|
|
1172
807
|
{ action: "graph", status: graph ? "ok" : "error" },
|
|
1173
808
|
!graph,
|
|
1174
809
|
);
|
|
1175
810
|
}
|
|
1176
811
|
const graphs = listRunGraphs(ctx.cwd);
|
|
1177
|
-
return result(
|
|
1178
|
-
|
|
1179
|
-
|
|
1180
|
-
|
|
1181
|
-
{ action: "graph", status: "ok" },
|
|
1182
|
-
);
|
|
812
|
+
return result(graphs.length ? `Available graphs:\n${graphs.join("\n")}` : "No graphs available.", {
|
|
813
|
+
action: "graph",
|
|
814
|
+
status: "ok",
|
|
815
|
+
});
|
|
1183
816
|
}
|
|
1184
817
|
case "search": {
|
|
1185
818
|
const query = params.goal ?? params.task ?? "";
|
|
1186
819
|
if (!query) {
|
|
1187
|
-
return result(
|
|
1188
|
-
"Search requires goal or task query.",
|
|
1189
|
-
{ action: "search", status: "error" },
|
|
1190
|
-
true,
|
|
1191
|
-
);
|
|
820
|
+
return result("Search requires goal or task query.", { action: "search", status: "error" }, true);
|
|
1192
821
|
}
|
|
1193
822
|
try {
|
|
1194
823
|
const [agentResults, teamResults] = await Promise.all([
|
|
@@ -1199,30 +828,19 @@ export async function handleTeamTool(
|
|
|
1199
828
|
if (teamResults.length) {
|
|
1200
829
|
lines.push("## Teams");
|
|
1201
830
|
for (const r of teamResults) {
|
|
1202
|
-
lines.push(
|
|
1203
|
-
`- [${r.team.name}] score=${r.score.toFixed(2)}: ${r.team.description ?? "(no description)"}`,
|
|
1204
|
-
);
|
|
831
|
+
lines.push(`- [${r.team.name}] score=${r.score.toFixed(2)}: ${r.team.description ?? "(no description)"}`);
|
|
1205
832
|
}
|
|
1206
833
|
}
|
|
1207
834
|
if (agentResults.length) {
|
|
1208
835
|
lines.push("## Agents");
|
|
1209
836
|
for (const r of agentResults) {
|
|
1210
|
-
lines.push(
|
|
1211
|
-
`- [${r.agent.name}] score=${r.score.toFixed(2)}: ${r.agent.description ?? "(no description)"}`,
|
|
1212
|
-
);
|
|
837
|
+
lines.push(`- [${r.agent.name}] score=${r.score.toFixed(2)}: ${r.agent.description ?? "(no description)"}`);
|
|
1213
838
|
}
|
|
1214
839
|
}
|
|
1215
|
-
return result(
|
|
1216
|
-
lines.length ? lines.join("\n") : "No results found.",
|
|
1217
|
-
{ action: "search", status: "ok" },
|
|
1218
|
-
);
|
|
840
|
+
return result(lines.length ? lines.join("\n") : "No results found.", { action: "search", status: "ok" });
|
|
1219
841
|
} catch (err) {
|
|
1220
842
|
const msg = err instanceof Error ? err.message : String(err);
|
|
1221
|
-
return result(
|
|
1222
|
-
`Search failed: ${msg}`,
|
|
1223
|
-
{ action: "search", status: "error" },
|
|
1224
|
-
true,
|
|
1225
|
-
);
|
|
843
|
+
return result(`Search failed: ${msg}`, { action: "search", status: "error" }, true);
|
|
1226
844
|
}
|
|
1227
845
|
}
|
|
1228
846
|
case "schedule":
|
|
@@ -1230,10 +848,7 @@ export async function handleTeamTool(
|
|
|
1230
848
|
case "scheduled":
|
|
1231
849
|
return handleListScheduled(params, ctx);
|
|
1232
850
|
case "anchor": {
|
|
1233
|
-
const subAction =
|
|
1234
|
-
typeof params.config?.subAction === "string"
|
|
1235
|
-
? params.config.subAction
|
|
1236
|
-
: "status";
|
|
851
|
+
const subAction = typeof params.config?.subAction === "string" ? params.config.subAction : "status";
|
|
1237
852
|
switch (subAction) {
|
|
1238
853
|
case "set":
|
|
1239
854
|
return handleAnchorSet(params, ctx);
|
|
@@ -1275,10 +890,10 @@ export async function handleTeamTool(
|
|
|
1275
890
|
case "toggle": {
|
|
1276
891
|
const service = createAutoSummarizeService();
|
|
1277
892
|
service.toggle();
|
|
1278
|
-
return result(
|
|
1279
|
-
|
|
1280
|
-
|
|
1281
|
-
);
|
|
893
|
+
return result(`Auto-summarize ${service.isEnabled() ? "enabled" : "disabled"}.`, {
|
|
894
|
+
action: "auto-summarize",
|
|
895
|
+
status: "ok",
|
|
896
|
+
});
|
|
1282
897
|
}
|
|
1283
898
|
default:
|
|
1284
899
|
return handleAutoSummarizeStatus(params, ctx);
|
|
@@ -1302,12 +917,7 @@ export async function handleTeamTool(
|
|
|
1302
917
|
}
|
|
1303
918
|
case "cache": {
|
|
1304
919
|
if (params.goal) {
|
|
1305
|
-
const key = computeRunCacheKey(
|
|
1306
|
-
params.goal,
|
|
1307
|
-
params.team ?? "default",
|
|
1308
|
-
params.workflow ?? "default",
|
|
1309
|
-
ctx.cwd,
|
|
1310
|
-
);
|
|
920
|
+
const key = computeRunCacheKey(params.goal, params.team ?? "default", params.workflow ?? "default", ctx.cwd);
|
|
1311
921
|
const cached = getCachedRun(ctx.cwd, key);
|
|
1312
922
|
if (cached) {
|
|
1313
923
|
return result(
|
|
@@ -1332,35 +942,19 @@ export async function handleTeamTool(
|
|
|
1332
942
|
});
|
|
1333
943
|
}
|
|
1334
944
|
const stats = getCacheStats(ctx.cwd);
|
|
1335
|
-
return result(
|
|
1336
|
-
`Cache stats: ${stats.entries} entries, ${stats.sizeBytes} bytes`,
|
|
1337
|
-
{ action: "cache", status: "ok" },
|
|
1338
|
-
);
|
|
945
|
+
return result(`Cache stats: ${stats.entries} entries, ${stats.sizeBytes} bytes`, { action: "cache", status: "ok" });
|
|
1339
946
|
}
|
|
1340
947
|
case "checkpoint": {
|
|
1341
948
|
if (!params.runId || !params.taskId) {
|
|
1342
|
-
return result(
|
|
1343
|
-
"Checkpoint requires runId and taskId.",
|
|
1344
|
-
{ action: "checkpoint", status: "error" },
|
|
1345
|
-
true,
|
|
1346
|
-
);
|
|
949
|
+
return result("Checkpoint requires runId and taskId.", { action: "checkpoint", status: "error" }, true);
|
|
1347
950
|
}
|
|
1348
951
|
assertSafePathId("runId", params.runId);
|
|
1349
952
|
assertSafePathId("taskId", params.taskId);
|
|
1350
|
-
const stateRoot = path.join(
|
|
1351
|
-
projectCrewRoot(ctx.cwd),
|
|
1352
|
-
"state",
|
|
1353
|
-
"runs",
|
|
1354
|
-
params.runId,
|
|
1355
|
-
);
|
|
953
|
+
const stateRoot = path.join(projectCrewRoot(ctx.cwd), "state", "runs", params.runId);
|
|
1356
954
|
const store = new FileCheckpointStore(stateRoot);
|
|
1357
955
|
const checkpoint = store.load(params.runId, params.taskId);
|
|
1358
956
|
if (!checkpoint) {
|
|
1359
|
-
return result(
|
|
1360
|
-
"No checkpoint found.",
|
|
1361
|
-
{ action: "checkpoint", status: "error" },
|
|
1362
|
-
true,
|
|
1363
|
-
);
|
|
957
|
+
return result("No checkpoint found.", { action: "checkpoint", status: "error" }, true);
|
|
1364
958
|
}
|
|
1365
959
|
return result(
|
|
1366
960
|
`Checkpoint: step=${checkpoint.step}, progress=${checkpoint.progress}, savedAt=${new Date(checkpoint.savedAt).toISOString()}`,
|
|
@@ -1403,15 +997,12 @@ interface CrewRegistry {
|
|
|
1403
997
|
// registerAgent/unregisterAgent/listDynamicAgents for cross-extension access.
|
|
1404
998
|
|
|
1405
999
|
export function registerCrewGlobalRegistry(registry: CrewRegistry): void {
|
|
1406
|
-
(globalThis as Record<symbol | string, unknown>)[CREW_REGISTRY_KEY] =
|
|
1407
|
-
registry;
|
|
1000
|
+
(globalThis as Record<symbol | string, unknown>)[CREW_REGISTRY_KEY] = registry;
|
|
1408
1001
|
}
|
|
1409
1002
|
|
|
1410
1003
|
/** @internal */
|
|
1411
1004
|
function getCrewGlobalRegistry(): CrewRegistry | undefined {
|
|
1412
|
-
return (globalThis as Record<symbol | string, unknown>)[
|
|
1413
|
-
CREW_REGISTRY_KEY
|
|
1414
|
-
] as CrewRegistry | undefined;
|
|
1005
|
+
return (globalThis as Record<symbol | string, unknown>)[CREW_REGISTRY_KEY] as CrewRegistry | undefined;
|
|
1415
1006
|
}
|
|
1416
1007
|
|
|
1417
1008
|
/** Create and install the global CrewRegistry singleton. Call once at extension init. */
|