claude-code-infinite 1.0.9 → 1.0.14

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 (136) hide show
  1. package/README.md +230 -37
  2. package/dist/cc-request.d.ts +94 -0
  3. package/dist/cc-request.d.ts.map +1 -0
  4. package/dist/cc-request.js +194 -0
  5. package/dist/cc-request.js.map +1 -0
  6. package/dist/claude-env.d.ts +30 -0
  7. package/dist/claude-env.d.ts.map +1 -0
  8. package/dist/claude-env.js +55 -0
  9. package/dist/claude-env.js.map +1 -0
  10. package/dist/cli-args.d.ts +32 -0
  11. package/dist/cli-args.d.ts.map +1 -0
  12. package/dist/cli-args.js +72 -0
  13. package/dist/cli-args.js.map +1 -0
  14. package/dist/cli-lifecycle.d.ts +17 -0
  15. package/dist/cli-lifecycle.d.ts.map +1 -0
  16. package/dist/cli-lifecycle.js +30 -0
  17. package/dist/cli-lifecycle.js.map +1 -0
  18. package/dist/cli-main.d.ts +15 -0
  19. package/dist/cli-main.d.ts.map +1 -0
  20. package/dist/cli-main.js +464 -0
  21. package/dist/cli-main.js.map +1 -0
  22. package/dist/cli.js +13 -177
  23. package/dist/cli.js.map +1 -1
  24. package/dist/config.d.ts +3 -0
  25. package/dist/config.d.ts.map +1 -1
  26. package/dist/config.js +29 -3
  27. package/dist/config.js.map +1 -1
  28. package/dist/count-tokens.d.ts +78 -0
  29. package/dist/count-tokens.d.ts.map +1 -0
  30. package/dist/count-tokens.js +277 -0
  31. package/dist/count-tokens.js.map +1 -0
  32. package/dist/final-index.d.ts +10 -0
  33. package/dist/final-index.d.ts.map +1 -0
  34. package/dist/final-index.js +37 -0
  35. package/dist/final-index.js.map +1 -0
  36. package/dist/hooks.d.ts +239 -0
  37. package/dist/hooks.d.ts.map +1 -0
  38. package/dist/hooks.js +618 -0
  39. package/dist/hooks.js.map +1 -0
  40. package/dist/index.d.ts +9 -0
  41. package/dist/index.d.ts.map +1 -1
  42. package/dist/index.js +8 -0
  43. package/dist/index.js.map +1 -1
  44. package/dist/memtree-fetch.d.ts +24 -0
  45. package/dist/memtree-fetch.d.ts.map +1 -0
  46. package/dist/memtree-fetch.js +121 -0
  47. package/dist/memtree-fetch.js.map +1 -0
  48. package/dist/memtree-finder.d.ts +99 -0
  49. package/dist/memtree-finder.d.ts.map +1 -0
  50. package/dist/memtree-finder.js +235 -0
  51. package/dist/memtree-finder.js.map +1 -0
  52. package/dist/memtree-links.d.ts +16 -0
  53. package/dist/memtree-links.d.ts.map +1 -0
  54. package/dist/memtree-links.js +66 -0
  55. package/dist/memtree-links.js.map +1 -0
  56. package/dist/memtree-mcp-config.d.ts +28 -0
  57. package/dist/memtree-mcp-config.d.ts.map +1 -0
  58. package/dist/memtree-mcp-config.js +121 -0
  59. package/dist/memtree-mcp-config.js.map +1 -0
  60. package/dist/memtree-mcp.d.ts +265 -0
  61. package/dist/memtree-mcp.d.ts.map +1 -0
  62. package/dist/memtree-mcp.js +667 -0
  63. package/dist/memtree-mcp.js.map +1 -0
  64. package/dist/memtree-newest.d.ts +74 -0
  65. package/dist/memtree-newest.d.ts.map +1 -0
  66. package/dist/memtree-newest.js +217 -0
  67. package/dist/memtree-newest.js.map +1 -0
  68. package/dist/memtree-tools.d.ts +105 -0
  69. package/dist/memtree-tools.d.ts.map +1 -0
  70. package/dist/memtree-tools.js +408 -0
  71. package/dist/memtree-tools.js.map +1 -0
  72. package/dist/memtree.d.ts +398 -0
  73. package/dist/memtree.d.ts.map +1 -0
  74. package/dist/memtree.js +1231 -0
  75. package/dist/memtree.js.map +1 -0
  76. package/dist/notices.d.ts +177 -0
  77. package/dist/notices.d.ts.map +1 -0
  78. package/dist/notices.js +469 -0
  79. package/dist/notices.js.map +1 -0
  80. package/dist/payment-gate.d.ts +53 -0
  81. package/dist/payment-gate.d.ts.map +1 -0
  82. package/dist/payment-gate.js +97 -0
  83. package/dist/payment-gate.js.map +1 -0
  84. package/dist/project-meta.d.ts +15 -0
  85. package/dist/project-meta.d.ts.map +1 -0
  86. package/dist/project-meta.js +80 -0
  87. package/dist/project-meta.js.map +1 -0
  88. package/dist/prompt-accounting.d.ts +12 -0
  89. package/dist/prompt-accounting.d.ts.map +1 -0
  90. package/dist/prompt-accounting.js +70 -0
  91. package/dist/prompt-accounting.js.map +1 -0
  92. package/dist/proxy.d.ts +197 -0
  93. package/dist/proxy.d.ts.map +1 -0
  94. package/dist/proxy.js +4247 -0
  95. package/dist/proxy.js.map +1 -0
  96. package/dist/reqlog.d.ts +419 -0
  97. package/dist/reqlog.d.ts.map +1 -0
  98. package/dist/reqlog.js +146 -0
  99. package/dist/reqlog.js.map +1 -0
  100. package/dist/request-sizing.d.ts +52 -0
  101. package/dist/request-sizing.d.ts.map +1 -0
  102. package/dist/request-sizing.js +92 -0
  103. package/dist/request-sizing.js.map +1 -0
  104. package/dist/resume-repair-file.d.ts +17 -0
  105. package/dist/resume-repair-file.d.ts.map +1 -0
  106. package/dist/resume-repair-file.js +100 -0
  107. package/dist/resume-repair-file.js.map +1 -0
  108. package/dist/resume-repair.d.ts +27 -0
  109. package/dist/resume-repair.d.ts.map +1 -0
  110. package/dist/resume-repair.js +198 -0
  111. package/dist/resume-repair.js.map +1 -0
  112. package/dist/route-cache.d.ts +5 -0
  113. package/dist/route-cache.d.ts.map +1 -0
  114. package/dist/route-cache.js +63 -0
  115. package/dist/route-cache.js.map +1 -0
  116. package/dist/route-fallback.d.ts +29 -0
  117. package/dist/route-fallback.d.ts.map +1 -0
  118. package/dist/route-fallback.js +49 -0
  119. package/dist/route-fallback.js.map +1 -0
  120. package/dist/route-identity.d.ts +6 -0
  121. package/dist/route-identity.d.ts.map +1 -0
  122. package/dist/route-identity.js +100 -0
  123. package/dist/route-identity.js.map +1 -0
  124. package/dist/transcript-usage.d.ts +57 -0
  125. package/dist/transcript-usage.d.ts.map +1 -0
  126. package/dist/transcript-usage.js +570 -0
  127. package/dist/transcript-usage.js.map +1 -0
  128. package/dist/turns.d.ts +73 -0
  129. package/dist/turns.d.ts.map +1 -0
  130. package/dist/turns.js +298 -0
  131. package/dist/turns.js.map +1 -0
  132. package/dist/update-check.d.ts +38 -0
  133. package/dist/update-check.d.ts.map +1 -0
  134. package/dist/update-check.js +67 -0
  135. package/dist/update-check.js.map +1 -0
  136. package/package.json +6 -2
@@ -0,0 +1,92 @@
1
+ /** Request-local sizing and selection. Shared response samples are copied once,
2
+ * exact counts remain attached to immutable body bytes, and every candidate
3
+ * shares the request's Count Tokens deadline and account cooldown. */
4
+ import { createHash } from "node:crypto";
5
+ import { plausibleSample, shouldCountTokens } from "./count-tokens.js";
6
+ import { approxTokensFromBytes } from "./reqlog.js";
7
+ export class RequestSizing {
8
+ counts;
9
+ enabled;
10
+ candidates = new Map();
11
+ excludedFallbacks = new Set();
12
+ constructor(counts, enabled) {
13
+ this.counts = counts;
14
+ this.enabled = enabled;
15
+ }
16
+ /** The first registration fixes both bytes and learned sample for this request. */
17
+ register(body, kind, sample) {
18
+ const key = createHash("sha256").update(body).digest("hex");
19
+ const existing = this.candidates.get(key);
20
+ if (existing)
21
+ return existing;
22
+ const snapshot = plausibleSample(sample) ? Object.freeze({ ...sample }) : undefined;
23
+ const candidate = Object.freeze({ key, body: Buffer.from(body), kind, sample: snapshot,
24
+ estimate: Object.freeze(estimateRequestTokens(snapshot, body.length)) });
25
+ this.candidates.set(key, candidate);
26
+ return candidate;
27
+ }
28
+ /** Eligibility belongs to route planning, not to a later byte-size guess. */
29
+ excludeFallback(candidate) {
30
+ this.excludedFallbacks.add(candidate);
31
+ }
32
+ /** Planning and metadata consult the same exact count, else the snapshotted estimate. */
33
+ plan(candidate) {
34
+ const exact = this.counts.peek(candidate.body)?.tokens;
35
+ return exact !== undefined ? { tokens: exact, source: "reported" } : candidate.estimate;
36
+ }
37
+ clientInputTokens(candidate) {
38
+ const size = this.plan(candidate);
39
+ return size.source === "reported" ? size.tokens : undefined;
40
+ }
41
+ /** Count only when a size decision needs it; all views reuse the same result. */
42
+ async measure(candidate, limits, phase = "delivery") {
43
+ let count = this.counts.peek(candidate.body);
44
+ const estimate = candidate.estimate.tokens;
45
+ const needed = shouldCountTokens(candidate.sample, candidate.body.length, estimate, limits.budget) ||
46
+ (phase === "delivery" && !fitsNative(estimate, limits));
47
+ if (!count && this.enabled && needed)
48
+ count = await this.counts.count(candidate.body);
49
+ if (count?.tokens !== undefined)
50
+ return {
51
+ tokens: count.tokens, source: "exact", estimatedTokens: estimate, count,
52
+ };
53
+ // A learned ratio can request compression, but cannot veto a body whose
54
+ // plain estimate fits when counting is unavailable or disabled.
55
+ const bytes = phase === "delivery" &&
56
+ (!this.enabled || count !== undefined || candidate.estimate.source === "bytes");
57
+ return { tokens: bytes ? Math.ceil(candidate.body.length / 4) : estimate,
58
+ source: bytes ? "bytes" : candidate.estimate.source,
59
+ estimatedTokens: estimate, count };
60
+ }
61
+ /** The preferred body gets first chance; only validated registered candidates
62
+ * are considered afterward. Exact overflow never degrades to a byte guess. */
63
+ async select(preferred, limits) {
64
+ const others = [...this.candidates.values()].filter(item => item !== preferred && !this.excludedFallbacks.has(item));
65
+ const rank = { replacement: 0, ride: 1, original: 2 };
66
+ others.sort((a, b) => rank[a.kind] - rank[b.kind]);
67
+ const ordered = preferred.kind === "original"
68
+ ? [...others.filter(item => item.kind !== "original"), preferred,
69
+ ...others.filter(item => item.kind === "original")]
70
+ : [preferred, ...others];
71
+ for (const candidate of ordered) {
72
+ const measurement = await this.measure(candidate, limits);
73
+ if (fitsNative(measurement.tokens, limits))
74
+ return { candidate, measurement };
75
+ }
76
+ return undefined;
77
+ }
78
+ }
79
+ export function fitsNative(input, limits) {
80
+ return [input, limits.output, limits.context].every(value => Number.isFinite(value) && value >= 0) &&
81
+ input + limits.output <= limits.context;
82
+ }
83
+ /** One shared estimator for planner telemetry and request-local snapshots. */
84
+ export function estimateRequestTokens(sample, bytes) {
85
+ if (!plausibleSample(sample))
86
+ return { tokens: approxTokensFromBytes(bytes), source: "bytes" };
87
+ const ratio = sample.tokens / sample.forwardedBytes;
88
+ const tokens = bytes <= sample.forwardedBytes ? Math.round(bytes * ratio) : sample.tokens +
89
+ Math.max(approxTokensFromBytes(bytes - sample.forwardedBytes), Math.round((bytes - sample.forwardedBytes) * ratio));
90
+ return { tokens, source: "reported" };
91
+ }
92
+ //# sourceMappingURL=request-sizing.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"request-sizing.js","sourceRoot":"","sources":["../src/request-sizing.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,17 @@
1
+ /** Conservative filesystem boundary for optional transcript repair. */
2
+ import fs from "node:fs";
3
+ /** Possible writers include Claude binaries and JS runtimes; uncertainty skips repair. */
4
+ export declare function transcriptIsQuiescent(file: string): boolean;
5
+ interface Replacement {
6
+ file: string;
7
+ original: Buffer;
8
+ snapshot: fs.BigIntStats;
9
+ replacement: string;
10
+ backupDir: string;
11
+ sessionId: string;
12
+ now?: Date;
13
+ quiescent: (file: string) => boolean;
14
+ }
15
+ export declare function replaceQuiescentTranscript(input: Replacement): string | undefined;
16
+ export {};
17
+ //# sourceMappingURL=resume-repair-file.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resume-repair-file.d.ts","sourceRoot":"","sources":["../src/resume-repair-file.ts"],"names":[],"mappings":"AAAA,uEAAuE;AACvE,OAAO,EAAE,MAAM,SAAS,CAAC;AAKzB,0FAA0F;AAC1F,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAqB3D;AAED,UAAU,WAAW;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,EAAE,CAAC,WAAW,CAAC;IACzB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,GAAG,CAAC,EAAE,IAAI,CAAC;IACX,SAAS,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC;CACtC;AAED,wBAAgB,0BAA0B,CAAC,KAAK,EAAE,WAAW,GAAG,MAAM,GAAG,SAAS,CA4BjF"}
@@ -0,0 +1,100 @@
1
+ /** Conservative filesystem boundary for optional transcript repair. */
2
+ import fs from "node:fs";
3
+ import path from "node:path";
4
+ import { randomUUID } from "node:crypto";
5
+ import { execFileSync } from "node:child_process";
6
+ /** Possible writers include Claude binaries and JS runtimes; uncertainty skips repair. */
7
+ export function transcriptIsQuiescent(file) {
8
+ try {
9
+ const processes = execFileSync("ps", ["-axo", "pid=,comm="], {
10
+ encoding: "utf8", timeout: 1000, stdio: ["ignore", "pipe", "ignore"],
11
+ });
12
+ if (!processes.trim())
13
+ return false;
14
+ for (const line of processes.trim().split("\n")) {
15
+ const match = line.trim().match(/^(\d+)\s+(.+)$/);
16
+ if (!match)
17
+ return false;
18
+ if (Number(match[1]) === process.pid)
19
+ continue;
20
+ if (/(?:claude|(?:^|\/)(?:node|bun|deno)(?:\s|$))/i.test(match[2]))
21
+ return false;
22
+ }
23
+ try {
24
+ execFileSync("lsof", ["-t", "--", file], {
25
+ timeout: 1000, stdio: ["ignore", "pipe", "ignore"],
26
+ });
27
+ return false; // Any open descriptor means a possible writer.
28
+ }
29
+ catch (error) {
30
+ return error?.status === 1 && !error.signal && error.stdout?.length === 0;
31
+ }
32
+ }
33
+ catch {
34
+ return false;
35
+ }
36
+ }
37
+ export function replaceQuiescentTranscript(input) {
38
+ const { file, original, snapshot, quiescent } = input;
39
+ const lock = `${file}.ccc-repair.lock`;
40
+ const temp = `${file}.ccc-${randomUUID()}.tmp`;
41
+ let locked = false;
42
+ let temporary = false;
43
+ try {
44
+ const lockFd = fs.openSync(lock, "wx", 0o600);
45
+ locked = true;
46
+ fs.closeSync(lockFd);
47
+ if (!quiescent(file) || !unchanged(file, snapshot, original))
48
+ return undefined;
49
+ fs.mkdirSync(input.backupDir, { recursive: true });
50
+ const stamp = (input.now ?? new Date()).toISOString().replace(/[:.]/g, "-");
51
+ const backup = path.join(input.backupDir, `${input.sessionId}.${stamp}.${randomUUID()}.jsonl`);
52
+ writeExclusive(backup, original, 0o600);
53
+ const fd = fs.openSync(temp, "wx", Number(snapshot.mode & 511n));
54
+ temporary = true;
55
+ try {
56
+ fs.writeFileSync(fd, input.replacement);
57
+ fs.fsyncSync(fd);
58
+ }
59
+ finally {
60
+ fs.closeSync(fd);
61
+ }
62
+ if (!quiescent(file) || !unchanged(file, snapshot, original))
63
+ return undefined;
64
+ fs.renameSync(temp, file);
65
+ temporary = false;
66
+ return backup;
67
+ }
68
+ catch {
69
+ return undefined;
70
+ }
71
+ finally {
72
+ if (temporary)
73
+ try {
74
+ fs.unlinkSync(temp);
75
+ }
76
+ catch { /* best effort */ }
77
+ if (locked)
78
+ try {
79
+ fs.unlinkSync(lock);
80
+ }
81
+ catch { /* best effort */ }
82
+ }
83
+ }
84
+ function writeExclusive(file, contents, mode) {
85
+ const fd = fs.openSync(file, "wx", mode);
86
+ try {
87
+ fs.writeFileSync(fd, contents);
88
+ fs.fsyncSync(fd);
89
+ }
90
+ finally {
91
+ fs.closeSync(fd);
92
+ }
93
+ }
94
+ function unchanged(file, expected, original) {
95
+ const actual = fs.lstatSync(file, { bigint: true });
96
+ return actual.isFile() && actual.nlink === 1n &&
97
+ ["ino", "dev", "size", "mtimeNs", "ctimeNs"].every(key => actual[key] === expected[key]) &&
98
+ fs.readFileSync(file).equals(original);
99
+ }
100
+ //# sourceMappingURL=resume-repair-file.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resume-repair-file.js","sourceRoot":"","sources":["../src/resume-repair-file.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,27 @@
1
+ /** Unknown versions use the full window: never the former speculative 90%. */
2
+ export declare const STRANDED_WINDOW_FRACTION = 1;
3
+ export declare const LOWERED_WINDOW_FRACTION = 0.5;
4
+ export interface ResumeRepair {
5
+ sessionId: string;
6
+ recordedTokens: number;
7
+ loweredTokens: number;
8
+ backupPath: string;
9
+ }
10
+ export interface ResumeRepairOptions {
11
+ nativeOneMillionContext: boolean;
12
+ projectsDir?: string;
13
+ backupDir?: string;
14
+ now?: Date;
15
+ claudeVersion?: string;
16
+ /** Injectable process check; production refuses if any possible writer exists. */
17
+ isQuiescent?: (file: string) => boolean;
18
+ }
19
+ export declare function repairStrandedResume(claudeArgs: string[], options: ResumeRepairOptions): ResumeRepair | undefined;
20
+ export declare function resumeSessionId(args: string[]): string | undefined;
21
+ export interface UsageRepairPlan {
22
+ lineIndexes: number[];
23
+ recordedTokens: number;
24
+ loweredTokens: number;
25
+ }
26
+ export declare function planUsageRepair(lines: string[], nativeOneMillionContext: boolean, claudeVersion?: string, modelOverride?: string): UsageRepairPlan | undefined;
27
+ //# sourceMappingURL=resume-repair.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resume-repair.d.ts","sourceRoot":"","sources":["../src/resume-repair.ts"],"names":[],"mappings":"AAaA,8EAA8E;AAC9E,eAAO,MAAM,wBAAwB,IAAI,CAAC;AAC1C,eAAO,MAAM,uBAAuB,MAAM,CAAC;AAE3C,MAAM,WAAW,YAAY;IAC3B,SAAS,EAAE,MAAM,CAAC;IAClB,cAAc,EAAE,MAAM,CAAC;IACvB,aAAa,EAAE,MAAM,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,mBAAmB;IAClC,uBAAuB,EAAE,OAAO,CAAC;IACjC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,GAAG,CAAC,EAAE,IAAI,CAAC;IACX,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,kFAAkF;IAClF,WAAW,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC;CACzC;AAED,wBAAgB,oBAAoB,CAClC,UAAU,EAAE,MAAM,EAAE,EAAE,OAAO,EAAE,mBAAmB,GACjD,YAAY,GAAG,SAAS,CA2B1B;AAED,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,MAAM,GAAG,SAAS,CAQlE;AAED,MAAM,WAAW,eAAe;IAC9B,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,cAAc,EAAE,MAAM,CAAC;IACvB,aAAa,EAAE,MAAM,CAAC;CACvB;AAED,wBAAgB,eAAe,CAC7B,KAAK,EAAE,MAAM,EAAE,EAAE,uBAAuB,EAAE,OAAO,EAAE,aAAa,SAAY,EAC5E,aAAa,CAAC,EAAE,MAAM,GACrB,eAAe,GAAG,SAAS,CAmC7B"}
@@ -0,0 +1,198 @@
1
+ /**
2
+ * Repair only a demonstrably stranded resume, before Claude starts. Unknown
3
+ * shapes, concurrent writers and filesystem errors leave the resume unchanged.
4
+ * Only the final response's totals and Claude's counted iteration are lowered.
5
+ */
6
+ import fs from "node:fs";
7
+ import path from "node:path";
8
+ import { execFileSync } from "node:child_process";
9
+ import { getConfigDir } from "./config.js";
10
+ import { defaultProjectsDir, findTranscript } from "./transcript-usage.js";
11
+ import { contextLimitForModel } from "./turns.js";
12
+ import { replaceQuiescentTranscript, transcriptIsQuiescent } from "./resume-repair-file.js";
13
+ /** Unknown versions use the full window: never the former speculative 90%. */
14
+ export const STRANDED_WINDOW_FRACTION = 1;
15
+ export const LOWERED_WINDOW_FRACTION = 0.5;
16
+ export function repairStrandedResume(claudeArgs, options) {
17
+ try {
18
+ const sessionId = resumeSessionId(claudeArgs);
19
+ if (!sessionId)
20
+ return undefined;
21
+ const file = findTranscript(options.projectsDir ?? defaultProjectsDir(), sessionId);
22
+ if (!file)
23
+ return undefined;
24
+ const quiescent = options.isQuiescent ?? transcriptIsQuiescent;
25
+ if (!quiescent(file) || !fs.lstatSync(file).isFile())
26
+ return undefined;
27
+ const snapshot = fs.statSync(file, { bigint: true });
28
+ const original = fs.readFileSync(file);
29
+ const lines = original.toString("utf8").split("\n");
30
+ if (!Buffer.from(lines.join("\n"), "utf8").equals(original))
31
+ return undefined;
32
+ const plan = planUsageRepair(lines, options.nativeOneMillionContext, options.claudeVersion ?? installedVersion(), resumeModelOverride(claudeArgs));
33
+ if (!plan)
34
+ return undefined;
35
+ for (const index of plan.lineIndexes)
36
+ lines[index] = lowerUsage(lines[index], plan.loweredTokens);
37
+ const backupPath = replaceQuiescentTranscript({
38
+ file, original, snapshot, replacement: lines.join("\n"), quiescent,
39
+ backupDir: options.backupDir ?? path.join(getConfigDir(), "transcript-backups"),
40
+ sessionId, now: options.now,
41
+ });
42
+ return backupPath ? { sessionId, recordedTokens: plan.recordedTokens,
43
+ loweredTokens: plan.loweredTokens, backupPath } : undefined;
44
+ }
45
+ catch {
46
+ // Repair is optional: no error may prevent launching the original resume.
47
+ return undefined;
48
+ }
49
+ }
50
+ export function resumeSessionId(args) {
51
+ for (let i = 0; i < args.length; i++) {
52
+ const arg = args[i];
53
+ if (arg === "--")
54
+ return undefined;
55
+ if (arg.startsWith("--resume="))
56
+ return validId(arg.slice("--resume=".length));
57
+ if (arg === "--resume" || arg === "-r")
58
+ return validId(args[i + 1]);
59
+ }
60
+ return undefined;
61
+ }
62
+ export function planUsageRepair(lines, nativeOneMillionContext, claudeVersion = "unknown", modelOverride) {
63
+ try {
64
+ const entries = lines.map(line => line.trim() ? JSON.parse(line) : undefined);
65
+ if (entries.some(e => e !== undefined && !record(e)))
66
+ return undefined;
67
+ const last = entries.findLast(e => e?.type === "assistant" && e?.message?.model !== "<synthetic>");
68
+ const message = last?.message;
69
+ if (!knownMessage(message))
70
+ return undefined;
71
+ const window = resumedWindow(entries, message.model, nativeOneMillionContext, modelOverride);
72
+ if (window === undefined)
73
+ return undefined;
74
+ const counted = countedUsage(message.usage);
75
+ const recordedInput = counted.input_tokens + counted.cache_read_input_tokens +
76
+ counted.cache_creation_input_tokens;
77
+ // A successful response already accepted this input. A smaller inferred
78
+ // window is disproven by the transcript, not evidence that it needs repair.
79
+ if (!Number.isSafeInteger(recordedInput) || recordedInput > window)
80
+ return undefined;
81
+ // 2.1.288's ode/RPe -> kvt: contextWindow - min(maxOutputTokens, 20000) - 3000.
82
+ // These supported model families all have >=20k output capacity. Overrides
83
+ // make the threshold uncertain, so automatic repair is skipped entirely.
84
+ if (process.env.CLAUDE_CODE_BLOCKING_LIMIT_OVERRIDE !== undefined ||
85
+ process.env.CLAUDE_CODE_MAX_OUTPUT_TOKENS !== undefined)
86
+ return undefined;
87
+ const threshold = claudeVersion === "2.1.288" ? window - 23_000 : window;
88
+ const recordedTokens = recordedSize(message.usage);
89
+ const loweredTokens = Math.floor(window * LOWERED_WINDOW_FRACTION);
90
+ if (recordedTokens === undefined || recordedTokens < threshold)
91
+ return undefined;
92
+ const lineIndexes = [];
93
+ for (let i = 0; i < entries.length; i++) {
94
+ const m = entries[i]?.type === "assistant" ? entries[i].message : undefined;
95
+ if (m?.id !== message.id)
96
+ continue;
97
+ if (!knownMessage(m) || m.model !== message.model ||
98
+ recordedSize(m.usage) !== recordedTokens ||
99
+ loweredTokens + countedUsage(m.usage).output_tokens >= threshold)
100
+ return undefined;
101
+ lineIndexes.push(i);
102
+ }
103
+ return { lineIndexes, recordedTokens, loweredTokens };
104
+ }
105
+ catch {
106
+ return undefined;
107
+ }
108
+ }
109
+ const BUCKETS = ["input_tokens", "cache_read_input_tokens", "cache_creation_input_tokens", "output_tokens"];
110
+ const KINDS = new Set(["message", "fallback_message", "advisor_message", "compaction"]);
111
+ const KNOWN_MODEL = /^claude-(?:opus-(?:4-[56]|5-5)|sonnet-4-[56])(?:-\d{8})?(?:\[1m\])?$/;
112
+ function resumeModelOverride(args) {
113
+ let model = process.env.ANTHROPIC_MODEL;
114
+ for (let i = 0; i < args.length && args[i] !== "--"; i++) {
115
+ if (args[i].startsWith("--model="))
116
+ model = args[i].slice("--model=".length);
117
+ else if (args[i] === "--model")
118
+ model = args[++i] ?? "";
119
+ }
120
+ return model;
121
+ }
122
+ function resumedWindow(entries, model, nativeOneMillionContext, override) {
123
+ // Aliases and future/custom model names cannot establish an exact window.
124
+ if (override !== undefined && !KNOWN_MODEL.test(override))
125
+ return undefined;
126
+ const window = contextLimitForModel(model, undefined, nativeOneMillionContext);
127
+ const overrideWindow = override === undefined ? window :
128
+ contextLimitForModel(override, undefined, nativeOneMillionContext);
129
+ // Historical explicit 1M selection remains evidence even when Claude strips
130
+ // the suffix from subsequent wire responses. Taking the larger window is
131
+ // conservative: it can skip a repair, never cause an otherwise fitting repair.
132
+ const recordedOneMillion = entries.some(e => [e?.model, e?.message?.model].some(m => typeof m === "string" && m.endsWith("[1m]")));
133
+ return Math.max(window, overrideWindow, recordedOneMillion ? 1_000_000 : 0);
134
+ }
135
+ function record(value) {
136
+ return value !== null && typeof value === "object" && !Array.isArray(value);
137
+ }
138
+ function knownMessage(message) {
139
+ return record(message) && typeof message.id === "string" && message.id.length > 0 &&
140
+ typeof message.model === "string" &&
141
+ KNOWN_MODEL.test(message.model) &&
142
+ validUsage(message.usage);
143
+ }
144
+ function validBuckets(value) {
145
+ return record(value) && BUCKETS.every(key => Number.isSafeInteger(value[key]) && value[key] >= 0) &&
146
+ (value.cache_creation === undefined || (record(value.cache_creation) &&
147
+ Object.values(value.cache_creation).every(n => Number.isSafeInteger(n) && n >= 0)));
148
+ }
149
+ function validUsage(usage) {
150
+ if (!validBuckets(usage))
151
+ return false;
152
+ if (usage.iterations === undefined)
153
+ return true;
154
+ return Array.isArray(usage.iterations) && usage.iterations.length > 0 &&
155
+ usage.iterations.every((it) => validBuckets(it) && KINDS.has(it.type)) &&
156
+ usage.iterations.some((it) => it.type === "message" || it.type === "fallback_message");
157
+ }
158
+ function countedUsage(usage) {
159
+ return usage.iterations?.findLast((it) => it.type !== "advisor_message" && it.type !== "compaction") ?? usage;
160
+ }
161
+ function recordedSize(usage) {
162
+ if (!validUsage(usage))
163
+ return undefined;
164
+ const counted = countedUsage(usage);
165
+ const total = BUCKETS.reduce((n, key) => n + counted[key], 0);
166
+ return Number.isSafeInteger(total) ? total : undefined;
167
+ }
168
+ function lowerUsage(line, loweredTokens) {
169
+ const entry = JSON.parse(line);
170
+ const usage = entry.message.usage;
171
+ const counted = countedUsage(usage);
172
+ lowerBuckets(usage, loweredTokens);
173
+ if (counted !== usage)
174
+ lowerBuckets(counted, loweredTokens);
175
+ return JSON.stringify(entry);
176
+ }
177
+ function lowerBuckets(usage, loweredTokens) {
178
+ usage.input_tokens = loweredTokens;
179
+ usage.cache_read_input_tokens = 0;
180
+ usage.cache_creation_input_tokens = 0;
181
+ if (usage.cache_creation) {
182
+ for (const key of Object.keys(usage.cache_creation))
183
+ usage.cache_creation[key] = 0;
184
+ }
185
+ }
186
+ function installedVersion() {
187
+ try {
188
+ return execFileSync("claude", ["--version"], { encoding: "utf8", timeout: 1500,
189
+ stdio: ["ignore", "pipe", "ignore"] }).match(/^(\d+\.\d+\.\d+)\b/)?.[1] ?? "unknown";
190
+ }
191
+ catch {
192
+ return "unknown";
193
+ }
194
+ }
195
+ function validId(value) {
196
+ return value !== undefined && /^[A-Za-z0-9][A-Za-z0-9-]*$/.test(value) ? value : undefined;
197
+ }
198
+ //# sourceMappingURL=resume-repair.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resume-repair.js","sourceRoot":"","sources":["../src/resume-repair.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ /** Keep stored prefix messages byte-identical while fitting Anthropic's marker cap. */
2
+ export declare function capCacheBreakpoints(body: Record<string, any>, prefixLength: number, options?: {
3
+ preserveSystem?: boolean;
4
+ }): boolean;
5
+ //# sourceMappingURL=route-cache.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"route-cache.d.ts","sourceRoot":"","sources":["../src/route-cache.ts"],"names":[],"mappings":"AAIA,uFAAuF;AACvF,wBAAgB,mBAAmB,CACjC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EACzB,YAAY,EAAE,MAAM,EACpB,OAAO,GAAE;IAAE,cAAc,CAAC,EAAE,OAAO,CAAA;CAAO,GACzC,OAAO,CAgBT"}
@@ -0,0 +1,63 @@
1
+ const MAX_CACHE_BREAKPOINTS = 4;
2
+ /** Keep stored prefix messages byte-identical while fitting Anthropic's marker cap. */
3
+ export function capCacheBreakpoints(body, prefixLength, options = {}) {
4
+ const slots = cacheSlots(body);
5
+ const excess = slots.length - MAX_CACHE_BREAKPOINTS;
6
+ if (excess <= 0)
7
+ return true;
8
+ const suffix = slots.filter((slot) => slot.message !== undefined && slot.message >= prefixLength);
9
+ const latest = suffix.at(-1);
10
+ const removable = [
11
+ ...suffix.filter((slot) => slot !== latest),
12
+ ...slots.filter((slot) => slot.field === "system" && !options.preserveSystem),
13
+ ...slots.filter((slot) => slot.field === "tools"),
14
+ ...(latest ? [latest] : []),
15
+ ];
16
+ // Refuse the candidate before changing anything if its protected part won't fit.
17
+ if (removable.length < excess)
18
+ return false;
19
+ removeMarkers(body, removable.slice(0, excess));
20
+ return true;
21
+ }
22
+ function cacheSlots(body) {
23
+ const slots = [];
24
+ const add = (blocks, where) => {
25
+ if (!Array.isArray(blocks))
26
+ return;
27
+ blocks.forEach((block, index) => {
28
+ if (block && typeof block === "object" && block.cache_control) {
29
+ slots.push({ blocks, index, ...where });
30
+ }
31
+ });
32
+ };
33
+ add(body.tools, { field: "tools" });
34
+ add(body.system, { field: "system" });
35
+ if (Array.isArray(body.messages)) {
36
+ body.messages.forEach((message, index) => add(message?.content, { message: index }));
37
+ }
38
+ return slots;
39
+ }
40
+ /** Copy suffix objects as well: they can share immutable incoming request objects. */
41
+ function removeMarkers(body, removed) {
42
+ const indices = new Map();
43
+ for (const slot of removed) {
44
+ const set = indices.get(slot.blocks) ?? new Set();
45
+ set.add(slot.index);
46
+ indices.set(slot.blocks, set);
47
+ }
48
+ const clean = (blocks) => blocks.map((block, index) => {
49
+ if (!indices.get(blocks)?.has(index))
50
+ return block;
51
+ const { cache_control: _ignored, ...rest } = block;
52
+ return rest;
53
+ });
54
+ for (const field of ["system", "tools"]) {
55
+ if (indices.has(body[field]))
56
+ body[field] = clean(body[field]);
57
+ }
58
+ if (Array.isArray(body.messages)) {
59
+ body.messages = body.messages.map((message) => indices.has(message?.content)
60
+ ? { ...message, content: clean(message.content) } : message);
61
+ }
62
+ }
63
+ //# sourceMappingURL=route-cache.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"route-cache.js","sourceRoot":"","sources":["../src/route-cache.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,29 @@
1
+ /** After attempting compression at the soft budget, forward input that fits
2
+ * the model's native context together with its output reservation. */
3
+ export declare function fitsFallbackBudget(inputTokens: number, outputTokens: number, budgetTokens: number, contextTokens: number): boolean;
4
+ export interface RouteFallbackError {
5
+ status: 503 | 400;
6
+ attempt: number;
7
+ headers: Record<string, string>;
8
+ body: {
9
+ type: "error";
10
+ error: {
11
+ type: string;
12
+ message: string;
13
+ };
14
+ };
15
+ }
16
+ /**
17
+ * Claude Code 2.1.288 retries 503 itself, even with SDK maxRetries=0.
18
+ * 529 has extra overload handling (including indefinite watchdog retries).
19
+ * Use ordinary 503 retries and bound the episode in the proxy itself.
20
+ * Successful delivery ends an episode; hook events and elapsed time do not.
21
+ */
22
+ export declare class RouteFallbackFailures {
23
+ private readonly capacity;
24
+ private readonly failures;
25
+ constructor(capacity?: number);
26
+ fail(lane: string): RouteFallbackError;
27
+ succeeded(lane: string): void;
28
+ }
29
+ //# sourceMappingURL=route-fallback.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"route-fallback.d.ts","sourceRoot":"","sources":["../src/route-fallback.ts"],"names":[],"mappings":"AAAA;sEACsE;AACtE,wBAAgB,kBAAkB,CAChC,WAAW,EAAE,MAAM,EACnB,YAAY,EAAE,MAAM,EACpB,YAAY,EAAE,MAAM,EACpB,aAAa,EAAE,MAAM,GACpB,OAAO,CAIT;AAED,MAAM,WAAW,kBAAkB;IACjC,MAAM,EAAE,GAAG,GAAG,GAAG,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAChC,IAAI,EAAE;QAAE,IAAI,EAAE,OAAO,CAAC;QAAC,KAAK,EAAE;YAAE,IAAI,EAAE,MAAM,CAAC;YAAC,OAAO,EAAE,MAAM,CAAA;SAAE,CAAA;KAAE,CAAC;CACnE;AAED;;;;;GAKG;AACH,qBAAa,qBAAqB;IAGpB,OAAO,CAAC,QAAQ,CAAC,QAAQ;IAFrC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAA6B;gBAEzB,QAAQ,SAAM;IAE3C,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,kBAAkB;IA4BtC,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;CAG9B"}