@specforge/mcp 2.6.0 → 3.0.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 (237) hide show
  1. package/README.md +73 -0
  2. package/bin/{specforge-mcp → specforge} +0 -5
  3. package/dist/ai-provider/circuit-breaker.d.ts +63 -0
  4. package/dist/ai-provider/circuit-breaker.d.ts.map +1 -0
  5. package/dist/ai-provider/circuit-breaker.js +160 -0
  6. package/dist/ai-provider/circuit-breaker.js.map +1 -0
  7. package/dist/ai-provider/cli-version.d.ts +50 -0
  8. package/dist/ai-provider/cli-version.d.ts.map +1 -0
  9. package/dist/ai-provider/cli-version.js +141 -0
  10. package/dist/ai-provider/cli-version.js.map +1 -0
  11. package/dist/ai-provider/config-loader.d.ts +45 -0
  12. package/dist/ai-provider/config-loader.d.ts.map +1 -0
  13. package/dist/ai-provider/config-loader.js +106 -0
  14. package/dist/ai-provider/config-loader.js.map +1 -0
  15. package/dist/ai-provider/errors.d.ts +48 -0
  16. package/dist/ai-provider/errors.d.ts.map +1 -0
  17. package/dist/ai-provider/errors.js +102 -0
  18. package/dist/ai-provider/errors.js.map +1 -0
  19. package/dist/ai-provider/events.d.ts +73 -0
  20. package/dist/ai-provider/events.d.ts.map +1 -0
  21. package/dist/ai-provider/events.js +75 -0
  22. package/dist/ai-provider/events.js.map +1 -0
  23. package/dist/ai-provider/factory.d.ts +31 -0
  24. package/dist/ai-provider/factory.d.ts.map +1 -0
  25. package/dist/ai-provider/factory.js +100 -0
  26. package/dist/ai-provider/factory.js.map +1 -0
  27. package/dist/ai-provider/index.d.ts +24 -0
  28. package/dist/ai-provider/index.d.ts.map +1 -0
  29. package/dist/ai-provider/index.js +46 -0
  30. package/dist/ai-provider/index.js.map +1 -0
  31. package/dist/ai-provider/instance-coordinator.d.ts +54 -0
  32. package/dist/ai-provider/instance-coordinator.d.ts.map +1 -0
  33. package/dist/ai-provider/instance-coordinator.js +199 -0
  34. package/dist/ai-provider/instance-coordinator.js.map +1 -0
  35. package/dist/ai-provider/jsonl-parser.d.ts +43 -0
  36. package/dist/ai-provider/jsonl-parser.d.ts.map +1 -0
  37. package/dist/ai-provider/jsonl-parser.js +107 -0
  38. package/dist/ai-provider/jsonl-parser.js.map +1 -0
  39. package/dist/ai-provider/lifecycle.d.ts +50 -0
  40. package/dist/ai-provider/lifecycle.d.ts.map +1 -0
  41. package/dist/ai-provider/lifecycle.js +145 -0
  42. package/dist/ai-provider/lifecycle.js.map +1 -0
  43. package/dist/ai-provider/logger.d.ts +69 -0
  44. package/dist/ai-provider/logger.d.ts.map +1 -0
  45. package/dist/ai-provider/logger.js +161 -0
  46. package/dist/ai-provider/logger.js.map +1 -0
  47. package/dist/ai-provider/metrics.d.ts +91 -0
  48. package/dist/ai-provider/metrics.d.ts.map +1 -0
  49. package/dist/ai-provider/metrics.js +187 -0
  50. package/dist/ai-provider/metrics.js.map +1 -0
  51. package/dist/ai-provider/process-manager.d.ts +97 -0
  52. package/dist/ai-provider/process-manager.d.ts.map +1 -0
  53. package/dist/ai-provider/process-manager.js +477 -0
  54. package/dist/ai-provider/process-manager.js.map +1 -0
  55. package/dist/ai-provider/providers/claude-code.d.ts +64 -0
  56. package/dist/ai-provider/providers/claude-code.d.ts.map +1 -0
  57. package/dist/ai-provider/providers/claude-code.js +205 -0
  58. package/dist/ai-provider/providers/claude-code.js.map +1 -0
  59. package/dist/ai-provider/retry-executor.d.ts +52 -0
  60. package/dist/ai-provider/retry-executor.d.ts.map +1 -0
  61. package/dist/ai-provider/retry-executor.js +138 -0
  62. package/dist/ai-provider/retry-executor.js.map +1 -0
  63. package/dist/ai-provider/safe-args.d.ts +58 -0
  64. package/dist/ai-provider/safe-args.d.ts.map +1 -0
  65. package/dist/ai-provider/safe-args.js +176 -0
  66. package/dist/ai-provider/safe-args.js.map +1 -0
  67. package/dist/ai-provider/semaphore.d.ts +50 -0
  68. package/dist/ai-provider/semaphore.d.ts.map +1 -0
  69. package/dist/ai-provider/semaphore.js +97 -0
  70. package/dist/ai-provider/semaphore.js.map +1 -0
  71. package/dist/ai-provider/tracer.d.ts +67 -0
  72. package/dist/ai-provider/tracer.d.ts.map +1 -0
  73. package/dist/ai-provider/tracer.js +209 -0
  74. package/dist/ai-provider/tracer.js.map +1 -0
  75. package/dist/ai-provider/types.d.ts +181 -0
  76. package/dist/ai-provider/types.d.ts.map +1 -0
  77. package/dist/ai-provider/types.js +8 -0
  78. package/dist/ai-provider/types.js.map +1 -0
  79. package/dist/autopilot/agents/agent-runner.d.ts +109 -0
  80. package/dist/autopilot/agents/agent-runner.d.ts.map +1 -0
  81. package/dist/autopilot/agents/agent-runner.js +731 -0
  82. package/dist/autopilot/agents/agent-runner.js.map +1 -0
  83. package/dist/autopilot/agents/agent-selector.d.ts +59 -0
  84. package/dist/autopilot/agents/agent-selector.d.ts.map +1 -0
  85. package/dist/autopilot/agents/agent-selector.js +234 -0
  86. package/dist/autopilot/agents/agent-selector.js.map +1 -0
  87. package/dist/autopilot/agents/model-selector.d.ts +49 -0
  88. package/dist/autopilot/agents/model-selector.d.ts.map +1 -0
  89. package/dist/autopilot/agents/model-selector.js +62 -0
  90. package/dist/autopilot/agents/model-selector.js.map +1 -0
  91. package/dist/autopilot/agents/profiles/builtin.d.ts +55 -0
  92. package/dist/autopilot/agents/profiles/builtin.d.ts.map +1 -0
  93. package/dist/autopilot/agents/profiles/builtin.js +323 -0
  94. package/dist/autopilot/agents/profiles/builtin.js.map +1 -0
  95. package/dist/autopilot/agents/profiles/types.d.ts +98 -0
  96. package/dist/autopilot/agents/profiles/types.d.ts.map +1 -0
  97. package/dist/autopilot/agents/profiles/types.js +17 -0
  98. package/dist/autopilot/agents/profiles/types.js.map +1 -0
  99. package/dist/autopilot/api/autopilot-api-client.d.ts +217 -0
  100. package/dist/autopilot/api/autopilot-api-client.d.ts.map +1 -0
  101. package/dist/autopilot/api/autopilot-api-client.js +402 -0
  102. package/dist/autopilot/api/autopilot-api-client.js.map +1 -0
  103. package/dist/autopilot/cli/abort.d.ts +20 -0
  104. package/dist/autopilot/cli/abort.d.ts.map +1 -0
  105. package/dist/autopilot/cli/abort.js +201 -0
  106. package/dist/autopilot/cli/abort.js.map +1 -0
  107. package/dist/autopilot/cli/display.d.ts +63 -0
  108. package/dist/autopilot/cli/display.d.ts.map +1 -0
  109. package/dist/autopilot/cli/display.js +260 -0
  110. package/dist/autopilot/cli/display.js.map +1 -0
  111. package/dist/autopilot/cli/index.d.ts +24 -0
  112. package/dist/autopilot/cli/index.d.ts.map +1 -0
  113. package/dist/autopilot/cli/index.js +79 -0
  114. package/dist/autopilot/cli/index.js.map +1 -0
  115. package/dist/autopilot/cli/pause.d.ts +18 -0
  116. package/dist/autopilot/cli/pause.d.ts.map +1 -0
  117. package/dist/autopilot/cli/pause.js +110 -0
  118. package/dist/autopilot/cli/pause.js.map +1 -0
  119. package/dist/autopilot/cli/resume.d.ts +22 -0
  120. package/dist/autopilot/cli/resume.d.ts.map +1 -0
  121. package/dist/autopilot/cli/resume.js +172 -0
  122. package/dist/autopilot/cli/resume.js.map +1 -0
  123. package/dist/autopilot/cli/run.d.ts +25 -0
  124. package/dist/autopilot/cli/run.d.ts.map +1 -0
  125. package/dist/autopilot/cli/run.js +220 -0
  126. package/dist/autopilot/cli/run.js.map +1 -0
  127. package/dist/autopilot/cli/status.d.ts +20 -0
  128. package/dist/autopilot/cli/status.d.ts.map +1 -0
  129. package/dist/autopilot/cli/status.js +217 -0
  130. package/dist/autopilot/cli/status.js.map +1 -0
  131. package/dist/autopilot/config.d.ts +45 -0
  132. package/dist/autopilot/config.d.ts.map +1 -0
  133. package/dist/autopilot/config.js +269 -0
  134. package/dist/autopilot/config.js.map +1 -0
  135. package/dist/autopilot/core/dependency-resolver.d.ts +108 -0
  136. package/dist/autopilot/core/dependency-resolver.d.ts.map +1 -0
  137. package/dist/autopilot/core/dependency-resolver.js +394 -0
  138. package/dist/autopilot/core/dependency-resolver.js.map +1 -0
  139. package/dist/autopilot/core/dispatcher.d.ts +215 -0
  140. package/dist/autopilot/core/dispatcher.d.ts.map +1 -0
  141. package/dist/autopilot/core/dispatcher.js +594 -0
  142. package/dist/autopilot/core/dispatcher.js.map +1 -0
  143. package/dist/autopilot/core/failure-handler.d.ts +145 -0
  144. package/dist/autopilot/core/failure-handler.d.ts.map +1 -0
  145. package/dist/autopilot/core/failure-handler.js +308 -0
  146. package/dist/autopilot/core/failure-handler.js.map +1 -0
  147. package/dist/autopilot/core/rate-limit-handler.d.ts +108 -0
  148. package/dist/autopilot/core/rate-limit-handler.d.ts.map +1 -0
  149. package/dist/autopilot/core/rate-limit-handler.js +195 -0
  150. package/dist/autopilot/core/rate-limit-handler.js.map +1 -0
  151. package/dist/autopilot/core/state-manager.d.ts +160 -0
  152. package/dist/autopilot/core/state-manager.d.ts.map +1 -0
  153. package/dist/autopilot/core/state-manager.js +393 -0
  154. package/dist/autopilot/core/state-manager.js.map +1 -0
  155. package/dist/autopilot/core/timeout-manager.d.ts +95 -0
  156. package/dist/autopilot/core/timeout-manager.d.ts.map +1 -0
  157. package/dist/autopilot/core/timeout-manager.js +188 -0
  158. package/dist/autopilot/core/timeout-manager.js.map +1 -0
  159. package/dist/autopilot/git/branch-manager.d.ts +117 -0
  160. package/dist/autopilot/git/branch-manager.d.ts.map +1 -0
  161. package/dist/autopilot/git/branch-manager.js +238 -0
  162. package/dist/autopilot/git/branch-manager.js.map +1 -0
  163. package/dist/autopilot/git/index.d.ts +9 -0
  164. package/dist/autopilot/git/index.d.ts.map +1 -0
  165. package/dist/autopilot/git/index.js +9 -0
  166. package/dist/autopilot/git/index.js.map +1 -0
  167. package/dist/autopilot/git/merge-manager.d.ts +118 -0
  168. package/dist/autopilot/git/merge-manager.d.ts.map +1 -0
  169. package/dist/autopilot/git/merge-manager.js +304 -0
  170. package/dist/autopilot/git/merge-manager.js.map +1 -0
  171. package/dist/autopilot/git/worktree-manager.d.ts +128 -0
  172. package/dist/autopilot/git/worktree-manager.d.ts.map +1 -0
  173. package/dist/autopilot/git/worktree-manager.js +298 -0
  174. package/dist/autopilot/git/worktree-manager.js.map +1 -0
  175. package/dist/autopilot/index.d.ts +30 -0
  176. package/dist/autopilot/index.d.ts.map +1 -0
  177. package/dist/autopilot/index.js +55 -0
  178. package/dist/autopilot/index.js.map +1 -0
  179. package/dist/autopilot/sync/index.d.ts +7 -0
  180. package/dist/autopilot/sync/index.d.ts.map +1 -0
  181. package/dist/autopilot/sync/index.js +7 -0
  182. package/dist/autopilot/sync/index.js.map +1 -0
  183. package/dist/autopilot/sync/sync-manager.d.ts +168 -0
  184. package/dist/autopilot/sync/sync-manager.d.ts.map +1 -0
  185. package/dist/autopilot/sync/sync-manager.js +303 -0
  186. package/dist/autopilot/sync/sync-manager.js.map +1 -0
  187. package/dist/autopilot/types.d.ts +454 -0
  188. package/dist/autopilot/types.d.ts.map +1 -0
  189. package/dist/autopilot/types.js +26 -0
  190. package/dist/autopilot/types.js.map +1 -0
  191. package/dist/autopilot/utils/audit-logger.d.ts +176 -0
  192. package/dist/autopilot/utils/audit-logger.d.ts.map +1 -0
  193. package/dist/autopilot/utils/audit-logger.js +308 -0
  194. package/dist/autopilot/utils/audit-logger.js.map +1 -0
  195. package/dist/autopilot/utils/cost-tracker.d.ts +162 -0
  196. package/dist/autopilot/utils/cost-tracker.d.ts.map +1 -0
  197. package/dist/autopilot/utils/cost-tracker.js +269 -0
  198. package/dist/autopilot/utils/cost-tracker.js.map +1 -0
  199. package/dist/autopilot/utils/index.d.ts +9 -0
  200. package/dist/autopilot/utils/index.d.ts.map +1 -0
  201. package/dist/autopilot/utils/index.js +9 -0
  202. package/dist/autopilot/utils/index.js.map +1 -0
  203. package/dist/autopilot/utils/progress-reporter.d.ts +132 -0
  204. package/dist/autopilot/utils/progress-reporter.d.ts.map +1 -0
  205. package/dist/autopilot/utils/progress-reporter.js +290 -0
  206. package/dist/autopilot/utils/progress-reporter.js.map +1 -0
  207. package/dist/autopilot/worker/worker-pool.d.ts +179 -0
  208. package/dist/autopilot/worker/worker-pool.d.ts.map +1 -0
  209. package/dist/autopilot/worker/worker-pool.js +331 -0
  210. package/dist/autopilot/worker/worker-pool.js.map +1 -0
  211. package/dist/autopilot/worker/worker-session.d.ts +171 -0
  212. package/dist/autopilot/worker/worker-session.d.ts.map +1 -0
  213. package/dist/autopilot/worker/worker-session.js +295 -0
  214. package/dist/autopilot/worker/worker-session.js.map +1 -0
  215. package/dist/cli/index.d.ts +1 -1
  216. package/dist/cli/index.d.ts.map +1 -1
  217. package/dist/cli/index.js +4 -1
  218. package/dist/cli/index.js.map +1 -1
  219. package/dist/index.js +0 -1
  220. package/dist/index.js.map +1 -1
  221. package/dist/tools/core/epic.js +1 -1
  222. package/dist/tools/core/epic.js.map +1 -1
  223. package/dist/tools/core/lookup.d.ts.map +1 -1
  224. package/dist/tools/core/lookup.js +3 -2
  225. package/dist/tools/core/lookup.js.map +1 -1
  226. package/dist/tools/core/specification.js +1 -1
  227. package/dist/tools/core/specification.js.map +1 -1
  228. package/dist/tools/core/ticket.d.ts.map +1 -1
  229. package/dist/tools/core/ticket.js +4 -6
  230. package/dist/tools/core/ticket.js.map +1 -1
  231. package/dist/tools/index.d.ts.map +1 -1
  232. package/dist/tools/index.js +60 -0
  233. package/dist/tools/index.js.map +1 -1
  234. package/dist/validation/index.d.ts.map +1 -1
  235. package/dist/validation/index.js +4 -1
  236. package/dist/validation/index.js.map +1 -1
  237. package/package.json +8 -4
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/ai-provider/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAqCH,+EAA+E;AAC/E,UAAU;AACV,+EAA+E;AAC/E,OAAO,EACL,gBAAgB,EAChB,qBAAqB,EACrB,cAAc,EACd,gBAAgB,EAChB,iBAAiB,GAClB,MAAM,cAAc,CAAC;AAEtB,+EAA+E;AAC/E,WAAW;AACX,+EAA+E;AAC/E,OAAO,EACL,kBAAkB,EAClB,wBAAwB,GACzB,MAAM,4BAA4B,CAAC;AAEpC,+EAA+E;AAC/E,kBAAkB;AAClB,+EAA+E;AAC/E,OAAO,EACL,wBAAwB,EACxB,oBAAoB,GACrB,MAAM,sBAAsB,CAAC;AAE9B,+EAA+E;AAC/E,SAAS;AACT,+EAA+E;AAC/E,OAAO,EACL,eAAe,EACf,kBAAkB,EAClB,mBAAmB,EACnB,cAAc,EACd,YAAY,EACZ,gBAAgB,EAChB,gBAAgB,EAChB,oBAAoB,EACpB,iBAAiB,EACjB,gBAAgB,EAChB,kBAAkB,EAClB,YAAY,GACb,MAAM,aAAa,CAAC;AAErB,+EAA+E;AAC/E,SAAS;AACT,+EAA+E;AAC/E,OAAO,EACL,gBAAgB,EAChB,cAAc,EACd,YAAY,EACZ,cAAc,EACd,sBAAsB,GACvB,MAAM,aAAa,CAAC;AAYrB,+EAA+E;AAC/E,YAAY;AACZ,+EAA+E;AAC/E,OAAO,EACL,SAAS,GACV,MAAM,gBAAgB,CAAC;AAExB,OAAO,EACL,cAAc,EACd,oBAAoB,GACrB,MAAM,sBAAsB,CAAC;AAE9B,OAAO,EACL,aAAa,EACb,mBAAmB,EACnB,SAAS,GACV,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EACL,mBAAmB,EACnB,yBAAyB,GAC1B,MAAM,2BAA2B,CAAC;AAEnC,OAAO,EACL,mBAAmB,EACnB,aAAa,EACb,uBAAuB,GACxB,MAAM,gBAAgB,CAAC;AAExB,OAAO,EACL,kBAAkB,EAClB,qBAAqB,EACrB,gBAAgB,EAChB,cAAc,GACf,MAAM,kBAAkB,CAAC;AAE1B,OAAO,EACL,YAAY,EACZ,eAAe,EACf,kBAAkB,GACnB,MAAM,oBAAoB,CAAC;AAE5B,+EAA+E;AAC/E,gBAAgB;AAChB,+EAA+E;AAC/E,OAAO,EACL,MAAM,EACN,YAAY,GACb,MAAM,aAAa,CAAC;AAErB,OAAO,EACL,OAAO,EACP,UAAU,EACV,aAAa,EACb,YAAY,GACb,MAAM,cAAc,CAAC;AAEtB,OAAO,EACL,MAAM,EACN,SAAS,EACT,YAAY,GACb,MAAM,aAAa,CAAC;AAErB,+EAA+E;AAC/E,YAAY;AACZ,+EAA+E;AAC/E,OAAO,EACL,uBAAuB,EACvB,mBAAmB,EACnB,sBAAsB,EACtB,UAAU,GACX,MAAM,gBAAgB,CAAC"}
@@ -0,0 +1,54 @@
1
+ /**
2
+ * Instance Coordinator
3
+ *
4
+ * Cross-process file lock coordination for limiting global process count.
5
+ */
6
+ export declare class InstanceCoordinator {
7
+ private maxGlobalProcesses;
8
+ private lockFile;
9
+ private instanceId;
10
+ private currentProcessCount;
11
+ constructor(maxGlobalProcesses?: number);
12
+ /**
13
+ * Try to acquire a global process slot.
14
+ */
15
+ tryAcquire(): Promise<boolean>;
16
+ /**
17
+ * Release a global process slot.
18
+ */
19
+ release(): void;
20
+ /**
21
+ * Release all slots for this instance (e.g., during shutdown).
22
+ */
23
+ releaseAll(): void;
24
+ /**
25
+ * Get global status across all instances.
26
+ */
27
+ getGlobalStatus(): {
28
+ totalProcesses: number;
29
+ maxProcesses: number;
30
+ instanceCount: number;
31
+ thisInstanceProcesses: number;
32
+ };
33
+ /**
34
+ * Clean up stale entries.
35
+ */
36
+ cleanup(): void;
37
+ /**
38
+ * Update max global processes.
39
+ */
40
+ setMaxGlobalProcesses(max: number): void;
41
+ /**
42
+ * Read state from lock file.
43
+ */
44
+ private readState;
45
+ /**
46
+ * Write state to lock file.
47
+ */
48
+ private writeState;
49
+ }
50
+ /**
51
+ * Create an instance coordinator with default configuration.
52
+ */
53
+ export declare function createInstanceCoordinator(maxGlobalProcesses?: number): InstanceCoordinator;
54
+ //# sourceMappingURL=instance-coordinator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"instance-coordinator.d.ts","sourceRoot":"","sources":["../../src/ai-provider/instance-coordinator.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAaH,qBAAa,mBAAmB;IAKlB,OAAO,CAAC,kBAAkB;IAJtC,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,mBAAmB,CAAa;gBAEpB,kBAAkB,GAAE,MAAW;IAKnD;;OAEG;IACG,UAAU,IAAI,OAAO,CAAC,OAAO,CAAC;IAyDpC;;OAEG;IACH,OAAO,IAAI,IAAI;IAuCf;;OAEG;IACH,UAAU,IAAI,IAAI;IAmBlB;;OAEG;IACH,eAAe,IAAI;QACjB,cAAc,EAAE,MAAM,CAAC;QACvB,YAAY,EAAE,MAAM,CAAC;QACrB,aAAa,EAAE,MAAM,CAAC;QACtB,qBAAqB,EAAE,MAAM,CAAC;KAC/B;IAgCD;;OAEG;IACH,OAAO,IAAI,IAAI;IAqBf;;OAEG;IACH,qBAAqB,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;IAIxC;;OAEG;IACH,OAAO,CAAC,SAAS;IASjB;;OAEG;IACH,OAAO,CAAC,UAAU;CAGnB;AAED;;GAEG;AACH,wBAAgB,yBAAyB,CACvC,kBAAkB,CAAC,EAAE,MAAM,GAC1B,mBAAmB,CAErB"}
@@ -0,0 +1,199 @@
1
+ /**
2
+ * Instance Coordinator
3
+ *
4
+ * Cross-process file lock coordination for limiting global process count.
5
+ */
6
+ import * as fs from 'fs';
7
+ import * as path from 'path';
8
+ import * as os from 'os';
9
+ import { createLogger } from './logger.js';
10
+ const logger = createLogger('InstanceCoordinator');
11
+ const DEFAULT_LOCK_FILE = 'specforge-ai-provider.lock';
12
+ const STALE_THRESHOLD_MS = 5 * 60 * 1000; // 5 minutes
13
+ export class InstanceCoordinator {
14
+ maxGlobalProcesses;
15
+ lockFile;
16
+ instanceId;
17
+ currentProcessCount = 0;
18
+ constructor(maxGlobalProcesses = 10) {
19
+ this.maxGlobalProcesses = maxGlobalProcesses;
20
+ this.lockFile = path.join(os.tmpdir(), DEFAULT_LOCK_FILE);
21
+ this.instanceId = `${process.pid}-${Date.now()}`;
22
+ }
23
+ /**
24
+ * Try to acquire a global process slot.
25
+ */
26
+ async tryAcquire() {
27
+ try {
28
+ const state = this.readState();
29
+ // Clean up stale entries (older than 5 minutes)
30
+ const now = Date.now();
31
+ const activeInstances = state.instances.filter(i => now - i.timestamp < STALE_THRESHOLD_MS);
32
+ const totalProcesses = activeInstances.reduce((sum, i) => sum + i.processCount, 0);
33
+ if (totalProcesses >= this.maxGlobalProcesses) {
34
+ logger.debug('Global process limit reached', {
35
+ totalProcesses,
36
+ maxGlobalProcesses: this.maxGlobalProcesses,
37
+ });
38
+ return false;
39
+ }
40
+ // Update or add this instance
41
+ const existingIndex = activeInstances.findIndex(i => i.instanceId === this.instanceId);
42
+ if (existingIndex >= 0) {
43
+ activeInstances[existingIndex].processCount++;
44
+ activeInstances[existingIndex].timestamp = now;
45
+ }
46
+ else {
47
+ activeInstances.push({
48
+ instanceId: this.instanceId,
49
+ processCount: 1,
50
+ timestamp: now,
51
+ });
52
+ }
53
+ this.currentProcessCount++;
54
+ this.writeState({ instances: activeInstances });
55
+ logger.debug('Acquired global process slot', {
56
+ instanceId: this.instanceId,
57
+ processCount: this.currentProcessCount,
58
+ totalGlobalProcesses: totalProcesses + 1,
59
+ });
60
+ return true;
61
+ }
62
+ catch (error) {
63
+ // If locking fails, allow the request (fail open)
64
+ logger.warn('Failed to acquire lock, allowing request', {
65
+ error: error.message,
66
+ });
67
+ return true;
68
+ }
69
+ }
70
+ /**
71
+ * Release a global process slot.
72
+ */
73
+ release() {
74
+ if (this.currentProcessCount <= 0) {
75
+ return;
76
+ }
77
+ try {
78
+ const state = this.readState();
79
+ const instance = state.instances.find(i => i.instanceId === this.instanceId);
80
+ if (instance) {
81
+ instance.processCount = Math.max(0, instance.processCount - 1);
82
+ instance.timestamp = Date.now();
83
+ // Remove instance if no more processes
84
+ if (instance.processCount === 0) {
85
+ state.instances = state.instances.filter(i => i.instanceId !== this.instanceId);
86
+ }
87
+ this.writeState(state);
88
+ }
89
+ this.currentProcessCount = Math.max(0, this.currentProcessCount - 1);
90
+ logger.debug('Released global process slot', {
91
+ instanceId: this.instanceId,
92
+ processCount: this.currentProcessCount,
93
+ });
94
+ }
95
+ catch (error) {
96
+ // Ignore release errors
97
+ logger.warn('Failed to release lock', {
98
+ error: error.message,
99
+ });
100
+ }
101
+ }
102
+ /**
103
+ * Release all slots for this instance (e.g., during shutdown).
104
+ */
105
+ releaseAll() {
106
+ try {
107
+ const state = this.readState();
108
+ state.instances = state.instances.filter(i => i.instanceId !== this.instanceId);
109
+ this.writeState(state);
110
+ this.currentProcessCount = 0;
111
+ logger.debug('Released all process slots', {
112
+ instanceId: this.instanceId,
113
+ });
114
+ }
115
+ catch (error) {
116
+ logger.warn('Failed to release all locks', {
117
+ error: error.message,
118
+ });
119
+ }
120
+ }
121
+ /**
122
+ * Get global status across all instances.
123
+ */
124
+ getGlobalStatus() {
125
+ try {
126
+ const state = this.readState();
127
+ const now = Date.now();
128
+ const activeInstances = state.instances.filter(i => now - i.timestamp < STALE_THRESHOLD_MS);
129
+ const totalProcesses = activeInstances.reduce((sum, i) => sum + i.processCount, 0);
130
+ const thisInstance = activeInstances.find(i => i.instanceId === this.instanceId);
131
+ return {
132
+ totalProcesses,
133
+ maxProcesses: this.maxGlobalProcesses,
134
+ instanceCount: activeInstances.length,
135
+ thisInstanceProcesses: thisInstance?.processCount ?? 0,
136
+ };
137
+ }
138
+ catch {
139
+ return {
140
+ totalProcesses: this.currentProcessCount,
141
+ maxProcesses: this.maxGlobalProcesses,
142
+ instanceCount: 1,
143
+ thisInstanceProcesses: this.currentProcessCount,
144
+ };
145
+ }
146
+ }
147
+ /**
148
+ * Clean up stale entries.
149
+ */
150
+ cleanup() {
151
+ try {
152
+ const state = this.readState();
153
+ const now = Date.now();
154
+ const activeInstances = state.instances.filter(i => now - i.timestamp < STALE_THRESHOLD_MS);
155
+ if (activeInstances.length !== state.instances.length) {
156
+ this.writeState({ instances: activeInstances });
157
+ logger.debug('Cleaned up stale instances', {
158
+ removed: state.instances.length - activeInstances.length,
159
+ });
160
+ }
161
+ }
162
+ catch (error) {
163
+ logger.warn('Failed to cleanup stale instances', {
164
+ error: error.message,
165
+ });
166
+ }
167
+ }
168
+ /**
169
+ * Update max global processes.
170
+ */
171
+ setMaxGlobalProcesses(max) {
172
+ this.maxGlobalProcesses = max;
173
+ }
174
+ /**
175
+ * Read state from lock file.
176
+ */
177
+ readState() {
178
+ try {
179
+ const content = fs.readFileSync(this.lockFile, 'utf-8');
180
+ return JSON.parse(content);
181
+ }
182
+ catch {
183
+ return { instances: [] };
184
+ }
185
+ }
186
+ /**
187
+ * Write state to lock file.
188
+ */
189
+ writeState(state) {
190
+ fs.writeFileSync(this.lockFile, JSON.stringify(state), { flag: 'w' });
191
+ }
192
+ }
193
+ /**
194
+ * Create an instance coordinator with default configuration.
195
+ */
196
+ export function createInstanceCoordinator(maxGlobalProcesses) {
197
+ return new InstanceCoordinator(maxGlobalProcesses);
198
+ }
199
+ //# sourceMappingURL=instance-coordinator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"instance-coordinator.js","sourceRoot":"","sources":["../../src/ai-provider/instance-coordinator.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,43 @@
1
+ /**
2
+ * JSONL Parser for Claude Code Session Logs
3
+ *
4
+ * Parses Claude Code JSONL log files to extract actual token usage.
5
+ * JSONL files are stored at ~/.claude/projects/<encoded-path>/<sessionId>.jsonl
6
+ */
7
+ /**
8
+ * Parsed token usage from JSONL logs
9
+ */
10
+ export interface ParsedTokenUsage {
11
+ inputTokens: number;
12
+ outputTokens: number;
13
+ cacheCreationTokens: number;
14
+ cacheReadTokens: number;
15
+ costUSD: number;
16
+ durationMs: number;
17
+ }
18
+ /**
19
+ * Parse a single JSONL line for token usage
20
+ */
21
+ export declare function parseJSONLLine(line: string): ParsedTokenUsage | null;
22
+ /**
23
+ * Parse JSONL content and sum token usage across all assistant messages
24
+ */
25
+ export declare function parseJSONLContent(content: string): ParsedTokenUsage;
26
+ /**
27
+ * Encode project path for Claude Code directory structure.
28
+ * Claude encodes paths like: /Users/agent/myproject -> Users-agent-myproject
29
+ */
30
+ export declare function encodeProjectPath(path: string): string;
31
+ /**
32
+ * Parse token usage from a session's JSONL file.
33
+ *
34
+ * @param sessionId - The session ID used when running Claude Code
35
+ * @param projectPath - The working directory used for the session
36
+ * @returns Parsed token usage or null if file not found/parse error
37
+ */
38
+ export declare function parseSessionTokens(sessionId: string, projectPath: string): Promise<ParsedTokenUsage | null>;
39
+ /**
40
+ * Create a default (zero) token usage object
41
+ */
42
+ export declare function createEmptyTokenUsage(): ParsedTokenUsage;
43
+ //# sourceMappingURL=jsonl-parser.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"jsonl-parser.d.ts","sourceRoot":"","sources":["../../src/ai-provider/jsonl-parser.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAMH;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,mBAAmB,EAAE,MAAM,CAAC;IAC5B,eAAe,EAAE,MAAM,CAAC;IACxB,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;CACpB;AAgCD;;GAEG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,gBAAgB,GAAG,IAAI,CA0BpE;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,GAAG,gBAAgB,CA2BnE;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAGtD;AAED;;;;;;GAMG;AACH,wBAAsB,kBAAkB,CACtC,SAAS,EAAE,MAAM,EACjB,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC,gBAAgB,GAAG,IAAI,CAAC,CAalC;AAED;;GAEG;AACH,wBAAgB,qBAAqB,IAAI,gBAAgB,CASxD"}
@@ -0,0 +1,107 @@
1
+ /**
2
+ * JSONL Parser for Claude Code Session Logs
3
+ *
4
+ * Parses Claude Code JSONL log files to extract actual token usage.
5
+ * JSONL files are stored at ~/.claude/projects/<encoded-path>/<sessionId>.jsonl
6
+ */
7
+ import { readFile } from 'fs/promises';
8
+ import { homedir } from 'os';
9
+ import { join } from 'path';
10
+ /**
11
+ * Parse a single JSONL line for token usage
12
+ */
13
+ export function parseJSONLLine(line) {
14
+ try {
15
+ const record = JSON.parse(line);
16
+ if (record.type !== 'assistant') {
17
+ return null;
18
+ }
19
+ const assistantRecord = record;
20
+ const usage = assistantRecord.message?.usage;
21
+ if (!usage) {
22
+ return null;
23
+ }
24
+ return {
25
+ inputTokens: usage.input_tokens || 0,
26
+ outputTokens: usage.output_tokens || 0,
27
+ cacheCreationTokens: usage.cache_creation_input_tokens || 0,
28
+ cacheReadTokens: usage.cache_read_input_tokens || 0,
29
+ costUSD: assistantRecord.costUSD || 0,
30
+ durationMs: assistantRecord.durationMs || 0,
31
+ };
32
+ }
33
+ catch {
34
+ return null;
35
+ }
36
+ }
37
+ /**
38
+ * Parse JSONL content and sum token usage across all assistant messages
39
+ */
40
+ export function parseJSONLContent(content) {
41
+ const lines = content.trim().split('\n');
42
+ const total = {
43
+ inputTokens: 0,
44
+ outputTokens: 0,
45
+ cacheCreationTokens: 0,
46
+ cacheReadTokens: 0,
47
+ costUSD: 0,
48
+ durationMs: 0,
49
+ };
50
+ for (const line of lines) {
51
+ if (!line.trim())
52
+ continue;
53
+ const parsed = parseJSONLLine(line);
54
+ if (parsed) {
55
+ total.inputTokens += parsed.inputTokens;
56
+ total.outputTokens += parsed.outputTokens;
57
+ total.cacheCreationTokens += parsed.cacheCreationTokens;
58
+ total.cacheReadTokens += parsed.cacheReadTokens;
59
+ total.costUSD += parsed.costUSD;
60
+ total.durationMs += parsed.durationMs;
61
+ }
62
+ }
63
+ return total;
64
+ }
65
+ /**
66
+ * Encode project path for Claude Code directory structure.
67
+ * Claude encodes paths like: /Users/agent/myproject -> Users-agent-myproject
68
+ */
69
+ export function encodeProjectPath(path) {
70
+ // Replace slashes with dashes and remove leading dash
71
+ return path.replace(/\//g, '-').replace(/^-/, '');
72
+ }
73
+ /**
74
+ * Parse token usage from a session's JSONL file.
75
+ *
76
+ * @param sessionId - The session ID used when running Claude Code
77
+ * @param projectPath - The working directory used for the session
78
+ * @returns Parsed token usage or null if file not found/parse error
79
+ */
80
+ export async function parseSessionTokens(sessionId, projectPath) {
81
+ // JSONL file location: ~/.claude/projects/<encoded-path>/<sessionId>.jsonl
82
+ const claudeDir = join(homedir(), '.claude', 'projects');
83
+ const encodedProject = encodeProjectPath(projectPath);
84
+ const jsonlPath = join(claudeDir, encodedProject, `${sessionId}.jsonl`);
85
+ try {
86
+ const content = await readFile(jsonlPath, 'utf-8');
87
+ return parseJSONLContent(content);
88
+ }
89
+ catch {
90
+ // File not found or read error
91
+ return null;
92
+ }
93
+ }
94
+ /**
95
+ * Create a default (zero) token usage object
96
+ */
97
+ export function createEmptyTokenUsage() {
98
+ return {
99
+ inputTokens: 0,
100
+ outputTokens: 0,
101
+ cacheCreationTokens: 0,
102
+ cacheReadTokens: 0,
103
+ costUSD: 0,
104
+ durationMs: 0,
105
+ };
106
+ }
107
+ //# sourceMappingURL=jsonl-parser.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"jsonl-parser.js","sourceRoot":"","sources":["../../src/ai-provider/jsonl-parser.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,50 @@
1
+ /**
2
+ * Process Lifecycle Manager
3
+ *
4
+ * Handles graceful shutdown on SIGTERM, SIGINT, and SIGHUP.
5
+ */
6
+ import { ClaudeCodeProcessManager } from './process-manager.js';
7
+ export declare class ProcessLifecycleManager {
8
+ private processManager?;
9
+ private shutdownInProgress;
10
+ private shutdownHandlers;
11
+ private signalsRegistered;
12
+ constructor(processManager?: ClaudeCodeProcessManager | undefined);
13
+ /**
14
+ * Set the process manager to manage.
15
+ */
16
+ setProcessManager(processManager: ClaudeCodeProcessManager): void;
17
+ /**
18
+ * Register an additional shutdown handler.
19
+ */
20
+ onShutdown(handler: () => Promise<void>): void;
21
+ /**
22
+ * Check if shutdown is in progress.
23
+ */
24
+ isShuttingDown(): boolean;
25
+ /**
26
+ * Manually trigger shutdown.
27
+ */
28
+ shutdown(): Promise<void>;
29
+ /**
30
+ * Setup signal handlers.
31
+ */
32
+ private setupSignalHandlers;
33
+ /**
34
+ * Perform the shutdown sequence.
35
+ */
36
+ private performShutdown;
37
+ }
38
+ /**
39
+ * Get or create global lifecycle manager.
40
+ */
41
+ export declare function getLifecycleManager(): ProcessLifecycleManager;
42
+ /**
43
+ * Create a lifecycle manager for a process manager.
44
+ */
45
+ export declare function createLifecycleManager(processManager: ClaudeCodeProcessManager): ProcessLifecycleManager;
46
+ /**
47
+ * Register a global shutdown handler.
48
+ */
49
+ export declare function onShutdown(handler: () => Promise<void>): void;
50
+ //# sourceMappingURL=lifecycle.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lifecycle.d.ts","sourceRoot":"","sources":["../../src/ai-provider/lifecycle.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,wBAAwB,EAAE,MAAM,sBAAsB,CAAC;AAMhE,qBAAa,uBAAuB;IAKtB,OAAO,CAAC,cAAc,CAAC;IAJnC,OAAO,CAAC,kBAAkB,CAAS;IACnC,OAAO,CAAC,gBAAgB,CAAkC;IAC1D,OAAO,CAAC,iBAAiB,CAAS;gBAEd,cAAc,CAAC,EAAE,wBAAwB,YAAA;IAO7D;;OAEG;IACH,iBAAiB,CAAC,cAAc,EAAE,wBAAwB,GAAG,IAAI;IAIjE;;OAEG;IACH,UAAU,CAAC,OAAO,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI;IAI9C;;OAEG;IACH,cAAc,IAAI,OAAO;IAIzB;;OAEG;IACG,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;IAS/B;;OAEG;IACH,OAAO,CAAC,mBAAmB;IAyC3B;;OAEG;YACW,eAAe;CAiC9B;AAOD;;GAEG;AACH,wBAAgB,mBAAmB,IAAI,uBAAuB,CAK7D;AAED;;GAEG;AACH,wBAAgB,sBAAsB,CACpC,cAAc,EAAE,wBAAwB,GACvC,uBAAuB,CAEzB;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,OAAO,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAE7D"}
@@ -0,0 +1,145 @@
1
+ /**
2
+ * Process Lifecycle Manager
3
+ *
4
+ * Handles graceful shutdown on SIGTERM, SIGINT, and SIGHUP.
5
+ */
6
+ import { createLogger } from './logger.js';
7
+ const logger = createLogger('ProcessLifecycle');
8
+ export class ProcessLifecycleManager {
9
+ processManager;
10
+ shutdownInProgress = false;
11
+ shutdownHandlers = [];
12
+ signalsRegistered = false;
13
+ constructor(processManager) {
14
+ this.processManager = processManager;
15
+ // Only setup signal handlers in Node.js environment
16
+ if (typeof process !== 'undefined' && typeof process.on === 'function') {
17
+ this.setupSignalHandlers();
18
+ }
19
+ }
20
+ /**
21
+ * Set the process manager to manage.
22
+ */
23
+ setProcessManager(processManager) {
24
+ this.processManager = processManager;
25
+ }
26
+ /**
27
+ * Register an additional shutdown handler.
28
+ */
29
+ onShutdown(handler) {
30
+ this.shutdownHandlers.push(handler);
31
+ }
32
+ /**
33
+ * Check if shutdown is in progress.
34
+ */
35
+ isShuttingDown() {
36
+ return this.shutdownInProgress;
37
+ }
38
+ /**
39
+ * Manually trigger shutdown.
40
+ */
41
+ async shutdown() {
42
+ if (this.shutdownInProgress) {
43
+ logger.warn('Shutdown already in progress');
44
+ return;
45
+ }
46
+ await this.performShutdown('manual');
47
+ }
48
+ /**
49
+ * Setup signal handlers.
50
+ */
51
+ setupSignalHandlers() {
52
+ if (this.signalsRegistered) {
53
+ return;
54
+ }
55
+ const signals = ['SIGTERM', 'SIGINT', 'SIGHUP'];
56
+ for (const signal of signals) {
57
+ process.on(signal, () => {
58
+ this.performShutdown(signal).then(() => {
59
+ process.exit(0);
60
+ }).catch((error) => {
61
+ logger.error('Error during shutdown', { error: error.message });
62
+ process.exit(1);
63
+ });
64
+ });
65
+ }
66
+ // Handle uncaught exceptions
67
+ process.on('uncaughtException', (error) => {
68
+ logger.error('Uncaught exception', {
69
+ error: error.message,
70
+ stack: error.stack,
71
+ });
72
+ this.performShutdown('uncaughtException').finally(() => {
73
+ process.exit(1);
74
+ });
75
+ });
76
+ // Handle unhandled promise rejections
77
+ process.on('unhandledRejection', (reason) => {
78
+ logger.error('Unhandled rejection', {
79
+ reason: String(reason),
80
+ });
81
+ });
82
+ this.signalsRegistered = true;
83
+ logger.debug('Signal handlers registered');
84
+ }
85
+ /**
86
+ * Perform the shutdown sequence.
87
+ */
88
+ async performShutdown(signal) {
89
+ if (this.shutdownInProgress) {
90
+ return;
91
+ }
92
+ this.shutdownInProgress = true;
93
+ logger.info(`Received ${signal}, starting graceful shutdown...`);
94
+ try {
95
+ // Run custom shutdown handlers first
96
+ for (const handler of this.shutdownHandlers) {
97
+ try {
98
+ await handler();
99
+ }
100
+ catch (error) {
101
+ logger.warn('Shutdown handler error', {
102
+ error: error.message,
103
+ });
104
+ }
105
+ }
106
+ // Shutdown process manager
107
+ if (this.processManager) {
108
+ await this.processManager.shutdown();
109
+ }
110
+ logger.info('Graceful shutdown completed');
111
+ }
112
+ catch (error) {
113
+ logger.error('Error during shutdown', {
114
+ error: error.message,
115
+ });
116
+ throw error;
117
+ }
118
+ }
119
+ }
120
+ /**
121
+ * Global lifecycle manager instance.
122
+ */
123
+ let globalLifecycleManager = null;
124
+ /**
125
+ * Get or create global lifecycle manager.
126
+ */
127
+ export function getLifecycleManager() {
128
+ if (!globalLifecycleManager) {
129
+ globalLifecycleManager = new ProcessLifecycleManager();
130
+ }
131
+ return globalLifecycleManager;
132
+ }
133
+ /**
134
+ * Create a lifecycle manager for a process manager.
135
+ */
136
+ export function createLifecycleManager(processManager) {
137
+ return new ProcessLifecycleManager(processManager);
138
+ }
139
+ /**
140
+ * Register a global shutdown handler.
141
+ */
142
+ export function onShutdown(handler) {
143
+ getLifecycleManager().onShutdown(handler);
144
+ }
145
+ //# sourceMappingURL=lifecycle.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lifecycle.js","sourceRoot":"","sources":["../../src/ai-provider/lifecycle.ts"],"names":[],"mappings":"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"}