myshell-tools 2.15.0 → 3.2.0

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.
Files changed (57) hide show
  1. package/CHANGELOG.md +83 -1
  2. package/README.md +39 -44
  3. package/dist/cli.js +33 -22
  4. package/dist/cli.js.map +1 -1
  5. package/dist/commands/cost.js +44 -21
  6. package/dist/commands/cost.js.map +1 -1
  7. package/dist/commands/doctor.d.ts +17 -4
  8. package/dist/commands/doctor.js +62 -35
  9. package/dist/commands/doctor.js.map +1 -1
  10. package/dist/commands/login.d.ts +18 -10
  11. package/dist/commands/login.js +81 -109
  12. package/dist/commands/login.js.map +1 -1
  13. package/dist/core/json-envelope.js +31 -3
  14. package/dist/core/json-envelope.js.map +1 -1
  15. package/dist/core/native-session.d.ts +57 -0
  16. package/dist/core/native-session.js +68 -0
  17. package/dist/core/native-session.js.map +1 -0
  18. package/dist/core/orchestrate.js +106 -43
  19. package/dist/core/orchestrate.js.map +1 -1
  20. package/dist/core/types.d.ts +26 -0
  21. package/dist/infra/atomic.d.ts +9 -1
  22. package/dist/infra/atomic.js +12 -2
  23. package/dist/infra/atomic.js.map +1 -1
  24. package/dist/infra/config.d.ts +8 -0
  25. package/dist/infra/config.js.map +1 -1
  26. package/dist/infra/credentials.d.ts +69 -3
  27. package/dist/infra/credentials.js +118 -9
  28. package/dist/infra/credentials.js.map +1 -1
  29. package/dist/infra/health.d.ts +57 -0
  30. package/dist/infra/health.js +96 -0
  31. package/dist/infra/health.js.map +1 -0
  32. package/dist/infra/insights.d.ts +14 -0
  33. package/dist/infra/insights.js +31 -0
  34. package/dist/infra/insights.js.map +1 -1
  35. package/dist/interface/menu.d.ts +70 -5
  36. package/dist/interface/menu.js +292 -88
  37. package/dist/interface/menu.js.map +1 -1
  38. package/dist/interface/render.js +20 -13
  39. package/dist/interface/render.js.map +1 -1
  40. package/dist/providers/claude.d.ts +24 -8
  41. package/dist/providers/claude.js +77 -15
  42. package/dist/providers/claude.js.map +1 -1
  43. package/dist/providers/codex-parse.js +14 -2
  44. package/dist/providers/codex-parse.js.map +1 -1
  45. package/dist/providers/codex.d.ts +13 -1
  46. package/dist/providers/codex.js +19 -8
  47. package/dist/providers/codex.js.map +1 -1
  48. package/dist/providers/detect.js +22 -1
  49. package/dist/providers/detect.js.map +1 -1
  50. package/dist/providers/port.d.ts +15 -0
  51. package/dist/providers/registry.d.ts +8 -4
  52. package/dist/providers/registry.js +7 -6
  53. package/dist/providers/registry.js.map +1 -1
  54. package/dist/ui/help.d.ts +17 -0
  55. package/dist/ui/help.js +106 -0
  56. package/dist/ui/help.js.map +1 -0
  57. package/package.json +1 -1
package/CHANGELOG.md CHANGED
@@ -9,7 +9,89 @@ and the project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.
9
9
  ### Pending
10
10
  - Live cross-vendor review demonstration (requires an authenticated Codex CLI).
11
11
  - Cross-OS CI execution (requires a public remote).
12
- - First npm publish.
12
+
13
+ ## [3.2.0]
14
+
15
+ ### Changed
16
+ - **Tokens, not dollars, on the everyday UI.** myshell-tools drives your *subscription* CLIs (flat fee), so per-task dollar figures were misleading — they don't map to subscription billing and read as bloat. The control-panel status line and the live per-task output now show **real, measured token counts**; the always-on money meter ("Today: $… · session so far: $…") is gone. The `tier-done` and final-summary lines show tokens; the control-panel line shows tasks + tokens.
17
+ - **`cost` reframed as "usage & efficiency".** It now leads with real tokens (overall + per model) and a **billing-agnostic routing-efficiency ratio** ("routing picked cheaper-tier models — ~N× less than always-flagship"), which is honest under a subscription. The dollar estimate is demoted to a clearly-captioned section: **"Estimated cost — API-equivalent (list price), not your subscription bill"** — and both the routed and always-flagship figures use the **same basis** (list price × tokens), so they're apples-to-apples and internally consistent (routed never exceeds flagship). The previous mix of a provider-reported total against a list-price counterfactual could read as a contradiction; that's resolved. New pure `formatTokens` helper; `SpendSummary` gained `todayTokens`/`totalTokens`; the `tier-done` event carries real `inputTokens`/`outputTokens`.
18
+
19
+ ### Added
20
+ - **Version status in the header** — the control-panel title now always tells you where you stand: `myshell-tools v3.2.0 (latest)` when current, or `myshell-tools v3.2.0 → 3.3.0 available` when a newer release exists. No more guessing whether you're up to date. (`versionStatusLabel`, pure + tested.)
21
+ - **npx-awareness** — when run via `npx myshell-tools`, the tool now detects it (`isRunningUnderNpx`) and is honest about updates: instead of silently running a global install that the next `npx` invocation would ignore (npx re-serves its own cache), it shows `Install globally to stay current: npm install -g myshell-tools@latest`. Silent auto-update and the `[u]` key are suppressed under npx because they cannot persist there.
22
+
23
+ ### Changed
24
+ - The update banner and `[u]` Update-now action appear **only when a newer version is genuinely available** (unchanged), and are now also gated on the update being able to persist (not under npx).
25
+
26
+ ### Performance
27
+ - **Control-panel menu no longer re-parses the ledger on every keystroke.** The spend summary is computed once and cached, and only refreshed after a task actually runs (the only time the ledger changes). Previously each keypress re-read and re-parsed the unbounded `ledger.jsonl`; on an active ledger that was tens-to-hundreds of ms of avoidable latency per keystroke. The menu hot path is now O(1) in ledger size.
28
+
29
+ ### Added (experimental, opt-in)
30
+ - **Native session continuity for Claude and Codex (`nativeSessions`, default OFF).** The default path replays a compacted history block into every turn's prompt so stateless `-p`/`exec` calls have context — correct and provider-portable, but it re-sends prior context each turn. When enabled, a conversation that stays on one provider reuses that provider's *native* session and the replayed history is skipped — better context fidelity and less re-sent context (matters most for subscription rate-limit headroom; it isn't a dollar saving on a flat plan). Two id models, handled transparently:
31
+ - **Claude** — we choose the id (the conversation id): `--session-id` to establish, `--resume` to continue.
32
+ - **Codex** — Codex generates its own thread id; myshell-tools captures it from the `thread.started` event, persists it on the turn in the conversation log, and resumes via `codex exec resume <thread-id>` on the next Codex turn.
33
+
34
+ If a turn routes to a provider with no active native session, it transparently falls back to history replay — so switching providers never loses context. Enable via Settings → `[4] Native sessions` or `"nativeSessions": true`.
35
+ - **Verification:** the planning logic, the Claude/Codex CLI-arg construction, the Codex thread-id capture (contract test against the recorded transcript), and the persist-on-the-turn behavior are all unit/contract-tested. The one thing only a live CLI can prove — that resuming actually carries context — is a **gated integration test** you run with your own authenticated CLIs: `MYSHELL_NATIVE_SESSION_E2E=1 npm run test:integration` (covers both Claude and Codex). Off until you opt in; the feature defaults off until you've confirmed it on your setup. opencode has no documented resume flag yet, so it stays on history replay.
36
+ - **Per-command help.** `myshell-tools <command> --help` now shows focused, command-specific help (e.g. `login --help` explains `--code`/`--browser` and the container flow; `cost --help` is honest about subscription-vs-API billing) instead of the generic command list. Bare `--help` still shows the global list. Pure `commandHelpText`, unit-tested.
37
+ - **Self-health, surfaced automatically — no command to run.** The control panel now evaluates its own environment at startup (Node version, state-directory writability, pricing-table staleness) and shows a short, actionable warning **only when something is actually wrong**. No problems → nothing shown. Pure `evaluateHealth` (fully unit-tested) + a one-shot `probeStateWritable`. The diagnostics that were already visible in the header (provider install/auth, Claude-token expiry) are not duplicated.
38
+ - **`doctor --fix` offers to refresh an expiring Claude token.** When Claude is signed in and the stored `sk-ant-oat…` token is expired or inside the 14-day warning window, the fix pass offers a one-keypress re-login — closing the gap where the expiry was *reported* but never *actionable*.
39
+
40
+ ### Changed
41
+ - **Retired the `doctor` name from the user-facing surface.** "Doctor" was borrowed jargon, and *requiring* a diagnostic command is itself friction — health now surfaces on its own (see above). The command still exists as a hidden, scriptable health check for support/CI, reachable as `status`, `check`, or `doctor` (the old name still works for muscle-memory and existing scripts); it's just no longer advertised in `--help`. Its report header now reads "environment health" rather than "doctor".
42
+
43
+ ### Why
44
+ - Users running the convenience `npx` path were landing on a stale cached version (e.g. 2.8.0) and could not understand why "auto-update" never advanced them — npx ignores the global install our updater performs. The tool now names that situation and points to the durable fix instead of failing silently.
45
+
46
+ ## [3.1.0]
47
+
48
+ ### Added
49
+ - **Claude token lifetime awareness** — `claude setup-token` mints an `sk-ant-oat…` token valid ~1 year; the tool now records when it was captured and surfaces the remaining lifetime. `doctor` shows `token: expires ~YYYY-MM-DD (NNN days left)`, and the control-panel header shows a concise warning only when the token is near expiry or already expired (`claudeTokenStatus`, pure + tested). No nagging when the token is healthy.
50
+
51
+ ## [3.0.0]
52
+
53
+ ### Added
54
+ - **opencode contract test** — parser pinned to a recorded real `opencode run --format json` transcript.
55
+
56
+ ### Changed
57
+ - **Wizard polish** — first-run prompts are simple `(y/n)` / `(Y/n)` instead of requiring the user to type `yes`.
58
+ - **Chat feels like a chat** — the conversation prompt is a bare `> ` (not `myshell-tools>`).
59
+ - **Claude token env-scoping** — the stored OAuth token is injected only into the provider child process env (and only when not already present), never globally exported.
60
+
61
+ ### Fixed
62
+ - **Browser→code login retry** — when the browser/localhost OAuth flow can't work (containers/SSH), the login offers an interactive `--code` retry.
63
+ - **Auth-aware routing** — `route()` prefers authenticated + available providers; auth errors short-circuit (no wasted failover/escalation).
64
+
65
+ ## [2.17.0]
66
+
67
+ ### Security
68
+ - Credentials file (~/.myshell-tools/credentials.json) is now created with mode 0600 and its directory 0700 from the first write (atomicWrite gained an optional mode), closing a brief world-readable window on shared systems.
69
+
70
+ ### Fixed
71
+ - opencode now advertises a model per tier so routing never picks a model it does not have.
72
+ - run (one-shot) now respects your Settings mode (cost-saver/balanced/quality-first) instead of always using the default policy.
73
+ - Environment detection runs once per launch (was duplicated: 6 provider --version spawns, now 3).
74
+
75
+ ### Changed
76
+ - Honest labels: opencode shows ready (free models) (not signed in); doctor shows free models (no sign-in needed); the cost total is labeled provider-reported where available, otherwise estimated from list prices (Codex costs are estimates).
77
+ - README de-staled (auto-update default-on + (Y/n) + MYSHELL_NO_UPDATE documented; alpha roadmap table removed; brittle test-count claims replaced).
78
+ - Architecture guards strengthened (no-orphan logic; core purity now also forbids new Date(/node:os/node:crypto) and two weak tests made assertive.
79
+
80
+ ## [2.16.0]
81
+
82
+ ### Fixed
83
+ - **Login no longer garbles the screen**: the Claude code-method sign-in now runs claude setup-token with inherited stdio (clean native animation) and uses the robust paste prompt, instead of piping/echoing the output (which turned the spinner into a scroll of repeated banners). Honest error on non-zero exit.
84
+ - **Auth errors short-circuit**: a not-signed-in provider no longer burns failover + tier escalation (3 failed attempts) before surfacing — it stops after one attempt and the conversation offers inline re-login immediately.
85
+ - **Orchestrator edge cases**: reviewer escalate at the top tier no longer loops silently; a failover event is never shown when no attempt remains to honor it; reviewer revise notes are now applied on retries at any tier; the JSON-envelope scanner is string-aware (braces inside string values no longer break confidence/verdict parsing).
86
+ - **Ctrl+C x2 returns to menu even mid-task** (was dropped while a task was running).
87
+ - **No dead-end runs**: starting a task with no signed-in provider now prompts you to sign in instead of failing through the tiers.
88
+ - **Inline re-login retries with refreshed auth** (was reusing stale provider state).
89
+
90
+ ### Changed
91
+ - **Conversation feels like a chat**: the per-message prompt is now a plain > (not myshell-tools>), and the verbose Classified: routing line is hidden unless MYSHELL_DEBUG is set — the model's reply is the focus.
92
+
93
+ ### Security
94
+ - Credentials file is created with 0600 and its dir 0700 from the start (no world-readable race) — see 2.16.x.
13
95
 
14
96
  ## [2.15.0]
15
97
 
package/README.md CHANGED
@@ -2,9 +2,9 @@
2
2
 
3
3
  **Hierarchical, multi-provider AI orchestration for your shell — over the CLIs you already use.**
4
4
 
5
- `myshell-tools` routes each task to the *cheapest* model likely to succeed, runs it on your real codebase, optionally has a **different vendor** review the result, and shows you exactly what it did and what it truly cost — with **no fabricated data, ever**.
5
+ `myshell-tools` routes each task to the *cheapest* model likely to succeed, runs it on your real codebase, optionally has a **different vendor** review the result, and shows you exactly what it did and how many real tokens it used — with **no fabricated data, ever**.
6
6
 
7
- > **Status: `2.15.0` — honest, tested, and real.** Claude, Codex, and opencode (experimental) all work, provider auth is detected for real, and the tool notifies you when a newer version is available.
7
+ > **Status: `3.2.0` — honest, tested, and real.** Claude, Codex, and opencode (experimental) all work, provider auth is detected for real, and the header always shows whether you're on the latest version (`(latest)` or `→ x.y.z available`).
8
8
 
9
9
  ---
10
10
 
@@ -38,13 +38,14 @@ myshell-tools
38
38
 
39
39
  Using one frontier model for everything is wasteful (renaming a variable doesn't need Opus) and single‑model output has blind spots. `myshell-tools` addresses both, honestly:
40
40
 
41
- - **Cost‑aware routing** — trivial work goes to the cheap tier (Haiku / GPT‑5 mini), real implementation to the mid tier, hard calls to the flagship. You see the savings as a real number.
41
+ - **Cost‑aware routing** — trivial work goes to the cheap tier (Haiku / GPT‑5 mini), real implementation to the mid tier, hard calls to the flagship. The efficiency shows up as a billing‑agnostic ratio (how many flagship tokens you avoided), not a dollar figure — because you're on a subscription, not metered API billing.
42
42
  - **Efficiency modes** — three policy presets control the cost/quality trade-off:
43
43
  - `cost-saver` — routes to the cheapest capable model for each tier; only runs the cross-vendor review pass on *critical*-risk tasks (not every IC call). An optional `maxCostUsd` cap halts further escalation/review once spend reaches the limit.
44
44
  - `balanced` — the default; routes intelligently and reviews high-risk work.
45
45
  - `quality-first` — always reviews IC output for high/critical tasks, regardless of cost.
46
46
  - **Cross‑vendor adversarial review** — a *different vendor* checks the first model's output (Codex reviewing Claude, or vice‑versa). Different families, different blind spots. Review gating depends on mode; see Efficiency modes above.
47
47
  - **Multi-turn context continuity** — follow-up messages carry real context. Prior conversation turns are compacted into a bounded history block (~6 k chars, most recent 12 turns) and replayed to the model, so it actually knows what was said earlier. Confidence envelopes are stripped before replay to save tokens.
48
+ - **Native session continuity** *(experimental, opt-in, default off)* — when enabled, a conversation that stays on one provider reuses that provider's *native* session instead of replaying the history block, for better fidelity and less re-sent context. **Claude** uses a session id we choose (the conversation id); **Codex** has its generated thread id captured (from `thread.started`), persisted on the turn, and resumed via `codex exec resume`. Falls back to history replay automatically when a turn routes to a provider without an active session. Because the live behavior depends on your CLI, it ships off with a gated verification test covering both providers — `MYSHELL_NATIVE_SESSION_E2E=1 npm run test:integration` — and you enable it (Settings → Native sessions) only after it passes on your setup.
48
49
  - **Container / SSH sign-in** — `myshell-tools login` auto-detects headless and cloud-IDE environments (Replit, Codespaces, Gitpod, SSH sessions) and switches to a no-localhost sign-in flow automatically. Force either flow with `--code` or `--browser`. For Claude, the tool prompts you to paste the `sk-ant-oat…` OAuth token printed by `claude setup-token`, stores it locally (mode 0600), and injects it at startup — no manual env-var wiring needed. For Codex, a device-code flow is used.
49
50
  - **opencode provider (experimental)** — auto-detected; works instantly with free hosted models (no keys). `[o]` is always visible in the Auth section: it installs `opencode-ai` (with consent) if missing, then runs `opencode auth login`. Route to it explicitly or let the policy fall back to it automatically.
50
51
  - **Routing prefers advertised models** — detection passes each provider's actual model list to `route()`, which picks the cheapest model the CLI *actually has*, not just the cheapest in the pricing table. Falls back gracefully if the advertised list doesn't match any pricing entry.
@@ -75,7 +76,7 @@ You need **one** to start; install **both** claude and codex to unlock cross‑v
75
76
 
76
77
  ### `npx` vs. `npm install -g` — which to choose?
77
78
 
78
- `npx myshell-tools` is convenient for a one-off run but **caches the downloaded version** — subsequent invocations reuse the cache and **will not pick up new releases** automatically.
79
+ `npx myshell-tools` is convenient for a one-off run but **caches the downloaded version** — subsequent invocations reuse the cache and **will not pick up new releases** automatically. The tool detects when it's running under npx and, if a newer version exists, tells you exactly that instead of pretending to self-update (a global install run from an npx process is ignored by the next `npx` invocation). If you're stuck on an old version via npx, clear the cache (`rm -rf ~/.npm/_npx`) or — better — install globally:
79
80
 
80
81
  For day-to-day use, a global install is recommended:
81
82
 
@@ -92,11 +93,13 @@ The globally-installed CLI includes the **update notifier**: it checks the npm r
92
93
 
93
94
  Press `u` to install the update in-place (`npm install -g myshell-tools@latest`). No relaunch is forced — restart the CLI when you're ready.
94
95
 
95
- You can also enable **auto-update** so the CLI updates and relaunches itself silently at startup:
96
+ You can also enable **auto-update** so the CLI updates and relaunches itself silently at startup. Auto-update is **on by default** — the first-run prompt asks `Keep myshell-tools up to date automatically? (Y/n)` and defaults to yes.
96
97
 
97
- - During first-run setup: answer `y` to the `Keep myshell-tools up to date automatically? (y/N)` prompt.
98
- - In the control panel: `[s] Settings [3] Auto-update: off on`.
99
- - Or set `"autoUpdate": true` in `~/.myshell-tools/config.json`.
98
+ To opt out:
99
+ - During first-run setup: answer `n` to the `Keep myshell-tools up to date automatically? (Y/n)` prompt.
100
+ - In the control panel: `[s] Settings → [3] Auto-update: on → off`.
101
+ - Or set `"autoUpdate": false` in `~/.myshell-tools/config.json`.
102
+ - Or set `MYSHELL_NO_UPDATE=1` in your environment to disable auto-update permanently without changing config.
100
103
 
101
104
  To update manually at any time:
102
105
 
@@ -128,7 +131,6 @@ Commands:
128
131
  run <task...> Run a one-shot task and exit
129
132
  repl Plain line REPL (no menu)
130
133
  login [prov] Sign in to a provider (claude or codex) via its own OAuth
131
- doctor Check providers, auth, environment
132
134
  cost Show real spend + the cost-routing counterfactual
133
135
 
134
136
  Options:
@@ -142,19 +144,26 @@ These are **actual, unedited** outputs (your costs/timings will differ):
142
144
 
143
145
  ```text
144
146
  $ myshell-tools run "what is 2 plus 2"
145
- Classified: worker tier, low risk — tier: worker keyword 'what is'; risk: defaulting to low
146
147
  ▶ WORKER (claude/claude-haiku-4-5) attempt 1
147
148
  2 plus 2 equals 4.
148
- ✓ tier done — confidence: 100%, cost: $0.0124, duration: 5648ms
149
- Success — tier: worker, cost: $0.0124, attempts: 1, session: 0dbfe2e3-…
149
+ ✓ tier done — confidence: 100%, 312 tokens, duration: 5648ms
150
+ Success — tier: worker, 312 tokens, attempts: 1, session: 0dbfe2e3-…
150
151
  ```
151
152
 
152
- The confidence (`100%`) is **parsed from the model's own structured reply**, not invented. The cost is the **CLI's own reported figure**, not an estimate.
153
+ The confidence (`100%`) is **parsed from the model's own structured reply**, not invented. The token count is the **CLI's own reported usage** — real and measured. Because myshell-tools drives your *subscription* CLIs (not metered API keys), the hot path shows tokens, not dollars; a per-task dollar figure wouldn't map to flat subscription billing. If you want a rough API-equivalent cost estimate, it lives in `myshell-tools cost`.
153
154
 
154
- ### Health check
155
+ ### Health — automatic, no command needed
156
+
157
+ The control panel checks its own environment on every launch (Node version, whether the state directory is writable, pricing freshness) and shows a short, actionable warning **only when something is actually wrong**. When everything is fine, it stays quiet — you never run a "doctor" command.
158
+
159
+ If you want the full report explicitly (handy for support threads or CI), it's still there as a hidden, scriptable command — `status`, `check`, or `doctor`:
155
160
 
156
161
  ```text
157
- $ myshell-tools doctor
162
+ $ myshell-tools status
163
+ myshell-tools — environment health
164
+ Platform: linux
165
+ Node: v22.19.0
166
+ ...
158
167
  Providers
159
168
  ✓ claude — installed, version: 2.1.157 (Claude Code)
160
169
  auth: signed in (pro)
@@ -163,21 +172,25 @@ Providers
163
172
  Ready — at least one provider is available.
164
173
  ```
165
174
 
166
- ### Cost & the routing counterfactual
175
+ ### Usage & efficiency (`cost`)
176
+
177
+ This is a *subscription* tool, so the everyday UI shows **real, measured tokens** — never per-task dollars, which wouldn't map to flat subscription billing. The on-demand `cost` view leads with tokens and a **billing-agnostic routing-efficiency ratio**, then offers a clearly-captioned API-equivalent dollar estimate for anyone who wants the magnitude:
167
178
 
168
179
  ```text
169
180
  $ myshell-tools cost
170
- Billed total: $0.0125 (as billed, incl. caching/discounts)
171
- Total calls: 1
172
- Per-model breakdown
173
- claude-haiku-4-5: 1 call, $0.0125
174
- Counterfactual list price, token-for-token
175
- Routed (models used): $0.0010
176
- Always-flagship: $0.0063
177
- Routing saved you money: always-flagship would cost 6.3x more
181
+ myshell-tools usage & efficiency
182
+ Tasks run: 3
183
+ Tokens used: 12.4k (real, measured)
184
+ Per-model usage
185
+ claude-haiku-4-5: 2 tasks, 4.1k tokens
186
+ claude-sonnet-4-6: 1 task, 8.3k tokens
187
+ Routing efficiency
188
+ Routing picked cheaper-tier models where it could — ~6. less than sending every task to the flagship (claude-opus-4-7).
189
+ Estimated cost — API-equivalent (list price), not your subscription bill
190
+ Routed: ~$0.0020 · always-flagship: ~$0.0126
178
191
  ```
179
192
 
180
- The counterfactual is **apples‑to‑apples** (both routed and flagship priced the same way), and the *billed* total is shown separately and labeled no mixing of cache‑adjusted and list prices.
193
+ The **efficiency ratio is honest under a subscription** (it compares flagship tokens you avoided, not dollars you were charged). The dollar figures are explicitly labeled an *API-equivalent estimate* not your actual bill — and both use the **same basis** (list price × tokens), so "routed vs always-flagship" is apples-to-apples and internally consistent.
181
194
 
182
195
  ---
183
196
 
@@ -204,7 +217,7 @@ classify ─▶ route(cheapest tier) ─▶ run ─▶ assess
204
217
  This is a ground‑up rebuild whose first principle is: **the tool never shows fabricated, mocked, or randomized data as if it were real.** It's enforced, not promised:
205
218
 
206
219
  - **Architecture guard tests** fail the build if the UI/command layers contain hardcoded "AI responses", fake metrics, or a digit‑then‑`%` literal; if the orchestration core touches the filesystem, clock, or RNG directly; or if any module other than the entry point can terminate the process.
207
- - **1000+ unit/architecture tests + 42 contract tests** (parsers pinned to *recorded real transcripts*), with `tsc --strict`, ESLint, and a clean `npm pack` checked in CI across Windows / macOS / Linux.
220
+ - **An extensive unit + architecture-guard suite** (plus contract tests with parsers pinned to *recorded real transcripts*), with `tsc --strict`, ESLint, and a clean `npm pack` checked in CI across Windows / macOS / Linux.
208
221
 
209
222
  ---
210
223
 
@@ -239,24 +252,6 @@ npm run build # tsc → dist/
239
252
 
240
253
  ---
241
254
 
242
- ## Status & roadmap
243
-
244
- Honest snapshot of `2.0.0-alpha.0`:
245
-
246
- | Area | State |
247
- | --- | --- |
248
- | Core routing + escalation + cross‑vendor review loop | ✅ implemented & unit‑proven |
249
- | Claude adapter | ✅ live, validated end‑to‑end on real models |
250
- | Codex adapter | ✅ built; auto‑activates once `codex` is installed + authed |
251
- | opencode adapter (experimental) | ✅ auto-detected; free models work without keys |
252
- | Routing prefers advertised models (never routes to unavailable model) | ✅ |
253
- | `doctor` / `cost` / REPL / streaming UI | ✅ |
254
- | Live cross‑vendor demonstration | ⏳ pending Codex auth |
255
- | Cross‑OS CI run | ⏳ pending a public remote |
256
- | npm publish | ⏳ alpha |
257
-
258
- ---
259
-
260
255
  ## License
261
256
 
262
257
  MIT — see [LICENSE](LICENSE).
package/dist/cli.js CHANGED
@@ -10,7 +10,7 @@ import { execa } from 'execa';
10
10
  import { systemClock } from './infra/clock.js';
11
11
  import { createSessionWriter } from './infra/session.js';
12
12
  import { createLedger } from './infra/ledger.js';
13
- import { DEFAULT_POLICY } from './core/policy.js';
13
+ import { DEFAULT_POLICY, POLICY_PRESETS } from './core/policy.js';
14
14
  import { runTask } from './interface/run.js';
15
15
  import { startRepl } from './interface/repl.js';
16
16
  import { startMenu } from './interface/menu.js';
@@ -19,14 +19,16 @@ import { detectEnvironment } from './providers/detect.js';
19
19
  import { createFileConversationStore } from './infra/conversations.js';
20
20
  import { loadConfig } from './infra/config.js';
21
21
  import { checkForUpdate } from './infra/update-check.js';
22
+ import { evaluateHealth, probeStateWritable } from './infra/health.js';
23
+ import { isPricingStale } from './infra/pricing.js';
22
24
  import { runDoctor } from './commands/doctor.js';
23
25
  import { runCost } from './commands/cost.js';
24
26
  import { runLogin } from './commands/login.js';
25
27
  import { runInstall } from './commands/install.js';
26
28
  import { banner } from './ui/banner.js';
29
+ import { commandHelpText } from './ui/help.js';
27
30
  import { createSpinner } from './ui/spinner.js';
28
31
  import { dim } from './ui/theme.js';
29
- import { applyStoredCredentials } from './infra/credentials.js';
30
32
  const require = createRequire(import.meta.url);
31
33
  const pkg = require('../package.json');
32
34
  const version = pkg.version;
@@ -47,9 +49,6 @@ Commands:
47
49
  Add --code to use the no-localhost flow (paste a code for
48
50
  claude, device code for codex) — best inside containers /
49
51
  over SSH. Add --browser to force the localhost flow.
50
- doctor [--fix] Check provider installation, auth, and environment health.
51
- Add --fix to interactively install missing providers and
52
- sign in to unauthenticated ones.
53
52
  cost Show real spend from the ledger with a per-model breakdown
54
53
  install Write a guarded startup hook to your shell rc file so new
55
54
  interactive shells launch myshell-tools automatically
@@ -63,12 +62,9 @@ Examples:
63
62
 
64
63
  Repository: https://github.com/hey-vera/myshell-tools
65
64
  `;
66
- /** Build the orchestration dependencies (includes provider detection). */
67
- async function buildDeps(cwd) {
68
- const [providers, env] = await Promise.all([
69
- buildProviders(cwd),
70
- detectEnvironment(),
71
- ]);
65
+ /** Build the orchestration dependencies from a pre-detected EnvironmentStatus. */
66
+ function buildDeps(cwd, env, policy = DEFAULT_POLICY) {
67
+ const providers = buildProviders(cwd, env);
72
68
  // Populate advertised model lists from detection so route() can prefer a
73
69
  // model the provider CLI actually has. Only include installed providers.
74
70
  const availableModels = {};
@@ -94,7 +90,7 @@ async function buildDeps(cwd) {
94
90
  clock: systemClock,
95
91
  session: createSessionWriter({ cwd, id: systemClock.uuid() }),
96
92
  ledger: createLedger({ cwd }),
97
- policy: DEFAULT_POLICY,
93
+ policy,
98
94
  providers,
99
95
  cwd,
100
96
  sandbox: 'workspace-write',
@@ -114,13 +110,12 @@ function welcome(deps, color) {
114
110
  '(diagnose: myshell-tools doctor)', color);
115
111
  }
116
112
  async function main() {
117
- // Inject any previously-saved Claude OAuth token into process.env before any
118
- // detection or provider spawn so `claude auth status` and `claude -p …` both
119
- // see it without the user needing to export CLAUDE_CODE_OAUTH_TOKEN manually.
120
- await applyStoredCredentials(process.env);
121
113
  const args = process.argv.slice(2);
122
114
  if (args.includes('--help') || args.includes('-h')) {
123
- process.stdout.write(HELP);
115
+ // Focused per-command help (e.g. `login --help`) when the first arg is a
116
+ // known command; otherwise the global command list.
117
+ const cmdHelp = args[0] !== undefined ? commandHelpText(args[0]) : null;
118
+ process.stdout.write(cmdHelp ?? HELP);
124
119
  process.exit(0);
125
120
  }
126
121
  if (args.includes('--version') || args.includes('-v')) {
@@ -148,7 +143,11 @@ async function main() {
148
143
  const provider = rest.find((a) => !a.startsWith('-'));
149
144
  process.exit(await runLogin(out, provider, method !== undefined ? { method } : undefined));
150
145
  }
151
- if (args[0] === 'doctor') {
146
+ // Health check surfaced automatically in the control panel, so this is no
147
+ // longer an advertised command. Kept as a hidden, scriptable entry point for
148
+ // support/CI; `status` and `check` are friendlier aliases for the old
149
+ // `doctor` name (which still works for muscle-memory / existing scripts).
150
+ if (args[0] === 'doctor' || args[0] === 'status' || args[0] === 'check') {
152
151
  const fix = args.includes('--fix');
153
152
  process.exit(await runDoctor(out, fix ? { fix: true } : undefined));
154
153
  }
@@ -168,7 +167,9 @@ async function main() {
168
167
  process.stderr.write('myshell-tools run: expected a task description\n');
169
168
  process.exit(1);
170
169
  }
171
- const deps = await buildDeps(cwd);
170
+ const [env, config] = await Promise.all([detectEnvironment(), loadConfig()]);
171
+ const policy = POLICY_PRESETS[config.mode ?? 'balanced'];
172
+ const deps = buildDeps(cwd, env, policy);
172
173
  const result = await runTask(taskParts.join(' '), deps, out, new AbortController().signal);
173
174
  process.exit(result.code);
174
175
  }
@@ -176,12 +177,20 @@ async function main() {
176
177
  if (args.length === 0) {
177
178
  const spinner = createSpinner(out);
178
179
  spinner.start('Detecting providers…');
179
- const [providers, env, config] = await Promise.all([
180
- buildProviders(cwd),
180
+ const [env, config, stateWritable] = await Promise.all([
181
181
  detectEnvironment(),
182
182
  loadConfig(),
183
+ probeStateWritable(cwd),
183
184
  ]);
185
+ const providers = buildProviders(cwd, env);
184
186
  spinner.stop();
187
+ // Evaluate non-provider environment health once at startup. Surfaced in the
188
+ // menu only when a problem exists — the user never runs a health command.
189
+ const healthIssues = evaluateHealth({
190
+ nodeVersion: process.version,
191
+ stateWritable,
192
+ pricingStale: isPricingStale(),
193
+ });
185
194
  const store = createFileConversationStore({ clock: systemClock });
186
195
  const ledger = createLedger({ cwd });
187
196
  const menuCtx = {
@@ -195,6 +204,7 @@ async function main() {
195
204
  cwd,
196
205
  sandbox: 'workspace-write',
197
206
  timeoutMs: 120000,
207
+ healthIssues,
198
208
  checkForUpdate: () => checkForUpdate({ currentVersion: version, now: Date.now() }),
199
209
  updateSelf: async (updateOut) => {
200
210
  try {
@@ -230,7 +240,8 @@ async function main() {
230
240
  out.write(banner(version, out.color) + '\n');
231
241
  const spinner = createSpinner(out);
232
242
  spinner.start('Detecting providers…');
233
- const deps = await buildDeps(cwd);
243
+ const env = await detectEnvironment();
244
+ const deps = buildDeps(cwd, env);
234
245
  spinner.stop();
235
246
  out.write(welcome(deps, out.color) + '\n\n');
236
247
  await startRepl(deps, out);
package/dist/cli.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AACA;;;;;GAKG;AAEH,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,KAAK,EAAE,MAAM,OAAO,CAAC;AAC9B,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC/C,OAAO,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AACzD,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAGlD,OAAO,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAC7C,OAAO,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAChD,OAAO,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAEhD,OAAO,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AACzD,OAAO,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAC1D,OAAO,EAAE,2BAA2B,EAAE,MAAM,0BAA0B,CAAC;AACvE,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAC/C,OAAO,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AACzD,OAAO,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AACjD,OAAO,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAC7C,OAAO,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAC/C,OAAO,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AACnD,OAAO,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAC;AACxC,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,EAAE,GAAG,EAAE,MAAM,eAAe,CAAC;AACpC,OAAO,EAAE,sBAAsB,EAAE,MAAM,wBAAwB,CAAC;AAEhE,MAAM,OAAO,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAC/C,MAAM,GAAG,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAAC;AACvC,MAAM,OAAO,GAAW,GAAG,CAAC,OAAiB,CAAC;AAE9C,MAAM,IAAI,GAAG;iBACI,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA+BvB,CAAC;AAEF,0EAA0E;AAC1E,KAAK,UAAU,SAAS,CAAC,GAAW;IAClC,MAAM,CAAC,SAAS,EAAE,GAAG,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;QACzC,cAAc,CAAC,GAAG,CAAC;QACnB,iBAAiB,EAAE;KACpB,CAAC,CAAC;IAEH,yEAAyE;IACzE,yEAAyE;IACzE,MAAM,eAAe,GAAiF,EAAE,CAAC;IACzG,IAAI,GAAG,CAAC,MAAM,CAAC,SAAS,IAAI,GAAG,CAAC,MAAM,CAAC,eAAe,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAClE,eAAe,CAAC,QAAQ,CAAC,GAAG,GAAG,CAAC,MAAM,CAAC,eAAe,CAAC;IACzD,CAAC;IACD,IAAI,GAAG,CAAC,KAAK,CAAC,SAAS,IAAI,GAAG,CAAC,KAAK,CAAC,eAAe,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAChE,eAAe,CAAC,OAAO,CAAC,GAAG,GAAG,CAAC,KAAK,CAAC,eAAe,CAAC;IACvD,CAAC;IACD,IAAI,GAAG,CAAC,QAAQ,CAAC,SAAS,IAAI,GAAG,CAAC,QAAQ,CAAC,eAAe,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACtE,eAAe,CAAC,UAAU,CAAC,GAAG,GAAG,CAAC,QAAQ,CAAC,eAAe,CAAC;IAC7D,CAAC;IAED,4EAA4E;IAC5E,gFAAgF;IAChF,MAAM,sBAAsB,GAA+C,EAAE,CAAC;IAC9E,IAAI,GAAG,CAAC,MAAM,CAAC,aAAa;QAAE,sBAAsB,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IACpE,IAAI,GAAG,CAAC,KAAK,CAAC,aAAa;QAAE,sBAAsB,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IAClE,IAAI,GAAG,CAAC,QAAQ,CAAC,aAAa;QAAE,sBAAsB,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;IAExE,OAAO;QACL,KAAK,EAAE,WAAW;QAClB,OAAO,EAAE,mBAAmB,CAAC,EAAE,GAAG,EAAE,EAAE,EAAE,WAAW,CAAC,IAAI,EAAE,EAAE,CAAC;QAC7D,MAAM,EAAE,YAAY,CAAC,EAAE,GAAG,EAAE,CAAC;QAC7B,MAAM,EAAE,cAAc;QACtB,SAAS;QACT,GAAG;QACH,OAAO,EAAE,iBAAiB;QAC1B,SAAS,EAAE,MAAM;QACjB,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,eAAe,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACvE,GAAG,CAAC,sBAAsB,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,sBAAsB,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KACzE,CAAC;AACJ,CAAC;AAED,uEAAuE;AACvE,SAAS,OAAO,CAAC,IAAqB,EAAE,KAAc;IACpD,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IAC1C,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACrB,OAAO,GAAG,CACR,cAAc,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,6CAA6C;YACzE,yCAAyC,EAC3C,KAAK,CACN,CAAC;IACJ,CAAC;IACD,OAAO,GAAG,CACR,uFAAuF;QACrF,kCAAkC,EACpC,KAAK,CACN,CAAC;AACJ,CAAC;AAED,KAAK,UAAU,IAAI;IACjB,6EAA6E;IAC7E,6EAA6E;IAC7E,8EAA8E;IAC9E,MAAM,sBAAsB,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IAE1C,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IAEnC,IAAI,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;QACnD,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAC3B,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,IAAI,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;QACtD,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,OAAO,IAAI,CAAC,CAAC;QACrC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC;IAC1B,MAAM,GAAG,GAAe;QACtB,KAAK,EAAE,CAAC,CAAC,EAAE,EAAE;YACX,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;QAC1B,CAAC;QACD,KAAK,EAAE,OAAO,CAAC,MAAM,CAAC,KAAK,KAAK,IAAI,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC;QAChE,KAAK,EAAE,OAAO,CAAC,MAAM,CAAC,KAAK,KAAK,IAAI;KACrC,CAAC;IAEF,+EAA+E;IAC/E,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,OAAO,EAAE,CAAC;QACxB,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;QAC3B,4EAA4E;QAC5E,yEAAyE;QACzE,MAAM,MAAM,GACV,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC;YAClD,CAAC,CAAE,MAAgB;YACnB,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC;gBAC1B,CAAC,CAAE,SAAmB;gBACtB,CAAC,CAAC,SAAS,CAAC;QAClB,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC;QACtD,OAAO,CAAC,IAAI,CAAC,MAAM,QAAQ,CAAC,GAAG,EAAE,QAAQ,EAAE,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC;IAC7F,CAAC;IAED,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,QAAQ,EAAE,CAAC;QACzB,MAAM,GAAG,GAAG,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;QACnC,OAAO,CAAC,IAAI,CAAC,MAAM,SAAS,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC;IACtE,CAAC;IAED,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,MAAM,EAAE,CAAC;QACvB,OAAO,CAAC,IAAI,CAAC,MAAM,OAAO,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC,CAAC;IACxC,CAAC;IAED,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,SAAS,EAAE,CAAC;QAC1B,OAAO,CAAC,IAAI,CAAC,MAAM,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC;IACtC,CAAC;IAED,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,WAAW,EAAE,CAAC;QAC5B,OAAO,CAAC,IAAI,CAAC,MAAM,UAAU,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;IAC3D,CAAC;IAED,+EAA+E;IAC/E,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,KAAK,EAAE,CAAC;QACtB,MAAM,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;QAChC,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC3B,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,kDAAkD,CAAC,CAAC;YACzE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;QACD,MAAM,IAAI,GAAG,MAAM,SAAS,CAAC,GAAG,CAAC,CAAC;QAClC,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,SAAS,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,eAAe,EAAE,CAAC,MAAM,CAAC,CAAC;QAC3F,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IAC5B,CAAC;IAED,8EAA8E;IAC9E,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACtB,MAAM,OAAO,GAAG,aAAa,CAAC,GAAG,CAAC,CAAC;QACnC,OAAO,CAAC,KAAK,CAAC,sBAAsB,CAAC,CAAC;QACtC,MAAM,CAAC,SAAS,EAAE,GAAG,EAAE,MAAM,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;YACjD,cAAc,CAAC,GAAG,CAAC;YACnB,iBAAiB,EAAE;YACnB,UAAU,EAAE;SACb,CAAC,CAAC;QACH,OAAO,CAAC,IAAI,EAAE,CAAC;QAEf,MAAM,KAAK,GAAG,2BAA2B,CAAC,EAAE,KAAK,EAAE,WAAW,EAAE,CAAC,CAAC;QAClE,MAAM,MAAM,GAAG,YAAY,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC;QAErC,MAAM,OAAO,GAAgB;YAC3B,OAAO;YACP,KAAK,EAAE,WAAW;YAClB,MAAM;YACN,SAAS;YACT,GAAG;YACH,KAAK;YACL,MAAM;YACN,GAAG;YACH,OAAO,EAAE,iBAAiB;YAC1B,SAAS,EAAE,MAAM;YACjB,cAAc,EAAE,GAAG,EAAE,CAAC,cAAc,CAAC,EAAE,cAAc,EAAE,OAAO,EAAE,GAAG,EAAE,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC;YAClF,UAAU,EAAE,KAAK,EAAE,SAAS,EAAE,EAAE;gBAC9B,IAAI,CAAC;oBACH,MAAM,MAAM,GAAG,MAAM,KAAK,CAAC,KAAK,EAAE,CAAC,SAAS,EAAE,IAAI,EAAE,sBAAsB,CAAC,EAAE;wBAC3E,KAAK,EAAE,SAAS;wBAChB,MAAM,EAAE,KAAK;qBACd,CAAC,CAAC;oBACH,OAAO,MAAM,CAAC,QAAQ,KAAK,CAAC,CAAC;gBAC/B,CAAC;gBAAC,MAAM,CAAC;oBACP,SAAS,CAAC,KAAK,CAAC,4DAA4D,CAAC,CAAC;oBAC9E,OAAO,KAAK,CAAC;gBACf,CAAC;YACH,CAAC;YACD,QAAQ,EAAE,KAAK,IAAI,EAAE;gBACnB,IAAI,CAAC;oBACH,MAAM,MAAM,GAAG,MAAM,KAAK,CAAC,eAAe,EAAE,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE;wBACjE,KAAK,EAAE,SAAS;wBAChB,MAAM,EAAE,KAAK;qBACd,CAAC,CAAC;oBACH,OAAO,MAAM,CAAC,QAAQ,IAAI,CAAC,CAAC;gBAC9B,CAAC;gBAAC,MAAM,CAAC;oBACP,OAAO,CAAC,CAAC;gBACX,CAAC;YACH,CAAC;SACF,CAAC;QAEF,MAAM,SAAS,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC;QAC9B,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,+EAA+E;IAC/E,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,MAAM,EAAE,CAAC;QACvB,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,OAAO,EAAE,GAAG,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC,CAAC;QAC7C,MAAM,OAAO,GAAG,aAAa,CAAC,GAAG,CAAC,CAAC;QACnC,OAAO,CAAC,KAAK,CAAC,sBAAsB,CAAC,CAAC;QACtC,MAAM,IAAI,GAAG,MAAM,SAAS,CAAC,GAAG,CAAC,CAAC;QAClC,OAAO,CAAC,IAAI,EAAE,CAAC;QACf,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC,KAAK,CAAC,GAAG,MAAM,CAAC,CAAC;QAC7C,MAAM,SAAS,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;QAC3B,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,+EAA+E;IAC/E,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,mCAAmC,IAAI,CAAC,CAAC,CAAC,IAAI,EAAE,0CAA0C,CAC3F,CAAC;IACF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;IACnB,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,CAAC;IACzC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
@@ -19,6 +19,7 @@
19
19
  * fabricated. If the ledger is empty the command says so and returns 0.
20
20
  */
21
21
  import { readLedger, summarizeLedger } from '../infra/ledger.js';
22
+ import { formatTokens } from '../infra/insights.js';
22
23
  import { getCheapestForTier, calculateCost, getModelPricing } from '../infra/pricing.js';
23
24
  import { bold, dim, cyan, divider, label } from '../ui/theme.js';
24
25
  // ---------------------------------------------------------------------------
@@ -32,7 +33,7 @@ import { bold, dim, cyan, divider, label } from '../ui/theme.js';
32
33
  */
33
34
  export function formatCostReport(entries, color = false) {
34
35
  if (entries.length === 0) {
35
- return ['No usage recorded yet run a task first.'];
36
+ return ['No usage recorded yet. Run a task first, e.g. myshell-tools run "summarize this repo"'];
36
37
  }
37
38
  const summary = summarizeLedger(entries);
38
39
  // Counterfactual uses the flagship from paid providers only (claude/codex).
@@ -42,9 +43,15 @@ export function formatCostReport(entries, color = false) {
42
43
  // Apples-to-apples: price BOTH the models actually used AND the flagship on the
43
44
  // SAME basis (list price × tokens). We do NOT compare the billed total (which
44
45
  // includes caching/discounts) against a list-price flagship estimate.
46
+ // Also accumulate REAL token totals (overall + per model) — the honest signal.
45
47
  let routedListUsd = 0;
46
48
  let flagshipListUsd = 0;
49
+ let totalTokens = 0;
50
+ const tokensByModel = {};
47
51
  for (const entry of entries) {
52
+ const entryTokens = entry.inputTokens + entry.outputTokens;
53
+ totalTokens += entryTokens;
54
+ tokensByModel[entry.model] = (tokensByModel[entry.model] ?? 0) + entryTokens;
48
55
  const entryPricing = getModelPricing(entry.provider, entry.model);
49
56
  if (entryPricing) {
50
57
  routedListUsd += calculateCost(entry.inputTokens, entry.outputTokens, entryPricing);
@@ -52,37 +59,53 @@ export function formatCostReport(entries, color = false) {
52
59
  flagshipListUsd += calculateCost(entry.inputTokens, entry.outputTokens, flagship);
53
60
  }
54
61
  const lines = [];
55
- lines.push(bold('myshell-tools cost', color));
62
+ lines.push(bold('myshell-tools — usage & efficiency', color));
56
63
  lines.push(divider(color));
57
- // ---- Summary ---------------------------------------------------------------
58
- lines.push(`${label('Billed total', color)}: $${summary.totalUsd.toFixed(4)} ` +
59
- `${dim('(as billed, incl. caching/discounts)', color)}`);
60
- lines.push(`${label('Total calls', color)}: ${summary.calls}`);
64
+ // ---- Usage (REAL, measured) -----------------------------------------------
65
+ // Tokens are measured, not estimated the trustworthy primary figure.
66
+ lines.push(`${label('Tasks run', color)}: ${summary.calls}`);
67
+ lines.push(`${label('Tokens used', color)}: ${formatTokens(totalTokens)} ${dim('(real, measured)', color)}`);
61
68
  lines.push(divider(color));
62
- // ---- Per-model breakdown ---------------------------------------------------
63
- lines.push(bold('Per-model breakdown', color));
69
+ lines.push(bold('Per-model usage', color));
64
70
  for (const [model, ms] of Object.entries(summary.byModel)) {
65
- const callStr = ms.calls === 1 ? '1 call' : `${ms.calls} calls`;
66
- lines.push(` ${cyan(model, color)}: ${callStr}, $${ms.usd.toFixed(4)}`);
71
+ const callStr = ms.calls === 1 ? '1 task' : `${ms.calls} tasks`;
72
+ lines.push(` ${cyan(model, color)}: ${callStr}, ${formatTokens(tokensByModel[model] ?? 0)} tokens`);
67
73
  }
68
74
  lines.push(divider(color));
69
- // ---- Counterfactual (list-price, token-for-token, apples-to-apples) --------
70
- const flagshipLabel = `${flagship.model} (${flagship.tier} tier)`;
71
- lines.push(bold('Counterfactual list price, token-for-token', color));
72
- lines.push(`${dim('Flagship model', color)}: ${flagshipLabel}` +
73
- ` ${dim(`($${flagship.inputPer1M}/M in, $${flagship.outputPer1M}/M out)`, color)}`);
74
- lines.push(`${label('Routed (models used)', color)}: $${routedListUsd.toFixed(4)}`);
75
- lines.push(`${label('Always-flagship', color)}: $${flagshipListUsd.toFixed(4)}`);
75
+ // ---- Routing efficiency (billing-agnostic ratio) --------------------------
76
+ // The savings RATIO is honest regardless of billing model: it compares how
77
+ // many flagship tokens you avoided by routing to cheaper tiers. This is the
78
+ // value-prop number, and it holds true on a subscription too.
79
+ lines.push(bold('Routing efficiency', color));
76
80
  if (routedListUsd > 0 && flagshipListUsd > routedListUsd) {
77
81
  const multiplier = flagshipListUsd / routedListUsd;
78
- lines.push(`Routing saved you money: always-flagship would cost ${multiplier.toFixed(1)}x more ` +
79
- `($${flagshipListUsd.toFixed(4)} vs $${routedListUsd.toFixed(4)} at list price).`);
82
+ lines.push(`Routing picked cheaper-tier models where it could ` +
83
+ `${cyan(`~${multiplier.toFixed(1)}× less`, color)} than sending every task to ` +
84
+ `the flagship (${flagship.model}).`);
80
85
  }
81
86
  else if (routedListUsd > 0) {
82
- lines.push('Every call already used a flagship-tier (or pricier) model — no routing savings to show.');
87
+ lines.push(dim('Every task already used a flagship-tier (or pricier) model — no routing savings to show.', color));
83
88
  }
84
89
  else {
85
- lines.push(dim('No priced models in the ledger — cannot compute a list-price comparison.', color));
90
+ lines.push(dim('No priced models in the ledger — cannot compute a routing comparison.', color));
91
+ }
92
+ // ---- Estimated cost (API-equivalent, NOT your subscription bill) ----------
93
+ // myshell-tools drives your SUBSCRIPTION CLIs — you pay a flat fee, not per
94
+ // token. This is a rough "if this were metered API usage" estimate, shown for
95
+ // devs who want the magnitude; it is not what you are billed. Both figures use
96
+ // the SAME basis (list price × tokens) so "routed vs always-flagship" is
97
+ // apples-to-apples and internally consistent (routed never exceeds flagship).
98
+ lines.push(divider(color));
99
+ lines.push(bold('Estimated cost', color) + dim(' — API-equivalent (list price), not your subscription bill', color));
100
+ if (routedListUsd > 0) {
101
+ let line = `${label('Routed', color)}: ~$${routedListUsd.toFixed(4)}`;
102
+ if (flagshipListUsd > routedListUsd) {
103
+ line += ` · ${dim(`always-flagship: ~$${flagshipListUsd.toFixed(4)}`, color)}`;
104
+ }
105
+ lines.push(line);
106
+ }
107
+ else {
108
+ lines.push(dim('No priced models in the ledger — no estimate available.', color));
86
109
  }
87
110
  return lines;
88
111
  }
@@ -1 +1 @@
1
- {"version":3,"file":"cost.js","sourceRoot":"","sources":["../../src/commands/cost.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"cost.js","sourceRoot":"","sources":["../../src/commands/cost.ts"],"names":[],"mappings":"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"}