@penclipai/server 2026.704.0 → 2026.714.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-Dtgfy1PK.js} +1 -1
  393. package/ui-dist/assets/{arc-HZhAwbOs.js → arc-BGdvNvs8.js} +1 -1
  394. package/ui-dist/assets/{architectureDiagram-ZJ3FMSHR-BteMjuOn.js → architectureDiagram-ZJ3FMSHR-CK19SQDx.js} +1 -1
  395. package/ui-dist/assets/{blockDiagram-677ZJIJ3-Iq66uZjf.js → blockDiagram-677ZJIJ3-Kh4N3XG4.js} +1 -1
  396. package/ui-dist/assets/{browser-ponyfill-BBsuyZJt.js → browser-ponyfill-B3hXtEFW.js} +1 -1
  397. package/ui-dist/assets/{c4Diagram-LMCZKHZV-_nlglj7I.js → c4Diagram-LMCZKHZV-CBHpGrgU.js} +1 -1
  398. package/ui-dist/assets/channel-4fjB8e8N.js +1 -0
  399. package/ui-dist/assets/{chunk-2Q5K7J3B-Cvz7WwSQ.js → chunk-2Q5K7J3B-BdHbqi7k.js} +1 -1
  400. package/ui-dist/assets/{chunk-32BRIVSS-LLubniCS.js → chunk-32BRIVSS-DxtzZzpt.js} +1 -1
  401. package/ui-dist/assets/{chunk-5VM5RSS4-BOst5hcr.js → chunk-5VM5RSS4-DMKxBbgu.js} +1 -1
  402. package/ui-dist/assets/{chunk-EX3LRPZG-D5WNShVm.js → chunk-EX3LRPZG-BaIOPi4v.js} +1 -1
  403. package/ui-dist/assets/{chunk-JWPE2WC7-CA07x4av.js → chunk-JWPE2WC7-DGo3MPmr.js} +1 -1
  404. package/ui-dist/assets/{chunk-MOJQB5TN-Clfi83rK.js → chunk-MOJQB5TN-BEhQg0uD.js} +1 -1
  405. package/ui-dist/assets/{chunk-RYQCIY6F-BhZ6p7YJ.js → chunk-RYQCIY6F-HPJ6zRpJ.js} +1 -1
  406. package/ui-dist/assets/{chunk-V7JOEXUC-CdexJGoV.js → chunk-V7JOEXUC-Bl_6cAJD.js} +1 -1
  407. package/ui-dist/assets/{chunk-VR4S4FIN-8vjmBhr1.js → chunk-VR4S4FIN-KMjgGCsw.js} +1 -1
  408. package/ui-dist/assets/{chunk-XXDRQBXY-CqmCaplj.js → chunk-XXDRQBXY-oWGAIKjr.js} +1 -1
  409. package/ui-dist/assets/classDiagram-OUVF2IWQ-CTXxO5l9.js +1 -0
  410. package/ui-dist/assets/classDiagram-v2-EOCWNBFH-CTXxO5l9.js +1 -0
  411. package/ui-dist/assets/{cose-bilkent-JH36ORCC-CY-zAygY.js → cose-bilkent-JH36ORCC-Ckqse1pH.js} +1 -1
  412. package/ui-dist/assets/{cynefin-VYW2F7L2-BQSQ1HKr.js → cynefin-VYW2F7L2-DfZ8Hzqi.js} +1 -1
  413. package/ui-dist/assets/{cynefinDiagram-TSTJHNR4-NJCuFrZL.js → cynefinDiagram-TSTJHNR4-BkDQo9oi.js} +1 -1
  414. package/ui-dist/assets/{dagre-VKFMJZFB-DAUPIc8g.js → dagre-VKFMJZFB-ClghXQ6E.js} +1 -1
  415. package/ui-dist/assets/{diagram-FQU43EPY-DvMwJlCi.js → diagram-FQU43EPY-D5a0CwpV.js} +1 -1
  416. package/ui-dist/assets/{diagram-G47NLZAW-DPY0Jz_y.js → diagram-G47NLZAW-hVjYR_xl.js} +1 -1
  417. package/ui-dist/assets/{diagram-NH7WQ7WH-BpopeEhp.js → diagram-NH7WQ7WH-BlDPgD5Z.js} +1 -1
  418. package/ui-dist/assets/{diagram-OA4YK3LP-Qpu05z9X.js → diagram-OA4YK3LP-D0iZKIS3.js} +1 -1
  419. package/ui-dist/assets/{diagram-WEI45ONY-DHnvw9XU.js → diagram-WEI45ONY-m6hrfD0J.js} +1 -1
  420. package/ui-dist/assets/{ebnfDiagram-CCIWWBDH-D61S54_7.js → ebnfDiagram-CCIWWBDH-D4SQYLod.js} +1 -1
  421. package/ui-dist/assets/{erDiagram-Q63AITRT-pplAN_x2.js → erDiagram-Q63AITRT-Byzb6-I5.js} +1 -1
  422. package/ui-dist/assets/{flowDiagram-23GEKE2U-BaBcbyDq.js → flowDiagram-23GEKE2U-CaTUkFO6.js} +1 -1
  423. package/ui-dist/assets/{ganttDiagram-NO4QXBWP-BOJSII2b.js → ganttDiagram-NO4QXBWP-DmdMQ3ES.js} +1 -1
  424. package/ui-dist/assets/{gitGraphDiagram-IHSO6WYX-aYAaO4a2.js → gitGraphDiagram-IHSO6WYX-Bt-1g2CS.js} +1 -1
  425. package/ui-dist/assets/{index-CZxYajxF.js → index-2Dk9yO0W.js} +1 -1
  426. package/ui-dist/assets/{index-B8H0SHw1.js → index-8jLpgFNU.js} +1 -1
  427. package/ui-dist/assets/{index-3EKATXgc.js → index-AP_iimxs.js} +1 -1
  428. package/ui-dist/assets/{index-C2JgdjPa.js → index-BNJasQY9.js} +1 -1
  429. package/ui-dist/assets/{index-BaiskB3o.js → index-BO-aNmyX.js} +1 -1
  430. package/ui-dist/assets/{index-B5YenxAQ.js → index-BPCzCn1Y.js} +1 -1
  431. package/ui-dist/assets/{index-Da2kqT1M.js → index-BSLnLTb2.js} +1 -1
  432. package/ui-dist/assets/{index-By0oeEvz.js → index-CCZ2qgHN.js} +1 -1
  433. package/ui-dist/assets/{index-bUFCSEgv.js → index-CLZXR1k9.js} +1 -1
  434. package/ui-dist/assets/{index-CJlw4l9L.js → index-CTNfrE1s.js} +1 -1
  435. package/ui-dist/assets/{index-TmpY6Xh_.js → index-ChNd25s7.js} +1 -1
  436. package/ui-dist/assets/{index-BRgdHUNR.js → index-CjHiMOEO.js} +1 -1
  437. package/ui-dist/assets/{index-DrL6pHSJ.js → index-CmeJQpXZ.js} +1 -1
  438. package/ui-dist/assets/index-CyuYtn7U.css +1 -0
  439. package/ui-dist/assets/{index-CKKytnOd.js → index-CzZjM8eh.js} +1 -1
  440. package/ui-dist/assets/{index-Dceamza_.js → index-D-6T0Aft.js} +1 -1
  441. package/ui-dist/assets/{index-CjDqB1SX.js → index-DG_7V1pG.js} +1 -1
  442. package/ui-dist/assets/index-DIKcgxCt.js +676 -0
  443. package/ui-dist/assets/{index-BKVeJ3Jh.js → index-DiUerHmi.js} +1 -1
  444. package/ui-dist/assets/{index-C-nKjFZh.js → index-NZ7v5Fc2.js} +1 -1
  445. package/ui-dist/assets/{index-CvPPuNs1.js → index-Py70EvBg.js} +1 -1
  446. package/ui-dist/assets/{index-LHkZdu0h.js → index-R3aYn0qM.js} +1 -1
  447. package/ui-dist/assets/{index-BT8b79Bd.js → index-YXpm7gW-.js} +1 -1
  448. package/ui-dist/assets/{index-CemenVOf.js → index-n4q3gzki.js} +1 -1
  449. package/ui-dist/assets/{index-D3ODiUup.js → index-vlZ3GoYY.js} +1 -1
  450. package/ui-dist/assets/{infoDiagram-FWYZ7A6U-C7_90qGq.js → infoDiagram-FWYZ7A6U-jdi5ciVg.js} +1 -1
  451. package/ui-dist/assets/{ishikawaDiagram-FXEZZL3T-T-nPPdTt.js → ishikawaDiagram-FXEZZL3T-CMz5VvYp.js} +1 -1
  452. package/ui-dist/assets/{journeyDiagram-5HDEW3XC-C3hqQN0R.js → journeyDiagram-5HDEW3XC-DK6dk2R-.js} +1 -1
  453. package/ui-dist/assets/{kanban-definition-HUTT4EX6-CPoD9DUm.js → kanban-definition-HUTT4EX6-DX5cZL-D.js} +1 -1
  454. package/ui-dist/assets/{linear-D-S8yr3Z.js → linear-CI96ABKp.js} +1 -1
  455. package/ui-dist/assets/{mermaid.core-DhvH8shK.js → mermaid.core-DnsEVfbd.js} +4 -4
  456. package/ui-dist/assets/{mindmap-definition-LN4V7U3C-CxCIKrKo.js → mindmap-definition-LN4V7U3C-BdDCY7hf.js} +1 -1
  457. package/ui-dist/assets/{pegDiagram-2B236MQR-D4G-PC6N.js → pegDiagram-2B236MQR-DuY4TF-f.js} +1 -1
  458. package/ui-dist/assets/{pieDiagram-ENE6RG2P-N4X8UvqY.js → pieDiagram-ENE6RG2P-bgFw7dm3.js} +1 -1
  459. package/ui-dist/assets/{quadrantDiagram-ABIIQ3AL-CZohoDln.js → quadrantDiagram-ABIIQ3AL-BCZVWyWS.js} +1 -1
  460. package/ui-dist/assets/{railroadDiagram-RFXS5EU6-fMGQVhwF.js → railroadDiagram-RFXS5EU6-D9V5_Cgc.js} +1 -1
  461. package/ui-dist/assets/{requirementDiagram-TGXJPOKE-CK0IuUmk.js → requirementDiagram-TGXJPOKE-CItsya2r.js} +1 -1
  462. package/ui-dist/assets/{sankeyDiagram-HTMAVEWB-pSfb3CqG.js → sankeyDiagram-HTMAVEWB-Cz9IHsZO.js} +1 -1
  463. package/ui-dist/assets/{sequenceDiagram-DBY2YBRQ-CbhkqIeq.js → sequenceDiagram-DBY2YBRQ-hMSqTiwK.js} +1 -1
  464. package/ui-dist/assets/{sizeCapture-X5ZJPWSS-B6vqqPx-.js → sizeCapture-X5ZJPWSS-0g9M5wMf.js} +1 -1
  465. package/ui-dist/assets/{stateDiagram-2N3HPSRC-DIJf9h5C.js → stateDiagram-2N3HPSRC-F8_YhgWl.js} +1 -1
  466. package/ui-dist/assets/stateDiagram-v2-6OUMAXLB-fZImUBtq.js +1 -0
  467. package/ui-dist/assets/{swimlanes-5IMT3BWC-DIX_LV8O.js → swimlanes-5IMT3BWC-CCZqPbpE.js} +2 -2
  468. package/ui-dist/assets/swimlanesDiagram-G3AALYLV-9C1UT51R.js +8 -0
  469. package/ui-dist/assets/{timeline-definition-FHXFAJF6-CD-Pxb_g.js → timeline-definition-FHXFAJF6-BeUIr18x.js} +1 -1
  470. package/ui-dist/assets/{vennDiagram-L72KCM5P-BAZsWL0R.js → vennDiagram-L72KCM5P-D3d5h_G4.js} +1 -1
  471. package/ui-dist/assets/{wardleyDiagram-EHGQE667-CnNyfwX5.js → wardleyDiagram-EHGQE667-Bzt-As9A.js} +1 -1
  472. package/ui-dist/assets/{xychartDiagram-FW5EYKEG-j9YgsD3Y.js → xychartDiagram-FW5EYKEG-C2mly0xf.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 +1142 -5
  478. package/ui-dist/locales/zh-CN/common.json +1140 -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
@@ -1,22 +1,21 @@
1
1
  import { Router } from "express";
2
- import { catalogSkillListQuerySchema, companySkillCommentCreateSchema, companySkillCommentUpdateSchema, companySkillCreateSchema, companySkillFileUpdateSchema, companySkillForkSchema, companySkillImportSchema, companySkillInstallCatalogSchema, companySkillInstallUpdateSchema, companySkillListQuerySchema, companySkillProjectScanRequestSchema, companySkillResetSchema, companySkillUpdateSchema, companySkillVersionCreateSchema, } from "@penclipai/shared";
2
+ import { catalogSkillListQuerySchema, companySkillCommentCreateSchema, companySkillCommentUpdateSchema, companySkillCreateSchema, companySkillFileDeleteSchema, companySkillFileUpdateSchema, companySkillForkSchema, companySkillImportSchema, companySkillInstallCatalogSchema, companySkillInstallUpdateSchema, companySkillListQuerySchema, companySkillProjectScanRequestSchema, companySkillResetSchema, companySkillTestInputCreateSchema, companySkillTestInputUpdateSchema, companySkillTestRunTemplateCreateSchema, companySkillTestRunTemplateUpdateSchema, companySkillTestRunCreateSchema, companySkillTestRunListQuerySchema, companySkillUpdateSchema, companySkillVersionCreateSchema, } from "@penclipai/shared";
3
3
  import { trackSkillImported } from "@penclipai/shared/telemetry";
4
4
  import { validate } from "../middleware/validate.js";
5
- import { accessService, agentService, companySkillService, logActivity } from "../services/index.js";
5
+ import { accessService, agentService, companySkillService, heartbeatService, issueService, logActivity } from "../services/index.js";
6
6
  import { getCatalogSkillOrThrow, listCatalogSkillsOrEmpty, readCatalogSkillFile, } from "../services/skills-catalog.js";
7
- import { forbidden } from "../errors.js";
7
+ import { forbidden, HttpError } from "../errors.js";
8
8
  import { assertAuthenticated, assertCompanyAccess, getActorInfo } from "./authz.js";
9
9
  import { getTelemetryClient } from "../telemetry.js";
10
+ import { authorizationDeniedDetails } from "../services/authorization.js";
11
+ import { changeConsentGateService, skillChangeTargetKey, skillImportChangeTargetKey, skillSlugChangeTargetKey, skillsScanProjectsChangeTargetKey, } from "../services/change-consent-gate.js";
10
12
  export function companySkillRoutes(db) {
11
13
  const router = Router();
12
14
  const agents = agentService(db);
13
15
  const access = accessService(db);
14
16
  const svc = companySkillService(db);
15
- function canCreateSkills(agent) {
16
- if (!agent.permissions || typeof agent.permissions !== "object")
17
- return true;
18
- return agent.permissions.canCreateSkills !== false;
19
- }
17
+ const issues = issueService(db);
18
+ const heartbeat = heartbeatService(db);
20
19
  function asString(value) {
21
20
  if (typeof value !== "string")
22
21
  return null;
@@ -59,14 +58,70 @@ export function companySkillRoutes(db) {
59
58
  }
60
59
  return { type: "system" };
61
60
  }
62
- async function assertCanMutateCompanySkills(req, companyId) {
61
+ function skillMutationTargets(input) {
62
+ const targetKeys = [];
63
+ const skillId = asString(input.skillId);
64
+ const slug = asString(input.slug);
65
+ const source = asString(input.source);
66
+ const catalogSkillId = asString(input.catalogSkillId);
67
+ if (skillId)
68
+ targetKeys.push(skillChangeTargetKey(skillId));
69
+ if (slug)
70
+ targetKeys.push(skillSlugChangeTargetKey(slug));
71
+ if (source)
72
+ targetKeys.push(skillImportChangeTargetKey(source));
73
+ if (catalogSkillId)
74
+ targetKeys.push(skillImportChangeTargetKey(catalogSkillId));
75
+ if (input.scanProjects)
76
+ targetKeys.push(skillsScanProjectsChangeTargetKey());
77
+ return targetKeys;
78
+ }
79
+ async function assertCanMutateCompanySkills(req, companyId, targetKeys = []) {
80
+ assertCompanyAccess(req, companyId);
81
+ const decision = await access.decide({
82
+ actor: req.actor,
83
+ action: "skill_config:update",
84
+ resource: { type: "company", companyId },
85
+ });
86
+ if (decision.allowed) {
87
+ return;
88
+ }
89
+ if (decision.reason === "deny_missing_consent" && req.actor.type === "agent" && targetKeys.length > 0) {
90
+ try {
91
+ await changeConsentGateService(db).assertConsented({
92
+ companyId,
93
+ actorAgentId: req.actor.agentId,
94
+ actorRunId: req.actor.runId ?? null,
95
+ targetKeys,
96
+ });
97
+ }
98
+ catch (err) {
99
+ if (err instanceof HttpError && err.status === 403) {
100
+ throw forbidden(decision.explanation, authorizationDeniedDetails(decision));
101
+ }
102
+ throw err;
103
+ }
104
+ const consentedDecision = await access.decide({
105
+ actor: req.actor,
106
+ action: "skill_config:update",
107
+ resource: { type: "company", companyId },
108
+ scope: { consentedChange: true },
109
+ });
110
+ if (consentedDecision.allowed) {
111
+ return;
112
+ }
113
+ throw forbidden(consentedDecision.explanation, { reason: consentedDecision.reason });
114
+ }
115
+ throw forbidden(decision.explanation, { reason: decision.reason });
116
+ }
117
+ async function assertCanStartSkillTestRuns(req, companyId) {
63
118
  assertCompanyAccess(req, companyId);
64
119
  if (req.actor.type === "board") {
65
120
  if (req.actor.source === "local_implicit" || req.actor.isInstanceAdmin)
66
121
  return;
67
- const allowed = await access.canUser(companyId, req.actor.userId, "skills:create");
122
+ const allowed = await access.canUser(companyId, req.actor.userId, "tasks:assign");
68
123
  if (!allowed) {
69
- throw forbidden("Missing permission: skills:create");
124
+ throw forbidden("Missing permission: tasks:assign");
70
125
  }
71
126
  return;
72
127
  }
@@ -77,14 +132,10 @@ export function companySkillRoutes(db) {
77
132
  if (!actorAgent || actorAgent.companyId !== companyId) {
78
133
  throw forbidden("Agent key cannot access another company");
79
134
  }
80
- if (canCreateSkills(actorAgent)) {
81
- return;
82
- }
83
- const allowedByGrant = await access.hasPermission(companyId, "agent", actorAgent.id, "skills:create");
84
- if (allowedByGrant) {
85
- return;
135
+ const allowedByGrant = await access.hasPermission(companyId, "agent", actorAgent.id, "tasks:assign");
136
+ if (!allowedByGrant) {
137
+ throw forbidden("Missing permission: tasks:assign");
86
138
  }
87
- throw forbidden("Missing permission: skills:create");
88
139
  }
89
140
  router.get("/skills/catalog", async (req, res) => {
90
141
  assertAuthenticated(req);
@@ -118,6 +169,10 @@ export function companySkillRoutes(db) {
118
169
  ...queryStringArray(req.query["categories[]"]),
119
170
  ],
120
171
  scope: firstQueryString(req.query.scope),
172
+ include: [
173
+ ...queryStringArray(req.query.include),
174
+ ...queryStringArray(req.query["include[]"]),
175
+ ],
121
176
  }));
122
177
  res.json(result);
123
178
  });
@@ -137,6 +192,17 @@ export function companySkillRoutes(db) {
137
192
  }
138
193
  res.json(result);
139
194
  });
195
+ router.get("/companies/:companyId/skills/:skillId/fork-precheck", async (req, res) => {
196
+ const companyId = req.params.companyId;
197
+ const skillId = req.params.skillId;
198
+ assertCompanyAccess(req, companyId);
199
+ const result = await svc.forkPrecheck(companyId, skillId, skillActor(req));
200
+ if (!result) {
201
+ res.status(404).json({ error: "Skill not found" });
202
+ return;
203
+ }
204
+ res.json(result);
205
+ });
140
206
  router.get("/companies/:companyId/skills/:skillId/versions", async (req, res) => {
141
207
  const companyId = req.params.companyId;
142
208
  const skillId = req.params.skillId;
@@ -155,10 +221,332 @@ export function companySkillRoutes(db) {
155
221
  }
156
222
  res.json(result);
157
223
  });
158
- router.post("/companies/:companyId/skills/:skillId/versions", validate(companySkillVersionCreateSchema), async (req, res) => {
224
+ router.get("/companies/:companyId/skills/:skillId/test-inputs", async (req, res) => {
225
+ const companyId = req.params.companyId;
226
+ const skillId = req.params.skillId;
227
+ assertCompanyAccess(req, companyId);
228
+ res.json(await svc.listTestInputs(companyId, skillId));
229
+ });
230
+ router.post("/companies/:companyId/skills/:skillId/test-inputs", validate(companySkillTestInputCreateSchema), async (req, res) => {
231
+ const companyId = req.params.companyId;
232
+ const skillId = req.params.skillId;
233
+ await assertCanMutateCompanySkills(req, companyId);
234
+ const result = await svc.createTestInput(companyId, skillId, req.body, skillActor(req));
235
+ const actor = getActorInfo(req);
236
+ await logActivity(db, {
237
+ companyId,
238
+ actorType: actor.actorType,
239
+ actorId: actor.actorId,
240
+ agentId: actor.agentId,
241
+ runId: actor.runId,
242
+ action: "company.skill_test_input_created",
243
+ entityType: "company_skill_test_input",
244
+ entityId: result.id,
245
+ details: { skillId, name: result.name },
246
+ });
247
+ res.status(201).json(result);
248
+ });
249
+ router.patch("/companies/:companyId/skills/:skillId/test-inputs/:inputId", validate(companySkillTestInputUpdateSchema), async (req, res) => {
159
250
  const companyId = req.params.companyId;
160
251
  const skillId = req.params.skillId;
252
+ const inputId = req.params.inputId;
161
253
  await assertCanMutateCompanySkills(req, companyId);
254
+ const result = await svc.updateTestInput(companyId, skillId, inputId, req.body);
255
+ if (!result) {
256
+ res.status(404).json({ error: "Test input not found" });
257
+ return;
258
+ }
259
+ const actor = getActorInfo(req);
260
+ await logActivity(db, {
261
+ companyId,
262
+ actorType: actor.actorType,
263
+ actorId: actor.actorId,
264
+ agentId: actor.agentId,
265
+ runId: actor.runId,
266
+ action: "company.skill_test_input_updated",
267
+ entityType: "company_skill_test_input",
268
+ entityId: result.id,
269
+ details: { skillId, changedKeys: Object.keys(req.body).sort() },
270
+ });
271
+ res.json(result);
272
+ });
273
+ router.delete("/companies/:companyId/skills/:skillId/test-inputs/:inputId", async (req, res) => {
274
+ const companyId = req.params.companyId;
275
+ const skillId = req.params.skillId;
276
+ const inputId = req.params.inputId;
277
+ await assertCanMutateCompanySkills(req, companyId);
278
+ const result = await svc.deleteTestInput(companyId, skillId, inputId);
279
+ if (!result) {
280
+ res.status(404).json({ error: "Test input not found" });
281
+ return;
282
+ }
283
+ const actor = getActorInfo(req);
284
+ await logActivity(db, {
285
+ companyId,
286
+ actorType: actor.actorType,
287
+ actorId: actor.actorId,
288
+ agentId: actor.agentId,
289
+ runId: actor.runId,
290
+ action: "company.skill_test_input_deleted",
291
+ entityType: "company_skill_test_input",
292
+ entityId: result.id,
293
+ details: { skillId, name: result.name },
294
+ });
295
+ res.json(result);
296
+ });
297
+ router.get("/companies/:companyId/skill-test-run-templates", async (req, res) => {
298
+ const companyId = req.params.companyId;
299
+ assertCompanyAccess(req, companyId);
300
+ res.json(await svc.listTestRunTemplates(companyId));
301
+ });
302
+ router.post("/companies/:companyId/skill-test-run-templates", validate(companySkillTestRunTemplateCreateSchema), async (req, res) => {
303
+ const companyId = req.params.companyId;
304
+ await assertCanMutateCompanySkills(req, companyId);
305
+ const result = await svc.createTestRunTemplate(companyId, req.body, skillActor(req));
306
+ const actor = getActorInfo(req);
307
+ await logActivity(db, {
308
+ companyId,
309
+ actorType: actor.actorType,
310
+ actorId: actor.actorId,
311
+ agentId: actor.agentId,
312
+ runId: actor.runId,
313
+ action: "company.skill_test_run_template_created",
314
+ entityType: "company_skill_test_run_template",
315
+ entityId: result.id,
316
+ details: { name: result.name },
317
+ });
318
+ res.status(201).json(result);
319
+ });
320
+ router.patch("/companies/:companyId/skill-test-run-templates/:templateId", validate(companySkillTestRunTemplateUpdateSchema), async (req, res) => {
321
+ const companyId = req.params.companyId;
322
+ const templateId = req.params.templateId;
323
+ await assertCanMutateCompanySkills(req, companyId);
324
+ const result = await svc.updateTestRunTemplate(companyId, templateId, req.body, skillActor(req));
325
+ if (!result) {
326
+ res.status(404).json({ error: "Test run template not found" });
327
+ return;
328
+ }
329
+ const actor = getActorInfo(req);
330
+ await logActivity(db, {
331
+ companyId,
332
+ actorType: actor.actorType,
333
+ actorId: actor.actorId,
334
+ agentId: actor.agentId,
335
+ runId: actor.runId,
336
+ action: "company.skill_test_run_template_updated",
337
+ entityType: "company_skill_test_run_template",
338
+ entityId: result.id,
339
+ details: { changedKeys: Object.keys(req.body).sort() },
340
+ });
341
+ res.json(result);
342
+ });
343
+ router.delete("/companies/:companyId/skill-test-run-templates/:templateId", async (req, res) => {
344
+ const companyId = req.params.companyId;
345
+ const templateId = req.params.templateId;
346
+ await assertCanMutateCompanySkills(req, companyId);
347
+ const result = await svc.deleteTestRunTemplate(companyId, templateId);
348
+ if (!result) {
349
+ res.status(404).json({ error: "Test run template not found" });
350
+ return;
351
+ }
352
+ const actor = getActorInfo(req);
353
+ await logActivity(db, {
354
+ companyId,
355
+ actorType: actor.actorType,
356
+ actorId: actor.actorId,
357
+ agentId: actor.agentId,
358
+ runId: actor.runId,
359
+ action: "company.skill_test_run_template_deleted",
360
+ entityType: "company_skill_test_run_template",
361
+ entityId: result.id,
362
+ details: { name: result.name },
363
+ });
364
+ res.json(result);
365
+ });
366
+ router.get("/companies/:companyId/skills/:skillId/test-runs", async (req, res) => {
367
+ const companyId = req.params.companyId;
368
+ const skillId = req.params.skillId;
369
+ assertCompanyAccess(req, companyId);
370
+ const query = companySkillTestRunListQuerySchema.parse({
371
+ inputId: firstQueryString(req.query.inputId),
372
+ });
373
+ res.json(await svc.listTestRuns(companyId, skillId, query));
374
+ });
375
+ router.get("/companies/:companyId/skills/:skillId/test-runs/:runId", async (req, res) => {
376
+ const companyId = req.params.companyId;
377
+ const skillId = req.params.skillId;
378
+ const runId = req.params.runId;
379
+ assertCompanyAccess(req, companyId);
380
+ const result = await svc.getTestRunDetail(companyId, skillId, runId);
381
+ if (!result) {
382
+ res.status(404).json({ error: "Test run not found" });
383
+ return;
384
+ }
385
+ res.json(result);
386
+ });
387
+ router.post("/companies/:companyId/skills/:skillId/test-runs", validate(companySkillTestRunCreateSchema), async (req, res) => {
388
+ const companyId = req.params.companyId;
389
+ const skillId = req.params.skillId;
390
+ await assertCanStartSkillTestRuns(req, companyId);
391
+ const actor = getActorInfo(req);
392
+ const result = await svc.createTestRun(companyId, skillId, req.body, skillActor(req), {
393
+ createHarnessIssue: async (harnessIssue) => {
394
+ const created = await issues.create(companyId, {
395
+ ...harnessIssue,
396
+ priority: "medium",
397
+ createdByAgentId: actor.agentId,
398
+ createdByUserId: actor.actorType === "user" ? actor.actorId : null,
399
+ actorRunId: actor.runId,
400
+ });
401
+ await logActivity(db, {
402
+ companyId,
403
+ actorType: actor.actorType,
404
+ actorId: actor.actorId,
405
+ agentId: actor.agentId,
406
+ runId: actor.runId,
407
+ action: "issue.created",
408
+ entityType: "issue",
409
+ entityId: created.id,
410
+ details: {
411
+ title: created.title,
412
+ identifier: created.identifier,
413
+ harnessKind: "skill_test",
414
+ source: "company_skill_test_run",
415
+ skillId,
416
+ },
417
+ });
418
+ return { id: created.id };
419
+ },
420
+ wakeHarnessIssue: async (issueId, agentId) => heartbeat.wakeup(agentId, {
421
+ source: "assignment",
422
+ triggerDetail: "system",
423
+ reason: "skill_test_run_created",
424
+ payload: { issueId, skillId },
425
+ requestedByActorType: actor.actorType,
426
+ requestedByActorId: actor.actorId,
427
+ contextSnapshot: { issueId, source: "company.skill_test_run" },
428
+ }),
429
+ cleanupHarnessIssue: async (issueId) => {
430
+ const issue = await issues.getById(issueId);
431
+ if (!issue || issue.companyId !== companyId)
432
+ return;
433
+ await issues.update(issueId, {
434
+ status: "cancelled",
435
+ hiddenAt: new Date(),
436
+ actorAgentId: actor.agentId ?? null,
437
+ actorUserId: actor.actorType === "user" ? actor.actorId : null,
438
+ });
439
+ await logActivity(db, {
440
+ companyId,
441
+ actorType: actor.actorType,
442
+ actorId: actor.actorId,
443
+ agentId: actor.agentId,
444
+ runId: actor.runId,
445
+ action: "company.skill_test_harness_issue_cleaned_up",
446
+ entityType: "issue",
447
+ entityId: issueId,
448
+ details: { skillId },
449
+ });
450
+ },
451
+ });
452
+ await logActivity(db, {
453
+ companyId,
454
+ actorType: actor.actorType,
455
+ actorId: actor.actorId,
456
+ agentId: actor.agentId,
457
+ runId: actor.runId,
458
+ action: "company.skill_test_run_created",
459
+ entityType: "company_skill_test_run",
460
+ entityId: result.id,
461
+ details: {
462
+ skillId,
463
+ inputId: result.inputId,
464
+ skillVersionId: result.skillVersionId,
465
+ agentId: result.agentId,
466
+ issueId: result.issueId,
467
+ },
468
+ });
469
+ res.status(201).json(result);
470
+ });
471
+ router.post("/companies/:companyId/skills/:skillId/test-runs/:runId/cancel", async (req, res) => {
472
+ const companyId = req.params.companyId;
473
+ const skillId = req.params.skillId;
474
+ const runId = req.params.runId;
475
+ await assertCanStartSkillTestRuns(req, companyId);
476
+ const actor = getActorInfo(req);
477
+ const result = await svc.cancelTestRun(companyId, skillId, runId, {
478
+ cancelHarnessIssue: async (issueId) => {
479
+ const issue = await issues.getById(issueId);
480
+ if (!issue || issue.companyId !== companyId)
481
+ return;
482
+ if (issue.executionRunId) {
483
+ await heartbeat.cancelRun(issue.executionRunId, "Cancelled by skill test run request");
484
+ }
485
+ if (issue.status !== "done" && issue.status !== "cancelled") {
486
+ await issues.update(issueId, {
487
+ status: "cancelled",
488
+ actorAgentId: actor.agentId ?? null,
489
+ actorUserId: actor.actorType === "user" ? actor.actorId : null,
490
+ });
491
+ }
492
+ },
493
+ });
494
+ if (!result) {
495
+ res.status(404).json({ error: "Test run not found" });
496
+ return;
497
+ }
498
+ await logActivity(db, {
499
+ companyId,
500
+ actorType: actor.actorType,
501
+ actorId: actor.actorId,
502
+ agentId: actor.agentId,
503
+ runId: actor.runId,
504
+ action: "company.skill_test_run_cancelled",
505
+ entityType: "company_skill_test_run",
506
+ entityId: result.id,
507
+ details: { skillId, issueId: result.issueId },
508
+ });
509
+ res.json(result);
510
+ });
511
+ router.delete("/companies/:companyId/skills/:skillId/test-runs/:runId", async (req, res) => {
512
+ const companyId = req.params.companyId;
513
+ const skillId = req.params.skillId;
514
+ const runId = req.params.runId;
515
+ await assertCanStartSkillTestRuns(req, companyId);
516
+ const actor = getActorInfo(req);
517
+ const result = await svc.deleteTestRun(companyId, skillId, runId, {
518
+ hideHarnessIssue: async (issueId) => {
519
+ const issue = await issues.getById(issueId);
520
+ if (!issue || issue.companyId !== companyId)
521
+ return;
522
+ await issues.update(issueId, {
523
+ hiddenAt: new Date(),
524
+ actorAgentId: actor.agentId ?? null,
525
+ actorUserId: actor.actorType === "user" ? actor.actorId : null,
526
+ });
527
+ },
528
+ });
529
+ if (!result) {
530
+ res.status(404).json({ error: "Test run not found" });
531
+ return;
532
+ }
533
+ await logActivity(db, {
534
+ companyId,
535
+ actorType: actor.actorType,
536
+ actorId: actor.actorId,
537
+ agentId: actor.agentId,
538
+ runId: actor.runId,
539
+ action: "company.skill_test_run_deleted",
540
+ entityType: "company_skill_test_run",
541
+ entityId: result.id,
542
+ details: { skillId, issueId: result.issueId },
543
+ });
544
+ res.json(result);
545
+ });
546
+ router.post("/companies/:companyId/skills/:skillId/versions", validate(companySkillVersionCreateSchema), async (req, res) => {
547
+ const companyId = req.params.companyId;
548
+ const skillId = req.params.skillId;
549
+ await assertCanMutateCompanySkills(req, companyId, skillMutationTargets({ skillId }));
162
550
  const result = await svc.createVersion(companyId, skillId, req.body, skillActor(req));
163
551
  const actor = getActorInfo(req);
164
552
  await logActivity(db, {
@@ -219,7 +607,10 @@ export function companySkillRoutes(db) {
219
607
  router.post("/companies/:companyId/skills/:skillId/fork", validate(companySkillForkSchema), async (req, res) => {
220
608
  const companyId = req.params.companyId;
221
609
  const skillId = req.params.skillId;
222
- await assertCanMutateCompanySkills(req, companyId);
610
+ await assertCanMutateCompanySkills(req, companyId, skillMutationTargets({
611
+ skillId,
612
+ slug: req.body.slug,
613
+ }));
223
614
  const result = await svc.forkSkill(companyId, skillId, req.body, skillActor(req));
224
615
  const actor = getActorInfo(req);
225
616
  await logActivity(db, {
@@ -230,11 +621,12 @@ export function companySkillRoutes(db) {
230
621
  runId: actor.runId,
231
622
  action: "company.skill_forked",
232
623
  entityType: "company_skill",
233
- entityId: result.id,
624
+ entityId: result.skill.id,
234
625
  details: {
235
626
  sourceSkillId: skillId,
236
- slug: result.slug,
237
- name: result.name,
627
+ slug: result.skill.slug,
628
+ name: result.skill.name,
629
+ reassignedAgentIds: result.reassignments.map((entry) => entry.agentId),
238
630
  },
239
631
  });
240
632
  res.status(201).json(result);
@@ -329,7 +721,9 @@ export function companySkillRoutes(db) {
329
721
  });
330
722
  router.post("/companies/:companyId/skills", validate(companySkillCreateSchema), async (req, res) => {
331
723
  const companyId = req.params.companyId;
332
- await assertCanMutateCompanySkills(req, companyId);
724
+ await assertCanMutateCompanySkills(req, companyId, skillMutationTargets({
725
+ slug: req.body.slug,
726
+ }));
333
727
  const result = await svc.createLocalSkill(companyId, req.body, skillActor(req));
334
728
  const actor = getActorInfo(req);
335
729
  await logActivity(db, {
@@ -351,7 +745,7 @@ export function companySkillRoutes(db) {
351
745
  router.patch("/companies/:companyId/skills/:skillId", validate(companySkillUpdateSchema), async (req, res) => {
352
746
  const companyId = req.params.companyId;
353
747
  const skillId = req.params.skillId;
354
- await assertCanMutateCompanySkills(req, companyId);
748
+ await assertCanMutateCompanySkills(req, companyId, skillMutationTargets({ skillId }));
355
749
  const result = await svc.updateSkill(companyId, skillId, req.body);
356
750
  const actor = getActorInfo(req);
357
751
  await logActivity(db, {
@@ -374,7 +768,7 @@ export function companySkillRoutes(db) {
374
768
  router.patch("/companies/:companyId/skills/:skillId/files", validate(companySkillFileUpdateSchema), async (req, res) => {
375
769
  const companyId = req.params.companyId;
376
770
  const skillId = req.params.skillId;
377
- await assertCanMutateCompanySkills(req, companyId);
771
+ await assertCanMutateCompanySkills(req, companyId, skillMutationTargets({ skillId }));
378
772
  const result = await svc.updateFile(companyId, skillId, String(req.body.path ?? ""), String(req.body.content ?? ""), skillActor(req));
379
773
  const actor = getActorInfo(req);
380
774
  await logActivity(db, {
@@ -393,10 +787,33 @@ export function companySkillRoutes(db) {
393
787
  });
394
788
  res.json(result);
395
789
  });
396
- router.post("/companies/:companyId/skills/import", validate(companySkillImportSchema), async (req, res) => {
790
+ router.delete("/companies/:companyId/skills/:skillId/files", validate(companySkillFileDeleteSchema), async (req, res) => {
397
791
  const companyId = req.params.companyId;
792
+ const skillId = req.params.skillId;
398
793
  await assertCanMutateCompanySkills(req, companyId);
794
+ const result = await svc.deleteFile(companyId, skillId, req.body, skillActor(req));
795
+ const actor = getActorInfo(req);
796
+ await logActivity(db, {
797
+ companyId,
798
+ actorType: actor.actorType,
799
+ actorId: actor.actorId,
800
+ agentId: actor.agentId,
801
+ runId: actor.runId,
802
+ action: "company.skill_file_deleted",
803
+ entityType: "company_skill",
804
+ entityId: skillId,
805
+ details: {
806
+ path: result.path,
807
+ target: result.target,
808
+ deletedPaths: result.deletedPaths,
809
+ },
810
+ });
811
+ res.json(result);
812
+ });
813
+ router.post("/companies/:companyId/skills/import", validate(companySkillImportSchema), async (req, res) => {
814
+ const companyId = req.params.companyId;
399
815
  const source = String(req.body.source ?? "");
816
+ await assertCanMutateCompanySkills(req, companyId, skillMutationTargets({ source }));
400
817
  const result = await svc.importFromSource(companyId, source);
401
818
  const actor = getActorInfo(req);
402
819
  await logActivity(db, {
@@ -428,7 +845,10 @@ export function companySkillRoutes(db) {
428
845
  });
429
846
  router.post("/companies/:companyId/skills/install-catalog", validate(companySkillInstallCatalogSchema), async (req, res) => {
430
847
  const companyId = req.params.companyId;
431
- await assertCanMutateCompanySkills(req, companyId);
848
+ await assertCanMutateCompanySkills(req, companyId, skillMutationTargets({
849
+ catalogSkillId: req.body.catalogSkillId,
850
+ slug: req.body.slug,
851
+ }));
432
852
  const result = await svc.installFromCatalog(companyId, req.body);
433
853
  const actor = getActorInfo(req);
434
854
  await logActivity(db, {
@@ -453,7 +873,7 @@ export function companySkillRoutes(db) {
453
873
  });
454
874
  router.post("/companies/:companyId/skills/scan-projects", validate(companySkillProjectScanRequestSchema), async (req, res) => {
455
875
  const companyId = req.params.companyId;
456
- await assertCanMutateCompanySkills(req, companyId);
876
+ await assertCanMutateCompanySkills(req, companyId, skillMutationTargets({ scanProjects: true }));
457
877
  const result = await svc.scanProjectWorkspaces(companyId, req.body);
458
878
  const actor = getActorInfo(req);
459
879
  await logActivity(db, {
@@ -480,7 +900,7 @@ export function companySkillRoutes(db) {
480
900
  router.delete("/companies/:companyId/skills/:skillId", async (req, res) => {
481
901
  const companyId = req.params.companyId;
482
902
  const skillId = req.params.skillId;
483
- await assertCanMutateCompanySkills(req, companyId);
903
+ await assertCanMutateCompanySkills(req, companyId, skillMutationTargets({ skillId }));
484
904
  const result = await svc.deleteSkill(companyId, skillId);
485
905
  if (!result) {
486
906
  res.status(404).json({ error: "Skill not found" });
@@ -506,7 +926,7 @@ export function companySkillRoutes(db) {
506
926
  router.post("/companies/:companyId/skills/:skillId/audit", async (req, res) => {
507
927
  const companyId = req.params.companyId;
508
928
  const skillId = req.params.skillId;
509
- await assertCanMutateCompanySkills(req, companyId);
929
+ await assertCanMutateCompanySkills(req, companyId, skillMutationTargets({ skillId }));
510
930
  const result = await svc.auditSkill(companyId, skillId);
511
931
  if (!result) {
512
932
  res.status(404).json({ error: "Skill not found" });
@@ -535,7 +955,7 @@ export function companySkillRoutes(db) {
535
955
  router.post("/companies/:companyId/skills/:skillId/install-update", validate(companySkillInstallUpdateSchema), async (req, res) => {
536
956
  const companyId = req.params.companyId;
537
957
  const skillId = req.params.skillId;
538
- await assertCanMutateCompanySkills(req, companyId);
958
+ await assertCanMutateCompanySkills(req, companyId, skillMutationTargets({ skillId }));
539
959
  const before = await svc.getById(companyId, skillId);
540
960
  const result = await svc.installUpdate(companyId, skillId, req.body);
541
961
  if (!result) {
@@ -568,7 +988,7 @@ export function companySkillRoutes(db) {
568
988
  router.post("/companies/:companyId/skills/:skillId/reset", validate(companySkillResetSchema), async (req, res) => {
569
989
  const companyId = req.params.companyId;
570
990
  const skillId = req.params.skillId;
571
- await assertCanMutateCompanySkills(req, companyId);
991
+ await assertCanMutateCompanySkills(req, companyId, skillMutationTargets({ skillId }));
572
992
  const before = await svc.getById(companyId, skillId);
573
993
  const result = await svc.resetSkill(companyId, skillId, req.body);
574
994
  if (!result) {