pi-crew 0.9.50 → 0.9.52
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 +150 -0
- package/README.md +216 -20
- package/dist/build-meta.json +2222 -1761
- package/dist/index.mjs +18636 -17603
- package/docs/actions-reference.md +431 -1
- package/package.json +19 -9
- package/schema.json +41 -0
- package/scripts/check-bundle-size.mjs +38 -0
- package/scripts/test-runner.mjs +11 -1
- package/skills/distill-software/SKILL.md +24 -1
- package/dist/index.mjs.map +0 -7
- package/docs/FEATURE_INTAKE.md +0 -126
- package/docs/HARNESS.md +0 -87
- package/docs/HARNESS_BACKLOG.md +0 -89
- package/docs/PROJECT_REVIEW.md +0 -270
- package/docs/PROJECT_REVIEW_FIXES.md +0 -342
- package/docs/PROJECT_REVIEW_ROUND4.md +0 -156
- package/docs/PROJECT_REVIEW_ROUND5.md +0 -86
- package/docs/REVIEW-FINDINGS-2026-06 +0 -357
- package/docs/REVIEW-FINDINGS-2026-07-CORE.md +0 -139
- package/docs/REVIEW-FINDINGS-2026-07.md +0 -125
- package/docs/TEST_MATRIX.md +0 -51
- package/docs/archive/README.md +0 -91
- package/docs/archive/followup-review-round3-2026-05-12.md +0 -342
- package/docs/archive/followup-review-round4-2026-05-13.md +0 -107
- package/docs/archive/pi-crew-bugs.md +0 -961
- package/docs/archive/pi-crew-test-final.md +0 -120
- package/docs/archive/pi-crew-test-results.md +0 -260
- package/docs/archive/pi-crew-test-round2.md +0 -136
- package/docs/archive/pi-crew-test-round4.md +0 -100
- package/docs/archive/pi-crew-test-round5.md +0 -70
- package/docs/archive/pi-crew-test-round6.md +0 -110
- package/docs/archive/pi-crew-v0.5.10-audit-fix-plan.md +0 -60
- package/docs/archive/pi-crew-v0.5.11-audit-fix-plan.md +0 -92
- package/docs/archive/pi-crew-v0.5.12-audit-fix-plan.md +0 -76
- package/docs/archive/pi-crew-v0.5.13-audit-fix-plan.md +0 -75
- package/docs/archive/pi-crew-v0.5.14-audit-fix-plan.md +0 -75
- package/docs/archive/pi-crew-v0.5.16-audit-fix-plan.md +0 -35
- package/docs/archive/pi-crew-v0.5.17-audit-fix-plan.md +0 -80
- package/docs/archive/pi-crew-v0.5.5-audit-fix-plan.md +0 -133
- package/docs/archive/pi-crew-v0.5.9-audit-fix-plan.md +0 -88
- package/docs/archive/pi-mono-opportunities.md +0 -969
- package/docs/archive/pi-mono-review.md +0 -291
- package/docs/archive/pi-subagent4-comparison.md +0 -261
- package/docs/archive/pi-subagents3-deep-analysis.md +0 -508
- package/docs/bugs/bug-021-notification-badge-counter-misleading.md +0 -293
- package/docs/bugs/bug-023-chain-windows-path-resolution.md +0 -106
- package/docs/bugs/bug-quota-display-truncation.md +0 -223
- package/docs/bugs/cross-session-notification-leakage.md +0 -82
- package/docs/code-review-2026-05-11.md +0 -592
- package/docs/coding-agent-optimization.md +0 -268
- package/docs/comparison-pi-subagents-vs-pi-crew.md +0 -303
- package/docs/decisions/0001-durable-state.md +0 -41
- package/docs/decisions/0002-child-process-for-async.md +0 -42
- package/docs/decisions/0003-depth-guard.md +0 -36
- package/docs/decisions/0004-execfile-over-exec.md +0 -34
- package/docs/decisions/0005-no-parameter-properties.md +0 -49
- package/docs/decisions/0006-publish-bundled-esm.md +0 -63
- package/docs/decisions/0007-active-run-binary-index.md +0 -54
- package/docs/decisions/0008-child-pi-warm-pool.md +0 -61
- package/docs/decisions/2026-07-21-broker-phase4-default-on.md +0 -77
- package/docs/decisions/2026-07-21-broker-windows-perms.md +0 -91
- package/docs/decisions/2026-07-22-broker-phase4-gated-on.md +0 -99
- package/docs/decisions/2026-07-24-oidc-trusted-publishing.md +0 -112
- package/docs/decisions/README.md +0 -26
- package/docs/deep-review-report.md +0 -384
- package/docs/distillation/cybersecurity-patterns.md +0 -294
- package/docs/feature-analysis-subagent4.md +0 -305
- package/docs/fix-plan-disabletools-exit-null.md +0 -219
- package/docs/fixes/BATCH_A_H1_H2.md +0 -86
- package/docs/fixes/bug-006-foreground-cancel-concurrent.md +0 -78
- package/docs/fixes/bug-007-async-notifier-stale-ctx.md +0 -112
- package/docs/fixes/bug-008-child-process-silent-timeout.md +0 -100
- package/docs/fixes/bug-009-executor-yield-limit-needs-attention.md +0 -75
- package/docs/fixes/bug-010-child-process-api-key-filtered.md +0 -109
- package/docs/fixes/bug-011-spawn-pi-enoent.md +0 -92
- package/docs/fixes/bug-012-essential-env-stripped.md +0 -89
- package/docs/fixes/bug-013-background-runner-death.md +0 -84
- package/docs/fixes/bug-014-infinite-retry-loop-needs-attention.md +0 -82
- package/docs/fixes/bug-015-background-runner-sigterm.md +0 -65
- package/docs/fixes/bug-017-background-runner-session-shutdown.md +0 -66
- package/docs/fixes/bug-017-background-runner-sigkill-double-fork.md +0 -28
- package/docs/fixes/bug-018-child-pi-worker-stdin-hang.md +0 -61
- package/docs/fixes/bug-019-phantom-runs-temp-workspace.md +0 -52
- package/docs/fixes/bug-020-infinite-retry-loop-needs-attention.md +0 -47
- package/docs/fixes/v0.9.10/locks-fix-verify.md +0 -3
- package/docs/fixes/v0.9.10/smoke-test.md +0 -12
- package/docs/followup-plan-2026-05-12.md +0 -463
- package/docs/followup-review-2026-05-12.md +0 -297
- package/docs/goals.md +0 -59
- package/docs/implementation-plan-top3.md +0 -333
- package/docs/issue-29-analysis.md +0 -189
- package/docs/live-mailbox-runtime.md +0 -36
- package/docs/migration/atomic-write-v2-migration.md +0 -299
- package/docs/next-upgrade-roadmap.md +0 -808
- package/docs/oh-my-pi-research.md +0 -509
- package/docs/optimization-plan-2026-07.md +0 -366
- package/docs/optimization-plan.md +0 -644
- package/docs/patterns/command-agent-skill.md +0 -71
- package/docs/perf/baseline-2026-05.md +0 -113
- package/docs/perf/final-report-2026-05.md +0 -206
- package/docs/perf/optimization-plan-2026-07-verified.md +0 -396
- package/docs/perf/performance-audit-report-2026-07.md +0 -948
- package/docs/perf/performance-review-2026-07.md +0 -287
- package/docs/perf/sprint-1-report.md +0 -71
- package/docs/perf/sprint-2-report.md +0 -81
- package/docs/perf/sprint-2.5-report.md +0 -53
- package/docs/perf/sprint-3-report.md +0 -36
- package/docs/perf/sprint-4-report.md +0 -47
- package/docs/perf/sprint-5-report.md +0 -51
- package/docs/perf/sprint-6-report.md +0 -94
- package/docs/perf/sprint-7-report.md +0 -74
- package/docs/perf/upgrade-plan-2026-05.md +0 -147
- package/docs/performance-optimization-execution-plan.md +0 -520
- package/docs/phase4-triage.md +0 -58
- package/docs/pi-crew-investigation-report.md +0 -411
- package/docs/product/README.md +0 -31
- package/docs/product/platform.md +0 -27
- package/docs/product/runtime-safety.md +0 -37
- package/docs/product/team-run.md +0 -39
- package/docs/product/team-tool.md +0 -37
- package/docs/runtime-analysis-child-vs-live.md +0 -171
- package/docs/runtime-migration-in-process-analysis.md +0 -250
- package/docs/skills/REFERENCE.md +0 -138
- package/docs/stories/README.md +0 -32
- package/docs/stories/US-DEPS-major-upgrade.md +0 -62
- package/docs/stories/backlog.md +0 -36
- package/docs/superpowers/plans/2026-06-09-fallow-patterns-adoption.md +0 -1270
- package/docs/templates/decision.md +0 -27
- package/docs/templates/story.md +0 -44
- package/docs/templates/validation-report.md +0 -32
- package/docs/ui-optimization-plan.md +0 -447
- package/src/adapters/claude-adapter.ts +0 -23
- package/src/adapters/codex-adapter.ts +0 -21
- package/src/adapters/cursor-adapter.ts +0 -17
- package/src/adapters/export-util.ts +0 -143
- package/src/adapters/index.ts +0 -15
- package/src/adapters/registry.ts +0 -18
- package/src/adapters/types.ts +0 -23
- package/src/agents/agent-config.ts +0 -194
- package/src/agents/agent-search.ts +0 -98
- package/src/agents/agent-serializer.ts +0 -38
- package/src/agents/discover-agents.ts +0 -623
- package/src/benchmark/benchmark-runner.ts +0 -313
- package/src/benchmark/feedback-loop.ts +0 -73
- package/src/config/config.ts +0 -1269
- package/src/config/defaults.ts +0 -193
- package/src/config/drift-detector.ts +0 -290
- package/src/config/markers.ts +0 -330
- package/src/config/resilient-parser.ts +0 -117
- package/src/config/role-tools.ts +0 -118
- package/src/config/suggestions.ts +0 -75
- package/src/config/types.ts +0 -278
- package/src/errors.ts +0 -194
- package/src/extension/action-suggestions.ts +0 -117
- package/src/extension/async-notifier.ts +0 -179
- package/src/extension/autonomous-policy.ts +0 -209
- package/src/extension/command-completions.ts +0 -120
- package/src/extension/context-status-injection.ts +0 -185
- package/src/extension/crew-autocomplete.ts +0 -131
- package/src/extension/crew-cleanup.ts +0 -168
- package/src/extension/crew-input-router.ts +0 -93
- package/src/extension/crew-shortcuts.ts +0 -87
- package/src/extension/crew-vibes/cat-frames.ts +0 -18
- package/src/extension/crew-vibes/config.ts +0 -195
- package/src/extension/crew-vibes/figures.ts +0 -101
- package/src/extension/crew-vibes/font-detect.ts +0 -71
- package/src/extension/crew-vibes/footer.ts +0 -292
- package/src/extension/crew-vibes/index.ts +0 -432
- package/src/extension/crew-vibes/provider-usage.ts +0 -396
- package/src/extension/crew-vibes/render.ts +0 -206
- package/src/extension/crew-vibes/speed.ts +0 -286
- package/src/extension/cross-extension-rpc.ts +0 -350
- package/src/extension/help.ts +0 -62
- package/src/extension/import-index.ts +0 -74
- package/src/extension/knowledge-injection.ts +0 -402
- package/src/extension/management.ts +0 -571
- package/src/extension/message-renderers.ts +0 -108
- package/src/extension/notification-router.ts +0 -152
- package/src/extension/notification-sink.ts +0 -54
- package/src/extension/pi-api.ts +0 -56
- package/src/extension/plan-orchestrate.ts +0 -302
- package/src/extension/project-init.ts +0 -170
- package/src/extension/register.ts +0 -113
- package/src/extension/registration/artifact-cleanup.ts +0 -20
- package/src/extension/registration/command-registration.ts +0 -58
- package/src/extension/registration/command-utils.ts +0 -58
- package/src/extension/registration/commands.ts +0 -1228
- package/src/extension/registration/compaction-guard.ts +0 -333
- package/src/extension/registration/context-builder.ts +0 -135
- package/src/extension/registration/crash-recovery-cache.ts +0 -54
- package/src/extension/registration/foreground-run-controller.ts +0 -238
- package/src/extension/registration/hook-registration.ts +0 -119
- package/src/extension/registration/lazy-configurers.ts +0 -124
- package/src/extension/registration/lifecycle-handlers.ts +0 -923
- package/src/extension/registration/lifecycle.ts +0 -259
- package/src/extension/registration/observability.ts +0 -322
- package/src/extension/registration/registration-types.ts +0 -158
- package/src/extension/registration/runtime-cleanup.ts +0 -230
- package/src/extension/registration/subagent-helpers.ts +0 -125
- package/src/extension/registration/subagent-manager-setup.ts +0 -330
- package/src/extension/registration/subagent-tools.ts +0 -456
- package/src/extension/registration/team-tool.ts +0 -220
- package/src/extension/registration/tool-registration.ts +0 -50
- package/src/extension/registration/ui.ts +0 -172
- package/src/extension/registration/viewers.ts +0 -121
- package/src/extension/registration/wire-cross-extension.ts +0 -37
- package/src/extension/result-watcher.ts +0 -139
- package/src/extension/rpc-hmac.ts +0 -256
- package/src/extension/run-bundle-schema.ts +0 -104
- package/src/extension/run-export.ts +0 -97
- package/src/extension/run-import.ts +0 -168
- package/src/extension/run-index.ts +0 -131
- package/src/extension/run-maintenance.ts +0 -190
- package/src/extension/session-summary.ts +0 -18
- package/src/extension/team-manager-command.ts +0 -153
- package/src/extension/team-onboard.ts +0 -177
- package/src/extension/team-recommendation.ts +0 -288
- package/src/extension/team-tool/anchor.ts +0 -172
- package/src/extension/team-tool/api.ts +0 -1244
- package/src/extension/team-tool/auto-summarize.ts +0 -142
- package/src/extension/team-tool/cache-control.ts +0 -19
- package/src/extension/team-tool/cancel.ts +0 -337
- package/src/extension/team-tool/chain-dispatch.ts +0 -95
- package/src/extension/team-tool/chain-executor.ts +0 -379
- package/src/extension/team-tool/config-patch.ts +0 -50
- package/src/extension/team-tool/context.ts +0 -149
- package/src/extension/team-tool/destructive-gate.ts +0 -52
- package/src/extension/team-tool/doctor.ts +0 -431
- package/src/extension/team-tool/explain.ts +0 -282
- package/src/extension/team-tool/failure-patterns.ts +0 -118
- package/src/extension/team-tool/goal-wrap.ts +0 -330
- package/src/extension/team-tool/goal.ts +0 -556
- package/src/extension/team-tool/handle-schedule.ts +0 -332
- package/src/extension/team-tool/handle-settings.ts +0 -520
- package/src/extension/team-tool/health-monitor.ts +0 -481
- package/src/extension/team-tool/inspect.ts +0 -88
- package/src/extension/team-tool/intent-policy.ts +0 -45
- package/src/extension/team-tool/lifecycle-actions.ts +0 -615
- package/src/extension/team-tool/orchestrate.ts +0 -98
- package/src/extension/team-tool/parallel-dispatch.ts +0 -183
- package/src/extension/team-tool/plan.ts +0 -50
- package/src/extension/team-tool/respond.ts +0 -150
- package/src/extension/team-tool/run-not-found.ts +0 -49
- package/src/extension/team-tool/run.ts +0 -1035
- package/src/extension/team-tool/status.ts +0 -260
- package/src/extension/team-tool/workflow-manage.ts +0 -261
- package/src/extension/team-tool-types.ts +0 -26
- package/src/extension/team-tool.ts +0 -1116
- package/src/extension/tool-result.ts +0 -16
- package/src/extension/validate-resources.ts +0 -108
- package/src/hooks/registry.ts +0 -200
- package/src/hooks/types.ts +0 -69
- package/src/i18n.ts +0 -212
- package/src/observability/correlation.ts +0 -50
- package/src/observability/event-bus.ts +0 -86
- package/src/observability/event-to-metric.ts +0 -170
- package/src/observability/exporters/adapter.ts +0 -27
- package/src/observability/exporters/otlp-exporter.ts +0 -356
- package/src/observability/exporters/prometheus-exporter.ts +0 -54
- package/src/observability/metric-registry.ts +0 -100
- package/src/observability/metric-retention.ts +0 -64
- package/src/observability/metric-sink.ts +0 -99
- package/src/observability/metrics-primitives.ts +0 -219
- package/src/plugins/plugin-define.ts +0 -6
- package/src/plugins/plugin-registry.ts +0 -32
- package/src/plugins/plugins/index.ts +0 -3
- package/src/plugins/plugins/nextjs.ts +0 -19
- package/src/plugins/plugins/vite.ts +0 -10
- package/src/plugins/plugins/vitest.ts +0 -9
- package/src/prompt/prompt-runtime.ts +0 -380
- package/src/runtime/adaptive-plan.ts +0 -563
- package/src/runtime/agent-control.ts +0 -215
- package/src/runtime/agent-memory.ts +0 -81
- package/src/runtime/agent-observability.ts +0 -122
- package/src/runtime/anchor-manager.ts +0 -475
- package/src/runtime/async-marker.ts +0 -32
- package/src/runtime/async-runner.ts +0 -381
- package/src/runtime/attention-events.ts +0 -28
- package/src/runtime/auto-summarize.ts +0 -344
- package/src/runtime/background-runner.ts +0 -837
- package/src/runtime/batch-barrier.ts +0 -147
- package/src/runtime/broker-issuer.ts +0 -37
- package/src/runtime/cancellation-token.ts +0 -99
- package/src/runtime/cancellation.ts +0 -99
- package/src/runtime/capability-inventory.ts +0 -137
- package/src/runtime/chain-parser.ts +0 -237
- package/src/runtime/chain-runner.ts +0 -606
- package/src/runtime/checkpoint.ts +0 -291
- package/src/runtime/child-pi-constants.ts +0 -42
- package/src/runtime/child-pi-kill.ts +0 -180
- package/src/runtime/child-pi-pool.ts +0 -68
- package/src/runtime/child-pi-spawn.ts +0 -287
- package/src/runtime/child-pi-steering.ts +0 -128
- package/src/runtime/child-pi-streams.ts +0 -296
- package/src/runtime/child-pi-transcript.ts +0 -169
- package/src/runtime/child-pi.ts +0 -1105
- package/src/runtime/coalesce-tasks.ts +0 -268
- package/src/runtime/code-summary.ts +0 -292
- package/src/runtime/command-trace.ts +0 -105
- package/src/runtime/compact-pipeline.ts +0 -56
- package/src/runtime/compact-stages/ansi-strip-stage.ts +0 -25
- package/src/runtime/compact-stages/blank-collapse-stage.ts +0 -31
- package/src/runtime/compact-stages/deduplicate-stage.ts +0 -34
- package/src/runtime/compact-stages/head-snap-stage.ts +0 -57
- package/src/runtime/compact-stages/index.ts +0 -23
- package/src/runtime/compact-stages/tail-capture-stage.ts +0 -77
- package/src/runtime/compact-stages/truncation-stage.ts +0 -74
- package/src/runtime/compaction-summary.ts +0 -278
- package/src/runtime/completion-guard.ts +0 -207
- package/src/runtime/concurrency.ts +0 -58
- package/src/runtime/crash-classification.ts +0 -229
- package/src/runtime/crash-recovery.ts +0 -577
- package/src/runtime/crew-agent-records.ts +0 -593
- package/src/runtime/crew-agent-runtime.ts +0 -62
- package/src/runtime/crew-broker-child.ts +0 -88
- package/src/runtime/crew-broker-client.ts +0 -673
- package/src/runtime/crew-broker-tokens.ts +0 -84
- package/src/runtime/crew-broker.ts +0 -1276
- package/src/runtime/crew-hooks.ts +0 -227
- package/src/runtime/cross-extension-rpc.ts +0 -143
- package/src/runtime/custom-tools/irc-tool.ts +0 -282
- package/src/runtime/custom-tools/submit-result-tool.ts +0 -102
- package/src/runtime/deadletter.ts +0 -47
- package/src/runtime/delivery-coordinator.ts +0 -211
- package/src/runtime/delta-conflict.ts +0 -348
- package/src/runtime/deterministic-ast.ts +0 -161
- package/src/runtime/diagnostic-export.ts +0 -171
- package/src/runtime/direct-run.ts +0 -45
- package/src/runtime/dwf-state-store.ts +0 -102
- package/src/runtime/dynamic-workflow-context.ts +0 -1016
- package/src/runtime/dynamic-workflow-runner.ts +0 -310
- package/src/runtime/effectiveness.ts +0 -90
- package/src/runtime/errors/crew-errors.ts +0 -162
- package/src/runtime/event-stream-bridge.ts +0 -98
- package/src/runtime/foreground-control.ts +0 -193
- package/src/runtime/foreground-watchdog.ts +0 -132
- package/src/runtime/global-worker-cap.ts +0 -96
- package/src/runtime/goal-achievement.ts +0 -148
- package/src/runtime/goal-evaluator.ts +0 -361
- package/src/runtime/goal-loop-runner.ts +0 -828
- package/src/runtime/goal-state-store.ts +0 -219
- package/src/runtime/green-contract.ts +0 -55
- package/src/runtime/group-join.ts +0 -267
- package/src/runtime/handoff-manager.ts +0 -598
- package/src/runtime/heartbeat-gradient.ts +0 -36
- package/src/runtime/heartbeat-watcher.ts +0 -239
- package/src/runtime/hidden-handoff.ts +0 -407
- package/src/runtime/important-line-classifier.ts +0 -140
- package/src/runtime/intercom-bridge.ts +0 -187
- package/src/runtime/iteration-hooks.ts +0 -305
- package/src/runtime/live-agent-control.ts +0 -136
- package/src/runtime/live-agent-manager.ts +0 -704
- package/src/runtime/live-control-realtime.ts +0 -56
- package/src/runtime/live-extension-bridge.ts +0 -148
- package/src/runtime/live-irc.ts +0 -97
- package/src/runtime/live-session-health.ts +0 -108
- package/src/runtime/live-session-runtime.ts +0 -1139
- package/src/runtime/loop-gates.ts +0 -128
- package/src/runtime/manifest-cache.ts +0 -375
- package/src/runtime/mcp-proxy.ts +0 -105
- package/src/runtime/metric-parser.ts +0 -36
- package/src/runtime/model-fallback.ts +0 -409
- package/src/runtime/model-resolver.ts +0 -126
- package/src/runtime/model-scope.ts +0 -158
- package/src/runtime/orphan-worker-registry.ts +0 -465
- package/src/runtime/output-validator.ts +0 -202
- package/src/runtime/overflow-recovery.ts +0 -206
- package/src/runtime/parallel-research.ts +0 -68
- package/src/runtime/parallel-utils.ts +0 -160
- package/src/runtime/parent-guard.ts +0 -134
- package/src/runtime/path-overlap.ts +0 -150
- package/src/runtime/peer-dep.ts +0 -292
- package/src/runtime/per-write-validator.ts +0 -181
- package/src/runtime/phase-progress.ts +0 -217
- package/src/runtime/phase-tracker.ts +0 -385
- package/src/runtime/pi-args.ts +0 -655
- package/src/runtime/pi-json-output.ts +0 -170
- package/src/runtime/pi-spawn.ts +0 -273
- package/src/runtime/pipeline-runner.ts +0 -523
- package/src/runtime/plan-templates.ts +0 -201
- package/src/runtime/policy-engine.ts +0 -115
- package/src/runtime/post-checks.ts +0 -142
- package/src/runtime/post-exit-stdio-guard.ts +0 -104
- package/src/runtime/process-lifecycle.ts +0 -491
- package/src/runtime/process-status.ts +0 -154
- package/src/runtime/progress-event-coalescer.ts +0 -44
- package/src/runtime/progress-tracker.ts +0 -124
- package/src/runtime/prose-compressor.ts +0 -162
- package/src/runtime/recovery-recipes.ts +0 -203
- package/src/runtime/replace.ts +0 -570
- package/src/runtime/resilient-edit.ts +0 -153
- package/src/runtime/result-extractor.ts +0 -213
- package/src/runtime/retry-executor.ts +0 -100
- package/src/runtime/retry-runner.ts +0 -336
- package/src/runtime/role-permission.ts +0 -59
- package/src/runtime/run-coalesced-task-group.ts +0 -308
- package/src/runtime/run-drift.ts +0 -219
- package/src/runtime/run-tracker.ts +0 -116
- package/src/runtime/runtime-policy.ts +0 -29
- package/src/runtime/runtime-resolver.ts +0 -172
- package/src/runtime/runtime-warmup.ts +0 -160
- package/src/runtime/scheduler.ts +0 -353
- package/src/runtime/semaphore.ts +0 -141
- package/src/runtime/sensitive-paths.ts +0 -93
- package/src/runtime/session-resources.ts +0 -25
- package/src/runtime/session-snapshot.ts +0 -59
- package/src/runtime/session-usage.ts +0 -79
- package/src/runtime/settings-store.ts +0 -155
- package/src/runtime/sidechain-output.ts +0 -35
- package/src/runtime/single-agent-compose.ts +0 -84
- package/src/runtime/skill-effectiveness.ts +0 -524
- package/src/runtime/skill-instructions.ts +0 -391
- package/src/runtime/stale-reconciler.ts +0 -680
- package/src/runtime/stream-preview.ts +0 -184
- package/src/runtime/streaming-output.ts +0 -50
- package/src/runtime/subagent-manager.ts +0 -561
- package/src/runtime/subprocess-tool-registry.ts +0 -70
- package/src/runtime/supervisor-contact.ts +0 -64
- package/src/runtime/task-display.ts +0 -52
- package/src/runtime/task-graph-scheduler.ts +0 -227
- package/src/runtime/task-graph.ts +0 -290
- package/src/runtime/task-health.ts +0 -83
- package/src/runtime/task-id.ts +0 -161
- package/src/runtime/task-output-context.ts +0 -602
- package/src/runtime/task-packet.ts +0 -268
- package/src/runtime/task-quality.ts +0 -199
- package/src/runtime/task-runner/capabilities.ts +0 -78
- package/src/runtime/task-runner/context-retrieval.ts +0 -163
- package/src/runtime/task-runner/live-executor.ts +0 -227
- package/src/runtime/task-runner/output-splitter.ts +0 -152
- package/src/runtime/task-runner/progress.ts +0 -157
- package/src/runtime/task-runner/prompt-builder.ts +0 -278
- package/src/runtime/task-runner/prompt-pipeline.ts +0 -88
- package/src/runtime/task-runner/result-utils.ts +0 -16
- package/src/runtime/task-runner/retrieval-orchestrator.ts +0 -310
- package/src/runtime/task-runner/run-projection.ts +0 -125
- package/src/runtime/task-runner/state-helpers.ts +0 -176
- package/src/runtime/task-runner/tail-read.ts +0 -34
- package/src/runtime/task-runner.ts +0 -1420
- package/src/runtime/team-runner-artifacts.ts +0 -13
- package/src/runtime/team-runner.ts +0 -1993
- package/src/runtime/tool-output-pruner.ts +0 -333
- package/src/runtime/tool-progress.ts +0 -278
- package/src/runtime/usage-tracker.ts +0 -73
- package/src/runtime/verification-gates.ts +0 -571
- package/src/runtime/verification-integrity.ts +0 -105
- package/src/runtime/verification-worktree.ts +0 -186
- package/src/runtime/worker-heartbeat.ts +0 -25
- package/src/runtime/worker-startup.ts +0 -83
- package/src/runtime/workflow-state.ts +0 -195
- package/src/runtime/workspace-lock.ts +0 -443
- package/src/runtime/workspace-tree.ts +0 -312
- package/src/runtime/yield-handler.ts +0 -224
- package/src/runtime/zombie-scanner.ts +0 -298
- package/src/schema/config-schema.ts +0 -327
- package/src/schema/team-tool-schema.ts +0 -415
- package/src/schema/validation-types.ts +0 -159
- package/src/skills/discover-skills.ts +0 -197
- package/src/skills/skill-templates.ts +0 -456
- package/src/skills/validate.ts +0 -285
- package/src/state/active-run-registry.ts +0 -439
- package/src/state/artifact-store.ts +0 -176
- package/src/state/atomic-write.ts +0 -903
- package/src/state/blob-store.ts +0 -308
- package/src/state/contracts.ts +0 -158
- package/src/state/crew-init.ts +0 -269
- package/src/state/decision-ledger.ts +0 -345
- package/src/state/event-log-rotation.ts +0 -342
- package/src/state/event-log.ts +0 -1311
- package/src/state/event-reconstructor.ts +0 -229
- package/src/state/gitignore-manager.ts +0 -46
- package/src/state/health-store.ts +0 -79
- package/src/state/hook-instinct-bridge.ts +0 -94
- package/src/state/hook-integrations.ts +0 -51
- package/src/state/instinct-store.ts +0 -275
- package/src/state/jsonl-writer.ts +0 -107
- package/src/state/locks.ts +0 -562
- package/src/state/mailbox.ts +0 -916
- package/src/state/observation-store.ts +0 -176
- package/src/state/run-cache.ts +0 -193
- package/src/state/run-graph.ts +0 -183
- package/src/state/run-metrics.ts +0 -165
- package/src/state/schedule.ts +0 -166
- package/src/state/session-state-map.ts +0 -51
- package/src/state/state-store.ts +0 -958
- package/src/state/task-claims.ts +0 -61
- package/src/state/tiered-eval.ts +0 -480
- package/src/state/types-eval.ts +0 -58
- package/src/state/types.ts +0 -440
- package/src/state/usage.ts +0 -138
- package/src/state/worker-atomic-writer.ts +0 -194
- package/src/subagents/async-entry.ts +0 -1
- package/src/subagents/index.ts +0 -3
- package/src/subagents/live/control.ts +0 -1
- package/src/subagents/live/manager.ts +0 -1
- package/src/subagents/live/realtime.ts +0 -1
- package/src/subagents/live/session-runtime.ts +0 -1
- package/src/subagents/manager.ts +0 -1
- package/src/subagents/spawn.ts +0 -1
- package/src/teams/discover-teams.ts +0 -187
- package/src/teams/team-config.ts +0 -27
- package/src/teams/team-serializer.ts +0 -38
- package/src/tools/safe-bash-extension.ts +0 -54
- package/src/tools/safe-bash.ts +0 -505
- package/src/types/diff.d.ts +0 -18
- package/src/types/new-api-types.ts +0 -35
- package/src/ui/agent-management-overlay.ts +0 -160
- package/src/ui/card-colors.ts +0 -139
- package/src/ui/crew-footer.ts +0 -102
- package/src/ui/crew-select-list.ts +0 -111
- package/src/ui/dashboard-panes/agents-pane.ts +0 -164
- package/src/ui/dashboard-panes/cancellation-pane.ts +0 -66
- package/src/ui/dashboard-panes/capability-pane.ts +0 -77
- package/src/ui/dashboard-panes/health-pane.ts +0 -31
- package/src/ui/dashboard-panes/mailbox-pane.ts +0 -35
- package/src/ui/dashboard-panes/metrics-pane.ts +0 -37
- package/src/ui/dashboard-panes/progress-pane.ts +0 -38
- package/src/ui/dashboard-panes/transcript-pane.ts +0 -10
- package/src/ui/deploy-bundled-themes.ts +0 -71
- package/src/ui/dwf-phase-display.ts +0 -151
- package/src/ui/dynamic-border.ts +0 -35
- package/src/ui/heartbeat-aggregator.ts +0 -74
- package/src/ui/key-utils.ts +0 -42
- package/src/ui/keybinding-map.ts +0 -248
- package/src/ui/layout-primitives.ts +0 -106
- package/src/ui/live-conversation-overlay.ts +0 -183
- package/src/ui/live-duration.ts +0 -55
- package/src/ui/live-run-sidebar.ts +0 -301
- package/src/ui/loaders.ts +0 -176
- package/src/ui/mascot.ts +0 -436
- package/src/ui/overlays/agent-picker-overlay.ts +0 -65
- package/src/ui/overlays/confirm-overlay.ts +0 -60
- package/src/ui/overlays/help-overlay.ts +0 -177
- package/src/ui/overlays/mailbox-compose-overlay.ts +0 -181
- package/src/ui/overlays/mailbox-compose-preview.ts +0 -78
- package/src/ui/overlays/mailbox-detail-overlay.ts +0 -154
- package/src/ui/pi-ui-compat.ts +0 -68
- package/src/ui/powerbar-publisher.ts +0 -459
- package/src/ui/render-coalescer.ts +0 -101
- package/src/ui/render-diff.ts +0 -160
- package/src/ui/render-scheduler.ts +0 -224
- package/src/ui/run-action-dispatcher.ts +0 -182
- package/src/ui/run-dashboard.ts +0 -913
- package/src/ui/run-event-bus.ts +0 -381
- package/src/ui/run-snapshot-cache.ts +0 -1057
- package/src/ui/settings-overlay.ts +0 -1067
- package/src/ui/snapshot-types.ts +0 -90
- package/src/ui/spinner.ts +0 -17
- package/src/ui/status-colors.ts +0 -143
- package/src/ui/syntax-highlight.ts +0 -136
- package/src/ui/terminal-status.ts +0 -269
- package/src/ui/theme-adapter.ts +0 -271
- package/src/ui/theme-discovery.ts +0 -199
- package/src/ui/tool-progress-formatter.ts +0 -93
- package/src/ui/tool-render.ts +0 -453
- package/src/ui/tool-renderers/brief-mode.ts +0 -225
- package/src/ui/tool-renderers/index.ts +0 -726
- package/src/ui/transcript-cache.ts +0 -128
- package/src/ui/transcript-entries.ts +0 -256
- package/src/ui/transcript-viewer.ts +0 -424
- package/src/ui/widget/index.ts +0 -357
- package/src/ui/widget/widget-formatters.ts +0 -182
- package/src/ui/widget/widget-model.ts +0 -110
- package/src/ui/widget/widget-renderer.ts +0 -182
- package/src/ui/widget/widget-types.ts +0 -36
- package/src/utils/bm25-search.ts +0 -235
- package/src/utils/completion-dedupe.ts +0 -63
- package/src/utils/conflict-detect.ts +0 -668
- package/src/utils/env-allowlist.ts +0 -30
- package/src/utils/env-filter.ts +0 -155
- package/src/utils/file-coalescer.ts +0 -98
- package/src/utils/fingerprint.ts +0 -180
- package/src/utils/frontmatter.ts +0 -70
- package/src/utils/fs-watch.ts +0 -37
- package/src/utils/gh-protocol.ts +0 -556
- package/src/utils/git.ts +0 -260
- package/src/utils/guards.ts +0 -107
- package/src/utils/ids.ts +0 -24
- package/src/utils/incremental-reader.ts +0 -220
- package/src/utils/internal-error.ts +0 -10
- package/src/utils/names.ts +0 -36
- package/src/utils/ndjson.ts +0 -115
- package/src/utils/paths.ts +0 -227
- package/src/utils/project-detector.ts +0 -160
- package/src/utils/redaction.ts +0 -347
- package/src/utils/resolve-shell.ts +0 -36
- package/src/utils/run-watcher-registry.ts +0 -152
- package/src/utils/safe-paths.ts +0 -383
- package/src/utils/scan-cache.ts +0 -144
- package/src/utils/session-utils.ts +0 -110
- package/src/utils/sleep.ts +0 -54
- package/src/utils/socket-path.ts +0 -127
- package/src/utils/sse-parser.ts +0 -129
- package/src/utils/task-name-generator.ts +0 -337
- package/src/utils/timings.ts +0 -33
- package/src/utils/token-counter.ts +0 -200
- package/src/utils/visual.ts +0 -207
- package/src/workflows/cost-estimator.ts +0 -34
- package/src/workflows/discover-workflows.ts +0 -290
- package/src/workflows/intermediate-store.ts +0 -166
- package/src/workflows/preflight-validator.ts +0 -168
- package/src/workflows/topology-analyzer.ts +0 -203
- package/src/workflows/validate-workflow.ts +0 -50
- package/src/workflows/workflow-config.ts +0 -70
- package/src/workflows/workflow-serializer.ts +0 -32
- package/src/worktree/branch-freshness.ts +0 -112
- package/src/worktree/cleanup.ts +0 -341
- package/src/worktree/worktree-manager.ts +0 -1200
|
@@ -1,195 +0,0 @@
|
|
|
1
|
-
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
2
|
-
import { dirname, join } from "node:path";
|
|
3
|
-
import { hasCrewFontFile, isWebTerminal } from "./font-detect.ts";
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* Self-contained config for the crew-vibes module (speed + capacity meters).
|
|
7
|
-
* Stored in its own JSON file so it never touches the strict typebox schema
|
|
8
|
-
* used by the rest of pi-crew.
|
|
9
|
-
*/
|
|
10
|
-
|
|
11
|
-
export const SPEED_STATUS_ID = "pi-crew-speed";
|
|
12
|
-
export const CAPACITY_STATUS_ID = "pi-crew-bar";
|
|
13
|
-
export const PROVIDER_STATUS_ID = "pi-crew-bar";
|
|
14
|
-
|
|
15
|
-
function resolveHome(): string {
|
|
16
|
-
return (process.env.PI_TEAMS_HOME ?? process.env.PI_CREW_HOME)?.trim() || process.env.HOME || process.env.USERPROFILE || "";
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
export function configPath(): string {
|
|
20
|
-
return join(resolveHome(), ".pi", "agent", "pi-crew-vibes.json");
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
export type TokenDisplay = "off" | "tokens" | "percentage";
|
|
24
|
-
|
|
25
|
-
export interface SpeedConfig {
|
|
26
|
-
enabled: boolean;
|
|
27
|
-
footer: boolean;
|
|
28
|
-
indicator: boolean;
|
|
29
|
-
label: string;
|
|
30
|
-
renderIntervalMs: number;
|
|
31
|
-
slidingWindowMs: number;
|
|
32
|
-
minReliableDurationMs: number;
|
|
33
|
-
maxDisplayTokS: number;
|
|
34
|
-
defaultIntervalMs: number;
|
|
35
|
-
minIntervalMs: number;
|
|
36
|
-
maxIntervalMs: number;
|
|
37
|
-
scale: number;
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
export interface CapacityConfig {
|
|
41
|
-
enabled: boolean;
|
|
42
|
-
tokenDisplay: TokenDisplay;
|
|
43
|
-
showLabel: boolean;
|
|
44
|
-
refreshIntervalMs: number;
|
|
45
|
-
labels: [string, string, string, string, string, string];
|
|
46
|
-
icons: [string, string, string, string, string, string];
|
|
47
|
-
providerUsage: boolean;
|
|
48
|
-
providerRefreshMs: number;
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
export interface CrewVibesConfig {
|
|
52
|
-
enabled: boolean;
|
|
53
|
-
speed: SpeedConfig;
|
|
54
|
-
capacity: CapacityConfig;
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
export const DEFAULT_CONFIG: CrewVibesConfig = {
|
|
58
|
-
enabled: true,
|
|
59
|
-
speed: {
|
|
60
|
-
enabled: true,
|
|
61
|
-
footer: false,
|
|
62
|
-
indicator: true,
|
|
63
|
-
label: "tok/s",
|
|
64
|
-
renderIntervalMs: 250,
|
|
65
|
-
slidingWindowMs: 1000,
|
|
66
|
-
minReliableDurationMs: 1000,
|
|
67
|
-
maxDisplayTokS: 500,
|
|
68
|
-
defaultIntervalMs: 167,
|
|
69
|
-
minIntervalMs: 50,
|
|
70
|
-
maxIntervalMs: 250,
|
|
71
|
-
scale: 6000,
|
|
72
|
-
},
|
|
73
|
-
capacity: {
|
|
74
|
-
enabled: true,
|
|
75
|
-
tokenDisplay: "tokens",
|
|
76
|
-
showLabel: true,
|
|
77
|
-
refreshIntervalMs: 2000,
|
|
78
|
-
labels: ["Orbit", "Cruise", "Warp", "Black Hole", "Supernova", "Big Bang"],
|
|
79
|
-
icons: ["", "", "", "", "", ""],
|
|
80
|
-
providerUsage: true,
|
|
81
|
-
providerRefreshMs: 120000,
|
|
82
|
-
},
|
|
83
|
-
};
|
|
84
|
-
|
|
85
|
-
// Fallback capacity icons using standard Unicode characters that render
|
|
86
|
-
// on any terminal without the crew-vibes PUA font.
|
|
87
|
-
const FALLBACK_CAPACITY_ICONS: [string, string, string, string, string, string] = [
|
|
88
|
-
"\u25CB ", // ○ empty circle (lean)
|
|
89
|
-
"\u25D4 ", // ◔ circle with dot (chonking)
|
|
90
|
-
"\u25D1 ", // ◑ circle half filled (chonky)
|
|
91
|
-
"\u25CF ", // ● filled circle (big chonk)
|
|
92
|
-
"\u2B24 ", // ⬤ large filled circle (mega chonk)
|
|
93
|
-
"\u2B22 ", // ⬢ filled hexagon (oh lawd)
|
|
94
|
-
];
|
|
95
|
-
|
|
96
|
-
/** Return capacity icons: standard Unicode glyphs that render on any terminal.
|
|
97
|
-
* PUA glyphs (U+E710..U+E715) require crew-vibes.ttf AND terminal PUA
|
|
98
|
-
* support — many terminals cannot render them even with the font installed. */
|
|
99
|
-
export function capacityIcons(): [string, string, string, string, string, string] {
|
|
100
|
-
// Web terminals cannot render PUA glyphs — use fallback.
|
|
101
|
-
if (isWebTerminal()) return FALLBACK_CAPACITY_ICONS;
|
|
102
|
-
return hasCrewFontFile() ? DEFAULT_CONFIG.capacity.icons : FALLBACK_CAPACITY_ICONS;
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
function asRecord(value: unknown): Record<string, unknown> {
|
|
106
|
-
return value !== null && typeof value === "object" && !Array.isArray(value) ? (value as Record<string, unknown>) : {};
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
function boolFrom(raw: unknown, fallback: boolean): boolean {
|
|
110
|
-
return typeof raw === "boolean" ? raw : fallback;
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
function stringFrom(raw: unknown, fallback: string): string {
|
|
114
|
-
return typeof raw === "string" ? raw : fallback;
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
function positiveFrom(raw: unknown, fallback: number): number {
|
|
118
|
-
return typeof raw === "number" && Number.isFinite(raw) && raw > 0 ? raw : fallback;
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
function sextet(
|
|
122
|
-
raw: unknown,
|
|
123
|
-
fallback: [string, string, string, string, string, string],
|
|
124
|
-
): [string, string, string, string, string, string] {
|
|
125
|
-
if (Array.isArray(raw) && raw.length === 6 && raw.every((entry) => typeof entry === "string")) {
|
|
126
|
-
return raw as [string, string, string, string, string, string];
|
|
127
|
-
}
|
|
128
|
-
return fallback;
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
function tokenDisplayFrom(raw: unknown, fallback: TokenDisplay): TokenDisplay {
|
|
132
|
-
return raw === "off" || raw === "tokens" || raw === "percentage" ? raw : fallback;
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
function normalizeSpeed(raw: unknown): SpeedConfig {
|
|
136
|
-
const input = asRecord(raw);
|
|
137
|
-
const speed: SpeedConfig = {
|
|
138
|
-
enabled: boolFrom(input.enabled, DEFAULT_CONFIG.speed.enabled),
|
|
139
|
-
footer: boolFrom(input.footer, DEFAULT_CONFIG.speed.footer),
|
|
140
|
-
indicator: boolFrom(input.indicator, DEFAULT_CONFIG.speed.indicator),
|
|
141
|
-
label: stringFrom(input.label, DEFAULT_CONFIG.speed.label),
|
|
142
|
-
renderIntervalMs: positiveFrom(input.renderIntervalMs, DEFAULT_CONFIG.speed.renderIntervalMs),
|
|
143
|
-
slidingWindowMs: positiveFrom(input.slidingWindowMs, DEFAULT_CONFIG.speed.slidingWindowMs),
|
|
144
|
-
minReliableDurationMs: positiveFrom(input.minReliableDurationMs, DEFAULT_CONFIG.speed.minReliableDurationMs),
|
|
145
|
-
maxDisplayTokS: positiveFrom(input.maxDisplayTokS, DEFAULT_CONFIG.speed.maxDisplayTokS),
|
|
146
|
-
defaultIntervalMs: positiveFrom(input.defaultIntervalMs, DEFAULT_CONFIG.speed.defaultIntervalMs),
|
|
147
|
-
minIntervalMs: positiveFrom(input.minIntervalMs, DEFAULT_CONFIG.speed.minIntervalMs),
|
|
148
|
-
maxIntervalMs: positiveFrom(input.maxIntervalMs, DEFAULT_CONFIG.speed.maxIntervalMs),
|
|
149
|
-
scale: positiveFrom(input.scale, DEFAULT_CONFIG.speed.scale),
|
|
150
|
-
};
|
|
151
|
-
if (speed.minIntervalMs > speed.maxIntervalMs) {
|
|
152
|
-
speed.minIntervalMs = DEFAULT_CONFIG.speed.minIntervalMs;
|
|
153
|
-
speed.maxIntervalMs = DEFAULT_CONFIG.speed.maxIntervalMs;
|
|
154
|
-
}
|
|
155
|
-
return speed;
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
function normalizeCapacity(raw: unknown): CapacityConfig {
|
|
159
|
-
const input = asRecord(raw);
|
|
160
|
-
return {
|
|
161
|
-
enabled: boolFrom(input.enabled, DEFAULT_CONFIG.capacity.enabled),
|
|
162
|
-
tokenDisplay: tokenDisplayFrom(input.tokenDisplay, DEFAULT_CONFIG.capacity.tokenDisplay),
|
|
163
|
-
showLabel: boolFrom(input.showLabel, DEFAULT_CONFIG.capacity.showLabel),
|
|
164
|
-
refreshIntervalMs: positiveFrom(input.refreshIntervalMs, DEFAULT_CONFIG.capacity.refreshIntervalMs),
|
|
165
|
-
labels: sextet(input.labels, DEFAULT_CONFIG.capacity.labels),
|
|
166
|
-
icons: sextet(input.icons, DEFAULT_CONFIG.capacity.icons),
|
|
167
|
-
providerUsage: boolFrom(input.providerUsage, DEFAULT_CONFIG.capacity.providerUsage),
|
|
168
|
-
providerRefreshMs: positiveFrom(input.providerRefreshMs, DEFAULT_CONFIG.capacity.providerRefreshMs),
|
|
169
|
-
};
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
export function normalizeConfig(raw: unknown): CrewVibesConfig {
|
|
173
|
-
const input = asRecord(raw);
|
|
174
|
-
return {
|
|
175
|
-
enabled: boolFrom(input.enabled, DEFAULT_CONFIG.enabled),
|
|
176
|
-
speed: normalizeSpeed(input.speed),
|
|
177
|
-
capacity: normalizeCapacity(input.capacity),
|
|
178
|
-
};
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
export function loadConfig(): CrewVibesConfig {
|
|
182
|
-
try {
|
|
183
|
-
const path = configPath();
|
|
184
|
-
if (!existsSync(path)) return normalizeConfig(undefined);
|
|
185
|
-
return normalizeConfig(JSON.parse(readFileSync(path, "utf8")));
|
|
186
|
-
} catch {
|
|
187
|
-
return normalizeConfig(undefined);
|
|
188
|
-
}
|
|
189
|
-
}
|
|
190
|
-
|
|
191
|
-
export function saveConfig(config: CrewVibesConfig): void {
|
|
192
|
-
const path = configPath();
|
|
193
|
-
mkdirSync(dirname(path), { recursive: true });
|
|
194
|
-
writeFileSync(path, `${JSON.stringify(normalizeConfig(config), null, 2)}\n`);
|
|
195
|
-
}
|
|
@@ -1,101 +0,0 @@
|
|
|
1
|
-
import type { SpeedConfig } from "./config.ts";
|
|
2
|
-
import { hasCrewFontFile, isWebTerminal } from "./font-detect.ts";
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* Crew figures replacing the original cat glyphs from pi-speeed / pi-chonk.
|
|
6
|
-
*
|
|
7
|
-
* The working indicator uses braille spinner characters by default — the
|
|
8
|
-
* same characters pi uses for its built-in loading animation (loaders.ts
|
|
9
|
-
* DEFAULT_FRAMES). These render on ANY terminal with basic Unicode support,
|
|
10
|
-
* no custom font required.
|
|
11
|
-
*
|
|
12
|
-
* PUA glyphs (U+E700..U+E70F) from the bundled crew-vibes.ttf font are
|
|
13
|
-
* available as an opt-in alternative (set speed.indicatorStyle = "pua" in
|
|
14
|
-
* config). Requires the font to be installed via `npm run install:crew-font`
|
|
15
|
-
* AND a terminal that renders Private Use Area codepoints.
|
|
16
|
-
*/
|
|
17
|
-
|
|
18
|
-
// ── Braille spinner frames (web terminal fallback) ───────────────────
|
|
19
|
-
// Standard Unicode braille spinner — same characters pi uses for its
|
|
20
|
-
// built-in loading animation. Renders on ANY terminal.
|
|
21
|
-
const BRAILLE_FRAMES: readonly string[] = [
|
|
22
|
-
"\u280B ", // ⠋
|
|
23
|
-
"\u2819 ", // ⠙
|
|
24
|
-
"\u2839 ", // ⠹
|
|
25
|
-
"\u2838 ", // ⠸
|
|
26
|
-
"\u283C ", // ⠼
|
|
27
|
-
"\u2834 ", // ⠴
|
|
28
|
-
"\u2826 ", // ⠦
|
|
29
|
-
"\u2827 ", // ⠧
|
|
30
|
-
"\u2807 ", // ⠇
|
|
31
|
-
"\u280F ", // ⠏
|
|
32
|
-
] as const;
|
|
33
|
-
|
|
34
|
-
// ── PUA runner frames (opt-in) ────────────────────────────────────────
|
|
35
|
-
// 16 runner poses from the bundled crew-vibes.ttf font. Only usable when
|
|
36
|
-
// the font is installed AND the terminal renders PUA codepoints correctly.
|
|
37
|
-
// Each frame is one glyph + trailing space for constant 2-cell width.
|
|
38
|
-
const PUA_CREW_FRAMES: readonly string[] = [
|
|
39
|
-
"\uE700 ",
|
|
40
|
-
"\uE701 ",
|
|
41
|
-
"\uE702 ",
|
|
42
|
-
"\uE703 ",
|
|
43
|
-
"\uE704 ",
|
|
44
|
-
"\uE705 ",
|
|
45
|
-
"\uE706 ",
|
|
46
|
-
"\uE707 ",
|
|
47
|
-
"\uE708 ",
|
|
48
|
-
"\uE709 ",
|
|
49
|
-
"\uE70A ",
|
|
50
|
-
"\uE70B ",
|
|
51
|
-
"\uE70C ",
|
|
52
|
-
"\uE70D ",
|
|
53
|
-
"\uE70E ",
|
|
54
|
-
"\uE70F ",
|
|
55
|
-
] as const;
|
|
56
|
-
|
|
57
|
-
/**
|
|
58
|
-
* Return the indicator frames for the given style.
|
|
59
|
-
*
|
|
60
|
-
* Default is `"braille"` — standard Unicode braille spinner (⠋⠙⠹⠸⠼⠴⠦⠧⠇⠏)
|
|
61
|
-
* that renders correctly on every terminal, every platform, with zero
|
|
62
|
-
* font dependency. PUA runner-glyphs require crew-vibes.ttf installed AND
|
|
63
|
-
* a terminal that does font fallback for Private Use Area codepoints —
|
|
64
|
-
* Windows Terminal does NOT do this reliably, showing garbage chars even
|
|
65
|
-
* with the font installed.
|
|
66
|
-
*
|
|
67
|
-
* To opt into the PUA runner look, pass `style: "pua"` explicitly.
|
|
68
|
-
*/
|
|
69
|
-
export function crewFrames(style: "braille" | "pua" = "braille"): readonly string[] {
|
|
70
|
-
// Even when explicitly requested, fall back to braille if the font is
|
|
71
|
-
// missing or we're on a web terminal (which can't render PUA at all).
|
|
72
|
-
if (style === "pua" && (isWebTerminal() || !hasCrewFontFile())) return BRAILLE_FRAMES;
|
|
73
|
-
return style === "pua" ? PUA_CREW_FRAMES : BRAILLE_FRAMES;
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
// Re-export PUA frames for backward compatibility and direct consumers.
|
|
77
|
-
export const RUN_CREW_FRAMES = PUA_CREW_FRAMES;
|
|
78
|
-
|
|
79
|
-
/**
|
|
80
|
-
* Map a tok/s reading to a working-indicator frame interval in ms.
|
|
81
|
-
* Ported from pi-speeed's runcatInterval: interval = scale / speed, clamped
|
|
82
|
-
* to [min, max]. A null/zero speed falls back to the default (idle) cadence.
|
|
83
|
-
*/
|
|
84
|
-
export function intervalForSpeed(config: SpeedConfig, speed: number | null): number {
|
|
85
|
-
if (speed === null || !Number.isFinite(speed) || speed <= 0) return config.defaultIntervalMs;
|
|
86
|
-
return Math.max(config.minIntervalMs, Math.min(config.maxIntervalMs, Math.round(config.scale / speed)));
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
/**
|
|
90
|
-
* Pick the capacity stage index (0..levels-1) for a context-fill percent.
|
|
91
|
-
* Ported from pi-chonk's chonkIndex.
|
|
92
|
-
*/
|
|
93
|
-
export function capacityIndex(percent: number | null | undefined, levels = 6): number {
|
|
94
|
-
if (percent === null || percent === undefined || !Number.isFinite(percent)) return 0;
|
|
95
|
-
return Math.max(0, Math.min(levels - 1, Math.floor((Math.max(0, Math.min(100, percent)) / 100) * levels)));
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
/** The last two stages are "danger" stages and get the error color. */
|
|
99
|
-
export function isDangerStage(index: number, levels: number): boolean {
|
|
100
|
-
return index >= Math.max(0, levels - 2);
|
|
101
|
-
}
|
|
@@ -1,71 +0,0 @@
|
|
|
1
|
-
import { existsSync, readFileSync } from "node:fs";
|
|
2
|
-
import { homedir, platform } from "node:os";
|
|
3
|
-
import { join } from "node:path";
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* Detect whether the crew-vibes PUA font (U+E700..U+E70F) file exists
|
|
7
|
-
* on disk. This is a *best-effort* heuristic — file existence does NOT
|
|
8
|
-
* guarantee the terminal can render PUA glyphs (many terminals have their
|
|
9
|
-
* own font stacks). For reliable animation, braille fallback frames are
|
|
10
|
-
* used by default; PUA frames are only activated when the user explicitly
|
|
11
|
-
* enables them via config (speed.indicatorStyle = "pua").
|
|
12
|
-
*/
|
|
13
|
-
|
|
14
|
-
function fontPath(): string {
|
|
15
|
-
const os = platform();
|
|
16
|
-
const home = homedir();
|
|
17
|
-
if (os === "darwin") return join(home, "Library", "Fonts", "crew-vibes.ttf");
|
|
18
|
-
if (os === "linux") return join(home, ".local", "share", "fonts", "crew-vibes.ttf");
|
|
19
|
-
if (os === "win32") {
|
|
20
|
-
const local = process.env.LOCALAPPDATA ?? join(home, "AppData", "Local");
|
|
21
|
-
return join(local, "Microsoft", "Windows", "Fonts", "crew-vibes.ttf");
|
|
22
|
-
}
|
|
23
|
-
return "";
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
let _hasFontFile: boolean | null = null;
|
|
27
|
-
|
|
28
|
-
/** Returns true when crew-vibes.ttf exists in the platform font directory. */
|
|
29
|
-
export function hasCrewFontFile(): boolean {
|
|
30
|
-
if (_hasFontFile !== null) return _hasFontFile;
|
|
31
|
-
const p = fontPath();
|
|
32
|
-
_hasFontFile = p !== "" && existsSync(p);
|
|
33
|
-
return _hasFontFile;
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
let _isWebTerminal: boolean | null = null;
|
|
37
|
-
|
|
38
|
-
/** Returns true when running in a web-based terminal (gotty, wetty, etc.)
|
|
39
|
-
* where system fonts are not available for PUA rendering. */
|
|
40
|
-
export function isWebTerminal(): boolean {
|
|
41
|
-
if (_isWebTerminal !== null) return _isWebTerminal;
|
|
42
|
-
if (process.env.GOTTY || process.env.WEBTERM) {
|
|
43
|
-
_isWebTerminal = true;
|
|
44
|
-
return true;
|
|
45
|
-
}
|
|
46
|
-
if (process.env.TERM === "dumb") {
|
|
47
|
-
_isWebTerminal = true;
|
|
48
|
-
return true;
|
|
49
|
-
}
|
|
50
|
-
try {
|
|
51
|
-
// Check current process and ancestors — gotty is often the grandparent
|
|
52
|
-
// (gotty → tmux → pi), so /proc/self/cgroup may not contain it.
|
|
53
|
-
let pid = process.pid;
|
|
54
|
-
for (let i = 0; i < 6 && pid > 1; i++) {
|
|
55
|
-
const cgroup = readFileSync(`/proc/${pid}/cgroup`, "utf8");
|
|
56
|
-
if (cgroup.includes("gotty") || cgroup.includes("wetty")) {
|
|
57
|
-
_isWebTerminal = true;
|
|
58
|
-
return true;
|
|
59
|
-
}
|
|
60
|
-
const match = cgroup.match(/\d+:.*:(.*)/);
|
|
61
|
-
// Read PPid from status
|
|
62
|
-
const status = readFileSync(`/proc/${pid}/status`, "utf8");
|
|
63
|
-
const ppid = status.match(/^PPid:\s+(\d+)/m);
|
|
64
|
-
pid = ppid ? Number.parseInt(ppid[1], 10) : 1;
|
|
65
|
-
}
|
|
66
|
-
} catch {
|
|
67
|
-
// not Linux or /proc not available
|
|
68
|
-
}
|
|
69
|
-
_isWebTerminal = false;
|
|
70
|
-
return false;
|
|
71
|
-
}
|
|
@@ -1,292 +0,0 @@
|
|
|
1
|
-
import { isAbsolute, relative, resolve, sep } from "node:path";
|
|
2
|
-
import type { ExtensionContext } from "@earendil-works/pi-coding-agent";
|
|
3
|
-
import { requestRenderTarget } from "../../ui/pi-ui-compat.ts";
|
|
4
|
-
import { asCrewTheme, type CrewTheme } from "../../ui/theme-adapter.ts";
|
|
5
|
-
import { truncateToWidth, visibleWidth } from "../../utils/visual.ts";
|
|
6
|
-
import type { CrewVibesConfig } from "./config.ts";
|
|
7
|
-
import type { ProviderUsage } from "./provider-usage.ts";
|
|
8
|
-
import { formatCount, getCapacityUsage, renderCapacity, renderProviderUsage } from "./render.ts";
|
|
9
|
-
|
|
10
|
-
/**
|
|
11
|
-
* Custom footer replacement for crew-vibes.
|
|
12
|
-
*
|
|
13
|
-
* Why this exists: pi joins ALL `setStatus()` entries onto ONE line and
|
|
14
|
-
* right-truncates when the line overflows. The provider quota lives at the
|
|
15
|
-
* tail, so it gets chopped to "W..." whenever the `pi-crew` widget status grows
|
|
16
|
-
* during sub-agent runs. Five prior attempts (right-align padding, dynamic
|
|
17
|
-
* padding, separate keys) all failed because an extension using `setStatus`
|
|
18
|
-
* cannot see the widget's width, other extensions' widths, or pi's real render
|
|
19
|
-
* width. `setFooter` sidesteps all of that: `render(width)` receives the REAL
|
|
20
|
-
* width and we own the line layout, so the meters get a dedicated line that is
|
|
21
|
-
* never truncated by the join.
|
|
22
|
-
*/
|
|
23
|
-
|
|
24
|
-
/** Live values the footer reads on each render (owned by the extension). */
|
|
25
|
-
export interface CrewVibesFooterSource {
|
|
26
|
-
getConfig(): CrewVibesConfig;
|
|
27
|
-
getQuotaUsage(): ProviderUsage | null;
|
|
28
|
-
getThinkingLevel(): string | undefined;
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
export interface CrewVibesFooterDeps {
|
|
32
|
-
tui: unknown;
|
|
33
|
-
theme: unknown;
|
|
34
|
-
footerData: unknown;
|
|
35
|
-
ctx: ExtensionContext;
|
|
36
|
-
source: CrewVibesFooterSource;
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
interface FooterData {
|
|
40
|
-
getGitBranch(): string | null;
|
|
41
|
-
getExtensionStatuses(): ReadonlyMap<string, string>;
|
|
42
|
-
getAvailableProviderCount(): number;
|
|
43
|
-
onBranchChange(cb: () => void): () => void;
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
interface FooterComponent {
|
|
47
|
-
render(width: number): string[];
|
|
48
|
-
invalidate(): void;
|
|
49
|
-
dispose(): void;
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
function num(value: unknown): number {
|
|
53
|
-
return typeof value === "number" && Number.isFinite(value) ? value : 0;
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
/** Mirror pi's footer cwd formatting: collapse the home prefix to `~`. */
|
|
57
|
-
function formatCwdForFooter(cwd: string, home: string | undefined): string {
|
|
58
|
-
if (!home) return cwd;
|
|
59
|
-
const resolvedCwd = resolve(cwd);
|
|
60
|
-
const resolvedHome = resolve(home);
|
|
61
|
-
const rel = relative(resolvedHome, resolvedCwd);
|
|
62
|
-
const inside = rel === "" || (rel !== ".." && !rel.startsWith(`..${sep}`) && !isAbsolute(rel));
|
|
63
|
-
if (!inside) return cwd;
|
|
64
|
-
return rel === "" ? "~" : `~${sep}${rel}`;
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
/** Mirror pi's status sanitizer (collapse control chars + runs of spaces). */
|
|
68
|
-
function sanitizeStatusText(text: string): string {
|
|
69
|
-
return text
|
|
70
|
-
.replace(/[\r\n\t]/g, " ")
|
|
71
|
-
.replace(/ +/g, " ")
|
|
72
|
-
.trim();
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
function asFooterData(value: unknown): FooterData | undefined {
|
|
76
|
-
if (!value || typeof value !== "object") return undefined;
|
|
77
|
-
const record = value as Record<string, unknown>;
|
|
78
|
-
if (
|
|
79
|
-
typeof record.getGitBranch !== "function" ||
|
|
80
|
-
typeof record.getExtensionStatuses !== "function" ||
|
|
81
|
-
typeof record.getAvailableProviderCount !== "function" ||
|
|
82
|
-
typeof record.onBranchChange !== "function"
|
|
83
|
-
) {
|
|
84
|
-
return undefined;
|
|
85
|
-
}
|
|
86
|
-
return value as FooterData;
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
interface SessionTotals {
|
|
90
|
-
input: number;
|
|
91
|
-
output: number;
|
|
92
|
-
cacheRead: number;
|
|
93
|
-
cacheWrite: number;
|
|
94
|
-
cost: number;
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
function computeTotals(entries: unknown[]): SessionTotals {
|
|
98
|
-
const totals: SessionTotals = { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, cost: 0 };
|
|
99
|
-
for (const entry of entries) {
|
|
100
|
-
const rec = entry as {
|
|
101
|
-
type?: string;
|
|
102
|
-
message?: { role?: string; usage?: Record<string, unknown> & { cost?: { total?: unknown } } };
|
|
103
|
-
};
|
|
104
|
-
if (rec?.type !== "message" || rec.message?.role !== "assistant") continue;
|
|
105
|
-
const usage = rec.message.usage;
|
|
106
|
-
if (!usage) continue;
|
|
107
|
-
totals.input += num(usage.input);
|
|
108
|
-
totals.output += num(usage.output);
|
|
109
|
-
totals.cacheRead += num(usage.cacheRead);
|
|
110
|
-
totals.cacheWrite += num(usage.cacheWrite);
|
|
111
|
-
totals.cost += num(usage.cost?.total);
|
|
112
|
-
}
|
|
113
|
-
return totals;
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
class CrewVibesFooter implements FooterComponent {
|
|
117
|
-
private readonly theme: CrewTheme;
|
|
118
|
-
private readonly footerData: FooterData | undefined;
|
|
119
|
-
private readonly ctx: ExtensionContext;
|
|
120
|
-
private readonly source: CrewVibesFooterSource;
|
|
121
|
-
private readonly tui: unknown;
|
|
122
|
-
private readonly unsubscribeBranch: () => void;
|
|
123
|
-
|
|
124
|
-
constructor(deps: CrewVibesFooterDeps) {
|
|
125
|
-
this.theme = asCrewTheme(deps.theme);
|
|
126
|
-
this.footerData = asFooterData(deps.footerData);
|
|
127
|
-
this.ctx = deps.ctx;
|
|
128
|
-
this.source = deps.source;
|
|
129
|
-
this.tui = deps.tui;
|
|
130
|
-
this.unsubscribeBranch = this.footerData ? this.footerData.onBranchChange(() => requestRenderTarget(this.tui)) : () => {};
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
invalidate(): void {}
|
|
134
|
-
|
|
135
|
-
dispose(): void {
|
|
136
|
-
this.unsubscribeBranch();
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
private buildPwdLine(width: number): string {
|
|
140
|
-
const sm = this.ctx.sessionManager;
|
|
141
|
-
let pwd = formatCwdForFooter(sm.getCwd(), process.env.HOME || process.env.USERPROFILE);
|
|
142
|
-
const branch = this.footerData?.getGitBranch();
|
|
143
|
-
if (branch) pwd = `${pwd} (${branch})`;
|
|
144
|
-
const sessionName = sm.getSessionName?.();
|
|
145
|
-
if (sessionName) pwd = `${pwd} • ${sessionName}`;
|
|
146
|
-
return truncateToWidth(this.theme.fg("dim", pwd), width, this.theme.fg("dim", "..."));
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
private buildStatsLine(width: number): string {
|
|
150
|
-
const theme = this.theme;
|
|
151
|
-
const model = this.ctx.model as { id?: string; provider?: string; reasoning?: unknown; contextWindow?: number } | undefined;
|
|
152
|
-
const totals = computeTotals(this.ctx.sessionManager.getEntries() as unknown[]);
|
|
153
|
-
const contextUsage = this.ctx.getContextUsage?.();
|
|
154
|
-
const contextWindow = contextUsage?.contextWindow ?? model?.contextWindow ?? 0;
|
|
155
|
-
const percentValue = contextUsage?.percent ?? 0;
|
|
156
|
-
const percentKnown = contextUsage?.percent !== null && contextUsage?.percent !== undefined;
|
|
157
|
-
|
|
158
|
-
const statsParts: string[] = [];
|
|
159
|
-
if (totals.input) statsParts.push(`↑${formatCount(totals.input)}`);
|
|
160
|
-
if (totals.output) statsParts.push(`↓${formatCount(totals.output)}`);
|
|
161
|
-
if (totals.cacheRead) statsParts.push(`R${formatCount(totals.cacheRead)}`);
|
|
162
|
-
if (totals.cacheWrite) statsParts.push(`W${formatCount(totals.cacheWrite)}`);
|
|
163
|
-
|
|
164
|
-
const usingSubscription = !!(model && this.ctx.modelRegistry?.isUsingOAuth?.(this.ctx.model as never));
|
|
165
|
-
if (totals.cost || usingSubscription) {
|
|
166
|
-
statsParts.push(`$${totals.cost.toFixed(3)}${usingSubscription ? " (sub)" : ""}`);
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
// User choice: always show the "(auto)" compaction indicator (pi's default);
|
|
170
|
-
// the toggle state is not observable by extensions.
|
|
171
|
-
const autoIndicator = " (auto)";
|
|
172
|
-
const contextDisplay = percentKnown
|
|
173
|
-
? `${percentValue.toFixed(1)}%/${formatCount(contextWindow)}${autoIndicator}`
|
|
174
|
-
: `?/${formatCount(contextWindow)}${autoIndicator}`;
|
|
175
|
-
const contextColored =
|
|
176
|
-
percentValue > 90
|
|
177
|
-
? theme.fg("error", contextDisplay)
|
|
178
|
-
: percentValue > 70
|
|
179
|
-
? theme.fg("warning", contextDisplay)
|
|
180
|
-
: contextDisplay;
|
|
181
|
-
statsParts.push(contextColored);
|
|
182
|
-
|
|
183
|
-
let statsLeft = statsParts.join(" ");
|
|
184
|
-
let statsLeftWidth = visibleWidth(statsLeft);
|
|
185
|
-
if (statsLeftWidth > width) {
|
|
186
|
-
statsLeft = truncateToWidth(statsLeft, width, "...");
|
|
187
|
-
statsLeftWidth = visibleWidth(statsLeft);
|
|
188
|
-
}
|
|
189
|
-
|
|
190
|
-
const minPadding = 2;
|
|
191
|
-
const modelName = model?.id || "no-model";
|
|
192
|
-
let rightSideWithoutProvider = modelName;
|
|
193
|
-
if (model?.reasoning) {
|
|
194
|
-
// Prefer the authoritative thinking level from session state
|
|
195
|
-
// (buildSessionContext), which reflects the current effective level
|
|
196
|
-
// including the model default — not just the last thinking_level_select
|
|
197
|
-
// event (which only fires on manual switch).
|
|
198
|
-
let level = this.source.getThinkingLevel();
|
|
199
|
-
try {
|
|
200
|
-
const ctx = this.ctx.sessionManager as { buildSessionContext?: () => { thinkingLevel?: string } };
|
|
201
|
-
if (typeof ctx.buildSessionContext === "function") {
|
|
202
|
-
const resolved = ctx.buildSessionContext()?.thinkingLevel;
|
|
203
|
-
if (resolved) level = resolved;
|
|
204
|
-
}
|
|
205
|
-
} catch {
|
|
206
|
-
// buildSessionContext may throw on empty/early sessions — fall back.
|
|
207
|
-
}
|
|
208
|
-
const finalLevel = level || "off";
|
|
209
|
-
rightSideWithoutProvider = finalLevel === "off" ? `${modelName} • thinking off` : `${modelName} • ${finalLevel}`;
|
|
210
|
-
}
|
|
211
|
-
|
|
212
|
-
let rightSide = rightSideWithoutProvider;
|
|
213
|
-
const providerCount = this.footerData?.getAvailableProviderCount() ?? 0;
|
|
214
|
-
if (providerCount > 1 && model?.provider) {
|
|
215
|
-
rightSide = `(${model.provider}) ${rightSideWithoutProvider}`;
|
|
216
|
-
if (statsLeftWidth + minPadding + visibleWidth(rightSide) > width) rightSide = rightSideWithoutProvider;
|
|
217
|
-
}
|
|
218
|
-
|
|
219
|
-
const rightSideWidth = visibleWidth(rightSide);
|
|
220
|
-
let statsLine: string;
|
|
221
|
-
if (statsLeftWidth + minPadding + rightSideWidth <= width) {
|
|
222
|
-
statsLine = statsLeft + " ".repeat(width - statsLeftWidth - rightSideWidth) + rightSide;
|
|
223
|
-
} else {
|
|
224
|
-
const availableForRight = width - statsLeftWidth - minPadding;
|
|
225
|
-
if (availableForRight > 0) {
|
|
226
|
-
const truncatedRight = truncateToWidth(rightSide, availableForRight, "");
|
|
227
|
-
const padding = " ".repeat(Math.max(0, width - statsLeftWidth - visibleWidth(truncatedRight)));
|
|
228
|
-
statsLine = statsLeft + padding + truncatedRight;
|
|
229
|
-
} else {
|
|
230
|
-
statsLine = statsLeft;
|
|
231
|
-
}
|
|
232
|
-
}
|
|
233
|
-
|
|
234
|
-
const dimStatsLeft = theme.fg("dim", statsLeft);
|
|
235
|
-
const dimRemainder = theme.fg("dim", statsLine.slice(statsLeft.length));
|
|
236
|
-
return dimStatsLeft + dimRemainder;
|
|
237
|
-
}
|
|
238
|
-
|
|
239
|
-
private buildStatusLine(width: number): string | undefined {
|
|
240
|
-
if (!this.footerData) return undefined;
|
|
241
|
-
const statuses = this.footerData.getExtensionStatuses();
|
|
242
|
-
if (statuses.size === 0) return undefined;
|
|
243
|
-
const joined = Array.from(statuses.entries())
|
|
244
|
-
.sort(([a], [b]) => a.localeCompare(b))
|
|
245
|
-
.map(([, text]) => sanitizeStatusText(text))
|
|
246
|
-
.join(" ");
|
|
247
|
-
if (!joined) return undefined;
|
|
248
|
-
return truncateToWidth(joined, width, this.theme.fg("dim", "..."));
|
|
249
|
-
}
|
|
250
|
-
|
|
251
|
-
private rightAlign(text: string, width: number): string {
|
|
252
|
-
const w = visibleWidth(text);
|
|
253
|
-
if (w >= width) return truncateToWidth(text, width, "…");
|
|
254
|
-
return " ".repeat(width - w) + text;
|
|
255
|
-
}
|
|
256
|
-
|
|
257
|
-
/** Capacity + provider quota. Uses the REAL render width, so the quota is
|
|
258
|
-
* never chopped. When both do not fit on one line, wrap to two lines
|
|
259
|
-
* (capacity above, quota right-aligned below) per the chosen behavior. */
|
|
260
|
-
private buildMeterLines(width: number): string[] {
|
|
261
|
-
const config = this.source.getConfig();
|
|
262
|
-
if (!config.enabled) return [];
|
|
263
|
-
const capText = config.capacity.enabled ? renderCapacity(this.theme, config.capacity, getCapacityUsage(this.ctx)) : undefined;
|
|
264
|
-
const quotaText = config.capacity.providerUsage ? renderProviderUsage(this.theme, this.source.getQuotaUsage()) : undefined;
|
|
265
|
-
|
|
266
|
-
if (!capText && !quotaText) return [];
|
|
267
|
-
if (capText && !quotaText) return [truncateToWidth(capText, width, "…")];
|
|
268
|
-
if (!capText && quotaText) return [this.rightAlign(quotaText, width)];
|
|
269
|
-
|
|
270
|
-
const cap = capText as string;
|
|
271
|
-
const quota = quotaText as string;
|
|
272
|
-
const capWidth = visibleWidth(cap);
|
|
273
|
-
const quotaWidth = visibleWidth(quota);
|
|
274
|
-
if (capWidth + 1 + quotaWidth <= width) {
|
|
275
|
-
const pad = Math.max(1, width - capWidth - quotaWidth);
|
|
276
|
-
return [cap + " ".repeat(pad) + quota];
|
|
277
|
-
}
|
|
278
|
-
return [truncateToWidth(cap, width, "…"), this.rightAlign(quota, width)];
|
|
279
|
-
}
|
|
280
|
-
|
|
281
|
-
render(width: number): string[] {
|
|
282
|
-
const lines = [this.buildPwdLine(width), this.buildStatsLine(width)];
|
|
283
|
-
const statusLine = this.buildStatusLine(width);
|
|
284
|
-
if (statusLine) lines.push(statusLine);
|
|
285
|
-
lines.push(...this.buildMeterLines(width));
|
|
286
|
-
return lines;
|
|
287
|
-
}
|
|
288
|
-
}
|
|
289
|
-
|
|
290
|
-
export function createCrewVibesFooter(deps: CrewVibesFooterDeps): FooterComponent {
|
|
291
|
-
return new CrewVibesFooter(deps);
|
|
292
|
-
}
|