@ai-devkit/agent-manager 0.26.2 → 0.26.4

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 (104) hide show
  1. package/dist/AgentManager.d.ts +5 -2
  2. package/dist/AgentManager.d.ts.map +1 -1
  3. package/dist/AgentManager.js +28 -10
  4. package/dist/AgentManager.js.map +1 -1
  5. package/dist/__tests__/AgentManager.test.js +289 -4
  6. package/dist/__tests__/AgentManager.test.js.map +1 -1
  7. package/dist/__tests__/adapters/ClaudeCodeAdapter.test.js +13 -4
  8. package/dist/__tests__/adapters/ClaudeCodeAdapter.test.js.map +1 -1
  9. package/dist/__tests__/adapters/CodexAdapter.test.js +13 -4
  10. package/dist/__tests__/adapters/CodexAdapter.test.js.map +1 -1
  11. package/dist/__tests__/adapters/CopilotAdapter.test.js +7 -2
  12. package/dist/__tests__/adapters/CopilotAdapter.test.js.map +1 -1
  13. package/dist/__tests__/adapters/GeminiCliAdapter.test.js +18 -5
  14. package/dist/__tests__/adapters/GeminiCliAdapter.test.js.map +1 -1
  15. package/dist/__tests__/adapters/GrokCliAdapter.test.js +7 -2
  16. package/dist/__tests__/adapters/GrokCliAdapter.test.js.map +1 -1
  17. package/dist/__tests__/adapters/OpenCodeAdapter.test.js +13 -4
  18. package/dist/__tests__/adapters/OpenCodeAdapter.test.js.map +1 -1
  19. package/dist/__tests__/adapters/PiAdapter.test.js +32 -4
  20. package/dist/__tests__/adapters/PiAdapter.test.js.map +1 -1
  21. package/dist/__tests__/utils/AgentRegistry.test.js +140 -0
  22. package/dist/__tests__/utils/AgentRegistry.test.js.map +1 -1
  23. package/dist/__tests__/utils/process.test.js +90 -2
  24. package/dist/__tests__/utils/process.test.js.map +1 -1
  25. package/dist/adapters/AgentAdapter.d.ts +9 -3
  26. package/dist/adapters/AgentAdapter.d.ts.map +1 -1
  27. package/dist/adapters/AgentAdapter.js.map +1 -1
  28. package/dist/adapters/ClaudeCodeAdapter.d.ts +5 -4
  29. package/dist/adapters/ClaudeCodeAdapter.d.ts.map +1 -1
  30. package/dist/adapters/ClaudeCodeAdapter.js +11 -7
  31. package/dist/adapters/ClaudeCodeAdapter.js.map +1 -1
  32. package/dist/adapters/CodexAdapter.d.ts +5 -4
  33. package/dist/adapters/CodexAdapter.d.ts.map +1 -1
  34. package/dist/adapters/CodexAdapter.js +11 -7
  35. package/dist/adapters/CodexAdapter.js.map +1 -1
  36. package/dist/adapters/CopilotAdapter.d.ts +5 -4
  37. package/dist/adapters/CopilotAdapter.d.ts.map +1 -1
  38. package/dist/adapters/CopilotAdapter.js +11 -7
  39. package/dist/adapters/CopilotAdapter.js.map +1 -1
  40. package/dist/adapters/GeminiCliAdapter.d.ts +6 -5
  41. package/dist/adapters/GeminiCliAdapter.d.ts.map +1 -1
  42. package/dist/adapters/GeminiCliAdapter.js +12 -8
  43. package/dist/adapters/GeminiCliAdapter.js.map +1 -1
  44. package/dist/adapters/GrokCliAdapter.d.ts +3 -2
  45. package/dist/adapters/GrokCliAdapter.d.ts.map +1 -1
  46. package/dist/adapters/GrokCliAdapter.js +10 -6
  47. package/dist/adapters/GrokCliAdapter.js.map +1 -1
  48. package/dist/adapters/OpenCodeAdapter.d.ts +5 -4
  49. package/dist/adapters/OpenCodeAdapter.d.ts.map +1 -1
  50. package/dist/adapters/OpenCodeAdapter.js +11 -7
  51. package/dist/adapters/OpenCodeAdapter.js.map +1 -1
  52. package/dist/adapters/PiAdapter.d.ts +3 -2
  53. package/dist/adapters/PiAdapter.d.ts.map +1 -1
  54. package/dist/adapters/PiAdapter.js +12 -9
  55. package/dist/adapters/PiAdapter.js.map +1 -1
  56. package/dist/adapters/index.d.ts +1 -1
  57. package/dist/adapters/index.d.ts.map +1 -1
  58. package/dist/adapters/index.js.map +1 -1
  59. package/dist/database/connection.d.ts +1 -1
  60. package/dist/database/connection.d.ts.map +1 -1
  61. package/dist/database/connection.js +1 -1
  62. package/dist/database/connection.js.map +1 -1
  63. package/dist/index.d.ts +3 -2
  64. package/dist/index.d.ts.map +1 -1
  65. package/dist/index.js +1 -0
  66. package/dist/index.js.map +1 -1
  67. package/dist/utils/AgentRegistry.d.ts +14 -1
  68. package/dist/utils/AgentRegistry.d.ts.map +1 -1
  69. package/dist/utils/AgentRegistry.js +65 -20
  70. package/dist/utils/AgentRegistry.js.map +1 -1
  71. package/dist/utils/index.d.ts +1 -1
  72. package/dist/utils/index.d.ts.map +1 -1
  73. package/dist/utils/index.js +1 -1
  74. package/dist/utils/index.js.map +1 -1
  75. package/dist/utils/process.d.ts +9 -1
  76. package/dist/utils/process.d.ts.map +1 -1
  77. package/dist/utils/process.js +155 -10
  78. package/dist/utils/process.js.map +1 -1
  79. package/package.json +1 -1
  80. package/src/AgentManager.ts +35 -8
  81. package/src/__tests__/AgentManager.test.ts +231 -4
  82. package/src/__tests__/adapters/ClaudeCodeAdapter.test.ts +16 -5
  83. package/src/__tests__/adapters/CodexAdapter.test.ts +16 -5
  84. package/src/__tests__/adapters/CopilotAdapter.test.ts +8 -1
  85. package/src/__tests__/adapters/GeminiCliAdapter.test.ts +20 -4
  86. package/src/__tests__/adapters/GrokCliAdapter.test.ts +8 -1
  87. package/src/__tests__/adapters/OpenCodeAdapter.test.ts +16 -5
  88. package/src/__tests__/adapters/PiAdapter.test.ts +28 -5
  89. package/src/__tests__/utils/AgentRegistry.test.ts +119 -0
  90. package/src/__tests__/utils/process.test.ts +72 -1
  91. package/src/adapters/AgentAdapter.ts +11 -3
  92. package/src/adapters/ClaudeCodeAdapter.ts +10 -7
  93. package/src/adapters/CodexAdapter.ts +10 -7
  94. package/src/adapters/CopilotAdapter.ts +16 -7
  95. package/src/adapters/GeminiCliAdapter.ts +17 -8
  96. package/src/adapters/GrokCliAdapter.ts +9 -6
  97. package/src/adapters/OpenCodeAdapter.ts +10 -7
  98. package/src/adapters/PiAdapter.ts +10 -9
  99. package/src/adapters/index.ts +1 -1
  100. package/src/database/connection.ts +4 -2
  101. package/src/index.ts +3 -1
  102. package/src/utils/AgentRegistry.ts +85 -17
  103. package/src/utils/index.ts +1 -1
  104. package/src/utils/process.ts +160 -10
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/adapters/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAC3D,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACrD,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AACzD,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACrD,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AACvD,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC3C,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,YAAY,EAAE,YAAY,EAAE,SAAS,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/adapters/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAC3D,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACrD,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AACzD,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACrD,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AACvD,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC3C,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,YAAY,EAAE,YAAY,EAAE,SAAS,EAAE,SAAS,EAAE,WAAW,EAAE,qBAAqB,EAAE,MAAM,mBAAmB,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/adapters/index.ts"],"sourcesContent":["export { ClaudeCodeAdapter } from './ClaudeCodeAdapter.js';\nexport { CodexAdapter } from './CodexAdapter.js';\nexport { CopilotAdapter } from './CopilotAdapter.js';\nexport { GeminiCliAdapter } from './GeminiCliAdapter.js';\nexport { GrokCliAdapter } from './GrokCliAdapter.js';\nexport { OpenCodeAdapter } from './OpenCodeAdapter.js';\nexport { PiAdapter } from './PiAdapter.js';\nexport { AgentStatus } from './AgentAdapter.js';\nexport type { AgentAdapter, AgentType, AgentInfo, ProcessInfo } from './AgentAdapter.js';\n"],"names":["ClaudeCodeAdapter","CodexAdapter","CopilotAdapter","GeminiCliAdapter","GrokCliAdapter","OpenCodeAdapter","PiAdapter","AgentStatus"],"mappings":"AAAA,SAASA,iBAAiB,QAAQ,yBAAyB;AAC3D,SAASC,YAAY,QAAQ,oBAAoB;AACjD,SAASC,cAAc,QAAQ,sBAAsB;AACrD,SAASC,gBAAgB,QAAQ,wBAAwB;AACzD,SAASC,cAAc,QAAQ,sBAAsB;AACrD,SAASC,eAAe,QAAQ,uBAAuB;AACvD,SAASC,SAAS,QAAQ,iBAAiB;AAC3C,SAASC,WAAW,QAAQ,oBAAoB"}
1
+ {"version":3,"sources":["../../src/adapters/index.ts"],"sourcesContent":["export { ClaudeCodeAdapter } from './ClaudeCodeAdapter.js';\nexport { CodexAdapter } from './CodexAdapter.js';\nexport { CopilotAdapter } from './CopilotAdapter.js';\nexport { GeminiCliAdapter } from './GeminiCliAdapter.js';\nexport { GrokCliAdapter } from './GrokCliAdapter.js';\nexport { OpenCodeAdapter } from './OpenCodeAdapter.js';\nexport { PiAdapter } from './PiAdapter.js';\nexport { AgentStatus } from './AgentAdapter.js';\nexport type { AgentAdapter, AgentType, AgentInfo, ProcessInfo, AgentDetectionContext } from './AgentAdapter.js';\n"],"names":["ClaudeCodeAdapter","CodexAdapter","CopilotAdapter","GeminiCliAdapter","GrokCliAdapter","OpenCodeAdapter","PiAdapter","AgentStatus"],"mappings":"AAAA,SAASA,iBAAiB,QAAQ,yBAAyB;AAC3D,SAASC,YAAY,QAAQ,oBAAoB;AACjD,SAASC,cAAc,QAAQ,sBAAsB;AACrD,SAASC,gBAAgB,QAAQ,wBAAwB;AACzD,SAASC,cAAc,QAAQ,sBAAsB;AACrD,SAASC,eAAe,QAAQ,uBAAuB;AACvD,SAASC,SAAS,QAAQ,iBAAiB;AAC3C,SAASC,WAAW,QAAQ,oBAAoB"}
@@ -2,7 +2,7 @@ import Database from 'better-sqlite3';
2
2
  export declare const DEFAULT_AGENT_REGISTRY_DB_PATH: string;
3
3
  export interface DatabaseOptions {
4
4
  dbPath?: string;
5
- verbose?: boolean;
5
+ verbose?: boolean | ((message: string) => void);
6
6
  readonly?: boolean;
7
7
  }
8
8
  export declare function resolveAgentRegistryDbPath(filePath?: string): string;
@@ -1 +1 @@
1
- {"version":3,"file":"connection.d.ts","sourceRoot":"","sources":["../../src/database/connection.ts"],"names":[],"mappings":"AAAA,OAAO,QAAQ,MAAM,gBAAgB,CAAC;AAMtC,eAAO,MAAM,8BAA8B,QAA6C,CAAC;AAEzF,MAAM,WAAW,eAAe;IAC5B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACtB;AAED,wBAAgB,0BAA0B,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,CAGpE;AAED,qBAAa,kBAAkB;IAC3B,OAAO,CAAC,EAAE,CAAoB;IAC9B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;gBAEpB,OAAO,GAAE,eAAoB;IAazC,OAAO,CAAC,SAAS;IAQjB,IAAI,QAAQ,IAAI,QAAQ,CAAC,QAAQ,CAEhC;IAED,IAAI,IAAI,IAAI,MAAM,CAEjB;IAED,KAAK,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,GAAE,OAAO,EAAO,GAAG,CAAC,EAAE;IAIlD,QAAQ,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,GAAE,OAAO,EAAO,GAAG,CAAC,GAAG,SAAS;IAI/D,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,GAAE,OAAO,EAAO,GAAG,QAAQ,CAAC,SAAS;IAIhE,WAAW,CAAC,CAAC,EAAE,EAAE,EAAE,MAAM,CAAC,GAAG,CAAC;IAI9B,KAAK,IAAI,IAAI;CAKhB"}
1
+ {"version":3,"file":"connection.d.ts","sourceRoot":"","sources":["../../src/database/connection.ts"],"names":[],"mappings":"AAAA,OAAO,QAAQ,MAAM,gBAAgB,CAAC;AAMtC,eAAO,MAAM,8BAA8B,QAA6C,CAAC;AAEzF,MAAM,WAAW,eAAe;IAC5B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,OAAO,GAAG,CAAC,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC,CAAC;IAChD,QAAQ,CAAC,EAAE,OAAO,CAAC;CACtB;AAED,wBAAgB,0BAA0B,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,CAGpE;AAED,qBAAa,kBAAkB;IAC3B,OAAO,CAAC,EAAE,CAAoB;IAC9B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;gBAEpB,OAAO,GAAE,eAAoB;IAezC,OAAO,CAAC,SAAS;IAQjB,IAAI,QAAQ,IAAI,QAAQ,CAAC,QAAQ,CAEhC;IAED,IAAI,IAAI,IAAI,MAAM,CAEjB;IAED,KAAK,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,GAAE,OAAO,EAAO,GAAG,CAAC,EAAE;IAIlD,QAAQ,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,GAAE,OAAO,EAAO,GAAG,CAAC,GAAG,SAAS;IAI/D,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,GAAE,OAAO,EAAO,GAAG,QAAQ,CAAC,SAAS;IAIhE,WAAW,CAAC,CAAC,EAAE,EAAE,EAAE,MAAM,CAAC,GAAG,CAAC;IAI9B,KAAK,IAAI,IAAI;CAKhB"}
@@ -18,7 +18,7 @@ export class DatabaseConnection {
18
18
  });
19
19
  this.db = new Database(this.dbPath, {
20
20
  readonly: options.readonly ?? false,
21
- verbose: options.verbose ? console.log : undefined
21
+ verbose: typeof options.verbose === 'function' ? options.verbose : options.verbose ? console.log : undefined
22
22
  });
23
23
  this.configure();
24
24
  initializeSchema(this);
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/database/connection.ts"],"sourcesContent":["import Database from 'better-sqlite3';\nimport { mkdirSync } from 'fs';\nimport { dirname, join } from 'path';\nimport { homedir } from 'os';\nimport { initializeSchema } from './schema.js';\n\nexport const DEFAULT_AGENT_REGISTRY_DB_PATH = join(homedir(), '.ai-devkit', 'agents.db');\n\nexport interface DatabaseOptions {\n dbPath?: string;\n verbose?: boolean;\n readonly?: boolean;\n}\n\nexport function resolveAgentRegistryDbPath(filePath?: string): string {\n if (!filePath) return DEFAULT_AGENT_REGISTRY_DB_PATH;\n return filePath.endsWith('.json') ? filePath.replace(/\\.json$/, '.db') : filePath;\n}\n\nexport class DatabaseConnection {\n private db: Database.Database;\n private readonly dbPath: string;\n\n constructor(options: DatabaseOptions = {}) {\n this.dbPath = options.dbPath ?? DEFAULT_AGENT_REGISTRY_DB_PATH;\n mkdirSync(dirname(this.dbPath), { recursive: true });\n\n this.db = new Database(this.dbPath, {\n readonly: options.readonly ?? false,\n verbose: options.verbose ? console.log : undefined,\n });\n\n this.configure();\n initializeSchema(this);\n }\n\n private configure(): void {\n this.db.pragma('journal_mode = WAL');\n this.db.pragma('foreign_keys = ON');\n this.db.pragma('synchronous = NORMAL');\n this.db.pragma('busy_timeout = 5000');\n this.db.pragma('mmap_size = 268435456');\n }\n\n get instance(): Database.Database {\n return this.db;\n }\n\n get path(): string {\n return this.dbPath;\n }\n\n query<T>(sql: string, params: unknown[] = []): T[] {\n return this.db.prepare(sql).all(...params) as T[];\n }\n\n queryOne<T>(sql: string, params: unknown[] = []): T | undefined {\n return this.db.prepare(sql).get(...params) as T | undefined;\n }\n\n execute(sql: string, params: unknown[] = []): Database.RunResult {\n return this.db.prepare(sql).run(...params);\n }\n\n transaction<T>(fn: () => T): T {\n return this.db.transaction(fn)();\n }\n\n close(): void {\n if (this.db.open) {\n this.db.close();\n }\n }\n}\n"],"names":["Database","mkdirSync","dirname","join","homedir","initializeSchema","DEFAULT_AGENT_REGISTRY_DB_PATH","resolveAgentRegistryDbPath","filePath","endsWith","replace","DatabaseConnection","db","dbPath","options","recursive","readonly","verbose","console","log","undefined","configure","pragma","instance","path","query","sql","params","prepare","all","queryOne","get","execute","run","transaction","fn","close","open"],"mappings":"AAAA,OAAOA,cAAc,iBAAiB;AACtC,SAASC,SAAS,QAAQ,KAAK;AAC/B,SAASC,OAAO,EAAEC,IAAI,QAAQ,OAAO;AACrC,SAASC,OAAO,QAAQ,KAAK;AAC7B,SAASC,gBAAgB,QAAQ,cAAc;AAE/C,OAAO,MAAMC,iCAAiCH,KAAKC,WAAW,cAAc,aAAa;AAQzF,OAAO,SAASG,2BAA2BC,QAAiB;IACxD,IAAI,CAACA,UAAU,OAAOF;IACtB,OAAOE,SAASC,QAAQ,CAAC,WAAWD,SAASE,OAAO,CAAC,WAAW,SAASF;AAC7E;AAEA,OAAO,MAAMG;IACDC,GAAsB;IACbC,OAAe;IAEhC,YAAYC,UAA2B,CAAC,CAAC,CAAE;QACvC,IAAI,CAACD,MAAM,GAAGC,QAAQD,MAAM,IAAIP;QAChCL,UAAUC,QAAQ,IAAI,CAACW,MAAM,GAAG;YAAEE,WAAW;QAAK;QAElD,IAAI,CAACH,EAAE,GAAG,IAAIZ,SAAS,IAAI,CAACa,MAAM,EAAE;YAChCG,UAAUF,QAAQE,QAAQ,IAAI;YAC9BC,SAASH,QAAQG,OAAO,GAAGC,QAAQC,GAAG,GAAGC;QAC7C;QAEA,IAAI,CAACC,SAAS;QACdhB,iBAAiB,IAAI;IACzB;IAEQgB,YAAkB;QACtB,IAAI,CAACT,EAAE,CAACU,MAAM,CAAC;QACf,IAAI,CAACV,EAAE,CAACU,MAAM,CAAC;QACf,IAAI,CAACV,EAAE,CAACU,MAAM,CAAC;QACf,IAAI,CAACV,EAAE,CAACU,MAAM,CAAC;QACf,IAAI,CAACV,EAAE,CAACU,MAAM,CAAC;IACnB;IAEA,IAAIC,WAA8B;QAC9B,OAAO,IAAI,CAACX,EAAE;IAClB;IAEA,IAAIY,OAAe;QACf,OAAO,IAAI,CAACX,MAAM;IACtB;IAEAY,MAASC,GAAW,EAAEC,SAAoB,EAAE,EAAO;QAC/C,OAAO,IAAI,CAACf,EAAE,CAACgB,OAAO,CAACF,KAAKG,GAAG,IAAIF;IACvC;IAEAG,SAAYJ,GAAW,EAAEC,SAAoB,EAAE,EAAiB;QAC5D,OAAO,IAAI,CAACf,EAAE,CAACgB,OAAO,CAACF,KAAKK,GAAG,IAAIJ;IACvC;IAEAK,QAAQN,GAAW,EAAEC,SAAoB,EAAE,EAAsB;QAC7D,OAAO,IAAI,CAACf,EAAE,CAACgB,OAAO,CAACF,KAAKO,GAAG,IAAIN;IACvC;IAEAO,YAAeC,EAAW,EAAK;QAC3B,OAAO,IAAI,CAACvB,EAAE,CAACsB,WAAW,CAACC;IAC/B;IAEAC,QAAc;QACV,IAAI,IAAI,CAACxB,EAAE,CAACyB,IAAI,EAAE;YACd,IAAI,CAACzB,EAAE,CAACwB,KAAK;QACjB;IACJ;AACJ"}
1
+ {"version":3,"sources":["../../src/database/connection.ts"],"sourcesContent":["import Database from 'better-sqlite3';\nimport { mkdirSync } from 'fs';\nimport { dirname, join } from 'path';\nimport { homedir } from 'os';\nimport { initializeSchema } from './schema.js';\n\nexport const DEFAULT_AGENT_REGISTRY_DB_PATH = join(homedir(), '.ai-devkit', 'agents.db');\n\nexport interface DatabaseOptions {\n dbPath?: string;\n verbose?: boolean | ((message: string) => void);\n readonly?: boolean;\n}\n\nexport function resolveAgentRegistryDbPath(filePath?: string): string {\n if (!filePath) return DEFAULT_AGENT_REGISTRY_DB_PATH;\n return filePath.endsWith('.json') ? filePath.replace(/\\.json$/, '.db') : filePath;\n}\n\nexport class DatabaseConnection {\n private db: Database.Database;\n private readonly dbPath: string;\n\n constructor(options: DatabaseOptions = {}) {\n this.dbPath = options.dbPath ?? DEFAULT_AGENT_REGISTRY_DB_PATH;\n mkdirSync(dirname(this.dbPath), { recursive: true });\n\n this.db = new Database(this.dbPath, {\n readonly: options.readonly ?? false,\n verbose: typeof options.verbose === 'function'\n ? options.verbose\n : options.verbose ? console.log : undefined,\n });\n\n this.configure();\n initializeSchema(this);\n }\n\n private configure(): void {\n this.db.pragma('journal_mode = WAL');\n this.db.pragma('foreign_keys = ON');\n this.db.pragma('synchronous = NORMAL');\n this.db.pragma('busy_timeout = 5000');\n this.db.pragma('mmap_size = 268435456');\n }\n\n get instance(): Database.Database {\n return this.db;\n }\n\n get path(): string {\n return this.dbPath;\n }\n\n query<T>(sql: string, params: unknown[] = []): T[] {\n return this.db.prepare(sql).all(...params) as T[];\n }\n\n queryOne<T>(sql: string, params: unknown[] = []): T | undefined {\n return this.db.prepare(sql).get(...params) as T | undefined;\n }\n\n execute(sql: string, params: unknown[] = []): Database.RunResult {\n return this.db.prepare(sql).run(...params);\n }\n\n transaction<T>(fn: () => T): T {\n return this.db.transaction(fn)();\n }\n\n close(): void {\n if (this.db.open) {\n this.db.close();\n }\n }\n}\n"],"names":["Database","mkdirSync","dirname","join","homedir","initializeSchema","DEFAULT_AGENT_REGISTRY_DB_PATH","resolveAgentRegistryDbPath","filePath","endsWith","replace","DatabaseConnection","db","dbPath","options","recursive","readonly","verbose","console","log","undefined","configure","pragma","instance","path","query","sql","params","prepare","all","queryOne","get","execute","run","transaction","fn","close","open"],"mappings":"AAAA,OAAOA,cAAc,iBAAiB;AACtC,SAASC,SAAS,QAAQ,KAAK;AAC/B,SAASC,OAAO,EAAEC,IAAI,QAAQ,OAAO;AACrC,SAASC,OAAO,QAAQ,KAAK;AAC7B,SAASC,gBAAgB,QAAQ,cAAc;AAE/C,OAAO,MAAMC,iCAAiCH,KAAKC,WAAW,cAAc,aAAa;AAQzF,OAAO,SAASG,2BAA2BC,QAAiB;IACxD,IAAI,CAACA,UAAU,OAAOF;IACtB,OAAOE,SAASC,QAAQ,CAAC,WAAWD,SAASE,OAAO,CAAC,WAAW,SAASF;AAC7E;AAEA,OAAO,MAAMG;IACDC,GAAsB;IACbC,OAAe;IAEhC,YAAYC,UAA2B,CAAC,CAAC,CAAE;QACvC,IAAI,CAACD,MAAM,GAAGC,QAAQD,MAAM,IAAIP;QAChCL,UAAUC,QAAQ,IAAI,CAACW,MAAM,GAAG;YAAEE,WAAW;QAAK;QAElD,IAAI,CAACH,EAAE,GAAG,IAAIZ,SAAS,IAAI,CAACa,MAAM,EAAE;YAChCG,UAAUF,QAAQE,QAAQ,IAAI;YAC9BC,SAAS,OAAOH,QAAQG,OAAO,KAAK,aAC9BH,QAAQG,OAAO,GACfH,QAAQG,OAAO,GAAGC,QAAQC,GAAG,GAAGC;QAC1C;QAEA,IAAI,CAACC,SAAS;QACdhB,iBAAiB,IAAI;IACzB;IAEQgB,YAAkB;QACtB,IAAI,CAACT,EAAE,CAACU,MAAM,CAAC;QACf,IAAI,CAACV,EAAE,CAACU,MAAM,CAAC;QACf,IAAI,CAACV,EAAE,CAACU,MAAM,CAAC;QACf,IAAI,CAACV,EAAE,CAACU,MAAM,CAAC;QACf,IAAI,CAACV,EAAE,CAACU,MAAM,CAAC;IACnB;IAEA,IAAIC,WAA8B;QAC9B,OAAO,IAAI,CAACX,EAAE;IAClB;IAEA,IAAIY,OAAe;QACf,OAAO,IAAI,CAACX,MAAM;IACtB;IAEAY,MAASC,GAAW,EAAEC,SAAoB,EAAE,EAAO;QAC/C,OAAO,IAAI,CAACf,EAAE,CAACgB,OAAO,CAACF,KAAKG,GAAG,IAAIF;IACvC;IAEAG,SAAYJ,GAAW,EAAEC,SAAoB,EAAE,EAAiB;QAC5D,OAAO,IAAI,CAACf,EAAE,CAACgB,OAAO,CAACF,KAAKK,GAAG,IAAIJ;IACvC;IAEAK,QAAQN,GAAW,EAAEC,SAAoB,EAAE,EAAsB;QAC7D,OAAO,IAAI,CAACf,EAAE,CAACgB,OAAO,CAACF,KAAKO,GAAG,IAAIN;IACvC;IAEAO,YAAeC,EAAW,EAAK;QAC3B,OAAO,IAAI,CAACvB,EAAE,CAACsB,WAAW,CAACC;IAC/B;IAEAC,QAAc;QACV,IAAI,IAAI,CAACxB,EAAE,CAACyB,IAAI,EAAE;YACd,IAAI,CAACzB,EAAE,CAACwB,KAAK;QACjB;IACJ;AACJ"}
package/dist/index.d.ts CHANGED
@@ -7,15 +7,16 @@ export { GrokCliAdapter } from './adapters/GrokCliAdapter.js';
7
7
  export { OpenCodeAdapter } from './adapters/OpenCodeAdapter.js';
8
8
  export { PiAdapter } from './adapters/PiAdapter.js';
9
9
  export { AgentStatus } from './adapters/AgentAdapter.js';
10
- export type { AgentAdapter, AgentType, AgentInfo, ProcessInfo, ConversationMessage, SessionSummary, ListSessionsOptions, } from './adapters/AgentAdapter.js';
10
+ export type { AgentAdapter, AgentType, AgentInfo, ProcessInfo, ConversationMessage, SessionSummary, ListSessionsOptions, AgentDetectionContext, } from './adapters/AgentAdapter.js';
11
11
  export { TerminalFocusManager, TerminalType } from './terminal/TerminalFocusManager.js';
12
12
  export type { TerminalLocation } from './terminal/TerminalFocusManager.js';
13
13
  export { TtyWriter } from './terminal/TtyWriter.js';
14
14
  export { getProcessTty } from './utils/process.js';
15
+ export { captureProcessSnapshot, executableBasename, filterByProcessNames } from './utils/process.js';
15
16
  export type { AgentSortKey } from './utils/sortAgents.js';
16
17
  export type { ListAgentsOptions } from './AgentManager.js';
17
18
  export { AgentRegistry, RenameNotFoundError, RenameConflictError } from './utils/AgentRegistry.js';
18
- export type { RegistryEntry } from './utils/AgentRegistry.js';
19
+ export type { AgentRegistryOptions, RegistryEntry } from './utils/AgentRegistry.js';
19
20
  export { TmuxManager } from './terminal/TmuxManager.js';
20
21
  export { AGENTS } from './utils/agents.js';
21
22
  export type { AgentConfig, StartableAgentType } from './utils/agents.js';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAEjD,OAAO,EAAE,iBAAiB,EAAE,MAAM,iCAAiC,CAAC;AACpE,OAAO,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAC1D,OAAO,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAC9D,OAAO,EAAE,gBAAgB,EAAE,MAAM,gCAAgC,CAAC;AAClE,OAAO,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAC9D,OAAO,EAAE,eAAe,EAAE,MAAM,+BAA+B,CAAC;AAChE,OAAO,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;AACpD,OAAO,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAC;AACzD,YAAY,EACR,YAAY,EACZ,SAAS,EACT,SAAS,EACT,WAAW,EACX,mBAAmB,EACnB,cAAc,EACd,mBAAmB,GACtB,MAAM,4BAA4B,CAAC;AAEpC,OAAO,EAAE,oBAAoB,EAAE,YAAY,EAAE,MAAM,oCAAoC,CAAC;AACxF,YAAY,EAAE,gBAAgB,EAAE,MAAM,oCAAoC,CAAC;AAC3E,OAAO,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;AAEpD,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,YAAY,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAC1D,YAAY,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAE3D,OAAO,EAAE,aAAa,EAAE,mBAAmB,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AACnG,YAAY,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AAC9D,OAAO,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAC;AACxD,OAAO,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAC3C,YAAY,EAAE,WAAW,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAEzE,YAAY,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AAC9D,OAAO,EAAE,mBAAmB,EAAE,sBAAsB,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAE3G,OAAO,EACH,eAAe,EACf,mBAAmB,EACnB,uBAAuB,EACvB,oBAAoB,EACpB,2BAA2B,EAC3B,gBAAgB,GACnB,MAAM,uBAAuB,CAAC;AAC/B,YAAY,EACR,UAAU,EACV,eAAe,EACf,kBAAkB,EAClB,cAAc,EACd,cAAc,EACd,eAAe,EACf,eAAe,GAClB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAC7D,OAAO,EAAE,qBAAqB,EAAE,MAAM,4BAA4B,CAAC;AACnE,YAAY,EACR,qBAAqB,EACrB,sBAAsB,EACtB,gBAAgB,EAChB,kBAAkB,GACrB,MAAM,4BAA4B,CAAC;AACpC,OAAO,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAC3D,YAAY,EAAE,qBAAqB,EAAE,MAAM,2BAA2B,CAAC;AACvE,OAAO,EAAE,iBAAiB,EAAE,MAAM,8BAA8B,CAAC;AACjE,YAAY,EACR,wBAAwB,EACxB,qBAAqB,EACrB,oBAAoB,GACvB,MAAM,8BAA8B,CAAC;AACtC,OAAO,EAAE,uBAAuB,EAAE,MAAM,oCAAoC,CAAC;AAC7E,YAAY,EACR,8BAA8B,EAC9B,qBAAqB,GACxB,MAAM,oCAAoC,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAEjD,OAAO,EAAE,iBAAiB,EAAE,MAAM,iCAAiC,CAAC;AACpE,OAAO,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAC1D,OAAO,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAC9D,OAAO,EAAE,gBAAgB,EAAE,MAAM,gCAAgC,CAAC;AAClE,OAAO,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAC9D,OAAO,EAAE,eAAe,EAAE,MAAM,+BAA+B,CAAC;AAChE,OAAO,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;AACpD,OAAO,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAC;AACzD,YAAY,EACR,YAAY,EACZ,SAAS,EACT,SAAS,EACT,WAAW,EACX,mBAAmB,EACnB,cAAc,EACd,mBAAmB,EACnB,qBAAqB,GACxB,MAAM,4BAA4B,CAAC;AAEpC,OAAO,EAAE,oBAAoB,EAAE,YAAY,EAAE,MAAM,oCAAoC,CAAC;AACxF,YAAY,EAAE,gBAAgB,EAAE,MAAM,oCAAoC,CAAC;AAC3E,OAAO,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;AAEpD,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,EAAE,sBAAsB,EAAE,kBAAkB,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AACtG,YAAY,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAC1D,YAAY,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAE3D,OAAO,EAAE,aAAa,EAAE,mBAAmB,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AACnG,YAAY,EAAE,oBAAoB,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AACpF,OAAO,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAC;AACxD,OAAO,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAC3C,YAAY,EAAE,WAAW,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAEzE,YAAY,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AAC9D,OAAO,EAAE,mBAAmB,EAAE,sBAAsB,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAE3G,OAAO,EACH,eAAe,EACf,mBAAmB,EACnB,uBAAuB,EACvB,oBAAoB,EACpB,2BAA2B,EAC3B,gBAAgB,GACnB,MAAM,uBAAuB,CAAC;AAC/B,YAAY,EACR,UAAU,EACV,eAAe,EACf,kBAAkB,EAClB,cAAc,EACd,cAAc,EACd,eAAe,EACf,eAAe,GAClB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAC7D,OAAO,EAAE,qBAAqB,EAAE,MAAM,4BAA4B,CAAC;AACnE,YAAY,EACR,qBAAqB,EACrB,sBAAsB,EACtB,gBAAgB,EAChB,kBAAkB,GACrB,MAAM,4BAA4B,CAAC;AACpC,OAAO,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAC3D,YAAY,EAAE,qBAAqB,EAAE,MAAM,2BAA2B,CAAC;AACvE,OAAO,EAAE,iBAAiB,EAAE,MAAM,8BAA8B,CAAC;AACjE,YAAY,EACR,wBAAwB,EACxB,qBAAqB,EACrB,oBAAoB,GACvB,MAAM,8BAA8B,CAAC;AACtC,OAAO,EAAE,uBAAuB,EAAE,MAAM,oCAAoC,CAAC;AAC7E,YAAY,EACR,8BAA8B,EAC9B,qBAAqB,GACxB,MAAM,oCAAoC,CAAC"}
package/dist/index.js CHANGED
@@ -10,6 +10,7 @@ export { AgentStatus } from './adapters/AgentAdapter.js';
10
10
  export { TerminalFocusManager, TerminalType } from './terminal/TerminalFocusManager.js';
11
11
  export { TtyWriter } from './terminal/TtyWriter.js';
12
12
  export { getProcessTty } from './utils/process.js';
13
+ export { captureProcessSnapshot, executableBasename, filterByProcessNames } from './utils/process.js';
13
14
  export { AgentRegistry, RenameNotFoundError, RenameConflictError } from './utils/AgentRegistry.js';
14
15
  export { TmuxManager } from './terminal/TmuxManager.js';
15
16
  export { AGENTS } from './utils/agents.js';
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts"],"sourcesContent":["export { AgentManager } from './AgentManager.js';\n\nexport { ClaudeCodeAdapter } from './adapters/ClaudeCodeAdapter.js';\nexport { CodexAdapter } from './adapters/CodexAdapter.js';\nexport { CopilotAdapter } from './adapters/CopilotAdapter.js';\nexport { GeminiCliAdapter } from './adapters/GeminiCliAdapter.js';\nexport { GrokCliAdapter } from './adapters/GrokCliAdapter.js';\nexport { OpenCodeAdapter } from './adapters/OpenCodeAdapter.js';\nexport { PiAdapter } from './adapters/PiAdapter.js';\nexport { AgentStatus } from './adapters/AgentAdapter.js';\nexport type {\n AgentAdapter,\n AgentType,\n AgentInfo,\n ProcessInfo,\n ConversationMessage,\n SessionSummary,\n ListSessionsOptions,\n} from './adapters/AgentAdapter.js';\n\nexport { TerminalFocusManager, TerminalType } from './terminal/TerminalFocusManager.js';\nexport type { TerminalLocation } from './terminal/TerminalFocusManager.js';\nexport { TtyWriter } from './terminal/TtyWriter.js';\n\nexport { getProcessTty } from './utils/process.js';\nexport type { AgentSortKey } from './utils/sortAgents.js';\nexport type { ListAgentsOptions } from './AgentManager.js';\n\nexport { AgentRegistry, RenameNotFoundError, RenameConflictError } from './utils/AgentRegistry.js';\nexport type { RegistryEntry } from './utils/AgentRegistry.js';\nexport { TmuxManager } from './terminal/TmuxManager.js';\nexport { AGENTS } from './utils/agents.js';\nexport type { AgentConfig, StartableAgentType } from './utils/agents.js';\n\nexport type { AgentRequest } from './utils/agent-requests.js';\nexport { getAgentRequestPath, readLatestAgentRequest, writeAgentRequest } from './utils/agent-requests.js';\n\nexport {\n PrintAgentError,\n PrintAgentBusyError,\n PrintAgentNotFoundError,\n PrintAgentStoreError,\n PrintAgentNameConflictError,\n ClaudePrintError,\n} from './print/PrintAgent.js';\nexport type {\n PrintAgent,\n PrintAgentState,\n PrintSessionHealth,\n PrintRunStatus,\n PrintActiveRun,\n PrintLastResult,\n ProcessIdentity,\n} from './print/PrintAgent.js';\nexport { PrintAgentStore } from './print/PrintAgentStore.js';\nexport { LocalProcessInspector } from './print/PrintAgentStore.js';\nexport type {\n CreatePrintAgentInput,\n PrintAgentStoreOptions,\n ProcessInspector,\n PrintRunCompletion,\n} from './print/PrintAgentStore.js';\nexport { ClaudeCliProbe } from './print/ClaudeCliProbe.js';\nexport type { ClaudeCliProbeOptions } from './print/ClaudeCliProbe.js';\nexport { ClaudePrintRunner } from './print/ClaudePrintRunner.js';\nexport type {\n ClaudePrintRunnerOptions,\n ClaudePrintRunRequest,\n ClaudePrintRunResult,\n} from './print/ClaudePrintRunner.js';\nexport { ClaudePrintAgentService } from './print/ClaudePrintAgentService.js';\nexport type {\n ClaudePrintAgentServiceOptions,\n ClaudePrintSendResult,\n} from './print/ClaudePrintAgentService.js';\n"],"names":["AgentManager","ClaudeCodeAdapter","CodexAdapter","CopilotAdapter","GeminiCliAdapter","GrokCliAdapter","OpenCodeAdapter","PiAdapter","AgentStatus","TerminalFocusManager","TerminalType","TtyWriter","getProcessTty","AgentRegistry","RenameNotFoundError","RenameConflictError","TmuxManager","AGENTS","getAgentRequestPath","readLatestAgentRequest","writeAgentRequest","PrintAgentError","PrintAgentBusyError","PrintAgentNotFoundError","PrintAgentStoreError","PrintAgentNameConflictError","ClaudePrintError","PrintAgentStore","LocalProcessInspector","ClaudeCliProbe","ClaudePrintRunner","ClaudePrintAgentService"],"mappings":"AAAA,SAASA,YAAY,QAAQ,oBAAoB;AAEjD,SAASC,iBAAiB,QAAQ,kCAAkC;AACpE,SAASC,YAAY,QAAQ,6BAA6B;AAC1D,SAASC,cAAc,QAAQ,+BAA+B;AAC9D,SAASC,gBAAgB,QAAQ,iCAAiC;AAClE,SAASC,cAAc,QAAQ,+BAA+B;AAC9D,SAASC,eAAe,QAAQ,gCAAgC;AAChE,SAASC,SAAS,QAAQ,0BAA0B;AACpD,SAASC,WAAW,QAAQ,6BAA6B;AAWzD,SAASC,oBAAoB,EAAEC,YAAY,QAAQ,qCAAqC;AAExF,SAASC,SAAS,QAAQ,0BAA0B;AAEpD,SAASC,aAAa,QAAQ,qBAAqB;AAInD,SAASC,aAAa,EAAEC,mBAAmB,EAAEC,mBAAmB,QAAQ,2BAA2B;AAEnG,SAASC,WAAW,QAAQ,4BAA4B;AACxD,SAASC,MAAM,QAAQ,oBAAoB;AAI3C,SAASC,mBAAmB,EAAEC,sBAAsB,EAAEC,iBAAiB,QAAQ,4BAA4B;AAE3G,SACIC,eAAe,EACfC,mBAAmB,EACnBC,uBAAuB,EACvBC,oBAAoB,EACpBC,2BAA2B,EAC3BC,gBAAgB,QACb,wBAAwB;AAU/B,SAASC,eAAe,QAAQ,6BAA6B;AAC7D,SAASC,qBAAqB,QAAQ,6BAA6B;AAOnE,SAASC,cAAc,QAAQ,4BAA4B;AAE3D,SAASC,iBAAiB,QAAQ,+BAA+B;AAMjE,SAASC,uBAAuB,QAAQ,qCAAqC"}
1
+ {"version":3,"sources":["../src/index.ts"],"sourcesContent":["export { AgentManager } from './AgentManager.js';\n\nexport { ClaudeCodeAdapter } from './adapters/ClaudeCodeAdapter.js';\nexport { CodexAdapter } from './adapters/CodexAdapter.js';\nexport { CopilotAdapter } from './adapters/CopilotAdapter.js';\nexport { GeminiCliAdapter } from './adapters/GeminiCliAdapter.js';\nexport { GrokCliAdapter } from './adapters/GrokCliAdapter.js';\nexport { OpenCodeAdapter } from './adapters/OpenCodeAdapter.js';\nexport { PiAdapter } from './adapters/PiAdapter.js';\nexport { AgentStatus } from './adapters/AgentAdapter.js';\nexport type {\n AgentAdapter,\n AgentType,\n AgentInfo,\n ProcessInfo,\n ConversationMessage,\n SessionSummary,\n ListSessionsOptions,\n AgentDetectionContext,\n} from './adapters/AgentAdapter.js';\n\nexport { TerminalFocusManager, TerminalType } from './terminal/TerminalFocusManager.js';\nexport type { TerminalLocation } from './terminal/TerminalFocusManager.js';\nexport { TtyWriter } from './terminal/TtyWriter.js';\n\nexport { getProcessTty } from './utils/process.js';\nexport { captureProcessSnapshot, executableBasename, filterByProcessNames } from './utils/process.js';\nexport type { AgentSortKey } from './utils/sortAgents.js';\nexport type { ListAgentsOptions } from './AgentManager.js';\n\nexport { AgentRegistry, RenameNotFoundError, RenameConflictError } from './utils/AgentRegistry.js';\nexport type { AgentRegistryOptions, RegistryEntry } from './utils/AgentRegistry.js';\nexport { TmuxManager } from './terminal/TmuxManager.js';\nexport { AGENTS } from './utils/agents.js';\nexport type { AgentConfig, StartableAgentType } from './utils/agents.js';\n\nexport type { AgentRequest } from './utils/agent-requests.js';\nexport { getAgentRequestPath, readLatestAgentRequest, writeAgentRequest } from './utils/agent-requests.js';\n\nexport {\n PrintAgentError,\n PrintAgentBusyError,\n PrintAgentNotFoundError,\n PrintAgentStoreError,\n PrintAgentNameConflictError,\n ClaudePrintError,\n} from './print/PrintAgent.js';\nexport type {\n PrintAgent,\n PrintAgentState,\n PrintSessionHealth,\n PrintRunStatus,\n PrintActiveRun,\n PrintLastResult,\n ProcessIdentity,\n} from './print/PrintAgent.js';\nexport { PrintAgentStore } from './print/PrintAgentStore.js';\nexport { LocalProcessInspector } from './print/PrintAgentStore.js';\nexport type {\n CreatePrintAgentInput,\n PrintAgentStoreOptions,\n ProcessInspector,\n PrintRunCompletion,\n} from './print/PrintAgentStore.js';\nexport { ClaudeCliProbe } from './print/ClaudeCliProbe.js';\nexport type { ClaudeCliProbeOptions } from './print/ClaudeCliProbe.js';\nexport { ClaudePrintRunner } from './print/ClaudePrintRunner.js';\nexport type {\n ClaudePrintRunnerOptions,\n ClaudePrintRunRequest,\n ClaudePrintRunResult,\n} from './print/ClaudePrintRunner.js';\nexport { ClaudePrintAgentService } from './print/ClaudePrintAgentService.js';\nexport type {\n ClaudePrintAgentServiceOptions,\n ClaudePrintSendResult,\n} from './print/ClaudePrintAgentService.js';\n"],"names":["AgentManager","ClaudeCodeAdapter","CodexAdapter","CopilotAdapter","GeminiCliAdapter","GrokCliAdapter","OpenCodeAdapter","PiAdapter","AgentStatus","TerminalFocusManager","TerminalType","TtyWriter","getProcessTty","captureProcessSnapshot","executableBasename","filterByProcessNames","AgentRegistry","RenameNotFoundError","RenameConflictError","TmuxManager","AGENTS","getAgentRequestPath","readLatestAgentRequest","writeAgentRequest","PrintAgentError","PrintAgentBusyError","PrintAgentNotFoundError","PrintAgentStoreError","PrintAgentNameConflictError","ClaudePrintError","PrintAgentStore","LocalProcessInspector","ClaudeCliProbe","ClaudePrintRunner","ClaudePrintAgentService"],"mappings":"AAAA,SAASA,YAAY,QAAQ,oBAAoB;AAEjD,SAASC,iBAAiB,QAAQ,kCAAkC;AACpE,SAASC,YAAY,QAAQ,6BAA6B;AAC1D,SAASC,cAAc,QAAQ,+BAA+B;AAC9D,SAASC,gBAAgB,QAAQ,iCAAiC;AAClE,SAASC,cAAc,QAAQ,+BAA+B;AAC9D,SAASC,eAAe,QAAQ,gCAAgC;AAChE,SAASC,SAAS,QAAQ,0BAA0B;AACpD,SAASC,WAAW,QAAQ,6BAA6B;AAYzD,SAASC,oBAAoB,EAAEC,YAAY,QAAQ,qCAAqC;AAExF,SAASC,SAAS,QAAQ,0BAA0B;AAEpD,SAASC,aAAa,QAAQ,qBAAqB;AACnD,SAASC,sBAAsB,EAAEC,kBAAkB,EAAEC,oBAAoB,QAAQ,qBAAqB;AAItG,SAASC,aAAa,EAAEC,mBAAmB,EAAEC,mBAAmB,QAAQ,2BAA2B;AAEnG,SAASC,WAAW,QAAQ,4BAA4B;AACxD,SAASC,MAAM,QAAQ,oBAAoB;AAI3C,SAASC,mBAAmB,EAAEC,sBAAsB,EAAEC,iBAAiB,QAAQ,4BAA4B;AAE3G,SACIC,eAAe,EACfC,mBAAmB,EACnBC,uBAAuB,EACvBC,oBAAoB,EACpBC,2BAA2B,EAC3BC,gBAAgB,QACb,wBAAwB;AAU/B,SAASC,eAAe,QAAQ,6BAA6B;AAC7D,SAASC,qBAAqB,QAAQ,6BAA6B;AAOnE,SAASC,cAAc,QAAQ,4BAA4B;AAE3D,SAASC,iBAAiB,QAAQ,+BAA+B;AAMjE,SAASC,uBAAuB,QAAQ,qCAAqC"}
@@ -17,19 +17,32 @@ export interface RegistryEntry {
17
17
  sessionId: string;
18
18
  sessionFilePath: string;
19
19
  }
20
+ export interface AgentRegistryOptions {
21
+ now?: () => Date;
22
+ pruneIntervalMs?: number;
23
+ onDatabaseOperation?: (sql: string) => void;
24
+ }
20
25
  export declare class AgentRegistry {
21
26
  private db;
22
- constructor(filePath?: string);
27
+ private readonly now;
28
+ private readonly pruneIntervalMs;
29
+ private lastPrunedAt;
30
+ constructor(filePath?: string, options?: AgentRegistryOptions);
23
31
  static default(): AgentRegistry;
24
32
  private rowToEntry;
25
33
  private mergeEntry;
26
34
  private findByIdentity;
27
35
  private findByName;
36
+ private findPidConflicts;
37
+ private entriesEqual;
28
38
  private deleteNameConflict;
29
39
  private insertOrUpdate;
40
+ private needsWrite;
30
41
  private save;
31
42
  isAlive(entry: RegistryEntry): boolean;
43
+ private pruneAt;
32
44
  prune(): void;
45
+ pruneIfDue(): void;
33
46
  register(entry: RegistryEntry): void;
34
47
  registerBatch(entries: RegistryEntry[]): void;
35
48
  rename(currentName: string, newName: string): void;
@@ -1 +1 @@
1
- {"version":3,"file":"AgentRegistry.d.ts","sourceRoot":"","sources":["../../src/utils/AgentRegistry.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,6BAA6B,CAAC;AAM7D,qBAAa,mBAAoB,SAAQ,KAAK;IACvB,SAAS,EAAE,MAAM;gBAAjB,SAAS,EAAE,MAAM;CAIvC;AAED,qBAAa,mBAAoB,SAAQ,KAAK;IACvB,SAAS,EAAE,MAAM;gBAAjB,SAAS,EAAE,MAAM;CAIvC;AAED,MAAM,WAAW,aAAa;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,SAAS,CAAC;IAChB,GAAG,EAAE,MAAM,CAAC;IACZ,WAAW,EAAE,MAAM,CAAC;IACpB,GAAG,EAAE,MAAM,CAAC;IACZ,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,eAAe,EAAE,MAAM,CAAC;CAC3B;AAkBD,qBAAa,aAAa;IACtB,OAAO,CAAC,EAAE,CAAqB;gBAEnB,QAAQ,GAAE,MAA8B;IAIpD,MAAM,CAAC,OAAO,IAAI,aAAa;IAO/B,OAAO,CAAC,UAAU;IAalB,OAAO,CAAC,UAAU;IAclB,OAAO,CAAC,cAAc;IAQtB,OAAO,CAAC,UAAU;IAKlB,OAAO,CAAC,kBAAkB;IAS1B,OAAO,CAAC,cAAc;IAmBtB,OAAO,CAAC,IAAI;IAKZ,OAAO,CAAC,KAAK,EAAE,aAAa,GAAG,OAAO;IAStC,KAAK,IAAI,IAAI;IAUb,QAAQ,CAAC,KAAK,EAAE,aAAa,GAAG,IAAI;IAIpC,aAAa,CAAC,OAAO,EAAE,aAAa,EAAE,GAAG,IAAI;IAU7C,MAAM,CAAC,WAAW,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI;IAqBlD,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,aAAa,GAAG,IAAI;IAI1C,IAAI,IAAI,aAAa,EAAE;CAI1B"}
1
+ {"version":3,"file":"AgentRegistry.d.ts","sourceRoot":"","sources":["../../src/utils/AgentRegistry.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,6BAA6B,CAAC;AAM7D,qBAAa,mBAAoB,SAAQ,KAAK;IACvB,SAAS,EAAE,MAAM;gBAAjB,SAAS,EAAE,MAAM;CAIvC;AAED,qBAAa,mBAAoB,SAAQ,KAAK;IACvB,SAAS,EAAE,MAAM;gBAAjB,SAAS,EAAE,MAAM;CAIvC;AAED,MAAM,WAAW,aAAa;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,SAAS,CAAC;IAChB,GAAG,EAAE,MAAM,CAAC;IACZ,WAAW,EAAE,MAAM,CAAC;IACpB,GAAG,EAAE,MAAM,CAAC;IACZ,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,eAAe,EAAE,MAAM,CAAC;CAC3B;AAmBD,MAAM,WAAW,oBAAoB;IACjC,GAAG,CAAC,EAAE,MAAM,IAAI,CAAC;IACjB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,mBAAmB,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;CAC/C;AAED,qBAAa,aAAa;IACtB,OAAO,CAAC,EAAE,CAAqB;IAC/B,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAa;IACjC,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAS;IACzC,OAAO,CAAC,YAAY,CAAqB;gBAE7B,QAAQ,GAAE,MAA8B,EAAE,OAAO,GAAE,oBAAyB;IASxF,MAAM,CAAC,OAAO,IAAI,aAAa;IAO/B,OAAO,CAAC,UAAU;IAalB,OAAO,CAAC,UAAU;IAclB,OAAO,CAAC,cAAc;IAQtB,OAAO,CAAC,UAAU;IAKlB,OAAO,CAAC,gBAAgB;IAOxB,OAAO,CAAC,YAAY;IAWpB,OAAO,CAAC,kBAAkB;IAS1B,OAAO,CAAC,cAAc;IAmBtB,OAAO,CAAC,UAAU;IAQlB,OAAO,CAAC,IAAI;IAeZ,OAAO,CAAC,KAAK,EAAE,aAAa,GAAG,OAAO;IAYtC,OAAO,CAAC,OAAO;IAaf,KAAK,IAAI,IAAI;IAIb,UAAU,IAAI,IAAI;IAOlB,QAAQ,CAAC,KAAK,EAAE,aAAa,GAAG,IAAI;IAIpC,aAAa,CAAC,OAAO,EAAE,aAAa,EAAE,GAAG,IAAI;IAU7C,MAAM,CAAC,WAAW,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI;IAqBlD,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,aAAa,GAAG,IAAI;IAI1C,IAAI,IAAI,aAAa,EAAE;CAI1B"}
@@ -16,12 +16,19 @@ export class RenameConflictError extends Error {
16
16
  }
17
17
  }
18
18
  const DEFAULT_REGISTRY_PATH = path.join(os.homedir(), '.ai-devkit', 'agents.json');
19
+ const DEFAULT_PRUNE_INTERVAL_MS = 30_000;
19
20
  let defaultInstance = null;
20
21
  export class AgentRegistry {
21
22
  db;
22
- constructor(filePath = DEFAULT_REGISTRY_PATH){
23
+ now;
24
+ pruneIntervalMs;
25
+ lastPrunedAt;
26
+ constructor(filePath = DEFAULT_REGISTRY_PATH, options = {}){
27
+ this.now = options.now ?? (()=>new Date());
28
+ this.pruneIntervalMs = options.pruneIntervalMs ?? DEFAULT_PRUNE_INTERVAL_MS;
23
29
  this.db = new DatabaseConnection({
24
- dbPath: resolveAgentRegistryDbPath(filePath)
30
+ dbPath: resolveAgentRegistryDbPath(filePath),
31
+ verbose: options.onDatabaseOperation
25
32
  });
26
33
  }
27
34
  static default() {
@@ -68,6 +75,15 @@ export class AgentRegistry {
68
75
  ]);
69
76
  return row ? this.rowToEntry(row) : undefined;
70
77
  }
78
+ findPidConflicts(type, pid) {
79
+ return this.db.query('SELECT * FROM agents WHERE pid = ? AND type <> ?', [
80
+ pid,
81
+ type
82
+ ]).map((row)=>this.rowToEntry(row));
83
+ }
84
+ entriesEqual(left, right) {
85
+ return left.name === right.name && left.type === right.type && left.pid === right.pid && left.tmuxSession === right.tmuxSession && left.cwd === right.cwd && left.startedAt === right.startedAt && left.sessionId === right.sessionId && left.sessionFilePath === right.sessionFilePath;
86
+ }
71
87
  deleteNameConflict(name, type, pid) {
72
88
  const conflict = this.findByName(name);
73
89
  if (!conflict) return;
@@ -97,32 +113,61 @@ export class AgentRegistry {
97
113
  updated_at = excluded.updated_at
98
114
  `).run({
99
115
  ...entry,
100
- updatedAt: new Date().toISOString()
116
+ updatedAt: this.now().toISOString()
101
117
  });
102
118
  }
103
- save(entry) {
104
- this.deleteNameConflict(entry.name, entry.type, entry.pid);
105
- this.insertOrUpdate(entry);
119
+ needsWrite(incoming) {
120
+ const existing = this.findByIdentity(incoming.type, incoming.pid);
121
+ const merged = this.mergeEntry(incoming, existing);
122
+ return !existing || !this.entriesEqual(merged, existing) || this.findPidConflicts(incoming.type, incoming.pid).length > 0;
123
+ }
124
+ save(incoming) {
125
+ const existing = this.findByIdentity(incoming.type, incoming.pid);
126
+ const merged = this.mergeEntry(incoming, existing);
127
+ const pidConflicts = this.findPidConflicts(incoming.type, incoming.pid);
128
+ if (existing && this.entriesEqual(merged, existing) && pidConflicts.length === 0) return;
129
+ for (const conflict of pidConflicts){
130
+ this.db.execute('DELETE FROM agents WHERE type = ? AND pid = ?', [
131
+ conflict.type,
132
+ conflict.pid
133
+ ]);
134
+ }
135
+ if (existing && this.entriesEqual(merged, existing)) return;
136
+ this.deleteNameConflict(merged.name, merged.type, merged.pid);
137
+ this.insertOrUpdate(merged);
106
138
  }
107
139
  isAlive(entry) {
108
140
  try {
109
141
  process.kill(entry.pid, 0);
110
142
  return true;
111
- } catch {
112
- return false;
143
+ } catch (error) {
144
+ const code = error && typeof error === 'object' && 'code' in error ? error.code : undefined;
145
+ return code !== 'ESRCH';
113
146
  }
114
147
  }
115
- prune() {
148
+ pruneAt(nowMs) {
116
149
  const entries = this.list();
117
150
  const stale = entries.filter((e)=>!this.isAlive(e));
118
- this.db.transaction(()=>{
119
- for (const entry of stale){
120
- this.db.execute('DELETE FROM agents WHERE type = ? AND pid = ?', [
121
- entry.type,
122
- entry.pid
123
- ]);
124
- }
125
- });
151
+ if (stale.length > 0) {
152
+ this.db.transaction(()=>{
153
+ for (const entry of stale){
154
+ this.db.execute('DELETE FROM agents WHERE type = ? AND pid = ?', [
155
+ entry.type,
156
+ entry.pid
157
+ ]);
158
+ }
159
+ });
160
+ }
161
+ this.lastPrunedAt = nowMs;
162
+ }
163
+ prune() {
164
+ this.pruneAt(this.now().getTime());
165
+ }
166
+ pruneIfDue() {
167
+ const nowMs = this.now().getTime();
168
+ const elapsed = this.lastPrunedAt === undefined ? undefined : nowMs - this.lastPrunedAt;
169
+ if (elapsed !== undefined && elapsed >= 0 && elapsed < this.pruneIntervalMs) return;
170
+ this.pruneAt(nowMs);
126
171
  }
127
172
  register(entry) {
128
173
  this.registerBatch([
@@ -131,10 +176,10 @@ export class AgentRegistry {
131
176
  }
132
177
  registerBatch(entries) {
133
178
  if (entries.length === 0) return;
179
+ if (!entries.some((entry)=>this.needsWrite(entry))) return;
134
180
  this.db.transaction(()=>{
135
181
  for (const incoming of entries){
136
- const existing = this.findByIdentity(incoming.type, incoming.pid);
137
- this.save(this.mergeEntry(incoming, existing));
182
+ this.save(incoming);
138
183
  }
139
184
  });
140
185
  }
@@ -156,7 +201,7 @@ export class AgentRegistry {
156
201
  }
157
202
  this.db.execute('UPDATE agents SET name = ?, updated_at = ? WHERE type = ? AND pid = ?', [
158
203
  newName,
159
- new Date().toISOString(),
204
+ this.now().toISOString(),
160
205
  existing.type,
161
206
  existing.pid
162
207
  ]);
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/utils/AgentRegistry.ts"],"sourcesContent":["import os from 'os';\nimport path from 'path';\nimport type { AgentType } from '../adapters/AgentAdapter.js';\nimport {\n DatabaseConnection,\n resolveAgentRegistryDbPath,\n} from '../database/index.js';\n\nexport class RenameNotFoundError extends Error {\n constructor(public agentName: string) {\n super(`Agent \"${agentName}\" not found in registry.`);\n this.name = 'RenameNotFoundError';\n }\n}\n\nexport class RenameConflictError extends Error {\n constructor(public agentName: string) {\n super(`Agent \"${agentName}\" is already in use.`);\n this.name = 'RenameConflictError';\n }\n}\n\nexport interface RegistryEntry {\n name: string;\n type: AgentType;\n pid: number;\n tmuxSession: string;\n cwd: string;\n startedAt: string; // ISO 8601\n sessionId: string;\n sessionFilePath: string;\n}\n\ninterface RegistryRow {\n name: string;\n type: AgentType;\n pid: number;\n tmux_session: string;\n cwd: string;\n started_at: string;\n session_id: string;\n session_file_path: string;\n updated_at: string;\n}\n\nconst DEFAULT_REGISTRY_PATH = path.join(os.homedir(), '.ai-devkit', 'agents.json');\n\nlet defaultInstance: AgentRegistry | null = null;\n\nexport class AgentRegistry {\n private db: DatabaseConnection;\n\n constructor(filePath: string = DEFAULT_REGISTRY_PATH) {\n this.db = new DatabaseConnection({ dbPath: resolveAgentRegistryDbPath(filePath) });\n }\n\n static default(): AgentRegistry {\n if (!defaultInstance) {\n defaultInstance = new AgentRegistry();\n }\n return defaultInstance;\n }\n\n private rowToEntry(row: RegistryRow): RegistryEntry {\n return {\n name: row.name,\n type: row.type,\n pid: row.pid,\n tmuxSession: row.tmux_session,\n cwd: row.cwd,\n startedAt: row.started_at,\n sessionId: row.session_id,\n sessionFilePath: row.session_file_path,\n };\n }\n\n private mergeEntry(incoming: RegistryEntry, existing: RegistryEntry | undefined): RegistryEntry {\n if (!existing) return incoming;\n const incomingIsManaged = Boolean(incoming.tmuxSession);\n return {\n ...existing,\n name: incomingIsManaged ? incoming.name : existing.name,\n tmuxSession: incoming.tmuxSession || existing.tmuxSession,\n cwd: incoming.cwd || existing.cwd,\n startedAt: existing.startedAt || incoming.startedAt,\n sessionId: incoming.sessionId || existing.sessionId,\n sessionFilePath: incoming.sessionFilePath || existing.sessionFilePath,\n };\n }\n\n private findByIdentity(type: AgentType, pid: number): RegistryEntry | undefined {\n const row = this.db.queryOne<RegistryRow>(\n 'SELECT * FROM agents WHERE type = ? AND pid = ?',\n [type, pid],\n );\n return row ? this.rowToEntry(row) : undefined;\n }\n\n private findByName(name: string): RegistryEntry | undefined {\n const row = this.db.queryOne<RegistryRow>('SELECT * FROM agents WHERE name = ?', [name]);\n return row ? this.rowToEntry(row) : undefined;\n }\n\n private deleteNameConflict(name: string, type: AgentType, pid: number): void {\n const conflict = this.findByName(name);\n if (!conflict) return;\n if (conflict.type === type && conflict.pid === pid) return;\n if (!this.isAlive(conflict)) {\n this.db.execute('DELETE FROM agents WHERE type = ? AND pid = ?', [conflict.type, conflict.pid]);\n }\n }\n\n private insertOrUpdate(entry: RegistryEntry): void {\n this.db.instance.prepare(`\n INSERT INTO agents (\n type, pid, name, tmux_session, cwd, started_at, session_id, session_file_path, updated_at\n )\n VALUES (\n @type, @pid, @name, @tmuxSession, @cwd, @startedAt, @sessionId, @sessionFilePath, @updatedAt\n )\n ON CONFLICT(type, pid) DO UPDATE SET\n name = excluded.name,\n tmux_session = excluded.tmux_session,\n cwd = excluded.cwd,\n started_at = agents.started_at,\n session_id = excluded.session_id,\n session_file_path = excluded.session_file_path,\n updated_at = excluded.updated_at\n `).run({ ...entry, updatedAt: new Date().toISOString() });\n }\n\n private save(entry: RegistryEntry): void {\n this.deleteNameConflict(entry.name, entry.type, entry.pid);\n this.insertOrUpdate(entry);\n }\n\n isAlive(entry: RegistryEntry): boolean {\n try {\n process.kill(entry.pid, 0);\n return true;\n } catch {\n return false;\n }\n }\n\n prune(): void {\n const entries = this.list();\n const stale = entries.filter((e) => !this.isAlive(e));\n this.db.transaction(() => {\n for (const entry of stale) {\n this.db.execute('DELETE FROM agents WHERE type = ? AND pid = ?', [entry.type, entry.pid]);\n }\n });\n }\n\n register(entry: RegistryEntry): void {\n this.registerBatch([entry]);\n }\n\n registerBatch(entries: RegistryEntry[]): void {\n if (entries.length === 0) return;\n this.db.transaction(() => {\n for (const incoming of entries) {\n const existing = this.findByIdentity(incoming.type, incoming.pid);\n this.save(this.mergeEntry(incoming, existing));\n }\n });\n }\n\n rename(currentName: string, newName: string): void {\n const existing = this.findByName(currentName);\n if (!existing) {\n throw new RenameNotFoundError(currentName);\n }\n const conflict = this.findByName(newName);\n if (conflict && this.isAlive(conflict)) {\n throw new RenameConflictError(newName);\n }\n\n this.db.transaction(() => {\n if (conflict) {\n this.db.execute('DELETE FROM agents WHERE type = ? AND pid = ?', [conflict.type, conflict.pid]);\n }\n this.db.execute(\n 'UPDATE agents SET name = ?, updated_at = ? WHERE type = ? AND pid = ?',\n [newName, new Date().toISOString(), existing.type, existing.pid],\n );\n });\n }\n\n lookup(name: string): RegistryEntry | null {\n return this.findByName(name) ?? null;\n }\n\n list(): RegistryEntry[] {\n const rows = this.db.query<RegistryRow>('SELECT * FROM agents ORDER BY started_at ASC, name ASC');\n return rows.map((row) => this.rowToEntry(row));\n }\n}\n"],"names":["os","path","DatabaseConnection","resolveAgentRegistryDbPath","RenameNotFoundError","Error","agentName","name","RenameConflictError","DEFAULT_REGISTRY_PATH","join","homedir","defaultInstance","AgentRegistry","db","filePath","dbPath","default","rowToEntry","row","type","pid","tmuxSession","tmux_session","cwd","startedAt","started_at","sessionId","session_id","sessionFilePath","session_file_path","mergeEntry","incoming","existing","incomingIsManaged","Boolean","findByIdentity","queryOne","undefined","findByName","deleteNameConflict","conflict","isAlive","execute","insertOrUpdate","entry","instance","prepare","run","updatedAt","Date","toISOString","save","process","kill","prune","entries","list","stale","filter","e","transaction","register","registerBatch","length","rename","currentName","newName","lookup","rows","query","map"],"mappings":"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"}
1
+ {"version":3,"sources":["../../src/utils/AgentRegistry.ts"],"sourcesContent":["import os from 'os';\nimport path from 'path';\nimport type { AgentType } from '../adapters/AgentAdapter.js';\nimport {\n DatabaseConnection,\n resolveAgentRegistryDbPath,\n} from '../database/index.js';\n\nexport class RenameNotFoundError extends Error {\n constructor(public agentName: string) {\n super(`Agent \"${agentName}\" not found in registry.`);\n this.name = 'RenameNotFoundError';\n }\n}\n\nexport class RenameConflictError extends Error {\n constructor(public agentName: string) {\n super(`Agent \"${agentName}\" is already in use.`);\n this.name = 'RenameConflictError';\n }\n}\n\nexport interface RegistryEntry {\n name: string;\n type: AgentType;\n pid: number;\n tmuxSession: string;\n cwd: string;\n startedAt: string; // ISO 8601\n sessionId: string;\n sessionFilePath: string;\n}\n\ninterface RegistryRow {\n name: string;\n type: AgentType;\n pid: number;\n tmux_session: string;\n cwd: string;\n started_at: string;\n session_id: string;\n session_file_path: string;\n updated_at: string;\n}\n\nconst DEFAULT_REGISTRY_PATH = path.join(os.homedir(), '.ai-devkit', 'agents.json');\nconst DEFAULT_PRUNE_INTERVAL_MS = 30_000;\n\nlet defaultInstance: AgentRegistry | null = null;\n\nexport interface AgentRegistryOptions {\n now?: () => Date;\n pruneIntervalMs?: number;\n onDatabaseOperation?: (sql: string) => void;\n}\n\nexport class AgentRegistry {\n private db: DatabaseConnection;\n private readonly now: () => Date;\n private readonly pruneIntervalMs: number;\n private lastPrunedAt: number | undefined;\n\n constructor(filePath: string = DEFAULT_REGISTRY_PATH, options: AgentRegistryOptions = {}) {\n this.now = options.now ?? (() => new Date());\n this.pruneIntervalMs = options.pruneIntervalMs ?? DEFAULT_PRUNE_INTERVAL_MS;\n this.db = new DatabaseConnection({\n dbPath: resolveAgentRegistryDbPath(filePath),\n verbose: options.onDatabaseOperation,\n });\n }\n\n static default(): AgentRegistry {\n if (!defaultInstance) {\n defaultInstance = new AgentRegistry();\n }\n return defaultInstance;\n }\n\n private rowToEntry(row: RegistryRow): RegistryEntry {\n return {\n name: row.name,\n type: row.type,\n pid: row.pid,\n tmuxSession: row.tmux_session,\n cwd: row.cwd,\n startedAt: row.started_at,\n sessionId: row.session_id,\n sessionFilePath: row.session_file_path,\n };\n }\n\n private mergeEntry(incoming: RegistryEntry, existing: RegistryEntry | undefined): RegistryEntry {\n if (!existing) return incoming;\n const incomingIsManaged = Boolean(incoming.tmuxSession);\n return {\n ...existing,\n name: incomingIsManaged ? incoming.name : existing.name,\n tmuxSession: incoming.tmuxSession || existing.tmuxSession,\n cwd: incoming.cwd || existing.cwd,\n startedAt: existing.startedAt || incoming.startedAt,\n sessionId: incoming.sessionId || existing.sessionId,\n sessionFilePath: incoming.sessionFilePath || existing.sessionFilePath,\n };\n }\n\n private findByIdentity(type: AgentType, pid: number): RegistryEntry | undefined {\n const row = this.db.queryOne<RegistryRow>(\n 'SELECT * FROM agents WHERE type = ? AND pid = ?',\n [type, pid],\n );\n return row ? this.rowToEntry(row) : undefined;\n }\n\n private findByName(name: string): RegistryEntry | undefined {\n const row = this.db.queryOne<RegistryRow>('SELECT * FROM agents WHERE name = ?', [name]);\n return row ? this.rowToEntry(row) : undefined;\n }\n\n private findPidConflicts(type: AgentType, pid: number): RegistryEntry[] {\n return this.db.query<RegistryRow>(\n 'SELECT * FROM agents WHERE pid = ? AND type <> ?',\n [pid, type],\n ).map((row) => this.rowToEntry(row));\n }\n\n private entriesEqual(left: RegistryEntry, right: RegistryEntry): boolean {\n return left.name === right.name\n && left.type === right.type\n && left.pid === right.pid\n && left.tmuxSession === right.tmuxSession\n && left.cwd === right.cwd\n && left.startedAt === right.startedAt\n && left.sessionId === right.sessionId\n && left.sessionFilePath === right.sessionFilePath;\n }\n\n private deleteNameConflict(name: string, type: AgentType, pid: number): void {\n const conflict = this.findByName(name);\n if (!conflict) return;\n if (conflict.type === type && conflict.pid === pid) return;\n if (!this.isAlive(conflict)) {\n this.db.execute('DELETE FROM agents WHERE type = ? AND pid = ?', [conflict.type, conflict.pid]);\n }\n }\n\n private insertOrUpdate(entry: RegistryEntry): void {\n this.db.instance.prepare(`\n INSERT INTO agents (\n type, pid, name, tmux_session, cwd, started_at, session_id, session_file_path, updated_at\n )\n VALUES (\n @type, @pid, @name, @tmuxSession, @cwd, @startedAt, @sessionId, @sessionFilePath, @updatedAt\n )\n ON CONFLICT(type, pid) DO UPDATE SET\n name = excluded.name,\n tmux_session = excluded.tmux_session,\n cwd = excluded.cwd,\n started_at = agents.started_at,\n session_id = excluded.session_id,\n session_file_path = excluded.session_file_path,\n updated_at = excluded.updated_at\n `).run({ ...entry, updatedAt: this.now().toISOString() });\n }\n\n private needsWrite(incoming: RegistryEntry): boolean {\n const existing = this.findByIdentity(incoming.type, incoming.pid);\n const merged = this.mergeEntry(incoming, existing);\n return !existing\n || !this.entriesEqual(merged, existing)\n || this.findPidConflicts(incoming.type, incoming.pid).length > 0;\n }\n\n private save(incoming: RegistryEntry): void {\n const existing = this.findByIdentity(incoming.type, incoming.pid);\n const merged = this.mergeEntry(incoming, existing);\n const pidConflicts = this.findPidConflicts(incoming.type, incoming.pid);\n if (existing && this.entriesEqual(merged, existing) && pidConflicts.length === 0) return;\n\n for (const conflict of pidConflicts) {\n this.db.execute('DELETE FROM agents WHERE type = ? AND pid = ?', [conflict.type, conflict.pid]);\n }\n if (existing && this.entriesEqual(merged, existing)) return;\n\n this.deleteNameConflict(merged.name, merged.type, merged.pid);\n this.insertOrUpdate(merged);\n }\n\n isAlive(entry: RegistryEntry): boolean {\n try {\n process.kill(entry.pid, 0);\n return true;\n } catch (error) {\n const code = error && typeof error === 'object' && 'code' in error\n ? error.code\n : undefined;\n return code !== 'ESRCH';\n }\n }\n\n private pruneAt(nowMs: number): void {\n const entries = this.list();\n const stale = entries.filter((e) => !this.isAlive(e));\n if (stale.length > 0) {\n this.db.transaction(() => {\n for (const entry of stale) {\n this.db.execute('DELETE FROM agents WHERE type = ? AND pid = ?', [entry.type, entry.pid]);\n }\n });\n }\n this.lastPrunedAt = nowMs;\n }\n\n prune(): void {\n this.pruneAt(this.now().getTime());\n }\n\n pruneIfDue(): void {\n const nowMs = this.now().getTime();\n const elapsed = this.lastPrunedAt === undefined ? undefined : nowMs - this.lastPrunedAt;\n if (elapsed !== undefined && elapsed >= 0 && elapsed < this.pruneIntervalMs) return;\n this.pruneAt(nowMs);\n }\n\n register(entry: RegistryEntry): void {\n this.registerBatch([entry]);\n }\n\n registerBatch(entries: RegistryEntry[]): void {\n if (entries.length === 0) return;\n if (!entries.some((entry) => this.needsWrite(entry))) return;\n this.db.transaction(() => {\n for (const incoming of entries) {\n this.save(incoming);\n }\n });\n }\n\n rename(currentName: string, newName: string): void {\n const existing = this.findByName(currentName);\n if (!existing) {\n throw new RenameNotFoundError(currentName);\n }\n const conflict = this.findByName(newName);\n if (conflict && this.isAlive(conflict)) {\n throw new RenameConflictError(newName);\n }\n\n this.db.transaction(() => {\n if (conflict) {\n this.db.execute('DELETE FROM agents WHERE type = ? AND pid = ?', [conflict.type, conflict.pid]);\n }\n this.db.execute(\n 'UPDATE agents SET name = ?, updated_at = ? WHERE type = ? AND pid = ?',\n [newName, this.now().toISOString(), existing.type, existing.pid],\n );\n });\n }\n\n lookup(name: string): RegistryEntry | null {\n return this.findByName(name) ?? null;\n }\n\n list(): RegistryEntry[] {\n const rows = this.db.query<RegistryRow>('SELECT * FROM agents ORDER BY started_at ASC, name ASC');\n return rows.map((row) => this.rowToEntry(row));\n }\n}\n"],"names":["os","path","DatabaseConnection","resolveAgentRegistryDbPath","RenameNotFoundError","Error","agentName","name","RenameConflictError","DEFAULT_REGISTRY_PATH","join","homedir","DEFAULT_PRUNE_INTERVAL_MS","defaultInstance","AgentRegistry","db","now","pruneIntervalMs","lastPrunedAt","filePath","options","Date","dbPath","verbose","onDatabaseOperation","default","rowToEntry","row","type","pid","tmuxSession","tmux_session","cwd","startedAt","started_at","sessionId","session_id","sessionFilePath","session_file_path","mergeEntry","incoming","existing","incomingIsManaged","Boolean","findByIdentity","queryOne","undefined","findByName","findPidConflicts","query","map","entriesEqual","left","right","deleteNameConflict","conflict","isAlive","execute","insertOrUpdate","entry","instance","prepare","run","updatedAt","toISOString","needsWrite","merged","length","save","pidConflicts","process","kill","error","code","pruneAt","nowMs","entries","list","stale","filter","e","transaction","prune","getTime","pruneIfDue","elapsed","register","registerBatch","some","rename","currentName","newName","lookup","rows"],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- export { listAgentProcesses, batchGetProcessCwds, batchGetProcessStartTimes, enrichProcesses } from './process.js';
1
+ export { listAgentProcesses, batchGetProcessCwds, batchGetProcessStartTimes, enrichProcesses, captureProcessSnapshot } from './process.js';
2
2
  export { getProcessTty } from './process.js';
3
3
  export { batchGetSessionFileBirthtimes } from './session.js';
4
4
  export type { SessionFile } from './session.js';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,yBAAyB,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AACnH,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAC7C,OAAO,EAAE,6BAA6B,EAAE,MAAM,cAAc,CAAC;AAC7D,YAAY,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAChD,OAAO,EAAE,wBAAwB,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAC5E,YAAY,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,yBAAyB,EAAE,eAAe,EAAE,sBAAsB,EAAE,MAAM,cAAc,CAAC;AAC3I,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAC7C,OAAO,EAAE,6BAA6B,EAAE,MAAM,cAAc,CAAC;AAC7D,YAAY,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAChD,OAAO,EAAE,wBAAwB,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAC5E,YAAY,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC"}
@@ -1,4 +1,4 @@
1
- export { listAgentProcesses, batchGetProcessCwds, batchGetProcessStartTimes, enrichProcesses } from './process.js';
1
+ export { listAgentProcesses, batchGetProcessCwds, batchGetProcessStartTimes, enrichProcesses, captureProcessSnapshot } from './process.js';
2
2
  export { getProcessTty } from './process.js';
3
3
  export { batchGetSessionFileBirthtimes } from './session.js';
4
4
  export { matchProcessesToSessions, generateAgentName } from './matching.js';
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/utils/index.ts"],"sourcesContent":["export { listAgentProcesses, batchGetProcessCwds, batchGetProcessStartTimes, enrichProcesses } from './process.js';\nexport { getProcessTty } from './process.js';\nexport { batchGetSessionFileBirthtimes } from './session.js';\nexport type { SessionFile } from './session.js';\nexport { matchProcessesToSessions, generateAgentName } from './matching.js';\nexport type { MatchResult } from './matching.js';\n"],"names":["listAgentProcesses","batchGetProcessCwds","batchGetProcessStartTimes","enrichProcesses","getProcessTty","batchGetSessionFileBirthtimes","matchProcessesToSessions","generateAgentName"],"mappings":"AAAA,SAASA,kBAAkB,EAAEC,mBAAmB,EAAEC,yBAAyB,EAAEC,eAAe,QAAQ,eAAe;AACnH,SAASC,aAAa,QAAQ,eAAe;AAC7C,SAASC,6BAA6B,QAAQ,eAAe;AAE7D,SAASC,wBAAwB,EAAEC,iBAAiB,QAAQ,gBAAgB"}
1
+ {"version":3,"sources":["../../src/utils/index.ts"],"sourcesContent":["export { listAgentProcesses, batchGetProcessCwds, batchGetProcessStartTimes, enrichProcesses, captureProcessSnapshot } from './process.js';\nexport { getProcessTty } from './process.js';\nexport { batchGetSessionFileBirthtimes } from './session.js';\nexport type { SessionFile } from './session.js';\nexport { matchProcessesToSessions, generateAgentName } from './matching.js';\nexport type { MatchResult } from './matching.js';\n"],"names":["listAgentProcesses","batchGetProcessCwds","batchGetProcessStartTimes","enrichProcesses","captureProcessSnapshot","getProcessTty","batchGetSessionFileBirthtimes","matchProcessesToSessions","generateAgentName"],"mappings":"AAAA,SAASA,kBAAkB,EAAEC,mBAAmB,EAAEC,yBAAyB,EAAEC,eAAe,EAAEC,sBAAsB,QAAQ,eAAe;AAC3I,SAASC,aAAa,QAAQ,eAAe;AAC7C,SAASC,6BAA6B,QAAQ,eAAe;AAE7D,SAASC,wBAAwB,EAAEC,iBAAiB,QAAQ,gBAAgB"}
@@ -2,9 +2,12 @@
2
2
  * Process Detection Utilities
3
3
  *
4
4
  * Shared shell command wrappers for detecting and inspecting running processes.
5
- * All execFileSync calls for process data live here — adapters must not call execFileSync directly.
5
+ * Built-in refresh discovery uses captureProcessSnapshot(); synchronous helpers
6
+ * remain exported for compatibility with existing consumers.
6
7
  */
7
8
  import type { ProcessInfo } from '../adapters/AgentAdapter.js';
9
+ export declare function executableBasename(command: string): string;
10
+ export declare function filterByProcessNames(processes: readonly ProcessInfo[], namePatterns: readonly string[]): ProcessInfo[];
8
11
  /**
9
12
  * List running processes matching an agent executable name.
10
13
  *
@@ -15,6 +18,11 @@ import type { ProcessInfo } from '../adapters/AgentAdapter.js';
15
18
  * cwd and startTime are NOT populated — call enrichProcesses() to fill them.
16
19
  */
17
20
  export declare function listAgentProcesses(namePattern: string): ProcessInfo[];
21
+ /**
22
+ * Capture and enrich relevant processes without blocking the event loop.
23
+ * One base process listing is shared by every requested executable name.
24
+ */
25
+ export declare function captureProcessSnapshot(namePatterns: readonly string[]): Promise<ProcessInfo[]>;
18
26
  /**
19
27
  * Batch-get current working directories for multiple PIDs.
20
28
  *
@@ -1 +1 @@
1
- {"version":3,"file":"process.d.ts","sourceRoot":"","sources":["../../src/utils/process.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,6BAA6B,CAAC;AAE/D;;;;;;;;GAQG;AACH,wBAAgB,kBAAkB,CAAC,WAAW,EAAE,MAAM,GAAG,WAAW,EAAE,CA+CrE;AAED;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAuCvE;AAED;;;;;;GAMG;AACH,wBAAgB,yBAAyB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,GAAG,CAAC,MAAM,EAAE,IAAI,CAAC,CAkC3E;AAED;;;;;;GAMG;AACH,wBAAgB,eAAe,CAAC,SAAS,EAAE,WAAW,EAAE,GAAG,WAAW,EAAE,CAavE;AAaD,wBAAgB,kBAAkB,CAC9B,SAAS,EAAE,WAAW,EAAE,EACxB,KAAK,EAAE,WAAW,GACnB,WAAW,GAAG,SAAS,CAMzB;AAED;;;;;;GAMG;AACH,wBAAgB,sBAAsB,CAClC,SAAS,EAAE,WAAW,EAAE,EACxB,gBAAgB,GAAE,WAAW,EAAO,GACrC,GAAG,CAAC,MAAM,CAAC,CAmBb;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAYjD"}
1
+ {"version":3,"file":"process.d.ts","sourceRoot":"","sources":["../../src/utils/process.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAIH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,6BAA6B,CAAC;AAK/D,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAG1D;AAWD,wBAAgB,oBAAoB,CAChC,SAAS,EAAE,SAAS,WAAW,EAAE,EACjC,YAAY,EAAE,SAAS,MAAM,EAAE,GAChC,WAAW,EAAE,CAMf;AAED;;;;;;;;GAQG;AACH,wBAAgB,kBAAkB,CAAC,WAAW,EAAE,MAAM,GAAG,WAAW,EAAE,CA0CrE;AAoGD;;;GAGG;AACH,wBAAsB,sBAAsB,CAAC,YAAY,EAAE,SAAS,MAAM,EAAE,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC,CAsBpG;AAED;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAuCvE;AAED;;;;;;GAMG;AACH,wBAAgB,yBAAyB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,GAAG,CAAC,MAAM,EAAE,IAAI,CAAC,CAkC3E;AAED;;;;;;GAMG;AACH,wBAAgB,eAAe,CAAC,SAAS,EAAE,WAAW,EAAE,GAAG,WAAW,EAAE,CAavE;AAaD,wBAAgB,kBAAkB,CAC9B,SAAS,EAAE,WAAW,EAAE,EACxB,KAAK,EAAE,WAAW,GACnB,WAAW,GAAG,SAAS,CAMzB;AAED;;;;;;GAMG;AACH,wBAAgB,sBAAsB,CAClC,SAAS,EAAE,WAAW,EAAE,EACxB,gBAAgB,GAAE,WAAW,EAAO,GACrC,GAAG,CAAC,MAAM,CAAC,CAmBb;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAYjD"}