reasonix 0.30.3 → 0.30.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -590,10 +590,17 @@ declare class SessionStats {
590
590
  private _carryoverCost;
591
591
  /** Turn count from prior runs of a resumed session. */
592
592
  private _carryoverTurns;
593
+ private _carryoverCacheHit;
594
+ private _carryoverCacheMiss;
595
+ /** Last turn's promptTokens before exit — surfaced via summary() until the next live turn lands. */
596
+ private _carryoverLastPromptTokens;
593
597
  /** Seed totals from a resumed session's persisted meta — only call once at construction. */
594
598
  seedCarryover(opts: {
595
599
  totalCostUsd?: number;
596
600
  turnCount?: number;
601
+ cacheHitTokens?: number;
602
+ cacheMissTokens?: number;
603
+ lastPromptTokens?: number;
597
604
  }): void;
598
605
  record(turn: number, model: string, usage: Usage): TurnStats;
599
606
  get totalCost(): number;
@@ -1353,6 +1360,11 @@ interface SessionMeta {
1353
1360
  workspace?: string;
1354
1361
  /** Wallet currency at last save — used to format `totalCostUsd` in the picker without re-fetching balance. */
1355
1362
  balanceCurrency?: string;
1363
+ /** Cumulative cache hit / miss tokens across the session — survives resume so /status cache% isn't 0 on a fresh boot. */
1364
+ cacheHitTokens?: number;
1365
+ cacheMissTokens?: number;
1366
+ /** Last turn's promptTokens — lets /status render the context bar before the next turn fires. */
1367
+ lastPromptTokens?: number;
1356
1368
  }
1357
1369
  declare function sessionsDir(): string;
1358
1370
  declare function sessionPath(name: string): string;
package/dist/index.js CHANGED
@@ -1480,6 +1480,10 @@ var SessionStats = class {
1480
1480
  _carryoverCost = 0;
1481
1481
  /** Turn count from prior runs of a resumed session. */
1482
1482
  _carryoverTurns = 0;
1483
+ _carryoverCacheHit = 0;
1484
+ _carryoverCacheMiss = 0;
1485
+ /** Last turn's promptTokens before exit — surfaced via summary() until the next live turn lands. */
1486
+ _carryoverLastPromptTokens = 0;
1483
1487
  /** Seed totals from a resumed session's persisted meta — only call once at construction. */
1484
1488
  seedCarryover(opts) {
1485
1489
  if (typeof opts.totalCostUsd === "number" && opts.totalCostUsd > 0) {
@@ -1488,6 +1492,15 @@ var SessionStats = class {
1488
1492
  if (typeof opts.turnCount === "number" && opts.turnCount > 0) {
1489
1493
  this._carryoverTurns = opts.turnCount;
1490
1494
  }
1495
+ if (typeof opts.cacheHitTokens === "number" && opts.cacheHitTokens > 0) {
1496
+ this._carryoverCacheHit = opts.cacheHitTokens;
1497
+ }
1498
+ if (typeof opts.cacheMissTokens === "number" && opts.cacheMissTokens > 0) {
1499
+ this._carryoverCacheMiss = opts.cacheMissTokens;
1500
+ }
1501
+ if (typeof opts.lastPromptTokens === "number" && opts.lastPromptTokens > 0) {
1502
+ this._carryoverLastPromptTokens = opts.lastPromptTokens;
1503
+ }
1491
1504
  }
1492
1505
  record(turn, model, usage) {
1493
1506
  const cost = costUsd(model, usage);
@@ -1518,8 +1531,8 @@ var SessionStats = class {
1518
1531
  return this.turns.reduce((sum, t) => sum + outputCostUsd(t.model, t.usage), 0);
1519
1532
  }
1520
1533
  get aggregateCacheHitRatio() {
1521
- let hit = 0;
1522
- let miss = 0;
1534
+ let hit = this._carryoverCacheHit;
1535
+ let miss = this._carryoverCacheMiss;
1523
1536
  for (const t of this.turns) {
1524
1537
  hit += t.usage.promptCacheHitTokens;
1525
1538
  miss += t.usage.promptCacheMissTokens;
@@ -1537,7 +1550,7 @@ var SessionStats = class {
1537
1550
  claudeEquivalentUsd: round(this.totalClaudeEquivalent, 6),
1538
1551
  savingsVsClaudePct: round(this.savingsVsClaude * 100, 2),
1539
1552
  cacheHitRatio: round(this.aggregateCacheHitRatio, 4),
1540
- lastPromptTokens: last?.usage.promptTokens ?? 0,
1553
+ lastPromptTokens: last?.usage.promptTokens ?? this._carryoverLastPromptTokens,
1541
1554
  lastTurnCostUsd: round(last?.cost ?? 0, 6)
1542
1555
  };
1543
1556
  }
@@ -2541,7 +2554,10 @@ var CacheFirstLoop = class {
2541
2554
  const meta = loadSessionMeta(this.sessionName);
2542
2555
  this.stats.seedCarryover({
2543
2556
  totalCostUsd: meta.totalCostUsd,
2544
- turnCount: meta.turnCount
2557
+ turnCount: meta.turnCount,
2558
+ cacheHitTokens: meta.cacheHitTokens,
2559
+ cacheMissTokens: meta.cacheMissTokens,
2560
+ lastPromptTokens: meta.lastPromptTokens
2545
2561
  });
2546
2562
  }
2547
2563
  if (healedCount > 0) {
@@ -4662,7 +4678,9 @@ function registerFilesystemTools(registry, opts) {
4662
4678
  const normRoot = pathMod3.resolve(rootDir);
4663
4679
  const rel = pathMod3.relative(normRoot, resolved);
4664
4680
  if (rel.startsWith("..") || pathMod3.isAbsolute(rel)) {
4665
- throw new Error(`path escapes sandbox root (${normRoot}): ${raw}`);
4681
+ throw new Error(
4682
+ `path escapes sandbox root (${normRoot}): ${raw} \u2014 workspace is pinned at launch; quit and relaunch with \`reasonix code --dir <path>\` to work in a different folder`
4683
+ );
4666
4684
  }
4667
4685
  return resolved;
4668
4686
  };