@graychennpm/codebridge 0.0.0-stage → 0.1.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 (434) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/LICENSE +21 -0
  3. package/README.md +217 -2
  4. package/README.zh-CN.md +222 -0
  5. package/apps/web/public/brand/agent-logo-carbon.svg +1 -0
  6. package/apps/web/public/brand/agent-logo.svg +1 -0
  7. package/docs/zh-CN/npm-release.md +77 -0
  8. package/node_modules/@codebridge/agent-registry/dist/index.d.ts +32 -0
  9. package/node_modules/@codebridge/agent-registry/dist/index.js +177 -0
  10. package/node_modules/@codebridge/agent-registry/dist/setup.d.ts +9 -0
  11. package/node_modules/@codebridge/agent-registry/dist/setup.js +115 -0
  12. package/node_modules/@codebridge/agent-registry/package.json +17 -0
  13. package/node_modules/@codebridge/backends/dist/acp/acp-active-session.d.ts +12 -0
  14. package/node_modules/@codebridge/backends/dist/acp/acp-active-session.js +57 -0
  15. package/node_modules/@codebridge/backends/dist/acp/acp-claude-activity.d.ts +9 -0
  16. package/node_modules/@codebridge/backends/dist/acp/acp-claude-activity.js +49 -0
  17. package/node_modules/@codebridge/backends/dist/acp/acp-config-options.d.ts +46 -0
  18. package/node_modules/@codebridge/backends/dist/acp/acp-config-options.js +220 -0
  19. package/node_modules/@codebridge/backends/dist/acp/acp-doctor.d.ts +3 -0
  20. package/node_modules/@codebridge/backends/dist/acp/acp-doctor.js +18 -0
  21. package/node_modules/@codebridge/backends/dist/acp/acp-event-mapper.d.ts +5 -0
  22. package/node_modules/@codebridge/backends/dist/acp/acp-event-mapper.js +136 -0
  23. package/node_modules/@codebridge/backends/dist/acp/acp-kill.d.ts +10 -0
  24. package/node_modules/@codebridge/backends/dist/acp/acp-kill.js +24 -0
  25. package/node_modules/@codebridge/backends/dist/acp/acp-race.d.ts +6 -0
  26. package/node_modules/@codebridge/backends/dist/acp/acp-race.js +29 -0
  27. package/node_modules/@codebridge/backends/dist/acp/acp-session-list.d.ts +32 -0
  28. package/node_modules/@codebridge/backends/dist/acp/acp-session-list.js +218 -0
  29. package/node_modules/@codebridge/backends/dist/acp/acp-session-pool.d.ts +85 -0
  30. package/node_modules/@codebridge/backends/dist/acp/acp-session-pool.js +165 -0
  31. package/node_modules/@codebridge/backends/dist/acp/acp-session-runner.d.ts +78 -0
  32. package/node_modules/@codebridge/backends/dist/acp/acp-session-runner.js +550 -0
  33. package/node_modules/@codebridge/backends/dist/acp/acp-spawn-profiles.d.ts +9 -0
  34. package/node_modules/@codebridge/backends/dist/acp/acp-spawn-profiles.js +28 -0
  35. package/node_modules/@codebridge/backends/dist/acp/headless-client.d.ts +19 -0
  36. package/node_modules/@codebridge/backends/dist/acp/headless-client.js +47 -0
  37. package/node_modules/@codebridge/backends/dist/acp/index.d.ts +9 -0
  38. package/node_modules/@codebridge/backends/dist/acp/index.js +9 -0
  39. package/node_modules/@codebridge/backends/dist/agent-setup.d.ts +60 -0
  40. package/node_modules/@codebridge/backends/dist/agent-setup.js +504 -0
  41. package/node_modules/@codebridge/backends/dist/attachment-prompt.d.ts +8 -0
  42. package/node_modules/@codebridge/backends/dist/attachment-prompt.js +28 -0
  43. package/node_modules/@codebridge/backends/dist/auth-error-hints.d.ts +8 -0
  44. package/node_modules/@codebridge/backends/dist/auth-error-hints.js +33 -0
  45. package/node_modules/@codebridge/backends/dist/codex-skill-commands.d.ts +3 -0
  46. package/node_modules/@codebridge/backends/dist/codex-skill-commands.js +88 -0
  47. package/node_modules/@codebridge/backends/dist/index.d.ts +18 -0
  48. package/node_modules/@codebridge/backends/dist/index.js +34 -0
  49. package/node_modules/@codebridge/backends/dist/pi-providers.d.ts +45 -0
  50. package/node_modules/@codebridge/backends/dist/pi-providers.js +148 -0
  51. package/node_modules/@codebridge/backends/dist/pi-session-runner.d.ts +85 -0
  52. package/node_modules/@codebridge/backends/dist/pi-session-runner.js +460 -0
  53. package/node_modules/@codebridge/backends/dist/provider-connection.d.ts +17 -0
  54. package/node_modules/@codebridge/backends/dist/provider-connection.js +99 -0
  55. package/node_modules/@codebridge/backends/dist/session-discovery.d.ts +23 -0
  56. package/node_modules/@codebridge/backends/dist/session-discovery.js +340 -0
  57. package/node_modules/@codebridge/backends/dist/skill-control-plane.d.ts +147 -0
  58. package/node_modules/@codebridge/backends/dist/skill-control-plane.js +832 -0
  59. package/node_modules/@codebridge/backends/package.json +22 -0
  60. package/node_modules/@codebridge/bridge/dist/alert-notification-rules.d.ts +14 -0
  61. package/node_modules/@codebridge/bridge/dist/alert-notification-rules.js +37 -0
  62. package/node_modules/@codebridge/bridge/dist/channel-config.d.ts +4 -0
  63. package/node_modules/@codebridge/bridge/dist/channel-config.js +9 -0
  64. package/node_modules/@codebridge/bridge/dist/channel-ingress.d.ts +5 -0
  65. package/node_modules/@codebridge/bridge/dist/channel-ingress.js +403 -0
  66. package/node_modules/@codebridge/bridge/dist/cli.d.ts +3 -0
  67. package/node_modules/@codebridge/bridge/dist/cli.js +581 -0
  68. package/node_modules/@codebridge/bridge/dist/deployment.d.ts +46 -0
  69. package/node_modules/@codebridge/bridge/dist/deployment.js +174 -0
  70. package/node_modules/@codebridge/bridge/dist/event-loop-lag.d.ts +19 -0
  71. package/node_modules/@codebridge/bridge/dist/event-loop-lag.js +33 -0
  72. package/node_modules/@codebridge/bridge/dist/feishu-alert-monitor.d.ts +70 -0
  73. package/node_modules/@codebridge/bridge/dist/feishu-alert-monitor.js +591 -0
  74. package/node_modules/@codebridge/bridge/dist/init-wizard.d.ts +52 -0
  75. package/node_modules/@codebridge/bridge/dist/init-wizard.js +571 -0
  76. package/node_modules/@codebridge/bridge/dist/mcp-api.d.ts +4 -0
  77. package/node_modules/@codebridge/bridge/dist/mcp-api.js +100 -0
  78. package/node_modules/@codebridge/bridge/dist/outbound-api.d.ts +31 -0
  79. package/node_modules/@codebridge/bridge/dist/outbound-api.js +184 -0
  80. package/node_modules/@codebridge/bridge/dist/outbound-publishers.d.ts +54 -0
  81. package/node_modules/@codebridge/bridge/dist/outbound-publishers.js +213 -0
  82. package/node_modules/@codebridge/bridge/dist/project-api.d.ts +4 -0
  83. package/node_modules/@codebridge/bridge/dist/project-api.js +161 -0
  84. package/node_modules/@codebridge/bridge/dist/secrets-command.d.ts +13 -0
  85. package/node_modules/@codebridge/bridge/dist/secrets-command.js +34 -0
  86. package/node_modules/@codebridge/bridge/dist/session-api.d.ts +26 -0
  87. package/node_modules/@codebridge/bridge/dist/session-api.js +1378 -0
  88. package/node_modules/@codebridge/bridge/dist/session-history-import.d.ts +24 -0
  89. package/node_modules/@codebridge/bridge/dist/session-history-import.js +82 -0
  90. package/node_modules/@codebridge/bridge/dist/session-runtime-api.d.ts +19 -0
  91. package/node_modules/@codebridge/bridge/dist/session-runtime-api.js +453 -0
  92. package/node_modules/@codebridge/bridge/dist/session-runtime-migration.d.ts +21 -0
  93. package/node_modules/@codebridge/bridge/dist/session-runtime-migration.js +43 -0
  94. package/node_modules/@codebridge/bridge/dist/session-runtime-types.d.ts +85 -0
  95. package/node_modules/@codebridge/bridge/dist/session-runtime-types.js +98 -0
  96. package/node_modules/@codebridge/bridge/dist/skill-api.d.ts +28 -0
  97. package/node_modules/@codebridge/bridge/dist/skill-api.js +129 -0
  98. package/node_modules/@codebridge/bridge/dist/startup-surfaces.d.ts +15 -0
  99. package/node_modules/@codebridge/bridge/dist/startup-surfaces.js +13 -0
  100. package/node_modules/@codebridge/bridge/dist/web-frontend.d.ts +8 -0
  101. package/node_modules/@codebridge/bridge/dist/web-frontend.js +76 -0
  102. package/node_modules/@codebridge/bridge/dist/work-item-api.d.ts +6 -0
  103. package/node_modules/@codebridge/bridge/dist/work-item-api.js +414 -0
  104. package/node_modules/@codebridge/bridge/package.json +28 -0
  105. package/node_modules/@codebridge/channel-feishu/dist/alert-reactions.d.ts +6 -0
  106. package/node_modules/@codebridge/channel-feishu/dist/alert-reactions.js +58 -0
  107. package/node_modules/@codebridge/channel-feishu/dist/alert-types.d.ts +35 -0
  108. package/node_modules/@codebridge/channel-feishu/dist/alert-types.js +2 -0
  109. package/node_modules/@codebridge/channel-feishu/dist/bridge.d.ts +130 -0
  110. package/node_modules/@codebridge/channel-feishu/dist/bridge.js +1231 -0
  111. package/node_modules/@codebridge/channel-feishu/dist/cardkit-writer.d.ts +48 -0
  112. package/node_modules/@codebridge/channel-feishu/dist/cardkit-writer.js +153 -0
  113. package/node_modules/@codebridge/channel-feishu/dist/chain-topics.d.ts +20 -0
  114. package/node_modules/@codebridge/channel-feishu/dist/chain-topics.js +35 -0
  115. package/node_modules/@codebridge/channel-feishu/dist/coalescing-card-writer.d.ts +12 -0
  116. package/node_modules/@codebridge/channel-feishu/dist/coalescing-card-writer.js +53 -0
  117. package/node_modules/@codebridge/channel-feishu/dist/delivery-reconciler.d.ts +19 -0
  118. package/node_modules/@codebridge/channel-feishu/dist/delivery-reconciler.js +53 -0
  119. package/node_modules/@codebridge/channel-feishu/dist/durable-markdown-card.d.ts +19 -0
  120. package/node_modules/@codebridge/channel-feishu/dist/durable-markdown-card.js +77 -0
  121. package/node_modules/@codebridge/channel-feishu/dist/feishu-extra-events.d.ts +27 -0
  122. package/node_modules/@codebridge/channel-feishu/dist/feishu-extra-events.js +24 -0
  123. package/node_modules/@codebridge/channel-feishu/dist/feishu-http.d.ts +4 -0
  124. package/node_modules/@codebridge/channel-feishu/dist/feishu-http.js +25 -0
  125. package/node_modules/@codebridge/channel-feishu/dist/feishu-inbound-context.d.ts +13 -0
  126. package/node_modules/@codebridge/channel-feishu/dist/feishu-inbound-context.js +45 -0
  127. package/node_modules/@codebridge/channel-feishu/dist/feishu-inbound-media.d.ts +22 -0
  128. package/node_modules/@codebridge/channel-feishu/dist/feishu-inbound-media.js +273 -0
  129. package/node_modules/@codebridge/channel-feishu/dist/feishu-mention-gate.d.ts +13 -0
  130. package/node_modules/@codebridge/channel-feishu/dist/feishu-mention-gate.js +22 -0
  131. package/node_modules/@codebridge/channel-feishu/dist/feishu-outbound-file.d.ts +12 -0
  132. package/node_modules/@codebridge/channel-feishu/dist/feishu-outbound-file.js +38 -0
  133. package/node_modules/@codebridge/channel-feishu/dist/feishu-quoted-message.d.ts +30 -0
  134. package/node_modules/@codebridge/channel-feishu/dist/feishu-quoted-message.js +183 -0
  135. package/node_modules/@codebridge/channel-feishu/dist/index.d.ts +7 -0
  136. package/node_modules/@codebridge/channel-feishu/dist/index.js +3 -0
  137. package/node_modules/@codebridge/channel-feishu/dist/redacting-logger.d.ts +17 -0
  138. package/node_modules/@codebridge/channel-feishu/dist/redacting-logger.js +41 -0
  139. package/node_modules/@codebridge/channel-feishu/dist/run-status.d.ts +39 -0
  140. package/node_modules/@codebridge/channel-feishu/dist/run-status.js +166 -0
  141. package/node_modules/@codebridge/channel-feishu/dist/session-watcher.d.ts +98 -0
  142. package/node_modules/@codebridge/channel-feishu/dist/session-watcher.js +655 -0
  143. package/node_modules/@codebridge/channel-feishu/package.json +19 -0
  144. package/node_modules/@codebridge/channel-telegram/dist/coalescing-message-writer.d.ts +14 -0
  145. package/node_modules/@codebridge/channel-telegram/dist/coalescing-message-writer.js +56 -0
  146. package/node_modules/@codebridge/channel-telegram/dist/index.d.ts +3 -0
  147. package/node_modules/@codebridge/channel-telegram/dist/index.js +3 -0
  148. package/node_modules/@codebridge/channel-telegram/dist/telegram-api.d.ts +62 -0
  149. package/node_modules/@codebridge/channel-telegram/dist/telegram-api.js +72 -0
  150. package/node_modules/@codebridge/channel-telegram/dist/telegram-bridge.d.ts +64 -0
  151. package/node_modules/@codebridge/channel-telegram/dist/telegram-bridge.js +469 -0
  152. package/node_modules/@codebridge/channel-telegram/dist/telegram-session-watcher.d.ts +41 -0
  153. package/node_modules/@codebridge/channel-telegram/dist/telegram-session-watcher.js +184 -0
  154. package/node_modules/@codebridge/channel-telegram/package.json +18 -0
  155. package/node_modules/@codebridge/core/dist/config-schema.d.ts +1195 -0
  156. package/node_modules/@codebridge/core/dist/config-schema.js +293 -0
  157. package/node_modules/@codebridge/core/dist/config-store.d.ts +48 -0
  158. package/node_modules/@codebridge/core/dist/config-store.js +207 -0
  159. package/node_modules/@codebridge/core/dist/index.d.ts +11 -0
  160. package/node_modules/@codebridge/core/dist/index.js +10 -0
  161. package/node_modules/@codebridge/core/dist/json-file-store.d.ts +16 -0
  162. package/node_modules/@codebridge/core/dist/json-file-store.js +46 -0
  163. package/node_modules/@codebridge/core/dist/mcp-types.d.ts +7 -0
  164. package/node_modules/@codebridge/core/dist/mcp-types.js +2 -0
  165. package/node_modules/@codebridge/core/dist/mentions.d.ts +36 -0
  166. package/node_modules/@codebridge/core/dist/mentions.js +138 -0
  167. package/node_modules/@codebridge/core/dist/secret-migration.d.ts +14 -0
  168. package/node_modules/@codebridge/core/dist/secret-migration.js +55 -0
  169. package/node_modules/@codebridge/core/dist/secret-refs.d.ts +34 -0
  170. package/node_modules/@codebridge/core/dist/secret-refs.js +142 -0
  171. package/node_modules/@codebridge/core/dist/session-event-wire.d.ts +17 -0
  172. package/node_modules/@codebridge/core/dist/session-event-wire.js +28 -0
  173. package/node_modules/@codebridge/core/dist/types.d.ts +363 -0
  174. package/node_modules/@codebridge/core/dist/types.js +22 -0
  175. package/node_modules/@codebridge/core/dist/workspace-key.d.ts +11 -0
  176. package/node_modules/@codebridge/core/dist/workspace-key.js +25 -0
  177. package/node_modules/@codebridge/core/package.json +22 -0
  178. package/node_modules/@codebridge/mcp-runtime/dist/.tsbuildinfo +1 -0
  179. package/node_modules/@codebridge/mcp-runtime/dist/index.d.ts +92 -0
  180. package/node_modules/@codebridge/mcp-runtime/dist/index.js +377 -0
  181. package/node_modules/@codebridge/mcp-runtime/package.json +19 -0
  182. package/node_modules/@codebridge/policy/dist/capability-runtime.d.ts +123 -0
  183. package/node_modules/@codebridge/policy/dist/capability-runtime.js +195 -0
  184. package/node_modules/@codebridge/policy/dist/demo-capabilities.d.ts +4 -0
  185. package/node_modules/@codebridge/policy/dist/demo-capabilities.js +134 -0
  186. package/node_modules/@codebridge/policy/dist/equity-capabilities.d.ts +8 -0
  187. package/node_modules/@codebridge/policy/dist/equity-capabilities.js +35 -0
  188. package/node_modules/@codebridge/policy/dist/index.d.ts +107 -0
  189. package/node_modules/@codebridge/policy/dist/index.js +317 -0
  190. package/node_modules/@codebridge/policy/package.json +17 -0
  191. package/node_modules/@codebridge/project-catalog/dist/index.d.ts +145 -0
  192. package/node_modules/@codebridge/project-catalog/dist/index.js +699 -0
  193. package/node_modules/@codebridge/project-catalog/package.json +18 -0
  194. package/node_modules/@codebridge/router/dist/channel-stream-projector.d.ts +19 -0
  195. package/node_modules/@codebridge/router/dist/channel-stream-projector.js +68 -0
  196. package/node_modules/@codebridge/router/dist/command-help.d.ts +14 -0
  197. package/node_modules/@codebridge/router/dist/command-help.js +151 -0
  198. package/node_modules/@codebridge/router/dist/feishu-stream-presenter.d.ts +18 -0
  199. package/node_modules/@codebridge/router/dist/feishu-stream-presenter.js +193 -0
  200. package/node_modules/@codebridge/router/dist/index.d.ts +9 -0
  201. package/node_modules/@codebridge/router/dist/index.js +9 -0
  202. package/node_modules/@codebridge/router/dist/model-effort.d.ts +5 -0
  203. package/node_modules/@codebridge/router/dist/model-effort.js +33 -0
  204. package/node_modules/@codebridge/router/dist/orchestrator.d.ts +56 -0
  205. package/node_modules/@codebridge/router/dist/orchestrator.js +290 -0
  206. package/node_modules/@codebridge/router/dist/session-list-format.d.ts +19 -0
  207. package/node_modules/@codebridge/router/dist/session-list-format.js +97 -0
  208. package/node_modules/@codebridge/router/dist/session-rotation.d.ts +9 -0
  209. package/node_modules/@codebridge/router/dist/session-rotation.js +31 -0
  210. package/node_modules/@codebridge/router/dist/session-router.d.ts +59 -0
  211. package/node_modules/@codebridge/router/dist/session-router.js +182 -0
  212. package/node_modules/@codebridge/router/dist/slash-commands.d.ts +78 -0
  213. package/node_modules/@codebridge/router/dist/slash-commands.js +874 -0
  214. package/node_modules/@codebridge/router/package.json +18 -0
  215. package/node_modules/@codebridge/run-executor/dist/agent-event-aggregator.d.ts +18 -0
  216. package/node_modules/@codebridge/run-executor/dist/agent-event-aggregator.js +88 -0
  217. package/node_modules/@codebridge/run-executor/dist/index.d.ts +55 -0
  218. package/node_modules/@codebridge/run-executor/dist/index.js +754 -0
  219. package/node_modules/@codebridge/run-executor/dist/run-heartbeat.d.ts +14 -0
  220. package/node_modules/@codebridge/run-executor/dist/run-heartbeat.js +24 -0
  221. package/node_modules/@codebridge/run-executor/package.json +20 -0
  222. package/node_modules/@codebridge/runner-client/dist/index.d.ts +142 -0
  223. package/node_modules/@codebridge/runner-client/dist/index.js +439 -0
  224. package/node_modules/@codebridge/runner-client/package.json +18 -0
  225. package/node_modules/@codebridge/runner-host/dist/cli.d.ts +3 -0
  226. package/node_modules/@codebridge/runner-host/dist/cli.js +58 -0
  227. package/node_modules/@codebridge/runner-host/dist/codex-session-ownership.d.ts +13 -0
  228. package/node_modules/@codebridge/runner-host/dist/codex-session-ownership.js +79 -0
  229. package/node_modules/@codebridge/runner-host/dist/deployment-mcp-server.d.ts +10 -0
  230. package/node_modules/@codebridge/runner-host/dist/deployment-mcp-server.js +54 -0
  231. package/node_modules/@codebridge/runner-host/dist/fcb-script.d.ts +3 -0
  232. package/node_modules/@codebridge/runner-host/dist/fcb-script.js +99 -0
  233. package/node_modules/@codebridge/runner-host/dist/index.d.ts +3 -0
  234. package/node_modules/@codebridge/runner-host/dist/index.js +2 -0
  235. package/node_modules/@codebridge/runner-host/dist/materialize-attachments.d.ts +4 -0
  236. package/node_modules/@codebridge/runner-host/dist/materialize-attachments.js +62 -0
  237. package/node_modules/@codebridge/runner-host/dist/server.d.ts +150 -0
  238. package/node_modules/@codebridge/runner-host/dist/server.js +1295 -0
  239. package/node_modules/@codebridge/runner-host/dist/session-lease.d.ts +12 -0
  240. package/node_modules/@codebridge/runner-host/dist/session-lease.js +146 -0
  241. package/node_modules/@codebridge/runner-host/package.json +26 -0
  242. package/node_modules/@codebridge/session-catalog/dist/index.d.ts +124 -0
  243. package/node_modules/@codebridge/session-catalog/dist/index.js +411 -0
  244. package/node_modules/@codebridge/session-catalog/package.json +17 -0
  245. package/node_modules/@codebridge/session-coordinator/dist/coordinator.d.ts +111 -0
  246. package/node_modules/@codebridge/session-coordinator/dist/coordinator.js +364 -0
  247. package/node_modules/@codebridge/session-coordinator/dist/index.d.ts +5 -0
  248. package/node_modules/@codebridge/session-coordinator/dist/index.js +5 -0
  249. package/node_modules/@codebridge/session-coordinator/dist/lease.d.ts +14 -0
  250. package/node_modules/@codebridge/session-coordinator/dist/lease.js +26 -0
  251. package/node_modules/@codebridge/session-coordinator/dist/queued-claim.d.ts +20 -0
  252. package/node_modules/@codebridge/session-coordinator/dist/queued-claim.js +45 -0
  253. package/node_modules/@codebridge/session-coordinator/dist/recovery.d.ts +31 -0
  254. package/node_modules/@codebridge/session-coordinator/dist/recovery.js +114 -0
  255. package/node_modules/@codebridge/session-coordinator/package.json +17 -0
  256. package/node_modules/@codebridge/web/dist/assets/KaTeX_AMS-Regular-BQhdFMY1.woff2 +0 -0
  257. package/node_modules/@codebridge/web/dist/assets/KaTeX_AMS-Regular-DMm9YOAa.woff +0 -0
  258. package/node_modules/@codebridge/web/dist/assets/KaTeX_AMS-Regular-DRggAlZN.ttf +0 -0
  259. package/node_modules/@codebridge/web/dist/assets/KaTeX_Caligraphic-Bold-ATXxdsX0.ttf +0 -0
  260. package/node_modules/@codebridge/web/dist/assets/KaTeX_Caligraphic-Bold-BEiXGLvX.woff +0 -0
  261. package/node_modules/@codebridge/web/dist/assets/KaTeX_Caligraphic-Bold-Dq_IR9rO.woff2 +0 -0
  262. package/node_modules/@codebridge/web/dist/assets/KaTeX_Caligraphic-Regular-CTRA-rTL.woff +0 -0
  263. package/node_modules/@codebridge/web/dist/assets/KaTeX_Caligraphic-Regular-Di6jR-x-.woff2 +0 -0
  264. package/node_modules/@codebridge/web/dist/assets/KaTeX_Caligraphic-Regular-wX97UBjC.ttf +0 -0
  265. package/node_modules/@codebridge/web/dist/assets/KaTeX_Fraktur-Bold-BdnERNNW.ttf +0 -0
  266. package/node_modules/@codebridge/web/dist/assets/KaTeX_Fraktur-Bold-BsDP51OF.woff +0 -0
  267. package/node_modules/@codebridge/web/dist/assets/KaTeX_Fraktur-Bold-CL6g_b3V.woff2 +0 -0
  268. package/node_modules/@codebridge/web/dist/assets/KaTeX_Fraktur-Regular-CB_wures.ttf +0 -0
  269. package/node_modules/@codebridge/web/dist/assets/KaTeX_Fraktur-Regular-CTYiF6lA.woff2 +0 -0
  270. package/node_modules/@codebridge/web/dist/assets/KaTeX_Fraktur-Regular-Dxdc4cR9.woff +0 -0
  271. package/node_modules/@codebridge/web/dist/assets/KaTeX_Main-Bold-Cx986IdX.woff2 +0 -0
  272. package/node_modules/@codebridge/web/dist/assets/KaTeX_Main-Bold-Jm3AIy58.woff +0 -0
  273. package/node_modules/@codebridge/web/dist/assets/KaTeX_Main-Bold-waoOVXN0.ttf +0 -0
  274. package/node_modules/@codebridge/web/dist/assets/KaTeX_Main-BoldItalic-DxDJ3AOS.woff2 +0 -0
  275. package/node_modules/@codebridge/web/dist/assets/KaTeX_Main-BoldItalic-DzxPMmG6.ttf +0 -0
  276. package/node_modules/@codebridge/web/dist/assets/KaTeX_Main-BoldItalic-SpSLRI95.woff +0 -0
  277. package/node_modules/@codebridge/web/dist/assets/KaTeX_Main-Italic-3WenGoN9.ttf +0 -0
  278. package/node_modules/@codebridge/web/dist/assets/KaTeX_Main-Italic-BMLOBm91.woff +0 -0
  279. package/node_modules/@codebridge/web/dist/assets/KaTeX_Main-Italic-NWA7e6Wa.woff2 +0 -0
  280. package/node_modules/@codebridge/web/dist/assets/KaTeX_Main-Regular-B22Nviop.woff2 +0 -0
  281. package/node_modules/@codebridge/web/dist/assets/KaTeX_Main-Regular-Dr94JaBh.woff +0 -0
  282. package/node_modules/@codebridge/web/dist/assets/KaTeX_Main-Regular-ypZvNtVU.ttf +0 -0
  283. package/node_modules/@codebridge/web/dist/assets/KaTeX_Math-BoldItalic-B3XSjfu4.ttf +0 -0
  284. package/node_modules/@codebridge/web/dist/assets/KaTeX_Math-BoldItalic-CZnvNsCZ.woff2 +0 -0
  285. package/node_modules/@codebridge/web/dist/assets/KaTeX_Math-BoldItalic-iY-2wyZ7.woff +0 -0
  286. package/node_modules/@codebridge/web/dist/assets/KaTeX_Math-Italic-DA0__PXp.woff +0 -0
  287. package/node_modules/@codebridge/web/dist/assets/KaTeX_Math-Italic-flOr_0UB.ttf +0 -0
  288. package/node_modules/@codebridge/web/dist/assets/KaTeX_Math-Italic-t53AETM-.woff2 +0 -0
  289. package/node_modules/@codebridge/web/dist/assets/KaTeX_SansSerif-Bold-CFMepnvq.ttf +0 -0
  290. package/node_modules/@codebridge/web/dist/assets/KaTeX_SansSerif-Bold-D1sUS0GD.woff2 +0 -0
  291. package/node_modules/@codebridge/web/dist/assets/KaTeX_SansSerif-Bold-DbIhKOiC.woff +0 -0
  292. package/node_modules/@codebridge/web/dist/assets/KaTeX_SansSerif-Italic-C3H0VqGB.woff2 +0 -0
  293. package/node_modules/@codebridge/web/dist/assets/KaTeX_SansSerif-Italic-DN2j7dab.woff +0 -0
  294. package/node_modules/@codebridge/web/dist/assets/KaTeX_SansSerif-Italic-YYjJ1zSn.ttf +0 -0
  295. package/node_modules/@codebridge/web/dist/assets/KaTeX_SansSerif-Regular-BNo7hRIc.ttf +0 -0
  296. package/node_modules/@codebridge/web/dist/assets/KaTeX_SansSerif-Regular-CS6fqUqJ.woff +0 -0
  297. package/node_modules/@codebridge/web/dist/assets/KaTeX_SansSerif-Regular-DDBCnlJ7.woff2 +0 -0
  298. package/node_modules/@codebridge/web/dist/assets/KaTeX_Script-Regular-C5JkGWo-.ttf +0 -0
  299. package/node_modules/@codebridge/web/dist/assets/KaTeX_Script-Regular-D3wIWfF6.woff2 +0 -0
  300. package/node_modules/@codebridge/web/dist/assets/KaTeX_Script-Regular-D5yQViql.woff +0 -0
  301. package/node_modules/@codebridge/web/dist/assets/KaTeX_Size1-Regular-C195tn64.woff +0 -0
  302. package/node_modules/@codebridge/web/dist/assets/KaTeX_Size1-Regular-Dbsnue_I.ttf +0 -0
  303. package/node_modules/@codebridge/web/dist/assets/KaTeX_Size1-Regular-mCD8mA8B.woff2 +0 -0
  304. package/node_modules/@codebridge/web/dist/assets/KaTeX_Size2-Regular-B7gKUWhC.ttf +0 -0
  305. package/node_modules/@codebridge/web/dist/assets/KaTeX_Size2-Regular-Dy4dx90m.woff2 +0 -0
  306. package/node_modules/@codebridge/web/dist/assets/KaTeX_Size2-Regular-oD1tc_U0.woff +0 -0
  307. package/node_modules/@codebridge/web/dist/assets/KaTeX_Size3-Regular-CTq5MqoE.woff +0 -0
  308. package/node_modules/@codebridge/web/dist/assets/KaTeX_Size3-Regular-DgpXs0kz.ttf +0 -0
  309. package/node_modules/@codebridge/web/dist/assets/KaTeX_Size4-Regular-BF-4gkZK.woff +0 -0
  310. package/node_modules/@codebridge/web/dist/assets/KaTeX_Size4-Regular-DWFBv043.ttf +0 -0
  311. package/node_modules/@codebridge/web/dist/assets/KaTeX_Size4-Regular-Dl5lxZxV.woff2 +0 -0
  312. package/node_modules/@codebridge/web/dist/assets/KaTeX_Typewriter-Regular-C0xS9mPB.woff +0 -0
  313. package/node_modules/@codebridge/web/dist/assets/KaTeX_Typewriter-Regular-CO6r4hn1.woff2 +0 -0
  314. package/node_modules/@codebridge/web/dist/assets/KaTeX_Typewriter-Regular-D3Ib7_Hf.ttf +0 -0
  315. package/node_modules/@codebridge/web/dist/assets/abnfDiagram-N423BO3Z-C-JdFv0U.js +1 -0
  316. package/node_modules/@codebridge/web/dist/assets/arc-DsNROjzU.js +1 -0
  317. package/node_modules/@codebridge/web/dist/assets/architecture-TIHT7OUA-ZEBHG2JZ.js +1 -0
  318. package/node_modules/@codebridge/web/dist/assets/architectureDiagram-T3A2C74G-OsrxcwPM.js +36 -0
  319. package/node_modules/@codebridge/web/dist/assets/array-BifhSqXX.js +1 -0
  320. package/node_modules/@codebridge/web/dist/assets/blockDiagram-VBNYF7ZC-DRgfNeNW.js +132 -0
  321. package/node_modules/@codebridge/web/dist/assets/c4Diagram-5PPSVZJV-BtOGKTh8.js +10 -0
  322. package/node_modules/@codebridge/web/dist/assets/channel-MhXyjxUS.js +1 -0
  323. package/node_modules/@codebridge/web/dist/assets/chunk-2GRJ4B5K-Dy1gJ7sY.js +1 -0
  324. package/node_modules/@codebridge/web/dist/assets/chunk-2Q5K7J3B-C1jixKkw.js +1 -0
  325. package/node_modules/@codebridge/web/dist/assets/chunk-4I5QYGJK-1pOLR_SG.js +1 -0
  326. package/node_modules/@codebridge/web/dist/assets/chunk-5RXB4S5H-CP43rgsO.js +231 -0
  327. package/node_modules/@codebridge/web/dist/assets/chunk-5VM5RSS4-ZNzvKenW.js +15 -0
  328. package/node_modules/@codebridge/web/dist/assets/chunk-6Q2QTUOP-Bi3Xrp6W.js +88 -0
  329. package/node_modules/@codebridge/web/dist/assets/chunk-7BUUIJ7U-Bb538aSH.js +1 -0
  330. package/node_modules/@codebridge/web/dist/assets/chunk-7Z6QIM7H-CILAW2Nk.js +10 -0
  331. package/node_modules/@codebridge/web/dist/assets/chunk-GF5L2VYU-CAp09yhq.js +206 -0
  332. package/node_modules/@codebridge/web/dist/assets/chunk-I66GZJ75-B_rJXmNu.js +128 -0
  333. package/node_modules/@codebridge/web/dist/assets/chunk-JQJVKLGR-OVeOJFCx.js +156 -0
  334. package/node_modules/@codebridge/web/dist/assets/chunk-JWPE2WC7-DVXcaiue.js +1 -0
  335. package/node_modules/@codebridge/web/dist/assets/chunk-KBJHAD2P-uaupp0k5.js +1 -0
  336. package/node_modules/@codebridge/web/dist/assets/chunk-KEIR6QF5-BICK3FdT.js +161 -0
  337. package/node_modules/@codebridge/web/dist/assets/chunk-NSK5VX7P-fIHF5wwn.js +2 -0
  338. package/node_modules/@codebridge/web/dist/assets/chunk-QR6OTTB3-DxkJuF2b.js +62 -0
  339. package/node_modules/@codebridge/web/dist/assets/chunk-RYQCIY6F-CC5j3u-X.js +1 -0
  340. package/node_modules/@codebridge/web/dist/assets/chunk-UBXNYLIW-DB35O-6R.js +1 -0
  341. package/node_modules/@codebridge/web/dist/assets/chunk-W5SLKNZC-bkRBsbq-.js +1 -0
  342. package/node_modules/@codebridge/web/dist/assets/chunk-WRU74C26-DwvEoD-1.js +70 -0
  343. package/node_modules/@codebridge/web/dist/assets/chunk-XXDRQBXY-DRyYA-HY.js +1 -0
  344. package/node_modules/@codebridge/web/dist/assets/chunk-Y2CYZVJY-DsF7k-Jl.js +1 -0
  345. package/node_modules/@codebridge/web/dist/assets/classDiagram-JCYQIIEL-B8r7z8ii.js +1 -0
  346. package/node_modules/@codebridge/web/dist/assets/classDiagram-v2-OCEON4UE-B8r7z8ii.js +1 -0
  347. package/node_modules/@codebridge/web/dist/assets/cose-bilkent-JH36ORCC-CLkwlrX7.js +1 -0
  348. package/node_modules/@codebridge/web/dist/assets/cynefin-VYW2F7L2-C3_Llw02.js +1 -0
  349. package/node_modules/@codebridge/web/dist/assets/cynefinDiagram-MW4NZA55-D5v7UnJy.js +62 -0
  350. package/node_modules/@codebridge/web/dist/assets/cytoscape.esm-B-NFISlW.js +321 -0
  351. package/node_modules/@codebridge/web/dist/assets/dagre-Buvkdvvj.js +1 -0
  352. package/node_modules/@codebridge/web/dist/assets/dagre-VZM6K2ZE-Cr0IibwW.js +4 -0
  353. package/node_modules/@codebridge/web/dist/assets/defaultLocale-BFoDCU3G.js +1 -0
  354. package/node_modules/@codebridge/web/dist/assets/diagram-7IWD3JNH-CpQXDIzA.js +30 -0
  355. package/node_modules/@codebridge/web/dist/assets/diagram-B4RE2ZJO-VaOkH0Ya.js +3 -0
  356. package/node_modules/@codebridge/web/dist/assets/diagram-LBJQPF4R-D0iXyNks.js +24 -0
  357. package/node_modules/@codebridge/web/dist/assets/diagram-Q27KOJAE-CtqYk01P.js +24 -0
  358. package/node_modules/@codebridge/web/dist/assets/diagram-UB23O5K3-CFnd3H1_.js +41 -0
  359. package/node_modules/@codebridge/web/dist/assets/dist-D2L7nRdk.js +1 -0
  360. package/node_modules/@codebridge/web/dist/assets/ebnfDiagram-BXEA7PRR-B0GIbJYt.js +1 -0
  361. package/node_modules/@codebridge/web/dist/assets/erDiagram-JOGREHBK-BApaLGVA.js +85 -0
  362. package/node_modules/@codebridge/web/dist/assets/eventmodeling-45OFAUF4-DqGGjcld.js +1 -0
  363. package/node_modules/@codebridge/web/dist/assets/flowDiagram-UKHOOZJN-I_qlizLH.js +1 -0
  364. package/node_modules/@codebridge/web/dist/assets/ganttDiagram-PKOTCBZU-B-QZ-J82.js +292 -0
  365. package/node_modules/@codebridge/web/dist/assets/gitGraph-TEB2WS4Q-DK2SJ2Ne.js +1 -0
  366. package/node_modules/@codebridge/web/dist/assets/gitGraphDiagram-DS77QQ5N-B6Z-pu0D.js +106 -0
  367. package/node_modules/@codebridge/web/dist/assets/graphlib-DS17s2tU.js +1 -0
  368. package/node_modules/@codebridge/web/dist/assets/index-8BzpyygS.js +559 -0
  369. package/node_modules/@codebridge/web/dist/assets/index-Bzaz89LE.css +1 -0
  370. package/node_modules/@codebridge/web/dist/assets/info-DKCQHKI2-CGWxt_Py.js +1 -0
  371. package/node_modules/@codebridge/web/dist/assets/infoDiagram-6WML65LV-77XjrPZs.js +2 -0
  372. package/node_modules/@codebridge/web/dist/assets/init-C-OQMol4.js +1 -0
  373. package/node_modules/@codebridge/web/dist/assets/ishikawaDiagram-WSZJBQD7-P1bZAz2x.js +70 -0
  374. package/node_modules/@codebridge/web/dist/assets/journeyDiagram-NVQOT4AX-C4rwMcBY.js +139 -0
  375. package/node_modules/@codebridge/web/dist/assets/kanban-definition-27J2QSJJ-mtw4a9bc.js +89 -0
  376. package/node_modules/@codebridge/web/dist/assets/line-DP4RkYqm.js +1 -0
  377. package/node_modules/@codebridge/web/dist/assets/linear-DMg3PPio.js +1 -0
  378. package/node_modules/@codebridge/web/dist/assets/map-BaFkSB1l.js +1 -0
  379. package/node_modules/@codebridge/web/dist/assets/mermaid-parser.core-HY84kHw1.js +7 -0
  380. package/node_modules/@codebridge/web/dist/assets/mermaid.core-DdgCdsnM.js +42 -0
  381. package/node_modules/@codebridge/web/dist/assets/mindmap-definition-FAOFIHXS-Cw1EnbhZ.js +96 -0
  382. package/node_modules/@codebridge/web/dist/assets/ordinal-BDEzSJ7C.js +1 -0
  383. package/node_modules/@codebridge/web/dist/assets/packet-7NZHBO7P-CEbrbJH3.js +1 -0
  384. package/node_modules/@codebridge/web/dist/assets/path-fybaL0A-.js +1 -0
  385. package/node_modules/@codebridge/web/dist/assets/pegDiagram-VL7TDLO6-CEc1Gedb.js +1 -0
  386. package/node_modules/@codebridge/web/dist/assets/pie-RZYD4A2V-DPXVs-IW.js +1 -0
  387. package/node_modules/@codebridge/web/dist/assets/pieDiagram-7S7Q4E2Y-hoQeGMFH.js +39 -0
  388. package/node_modules/@codebridge/web/dist/assets/quadrantDiagram-CIZ2JOQS-C-Nmxx0f.js +7 -0
  389. package/node_modules/@codebridge/web/dist/assets/radar-I7S5WNFK-BVd3X3Pd.js +1 -0
  390. package/node_modules/@codebridge/web/dist/assets/railroad-3IZDKUUU-CxLxzr_v.js +1 -0
  391. package/node_modules/@codebridge/web/dist/assets/railroad-abnf-AHOZXSZD-MA1zPI84.js +1 -0
  392. package/node_modules/@codebridge/web/dist/assets/railroad-ebnf-EBAXGLYW-Bqug_umD.js +1 -0
  393. package/node_modules/@codebridge/web/dist/assets/railroad-peg-LSFZ7HO6-DRcRFwpq.js +1 -0
  394. package/node_modules/@codebridge/web/dist/assets/railroadDiagram-AXF67PYL-B007ZkL9.js +1 -0
  395. package/node_modules/@codebridge/web/dist/assets/requirementDiagram-LRYGKXZP-LrTCcEi5.js +84 -0
  396. package/node_modules/@codebridge/web/dist/assets/rough.esm-Dy-Kn_BL.js +1 -0
  397. package/node_modules/@codebridge/web/dist/assets/sankeyDiagram-W5VNT64P-Ch4mzHck.js +40 -0
  398. package/node_modules/@codebridge/web/dist/assets/sequenceDiagram-SI44F4Z6-CHg4OzLX.js +162 -0
  399. package/node_modules/@codebridge/web/dist/assets/sizeCapture-X5ZJPWSS-B0uUizjq.js +1 -0
  400. package/node_modules/@codebridge/web/dist/assets/src-BrO6_odD.js +1 -0
  401. package/node_modules/@codebridge/web/dist/assets/stateDiagram-OKZ733FA-7cVkr5nR.js +1 -0
  402. package/node_modules/@codebridge/web/dist/assets/stateDiagram-v2-UEYNNEHI-CTy_mAXb.js +1 -0
  403. package/node_modules/@codebridge/web/dist/assets/swimlanes-SLNWSIFB-BwSVF5qy.js +2 -0
  404. package/node_modules/@codebridge/web/dist/assets/swimlanesDiagram-ULZ7WXOC-BBQnfZ1j.js +8 -0
  405. package/node_modules/@codebridge/web/dist/assets/timeline-definition-Z64GVDOM-BaHEkVDV.js +120 -0
  406. package/node_modules/@codebridge/web/dist/assets/treeView-QDETBFTQ-CF0kLN62.js +1 -0
  407. package/node_modules/@codebridge/web/dist/assets/treemap-6X3UGDF4-BB8A8uux.js +1 -0
  408. package/node_modules/@codebridge/web/dist/assets/vennDiagram-T6HMQDX7-BFK12Iro.js +34 -0
  409. package/node_modules/@codebridge/web/dist/assets/wardley-OPB4EBWU-C_3y61zk.js +1 -0
  410. package/node_modules/@codebridge/web/dist/assets/wardleyDiagram-T6FBY63Y-W2oGu4WK.js +78 -0
  411. package/node_modules/@codebridge/web/dist/assets/xychartDiagram-ELKLHX3M-BiVRnbvz.js +7 -0
  412. package/node_modules/@codebridge/web/dist/brand/agent-logo-carbon.svg +1 -0
  413. package/node_modules/@codebridge/web/dist/brand/agent-logo.svg +1 -0
  414. package/node_modules/@codebridge/web/dist/brand/agnet-logo-carbon.svg +1 -0
  415. package/node_modules/@codebridge/web/dist/brand/agnet-logo.svg +1 -0
  416. package/node_modules/@codebridge/web/dist/brand/agnet-mark-carbon.svg +1 -0
  417. package/node_modules/@codebridge/web/dist/brand/agnet-mark.svg +1 -0
  418. package/node_modules/@codebridge/web/dist/fonts/CommitMono-400-Regular.otf +0 -0
  419. package/node_modules/@codebridge/web/dist/fonts/CommitMono-700-Regular.otf +0 -0
  420. package/node_modules/@codebridge/web/dist/fonts/CommitMono-OFL.txt +21 -0
  421. package/node_modules/@codebridge/web/dist/fonts/DepartureMono-OFL.txt +21 -0
  422. package/node_modules/@codebridge/web/dist/fonts/DepartureMono-Regular.woff2 +0 -0
  423. package/node_modules/@codebridge/web/dist/index.html +25 -0
  424. package/node_modules/@codebridge/web/package.json +7 -0
  425. package/node_modules/@codebridge/work-items/dist/index.d.ts +371 -0
  426. package/node_modules/@codebridge/work-items/dist/index.js +1784 -0
  427. package/node_modules/@codebridge/work-items/dist/session-projector.d.ts +4 -0
  428. package/node_modules/@codebridge/work-items/dist/session-projector.js +506 -0
  429. package/node_modules/@codebridge/work-items/dist/session-runtime.d.ts +274 -0
  430. package/node_modules/@codebridge/work-items/dist/session-runtime.js +1103 -0
  431. package/node_modules/@codebridge/work-items/dist/session-schema.d.ts +9 -0
  432. package/node_modules/@codebridge/work-items/dist/session-schema.js +292 -0
  433. package/node_modules/@codebridge/work-items/package.json +20 -0
  434. package/package.json +75 -4
@@ -0,0 +1,699 @@
1
+ import { randomUUID } from "node:crypto";
2
+ import { execFileSync } from "node:child_process";
3
+ import fs from "node:fs";
4
+ import os from "node:os";
5
+ import path from "node:path";
6
+ import { createRequire } from "node:module";
7
+ import { parse as parseYaml } from "yaml";
8
+ const { DatabaseSync } = createRequire(import.meta.url)("node:sqlite");
9
+ export class ProjectCatalogStore {
10
+ database;
11
+ constructor(databasePath) {
12
+ if (databasePath !== ":memory:")
13
+ fs.mkdirSync(path.dirname(databasePath), { recursive: true });
14
+ this.database = new DatabaseSync(databasePath);
15
+ this.database.exec(`
16
+ CREATE TABLE IF NOT EXISTS project_candidates (
17
+ id TEXT PRIMARY KEY,
18
+ project_id TEXT NOT NULL UNIQUE,
19
+ display_name TEXT,
20
+ repository_remote TEXT,
21
+ language TEXT,
22
+ deploy_service TEXT,
23
+ log_service TEXT,
24
+ apm_service TEXT,
25
+ confidence TEXT NOT NULL,
26
+ status TEXT NOT NULL,
27
+ evidence TEXT NOT NULL,
28
+ dependencies TEXT NOT NULL DEFAULT '[]',
29
+ observed_at TEXT NOT NULL
30
+ );
31
+ CREATE TABLE IF NOT EXISTS projects (
32
+ id TEXT PRIMARY KEY,
33
+ display_name TEXT,
34
+ repository_remote TEXT,
35
+ language TEXT,
36
+ deploy_service TEXT,
37
+ log_service TEXT,
38
+ apm_service TEXT,
39
+ confidence TEXT NOT NULL,
40
+ status TEXT NOT NULL,
41
+ evidence TEXT NOT NULL,
42
+ dependencies TEXT NOT NULL DEFAULT '[]',
43
+ registered_at TEXT NOT NULL
44
+ );
45
+ CREATE TABLE IF NOT EXISTS project_drifts (
46
+ id TEXT PRIMARY KEY,
47
+ project_id TEXT NOT NULL,
48
+ candidate_id TEXT NOT NULL,
49
+ changes TEXT NOT NULL,
50
+ evidence TEXT NOT NULL DEFAULT '[]',
51
+ status TEXT NOT NULL,
52
+ observed_at TEXT NOT NULL,
53
+ resolved_at TEXT
54
+ );
55
+ CREATE INDEX IF NOT EXISTS project_drifts_project_status
56
+ ON project_drifts (project_id, status, observed_at);
57
+ CREATE TABLE IF NOT EXISTS discovery_tasks (
58
+ id TEXT PRIMARY KEY,
59
+ status TEXT NOT NULL,
60
+ workspace_path TEXT NOT NULL,
61
+ work_item_id TEXT,
62
+ candidate_id TEXT,
63
+ error TEXT,
64
+ created_at TEXT NOT NULL,
65
+ updated_at TEXT NOT NULL
66
+ );
67
+ `);
68
+ for (const statement of [
69
+ "ALTER TABLE project_candidates ADD COLUMN dependencies TEXT NOT NULL DEFAULT '[]'",
70
+ "ALTER TABLE projects ADD COLUMN dependencies TEXT NOT NULL DEFAULT '[]'",
71
+ "ALTER TABLE project_drifts ADD COLUMN evidence TEXT NOT NULL DEFAULT '[]'",
72
+ ]) {
73
+ try {
74
+ this.database.exec(statement);
75
+ }
76
+ catch { /* Existing databases already contain the column. */ }
77
+ }
78
+ this.database
79
+ .prepare("UPDATE discovery_tasks SET status = 'queued', updated_at = ? WHERE status = 'running'")
80
+ .run(new Date().toISOString());
81
+ }
82
+ saveCandidate(input) {
83
+ const existing = this.getCandidateByProjectId(input.projectId);
84
+ if (existing) {
85
+ const evidence = mergeEvidence(existing.evidence, input.evidence);
86
+ this.recordDrift(existing.id, input);
87
+ // A registered candidate is immutable until a human edits the catalog.
88
+ if (existing.status === "candidate") {
89
+ this.database
90
+ .prepare(`UPDATE project_candidates
91
+ SET display_name = COALESCE(?, display_name),
92
+ repository_remote = COALESCE(?, repository_remote),
93
+ language = COALESCE(?, language),
94
+ deploy_service = COALESCE(?, deploy_service),
95
+ log_service = COALESCE(?, log_service),
96
+ apm_service = COALESCE(?, apm_service),
97
+ dependencies = CASE WHEN ? IS NULL THEN dependencies ELSE ? END,
98
+ confidence = ?, evidence = ?, observed_at = ?
99
+ WHERE id = ?`)
100
+ .run(input.displayName ?? null, input.repositoryRemote ?? null, input.language ?? null, input.deployService ?? null, input.logService ?? null, input.apmService ?? null, input.dependencies ? JSON.stringify(input.dependencies) : null, input.dependencies ? JSON.stringify(input.dependencies) : null, maxConfidence(existing.confidence, input.confidence), JSON.stringify(evidence), new Date().toISOString(), existing.id);
101
+ }
102
+ return this.getCandidate(existing.id);
103
+ }
104
+ const candidate = {
105
+ ...input,
106
+ id: `pc_${randomUUID().replaceAll("-", "")}`,
107
+ status: "candidate",
108
+ observedAt: new Date().toISOString(),
109
+ evidence: [...input.evidence],
110
+ };
111
+ this.database
112
+ .prepare(`INSERT INTO project_candidates (
113
+ id, project_id, display_name, repository_remote, language,
114
+ deploy_service, log_service, apm_service, confidence, status,
115
+ evidence, dependencies, observed_at
116
+ ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`)
117
+ .run(candidate.id, candidate.projectId, candidate.displayName ?? null, candidate.repositoryRemote ?? null, candidate.language ?? null, candidate.deployService ?? null, candidate.logService ?? null, candidate.apmService ?? null, candidate.confidence, candidate.status, JSON.stringify(candidate.evidence), JSON.stringify(candidate.dependencies ?? []), candidate.observedAt);
118
+ return candidate;
119
+ }
120
+ listCandidates() {
121
+ return this.database.prepare("SELECT * FROM project_candidates ORDER BY observed_at DESC").all().map(toCandidate);
122
+ }
123
+ getCandidate(id) {
124
+ const row = this.database.prepare("SELECT * FROM project_candidates WHERE id = ?").get(id);
125
+ return row ? toCandidate(row) : undefined;
126
+ }
127
+ getCandidateByProjectId(projectId) {
128
+ const row = this.database.prepare("SELECT * FROM project_candidates WHERE project_id = ?").get(projectId);
129
+ return row ? toCandidate(row) : undefined;
130
+ }
131
+ acceptCandidate(id) {
132
+ const candidate = this.getCandidate(id);
133
+ if (!candidate)
134
+ throw new Error(`Project candidate not found: ${id}`);
135
+ const existing = this.getProject(candidate.projectId);
136
+ if (!existing) {
137
+ const registeredAt = new Date().toISOString();
138
+ this.database
139
+ .prepare(`INSERT INTO projects (
140
+ id, display_name, repository_remote, language, deploy_service,
141
+ log_service, apm_service, confidence, status, evidence, dependencies, registered_at
142
+ ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`)
143
+ .run(candidate.projectId, candidate.displayName ?? null, candidate.repositoryRemote ?? null, candidate.language ?? null, candidate.deployService ?? null, candidate.logService ?? null, candidate.apmService ?? null, candidate.confidence, "registered", JSON.stringify(candidate.evidence), JSON.stringify(candidate.dependencies ?? []), registeredAt);
144
+ }
145
+ this.database.prepare("UPDATE project_candidates SET status = 'accepted' WHERE id = ?").run(id);
146
+ return this.getProject(candidate.projectId);
147
+ }
148
+ getProject(id) {
149
+ const row = this.database.prepare("SELECT * FROM projects WHERE id = ?").get(id);
150
+ return row ? toProject(row) : undefined;
151
+ }
152
+ listProjects() {
153
+ return this.database.prepare("SELECT * FROM projects ORDER BY id ASC").all().map(toProject);
154
+ }
155
+ projectsForCandidate(id) {
156
+ const candidate = this.getCandidate(id);
157
+ if (!candidate)
158
+ throw new Error(`Project candidate not found: ${id}`);
159
+ const existing = this.getProject(candidate.projectId);
160
+ const openDrift = this.listDrifts(candidate.projectId)[0];
161
+ const proposed = openDrift ? applyDriftValues(candidate, openDrift.changes) : candidate;
162
+ const project = {
163
+ ...proposed,
164
+ id: candidate.projectId,
165
+ status: "registered",
166
+ registeredAt: existing?.registeredAt ?? new Date().toISOString(),
167
+ };
168
+ return [...this.listProjects().filter((item) => item.id !== project.id), project]
169
+ .sort((left, right) => left.id.localeCompare(right.id));
170
+ }
171
+ syncProjects(projects, revision) {
172
+ const ids = new Set(projects.map((project) => project.id));
173
+ if (ids.size !== projects.length)
174
+ throw new Error("Project catalog contains duplicate project_id values");
175
+ this.database.exec("BEGIN IMMEDIATE");
176
+ try {
177
+ this.database.prepare("UPDATE projects SET status = 'deprecated'").run();
178
+ for (const project of projects) {
179
+ const existing = this.getProject(project.id);
180
+ const evidence = mergeEvidence(project.evidence, [{ kind: "git_catalog", ref: revision }]);
181
+ this.database.prepare(`INSERT INTO projects (
182
+ id, display_name, repository_remote, language, deploy_service,
183
+ log_service, apm_service, confidence, status, evidence, dependencies, registered_at
184
+ ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, 'registered', ?, ?, ?)
185
+ ON CONFLICT(id) DO UPDATE SET display_name = excluded.display_name,
186
+ repository_remote = excluded.repository_remote, language = excluded.language,
187
+ deploy_service = excluded.deploy_service, log_service = excluded.log_service,
188
+ apm_service = excluded.apm_service, confidence = excluded.confidence,
189
+ status = 'registered', evidence = excluded.evidence,
190
+ dependencies = excluded.dependencies`).run(project.id, project.displayName ?? null, project.repositoryRemote ?? null, project.language ?? null, project.deployService ?? null, project.logService ?? null, project.apmService ?? null, project.confidence, JSON.stringify(evidence), JSON.stringify(project.dependencies ?? []), existing?.registeredAt ?? project.registeredAt);
191
+ this.database.prepare("UPDATE project_candidates SET status = 'accepted' WHERE project_id = ?").run(project.id);
192
+ }
193
+ this.database.exec("COMMIT");
194
+ }
195
+ catch (error) {
196
+ this.database.exec("ROLLBACK");
197
+ throw error;
198
+ }
199
+ return this.listProjects();
200
+ }
201
+ listDrifts(projectId, status = "open") {
202
+ const rows = projectId
203
+ ? this.database.prepare("SELECT * FROM project_drifts WHERE project_id = ? AND status = ? ORDER BY observed_at DESC").all(projectId, status)
204
+ : this.database.prepare("SELECT * FROM project_drifts WHERE status = ? ORDER BY observed_at DESC").all(status);
205
+ return rows.map(toDrift);
206
+ }
207
+ resolveDrift(id) {
208
+ const row = this.database.prepare("SELECT * FROM project_drifts WHERE id = ?").get(id);
209
+ if (!row)
210
+ return undefined;
211
+ this.database
212
+ .prepare("UPDATE project_drifts SET status = 'resolved', resolved_at = ? WHERE id = ? AND status = 'open'")
213
+ .run(new Date().toISOString(), id);
214
+ return toDrift(this.database.prepare("SELECT * FROM project_drifts WHERE id = ?").get(id));
215
+ }
216
+ applyDrift(id) {
217
+ const drift = this.listDrifts(undefined, "open").find((item) => item.id === id);
218
+ if (!drift)
219
+ return undefined;
220
+ const project = this.getProject(drift.projectId);
221
+ if (!project)
222
+ return undefined;
223
+ const next = { ...project };
224
+ for (const change of drift.changes) {
225
+ next[change.field] = change.observed;
226
+ }
227
+ this.database
228
+ .prepare(`UPDATE projects SET repository_remote = ?, language = ?, deploy_service = ?,
229
+ log_service = ?, apm_service = ?, dependencies = ?, evidence = ? WHERE id = ?`)
230
+ .run(next.repositoryRemote ?? null, next.language ?? null, next.deployService ?? null, next.logService ?? null, next.apmService ?? null, JSON.stringify(next.dependencies ?? []), JSON.stringify(mergeEvidence(project.evidence, [{ kind: "drift_applied", ref: drift.id }])), project.id);
231
+ this.database
232
+ .prepare("UPDATE project_candidates SET repository_remote = ?, language = ?, deploy_service = ?, log_service = ?, apm_service = ?, dependencies = ?, evidence = ? WHERE project_id = ?")
233
+ .run(next.repositoryRemote ?? null, next.language ?? null, next.deployService ?? null, next.logService ?? null, next.apmService ?? null, JSON.stringify(next.dependencies ?? []), JSON.stringify(mergeEvidence(project.evidence, [{ kind: "drift_applied", ref: drift.id }])), project.id);
234
+ this.resolveDrift(id);
235
+ return this.getProject(project.id);
236
+ }
237
+ previewCandidate(id) {
238
+ const candidate = this.getCandidate(id);
239
+ if (!candidate)
240
+ throw new Error(`Project candidate not found: ${id}`);
241
+ const existing = this.getProject(candidate.projectId);
242
+ const before = existing ? renderProjectYaml(existing) : "";
243
+ const openDrift = this.listDrifts(candidate.projectId)[0];
244
+ const preview = openDrift
245
+ ? applyDriftValues(candidate, openDrift.changes)
246
+ : candidate;
247
+ const after = renderProjectYaml({
248
+ ...preview,
249
+ id: candidate.projectId,
250
+ status: "registered",
251
+ registeredAt: existing?.registeredAt ?? new Date().toISOString(),
252
+ });
253
+ return { path: "catalog/projects.yaml", before, after, unified: diffText(before, after) };
254
+ }
255
+ recordDrift(candidateId, observed) {
256
+ const registered = this.getProject(observed.projectId);
257
+ if (!registered)
258
+ return;
259
+ const changes = projectDrift(registered, observed);
260
+ if (!changes.length)
261
+ return;
262
+ const serialized = JSON.stringify(changes);
263
+ const duplicate = this.database
264
+ .prepare("SELECT id FROM project_drifts WHERE project_id = ? AND status = 'open' AND changes = ?")
265
+ .get(observed.projectId, serialized);
266
+ if (duplicate)
267
+ return;
268
+ this.database
269
+ .prepare("INSERT INTO project_drifts (id, project_id, candidate_id, changes, evidence, status, observed_at, resolved_at) VALUES (?, ?, ?, ?, ?, 'open', ?, NULL)")
270
+ .run(`pdr_${randomUUID().replaceAll("-", "")}`, observed.projectId, candidateId, serialized, JSON.stringify(observed.evidence), new Date().toISOString());
271
+ }
272
+ createDiscoveryTask(input) {
273
+ if (!input.workspacePath.trim())
274
+ throw new Error("workspace path must not be empty");
275
+ const now = new Date().toISOString();
276
+ const task = {
277
+ id: input.id ?? `dst_${randomUUID().replaceAll("-", "")}`,
278
+ status: "queued",
279
+ workspacePath: input.workspacePath,
280
+ workItemId: input.workItemId ?? null,
281
+ candidateId: null,
282
+ error: null,
283
+ createdAt: now,
284
+ updatedAt: now,
285
+ };
286
+ this.database
287
+ .prepare(`INSERT INTO discovery_tasks (
288
+ id, status, workspace_path, work_item_id, candidate_id, error, created_at, updated_at
289
+ ) VALUES (?, ?, ?, ?, ?, ?, ?, ?)`)
290
+ .run(task.id, task.status, task.workspacePath, task.workItemId, task.candidateId, task.error, task.createdAt, task.updatedAt);
291
+ return task;
292
+ }
293
+ getDiscoveryTask(id) {
294
+ const row = this.database.prepare("SELECT * FROM discovery_tasks WHERE id = ?").get(id);
295
+ return row ? toDiscoveryTask(row) : undefined;
296
+ }
297
+ listDiscoveryTasks(statuses) {
298
+ const rows = statuses?.length
299
+ ? this.database
300
+ .prepare(`SELECT * FROM discovery_tasks WHERE status IN (${statuses.map(() => "?").join(", ")}) ORDER BY created_at ASC`)
301
+ .all(...statuses)
302
+ : this.database.prepare("SELECT * FROM discovery_tasks ORDER BY created_at DESC").all();
303
+ return rows.map(toDiscoveryTask);
304
+ }
305
+ updateDiscoveryTask(id, input) {
306
+ const current = this.getDiscoveryTask(id);
307
+ if (!current)
308
+ throw new Error(`Discovery task not found: ${id}`);
309
+ const next = {
310
+ ...current,
311
+ status: input.status ?? current.status,
312
+ candidateId: input.candidateId === undefined ? current.candidateId : input.candidateId,
313
+ error: input.error === undefined ? current.error : input.error,
314
+ updatedAt: new Date().toISOString(),
315
+ };
316
+ this.database
317
+ .prepare("UPDATE discovery_tasks SET status = ?, candidate_id = ?, error = ?, updated_at = ? WHERE id = ?")
318
+ .run(next.status, next.candidateId, next.error, next.updatedAt, id);
319
+ return next;
320
+ }
321
+ close() {
322
+ if (this.database.isOpen)
323
+ this.database.close();
324
+ }
325
+ }
326
+ export class ProjectCatalogGitRepository {
327
+ options;
328
+ repositoryPath;
329
+ catalogPath;
330
+ constructor(options) {
331
+ this.options = options;
332
+ this.repositoryPath = path.resolve(options.repositoryPath);
333
+ this.catalogPath = normalizeCatalogPath(options.catalogPath ?? "catalog/projects.yaml");
334
+ if (!options.baseRef.trim())
335
+ throw new Error("Project catalog baseRef must not be empty");
336
+ runGit(this.repositoryPath, ["rev-parse", "--git-dir"]);
337
+ }
338
+ get baseRef() {
339
+ return this.options.baseRef;
340
+ }
341
+ createProposal(projects, input) {
342
+ const branch = input.branch.trim();
343
+ if (!branch)
344
+ throw new Error("Project catalog proposal branch must not be empty");
345
+ runGit(this.repositoryPath, ["check-ref-format", "--branch", branch]);
346
+ const branchRef = `refs/heads/${branch}`;
347
+ if (gitRefExists(this.repositoryPath, branchRef)) {
348
+ throw new Error(`Project catalog proposal branch already exists: ${branch}`);
349
+ }
350
+ const baseCommit = runGit(this.repositoryPath, ["rev-parse", "--verify", `${this.options.baseRef}^{commit}`]);
351
+ const content = renderProjectsYaml(projects);
352
+ const temporaryDirectory = fs.mkdtempSync(path.join(os.tmpdir(), "codebridge-catalog-index-"));
353
+ const indexPath = path.join(temporaryDirectory, "index");
354
+ const environment = { GIT_INDEX_FILE: indexPath };
355
+ try {
356
+ runGit(this.repositoryPath, ["read-tree", baseCommit], { environment });
357
+ const blob = runGit(this.repositoryPath, ["hash-object", "-w", "--stdin"], { input: content });
358
+ runGit(this.repositoryPath, ["update-index", "--add", "--cacheinfo", "100644", blob, this.catalogPath], { environment });
359
+ const tree = runGit(this.repositoryPath, ["write-tree"], { environment });
360
+ const commit = runGit(this.repositoryPath, [
361
+ "commit-tree",
362
+ tree,
363
+ "-p",
364
+ baseCommit,
365
+ "-m",
366
+ input.message?.trim() || `catalog: update ${this.catalogPath}`,
367
+ ]);
368
+ runGit(this.repositoryPath, ["update-ref", branchRef, commit, "0000000000000000000000000000000000000000"]);
369
+ return { branch, baseRef: this.options.baseRef, baseCommit, commit, path: this.catalogPath };
370
+ }
371
+ finally {
372
+ fs.rmSync(temporaryDirectory, { recursive: true, force: true });
373
+ }
374
+ }
375
+ readProjects(ref = this.options.baseRef) {
376
+ const revision = runGit(this.repositoryPath, ["rev-parse", "--verify", `${ref}^{commit}`]);
377
+ const source = runGit(this.repositoryPath, ["show", `${revision}:${this.catalogPath}`], { trim: false });
378
+ return parseProjectsYaml(source, revision);
379
+ }
380
+ }
381
+ export class ProjectDiscovery {
382
+ catalog;
383
+ options;
384
+ reader;
385
+ constructor(catalog, options = {}) {
386
+ this.catalog = catalog;
387
+ this.options = options;
388
+ this.reader = options.reader ?? readWorkspaceEvidence;
389
+ }
390
+ async observe(workspacePath, workItemId) {
391
+ const observation = await this.reader(workspacePath);
392
+ const remote = normalizeRemote(observation.remote);
393
+ const projectId = projectIdFromRemote(remote) ?? path.basename(workspacePath);
394
+ if (!projectId)
395
+ throw new Error(`Unable to identify project from ${workspacePath}`);
396
+ const candidate = this.catalog.saveCandidate({
397
+ projectId,
398
+ displayName: projectId,
399
+ repositoryRemote: remote,
400
+ language: observation.language,
401
+ deployService: observation.deployService,
402
+ logService: observation.logService,
403
+ apmService: observation.apmService,
404
+ dependencies: observation.dependencies,
405
+ confidence: remote ? "high" : "medium",
406
+ evidence: [
407
+ { kind: "workspace_path", ref: workspacePath },
408
+ ...observation.evidence,
409
+ ],
410
+ });
411
+ if (workItemId && this.options.events) {
412
+ const drifts = this.catalog.listDrifts(candidate.projectId);
413
+ this.options.events.appendEvent({
414
+ workItemId,
415
+ type: "PROJECT_CANDIDATE_FOUND",
416
+ actor: "system",
417
+ target: candidate.projectId,
418
+ payload: {
419
+ candidate_id: candidate.id,
420
+ project_id: candidate.projectId,
421
+ confidence: candidate.confidence,
422
+ evidence: candidate.evidence,
423
+ drifts: drifts.map((drift) => ({ drift_id: drift.id, changes: drift.changes })),
424
+ },
425
+ });
426
+ }
427
+ return candidate;
428
+ }
429
+ close() {
430
+ this.catalog.close();
431
+ }
432
+ }
433
+ async function readWorkspaceEvidence(workspacePath) {
434
+ const evidence = [{ kind: "workspace_path", ref: workspacePath }];
435
+ let remote;
436
+ try {
437
+ remote = execFileSync("git", ["config", "--get", "remote.origin.url"], {
438
+ cwd: workspacePath,
439
+ encoding: "utf8",
440
+ stdio: ["ignore", "pipe", "ignore"],
441
+ }).trim();
442
+ }
443
+ catch {
444
+ // A workspace may not be a Git checkout yet; it remains a medium-confidence candidate.
445
+ }
446
+ if (remote)
447
+ evidence.push({ kind: "git_remote", ref: "git config remote.origin.url", value: remote });
448
+ let language;
449
+ if (fs.existsSync(path.join(workspacePath, "go.mod")))
450
+ language = "go";
451
+ else if (fs.existsSync(path.join(workspacePath, "pyproject.toml")) || fs.existsSync(path.join(workspacePath, "requirements.txt")))
452
+ language = "python";
453
+ else if (fs.existsSync(path.join(workspacePath, "package.json")))
454
+ language = "node";
455
+ if (language)
456
+ evidence.push({ kind: "manifest", ref: language });
457
+ return { remote, language, ...readProjectMetadata(workspacePath, evidence), evidence };
458
+ }
459
+ function readProjectMetadata(workspacePath, evidence) {
460
+ for (const file of [".codebridge/project.json", "codebridge.project.json"]) {
461
+ const metadataPath = path.join(workspacePath, file);
462
+ if (!fs.existsSync(metadataPath))
463
+ continue;
464
+ try {
465
+ const parsed = JSON.parse(fs.readFileSync(metadataPath, "utf8"));
466
+ const value = (snakeCase, camelCase) => {
467
+ const candidate = parsed[snakeCase] ?? parsed[camelCase];
468
+ return typeof candidate === "string" && candidate.trim() ? candidate.trim() : undefined;
469
+ };
470
+ const dependencies = Array.isArray(parsed.dependencies)
471
+ ? parsed.dependencies.filter((entry) => typeof entry === "string" && Boolean(entry.trim()))
472
+ : undefined;
473
+ evidence.push({ kind: "project_metadata", ref: file });
474
+ return {
475
+ deployService: value("deploy_service", "deployService"),
476
+ logService: value("log_service", "logService"),
477
+ apmService: value("apm_service", "apmService"),
478
+ dependencies,
479
+ };
480
+ }
481
+ catch {
482
+ evidence.push({ kind: "project_metadata_invalid", ref: file });
483
+ }
484
+ }
485
+ return {};
486
+ }
487
+ function normalizeRemote(remote) {
488
+ if (!remote)
489
+ return undefined;
490
+ return remote.trim().replace(/^https?:\/\//, "").replace(/^git@/, "").replace(":", "/").replace(/\.git$/, "");
491
+ }
492
+ function projectIdFromRemote(remote) {
493
+ const value = remote?.split("/").filter(Boolean).at(-1);
494
+ return value?.trim() || undefined;
495
+ }
496
+ function mergeEvidence(existing, incoming) {
497
+ const seen = new Set(existing.map((entry) => `${entry.kind}:${entry.ref}:${entry.value ?? ""}`));
498
+ return [...existing, ...incoming.filter((entry) => !seen.has(`${entry.kind}:${entry.ref}:${entry.value ?? ""}`))];
499
+ }
500
+ function maxConfidence(a, b) {
501
+ const rank = { low: 0, medium: 1, high: 2 };
502
+ return rank[a] >= rank[b] ? a : b;
503
+ }
504
+ function toCandidate(row) {
505
+ return {
506
+ id: String(row.id),
507
+ projectId: String(row.project_id),
508
+ displayName: optionalString(row.display_name),
509
+ repositoryRemote: optionalString(row.repository_remote),
510
+ language: optionalString(row.language),
511
+ deployService: optionalString(row.deploy_service),
512
+ logService: optionalString(row.log_service),
513
+ apmService: optionalString(row.apm_service),
514
+ dependencies: row.dependencies ? JSON.parse(String(row.dependencies)) : [],
515
+ confidence: String(row.confidence),
516
+ status: String(row.status),
517
+ evidence: JSON.parse(String(row.evidence)),
518
+ observedAt: String(row.observed_at),
519
+ };
520
+ }
521
+ function toDrift(row) {
522
+ return {
523
+ id: String(row.id),
524
+ projectId: String(row.project_id),
525
+ candidateId: String(row.candidate_id),
526
+ changes: JSON.parse(String(row.changes)),
527
+ evidence: JSON.parse(String(row.evidence)),
528
+ status: String(row.status),
529
+ observedAt: String(row.observed_at),
530
+ resolvedAt: row.resolved_at === null ? null : String(row.resolved_at),
531
+ };
532
+ }
533
+ function toProject(row) {
534
+ return {
535
+ ...toCandidate({ ...row, id: row.id, status: row.status }),
536
+ id: String(row.id),
537
+ status: String(row.status),
538
+ registeredAt: String(row.registered_at),
539
+ };
540
+ }
541
+ function toDiscoveryTask(row) {
542
+ return {
543
+ id: String(row.id),
544
+ status: String(row.status),
545
+ workspacePath: String(row.workspace_path),
546
+ workItemId: row.work_item_id === null ? null : String(row.work_item_id),
547
+ candidateId: row.candidate_id === null ? null : String(row.candidate_id),
548
+ error: row.error === null ? null : String(row.error),
549
+ createdAt: String(row.created_at),
550
+ updatedAt: String(row.updated_at),
551
+ };
552
+ }
553
+ function optionalString(value) {
554
+ return value === null || value === undefined ? undefined : String(value);
555
+ }
556
+ function projectDrift(registered, observed) {
557
+ const fields = [
558
+ "repositoryRemote",
559
+ "language",
560
+ "deployService",
561
+ "logService",
562
+ "apmService",
563
+ "dependencies",
564
+ ];
565
+ return fields.flatMap((field) => {
566
+ const actual = observed[field];
567
+ if (actual === undefined)
568
+ return [];
569
+ const current = registered[field] ?? null;
570
+ if (JSON.stringify(current) === JSON.stringify(actual))
571
+ return [];
572
+ return [{ field, registered: current, observed: actual }];
573
+ });
574
+ }
575
+ function applyDriftValues(value, changes) {
576
+ const next = { ...value };
577
+ const writable = next;
578
+ for (const change of changes)
579
+ writable[change.field] = change.observed;
580
+ return next;
581
+ }
582
+ function renderProjectYaml(project) {
583
+ return [
584
+ "projects:",
585
+ ` - project_id: ${yamlString(project.id)}`,
586
+ ` repository_remote: ${yamlString(project.repositoryRemote)}`,
587
+ ` language: ${yamlString(project.language)}`,
588
+ ` deploy_service: ${yamlString(project.deployService)}`,
589
+ ` log_service: ${yamlString(project.logService)}`,
590
+ ` apm_service: ${yamlString(project.apmService)}`,
591
+ ` dependencies: [${(project.dependencies ?? []).map(yamlString).join(", ")}]`,
592
+ "",
593
+ ].join("\n");
594
+ }
595
+ export function renderProjectsYaml(projects) {
596
+ const lines = ["schema_version: 1", "projects:"];
597
+ for (const project of [...projects].sort((left, right) => left.id.localeCompare(right.id))) {
598
+ lines.push(` - project_id: ${yamlString(project.id)}`, ` display_name: ${yamlString(project.displayName)}`, ` repository_remote: ${yamlString(project.repositoryRemote)}`, ` language: ${yamlString(project.language)}`, ` deploy_service: ${yamlString(project.deployService)}`, ` log_service: ${yamlString(project.logService)}`, ` apm_service: ${yamlString(project.apmService)}`, ` dependencies: [${[...(project.dependencies ?? [])].sort().map(yamlString).join(", ")}]`);
599
+ }
600
+ return `${lines.join("\n")}\n`;
601
+ }
602
+ function parseProjectsYaml(source, revision) {
603
+ const parsed = parseYaml(source);
604
+ if (!isRecord(parsed) || parsed.schema_version !== 1 || !Array.isArray(parsed.projects)) {
605
+ throw new Error("Project catalog must contain schema_version: 1 and a projects array");
606
+ }
607
+ const seen = new Set();
608
+ return parsed.projects.map((entry, index) => {
609
+ if (!isRecord(entry))
610
+ throw new Error(`Project catalog entry ${index} must be an object`);
611
+ const id = requiredCatalogString(entry.project_id, `projects[${index}].project_id`);
612
+ if (seen.has(id))
613
+ throw new Error(`Project catalog contains duplicate project_id: ${id}`);
614
+ seen.add(id);
615
+ const dependencies = entry.dependencies === undefined
616
+ ? []
617
+ : Array.isArray(entry.dependencies)
618
+ ? entry.dependencies.map((value, dependencyIndex) => requiredCatalogString(value, `projects[${index}].dependencies[${dependencyIndex}]`))
619
+ : (() => { throw new Error(`projects[${index}].dependencies must be an array`); })();
620
+ return {
621
+ id,
622
+ projectId: id,
623
+ displayName: optionalCatalogString(entry.display_name, `projects[${index}].display_name`),
624
+ repositoryRemote: optionalCatalogString(entry.repository_remote, `projects[${index}].repository_remote`),
625
+ language: optionalCatalogString(entry.language, `projects[${index}].language`),
626
+ deployService: optionalCatalogString(entry.deploy_service, `projects[${index}].deploy_service`),
627
+ logService: optionalCatalogString(entry.log_service, `projects[${index}].log_service`),
628
+ apmService: optionalCatalogString(entry.apm_service, `projects[${index}].apm_service`),
629
+ dependencies,
630
+ confidence: "high",
631
+ evidence: [{ kind: "git_catalog", ref: revision }],
632
+ status: "registered",
633
+ registeredAt: new Date().toISOString(),
634
+ };
635
+ }).sort((left, right) => left.id.localeCompare(right.id));
636
+ }
637
+ function yamlString(value) {
638
+ return value ? JSON.stringify(value) : "null";
639
+ }
640
+ function diffText(before, after) {
641
+ const oldLines = before ? before.trimEnd().split("\n") : [];
642
+ const newLines = after.trimEnd().split("\n");
643
+ return [
644
+ "--- catalog/projects.yaml",
645
+ "+++ catalog/projects.yaml",
646
+ ...oldLines.map((line) => `-${line}`),
647
+ ...newLines.map((line) => `+${line}`),
648
+ "",
649
+ ].join("\n");
650
+ }
651
+ function normalizeCatalogPath(value) {
652
+ const normalized = value.replaceAll("\\", "/").replace(/^\.\//, "");
653
+ if (!normalized || path.posix.isAbsolute(normalized) || normalized.split("/").includes("..")) {
654
+ throw new Error("Project catalog path must be a relative path inside the repository");
655
+ }
656
+ return normalized;
657
+ }
658
+ function runGit(repositoryPath, args, options = {}) {
659
+ try {
660
+ const output = execFileSync("git", args, {
661
+ cwd: repositoryPath,
662
+ encoding: "utf8",
663
+ input: options.input,
664
+ env: { ...process.env, ...options.environment },
665
+ stdio: ["pipe", "pipe", "pipe"],
666
+ });
667
+ return options.trim === false ? output : output.trim();
668
+ }
669
+ catch (error) {
670
+ const stderr = isRecord(error) && typeof error.stderr === "string" ? error.stderr.trim() : "";
671
+ throw new Error(`Git command failed: git ${args.join(" ")}${stderr ? `: ${stderr}` : ""}`);
672
+ }
673
+ }
674
+ function gitRefExists(repositoryPath, ref) {
675
+ try {
676
+ execFileSync("git", ["show-ref", "--verify", "--quiet", ref], {
677
+ cwd: repositoryPath,
678
+ stdio: "ignore",
679
+ });
680
+ return true;
681
+ }
682
+ catch {
683
+ return false;
684
+ }
685
+ }
686
+ function isRecord(value) {
687
+ return Boolean(value) && typeof value === "object" && !Array.isArray(value);
688
+ }
689
+ function requiredCatalogString(value, field) {
690
+ if (typeof value !== "string" || !value.trim())
691
+ throw new Error(`${field} must be a non-empty string`);
692
+ return value.trim();
693
+ }
694
+ function optionalCatalogString(value, field) {
695
+ if (value === null || value === undefined)
696
+ return undefined;
697
+ return requiredCatalogString(value, field);
698
+ }
699
+ //# sourceMappingURL=index.js.map