@capybara-hq/kernel 0.0.0-stage → 0.1.0-rc.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (631) hide show
  1. package/LICENSE +202 -0
  2. package/NOTICE +2 -0
  3. package/README.md +20 -2
  4. package/bootstrap.json +22 -0
  5. package/dist/admin/admin.controller.d.ts +139 -0
  6. package/dist/admin/admin.controller.js +238 -0
  7. package/dist/admin/extensions.controller.d.ts +100 -0
  8. package/dist/admin/extensions.controller.js +226 -0
  9. package/dist/admin/setup.controller.d.ts +36 -0
  10. package/dist/admin/setup.controller.js +106 -0
  11. package/dist/admin/setup.service.d.ts +47 -0
  12. package/dist/admin/setup.service.js +90 -0
  13. package/dist/agents/agents.controller.d.ts +205 -0
  14. package/dist/agents/agents.controller.js +144 -0
  15. package/dist/agents/agents.service.d.ts +177 -0
  16. package/dist/agents/agents.service.js +677 -0
  17. package/dist/agents/definition.d.ts +198 -0
  18. package/dist/agents/definition.js +152 -0
  19. package/dist/agents/models.controller.d.ts +13 -0
  20. package/dist/agents/models.controller.js +31 -0
  21. package/dist/agents/templates.controller.d.ts +15 -0
  22. package/dist/agents/templates.controller.js +37 -0
  23. package/dist/agents/templates.d.ts +83 -0
  24. package/dist/agents/templates.js +173 -0
  25. package/dist/catalog/admin-catalog.controller.d.ts +143 -0
  26. package/dist/catalog/admin-catalog.controller.js +245 -0
  27. package/dist/catalog/catalog.service.d.ts +430 -0
  28. package/dist/catalog/catalog.service.js +882 -0
  29. package/dist/catalog/claude/agents.d.ts +27 -0
  30. package/dist/catalog/claude/agents.js +270 -0
  31. package/dist/catalog/claude/commands.d.ts +50 -0
  32. package/dist/catalog/claude/commands.js +179 -0
  33. package/dist/catalog/claude/manifest.d.ts +69 -0
  34. package/dist/catalog/claude/manifest.js +134 -0
  35. package/dist/catalog/claude/marketplace.d.ts +35 -0
  36. package/dist/catalog/claude/marketplace.js +194 -0
  37. package/dist/catalog/claude/mcp.d.ts +33 -0
  38. package/dist/catalog/claude/mcp.js +226 -0
  39. package/dist/catalog/claude/report.d.ts +86 -0
  40. package/dist/catalog/claude/report.js +121 -0
  41. package/dist/catalog/claude/translate.d.ts +56 -0
  42. package/dist/catalog/claude/translate.js +857 -0
  43. package/dist/catalog/cli.d.ts +46 -0
  44. package/dist/catalog/cli.js +211 -0
  45. package/dist/catalog/git-source.d.ts +127 -0
  46. package/dist/catalog/git-source.js +520 -0
  47. package/dist/catalog/marketplace-fetch.d.ts +99 -0
  48. package/dist/catalog/marketplace-fetch.js +203 -0
  49. package/dist/catalog/marketplaces.controller.d.ts +97 -0
  50. package/dist/catalog/marketplaces.controller.js +197 -0
  51. package/dist/catalog/marketplaces.service.d.ts +340 -0
  52. package/dist/catalog/marketplaces.service.js +1217 -0
  53. package/dist/catalog/org-catalog.controller.d.ts +128 -0
  54. package/dist/catalog/org-catalog.controller.js +277 -0
  55. package/dist/catalog/org-catalog.service.d.ts +246 -0
  56. package/dist/catalog/org-catalog.service.js +625 -0
  57. package/dist/catalog/plugin-import.d.ts +436 -0
  58. package/dist/catalog/plugin-import.js +1069 -0
  59. package/dist/catalog/plugin-install.d.ts +447 -0
  60. package/dist/catalog/plugin-install.js +1333 -0
  61. package/dist/catalog/plugin-package.d.ts +143 -0
  62. package/dist/catalog/plugin-package.js +382 -0
  63. package/dist/catalog/plugin-upgrade.d.ts +222 -0
  64. package/dist/catalog/plugin-upgrade.js +1219 -0
  65. package/dist/catalog/requests.service.d.ts +162 -0
  66. package/dist/catalog/requests.service.js +504 -0
  67. package/dist/catalog/schema-path.d.ts +7 -0
  68. package/dist/catalog/schema-path.js +63 -0
  69. package/dist/catalog/upgrade-targets.d.ts +59 -0
  70. package/dist/catalog/upgrade-targets.js +90 -0
  71. package/dist/catalog/versions.d.ts +31 -0
  72. package/dist/catalog/versions.js +44 -0
  73. package/dist/channels/actions.d.ts +37 -0
  74. package/dist/channels/actions.js +121 -0
  75. package/dist/channels/cards.d.ts +44 -0
  76. package/dist/channels/cards.js +156 -0
  77. package/dist/channels/connections.controller.d.ts +59 -0
  78. package/dist/channels/connections.controller.js +115 -0
  79. package/dist/channels/connections.service.d.ts +187 -0
  80. package/dist/channels/connections.service.js +534 -0
  81. package/dist/channels/features.d.ts +12 -0
  82. package/dist/channels/features.js +22 -0
  83. package/dist/channels/inbound.d.ts +120 -0
  84. package/dist/channels/inbound.js +332 -0
  85. package/dist/channels/outbound.d.ts +140 -0
  86. package/dist/channels/outbound.js +1125 -0
  87. package/dist/channels/phrases.d.ts +100 -0
  88. package/dist/channels/phrases.js +81 -0
  89. package/dist/channels/supervisor.d.ts +182 -0
  90. package/dist/channels/supervisor.js +625 -0
  91. package/dist/channels/threads.d.ts +29 -0
  92. package/dist/channels/threads.js +104 -0
  93. package/dist/channels/webhook-url.d.ts +16 -0
  94. package/dist/channels/webhook-url.js +34 -0
  95. package/dist/channels/webhook.controller.d.ts +19 -0
  96. package/dist/channels/webhook.controller.js +72 -0
  97. package/dist/channels/webhook.d.ts +73 -0
  98. package/dist/channels/webhook.js +274 -0
  99. package/dist/config/docs.d.ts +9 -0
  100. package/dist/config/docs.js +85 -0
  101. package/dist/config/env.d.ts +6 -0
  102. package/dist/config/env.js +73 -0
  103. package/dist/config/fields.d.ts +42 -0
  104. package/dist/config/fields.js +214 -0
  105. package/dist/config/file-source.d.ts +3 -0
  106. package/dist/config/file-source.js +31 -0
  107. package/dist/config/load.d.ts +20 -0
  108. package/dist/config/load.js +98 -0
  109. package/dist/config/nacos-source.d.ts +31 -0
  110. package/dist/config/nacos-source.js +229 -0
  111. package/dist/config/schema.d.ts +223 -0
  112. package/dist/config/schema.js +1151 -0
  113. package/dist/config/sources.d.ts +18 -0
  114. package/dist/config/sources.js +59 -0
  115. package/dist/config/types.d.ts +9 -0
  116. package/dist/config/types.js +7 -0
  117. package/dist/conversations/artifacts.d.ts +52 -0
  118. package/dist/conversations/artifacts.js +137 -0
  119. package/dist/conversations/attachments.controller.d.ts +28 -0
  120. package/dist/conversations/attachments.controller.js +96 -0
  121. package/dist/conversations/attachments.service.d.ts +180 -0
  122. package/dist/conversations/attachments.service.js +578 -0
  123. package/dist/conversations/conversations.controller.d.ts +288 -0
  124. package/dist/conversations/conversations.controller.js +607 -0
  125. package/dist/conversations/conversations.service.d.ts +321 -0
  126. package/dist/conversations/conversations.service.js +754 -0
  127. package/dist/conversations/event-log.d.ts +122 -0
  128. package/dist/conversations/event-log.js +259 -0
  129. package/dist/conversations/events.d.ts +856 -0
  130. package/dist/conversations/events.js +639 -0
  131. package/dist/conversations/files.d.ts +92 -0
  132. package/dist/conversations/files.js +213 -0
  133. package/dist/conversations/outputs-read.d.ts +34 -0
  134. package/dist/conversations/outputs-read.js +37 -0
  135. package/dist/conversations/queue.d.ts +169 -0
  136. package/dist/conversations/queue.js +527 -0
  137. package/dist/conversations/sandbox-status.d.ts +21 -0
  138. package/dist/conversations/sandbox-status.js +24 -0
  139. package/dist/conversations/selection.d.ts +46 -0
  140. package/dist/conversations/selection.js +75 -0
  141. package/dist/conversations/titles.d.ts +93 -0
  142. package/dist/conversations/titles.js +422 -0
  143. package/dist/ctx/bus.d.ts +16 -0
  144. package/dist/ctx/bus.js +101 -0
  145. package/dist/ctx/create-ctx.d.ts +109 -0
  146. package/dist/ctx/create-ctx.js +592 -0
  147. package/dist/ctx/kv.d.ts +4 -0
  148. package/dist/ctx/kv.js +31 -0
  149. package/dist/ctx/lock.d.ts +4 -0
  150. package/dist/ctx/lock.js +39 -0
  151. package/dist/ctx/namespace.d.ts +6 -0
  152. package/dist/ctx/namespace.js +12 -0
  153. package/dist/ctx/queue.d.ts +25 -0
  154. package/dist/ctx/queue.js +150 -0
  155. package/dist/ctx/secrets.d.ts +45 -0
  156. package/dist/ctx/secrets.js +175 -0
  157. package/dist/db/kernel-schema.d.ts +1122 -0
  158. package/dist/db/kernel-schema.js +5 -0
  159. package/dist/db/migrator.d.ts +28 -0
  160. package/dist/db/migrator.js +140 -0
  161. package/dist/db/pool.d.ts +21 -0
  162. package/dist/db/pool.js +28 -0
  163. package/dist/db/sql-statements.d.ts +34 -0
  164. package/dist/db/sql-statements.js +168 -0
  165. package/dist/errors.d.ts +210 -0
  166. package/dist/errors.js +212 -0
  167. package/dist/evals/budget.d.ts +61 -0
  168. package/dist/evals/budget.js +181 -0
  169. package/dist/evals/diff.d.ts +55 -0
  170. package/dist/evals/diff.js +133 -0
  171. package/dist/evals/judge.d.ts +53 -0
  172. package/dist/evals/judge.js +149 -0
  173. package/dist/evals/plan.d.ts +47 -0
  174. package/dist/evals/plan.js +77 -0
  175. package/dist/evals/reconstruct.d.ts +137 -0
  176. package/dist/evals/reconstruct.js +322 -0
  177. package/dist/evals/recorded-tools.d.ts +54 -0
  178. package/dist/evals/recorded-tools.js +167 -0
  179. package/dist/evals/run-replay.d.ts +86 -0
  180. package/dist/evals/run-replay.js +502 -0
  181. package/dist/evals/runs.controller.d.ts +100 -0
  182. package/dist/evals/runs.controller.js +199 -0
  183. package/dist/evals/runs.service.d.ts +275 -0
  184. package/dist/evals/runs.service.js +836 -0
  185. package/dist/evals/sets.controller.d.ts +61 -0
  186. package/dist/evals/sets.controller.js +183 -0
  187. package/dist/evals/sets.service.d.ts +128 -0
  188. package/dist/evals/sets.service.js +558 -0
  189. package/dist/evals/snapshot.d.ts +76 -0
  190. package/dist/evals/snapshot.js +207 -0
  191. package/dist/evals/step-replay.d.ts +113 -0
  192. package/dist/evals/step-replay.js +181 -0
  193. package/dist/evals/trajectory.controller.d.ts +41 -0
  194. package/dist/evals/trajectory.controller.js +88 -0
  195. package/dist/evals/trajectory.d.ts +144 -0
  196. package/dist/evals/trajectory.js +338 -0
  197. package/dist/evals/trajectory.service.d.ts +108 -0
  198. package/dist/evals/trajectory.service.js +323 -0
  199. package/dist/evals/worker.d.ts +101 -0
  200. package/dist/evals/worker.js +789 -0
  201. package/dist/extensions/admin-ops.d.ts +105 -0
  202. package/dist/extensions/admin-ops.js +353 -0
  203. package/dist/extensions/admin-view.d.ts +79 -0
  204. package/dist/extensions/admin-view.js +327 -0
  205. package/dist/extensions/approvals.d.ts +119 -0
  206. package/dist/extensions/approvals.js +205 -0
  207. package/dist/extensions/blobs.d.ts +45 -0
  208. package/dist/extensions/blobs.js +160 -0
  209. package/dist/extensions/bootstrap.d.ts +149 -0
  210. package/dist/extensions/bootstrap.js +441 -0
  211. package/dist/extensions/cli.d.ts +61 -0
  212. package/dist/extensions/cli.js +165 -0
  213. package/dist/extensions/config-json-schema.d.ts +9 -0
  214. package/dist/extensions/config-json-schema.js +73 -0
  215. package/dist/extensions/deployment-config.d.ts +138 -0
  216. package/dist/extensions/deployment-config.js +394 -0
  217. package/dist/extensions/enabled.d.ts +31 -0
  218. package/dist/extensions/enabled.js +55 -0
  219. package/dist/extensions/hooks.d.ts +161 -0
  220. package/dist/extensions/hooks.js +425 -0
  221. package/dist/extensions/host.d.ts +577 -0
  222. package/dist/extensions/host.js +2071 -0
  223. package/dist/extensions/inflight.d.ts +69 -0
  224. package/dist/extensions/inflight.js +277 -0
  225. package/dist/extensions/installs.d.ts +166 -0
  226. package/dist/extensions/installs.js +253 -0
  227. package/dist/extensions/instance.d.ts +167 -0
  228. package/dist/extensions/instance.js +329 -0
  229. package/dist/extensions/ledger.d.ts +30 -0
  230. package/dist/extensions/ledger.js +50 -0
  231. package/dist/extensions/lifecycle.d.ts +80 -0
  232. package/dist/extensions/lifecycle.js +152 -0
  233. package/dist/extensions/migrate-lock.d.ts +51 -0
  234. package/dist/extensions/migrate-lock.js +100 -0
  235. package/dist/extensions/org-config.controller.d.ts +24 -0
  236. package/dist/extensions/org-config.controller.js +59 -0
  237. package/dist/extensions/org-config.d.ts +169 -0
  238. package/dist/extensions/org-config.js +520 -0
  239. package/dist/extensions/package.d.ts +115 -0
  240. package/dist/extensions/package.js +246 -0
  241. package/dist/extensions/permission-set.d.ts +117 -0
  242. package/dist/extensions/permission-set.js +184 -0
  243. package/dist/extensions/permission-view.d.ts +194 -0
  244. package/dist/extensions/permission-view.js +284 -0
  245. package/dist/extensions/registry.d.ts +24 -0
  246. package/dist/extensions/registry.js +56 -0
  247. package/dist/extensions/resolve.d.ts +12 -0
  248. package/dist/extensions/resolve.js +71 -0
  249. package/dist/extensions/sources.d.ts +69 -0
  250. package/dist/extensions/sources.js +120 -0
  251. package/dist/extensions/sync.d.ts +40 -0
  252. package/dist/extensions/sync.js +242 -0
  253. package/dist/files/previewers.controller.d.ts +46 -0
  254. package/dist/files/previewers.controller.js +105 -0
  255. package/dist/files/previewers.d.ts +100 -0
  256. package/dist/files/previewers.js +250 -0
  257. package/dist/http/api.module.d.ts +114 -0
  258. package/dist/http/api.module.js +448 -0
  259. package/dist/http/app.d.ts +77 -0
  260. package/dist/http/app.js +170 -0
  261. package/dist/http/error.filter.d.ts +21 -0
  262. package/dist/http/error.filter.js +85 -0
  263. package/dist/http/gateway.module.d.ts +15 -0
  264. package/dist/http/gateway.module.js +13 -0
  265. package/dist/http/health.controller.d.ts +26 -0
  266. package/dist/http/health.controller.js +79 -0
  267. package/dist/http/nest-logger.d.ts +20 -0
  268. package/dist/http/nest-logger.js +28 -0
  269. package/dist/http/plugin-dispatch.d.ts +68 -0
  270. package/dist/http/plugin-dispatch.js +200 -0
  271. package/dist/http/tokens.d.ts +131 -0
  272. package/dist/http/tokens.js +131 -0
  273. package/dist/http/zod.pipe.d.ts +8 -0
  274. package/dist/http/zod.pipe.js +14 -0
  275. package/dist/identity/accounts.d.ts +93 -0
  276. package/dist/identity/accounts.js +367 -0
  277. package/dist/identity/api-tokens.d.ts +73 -0
  278. package/dist/identity/api-tokens.js +197 -0
  279. package/dist/identity/audit.d.ts +23 -0
  280. package/dist/identity/audit.js +41 -0
  281. package/dist/identity/auth.controller.d.ts +40 -0
  282. package/dist/identity/auth.controller.js +130 -0
  283. package/dist/identity/auth.guard.d.ts +41 -0
  284. package/dist/identity/auth.guard.js +162 -0
  285. package/dist/identity/binding.d.ts +47 -0
  286. package/dist/identity/binding.js +84 -0
  287. package/dist/identity/cookies.d.ts +16 -0
  288. package/dist/identity/cookies.js +32 -0
  289. package/dist/identity/credential-check.d.ts +17 -0
  290. package/dist/identity/credential-check.js +24 -0
  291. package/dist/identity/enterprise-admin.d.ts +14 -0
  292. package/dist/identity/enterprise-admin.js +27 -0
  293. package/dist/identity/external.d.ts +106 -0
  294. package/dist/identity/external.js +337 -0
  295. package/dist/identity/hash.d.ts +2 -0
  296. package/dist/identity/hash.js +3 -0
  297. package/dist/identity/login.d.ts +6 -0
  298. package/dist/identity/login.js +20 -0
  299. package/dist/identity/me.controller.d.ts +61 -0
  300. package/dist/identity/me.controller.js +159 -0
  301. package/dist/identity/passwords.d.ts +6 -0
  302. package/dist/identity/passwords.js +37 -0
  303. package/dist/identity/principal.d.ts +56 -0
  304. package/dist/identity/principal.js +38 -0
  305. package/dist/identity/rate-limit.d.ts +55 -0
  306. package/dist/identity/rate-limit.js +121 -0
  307. package/dist/identity/sessions.d.ts +84 -0
  308. package/dist/identity/sessions.js +306 -0
  309. package/dist/identity/settings.d.ts +121 -0
  310. package/dist/identity/settings.js +248 -0
  311. package/dist/identity/sso.controller.d.ts +59 -0
  312. package/dist/identity/sso.controller.js +192 -0
  313. package/dist/identity/sso.d.ts +83 -0
  314. package/dist/identity/sso.js +202 -0
  315. package/dist/inbox/inbox.service.d.ts +43 -0
  316. package/dist/inbox/inbox.service.js +57 -0
  317. package/dist/index.d.ts +67 -0
  318. package/dist/index.js +65 -0
  319. package/dist/kernel.d.ts +256 -0
  320. package/dist/kernel.js +1326 -0
  321. package/dist/log.d.ts +48 -0
  322. package/dist/log.js +229 -0
  323. package/dist/models/prices.d.ts +53 -0
  324. package/dist/models/prices.js +121 -0
  325. package/dist/models/purposes.controller.d.ts +19 -0
  326. package/dist/models/purposes.controller.js +56 -0
  327. package/dist/models/purposes.d.ts +140 -0
  328. package/dist/models/purposes.js +267 -0
  329. package/dist/net/proxy.d.ts +44 -0
  330. package/dist/net/proxy.js +162 -0
  331. package/dist/net/public-address.d.ts +60 -0
  332. package/dist/net/public-address.js +271 -0
  333. package/dist/net/safe-fetch.d.ts +38 -0
  334. package/dist/net/safe-fetch.js +140 -0
  335. package/dist/orgs/directory-sync.controller.d.ts +14 -0
  336. package/dist/orgs/directory-sync.controller.js +40 -0
  337. package/dist/orgs/directory-sync.d.ts +166 -0
  338. package/dist/orgs/directory-sync.js +558 -0
  339. package/dist/orgs/invitations.controller.d.ts +58 -0
  340. package/dist/orgs/invitations.controller.js +137 -0
  341. package/dist/orgs/invitations.service.d.ts +80 -0
  342. package/dist/orgs/invitations.service.js +217 -0
  343. package/dist/orgs/members.service.d.ts +63 -0
  344. package/dist/orgs/members.service.js +234 -0
  345. package/dist/orgs/offboarding.d.ts +141 -0
  346. package/dist/orgs/offboarding.js +398 -0
  347. package/dist/orgs/org-lock.d.ts +32 -0
  348. package/dist/orgs/org-lock.js +46 -0
  349. package/dist/orgs/org.guard.d.ts +35 -0
  350. package/dist/orgs/org.guard.js +95 -0
  351. package/dist/orgs/orgs.controller.d.ts +78 -0
  352. package/dist/orgs/orgs.controller.js +192 -0
  353. package/dist/orgs/orgs.service.d.ts +61 -0
  354. package/dist/orgs/orgs.service.js +209 -0
  355. package/dist/orgs/roles.d.ts +13 -0
  356. package/dist/orgs/roles.js +58 -0
  357. package/dist/orgs/settings.controller.d.ts +20 -0
  358. package/dist/orgs/settings.controller.js +53 -0
  359. package/dist/orgs/settings.service.d.ts +120 -0
  360. package/dist/orgs/settings.service.js +178 -0
  361. package/dist/packages/npm.d.ts +50 -0
  362. package/dist/packages/npm.js +218 -0
  363. package/dist/packages/provenance.d.ts +47 -0
  364. package/dist/packages/provenance.js +147 -0
  365. package/dist/packages/tgz.d.ts +76 -0
  366. package/dist/packages/tgz.js +225 -0
  367. package/dist/runtime/abort.d.ts +32 -0
  368. package/dist/runtime/abort.js +71 -0
  369. package/dist/runtime/checkpointer.d.ts +32 -0
  370. package/dist/runtime/checkpointer.js +243 -0
  371. package/dist/runtime/context/build.d.ts +254 -0
  372. package/dist/runtime/context/build.js +693 -0
  373. package/dist/runtime/context/claude-tools.d.ts +11 -0
  374. package/dist/runtime/context/claude-tools.js +24 -0
  375. package/dist/runtime/context/compaction.d.ts +26 -0
  376. package/dist/runtime/context/compaction.js +195 -0
  377. package/dist/runtime/context/pairing.d.ts +11 -0
  378. package/dist/runtime/context/pairing.js +82 -0
  379. package/dist/runtime/context/reminders.d.ts +5 -0
  380. package/dist/runtime/context/reminders.js +11 -0
  381. package/dist/runtime/context/skills.d.ts +105 -0
  382. package/dist/runtime/context/skills.js +283 -0
  383. package/dist/runtime/context/tokens.d.ts +19 -0
  384. package/dist/runtime/context/tokens.js +104 -0
  385. package/dist/runtime/conversation-lock.d.ts +40 -0
  386. package/dist/runtime/conversation-lock.js +97 -0
  387. package/dist/runtime/hook-calls.d.ts +84 -0
  388. package/dist/runtime/hook-calls.js +136 -0
  389. package/dist/runtime/langgraph-loop.d.ts +52 -0
  390. package/dist/runtime/langgraph-loop.js +247 -0
  391. package/dist/runtime/loop.d.ts +93 -0
  392. package/dist/runtime/loop.js +7 -0
  393. package/dist/runtime/maintenance.d.ts +80 -0
  394. package/dist/runtime/maintenance.js +147 -0
  395. package/dist/runtime/media-cache.d.ts +21 -0
  396. package/dist/runtime/media-cache.js +51 -0
  397. package/dist/runtime/model-call.d.ts +176 -0
  398. package/dist/runtime/model-call.js +1049 -0
  399. package/dist/runtime/providers.d.ts +86 -0
  400. package/dist/runtime/providers.js +224 -0
  401. package/dist/runtime/quota.d.ts +29 -0
  402. package/dist/runtime/quota.js +70 -0
  403. package/dist/runtime/run-finish.d.ts +45 -0
  404. package/dist/runtime/run-finish.js +69 -0
  405. package/dist/runtime/run-queue.d.ts +121 -0
  406. package/dist/runtime/run-queue.js +493 -0
  407. package/dist/runtime/run-worker.d.ts +138 -0
  408. package/dist/runtime/run-worker.js +805 -0
  409. package/dist/runtime/stream.controller.d.ts +34 -0
  410. package/dist/runtime/stream.controller.js +122 -0
  411. package/dist/runtime/stream.d.ts +63 -0
  412. package/dist/runtime/stream.js +262 -0
  413. package/dist/runtime/subagents/child.d.ts +80 -0
  414. package/dist/runtime/subagents/child.js +225 -0
  415. package/dist/runtime/subagents/definition.d.ts +103 -0
  416. package/dist/runtime/subagents/definition.js +392 -0
  417. package/dist/runtime/subagents/dispatch.d.ts +69 -0
  418. package/dist/runtime/subagents/dispatch.js +502 -0
  419. package/dist/runtime/subagents/limits.d.ts +23 -0
  420. package/dist/runtime/subagents/limits.js +34 -0
  421. package/dist/runtime/subagents/org-agents.d.ts +50 -0
  422. package/dist/runtime/subagents/org-agents.js +70 -0
  423. package/dist/runtime/subagents/preamble.d.ts +7 -0
  424. package/dist/runtime/subagents/preamble.js +11 -0
  425. package/dist/runtime/subagents/progress.d.ts +26 -0
  426. package/dist/runtime/subagents/progress.js +36 -0
  427. package/dist/runtime/subagents/roster.d.ts +55 -0
  428. package/dist/runtime/subagents/roster.js +111 -0
  429. package/dist/runtime/subagents/skill-fork.d.ts +123 -0
  430. package/dist/runtime/subagents/skill-fork.js +259 -0
  431. package/dist/runtime/usage-report.d.ts +163 -0
  432. package/dist/runtime/usage-report.js +550 -0
  433. package/dist/runtime/waits.d.ts +233 -0
  434. package/dist/runtime/waits.js +883 -0
  435. package/dist/sandbox/leases.d.ts +169 -0
  436. package/dist/sandbox/leases.js +515 -0
  437. package/dist/sandbox/lifecycle.d.ts +21 -0
  438. package/dist/sandbox/lifecycle.js +68 -0
  439. package/dist/sandbox/sandbox.service.d.ts +249 -0
  440. package/dist/sandbox/sandbox.service.js +908 -0
  441. package/dist/skills/catalog.d.ts +149 -0
  442. package/dist/skills/catalog.js +405 -0
  443. package/dist/skills/changes.controller.d.ts +56 -0
  444. package/dist/skills/changes.controller.js +136 -0
  445. package/dist/skills/changes.service.d.ts +175 -0
  446. package/dist/skills/changes.service.js +805 -0
  447. package/dist/skills/invocable.controller.d.ts +23 -0
  448. package/dist/skills/invocable.controller.js +50 -0
  449. package/dist/skills/invocation-keys.d.ts +23 -0
  450. package/dist/skills/invocation-keys.js +44 -0
  451. package/dist/skills/invoke.d.ts +135 -0
  452. package/dist/skills/invoke.js +286 -0
  453. package/dist/skills/package.d.ts +87 -0
  454. package/dist/skills/package.js +227 -0
  455. package/dist/skills/skills.controller.d.ts +40 -0
  456. package/dist/skills/skills.controller.js +110 -0
  457. package/dist/skills/skills.service.d.ts +192 -0
  458. package/dist/skills/skills.service.js +567 -0
  459. package/dist/storage/prefix.d.ts +36 -0
  460. package/dist/storage/prefix.js +104 -0
  461. package/dist/storage/purge.d.ts +27 -0
  462. package/dist/storage/purge.js +75 -0
  463. package/dist/storage/storage.service.d.ts +44 -0
  464. package/dist/storage/storage.service.js +145 -0
  465. package/dist/text.d.ts +13 -0
  466. package/dist/text.js +13 -0
  467. package/dist/tools/approvals.controller.d.ts +53 -0
  468. package/dist/tools/approvals.controller.js +128 -0
  469. package/dist/tools/approvals.service.d.ts +172 -0
  470. package/dist/tools/approvals.service.js +568 -0
  471. package/dist/tools/breaker.d.ts +28 -0
  472. package/dist/tools/breaker.js +72 -0
  473. package/dist/tools/builtins/agent.d.ts +81 -0
  474. package/dist/tools/builtins/agent.js +223 -0
  475. package/dist/tools/builtins/ask-user.d.ts +28 -0
  476. package/dist/tools/builtins/ask-user.js +139 -0
  477. package/dist/tools/builtins/read-tool-output.d.ts +18 -0
  478. package/dist/tools/builtins/read-tool-output.js +108 -0
  479. package/dist/tools/builtins/sandbox/bash.d.ts +16 -0
  480. package/dist/tools/builtins/sandbox/bash.js +137 -0
  481. package/dist/tools/builtins/sandbox/common.d.ts +114 -0
  482. package/dist/tools/builtins/sandbox/common.js +304 -0
  483. package/dist/tools/builtins/sandbox/deliver.d.ts +5 -0
  484. package/dist/tools/builtins/sandbox/deliver.js +180 -0
  485. package/dist/tools/builtins/sandbox/edit.d.ts +4 -0
  486. package/dist/tools/builtins/sandbox/edit.js +98 -0
  487. package/dist/tools/builtins/sandbox/glob-match.d.ts +25 -0
  488. package/dist/tools/builtins/sandbox/glob-match.js +240 -0
  489. package/dist/tools/builtins/sandbox/glob.d.ts +4 -0
  490. package/dist/tools/builtins/sandbox/glob.js +104 -0
  491. package/dist/tools/builtins/sandbox/grep.d.ts +9 -0
  492. package/dist/tools/builtins/sandbox/grep.js +133 -0
  493. package/dist/tools/builtins/sandbox/index.d.ts +12 -0
  494. package/dist/tools/builtins/sandbox/index.js +27 -0
  495. package/dist/tools/builtins/sandbox/names.d.ts +7 -0
  496. package/dist/tools/builtins/sandbox/names.js +20 -0
  497. package/dist/tools/builtins/sandbox/read.d.ts +8 -0
  498. package/dist/tools/builtins/sandbox/read.js +121 -0
  499. package/dist/tools/builtins/sandbox/write.d.ts +4 -0
  500. package/dist/tools/builtins/sandbox/write.js +88 -0
  501. package/dist/tools/builtins/skill-load.d.ts +53 -0
  502. package/dist/tools/builtins/skill-load.js +446 -0
  503. package/dist/tools/builtins/skill-write.d.ts +59 -0
  504. package/dist/tools/builtins/skill-write.js +244 -0
  505. package/dist/tools/builtins/tool-search.d.ts +31 -0
  506. package/dist/tools/builtins/tool-search.js +171 -0
  507. package/dist/tools/connector-content.controller.d.ts +34 -0
  508. package/dist/tools/connector-content.controller.js +78 -0
  509. package/dist/tools/connector-content.d.ts +104 -0
  510. package/dist/tools/connector-content.js +267 -0
  511. package/dist/tools/connectors.controller.d.ts +210 -0
  512. package/dist/tools/connectors.controller.js +234 -0
  513. package/dist/tools/connectors.service.d.ts +303 -0
  514. package/dist/tools/connectors.service.js +1102 -0
  515. package/dist/tools/credentials.d.ts +139 -0
  516. package/dist/tools/credentials.js +351 -0
  517. package/dist/tools/drift.d.ts +141 -0
  518. package/dist/tools/drift.js +539 -0
  519. package/dist/tools/elicitation.d.ts +81 -0
  520. package/dist/tools/elicitation.js +266 -0
  521. package/dist/tools/endpoint.d.ts +18 -0
  522. package/dist/tools/endpoint.js +115 -0
  523. package/dist/tools/info.d.ts +67 -0
  524. package/dist/tools/info.js +113 -0
  525. package/dist/tools/naming.d.ts +27 -0
  526. package/dist/tools/naming.js +47 -0
  527. package/dist/tools/oauth/discovery.d.ts +65 -0
  528. package/dist/tools/oauth/discovery.js +307 -0
  529. package/dist/tools/oauth/flow.d.ts +63 -0
  530. package/dist/tools/oauth/flow.js +237 -0
  531. package/dist/tools/oauth/oauth.controller.d.ts +31 -0
  532. package/dist/tools/oauth/oauth.controller.js +95 -0
  533. package/dist/tools/oauth/tokens.d.ts +111 -0
  534. package/dist/tools/oauth/tokens.js +258 -0
  535. package/dist/tools/outputs.d.ts +61 -0
  536. package/dist/tools/outputs.js +156 -0
  537. package/dist/tools/pipeline.d.ts +322 -0
  538. package/dist/tools/pipeline.js +1236 -0
  539. package/dist/tools/policy.d.ts +60 -0
  540. package/dist/tools/policy.js +236 -0
  541. package/dist/tools/questions.controller.d.ts +24 -0
  542. package/dist/tools/questions.controller.js +58 -0
  543. package/dist/tools/questions.service.d.ts +103 -0
  544. package/dist/tools/questions.service.js +295 -0
  545. package/dist/tools/redact.d.ts +20 -0
  546. package/dist/tools/redact.js +60 -0
  547. package/dist/tools/registry.d.ts +246 -0
  548. package/dist/tools/registry.js +481 -0
  549. package/dist/tools/resources.d.ts +16 -0
  550. package/dist/tools/resources.js +76 -0
  551. package/dist/tools/specs.d.ts +14 -0
  552. package/dist/tools/specs.js +31 -0
  553. package/dist/tools/validate.d.ts +20 -0
  554. package/dist/tools/validate.js +183 -0
  555. package/dist/tools/view.d.ts +43 -0
  556. package/dist/tools/view.js +225 -0
  557. package/dist/ui/embed-token.d.ts +31 -0
  558. package/dist/ui/embed-token.js +132 -0
  559. package/dist/ui/registry.d.ts +58 -0
  560. package/dist/ui/registry.js +90 -0
  561. package/dist/ui/ui-stream.d.ts +37 -0
  562. package/dist/ui/ui-stream.js +162 -0
  563. package/dist/ui/views.controller.d.ts +81 -0
  564. package/dist/ui/views.controller.js +261 -0
  565. package/dist/ui/views.d.ts +155 -0
  566. package/dist/ui/views.js +306 -0
  567. package/dist/version.d.ts +5 -0
  568. package/dist/version.js +6 -0
  569. package/package.json +67 -3
  570. package/src/migrations/0001_init.sql +8 -0
  571. package/src/migrations/0002_secrets.sql +8 -0
  572. package/src/migrations/0003_identity.sql +117 -0
  573. package/src/migrations/0004_plugin_org_config_nullable.sql +3 -0
  574. package/src/migrations/0005_agents.sql +27 -0
  575. package/src/migrations/0006_conversations.sql +37 -0
  576. package/src/migrations/0007_checkpoints.sql +26 -0
  577. package/src/migrations/0008_runs_trigger_seq.sql +3 -0
  578. package/src/migrations/0009_runs_active_unique.sql +4 -0
  579. package/src/migrations/0010_tools.sql +125 -0
  580. package/src/migrations/0011_approvals_spec.sql +10 -0
  581. package/src/migrations/0012_run_waits.sql +24 -0
  582. package/src/migrations/0013_app_tools_source.sql +4 -0
  583. package/src/migrations/0014_tool_specs.sql +8 -0
  584. package/src/migrations/0015_tool_drift.sql +20 -0
  585. package/src/migrations/0016_plugin_permissions.sql +11 -0
  586. package/src/migrations/0017_identity_sources.sql +6 -0
  587. package/src/migrations/0018_channels.sql +74 -0
  588. package/src/migrations/0019_identity_trust.sql +17 -0
  589. package/src/migrations/0020_channel_card_lookup.sql +10 -0
  590. package/src/migrations/0021_org_storage_purge.sql +9 -0
  591. package/src/migrations/0022_attachments.sql +29 -0
  592. package/src/migrations/0023_sandboxes.sql +37 -0
  593. package/src/migrations/0024_skills.sql +46 -0
  594. package/src/migrations/0025_skills_catalog_idx.sql +6 -0
  595. package/src/migrations/0026_skill_changes.sql +34 -0
  596. package/src/migrations/0027_model_prices.sql +18 -0
  597. package/src/migrations/0028_evals.sql +105 -0
  598. package/src/migrations/0029_model_purposes.sql +18 -0
  599. package/src/migrations/0030_plugin_installs.sql +73 -0
  600. package/src/migrations/0031_plugin_snapshot_source.sql +6 -0
  601. package/src/migrations/0032_plugin_deployment_configs.sql +10 -0
  602. package/src/migrations/0033_rename_apps_to_connectors.sql +25 -0
  603. package/src/migrations/0034_directory.sql +49 -0
  604. package/src/migrations/0035_catalogs.sql +40 -0
  605. package/src/migrations/0036_app_import_staging.sql +17 -0
  606. package/src/migrations/0037_directory_installs.sql +92 -0
  607. package/src/migrations/0038_channel_inbound_mode.sql +6 -0
  608. package/src/migrations/0039_channel_card_pending.sql +8 -0
  609. package/src/migrations/0040_usage_report_sweep.sql +10 -0
  610. package/src/migrations/0041_rename_plugins_to_extensions.sql +38 -0
  611. package/src/migrations/0042_rename_directory_to_catalog.sql +80 -0
  612. package/src/migrations/0043_rename_app_installs_to_plugin_installs.sql +20 -0
  613. package/src/migrations/0044_catalog_one_kind.sql +90 -0
  614. package/src/migrations/0045_plugin_dependencies.sql +9 -0
  615. package/src/migrations/0046_git_sources.sql +25 -0
  616. package/src/migrations/0047_marketplace_entry_heads.sql +7 -0
  617. package/src/migrations/0048_marketplace_entry_trees.sql +8 -0
  618. package/src/migrations/0049_plugin_upgrades.sql +37 -0
  619. package/src/migrations/0050_bootstrap.sql +53 -0
  620. package/src/migrations/0051_claude_compat.sql +26 -0
  621. package/src/migrations/0052_conversations_account_agent_idx.sql +5 -0
  622. package/src/migrations/0053_subagents.sql +73 -0
  623. package/src/migrations/0054_subagent_wait_expiry.sql +7 -0
  624. package/src/migrations/0055_subagent_parent_indexes.sql +10 -0
  625. package/src/migrations/0056_approval_reason.sql +3 -0
  626. package/src/migrations/0057_conversation_titles.sql +11 -0
  627. package/src/migrations/0058_conversation_selection.sql +4 -0
  628. package/src/migrations/0059_conversation_queue.sql +22 -0
  629. package/src/migrations/0060_file_previewers.sql +10 -0
  630. package/src/migrations/0061_queue_selection.sql +5 -0
  631. package/src/migrations/0062_queued_skill.sql +8 -0
@@ -0,0 +1,857 @@
1
+ // biome-ignore-all lint/suspicious/noTemplateCurlyInString: Claude Code variables such as ${CLAUDE_PLUGIN_ROOT} are plain text here
2
+ import { CATALOG_ITEM_NAME_RE, hasShellInjection, PLUGIN_MANIFEST_FILE, PLUGIN_MANIFEST_LIMITS, parsePluginManifest, parseSkillMd, SEMVER_VERSION_RE, SKILL_ENTRY_FILE, skillInvocation, } from "@capybara-hq/plugin-sdk";
3
+ import semver from "semver";
4
+ import { cleanInvocationKeys } from "../../skills/invocation-keys.js";
5
+ import { PluginPackageError } from "../plugin-package.js";
6
+ import { translateClaudeAgents } from "./agents.js";
7
+ import { CLAUDE_TRANSLATOR_REVISION, invocationKeyItems, translateClaudeCommands, } from "./commands.js";
8
+ import { asList, CLAUDE_PLUGIN_FILE, CLAUDE_STRICT_COMPONENT_KEYS, componentPath, cut, decodeUtf8, isObj, readJsonFile, showName, } from "./manifest.js";
9
+ import { GENERATED_CONNECTORS_DIR, mcpServerTemplates } from "./mcp.js";
10
+ import { item, printable, sortItems, } from "./report.js";
11
+ const HOOKS_FILE = "hooks/hooks.json";
12
+ const MCP_FILE = ".mcp.json";
13
+ const MAX_HOOK_ITEMS = 100;
14
+ /**
15
+ * Most distinct entries one component key takes over all its declarations (plugin.json and the
16
+ * marketplace entry); the rest are counted in one "too many paths" item. Bounds the work a hostile
17
+ * manifest can cause (each path may read and parse a file).
18
+ */
19
+ const MAX_DECLARED_PATHS = 100;
20
+ /** Top-level `plugin.json` keys this reader knows; any other key is "unknown_field". */
21
+ const MAPPED_KEYS = new Set([
22
+ "$schema",
23
+ "name",
24
+ "version",
25
+ "description",
26
+ "displayName",
27
+ "author",
28
+ "license",
29
+ "homepage",
30
+ "repository",
31
+ "keywords",
32
+ "dependencies",
33
+ "skills",
34
+ "commands",
35
+ "agents",
36
+ "hooks",
37
+ "mcpServers",
38
+ "types",
39
+ ]);
40
+ /** Keys that mean nothing to Capybara (spec §8.3 "not applicable"). */
41
+ const NOT_APPLICABLE_KEYS = [
42
+ "lspServers",
43
+ "outputStyles",
44
+ "themes",
45
+ "monitors",
46
+ "workflows",
47
+ "userConfig",
48
+ "channels",
49
+ "settings",
50
+ "defaultEnabled",
51
+ "metadata",
52
+ "icon",
53
+ "documentationUrl",
54
+ "supportUrl",
55
+ "privacyPolicyUrl",
56
+ "termsOfServiceUrl",
57
+ ];
58
+ /** Default files and directories that mean nothing to Capybara. */
59
+ const NOT_APPLICABLE_FILES = [
60
+ ".lsp.json",
61
+ "output-styles/",
62
+ "themes/",
63
+ "monitors/",
64
+ "workflows/",
65
+ "bin/",
66
+ "settings.json",
67
+ ];
68
+ /** Manifests and directories of other agent harnesses at the root (besides `.<x>-plugin/`). */
69
+ const OTHER_HARNESS = [".agents/", ".opencode/", ".pi/", "gemini-extension.json"];
70
+ /**
71
+ * Root entries a root SKILL.md does not take with it (spec §8.3): every harness manifest directory
72
+ * (`.<x>-plugin/`, including Claude's and Capybara's), `.capybara-generated/`, git files, the other
73
+ * component directories and files, package.json and the license. The not-applicable files, the
74
+ * other harnesses' entries and the other skill directories are excluded where the set is built.
75
+ */
76
+ const ROOT_SKILL_EXCLUDE = /^(?:\.[^/]+-plugin\/|\.capybara-generated\/|\.git|hooks\/|commands\/|agents\/|skills\/|\.mcp\.json$|\.lsp\.json$|package\.json$|LICEN[CS]E)/;
77
+ /** Top directories no skill may live in: the manifests and the generated templates. */
78
+ const RESERVED_SKILL_TOPS = new Set([".capybara-plugin", ".capybara-generated", ".claude-plugin"]);
79
+ const RESTRICTION_KEYS = ["allowed-tools", "disallowed-tools", "model", "effort"];
80
+ /** Claude Code's built-in sub-agent types a forked skill may name (run as general-purpose). */
81
+ const BUILTIN_AGENT_TYPES = new Set(["general-purpose", "Explore", "Plan"]);
82
+ const CLAUDE_VARIABLES = [
83
+ "${CLAUDE_PLUGIN_ROOT}",
84
+ "${CLAUDE_PLUGIN_DATA}",
85
+ "${CLAUDE_PROJECT_DIR}",
86
+ "${user_config.",
87
+ ];
88
+ /** The Claude Code variables used in `texts`, as one `skill_claude_variables` item, or none. */
89
+ function claudeVariableItems(component, name, at, texts) {
90
+ const seen = new Set();
91
+ for (const t of texts)
92
+ for (const v of CLAUDE_VARIABLES)
93
+ if (t.includes(v))
94
+ seen.add(v);
95
+ if (seen.size === 0)
96
+ return [];
97
+ const variables = CLAUDE_VARIABLES.filter((v) => seen.has(v))
98
+ .map((v) => (v.endsWith(".") ? `${v}*}` : v))
99
+ .join(", ");
100
+ return [item("skill_claude_variables", component, name, { ...at, detail: { variables } })];
101
+ }
102
+ /**
103
+ * Claude Code's `@path` file references (`@src/a.ts`, `(@README.md)`): an `@` at the start or after
104
+ * whitespace or `(`, then a token with a `/` or a `.` inside. Mentions (`@team`) and e-mail
105
+ * addresses are not references.
106
+ */
107
+ const FILE_REF_RE = /(?:^|[\s(])@([^\s`'"<>()[\]{},;]+)/g;
108
+ const FILE_REFS_LISTED = 5;
109
+ /** The `skill_file_reference` item of a body with `@file` references (they stay text), or none. */
110
+ function fileReferenceItems(component, name, at, body) {
111
+ const refs = [];
112
+ for (const m of body.matchAll(FILE_REF_RE)) {
113
+ const ref = m[1].replace(/[.:!?]+$/, "");
114
+ if (/[/.]/.test(ref) && !refs.includes(ref))
115
+ refs.push(ref);
116
+ }
117
+ if (refs.length === 0)
118
+ return [];
119
+ const listed = refs.slice(0, FILE_REFS_LISTED).map((r) => showName(r));
120
+ if (refs.length > FILE_REFS_LISTED)
121
+ listed.push("…");
122
+ return [
123
+ item("skill_file_reference", component, name, { ...at, detail: { files: listed.join(", ") } }),
124
+ ];
125
+ }
126
+ /**
127
+ * The tree looks like a Claude plugin: no `.capybara-plugin/plugin.json` and one of
128
+ * `.claude-plugin/plugin.json`, `hooks/hooks.json`, `.mcp.json`, `commands/`, `agents/`, a root
129
+ * `SKILL.md`; or `hint` (a Claude marketplace entry). A tree with only `skills/` stays the A1
130
+ * skills-only plugin.
131
+ */
132
+ export function isClaudePluginTree(files, hint) {
133
+ if (files.has(PLUGIN_MANIFEST_FILE))
134
+ return false;
135
+ if (hint !== undefined)
136
+ return true;
137
+ if ([CLAUDE_PLUGIN_FILE, HOOKS_FILE, MCP_FILE, SKILL_ENTRY_FILE].some((p) => files.has(p))) {
138
+ return true;
139
+ }
140
+ for (const p of files.keys())
141
+ if (p.startsWith("commands/") || p.startsWith("agents/"))
142
+ return true;
143
+ return false;
144
+ }
145
+ const invalidManifest = (issue) => {
146
+ throw new PluginPackageError("catalog.invalid_manifest", [issue]);
147
+ };
148
+ /**
149
+ * Translates the tree (see the file header). Throws `PluginPackageError("catalog.invalid_manifest")`
150
+ * only for: a plugin name Capybara cannot use (including an unreadable `plugin.json`), a
151
+ * `strict: false` conflict, a path leaving the root, and a plugin with no importable skill and no
152
+ * template.
153
+ */
154
+ export function translateClaudePlugin(files, o) {
155
+ const items = [];
156
+ const add = (...it) => items.push(...it);
157
+ const keys = [...files.keys()].sort();
158
+ const under = (dir) => (dir === "" ? keys : keys.filter((p) => p.startsWith(`${dir}/`)));
159
+ const dirExists = (dir) => keys.some((p) => p.startsWith(`${dir}/`));
160
+ // plugin.json: optional; when present it must be a readable JSON object with a usable name.
161
+ const manifestBytes = files.get(CLAUDE_PLUGIN_FILE);
162
+ let m = {};
163
+ if (manifestBytes !== undefined) {
164
+ const r = readJsonFile(manifestBytes);
165
+ if ("problem" in r)
166
+ invalidManifest(`${CLAUDE_PLUGIN_FILE} is ${r.problem}`);
167
+ else if (!isObj(r.value))
168
+ invalidManifest(`${CLAUDE_PLUGIN_FILE} must be a JSON object`);
169
+ else
170
+ m = r.value;
171
+ }
172
+ const hasManifest = manifestBytes !== undefined;
173
+ const name = hasManifest && m.name !== undefined
174
+ ? m.name
175
+ : hasManifest
176
+ ? invalidManifest(`${CLAUDE_PLUGIN_FILE}: name is required`)
177
+ : o.fallbackName;
178
+ if (typeof name !== "string" || !CATALOG_ITEM_NAME_RE.test(name)) {
179
+ invalidManifest(`${hasManifest ? `${CLAUDE_PLUGIN_FILE} name` : "plugin name"} ${JSON.stringify(typeof name === "string" ? showName(name) : String(name))} must match ^[a-z0-9][a-z0-9-]{0,63}$`);
180
+ }
181
+ const pluginName = name;
182
+ const field = (code, key, detail) => add(item(code, "field", key, detail !== undefined ? { detail } : {}));
183
+ const wrongType = (key, problem) => field("unknown_field", key, { problem });
184
+ // Version (spec §5.3): plugin.json, else the entry's, else derived from the source.
185
+ let version;
186
+ if (typeof m.version === "string" &&
187
+ SEMVER_VERSION_RE.test(m.version) &&
188
+ m.version.length <= 256) {
189
+ version = m.version;
190
+ }
191
+ else if (o.entryVersion !== undefined && SEMVER_VERSION_RE.test(o.entryVersion)) {
192
+ version = o.entryVersion;
193
+ field("version_from_entry", "version", { version });
194
+ }
195
+ else {
196
+ version = o.fallbackVersion;
197
+ field("version_fallback", "version", { version });
198
+ }
199
+ const text = (key, max) => {
200
+ const v = m[key];
201
+ if (v === undefined)
202
+ return undefined;
203
+ if (typeof v !== "string") {
204
+ wrongType(key, `${key} must be a string`);
205
+ return undefined;
206
+ }
207
+ const s = cut(v, max);
208
+ return s === "" ? undefined : s;
209
+ };
210
+ const description = text("description", PLUGIN_MANIFEST_LIMITS.descriptionChars);
211
+ const displayName = text("displayName", PLUGIN_MANIFEST_LIMITS.displayNameChars);
212
+ const license = text("license", 100);
213
+ const homepageRaw = text("homepage", 2000);
214
+ const homepage = homepageRaw !== undefined && /^https:\/\/\S+$/.test(homepageRaw) ? homepageRaw : undefined;
215
+ if (homepageRaw !== undefined && homepage === undefined) {
216
+ wrongType("homepage", "homepage must be an https URL");
217
+ }
218
+ const repository = typeof m.repository === "string" ? printable(cut(m.repository, 2000)) : undefined;
219
+ let publisher;
220
+ if (m.author !== undefined) {
221
+ if (isObj(m.author) && typeof m.author.name === "string") {
222
+ publisher = cut(m.author.name, PLUGIN_MANIFEST_LIMITS.publisherChars) || undefined;
223
+ }
224
+ else
225
+ wrongType("author", "author must be an object with a name");
226
+ }
227
+ if (publisher === undefined) {
228
+ publisher = cut(o.overlay?.publisher ?? o.fallbackPublisher, PLUGIN_MANIFEST_LIMITS.publisherChars);
229
+ field("publisher_from_marketplace", "publisher", { publisher });
230
+ }
231
+ // Dependencies: "name", "name@marketplace" or { name, version?, marketplace? }.
232
+ const dependencies = [];
233
+ if (m.dependencies !== undefined) {
234
+ if (!Array.isArray(m.dependencies)) {
235
+ wrongType("dependencies", "dependencies must be an array");
236
+ }
237
+ else {
238
+ for (const d of m.dependencies) {
239
+ let dn;
240
+ let range;
241
+ let marketplace;
242
+ if (typeof d === "string") {
243
+ const at = d.indexOf("@");
244
+ dn = at < 0 ? d : d.slice(0, at);
245
+ marketplace = at < 0 ? undefined : d.slice(at + 1);
246
+ }
247
+ else if (isObj(d)) {
248
+ dn = d.name;
249
+ range = d.version;
250
+ marketplace = d.marketplace;
251
+ }
252
+ const label = typeof dn === "string" ? showName(dn) : "?";
253
+ const ignore = (problem) => add(item("unknown_field", "plugin", label, { detail: { problem } }));
254
+ if (typeof dn !== "string" || !CATALOG_ITEM_NAME_RE.test(dn)) {
255
+ ignore("the dependency name must match ^[a-z0-9][a-z0-9-]{0,63}$");
256
+ continue;
257
+ }
258
+ if (dn === pluginName || dependencies.some((x) => x.name === dn)) {
259
+ ignore("duplicate dependency or a dependency on itself");
260
+ continue;
261
+ }
262
+ if (range !== undefined &&
263
+ (typeof range !== "string" || semver.validRange(range) === null)) {
264
+ ignore("the dependency version must be a semver range");
265
+ continue;
266
+ }
267
+ if (dependencies.length >= PLUGIN_MANIFEST_LIMITS.dependencies) {
268
+ ignore("too many dependencies");
269
+ continue;
270
+ }
271
+ const v = range ?? "*";
272
+ dependencies.push({ name: dn, version: v });
273
+ add(item("dependency_mapped", "plugin", dn, {
274
+ detail: {
275
+ version: v,
276
+ ...(typeof marketplace === "string" && { marketplace: showName(marketplace) }),
277
+ },
278
+ }));
279
+ }
280
+ }
281
+ }
282
+ // Other plugin.json keys.
283
+ for (const k of NOT_APPLICABLE_KEYS)
284
+ if (m[k] !== undefined)
285
+ field("not_applicable", k);
286
+ if (m.experimental !== undefined) {
287
+ if (isObj(m.experimental)) {
288
+ for (const k of Object.keys(m.experimental)) {
289
+ field("not_applicable", `experimental.${showName(k)}`);
290
+ }
291
+ }
292
+ else
293
+ field("not_applicable", "experimental");
294
+ }
295
+ for (const k of Object.keys(m)) {
296
+ if (!MAPPED_KEYS.has(k) && !NOT_APPLICABLE_KEYS.includes(k)) {
297
+ if (k !== "experimental")
298
+ field("unknown_field", showName(k));
299
+ }
300
+ }
301
+ if (m.types !== undefined)
302
+ add(item("hooks_module", "hook", "types"));
303
+ // Component declarations: plugin.json, then the marketplace entry by Claude's strict rule.
304
+ const ov = o.overlay;
305
+ const entryWhere = `marketplace entry ${showName(o.fallbackName)}`;
306
+ /**
307
+ * Deduplicates and caps the entries of one component key (see MAX_DECLARED_PATHS): `take` says
308
+ * whether to process an entry (`id` is its resolved path, or undefined for an inline object);
309
+ * `done` reports what was left out.
310
+ */
311
+ const limiter = (key) => {
312
+ const seen = new Set();
313
+ let taken = 0;
314
+ let more = 0;
315
+ return {
316
+ take(id) {
317
+ if (id !== undefined && seen.has(id))
318
+ return false;
319
+ if (taken >= MAX_DECLARED_PATHS) {
320
+ more++;
321
+ return false;
322
+ }
323
+ if (id !== undefined)
324
+ seen.add(id);
325
+ taken++;
326
+ return true;
327
+ },
328
+ done() {
329
+ if (more > 0) {
330
+ add(item("unknown_field", "field", key, { detail: { problem: "too many paths", more } }));
331
+ }
332
+ },
333
+ };
334
+ };
335
+ // Each JSON file is parsed at most once per translation.
336
+ const jsonCache = new Map();
337
+ const readJson = (path, data) => {
338
+ let r = jsonCache.get(path);
339
+ if (r === undefined) {
340
+ r = readJsonFile(data);
341
+ jsonCache.set(path, r);
342
+ }
343
+ return r;
344
+ };
345
+ const decls = (key) => {
346
+ const out = [];
347
+ if (m[key] !== undefined)
348
+ out.push({ value: m[key], where: CLAUDE_PLUGIN_FILE });
349
+ const ev = ov?.components[key];
350
+ if (ev === undefined)
351
+ return out;
352
+ const strictKey = CLAUDE_STRICT_COMPONENT_KEYS.includes(key);
353
+ if (!hasManifest || strictKey)
354
+ out.push({ value: ev, where: entryWhere });
355
+ return out;
356
+ };
357
+ if (ov !== undefined) {
358
+ const entryKeys = Object.keys(ov.components);
359
+ const entryStrict = entryKeys.filter((k) => CLAUDE_STRICT_COMPONENT_KEYS.includes(k));
360
+ if (hasManifest && !ov.strict && entryStrict.length > 0) {
361
+ const both = CLAUDE_STRICT_COMPONENT_KEYS.some((k) => m[k] !== undefined);
362
+ if (both) {
363
+ invalidManifest(`marketplace entry ${showName(o.fallbackName)} sets strict: false and declares components that plugin.json declares too`);
364
+ }
365
+ }
366
+ if (hasManifest) {
367
+ for (const k of entryKeys) {
368
+ if (!CLAUDE_STRICT_COMPONENT_KEYS.includes(k)) {
369
+ wrongType(`entry.${showName(k)}`, "this entry field applies only to plugins without plugin.json");
370
+ }
371
+ }
372
+ }
373
+ else {
374
+ for (const k of NOT_APPLICABLE_KEYS) {
375
+ if (ov.components[k] !== undefined)
376
+ field("not_applicable", k);
377
+ }
378
+ }
379
+ const used = entryKeys.filter((k) => !hasManifest || entryStrict.includes(k));
380
+ if (used.length > 0) {
381
+ field("entry_components_merged", "components", { keys: used.join(", ") });
382
+ }
383
+ }
384
+ // Commands and agents: listed paths replace the default directory.
385
+ const mdFiles = (dir, recursive) => under(dir).filter((p) => p.endsWith(".md") && (recursive || !p.slice(dir.length + 1).includes("/")));
386
+ /** The declared (else default-directory) Markdown files of `commands` / `agents`. */
387
+ const collectMd = (key, recursive) => {
388
+ const ds = decls(key);
389
+ const limit = limiter(key);
390
+ const paths = [];
391
+ const named = [];
392
+ if (ds.length === 0)
393
+ paths.push(...mdFiles(key, recursive));
394
+ for (const d of ds) {
395
+ if (key === "commands" && isObj(d.value)) {
396
+ for (const [cn, cv] of Object.entries(d.value)) {
397
+ if (!limit.take(`\0${cn}`))
398
+ continue;
399
+ const src = isObj(cv) && typeof cv.source === "string"
400
+ ? componentPath(cv.source, `${d.where} commands`)
401
+ : null;
402
+ const content = isObj(cv) && typeof cv.content === "string" ? cv.content : undefined;
403
+ named.push({
404
+ name: showName(cn),
405
+ ...(src && "rel" in src && { path: src.rel }),
406
+ ...(src === null && content !== undefined && { content }),
407
+ });
408
+ }
409
+ continue;
410
+ }
411
+ const list = asList(d.value);
412
+ if (list === null || list.some((x) => typeof x !== "string")) {
413
+ wrongType(key, `${key} must be a path or an array of paths`);
414
+ continue;
415
+ }
416
+ for (const raw of list) {
417
+ const r = componentPath(raw, `${d.where} ${key}`);
418
+ if (!limit.take("rel" in r ? r.rel : `\0${raw}`))
419
+ continue;
420
+ if ("problem" in r) {
421
+ wrongType(key, r.problem);
422
+ continue;
423
+ }
424
+ if (files.has(r.rel))
425
+ paths.push(r.rel);
426
+ else
427
+ paths.push(...mdFiles(r.rel, recursive));
428
+ }
429
+ }
430
+ limit.done();
431
+ for (const p of [...new Set(paths)]) {
432
+ const base = p.startsWith(`${key}/`)
433
+ ? p.slice(key.length + 1)
434
+ : p.split("/").pop();
435
+ named.push({ name: showName(base.replace(/\.md$/, "")), path: p });
436
+ }
437
+ return named;
438
+ };
439
+ // Agents become agent templates (phase C, sub-agents spec §16.4); before the skills, whose
440
+ // `agent` names are checked against them
441
+ const agentPaths = collectMd("agents", true).flatMap((n) => (n.path ? [n.path] : []));
442
+ const agents = translateClaudeAgents(files, agentPaths, pluginName);
443
+ add(...agents.items);
444
+ const agentNames = new Set(agents.agents.map((a) => a.name));
445
+ /**
446
+ * The items of an imported skill or command beyond "imported" (phase D spec §8.1): manual-only,
447
+ * forked (with an unknown `agent` warned), shell injections, ignored restrictions.
448
+ */
449
+ const skillItems = (component, sn, at, fm, body) => {
450
+ const out = [];
451
+ const inv = skillInvocation(fm);
452
+ if (!inv.model)
453
+ out.push(item("skill_manual_only", component, sn, at));
454
+ if (inv.fork) {
455
+ const agent = inv.fork.agent ?? "general-purpose";
456
+ out.push(item("skill_forked", component, sn, { ...at, detail: { agent } }));
457
+ const own = agent.startsWith(`${pluginName}:`) ? agent.slice(pluginName.length + 1) : agent;
458
+ if (!BUILTIN_AGENT_TYPES.has(agent) && !agentNames.has(own)) {
459
+ out.push(item("skill_agent_unknown", component, sn, { ...at, detail: { agent } }));
460
+ }
461
+ }
462
+ if (hasShellInjection(body))
463
+ out.push(item("skill_shell_injection", component, sn, at));
464
+ out.push(...fileReferenceItems(component, sn, at, body));
465
+ const restricted = RESTRICTION_KEYS.filter((k) => fm[k] !== undefined);
466
+ if (restricted.length > 0) {
467
+ out.push(item("skill_ignored_restrictions", component, sn, {
468
+ ...at,
469
+ detail: { keys: restricted.join(", ") },
470
+ }));
471
+ }
472
+ return out;
473
+ };
474
+ // Skills: skills/*/SKILL.md plus the listed directories; a root SKILL.md is one skill. A
475
+ // directory in a reserved place, or inside / around one already taken, is an item (first wins).
476
+ const skillDirs = [];
477
+ const addSkillDir = (dir) => {
478
+ if (skillDirs.includes(dir))
479
+ return;
480
+ const rejected = (problem) => add(item("skill_invalid", "skill", showName(dir.split("/").pop()), {
481
+ path: dir,
482
+ detail: { problem: `${showName(dir)} ${problem}` },
483
+ }));
484
+ if (dir !== "") {
485
+ if (RESERVED_SKILL_TOPS.has(dir.split("/")[0])) {
486
+ return rejected("is a reserved directory");
487
+ }
488
+ for (const d of skillDirs) {
489
+ if (d === "")
490
+ continue;
491
+ if (dir.startsWith(`${d}/`))
492
+ return rejected(`is inside the skill directory ${d}`);
493
+ if (d.startsWith(`${dir}/`))
494
+ return rejected(`contains the skill directory ${d}`);
495
+ }
496
+ }
497
+ skillDirs.push(dir);
498
+ };
499
+ const skillDecls = decls("skills");
500
+ for (const p of keys) {
501
+ const mm = /^(skills\/[^/]+)\/SKILL\.md$/.exec(p);
502
+ if (mm)
503
+ addSkillDir(mm[1]);
504
+ }
505
+ const skillLimit = limiter("skills");
506
+ for (const d of skillDecls) {
507
+ const list = asList(d.value);
508
+ if (list === null || list.some((x) => typeof x !== "string")) {
509
+ wrongType("skills", "skills must be a path or an array of paths");
510
+ continue;
511
+ }
512
+ for (const raw of list) {
513
+ const r = componentPath(raw, `${d.where} skills`, true);
514
+ if (!skillLimit.take("rel" in r ? r.rel : `\0${raw}`))
515
+ continue;
516
+ if ("problem" in r) {
517
+ wrongType("skills", r.problem);
518
+ continue;
519
+ }
520
+ const dir = r.rel;
521
+ const entry = dir === "" ? SKILL_ENTRY_FILE : `${dir}/${SKILL_ENTRY_FILE}`;
522
+ if (files.has(entry)) {
523
+ addSkillDir(dir);
524
+ continue;
525
+ }
526
+ const re = new RegExp(`^${dir === "" ? "" : `${escapeRe(dir)}/`}([^/]+)/SKILL\\.md$`);
527
+ const found = keys.filter((p) => re.test(p));
528
+ if (found.length === 0) {
529
+ add(item("skill_invalid", "skill", showName(dir || "."), {
530
+ path: dir || ".",
531
+ detail: { problem: "no SKILL.md found" },
532
+ }));
533
+ }
534
+ for (const p of found)
535
+ addSkillDir(p.slice(0, -`/${SKILL_ENTRY_FILE}`.length));
536
+ }
537
+ }
538
+ skillLimit.done();
539
+ if (files.has(SKILL_ENTRY_FILE) && !dirExists("skills") && skillDecls.length === 0) {
540
+ addSkillDir("");
541
+ }
542
+ // What a root SKILL.md leaves where it is (see ROOT_SKILL_EXCLUDE).
543
+ const rootExcluded = (p) => ROOT_SKILL_EXCLUDE.test(p) ||
544
+ [...NOT_APPLICABLE_FILES, ...OTHER_HARNESS].some((f) => f.endsWith("/") ? p.startsWith(f) : p === f) ||
545
+ skillDirs.some((d) => d !== "" && p.startsWith(`${d}/`));
546
+ const tree = new Map();
547
+ for (const [p, data] of files)
548
+ if (p !== "package.json")
549
+ tree.set(p, data);
550
+ const imported = [];
551
+ for (const dir of skillDirs) {
552
+ const entryPath = dir === "" ? SKILL_ENTRY_FILE : `${dir}/${SKILL_ENTRY_FILE}`;
553
+ const label = showName(dir === "" ? SKILL_ENTRY_FILE : dir.split("/").pop());
554
+ const at = { path: dir === "" ? SKILL_ENTRY_FILE : dir };
555
+ const md = decodeUtf8(files.get(entryPath));
556
+ // Invocation keys are read leniently: one the strict checks refuse is ignored with a warning,
557
+ // as the skill imported before phase D (batch 1 review M3); the source file is kept as written
558
+ const parsed = md === undefined
559
+ ? { errors: ["not valid UTF-8 text"] }
560
+ : parseSkillMd(md, { invocationKeys: false });
561
+ if ("errors" in parsed) {
562
+ add(item("skill_invalid", "skill", label, {
563
+ ...at,
564
+ detail: { problem: parsed.errors.join("; ") },
565
+ }));
566
+ continue;
567
+ }
568
+ const clean = cleanInvocationKeys(parsed.frontmatter);
569
+ const fm = clean.frontmatter;
570
+ const sn = parsed.name;
571
+ const other = imported.find((s) => s.name === sn);
572
+ if (other !== undefined) {
573
+ add(item("skill_invalid", "skill", sn, {
574
+ ...at,
575
+ detail: { problem: `skill name ${sn} is also used by ${other.dir || SKILL_ENTRY_FILE}` },
576
+ }));
577
+ continue;
578
+ }
579
+ if (imported.length >= PLUGIN_MANIFEST_LIMITS.skills) {
580
+ add(item("skill_invalid", "skill", sn, { ...at, detail: { problem: "too many skills" } }));
581
+ continue;
582
+ }
583
+ let target = dir;
584
+ const skillFiles = dir === "" ? keys.filter((p) => !rootExcluded(p)) : under(dir);
585
+ if (dir === "") {
586
+ target = `skills/${sn}`;
587
+ if (dirExists(target)) {
588
+ add(item("skill_invalid", "skill", sn, {
589
+ ...at,
590
+ detail: { problem: `the root SKILL.md cannot move to ${target}: it exists` },
591
+ }));
592
+ continue;
593
+ }
594
+ for (const p of skillFiles) {
595
+ tree.delete(p);
596
+ tree.set(`${target}/${p}`, files.get(p));
597
+ }
598
+ add(item("skill_root_relocated", "skill", sn, {
599
+ path: SKILL_ENTRY_FILE,
600
+ detail: { to: target },
601
+ }));
602
+ }
603
+ imported.push({ name: sn, dir: target });
604
+ add(item("skill_imported", "skill", sn, { path: target }));
605
+ add(...invocationKeyItems("skill", sn, { path: target }, clean.dropped));
606
+ add(...skillItems("skill", sn, { path: target }, fm, parsed.body));
607
+ const texts = skillFiles
608
+ .map((p) => decodeUtf8(files.get(p)))
609
+ .filter((t) => t !== undefined);
610
+ add(...claudeVariableItems("skill", sn, { path: target }, texts));
611
+ }
612
+ // Commands become skills (phase D spec §8.2), after the skills: a skill wins over a command
613
+ const commands = translateClaudeCommands(files, collectMd("commands", false), new Set(imported.map((x) => x.name)), {
614
+ room: PLUGIN_MANIFEST_LIMITS.skills - imported.length,
615
+ // A command's body is its whole skill, so it is scanned for Claude variables here (M1)
616
+ skillItems: (component, name, at, fm, body) => [
617
+ ...skillItems(component, name, at, fm, body),
618
+ ...claudeVariableItems(component, name, at, [body]),
619
+ ],
620
+ });
621
+ add(...commands.items);
622
+ for (const [p, data] of commands.generated)
623
+ tree.set(p, data);
624
+ imported.push(...commands.skills);
625
+ // Hooks: never run (spec §8.3); one item per event with its handler types.
626
+ const events = new Map();
627
+ const hookProblems = [];
628
+ const readEvents = (map, path) => {
629
+ if (!isObj(map)) {
630
+ hookProblems.push(item("hooks_not_run", "hook", showName(path ?? "hooks"), {
631
+ ...(path !== undefined && { path }),
632
+ detail: { problem: "the hooks configuration is not an object" },
633
+ }));
634
+ return;
635
+ }
636
+ for (const [ev, matchers] of Object.entries(map)) {
637
+ const e = events.get(ev) ?? { types: new Set(), ...(path !== undefined && { path }) };
638
+ events.set(ev, e);
639
+ if (!Array.isArray(matchers))
640
+ continue;
641
+ for (const mt of matchers.slice(0, 1000)) {
642
+ if (!isObj(mt) || !Array.isArray(mt.hooks))
643
+ continue;
644
+ for (const h of mt.hooks.slice(0, 1000)) {
645
+ if (isObj(h) && typeof h.type === "string")
646
+ e.types.add(showName(h.type));
647
+ }
648
+ }
649
+ }
650
+ };
651
+ const readHooksFile = (path) => {
652
+ const data = files.get(path);
653
+ if (data === undefined) {
654
+ hookProblems.push(item("hooks_not_run", "hook", showName(path), {
655
+ path,
656
+ detail: { problem: "file not found" },
657
+ }));
658
+ return;
659
+ }
660
+ const r = readJson(path, data);
661
+ if ("problem" in r) {
662
+ hookProblems.push(item("hooks_not_run", "hook", showName(path), { path, detail: { problem: r.problem } }));
663
+ return;
664
+ }
665
+ readEvents(isObj(r.value) ? r.value.hooks : undefined, path);
666
+ };
667
+ if (files.has(HOOKS_FILE))
668
+ readHooksFile(HOOKS_FILE);
669
+ const hookLimit = limiter("hooks");
670
+ for (const d of decls("hooks")) {
671
+ const list = Array.isArray(d.value) ? d.value : [d.value];
672
+ for (const h of list) {
673
+ if (isObj(h)) {
674
+ if (!hookLimit.take(undefined))
675
+ continue;
676
+ readEvents(h, d.where === CLAUDE_PLUGIN_FILE ? CLAUDE_PLUGIN_FILE : undefined);
677
+ continue;
678
+ }
679
+ const r = componentPath(h, `${d.where} hooks`);
680
+ if (!hookLimit.take("rel" in r ? r.rel : `\0${String(h)}`))
681
+ continue;
682
+ if ("problem" in r) {
683
+ wrongType("hooks", r.problem);
684
+ continue;
685
+ }
686
+ if (/\.(?:[cm]?js|[cm]?ts)$/.test(r.rel)) {
687
+ add(item("hooks_module", "hook", showName(r.rel), { path: r.rel }));
688
+ continue;
689
+ }
690
+ readHooksFile(r.rel);
691
+ }
692
+ }
693
+ hookLimit.done();
694
+ const eventItems = [...events.entries()].map(([ev, e]) => item("hooks_not_run", "hook", showName(ev), {
695
+ ...(e.path !== undefined && { path: e.path }),
696
+ detail: { handlers: [...e.types].sort().join(", ") },
697
+ }));
698
+ add(...eventItems.slice(0, MAX_HOOK_ITEMS), ...hookProblems.slice(0, MAX_HOOK_ITEMS));
699
+ const moreHooks = Math.max(0, eventItems.length - MAX_HOOK_ITEMS) +
700
+ Math.max(0, hookProblems.length - MAX_HOOK_ITEMS);
701
+ if (moreHooks > 0)
702
+ add(item("hooks_not_run", "hook", "…", { detail: { more: moreHooks } }));
703
+ const sessionStart = events.has("SessionStart");
704
+ if (sessionStart)
705
+ add(item("session_start_pin_hint", "hook", "SessionStart"));
706
+ // MCP servers: .mcp.json first, then each declaration; a later name replaces an earlier one.
707
+ // A Map: an untrusted "__proto__" key must never touch an object's prototype.
708
+ const servers = new Map();
709
+ const serverPaths = new Map();
710
+ const takeServers = (map, path) => {
711
+ if (!isObj(map)) {
712
+ add(item("mcp_invalid", "mcpServer", showName(path ?? "mcpServers"), {
713
+ ...(path !== undefined && { path }),
714
+ detail: { reason: "not an object" },
715
+ }));
716
+ return;
717
+ }
718
+ const inner = isObj(map.mcpServers) ? map.mcpServers : map;
719
+ for (const [k, v] of Object.entries(inner)) {
720
+ if (k === "__proto__") {
721
+ add(item("mcp_invalid", "mcpServer", k, {
722
+ ...(path !== undefined && { path }),
723
+ detail: { reason: "the server name __proto__ is not allowed" },
724
+ }));
725
+ continue;
726
+ }
727
+ if (servers.size >= 200 && !servers.has(k)) {
728
+ add(item("mcp_invalid", "mcpServer", showName(k), {
729
+ ...(path !== undefined && { path }),
730
+ detail: { reason: "too many servers" },
731
+ }));
732
+ continue;
733
+ }
734
+ servers.set(k, v);
735
+ if (path !== undefined)
736
+ serverPaths.set(k, path);
737
+ else
738
+ serverPaths.delete(k);
739
+ }
740
+ };
741
+ const readMcpFile = (path) => {
742
+ const data = files.get(path);
743
+ const r = data === undefined ? { problem: "file not found" } : readJson(path, data);
744
+ if ("problem" in r) {
745
+ add(item("mcp_invalid", "mcpServer", showName(path), { path, detail: { reason: r.problem } }));
746
+ return;
747
+ }
748
+ takeServers(r.value, path);
749
+ };
750
+ if (files.has(MCP_FILE))
751
+ readMcpFile(MCP_FILE);
752
+ const mcpLimit = limiter("mcpServers");
753
+ for (const d of decls("mcpServers")) {
754
+ const list = Array.isArray(d.value) ? d.value : [d.value];
755
+ for (const s of list) {
756
+ if (!mcpLimit.take(isObj(s) ? undefined : `\0${String(s)}`))
757
+ continue;
758
+ if (isObj(s)) {
759
+ takeServers(s, d.where === CLAUDE_PLUGIN_FILE ? CLAUDE_PLUGIN_FILE : undefined);
760
+ continue;
761
+ }
762
+ if (typeof s === "string" && /^https:\/\//.test(s) && /\.(?:mcpb|dxt)$/.test(s)) {
763
+ add(item("mcp_unsupported_transport", "mcpServer", showName(s), {
764
+ detail: { transport: "mcpb" },
765
+ }));
766
+ continue;
767
+ }
768
+ const r = componentPath(s, `${d.where} mcpServers`);
769
+ if ("problem" in r) {
770
+ wrongType("mcpServers", r.problem);
771
+ continue;
772
+ }
773
+ if (/\.(?:mcpb|dxt)$/.test(r.rel)) {
774
+ add(item("mcp_unsupported_transport", "mcpServer", showName(r.rel), {
775
+ path: r.rel,
776
+ detail: { transport: r.rel.endsWith(".dxt") ? "dxt" : "mcpb" },
777
+ }));
778
+ continue;
779
+ }
780
+ readMcpFile(r.rel);
781
+ }
782
+ }
783
+ mcpLimit.done();
784
+ const mcp = mcpServerTemplates(servers, pluginName, {
785
+ paths: serverPaths,
786
+ ...(o.allowInsecureLoopback === true && { allowInsecureLoopback: true }),
787
+ });
788
+ add(...mcp.items);
789
+ // Not applicable files and other harnesses' manifests.
790
+ for (const f of NOT_APPLICABLE_FILES) {
791
+ const present = f.endsWith("/") ? dirExists(f.slice(0, -1)) : files.has(f);
792
+ if (present)
793
+ add(item("not_applicable", "file", f.replace(/\/$/, ""), { path: f.replace(/\/$/, "") }));
794
+ }
795
+ const harness = new Set();
796
+ for (const p of keys) {
797
+ const top = p.split("/")[0];
798
+ if (p.includes("/") &&
799
+ /^\.[^/]+-plugin$/.test(top) &&
800
+ top !== ".claude-plugin" &&
801
+ top !== ".capybara-plugin") {
802
+ harness.add(top);
803
+ }
804
+ }
805
+ for (const f of OTHER_HARNESS) {
806
+ if (f.endsWith("/") ? dirExists(f.slice(0, -1)) : files.has(f))
807
+ harness.add(f.replace(/\/$/, ""));
808
+ }
809
+ for (const h of harness)
810
+ add(item("other_harness", "file", h, { path: h }));
811
+ if (imported.length === 0 && mcp.files.size === 0 && agents.agents.length === 0) {
812
+ invalidManifest("the Claude Code plugin has no skill Capybara can import, no agent and no remote MCP server (see the translation report)");
813
+ }
814
+ // The synthesized manifest lists every skill and template, so the reader never scans.
815
+ const templatePaths = [];
816
+ for (const [id, file] of mcp.files) {
817
+ const p = `${GENERATED_CONNECTORS_DIR}/${id}.json`;
818
+ tree.set(p, new TextEncoder().encode(`${JSON.stringify(file, null, 2)}\n`));
819
+ templatePaths.push(p);
820
+ }
821
+ for (const a of agents.agents)
822
+ tree.set(a.path, a.data);
823
+ const manifest = {
824
+ schemaVersion: 1,
825
+ name: pluginName,
826
+ version,
827
+ publisher: publisher || pluginName,
828
+ description: description ?? `Claude Code plugin ${pluginName}`,
829
+ ...(displayName !== undefined && { displayName: { zh: displayName, en: displayName } }),
830
+ ...(license !== undefined && { license }),
831
+ ...(homepage !== undefined && { homepage }),
832
+ ...(dependencies.length > 0 && { dependencies }),
833
+ skills: imported.map((s) => ({ path: `./${s.dir}` })),
834
+ connectorTemplates: templatePaths.map((p) => ({ path: `./${p}` })),
835
+ // always listed, empty when nothing translated: without the list readPluginFiles would scan
836
+ // the raw Claude agents/*.md the tree still holds and parse them as Capybara templates
837
+ // (batch 12 review I1); normalizedManifest drops an empty list, so digests are unchanged
838
+ agents: agents.agents.map((a) => ({ path: `./${a.path}` })),
839
+ };
840
+ const checked = parsePluginManifest(manifest);
841
+ if ("errors" in checked) {
842
+ invalidManifest(`${PLUGIN_MANIFEST_FILE} (translated): ${checked.errors[0]}`);
843
+ }
844
+ tree.set(PLUGIN_MANIFEST_FILE, new TextEncoder().encode(`${JSON.stringify(manifest, null, 2)}\n`));
845
+ return {
846
+ tree,
847
+ report: {
848
+ format: "claude-code",
849
+ manifestPath: hasManifest ? CLAUDE_PLUGIN_FILE : null,
850
+ sessionStart,
851
+ items: sortItems(items),
852
+ },
853
+ ...(repository !== undefined && repository !== "" && { repository }),
854
+ ...(items.some((i) => i.component === "command" || i.code === "skill_manual_only" || i.code === "skill_forked") && { translatorRevision: CLAUDE_TRANSLATOR_REVISION }),
855
+ };
856
+ }
857
+ const escapeRe = (s) => s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");