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
|
@@ -1,17 +1,24 @@
|
|
|
1
1
|
import { createHash } from "node:crypto";
|
|
2
2
|
import * as fs from "node:fs";
|
|
3
3
|
import * as path from "node:path";
|
|
4
|
-
import {
|
|
4
|
+
import { agentOutputPath, agentsPath, readCrewAgents, readCrewAgentsAsync } from "../runtime/crew-agent-records.ts";
|
|
5
5
|
import type { CrewAgentRecord } from "../runtime/crew-agent-runtime.ts";
|
|
6
6
|
import { isActiveRunStatus } from "../runtime/process-status.ts";
|
|
7
7
|
import type { TeamEvent } from "../state/event-log.ts";
|
|
8
|
+
import { sequencePath } from "../state/event-log.ts";
|
|
8
9
|
import type { MailboxMessageStatus } from "../state/mailbox.ts";
|
|
9
10
|
import { loadRunManifestById, loadRunManifestByIdAsync } from "../state/state-store.ts";
|
|
10
11
|
import type { TeamRunManifest, TeamTaskState } from "../state/types.ts";
|
|
11
|
-
import type { RunSnapshotCache as RunSnapshotCacheBase, RunUiGroupJoin, RunUiMailbox, RunUiProgress, RunUiSnapshot, RunUiUsage } from "./snapshot-types.ts";
|
|
12
|
-
import { runEventBus } from "./run-event-bus.ts";
|
|
13
12
|
import { extractDwfPhaseState } from "./dwf-phase-display.ts";
|
|
14
|
-
import {
|
|
13
|
+
import { runEventBus } from "./run-event-bus.ts";
|
|
14
|
+
import type {
|
|
15
|
+
RunSnapshotCache as RunSnapshotCacheBase,
|
|
16
|
+
RunUiGroupJoin,
|
|
17
|
+
RunUiMailbox,
|
|
18
|
+
RunUiProgress,
|
|
19
|
+
RunUiSnapshot,
|
|
20
|
+
RunUiUsage,
|
|
21
|
+
} from "./snapshot-types.ts";
|
|
15
22
|
|
|
16
23
|
export interface RunSnapshotCache extends RunSnapshotCacheBase {
|
|
17
24
|
preloadStale(runId: string): Promise<RunUiSnapshot | undefined>;
|
|
@@ -90,7 +97,9 @@ function eventsStamp(eventsPath: string): FileStamp {
|
|
|
90
97
|
const raw = fs.readFileSync(sequencePath(eventsPath), "utf-8");
|
|
91
98
|
const seq = Number.parseInt(raw.trim(), 10);
|
|
92
99
|
if (Number.isFinite(seq) && seq >= 0) return { mtimeMs: 0, size: seq + 1 };
|
|
93
|
-
} catch {
|
|
100
|
+
} catch {
|
|
101
|
+
/* fall through to legacy stat */
|
|
102
|
+
}
|
|
94
103
|
return stampFile(eventsPath);
|
|
95
104
|
}
|
|
96
105
|
|
|
@@ -99,12 +108,20 @@ async function eventsStampAsync(eventsPath: string): Promise<FileStamp> {
|
|
|
99
108
|
const raw = await fs.promises.readFile(sequencePath(eventsPath), "utf-8");
|
|
100
109
|
const seq = Number.parseInt(raw.trim(), 10);
|
|
101
110
|
if (Number.isFinite(seq) && seq >= 0) return { mtimeMs: 0, size: seq + 1 };
|
|
102
|
-
} catch {
|
|
111
|
+
} catch {
|
|
112
|
+
/* fall through to legacy stat */
|
|
113
|
+
}
|
|
103
114
|
return stampFileAsync(eventsPath);
|
|
104
115
|
}
|
|
105
116
|
|
|
106
117
|
function combineStamps(stamps: FileStamp[]): FileStamp {
|
|
107
|
-
return stamps.reduce(
|
|
118
|
+
return stamps.reduce(
|
|
119
|
+
(acc, stamp) => ({
|
|
120
|
+
mtimeMs: Math.max(acc.mtimeMs, stamp.mtimeMs),
|
|
121
|
+
size: acc.size + stamp.size,
|
|
122
|
+
}),
|
|
123
|
+
zeroStamp(),
|
|
124
|
+
);
|
|
108
125
|
}
|
|
109
126
|
|
|
110
127
|
function mailboxStamp(manifest: TeamRunManifest): FileStamp {
|
|
@@ -116,7 +133,9 @@ function mailboxStamp(manifest: TeamRunManifest): FileStamp {
|
|
|
116
133
|
];
|
|
117
134
|
const tasksRoot = path.join(root, "tasks");
|
|
118
135
|
try {
|
|
119
|
-
for (const entry of fs.readdirSync(tasksRoot, {
|
|
136
|
+
for (const entry of fs.readdirSync(tasksRoot, {
|
|
137
|
+
withFileTypes: true,
|
|
138
|
+
})) {
|
|
120
139
|
if (!entry.isDirectory()) continue;
|
|
121
140
|
stamps.push(stampFile(path.join(tasksRoot, entry.name, "inbox.jsonl")));
|
|
122
141
|
stamps.push(stampFile(path.join(tasksRoot, entry.name, "outbox.jsonl")));
|
|
@@ -136,7 +155,9 @@ async function mailboxStampAsync(manifest: TeamRunManifest): Promise<FileStamp>
|
|
|
136
155
|
];
|
|
137
156
|
const tasksRoot = path.join(root, "tasks");
|
|
138
157
|
try {
|
|
139
|
-
for (const entry of await fs.promises.readdir(tasksRoot, {
|
|
158
|
+
for (const entry of await fs.promises.readdir(tasksRoot, {
|
|
159
|
+
withFileTypes: true,
|
|
160
|
+
})) {
|
|
140
161
|
if (!entry.isDirectory()) continue;
|
|
141
162
|
stamps.push(await stampFileAsync(path.join(tasksRoot, entry.name, "inbox.jsonl")));
|
|
142
163
|
stamps.push(await stampFileAsync(path.join(tasksRoot, entry.name, "outbox.jsonl")));
|
|
@@ -168,11 +189,13 @@ function sameStamp(a: FileStamp, b: FileStamp): boolean {
|
|
|
168
189
|
}
|
|
169
190
|
|
|
170
191
|
function sameStamps(a: SnapshotStamps, b: SnapshotStamps): boolean {
|
|
171
|
-
return
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
192
|
+
return (
|
|
193
|
+
sameStamp(a.manifest, b.manifest) &&
|
|
194
|
+
sameStamp(a.tasks, b.tasks) &&
|
|
195
|
+
sameStamp(a.agents, b.agents) &&
|
|
196
|
+
sameStamp(a.events, b.events) &&
|
|
197
|
+
sameStamp(a.mailbox, b.mailbox)
|
|
198
|
+
);
|
|
176
199
|
}
|
|
177
200
|
|
|
178
201
|
function readTasks(tasksPath: string): TeamTaskState[] {
|
|
@@ -195,10 +218,12 @@ function tailJsonlLines<T>(filePath: string, limit: number, parse: (line: string
|
|
|
195
218
|
const buffer = Buffer.alloc(bytesToRead);
|
|
196
219
|
fs.readSync(fd, buffer, 0, bytesToRead, stat.size - bytesToRead);
|
|
197
220
|
const lines = buffer.toString("utf-8").split(/\r?\n/).filter(Boolean);
|
|
198
|
-
return lines
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
221
|
+
return lines
|
|
222
|
+
.flatMap((line) => {
|
|
223
|
+
const item = parse(line);
|
|
224
|
+
return item ? [item] : [];
|
|
225
|
+
})
|
|
226
|
+
.slice(-limit);
|
|
202
227
|
} finally {
|
|
203
228
|
fs.closeSync(fd);
|
|
204
229
|
}
|
|
@@ -218,10 +243,12 @@ async function tailJsonlLinesAsync<T>(filePath: string, limit: number, parse: (l
|
|
|
218
243
|
const buffer = Buffer.alloc(bytesToRead);
|
|
219
244
|
await handle.read(buffer, 0, bytesToRead, stat.size - bytesToRead);
|
|
220
245
|
const lines = buffer.toString("utf-8").split(/\r?\n/).filter(Boolean);
|
|
221
|
-
return lines
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
246
|
+
return lines
|
|
247
|
+
.flatMap((line) => {
|
|
248
|
+
const item = parse(line);
|
|
249
|
+
return item ? [item] : [];
|
|
250
|
+
})
|
|
251
|
+
.slice(-limit);
|
|
225
252
|
} finally {
|
|
226
253
|
await handle.close();
|
|
227
254
|
}
|
|
@@ -294,21 +321,39 @@ function recentOutputLines(manifest: TeamRunManifest, agents: CrewAgentRecord[],
|
|
|
294
321
|
const outputPath = safeAgentOutputPath(manifest, agent);
|
|
295
322
|
return outputPath ? tailLines(outputPath, limit) : [];
|
|
296
323
|
});
|
|
297
|
-
return [...fromProgress, ...fromFiles]
|
|
324
|
+
return [...fromProgress, ...fromFiles]
|
|
325
|
+
.map((line) => line.replace(/\s+/g, " ").trim())
|
|
326
|
+
.filter(Boolean)
|
|
327
|
+
.slice(-limit);
|
|
298
328
|
}
|
|
299
329
|
|
|
300
330
|
async function recentOutputLinesAsync(manifest: TeamRunManifest, agents: CrewAgentRecord[], limit: number): Promise<string[]> {
|
|
301
331
|
const fromProgress = agents.flatMap((agent) => agent.progress?.recentOutput ?? []);
|
|
302
|
-
const fromFilesArrays = await Promise.all(
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
332
|
+
const fromFilesArrays = await Promise.all(
|
|
333
|
+
agents.map((agent) => {
|
|
334
|
+
const outputPath = safeAgentOutputPath(manifest, agent);
|
|
335
|
+
return outputPath ? tailLinesAsync(outputPath, limit) : Promise.resolve([]);
|
|
336
|
+
}),
|
|
337
|
+
);
|
|
306
338
|
const fromFiles = fromFilesArrays.flat();
|
|
307
|
-
return [...fromProgress, ...fromFiles]
|
|
339
|
+
return [...fromProgress, ...fromFiles]
|
|
340
|
+
.map((line) => line.replace(/\s+/g, " ").trim())
|
|
341
|
+
.filter(Boolean)
|
|
342
|
+
.slice(-limit);
|
|
308
343
|
}
|
|
309
344
|
|
|
310
345
|
function progressFromTasks(tasks: TeamTaskState[]): RunUiProgress {
|
|
311
|
-
const progress: RunUiProgress = {
|
|
346
|
+
const progress: RunUiProgress = {
|
|
347
|
+
total: tasks.length,
|
|
348
|
+
completed: 0,
|
|
349
|
+
running: 0,
|
|
350
|
+
failed: 0,
|
|
351
|
+
queued: 0,
|
|
352
|
+
waiting: 0,
|
|
353
|
+
cancelled: 0,
|
|
354
|
+
skipped: 0,
|
|
355
|
+
needsAttention: 0,
|
|
356
|
+
};
|
|
312
357
|
for (const task of tasks) {
|
|
313
358
|
if (task.status === "completed") progress.completed += 1;
|
|
314
359
|
else if (task.status === "running") progress.running += 1;
|
|
@@ -323,19 +368,25 @@ function progressFromTasks(tasks: TeamTaskState[]): RunUiProgress {
|
|
|
323
368
|
}
|
|
324
369
|
|
|
325
370
|
function usageFrom(tasks: TeamTaskState[], agents: CrewAgentRecord[]): RunUiUsage {
|
|
326
|
-
const taskUsage = tasks.reduce(
|
|
327
|
-
acc
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
371
|
+
const taskUsage = tasks.reduce(
|
|
372
|
+
(acc, task) => {
|
|
373
|
+
acc.tokensIn += task.usage?.input ?? 0;
|
|
374
|
+
acc.tokensOut += task.usage?.output ?? 0;
|
|
375
|
+
acc.toolUses += task.agentProgress?.toolCount ?? 0;
|
|
376
|
+
return acc;
|
|
377
|
+
},
|
|
378
|
+
{ tokensIn: 0, tokensOut: 0, toolUses: 0 },
|
|
379
|
+
);
|
|
332
380
|
if (taskUsage.tokensIn || taskUsage.tokensOut || taskUsage.toolUses) return taskUsage;
|
|
333
|
-
return agents.reduce(
|
|
334
|
-
acc
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
381
|
+
return agents.reduce(
|
|
382
|
+
(acc, agent) => {
|
|
383
|
+
acc.tokensIn += agent.usage?.input ?? 0;
|
|
384
|
+
acc.tokensOut += agent.usage?.output ?? agent.progress?.tokens ?? 0;
|
|
385
|
+
acc.toolUses += agent.toolUses ?? agent.progress?.toolCount ?? 0;
|
|
386
|
+
return acc;
|
|
387
|
+
},
|
|
388
|
+
{ tokensIn: 0, tokensOut: 0, toolUses: 0 },
|
|
389
|
+
);
|
|
339
390
|
}
|
|
340
391
|
|
|
341
392
|
function isMailboxStatus(value: unknown): value is MailboxMessageStatus {
|
|
@@ -377,9 +428,17 @@ function readGroupJoinMailbox(filePath: string, delivery: Record<string, Mailbox
|
|
|
377
428
|
const parsed = JSON.parse(line) as unknown;
|
|
378
429
|
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) return undefined;
|
|
379
430
|
const message = parsed as { id?: unknown; data?: unknown };
|
|
380
|
-
const data =
|
|
431
|
+
const data =
|
|
432
|
+
message.data && typeof message.data === "object" && !Array.isArray(message.data)
|
|
433
|
+
? (message.data as Record<string, unknown>)
|
|
434
|
+
: undefined;
|
|
381
435
|
if (typeof message.id !== "string" || data?.kind !== "group_join" || typeof data.requestId !== "string") return undefined;
|
|
382
|
-
return {
|
|
436
|
+
return {
|
|
437
|
+
requestId: data.requestId,
|
|
438
|
+
messageId: message.id,
|
|
439
|
+
partial: data.partial === true,
|
|
440
|
+
ack: delivery[message.id] === "acknowledged" ? ("acknowledged" as const) : ("pending" as const),
|
|
441
|
+
};
|
|
383
442
|
} catch {
|
|
384
443
|
return undefined;
|
|
385
444
|
}
|
|
@@ -392,9 +451,17 @@ async function readGroupJoinMailboxAsync(filePath: string, delivery: Record<stri
|
|
|
392
451
|
const parsed = JSON.parse(line) as unknown;
|
|
393
452
|
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) return undefined;
|
|
394
453
|
const message = parsed as { id?: unknown; data?: unknown };
|
|
395
|
-
const data =
|
|
454
|
+
const data =
|
|
455
|
+
message.data && typeof message.data === "object" && !Array.isArray(message.data)
|
|
456
|
+
? (message.data as Record<string, unknown>)
|
|
457
|
+
: undefined;
|
|
396
458
|
if (typeof message.id !== "string" || data?.kind !== "group_join" || typeof data.requestId !== "string") return undefined;
|
|
397
|
-
return {
|
|
459
|
+
return {
|
|
460
|
+
requestId: data.requestId,
|
|
461
|
+
messageId: message.id,
|
|
462
|
+
partial: data.partial === true,
|
|
463
|
+
ack: delivery[message.id] === "acknowledged" ? ("acknowledged" as const) : ("pending" as const),
|
|
464
|
+
};
|
|
398
465
|
} catch {
|
|
399
466
|
return undefined;
|
|
400
467
|
}
|
|
@@ -435,10 +502,20 @@ function readMailboxCounts(filePath: string, delivery: Record<string, MailboxMes
|
|
|
435
502
|
try {
|
|
436
503
|
const parsed = JSON.parse(line) as unknown;
|
|
437
504
|
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) return 0;
|
|
438
|
-
const msg = parsed as {
|
|
505
|
+
const msg = parsed as {
|
|
506
|
+
id?: unknown;
|
|
507
|
+
status?: unknown;
|
|
508
|
+
kind?: unknown;
|
|
509
|
+
data?: unknown;
|
|
510
|
+
};
|
|
439
511
|
if (typeof msg.id !== "string" || !isMailboxStatus(msg.status)) return 0;
|
|
440
512
|
if (msg.status !== "acknowledged" && delivery[msg.id] !== "acknowledged") {
|
|
441
|
-
const kind =
|
|
513
|
+
const kind =
|
|
514
|
+
typeof msg.kind === "string"
|
|
515
|
+
? msg.kind
|
|
516
|
+
: typeof (msg.data as Record<string, unknown>)?.kind === "string"
|
|
517
|
+
? ((msg.data as Record<string, unknown>).kind as string)
|
|
518
|
+
: undefined;
|
|
442
519
|
if (kind === "steer") kindCounts.steer++;
|
|
443
520
|
else if (kind === "follow-up") kindCounts.followUp++;
|
|
444
521
|
else if (kind === "response") kindCounts.response++;
|
|
@@ -451,19 +528,36 @@ function readMailboxCounts(filePath: string, delivery: Record<string, MailboxMes
|
|
|
451
528
|
}
|
|
452
529
|
}) as number[];
|
|
453
530
|
const count = items.reduce((sum, val) => sum + val, 0);
|
|
454
|
-
return {
|
|
531
|
+
return {
|
|
532
|
+
count,
|
|
533
|
+
approximate: tailApproximate(filePath),
|
|
534
|
+
steer: kindCounts.steer,
|
|
535
|
+
followUp: kindCounts.followUp,
|
|
536
|
+
response: kindCounts.response,
|
|
537
|
+
message: kindCounts.message,
|
|
538
|
+
};
|
|
455
539
|
}
|
|
456
540
|
|
|
457
541
|
async function readMailboxCountsAsync(filePath: string, delivery: Record<string, MailboxMessageStatus>): Promise<MailboxKindCount> {
|
|
458
542
|
const kindCounts = { steer: 0, followUp: 0, response: 0, message: 0 };
|
|
459
|
-
const items = await tailJsonlLinesAsync(filePath, MAX_TAIL_LINES, (line) => {
|
|
543
|
+
const items = (await tailJsonlLinesAsync(filePath, MAX_TAIL_LINES, (line) => {
|
|
460
544
|
try {
|
|
461
545
|
const parsed = JSON.parse(line) as unknown;
|
|
462
546
|
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) return 0;
|
|
463
|
-
const msg = parsed as {
|
|
547
|
+
const msg = parsed as {
|
|
548
|
+
id?: unknown;
|
|
549
|
+
status?: unknown;
|
|
550
|
+
kind?: unknown;
|
|
551
|
+
data?: unknown;
|
|
552
|
+
};
|
|
464
553
|
if (typeof msg.id !== "string" || !isMailboxStatus(msg.status)) return 0;
|
|
465
554
|
if (msg.status !== "acknowledged" && delivery[msg.id] !== "acknowledged") {
|
|
466
|
-
const kind =
|
|
555
|
+
const kind =
|
|
556
|
+
typeof msg.kind === "string"
|
|
557
|
+
? msg.kind
|
|
558
|
+
: typeof (msg.data as Record<string, unknown>)?.kind === "string"
|
|
559
|
+
? ((msg.data as Record<string, unknown>).kind as string)
|
|
560
|
+
: undefined;
|
|
467
561
|
if (kind === "steer") kindCounts.steer++;
|
|
468
562
|
else if (kind === "follow-up") kindCounts.followUp++;
|
|
469
563
|
else if (kind === "response") kindCounts.response++;
|
|
@@ -474,9 +568,16 @@ async function readMailboxCountsAsync(filePath: string, delivery: Record<string,
|
|
|
474
568
|
} catch {
|
|
475
569
|
return 0;
|
|
476
570
|
}
|
|
477
|
-
}) as number[];
|
|
571
|
+
})) as number[];
|
|
478
572
|
const count = items.reduce((sum, val) => sum + val, 0);
|
|
479
|
-
return {
|
|
573
|
+
return {
|
|
574
|
+
count,
|
|
575
|
+
approximate: await tailApproximateAsync(filePath),
|
|
576
|
+
steer: kindCounts.steer,
|
|
577
|
+
followUp: kindCounts.followUp,
|
|
578
|
+
response: kindCounts.response,
|
|
579
|
+
message: kindCounts.message,
|
|
580
|
+
};
|
|
480
581
|
}
|
|
481
582
|
|
|
482
583
|
function groupJoinsFrom(manifest: TeamRunManifest): RunUiGroupJoin[] {
|
|
@@ -509,7 +610,9 @@ function mailboxFrom(manifest: TeamRunManifest, agents: CrewAgentRecord[]): RunU
|
|
|
509
610
|
let outbox = readMailboxCounts(path.join(root, "outbox.jsonl"), delivery);
|
|
510
611
|
const tasksRoot = path.join(root, "tasks");
|
|
511
612
|
try {
|
|
512
|
-
for (const entry of fs.readdirSync(tasksRoot, {
|
|
613
|
+
for (const entry of fs.readdirSync(tasksRoot, {
|
|
614
|
+
withFileTypes: true,
|
|
615
|
+
})) {
|
|
513
616
|
if (!entry.isDirectory()) continue;
|
|
514
617
|
const taskInbox = readMailboxCounts(path.join(tasksRoot, entry.name, "inbox.jsonl"), delivery);
|
|
515
618
|
const taskOutbox = readMailboxCounts(path.join(tasksRoot, entry.name, "outbox.jsonl"), delivery);
|
|
@@ -521,8 +624,14 @@ function mailboxFrom(manifest: TeamRunManifest, agents: CrewAgentRecord[]): RunU
|
|
|
521
624
|
}
|
|
522
625
|
const attentionAgents = agents.filter((agent) => agent.progress?.activityState === "needs_attention").length;
|
|
523
626
|
return {
|
|
524
|
-
inboxUnread: inbox.count,
|
|
525
|
-
|
|
627
|
+
inboxUnread: inbox.count,
|
|
628
|
+
outboxPending: outbox.count,
|
|
629
|
+
needsAttention: inbox.count + attentionAgents,
|
|
630
|
+
approximate: inbox.approximate || outbox.approximate,
|
|
631
|
+
steerUnread: inbox.steer + outbox.steer,
|
|
632
|
+
followUpUnread: inbox.followUp + outbox.followUp,
|
|
633
|
+
responseUnread: inbox.response + outbox.response,
|
|
634
|
+
messageUnread: inbox.message + outbox.message,
|
|
526
635
|
};
|
|
527
636
|
}
|
|
528
637
|
|
|
@@ -533,7 +642,9 @@ async function mailboxFromAsync(manifest: TeamRunManifest, agents: CrewAgentReco
|
|
|
533
642
|
let outbox = await readMailboxCountsAsync(path.join(root, "outbox.jsonl"), delivery);
|
|
534
643
|
const tasksRoot = path.join(root, "tasks");
|
|
535
644
|
try {
|
|
536
|
-
for (const entry of await fs.promises.readdir(tasksRoot, {
|
|
645
|
+
for (const entry of await fs.promises.readdir(tasksRoot, {
|
|
646
|
+
withFileTypes: true,
|
|
647
|
+
})) {
|
|
537
648
|
if (!entry.isDirectory()) continue;
|
|
538
649
|
const taskInbox = await readMailboxCountsAsync(path.join(tasksRoot, entry.name, "inbox.jsonl"), delivery);
|
|
539
650
|
const taskOutbox = await readMailboxCountsAsync(path.join(tasksRoot, entry.name, "outbox.jsonl"), delivery);
|
|
@@ -545,33 +656,59 @@ async function mailboxFromAsync(manifest: TeamRunManifest, agents: CrewAgentReco
|
|
|
545
656
|
}
|
|
546
657
|
const attentionAgents = agents.filter((agent) => agent.progress?.activityState === "needs_attention").length;
|
|
547
658
|
return {
|
|
548
|
-
inboxUnread: inbox.count,
|
|
549
|
-
|
|
659
|
+
inboxUnread: inbox.count,
|
|
660
|
+
outboxPending: outbox.count,
|
|
661
|
+
needsAttention: inbox.count + attentionAgents,
|
|
662
|
+
approximate: inbox.approximate || outbox.approximate,
|
|
663
|
+
steerUnread: inbox.steer + outbox.steer,
|
|
664
|
+
followUpUnread: inbox.followUp + outbox.followUp,
|
|
665
|
+
responseUnread: inbox.response + outbox.response,
|
|
666
|
+
messageUnread: inbox.message + outbox.message,
|
|
550
667
|
};
|
|
551
668
|
}
|
|
552
669
|
|
|
553
670
|
function cancellationReasonFromEvents(events: TeamEvent[]): string | undefined {
|
|
554
|
-
return [...events].reverse().find((event) => event.type === "run.cancelled" && typeof event.data?.reason === "string")?.data?.reason as
|
|
671
|
+
return [...events].reverse().find((event) => event.type === "run.cancelled" && typeof event.data?.reason === "string")?.data?.reason as
|
|
672
|
+
| string
|
|
673
|
+
| undefined;
|
|
555
674
|
}
|
|
556
675
|
|
|
557
676
|
function signatureFor(input: Omit<RunUiSnapshot, "signature" | "fetchedAt" | "sliceSignatures">, stamps: SnapshotStamps): string {
|
|
558
677
|
try {
|
|
559
678
|
const digest = createHash("sha256");
|
|
560
|
-
digest.update(
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
679
|
+
digest.update(
|
|
680
|
+
JSON.stringify({
|
|
681
|
+
run: [input.manifest.runId, input.manifest.status, input.manifest.updatedAt, input.manifest.artifacts.length],
|
|
682
|
+
tasks: input.tasks.map((task) => [task.id, task.status, task.startedAt, task.finishedAt, task.agentProgress, task.usage]),
|
|
683
|
+
agents: input.agents.map((agent) => [
|
|
684
|
+
agent.id,
|
|
685
|
+
agent.status,
|
|
686
|
+
agent.startedAt,
|
|
687
|
+
agent.completedAt,
|
|
688
|
+
agent.toolUses,
|
|
689
|
+
agent.progress,
|
|
690
|
+
agent.usage,
|
|
691
|
+
agent.model,
|
|
692
|
+
]),
|
|
693
|
+
progress: input.progress,
|
|
694
|
+
usage: input.usage,
|
|
695
|
+
mailbox: input.mailbox,
|
|
696
|
+
groupJoins: input.groupJoins,
|
|
697
|
+
events: input.recentEvents.map((event) => [
|
|
698
|
+
event.metadata?.seq,
|
|
699
|
+
event.time,
|
|
700
|
+
event.type,
|
|
701
|
+
event.taskId,
|
|
702
|
+
event.message,
|
|
703
|
+
event.data?.reason,
|
|
704
|
+
]),
|
|
705
|
+
cancellationReason: input.cancellationReason,
|
|
706
|
+
dwfPhaseState: input.dwfPhaseState,
|
|
707
|
+
output: input.recentOutputLines,
|
|
708
|
+
stamps,
|
|
709
|
+
}),
|
|
710
|
+
);
|
|
711
|
+
return digest.digest("hex").slice(0, 16);
|
|
575
712
|
} catch {
|
|
576
713
|
// Circular reference or non-serializable data — fall back to timestamp.
|
|
577
714
|
return String(Date.now());
|
|
@@ -593,10 +730,30 @@ function sliceSignaturesFor(input: Omit<RunUiSnapshot, "signature" | "fetchedAt"
|
|
|
593
730
|
};
|
|
594
731
|
return {
|
|
595
732
|
tasks: hash(input.tasks.map((task) => [task.id, task.status, task.startedAt, task.finishedAt, task.agentProgress, task.usage])),
|
|
596
|
-
agents: hash(
|
|
733
|
+
agents: hash(
|
|
734
|
+
input.agents.map((agent) => [
|
|
735
|
+
agent.id,
|
|
736
|
+
agent.status,
|
|
737
|
+
agent.startedAt,
|
|
738
|
+
agent.completedAt,
|
|
739
|
+
agent.toolUses,
|
|
740
|
+
agent.progress,
|
|
741
|
+
agent.usage,
|
|
742
|
+
agent.model,
|
|
743
|
+
]),
|
|
744
|
+
),
|
|
597
745
|
mailbox: hash([input.mailbox, input.groupJoins]),
|
|
598
746
|
progress: hash([input.progress, input.usage, input.cancellationReason]),
|
|
599
|
-
events: hash(
|
|
747
|
+
events: hash(
|
|
748
|
+
input.recentEvents.map((event) => [
|
|
749
|
+
event.metadata?.seq,
|
|
750
|
+
event.time,
|
|
751
|
+
event.type,
|
|
752
|
+
event.taskId,
|
|
753
|
+
event.message,
|
|
754
|
+
event.data?.reason,
|
|
755
|
+
]),
|
|
756
|
+
),
|
|
600
757
|
};
|
|
601
758
|
}
|
|
602
759
|
|
|
@@ -623,7 +780,13 @@ async function stampsForAsync(manifest: TeamRunManifest, _agents: CrewAgentRecor
|
|
|
623
780
|
eventsStampAsync(manifest.eventsPath),
|
|
624
781
|
mailboxStampAsync(manifest),
|
|
625
782
|
]);
|
|
626
|
-
return {
|
|
783
|
+
return {
|
|
784
|
+
manifest: manifestStamp,
|
|
785
|
+
tasks: tasksStamp,
|
|
786
|
+
agents: agentsStamp,
|
|
787
|
+
events: eventsStampValue,
|
|
788
|
+
mailbox,
|
|
789
|
+
};
|
|
627
790
|
}
|
|
628
791
|
|
|
629
792
|
export function createRunSnapshotCache(cwd: string, options: RunSnapshotCacheOptions = {}): RunSnapshotCache {
|
|
@@ -691,8 +854,18 @@ export function createRunSnapshotCache(cwd: string, options: RunSnapshotCacheOpt
|
|
|
691
854
|
recentOutputLines: recentOutputLines(loaded.manifest, agents, recentOutputLimit),
|
|
692
855
|
};
|
|
693
856
|
const stamps = stampsFor(loaded.manifest, agents);
|
|
694
|
-
const snapshot: RunUiSnapshot = {
|
|
695
|
-
|
|
857
|
+
const snapshot: RunUiSnapshot = {
|
|
858
|
+
...base,
|
|
859
|
+
fetchedAt: Date.now(),
|
|
860
|
+
signature: signatureFor(base, stamps),
|
|
861
|
+
sliceSignatures: sliceSignaturesFor(base),
|
|
862
|
+
};
|
|
863
|
+
return {
|
|
864
|
+
snapshot,
|
|
865
|
+
stamps,
|
|
866
|
+
loadedAtMs: snapshot.fetchedAt,
|
|
867
|
+
lastAccessMs: snapshot.fetchedAt,
|
|
868
|
+
};
|
|
696
869
|
}
|
|
697
870
|
|
|
698
871
|
async function buildAsync(runId: string, previous?: CacheEntry): Promise<CacheEntry> {
|
|
@@ -738,8 +911,18 @@ export function createRunSnapshotCache(cwd: string, options: RunSnapshotCacheOpt
|
|
|
738
911
|
recentOutputLines: recentOutput,
|
|
739
912
|
};
|
|
740
913
|
const stamps = await stampsForAsync(loaded.manifest, agents);
|
|
741
|
-
const snapshot: RunUiSnapshot = {
|
|
742
|
-
|
|
914
|
+
const snapshot: RunUiSnapshot = {
|
|
915
|
+
...base,
|
|
916
|
+
fetchedAt: Date.now(),
|
|
917
|
+
signature: signatureFor(base, stamps),
|
|
918
|
+
sliceSignatures: sliceSignaturesFor(base),
|
|
919
|
+
};
|
|
920
|
+
return {
|
|
921
|
+
snapshot,
|
|
922
|
+
stamps,
|
|
923
|
+
loadedAtMs: snapshot.fetchedAt,
|
|
924
|
+
lastAccessMs: snapshot.fetchedAt,
|
|
925
|
+
};
|
|
743
926
|
}
|
|
744
927
|
|
|
745
928
|
function currentStamps(previous: CacheEntry): SnapshotStamps {
|
|
@@ -819,10 +1002,17 @@ export function createRunSnapshotCache(cwd: string, options: RunSnapshotCacheOpt
|
|
|
819
1002
|
const scheduleRefresh = (runId: string): void => {
|
|
820
1003
|
const existing = pendingRefreshes.get(runId);
|
|
821
1004
|
if (existing) clearTimeout(existing);
|
|
822
|
-
pendingRefreshes.set(
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
1005
|
+
pendingRefreshes.set(
|
|
1006
|
+
runId,
|
|
1007
|
+
setTimeout(() => {
|
|
1008
|
+
pendingRefreshes.delete(runId);
|
|
1009
|
+
try {
|
|
1010
|
+
localRefreshIfStale(runId);
|
|
1011
|
+
} catch {
|
|
1012
|
+
/* best-effort; widget falls back gracefully */
|
|
1013
|
+
}
|
|
1014
|
+
}, INVAL_COALESCE_MS),
|
|
1015
|
+
);
|
|
826
1016
|
};
|
|
827
1017
|
const unsubState = runEventBus.onChannel("run:state", (event) => {
|
|
828
1018
|
if (entries.has(event.runId)) scheduleRefresh(event.runId);
|