reasonix 0.33.0 → 0.33.1

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.
@@ -1,10 +1,10 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  chatCommand
4
- } from "./chunk-LVQX5KGF.js";
4
+ } from "./chunk-MDHVWCJ4.js";
5
5
  import "./chunk-BQNUJJN7.js";
6
6
  import "./chunk-RFX7TYVV.js";
7
- import "./chunk-Q5GRLZJF.js";
7
+ import "./chunk-63KAV5DX.js";
8
8
  import "./chunk-CPOV2O73.js";
9
9
  import "./chunk-Q6YFXW7H.js";
10
10
  import "./chunk-I6YIAK6C.js";
@@ -36,4 +36,4 @@ import "./chunk-ORM6PK57.js";
36
36
  export {
37
37
  chatCommand
38
38
  };
39
- //# sourceMappingURL=chat-EIFLHBZ6.js.map
39
+ //# sourceMappingURL=chat-Q5ZCVIOO.js.map
@@ -65,6 +65,12 @@ function formatCost(costUsd, currency, fractionDigits = 4) {
65
65
  const amount = cur === "CNY" ? costUsd * USD_TO_CNY : costUsd;
66
66
  return formatBalance(amount, cur, { fractionDigits });
67
67
  }
68
+ function balanceColor(amount, currency) {
69
+ const cny = (currency ?? "CNY") === "USD" ? amount * USD_TO_CNY : amount;
70
+ if (cny < 5) return TONE.err;
71
+ if (cny < 20) return TONE.warn;
72
+ return TONE.brand;
73
+ }
68
74
 
69
75
  // src/cli/ui/primitives.tsx
70
76
  import { Text, useStdout } from "ink";
@@ -93,7 +99,8 @@ export {
93
99
  CARD,
94
100
  formatBalance,
95
101
  formatCost,
102
+ balanceColor,
96
103
  ChromeRule,
97
104
  Bar
98
105
  };
99
- //# sourceMappingURL=chunk-Q5GRLZJF.js.map
106
+ //# sourceMappingURL=chunk-63KAV5DX.js.map
@@ -1 +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":[]}
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":[]}
@@ -12,9 +12,10 @@ import {
12
12
  SURFACE,
13
13
  TONE,
14
14
  TONE_ACTIVE,
15
+ balanceColor,
15
16
  formatBalance,
16
17
  formatCost
17
- } from "./chunk-Q5GRLZJF.js";
18
+ } from "./chunk-63KAV5DX.js";
18
19
  import {
19
20
  dumpStartupProfile,
20
21
  markPhase
@@ -5714,7 +5715,7 @@ function PromptInput({
5714
5715
  const continuationIndent = " ";
5715
5716
  const prefixCells = promptPrefix.length;
5716
5717
  const visibleCells = Math.max(8, cols - prefixCells - 3);
5717
- const effectivePlaceholder = disabled ? placeholder ?? "\u2026waiting for response\u2026" : placeholder ?? "type a message \xB7 slash for commands \xB7 at-sign for files";
5718
+ const effectivePlaceholder = disabled ? placeholder ?? "\u2026waiting for response\u2026" : placeholder ?? "ask anything \xB7 slash for commands \xB7 at-sign for files";
5718
5719
  const lines = value.length > 0 ? value.split("\n") : [""];
5719
5720
  const accentColor = disabled ? FG.faint : TONE.brand;
5720
5721
  const cursorVisible = true;
@@ -5834,7 +5835,17 @@ function PromptInput({
5834
5835
  }
5835
5836
  }
5836
5837
  return rows;
5837
- })(), showHugeBufferHints && !disabled ? /* @__PURE__ */ React23.createElement(Box19, null, /* @__PURE__ */ React23.createElement(Text19, { color: FG.faint }, ` [${lines.length} lines \xB7 PgUp/PgDn jump \xB7 Ctrl+U clear \xB7 Ctrl+W del word]`)) : null, !disabled ? /* @__PURE__ */ React23.createElement(Box19, { marginTop: 1 }, /* @__PURE__ */ React23.createElement(Text19, { color: FG.faint }, " \u23CE send \xB7 shift/alt+\u23CE newline \xB7 \u2191\u2193 history \xB7 esc abort \xB7 ctrl-c quit")) : /* @__PURE__ */ React23.createElement(Box19, { marginTop: 1 }, /* @__PURE__ */ React23.createElement(Text19, { color: FG.faint }, " esc to stop")));
5838
+ })(), showHugeBufferHints && !disabled ? /* @__PURE__ */ React23.createElement(Box19, null, /* @__PURE__ */ React23.createElement(Text19, { color: FG.faint }, ` [${lines.length} lines \xB7 PgUp/PgDn jump \xB7 Ctrl+U clear \xB7 Ctrl+W del word]`)) : null, !disabled ? /* @__PURE__ */ React23.createElement(Box19, { marginTop: 1 }, /* @__PURE__ */ React23.createElement(HintRow, null)) : /* @__PURE__ */ React23.createElement(Box19, { marginTop: 1 }, /* @__PURE__ */ React23.createElement(Text19, { color: FG.faint }, " esc to stop")));
5839
+ }
5840
+ function HintRow() {
5841
+ const items = [
5842
+ { key: "\u23CE", sep: "send" },
5843
+ { key: "\u21E7\u23CE", sep: "newline" },
5844
+ { key: "\u2191\u2193", sep: "history" },
5845
+ { key: "esc", sep: "abort" },
5846
+ { key: "^C", sep: "quit" }
5847
+ ];
5848
+ return /* @__PURE__ */ React23.createElement(Box19, { flexDirection: "row" }, /* @__PURE__ */ React23.createElement(Text19, null, " "), items.map((item, i) => /* @__PURE__ */ React23.createElement(React23.Fragment, { key: item.key }, i > 0 && /* @__PURE__ */ React23.createElement(Text19, { color: FG.faint }, " \xB7 "), /* @__PURE__ */ React23.createElement(Text19, { color: FG.meta }, item.key), /* @__PURE__ */ React23.createElement(Text19, { color: FG.faint }, ` ${item.sep}`))));
5838
5849
  }
5839
5850
  function splitLineByPastes(line) {
5840
5851
  const out = [];
@@ -9160,6 +9171,7 @@ function Countdown({ endsAt, color = TONE.brand }) {
9160
9171
  // src/cli/ui/layout/StatusRow.tsx
9161
9172
  var RULE_PAD = 4;
9162
9173
  var RULE_MIN = 20;
9174
+ var WALLET_MIN_COLS = 90;
9163
9175
  function StatusRow() {
9164
9176
  const status2 = useAgentState((s) => s.status);
9165
9177
  const session = useAgentState((s) => s.session);
@@ -9167,7 +9179,26 @@ function StatusRow() {
9167
9179
  const cols = stdout?.columns ?? 80;
9168
9180
  const ruleWidth = Math.max(RULE_MIN, cols - RULE_PAD);
9169
9181
  const hasTurn = status2.cost > 0;
9170
- return /* @__PURE__ */ React55.createElement(Box45, { flexDirection: "column" }, /* @__PURE__ */ React55.createElement(Box45, null, /* @__PURE__ */ React55.createElement(Text48, null, " "), /* @__PURE__ */ React55.createElement(Text48, { color: FG.faint }, "\u2500".repeat(ruleWidth))), /* @__PURE__ */ React55.createElement(Box45, { flexDirection: "row" }, /* @__PURE__ */ React55.createElement(Text48, null, " "), status2.recording ? /* @__PURE__ */ React55.createElement(RecordingPill, { rec: status2.recording }) : status2.countdownSeconds !== void 0 ? /* @__PURE__ */ React55.createElement(CountdownRow, { mode: status2.mode, secondsLeft: status2.countdownSeconds }) : /* @__PURE__ */ React55.createElement(ModePill2, { mode: status2.mode, network: status2.network, detail: status2.networkDetail }), /* @__PURE__ */ React55.createElement(Sep, null), /* @__PURE__ */ React55.createElement(Text48, { color: FG.sub }, `${session.id} \xB7 ${session.branch}`), hasTurn && /* @__PURE__ */ React55.createElement(React55.Fragment, null, /* @__PURE__ */ React55.createElement(Sep, null), /* @__PURE__ */ React55.createElement(Text48, { bold: true, color: TONE.brand }, "\u25B8 "), /* @__PURE__ */ React55.createElement(Text48, { bold: true, color: FG.body }, `${formatCost(status2.cost, status2.balanceCurrency)} turn`)), /* @__PURE__ */ React55.createElement(Sep, null), /* @__PURE__ */ React55.createElement(Text48, { color: TONE.accent }, `cache ${Math.round(status2.cacheHit * 100)}%`)));
9182
+ const hasSession = status2.sessionCost > 0;
9183
+ const hasBalance = typeof status2.balance === "number";
9184
+ const showWallet = cols >= WALLET_MIN_COLS && (hasSession || hasBalance);
9185
+ return /* @__PURE__ */ React55.createElement(Box45, { flexDirection: "column" }, /* @__PURE__ */ React55.createElement(Box45, null, /* @__PURE__ */ React55.createElement(Text48, null, " "), /* @__PURE__ */ React55.createElement(Text48, { color: FG.faint }, "\u2500".repeat(ruleWidth))), /* @__PURE__ */ React55.createElement(Box45, { flexDirection: "row" }, /* @__PURE__ */ React55.createElement(Text48, null, " "), status2.recording ? /* @__PURE__ */ React55.createElement(RecordingPill, { rec: status2.recording }) : status2.countdownSeconds !== void 0 ? /* @__PURE__ */ React55.createElement(CountdownRow, { mode: status2.mode, secondsLeft: status2.countdownSeconds }) : /* @__PURE__ */ React55.createElement(ModePill2, { mode: status2.mode, network: status2.network, detail: status2.networkDetail }), /* @__PURE__ */ React55.createElement(Sep, null), /* @__PURE__ */ React55.createElement(Text48, { color: FG.sub }, `${session.id} \xB7 ${session.branch}`), hasTurn && /* @__PURE__ */ React55.createElement(React55.Fragment, null, /* @__PURE__ */ React55.createElement(Sep, null), /* @__PURE__ */ React55.createElement(Text48, { bold: true, color: TONE.brand }, "\u25B8 "), /* @__PURE__ */ React55.createElement(Text48, { bold: true, color: FG.body }, `${formatCost(status2.cost, status2.balanceCurrency)} turn`)), /* @__PURE__ */ React55.createElement(Sep, null), /* @__PURE__ */ React55.createElement(Text48, { color: TONE.accent }, `cache ${Math.round(status2.cacheHit * 100)}%`), showWallet && /* @__PURE__ */ React55.createElement(
9186
+ WalletPill,
9187
+ {
9188
+ sessionCostUsd: status2.sessionCost,
9189
+ balance: status2.balance,
9190
+ currency: status2.balanceCurrency
9191
+ }
9192
+ )));
9193
+ }
9194
+ function WalletPill({
9195
+ sessionCostUsd,
9196
+ balance,
9197
+ currency
9198
+ }) {
9199
+ const showSpent = sessionCostUsd > 0;
9200
+ const showBalance = typeof balance === "number";
9201
+ return /* @__PURE__ */ React55.createElement(React55.Fragment, null, /* @__PURE__ */ React55.createElement(Sep, null), /* @__PURE__ */ React55.createElement(Text48, { color: FG.meta }, "\u26C1 "), showSpent && /* @__PURE__ */ React55.createElement(Text48, { color: FG.body }, `${formatCost(sessionCostUsd, currency, 2)} spent`), showSpent && showBalance && /* @__PURE__ */ React55.createElement(Text48, { color: FG.meta }, " / "), showBalance && /* @__PURE__ */ React55.createElement(Text48, { bold: true, color: balanceColor(balance, currency) }, formatBalance(balance, currency, { fractionDigits: 2 })), showBalance && /* @__PURE__ */ React55.createElement(Text48, { color: FG.faint }, " left"));
9171
9202
  }
9172
9203
  function ModePill2({
9173
9204
  mode: mode2,
@@ -14931,4 +14962,4 @@ async function chatCommand(opts) {
14931
14962
  export {
14932
14963
  chatCommand
14933
14964
  };
14934
- //# sourceMappingURL=chunk-LVQX5KGF.js.map
14965
+ //# sourceMappingURL=chunk-MDHVWCJ4.js.map