pi-crew 0.9.15 → 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 +145 -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 +193 -40
- 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 +86 -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
package/src/ui/run-dashboard.ts
CHANGED
|
@@ -1,32 +1,32 @@
|
|
|
1
1
|
import * as fs from "node:fs";
|
|
2
|
-
import type {
|
|
2
|
+
import type { MetricRegistry } from "../observability/metric-registry.ts";
|
|
3
3
|
import { readCrewAgents } from "../runtime/crew-agent-records.ts";
|
|
4
|
-
import { getLiveAgentContextPercent } from "../runtime/live-agent-manager.ts";
|
|
5
4
|
import type { CrewAgentRecord } from "../runtime/crew-agent-runtime.ts";
|
|
5
|
+
import { getLiveAgentContextPercent } from "../runtime/live-agent-manager.ts";
|
|
6
6
|
import { isDisplayActiveRun, isLikelyOrphanedActiveRun } from "../runtime/process-status.ts";
|
|
7
|
-
import {
|
|
8
|
-
import type { CrewTheme } from "./theme-adapter.ts";
|
|
9
|
-
import { asCrewTheme, subscribeThemeChange } from "./theme-adapter.ts";
|
|
10
|
-
import { applyStatusColor, colorizeStatusGlyphs, iconForStatus, type RunStatus } from "./status-colors.ts";
|
|
11
|
-
import { pad, truncate, sanitizeLine, visibleWidth } from "../utils/visual.ts";
|
|
12
|
-
import { Box, Text } from "./layout-primitives.ts";
|
|
13
|
-
import { DynamicCrewBorder } from "./dynamic-border.ts";
|
|
7
|
+
import type { TeamRunManifest, TeamTaskState, UsageState } from "../state/types.ts";
|
|
14
8
|
import { aggregateUsage } from "../state/usage.ts";
|
|
9
|
+
import { readJsonFileCoalesced } from "../utils/file-coalescer.ts";
|
|
15
10
|
import { logInternalError } from "../utils/internal-error.ts";
|
|
11
|
+
import { resolveRealContainedPath } from "../utils/safe-paths.ts";
|
|
12
|
+
import { pad, sanitizeLine, truncate, visibleWidth } from "../utils/visual.ts";
|
|
16
13
|
import { renderAgentsPane } from "./dashboard-panes/agents-pane.ts";
|
|
14
|
+
import { summarizeTerminalReason } from "./dashboard-panes/cancellation-pane.ts";
|
|
15
|
+
import { renderHealthPane } from "./dashboard-panes/health-pane.ts";
|
|
17
16
|
import { renderMailboxPane } from "./dashboard-panes/mailbox-pane.ts";
|
|
17
|
+
import { renderMetricsPane } from "./dashboard-panes/metrics-pane.ts";
|
|
18
18
|
import { renderProgressPane } from "./dashboard-panes/progress-pane.ts";
|
|
19
19
|
import { renderTranscriptPane } from "./dashboard-panes/transcript-pane.ts";
|
|
20
|
-
import {
|
|
21
|
-
import { renderMetricsPane } from "./dashboard-panes/metrics-pane.ts";
|
|
22
|
-
import { summarizeTerminalReason } from "./dashboard-panes/cancellation-pane.ts";
|
|
23
|
-
import { HelpOverlay } from "./overlays/help-overlay.ts";
|
|
20
|
+
import { DynamicCrewBorder } from "./dynamic-border.ts";
|
|
24
21
|
import { dashboardActionForKey } from "./keybinding-map.ts";
|
|
22
|
+
import { Box, Text } from "./layout-primitives.ts";
|
|
23
|
+
import { HelpOverlay } from "./overlays/help-overlay.ts";
|
|
24
|
+
import { runEventBus } from "./run-event-bus.ts";
|
|
25
25
|
import type { RunSnapshotCache, RunUiSnapshot } from "./snapshot-types.ts";
|
|
26
26
|
import { spinnerBucket, spinnerFrame } from "./spinner.ts";
|
|
27
|
-
import type
|
|
28
|
-
import {
|
|
29
|
-
import {
|
|
27
|
+
import { applyStatusColor, colorizeStatusGlyphs, iconForStatus, type RunStatus } from "./status-colors.ts";
|
|
28
|
+
import type { CrewTheme } from "./theme-adapter.ts";
|
|
29
|
+
import { asCrewTheme, subscribeThemeChange } from "./theme-adapter.ts";
|
|
30
30
|
|
|
31
31
|
interface DashboardComponent {
|
|
32
32
|
invalidate(): void;
|
|
@@ -66,7 +66,24 @@ export interface RunDashboardOptions {
|
|
|
66
66
|
*/
|
|
67
67
|
let lastActivePane: "agents" | "progress" | "mailbox" | "output" | "health" | "metrics" = "agents";
|
|
68
68
|
|
|
69
|
-
export type RunDashboardAction =
|
|
69
|
+
export type RunDashboardAction =
|
|
70
|
+
| "status"
|
|
71
|
+
| "summary"
|
|
72
|
+
| "artifacts"
|
|
73
|
+
| "api"
|
|
74
|
+
| "events"
|
|
75
|
+
| "agents"
|
|
76
|
+
| "agent-events"
|
|
77
|
+
| "agent-output"
|
|
78
|
+
| "agent-transcript"
|
|
79
|
+
| "agent-live"
|
|
80
|
+
| "mailbox"
|
|
81
|
+
| "reload"
|
|
82
|
+
| "mailbox-detail"
|
|
83
|
+
| "health-recovery"
|
|
84
|
+
| "health-kill-stale"
|
|
85
|
+
| "health-diagnostic-export"
|
|
86
|
+
| "notifications-dismiss";
|
|
70
87
|
export interface RunDashboardSelection {
|
|
71
88
|
runId: string;
|
|
72
89
|
action: RunDashboardAction;
|
|
@@ -199,7 +216,8 @@ function agentPreviewLine(agent: CrewAgentRecord, task: TeamTaskState | undefine
|
|
|
199
216
|
agent.progress?.activityState,
|
|
200
217
|
options.showModel !== false && modelForAgent(agent, task) ? `model=${modelForAgent(agent, task)}` : undefined,
|
|
201
218
|
options.showTokens !== false
|
|
202
|
-
? formatTokens(usageForAgent(agent, task)) ??
|
|
219
|
+
? (formatTokens(usageForAgent(agent, task)) ??
|
|
220
|
+
(agent.progress?.tokens !== undefined ? `tok=${agent.progress.tokens}` : undefined))
|
|
203
221
|
: undefined,
|
|
204
222
|
options.showTools !== false && agent.progress?.currentTool ? `tool=${agent.progress.currentTool}` : undefined,
|
|
205
223
|
options.showTools !== false && agent.toolUses !== undefined ? `${agent.toolUses} tools` : undefined,
|
|
@@ -208,8 +226,12 @@ function agentPreviewLine(agent: CrewAgentRecord, task: TeamTaskState | undefine
|
|
|
208
226
|
agent.startedAt ? `age=${formatAge(agent.completedAt ?? agent.startedAt)}` : undefined,
|
|
209
227
|
].filter((part): part is string => Boolean(part));
|
|
210
228
|
const recent = agent.progress?.recentOutput?.at(-1);
|
|
211
|
-
const icon = iconForStatus(agent.status, {
|
|
212
|
-
|
|
229
|
+
const icon = iconForStatus(agent.status, {
|
|
230
|
+
runningGlyph: spinnerFrame(agent.taskId),
|
|
231
|
+
});
|
|
232
|
+
return sanitizeLine(
|
|
233
|
+
`Agent: ${icon} ${agent.taskId} ${agent.role}->${agent.agent}${stats.length ? ` · ${stats.join(" · ")}` : ""}${recent ? ` ⎿ ${recent}` : ""}`,
|
|
234
|
+
);
|
|
213
235
|
}
|
|
214
236
|
|
|
215
237
|
function readAgentPreview(run: TeamRunManifest, maxLines = 5, options: RunDashboardOptions = {}): string[] {
|
|
@@ -218,20 +240,27 @@ function readAgentPreview(run: TeamRunManifest, maxLines = 5, options: RunDashbo
|
|
|
218
240
|
const agents = snapshot?.agents ?? readCrewAgents(run);
|
|
219
241
|
const tasks = snapshot?.tasks ?? readRunTasks(run, options.snapshotCache);
|
|
220
242
|
if (!agents.length) return ["Agents: (none)"];
|
|
221
|
-
const totals = tasks.reduce(
|
|
222
|
-
acc
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
243
|
+
const totals = tasks.reduce(
|
|
244
|
+
(acc, task) => {
|
|
245
|
+
acc.input += task.usage?.input ?? 0;
|
|
246
|
+
acc.output += task.usage?.output ?? 0;
|
|
247
|
+
acc.cacheRead += task.usage?.cacheRead ?? 0;
|
|
248
|
+
acc.cacheWrite += task.usage?.cacheWrite ?? 0;
|
|
249
|
+
acc.cost += task.usage?.cost ?? 0;
|
|
250
|
+
return acc;
|
|
251
|
+
},
|
|
252
|
+
{ input: 0, output: 0, cacheRead: 0, cacheWrite: 0, cost: 0 } as {
|
|
253
|
+
input: number;
|
|
254
|
+
output: number;
|
|
255
|
+
cacheRead: number;
|
|
256
|
+
cacheWrite: number;
|
|
257
|
+
cost: number;
|
|
258
|
+
},
|
|
259
|
+
);
|
|
229
260
|
const header = formatTokens(totals) ? `Agents: ${formatTokens(totals)}` : "Agents:";
|
|
230
261
|
return [
|
|
231
262
|
header,
|
|
232
|
-
...agents
|
|
233
|
-
.slice(0, maxLines)
|
|
234
|
-
.map((agent) => agentPreviewLine(agent, taskForAgent(tasks, agent), options)),
|
|
263
|
+
...agents.slice(0, maxLines).map((agent) => agentPreviewLine(agent, taskForAgent(tasks, agent), options)),
|
|
235
264
|
...(agents.length > maxLines ? [`Agents: +${agents.length - maxLines} more`] : []),
|
|
236
265
|
];
|
|
237
266
|
} catch (error) {
|
|
@@ -255,10 +284,18 @@ function runLabel(run: TeamRunManifest, selected: boolean, snapshotCache?: RunSn
|
|
|
255
284
|
const stale = isLikelyOrphanedActiveRun(run, agents);
|
|
256
285
|
const running = agents.find((agent) => agent.status === "running");
|
|
257
286
|
const queued = agents.find((agent) => agent.status === "queued");
|
|
258
|
-
const step = stale
|
|
287
|
+
const step = stale
|
|
288
|
+
? "orphaned queued run"
|
|
289
|
+
: running
|
|
290
|
+
? `step ${running.taskId}`
|
|
291
|
+
: queued
|
|
292
|
+
? `queued ${queued.taskId}`
|
|
293
|
+
: `agents ${agents.length}`;
|
|
259
294
|
const status: RunStatus = stale ? "stale" : (run.status as RunStatus);
|
|
260
295
|
const marker = selected ? "›" : " ";
|
|
261
|
-
const icon = iconForStatus(status, {
|
|
296
|
+
const icon = iconForStatus(status, {
|
|
297
|
+
runningGlyph: spinnerFrame(run.runId),
|
|
298
|
+
});
|
|
262
299
|
// L-5: unified " · " separator (was "|").
|
|
263
300
|
// L-3: keep the GOAL (the human identifier) visible on narrow terminals —
|
|
264
301
|
// when the full line overflows, sacrifice the meta prefix (runId/status
|
|
@@ -304,8 +341,12 @@ function resolveRuns(runs: TeamRunManifest[], snapshotCache?: RunSnapshotCache):
|
|
|
304
341
|
function groupedRuns(runs: TeamRunManifest[], snapshotCache?: RunSnapshotCache): Array<{ label: string; run?: TeamRunManifest }> {
|
|
305
342
|
const resolved = resolveRuns(runs, snapshotCache);
|
|
306
343
|
const rows: Array<{ label: string; run?: TeamRunManifest }> = [];
|
|
307
|
-
const active = runs.filter((run) =>
|
|
308
|
-
|
|
344
|
+
const active = runs.filter((run) =>
|
|
345
|
+
isDisplayActiveRun(resolved.get(run.runId)?.snapshot?.manifest ?? run, resolved.get(run.runId)?.agents ?? []),
|
|
346
|
+
);
|
|
347
|
+
const rest = runs.filter(
|
|
348
|
+
(run) => !isDisplayActiveRun(resolved.get(run.runId)?.snapshot?.manifest ?? run, resolved.get(run.runId)?.agents ?? []),
|
|
349
|
+
);
|
|
309
350
|
if (active.length) rows.push({ label: "Active" }, ...active.map((run) => ({ label: run.runId, run })));
|
|
310
351
|
if (rest.length) rows.push({ label: "Recent" }, ...rest.map((run) => ({ label: run.runId, run })));
|
|
311
352
|
return rows;
|
|
@@ -355,11 +396,15 @@ export class RunDashboard implements DashboardComponent {
|
|
|
355
396
|
this.options = options;
|
|
356
397
|
this.unsubscribeTheme = subscribeThemeChange(theme, () => this.invalidateAndRender());
|
|
357
398
|
this.unsubscribeEventBus = (() => {
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
399
|
+
const unsub1 = runEventBus.onChannel("run:state", () => this.invalidateAndRender());
|
|
400
|
+
const unsub2 = runEventBus.onChannel("worker:lifecycle", () => this.invalidateAndRender());
|
|
401
|
+
const unsub3 = runEventBus.onChannel("ui:invalidate", () => this.invalidateAndRender());
|
|
402
|
+
return () => {
|
|
403
|
+
unsub1();
|
|
404
|
+
unsub2();
|
|
405
|
+
unsub3();
|
|
406
|
+
};
|
|
407
|
+
})();
|
|
363
408
|
}
|
|
364
409
|
|
|
365
410
|
/**
|
|
@@ -373,7 +418,11 @@ export class RunDashboard implements DashboardComponent {
|
|
|
373
418
|
*/
|
|
374
419
|
private invalidateAndRender(): void {
|
|
375
420
|
this.invalidate();
|
|
376
|
-
try {
|
|
421
|
+
try {
|
|
422
|
+
this.options.requestRender?.();
|
|
423
|
+
} catch {
|
|
424
|
+
/* host may not expose requestRender */
|
|
425
|
+
}
|
|
377
426
|
}
|
|
378
427
|
|
|
379
428
|
/**
|
|
@@ -396,7 +445,9 @@ export class RunDashboard implements DashboardComponent {
|
|
|
396
445
|
const next = this.options.runProvider();
|
|
397
446
|
this.runs = Array.isArray(next) ? next : this.runs;
|
|
398
447
|
if (selectedRunId) {
|
|
399
|
-
const nextIndex = groupedRuns(this.runs, this.options.snapshotCache)
|
|
448
|
+
const nextIndex = groupedRuns(this.runs, this.options.snapshotCache)
|
|
449
|
+
.filter((row) => row.run)
|
|
450
|
+
.findIndex((row) => row.run?.runId === selectedRunId);
|
|
400
451
|
if (nextIndex >= 0) this.selected = nextIndex;
|
|
401
452
|
else this.selected = 0;
|
|
402
453
|
}
|
|
@@ -428,16 +479,19 @@ export class RunDashboard implements DashboardComponent {
|
|
|
428
479
|
|
|
429
480
|
private buildSignature(): string {
|
|
430
481
|
let hasRunning = false;
|
|
431
|
-
const statuses = this.runs
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
482
|
+
const statuses = this.runs
|
|
483
|
+
.map((run) => {
|
|
484
|
+
const snapshot = snapshotFor(run, this.options.snapshotCache);
|
|
485
|
+
const displayRun = snapshot?.manifest ?? run;
|
|
486
|
+
const agents = snapshot?.agents ?? agentsFor(run, this.options.snapshotCache);
|
|
487
|
+
const stale = isLikelyOrphanedActiveRun(displayRun, agents);
|
|
488
|
+
const status: RunStatus = stale ? "stale" : (displayRun.status as RunStatus);
|
|
489
|
+
if (status === "running" || agents.some((agent) => agent.status === "running")) hasRunning = true;
|
|
490
|
+
return snapshot?.signature ?? `${displayRun.runId}:${displayRun.status}:${displayRun.updatedAt}:${status}`;
|
|
491
|
+
})
|
|
492
|
+
.join("|");
|
|
493
|
+
const metricsSig =
|
|
494
|
+
this.activePane === "metrics" ? `:metrics=${this.options.registry?.snapshot().length ?? 0}:${spinnerBucket()}` : "";
|
|
441
495
|
return `${this.selected}:${this.showHelp ? 1 : 0}:${this.showFullProgress ? 1 : 0}:${this.activePane}:${statuses}${hasRunning ? `:spin=${spinnerBucket()}` : ""}${metricsSig}`;
|
|
442
496
|
}
|
|
443
497
|
|
|
@@ -460,10 +514,7 @@ export class RunDashboard implements DashboardComponent {
|
|
|
460
514
|
return this.renderUnsafe(width);
|
|
461
515
|
} catch (error) {
|
|
462
516
|
logInternalError("run-dashboard.render", error);
|
|
463
|
-
return renderLines([
|
|
464
|
-
"Dashboard error — see logs for details.",
|
|
465
|
-
"Press r to reload · Esc to close.",
|
|
466
|
-
], width);
|
|
517
|
+
return renderLines(["Dashboard error — see logs for details.", "Press r to reload · Esc to close."], width);
|
|
467
518
|
}
|
|
468
519
|
}
|
|
469
520
|
|
|
@@ -478,7 +529,7 @@ export class RunDashboard implements DashboardComponent {
|
|
|
478
529
|
const border = (left: string, right: string) => `${fg("border", left)}${borderFill(borderWidth)}${fg("border", right)}`;
|
|
479
530
|
const row = (text: string) => `│ ${pad(truncate(text, innerWidth - 1), innerWidth - 1)}│`;
|
|
480
531
|
const sep = () => border("├", "┤");
|
|
481
|
-
|
|
532
|
+
|
|
482
533
|
const lines: string[] = [];
|
|
483
534
|
if (this.showHelp) {
|
|
484
535
|
// K-1: help overlay replaces the dashboard body until dismissed.
|
|
@@ -486,7 +537,9 @@ export class RunDashboard implements DashboardComponent {
|
|
|
486
537
|
} else {
|
|
487
538
|
lines.push(
|
|
488
539
|
border("╭", "╮"),
|
|
489
|
-
row(
|
|
540
|
+
row(
|
|
541
|
+
`${fg("accent", "▐")} ${this.theme.bold("pi-crew")} · ${this.runs.length} runs ${fg("dim", "1-6 pane · ↑↓ · Enter · ? help · Esc")}`,
|
|
542
|
+
),
|
|
490
543
|
sep(),
|
|
491
544
|
);
|
|
492
545
|
|
|
@@ -504,7 +557,10 @@ export class RunDashboard implements DashboardComponent {
|
|
|
504
557
|
if (selectableCount <= RUN_LIST_MAX) {
|
|
505
558
|
// Common case (≤8 runs): keep the Active/Recent group headers.
|
|
506
559
|
for (const rowItem of allGrouped) {
|
|
507
|
-
if (!rowItem.run) {
|
|
560
|
+
if (!rowItem.run) {
|
|
561
|
+
lines.push(row(fg("dim", `── ${rowItem.label} ──`)));
|
|
562
|
+
continue;
|
|
563
|
+
}
|
|
508
564
|
const idx = selectable.findIndex((c) => c.run?.runId === rowItem.run?.runId);
|
|
509
565
|
const snap = snapshotFor(rowItem.run, this.options.snapshotCache);
|
|
510
566
|
const run = snap?.manifest ?? rowItem.run;
|
|
@@ -527,7 +583,8 @@ export class RunDashboard implements DashboardComponent {
|
|
|
527
583
|
const label = runLabel(run, gi === this.selected, this.options.snapshotCache, innerWidth - 2);
|
|
528
584
|
lines.push(row(applyStatusColor(this.theme, status, label)));
|
|
529
585
|
}
|
|
530
|
-
if (win.hasBottom)
|
|
586
|
+
if (win.hasBottom)
|
|
587
|
+
lines.push(row(fg("dim", `↓ ${selectableCount - (this.runScrollOffset + win.slots)} more below`)));
|
|
531
588
|
}
|
|
532
589
|
|
|
533
590
|
// Selected run detail — compact
|
|
@@ -544,21 +601,36 @@ export class RunDashboard implements DashboardComponent {
|
|
|
544
601
|
const isTerminal = statusStr === "failed" || statusStr === "cancelled" || statusStr === "stopped";
|
|
545
602
|
const reason = isTerminal ? summarizeTerminalReason(r, selectedTasks, snap?.cancellationReason) : undefined;
|
|
546
603
|
const reasonSuffix = reason ? ` · ${truncate(sanitizeLine(reason), 40)}` : "";
|
|
547
|
-
lines.push(
|
|
604
|
+
lines.push(
|
|
605
|
+
row(
|
|
606
|
+
fg(
|
|
607
|
+
"dim",
|
|
608
|
+
sanitizeLine(
|
|
609
|
+
` ${r.team}/${r.workflow ?? "default"} · ${statusStr} · ${r.runId.slice(-10)}${reasonSuffix}`,
|
|
610
|
+
),
|
|
611
|
+
),
|
|
612
|
+
),
|
|
613
|
+
);
|
|
548
614
|
|
|
549
615
|
// Pane content (max 8 lines) — F-2: colorize embedded status glyphs.
|
|
550
616
|
const paneLines = snap
|
|
551
|
-
? this.activePane === "agents"
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
617
|
+
? this.activePane === "agents"
|
|
618
|
+
? renderAgentsPane(snap, this.options)
|
|
619
|
+
: this.activePane === "progress"
|
|
620
|
+
? renderProgressPane(snap)
|
|
621
|
+
: this.activePane === "mailbox"
|
|
622
|
+
? renderMailboxPane(snap)
|
|
623
|
+
: this.activePane === "health"
|
|
624
|
+
? renderHealthPane(snap, {
|
|
625
|
+
isForeground: !r.async,
|
|
626
|
+
})
|
|
627
|
+
: this.activePane === "metrics"
|
|
628
|
+
? renderMetricsPane(snap, {
|
|
629
|
+
registry: this.options.registry,
|
|
630
|
+
})
|
|
631
|
+
: renderTranscriptPane(snap)
|
|
632
|
+
: [...readAgentPreview(r, 4, this.options), ...readProgressPreview(r, 2)];
|
|
633
|
+
const filteredPane = paneLines.filter((l) => l && !l.includes("(none)") && l.trim() !== "");
|
|
562
634
|
if (filteredPane.length > 0) {
|
|
563
635
|
lines.push(row(fg("dim", `── ${this.activePane} ──`)));
|
|
564
636
|
for (const line of filteredPane.slice(0, 8)) {
|
|
@@ -573,14 +645,23 @@ export class RunDashboard implements DashboardComponent {
|
|
|
573
645
|
|
|
574
646
|
// One-line footer — V-1: width-padded so the right edge doesn't jitter.
|
|
575
647
|
const usage = aggregateUsage(selectedTasks);
|
|
576
|
-
const u = usage ?? {
|
|
648
|
+
const u = usage ?? {
|
|
649
|
+
input: 0,
|
|
650
|
+
output: 0,
|
|
651
|
+
cacheRead: 0,
|
|
652
|
+
cacheWrite: 0,
|
|
653
|
+
cost: 0,
|
|
654
|
+
};
|
|
577
655
|
const tok = (u.input ?? 0) + (u.output ?? 0) + (u.cacheRead ?? 0) + (u.cacheWrite ?? 0);
|
|
578
656
|
const tokStr = tok > 0 ? (tok >= 1000 ? `${(tok / 1000).toFixed(1)}k tok` : `${tok} tok`) : "";
|
|
579
657
|
let ctxPct: number | undefined;
|
|
580
658
|
for (const agent of agents) {
|
|
581
659
|
if (agent.status === "running" && agent.runtime === "live-session") {
|
|
582
660
|
const pct = getLiveAgentContextPercent(agent.taskId);
|
|
583
|
-
if (pct != null) {
|
|
661
|
+
if (pct != null) {
|
|
662
|
+
ctxPct = pct;
|
|
663
|
+
break;
|
|
664
|
+
}
|
|
584
665
|
}
|
|
585
666
|
}
|
|
586
667
|
const ctxStr = ctxPct != null ? `${Math.round(ctxPct)}% ctx` : "";
|
|
@@ -607,7 +688,10 @@ export class RunDashboard implements DashboardComponent {
|
|
|
607
688
|
lines.push(bottom);
|
|
608
689
|
}
|
|
609
690
|
|
|
610
|
-
this.cachedLines = renderLines(
|
|
691
|
+
this.cachedLines = renderLines(
|
|
692
|
+
lines.map((line) => truncate(line, width)),
|
|
693
|
+
width,
|
|
694
|
+
);
|
|
611
695
|
this.cachedVersion = signature;
|
|
612
696
|
this.cachedWidth = width;
|
|
613
697
|
}
|
|
@@ -637,7 +721,19 @@ export class RunDashboard implements DashboardComponent {
|
|
|
637
721
|
this.done(selectedRunId ? { runId: selectedRunId, action: "status" } : undefined);
|
|
638
722
|
return;
|
|
639
723
|
}
|
|
640
|
-
if (
|
|
724
|
+
if (
|
|
725
|
+
action === "summary" ||
|
|
726
|
+
action === "artifacts" ||
|
|
727
|
+
action === "api" ||
|
|
728
|
+
action === "agents" ||
|
|
729
|
+
action === "mailbox" ||
|
|
730
|
+
action === "reload" ||
|
|
731
|
+
action === "mailbox-detail" ||
|
|
732
|
+
action === "health-recovery" ||
|
|
733
|
+
action === "health-kill-stale" ||
|
|
734
|
+
action === "health-diagnostic-export" ||
|
|
735
|
+
action === "notifications-dismiss"
|
|
736
|
+
) {
|
|
641
737
|
this.done(selectedRunId ? { runId: selectedRunId, action } : action === "reload" ? { runId: "", action } : undefined);
|
|
642
738
|
return;
|
|
643
739
|
}
|
package/src/ui/run-event-bus.ts
CHANGED
|
@@ -16,32 +16,31 @@ export type RunEventType =
|
|
|
16
16
|
| "run.cache_invalidated";
|
|
17
17
|
|
|
18
18
|
/** Typed channel names for category-based event subscription. */
|
|
19
|
-
export type EventChannel =
|
|
20
|
-
| "worker:progress"
|
|
21
|
-
| "worker:lifecycle"
|
|
22
|
-
| "worker:stream"
|
|
23
|
-
| "run:state"
|
|
24
|
-
| "ui:invalidate";
|
|
19
|
+
export type EventChannel = "worker:progress" | "worker:lifecycle" | "worker:stream" | "run:state" | "ui:invalidate";
|
|
25
20
|
|
|
26
21
|
/** Sets used by classifyEventChannel for O(1) lookup. */
|
|
27
|
-
const WORKER_PROGRESS_TYPES = new Set([
|
|
28
|
-
"tool_execution_start", "tool_result", "agent_progress", "worker_status",
|
|
29
|
-
]);
|
|
22
|
+
const WORKER_PROGRESS_TYPES = new Set(["tool_execution_start", "tool_result", "agent_progress", "worker_status"]);
|
|
30
23
|
const WORKER_LIFECYCLE_TYPES = new Set([
|
|
31
|
-
"task.started",
|
|
32
|
-
"
|
|
33
|
-
"
|
|
34
|
-
"
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
"
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
"
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
"
|
|
24
|
+
"task.started",
|
|
25
|
+
"task.completed",
|
|
26
|
+
"task.failed",
|
|
27
|
+
"task.needs_attention",
|
|
28
|
+
"task_started",
|
|
29
|
+
"task_completed",
|
|
30
|
+
"task_failed",
|
|
31
|
+
"task_cancelled",
|
|
32
|
+
"run.started",
|
|
33
|
+
"run.completed",
|
|
34
|
+
"run.cancelled",
|
|
35
|
+
"run.failed",
|
|
36
|
+
"run_started",
|
|
37
|
+
"run_completed",
|
|
38
|
+
"run_cancelled",
|
|
39
|
+
"run_blocked",
|
|
44
40
|
]);
|
|
41
|
+
const WORKER_STREAM_TYPES = new Set(["stdout_chunk", "stderr_chunk", "stream"]);
|
|
42
|
+
const RUN_STATE_TYPES = new Set(["manifest.saved", "task.claimed", "task.unclaimed", "mailbox_updated"]);
|
|
43
|
+
const UI_INVALIDATE_TYPES = new Set(["effectiveness_changed", "snapshot_stale", "run.cache_invalidated"]);
|
|
45
44
|
|
|
46
45
|
/** Classify an event type string into a typed channel. */
|
|
47
46
|
export function classifyEventChannel(type: string): EventChannel {
|
|
@@ -86,12 +85,17 @@ class RunEventBus {
|
|
|
86
85
|
const listeners = this.#listeners.get(runId) ?? new Set();
|
|
87
86
|
listeners.add(callback);
|
|
88
87
|
this.#listeners.set(runId, listeners);
|
|
89
|
-
return () => {
|
|
88
|
+
return () => {
|
|
89
|
+
listeners.delete(callback);
|
|
90
|
+
if (listeners.size === 0) this.#listeners.delete(runId);
|
|
91
|
+
};
|
|
90
92
|
}
|
|
91
93
|
|
|
92
94
|
onAny(callback: RunEventCallback): () => void {
|
|
93
95
|
this.#globalListeners.add(callback);
|
|
94
|
-
return () => {
|
|
96
|
+
return () => {
|
|
97
|
+
this.#globalListeners.delete(callback);
|
|
98
|
+
};
|
|
95
99
|
}
|
|
96
100
|
|
|
97
101
|
off(runId: string, callback: RunEventCallback): void {
|
|
@@ -151,17 +155,15 @@ class RunEventBus {
|
|
|
151
155
|
* fan-out to other subscribers).
|
|
152
156
|
* @returns unsubscribe handle (detaches the live listener).
|
|
153
157
|
*/
|
|
154
|
-
onWithReplay(
|
|
155
|
-
runId: string,
|
|
156
|
-
eventsPath: string,
|
|
157
|
-
lastSeenSeq: number,
|
|
158
|
-
callback: RunEventCallback,
|
|
159
|
-
): () => void {
|
|
158
|
+
onWithReplay(runId: string, eventsPath: string, lastSeenSeq: number, callback: RunEventCallback): () => void {
|
|
160
159
|
// Phase 1: replay missed events from the durable log directly to this
|
|
161
160
|
// callback. Bounded by limit; readEventsCursor already tail-caps.
|
|
162
161
|
let maxReplayedSeq = lastSeenSeq;
|
|
163
162
|
try {
|
|
164
|
-
const cursor = readEventsCursor(eventsPath, {
|
|
163
|
+
const cursor = readEventsCursor(eventsPath, {
|
|
164
|
+
sinceSeq: lastSeenSeq,
|
|
165
|
+
limit: 1000,
|
|
166
|
+
});
|
|
165
167
|
for (const teamEvent of cursor.events) {
|
|
166
168
|
const type = teamEventToRunEventType(teamEvent);
|
|
167
169
|
if (!type) continue; // not all TeamEvents map to a RunEventType
|
|
@@ -174,7 +176,11 @@ class RunEventBus {
|
|
|
174
176
|
channel: classifyEventChannel(type),
|
|
175
177
|
seq: teamEvent.metadata?.seq,
|
|
176
178
|
};
|
|
177
|
-
try {
|
|
179
|
+
try {
|
|
180
|
+
callback(payload);
|
|
181
|
+
} catch {
|
|
182
|
+
/* subscriber errors are non-fatal */
|
|
183
|
+
}
|
|
178
184
|
if (typeof teamEvent.metadata?.seq === "number") {
|
|
179
185
|
maxReplayedSeq = Math.max(maxReplayedSeq, teamEvent.metadata.seq);
|
|
180
186
|
}
|
|
@@ -208,20 +214,32 @@ class RunEventBus {
|
|
|
208
214
|
const listeners = this.#listeners.get(event.runId);
|
|
209
215
|
if (listeners) {
|
|
210
216
|
for (const cb of listeners) {
|
|
211
|
-
try {
|
|
217
|
+
try {
|
|
218
|
+
cb(event);
|
|
219
|
+
} catch {
|
|
220
|
+
/* subscriber errors are non-fatal */
|
|
221
|
+
}
|
|
212
222
|
}
|
|
213
223
|
}
|
|
214
224
|
|
|
215
225
|
// Existing: global listeners
|
|
216
226
|
for (const cb of this.#globalListeners) {
|
|
217
|
-
try {
|
|
227
|
+
try {
|
|
228
|
+
cb(event);
|
|
229
|
+
} catch {
|
|
230
|
+
/* subscriber errors are non-fatal */
|
|
231
|
+
}
|
|
218
232
|
}
|
|
219
233
|
|
|
220
234
|
// New: channel listeners
|
|
221
235
|
const channelListeners = this.#channelListeners.get(channel);
|
|
222
236
|
if (channelListeners) {
|
|
223
237
|
for (const cb of channelListeners) {
|
|
224
|
-
try {
|
|
238
|
+
try {
|
|
239
|
+
cb(event);
|
|
240
|
+
} catch {
|
|
241
|
+
/* subscriber errors are non-fatal */
|
|
242
|
+
}
|
|
225
243
|
}
|
|
226
244
|
}
|
|
227
245
|
|
|
@@ -232,7 +250,11 @@ class RunEventBus {
|
|
|
232
250
|
const runChannelListeners = runMap.get(channel);
|
|
233
251
|
if (runChannelListeners) {
|
|
234
252
|
for (const cb of runChannelListeners) {
|
|
235
|
-
try {
|
|
253
|
+
try {
|
|
254
|
+
cb(event);
|
|
255
|
+
} catch {
|
|
256
|
+
/* subscriber errors are non-fatal */
|
|
257
|
+
}
|
|
236
258
|
}
|
|
237
259
|
}
|
|
238
260
|
}
|
|
@@ -290,4 +312,4 @@ export function emitFromTeamEvent(event: TeamEvent): void {
|
|
|
290
312
|
// delivery against replayed events.
|
|
291
313
|
seq: event.metadata?.seq,
|
|
292
314
|
});
|
|
293
|
-
}
|
|
315
|
+
}
|