@fidelios/server 0.0.1

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 (743) hide show
  1. package/dist/adapters/codex-models.d.ts +4 -0
  2. package/dist/adapters/codex-models.d.ts.map +1 -0
  3. package/dist/adapters/codex-models.js +98 -0
  4. package/dist/adapters/codex-models.js.map +1 -0
  5. package/dist/adapters/cursor-models.d.ts +13 -0
  6. package/dist/adapters/cursor-models.d.ts.map +1 -0
  7. package/dist/adapters/cursor-models.js +148 -0
  8. package/dist/adapters/cursor-models.js.map +1 -0
  9. package/dist/adapters/http/execute.d.ts +3 -0
  10. package/dist/adapters/http/execute.d.ts.map +1 -0
  11. package/dist/adapters/http/execute.js +39 -0
  12. package/dist/adapters/http/execute.js.map +1 -0
  13. package/dist/adapters/http/index.d.ts +3 -0
  14. package/dist/adapters/http/index.d.ts.map +1 -0
  15. package/dist/adapters/http/index.js +20 -0
  16. package/dist/adapters/http/index.js.map +1 -0
  17. package/dist/adapters/http/test.d.ts +3 -0
  18. package/dist/adapters/http/test.d.ts.map +1 -0
  19. package/dist/adapters/http/test.js +106 -0
  20. package/dist/adapters/http/test.js.map +1 -0
  21. package/dist/adapters/index.d.ts +4 -0
  22. package/dist/adapters/index.d.ts.map +1 -0
  23. package/dist/adapters/index.js +3 -0
  24. package/dist/adapters/index.js.map +1 -0
  25. package/dist/adapters/process/execute.d.ts +3 -0
  26. package/dist/adapters/process/execute.d.ts.map +1 -0
  27. package/dist/adapters/process/execute.js +63 -0
  28. package/dist/adapters/process/execute.js.map +1 -0
  29. package/dist/adapters/process/index.d.ts +3 -0
  30. package/dist/adapters/process/index.d.ts.map +1 -0
  31. package/dist/adapters/process/index.js +23 -0
  32. package/dist/adapters/process/index.js.map +1 -0
  33. package/dist/adapters/process/test.d.ts +3 -0
  34. package/dist/adapters/process/test.d.ts.map +1 -0
  35. package/dist/adapters/process/test.js +77 -0
  36. package/dist/adapters/process/test.js.map +1 -0
  37. package/dist/adapters/registry.d.ts +14 -0
  38. package/dist/adapters/registry.d.ts.map +1 -0
  39. package/dist/adapters/registry.js +164 -0
  40. package/dist/adapters/registry.js.map +1 -0
  41. package/dist/adapters/types.d.ts +2 -0
  42. package/dist/adapters/types.d.ts.map +1 -0
  43. package/dist/adapters/types.js +2 -0
  44. package/dist/adapters/types.js.map +1 -0
  45. package/dist/adapters/utils.d.ts +10 -0
  46. package/dist/adapters/utils.d.ts.map +1 -0
  47. package/dist/adapters/utils.js +14 -0
  48. package/dist/adapters/utils.js.map +1 -0
  49. package/dist/agent-auth-jwt.d.ts +14 -0
  50. package/dist/agent-auth-jwt.d.ts.map +1 -0
  51. package/dist/agent-auth-jwt.js +117 -0
  52. package/dist/agent-auth-jwt.js.map +1 -0
  53. package/dist/app.d.ts +25 -0
  54. package/dist/app.d.ts.map +1 -0
  55. package/dist/app.js +265 -0
  56. package/dist/app.js.map +1 -0
  57. package/dist/attachment-types.d.ts +33 -0
  58. package/dist/attachment-types.d.ts.map +1 -0
  59. package/dist/attachment-types.js +67 -0
  60. package/dist/attachment-types.js.map +1 -0
  61. package/dist/auth/better-auth.d.ts +24 -0
  62. package/dist/auth/better-auth.d.ts.map +1 -0
  63. package/dist/auth/better-auth.js +108 -0
  64. package/dist/auth/better-auth.js.map +1 -0
  65. package/dist/board-claim.d.ts +23 -0
  66. package/dist/board-claim.d.ts.map +1 -0
  67. package/dist/board-claim.js +115 -0
  68. package/dist/board-claim.js.map +1 -0
  69. package/dist/config-file.d.ts +3 -0
  70. package/dist/config-file.d.ts.map +1 -0
  71. package/dist/config-file.js +16 -0
  72. package/dist/config-file.js.map +1 -0
  73. package/dist/config.d.ts +45 -0
  74. package/dist/config.d.ts.map +1 -0
  75. package/dist/config.js +171 -0
  76. package/dist/config.js.map +1 -0
  77. package/dist/dev-server-status.d.ts +27 -0
  78. package/dist/dev-server-status.d.ts.map +1 -0
  79. package/dist/dev-server-status.js +70 -0
  80. package/dist/dev-server-status.js.map +1 -0
  81. package/dist/dev-watch-ignore.d.ts +2 -0
  82. package/dist/dev-watch-ignore.d.ts.map +1 -0
  83. package/dist/dev-watch-ignore.js +33 -0
  84. package/dist/dev-watch-ignore.js.map +1 -0
  85. package/dist/errors.d.ts +12 -0
  86. package/dist/errors.d.ts.map +1 -0
  87. package/dist/errors.js +28 -0
  88. package/dist/errors.js.map +1 -0
  89. package/dist/home-paths.d.ts +17 -0
  90. package/dist/home-paths.d.ts.map +1 -0
  91. package/dist/home-paths.js +75 -0
  92. package/dist/home-paths.js.map +1 -0
  93. package/dist/index.d.ts +10 -0
  94. package/dist/index.d.ts.map +1 -0
  95. package/dist/index.js +642 -0
  96. package/dist/index.js.map +1 -0
  97. package/dist/log-redaction.d.ts +11 -0
  98. package/dist/log-redaction.d.ts.map +1 -0
  99. package/dist/log-redaction.js +118 -0
  100. package/dist/log-redaction.js.map +1 -0
  101. package/dist/middleware/auth.d.ts +12 -0
  102. package/dist/middleware/auth.d.ts.map +1 -0
  103. package/dist/middleware/auth.js +144 -0
  104. package/dist/middleware/auth.js.map +1 -0
  105. package/dist/middleware/board-mutation-guard.d.ts +3 -0
  106. package/dist/middleware/board-mutation-guard.d.ts.map +1 -0
  107. package/dist/middleware/board-mutation-guard.js +59 -0
  108. package/dist/middleware/board-mutation-guard.js.map +1 -0
  109. package/dist/middleware/error-handler.d.ts +17 -0
  110. package/dist/middleware/error-handler.d.ts.map +1 -0
  111. package/dist/middleware/error-handler.js +37 -0
  112. package/dist/middleware/error-handler.js.map +1 -0
  113. package/dist/middleware/index.d.ts +4 -0
  114. package/dist/middleware/index.d.ts.map +1 -0
  115. package/dist/middleware/index.js +4 -0
  116. package/dist/middleware/index.js.map +1 -0
  117. package/dist/middleware/logger.d.ts +4 -0
  118. package/dist/middleware/logger.d.ts.map +1 -0
  119. package/dist/middleware/logger.js +87 -0
  120. package/dist/middleware/logger.js.map +1 -0
  121. package/dist/middleware/private-hostname-guard.d.ts +11 -0
  122. package/dist/middleware/private-hostname-guard.d.ts.map +1 -0
  123. package/dist/middleware/private-hostname-guard.js +78 -0
  124. package/dist/middleware/private-hostname-guard.js.map +1 -0
  125. package/dist/middleware/validate.d.ts +4 -0
  126. package/dist/middleware/validate.d.ts.map +1 -0
  127. package/dist/middleware/validate.js +7 -0
  128. package/dist/middleware/validate.js.map +1 -0
  129. package/dist/onboarding-assets/ceo/AGENTS.md +54 -0
  130. package/dist/onboarding-assets/ceo/HEARTBEAT.md +72 -0
  131. package/dist/onboarding-assets/ceo/SOUL.md +33 -0
  132. package/dist/onboarding-assets/ceo/TOOLS.md +3 -0
  133. package/dist/onboarding-assets/default/AGENTS.md +3 -0
  134. package/dist/paths.d.ts +3 -0
  135. package/dist/paths.d.ts.map +1 -0
  136. package/dist/paths.js +31 -0
  137. package/dist/paths.js.map +1 -0
  138. package/dist/realtime/live-events-ws.d.ts +28 -0
  139. package/dist/realtime/live-events-ws.d.ts.map +1 -0
  140. package/dist/realtime/live-events-ws.js +187 -0
  141. package/dist/realtime/live-events-ws.js.map +1 -0
  142. package/dist/redaction.d.ts +4 -0
  143. package/dist/redaction.d.ts.map +1 -0
  144. package/dist/redaction.js +63 -0
  145. package/dist/redaction.js.map +1 -0
  146. package/dist/routes/access.d.ts +61 -0
  147. package/dist/routes/access.d.ts.map +1 -0
  148. package/dist/routes/access.js +2265 -0
  149. package/dist/routes/access.js.map +1 -0
  150. package/dist/routes/activity.d.ts +3 -0
  151. package/dist/routes/activity.d.ts.map +1 -0
  152. package/dist/routes/activity.js +78 -0
  153. package/dist/routes/activity.js.map +1 -0
  154. package/dist/routes/agents.d.ts +3 -0
  155. package/dist/routes/agents.d.ts.map +1 -0
  156. package/dist/routes/agents.js +1828 -0
  157. package/dist/routes/agents.js.map +1 -0
  158. package/dist/routes/approvals.d.ts +3 -0
  159. package/dist/routes/approvals.d.ts.map +1 -0
  160. package/dist/routes/approvals.js +275 -0
  161. package/dist/routes/approvals.js.map +1 -0
  162. package/dist/routes/assets.d.ts +4 -0
  163. package/dist/routes/assets.d.ts.map +1 -0
  164. package/dist/routes/assets.js +309 -0
  165. package/dist/routes/assets.js.map +1 -0
  166. package/dist/routes/authz.d.ts +16 -0
  167. package/dist/routes/authz.d.ts.map +1 -0
  168. package/dist/routes/authz.js +47 -0
  169. package/dist/routes/authz.js.map +1 -0
  170. package/dist/routes/companies.d.ts +4 -0
  171. package/dist/routes/companies.d.ts.map +1 -0
  172. package/dist/routes/companies.js +303 -0
  173. package/dist/routes/companies.js.map +1 -0
  174. package/dist/routes/company-skills.d.ts +3 -0
  175. package/dist/routes/company-skills.d.ts.map +1 -0
  176. package/dist/routes/company-skills.js +228 -0
  177. package/dist/routes/company-skills.js.map +1 -0
  178. package/dist/routes/costs.d.ts +3 -0
  179. package/dist/routes/costs.d.ts.map +1 -0
  180. package/dist/routes/costs.js +268 -0
  181. package/dist/routes/costs.js.map +1 -0
  182. package/dist/routes/dashboard.d.ts +3 -0
  183. package/dist/routes/dashboard.d.ts.map +1 -0
  184. package/dist/routes/dashboard.js +15 -0
  185. package/dist/routes/dashboard.js.map +1 -0
  186. package/dist/routes/execution-workspaces.d.ts +3 -0
  187. package/dist/routes/execution-workspaces.d.ts.map +1 -0
  188. package/dist/routes/execution-workspaces.js +165 -0
  189. package/dist/routes/execution-workspaces.js.map +1 -0
  190. package/dist/routes/goals.d.ts +3 -0
  191. package/dist/routes/goals.d.ts.map +1 -0
  192. package/dist/routes/goals.js +95 -0
  193. package/dist/routes/goals.js.map +1 -0
  194. package/dist/routes/health.d.ts +9 -0
  195. package/dist/routes/health.d.ts.map +1 -0
  196. package/dist/routes/health.js +69 -0
  197. package/dist/routes/health.js.map +1 -0
  198. package/dist/routes/index.d.ts +18 -0
  199. package/dist/routes/index.d.ts.map +1 -0
  200. package/dist/routes/index.js +18 -0
  201. package/dist/routes/index.js.map +1 -0
  202. package/dist/routes/instance-settings.d.ts +3 -0
  203. package/dist/routes/instance-settings.d.ts.map +1 -0
  204. package/dist/routes/instance-settings.js +71 -0
  205. package/dist/routes/instance-settings.js.map +1 -0
  206. package/dist/routes/issues-checkout-wakeup.d.ts +9 -0
  207. package/dist/routes/issues-checkout-wakeup.d.ts.map +1 -0
  208. package/dist/routes/issues-checkout-wakeup.js +12 -0
  209. package/dist/routes/issues-checkout-wakeup.js.map +1 -0
  210. package/dist/routes/issues.d.ts +4 -0
  211. package/dist/routes/issues.d.ts.map +1 -0
  212. package/dist/routes/issues.js +1520 -0
  213. package/dist/routes/issues.js.map +1 -0
  214. package/dist/routes/llms.d.ts +3 -0
  215. package/dist/routes/llms.d.ts.map +1 -0
  216. package/dist/routes/llms.js +78 -0
  217. package/dist/routes/llms.js.map +1 -0
  218. package/dist/routes/org-chart-svg.d.ts +25 -0
  219. package/dist/routes/org-chart-svg.d.ts.map +1 -0
  220. package/dist/routes/org-chart-svg.js +656 -0
  221. package/dist/routes/org-chart-svg.js.map +1 -0
  222. package/dist/routes/plugin-ui-static.d.ts +69 -0
  223. package/dist/routes/plugin-ui-static.d.ts.map +1 -0
  224. package/dist/routes/plugin-ui-static.js +411 -0
  225. package/dist/routes/plugin-ui-static.js.map +1 -0
  226. package/dist/routes/plugins.d.ts +120 -0
  227. package/dist/routes/plugins.d.ts.map +1 -0
  228. package/dist/routes/plugins.js +1784 -0
  229. package/dist/routes/plugins.js.map +1 -0
  230. package/dist/routes/projects.d.ts +3 -0
  231. package/dist/routes/projects.d.ts.map +1 -0
  232. package/dist/routes/projects.js +257 -0
  233. package/dist/routes/projects.js.map +1 -0
  234. package/dist/routes/routines.d.ts +3 -0
  235. package/dist/routes/routines.d.ts.map +1 -0
  236. package/dist/routes/routines.js +277 -0
  237. package/dist/routes/routines.js.map +1 -0
  238. package/dist/routes/secrets.d.ts +3 -0
  239. package/dist/routes/secrets.d.ts.map +1 -0
  240. package/dist/routes/secrets.js +128 -0
  241. package/dist/routes/secrets.js.map +1 -0
  242. package/dist/routes/sidebar-badges.d.ts +3 -0
  243. package/dist/routes/sidebar-badges.d.ts.map +1 -0
  244. package/dist/routes/sidebar-badges.js +45 -0
  245. package/dist/routes/sidebar-badges.js.map +1 -0
  246. package/dist/secrets/external-stub-providers.d.ts +5 -0
  247. package/dist/secrets/external-stub-providers.d.ts.map +1 -0
  248. package/dist/secrets/external-stub-providers.js +21 -0
  249. package/dist/secrets/external-stub-providers.js.map +1 -0
  250. package/dist/secrets/local-encrypted-provider.d.ts +3 -0
  251. package/dist/secrets/local-encrypted-provider.d.ts.map +1 -0
  252. package/dist/secrets/local-encrypted-provider.js +116 -0
  253. package/dist/secrets/local-encrypted-provider.js.map +1 -0
  254. package/dist/secrets/provider-registry.d.ts +5 -0
  255. package/dist/secrets/provider-registry.d.ts.map +1 -0
  256. package/dist/secrets/provider-registry.js +20 -0
  257. package/dist/secrets/provider-registry.js.map +1 -0
  258. package/dist/secrets/types.d.ts +21 -0
  259. package/dist/secrets/types.d.ts.map +1 -0
  260. package/dist/secrets/types.js +2 -0
  261. package/dist/secrets/types.js.map +1 -0
  262. package/dist/services/access.d.ts +113 -0
  263. package/dist/services/access.d.ts.map +1 -0
  264. package/dist/services/access.js +247 -0
  265. package/dist/services/access.js.map +1 -0
  266. package/dist/services/activity-log.d.ts +17 -0
  267. package/dist/services/activity-log.d.ts.map +1 -0
  268. package/dist/services/activity-log.js +74 -0
  269. package/dist/services/activity-log.js.map +1 -0
  270. package/dist/services/activity.d.ts +764 -0
  271. package/dist/services/activity.d.ts.map +1 -0
  272. package/dist/services/activity.js +105 -0
  273. package/dist/services/activity.js.map +1 -0
  274. package/dist/services/agent-instructions.d.ts +91 -0
  275. package/dist/services/agent-instructions.d.ts.map +1 -0
  276. package/dist/services/agent-instructions.js +580 -0
  277. package/dist/services/agent-instructions.js.map +1 -0
  278. package/dist/services/agent-permissions.d.ts +6 -0
  279. package/dist/services/agent-permissions.d.ts.map +1 -0
  280. package/dist/services/agent-permissions.js +18 -0
  281. package/dist/services/agent-permissions.js.map +1 -0
  282. package/dist/services/agents.d.ts +1670 -0
  283. package/dist/services/agents.d.ts.map +1 -0
  284. package/dist/services/agents.js +566 -0
  285. package/dist/services/agents.js.map +1 -0
  286. package/dist/services/approvals.d.ts +546 -0
  287. package/dist/services/approvals.d.ts.map +1 -0
  288. package/dist/services/approvals.js +212 -0
  289. package/dist/services/approvals.js.map +1 -0
  290. package/dist/services/assets.d.ts +33 -0
  291. package/dist/services/assets.d.ts.map +1 -0
  292. package/dist/services/assets.js +17 -0
  293. package/dist/services/assets.js.map +1 -0
  294. package/dist/services/board-auth.d.ts +234 -0
  295. package/dist/services/board-auth.d.ts.map +1 -0
  296. package/dist/services/board-auth.js +295 -0
  297. package/dist/services/board-auth.js.map +1 -0
  298. package/dist/services/budgets.d.ts +38 -0
  299. package/dist/services/budgets.d.ts.map +1 -0
  300. package/dist/services/budgets.js +784 -0
  301. package/dist/services/budgets.js.map +1 -0
  302. package/dist/services/companies.d.ts +124 -0
  303. package/dist/services/companies.d.ts.map +1 -0
  304. package/dist/services/companies.js +256 -0
  305. package/dist/services/companies.js.map +1 -0
  306. package/dist/services/company-export-readme.d.ts +17 -0
  307. package/dist/services/company-export-readme.d.ts.map +1 -0
  308. package/dist/services/company-export-readme.js +148 -0
  309. package/dist/services/company-export-readme.js.map +1 -0
  310. package/dist/services/company-portability.d.ts +23 -0
  311. package/dist/services/company-portability.d.ts.map +1 -0
  312. package/dist/services/company-portability.js +3739 -0
  313. package/dist/services/company-portability.js.map +1 -0
  314. package/dist/services/company-skills.d.ts +77 -0
  315. package/dist/services/company-skills.d.ts.map +1 -0
  316. package/dist/services/company-skills.js +2042 -0
  317. package/dist/services/company-skills.js.map +1 -0
  318. package/dist/services/costs.d.ts +114 -0
  319. package/dist/services/costs.d.ts.map +1 -0
  320. package/dist/services/costs.js +294 -0
  321. package/dist/services/costs.js.map +1 -0
  322. package/dist/services/cron.d.ts +80 -0
  323. package/dist/services/cron.d.ts.map +1 -0
  324. package/dist/services/cron.js +300 -0
  325. package/dist/services/cron.js.map +1 -0
  326. package/dist/services/dashboard.d.ts +26 -0
  327. package/dist/services/dashboard.d.ts.map +1 -0
  328. package/dist/services/dashboard.js +98 -0
  329. package/dist/services/dashboard.js.map +1 -0
  330. package/dist/services/default-agent-instructions.d.ts +9 -0
  331. package/dist/services/default-agent-instructions.d.ts.map +1 -0
  332. package/dist/services/default-agent-instructions.js +20 -0
  333. package/dist/services/default-agent-instructions.js.map +1 -0
  334. package/dist/services/documents.d.ts +164 -0
  335. package/dist/services/documents.d.ts.map +1 -0
  336. package/dist/services/documents.js +382 -0
  337. package/dist/services/documents.js.map +1 -0
  338. package/dist/services/execution-workspace-policy.d.ts +21 -0
  339. package/dist/services/execution-workspace-policy.d.ts.map +1 -0
  340. package/dist/services/execution-workspace-policy.js +177 -0
  341. package/dist/services/execution-workspace-policy.js.map +1 -0
  342. package/dist/services/execution-workspaces.d.ts +19 -0
  343. package/dist/services/execution-workspaces.d.ts.map +1 -0
  344. package/dist/services/execution-workspaces.js +87 -0
  345. package/dist/services/execution-workspaces.js.map +1 -0
  346. package/dist/services/finance.d.ts +93 -0
  347. package/dist/services/finance.d.ts.map +1 -0
  348. package/dist/services/finance.js +120 -0
  349. package/dist/services/finance.js.map +1 -0
  350. package/dist/services/goals.d.ts +433 -0
  351. package/dist/services/goals.d.ts.map +1 -0
  352. package/dist/services/goals.js +54 -0
  353. package/dist/services/goals.js.map +1 -0
  354. package/dist/services/heartbeat-run-summary.d.ts +2 -0
  355. package/dist/services/heartbeat-run-summary.d.ts.map +1 -0
  356. package/dist/services/heartbeat-run-summary.js +30 -0
  357. package/dist/services/heartbeat-run-summary.js.map +1 -0
  358. package/dist/services/heartbeat.d.ts +812 -0
  359. package/dist/services/heartbeat.d.ts.map +1 -0
  360. package/dist/services/heartbeat.js +3156 -0
  361. package/dist/services/heartbeat.js.map +1 -0
  362. package/dist/services/hire-hook.d.ts +14 -0
  363. package/dist/services/hire-hook.d.ts.map +1 -0
  364. package/dist/services/hire-hook.js +85 -0
  365. package/dist/services/hire-hook.js.map +1 -0
  366. package/dist/services/index.d.ts +33 -0
  367. package/dist/services/index.d.ts.map +1 -0
  368. package/dist/services/index.js +33 -0
  369. package/dist/services/index.js.map +1 -0
  370. package/dist/services/instance-settings.d.ts +11 -0
  371. package/dist/services/instance-settings.d.ts.map +1 -0
  372. package/dist/services/instance-settings.js +116 -0
  373. package/dist/services/instance-settings.js.map +1 -0
  374. package/dist/services/issue-approvals.d.ts +56 -0
  375. package/dist/services/issue-approvals.d.ts.map +1 -0
  376. package/dist/services/issue-approvals.js +153 -0
  377. package/dist/services/issue-approvals.js.map +1 -0
  378. package/dist/services/issue-assignment-wakeup.d.ts +29 -0
  379. package/dist/services/issue-assignment-wakeup.d.ts.map +1 -0
  380. package/dist/services/issue-assignment-wakeup.js +22 -0
  381. package/dist/services/issue-assignment-wakeup.js.map +1 -0
  382. package/dist/services/issue-goal-fallback.d.ts +18 -0
  383. package/dist/services/issue-goal-fallback.d.ts.map +1 -0
  384. package/dist/services/issue-goal-fallback.js +33 -0
  385. package/dist/services/issue-goal-fallback.js.map +1 -0
  386. package/dist/services/issues.d.ts +560 -0
  387. package/dist/services/issues.d.ts.map +1 -0
  388. package/dist/services/issues.js +1478 -0
  389. package/dist/services/issues.js.map +1 -0
  390. package/dist/services/live-events.d.ts +17 -0
  391. package/dist/services/live-events.d.ts.map +1 -0
  392. package/dist/services/live-events.js +33 -0
  393. package/dist/services/live-events.js.map +1 -0
  394. package/dist/services/plugin-capability-validator.d.ts +108 -0
  395. package/dist/services/plugin-capability-validator.d.ts.map +1 -0
  396. package/dist/services/plugin-capability-validator.js +268 -0
  397. package/dist/services/plugin-capability-validator.js.map +1 -0
  398. package/dist/services/plugin-config-validator.d.ts +26 -0
  399. package/dist/services/plugin-config-validator.d.ts.map +1 -0
  400. package/dist/services/plugin-config-validator.js +41 -0
  401. package/dist/services/plugin-config-validator.js.map +1 -0
  402. package/dist/services/plugin-dev-watcher.d.ts +30 -0
  403. package/dist/services/plugin-dev-watcher.d.ts.map +1 -0
  404. package/dist/services/plugin-dev-watcher.js +241 -0
  405. package/dist/services/plugin-dev-watcher.js.map +1 -0
  406. package/dist/services/plugin-event-bus.d.ts +149 -0
  407. package/dist/services/plugin-event-bus.d.ts.map +1 -0
  408. package/dist/services/plugin-event-bus.js +258 -0
  409. package/dist/services/plugin-event-bus.js.map +1 -0
  410. package/dist/services/plugin-host-service-cleanup.d.ts +14 -0
  411. package/dist/services/plugin-host-service-cleanup.d.ts.map +1 -0
  412. package/dist/services/plugin-host-service-cleanup.js +37 -0
  413. package/dist/services/plugin-host-service-cleanup.js.map +1 -0
  414. package/dist/services/plugin-host-services.d.ts +13 -0
  415. package/dist/services/plugin-host-services.d.ts.map +1 -0
  416. package/dist/services/plugin-host-services.js +969 -0
  417. package/dist/services/plugin-host-services.js.map +1 -0
  418. package/dist/services/plugin-job-coordinator.d.ts +81 -0
  419. package/dist/services/plugin-job-coordinator.d.ts.map +1 -0
  420. package/dist/services/plugin-job-coordinator.js +172 -0
  421. package/dist/services/plugin-job-coordinator.js.map +1 -0
  422. package/dist/services/plugin-job-scheduler.d.ts +163 -0
  423. package/dist/services/plugin-job-scheduler.d.ts.map +1 -0
  424. package/dist/services/plugin-job-scheduler.js +454 -0
  425. package/dist/services/plugin-job-scheduler.js.map +1 -0
  426. package/dist/services/plugin-job-store.d.ts +208 -0
  427. package/dist/services/plugin-job-store.d.ts.map +1 -0
  428. package/dist/services/plugin-job-store.js +350 -0
  429. package/dist/services/plugin-job-store.js.map +1 -0
  430. package/dist/services/plugin-lifecycle.d.ts +203 -0
  431. package/dist/services/plugin-lifecycle.d.ts.map +1 -0
  432. package/dist/services/plugin-lifecycle.js +476 -0
  433. package/dist/services/plugin-lifecycle.js.map +1 -0
  434. package/dist/services/plugin-loader.d.ts +441 -0
  435. package/dist/services/plugin-loader.d.ts.map +1 -0
  436. package/dist/services/plugin-loader.js +1192 -0
  437. package/dist/services/plugin-loader.js.map +1 -0
  438. package/dist/services/plugin-log-retention.d.ts +20 -0
  439. package/dist/services/plugin-log-retention.d.ts.map +1 -0
  440. package/dist/services/plugin-log-retention.js +63 -0
  441. package/dist/services/plugin-log-retention.js.map +1 -0
  442. package/dist/services/plugin-manifest-validator.d.ts +79 -0
  443. package/dist/services/plugin-manifest-validator.d.ts.map +1 -0
  444. package/dist/services/plugin-manifest-validator.js +84 -0
  445. package/dist/services/plugin-manifest-validator.js.map +1 -0
  446. package/dist/services/plugin-registry.d.ts +2542 -0
  447. package/dist/services/plugin-registry.d.ts.map +1 -0
  448. package/dist/services/plugin-registry.js +539 -0
  449. package/dist/services/plugin-registry.js.map +1 -0
  450. package/dist/services/plugin-runtime-sandbox.d.ts +40 -0
  451. package/dist/services/plugin-runtime-sandbox.d.ts.map +1 -0
  452. package/dist/services/plugin-runtime-sandbox.js +154 -0
  453. package/dist/services/plugin-runtime-sandbox.js.map +1 -0
  454. package/dist/services/plugin-secrets-handler.d.ts +81 -0
  455. package/dist/services/plugin-secrets-handler.d.ts.map +1 -0
  456. package/dist/services/plugin-secrets-handler.js +275 -0
  457. package/dist/services/plugin-secrets-handler.js.map +1 -0
  458. package/dist/services/plugin-state-store.d.ts +92 -0
  459. package/dist/services/plugin-state-store.d.ts.map +1 -0
  460. package/dist/services/plugin-state-store.js +190 -0
  461. package/dist/services/plugin-state-store.js.map +1 -0
  462. package/dist/services/plugin-stream-bus.d.ts +29 -0
  463. package/dist/services/plugin-stream-bus.d.ts.map +1 -0
  464. package/dist/services/plugin-stream-bus.js +48 -0
  465. package/dist/services/plugin-stream-bus.js.map +1 -0
  466. package/dist/services/plugin-tool-dispatcher.d.ts +180 -0
  467. package/dist/services/plugin-tool-dispatcher.d.ts.map +1 -0
  468. package/dist/services/plugin-tool-dispatcher.js +224 -0
  469. package/dist/services/plugin-tool-dispatcher.js.map +1 -0
  470. package/dist/services/plugin-tool-registry.d.ts +192 -0
  471. package/dist/services/plugin-tool-registry.d.ts.map +1 -0
  472. package/dist/services/plugin-tool-registry.js +224 -0
  473. package/dist/services/plugin-tool-registry.js.map +1 -0
  474. package/dist/services/plugin-worker-manager.d.ts +260 -0
  475. package/dist/services/plugin-worker-manager.d.ts.map +1 -0
  476. package/dist/services/plugin-worker-manager.js +835 -0
  477. package/dist/services/plugin-worker-manager.js.map +1 -0
  478. package/dist/services/projects.d.ts +87 -0
  479. package/dist/services/projects.d.ts.map +1 -0
  480. package/dist/services/projects.js +656 -0
  481. package/dist/services/projects.js.map +1 -0
  482. package/dist/services/quota-windows.d.ts +9 -0
  483. package/dist/services/quota-windows.d.ts.map +1 -0
  484. package/dist/services/quota-windows.js +56 -0
  485. package/dist/services/quota-windows.js.map +1 -0
  486. package/dist/services/routines.d.ts +135 -0
  487. package/dist/services/routines.d.ts.map +1 -0
  488. package/dist/services/routines.js +1105 -0
  489. package/dist/services/routines.js.map +1 -0
  490. package/dist/services/run-log-store.d.ts +34 -0
  491. package/dist/services/run-log-store.d.ts.map +1 -0
  492. package/dist/services/run-log-store.js +109 -0
  493. package/dist/services/run-log-store.js.map +1 -0
  494. package/dist/services/secrets.d.ts +511 -0
  495. package/dist/services/secrets.d.ts.map +1 -0
  496. package/dist/services/secrets.js +289 -0
  497. package/dist/services/secrets.js.map +1 -0
  498. package/dist/services/sidebar-badges.d.ts +9 -0
  499. package/dist/services/sidebar-badges.d.ts.map +1 -0
  500. package/dist/services/sidebar-badges.js +33 -0
  501. package/dist/services/sidebar-badges.js.map +1 -0
  502. package/dist/services/work-products.d.ts +14 -0
  503. package/dist/services/work-products.d.ts.map +1 -0
  504. package/dist/services/work-products.js +100 -0
  505. package/dist/services/work-products.js.map +1 -0
  506. package/dist/services/workspace-operation-log-store.d.ts +33 -0
  507. package/dist/services/workspace-operation-log-store.d.ts.map +1 -0
  508. package/dist/services/workspace-operation-log-store.js +110 -0
  509. package/dist/services/workspace-operation-log-store.js.map +1 -0
  510. package/dist/services/workspace-operations.d.ts +44 -0
  511. package/dist/services/workspace-operations.d.ts.map +1 -0
  512. package/dist/services/workspace-operations.js +211 -0
  513. package/dist/services/workspace-operations.js.map +1 -0
  514. package/dist/services/workspace-runtime.d.ts +164 -0
  515. package/dist/services/workspace-runtime.d.ts.map +1 -0
  516. package/dist/services/workspace-runtime.js +1235 -0
  517. package/dist/services/workspace-runtime.js.map +1 -0
  518. package/dist/startup-banner.d.ts +31 -0
  519. package/dist/startup-banner.d.ts.map +1 -0
  520. package/dist/startup-banner.js +117 -0
  521. package/dist/startup-banner.js.map +1 -0
  522. package/dist/storage/index.d.ts +6 -0
  523. package/dist/storage/index.d.ts.map +1 -0
  524. package/dist/storage/index.js +29 -0
  525. package/dist/storage/index.js.map +1 -0
  526. package/dist/storage/local-disk-provider.d.ts +3 -0
  527. package/dist/storage/local-disk-provider.d.ts.map +1 -0
  528. package/dist/storage/local-disk-provider.js +79 -0
  529. package/dist/storage/local-disk-provider.js.map +1 -0
  530. package/dist/storage/provider-registry.d.ts +4 -0
  531. package/dist/storage/provider-registry.d.ts.map +1 -0
  532. package/dist/storage/provider-registry.js +15 -0
  533. package/dist/storage/provider-registry.js.map +1 -0
  534. package/dist/storage/s3-provider.d.ts +11 -0
  535. package/dist/storage/s3-provider.d.ts.map +1 -0
  536. package/dist/storage/s3-provider.js +123 -0
  537. package/dist/storage/s3-provider.js.map +1 -0
  538. package/dist/storage/service.d.ts +3 -0
  539. package/dist/storage/service.d.ts.map +1 -0
  540. package/dist/storage/service.js +120 -0
  541. package/dist/storage/service.js.map +1 -0
  542. package/dist/storage/types.d.ts +55 -0
  543. package/dist/storage/types.d.ts.map +1 -0
  544. package/dist/storage/types.js +2 -0
  545. package/dist/storage/types.js.map +1 -0
  546. package/dist/ui-branding.d.ts +13 -0
  547. package/dist/ui-branding.d.ts.map +1 -0
  548. package/dist/ui-branding.js +187 -0
  549. package/dist/ui-branding.js.map +1 -0
  550. package/dist/version.d.ts +2 -0
  551. package/dist/version.d.ts.map +1 -0
  552. package/dist/version.js +5 -0
  553. package/dist/version.js.map +1 -0
  554. package/dist/worktree-config.d.ts +19 -0
  555. package/dist/worktree-config.d.ts.map +1 -0
  556. package/dist/worktree-config.js +365 -0
  557. package/dist/worktree-config.js.map +1 -0
  558. package/package.json +95 -0
  559. package/ui-dist/android-chrome-192x192.png +0 -0
  560. package/ui-dist/android-chrome-512x512.png +0 -0
  561. package/ui-dist/apple-touch-icon.png +0 -0
  562. package/ui-dist/assets/_basePickBy-BB1S19s0.js +1 -0
  563. package/ui-dist/assets/_baseUniq-BNk0p-bq.js +1 -0
  564. package/ui-dist/assets/apl-B4CMkyY2.js +1 -0
  565. package/ui-dist/assets/arc-Ds13x1NW.js +1 -0
  566. package/ui-dist/assets/architectureDiagram-VXUJARFQ-D8Br-_jt.js +36 -0
  567. package/ui-dist/assets/asciiarmor-Df11BRmG.js +1 -0
  568. package/ui-dist/assets/asn1-EdZsLKOL.js +1 -0
  569. package/ui-dist/assets/asterisk-B-8jnY81.js +1 -0
  570. package/ui-dist/assets/blockDiagram-VD42YOAC-CCYsAhQ5.js +122 -0
  571. package/ui-dist/assets/brainfuck-C4LP7Hcl.js +1 -0
  572. package/ui-dist/assets/c4Diagram-YG6GDRKO-CsrnTJYB.js +10 -0
  573. package/ui-dist/assets/channel-Df4ReTUQ.js +1 -0
  574. package/ui-dist/assets/chunk-4BX2VUAB-s-S3bm2a.js +1 -0
  575. package/ui-dist/assets/chunk-55IACEB6-AlPeSG3C.js +1 -0
  576. package/ui-dist/assets/chunk-B4BG7PRW-Dlv3zmp0.js +165 -0
  577. package/ui-dist/assets/chunk-DI55MBZ5-y3Hfc2F6.js +220 -0
  578. package/ui-dist/assets/chunk-FMBD7UC4-ZbmFZ8uD.js +15 -0
  579. package/ui-dist/assets/chunk-QN33PNHL-g7XrAaL5.js +1 -0
  580. package/ui-dist/assets/chunk-QZHKN3VN-DQz2X_ZR.js +1 -0
  581. package/ui-dist/assets/chunk-TZMSLE5B-NRbDhryd.js +1 -0
  582. package/ui-dist/assets/classDiagram-2ON5EDUG-CdLb01dH.js +1 -0
  583. package/ui-dist/assets/classDiagram-v2-WZHVMYZB-CdLb01dH.js +1 -0
  584. package/ui-dist/assets/clike-B9uivgTg.js +1 -0
  585. package/ui-dist/assets/clojure-BMjYHr_A.js +1 -0
  586. package/ui-dist/assets/clone-ycTwxHSX.js +1 -0
  587. package/ui-dist/assets/cmake-BQqOBYOt.js +1 -0
  588. package/ui-dist/assets/cobol-CWcv1MsR.js +1 -0
  589. package/ui-dist/assets/coffeescript-S37ZYGWr.js +1 -0
  590. package/ui-dist/assets/commonlisp-DBKNyK5s.js +1 -0
  591. package/ui-dist/assets/cose-bilkent-S5V4N54A-CifA3UGC.js +1 -0
  592. package/ui-dist/assets/crystal-SjHAIU92.js +1 -0
  593. package/ui-dist/assets/css-BnMrqG3P.js +1 -0
  594. package/ui-dist/assets/cypher-C_CwsFkJ.js +1 -0
  595. package/ui-dist/assets/cytoscape.esm-BQaXIfA_.js +331 -0
  596. package/ui-dist/assets/d-pRatUO7H.js +1 -0
  597. package/ui-dist/assets/dagre-6UL2VRFP-Cy4_402x.js +4 -0
  598. package/ui-dist/assets/defaultLocale-DX6XiGOO.js +1 -0
  599. package/ui-dist/assets/diagram-PSM6KHXK-CUA-Vqxe.js +24 -0
  600. package/ui-dist/assets/diagram-QEK2KX5R-D763Ackt.js +43 -0
  601. package/ui-dist/assets/diagram-S2PKOQOG-Cu1xEKHt.js +24 -0
  602. package/ui-dist/assets/diff-DbItnlRl.js +1 -0
  603. package/ui-dist/assets/dockerfile-BKs6k2Af.js +1 -0
  604. package/ui-dist/assets/dtd-DF_7sFjM.js +1 -0
  605. package/ui-dist/assets/dylan-DwRh75JA.js +1 -0
  606. package/ui-dist/assets/ebnf-CDyGwa7X.js +1 -0
  607. package/ui-dist/assets/ecl-Cabwm37j.js +1 -0
  608. package/ui-dist/assets/eiffel-CnydiIhH.js +1 -0
  609. package/ui-dist/assets/elm-vLlmbW-K.js +1 -0
  610. package/ui-dist/assets/erDiagram-Q2GNP2WA-9RlN9oCi.js +60 -0
  611. package/ui-dist/assets/erlang-BNw1qcRV.js +1 -0
  612. package/ui-dist/assets/factor-kuTfRLto.js +1 -0
  613. package/ui-dist/assets/fcl-Kvtd6kyn.js +1 -0
  614. package/ui-dist/assets/flowDiagram-NV44I4VS-Ddv1tq-H.js +162 -0
  615. package/ui-dist/assets/forth-Ffai-XNe.js +1 -0
  616. package/ui-dist/assets/fortran-DYz_wnZ1.js +1 -0
  617. package/ui-dist/assets/ganttDiagram-JELNMOA3-DAw7UfVT.js +267 -0
  618. package/ui-dist/assets/gas-Bneqetm1.js +1 -0
  619. package/ui-dist/assets/gherkin-heZmZLOM.js +1 -0
  620. package/ui-dist/assets/gitGraphDiagram-V2S2FVAM-CLPkzwpF.js +65 -0
  621. package/ui-dist/assets/graph-B1ThnnK5.js +1 -0
  622. package/ui-dist/assets/groovy-D9Dt4D0W.js +1 -0
  623. package/ui-dist/assets/haskell-Cw1EW3IL.js +1 -0
  624. package/ui-dist/assets/haxe-H-WmDvRZ.js +1 -0
  625. package/ui-dist/assets/http-DBlCnlav.js +1 -0
  626. package/ui-dist/assets/idl-BEugSyMb.js +1 -0
  627. package/ui-dist/assets/index-0DYmQxT3.js +2 -0
  628. package/ui-dist/assets/index-1BRIjwwa.js +1 -0
  629. package/ui-dist/assets/index-4pxn9bje.js +1 -0
  630. package/ui-dist/assets/index-B02pjBpR.js +7 -0
  631. package/ui-dist/assets/index-BGjMkZzC.js +1 -0
  632. package/ui-dist/assets/index-BHsjaYJ1.js +1 -0
  633. package/ui-dist/assets/index-BTwpjL-6.js +1 -0
  634. package/ui-dist/assets/index-BZ72uG4K.js +6 -0
  635. package/ui-dist/assets/index-BpC8VHcj.js +3 -0
  636. package/ui-dist/assets/index-BrvXvCkd.js +1 -0
  637. package/ui-dist/assets/index-CEBcI-2f.js +1 -0
  638. package/ui-dist/assets/index-CkmjCahV.js +1 -0
  639. package/ui-dist/assets/index-Cp84QmJD.css +1 -0
  640. package/ui-dist/assets/index-CpVjtxma.js +1 -0
  641. package/ui-dist/assets/index-D3AJPUjv.js +1 -0
  642. package/ui-dist/assets/index-DRkeP4vs.js +13 -0
  643. package/ui-dist/assets/index-DXeNhnre.js +1180 -0
  644. package/ui-dist/assets/index-DXvXmooU.js +1 -0
  645. package/ui-dist/assets/index-DZdwValG.js +1 -0
  646. package/ui-dist/assets/index-DbWj5-qO.js +1 -0
  647. package/ui-dist/assets/index-DbcKBTbp.js +1 -0
  648. package/ui-dist/assets/index-DdAQdjTR.js +1 -0
  649. package/ui-dist/assets/index-DlImcHKo.js +1 -0
  650. package/ui-dist/assets/index-X9LdJDbl.js +1 -0
  651. package/ui-dist/assets/infoDiagram-HS3SLOUP-CbJm6kuq.js +2 -0
  652. package/ui-dist/assets/init-Gi6I4Gst.js +1 -0
  653. package/ui-dist/assets/javascript-iXu5QeM3.js +1 -0
  654. package/ui-dist/assets/journeyDiagram-XKPGCS4Q-CeNVFpGu.js +139 -0
  655. package/ui-dist/assets/julia-DuME0IfC.js +1 -0
  656. package/ui-dist/assets/kanban-definition-3W4ZIXB7-DRqPoDRI.js +89 -0
  657. package/ui-dist/assets/katex-O9d3_IXG.js +261 -0
  658. package/ui-dist/assets/layout-CZTKj8OD.js +1 -0
  659. package/ui-dist/assets/linear-BDJjeIco.js +1 -0
  660. package/ui-dist/assets/livescript-BwQOo05w.js +1 -0
  661. package/ui-dist/assets/lua-BgMRiT3U.js +1 -0
  662. package/ui-dist/assets/mathematica-DTrFuWx2.js +1 -0
  663. package/ui-dist/assets/mbox-CNhZ1qSd.js +1 -0
  664. package/ui-dist/assets/mermaid.core-B5v7dPHY.js +256 -0
  665. package/ui-dist/assets/mindmap-definition-VGOIOE7T-zjw0AyzL.js +68 -0
  666. package/ui-dist/assets/mirc-CjQqDB4T.js +1 -0
  667. package/ui-dist/assets/mllike-CXdrOF99.js +1 -0
  668. package/ui-dist/assets/modelica-Dc1JOy9r.js +1 -0
  669. package/ui-dist/assets/mscgen-BA5vi2Kp.js +1 -0
  670. package/ui-dist/assets/mumps-BT43cFF4.js +1 -0
  671. package/ui-dist/assets/nginx-DdIZxoE0.js +1 -0
  672. package/ui-dist/assets/nsis-LdVXkNf5.js +1 -0
  673. package/ui-dist/assets/ntriples-BfvgReVJ.js +1 -0
  674. package/ui-dist/assets/octave-Ck1zUtKM.js +1 -0
  675. package/ui-dist/assets/ordinal-Cboi1Yqb.js +1 -0
  676. package/ui-dist/assets/oz-BzwKVEFT.js +1 -0
  677. package/ui-dist/assets/pascal--L3eBynH.js +1 -0
  678. package/ui-dist/assets/perl-CdXCOZ3F.js +1 -0
  679. package/ui-dist/assets/pieDiagram-ADFJNKIX-ojNQ8Ukr.js +30 -0
  680. package/ui-dist/assets/pig-CevX1Tat.js +1 -0
  681. package/ui-dist/assets/powershell-CFHJl5sT.js +1 -0
  682. package/ui-dist/assets/properties-C78fOPTZ.js +1 -0
  683. package/ui-dist/assets/protobuf-ChK-085T.js +1 -0
  684. package/ui-dist/assets/pug-DeIclll2.js +1 -0
  685. package/ui-dist/assets/puppet-DMA9R1ak.js +1 -0
  686. package/ui-dist/assets/python-BuPzkPfP.js +1 -0
  687. package/ui-dist/assets/q-pXgVlZs6.js +1 -0
  688. package/ui-dist/assets/quadrantDiagram-AYHSOK5B-B8K2F86x.js +7 -0
  689. package/ui-dist/assets/r-B6wPVr8A.js +1 -0
  690. package/ui-dist/assets/requirementDiagram-UZGBJVZJ-DA_Bjcpk.js +64 -0
  691. package/ui-dist/assets/rpm-CTu-6PCP.js +1 -0
  692. package/ui-dist/assets/ruby-B2Rjki9n.js +1 -0
  693. package/ui-dist/assets/sankeyDiagram-TZEHDZUN-yQfMgroQ.js +10 -0
  694. package/ui-dist/assets/sas-B4kiWyti.js +1 -0
  695. package/ui-dist/assets/scheme-C41bIUwD.js +1 -0
  696. package/ui-dist/assets/sequenceDiagram-WL72ISMW-CWQm0UQc.js +145 -0
  697. package/ui-dist/assets/shell-CjFT_Tl9.js +1 -0
  698. package/ui-dist/assets/sieve-C3Gn_uJK.js +1 -0
  699. package/ui-dist/assets/simple-mode-GW_nhZxv.js +1 -0
  700. package/ui-dist/assets/smalltalk-CnHTOXQT.js +1 -0
  701. package/ui-dist/assets/solr-DehyRSwq.js +1 -0
  702. package/ui-dist/assets/sparql-DkYu6x3z.js +1 -0
  703. package/ui-dist/assets/spreadsheet-BCZA_wO0.js +1 -0
  704. package/ui-dist/assets/sql-D0XecflT.js +1 -0
  705. package/ui-dist/assets/stateDiagram-FKZM4ZOC-C9L_ELvE.js +1 -0
  706. package/ui-dist/assets/stateDiagram-v2-4FDKWEC3-D3i22gRM.js +1 -0
  707. package/ui-dist/assets/stex-C3f8Ysf7.js +1 -0
  708. package/ui-dist/assets/stylus-B533Al4x.js +1 -0
  709. package/ui-dist/assets/swift-BzpIVaGY.js +1 -0
  710. package/ui-dist/assets/tcl-DVfN8rqt.js +1 -0
  711. package/ui-dist/assets/textile-CnDTJFAw.js +1 -0
  712. package/ui-dist/assets/tiddlywiki-DO-Gjzrf.js +1 -0
  713. package/ui-dist/assets/tiki-DGYXhP31.js +1 -0
  714. package/ui-dist/assets/timeline-definition-IT6M3QCI-Bfva-2zq.js +61 -0
  715. package/ui-dist/assets/toml-Bm5Em-hy.js +1 -0
  716. package/ui-dist/assets/treemap-GDKQZRPO-6wTQWQt4.js +162 -0
  717. package/ui-dist/assets/troff-wAsdV37c.js +1 -0
  718. package/ui-dist/assets/ttcn-CfJYG6tj.js +1 -0
  719. package/ui-dist/assets/ttcn-cfg-B9xdYoR4.js +1 -0
  720. package/ui-dist/assets/turtle-B1tBg_DP.js +1 -0
  721. package/ui-dist/assets/vb-CmGdzxic.js +1 -0
  722. package/ui-dist/assets/vbscript-BuJXcnF6.js +1 -0
  723. package/ui-dist/assets/velocity-D8B20fx6.js +1 -0
  724. package/ui-dist/assets/verilog-C6RDOZhf.js +1 -0
  725. package/ui-dist/assets/vhdl-lSbBsy5d.js +1 -0
  726. package/ui-dist/assets/webidl-ZXfAyPTL.js +1 -0
  727. package/ui-dist/assets/xquery-DzFWVndE.js +1 -0
  728. package/ui-dist/assets/xychartDiagram-PRI3JC2R-DNsmIw3v.js +7 -0
  729. package/ui-dist/assets/yacas-BJ4BC0dw.js +1 -0
  730. package/ui-dist/assets/z80-Hz9HOZM7.js +1 -0
  731. package/ui-dist/brands/opencode-logo-dark-square.svg +18 -0
  732. package/ui-dist/brands/opencode-logo-light-square.svg +18 -0
  733. package/ui-dist/favicon-16x16.png +0 -0
  734. package/ui-dist/favicon-32x32.png +0 -0
  735. package/ui-dist/favicon.ico +0 -0
  736. package/ui-dist/favicon.svg +9 -0
  737. package/ui-dist/index.html +48 -0
  738. package/ui-dist/site.webmanifest +30 -0
  739. package/ui-dist/sw.js +42 -0
  740. package/ui-dist/worktree-favicon-16x16.png +0 -0
  741. package/ui-dist/worktree-favicon-32x32.png +0 -0
  742. package/ui-dist/worktree-favicon.ico +0 -0
  743. package/ui-dist/worktree-favicon.svg +9 -0
@@ -0,0 +1,1828 @@
1
+ import { Router } from "express";
2
+ import { generateKeyPairSync, randomUUID } from "node:crypto";
3
+ import path from "node:path";
4
+ import { agents as agentsTable, companies, heartbeatRuns } from "@fidelios/db";
5
+ import { and, desc, eq, inArray, not, sql } from "drizzle-orm";
6
+ import { agentSkillSyncSchema, createAgentKeySchema, createAgentHireSchema, createAgentSchema, deriveAgentUrlKey, isUuidLike, resetAgentSessionSchema, testAdapterEnvironmentSchema, upsertAgentInstructionsFileSchema, updateAgentInstructionsBundleSchema, updateAgentPermissionsSchema, updateAgentInstructionsPathSchema, wakeAgentSchema, updateAgentSchema, } from "@fidelios/shared";
7
+ import { readFideliOSSkillSyncPreference, writeFideliOSSkillSyncPreference, } from "@fidelios/adapter-utils/server-utils";
8
+ import { validate } from "../middleware/validate.js";
9
+ import { agentService, agentInstructionsService, accessService, approvalService, companySkillService, budgetService, heartbeatService, issueApprovalService, issueService, logActivity, secretService, syncInstructionsBundleConfigFromFilePath, workspaceOperationService, } from "../services/index.js";
10
+ import { conflict, forbidden, notFound, unprocessable } from "../errors.js";
11
+ import { assertBoard, assertCompanyAccess, assertInstanceAdmin, getActorInfo } from "./authz.js";
12
+ import { findServerAdapter, listAdapterModels, detectAdapterModel } from "../adapters/index.js";
13
+ import { redactEventPayload } from "../redaction.js";
14
+ import { redactCurrentUserValue } from "../log-redaction.js";
15
+ import { renderOrgChartSvg, renderOrgChartPng, ORG_CHART_STYLES } from "./org-chart-svg.js";
16
+ import { instanceSettingsService } from "../services/instance-settings.js";
17
+ import { runClaudeLogin } from "@fidelios/adapter-claude-local/server";
18
+ import { DEFAULT_CODEX_LOCAL_BYPASS_APPROVALS_AND_SANDBOX, DEFAULT_CODEX_LOCAL_MODEL, } from "@fidelios/adapter-codex-local";
19
+ import { DEFAULT_CURSOR_LOCAL_MODEL } from "@fidelios/adapter-cursor-local";
20
+ import { DEFAULT_GEMINI_LOCAL_MODEL } from "@fidelios/adapter-gemini-local";
21
+ import { ensureOpenCodeModelConfiguredAndAvailable } from "@fidelios/adapter-opencode-local/server";
22
+ import { loadDefaultAgentInstructionsBundle, resolveDefaultAgentInstructionsBundleRole, } from "../services/default-agent-instructions.js";
23
+ export function agentRoutes(db) {
24
+ const DEFAULT_INSTRUCTIONS_PATH_KEYS = {
25
+ claude_local: "instructionsFilePath",
26
+ codex_local: "instructionsFilePath",
27
+ gemini_local: "instructionsFilePath",
28
+ opencode_local: "instructionsFilePath",
29
+ cursor: "instructionsFilePath",
30
+ pi_local: "instructionsFilePath",
31
+ };
32
+ const DEFAULT_MANAGED_INSTRUCTIONS_ADAPTER_TYPES = new Set(Object.keys(DEFAULT_INSTRUCTIONS_PATH_KEYS));
33
+ const KNOWN_INSTRUCTIONS_PATH_KEYS = new Set(["instructionsFilePath", "agentsMdPath"]);
34
+ const KNOWN_INSTRUCTIONS_BUNDLE_KEYS = [
35
+ "instructionsBundleMode",
36
+ "instructionsRootPath",
37
+ "instructionsEntryFile",
38
+ "instructionsFilePath",
39
+ "agentsMdPath",
40
+ ];
41
+ const router = Router();
42
+ const svc = agentService(db);
43
+ const access = accessService(db);
44
+ const approvalsSvc = approvalService(db);
45
+ const budgets = budgetService(db);
46
+ const heartbeat = heartbeatService(db);
47
+ const issueApprovalsSvc = issueApprovalService(db);
48
+ const secretsSvc = secretService(db);
49
+ const instructions = agentInstructionsService();
50
+ const companySkills = companySkillService(db);
51
+ const workspaceOperations = workspaceOperationService(db);
52
+ const instanceSettings = instanceSettingsService(db);
53
+ const strictSecretsMode = process.env.FIDELIOS_SECRETS_STRICT_MODE === "true";
54
+ async function getCurrentUserRedactionOptions() {
55
+ return {
56
+ enabled: (await instanceSettings.getGeneral()).censorUsernameInLogs,
57
+ };
58
+ }
59
+ function canCreateAgents(agent) {
60
+ if (!agent.permissions || typeof agent.permissions !== "object")
61
+ return false;
62
+ return Boolean(agent.permissions.canCreateAgents);
63
+ }
64
+ async function buildAgentAccessState(agent) {
65
+ const membership = await access.getMembership(agent.companyId, "agent", agent.id);
66
+ const grants = membership
67
+ ? await access.listPrincipalGrants(agent.companyId, "agent", agent.id)
68
+ : [];
69
+ const hasExplicitTaskAssignGrant = grants.some((grant) => grant.permissionKey === "tasks:assign");
70
+ if (agent.role === "ceo") {
71
+ return {
72
+ canAssignTasks: true,
73
+ taskAssignSource: "ceo_role",
74
+ membership,
75
+ grants,
76
+ };
77
+ }
78
+ if (canCreateAgents(agent)) {
79
+ return {
80
+ canAssignTasks: true,
81
+ taskAssignSource: "agent_creator",
82
+ membership,
83
+ grants,
84
+ };
85
+ }
86
+ if (hasExplicitTaskAssignGrant) {
87
+ return {
88
+ canAssignTasks: true,
89
+ taskAssignSource: "explicit_grant",
90
+ membership,
91
+ grants,
92
+ };
93
+ }
94
+ return {
95
+ canAssignTasks: false,
96
+ taskAssignSource: "none",
97
+ membership,
98
+ grants,
99
+ };
100
+ }
101
+ async function buildAgentDetail(agent, options) {
102
+ const [chainOfCommand, accessState] = await Promise.all([
103
+ svc.getChainOfCommand(agent.id),
104
+ buildAgentAccessState(agent),
105
+ ]);
106
+ return {
107
+ ...(options?.restricted ? redactForRestrictedAgentView(agent) : agent),
108
+ chainOfCommand,
109
+ access: accessState,
110
+ };
111
+ }
112
+ async function applyDefaultAgentTaskAssignGrant(companyId, agentId, grantedByUserId) {
113
+ await access.ensureMembership(companyId, "agent", agentId, "member", "active");
114
+ await access.setPrincipalPermission(companyId, "agent", agentId, "tasks:assign", true, grantedByUserId);
115
+ }
116
+ async function assertCanCreateAgentsForCompany(req, companyId) {
117
+ assertCompanyAccess(req, companyId);
118
+ if (req.actor.type === "board") {
119
+ if (req.actor.source === "local_implicit" || req.actor.isInstanceAdmin)
120
+ return null;
121
+ const allowed = await access.canUser(companyId, req.actor.userId, "agents:create");
122
+ if (!allowed) {
123
+ throw forbidden("Missing permission: agents:create");
124
+ }
125
+ return null;
126
+ }
127
+ if (!req.actor.agentId)
128
+ throw forbidden("Agent authentication required");
129
+ const actorAgent = await svc.getById(req.actor.agentId);
130
+ if (!actorAgent || actorAgent.companyId !== companyId) {
131
+ throw forbidden("Agent key cannot access another company");
132
+ }
133
+ const allowedByGrant = await access.hasPermission(companyId, "agent", actorAgent.id, "agents:create");
134
+ if (!allowedByGrant && !canCreateAgents(actorAgent)) {
135
+ throw forbidden("Missing permission: can create agents");
136
+ }
137
+ return actorAgent;
138
+ }
139
+ async function assertCanReadConfigurations(req, companyId) {
140
+ return assertCanCreateAgentsForCompany(req, companyId);
141
+ }
142
+ async function actorCanReadConfigurationsForCompany(req, companyId) {
143
+ assertCompanyAccess(req, companyId);
144
+ if (req.actor.type === "board") {
145
+ if (req.actor.source === "local_implicit" || req.actor.isInstanceAdmin)
146
+ return true;
147
+ return access.canUser(companyId, req.actor.userId, "agents:create");
148
+ }
149
+ if (!req.actor.agentId)
150
+ return false;
151
+ const actorAgent = await svc.getById(req.actor.agentId);
152
+ if (!actorAgent || actorAgent.companyId !== companyId)
153
+ return false;
154
+ const allowedByGrant = await access.hasPermission(companyId, "agent", actorAgent.id, "agents:create");
155
+ return allowedByGrant || canCreateAgents(actorAgent);
156
+ }
157
+ async function assertCanUpdateAgent(req, targetAgent) {
158
+ assertCompanyAccess(req, targetAgent.companyId);
159
+ if (req.actor.type === "board")
160
+ return;
161
+ if (!req.actor.agentId)
162
+ throw forbidden("Agent authentication required");
163
+ const actorAgent = await svc.getById(req.actor.agentId);
164
+ if (!actorAgent || actorAgent.companyId !== targetAgent.companyId) {
165
+ throw forbidden("Agent key cannot access another company");
166
+ }
167
+ if (actorAgent.id === targetAgent.id)
168
+ return;
169
+ if (actorAgent.role === "ceo")
170
+ return;
171
+ const allowedByGrant = await access.hasPermission(targetAgent.companyId, "agent", actorAgent.id, "agents:create");
172
+ if (allowedByGrant || canCreateAgents(actorAgent))
173
+ return;
174
+ throw forbidden("Only CEO or agent creators can modify other agents");
175
+ }
176
+ async function assertCanReadAgent(req, targetAgent) {
177
+ assertCompanyAccess(req, targetAgent.companyId);
178
+ if (req.actor.type === "board")
179
+ return;
180
+ if (!req.actor.agentId)
181
+ throw forbidden("Agent authentication required");
182
+ const actorAgent = await svc.getById(req.actor.agentId);
183
+ if (!actorAgent || actorAgent.companyId !== targetAgent.companyId) {
184
+ throw forbidden("Agent key cannot access another company");
185
+ }
186
+ }
187
+ async function resolveCompanyIdForAgentReference(req) {
188
+ const companyIdQuery = req.query.companyId;
189
+ const requestedCompanyId = typeof companyIdQuery === "string" && companyIdQuery.trim().length > 0
190
+ ? companyIdQuery.trim()
191
+ : null;
192
+ if (requestedCompanyId) {
193
+ assertCompanyAccess(req, requestedCompanyId);
194
+ return requestedCompanyId;
195
+ }
196
+ if (req.actor.type === "agent" && req.actor.companyId) {
197
+ return req.actor.companyId;
198
+ }
199
+ return null;
200
+ }
201
+ async function normalizeAgentReference(req, rawId) {
202
+ const raw = rawId.trim();
203
+ if (isUuidLike(raw))
204
+ return raw;
205
+ const companyId = await resolveCompanyIdForAgentReference(req);
206
+ if (!companyId) {
207
+ throw unprocessable("Agent shortname lookup requires companyId query parameter");
208
+ }
209
+ const resolved = await svc.resolveByReference(companyId, raw);
210
+ if (resolved.ambiguous) {
211
+ throw conflict("Agent shortname is ambiguous in this company. Use the agent ID.");
212
+ }
213
+ if (!resolved.agent) {
214
+ throw notFound("Agent not found");
215
+ }
216
+ return resolved.agent.id;
217
+ }
218
+ function parseSourceIssueIds(input) {
219
+ const values = [];
220
+ if (Array.isArray(input.sourceIssueIds))
221
+ values.push(...input.sourceIssueIds);
222
+ if (typeof input.sourceIssueId === "string" && input.sourceIssueId.length > 0) {
223
+ values.push(input.sourceIssueId);
224
+ }
225
+ return Array.from(new Set(values));
226
+ }
227
+ function asRecord(value) {
228
+ if (typeof value !== "object" || value === null || Array.isArray(value))
229
+ return null;
230
+ return value;
231
+ }
232
+ function asNonEmptyString(value) {
233
+ if (typeof value !== "string")
234
+ return null;
235
+ const trimmed = value.trim();
236
+ return trimmed.length > 0 ? trimmed : null;
237
+ }
238
+ function preserveInstructionsBundleConfig(existingAdapterConfig, nextAdapterConfig) {
239
+ const nextKeys = new Set(Object.keys(nextAdapterConfig));
240
+ if (KNOWN_INSTRUCTIONS_BUNDLE_KEYS.some((key) => nextKeys.has(key))) {
241
+ return nextAdapterConfig;
242
+ }
243
+ const merged = { ...nextAdapterConfig };
244
+ for (const key of KNOWN_INSTRUCTIONS_BUNDLE_KEYS) {
245
+ if (merged[key] === undefined && existingAdapterConfig[key] !== undefined) {
246
+ merged[key] = existingAdapterConfig[key];
247
+ }
248
+ }
249
+ return merged;
250
+ }
251
+ function parseBooleanLike(value) {
252
+ if (typeof value === "boolean")
253
+ return value;
254
+ if (typeof value === "number") {
255
+ if (value === 1)
256
+ return true;
257
+ if (value === 0)
258
+ return false;
259
+ return null;
260
+ }
261
+ if (typeof value !== "string")
262
+ return null;
263
+ const normalized = value.trim().toLowerCase();
264
+ if (normalized === "true" || normalized === "1" || normalized === "yes" || normalized === "on") {
265
+ return true;
266
+ }
267
+ if (normalized === "false" || normalized === "0" || normalized === "no" || normalized === "off") {
268
+ return false;
269
+ }
270
+ return null;
271
+ }
272
+ function parseNumberLike(value) {
273
+ if (typeof value === "number" && Number.isFinite(value))
274
+ return value;
275
+ if (typeof value !== "string")
276
+ return null;
277
+ const parsed = Number(value.trim());
278
+ return Number.isFinite(parsed) ? parsed : null;
279
+ }
280
+ function parseSchedulerHeartbeatPolicy(runtimeConfig) {
281
+ const heartbeat = asRecord(asRecord(runtimeConfig)?.heartbeat) ?? {};
282
+ return {
283
+ enabled: parseBooleanLike(heartbeat.enabled) ?? true,
284
+ intervalSec: Math.max(0, parseNumberLike(heartbeat.intervalSec) ?? 0),
285
+ };
286
+ }
287
+ function generateEd25519PrivateKeyPem() {
288
+ const { privateKey } = generateKeyPairSync("ed25519");
289
+ return privateKey.export({ type: "pkcs8", format: "pem" }).toString();
290
+ }
291
+ function ensureGatewayDeviceKey(adapterType, adapterConfig) {
292
+ if (adapterType !== "openclaw_gateway")
293
+ return adapterConfig;
294
+ const disableDeviceAuth = parseBooleanLike(adapterConfig.disableDeviceAuth) === true;
295
+ if (disableDeviceAuth)
296
+ return adapterConfig;
297
+ if (asNonEmptyString(adapterConfig.devicePrivateKeyPem))
298
+ return adapterConfig;
299
+ return { ...adapterConfig, devicePrivateKeyPem: generateEd25519PrivateKeyPem() };
300
+ }
301
+ function applyCreateDefaultsByAdapterType(adapterType, adapterConfig) {
302
+ const next = { ...adapterConfig };
303
+ if (adapterType === "codex_local") {
304
+ if (!asNonEmptyString(next.model)) {
305
+ next.model = DEFAULT_CODEX_LOCAL_MODEL;
306
+ }
307
+ const hasBypassFlag = typeof next.dangerouslyBypassApprovalsAndSandbox === "boolean" ||
308
+ typeof next.dangerouslyBypassSandbox === "boolean";
309
+ if (!hasBypassFlag) {
310
+ next.dangerouslyBypassApprovalsAndSandbox = DEFAULT_CODEX_LOCAL_BYPASS_APPROVALS_AND_SANDBOX;
311
+ }
312
+ return ensureGatewayDeviceKey(adapterType, next);
313
+ }
314
+ if (adapterType === "gemini_local" && !asNonEmptyString(next.model)) {
315
+ next.model = DEFAULT_GEMINI_LOCAL_MODEL;
316
+ return ensureGatewayDeviceKey(adapterType, next);
317
+ }
318
+ // OpenCode requires explicit model selection — no default
319
+ if (adapterType === "cursor" && !asNonEmptyString(next.model)) {
320
+ next.model = DEFAULT_CURSOR_LOCAL_MODEL;
321
+ }
322
+ return ensureGatewayDeviceKey(adapterType, next);
323
+ }
324
+ async function assertAdapterConfigConstraints(companyId, adapterType, adapterConfig) {
325
+ if (adapterType !== "opencode_local")
326
+ return;
327
+ const { config: runtimeConfig } = await secretsSvc.resolveAdapterConfigForRuntime(companyId, adapterConfig);
328
+ const runtimeEnv = asRecord(runtimeConfig.env) ?? {};
329
+ try {
330
+ await ensureOpenCodeModelConfiguredAndAvailable({
331
+ model: runtimeConfig.model,
332
+ command: runtimeConfig.command,
333
+ cwd: runtimeConfig.cwd,
334
+ env: runtimeEnv,
335
+ });
336
+ }
337
+ catch (err) {
338
+ const reason = err instanceof Error ? err.message : String(err);
339
+ throw unprocessable(`Invalid opencode_local adapterConfig: ${reason}`);
340
+ }
341
+ }
342
+ function resolveInstructionsFilePath(candidatePath, adapterConfig) {
343
+ const trimmed = candidatePath.trim();
344
+ if (path.isAbsolute(trimmed))
345
+ return trimmed;
346
+ const cwd = asNonEmptyString(adapterConfig.cwd);
347
+ if (!cwd) {
348
+ throw unprocessable("Relative instructions path requires adapterConfig.cwd to be set to an absolute path");
349
+ }
350
+ if (!path.isAbsolute(cwd)) {
351
+ throw unprocessable("adapterConfig.cwd must be an absolute path to resolve relative instructions path");
352
+ }
353
+ return path.resolve(cwd, trimmed);
354
+ }
355
+ async function materializeDefaultInstructionsBundleForNewAgent(agent) {
356
+ if (!DEFAULT_MANAGED_INSTRUCTIONS_ADAPTER_TYPES.has(agent.adapterType)) {
357
+ return agent;
358
+ }
359
+ const adapterConfig = asRecord(agent.adapterConfig) ?? {};
360
+ const hasExplicitInstructionsBundle = Boolean(asNonEmptyString(adapterConfig.instructionsBundleMode))
361
+ || Boolean(asNonEmptyString(adapterConfig.instructionsRootPath))
362
+ || Boolean(asNonEmptyString(adapterConfig.instructionsEntryFile))
363
+ || Boolean(asNonEmptyString(adapterConfig.instructionsFilePath))
364
+ || Boolean(asNonEmptyString(adapterConfig.agentsMdPath));
365
+ if (hasExplicitInstructionsBundle) {
366
+ return agent;
367
+ }
368
+ const promptTemplate = typeof adapterConfig.promptTemplate === "string"
369
+ ? adapterConfig.promptTemplate
370
+ : "";
371
+ const files = promptTemplate.trim().length === 0
372
+ ? await loadDefaultAgentInstructionsBundle(resolveDefaultAgentInstructionsBundleRole(agent.role))
373
+ : { "AGENTS.md": promptTemplate };
374
+ const materialized = await instructions.materializeManagedBundle(agent, files, { entryFile: "AGENTS.md", replaceExisting: false });
375
+ const nextAdapterConfig = { ...materialized.adapterConfig };
376
+ delete nextAdapterConfig.promptTemplate;
377
+ const updated = await svc.update(agent.id, { adapterConfig: nextAdapterConfig });
378
+ return updated ?? { ...agent, adapterConfig: nextAdapterConfig };
379
+ }
380
+ async function assertCanManageInstructionsPath(req, targetAgent) {
381
+ assertCompanyAccess(req, targetAgent.companyId);
382
+ if (req.actor.type === "board")
383
+ return;
384
+ if (!req.actor.agentId)
385
+ throw forbidden("Agent authentication required");
386
+ const actorAgent = await svc.getById(req.actor.agentId);
387
+ if (!actorAgent || actorAgent.companyId !== targetAgent.companyId) {
388
+ throw forbidden("Agent key cannot access another company");
389
+ }
390
+ if (actorAgent.id === targetAgent.id)
391
+ return;
392
+ const chainOfCommand = await svc.getChainOfCommand(targetAgent.id);
393
+ if (chainOfCommand.some((manager) => manager.id === actorAgent.id))
394
+ return;
395
+ throw forbidden("Only the target agent or an ancestor manager can update instructions path");
396
+ }
397
+ function summarizeAgentUpdateDetails(patch) {
398
+ const changedTopLevelKeys = Object.keys(patch).sort();
399
+ const details = { changedTopLevelKeys };
400
+ const adapterConfigPatch = asRecord(patch.adapterConfig);
401
+ if (adapterConfigPatch) {
402
+ details.changedAdapterConfigKeys = Object.keys(adapterConfigPatch).sort();
403
+ }
404
+ const runtimeConfigPatch = asRecord(patch.runtimeConfig);
405
+ if (runtimeConfigPatch) {
406
+ details.changedRuntimeConfigKeys = Object.keys(runtimeConfigPatch).sort();
407
+ }
408
+ return details;
409
+ }
410
+ function buildUnsupportedSkillSnapshot(adapterType, desiredSkills = []) {
411
+ return {
412
+ adapterType,
413
+ supported: false,
414
+ mode: "unsupported",
415
+ desiredSkills,
416
+ entries: [],
417
+ warnings: ["This adapter does not implement skill sync yet."],
418
+ };
419
+ }
420
+ function shouldMaterializeRuntimeSkillsForAdapter(adapterType) {
421
+ return adapterType !== "claude_local";
422
+ }
423
+ async function buildRuntimeSkillConfig(companyId, adapterType, config) {
424
+ const runtimeSkillEntries = await companySkills.listRuntimeSkillEntries(companyId, {
425
+ materializeMissing: shouldMaterializeRuntimeSkillsForAdapter(adapterType),
426
+ });
427
+ return {
428
+ ...config,
429
+ fideliosRuntimeSkills: runtimeSkillEntries,
430
+ };
431
+ }
432
+ async function resolveDesiredSkillAssignment(companyId, adapterType, adapterConfig, requestedDesiredSkills) {
433
+ if (!requestedDesiredSkills) {
434
+ return {
435
+ adapterConfig,
436
+ desiredSkills: null,
437
+ runtimeSkillEntries: null,
438
+ };
439
+ }
440
+ const resolvedRequestedSkills = await companySkills.resolveRequestedSkillKeys(companyId, requestedDesiredSkills);
441
+ const runtimeSkillEntries = await companySkills.listRuntimeSkillEntries(companyId, {
442
+ materializeMissing: shouldMaterializeRuntimeSkillsForAdapter(adapterType),
443
+ });
444
+ const requiredSkills = runtimeSkillEntries
445
+ .filter((entry) => entry.required)
446
+ .map((entry) => entry.key);
447
+ const desiredSkills = Array.from(new Set([...requiredSkills, ...resolvedRequestedSkills]));
448
+ return {
449
+ adapterConfig: writeFideliOSSkillSyncPreference(adapterConfig, desiredSkills),
450
+ desiredSkills,
451
+ runtimeSkillEntries,
452
+ };
453
+ }
454
+ function redactForRestrictedAgentView(agent) {
455
+ if (!agent)
456
+ return null;
457
+ return {
458
+ ...agent,
459
+ adapterConfig: {},
460
+ runtimeConfig: {},
461
+ };
462
+ }
463
+ function redactAgentConfiguration(agent) {
464
+ if (!agent)
465
+ return null;
466
+ return {
467
+ id: agent.id,
468
+ companyId: agent.companyId,
469
+ name: agent.name,
470
+ role: agent.role,
471
+ title: agent.title,
472
+ status: agent.status,
473
+ reportsTo: agent.reportsTo,
474
+ adapterType: agent.adapterType,
475
+ adapterConfig: redactEventPayload(agent.adapterConfig),
476
+ runtimeConfig: redactEventPayload(agent.runtimeConfig),
477
+ permissions: agent.permissions,
478
+ updatedAt: agent.updatedAt,
479
+ };
480
+ }
481
+ function redactRevisionSnapshot(snapshot) {
482
+ if (!snapshot || typeof snapshot !== "object" || Array.isArray(snapshot))
483
+ return {};
484
+ const record = snapshot;
485
+ return {
486
+ ...record,
487
+ adapterConfig: redactEventPayload(typeof record.adapterConfig === "object" && record.adapterConfig !== null
488
+ ? record.adapterConfig
489
+ : {}),
490
+ runtimeConfig: redactEventPayload(typeof record.runtimeConfig === "object" && record.runtimeConfig !== null
491
+ ? record.runtimeConfig
492
+ : {}),
493
+ metadata: typeof record.metadata === "object" && record.metadata !== null
494
+ ? redactEventPayload(record.metadata)
495
+ : record.metadata ?? null,
496
+ };
497
+ }
498
+ function redactConfigRevision(revision) {
499
+ return {
500
+ ...revision,
501
+ beforeConfig: redactRevisionSnapshot(revision.beforeConfig),
502
+ afterConfig: redactRevisionSnapshot(revision.afterConfig),
503
+ };
504
+ }
505
+ function toLeanOrgNode(node) {
506
+ const reports = Array.isArray(node.reports)
507
+ ? node.reports.map((report) => toLeanOrgNode(report))
508
+ : [];
509
+ return {
510
+ id: String(node.id),
511
+ name: String(node.name),
512
+ role: String(node.role),
513
+ status: String(node.status),
514
+ reports,
515
+ };
516
+ }
517
+ router.param("id", async (req, _res, next, rawId) => {
518
+ try {
519
+ req.params.id = await normalizeAgentReference(req, String(rawId));
520
+ next();
521
+ }
522
+ catch (err) {
523
+ next(err);
524
+ }
525
+ });
526
+ router.get("/companies/:companyId/adapters/:type/models", async (req, res) => {
527
+ const companyId = req.params.companyId;
528
+ assertCompanyAccess(req, companyId);
529
+ const type = req.params.type;
530
+ const models = await listAdapterModels(type);
531
+ res.json(models);
532
+ });
533
+ router.get("/companies/:companyId/adapters/:type/detect-model", async (req, res) => {
534
+ const companyId = req.params.companyId;
535
+ assertCompanyAccess(req, companyId);
536
+ const type = req.params.type;
537
+ const detected = await detectAdapterModel(type);
538
+ res.json(detected);
539
+ });
540
+ router.post("/companies/:companyId/adapters/:type/test-environment", validate(testAdapterEnvironmentSchema), async (req, res) => {
541
+ const companyId = req.params.companyId;
542
+ const type = req.params.type;
543
+ await assertCanReadConfigurations(req, companyId);
544
+ const adapter = findServerAdapter(type);
545
+ if (!adapter) {
546
+ res.status(404).json({ error: `Unknown adapter type: ${type}` });
547
+ return;
548
+ }
549
+ const inputAdapterConfig = (req.body?.adapterConfig ?? {});
550
+ const normalizedAdapterConfig = await secretsSvc.normalizeAdapterConfigForPersistence(companyId, inputAdapterConfig, { strictMode: strictSecretsMode });
551
+ const { config: runtimeAdapterConfig } = await secretsSvc.resolveAdapterConfigForRuntime(companyId, normalizedAdapterConfig);
552
+ const result = await adapter.testEnvironment({
553
+ companyId,
554
+ adapterType: type,
555
+ config: runtimeAdapterConfig,
556
+ });
557
+ res.json(result);
558
+ });
559
+ router.get("/agents/:id/skills", async (req, res) => {
560
+ const id = req.params.id;
561
+ const agent = await svc.getById(id);
562
+ if (!agent) {
563
+ res.status(404).json({ error: "Agent not found" });
564
+ return;
565
+ }
566
+ await assertCanReadConfigurations(req, agent.companyId);
567
+ const adapter = findServerAdapter(agent.adapterType);
568
+ if (!adapter?.listSkills) {
569
+ const preference = readFideliOSSkillSyncPreference(agent.adapterConfig);
570
+ const runtimeSkillEntries = await companySkills.listRuntimeSkillEntries(agent.companyId, {
571
+ materializeMissing: false,
572
+ });
573
+ const requiredSkills = runtimeSkillEntries.filter((entry) => entry.required).map((entry) => entry.key);
574
+ res.json(buildUnsupportedSkillSnapshot(agent.adapterType, Array.from(new Set([...requiredSkills, ...preference.desiredSkills]))));
575
+ return;
576
+ }
577
+ const { config: runtimeConfig } = await secretsSvc.resolveAdapterConfigForRuntime(agent.companyId, agent.adapterConfig);
578
+ const runtimeSkillConfig = await buildRuntimeSkillConfig(agent.companyId, agent.adapterType, runtimeConfig);
579
+ const snapshot = await adapter.listSkills({
580
+ agentId: agent.id,
581
+ companyId: agent.companyId,
582
+ adapterType: agent.adapterType,
583
+ config: runtimeSkillConfig,
584
+ });
585
+ res.json(snapshot);
586
+ });
587
+ router.post("/agents/:id/skills/sync", validate(agentSkillSyncSchema), async (req, res) => {
588
+ const id = req.params.id;
589
+ const agent = await svc.getById(id);
590
+ if (!agent) {
591
+ res.status(404).json({ error: "Agent not found" });
592
+ return;
593
+ }
594
+ await assertCanUpdateAgent(req, agent);
595
+ const requestedSkills = Array.from(new Set(req.body.desiredSkills
596
+ .map((value) => value.trim())
597
+ .filter(Boolean)));
598
+ const { adapterConfig: nextAdapterConfig, desiredSkills, runtimeSkillEntries, } = await resolveDesiredSkillAssignment(agent.companyId, agent.adapterType, agent.adapterConfig, requestedSkills);
599
+ if (!desiredSkills || !runtimeSkillEntries) {
600
+ throw unprocessable("Skill sync requires desiredSkills.");
601
+ }
602
+ const actor = getActorInfo(req);
603
+ const updated = await svc.update(agent.id, {
604
+ adapterConfig: nextAdapterConfig,
605
+ }, {
606
+ recordRevision: {
607
+ createdByAgentId: actor.agentId,
608
+ createdByUserId: actor.actorType === "user" ? actor.actorId : null,
609
+ source: "skill-sync",
610
+ },
611
+ });
612
+ if (!updated) {
613
+ res.status(404).json({ error: "Agent not found" });
614
+ return;
615
+ }
616
+ const adapter = findServerAdapter(updated.adapterType);
617
+ const { config: runtimeConfig } = await secretsSvc.resolveAdapterConfigForRuntime(updated.companyId, updated.adapterConfig);
618
+ const runtimeSkillConfig = {
619
+ ...runtimeConfig,
620
+ fideliosRuntimeSkills: runtimeSkillEntries,
621
+ };
622
+ const snapshot = adapter?.syncSkills
623
+ ? await adapter.syncSkills({
624
+ agentId: updated.id,
625
+ companyId: updated.companyId,
626
+ adapterType: updated.adapterType,
627
+ config: runtimeSkillConfig,
628
+ }, desiredSkills)
629
+ : adapter?.listSkills
630
+ ? await adapter.listSkills({
631
+ agentId: updated.id,
632
+ companyId: updated.companyId,
633
+ adapterType: updated.adapterType,
634
+ config: runtimeSkillConfig,
635
+ })
636
+ : buildUnsupportedSkillSnapshot(updated.adapterType, desiredSkills);
637
+ await logActivity(db, {
638
+ companyId: updated.companyId,
639
+ actorType: actor.actorType,
640
+ actorId: actor.actorId,
641
+ action: "agent.skills_synced",
642
+ entityType: "agent",
643
+ entityId: updated.id,
644
+ agentId: actor.agentId,
645
+ runId: actor.runId,
646
+ details: {
647
+ adapterType: updated.adapterType,
648
+ desiredSkills,
649
+ mode: snapshot.mode,
650
+ supported: snapshot.supported,
651
+ entryCount: snapshot.entries.length,
652
+ warningCount: snapshot.warnings.length,
653
+ },
654
+ });
655
+ res.json(snapshot);
656
+ });
657
+ router.get("/companies/:companyId/agents", async (req, res) => {
658
+ const companyId = req.params.companyId;
659
+ assertCompanyAccess(req, companyId);
660
+ const result = await svc.list(companyId);
661
+ const canReadConfigs = await actorCanReadConfigurationsForCompany(req, companyId);
662
+ if (canReadConfigs || req.actor.type === "board") {
663
+ res.json(result);
664
+ return;
665
+ }
666
+ res.json(result.map((agent) => redactForRestrictedAgentView(agent)));
667
+ });
668
+ router.get("/instance/scheduler-heartbeats", async (req, res) => {
669
+ assertInstanceAdmin(req);
670
+ const rows = await db
671
+ .select({
672
+ id: agentsTable.id,
673
+ companyId: agentsTable.companyId,
674
+ agentName: agentsTable.name,
675
+ role: agentsTable.role,
676
+ title: agentsTable.title,
677
+ status: agentsTable.status,
678
+ adapterType: agentsTable.adapterType,
679
+ runtimeConfig: agentsTable.runtimeConfig,
680
+ lastHeartbeatAt: agentsTable.lastHeartbeatAt,
681
+ companyName: companies.name,
682
+ companyIssuePrefix: companies.issuePrefix,
683
+ })
684
+ .from(agentsTable)
685
+ .innerJoin(companies, eq(agentsTable.companyId, companies.id))
686
+ .orderBy(companies.name, agentsTable.name);
687
+ const items = rows
688
+ .map((row) => {
689
+ const policy = parseSchedulerHeartbeatPolicy(row.runtimeConfig);
690
+ const statusEligible = row.status !== "paused" &&
691
+ row.status !== "terminated" &&
692
+ row.status !== "pending_approval";
693
+ return {
694
+ id: row.id,
695
+ companyId: row.companyId,
696
+ companyName: row.companyName,
697
+ companyIssuePrefix: row.companyIssuePrefix,
698
+ agentName: row.agentName,
699
+ agentUrlKey: deriveAgentUrlKey(row.agentName, row.id),
700
+ role: row.role,
701
+ title: row.title,
702
+ status: row.status,
703
+ adapterType: row.adapterType,
704
+ intervalSec: policy.intervalSec,
705
+ heartbeatEnabled: policy.enabled,
706
+ schedulerActive: statusEligible && policy.enabled && policy.intervalSec > 0,
707
+ lastHeartbeatAt: row.lastHeartbeatAt,
708
+ };
709
+ })
710
+ .filter((item) => item.status !== "paused" &&
711
+ item.status !== "terminated" &&
712
+ item.status !== "pending_approval")
713
+ .sort((left, right) => {
714
+ if (left.schedulerActive !== right.schedulerActive) {
715
+ return left.schedulerActive ? -1 : 1;
716
+ }
717
+ const companyOrder = left.companyName.localeCompare(right.companyName);
718
+ if (companyOrder !== 0)
719
+ return companyOrder;
720
+ return left.agentName.localeCompare(right.agentName);
721
+ });
722
+ res.json(items);
723
+ });
724
+ router.get("/companies/:companyId/org", async (req, res) => {
725
+ const companyId = req.params.companyId;
726
+ assertCompanyAccess(req, companyId);
727
+ const tree = await svc.orgForCompany(companyId);
728
+ const leanTree = tree.map((node) => toLeanOrgNode(node));
729
+ res.json(leanTree);
730
+ });
731
+ router.get("/companies/:companyId/org.svg", async (req, res) => {
732
+ const companyId = req.params.companyId;
733
+ assertCompanyAccess(req, companyId);
734
+ const style = (ORG_CHART_STYLES.includes(req.query.style) ? req.query.style : "warmth");
735
+ const tree = await svc.orgForCompany(companyId);
736
+ const leanTree = tree.map((node) => toLeanOrgNode(node));
737
+ const svg = renderOrgChartSvg(leanTree, style);
738
+ res.setHeader("Content-Type", "image/svg+xml");
739
+ res.setHeader("Cache-Control", "no-cache");
740
+ res.send(svg);
741
+ });
742
+ router.get("/companies/:companyId/org.png", async (req, res) => {
743
+ const companyId = req.params.companyId;
744
+ assertCompanyAccess(req, companyId);
745
+ const style = (ORG_CHART_STYLES.includes(req.query.style) ? req.query.style : "warmth");
746
+ const tree = await svc.orgForCompany(companyId);
747
+ const leanTree = tree.map((node) => toLeanOrgNode(node));
748
+ const png = await renderOrgChartPng(leanTree, style);
749
+ res.setHeader("Content-Type", "image/png");
750
+ res.setHeader("Cache-Control", "no-cache");
751
+ res.send(png);
752
+ });
753
+ router.get("/companies/:companyId/agent-configurations", async (req, res) => {
754
+ const companyId = req.params.companyId;
755
+ await assertCanReadConfigurations(req, companyId);
756
+ const rows = await svc.list(companyId);
757
+ res.json(rows.map((row) => redactAgentConfiguration(row)));
758
+ });
759
+ router.get("/agents/me", async (req, res) => {
760
+ if (req.actor.type !== "agent" || !req.actor.agentId) {
761
+ res.status(401).json({ error: "Agent authentication required" });
762
+ return;
763
+ }
764
+ const agent = await svc.getById(req.actor.agentId);
765
+ if (!agent) {
766
+ res.status(404).json({ error: "Agent not found" });
767
+ return;
768
+ }
769
+ res.json(await buildAgentDetail(agent));
770
+ });
771
+ router.get("/agents/me/inbox-lite", async (req, res) => {
772
+ if (req.actor.type !== "agent" || !req.actor.agentId || !req.actor.companyId) {
773
+ res.status(401).json({ error: "Agent authentication required" });
774
+ return;
775
+ }
776
+ const issuesSvc = issueService(db);
777
+ const rows = await issuesSvc.list(req.actor.companyId, {
778
+ assigneeAgentId: req.actor.agentId,
779
+ status: "todo,in_progress,blocked",
780
+ });
781
+ res.json(rows.map((issue) => ({
782
+ id: issue.id,
783
+ identifier: issue.identifier,
784
+ title: issue.title,
785
+ status: issue.status,
786
+ priority: issue.priority,
787
+ projectId: issue.projectId,
788
+ goalId: issue.goalId,
789
+ parentId: issue.parentId,
790
+ updatedAt: issue.updatedAt,
791
+ activeRun: issue.activeRun,
792
+ })));
793
+ });
794
+ router.get("/agents/:id", async (req, res) => {
795
+ const id = req.params.id;
796
+ const agent = await svc.getById(id);
797
+ if (!agent) {
798
+ res.status(404).json({ error: "Agent not found" });
799
+ return;
800
+ }
801
+ assertCompanyAccess(req, agent.companyId);
802
+ if (req.actor.type === "agent" && req.actor.agentId !== id) {
803
+ const canRead = await actorCanReadConfigurationsForCompany(req, agent.companyId);
804
+ if (!canRead) {
805
+ res.json(await buildAgentDetail(agent, { restricted: true }));
806
+ return;
807
+ }
808
+ }
809
+ res.json(await buildAgentDetail(agent));
810
+ });
811
+ router.get("/agents/:id/configuration", async (req, res) => {
812
+ const id = req.params.id;
813
+ const agent = await svc.getById(id);
814
+ if (!agent) {
815
+ res.status(404).json({ error: "Agent not found" });
816
+ return;
817
+ }
818
+ await assertCanReadConfigurations(req, agent.companyId);
819
+ res.json(redactAgentConfiguration(agent));
820
+ });
821
+ router.get("/agents/:id/config-revisions", async (req, res) => {
822
+ const id = req.params.id;
823
+ const agent = await svc.getById(id);
824
+ if (!agent) {
825
+ res.status(404).json({ error: "Agent not found" });
826
+ return;
827
+ }
828
+ await assertCanReadConfigurations(req, agent.companyId);
829
+ const revisions = await svc.listConfigRevisions(id);
830
+ res.json(revisions.map((revision) => redactConfigRevision(revision)));
831
+ });
832
+ router.get("/agents/:id/config-revisions/:revisionId", async (req, res) => {
833
+ const id = req.params.id;
834
+ const revisionId = req.params.revisionId;
835
+ const agent = await svc.getById(id);
836
+ if (!agent) {
837
+ res.status(404).json({ error: "Agent not found" });
838
+ return;
839
+ }
840
+ await assertCanReadConfigurations(req, agent.companyId);
841
+ const revision = await svc.getConfigRevision(id, revisionId);
842
+ if (!revision) {
843
+ res.status(404).json({ error: "Revision not found" });
844
+ return;
845
+ }
846
+ res.json(redactConfigRevision(revision));
847
+ });
848
+ router.post("/agents/:id/config-revisions/:revisionId/rollback", async (req, res) => {
849
+ const id = req.params.id;
850
+ const revisionId = req.params.revisionId;
851
+ const existing = await svc.getById(id);
852
+ if (!existing) {
853
+ res.status(404).json({ error: "Agent not found" });
854
+ return;
855
+ }
856
+ await assertCanUpdateAgent(req, existing);
857
+ const actor = getActorInfo(req);
858
+ const updated = await svc.rollbackConfigRevision(id, revisionId, {
859
+ agentId: actor.agentId,
860
+ userId: actor.actorType === "user" ? actor.actorId : null,
861
+ });
862
+ if (!updated) {
863
+ res.status(404).json({ error: "Revision not found" });
864
+ return;
865
+ }
866
+ await logActivity(db, {
867
+ companyId: updated.companyId,
868
+ actorType: actor.actorType,
869
+ actorId: actor.actorId,
870
+ agentId: actor.agentId,
871
+ runId: actor.runId,
872
+ action: "agent.config_rolled_back",
873
+ entityType: "agent",
874
+ entityId: updated.id,
875
+ details: { revisionId },
876
+ });
877
+ res.json(updated);
878
+ });
879
+ router.get("/agents/:id/runtime-state", async (req, res) => {
880
+ assertBoard(req);
881
+ const id = req.params.id;
882
+ const agent = await svc.getById(id);
883
+ if (!agent) {
884
+ res.status(404).json({ error: "Agent not found" });
885
+ return;
886
+ }
887
+ assertCompanyAccess(req, agent.companyId);
888
+ const state = await heartbeat.getRuntimeState(id);
889
+ res.json(state);
890
+ });
891
+ router.get("/agents/:id/task-sessions", async (req, res) => {
892
+ assertBoard(req);
893
+ const id = req.params.id;
894
+ const agent = await svc.getById(id);
895
+ if (!agent) {
896
+ res.status(404).json({ error: "Agent not found" });
897
+ return;
898
+ }
899
+ assertCompanyAccess(req, agent.companyId);
900
+ const sessions = await heartbeat.listTaskSessions(id);
901
+ res.json(sessions.map((session) => ({
902
+ ...session,
903
+ sessionParamsJson: redactEventPayload(session.sessionParamsJson ?? null),
904
+ })));
905
+ });
906
+ router.post("/agents/:id/runtime-state/reset-session", validate(resetAgentSessionSchema), async (req, res) => {
907
+ assertBoard(req);
908
+ const id = req.params.id;
909
+ const agent = await svc.getById(id);
910
+ if (!agent) {
911
+ res.status(404).json({ error: "Agent not found" });
912
+ return;
913
+ }
914
+ assertCompanyAccess(req, agent.companyId);
915
+ const taskKey = typeof req.body.taskKey === "string" && req.body.taskKey.trim().length > 0
916
+ ? req.body.taskKey.trim()
917
+ : null;
918
+ const state = await heartbeat.resetRuntimeSession(id, { taskKey });
919
+ await logActivity(db, {
920
+ companyId: agent.companyId,
921
+ actorType: "user",
922
+ actorId: req.actor.userId ?? "board",
923
+ action: "agent.runtime_session_reset",
924
+ entityType: "agent",
925
+ entityId: id,
926
+ details: { taskKey: taskKey ?? null },
927
+ });
928
+ res.json(state);
929
+ });
930
+ router.post("/companies/:companyId/agent-hires", validate(createAgentHireSchema), async (req, res) => {
931
+ const companyId = req.params.companyId;
932
+ await assertCanCreateAgentsForCompany(req, companyId);
933
+ const sourceIssueIds = parseSourceIssueIds(req.body);
934
+ const { desiredSkills: requestedDesiredSkills, sourceIssueId: _sourceIssueId, sourceIssueIds: _sourceIssueIds, ...hireInput } = req.body;
935
+ const requestedAdapterConfig = applyCreateDefaultsByAdapterType(hireInput.adapterType, (hireInput.adapterConfig ?? {}));
936
+ const desiredSkillAssignment = await resolveDesiredSkillAssignment(companyId, hireInput.adapterType, requestedAdapterConfig, Array.isArray(requestedDesiredSkills) ? requestedDesiredSkills : undefined);
937
+ const normalizedAdapterConfig = await secretsSvc.normalizeAdapterConfigForPersistence(companyId, desiredSkillAssignment.adapterConfig, { strictMode: strictSecretsMode });
938
+ await assertAdapterConfigConstraints(companyId, hireInput.adapterType, normalizedAdapterConfig);
939
+ const normalizedHireInput = {
940
+ ...hireInput,
941
+ adapterConfig: normalizedAdapterConfig,
942
+ };
943
+ const company = await db
944
+ .select()
945
+ .from(companies)
946
+ .where(eq(companies.id, companyId))
947
+ .then((rows) => rows[0] ?? null);
948
+ if (!company) {
949
+ res.status(404).json({ error: "Company not found" });
950
+ return;
951
+ }
952
+ const requiresApproval = company.requireBoardApprovalForNewAgents;
953
+ const status = requiresApproval ? "pending_approval" : "idle";
954
+ const createdAgent = await svc.create(companyId, {
955
+ ...normalizedHireInput,
956
+ status,
957
+ spentMonthlyCents: 0,
958
+ lastHeartbeatAt: null,
959
+ });
960
+ const agent = await materializeDefaultInstructionsBundleForNewAgent(createdAgent);
961
+ let approval = null;
962
+ const actor = getActorInfo(req);
963
+ if (requiresApproval) {
964
+ const requestedAdapterType = normalizedHireInput.adapterType ?? agent.adapterType;
965
+ const requestedAdapterConfig = redactEventPayload((agent.adapterConfig ?? normalizedHireInput.adapterConfig)) ?? {};
966
+ const requestedRuntimeConfig = redactEventPayload((normalizedHireInput.runtimeConfig ?? agent.runtimeConfig)) ?? {};
967
+ const requestedMetadata = redactEventPayload((normalizedHireInput.metadata ?? agent.metadata ?? {})) ?? {};
968
+ approval = await approvalsSvc.create(companyId, {
969
+ type: "hire_agent",
970
+ requestedByAgentId: actor.actorType === "agent" ? actor.actorId : null,
971
+ requestedByUserId: actor.actorType === "user" ? actor.actorId : null,
972
+ status: "pending",
973
+ payload: {
974
+ name: normalizedHireInput.name,
975
+ role: normalizedHireInput.role,
976
+ title: normalizedHireInput.title ?? null,
977
+ icon: normalizedHireInput.icon ?? null,
978
+ reportsTo: normalizedHireInput.reportsTo ?? null,
979
+ capabilities: normalizedHireInput.capabilities ?? null,
980
+ adapterType: requestedAdapterType,
981
+ adapterConfig: requestedAdapterConfig,
982
+ runtimeConfig: requestedRuntimeConfig,
983
+ budgetMonthlyCents: typeof normalizedHireInput.budgetMonthlyCents === "number"
984
+ ? normalizedHireInput.budgetMonthlyCents
985
+ : agent.budgetMonthlyCents,
986
+ desiredSkills: desiredSkillAssignment.desiredSkills,
987
+ metadata: requestedMetadata,
988
+ agentId: agent.id,
989
+ requestedByAgentId: actor.actorType === "agent" ? actor.actorId : null,
990
+ requestedConfigurationSnapshot: {
991
+ adapterType: requestedAdapterType,
992
+ adapterConfig: requestedAdapterConfig,
993
+ runtimeConfig: requestedRuntimeConfig,
994
+ desiredSkills: desiredSkillAssignment.desiredSkills,
995
+ },
996
+ },
997
+ decisionNote: null,
998
+ decidedByUserId: null,
999
+ decidedAt: null,
1000
+ updatedAt: new Date(),
1001
+ });
1002
+ if (sourceIssueIds.length > 0) {
1003
+ await issueApprovalsSvc.linkManyForApproval(approval.id, sourceIssueIds, {
1004
+ agentId: actor.actorType === "agent" ? actor.actorId : null,
1005
+ userId: actor.actorType === "user" ? actor.actorId : null,
1006
+ });
1007
+ }
1008
+ }
1009
+ await logActivity(db, {
1010
+ companyId,
1011
+ actorType: actor.actorType,
1012
+ actorId: actor.actorId,
1013
+ agentId: actor.agentId,
1014
+ runId: actor.runId,
1015
+ action: "agent.hire_created",
1016
+ entityType: "agent",
1017
+ entityId: agent.id,
1018
+ details: {
1019
+ name: agent.name,
1020
+ role: agent.role,
1021
+ requiresApproval,
1022
+ approvalId: approval?.id ?? null,
1023
+ issueIds: sourceIssueIds,
1024
+ desiredSkills: desiredSkillAssignment.desiredSkills,
1025
+ },
1026
+ });
1027
+ await applyDefaultAgentTaskAssignGrant(companyId, agent.id, actor.actorType === "user" ? actor.actorId : null);
1028
+ if (approval) {
1029
+ await logActivity(db, {
1030
+ companyId,
1031
+ actorType: actor.actorType,
1032
+ actorId: actor.actorId,
1033
+ agentId: actor.agentId,
1034
+ runId: actor.runId,
1035
+ action: "approval.created",
1036
+ entityType: "approval",
1037
+ entityId: approval.id,
1038
+ details: { type: approval.type, linkedAgentId: agent.id },
1039
+ });
1040
+ }
1041
+ res.status(201).json({ agent, approval });
1042
+ });
1043
+ router.post("/companies/:companyId/agents", validate(createAgentSchema), async (req, res) => {
1044
+ const companyId = req.params.companyId;
1045
+ assertCompanyAccess(req, companyId);
1046
+ if (req.actor.type === "agent") {
1047
+ assertBoard(req);
1048
+ }
1049
+ const { desiredSkills: requestedDesiredSkills, ...createInput } = req.body;
1050
+ const requestedAdapterConfig = applyCreateDefaultsByAdapterType(createInput.adapterType, (createInput.adapterConfig ?? {}));
1051
+ const desiredSkillAssignment = await resolveDesiredSkillAssignment(companyId, createInput.adapterType, requestedAdapterConfig, Array.isArray(requestedDesiredSkills) ? requestedDesiredSkills : undefined);
1052
+ const normalizedAdapterConfig = await secretsSvc.normalizeAdapterConfigForPersistence(companyId, desiredSkillAssignment.adapterConfig, { strictMode: strictSecretsMode });
1053
+ await assertAdapterConfigConstraints(companyId, createInput.adapterType, normalizedAdapterConfig);
1054
+ const createdAgent = await svc.create(companyId, {
1055
+ ...createInput,
1056
+ adapterConfig: normalizedAdapterConfig,
1057
+ status: "idle",
1058
+ spentMonthlyCents: 0,
1059
+ lastHeartbeatAt: null,
1060
+ });
1061
+ const agent = await materializeDefaultInstructionsBundleForNewAgent(createdAgent);
1062
+ const actor = getActorInfo(req);
1063
+ await logActivity(db, {
1064
+ companyId,
1065
+ actorType: actor.actorType,
1066
+ actorId: actor.actorId,
1067
+ agentId: actor.agentId,
1068
+ runId: actor.runId,
1069
+ action: "agent.created",
1070
+ entityType: "agent",
1071
+ entityId: agent.id,
1072
+ details: {
1073
+ name: agent.name,
1074
+ role: agent.role,
1075
+ desiredSkills: desiredSkillAssignment.desiredSkills,
1076
+ },
1077
+ });
1078
+ await applyDefaultAgentTaskAssignGrant(companyId, agent.id, req.actor.type === "board" ? (req.actor.userId ?? null) : null);
1079
+ if (agent.budgetMonthlyCents > 0) {
1080
+ await budgets.upsertPolicy(companyId, {
1081
+ scopeType: "agent",
1082
+ scopeId: agent.id,
1083
+ amount: agent.budgetMonthlyCents,
1084
+ windowKind: "calendar_month_utc",
1085
+ }, actor.actorType === "user" ? actor.actorId : null);
1086
+ }
1087
+ res.status(201).json(agent);
1088
+ });
1089
+ router.patch("/agents/:id/permissions", validate(updateAgentPermissionsSchema), async (req, res) => {
1090
+ const id = req.params.id;
1091
+ const existing = await svc.getById(id);
1092
+ if (!existing) {
1093
+ res.status(404).json({ error: "Agent not found" });
1094
+ return;
1095
+ }
1096
+ assertCompanyAccess(req, existing.companyId);
1097
+ if (req.actor.type === "agent") {
1098
+ const actorAgent = req.actor.agentId ? await svc.getById(req.actor.agentId) : null;
1099
+ if (!actorAgent || actorAgent.companyId !== existing.companyId) {
1100
+ res.status(403).json({ error: "Forbidden" });
1101
+ return;
1102
+ }
1103
+ if (actorAgent.role !== "ceo") {
1104
+ res.status(403).json({ error: "Only CEO can manage permissions" });
1105
+ return;
1106
+ }
1107
+ }
1108
+ const agent = await svc.updatePermissions(id, req.body);
1109
+ if (!agent) {
1110
+ res.status(404).json({ error: "Agent not found" });
1111
+ return;
1112
+ }
1113
+ const effectiveCanAssignTasks = agent.role === "ceo" || Boolean(agent.permissions?.canCreateAgents) || req.body.canAssignTasks;
1114
+ await access.ensureMembership(agent.companyId, "agent", agent.id, "member", "active");
1115
+ await access.setPrincipalPermission(agent.companyId, "agent", agent.id, "tasks:assign", effectiveCanAssignTasks, req.actor.type === "board" ? (req.actor.userId ?? null) : null);
1116
+ const actor = getActorInfo(req);
1117
+ await logActivity(db, {
1118
+ companyId: agent.companyId,
1119
+ actorType: actor.actorType,
1120
+ actorId: actor.actorId,
1121
+ agentId: actor.agentId,
1122
+ runId: actor.runId,
1123
+ action: "agent.permissions_updated",
1124
+ entityType: "agent",
1125
+ entityId: agent.id,
1126
+ details: {
1127
+ canCreateAgents: agent.permissions?.canCreateAgents ?? false,
1128
+ canAssignTasks: effectiveCanAssignTasks,
1129
+ },
1130
+ });
1131
+ res.json(await buildAgentDetail(agent));
1132
+ });
1133
+ router.patch("/agents/:id/instructions-path", validate(updateAgentInstructionsPathSchema), async (req, res) => {
1134
+ const id = req.params.id;
1135
+ const existing = await svc.getById(id);
1136
+ if (!existing) {
1137
+ res.status(404).json({ error: "Agent not found" });
1138
+ return;
1139
+ }
1140
+ await assertCanManageInstructionsPath(req, existing);
1141
+ const existingAdapterConfig = asRecord(existing.adapterConfig) ?? {};
1142
+ const explicitKey = asNonEmptyString(req.body.adapterConfigKey);
1143
+ const defaultKey = DEFAULT_INSTRUCTIONS_PATH_KEYS[existing.adapterType] ?? null;
1144
+ const adapterConfigKey = explicitKey ?? defaultKey;
1145
+ if (!adapterConfigKey) {
1146
+ res.status(422).json({
1147
+ error: `No default instructions path key for adapter type '${existing.adapterType}'. Provide adapterConfigKey.`,
1148
+ });
1149
+ return;
1150
+ }
1151
+ const nextAdapterConfig = { ...existingAdapterConfig };
1152
+ if (req.body.path === null) {
1153
+ delete nextAdapterConfig[adapterConfigKey];
1154
+ }
1155
+ else {
1156
+ nextAdapterConfig[adapterConfigKey] = resolveInstructionsFilePath(req.body.path, existingAdapterConfig);
1157
+ }
1158
+ const syncedAdapterConfig = syncInstructionsBundleConfigFromFilePath(existing, nextAdapterConfig);
1159
+ const normalizedAdapterConfig = await secretsSvc.normalizeAdapterConfigForPersistence(existing.companyId, syncedAdapterConfig, { strictMode: strictSecretsMode });
1160
+ const actor = getActorInfo(req);
1161
+ const agent = await svc.update(id, { adapterConfig: normalizedAdapterConfig }, {
1162
+ recordRevision: {
1163
+ createdByAgentId: actor.agentId,
1164
+ createdByUserId: actor.actorType === "user" ? actor.actorId : null,
1165
+ source: "instructions_path_patch",
1166
+ },
1167
+ });
1168
+ if (!agent) {
1169
+ res.status(404).json({ error: "Agent not found" });
1170
+ return;
1171
+ }
1172
+ const updatedAdapterConfig = asRecord(agent.adapterConfig) ?? {};
1173
+ const pathValue = asNonEmptyString(updatedAdapterConfig[adapterConfigKey]);
1174
+ await logActivity(db, {
1175
+ companyId: agent.companyId,
1176
+ actorType: actor.actorType,
1177
+ actorId: actor.actorId,
1178
+ agentId: actor.agentId,
1179
+ runId: actor.runId,
1180
+ action: "agent.instructions_path_updated",
1181
+ entityType: "agent",
1182
+ entityId: agent.id,
1183
+ details: {
1184
+ adapterConfigKey,
1185
+ path: pathValue,
1186
+ cleared: req.body.path === null,
1187
+ },
1188
+ });
1189
+ res.json({
1190
+ agentId: agent.id,
1191
+ adapterType: agent.adapterType,
1192
+ adapterConfigKey,
1193
+ path: pathValue,
1194
+ });
1195
+ });
1196
+ router.get("/agents/:id/instructions-bundle", async (req, res) => {
1197
+ const id = req.params.id;
1198
+ const existing = await svc.getById(id);
1199
+ if (!existing) {
1200
+ res.status(404).json({ error: "Agent not found" });
1201
+ return;
1202
+ }
1203
+ await assertCanReadAgent(req, existing);
1204
+ res.json(await instructions.getBundle(existing));
1205
+ });
1206
+ router.patch("/agents/:id/instructions-bundle", validate(updateAgentInstructionsBundleSchema), async (req, res) => {
1207
+ const id = req.params.id;
1208
+ const existing = await svc.getById(id);
1209
+ if (!existing) {
1210
+ res.status(404).json({ error: "Agent not found" });
1211
+ return;
1212
+ }
1213
+ await assertCanManageInstructionsPath(req, existing);
1214
+ const actor = getActorInfo(req);
1215
+ const { bundle, adapterConfig } = await instructions.updateBundle(existing, req.body);
1216
+ const normalizedAdapterConfig = await secretsSvc.normalizeAdapterConfigForPersistence(existing.companyId, adapterConfig, { strictMode: strictSecretsMode });
1217
+ await svc.update(id, { adapterConfig: normalizedAdapterConfig }, {
1218
+ recordRevision: {
1219
+ createdByAgentId: actor.agentId,
1220
+ createdByUserId: actor.actorType === "user" ? actor.actorId : null,
1221
+ source: "instructions_bundle_patch",
1222
+ },
1223
+ });
1224
+ await logActivity(db, {
1225
+ companyId: existing.companyId,
1226
+ actorType: actor.actorType,
1227
+ actorId: actor.actorId,
1228
+ agentId: actor.agentId,
1229
+ runId: actor.runId,
1230
+ action: "agent.instructions_bundle_updated",
1231
+ entityType: "agent",
1232
+ entityId: existing.id,
1233
+ details: {
1234
+ mode: bundle.mode,
1235
+ rootPath: bundle.rootPath,
1236
+ entryFile: bundle.entryFile,
1237
+ clearLegacyPromptTemplate: req.body.clearLegacyPromptTemplate === true,
1238
+ },
1239
+ });
1240
+ res.json(bundle);
1241
+ });
1242
+ router.get("/agents/:id/instructions-bundle/file", async (req, res) => {
1243
+ const id = req.params.id;
1244
+ const existing = await svc.getById(id);
1245
+ if (!existing) {
1246
+ res.status(404).json({ error: "Agent not found" });
1247
+ return;
1248
+ }
1249
+ await assertCanReadAgent(req, existing);
1250
+ const relativePath = typeof req.query.path === "string" ? req.query.path : "";
1251
+ if (!relativePath.trim()) {
1252
+ res.status(422).json({ error: "Query parameter 'path' is required" });
1253
+ return;
1254
+ }
1255
+ res.json(await instructions.readFile(existing, relativePath));
1256
+ });
1257
+ router.put("/agents/:id/instructions-bundle/file", validate(upsertAgentInstructionsFileSchema), async (req, res) => {
1258
+ const id = req.params.id;
1259
+ const existing = await svc.getById(id);
1260
+ if (!existing) {
1261
+ res.status(404).json({ error: "Agent not found" });
1262
+ return;
1263
+ }
1264
+ await assertCanManageInstructionsPath(req, existing);
1265
+ const actor = getActorInfo(req);
1266
+ const result = await instructions.writeFile(existing, req.body.path, req.body.content, {
1267
+ clearLegacyPromptTemplate: req.body.clearLegacyPromptTemplate,
1268
+ });
1269
+ const normalizedAdapterConfig = await secretsSvc.normalizeAdapterConfigForPersistence(existing.companyId, result.adapterConfig, { strictMode: strictSecretsMode });
1270
+ await svc.update(id, { adapterConfig: normalizedAdapterConfig }, {
1271
+ recordRevision: {
1272
+ createdByAgentId: actor.agentId,
1273
+ createdByUserId: actor.actorType === "user" ? actor.actorId : null,
1274
+ source: "instructions_bundle_file_put",
1275
+ },
1276
+ });
1277
+ await logActivity(db, {
1278
+ companyId: existing.companyId,
1279
+ actorType: actor.actorType,
1280
+ actorId: actor.actorId,
1281
+ agentId: actor.agentId,
1282
+ runId: actor.runId,
1283
+ action: "agent.instructions_file_updated",
1284
+ entityType: "agent",
1285
+ entityId: existing.id,
1286
+ details: {
1287
+ path: result.file.path,
1288
+ size: result.file.size,
1289
+ clearLegacyPromptTemplate: req.body.clearLegacyPromptTemplate === true,
1290
+ },
1291
+ });
1292
+ res.json(result.file);
1293
+ });
1294
+ router.delete("/agents/:id/instructions-bundle/file", async (req, res) => {
1295
+ const id = req.params.id;
1296
+ const existing = await svc.getById(id);
1297
+ if (!existing) {
1298
+ res.status(404).json({ error: "Agent not found" });
1299
+ return;
1300
+ }
1301
+ await assertCanManageInstructionsPath(req, existing);
1302
+ const relativePath = typeof req.query.path === "string" ? req.query.path : "";
1303
+ if (!relativePath.trim()) {
1304
+ res.status(422).json({ error: "Query parameter 'path' is required" });
1305
+ return;
1306
+ }
1307
+ const actor = getActorInfo(req);
1308
+ const result = await instructions.deleteFile(existing, relativePath);
1309
+ await logActivity(db, {
1310
+ companyId: existing.companyId,
1311
+ actorType: actor.actorType,
1312
+ actorId: actor.actorId,
1313
+ agentId: actor.agentId,
1314
+ runId: actor.runId,
1315
+ action: "agent.instructions_file_deleted",
1316
+ entityType: "agent",
1317
+ entityId: existing.id,
1318
+ details: {
1319
+ path: relativePath,
1320
+ },
1321
+ });
1322
+ res.json(result.bundle);
1323
+ });
1324
+ router.patch("/agents/:id", validate(updateAgentSchema), async (req, res) => {
1325
+ const id = req.params.id;
1326
+ const existing = await svc.getById(id);
1327
+ if (!existing) {
1328
+ res.status(404).json({ error: "Agent not found" });
1329
+ return;
1330
+ }
1331
+ await assertCanUpdateAgent(req, existing);
1332
+ if (Object.prototype.hasOwnProperty.call(req.body, "permissions")) {
1333
+ res.status(422).json({ error: "Use /api/agents/:id/permissions for permission changes" });
1334
+ return;
1335
+ }
1336
+ const patchData = { ...req.body };
1337
+ const replaceAdapterConfig = patchData.replaceAdapterConfig === true;
1338
+ delete patchData.replaceAdapterConfig;
1339
+ if (Object.prototype.hasOwnProperty.call(patchData, "adapterConfig")) {
1340
+ const adapterConfig = asRecord(patchData.adapterConfig);
1341
+ if (!adapterConfig) {
1342
+ res.status(422).json({ error: "adapterConfig must be an object" });
1343
+ return;
1344
+ }
1345
+ const changingInstructionsPath = Object.keys(adapterConfig).some((key) => KNOWN_INSTRUCTIONS_PATH_KEYS.has(key));
1346
+ if (changingInstructionsPath) {
1347
+ await assertCanManageInstructionsPath(req, existing);
1348
+ }
1349
+ patchData.adapterConfig = adapterConfig;
1350
+ }
1351
+ const requestedAdapterType = typeof patchData.adapterType === "string" ? patchData.adapterType : existing.adapterType;
1352
+ const touchesAdapterConfiguration = Object.prototype.hasOwnProperty.call(patchData, "adapterType") ||
1353
+ Object.prototype.hasOwnProperty.call(patchData, "adapterConfig");
1354
+ if (touchesAdapterConfiguration) {
1355
+ const existingAdapterConfig = asRecord(existing.adapterConfig) ?? {};
1356
+ const changingAdapterType = typeof patchData.adapterType === "string" && patchData.adapterType !== existing.adapterType;
1357
+ const requestedAdapterConfig = Object.prototype.hasOwnProperty.call(patchData, "adapterConfig")
1358
+ ? (asRecord(patchData.adapterConfig) ?? {})
1359
+ : null;
1360
+ if (requestedAdapterConfig
1361
+ && replaceAdapterConfig
1362
+ && KNOWN_INSTRUCTIONS_BUNDLE_KEYS.some((key) => existingAdapterConfig[key] !== undefined && requestedAdapterConfig[key] === undefined)) {
1363
+ await assertCanManageInstructionsPath(req, existing);
1364
+ }
1365
+ let rawEffectiveAdapterConfig = requestedAdapterConfig ?? existingAdapterConfig;
1366
+ if (requestedAdapterConfig && !changingAdapterType && !replaceAdapterConfig) {
1367
+ rawEffectiveAdapterConfig = { ...existingAdapterConfig, ...requestedAdapterConfig };
1368
+ }
1369
+ if (changingAdapterType) {
1370
+ rawEffectiveAdapterConfig = preserveInstructionsBundleConfig(existingAdapterConfig, rawEffectiveAdapterConfig);
1371
+ }
1372
+ const effectiveAdapterConfig = applyCreateDefaultsByAdapterType(requestedAdapterType, rawEffectiveAdapterConfig);
1373
+ const normalizedEffectiveAdapterConfig = await secretsSvc.normalizeAdapterConfigForPersistence(existing.companyId, effectiveAdapterConfig, { strictMode: strictSecretsMode });
1374
+ patchData.adapterConfig = syncInstructionsBundleConfigFromFilePath(existing, normalizedEffectiveAdapterConfig);
1375
+ }
1376
+ if (touchesAdapterConfiguration && requestedAdapterType === "opencode_local") {
1377
+ const effectiveAdapterConfig = asRecord(patchData.adapterConfig) ?? {};
1378
+ await assertAdapterConfigConstraints(existing.companyId, requestedAdapterType, effectiveAdapterConfig);
1379
+ }
1380
+ const actor = getActorInfo(req);
1381
+ const agent = await svc.update(id, patchData, {
1382
+ recordRevision: {
1383
+ createdByAgentId: actor.agentId,
1384
+ createdByUserId: actor.actorType === "user" ? actor.actorId : null,
1385
+ source: "patch",
1386
+ },
1387
+ });
1388
+ if (!agent) {
1389
+ res.status(404).json({ error: "Agent not found" });
1390
+ return;
1391
+ }
1392
+ await logActivity(db, {
1393
+ companyId: agent.companyId,
1394
+ actorType: actor.actorType,
1395
+ actorId: actor.actorId,
1396
+ agentId: actor.agentId,
1397
+ runId: actor.runId,
1398
+ action: "agent.updated",
1399
+ entityType: "agent",
1400
+ entityId: agent.id,
1401
+ details: summarizeAgentUpdateDetails(patchData),
1402
+ });
1403
+ res.json(agent);
1404
+ });
1405
+ router.post("/agents/:id/pause", async (req, res) => {
1406
+ assertBoard(req);
1407
+ const id = req.params.id;
1408
+ const agent = await svc.pause(id);
1409
+ if (!agent) {
1410
+ res.status(404).json({ error: "Agent not found" });
1411
+ return;
1412
+ }
1413
+ await heartbeat.cancelActiveForAgent(id);
1414
+ await logActivity(db, {
1415
+ companyId: agent.companyId,
1416
+ actorType: "user",
1417
+ actorId: req.actor.userId ?? "board",
1418
+ action: "agent.paused",
1419
+ entityType: "agent",
1420
+ entityId: agent.id,
1421
+ });
1422
+ res.json(agent);
1423
+ });
1424
+ router.post("/agents/:id/resume", async (req, res) => {
1425
+ assertBoard(req);
1426
+ const id = req.params.id;
1427
+ const agent = await svc.resume(id);
1428
+ if (!agent) {
1429
+ res.status(404).json({ error: "Agent not found" });
1430
+ return;
1431
+ }
1432
+ await logActivity(db, {
1433
+ companyId: agent.companyId,
1434
+ actorType: "user",
1435
+ actorId: req.actor.userId ?? "board",
1436
+ action: "agent.resumed",
1437
+ entityType: "agent",
1438
+ entityId: agent.id,
1439
+ });
1440
+ res.json(agent);
1441
+ });
1442
+ router.post("/agents/:id/terminate", async (req, res) => {
1443
+ assertBoard(req);
1444
+ const id = req.params.id;
1445
+ const agent = await svc.terminate(id);
1446
+ if (!agent) {
1447
+ res.status(404).json({ error: "Agent not found" });
1448
+ return;
1449
+ }
1450
+ await heartbeat.cancelActiveForAgent(id);
1451
+ await logActivity(db, {
1452
+ companyId: agent.companyId,
1453
+ actorType: "user",
1454
+ actorId: req.actor.userId ?? "board",
1455
+ action: "agent.terminated",
1456
+ entityType: "agent",
1457
+ entityId: agent.id,
1458
+ });
1459
+ res.json(agent);
1460
+ });
1461
+ router.delete("/agents/:id", async (req, res) => {
1462
+ assertBoard(req);
1463
+ const id = req.params.id;
1464
+ const agent = await svc.remove(id);
1465
+ if (!agent) {
1466
+ res.status(404).json({ error: "Agent not found" });
1467
+ return;
1468
+ }
1469
+ await logActivity(db, {
1470
+ companyId: agent.companyId,
1471
+ actorType: "user",
1472
+ actorId: req.actor.userId ?? "board",
1473
+ action: "agent.deleted",
1474
+ entityType: "agent",
1475
+ entityId: agent.id,
1476
+ });
1477
+ res.json({ ok: true });
1478
+ });
1479
+ router.get("/agents/:id/keys", async (req, res) => {
1480
+ assertBoard(req);
1481
+ const id = req.params.id;
1482
+ const keys = await svc.listKeys(id);
1483
+ res.json(keys);
1484
+ });
1485
+ router.post("/agents/:id/keys", validate(createAgentKeySchema), async (req, res) => {
1486
+ assertBoard(req);
1487
+ const id = req.params.id;
1488
+ const key = await svc.createApiKey(id, req.body.name);
1489
+ const agent = await svc.getById(id);
1490
+ if (agent) {
1491
+ await logActivity(db, {
1492
+ companyId: agent.companyId,
1493
+ actorType: "user",
1494
+ actorId: req.actor.userId ?? "board",
1495
+ action: "agent.key_created",
1496
+ entityType: "agent",
1497
+ entityId: agent.id,
1498
+ details: { keyId: key.id, name: key.name },
1499
+ });
1500
+ }
1501
+ res.status(201).json(key);
1502
+ });
1503
+ router.delete("/agents/:id/keys/:keyId", async (req, res) => {
1504
+ assertBoard(req);
1505
+ const keyId = req.params.keyId;
1506
+ const revoked = await svc.revokeKey(keyId);
1507
+ if (!revoked) {
1508
+ res.status(404).json({ error: "Key not found" });
1509
+ return;
1510
+ }
1511
+ res.json({ ok: true });
1512
+ });
1513
+ router.post("/agents/:id/wakeup", validate(wakeAgentSchema), async (req, res) => {
1514
+ const id = req.params.id;
1515
+ const agent = await svc.getById(id);
1516
+ if (!agent) {
1517
+ res.status(404).json({ error: "Agent not found" });
1518
+ return;
1519
+ }
1520
+ assertCompanyAccess(req, agent.companyId);
1521
+ if (req.actor.type === "agent" && req.actor.agentId !== id) {
1522
+ res.status(403).json({ error: "Agent can only invoke itself" });
1523
+ return;
1524
+ }
1525
+ const run = await heartbeat.wakeup(id, {
1526
+ source: req.body.source,
1527
+ triggerDetail: req.body.triggerDetail ?? "manual",
1528
+ reason: req.body.reason ?? null,
1529
+ payload: req.body.payload ?? null,
1530
+ idempotencyKey: req.body.idempotencyKey ?? null,
1531
+ requestedByActorType: req.actor.type === "agent" ? "agent" : "user",
1532
+ requestedByActorId: req.actor.type === "agent" ? req.actor.agentId ?? null : req.actor.userId ?? null,
1533
+ contextSnapshot: {
1534
+ triggeredBy: req.actor.type,
1535
+ actorId: req.actor.type === "agent" ? req.actor.agentId : req.actor.userId,
1536
+ forceFreshSession: req.body.forceFreshSession === true,
1537
+ },
1538
+ });
1539
+ if (!run) {
1540
+ res.status(202).json({ status: "skipped" });
1541
+ return;
1542
+ }
1543
+ const actor = getActorInfo(req);
1544
+ await logActivity(db, {
1545
+ companyId: agent.companyId,
1546
+ actorType: actor.actorType,
1547
+ actorId: actor.actorId,
1548
+ agentId: actor.agentId,
1549
+ runId: actor.runId,
1550
+ action: "heartbeat.invoked",
1551
+ entityType: "heartbeat_run",
1552
+ entityId: run.id,
1553
+ details: { agentId: id },
1554
+ });
1555
+ res.status(202).json(run);
1556
+ });
1557
+ router.post("/agents/:id/heartbeat/invoke", async (req, res) => {
1558
+ const id = req.params.id;
1559
+ const agent = await svc.getById(id);
1560
+ if (!agent) {
1561
+ res.status(404).json({ error: "Agent not found" });
1562
+ return;
1563
+ }
1564
+ assertCompanyAccess(req, agent.companyId);
1565
+ if (req.actor.type === "agent" && req.actor.agentId !== id) {
1566
+ res.status(403).json({ error: "Agent can only invoke itself" });
1567
+ return;
1568
+ }
1569
+ const run = await heartbeat.invoke(id, "on_demand", {
1570
+ triggeredBy: req.actor.type,
1571
+ actorId: req.actor.type === "agent" ? req.actor.agentId : req.actor.userId,
1572
+ }, "manual", {
1573
+ actorType: req.actor.type === "agent" ? "agent" : "user",
1574
+ actorId: req.actor.type === "agent" ? req.actor.agentId ?? null : req.actor.userId ?? null,
1575
+ });
1576
+ if (!run) {
1577
+ res.status(202).json({ status: "skipped" });
1578
+ return;
1579
+ }
1580
+ const actor = getActorInfo(req);
1581
+ await logActivity(db, {
1582
+ companyId: agent.companyId,
1583
+ actorType: actor.actorType,
1584
+ actorId: actor.actorId,
1585
+ agentId: actor.agentId,
1586
+ runId: actor.runId,
1587
+ action: "heartbeat.invoked",
1588
+ entityType: "heartbeat_run",
1589
+ entityId: run.id,
1590
+ details: { agentId: id },
1591
+ });
1592
+ res.status(202).json(run);
1593
+ });
1594
+ router.post("/agents/:id/claude-login", async (req, res) => {
1595
+ assertBoard(req);
1596
+ const id = req.params.id;
1597
+ const agent = await svc.getById(id);
1598
+ if (!agent) {
1599
+ res.status(404).json({ error: "Agent not found" });
1600
+ return;
1601
+ }
1602
+ assertCompanyAccess(req, agent.companyId);
1603
+ if (agent.adapterType !== "claude_local") {
1604
+ res.status(400).json({ error: "Login is only supported for claude_local agents" });
1605
+ return;
1606
+ }
1607
+ const config = asRecord(agent.adapterConfig) ?? {};
1608
+ const { config: runtimeConfig } = await secretsSvc.resolveAdapterConfigForRuntime(agent.companyId, config);
1609
+ const result = await runClaudeLogin({
1610
+ runId: `claude-login-${randomUUID()}`,
1611
+ agent: {
1612
+ id: agent.id,
1613
+ companyId: agent.companyId,
1614
+ name: agent.name,
1615
+ adapterType: agent.adapterType,
1616
+ adapterConfig: agent.adapterConfig,
1617
+ },
1618
+ config: runtimeConfig,
1619
+ });
1620
+ res.json(result);
1621
+ });
1622
+ router.get("/companies/:companyId/heartbeat-runs", async (req, res) => {
1623
+ const companyId = req.params.companyId;
1624
+ assertCompanyAccess(req, companyId);
1625
+ const agentId = req.query.agentId;
1626
+ const limitParam = req.query.limit;
1627
+ const limit = limitParam ? Math.max(1, Math.min(1000, parseInt(limitParam, 10) || 200)) : undefined;
1628
+ const runs = await heartbeat.list(companyId, agentId, limit);
1629
+ res.json(runs);
1630
+ });
1631
+ router.get("/companies/:companyId/live-runs", async (req, res) => {
1632
+ const companyId = req.params.companyId;
1633
+ assertCompanyAccess(req, companyId);
1634
+ const minCountParam = req.query.minCount;
1635
+ const minCount = minCountParam ? Math.max(0, Math.min(20, parseInt(minCountParam, 10) || 0)) : 0;
1636
+ const columns = {
1637
+ id: heartbeatRuns.id,
1638
+ status: heartbeatRuns.status,
1639
+ invocationSource: heartbeatRuns.invocationSource,
1640
+ triggerDetail: heartbeatRuns.triggerDetail,
1641
+ startedAt: heartbeatRuns.startedAt,
1642
+ finishedAt: heartbeatRuns.finishedAt,
1643
+ createdAt: heartbeatRuns.createdAt,
1644
+ agentId: heartbeatRuns.agentId,
1645
+ agentName: agentsTable.name,
1646
+ adapterType: agentsTable.adapterType,
1647
+ issueId: sql `${heartbeatRuns.contextSnapshot} ->> 'issueId'`.as("issueId"),
1648
+ };
1649
+ const liveRuns = await db
1650
+ .select(columns)
1651
+ .from(heartbeatRuns)
1652
+ .innerJoin(agentsTable, eq(heartbeatRuns.agentId, agentsTable.id))
1653
+ .where(and(eq(heartbeatRuns.companyId, companyId), inArray(heartbeatRuns.status, ["queued", "running"])))
1654
+ .orderBy(desc(heartbeatRuns.createdAt));
1655
+ if (minCount > 0 && liveRuns.length < minCount) {
1656
+ const activeIds = liveRuns.map((r) => r.id);
1657
+ const recentRuns = await db
1658
+ .select(columns)
1659
+ .from(heartbeatRuns)
1660
+ .innerJoin(agentsTable, eq(heartbeatRuns.agentId, agentsTable.id))
1661
+ .where(and(eq(heartbeatRuns.companyId, companyId), not(inArray(heartbeatRuns.status, ["queued", "running"])), ...(activeIds.length > 0 ? [not(inArray(heartbeatRuns.id, activeIds))] : [])))
1662
+ .orderBy(desc(heartbeatRuns.createdAt))
1663
+ .limit(minCount - liveRuns.length);
1664
+ res.json([...liveRuns, ...recentRuns]);
1665
+ return;
1666
+ }
1667
+ res.json(liveRuns);
1668
+ });
1669
+ router.get("/heartbeat-runs/:runId", async (req, res) => {
1670
+ const runId = req.params.runId;
1671
+ const run = await heartbeat.getRun(runId);
1672
+ if (!run) {
1673
+ res.status(404).json({ error: "Heartbeat run not found" });
1674
+ return;
1675
+ }
1676
+ assertCompanyAccess(req, run.companyId);
1677
+ res.json(redactCurrentUserValue(run, await getCurrentUserRedactionOptions()));
1678
+ });
1679
+ router.post("/heartbeat-runs/:runId/cancel", async (req, res) => {
1680
+ assertBoard(req);
1681
+ const runId = req.params.runId;
1682
+ const run = await heartbeat.cancelRun(runId);
1683
+ if (run) {
1684
+ await logActivity(db, {
1685
+ companyId: run.companyId,
1686
+ actorType: "user",
1687
+ actorId: req.actor.userId ?? "board",
1688
+ action: "heartbeat.cancelled",
1689
+ entityType: "heartbeat_run",
1690
+ entityId: run.id,
1691
+ details: { agentId: run.agentId },
1692
+ });
1693
+ }
1694
+ res.json(run);
1695
+ });
1696
+ router.get("/heartbeat-runs/:runId/events", async (req, res) => {
1697
+ const runId = req.params.runId;
1698
+ const run = await heartbeat.getRun(runId);
1699
+ if (!run) {
1700
+ res.status(404).json({ error: "Heartbeat run not found" });
1701
+ return;
1702
+ }
1703
+ assertCompanyAccess(req, run.companyId);
1704
+ const afterSeq = Number(req.query.afterSeq ?? 0);
1705
+ const limit = Number(req.query.limit ?? 200);
1706
+ const events = await heartbeat.listEvents(runId, Number.isFinite(afterSeq) ? afterSeq : 0, Number.isFinite(limit) ? limit : 200);
1707
+ const currentUserRedactionOptions = await getCurrentUserRedactionOptions();
1708
+ const redactedEvents = events.map((event) => redactCurrentUserValue({
1709
+ ...event,
1710
+ payload: redactEventPayload(event.payload),
1711
+ }, currentUserRedactionOptions));
1712
+ res.json(redactedEvents);
1713
+ });
1714
+ router.get("/heartbeat-runs/:runId/log", async (req, res) => {
1715
+ const runId = req.params.runId;
1716
+ const run = await heartbeat.getRun(runId);
1717
+ if (!run) {
1718
+ res.status(404).json({ error: "Heartbeat run not found" });
1719
+ return;
1720
+ }
1721
+ assertCompanyAccess(req, run.companyId);
1722
+ const offset = Number(req.query.offset ?? 0);
1723
+ const limitBytes = Number(req.query.limitBytes ?? 256000);
1724
+ const result = await heartbeat.readLog(runId, {
1725
+ offset: Number.isFinite(offset) ? offset : 0,
1726
+ limitBytes: Number.isFinite(limitBytes) ? limitBytes : 256000,
1727
+ });
1728
+ res.json(result);
1729
+ });
1730
+ router.get("/heartbeat-runs/:runId/workspace-operations", async (req, res) => {
1731
+ const runId = req.params.runId;
1732
+ const run = await heartbeat.getRun(runId);
1733
+ if (!run) {
1734
+ res.status(404).json({ error: "Heartbeat run not found" });
1735
+ return;
1736
+ }
1737
+ assertCompanyAccess(req, run.companyId);
1738
+ const context = asRecord(run.contextSnapshot);
1739
+ const executionWorkspaceId = asNonEmptyString(context?.executionWorkspaceId);
1740
+ const operations = await workspaceOperations.listForRun(runId, executionWorkspaceId);
1741
+ res.json(redactCurrentUserValue(operations, await getCurrentUserRedactionOptions()));
1742
+ });
1743
+ router.get("/workspace-operations/:operationId/log", async (req, res) => {
1744
+ const operationId = req.params.operationId;
1745
+ const operation = await workspaceOperations.getById(operationId);
1746
+ if (!operation) {
1747
+ res.status(404).json({ error: "Workspace operation not found" });
1748
+ return;
1749
+ }
1750
+ assertCompanyAccess(req, operation.companyId);
1751
+ const offset = Number(req.query.offset ?? 0);
1752
+ const limitBytes = Number(req.query.limitBytes ?? 256000);
1753
+ const result = await workspaceOperations.readLog(operationId, {
1754
+ offset: Number.isFinite(offset) ? offset : 0,
1755
+ limitBytes: Number.isFinite(limitBytes) ? limitBytes : 256000,
1756
+ });
1757
+ res.json(result);
1758
+ });
1759
+ router.get("/issues/:issueId/live-runs", async (req, res) => {
1760
+ const rawId = req.params.issueId;
1761
+ const issueSvc = issueService(db);
1762
+ const isIdentifier = /^[A-Z]+-\d+$/i.test(rawId);
1763
+ const issue = isIdentifier ? await issueSvc.getByIdentifier(rawId) : await issueSvc.getById(rawId);
1764
+ if (!issue) {
1765
+ res.status(404).json({ error: "Issue not found" });
1766
+ return;
1767
+ }
1768
+ assertCompanyAccess(req, issue.companyId);
1769
+ const liveRuns = await db
1770
+ .select({
1771
+ id: heartbeatRuns.id,
1772
+ status: heartbeatRuns.status,
1773
+ invocationSource: heartbeatRuns.invocationSource,
1774
+ triggerDetail: heartbeatRuns.triggerDetail,
1775
+ startedAt: heartbeatRuns.startedAt,
1776
+ finishedAt: heartbeatRuns.finishedAt,
1777
+ createdAt: heartbeatRuns.createdAt,
1778
+ agentId: heartbeatRuns.agentId,
1779
+ agentName: agentsTable.name,
1780
+ adapterType: agentsTable.adapterType,
1781
+ })
1782
+ .from(heartbeatRuns)
1783
+ .innerJoin(agentsTable, eq(heartbeatRuns.agentId, agentsTable.id))
1784
+ .where(and(eq(heartbeatRuns.companyId, issue.companyId), inArray(heartbeatRuns.status, ["queued", "running"]), sql `${heartbeatRuns.contextSnapshot} ->> 'issueId' = ${issue.id}`))
1785
+ .orderBy(desc(heartbeatRuns.createdAt));
1786
+ res.json(liveRuns);
1787
+ });
1788
+ router.get("/issues/:issueId/active-run", async (req, res) => {
1789
+ const rawId = req.params.issueId;
1790
+ const issueSvc = issueService(db);
1791
+ const isIdentifier = /^[A-Z]+-\d+$/i.test(rawId);
1792
+ const issue = isIdentifier ? await issueSvc.getByIdentifier(rawId) : await issueSvc.getById(rawId);
1793
+ if (!issue) {
1794
+ res.status(404).json({ error: "Issue not found" });
1795
+ return;
1796
+ }
1797
+ assertCompanyAccess(req, issue.companyId);
1798
+ let run = issue.executionRunId ? await heartbeat.getRun(issue.executionRunId) : null;
1799
+ if (run && run.status !== "queued" && run.status !== "running") {
1800
+ run = null;
1801
+ }
1802
+ if (!run && issue.assigneeAgentId && issue.status === "in_progress") {
1803
+ const candidateRun = await heartbeat.getActiveRunForAgent(issue.assigneeAgentId);
1804
+ const candidateContext = asRecord(candidateRun?.contextSnapshot);
1805
+ const candidateIssueId = asNonEmptyString(candidateContext?.issueId);
1806
+ if (candidateRun && candidateIssueId === issue.id) {
1807
+ run = candidateRun;
1808
+ }
1809
+ }
1810
+ if (!run) {
1811
+ res.json(null);
1812
+ return;
1813
+ }
1814
+ const agent = await svc.getById(run.agentId);
1815
+ if (!agent) {
1816
+ res.json(null);
1817
+ return;
1818
+ }
1819
+ res.json({
1820
+ ...redactCurrentUserValue(run, await getCurrentUserRedactionOptions()),
1821
+ agentId: agent.id,
1822
+ agentName: agent.name,
1823
+ adapterType: agent.adapterType,
1824
+ });
1825
+ });
1826
+ return router;
1827
+ }
1828
+ //# sourceMappingURL=agents.js.map