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,200 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Lightweight token counter for estimating token counts in text.
|
|
3
|
+
*
|
|
4
|
+
* Provides a more accurate estimate than the naive char/4 heuristic by
|
|
5
|
+
* distinguishing word characters from punctuation, and by detecting
|
|
6
|
+
* code-heavy content where BPE tokenizers produce more tokens per
|
|
7
|
+
* character (more operators, shorter identifiers, multi-char operators).
|
|
8
|
+
*
|
|
9
|
+
* Accuracy:
|
|
10
|
+
* - Prose: within ±10% of actual BPE token counts (unchanged formula).
|
|
11
|
+
* - Code: within ±10% of actual BPE token counts (improved from ±15%).
|
|
12
|
+
*
|
|
13
|
+
* Performance: O(n) single-pass, ~1ms for 10KB text, no external deps.
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
/** Density threshold above which content is classified as code. */
|
|
17
|
+
const CODE_DENSITY_THRESHOLD = 0.1;
|
|
18
|
+
|
|
19
|
+
/** Divisor for code content alpha estimation (~3.5 chars/token). */
|
|
20
|
+
const CODE_ALPHA_DIVISOR = 3.5;
|
|
21
|
+
|
|
22
|
+
/** Divisor for prose content alpha estimation (~4 chars/token). */
|
|
23
|
+
const PROSE_ALPHA_DIVISOR = 4;
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Check if two consecutive chars form a multi-character operator that BPE
|
|
27
|
+
* typically tokenizes as fewer tokens than the individual characters.
|
|
28
|
+
* Covers: => == != <= >= && || ?. ?? ++ -- += -= *= /=
|
|
29
|
+
*/
|
|
30
|
+
function isMultiCharOp(c1: number, c2: number): boolean {
|
|
31
|
+
switch (c1) {
|
|
32
|
+
case 0x3d:
|
|
33
|
+
return c2 === 0x3e || c2 === 0x3d; // = → => or ==
|
|
34
|
+
case 0x21:
|
|
35
|
+
return c2 === 0x3d; // ! → !=
|
|
36
|
+
case 0x3c:
|
|
37
|
+
return c2 === 0x3d; // < → <=
|
|
38
|
+
case 0x3e:
|
|
39
|
+
return c2 === 0x3d; // > → >=
|
|
40
|
+
case 0x26:
|
|
41
|
+
return c2 === 0x26; // & → &&
|
|
42
|
+
case 0x7c:
|
|
43
|
+
return c2 === 0x7c; // | → ||
|
|
44
|
+
case 0x3f:
|
|
45
|
+
return c2 === 0x2e || c2 === 0x3f; // ? → ?. or ??
|
|
46
|
+
case 0x2b:
|
|
47
|
+
return c2 === 0x2b || c2 === 0x3d; // + → ++ or +=
|
|
48
|
+
case 0x2d:
|
|
49
|
+
return c2 === 0x2d || c2 === 0x3d; // - → -- or -=
|
|
50
|
+
case 0x2a:
|
|
51
|
+
return c2 === 0x3d; // * → *=
|
|
52
|
+
case 0x2f:
|
|
53
|
+
return c2 === 0x3d; // / → /=
|
|
54
|
+
default:
|
|
55
|
+
return false;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Detect whether the text is code-heavy content based on the density of
|
|
61
|
+
* code-specific punctuation (brackets, semicolons, colons) and multi-char
|
|
62
|
+
* operators (=>, ==, &&, etc.).
|
|
63
|
+
*
|
|
64
|
+
* @param text Input text.
|
|
65
|
+
* @returns True if the content appears to be code.
|
|
66
|
+
*/
|
|
67
|
+
export function detectCodeContent(text: string): boolean {
|
|
68
|
+
if (!text || text.length === 0) return false;
|
|
69
|
+
|
|
70
|
+
let alphaChars = 0;
|
|
71
|
+
let punctChars = 0;
|
|
72
|
+
let codePunct = 0;
|
|
73
|
+
let multiCharOps = 0;
|
|
74
|
+
let skipOpCheck = false;
|
|
75
|
+
const len = text.length;
|
|
76
|
+
|
|
77
|
+
for (let i = 0; i < len; i++) {
|
|
78
|
+
const c = text.charCodeAt(i);
|
|
79
|
+
if (c === 0x20 || c === 0x09 || c === 0x0a || c === 0x0d) {
|
|
80
|
+
skipOpCheck = false;
|
|
81
|
+
continue;
|
|
82
|
+
}
|
|
83
|
+
if ((c >= 0x30 && c <= 0x39) || (c >= 0x41 && c <= 0x5a) || (c >= 0x61 && c <= 0x7a) || c === 0x5f) {
|
|
84
|
+
alphaChars++;
|
|
85
|
+
skipOpCheck = false;
|
|
86
|
+
} else {
|
|
87
|
+
punctChars++;
|
|
88
|
+
if (
|
|
89
|
+
c === 0x7b ||
|
|
90
|
+
c === 0x7d || // { }
|
|
91
|
+
c === 0x5b ||
|
|
92
|
+
c === 0x5d || // [ ]
|
|
93
|
+
c === 0x28 ||
|
|
94
|
+
c === 0x29 || // ( )
|
|
95
|
+
c === 0x3b ||
|
|
96
|
+
c === 0x3a // ; :
|
|
97
|
+
) {
|
|
98
|
+
codePunct++;
|
|
99
|
+
}
|
|
100
|
+
if (skipOpCheck) {
|
|
101
|
+
skipOpCheck = false;
|
|
102
|
+
} else if (i + 1 < len && isMultiCharOp(c, text.charCodeAt(i + 1))) {
|
|
103
|
+
multiCharOps++;
|
|
104
|
+
skipOpCheck = true;
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
const total = alphaChars + punctChars;
|
|
110
|
+
if (total === 0) return false;
|
|
111
|
+
return (codePunct + multiCharOps) / total >= CODE_DENSITY_THRESHOLD;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* Estimate token count for a string using a single-pass O(n) scan.
|
|
116
|
+
*
|
|
117
|
+
* Algorithm:
|
|
118
|
+
* 1. Walk text char-by-char with charCodeAt (fast, no allocations).
|
|
119
|
+
* 2. Count alphabetic chars, alpha runs (words), punctuation chars,
|
|
120
|
+
* code-specific punctuation, and multi-char operators — all in one pass.
|
|
121
|
+
* 3. Detect code-heavy content using indicator density.
|
|
122
|
+
* 4. For prose: ceil(alpha / 4) + punct — BPE averages ~4 chars/token
|
|
123
|
+
* for English words; each punctuation char is a separate token.
|
|
124
|
+
* 5. For code: max(ceil(alpha / 3.5), alphaRuns) + punct - multiCharOps.
|
|
125
|
+
* - max() handles both short-identifier code (alphaRuns dominates)
|
|
126
|
+
* and long-identifier code (alpha/3.5 dominates).
|
|
127
|
+
* - Subtracting multiCharOps corrects for operators like => or ==
|
|
128
|
+
* that BPE tokenizes as 1 token, not 2 chars.
|
|
129
|
+
*
|
|
130
|
+
* @param text Input text to estimate tokens for.
|
|
131
|
+
* @returns Estimated token count.
|
|
132
|
+
*/
|
|
133
|
+
export function countTokens(text: string): number {
|
|
134
|
+
if (!text || text.length === 0) return 0;
|
|
135
|
+
|
|
136
|
+
let alphaChars = 0;
|
|
137
|
+
let alphaRuns = 0;
|
|
138
|
+
let punctChars = 0;
|
|
139
|
+
let codePunct = 0;
|
|
140
|
+
let multiCharOps = 0;
|
|
141
|
+
let inAlphaRun = false;
|
|
142
|
+
let skipOpCheck = false;
|
|
143
|
+
const len = text.length;
|
|
144
|
+
|
|
145
|
+
for (let i = 0; i < len; i++) {
|
|
146
|
+
const c = text.charCodeAt(i);
|
|
147
|
+
|
|
148
|
+
// Inline whitespace check (hot path)
|
|
149
|
+
if (c === 0x20 || c === 0x09 || c === 0x0a || c === 0x0d) {
|
|
150
|
+
inAlphaRun = false;
|
|
151
|
+
skipOpCheck = false;
|
|
152
|
+
continue;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
// Inline alphanumeric check (hot path)
|
|
156
|
+
if ((c >= 0x30 && c <= 0x39) || (c >= 0x41 && c <= 0x5a) || (c >= 0x61 && c <= 0x7a) || c === 0x5f) {
|
|
157
|
+
alphaChars++;
|
|
158
|
+
if (!inAlphaRun) {
|
|
159
|
+
alphaRuns++;
|
|
160
|
+
inAlphaRun = true;
|
|
161
|
+
}
|
|
162
|
+
skipOpCheck = false;
|
|
163
|
+
continue;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
// Punctuation path
|
|
167
|
+
inAlphaRun = false;
|
|
168
|
+
punctChars++;
|
|
169
|
+
|
|
170
|
+
// Code-specific punctuation: { } [ ] ( ) ; :
|
|
171
|
+
if (c === 0x7b || c === 0x7d || c === 0x5b || c === 0x5d || c === 0x28 || c === 0x29 || c === 0x3b || c === 0x3a) {
|
|
172
|
+
codePunct++;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
// Multi-char operator detection. When a pair is found at position i,
|
|
176
|
+
// skip the check at i+1 to avoid double-counting (e.g. === → 1 op).
|
|
177
|
+
if (skipOpCheck) {
|
|
178
|
+
skipOpCheck = false;
|
|
179
|
+
} else if (i + 1 < len && isMultiCharOp(c, text.charCodeAt(i + 1))) {
|
|
180
|
+
multiCharOps++;
|
|
181
|
+
skipOpCheck = true;
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
const total = alphaChars + punctChars;
|
|
186
|
+
if (total === 0) return 0;
|
|
187
|
+
|
|
188
|
+
const codeIndicators = codePunct + multiCharOps;
|
|
189
|
+
if (codeIndicators / total >= CODE_DENSITY_THRESHOLD) {
|
|
190
|
+
// Code content: shorter identifiers and more operators mean more
|
|
191
|
+
// tokens per character than prose. Use the larger of word-count
|
|
192
|
+
// and char/3.5 to handle both short and long identifiers.
|
|
193
|
+
const alphaTokens = Math.max(Math.ceil(alphaChars / CODE_ALPHA_DIVISOR), alphaRuns);
|
|
194
|
+
return alphaTokens + punctChars - multiCharOps;
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
// Prose content: standard ~4 chars/token for alphanumeric words,
|
|
198
|
+
// 1 token per punctuation char (unchanged from original formula).
|
|
199
|
+
return Math.ceil(alphaChars / PROSE_ALPHA_DIVISOR) + punctChars;
|
|
200
|
+
}
|
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
import { visibleWidth as tuiVisibleWidth } from "@earendil-works/pi-tui";
|
|
2
|
+
|
|
3
|
+
export const ANSI_PATTERN = /\u001b\[[0-?]*[ -/]*[@-~]/g;
|
|
4
|
+
|
|
5
|
+
const WIDTH_CACHE_LIMIT = 256;
|
|
6
|
+
const widthCache = new Map<string, number>();
|
|
7
|
+
|
|
8
|
+
// NOTE: width measurement is delegated to pi-tui's `visibleWidth` (see below).
|
|
9
|
+
// pi-tui is the renderer that HARD-ABORTS the session if any line exceeds the
|
|
10
|
+
// terminal width by ITS measure, so our truncate/pad/wrap MUST agree with it.
|
|
11
|
+
// A previous hand-maintained WIDE_RANGES table diverged from pi-tui's
|
|
12
|
+
// grapheme+RGI-emoji model on codepoints like ⏳ U+23F3 (hourglass: we counted
|
|
13
|
+
// 1, pi-tui counts 2) → lines we believed fit were rejected →
|
|
14
|
+
// "Rendered line N exceeds terminal width (160 > 159)" crash. Delegating makes
|
|
15
|
+
// divergence structurally impossible.
|
|
16
|
+
|
|
17
|
+
export function visibleWidth(value: string): number {
|
|
18
|
+
// Delegate to pi-tui's authoritative width model so our truncate/pad/wrap
|
|
19
|
+
// can never disagree with the renderer's doRender measurement. Keep our own
|
|
20
|
+
// LRU cache on top (pi-tui caches too, but this avoids repeated calls for the
|
|
21
|
+
// hot render path).
|
|
22
|
+
if (value.length > 4096) return tuiVisibleWidth(value);
|
|
23
|
+
const cached = widthCache.get(value);
|
|
24
|
+
if (cached !== undefined) return cached;
|
|
25
|
+
const length = tuiVisibleWidth(value);
|
|
26
|
+
if (widthCache.size >= WIDTH_CACHE_LIMIT) {
|
|
27
|
+
const firstKey = widthCache.keys().next().value;
|
|
28
|
+
if (firstKey !== undefined) widthCache.delete(firstKey);
|
|
29
|
+
}
|
|
30
|
+
widthCache.set(value, length);
|
|
31
|
+
return length;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export function __test__clearVisibleWidthCache(): void {
|
|
35
|
+
widthCache.clear();
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export function __test__visibleWidthCacheSize(): number {
|
|
39
|
+
return widthCache.size;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
function consumeAnsi(input: string, index: number): number {
|
|
43
|
+
const char = input[index];
|
|
44
|
+
if (!char || char !== "\u001b") return 0;
|
|
45
|
+
if (input[index + 1] !== "[") return 0;
|
|
46
|
+
let i = index + 2;
|
|
47
|
+
while (i < input.length) {
|
|
48
|
+
const code = input.charCodeAt(i);
|
|
49
|
+
if (code >= 0x40 && code <= 0x7e) return i - index + 1;
|
|
50
|
+
i++;
|
|
51
|
+
}
|
|
52
|
+
return 0;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
function splitGraphemes(value: string): string[] {
|
|
56
|
+
return Array.from(value.replace(ANSI_PATTERN, ""));
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
export function truncateToWidth(value: string, width: number, ellipsis = "…"): string {
|
|
60
|
+
if (width <= 0) return "";
|
|
61
|
+
if (visibleWidth(value) <= width) return value;
|
|
62
|
+
if (width <= ellipsis.length) return ellipsis.slice(0, width);
|
|
63
|
+
let output = "";
|
|
64
|
+
let renderedWidth = 0;
|
|
65
|
+
for (let i = 0; i < value.length; ) {
|
|
66
|
+
const ansiLen = consumeAnsi(value, i);
|
|
67
|
+
if (ansiLen) {
|
|
68
|
+
output += value.slice(i, i + ansiLen);
|
|
69
|
+
i += ansiLen;
|
|
70
|
+
continue;
|
|
71
|
+
}
|
|
72
|
+
// Read the codepoint at position i on the FULL string — NOT
|
|
73
|
+
// `value[i].codePointAt(0)`, which for a surrogate pair returns the
|
|
74
|
+
// lone half (≤ 0xFFFF) and slices each half separately. pi-tui's
|
|
75
|
+
// visibleWidth zero-widths lone `\p{Surrogate}` halves, so 🤖 would
|
|
76
|
+
// undercount as 0 and truncation would never cut (latent bug unmasked
|
|
77
|
+
// once visibleWidth delegated to pi-tui).
|
|
78
|
+
const codepoint = value.codePointAt(i) ?? 0;
|
|
79
|
+
const nextIndex = codepoint > 0xffff ? i + 2 : i + 1;
|
|
80
|
+
const segment = value.slice(i, nextIndex);
|
|
81
|
+
const charWidth = visibleWidth(segment);
|
|
82
|
+
if (renderedWidth + charWidth > width - ellipsis.length) {
|
|
83
|
+
return `${output}${ellipsis}`;
|
|
84
|
+
}
|
|
85
|
+
output += segment;
|
|
86
|
+
renderedWidth += charWidth;
|
|
87
|
+
i = nextIndex;
|
|
88
|
+
}
|
|
89
|
+
return output;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
export const truncate = truncateToWidth;
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* Strip newlines and other terminal-confusing control characters from a
|
|
96
|
+
* single-line label. Without this, embedded `\n`/`\r` in user-provided
|
|
97
|
+
* text (run.goal, run.team, mailbox preview, agent activity, ...) breaks
|
|
98
|
+
* box-drawing rows because the terminal advances to the next line in the
|
|
99
|
+
* middle of a row, leaving the overlay's `│` border misaligned and the
|
|
100
|
+
* dashboard appearing to "duplicate" itself below the original render.
|
|
101
|
+
*
|
|
102
|
+
* Preserves ANSI color/style escape sequences (\u001b[...m) which the
|
|
103
|
+
* caller has already wrapped around the text via the theme adapter.
|
|
104
|
+
*/
|
|
105
|
+
export function sanitizeLine(value: string): string {
|
|
106
|
+
if (!value) return "";
|
|
107
|
+
let result = "";
|
|
108
|
+
let i = 0;
|
|
109
|
+
while (i < value.length) {
|
|
110
|
+
const ansi = readAnsiCode(value, i);
|
|
111
|
+
if (ansi) {
|
|
112
|
+
result += ansi;
|
|
113
|
+
i += ansi.length;
|
|
114
|
+
continue;
|
|
115
|
+
}
|
|
116
|
+
const code = value.charCodeAt(i);
|
|
117
|
+
// Replace any C0/C1 control char (incl. \n \r \t \v \f and 0x7F-0x9F)
|
|
118
|
+
// with a single space; everything else is passed through verbatim.
|
|
119
|
+
if (code < 0x20 || (code >= 0x7f && code <= 0x9f)) {
|
|
120
|
+
result += " ";
|
|
121
|
+
i += 1;
|
|
122
|
+
continue;
|
|
123
|
+
}
|
|
124
|
+
result += value[i];
|
|
125
|
+
i += 1;
|
|
126
|
+
}
|
|
127
|
+
return result;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
export function pad(value: string, width: number): string {
|
|
131
|
+
const current = visibleWidth(value);
|
|
132
|
+
if (current >= width) return value;
|
|
133
|
+
return `${value}${" ".repeat(width - current)}`;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
export function boxLine(text: string, innerWidth: number): string {
|
|
137
|
+
return `│ ${truncate(text, innerWidth - 4)} │`;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
function readAnsiCode(input: string, index: number): string | undefined {
|
|
141
|
+
const ansiLength = consumeAnsi(input, index);
|
|
142
|
+
if (ansiLength > 0) return input.slice(index, index + ansiLength);
|
|
143
|
+
return undefined;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
function takeCodePoint(input: string, index: number): { chunk: string; nextIndex: number } {
|
|
147
|
+
const code = input.codePointAt(index);
|
|
148
|
+
if (code === undefined) return { chunk: "", nextIndex: index + 1 };
|
|
149
|
+
if (code >= 0xd800 && code <= 0xdbff && index + 1 < input.length) {
|
|
150
|
+
return { chunk: input.slice(index, index + 2), nextIndex: index + 2 };
|
|
151
|
+
}
|
|
152
|
+
return { chunk: input[index] ?? "", nextIndex: index + 1 };
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
export function wrapHard(value: string, width: number): string[] {
|
|
156
|
+
if (width <= 0 || !value) return [];
|
|
157
|
+
const lines: string[] = [];
|
|
158
|
+
let current = "";
|
|
159
|
+
let currentWidth = 0;
|
|
160
|
+
let i = 0;
|
|
161
|
+
while (i < value.length) {
|
|
162
|
+
const ansi = readAnsiCode(value, i);
|
|
163
|
+
if (ansi) {
|
|
164
|
+
current += ansi;
|
|
165
|
+
i += ansi.length;
|
|
166
|
+
continue;
|
|
167
|
+
}
|
|
168
|
+
const { chunk, nextIndex } = takeCodePoint(value, i);
|
|
169
|
+
const chunkWidth = visibleWidth(chunk);
|
|
170
|
+
if (chunkWidth > width) {
|
|
171
|
+
lines.push(current ? current + chunk : chunk);
|
|
172
|
+
current = "";
|
|
173
|
+
currentWidth = 0;
|
|
174
|
+
i = nextIndex;
|
|
175
|
+
continue;
|
|
176
|
+
}
|
|
177
|
+
if (currentWidth + chunkWidth > width) {
|
|
178
|
+
if (current) lines.push(current);
|
|
179
|
+
current = chunk;
|
|
180
|
+
currentWidth = chunkWidth;
|
|
181
|
+
i = nextIndex;
|
|
182
|
+
continue;
|
|
183
|
+
}
|
|
184
|
+
current += chunk;
|
|
185
|
+
currentWidth += chunkWidth;
|
|
186
|
+
i = nextIndex;
|
|
187
|
+
}
|
|
188
|
+
if (current) lines.push(current);
|
|
189
|
+
return lines.length > 0 ? lines : [""];
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
export interface VisualTruncateResult {
|
|
193
|
+
visualLines: string[];
|
|
194
|
+
skippedCount: number;
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
export function truncateToVisualLines(text: string, maxVisualLines: number, width: number, paddingX = 0): VisualTruncateResult {
|
|
198
|
+
if (!text) {
|
|
199
|
+
return { visualLines: [], skippedCount: 0 };
|
|
200
|
+
}
|
|
201
|
+
const effectiveWidth = Math.max(1, width - paddingX * 2);
|
|
202
|
+
const limit = Math.max(1, maxVisualLines);
|
|
203
|
+
const visualLines = text.split("\n").flatMap((line) => wrapHard(pad(line, Math.max(0, effectiveWidth)).trimEnd(), effectiveWidth));
|
|
204
|
+
if (visualLines.length <= limit) return { visualLines, skippedCount: 0 };
|
|
205
|
+
const truncated = visualLines.slice(-limit);
|
|
206
|
+
return { visualLines: truncated, skippedCount: visualLines.length - limit };
|
|
207
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import type { WorkflowConfig } from "./workflow-config.ts";
|
|
2
|
+
|
|
3
|
+
// Rough token estimates per role (input + output combined)
|
|
4
|
+
const ROLE_TOKEN_ESTIMATES: Record<string, number> = {
|
|
5
|
+
explorer: 15000,
|
|
6
|
+
planner: 20000,
|
|
7
|
+
executor: 25000,
|
|
8
|
+
reviewer: 12000,
|
|
9
|
+
"security-reviewer": 12000,
|
|
10
|
+
"test-engineer": 15000,
|
|
11
|
+
analyst: 18000,
|
|
12
|
+
writer: 15000,
|
|
13
|
+
verifier: 10000,
|
|
14
|
+
critic: 12000,
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
// Rough cost per 1K tokens (USD) — using a mid-range model price
|
|
18
|
+
const COST_PER_1K_TOKENS = 0.003;
|
|
19
|
+
|
|
20
|
+
export interface CostEstimate {
|
|
21
|
+
totalTokens: number;
|
|
22
|
+
estimatedCostUSD: number;
|
|
23
|
+
perStep: Array<{ stepId: string; role: string; tokens: number }>;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export function estimateWorkflowCost(workflow: WorkflowConfig): CostEstimate {
|
|
27
|
+
const perStep = workflow.steps.map((step) => {
|
|
28
|
+
const tokens = ROLE_TOKEN_ESTIMATES[step.role] ?? 15000; // default 15K
|
|
29
|
+
return { stepId: step.id, role: step.role, tokens };
|
|
30
|
+
});
|
|
31
|
+
const totalTokens = perStep.reduce((sum, s) => sum + s.tokens, 0);
|
|
32
|
+
const estimatedCostUSD = (totalTokens / 1000) * COST_PER_1K_TOKENS;
|
|
33
|
+
return { totalTokens, estimatedCostUSD, perStep };
|
|
34
|
+
}
|