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
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAC9D,YAAY,EAAE,gBAAgB,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AACxC,YAAY,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC7D,OAAO,EACL,sBAAsB,EACtB,kBAAkB,EAClB,aAAa,EACb,0BAA0B,EAC1B,2BAA2B,EAC3B,mBAAmB,EACnB,uBAAuB,GACxB,MAAM,cAAc,CAAC;AACtB,YAAY,EACV,cAAc,EACd,cAAc,EACd,sBAAsB,GACvB,MAAM,cAAc,CAAC;AACtB,OAAO,EACL,oBAAoB,EACpB,uBAAuB,EACvB,wBAAwB,EACxB,sBAAsB,EACtB,0BAA0B,EAC1B,oBAAoB,EACpB,eAAe,EACf,4BAA4B,EAC5B,sBAAsB,EACtB,kBAAkB,EAClB,oBAAoB,GACrB,MAAM,YAAY,CAAC;AACpB,YAAY,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAC1C,OAAO,EACL,WAAW,EACX,YAAY,EACZ,iBAAiB,EACjB,mBAAmB,EACnB,eAAe,EACf,uBAAuB,EACvB,uBAAuB,EACvB,cAAc,EACd,iBAAiB,EACjB,oBAAoB,EACpB,UAAU,EACV,4BAA4B,EAC5B,iBAAiB,EACjB,iBAAiB,EACjB,iBAAiB,EACjB,iBAAiB,EACjB,iCAAiC,EACjC,sBAAsB,GACvB,MAAM,cAAc,CAAC;AACtB,OAAO,EACL,mBAAmB,EACnB,oBAAoB,EACpB,yBAAyB,EACzB,sBAAsB,EACtB,qBAAqB,EACrB,2BAA2B,EAC3B,2BAA2B,GAC5B,MAAM,YAAY,CAAC;AACpB,YAAY,EACV,eAAe,EACf,gBAAgB,EAChB,mBAAmB,GACpB,MAAM,YAAY,CAAC;AAIpB,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAC9D,YAAY,EAAE,gBAAgB,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAC"}
package/dist/index.js CHANGED
@@ -1,2 +1,10 @@
1
+ export { startProxy } from "./proxy.js";
2
+ export { checkCompressedHistory, didMemtreeCompress, MemtreeClient, MIN_RETAINED_HISTORY_CHARS, normalizeMessagesForMemtree, rawPromptTokenCount, serverFlattenedMessages, } from "./memtree.js";
3
+ export { isNonToolUserMessage, isToolResultUserMessage, isAwaySummaryUserMessage, isLocalBashCommandTurn, AWAY_SUMMARY_PROMPT_PREFIX, lastNonSystemMessage, userMessageText, hasEarlierNonToolUserMessage, stripCcSystemReminders, messagesWithSystem, contextLimitForModel, } from "./turns.js";
4
+ export { NOTICE_OPEN, NOTICE_CLOSE, COMPRESSED_NOTICE, MODEL_HIDDEN_NOTICE, DEGRADED_NOTICE, PAYMENT_REQUIRED_NOTICE, SLOW_FIRST_TOKEN_NOTICE, STARTUP_NOTICE, startupNoticeText, sanitizeNoticeDetail, wrapNotice, exciseKnownLegacyNoticeSpans, stripNoticeBlocks, stripNoticeSystem, SseNoticeRewriter, fabricatedPrelude, insertNoticeBeforeResponseContent, appendNoticeToJsonBody, } from "./notices.js";
5
+ export { NoticeDeliveryQueue, parseNoticeHookInput, createSessionNoticePlugin, supportsMessageDisplay, terminalSupportsColor, withSessionNoticePluginArgs, MESSAGE_DISPLAY_MIN_VERSION, } from "./hooks.js";
6
+ // Keychain access is the designed-but-unbuilt fallback in case Anthropic stops
7
+ // sending OAuth to custom base URLs (plan: "Auth to Anthropic"). Not used by
8
+ // the launcher — Claude Code owns its credentials.
1
9
  export { getOAuthToken, isTokenExpired } from "./keychain.js";
2
10
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAExC,OAAO,EACL,sBAAsB,EACtB,kBAAkB,EAClB,aAAa,EACb,0BAA0B,EAC1B,2BAA2B,EAC3B,mBAAmB,EACnB,uBAAuB,GACxB,MAAM,cAAc,CAAC;AAMtB,OAAO,EACL,oBAAoB,EACpB,uBAAuB,EACvB,wBAAwB,EACxB,sBAAsB,EACtB,0BAA0B,EAC1B,oBAAoB,EACpB,eAAe,EACf,4BAA4B,EAC5B,sBAAsB,EACtB,kBAAkB,EAClB,oBAAoB,GACrB,MAAM,YAAY,CAAC;AAEpB,OAAO,EACL,WAAW,EACX,YAAY,EACZ,iBAAiB,EACjB,mBAAmB,EACnB,eAAe,EACf,uBAAuB,EACvB,uBAAuB,EACvB,cAAc,EACd,iBAAiB,EACjB,oBAAoB,EACpB,UAAU,EACV,4BAA4B,EAC5B,iBAAiB,EACjB,iBAAiB,EACjB,iBAAiB,EACjB,iBAAiB,EACjB,iCAAiC,EACjC,sBAAsB,GACvB,MAAM,cAAc,CAAC;AACtB,OAAO,EACL,mBAAmB,EACnB,oBAAoB,EACpB,yBAAyB,EACzB,sBAAsB,EACtB,qBAAqB,EACrB,2BAA2B,EAC3B,2BAA2B,GAC5B,MAAM,YAAY,CAAC;AAMpB,+EAA+E;AAC/E,6EAA6E;AAC7E,mDAAmD;AACnD,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC"}
@@ -0,0 +1,24 @@
1
+ export type FetchMode = "production" | "staging" | "local";
2
+ export declare const USAGE: string;
3
+ export interface FetchKeys {
4
+ production?: string;
5
+ staging?: string;
6
+ local?: string;
7
+ }
8
+ export interface FetchDeps {
9
+ fetch: typeof fetch;
10
+ keys: FetchKeys;
11
+ stdout: (text: string) => void;
12
+ stderr: (text: string) => void;
13
+ }
14
+ /** Exit codes: 0 printed, 1 server refused, 2 bad invocation, 3 no key saved. */
15
+ export declare function runMemtreeFetchCommand(argv: string[], overrides?: Partial<FetchDeps>): Promise<number>;
16
+ /** The `.json` form of a MemTree page URL, or null when it is not one. */
17
+ export declare function memtreeJsonUrl(raw: string): URL | null;
18
+ /**
19
+ * Which saved key a host needs, mirroring the `ccc [staging|local]` modes; null
20
+ * for any other host. Production and staging keys travel only over https.
21
+ */
22
+ export declare function modeForUrl(url: URL): FetchMode | null;
23
+ export declare function keyForMode(mode: FetchMode, keys: FetchKeys): string | undefined;
24
+ //# sourceMappingURL=memtree-fetch.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"memtree-fetch.d.ts","sourceRoot":"","sources":["../src/memtree-fetch.ts"],"names":[],"mappings":"AAqBA,MAAM,MAAM,SAAS,GAAG,YAAY,GAAG,SAAS,GAAG,OAAO,CAAC;AAiB3D,eAAO,MAAM,KAAK,QAG6D,CAAC;AAEhF,MAAM,WAAW,SAAS;IACxB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,SAAS;IACxB,KAAK,EAAE,OAAO,KAAK,CAAC;IACpB,IAAI,EAAE,SAAS,CAAC;IAChB,MAAM,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IAC/B,MAAM,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;CAChC;AAED,iFAAiF;AACjF,wBAAsB,sBAAsB,CAC1C,IAAI,EAAE,MAAM,EAAE,EACd,SAAS,GAAE,OAAO,CAAC,SAAS,CAAM,GACjC,OAAO,CAAC,MAAM,CAAC,CA2CjB;AAED,0EAA0E;AAC1E,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,GAAG,IAAI,CAatD;AAED;;;GAGG;AACH,wBAAgB,UAAU,CAAC,GAAG,EAAE,GAAG,GAAG,SAAS,GAAG,IAAI,CAMrD;AAED,wBAAgB,UAAU,CAAC,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,SAAS,GAAG,MAAM,GAAG,SAAS,CAE/E"}
@@ -0,0 +1,121 @@
1
+ /**
2
+ * `ccc fetch <memtree-url>`: print one of the user's MemTree pages as JSON,
3
+ * authenticated with the key ccc already stores.
4
+ *
5
+ * The polychat MemTree page (`/m/<short id>`, or the canonical
6
+ * `/usage/memtree/<request id>`) answers an unauthenticated
7
+ * agent with a 401 that lists, in order: the loopback proxy of a running ccc
8
+ * session, this command, and the raw key. This is the middle option — for an
9
+ * agent on the user's machine when no ccc session is running. The tree is
10
+ * never published; the agent simply acts as the user.
11
+ *
12
+ * The page URL and its `.json` twin are accepted interchangeably: the machine
13
+ * form is always what gets printed. A `?share=` token survives untouched.
14
+ */
15
+ import { getLocalPolychatApiKey, getPolychatApiKey, getStagingPolychatApiKey, } from "./config.js";
16
+ import { CLIENT_NAME, CLIENT_VERSION } from "./memtree.js";
17
+ /**
18
+ * `/m/<short id>` or `/usage/memtree/<request id>`, with or without the
19
+ * `.json` suffix. The server serves both spellings of either id.
20
+ */
21
+ const MEMTREE_PATH_RE = /^(\/m|\/usage\/memtree)\/([A-Za-z0-9-]+)(\.json)?$/;
22
+ /**
23
+ * The only hosts a saved key may be sent to. Anything else (including look-alikes
24
+ * such as `polychat-staging.evil.example`) gets no key: a pasted URL decides
25
+ * where the request goes, so it must never decide that a stranger gets a key.
26
+ */
27
+ const PRODUCTION_HOSTS = new Set(["api.polychat.co", "app.polychat.co"]);
28
+ const STAGING_HOSTS = new Set(["polychat-staging-421312241218.us-west2.run.app"]);
29
+ const LOCAL_HOSTS = new Set(["localhost", "127.0.0.1", "local.polychat.co"]);
30
+ const ERROR_BODY_PREVIEW_CHARS = 1000;
31
+ export const USAGE = "usage: ccc fetch <memtree-url>\n" +
32
+ " Prints the MemTree at <memtree-url> as JSON (nodes, blocks, instructions),\n" +
33
+ " using the MemTree key saved for that host (production, staging or local).";
34
+ /** Exit codes: 0 printed, 1 server refused, 2 bad invocation, 3 no key saved. */
35
+ export async function runMemtreeFetchCommand(argv, overrides = {}) {
36
+ const deps = withDefaults(overrides);
37
+ const raw = argv[0];
38
+ if (!raw || raw === "--help" || raw === "-h") {
39
+ deps.stderr(USAGE + "\n");
40
+ return 2;
41
+ }
42
+ const url = memtreeJsonUrl(raw);
43
+ if (!url) {
44
+ deps.stderr(`ccc fetch: not a MemTree URL: ${raw}\n${USAGE}\n`);
45
+ return 2;
46
+ }
47
+ const mode = modeForUrl(url);
48
+ if (!mode) {
49
+ deps.stderr(`ccc fetch: not a Polychat host, so no key is sent: ${url.host}\n`);
50
+ return 2;
51
+ }
52
+ const key = keyForMode(mode, deps.keys);
53
+ if (!key) {
54
+ deps.stderr(`ccc fetch: no MemTree key saved for ${mode} (${url.host}). ` +
55
+ `Run \`ccc${mode === "production" ? "" : ` ${mode}`}\` once to save one.\n`);
56
+ return 3;
57
+ }
58
+ const response = await deps.fetch(url, {
59
+ headers: {
60
+ authorization: `Bearer ${key}`,
61
+ accept: "application/json",
62
+ "x-client": CLIENT_NAME,
63
+ "x-client-version": CLIENT_VERSION,
64
+ },
65
+ });
66
+ const body = await response.text();
67
+ if (!response.ok) {
68
+ deps.stderr(`ccc fetch: HTTP ${response.status} from ${url.host}\n` +
69
+ `${body.slice(0, ERROR_BODY_PREVIEW_CHARS)}\n`);
70
+ return 1;
71
+ }
72
+ deps.stdout(body.endsWith("\n") ? body : body + "\n");
73
+ return 0;
74
+ }
75
+ /** The `.json` form of a MemTree page URL, or null when it is not one. */
76
+ export function memtreeJsonUrl(raw) {
77
+ let url;
78
+ try {
79
+ url = new URL(raw);
80
+ }
81
+ catch {
82
+ return null;
83
+ }
84
+ const match = MEMTREE_PATH_RE.exec(url.pathname);
85
+ if (!match || (url.protocol !== "https:" && url.protocol !== "http:")) {
86
+ return null;
87
+ }
88
+ url.pathname = `${match[1]}/${match[2]}.json`;
89
+ return url;
90
+ }
91
+ /**
92
+ * Which saved key a host needs, mirroring the `ccc [staging|local]` modes; null
93
+ * for any other host. Production and staging keys travel only over https.
94
+ */
95
+ export function modeForUrl(url) {
96
+ if (LOCAL_HOSTS.has(url.hostname))
97
+ return "local";
98
+ if (url.protocol !== "https:")
99
+ return null;
100
+ if (STAGING_HOSTS.has(url.hostname))
101
+ return "staging";
102
+ if (PRODUCTION_HOSTS.has(url.hostname))
103
+ return "production";
104
+ return null;
105
+ }
106
+ export function keyForMode(mode, keys) {
107
+ return keys[mode] || undefined;
108
+ }
109
+ function withDefaults(overrides) {
110
+ return {
111
+ fetch: overrides.fetch ?? globalThis.fetch,
112
+ keys: overrides.keys ?? {
113
+ production: getPolychatApiKey(),
114
+ staging: getStagingPolychatApiKey(),
115
+ local: getLocalPolychatApiKey(),
116
+ },
117
+ stdout: overrides.stdout ?? ((text) => process.stdout.write(text)),
118
+ stderr: overrides.stderr ?? ((text) => process.stderr.write(text)),
119
+ };
120
+ }
121
+ //# sourceMappingURL=memtree-fetch.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"memtree-fetch.js","sourceRoot":"","sources":["../src/memtree-fetch.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,99 @@
1
+ export declare const SESSIONS_DEFAULT_LIMIT = 20;
2
+ export declare const SESSIONS_MAX_LIMIT = 100;
3
+ export declare const FINDER_SEARCH_DEFAULT_LIMIT = 10;
4
+ export declare const FINDER_SEARCH_MAX_LIMIT = 50;
5
+ export declare const FINDER_SEARCH_MODES: readonly ["vector", "text"];
6
+ export interface FinderProject {
7
+ dir?: string | null;
8
+ repo?: string | null;
9
+ branch?: string | null;
10
+ commit?: string | null;
11
+ }
12
+ export interface FinderTreeLinks {
13
+ url?: string;
14
+ html?: string;
15
+ json?: string;
16
+ lines?: string;
17
+ }
18
+ export interface FinderSession {
19
+ id: string;
20
+ kind?: string;
21
+ session_id?: string | null;
22
+ title?: string | null;
23
+ snippet?: string | null;
24
+ first_at?: string | null;
25
+ last_at?: string | null;
26
+ project?: FinderProject | null;
27
+ models?: string[];
28
+ request_count?: number;
29
+ tokens?: {
30
+ prompt?: number;
31
+ completion?: number;
32
+ conversation?: number | null;
33
+ };
34
+ latest_tree?: {
35
+ request_id: string;
36
+ ref?: string;
37
+ links?: FinderTreeLinks;
38
+ } | null;
39
+ }
40
+ export interface FinderHit {
41
+ id: string;
42
+ kind?: string;
43
+ session_id?: string | null;
44
+ tree: {
45
+ request_id: string;
46
+ ref?: string;
47
+ created_at?: string | null;
48
+ links?: FinderTreeLinks | null;
49
+ };
50
+ leaf?: string;
51
+ range?: {
52
+ block: number;
53
+ start: number;
54
+ end: number;
55
+ } | null;
56
+ snippet?: string | null;
57
+ score?: number;
58
+ embedding_model?: string;
59
+ /** `<tree>#<node>`: the matched node, for read_node / read_lines `node`. */
60
+ address?: string;
61
+ node?: number;
62
+ /** Ancestors of the node, root first. */
63
+ path?: {
64
+ id: number;
65
+ summary: string;
66
+ }[];
67
+ }
68
+ export interface FinderSessionsResponse {
69
+ sessions?: FinderSession[];
70
+ next_cursor?: string | null;
71
+ }
72
+ export interface FinderSearchResponse {
73
+ query?: string;
74
+ mode?: string;
75
+ hits?: FinderHit[];
76
+ groups?: {
77
+ embedding_model: string;
78
+ hits: FinderHit[];
79
+ has_more?: boolean;
80
+ }[];
81
+ next_cursor?: string | null;
82
+ matches_capped?: boolean;
83
+ charged?: boolean;
84
+ /** "any_word": no passage held every word, so these hold some of them. */
85
+ relaxed?: string;
86
+ }
87
+ /** Query string for `/memtree/sessions` from the tool's arguments. */
88
+ export declare function sessionsQuery(args: Record<string, unknown>): string;
89
+ /** Query string for `/memtree/search`; `mode` defaults to text; `tree` scopes it to one tree. */
90
+ export declare function searchQuery(args: Record<string, unknown>, tree?: string): string;
91
+ export declare function searchMode(value: unknown): (typeof FINDER_SEARCH_MODES)[number];
92
+ export declare function formatSessions(body: FinderSessionsResponse, args: Record<string, unknown>): string;
93
+ export declare function formatSearchResults(body: FinderSearchResponse, args: Record<string, unknown>): string;
94
+ /** Ancestors root first, ` › `-joined, each with its address when the tree is known. */
95
+ export declare function formatPath(path: {
96
+ id: number;
97
+ summary: string;
98
+ }[], ref?: string): string;
99
+ //# sourceMappingURL=memtree-finder.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"memtree-finder.d.ts","sourceRoot":"","sources":["../src/memtree-finder.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,235 @@
1
+ /**
2
+ * The `memtree` MCP server's server-side finding: `list` (the user's sessions)
3
+ * and `search` across sessions or within one tree by `tree`, in text or vector
4
+ * mode (memtree-mcp.ts wires them up; a text search of one tree uses the
5
+ * per-tree term search instead).
6
+ *
7
+ * Both call the ccc loopback proxy (`/memtree/sessions`, `/memtree/search`),
8
+ * which relays to the server's owner-only `GET /v1/memtree/sessions` and
9
+ * `GET /v1/memtree/search` with the user's key; the key never reaches this
10
+ * process. Results are formatted as plain text for the model, like the
11
+ * single-tree tools (memtree-tools.ts). Every hit names the tree (a pinned
12
+ * reference, or a request id on older servers) and the transcript lines,
13
+ * and says which `read_lines` / `read_node`
14
+ * call opens it: those tools take the tree id as `tree`.
15
+ */
16
+ import { ToolInputError } from "./memtree-tools.js";
17
+ export const SESSIONS_DEFAULT_LIMIT = 20;
18
+ export const SESSIONS_MAX_LIMIT = 100;
19
+ export const FINDER_SEARCH_DEFAULT_LIMIT = 10;
20
+ export const FINDER_SEARCH_MAX_LIMIT = 50;
21
+ export const FINDER_SEARCH_MODES = ["vector", "text"];
22
+ const SNIPPET_CHARS = 400;
23
+ const TITLE_CHARS = 300;
24
+ const PATH_SUMMARY_CHARS = 80;
25
+ /** Query string for `/memtree/sessions` from the tool's arguments. */
26
+ export function sessionsQuery(args) {
27
+ const params = new URLSearchParams();
28
+ addText(params, "since", args.since);
29
+ addText(params, "until", args.until);
30
+ addText(params, "project", args.project);
31
+ addText(params, "q", args.q);
32
+ addText(params, "cursor", args.cursor);
33
+ addLimit(params, args.limit, SESSIONS_MAX_LIMIT);
34
+ const query = params.toString();
35
+ return query ? `?${query}` : "";
36
+ }
37
+ /** Query string for `/memtree/search`; `mode` defaults to text; `tree` scopes it to one tree. */
38
+ export function searchQuery(args, tree) {
39
+ if (typeof args.query !== "string" || !args.query.trim()) {
40
+ throw new ToolInputError("search: query must be a non-empty string");
41
+ }
42
+ const mode = searchMode(args.mode);
43
+ const params = new URLSearchParams({ q: args.query.trim(), mode });
44
+ if (tree)
45
+ params.set("tree", tree);
46
+ addText(params, "project", args.project);
47
+ addText(params, "since", args.since);
48
+ addText(params, "until", args.until);
49
+ addText(params, "cursor", args.cursor);
50
+ addLimit(params, args.limit, FINDER_SEARCH_MAX_LIMIT);
51
+ return `?${params.toString()}`;
52
+ }
53
+ export function searchMode(value) {
54
+ if (value === undefined || value === null || value === "")
55
+ return "text";
56
+ const mode = String(value).trim().toLowerCase();
57
+ if (mode === "vector" || mode === "text")
58
+ return mode;
59
+ throw new ToolInputError(`search: mode must be "vector" or "text", got ${JSON.stringify(value)}`);
60
+ }
61
+ function addText(params, name, value) {
62
+ if (value === undefined || value === null)
63
+ return;
64
+ if (typeof value !== "string") {
65
+ throw new ToolInputError(`${name} must be a string`);
66
+ }
67
+ if (value.trim())
68
+ params.set(name, value.trim());
69
+ }
70
+ function addLimit(params, value, max) {
71
+ if (value === undefined || value === null || value === "")
72
+ return;
73
+ const n = Number(value);
74
+ if (!Number.isFinite(n))
75
+ throw new ToolInputError("limit must be a number");
76
+ params.set("limit", String(Math.max(1, Math.min(max, Math.floor(n)))));
77
+ }
78
+ export function formatSessions(body, args) {
79
+ const sessions = body.sessions ?? [];
80
+ if (!sessions.length) {
81
+ return args.cursor
82
+ ? "No more sessions."
83
+ : "No sessions match. Widen the time range (since/until), drop the project or q filter, or check the spelling.";
84
+ }
85
+ const out = [`${sessions.length} session${sessions.length === 1 ? "" : "s"}, most recently active first:`];
86
+ sessions.forEach((s, i) => {
87
+ out.push("", `[${i + 1}] ${oneLine(s.title, TITLE_CHARS) || "(no MemTree yet)"}`);
88
+ const when = [s.first_at, s.last_at].map(shortTime).filter(Boolean);
89
+ out.push(" " +
90
+ [
91
+ sessionLabel(s.kind, s.id, s.session_id),
92
+ when.length ? when.join(" → ") : undefined,
93
+ s.request_count !== undefined ? `${s.request_count} request${s.request_count === 1 ? "" : "s"}` : undefined,
94
+ s.models?.length ? `models ${s.models.join(", ")}` : undefined,
95
+ ]
96
+ .filter(Boolean)
97
+ .join(" · "));
98
+ const project = projectLabel(s.project);
99
+ if (project)
100
+ out.push(` project: ${project}`);
101
+ if (s.snippet)
102
+ out.push(` first message: ${oneLine(s.snippet, SNIPPET_CHARS)}`);
103
+ const tree = s.latest_tree;
104
+ if (tree?.request_id) {
105
+ const ref = tree.ref ?? tree.request_id;
106
+ out.push(` latest tree: ${tree.request_id}${tree.links?.url ? ` (${tree.links.url})` : ""}; ` +
107
+ `browse it with read_node {"tree": "${ref}", "id": 0}, or search it with search {"tree": "${ref}", "query": …}`);
108
+ }
109
+ });
110
+ out.push("", nextPage("list", body.next_cursor));
111
+ return out.join("\n");
112
+ }
113
+ export function formatSearchResults(body, args) {
114
+ const query = typeof body.query === "string" ? body.query : String(args.query ?? "");
115
+ if (body.groups) {
116
+ const groups = body.groups.filter((g) => g.hits?.length);
117
+ if (!groups.length)
118
+ return noHits(query, "vector", args);
119
+ const out = [
120
+ `Semantic matches for ${JSON.stringify(query)}` +
121
+ (body.charged ? " (charged: one query embedding per model)" : "") +
122
+ ":",
123
+ ];
124
+ if (groups.length > 1) {
125
+ out.push("Each embedding model is ranked on its own; scores are not comparable across groups.");
126
+ }
127
+ for (const group of groups) {
128
+ out.push("", `== ${group.embedding_model} ==`);
129
+ group.hits.forEach((hit, i) => out.push(...formatHit(hit, i + 1)));
130
+ }
131
+ out.push("", nextPage("search", body.next_cursor), OPEN_NOTE);
132
+ return out.join("\n");
133
+ }
134
+ const hits = body.hits ?? [];
135
+ if (!hits.length)
136
+ return noHits(query, "text", args);
137
+ const out = [`${hits.length} text match${hits.length === 1 ? "" : "es"} for ${JSON.stringify(query)}:`];
138
+ hits.forEach((hit, i) => out.push(...formatHit(hit, i + 1)));
139
+ if (body.relaxed === "any_word") {
140
+ out.splice(1, 0, "(No passage has every word, so these have some of them, best first. Try other words, or mode \"vector\" for meaning.)");
141
+ }
142
+ if (body.matches_capped) {
143
+ out.push("", "(Only the newest matching passages were ranked: add words, or narrow with since, until or project.)");
144
+ }
145
+ out.push("", nextPage("search", body.next_cursor), OPEN_NOTE);
146
+ return out.join("\n");
147
+ }
148
+ const OPEN_NOTE = "Snippets are excerpts. read_node {\"node\": <address>} opens a hit's node (its children and path; the path's " +
149
+ "addresses lead to parents and siblings); read_lines {\"node\": <address>} returns its exact transcript lines.";
150
+ function formatHit(hit, n) {
151
+ const tree = hit.tree?.request_id;
152
+ const ref = hit.tree?.ref ?? tree;
153
+ const range = hit.range;
154
+ const head = [
155
+ sessionLabel(hit.kind, hit.id, hit.session_id),
156
+ hit.tree?.created_at ? `tree ${tree} of ${shortTime(hit.tree.created_at)}` : `tree ${tree}`,
157
+ hit.leaf ? `leaf ${hit.leaf}` : undefined,
158
+ range ? `block ${range.block} lines ${range.start}-${range.end}` : undefined,
159
+ typeof hit.score === "number" ? `score ${hit.score.toFixed(3)}` : undefined,
160
+ ]
161
+ .filter(Boolean)
162
+ .join(" · ");
163
+ const lines = ["", `[${n}] ${head}`];
164
+ if (hit.tree?.links?.url)
165
+ lines.push(` page: ${hit.tree.links.url}`);
166
+ if (hit.path?.length)
167
+ lines.push(` path: ${formatPath(hit.path, ref)}`);
168
+ if (hit.snippet)
169
+ lines.push(` ${oneLine(boldToMarkdown(hit.snippet), SNIPPET_CHARS)}`);
170
+ if (hit.address) {
171
+ lines.push(` address: ${hit.address}`);
172
+ }
173
+ else if (ref && range) {
174
+ lines.push(` open: read_lines {"tree": "${ref}", "block": ${range.block}, "start": ${range.start}, "end": ${range.end}}`);
175
+ }
176
+ return lines;
177
+ }
178
+ /** Ancestors root first, ` › `-joined, each with its address when the tree is known. */
179
+ export function formatPath(path, ref) {
180
+ return path
181
+ .map((p) => `${oneLine(p.summary, PATH_SUMMARY_CHARS)}${ref ? ` (${ref}#${p.id})` : ` (node ${p.id})`}`)
182
+ .join(" › ");
183
+ }
184
+ function noHits(query, mode, args) {
185
+ if (args.cursor)
186
+ return "No more matches.";
187
+ const other = mode === "vector"
188
+ ? 'For an exact word, id or path, try mode "text".'
189
+ : 'For meaning rather than exact words, try mode "vector".';
190
+ if (typeof args.tree === "string" && args.tree) {
191
+ return `Nothing in tree ${args.tree} matches ${JSON.stringify(query)} (${mode} search). ${other}`;
192
+ }
193
+ return `No passage in your sessions matches ${JSON.stringify(query)} (${mode} search). ${other} Or widen since/until, or drop the project filter.`;
194
+ }
195
+ function nextPage(tool, cursor) {
196
+ return cursor
197
+ ? `More results: call ${tool} again with the same arguments and "cursor": "${cursor}".`
198
+ : "No more results.";
199
+ }
200
+ function sessionLabel(kind, id, sessionId) {
201
+ if (kind === "claude_code_session")
202
+ return `session ${sessionId || id}`;
203
+ if (kind === "conversation")
204
+ return `conversation ${id.replace(/^conversation:/, "").slice(0, 16)}`;
205
+ if (kind === "request")
206
+ return `request ${id.replace(/^request:/, "")}`;
207
+ return `session ${id}`;
208
+ }
209
+ function projectLabel(project) {
210
+ if (!project)
211
+ return undefined;
212
+ const where = [project.repo, project.dir && project.dir !== project.repo?.split("/").pop() ? `dir ${project.dir}` : undefined]
213
+ .filter(Boolean)
214
+ .join(", ");
215
+ const at = [project.branch, project.commit ? `@ ${project.commit}` : undefined].filter(Boolean).join(" ");
216
+ return [where || project.dir, at].filter(Boolean).join(" · ") || undefined;
217
+ }
218
+ /** `2026-09-29T01:40:57.018000+00:00` → `2026-09-29 01:40 UTC`. */
219
+ function shortTime(value) {
220
+ if (!value)
221
+ return undefined;
222
+ const date = new Date(value);
223
+ if (Number.isNaN(date.getTime()))
224
+ return value;
225
+ return `${date.toISOString().slice(0, 16).replace("T", " ")} UTC`;
226
+ }
227
+ function oneLine(text, max) {
228
+ const flat = (text ?? "").replace(/\s+/g, " ").trim();
229
+ return flat.length <= max ? flat : `${flat.slice(0, max - 1)}…`;
230
+ }
231
+ /** Text search snippets mark matched words `<b>…</b>`. */
232
+ function boldToMarkdown(text) {
233
+ return text.replace(/<b>/g, "**").replace(/<\/b>/g, "**");
234
+ }
235
+ //# sourceMappingURL=memtree-finder.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"memtree-finder.js","sourceRoot":"","sources":["../src/memtree-finder.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AACH,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAEpD,MAAM,CAAC,MAAM,sBAAsB,GAAG,EAAE,CAAC;AACzC,MAAM,CAAC,MAAM,kBAAkB,GAAG,GAAG,CAAC;AACtC,MAAM,CAAC,MAAM,2BAA2B,GAAG,EAAE,CAAC;AAC9C,MAAM,CAAC,MAAM,uBAAuB,GAAG,EAAE,CAAC;AAC1C,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,QAAQ,EAAE,MAAM,CAAU,CAAC;AAC/D,MAAM,aAAa,GAAG,GAAG,CAAC;AAC1B,MAAM,WAAW,GAAG,GAAG,CAAC;AACxB,MAAM,kBAAkB,GAAG,EAAE,CAAC;AAiE9B,sEAAsE;AACtE,MAAM,UAAU,aAAa,CAAC,IAA6B;IACzD,MAAM,MAAM,GAAG,IAAI,eAAe,EAAE,CAAC;IACrC,OAAO,CAAC,MAAM,EAAE,OAAO,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC;IACrC,OAAO,CAAC,MAAM,EAAE,OAAO,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC;IACrC,OAAO,CAAC,MAAM,EAAE,SAAS,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC;IACzC,OAAO,CAAC,MAAM,EAAE,GAAG,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC;IAC7B,OAAO,CAAC,MAAM,EAAE,QAAQ,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;IACvC,QAAQ,CAAC,MAAM,EAAE,IAAI,CAAC,KAAK,EAAE,kBAAkB,CAAC,CAAC;IACjD,MAAM,KAAK,GAAG,MAAM,CAAC,QAAQ,EAAE,CAAC;IAChC,OAAO,KAAK,CAAC,CAAC,CAAC,IAAI,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;AAClC,CAAC;AAED,iGAAiG;AACjG,MAAM,UAAU,WAAW,CAAC,IAA6B,EAAE,IAAa;IACtE,IAAI,OAAO,IAAI,CAAC,KAAK,KAAK,QAAQ,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,EAAE,CAAC;QACzD,MAAM,IAAI,cAAc,CAAC,0CAA0C,CAAC,CAAC;IACvE,CAAC;IACD,MAAM,IAAI,GAAG,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACnC,MAAM,MAAM,GAAG,IAAI,eAAe,CAAC,EAAE,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC;IACnE,IAAI,IAAI;QAAE,MAAM,CAAC,GAAG,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;IACnC,OAAO,CAAC,MAAM,EAAE,SAAS,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC;IACzC,OAAO,CAAC,MAAM,EAAE,OAAO,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC;IACrC,OAAO,CAAC,MAAM,EAAE,OAAO,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC;IACrC,OAAO,CAAC,MAAM,EAAE,QAAQ,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;IACvC,QAAQ,CAAC,MAAM,EAAE,IAAI,CAAC,KAAK,EAAE,uBAAuB,CAAC,CAAC;IACtD,OAAO,IAAI,MAAM,CAAC,QAAQ,EAAE,EAAE,CAAC;AACjC,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,KAAc;IACvC,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,EAAE;QAAE,OAAO,MAAM,CAAC;IACzE,MAAM,IAAI,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IAChD,IAAI,IAAI,KAAK,QAAQ,IAAI,IAAI,KAAK,MAAM;QAAE,OAAO,IAAI,CAAC;IACtD,MAAM,IAAI,cAAc,CAAC,gDAAgD,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;AACpG,CAAC;AAED,SAAS,OAAO,CAAC,MAAuB,EAAE,IAAY,EAAE,KAAc;IACpE,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,IAAI;QAAE,OAAO;IAClD,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC9B,MAAM,IAAI,cAAc,CAAC,GAAG,IAAI,mBAAmB,CAAC,CAAC;IACvD,CAAC;IACD,IAAI,KAAK,CAAC,IAAI,EAAE;QAAE,MAAM,CAAC,GAAG,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC;AACnD,CAAC;AAED,SAAS,QAAQ,CAAC,MAAuB,EAAE,KAAc,EAAE,GAAW;IACpE,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,EAAE;QAAE,OAAO;IAClE,MAAM,CAAC,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;IACxB,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC;QAAE,MAAM,IAAI,cAAc,CAAC,wBAAwB,CAAC,CAAC;IAC5E,MAAM,CAAC,GAAG,CAAC,OAAO,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AACzE,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,IAA4B,EAAE,IAA6B;IACxF,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,IAAI,EAAE,CAAC;IACrC,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAC;QACrB,OAAO,IAAI,CAAC,MAAM;YAChB,CAAC,CAAC,mBAAmB;YACrB,CAAC,CAAC,6GAA6G,CAAC;IACpH,CAAC;IACD,MAAM,GAAG,GAAG,CAAC,GAAG,QAAQ,CAAC,MAAM,WAAW,QAAQ,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,+BAA+B,CAAC,CAAC;IAC3G,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE;QACxB,GAAG,CAAC,IAAI,CAAC,EAAE,EAAE,IAAI,CAAC,GAAG,CAAC,KAAK,OAAO,CAAC,CAAC,CAAC,KAAK,EAAE,WAAW,CAAC,IAAI,kBAAkB,EAAE,CAAC,CAAC;QAClF,MAAM,IAAI,GAAG,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QACpE,GAAG,CAAC,IAAI,CACN,MAAM;YACJ;gBACE,YAAY,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,UAAU,CAAC;gBACxC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS;gBAC1C,CAAC,CAAC,aAAa,KAAK,SAAS,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,aAAa,WAAW,CAAC,CAAC,aAAa,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,SAAS;gBAC3G,CAAC,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS;aAC/D;iBACE,MAAM,CAAC,OAAO,CAAC;iBACf,IAAI,CAAC,KAAK,CAAC,CACjB,CAAC;QACF,MAAM,OAAO,GAAG,YAAY,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC;QACxC,IAAI,OAAO;YAAE,GAAG,CAAC,IAAI,CAAC,gBAAgB,OAAO,EAAE,CAAC,CAAC;QACjD,IAAI,CAAC,CAAC,OAAO;YAAE,GAAG,CAAC,IAAI,CAAC,sBAAsB,OAAO,CAAC,CAAC,CAAC,OAAO,EAAE,aAAa,CAAC,EAAE,CAAC,CAAC;QACnF,MAAM,IAAI,GAAG,CAAC,CAAC,WAAW,CAAC;QAC3B,IAAI,IAAI,EAAE,UAAU,EAAE,CAAC;YACrB,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,IAAI,IAAI,CAAC,UAAU,CAAC;YACxC,GAAG,CAAC,IAAI,CACN,oBAAoB,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC,KAAK,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,EAAE,IAAI;gBACrF,sCAAsC,GAAG,mDAAmD,GAAG,gBAAgB,CAClH,CAAC;QACJ,CAAC;IACH,CAAC,CAAC,CAAC;IACH,GAAG,CAAC,IAAI,CAAC,EAAE,EAAE,QAAQ,CAAC,MAAM,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC;IACjD,OAAO,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACxB,CAAC;AAED,MAAM,UAAU,mBAAmB,CAAC,IAA0B,EAAE,IAA6B;IAC3F,MAAM,KAAK,GAAG,OAAO,IAAI,CAAC,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC;IACrF,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;QAChB,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;QACzD,IAAI,CAAC,MAAM,CAAC,MAAM;YAAE,OAAO,MAAM,CAAC,KAAK,EAAE,QAAQ,EAAE,IAAI,CAAC,CAAC;QACzD,MAAM,GAAG,GAAG;YACV,wBAAwB,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE;gBAC7C,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,2CAA2C,CAAC,CAAC,CAAC,EAAE,CAAC;gBACjE,GAAG;SACN,CAAC;QACF,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACtB,GAAG,CAAC,IAAI,CAAC,qFAAqF,CAAC,CAAC;QAClG,CAAC;QACD,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;YAC3B,GAAG,CAAC,IAAI,CAAC,EAAE,EAAE,MAAM,KAAK,CAAC,eAAe,KAAK,CAAC,CAAC;YAC/C,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,SAAS,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;QACrE,CAAC;QACD,GAAG,CAAC,IAAI,CAAC,EAAE,EAAE,QAAQ,CAAC,QAAQ,EAAE,IAAI,CAAC,WAAW,CAAC,EAAE,SAAS,CAAC,CAAC;QAC9D,OAAO,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACxB,CAAC;IACD,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,IAAI,EAAE,CAAC;IAC7B,IAAI,CAAC,IAAI,CAAC,MAAM;QAAE,OAAO,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,CAAC,CAAC;IACrD,MAAM,GAAG,GAAG,CAAC,GAAG,IAAI,CAAC,MAAM,cAAc,IAAI,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,QAAQ,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IACxG,IAAI,CAAC,OAAO,CAAC,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,SAAS,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;IAC7D,IAAI,IAAI,CAAC,OAAO,KAAK,UAAU,EAAE,CAAC;QAChC,GAAG,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,uHAAuH,CAAC,CAAC;IAC5I,CAAC;IACD,IAAI,IAAI,CAAC,cAAc,EAAE,CAAC;QACxB,GAAG,CAAC,IAAI,CAAC,EAAE,EAAE,qGAAqG,CAAC,CAAC;IACtH,CAAC;IACD,GAAG,CAAC,IAAI,CAAC,EAAE,EAAE,QAAQ,CAAC,QAAQ,EAAE,IAAI,CAAC,WAAW,CAAC,EAAE,SAAS,CAAC,CAAC;IAC9D,OAAO,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACxB,CAAC;AAED,MAAM,SAAS,GACb,+GAA+G;IAC/G,+GAA+G,CAAC;AAElH,SAAS,SAAS,CAAC,GAAc,EAAE,CAAS;IAC1C,MAAM,IAAI,GAAG,GAAG,CAAC,IAAI,EAAE,UAAU,CAAC;IAClC,MAAM,GAAG,GAAG,GAAG,CAAC,IAAI,EAAE,GAAG,IAAI,IAAI,CAAC;IAClC,MAAM,KAAK,GAAG,GAAG,CAAC,KAAK,CAAC;IACxB,MAAM,IAAI,GAAG;QACX,YAAY,CAAC,GAAG,CAAC,IAAI,EAAE,GAAG,CAAC,EAAE,EAAE,GAAG,CAAC,UAAU,CAAC;QAC9C,GAAG,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC,CAAC,QAAQ,IAAI,OAAO,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,IAAI,EAAE;QAC3F,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,QAAQ,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,SAAS;QACzC,KAAK,CAAC,CAAC,CAAC,SAAS,KAAK,CAAC,KAAK,UAAU,KAAK,CAAC,KAAK,IAAI,KAAK,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,SAAS;QAC5E,OAAO,GAAG,CAAC,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,SAAS,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS;KAC5E;SACE,MAAM,CAAC,OAAO,CAAC;SACf,IAAI,CAAC,KAAK,CAAC,CAAC;IACf,MAAM,KAAK,GAAG,CAAC,EAAE,EAAE,IAAI,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC;IACrC,IAAI,GAAG,CAAC,IAAI,EAAE,KAAK,EAAE,GAAG;QAAE,KAAK,CAAC,IAAI,CAAC,aAAa,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,CAAC;IACxE,IAAI,GAAG,CAAC,IAAI,EAAE,MAAM;QAAE,KAAK,CAAC,IAAI,CAAC,aAAa,UAAU,CAAC,GAAG,CAAC,IAAI,EAAE,GAAG,CAAC,EAAE,CAAC,CAAC;IAC3E,IAAI,GAAG,CAAC,OAAO;QAAE,KAAK,CAAC,IAAI,CAAC,OAAO,OAAO,CAAC,cAAc,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,aAAa,CAAC,EAAE,CAAC,CAAC;IAC1F,IAAI,GAAG,CAAC,OAAO,EAAE,CAAC;QAChB,KAAK,CAAC,IAAI,CAAC,gBAAgB,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC;IAC5C,CAAC;SAAM,IAAI,GAAG,IAAI,KAAK,EAAE,CAAC;QACxB,KAAK,CAAC,IAAI,CACR,kCAAkC,GAAG,eAAe,KAAK,CAAC,KAAK,cAAc,KAAK,CAAC,KAAK,YAAY,KAAK,CAAC,GAAG,GAAG,CACjH,CAAC;IACJ,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,wFAAwF;AACxF,MAAM,UAAU,UAAU,CAAC,IAAuC,EAAE,GAAY;IAC9E,OAAO,IAAI;SACR,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,OAAO,EAAE,kBAAkB,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,KAAK,GAAG,IAAI,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC;SACvG,IAAI,CAAC,KAAK,CAAC,CAAC;AACjB,CAAC;AAED,SAAS,MAAM,CAAC,KAAa,EAAE,IAAY,EAAE,IAA6B;IACxE,IAAI,IAAI,CAAC,MAAM;QAAE,OAAO,kBAAkB,CAAC;IAC3C,MAAM,KAAK,GACT,IAAI,KAAK,QAAQ;QACf,CAAC,CAAC,iDAAiD;QACnD,CAAC,CAAC,yDAAyD,CAAC;IAChE,IAAI,OAAO,IAAI,CAAC,IAAI,KAAK,QAAQ,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;QAC/C,OAAO,mBAAmB,IAAI,CAAC,IAAI,YAAY,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,KAAK,IAAI,aAAa,KAAK,EAAE,CAAC;IACpG,CAAC;IACD,OAAO,uCAAuC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,KAAK,IAAI,aAAa,KAAK,oDAAoD,CAAC;AACrJ,CAAC;AAED,SAAS,QAAQ,CAAC,IAAY,EAAE,MAAiC;IAC/D,OAAO,MAAM;QACX,CAAC,CAAC,sBAAsB,IAAI,iDAAiD,MAAM,IAAI;QACvF,CAAC,CAAC,kBAAkB,CAAC;AACzB,CAAC;AAED,SAAS,YAAY,CAAC,IAAwB,EAAE,EAAU,EAAE,SAAyB;IACnF,IAAI,IAAI,KAAK,qBAAqB;QAAE,OAAO,WAAW,SAAS,IAAI,EAAE,EAAE,CAAC;IACxE,IAAI,IAAI,KAAK,cAAc;QAAE,OAAO,gBAAgB,EAAE,CAAC,OAAO,CAAC,gBAAgB,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC;IACpG,IAAI,IAAI,KAAK,SAAS;QAAE,OAAO,WAAW,EAAE,CAAC,OAAO,CAAC,WAAW,EAAE,EAAE,CAAC,EAAE,CAAC;IACxE,OAAO,WAAW,EAAE,EAAE,CAAC;AACzB,CAAC;AAED,SAAS,YAAY,CAAC,OAAyC;IAC7D,IAAI,CAAC,OAAO;QAAE,OAAO,SAAS,CAAC;IAC/B,MAAM,KAAK,GAAG,CAAC,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,GAAG,IAAI,OAAO,CAAC,GAAG,KAAK,OAAO,CAAC,IAAI,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,OAAO,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC;SAC3H,MAAM,CAAC,OAAO,CAAC;SACf,IAAI,CAAC,IAAI,CAAC,CAAC;IACd,MAAM,EAAE,GAAG,CAAC,OAAO,CAAC,MAAM,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAC1G,OAAO,CAAC,KAAK,IAAI,OAAO,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,SAAS,CAAC;AAC7E,CAAC;AAED,mEAAmE;AACnE,SAAS,SAAS,CAAC,KAAgC;IACjD,IAAI,CAAC,KAAK;QAAE,OAAO,SAAS,CAAC;IAC7B,MAAM,IAAI,GAAG,IAAI,IAAI,CAAC,KAAK,CAAC,CAAC;IAC7B,IAAI,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC;QAAE,OAAO,KAAK,CAAC;IAC/C,OAAO,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,GAAG,EAAE,GAAG,CAAC,MAAM,CAAC;AACpE,CAAC;AAED,SAAS,OAAO,CAAC,IAA+B,EAAE,GAAW;IAC3D,MAAM,IAAI,GAAG,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC;IACtD,OAAO,IAAI,CAAC,MAAM,IAAI,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,GAAG,CAAC,CAAC,GAAG,CAAC;AAClE,CAAC;AAED,0DAA0D;AAC1D,SAAS,cAAc,CAAC,IAAY;IAClC,OAAO,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC,OAAO,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;AAC5D,CAAC"}
@@ -0,0 +1,16 @@
1
+ export interface StoredMemtreeLink {
2
+ url: string;
3
+ index: string;
4
+ compressed: boolean;
5
+ updatedAt: string;
6
+ }
7
+ export declare const MEMTREE_LINKS_MAX_SESSIONS = 200;
8
+ export declare class MemtreeLinkStore {
9
+ readonly filePath: string;
10
+ private readonly maxSessions;
11
+ constructor(filePath?: string, maxSessions?: number);
12
+ get(sessionId: string): StoredMemtreeLink | undefined;
13
+ put(sessionId: string, link: Omit<StoredMemtreeLink, "updatedAt">): void;
14
+ private readAll;
15
+ }
16
+ //# sourceMappingURL=memtree-links.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"memtree-links.d.ts","sourceRoot":"","sources":["../src/memtree-links.ts"],"names":[],"mappings":"AAeA,MAAM,WAAW,iBAAiB;IAChC,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,OAAO,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,eAAO,MAAM,0BAA0B,MAAM,CAAC;AAE9C,qBAAa,gBAAgB;IAEzB,QAAQ,CAAC,QAAQ,EAAE,MAAM;IACzB,OAAO,CAAC,QAAQ,CAAC,WAAW;gBADnB,QAAQ,GAAE,MAAwD,EAC1D,WAAW,SAA6B;IAG3D,GAAG,CAAC,SAAS,EAAE,MAAM,GAAG,iBAAiB,GAAG,SAAS;IAKrD,GAAG,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,CAAC,iBAAiB,EAAE,WAAW,CAAC,GAAG,IAAI;IAkBxE,OAAO,CAAC,OAAO;CAQhB"}
@@ -0,0 +1,66 @@
1
+ /**
2
+ * The newest MemTree page per Claude Code session, kept on disk so a resumed
3
+ * session (`claude --resume`, `/resume`) can show its link before the first
4
+ * new turn. A fresh ccc process starts with no in-memory state, and the page
5
+ * URL comes only from compress responses, so without this a resumed session
6
+ * shows no link until its next compressed turn.
7
+ *
8
+ * Small JSON file, read and rewritten whole; bounded to the most recent
9
+ * sessions. Every failure is swallowed: the link is a convenience and must
10
+ * never break a request or a hook.
11
+ */
12
+ import fs from "node:fs";
13
+ import path from "node:path";
14
+ import { getConfigDir } from "./config.js";
15
+ export const MEMTREE_LINKS_MAX_SESSIONS = 200;
16
+ export class MemtreeLinkStore {
17
+ filePath;
18
+ maxSessions;
19
+ constructor(filePath = path.join(getConfigDir(), "memtree-links.json"), maxSessions = MEMTREE_LINKS_MAX_SESSIONS) {
20
+ this.filePath = filePath;
21
+ this.maxSessions = maxSessions;
22
+ }
23
+ get(sessionId) {
24
+ const entry = this.readAll()[sessionId];
25
+ return isStoredLink(entry) ? entry : undefined;
26
+ }
27
+ put(sessionId, link) {
28
+ try {
29
+ const all = this.readAll();
30
+ all[sessionId] = { ...link, updatedAt: new Date().toISOString() };
31
+ const kept = Object.entries(all)
32
+ .filter(([, v]) => isStoredLink(v))
33
+ .sort(([, a], [, b]) => b.updatedAt.localeCompare(a.updatedAt))
34
+ .slice(0, this.maxSessions);
35
+ fs.mkdirSync(path.dirname(this.filePath), { recursive: true });
36
+ // Write-then-rename so a concurrent reader never sees a torn file.
37
+ const tmp = `${this.filePath}.${process.pid}.tmp`;
38
+ fs.writeFileSync(tmp, JSON.stringify(Object.fromEntries(kept)), { mode: 0o600 });
39
+ fs.renameSync(tmp, this.filePath);
40
+ }
41
+ catch {
42
+ // A lost link is a missed convenience, never an error.
43
+ }
44
+ }
45
+ readAll() {
46
+ try {
47
+ const parsed = JSON.parse(fs.readFileSync(this.filePath, "utf-8"));
48
+ return parsed && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : {};
49
+ }
50
+ catch {
51
+ return {};
52
+ }
53
+ }
54
+ }
55
+ function isStoredLink(value) {
56
+ const v = value;
57
+ return (!!v &&
58
+ typeof v === "object" &&
59
+ typeof v.url === "string" &&
60
+ /^https?:\/\//.test(v.url) &&
61
+ typeof v.index === "string" &&
62
+ v.index.length > 0 &&
63
+ typeof v.compressed === "boolean" &&
64
+ typeof v.updatedAt === "string");
65
+ }
66
+ //# sourceMappingURL=memtree-links.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"memtree-links.js","sourceRoot":"","sources":["../src/memtree-links.ts"],"names":[],"mappings":"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"}