pi-crew 0.9.53 → 0.9.55
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 +45 -0
- package/package.json +6 -3
- package/scripts/clean-strip-types.mjs +60 -0
- package/src/adapters/claude-adapter.ts +23 -0
- package/src/adapters/codex-adapter.ts +21 -0
- package/src/adapters/cursor-adapter.ts +17 -0
- package/src/adapters/export-util.ts +143 -0
- package/src/adapters/index.ts +15 -0
- package/src/adapters/registry.ts +18 -0
- package/src/adapters/types.ts +23 -0
- package/src/agents/agent-config.ts +194 -0
- package/src/agents/agent-search.ts +98 -0
- package/src/agents/agent-serializer.ts +38 -0
- package/src/agents/discover-agents.ts +623 -0
- package/src/benchmark/benchmark-runner.ts +313 -0
- package/src/benchmark/feedback-loop.ts +73 -0
- package/src/config/config.ts +1270 -0
- package/src/config/defaults.ts +193 -0
- package/src/config/drift-detector.ts +290 -0
- package/src/config/markers.ts +330 -0
- package/src/config/resilient-parser.ts +117 -0
- package/src/config/role-tools.ts +118 -0
- package/src/config/suggestions.ts +75 -0
- package/src/config/types.ts +280 -0
- package/src/errors.ts +194 -0
- package/src/extension/action-suggestions.ts +117 -0
- package/src/extension/async-notifier.ts +179 -0
- package/src/extension/autonomous-policy.ts +209 -0
- package/src/extension/command-completions.ts +120 -0
- package/src/extension/context-status-injection.ts +185 -0
- package/src/extension/crew-autocomplete.ts +131 -0
- package/src/extension/crew-cleanup.ts +168 -0
- package/src/extension/crew-input-router.ts +93 -0
- package/src/extension/crew-shortcuts.ts +87 -0
- package/src/extension/crew-vibes/cat-frames.ts +18 -0
- package/src/extension/crew-vibes/config.ts +195 -0
- package/src/extension/crew-vibes/figures.ts +101 -0
- package/src/extension/crew-vibes/font-detect.ts +71 -0
- package/src/extension/crew-vibes/footer.ts +292 -0
- package/src/extension/crew-vibes/index.ts +432 -0
- package/src/extension/crew-vibes/provider-usage.ts +396 -0
- package/src/extension/crew-vibes/render.ts +206 -0
- package/src/extension/crew-vibes/speed.ts +286 -0
- package/src/extension/cross-extension-rpc.ts +350 -0
- package/src/extension/help.ts +62 -0
- package/src/extension/import-index.ts +74 -0
- package/src/extension/knowledge-injection.ts +402 -0
- package/src/extension/management.ts +571 -0
- package/src/extension/message-renderers.ts +108 -0
- package/src/extension/notification-router.ts +152 -0
- package/src/extension/notification-sink.ts +54 -0
- package/src/extension/pi-api.ts +56 -0
- package/src/extension/plan-orchestrate.ts +302 -0
- package/src/extension/project-init.ts +170 -0
- package/src/extension/register.ts +113 -0
- package/src/extension/registration/artifact-cleanup.ts +20 -0
- package/src/extension/registration/command-registration.ts +58 -0
- package/src/extension/registration/command-utils.ts +58 -0
- package/src/extension/registration/commands.ts +1228 -0
- package/src/extension/registration/compaction-guard.ts +333 -0
- package/src/extension/registration/context-builder.ts +135 -0
- package/src/extension/registration/crash-recovery-cache.ts +54 -0
- package/src/extension/registration/foreground-run-controller.ts +238 -0
- package/src/extension/registration/hook-registration.ts +119 -0
- package/src/extension/registration/lazy-configurers.ts +124 -0
- package/src/extension/registration/lifecycle-handlers.ts +923 -0
- package/src/extension/registration/lifecycle.ts +259 -0
- package/src/extension/registration/observability.ts +322 -0
- package/src/extension/registration/registration-types.ts +158 -0
- package/src/extension/registration/runtime-cleanup.ts +230 -0
- package/src/extension/registration/subagent-helpers.ts +125 -0
- package/src/extension/registration/subagent-manager-setup.ts +330 -0
- package/src/extension/registration/subagent-tools.ts +456 -0
- package/src/extension/registration/team-tool.ts +225 -0
- package/src/extension/registration/tool-registration.ts +50 -0
- package/src/extension/registration/ui.ts +172 -0
- package/src/extension/registration/viewers.ts +121 -0
- package/src/extension/registration/wire-cross-extension.ts +37 -0
- package/src/extension/result-watcher.ts +139 -0
- package/src/extension/rpc-hmac.ts +256 -0
- package/src/extension/run-bundle-schema.ts +104 -0
- package/src/extension/run-export.ts +97 -0
- package/src/extension/run-import.ts +168 -0
- package/src/extension/run-index.ts +131 -0
- package/src/extension/run-maintenance.ts +190 -0
- package/src/extension/session-summary.ts +18 -0
- package/src/extension/team-manager-command.ts +153 -0
- package/src/extension/team-onboard.ts +180 -0
- package/src/extension/team-recommendation.ts +288 -0
- package/src/extension/team-tool/anchor.ts +172 -0
- package/src/extension/team-tool/api.ts +1244 -0
- package/src/extension/team-tool/auto-summarize.ts +142 -0
- package/src/extension/team-tool/cache-control.ts +19 -0
- package/src/extension/team-tool/cancel.ts +337 -0
- package/src/extension/team-tool/chain-dispatch.ts +95 -0
- package/src/extension/team-tool/chain-executor.ts +379 -0
- package/src/extension/team-tool/config-patch.ts +50 -0
- package/src/extension/team-tool/context.ts +149 -0
- package/src/extension/team-tool/destructive-gate.ts +52 -0
- package/src/extension/team-tool/dispatch/automate.ts +80 -0
- package/src/extension/team-tool/dispatch/control.ts +42 -0
- package/src/extension/team-tool/dispatch/index.ts +95 -0
- package/src/extension/team-tool/dispatch/manage.ts +161 -0
- package/src/extension/team-tool/dispatch/run.ts +53 -0
- package/src/extension/team-tool/dispatch/status.ts +187 -0
- package/src/extension/team-tool/doctor.ts +431 -0
- package/src/extension/team-tool/explain.ts +282 -0
- package/src/extension/team-tool/failure-patterns.ts +118 -0
- package/src/extension/team-tool/goal-wrap.ts +330 -0
- package/src/extension/team-tool/goal.ts +556 -0
- package/src/extension/team-tool/handle-schedule.ts +332 -0
- package/src/extension/team-tool/handle-settings.ts +520 -0
- package/src/extension/team-tool/health-monitor.ts +481 -0
- package/src/extension/team-tool/inspect.ts +88 -0
- package/src/extension/team-tool/intent-policy.ts +45 -0
- package/src/extension/team-tool/lifecycle-actions.ts +615 -0
- package/src/extension/team-tool/orchestrate.ts +98 -0
- package/src/extension/team-tool/parallel-dispatch.ts +183 -0
- package/src/extension/team-tool/plan.ts +50 -0
- package/src/extension/team-tool/respond.ts +150 -0
- package/src/extension/team-tool/run-deadline.ts +66 -0
- package/src/extension/team-tool/run-not-found.ts +49 -0
- package/src/extension/team-tool/run.ts +1051 -0
- package/src/extension/team-tool/status.ts +260 -0
- package/src/extension/team-tool/workflow-manage.ts +261 -0
- package/src/extension/team-tool-types.ts +26 -0
- package/src/extension/team-tool.ts +750 -0
- package/src/extension/tool-result.ts +16 -0
- package/src/extension/validate-resources.ts +108 -0
- package/src/hooks/registry.ts +200 -0
- package/src/hooks/types.ts +69 -0
- package/src/i18n.ts +212 -0
- package/src/observability/correlation.ts +50 -0
- package/src/observability/event-bus.ts +86 -0
- package/src/observability/event-to-metric.ts +170 -0
- package/src/observability/exporters/adapter.ts +27 -0
- package/src/observability/exporters/otlp-exporter.ts +356 -0
- package/src/observability/exporters/prometheus-exporter.ts +54 -0
- package/src/observability/metric-registry.ts +100 -0
- package/src/observability/metric-retention.ts +64 -0
- package/src/observability/metric-sink.ts +99 -0
- package/src/observability/metrics-primitives.ts +219 -0
- package/src/plugins/plugin-define.ts +6 -0
- package/src/plugins/plugin-registry.ts +32 -0
- package/src/plugins/plugins/index.ts +3 -0
- package/src/plugins/plugins/nextjs.ts +19 -0
- package/src/plugins/plugins/vite.ts +10 -0
- package/src/plugins/plugins/vitest.ts +9 -0
- package/src/prompt/prompt-runtime.ts +380 -0
- package/src/runtime/adaptive-plan.ts +563 -0
- package/src/runtime/agent-control.ts +215 -0
- package/src/runtime/agent-memory.ts +81 -0
- package/src/runtime/agent-observability.ts +122 -0
- package/src/runtime/anchor-manager.ts +475 -0
- package/src/runtime/async-marker.ts +32 -0
- package/src/runtime/async-runner.ts +381 -0
- package/src/runtime/attention-events.ts +28 -0
- package/src/runtime/auto-summarize.ts +344 -0
- package/src/runtime/background-runner.ts +840 -0
- package/src/runtime/batch-barrier.ts +147 -0
- package/src/runtime/broker-issuer.ts +39 -0
- package/src/runtime/cancellation-token.ts +99 -0
- package/src/runtime/cancellation.ts +99 -0
- package/src/runtime/capability-inventory.ts +137 -0
- package/src/runtime/chain-parser.ts +237 -0
- package/src/runtime/chain-runner.ts +606 -0
- package/src/runtime/checkpoint.ts +291 -0
- package/src/runtime/child-pi-constants.ts +42 -0
- package/src/runtime/child-pi-kill.ts +180 -0
- package/src/runtime/child-pi-pool.ts +68 -0
- package/src/runtime/child-pi-spawn.ts +287 -0
- package/src/runtime/child-pi-steering.ts +128 -0
- package/src/runtime/child-pi-streams.ts +296 -0
- package/src/runtime/child-pi-transcript.ts +169 -0
- package/src/runtime/child-pi.ts +1105 -0
- package/src/runtime/coalesce-tasks.ts +268 -0
- package/src/runtime/code-summary.ts +292 -0
- package/src/runtime/command-trace.ts +105 -0
- package/src/runtime/compact-pipeline.ts +56 -0
- package/src/runtime/compact-stages/ansi-strip-stage.ts +25 -0
- package/src/runtime/compact-stages/blank-collapse-stage.ts +31 -0
- package/src/runtime/compact-stages/deduplicate-stage.ts +34 -0
- package/src/runtime/compact-stages/head-snap-stage.ts +57 -0
- package/src/runtime/compact-stages/index.ts +23 -0
- package/src/runtime/compact-stages/tail-capture-stage.ts +77 -0
- package/src/runtime/compact-stages/truncation-stage.ts +74 -0
- package/src/runtime/compaction-summary.ts +278 -0
- package/src/runtime/completion-guard.ts +207 -0
- package/src/runtime/concurrency.ts +58 -0
- package/src/runtime/crash-classification.ts +229 -0
- package/src/runtime/crash-recovery.ts +594 -0
- package/src/runtime/crew-agent-records.ts +595 -0
- package/src/runtime/crew-agent-runtime.ts +62 -0
- package/src/runtime/crew-broker-child.ts +88 -0
- package/src/runtime/crew-broker-client.ts +673 -0
- package/src/runtime/crew-broker-tokens.ts +159 -0
- package/src/runtime/crew-broker.ts +1304 -0
- package/src/runtime/crew-hooks.ts +227 -0
- package/src/runtime/cross-extension-rpc.ts +143 -0
- package/src/runtime/custom-tools/irc-tool.ts +282 -0
- package/src/runtime/custom-tools/submit-result-tool.ts +102 -0
- package/src/runtime/deadletter.ts +47 -0
- package/src/runtime/delivery-coordinator.ts +211 -0
- package/src/runtime/delta-conflict.ts +348 -0
- package/src/runtime/deterministic-ast.ts +161 -0
- package/src/runtime/diagnostic-export.ts +171 -0
- package/src/runtime/direct-run.ts +45 -0
- package/src/runtime/dwf-state-store.ts +102 -0
- package/src/runtime/dynamic-workflow-context.ts +1013 -0
- package/src/runtime/dynamic-workflow-runner.ts +325 -0
- package/src/runtime/effectiveness.ts +90 -0
- package/src/runtime/errors/crew-errors.ts +162 -0
- package/src/runtime/event-stream-bridge.ts +98 -0
- package/src/runtime/foreground-control.ts +193 -0
- package/src/runtime/foreground-watchdog.ts +132 -0
- package/src/runtime/global-worker-cap.ts +96 -0
- package/src/runtime/goal-achievement.ts +148 -0
- package/src/runtime/goal-evaluator.ts +365 -0
- package/src/runtime/goal-loop-runner.ts +825 -0
- package/src/runtime/goal-state-store.ts +219 -0
- package/src/runtime/green-contract.ts +55 -0
- package/src/runtime/group-join.ts +267 -0
- package/src/runtime/handoff-manager.ts +598 -0
- package/src/runtime/heartbeat-gradient.ts +36 -0
- package/src/runtime/heartbeat-watcher.ts +239 -0
- package/src/runtime/hidden-handoff.ts +407 -0
- package/src/runtime/important-line-classifier.ts +140 -0
- package/src/runtime/intercom-bridge.ts +187 -0
- package/src/runtime/iteration-hooks.ts +305 -0
- package/src/runtime/live-agent-control.ts +136 -0
- package/src/runtime/live-agent-manager.ts +704 -0
- package/src/runtime/live-control-realtime.ts +56 -0
- package/src/runtime/live-extension-bridge.ts +148 -0
- package/src/runtime/live-irc.ts +97 -0
- package/src/runtime/live-session-health.ts +108 -0
- package/src/runtime/live-session-runtime.ts +1146 -0
- package/src/runtime/loop-gates.ts +128 -0
- package/src/runtime/manifest-cache.ts +375 -0
- package/src/runtime/mcp-proxy.ts +105 -0
- package/src/runtime/metric-parser.ts +36 -0
- package/src/runtime/model-fallback.ts +409 -0
- package/src/runtime/model-resolver.ts +126 -0
- package/src/runtime/model-scope.ts +158 -0
- package/src/runtime/orphan-worker-registry.ts +465 -0
- package/src/runtime/output-validator.ts +202 -0
- package/src/runtime/overflow-recovery.ts +206 -0
- package/src/runtime/parallel-research.ts +68 -0
- package/src/runtime/parallel-utils.ts +160 -0
- package/src/runtime/parent-guard.ts +134 -0
- package/src/runtime/path-overlap.ts +150 -0
- package/src/runtime/peer-dep.ts +292 -0
- package/src/runtime/per-write-validator.ts +181 -0
- package/src/runtime/phase-progress.ts +217 -0
- package/src/runtime/phase-tracker.ts +385 -0
- package/src/runtime/pi-args.ts +655 -0
- package/src/runtime/pi-json-output.ts +170 -0
- package/src/runtime/pi-spawn.ts +273 -0
- package/src/runtime/pipeline-runner.ts +523 -0
- package/src/runtime/plan-templates.ts +201 -0
- package/src/runtime/policy-engine.ts +115 -0
- package/src/runtime/post-checks.ts +142 -0
- package/src/runtime/post-exit-stdio-guard.ts +109 -0
- package/src/runtime/process-lifecycle.ts +491 -0
- package/src/runtime/process-status.ts +154 -0
- package/src/runtime/progress-event-coalescer.ts +44 -0
- package/src/runtime/progress-tracker.ts +124 -0
- package/src/runtime/prose-compressor.ts +162 -0
- package/src/runtime/recovery-recipes.ts +203 -0
- package/src/runtime/replace.ts +570 -0
- package/src/runtime/resilient-edit.ts +153 -0
- package/src/runtime/result-extractor.ts +217 -0
- package/src/runtime/retry-executor.ts +109 -0
- package/src/runtime/retry-runner.ts +336 -0
- package/src/runtime/role-permission.ts +59 -0
- package/src/runtime/run-coalesced-task-group.ts +308 -0
- package/src/runtime/run-drift.ts +219 -0
- package/src/runtime/run-tracker.ts +116 -0
- package/src/runtime/run-worker.ts +78 -0
- package/src/runtime/runtime-policy.ts +29 -0
- package/src/runtime/runtime-resolver.ts +172 -0
- package/src/runtime/runtime-warmup.ts +160 -0
- package/src/runtime/scheduler.ts +353 -0
- package/src/runtime/semaphore.ts +141 -0
- package/src/runtime/sensitive-paths.ts +93 -0
- package/src/runtime/session-resources.ts +25 -0
- package/src/runtime/session-snapshot.ts +59 -0
- package/src/runtime/session-usage.ts +79 -0
- package/src/runtime/settings-store.ts +155 -0
- package/src/runtime/sidechain-output.ts +35 -0
- package/src/runtime/single-agent-compose.ts +84 -0
- package/src/runtime/skill-effectiveness.ts +524 -0
- package/src/runtime/skill-instructions.ts +394 -0
- package/src/runtime/stale-reconciler.ts +680 -0
- package/src/runtime/stream-preview.ts +184 -0
- package/src/runtime/streaming-output.ts +50 -0
- package/src/runtime/subagent-manager.ts +561 -0
- package/src/runtime/subprocess-tool-registry.ts +70 -0
- package/src/runtime/supervisor-contact.ts +64 -0
- package/src/runtime/task-display.ts +52 -0
- package/src/runtime/task-graph-scheduler.ts +227 -0
- package/src/runtime/task-graph.ts +290 -0
- package/src/runtime/task-health.ts +83 -0
- package/src/runtime/task-id.ts +161 -0
- package/src/runtime/task-output-context.ts +602 -0
- package/src/runtime/task-packet.ts +268 -0
- package/src/runtime/task-quality.ts +199 -0
- package/src/runtime/task-runner/capabilities.ts +78 -0
- package/src/runtime/task-runner/child-executor.ts +790 -0
- package/src/runtime/task-runner/context-retrieval.ts +163 -0
- package/src/runtime/task-runner/live-executor.ts +227 -0
- package/src/runtime/task-runner/output-splitter.ts +152 -0
- package/src/runtime/task-runner/post-execution.ts +480 -0
- package/src/runtime/task-runner/pre-execution.ts +365 -0
- package/src/runtime/task-runner/progress.ts +157 -0
- package/src/runtime/task-runner/prompt-builder.ts +278 -0
- package/src/runtime/task-runner/prompt-pipeline.ts +88 -0
- package/src/runtime/task-runner/result-utils.ts +16 -0
- package/src/runtime/task-runner/retrieval-orchestrator.ts +310 -0
- package/src/runtime/task-runner/run-projection.ts +125 -0
- package/src/runtime/task-runner/scaffold-executor.ts +25 -0
- package/src/runtime/task-runner/state-helpers.ts +176 -0
- package/src/runtime/task-runner/tail-read.ts +34 -0
- package/src/runtime/task-runner.ts +216 -0
- package/src/runtime/team-runner-artifacts.ts +13 -0
- package/src/runtime/team-runner.ts +2396 -0
- package/src/runtime/tool-output-pruner.ts +333 -0
- package/src/runtime/tool-progress.ts +278 -0
- package/src/runtime/usage-tracker.ts +73 -0
- package/src/runtime/verification-gates.ts +579 -0
- package/src/runtime/verification-integrity.ts +108 -0
- package/src/runtime/verification-worktree.ts +186 -0
- package/src/runtime/worker-heartbeat.ts +25 -0
- package/src/runtime/worker-startup.ts +83 -0
- package/src/runtime/workflow-state.ts +195 -0
- package/src/runtime/workspace-lock.ts +443 -0
- package/src/runtime/workspace-tree.ts +312 -0
- package/src/runtime/yield-handler.ts +224 -0
- package/src/runtime/zombie-scanner.ts +298 -0
- package/src/schema/config-schema.ts +327 -0
- package/src/schema/team-tool-schema.ts +492 -0
- package/src/schema/validation-types.ts +159 -0
- package/src/skills/discover-skills.ts +203 -0
- package/src/skills/skill-templates.ts +456 -0
- package/src/skills/validate.ts +285 -0
- package/src/state/active-run-registry.ts +439 -0
- package/src/state/artifact-store.ts +176 -0
- package/src/state/atomic-write.ts +970 -0
- package/src/state/blob-store.ts +308 -0
- package/src/state/contracts.ts +160 -0
- package/src/state/crew-init.ts +269 -0
- package/src/state/decision-ledger.ts +372 -0
- package/src/state/event-log-rotation.ts +399 -0
- package/src/state/event-log.ts +1465 -0
- package/src/state/event-reconstructor.ts +229 -0
- package/src/state/gitignore-manager.ts +46 -0
- package/src/state/health-store.ts +79 -0
- package/src/state/hook-instinct-bridge.ts +94 -0
- package/src/state/hook-integrations.ts +51 -0
- package/src/state/instinct-store.ts +275 -0
- package/src/state/jsonl-writer.ts +107 -0
- package/src/state/locks.ts +562 -0
- package/src/state/mailbox.ts +916 -0
- package/src/state/observation-store.ts +176 -0
- package/src/state/run-cache.ts +193 -0
- package/src/state/run-graph.ts +183 -0
- package/src/state/run-metrics.ts +165 -0
- package/src/state/schedule.ts +166 -0
- package/src/state/session-state-map.ts +51 -0
- package/src/state/state-store.ts +973 -0
- package/src/state/task-claims.ts +61 -0
- package/src/state/tiered-eval.ts +480 -0
- package/src/state/types-eval.ts +58 -0
- package/src/state/types.ts +447 -0
- package/src/state/usage.ts +138 -0
- package/src/state/worker-atomic-writer.ts +198 -0
- package/src/subagents/async-entry.ts +1 -0
- package/src/subagents/index.ts +3 -0
- package/src/subagents/live/control.ts +1 -0
- package/src/subagents/live/manager.ts +1 -0
- package/src/subagents/live/realtime.ts +1 -0
- package/src/subagents/live/session-runtime.ts +1 -0
- package/src/subagents/manager.ts +1 -0
- package/src/subagents/spawn.ts +1 -0
- package/src/teams/discover-teams.ts +187 -0
- package/src/teams/team-config.ts +27 -0
- package/src/teams/team-serializer.ts +38 -0
- package/src/tools/safe-bash-extension.ts +54 -0
- package/src/tools/safe-bash.ts +505 -0
- package/src/types/diff.d.ts +18 -0
- package/src/types/new-api-types.ts +35 -0
- package/src/ui/agent-management-overlay.ts +160 -0
- package/src/ui/card-colors.ts +139 -0
- package/src/ui/crew-footer.ts +102 -0
- package/src/ui/crew-select-list.ts +112 -0
- package/src/ui/dashboard-panes/agents-pane.ts +164 -0
- package/src/ui/dashboard-panes/cancellation-pane.ts +66 -0
- package/src/ui/dashboard-panes/capability-pane.ts +77 -0
- package/src/ui/dashboard-panes/health-pane.ts +31 -0
- package/src/ui/dashboard-panes/mailbox-pane.ts +35 -0
- package/src/ui/dashboard-panes/metrics-pane.ts +37 -0
- package/src/ui/dashboard-panes/progress-pane.ts +38 -0
- package/src/ui/dashboard-panes/transcript-pane.ts +10 -0
- package/src/ui/deploy-bundled-themes.ts +71 -0
- package/src/ui/dwf-phase-display.ts +151 -0
- package/src/ui/dynamic-border.ts +35 -0
- package/src/ui/format-helpers.ts +31 -0
- package/src/ui/heartbeat-aggregator.ts +74 -0
- package/src/ui/key-utils.ts +42 -0
- package/src/ui/keybinding-map.ts +248 -0
- package/src/ui/layout-primitives.ts +106 -0
- package/src/ui/live-conversation-overlay.ts +183 -0
- package/src/ui/live-duration.ts +55 -0
- package/src/ui/live-run-sidebar.ts +293 -0
- package/src/ui/loaders.ts +6 -0
- package/src/ui/mascot.ts +449 -0
- package/src/ui/overlays/agent-picker-overlay.ts +66 -0
- package/src/ui/overlays/confirm-overlay.ts +60 -0
- package/src/ui/overlays/help-overlay.ts +177 -0
- package/src/ui/overlays/mailbox-compose-overlay.ts +181 -0
- package/src/ui/overlays/mailbox-compose-preview.ts +78 -0
- package/src/ui/overlays/mailbox-detail-overlay.ts +155 -0
- package/src/ui/pi-ui-compat.ts +68 -0
- package/src/ui/powerbar-publisher.ts +459 -0
- package/src/ui/render-coalescer.ts +101 -0
- package/src/ui/render-diff.ts +160 -0
- package/src/ui/render-scheduler.ts +278 -0
- package/src/ui/run-action-dispatcher.ts +182 -0
- package/src/ui/run-dashboard.ts +910 -0
- package/src/ui/run-event-bus.ts +381 -0
- package/src/ui/run-snapshot-cache.ts +1057 -0
- package/src/ui/settings-overlay.ts +1067 -0
- package/src/ui/shared-overlay-scheduler.ts +96 -0
- package/src/ui/snapshot-types.ts +90 -0
- package/src/ui/spinner.ts +17 -0
- package/src/ui/status-colors.ts +143 -0
- package/src/ui/syntax-highlight.ts +136 -0
- package/src/ui/terminal-status.ts +269 -0
- package/src/ui/theme-adapter.ts +271 -0
- package/src/ui/theme-discovery.ts +199 -0
- package/src/ui/tool-progress-formatter.ts +93 -0
- package/src/ui/tool-renderers/brief-mode.ts +225 -0
- package/src/ui/tool-renderers/index.ts +726 -0
- package/src/ui/transcript-cache.ts +128 -0
- package/src/ui/transcript-entries.ts +256 -0
- package/src/ui/transcript-viewer.ts +424 -0
- package/src/ui/widget/index.ts +418 -0
- package/src/ui/widget/widget-formatters.ts +182 -0
- package/src/ui/widget/widget-model.ts +110 -0
- package/src/ui/widget/widget-renderer.ts +182 -0
- package/src/ui/widget/widget-types.ts +36 -0
- package/src/utils/bm25-search.ts +235 -0
- package/src/utils/completion-dedupe.ts +63 -0
- package/src/utils/conflict-detect.ts +668 -0
- package/src/utils/env-allowlist.ts +30 -0
- package/src/utils/env-filter.ts +155 -0
- package/src/utils/file-coalescer.ts +98 -0
- package/src/utils/fingerprint.ts +180 -0
- package/src/utils/frontmatter.ts +70 -0
- package/src/utils/fs-watch.ts +37 -0
- package/src/utils/gh-protocol.ts +556 -0
- package/src/utils/git.ts +260 -0
- package/src/utils/guards.ts +107 -0
- package/src/utils/ids.ts +24 -0
- package/src/utils/incremental-reader.ts +220 -0
- package/src/utils/internal-error.ts +10 -0
- package/src/utils/names.ts +36 -0
- package/src/utils/ndjson.ts +115 -0
- package/src/utils/paths.ts +227 -0
- package/src/utils/project-detector.ts +160 -0
- package/src/utils/redaction.ts +370 -0
- package/src/utils/resolve-shell.ts +36 -0
- package/src/utils/run-watcher-registry.ts +152 -0
- package/src/utils/safe-paths.ts +393 -0
- package/src/utils/scan-cache.ts +144 -0
- package/src/utils/session-utils.ts +110 -0
- package/src/utils/sleep.ts +54 -0
- package/src/utils/socket-path.ts +164 -0
- package/src/utils/sse-parser.ts +131 -0
- package/src/utils/task-name-generator.ts +337 -0
- package/src/utils/timings.ts +33 -0
- package/src/utils/token-counter.ts +200 -0
- package/src/utils/visual.ts +207 -0
- package/src/workflows/cost-estimator.ts +34 -0
- package/src/workflows/discover-workflows.ts +308 -0
- package/src/workflows/intermediate-store.ts +166 -0
- package/src/workflows/preflight-validator.ts +168 -0
- package/src/workflows/topology-analyzer.ts +203 -0
- package/src/workflows/validate-workflow.ts +50 -0
- package/src/workflows/workflow-config.ts +75 -0
- package/src/workflows/workflow-serializer.ts +32 -0
- package/src/worktree/branch-freshness.ts +112 -0
- package/src/worktree/cleanup.ts +341 -0
- package/src/worktree/worktree-manager.ts +1204 -0
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* deterministic-ast.ts — AST-based determinism enforcement for dynamic-workflow scripts (round-13 P0-2).
|
|
3
|
+
*
|
|
4
|
+
* Rejects `Date.now()`, `Math.random()`, and `new Date()` at workflow-load time
|
|
5
|
+
* using a true AST walk (not regex) so that:
|
|
6
|
+
* - Prompts mentioning "Date.now()" as string literals are accepted.
|
|
7
|
+
* - Comments containing "Date.now()" are accepted.
|
|
8
|
+
* - `Date.parse()`, `Date.UTC()`, `Math.floor()`, etc. are accepted (only `now` and `random` are blocked).
|
|
9
|
+
*
|
|
10
|
+
* Adapted from pi-dynamic-workflows/src/workflow.ts (MIT) — see NOTICE.md.
|
|
11
|
+
*
|
|
12
|
+
* The walker uses acorn's parse() with permissive flags (allowAwaitOutsideFunction,
|
|
13
|
+
* allowReturnOutsideFunction) so we don't reject perfectly valid workflow scripts
|
|
14
|
+
* that contain top-level `await` or `return`.
|
|
15
|
+
*
|
|
16
|
+
* On parse error, this function returns silently: jiti will surface a clearer
|
|
17
|
+
* parse error downstream. We don't double-report parse errors.
|
|
18
|
+
*/
|
|
19
|
+
|
|
20
|
+
import { parse } from "acorn";
|
|
21
|
+
|
|
22
|
+
const NONDETERMINISM_ERROR =
|
|
23
|
+
"Workflow scripts must be deterministic: Date.now()/Math.random()/new Date() are unavailable. These introduce non-reproducible behavior across runs. Use ctx.vars for cached state, or pass a fixed seed via ctx.setArgs(). To bypass this check (escape hatch), set PI_CREW_DWF_SKIP_DETERMINISM_CHECK=1.";
|
|
24
|
+
|
|
25
|
+
export class DeterminismError extends Error {
|
|
26
|
+
constructor() {
|
|
27
|
+
super(NONDETERMINISM_ERROR);
|
|
28
|
+
this.name = "DeterminismError";
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Parse `script` and walk the AST looking for non-deterministic calls.
|
|
34
|
+
* Throws DeterminismError on the first hit. Silently returns on parse error
|
|
35
|
+
* (jiti will produce a clearer message downstream).
|
|
36
|
+
*/
|
|
37
|
+
export function assertDeterministicScript(script: string): void {
|
|
38
|
+
let ast: AstNode;
|
|
39
|
+
try {
|
|
40
|
+
ast = parse(script, {
|
|
41
|
+
ecmaVersion: "latest",
|
|
42
|
+
sourceType: "module",
|
|
43
|
+
allowAwaitOutsideFunction: true,
|
|
44
|
+
allowReturnOutsideFunction: true,
|
|
45
|
+
ranges: false,
|
|
46
|
+
}) as unknown as AstNode;
|
|
47
|
+
} catch {
|
|
48
|
+
// Parse errors are handled by jiti downstream — don't double-report.
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
assertDeterministicAst(ast);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Escape hatch: when PI_CREW_DWF_SKIP_DETERMINISM_CHECK=1 the check is bypassed.
|
|
56
|
+
* Power users may need this when a workflow legitimately depends on time/random
|
|
57
|
+
* (e.g. randomized benchmark scripts).
|
|
58
|
+
*/
|
|
59
|
+
export function isDeterminismCheckEnabled(): boolean {
|
|
60
|
+
return process.env.PI_CREW_DWF_SKIP_DETERMINISM_CHECK !== "1";
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
// ---------------------------------------------------------------------------
|
|
64
|
+
// AST walker
|
|
65
|
+
// ---------------------------------------------------------------------------
|
|
66
|
+
|
|
67
|
+
interface AstNode {
|
|
68
|
+
type: string;
|
|
69
|
+
[key: string]: unknown;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
function asAstNode(value: unknown): AstNode | undefined {
|
|
73
|
+
if (!value || typeof value !== "object") return undefined;
|
|
74
|
+
const obj = value as Record<string, unknown>;
|
|
75
|
+
if (typeof obj.type !== "string") return undefined;
|
|
76
|
+
return obj as AstNode;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
function astChildren(node: AstNode): AstNode[] {
|
|
80
|
+
const out: AstNode[] = [];
|
|
81
|
+
for (const value of Object.values(node)) {
|
|
82
|
+
if (Array.isArray(value)) {
|
|
83
|
+
for (const item of value) {
|
|
84
|
+
const child = asAstNode(item);
|
|
85
|
+
if (child) out.push(child);
|
|
86
|
+
}
|
|
87
|
+
} else {
|
|
88
|
+
const child = asAstNode(value);
|
|
89
|
+
if (child) out.push(child);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
return out;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
function assertDeterministicAst(node: AstNode): void {
|
|
96
|
+
if (isDateNowCall(node) || isMathRandomCall(node) || isNewDateExpression(node)) {
|
|
97
|
+
throw new DeterminismError();
|
|
98
|
+
}
|
|
99
|
+
for (const child of astChildren(node)) assertDeterministicAst(child);
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
function isDateNowCall(node: AstNode): boolean {
|
|
103
|
+
return node.type === "CallExpression" && isMemberExpression(node, "callee", "Date", "now");
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
function isMathRandomCall(node: AstNode): boolean {
|
|
107
|
+
return node.type === "CallExpression" && isMemberExpression(node, "callee", "Math", "random");
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
function isNewDateExpression(node: AstNode): boolean {
|
|
111
|
+
if (node.type !== "NewExpression") return false;
|
|
112
|
+
const callee = asAstNode(node.callee);
|
|
113
|
+
return callee?.type === "Identifier" && callee.name === "Date";
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* Test whether `node[childKey]` is a MemberExpression of shape `objectName.propertyName`,
|
|
118
|
+
* where the property is either a static Identifier or a resolvable static string.
|
|
119
|
+
* `childKey` is the property name on `node` (usually "callee" for CallExpression).
|
|
120
|
+
*/
|
|
121
|
+
function isMemberExpression(node: AstNode, childKey: string, objectName: string, propertyName: string): boolean {
|
|
122
|
+
const child = asAstNode(node[childKey]);
|
|
123
|
+
if (child?.type !== "MemberExpression") return false;
|
|
124
|
+
const object = asAstNode(child.object);
|
|
125
|
+
if (object?.type !== "Identifier" || object.name !== objectName) return false;
|
|
126
|
+
return propertyNameOf(child) === propertyName;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
function propertyNameOf(node: AstNode): string | undefined {
|
|
130
|
+
const computed = node.computed === true;
|
|
131
|
+
const property = asAstNode(node.property);
|
|
132
|
+
if (!property) return undefined;
|
|
133
|
+
if (!computed && property.type === "Identifier") {
|
|
134
|
+
return property.name as string | undefined;
|
|
135
|
+
}
|
|
136
|
+
return staticStringOf(property);
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
function staticStringOf(node: AstNode | undefined): string | undefined {
|
|
140
|
+
if (!node) return undefined;
|
|
141
|
+
if (node.type === "Literal" && typeof node.value === "string") return node.value;
|
|
142
|
+
if (node.type === "TemplateLiteral") {
|
|
143
|
+
const expressions = node.expressions;
|
|
144
|
+
if (Array.isArray(expressions) && expressions.length > 0) return undefined;
|
|
145
|
+
const quasis = node.quasis;
|
|
146
|
+
if (!Array.isArray(quasis)) return undefined;
|
|
147
|
+
return quasis
|
|
148
|
+
.map((q) => {
|
|
149
|
+
const quasi = asAstNode(q);
|
|
150
|
+
const value = quasi?.value as { cooked?: string; raw?: string } | undefined;
|
|
151
|
+
return value?.cooked ?? value?.raw ?? "";
|
|
152
|
+
})
|
|
153
|
+
.join("");
|
|
154
|
+
}
|
|
155
|
+
if (node.type === "BinaryExpression" && node.operator === "+") {
|
|
156
|
+
const left = staticStringOf(asAstNode(node.left));
|
|
157
|
+
const right = staticStringOf(asAstNode(node.right));
|
|
158
|
+
if (left !== undefined && right !== undefined) return left + right;
|
|
159
|
+
}
|
|
160
|
+
return undefined;
|
|
161
|
+
}
|
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
import * as fs from "node:fs";
|
|
2
|
+
import * as path from "node:path";
|
|
3
|
+
import type { ExtensionContext } from "@earendil-works/pi-coding-agent";
|
|
4
|
+
import type { MetricRegistry } from "../observability/metric-registry.ts";
|
|
5
|
+
import type { MetricSnapshot } from "../observability/metrics-primitives.ts";
|
|
6
|
+
import { atomicWriteFile } from "../state/atomic-write.ts";
|
|
7
|
+
import { readEvents, type TeamEvent } from "../state/event-log.ts";
|
|
8
|
+
import { loadRunManifestById } from "../state/state-store.ts";
|
|
9
|
+
import type { TeamRunManifest, TeamTaskState } from "../state/types.ts";
|
|
10
|
+
import { type HeartbeatSummary, summarizeHeartbeats } from "../ui/heartbeat-aggregator.ts";
|
|
11
|
+
import type { RunUiSnapshot } from "../ui/snapshot-types.ts";
|
|
12
|
+
import { isSecretKey, redactSecrets } from "../utils/redaction.ts";
|
|
13
|
+
import { readCrewAgents } from "./crew-agent-records.ts";
|
|
14
|
+
import { buildRecoveryLedger, type RecoveryLedgerEntry } from "./recovery-recipes.ts";
|
|
15
|
+
|
|
16
|
+
export { isSecretKey, redactSecrets } from "../utils/redaction.ts";
|
|
17
|
+
|
|
18
|
+
export interface DiagnosticReport {
|
|
19
|
+
schemaVersion?: number;
|
|
20
|
+
runId: string;
|
|
21
|
+
exportedAt: string;
|
|
22
|
+
manifest: TeamRunManifest;
|
|
23
|
+
tasks: TeamTaskState[];
|
|
24
|
+
recentEvents: TeamEvent[];
|
|
25
|
+
heartbeat: HeartbeatSummary;
|
|
26
|
+
agents: unknown[];
|
|
27
|
+
envRedacted: Record<string, string>;
|
|
28
|
+
metricsSnapshot?: MetricSnapshot[];
|
|
29
|
+
// Layer 8: task diagnostics
|
|
30
|
+
taskDiagnostics: Record<string, Record<string, unknown>>;
|
|
31
|
+
// Layer 9: terminal evidence
|
|
32
|
+
terminalEvidence: Record<string, TeamTaskState["terminalEvidence"]>;
|
|
33
|
+
// Layer 10: model attempts and routing
|
|
34
|
+
modelAttempts: {
|
|
35
|
+
taskId: string;
|
|
36
|
+
attempts: TeamTaskState["modelAttempts"];
|
|
37
|
+
routing: TeamTaskState["modelRouting"];
|
|
38
|
+
}[];
|
|
39
|
+
// Layer 11: pending mailbox
|
|
40
|
+
pendingMailbox: {
|
|
41
|
+
taskId: string;
|
|
42
|
+
pendingSteers: TeamTaskState["pendingSteers"];
|
|
43
|
+
}[];
|
|
44
|
+
runMailboxUnread: RunUiSnapshot["mailbox"];
|
|
45
|
+
// Layer 12: recovery ledger
|
|
46
|
+
recoveryLedger: RecoveryLedgerEntry[];
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
const ENV_DEBUG_ALLOWLIST =
|
|
50
|
+
/^(PI_CREW_|PI_TEAMS_|PI_.*HOME|NODE_ENV|NODE_VERSION|OS|PROCESSOR|TERM|LANG|HOME|USERPROFILE|APPDATA|PLATFORM|ARCH|WIN32|DOCKER|CI|VERBOSE|DEBUG|NO_COLOR|FORCE_COLOR|NPM_CONFIG|npm_)/i;
|
|
51
|
+
|
|
52
|
+
function envRedacted(): Record<string, string> {
|
|
53
|
+
const output: Record<string, string> = {};
|
|
54
|
+
for (const [key, value] of Object.entries(process.env)) {
|
|
55
|
+
if (isSecretKey(key)) output[key] = "***";
|
|
56
|
+
else if (typeof value === "string" && ENV_DEBUG_ALLOWLIST.test(key)) output[key] = value;
|
|
57
|
+
// All other env vars are omitted to prevent leaking sensitive paths or system topology.
|
|
58
|
+
}
|
|
59
|
+
return output;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
function buildSnapshot(manifest: TeamRunManifest, tasks: TeamTaskState[]): RunUiSnapshot {
|
|
63
|
+
const agents = readCrewAgents(manifest);
|
|
64
|
+
return {
|
|
65
|
+
runId: manifest.runId,
|
|
66
|
+
cwd: manifest.cwd,
|
|
67
|
+
fetchedAt: Date.now(),
|
|
68
|
+
signature: `${manifest.runId}:${manifest.updatedAt}`,
|
|
69
|
+
manifest,
|
|
70
|
+
tasks,
|
|
71
|
+
agents,
|
|
72
|
+
progress: {
|
|
73
|
+
total: tasks.length,
|
|
74
|
+
completed: tasks.filter((task) => task.status === "completed").length,
|
|
75
|
+
running: tasks.filter((task) => task.status === "running").length,
|
|
76
|
+
failed: tasks.filter((task) => task.status === "failed").length,
|
|
77
|
+
queued: tasks.filter((task) => task.status === "queued").length,
|
|
78
|
+
},
|
|
79
|
+
usage: { tokensIn: 0, tokensOut: 0, toolUses: 0 },
|
|
80
|
+
mailbox: { inboxUnread: 0, outboxPending: 0, needsAttention: 0 },
|
|
81
|
+
recentEvents: [],
|
|
82
|
+
recentOutputLines: [],
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
export async function exportDiagnostic(
|
|
87
|
+
ctx: Pick<ExtensionContext, "cwd">,
|
|
88
|
+
runId: string,
|
|
89
|
+
options: { registry?: MetricRegistry } = {},
|
|
90
|
+
): Promise<{ path: string; report: DiagnosticReport }> {
|
|
91
|
+
const loaded = loadRunManifestById(ctx.cwd, runId); // NOTE: no withRunLock - best-effort only; concurrent writes may cause inconsistency;
|
|
92
|
+
if (!loaded) throw new Error(`Run '${runId}' not found.`);
|
|
93
|
+
const exportedAt = new Date().toISOString();
|
|
94
|
+
const safeTimestamp = exportedAt.replace(/[:.]/g, "-");
|
|
95
|
+
const recentEvents = readEvents(loaded.manifest.eventsPath).slice(-200);
|
|
96
|
+
const metricsSnapshot = options.registry?.snapshot();
|
|
97
|
+
const taskDiagnostics: Record<string, Record<string, unknown>> = {};
|
|
98
|
+
const terminalEvidence: Record<string, TeamTaskState["terminalEvidence"]> = {};
|
|
99
|
+
const modelAttempts: {
|
|
100
|
+
taskId: string;
|
|
101
|
+
attempts: TeamTaskState["modelAttempts"];
|
|
102
|
+
routing: TeamTaskState["modelRouting"];
|
|
103
|
+
}[] = [];
|
|
104
|
+
const pendingMailbox: {
|
|
105
|
+
taskId: string;
|
|
106
|
+
pendingSteers: TeamTaskState["pendingSteers"];
|
|
107
|
+
}[] = [];
|
|
108
|
+
for (const task of loaded.tasks) {
|
|
109
|
+
if (task.diagnostics) taskDiagnostics[task.id] = task.diagnostics;
|
|
110
|
+
if (task.terminalEvidence) terminalEvidence[task.id] = task.terminalEvidence;
|
|
111
|
+
if (task.modelAttempts || task.modelRouting) {
|
|
112
|
+
modelAttempts.push({
|
|
113
|
+
taskId: task.id,
|
|
114
|
+
attempts: task.modelAttempts,
|
|
115
|
+
routing: task.modelRouting,
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
if (task.pendingSteers) {
|
|
119
|
+
pendingMailbox.push({
|
|
120
|
+
taskId: task.id,
|
|
121
|
+
pendingSteers: task.pendingSteers,
|
|
122
|
+
});
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
const recoveryLedger = loaded.manifest.policyDecisions ? buildRecoveryLedger(loaded.manifest.policyDecisions).entries : [];
|
|
126
|
+
const snapshot = buildSnapshot(loaded.manifest, loaded.tasks);
|
|
127
|
+
const report: DiagnosticReport = {
|
|
128
|
+
...(metricsSnapshot ? { schemaVersion: 2 } : {}),
|
|
129
|
+
runId,
|
|
130
|
+
exportedAt,
|
|
131
|
+
manifest: redactSecrets(loaded.manifest) as TeamRunManifest,
|
|
132
|
+
tasks: redactSecrets(loaded.tasks) as TeamTaskState[],
|
|
133
|
+
recentEvents: redactSecrets(recentEvents) as TeamEvent[],
|
|
134
|
+
heartbeat: summarizeHeartbeats(snapshot),
|
|
135
|
+
agents: redactSecrets(readCrewAgents(loaded.manifest)) as unknown[],
|
|
136
|
+
envRedacted: envRedacted(),
|
|
137
|
+
...(metricsSnapshot
|
|
138
|
+
? {
|
|
139
|
+
metricsSnapshot: redactSecrets(metricsSnapshot) as MetricSnapshot[],
|
|
140
|
+
}
|
|
141
|
+
: {}),
|
|
142
|
+
taskDiagnostics,
|
|
143
|
+
terminalEvidence,
|
|
144
|
+
modelAttempts,
|
|
145
|
+
pendingMailbox,
|
|
146
|
+
runMailboxUnread: snapshot.mailbox,
|
|
147
|
+
recoveryLedger,
|
|
148
|
+
};
|
|
149
|
+
const dir = path.join(loaded.manifest.artifactsRoot, "diagnostic");
|
|
150
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
151
|
+
const filePath = path.join(dir, `diagnostic-${safeTimestamp}.json`);
|
|
152
|
+
atomicWriteFile(filePath, `${JSON.stringify(report, null, 2)}\n`);
|
|
153
|
+
return { path: filePath, report };
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
export function listRecentDiagnostic(dir: string, windowMs: number, now = Date.now()): string | undefined {
|
|
157
|
+
try {
|
|
158
|
+
if (!fs.existsSync(dir)) return undefined;
|
|
159
|
+
return fs
|
|
160
|
+
.readdirSync(dir)
|
|
161
|
+
.filter((file) => file.startsWith("diagnostic-") && file.endsWith(".json"))
|
|
162
|
+
.map((file) => ({
|
|
163
|
+
file,
|
|
164
|
+
mtimeMs: fs.statSync(path.join(dir, file)).mtimeMs,
|
|
165
|
+
}))
|
|
166
|
+
.filter((entry) => now - entry.mtimeMs < windowMs)
|
|
167
|
+
.sort((a, b) => b.mtimeMs - a.mtimeMs)[0]?.file;
|
|
168
|
+
} catch {
|
|
169
|
+
return undefined;
|
|
170
|
+
}
|
|
171
|
+
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import type { AgentConfig } from "../agents/agent-config.ts";
|
|
2
|
+
import type { TeamRunManifest, TeamTaskState } from "../state/types.ts";
|
|
3
|
+
import type { TeamConfig } from "../teams/team-config.ts";
|
|
4
|
+
import type { WorkflowConfig } from "../workflows/workflow-config.ts";
|
|
5
|
+
|
|
6
|
+
export function isDirectRun(manifest: Pick<TeamRunManifest, "team" | "workflow">): boolean {
|
|
7
|
+
return manifest.workflow === "direct-agent";
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export function directTeamAndWorkflowFromRun(
|
|
11
|
+
manifest: TeamRunManifest,
|
|
12
|
+
tasks: TeamTaskState[],
|
|
13
|
+
agents: AgentConfig[],
|
|
14
|
+
): { team: TeamConfig; workflow: WorkflowConfig } | undefined {
|
|
15
|
+
if (!isDirectRun(manifest)) return undefined;
|
|
16
|
+
const firstTask = tasks[0];
|
|
17
|
+
const agentName = firstTask?.agent ?? (manifest.team.replace(/^direct-/, "") || "executor");
|
|
18
|
+
const agent = agents.find((candidate) => candidate.name === agentName);
|
|
19
|
+
const role = firstTask?.role ?? "agent";
|
|
20
|
+
const stepId = firstTask?.stepId ?? "01_agent";
|
|
21
|
+
return {
|
|
22
|
+
team: {
|
|
23
|
+
name: manifest.team,
|
|
24
|
+
description: `Direct subagent run for ${agentName}`,
|
|
25
|
+
source: "builtin",
|
|
26
|
+
filePath: "<generated>",
|
|
27
|
+
roles: [
|
|
28
|
+
{
|
|
29
|
+
name: role,
|
|
30
|
+
agent: agentName,
|
|
31
|
+
description: agent?.description,
|
|
32
|
+
},
|
|
33
|
+
],
|
|
34
|
+
defaultWorkflow: "direct-agent",
|
|
35
|
+
workspaceMode: manifest.workspaceMode,
|
|
36
|
+
},
|
|
37
|
+
workflow: {
|
|
38
|
+
name: manifest.workflow ?? "direct-agent",
|
|
39
|
+
description: `Direct task for ${agentName}`,
|
|
40
|
+
source: "builtin",
|
|
41
|
+
filePath: "<generated>",
|
|
42
|
+
steps: [{ id: stepId, role, task: "{goal}", model: firstTask?.model }],
|
|
43
|
+
},
|
|
44
|
+
};
|
|
45
|
+
}
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* dwf-state-store.ts — Persistent checkpoint state for dynamic-workflow runs (P2-3, round-18).
|
|
3
|
+
*
|
|
4
|
+
* Modeled on GoalStore (goal-state-store.ts) and FileCheckpointStore (checkpoint.ts),
|
|
5
|
+
* but scoped to a single run's stateRoot (which is already <crewRoot>/state/runs/<runId>).
|
|
6
|
+
*
|
|
7
|
+
* Stores DwfCheckpointState as atomic JSON at <stateRoot>/dwf-checkpoint.json.
|
|
8
|
+
* atomicWriteJson (temp + rename + fsync) guarantees either the old or the new file,
|
|
9
|
+
* never a partial write — safe across crashes.
|
|
10
|
+
*
|
|
11
|
+
* Resume semantics (round-18): the runner loads a checkpoint on run start and hydrates
|
|
12
|
+
* ctx.vars/phases/logs from it; on clean completion the runner deletes it. A missing or
|
|
13
|
+
* corrupt checkpoint is treated as a fresh run (load() returns undefined). If a crash
|
|
14
|
+
* happens mid-agent, that agent simply re-runs from scratch on resume — agent results
|
|
15
|
+
* are expected to be idempotent-ish.
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
import { existsSync, mkdirSync, readFileSync, unlinkSync } from "node:fs";
|
|
19
|
+
import { dirname } from "node:path";
|
|
20
|
+
import { atomicWriteJson } from "../state/atomic-write.ts";
|
|
21
|
+
import { logInternalError } from "../utils/internal-error.ts";
|
|
22
|
+
|
|
23
|
+
export interface DwfCheckpointState {
|
|
24
|
+
runId: string;
|
|
25
|
+
vars: Record<string, unknown>;
|
|
26
|
+
phases: string[];
|
|
27
|
+
currentPhase: string | undefined;
|
|
28
|
+
logs: string[]; // capped copy (≤1000); the events log (dwf.log) is the durable source of truth
|
|
29
|
+
spent: number; // budget accumulator (round-14 P1-2)
|
|
30
|
+
agentCount: number;
|
|
31
|
+
/** PERS-1: per-agent-call idempotency cache. Maps a deterministic call ID to the
|
|
32
|
+
* cached result so a DWF resume skips already-completed agent calls (avoids
|
|
33
|
+
* duplicating artifacts/mailbox/tokens). Uses Record (not Map) for JSON
|
|
34
|
+
* serialization safety. */
|
|
35
|
+
completedAgentCalls?: Record<string, { text: string; usage?: { input: number; output: number } }>;
|
|
36
|
+
updatedAt: string;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* DwfStore — atomic CRUD for a single run's DWF checkpoint.
|
|
41
|
+
*
|
|
42
|
+
* Concurrency: writes are atomic (atomicWriteJson). The DWF runner is the sole
|
|
43
|
+
* writer during a run; `team resume` loads the checkpoint read-only before the
|
|
44
|
+
* script re-executes. No file-lock is needed here because only one runner owns a
|
|
45
|
+
* run's stateRoot at a time (run locks protect manifest transitions elsewhere).
|
|
46
|
+
*
|
|
47
|
+
* Note: the constructor takes the run's stateRoot directly (NOT cwd + runId) to
|
|
48
|
+
* avoid a double-nesting bug — stateRoot is already <crewRoot>/state/runs/<runId>,
|
|
49
|
+
* so the checkpoint lands at <crewRoot>/state/runs/<runId>/dwf-checkpoint.json.
|
|
50
|
+
* This mirrors FileCheckpointStore (checkpoint.ts: constructor(stateRoot)).
|
|
51
|
+
*/
|
|
52
|
+
export class DwfStore {
|
|
53
|
+
private readonly stateRoot: string;
|
|
54
|
+
|
|
55
|
+
constructor(stateRoot: string) {
|
|
56
|
+
this.stateRoot = stateRoot;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
private get path(): string {
|
|
60
|
+
return `${this.stateRoot}/dwf-checkpoint.json`;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/** Load the checkpoint for this run's stateRoot. Returns undefined if missing or corrupt (fresh run). */
|
|
64
|
+
load(): DwfCheckpointState | undefined {
|
|
65
|
+
const path = this.path;
|
|
66
|
+
try {
|
|
67
|
+
if (!existsSync(path)) return undefined;
|
|
68
|
+
const raw = readFileSync(path, "utf-8");
|
|
69
|
+
const parsed = JSON.parse(raw);
|
|
70
|
+
// Corrupt-guard: a valid checkpoint must be an object with a string runId
|
|
71
|
+
// (mirrors GoalStore.load's typeof parsed.goalId !== "string" check).
|
|
72
|
+
if (!parsed || typeof parsed !== "object" || typeof parsed.runId !== "string") return undefined;
|
|
73
|
+
return parsed as DwfCheckpointState;
|
|
74
|
+
} catch {
|
|
75
|
+
return undefined;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/** Atomically persist a checkpoint state. Stamps `updatedAt` (callers need not set it). */
|
|
80
|
+
save(state: DwfCheckpointState): void {
|
|
81
|
+
const path = this.path;
|
|
82
|
+
const next = { ...state, updatedAt: new Date().toISOString() };
|
|
83
|
+
try {
|
|
84
|
+
mkdirSync(dirname(path), { recursive: true });
|
|
85
|
+
atomicWriteJson(path, next);
|
|
86
|
+
} catch (error) {
|
|
87
|
+
logInternalError("dwf-state-store.save", error, `runId=${state.runId}`);
|
|
88
|
+
throw error;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/** Remove the checkpoint file (after a clean completion). Best-effort; never throws. */
|
|
93
|
+
delete(): void {
|
|
94
|
+
const path = this.path;
|
|
95
|
+
try {
|
|
96
|
+
if (!existsSync(path)) return;
|
|
97
|
+
unlinkSync(path);
|
|
98
|
+
} catch (error) {
|
|
99
|
+
logInternalError("dwf-state-store.delete", error);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
}
|