@penclipai/server 2026.704.0 → 2026.714.0-canary.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (485) hide show
  1. package/dist/adapters/index.d.ts +1 -1
  2. package/dist/adapters/index.d.ts.map +1 -1
  3. package/dist/adapters/index.js.map +1 -1
  4. package/dist/adapters/process/execute.d.ts.map +1 -1
  5. package/dist/adapters/process/execute.js +1 -0
  6. package/dist/adapters/process/execute.js.map +1 -1
  7. package/dist/adapters/registry.d.ts.map +1 -1
  8. package/dist/adapters/registry.js +79 -51
  9. package/dist/adapters/registry.js.map +1 -1
  10. package/dist/adapters/utils.d.ts +5 -0
  11. package/dist/adapters/utils.d.ts.map +1 -1
  12. package/dist/adapters/utils.js.map +1 -1
  13. package/dist/agent-auth-jwt.d.ts +5 -1
  14. package/dist/agent-auth-jwt.d.ts.map +1 -1
  15. package/dist/agent-auth-jwt.js +72 -20
  16. package/dist/agent-auth-jwt.js.map +1 -1
  17. package/dist/app.d.ts +2 -0
  18. package/dist/app.d.ts.map +1 -1
  19. package/dist/app.js +10 -0
  20. package/dist/app.js.map +1 -1
  21. package/dist/built-ins/agents/reflection-coach/AGENTS.md +47 -0
  22. package/dist/built-ins/agents/reflection-coach/routines/recent-agent-reflection.md +77 -0
  23. package/dist/errors.d.ts +1 -1
  24. package/dist/errors.d.ts.map +1 -1
  25. package/dist/errors.js +2 -2
  26. package/dist/errors.js.map +1 -1
  27. package/dist/index.d.ts.map +1 -1
  28. package/dist/index.js +208 -116
  29. package/dist/index.js.map +1 -1
  30. package/dist/middleware/api-compression.d.ts +8 -0
  31. package/dist/middleware/api-compression.d.ts.map +1 -0
  32. package/dist/middleware/api-compression.js +207 -0
  33. package/dist/middleware/api-compression.js.map +1 -0
  34. package/dist/middleware/auth.d.ts.map +1 -1
  35. package/dist/middleware/auth.js +130 -3
  36. package/dist/middleware/auth.js.map +1 -1
  37. package/dist/middleware/error-handler.d.ts.map +1 -1
  38. package/dist/middleware/error-handler.js +27 -0
  39. package/dist/middleware/error-handler.js.map +1 -1
  40. package/dist/onboarding-assets/default/AGENTS.md +1 -0
  41. package/dist/redaction.d.ts.map +1 -1
  42. package/dist/redaction.js +11 -0
  43. package/dist/redaction.js.map +1 -1
  44. package/dist/routes/access.d.ts.map +1 -1
  45. package/dist/routes/access.js +4 -3
  46. package/dist/routes/access.js.map +1 -1
  47. package/dist/routes/adapters.d.ts.map +1 -1
  48. package/dist/routes/adapters.js +2 -0
  49. package/dist/routes/adapters.js.map +1 -1
  50. package/dist/routes/agents.d.ts.map +1 -1
  51. package/dist/routes/agents.js +222 -87
  52. package/dist/routes/agents.js.map +1 -1
  53. package/dist/routes/attention.d.ts +3 -0
  54. package/dist/routes/attention.d.ts.map +1 -0
  55. package/dist/routes/attention.js +24 -0
  56. package/dist/routes/attention.js.map +1 -0
  57. package/dist/routes/authz.d.ts.map +1 -1
  58. package/dist/routes/authz.js +29 -1
  59. package/dist/routes/authz.js.map +1 -1
  60. package/dist/routes/board-chat.d.ts.map +1 -1
  61. package/dist/routes/board-chat.js +4 -1
  62. package/dist/routes/board-chat.js.map +1 -1
  63. package/dist/routes/built-in-agents.d.ts +3 -0
  64. package/dist/routes/built-in-agents.d.ts.map +1 -0
  65. package/dist/routes/built-in-agents.js +267 -0
  66. package/dist/routes/built-in-agents.js.map +1 -0
  67. package/dist/routes/cases.d.ts +46 -0
  68. package/dist/routes/cases.d.ts.map +1 -0
  69. package/dist/routes/cases.js +1395 -0
  70. package/dist/routes/cases.js.map +1 -0
  71. package/dist/routes/companies.d.ts.map +1 -1
  72. package/dist/routes/companies.js +4 -1
  73. package/dist/routes/companies.js.map +1 -1
  74. package/dist/routes/company-skills.d.ts.map +1 -1
  75. package/dist/routes/company-skills.js +453 -33
  76. package/dist/routes/company-skills.js.map +1 -1
  77. package/dist/routes/environments.d.ts.map +1 -1
  78. package/dist/routes/environments.js +71 -8
  79. package/dist/routes/environments.js.map +1 -1
  80. package/dist/routes/execution-workspaces.d.ts.map +1 -1
  81. package/dist/routes/execution-workspaces.js +89 -3
  82. package/dist/routes/execution-workspaces.js.map +1 -1
  83. package/dist/routes/health.d.ts +2 -0
  84. package/dist/routes/health.d.ts.map +1 -1
  85. package/dist/routes/health.js +30 -0
  86. package/dist/routes/health.js.map +1 -1
  87. package/dist/routes/inbox-dismissals.d.ts.map +1 -1
  88. package/dist/routes/inbox-dismissals.js +80 -19
  89. package/dist/routes/inbox-dismissals.js.map +1 -1
  90. package/dist/routes/index.d.ts +2 -0
  91. package/dist/routes/index.d.ts.map +1 -1
  92. package/dist/routes/index.js +2 -0
  93. package/dist/routes/index.js.map +1 -1
  94. package/dist/routes/issues.d.ts +25 -0
  95. package/dist/routes/issues.d.ts.map +1 -1
  96. package/dist/routes/issues.js +1455 -46
  97. package/dist/routes/issues.js.map +1 -1
  98. package/dist/routes/openapi.d.ts.map +1 -1
  99. package/dist/routes/openapi.js +448 -11
  100. package/dist/routes/openapi.js.map +1 -1
  101. package/dist/routes/pipelines.js +2 -2
  102. package/dist/routes/pipelines.js.map +1 -1
  103. package/dist/routes/resource-memberships.d.ts.map +1 -1
  104. package/dist/routes/resource-memberships.js +13 -5
  105. package/dist/routes/resource-memberships.js.map +1 -1
  106. package/dist/routes/secrets.d.ts.map +1 -1
  107. package/dist/routes/secrets.js +261 -1
  108. package/dist/routes/secrets.js.map +1 -1
  109. package/dist/routes/sidebar-badges.d.ts.map +1 -1
  110. package/dist/routes/sidebar-badges.js +18 -2
  111. package/dist/routes/sidebar-badges.js.map +1 -1
  112. package/dist/routes/user-profiles.d.ts.map +1 -1
  113. package/dist/routes/user-profiles.js +5 -4
  114. package/dist/routes/user-profiles.js.map +1 -1
  115. package/dist/server-info.d.ts +2 -0
  116. package/dist/server-info.d.ts.map +1 -1
  117. package/dist/server-info.js +20 -5
  118. package/dist/server-info.js.map +1 -1
  119. package/dist/services/access.d.ts +4 -4
  120. package/dist/services/access.d.ts.map +1 -1
  121. package/dist/services/activity.d.ts +3 -3
  122. package/dist/services/activity.d.ts.map +1 -1
  123. package/dist/services/activity.js +5 -4
  124. package/dist/services/activity.js.map +1 -1
  125. package/dist/services/adapter-registry-bootstrap.reconcile.test.js +1 -0
  126. package/dist/services/adapter-registry-bootstrap.reconcile.test.js.map +1 -1
  127. package/dist/services/agent-secret-bindings.d.ts +15 -0
  128. package/dist/services/agent-secret-bindings.d.ts.map +1 -1
  129. package/dist/services/agent-secret-bindings.js +43 -0
  130. package/dist/services/agent-secret-bindings.js.map +1 -1
  131. package/dist/services/agents.d.ts +194 -133
  132. package/dist/services/agents.d.ts.map +1 -1
  133. package/dist/services/agents.js +107 -4
  134. package/dist/services/agents.js.map +1 -1
  135. package/dist/services/approvals.d.ts +10 -10
  136. package/dist/services/approvals.d.ts.map +1 -1
  137. package/dist/services/approvals.js +9 -1
  138. package/dist/services/approvals.js.map +1 -1
  139. package/dist/services/assets.d.ts +5 -5
  140. package/dist/services/attention.d.ts +11 -0
  141. package/dist/services/attention.d.ts.map +1 -0
  142. package/dist/services/attention.js +1024 -0
  143. package/dist/services/attention.js.map +1 -0
  144. package/dist/services/authorization.d.ts +15 -2
  145. package/dist/services/authorization.d.ts.map +1 -1
  146. package/dist/services/authorization.js +324 -8
  147. package/dist/services/authorization.js.map +1 -1
  148. package/dist/services/board-auth.d.ts +2 -2
  149. package/dist/services/budgets.d.ts.map +1 -1
  150. package/dist/services/budgets.js +8 -7
  151. package/dist/services/budgets.js.map +1 -1
  152. package/dist/services/built-in-agent-metadata.d.ts +9 -0
  153. package/dist/services/built-in-agent-metadata.d.ts.map +1 -0
  154. package/dist/services/built-in-agent-metadata.js +39 -0
  155. package/dist/services/built-in-agent-metadata.js.map +1 -0
  156. package/dist/services/built-in-agents.d.ts +394 -0
  157. package/dist/services/built-in-agents.d.ts.map +1 -0
  158. package/dist/services/built-in-agents.js +1426 -0
  159. package/dist/services/built-in-agents.js.map +1 -0
  160. package/dist/services/change-consent-gate.d.ts +18 -0
  161. package/dist/services/change-consent-gate.d.ts.map +1 -0
  162. package/dist/services/change-consent-gate.js +170 -0
  163. package/dist/services/change-consent-gate.js.map +1 -0
  164. package/dist/services/companies.d.ts +14 -8
  165. package/dist/services/companies.d.ts.map +1 -1
  166. package/dist/services/companies.js +6 -1
  167. package/dist/services/companies.js.map +1 -1
  168. package/dist/services/company-artifacts.d.ts +4 -1
  169. package/dist/services/company-artifacts.d.ts.map +1 -1
  170. package/dist/services/company-artifacts.js +9 -1
  171. package/dist/services/company-artifacts.js.map +1 -1
  172. package/dist/services/company-member-roles.d.ts.map +1 -1
  173. package/dist/services/company-member-roles.js +2 -0
  174. package/dist/services/company-member-roles.js.map +1 -1
  175. package/dist/services/company-portability.d.ts +1 -1
  176. package/dist/services/company-portability.d.ts.map +1 -1
  177. package/dist/services/company-portability.js +113 -8
  178. package/dist/services/company-portability.js.map +1 -1
  179. package/dist/services/company-search.d.ts.map +1 -1
  180. package/dist/services/company-search.js +843 -294
  181. package/dist/services/company-search.js.map +1 -1
  182. package/dist/services/company-skills.d.ts +64 -3
  183. package/dist/services/company-skills.d.ts.map +1 -1
  184. package/dist/services/company-skills.js +1205 -20
  185. package/dist/services/company-skills.js.map +1 -1
  186. package/dist/services/costs.d.ts +9 -8
  187. package/dist/services/costs.d.ts.map +1 -1
  188. package/dist/services/costs.js +9 -2
  189. package/dist/services/costs.js.map +1 -1
  190. package/dist/services/dashboard.d.ts +2 -0
  191. package/dist/services/dashboard.d.ts.map +1 -1
  192. package/dist/services/dashboard.js +60 -17
  193. package/dist/services/dashboard.js.map +1 -1
  194. package/dist/services/database-backup-health.d.ts +34 -0
  195. package/dist/services/database-backup-health.d.ts.map +1 -0
  196. package/dist/services/database-backup-health.js +104 -0
  197. package/dist/services/database-backup-health.js.map +1 -0
  198. package/dist/services/document-annotations.d.ts +169 -1
  199. package/dist/services/document-annotations.d.ts.map +1 -1
  200. package/dist/services/document-annotations.js +272 -1
  201. package/dist/services/document-annotations.js.map +1 -1
  202. package/dist/services/documents.d.ts +368 -0
  203. package/dist/services/documents.d.ts.map +1 -1
  204. package/dist/services/documents.js +2 -2
  205. package/dist/services/documents.js.map +1 -1
  206. package/dist/services/environment-config.d.ts.map +1 -1
  207. package/dist/services/environment-config.js +6 -0
  208. package/dist/services/environment-config.js.map +1 -1
  209. package/dist/services/environment-custom-image-runtime.d.ts +28 -0
  210. package/dist/services/environment-custom-image-runtime.d.ts.map +1 -1
  211. package/dist/services/environment-custom-image-runtime.js +106 -7
  212. package/dist/services/environment-custom-image-runtime.js.map +1 -1
  213. package/dist/services/environment-custom-images.d.ts +31 -1
  214. package/dist/services/environment-custom-images.d.ts.map +1 -1
  215. package/dist/services/environment-custom-images.js +110 -4
  216. package/dist/services/environment-custom-images.js.map +1 -1
  217. package/dist/services/environment-execution-target.d.ts.map +1 -1
  218. package/dist/services/environment-execution-target.js +1 -3
  219. package/dist/services/environment-execution-target.js.map +1 -1
  220. package/dist/services/environment-probe.d.ts +1 -0
  221. package/dist/services/environment-probe.d.ts.map +1 -1
  222. package/dist/services/environment-probe.js +99 -5
  223. package/dist/services/environment-probe.js.map +1 -1
  224. package/dist/services/environments.d.ts +3 -1
  225. package/dist/services/environments.d.ts.map +1 -1
  226. package/dist/services/environments.js +98 -3
  227. package/dist/services/environments.js.map +1 -1
  228. package/dist/services/execution-workspace-policy.d.ts +29 -3
  229. package/dist/services/execution-workspace-policy.d.ts.map +1 -1
  230. package/dist/services/execution-workspace-policy.js +44 -1
  231. package/dist/services/execution-workspace-policy.js.map +1 -1
  232. package/dist/services/execution-workspaces.d.ts +64 -1
  233. package/dist/services/execution-workspaces.d.ts.map +1 -1
  234. package/dist/services/execution-workspaces.js +634 -3
  235. package/dist/services/execution-workspaces.js.map +1 -1
  236. package/dist/services/external-objects.d.ts +26 -26
  237. package/dist/services/feedback.d.ts +2 -2
  238. package/dist/services/finance.d.ts +5 -5
  239. package/dist/services/goals.d.ts +8 -8
  240. package/dist/services/heartbeat-stop-metadata.d.ts +2 -2
  241. package/dist/services/heartbeat-stop-metadata.d.ts.map +1 -1
  242. package/dist/services/heartbeat-stop-metadata.js +4 -0
  243. package/dist/services/heartbeat-stop-metadata.js.map +1 -1
  244. package/dist/services/heartbeat-stop-metadata.test.js +9 -0
  245. package/dist/services/heartbeat-stop-metadata.test.js.map +1 -1
  246. package/dist/services/heartbeat.d.ts +133 -28
  247. package/dist/services/heartbeat.d.ts.map +1 -1
  248. package/dist/services/heartbeat.js +1963 -239
  249. package/dist/services/heartbeat.js.map +1 -1
  250. package/dist/services/inbox-dismissals.d.ts +26 -0
  251. package/dist/services/inbox-dismissals.d.ts.map +1 -1
  252. package/dist/services/inbox-dismissals.js +33 -18
  253. package/dist/services/inbox-dismissals.js.map +1 -1
  254. package/dist/services/index.d.ts +3 -1
  255. package/dist/services/index.d.ts.map +1 -1
  256. package/dist/services/index.js +3 -1
  257. package/dist/services/index.js.map +1 -1
  258. package/dist/services/instance-settings.d.ts +25 -1
  259. package/dist/services/instance-settings.d.ts.map +1 -1
  260. package/dist/services/instance-settings.js +103 -5
  261. package/dist/services/instance-settings.js.map +1 -1
  262. package/dist/services/issue-continuation-summary.js +1 -1
  263. package/dist/services/issue-continuation-summary.js.map +1 -1
  264. package/dist/services/issue-recovery-actions.d.ts +3 -0
  265. package/dist/services/issue-recovery-actions.d.ts.map +1 -1
  266. package/dist/services/issue-recovery-actions.js +9 -0
  267. package/dist/services/issue-recovery-actions.js.map +1 -1
  268. package/dist/services/issue-rewake-throttle.d.ts +92 -0
  269. package/dist/services/issue-rewake-throttle.d.ts.map +1 -0
  270. package/dist/services/issue-rewake-throttle.js +139 -0
  271. package/dist/services/issue-rewake-throttle.js.map +1 -0
  272. package/dist/services/issue-thread-interactions.d.ts +8 -1
  273. package/dist/services/issue-thread-interactions.d.ts.map +1 -1
  274. package/dist/services/issue-thread-interactions.js +231 -16
  275. package/dist/services/issue-thread-interactions.js.map +1 -1
  276. package/dist/services/issue-visibility.d.ts +4 -0
  277. package/dist/services/issue-visibility.d.ts.map +1 -0
  278. package/dist/services/issue-visibility.js +9 -0
  279. package/dist/services/issue-visibility.js.map +1 -0
  280. package/dist/services/issues.d.ts +225 -105
  281. package/dist/services/issues.d.ts.map +1 -1
  282. package/dist/services/issues.js +540 -18
  283. package/dist/services/issues.js.map +1 -1
  284. package/dist/services/local-service-supervisor.d.ts +3 -0
  285. package/dist/services/local-service-supervisor.d.ts.map +1 -1
  286. package/dist/services/local-service-supervisor.js +51 -0
  287. package/dist/services/local-service-supervisor.js.map +1 -1
  288. package/dist/services/pipeline-case-outputs.d.ts.map +1 -1
  289. package/dist/services/pipeline-case-outputs.js +2 -1
  290. package/dist/services/pipeline-case-outputs.js.map +1 -1
  291. package/dist/services/pipelines-aggregation.d.ts.map +1 -1
  292. package/dist/services/pipelines-aggregation.js +3 -2
  293. package/dist/services/pipelines-aggregation.js.map +1 -1
  294. package/dist/services/pipelines.d.ts +165 -165
  295. package/dist/services/pipelines.d.ts.map +1 -1
  296. package/dist/services/pipelines.js +6 -4
  297. package/dist/services/pipelines.js.map +1 -1
  298. package/dist/services/plugin-database.d.ts +2 -2
  299. package/dist/services/plugin-environment-driver.d.ts +1 -1
  300. package/dist/services/plugin-host-services.d.ts.map +1 -1
  301. package/dist/services/plugin-host-services.js +3 -1
  302. package/dist/services/plugin-host-services.js.map +1 -1
  303. package/dist/services/plugin-managed-routines.d.ts +1 -0
  304. package/dist/services/plugin-managed-routines.d.ts.map +1 -1
  305. package/dist/services/plugin-registry.d.ts +21 -21
  306. package/dist/services/productivity-review.d.ts +1 -0
  307. package/dist/services/productivity-review.d.ts.map +1 -1
  308. package/dist/services/productivity-review.js +6 -5
  309. package/dist/services/productivity-review.js.map +1 -1
  310. package/dist/services/projects.d.ts +9 -9
  311. package/dist/services/recovery/service.d.ts +82 -54
  312. package/dist/services/recovery/service.d.ts.map +1 -1
  313. package/dist/services/recovery/service.js +200 -35
  314. package/dist/services/recovery/service.js.map +1 -1
  315. package/dist/services/recovery/successful-run-handoff.d.ts +1 -0
  316. package/dist/services/recovery/successful-run-handoff.d.ts.map +1 -1
  317. package/dist/services/recovery/successful-run-handoff.js +2 -0
  318. package/dist/services/recovery/successful-run-handoff.js.map +1 -1
  319. package/dist/services/recovery/successful-run-handoff.test.js +20 -0
  320. package/dist/services/recovery/successful-run-handoff.test.js.map +1 -1
  321. package/dist/services/resource-memberships.d.ts +13 -10
  322. package/dist/services/resource-memberships.d.ts.map +1 -1
  323. package/dist/services/resource-memberships.js +89 -20
  324. package/dist/services/resource-memberships.js.map +1 -1
  325. package/dist/services/responsible-user-denial-run-outcomes.d.ts +60 -0
  326. package/dist/services/responsible-user-denial-run-outcomes.d.ts.map +1 -0
  327. package/dist/services/responsible-user-denial-run-outcomes.js +56 -0
  328. package/dist/services/responsible-user-denial-run-outcomes.js.map +1 -0
  329. package/dist/services/responsible-user-denial-run-outcomes.test.d.ts +2 -0
  330. package/dist/services/responsible-user-denial-run-outcomes.test.d.ts.map +1 -0
  331. package/dist/services/responsible-user-denial-run-outcomes.test.js +75 -0
  332. package/dist/services/responsible-user-denial-run-outcomes.test.js.map +1 -0
  333. package/dist/services/routines.d.ts +30 -8
  334. package/dist/services/routines.d.ts.map +1 -1
  335. package/dist/services/routines.js +241 -18
  336. package/dist/services/routines.js.map +1 -1
  337. package/dist/services/run-liveness.d.ts.map +1 -1
  338. package/dist/services/run-liveness.js +21 -0
  339. package/dist/services/run-liveness.js.map +1 -1
  340. package/dist/services/run-log-store.d.ts +1 -0
  341. package/dist/services/run-log-store.d.ts.map +1 -1
  342. package/dist/services/run-log-store.js +4 -0
  343. package/dist/services/run-log-store.js.map +1 -1
  344. package/dist/services/run-scratch.d.ts +42 -0
  345. package/dist/services/run-scratch.d.ts.map +1 -0
  346. package/dist/services/run-scratch.js +111 -0
  347. package/dist/services/run-scratch.js.map +1 -0
  348. package/dist/services/run-scratch.test.d.ts +2 -0
  349. package/dist/services/run-scratch.test.d.ts.map +1 -0
  350. package/dist/services/run-scratch.test.js +98 -0
  351. package/dist/services/run-scratch.test.js.map +1 -0
  352. package/dist/services/secrets.d.ts +1261 -64
  353. package/dist/services/secrets.d.ts.map +1 -1
  354. package/dist/services/secrets.js +1089 -96
  355. package/dist/services/secrets.js.map +1 -1
  356. package/dist/services/task-watchdogs.d.ts +1 -0
  357. package/dist/services/task-watchdogs.d.ts.map +1 -1
  358. package/dist/services/task-watchdogs.js +78 -9
  359. package/dist/services/task-watchdogs.js.map +1 -1
  360. package/dist/services/work-timeline.d.ts.map +1 -1
  361. package/dist/services/work-timeline.js +34 -2
  362. package/dist/services/work-timeline.js.map +1 -1
  363. package/dist/services/workspace-runtime-read-model.d.ts +30 -29
  364. package/dist/services/workspace-runtime-read-model.d.ts.map +1 -1
  365. package/dist/services/workspace-runtime-read-model.js.map +1 -1
  366. package/dist/services/workspace-runtime.d.ts +59 -13
  367. package/dist/services/workspace-runtime.d.ts.map +1 -1
  368. package/dist/services/workspace-runtime.js +1121 -102
  369. package/dist/services/workspace-runtime.js.map +1 -1
  370. package/dist/skills-catalog/catalog/bundled/paperclip-operations/reflection-coach/SKILL.md +202 -0
  371. package/dist/skills-catalog/catalog/bundled/product/paperclip-capsules/SKILL.md +1 -1
  372. package/dist/skills-catalog/catalog/bundled/product/wireframe/SKILL.md +1 -1
  373. package/dist/skills-catalog/catalog/optional/content/release-announcement/SKILL.md +90 -0
  374. package/dist/skills-catalog/catalog/optional/finance/ramp/SKILL.md +98 -0
  375. package/dist/skills-catalog/generated/catalog.json +84 -12
  376. package/dist/ui-branding.d.ts +7 -0
  377. package/dist/ui-branding.d.ts.map +1 -1
  378. package/dist/ui-branding.js +8 -2
  379. package/dist/ui-branding.js.map +1 -1
  380. package/dist/version.d.ts +14 -0
  381. package/dist/version.d.ts.map +1 -1
  382. package/dist/version.js +114 -3
  383. package/dist/version.js.map +1 -1
  384. package/package.json +19 -20
  385. package/skills/paperclip/SKILL.md +45 -10
  386. package/skills/paperclip/references/api-reference.md +246 -1
  387. package/skills/paperclip/references/cases.md +295 -0
  388. package/skills/paperclip/references/company-skills.md +1 -1
  389. package/skills/paperclip-board/SKILL.md +3 -4
  390. package/skills/paperclip-converting-plans-to-tasks/SKILL.md +3 -7
  391. package/skills/para-memory-files/SKILL.md +3 -7
  392. package/ui-dist/assets/{abnfDiagram-VRR7QNED-BsFz2IiG.js → abnfDiagram-VRR7QNED-Cy91Tlk9.js} +1 -1
  393. package/ui-dist/assets/{arc-HZhAwbOs.js → arc-BBAQu311.js} +1 -1
  394. package/ui-dist/assets/{architectureDiagram-ZJ3FMSHR-BteMjuOn.js → architectureDiagram-ZJ3FMSHR-BrTSDi88.js} +1 -1
  395. package/ui-dist/assets/{blockDiagram-677ZJIJ3-Iq66uZjf.js → blockDiagram-677ZJIJ3-e5uziFO5.js} +1 -1
  396. package/ui-dist/assets/{browser-ponyfill-BBsuyZJt.js → browser-ponyfill-D8l5pq-s.js} +1 -1
  397. package/ui-dist/assets/{c4Diagram-LMCZKHZV-_nlglj7I.js → c4Diagram-LMCZKHZV-DQjqZvNw.js} +1 -1
  398. package/ui-dist/assets/channel-FQ5LRr4r.js +1 -0
  399. package/ui-dist/assets/{chunk-2Q5K7J3B-Cvz7WwSQ.js → chunk-2Q5K7J3B-ff7RVJIE.js} +1 -1
  400. package/ui-dist/assets/{chunk-32BRIVSS-LLubniCS.js → chunk-32BRIVSS-DUJjWWOm.js} +1 -1
  401. package/ui-dist/assets/{chunk-5VM5RSS4-BOst5hcr.js → chunk-5VM5RSS4-0Yi4VBgb.js} +1 -1
  402. package/ui-dist/assets/{chunk-EX3LRPZG-D5WNShVm.js → chunk-EX3LRPZG-NKvQ4wVr.js} +1 -1
  403. package/ui-dist/assets/{chunk-JWPE2WC7-CA07x4av.js → chunk-JWPE2WC7-C9fJ6g-i.js} +1 -1
  404. package/ui-dist/assets/{chunk-MOJQB5TN-Clfi83rK.js → chunk-MOJQB5TN-DEFFsbL_.js} +1 -1
  405. package/ui-dist/assets/{chunk-RYQCIY6F-BhZ6p7YJ.js → chunk-RYQCIY6F-B3v41_7G.js} +1 -1
  406. package/ui-dist/assets/{chunk-V7JOEXUC-CdexJGoV.js → chunk-V7JOEXUC-DVUU3xAk.js} +1 -1
  407. package/ui-dist/assets/{chunk-VR4S4FIN-8vjmBhr1.js → chunk-VR4S4FIN-bemyw0k2.js} +1 -1
  408. package/ui-dist/assets/{chunk-XXDRQBXY-CqmCaplj.js → chunk-XXDRQBXY-CWvhgyeb.js} +1 -1
  409. package/ui-dist/assets/classDiagram-OUVF2IWQ-QaL1os8Q.js +1 -0
  410. package/ui-dist/assets/classDiagram-v2-EOCWNBFH-QaL1os8Q.js +1 -0
  411. package/ui-dist/assets/{cose-bilkent-JH36ORCC-CY-zAygY.js → cose-bilkent-JH36ORCC-E-2cLOc1.js} +1 -1
  412. package/ui-dist/assets/{cynefin-VYW2F7L2-BQSQ1HKr.js → cynefin-VYW2F7L2-CxotRukv.js} +1 -1
  413. package/ui-dist/assets/{cynefinDiagram-TSTJHNR4-NJCuFrZL.js → cynefinDiagram-TSTJHNR4-AGQOPMl5.js} +1 -1
  414. package/ui-dist/assets/{dagre-VKFMJZFB-DAUPIc8g.js → dagre-VKFMJZFB-BxLGfVbk.js} +1 -1
  415. package/ui-dist/assets/{diagram-FQU43EPY-DvMwJlCi.js → diagram-FQU43EPY-DWXO_O6m.js} +1 -1
  416. package/ui-dist/assets/{diagram-G47NLZAW-DPY0Jz_y.js → diagram-G47NLZAW-C3WsiNNv.js} +1 -1
  417. package/ui-dist/assets/{diagram-NH7WQ7WH-BpopeEhp.js → diagram-NH7WQ7WH-CbLSRXTf.js} +1 -1
  418. package/ui-dist/assets/{diagram-OA4YK3LP-Qpu05z9X.js → diagram-OA4YK3LP-hwvxJr04.js} +1 -1
  419. package/ui-dist/assets/{diagram-WEI45ONY-DHnvw9XU.js → diagram-WEI45ONY-xwXsnT5Q.js} +1 -1
  420. package/ui-dist/assets/{ebnfDiagram-CCIWWBDH-D61S54_7.js → ebnfDiagram-CCIWWBDH-G311pLCP.js} +1 -1
  421. package/ui-dist/assets/{erDiagram-Q63AITRT-pplAN_x2.js → erDiagram-Q63AITRT-BnnuR_2P.js} +1 -1
  422. package/ui-dist/assets/{flowDiagram-23GEKE2U-BaBcbyDq.js → flowDiagram-23GEKE2U-CSHgefz-.js} +1 -1
  423. package/ui-dist/assets/{ganttDiagram-NO4QXBWP-BOJSII2b.js → ganttDiagram-NO4QXBWP-CERr9vTh.js} +1 -1
  424. package/ui-dist/assets/{gitGraphDiagram-IHSO6WYX-aYAaO4a2.js → gitGraphDiagram-IHSO6WYX-DHFHVLdn.js} +1 -1
  425. package/ui-dist/assets/{index-TmpY6Xh_.js → index-B-quLPan.js} +1 -1
  426. package/ui-dist/assets/{index-LHkZdu0h.js → index-B6QznFjN.js} +1 -1
  427. package/ui-dist/assets/{index-3EKATXgc.js → index-B7BUwUuV.js} +1 -1
  428. package/ui-dist/assets/{index-CvPPuNs1.js → index-BDiZss3L.js} +1 -1
  429. package/ui-dist/assets/{index-BaiskB3o.js → index-BHdxZ8mW.js} +1 -1
  430. package/ui-dist/assets/{index-CZxYajxF.js → index-BP3GWFFq.js} +1 -1
  431. package/ui-dist/assets/{index-B5YenxAQ.js → index-BPjK1nba.js} +1 -1
  432. package/ui-dist/assets/{index-BKVeJ3Jh.js → index-BUGIBR28.js} +1 -1
  433. package/ui-dist/assets/{index-BRgdHUNR.js → index-BVe5Mpsj.js} +1 -1
  434. package/ui-dist/assets/{index-Dceamza_.js → index-B_vsK1nr.js} +1 -1
  435. package/ui-dist/assets/{index-DrL6pHSJ.js → index-BbtsvYoS.js} +1 -1
  436. package/ui-dist/assets/{index-CemenVOf.js → index-CCptD5rH.js} +1 -1
  437. package/ui-dist/assets/{index-C-nKjFZh.js → index-CPd0SXS5.js} +1 -1
  438. package/ui-dist/assets/index-C_R8L9b5.js +676 -0
  439. package/ui-dist/assets/{index-B8H0SHw1.js → index-CuR0ldHA.js} +1 -1
  440. package/ui-dist/assets/{index-CKKytnOd.js → index-CvKZQ7p2.js} +1 -1
  441. package/ui-dist/assets/index-CyuYtn7U.css +1 -0
  442. package/ui-dist/assets/{index-D3ODiUup.js → index-DSwKPLnt.js} +1 -1
  443. package/ui-dist/assets/{index-CJlw4l9L.js → index-Daq0pXqe.js} +1 -1
  444. package/ui-dist/assets/{index-bUFCSEgv.js → index-DmsO--MD.js} +1 -1
  445. package/ui-dist/assets/{index-Da2kqT1M.js → index-DozP52ue.js} +1 -1
  446. package/ui-dist/assets/{index-C2JgdjPa.js → index-DxjbpC1V.js} +1 -1
  447. package/ui-dist/assets/{index-By0oeEvz.js → index-H1y6lR4h.js} +1 -1
  448. package/ui-dist/assets/{index-BT8b79Bd.js → index-ICaKahDe.js} +1 -1
  449. package/ui-dist/assets/{index-CjDqB1SX.js → index-q2ZXRiiu.js} +1 -1
  450. package/ui-dist/assets/{infoDiagram-FWYZ7A6U-C7_90qGq.js → infoDiagram-FWYZ7A6U-BX-kzcCv.js} +1 -1
  451. package/ui-dist/assets/{ishikawaDiagram-FXEZZL3T-T-nPPdTt.js → ishikawaDiagram-FXEZZL3T-CRO2OGCv.js} +1 -1
  452. package/ui-dist/assets/{journeyDiagram-5HDEW3XC-C3hqQN0R.js → journeyDiagram-5HDEW3XC-Di6QSKTh.js} +1 -1
  453. package/ui-dist/assets/{kanban-definition-HUTT4EX6-CPoD9DUm.js → kanban-definition-HUTT4EX6-D9TB3XsU.js} +1 -1
  454. package/ui-dist/assets/{linear-D-S8yr3Z.js → linear-DNuyBs03.js} +1 -1
  455. package/ui-dist/assets/{mermaid.core-DhvH8shK.js → mermaid.core-CRXbfGc8.js} +4 -4
  456. package/ui-dist/assets/{mindmap-definition-LN4V7U3C-CxCIKrKo.js → mindmap-definition-LN4V7U3C-BVxJgBfB.js} +1 -1
  457. package/ui-dist/assets/{pegDiagram-2B236MQR-D4G-PC6N.js → pegDiagram-2B236MQR-BuMRgd7M.js} +1 -1
  458. package/ui-dist/assets/{pieDiagram-ENE6RG2P-N4X8UvqY.js → pieDiagram-ENE6RG2P-DFT7WuwK.js} +1 -1
  459. package/ui-dist/assets/{quadrantDiagram-ABIIQ3AL-CZohoDln.js → quadrantDiagram-ABIIQ3AL-HOLkwSzD.js} +1 -1
  460. package/ui-dist/assets/{railroadDiagram-RFXS5EU6-fMGQVhwF.js → railroadDiagram-RFXS5EU6-BND-mOri.js} +1 -1
  461. package/ui-dist/assets/{requirementDiagram-TGXJPOKE-CK0IuUmk.js → requirementDiagram-TGXJPOKE-BOa8A9lE.js} +1 -1
  462. package/ui-dist/assets/{sankeyDiagram-HTMAVEWB-pSfb3CqG.js → sankeyDiagram-HTMAVEWB-B7cM3qvd.js} +1 -1
  463. package/ui-dist/assets/{sequenceDiagram-DBY2YBRQ-CbhkqIeq.js → sequenceDiagram-DBY2YBRQ-ClQvkzoo.js} +1 -1
  464. package/ui-dist/assets/{sizeCapture-X5ZJPWSS-B6vqqPx-.js → sizeCapture-X5ZJPWSS-D4r_s7na.js} +1 -1
  465. package/ui-dist/assets/{stateDiagram-2N3HPSRC-DIJf9h5C.js → stateDiagram-2N3HPSRC-Cx0UQpxD.js} +1 -1
  466. package/ui-dist/assets/stateDiagram-v2-6OUMAXLB-C8L1NW8Q.js +1 -0
  467. package/ui-dist/assets/{swimlanes-5IMT3BWC-DIX_LV8O.js → swimlanes-5IMT3BWC-cGIUWMIm.js} +2 -2
  468. package/ui-dist/assets/swimlanesDiagram-G3AALYLV-Dj9aJ1a_.js +8 -0
  469. package/ui-dist/assets/{timeline-definition-FHXFAJF6-CD-Pxb_g.js → timeline-definition-FHXFAJF6-BUHQ5Auj.js} +1 -1
  470. package/ui-dist/assets/{vennDiagram-L72KCM5P-BAZsWL0R.js → vennDiagram-L72KCM5P-TvbS6VWx.js} +1 -1
  471. package/ui-dist/assets/{wardleyDiagram-EHGQE667-CnNyfwX5.js → wardleyDiagram-EHGQE667-VkQDXzb8.js} +1 -1
  472. package/ui-dist/assets/{xychartDiagram-FW5EYKEG-j9YgsD3Y.js → xychartDiagram-FW5EYKEG-ButPn9aQ.js} +1 -1
  473. package/ui-dist/fonts/InterVariable-Italic.woff2 +0 -0
  474. package/ui-dist/fonts/InterVariable.woff2 +0 -0
  475. package/ui-dist/fonts/NOTICE.md +17 -0
  476. package/ui-dist/index.html +2 -2
  477. package/ui-dist/locales/en/common.json +1002 -2
  478. package/ui-dist/locales/zh-CN/common.json +1003 -3
  479. package/ui-dist/assets/channel-CsiI2LYw.js +0 -1
  480. package/ui-dist/assets/classDiagram-OUVF2IWQ-CBn1Jqo8.js +0 -1
  481. package/ui-dist/assets/classDiagram-v2-EOCWNBFH-CBn1Jqo8.js +0 -1
  482. package/ui-dist/assets/index-BsL8K1vL.css +0 -1
  483. package/ui-dist/assets/index-D__fTsb2.js +0 -643
  484. package/ui-dist/assets/stateDiagram-v2-6OUMAXLB-DpwLD7YL.js +0 -1
  485. package/ui-dist/assets/swimlanesDiagram-G3AALYLV-Cklauutg.js +0 -8
@@ -3,12 +3,12 @@ import { generateKeyPairSync, randomUUID } from "node:crypto";
3
3
  import path from "node:path";
4
4
  import { agents as agentsTable, companies, heartbeatRuns, issues as issuesTable, projects as projectsTable } from "@penclipai/db";
5
5
  import { and, desc, eq, inArray, not, sql } from "drizzle-orm";
6
- import { agentSkillSyncSchema, agentMineInboxQuerySchema, AGENT_DEFAULT_MAX_CONCURRENT_RUNS, createAgentKeySchema, createAgentHireSchema, createAgentSchema, deriveAgentUrlKey, isUuidLike, normalizeIssueIdentifier, resetAgentSessionSchema, testAdapterEnvironmentSchema, upsertAgentInstructionsFileSchema, updateAgentInstructionsBundleSchema, updateAgentPermissionsSchema, updateAgentInstructionsPathSchema, wakeAgentSchema, updateAgentSchema, supportedEnvironmentDriversForAdapter, LOW_TRUST_REVIEW_PRESET, } from "@penclipai/shared";
6
+ import { agentSkillSyncSchema, agentMineInboxQuerySchema, ADAPTER_AGNOSTIC_KEYS, AGENT_DEFAULT_MAX_CONCURRENT_RUNS, createAgentKeySchema, createAgentHireSchema, createAgentSchema, deriveAgentUrlKey, isUuidLike, normalizeIssueIdentifier, resetAgentSessionSchema, testAdapterEnvironmentSchema, upsertAgentInstructionsFileSchema, updateAgentInstructionsBundleSchema, updateAgentPermissionsSchema, updateAgentInstructionsPathSchema, wakeAgentSchema, updateAgentSchema, supportedEnvironmentDriversForAdapter, LOW_TRUST_REVIEW_PRESET, } from "@penclipai/shared";
7
7
  import { resolvePaperclipInstanceRootForAdapter, readPaperclipSkillSyncPreference, writePaperclipSkillSyncPreference, } from "@penclipai/adapter-utils/server-utils";
8
8
  import { trackAgentCreated } from "@penclipai/shared/telemetry";
9
9
  import { validate } from "../middleware/validate.js";
10
- import { agentService, agentInstructionsService, accessService, approvalService, companySkillService, budgetService, heartbeatService, ISSUE_LIST_DEFAULT_LIMIT, issueApprovalService, issueRecoveryActionService, issueService, logActivity, syncInstructionsBundleConfigFromFilePath, workspaceOperationService, } from "../services/index.js";
11
- import { conflict, forbidden, notFound, unprocessable } from "../errors.js";
10
+ import { agentService, agentInstructionsService, accessService, approvalService, builtInAgentService, companySkillService, budgetService, heartbeatService, ISSUE_LIST_DEFAULT_LIMIT, issueApprovalService, issueRecoveryActionService, issueService, logActivity, syncInstructionsBundleConfigFromFilePath, workspaceOperationService, } from "../services/index.js";
11
+ import { conflict, forbidden, HttpError, notFound, unprocessable } from "../errors.js";
12
12
  import { assertBoard, assertCompanyAccess, assertInstanceAdmin, getActorInfo } from "./authz.js";
13
13
  import { assertNoAgentHostWorkspaceCommandMutation, collectAgentAdapterWorkspaceCommandPaths, } from "./workspace-command-authz.js";
14
14
  import { environmentService } from "../services/environments.js";
@@ -16,15 +16,15 @@ import { resolveEnvironmentExecutionTarget } from "../services/environment-execu
16
16
  import { environmentRuntimeService } from "../services/environment-runtime.js";
17
17
  import { skillVersionSelectionMap } from "../services/runtime-skill-selections.js";
18
18
  import { secretService } from "../services/secrets.js";
19
+ import { authorizationDeniedDetails } from "../services/authorization.js";
19
20
  import { detectAdapterModel, findActiveServerAdapter, findServerAdapter, listAdapterModels, listAdapterModelProfiles, refreshAdapterModels, requireServerAdapter, } from "../adapters/index.js";
20
21
  import { redactEventPayload } from "../redaction.js";
21
22
  import { redactCurrentUserValue } from "../log-redaction.js";
22
23
  import { resolveExplicitRequestUiLocale } from "../ui-locale.js";
23
24
  import { getBundledPaperclipSkillIdentity } from "../services/bundled-paperclip-skills.js";
24
25
  import { renderOrgChartSvg, renderOrgChartPng, ORG_CHART_STYLES } from "./org-chart-svg.js";
25
- import { instanceSettingsService } from "../services/instance-settings.js";
26
+ import { instanceSettingsService, isTruthyRuntimeEnvValue, resolveWorktreeRunExecutionActivationState, } from "../services/instance-settings.js";
26
27
  import { runClaudeLogin } from "@penclipai/adapter-claude-local/server";
27
- import { DEFAULT_ACPX_LOCAL_AGENT, DEFAULT_ACPX_LOCAL_MODE, DEFAULT_ACPX_LOCAL_NON_INTERACTIVE_PERMISSIONS, DEFAULT_ACPX_LOCAL_PERMISSION_MODE, } from "@penclipai/adapter-acpx-local";
28
28
  import { DEFAULT_CODEX_LOCAL_BYPASS_APPROVALS_AND_SANDBOX } from "@penclipai/adapter-codex-local";
29
29
  import { DEFAULT_CURSOR_LOCAL_MODEL } from "@penclipai/adapter-cursor-local";
30
30
  import { DEFAULT_GEMINI_LOCAL_MODEL } from "@penclipai/adapter-gemini-local";
@@ -37,6 +37,7 @@ import { recoveryService } from "../services/recovery/service.js";
37
37
  import { resolveCoreTrustPreset } from "../services/trust-preset-resolver.js";
38
38
  import { readObject } from "../lib/objects.js";
39
39
  import { listInvalidOrgChainDescendantIds } from "../services/agent-invokability.js";
40
+ import { AGENT_PROFILE_CHANGE_CONSENT_FIELDS, agentInstructionsChangeTargetKey, agentProfileChangeTargetKey, changeConsentGateService, touchesAgentProfileChangeConsentFields, } from "../services/change-consent-gate.js";
40
41
  const RUN_LOG_DEFAULT_LIMIT_BYTES = 256_000;
41
42
  const RUN_LOG_MAX_LIMIT_BYTES = 1024 * 1024;
42
43
  function readRunLogLimitBytes(value) {
@@ -65,7 +66,6 @@ export function agentRoutes(db, options = {}) {
65
66
  // Legacy hardcoded maps — used as fallback when adapter module does not
66
67
  // declare capability flags explicitly.
67
68
  const DEFAULT_INSTRUCTIONS_PATH_KEYS = {
68
- acpx_local: "instructionsFilePath",
69
69
  claude_local: "instructionsFilePath",
70
70
  codex_local: "instructionsFilePath",
71
71
  droid_local: "instructionsFilePath",
@@ -101,6 +101,7 @@ export function agentRoutes(db, options = {}) {
101
101
  "instructionsFilePath",
102
102
  "agentsMdPath",
103
103
  ];
104
+ const KNOWN_INSTRUCTIONS_BUNDLE_KEY_SET = new Set(KNOWN_INSTRUCTIONS_BUNDLE_KEYS);
104
105
  const router = Router();
105
106
  const svc = agentService(db);
106
107
  const access = accessService(db);
@@ -260,11 +261,26 @@ export function agentRoutes(db, options = {}) {
260
261
  // run id to heartbeat_runs.id, and we don't want to manufacture a fake
261
262
  // run row. Cleanup goes through the driver's `releaseRunLease` directly
262
263
  // (by lease record), since the batch helper queries by heartbeatRunId.
264
+ //
265
+ // Sandbox tests boot a fresh throwaway sandbox (never resume a retained
266
+ // agent lease) and archive it on release instead of deleting it, so the
267
+ // operator can inspect the exact sandbox from the provider dashboard while
268
+ // provider-side expiry reaps it later.
269
+ const testEnvironment = environment.driver === "sandbox"
270
+ ? {
271
+ ...environment,
272
+ config: {
273
+ ...(environment.config ?? {}),
274
+ reuseLease: false,
275
+ archiveOnRelease: true,
276
+ },
277
+ }
278
+ : environment;
263
279
  let leaseRecord;
264
280
  try {
265
281
  leaseRecord = await environmentRuntime.acquireRunLease({
266
282
  companyId: input.companyId,
267
- environment,
283
+ environment: testEnvironment,
268
284
  issueId: null,
269
285
  heartbeatRunId: null,
270
286
  persistedExecutionWorkspace: null,
@@ -296,7 +312,7 @@ export function agentRoutes(db, options = {}) {
296
312
  try {
297
313
  if (driver) {
298
314
  await driver.releaseRunLease({
299
- environment,
315
+ environment: testEnvironment,
300
316
  lease: leaseRecord.lease,
301
317
  status,
302
318
  });
@@ -314,7 +330,7 @@ export function agentRoutes(db, options = {}) {
314
330
  let realizedCwd = null;
315
331
  try {
316
332
  const realized = await environmentRuntime.realizeWorkspace({
317
- environment,
333
+ environment: testEnvironment,
318
334
  lease: leaseRecord.lease,
319
335
  // No host workspace to copy for a Test invocation; sandbox/plugin
320
336
  // realize implementations use the lease metadata's remoteCwd to
@@ -353,9 +369,9 @@ export function agentRoutes(db, options = {}) {
353
369
  companyId: input.companyId,
354
370
  adapterType: input.adapterType,
355
371
  environment: {
356
- id: environment.id,
357
- driver: environment.driver,
358
- config: environment.config ?? null,
372
+ id: testEnvironment.id,
373
+ driver: testEnvironment.driver,
374
+ config: testEnvironment.config ?? null,
359
375
  },
360
376
  leaseId: leaseRecord.lease.id,
361
377
  leaseMetadata: leaseMetadataForTarget,
@@ -398,9 +414,64 @@ export function agentRoutes(db, options = {}) {
398
414
  executionTarget: target,
399
415
  environmentName: environment.name,
400
416
  fallbackChecks: [],
417
+ sandboxIdentityCheck: buildSandboxIdentityCheck({
418
+ environmentName: environment.name,
419
+ lease: leaseRecord.lease,
420
+ }),
401
421
  release: releaseLease,
402
422
  };
403
423
  }
424
+ function readMetadataString(metadata, keys) {
425
+ for (const key of keys) {
426
+ const value = metadata[key];
427
+ if (typeof value === "string" && value.trim().length > 0)
428
+ return value.trim();
429
+ }
430
+ return null;
431
+ }
432
+ function buildSandboxIdentityCheck(input) {
433
+ const metadata = input.lease.metadata ?? {};
434
+ const provider = input.lease.provider ?? readMetadataString(metadata, ["provider"]);
435
+ const sandboxId = readMetadataString(metadata, ["sandboxId", "sandboxID", "sandbox_id", "id"]);
436
+ const sandboxName = readMetadataString(metadata, ["sandboxName", "sandbox_name", "name"]);
437
+ const snapshotRef = readMetadataString(metadata, [
438
+ "snapshot",
439
+ "snapshotId",
440
+ "snapshotID",
441
+ "snapshotRef",
442
+ "snapshot_ref",
443
+ "templateRef",
444
+ "template_ref",
445
+ "templateId",
446
+ "templateID",
447
+ "image",
448
+ "imageId",
449
+ "imageID",
450
+ "imageRef",
451
+ "image_ref",
452
+ ]);
453
+ const templateKind = readMetadataString(metadata, [
454
+ "templateKind",
455
+ "template_kind",
456
+ "templateRefKind",
457
+ "template_ref_kind",
458
+ ]);
459
+ const detailParts = [
460
+ `paperclipLeaseId=${input.lease.id}`,
461
+ input.lease.providerLeaseId ? `providerLeaseId=${input.lease.providerLeaseId}` : null,
462
+ provider ? `provider=${provider}` : null,
463
+ sandboxId ? `sandboxId=${sandboxId}` : null,
464
+ sandboxName ? `sandboxName=${sandboxName}` : null,
465
+ snapshotRef ? `${templateKind ? `${templateKind}Ref` : "snapshotOrTemplateRef"}=${snapshotRef}` : null,
466
+ ].filter((part) => Boolean(part));
467
+ return {
468
+ code: "sandbox_test_identity",
469
+ level: "info",
470
+ message: `Sandbox test identity for "${input.environmentName}".`,
471
+ detail: detailParts.join("; "),
472
+ hint: "Use these provider-neutral IDs when comparing model-test output with provider logs or refreshed sandbox snapshots.",
473
+ };
474
+ }
404
475
  async function getCurrentUserRedactionOptions() {
405
476
  return {
406
477
  enabled: (await instanceSettings.getGeneral()).censorUsernameInLogs,
@@ -539,7 +610,7 @@ export function agentRoutes(db, options = {}) {
539
610
  resource: { type: "company", companyId },
540
611
  });
541
612
  if (!decision.allowed) {
542
- throw forbidden(decision.explanation);
613
+ throw forbidden(decision.explanation, authorizationDeniedDetails(decision));
543
614
  }
544
615
  if (req.actor.type !== "agent")
545
616
  return null;
@@ -559,33 +630,29 @@ export function agentRoutes(db, options = {}) {
559
630
  });
560
631
  if (decision.allowed)
561
632
  return;
562
- throw forbidden(decision.explanation);
633
+ throw forbidden(decision.explanation, authorizationDeniedDetails(decision));
563
634
  }
564
635
  async function assertCanReadConfigurations(req, companyId) {
565
636
  // Reading agent configurations, skills, and config revisions is a
566
637
  // read-only operation available to any board (human) member of the
567
638
  // company. Responses go through `redactAgentConfiguration` so secrets
568
639
  // are never exposed. Mutations and environment probes still gate on
569
- // agents:create via assertCanCreateAgentsForCompany / assertCanUpdateAgent.
640
+ // agents:create or agents:configure via the mutating route helpers.
570
641
  //
571
- // For AGENT actors we keep the previous, stricter gate: an agent must
572
- // either have an explicit `agents:create` grant or the legacy
573
- // `canCreateAgents` permission on its own record. Agents are
574
- // non-human principals — they should not be able to introspect peer
575
- // agents' configurations just by virtue of being in the same company.
642
+ // For AGENT actors we keep a stricter gate: an agent must have either
643
+ // agents:configure or agents:suggest-changes before it can inspect peer
644
+ // agent configuration for a proposed diff.
576
645
  assertCompanyAccess(req, companyId);
577
646
  if (req.actor.type === "agent") {
578
- if (!req.actor.agentId)
579
- throw forbidden("Agent authentication required");
580
- const actorAgent = await svc.getById(req.actor.agentId);
581
- if (!actorAgent || actorAgent.companyId !== companyId) {
582
- throw forbidden("Agent key cannot access another company");
583
- }
584
- const allowedByGrant = await access.hasPermission(companyId, "agent", actorAgent.id, "agents:create");
585
- if (!allowedByGrant && !canCreateAgents(actorAgent)) {
586
- throw forbidden("Missing permission: can create agents");
647
+ const decision = await access.decide({
648
+ actor: req.actor,
649
+ action: "agent_config:read",
650
+ resource: { type: "company", companyId },
651
+ });
652
+ if (!decision.allowed) {
653
+ throw forbidden(decision.explanation, authorizationDeniedDetails(decision));
587
654
  }
588
- return actorAgent;
655
+ return req.actor.agentId ? await svc.getById(req.actor.agentId) : null;
589
656
  }
590
657
  return null;
591
658
  }
@@ -603,10 +670,9 @@ export function agentRoutes(db, options = {}) {
603
670
  }
604
671
  async function actorCanReadConfigurationsForCompany(req, companyId) {
605
672
  // Mirrors assertCanReadConfigurations but returns a boolean instead of
606
- // throwing. Board actors only need company access; agent actors must
607
- // still pass the agents:create gate (explicit grant or canCreateAgents
608
- // on their own record) so peer agents cannot snoop each others'
609
- // configurations.
673
+ // throwing. Board actors only need company access; agent actors must pass
674
+ // the agent configuration read grant ladder so peer agents cannot snoop
675
+ // each others' configurations.
610
676
  try {
611
677
  assertCompanyAccess(req, companyId);
612
678
  }
@@ -615,13 +681,12 @@ export function agentRoutes(db, options = {}) {
615
681
  }
616
682
  if (req.actor.type === "board")
617
683
  return true;
618
- if (!req.actor.agentId)
619
- return false;
620
- const actorAgent = await svc.getById(req.actor.agentId);
621
- if (!actorAgent || actorAgent.companyId !== companyId)
622
- return false;
623
- const allowedByGrant = await access.hasPermission(companyId, "agent", actorAgent.id, "agents:create");
624
- return allowedByGrant || canCreateAgents(actorAgent);
684
+ const decision = await access.decide({
685
+ actor: req.actor,
686
+ action: "agent_config:read",
687
+ resource: { type: "company", companyId },
688
+ });
689
+ return decision.allowed;
625
690
  }
626
691
  async function buildSkippedWakeupResponse(agent, payload) {
627
692
  const issueId = typeof payload?.issueId === "string" && payload.issueId.trim() ? payload.issueId : null;
@@ -690,7 +755,7 @@ export function agentRoutes(db, options = {}) {
690
755
  });
691
756
  if (decision.allowed)
692
757
  return;
693
- throw forbidden(decision.explanation);
758
+ throw forbidden(decision.explanation, authorizationDeniedDetails(decision));
694
759
  }
695
760
  async function assertCanReadAgent(req, targetAgent) {
696
761
  assertCompanyAccess(req, targetAgent.companyId);
@@ -704,6 +769,14 @@ export function agentRoutes(db, options = {}) {
704
769
  if (!actorAgent || actorAgent.companyId !== targetAgent.companyId) {
705
770
  throw forbidden("Agent key cannot access another company");
706
771
  }
772
+ const decision = await access.decide({
773
+ actor: req.actor,
774
+ action: "agent_config:read",
775
+ resource: { type: "agent", companyId: targetAgent.companyId, agentId: targetAgent.id },
776
+ });
777
+ if (decision.allowed)
778
+ return;
779
+ throw forbidden(decision.explanation, authorizationDeniedDetails(decision));
707
780
  }
708
781
  function assertKnownAdapterType(type) {
709
782
  const adapterType = typeof type === "string" ? type.trim() : "";
@@ -984,21 +1057,6 @@ export function agentRoutes(db, options = {}) {
984
1057
  }
985
1058
  function applyCreateDefaultsByAdapterType(adapterType, adapterConfig) {
986
1059
  const next = { ...adapterConfig };
987
- if (adapterType === "acpx_local") {
988
- if (!asNonEmptyString(next.agent)) {
989
- next.agent = DEFAULT_ACPX_LOCAL_AGENT;
990
- }
991
- if (!asNonEmptyString(next.mode)) {
992
- next.mode = DEFAULT_ACPX_LOCAL_MODE;
993
- }
994
- if (!asNonEmptyString(next.permissionMode)) {
995
- next.permissionMode = DEFAULT_ACPX_LOCAL_PERMISSION_MODE;
996
- }
997
- if (!asNonEmptyString(next.nonInteractivePermissions)) {
998
- next.nonInteractivePermissions = DEFAULT_ACPX_LOCAL_NON_INTERACTIVE_PERMISSIONS;
999
- }
1000
- return ensureGatewayDeviceKey(adapterType, next);
1001
- }
1002
1060
  if (adapterType === "codex_local") {
1003
1061
  const hasBypassFlag = typeof next.dangerouslyBypassApprovalsAndSandbox === "boolean" ||
1004
1062
  typeof next.dangerouslyBypassSandbox === "boolean";
@@ -1062,7 +1120,9 @@ export function agentRoutes(db, options = {}) {
1062
1120
  delete nextAdapterConfig.bootstrapPromptTemplate;
1063
1121
  if (!hadLegacyPrompt)
1064
1122
  return agent;
1065
- const updated = await svc.update(agent.id, { adapterConfig: nextAdapterConfig });
1123
+ const updated = await svc.update(agent.id, { adapterConfig: nextAdapterConfig }, {
1124
+ allowPendingApprovalConfigUpdate: true,
1125
+ });
1066
1126
  return updated ?? { ...agent, adapterConfig: nextAdapterConfig };
1067
1127
  }
1068
1128
  const files = input?.files
@@ -1071,7 +1131,9 @@ export function agentRoutes(db, options = {}) {
1071
1131
  const nextAdapterConfig = { ...materialized.adapterConfig };
1072
1132
  delete nextAdapterConfig.promptTemplate;
1073
1133
  delete nextAdapterConfig.bootstrapPromptTemplate;
1074
- const updated = await svc.update(agent.id, { adapterConfig: nextAdapterConfig });
1134
+ const updated = await svc.update(agent.id, { adapterConfig: nextAdapterConfig }, {
1135
+ allowPendingApprovalConfigUpdate: true,
1136
+ });
1075
1137
  return updated ?? { ...agent, adapterConfig: nextAdapterConfig };
1076
1138
  }
1077
1139
  function assertNoNewAgentLegacyPromptTemplate(adapterType, adapterConfig) {
@@ -1082,12 +1144,51 @@ export function agentRoutes(db, options = {}) {
1082
1144
  throw unprocessable("New agents must use instructionsBundle/AGENTS.md instead of adapterConfig.promptTemplate or bootstrapPromptTemplate");
1083
1145
  }
1084
1146
  }
1085
- async function assertCanManageInstructionsPath(req, targetAgent) {
1147
+ async function assertCanApplyProtectedAgentChange(req, targetAgent, targetKeys) {
1086
1148
  assertCompanyAccess(req, targetAgent.companyId);
1087
- if (req.actor.type !== "board") {
1088
- throw forbidden("Only board-authenticated callers can manage instructions path or bundle configuration");
1149
+ const changeScope = { requiresChangeGrant: true };
1150
+ const decision = await access.decide({
1151
+ actor: req.actor,
1152
+ action: "agent_config:update",
1153
+ resource: { type: "agent", companyId: targetAgent.companyId, agentId: targetAgent.id },
1154
+ scope: changeScope,
1155
+ });
1156
+ if (decision.allowed) {
1157
+ return;
1158
+ }
1159
+ if (decision.reason === "deny_missing_consent" && req.actor.type === "agent" && targetKeys.length > 0) {
1160
+ try {
1161
+ await changeConsentGateService(db).assertConsented({
1162
+ companyId: targetAgent.companyId,
1163
+ actorAgentId: req.actor.agentId,
1164
+ actorRunId: req.actor.runId ?? null,
1165
+ targetKeys,
1166
+ });
1167
+ }
1168
+ catch (err) {
1169
+ if (err instanceof HttpError && err.status === 403) {
1170
+ throw forbidden(decision.explanation, authorizationDeniedDetails(decision));
1171
+ }
1172
+ throw err;
1173
+ }
1174
+ const consentedDecision = await access.decide({
1175
+ actor: req.actor,
1176
+ action: "agent_config:update",
1177
+ resource: { type: "agent", companyId: targetAgent.companyId, agentId: targetAgent.id },
1178
+ scope: { ...changeScope, consentedChange: true },
1179
+ });
1180
+ if (consentedDecision.allowed) {
1181
+ return;
1182
+ }
1183
+ throw forbidden(consentedDecision.explanation, authorizationDeniedDetails(consentedDecision));
1089
1184
  }
1090
- await assertBoardCanManageAgentsForCompany(req, targetAgent.companyId);
1185
+ throw forbidden(decision.explanation, authorizationDeniedDetails(decision));
1186
+ }
1187
+ async function assertCanManageInstructionsPath(req, targetAgent) {
1188
+ await assertCanApplyProtectedAgentChange(req, targetAgent, [agentInstructionsChangeTargetKey(targetAgent.id)]);
1189
+ }
1190
+ async function assertCanApplyAgentProfileChange(req, targetAgent) {
1191
+ await assertCanApplyProtectedAgentChange(req, targetAgent, [agentProfileChangeTargetKey(targetAgent.id)]);
1091
1192
  }
1092
1193
  function assertNoAgentInstructionsConfigMutation(req, adapterConfig, path = "adapterConfig") {
1093
1194
  if (req.actor.type !== "agent" || !adapterConfig)
@@ -1175,7 +1276,7 @@ export function agentRoutes(db, options = {}) {
1175
1276
  paperclipRuntimeSkills: runtimeSkillEntries,
1176
1277
  };
1177
1278
  }
1178
- async function resolveDesiredSkillAssignment(companyId, adapterType, adapterConfig, requestedDesiredSkills) {
1279
+ async function resolveDesiredSkillAssignment(companyId, adapterType, adapterConfig, requestedDesiredSkills, options = {}) {
1179
1280
  if (!requestedDesiredSkills) {
1180
1281
  return {
1181
1282
  adapterConfig,
@@ -1184,18 +1285,22 @@ export function agentRoutes(db, options = {}) {
1184
1285
  runtimeSkillEntries: null,
1185
1286
  };
1186
1287
  }
1187
- const resolvedRequestedSkillEntries = await companySkills.resolveRequestedSkillEntries(companyId, requestedDesiredSkills);
1288
+ const { resolved: resolvedRequestedSkillEntries, unresolved: unresolvedDesiredSkillKeys } = await companySkills.resolveRequestedSkillEntries(companyId, requestedDesiredSkills, {
1289
+ tolerateUnknownReferences: options.tolerateUnknownDesiredSkills,
1290
+ });
1291
+ // Runtime materialization + version selection only ever consider skills that
1292
+ // actually resolve to the company library; stale keys can't be materialized.
1188
1293
  const runtimeSkillEntries = await companySkills.listRuntimeSkillEntries(companyId, {
1189
1294
  materializeMissing: shouldMaterializeRuntimeSkillsForAdapter(adapterType),
1190
1295
  versionSelections: skillVersionSelectionMap(resolvedRequestedSkillEntries),
1191
1296
  });
1192
- const requiredSkills = runtimeSkillEntries
1193
- .filter((entry) => entry.required)
1194
- .map((entry) => entry.key);
1297
+ const resolvedDesiredSkillEntries = resolvedRequestedSkillEntries.filter((entry, index, entries) => entries.findIndex((candidate) => candidate.key === entry.key) === index);
1298
+ // Preserve stale/unresolvable keys in the persisted desired set so they stay
1299
+ // visible (and explicitly removable) instead of vanishing on the next save.
1195
1300
  const desiredSkillEntries = [
1196
- ...requiredSkills.map((key) => ({ key, versionId: null })),
1197
- ...resolvedRequestedSkillEntries,
1198
- ].filter((entry, index, entries) => entries.findIndex((candidate) => desiredSkillEntryIdentity(candidate) === desiredSkillEntryIdentity(entry)) === index);
1301
+ ...resolvedDesiredSkillEntries,
1302
+ ...unresolvedDesiredSkillKeys.map((key) => ({ key, versionId: null })),
1303
+ ];
1199
1304
  const desiredSkills = desiredSkillEntries.map((entry) => entry.key);
1200
1305
  return {
1201
1306
  adapterConfig: writePaperclipSkillSyncPreference(adapterConfig, desiredSkillEntries),
@@ -1324,7 +1429,7 @@ export function agentRoutes(db, options = {}) {
1324
1429
  : null;
1325
1430
  const normalizedAdapterConfig = await secretsSvc.normalizeAdapterConfigForPersistence(companyId, inputAdapterConfig, { strictMode: strictSecretsMode, adapterType: type });
1326
1431
  const { config: runtimeAdapterConfig } = await secretsSvc.resolveAdapterConfigForRuntime(companyId, normalizedAdapterConfig, undefined, { adapterType: type });
1327
- const { executionTarget, environmentName, fallbackChecks, release } = await resolveAdapterTestExecutionContext({
1432
+ const { executionTarget, environmentName, fallbackChecks, sandboxIdentityCheck, release } = await resolveAdapterTestExecutionContext({
1328
1433
  companyId,
1329
1434
  adapterType: type,
1330
1435
  environmentId: requestedEnvironmentId,
@@ -1360,7 +1465,10 @@ export function agentRoutes(db, options = {}) {
1360
1465
  });
1361
1466
  if (result.status === "fail")
1362
1467
  releaseStatus = "failed";
1363
- res.json(result);
1468
+ res.json({
1469
+ ...result,
1470
+ checks: sandboxIdentityCheck ? [sandboxIdentityCheck, ...result.checks] : result.checks,
1471
+ });
1364
1472
  }
1365
1473
  catch (err) {
1366
1474
  releaseStatus = "failed";
@@ -1385,7 +1493,7 @@ export function agentRoutes(db, options = {}) {
1385
1493
  res.json(buildUnsupportedSkillSnapshot(agent.adapterType, desiredSkillEntries));
1386
1494
  return;
1387
1495
  }
1388
- const { config: runtimeConfig } = await secretsSvc.resolveAdapterConfigForRuntime(agent.companyId, agent.adapterConfig);
1496
+ const { config: runtimeConfig } = await secretsSvc.resolveAdapterConfigForRuntime(agent.companyId, agent.adapterConfig, undefined, { adapterType: agent.adapterType, skipUserSecrets: true });
1389
1497
  const runtimeSkillConfig = await buildRuntimeSkillConfig(agent.companyId, agent.adapterType, runtimeConfig, { materializeMissing: false });
1390
1498
  const snapshot = await adapter.listSkills({
1391
1499
  agentId: agent.id,
@@ -1404,7 +1512,11 @@ export function agentRoutes(db, options = {}) {
1404
1512
  }
1405
1513
  await assertCanUpdateAgent(req, agent);
1406
1514
  const requestedSkills = normalizeDesiredSkillSelections(req.body.desiredSkills);
1407
- const { adapterConfig: nextAdapterConfig, desiredSkills, desiredSkillEntries, runtimeSkillEntries, } = await resolveDesiredSkillAssignment(agent.companyId, agent.adapterType, agent.adapterConfig, requestedSkills);
1515
+ const { adapterConfig: nextAdapterConfig, desiredSkills, desiredSkillEntries, runtimeSkillEntries, } = await resolveDesiredSkillAssignment(agent.companyId, agent.adapterType, agent.adapterConfig, requestedSkills,
1516
+ // Toggling a resolvable skill must not fail just because the agent
1517
+ // already carries stale desired keys (e.g. a skill removed from the
1518
+ // library). Preserve those keys so they remain visible/removable.
1519
+ { tolerateUnknownDesiredSkills: true });
1408
1520
  if (!desiredSkills || !desiredSkillEntries || !runtimeSkillEntries) {
1409
1521
  throw unprocessable("Skill sync requires desiredSkills.");
1410
1522
  }
@@ -1423,7 +1535,7 @@ export function agentRoutes(db, options = {}) {
1423
1535
  return;
1424
1536
  }
1425
1537
  const adapter = findActiveServerAdapter(updated.adapterType);
1426
- const { config: runtimeConfig } = await secretsSvc.resolveAdapterConfigForRuntime(updated.companyId, updated.adapterConfig);
1538
+ const { config: runtimeConfig } = await secretsSvc.resolveAdapterConfigForRuntime(updated.companyId, updated.adapterConfig, undefined, { adapterType: updated.adapterType, skipUserSecrets: true });
1427
1539
  const runtimeSkillConfig = {
1428
1540
  ...runtimeConfig,
1429
1541
  paperclipRuntimeSkills: runtimeSkillEntries,
@@ -1619,12 +1731,21 @@ export function agentRoutes(db, options = {}) {
1619
1731
  includeRoutineExecutions: true,
1620
1732
  limit: ISSUE_LIST_DEFAULT_LIMIT,
1621
1733
  });
1622
- const issueIds = rows.map((issue) => issue.id);
1734
+ const worktreeActivation = await resolveWorktreeRunExecutionActivationState({
1735
+ getExperimental: () => instanceSettingsService(db).getExperimental(),
1736
+ });
1737
+ const isWorktreeRuntime = isTruthyRuntimeEnvValue(process.env.PAPERCLIP_IN_WORKTREE);
1738
+ const eligibleRows = !isWorktreeRuntime
1739
+ ? rows
1740
+ : worktreeActivation.armed
1741
+ ? rows.filter((issue) => new Date(issue.createdAt) >= new Date(worktreeActivation.cutoff))
1742
+ : [];
1743
+ const issueIds = eligibleRows.map((issue) => issue.id);
1623
1744
  const [dependencyReadiness, recoveryActionByIssue] = await Promise.all([
1624
1745
  issuesSvc.listDependencyReadiness(req.actor.companyId, issueIds),
1625
1746
  recoveryActionsSvc.listActiveForIssues(req.actor.companyId, issueIds),
1626
1747
  ]);
1627
- res.json(rows.map((issue) => ({
1748
+ res.json(eligibleRows.map((issue) => ({
1628
1749
  id: issue.id,
1629
1750
  identifier: issue.identifier,
1630
1751
  title: issue.title,
@@ -2004,6 +2125,7 @@ export function agentRoutes(db, options = {}) {
2004
2125
  trackAgentCreated(telemetryClient, { agentRole: agent.role, agentId: agent.id });
2005
2126
  }
2006
2127
  await applyDefaultAgentTaskAssignGrant(companyId, agent.id, req.actor.type === "board" ? (req.actor.userId ?? null) : null);
2128
+ await builtInAgentService(db).ensureCompanyDefaultAgentGrants(companyId);
2007
2129
  if (agent.budgetMonthlyCents > 0) {
2008
2130
  await budgets.upsertPolicy(companyId, {
2009
2131
  scopeType: "agent",
@@ -2264,7 +2386,7 @@ export function agentRoutes(db, options = {}) {
2264
2386
  res.status(404).json({ error: "Agent not found" });
2265
2387
  return;
2266
2388
  }
2267
- await assertCanUpdateAgent(req, existing);
2389
+ assertCompanyAccess(req, existing.companyId);
2268
2390
  if (hasOwn(req.body, "permissions")) {
2269
2391
  res.status(422).json({ error: "Use /api/agents/:id/permissions for permission changes" });
2270
2392
  return;
@@ -2319,11 +2441,9 @@ export function agentRoutes(db, options = {}) {
2319
2441
  // Preserve adapter-agnostic keys (env, cwd, etc.) from the existing config
2320
2442
  // when the adapter type changes. Without this, a PATCH that includes
2321
2443
  // adapterConfig but omits these keys would silently drop them.
2322
- const ADAPTER_AGNOSTIC_KEYS = [
2323
- "env", "cwd", "timeoutSec", "graceSec",
2324
- "promptTemplate", "bootstrapPromptTemplate",
2325
- ];
2326
2444
  for (const key of ADAPTER_AGNOSTIC_KEYS) {
2445
+ if (KNOWN_INSTRUCTIONS_BUNDLE_KEY_SET.has(key))
2446
+ continue;
2327
2447
  if (rawEffectiveAdapterConfig[key] === undefined && existingAdapterConfig[key] !== undefined) {
2328
2448
  rawEffectiveAdapterConfig = { ...rawEffectiveAdapterConfig, [key]: existingAdapterConfig[key] };
2329
2449
  }
@@ -2350,6 +2470,14 @@ export function agentRoutes(db, options = {}) {
2350
2470
  allowedSandboxProviders: allowedSandboxProvidersForAgent(requestedAdapterType),
2351
2471
  });
2352
2472
  }
2473
+ const touchesProfileFields = touchesAgentProfileChangeConsentFields(patchData);
2474
+ const profileOnlyChange = touchesProfileFields && Object.keys(patchData).every((key) => AGENT_PROFILE_CHANGE_CONSENT_FIELDS.includes(key));
2475
+ if (profileOnlyChange) {
2476
+ await assertCanApplyAgentProfileChange(req, existing);
2477
+ }
2478
+ else {
2479
+ await assertCanUpdateAgent(req, existing);
2480
+ }
2353
2481
  const actor = getActorInfo(req);
2354
2482
  const agent = await svc.update(id, patchData, {
2355
2483
  recordRevision: {
@@ -2602,7 +2730,9 @@ export function agentRoutes(db, options = {}) {
2602
2730
  if (!agent) {
2603
2731
  return;
2604
2732
  }
2605
- const key = await svc.createApiKey(id, req.body.name, req.body.scope);
2733
+ const key = await svc.createApiKey(id, req.body.name, req.body.scope, {
2734
+ responsibleUserId: req.actor.userId ?? null,
2735
+ });
2606
2736
  await logActivity(db, {
2607
2737
  companyId: agent.companyId,
2608
2738
  actorType: "user",
@@ -2610,7 +2740,12 @@ export function agentRoutes(db, options = {}) {
2610
2740
  action: "agent.key_created",
2611
2741
  entityType: "agent",
2612
2742
  entityId: agent.id,
2613
- details: { keyId: key.id, name: key.name, scope: key.scope },
2743
+ details: {
2744
+ keyId: key.id,
2745
+ name: key.name,
2746
+ scope: key.scope,
2747
+ responsibleUserId: key.responsibleUserId,
2748
+ },
2614
2749
  });
2615
2750
  res.status(201).json(key);
2616
2751
  });
@@ -2692,7 +2827,7 @@ export function agentRoutes(db, options = {}) {
2692
2827
  actorType: actor.actorType,
2693
2828
  actorId: actor.actorId,
2694
2829
  agentId: actor.agentId,
2695
- runId: actor.runId,
2830
+ runId: run.id,
2696
2831
  action: "heartbeat.invoked",
2697
2832
  entityType: "heartbeat_run",
2698
2833
  entityId: run.id,
@@ -2775,7 +2910,7 @@ export function agentRoutes(db, options = {}) {
2775
2910
  actorType: actor.actorType,
2776
2911
  actorId: actor.actorId,
2777
2912
  agentId: actor.agentId,
2778
- runId: actor.runId,
2913
+ runId: run.id,
2779
2914
  action: "heartbeat.invoked",
2780
2915
  entityType: "heartbeat_run",
2781
2916
  entityId: run.id,