@caupulican/pi-adaptative 0.78.2 → 0.78.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +30 -0
- package/README.md +14 -12
- package/dist/cli/args.d.ts.map +1 -1
- package/dist/cli/args.js +1 -1
- package/dist/cli/args.js.map +1 -1
- package/dist/core/agent-session.d.ts +1 -0
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +34 -12
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/extensions/types.d.ts +16 -1
- package/dist/core/extensions/types.d.ts.map +1 -1
- package/dist/core/extensions/types.js.map +1 -1
- package/dist/core/model-registry.d.ts.map +1 -1
- package/dist/core/model-registry.js +10 -0
- package/dist/core/model-registry.js.map +1 -1
- package/dist/core/model-resolver.d.ts.map +1 -1
- package/dist/core/model-resolver.js +1 -0
- package/dist/core/model-resolver.js.map +1 -1
- package/dist/core/prompt-templates.d.ts +3 -2
- package/dist/core/prompt-templates.d.ts.map +1 -1
- package/dist/core/prompt-templates.js +8 -3
- package/dist/core/prompt-templates.js.map +1 -1
- package/dist/core/provider-display-names.d.ts.map +1 -1
- package/dist/core/provider-display-names.js +1 -0
- package/dist/core/provider-display-names.js.map +1 -1
- package/dist/core/resource-loader.d.ts +5 -5
- package/dist/core/resource-loader.d.ts.map +1 -1
- package/dist/core/resource-loader.js +1 -9
- package/dist/core/resource-loader.js.map +1 -1
- package/dist/core/session-manager.d.ts.map +1 -1
- package/dist/core/session-manager.js +169 -80
- package/dist/core/session-manager.js.map +1 -1
- package/dist/core/settings-manager.d.ts +23 -0
- package/dist/core/settings-manager.d.ts.map +1 -1
- package/dist/core/settings-manager.js +19 -0
- package/dist/core/settings-manager.js.map +1 -1
- package/dist/core/skills.d.ts.map +1 -1
- package/dist/core/skills.js +3 -7
- package/dist/core/skills.js.map +1 -1
- package/dist/core/slash-commands.d.ts.map +1 -1
- package/dist/core/slash-commands.js +6 -3
- package/dist/core/slash-commands.js.map +1 -1
- package/dist/core/system-prompt.d.ts +3 -3
- package/dist/core/system-prompt.d.ts.map +1 -1
- package/dist/core/system-prompt.js +27 -18
- package/dist/core/system-prompt.js.map +1 -1
- package/dist/core/tools/find.d.ts.map +1 -1
- package/dist/core/tools/find.js +4 -3
- package/dist/core/tools/find.js.map +1 -1
- package/dist/core/tools/grep.d.ts.map +1 -1
- package/dist/core/tools/grep.js +4 -3
- package/dist/core/tools/grep.js.map +1 -1
- package/dist/core/tools/ls.d.ts.map +1 -1
- package/dist/core/tools/ls.js +1 -0
- package/dist/core/tools/ls.js.map +1 -1
- package/dist/core/tools/render-utils.d.ts +1 -1
- package/dist/core/tools/render-utils.d.ts.map +1 -1
- package/dist/core/tools/render-utils.js +29 -4
- package/dist/core/tools/render-utils.js.map +1 -1
- package/dist/modes/interactive/components/footer.d.ts.map +1 -1
- package/dist/modes/interactive/components/footer.js +2 -2
- package/dist/modes/interactive/components/footer.js.map +1 -1
- package/dist/modes/interactive/components/index.d.ts +2 -0
- package/dist/modes/interactive/components/index.d.ts.map +1 -1
- package/dist/modes/interactive/components/index.js +2 -0
- package/dist/modes/interactive/components/index.js.map +1 -1
- package/dist/modes/interactive/components/tool-execution.d.ts +7 -0
- package/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
- package/dist/modes/interactive/components/tool-execution.js +66 -8
- package/dist/modes/interactive/components/tool-execution.js.map +1 -1
- package/dist/modes/interactive/components/tool-group.d.ts +17 -0
- package/dist/modes/interactive/components/tool-group.d.ts.map +1 -0
- package/dist/modes/interactive/components/tool-group.js +63 -0
- package/dist/modes/interactive/components/tool-group.js.map +1 -0
- package/dist/modes/interactive/components/tool-panel-registry.d.ts +23 -0
- package/dist/modes/interactive/components/tool-panel-registry.d.ts.map +1 -0
- package/dist/modes/interactive/components/tool-panel-registry.js +70 -0
- package/dist/modes/interactive/components/tool-panel-registry.js.map +1 -0
- package/dist/modes/interactive/interactive-mode.d.ts +6 -1
- package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode.js +119 -60
- package/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/dist/utils/paths.d.ts.map +1 -1
- package/dist/utils/paths.js +4 -1
- package/dist/utils/paths.js.map +1 -1
- package/docs/extensions.md +6 -3
- package/docs/quickstart.md +3 -3
- package/docs/sdk.md +1 -1
- package/docs/settings.md +50 -0
- package/docs/skills.md +3 -3
- package/docs/usage.md +3 -3
- package/examples/extensions/custom-provider-anthropic/package-lock.json +2 -2
- package/examples/extensions/custom-provider-anthropic/package.json +1 -1
- package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
- package/examples/extensions/sandbox/package-lock.json +2 -2
- package/examples/extensions/sandbox/package.json +1 -1
- package/examples/extensions/with-deps/package-lock.json +2 -2
- package/examples/extensions/with-deps/package.json +1 -1
- package/examples/sdk/07-context-files.ts +3 -14
- package/npm-shrinkwrap.json +388 -2704
- package/package.json +5 -5
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import { uuidv7 } from "@earendil-works/pi-agent-core";
|
|
2
2
|
import { randomUUID } from "crypto";
|
|
3
|
-
import { appendFileSync, closeSync, existsSync, mkdirSync, openSync, readdirSync,
|
|
4
|
-
import { readdir,
|
|
3
|
+
import { appendFileSync, closeSync, createReadStream, existsSync, mkdirSync, openSync, readdirSync, readSync, statSync, writeFileSync, } from "fs";
|
|
4
|
+
import { readdir, stat } from "fs/promises";
|
|
5
5
|
import { join, resolve } from "path";
|
|
6
|
+
import { createInterface } from "readline";
|
|
7
|
+
import { StringDecoder } from "string_decoder";
|
|
6
8
|
import { getAgentDir as getDefaultAgentDir, getSessionsDir } from "../config.js";
|
|
7
9
|
import { normalizePath, resolvePath } from "../utils/paths.js";
|
|
8
10
|
import { createBranchSummaryMessage, createCompactionSummaryMessage, createCustomMessage, } from "./messages.js";
|
|
@@ -215,12 +217,24 @@ export function buildSessionContext(entries, leafId, byId) {
|
|
|
215
217
|
* Compute the default session directory for a cwd.
|
|
216
218
|
* Encodes cwd into a safe directory name under ~/.pi/agent/sessions/.
|
|
217
219
|
*/
|
|
218
|
-
function
|
|
220
|
+
function getEncodedSessionDirName(cwd) {
|
|
221
|
+
return `--${encodeURIComponent(resolvePath(cwd))}--`;
|
|
222
|
+
}
|
|
223
|
+
function getLegacySessionDirPath(cwd, agentDir = getDefaultAgentDir()) {
|
|
219
224
|
const resolvedCwd = resolvePath(cwd);
|
|
220
225
|
const resolvedAgentDir = resolvePath(agentDir);
|
|
221
226
|
const safePath = `--${resolvedCwd.replace(/^[/\\]/, "").replace(/[/\\:]/g, "-")}--`;
|
|
222
227
|
return join(resolvedAgentDir, "sessions", safePath);
|
|
223
228
|
}
|
|
229
|
+
function getDefaultSessionDirPath(cwd, agentDir = getDefaultAgentDir()) {
|
|
230
|
+
const resolvedAgentDir = resolvePath(agentDir);
|
|
231
|
+
return join(resolvedAgentDir, "sessions", getEncodedSessionDirName(cwd));
|
|
232
|
+
}
|
|
233
|
+
function getDefaultSessionDirCandidates(cwd, agentDir = getDefaultAgentDir()) {
|
|
234
|
+
const current = getDefaultSessionDirPath(cwd, agentDir);
|
|
235
|
+
const legacy = getLegacySessionDirPath(cwd, agentDir);
|
|
236
|
+
return current === legacy ? [current] : [current, legacy];
|
|
237
|
+
}
|
|
224
238
|
export function getDefaultSessionDir(cwd, agentDir = getDefaultAgentDir()) {
|
|
225
239
|
const sessionDir = getDefaultSessionDirPath(cwd, agentDir);
|
|
226
240
|
if (!existsSync(sessionDir)) {
|
|
@@ -228,24 +242,52 @@ export function getDefaultSessionDir(cwd, agentDir = getDefaultAgentDir()) {
|
|
|
228
242
|
}
|
|
229
243
|
return sessionDir;
|
|
230
244
|
}
|
|
245
|
+
const SESSION_READ_BUFFER_SIZE = 1024 * 1024;
|
|
246
|
+
function parseSessionEntryLine(line) {
|
|
247
|
+
if (!line.trim())
|
|
248
|
+
return null;
|
|
249
|
+
try {
|
|
250
|
+
return JSON.parse(line);
|
|
251
|
+
}
|
|
252
|
+
catch {
|
|
253
|
+
// Skip malformed lines
|
|
254
|
+
return null;
|
|
255
|
+
}
|
|
256
|
+
}
|
|
231
257
|
/** Exported for testing */
|
|
232
258
|
export function loadEntriesFromFile(filePath) {
|
|
233
259
|
const resolvedFilePath = normalizePath(filePath);
|
|
234
260
|
if (!existsSync(resolvedFilePath))
|
|
235
261
|
return [];
|
|
236
|
-
const content = readFileSync(resolvedFilePath, "utf8");
|
|
237
262
|
const entries = [];
|
|
238
|
-
const
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
263
|
+
const fd = openSync(resolvedFilePath, "r");
|
|
264
|
+
try {
|
|
265
|
+
const decoder = new StringDecoder("utf8");
|
|
266
|
+
const buffer = Buffer.allocUnsafe(SESSION_READ_BUFFER_SIZE);
|
|
267
|
+
let pending = "";
|
|
268
|
+
while (true) {
|
|
269
|
+
const bytesRead = readSync(fd, buffer, 0, buffer.length, null);
|
|
270
|
+
if (bytesRead === 0)
|
|
271
|
+
break;
|
|
272
|
+
pending += decoder.write(buffer.subarray(0, bytesRead));
|
|
273
|
+
let lineStart = 0;
|
|
274
|
+
let newlineIndex = pending.indexOf("\n", lineStart);
|
|
275
|
+
while (newlineIndex !== -1) {
|
|
276
|
+
const entry = parseSessionEntryLine(pending.slice(lineStart, newlineIndex));
|
|
277
|
+
if (entry)
|
|
278
|
+
entries.push(entry);
|
|
279
|
+
lineStart = newlineIndex + 1;
|
|
280
|
+
newlineIndex = pending.indexOf("\n", lineStart);
|
|
281
|
+
}
|
|
282
|
+
pending = pending.slice(lineStart);
|
|
248
283
|
}
|
|
284
|
+
pending += decoder.end();
|
|
285
|
+
const finalEntry = parseSessionEntryLine(pending);
|
|
286
|
+
if (finalEntry)
|
|
287
|
+
entries.push(finalEntry);
|
|
288
|
+
}
|
|
289
|
+
finally {
|
|
290
|
+
closeSync(fd);
|
|
249
291
|
}
|
|
250
292
|
// Validate session header
|
|
251
293
|
if (entries.length === 0)
|
|
@@ -301,6 +343,24 @@ export function findMostRecentSession(sessionDir, cwd) {
|
|
|
301
343
|
return null;
|
|
302
344
|
}
|
|
303
345
|
}
|
|
346
|
+
function findMostRecentSessionInDirs(sessionDirs, cwd) {
|
|
347
|
+
let mostRecent = null;
|
|
348
|
+
for (const dir of sessionDirs) {
|
|
349
|
+
const sessionPath = findMostRecentSession(dir, cwd);
|
|
350
|
+
if (!sessionPath)
|
|
351
|
+
continue;
|
|
352
|
+
try {
|
|
353
|
+
const mtime = statSync(sessionPath).mtime.getTime();
|
|
354
|
+
if (!mostRecent || mtime > mostRecent.mtime) {
|
|
355
|
+
mostRecent = { path: sessionPath, mtime };
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
catch {
|
|
359
|
+
// Ignore races/deleted files
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
return mostRecent?.path ?? null;
|
|
363
|
+
}
|
|
304
364
|
function isMessageWithContent(message) {
|
|
305
365
|
return typeof message.role === "string" && "content" in message;
|
|
306
366
|
}
|
|
@@ -314,73 +374,64 @@ function extractTextContent(message) {
|
|
|
314
374
|
.map((block) => block.text)
|
|
315
375
|
.join(" ");
|
|
316
376
|
}
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
const msgTimestamp = message.timestamp;
|
|
328
|
-
if (typeof msgTimestamp === "number") {
|
|
329
|
-
lastActivityTime = Math.max(lastActivityTime ?? 0, msgTimestamp);
|
|
330
|
-
continue;
|
|
331
|
-
}
|
|
332
|
-
const entryTimestamp = entry.timestamp;
|
|
333
|
-
if (typeof entryTimestamp === "string") {
|
|
334
|
-
const t = new Date(entryTimestamp).getTime();
|
|
335
|
-
if (!Number.isNaN(t)) {
|
|
336
|
-
lastActivityTime = Math.max(lastActivityTime ?? 0, t);
|
|
337
|
-
}
|
|
338
|
-
}
|
|
339
|
-
}
|
|
340
|
-
return lastActivityTime;
|
|
341
|
-
}
|
|
342
|
-
function getSessionModifiedDate(entries, header, statsMtime) {
|
|
343
|
-
const lastActivityTime = getLastActivityTime(entries);
|
|
344
|
-
if (typeof lastActivityTime === "number" && lastActivityTime > 0) {
|
|
345
|
-
return new Date(lastActivityTime);
|
|
377
|
+
const MAX_SESSION_SEARCH_TEXT_CHARS = 20_000;
|
|
378
|
+
function getMessageActivityTime(entry) {
|
|
379
|
+
const message = entry.message;
|
|
380
|
+
if (!isMessageWithContent(message))
|
|
381
|
+
return undefined;
|
|
382
|
+
if (message.role !== "user" && message.role !== "assistant")
|
|
383
|
+
return undefined;
|
|
384
|
+
const msgTimestamp = message.timestamp;
|
|
385
|
+
if (typeof msgTimestamp === "number") {
|
|
386
|
+
return msgTimestamp;
|
|
346
387
|
}
|
|
347
|
-
const
|
|
348
|
-
return
|
|
388
|
+
const t = new Date(entry.timestamp).getTime();
|
|
389
|
+
return Number.isNaN(t) ? undefined : t;
|
|
349
390
|
}
|
|
350
391
|
async function buildSessionInfo(filePath) {
|
|
351
392
|
try {
|
|
352
|
-
const content = await readFile(filePath, "utf8");
|
|
353
|
-
const entries = [];
|
|
354
|
-
const lines = content.trim().split("\n");
|
|
355
|
-
for (const line of lines) {
|
|
356
|
-
if (!line.trim())
|
|
357
|
-
continue;
|
|
358
|
-
try {
|
|
359
|
-
entries.push(JSON.parse(line));
|
|
360
|
-
}
|
|
361
|
-
catch {
|
|
362
|
-
// Skip malformed lines
|
|
363
|
-
}
|
|
364
|
-
}
|
|
365
|
-
if (entries.length === 0)
|
|
366
|
-
return null;
|
|
367
|
-
const header = entries[0];
|
|
368
|
-
if (header.type !== "session")
|
|
369
|
-
return null;
|
|
370
393
|
const stats = await stat(filePath);
|
|
394
|
+
let header = null;
|
|
371
395
|
let messageCount = 0;
|
|
372
396
|
let firstMessage = "";
|
|
373
|
-
|
|
397
|
+
let allMessagesText = "";
|
|
374
398
|
let name;
|
|
375
|
-
|
|
399
|
+
let lastActivityTime;
|
|
400
|
+
const appendSearchText = (text) => {
|
|
401
|
+
if (!text || allMessagesText.length >= MAX_SESSION_SEARCH_TEXT_CHARS)
|
|
402
|
+
return;
|
|
403
|
+
const prefix = allMessagesText.length === 0 ? "" : " ";
|
|
404
|
+
const remaining = MAX_SESSION_SEARCH_TEXT_CHARS - allMessagesText.length - prefix.length;
|
|
405
|
+
if (remaining <= 0)
|
|
406
|
+
return;
|
|
407
|
+
allMessagesText += `${prefix}${text.slice(0, remaining)}`;
|
|
408
|
+
};
|
|
409
|
+
const rl = createInterface({
|
|
410
|
+
input: createReadStream(filePath, { encoding: "utf8" }),
|
|
411
|
+
crlfDelay: Infinity,
|
|
412
|
+
});
|
|
413
|
+
for await (const line of rl) {
|
|
414
|
+
const entry = parseSessionEntryLine(line);
|
|
415
|
+
if (!entry)
|
|
416
|
+
continue;
|
|
417
|
+
if (!header) {
|
|
418
|
+
if (entry.type !== "session")
|
|
419
|
+
return null;
|
|
420
|
+
header = entry;
|
|
421
|
+
continue;
|
|
422
|
+
}
|
|
376
423
|
// Extract session name (use latest, including explicit clears)
|
|
377
424
|
if (entry.type === "session_info") {
|
|
378
|
-
|
|
379
|
-
|
|
425
|
+
name = entry.name?.trim() || undefined;
|
|
426
|
+
continue;
|
|
380
427
|
}
|
|
381
428
|
if (entry.type !== "message")
|
|
382
429
|
continue;
|
|
383
430
|
messageCount++;
|
|
431
|
+
const activityTime = getMessageActivityTime(entry);
|
|
432
|
+
if (typeof activityTime === "number") {
|
|
433
|
+
lastActivityTime = Math.max(lastActivityTime ?? 0, activityTime);
|
|
434
|
+
}
|
|
384
435
|
const message = entry.message;
|
|
385
436
|
if (!isMessageWithContent(message))
|
|
386
437
|
continue;
|
|
@@ -389,14 +440,21 @@ async function buildSessionInfo(filePath) {
|
|
|
389
440
|
const textContent = extractTextContent(message);
|
|
390
441
|
if (!textContent)
|
|
391
442
|
continue;
|
|
392
|
-
|
|
443
|
+
appendSearchText(textContent);
|
|
393
444
|
if (!firstMessage && message.role === "user") {
|
|
394
445
|
firstMessage = textContent;
|
|
395
446
|
}
|
|
396
447
|
}
|
|
448
|
+
if (!header)
|
|
449
|
+
return null;
|
|
397
450
|
const cwd = typeof header.cwd === "string" ? header.cwd : "";
|
|
398
451
|
const parentSessionPath = header.parentSession;
|
|
399
|
-
const
|
|
452
|
+
const headerTime = typeof header.timestamp === "string" ? new Date(header.timestamp).getTime() : NaN;
|
|
453
|
+
const modified = typeof lastActivityTime === "number" && lastActivityTime > 0
|
|
454
|
+
? new Date(lastActivityTime)
|
|
455
|
+
: !Number.isNaN(headerTime)
|
|
456
|
+
? new Date(headerTime)
|
|
457
|
+
: stats.mtime;
|
|
400
458
|
return {
|
|
401
459
|
path: filePath,
|
|
402
460
|
id: header.id,
|
|
@@ -407,7 +465,7 @@ async function buildSessionInfo(filePath) {
|
|
|
407
465
|
modified,
|
|
408
466
|
messageCount,
|
|
409
467
|
firstMessage: firstMessage || "(no messages)",
|
|
410
|
-
allMessagesText
|
|
468
|
+
allMessagesText,
|
|
411
469
|
};
|
|
412
470
|
}
|
|
413
471
|
catch {
|
|
@@ -448,6 +506,17 @@ async function buildSessionInfosWithConcurrency(files, onLoaded) {
|
|
|
448
506
|
}
|
|
449
507
|
return results;
|
|
450
508
|
}
|
|
509
|
+
async function countSessionFiles(dir) {
|
|
510
|
+
if (!existsSync(dir))
|
|
511
|
+
return 0;
|
|
512
|
+
try {
|
|
513
|
+
const dirEntries = await readdir(dir);
|
|
514
|
+
return dirEntries.filter((f) => f.endsWith(".jsonl")).length;
|
|
515
|
+
}
|
|
516
|
+
catch {
|
|
517
|
+
return 0;
|
|
518
|
+
}
|
|
519
|
+
}
|
|
451
520
|
async function listSessionsFromDir(dir, onProgress, progressOffset = 0, progressTotal) {
|
|
452
521
|
const sessions = [];
|
|
453
522
|
if (!existsSync(dir)) {
|
|
@@ -589,8 +658,15 @@ export class SessionManager {
|
|
|
589
658
|
_rewriteFile() {
|
|
590
659
|
if (!this.persist || !this.sessionFile)
|
|
591
660
|
return;
|
|
592
|
-
const
|
|
593
|
-
|
|
661
|
+
const fd = openSync(this.sessionFile, "w");
|
|
662
|
+
try {
|
|
663
|
+
for (const entry of this.fileEntries) {
|
|
664
|
+
writeFileSync(fd, `${JSON.stringify(entry)}\n`);
|
|
665
|
+
}
|
|
666
|
+
}
|
|
667
|
+
finally {
|
|
668
|
+
closeSync(fd);
|
|
669
|
+
}
|
|
594
670
|
}
|
|
595
671
|
isPersisted() {
|
|
596
672
|
return this.persist;
|
|
@@ -602,7 +678,7 @@ export class SessionManager {
|
|
|
602
678
|
return this.sessionDir;
|
|
603
679
|
}
|
|
604
680
|
usesDefaultSessionDir() {
|
|
605
|
-
return this.
|
|
681
|
+
return getDefaultSessionDirCandidates(this.cwd).includes(this.sessionDir);
|
|
606
682
|
}
|
|
607
683
|
getSessionId() {
|
|
608
684
|
return this.sessionId;
|
|
@@ -1069,10 +1145,12 @@ export class SessionManager {
|
|
|
1069
1145
|
*/
|
|
1070
1146
|
static continueRecent(cwd, sessionDir) {
|
|
1071
1147
|
const dir = sessionDir ? normalizePath(sessionDir) : getDefaultSessionDir(cwd);
|
|
1072
|
-
const
|
|
1073
|
-
const
|
|
1148
|
+
const defaultDirs = getDefaultSessionDirCandidates(cwd);
|
|
1149
|
+
const filterCwd = sessionDir !== undefined && !defaultDirs.includes(dir);
|
|
1150
|
+
const searchDirs = sessionDir ? [dir] : defaultDirs;
|
|
1151
|
+
const mostRecent = findMostRecentSessionInDirs(searchDirs, filterCwd ? cwd : undefined);
|
|
1074
1152
|
if (mostRecent) {
|
|
1075
|
-
return new SessionManager(cwd,
|
|
1153
|
+
return new SessionManager(cwd, resolve(mostRecent, ".."), mostRecent, true);
|
|
1076
1154
|
}
|
|
1077
1155
|
return new SessionManager(cwd, dir, undefined, true);
|
|
1078
1156
|
}
|
|
@@ -1136,11 +1214,22 @@ export class SessionManager {
|
|
|
1136
1214
|
*/
|
|
1137
1215
|
static async list(cwd, sessionDir, onProgress) {
|
|
1138
1216
|
const dir = sessionDir ? normalizePath(sessionDir) : getDefaultSessionDir(cwd);
|
|
1139
|
-
const
|
|
1217
|
+
const defaultDirs = getDefaultSessionDirCandidates(cwd);
|
|
1218
|
+
const filterCwd = sessionDir !== undefined && !defaultDirs.includes(dir);
|
|
1140
1219
|
const resolvedCwd = resolvePath(cwd);
|
|
1141
|
-
const
|
|
1142
|
-
|
|
1143
|
-
|
|
1220
|
+
const dirs = sessionDir ? [dir] : defaultDirs;
|
|
1221
|
+
const progressCounts = await Promise.all(dirs.map((candidateDir) => countSessionFiles(candidateDir)));
|
|
1222
|
+
const progressTotal = progressCounts.reduce((sum, count) => sum + count, 0);
|
|
1223
|
+
const allSessions = [];
|
|
1224
|
+
let progressOffset = 0;
|
|
1225
|
+
for (let i = 0; i < dirs.length; i++) {
|
|
1226
|
+
const candidateDir = dirs[i];
|
|
1227
|
+
const sessions = (await listSessionsFromDir(candidateDir, onProgress, progressOffset, progressTotal)).filter((session) => !filterCwd || sessionCwdMatches(session.cwd, resolvedCwd));
|
|
1228
|
+
progressOffset += progressCounts[i];
|
|
1229
|
+
allSessions.push(...sessions);
|
|
1230
|
+
}
|
|
1231
|
+
allSessions.sort((a, b) => b.modified.getTime() - a.modified.getTime());
|
|
1232
|
+
return allSessions;
|
|
1144
1233
|
}
|
|
1145
1234
|
static async listAll(sessionDirOrOnProgress, onProgress) {
|
|
1146
1235
|
const customSessionDir = typeof sessionDirOrOnProgress === "string" ? normalizePath(sessionDirOrOnProgress) : undefined;
|