pi-crew 0.9.54 → 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 +24 -0
- package/package.json +5 -2
- 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,54 @@
|
|
|
1
|
+
import { execFileSync } from "node:child_process";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Synchronous sleep using Atomics.wait (non-busy) with low-CPU fallback.
|
|
5
|
+
*
|
|
6
|
+
* WARNING: This blocks the Node.js main thread. Only use in sync I/O paths
|
|
7
|
+
* where blocking is acceptable (lock acquisition, rename retry).
|
|
8
|
+
* NOT safe to call from Pi extension async code paths.
|
|
9
|
+
*/
|
|
10
|
+
export function sleepSync(ms: number): void {
|
|
11
|
+
try {
|
|
12
|
+
const buffer = new SharedArrayBuffer(4);
|
|
13
|
+
Atomics.wait(new Int32Array(buffer), 0, 0, ms);
|
|
14
|
+
} catch {
|
|
15
|
+
// Fallback for environments without Atomics.wait (e.g. Windows).
|
|
16
|
+
// On Unix, try spawning the `sleep` command to avoid CPU busy-wait.
|
|
17
|
+
if (process.platform !== "win32" && ms >= 10) {
|
|
18
|
+
try {
|
|
19
|
+
execFileSync("sleep", [(ms / 1000).toFixed(3)], {
|
|
20
|
+
timeout: ms + 1000,
|
|
21
|
+
stdio: "pipe",
|
|
22
|
+
});
|
|
23
|
+
return;
|
|
24
|
+
} catch {
|
|
25
|
+
// sleep command unavailable — fall through to busy-wait
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
// Last resort: busy-wait. This burns CPU but is the only guaranteed
|
|
29
|
+
// synchronous delay on Windows without SharedArrayBuffer.
|
|
30
|
+
const deadline = Date.now() + ms;
|
|
31
|
+
while (Date.now() < deadline) {
|
|
32
|
+
// Busy-wait fallback for environments without Atomics.wait.
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Async sleep with optional AbortSignal support.
|
|
39
|
+
* Rejects immediately if the signal is already aborted, or when aborted during wait.
|
|
40
|
+
*/
|
|
41
|
+
export function sleep(ms: number, signal?: AbortSignal): Promise<void> {
|
|
42
|
+
if (signal?.aborted) return Promise.reject(new Error("aborted"));
|
|
43
|
+
return new Promise<void>((resolve, reject) => {
|
|
44
|
+
const timer = setTimeout(resolve, ms);
|
|
45
|
+
signal?.addEventListener(
|
|
46
|
+
"abort",
|
|
47
|
+
() => {
|
|
48
|
+
clearTimeout(timer);
|
|
49
|
+
reject(new Error("aborted"));
|
|
50
|
+
},
|
|
51
|
+
{ once: true },
|
|
52
|
+
);
|
|
53
|
+
});
|
|
54
|
+
}
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* socket-path.ts — Canonical broker Unix-socket / named-pipe path utilities.
|
|
3
|
+
*
|
|
4
|
+
* Moved out of the parallel-work stub `src/runtime/crew-broker-deps.ts`.
|
|
5
|
+
* The public surface (hashSessionId, getBrokerSocketPath,
|
|
6
|
+
* prepareBrokerSocketDir, removeStaleBrokerSocket) is preserved verbatim
|
|
7
|
+
* so importers can be updated with a single import-path change.
|
|
8
|
+
*
|
|
9
|
+
* No internal dependencies on other src/ modules — only Node built-ins.
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
import { createHash } from "node:crypto";
|
|
13
|
+
import * as fsp from "node:fs/promises";
|
|
14
|
+
import * as net from "node:net";
|
|
15
|
+
import * as os from "node:os";
|
|
16
|
+
import * as path from "node:path";
|
|
17
|
+
|
|
18
|
+
/** Default hash length for the short socket filename (8 hex chars). */
|
|
19
|
+
const DEFAULT_PATH_HASH_LEN = 8;
|
|
20
|
+
|
|
21
|
+
/** POSIX sun_path cap (108 bytes including the null terminator). Use 107 for the
|
|
22
|
+
* string portion of the path. */
|
|
23
|
+
const POSIX_SUN_PATH_BUDGET = 107;
|
|
24
|
+
|
|
25
|
+
/** SHA-256 hex prefix of `sessionId`. `length` defaults to 8; must be in [4, 32]. */
|
|
26
|
+
export function hashSessionId(sessionId: string, length: number = DEFAULT_PATH_HASH_LEN): string {
|
|
27
|
+
if (typeof sessionId !== "string" || sessionId.length === 0) {
|
|
28
|
+
throw new Error("hashSessionId: sessionId must be a non-empty string");
|
|
29
|
+
}
|
|
30
|
+
if (!Number.isInteger(length) || length < 4 || length > 32) {
|
|
31
|
+
throw new Error(`hashSessionId: length must be an integer in [4, 32] (got ${length})`);
|
|
32
|
+
}
|
|
33
|
+
const hex = createHash("sha256").update(sessionId, "utf8").digest("hex");
|
|
34
|
+
return hex.substring(0, length);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/** Resolve the current POSIX user id. Uses `process.getuid` (POSIX-only);
|
|
38
|
+
* falls back to `os.userInfo().uid`, then 0. Never throws. */
|
|
39
|
+
function getCurrentUid(): number {
|
|
40
|
+
try {
|
|
41
|
+
const uid = process.getuid?.();
|
|
42
|
+
if (typeof uid === "number") return uid;
|
|
43
|
+
} catch {
|
|
44
|
+
/* ignore */
|
|
45
|
+
}
|
|
46
|
+
try {
|
|
47
|
+
const info = os.userInfo();
|
|
48
|
+
if (typeof info.uid === "number") return info.uid;
|
|
49
|
+
} catch {
|
|
50
|
+
/* ignore */
|
|
51
|
+
}
|
|
52
|
+
return 0;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/** Resolve a per-user subdirectory under the runtime base for broker sockets.
|
|
56
|
+
*
|
|
57
|
+
* `${base}/pi-crew-<uid>/` isolates each user's sockets so that
|
|
58
|
+
* `prepareBrokerSocketDir` can chmod 0700 a user-owned dir instead of the
|
|
59
|
+
* shared base (`/tmp` or `XDG_RUNTIME_DIR`). Chmod-ing the shared base under
|
|
60
|
+
* root strips the sticky bit and breaks the system. On Windows, named pipes
|
|
61
|
+
* have no enclosing dir, so an empty string is returned. */
|
|
62
|
+
export function getPerUserSocketDir(platform: NodeJS.Platform = process.platform): string {
|
|
63
|
+
if (platform === "win32") return "";
|
|
64
|
+
const base = process.env.XDG_RUNTIME_DIR || os.tmpdir();
|
|
65
|
+
const uid = getCurrentUid();
|
|
66
|
+
return path.join(base, `pi-crew-${uid}`);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/** Resolve the broker endpoint for the given session.
|
|
70
|
+
*
|
|
71
|
+
* - POSIX: `${XDG_RUNTIME_DIR || os.tmpdir()}/pi-crew-<uid>/pi-crew-<hash8>.sock`
|
|
72
|
+
* (per-user dir 0700 enforced by `prepareBrokerSocketDir`; socket 0600 by
|
|
73
|
+
* the server).
|
|
74
|
+
* - Windows: `\\\\.\\pipe\\pi-crew-broker-<hash8>`.
|
|
75
|
+
* - Throws if the encoded POSIX path exceeds sun_path (108 bytes) — the
|
|
76
|
+
* caller cannot fix this without changing the hash length, so fail fast. */
|
|
77
|
+
export function getBrokerSocketPath(sessionId: string, platform: NodeJS.Platform = process.platform): string {
|
|
78
|
+
const hash = hashSessionId(sessionId);
|
|
79
|
+
if (platform === "win32") {
|
|
80
|
+
return `\\\\.\\pipe\\pi-crew-broker-${hash}`;
|
|
81
|
+
}
|
|
82
|
+
const perUserDir = getPerUserSocketDir(platform);
|
|
83
|
+
const sock = path.join(perUserDir, `pi-crew-${hash}.sock`);
|
|
84
|
+
const encoded = Buffer.byteLength(sock, "utf8");
|
|
85
|
+
if (encoded > POSIX_SUN_PATH_BUDGET) {
|
|
86
|
+
throw new Error(
|
|
87
|
+
`broker socket path ${encoded} bytes exceeds sun_path budget (${POSIX_SUN_PATH_BUDGET}); check XDG_RUNTIME_DIR or use a shorter hash`,
|
|
88
|
+
);
|
|
89
|
+
}
|
|
90
|
+
return sock;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/** Create the parent directory of a broker socket with mode 0700 (POSIX).
|
|
94
|
+
* Idempotent: if the directory already exists with the correct mode, leaves
|
|
95
|
+
* it alone. Refuses to operate on a symlink. Windows is a no-op (named pipes
|
|
96
|
+
* do not have an enclosing dir).
|
|
97
|
+
*
|
|
98
|
+
* The parent is a per-user subdir (see `getPerUserSocketDir`), NOT the shared
|
|
99
|
+
* runtime base, so chmod 0700 targets a user-owned dir rather than stripping
|
|
100
|
+
* the sticky bit from `/tmp`. */
|
|
101
|
+
export async function prepareBrokerSocketDir(sockPath: string): Promise<void> {
|
|
102
|
+
if (process.platform === "win32") return;
|
|
103
|
+
const dir = path.dirname(sockPath);
|
|
104
|
+
// mkdir with mode 0o700; recursive:true so nested paths work.
|
|
105
|
+
await fsp.mkdir(dir, { recursive: true, mode: 0o700 });
|
|
106
|
+
// Tighten mode if it already existed (mkdir with mode ignores on existing).
|
|
107
|
+
try {
|
|
108
|
+
await fsp.chmod(dir, 0o700);
|
|
109
|
+
} catch {
|
|
110
|
+
// ENOENT or EPERM on non-POSIX — best-effort.
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
/** Connect-then-unlink stale socket (herdr pattern). If a live broker is
|
|
115
|
+
* listening, leave the endpoint intact (EADDRINUSE will surface on bind).
|
|
116
|
+
* If a stale file exists with no listener, remove it. If the path is a
|
|
117
|
+
* symlink, refuse rather than follow.
|
|
118
|
+
*
|
|
119
|
+
* Returns "removed" when the stale entry was unlinked, "kept" when a live
|
|
120
|
+
* listener was detected, "absent" when no entry existed, "refused"
|
|
121
|
+
* when the entry is a symlink. */
|
|
122
|
+
export async function removeStaleBrokerSocket(
|
|
123
|
+
sockPath: string,
|
|
124
|
+
probeTimeoutMs: number = 250,
|
|
125
|
+
): Promise<"removed" | "kept" | "absent" | "refused"> {
|
|
126
|
+
// Reject symlinks outright.
|
|
127
|
+
let st: Awaited<ReturnType<typeof fsp.lstat>>;
|
|
128
|
+
try {
|
|
129
|
+
st = await fsp.lstat(sockPath);
|
|
130
|
+
} catch (e) {
|
|
131
|
+
const code = (e as NodeJS.ErrnoException).code;
|
|
132
|
+
if (code === "ENOENT") return "absent";
|
|
133
|
+
throw e;
|
|
134
|
+
}
|
|
135
|
+
if (st.isSymbolicLink()) return "refused";
|
|
136
|
+
// Bound the probe: connect with a short timeout. If anything answers, treat as live.
|
|
137
|
+
const live = await new Promise<boolean>((resolve) => {
|
|
138
|
+
let settled = false;
|
|
139
|
+
const sock = net.createConnection(sockPath);
|
|
140
|
+
const finish = (v: boolean) => {
|
|
141
|
+
if (settled) return;
|
|
142
|
+
settled = true;
|
|
143
|
+
try {
|
|
144
|
+
sock.destroy();
|
|
145
|
+
} catch {
|
|
146
|
+
/* ignore */
|
|
147
|
+
}
|
|
148
|
+
resolve(v);
|
|
149
|
+
};
|
|
150
|
+
sock.once("connect", () => finish(true));
|
|
151
|
+
sock.once("error", () => finish(false));
|
|
152
|
+
setTimeout(() => finish(false), probeTimeoutMs);
|
|
153
|
+
});
|
|
154
|
+
if (live) return "kept";
|
|
155
|
+
// Stale: remove.
|
|
156
|
+
try {
|
|
157
|
+
await fsp.unlink(sockPath);
|
|
158
|
+
return "removed";
|
|
159
|
+
} catch (e) {
|
|
160
|
+
const code = (e as NodeJS.ErrnoException).code;
|
|
161
|
+
if (code === "ENOENT") return "absent";
|
|
162
|
+
throw e;
|
|
163
|
+
}
|
|
164
|
+
}
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
/** A single Server-Sent Event */
|
|
2
|
+
export interface ServerSentEvent {
|
|
3
|
+
event: string | null;
|
|
4
|
+
data: string;
|
|
5
|
+
raw: string[];
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
/** L1: Maximum number of raw lines before discarding an oversized event. */
|
|
9
|
+
const MAX_EVENT_LINES = 1000;
|
|
10
|
+
|
|
11
|
+
/** L2: Maximum data size per line to prevent unbounded memory usage. */
|
|
12
|
+
const MAX_DATA_SIZE = 100000; // 100KB per line
|
|
13
|
+
|
|
14
|
+
/** Read newline-delimited lines from a text ReadableStream, buffering partial chunks. */
|
|
15
|
+
async function* readLines(stream: ReadableStream<string>, signal?: AbortSignal): AsyncGenerator<string> {
|
|
16
|
+
const reader = stream.getReader();
|
|
17
|
+
let buffer = "";
|
|
18
|
+
try {
|
|
19
|
+
while (true) {
|
|
20
|
+
if (signal?.aborted) return;
|
|
21
|
+
const { done, value } = await reader.read();
|
|
22
|
+
if (done) {
|
|
23
|
+
if (buffer.length > 0) yield buffer;
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
buffer += value;
|
|
27
|
+
let idx: number;
|
|
28
|
+
while ((idx = buffer.indexOf("\n")) !== -1) {
|
|
29
|
+
const line = buffer.endsWith("\r\n", idx + 1) ? buffer.slice(0, idx - 1) : buffer.slice(0, idx);
|
|
30
|
+
yield line;
|
|
31
|
+
buffer = buffer.slice(idx + 1);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
} finally {
|
|
35
|
+
reader.releaseLock();
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/** Parse SSE events from a byte stream */
|
|
40
|
+
export async function* readSseEvents(stream: ReadableStream<Uint8Array>, signal?: AbortSignal): AsyncGenerator<ServerSentEvent> {
|
|
41
|
+
const textStream = stream.pipeThrough(new TextDecoderStream() as unknown as TransformStream<Uint8Array, string>);
|
|
42
|
+
let currentEvent: string | null = null;
|
|
43
|
+
let currentData: string[] = [];
|
|
44
|
+
let currentRaw: string[] = [];
|
|
45
|
+
|
|
46
|
+
function flush(): ServerSentEvent | null {
|
|
47
|
+
if (currentData.length === 0 && currentEvent === null) return null;
|
|
48
|
+
const evt: ServerSentEvent = {
|
|
49
|
+
event: currentEvent,
|
|
50
|
+
data: currentData.join("\n"),
|
|
51
|
+
raw: currentRaw,
|
|
52
|
+
};
|
|
53
|
+
currentEvent = null;
|
|
54
|
+
currentData = [];
|
|
55
|
+
currentRaw = [];
|
|
56
|
+
return evt;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
for await (const line of readLines(textStream, signal)) {
|
|
60
|
+
if (signal?.aborted) return;
|
|
61
|
+
|
|
62
|
+
// Empty line → dispatch
|
|
63
|
+
if (line === "") {
|
|
64
|
+
const evt = flush();
|
|
65
|
+
if (evt) yield evt;
|
|
66
|
+
continue;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
// Comment
|
|
70
|
+
if (line.startsWith(":")) continue;
|
|
71
|
+
|
|
72
|
+
// [DONE] sentinel
|
|
73
|
+
if (line === "[DONE]") return;
|
|
74
|
+
|
|
75
|
+
const colonIdx = line.indexOf(":");
|
|
76
|
+
if (colonIdx === -1) {
|
|
77
|
+
// Field with no value
|
|
78
|
+
const field = line;
|
|
79
|
+
if (field === "event") {
|
|
80
|
+
currentEvent = "";
|
|
81
|
+
} else if (field === "data") {
|
|
82
|
+
currentData.push("");
|
|
83
|
+
}
|
|
84
|
+
currentRaw.push(line);
|
|
85
|
+
continue;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
const field = line.slice(0, colonIdx);
|
|
89
|
+
let value = line.slice(colonIdx + 1);
|
|
90
|
+
// Remove leading space after colon per SSE spec
|
|
91
|
+
if (value.startsWith(" ")) value = value.slice(1);
|
|
92
|
+
|
|
93
|
+
currentRaw.push(line);
|
|
94
|
+
|
|
95
|
+
// L1: Guard against unbounded memory growth (line count)
|
|
96
|
+
if (currentRaw.length > MAX_EVENT_LINES) {
|
|
97
|
+
const evt = flush();
|
|
98
|
+
if (evt) yield evt;
|
|
99
|
+
continue;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
// L2: Guard against unbounded memory growth (data size per line)
|
|
103
|
+
if (value.length > MAX_DATA_SIZE) {
|
|
104
|
+
// Truncate oversized data to prevent memory issues
|
|
105
|
+
value = value.slice(0, MAX_DATA_SIZE);
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
if (field === "event") {
|
|
109
|
+
currentEvent = value;
|
|
110
|
+
} else if (field === "data") {
|
|
111
|
+
currentData.push(value);
|
|
112
|
+
}
|
|
113
|
+
// id / retry fields ignored
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
// Flush any remaining event at end of stream
|
|
117
|
+
const evt = flush();
|
|
118
|
+
if (evt) yield evt;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
/** Parse SSE events and yield parsed JSON data objects */
|
|
122
|
+
export async function* readSseJson<T>(stream: ReadableStream<Uint8Array>, signal?: AbortSignal): AsyncGenerator<T> {
|
|
123
|
+
for await (const evt of readSseEvents(stream, signal)) {
|
|
124
|
+
try {
|
|
125
|
+
const parsed: T = JSON.parse(evt.data) as T;
|
|
126
|
+
yield parsed;
|
|
127
|
+
} catch {
|
|
128
|
+
// intentional parse fallback
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
}
|
|
@@ -0,0 +1,337 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Human-readable task name generator.
|
|
3
|
+
* Format: AdjectiveNoun (e.g., "SwiftFalcon", "CalmPanda")
|
|
4
|
+
*
|
|
5
|
+
* Curated lists of ~120 adjectives and ~120 animals/nouns.
|
|
6
|
+
* 120 × 120 = 14,400 combinations.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
const ADJECTIVES = [
|
|
10
|
+
"active",
|
|
11
|
+
"agile",
|
|
12
|
+
"alert",
|
|
13
|
+
"ancient",
|
|
14
|
+
"bold",
|
|
15
|
+
"brave",
|
|
16
|
+
"bright",
|
|
17
|
+
"brilliant",
|
|
18
|
+
"calm",
|
|
19
|
+
"capable",
|
|
20
|
+
"careful",
|
|
21
|
+
"charming",
|
|
22
|
+
"cheerful",
|
|
23
|
+
"clever",
|
|
24
|
+
"cloudy",
|
|
25
|
+
"cold",
|
|
26
|
+
"cool",
|
|
27
|
+
"curious",
|
|
28
|
+
"cute",
|
|
29
|
+
"daring",
|
|
30
|
+
"dark",
|
|
31
|
+
"deep",
|
|
32
|
+
"direct",
|
|
33
|
+
"eager",
|
|
34
|
+
"early",
|
|
35
|
+
"electric",
|
|
36
|
+
"elegant",
|
|
37
|
+
"energetic",
|
|
38
|
+
"enormous",
|
|
39
|
+
"epic",
|
|
40
|
+
"exact",
|
|
41
|
+
"exotic",
|
|
42
|
+
"fair",
|
|
43
|
+
"fancy",
|
|
44
|
+
"fast",
|
|
45
|
+
"fierce",
|
|
46
|
+
"firm",
|
|
47
|
+
"flat",
|
|
48
|
+
"flexible",
|
|
49
|
+
"fresh",
|
|
50
|
+
"friendly",
|
|
51
|
+
"full",
|
|
52
|
+
"fun",
|
|
53
|
+
"funny",
|
|
54
|
+
"gentle",
|
|
55
|
+
"global",
|
|
56
|
+
"golden",
|
|
57
|
+
"good",
|
|
58
|
+
"grand",
|
|
59
|
+
"grateful",
|
|
60
|
+
"great",
|
|
61
|
+
"green",
|
|
62
|
+
"happy",
|
|
63
|
+
"hard",
|
|
64
|
+
"heavy",
|
|
65
|
+
"hidden",
|
|
66
|
+
"honest",
|
|
67
|
+
"hot",
|
|
68
|
+
"huge",
|
|
69
|
+
"icy",
|
|
70
|
+
"ideal",
|
|
71
|
+
"keen",
|
|
72
|
+
"kind",
|
|
73
|
+
"large",
|
|
74
|
+
"lazy",
|
|
75
|
+
"light",
|
|
76
|
+
"lively",
|
|
77
|
+
"local",
|
|
78
|
+
"loud",
|
|
79
|
+
"lucky",
|
|
80
|
+
"magic",
|
|
81
|
+
"mighty",
|
|
82
|
+
"mild",
|
|
83
|
+
"modern",
|
|
84
|
+
"neat",
|
|
85
|
+
"new",
|
|
86
|
+
"nice",
|
|
87
|
+
"noble",
|
|
88
|
+
"odd",
|
|
89
|
+
"old",
|
|
90
|
+
"open",
|
|
91
|
+
"patient",
|
|
92
|
+
"perfect",
|
|
93
|
+
"plain",
|
|
94
|
+
"polite",
|
|
95
|
+
"popular",
|
|
96
|
+
"powerful",
|
|
97
|
+
"precise",
|
|
98
|
+
"pretty",
|
|
99
|
+
"proud",
|
|
100
|
+
"pure",
|
|
101
|
+
"quick",
|
|
102
|
+
"quiet",
|
|
103
|
+
"rapid",
|
|
104
|
+
"rare",
|
|
105
|
+
"real",
|
|
106
|
+
"rich",
|
|
107
|
+
"robust",
|
|
108
|
+
"round",
|
|
109
|
+
"royal",
|
|
110
|
+
"safe",
|
|
111
|
+
"sharp",
|
|
112
|
+
"short",
|
|
113
|
+
"shy",
|
|
114
|
+
"silent",
|
|
115
|
+
"simple",
|
|
116
|
+
"slim",
|
|
117
|
+
"smart",
|
|
118
|
+
"smooth",
|
|
119
|
+
"soft",
|
|
120
|
+
"solar",
|
|
121
|
+
"solid",
|
|
122
|
+
"steady",
|
|
123
|
+
"strange",
|
|
124
|
+
"strong",
|
|
125
|
+
"sunny",
|
|
126
|
+
"swift",
|
|
127
|
+
"tall",
|
|
128
|
+
"tame",
|
|
129
|
+
"tiny",
|
|
130
|
+
"tough",
|
|
131
|
+
"true",
|
|
132
|
+
"unique",
|
|
133
|
+
"vast",
|
|
134
|
+
"warm",
|
|
135
|
+
"wild",
|
|
136
|
+
"wise",
|
|
137
|
+
"zany",
|
|
138
|
+
"zen",
|
|
139
|
+
] as const;
|
|
140
|
+
|
|
141
|
+
const NOUNS = [
|
|
142
|
+
"albatross",
|
|
143
|
+
"ant",
|
|
144
|
+
"antelope",
|
|
145
|
+
"ape",
|
|
146
|
+
"archer",
|
|
147
|
+
"badger",
|
|
148
|
+
"bass",
|
|
149
|
+
"bat",
|
|
150
|
+
"bear",
|
|
151
|
+
"beaver",
|
|
152
|
+
"bee",
|
|
153
|
+
"beetle",
|
|
154
|
+
"bird",
|
|
155
|
+
"bison",
|
|
156
|
+
"boar",
|
|
157
|
+
"bobcat",
|
|
158
|
+
"bull",
|
|
159
|
+
"buzzard",
|
|
160
|
+
"camel",
|
|
161
|
+
"canary",
|
|
162
|
+
"carp",
|
|
163
|
+
"cat",
|
|
164
|
+
"cedar",
|
|
165
|
+
"cheetah",
|
|
166
|
+
"chicken",
|
|
167
|
+
"cobra",
|
|
168
|
+
"cod",
|
|
169
|
+
"condor",
|
|
170
|
+
"coral",
|
|
171
|
+
"cougar",
|
|
172
|
+
"crab",
|
|
173
|
+
"crane",
|
|
174
|
+
"cricket",
|
|
175
|
+
"crow",
|
|
176
|
+
"deer",
|
|
177
|
+
"dolphin",
|
|
178
|
+
"dove",
|
|
179
|
+
"dragon",
|
|
180
|
+
"duck",
|
|
181
|
+
"eagle",
|
|
182
|
+
"eel",
|
|
183
|
+
"elk",
|
|
184
|
+
"falcon",
|
|
185
|
+
"ferret",
|
|
186
|
+
"finch",
|
|
187
|
+
"flamingo",
|
|
188
|
+
"fox",
|
|
189
|
+
"frog",
|
|
190
|
+
"gazelle",
|
|
191
|
+
"gecko",
|
|
192
|
+
"ghost",
|
|
193
|
+
"gibbon",
|
|
194
|
+
"goat",
|
|
195
|
+
"goldfish",
|
|
196
|
+
"goose",
|
|
197
|
+
"gorilla",
|
|
198
|
+
"halibut",
|
|
199
|
+
"hamster",
|
|
200
|
+
"hare",
|
|
201
|
+
"hawk",
|
|
202
|
+
"heron",
|
|
203
|
+
"horse",
|
|
204
|
+
"hummingbird",
|
|
205
|
+
"hyena",
|
|
206
|
+
"ibis",
|
|
207
|
+
"iguana",
|
|
208
|
+
"impala",
|
|
209
|
+
"jackal",
|
|
210
|
+
"jaguar",
|
|
211
|
+
"jay",
|
|
212
|
+
"jellyfish",
|
|
213
|
+
"kangaroo",
|
|
214
|
+
"kite",
|
|
215
|
+
"kiwi",
|
|
216
|
+
"koala",
|
|
217
|
+
"krill",
|
|
218
|
+
"lark",
|
|
219
|
+
"lemur",
|
|
220
|
+
"leopard",
|
|
221
|
+
"lion",
|
|
222
|
+
"lizard",
|
|
223
|
+
"llama",
|
|
224
|
+
"lobster",
|
|
225
|
+
"lynx",
|
|
226
|
+
"macaw",
|
|
227
|
+
"magnet",
|
|
228
|
+
"mammoth",
|
|
229
|
+
"marmot",
|
|
230
|
+
"mink",
|
|
231
|
+
"mole",
|
|
232
|
+
"monkey",
|
|
233
|
+
"moose",
|
|
234
|
+
"moth",
|
|
235
|
+
"mouse",
|
|
236
|
+
"newt",
|
|
237
|
+
"ocelot",
|
|
238
|
+
"octopus",
|
|
239
|
+
"orca",
|
|
240
|
+
"ostrich",
|
|
241
|
+
"otter",
|
|
242
|
+
"owl",
|
|
243
|
+
"ox",
|
|
244
|
+
"panda",
|
|
245
|
+
"panther",
|
|
246
|
+
"parrot",
|
|
247
|
+
"peacock",
|
|
248
|
+
"pelican",
|
|
249
|
+
"penguin",
|
|
250
|
+
"pike",
|
|
251
|
+
"pony",
|
|
252
|
+
"python",
|
|
253
|
+
"quail",
|
|
254
|
+
"rabbit",
|
|
255
|
+
"raccoon",
|
|
256
|
+
"ram",
|
|
257
|
+
"raven",
|
|
258
|
+
"robin",
|
|
259
|
+
"rook",
|
|
260
|
+
"sable",
|
|
261
|
+
"salmon",
|
|
262
|
+
"scorpion",
|
|
263
|
+
"seal",
|
|
264
|
+
"shark",
|
|
265
|
+
"sheep",
|
|
266
|
+
"snail",
|
|
267
|
+
"sparrow",
|
|
268
|
+
"spider",
|
|
269
|
+
"squid",
|
|
270
|
+
"squirrel",
|
|
271
|
+
"stork",
|
|
272
|
+
"swan",
|
|
273
|
+
"tiger",
|
|
274
|
+
"toad",
|
|
275
|
+
"tortoise",
|
|
276
|
+
"toucan",
|
|
277
|
+
"trout",
|
|
278
|
+
"tuna",
|
|
279
|
+
"turkey",
|
|
280
|
+
"turtle",
|
|
281
|
+
"viper",
|
|
282
|
+
"vulture",
|
|
283
|
+
"walrus",
|
|
284
|
+
"wasp",
|
|
285
|
+
"whale",
|
|
286
|
+
"wolf",
|
|
287
|
+
"wombat",
|
|
288
|
+
"woodpecker",
|
|
289
|
+
"wren",
|
|
290
|
+
"yak",
|
|
291
|
+
"zebra",
|
|
292
|
+
] as const;
|
|
293
|
+
|
|
294
|
+
function capitalize(s: string): string {
|
|
295
|
+
return s.charAt(0).toUpperCase() + s.slice(1);
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
let usedNames = new Set<string>();
|
|
299
|
+
|
|
300
|
+
/**
|
|
301
|
+
* Generate a unique two-word identifier (e.g., "SwiftFalcon").
|
|
302
|
+
* Resets and starts over if all combinations exhausted.
|
|
303
|
+
*/
|
|
304
|
+
export function generateTaskName(): string {
|
|
305
|
+
// Try random combinations first (50 attempts)
|
|
306
|
+
for (let attempt = 0; attempt < 50; attempt++) {
|
|
307
|
+
const adj = ADJECTIVES[Math.floor(Math.random() * ADJECTIVES.length)]!;
|
|
308
|
+
const noun = NOUNS[Math.floor(Math.random() * NOUNS.length)]!;
|
|
309
|
+
const name = `${capitalize(adj)}${capitalize(noun)}`;
|
|
310
|
+
if (!usedNames.has(name)) {
|
|
311
|
+
usedNames.add(name);
|
|
312
|
+
return name;
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
// Exhaustive search if random fails
|
|
317
|
+
for (const adj of ADJECTIVES) {
|
|
318
|
+
for (const noun of NOUNS) {
|
|
319
|
+
const name = `${capitalize(adj)}${capitalize(noun)}`;
|
|
320
|
+
if (!usedNames.has(name)) {
|
|
321
|
+
usedNames.add(name);
|
|
322
|
+
return name;
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
// All combinations exhausted — reset and start over
|
|
328
|
+
usedNames.clear();
|
|
329
|
+
return generateTaskName();
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
/**
|
|
333
|
+
* Reset name generator state (for testing).
|
|
334
|
+
*/
|
|
335
|
+
export function resetTaskNames(): void {
|
|
336
|
+
usedNames = new Set<string>();
|
|
337
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Central timing instrumentation for startup profiling.
|
|
3
|
+
* Enable with PI_TIMING=1 environment variable.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
const ENABLED = process.env.PI_TIMING === "1";
|
|
7
|
+
const timings: Array<{ label: string; ms: number }> = [];
|
|
8
|
+
const MAX_TIMINGS = 500;
|
|
9
|
+
let lastTime = Date.now();
|
|
10
|
+
|
|
11
|
+
export function resetTimings(): void {
|
|
12
|
+
if (!ENABLED) return;
|
|
13
|
+
timings.length = 0;
|
|
14
|
+
lastTime = Date.now();
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export function time(label: string): void {
|
|
18
|
+
if (!ENABLED) return;
|
|
19
|
+
if (timings.length >= MAX_TIMINGS) timings.shift();
|
|
20
|
+
const now = Date.now();
|
|
21
|
+
timings.push({ label, ms: now - lastTime });
|
|
22
|
+
lastTime = now;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export function printTimings(): void {
|
|
26
|
+
if (!ENABLED || timings.length === 0) return;
|
|
27
|
+
console.error("\n--- Startup Timings ---");
|
|
28
|
+
for (const t of timings) {
|
|
29
|
+
console.error(` ${t.label}: ${t.ms}ms`);
|
|
30
|
+
}
|
|
31
|
+
console.error(` TOTAL: ${timings.reduce((a, b) => a + b.ms, 0)}ms`);
|
|
32
|
+
console.error("------------------------\n");
|
|
33
|
+
}
|