@fleetagent/pi-coding-agent 0.0.6 → 0.0.7

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 (153) hide show
  1. package/CHANGELOG.md +17 -0
  2. package/dist/cli/file-processor.d.ts.map +1 -1
  3. package/dist/cli/file-processor.js +2 -3
  4. package/dist/cli/file-processor.js.map +1 -1
  5. package/dist/config.d.ts.map +1 -1
  6. package/dist/config.js +15 -2
  7. package/dist/config.js.map +1 -1
  8. package/dist/core/agent-session.d.ts +9 -0
  9. package/dist/core/agent-session.d.ts.map +1 -1
  10. package/dist/core/agent-session.js +86 -15
  11. package/dist/core/agent-session.js.map +1 -1
  12. package/dist/core/export-html/template.js +6 -3
  13. package/dist/core/extensions/runner.d.ts +1 -1
  14. package/dist/core/extensions/runner.d.ts.map +1 -1
  15. package/dist/core/extensions/runner.js +8 -2
  16. package/dist/core/extensions/runner.js.map +1 -1
  17. package/dist/core/extensions/types.d.ts +4 -2
  18. package/dist/core/extensions/types.d.ts.map +1 -1
  19. package/dist/core/extensions/types.js.map +1 -1
  20. package/dist/core/model-registry.d.ts.map +1 -1
  21. package/dist/core/model-registry.js +65 -13
  22. package/dist/core/model-registry.js.map +1 -1
  23. package/dist/core/output-guard.d.ts +1 -0
  24. package/dist/core/output-guard.d.ts.map +1 -1
  25. package/dist/core/output-guard.js +52 -22
  26. package/dist/core/output-guard.js.map +1 -1
  27. package/dist/core/package-manager.d.ts.map +1 -1
  28. package/dist/core/package-manager.js +31 -12
  29. package/dist/core/package-manager.js.map +1 -1
  30. package/dist/core/pi-agent.d.ts.map +1 -1
  31. package/dist/core/pi-agent.js +12 -3
  32. package/dist/core/pi-agent.js.map +1 -1
  33. package/dist/core/resolve-config-value.d.ts +9 -1
  34. package/dist/core/resolve-config-value.d.ts.map +1 -1
  35. package/dist/core/resolve-config-value.js +134 -11
  36. package/dist/core/resolve-config-value.js.map +1 -1
  37. package/dist/core/session/jsonl-helpers.d.ts +2 -1
  38. package/dist/core/session/jsonl-helpers.d.ts.map +1 -1
  39. package/dist/core/session/jsonl-helpers.js +6 -3
  40. package/dist/core/session/jsonl-helpers.js.map +1 -1
  41. package/dist/core/session/local-session-manager.d.ts +1 -0
  42. package/dist/core/session/local-session-manager.d.ts.map +1 -1
  43. package/dist/core/session/local-session-manager.js +12 -4
  44. package/dist/core/session/local-session-manager.js.map +1 -1
  45. package/dist/core/session/session-manager.d.ts +1 -0
  46. package/dist/core/session/session-manager.d.ts.map +1 -1
  47. package/dist/core/session/session-manager.js.map +1 -1
  48. package/dist/core/session/stores/jsonl-session-store.d.ts +2 -1
  49. package/dist/core/session/stores/jsonl-session-store.d.ts.map +1 -1
  50. package/dist/core/session/stores/jsonl-session-store.js +105 -78
  51. package/dist/core/session/stores/jsonl-session-store.js.map +1 -1
  52. package/dist/core/settings-manager.d.ts +2 -0
  53. package/dist/core/settings-manager.d.ts.map +1 -1
  54. package/dist/core/settings-manager.js +14 -9
  55. package/dist/core/settings-manager.js.map +1 -1
  56. package/dist/core/tools/bash.d.ts.map +1 -1
  57. package/dist/core/tools/bash.js +73 -63
  58. package/dist/core/tools/bash.js.map +1 -1
  59. package/dist/core/tools/edit.d.ts.map +1 -1
  60. package/dist/core/tools/edit.js +45 -76
  61. package/dist/core/tools/edit.js.map +1 -1
  62. package/dist/core/tools/file-mutation-queue.d.ts.map +1 -1
  63. package/dist/core/tools/file-mutation-queue.js +27 -12
  64. package/dist/core/tools/file-mutation-queue.js.map +1 -1
  65. package/dist/core/tools/find.d.ts.map +1 -1
  66. package/dist/core/tools/find.js +11 -2
  67. package/dist/core/tools/find.js.map +1 -1
  68. package/dist/core/tools/grep.d.ts.map +1 -1
  69. package/dist/core/tools/grep.js +3 -3
  70. package/dist/core/tools/grep.js.map +1 -1
  71. package/dist/core/tools/ls.d.ts.map +1 -1
  72. package/dist/core/tools/ls.js +13 -4
  73. package/dist/core/tools/ls.js.map +1 -1
  74. package/dist/core/tools/path-utils.d.ts +1 -0
  75. package/dist/core/tools/path-utils.d.ts.map +1 -1
  76. package/dist/core/tools/path-utils.js +37 -0
  77. package/dist/core/tools/path-utils.js.map +1 -1
  78. package/dist/core/tools/read.d.ts.map +1 -1
  79. package/dist/core/tools/read.js +7 -6
  80. package/dist/core/tools/read.js.map +1 -1
  81. package/dist/core/tools/write.d.ts.map +1 -1
  82. package/dist/core/tools/write.js +24 -32
  83. package/dist/core/tools/write.js.map +1 -1
  84. package/dist/main.d.ts.map +1 -1
  85. package/dist/main.js +3 -2
  86. package/dist/main.js.map +1 -1
  87. package/dist/migrations.d.ts.map +1 -1
  88. package/dist/migrations.js +118 -1
  89. package/dist/migrations.js.map +1 -1
  90. package/dist/modes/interactive/components/footer.d.ts +1 -0
  91. package/dist/modes/interactive/components/footer.d.ts.map +1 -1
  92. package/dist/modes/interactive/components/footer.js +14 -5
  93. package/dist/modes/interactive/components/footer.js.map +1 -1
  94. package/dist/modes/interactive/components/user-message.d.ts.map +1 -1
  95. package/dist/modes/interactive/components/user-message.js +1 -1
  96. package/dist/modes/interactive/components/user-message.js.map +1 -1
  97. package/dist/modes/interactive/interactive-mode.d.ts +1 -0
  98. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  99. package/dist/modes/interactive/interactive-mode.js +30 -5
  100. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  101. package/dist/modes/interactive/theme/theme.d.ts.map +1 -1
  102. package/dist/modes/interactive/theme/theme.js +10 -0
  103. package/dist/modes/interactive/theme/theme.js.map +1 -1
  104. package/dist/modes/rpc/rpc-client.d.ts +3 -0
  105. package/dist/modes/rpc/rpc-client.d.ts.map +1 -1
  106. package/dist/modes/rpc/rpc-client.js +64 -7
  107. package/dist/modes/rpc/rpc-client.js.map +1 -1
  108. package/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
  109. package/dist/modes/rpc/rpc-mode.js +15 -3
  110. package/dist/modes/rpc/rpc-mode.js.map +1 -1
  111. package/dist/utils/clipboard-native.d.ts +3 -1
  112. package/dist/utils/clipboard-native.d.ts.map +1 -1
  113. package/dist/utils/clipboard-native.js +14 -8
  114. package/dist/utils/clipboard-native.js.map +1 -1
  115. package/dist/utils/deprecation.d.ts +4 -0
  116. package/dist/utils/deprecation.d.ts.map +1 -0
  117. package/dist/utils/deprecation.js +13 -0
  118. package/dist/utils/deprecation.js.map +1 -0
  119. package/dist/utils/image-resize-core.d.ts +30 -0
  120. package/dist/utils/image-resize-core.d.ts.map +1 -0
  121. package/dist/utils/image-resize-core.js +124 -0
  122. package/dist/utils/image-resize-core.js.map +1 -0
  123. package/dist/utils/image-resize-worker.d.ts +2 -0
  124. package/dist/utils/image-resize-worker.d.ts.map +1 -0
  125. package/dist/utils/image-resize-worker.js +31 -0
  126. package/dist/utils/image-resize-worker.js.map +1 -0
  127. package/dist/utils/image-resize.d.ts +6 -27
  128. package/dist/utils/image-resize.d.ts.map +1 -1
  129. package/dist/utils/image-resize.js +60 -116
  130. package/dist/utils/image-resize.js.map +1 -1
  131. package/dist/utils/json.d.ts +3 -0
  132. package/dist/utils/json.d.ts.map +1 -0
  133. package/dist/utils/json.js +7 -0
  134. package/dist/utils/json.js.map +1 -0
  135. package/docs/custom-provider.md +22 -9
  136. package/docs/extensions.md +4 -3
  137. package/docs/models.md +34 -12
  138. package/docs/packages.md +5 -4
  139. package/docs/providers.md +13 -5
  140. package/docs/sdk.md +56 -0
  141. package/docs/settings.md +3 -1
  142. package/docs/terminal-setup.md +6 -0
  143. package/docs/usage.md +2 -2
  144. package/examples/extensions/README.md +1 -0
  145. package/examples/extensions/custom-provider-anthropic/index.ts +1 -1
  146. package/examples/extensions/custom-provider-anthropic/package.json +1 -1
  147. package/examples/extensions/custom-provider-gitlab-duo/index.ts +54 -3
  148. package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
  149. package/examples/extensions/git-merge-and-resolve.ts +115 -0
  150. package/examples/extensions/sandbox/package.json +1 -1
  151. package/examples/extensions/with-deps/package.json +1 -1
  152. package/npm-shrinkwrap.json +13 -12
  153. package/package.json +5 -5
@@ -1,6 +1,8 @@
1
- import { appendFileSync, closeSync, existsSync, mkdirSync, openSync, readdirSync, readFileSync, readSync, statSync, writeFileSync, } from "fs";
2
- import { readdir, readFile, stat } from "fs/promises";
1
+ import { appendFileSync, closeSync, createReadStream, existsSync, mkdirSync, openSync, readdirSync, readSync, statSync, writeFileSync, } from "fs";
2
+ import { readdir, stat } from "fs/promises";
3
3
  import { join, resolve } from "path";
4
+ import { createInterface } from "readline";
5
+ import { StringDecoder } from "string_decoder";
4
6
  import { getAgentDir as getDefaultAgentDir, getSessionsDir } from "../../../config.js";
5
7
  import { InMemorySessionStore } from "./in-memory-session-store.js";
6
8
  function isMessageWithContent(message) {
@@ -16,40 +18,30 @@ function extractTextContent(message) {
16
18
  .map((block) => block.text)
17
19
  .join(" ");
18
20
  }
19
- function getLastActivityTime(entries) {
20
- let lastActivityTime;
21
- for (const entry of entries) {
22
- if (entry.type !== "message")
23
- continue;
24
- const message = entry.message;
25
- if (!isMessageWithContent(message))
26
- continue;
27
- if (message.role !== "user" && message.role !== "assistant")
28
- continue;
29
- const msgTimestamp = message.timestamp;
30
- if (typeof msgTimestamp === "number") {
31
- lastActivityTime = Math.max(lastActivityTime ?? 0, msgTimestamp);
32
- continue;
33
- }
34
- const entryTimestamp = entry.timestamp;
35
- if (typeof entryTimestamp === "string") {
36
- const t = new Date(entryTimestamp).getTime();
37
- if (!Number.isNaN(t)) {
38
- lastActivityTime = Math.max(lastActivityTime ?? 0, t);
39
- }
40
- }
21
+ function getMessageActivityTime(entry) {
22
+ const message = entry.message;
23
+ if (!isMessageWithContent(message))
24
+ return undefined;
25
+ if (message.role !== "user" && message.role !== "assistant")
26
+ return undefined;
27
+ const msgTimestamp = message.timestamp;
28
+ if (typeof msgTimestamp === "number") {
29
+ return msgTimestamp;
41
30
  }
42
- return lastActivityTime;
31
+ const t = new Date(entry.timestamp).getTime();
32
+ return Number.isNaN(t) ? undefined : t;
43
33
  }
44
- function getSessionModifiedDate(entries, header, statsMtime) {
45
- const lastActivityTime = getLastActivityTime(entries);
46
- if (typeof lastActivityTime === "number" && lastActivityTime > 0) {
47
- return new Date(lastActivityTime);
34
+ function parseSessionEntryLine(line) {
35
+ if (!line.trim())
36
+ return null;
37
+ try {
38
+ return JSON.parse(line);
39
+ }
40
+ catch {
41
+ return null;
48
42
  }
49
- const headerTime = typeof header.timestamp === "string" ? new Date(header.timestamp).getTime() : NaN;
50
- return !Number.isNaN(headerTime) ? new Date(headerTime) : statsMtime;
51
43
  }
52
- function isValidSessionFile(filePath) {
44
+ function readSessionHeader(filePath) {
53
45
  try {
54
46
  const fd = openSync(filePath, "r");
55
47
  const buffer = Buffer.alloc(512);
@@ -57,47 +49,53 @@ function isValidSessionFile(filePath) {
57
49
  closeSync(fd);
58
50
  const firstLine = buffer.toString("utf8", 0, bytesRead).split("\n")[0];
59
51
  if (!firstLine)
60
- return false;
52
+ return null;
61
53
  const header = JSON.parse(firstLine);
62
- return header.type === "session" && typeof header.id === "string";
54
+ if (header.type !== "session" || typeof header.id !== "string") {
55
+ return null;
56
+ }
57
+ return header;
63
58
  }
64
59
  catch {
65
- return false;
60
+ return null;
66
61
  }
67
62
  }
63
+ function sessionCwdMatches(cwd, resolvedCwd) {
64
+ return cwd !== undefined && cwd !== "" && resolve(cwd) === resolvedCwd;
65
+ }
68
66
  async function buildSessionInfo(filePath) {
69
67
  try {
70
- const content = await readFile(filePath, "utf8");
71
- const entries = [];
72
- const lines = content.trim().split("\n");
73
- for (const line of lines) {
74
- if (!line.trim())
75
- continue;
76
- try {
77
- entries.push(JSON.parse(line));
78
- }
79
- catch {
80
- // Skip malformed lines
81
- }
82
- }
83
- if (entries.length === 0)
84
- return null;
85
- const header = entries[0];
86
- if (header.type !== "session")
87
- return null;
88
68
  const stats = await stat(filePath);
69
+ let header = null;
89
70
  let messageCount = 0;
90
71
  let firstMessage = "";
91
72
  const allMessages = [];
92
73
  let name;
93
- for (const entry of entries) {
74
+ let lastActivityTime;
75
+ const rl = createInterface({
76
+ input: createReadStream(filePath, { encoding: "utf8" }),
77
+ crlfDelay: Infinity,
78
+ });
79
+ for await (const line of rl) {
80
+ const entry = parseSessionEntryLine(line);
81
+ if (!entry)
82
+ continue;
83
+ if (!header) {
84
+ if (entry.type !== "session")
85
+ return null;
86
+ header = entry;
87
+ continue;
88
+ }
94
89
  if (entry.type === "session_info") {
95
- const infoEntry = entry;
96
- name = infoEntry.name?.trim() || undefined;
90
+ name = entry.name?.trim() || undefined;
97
91
  }
98
92
  if (entry.type !== "message")
99
93
  continue;
100
94
  messageCount++;
95
+ const activityTime = getMessageActivityTime(entry);
96
+ if (typeof activityTime === "number") {
97
+ lastActivityTime = Math.max(lastActivityTime ?? 0, activityTime);
98
+ }
101
99
  const message = entry.message;
102
100
  if (!isMessageWithContent(message))
103
101
  continue;
@@ -111,18 +109,24 @@ async function buildSessionInfo(filePath) {
111
109
  firstMessage = textContent;
112
110
  }
113
111
  }
114
- const sessionHeader = header;
115
- const cwd = typeof sessionHeader.cwd === "string" ? sessionHeader.cwd : "";
116
- const parentSessionPath = sessionHeader.parentSession;
117
- const modified = getSessionModifiedDate(entries, sessionHeader, stats.mtime);
112
+ if (!header)
113
+ return null;
114
+ const cwd = typeof header.cwd === "string" ? header.cwd : "";
115
+ const parentSessionPath = header.parentSession;
116
+ const headerTime = typeof header.timestamp === "string" ? new Date(header.timestamp).getTime() : NaN;
117
+ const modified = typeof lastActivityTime === "number" && lastActivityTime > 0
118
+ ? new Date(lastActivityTime)
119
+ : !Number.isNaN(headerTime)
120
+ ? new Date(headerTime)
121
+ : stats.mtime;
118
122
  return {
119
123
  reference: filePath,
120
124
  path: filePath,
121
- id: sessionHeader.id,
125
+ id: header.id,
122
126
  cwd,
123
127
  name,
124
128
  parentSessionPath,
125
- created: new Date(sessionHeader.timestamp),
129
+ created: new Date(header.timestamp),
126
130
  modified,
127
131
  messageCount,
128
132
  firstMessage: firstMessage || "(no messages)",
@@ -137,9 +141,13 @@ const MAX_CONCURRENT_SESSION_INFO_LOADS = 10;
137
141
  export function getSessionDirForReference(reference) {
138
142
  return resolve(reference, "..");
139
143
  }
144
+ export function getDefaultSessionDirPath(cwd, agentDir = getDefaultAgentDir()) {
145
+ const resolvedCwd = resolve(cwd);
146
+ const safePath = `--${resolvedCwd.replace(/^[/\\]/, "").replace(/[/\\:]/g, "-")}--`;
147
+ return join(resolve(agentDir), "sessions", safePath);
148
+ }
140
149
  export function getDefaultSessionDir(cwd, agentDir = getDefaultAgentDir()) {
141
- const safePath = `--${cwd.replace(/^[/\\]/, "").replace(/[/\\:]/g, "-")}--`;
142
- const sessionDir = join(agentDir, "sessions", safePath);
150
+ const sessionDir = getDefaultSessionDirPath(cwd, agentDir);
143
151
  ensureDir(sessionDir);
144
152
  return sessionDir;
145
153
  }
@@ -158,22 +166,39 @@ export function ensureDir(path) {
158
166
  mkdirSync(path, { recursive: true });
159
167
  }
160
168
  }
169
+ const SESSION_READ_BUFFER_SIZE = 1024 * 1024;
161
170
  export function load(filePath) {
162
171
  if (!existsSync(filePath))
163
172
  return [];
164
- const content = readFileSync(filePath, "utf8");
165
173
  const entries = [];
166
- const lines = content.trim().split("\n");
167
- for (const line of lines) {
168
- if (!line.trim())
169
- continue;
170
- try {
171
- const entry = JSON.parse(line);
172
- entries.push(entry);
173
- }
174
- catch {
175
- // Skip malformed lines
174
+ const fd = openSync(filePath, "r");
175
+ try {
176
+ const decoder = new StringDecoder("utf8");
177
+ const buffer = Buffer.allocUnsafe(SESSION_READ_BUFFER_SIZE);
178
+ let pending = "";
179
+ while (true) {
180
+ const bytesRead = readSync(fd, buffer, 0, buffer.length, null);
181
+ if (bytesRead === 0)
182
+ break;
183
+ pending += decoder.write(buffer.subarray(0, bytesRead));
184
+ let lineStart = 0;
185
+ let newlineIndex = pending.indexOf("\n", lineStart);
186
+ while (newlineIndex !== -1) {
187
+ const entry = parseSessionEntryLine(pending.slice(lineStart, newlineIndex));
188
+ if (entry)
189
+ entries.push(entry);
190
+ lineStart = newlineIndex + 1;
191
+ newlineIndex = pending.indexOf("\n", lineStart);
192
+ }
193
+ pending = pending.slice(lineStart);
176
194
  }
195
+ pending += decoder.end();
196
+ const finalEntry = parseSessionEntryLine(pending);
197
+ if (finalEntry)
198
+ entries.push(finalEntry);
199
+ }
200
+ finally {
201
+ closeSync(fd);
177
202
  }
178
203
  if (entries.length === 0)
179
204
  return entries;
@@ -200,13 +225,15 @@ export function forkSession(sessionDir, header, sourceEntries) {
200
225
  }
201
226
  return reference;
202
227
  }
203
- export function findMostRecent(sessionDir) {
228
+ export function findMostRecent(sessionDir, cwd) {
229
+ const resolvedCwd = cwd ? resolve(cwd) : undefined;
204
230
  try {
205
231
  const files = readdirSync(sessionDir)
206
232
  .filter((file) => file.endsWith(".jsonl"))
207
233
  .map((file) => join(sessionDir, file))
208
- .filter(isValidSessionFile)
209
- .map((path) => ({ path, mtime: statSync(path).mtime }))
234
+ .map((path) => ({ path, header: readSessionHeader(path) }))
235
+ .filter((file) => file.header !== null && (!resolvedCwd || sessionCwdMatches(file.header.cwd, resolvedCwd)))
236
+ .map(({ path }) => ({ path, mtime: statSync(path).mtime }))
210
237
  .sort((a, b) => b.mtime.getTime() - a.mtime.getTime());
211
238
  return files[0]?.path || null;
212
239
  }
@@ -1 +1 @@
1
- {"version":3,"file":"jsonl-session-store.js","sourceRoot":"","sources":["../../../../src/core/session/stores/jsonl-session-store.ts"],"names":[],"mappings":"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","sourcesContent":["import type { AgentMessage } from \"@fleetagent/pi-agent-core\";\nimport type { Message, TextContent } from \"@fleetagent/pi-ai\";\nimport {\n\tappendFileSync,\n\tcloseSync,\n\texistsSync,\n\tmkdirSync,\n\topenSync,\n\treaddirSync,\n\treadFileSync,\n\treadSync,\n\tstatSync,\n\twriteFileSync,\n} from \"fs\";\nimport { readdir, readFile, stat } from \"fs/promises\";\nimport { join, resolve } from \"path\";\nimport { getAgentDir as getDefaultAgentDir, getSessionsDir } from \"../../../config.ts\";\nimport type {\n\tFileEntry,\n\tSessionEntry,\n\tSessionEntryBase,\n\tSessionHeader,\n\tSessionInfo,\n\tSessionInfoEntry,\n\tSessionListProgress,\n\tSessionMessageEntry,\n} from \"../types.ts\";\nimport { InMemorySessionStore } from \"./in-memory-session-store.ts\";\n\nfunction isMessageWithContent(message: AgentMessage): message is Message {\n\treturn typeof (message as Message).role === \"string\" && \"content\" in message;\n}\n\nfunction extractTextContent(message: Message): string {\n\tconst content = message.content;\n\tif (typeof content === \"string\") {\n\t\treturn content;\n\t}\n\treturn content\n\t\t.filter((block): block is TextContent => block.type === \"text\")\n\t\t.map((block) => block.text)\n\t\t.join(\" \");\n}\n\nfunction getLastActivityTime(entries: FileEntry[]): number | undefined {\n\tlet lastActivityTime: number | undefined;\n\n\tfor (const entry of entries) {\n\t\tif (entry.type !== \"message\") continue;\n\n\t\tconst message = (entry as SessionMessageEntry).message;\n\t\tif (!isMessageWithContent(message)) continue;\n\t\tif (message.role !== \"user\" && message.role !== \"assistant\") continue;\n\n\t\tconst msgTimestamp = (message as { timestamp?: number }).timestamp;\n\t\tif (typeof msgTimestamp === \"number\") {\n\t\t\tlastActivityTime = Math.max(lastActivityTime ?? 0, msgTimestamp);\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst entryTimestamp = (entry as SessionEntryBase).timestamp;\n\t\tif (typeof entryTimestamp === \"string\") {\n\t\t\tconst t = new Date(entryTimestamp).getTime();\n\t\t\tif (!Number.isNaN(t)) {\n\t\t\t\tlastActivityTime = Math.max(lastActivityTime ?? 0, t);\n\t\t\t}\n\t\t}\n\t}\n\n\treturn lastActivityTime;\n}\n\nfunction getSessionModifiedDate(entries: FileEntry[], header: SessionHeader, statsMtime: Date): Date {\n\tconst lastActivityTime = getLastActivityTime(entries);\n\tif (typeof lastActivityTime === \"number\" && lastActivityTime > 0) {\n\t\treturn new Date(lastActivityTime);\n\t}\n\n\tconst headerTime = typeof header.timestamp === \"string\" ? new Date(header.timestamp).getTime() : NaN;\n\treturn !Number.isNaN(headerTime) ? new Date(headerTime) : statsMtime;\n}\n\nfunction isValidSessionFile(filePath: string): boolean {\n\ttry {\n\t\tconst fd = openSync(filePath, \"r\");\n\t\tconst buffer = Buffer.alloc(512);\n\t\tconst bytesRead = readSync(fd, buffer, 0, 512, 0);\n\t\tcloseSync(fd);\n\t\tconst firstLine = buffer.toString(\"utf8\", 0, bytesRead).split(\"\\n\")[0];\n\t\tif (!firstLine) return false;\n\t\tconst header = JSON.parse(firstLine) as Partial<SessionHeader>;\n\t\treturn header.type === \"session\" && typeof header.id === \"string\";\n\t} catch {\n\t\treturn false;\n\t}\n}\n\nasync function buildSessionInfo(filePath: string): Promise<SessionInfo | null> {\n\ttry {\n\t\tconst content = await readFile(filePath, \"utf8\");\n\t\tconst entries: FileEntry[] = [];\n\t\tconst lines = content.trim().split(\"\\n\");\n\n\t\tfor (const line of lines) {\n\t\t\tif (!line.trim()) continue;\n\t\t\ttry {\n\t\t\t\tentries.push(JSON.parse(line) as FileEntry);\n\t\t\t} catch {\n\t\t\t\t// Skip malformed lines\n\t\t\t}\n\t\t}\n\n\t\tif (entries.length === 0) return null;\n\t\tconst header = entries[0];\n\t\tif (header.type !== \"session\") return null;\n\n\t\tconst stats = await stat(filePath);\n\t\tlet messageCount = 0;\n\t\tlet firstMessage = \"\";\n\t\tconst allMessages: string[] = [];\n\t\tlet name: string | undefined;\n\n\t\tfor (const entry of entries) {\n\t\t\tif (entry.type === \"session_info\") {\n\t\t\t\tconst infoEntry = entry as SessionInfoEntry;\n\t\t\t\tname = infoEntry.name?.trim() || undefined;\n\t\t\t}\n\n\t\t\tif (entry.type !== \"message\") continue;\n\t\t\tmessageCount++;\n\n\t\t\tconst message = (entry as SessionMessageEntry).message;\n\t\t\tif (!isMessageWithContent(message)) continue;\n\t\t\tif (message.role !== \"user\" && message.role !== \"assistant\") continue;\n\n\t\t\tconst textContent = extractTextContent(message);\n\t\t\tif (!textContent) continue;\n\n\t\t\tallMessages.push(textContent);\n\t\t\tif (!firstMessage && message.role === \"user\") {\n\t\t\t\tfirstMessage = textContent;\n\t\t\t}\n\t\t}\n\n\t\tconst sessionHeader = header as SessionHeader;\n\t\tconst cwd = typeof sessionHeader.cwd === \"string\" ? sessionHeader.cwd : \"\";\n\t\tconst parentSessionPath = sessionHeader.parentSession;\n\t\tconst modified = getSessionModifiedDate(entries, sessionHeader, stats.mtime);\n\n\t\treturn {\n\t\t\treference: filePath,\n\t\t\tpath: filePath,\n\t\t\tid: sessionHeader.id,\n\t\t\tcwd,\n\t\t\tname,\n\t\t\tparentSessionPath,\n\t\t\tcreated: new Date(sessionHeader.timestamp),\n\t\t\tmodified,\n\t\t\tmessageCount,\n\t\t\tfirstMessage: firstMessage || \"(no messages)\",\n\t\t\tallMessagesText: allMessages.join(\" \"),\n\t\t};\n\t} catch {\n\t\treturn null;\n\t}\n}\n\nconst MAX_CONCURRENT_SESSION_INFO_LOADS = 10;\n\nexport function getSessionDirForReference(reference: string): string {\n\treturn resolve(reference, \"..\");\n}\n\nexport function getDefaultSessionDir(cwd: string, agentDir: string = getDefaultAgentDir()): string {\n\tconst safePath = `--${cwd.replace(/^[/\\\\]/, \"\").replace(/[/\\\\:]/g, \"-\")}--`;\n\tconst sessionDir = join(agentDir, \"sessions\", safePath);\n\tensureDir(sessionDir);\n\treturn sessionDir;\n}\n\nexport function getSessionsRoot(): string {\n\treturn getSessionsDir();\n}\n\nexport function prepareSessionReference(sessionDir: string, sessionId: string, timestamp: string): string {\n\tconst fileTimestamp = timestamp.replace(/[:.]/g, \"-\");\n\treturn join(sessionDir, `${fileTimestamp}_${sessionId}.jsonl`);\n}\n\nexport function exists(path: string): boolean {\n\treturn existsSync(path);\n}\n\nexport function ensureDir(path: string): void {\n\tif (!existsSync(path)) {\n\t\tmkdirSync(path, { recursive: true });\n\t}\n}\n\nexport function load(filePath: string): FileEntry[] {\n\tif (!existsSync(filePath)) return [];\n\n\tconst content = readFileSync(filePath, \"utf8\");\n\tconst entries: FileEntry[] = [];\n\tconst lines = content.trim().split(\"\\n\");\n\n\tfor (const line of lines) {\n\t\tif (!line.trim()) continue;\n\t\ttry {\n\t\t\tconst entry = JSON.parse(line) as FileEntry;\n\t\t\tentries.push(entry);\n\t\t} catch {\n\t\t\t// Skip malformed lines\n\t\t}\n\t}\n\n\tif (entries.length === 0) return entries;\n\tconst header = entries[0];\n\tif (header.type !== \"session\" || typeof (header as Partial<SessionHeader>).id !== \"string\") {\n\t\treturn [];\n\t}\n\n\treturn entries;\n}\n\nexport function append(filePath: string, entry: FileEntry): void {\n\tappendFileSync(filePath, `${JSON.stringify(entry)}\\n`);\n}\n\nexport function rewrite(filePath: string, entries: FileEntry[]): void {\n\tconst content = `${entries.map((entry) => JSON.stringify(entry)).join(\"\\n\")}\\n`;\n\twriteFileSync(filePath, content);\n}\n\nexport function forkSession(sessionDir: string, header: SessionHeader, sourceEntries: FileEntry[]): string {\n\tconst reference = prepareSessionReference(sessionDir, header.id, header.timestamp);\n\tappend(reference, header);\n\tfor (const entry of sourceEntries) {\n\t\tif (entry.type !== \"session\") {\n\t\t\tappend(reference, entry);\n\t\t}\n\t}\n\treturn reference;\n}\n\nexport function findMostRecent(sessionDir: string): string | null {\n\ttry {\n\t\tconst files = readdirSync(sessionDir)\n\t\t\t.filter((file) => file.endsWith(\".jsonl\"))\n\t\t\t.map((file) => join(sessionDir, file))\n\t\t\t.filter(isValidSessionFile)\n\t\t\t.map((path) => ({ path, mtime: statSync(path).mtime }))\n\t\t\t.sort((a, b) => b.mtime.getTime() - a.mtime.getTime());\n\n\t\treturn files[0]?.path || null;\n\t} catch {\n\t\treturn null;\n\t}\n}\n\nexport async function list(dir: string, onProgress?: SessionListProgress): Promise<SessionInfo[]> {\n\tconst sessions: SessionInfo[] = [];\n\tif (!existsSync(dir)) {\n\t\treturn sessions;\n\t}\n\n\ttry {\n\t\tconst dirEntries = await readdir(dir);\n\t\tconst files = dirEntries.filter((file) => file.endsWith(\".jsonl\")).map((file) => join(dir, file));\n\t\tlet loaded = 0;\n\t\tconst results = await buildSessionInfosWithConcurrency(files, () => {\n\t\t\tloaded++;\n\t\t\tonProgress?.(loaded, files.length);\n\t\t});\n\t\tfor (const info of results) {\n\t\t\tif (info) {\n\t\t\t\tsessions.push(info);\n\t\t\t}\n\t\t}\n\t} catch {\n\t\t// Return empty list on error\n\t}\n\n\treturn sessions;\n}\n\nexport async function listAll(sessionsDir: string, onProgress?: SessionListProgress): Promise<SessionInfo[]> {\n\ttry {\n\t\tif (!existsSync(sessionsDir)) {\n\t\t\treturn [];\n\t\t}\n\t\tconst entries = await readdir(sessionsDir, { withFileTypes: true });\n\t\tconst dirs = entries.filter((entry) => entry.isDirectory()).map((entry) => join(sessionsDir, entry.name));\n\n\t\tlet totalFiles = 0;\n\t\tconst dirFiles: string[][] = [];\n\t\tfor (const dir of dirs) {\n\t\t\ttry {\n\t\t\t\tconst files = (await readdir(dir)).filter((file) => file.endsWith(\".jsonl\"));\n\t\t\t\tdirFiles.push(files.map((file) => join(dir, file)));\n\t\t\t\ttotalFiles += files.length;\n\t\t\t} catch {\n\t\t\t\tdirFiles.push([]);\n\t\t\t}\n\t\t}\n\n\t\tlet loaded = 0;\n\t\tconst sessions: SessionInfo[] = [];\n\t\tconst allFiles = dirFiles.flat();\n\t\tconst results = await buildSessionInfosWithConcurrency(allFiles, () => {\n\t\t\tloaded++;\n\t\t\tonProgress?.(loaded, totalFiles);\n\t\t});\n\n\t\tfor (const info of results) {\n\t\t\tif (info) {\n\t\t\t\tsessions.push(info);\n\t\t\t}\n\t\t}\n\n\t\treturn sessions;\n\t} catch {\n\t\treturn [];\n\t}\n}\n\nasync function buildSessionInfosWithConcurrency(\n\tfiles: string[],\n\tonLoaded: () => void,\n): Promise<(SessionInfo | null)[]> {\n\tconst results: (SessionInfo | null)[] = new Array(files.length).fill(null);\n\tconst inFlight = new Set<Promise<void>>();\n\tlet nextIndex = 0;\n\n\tconst startNext = (): void => {\n\t\tconst index = nextIndex++;\n\t\tconst file = files[index];\n\t\tif (!file) return;\n\n\t\tlet task: Promise<void>;\n\t\ttask = buildSessionInfo(file)\n\t\t\t.then((info) => {\n\t\t\t\tresults[index] = info;\n\t\t\t})\n\t\t\t.catch(() => {\n\t\t\t\tresults[index] = null;\n\t\t\t})\n\t\t\t.finally(() => {\n\t\t\t\tinFlight.delete(task);\n\t\t\t\tonLoaded();\n\t\t\t});\n\t\tinFlight.add(task);\n\t};\n\n\twhile (nextIndex < files.length || inFlight.size > 0) {\n\t\twhile (nextIndex < files.length && inFlight.size < MAX_CONCURRENT_SESSION_INFO_LOADS) {\n\t\t\tstartNext();\n\t\t}\n\t\tif (inFlight.size > 0) {\n\t\t\tawait Promise.race(inFlight);\n\t\t}\n\t}\n\n\treturn results;\n}\n\nexport class JsonlSessionStore extends InMemorySessionStore {\n\tprivate reference: string | undefined;\n\tprivate flushed = false;\n\n\tisPersisted(): boolean {\n\t\treturn true;\n\t}\n\n\tgetSessionReference(): string | undefined {\n\t\treturn this.reference;\n\t}\n\n\tsetSessionReference(reference: string): void {\n\t\tthis.reference = resolve(reference);\n\t\tthis.flushed = false;\n\t}\n\n\texists(path: string): boolean {\n\t\treturn exists(path);\n\t}\n\n\tensureDir(path: string): void {\n\t\tensureDir(path);\n\t}\n\n\tload(filePath: string): FileEntry[] {\n\t\tif (!exists(filePath)) return [];\n\t\tthis.flushed = true;\n\t\treturn load(filePath);\n\t}\n\n\tappendEntry(entry: SessionEntry): void {\n\t\tsuper.appendEntry(entry);\n\t\tthis.persistAppendedEntry(entry);\n\t}\n\n\tprivate persistAppendedEntry(entry: SessionEntry): void {\n\t\tif (!this.reference) return;\n\n\t\tif (!this.hasAssistantMessage()) {\n\t\t\tthis.flushed = false;\n\t\t\treturn;\n\t\t}\n\n\t\tif (!this.flushed) {\n\t\t\tfor (const fileEntry of this.getFileEntries()) {\n\t\t\t\tappend(this.reference, fileEntry);\n\t\t\t}\n\t\t\tthis.flushed = true;\n\t\t} else {\n\t\t\tappend(this.reference, entry);\n\t\t}\n\t}\n\n\tsaveSnapshot(): void {\n\t\tif (!this.reference) return;\n\t\trewrite(this.reference, this.getFileEntries());\n\t\tthis.flushed = true;\n\t}\n\n\tcommitSnapshot(): void {\n\t\tif (!this.hasAssistantMessage()) {\n\t\t\tthis.flushed = false;\n\t\t\treturn;\n\t\t}\n\t\tthis.saveSnapshot();\n\t}\n}\n"]}
1
+ {"version":3,"file":"jsonl-session-store.js","sourceRoot":"","sources":["../../../../src/core/session/stores/jsonl-session-store.ts"],"names":[],"mappings":"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","sourcesContent":["import type { AgentMessage } from \"@fleetagent/pi-agent-core\";\nimport type { Message, TextContent } from \"@fleetagent/pi-ai\";\nimport {\n\tappendFileSync,\n\tcloseSync,\n\tcreateReadStream,\n\texistsSync,\n\tmkdirSync,\n\topenSync,\n\treaddirSync,\n\treadSync,\n\tstatSync,\n\twriteFileSync,\n} from \"fs\";\nimport { readdir, stat } from \"fs/promises\";\nimport { join, resolve } from \"path\";\nimport { createInterface } from \"readline\";\nimport { StringDecoder } from \"string_decoder\";\nimport { getAgentDir as getDefaultAgentDir, getSessionsDir } from \"../../../config.ts\";\nimport type {\n\tFileEntry,\n\tSessionEntry,\n\tSessionHeader,\n\tSessionInfo,\n\tSessionListProgress,\n\tSessionMessageEntry,\n} from \"../types.ts\";\nimport { InMemorySessionStore } from \"./in-memory-session-store.ts\";\n\nfunction isMessageWithContent(message: AgentMessage): message is Message {\n\treturn typeof (message as Message).role === \"string\" && \"content\" in message;\n}\n\nfunction extractTextContent(message: Message): string {\n\tconst content = message.content;\n\tif (typeof content === \"string\") {\n\t\treturn content;\n\t}\n\treturn content\n\t\t.filter((block): block is TextContent => block.type === \"text\")\n\t\t.map((block) => block.text)\n\t\t.join(\" \");\n}\n\nfunction getMessageActivityTime(entry: SessionMessageEntry): number | undefined {\n\tconst message = entry.message;\n\tif (!isMessageWithContent(message)) return undefined;\n\tif (message.role !== \"user\" && message.role !== \"assistant\") return undefined;\n\n\tconst msgTimestamp = (message as { timestamp?: number }).timestamp;\n\tif (typeof msgTimestamp === \"number\") {\n\t\treturn msgTimestamp;\n\t}\n\n\tconst t = new Date(entry.timestamp).getTime();\n\treturn Number.isNaN(t) ? undefined : t;\n}\n\nfunction parseSessionEntryLine(line: string): FileEntry | null {\n\tif (!line.trim()) return null;\n\ttry {\n\t\treturn JSON.parse(line) as FileEntry;\n\t} catch {\n\t\treturn null;\n\t}\n}\n\nfunction readSessionHeader(filePath: string): SessionHeader | null {\n\ttry {\n\t\tconst fd = openSync(filePath, \"r\");\n\t\tconst buffer = Buffer.alloc(512);\n\t\tconst bytesRead = readSync(fd, buffer, 0, 512, 0);\n\t\tcloseSync(fd);\n\t\tconst firstLine = buffer.toString(\"utf8\", 0, bytesRead).split(\"\\n\")[0];\n\t\tif (!firstLine) return null;\n\t\tconst header = JSON.parse(firstLine) as Partial<SessionHeader>;\n\t\tif (header.type !== \"session\" || typeof header.id !== \"string\") {\n\t\t\treturn null;\n\t\t}\n\t\treturn header as SessionHeader;\n\t} catch {\n\t\treturn null;\n\t}\n}\n\nfunction sessionCwdMatches(cwd: string | undefined, resolvedCwd: string): boolean {\n\treturn cwd !== undefined && cwd !== \"\" && resolve(cwd) === resolvedCwd;\n}\n\nasync function buildSessionInfo(filePath: string): Promise<SessionInfo | null> {\n\ttry {\n\t\tconst stats = await stat(filePath);\n\t\tlet header: SessionHeader | null = null;\n\t\tlet messageCount = 0;\n\t\tlet firstMessage = \"\";\n\t\tconst allMessages: string[] = [];\n\t\tlet name: string | undefined;\n\t\tlet lastActivityTime: number | undefined;\n\n\t\tconst rl = createInterface({\n\t\t\tinput: createReadStream(filePath, { encoding: \"utf8\" }),\n\t\t\tcrlfDelay: Infinity,\n\t\t});\n\n\t\tfor await (const line of rl) {\n\t\t\tconst entry = parseSessionEntryLine(line);\n\t\t\tif (!entry) continue;\n\n\t\t\tif (!header) {\n\t\t\t\tif (entry.type !== \"session\") return null;\n\t\t\t\theader = entry;\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tif (entry.type === \"session_info\") {\n\t\t\t\tname = entry.name?.trim() || undefined;\n\t\t\t}\n\n\t\t\tif (entry.type !== \"message\") continue;\n\t\t\tmessageCount++;\n\n\t\t\tconst activityTime = getMessageActivityTime(entry);\n\t\t\tif (typeof activityTime === \"number\") {\n\t\t\t\tlastActivityTime = Math.max(lastActivityTime ?? 0, activityTime);\n\t\t\t}\n\n\t\t\tconst message = entry.message;\n\t\t\tif (!isMessageWithContent(message)) continue;\n\t\t\tif (message.role !== \"user\" && message.role !== \"assistant\") continue;\n\n\t\t\tconst textContent = extractTextContent(message);\n\t\t\tif (!textContent) continue;\n\n\t\t\tallMessages.push(textContent);\n\t\t\tif (!firstMessage && message.role === \"user\") {\n\t\t\t\tfirstMessage = textContent;\n\t\t\t}\n\t\t}\n\n\t\tif (!header) return null;\n\n\t\tconst cwd = typeof header.cwd === \"string\" ? header.cwd : \"\";\n\t\tconst parentSessionPath = header.parentSession;\n\t\tconst headerTime = typeof header.timestamp === \"string\" ? new Date(header.timestamp).getTime() : NaN;\n\t\tconst modified =\n\t\t\ttypeof lastActivityTime === \"number\" && lastActivityTime > 0\n\t\t\t\t? new Date(lastActivityTime)\n\t\t\t\t: !Number.isNaN(headerTime)\n\t\t\t\t\t? new Date(headerTime)\n\t\t\t\t\t: stats.mtime;\n\n\t\treturn {\n\t\t\treference: filePath,\n\t\t\tpath: filePath,\n\t\t\tid: header.id,\n\t\t\tcwd,\n\t\t\tname,\n\t\t\tparentSessionPath,\n\t\t\tcreated: new Date(header.timestamp),\n\t\t\tmodified,\n\t\t\tmessageCount,\n\t\t\tfirstMessage: firstMessage || \"(no messages)\",\n\t\t\tallMessagesText: allMessages.join(\" \"),\n\t\t};\n\t} catch {\n\t\treturn null;\n\t}\n}\n\nconst MAX_CONCURRENT_SESSION_INFO_LOADS = 10;\n\nexport function getSessionDirForReference(reference: string): string {\n\treturn resolve(reference, \"..\");\n}\n\nexport function getDefaultSessionDirPath(cwd: string, agentDir: string = getDefaultAgentDir()): string {\n\tconst resolvedCwd = resolve(cwd);\n\tconst safePath = `--${resolvedCwd.replace(/^[/\\\\]/, \"\").replace(/[/\\\\:]/g, \"-\")}--`;\n\treturn join(resolve(agentDir), \"sessions\", safePath);\n}\n\nexport function getDefaultSessionDir(cwd: string, agentDir: string = getDefaultAgentDir()): string {\n\tconst sessionDir = getDefaultSessionDirPath(cwd, agentDir);\n\tensureDir(sessionDir);\n\treturn sessionDir;\n}\n\nexport function getSessionsRoot(): string {\n\treturn getSessionsDir();\n}\n\nexport function prepareSessionReference(sessionDir: string, sessionId: string, timestamp: string): string {\n\tconst fileTimestamp = timestamp.replace(/[:.]/g, \"-\");\n\treturn join(sessionDir, `${fileTimestamp}_${sessionId}.jsonl`);\n}\n\nexport function exists(path: string): boolean {\n\treturn existsSync(path);\n}\n\nexport function ensureDir(path: string): void {\n\tif (!existsSync(path)) {\n\t\tmkdirSync(path, { recursive: true });\n\t}\n}\n\nconst SESSION_READ_BUFFER_SIZE = 1024 * 1024;\n\nexport function load(filePath: string): FileEntry[] {\n\tif (!existsSync(filePath)) return [];\n\n\tconst entries: FileEntry[] = [];\n\tconst fd = openSync(filePath, \"r\");\n\ttry {\n\t\tconst decoder = new StringDecoder(\"utf8\");\n\t\tconst buffer = Buffer.allocUnsafe(SESSION_READ_BUFFER_SIZE);\n\t\tlet pending = \"\";\n\n\t\twhile (true) {\n\t\t\tconst bytesRead = readSync(fd, buffer, 0, buffer.length, null);\n\t\t\tif (bytesRead === 0) break;\n\n\t\t\tpending += decoder.write(buffer.subarray(0, bytesRead));\n\t\t\tlet lineStart = 0;\n\t\t\tlet newlineIndex = pending.indexOf(\"\\n\", lineStart);\n\t\t\twhile (newlineIndex !== -1) {\n\t\t\t\tconst entry = parseSessionEntryLine(pending.slice(lineStart, newlineIndex));\n\t\t\t\tif (entry) entries.push(entry);\n\t\t\t\tlineStart = newlineIndex + 1;\n\t\t\t\tnewlineIndex = pending.indexOf(\"\\n\", lineStart);\n\t\t\t}\n\t\t\tpending = pending.slice(lineStart);\n\t\t}\n\n\t\tpending += decoder.end();\n\t\tconst finalEntry = parseSessionEntryLine(pending);\n\t\tif (finalEntry) entries.push(finalEntry);\n\t} finally {\n\t\tcloseSync(fd);\n\t}\n\n\tif (entries.length === 0) return entries;\n\tconst header = entries[0];\n\tif (header.type !== \"session\" || typeof (header as Partial<SessionHeader>).id !== \"string\") {\n\t\treturn [];\n\t}\n\n\treturn entries;\n}\n\nexport function append(filePath: string, entry: FileEntry): void {\n\tappendFileSync(filePath, `${JSON.stringify(entry)}\\n`);\n}\n\nexport function rewrite(filePath: string, entries: FileEntry[]): void {\n\tconst content = `${entries.map((entry) => JSON.stringify(entry)).join(\"\\n\")}\\n`;\n\twriteFileSync(filePath, content);\n}\n\nexport function forkSession(sessionDir: string, header: SessionHeader, sourceEntries: FileEntry[]): string {\n\tconst reference = prepareSessionReference(sessionDir, header.id, header.timestamp);\n\tappend(reference, header);\n\tfor (const entry of sourceEntries) {\n\t\tif (entry.type !== \"session\") {\n\t\t\tappend(reference, entry);\n\t\t}\n\t}\n\treturn reference;\n}\n\nexport function findMostRecent(sessionDir: string, cwd?: string): string | null {\n\tconst resolvedCwd = cwd ? resolve(cwd) : undefined;\n\ttry {\n\t\tconst files = readdirSync(sessionDir)\n\t\t\t.filter((file) => file.endsWith(\".jsonl\"))\n\t\t\t.map((file) => join(sessionDir, file))\n\t\t\t.map((path) => ({ path, header: readSessionHeader(path) }))\n\t\t\t.filter(\n\t\t\t\t(file): file is { path: string; header: SessionHeader } =>\n\t\t\t\t\tfile.header !== null && (!resolvedCwd || sessionCwdMatches(file.header.cwd, resolvedCwd)),\n\t\t\t)\n\t\t\t.map(({ path }) => ({ path, mtime: statSync(path).mtime }))\n\t\t\t.sort((a, b) => b.mtime.getTime() - a.mtime.getTime());\n\n\t\treturn files[0]?.path || null;\n\t} catch {\n\t\treturn null;\n\t}\n}\n\nexport async function list(dir: string, onProgress?: SessionListProgress): Promise<SessionInfo[]> {\n\tconst sessions: SessionInfo[] = [];\n\tif (!existsSync(dir)) {\n\t\treturn sessions;\n\t}\n\n\ttry {\n\t\tconst dirEntries = await readdir(dir);\n\t\tconst files = dirEntries.filter((file) => file.endsWith(\".jsonl\")).map((file) => join(dir, file));\n\t\tlet loaded = 0;\n\t\tconst results = await buildSessionInfosWithConcurrency(files, () => {\n\t\t\tloaded++;\n\t\t\tonProgress?.(loaded, files.length);\n\t\t});\n\t\tfor (const info of results) {\n\t\t\tif (info) {\n\t\t\t\tsessions.push(info);\n\t\t\t}\n\t\t}\n\t} catch {\n\t\t// Return empty list on error\n\t}\n\n\treturn sessions;\n}\n\nexport async function listAll(sessionsDir: string, onProgress?: SessionListProgress): Promise<SessionInfo[]> {\n\ttry {\n\t\tif (!existsSync(sessionsDir)) {\n\t\t\treturn [];\n\t\t}\n\t\tconst entries = await readdir(sessionsDir, { withFileTypes: true });\n\t\tconst dirs = entries.filter((entry) => entry.isDirectory()).map((entry) => join(sessionsDir, entry.name));\n\n\t\tlet totalFiles = 0;\n\t\tconst dirFiles: string[][] = [];\n\t\tfor (const dir of dirs) {\n\t\t\ttry {\n\t\t\t\tconst files = (await readdir(dir)).filter((file) => file.endsWith(\".jsonl\"));\n\t\t\t\tdirFiles.push(files.map((file) => join(dir, file)));\n\t\t\t\ttotalFiles += files.length;\n\t\t\t} catch {\n\t\t\t\tdirFiles.push([]);\n\t\t\t}\n\t\t}\n\n\t\tlet loaded = 0;\n\t\tconst sessions: SessionInfo[] = [];\n\t\tconst allFiles = dirFiles.flat();\n\t\tconst results = await buildSessionInfosWithConcurrency(allFiles, () => {\n\t\t\tloaded++;\n\t\t\tonProgress?.(loaded, totalFiles);\n\t\t});\n\n\t\tfor (const info of results) {\n\t\t\tif (info) {\n\t\t\t\tsessions.push(info);\n\t\t\t}\n\t\t}\n\n\t\treturn sessions;\n\t} catch {\n\t\treturn [];\n\t}\n}\n\nasync function buildSessionInfosWithConcurrency(\n\tfiles: string[],\n\tonLoaded: () => void,\n): Promise<(SessionInfo | null)[]> {\n\tconst results: (SessionInfo | null)[] = new Array(files.length).fill(null);\n\tconst inFlight = new Set<Promise<void>>();\n\tlet nextIndex = 0;\n\n\tconst startNext = (): void => {\n\t\tconst index = nextIndex++;\n\t\tconst file = files[index];\n\t\tif (!file) return;\n\n\t\tlet task: Promise<void>;\n\t\ttask = buildSessionInfo(file)\n\t\t\t.then((info) => {\n\t\t\t\tresults[index] = info;\n\t\t\t})\n\t\t\t.catch(() => {\n\t\t\t\tresults[index] = null;\n\t\t\t})\n\t\t\t.finally(() => {\n\t\t\t\tinFlight.delete(task);\n\t\t\t\tonLoaded();\n\t\t\t});\n\t\tinFlight.add(task);\n\t};\n\n\twhile (nextIndex < files.length || inFlight.size > 0) {\n\t\twhile (nextIndex < files.length && inFlight.size < MAX_CONCURRENT_SESSION_INFO_LOADS) {\n\t\t\tstartNext();\n\t\t}\n\t\tif (inFlight.size > 0) {\n\t\t\tawait Promise.race(inFlight);\n\t\t}\n\t}\n\n\treturn results;\n}\n\nexport class JsonlSessionStore extends InMemorySessionStore {\n\tprivate reference: string | undefined;\n\tprivate flushed = false;\n\n\tisPersisted(): boolean {\n\t\treturn true;\n\t}\n\n\tgetSessionReference(): string | undefined {\n\t\treturn this.reference;\n\t}\n\n\tsetSessionReference(reference: string): void {\n\t\tthis.reference = resolve(reference);\n\t\tthis.flushed = false;\n\t}\n\n\texists(path: string): boolean {\n\t\treturn exists(path);\n\t}\n\n\tensureDir(path: string): void {\n\t\tensureDir(path);\n\t}\n\n\tload(filePath: string): FileEntry[] {\n\t\tif (!exists(filePath)) return [];\n\t\tthis.flushed = true;\n\t\treturn load(filePath);\n\t}\n\n\tappendEntry(entry: SessionEntry): void {\n\t\tsuper.appendEntry(entry);\n\t\tthis.persistAppendedEntry(entry);\n\t}\n\n\tprivate persistAppendedEntry(entry: SessionEntry): void {\n\t\tif (!this.reference) return;\n\n\t\tif (!this.hasAssistantMessage()) {\n\t\t\tthis.flushed = false;\n\t\t\treturn;\n\t\t}\n\n\t\tif (!this.flushed) {\n\t\t\tfor (const fileEntry of this.getFileEntries()) {\n\t\t\t\tappend(this.reference, fileEntry);\n\t\t\t}\n\t\t\tthis.flushed = true;\n\t\t} else {\n\t\t\tappend(this.reference, entry);\n\t\t}\n\t}\n\n\tsaveSnapshot(): void {\n\t\tif (!this.reference) return;\n\t\trewrite(this.reference, this.getFileEntries());\n\t\tthis.flushed = true;\n\t}\n\n\tcommitSnapshot(): void {\n\t\tif (!this.hasAssistantMessage()) {\n\t\t\tthis.flushed = false;\n\t\t\treturn;\n\t\t}\n\t\tthis.saveSnapshot();\n\t}\n}\n"]}
@@ -94,6 +94,7 @@ export interface Settings {
94
94
  warnings?: WarningSettings;
95
95
  sessionDir?: string;
96
96
  httpIdleTimeoutMs?: number;
97
+ websocketConnectTimeoutMs?: number;
97
98
  }
98
99
  export type SettingsScope = "global" | "project";
99
100
  export interface SettingsStorage {
@@ -198,6 +199,7 @@ export declare class SettingsManager {
198
199
  };
199
200
  getHttpIdleTimeoutMs(): number;
200
201
  setHttpIdleTimeoutMs(timeoutMs: number): void;
202
+ getWebSocketConnectTimeoutMs(): number | undefined;
201
203
  getProviderRetrySettings(): {
202
204
  timeoutMs?: number;
203
205
  maxRetries?: number;