devchain-cli 0.10.4 → 0.11.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (363) hide show
  1. package/README.md +13 -7
  2. package/dist/cli.js +55 -63
  3. package/dist/drizzle/0048_sessions_transcript_fields.sql +6 -0
  4. package/dist/drizzle/0049_provider_models_and_agent_model_override.sql +24 -0
  5. package/dist/drizzle/meta/_journal.json +14 -0
  6. package/dist/node_modules/@devchain/shared/schemas/export-schema.d.ts +25 -0
  7. package/dist/node_modules/@devchain/shared/schemas/export-schema.d.ts.map +1 -1
  8. package/dist/node_modules/@devchain/shared/schemas/export-schema.js +9 -3
  9. package/dist/node_modules/@devchain/shared/schemas/export-schema.js.map +1 -1
  10. package/dist/node_modules/@devchain/shared/tsconfig.tsbuildinfo +1 -1
  11. package/dist/server/app.main.module.js +2 -0
  12. package/dist/server/app.main.module.js.map +1 -1
  13. package/dist/server/app.normal.module.js +2 -0
  14. package/dist/server/app.normal.module.js.map +1 -1
  15. package/dist/server/common/config/env.config.js +1 -10
  16. package/dist/server/common/config/env.config.js.map +1 -1
  17. package/dist/server/modules/agents/controllers/agents.controller.d.ts +1 -0
  18. package/dist/server/modules/agents/controllers/agents.controller.js +3 -0
  19. package/dist/server/modules/agents/controllers/agents.controller.js.map +1 -1
  20. package/dist/server/modules/chat/dtos/chat.dto.d.ts +4 -4
  21. package/dist/server/modules/core/services/preflight.service.js +7 -0
  22. package/dist/server/modules/core/services/preflight.service.js.map +1 -1
  23. package/dist/server/modules/core/services/provider-mcp-ensure.service.js +8 -0
  24. package/dist/server/modules/core/services/provider-mcp-ensure.service.js.map +1 -1
  25. package/dist/server/modules/documents/controllers/documents.controller.d.ts +2 -2
  26. package/dist/server/modules/documents/controllers/documents.controller.js.map +1 -1
  27. package/dist/server/modules/epics/controllers/epic-comments.controller.d.ts +2 -2
  28. package/dist/server/modules/epics/controllers/epic-comments.controller.js.map +1 -1
  29. package/dist/server/modules/events/catalog/claude.hooks.session.started.d.ts +4 -4
  30. package/dist/server/modules/events/catalog/index.d.ts +115 -4
  31. package/dist/server/modules/events/catalog/index.js +6 -0
  32. package/dist/server/modules/events/catalog/index.js.map +1 -1
  33. package/dist/server/modules/events/catalog/session.transcript.discovered.d.ts +24 -0
  34. package/dist/server/modules/events/catalog/session.transcript.discovered.js +15 -0
  35. package/dist/server/modules/events/catalog/session.transcript.discovered.js.map +1 -0
  36. package/dist/server/modules/events/catalog/session.transcript.ended.d.ts +51 -0
  37. package/dist/server/modules/events/catalog/session.transcript.ended.js +20 -0
  38. package/dist/server/modules/events/catalog/session.transcript.ended.js.map +1 -0
  39. package/dist/server/modules/events/catalog/session.transcript.updated.d.ts +51 -0
  40. package/dist/server/modules/events/catalog/session.transcript.updated.js +20 -0
  41. package/dist/server/modules/events/catalog/session.transcript.updated.js.map +1 -0
  42. package/dist/server/modules/events/subscribers/chat-message-delivery.subscriber.d.ts +2 -2
  43. package/dist/server/modules/events/subscribers/chat-message-delivery.subscriber.js.map +1 -1
  44. package/dist/server/modules/events/subscribers/index.js +2 -0
  45. package/dist/server/modules/events/subscribers/index.js.map +1 -1
  46. package/dist/server/modules/events/subscribers/review-comment-notifier.subscriber.d.ts +2 -2
  47. package/dist/server/modules/events/subscribers/review-comment-notifier.subscriber.js.map +1 -1
  48. package/dist/server/modules/events/subscribers/transcript-broadcaster.subscriber.d.ts +12 -0
  49. package/dist/server/modules/events/subscribers/transcript-broadcaster.subscriber.js +88 -0
  50. package/dist/server/modules/events/subscribers/transcript-broadcaster.subscriber.js.map +1 -0
  51. package/dist/server/modules/guests/services/guest-health.service.d.ts +2 -2
  52. package/dist/server/modules/guests/services/guest-health.service.js.map +1 -1
  53. package/dist/server/modules/hooks/dtos/hook-event.dto.d.ts +4 -4
  54. package/dist/server/modules/hooks/services/hooks.service.d.ts +2 -2
  55. package/dist/server/modules/hooks/services/hooks.service.js.map +1 -1
  56. package/dist/server/modules/mcp/dtos/mcp.dto.js +8 -3
  57. package/dist/server/modules/mcp/dtos/mcp.dto.js.map +1 -1
  58. package/dist/server/modules/mcp/services/handlers/activity-tools.d.ts +4 -0
  59. package/dist/server/modules/mcp/services/handlers/activity-tools.js +193 -0
  60. package/dist/server/modules/mcp/services/handlers/activity-tools.js.map +1 -0
  61. package/dist/server/modules/mcp/services/handlers/chat-tools.d.ts +6 -0
  62. package/dist/server/modules/mcp/services/handlers/chat-tools.js +605 -0
  63. package/dist/server/modules/mcp/services/handlers/chat-tools.js.map +1 -0
  64. package/dist/server/modules/mcp/services/handlers/document-tools.d.ts +6 -0
  65. package/dist/server/modules/mcp/services/handlers/document-tools.js +141 -0
  66. package/dist/server/modules/mcp/services/handlers/document-tools.js.map +1 -0
  67. package/dist/server/modules/mcp/services/handlers/epic-tools.d.ts +11 -0
  68. package/dist/server/modules/mcp/services/handlers/epic-tools.js +913 -0
  69. package/dist/server/modules/mcp/services/handlers/epic-tools.js.map +1 -0
  70. package/dist/server/modules/mcp/services/handlers/prompt-tools.d.ts +4 -0
  71. package/dist/server/modules/mcp/services/handlers/prompt-tools.js +109 -0
  72. package/dist/server/modules/mcp/services/handlers/prompt-tools.js.map +1 -0
  73. package/dist/server/modules/mcp/services/handlers/record-tools.d.ts +8 -0
  74. package/dist/server/modules/mcp/services/handlers/record-tools.js +114 -0
  75. package/dist/server/modules/mcp/services/handlers/record-tools.js.map +1 -0
  76. package/dist/server/modules/mcp/services/handlers/review-tools.d.ts +8 -0
  77. package/dist/server/modules/mcp/services/handlers/review-tools.js +672 -0
  78. package/dist/server/modules/mcp/services/handlers/review-tools.js.map +1 -0
  79. package/dist/server/modules/mcp/services/handlers/session-tools.d.ts +4 -0
  80. package/dist/server/modules/mcp/services/handlers/session-tools.js +114 -0
  81. package/dist/server/modules/mcp/services/handlers/session-tools.js.map +1 -0
  82. package/dist/server/modules/mcp/services/handlers/skill-tools.d.ts +4 -0
  83. package/dist/server/modules/mcp/services/handlers/skill-tools.js +124 -0
  84. package/dist/server/modules/mcp/services/handlers/skill-tools.js.map +1 -0
  85. package/dist/server/modules/mcp/services/handlers/types.d.ts +33 -0
  86. package/dist/server/modules/mcp/services/handlers/types.js +3 -0
  87. package/dist/server/modules/mcp/services/handlers/types.js.map +1 -0
  88. package/dist/server/modules/mcp/services/mappers/dto-mappers.d.ts +14 -0
  89. package/dist/server/modules/mcp/services/mappers/dto-mappers.js +138 -0
  90. package/dist/server/modules/mcp/services/mappers/dto-mappers.js.map +1 -0
  91. package/dist/server/modules/mcp/services/mcp-provider-registration.service.d.ts +8 -0
  92. package/dist/server/modules/mcp/services/mcp-provider-registration.service.js +258 -51
  93. package/dist/server/modules/mcp/services/mcp-provider-registration.service.js.map +1 -1
  94. package/dist/server/modules/mcp/services/mcp.service.d.ts +6 -66
  95. package/dist/server/modules/mcp/services/mcp.service.js +97 -3329
  96. package/dist/server/modules/mcp/services/mcp.service.js.map +1 -1
  97. package/dist/server/modules/mcp/services/utils/document-link-resolver.d.ts +10 -0
  98. package/dist/server/modules/mcp/services/utils/document-link-resolver.js +124 -0
  99. package/dist/server/modules/mcp/services/utils/document-link-resolver.js.map +1 -0
  100. package/dist/server/modules/mcp/services/utils/resolve-epic-id.d.ts +3 -0
  101. package/dist/server/modules/mcp/services/utils/resolve-epic-id.js +40 -0
  102. package/dist/server/modules/mcp/services/utils/resolve-epic-id.js.map +1 -0
  103. package/dist/server/modules/mcp/services/utils/resource-resolver.d.ts +10 -0
  104. package/dist/server/modules/mcp/services/utils/resource-resolver.js +124 -0
  105. package/dist/server/modules/mcp/services/utils/resource-resolver.js.map +1 -0
  106. package/dist/server/modules/mcp/services/utils/session-context-resolver.d.ts +14 -0
  107. package/dist/server/modules/mcp/services/utils/session-context-resolver.js +169 -0
  108. package/dist/server/modules/mcp/services/utils/session-context-resolver.js.map +1 -0
  109. package/dist/server/modules/mcp/tool-definitions.js +12 -3
  110. package/dist/server/modules/mcp/tool-definitions.js.map +1 -1
  111. package/dist/server/modules/orchestrator/docker/services/docker.service.js +16 -2
  112. package/dist/server/modules/orchestrator/docker/services/docker.service.js.map +1 -1
  113. package/dist/server/modules/orchestrator/ui/app/lib/worktrees.js +9 -0
  114. package/dist/server/modules/orchestrator/ui/app/lib/worktrees.js.map +1 -1
  115. package/dist/server/modules/profiles/controllers/provider-configs.controller.d.ts +2 -2
  116. package/dist/server/modules/profiles/controllers/provider-configs.controller.js.map +1 -1
  117. package/dist/server/modules/profiles/dto.d.ts +2 -2
  118. package/dist/server/modules/projects/controllers/projects.controller.d.ts +38 -33
  119. package/dist/server/modules/projects/controllers/projects.controller.js +12 -7
  120. package/dist/server/modules/projects/controllers/projects.controller.js.map +1 -1
  121. package/dist/server/modules/projects/dtos/export.dto.d.ts +7 -0
  122. package/dist/server/modules/projects/dtos/export.dto.js +1 -0
  123. package/dist/server/modules/projects/dtos/export.dto.js.map +1 -1
  124. package/dist/server/modules/projects/helpers/profile-mapping.helpers.d.ts +102 -0
  125. package/dist/server/modules/projects/helpers/profile-mapping.helpers.js +369 -0
  126. package/dist/server/modules/projects/helpers/profile-mapping.helpers.js.map +1 -0
  127. package/dist/server/modules/projects/helpers/project-export.d.ts +141 -0
  128. package/dist/server/modules/projects/helpers/project-export.js +314 -0
  129. package/dist/server/modules/projects/helpers/project-export.js.map +1 -0
  130. package/dist/server/modules/projects/helpers/project-import.d.ts +132 -0
  131. package/dist/server/modules/projects/helpers/project-import.js +600 -0
  132. package/dist/server/modules/projects/helpers/project-import.js.map +1 -0
  133. package/dist/server/modules/projects/helpers/project-presets.helpers.d.ts +26 -0
  134. package/dist/server/modules/projects/helpers/project-presets.helpers.js +110 -0
  135. package/dist/server/modules/projects/helpers/project-presets.helpers.js.map +1 -0
  136. package/dist/server/modules/projects/helpers/project-runtime.helpers.d.ts +69 -0
  137. package/dist/server/modules/projects/helpers/project-runtime.helpers.js +201 -0
  138. package/dist/server/modules/projects/helpers/project-runtime.helpers.js.map +1 -0
  139. package/dist/server/modules/projects/helpers/project-template-manifest.helpers.d.ts +16 -0
  140. package/dist/server/modules/projects/helpers/project-template-manifest.helpers.js +107 -0
  141. package/dist/server/modules/projects/helpers/project-template-manifest.helpers.js.map +1 -0
  142. package/dist/server/modules/projects/helpers/template-file.helpers.d.ts +9 -0
  143. package/dist/server/modules/projects/helpers/template-file.helpers.js +92 -0
  144. package/dist/server/modules/projects/helpers/template-file.helpers.js.map +1 -0
  145. package/dist/server/modules/projects/helpers/template-loader.d.ts +85 -0
  146. package/dist/server/modules/projects/helpers/template-loader.js +406 -0
  147. package/dist/server/modules/projects/helpers/template-loader.js.map +1 -0
  148. package/dist/server/modules/projects/services/main-project-bootstrap.service.js +4 -0
  149. package/dist/server/modules/projects/services/main-project-bootstrap.service.js.map +1 -1
  150. package/dist/server/modules/projects/services/projects.service.d.ts +29 -54
  151. package/dist/server/modules/projects/services/projects.service.js +46 -1704
  152. package/dist/server/modules/projects/services/projects.service.js.map +1 -1
  153. package/dist/server/modules/prompts/controllers/prompts.controller.d.ts +2 -2
  154. package/dist/server/modules/prompts/controllers/prompts.controller.js.map +1 -1
  155. package/dist/server/modules/providers/adapters/index.d.ts +1 -0
  156. package/dist/server/modules/providers/adapters/index.js +1 -0
  157. package/dist/server/modules/providers/adapters/index.js.map +1 -1
  158. package/dist/server/modules/providers/adapters/opencode.adapter.d.ts +16 -0
  159. package/dist/server/modules/providers/adapters/opencode.adapter.js +64 -0
  160. package/dist/server/modules/providers/adapters/opencode.adapter.js.map +1 -0
  161. package/dist/server/modules/providers/adapters/provider-adapter.factory.d.ts +2 -1
  162. package/dist/server/modules/providers/adapters/provider-adapter.factory.js +5 -2
  163. package/dist/server/modules/providers/adapters/provider-adapter.factory.js.map +1 -1
  164. package/dist/server/modules/providers/adapters/provider-adapter.interface.d.ts +1 -0
  165. package/dist/server/modules/providers/adapters/provider-adapters.module.js +2 -1
  166. package/dist/server/modules/providers/adapters/provider-adapters.module.js.map +1 -1
  167. package/dist/server/modules/providers/controllers/provider-models.controller.d.ts +22 -0
  168. package/dist/server/modules/providers/controllers/provider-models.controller.js +173 -0
  169. package/dist/server/modules/providers/controllers/provider-models.controller.js.map +1 -0
  170. package/dist/server/modules/providers/providers.module.js +2 -1
  171. package/dist/server/modules/providers/providers.module.js.map +1 -1
  172. package/dist/server/modules/records/controllers/records.controller.d.ts +2 -2
  173. package/dist/server/modules/records/controllers/records.controller.js.map +1 -1
  174. package/dist/server/modules/registry/services/template-upgrade.service.js +1 -9
  175. package/dist/server/modules/registry/services/template-upgrade.service.js.map +1 -1
  176. package/dist/server/modules/session-reader/adapters/claude-session-reader.adapter.d.ts +21 -0
  177. package/dist/server/modules/session-reader/adapters/claude-session-reader.adapter.js +207 -0
  178. package/dist/server/modules/session-reader/adapters/claude-session-reader.adapter.js.map +1 -0
  179. package/dist/server/modules/session-reader/adapters/codex-session-reader.adapter.d.ts +22 -0
  180. package/dist/server/modules/session-reader/adapters/codex-session-reader.adapter.js +214 -0
  181. package/dist/server/modules/session-reader/adapters/codex-session-reader.adapter.js.map +1 -0
  182. package/dist/server/modules/session-reader/adapters/gemini-session-reader.adapter.d.ts +23 -0
  183. package/dist/server/modules/session-reader/adapters/gemini-session-reader.adapter.js +224 -0
  184. package/dist/server/modules/session-reader/adapters/gemini-session-reader.adapter.js.map +1 -0
  185. package/dist/server/modules/session-reader/adapters/session-reader-adapter.factory.d.ts +9 -0
  186. package/dist/server/modules/session-reader/adapters/session-reader-adapter.factory.js +40 -0
  187. package/dist/server/modules/session-reader/adapters/session-reader-adapter.factory.js.map +1 -0
  188. package/dist/server/modules/session-reader/adapters/session-reader-adapter.interface.d.ts +37 -0
  189. package/dist/server/modules/session-reader/adapters/session-reader-adapter.interface.js +3 -0
  190. package/dist/server/modules/session-reader/adapters/session-reader-adapter.interface.js.map +1 -0
  191. package/dist/server/modules/session-reader/adapters/utils/estimate-content-tokens.d.ts +11 -0
  192. package/dist/server/modules/session-reader/adapters/utils/estimate-content-tokens.js +77 -0
  193. package/dist/server/modules/session-reader/adapters/utils/estimate-content-tokens.js.map +1 -0
  194. package/dist/server/modules/session-reader/adapters/utils/file-search.util.d.ts +1 -0
  195. package/dist/server/modules/session-reader/adapters/utils/file-search.util.js +22 -0
  196. package/dist/server/modules/session-reader/adapters/utils/file-search.util.js.map +1 -0
  197. package/dist/server/modules/session-reader/builders/chunk-builder.d.ts +5 -0
  198. package/dist/server/modules/session-reader/builders/chunk-builder.js +131 -0
  199. package/dist/server/modules/session-reader/builders/chunk-builder.js.map +1 -0
  200. package/dist/server/modules/session-reader/builders/semantic-step-extractor.d.ts +3 -0
  201. package/dist/server/modules/session-reader/builders/semantic-step-extractor.js +93 -0
  202. package/dist/server/modules/session-reader/builders/semantic-step-extractor.js.map +1 -0
  203. package/dist/server/modules/session-reader/builders/turn-builder.d.ts +3 -0
  204. package/dist/server/modules/session-reader/builders/turn-builder.js +102 -0
  205. package/dist/server/modules/session-reader/builders/turn-builder.js.map +1 -0
  206. package/dist/server/modules/session-reader/controllers/session-reader.controller.d.ts +430 -0
  207. package/dist/server/modules/session-reader/controllers/session-reader.controller.js +252 -0
  208. package/dist/server/modules/session-reader/controllers/session-reader.controller.js.map +1 -0
  209. package/dist/server/modules/session-reader/data/pricing.json +5001 -0
  210. package/dist/server/modules/session-reader/dtos/index.d.ts +2 -0
  211. package/dist/server/modules/session-reader/dtos/index.js +10 -0
  212. package/dist/server/modules/session-reader/dtos/index.js.map +1 -0
  213. package/dist/server/modules/session-reader/dtos/unified-chunk.types.d.ts +92 -0
  214. package/dist/server/modules/session-reader/dtos/unified-chunk.types.js +19 -0
  215. package/dist/server/modules/session-reader/dtos/unified-chunk.types.js.map +1 -0
  216. package/dist/server/modules/session-reader/dtos/unified-session.types.d.ts +118 -0
  217. package/dist/server/modules/session-reader/dtos/unified-session.types.js +23 -0
  218. package/dist/server/modules/session-reader/dtos/unified-session.types.js.map +1 -0
  219. package/dist/server/modules/session-reader/parsers/claude-jsonl.parser.d.ts +15 -0
  220. package/dist/server/modules/session-reader/parsers/claude-jsonl.parser.js +363 -0
  221. package/dist/server/modules/session-reader/parsers/claude-jsonl.parser.js.map +1 -0
  222. package/dist/server/modules/session-reader/parsers/codex-jsonl.parser.d.ts +16 -0
  223. package/dist/server/modules/session-reader/parsers/codex-jsonl.parser.js +622 -0
  224. package/dist/server/modules/session-reader/parsers/codex-jsonl.parser.js.map +1 -0
  225. package/dist/server/modules/session-reader/parsers/gemini-json.parser.d.ts +15 -0
  226. package/dist/server/modules/session-reader/parsers/gemini-json.parser.js +380 -0
  227. package/dist/server/modules/session-reader/parsers/gemini-json.parser.js.map +1 -0
  228. package/dist/server/modules/session-reader/services/pricing.interface.d.ts +9 -0
  229. package/dist/server/modules/session-reader/services/pricing.interface.js +24 -0
  230. package/dist/server/modules/session-reader/services/pricing.interface.js.map +1 -0
  231. package/dist/server/modules/session-reader/services/pricing.service.d.ts +21 -0
  232. package/dist/server/modules/session-reader/services/pricing.service.js +106 -0
  233. package/dist/server/modules/session-reader/services/pricing.service.js.map +1 -0
  234. package/dist/server/modules/session-reader/services/session-cache.service.d.ts +24 -0
  235. package/dist/server/modules/session-reader/services/session-cache.service.js +203 -0
  236. package/dist/server/modules/session-reader/services/session-cache.service.js.map +1 -0
  237. package/dist/server/modules/session-reader/services/session-reader.service.d.ts +56 -0
  238. package/dist/server/modules/session-reader/services/session-reader.service.js +305 -0
  239. package/dist/server/modules/session-reader/services/session-reader.service.js.map +1 -0
  240. package/dist/server/modules/session-reader/services/subagent-locator.service.d.ts +10 -0
  241. package/dist/server/modules/session-reader/services/subagent-locator.service.js +102 -0
  242. package/dist/server/modules/session-reader/services/subagent-locator.service.js.map +1 -0
  243. package/dist/server/modules/session-reader/services/subagent-resolver.service.d.ts +22 -0
  244. package/dist/server/modules/session-reader/services/subagent-resolver.service.js +211 -0
  245. package/dist/server/modules/session-reader/services/subagent-resolver.service.js.map +1 -0
  246. package/dist/server/modules/session-reader/services/transcript-path-validator.service.d.ts +7 -0
  247. package/dist/server/modules/session-reader/services/transcript-path-validator.service.js +150 -0
  248. package/dist/server/modules/session-reader/services/transcript-path-validator.service.js.map +1 -0
  249. package/dist/server/modules/session-reader/services/transcript-persistence.listener.d.ts +30 -0
  250. package/dist/server/modules/session-reader/services/transcript-persistence.listener.js +336 -0
  251. package/dist/server/modules/session-reader/services/transcript-persistence.listener.js.map +1 -0
  252. package/dist/server/modules/session-reader/services/transcript-watcher.service.d.ts +28 -0
  253. package/dist/server/modules/session-reader/services/transcript-watcher.service.js +325 -0
  254. package/dist/server/modules/session-reader/services/transcript-watcher.service.js.map +1 -0
  255. package/dist/server/modules/session-reader/session-reader.module.d.ts +13 -0
  256. package/dist/server/modules/session-reader/session-reader.module.js +82 -0
  257. package/dist/server/modules/session-reader/session-reader.module.js.map +1 -0
  258. package/dist/server/modules/sessions/dtos/sessions.dto.d.ts +2 -0
  259. package/dist/server/modules/sessions/dtos/sessions.dto.js.map +1 -1
  260. package/dist/server/modules/sessions/services/sessions-message-pool.service.d.ts +2 -2
  261. package/dist/server/modules/sessions/services/sessions-message-pool.service.js.map +1 -1
  262. package/dist/server/modules/sessions/services/sessions.service.js +19 -4
  263. package/dist/server/modules/sessions/services/sessions.service.js.map +1 -1
  264. package/dist/server/modules/sessions/utils/profile-options.d.ts +1 -0
  265. package/dist/server/modules/sessions/utils/profile-options.js +18 -0
  266. package/dist/server/modules/sessions/utils/profile-options.js.map +1 -1
  267. package/dist/server/modules/settings/controllers/settings.controller.d.ts +2 -2
  268. package/dist/server/modules/settings/controllers/settings.controller.js.map +1 -1
  269. package/dist/server/modules/settings/dtos/settings.dto.d.ts +14 -2
  270. package/dist/server/modules/settings/dtos/settings.dto.js +1 -0
  271. package/dist/server/modules/settings/dtos/settings.dto.js.map +1 -1
  272. package/dist/server/modules/skills/services/skill-source-registry.service.d.ts +2 -2
  273. package/dist/server/modules/skills/services/skill-source-registry.service.js.map +1 -1
  274. package/dist/server/modules/statuses/controllers/statuses.controller.d.ts +2 -2
  275. package/dist/server/modules/statuses/controllers/statuses.controller.js.map +1 -1
  276. package/dist/server/modules/storage/db/schema.d.ts +176 -0
  277. package/dist/server/modules/storage/db/schema.js +17 -1
  278. package/dist/server/modules/storage/db/schema.js.map +1 -1
  279. package/dist/server/modules/storage/interfaces/storage.interface.d.ts +53 -9
  280. package/dist/server/modules/storage/interfaces/storage.interface.js.map +1 -1
  281. package/dist/server/modules/storage/local/delegates/agent-profile.delegate.d.ts +39 -0
  282. package/dist/server/modules/storage/local/delegates/agent-profile.delegate.js +286 -0
  283. package/dist/server/modules/storage/local/delegates/agent-profile.delegate.js.map +1 -0
  284. package/dist/server/modules/storage/local/delegates/agent.delegate.d.ts +21 -0
  285. package/dist/server/modules/storage/local/delegates/agent.delegate.js +210 -0
  286. package/dist/server/modules/storage/local/delegates/agent.delegate.js.map +1 -0
  287. package/dist/server/modules/storage/local/delegates/base-storage.delegate.d.ts +12 -0
  288. package/dist/server/modules/storage/local/delegates/base-storage.delegate.js +19 -0
  289. package/dist/server/modules/storage/local/delegates/base-storage.delegate.js.map +1 -0
  290. package/dist/server/modules/storage/local/delegates/document.delegate.d.ts +20 -0
  291. package/dist/server/modules/storage/local/delegates/document.delegate.js +267 -0
  292. package/dist/server/modules/storage/local/delegates/document.delegate.js.map +1 -0
  293. package/dist/server/modules/storage/local/delegates/epic.delegate.d.ts +38 -0
  294. package/dist/server/modules/storage/local/delegates/epic.delegate.js +686 -0
  295. package/dist/server/modules/storage/local/delegates/epic.delegate.js.map +1 -0
  296. package/dist/server/modules/storage/local/delegates/guest.delegate.d.ts +14 -0
  297. package/dist/server/modules/storage/local/delegates/guest.delegate.js +172 -0
  298. package/dist/server/modules/storage/local/delegates/guest.delegate.js.map +1 -0
  299. package/dist/server/modules/storage/local/delegates/profile-provider-config.delegate.d.ts +17 -0
  300. package/dist/server/modules/storage/local/delegates/profile-provider-config.delegate.js +249 -0
  301. package/dist/server/modules/storage/local/delegates/profile-provider-config.delegate.js.map +1 -0
  302. package/dist/server/modules/storage/local/delegates/project.delegate.d.ts +16 -0
  303. package/dist/server/modules/storage/local/delegates/project.delegate.js +630 -0
  304. package/dist/server/modules/storage/local/delegates/project.delegate.js.map +1 -0
  305. package/dist/server/modules/storage/local/delegates/prompt.delegate.d.ts +17 -0
  306. package/dist/server/modules/storage/local/delegates/prompt.delegate.js +318 -0
  307. package/dist/server/modules/storage/local/delegates/prompt.delegate.js.map +1 -0
  308. package/dist/server/modules/storage/local/delegates/provider-model.delegate.d.ts +15 -0
  309. package/dist/server/modules/storage/local/delegates/provider-model.delegate.js +210 -0
  310. package/dist/server/modules/storage/local/delegates/provider-model.delegate.js.map +1 -0
  311. package/dist/server/modules/storage/local/delegates/provider.delegate.d.ts +18 -0
  312. package/dist/server/modules/storage/local/delegates/provider.delegate.js +151 -0
  313. package/dist/server/modules/storage/local/delegates/provider.delegate.js.map +1 -0
  314. package/dist/server/modules/storage/local/delegates/record.delegate.d.ts +16 -0
  315. package/dist/server/modules/storage/local/delegates/record.delegate.js +190 -0
  316. package/dist/server/modules/storage/local/delegates/record.delegate.js.map +1 -0
  317. package/dist/server/modules/storage/local/delegates/review.delegate.d.ts +25 -0
  318. package/dist/server/modules/storage/local/delegates/review.delegate.js +426 -0
  319. package/dist/server/modules/storage/local/delegates/review.delegate.js.map +1 -0
  320. package/dist/server/modules/storage/local/delegates/skill-source.delegate.d.ts +28 -0
  321. package/dist/server/modules/storage/local/delegates/skill-source.delegate.js +347 -0
  322. package/dist/server/modules/storage/local/delegates/skill-source.delegate.js.map +1 -0
  323. package/dist/server/modules/storage/local/delegates/status.delegate.d.ts +12 -0
  324. package/dist/server/modules/storage/local/delegates/status.delegate.js +130 -0
  325. package/dist/server/modules/storage/local/delegates/status.delegate.js.map +1 -0
  326. package/dist/server/modules/storage/local/delegates/subscriber.delegate.d.ts +11 -0
  327. package/dist/server/modules/storage/local/delegates/subscriber.delegate.js +144 -0
  328. package/dist/server/modules/storage/local/delegates/subscriber.delegate.js.map +1 -0
  329. package/dist/server/modules/storage/local/delegates/tag.delegate.d.ts +11 -0
  330. package/dist/server/modules/storage/local/delegates/tag.delegate.js +102 -0
  331. package/dist/server/modules/storage/local/delegates/tag.delegate.js.map +1 -0
  332. package/dist/server/modules/storage/local/delegates/watcher.delegate.d.ts +12 -0
  333. package/dist/server/modules/storage/local/delegates/watcher.delegate.js +183 -0
  334. package/dist/server/modules/storage/local/delegates/watcher.delegate.js.map +1 -0
  335. package/dist/server/modules/storage/local/helpers/storage-helpers.d.ts +32 -0
  336. package/dist/server/modules/storage/local/helpers/storage-helpers.js +276 -0
  337. package/dist/server/modules/storage/local/helpers/storage-helpers.js.map +1 -0
  338. package/dist/server/modules/storage/local/local-storage.service.d.ts +30 -22
  339. package/dist/server/modules/storage/local/local-storage.service.js +227 -3627
  340. package/dist/server/modules/storage/local/local-storage.service.js.map +1 -1
  341. package/dist/server/modules/storage/models/domain.models.d.ts +14 -1
  342. package/dist/server/modules/subscribers/services/subscribers.service.d.ts +2 -2
  343. package/dist/server/modules/subscribers/services/subscribers.service.js.map +1 -1
  344. package/dist/server/modules/ui/ui.controller.d.ts +2 -2
  345. package/dist/server/modules/ui/ui.controller.js +9 -3
  346. package/dist/server/modules/ui/ui.controller.js.map +1 -1
  347. package/dist/server/modules/watchers/services/watchers.service.d.ts +2 -2
  348. package/dist/server/templates/3-agents-dev.json +209 -191
  349. package/dist/server/templates/5-agents-dev.json +243 -198
  350. package/dist/server/test-setup.js +14 -0
  351. package/dist/server/test-setup.js.map +1 -1
  352. package/dist/server/tsconfig.tsbuildinfo +1 -1
  353. package/dist/server/ui/assets/{ReviewDetailPage-CvHhaFJw.js → ReviewDetailPage-DJyH8bKk.js} +1 -1
  354. package/dist/server/ui/assets/{ReviewsPage-DCDiMjwZ.js → ReviewsPage-DHvmyjjG.js} +1 -1
  355. package/dist/server/ui/assets/index-cHqKW6LQ.css +32 -0
  356. package/dist/server/ui/assets/index-f0KXZKs1.js +1011 -0
  357. package/dist/server/ui/assets/{useReviewSubscription-D_vmMkNu.js → useReviewSubscription-CUbCp0An.js} +32 -35
  358. package/dist/server/ui/index.html +2 -2
  359. package/dist/templates/3-agents-dev.json +209 -191
  360. package/dist/templates/5-agents-dev.json +243 -198
  361. package/package.json +18 -1
  362. package/dist/server/ui/assets/index-CWqSXDUZ.js +0 -977
  363. package/dist/server/ui/assets/index-DvRuLfpZ.css +0 -32
@@ -0,0 +1,913 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.handleListAgents = handleListAgents;
4
+ exports.handleGetAgentByName = handleGetAgentByName;
5
+ exports.handleListStatuses = handleListStatuses;
6
+ exports.handleListEpics = handleListEpics;
7
+ exports.handleListAssignedEpicsTasks = handleListAssignedEpicsTasks;
8
+ exports.handleCreateEpic = handleCreateEpic;
9
+ exports.handleGetEpicById = handleGetEpicById;
10
+ exports.handleAddEpicComment = handleAddEpicComment;
11
+ exports.handleUpdateEpic = handleUpdateEpic;
12
+ const logger_1 = require("../../../../common/logging/logger");
13
+ const error_types_1 = require("../../../../common/errors/error-types");
14
+ const mcp_dto_1 = require("../../dtos/mcp.dto");
15
+ const dto_mappers_1 = require("../mappers/dto-mappers");
16
+ const resolve_epic_id_1 = require("../utils/resolve-epic-id");
17
+ const logger = (0, logger_1.createLogger)('McpService');
18
+ function getActorFromContext(ctx) {
19
+ if (ctx.type === 'agent') {
20
+ return ctx.agent;
21
+ }
22
+ if (ctx.type === 'guest') {
23
+ return {
24
+ id: ctx.guest.id,
25
+ name: ctx.guest.name,
26
+ projectId: ctx.guest.projectId,
27
+ };
28
+ }
29
+ return null;
30
+ }
31
+ function missingSessionResolver() {
32
+ return {
33
+ success: false,
34
+ error: {
35
+ code: 'SERVICE_UNAVAILABLE',
36
+ message: 'Session resolution requires full app context (not available in standalone MCP mode)',
37
+ },
38
+ };
39
+ }
40
+ async function resolveSessionContext(ctx, sessionId) {
41
+ if (!ctx.resolveSessionContext) {
42
+ return missingSessionResolver();
43
+ }
44
+ return ctx.resolveSessionContext(sessionId);
45
+ }
46
+ async function handleListAgents(ctx, params) {
47
+ const validated = mcp_dto_1.ListAgentsParamsSchema.parse(params);
48
+ const sessionCtxResult = await resolveSessionContext(ctx, validated.sessionId);
49
+ if (!sessionCtxResult.success)
50
+ return sessionCtxResult;
51
+ const { project } = sessionCtxResult.data;
52
+ if (!project) {
53
+ return {
54
+ success: false,
55
+ error: {
56
+ code: 'PROJECT_NOT_FOUND',
57
+ message: 'No project associated with this session',
58
+ },
59
+ };
60
+ }
61
+ const limit = validated.limit ?? 100;
62
+ const offset = validated.offset ?? 0;
63
+ const normalizedQuery = validated.q?.toLowerCase();
64
+ const MAX_COMBINED_FETCH = 1000;
65
+ const [agentsResult, guests] = await Promise.all([
66
+ ctx.storage.listAgents(project.id, { limit: MAX_COMBINED_FETCH, offset: 0 }),
67
+ ctx.storage.listGuests(project.id),
68
+ ]);
69
+ const [agentPresence, tmuxSessions] = await Promise.all([
70
+ ctx.sessionsService
71
+ ? ctx.sessionsService.getAgentPresence(project.id)
72
+ : Promise.resolve(new Map()),
73
+ ctx.tmuxService ? ctx.tmuxService.listAllSessionNames() : Promise.resolve(new Set()),
74
+ ]);
75
+ const agentItems = agentsResult.items.map((agent) => ({
76
+ id: agent.id,
77
+ name: agent.name,
78
+ profileId: agent.profileId,
79
+ description: agent.description,
80
+ type: 'agent',
81
+ online: agentPresence.get(agent.id)?.online ?? false,
82
+ }));
83
+ const guestItems = guests.map((guest) => ({
84
+ id: guest.id,
85
+ name: guest.name,
86
+ profileId: null,
87
+ description: guest.description,
88
+ type: 'guest',
89
+ online: tmuxSessions.has(guest.tmuxSessionId),
90
+ }));
91
+ let allItems = [...agentItems, ...guestItems].sort((a, b) => {
92
+ const nameCompare = a.name.localeCompare(b.name);
93
+ if (nameCompare !== 0)
94
+ return nameCompare;
95
+ return a.type === 'agent' ? -1 : 1;
96
+ });
97
+ if (normalizedQuery) {
98
+ allItems = allItems.filter((item) => item.name.toLowerCase().includes(normalizedQuery));
99
+ }
100
+ const total = allItems.length;
101
+ const paginatedItems = allItems.slice(offset, offset + limit);
102
+ const response = {
103
+ agents: paginatedItems,
104
+ total,
105
+ limit,
106
+ offset,
107
+ };
108
+ return { success: true, data: response };
109
+ }
110
+ async function handleGetAgentByName(ctx, params) {
111
+ const validated = mcp_dto_1.GetAgentByNameParamsSchema.parse(params);
112
+ const sessionCtxResult = await resolveSessionContext(ctx, validated.sessionId);
113
+ if (!sessionCtxResult.success)
114
+ return sessionCtxResult;
115
+ const { project } = sessionCtxResult.data;
116
+ if (!project) {
117
+ return {
118
+ success: false,
119
+ error: {
120
+ code: 'PROJECT_NOT_FOUND',
121
+ message: 'No project associated with this session',
122
+ },
123
+ };
124
+ }
125
+ const normalizedName = validated.name.trim().toLowerCase();
126
+ const agentsList = await ctx.storage.listAgents(project.id, { limit: 1000, offset: 0 });
127
+ const candidate = agentsList.items.find((agent) => agent.name.toLowerCase() === normalizedName);
128
+ if (!candidate) {
129
+ return {
130
+ success: false,
131
+ error: {
132
+ code: 'AGENT_NOT_FOUND',
133
+ message: `Agent "${validated.name}" not found in project`,
134
+ data: {
135
+ availableNames: agentsList.items.map((agent) => agent.name),
136
+ },
137
+ },
138
+ };
139
+ }
140
+ let agentWithProfile;
141
+ try {
142
+ agentWithProfile = await ctx.storage.getAgentByName(project.id, candidate.name);
143
+ }
144
+ catch (error) {
145
+ if (error instanceof error_types_1.NotFoundError) {
146
+ return {
147
+ success: false,
148
+ error: {
149
+ code: 'AGENT_NOT_FOUND',
150
+ message: `Agent "${validated.name}" not found in project`,
151
+ data: {
152
+ availableNames: agentsList.items.map((agent) => agent.name),
153
+ },
154
+ },
155
+ };
156
+ }
157
+ logger.warn({ projectId: project.id, name: candidate.name, error }, 'Agent lookup failed after matching by name');
158
+ throw error;
159
+ }
160
+ if (!ctx.instructionsResolver) {
161
+ return {
162
+ success: false,
163
+ error: {
164
+ code: 'SERVICE_UNAVAILABLE',
165
+ message: 'Instructions resolver requires full app context (not available in standalone MCP mode)',
166
+ },
167
+ };
168
+ }
169
+ const profile = agentWithProfile.profile;
170
+ const resolvedInstructions = profile
171
+ ? await ctx.instructionsResolver.resolve(project.id, profile.instructions ?? null, {
172
+ maxBytes: ctx.defaultInlineMaxBytes ?? 64 * 1024,
173
+ })
174
+ : null;
175
+ if (profile && ctx.featureFlags?.enableProfileInstructionTemplates) {
176
+ }
177
+ const response = {
178
+ agent: {
179
+ id: agentWithProfile.id,
180
+ name: agentWithProfile.name,
181
+ profileId: agentWithProfile.profileId,
182
+ description: agentWithProfile.description,
183
+ profile: profile
184
+ ? {
185
+ id: profile.id,
186
+ name: profile.name,
187
+ instructions: profile.instructions ?? null,
188
+ instructionsResolved: resolvedInstructions ?? undefined,
189
+ }
190
+ : undefined,
191
+ },
192
+ };
193
+ return { success: true, data: response };
194
+ }
195
+ async function handleListStatuses(ctx, params) {
196
+ const validated = mcp_dto_1.ListStatusesParamsSchema.parse(params);
197
+ const sessionCtxResult = await resolveSessionContext(ctx, validated.sessionId);
198
+ if (!sessionCtxResult.success)
199
+ return sessionCtxResult;
200
+ const { project } = sessionCtxResult.data;
201
+ if (!project) {
202
+ return {
203
+ success: false,
204
+ error: {
205
+ code: 'PROJECT_NOT_FOUND',
206
+ message: 'No project associated with this session',
207
+ },
208
+ };
209
+ }
210
+ const result = await ctx.storage.listStatuses(project.id, {
211
+ limit: 1000,
212
+ offset: 0,
213
+ });
214
+ const response = {
215
+ statuses: result.items.map((status) => (0, dto_mappers_1.mapStatusSummary)(status)),
216
+ };
217
+ return { success: true, data: response };
218
+ }
219
+ async function handleListEpics(ctx, params) {
220
+ const validated = mcp_dto_1.ListEpicsParamsSchema.parse(params);
221
+ const sessionCtxResult = await resolveSessionContext(ctx, validated.sessionId);
222
+ if (!sessionCtxResult.success)
223
+ return sessionCtxResult;
224
+ const { project } = sessionCtxResult.data;
225
+ if (!project) {
226
+ return {
227
+ success: false,
228
+ error: {
229
+ code: 'PROJECT_NOT_FOUND',
230
+ message: 'No project associated with this session',
231
+ },
232
+ };
233
+ }
234
+ let statusId;
235
+ if (validated.statusName) {
236
+ const status = await ctx.storage.findStatusByName(project.id, validated.statusName);
237
+ if (!status) {
238
+ return {
239
+ success: false,
240
+ error: {
241
+ code: 'STATUS_NOT_FOUND',
242
+ message: `Status "${validated.statusName}" was not found for project ${project.id}.`,
243
+ },
244
+ };
245
+ }
246
+ statusId = status.id;
247
+ }
248
+ const limit = validated.limit ?? 100;
249
+ const offset = validated.offset ?? 0;
250
+ const query = validated.q?.trim();
251
+ const result = await ctx.storage.listProjectEpics(project.id, {
252
+ statusId,
253
+ q: query && query.length ? query : undefined,
254
+ limit,
255
+ offset,
256
+ excludeMcpHidden: true,
257
+ parentOnly: true,
258
+ });
259
+ const statusesResult = await ctx.storage.listStatuses(project.id, {
260
+ limit: 1000,
261
+ offset: 0,
262
+ });
263
+ const statusById = new Map();
264
+ for (const s of statusesResult.items)
265
+ statusById.set(s.id, s);
266
+ const agentIds = new Set();
267
+ for (const epic of result.items) {
268
+ if (epic.agentId)
269
+ agentIds.add(epic.agentId);
270
+ }
271
+ const agentNameById = new Map();
272
+ for (const agentId of agentIds) {
273
+ try {
274
+ const agent = await ctx.storage.getAgent(agentId);
275
+ agentNameById.set(agentId, agent.name);
276
+ }
277
+ catch (error) {
278
+ logger.warn({ agentId }, 'Failed to resolve agent name');
279
+ }
280
+ }
281
+ const parentIds = result.items.map((epic) => epic.id);
282
+ const subEpicsMap = await ctx.storage.listSubEpicsForParents(project.id, parentIds, {
283
+ excludeMcpHidden: true,
284
+ type: 'active',
285
+ limitPerParent: 50,
286
+ });
287
+ const epicsWithStatus = result.items.map((epic) => {
288
+ const summary = (0, dto_mappers_1.mapEpicSummary)(epic, agentNameById);
289
+ const status = statusById.get(epic.statusId);
290
+ if (status) {
291
+ summary.status = (0, dto_mappers_1.mapStatusSummary)(status);
292
+ }
293
+ const subEpics = subEpicsMap.get(epic.id) ?? [];
294
+ summary.subEpics = subEpics.map((subEpic) => {
295
+ const child = (0, dto_mappers_1.mapEpicChild)(subEpic);
296
+ const subStatus = statusById.get(subEpic.statusId);
297
+ if (subStatus) {
298
+ child.status = (0, dto_mappers_1.mapStatusSummary)(subStatus);
299
+ }
300
+ return child;
301
+ });
302
+ return summary;
303
+ });
304
+ const response = {
305
+ epics: epicsWithStatus,
306
+ total: result.total,
307
+ limit: result.limit,
308
+ offset: result.offset,
309
+ };
310
+ return { success: true, data: response };
311
+ }
312
+ async function handleListAssignedEpicsTasks(ctx, params) {
313
+ const validated = mcp_dto_1.ListAssignedEpicsTasksParamsSchema.parse(params);
314
+ const sessionCtxResult = await resolveSessionContext(ctx, validated.sessionId);
315
+ if (!sessionCtxResult.success)
316
+ return sessionCtxResult;
317
+ const { project } = sessionCtxResult.data;
318
+ if (!project) {
319
+ return {
320
+ success: false,
321
+ error: {
322
+ code: 'PROJECT_NOT_FOUND',
323
+ message: 'No project associated with this session',
324
+ },
325
+ };
326
+ }
327
+ const limit = validated.limit ?? 100;
328
+ const offset = validated.offset ?? 0;
329
+ try {
330
+ const result = await ctx.storage.listAssignedEpics(project.id, {
331
+ agentName: validated.agentName,
332
+ limit,
333
+ offset,
334
+ excludeMcpHidden: true,
335
+ });
336
+ const statusesResult = await ctx.storage.listStatuses(project.id, {
337
+ limit: 1000,
338
+ offset: 0,
339
+ });
340
+ const statusById = new Map();
341
+ for (const s of statusesResult.items)
342
+ statusById.set(s.id, s);
343
+ const agentIds = new Set();
344
+ for (const epic of result.items) {
345
+ if (epic.agentId)
346
+ agentIds.add(epic.agentId);
347
+ }
348
+ const agentNameById = new Map();
349
+ for (const agentId of agentIds) {
350
+ try {
351
+ const agent = await ctx.storage.getAgent(agentId);
352
+ agentNameById.set(agentId, agent.name);
353
+ }
354
+ catch (error) {
355
+ logger.warn({ agentId }, 'Failed to resolve agent name');
356
+ }
357
+ }
358
+ const epicsWithStatus = result.items.map((epic) => {
359
+ const summary = (0, dto_mappers_1.mapEpicSummary)(epic, agentNameById);
360
+ const status = statusById.get(epic.statusId);
361
+ if (status) {
362
+ summary.status = (0, dto_mappers_1.mapStatusSummary)(status);
363
+ }
364
+ return summary;
365
+ });
366
+ const response = {
367
+ epics: epicsWithStatus,
368
+ total: result.total,
369
+ limit: result.limit,
370
+ offset: result.offset,
371
+ };
372
+ return { success: true, data: response };
373
+ }
374
+ catch (error) {
375
+ if (error instanceof error_types_1.NotFoundError) {
376
+ return {
377
+ success: false,
378
+ error: {
379
+ code: 'AGENT_NOT_FOUND',
380
+ message: `Agent "${validated.agentName}" was not found for project ${project.id}.`,
381
+ },
382
+ };
383
+ }
384
+ if (error instanceof error_types_1.ValidationError) {
385
+ return {
386
+ success: false,
387
+ error: {
388
+ code: 'VALIDATION_ERROR',
389
+ message: error.message,
390
+ data: error.details,
391
+ },
392
+ };
393
+ }
394
+ throw error;
395
+ }
396
+ }
397
+ async function handleCreateEpic(ctx, params) {
398
+ if (!ctx.epicsService) {
399
+ return {
400
+ success: false,
401
+ error: {
402
+ code: 'SERVICE_UNAVAILABLE',
403
+ message: 'Epic creation requires full app context (not available in standalone MCP mode)',
404
+ },
405
+ };
406
+ }
407
+ const validated = mcp_dto_1.CreateEpicParamsSchema.parse(params);
408
+ const sessionCtxResult = await resolveSessionContext(ctx, validated.sessionId);
409
+ if (!sessionCtxResult.success)
410
+ return sessionCtxResult;
411
+ const { project } = sessionCtxResult.data;
412
+ if (!project) {
413
+ return {
414
+ success: false,
415
+ error: {
416
+ code: 'PROJECT_NOT_FOUND',
417
+ message: 'No project associated with this session',
418
+ },
419
+ };
420
+ }
421
+ let statusId;
422
+ if (validated.statusName) {
423
+ const status = await ctx.storage.findStatusByName(project.id, validated.statusName);
424
+ if (!status) {
425
+ const statusesResult = await ctx.storage.listStatuses(project.id, {
426
+ limit: 1000,
427
+ offset: 0,
428
+ });
429
+ return {
430
+ success: false,
431
+ error: {
432
+ code: 'STATUS_NOT_FOUND',
433
+ message: `Status "${validated.statusName}" was not found for project.`,
434
+ data: {
435
+ availableStatuses: statusesResult.items.map((s) => ({ id: s.id, name: s.label })),
436
+ },
437
+ },
438
+ };
439
+ }
440
+ statusId = status.id;
441
+ }
442
+ try {
443
+ const sessionCtx = sessionCtxResult.data;
444
+ const actor = sessionCtx.type === 'agent'
445
+ ? { type: 'agent', id: sessionCtx.agent.id }
446
+ : sessionCtx.type === 'guest'
447
+ ? { type: 'guest', id: sessionCtx.guest.id }
448
+ : null;
449
+ const context = { actor };
450
+ const epic = await ctx.epicsService.createEpicForProject(project.id, {
451
+ title: validated.title,
452
+ description: validated.description ?? null,
453
+ statusId,
454
+ tags: validated.tags ?? [],
455
+ agentName: validated.agentName,
456
+ parentId: validated.parentId ?? null,
457
+ skillsRequired: validated.skillsRequired ?? null,
458
+ }, context);
459
+ let agentNameById;
460
+ if (epic.agentId) {
461
+ agentNameById = new Map();
462
+ try {
463
+ const agent = await ctx.storage.getAgent(epic.agentId);
464
+ agentNameById.set(epic.agentId, agent.name);
465
+ }
466
+ catch (error) {
467
+ logger.warn({ agentId: epic.agentId }, 'Failed to resolve agent name');
468
+ }
469
+ }
470
+ const response = {
471
+ epic: (0, dto_mappers_1.mapEpicSummary)(epic, agentNameById),
472
+ };
473
+ return { success: true, data: response };
474
+ }
475
+ catch (error) {
476
+ if (error instanceof error_types_1.NotFoundError) {
477
+ return {
478
+ success: false,
479
+ error: {
480
+ code: 'AGENT_NOT_FOUND',
481
+ message: `Agent "${validated.agentName}" was not found for project ${project.id}.`,
482
+ },
483
+ };
484
+ }
485
+ if (error instanceof error_types_1.ValidationError) {
486
+ return {
487
+ success: false,
488
+ error: {
489
+ code: 'VALIDATION_ERROR',
490
+ message: error.message,
491
+ data: error.details,
492
+ },
493
+ };
494
+ }
495
+ throw error;
496
+ }
497
+ }
498
+ async function handleGetEpicById(ctx, params) {
499
+ const validated = mcp_dto_1.GetEpicByIdParamsSchema.parse(params);
500
+ const sessionCtxResult = await resolveSessionContext(ctx, validated.sessionId);
501
+ if (!sessionCtxResult.success)
502
+ return sessionCtxResult;
503
+ const { project } = sessionCtxResult.data;
504
+ if (!project) {
505
+ return {
506
+ success: false,
507
+ error: {
508
+ code: 'PROJECT_NOT_FOUND',
509
+ message: 'No project associated with this session',
510
+ },
511
+ };
512
+ }
513
+ const resolved = await (0, resolve_epic_id_1.resolveEpicId)(ctx.storage, project.id, validated.id);
514
+ if (!resolved.success)
515
+ return resolved;
516
+ const epicId = resolved.data.epicId;
517
+ let epic;
518
+ try {
519
+ epic = await ctx.storage.getEpic(epicId);
520
+ }
521
+ catch (error) {
522
+ if (error instanceof error_types_1.NotFoundError) {
523
+ return {
524
+ success: false,
525
+ error: {
526
+ code: 'EPIC_NOT_FOUND',
527
+ message: `Epic ${epicId} was not found.`,
528
+ },
529
+ };
530
+ }
531
+ throw error;
532
+ }
533
+ if (epic.projectId !== project.id) {
534
+ return {
535
+ success: false,
536
+ error: {
537
+ code: 'EPIC_NOT_FOUND',
538
+ message: `Epic ${epicId} does not belong to the resolved project.`,
539
+ },
540
+ };
541
+ }
542
+ const commentsResult = await ctx.storage.listEpicComments(epic.id, {
543
+ limit: 250,
544
+ offset: 0,
545
+ });
546
+ const subEpicsResult = await ctx.storage.listSubEpics(epic.id, { limit: 250, offset: 0 });
547
+ let parentEpic;
548
+ if (epic.parentId) {
549
+ try {
550
+ const parent = await ctx.storage.getEpic(epic.parentId);
551
+ if (parent.projectId === project.id) {
552
+ parentEpic = parent;
553
+ }
554
+ }
555
+ catch (error) {
556
+ if (error instanceof error_types_1.NotFoundError) {
557
+ logger.warn({ epicId: epic.id, parentId: epic.parentId }, 'Parent epic missing');
558
+ }
559
+ else {
560
+ throw error;
561
+ }
562
+ }
563
+ }
564
+ const statusesResult = await ctx.storage.listStatuses(project.id, {
565
+ limit: 1000,
566
+ offset: 0,
567
+ });
568
+ const statusById = new Map();
569
+ for (const s of statusesResult.items)
570
+ statusById.set(s.id, s);
571
+ const agentIds = new Set();
572
+ if (epic.agentId)
573
+ agentIds.add(epic.agentId);
574
+ for (const child of subEpicsResult.items) {
575
+ if (child.agentId)
576
+ agentIds.add(child.agentId);
577
+ }
578
+ if (parentEpic?.agentId)
579
+ agentIds.add(parentEpic.agentId);
580
+ const agentNameById = new Map();
581
+ for (const agentId of agentIds) {
582
+ try {
583
+ const agent = await ctx.storage.getAgent(agentId);
584
+ agentNameById.set(agentId, agent.name);
585
+ }
586
+ catch (error) {
587
+ logger.warn({ agentId }, 'Failed to resolve agent name');
588
+ }
589
+ }
590
+ let parentSummary;
591
+ if (parentEpic) {
592
+ parentSummary = (0, dto_mappers_1.mapEpicParent)(parentEpic, agentNameById);
593
+ }
594
+ const epicSummary = (0, dto_mappers_1.mapEpicSummary)(epic, agentNameById);
595
+ const epicStatus = statusById.get(epic.statusId);
596
+ if (epicStatus) {
597
+ epicSummary.status = (0, dto_mappers_1.mapStatusSummary)(epicStatus);
598
+ }
599
+ const subEpicsWithStatus = subEpicsResult.items.map((child) => {
600
+ const childSummary = (0, dto_mappers_1.mapEpicChild)(child);
601
+ const childStatus = statusById.get(child.statusId);
602
+ if (childStatus) {
603
+ childSummary.status = (0, dto_mappers_1.mapStatusSummary)(childStatus);
604
+ }
605
+ return childSummary;
606
+ });
607
+ const response = {
608
+ epic: epicSummary,
609
+ comments: [...commentsResult.items]
610
+ .reverse()
611
+ .map((comment, idx) => ({ ...(0, dto_mappers_1.mapEpicComment)(comment), commentNumber: idx + 1 })),
612
+ subEpics: subEpicsWithStatus,
613
+ };
614
+ if (parentSummary) {
615
+ response.parent = parentSummary;
616
+ }
617
+ return { success: true, data: response };
618
+ }
619
+ async function handleAddEpicComment(ctx, params) {
620
+ const validated = mcp_dto_1.AddEpicCommentParamsSchema.parse(params);
621
+ const sessionCtxResult = await resolveSessionContext(ctx, validated.sessionId);
622
+ if (!sessionCtxResult.success)
623
+ return sessionCtxResult;
624
+ const sessionCtx = sessionCtxResult.data;
625
+ const authorActor = getActorFromContext(sessionCtx);
626
+ if (!authorActor) {
627
+ return {
628
+ success: false,
629
+ error: {
630
+ code: 'AGENT_REQUIRED',
631
+ message: 'Session must be associated with an agent or guest to add comments',
632
+ },
633
+ };
634
+ }
635
+ const project = sessionCtx.project;
636
+ if (!project) {
637
+ return {
638
+ success: false,
639
+ error: {
640
+ code: 'PROJECT_NOT_FOUND',
641
+ message: 'No project associated with this session',
642
+ },
643
+ };
644
+ }
645
+ const resolved = await (0, resolve_epic_id_1.resolveEpicId)(ctx.storage, project.id, validated.epicId);
646
+ if (!resolved.success)
647
+ return resolved;
648
+ const epicId = resolved.data.epicId;
649
+ let epic;
650
+ try {
651
+ epic = await ctx.storage.getEpic(epicId);
652
+ }
653
+ catch (error) {
654
+ if (error instanceof error_types_1.NotFoundError) {
655
+ return {
656
+ success: false,
657
+ error: {
658
+ code: 'EPIC_NOT_FOUND',
659
+ message: `Epic ${epicId} was not found.`,
660
+ },
661
+ };
662
+ }
663
+ throw error;
664
+ }
665
+ if (epic.projectId !== project.id) {
666
+ return {
667
+ success: false,
668
+ error: {
669
+ code: 'EPIC_NOT_FOUND',
670
+ message: `Epic ${epicId} does not belong to the resolved project.`,
671
+ },
672
+ };
673
+ }
674
+ const comment = await ctx.storage.createEpicComment({
675
+ epicId,
676
+ authorName: authorActor.name,
677
+ content: validated.content,
678
+ });
679
+ const response = {
680
+ comment: (0, dto_mappers_1.mapEpicComment)(comment),
681
+ };
682
+ return { success: true, data: response };
683
+ }
684
+ async function handleUpdateEpic(ctx, params) {
685
+ if (!ctx.epicsService) {
686
+ return {
687
+ success: false,
688
+ error: {
689
+ code: 'SERVICE_UNAVAILABLE',
690
+ message: 'Epic updates require full app context (not available in standalone MCP mode)',
691
+ },
692
+ };
693
+ }
694
+ let preprocessedParams = params;
695
+ if (params && typeof params === 'object' && 'assignment' in params) {
696
+ const p = params;
697
+ if (typeof p.assignment === 'string') {
698
+ try {
699
+ preprocessedParams = { ...p, assignment: JSON.parse(p.assignment) };
700
+ }
701
+ catch {
702
+ }
703
+ }
704
+ }
705
+ const validated = mcp_dto_1.UpdateEpicParamsSchema.parse(preprocessedParams);
706
+ const sessionCtxResult = await resolveSessionContext(ctx, validated.sessionId);
707
+ if (!sessionCtxResult.success)
708
+ return sessionCtxResult;
709
+ const { project } = sessionCtxResult.data;
710
+ if (!project) {
711
+ return {
712
+ success: false,
713
+ error: {
714
+ code: 'PROJECT_NOT_FOUND',
715
+ message: 'No project associated with this session',
716
+ },
717
+ };
718
+ }
719
+ const resolved = await (0, resolve_epic_id_1.resolveEpicId)(ctx.storage, project.id, validated.id);
720
+ if (!resolved.success)
721
+ return resolved;
722
+ const epicId = resolved.data.epicId;
723
+ let epic;
724
+ try {
725
+ epic = await ctx.storage.getEpic(epicId);
726
+ }
727
+ catch (error) {
728
+ if (error instanceof error_types_1.NotFoundError) {
729
+ return {
730
+ success: false,
731
+ error: {
732
+ code: 'EPIC_NOT_FOUND',
733
+ message: `Epic ${epicId} was not found.`,
734
+ },
735
+ };
736
+ }
737
+ throw error;
738
+ }
739
+ if (epic.projectId !== project.id) {
740
+ return {
741
+ success: false,
742
+ error: {
743
+ code: 'EPIC_NOT_FOUND',
744
+ message: `Epic ${epicId} does not belong to the resolved project.`,
745
+ },
746
+ };
747
+ }
748
+ const updateData = {};
749
+ if (validated.title !== undefined) {
750
+ updateData.title = validated.title;
751
+ }
752
+ if (validated.description !== undefined) {
753
+ updateData.description = validated.description;
754
+ }
755
+ if (validated.skillsRequired !== undefined) {
756
+ updateData.skillsRequired = validated.skillsRequired;
757
+ }
758
+ if (validated.statusName) {
759
+ const status = await ctx.storage.findStatusByName(project.id, validated.statusName);
760
+ if (!status) {
761
+ const statusesResult = await ctx.storage.listStatuses(project.id, {
762
+ limit: 1000,
763
+ offset: 0,
764
+ });
765
+ return {
766
+ success: false,
767
+ error: {
768
+ code: 'STATUS_NOT_FOUND',
769
+ message: `Status "${validated.statusName}" was not found for project.`,
770
+ data: {
771
+ availableStatuses: statusesResult.items.map((s) => ({ id: s.id, name: s.label })),
772
+ },
773
+ },
774
+ };
775
+ }
776
+ updateData.statusId = status.id;
777
+ }
778
+ if (validated.assignment) {
779
+ if ('clear' in validated.assignment && validated.assignment.clear) {
780
+ updateData.agentId = null;
781
+ }
782
+ else if ('agentName' in validated.assignment) {
783
+ try {
784
+ const agent = await ctx.storage.getAgentByName(project.id, validated.assignment.agentName);
785
+ updateData.agentId = agent.id;
786
+ }
787
+ catch (error) {
788
+ if (error instanceof error_types_1.NotFoundError) {
789
+ const agentsList = await ctx.storage.listAgents(project.id, {
790
+ limit: 1000,
791
+ offset: 0,
792
+ });
793
+ return {
794
+ success: false,
795
+ error: {
796
+ code: 'AGENT_NOT_FOUND',
797
+ message: `Agent "${validated.assignment.agentName}" was not found for project.`,
798
+ data: {
799
+ availableAgents: agentsList.items.map((a) => ({ id: a.id, name: a.name })),
800
+ },
801
+ },
802
+ };
803
+ }
804
+ throw error;
805
+ }
806
+ }
807
+ }
808
+ if (validated.clearParent) {
809
+ updateData.parentId = null;
810
+ }
811
+ else if (validated.parentId !== undefined) {
812
+ if (validated.parentId === epicId) {
813
+ return {
814
+ success: false,
815
+ error: {
816
+ code: 'PARENT_INVALID',
817
+ message: 'An epic cannot be its own parent.',
818
+ },
819
+ };
820
+ }
821
+ let parentEpic;
822
+ try {
823
+ parentEpic = await ctx.storage.getEpic(validated.parentId);
824
+ }
825
+ catch (error) {
826
+ if (error instanceof error_types_1.NotFoundError) {
827
+ return {
828
+ success: false,
829
+ error: {
830
+ code: 'PARENT_INVALID',
831
+ message: `Parent epic ${validated.parentId} was not found.`,
832
+ },
833
+ };
834
+ }
835
+ throw error;
836
+ }
837
+ if (parentEpic.projectId !== project.id) {
838
+ return {
839
+ success: false,
840
+ error: {
841
+ code: 'PARENT_INVALID',
842
+ message: 'Parent epic must belong to the same project.',
843
+ },
844
+ };
845
+ }
846
+ if (parentEpic.parentId !== null) {
847
+ return {
848
+ success: false,
849
+ error: {
850
+ code: 'HIERARCHY_CONFLICT',
851
+ message: 'Only one level of epic hierarchy is allowed. The specified parent already has a parent.',
852
+ },
853
+ };
854
+ }
855
+ updateData.parentId = validated.parentId;
856
+ }
857
+ if (validated.setTags !== undefined) {
858
+ updateData.tags = validated.setTags;
859
+ }
860
+ else if (validated.addTags || validated.removeTags) {
861
+ const currentTags = new Set(epic.tags);
862
+ if (validated.addTags) {
863
+ validated.addTags.forEach((tag) => currentTags.add(tag));
864
+ }
865
+ if (validated.removeTags) {
866
+ validated.removeTags.forEach((tag) => currentTags.delete(tag));
867
+ }
868
+ updateData.tags = Array.from(currentTags);
869
+ }
870
+ let updatedEpic;
871
+ try {
872
+ const sessionCtx = sessionCtxResult.data;
873
+ const actor = sessionCtx.type === 'agent'
874
+ ? { type: 'agent', id: sessionCtx.agent.id }
875
+ : sessionCtx.type === 'guest'
876
+ ? { type: 'guest', id: sessionCtx.guest.id }
877
+ : null;
878
+ const context = { actor };
879
+ updatedEpic = await ctx.epicsService.updateEpic(epicId, updateData, validated.version, context);
880
+ }
881
+ catch (error) {
882
+ if (error instanceof Error && error.message.includes('was modified by another operation')) {
883
+ const currentEpic = await ctx.storage.getEpic(epicId);
884
+ return {
885
+ success: false,
886
+ error: {
887
+ code: 'VERSION_CONFLICT',
888
+ message: `Epic version conflict. Expected version ${validated.version}, but current version is ${currentEpic.version}.`,
889
+ data: {
890
+ currentVersion: currentEpic.version,
891
+ },
892
+ },
893
+ };
894
+ }
895
+ throw error;
896
+ }
897
+ let agentNameById;
898
+ if (updatedEpic.agentId) {
899
+ agentNameById = new Map();
900
+ try {
901
+ const agent = await ctx.storage.getAgent(updatedEpic.agentId);
902
+ agentNameById.set(updatedEpic.agentId, agent.name);
903
+ }
904
+ catch (error) {
905
+ logger.warn({ agentId: updatedEpic.agentId }, 'Failed to resolve agent name');
906
+ }
907
+ }
908
+ const response = {
909
+ epic: (0, dto_mappers_1.mapEpicSummary)(updatedEpic, agentNameById),
910
+ };
911
+ return { success: true, data: response };
912
+ }
913
+ //# sourceMappingURL=epic-tools.js.map