@zmeel/server 0.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (772) hide show
  1. package/LICENSE +21 -0
  2. package/dist/adapters/codex-models.d.ts +4 -0
  3. package/dist/adapters/codex-models.d.ts.map +1 -0
  4. package/dist/adapters/codex-models.js +98 -0
  5. package/dist/adapters/codex-models.js.map +1 -0
  6. package/dist/adapters/cursor-models.d.ts +13 -0
  7. package/dist/adapters/cursor-models.d.ts.map +1 -0
  8. package/dist/adapters/cursor-models.js +148 -0
  9. package/dist/adapters/cursor-models.js.map +1 -0
  10. package/dist/adapters/http/execute.d.ts +3 -0
  11. package/dist/adapters/http/execute.d.ts.map +1 -0
  12. package/dist/adapters/http/execute.js +39 -0
  13. package/dist/adapters/http/execute.js.map +1 -0
  14. package/dist/adapters/http/index.d.ts +3 -0
  15. package/dist/adapters/http/index.d.ts.map +1 -0
  16. package/dist/adapters/http/index.js +20 -0
  17. package/dist/adapters/http/index.js.map +1 -0
  18. package/dist/adapters/http/test.d.ts +3 -0
  19. package/dist/adapters/http/test.d.ts.map +1 -0
  20. package/dist/adapters/http/test.js +106 -0
  21. package/dist/adapters/http/test.js.map +1 -0
  22. package/dist/adapters/index.d.ts +4 -0
  23. package/dist/adapters/index.d.ts.map +1 -0
  24. package/dist/adapters/index.js +3 -0
  25. package/dist/adapters/index.js.map +1 -0
  26. package/dist/adapters/process/execute.d.ts +3 -0
  27. package/dist/adapters/process/execute.d.ts.map +1 -0
  28. package/dist/adapters/process/execute.js +70 -0
  29. package/dist/adapters/process/execute.js.map +1 -0
  30. package/dist/adapters/process/index.d.ts +3 -0
  31. package/dist/adapters/process/index.d.ts.map +1 -0
  32. package/dist/adapters/process/index.js +23 -0
  33. package/dist/adapters/process/index.js.map +1 -0
  34. package/dist/adapters/process/test.d.ts +3 -0
  35. package/dist/adapters/process/test.d.ts.map +1 -0
  36. package/dist/adapters/process/test.js +77 -0
  37. package/dist/adapters/process/test.js.map +1 -0
  38. package/dist/adapters/registry.d.ts +14 -0
  39. package/dist/adapters/registry.d.ts.map +1 -0
  40. package/dist/adapters/registry.js +164 -0
  41. package/dist/adapters/registry.js.map +1 -0
  42. package/dist/adapters/types.d.ts +2 -0
  43. package/dist/adapters/types.d.ts.map +1 -0
  44. package/dist/adapters/types.js +2 -0
  45. package/dist/adapters/types.js.map +1 -0
  46. package/dist/adapters/utils.d.ts +41 -0
  47. package/dist/adapters/utils.d.ts.map +1 -0
  48. package/dist/adapters/utils.js +51 -0
  49. package/dist/adapters/utils.js.map +1 -0
  50. package/dist/agent-auth-jwt.d.ts +14 -0
  51. package/dist/agent-auth-jwt.d.ts.map +1 -0
  52. package/dist/agent-auth-jwt.js +117 -0
  53. package/dist/agent-auth-jwt.js.map +1 -0
  54. package/dist/app.d.ts +32 -0
  55. package/dist/app.d.ts.map +1 -0
  56. package/dist/app.js +281 -0
  57. package/dist/app.js.map +1 -0
  58. package/dist/attachment-types.d.ts +33 -0
  59. package/dist/attachment-types.d.ts.map +1 -0
  60. package/dist/attachment-types.js +67 -0
  61. package/dist/attachment-types.js.map +1 -0
  62. package/dist/auth/better-auth.d.ts +24 -0
  63. package/dist/auth/better-auth.d.ts.map +1 -0
  64. package/dist/auth/better-auth.js +108 -0
  65. package/dist/auth/better-auth.js.map +1 -0
  66. package/dist/board-claim.d.ts +23 -0
  67. package/dist/board-claim.d.ts.map +1 -0
  68. package/dist/board-claim.js +115 -0
  69. package/dist/board-claim.js.map +1 -0
  70. package/dist/config-file.d.ts +3 -0
  71. package/dist/config-file.d.ts.map +1 -0
  72. package/dist/config-file.js +16 -0
  73. package/dist/config-file.js.map +1 -0
  74. package/dist/config.d.ts +41 -0
  75. package/dist/config.d.ts.map +1 -0
  76. package/dist/config.js +173 -0
  77. package/dist/config.js.map +1 -0
  78. package/dist/dev-server-status.d.ts +27 -0
  79. package/dist/dev-server-status.d.ts.map +1 -0
  80. package/dist/dev-server-status.js +70 -0
  81. package/dist/dev-server-status.js.map +1 -0
  82. package/dist/dev-watch-ignore.d.ts +2 -0
  83. package/dist/dev-watch-ignore.d.ts.map +1 -0
  84. package/dist/dev-watch-ignore.js +33 -0
  85. package/dist/dev-watch-ignore.js.map +1 -0
  86. package/dist/errors.d.ts +12 -0
  87. package/dist/errors.d.ts.map +1 -0
  88. package/dist/errors.js +28 -0
  89. package/dist/errors.js.map +1 -0
  90. package/dist/home-paths.d.ts +17 -0
  91. package/dist/home-paths.d.ts.map +1 -0
  92. package/dist/home-paths.js +75 -0
  93. package/dist/home-paths.js.map +1 -0
  94. package/dist/index.d.ts +10 -0
  95. package/dist/index.d.ts.map +1 -0
  96. package/dist/index.js +627 -0
  97. package/dist/index.js.map +1 -0
  98. package/dist/log-redaction.d.ts +11 -0
  99. package/dist/log-redaction.d.ts.map +1 -0
  100. package/dist/log-redaction.js +118 -0
  101. package/dist/log-redaction.js.map +1 -0
  102. package/dist/middleware/auth.d.ts +12 -0
  103. package/dist/middleware/auth.d.ts.map +1 -0
  104. package/dist/middleware/auth.js +144 -0
  105. package/dist/middleware/auth.js.map +1 -0
  106. package/dist/middleware/board-mutation-guard.d.ts +3 -0
  107. package/dist/middleware/board-mutation-guard.d.ts.map +1 -0
  108. package/dist/middleware/board-mutation-guard.js +60 -0
  109. package/dist/middleware/board-mutation-guard.js.map +1 -0
  110. package/dist/middleware/error-handler.d.ts +17 -0
  111. package/dist/middleware/error-handler.d.ts.map +1 -0
  112. package/dist/middleware/error-handler.js +45 -0
  113. package/dist/middleware/error-handler.js.map +1 -0
  114. package/dist/middleware/index.d.ts +4 -0
  115. package/dist/middleware/index.d.ts.map +1 -0
  116. package/dist/middleware/index.js +4 -0
  117. package/dist/middleware/index.js.map +1 -0
  118. package/dist/middleware/logger.d.ts +4 -0
  119. package/dist/middleware/logger.d.ts.map +1 -0
  120. package/dist/middleware/logger.js +87 -0
  121. package/dist/middleware/logger.js.map +1 -0
  122. package/dist/middleware/private-hostname-guard.d.ts +11 -0
  123. package/dist/middleware/private-hostname-guard.d.ts.map +1 -0
  124. package/dist/middleware/private-hostname-guard.js +78 -0
  125. package/dist/middleware/private-hostname-guard.js.map +1 -0
  126. package/dist/middleware/validate.d.ts +4 -0
  127. package/dist/middleware/validate.d.ts.map +1 -0
  128. package/dist/middleware/validate.js +7 -0
  129. package/dist/middleware/validate.js.map +1 -0
  130. package/dist/onboarding-assets/ceo/AGENTS.md +54 -0
  131. package/dist/onboarding-assets/ceo/HEARTBEAT.md +72 -0
  132. package/dist/onboarding-assets/ceo/SOUL.md +33 -0
  133. package/dist/onboarding-assets/ceo/TOOLS.md +3 -0
  134. package/dist/onboarding-assets/default/AGENTS.md +3 -0
  135. package/dist/paths.d.ts +3 -0
  136. package/dist/paths.d.ts.map +1 -0
  137. package/dist/paths.js +31 -0
  138. package/dist/paths.js.map +1 -0
  139. package/dist/realtime/live-events-ws.d.ts +28 -0
  140. package/dist/realtime/live-events-ws.d.ts.map +1 -0
  141. package/dist/realtime/live-events-ws.js +187 -0
  142. package/dist/realtime/live-events-ws.js.map +1 -0
  143. package/dist/redaction.d.ts +4 -0
  144. package/dist/redaction.d.ts.map +1 -0
  145. package/dist/redaction.js +63 -0
  146. package/dist/redaction.js.map +1 -0
  147. package/dist/routes/access.d.ts +62 -0
  148. package/dist/routes/access.d.ts.map +1 -0
  149. package/dist/routes/access.js +2296 -0
  150. package/dist/routes/access.js.map +1 -0
  151. package/dist/routes/activity.d.ts +3 -0
  152. package/dist/routes/activity.d.ts.map +1 -0
  153. package/dist/routes/activity.js +78 -0
  154. package/dist/routes/activity.js.map +1 -0
  155. package/dist/routes/agents.d.ts +3 -0
  156. package/dist/routes/agents.d.ts.map +1 -0
  157. package/dist/routes/agents.js +1918 -0
  158. package/dist/routes/agents.js.map +1 -0
  159. package/dist/routes/approvals.d.ts +3 -0
  160. package/dist/routes/approvals.d.ts.map +1 -0
  161. package/dist/routes/approvals.js +275 -0
  162. package/dist/routes/approvals.js.map +1 -0
  163. package/dist/routes/assets.d.ts +4 -0
  164. package/dist/routes/assets.d.ts.map +1 -0
  165. package/dist/routes/assets.js +309 -0
  166. package/dist/routes/assets.js.map +1 -0
  167. package/dist/routes/authz.d.ts +16 -0
  168. package/dist/routes/authz.d.ts.map +1 -0
  169. package/dist/routes/authz.js +47 -0
  170. package/dist/routes/authz.js.map +1 -0
  171. package/dist/routes/companies.d.ts +4 -0
  172. package/dist/routes/companies.d.ts.map +1 -0
  173. package/dist/routes/companies.js +356 -0
  174. package/dist/routes/companies.js.map +1 -0
  175. package/dist/routes/company-skills.d.ts +3 -0
  176. package/dist/routes/company-skills.d.ts.map +1 -0
  177. package/dist/routes/company-skills.js +228 -0
  178. package/dist/routes/company-skills.js.map +1 -0
  179. package/dist/routes/costs.d.ts +3 -0
  180. package/dist/routes/costs.d.ts.map +1 -0
  181. package/dist/routes/costs.js +268 -0
  182. package/dist/routes/costs.js.map +1 -0
  183. package/dist/routes/dashboard.d.ts +3 -0
  184. package/dist/routes/dashboard.d.ts.map +1 -0
  185. package/dist/routes/dashboard.js +15 -0
  186. package/dist/routes/dashboard.js.map +1 -0
  187. package/dist/routes/execution-workspaces.d.ts +3 -0
  188. package/dist/routes/execution-workspaces.d.ts.map +1 -0
  189. package/dist/routes/execution-workspaces.js +367 -0
  190. package/dist/routes/execution-workspaces.js.map +1 -0
  191. package/dist/routes/goals.d.ts +3 -0
  192. package/dist/routes/goals.d.ts.map +1 -0
  193. package/dist/routes/goals.js +95 -0
  194. package/dist/routes/goals.js.map +1 -0
  195. package/dist/routes/health.d.ts +9 -0
  196. package/dist/routes/health.d.ts.map +1 -0
  197. package/dist/routes/health.js +80 -0
  198. package/dist/routes/health.js.map +1 -0
  199. package/dist/routes/index.d.ts +18 -0
  200. package/dist/routes/index.d.ts.map +1 -0
  201. package/dist/routes/index.js +18 -0
  202. package/dist/routes/index.js.map +1 -0
  203. package/dist/routes/instance-settings.d.ts +3 -0
  204. package/dist/routes/instance-settings.d.ts.map +1 -0
  205. package/dist/routes/instance-settings.js +79 -0
  206. package/dist/routes/instance-settings.js.map +1 -0
  207. package/dist/routes/issues-checkout-wakeup.d.ts +9 -0
  208. package/dist/routes/issues-checkout-wakeup.d.ts.map +1 -0
  209. package/dist/routes/issues-checkout-wakeup.js +12 -0
  210. package/dist/routes/issues-checkout-wakeup.js.map +1 -0
  211. package/dist/routes/issues.d.ts +4 -0
  212. package/dist/routes/issues.d.ts.map +1 -0
  213. package/dist/routes/issues.js +1834 -0
  214. package/dist/routes/issues.js.map +1 -0
  215. package/dist/routes/llms.d.ts +3 -0
  216. package/dist/routes/llms.d.ts.map +1 -0
  217. package/dist/routes/llms.js +78 -0
  218. package/dist/routes/llms.js.map +1 -0
  219. package/dist/routes/org-chart-svg.d.ts +25 -0
  220. package/dist/routes/org-chart-svg.d.ts.map +1 -0
  221. package/dist/routes/org-chart-svg.js +656 -0
  222. package/dist/routes/org-chart-svg.js.map +1 -0
  223. package/dist/routes/plugin-ui-static.d.ts +69 -0
  224. package/dist/routes/plugin-ui-static.d.ts.map +1 -0
  225. package/dist/routes/plugin-ui-static.js +411 -0
  226. package/dist/routes/plugin-ui-static.js.map +1 -0
  227. package/dist/routes/plugins.d.ts +120 -0
  228. package/dist/routes/plugins.d.ts.map +1 -0
  229. package/dist/routes/plugins.js +1784 -0
  230. package/dist/routes/plugins.js.map +1 -0
  231. package/dist/routes/projects.d.ts +3 -0
  232. package/dist/routes/projects.d.ts.map +1 -0
  233. package/dist/routes/projects.js +386 -0
  234. package/dist/routes/projects.js.map +1 -0
  235. package/dist/routes/routines.d.ts +3 -0
  236. package/dist/routes/routines.d.ts.map +1 -0
  237. package/dist/routes/routines.js +277 -0
  238. package/dist/routes/routines.js.map +1 -0
  239. package/dist/routes/secrets.d.ts +3 -0
  240. package/dist/routes/secrets.d.ts.map +1 -0
  241. package/dist/routes/secrets.js +128 -0
  242. package/dist/routes/secrets.js.map +1 -0
  243. package/dist/routes/sidebar-badges.d.ts +3 -0
  244. package/dist/routes/sidebar-badges.d.ts.map +1 -0
  245. package/dist/routes/sidebar-badges.js +45 -0
  246. package/dist/routes/sidebar-badges.js.map +1 -0
  247. package/dist/secrets/external-stub-providers.d.ts +5 -0
  248. package/dist/secrets/external-stub-providers.d.ts.map +1 -0
  249. package/dist/secrets/external-stub-providers.js +21 -0
  250. package/dist/secrets/external-stub-providers.js.map +1 -0
  251. package/dist/secrets/local-encrypted-provider.d.ts +3 -0
  252. package/dist/secrets/local-encrypted-provider.d.ts.map +1 -0
  253. package/dist/secrets/local-encrypted-provider.js +116 -0
  254. package/dist/secrets/local-encrypted-provider.js.map +1 -0
  255. package/dist/secrets/provider-registry.d.ts +5 -0
  256. package/dist/secrets/provider-registry.d.ts.map +1 -0
  257. package/dist/secrets/provider-registry.js +20 -0
  258. package/dist/secrets/provider-registry.js.map +1 -0
  259. package/dist/secrets/types.d.ts +21 -0
  260. package/dist/secrets/types.d.ts.map +1 -0
  261. package/dist/secrets/types.js +2 -0
  262. package/dist/secrets/types.js.map +1 -0
  263. package/dist/services/access.d.ts +113 -0
  264. package/dist/services/access.d.ts.map +1 -0
  265. package/dist/services/access.js +247 -0
  266. package/dist/services/access.js.map +1 -0
  267. package/dist/services/activity-log.d.ts +17 -0
  268. package/dist/services/activity-log.d.ts.map +1 -0
  269. package/dist/services/activity-log.js +74 -0
  270. package/dist/services/activity-log.js.map +1 -0
  271. package/dist/services/activity.d.ts +764 -0
  272. package/dist/services/activity.d.ts.map +1 -0
  273. package/dist/services/activity.js +105 -0
  274. package/dist/services/activity.js.map +1 -0
  275. package/dist/services/agent-instructions.d.ts +91 -0
  276. package/dist/services/agent-instructions.d.ts.map +1 -0
  277. package/dist/services/agent-instructions.js +580 -0
  278. package/dist/services/agent-instructions.js.map +1 -0
  279. package/dist/services/agent-permissions.d.ts +6 -0
  280. package/dist/services/agent-permissions.d.ts.map +1 -0
  281. package/dist/services/agent-permissions.js +18 -0
  282. package/dist/services/agent-permissions.js.map +1 -0
  283. package/dist/services/agents.d.ts +1670 -0
  284. package/dist/services/agents.d.ts.map +1 -0
  285. package/dist/services/agents.js +566 -0
  286. package/dist/services/agents.js.map +1 -0
  287. package/dist/services/approvals.d.ts +546 -0
  288. package/dist/services/approvals.d.ts.map +1 -0
  289. package/dist/services/approvals.js +212 -0
  290. package/dist/services/approvals.js.map +1 -0
  291. package/dist/services/assets.d.ts +33 -0
  292. package/dist/services/assets.d.ts.map +1 -0
  293. package/dist/services/assets.js +17 -0
  294. package/dist/services/assets.js.map +1 -0
  295. package/dist/services/board-auth.d.ts +234 -0
  296. package/dist/services/board-auth.d.ts.map +1 -0
  297. package/dist/services/board-auth.js +295 -0
  298. package/dist/services/board-auth.js.map +1 -0
  299. package/dist/services/budgets.d.ts +38 -0
  300. package/dist/services/budgets.d.ts.map +1 -0
  301. package/dist/services/budgets.js +784 -0
  302. package/dist/services/budgets.js.map +1 -0
  303. package/dist/services/companies.d.ts +148 -0
  304. package/dist/services/companies.d.ts.map +1 -0
  305. package/dist/services/companies.js +260 -0
  306. package/dist/services/companies.js.map +1 -0
  307. package/dist/services/company-export-readme.d.ts +17 -0
  308. package/dist/services/company-export-readme.d.ts.map +1 -0
  309. package/dist/services/company-export-readme.js +148 -0
  310. package/dist/services/company-export-readme.js.map +1 -0
  311. package/dist/services/company-portability.d.ts +24 -0
  312. package/dist/services/company-portability.d.ts.map +1 -0
  313. package/dist/services/company-portability.js +3807 -0
  314. package/dist/services/company-portability.js.map +1 -0
  315. package/dist/services/company-skills.d.ts +77 -0
  316. package/dist/services/company-skills.d.ts.map +1 -0
  317. package/dist/services/company-skills.js +2063 -0
  318. package/dist/services/company-skills.js.map +1 -0
  319. package/dist/services/costs.d.ts +114 -0
  320. package/dist/services/costs.d.ts.map +1 -0
  321. package/dist/services/costs.js +294 -0
  322. package/dist/services/costs.js.map +1 -0
  323. package/dist/services/cron.d.ts +80 -0
  324. package/dist/services/cron.d.ts.map +1 -0
  325. package/dist/services/cron.js +300 -0
  326. package/dist/services/cron.js.map +1 -0
  327. package/dist/services/dashboard.d.ts +26 -0
  328. package/dist/services/dashboard.d.ts.map +1 -0
  329. package/dist/services/dashboard.js +98 -0
  330. package/dist/services/dashboard.js.map +1 -0
  331. package/dist/services/default-agent-instructions.d.ts +9 -0
  332. package/dist/services/default-agent-instructions.d.ts.map +1 -0
  333. package/dist/services/default-agent-instructions.js +20 -0
  334. package/dist/services/default-agent-instructions.js.map +1 -0
  335. package/dist/services/documents.d.ts +195 -0
  336. package/dist/services/documents.d.ts.map +1 -0
  337. package/dist/services/documents.js +409 -0
  338. package/dist/services/documents.js.map +1 -0
  339. package/dist/services/execution-workspace-policy.d.ts +21 -0
  340. package/dist/services/execution-workspace-policy.d.ts.map +1 -0
  341. package/dist/services/execution-workspace-policy.js +177 -0
  342. package/dist/services/execution-workspace-policy.js.map +1 -0
  343. package/dist/services/execution-workspaces.d.ts +22 -0
  344. package/dist/services/execution-workspaces.d.ts.map +1 -0
  345. package/dist/services/execution-workspaces.js +551 -0
  346. package/dist/services/execution-workspaces.js.map +1 -0
  347. package/dist/services/feedback-redaction.d.ts +23 -0
  348. package/dist/services/feedback-redaction.d.ts.map +1 -0
  349. package/dist/services/feedback-redaction.js +150 -0
  350. package/dist/services/feedback-redaction.js.map +1 -0
  351. package/dist/services/feedback-share-client.d.ts +9 -0
  352. package/dist/services/feedback-share-client.d.ts.map +1 -0
  353. package/dist/services/feedback-share-client.js +42 -0
  354. package/dist/services/feedback-share-client.js.map +1 -0
  355. package/dist/services/feedback.d.ts +91 -0
  356. package/dist/services/feedback.d.ts.map +1 -0
  357. package/dist/services/feedback.js +1662 -0
  358. package/dist/services/feedback.js.map +1 -0
  359. package/dist/services/finance.d.ts +93 -0
  360. package/dist/services/finance.d.ts.map +1 -0
  361. package/dist/services/finance.js +120 -0
  362. package/dist/services/finance.js.map +1 -0
  363. package/dist/services/github-fetch.d.ts +4 -0
  364. package/dist/services/github-fetch.d.ts.map +1 -0
  365. package/dist/services/github-fetch.js +23 -0
  366. package/dist/services/github-fetch.js.map +1 -0
  367. package/dist/services/goals.d.ts +433 -0
  368. package/dist/services/goals.d.ts.map +1 -0
  369. package/dist/services/goals.js +54 -0
  370. package/dist/services/goals.js.map +1 -0
  371. package/dist/services/heartbeat-run-summary.d.ts +2 -0
  372. package/dist/services/heartbeat-run-summary.d.ts.map +1 -0
  373. package/dist/services/heartbeat-run-summary.js +30 -0
  374. package/dist/services/heartbeat-run-summary.js.map +1 -0
  375. package/dist/services/heartbeat.d.ts +839 -0
  376. package/dist/services/heartbeat.d.ts.map +1 -0
  377. package/dist/services/heartbeat.js +3287 -0
  378. package/dist/services/heartbeat.js.map +1 -0
  379. package/dist/services/hire-hook.d.ts +14 -0
  380. package/dist/services/hire-hook.d.ts.map +1 -0
  381. package/dist/services/hire-hook.js +85 -0
  382. package/dist/services/hire-hook.js.map +1 -0
  383. package/dist/services/index.d.ts +34 -0
  384. package/dist/services/index.d.ts.map +1 -0
  385. package/dist/services/index.js +34 -0
  386. package/dist/services/index.js.map +1 -0
  387. package/dist/services/instance-settings.d.ts +11 -0
  388. package/dist/services/instance-settings.d.ts.map +1 -0
  389. package/dist/services/instance-settings.js +120 -0
  390. package/dist/services/instance-settings.js.map +1 -0
  391. package/dist/services/issue-approvals.d.ts +56 -0
  392. package/dist/services/issue-approvals.d.ts.map +1 -0
  393. package/dist/services/issue-approvals.js +153 -0
  394. package/dist/services/issue-approvals.js.map +1 -0
  395. package/dist/services/issue-assignment-wakeup.d.ts +29 -0
  396. package/dist/services/issue-assignment-wakeup.d.ts.map +1 -0
  397. package/dist/services/issue-assignment-wakeup.js +22 -0
  398. package/dist/services/issue-assignment-wakeup.js.map +1 -0
  399. package/dist/services/issue-goal-fallback.d.ts +18 -0
  400. package/dist/services/issue-goal-fallback.d.ts.map +1 -0
  401. package/dist/services/issue-goal-fallback.js +33 -0
  402. package/dist/services/issue-goal-fallback.js.map +1 -0
  403. package/dist/services/issues.d.ts +568 -0
  404. package/dist/services/issues.d.ts.map +1 -0
  405. package/dist/services/issues.js +1671 -0
  406. package/dist/services/issues.js.map +1 -0
  407. package/dist/services/live-events.d.ts +17 -0
  408. package/dist/services/live-events.d.ts.map +1 -0
  409. package/dist/services/live-events.js +33 -0
  410. package/dist/services/live-events.js.map +1 -0
  411. package/dist/services/local-service-supervisor.d.ts +55 -0
  412. package/dist/services/local-service-supervisor.d.ts.map +1 -0
  413. package/dist/services/local-service-supervisor.js +240 -0
  414. package/dist/services/local-service-supervisor.js.map +1 -0
  415. package/dist/services/plugin-capability-validator.d.ts +108 -0
  416. package/dist/services/plugin-capability-validator.d.ts.map +1 -0
  417. package/dist/services/plugin-capability-validator.js +269 -0
  418. package/dist/services/plugin-capability-validator.js.map +1 -0
  419. package/dist/services/plugin-config-validator.d.ts +26 -0
  420. package/dist/services/plugin-config-validator.d.ts.map +1 -0
  421. package/dist/services/plugin-config-validator.js +41 -0
  422. package/dist/services/plugin-config-validator.js.map +1 -0
  423. package/dist/services/plugin-dev-watcher.d.ts +30 -0
  424. package/dist/services/plugin-dev-watcher.d.ts.map +1 -0
  425. package/dist/services/plugin-dev-watcher.js +241 -0
  426. package/dist/services/plugin-dev-watcher.js.map +1 -0
  427. package/dist/services/plugin-event-bus.d.ts +149 -0
  428. package/dist/services/plugin-event-bus.d.ts.map +1 -0
  429. package/dist/services/plugin-event-bus.js +258 -0
  430. package/dist/services/plugin-event-bus.js.map +1 -0
  431. package/dist/services/plugin-host-service-cleanup.d.ts +14 -0
  432. package/dist/services/plugin-host-service-cleanup.d.ts.map +1 -0
  433. package/dist/services/plugin-host-service-cleanup.js +37 -0
  434. package/dist/services/plugin-host-service-cleanup.js.map +1 -0
  435. package/dist/services/plugin-host-services.d.ts +13 -0
  436. package/dist/services/plugin-host-services.d.ts.map +1 -0
  437. package/dist/services/plugin-host-services.js +983 -0
  438. package/dist/services/plugin-host-services.js.map +1 -0
  439. package/dist/services/plugin-job-coordinator.d.ts +81 -0
  440. package/dist/services/plugin-job-coordinator.d.ts.map +1 -0
  441. package/dist/services/plugin-job-coordinator.js +172 -0
  442. package/dist/services/plugin-job-coordinator.js.map +1 -0
  443. package/dist/services/plugin-job-scheduler.d.ts +163 -0
  444. package/dist/services/plugin-job-scheduler.d.ts.map +1 -0
  445. package/dist/services/plugin-job-scheduler.js +454 -0
  446. package/dist/services/plugin-job-scheduler.js.map +1 -0
  447. package/dist/services/plugin-job-store.d.ts +208 -0
  448. package/dist/services/plugin-job-store.d.ts.map +1 -0
  449. package/dist/services/plugin-job-store.js +350 -0
  450. package/dist/services/plugin-job-store.js.map +1 -0
  451. package/dist/services/plugin-lifecycle.d.ts +203 -0
  452. package/dist/services/plugin-lifecycle.d.ts.map +1 -0
  453. package/dist/services/plugin-lifecycle.js +476 -0
  454. package/dist/services/plugin-lifecycle.js.map +1 -0
  455. package/dist/services/plugin-loader.d.ts +441 -0
  456. package/dist/services/plugin-loader.d.ts.map +1 -0
  457. package/dist/services/plugin-loader.js +1192 -0
  458. package/dist/services/plugin-loader.js.map +1 -0
  459. package/dist/services/plugin-log-retention.d.ts +20 -0
  460. package/dist/services/plugin-log-retention.d.ts.map +1 -0
  461. package/dist/services/plugin-log-retention.js +63 -0
  462. package/dist/services/plugin-log-retention.js.map +1 -0
  463. package/dist/services/plugin-manifest-validator.d.ts +79 -0
  464. package/dist/services/plugin-manifest-validator.d.ts.map +1 -0
  465. package/dist/services/plugin-manifest-validator.js +84 -0
  466. package/dist/services/plugin-manifest-validator.js.map +1 -0
  467. package/dist/services/plugin-registry.d.ts +2542 -0
  468. package/dist/services/plugin-registry.d.ts.map +1 -0
  469. package/dist/services/plugin-registry.js +539 -0
  470. package/dist/services/plugin-registry.js.map +1 -0
  471. package/dist/services/plugin-runtime-sandbox.d.ts +40 -0
  472. package/dist/services/plugin-runtime-sandbox.d.ts.map +1 -0
  473. package/dist/services/plugin-runtime-sandbox.js +154 -0
  474. package/dist/services/plugin-runtime-sandbox.js.map +1 -0
  475. package/dist/services/plugin-secrets-handler.d.ts +81 -0
  476. package/dist/services/plugin-secrets-handler.d.ts.map +1 -0
  477. package/dist/services/plugin-secrets-handler.js +275 -0
  478. package/dist/services/plugin-secrets-handler.js.map +1 -0
  479. package/dist/services/plugin-state-store.d.ts +92 -0
  480. package/dist/services/plugin-state-store.d.ts.map +1 -0
  481. package/dist/services/plugin-state-store.js +190 -0
  482. package/dist/services/plugin-state-store.js.map +1 -0
  483. package/dist/services/plugin-stream-bus.d.ts +29 -0
  484. package/dist/services/plugin-stream-bus.d.ts.map +1 -0
  485. package/dist/services/plugin-stream-bus.js +48 -0
  486. package/dist/services/plugin-stream-bus.js.map +1 -0
  487. package/dist/services/plugin-tool-dispatcher.d.ts +180 -0
  488. package/dist/services/plugin-tool-dispatcher.d.ts.map +1 -0
  489. package/dist/services/plugin-tool-dispatcher.js +224 -0
  490. package/dist/services/plugin-tool-dispatcher.js.map +1 -0
  491. package/dist/services/plugin-tool-registry.d.ts +192 -0
  492. package/dist/services/plugin-tool-registry.d.ts.map +1 -0
  493. package/dist/services/plugin-tool-registry.js +224 -0
  494. package/dist/services/plugin-tool-registry.js.map +1 -0
  495. package/dist/services/plugin-worker-manager.d.ts +260 -0
  496. package/dist/services/plugin-worker-manager.d.ts.map +1 -0
  497. package/dist/services/plugin-worker-manager.js +835 -0
  498. package/dist/services/plugin-worker-manager.js.map +1 -0
  499. package/dist/services/project-workspace-runtime-config.d.ts +4 -0
  500. package/dist/services/project-workspace-runtime-config.d.ts.map +1 -0
  501. package/dist/services/project-workspace-runtime-config.js +43 -0
  502. package/dist/services/project-workspace-runtime-config.js.map +1 -0
  503. package/dist/services/projects.d.ts +88 -0
  504. package/dist/services/projects.d.ts.map +1 -0
  505. package/dist/services/projects.js +669 -0
  506. package/dist/services/projects.js.map +1 -0
  507. package/dist/services/quota-windows.d.ts +9 -0
  508. package/dist/services/quota-windows.d.ts.map +1 -0
  509. package/dist/services/quota-windows.js +56 -0
  510. package/dist/services/quota-windows.js.map +1 -0
  511. package/dist/services/routines.d.ts +136 -0
  512. package/dist/services/routines.d.ts.map +1 -0
  513. package/dist/services/routines.js +1268 -0
  514. package/dist/services/routines.js.map +1 -0
  515. package/dist/services/run-log-store.d.ts +34 -0
  516. package/dist/services/run-log-store.d.ts.map +1 -0
  517. package/dist/services/run-log-store.js +109 -0
  518. package/dist/services/run-log-store.js.map +1 -0
  519. package/dist/services/secrets.d.ts +511 -0
  520. package/dist/services/secrets.d.ts.map +1 -0
  521. package/dist/services/secrets.js +289 -0
  522. package/dist/services/secrets.js.map +1 -0
  523. package/dist/services/sidebar-badges.d.ts +9 -0
  524. package/dist/services/sidebar-badges.d.ts.map +1 -0
  525. package/dist/services/sidebar-badges.js +33 -0
  526. package/dist/services/sidebar-badges.js.map +1 -0
  527. package/dist/services/work-products.d.ts +14 -0
  528. package/dist/services/work-products.d.ts.map +1 -0
  529. package/dist/services/work-products.js +100 -0
  530. package/dist/services/work-products.js.map +1 -0
  531. package/dist/services/workspace-operation-log-store.d.ts +33 -0
  532. package/dist/services/workspace-operation-log-store.d.ts.map +1 -0
  533. package/dist/services/workspace-operation-log-store.js +110 -0
  534. package/dist/services/workspace-operation-log-store.js.map +1 -0
  535. package/dist/services/workspace-operations.d.ts +44 -0
  536. package/dist/services/workspace-operations.d.ts.map +1 -0
  537. package/dist/services/workspace-operations.js +211 -0
  538. package/dist/services/workspace-operations.js.map +1 -0
  539. package/dist/services/workspace-runtime.d.ts +188 -0
  540. package/dist/services/workspace-runtime.d.ts.map +1 -0
  541. package/dist/services/workspace-runtime.js +1705 -0
  542. package/dist/services/workspace-runtime.js.map +1 -0
  543. package/dist/startup-banner.d.ts +31 -0
  544. package/dist/startup-banner.d.ts.map +1 -0
  545. package/dist/startup-banner.js +117 -0
  546. package/dist/startup-banner.js.map +1 -0
  547. package/dist/storage/index.d.ts +6 -0
  548. package/dist/storage/index.d.ts.map +1 -0
  549. package/dist/storage/index.js +29 -0
  550. package/dist/storage/index.js.map +1 -0
  551. package/dist/storage/local-disk-provider.d.ts +3 -0
  552. package/dist/storage/local-disk-provider.d.ts.map +1 -0
  553. package/dist/storage/local-disk-provider.js +79 -0
  554. package/dist/storage/local-disk-provider.js.map +1 -0
  555. package/dist/storage/provider-registry.d.ts +4 -0
  556. package/dist/storage/provider-registry.d.ts.map +1 -0
  557. package/dist/storage/provider-registry.js +15 -0
  558. package/dist/storage/provider-registry.js.map +1 -0
  559. package/dist/storage/s3-provider.d.ts +11 -0
  560. package/dist/storage/s3-provider.d.ts.map +1 -0
  561. package/dist/storage/s3-provider.js +123 -0
  562. package/dist/storage/s3-provider.js.map +1 -0
  563. package/dist/storage/service.d.ts +3 -0
  564. package/dist/storage/service.d.ts.map +1 -0
  565. package/dist/storage/service.js +120 -0
  566. package/dist/storage/service.js.map +1 -0
  567. package/dist/storage/types.d.ts +55 -0
  568. package/dist/storage/types.d.ts.map +1 -0
  569. package/dist/storage/types.js +2 -0
  570. package/dist/storage/types.js.map +1 -0
  571. package/dist/telemetry.d.ts +6 -0
  572. package/dist/telemetry.d.ts.map +1 -0
  573. package/dist/telemetry.js +20 -0
  574. package/dist/telemetry.js.map +1 -0
  575. package/dist/ui-branding.d.ts +13 -0
  576. package/dist/ui-branding.d.ts.map +1 -0
  577. package/dist/ui-branding.js +187 -0
  578. package/dist/ui-branding.js.map +1 -0
  579. package/dist/version.d.ts +2 -0
  580. package/dist/version.d.ts.map +1 -0
  581. package/dist/version.js +5 -0
  582. package/dist/version.js.map +1 -0
  583. package/dist/worktree-config.d.ts +19 -0
  584. package/dist/worktree-config.d.ts.map +1 -0
  585. package/dist/worktree-config.js +365 -0
  586. package/dist/worktree-config.js.map +1 -0
  587. package/package.json +90 -0
  588. package/ui-dist/android-chrome-192x192.png +0 -0
  589. package/ui-dist/android-chrome-512x512.png +0 -0
  590. package/ui-dist/apple-touch-icon.png +0 -0
  591. package/ui-dist/assets/_basePickBy-D2fZf0o0.js +1 -0
  592. package/ui-dist/assets/_baseUniq-CWLG_Xqf.js +1 -0
  593. package/ui-dist/assets/apl-B4CMkyY2.js +1 -0
  594. package/ui-dist/assets/arc-DeECLtLk.js +1 -0
  595. package/ui-dist/assets/architectureDiagram-VXUJARFQ-a4Gzo-8u.js +36 -0
  596. package/ui-dist/assets/asciiarmor-Df11BRmG.js +1 -0
  597. package/ui-dist/assets/asn1-EdZsLKOL.js +1 -0
  598. package/ui-dist/assets/asterisk-B-8jnY81.js +1 -0
  599. package/ui-dist/assets/blockDiagram-VD42YOAC-tsACr-ke.js +122 -0
  600. package/ui-dist/assets/brainfuck-C4LP7Hcl.js +1 -0
  601. package/ui-dist/assets/c4Diagram-YG6GDRKO-CxIEiGp0.js +10 -0
  602. package/ui-dist/assets/channel-B8aOlvkH.js +1 -0
  603. package/ui-dist/assets/chunk-4BX2VUAB-DXyq1OVE.js +1 -0
  604. package/ui-dist/assets/chunk-55IACEB6-DE0IJwCp.js +1 -0
  605. package/ui-dist/assets/chunk-B4BG7PRW-C4VgkuRm.js +165 -0
  606. package/ui-dist/assets/chunk-DI55MBZ5-DUnVODLP.js +220 -0
  607. package/ui-dist/assets/chunk-FMBD7UC4-D14U1wU8.js +15 -0
  608. package/ui-dist/assets/chunk-QN33PNHL--9Fa_-d7.js +1 -0
  609. package/ui-dist/assets/chunk-QZHKN3VN-6vF9hrbB.js +1 -0
  610. package/ui-dist/assets/chunk-TZMSLE5B-BOKdVMfQ.js +1 -0
  611. package/ui-dist/assets/classDiagram-2ON5EDUG-CNtVQyHf.js +1 -0
  612. package/ui-dist/assets/classDiagram-v2-WZHVMYZB-CNtVQyHf.js +1 -0
  613. package/ui-dist/assets/clike-B9uivgTg.js +1 -0
  614. package/ui-dist/assets/clojure-BMjYHr_A.js +1 -0
  615. package/ui-dist/assets/clone-DbnZAhBs.js +1 -0
  616. package/ui-dist/assets/cmake-BQqOBYOt.js +1 -0
  617. package/ui-dist/assets/cobol-CWcv1MsR.js +1 -0
  618. package/ui-dist/assets/coffeescript-S37ZYGWr.js +1 -0
  619. package/ui-dist/assets/commonlisp-DBKNyK5s.js +1 -0
  620. package/ui-dist/assets/cose-bilkent-S5V4N54A-BSFYrItZ.js +1 -0
  621. package/ui-dist/assets/crystal-SjHAIU92.js +1 -0
  622. package/ui-dist/assets/css-BnMrqG3P.js +1 -0
  623. package/ui-dist/assets/cypher-C_CwsFkJ.js +1 -0
  624. package/ui-dist/assets/cytoscape.esm-BQaXIfA_.js +331 -0
  625. package/ui-dist/assets/d-pRatUO7H.js +1 -0
  626. package/ui-dist/assets/dagre-6UL2VRFP-D8xEb_jz.js +4 -0
  627. package/ui-dist/assets/defaultLocale-DX6XiGOO.js +1 -0
  628. package/ui-dist/assets/diagram-PSM6KHXK-kkdfif_P.js +24 -0
  629. package/ui-dist/assets/diagram-QEK2KX5R-BOA1wTkn.js +43 -0
  630. package/ui-dist/assets/diagram-S2PKOQOG-BMxIrdD_.js +24 -0
  631. package/ui-dist/assets/diff-DbItnlRl.js +1 -0
  632. package/ui-dist/assets/dockerfile-BKs6k2Af.js +1 -0
  633. package/ui-dist/assets/dtd-DF_7sFjM.js +1 -0
  634. package/ui-dist/assets/dylan-DwRh75JA.js +1 -0
  635. package/ui-dist/assets/ebnf-CDyGwa7X.js +1 -0
  636. package/ui-dist/assets/ecl-Cabwm37j.js +1 -0
  637. package/ui-dist/assets/eiffel-CnydiIhH.js +1 -0
  638. package/ui-dist/assets/elm-vLlmbW-K.js +1 -0
  639. package/ui-dist/assets/erDiagram-Q2GNP2WA-O1OwJuJt.js +60 -0
  640. package/ui-dist/assets/erlang-BNw1qcRV.js +1 -0
  641. package/ui-dist/assets/factor-kuTfRLto.js +1 -0
  642. package/ui-dist/assets/fcl-Kvtd6kyn.js +1 -0
  643. package/ui-dist/assets/flowDiagram-NV44I4VS-Ca9TsVEe.js +162 -0
  644. package/ui-dist/assets/forth-Ffai-XNe.js +1 -0
  645. package/ui-dist/assets/fortran-DYz_wnZ1.js +1 -0
  646. package/ui-dist/assets/ganttDiagram-JELNMOA3-CZ3k4lR4.js +267 -0
  647. package/ui-dist/assets/gas-Bneqetm1.js +1 -0
  648. package/ui-dist/assets/gherkin-heZmZLOM.js +1 -0
  649. package/ui-dist/assets/gitGraphDiagram-V2S2FVAM-CYXpu5VF.js +65 -0
  650. package/ui-dist/assets/graph-Ct1Mwc2w.js +1 -0
  651. package/ui-dist/assets/groovy-D9Dt4D0W.js +1 -0
  652. package/ui-dist/assets/haskell-Cw1EW3IL.js +1 -0
  653. package/ui-dist/assets/haxe-H-WmDvRZ.js +1 -0
  654. package/ui-dist/assets/http-DBlCnlav.js +1 -0
  655. package/ui-dist/assets/idl-BEugSyMb.js +1 -0
  656. package/ui-dist/assets/index-1-xGTyG8.js +1 -0
  657. package/ui-dist/assets/index-2BV3lexL.js +1 -0
  658. package/ui-dist/assets/index-7nZVjhgZ.js +1227 -0
  659. package/ui-dist/assets/index-B3cKIXfV.js +1 -0
  660. package/ui-dist/assets/index-BKVrlVnm.js +1 -0
  661. package/ui-dist/assets/index-BoQp7qpa.js +6 -0
  662. package/ui-dist/assets/index-Bso7Ph2z.js +1 -0
  663. package/ui-dist/assets/index-C016T1QA.js +1 -0
  664. package/ui-dist/assets/index-CKShy7qg.js +1 -0
  665. package/ui-dist/assets/index-CTeTAOP4.js +2 -0
  666. package/ui-dist/assets/index-CU0xjnJx.js +1 -0
  667. package/ui-dist/assets/index-CX3xG_nU.js +1 -0
  668. package/ui-dist/assets/index-ChGANpP5.js +1 -0
  669. package/ui-dist/assets/index-Cyi4EPvJ.js +13 -0
  670. package/ui-dist/assets/index-D4ERoZ49.js +1 -0
  671. package/ui-dist/assets/index-DAhE9Tae.js +1 -0
  672. package/ui-dist/assets/index-DYf-Vmt-.js +1 -0
  673. package/ui-dist/assets/index-DZ5z-1W5.js +1 -0
  674. package/ui-dist/assets/index-Dbx0Jq5s.js +1 -0
  675. package/ui-dist/assets/index-DcJU9_Xw.js +3 -0
  676. package/ui-dist/assets/index-DzvAUKSy.js +1 -0
  677. package/ui-dist/assets/index-Ip5TfL79.css +1 -0
  678. package/ui-dist/assets/index-b-wjeoWr.js +7 -0
  679. package/ui-dist/assets/index-zAFj8SiW.js +1 -0
  680. package/ui-dist/assets/infoDiagram-HS3SLOUP-BBoge3td.js +2 -0
  681. package/ui-dist/assets/init-Gi6I4Gst.js +1 -0
  682. package/ui-dist/assets/javascript-iXu5QeM3.js +1 -0
  683. package/ui-dist/assets/journeyDiagram-XKPGCS4Q-D6qBxJvS.js +139 -0
  684. package/ui-dist/assets/julia-DuME0IfC.js +1 -0
  685. package/ui-dist/assets/kanban-definition-3W4ZIXB7-BKw70hff.js +89 -0
  686. package/ui-dist/assets/katex-O9d3_IXG.js +261 -0
  687. package/ui-dist/assets/layout-C-MelZ5a.js +1 -0
  688. package/ui-dist/assets/linear-BDJBF_lN.js +1 -0
  689. package/ui-dist/assets/livescript-BwQOo05w.js +1 -0
  690. package/ui-dist/assets/lua-BgMRiT3U.js +1 -0
  691. package/ui-dist/assets/mathematica-DTrFuWx2.js +1 -0
  692. package/ui-dist/assets/mbox-CNhZ1qSd.js +1 -0
  693. package/ui-dist/assets/mermaid.core-C_LSSro9.js +256 -0
  694. package/ui-dist/assets/mindmap-definition-VGOIOE7T-DKTz8YjL.js +68 -0
  695. package/ui-dist/assets/mirc-CjQqDB4T.js +1 -0
  696. package/ui-dist/assets/mllike-CXdrOF99.js +1 -0
  697. package/ui-dist/assets/modelica-Dc1JOy9r.js +1 -0
  698. package/ui-dist/assets/mscgen-BA5vi2Kp.js +1 -0
  699. package/ui-dist/assets/mumps-BT43cFF4.js +1 -0
  700. package/ui-dist/assets/nginx-DdIZxoE0.js +1 -0
  701. package/ui-dist/assets/nsis-LdVXkNf5.js +1 -0
  702. package/ui-dist/assets/ntriples-BfvgReVJ.js +1 -0
  703. package/ui-dist/assets/octave-Ck1zUtKM.js +1 -0
  704. package/ui-dist/assets/ordinal-Cboi1Yqb.js +1 -0
  705. package/ui-dist/assets/oz-BzwKVEFT.js +1 -0
  706. package/ui-dist/assets/pascal--L3eBynH.js +1 -0
  707. package/ui-dist/assets/perl-CdXCOZ3F.js +1 -0
  708. package/ui-dist/assets/pieDiagram-ADFJNKIX-COzMH2F2.js +30 -0
  709. package/ui-dist/assets/pig-CevX1Tat.js +1 -0
  710. package/ui-dist/assets/powershell-CFHJl5sT.js +1 -0
  711. package/ui-dist/assets/properties-C78fOPTZ.js +1 -0
  712. package/ui-dist/assets/protobuf-ChK-085T.js +1 -0
  713. package/ui-dist/assets/pug-DeIclll2.js +1 -0
  714. package/ui-dist/assets/puppet-DMA9R1ak.js +1 -0
  715. package/ui-dist/assets/python-BuPzkPfP.js +1 -0
  716. package/ui-dist/assets/q-pXgVlZs6.js +1 -0
  717. package/ui-dist/assets/quadrantDiagram-AYHSOK5B-I8FRTFaI.js +7 -0
  718. package/ui-dist/assets/r-B6wPVr8A.js +1 -0
  719. package/ui-dist/assets/requirementDiagram-UZGBJVZJ-DI3nQy2l.js +64 -0
  720. package/ui-dist/assets/rpm-CTu-6PCP.js +1 -0
  721. package/ui-dist/assets/ruby-B2Rjki9n.js +1 -0
  722. package/ui-dist/assets/sankeyDiagram-TZEHDZUN-Pf_PmYIt.js +10 -0
  723. package/ui-dist/assets/sas-B4kiWyti.js +1 -0
  724. package/ui-dist/assets/scheme-C41bIUwD.js +1 -0
  725. package/ui-dist/assets/sequenceDiagram-WL72ISMW-DLgaS7kB.js +145 -0
  726. package/ui-dist/assets/shell-CjFT_Tl9.js +1 -0
  727. package/ui-dist/assets/sieve-C3Gn_uJK.js +1 -0
  728. package/ui-dist/assets/simple-mode-GW_nhZxv.js +1 -0
  729. package/ui-dist/assets/smalltalk-CnHTOXQT.js +1 -0
  730. package/ui-dist/assets/solr-DehyRSwq.js +1 -0
  731. package/ui-dist/assets/sparql-DkYu6x3z.js +1 -0
  732. package/ui-dist/assets/spreadsheet-BCZA_wO0.js +1 -0
  733. package/ui-dist/assets/sql-D0XecflT.js +1 -0
  734. package/ui-dist/assets/stateDiagram-FKZM4ZOC-BvMa1uU-.js +1 -0
  735. package/ui-dist/assets/stateDiagram-v2-4FDKWEC3-BKAZNp5l.js +1 -0
  736. package/ui-dist/assets/stex-C3f8Ysf7.js +1 -0
  737. package/ui-dist/assets/stylus-B533Al4x.js +1 -0
  738. package/ui-dist/assets/swift-BzpIVaGY.js +1 -0
  739. package/ui-dist/assets/tcl-DVfN8rqt.js +1 -0
  740. package/ui-dist/assets/textile-CnDTJFAw.js +1 -0
  741. package/ui-dist/assets/tiddlywiki-DO-Gjzrf.js +1 -0
  742. package/ui-dist/assets/tiki-DGYXhP31.js +1 -0
  743. package/ui-dist/assets/timeline-definition-IT6M3QCI-JQUCAkOQ.js +61 -0
  744. package/ui-dist/assets/toml-Bm5Em-hy.js +1 -0
  745. package/ui-dist/assets/treemap-GDKQZRPO-BK87qA0V.js +162 -0
  746. package/ui-dist/assets/troff-wAsdV37c.js +1 -0
  747. package/ui-dist/assets/ttcn-CfJYG6tj.js +1 -0
  748. package/ui-dist/assets/ttcn-cfg-B9xdYoR4.js +1 -0
  749. package/ui-dist/assets/turtle-B1tBg_DP.js +1 -0
  750. package/ui-dist/assets/vb-CmGdzxic.js +1 -0
  751. package/ui-dist/assets/vbscript-BuJXcnF6.js +1 -0
  752. package/ui-dist/assets/velocity-D8B20fx6.js +1 -0
  753. package/ui-dist/assets/verilog-C6RDOZhf.js +1 -0
  754. package/ui-dist/assets/vhdl-lSbBsy5d.js +1 -0
  755. package/ui-dist/assets/webidl-ZXfAyPTL.js +1 -0
  756. package/ui-dist/assets/xquery-DzFWVndE.js +1 -0
  757. package/ui-dist/assets/xychartDiagram-PRI3JC2R-UI3XP-6x.js +7 -0
  758. package/ui-dist/assets/yacas-BJ4BC0dw.js +1 -0
  759. package/ui-dist/assets/z80-Hz9HOZM7.js +1 -0
  760. package/ui-dist/brands/opencode-logo-dark-square.svg +18 -0
  761. package/ui-dist/brands/opencode-logo-light-square.svg +18 -0
  762. package/ui-dist/favicon-16x16.png +0 -0
  763. package/ui-dist/favicon-32x32.png +0 -0
  764. package/ui-dist/favicon.ico +0 -0
  765. package/ui-dist/favicon.svg +9 -0
  766. package/ui-dist/index.html +49 -0
  767. package/ui-dist/site.webmanifest +30 -0
  768. package/ui-dist/sw.js +42 -0
  769. package/ui-dist/worktree-favicon-16x16.png +0 -0
  770. package/ui-dist/worktree-favicon-32x32.png +0 -0
  771. package/ui-dist/worktree-favicon.ico +0 -0
  772. package/ui-dist/worktree-favicon.svg +9 -0
@@ -0,0 +1,2063 @@
1
+ import { createHash } from "node:crypto";
2
+ import { promises as fs } from "node:fs";
3
+ import path from "node:path";
4
+ import { fileURLToPath } from "node:url";
5
+ import { and, asc, eq } from "drizzle-orm";
6
+ import { companySkills } from "@zmeel/db";
7
+ import { readzmeelSkillSyncPreference, writezmeelSkillSyncPreference } from "@zmeel/adapter-utils/server-utils";
8
+ import { normalizeAgentUrlKey } from "@zmeel/shared";
9
+ import { findServerAdapter } from "../adapters/index.js";
10
+ import { resolvezmeelInstanceRoot } from "../home-paths.js";
11
+ import { notFound, unprocessable } from "../errors.js";
12
+ import { ghFetch, gitHubApiBase, resolveRawGitHubUrl } from "./github-fetch.js";
13
+ import { agentService } from "./agents.js";
14
+ import { projectService } from "./projects.js";
15
+ import { secretService } from "./secrets.js";
16
+ const skillInventoryRefreshPromises = new Map();
17
+ const PROJECT_SCAN_DIRECTORY_ROOTS = [
18
+ "skills",
19
+ "skills/.curated",
20
+ "skills/.experimental",
21
+ "skills/.system",
22
+ ".agents/skills",
23
+ ".agent/skills",
24
+ ".augment/skills",
25
+ ".claude/skills",
26
+ ".codebuddy/skills",
27
+ ".commandcode/skills",
28
+ ".continue/skills",
29
+ ".cortex/skills",
30
+ ".crush/skills",
31
+ ".factory/skills",
32
+ ".goose/skills",
33
+ ".junie/skills",
34
+ ".iflow/skills",
35
+ ".kilocode/skills",
36
+ ".kiro/skills",
37
+ ".kode/skills",
38
+ ".mcpjam/skills",
39
+ ".vibe/skills",
40
+ ".mux/skills",
41
+ ".openhands/skills",
42
+ ".pi/skills",
43
+ ".qoder/skills",
44
+ ".qwen/skills",
45
+ ".roo/skills",
46
+ ".trae/skills",
47
+ ".windsurf/skills",
48
+ ".zencoder/skills",
49
+ ".neovate/skills",
50
+ ".pochi/skills",
51
+ ".adal/skills",
52
+ ];
53
+ const PROJECT_ROOT_SKILL_SUBDIRECTORIES = [
54
+ "references",
55
+ "scripts",
56
+ "assets",
57
+ ];
58
+ function asString(value) {
59
+ if (typeof value !== "string")
60
+ return null;
61
+ const trimmed = value.trim();
62
+ return trimmed.length > 0 ? trimmed : null;
63
+ }
64
+ function isPlainRecord(value) {
65
+ return typeof value === "object" && value !== null && !Array.isArray(value);
66
+ }
67
+ function normalizePortablePath(input) {
68
+ const parts = [];
69
+ for (const segment of input.replace(/\\/g, "/").replace(/^\.\/+/, "").replace(/^\/+/, "").split("/")) {
70
+ if (!segment || segment === ".")
71
+ continue;
72
+ if (segment === "..") {
73
+ if (parts.length > 0)
74
+ parts.pop();
75
+ continue;
76
+ }
77
+ parts.push(segment);
78
+ }
79
+ return parts.join("/");
80
+ }
81
+ function normalizePackageFileMap(files) {
82
+ const out = {};
83
+ for (const [rawPath, content] of Object.entries(files)) {
84
+ const nextPath = normalizePortablePath(rawPath);
85
+ if (!nextPath)
86
+ continue;
87
+ out[nextPath] = content;
88
+ }
89
+ return out;
90
+ }
91
+ function normalizeSkillSlug(value) {
92
+ return value ? normalizeAgentUrlKey(value) ?? null : null;
93
+ }
94
+ function normalizeSkillKey(value) {
95
+ if (!value)
96
+ return null;
97
+ const segments = value
98
+ .split("/")
99
+ .map((segment) => normalizeSkillSlug(segment))
100
+ .filter((segment) => Boolean(segment));
101
+ return segments.length > 0 ? segments.join("/") : null;
102
+ }
103
+ export function normalizeGitHubSkillDirectory(value, fallback) {
104
+ const normalized = normalizePortablePath(value ?? "");
105
+ if (!normalized)
106
+ return normalizePortablePath(fallback);
107
+ if (path.posix.basename(normalized).toLowerCase() === "skill.md") {
108
+ return normalizePortablePath(path.posix.dirname(normalized));
109
+ }
110
+ return normalized;
111
+ }
112
+ function hashSkillValue(value) {
113
+ return createHash("sha256").update(value).digest("hex").slice(0, 10);
114
+ }
115
+ function uniqueSkillSlug(baseSlug, usedSlugs) {
116
+ if (!usedSlugs.has(baseSlug))
117
+ return baseSlug;
118
+ let attempt = 2;
119
+ let candidate = `${baseSlug}-${attempt}`;
120
+ while (usedSlugs.has(candidate)) {
121
+ attempt += 1;
122
+ candidate = `${baseSlug}-${attempt}`;
123
+ }
124
+ return candidate;
125
+ }
126
+ function uniqueImportedSkillKey(companyId, baseSlug, usedKeys) {
127
+ const initial = `company/${companyId}/${baseSlug}`;
128
+ if (!usedKeys.has(initial))
129
+ return initial;
130
+ let attempt = 2;
131
+ let candidate = `company/${companyId}/${baseSlug}-${attempt}`;
132
+ while (usedKeys.has(candidate)) {
133
+ attempt += 1;
134
+ candidate = `company/${companyId}/${baseSlug}-${attempt}`;
135
+ }
136
+ return candidate;
137
+ }
138
+ function buildSkillRuntimeName(key, slug) {
139
+ if (key.startsWith("zmeel/zmeel/"))
140
+ return slug;
141
+ return `${slug}--${hashSkillValue(key)}`;
142
+ }
143
+ function readCanonicalSkillKey(frontmatter, metadata) {
144
+ const direct = normalizeSkillKey(asString(frontmatter.key)
145
+ ?? asString(frontmatter.skillKey)
146
+ ?? asString(metadata?.skillKey)
147
+ ?? asString(metadata?.canonicalKey)
148
+ ?? asString(metadata?.zmeelSkillKey));
149
+ if (direct)
150
+ return direct;
151
+ const zmeel = isPlainRecord(metadata?.zmeel) ? metadata?.zmeel : null;
152
+ return normalizeSkillKey(asString(zmeel?.skillKey)
153
+ ?? asString(zmeel?.key));
154
+ }
155
+ function deriveCanonicalSkillKey(companyId, input) {
156
+ const slug = normalizeSkillSlug(input.slug) ?? "skill";
157
+ const metadata = isPlainRecord(input.metadata) ? input.metadata : null;
158
+ const explicitKey = readCanonicalSkillKey({}, metadata);
159
+ if (explicitKey)
160
+ return explicitKey;
161
+ const sourceKind = asString(metadata?.sourceKind);
162
+ if (sourceKind === "zmeel_bundled") {
163
+ return `zmeel/zmeel/${slug}`;
164
+ }
165
+ const owner = normalizeSkillSlug(asString(metadata?.owner));
166
+ const repo = normalizeSkillSlug(asString(metadata?.repo));
167
+ if ((input.sourceType === "github" || input.sourceType === "skills_sh" || sourceKind === "github" || sourceKind === "skills_sh") && owner && repo) {
168
+ return `${owner}/${repo}/${slug}`;
169
+ }
170
+ if (input.sourceType === "url" || sourceKind === "url") {
171
+ const locator = asString(input.sourceLocator);
172
+ if (locator) {
173
+ try {
174
+ const url = new URL(locator);
175
+ const host = normalizeSkillSlug(url.host) ?? "url";
176
+ return `url/${host}/${hashSkillValue(locator)}/${slug}`;
177
+ }
178
+ catch {
179
+ return `url/unknown/${hashSkillValue(locator)}/${slug}`;
180
+ }
181
+ }
182
+ }
183
+ if (input.sourceType === "local_path") {
184
+ if (sourceKind === "managed_local") {
185
+ return `company/${companyId}/${slug}`;
186
+ }
187
+ const locator = asString(input.sourceLocator);
188
+ if (locator) {
189
+ return `local/${hashSkillValue(path.resolve(locator))}/${slug}`;
190
+ }
191
+ }
192
+ return `company/${companyId}/${slug}`;
193
+ }
194
+ function classifyInventoryKind(relativePath) {
195
+ const normalized = normalizePortablePath(relativePath).toLowerCase();
196
+ if (normalized.endsWith("/skill.md") || normalized === "skill.md")
197
+ return "skill";
198
+ if (normalized.startsWith("references/"))
199
+ return "reference";
200
+ if (normalized.startsWith("scripts/"))
201
+ return "script";
202
+ if (normalized.startsWith("assets/"))
203
+ return "asset";
204
+ if (normalized.endsWith(".md"))
205
+ return "markdown";
206
+ const fileName = path.posix.basename(normalized);
207
+ if (fileName.endsWith(".sh")
208
+ || fileName.endsWith(".js")
209
+ || fileName.endsWith(".mjs")
210
+ || fileName.endsWith(".cjs")
211
+ || fileName.endsWith(".ts")
212
+ || fileName.endsWith(".py")
213
+ || fileName.endsWith(".rb")
214
+ || fileName.endsWith(".bash")) {
215
+ return "script";
216
+ }
217
+ if (fileName.endsWith(".png")
218
+ || fileName.endsWith(".jpg")
219
+ || fileName.endsWith(".jpeg")
220
+ || fileName.endsWith(".gif")
221
+ || fileName.endsWith(".svg")
222
+ || fileName.endsWith(".webp")
223
+ || fileName.endsWith(".pdf")) {
224
+ return "asset";
225
+ }
226
+ return "other";
227
+ }
228
+ function deriveTrustLevel(fileInventory) {
229
+ if (fileInventory.some((entry) => entry.kind === "script"))
230
+ return "scripts_executables";
231
+ if (fileInventory.some((entry) => entry.kind === "asset" || entry.kind === "other"))
232
+ return "assets";
233
+ return "markdown_only";
234
+ }
235
+ function prepareYamlLines(raw) {
236
+ return raw
237
+ .split("\n")
238
+ .map((line) => ({
239
+ indent: line.match(/^ */)?.[0].length ?? 0,
240
+ content: line.trim(),
241
+ }))
242
+ .filter((line) => line.content.length > 0 && !line.content.startsWith("#"));
243
+ }
244
+ function parseYamlScalar(rawValue) {
245
+ const trimmed = rawValue.trim();
246
+ if (trimmed === "")
247
+ return "";
248
+ if (trimmed === "null" || trimmed === "~")
249
+ return null;
250
+ if (trimmed === "true")
251
+ return true;
252
+ if (trimmed === "false")
253
+ return false;
254
+ if (trimmed === "[]")
255
+ return [];
256
+ if (trimmed === "{}")
257
+ return {};
258
+ if (/^-?\d+(\.\d+)?$/.test(trimmed))
259
+ return Number(trimmed);
260
+ if (trimmed.startsWith("\"") || trimmed.startsWith("[") || trimmed.startsWith("{")) {
261
+ try {
262
+ return JSON.parse(trimmed);
263
+ }
264
+ catch {
265
+ return trimmed;
266
+ }
267
+ }
268
+ return trimmed;
269
+ }
270
+ function parseYamlBlock(lines, startIndex, indentLevel) {
271
+ let index = startIndex;
272
+ while (index < lines.length && lines[index].content.length === 0)
273
+ index += 1;
274
+ if (index >= lines.length || lines[index].indent < indentLevel) {
275
+ return { value: {}, nextIndex: index };
276
+ }
277
+ const isArray = lines[index].indent === indentLevel && lines[index].content.startsWith("-");
278
+ if (isArray) {
279
+ const values = [];
280
+ while (index < lines.length) {
281
+ const line = lines[index];
282
+ if (line.indent < indentLevel)
283
+ break;
284
+ if (line.indent !== indentLevel || !line.content.startsWith("-"))
285
+ break;
286
+ const remainder = line.content.slice(1).trim();
287
+ index += 1;
288
+ if (!remainder) {
289
+ const nested = parseYamlBlock(lines, index, indentLevel + 2);
290
+ values.push(nested.value);
291
+ index = nested.nextIndex;
292
+ continue;
293
+ }
294
+ const inlineObjectSeparator = remainder.indexOf(":");
295
+ if (inlineObjectSeparator > 0 &&
296
+ !remainder.startsWith("\"") &&
297
+ !remainder.startsWith("{") &&
298
+ !remainder.startsWith("[")) {
299
+ const key = remainder.slice(0, inlineObjectSeparator).trim();
300
+ const rawValue = remainder.slice(inlineObjectSeparator + 1).trim();
301
+ const nextObject = {
302
+ [key]: parseYamlScalar(rawValue),
303
+ };
304
+ if (index < lines.length && lines[index].indent > indentLevel) {
305
+ const nested = parseYamlBlock(lines, index, indentLevel + 2);
306
+ if (isPlainRecord(nested.value)) {
307
+ Object.assign(nextObject, nested.value);
308
+ }
309
+ index = nested.nextIndex;
310
+ }
311
+ values.push(nextObject);
312
+ continue;
313
+ }
314
+ values.push(parseYamlScalar(remainder));
315
+ }
316
+ return { value: values, nextIndex: index };
317
+ }
318
+ const record = {};
319
+ while (index < lines.length) {
320
+ const line = lines[index];
321
+ if (line.indent < indentLevel)
322
+ break;
323
+ if (line.indent !== indentLevel) {
324
+ index += 1;
325
+ continue;
326
+ }
327
+ const separatorIndex = line.content.indexOf(":");
328
+ if (separatorIndex <= 0) {
329
+ index += 1;
330
+ continue;
331
+ }
332
+ const key = line.content.slice(0, separatorIndex).trim();
333
+ const remainder = line.content.slice(separatorIndex + 1).trim();
334
+ index += 1;
335
+ if (!remainder) {
336
+ const nested = parseYamlBlock(lines, index, indentLevel + 2);
337
+ record[key] = nested.value;
338
+ index = nested.nextIndex;
339
+ continue;
340
+ }
341
+ record[key] = parseYamlScalar(remainder);
342
+ }
343
+ return { value: record, nextIndex: index };
344
+ }
345
+ function parseYamlFrontmatter(raw) {
346
+ const prepared = prepareYamlLines(raw);
347
+ if (prepared.length === 0)
348
+ return {};
349
+ const parsed = parseYamlBlock(prepared, 0, prepared[0].indent);
350
+ return isPlainRecord(parsed.value) ? parsed.value : {};
351
+ }
352
+ function parseFrontmatterMarkdown(raw) {
353
+ const normalized = raw.replace(/\r\n/g, "\n");
354
+ if (!normalized.startsWith("---\n")) {
355
+ return { frontmatter: {}, body: normalized.trim() };
356
+ }
357
+ const closing = normalized.indexOf("\n---\n", 4);
358
+ if (closing < 0) {
359
+ return { frontmatter: {}, body: normalized.trim() };
360
+ }
361
+ const frontmatterRaw = normalized.slice(4, closing).trim();
362
+ const body = normalized.slice(closing + 5).trim();
363
+ return {
364
+ frontmatter: parseYamlFrontmatter(frontmatterRaw),
365
+ body,
366
+ };
367
+ }
368
+ async function fetchText(url) {
369
+ const response = await ghFetch(url);
370
+ if (!response.ok) {
371
+ throw unprocessable(`Failed to fetch ${url}: ${response.status}`);
372
+ }
373
+ return response.text();
374
+ }
375
+ async function fetchJson(url) {
376
+ const response = await ghFetch(url, {
377
+ headers: {
378
+ accept: "application/vnd.github+json",
379
+ },
380
+ });
381
+ if (!response.ok) {
382
+ throw unprocessable(`Failed to fetch ${url}: ${response.status}`);
383
+ }
384
+ return response.json();
385
+ }
386
+ async function resolveGitHubDefaultBranch(owner, repo, apiBase) {
387
+ const response = await fetchJson(`${apiBase}/repos/${owner}/${repo}`);
388
+ return asString(response.default_branch) ?? "main";
389
+ }
390
+ async function resolveGitHubCommitSha(owner, repo, ref, apiBase) {
391
+ const response = await fetchJson(`${apiBase}/repos/${owner}/${repo}/commits/${encodeURIComponent(ref)}`);
392
+ const sha = asString(response.sha);
393
+ if (!sha) {
394
+ throw unprocessable(`Failed to resolve GitHub ref ${ref}`);
395
+ }
396
+ return sha;
397
+ }
398
+ function parseGitHubSourceUrl(rawUrl) {
399
+ const url = new URL(rawUrl);
400
+ if (url.protocol !== "https:") {
401
+ throw unprocessable("GitHub source URL must use HTTPS");
402
+ }
403
+ const parts = url.pathname.split("/").filter(Boolean);
404
+ if (parts.length < 2) {
405
+ throw unprocessable("Invalid GitHub URL");
406
+ }
407
+ const owner = parts[0];
408
+ const repo = parts[1].replace(/\.git$/i, "");
409
+ let ref = "main";
410
+ let basePath = "";
411
+ let filePath = null;
412
+ let explicitRef = false;
413
+ if (parts[2] === "tree") {
414
+ ref = parts[3] ?? "main";
415
+ basePath = parts.slice(4).join("/");
416
+ explicitRef = true;
417
+ }
418
+ else if (parts[2] === "blob") {
419
+ ref = parts[3] ?? "main";
420
+ filePath = parts.slice(4).join("/");
421
+ basePath = filePath ? path.posix.dirname(filePath) : "";
422
+ explicitRef = true;
423
+ }
424
+ return { hostname: url.hostname, owner, repo, ref, basePath, filePath, explicitRef };
425
+ }
426
+ async function resolveGitHubPinnedRef(parsed) {
427
+ const apiBase = gitHubApiBase(parsed.hostname);
428
+ if (/^[0-9a-f]{40}$/i.test(parsed.ref.trim())) {
429
+ return {
430
+ pinnedRef: parsed.ref,
431
+ trackingRef: parsed.explicitRef ? parsed.ref : null,
432
+ };
433
+ }
434
+ const trackingRef = parsed.explicitRef
435
+ ? parsed.ref
436
+ : await resolveGitHubDefaultBranch(parsed.owner, parsed.repo, apiBase);
437
+ const pinnedRef = await resolveGitHubCommitSha(parsed.owner, parsed.repo, trackingRef, apiBase);
438
+ return { pinnedRef, trackingRef };
439
+ }
440
+ function extractCommandTokens(raw) {
441
+ const matches = raw.match(/"[^"]*"|'[^']*'|\S+/g) ?? [];
442
+ return matches.map((token) => token.replace(/^['"]|['"]$/g, ""));
443
+ }
444
+ export function parseSkillImportSourceInput(rawInput) {
445
+ const trimmed = rawInput.trim();
446
+ if (!trimmed) {
447
+ throw unprocessable("Skill source is required.");
448
+ }
449
+ const warnings = [];
450
+ let source = trimmed;
451
+ let requestedSkillSlug = null;
452
+ if (/^npx\s+skills\s+add\s+/i.test(trimmed)) {
453
+ const tokens = extractCommandTokens(trimmed);
454
+ const addIndex = tokens.findIndex((token, index) => token === "add"
455
+ && index > 0
456
+ && tokens[index - 1]?.toLowerCase() === "skills");
457
+ if (addIndex >= 0) {
458
+ source = tokens[addIndex + 1] ?? "";
459
+ for (let index = addIndex + 2; index < tokens.length; index += 1) {
460
+ const token = tokens[index];
461
+ if (token === "--skill") {
462
+ requestedSkillSlug = normalizeSkillSlug(tokens[index + 1] ?? null);
463
+ index += 1;
464
+ continue;
465
+ }
466
+ if (token.startsWith("--skill=")) {
467
+ requestedSkillSlug = normalizeSkillSlug(token.slice("--skill=".length));
468
+ }
469
+ }
470
+ }
471
+ }
472
+ const normalizedSource = source.trim();
473
+ if (!normalizedSource) {
474
+ throw unprocessable("Skill source is required.");
475
+ }
476
+ // Key-style imports (org/repo/skill) originate from the skills.sh registry
477
+ if (!/^https?:\/\//i.test(normalizedSource) && /^[A-Za-z0-9_.-]+\/[A-Za-z0-9_.-]+\/[A-Za-z0-9_.-]+$/.test(normalizedSource)) {
478
+ const [owner, repo, skillSlugRaw] = normalizedSource.split("/");
479
+ return {
480
+ resolvedSource: `https://github.com/${owner}/${repo}`,
481
+ requestedSkillSlug: normalizeSkillSlug(skillSlugRaw),
482
+ originalSkillsShUrl: `https://skills.sh/${owner}/${repo}/${skillSlugRaw}`,
483
+ warnings,
484
+ };
485
+ }
486
+ if (!/^https?:\/\//i.test(normalizedSource) && /^[A-Za-z0-9_.-]+\/[A-Za-z0-9_.-]+$/.test(normalizedSource)) {
487
+ return {
488
+ resolvedSource: `https://github.com/${normalizedSource}`,
489
+ requestedSkillSlug,
490
+ originalSkillsShUrl: null,
491
+ warnings,
492
+ };
493
+ }
494
+ // Detect skills.sh URLs and resolve to GitHub: https://skills.sh/org/repo/skill → org/repo/skill key
495
+ const skillsShMatch = normalizedSource.match(/^https?:\/\/(?:www\.)?skills\.sh\/([A-Za-z0-9_.-]+)\/([A-Za-z0-9_.-]+)(?:\/([A-Za-z0-9_.-]+))?(?:[?#].*)?$/i);
496
+ if (skillsShMatch) {
497
+ const [, owner, repo, skillSlugRaw] = skillsShMatch;
498
+ return {
499
+ resolvedSource: `https://github.com/${owner}/${repo}`,
500
+ requestedSkillSlug: skillSlugRaw ? normalizeSkillSlug(skillSlugRaw) : requestedSkillSlug,
501
+ originalSkillsShUrl: normalizedSource,
502
+ warnings,
503
+ };
504
+ }
505
+ return {
506
+ resolvedSource: normalizedSource,
507
+ requestedSkillSlug,
508
+ originalSkillsShUrl: null,
509
+ warnings,
510
+ };
511
+ }
512
+ function resolveBundledSkillsRoot() {
513
+ const moduleDir = path.dirname(fileURLToPath(import.meta.url));
514
+ return [
515
+ path.resolve(moduleDir, "../../skills"),
516
+ path.resolve(process.cwd(), "skills"),
517
+ path.resolve(moduleDir, "../../../skills"),
518
+ ];
519
+ }
520
+ function matchesRequestedSkill(relativeSkillPath, requestedSkillSlug) {
521
+ if (!requestedSkillSlug)
522
+ return true;
523
+ const skillDir = path.posix.dirname(relativeSkillPath);
524
+ return normalizeSkillSlug(path.posix.basename(skillDir)) === requestedSkillSlug;
525
+ }
526
+ function deriveImportedSkillSlug(frontmatter, fallback) {
527
+ return normalizeSkillSlug(asString(frontmatter.slug))
528
+ ?? normalizeSkillSlug(asString(frontmatter.name))
529
+ ?? normalizeAgentUrlKey(fallback)
530
+ ?? "skill";
531
+ }
532
+ function deriveImportedSkillSource(frontmatter, fallbackSlug) {
533
+ const metadata = isPlainRecord(frontmatter.metadata) ? frontmatter.metadata : null;
534
+ const canonicalKey = readCanonicalSkillKey(frontmatter, metadata);
535
+ const rawSources = metadata && Array.isArray(metadata.sources) ? metadata.sources : [];
536
+ const sourceEntry = rawSources.find((entry) => isPlainRecord(entry));
537
+ const kind = asString(sourceEntry?.kind);
538
+ if (kind === "github-dir" || kind === "github-file") {
539
+ const repo = asString(sourceEntry?.repo);
540
+ const repoPath = asString(sourceEntry?.path);
541
+ const commit = asString(sourceEntry?.commit);
542
+ const trackingRef = asString(sourceEntry?.trackingRef);
543
+ const sourceHostname = asString(sourceEntry?.hostname) || "github.com";
544
+ const url = asString(sourceEntry?.url)
545
+ ?? (repo
546
+ ? `https://${sourceHostname}/${repo}${repoPath ? `/tree/${trackingRef ?? commit ?? "main"}/${repoPath}` : ""}`
547
+ : null);
548
+ const [owner, repoName] = (repo ?? "").split("/");
549
+ if (repo && owner && repoName) {
550
+ return {
551
+ sourceType: "github",
552
+ sourceLocator: url,
553
+ sourceRef: commit,
554
+ metadata: {
555
+ ...(canonicalKey ? { skillKey: canonicalKey } : {}),
556
+ sourceKind: "github",
557
+ ...(sourceHostname !== "github.com" ? { hostname: sourceHostname } : {}),
558
+ owner,
559
+ repo: repoName,
560
+ ref: commit,
561
+ trackingRef,
562
+ repoSkillDir: repoPath ?? `skills/${fallbackSlug}`,
563
+ },
564
+ };
565
+ }
566
+ }
567
+ if (kind === "url") {
568
+ const url = asString(sourceEntry?.url) ?? asString(sourceEntry?.rawUrl);
569
+ if (url) {
570
+ return {
571
+ sourceType: "url",
572
+ sourceLocator: url,
573
+ sourceRef: null,
574
+ metadata: {
575
+ ...(canonicalKey ? { skillKey: canonicalKey } : {}),
576
+ sourceKind: "url",
577
+ },
578
+ };
579
+ }
580
+ }
581
+ return {
582
+ sourceType: "catalog",
583
+ sourceLocator: null,
584
+ sourceRef: null,
585
+ metadata: {
586
+ ...(canonicalKey ? { skillKey: canonicalKey } : {}),
587
+ sourceKind: "catalog",
588
+ },
589
+ };
590
+ }
591
+ function readInlineSkillImports(companyId, files) {
592
+ const normalizedFiles = normalizePackageFileMap(files);
593
+ const skillPaths = Object.keys(normalizedFiles).filter((entry) => path.posix.basename(entry).toLowerCase() === "skill.md");
594
+ const imports = [];
595
+ for (const skillPath of skillPaths) {
596
+ const dir = path.posix.dirname(skillPath);
597
+ const skillDir = dir === "." ? "" : dir;
598
+ const slugFallback = path.posix.basename(skillDir || path.posix.dirname(skillPath));
599
+ const markdown = normalizedFiles[skillPath];
600
+ const parsed = parseFrontmatterMarkdown(markdown);
601
+ const slug = deriveImportedSkillSlug(parsed.frontmatter, slugFallback);
602
+ const source = deriveImportedSkillSource(parsed.frontmatter, slug);
603
+ const inventory = Object.keys(normalizedFiles)
604
+ .filter((entry) => entry === skillPath || (skillDir ? entry.startsWith(`${skillDir}/`) : false))
605
+ .map((entry) => {
606
+ const relative = entry === skillPath ? "SKILL.md" : entry.slice(skillDir.length + 1);
607
+ return {
608
+ path: normalizePortablePath(relative),
609
+ kind: classifyInventoryKind(relative),
610
+ };
611
+ })
612
+ .sort((left, right) => left.path.localeCompare(right.path));
613
+ imports.push({
614
+ key: "",
615
+ slug,
616
+ name: asString(parsed.frontmatter.name) ?? slug,
617
+ description: asString(parsed.frontmatter.description),
618
+ markdown,
619
+ packageDir: skillDir,
620
+ sourceType: source.sourceType,
621
+ sourceLocator: source.sourceLocator,
622
+ sourceRef: source.sourceRef,
623
+ trustLevel: deriveTrustLevel(inventory),
624
+ compatibility: "compatible",
625
+ fileInventory: inventory,
626
+ metadata: source.metadata,
627
+ });
628
+ imports[imports.length - 1].key = deriveCanonicalSkillKey(companyId, imports[imports.length - 1]);
629
+ }
630
+ return imports;
631
+ }
632
+ async function walkLocalFiles(root, current, out) {
633
+ const entries = await fs.readdir(current, { withFileTypes: true });
634
+ for (const entry of entries) {
635
+ if (entry.name === ".git" || entry.name === "node_modules")
636
+ continue;
637
+ const absolutePath = path.join(current, entry.name);
638
+ if (entry.isDirectory()) {
639
+ await walkLocalFiles(root, absolutePath, out);
640
+ continue;
641
+ }
642
+ if (!entry.isFile())
643
+ continue;
644
+ out.push(normalizePortablePath(path.relative(root, absolutePath)));
645
+ }
646
+ }
647
+ async function statPath(targetPath) {
648
+ return fs.stat(targetPath).catch(() => null);
649
+ }
650
+ async function collectLocalSkillInventory(skillDir, mode = "full") {
651
+ const skillFilePath = path.join(skillDir, "SKILL.md");
652
+ const skillFileStat = await statPath(skillFilePath);
653
+ if (!skillFileStat?.isFile()) {
654
+ throw unprocessable(`No SKILL.md file was found in ${skillDir}.`);
655
+ }
656
+ const allFiles = new Set(["SKILL.md"]);
657
+ if (mode === "full") {
658
+ const discoveredFiles = [];
659
+ await walkLocalFiles(skillDir, skillDir, discoveredFiles);
660
+ for (const relativePath of discoveredFiles) {
661
+ allFiles.add(relativePath);
662
+ }
663
+ }
664
+ else {
665
+ for (const relativeDir of PROJECT_ROOT_SKILL_SUBDIRECTORIES) {
666
+ const absoluteDir = path.join(skillDir, relativeDir);
667
+ const dirStat = await statPath(absoluteDir);
668
+ if (!dirStat?.isDirectory())
669
+ continue;
670
+ const discoveredFiles = [];
671
+ await walkLocalFiles(skillDir, absoluteDir, discoveredFiles);
672
+ for (const relativePath of discoveredFiles) {
673
+ allFiles.add(relativePath);
674
+ }
675
+ }
676
+ }
677
+ return Array.from(allFiles)
678
+ .map((relativePath) => ({
679
+ path: normalizePortablePath(relativePath),
680
+ kind: classifyInventoryKind(relativePath),
681
+ }))
682
+ .sort((left, right) => left.path.localeCompare(right.path));
683
+ }
684
+ export async function readLocalSkillImportFromDirectory(companyId, skillDir, options) {
685
+ const resolvedSkillDir = path.resolve(skillDir);
686
+ const skillFilePath = path.join(resolvedSkillDir, "SKILL.md");
687
+ const markdown = await fs.readFile(skillFilePath, "utf8");
688
+ const parsed = parseFrontmatterMarkdown(markdown);
689
+ const slug = deriveImportedSkillSlug(parsed.frontmatter, path.basename(resolvedSkillDir));
690
+ const parsedMetadata = isPlainRecord(parsed.frontmatter.metadata) ? parsed.frontmatter.metadata : null;
691
+ const skillKey = readCanonicalSkillKey(parsed.frontmatter, parsedMetadata);
692
+ const metadata = {
693
+ ...(skillKey ? { skillKey } : {}),
694
+ ...(parsedMetadata ?? {}),
695
+ sourceKind: "local_path",
696
+ ...(options?.metadata ?? {}),
697
+ };
698
+ const inventory = await collectLocalSkillInventory(resolvedSkillDir, options?.inventoryMode ?? "full");
699
+ return {
700
+ key: deriveCanonicalSkillKey(companyId, {
701
+ slug,
702
+ sourceType: "local_path",
703
+ sourceLocator: resolvedSkillDir,
704
+ metadata,
705
+ }),
706
+ slug,
707
+ name: asString(parsed.frontmatter.name) ?? slug,
708
+ description: asString(parsed.frontmatter.description),
709
+ markdown,
710
+ packageDir: resolvedSkillDir,
711
+ sourceType: "local_path",
712
+ sourceLocator: resolvedSkillDir,
713
+ sourceRef: null,
714
+ trustLevel: deriveTrustLevel(inventory),
715
+ compatibility: "compatible",
716
+ fileInventory: inventory,
717
+ metadata,
718
+ };
719
+ }
720
+ export async function discoverProjectWorkspaceSkillDirectories(target) {
721
+ const discovered = new Map();
722
+ const rootSkillPath = path.join(target.workspaceCwd, "SKILL.md");
723
+ if ((await statPath(rootSkillPath))?.isFile()) {
724
+ discovered.set(path.resolve(target.workspaceCwd), "project_root");
725
+ }
726
+ for (const relativeRoot of PROJECT_SCAN_DIRECTORY_ROOTS) {
727
+ const absoluteRoot = path.join(target.workspaceCwd, relativeRoot);
728
+ const rootStat = await statPath(absoluteRoot);
729
+ if (!rootStat?.isDirectory())
730
+ continue;
731
+ const entries = await fs.readdir(absoluteRoot, { withFileTypes: true }).catch(() => []);
732
+ for (const entry of entries) {
733
+ if (!entry.isDirectory())
734
+ continue;
735
+ const absoluteSkillDir = path.resolve(absoluteRoot, entry.name);
736
+ if (!(await statPath(path.join(absoluteSkillDir, "SKILL.md")))?.isFile())
737
+ continue;
738
+ discovered.set(absoluteSkillDir, "full");
739
+ }
740
+ }
741
+ return Array.from(discovered.entries())
742
+ .map(([skillDir, inventoryMode]) => ({ skillDir, inventoryMode }))
743
+ .sort((left, right) => left.skillDir.localeCompare(right.skillDir));
744
+ }
745
+ async function readLocalSkillImports(companyId, sourcePath) {
746
+ const resolvedPath = path.resolve(sourcePath);
747
+ const stat = await fs.stat(resolvedPath).catch(() => null);
748
+ if (!stat) {
749
+ throw unprocessable(`Skill source path does not exist: ${sourcePath}`);
750
+ }
751
+ if (stat.isFile()) {
752
+ const markdown = await fs.readFile(resolvedPath, "utf8");
753
+ const parsed = parseFrontmatterMarkdown(markdown);
754
+ const slug = deriveImportedSkillSlug(parsed.frontmatter, path.basename(path.dirname(resolvedPath)));
755
+ const parsedMetadata = isPlainRecord(parsed.frontmatter.metadata) ? parsed.frontmatter.metadata : null;
756
+ const skillKey = readCanonicalSkillKey(parsed.frontmatter, parsedMetadata);
757
+ const metadata = {
758
+ ...(skillKey ? { skillKey } : {}),
759
+ ...(parsedMetadata ?? {}),
760
+ sourceKind: "local_path",
761
+ };
762
+ const inventory = [
763
+ { path: "SKILL.md", kind: "skill" },
764
+ ];
765
+ return [{
766
+ key: deriveCanonicalSkillKey(companyId, {
767
+ slug,
768
+ sourceType: "local_path",
769
+ sourceLocator: path.dirname(resolvedPath),
770
+ metadata,
771
+ }),
772
+ slug,
773
+ name: asString(parsed.frontmatter.name) ?? slug,
774
+ description: asString(parsed.frontmatter.description),
775
+ markdown,
776
+ packageDir: path.dirname(resolvedPath),
777
+ sourceType: "local_path",
778
+ sourceLocator: path.dirname(resolvedPath),
779
+ sourceRef: null,
780
+ trustLevel: deriveTrustLevel(inventory),
781
+ compatibility: "compatible",
782
+ fileInventory: inventory,
783
+ metadata,
784
+ }];
785
+ }
786
+ const root = resolvedPath;
787
+ const allFiles = [];
788
+ await walkLocalFiles(root, root, allFiles);
789
+ const skillPaths = allFiles.filter((entry) => path.posix.basename(entry).toLowerCase() === "skill.md");
790
+ if (skillPaths.length === 0) {
791
+ throw unprocessable("No SKILL.md files were found in the provided path.");
792
+ }
793
+ const imports = [];
794
+ for (const skillPath of skillPaths) {
795
+ const skillDir = path.posix.dirname(skillPath);
796
+ const inventory = allFiles
797
+ .filter((entry) => entry === skillPath || entry.startsWith(`${skillDir}/`))
798
+ .map((entry) => {
799
+ const relative = entry === skillPath ? "SKILL.md" : entry.slice(skillDir.length + 1);
800
+ return {
801
+ path: normalizePortablePath(relative),
802
+ kind: classifyInventoryKind(relative),
803
+ };
804
+ })
805
+ .sort((left, right) => left.path.localeCompare(right.path));
806
+ const imported = await readLocalSkillImportFromDirectory(companyId, path.join(root, skillDir));
807
+ imported.fileInventory = inventory;
808
+ imported.trustLevel = deriveTrustLevel(inventory);
809
+ imports.push(imported);
810
+ }
811
+ return imports;
812
+ }
813
+ async function readUrlSkillImports(companyId, sourceUrl, requestedSkillSlug = null) {
814
+ const url = sourceUrl.trim();
815
+ const warnings = [];
816
+ const looksLikeRepoUrl = (() => {
817
+ try {
818
+ const parsed = new URL(url);
819
+ if (parsed.protocol !== "https:")
820
+ return false;
821
+ const h = parsed.hostname.toLowerCase();
822
+ if (h.endsWith(".githubusercontent.com") || h === "gist.github.com")
823
+ return false;
824
+ const segments = parsed.pathname.split("/").filter(Boolean);
825
+ return segments.length >= 2 && !parsed.pathname.endsWith(".md");
826
+ }
827
+ catch {
828
+ return false;
829
+ }
830
+ })();
831
+ if (looksLikeRepoUrl) {
832
+ const parsed = parseGitHubSourceUrl(url);
833
+ const apiBase = gitHubApiBase(parsed.hostname);
834
+ const { pinnedRef, trackingRef } = await resolveGitHubPinnedRef(parsed);
835
+ let ref = pinnedRef;
836
+ const tree = await fetchJson(`${apiBase}/repos/${parsed.owner}/${parsed.repo}/git/trees/${ref}?recursive=1`).catch(() => {
837
+ throw unprocessable(`Failed to read GitHub tree for ${url}`);
838
+ });
839
+ const allPaths = (tree.tree ?? [])
840
+ .filter((entry) => entry.type === "blob")
841
+ .map((entry) => entry.path)
842
+ .filter((entry) => typeof entry === "string");
843
+ const basePrefix = parsed.basePath ? `${parsed.basePath.replace(/^\/+|\/+$/g, "")}/` : "";
844
+ const scopedPaths = basePrefix
845
+ ? allPaths.filter((entry) => entry.startsWith(basePrefix))
846
+ : allPaths;
847
+ const relativePaths = scopedPaths.map((entry) => basePrefix ? entry.slice(basePrefix.length) : entry);
848
+ const filteredPaths = parsed.filePath
849
+ ? relativePaths.filter((entry) => entry === path.posix.relative(parsed.basePath || ".", parsed.filePath))
850
+ : relativePaths;
851
+ const skillPaths = filteredPaths.filter((entry) => path.posix.basename(entry).toLowerCase() === "skill.md");
852
+ if (skillPaths.length === 0) {
853
+ throw unprocessable("No SKILL.md files were found in the provided GitHub source.");
854
+ }
855
+ const skills = [];
856
+ for (const relativeSkillPath of skillPaths) {
857
+ const repoSkillPath = basePrefix ? `${basePrefix}${relativeSkillPath}` : relativeSkillPath;
858
+ const markdown = await fetchText(resolveRawGitHubUrl(parsed.hostname, parsed.owner, parsed.repo, ref, repoSkillPath));
859
+ const parsedMarkdown = parseFrontmatterMarkdown(markdown);
860
+ const skillDir = path.posix.dirname(relativeSkillPath);
861
+ const slug = deriveImportedSkillSlug(parsedMarkdown.frontmatter, path.posix.basename(skillDir));
862
+ const skillKey = readCanonicalSkillKey(parsedMarkdown.frontmatter, isPlainRecord(parsedMarkdown.frontmatter.metadata) ? parsedMarkdown.frontmatter.metadata : null);
863
+ if (requestedSkillSlug && !matchesRequestedSkill(relativeSkillPath, requestedSkillSlug) && slug !== requestedSkillSlug) {
864
+ continue;
865
+ }
866
+ const metadata = {
867
+ ...(skillKey ? { skillKey } : {}),
868
+ sourceKind: "github",
869
+ ...(parsed.hostname !== "github.com" ? { hostname: parsed.hostname } : {}),
870
+ owner: parsed.owner,
871
+ repo: parsed.repo,
872
+ ref,
873
+ trackingRef,
874
+ repoSkillDir: normalizeGitHubSkillDirectory(basePrefix ? `${basePrefix}${skillDir}` : skillDir, slug),
875
+ };
876
+ const inventory = filteredPaths
877
+ .filter((entry) => entry === relativeSkillPath || entry.startsWith(`${skillDir}/`))
878
+ .map((entry) => ({
879
+ path: entry === relativeSkillPath ? "SKILL.md" : entry.slice(skillDir.length + 1),
880
+ kind: classifyInventoryKind(entry === relativeSkillPath ? "SKILL.md" : entry.slice(skillDir.length + 1)),
881
+ }))
882
+ .sort((left, right) => left.path.localeCompare(right.path));
883
+ skills.push({
884
+ key: deriveCanonicalSkillKey(companyId, {
885
+ slug,
886
+ sourceType: "github",
887
+ sourceLocator: sourceUrl,
888
+ metadata,
889
+ }),
890
+ slug,
891
+ name: asString(parsedMarkdown.frontmatter.name) ?? slug,
892
+ description: asString(parsedMarkdown.frontmatter.description),
893
+ markdown,
894
+ sourceType: "github",
895
+ sourceLocator: sourceUrl,
896
+ sourceRef: ref,
897
+ trustLevel: deriveTrustLevel(inventory),
898
+ compatibility: "compatible",
899
+ fileInventory: inventory,
900
+ metadata,
901
+ });
902
+ }
903
+ if (skills.length === 0) {
904
+ throw unprocessable(requestedSkillSlug
905
+ ? `Skill ${requestedSkillSlug} was not found in the provided GitHub source.`
906
+ : "No SKILL.md files were found in the provided GitHub source.");
907
+ }
908
+ return { skills, warnings };
909
+ }
910
+ if (url.startsWith("http://") || url.startsWith("https://")) {
911
+ const markdown = await fetchText(url);
912
+ const parsedMarkdown = parseFrontmatterMarkdown(markdown);
913
+ const urlObj = new URL(url);
914
+ const fileName = path.posix.basename(urlObj.pathname);
915
+ const slug = deriveImportedSkillSlug(parsedMarkdown.frontmatter, fileName.replace(/\.md$/i, ""));
916
+ const skillKey = readCanonicalSkillKey(parsedMarkdown.frontmatter, isPlainRecord(parsedMarkdown.frontmatter.metadata) ? parsedMarkdown.frontmatter.metadata : null);
917
+ const metadata = {
918
+ ...(skillKey ? { skillKey } : {}),
919
+ sourceKind: "url",
920
+ };
921
+ const inventory = [{ path: "SKILL.md", kind: "skill" }];
922
+ return {
923
+ skills: [{
924
+ key: deriveCanonicalSkillKey(companyId, {
925
+ slug,
926
+ sourceType: "url",
927
+ sourceLocator: url,
928
+ metadata,
929
+ }),
930
+ slug,
931
+ name: asString(parsedMarkdown.frontmatter.name) ?? slug,
932
+ description: asString(parsedMarkdown.frontmatter.description),
933
+ markdown,
934
+ sourceType: "url",
935
+ sourceLocator: url,
936
+ sourceRef: null,
937
+ trustLevel: deriveTrustLevel(inventory),
938
+ compatibility: "compatible",
939
+ fileInventory: inventory,
940
+ metadata,
941
+ }],
942
+ warnings,
943
+ };
944
+ }
945
+ throw unprocessable("Unsupported skill source. Use a local path or URL.");
946
+ }
947
+ function toCompanySkill(row) {
948
+ return {
949
+ ...row,
950
+ description: row.description ?? null,
951
+ sourceType: row.sourceType,
952
+ sourceLocator: row.sourceLocator ?? null,
953
+ sourceRef: row.sourceRef ?? null,
954
+ trustLevel: row.trustLevel,
955
+ compatibility: row.compatibility,
956
+ fileInventory: Array.isArray(row.fileInventory)
957
+ ? row.fileInventory.flatMap((entry) => {
958
+ if (!isPlainRecord(entry))
959
+ return [];
960
+ return [{
961
+ path: String(entry.path ?? ""),
962
+ kind: String(entry.kind ?? "other"),
963
+ }];
964
+ })
965
+ : [],
966
+ metadata: isPlainRecord(row.metadata) ? row.metadata : null,
967
+ };
968
+ }
969
+ function serializeFileInventory(fileInventory) {
970
+ return fileInventory.map((entry) => ({
971
+ path: entry.path,
972
+ kind: entry.kind,
973
+ }));
974
+ }
975
+ function getSkillMeta(skill) {
976
+ return isPlainRecord(skill.metadata) ? skill.metadata : {};
977
+ }
978
+ function resolveSkillReference(skills, reference) {
979
+ const trimmed = reference.trim();
980
+ if (!trimmed) {
981
+ return { skill: null, ambiguous: false };
982
+ }
983
+ const byId = skills.find((skill) => skill.id === trimmed);
984
+ if (byId) {
985
+ return { skill: byId, ambiguous: false };
986
+ }
987
+ const normalizedKey = normalizeSkillKey(trimmed);
988
+ if (normalizedKey) {
989
+ const byKey = skills.find((skill) => skill.key === normalizedKey);
990
+ if (byKey) {
991
+ return { skill: byKey, ambiguous: false };
992
+ }
993
+ }
994
+ const normalizedSlug = normalizeSkillSlug(trimmed);
995
+ if (!normalizedSlug) {
996
+ return { skill: null, ambiguous: false };
997
+ }
998
+ const bySlug = skills.filter((skill) => skill.slug === normalizedSlug);
999
+ if (bySlug.length === 1) {
1000
+ return { skill: bySlug[0] ?? null, ambiguous: false };
1001
+ }
1002
+ if (bySlug.length > 1) {
1003
+ return { skill: null, ambiguous: true };
1004
+ }
1005
+ return { skill: null, ambiguous: false };
1006
+ }
1007
+ function resolveRequestedSkillKeysOrThrow(skills, requestedReferences) {
1008
+ const missing = new Set();
1009
+ const ambiguous = new Set();
1010
+ const resolved = new Set();
1011
+ for (const reference of requestedReferences) {
1012
+ const trimmed = reference.trim();
1013
+ if (!trimmed)
1014
+ continue;
1015
+ const match = resolveSkillReference(skills, trimmed);
1016
+ if (match.skill) {
1017
+ resolved.add(match.skill.key);
1018
+ continue;
1019
+ }
1020
+ if (match.ambiguous) {
1021
+ ambiguous.add(trimmed);
1022
+ continue;
1023
+ }
1024
+ missing.add(trimmed);
1025
+ }
1026
+ if (ambiguous.size > 0 || missing.size > 0) {
1027
+ const problems = [];
1028
+ if (ambiguous.size > 0) {
1029
+ problems.push(`ambiguous references: ${Array.from(ambiguous).sort().join(", ")}`);
1030
+ }
1031
+ if (missing.size > 0) {
1032
+ problems.push(`unknown references: ${Array.from(missing).sort().join(", ")}`);
1033
+ }
1034
+ throw unprocessable(`Invalid company skill selection (${problems.join("; ")}).`);
1035
+ }
1036
+ return Array.from(resolved);
1037
+ }
1038
+ function resolveDesiredSkillKeys(skills, config) {
1039
+ const preference = readzmeelSkillSyncPreference(config);
1040
+ return Array.from(new Set(preference.desiredSkills
1041
+ .map((reference) => resolveSkillReference(skills, reference).skill?.key ?? normalizeSkillKey(reference))
1042
+ .filter((value) => Boolean(value))));
1043
+ }
1044
+ function normalizeSkillDirectory(skill) {
1045
+ if ((skill.sourceType !== "local_path" && skill.sourceType !== "catalog") || !skill.sourceLocator)
1046
+ return null;
1047
+ const resolved = path.resolve(skill.sourceLocator);
1048
+ if (path.basename(resolved).toLowerCase() === "skill.md") {
1049
+ return path.dirname(resolved);
1050
+ }
1051
+ return resolved;
1052
+ }
1053
+ function normalizeSourceLocatorDirectory(sourceLocator) {
1054
+ if (!sourceLocator)
1055
+ return null;
1056
+ const resolved = path.resolve(sourceLocator);
1057
+ return path.basename(resolved).toLowerCase() === "skill.md" ? path.dirname(resolved) : resolved;
1058
+ }
1059
+ export async function findMissingLocalSkillIds(skills) {
1060
+ const missingIds = [];
1061
+ for (const skill of skills) {
1062
+ if (skill.sourceType !== "local_path")
1063
+ continue;
1064
+ const skillDir = normalizeSourceLocatorDirectory(skill.sourceLocator);
1065
+ if (!skillDir) {
1066
+ missingIds.push(skill.id);
1067
+ continue;
1068
+ }
1069
+ const skillDirStat = await statPath(skillDir);
1070
+ const skillFileStat = await statPath(path.join(skillDir, "SKILL.md"));
1071
+ if (!skillDirStat?.isDirectory() || !skillFileStat?.isFile()) {
1072
+ missingIds.push(skill.id);
1073
+ }
1074
+ }
1075
+ return missingIds;
1076
+ }
1077
+ function resolveManagedSkillsRoot(companyId) {
1078
+ return path.resolve(resolvezmeelInstanceRoot(), "skills", companyId);
1079
+ }
1080
+ function resolveLocalSkillFilePath(skill, relativePath) {
1081
+ const normalized = normalizePortablePath(relativePath);
1082
+ const skillDir = normalizeSkillDirectory(skill);
1083
+ if (skillDir) {
1084
+ return path.resolve(skillDir, normalized);
1085
+ }
1086
+ if (!skill.sourceLocator)
1087
+ return null;
1088
+ const fallbackRoot = path.resolve(skill.sourceLocator);
1089
+ const directPath = path.resolve(fallbackRoot, normalized);
1090
+ return directPath;
1091
+ }
1092
+ function inferLanguageFromPath(filePath) {
1093
+ const fileName = path.posix.basename(filePath).toLowerCase();
1094
+ if (fileName === "skill.md" || fileName.endsWith(".md"))
1095
+ return "markdown";
1096
+ if (fileName.endsWith(".ts"))
1097
+ return "typescript";
1098
+ if (fileName.endsWith(".tsx"))
1099
+ return "tsx";
1100
+ if (fileName.endsWith(".js"))
1101
+ return "javascript";
1102
+ if (fileName.endsWith(".jsx"))
1103
+ return "jsx";
1104
+ if (fileName.endsWith(".json"))
1105
+ return "json";
1106
+ if (fileName.endsWith(".yml") || fileName.endsWith(".yaml"))
1107
+ return "yaml";
1108
+ if (fileName.endsWith(".sh"))
1109
+ return "bash";
1110
+ if (fileName.endsWith(".py"))
1111
+ return "python";
1112
+ if (fileName.endsWith(".html"))
1113
+ return "html";
1114
+ if (fileName.endsWith(".css"))
1115
+ return "css";
1116
+ return null;
1117
+ }
1118
+ function isMarkdownPath(filePath) {
1119
+ const fileName = path.posix.basename(filePath).toLowerCase();
1120
+ return fileName === "skill.md" || fileName.endsWith(".md");
1121
+ }
1122
+ function deriveSkillSourceInfo(skill) {
1123
+ const metadata = getSkillMeta(skill);
1124
+ const localSkillDir = normalizeSkillDirectory(skill);
1125
+ if (metadata.sourceKind === "zmeel_bundled") {
1126
+ return {
1127
+ editable: false,
1128
+ editableReason: "Bundled zmeel skills are read-only.",
1129
+ sourceLabel: "zmeel bundled",
1130
+ sourceBadge: "zmeel",
1131
+ sourcePath: null,
1132
+ };
1133
+ }
1134
+ if (skill.sourceType === "skills_sh") {
1135
+ const owner = asString(metadata.owner) ?? null;
1136
+ const repo = asString(metadata.repo) ?? null;
1137
+ return {
1138
+ editable: false,
1139
+ editableReason: "Skills.sh-managed skills are read-only.",
1140
+ sourceLabel: skill.sourceLocator ?? (owner && repo ? `${owner}/${repo}` : null),
1141
+ sourceBadge: "skills_sh",
1142
+ sourcePath: null,
1143
+ };
1144
+ }
1145
+ if (skill.sourceType === "github") {
1146
+ const owner = asString(metadata.owner) ?? null;
1147
+ const repo = asString(metadata.repo) ?? null;
1148
+ return {
1149
+ editable: false,
1150
+ editableReason: "Remote GitHub skills are read-only. Fork or import locally to edit them.",
1151
+ sourceLabel: owner && repo ? `${owner}/${repo}` : skill.sourceLocator,
1152
+ sourceBadge: "github",
1153
+ sourcePath: null,
1154
+ };
1155
+ }
1156
+ if (skill.sourceType === "url") {
1157
+ return {
1158
+ editable: false,
1159
+ editableReason: "URL-based skills are read-only. Save them locally to edit them.",
1160
+ sourceLabel: skill.sourceLocator,
1161
+ sourceBadge: "url",
1162
+ sourcePath: null,
1163
+ };
1164
+ }
1165
+ if (skill.sourceType === "local_path") {
1166
+ const managedRoot = resolveManagedSkillsRoot(skill.companyId);
1167
+ const projectName = asString(metadata.projectName);
1168
+ const workspaceName = asString(metadata.workspaceName);
1169
+ const isProjectScan = metadata.sourceKind === "project_scan";
1170
+ if (localSkillDir && localSkillDir.startsWith(managedRoot)) {
1171
+ return {
1172
+ editable: true,
1173
+ editableReason: null,
1174
+ sourceLabel: "zmeel workspace",
1175
+ sourceBadge: "zmeel",
1176
+ sourcePath: managedRoot,
1177
+ };
1178
+ }
1179
+ return {
1180
+ editable: true,
1181
+ editableReason: null,
1182
+ sourceLabel: isProjectScan
1183
+ ? [projectName, workspaceName].filter((value) => Boolean(value)).join(" / ")
1184
+ || skill.sourceLocator
1185
+ : skill.sourceLocator,
1186
+ sourceBadge: "local",
1187
+ sourcePath: null,
1188
+ };
1189
+ }
1190
+ return {
1191
+ editable: false,
1192
+ editableReason: "This skill source is read-only.",
1193
+ sourceLabel: skill.sourceLocator,
1194
+ sourceBadge: "catalog",
1195
+ sourcePath: null,
1196
+ };
1197
+ }
1198
+ function enrichSkill(skill, attachedAgentCount, usedByAgents = []) {
1199
+ const source = deriveSkillSourceInfo(skill);
1200
+ return {
1201
+ ...skill,
1202
+ attachedAgentCount,
1203
+ usedByAgents,
1204
+ ...source,
1205
+ };
1206
+ }
1207
+ function toCompanySkillListItem(skill, attachedAgentCount) {
1208
+ const source = deriveSkillSourceInfo(skill);
1209
+ return {
1210
+ id: skill.id,
1211
+ companyId: skill.companyId,
1212
+ key: skill.key,
1213
+ slug: skill.slug,
1214
+ name: skill.name,
1215
+ description: skill.description,
1216
+ sourceType: skill.sourceType,
1217
+ sourceLocator: skill.sourceLocator,
1218
+ sourceRef: skill.sourceRef,
1219
+ trustLevel: skill.trustLevel,
1220
+ compatibility: skill.compatibility,
1221
+ fileInventory: skill.fileInventory,
1222
+ createdAt: skill.createdAt,
1223
+ updatedAt: skill.updatedAt,
1224
+ attachedAgentCount,
1225
+ editable: source.editable,
1226
+ editableReason: source.editableReason,
1227
+ sourceLabel: source.sourceLabel,
1228
+ sourceBadge: source.sourceBadge,
1229
+ sourcePath: source.sourcePath,
1230
+ };
1231
+ }
1232
+ export function companySkillService(db) {
1233
+ const agents = agentService(db);
1234
+ const projects = projectService(db);
1235
+ const secretsSvc = secretService(db);
1236
+ async function ensureBundledSkills(companyId) {
1237
+ for (const skillsRoot of resolveBundledSkillsRoot()) {
1238
+ const stats = await fs.stat(skillsRoot).catch(() => null);
1239
+ if (!stats?.isDirectory())
1240
+ continue;
1241
+ const bundledSkills = await readLocalSkillImports(companyId, skillsRoot)
1242
+ .then((skills) => skills.map((skill) => ({
1243
+ ...skill,
1244
+ key: deriveCanonicalSkillKey(companyId, {
1245
+ ...skill,
1246
+ metadata: {
1247
+ ...(skill.metadata ?? {}),
1248
+ sourceKind: "zmeel_bundled",
1249
+ },
1250
+ }),
1251
+ metadata: {
1252
+ ...(skill.metadata ?? {}),
1253
+ sourceKind: "zmeel_bundled",
1254
+ },
1255
+ })))
1256
+ .catch(() => []);
1257
+ if (bundledSkills.length === 0)
1258
+ continue;
1259
+ return upsertImportedSkills(companyId, bundledSkills);
1260
+ }
1261
+ return [];
1262
+ }
1263
+ async function pruneMissingLocalPathSkills(companyId) {
1264
+ const rows = await db
1265
+ .select()
1266
+ .from(companySkills)
1267
+ .where(eq(companySkills.companyId, companyId));
1268
+ const skills = rows.map((row) => toCompanySkill(row));
1269
+ const missingIds = new Set(await findMissingLocalSkillIds(skills));
1270
+ if (missingIds.size === 0)
1271
+ return;
1272
+ for (const skill of skills) {
1273
+ if (!missingIds.has(skill.id))
1274
+ continue;
1275
+ await db
1276
+ .delete(companySkills)
1277
+ .where(eq(companySkills.id, skill.id));
1278
+ await fs.rm(resolveRuntimeSkillMaterializedPath(companyId, skill), { recursive: true, force: true });
1279
+ }
1280
+ }
1281
+ async function ensureSkillInventoryCurrent(companyId) {
1282
+ const existingRefresh = skillInventoryRefreshPromises.get(companyId);
1283
+ if (existingRefresh) {
1284
+ await existingRefresh;
1285
+ return;
1286
+ }
1287
+ const refreshPromise = (async () => {
1288
+ await ensureBundledSkills(companyId);
1289
+ await pruneMissingLocalPathSkills(companyId);
1290
+ })();
1291
+ skillInventoryRefreshPromises.set(companyId, refreshPromise);
1292
+ try {
1293
+ await refreshPromise;
1294
+ }
1295
+ finally {
1296
+ if (skillInventoryRefreshPromises.get(companyId) === refreshPromise) {
1297
+ skillInventoryRefreshPromises.delete(companyId);
1298
+ }
1299
+ }
1300
+ }
1301
+ async function list(companyId) {
1302
+ const rows = await listFull(companyId);
1303
+ const agentRows = await agents.list(companyId);
1304
+ return rows.map((skill) => {
1305
+ const attachedAgentCount = agentRows.filter((agent) => {
1306
+ const desiredSkills = resolveDesiredSkillKeys(rows, agent.adapterConfig);
1307
+ return desiredSkills.includes(skill.key);
1308
+ }).length;
1309
+ return toCompanySkillListItem(skill, attachedAgentCount);
1310
+ });
1311
+ }
1312
+ async function listFull(companyId) {
1313
+ await ensureSkillInventoryCurrent(companyId);
1314
+ const rows = await db
1315
+ .select()
1316
+ .from(companySkills)
1317
+ .where(eq(companySkills.companyId, companyId))
1318
+ .orderBy(asc(companySkills.name), asc(companySkills.key));
1319
+ return rows.map((row) => toCompanySkill(row));
1320
+ }
1321
+ async function getById(id) {
1322
+ const row = await db
1323
+ .select()
1324
+ .from(companySkills)
1325
+ .where(eq(companySkills.id, id))
1326
+ .then((rows) => rows[0] ?? null);
1327
+ return row ? toCompanySkill(row) : null;
1328
+ }
1329
+ async function getByKey(companyId, key) {
1330
+ const row = await db
1331
+ .select()
1332
+ .from(companySkills)
1333
+ .where(and(eq(companySkills.companyId, companyId), eq(companySkills.key, key)))
1334
+ .then((rows) => rows[0] ?? null);
1335
+ return row ? toCompanySkill(row) : null;
1336
+ }
1337
+ async function usage(companyId, key) {
1338
+ const skills = await listFull(companyId);
1339
+ const agentRows = await agents.list(companyId);
1340
+ const desiredAgents = agentRows.filter((agent) => {
1341
+ const desiredSkills = resolveDesiredSkillKeys(skills, agent.adapterConfig);
1342
+ return desiredSkills.includes(key);
1343
+ });
1344
+ return Promise.all(desiredAgents.map(async (agent) => {
1345
+ const adapter = findServerAdapter(agent.adapterType);
1346
+ let actualState = null;
1347
+ if (!adapter?.listSkills) {
1348
+ actualState = "unsupported";
1349
+ }
1350
+ else {
1351
+ try {
1352
+ const { config: runtimeConfig } = await secretsSvc.resolveAdapterConfigForRuntime(agent.companyId, agent.adapterConfig);
1353
+ const runtimeSkillEntries = await listRuntimeSkillEntries(agent.companyId);
1354
+ const snapshot = await adapter.listSkills({
1355
+ agentId: agent.id,
1356
+ companyId: agent.companyId,
1357
+ adapterType: agent.adapterType,
1358
+ config: {
1359
+ ...runtimeConfig,
1360
+ zmeelRuntimeSkills: runtimeSkillEntries,
1361
+ },
1362
+ });
1363
+ actualState = snapshot.entries.find((entry) => entry.key === key)?.state
1364
+ ?? (snapshot.supported ? "missing" : "unsupported");
1365
+ }
1366
+ catch {
1367
+ actualState = "unknown";
1368
+ }
1369
+ }
1370
+ return {
1371
+ id: agent.id,
1372
+ name: agent.name,
1373
+ urlKey: agent.urlKey,
1374
+ adapterType: agent.adapterType,
1375
+ desired: true,
1376
+ actualState,
1377
+ };
1378
+ }));
1379
+ }
1380
+ async function detail(companyId, id) {
1381
+ await ensureSkillInventoryCurrent(companyId);
1382
+ const skill = await getById(id);
1383
+ if (!skill || skill.companyId !== companyId)
1384
+ return null;
1385
+ const usedByAgents = await usage(companyId, skill.key);
1386
+ return enrichSkill(skill, usedByAgents.length, usedByAgents);
1387
+ }
1388
+ async function updateStatus(companyId, skillId) {
1389
+ await ensureSkillInventoryCurrent(companyId);
1390
+ const skill = await getById(skillId);
1391
+ if (!skill || skill.companyId !== companyId)
1392
+ return null;
1393
+ if (skill.sourceType !== "github" && skill.sourceType !== "skills_sh") {
1394
+ return {
1395
+ supported: false,
1396
+ reason: "Only GitHub-managed skills support update checks.",
1397
+ trackingRef: null,
1398
+ currentRef: skill.sourceRef ?? null,
1399
+ latestRef: null,
1400
+ hasUpdate: false,
1401
+ };
1402
+ }
1403
+ const metadata = getSkillMeta(skill);
1404
+ const owner = asString(metadata.owner);
1405
+ const repo = asString(metadata.repo);
1406
+ const trackingRef = asString(metadata.trackingRef) ?? asString(metadata.ref);
1407
+ if (!owner || !repo || !trackingRef) {
1408
+ return {
1409
+ supported: false,
1410
+ reason: "This GitHub skill does not have enough metadata to track updates.",
1411
+ trackingRef: trackingRef ?? null,
1412
+ currentRef: skill.sourceRef ?? null,
1413
+ latestRef: null,
1414
+ hasUpdate: false,
1415
+ };
1416
+ }
1417
+ const hostname = asString(metadata.hostname) || "github.com";
1418
+ const apiBase = gitHubApiBase(hostname);
1419
+ const latestRef = await resolveGitHubCommitSha(owner, repo, trackingRef, apiBase);
1420
+ return {
1421
+ supported: true,
1422
+ reason: null,
1423
+ trackingRef,
1424
+ currentRef: skill.sourceRef ?? null,
1425
+ latestRef,
1426
+ hasUpdate: latestRef !== (skill.sourceRef ?? null),
1427
+ };
1428
+ }
1429
+ async function readFile(companyId, skillId, relativePath) {
1430
+ await ensureSkillInventoryCurrent(companyId);
1431
+ const skill = await getById(skillId);
1432
+ if (!skill || skill.companyId !== companyId)
1433
+ return null;
1434
+ const normalizedPath = normalizePortablePath(relativePath || "SKILL.md");
1435
+ const fileEntry = skill.fileInventory.find((entry) => entry.path === normalizedPath);
1436
+ if (!fileEntry) {
1437
+ throw notFound("Skill file not found");
1438
+ }
1439
+ const source = deriveSkillSourceInfo(skill);
1440
+ let content = "";
1441
+ if (skill.sourceType === "local_path" || skill.sourceType === "catalog") {
1442
+ const absolutePath = resolveLocalSkillFilePath(skill, normalizedPath);
1443
+ if (absolutePath) {
1444
+ content = await fs.readFile(absolutePath, "utf8");
1445
+ }
1446
+ else if (normalizedPath === "SKILL.md") {
1447
+ content = skill.markdown;
1448
+ }
1449
+ else {
1450
+ throw notFound("Skill file not found");
1451
+ }
1452
+ }
1453
+ else if (skill.sourceType === "github" || skill.sourceType === "skills_sh") {
1454
+ const metadata = getSkillMeta(skill);
1455
+ const owner = asString(metadata.owner);
1456
+ const repo = asString(metadata.repo);
1457
+ const hostname = asString(metadata.hostname) || "github.com";
1458
+ const ref = skill.sourceRef ?? asString(metadata.ref) ?? "main";
1459
+ const repoSkillDir = normalizeGitHubSkillDirectory(asString(metadata.repoSkillDir), skill.slug);
1460
+ if (!owner || !repo) {
1461
+ throw unprocessable("Skill source metadata is incomplete.");
1462
+ }
1463
+ const repoPath = normalizePortablePath(path.posix.join(repoSkillDir, normalizedPath));
1464
+ content = await fetchText(resolveRawGitHubUrl(hostname, owner, repo, ref, repoPath));
1465
+ }
1466
+ else if (skill.sourceType === "url") {
1467
+ if (normalizedPath !== "SKILL.md") {
1468
+ throw notFound("This skill source only exposes SKILL.md");
1469
+ }
1470
+ content = skill.markdown;
1471
+ }
1472
+ else {
1473
+ throw unprocessable("Unsupported skill source.");
1474
+ }
1475
+ return {
1476
+ skillId: skill.id,
1477
+ path: normalizedPath,
1478
+ kind: fileEntry.kind,
1479
+ content,
1480
+ language: inferLanguageFromPath(normalizedPath),
1481
+ markdown: isMarkdownPath(normalizedPath),
1482
+ editable: source.editable,
1483
+ };
1484
+ }
1485
+ async function createLocalSkill(companyId, input) {
1486
+ const slug = normalizeSkillSlug(input.slug ?? input.name) ?? "skill";
1487
+ const managedRoot = resolveManagedSkillsRoot(companyId);
1488
+ const skillDir = path.resolve(managedRoot, slug);
1489
+ const skillFilePath = path.resolve(skillDir, "SKILL.md");
1490
+ await fs.mkdir(skillDir, { recursive: true });
1491
+ const markdown = (input.markdown?.trim().length
1492
+ ? input.markdown
1493
+ : [
1494
+ "---",
1495
+ `name: ${input.name}`,
1496
+ ...(input.description?.trim() ? [`description: ${input.description.trim()}`] : []),
1497
+ "---",
1498
+ "",
1499
+ `# ${input.name}`,
1500
+ "",
1501
+ input.description?.trim() ? input.description.trim() : "Describe what this skill does.",
1502
+ "",
1503
+ ].join("\n"));
1504
+ await fs.writeFile(skillFilePath, markdown, "utf8");
1505
+ const parsed = parseFrontmatterMarkdown(markdown);
1506
+ const imported = await upsertImportedSkills(companyId, [{
1507
+ key: `company/${companyId}/${slug}`,
1508
+ slug,
1509
+ name: asString(parsed.frontmatter.name) ?? input.name,
1510
+ description: asString(parsed.frontmatter.description) ?? input.description?.trim() ?? null,
1511
+ markdown,
1512
+ sourceType: "local_path",
1513
+ sourceLocator: skillDir,
1514
+ sourceRef: null,
1515
+ trustLevel: "markdown_only",
1516
+ compatibility: "compatible",
1517
+ fileInventory: [{ path: "SKILL.md", kind: "skill" }],
1518
+ metadata: { sourceKind: "managed_local" },
1519
+ }]);
1520
+ return imported[0];
1521
+ }
1522
+ async function updateFile(companyId, skillId, relativePath, content) {
1523
+ await ensureSkillInventoryCurrent(companyId);
1524
+ const skill = await getById(skillId);
1525
+ if (!skill || skill.companyId !== companyId)
1526
+ throw notFound("Skill not found");
1527
+ const source = deriveSkillSourceInfo(skill);
1528
+ if (!source.editable || skill.sourceType !== "local_path") {
1529
+ throw unprocessable(source.editableReason ?? "This skill cannot be edited.");
1530
+ }
1531
+ const normalizedPath = normalizePortablePath(relativePath);
1532
+ const absolutePath = resolveLocalSkillFilePath(skill, normalizedPath);
1533
+ if (!absolutePath)
1534
+ throw notFound("Skill file not found");
1535
+ await fs.mkdir(path.dirname(absolutePath), { recursive: true });
1536
+ await fs.writeFile(absolutePath, content, "utf8");
1537
+ if (normalizedPath === "SKILL.md") {
1538
+ const parsed = parseFrontmatterMarkdown(content);
1539
+ await db
1540
+ .update(companySkills)
1541
+ .set({
1542
+ name: asString(parsed.frontmatter.name) ?? skill.name,
1543
+ description: asString(parsed.frontmatter.description) ?? skill.description,
1544
+ markdown: content,
1545
+ updatedAt: new Date(),
1546
+ })
1547
+ .where(eq(companySkills.id, skill.id));
1548
+ }
1549
+ else {
1550
+ await db
1551
+ .update(companySkills)
1552
+ .set({ updatedAt: new Date() })
1553
+ .where(eq(companySkills.id, skill.id));
1554
+ }
1555
+ const detail = await readFile(companyId, skillId, normalizedPath);
1556
+ if (!detail)
1557
+ throw notFound("Skill file not found");
1558
+ return detail;
1559
+ }
1560
+ async function installUpdate(companyId, skillId) {
1561
+ await ensureSkillInventoryCurrent(companyId);
1562
+ const skill = await getById(skillId);
1563
+ if (!skill || skill.companyId !== companyId)
1564
+ return null;
1565
+ const status = await updateStatus(companyId, skillId);
1566
+ if (!status?.supported) {
1567
+ throw unprocessable(status?.reason ?? "This skill does not support updates.");
1568
+ }
1569
+ if (!skill.sourceLocator) {
1570
+ throw unprocessable("Skill source locator is missing.");
1571
+ }
1572
+ const result = await readUrlSkillImports(companyId, skill.sourceLocator, skill.slug);
1573
+ const matching = result.skills.find((entry) => entry.key === skill.key) ?? result.skills[0] ?? null;
1574
+ if (!matching) {
1575
+ throw unprocessable(`Skill ${skill.key} could not be re-imported from its source.`);
1576
+ }
1577
+ const imported = await upsertImportedSkills(companyId, [matching]);
1578
+ return imported[0] ?? null;
1579
+ }
1580
+ async function scanProjectWorkspaces(companyId, input = {}) {
1581
+ await ensureSkillInventoryCurrent(companyId);
1582
+ const projectRows = input.projectIds?.length
1583
+ ? await projects.listByIds(companyId, input.projectIds)
1584
+ : await projects.list(companyId);
1585
+ const workspaceFilter = new Set(input.workspaceIds ?? []);
1586
+ const skipped = [];
1587
+ const conflicts = [];
1588
+ const warnings = [];
1589
+ const imported = [];
1590
+ const updated = [];
1591
+ const availableSkills = await listFull(companyId);
1592
+ const acceptedSkills = [...availableSkills];
1593
+ const acceptedByKey = new Map(acceptedSkills.map((skill) => [skill.key, skill]));
1594
+ const scanTargets = [];
1595
+ const scannedProjectIds = new Set();
1596
+ let discovered = 0;
1597
+ const trackWarning = (message) => {
1598
+ warnings.push(message);
1599
+ return message;
1600
+ };
1601
+ const upsertAcceptedSkill = (skill) => {
1602
+ const nextIndex = acceptedSkills.findIndex((entry) => entry.id === skill.id || entry.key === skill.key);
1603
+ if (nextIndex >= 0)
1604
+ acceptedSkills[nextIndex] = skill;
1605
+ else
1606
+ acceptedSkills.push(skill);
1607
+ acceptedByKey.set(skill.key, skill);
1608
+ };
1609
+ for (const project of projectRows) {
1610
+ for (const workspace of project.workspaces) {
1611
+ if (workspaceFilter.size > 0 && !workspaceFilter.has(workspace.id))
1612
+ continue;
1613
+ const workspaceCwd = asString(workspace.cwd);
1614
+ if (!workspaceCwd) {
1615
+ skipped.push({
1616
+ projectId: project.id,
1617
+ projectName: project.name,
1618
+ workspaceId: workspace.id,
1619
+ workspaceName: workspace.name,
1620
+ path: null,
1621
+ reason: trackWarning(`Skipped ${project.name} / ${workspace.name}: no local workspace path is configured.`),
1622
+ });
1623
+ continue;
1624
+ }
1625
+ const workspaceStat = await statPath(workspaceCwd);
1626
+ if (!workspaceStat?.isDirectory()) {
1627
+ skipped.push({
1628
+ projectId: project.id,
1629
+ projectName: project.name,
1630
+ workspaceId: workspace.id,
1631
+ workspaceName: workspace.name,
1632
+ path: workspaceCwd,
1633
+ reason: trackWarning(`Skipped ${project.name} / ${workspace.name}: local workspace path is not available at ${workspaceCwd}.`),
1634
+ });
1635
+ continue;
1636
+ }
1637
+ scanTargets.push({
1638
+ projectId: project.id,
1639
+ projectName: project.name,
1640
+ workspaceId: workspace.id,
1641
+ workspaceName: workspace.name,
1642
+ workspaceCwd,
1643
+ });
1644
+ }
1645
+ }
1646
+ for (const target of scanTargets) {
1647
+ scannedProjectIds.add(target.projectId);
1648
+ const directories = await discoverProjectWorkspaceSkillDirectories(target);
1649
+ for (const directory of directories) {
1650
+ discovered += 1;
1651
+ let nextSkill;
1652
+ try {
1653
+ nextSkill = await readLocalSkillImportFromDirectory(companyId, directory.skillDir, {
1654
+ inventoryMode: directory.inventoryMode,
1655
+ metadata: {
1656
+ sourceKind: "project_scan",
1657
+ projectId: target.projectId,
1658
+ projectName: target.projectName,
1659
+ workspaceId: target.workspaceId,
1660
+ workspaceName: target.workspaceName,
1661
+ workspaceCwd: target.workspaceCwd,
1662
+ },
1663
+ });
1664
+ }
1665
+ catch (error) {
1666
+ const message = error instanceof Error ? error.message : String(error);
1667
+ skipped.push({
1668
+ projectId: target.projectId,
1669
+ projectName: target.projectName,
1670
+ workspaceId: target.workspaceId,
1671
+ workspaceName: target.workspaceName,
1672
+ path: directory.skillDir,
1673
+ reason: trackWarning(`Skipped ${directory.skillDir}: ${message}`),
1674
+ });
1675
+ continue;
1676
+ }
1677
+ const normalizedSourceDir = normalizeSourceLocatorDirectory(nextSkill.sourceLocator);
1678
+ const existingByKey = acceptedByKey.get(nextSkill.key) ?? null;
1679
+ if (existingByKey) {
1680
+ const existingSourceDir = normalizeSkillDirectory(existingByKey);
1681
+ if (existingByKey.sourceType !== "local_path"
1682
+ || !existingSourceDir
1683
+ || !normalizedSourceDir
1684
+ || existingSourceDir !== normalizedSourceDir) {
1685
+ conflicts.push({
1686
+ slug: nextSkill.slug,
1687
+ key: nextSkill.key,
1688
+ projectId: target.projectId,
1689
+ projectName: target.projectName,
1690
+ workspaceId: target.workspaceId,
1691
+ workspaceName: target.workspaceName,
1692
+ path: directory.skillDir,
1693
+ existingSkillId: existingByKey.id,
1694
+ existingSkillKey: existingByKey.key,
1695
+ existingSourceLocator: existingByKey.sourceLocator,
1696
+ reason: `Skill key ${nextSkill.key} already points at ${existingByKey.sourceLocator ?? "another source"}.`,
1697
+ });
1698
+ continue;
1699
+ }
1700
+ const persisted = (await upsertImportedSkills(companyId, [nextSkill]))[0];
1701
+ if (!persisted)
1702
+ continue;
1703
+ updated.push(persisted);
1704
+ upsertAcceptedSkill(persisted);
1705
+ continue;
1706
+ }
1707
+ const slugConflict = acceptedSkills.find((skill) => {
1708
+ if (skill.slug !== nextSkill.slug)
1709
+ return false;
1710
+ return normalizeSkillDirectory(skill) !== normalizedSourceDir;
1711
+ });
1712
+ if (slugConflict) {
1713
+ conflicts.push({
1714
+ slug: nextSkill.slug,
1715
+ key: nextSkill.key,
1716
+ projectId: target.projectId,
1717
+ projectName: target.projectName,
1718
+ workspaceId: target.workspaceId,
1719
+ workspaceName: target.workspaceName,
1720
+ path: directory.skillDir,
1721
+ existingSkillId: slugConflict.id,
1722
+ existingSkillKey: slugConflict.key,
1723
+ existingSourceLocator: slugConflict.sourceLocator,
1724
+ reason: `Slug ${nextSkill.slug} is already in use by ${slugConflict.sourceLocator ?? slugConflict.key}.`,
1725
+ });
1726
+ continue;
1727
+ }
1728
+ const persisted = (await upsertImportedSkills(companyId, [nextSkill]))[0];
1729
+ if (!persisted)
1730
+ continue;
1731
+ imported.push(persisted);
1732
+ upsertAcceptedSkill(persisted);
1733
+ }
1734
+ }
1735
+ return {
1736
+ scannedProjects: scannedProjectIds.size,
1737
+ scannedWorkspaces: scanTargets.length,
1738
+ discovered,
1739
+ imported,
1740
+ updated,
1741
+ skipped,
1742
+ conflicts,
1743
+ warnings,
1744
+ };
1745
+ }
1746
+ async function materializeCatalogSkillFiles(companyId, skill, normalizedFiles) {
1747
+ const packageDir = skill.packageDir ? normalizePortablePath(skill.packageDir) : null;
1748
+ if (!packageDir)
1749
+ return null;
1750
+ const catalogRoot = path.resolve(resolveManagedSkillsRoot(companyId), "__catalog__");
1751
+ const skillDir = path.resolve(catalogRoot, buildSkillRuntimeName(skill.key, skill.slug));
1752
+ await fs.rm(skillDir, { recursive: true, force: true });
1753
+ await fs.mkdir(skillDir, { recursive: true });
1754
+ for (const entry of skill.fileInventory) {
1755
+ const sourcePath = entry.path === "SKILL.md"
1756
+ ? `${packageDir}/SKILL.md`
1757
+ : `${packageDir}/${entry.path}`;
1758
+ const content = normalizedFiles[sourcePath];
1759
+ if (typeof content !== "string")
1760
+ continue;
1761
+ const targetPath = path.resolve(skillDir, entry.path);
1762
+ await fs.mkdir(path.dirname(targetPath), { recursive: true });
1763
+ await fs.writeFile(targetPath, content, "utf8");
1764
+ }
1765
+ return skillDir;
1766
+ }
1767
+ async function materializeRuntimeSkillFiles(companyId, skill) {
1768
+ const runtimeRoot = path.resolve(resolveManagedSkillsRoot(companyId), "__runtime__");
1769
+ const skillDir = path.resolve(runtimeRoot, buildSkillRuntimeName(skill.key, skill.slug));
1770
+ await fs.rm(skillDir, { recursive: true, force: true });
1771
+ await fs.mkdir(skillDir, { recursive: true });
1772
+ for (const entry of skill.fileInventory) {
1773
+ const detail = await readFile(companyId, skill.id, entry.path).catch(() => null);
1774
+ if (!detail)
1775
+ continue;
1776
+ const targetPath = path.resolve(skillDir, entry.path);
1777
+ await fs.mkdir(path.dirname(targetPath), { recursive: true });
1778
+ await fs.writeFile(targetPath, detail.content, "utf8");
1779
+ }
1780
+ return skillDir;
1781
+ }
1782
+ function resolveRuntimeSkillMaterializedPath(companyId, skill) {
1783
+ const runtimeRoot = path.resolve(resolveManagedSkillsRoot(companyId), "__runtime__");
1784
+ return path.resolve(runtimeRoot, buildSkillRuntimeName(skill.key, skill.slug));
1785
+ }
1786
+ async function listRuntimeSkillEntries(companyId, options = {}) {
1787
+ const skills = await listFull(companyId);
1788
+ const out = [];
1789
+ for (const skill of skills) {
1790
+ const sourceKind = asString(getSkillMeta(skill).sourceKind);
1791
+ let source = normalizeSkillDirectory(skill);
1792
+ if (!source) {
1793
+ source = options.materializeMissing === false
1794
+ ? resolveRuntimeSkillMaterializedPath(companyId, skill)
1795
+ : await materializeRuntimeSkillFiles(companyId, skill).catch(() => null);
1796
+ }
1797
+ if (!source)
1798
+ continue;
1799
+ const required = sourceKind === "zmeel_bundled";
1800
+ out.push({
1801
+ key: skill.key,
1802
+ runtimeName: buildSkillRuntimeName(skill.key, skill.slug),
1803
+ source,
1804
+ required,
1805
+ requiredReason: required
1806
+ ? "Bundled zmeel skills are always available for local adapters."
1807
+ : null,
1808
+ });
1809
+ }
1810
+ out.sort((left, right) => left.key.localeCompare(right.key));
1811
+ return out;
1812
+ }
1813
+ async function importPackageFiles(companyId, files, options) {
1814
+ await ensureSkillInventoryCurrent(companyId);
1815
+ const normalizedFiles = normalizePackageFileMap(files);
1816
+ const importedSkills = readInlineSkillImports(companyId, normalizedFiles);
1817
+ if (importedSkills.length === 0)
1818
+ return [];
1819
+ for (const skill of importedSkills) {
1820
+ if (skill.sourceType !== "catalog")
1821
+ continue;
1822
+ const materializedDir = await materializeCatalogSkillFiles(companyId, skill, normalizedFiles);
1823
+ if (materializedDir) {
1824
+ skill.sourceLocator = materializedDir;
1825
+ }
1826
+ }
1827
+ const conflictStrategy = options?.onConflict ?? "replace";
1828
+ const existingSkills = await listFull(companyId);
1829
+ const existingByKey = new Map(existingSkills.map((skill) => [skill.key, skill]));
1830
+ const existingBySlug = new Map(existingSkills.map((skill) => [normalizeSkillSlug(skill.slug) ?? skill.slug, skill]));
1831
+ const usedSlugs = new Set(existingBySlug.keys());
1832
+ const usedKeys = new Set(existingByKey.keys());
1833
+ const toPersist = [];
1834
+ const prepared = [];
1835
+ const out = [];
1836
+ for (const importedSkill of importedSkills) {
1837
+ const originalKey = importedSkill.key;
1838
+ const originalSlug = importedSkill.slug;
1839
+ const normalizedSlug = normalizeSkillSlug(importedSkill.slug) ?? importedSkill.slug;
1840
+ const existingByIncomingKey = existingByKey.get(importedSkill.key) ?? null;
1841
+ const existingByIncomingSlug = existingBySlug.get(normalizedSlug) ?? null;
1842
+ const conflict = existingByIncomingKey ?? existingByIncomingSlug;
1843
+ if (!conflict || conflictStrategy === "replace") {
1844
+ toPersist.push(importedSkill);
1845
+ prepared.push({
1846
+ skill: importedSkill,
1847
+ originalKey,
1848
+ originalSlug,
1849
+ existingBefore: existingByIncomingKey,
1850
+ actionHint: existingByIncomingKey ? "updated" : "created",
1851
+ reason: existingByIncomingKey ? "Existing skill key matched; replace strategy." : null,
1852
+ });
1853
+ usedSlugs.add(normalizedSlug);
1854
+ usedKeys.add(importedSkill.key);
1855
+ continue;
1856
+ }
1857
+ if (conflictStrategy === "skip") {
1858
+ out.push({
1859
+ skill: conflict,
1860
+ action: "skipped",
1861
+ originalKey,
1862
+ originalSlug,
1863
+ requestedRefs: Array.from(new Set([originalKey, originalSlug])),
1864
+ reason: "Existing skill matched; skip strategy.",
1865
+ });
1866
+ continue;
1867
+ }
1868
+ const renamedSlug = uniqueSkillSlug(normalizedSlug || "skill", usedSlugs);
1869
+ const renamedKey = uniqueImportedSkillKey(companyId, renamedSlug, usedKeys);
1870
+ const renamedSkill = {
1871
+ ...importedSkill,
1872
+ slug: renamedSlug,
1873
+ key: renamedKey,
1874
+ metadata: {
1875
+ ...(importedSkill.metadata ?? {}),
1876
+ skillKey: renamedKey,
1877
+ importedFromSkillKey: originalKey,
1878
+ importedFromSkillSlug: originalSlug,
1879
+ },
1880
+ };
1881
+ toPersist.push(renamedSkill);
1882
+ prepared.push({
1883
+ skill: renamedSkill,
1884
+ originalKey,
1885
+ originalSlug,
1886
+ existingBefore: null,
1887
+ actionHint: "created",
1888
+ reason: `Existing skill matched; renamed to ${renamedSlug}.`,
1889
+ });
1890
+ usedSlugs.add(renamedSlug);
1891
+ usedKeys.add(renamedKey);
1892
+ }
1893
+ if (toPersist.length === 0)
1894
+ return out;
1895
+ const persisted = await upsertImportedSkills(companyId, toPersist);
1896
+ for (let index = 0; index < prepared.length; index += 1) {
1897
+ const persistedSkill = persisted[index];
1898
+ const preparedSkill = prepared[index];
1899
+ if (!persistedSkill || !preparedSkill)
1900
+ continue;
1901
+ out.push({
1902
+ skill: persistedSkill,
1903
+ action: preparedSkill.actionHint,
1904
+ originalKey: preparedSkill.originalKey,
1905
+ originalSlug: preparedSkill.originalSlug,
1906
+ requestedRefs: Array.from(new Set([preparedSkill.originalKey, preparedSkill.originalSlug])),
1907
+ reason: preparedSkill.reason,
1908
+ });
1909
+ }
1910
+ return out;
1911
+ }
1912
+ async function upsertImportedSkills(companyId, imported) {
1913
+ const out = [];
1914
+ for (const skill of imported) {
1915
+ const existing = await getByKey(companyId, skill.key);
1916
+ const existingMeta = existing ? getSkillMeta(existing) : {};
1917
+ const incomingMeta = skill.metadata && isPlainRecord(skill.metadata) ? skill.metadata : {};
1918
+ const incomingOwner = asString(incomingMeta.owner);
1919
+ const incomingRepo = asString(incomingMeta.repo);
1920
+ const incomingKind = asString(incomingMeta.sourceKind);
1921
+ if (existing
1922
+ && existingMeta.sourceKind === "zmeel_bundled"
1923
+ && incomingKind === "github"
1924
+ && incomingOwner === "zmeel"
1925
+ && incomingRepo === "zmeel") {
1926
+ out.push(existing);
1927
+ continue;
1928
+ }
1929
+ const metadata = {
1930
+ ...(skill.metadata ?? {}),
1931
+ skillKey: skill.key,
1932
+ };
1933
+ const values = {
1934
+ companyId,
1935
+ key: skill.key,
1936
+ slug: skill.slug,
1937
+ name: skill.name,
1938
+ description: skill.description,
1939
+ markdown: skill.markdown,
1940
+ sourceType: skill.sourceType,
1941
+ sourceLocator: skill.sourceLocator,
1942
+ sourceRef: skill.sourceRef,
1943
+ trustLevel: skill.trustLevel,
1944
+ compatibility: skill.compatibility,
1945
+ fileInventory: serializeFileInventory(skill.fileInventory),
1946
+ metadata,
1947
+ updatedAt: new Date(),
1948
+ };
1949
+ const row = existing
1950
+ ? await db
1951
+ .update(companySkills)
1952
+ .set(values)
1953
+ .where(eq(companySkills.id, existing.id))
1954
+ .returning()
1955
+ .then((rows) => rows[0] ?? null)
1956
+ : await db
1957
+ .insert(companySkills)
1958
+ .values(values)
1959
+ .returning()
1960
+ .then((rows) => rows[0] ?? null);
1961
+ if (!row)
1962
+ throw notFound("Failed to persist company skill");
1963
+ out.push(toCompanySkill(row));
1964
+ }
1965
+ return out;
1966
+ }
1967
+ async function importFromSource(companyId, source) {
1968
+ await ensureSkillInventoryCurrent(companyId);
1969
+ const parsed = parseSkillImportSourceInput(source);
1970
+ const local = !/^https?:\/\//i.test(parsed.resolvedSource);
1971
+ const { skills, warnings } = local
1972
+ ? {
1973
+ skills: (await readLocalSkillImports(companyId, parsed.resolvedSource))
1974
+ .filter((skill) => !parsed.requestedSkillSlug || skill.slug === parsed.requestedSkillSlug),
1975
+ warnings: parsed.warnings,
1976
+ }
1977
+ : await readUrlSkillImports(companyId, parsed.resolvedSource, parsed.requestedSkillSlug)
1978
+ .then((result) => ({
1979
+ skills: result.skills,
1980
+ warnings: [...parsed.warnings, ...result.warnings],
1981
+ }));
1982
+ const filteredSkills = parsed.requestedSkillSlug
1983
+ ? skills.filter((skill) => skill.slug === parsed.requestedSkillSlug)
1984
+ : skills;
1985
+ if (filteredSkills.length === 0) {
1986
+ throw unprocessable(parsed.requestedSkillSlug
1987
+ ? `Skill ${parsed.requestedSkillSlug} was not found in the provided source.`
1988
+ : "No skills were found in the provided source.");
1989
+ }
1990
+ // Override sourceType/sourceLocator for skills imported via skills.sh
1991
+ if (parsed.originalSkillsShUrl) {
1992
+ for (const skill of filteredSkills) {
1993
+ skill.sourceType = "skills_sh";
1994
+ skill.sourceLocator = parsed.originalSkillsShUrl;
1995
+ if (skill.metadata) {
1996
+ skill.metadata.sourceKind = "skills_sh";
1997
+ }
1998
+ skill.key = deriveCanonicalSkillKey(companyId, skill);
1999
+ }
2000
+ }
2001
+ const imported = await upsertImportedSkills(companyId, filteredSkills);
2002
+ return { imported, warnings };
2003
+ }
2004
+ async function deleteSkill(companyId, skillId) {
2005
+ const row = await db
2006
+ .select()
2007
+ .from(companySkills)
2008
+ .where(and(eq(companySkills.id, skillId), eq(companySkills.companyId, companyId)))
2009
+ .then((rows) => rows[0] ?? null);
2010
+ if (!row)
2011
+ return null;
2012
+ const skill = toCompanySkill(row);
2013
+ // Remove from any agent desiredSkills that reference this skill
2014
+ const agentRows = await agents.list(companyId);
2015
+ const allSkills = await listFull(companyId);
2016
+ for (const agent of agentRows) {
2017
+ const config = agent.adapterConfig;
2018
+ const preference = readzmeelSkillSyncPreference(config);
2019
+ const referencesSkill = preference.desiredSkills.some((ref) => {
2020
+ const resolved = resolveSkillReference(allSkills, ref);
2021
+ return resolved.skill?.id === skillId;
2022
+ });
2023
+ if (referencesSkill) {
2024
+ const filtered = preference.desiredSkills.filter((ref) => {
2025
+ const resolved = resolveSkillReference(allSkills, ref);
2026
+ return resolved.skill?.id !== skillId;
2027
+ });
2028
+ await agents.update(agent.id, {
2029
+ adapterConfig: writezmeelSkillSyncPreference(config, filtered),
2030
+ });
2031
+ }
2032
+ }
2033
+ // Delete DB row
2034
+ await db
2035
+ .delete(companySkills)
2036
+ .where(eq(companySkills.id, skillId));
2037
+ // Clean up materialized runtime files
2038
+ await fs.rm(resolveRuntimeSkillMaterializedPath(companyId, skill), { recursive: true, force: true });
2039
+ return skill;
2040
+ }
2041
+ return {
2042
+ list,
2043
+ listFull,
2044
+ getById,
2045
+ getByKey,
2046
+ resolveRequestedSkillKeys: async (companyId, requestedReferences) => {
2047
+ const skills = await listFull(companyId);
2048
+ return resolveRequestedSkillKeysOrThrow(skills, requestedReferences);
2049
+ },
2050
+ detail,
2051
+ updateStatus,
2052
+ readFile,
2053
+ updateFile,
2054
+ createLocalSkill,
2055
+ deleteSkill,
2056
+ importFromSource,
2057
+ scanProjectWorkspaces,
2058
+ importPackageFiles,
2059
+ installUpdate,
2060
+ listRuntimeSkillEntries,
2061
+ };
2062
+ }
2063
+ //# sourceMappingURL=company-skills.js.map