@ai-devkit/agent-manager 0.9.0 → 0.11.0

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 (63) hide show
  1. package/dist/AgentManager.d.ts +21 -1
  2. package/dist/AgentManager.d.ts.map +1 -1
  3. package/dist/AgentManager.js +47 -0
  4. package/dist/AgentManager.js.map +1 -1
  5. package/dist/adapters/AgentAdapter.d.ts +66 -0
  6. package/dist/adapters/AgentAdapter.d.ts.map +1 -1
  7. package/dist/adapters/ClaudeCodeAdapter.d.ts +14 -43
  8. package/dist/adapters/ClaudeCodeAdapter.d.ts.map +1 -1
  9. package/dist/adapters/ClaudeCodeAdapter.js +60 -275
  10. package/dist/adapters/ClaudeCodeAdapter.js.map +1 -1
  11. package/dist/adapters/CodexAdapter.d.ts +14 -1
  12. package/dist/adapters/CodexAdapter.d.ts.map +1 -1
  13. package/dist/adapters/CodexAdapter.js +105 -6
  14. package/dist/adapters/CodexAdapter.js.map +1 -1
  15. package/dist/adapters/GeminiCliAdapter.d.ts +9 -1
  16. package/dist/adapters/GeminiCliAdapter.d.ts.map +1 -1
  17. package/dist/adapters/GeminiCliAdapter.js +77 -6
  18. package/dist/adapters/GeminiCliAdapter.js.map +1 -1
  19. package/dist/index.d.ts +1 -1
  20. package/dist/index.d.ts.map +1 -1
  21. package/dist/index.js.map +1 -1
  22. package/dist/terminal/TerminalFocusManager.d.ts.map +1 -1
  23. package/dist/terminal/TerminalFocusManager.js +36 -27
  24. package/dist/terminal/TerminalFocusManager.js.map +1 -1
  25. package/dist/terminal/TtyWriter.d.ts.map +1 -1
  26. package/dist/terminal/TtyWriter.js +3 -12
  27. package/dist/terminal/TtyWriter.js.map +1 -1
  28. package/dist/utils/ClaudeSessionParser.d.ts +114 -0
  29. package/dist/utils/ClaudeSessionParser.d.ts.map +1 -0
  30. package/dist/utils/ClaudeSessionParser.js +377 -0
  31. package/dist/utils/ClaudeSessionParser.js.map +1 -0
  32. package/dist/utils/applescript.d.ts +6 -0
  33. package/dist/utils/applescript.d.ts.map +1 -0
  34. package/dist/utils/applescript.js +14 -0
  35. package/dist/utils/applescript.js.map +1 -0
  36. package/dist/utils/process.d.ts +3 -4
  37. package/dist/utils/process.d.ts.map +1 -1
  38. package/dist/utils/process.js +11 -15
  39. package/dist/utils/process.js.map +1 -1
  40. package/dist/utils/session.d.ts +34 -5
  41. package/dist/utils/session.d.ts.map +1 -1
  42. package/dist/utils/session.js +90 -44
  43. package/dist/utils/session.js.map +1 -1
  44. package/package.json +1 -1
  45. package/src/AgentManager.ts +66 -4
  46. package/src/__tests__/AgentManager.test.ts +134 -2
  47. package/src/__tests__/adapters/ClaudeCodeAdapter.test.ts +188 -32
  48. package/src/__tests__/adapters/CodexAdapter.test.ts +123 -3
  49. package/src/__tests__/adapters/GeminiCliAdapter.test.ts +133 -0
  50. package/src/__tests__/utils/ClaudeSessionParser.test.ts +195 -0
  51. package/src/__tests__/utils/process.test.ts +27 -27
  52. package/src/__tests__/utils/session.test.ts +79 -43
  53. package/src/adapters/AgentAdapter.ts +76 -0
  54. package/src/adapters/ClaudeCodeAdapter.ts +82 -356
  55. package/src/adapters/CodexAdapter.ts +126 -8
  56. package/src/adapters/GeminiCliAdapter.ts +102 -7
  57. package/src/index.ts +9 -1
  58. package/src/terminal/TerminalFocusManager.ts +35 -26
  59. package/src/terminal/TtyWriter.ts +1 -11
  60. package/src/utils/ClaudeSessionParser.ts +437 -0
  61. package/src/utils/applescript.ts +10 -0
  62. package/src/utils/process.ts +21 -24
  63. package/src/utils/session.ts +86 -45
@@ -1 +1 @@
1
- {"version":3,"file":"process.js","sourceRoot":"","sources":["../../src/utils/process.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"process.js","sourceRoot":"","sources":["../../src/utils/process.ts"],"names":[],"mappings":";AAAA;;;;;GAKG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAeH,gDA6CC;AAQD,kDAuCC;AASD,8DAkCC;AASD,0CAaC;AAKD,sCAYC;AA3LD,2CAA6B;AAC7B,iDAA6C;AAG7C;;;;;;;;GAQG;AACH,SAAgB,kBAAkB,CAAC,WAAmB;IAClD,kFAAkF;IAClF,IAAI,CAAC,WAAW,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,WAAW,CAAC,EAAE,CAAC;QACxD,OAAO,EAAE,CAAC;IACd,CAAC;IAED,IAAI,CAAC;QACD,MAAM,MAAM,GAAG,IAAA,4BAAY,EAAC,IAAI,EAAE,CAAC,KAAK,CAAC,EAAE,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC,CAAC;QAElE,MAAM,YAAY,GAAG,WAAW,CAAC,WAAW,EAAE,CAAC;QAC/C,MAAM,SAAS,GAAkB,EAAE,CAAC;QAEpC,KAAK,MAAM,IAAI,IAAI,MAAM,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;YAC3C,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE;gBAAE,SAAS;YAE3B,MAAM,KAAK,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;YACvC,IAAI,KAAK,CAAC,MAAM,GAAG,EAAE;gBAAE,SAAS;YAEhC,MAAM,GAAG,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;YACnC,IAAI,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC;gBAAE,SAAS;YAEhC,MAAM,GAAG,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;YACrB,MAAM,OAAO,GAAG,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YAE1C,qDAAqD;YACrD,MAAM,UAAU,GAAG,OAAO,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;YACxD,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC,WAAW,EAAE,CAAC;YACrD,IAAI,IAAI,KAAK,YAAY,IAAI,IAAI,KAAK,GAAG,YAAY,MAAM,EAAE,CAAC;gBAC1D,SAAS;YACb,CAAC;YAED,MAAM,QAAQ,GAAG,GAAG,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC;YAE9D,SAAS,CAAC,IAAI,CAAC;gBACX,GAAG;gBACH,OAAO;gBACP,GAAG,EAAE,EAAE;gBACP,GAAG,EAAE,QAAQ;aAChB,CAAC,CAAC;QACP,CAAC;QAED,OAAO,SAAS,CAAC;IACrB,CAAC;IAAC,MAAM,CAAC;QACL,OAAO,EAAE,CAAC;IACd,CAAC;AACL,CAAC;AAED;;;;;GAKG;AACH,SAAgB,mBAAmB,CAAC,IAAc;IAC9C,MAAM,MAAM,GAAG,IAAI,GAAG,EAAkB,CAAC;IACzC,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,MAAM,CAAC;IAErC,IAAI,CAAC;QACD,MAAM,MAAM,GAAG,IAAA,4BAAY,EACvB,MAAM,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EACxD,EAAE,QAAQ,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,CAC3D,CAAC;QAEF,0DAA0D;QAC1D,IAAI,UAAU,GAAkB,IAAI,CAAC;QACrC,KAAK,MAAM,IAAI,IAAI,MAAM,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;YAC3C,IAAI,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;gBACvB,UAAU,GAAG,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;YAC7C,CAAC;iBAAM,IAAI,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,UAAU,KAAK,IAAI,EAAE,CAAC;gBACrD,MAAM,CAAC,GAAG,CAAC,UAAU,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;gBACtC,UAAU,GAAG,IAAI,CAAC;YACtB,CAAC;QACL,CAAC;IACL,CAAC;IAAC,MAAM,CAAC;QACL,yCAAyC;QACzC,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;YACrB,IAAI,CAAC;gBACD,MAAM,MAAM,GAAG,IAAA,4BAAY,EACvB,MAAM,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,EACrB,EAAE,QAAQ,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,CAC3D,CAAC;gBACF,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,eAAe,CAAC,CAAC;gBAC5C,IAAI,KAAK,EAAE,CAAC;oBACR,MAAM,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;gBACrC,CAAC;YACL,CAAC;YAAC,MAAM,CAAC;gBACL,gBAAgB;YACpB,CAAC;QACL,CAAC;IACL,CAAC;IAED,OAAO,MAAM,CAAC;AAClB,CAAC;AAED;;;;;;GAMG;AACH,SAAgB,yBAAyB,CAAC,IAAc;IACpD,MAAM,MAAM,GAAG,IAAI,GAAG,EAAgB,CAAC;IACvC,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,MAAM,CAAC;IAErC,IAAI,CAAC;QACD,MAAM,MAAM,GAAG,IAAA,4BAAY,EACvB,IAAI,EAAE,CAAC,IAAI,EAAE,cAAc,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAClD,EAAE,QAAQ,EAAE,OAAO,EAAE,CACxB,CAAC;QAEF,KAAK,MAAM,OAAO,IAAI,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;YACvC,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,EAAE,CAAC;YAC5B,IAAI,CAAC,IAAI;gBAAE,SAAS;YAEpB,4CAA4C;YAC5C,0CAA0C;YAC1C,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,mBAAmB,CAAC,CAAC;YAC9C,IAAI,CAAC,KAAK;gBAAE,SAAS;YAErB,MAAM,GAAG,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;YACnC,MAAM,OAAO,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;YAEhC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC;gBAAE,SAAS;YAEpC,MAAM,IAAI,GAAG,IAAI,IAAI,CAAC,OAAO,CAAC,CAAC;YAC/B,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,EAAE,CAAC;gBAChC,MAAM,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;YAC1B,CAAC;QACL,CAAC;IACL,CAAC;IAAC,MAAM,CAAC;QACL,0BAA0B;IAC9B,CAAC;IAED,OAAO,MAAM,CAAC;AAClB,CAAC;AAED;;;;;;GAMG;AACH,SAAgB,eAAe,CAAC,SAAwB;IACpD,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,SAAS,CAAC;IAE7C,MAAM,IAAI,GAAG,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;IACvC,MAAM,MAAM,GAAG,mBAAmB,CAAC,IAAI,CAAC,CAAC;IACzC,MAAM,YAAY,GAAG,yBAAyB,CAAC,IAAI,CAAC,CAAC;IAErD,KAAK,MAAM,IAAI,IAAI,SAAS,EAAE,CAAC;QAC3B,IAAI,CAAC,GAAG,GAAG,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC;QACtC,IAAI,CAAC,SAAS,GAAG,YAAY,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAChD,CAAC;IAED,OAAO,SAAS,CAAC;AACrB,CAAC;AAED;;GAEG;AACH,SAAgB,aAAa,CAAC,GAAW;IACrC,IAAI,CAAC;QACD,MAAM,MAAM,GAAG,IAAA,4BAAY,EACvB,IAAI,EAAE,CAAC,IAAI,EAAE,MAAM,CAAC,GAAG,CAAC,EAAE,IAAI,EAAE,MAAM,CAAC,EACvC,EAAE,QAAQ,EAAE,OAAO,EAAE,CACxB,CAAC;QAEF,MAAM,GAAG,GAAG,MAAM,CAAC,IAAI,EAAE,CAAC;QAC1B,OAAO,GAAG,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC;IACxD,CAAC;IAAC,MAAM,CAAC;QACL,OAAO,GAAG,CAAC;IACf,CAAC;AACL,CAAC"}
@@ -1,9 +1,10 @@
1
1
  /**
2
2
  * Session File Utilities
3
3
  *
4
- * Shell command wrappers for discovering session files and their birth times.
5
- * Uses `stat` to get exact epoch-second birth timestamps without reading file contents.
4
+ * Utilities for discovering session files and their birth times.
5
+ * Uses Node.js fs APIs to get birth timestamps without reading file contents.
6
6
  */
7
+ import * as fs from 'fs';
7
8
  /**
8
9
  * Represents a session file with its birth time metadata.
9
10
  */
@@ -20,10 +21,38 @@ export interface SessionFile {
20
21
  resolvedCwd: string;
21
22
  }
22
23
  /**
23
- * Get birth times for .jsonl session files across multiple directories in a single shell call.
24
+ * Check whether a path exists and is a directory.
25
+ * Returns false on any error (missing path, permission denied, broken symlink, etc.).
26
+ */
27
+ export declare function isDirectory(p: string): boolean;
28
+ /**
29
+ * `fs.statSync` that swallows errors and returns `undefined` on failure.
30
+ * Callers can pull whichever fields they need (mtime, birthtime, ...).
31
+ */
32
+ export declare function safeStat(filePath: string): fs.Stats | undefined;
33
+ /**
34
+ * `fs.readFileSync` (utf-8) that swallows errors and returns `undefined`
35
+ * on failure. Use when an unreadable file should be skipped rather than
36
+ * raised.
37
+ */
38
+ export declare function safeReadFile(filePath: string): string | undefined;
39
+ /**
40
+ * `fs.readdirSync` that swallows errors and returns `[]` on failure.
41
+ * Useful when walking optional/transient directories where missing or
42
+ * unreadable entries should be skipped silently.
43
+ */
44
+ export declare function safeReaddir(dir: string): string[];
45
+ /**
46
+ * List entries in a directory that end with `.jsonl`. Returns `[]` on
47
+ * read errors. The result preserves directory order (no sorting).
48
+ */
49
+ export declare function listJsonl(dir: string): string[];
50
+ /**
51
+ * Get birth times for .jsonl session files across multiple directories.
24
52
  *
25
- * Combines all directory globs into one `stat` command to avoid per-directory exec overhead.
26
- * Returns empty array if no directories have .jsonl files or command fails.
53
+ * Enumerates each directory with readdirSync and stats each .jsonl file
54
+ * to get its birth time. No shell commands are used.
55
+ * Returns empty array if no directories have .jsonl files or reads fail.
27
56
  * resolvedCwd is left empty — the adapter must set it.
28
57
  */
29
58
  export declare function batchGetSessionFileBirthtimes(dirs: string[]): SessionFile[];
@@ -1 +1 @@
1
- {"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../../src/utils/session.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAKH;;GAEG;AACH,MAAM,WAAW,WAAW;IACxB,6DAA6D;IAC7D,SAAS,EAAE,MAAM,CAAC;IAElB,oCAAoC;IACpC,QAAQ,EAAE,MAAM,CAAC;IAEjB,2CAA2C;IAC3C,UAAU,EAAE,MAAM,CAAC;IAEnB,qDAAqD;IACrD,WAAW,EAAE,MAAM,CAAC;IAEpB,kGAAkG;IAClG,WAAW,EAAE,MAAM,CAAC;CACvB;AAED;;;;;;GAMG;AACH,wBAAgB,6BAA6B,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,WAAW,EAAE,CAiB3E"}
1
+ {"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../../src/utils/session.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,MAAM,IAAI,CAAC;AAGzB;;GAEG;AACH,MAAM,WAAW,WAAW;IACxB,6DAA6D;IAC7D,SAAS,EAAE,MAAM,CAAC;IAElB,oCAAoC;IACpC,QAAQ,EAAE,MAAM,CAAC;IAEjB,2CAA2C;IAC3C,UAAU,EAAE,MAAM,CAAC;IAEnB,qDAAqD;IACrD,WAAW,EAAE,MAAM,CAAC;IAEpB,kGAAkG;IAClG,WAAW,EAAE,MAAM,CAAC;CACvB;AAED;;;GAGG;AACH,wBAAgB,WAAW,CAAC,CAAC,EAAE,MAAM,GAAG,OAAO,CAE9C;AAED;;;GAGG;AACH,wBAAgB,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,EAAE,CAAC,KAAK,GAAG,SAAS,CAM/D;AAED;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAMjE;AAED;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,EAAE,CAMjD;AAED;;;GAGG;AACH,wBAAgB,SAAS,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,EAAE,CAE/C;AAED;;;;;;;GAOG;AACH,wBAAgB,6BAA6B,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,WAAW,EAAE,CAwC3E"}
@@ -2,8 +2,8 @@
2
2
  /**
3
3
  * Session File Utilities
4
4
  *
5
- * Shell command wrappers for discovering session files and their birth times.
6
- * Uses `stat` to get exact epoch-second birth timestamps without reading file contents.
5
+ * Utilities for discovering session files and their birth times.
6
+ * Uses Node.js fs APIs to get birth timestamps without reading file contents.
7
7
  */
8
8
  var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
9
9
  if (k2 === undefined) k2 = k;
@@ -39,62 +39,108 @@ var __importStar = (this && this.__importStar) || (function () {
39
39
  };
40
40
  })();
41
41
  Object.defineProperty(exports, "__esModule", { value: true });
42
+ exports.isDirectory = isDirectory;
43
+ exports.safeStat = safeStat;
44
+ exports.safeReadFile = safeReadFile;
45
+ exports.safeReaddir = safeReaddir;
46
+ exports.listJsonl = listJsonl;
42
47
  exports.batchGetSessionFileBirthtimes = batchGetSessionFileBirthtimes;
48
+ const fs = __importStar(require("fs"));
43
49
  const path = __importStar(require("path"));
44
- const child_process_1 = require("child_process");
45
50
  /**
46
- * Get birth times for .jsonl session files across multiple directories in a single shell call.
47
- *
48
- * Combines all directory globs into one `stat` command to avoid per-directory exec overhead.
49
- * Returns empty array if no directories have .jsonl files or command fails.
50
- * resolvedCwd is left empty — the adapter must set it.
51
+ * Check whether a path exists and is a directory.
52
+ * Returns false on any error (missing path, permission denied, broken symlink, etc.).
51
53
  */
52
- function batchGetSessionFileBirthtimes(dirs) {
53
- if (dirs.length === 0)
54
- return [];
54
+ function isDirectory(p) {
55
+ return safeStat(p)?.isDirectory() ?? false;
56
+ }
57
+ /**
58
+ * `fs.statSync` that swallows errors and returns `undefined` on failure.
59
+ * Callers can pull whichever fields they need (mtime, birthtime, ...).
60
+ */
61
+ function safeStat(filePath) {
55
62
  try {
56
- const isMacOS = process.platform === 'darwin';
57
- const globs = dirs.map((d) => `"${d}"/*.jsonl`).join(' ');
58
- // || true prevents non-zero exit when some globs have no .jsonl matches
59
- const command = isMacOS
60
- ? `stat -f '%B %N' ${globs} 2>/dev/null || true`
61
- : `stat --format='%W %n' ${globs} 2>/dev/null || true`;
62
- const output = (0, child_process_1.execSync)(command, { encoding: 'utf-8' });
63
- return parseStatOutput(output);
63
+ return fs.statSync(filePath);
64
+ }
65
+ catch {
66
+ return undefined;
67
+ }
68
+ }
69
+ /**
70
+ * `fs.readFileSync` (utf-8) that swallows errors and returns `undefined`
71
+ * on failure. Use when an unreadable file should be skipped rather than
72
+ * raised.
73
+ */
74
+ function safeReadFile(filePath) {
75
+ try {
76
+ return fs.readFileSync(filePath, 'utf-8');
77
+ }
78
+ catch {
79
+ return undefined;
80
+ }
81
+ }
82
+ /**
83
+ * `fs.readdirSync` that swallows errors and returns `[]` on failure.
84
+ * Useful when walking optional/transient directories where missing or
85
+ * unreadable entries should be skipped silently.
86
+ */
87
+ function safeReaddir(dir) {
88
+ try {
89
+ return fs.readdirSync(dir);
64
90
  }
65
91
  catch {
66
92
  return [];
67
93
  }
68
94
  }
69
95
  /**
70
- * Parse stat output lines into SessionFile entries.
96
+ * List entries in a directory that end with `.jsonl`. Returns `[]` on
97
+ * read errors. The result preserves directory order (no sorting).
98
+ */
99
+ function listJsonl(dir) {
100
+ return safeReaddir(dir).filter((name) => name.endsWith('.jsonl'));
101
+ }
102
+ /**
103
+ * Get birth times for .jsonl session files across multiple directories.
104
+ *
105
+ * Enumerates each directory with readdirSync and stats each .jsonl file
106
+ * to get its birth time. No shell commands are used.
107
+ * Returns empty array if no directories have .jsonl files or reads fail.
108
+ * resolvedCwd is left empty — the adapter must set it.
71
109
  */
72
- function parseStatOutput(output) {
110
+ function batchGetSessionFileBirthtimes(dirs) {
111
+ if (dirs.length === 0)
112
+ return [];
73
113
  const results = [];
74
- for (const rawLine of output.trim().split('\n')) {
75
- const line = rawLine.trim();
76
- if (!line)
77
- continue;
78
- // Format: "<epoch_seconds> <filepath>"
79
- const spaceIdx = line.indexOf(' ');
80
- if (spaceIdx === -1)
81
- continue;
82
- const epochStr = line.slice(0, spaceIdx);
83
- const filePath = line.slice(spaceIdx + 1).trim();
84
- const epochSeconds = parseInt(epochStr, 10);
85
- if (!Number.isFinite(epochSeconds) || epochSeconds <= 0)
86
- continue;
87
- const fileName = path.basename(filePath);
88
- if (!fileName.endsWith('.jsonl'))
114
+ for (const dir of dirs) {
115
+ let entries;
116
+ try {
117
+ entries = fs.readdirSync(dir);
118
+ }
119
+ catch {
89
120
  continue;
90
- const sessionId = fileName.replace(/\.jsonl$/, '');
91
- results.push({
92
- sessionId,
93
- filePath,
94
- projectDir: path.dirname(filePath),
95
- birthtimeMs: epochSeconds * 1000,
96
- resolvedCwd: '',
97
- });
121
+ }
122
+ for (const entry of entries) {
123
+ if (!entry.endsWith('.jsonl'))
124
+ continue;
125
+ const filePath = path.join(dir, entry);
126
+ let birthtimeMs;
127
+ try {
128
+ birthtimeMs = fs.statSync(filePath).birthtimeMs;
129
+ }
130
+ catch {
131
+ continue;
132
+ }
133
+ if (!Number.isFinite(birthtimeMs) || birthtimeMs <= 0)
134
+ continue;
135
+ const sessionId = entry.replace(/\.jsonl$/, '');
136
+ results.push({
137
+ sessionId,
138
+ filePath,
139
+ projectDir: dir,
140
+ birthtimeMs,
141
+ resolvedCwd: '',
142
+ });
143
+ }
98
144
  }
99
145
  return results;
100
146
  }
@@ -1 +1 @@
1
- {"version":3,"file":"session.js","sourceRoot":"","sources":["../../src/utils/session.ts"],"names":[],"mappings":";AAAA;;;;;GAKG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAgCH,sEAiBC;AA/CD,2CAA6B;AAC7B,iDAAyC;AAsBzC;;;;;;GAMG;AACH,SAAgB,6BAA6B,CAAC,IAAc;IACxD,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,EAAE,CAAC;IAEjC,IAAI,CAAC;QACD,MAAM,OAAO,GAAG,OAAO,CAAC,QAAQ,KAAK,QAAQ,CAAC;QAC9C,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAC1D,wEAAwE;QACxE,MAAM,OAAO,GAAG,OAAO;YACnB,CAAC,CAAC,mBAAmB,KAAK,sBAAsB;YAChD,CAAC,CAAC,yBAAyB,KAAK,sBAAsB,CAAC;QAE3D,MAAM,MAAM,GAAG,IAAA,wBAAQ,EAAC,OAAO,EAAE,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC,CAAC;QAExD,OAAO,eAAe,CAAC,MAAM,CAAC,CAAC;IACnC,CAAC;IAAC,MAAM,CAAC;QACL,OAAO,EAAE,CAAC;IACd,CAAC;AACL,CAAC;AAED;;GAEG;AACH,SAAS,eAAe,CAAC,MAAc;IACnC,MAAM,OAAO,GAAkB,EAAE,CAAC;IAElC,KAAK,MAAM,OAAO,IAAI,MAAM,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;QAC9C,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,EAAE,CAAC;QAC5B,IAAI,CAAC,IAAI;YAAE,SAAS;QAEpB,uCAAuC;QACvC,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QACnC,IAAI,QAAQ,KAAK,CAAC,CAAC;YAAE,SAAS;QAE9B,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC;QACzC,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,QAAQ,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QAEjD,MAAM,YAAY,GAAG,QAAQ,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;QAC5C,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,YAAY,CAAC,IAAI,YAAY,IAAI,CAAC;YAAE,SAAS;QAElE,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;QACzC,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,QAAQ,CAAC;YAAE,SAAS;QAE3C,MAAM,SAAS,GAAG,QAAQ,CAAC,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC;QAEnD,OAAO,CAAC,IAAI,CAAC;YACT,SAAS;YACT,QAAQ;YACR,UAAU,EAAE,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC;YAClC,WAAW,EAAE,YAAY,GAAG,IAAI;YAChC,WAAW,EAAE,EAAE;SAClB,CAAC,CAAC;IACP,CAAC;IAED,OAAO,OAAO,CAAC;AACnB,CAAC"}
1
+ {"version":3,"file":"session.js","sourceRoot":"","sources":["../../src/utils/session.ts"],"names":[],"mappings":";AAAA;;;;;GAKG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA6BH,kCAEC;AAMD,4BAMC;AAOD,oCAMC;AAOD,kCAMC;AAMD,8BAEC;AAUD,sEAwCC;AA7HD,uCAAyB;AACzB,2CAA6B;AAsB7B;;;GAGG;AACH,SAAgB,WAAW,CAAC,CAAS;IACjC,OAAO,QAAQ,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,IAAI,KAAK,CAAC;AAC/C,CAAC;AAED;;;GAGG;AACH,SAAgB,QAAQ,CAAC,QAAgB;IACrC,IAAI,CAAC;QACD,OAAO,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;IACjC,CAAC;IAAC,MAAM,CAAC;QACL,OAAO,SAAS,CAAC;IACrB,CAAC;AACL,CAAC;AAED;;;;GAIG;AACH,SAAgB,YAAY,CAAC,QAAgB;IACzC,IAAI,CAAC;QACD,OAAO,EAAE,CAAC,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;IAC9C,CAAC;IAAC,MAAM,CAAC;QACL,OAAO,SAAS,CAAC;IACrB,CAAC;AACL,CAAC;AAED;;;;GAIG;AACH,SAAgB,WAAW,CAAC,GAAW;IACnC,IAAI,CAAC;QACD,OAAO,EAAE,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;IAC/B,CAAC;IAAC,MAAM,CAAC;QACL,OAAO,EAAE,CAAC;IACd,CAAC;AACL,CAAC;AAED;;;GAGG;AACH,SAAgB,SAAS,CAAC,GAAW;IACjC,OAAO,WAAW,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC;AACtE,CAAC;AAED;;;;;;;GAOG;AACH,SAAgB,6BAA6B,CAAC,IAAc;IACxD,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,EAAE,CAAC;IAEjC,MAAM,OAAO,GAAkB,EAAE,CAAC;IAElC,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;QACrB,IAAI,OAAiB,CAAC;QACtB,IAAI,CAAC;YACD,OAAO,GAAG,EAAE,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;QAClC,CAAC;QAAC,MAAM,CAAC;YACL,SAAS;QACb,CAAC;QAED,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;YAC1B,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,QAAQ,CAAC;gBAAE,SAAS;YAExC,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;YAEvC,IAAI,WAAmB,CAAC;YACxB,IAAI,CAAC;gBACD,WAAW,GAAG,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,WAAW,CAAC;YACpD,CAAC;YAAC,MAAM,CAAC;gBACL,SAAS;YACb,CAAC;YAED,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,WAAW,CAAC,IAAI,WAAW,IAAI,CAAC;gBAAE,SAAS;YAEhE,MAAM,SAAS,GAAG,KAAK,CAAC,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC;YAEhD,OAAO,CAAC,IAAI,CAAC;gBACT,SAAS;gBACT,QAAQ;gBACR,UAAU,EAAE,GAAG;gBACf,WAAW;gBACX,WAAW,EAAE,EAAE;aAClB,CAAC,CAAC;QACP,CAAC;IACL,CAAC;IAED,OAAO,OAAO,CAAC;AACnB,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ai-devkit/agent-manager",
3
- "version": "0.9.0",
3
+ "version": "0.11.0",
4
4
  "description": "Standalone agent detection and management utilities for AI DevKit",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -5,7 +5,12 @@
5
5
  * Manages adapter registration and aggregates results from all adapters.
6
6
  */
7
7
 
8
- import type { AgentAdapter, AgentInfo } from './adapters/AgentAdapter';
8
+ import type {
9
+ AgentAdapter,
10
+ AgentInfo,
11
+ SessionSummary,
12
+ ListSessionsOptions,
13
+ } from './adapters/AgentAdapter';
9
14
  import { AgentStatus } from './adapters/AgentAdapter';
10
15
 
11
16
  /**
@@ -66,9 +71,19 @@ export class AgentManager {
66
71
  return Array.from(this.adapters.values());
67
72
  }
68
73
 
74
+ /**
75
+ * Get a registered adapter by type
76
+ *
77
+ * @param type Agent type to look up
78
+ * @returns The adapter, or undefined if not registered
79
+ */
80
+ getAdapter(type: string): AgentAdapter | undefined {
81
+ return this.adapters.get(type);
82
+ }
83
+
69
84
  /**
70
85
  * Check if an adapter is registered for a specific type
71
- *
86
+ *
72
87
  * @param type Agent type to check
73
88
  * @returns True if adapter is registered
74
89
  */
@@ -131,12 +146,59 @@ export class AgentManager {
131
146
  return this.sortAgentsByStatus(allAgents);
132
147
  }
133
148
 
149
+ /**
150
+ * List historical sessions across every registered adapter.
151
+ *
152
+ * When `opts.type` is set, adapters whose `type` doesn't match are
153
+ * skipped without being called. The remaining adapters' results are
154
+ * merged and sorted by `lastActive` descending. Adapter failures are
155
+ * caught (one-line stderr warning) so one broken adapter doesn't hide
156
+ * the others.
157
+ *
158
+ * @param opts Filter options computed by the CLI; the manager passes
159
+ * them through to each adapter unchanged.
160
+ */
161
+ async listSessions(opts?: ListSessionsOptions): Promise<SessionSummary[]> {
162
+ const targetAdapters = Array.from(this.adapters.values()).filter(
163
+ (adapter) => opts?.type === undefined || adapter.type === opts.type,
164
+ );
165
+
166
+ const errors: Array<{ type: string; error: Error }> = [];
167
+
168
+ const results = await Promise.all(
169
+ targetAdapters.map(async (adapter) => {
170
+ try {
171
+ return await adapter.listSessions(opts);
172
+ } catch (error) {
173
+ const err = error instanceof Error ? error : new Error(String(error));
174
+ errors.push({ type: adapter.type, error: err });
175
+ return [];
176
+ }
177
+ }),
178
+ );
179
+
180
+ if (errors.length > 0) {
181
+ console.error(`Warning: ${errors.length} adapter(s) failed to list sessions:`);
182
+ for (const { type, error } of errors) {
183
+ console.error(` - ${type}: ${error.message}`);
184
+ }
185
+ }
186
+
187
+ const merged: SessionSummary[] = [];
188
+ for (const list of results) {
189
+ merged.push(...list);
190
+ }
191
+
192
+ merged.sort((a, b) => b.lastActive.getTime() - a.lastActive.getTime());
193
+ return merged;
194
+ }
195
+
134
196
  /**
135
197
  * Sort agents by status priority
136
- *
198
+ *
137
199
  * Priority order: waiting > running > idle > unknown
138
200
  * This ensures agents that need attention appear first.
139
- *
201
+ *
140
202
  * @param agents Array of agents to sort
141
203
  * @returns Sorted array of agents
142
204
  */
@@ -4,15 +4,25 @@
4
4
 
5
5
  import { describe, it, expect, beforeEach } from '@jest/globals';
6
6
  import { AgentManager } from '../AgentManager';
7
- import type { AgentAdapter, AgentInfo, AgentType, ConversationMessage } from '../adapters/AgentAdapter';
7
+ import type {
8
+ AgentAdapter,
9
+ AgentInfo,
10
+ AgentType,
11
+ ConversationMessage,
12
+ SessionSummary,
13
+ } from '../adapters/AgentAdapter';
8
14
  import { AgentStatus } from '../adapters/AgentAdapter';
9
15
 
10
16
  // Mock adapter for testing
11
17
  class MockAdapter implements AgentAdapter {
18
+ public lastListSessionsOpts: unknown = undefined;
19
+
12
20
  constructor(
13
21
  public readonly type: AgentType,
14
22
  private mockAgents: AgentInfo[] = [],
15
- private shouldFail: boolean = false
23
+ private shouldFail: boolean = false,
24
+ private mockSessions: SessionSummary[] = [],
25
+ private shouldFailListSessions: boolean = false,
16
26
  ) { }
17
27
 
18
28
  async detectAgents(): Promise<AgentInfo[]> {
@@ -30,6 +40,14 @@ class MockAdapter implements AgentAdapter {
30
40
  return [];
31
41
  }
32
42
 
43
+ async listSessions(opts?: unknown): Promise<SessionSummary[]> {
44
+ this.lastListSessionsOpts = opts;
45
+ if (this.shouldFailListSessions) {
46
+ throw new Error(`Mock adapter ${this.type} listSessions failed`);
47
+ }
48
+ return this.mockSessions;
49
+ }
50
+
33
51
  setAgents(agents: AgentInfo[]): void {
34
52
  this.mockAgents = agents;
35
53
  }
@@ -37,6 +55,14 @@ class MockAdapter implements AgentAdapter {
37
55
  setFail(shouldFail: boolean): void {
38
56
  this.shouldFail = shouldFail;
39
57
  }
58
+
59
+ setSessions(sessions: SessionSummary[]): void {
60
+ this.mockSessions = sessions;
61
+ }
62
+
63
+ setFailListSessions(shouldFail: boolean): void {
64
+ this.shouldFailListSessions = shouldFail;
65
+ }
40
66
  }
41
67
 
42
68
  // Helper to create mock agent
@@ -226,6 +252,112 @@ describe('AgentManager', () => {
226
252
  });
227
253
  });
228
254
 
255
+ describe('listSessions', () => {
256
+ function createMockSession(overrides: Partial<SessionSummary> = {}): SessionSummary {
257
+ return {
258
+ type: 'claude',
259
+ sessionId: 'session-1',
260
+ cwd: '/repo',
261
+ firstUserMessage: 'hello',
262
+ lastActive: new Date('2025-01-01T00:00:00Z'),
263
+ startedAt: new Date('2025-01-01T00:00:00Z'),
264
+ sessionFilePath: '/tmp/session-1.jsonl',
265
+ ...overrides,
266
+ };
267
+ }
268
+
269
+ it('returns empty array when no adapters are registered', async () => {
270
+ const result = await manager.listSessions();
271
+ expect(result).toEqual([]);
272
+ });
273
+
274
+ it('merges sessions from every registered adapter', async () => {
275
+ const claudeSession = createMockSession({ type: 'claude', sessionId: 'c1' });
276
+ const codexSession = createMockSession({ type: 'codex', sessionId: 'cx1' });
277
+ manager.registerAdapter(new MockAdapter('claude', [], false, [claudeSession]));
278
+ manager.registerAdapter(new MockAdapter('codex', [], false, [codexSession]));
279
+
280
+ const result = await manager.listSessions();
281
+
282
+ expect(result).toHaveLength(2);
283
+ expect(result.map((s) => s.sessionId).sort()).toEqual(['c1', 'cx1']);
284
+ });
285
+
286
+ it('sorts merged sessions by lastActive descending', async () => {
287
+ const older = createMockSession({
288
+ sessionId: 'older',
289
+ lastActive: new Date('2025-01-01T00:00:00Z'),
290
+ });
291
+ const newer = createMockSession({
292
+ type: 'codex',
293
+ sessionId: 'newer',
294
+ lastActive: new Date('2025-06-01T00:00:00Z'),
295
+ });
296
+ manager.registerAdapter(new MockAdapter('claude', [], false, [older]));
297
+ manager.registerAdapter(new MockAdapter('codex', [], false, [newer]));
298
+
299
+ const result = await manager.listSessions();
300
+
301
+ expect(result.map((s) => s.sessionId)).toEqual(['newer', 'older']);
302
+ });
303
+
304
+ it('skips adapters whose type does not match opts.type', async () => {
305
+ const claudeAdapter = new MockAdapter(
306
+ 'claude',
307
+ [],
308
+ false,
309
+ [createMockSession({ type: 'claude', sessionId: 'c1' })],
310
+ );
311
+ const codexAdapter = new MockAdapter(
312
+ 'codex',
313
+ [],
314
+ false,
315
+ [createMockSession({ type: 'codex', sessionId: 'cx1' })],
316
+ );
317
+ manager.registerAdapter(claudeAdapter);
318
+ manager.registerAdapter(codexAdapter);
319
+
320
+ const result = await manager.listSessions({ type: 'claude' });
321
+
322
+ expect(result).toHaveLength(1);
323
+ expect(result[0].sessionId).toBe('c1');
324
+ // Codex adapter must not have been called
325
+ expect(codexAdapter.lastListSessionsOpts).toBeUndefined();
326
+ expect(claudeAdapter.lastListSessionsOpts).toEqual({ type: 'claude' });
327
+ });
328
+
329
+ it('tolerates an adapter that throws and still returns the others', async () => {
330
+ const goodSession = createMockSession({ sessionId: 'good' });
331
+ manager.registerAdapter(new MockAdapter('claude', [], false, [goodSession]));
332
+ manager.registerAdapter(
333
+ new MockAdapter('codex', [], false, [], true /* failListSessions */),
334
+ );
335
+
336
+ const consoleErrorSpy = jest.spyOn(console, 'error').mockImplementation(() => undefined);
337
+
338
+ try {
339
+ const result = await manager.listSessions();
340
+ expect(result).toHaveLength(1);
341
+ expect(result[0].sessionId).toBe('good');
342
+ expect(consoleErrorSpy).toHaveBeenCalled();
343
+ } finally {
344
+ consoleErrorSpy.mockRestore();
345
+ }
346
+ });
347
+
348
+ it('passes the same opts to every called adapter', async () => {
349
+ const a = new MockAdapter('claude', [], false, []);
350
+ const b = new MockAdapter('codex', [], false, []);
351
+ manager.registerAdapter(a);
352
+ manager.registerAdapter(b);
353
+
354
+ await manager.listSessions({ cwd: '/Users/test/proj' });
355
+
356
+ expect(a.lastListSessionsOpts).toEqual({ cwd: '/Users/test/proj' });
357
+ expect(b.lastListSessionsOpts).toEqual({ cwd: '/Users/test/proj' });
358
+ });
359
+ });
360
+
229
361
  describe('resolveAgent', () => {
230
362
  it('should return null for empty input or empty agents list', () => {
231
363
  const agent = createMockAgent({ name: 'test-agent' });