claude-code-infinite 1.0.11 → 1.0.16

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 +214 -47
  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 -178
  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 +430 -0
  73. package/dist/memtree.d.ts.map +1 -0
  74. package/dist/memtree.js +1286 -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 +204 -0
  93. package/dist/proxy.d.ts.map +1 -0
  94. package/dist/proxy.js +4299 -0
  95. package/dist/proxy.js.map +1 -0
  96. package/dist/reqlog.d.ts +427 -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 +74 -0
  101. package/dist/request-sizing.d.ts.map +1 -0
  102. package/dist/request-sizing.js +121 -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 +67 -0
  117. package/dist/route-fallback.d.ts.map +1 -0
  118. package/dist/route-fallback.js +126 -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 +77 -0
  129. package/dist/turns.d.ts.map +1 -0
  130. package/dist/turns.js +330 -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,430 @@
1
+ /**
2
+ * Client for the polychat.co MemTree API (/v1/context_memory).
3
+ *
4
+ * Two modes, mirroring the server's lazy-compression path (cc_api.py):
5
+ * - Tool turns: fire-and-forget indexing POST, off the response path.
6
+ * - User turns: blocking compression call with a hard timeout; the caller
7
+ * degrades to transparent pass-through on any failure (including 402 —
8
+ * compression is the paid feature, the user's own Anthropic call is never
9
+ * gated on it). A 402 from either mode additionally records
10
+ * payment-required state (paymentRequiredDetail) so the proxy can tell the
11
+ * user WHY MemTree is off instead of implying a transient outage; any later
12
+ * successful call clears it (the user paid mid-session).
13
+ *
14
+ * Compression work is deduped per complete request key, while background
15
+ * indexing is deduped per messages hash. Claude Code retries therefore cannot
16
+ * amplify identical HTTP calls, and budget-changing inputs never reuse a
17
+ * stale compression result.
18
+ */
19
+ import { type FinalReplyReader } from "./final-index.js";
20
+ import type { MessageTimes, MessageUsage } from "./transcript-usage.js";
21
+ import type { RequestLogSink } from "./reqlog.js";
22
+ import { type Message } from "./turns.js";
23
+ export declare const CLIENT_NAME = "cc-infinite";
24
+ export declare const CLIENT_VERSION: string;
25
+ /**
26
+ * A main-lane Stop followed by this long without a new request is taken as the
27
+ * session's end, and its final index goes out (exit sends it at once). Shorter
28
+ * pauses spend the server's once-per-30-minutes final index mid-session.
29
+ */
30
+ export declare const FINAL_INDEX_IDLE_MS: number;
31
+ /** Sessions finalized at exit at most (newest first), inside the 2 s drain. */
32
+ export declare const FINAL_INDEX_EXIT_SESSIONS = 3;
33
+ export interface MemtreeOptions {
34
+ baseUrl: string;
35
+ apiKey: string;
36
+ compressTimeoutMs?: number;
37
+ debug?: boolean;
38
+ /** Always-on JSONL diagnostics; every MemTree call logs one line. */
39
+ reqlog?: RequestLogSink;
40
+ /**
41
+ * `x-memtree-tools` on compress calls: the memtree MCP tools this Claude
42
+ * Code session has (e.g. "search,read_node,read_lines"), so the server can
43
+ * tell the model how to use them in the memory it returns. Set only when
44
+ * the `memtree` MCP server is configured for the session (memtree-mcp-config.ts).
45
+ */
46
+ memtreeTools?: string;
47
+ }
48
+ /**
49
+ * Request metadata forwarded to the server so it can resolve a model-based
50
+ * memory budget (e.g. the 800k whole-request target for Fable / Opus 5).
51
+ * Without `model` the server can only apply its static 50k fallback.
52
+ */
53
+ export interface CompressRequestMeta {
54
+ model?: string;
55
+ tools?: unknown[];
56
+ /**
57
+ * Explicit whole-request target (server `compression_target_tokens`),
58
+ * overriding the model-based budget. Set by `/memtree-compact` so a session
59
+ * is compressed even while it would still fit the model's window.
60
+ */
61
+ compressionTargetTokens?: number;
62
+ /**
63
+ * Server `compression_threshold_tokens`: compress only when the whole
64
+ * request exceeds this many tokens, and then to `compressionTargetTokens`.
65
+ * Without it the target is also the threshold. Servers that predate the
66
+ * field ignore it (they also omit `model_budget_tokens`, which is how the
67
+ * proxy tells them apart).
68
+ */
69
+ compressionThresholdTokens?: number;
70
+ /**
71
+ * Server `client_input_tokens`: the proxy's own estimate of the request's
72
+ * input tokens, the one its fallback gate refuses over-budget input by.
73
+ * Over the budget, the server compresses even when its char estimate says
74
+ * the request fits, so the two cannot disagree into a stuck session
75
+ * (2026-10-05). Part of the cache key: a different estimate can flip the
76
+ * server's verdict for the same messages.
77
+ */
78
+ clientInputTokens?: number;
79
+ /**
80
+ * Each assistant message's response usage (output, thinking, input), keyed
81
+ * by its position in the messages sent. Archived by the server for the
82
+ * MemTree page; never hashed, never part of the compression cache key.
83
+ */
84
+ messageUsage?: MessageUsage;
85
+ /**
86
+ * When Claude Code wrote each message (ISO), keyed like messageUsage. The
87
+ * server records a time range per MemTree input block; never hashed, never
88
+ * part of the compression cache key.
89
+ */
90
+ messageTimes?: MessageTimes;
91
+ /**
92
+ * Claude Code's session id, sent as `x-claude-code-session-id` so the
93
+ * server can list a session's MemTree pages by it. Also scopes cached pages.
94
+ */
95
+ sessionId?: string;
96
+ /** Sent as `x-client-meta`; stored on the usage row. Not part of the cache key. */
97
+ clientMeta?: Record<string, string>;
98
+ }
99
+ export interface CompressResult {
100
+ /** Processed (compressed) messages from the server; system role may be included. */
101
+ messages: Message[];
102
+ /**
103
+ * The server-side flatten of `messages`: exactly one user message whose
104
+ * string content is the whole compressed conversation, produced by the
105
+ * server's `flatten_to_single_user_message` (the single implementation of
106
+ * the flatten format). Returned when the request asked for `flatten: true`;
107
+ * pre-flatten servers omit it. The client treats these bytes as opaque —
108
+ * it no longer has a flatten of its own — so a result without this field
109
+ * cannot be forwarded compressed (see serverFlattenedMessages).
110
+ */
111
+ flattened_messages?: Message[];
112
+ /**
113
+ * Explicit server verdict on whether the conversation was rewritten. False
114
+ * on a passthrough (request already under the model budget, or no index
115
+ * yet), where `messages` is the conversation as-is and the server also
116
+ * omits `flattened_messages`. Older servers omit this field; callers fall
117
+ * back to the cached_tokens heuristic (see didMemtreeCompress).
118
+ */
119
+ compressed?: boolean;
120
+ /**
121
+ * The model's whole-request budget the server computed (tokens), whatever
122
+ * target the request set. Servers that predate it omit the field.
123
+ */
124
+ model_budget_tokens?: number;
125
+ /**
126
+ * Optional explicit unfolded index, consumed only by the memoryChars
127
+ * reqlog diagnostic. Older servers omit it; callers fall back to the first
128
+ * non-system processed message, which is the current server layout.
129
+ */
130
+ unfolded_memory?: string;
131
+ usage?: unknown;
132
+ /** Client-observed latency of the underlying HTTP call (survives retry dedupe). */
133
+ clientLatencyMs?: number;
134
+ /**
135
+ * The per-request MemTree page (`X-Polychat-Memtree-Url`), when the server
136
+ * sent one. `.json` on the same path is the machine-readable tree.
137
+ */
138
+ memtreeUrl?: string;
139
+ /**
140
+ * The completed index this turn was compressed against
141
+ * (`X-Polychat-Memtree-Index`); absent on index-only acks and servers that
142
+ * predate it. A new value means a new index finished and is now in use.
143
+ */
144
+ memtreeIndex?: string;
145
+ /**
146
+ * Proposed server field: true when messages in this request are not yet in
147
+ * the tree it answered from and an indexing job will cover them. Absent on
148
+ * current servers, which then report no lag (see indexBehind).
149
+ */
150
+ index_pending?: boolean;
151
+ }
152
+ /**
153
+ * The server-flattened single user message of a compressed result, or null
154
+ * when the server did not provide a valid one (a pre-flatten server, or a
155
+ * malformed field). The flatten format lives server-side ONLY — the client
156
+ * must never re-derive or post-process it — so a null here means the result
157
+ * cannot be forwarded in compressed form and the caller degrades to the
158
+ * original history. Returns a fresh single-message array so callers may
159
+ * embed it in a request body without sharing structure with the result.
160
+ */
161
+ export declare function serverFlattenedMessages(result: CompressResult): Message[] | null;
162
+ /**
163
+ * Whether the server actually rewrote the conversation. A successful
164
+ * context_memory response is not enough: the endpoint returns the messages
165
+ * as-is while an index is still warming AND whenever the request already fits
166
+ * the model budget. The server's explicit `compressed` verdict is
167
+ * authoritative. The cached_tokens fallback only covers servers that predate
168
+ * it: cached_tokens is a billing prediction, not a compression signal, and is
169
+ * > 0 on most under-budget passthroughs — so on such servers those turns are
170
+ * flattened and Anthropic's prefix cache misses every human turn.
171
+ */
172
+ export declare function didMemtreeCompress(result: CompressResult): boolean;
173
+ /**
174
+ * Number of original prompt tokens covered by the index MemTree selected.
175
+ *
176
+ * Prefers `usage.indexed_tokens`: since 2026-10-04 the server bills a
177
+ * passthrough's covered input at nothing, so `cached_tokens` is 0 there even
178
+ * when a tree covers the prompt. Older servers only send `cached_tokens`.
179
+ */
180
+ export declare function cachedPromptTokenCount(result: CompressResult): number | undefined;
181
+ /**
182
+ * Whether the server says its index trails this conversation (`index_pending`):
183
+ * unindexed messages stay verbatim, so a compress once indexing catches up can
184
+ * shrink what this one could not. Usage counters cannot say this —
185
+ * `indexed_tokens` is a billing figure that counts a still-running job as
186
+ * covered — so a server without the field reports no lag.
187
+ */
188
+ export declare function indexBehind(result: CompressResult): boolean;
189
+ /**
190
+ * Evidence that MemTree's index has not caught up with this conversation:
191
+ * the server says so, or it passed the conversation through with nothing
192
+ * indexed and a page for the tree it is building.
193
+ */
194
+ export declare function indexLagEvidence(result: CompressResult): boolean;
195
+ /** The server-reported model budget, when present and sane. */
196
+ export declare function modelBudgetTokens(result: CompressResult): number | undefined;
197
+ /**
198
+ * MemTree's informational estimate of the original, pre-consolidation prompt.
199
+ * Newer servers include images as visual-token estimates and deliberately keep
200
+ * this value separate from billable Context Memory usage.
201
+ */
202
+ export declare function rawPromptTokenCount(result: CompressResult): number | undefined;
203
+ /**
204
+ * Minimum conversation content, beyond any verbatim echo of the current turn,
205
+ * that a compressed response must carry before we will send it to Anthropic in
206
+ * place of the real history.
207
+ *
208
+ * Sized well below any useful memory (the server's own semantic floor is 15k
209
+ * chars) and well above an empty answer, so this fires only on genuine context
210
+ * loss and never on a legitimately aggressive compression.
211
+ */
212
+ export declare const MIN_RETAINED_HISTORY_CHARS = 2000;
213
+ export interface CompressedHistoryCheck {
214
+ /** Flattened conversation characters, falling back to structured messages. */
215
+ retainedChars: number;
216
+ /** Characters in the turn that prompted this request (as sent). */
217
+ currentTurnChars: number;
218
+ /** Non-system characters of prior conversation we asked it to compress. */
219
+ priorHistoryChars: number;
220
+ /** False when the response carries no usable prior conversation. */
221
+ usable: boolean;
222
+ }
223
+ /**
224
+ * Decide whether a compressed response still contains the conversation.
225
+ *
226
+ * This is deliberately NOT derived from `usage`. Every usage-derived signal —
227
+ * `cached_tokens` and the `raw - cached` tail — measures how much of the prompt
228
+ * the server's INDEX covered, not how much context it put in the response. A
229
+ * server that indexes every message and then allocates zero characters to
230
+ * memory (because fixed system+tool overhead exceeded its whole-request budget)
231
+ * reports perfect coverage while returning nothing at all, and the tail metric
232
+ * scores that empty answer as the best possible result. Only the body itself
233
+ * says what the model will actually see.
234
+ *
235
+ * "Retained prior conversation" is measured as the result's conversation
236
+ * characters minus only the part that verbatim-echoes the SENT current turn —
237
+ * not minus the current turn's full size. A turn the server itself shrank
238
+ * (e.g. a 100k-char pasted log returned as a 5k summary) leaves no verbatim
239
+ * echo, so its compressed rendering counts as retained context instead of
240
+ * sinking the score below zero and disabling compression on exactly the turns
241
+ * that need it. The failure the floor exists to catch — the server echoing the
242
+ * current turn back with essentially nothing of the prior conversation — still
243
+ * scores ~0, because every verbatim echo (whole, truncated, or embedded in a
244
+ * larger message) is fully subtracted, and a double echo — the turn embedded
245
+ * in the memory block AND replayed as the tail, or carried twice within one
246
+ * memory blob — is charged for every copy rather than netting out to a
247
+ * single turn's worth of "retained" text. An echo fragmented across
248
+ * consecutive text blocks is caught by re-checking each run of adjacent
249
+ * plain-text pieces as one coalesced passage. Fragments below a small length
250
+ * floor are never counted as echo, so a turn that quotes prior messages
251
+ * cannot sink the genuine memory that contains those same fragments. A rewritten-but-still-empty answer can
252
+ * in principle slip through; the trade is deliberate, since rewriting proves
253
+ * the server did compression work rather than dropping context.
254
+ */
255
+ export declare function checkCompressedHistory(result: CompressResult, sentMessages: Message[], minRetainedChars?: number): CompressedHistoryCheck;
256
+ /**
257
+ * Remove model-specific reasoning blocks from the copy sent to MemTree.
258
+ *
259
+ * Claude Code does not reliably replay prior-turn thinking after a model
260
+ * change or process resume. Thinking text, redacted payloads, and signatures
261
+ * are required when present in the live Anthropic request, but none is stable
262
+ * conversation identity for indexing.
263
+ *
264
+ * Scope this narrowly to assistant thinking blocks. A field named `signature`
265
+ * inside tool input/result data can be real user data and must remain intact.
266
+ * The original request is never mutated and still goes to Anthropic verbatim.
267
+ */
268
+ export declare function normalizeMessagesForMemtree(messages: Message[]): Message[];
269
+ export declare class MemtreeClient {
270
+ private baseUrl;
271
+ private apiKey;
272
+ private compressTimeoutMs;
273
+ private debug;
274
+ private reqlog;
275
+ private memtreeTools;
276
+ /** Complete compression request key → in-flight/settled promise (retry dedupe). */
277
+ private compressCache;
278
+ /** When a cached compress result stops answering (expireCompressResult). */
279
+ private readonly compressExpiry;
280
+ private readonly compressResultKeys;
281
+ /** Message hashes already submitted for background indexing. */
282
+ private indexedHashes;
283
+ /** In-flight index-only calls, tracked so shutdown cannot outrun their logs. */
284
+ private backgroundIndexes;
285
+ /** Once draining begins, no later request may create another log producer. */
286
+ private backgroundClosing;
287
+ /** Session → its main lane's latest conversation, for the final index. */
288
+ private readonly mainConversations;
289
+ /** Session → its final index waiting for the session to stay idle. */
290
+ private readonly pendingFinals;
291
+ /** Session → hash of the conversation its last final index sent. */
292
+ private readonly finalIndexed;
293
+ private readonly finalPreparing;
294
+ private finalDrainDeadline;
295
+ /** FastAPI `detail` text from the most recent 402, or null while paid. */
296
+ private unpaidDetail;
297
+ /** Complete compression request key → whether its latest failure arms fuse. */
298
+ private compressFailureArming;
299
+ /**
300
+ * Non-null when the server last answered 402 (unpaid MemTree key): the
301
+ * server's human-readable detail text. Set by both compression and
302
+ * background-indexing calls; cleared by any subsequent success.
303
+ */
304
+ get paymentRequiredDetail(): string | null;
305
+ /**
306
+ * The blocking-compress abort budget. Exposed so the proxy's request log
307
+ * can label a failed compress that consumed (roughly) the whole budget as a
308
+ * timeout rather than a fast server error.
309
+ */
310
+ get compressBudgetMs(): number;
311
+ /** Change the `x-memtree-tools` value for later calls (undefined: none). */
312
+ setMemtreeTools(value: string | undefined): void;
313
+ /**
314
+ * GET a MemTree view path (`/usage/memtree/<id>[.json][?share=…]`) on the
315
+ * polychat host with this client's key. Backs the loopback `/memtree/*`
316
+ * passthrough, so an agent inside a ccc session reads the user's own tree
317
+ * through ANTHROPIC_BASE_URL without ever handling the key.
318
+ */
319
+ fetchMemTree(pathAndQuery: string, accept?: string, signal?: AbortSignal, extraHeaders?: Record<string, string>): Promise<{
320
+ status: number;
321
+ contentType: string;
322
+ body: Buffer;
323
+ }>;
324
+ constructor(opts: MemtreeOptions);
325
+ static hashMessages(messages: Message[]): string;
326
+ /**
327
+ * Whether compress(hash, limit, meta) would answer without contacting the server: an
328
+ * already-settled success, or a leg another caller has in flight. Callers
329
+ * that read a compress result as evidence about the SERVER's health must
330
+ * consult this first — a memoized answer proves only that the server was
331
+ * alive whenever that entry was created, which may be many minutes and one
332
+ * outage ago. In-flight entries count as cached here even though they are
333
+ * real round trips: conservatively discarding live evidence only forgoes an
334
+ * optimization, whereas trusting a stale one suppresses a real outage.
335
+ */
336
+ hasCachedCompress(hash: string, modelContextLimit: number, meta?: CompressRequestMeta): boolean;
337
+ /**
338
+ * Fuse classification for the most recent live compress failure of `hash`.
339
+ * The entry is recorded before the failed promise settles null, and a
340
+ * concurrent same-request retry MAY overwrite it with a different class — so
341
+ * callers must sample at their own leg's settle (a .then on the compress
342
+ * promise), not after awaiting other work; only that keeps the read paired
343
+ * with the failure it describes.
344
+ * Arming failures are evidence about the SERVER's health: no response at
345
+ * all (network error or the abort-budget timeout), any 5xx, and 402 —
346
+ * unpaid is global and persistent, so it must keep arming. Any other 4xx
347
+ * came from a responsive server rejecting this one request and must not
348
+ * open the shared fuse. Unclassified failures default to arming: muting
349
+ * the fuse needs positive evidence of a responsive server.
350
+ */
351
+ lastCompressFailureArming(hash: string, modelContextLimit: number, meta?: CompressRequestMeta): boolean;
352
+ /**
353
+ * Blocking user-turn compression. Returns null on ANY failure (timeout,
354
+ * network, 4xx/5xx including 402) — the caller must degrade to passthrough.
355
+ * On 402 the failure is additionally recorded in paymentRequiredDetail so
356
+ * the caller can distinguish "unpaid" from "outage".
357
+ */
358
+ compress(hash: string, messages: Message[], modelContextLimit: number, signal?: AbortSignal, meta?: CompressRequestMeta): Promise<CompressResult | null>;
359
+ /**
360
+ * Let `result` answer identical requests for `afterMs` more, then ask the
361
+ * server again: an answer from a lagging index goes stale once indexing
362
+ * catches up. In-flight calls are untouched (still deduplicated), and an
363
+ * earlier expiry is kept, so retries cannot postpone the refresh.
364
+ */
365
+ expireCompressResult(result: CompressResult, afterMs: number): void;
366
+ /** The cached compress promise for `key`, dropping one past its expiry. */
367
+ private liveCompress;
368
+ /**
369
+ * Fire-and-forget background indexing for tool and first-user turns. Keeps
370
+ * the server index fed during tool loops; adds zero latency to the response
371
+ * path. A tool turn whose route-miss recovery got any non-null compress()
372
+ * response skips this: that call already submitted the same history. A
373
+ * recovery that returned null skips it too when the client has already
374
+ * disconnected, or on shutdown/402 — only an ordinary failure with a live
375
+ * client keeps the longer-budget background retry.
376
+ */
377
+ indexInBackground(hash: string, messages: Message[], modelContextLimit: number, sessionId?: string, clientMeta?: Record<string, string>,
378
+ /** Times for retained original messages, in the positions actually sent. */
379
+ messageTimesFor?: (messages: Message[]) => MessageTimes): void;
380
+ /**
381
+ * The main lane's latest conversation for a session, kept for its final
382
+ * index (scheduleFinalIndex). A new request also means the session did not
383
+ * end at the last Stop: its pending final index is cancelled.
384
+ */
385
+ noteMainConversation(sessionId: string | undefined, conversation: MainConversation): void;
386
+ /**
387
+ * After a main-lane Stop: once the session has been idle `delayMs` (or at
388
+ * shutdown, flushFinalIndexes), send its conversation plus the reply it
389
+ * ended with as one index-only call flagged final_index, so the server
390
+ * indexes the tail even below its 10k-token minimum (at most once per
391
+ * conversation per 30 minutes, server-side). Every per-request index call
392
+ * lacks that reply: it only appears in the next request. `readReply` reads
393
+ * it from the transcript when the call goes out, not inside the hook.
394
+ */
395
+ scheduleFinalIndex(sessionId: string | undefined, readReply: FinalReplyReader, delayMs?: number): void;
396
+ /**
397
+ * At shutdown, before drainBackground: finalize at most the three newest
398
+ * sessions, including sessions that never had a Stop (`-p`
399
+ * and non-TTY runs install no hooks). Never throws: a failure here must not
400
+ * change ccc's exit code. The calls share drainBackground's bounded wait.
401
+ */
402
+ flushFinalIndexes(timeoutMs?: number): void;
403
+ private cancelFinalIndex;
404
+ private fireFinalIndex;
405
+ private sendFinalIndex;
406
+ private submitIndexOnly;
407
+ /**
408
+ * Stop accepting background indexes and wait boundedly for those already in
409
+ * flight. Calls still running after the grace period are aborted, and this
410
+ * method does not return until their final request-log records are produced.
411
+ * The boolean is true for a graceful drain and false when abort was needed.
412
+ */
413
+ drainBackground(timeoutMs?: number): Promise<boolean>;
414
+ private compressKey;
415
+ private remember;
416
+ private callContextMemory;
417
+ private log;
418
+ }
419
+ /** What noteMainConversation keeps: the last main-lane request as sent to MemTree. */
420
+ export interface MainConversation {
421
+ messages: Message[];
422
+ modelContextLimit: number;
423
+ clientMeta?: Record<string, string>;
424
+ messageTimesFor?: (messages: Message[]) => MessageTimes;
425
+ /** The reply the session ended with (Claude Code's transcript), for a final index at exit. */
426
+ readReply?: FinalReplyReader;
427
+ }
428
+ /** The conversation plus the reply that ended it, unless it already ends with a reply. */
429
+ export declare function withFinalReply(messages: Message[], reply: Message | undefined): Message[];
430
+ //# sourceMappingURL=memtree.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"memtree.d.ts","sourceRoot":"","sources":["../src/memtree.ts"],"names":[],"mappings":"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"}