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,20 +1,20 @@
|
|
|
1
1
|
import { loadConfig } from "../../config/config.ts";
|
|
2
|
-
import type { TeamToolParamsValue } from "../../schema/team-tool-schema.ts";
|
|
3
|
-
import { appendEvent, readEvents } from "../../state/event-log.ts";
|
|
4
|
-
import { readDeliveryState, readMailbox } from "../../state/mailbox.ts";
|
|
5
|
-
import { loadRunManifestById, updateRunStatus, saveRunTasks } from "../../state/state-store.ts";
|
|
6
|
-
import { aggregateUsage, formatUsage, formatCost } from "../../state/usage.ts";
|
|
7
2
|
import { applyAttentionState, formatActivityAge, resolveCrewControlConfig } from "../../runtime/agent-control.ts";
|
|
3
|
+
import { extractCommandTrace } from "../../runtime/command-trace.ts";
|
|
4
|
+
import { verifyTaskCompletion } from "../../runtime/completion-guard.ts";
|
|
8
5
|
import { readCrewAgents } from "../../runtime/crew-agent-records.ts";
|
|
6
|
+
import { evaluateRunEffectiveness } from "../../runtime/effectiveness.ts";
|
|
7
|
+
import { computePhaseProgress } from "../../runtime/phase-progress.ts";
|
|
9
8
|
import { checkProcessLiveness, isActiveRunStatus } from "../../runtime/process-status.ts";
|
|
10
9
|
import { formatTaskGraphLines, waitingReason } from "../../runtime/task-display.ts";
|
|
11
|
-
import {
|
|
10
|
+
import type { TeamToolParamsValue } from "../../schema/team-tool-schema.ts";
|
|
11
|
+
import { appendEvent, readEvents } from "../../state/event-log.ts";
|
|
12
|
+
import { readDeliveryState, readMailbox } from "../../state/mailbox.ts";
|
|
13
|
+
import { loadRunManifestById, saveRunTasks, updateRunStatus } from "../../state/state-store.ts";
|
|
14
|
+
import { aggregateUsage, formatCost, formatUsage } from "../../state/usage.ts";
|
|
12
15
|
import { formatDuration } from "../../ui/tool-render.ts";
|
|
13
|
-
import { verifyTaskCompletion } from "../../runtime/completion-guard.ts";
|
|
14
|
-
import { evaluateRunEffectiveness } from "../../runtime/effectiveness.ts";
|
|
15
|
-
import { extractCommandTrace } from "../../runtime/command-trace.ts";
|
|
16
|
-
import type { PiTeamsToolResult } from "../tool-result.ts";
|
|
17
16
|
import { locateRunCwd } from "../team-tool.ts";
|
|
17
|
+
import type { PiTeamsToolResult } from "../tool-result.ts";
|
|
18
18
|
import { result, type TeamContext } from "./context.ts";
|
|
19
19
|
import { RUN_NOT_FOUND_HINT } from "./run-not-found.ts";
|
|
20
20
|
|
|
@@ -36,9 +36,23 @@ export function handleStatus(params: TeamToolParamsValue, ctx: TeamContext): PiT
|
|
|
36
36
|
asyncLivenessLine = `Async: pid=${asyncState.pid ?? "unknown"} alive=${liveness.alive ? "true" : "false"} detail=${liveness.detail} log=${asyncState.logPath} spawnedAt=${asyncState.spawnedAt}`;
|
|
37
37
|
if (!liveness.alive && isActiveRunStatus(manifest.status)) {
|
|
38
38
|
manifest = updateRunStatus(manifest, "failed", `Async process stale: ${liveness.detail}`);
|
|
39
|
-
tasks = tasks.map((task) =>
|
|
39
|
+
tasks = tasks.map((task) =>
|
|
40
|
+
task.status === "running"
|
|
41
|
+
? {
|
|
42
|
+
...task,
|
|
43
|
+
status: "cancelled" as const,
|
|
44
|
+
finishedAt: new Date().toISOString(),
|
|
45
|
+
error: "Async process died; task was not completed.",
|
|
46
|
+
}
|
|
47
|
+
: task,
|
|
48
|
+
);
|
|
40
49
|
saveRunTasks(manifest, tasks);
|
|
41
|
-
appendEvent(manifest.eventsPath, {
|
|
50
|
+
appendEvent(manifest.eventsPath, {
|
|
51
|
+
type: "async.stale",
|
|
52
|
+
runId: manifest.runId,
|
|
53
|
+
message: liveness.detail,
|
|
54
|
+
data: { pid: asyncState.pid },
|
|
55
|
+
});
|
|
42
56
|
}
|
|
43
57
|
}
|
|
44
58
|
const counts = new Map<string, number>();
|
|
@@ -46,32 +60,64 @@ export function handleStatus(params: TeamToolParamsValue, ctx: TeamContext): PiT
|
|
|
46
60
|
const phaseProgress = computePhaseProgress(tasks);
|
|
47
61
|
const allEvents = readEvents(manifest.eventsPath);
|
|
48
62
|
const events = allEvents.slice(-8);
|
|
49
|
-
const attentionByTask = new Map(
|
|
63
|
+
const attentionByTask = new Map(
|
|
64
|
+
allEvents.filter((event) => event.type === "task.attention" && event.taskId).map((event) => [event.taskId!, event]),
|
|
65
|
+
);
|
|
50
66
|
const controlConfig = resolveCrewControlConfig(loadConfig(ctx.cwd).config);
|
|
51
67
|
const crewAgents = readCrewAgents(manifest).map((agent) => applyAttentionState(manifest, agent, controlConfig));
|
|
52
|
-
const artifactLines = manifest.artifacts
|
|
68
|
+
const artifactLines = manifest.artifacts
|
|
69
|
+
.slice(-10)
|
|
70
|
+
.map(
|
|
71
|
+
(artifact) => `- ${artifact.kind}: ${artifact.path}${artifact.sizeBytes !== undefined ? ` (${artifact.sizeBytes} bytes)` : ""}`,
|
|
72
|
+
);
|
|
53
73
|
const deliveryState = readDeliveryState(manifest);
|
|
54
74
|
const ackTimeoutMs = loadConfig(ctx.cwd).config.runtime?.groupJoinAckTimeoutMs;
|
|
55
75
|
const groupJoinLines: string[] = [];
|
|
56
|
-
for (const message of readMailbox(manifest, "outbox")
|
|
76
|
+
for (const message of readMailbox(manifest, "outbox")
|
|
77
|
+
.filter((m) => m.data?.kind === "group_join")
|
|
78
|
+
.slice(-5)) {
|
|
57
79
|
const ack = deliveryState.messages[message.id] === "acknowledged" ? "acknowledged" : "pending";
|
|
58
80
|
const ageMs = Date.now() - new Date(message.createdAt).getTime();
|
|
59
81
|
const requestId = String(message.data?.requestId ?? "unknown");
|
|
60
82
|
const timedOut = ack === "pending" && ackTimeoutMs !== undefined && Number.isFinite(ageMs) && ageMs > ackTimeoutMs;
|
|
61
83
|
if (timedOut && !allEvents.some((event) => event.type === "agent.group_join.ack_timeout" && event.data?.requestId === requestId)) {
|
|
62
|
-
appendEvent(manifest.eventsPath, {
|
|
84
|
+
appendEvent(manifest.eventsPath, {
|
|
85
|
+
type: "agent.group_join.ack_timeout",
|
|
86
|
+
runId: manifest.runId,
|
|
87
|
+
message: "Group join delivery ack timed out; mailbox delivery remains the fallback.",
|
|
88
|
+
data: {
|
|
89
|
+
requestId,
|
|
90
|
+
messageId: message.id,
|
|
91
|
+
batchId: message.data?.batchId,
|
|
92
|
+
partial: message.data?.partial,
|
|
93
|
+
ageMs,
|
|
94
|
+
ackTimeoutMs,
|
|
95
|
+
},
|
|
96
|
+
});
|
|
63
97
|
}
|
|
64
|
-
groupJoinLines.push(
|
|
98
|
+
groupJoinLines.push(
|
|
99
|
+
`- ${String(message.data?.partial) === "true" ? "partial" : "completed"} request=${requestId} message=${message.id} ack=${timedOut ? "timeout" : ack}`,
|
|
100
|
+
);
|
|
65
101
|
}
|
|
66
102
|
const totalUsage = aggregateUsage(tasks);
|
|
67
103
|
const completedTasks = tasks.filter((task) => task.status === "completed");
|
|
68
|
-
const effectiveness = evaluateRunEffectiveness({
|
|
69
|
-
|
|
70
|
-
|
|
104
|
+
const effectiveness = evaluateRunEffectiveness({
|
|
105
|
+
manifest,
|
|
106
|
+
tasks,
|
|
107
|
+
executeWorkers: manifest.runtimeResolution?.kind !== "scaffold",
|
|
108
|
+
runtimeConfig: loadConfig(ctx.cwd).config.runtime,
|
|
109
|
+
});
|
|
110
|
+
const noObservedWorkTasks = effectiveness.noObservedWorkTaskIds
|
|
111
|
+
.map((id) => tasks.find((task) => task.id === id))
|
|
112
|
+
.filter((task): task is (typeof tasks)[number] => task !== undefined);
|
|
113
|
+
const attentionTasks = effectiveness.needsAttentionTaskIds
|
|
114
|
+
.map((id) => tasks.find((task) => task.id === id))
|
|
115
|
+
.filter((task): task is (typeof tasks)[number] => task !== undefined);
|
|
71
116
|
const activeAgents = crewAgents.filter((agent) => agent.status === "running");
|
|
72
117
|
const completedAgents = crewAgents.filter((agent) => agent.status !== "running");
|
|
73
118
|
const waitingTasks = tasks.filter((task) => task.status === "queued" || task.status === "waiting");
|
|
74
|
-
const agentLine = (agent: typeof crewAgents[number]): string =>
|
|
119
|
+
const agentLine = (agent: (typeof crewAgents)[number]): string =>
|
|
120
|
+
`- ${agent.id} [${agent.status}] ${agent.role} -> ${agent.agent} runtime=${agent.runtime}${agent.model ? ` model=${agent.model}` : ""}${agent.usage ? ` usage=${formatUsage(agent.usage)}` : ""}${agent.usage?.cost ? ` cost=${formatCost(agent.usage.cost)}` : ""}${agent.progress?.activityState ? ` activityState=${agent.progress.activityState}` : ""}${formatActivityAge(agent) ? ` activity=${formatActivityAge(agent)}` : ""}${agent.progress?.currentTool ? ` tool=${agent.progress.currentTool}` : ""}${agent.toolUses ? ` tools=${agent.toolUses}` : ""}${!agent.usage && agent.progress?.tokens ? ` tokens=${agent.progress.tokens}` : ""}${agent.progress?.turns ? ` turns=${agent.progress.turns}` : ""}${agent.jsonEvents !== undefined ? ` jsonEvents=${agent.jsonEvents}` : ""}${agent.outputPath ? ` output=${agent.outputPath}` : ""}${agent.transcriptPath ? ` transcript=${agent.transcriptPath}` : ""}${agent.statusPath ? ` status=${agent.statusPath}` : ""}${agent.error ? ` error=${agent.error}` : ""}`;
|
|
75
121
|
const lines = [
|
|
76
122
|
`Run: ${manifest.runId}`,
|
|
77
123
|
`Team: ${manifest.team}`,
|
|
@@ -79,7 +125,13 @@ export function handleStatus(params: TeamToolParamsValue, ctx: TeamContext): PiT
|
|
|
79
125
|
`Status: ${manifest.status}`,
|
|
80
126
|
`Progress: ${phaseProgress.overallPercentage}% (~${formatDuration(phaseProgress.estimatedRemainingMs)} remaining)`,
|
|
81
127
|
`Workspace mode: ${manifest.workspaceMode}`,
|
|
82
|
-
...(manifest.runtimeResolution
|
|
128
|
+
...(manifest.runtimeResolution
|
|
129
|
+
? [
|
|
130
|
+
`Runtime: ${manifest.runtimeResolution.kind}`,
|
|
131
|
+
`Runtime safety: ${manifest.runtimeResolution.safety}`,
|
|
132
|
+
`Runtime requested: ${manifest.runtimeResolution.requestedMode}${manifest.runtimeResolution.reason ? ` (${manifest.runtimeResolution.reason})` : ""}`,
|
|
133
|
+
]
|
|
134
|
+
: []),
|
|
83
135
|
`Goal: ${manifest.goal}`,
|
|
84
136
|
`Created: ${manifest.createdAt}`,
|
|
85
137
|
`Updated: ${manifest.updatedAt}`,
|
|
@@ -89,7 +141,15 @@ export function handleStatus(params: TeamToolParamsValue, ctx: TeamContext): PiT
|
|
|
89
141
|
"Task graph:",
|
|
90
142
|
...formatTaskGraphLines(tasks),
|
|
91
143
|
"Tasks:",
|
|
92
|
-
...(tasks.length
|
|
144
|
+
...(tasks.length
|
|
145
|
+
? tasks.map(
|
|
146
|
+
(task) =>
|
|
147
|
+
`- ${task.id} [${task.status}] ${task.role} -> ${task.agent}${task.taskPacket ? ` scope=${task.taskPacket.scope}` : ""}${task.verification ? ` green=${task.verification.observedGreenLevel}/${task.verification.requiredGreenLevel}` : ""}${task.modelAttempts?.length ? ` attempts=${task.modelAttempts.length}` : ""}${task.modelRouting ? ` modelRouting=${task.modelRouting.requested ? `${task.modelRouting.requested}->` : ""}${task.modelRouting.resolved}${task.modelRouting.usedAttempt ? ` attempt=${task.modelRouting.usedAttempt + 1}` : ""}` : ""}${task.agentProgress?.activityState ? ` activityState=${task.agentProgress.activityState}` : ""}${(() => {
|
|
148
|
+
const t = extractCommandTrace(task.agentProgress?.recentTools);
|
|
149
|
+
return t.summary ? ` ${t.summary}` : "";
|
|
150
|
+
})()}${attentionByTask.get(task.id)?.data?.reason ? ` attention=${String(attentionByTask.get(task.id)?.data?.reason)}` : ""}${task.jsonEvents !== undefined ? ` jsonEvents=${task.jsonEvents}` : ""}${task.usage ? ` usage=${JSON.stringify(task.usage)}` : ""}${task.resultArtifact ? ` result=${task.resultArtifact.path}` : ""}${task.transcriptArtifact ? ` transcript=${task.transcriptArtifact.path}` : ""}${task.worktree ? ` worktree=${task.worktree.path}` : ""}${task.error ? ` error=${task.error}` : ""}`,
|
|
151
|
+
)
|
|
152
|
+
: ["- (none)"]),
|
|
93
153
|
`Task counts: ${[...counts.entries()].map(([status, count]) => `${status}=${count}`).join(", ") || "none"}`,
|
|
94
154
|
"Effectiveness:",
|
|
95
155
|
`- observable=${effectiveness.observable}/${Math.max(1, effectiveness.completed)} completed tasks`,
|
|
@@ -97,18 +157,28 @@ export function handleStatus(params: TeamToolParamsValue, ctx: TeamContext): PiT
|
|
|
97
157
|
`- noObservedWork=${effectiveness.noObservedWorkTaskIds.length ? effectiveness.noObservedWorkTaskIds.join(",") : "none"}`,
|
|
98
158
|
`- needsAttention=${effectiveness.needsAttentionTaskIds.length ? effectiveness.needsAttentionTaskIds.join(",") : "none"}`,
|
|
99
159
|
"Completion verification",
|
|
100
|
-
...(tasks.filter((t) => t.status === "completed").length
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
160
|
+
...(tasks.filter((t) => t.status === "completed").length
|
|
161
|
+
? tasks
|
|
162
|
+
.filter((t) => t.status === "completed")
|
|
163
|
+
.map((t) => {
|
|
164
|
+
const guard = verifyTaskCompletion(t, manifest);
|
|
165
|
+
return `- ${t.id} green=${guard.greenLevel}/3${guard.warnings.length ? ` warnings=[${guard.warnings.join(", ")}]` : ""}`;
|
|
166
|
+
})
|
|
167
|
+
: ["- (no completed tasks)"]),
|
|
104
168
|
"Active agents:",
|
|
105
169
|
...(activeAgents.length ? activeAgents.map(agentLine) : ["- (none)"]),
|
|
106
170
|
"Waiting tasks:",
|
|
107
|
-
...(waitingTasks.length
|
|
171
|
+
...(waitingTasks.length
|
|
172
|
+
? waitingTasks.map((task) => `- ${task.id} [queued] ${task.role} -> ${task.agent} ${waitingReason(task, tasks) ?? "waiting"}`)
|
|
173
|
+
: ["- (none)"]),
|
|
108
174
|
"Completed agents:",
|
|
109
175
|
...(completedAgents.length ? completedAgents.map(agentLine) : ["- (none)"]),
|
|
110
176
|
"Policy decisions:",
|
|
111
|
-
...(manifest.policyDecisions?.length
|
|
177
|
+
...(manifest.policyDecisions?.length
|
|
178
|
+
? manifest.policyDecisions.map(
|
|
179
|
+
(item) => `- ${item.action} (${item.reason})${item.taskId ? ` ${item.taskId}` : ""}: ${item.message}`,
|
|
180
|
+
)
|
|
181
|
+
: ["- (none)"]),
|
|
112
182
|
`Total usage: ${formatUsage(totalUsage)}`,
|
|
113
183
|
"Group joins:",
|
|
114
184
|
...(groupJoinLines.length ? groupJoinLines : ["- (none)"]),
|
|
@@ -117,15 +187,29 @@ export function handleStatus(params: TeamToolParamsValue, ctx: TeamContext): PiT
|
|
|
117
187
|
...(artifactLines.length ? artifactLines : ["- (none)"]),
|
|
118
188
|
"",
|
|
119
189
|
"Recent events:",
|
|
120
|
-
...(events.length
|
|
190
|
+
...(events.length
|
|
191
|
+
? events.map(
|
|
192
|
+
(event) =>
|
|
193
|
+
`- ${event.time} ${event.type}${event.taskId ? ` ${event.taskId}` : ""}${event.message ? `: ${event.message}` : ""}`,
|
|
194
|
+
)
|
|
195
|
+
: ["- (none)"]),
|
|
121
196
|
];
|
|
122
197
|
if (!fullDetails) {
|
|
123
|
-
return result(
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
198
|
+
return result(buildCompactStatus(manifest, tasks, counts, asyncLivenessLine, phaseProgress).join("\n"), {
|
|
199
|
+
action: "status",
|
|
200
|
+
status: "ok",
|
|
201
|
+
runId: manifest.runId,
|
|
202
|
+
artifactsRoot: manifest.artifactsRoot,
|
|
203
|
+
intent: `status ${manifest.runId}: ${manifest.status} (compact)`,
|
|
204
|
+
});
|
|
127
205
|
}
|
|
128
|
-
return result(lines.join("\n"), {
|
|
206
|
+
return result(lines.join("\n"), {
|
|
207
|
+
action: "status",
|
|
208
|
+
status: "ok",
|
|
209
|
+
runId: manifest.runId,
|
|
210
|
+
artifactsRoot: manifest.artifactsRoot,
|
|
211
|
+
intent: `status ${manifest.runId}: ${manifest.status}`,
|
|
212
|
+
});
|
|
129
213
|
}
|
|
130
214
|
|
|
131
215
|
/**
|
|
@@ -136,18 +220,26 @@ export function handleStatus(params: TeamToolParamsValue, ctx: TeamContext): PiT
|
|
|
136
220
|
* Exported for unit testing.
|
|
137
221
|
*/
|
|
138
222
|
export function buildCompactStatus(
|
|
139
|
-
manifest: {
|
|
140
|
-
|
|
223
|
+
manifest: {
|
|
224
|
+
runId: string;
|
|
225
|
+
team: string;
|
|
226
|
+
workflow?: string;
|
|
227
|
+
status: string;
|
|
228
|
+
goal: string;
|
|
229
|
+
workspaceMode?: string;
|
|
230
|
+
},
|
|
231
|
+
tasks: Array<{
|
|
232
|
+
id: string;
|
|
233
|
+
status: string;
|
|
234
|
+
role: string;
|
|
235
|
+
agent: string;
|
|
236
|
+
error?: string;
|
|
237
|
+
}>,
|
|
141
238
|
counts: Map<string, number>,
|
|
142
239
|
asyncLivenessLine?: string,
|
|
143
240
|
progress?: { overallPercentage: number; estimatedRemainingMs: number },
|
|
144
241
|
): string[] {
|
|
145
|
-
const failedOrAttention = tasks.filter(
|
|
146
|
-
(t) =>
|
|
147
|
-
t.status === "failed" ||
|
|
148
|
-
t.status === "needs_attention" ||
|
|
149
|
-
t.status === "cancelled",
|
|
150
|
-
);
|
|
242
|
+
const failedOrAttention = tasks.filter((t) => t.status === "failed" || t.status === "needs_attention" || t.status === "cancelled");
|
|
151
243
|
const lines = [
|
|
152
244
|
`Run: ${manifest.runId}`,
|
|
153
245
|
`Team: ${manifest.team}${manifest.workflow ? ` (${manifest.workflow})` : ""}`,
|
|
@@ -14,24 +14,20 @@
|
|
|
14
14
|
* - workflow-delete : remove a dynamic workflow file (confirm-gated).
|
|
15
15
|
*/
|
|
16
16
|
|
|
17
|
-
import {
|
|
18
|
-
import { dirname, join
|
|
19
|
-
import {
|
|
17
|
+
import { existsSync, readFileSync, rmSync, writeFileSync } from "node:fs";
|
|
18
|
+
import { basename, dirname, join } from "node:path";
|
|
19
|
+
import type { TeamToolParamsValue } from "../../schema/team-tool-schema.ts";
|
|
20
|
+
import { logInternalError } from "../../utils/internal-error.ts";
|
|
21
|
+
import { packageRoot, projectCrewRoot, userPiRoot } from "../../utils/paths.ts";
|
|
20
22
|
import { assertSafePathId, resolveRealContainedPath } from "../../utils/safe-paths.ts";
|
|
21
|
-
import { projectCrewRoot, userPiRoot, packageRoot } from "../../utils/paths.ts";
|
|
22
23
|
import { allWorkflows, discoverWorkflows } from "../../workflows/discover-workflows.ts";
|
|
23
|
-
import {
|
|
24
|
-
import type { TeamToolParamsValue } from "../../schema/team-tool-schema.ts";
|
|
24
|
+
import { result, type TeamContext } from "./context.ts";
|
|
25
25
|
|
|
26
26
|
/** The 3 allowed bases for dynamic-workflow scripts (§0c C5). */
|
|
27
27
|
function allowedWorkflowDirs(cwd: string): string[] {
|
|
28
28
|
// Fix round-6: align with discoverWorkflows (which reads userPiRoot/workflows, NOT
|
|
29
29
|
// userCrewRoot/workflows). The old userCrewRoot path silently orphaned user-scope workflows.
|
|
30
|
-
return [
|
|
31
|
-
join(projectCrewRoot(cwd), "workflows"),
|
|
32
|
-
join(userPiRoot(), "workflows"),
|
|
33
|
-
join(packageRoot(), "workflows"),
|
|
34
|
-
];
|
|
30
|
+
return [join(projectCrewRoot(cwd), "workflows"), join(userPiRoot(), "workflows"), join(packageRoot(), "workflows")];
|
|
35
31
|
}
|
|
36
32
|
|
|
37
33
|
/** Best-effort ADVISORY content check (review H-3): trivially bypassable
|
|
@@ -70,12 +66,20 @@ export function handleWorkflowCreate(params: TeamToolParamsValue, ctx: TeamConte
|
|
|
70
66
|
// runs (the run is blocked at the tool_call layer if confirm is missing). We re-check here
|
|
71
67
|
// as defense-in-depth in case the gate is bypassed.
|
|
72
68
|
if (params.confirm !== true) {
|
|
73
|
-
return result(
|
|
69
|
+
return result(
|
|
70
|
+
"workflow-create is a new arbitrary-code-execution surface and requires confirm:true. Add the action to DESTRUCTIVE_TEAM_ACTIONS (destructive-gate.ts) so the runtime gate enforces this.",
|
|
71
|
+
{ action: "workflow-create", status: "error" },
|
|
72
|
+
true,
|
|
73
|
+
);
|
|
74
74
|
}
|
|
75
75
|
const name = params.config?.name as string | undefined;
|
|
76
76
|
const script = params.config?.script as string | undefined;
|
|
77
77
|
if (!name || typeof name !== "string") {
|
|
78
|
-
return result(
|
|
78
|
+
return result(
|
|
79
|
+
"workflow-create requires config.name (the workflow name, path-safe).",
|
|
80
|
+
{ action: "workflow-create", status: "error" },
|
|
81
|
+
true,
|
|
82
|
+
);
|
|
79
83
|
}
|
|
80
84
|
if (!script || typeof script !== "string") {
|
|
81
85
|
return result("workflow-create requires config.script (the .dwf.ts source).", { action: "workflow-create", status: "error" }, true);
|
|
@@ -88,7 +92,15 @@ export function handleWorkflowCreate(params: TeamToolParamsValue, ctx: TeamConte
|
|
|
88
92
|
const scope = (params.scope === "user" ? "user" : "project") as "user" | "project";
|
|
89
93
|
const filePath = resolveWorkflowWritePath(ctx.cwd, name, scope);
|
|
90
94
|
writeFileSync(filePath, script, "utf-8");
|
|
91
|
-
return result(
|
|
95
|
+
return result(
|
|
96
|
+
`Dynamic workflow '${name}' created at ${filePath}.\n\nIt is now runnable via: team action='run' workflow='${name}' goal='...'\n/scripts are commit-reviewed (postinstall-equivalent trust — see docs/dynamic-workflows.md).`,
|
|
97
|
+
{
|
|
98
|
+
action: "workflow-create",
|
|
99
|
+
status: "ok",
|
|
100
|
+
data: { name, filePath, scope },
|
|
101
|
+
},
|
|
102
|
+
false,
|
|
103
|
+
);
|
|
92
104
|
} catch (error) {
|
|
93
105
|
const message = error instanceof Error ? error.message : String(error);
|
|
94
106
|
return result(`workflow-create failed: ${message}`, { action: "workflow-create", status: "error" }, true);
|
|
@@ -121,8 +133,18 @@ export function handleWorkflowGet(params: TeamToolParamsValue, ctx: TeamContext)
|
|
|
121
133
|
isDynamic ? "```" : "",
|
|
122
134
|
isDynamic ? source : "",
|
|
123
135
|
isDynamic ? "```" : "",
|
|
124
|
-
]
|
|
125
|
-
|
|
136
|
+
]
|
|
137
|
+
.filter(Boolean)
|
|
138
|
+
.join("\n"),
|
|
139
|
+
{
|
|
140
|
+
action: "workflow-get",
|
|
141
|
+
status: "ok",
|
|
142
|
+
data: {
|
|
143
|
+
name: wf.name,
|
|
144
|
+
runtime: wf.runtime ?? "static",
|
|
145
|
+
filePath: wf.filePath,
|
|
146
|
+
},
|
|
147
|
+
},
|
|
126
148
|
false,
|
|
127
149
|
);
|
|
128
150
|
}
|
|
@@ -132,29 +154,52 @@ export function handleWorkflowList(params: TeamToolParamsValue, ctx: TeamContext
|
|
|
132
154
|
if (workflows.length === 0) return result("No workflows found.", { action: "workflow-list", status: "ok" }, false);
|
|
133
155
|
const lines = workflows.map((w) => {
|
|
134
156
|
const tag = w.runtime === "dynamic" ? "[dynamic]" : "[static] ";
|
|
135
|
-
const detail = w.runtime === "dynamic" ? w.dynamicScript ?? w.filePath : `${w.steps.length} steps`;
|
|
157
|
+
const detail = w.runtime === "dynamic" ? (w.dynamicScript ?? w.filePath) : `${w.steps.length} steps`;
|
|
136
158
|
return ` ${tag} ${w.name.padEnd(20)} ${detail}`;
|
|
137
159
|
});
|
|
138
|
-
return result(
|
|
160
|
+
return result(
|
|
161
|
+
`Workflows (${workflows.length}):\n${lines.join("\n")}`,
|
|
162
|
+
{
|
|
163
|
+
action: "workflow-list",
|
|
164
|
+
status: "ok",
|
|
165
|
+
data: {
|
|
166
|
+
count: workflows.length,
|
|
167
|
+
workflows: workflows.map((w) => ({
|
|
168
|
+
name: w.name,
|
|
169
|
+
runtime: w.runtime ?? "static",
|
|
170
|
+
})),
|
|
171
|
+
},
|
|
172
|
+
},
|
|
173
|
+
false,
|
|
174
|
+
);
|
|
139
175
|
}
|
|
140
176
|
|
|
141
177
|
export function handleWorkflowSave(params: TeamToolParamsValue, ctx: TeamContext): ReturnType<typeof result> {
|
|
142
178
|
// H-1 (review): workflow-save writes an arbitrary .dwf.ts (ACE-equivalent) — gate it
|
|
143
179
|
// via destructive-gate.ts confirm:true (now in DESTRUCTIVE_TEAM_ACTIONS) + re-check here.
|
|
144
180
|
if (params.confirm !== true) {
|
|
145
|
-
return result(
|
|
181
|
+
return result(
|
|
182
|
+
"workflow-save writes an executable .dwf.ts and requires confirm:true (gated by destructive-gate.ts).",
|
|
183
|
+
{ action: "workflow-save", status: "error" },
|
|
184
|
+
true,
|
|
185
|
+
);
|
|
146
186
|
}
|
|
147
187
|
// workflow-save: persist an ephemeral run's script as a named reusable workflow.
|
|
148
188
|
// Reads the source from config.script (the caller provides what to save).
|
|
149
189
|
const name = params.config?.name as string | undefined;
|
|
150
190
|
const script = params.config?.script as string | undefined;
|
|
151
|
-
if (!name || !script)
|
|
191
|
+
if (!name || !script)
|
|
192
|
+
return result("workflow-save requires config.name + config.script.", { action: "workflow-save", status: "error" }, true);
|
|
152
193
|
const validationError = validateScriptContent(script);
|
|
153
194
|
if (validationError) return result(`workflow-save rejected: ${validationError}`, { action: "workflow-save", status: "error" }, true);
|
|
154
195
|
try {
|
|
155
196
|
const filePath = resolveWorkflowWritePath(ctx.cwd, name, "project");
|
|
156
197
|
writeFileSync(filePath, script, "utf-8");
|
|
157
|
-
return result(
|
|
198
|
+
return result(
|
|
199
|
+
`Saved dynamic workflow '${name}' → ${filePath}.`,
|
|
200
|
+
{ action: "workflow-save", status: "ok", data: { name, filePath } },
|
|
201
|
+
false,
|
|
202
|
+
);
|
|
158
203
|
} catch (error) {
|
|
159
204
|
const message = error instanceof Error ? error.message : String(error);
|
|
160
205
|
return result(`workflow-save failed: ${message}`, { action: "workflow-save", status: "error" }, true);
|
|
@@ -164,13 +209,22 @@ export function handleWorkflowSave(params: TeamToolParamsValue, ctx: TeamContext
|
|
|
164
209
|
export function handleWorkflowDelete(params: TeamToolParamsValue, ctx: TeamContext): ReturnType<typeof result> {
|
|
165
210
|
// workflow-delete is destructive (removes a file) — gated by destructive-gate.ts confirm:true.
|
|
166
211
|
if (params.confirm !== true) {
|
|
167
|
-
return result(
|
|
212
|
+
return result(
|
|
213
|
+
"workflow-delete requires confirm:true (gated by destructive-gate.ts).",
|
|
214
|
+
{ action: "workflow-delete", status: "error" },
|
|
215
|
+
true,
|
|
216
|
+
);
|
|
168
217
|
}
|
|
169
218
|
const name = (params.config?.name as string | undefined) ?? params.workflow;
|
|
170
219
|
if (!name) return result("workflow-delete requires config.name.", { action: "workflow-delete", status: "error" }, true);
|
|
171
220
|
const wf = allWorkflows(discoverWorkflows(ctx.cwd)).find((w) => w.name === name);
|
|
172
221
|
if (!wf) return result(`Workflow '${name}' not found.`, { action: "workflow-delete", status: "error" }, true);
|
|
173
|
-
if (wf.runtime !== "dynamic")
|
|
222
|
+
if (wf.runtime !== "dynamic")
|
|
223
|
+
return result(
|
|
224
|
+
`Workflow '${name}' is not a dynamic workflow (only .dwf.ts files can be deleted via this action).`,
|
|
225
|
+
{ action: "workflow-delete", status: "error" },
|
|
226
|
+
true,
|
|
227
|
+
);
|
|
174
228
|
try {
|
|
175
229
|
assertSafePathId("workflowName", name);
|
|
176
230
|
// Verify the file is inside an allowed dir before deleting.
|
|
@@ -182,9 +236,22 @@ export function handleWorkflowDelete(params: TeamToolParamsValue, ctx: TeamConte
|
|
|
182
236
|
return false;
|
|
183
237
|
}
|
|
184
238
|
});
|
|
185
|
-
if (!contained)
|
|
239
|
+
if (!contained)
|
|
240
|
+
return result(
|
|
241
|
+
`Refusing to delete '${wf.filePath}': not inside an allowed workflows directory.`,
|
|
242
|
+
{ action: "workflow-delete", status: "error" },
|
|
243
|
+
true,
|
|
244
|
+
);
|
|
186
245
|
rmSync(wf.filePath, { force: true });
|
|
187
|
-
return result(
|
|
246
|
+
return result(
|
|
247
|
+
`Deleted dynamic workflow '${name}' (${wf.filePath}).`,
|
|
248
|
+
{
|
|
249
|
+
action: "workflow-delete",
|
|
250
|
+
status: "ok",
|
|
251
|
+
data: { name, filePath: wf.filePath },
|
|
252
|
+
},
|
|
253
|
+
false,
|
|
254
|
+
);
|
|
188
255
|
} catch (error) {
|
|
189
256
|
const message = error instanceof Error ? error.message : String(error);
|
|
190
257
|
return result(`workflow-delete failed: ${message}`, { action: "workflow-delete", status: "error" }, true);
|
|
@@ -13,7 +13,14 @@ export interface TeamToolDetails {
|
|
|
13
13
|
/** Resource scope affected by the action (e.g. cleanup: "project"). */
|
|
14
14
|
scope?: string;
|
|
15
15
|
/** Run metrics for compact display in TUI tool result rendering. */
|
|
16
|
-
metrics?: {
|
|
16
|
+
metrics?: {
|
|
17
|
+
taskCount?: number;
|
|
18
|
+
completedCount?: number;
|
|
19
|
+
totalTokens?: number;
|
|
20
|
+
totalCost?: number;
|
|
21
|
+
durationMs?: number;
|
|
22
|
+
consistencyScore?: number;
|
|
23
|
+
};
|
|
17
24
|
/** Structured data for programmatic consumption (e.g. TUI widgets). */
|
|
18
25
|
data?: Record<string, unknown>;
|
|
19
26
|
}
|