reasonix 0.32.0 → 0.33.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 (118) hide show
  1. package/dist/cli/chat-EIFLHBZ6.js +39 -0
  2. package/dist/cli/chunk-2AWTGJ2C.js +110 -0
  3. package/dist/cli/chunk-2AWTGJ2C.js.map +1 -0
  4. package/dist/cli/chunk-3Q3C4W66.js +30 -0
  5. package/dist/cli/chunk-3Q3C4W66.js.map +1 -0
  6. package/dist/cli/chunk-4DCHFFEY.js +149 -0
  7. package/dist/cli/chunk-4DCHFFEY.js.map +1 -0
  8. package/dist/cli/chunk-5X7LZJDE.js +36 -0
  9. package/dist/cli/chunk-5X7LZJDE.js.map +1 -0
  10. package/dist/cli/chunk-6TMHAK5D.js +576 -0
  11. package/dist/cli/chunk-6TMHAK5D.js.map +1 -0
  12. package/dist/cli/chunk-APPB3ZPQ.js +43 -0
  13. package/dist/cli/chunk-APPB3ZPQ.js.map +1 -0
  14. package/dist/cli/chunk-BQNUJJN7.js +42 -0
  15. package/dist/cli/chunk-BQNUJJN7.js.map +1 -0
  16. package/dist/cli/chunk-CPOV2O73.js +39 -0
  17. package/dist/cli/chunk-CPOV2O73.js.map +1 -0
  18. package/dist/cli/chunk-D5DKXIP5.js +368 -0
  19. package/dist/cli/chunk-D5DKXIP5.js.map +1 -0
  20. package/dist/cli/chunk-DFP4YSVM.js +247 -0
  21. package/dist/cli/chunk-DFP4YSVM.js.map +1 -0
  22. package/dist/cli/chunk-DULSP7JH.js +410 -0
  23. package/dist/cli/chunk-DULSP7JH.js.map +1 -0
  24. package/dist/cli/chunk-FM57FNPJ.js +46 -0
  25. package/dist/cli/chunk-FM57FNPJ.js.map +1 -0
  26. package/dist/cli/chunk-FWGEHRB7.js +54 -0
  27. package/dist/cli/chunk-FWGEHRB7.js.map +1 -0
  28. package/dist/cli/chunk-FXGQ5NHE.js +513 -0
  29. package/dist/cli/chunk-FXGQ5NHE.js.map +1 -0
  30. package/dist/cli/chunk-G3XNWSFN.js +53 -0
  31. package/dist/cli/chunk-G3XNWSFN.js.map +1 -0
  32. package/dist/cli/chunk-I6YIAK6C.js +757 -0
  33. package/dist/cli/chunk-I6YIAK6C.js.map +1 -0
  34. package/dist/cli/chunk-J5VLP23S.js +94 -0
  35. package/dist/cli/chunk-J5VLP23S.js.map +1 -0
  36. package/dist/cli/chunk-KMWKGPFZ.js +303 -0
  37. package/dist/cli/chunk-KMWKGPFZ.js.map +1 -0
  38. package/dist/cli/chunk-LVQX5KGF.js +14934 -0
  39. package/dist/cli/chunk-LVQX5KGF.js.map +1 -0
  40. package/dist/cli/chunk-MHDNZXJJ.js +48 -0
  41. package/dist/cli/chunk-MHDNZXJJ.js.map +1 -0
  42. package/dist/cli/chunk-ORM6PK57.js +140 -0
  43. package/dist/cli/chunk-ORM6PK57.js.map +1 -0
  44. package/dist/cli/chunk-Q5GRLZJF.js +99 -0
  45. package/dist/cli/chunk-Q5GRLZJF.js.map +1 -0
  46. package/dist/cli/chunk-Q6YFXW7H.js +4986 -0
  47. package/dist/cli/chunk-Q6YFXW7H.js.map +1 -0
  48. package/dist/cli/chunk-QGE6AF76.js +1467 -0
  49. package/dist/cli/chunk-QGE6AF76.js.map +1 -0
  50. package/dist/cli/chunk-RFX7TYVV.js +28 -0
  51. package/dist/cli/chunk-RFX7TYVV.js.map +1 -0
  52. package/dist/cli/chunk-RZILUXUC.js +940 -0
  53. package/dist/cli/chunk-RZILUXUC.js.map +1 -0
  54. package/dist/cli/chunk-SDE5U32Z.js +535 -0
  55. package/dist/cli/chunk-SDE5U32Z.js.map +1 -0
  56. package/dist/cli/chunk-SOZE7V7V.js +340 -0
  57. package/dist/cli/chunk-SOZE7V7V.js.map +1 -0
  58. package/dist/cli/chunk-U3V2ZQ5J.js +479 -0
  59. package/dist/cli/chunk-U3V2ZQ5J.js.map +1 -0
  60. package/dist/cli/chunk-W4LDFAZ6.js +1544 -0
  61. package/dist/cli/chunk-W4LDFAZ6.js.map +1 -0
  62. package/dist/cli/chunk-WBDE4IRI.js +208 -0
  63. package/dist/cli/chunk-WBDE4IRI.js.map +1 -0
  64. package/dist/cli/chunk-XHQIK7B6.js +189 -0
  65. package/dist/cli/chunk-XHQIK7B6.js.map +1 -0
  66. package/dist/cli/chunk-XJLZ4HKU.js +307 -0
  67. package/dist/cli/chunk-XJLZ4HKU.js.map +1 -0
  68. package/dist/cli/chunk-ZPTSJGX5.js +88 -0
  69. package/dist/cli/chunk-ZPTSJGX5.js.map +1 -0
  70. package/dist/cli/chunk-ZTLZO42A.js +231 -0
  71. package/dist/cli/chunk-ZTLZO42A.js.map +1 -0
  72. package/dist/cli/code-F4KJOE3K.js +151 -0
  73. package/dist/cli/code-F4KJOE3K.js.map +1 -0
  74. package/dist/cli/commands-JWT2MWVH.js +352 -0
  75. package/dist/cli/commands-JWT2MWVH.js.map +1 -0
  76. package/dist/cli/commit-RPZBOZS2.js +288 -0
  77. package/dist/cli/commit-RPZBOZS2.js.map +1 -0
  78. package/dist/cli/diff-NTEHCSDW.js +145 -0
  79. package/dist/cli/diff-NTEHCSDW.js.map +1 -0
  80. package/dist/cli/doctor-3TGB2NZN.js +19 -0
  81. package/dist/cli/doctor-3TGB2NZN.js.map +1 -0
  82. package/dist/cli/events-P27CX7LN.js +338 -0
  83. package/dist/cli/events-P27CX7LN.js.map +1 -0
  84. package/dist/cli/index.js +80 -33693
  85. package/dist/cli/index.js.map +1 -1
  86. package/dist/cli/mcp-ARTNQ24O.js +266 -0
  87. package/dist/cli/mcp-ARTNQ24O.js.map +1 -0
  88. package/dist/cli/mcp-browse-HLO2ENDL.js +163 -0
  89. package/dist/cli/mcp-browse-HLO2ENDL.js.map +1 -0
  90. package/dist/cli/mcp-inspect-T2HBR22P.js +103 -0
  91. package/dist/cli/mcp-inspect-T2HBR22P.js.map +1 -0
  92. package/dist/cli/{prompt-XHICFAYN.js → prompt-V47QKSAR.js} +3 -2
  93. package/dist/cli/prompt-V47QKSAR.js.map +1 -0
  94. package/dist/cli/prune-sessions-ERL6B4G5.js +42 -0
  95. package/dist/cli/prune-sessions-ERL6B4G5.js.map +1 -0
  96. package/dist/cli/replay-TMJASRC4.js +273 -0
  97. package/dist/cli/replay-TMJASRC4.js.map +1 -0
  98. package/dist/cli/run-JMEOTQCG.js +215 -0
  99. package/dist/cli/run-JMEOTQCG.js.map +1 -0
  100. package/dist/cli/server-SYC3OVOP.js +2967 -0
  101. package/dist/cli/server-SYC3OVOP.js.map +1 -0
  102. package/dist/cli/sessions-MOJAALJI.js +102 -0
  103. package/dist/cli/sessions-MOJAALJI.js.map +1 -0
  104. package/dist/cli/setup-CCJZAWTY.js +404 -0
  105. package/dist/cli/setup-CCJZAWTY.js.map +1 -0
  106. package/dist/cli/stats-5RJCATCE.js +12 -0
  107. package/dist/cli/stats-5RJCATCE.js.map +1 -0
  108. package/dist/cli/update-4TJWRUIN.js +90 -0
  109. package/dist/cli/update-4TJWRUIN.js.map +1 -0
  110. package/dist/cli/version-3MYFE4G6.js +29 -0
  111. package/dist/cli/version-3MYFE4G6.js.map +1 -0
  112. package/dist/index.d.ts +13 -2
  113. package/dist/index.js +493 -89
  114. package/dist/index.js.map +1 -1
  115. package/package.json +1 -1
  116. package/dist/cli/chunk-VWFJNLIK.js +0 -1031
  117. package/dist/cli/chunk-VWFJNLIK.js.map +0 -1
  118. /package/dist/cli/{prompt-XHICFAYN.js.map → chat-EIFLHBZ6.js.map} +0 -0
@@ -0,0 +1,48 @@
1
+ #!/usr/bin/env node
2
+
3
+ // src/cli/ui/presets.ts
4
+ var PRESETS = {
5
+ auto: {
6
+ model: "deepseek-v4-flash",
7
+ reasoningEffort: "max",
8
+ autoEscalate: true
9
+ },
10
+ flash: {
11
+ model: "deepseek-v4-flash",
12
+ reasoningEffort: "max",
13
+ autoEscalate: false
14
+ },
15
+ pro: {
16
+ model: "deepseek-v4-pro",
17
+ reasoningEffort: "max",
18
+ autoEscalate: false
19
+ }
20
+ };
21
+ var PRESET_DESCRIPTIONS = {
22
+ auto: {
23
+ headline: "flash \u2192 pro on hard turns",
24
+ cost: "default \xB7 ~96% turns stay on flash \xB7 pro kicks in only when needed"
25
+ },
26
+ flash: {
27
+ headline: "v4-flash always",
28
+ cost: "cheapest \xB7 predictable \xB7 /pro still works for a one-turn bump"
29
+ },
30
+ pro: {
31
+ headline: "v4-pro always",
32
+ cost: "~3\xD7 flash (5/31 discount) / ~12\xD7 full price \xB7 for hard multi-turn work"
33
+ }
34
+ };
35
+ function resolvePreset(name) {
36
+ if (name === "auto" || name === "flash" || name === "pro") return PRESETS[name];
37
+ if (name === "fast") return { ...PRESETS.flash, reasoningEffort: "high" };
38
+ if (name === "smart") return PRESETS.auto;
39
+ if (name === "max") return PRESETS.pro;
40
+ return PRESETS.auto;
41
+ }
42
+
43
+ export {
44
+ PRESETS,
45
+ PRESET_DESCRIPTIONS,
46
+ resolvePreset
47
+ };
48
+ //# sourceMappingURL=chunk-MHDNZXJJ.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/cli/ui/presets.ts"],"sourcesContent":["import type { PresetName } from \"../../config.js\";\n\nexport interface PresetSettings {\n model: string;\n reasoningEffort: \"high\" | \"max\";\n autoEscalate: boolean;\n}\n\n/** Old names `fast`/`smart`/`max` aliased via `resolvePreset` so legacy configs still load. */\nexport const PRESETS: Record<\"auto\" | \"flash\" | \"pro\", PresetSettings> = {\n auto: {\n model: \"deepseek-v4-flash\",\n reasoningEffort: \"max\",\n autoEscalate: true,\n },\n flash: {\n model: \"deepseek-v4-flash\",\n reasoningEffort: \"max\",\n autoEscalate: false,\n },\n pro: {\n model: \"deepseek-v4-pro\",\n reasoningEffort: \"max\",\n autoEscalate: false,\n },\n};\n\nexport const PRESET_DESCRIPTIONS: Record<\n \"auto\" | \"flash\" | \"pro\",\n { headline: string; cost: string }\n> = {\n auto: {\n headline: \"flash → pro on hard turns\",\n cost: \"default · ~96% turns stay on flash · pro kicks in only when needed\",\n },\n flash: {\n headline: \"v4-flash always\",\n cost: \"cheapest · predictable · /pro still works for a one-turn bump\",\n },\n pro: {\n headline: \"v4-pro always\",\n cost: \"~3× flash (5/31 discount) / ~12× full price · for hard multi-turn work\",\n },\n};\n\n/** Legacy aliases: fast→flash+high, smart→auto, max→pro. Unknown names fall through to auto. */\nexport function resolvePreset(name: PresetName | undefined): PresetSettings {\n if (name === \"auto\" || name === \"flash\" || name === \"pro\") return PRESETS[name];\n if (name === \"fast\") return { ...PRESETS.flash, reasoningEffort: \"high\" };\n if (name === \"smart\") return PRESETS.auto;\n if (name === \"max\") return PRESETS.pro;\n return PRESETS.auto;\n}\n\n/** Canonical name for storage / display — unknown values become auto. */\nexport function canonicalPresetName(name: PresetName | undefined): \"auto\" | \"flash\" | \"pro\" {\n if (name === \"auto\" || name === \"flash\" || name === \"pro\") return name;\n return \"auto\";\n}\n"],"mappings":";;;AASO,IAAM,UAA4D;AAAA,EACvE,MAAM;AAAA,IACJ,OAAO;AAAA,IACP,iBAAiB;AAAA,IACjB,cAAc;AAAA,EAChB;AAAA,EACA,OAAO;AAAA,IACL,OAAO;AAAA,IACP,iBAAiB;AAAA,IACjB,cAAc;AAAA,EAChB;AAAA,EACA,KAAK;AAAA,IACH,OAAO;AAAA,IACP,iBAAiB;AAAA,IACjB,cAAc;AAAA,EAChB;AACF;AAEO,IAAM,sBAGT;AAAA,EACF,MAAM;AAAA,IACJ,UAAU;AAAA,IACV,MAAM;AAAA,EACR;AAAA,EACA,OAAO;AAAA,IACL,UAAU;AAAA,IACV,MAAM;AAAA,EACR;AAAA,EACA,KAAK;AAAA,IACH,UAAU;AAAA,IACV,MAAM;AAAA,EACR;AACF;AAGO,SAAS,cAAc,MAA8C;AAC1E,MAAI,SAAS,UAAU,SAAS,WAAW,SAAS,MAAO,QAAO,QAAQ,IAAI;AAC9E,MAAI,SAAS,OAAQ,QAAO,EAAE,GAAG,QAAQ,OAAO,iBAAiB,OAAO;AACxE,MAAI,SAAS,QAAS,QAAO,QAAQ;AACrC,MAAI,SAAS,MAAO,QAAO,QAAQ;AACnC,SAAO,QAAQ;AACjB;","names":[]}
@@ -0,0 +1,140 @@
1
+ #!/usr/bin/env node
2
+
3
+ // src/telemetry/stats.ts
4
+ var DEEPSEEK_PRICING = {
5
+ "deepseek-v4-flash": { inputCacheHit: 0.028, inputCacheMiss: 0.139, output: 0.278 },
6
+ "deepseek-v4-pro": { inputCacheHit: 0.139, inputCacheMiss: 1.667, output: 3.333 },
7
+ // Compat aliases — priced as v4-flash per the deprecation notice.
8
+ "deepseek-chat": { inputCacheHit: 0.028, inputCacheMiss: 0.139, output: 0.278 },
9
+ "deepseek-reasoner": { inputCacheHit: 0.028, inputCacheMiss: 0.139, output: 0.278 }
10
+ };
11
+ var CLAUDE_SONNET_PRICING = { input: 3, output: 15 };
12
+ var DEEPSEEK_CONTEXT_TOKENS = {
13
+ "deepseek-v4-flash": 1e6,
14
+ "deepseek-v4-pro": 1e6,
15
+ "deepseek-chat": 1e6,
16
+ "deepseek-reasoner": 1e6
17
+ };
18
+ var DEFAULT_CONTEXT_TOKENS = 131072;
19
+ function costUsd(model, usage) {
20
+ const p = DEEPSEEK_PRICING[model];
21
+ if (!p) return 0;
22
+ return (usage.promptCacheHitTokens * p.inputCacheHit + usage.promptCacheMissTokens * p.inputCacheMiss + usage.completionTokens * p.output) / 1e6;
23
+ }
24
+ function inputCostUsd(model, usage) {
25
+ const p = DEEPSEEK_PRICING[model];
26
+ if (!p) return 0;
27
+ return (usage.promptCacheHitTokens * p.inputCacheHit + usage.promptCacheMissTokens * p.inputCacheMiss) / 1e6;
28
+ }
29
+ function outputCostUsd(model, usage) {
30
+ const p = DEEPSEEK_PRICING[model];
31
+ if (!p) return 0;
32
+ return usage.completionTokens * p.output / 1e6;
33
+ }
34
+ function cacheSavingsUsd(model, hitTokens) {
35
+ if (hitTokens <= 0) return 0;
36
+ const p = DEEPSEEK_PRICING[model];
37
+ if (!p) return 0;
38
+ return hitTokens * (p.inputCacheMiss - p.inputCacheHit) / 1e6;
39
+ }
40
+ function claudeEquivalentCost(usage) {
41
+ return (usage.promptTokens * CLAUDE_SONNET_PRICING.input + usage.completionTokens * CLAUDE_SONNET_PRICING.output) / 1e6;
42
+ }
43
+ var SessionStats = class {
44
+ turns = [];
45
+ /** Cost from prior runs of a resumed session, restored from session meta. */
46
+ _carryoverCost = 0;
47
+ /** Turn count from prior runs of a resumed session. */
48
+ _carryoverTurns = 0;
49
+ _carryoverCacheHit = 0;
50
+ _carryoverCacheMiss = 0;
51
+ /** Last turn's promptTokens before exit — surfaced via summary() until the next live turn lands. */
52
+ _carryoverLastPromptTokens = 0;
53
+ /** Seed totals from a resumed session's persisted meta — only call once at construction. */
54
+ seedCarryover(opts) {
55
+ if (typeof opts.totalCostUsd === "number" && opts.totalCostUsd > 0) {
56
+ this._carryoverCost = opts.totalCostUsd;
57
+ }
58
+ if (typeof opts.turnCount === "number" && opts.turnCount > 0) {
59
+ this._carryoverTurns = opts.turnCount;
60
+ }
61
+ if (typeof opts.cacheHitTokens === "number" && opts.cacheHitTokens > 0) {
62
+ this._carryoverCacheHit = opts.cacheHitTokens;
63
+ }
64
+ if (typeof opts.cacheMissTokens === "number" && opts.cacheMissTokens > 0) {
65
+ this._carryoverCacheMiss = opts.cacheMissTokens;
66
+ }
67
+ if (typeof opts.lastPromptTokens === "number" && opts.lastPromptTokens > 0) {
68
+ this._carryoverLastPromptTokens = opts.lastPromptTokens;
69
+ }
70
+ }
71
+ record(turn, model, usage) {
72
+ const cost = costUsd(model, usage);
73
+ const stats = {
74
+ turn,
75
+ model,
76
+ usage,
77
+ cost,
78
+ cacheHitRatio: usage.cacheHitRatio
79
+ };
80
+ this.turns.push(stats);
81
+ return stats;
82
+ }
83
+ get totalCost() {
84
+ return this._carryoverCost + this.turns.reduce((sum, t) => sum + t.cost, 0);
85
+ }
86
+ get totalClaudeEquivalent() {
87
+ return this.turns.reduce((sum, t) => sum + claudeEquivalentCost(t.usage), 0);
88
+ }
89
+ get savingsVsClaude() {
90
+ const c = this.totalClaudeEquivalent;
91
+ return c > 0 ? 1 - this.totalCost / c : 0;
92
+ }
93
+ get totalInputCost() {
94
+ return this.turns.reduce((sum, t) => sum + inputCostUsd(t.model, t.usage), 0);
95
+ }
96
+ get totalOutputCost() {
97
+ return this.turns.reduce((sum, t) => sum + outputCostUsd(t.model, t.usage), 0);
98
+ }
99
+ get aggregateCacheHitRatio() {
100
+ let hit = this._carryoverCacheHit;
101
+ let miss = this._carryoverCacheMiss;
102
+ for (const t of this.turns) {
103
+ hit += t.usage.promptCacheHitTokens;
104
+ miss += t.usage.promptCacheMissTokens;
105
+ }
106
+ const denom = hit + miss;
107
+ return denom > 0 ? hit / denom : 0;
108
+ }
109
+ summary() {
110
+ const last = this.turns[this.turns.length - 1];
111
+ return {
112
+ turns: this.turns.length + this._carryoverTurns,
113
+ totalCostUsd: round(this.totalCost, 6),
114
+ totalInputCostUsd: round(this.totalInputCost, 6),
115
+ totalOutputCostUsd: round(this.totalOutputCost, 6),
116
+ claudeEquivalentUsd: round(this.totalClaudeEquivalent, 6),
117
+ savingsVsClaudePct: round(this.savingsVsClaude * 100, 2),
118
+ cacheHitRatio: round(this.aggregateCacheHitRatio, 4),
119
+ lastPromptTokens: last?.usage.promptTokens ?? this._carryoverLastPromptTokens,
120
+ lastTurnCostUsd: round(last?.cost ?? 0, 6)
121
+ };
122
+ }
123
+ };
124
+ function round(n, digits) {
125
+ const f = 10 ** digits;
126
+ return Math.round(n * f) / f;
127
+ }
128
+
129
+ export {
130
+ DEEPSEEK_PRICING,
131
+ DEEPSEEK_CONTEXT_TOKENS,
132
+ DEFAULT_CONTEXT_TOKENS,
133
+ costUsd,
134
+ inputCostUsd,
135
+ outputCostUsd,
136
+ cacheSavingsUsd,
137
+ claudeEquivalentCost,
138
+ SessionStats
139
+ };
140
+ //# sourceMappingURL=chunk-ORM6PK57.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/telemetry/stats.ts"],"sourcesContent":["import type { Usage } from \"../client.js\";\n\n/** USD per 1M tokens; CNY sheet converted at fixed 7.2 — revisit if FX moves >±5%. */\nexport const DEEPSEEK_PRICING: Record<\n string,\n { inputCacheHit: number; inputCacheMiss: number; output: number }\n> = {\n \"deepseek-v4-flash\": { inputCacheHit: 0.028, inputCacheMiss: 0.139, output: 0.278 },\n \"deepseek-v4-pro\": { inputCacheHit: 0.139, inputCacheMiss: 1.667, output: 3.333 },\n // Compat aliases — priced as v4-flash per the deprecation notice.\n \"deepseek-chat\": { inputCacheHit: 0.028, inputCacheMiss: 0.139, output: 0.278 },\n \"deepseek-reasoner\": { inputCacheHit: 0.028, inputCacheMiss: 0.139, output: 0.278 },\n};\n\n/** Reference Claude Sonnet 4.6 pricing (USD per 1M tokens). */\nexport const CLAUDE_SONNET_PRICING = { input: 3.0, output: 15.0 };\n\n/** Prompt-side window only; completion caps live server-side and don't affect this gauge. */\nexport const DEEPSEEK_CONTEXT_TOKENS: Record<string, number> = {\n \"deepseek-v4-flash\": 1_000_000,\n \"deepseek-v4-pro\": 1_000_000,\n \"deepseek-chat\": 1_000_000,\n \"deepseek-reasoner\": 1_000_000,\n};\n\n/** Fallback when the caller's model id isn't in the table — safe lower bound. */\nexport const DEFAULT_CONTEXT_TOKENS = 131_072;\n\nexport function costUsd(model: string, usage: Usage): number {\n const p = DEEPSEEK_PRICING[model];\n if (!p) return 0;\n return (\n (usage.promptCacheHitTokens * p.inputCacheHit +\n usage.promptCacheMissTokens * p.inputCacheMiss +\n usage.completionTokens * p.output) /\n 1_000_000\n );\n}\n\n/** Input-side cost only (prompt, cache hit + miss). Used for the panel breakdown. */\nexport function inputCostUsd(model: string, usage: Usage): number {\n const p = DEEPSEEK_PRICING[model];\n if (!p) return 0;\n return (\n (usage.promptCacheHitTokens * p.inputCacheHit +\n usage.promptCacheMissTokens * p.inputCacheMiss) /\n 1_000_000\n );\n}\n\n/** Output-side cost only (completion tokens). Used for the panel breakdown. */\nexport function outputCostUsd(model: string, usage: Usage): number {\n const p = DEEPSEEK_PRICING[model];\n if (!p) return 0;\n return (usage.completionTokens * p.output) / 1_000_000;\n}\n\nexport function cacheSavingsUsd(model: string, hitTokens: number): number {\n if (hitTokens <= 0) return 0;\n const p = DEEPSEEK_PRICING[model];\n if (!p) return 0;\n return (hitTokens * (p.inputCacheMiss - p.inputCacheHit)) / 1_000_000;\n}\n\nexport function claudeEquivalentCost(usage: Usage): number {\n return (\n (usage.promptTokens * CLAUDE_SONNET_PRICING.input +\n usage.completionTokens * CLAUDE_SONNET_PRICING.output) /\n 1_000_000\n );\n}\n\nexport interface TurnStats {\n turn: number;\n model: string;\n usage: Usage;\n cost: number;\n cacheHitRatio: number;\n}\n\nexport interface SessionSummary {\n turns: number;\n totalCostUsd: number;\n totalInputCostUsd: number;\n /** Output-side (completion) cost aggregated across the session. */\n totalOutputCostUsd: number;\n /** @deprecated Claude reference; kept for benchmarks + replay compat, no longer surfaced in the TUI. */\n claudeEquivalentUsd: number;\n /** @deprecated. Same as claudeEquivalentUsd — synthetic ratio, not a real measurement. */\n savingsVsClaudePct: number;\n cacheHitRatio: number;\n /** Floor estimate for next call — actual cost = this + user delta + new tool outputs. */\n lastPromptTokens: number;\n lastTurnCostUsd: number;\n}\n\nexport class SessionStats {\n readonly turns: TurnStats[] = [];\n /** Cost from prior runs of a resumed session, restored from session meta. */\n private _carryoverCost = 0;\n /** Turn count from prior runs of a resumed session. */\n private _carryoverTurns = 0;\n private _carryoverCacheHit = 0;\n private _carryoverCacheMiss = 0;\n /** Last turn's promptTokens before exit — surfaced via summary() until the next live turn lands. */\n private _carryoverLastPromptTokens = 0;\n\n /** Seed totals from a resumed session's persisted meta — only call once at construction. */\n seedCarryover(opts: {\n totalCostUsd?: number;\n turnCount?: number;\n cacheHitTokens?: number;\n cacheMissTokens?: number;\n lastPromptTokens?: number;\n }): void {\n if (typeof opts.totalCostUsd === \"number\" && opts.totalCostUsd > 0) {\n this._carryoverCost = opts.totalCostUsd;\n }\n if (typeof opts.turnCount === \"number\" && opts.turnCount > 0) {\n this._carryoverTurns = opts.turnCount;\n }\n if (typeof opts.cacheHitTokens === \"number\" && opts.cacheHitTokens > 0) {\n this._carryoverCacheHit = opts.cacheHitTokens;\n }\n if (typeof opts.cacheMissTokens === \"number\" && opts.cacheMissTokens > 0) {\n this._carryoverCacheMiss = opts.cacheMissTokens;\n }\n if (typeof opts.lastPromptTokens === \"number\" && opts.lastPromptTokens > 0) {\n this._carryoverLastPromptTokens = opts.lastPromptTokens;\n }\n }\n\n record(turn: number, model: string, usage: Usage): TurnStats {\n const cost = costUsd(model, usage);\n const stats: TurnStats = {\n turn,\n model,\n usage,\n cost,\n cacheHitRatio: usage.cacheHitRatio,\n };\n this.turns.push(stats);\n return stats;\n }\n\n get totalCost(): number {\n return this._carryoverCost + this.turns.reduce((sum, t) => sum + t.cost, 0);\n }\n\n get totalClaudeEquivalent(): number {\n return this.turns.reduce((sum, t) => sum + claudeEquivalentCost(t.usage), 0);\n }\n\n get savingsVsClaude(): number {\n const c = this.totalClaudeEquivalent;\n return c > 0 ? 1 - this.totalCost / c : 0;\n }\n\n get totalInputCost(): number {\n return this.turns.reduce((sum, t) => sum + inputCostUsd(t.model, t.usage), 0);\n }\n\n get totalOutputCost(): number {\n return this.turns.reduce((sum, t) => sum + outputCostUsd(t.model, t.usage), 0);\n }\n\n get aggregateCacheHitRatio(): number {\n let hit = this._carryoverCacheHit;\n let miss = this._carryoverCacheMiss;\n for (const t of this.turns) {\n hit += t.usage.promptCacheHitTokens;\n miss += t.usage.promptCacheMissTokens;\n }\n const denom = hit + miss;\n return denom > 0 ? hit / denom : 0;\n }\n\n summary(): SessionSummary {\n const last = this.turns[this.turns.length - 1];\n return {\n turns: this.turns.length + this._carryoverTurns,\n totalCostUsd: round(this.totalCost, 6),\n totalInputCostUsd: round(this.totalInputCost, 6),\n totalOutputCostUsd: round(this.totalOutputCost, 6),\n claudeEquivalentUsd: round(this.totalClaudeEquivalent, 6),\n savingsVsClaudePct: round(this.savingsVsClaude * 100, 2),\n cacheHitRatio: round(this.aggregateCacheHitRatio, 4),\n lastPromptTokens: last?.usage.promptTokens ?? this._carryoverLastPromptTokens,\n lastTurnCostUsd: round(last?.cost ?? 0, 6),\n };\n }\n}\n\nfunction round(n: number, digits: number): number {\n const f = 10 ** digits;\n return Math.round(n * f) / f;\n}\n"],"mappings":"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","names":[]}
@@ -0,0 +1,99 @@
1
+ #!/usr/bin/env node
2
+
3
+ // src/cli/ui/theme/tokens.ts
4
+ var FG = {
5
+ strong: "#e6edf3",
6
+ body: "#c9d1d9",
7
+ sub: "#8b949e",
8
+ meta: "#6e7681",
9
+ faint: "#484f58"
10
+ };
11
+ var TONE = {
12
+ brand: "#79c0ff",
13
+ accent: "#d2a8ff",
14
+ violet: "#b395f5",
15
+ ok: "#7ee787",
16
+ warn: "#f0b07d",
17
+ err: "#ff8b81",
18
+ info: "#79c0ff"
19
+ };
20
+ var TONE_ACTIVE = {
21
+ brand: "#a5d6ff",
22
+ accent: "#e2c5ff",
23
+ violet: "#c8aaff",
24
+ ok: "#a8f5ad",
25
+ warn: "#ffc99e",
26
+ err: "#ffaba3",
27
+ info: "#a5d6ff"
28
+ };
29
+ var SURFACE = {
30
+ bg: "#0a0c10",
31
+ bgInput: "#0d1015",
32
+ bgCode: "#06080c",
33
+ bgElev: "#11141a"
34
+ };
35
+ var CARD = {
36
+ user: { color: FG.meta, glyph: "\u25C7" },
37
+ reasoning: { color: TONE.accent, glyph: "\u25C6" },
38
+ streaming: { color: TONE.brand, glyph: "\u25C8" },
39
+ task: { color: TONE.warn, glyph: "\u25B6" },
40
+ tool: { color: TONE.info, glyph: "\u25A3" },
41
+ plan: { color: TONE.accent, glyph: "\u229E" },
42
+ diff: { color: TONE.ok, glyph: "\xB1" },
43
+ error: { color: TONE.err, glyph: "\u2716" },
44
+ warn: { color: TONE.warn, glyph: "\u26A0" },
45
+ usage: { color: FG.meta, glyph: "\u03A3" },
46
+ subagent: { color: TONE.violet, glyph: "\u232C" },
47
+ approval: { color: TONE.warn, glyph: "?" },
48
+ search: { color: TONE.info, glyph: "\u2299" },
49
+ memory: { color: FG.meta, glyph: "\u2311" },
50
+ ctx: { color: TONE.brand, glyph: "\u25D4" },
51
+ doctor: { color: FG.meta, glyph: "\u2695" },
52
+ branch: { color: TONE.violet, glyph: "\u2387" }
53
+ };
54
+ var USD_TO_CNY = 7.2;
55
+ var SYMBOL = { USD: "$", CNY: "\xA5" };
56
+ function formatBalance(amount, currency, opts) {
57
+ const cur = currency ?? "CNY";
58
+ const sym = SYMBOL[cur];
59
+ const digits = opts?.fractionDigits ?? 2;
60
+ const body = sym ? `${sym}${amount.toFixed(digits)}` : `${cur} ${amount.toFixed(digits)}`;
61
+ return opts?.label ? `w ${body}` : body;
62
+ }
63
+ function formatCost(costUsd, currency, fractionDigits = 4) {
64
+ const cur = currency ?? "CNY";
65
+ const amount = cur === "CNY" ? costUsd * USD_TO_CNY : costUsd;
66
+ return formatBalance(amount, cur, { fractionDigits });
67
+ }
68
+
69
+ // src/cli/ui/primitives.tsx
70
+ import { Text, useStdout } from "ink";
71
+ import React from "react";
72
+ function ChromeRule() {
73
+ const { stdout } = useStdout();
74
+ const cols = stdout?.columns ?? 80;
75
+ const w = Math.max(20, cols - 2);
76
+ return /* @__PURE__ */ React.createElement(Text, { dimColor: true }, "\u2500".repeat(w));
77
+ }
78
+ function Bar({
79
+ ratio,
80
+ color,
81
+ cells = 14,
82
+ dim
83
+ }) {
84
+ const filled = Math.max(0, Math.min(cells, Math.round(ratio * cells)));
85
+ return /* @__PURE__ */ React.createElement(Text, null, /* @__PURE__ */ React.createElement(Text, { color, dimColor: dim }, "\u25B0".repeat(filled)), /* @__PURE__ */ React.createElement(Text, { dimColor: true }, "\u25B1".repeat(cells - filled)));
86
+ }
87
+
88
+ export {
89
+ FG,
90
+ TONE,
91
+ TONE_ACTIVE,
92
+ SURFACE,
93
+ CARD,
94
+ formatBalance,
95
+ formatCost,
96
+ ChromeRule,
97
+ Bar
98
+ };
99
+ //# sourceMappingURL=chunk-Q5GRLZJF.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/cli/ui/theme/tokens.ts","../../src/cli/ui/primitives.tsx"],"sourcesContent":["export const FG = {\n strong: \"#e6edf3\",\n body: \"#c9d1d9\",\n sub: \"#8b949e\",\n meta: \"#6e7681\",\n faint: \"#484f58\",\n} as const;\n\nexport const TONE = {\n brand: \"#79c0ff\",\n accent: \"#d2a8ff\",\n violet: \"#b395f5\",\n ok: \"#7ee787\",\n warn: \"#f0b07d\",\n err: \"#ff8b81\",\n info: \"#79c0ff\",\n} as const;\n\n/** Used only while a card is streaming/running, so live cards stand out from settled history. */\nexport const TONE_ACTIVE = {\n brand: \"#a5d6ff\",\n accent: \"#e2c5ff\",\n violet: \"#c8aaff\",\n ok: \"#a8f5ad\",\n warn: \"#ffc99e\",\n err: \"#ffaba3\",\n info: \"#a5d6ff\",\n} as const;\n\nexport const SURFACE = {\n bg: \"#0a0c10\",\n bgInput: \"#0d1015\",\n bgCode: \"#06080c\",\n bgElev: \"#11141a\",\n} as const;\n\nexport const CARD = {\n user: { color: FG.meta, glyph: \"◇\" },\n reasoning: { color: TONE.accent, glyph: \"◆\" },\n streaming: { color: TONE.brand, glyph: \"◈\" },\n task: { color: TONE.warn, glyph: \"▶\" },\n tool: { color: TONE.info, glyph: \"▣\" },\n plan: { color: TONE.accent, glyph: \"⊞\" },\n diff: { color: TONE.ok, glyph: \"±\" },\n error: { color: TONE.err, glyph: \"✖\" },\n warn: { color: TONE.warn, glyph: \"⚠\" },\n usage: { color: FG.meta, glyph: \"Σ\" },\n subagent: { color: TONE.violet, glyph: \"⌬\" },\n approval: { color: TONE.warn, glyph: \"?\" },\n search: { color: TONE.info, glyph: \"⊙\" },\n memory: { color: FG.meta, glyph: \"⌑\" },\n ctx: { color: TONE.brand, glyph: \"◔\" },\n doctor: { color: FG.meta, glyph: \"⚕\" },\n branch: { color: TONE.violet, glyph: \"⎇\" },\n} as const;\n\nexport type CardTone = keyof typeof CARD;\n\n/** DeepSeek prices in CNY; our internal table is USD divided by 7.2. Multiply back for display. */\nexport const USD_TO_CNY = 7.2;\n\nconst SYMBOL: Record<string, string> = { USD: \"$\", CNY: \"¥\" };\n\n/** Format an amount already in `currency`. Undefined currency → CNY (matches pre-fix behavior). */\nexport function formatBalance(\n amount: number,\n currency?: string,\n opts?: { fractionDigits?: number; label?: boolean },\n): string {\n const cur = currency ?? \"CNY\";\n const sym = SYMBOL[cur];\n const digits = opts?.fractionDigits ?? 2;\n const body = sym ? `${sym}${amount.toFixed(digits)}` : `${cur} ${amount.toFixed(digits)}`;\n return opts?.label ? `w ${body}` : body;\n}\n\n/** Format an internal USD cost in the wallet's display currency. Undefined currency → CNY. */\nexport function formatCost(costUsd: number, currency?: string, fractionDigits = 4): string {\n const cur = currency ?? \"CNY\";\n const amount = cur === \"CNY\" ? costUsd * USD_TO_CNY : costUsd;\n return formatBalance(amount, cur, { fractionDigits });\n}\n\n/** Threshold color for a wallet balance. USD is converted to CNY before the threshold check. */\nexport function balanceColor(amount: number, currency?: string): string {\n const cny = (currency ?? \"CNY\") === \"USD\" ? amount * USD_TO_CNY : amount;\n if (cny < 5) return TONE.err;\n if (cny < 20) return TONE.warn;\n return TONE.brand;\n}\n","import { Text, useStdout } from \"ink\";\n// biome-ignore lint/style/useImportType: tsconfig jsx=react needs React in value scope for JSX compilation\nimport React from \"react\";\nimport { COLOR } from \"./theme.js\";\n\n/**\n * Faint full-width horizontal rule. Width tracks the terminal columns\n * minus 2 cells so it lines up exactly under content rendered inside\n * a `paddingX={1}` parent — the standard chrome layout. Used by the\n * top chrome bar, the replay StatsPanel, and the bottom ctx footer.\n */\nexport function ChromeRule(): React.ReactElement {\n const { stdout } = useStdout();\n const cols = stdout?.columns ?? 80;\n const w = Math.max(20, cols - 2);\n return <Text dimColor>{\"─\".repeat(w)}</Text>;\n}\n\n/** Compact binary-K formatter — `1234 → \"1.2K\"`, `131072 → \"128K\"`. */\nexport function formatTokens(n: number): string {\n if (n < 1024) return String(n);\n const k = n / 1024;\n return k >= 100 ? `${k.toFixed(0)}K` : `${k.toFixed(1)}K`;\n}\n\n/**\n * Filled / empty progress bar. `▰▱` glyphs have distinct shapes so the\n * boundary stays visible even when the terminal collapses to 8-color slots.\n */\nexport function Bar({\n ratio,\n color,\n cells = 14,\n dim,\n}: {\n ratio: number;\n color: string;\n cells?: number;\n dim?: boolean;\n}): React.ReactElement {\n const filled = Math.max(0, Math.min(cells, Math.round(ratio * cells)));\n return (\n <Text>\n <Text color={color} dimColor={dim}>\n {\"▰\".repeat(filled)}\n </Text>\n <Text dimColor>{\"▱\".repeat(cells - filled)}</Text>\n </Text>\n );\n}\n\n/**\n * `▣ ctx ▰▰▱▱… 14K/128K (11%)` — the canonical context-pressure cell.\n * Used by the persistent footer (chat) and StatsPanel (replay). Color\n * thresholds match the `/compact` warning policy in the loop:\n * green <60% · amber 60-80% · red ≥80% (with `· /compact` hint).\n */\nexport function ContextCell({\n ratio,\n promptTokens,\n ctxMax,\n showBar,\n}: {\n ratio: number;\n promptTokens: number;\n ctxMax: number;\n showBar?: boolean;\n}): React.ReactElement {\n if (promptTokens === 0) {\n return (\n <Text>\n <Text color={COLOR.info} dimColor>\n {\"▣ ctx \"}\n </Text>\n <Text dimColor>— (no turns yet)</Text>\n </Text>\n );\n }\n const color = ratio >= 0.8 ? COLOR.err : ratio >= 0.6 ? COLOR.warn : COLOR.ok;\n const pct = Math.round(ratio * 100);\n return (\n <Text>\n <Text color={COLOR.info}>{\"▣ ctx \"}</Text>\n <Bar ratio={ratio} color={color} cells={showBar ? 14 : 10} />\n <Text> </Text>\n <Text color={color} bold>\n {formatTokens(promptTokens)}/{formatTokens(ctxMax)}\n </Text>\n <Text dimColor> ({pct}%)</Text>\n {ratio >= 0.8 ? (\n <Text color={COLOR.err} bold>\n {\" · /compact\"}\n </Text>\n ) : null}\n </Text>\n );\n}\n"],"mappings":"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","names":[]}