gentyr 1.3.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 (599) hide show
  1. package/.claude/agents/antipattern-hunter.md +176 -0
  2. package/.claude/agents/code-reviewer.md +205 -0
  3. package/.claude/agents/code-writer.md +154 -0
  4. package/.claude/agents/deputy-cto.md +309 -0
  5. package/.claude/agents/feedback-agent.md +101 -0
  6. package/.claude/agents/investigator.md +136 -0
  7. package/.claude/agents/product-manager.md +97 -0
  8. package/.claude/agents/project-manager.md +116 -0
  9. package/.claude/agents/repo-hygiene-expert.md +626 -0
  10. package/.claude/agents/secret-manager.md +324 -0
  11. package/.claude/agents/test-writer.md +354 -0
  12. package/.claude/commands/configure-personas.md +144 -0
  13. package/.claude/commands/cto-report.md +36 -0
  14. package/.claude/commands/demo.md +89 -0
  15. package/.claude/commands/deputy-cto.md +345 -0
  16. package/.claude/commands/hotfix.md +31 -0
  17. package/.claude/commands/overdrive-gentyr.md +167 -0
  18. package/.claude/commands/product-manager.md +32 -0
  19. package/.claude/commands/push-migrations.md +86 -0
  20. package/.claude/commands/push-secrets.md +97 -0
  21. package/.claude/commands/services.json.example +30 -0
  22. package/.claude/commands/setup-gentyr.md +396 -0
  23. package/.claude/commands/show.md +42 -0
  24. package/.claude/commands/spawn-tasks.md +79 -0
  25. package/.claude/commands/toggle-automation-gentyr.md +75 -0
  26. package/.claude/commands/toggle-product-manager.md +19 -0
  27. package/.claude/commands/triage.md +69 -0
  28. package/.claude/hooks/README.md +686 -0
  29. package/.claude/hooks/__tests__/README.md +129 -0
  30. package/.claude/hooks/agent-tracker.js +434 -0
  31. package/.claude/hooks/antipattern-hunter-hook.js +401 -0
  32. package/.claude/hooks/api-key-watcher.js +289 -0
  33. package/.claude/hooks/block-no-verify.js +301 -0
  34. package/.claude/hooks/bypass-approval-hook.js +313 -0
  35. package/.claude/hooks/compliance-checker.js +1309 -0
  36. package/.claude/hooks/config-reader.js +143 -0
  37. package/.claude/hooks/credential-file-guard.js +1139 -0
  38. package/.claude/hooks/credential-health-check.js +168 -0
  39. package/.claude/hooks/credential-sync-hook.js +79 -0
  40. package/.claude/hooks/cto-notification-hook.js +656 -0
  41. package/.claude/hooks/feedback-launcher.js +424 -0
  42. package/.claude/hooks/feedback-orchestrator.js +367 -0
  43. package/.claude/hooks/gentyr-splash.js +47 -0
  44. package/.claude/hooks/gentyr-sync.js +389 -0
  45. package/.claude/hooks/hourly-automation.js +3340 -0
  46. package/.claude/hooks/key-sync.js +899 -0
  47. package/.claude/hooks/lib/approval-utils.js +731 -0
  48. package/.claude/hooks/lib/feature-branch-helper.js +102 -0
  49. package/.claude/hooks/lib/worktree-manager.js +330 -0
  50. package/.claude/hooks/mapping-validator.js +285 -0
  51. package/.claude/hooks/plan-executor.js +398 -0
  52. package/.claude/hooks/playwright-cli-guard.js +104 -0
  53. package/.claude/hooks/playwright-health-check.js +71 -0
  54. package/.claude/hooks/pre-commit-review.js +725 -0
  55. package/.claude/hooks/prompts/local-spec-enforcement.md +310 -0
  56. package/.claude/hooks/prompts/mapping-fix.md +92 -0
  57. package/.claude/hooks/prompts/mapping-review.md +140 -0
  58. package/.claude/hooks/prompts/schema-mapper.md +185 -0
  59. package/.claude/hooks/prompts/spec-enforcement.md +233 -0
  60. package/.claude/hooks/protected-action-approval-hook.js +336 -0
  61. package/.claude/hooks/protected-action-gate.js +562 -0
  62. package/.claude/hooks/protected-actions.json +208 -0
  63. package/.claude/hooks/protected-actions.json.template +122 -0
  64. package/.claude/hooks/quota-monitor.js +490 -0
  65. package/.claude/hooks/reporters/jest-failure-reporter.js +401 -0
  66. package/.claude/hooks/reporters/playwright-failure-reporter.js +446 -0
  67. package/.claude/hooks/reporters/vitest-failure-reporter.js +443 -0
  68. package/.claude/hooks/schema-mapper-hook.js +544 -0
  69. package/.claude/hooks/secret-leak-detector.js +216 -0
  70. package/.claude/hooks/session-reviver.js +514 -0
  71. package/.claude/hooks/slash-command-prefetch.js +1145 -0
  72. package/.claude/hooks/stale-work-detector.js +205 -0
  73. package/.claude/hooks/stop-continue-hook.js +414 -0
  74. package/.claude/hooks/todo-maintenance.js +522 -0
  75. package/.claude/hooks/todo-processing-prompt.md +75 -0
  76. package/.claude/hooks/usage-optimizer.js +791 -0
  77. package/.claude/mcp/README.md +246 -0
  78. package/.claude/settings.json.template +168 -0
  79. package/.mcp.json.template +207 -0
  80. package/CLAUDE.md +340 -0
  81. package/CLAUDE.md.gentyr-section +89 -0
  82. package/LICENSE +21 -0
  83. package/README.md +297 -0
  84. package/cli/commands/init.js +471 -0
  85. package/cli/commands/migrate.js +132 -0
  86. package/cli/commands/protect.js +271 -0
  87. package/cli/commands/scaffold.js +48 -0
  88. package/cli/commands/status.js +133 -0
  89. package/cli/commands/sync.js +101 -0
  90. package/cli/commands/uninstall.js +207 -0
  91. package/cli/index.js +111 -0
  92. package/cli/lib/config-gen.js +214 -0
  93. package/cli/lib/resolve-framework.js +97 -0
  94. package/cli/lib/state.js +140 -0
  95. package/cli/lib/symlinks.js +260 -0
  96. package/docs/AUTOMATION-SYSTEMS.md +484 -0
  97. package/docs/BINARY-PATCHING.md +212 -0
  98. package/docs/CHANGELOG.md +2830 -0
  99. package/docs/CREDENTIAL-DETECTION.md +151 -0
  100. package/docs/CTO-DASHBOARD.md +476 -0
  101. package/docs/DEPLOYMENT-FLOW.md +477 -0
  102. package/docs/DEVELOPER.md +116 -0
  103. package/docs/Executive.md +372 -0
  104. package/docs/SECRET-PATHS.md +77 -0
  105. package/docs/SETUP-GUIDE.md +419 -0
  106. package/docs/STACK.md +109 -0
  107. package/docs/TESTING.md +440 -0
  108. package/docs/assets/claude-logo.svg +3 -0
  109. package/docs/sessions/2026-01-24-spec-suite-implementation.md +190 -0
  110. package/docs/sessions/2026-02-15-feedback-e2e-audit.md +484 -0
  111. package/docs/sessions/2026-02-20-credential-rotation-experiments.md +340 -0
  112. package/docs/sessions/TEST-COVERAGE-REPORT-2026-02-20.md +168 -0
  113. package/docs/shared/EPHEMERAL-STATE-FILES.md +115 -0
  114. package/docs/shared/PROTECTION-SYSTEM.md +341 -0
  115. package/husky/post-commit +10 -0
  116. package/husky/pre-commit +40 -0
  117. package/husky/pre-push +94 -0
  118. package/package.json +43 -0
  119. package/packages/cto-dashboard/package-lock.json +3510 -0
  120. package/packages/cto-dashboard/package.json +41 -0
  121. package/packages/cto-dashboard/pnpm-lock.yaml +2168 -0
  122. package/packages/mcp-servers/dist/__testUtils__/fixtures.d.ts +220 -0
  123. package/packages/mcp-servers/dist/__testUtils__/fixtures.d.ts.map +1 -0
  124. package/packages/mcp-servers/dist/__testUtils__/fixtures.js +376 -0
  125. package/packages/mcp-servers/dist/__testUtils__/fixtures.js.map +1 -0
  126. package/packages/mcp-servers/dist/__testUtils__/index.d.ts +121 -0
  127. package/packages/mcp-servers/dist/__testUtils__/index.d.ts.map +1 -0
  128. package/packages/mcp-servers/dist/__testUtils__/index.js +180 -0
  129. package/packages/mcp-servers/dist/__testUtils__/index.js.map +1 -0
  130. package/packages/mcp-servers/dist/__testUtils__/schemas.d.ts +84 -0
  131. package/packages/mcp-servers/dist/__testUtils__/schemas.d.ts.map +1 -0
  132. package/packages/mcp-servers/dist/__testUtils__/schemas.js +309 -0
  133. package/packages/mcp-servers/dist/__testUtils__/schemas.js.map +1 -0
  134. package/packages/mcp-servers/dist/agent-reports/index.d.ts +7 -0
  135. package/packages/mcp-servers/dist/agent-reports/index.d.ts.map +1 -0
  136. package/packages/mcp-servers/dist/agent-reports/index.js +8 -0
  137. package/packages/mcp-servers/dist/agent-reports/index.js.map +1 -0
  138. package/packages/mcp-servers/dist/agent-reports/server.d.ts +22 -0
  139. package/packages/mcp-servers/dist/agent-reports/server.d.ts.map +1 -0
  140. package/packages/mcp-servers/dist/agent-reports/server.js +535 -0
  141. package/packages/mcp-servers/dist/agent-reports/server.js.map +1 -0
  142. package/packages/mcp-servers/dist/agent-reports/types.d.ts +258 -0
  143. package/packages/mcp-servers/dist/agent-reports/types.d.ts.map +1 -0
  144. package/packages/mcp-servers/dist/agent-reports/types.js +81 -0
  145. package/packages/mcp-servers/dist/agent-reports/types.js.map +1 -0
  146. package/packages/mcp-servers/dist/agent-tracker/index.d.ts +5 -0
  147. package/packages/mcp-servers/dist/agent-tracker/index.d.ts.map +1 -0
  148. package/packages/mcp-servers/dist/agent-tracker/index.js +5 -0
  149. package/packages/mcp-servers/dist/agent-tracker/index.js.map +1 -0
  150. package/packages/mcp-servers/dist/agent-tracker/server.d.ts +12 -0
  151. package/packages/mcp-servers/dist/agent-tracker/server.d.ts.map +1 -0
  152. package/packages/mcp-servers/dist/agent-tracker/server.js +919 -0
  153. package/packages/mcp-servers/dist/agent-tracker/server.js.map +1 -0
  154. package/packages/mcp-servers/dist/agent-tracker/types.d.ts +328 -0
  155. package/packages/mcp-servers/dist/agent-tracker/types.d.ts.map +1 -0
  156. package/packages/mcp-servers/dist/agent-tracker/types.js +128 -0
  157. package/packages/mcp-servers/dist/agent-tracker/types.js.map +1 -0
  158. package/packages/mcp-servers/dist/chrome-bridge/browser-tips.d.ts +27 -0
  159. package/packages/mcp-servers/dist/chrome-bridge/browser-tips.d.ts.map +1 -0
  160. package/packages/mcp-servers/dist/chrome-bridge/browser-tips.js +167 -0
  161. package/packages/mcp-servers/dist/chrome-bridge/browser-tips.js.map +1 -0
  162. package/packages/mcp-servers/dist/chrome-bridge/index.d.ts +6 -0
  163. package/packages/mcp-servers/dist/chrome-bridge/index.d.ts.map +1 -0
  164. package/packages/mcp-servers/dist/chrome-bridge/index.js +6 -0
  165. package/packages/mcp-servers/dist/chrome-bridge/index.js.map +1 -0
  166. package/packages/mcp-servers/dist/chrome-bridge/server.d.ts +13 -0
  167. package/packages/mcp-servers/dist/chrome-bridge/server.d.ts.map +1 -0
  168. package/packages/mcp-servers/dist/chrome-bridge/server.js +959 -0
  169. package/packages/mcp-servers/dist/chrome-bridge/server.js.map +1 -0
  170. package/packages/mcp-servers/dist/chrome-bridge/types.d.ts +41 -0
  171. package/packages/mcp-servers/dist/chrome-bridge/types.d.ts.map +1 -0
  172. package/packages/mcp-servers/dist/chrome-bridge/types.js +8 -0
  173. package/packages/mcp-servers/dist/chrome-bridge/types.js.map +1 -0
  174. package/packages/mcp-servers/dist/cloudflare/index.d.ts +8 -0
  175. package/packages/mcp-servers/dist/cloudflare/index.d.ts.map +1 -0
  176. package/packages/mcp-servers/dist/cloudflare/index.js +8 -0
  177. package/packages/mcp-servers/dist/cloudflare/index.js.map +1 -0
  178. package/packages/mcp-servers/dist/cloudflare/server.d.ts +16 -0
  179. package/packages/mcp-servers/dist/cloudflare/server.d.ts.map +1 -0
  180. package/packages/mcp-servers/dist/cloudflare/server.js +253 -0
  181. package/packages/mcp-servers/dist/cloudflare/server.js.map +1 -0
  182. package/packages/mcp-servers/dist/cloudflare/types.d.ts +141 -0
  183. package/packages/mcp-servers/dist/cloudflare/types.d.ts.map +1 -0
  184. package/packages/mcp-servers/dist/cloudflare/types.js +53 -0
  185. package/packages/mcp-servers/dist/cloudflare/types.js.map +1 -0
  186. package/packages/mcp-servers/dist/codecov/index.d.ts +7 -0
  187. package/packages/mcp-servers/dist/codecov/index.d.ts.map +1 -0
  188. package/packages/mcp-servers/dist/codecov/index.js +7 -0
  189. package/packages/mcp-servers/dist/codecov/index.js.map +1 -0
  190. package/packages/mcp-servers/dist/codecov/server.d.ts +21 -0
  191. package/packages/mcp-servers/dist/codecov/server.d.ts.map +1 -0
  192. package/packages/mcp-servers/dist/codecov/server.js +376 -0
  193. package/packages/mcp-servers/dist/codecov/server.js.map +1 -0
  194. package/packages/mcp-servers/dist/codecov/types.d.ts +269 -0
  195. package/packages/mcp-servers/dist/codecov/types.d.ts.map +1 -0
  196. package/packages/mcp-servers/dist/codecov/types.js +128 -0
  197. package/packages/mcp-servers/dist/codecov/types.js.map +1 -0
  198. package/packages/mcp-servers/dist/cto-report/index.d.ts +9 -0
  199. package/packages/mcp-servers/dist/cto-report/index.d.ts.map +1 -0
  200. package/packages/mcp-servers/dist/cto-report/index.js +9 -0
  201. package/packages/mcp-servers/dist/cto-report/index.js.map +1 -0
  202. package/packages/mcp-servers/dist/cto-report/server.d.ts +14 -0
  203. package/packages/mcp-servers/dist/cto-report/server.d.ts.map +1 -0
  204. package/packages/mcp-servers/dist/cto-report/server.js +859 -0
  205. package/packages/mcp-servers/dist/cto-report/server.js.map +1 -0
  206. package/packages/mcp-servers/dist/cto-report/types.d.ts +213 -0
  207. package/packages/mcp-servers/dist/cto-report/types.d.ts.map +1 -0
  208. package/packages/mcp-servers/dist/cto-report/types.js +29 -0
  209. package/packages/mcp-servers/dist/cto-report/types.js.map +1 -0
  210. package/packages/mcp-servers/dist/cto-reports/index.d.ts +7 -0
  211. package/packages/mcp-servers/dist/cto-reports/index.d.ts.map +1 -0
  212. package/packages/mcp-servers/dist/cto-reports/index.js +8 -0
  213. package/packages/mcp-servers/dist/cto-reports/index.js.map +1 -0
  214. package/packages/mcp-servers/dist/cto-reports/server.d.ts +20 -0
  215. package/packages/mcp-servers/dist/cto-reports/server.d.ts.map +1 -0
  216. package/packages/mcp-servers/dist/cto-reports/server.js +538 -0
  217. package/packages/mcp-servers/dist/cto-reports/server.js.map +1 -0
  218. package/packages/mcp-servers/dist/cto-reports/types.d.ts +236 -0
  219. package/packages/mcp-servers/dist/cto-reports/types.d.ts.map +1 -0
  220. package/packages/mcp-servers/dist/cto-reports/types.js +77 -0
  221. package/packages/mcp-servers/dist/cto-reports/types.js.map +1 -0
  222. package/packages/mcp-servers/dist/deputy-cto/index.d.ts +7 -0
  223. package/packages/mcp-servers/dist/deputy-cto/index.d.ts.map +1 -0
  224. package/packages/mcp-servers/dist/deputy-cto/index.js +8 -0
  225. package/packages/mcp-servers/dist/deputy-cto/index.js.map +1 -0
  226. package/packages/mcp-servers/dist/deputy-cto/server.d.ts +23 -0
  227. package/packages/mcp-servers/dist/deputy-cto/server.d.ts.map +1 -0
  228. package/packages/mcp-servers/dist/deputy-cto/server.js +1700 -0
  229. package/packages/mcp-servers/dist/deputy-cto/server.js.map +1 -0
  230. package/packages/mcp-servers/dist/deputy-cto/types.d.ts +439 -0
  231. package/packages/mcp-servers/dist/deputy-cto/types.d.ts.map +1 -0
  232. package/packages/mcp-servers/dist/deputy-cto/types.js +102 -0
  233. package/packages/mcp-servers/dist/deputy-cto/types.js.map +1 -0
  234. package/packages/mcp-servers/dist/elastic-logs/index.d.ts +5 -0
  235. package/packages/mcp-servers/dist/elastic-logs/index.d.ts.map +1 -0
  236. package/packages/mcp-servers/dist/elastic-logs/index.js +5 -0
  237. package/packages/mcp-servers/dist/elastic-logs/index.js.map +1 -0
  238. package/packages/mcp-servers/dist/elastic-logs/server.d.ts +18 -0
  239. package/packages/mcp-servers/dist/elastic-logs/server.d.ts.map +1 -0
  240. package/packages/mcp-servers/dist/elastic-logs/server.js +259 -0
  241. package/packages/mcp-servers/dist/elastic-logs/server.js.map +1 -0
  242. package/packages/mcp-servers/dist/elastic-logs/types.d.ts +107 -0
  243. package/packages/mcp-servers/dist/elastic-logs/types.d.ts.map +1 -0
  244. package/packages/mcp-servers/dist/elastic-logs/types.js +31 -0
  245. package/packages/mcp-servers/dist/elastic-logs/types.js.map +1 -0
  246. package/packages/mcp-servers/dist/feedback-explorer/index.d.ts +2 -0
  247. package/packages/mcp-servers/dist/feedback-explorer/index.d.ts.map +1 -0
  248. package/packages/mcp-servers/dist/feedback-explorer/index.js +2 -0
  249. package/packages/mcp-servers/dist/feedback-explorer/index.js.map +1 -0
  250. package/packages/mcp-servers/dist/feedback-explorer/server.d.ts +21 -0
  251. package/packages/mcp-servers/dist/feedback-explorer/server.d.ts.map +1 -0
  252. package/packages/mcp-servers/dist/feedback-explorer/server.js +580 -0
  253. package/packages/mcp-servers/dist/feedback-explorer/server.js.map +1 -0
  254. package/packages/mcp-servers/dist/feedback-explorer/types.d.ts +331 -0
  255. package/packages/mcp-servers/dist/feedback-explorer/types.d.ts.map +1 -0
  256. package/packages/mcp-servers/dist/feedback-explorer/types.js +40 -0
  257. package/packages/mcp-servers/dist/feedback-explorer/types.js.map +1 -0
  258. package/packages/mcp-servers/dist/feedback-reporter/index.d.ts +9 -0
  259. package/packages/mcp-servers/dist/feedback-reporter/index.d.ts.map +1 -0
  260. package/packages/mcp-servers/dist/feedback-reporter/index.js +9 -0
  261. package/packages/mcp-servers/dist/feedback-reporter/index.js.map +1 -0
  262. package/packages/mcp-servers/dist/feedback-reporter/server.d.ts +36 -0
  263. package/packages/mcp-servers/dist/feedback-reporter/server.d.ts.map +1 -0
  264. package/packages/mcp-servers/dist/feedback-reporter/server.js +392 -0
  265. package/packages/mcp-servers/dist/feedback-reporter/server.js.map +1 -0
  266. package/packages/mcp-servers/dist/feedback-reporter/types.d.ts +152 -0
  267. package/packages/mcp-servers/dist/feedback-reporter/types.d.ts.map +1 -0
  268. package/packages/mcp-servers/dist/feedback-reporter/types.js +67 -0
  269. package/packages/mcp-servers/dist/feedback-reporter/types.js.map +1 -0
  270. package/packages/mcp-servers/dist/github/index.d.ts +7 -0
  271. package/packages/mcp-servers/dist/github/index.d.ts.map +1 -0
  272. package/packages/mcp-servers/dist/github/index.js +7 -0
  273. package/packages/mcp-servers/dist/github/index.js.map +1 -0
  274. package/packages/mcp-servers/dist/github/server.d.ts +15 -0
  275. package/packages/mcp-servers/dist/github/server.d.ts.map +1 -0
  276. package/packages/mcp-servers/dist/github/server.js +686 -0
  277. package/packages/mcp-servers/dist/github/server.js.map +1 -0
  278. package/packages/mcp-servers/dist/github/types.d.ts +660 -0
  279. package/packages/mcp-servers/dist/github/types.d.ts.map +1 -0
  280. package/packages/mcp-servers/dist/github/types.js +209 -0
  281. package/packages/mcp-servers/dist/github/types.js.map +1 -0
  282. package/packages/mcp-servers/dist/index.d.ts +30 -0
  283. package/packages/mcp-servers/dist/index.d.ts.map +1 -0
  284. package/packages/mcp-servers/dist/index.js +32 -0
  285. package/packages/mcp-servers/dist/index.js.map +1 -0
  286. package/packages/mcp-servers/dist/makerkit-docs/index.d.ts +5 -0
  287. package/packages/mcp-servers/dist/makerkit-docs/index.d.ts.map +1 -0
  288. package/packages/mcp-servers/dist/makerkit-docs/index.js +5 -0
  289. package/packages/mcp-servers/dist/makerkit-docs/index.js.map +1 -0
  290. package/packages/mcp-servers/dist/makerkit-docs/server.d.ts +15 -0
  291. package/packages/mcp-servers/dist/makerkit-docs/server.d.ts.map +1 -0
  292. package/packages/mcp-servers/dist/makerkit-docs/server.js +252 -0
  293. package/packages/mcp-servers/dist/makerkit-docs/server.js.map +1 -0
  294. package/packages/mcp-servers/dist/makerkit-docs/types.d.ts +74 -0
  295. package/packages/mcp-servers/dist/makerkit-docs/types.d.ts.map +1 -0
  296. package/packages/mcp-servers/dist/makerkit-docs/types.js +20 -0
  297. package/packages/mcp-servers/dist/makerkit-docs/types.js.map +1 -0
  298. package/packages/mcp-servers/dist/onepassword/index.d.ts +2 -0
  299. package/packages/mcp-servers/dist/onepassword/index.d.ts.map +1 -0
  300. package/packages/mcp-servers/dist/onepassword/index.js +2 -0
  301. package/packages/mcp-servers/dist/onepassword/index.js.map +1 -0
  302. package/packages/mcp-servers/dist/onepassword/server.d.ts +2 -0
  303. package/packages/mcp-servers/dist/onepassword/server.d.ts.map +1 -0
  304. package/packages/mcp-servers/dist/onepassword/server.js +159 -0
  305. package/packages/mcp-servers/dist/onepassword/server.js.map +1 -0
  306. package/packages/mcp-servers/dist/onepassword/types.d.ts +55 -0
  307. package/packages/mcp-servers/dist/onepassword/types.d.ts.map +1 -0
  308. package/packages/mcp-servers/dist/onepassword/types.js +22 -0
  309. package/packages/mcp-servers/dist/onepassword/types.js.map +1 -0
  310. package/packages/mcp-servers/dist/playwright/helpers.d.ts +20 -0
  311. package/packages/mcp-servers/dist/playwright/helpers.d.ts.map +1 -0
  312. package/packages/mcp-servers/dist/playwright/helpers.js +31 -0
  313. package/packages/mcp-servers/dist/playwright/helpers.js.map +1 -0
  314. package/packages/mcp-servers/dist/playwright/index.d.ts +5 -0
  315. package/packages/mcp-servers/dist/playwright/index.d.ts.map +1 -0
  316. package/packages/mcp-servers/dist/playwright/index.js +5 -0
  317. package/packages/mcp-servers/dist/playwright/index.js.map +1 -0
  318. package/packages/mcp-servers/dist/playwright/server.d.ts +13 -0
  319. package/packages/mcp-servers/dist/playwright/server.d.ts.map +1 -0
  320. package/packages/mcp-servers/dist/playwright/server.js +1201 -0
  321. package/packages/mcp-servers/dist/playwright/server.js.map +1 -0
  322. package/packages/mcp-servers/dist/playwright/types.d.ts +216 -0
  323. package/packages/mcp-servers/dist/playwright/types.d.ts.map +1 -0
  324. package/packages/mcp-servers/dist/playwright/types.js +172 -0
  325. package/packages/mcp-servers/dist/playwright/types.js.map +1 -0
  326. package/packages/mcp-servers/dist/playwright-feedback/browser-manager.d.ts +39 -0
  327. package/packages/mcp-servers/dist/playwright-feedback/browser-manager.d.ts.map +1 -0
  328. package/packages/mcp-servers/dist/playwright-feedback/browser-manager.js +71 -0
  329. package/packages/mcp-servers/dist/playwright-feedback/browser-manager.js.map +1 -0
  330. package/packages/mcp-servers/dist/playwright-feedback/index.d.ts +5 -0
  331. package/packages/mcp-servers/dist/playwright-feedback/index.d.ts.map +1 -0
  332. package/packages/mcp-servers/dist/playwright-feedback/index.js +5 -0
  333. package/packages/mcp-servers/dist/playwright-feedback/index.js.map +1 -0
  334. package/packages/mcp-servers/dist/playwright-feedback/server.d.ts +34 -0
  335. package/packages/mcp-servers/dist/playwright-feedback/server.d.ts.map +1 -0
  336. package/packages/mcp-servers/dist/playwright-feedback/server.js +538 -0
  337. package/packages/mcp-servers/dist/playwright-feedback/server.js.map +1 -0
  338. package/packages/mcp-servers/dist/playwright-feedback/types.d.ts +305 -0
  339. package/packages/mcp-servers/dist/playwright-feedback/types.d.ts.map +1 -0
  340. package/packages/mcp-servers/dist/playwright-feedback/types.js +123 -0
  341. package/packages/mcp-servers/dist/playwright-feedback/types.js.map +1 -0
  342. package/packages/mcp-servers/dist/product-manager/server.d.ts +17 -0
  343. package/packages/mcp-servers/dist/product-manager/server.d.ts.map +1 -0
  344. package/packages/mcp-servers/dist/product-manager/server.js +690 -0
  345. package/packages/mcp-servers/dist/product-manager/server.js.map +1 -0
  346. package/packages/mcp-servers/dist/product-manager/types.d.ts +286 -0
  347. package/packages/mcp-servers/dist/product-manager/types.d.ts.map +1 -0
  348. package/packages/mcp-servers/dist/product-manager/types.js +99 -0
  349. package/packages/mcp-servers/dist/product-manager/types.js.map +1 -0
  350. package/packages/mcp-servers/dist/programmatic-feedback/index.d.ts +7 -0
  351. package/packages/mcp-servers/dist/programmatic-feedback/index.d.ts.map +1 -0
  352. package/packages/mcp-servers/dist/programmatic-feedback/index.js +7 -0
  353. package/packages/mcp-servers/dist/programmatic-feedback/index.js.map +1 -0
  354. package/packages/mcp-servers/dist/programmatic-feedback/sandbox.d.ts +19 -0
  355. package/packages/mcp-servers/dist/programmatic-feedback/sandbox.d.ts.map +1 -0
  356. package/packages/mcp-servers/dist/programmatic-feedback/sandbox.js +174 -0
  357. package/packages/mcp-servers/dist/programmatic-feedback/sandbox.js.map +1 -0
  358. package/packages/mcp-servers/dist/programmatic-feedback/server.d.ts +35 -0
  359. package/packages/mcp-servers/dist/programmatic-feedback/server.d.ts.map +1 -0
  360. package/packages/mcp-servers/dist/programmatic-feedback/server.js +465 -0
  361. package/packages/mcp-servers/dist/programmatic-feedback/server.js.map +1 -0
  362. package/packages/mcp-servers/dist/programmatic-feedback/types.d.ts +127 -0
  363. package/packages/mcp-servers/dist/programmatic-feedback/types.d.ts.map +1 -0
  364. package/packages/mcp-servers/dist/programmatic-feedback/types.js +80 -0
  365. package/packages/mcp-servers/dist/programmatic-feedback/types.js.map +1 -0
  366. package/packages/mcp-servers/dist/render/index.d.ts +8 -0
  367. package/packages/mcp-servers/dist/render/index.d.ts.map +1 -0
  368. package/packages/mcp-servers/dist/render/index.js +8 -0
  369. package/packages/mcp-servers/dist/render/index.js.map +1 -0
  370. package/packages/mcp-servers/dist/render/server.d.ts +15 -0
  371. package/packages/mcp-servers/dist/render/server.d.ts.map +1 -0
  372. package/packages/mcp-servers/dist/render/server.js +428 -0
  373. package/packages/mcp-servers/dist/render/server.js.map +1 -0
  374. package/packages/mcp-servers/dist/render/types.d.ts +273 -0
  375. package/packages/mcp-servers/dist/render/types.d.ts.map +1 -0
  376. package/packages/mcp-servers/dist/render/types.js +102 -0
  377. package/packages/mcp-servers/dist/render/types.js.map +1 -0
  378. package/packages/mcp-servers/dist/resend/index.d.ts +7 -0
  379. package/packages/mcp-servers/dist/resend/index.d.ts.map +1 -0
  380. package/packages/mcp-servers/dist/resend/index.js +7 -0
  381. package/packages/mcp-servers/dist/resend/index.js.map +1 -0
  382. package/packages/mcp-servers/dist/resend/server.d.ts +15 -0
  383. package/packages/mcp-servers/dist/resend/server.d.ts.map +1 -0
  384. package/packages/mcp-servers/dist/resend/server.js +298 -0
  385. package/packages/mcp-servers/dist/resend/server.js.map +1 -0
  386. package/packages/mcp-servers/dist/resend/types.d.ts +222 -0
  387. package/packages/mcp-servers/dist/resend/types.d.ts.map +1 -0
  388. package/packages/mcp-servers/dist/resend/types.js +58 -0
  389. package/packages/mcp-servers/dist/resend/types.js.map +1 -0
  390. package/packages/mcp-servers/dist/review-queue/index.d.ts +6 -0
  391. package/packages/mcp-servers/dist/review-queue/index.d.ts.map +1 -0
  392. package/packages/mcp-servers/dist/review-queue/index.js +6 -0
  393. package/packages/mcp-servers/dist/review-queue/index.js.map +1 -0
  394. package/packages/mcp-servers/dist/review-queue/server.d.ts +17 -0
  395. package/packages/mcp-servers/dist/review-queue/server.d.ts.map +1 -0
  396. package/packages/mcp-servers/dist/review-queue/server.js +348 -0
  397. package/packages/mcp-servers/dist/review-queue/server.js.map +1 -0
  398. package/packages/mcp-servers/dist/review-queue/types.d.ts +162 -0
  399. package/packages/mcp-servers/dist/review-queue/types.d.ts.map +1 -0
  400. package/packages/mcp-servers/dist/review-queue/types.js +56 -0
  401. package/packages/mcp-servers/dist/review-queue/types.js.map +1 -0
  402. package/packages/mcp-servers/dist/secret-sync/server.d.ts +19 -0
  403. package/packages/mcp-servers/dist/secret-sync/server.d.ts.map +1 -0
  404. package/packages/mcp-servers/dist/secret-sync/server.js +1139 -0
  405. package/packages/mcp-servers/dist/secret-sync/server.js.map +1 -0
  406. package/packages/mcp-servers/dist/secret-sync/types.d.ts +442 -0
  407. package/packages/mcp-servers/dist/secret-sync/types.d.ts.map +1 -0
  408. package/packages/mcp-servers/dist/secret-sync/types.js +113 -0
  409. package/packages/mcp-servers/dist/secret-sync/types.js.map +1 -0
  410. package/packages/mcp-servers/dist/session-events/index.d.ts +5 -0
  411. package/packages/mcp-servers/dist/session-events/index.d.ts.map +1 -0
  412. package/packages/mcp-servers/dist/session-events/index.js +5 -0
  413. package/packages/mcp-servers/dist/session-events/index.js.map +1 -0
  414. package/packages/mcp-servers/dist/session-events/server.d.ts +11 -0
  415. package/packages/mcp-servers/dist/session-events/server.d.ts.map +1 -0
  416. package/packages/mcp-servers/dist/session-events/server.js +290 -0
  417. package/packages/mcp-servers/dist/session-events/server.js.map +1 -0
  418. package/packages/mcp-servers/dist/session-events/types.d.ts +213 -0
  419. package/packages/mcp-servers/dist/session-events/types.d.ts.map +1 -0
  420. package/packages/mcp-servers/dist/session-events/types.js +69 -0
  421. package/packages/mcp-servers/dist/session-events/types.js.map +1 -0
  422. package/packages/mcp-servers/dist/session-restart/index.d.ts +9 -0
  423. package/packages/mcp-servers/dist/session-restart/index.d.ts.map +1 -0
  424. package/packages/mcp-servers/dist/session-restart/index.js +9 -0
  425. package/packages/mcp-servers/dist/session-restart/index.js.map +1 -0
  426. package/packages/mcp-servers/dist/session-restart/server.d.ts +20 -0
  427. package/packages/mcp-servers/dist/session-restart/server.d.ts.map +1 -0
  428. package/packages/mcp-servers/dist/session-restart/server.js +411 -0
  429. package/packages/mcp-servers/dist/session-restart/server.js.map +1 -0
  430. package/packages/mcp-servers/dist/session-restart/types.d.ts +26 -0
  431. package/packages/mcp-servers/dist/session-restart/types.d.ts.map +1 -0
  432. package/packages/mcp-servers/dist/session-restart/types.js +16 -0
  433. package/packages/mcp-servers/dist/session-restart/types.js.map +1 -0
  434. package/packages/mcp-servers/dist/setup-helper/index.d.ts +5 -0
  435. package/packages/mcp-servers/dist/setup-helper/index.d.ts.map +1 -0
  436. package/packages/mcp-servers/dist/setup-helper/index.js +5 -0
  437. package/packages/mcp-servers/dist/setup-helper/index.js.map +1 -0
  438. package/packages/mcp-servers/dist/setup-helper/server.d.ts +14 -0
  439. package/packages/mcp-servers/dist/setup-helper/server.d.ts.map +1 -0
  440. package/packages/mcp-servers/dist/setup-helper/server.js +454 -0
  441. package/packages/mcp-servers/dist/setup-helper/server.js.map +1 -0
  442. package/packages/mcp-servers/dist/setup-helper/types.d.ts +81 -0
  443. package/packages/mcp-servers/dist/setup-helper/types.d.ts.map +1 -0
  444. package/packages/mcp-servers/dist/setup-helper/types.js +41 -0
  445. package/packages/mcp-servers/dist/setup-helper/types.js.map +1 -0
  446. package/packages/mcp-servers/dist/shared/audited-server.d.ts +31 -0
  447. package/packages/mcp-servers/dist/shared/audited-server.d.ts.map +1 -0
  448. package/packages/mcp-servers/dist/shared/audited-server.js +126 -0
  449. package/packages/mcp-servers/dist/shared/audited-server.js.map +1 -0
  450. package/packages/mcp-servers/dist/shared/constants.d.ts +26 -0
  451. package/packages/mcp-servers/dist/shared/constants.d.ts.map +1 -0
  452. package/packages/mcp-servers/dist/shared/constants.js +41 -0
  453. package/packages/mcp-servers/dist/shared/constants.js.map +1 -0
  454. package/packages/mcp-servers/dist/shared/index.d.ts +6 -0
  455. package/packages/mcp-servers/dist/shared/index.d.ts.map +1 -0
  456. package/packages/mcp-servers/dist/shared/index.js +6 -0
  457. package/packages/mcp-servers/dist/shared/index.js.map +1 -0
  458. package/packages/mcp-servers/dist/shared/readonly-db.d.ts +11 -0
  459. package/packages/mcp-servers/dist/shared/readonly-db.d.ts.map +1 -0
  460. package/packages/mcp-servers/dist/shared/readonly-db.js +47 -0
  461. package/packages/mcp-servers/dist/shared/readonly-db.js.map +1 -0
  462. package/packages/mcp-servers/dist/shared/resolve-framework.d.ts +20 -0
  463. package/packages/mcp-servers/dist/shared/resolve-framework.d.ts.map +1 -0
  464. package/packages/mcp-servers/dist/shared/resolve-framework.js +65 -0
  465. package/packages/mcp-servers/dist/shared/resolve-framework.js.map +1 -0
  466. package/packages/mcp-servers/dist/shared/server.d.ts +86 -0
  467. package/packages/mcp-servers/dist/shared/server.d.ts.map +1 -0
  468. package/packages/mcp-servers/dist/shared/server.js +291 -0
  469. package/packages/mcp-servers/dist/shared/server.js.map +1 -0
  470. package/packages/mcp-servers/dist/shared/types.d.ts +113 -0
  471. package/packages/mcp-servers/dist/shared/types.d.ts.map +1 -0
  472. package/packages/mcp-servers/dist/shared/types.js +36 -0
  473. package/packages/mcp-servers/dist/shared/types.js.map +1 -0
  474. package/packages/mcp-servers/dist/show/server.d.ts +12 -0
  475. package/packages/mcp-servers/dist/show/server.d.ts.map +1 -0
  476. package/packages/mcp-servers/dist/show/server.js +97 -0
  477. package/packages/mcp-servers/dist/show/server.js.map +1 -0
  478. package/packages/mcp-servers/dist/show/types.d.ts +19 -0
  479. package/packages/mcp-servers/dist/show/types.d.ts.map +1 -0
  480. package/packages/mcp-servers/dist/show/types.js +32 -0
  481. package/packages/mcp-servers/dist/show/types.js.map +1 -0
  482. package/packages/mcp-servers/dist/specs-browser/index.d.ts +5 -0
  483. package/packages/mcp-servers/dist/specs-browser/index.d.ts.map +1 -0
  484. package/packages/mcp-servers/dist/specs-browser/index.js +5 -0
  485. package/packages/mcp-servers/dist/specs-browser/index.js.map +1 -0
  486. package/packages/mcp-servers/dist/specs-browser/server.d.ts +13 -0
  487. package/packages/mcp-servers/dist/specs-browser/server.d.ts.map +1 -0
  488. package/packages/mcp-servers/dist/specs-browser/server.js +692 -0
  489. package/packages/mcp-servers/dist/specs-browser/server.js.map +1 -0
  490. package/packages/mcp-servers/dist/specs-browser/types.d.ts +337 -0
  491. package/packages/mcp-servers/dist/specs-browser/types.d.ts.map +1 -0
  492. package/packages/mcp-servers/dist/specs-browser/types.js +134 -0
  493. package/packages/mcp-servers/dist/specs-browser/types.js.map +1 -0
  494. package/packages/mcp-servers/dist/supabase/index.d.ts +10 -0
  495. package/packages/mcp-servers/dist/supabase/index.d.ts.map +1 -0
  496. package/packages/mcp-servers/dist/supabase/index.js +10 -0
  497. package/packages/mcp-servers/dist/supabase/index.js.map +1 -0
  498. package/packages/mcp-servers/dist/supabase/server.d.ts +20 -0
  499. package/packages/mcp-servers/dist/supabase/server.d.ts.map +1 -0
  500. package/packages/mcp-servers/dist/supabase/server.js +451 -0
  501. package/packages/mcp-servers/dist/supabase/server.js.map +1 -0
  502. package/packages/mcp-servers/dist/supabase/types.d.ts +196 -0
  503. package/packages/mcp-servers/dist/supabase/types.d.ts.map +1 -0
  504. package/packages/mcp-servers/dist/supabase/types.js +76 -0
  505. package/packages/mcp-servers/dist/supabase/types.js.map +1 -0
  506. package/packages/mcp-servers/dist/todo-db/index.d.ts +5 -0
  507. package/packages/mcp-servers/dist/todo-db/index.d.ts.map +1 -0
  508. package/packages/mcp-servers/dist/todo-db/index.js +5 -0
  509. package/packages/mcp-servers/dist/todo-db/index.js.map +1 -0
  510. package/packages/mcp-servers/dist/todo-db/server.d.ts +13 -0
  511. package/packages/mcp-servers/dist/todo-db/server.d.ts.map +1 -0
  512. package/packages/mcp-servers/dist/todo-db/server.js +649 -0
  513. package/packages/mcp-servers/dist/todo-db/server.js.map +1 -0
  514. package/packages/mcp-servers/dist/todo-db/types.d.ts +225 -0
  515. package/packages/mcp-servers/dist/todo-db/types.d.ts.map +1 -0
  516. package/packages/mcp-servers/dist/todo-db/types.js +69 -0
  517. package/packages/mcp-servers/dist/todo-db/types.js.map +1 -0
  518. package/packages/mcp-servers/dist/user-feedback/index.d.ts +7 -0
  519. package/packages/mcp-servers/dist/user-feedback/index.d.ts.map +1 -0
  520. package/packages/mcp-servers/dist/user-feedback/index.js +8 -0
  521. package/packages/mcp-servers/dist/user-feedback/index.js.map +1 -0
  522. package/packages/mcp-servers/dist/user-feedback/server.d.ts +25 -0
  523. package/packages/mcp-servers/dist/user-feedback/server.d.ts.map +1 -0
  524. package/packages/mcp-servers/dist/user-feedback/server.js +914 -0
  525. package/packages/mcp-servers/dist/user-feedback/server.js.map +1 -0
  526. package/packages/mcp-servers/dist/user-feedback/types.d.ts +415 -0
  527. package/packages/mcp-servers/dist/user-feedback/types.d.ts.map +1 -0
  528. package/packages/mcp-servers/dist/user-feedback/types.js +132 -0
  529. package/packages/mcp-servers/dist/user-feedback/types.js.map +1 -0
  530. package/packages/mcp-servers/dist/vercel/index.d.ts +9 -0
  531. package/packages/mcp-servers/dist/vercel/index.d.ts.map +1 -0
  532. package/packages/mcp-servers/dist/vercel/index.js +9 -0
  533. package/packages/mcp-servers/dist/vercel/index.js.map +1 -0
  534. package/packages/mcp-servers/dist/vercel/server.d.ts +17 -0
  535. package/packages/mcp-servers/dist/vercel/server.d.ts.map +1 -0
  536. package/packages/mcp-servers/dist/vercel/server.js +265 -0
  537. package/packages/mcp-servers/dist/vercel/server.js.map +1 -0
  538. package/packages/mcp-servers/dist/vercel/types.d.ts +189 -0
  539. package/packages/mcp-servers/dist/vercel/types.d.ts.map +1 -0
  540. package/packages/mcp-servers/dist/vercel/types.js +65 -0
  541. package/packages/mcp-servers/dist/vercel/types.js.map +1 -0
  542. package/packages/mcp-servers/package-lock.json +3765 -0
  543. package/packages/mcp-servers/package.json +64 -0
  544. package/packages/mcp-servers/test/reporters/test-failure-reporter.ts +372 -0
  545. package/packages/mcp-servers/vitest.config.ts +27 -0
  546. package/scripts/__tests__/README.md +163 -0
  547. package/scripts/apply-credential-hardening.sh +271 -0
  548. package/scripts/credential-providers/manual.js +56 -0
  549. package/scripts/credential-providers/onepassword.js +85 -0
  550. package/scripts/credential-providers/provider-interface.js +104 -0
  551. package/scripts/encrypt-credential.js +337 -0
  552. package/scripts/feedback-launcher.js +338 -0
  553. package/scripts/feedback-orchestrator.js +373 -0
  554. package/scripts/fix-mcp-launcher-issues.sh +97 -0
  555. package/scripts/force-spawn-tasks.js +651 -0
  556. package/scripts/force-triage-reports.js +560 -0
  557. package/scripts/generate-protected-actions-spec.js +142 -0
  558. package/scripts/generate-proxy-certs.sh +158 -0
  559. package/scripts/grant-chrome-ext-permissions.sh +242 -0
  560. package/scripts/mcp-launcher.js +125 -0
  561. package/scripts/merge-settings.cjs +167 -0
  562. package/scripts/patch-clawd.py +844 -0
  563. package/scripts/patch-credential-cache.py +313 -0
  564. package/scripts/patches/credential-file-guard-patched.mjs +573 -0
  565. package/scripts/patches/credential-file-guard.js.patched +573 -0
  566. package/scripts/patches/verify-tokenizer.mjs +132 -0
  567. package/scripts/protect-framework.sh +478 -0
  568. package/scripts/readme-chrome.template +12 -0
  569. package/scripts/reap-completed-agents.js +439 -0
  570. package/scripts/reinstall.sh +86 -0
  571. package/scripts/resign-node.sh +185 -0
  572. package/scripts/rotation-proxy.js +656 -0
  573. package/scripts/rotation-stress-monitor.mjs +862 -0
  574. package/scripts/setup-automation-service.sh +648 -0
  575. package/scripts/setup-check.js +251 -0
  576. package/scripts/watch-claude-version.js +142 -0
  577. package/specs/framework/CORE-INVARIANTS.md +161 -0
  578. package/specs/patterns/AGENT-PATTERNS.md +223 -0
  579. package/specs/patterns/HOOK-PATTERNS.md +242 -0
  580. package/specs/patterns/MCP-SERVER-PATTERNS.md +144 -0
  581. package/templates/config/gitignore.template +14 -0
  582. package/templates/config/merge-chain-check.yml.template +51 -0
  583. package/templates/config/package.json.template +18 -0
  584. package/templates/config/pnpm-workspace.yaml +5 -0
  585. package/templates/config/services.json.template +18 -0
  586. package/templates/config/tsconfig.base.json +17 -0
  587. package/templates/scaffold/integrations/_template/.gitkeep +0 -0
  588. package/templates/scaffold/packages/logger/package.json +17 -0
  589. package/templates/scaffold/packages/logger/src/logger.ts +44 -0
  590. package/templates/scaffold/packages/shared/package.json +17 -0
  591. package/templates/scaffold/packages/shared/src/errors.ts +43 -0
  592. package/templates/scaffold/products/_product/apps/backend/package.json +21 -0
  593. package/templates/scaffold/products/_product/apps/backend/src/index.ts +17 -0
  594. package/templates/scaffold/products/_product/apps/extension/.gitkeep +0 -0
  595. package/templates/scaffold/products/_product/apps/web/.gitkeep +0 -0
  596. package/templates/scaffold/specs/global/.gitkeep +0 -0
  597. package/templates/scaffold/specs/local/.gitkeep +0 -0
  598. package/templates/scaffold/specs/reference/.gitkeep +0 -0
  599. package/version.json +15 -0
@@ -0,0 +1,919 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Agent Tracker MCP Server
4
+ *
5
+ * Tracks all Claude agents spawned by hooks in this project.
6
+ * Provides tools to list agents, view prompts, and access session transcripts.
7
+ * Extended with unified session browser for ALL Claude Code sessions.
8
+ *
9
+ * @version 4.0.0
10
+ */
11
+ import * as fs from 'fs';
12
+ import * as path from 'path';
13
+ import * as os from 'os';
14
+ import { execSync, execFileSync } from 'child_process';
15
+ import { fileURLToPath } from 'url';
16
+ import { McpServer } from '../shared/server.js';
17
+ import { ListSpawnedAgentsArgsSchema, GetAgentPromptArgsSchema, GetAgentSessionArgsSchema, GetAgentStatsArgsSchema, GetConcurrencyStatusArgsSchema, ForceSpawnTasksArgsSchema, ForceTriageReportsArgsSchema, ListSessionsArgsSchema, SearchSessionsArgsSchema, GetSessionSummaryArgsSchema, AGENT_TYPES, } from './types.js';
18
+ // ============================================================================
19
+ // Configuration
20
+ // ============================================================================
21
+ const PROJECT_DIR = path.resolve(process.env.CLAUDE_PROJECT_DIR || process.cwd());
22
+ const TRACKER_FILE = path.join(PROJECT_DIR, '.claude', 'state', 'agent-tracker-history.json');
23
+ const CLAUDE_PROJECTS_DIR = path.join(os.homedir(), '.claude', 'projects');
24
+ const MAX_PROMPT_PREVIEW_LENGTH = 200;
25
+ // ============================================================================
26
+ // Helper Functions
27
+ // ============================================================================
28
+ /**
29
+ * Read the agent history from file
30
+ */
31
+ function readHistory() {
32
+ // G001: File-not-found is different from corruption
33
+ if (!fs.existsSync(TRACKER_FILE)) {
34
+ return { agents: [], stats: {} };
35
+ }
36
+ // File exists - must read successfully or throw (G001: no silent corruption)
37
+ try {
38
+ const content = fs.readFileSync(TRACKER_FILE, 'utf8');
39
+ return JSON.parse(content);
40
+ }
41
+ catch (err) {
42
+ const message = err instanceof Error ? err.message : String(err);
43
+ throw new Error(`[agent-tracker] History file corrupted at ${TRACKER_FILE}: ${message}. Delete file to reset.`);
44
+ }
45
+ }
46
+ /**
47
+ * Find Claude session transcript for a given spawn
48
+ */
49
+ function findSessionFile(agent) {
50
+ if (!agent.projectDir) {
51
+ return null;
52
+ }
53
+ try {
54
+ // Claude stores sessions in ~/.claude/projects/-path-to-project/
55
+ // Normalize path: replace / with - to get leading-dash format (e.g., "-home-user-project")
56
+ const projectPath = agent.projectDir.replace(/[^a-zA-Z0-9]/g, '-');
57
+ const sessionDir = path.join(CLAUDE_PROJECTS_DIR, projectPath);
58
+ if (!fs.existsSync(sessionDir)) {
59
+ // Try alternative path format (without leading dash, for backwards compatibility)
60
+ const altPath = path.join(CLAUDE_PROJECTS_DIR, projectPath.replace(/^-/, ''));
61
+ if (!fs.existsSync(altPath)) {
62
+ return null;
63
+ }
64
+ }
65
+ const actualDir = fs.existsSync(sessionDir)
66
+ ? sessionDir
67
+ : path.join(CLAUDE_PROJECTS_DIR, projectPath.replace(/^-/, ''));
68
+ // List all JSONL files and find one close to spawn time
69
+ const files = fs.readdirSync(actualDir)
70
+ .filter(f => f.endsWith('.jsonl'))
71
+ .map(f => ({
72
+ name: f,
73
+ path: path.join(actualDir, f),
74
+ mtime: fs.statSync(path.join(actualDir, f)).mtime.getTime(),
75
+ }))
76
+ .sort((a, b) => b.mtime - a.mtime);
77
+ if (files.length === 0) {
78
+ return null;
79
+ }
80
+ // Find session file created around spawn time (within 5 minutes)
81
+ const spawnTime = new Date(agent.timestamp).getTime();
82
+ const matchingFile = files.find(f => {
83
+ const diff = Math.abs(f.mtime - spawnTime);
84
+ return diff < 5 * 60 * 1000; // Within 5 minutes
85
+ });
86
+ return matchingFile ? matchingFile.path : files[0].path;
87
+ }
88
+ catch (err) {
89
+ // G001: Log session search errors (non-critical, return null)
90
+ const message = err instanceof Error ? err.message : String(err);
91
+ process.stderr.write(`[agent-tracker] Error finding session file: ${message}\n`);
92
+ return null;
93
+ }
94
+ }
95
+ /**
96
+ * Read and parse a session JSONL file
97
+ */
98
+ function readSessionFile(filePath) {
99
+ // G001: File read errors should be logged, not silently ignored
100
+ if (!fs.existsSync(filePath)) {
101
+ return [];
102
+ }
103
+ try {
104
+ const content = fs.readFileSync(filePath, 'utf8');
105
+ const lines = content.trim().split('\n');
106
+ const messages = [];
107
+ let parseErrors = 0;
108
+ for (const line of lines) {
109
+ try {
110
+ const parsed = JSON.parse(line);
111
+ messages.push(parsed);
112
+ }
113
+ catch {
114
+ // JSONL files may have occasional malformed lines - count but don't fail
115
+ parseErrors++;
116
+ }
117
+ }
118
+ // Log if significant parse failures (>10%)
119
+ if (parseErrors > 0 && parseErrors > lines.length * 0.1) {
120
+ process.stderr.write(`[agent-tracker] Warning: ${parseErrors}/${lines.length} lines failed to parse in ${filePath}\n`);
121
+ }
122
+ return messages;
123
+ }
124
+ catch (err) {
125
+ // G001: Log file read errors
126
+ const message = err instanceof Error ? err.message : String(err);
127
+ process.stderr.write(`[agent-tracker] Error reading session file ${filePath}: ${message}\n`);
128
+ return [];
129
+ }
130
+ }
131
+ /**
132
+ * Format session messages for display
133
+ */
134
+ function formatSession(messages) {
135
+ const formatted = {
136
+ messageCount: messages.length,
137
+ summary: {
138
+ userMessages: 0,
139
+ assistantMessages: 0,
140
+ toolResults: 0,
141
+ totalMessages: messages.length,
142
+ },
143
+ messages: [],
144
+ };
145
+ for (const msg of messages) {
146
+ const entry = {
147
+ type: msg.type ?? 'unknown',
148
+ timestamp: msg.timestamp ?? null,
149
+ };
150
+ if (msg.type === 'human' || msg.type === 'user') {
151
+ entry.role = 'user';
152
+ entry.content = typeof msg.message?.content === 'string'
153
+ ? msg.message.content
154
+ : (msg.content ?? '[no content]');
155
+ formatted.summary.userMessages++;
156
+ }
157
+ else if (msg.type === 'assistant') {
158
+ entry.role = 'assistant';
159
+ // Extract text content from assistant messages
160
+ if (Array.isArray(msg.message?.content)) {
161
+ entry.content = msg.message.content
162
+ .filter((c) => c.type === 'text' && typeof c.text === 'string')
163
+ .map(c => c.text)
164
+ .join('\n');
165
+ entry.toolCalls = msg.message.content
166
+ .filter((c) => c.type === 'tool_use' && typeof c.name === 'string' && typeof c.id === 'string')
167
+ .map(c => ({ name: c.name, id: c.id }));
168
+ }
169
+ else {
170
+ entry.content = typeof msg.message?.content === 'string'
171
+ ? msg.message.content
172
+ : (msg.content ?? '[no content]');
173
+ }
174
+ formatted.summary.assistantMessages++;
175
+ }
176
+ else if (msg.type === 'tool_result') {
177
+ entry.role = 'tool_result';
178
+ entry.toolId = msg.tool_use_id;
179
+ entry.content = typeof msg.content === 'string'
180
+ ? msg.content.substring(0, 500) + (msg.content.length > 500 ? '...' : '')
181
+ : '[complex content]';
182
+ formatted.summary.toolResults++;
183
+ }
184
+ formatted.messages.push(entry);
185
+ }
186
+ return formatted;
187
+ }
188
+ /**
189
+ * Discover all session files for the current project
190
+ */
191
+ function discoverSessions() {
192
+ try {
193
+ // Normalize path: replace / with - to get leading-dash format (e.g., "-home-user-project")
194
+ const projectPath = PROJECT_DIR.replace(/[^a-zA-Z0-9]/g, '-');
195
+ const sessionDir = path.join(CLAUDE_PROJECTS_DIR, projectPath);
196
+ if (!fs.existsSync(sessionDir)) {
197
+ // Try alternative path format (without leading dash, for backwards compatibility)
198
+ const altPath = path.join(CLAUDE_PROJECTS_DIR, projectPath.replace(/^-/, ''));
199
+ if (!fs.existsSync(altPath)) {
200
+ return [];
201
+ }
202
+ }
203
+ const actualDir = fs.existsSync(sessionDir)
204
+ ? sessionDir
205
+ : path.join(CLAUDE_PROJECTS_DIR, projectPath.replace(/^-/, ''));
206
+ const files = fs.readdirSync(actualDir);
207
+ const sessions = [];
208
+ for (const f of files) {
209
+ // Only top-level JSONL files (not in subdirectories)
210
+ if (!f.endsWith('.jsonl')) {
211
+ continue;
212
+ }
213
+ const filePath = path.join(actualDir, f);
214
+ try {
215
+ const stats = fs.statSync(filePath);
216
+ if (stats.isFile()) {
217
+ sessions.push({
218
+ session_id: f.replace('.jsonl', ''),
219
+ file_path: filePath,
220
+ mtime: stats.mtime,
221
+ size_bytes: stats.size,
222
+ });
223
+ }
224
+ }
225
+ catch {
226
+ // Skip files we can't stat
227
+ }
228
+ }
229
+ return sessions;
230
+ }
231
+ catch (err) {
232
+ const message = err instanceof Error ? err.message : String(err);
233
+ process.stderr.write(`[agent-tracker] Error discovering sessions: ${message}\n`);
234
+ return [];
235
+ }
236
+ }
237
+ /**
238
+ * Match a session to a hook-spawned agent using timestamp proximity
239
+ */
240
+ function matchSessionToHook(session, agentHistory) {
241
+ const sessionTime = session.mtime.getTime();
242
+ // Find agent spawned within 5 minutes of session modification
243
+ const match = agentHistory.find(agent => {
244
+ const agentTime = new Date(agent.timestamp).getTime();
245
+ return Math.abs(sessionTime - agentTime) < 5 * 60 * 1000;
246
+ });
247
+ if (!match) {
248
+ return null;
249
+ }
250
+ return {
251
+ agent_id: match.id,
252
+ type: match.type,
253
+ hook_type: match.hookType,
254
+ description: match.description,
255
+ };
256
+ }
257
+ /**
258
+ * Read session file lines (for searching)
259
+ */
260
+ function readSessionLines(filePath) {
261
+ if (!fs.existsSync(filePath)) {
262
+ return [];
263
+ }
264
+ try {
265
+ const content = fs.readFileSync(filePath, 'utf8');
266
+ const lines = content.split('\n');
267
+ const result = [];
268
+ for (let i = 0; i < lines.length; i++) {
269
+ if (lines[i].trim()) {
270
+ result.push({ line: lines[i], lineNum: i + 1 });
271
+ }
272
+ }
273
+ return result;
274
+ }
275
+ catch (err) {
276
+ const message = err instanceof Error ? err.message : String(err);
277
+ process.stderr.write(`[agent-tracker] Error reading session: ${message}\n`);
278
+ return [];
279
+ }
280
+ }
281
+ /**
282
+ * Get message type from parsed session entry
283
+ */
284
+ function getMessageType(entry) {
285
+ if (entry.type === 'human' || entry.type === 'user') {
286
+ return 'user';
287
+ }
288
+ if (entry.type === 'assistant') {
289
+ return 'assistant';
290
+ }
291
+ if (entry.type === 'tool_result') {
292
+ return 'tool_result';
293
+ }
294
+ return 'unknown';
295
+ }
296
+ // ============================================================================
297
+ // Tool Implementations
298
+ // ============================================================================
299
+ /**
300
+ * List all spawned agents
301
+ */
302
+ function listAgents(args) {
303
+ const history = readHistory();
304
+ let agents = history.agents ?? [];
305
+ // Apply filters
306
+ if (args.type) {
307
+ agents = agents.filter(a => a.type === args.type);
308
+ }
309
+ if (args.hookType) {
310
+ agents = agents.filter(a => a.hookType === args.hookType);
311
+ }
312
+ if (args.since) {
313
+ const sinceDate = new Date(args.since);
314
+ agents = agents.filter(a => new Date(a.timestamp) >= sinceDate);
315
+ }
316
+ const limit = args.limit ?? 50;
317
+ agents = agents.slice(0, limit);
318
+ // Format for display
319
+ const formatted = agents.map((a, index) => ({
320
+ id: a.id,
321
+ index,
322
+ type: a.type,
323
+ hookType: a.hookType,
324
+ description: a.description,
325
+ timestamp: a.timestamp,
326
+ promptPreview: a.prompt
327
+ ? a.prompt.substring(0, MAX_PROMPT_PREVIEW_LENGTH) +
328
+ (a.prompt.length > MAX_PROMPT_PREVIEW_LENGTH ? '...' : '')
329
+ : '[no prompt stored]',
330
+ hasSession: Boolean(findSessionFile(a)),
331
+ pid: a.pid,
332
+ status: a.status,
333
+ reapedAt: a.reapedAt,
334
+ reapReason: a.reapReason,
335
+ }));
336
+ return {
337
+ total: formatted.length,
338
+ agents: formatted,
339
+ availableTypes: Object.values(AGENT_TYPES),
340
+ };
341
+ }
342
+ /**
343
+ * Get full prompt for an agent
344
+ */
345
+ function getAgentPrompt(args) {
346
+ const history = readHistory();
347
+ const agent = history.agents.find(a => a.id === args.agentId);
348
+ if (!agent) {
349
+ return { error: `Agent not found: ${args.agentId}` };
350
+ }
351
+ return {
352
+ id: agent.id,
353
+ type: agent.type,
354
+ hookType: agent.hookType,
355
+ description: agent.description,
356
+ timestamp: agent.timestamp,
357
+ prompt: agent.prompt ?? '[no prompt stored]',
358
+ promptLength: agent.prompt ? agent.prompt.length : 0,
359
+ metadata: agent.metadata ?? {},
360
+ };
361
+ }
362
+ /**
363
+ * Get session transcript for an agent
364
+ */
365
+ function getAgentSession(args) {
366
+ const history = readHistory();
367
+ const agent = history.agents.find(a => a.id === args.agentId);
368
+ if (!agent) {
369
+ return { error: `Agent not found: ${args.agentId}` };
370
+ }
371
+ const sessionPath = findSessionFile(agent);
372
+ if (!sessionPath) {
373
+ return {
374
+ id: agent.id,
375
+ type: agent.type,
376
+ description: agent.description,
377
+ timestamp: agent.timestamp,
378
+ session: null,
379
+ sessionPath: null,
380
+ message: 'No session file found. Session may have been cleaned up or not yet created.',
381
+ };
382
+ }
383
+ const messages = readSessionFile(sessionPath);
384
+ const formatted = formatSession(messages);
385
+ // Limit messages if requested
386
+ const limit = args.limit ?? 100;
387
+ if (formatted.messages.length > limit) {
388
+ formatted.messages = formatted.messages.slice(0, limit);
389
+ formatted.truncated = true;
390
+ }
391
+ return {
392
+ id: agent.id,
393
+ type: agent.type,
394
+ description: agent.description,
395
+ timestamp: agent.timestamp,
396
+ sessionPath,
397
+ session: formatted,
398
+ };
399
+ }
400
+ /**
401
+ * Get statistics about spawned agents
402
+ */
403
+ function getAgentStats() {
404
+ const history = readHistory();
405
+ const agents = history.agents ?? [];
406
+ const stats = {
407
+ totalSpawns: agents.length,
408
+ byType: {},
409
+ byHookType: {},
410
+ last24Hours: 0,
411
+ last7Days: 0,
412
+ oldestSpawn: null,
413
+ newestSpawn: null,
414
+ byStatus: {},
415
+ totalReaped: 0,
416
+ };
417
+ const now = Date.now();
418
+ const day = 24 * 60 * 60 * 1000;
419
+ for (const agent of agents) {
420
+ // Count by type
421
+ stats.byType[agent.type] = (stats.byType[agent.type] || 0) + 1;
422
+ // Count by hook type
423
+ stats.byHookType[agent.hookType] = (stats.byHookType[agent.hookType] || 0) + 1;
424
+ // Count by status (running/completed/reaped)
425
+ if (agent.status) {
426
+ stats.byStatus[agent.status] = (stats.byStatus[agent.status] || 0) + 1;
427
+ if (agent.status === 'reaped') {
428
+ stats.totalReaped++;
429
+ }
430
+ }
431
+ // Time-based stats
432
+ const spawnTime = new Date(agent.timestamp).getTime();
433
+ if (now - spawnTime < day) {
434
+ stats.last24Hours++;
435
+ }
436
+ if (now - spawnTime < 7 * day) {
437
+ stats.last7Days++;
438
+ }
439
+ // Track oldest/newest
440
+ if (!stats.oldestSpawn || spawnTime < new Date(stats.oldestSpawn).getTime()) {
441
+ stats.oldestSpawn = agent.timestamp;
442
+ }
443
+ if (!stats.newestSpawn || spawnTime > new Date(stats.newestSpawn).getTime()) {
444
+ stats.newestSpawn = agent.timestamp;
445
+ }
446
+ }
447
+ return stats;
448
+ }
449
+ // ============================================================================
450
+ // Session Browser Tool Implementations
451
+ // ============================================================================
452
+ /**
453
+ * List all sessions with optional hook metadata annotation
454
+ */
455
+ function listSessions(args) {
456
+ const history = readHistory();
457
+ const agentHistory = history.agents ?? [];
458
+ // Discover all sessions
459
+ let sessions = discoverSessions();
460
+ // Apply time filters - explicit 'since' overrides maxAgeDays
461
+ if (args.since) {
462
+ const sinceDate = new Date(args.since);
463
+ sessions = sessions.filter(s => s.mtime >= sinceDate);
464
+ }
465
+ else if (args.maxAgeDays && args.maxAgeDays > 0) {
466
+ // Default: only include sessions from last N days (performance optimization)
467
+ const cutoffDate = new Date(Date.now() - args.maxAgeDays * 24 * 60 * 60 * 1000);
468
+ sessions = sessions.filter(s => s.mtime >= cutoffDate);
469
+ }
470
+ if (args.before) {
471
+ const beforeDate = new Date(args.before);
472
+ sessions = sessions.filter(s => s.mtime <= beforeDate);
473
+ }
474
+ // Match sessions to hooks and build enriched list
475
+ const enriched = sessions.map(s => ({
476
+ ...s,
477
+ hook_info: matchSessionToHook(s, agentHistory) ?? undefined,
478
+ }));
479
+ // Apply filter (all, hook-spawned, manual)
480
+ let filtered = enriched;
481
+ if (args.filter === 'hook-spawned') {
482
+ filtered = enriched.filter(s => s.hook_info !== undefined);
483
+ }
484
+ else if (args.filter === 'manual') {
485
+ filtered = enriched.filter(s => s.hook_info === undefined);
486
+ }
487
+ // Apply hookType filter if specified
488
+ if (args.hookType) {
489
+ filtered = filtered.filter(s => s.hook_info?.hook_type === args.hookType);
490
+ }
491
+ // Sort
492
+ const sortBy = args.sortBy ?? 'newest';
493
+ if (sortBy === 'newest') {
494
+ filtered.sort((a, b) => b.mtime.getTime() - a.mtime.getTime());
495
+ }
496
+ else if (sortBy === 'oldest') {
497
+ filtered.sort((a, b) => a.mtime.getTime() - b.mtime.getTime());
498
+ }
499
+ else if (sortBy === 'largest') {
500
+ filtered.sort((a, b) => b.size_bytes - a.size_bytes);
501
+ }
502
+ // Pagination
503
+ const offset = args.offset ?? 0;
504
+ const limit = args.limit ?? 50;
505
+ const total = filtered.length;
506
+ const paginated = filtered.slice(offset, offset + limit);
507
+ // Format result
508
+ const sessionList = paginated.map(s => ({
509
+ session_id: s.session_id,
510
+ file_path: s.file_path,
511
+ mtime: s.mtime.toISOString(),
512
+ size_bytes: s.size_bytes,
513
+ hook_info: s.hook_info,
514
+ }));
515
+ return {
516
+ total,
517
+ sessions: sessionList,
518
+ offset,
519
+ limit,
520
+ hasMore: offset + limit < total,
521
+ };
522
+ }
523
+ /**
524
+ * Search across session content
525
+ */
526
+ function searchSessions(args) {
527
+ const history = readHistory();
528
+ const agentHistory = history.agents ?? [];
529
+ const query = args.query.toLowerCase();
530
+ const limit = args.limit ?? 20;
531
+ // Discover and filter sessions
532
+ let sessions = discoverSessions();
533
+ // Apply time filters - explicit 'since' overrides maxAgeDays
534
+ if (args.since) {
535
+ const sinceDate = new Date(args.since);
536
+ sessions = sessions.filter(s => s.mtime >= sinceDate);
537
+ }
538
+ else if (args.maxAgeDays && args.maxAgeDays > 0) {
539
+ // Default: only search sessions from last N days (major performance optimization)
540
+ const cutoffDate = new Date(Date.now() - args.maxAgeDays * 24 * 60 * 60 * 1000);
541
+ sessions = sessions.filter(s => s.mtime >= cutoffDate);
542
+ }
543
+ // Match sessions to hooks
544
+ const enriched = sessions.map(s => ({
545
+ ...s,
546
+ hook_info: matchSessionToHook(s, agentHistory) ?? undefined,
547
+ }));
548
+ // Apply filter
549
+ let filtered = enriched;
550
+ if (args.filter === 'hook-spawned') {
551
+ filtered = enriched.filter(s => s.hook_info !== undefined);
552
+ }
553
+ else if (args.filter === 'manual') {
554
+ filtered = enriched.filter(s => s.hook_info === undefined);
555
+ }
556
+ if (args.hookType) {
557
+ filtered = filtered.filter(s => s.hook_info?.hook_type === args.hookType);
558
+ }
559
+ // Sort by newest first for search
560
+ filtered.sort((a, b) => b.mtime.getTime() - a.mtime.getTime());
561
+ const results = [];
562
+ let totalMatches = 0;
563
+ // Search through sessions
564
+ for (const session of filtered) {
565
+ if (results.length >= limit) {
566
+ break;
567
+ }
568
+ const matches = [];
569
+ for (const { line, lineNum } of readSessionLines(session.file_path)) {
570
+ if (line.toLowerCase().includes(query)) {
571
+ try {
572
+ const parsed = JSON.parse(line);
573
+ const messageType = getMessageType(parsed);
574
+ // Extract content for preview
575
+ const content = (() => {
576
+ if (typeof parsed.message?.content === 'string') {
577
+ return parsed.message.content;
578
+ }
579
+ if (Array.isArray(parsed.message?.content)) {
580
+ return parsed.message.content
581
+ .filter((c) => c.type === 'text')
582
+ .map(c => c.text)
583
+ .join(' ');
584
+ }
585
+ if (typeof parsed.content === 'string') {
586
+ return parsed.content;
587
+ }
588
+ return '';
589
+ })();
590
+ // Find the match position and create preview
591
+ const lowerContent = content.toLowerCase();
592
+ const matchIndex = lowerContent.indexOf(query);
593
+ const start = Math.max(0, matchIndex - 50);
594
+ const end = Math.min(content.length, matchIndex + query.length + 50);
595
+ const preview = (start > 0 ? '...' : '') +
596
+ content.substring(start, end) +
597
+ (end < content.length ? '...' : '');
598
+ matches.push({
599
+ line_number: lineNum,
600
+ content_preview: preview || '[match in metadata]',
601
+ message_type: messageType,
602
+ });
603
+ totalMatches++;
604
+ // Limit matches per session for performance
605
+ if (matches.length >= 10) {
606
+ break;
607
+ }
608
+ }
609
+ catch {
610
+ // Skip unparseable lines
611
+ }
612
+ }
613
+ }
614
+ if (matches.length > 0) {
615
+ results.push({
616
+ session_id: session.session_id,
617
+ file_path: session.file_path,
618
+ mtime: session.mtime.toISOString(),
619
+ matches,
620
+ hook_info: session.hook_info,
621
+ });
622
+ }
623
+ }
624
+ return {
625
+ query: args.query,
626
+ total_sessions: results.length,
627
+ total_matches: totalMatches,
628
+ results,
629
+ };
630
+ }
631
+ /**
632
+ * Get detailed summary of a specific session
633
+ */
634
+ function getSessionSummary(args) {
635
+ const history = readHistory();
636
+ const agentHistory = history.agents ?? [];
637
+ // Find the session file
638
+ const sessions = discoverSessions();
639
+ const session = sessions.find(s => s.session_id === args.session_id);
640
+ if (!session) {
641
+ return { error: `Session not found: ${args.session_id}` };
642
+ }
643
+ // Get hook info
644
+ const hookInfo = matchSessionToHook(session, agentHistory) ?? undefined;
645
+ // Parse session content
646
+ const messages = readSessionFile(session.file_path);
647
+ const messageCounts = {
648
+ user: 0,
649
+ assistant: 0,
650
+ tool_result: 0,
651
+ other: 0,
652
+ };
653
+ const toolsUsed = new Set();
654
+ let firstTimestamp = null;
655
+ let lastTimestamp = null;
656
+ let firstUserMessage;
657
+ for (const msg of messages) {
658
+ const msgType = getMessageType(msg);
659
+ // Count message types
660
+ if (msgType === 'user') {
661
+ messageCounts.user++;
662
+ // Capture first user message
663
+ if (!firstUserMessage) {
664
+ if (typeof msg.message?.content === 'string') {
665
+ firstUserMessage = msg.message.content.substring(0, 200) +
666
+ (msg.message.content.length > 200 ? '...' : '');
667
+ }
668
+ else if (typeof msg.content === 'string') {
669
+ firstUserMessage = msg.content.substring(0, 200) +
670
+ (msg.content.length > 200 ? '...' : '');
671
+ }
672
+ }
673
+ }
674
+ else if (msgType === 'assistant') {
675
+ messageCounts.assistant++;
676
+ // Extract tool calls
677
+ if (Array.isArray(msg.message?.content)) {
678
+ for (const c of msg.message.content) {
679
+ if (c.type === 'tool_use' && typeof c.name === 'string') {
680
+ toolsUsed.add(c.name);
681
+ }
682
+ }
683
+ }
684
+ }
685
+ else if (msgType === 'tool_result') {
686
+ messageCounts.tool_result++;
687
+ }
688
+ else {
689
+ messageCounts.other++;
690
+ }
691
+ // Track timestamps
692
+ if (msg.timestamp) {
693
+ if (!firstTimestamp) {
694
+ firstTimestamp = msg.timestamp;
695
+ }
696
+ lastTimestamp = msg.timestamp;
697
+ }
698
+ }
699
+ // Calculate duration estimate
700
+ let durationEstimate;
701
+ if (firstTimestamp && lastTimestamp) {
702
+ const first = new Date(firstTimestamp).getTime();
703
+ const last = new Date(lastTimestamp).getTime();
704
+ const durationMs = last - first;
705
+ if (durationMs > 0) {
706
+ const minutes = Math.floor(durationMs / 60000);
707
+ const seconds = Math.floor((durationMs % 60000) / 1000);
708
+ if (minutes > 60) {
709
+ const hours = Math.floor(minutes / 60);
710
+ durationEstimate = `${hours}h ${minutes % 60}m`;
711
+ }
712
+ else if (minutes > 0) {
713
+ durationEstimate = `${minutes}m ${seconds}s`;
714
+ }
715
+ else {
716
+ durationEstimate = `${seconds}s`;
717
+ }
718
+ }
719
+ }
720
+ return {
721
+ session_id: session.session_id,
722
+ file_path: session.file_path,
723
+ mtime: session.mtime.toISOString(),
724
+ size_bytes: session.size_bytes,
725
+ message_counts: messageCounts,
726
+ tools_used: Array.from(toolsUsed).sort(),
727
+ duration_estimate: durationEstimate,
728
+ hook_info: hookInfo,
729
+ first_user_message: firstUserMessage,
730
+ };
731
+ }
732
+ // ============================================================================
733
+ // Concurrency & Force-Spawn Tool Implementations
734
+ // ============================================================================
735
+ /**
736
+ * Get real-time concurrency status: running agents, max allowed, available slots
737
+ */
738
+ function getConcurrencyStatus(_args) {
739
+ // Count running agents via pgrep (same pattern as force-spawn-tasks.js)
740
+ let running = 0;
741
+ try {
742
+ const result = execSync("pgrep -cf 'claude.*--dangerously-skip-permissions'", { encoding: 'utf8', timeout: 5000, stdio: 'pipe' }).trim();
743
+ running = parseInt(result, 10) || 0;
744
+ }
745
+ catch {
746
+ // pgrep returns exit code 1 when no processes match
747
+ }
748
+ // Read max concurrent from automation-config.json
749
+ let maxConcurrent = 10;
750
+ const automationConfigPath = path.join(PROJECT_DIR, '.claude', 'state', 'automation-config.json');
751
+ try {
752
+ const config = JSON.parse(fs.readFileSync(automationConfigPath, 'utf8'));
753
+ if (config?.effective?.MAX_CONCURRENT_AGENTS) {
754
+ maxConcurrent = config.effective.MAX_CONCURRENT_AGENTS;
755
+ }
756
+ }
757
+ catch {
758
+ // Fall back to default
759
+ }
760
+ // Read agent-tracker-history.json, count agents with status === 'running' by type
761
+ const history = readHistory();
762
+ const trackedByType = {};
763
+ for (const agent of history.agents ?? []) {
764
+ if (agent.status === 'running') {
765
+ trackedByType[agent.type] = (trackedByType[agent.type] || 0) + 1;
766
+ }
767
+ }
768
+ return {
769
+ running,
770
+ maxConcurrent,
771
+ available: Math.max(0, maxConcurrent - running),
772
+ trackedRunning: { byType: trackedByType },
773
+ };
774
+ }
775
+ /**
776
+ * Force-spawn pending tasks by wrapping the existing force-spawn-tasks.js script
777
+ */
778
+ function forceSpawnTasks(args) {
779
+ // Derive framework path from import.meta.url
780
+ // Compiled path: <framework>/packages/mcp-servers/dist/agent-tracker/server.js
781
+ // Navigate up 4 levels to reach framework root
782
+ const thisFile = fileURLToPath(import.meta.url);
783
+ const frameworkRoot = path.resolve(path.dirname(thisFile), '..', '..', '..', '..');
784
+ const scriptPath = path.join(frameworkRoot, 'scripts', 'force-spawn-tasks.js');
785
+ if (!fs.existsSync(scriptPath)) {
786
+ return { error: `force-spawn-tasks.js not found at ${scriptPath}. Framework root resolved to: ${frameworkRoot}` };
787
+ }
788
+ try {
789
+ const output = execFileSync('node', [
790
+ scriptPath,
791
+ '--sections', args.sections.join(','),
792
+ '--project-dir', PROJECT_DIR,
793
+ '--max-concurrent', String(args.maxConcurrent),
794
+ ], {
795
+ encoding: 'utf8',
796
+ timeout: 120000,
797
+ env: { ...process.env, CLAUDE_PROJECT_DIR: PROJECT_DIR },
798
+ });
799
+ return JSON.parse(output.trim());
800
+ }
801
+ catch (err) {
802
+ // Attempt to parse stdout from the error (script may have written partial results)
803
+ const execErr = err;
804
+ if (execErr.stdout) {
805
+ try {
806
+ return JSON.parse(execErr.stdout.trim());
807
+ }
808
+ catch {
809
+ // Fall through to error return
810
+ }
811
+ }
812
+ return { error: `force-spawn-tasks.js failed: ${execErr.message ?? String(err)}` };
813
+ }
814
+ }
815
+ function forceTriageReports() {
816
+ const thisFile = fileURLToPath(import.meta.url);
817
+ const frameworkRoot = path.resolve(path.dirname(thisFile), '..', '..', '..', '..');
818
+ const scriptPath = path.join(frameworkRoot, 'scripts', 'force-triage-reports.js');
819
+ if (!fs.existsSync(scriptPath)) {
820
+ return { error: `force-triage-reports.js not found at ${scriptPath}. Framework root resolved to: ${frameworkRoot}` };
821
+ }
822
+ try {
823
+ const output = execFileSync('node', [
824
+ scriptPath,
825
+ '--project-dir', PROJECT_DIR,
826
+ ], {
827
+ encoding: 'utf8',
828
+ timeout: 120000,
829
+ env: { ...process.env, CLAUDE_PROJECT_DIR: PROJECT_DIR },
830
+ });
831
+ return JSON.parse(output.trim());
832
+ }
833
+ catch (err) {
834
+ const execErr = err;
835
+ if (execErr.stdout) {
836
+ try {
837
+ return JSON.parse(execErr.stdout.trim());
838
+ }
839
+ catch {
840
+ // Fall through to error return
841
+ }
842
+ }
843
+ return { error: `force-triage-reports.js failed: ${execErr.message ?? String(err)}` };
844
+ }
845
+ }
846
+ // ============================================================================
847
+ // Server Setup
848
+ // ============================================================================
849
+ const tools = [
850
+ {
851
+ name: 'list_spawned_agents',
852
+ description: 'List all Claude agents spawned by hooks. Returns agent ID, type, description, timestamp, and prompt preview.',
853
+ schema: ListSpawnedAgentsArgsSchema,
854
+ handler: listAgents,
855
+ },
856
+ {
857
+ name: 'get_agent_prompt',
858
+ description: 'Get the full prompt that was given to a spawned agent',
859
+ schema: GetAgentPromptArgsSchema,
860
+ handler: getAgentPrompt,
861
+ },
862
+ {
863
+ name: 'get_agent_session',
864
+ description: 'Get the full session transcript for a spawned agent (if available). Sessions are stored in ~/.claude/projects/ as JSONL files.',
865
+ schema: GetAgentSessionArgsSchema,
866
+ handler: getAgentSession,
867
+ },
868
+ {
869
+ name: 'get_agent_stats',
870
+ description: 'Get statistics about spawned agents: totals by type, by hook, and time-based metrics',
871
+ schema: GetAgentStatsArgsSchema,
872
+ handler: getAgentStats,
873
+ },
874
+ // Concurrency & Force-Spawn Tools
875
+ {
876
+ name: 'get_concurrency_status',
877
+ description: 'Get real-time concurrency status: running agent count, max allowed, available slots, and tracked running agents by type.',
878
+ schema: GetConcurrencyStatusArgsSchema,
879
+ handler: getConcurrencyStatus,
880
+ },
881
+ {
882
+ name: 'force_spawn_tasks',
883
+ description: 'Force-spawn all pending TODO tasks for the specified sections immediately, bypassing age filters, batch limits, cooldowns, and CTO activity gate. Preserves concurrency guard and task tracking.',
884
+ schema: ForceSpawnTasksArgsSchema,
885
+ handler: forceSpawnTasks,
886
+ },
887
+ {
888
+ name: 'force_triage_reports',
889
+ description: 'Force-spawn a deputy-CTO triage agent to process all pending reports immediately, bypassing the hourly automation triage interval. Returns the spawned agent ID, PID, and session ID.',
890
+ schema: ForceTriageReportsArgsSchema,
891
+ handler: forceTriageReports,
892
+ },
893
+ // Session Browser Tools
894
+ {
895
+ name: 'list_sessions',
896
+ description: 'List all Claude Code sessions for this project with optional hook metadata. Shows which sessions were spawned by hooks vs manual user sessions.',
897
+ schema: ListSessionsArgsSchema,
898
+ handler: listSessions,
899
+ },
900
+ {
901
+ name: 'search_sessions',
902
+ description: 'Search across all session content. Returns matching sessions with preview context. Useful for finding specific conversations or debugging.',
903
+ schema: SearchSessionsArgsSchema,
904
+ handler: searchSessions,
905
+ },
906
+ {
907
+ name: 'get_session_summary',
908
+ description: 'Get detailed summary of a specific session including message counts, tools used, duration estimate, and first user message.',
909
+ schema: GetSessionSummaryArgsSchema,
910
+ handler: getSessionSummary,
911
+ },
912
+ ];
913
+ const server = new McpServer({
914
+ name: 'agent-tracker',
915
+ version: '4.0.0', // Added concurrency status + force-spawn tools
916
+ tools,
917
+ });
918
+ server.start();
919
+ //# sourceMappingURL=server.js.map