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
|
@@ -2,14 +2,14 @@ import { execFileSync, spawnSync } from "node:child_process";
|
|
|
2
2
|
import { randomBytes } from "node:crypto";
|
|
3
3
|
import * as fs from "node:fs";
|
|
4
4
|
import * as path from "node:path";
|
|
5
|
-
import { WINDOWS_ESSENTIAL_ENV_VARS } from "../utils/env-allowlist.ts";
|
|
6
5
|
import { loadConfig } from "../config/config.ts";
|
|
7
|
-
import { projectCrewRoot } from "../utils/paths.ts";
|
|
8
6
|
import { DEFAULT_PATHS } from "../config/defaults.ts";
|
|
9
|
-
import { logInternalError } from "../utils/internal-error.ts";
|
|
10
|
-
import { sanitizeEnvSecrets } from "../utils/env-filter.ts";
|
|
11
7
|
import { writeArtifact } from "../state/artifact-store.ts";
|
|
12
8
|
import type { TeamRunManifest, TeamTaskState } from "../state/types.ts";
|
|
9
|
+
import { WINDOWS_ESSENTIAL_ENV_VARS } from "../utils/env-allowlist.ts";
|
|
10
|
+
import { sanitizeEnvSecrets } from "../utils/env-filter.ts";
|
|
11
|
+
import { logInternalError } from "../utils/internal-error.ts";
|
|
12
|
+
import { projectCrewRoot } from "../utils/paths.ts";
|
|
13
13
|
|
|
14
14
|
export interface PreparedTaskWorkspace {
|
|
15
15
|
cwd: string;
|
|
@@ -29,15 +29,56 @@ export interface WorktreeDiffStat {
|
|
|
29
29
|
|
|
30
30
|
function git(cwd: string, args: string[]): string {
|
|
31
31
|
// SECURITY: PI_* and PI_CREW_* wildcards removed — they could match secret vars like PI_PASSWORD.
|
|
32
|
-
// Git operations do not need PI_CREW_* execution-control vars.
|
|
33
|
-
return execFileSync("git", args, {
|
|
32
|
+
// Git operations do not need PI_CREW_* execution-control vars.
|
|
33
|
+
return execFileSync("git", args, {
|
|
34
|
+
cwd,
|
|
35
|
+
encoding: "utf-8",
|
|
36
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
37
|
+
env: {
|
|
38
|
+
...sanitizeEnvSecrets(process.env, {
|
|
39
|
+
allowList: [
|
|
40
|
+
"PATH",
|
|
41
|
+
"HOME",
|
|
42
|
+
"USER",
|
|
43
|
+
...WINDOWS_ESSENTIAL_ENV_VARS,
|
|
44
|
+
"SHELL",
|
|
45
|
+
"TERM",
|
|
46
|
+
"LANG",
|
|
47
|
+
"LC_ALL",
|
|
48
|
+
"LC_COLLATE",
|
|
49
|
+
"LC_CTYPE",
|
|
50
|
+
"LC_MESSAGES",
|
|
51
|
+
"XDG_CONFIG_HOME",
|
|
52
|
+
"XDG_DATA_HOME",
|
|
53
|
+
"XDG_CACHE_HOME",
|
|
54
|
+
"NVM_BIN",
|
|
55
|
+
"NVM_DIR",
|
|
56
|
+
"NODE_PATH",
|
|
57
|
+
"GIT_CONFIG_GLOBAL",
|
|
58
|
+
"GIT_CONFIG_SYSTEM",
|
|
59
|
+
"GIT_AUTHOR_NAME",
|
|
60
|
+
"GIT_AUTHOR_EMAIL",
|
|
61
|
+
"GIT_COMMITTER_NAME",
|
|
62
|
+
"GIT_COMMITTER_EMAIL",
|
|
63
|
+
],
|
|
64
|
+
}),
|
|
65
|
+
LANG: "en_US.UTF-8",
|
|
66
|
+
LC_ALL: "en_US.UTF-8",
|
|
67
|
+
},
|
|
68
|
+
windowsHide: true,
|
|
69
|
+
}).trim();
|
|
34
70
|
}
|
|
35
71
|
|
|
36
72
|
// Dots are removed from branch names since they are used in path construction,
|
|
37
73
|
// and dots could cause ambiguity with relative path handling on some platforms.
|
|
38
74
|
// Branch names themselves support dots in git, but we strip them for safe path use.
|
|
39
75
|
function sanitizeBranchPart(value: string): string {
|
|
40
|
-
return
|
|
76
|
+
return (
|
|
77
|
+
value
|
|
78
|
+
.toLowerCase()
|
|
79
|
+
.replace(/[^a-z0-9_/-]+/g, "-")
|
|
80
|
+
.replace(/^-+|-+$/g, "") || "task"
|
|
81
|
+
);
|
|
41
82
|
}
|
|
42
83
|
|
|
43
84
|
export function findGitRoot(cwd: string): string {
|
|
@@ -55,16 +96,24 @@ function linkNodeModulesIfPresent(repoRoot: string, worktreePath: string): boole
|
|
|
55
96
|
const source = path.join(repoRoot, "node_modules");
|
|
56
97
|
const target = path.join(worktreePath, "node_modules");
|
|
57
98
|
let sourceStat: fs.Stats;
|
|
58
|
-
try {
|
|
99
|
+
try {
|
|
100
|
+
sourceStat = fs.statSync(source);
|
|
101
|
+
} catch {
|
|
102
|
+
return false;
|
|
103
|
+
}
|
|
59
104
|
if (!sourceStat.isDirectory()) return false;
|
|
60
105
|
if (fs.existsSync(target)) return false;
|
|
61
|
-
|
|
106
|
+
// M5 fix: log symlink failure reason, especially on Windows non-admin.
|
|
62
107
|
try {
|
|
63
108
|
fs.symlinkSync(source, target, process.platform === "win32" ? "junction" : "dir");
|
|
64
109
|
return true;
|
|
65
110
|
} catch (error) {
|
|
66
111
|
const isWindows = process.platform === "win32";
|
|
67
|
-
logInternalError(
|
|
112
|
+
logInternalError(
|
|
113
|
+
"worktree.symlink-fail",
|
|
114
|
+
error,
|
|
115
|
+
isWindows ? "Windows non-admin: SeCreateSymbolicLinkPrivilege needed for node_modules symlink" : String(error),
|
|
116
|
+
);
|
|
68
117
|
return false;
|
|
69
118
|
}
|
|
70
119
|
}
|
|
@@ -133,13 +182,21 @@ function runSetupHook(manifest: TeamRunManifest, task: TeamTaskState, repoRoot:
|
|
|
133
182
|
// (isAllowedSetupHook, isHookPathContainedInRepoRoot) prevents hook scripts from writing outside
|
|
134
183
|
// the worktree, but cannot prevent a trusted hook from performing harmful operations within it.
|
|
135
184
|
if (path.isAbsolute(rawHookPath)) {
|
|
136
|
-
logInternalError(
|
|
185
|
+
logInternalError(
|
|
186
|
+
"worktree.setupHook.homeHook",
|
|
187
|
+
new Error("Home directory hook used — ensure ~/.pi/hooks/ is trusted"),
|
|
188
|
+
`hookPath=${rawHookPath}`,
|
|
189
|
+
);
|
|
137
190
|
}
|
|
138
191
|
const hookPath = path.isAbsolute(rawHookPath) ? rawHookPath : path.resolve(repoRoot, rawHookPath);
|
|
139
192
|
// SECURITY: Verify the resolved hook path is contained within the real repoRoot.
|
|
140
193
|
// This prevents symlink-based escape where repoRoot is a symlink.
|
|
141
194
|
if (!path.isAbsolute(rawHookPath) && !isHookPathContainedInRepoRoot(repoRoot, hookPath)) {
|
|
142
|
-
logInternalError(
|
|
195
|
+
logInternalError(
|
|
196
|
+
"worktree.setupHook.contained",
|
|
197
|
+
new Error("hook path escapes repoRoot after realpath resolution: " + hookPath),
|
|
198
|
+
`repoRoot=${repoRoot}`,
|
|
199
|
+
);
|
|
143
200
|
return [];
|
|
144
201
|
}
|
|
145
202
|
try {
|
|
@@ -160,7 +217,11 @@ function runSetupHook(manifest: TeamRunManifest, task: TeamTaskState, repoRoot:
|
|
|
160
217
|
// running through a shell that could interpret malicious filenames.
|
|
161
218
|
const useShell = false;
|
|
162
219
|
if (process.platform === "win32" && !nodeHook && !isBatchFile) {
|
|
163
|
-
logInternalError(
|
|
220
|
+
logInternalError(
|
|
221
|
+
"worktree.setupHook.windowsNoShell",
|
|
222
|
+
new Error("Non-node, non-batch hook skipped on Windows (shell:true disabled for security)"),
|
|
223
|
+
`hook=${hookPath}`,
|
|
224
|
+
);
|
|
164
225
|
}
|
|
165
226
|
// SECURITY: Resolve the hook to its real path before execution to close the TOCTOU window.
|
|
166
227
|
// This prevents a symlink swap between the containment check and actual execution.
|
|
@@ -179,45 +240,76 @@ function runSetupHook(manifest: TeamRunManifest, task: TeamTaskState, repoRoot:
|
|
|
179
240
|
}
|
|
180
241
|
const result = isBatchFile
|
|
181
242
|
? spawnSync("cmd.exe", ["/c", realHookPath], {
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
243
|
+
cwd: worktreePath,
|
|
244
|
+
encoding: "utf-8",
|
|
245
|
+
input: JSON.stringify({
|
|
246
|
+
version: 1,
|
|
247
|
+
repoRoot,
|
|
248
|
+
worktreePath,
|
|
249
|
+
agentCwd: worktreePath,
|
|
250
|
+
branch,
|
|
251
|
+
runId: manifest.runId,
|
|
252
|
+
taskId: task.id,
|
|
253
|
+
agent: task.agent,
|
|
254
|
+
}),
|
|
255
|
+
timeout: cfg.setupHookTimeoutMs ?? 30_000,
|
|
256
|
+
shell: false, // cmd.exe /c handles batch files safely
|
|
257
|
+
env: sanitizeEnvSecrets(process.env, {
|
|
258
|
+
allowList: ["PATH", "HOME", ...WINDOWS_ESSENTIAL_ENV_VARS, "TMPDIR", "LANG", "LC_ALL"],
|
|
259
|
+
}),
|
|
260
|
+
windowsHide: true,
|
|
261
|
+
})
|
|
192
262
|
: spawnSync(nodeHook ? process.execPath : realHookPath, nodeHook ? [realHookPath] : [], {
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
263
|
+
cwd: worktreePath,
|
|
264
|
+
encoding: "utf-8",
|
|
265
|
+
input: JSON.stringify({
|
|
266
|
+
version: 1,
|
|
267
|
+
repoRoot,
|
|
268
|
+
worktreePath,
|
|
269
|
+
agentCwd: worktreePath,
|
|
270
|
+
branch,
|
|
271
|
+
runId: manifest.runId,
|
|
272
|
+
taskId: task.id,
|
|
273
|
+
agent: task.agent,
|
|
274
|
+
}),
|
|
275
|
+
timeout: cfg.setupHookTimeoutMs ?? 30_000,
|
|
276
|
+
shell: false,
|
|
277
|
+
env: sanitizeEnvSecrets(process.env, {
|
|
278
|
+
allowList: ["PATH", "HOME", ...WINDOWS_ESSENTIAL_ENV_VARS, "TMPDIR", "LANG", "LC_ALL"],
|
|
279
|
+
}),
|
|
280
|
+
windowsHide: true,
|
|
281
|
+
});
|
|
203
282
|
if (result.error) throw new Error(`worktree setup hook failed: ${result.error.message}`);
|
|
204
|
-
if (result.status !== 0)
|
|
283
|
+
if (result.status !== 0)
|
|
284
|
+
throw new Error(`worktree setup hook failed with exit code ${result.status}: ${result.stderr || result.stdout || "no output"}`);
|
|
205
285
|
const trimmed = result.stdout.trim();
|
|
206
286
|
if (!trimmed) return [];
|
|
207
287
|
try {
|
|
208
288
|
// Extract JSON — hooks may output debug logging before JSON.
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
289
|
+
// M4 fix: try full trimmed (multi-line JSON object) before falling back to last line.
|
|
290
|
+
const lines = trimmed.split(/\r?\n/);
|
|
291
|
+
let parsed: { syntheticPaths?: unknown } | null = null;
|
|
292
|
+
try {
|
|
293
|
+
parsed = JSON.parse(trimmed) as { syntheticPaths?: unknown };
|
|
294
|
+
} catch {
|
|
295
|
+
/* fall through — try last line */
|
|
296
|
+
}
|
|
297
|
+
if (!parsed && lines.length > 0) {
|
|
298
|
+
const lastLine = lines[lines.length - 1];
|
|
299
|
+
try {
|
|
300
|
+
parsed = JSON.parse(lastLine) as { syntheticPaths?: unknown };
|
|
301
|
+
} catch {
|
|
302
|
+
/* give up */
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
if (!parsed || !Array.isArray(parsed.syntheticPaths)) return [];
|
|
306
|
+
return [
|
|
307
|
+
...new Set(
|
|
308
|
+
parsed.syntheticPaths
|
|
309
|
+
.filter((entry): entry is string => typeof entry === "string")
|
|
310
|
+
.map((entry) => normalizeSyntheticPath(worktreePath, entry)),
|
|
311
|
+
),
|
|
312
|
+
];
|
|
221
313
|
} catch (error) {
|
|
222
314
|
logInternalError("worktree.setupHook.parse", error, `lastLine=${(trimmed.split(/\r?\n/).pop() ?? "").slice(0, 200)}`);
|
|
223
315
|
return [];
|
|
@@ -226,19 +318,34 @@ function runSetupHook(manifest: TeamRunManifest, task: TeamTaskState, repoRoot:
|
|
|
226
318
|
|
|
227
319
|
function branchExists(repoRoot: string, branch: string): { local: boolean; remoteOnly: boolean } {
|
|
228
320
|
let local = false;
|
|
229
|
-
try {
|
|
321
|
+
try {
|
|
322
|
+
git(repoRoot, ["rev-parse", "--verify", `refs/heads/${branch}`]);
|
|
323
|
+
local = true;
|
|
324
|
+
} catch {}
|
|
230
325
|
if (local) return { local: true, remoteOnly: false };
|
|
231
326
|
// Check remote-tracking branch
|
|
232
327
|
try {
|
|
233
|
-
const out = execFileSync("git", ["for-each-ref", "--format=%(refname)", `refs/remotes/*/${branch}`],
|
|
234
|
-
|
|
328
|
+
const out = execFileSync("git", ["for-each-ref", "--format=%(refname)", `refs/remotes/*/${branch}`], {
|
|
329
|
+
cwd: repoRoot,
|
|
330
|
+
encoding: "utf-8",
|
|
331
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
332
|
+
windowsHide: true,
|
|
333
|
+
}).trim();
|
|
235
334
|
return { local: false, remoteOnly: out.length > 0 };
|
|
236
|
-
} catch {
|
|
335
|
+
} catch {
|
|
336
|
+
return { local: false, remoteOnly: false };
|
|
337
|
+
}
|
|
237
338
|
}
|
|
238
339
|
|
|
239
340
|
function pruneStaleWorktrees(repoRoot: string): void {
|
|
240
|
-
try {
|
|
241
|
-
|
|
341
|
+
try {
|
|
342
|
+
execFileSync("git", ["worktree", "prune"], {
|
|
343
|
+
cwd: repoRoot,
|
|
344
|
+
stdio: "ignore",
|
|
345
|
+
});
|
|
346
|
+
} catch {
|
|
347
|
+
/* best-effort */
|
|
348
|
+
}
|
|
242
349
|
}
|
|
243
350
|
|
|
244
351
|
/**
|
|
@@ -344,7 +451,11 @@ export function prepareTaskWorkspace(manifest: TeamRunManifest, task: TeamTaskSt
|
|
|
344
451
|
const r = fs.realpathSync.native(worktreeRoot);
|
|
345
452
|
resolvedWorktreeRoot = r.startsWith("\\\\?\\") ? r.slice(4) : r;
|
|
346
453
|
} catch {
|
|
347
|
-
try {
|
|
454
|
+
try {
|
|
455
|
+
resolvedWorktreeRoot = fs.realpathSync(worktreeRoot);
|
|
456
|
+
} catch {
|
|
457
|
+
/* keep as-is */
|
|
458
|
+
}
|
|
348
459
|
}
|
|
349
460
|
const sanitizedTaskId = sanitizeBranchPart(task.id);
|
|
350
461
|
const worktreePath = path.join(resolvedWorktreeRoot, sanitizedTaskId);
|
|
@@ -360,7 +471,19 @@ export function prepareTaskWorkspace(manifest: TeamRunManifest, task: TeamTaskSt
|
|
|
360
471
|
// worktreePath uses short-name backslash form. Resolve both through
|
|
361
472
|
// realpathSync.native (which always returns long-name on Windows)
|
|
362
473
|
// for consistent comparison.
|
|
363
|
-
const normalizedWtPath =
|
|
474
|
+
const normalizedWtPath =
|
|
475
|
+
process.platform === "win32"
|
|
476
|
+
? (() => {
|
|
477
|
+
try {
|
|
478
|
+
const r = fs.realpathSync.native(worktreePath);
|
|
479
|
+
return r.startsWith("\\\\?\\") ? r.slice(4) : r;
|
|
480
|
+
} catch {
|
|
481
|
+
return worktreePath;
|
|
482
|
+
}
|
|
483
|
+
})()
|
|
484
|
+
.replace(/\\/g, "/")
|
|
485
|
+
.toLowerCase()
|
|
486
|
+
: worktreePath;
|
|
364
487
|
worktreeExists = worktreeList.split("\n").some((line) => {
|
|
365
488
|
const trimmed = line.trim();
|
|
366
489
|
const matchPath = trimmed.startsWith("worktree ") ? trimmed.slice(9) : trimmed;
|
|
@@ -369,13 +492,17 @@ export function prepareTaskWorkspace(manifest: TeamRunManifest, task: TeamTaskSt
|
|
|
369
492
|
}
|
|
370
493
|
return matchPath === worktreePath;
|
|
371
494
|
});
|
|
372
|
-
} catch {
|
|
495
|
+
} catch {
|
|
496
|
+
worktreeExists = false;
|
|
497
|
+
}
|
|
373
498
|
if (worktreeExists) {
|
|
374
499
|
let currentBranch: string;
|
|
375
500
|
try {
|
|
376
501
|
currentBranch = git(worktreePath, ["rev-parse", "--abbrev-ref", "HEAD"]);
|
|
377
502
|
} catch (gitError) {
|
|
378
|
-
throw new Error(
|
|
503
|
+
throw new Error(
|
|
504
|
+
`Existing worktree at ${worktreePath} is not a valid git repository; cannot verify branch: ${gitError instanceof Error ? gitError.message : String(gitError)}`,
|
|
505
|
+
);
|
|
379
506
|
}
|
|
380
507
|
if (currentBranch !== branch) {
|
|
381
508
|
throw new Error(`Existing worktree branch mismatch at ${worktreePath}: expected '${branch}', got '${currentBranch}'.`);
|
|
@@ -384,7 +511,11 @@ export function prepareTaskWorkspace(manifest: TeamRunManifest, task: TeamTaskSt
|
|
|
384
511
|
const dirtyStatus = git(worktreePath, ["status", "--porcelain"]);
|
|
385
512
|
if (dirtyStatus.trim()) {
|
|
386
513
|
// Discard uncommitted changes to ensure clean slate for new task
|
|
387
|
-
logInternalError(
|
|
514
|
+
logInternalError(
|
|
515
|
+
"worktree.reused.dirty",
|
|
516
|
+
new Error(`Discarding uncommitted changes in reused worktree at ${worktreePath}`),
|
|
517
|
+
`runId=${manifest.runId}, taskId=${task.id}, dirtyStatus=${dirtyStatus.trim()}`,
|
|
518
|
+
);
|
|
388
519
|
git(worktreePath, ["checkout", "--", "."]);
|
|
389
520
|
git(worktreePath, ["clean", "-fd"]);
|
|
390
521
|
}
|
|
@@ -406,7 +537,11 @@ export function prepareTaskWorkspace(manifest: TeamRunManifest, task: TeamTaskSt
|
|
|
406
537
|
git(repoRoot, ["worktree", "add", worktreePath, branch]);
|
|
407
538
|
} else {
|
|
408
539
|
if (exists.remoteOnly) {
|
|
409
|
-
logInternalError(
|
|
540
|
+
logInternalError(
|
|
541
|
+
"worktree.branchRemoteOnly",
|
|
542
|
+
new Error(`Branch '${branch}' exists only on remote; creating local from HEAD instead of tracking remote.`),
|
|
543
|
+
`branch=${branch}`,
|
|
544
|
+
);
|
|
410
545
|
}
|
|
411
546
|
git(repoRoot, ["worktree", "add", "-b", branch, worktreePath, "HEAD"]);
|
|
412
547
|
}
|
|
@@ -416,23 +551,35 @@ export function prepareTaskWorkspace(manifest: TeamRunManifest, task: TeamTaskSt
|
|
|
416
551
|
if (fs.existsSync(worktreePath)) {
|
|
417
552
|
try {
|
|
418
553
|
fs.rmSync(worktreePath, { recursive: true, force: true });
|
|
419
|
-
} catch {
|
|
554
|
+
} catch {
|
|
555
|
+
/* best-effort cleanup */
|
|
556
|
+
}
|
|
420
557
|
}
|
|
421
558
|
const msg = error instanceof Error ? error.message : String(error);
|
|
422
559
|
if (/already checked out|is already used by worktree/i.test(msg)) {
|
|
423
|
-
throw new Error(
|
|
560
|
+
throw new Error(
|
|
561
|
+
`Branch '${branch}' is checked out at another worktree. Run \`team cleanup runId=${manifest.runId} force=true\` or manually remove the conflicting worktree.`,
|
|
562
|
+
);
|
|
424
563
|
}
|
|
425
564
|
throw error;
|
|
426
565
|
}
|
|
427
566
|
const syntheticPaths = runSetupHook(manifest, task, repoRoot, worktreePath, branch);
|
|
428
|
-
const nodeModulesLinked =
|
|
567
|
+
const nodeModulesLinked =
|
|
568
|
+
loadedConfig.config.worktree?.linkNodeModules === true ? linkNodeModulesIfPresent(repoRoot, worktreePath) : false;
|
|
429
569
|
// Overlay seed paths from config + step-level seedPaths
|
|
430
570
|
const globalSeedPaths = loadedConfig.config.worktree?.seedPaths ?? [];
|
|
431
571
|
const merged = normalizeSeedPaths([...globalSeedPaths, ...(stepSeedPaths ?? [])], repoRoot);
|
|
432
572
|
if (merged.length > 0) {
|
|
433
573
|
overlaySeedPaths(repoRoot, worktreePath, merged);
|
|
434
574
|
}
|
|
435
|
-
return {
|
|
575
|
+
return {
|
|
576
|
+
cwd: worktreePath,
|
|
577
|
+
worktreePath,
|
|
578
|
+
branch,
|
|
579
|
+
reused: false,
|
|
580
|
+
nodeModulesLinked,
|
|
581
|
+
syntheticPaths,
|
|
582
|
+
};
|
|
436
583
|
}
|
|
437
584
|
|
|
438
585
|
export function captureWorktreeDiffStat(worktreePath: string): WorktreeDiffStat {
|
|
@@ -475,10 +622,7 @@ export function captureWorktreeDiff(worktreePath: string): string {
|
|
|
475
622
|
* Returns `undefined` when worktree creation is unavailable (no git repo, dirty
|
|
476
623
|
* leader, git error) so the caller (`ctx.agent`) can fall back gracefully.
|
|
477
624
|
*/
|
|
478
|
-
export function prepareAgentWorktree(
|
|
479
|
-
manifest: TeamRunManifest,
|
|
480
|
-
agentId: string,
|
|
481
|
-
): PreparedTaskWorkspace | undefined {
|
|
625
|
+
export function prepareAgentWorktree(manifest: TeamRunManifest, agentId: string): PreparedTaskWorkspace | undefined {
|
|
482
626
|
try {
|
|
483
627
|
const repoRoot = findGitRoot(manifest.cwd);
|
|
484
628
|
const loadedConfig = loadConfig(manifest.cwd);
|
|
@@ -491,9 +635,8 @@ export function prepareAgentWorktree(
|
|
|
491
635
|
const branch = `pi-crew/${sanitizedRunId}/${sanitizedAgentId}`;
|
|
492
636
|
pruneStaleWorktrees(repoRoot);
|
|
493
637
|
git(repoRoot, ["worktree", "add", "-b", branch, worktreePath, "HEAD"]);
|
|
494
|
-
const nodeModulesLinked =
|
|
495
|
-
? linkNodeModulesIfPresent(repoRoot, worktreePath)
|
|
496
|
-
: false;
|
|
638
|
+
const nodeModulesLinked =
|
|
639
|
+
loadedConfig.config.worktree?.linkNodeModules === true ? linkNodeModulesIfPresent(repoRoot, worktreePath) : false;
|
|
497
640
|
return { cwd: worktreePath, worktreePath, branch, nodeModulesLinked };
|
|
498
641
|
} catch {
|
|
499
642
|
// Graceful fallback: no git repo, dirty leader, or git error → run normally.
|