contextos-agents 1.6.1 → 2.0.0-beta.2

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 (323) hide show
  1. package/.agents/AGENTS.md +6 -1
  2. package/.agents/adapters/aider/export.js +117 -97
  3. package/.agents/adapters/claude/export.js +68 -26
  4. package/.agents/adapters/copilot/export.js +90 -51
  5. package/.agents/adapters/cursor/export.js +83 -68
  6. package/.agents/adapters/drift-detector.js +196 -0
  7. package/.agents/adapters/gemini/export.js +76 -45
  8. package/.agents/adapters/pure-compiler.js +443 -0
  9. package/.agents/adapters/zed/export.js +109 -62
  10. package/.agents/compiled/registry.v2.json +504 -0
  11. package/.agents/compiled/registry.v2.sha256 +1 -0
  12. package/.agents/compiler/manifest-compiler.js +963 -0
  13. package/.agents/compiler/vendor/yaml.LICENSE.txt +13 -0
  14. package/.agents/compiler/vendor/yaml.SBOM.json +6 -0
  15. package/.agents/compiler/vendor/yaml.js +139 -0
  16. package/.agents/core/profiles/init.yaml +25 -0
  17. package/.agents/core/skills/context-manager/references/context-rules.md +59 -0
  18. package/.agents/core/skills/context-manager/skill.yaml +10 -5
  19. package/.agents/core/skills/context-os/SKILL.md +3 -6
  20. package/.agents/core/skills/context-os/skill.yaml +14 -8
  21. package/.agents/core/skills/engineering-workflow/SKILL.md +1 -1
  22. package/.agents/core/skills/engineering-workflow/skill.yaml +7 -7
  23. package/.agents/core/skills/gemini-precision/SKILL.md +4 -0
  24. package/.agents/core/skills/gemini-precision/skill.yaml +5 -6
  25. package/.agents/core/skills/gstack-roles/SKILL.md +3 -1
  26. package/.agents/core/skills/gstack-roles/skill.yaml +9 -6
  27. package/.agents/core/skills/ponytail-mindset/skill.yaml +7 -7
  28. package/.agents/core/skills/security/skill.yaml +21 -2
  29. package/.agents/ctx.js +587 -111
  30. package/.agents/customization-dx.js +282 -0
  31. package/.agents/doctor.js +877 -33
  32. package/.agents/filesystem/index.js +71 -0
  33. package/.agents/filesystem/journaled-transaction.js +451 -0
  34. package/.agents/filesystem/lockfile-v2.js +275 -0
  35. package/.agents/filesystem/platform-hardening.js +222 -0
  36. package/.agents/filesystem/project-lock.js +218 -0
  37. package/.agents/filesystem/safe-path.js +256 -0
  38. package/.agents/generated/claude/skills/context-os/SKILL.md +1 -1
  39. package/.agents/generated/claude/skills/engineering-workflow/SKILL.md +1 -1
  40. package/.agents/generated/claude/skills/gemini-precision/SKILL.md +4 -0
  41. package/.agents/generated/claude/skills/gstack-roles/SKILL.md +3 -1
  42. package/.agents/generated/gemini/skills/context-os/SKILL.md +2 -2
  43. package/.agents/generated/gemini/skills/engineering-workflow/SKILL.md +1 -1
  44. package/.agents/generated/gemini/skills/gemini-precision/SKILL.md +4 -0
  45. package/.agents/generated/gemini/skills/gstack-roles/SKILL.md +3 -1
  46. package/.agents/plugins/contextos/hooks.json +25 -0
  47. package/.agents/plugins/contextos/plugin.json +19 -0
  48. package/.agents/plugins.js +432 -73
  49. package/.agents/profiles.js +507 -46
  50. package/.agents/resolver.js +50 -414
  51. package/.agents/schemas/attestation.review.v1.json +111 -0
  52. package/.agents/schemas/attestation.verification.v1.json +85 -0
  53. package/.agents/schemas/lockfile.v2.schema.json +134 -0
  54. package/.agents/schemas/profile.v2.schema.json +114 -0
  55. package/.agents/schemas/runtime.thread.v1.json +192 -0
  56. package/.agents/schemas/skill.manifest.v2.json +177 -0
  57. package/.agents/schemas/verification.spec.v1.json +39 -0
  58. package/.agents/schemas/workspace.graph.schema.json +106 -0
  59. package/.agents/stats.js +22 -9
  60. package/.agents/transaction-core/event-store.js +288 -0
  61. package/.agents/transaction-core/idempotency.js +129 -0
  62. package/.agents/transaction-core/ipc-lock.js +311 -0
  63. package/.agents/transaction-core/plugin-supply-chain-bundle.js +436 -0
  64. package/.agents/validate.js +143 -14
  65. package/.agents/watch.js +354 -102
  66. package/.agents/workspace/workspace-graph.js +778 -0
  67. package/README.md +59 -387
  68. package/benchmarks/v2/analysis/statistics.js +140 -0
  69. package/benchmarks/v2/analysis/stats.js +69 -0
  70. package/benchmarks/v2/arms/arm-definitions.js +79 -0
  71. package/benchmarks/v2/dataset.schema.json +34 -0
  72. package/benchmarks/v2/evaluators/index.js +25 -0
  73. package/benchmarks/v2/evaluators/verified-success.js +116 -0
  74. package/benchmarks/v2/harness/runner.js +88 -0
  75. package/benchmarks/v2/pilot-tasks.json +392 -0
  76. package/bin/commands/recover.js +88 -0
  77. package/bin/commands/uninstall.js +207 -0
  78. package/bin/commands/update.js +325 -0
  79. package/bin/commands.js +342 -0
  80. package/bin/index.js +326 -149
  81. package/bin/lib/detector.js +106 -0
  82. package/bin/lib/lockfile.js +253 -0
  83. package/bin/lib/safe-writer.js +290 -0
  84. package/package.json +85 -73
  85. package/registry.json +15 -7
  86. package/registry.schema.json +3 -1
  87. package/registry.v2.schema.json +86 -0
  88. package/.agents/core/profiles/backend.yaml +0 -47
  89. package/.agents/core/profiles/enterprise.yaml +0 -46
  90. package/.agents/core/profiles/frontend.yaml +0 -46
  91. package/.agents/core/profiles/hackathon.yaml +0 -45
  92. package/.agents/core/profiles/mvp.yaml +0 -44
  93. package/.agents/core/profiles/startup.yaml +0 -48
  94. package/.agents/core/skills/adapters/EXAMPLES.md +0 -19
  95. package/.agents/core/skills/adapters/SKILL.md +0 -105
  96. package/.agents/core/skills/adapters/TROUBLESHOOTING.md +0 -7
  97. package/.agents/core/skills/adapters/VALIDATION.json +0 -12
  98. package/.agents/core/skills/adapters/skill.yaml +0 -10
  99. package/.agents/core/skills/architecture-diagrams/SKILL.md +0 -108
  100. package/.agents/core/skills/architecture-diagrams/VALIDATION.json +0 -12
  101. package/.agents/core/skills/architecture-diagrams/skill.yaml +0 -8
  102. package/.agents/core/skills/brutalist-design/SKILL.md +0 -150
  103. package/.agents/core/skills/brutalist-design/VALIDATION.json +0 -12
  104. package/.agents/core/skills/brutalist-design/skill.yaml +0 -8
  105. package/.agents/core/skills/database/EXAMPLES.md +0 -74
  106. package/.agents/core/skills/database/SKILL.md +0 -101
  107. package/.agents/core/skills/database/TROUBLESHOOTING.md +0 -18
  108. package/.agents/core/skills/database/VALIDATION.json +0 -11
  109. package/.agents/core/skills/database/skill.yaml +0 -25
  110. package/.agents/core/skills/ddd/EXAMPLES.md +0 -42
  111. package/.agents/core/skills/ddd/SKILL.md +0 -247
  112. package/.agents/core/skills/ddd/TROUBLESHOOTING.md +0 -19
  113. package/.agents/core/skills/ddd/VALIDATION.json +0 -12
  114. package/.agents/core/skills/ddd/ddd.md +0 -178
  115. package/.agents/core/skills/ddd/skill.yaml +0 -10
  116. package/.agents/core/skills/decisions/EXAMPLES.md +0 -35
  117. package/.agents/core/skills/decisions/SKILL.md +0 -90
  118. package/.agents/core/skills/decisions/TROUBLESHOOTING.md +0 -13
  119. package/.agents/core/skills/decisions/VALIDATION.json +0 -12
  120. package/.agents/core/skills/decisions/skill.yaml +0 -10
  121. package/.agents/core/skills/docker/EXAMPLES.md +0 -56
  122. package/.agents/core/skills/docker/SKILL.md +0 -63
  123. package/.agents/core/skills/docker/TROUBLESHOOTING.md +0 -18
  124. package/.agents/core/skills/docker/VALIDATION.json +0 -11
  125. package/.agents/core/skills/docker/skill.yaml +0 -23
  126. package/.agents/core/skills/fastapi/EXAMPLES.md +0 -36
  127. package/.agents/core/skills/fastapi/SKILL.md +0 -148
  128. package/.agents/core/skills/fastapi/TROUBLESHOOTING.md +0 -19
  129. package/.agents/core/skills/fastapi/VALIDATION.json +0 -12
  130. package/.agents/core/skills/fastapi/fastapi.md +0 -112
  131. package/.agents/core/skills/fastapi/skill.yaml +0 -10
  132. package/.agents/core/skills/generators/EXAMPLES.md +0 -19
  133. package/.agents/core/skills/generators/SKILL.md +0 -112
  134. package/.agents/core/skills/generators/TROUBLESHOOTING.md +0 -7
  135. package/.agents/core/skills/generators/VALIDATION.json +0 -12
  136. package/.agents/core/skills/generators/skill.yaml +0 -10
  137. package/.agents/core/skills/generators/templates/API.md +0 -77
  138. package/.agents/core/skills/generators/templates/ARCHITECTURE.md +0 -70
  139. package/.agents/core/skills/generators/templates/DATABASE.md +0 -42
  140. package/.agents/core/skills/generators/templates/DECISION.md +0 -46
  141. package/.agents/core/skills/generators/templates/PRD.md +0 -67
  142. package/.agents/core/skills/generators/templates/PROJECT_GRAPH.md +0 -56
  143. package/.agents/core/skills/generators/templates/ROADMAP.md +0 -51
  144. package/.agents/core/skills/generators/templates/TASKS.md +0 -43
  145. package/.agents/core/skills/generators/templates/UI.md +0 -73
  146. package/.agents/core/skills/graphify/EXAMPLES.md +0 -73
  147. package/.agents/core/skills/graphify/SKILL.md +0 -130
  148. package/.agents/core/skills/graphify/VALIDATION.json +0 -12
  149. package/.agents/core/skills/graphify/skill.yaml +0 -13
  150. package/.agents/core/skills/impeccable-design/EXAMPLES.md +0 -26
  151. package/.agents/core/skills/impeccable-design/SKILL.md +0 -201
  152. package/.agents/core/skills/impeccable-design/TROUBLESHOOTING.md +0 -19
  153. package/.agents/core/skills/impeccable-design/VALIDATION.json +0 -12
  154. package/.agents/core/skills/impeccable-design/skill.yaml +0 -14
  155. package/.agents/core/skills/interview-me/SKILL.md +0 -97
  156. package/.agents/core/skills/interview-me/VALIDATION.json +0 -12
  157. package/.agents/core/skills/interview-me/skill.yaml +0 -8
  158. package/.agents/core/skills/microservices/EXAMPLES.md +0 -38
  159. package/.agents/core/skills/microservices/SKILL.md +0 -164
  160. package/.agents/core/skills/microservices/TROUBLESHOOTING.md +0 -19
  161. package/.agents/core/skills/microservices/VALIDATION.json +0 -12
  162. package/.agents/core/skills/microservices/microservices.md +0 -119
  163. package/.agents/core/skills/microservices/skill.yaml +0 -10
  164. package/.agents/core/skills/minimalist-design/SKILL.md +0 -113
  165. package/.agents/core/skills/minimalist-design/VALIDATION.json +0 -12
  166. package/.agents/core/skills/minimalist-design/skill.yaml +0 -8
  167. package/.agents/core/skills/nestjs/EXAMPLES.md +0 -40
  168. package/.agents/core/skills/nestjs/SKILL.md +0 -139
  169. package/.agents/core/skills/nestjs/TROUBLESHOOTING.md +0 -19
  170. package/.agents/core/skills/nestjs/VALIDATION.json +0 -12
  171. package/.agents/core/skills/nestjs/nestjs.md +0 -103
  172. package/.agents/core/skills/nestjs/skill.yaml +0 -10
  173. package/.agents/core/skills/nextjs/EXAMPLES.md +0 -40
  174. package/.agents/core/skills/nextjs/SKILL.md +0 -163
  175. package/.agents/core/skills/nextjs/TROUBLESHOOTING.md +0 -19
  176. package/.agents/core/skills/nextjs/VALIDATION.json +0 -12
  177. package/.agents/core/skills/nextjs/nextjs.md +0 -67
  178. package/.agents/core/skills/nextjs/skill.yaml +0 -10
  179. package/.agents/core/skills/node/EXAMPLES.md +0 -80
  180. package/.agents/core/skills/node/SKILL.md +0 -128
  181. package/.agents/core/skills/node/TROUBLESHOOTING.md +0 -19
  182. package/.agents/core/skills/node/VALIDATION.json +0 -12
  183. package/.agents/core/skills/node/node.md +0 -87
  184. package/.agents/core/skills/node/skill.yaml +0 -10
  185. package/.agents/core/skills/performance/EXAMPLES.md +0 -30
  186. package/.agents/core/skills/performance/SKILL.md +0 -75
  187. package/.agents/core/skills/performance/TROUBLESHOOTING.md +0 -19
  188. package/.agents/core/skills/performance/VALIDATION.json +0 -12
  189. package/.agents/core/skills/performance/performance.md +0 -52
  190. package/.agents/core/skills/performance/skill.yaml +0 -10
  191. package/.agents/core/skills/react/EXAMPLES.md +0 -79
  192. package/.agents/core/skills/react/SKILL.md +0 -132
  193. package/.agents/core/skills/react/TROUBLESHOOTING.md +0 -19
  194. package/.agents/core/skills/react/VALIDATION.json +0 -12
  195. package/.agents/core/skills/react/react.md +0 -93
  196. package/.agents/core/skills/react/skill.yaml +0 -10
  197. package/.agents/core/skills/react-best-practices/SKILL.md +0 -155
  198. package/.agents/core/skills/react-best-practices/VALIDATION.json +0 -12
  199. package/.agents/core/skills/react-best-practices/skill.yaml +0 -10
  200. package/.agents/core/skills/redesign-audit/SKILL.md +0 -117
  201. package/.agents/core/skills/redesign-audit/VALIDATION.json +0 -12
  202. package/.agents/core/skills/redesign-audit/skill.yaml +0 -8
  203. package/.agents/core/skills/soft-design/SKILL.md +0 -108
  204. package/.agents/core/skills/soft-design/VALIDATION.json +0 -12
  205. package/.agents/core/skills/soft-design/skill.yaml +0 -8
  206. package/.agents/core/skills/state-management/EXAMPLES.md +0 -56
  207. package/.agents/core/skills/state-management/SKILL.md +0 -48
  208. package/.agents/core/skills/state-management/TROUBLESHOOTING.md +0 -18
  209. package/.agents/core/skills/state-management/VALIDATION.json +0 -11
  210. package/.agents/core/skills/state-management/skill.yaml +0 -22
  211. package/.agents/core/skills/subagent-orchestrator/SKILL.md +0 -100
  212. package/.agents/core/skills/subagent-orchestrator/VALIDATION.json +0 -12
  213. package/.agents/core/skills/subagent-orchestrator/skill.yaml +0 -8
  214. package/.agents/core/skills/system-design/EXAMPLES.md +0 -75
  215. package/.agents/core/skills/system-design/SKILL.md +0 -419
  216. package/.agents/core/skills/system-design/TROUBLESHOOTING.md +0 -19
  217. package/.agents/core/skills/system-design/VALIDATION.json +0 -12
  218. package/.agents/core/skills/system-design/skill.yaml +0 -13
  219. package/.agents/core/skills/system-design/system-design.md +0 -112
  220. package/.agents/core/skills/testing/EXAMPLES.md +0 -71
  221. package/.agents/core/skills/testing/SKILL.md +0 -70
  222. package/.agents/core/skills/testing/TROUBLESHOOTING.md +0 -18
  223. package/.agents/core/skills/testing/VALIDATION.json +0 -11
  224. package/.agents/core/skills/testing/skill.yaml +0 -26
  225. package/.agents/core/skills/typescript/EXAMPLES.md +0 -64
  226. package/.agents/core/skills/typescript/SKILL.md +0 -112
  227. package/.agents/core/skills/typescript/TROUBLESHOOTING.md +0 -19
  228. package/.agents/core/skills/typescript/VALIDATION.json +0 -12
  229. package/.agents/core/skills/typescript/skill.yaml +0 -10
  230. package/.agents/core/skills/typescript/typescript.md +0 -71
  231. package/.agents/core/skills/ui-design/EXAMPLES.md +0 -21
  232. package/.agents/core/skills/ui-design/SKILL.md +0 -124
  233. package/.agents/core/skills/ui-design/TROUBLESHOOTING.md +0 -19
  234. package/.agents/core/skills/ui-design/VALIDATION.json +0 -12
  235. package/.agents/core/skills/ui-design/skill.yaml +0 -10
  236. package/.agents/core/skills/ui-design/ui.md +0 -88
  237. package/.agents/core/skills/ui-ux-pro/EXAMPLES.md +0 -62
  238. package/.agents/core/skills/ui-ux-pro/SKILL.md +0 -375
  239. package/.agents/core/skills/ui-ux-pro/TROUBLESHOOTING.md +0 -19
  240. package/.agents/core/skills/ui-ux-pro/VALIDATION.json +0 -12
  241. package/.agents/core/skills/ui-ux-pro/skill.yaml +0 -13
  242. package/.agents/core/skills/ux-design/EXAMPLES.md +0 -36
  243. package/.agents/core/skills/ux-design/SKILL.md +0 -116
  244. package/.agents/core/skills/ux-design/TROUBLESHOOTING.md +0 -19
  245. package/.agents/core/skills/ux-design/VALIDATION.json +0 -12
  246. package/.agents/core/skills/ux-design/skill.yaml +0 -10
  247. package/.agents/core/skills/ux-design/ux.md +0 -80
  248. package/.agents/core/skills/vercel-optimize/SKILL.md +0 -83
  249. package/.agents/core/skills/vercel-optimize/VALIDATION.json +0 -12
  250. package/.agents/core/skills/vercel-optimize/skill.yaml +0 -10
  251. package/.agents/core/skills/web-accessibility/EXAMPLES.md +0 -39
  252. package/.agents/core/skills/web-accessibility/SKILL.md +0 -170
  253. package/.agents/core/skills/web-accessibility/TROUBLESHOOTING.md +0 -19
  254. package/.agents/core/skills/web-accessibility/VALIDATION.json +0 -12
  255. package/.agents/core/skills/web-accessibility/accessibility.md +0 -63
  256. package/.agents/core/skills/web-accessibility/skill.yaml +0 -10
  257. package/.agents/generated/claude/skills/adapters/SKILL.md +0 -126
  258. package/.agents/generated/claude/skills/architecture-diagrams/SKILL.md +0 -101
  259. package/.agents/generated/claude/skills/brutalist-design/SKILL.md +0 -145
  260. package/.agents/generated/claude/skills/database/SKILL.md +0 -191
  261. package/.agents/generated/claude/skills/ddd/SKILL.md +0 -305
  262. package/.agents/generated/claude/skills/decisions/SKILL.md +0 -134
  263. package/.agents/generated/claude/skills/docker/SKILL.md +0 -135
  264. package/.agents/generated/claude/skills/fastapi/SKILL.md +0 -200
  265. package/.agents/generated/claude/skills/generators/SKILL.md +0 -133
  266. package/.agents/generated/claude/skills/graphify/SKILL.md +0 -198
  267. package/.agents/generated/claude/skills/impeccable-design/SKILL.md +0 -241
  268. package/.agents/generated/claude/skills/interview-me/SKILL.md +0 -90
  269. package/.agents/generated/claude/skills/microservices/SKILL.md +0 -218
  270. package/.agents/generated/claude/skills/minimalist-design/SKILL.md +0 -108
  271. package/.agents/generated/claude/skills/nestjs/SKILL.md +0 -195
  272. package/.agents/generated/claude/skills/nextjs/SKILL.md +0 -219
  273. package/.agents/generated/claude/skills/node/SKILL.md +0 -224
  274. package/.agents/generated/claude/skills/performance/SKILL.md +0 -121
  275. package/.agents/generated/claude/skills/react/SKILL.md +0 -227
  276. package/.agents/generated/claude/skills/react-best-practices/SKILL.md +0 -146
  277. package/.agents/generated/claude/skills/redesign-audit/SKILL.md +0 -112
  278. package/.agents/generated/claude/skills/soft-design/SKILL.md +0 -103
  279. package/.agents/generated/claude/skills/state-management/SKILL.md +0 -120
  280. package/.agents/generated/claude/skills/subagent-orchestrator/SKILL.md +0 -93
  281. package/.agents/generated/claude/skills/system-design/SKILL.md +0 -507
  282. package/.agents/generated/claude/skills/testing/SKILL.md +0 -157
  283. package/.agents/generated/claude/skills/typescript/SKILL.md +0 -192
  284. package/.agents/generated/claude/skills/ui-design/SKILL.md +0 -161
  285. package/.agents/generated/claude/skills/ui-ux-pro/SKILL.md +0 -451
  286. package/.agents/generated/claude/skills/ux-design/SKILL.md +0 -168
  287. package/.agents/generated/claude/skills/vercel-optimize/SKILL.md +0 -76
  288. package/.agents/generated/claude/skills/web-accessibility/SKILL.md +0 -225
  289. package/.agents/generated/gemini/skills/adapters/SKILL.md +0 -135
  290. package/.agents/generated/gemini/skills/architecture-diagrams/SKILL.md +0 -107
  291. package/.agents/generated/gemini/skills/brutalist-design/SKILL.md +0 -151
  292. package/.agents/generated/gemini/skills/database/SKILL.md +0 -200
  293. package/.agents/generated/gemini/skills/ddd/SKILL.md +0 -314
  294. package/.agents/generated/gemini/skills/decisions/SKILL.md +0 -143
  295. package/.agents/generated/gemini/skills/docker/SKILL.md +0 -144
  296. package/.agents/generated/gemini/skills/fastapi/SKILL.md +0 -209
  297. package/.agents/generated/gemini/skills/generators/SKILL.md +0 -142
  298. package/.agents/generated/gemini/skills/graphify/SKILL.md +0 -205
  299. package/.agents/generated/gemini/skills/impeccable-design/SKILL.md +0 -250
  300. package/.agents/generated/gemini/skills/interview-me/SKILL.md +0 -96
  301. package/.agents/generated/gemini/skills/microservices/SKILL.md +0 -227
  302. package/.agents/generated/gemini/skills/minimalist-design/SKILL.md +0 -114
  303. package/.agents/generated/gemini/skills/nestjs/SKILL.md +0 -204
  304. package/.agents/generated/gemini/skills/nextjs/SKILL.md +0 -298
  305. package/.agents/generated/gemini/skills/node/SKILL.md +0 -323
  306. package/.agents/generated/gemini/skills/performance/SKILL.md +0 -185
  307. package/.agents/generated/gemini/skills/react/SKILL.md +0 -332
  308. package/.agents/generated/gemini/skills/react-best-practices/SKILL.md +0 -152
  309. package/.agents/generated/gemini/skills/redesign-audit/SKILL.md +0 -118
  310. package/.agents/generated/gemini/skills/soft-design/SKILL.md +0 -109
  311. package/.agents/generated/gemini/skills/state-management/SKILL.md +0 -129
  312. package/.agents/generated/gemini/skills/subagent-orchestrator/SKILL.md +0 -99
  313. package/.agents/generated/gemini/skills/system-design/SKILL.md +0 -631
  314. package/.agents/generated/gemini/skills/testing/SKILL.md +0 -166
  315. package/.agents/generated/gemini/skills/typescript/SKILL.md +0 -275
  316. package/.agents/generated/gemini/skills/ui-design/SKILL.md +0 -170
  317. package/.agents/generated/gemini/skills/ui-ux-pro/SKILL.md +0 -460
  318. package/.agents/generated/gemini/skills/ux-design/SKILL.md +0 -177
  319. package/.agents/generated/gemini/skills/vercel-optimize/SKILL.md +0 -82
  320. package/.agents/generated/gemini/skills/web-accessibility/SKILL.md +0 -300
  321. package/.agents/mcp/runtime.py +0 -470
  322. package/.agents/mcp/server.mjs +0 -189271
  323. package/benchmarks/gemini-issues.js +0 -533
@@ -0,0 +1,436 @@
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
11
+ };
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(to, key) && key !== except)
16
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
+ }
18
+ return to;
19
+ };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
28
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
+
30
+ // src/plugins/adapter.ts
31
+ var adapter_exports = {};
32
+ __export(adapter_exports, {
33
+ AtomicPluginUpdater: () => AtomicPluginUpdater,
34
+ ScriptGrantManager: () => ScriptGrantManager,
35
+ THREAT_CODES: () => THREAT_CODES,
36
+ calculateTreeDigest: () => calculateTreeDigest,
37
+ sha256: () => sha256,
38
+ validateArchiveEntry: () => validateArchiveEntry,
39
+ validatePluginPinning: () => validatePluginPinning,
40
+ verifyNpmTarballIntegrity: () => verifyNpmTarballIntegrity
41
+ });
42
+ module.exports = __toCommonJS(adapter_exports);
43
+
44
+ // src/plugins/core/archive.ts
45
+ var path = __toESM(require("node:path"), 1);
46
+
47
+ // src/plugins/core/types.ts
48
+ var THREAT_CODES = {
49
+ UNKNOWN_SOURCE_TYPE: "CTX_PLUGIN_UNKNOWN_SOURCE_TYPE",
50
+ FLOATING_SOURCE_BLOCKED: "CTX_PLUGIN_FLOATING_SOURCE_BLOCKED",
51
+ IMPLICIT_LATEST_BLOCKED: "CTX_PLUGIN_IMPLICIT_LATEST_BLOCKED",
52
+ MISSING_INTEGRITY: "CTX_PLUGIN_MISSING_INTEGRITY",
53
+ INVALID_PATH: "CTX_ARCHIVE_INVALID_PATH",
54
+ ABSOLUTE_PATH: "CTX_ARCHIVE_ABSOLUTE_PATH",
55
+ PATH_TRAVERSAL: "CTX_ARCHIVE_PATH_TRAVERSAL",
56
+ RESERVED_NAME: "CTX_ARCHIVE_RESERVED_NAME",
57
+ MAX_FILES_EXCEEDED: "CTX_ARCHIVE_MAX_FILES_EXCEEDED",
58
+ MAX_SIZE_EXCEEDED: "CTX_ARCHIVE_MAX_SIZE_EXCEEDED",
59
+ RATIO_EXCEEDED: "CTX_ARCHIVE_RATIO_EXCEEDED",
60
+ CASE_COLLISION: "CTX_ARCHIVE_CASE_COLLISION",
61
+ SYMLINK_ESCAPE: "CTX_ARCHIVE_SYMLINK_ESCAPE",
62
+ SPECIAL_FILE: "CTX_ARCHIVE_SPECIAL_FILE",
63
+ MODIFIED_LOCALLY: "CTX_PLUGIN_MODIFIED_LOCALLY"
64
+ };
65
+
66
+ // src/plugins/core/archive.ts
67
+ var WINDOWS_RESERVED_NAMES = /^(?:con|prn|aux|nul|com[1-9]|lpt[1-9])(?:\..*)?$/i;
68
+ function validateArchiveEntry(entryPath, limits = {}) {
69
+ if (typeof entryPath !== "string" || !entryPath.trim()) {
70
+ return {
71
+ valid: false,
72
+ code: THREAT_CODES.INVALID_PATH,
73
+ error: "Empty or non-string archive path"
74
+ };
75
+ }
76
+ const normalized = entryPath.replace(/\\/g, "/").replace(/^\.\//, "");
77
+ if (path.isAbsolute(entryPath) || /^[a-zA-Z]:[\\/]/.test(entryPath) || /^[a-zA-Z]:/.test(normalized) || normalized.startsWith("/")) {
78
+ return {
79
+ valid: false,
80
+ code: THREAT_CODES.ABSOLUTE_PATH,
81
+ error: `Security violation: absolute archive path rejected: "${entryPath}"`
82
+ };
83
+ }
84
+ const parts = normalized.split("/");
85
+ if (parts.includes("..") || normalized.startsWith("../") || normalized.includes("/../")) {
86
+ return {
87
+ valid: false,
88
+ code: THREAT_CODES.PATH_TRAVERSAL,
89
+ error: `Security violation: archive path attempts traversal outside destination: "${entryPath}"`
90
+ };
91
+ }
92
+ for (const part of parts) {
93
+ if (WINDOWS_RESERVED_NAMES.test(part)) {
94
+ return {
95
+ valid: false,
96
+ code: THREAT_CODES.RESERVED_NAME,
97
+ error: `Security violation: Windows reserved device name rejected: "${part}" in "${entryPath}"`
98
+ };
99
+ }
100
+ }
101
+ if (limits.entryType === "socket" || limits.entryType === "fifo" || limits.entryType === "characterDevice" || limits.entryType === "blockDevice") {
102
+ return {
103
+ valid: false,
104
+ code: THREAT_CODES.SPECIAL_FILE,
105
+ error: `Security violation: special device or socket rejected: "${entryPath}" (${limits.entryType})`
106
+ };
107
+ }
108
+ if (limits.linkTarget || limits.entryType === "symlink" || limits.entryType === "hardlink") {
109
+ if (limits.linkTarget) {
110
+ const targetNorm = limits.linkTarget.replace(/\\/g, "/");
111
+ if (path.isAbsolute(limits.linkTarget) || /^[a-zA-Z]:/.test(targetNorm) || targetNorm.startsWith("/")) {
112
+ return {
113
+ valid: false,
114
+ code: THREAT_CODES.SYMLINK_ESCAPE,
115
+ error: `Security violation: absolute symlink/hardlink target rejected: "${limits.linkTarget}"`
116
+ };
117
+ }
118
+ const entryDir = path.posix.dirname(normalized);
119
+ const resolvedTarget = path.posix.normalize(path.posix.join(entryDir, targetNorm));
120
+ if (resolvedTarget.startsWith("../") || resolvedTarget === ".." || resolvedTarget.includes("/../")) {
121
+ return {
122
+ valid: false,
123
+ code: THREAT_CODES.SYMLINK_ESCAPE,
124
+ error: `Security violation: symlink target escapes archive boundary: "${limits.linkTarget}"`
125
+ };
126
+ }
127
+ }
128
+ }
129
+ if (limits.seenPaths) {
130
+ const folded = normalized.toLowerCase().normalize("NFC");
131
+ if (limits.seenPaths.has(folded)) {
132
+ return {
133
+ valid: false,
134
+ code: THREAT_CODES.CASE_COLLISION,
135
+ error: `Security violation: case or Unicode collision detected for path: "${entryPath}"`
136
+ };
137
+ }
138
+ limits.seenPaths.add(folded);
139
+ }
140
+ if (typeof limits.uncompressedSize === "number" && typeof limits.compressedSize === "number") {
141
+ if (limits.compressedSize > 0) {
142
+ const ratio = limits.uncompressedSize / limits.compressedSize;
143
+ const maxRatio = limits.maxRatio ?? 100;
144
+ if (ratio > maxRatio && limits.uncompressedSize > 1024 * 1024) {
145
+ return {
146
+ valid: false,
147
+ code: THREAT_CODES.RATIO_EXCEEDED,
148
+ error: `Security violation: suspicious compression ratio (${ratio.toFixed(1)}x) exceeds limit (${maxRatio}x)`
149
+ };
150
+ }
151
+ }
152
+ }
153
+ if (typeof limits.currentCount === "number" && limits.maxFiles && limits.currentCount >= limits.maxFiles) {
154
+ return {
155
+ valid: false,
156
+ code: THREAT_CODES.MAX_FILES_EXCEEDED,
157
+ error: `Security violation: archive exceeds maximum permitted file count (${limits.maxFiles})`
158
+ };
159
+ }
160
+ if (typeof limits.currentTotalBytes === "number" && limits.maxTotalBytes && limits.currentTotalBytes >= limits.maxTotalBytes) {
161
+ return {
162
+ valid: false,
163
+ code: THREAT_CODES.MAX_SIZE_EXCEEDED,
164
+ error: `Security violation: archive exceeds maximum uncompressed size (${limits.maxTotalBytes} bytes)`
165
+ };
166
+ }
167
+ return { valid: true };
168
+ }
169
+
170
+ // src/plugins/core/digest.ts
171
+ var crypto = __toESM(require("node:crypto"), 1);
172
+ var fs = __toESM(require("node:fs"), 1);
173
+ var path2 = __toESM(require("node:path"), 1);
174
+ function sha256(data) {
175
+ return crypto.createHash("sha256").update(data).digest("hex");
176
+ }
177
+ function calculateTreeDigest(dirPath, _options = {}) {
178
+ const resolvedDir = path2.resolve(dirPath);
179
+ if (!fs.existsSync(resolvedDir)) {
180
+ throw new Error(`Directory does not exist: ${resolvedDir}`);
181
+ }
182
+ const fileEntries = [];
183
+ function walk(current) {
184
+ const items = fs.readdirSync(current, { withFileTypes: true });
185
+ items.sort((a, b) => a.name.localeCompare(b.name));
186
+ for (const item of items) {
187
+ const fullPath = path2.join(current, item.name);
188
+ if (item.isDirectory()) {
189
+ walk(fullPath);
190
+ } else if (item.isSymbolicLink()) {
191
+ const rel = path2.relative(resolvedDir, fullPath).replace(/\\/g, "/");
192
+ const stat = fs.lstatSync(fullPath);
193
+ const linkTarget = fs.readlinkSync(fullPath);
194
+ const hash = sha256(linkTarget);
195
+ fileEntries.push({
196
+ relativePath: rel,
197
+ size: stat.size,
198
+ mode: stat.mode & 511,
199
+ sha256: hash,
200
+ type: "symlink"
201
+ });
202
+ } else if (item.isFile()) {
203
+ const rel = path2.relative(resolvedDir, fullPath).replace(/\\/g, "/");
204
+ const stat = fs.statSync(fullPath);
205
+ const content = fs.readFileSync(fullPath);
206
+ const hash = sha256(content);
207
+ fileEntries.push({
208
+ relativePath: rel,
209
+ size: stat.size,
210
+ mode: stat.mode & 511,
211
+ sha256: hash,
212
+ type: "file"
213
+ });
214
+ }
215
+ }
216
+ }
217
+ walk(resolvedDir);
218
+ fileEntries.sort((a, b) => a.relativePath.localeCompare(b.relativePath));
219
+ const manifestString = fileEntries.map((f) => `${f.relativePath}|${f.size}|${f.mode}|${f.type}|${f.sha256}`).join("\n");
220
+ const treeDigest = sha256(manifestString);
221
+ return {
222
+ treeDigest,
223
+ files: fileEntries
224
+ };
225
+ }
226
+
227
+ // src/plugins/core/grants.ts
228
+ var fs2 = __toESM(require("node:fs"), 1);
229
+ var path3 = __toESM(require("node:path"), 1);
230
+ var ScriptGrantManager = class {
231
+ grantsFilePath;
232
+ grants;
233
+ constructor(grantsFilePath) {
234
+ this.grantsFilePath = path3.resolve(grantsFilePath);
235
+ this.grants = this._load();
236
+ }
237
+ _load() {
238
+ if (!fs2.existsSync(this.grantsFilePath)) return {};
239
+ try {
240
+ return JSON.parse(fs2.readFileSync(this.grantsFilePath, "utf8"));
241
+ } catch {
242
+ return {};
243
+ }
244
+ }
245
+ _save() {
246
+ fs2.mkdirSync(path3.dirname(this.grantsFilePath), { recursive: true });
247
+ fs2.writeFileSync(this.grantsFilePath, JSON.stringify(this.grants, null, 2), "utf8");
248
+ }
249
+ /**
250
+ * Grants execution permission to a specific script by its content hash.
251
+ * Binds both to plugin identity and content hash.
252
+ */
253
+ grant(scriptPath, options = {}) {
254
+ const resolved = path3.resolve(scriptPath);
255
+ const content = fs2.readFileSync(resolved);
256
+ const hash = sha256(content);
257
+ const record = {
258
+ hash,
259
+ grantedAt: Date.now(),
260
+ pluginId: options.pluginId,
261
+ relPath: options.relPath
262
+ };
263
+ if (options.pluginId) {
264
+ const idKey = `plugin:${options.pluginId}:${options.relPath || path3.basename(scriptPath)}`;
265
+ this.grants[idKey] = record;
266
+ }
267
+ this.grants[resolved] = record;
268
+ this._save();
269
+ }
270
+ /**
271
+ * Verifies if a script is authorized to run.
272
+ * Invalidates grant immediately if script was altered.
273
+ */
274
+ checkAuthorization(scriptPath, options = {}) {
275
+ const resolved = path3.resolve(scriptPath);
276
+ if (!fs2.existsSync(resolved)) {
277
+ return { authorized: false, reason: "Script file not found." };
278
+ }
279
+ let record;
280
+ if (options.pluginId) {
281
+ const idKey = `plugin:${options.pluginId}:${options.relPath || path3.basename(scriptPath)}`;
282
+ record = this.grants[idKey] || this.grants[resolved];
283
+ } else {
284
+ record = this.grants[resolved];
285
+ }
286
+ if (!record) {
287
+ return {
288
+ authorized: false,
289
+ reason: "Script execution is disabled by default. Requires explicit user grant."
290
+ };
291
+ }
292
+ const currentHash = sha256(fs2.readFileSync(resolved));
293
+ if (currentHash !== record.hash) {
294
+ delete this.grants[resolved];
295
+ if (options.pluginId) {
296
+ delete this.grants[`plugin:${options.pluginId}:${options.relPath || path3.basename(scriptPath)}`];
297
+ }
298
+ this._save();
299
+ return {
300
+ authorized: false,
301
+ reason: "Script content has been modified since grant was issued. Grant invalidated."
302
+ };
303
+ }
304
+ return { authorized: true, reason: "Authorized" };
305
+ }
306
+ };
307
+
308
+ // src/plugins/core/pinning.ts
309
+ var crypto2 = __toESM(require("node:crypto"), 1);
310
+ var EXACT_COMMIT_SHA = /^[0-9a-f]{40}$/i;
311
+ var EXACT_SEMVER = /^\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?(?:\+[0-9A-Za-z.-]+)?$/;
312
+ function validatePluginPinning(sourceSpec = { type: "" }, options = {}) {
313
+ if (!sourceSpec || typeof sourceSpec !== "object" || !sourceSpec.type) {
314
+ return {
315
+ valid: false,
316
+ code: THREAT_CODES.UNKNOWN_SOURCE_TYPE,
317
+ error: "Missing or invalid plugin source specification"
318
+ };
319
+ }
320
+ const { type } = sourceSpec;
321
+ const allowFloating = options.allowFloating || false;
322
+ if (type === "github") {
323
+ const commit = sourceSpec.commit;
324
+ if (!commit || !EXACT_COMMIT_SHA.test(commit)) {
325
+ if (!allowFloating) {
326
+ return {
327
+ valid: false,
328
+ code: THREAT_CODES.FLOATING_SOURCE_BLOCKED,
329
+ error: "GitHub plugin source must be pinned to an exact 40-character commit SHA. Floating branch or tag is prohibited without --allow-floating."
330
+ };
331
+ }
332
+ }
333
+ } else if (type === "npm") {
334
+ const version = sourceSpec.version;
335
+ const integrity = sourceSpec.integrity;
336
+ if (!version || version === "latest" || version.startsWith("^") || version.startsWith("~") || version.includes(">") || version.includes("<") || version.includes("*") || !EXACT_SEMVER.test(version)) {
337
+ return {
338
+ valid: false,
339
+ code: THREAT_CODES.IMPLICIT_LATEST_BLOCKED,
340
+ error: 'npm plugin source must be pinned to an exact version (e.g. "1.2.3"). Ranges and "latest" are prohibited.'
341
+ };
342
+ }
343
+ if (!integrity || !integrity.startsWith("sha512-")) {
344
+ return {
345
+ valid: false,
346
+ code: THREAT_CODES.MISSING_INTEGRITY,
347
+ error: "npm plugin source requires dist.integrity verification (sha512-...)."
348
+ };
349
+ }
350
+ } else {
351
+ return {
352
+ valid: false,
353
+ code: THREAT_CODES.UNKNOWN_SOURCE_TYPE,
354
+ error: `Unknown or unsupported plugin source type: "${type}". Only "github" and "npm" are permitted.`
355
+ };
356
+ }
357
+ return { valid: true };
358
+ }
359
+ function verifyNpmTarballIntegrity(tarballBuffer, expectedIntegrity) {
360
+ if (!expectedIntegrity.startsWith("sha512-")) {
361
+ return false;
362
+ }
363
+ const expectedHash = expectedIntegrity.slice("sha512-".length);
364
+ const computedHash = crypto2.createHash("sha512").update(tarballBuffer).digest("base64");
365
+ const bufA = Buffer.from(computedHash, "utf8");
366
+ const bufB = Buffer.from(expectedHash, "utf8");
367
+ if (bufA.length !== bufB.length) {
368
+ return false;
369
+ }
370
+ return crypto2.timingSafeEqual(bufA, bufB);
371
+ }
372
+
373
+ // src/plugins/core/updater.ts
374
+ var fs3 = __toESM(require("node:fs"), 1);
375
+ var path4 = __toESM(require("node:path"), 1);
376
+ var AtomicPluginUpdater = class _AtomicPluginUpdater {
377
+ /**
378
+ * Checks if local plugin has been modified since it was installed/recorded in lockfile.
379
+ */
380
+ static isModifiedLocally(pluginDir, expectedTreeDigest) {
381
+ if (!fs3.existsSync(pluginDir)) return false;
382
+ const current = calculateTreeDigest(pluginDir);
383
+ return current.treeDigest !== expectedTreeDigest;
384
+ }
385
+ /**
386
+ * Atomically installs or updates a plugin directory with rollback.
387
+ * Rejects updates when local uncommitted user modifications exist unless forced.
388
+ */
389
+ static applyUpdate(targetDir, stagedDir, options = {}) {
390
+ const { expectedOldTreeDigest, force = false } = options;
391
+ const resolvedTarget = path4.resolve(targetDir);
392
+ const resolvedStaged = path4.resolve(stagedDir);
393
+ if (fs3.existsSync(resolvedTarget) && expectedOldTreeDigest && !force) {
394
+ if (_AtomicPluginUpdater.isModifiedLocally(resolvedTarget, expectedOldTreeDigest)) {
395
+ const err = new Error(
396
+ `Plugin in "${resolvedTarget}" has local modifications. Update aborted to prevent overwriting user changes. Pass --force to overwrite.`
397
+ );
398
+ err.code = THREAT_CODES.MODIFIED_LOCALLY;
399
+ throw err;
400
+ }
401
+ }
402
+ const backupDir = `${resolvedTarget}.bak-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
403
+ let hasBackup = false;
404
+ try {
405
+ if (fs3.existsSync(resolvedTarget)) {
406
+ fs3.renameSync(resolvedTarget, backupDir);
407
+ hasBackup = true;
408
+ }
409
+ fs3.renameSync(resolvedStaged, resolvedTarget);
410
+ const digest = calculateTreeDigest(resolvedTarget);
411
+ if (hasBackup) {
412
+ fs3.rmSync(backupDir, { recursive: true, force: true });
413
+ }
414
+ return { success: true, treeDigest: digest.treeDigest };
415
+ } catch (err) {
416
+ if (hasBackup && !fs3.existsSync(resolvedTarget)) {
417
+ try {
418
+ fs3.renameSync(backupDir, resolvedTarget);
419
+ } catch {
420
+ }
421
+ }
422
+ throw err;
423
+ }
424
+ }
425
+ };
426
+ // Annotate the CommonJS export names for ESM import in node:
427
+ 0 && (module.exports = {
428
+ AtomicPluginUpdater,
429
+ ScriptGrantManager,
430
+ THREAT_CODES,
431
+ calculateTreeDigest,
432
+ sha256,
433
+ validateArchiveEntry,
434
+ validatePluginPinning,
435
+ verifyNpmTarballIntegrity
436
+ });
@@ -17,15 +17,26 @@ const fs = require('fs');
17
17
  const path = require('path');
18
18
  const { collectAllSkillDirs } = require('./plugins.js');
19
19
 
20
- // ── Paths ─────────────────────────────────────────────────────────────────────
21
20
  const ROOT = process.cwd();
22
21
  const AGENTS_DIR = path.join(ROOT, '.agents');
23
22
  const CORE_SKILLS = path.join(AGENTS_DIR, 'core', 'skills');
23
+ const CORE_PROFILES = path.join(AGENTS_DIR, 'core', 'profiles');
24
24
  const GENERATED = path.join(AGENTS_DIR, 'generated');
25
25
 
26
26
  // Adapters that compile to generated/<name>/skills/
27
27
  const COMPILED_ADAPTERS = ['gemini', 'claude'];
28
28
 
29
+ // Well-known external frameworks/tools valid in conflicts/optional/profiles but not internal ContextOS skills
30
+ const EXTERNAL_NAMES = new Set([
31
+ 'vue', 'angular', 'svelte', 'remix', 'express', 'koa', 'hapi', 'sails',
32
+ 'tailwind', 'prisma', 'drizzle', 'mongoose', 'sequelize', 'typeorm',
33
+ 'next-auth', 'react-query', 'zustand', 'redux', 'mobx', 'jotai', 'valtio',
34
+ 'vitest', 'jest', 'mocha', 'cypress', 'playwright', 'storybook',
35
+ 'graphql', 'trpc', 'apollo', 'relay', 'urql',
36
+ 'sqlite', 'simple-auth', 'kubernetes', 'monitoring', 'cicd', 'cqrs',
37
+ 'redis', 'postgres', 'postgresql', 'jwt', 'auth'
38
+ ]);
39
+
29
40
  // ── Tiny ANSI helpers (no deps) ───────────────────────────────────────────────
30
41
  const NO_COLOR = process.env.NO_COLOR || !process.stdout.isTTY;
31
42
  const c = {
@@ -68,7 +79,7 @@ function yamlList(text, field) {
68
79
  const re = new RegExp(`^${field}:\\s*\\[([^\\]]*)]`, 'm');
69
80
  const m = text.match(re);
70
81
  if (!m || !m[1].trim()) return [];
71
- return m[1].split(',').map(s => s.trim()).filter(Boolean);
82
+ return m[1].split(',').map(s => s.replace(/\s*#.*$/, '').trim()).filter(Boolean);
72
83
  }
73
84
 
74
85
  /**
@@ -83,7 +94,7 @@ function yamlBlockList(text, field) {
83
94
  if (!m) return [];
84
95
  return m[1]
85
96
  .split('\n')
86
- .map(l => l.replace(/^[ \t]+-\s*/, '').trim())
97
+ .map(l => l.replace(/^[ \t]+-\s*/, '').replace(/\s*#.*$/, '').trim())
87
98
  .filter(Boolean);
88
99
  }
89
100
 
@@ -102,6 +113,8 @@ function parseSkillYaml(yamlText) {
102
113
  name: yamlField(yamlText, 'name'),
103
114
  description: yamlField(yamlText, 'description'),
104
115
  version: yamlField(yamlText, 'version'),
116
+ type: yamlField(yamlText, 'type'),
117
+ resources: yamlList(yamlText, 'resources').concat(yamlBlockList(yamlText, 'resources')),
105
118
  requires: yamlList(yamlText, 'requires').concat(yamlBlockList(yamlText, 'requires')),
106
119
  conflicts: yamlList(yamlText, 'conflicts').concat(yamlBlockList(yamlText, 'conflicts')),
107
120
  optional: yamlList(yamlText, 'optional').concat(yamlBlockList(yamlText, 'optional')),
@@ -204,6 +217,12 @@ function checkSkillYaml(sourceSkills) {
204
217
  error(`[yaml] ${name}/skill.yaml — missing 'name:' field`);
205
218
  continue;
206
219
  }
220
+ const VALID_TYPES = new Set(['instruction-only', 'compiler', 'runtime', 'experimental']);
221
+ if (!parsed.type) {
222
+ error(`[yaml] ${name}/skill.yaml — missing 'type:' field (expected instruction-only | compiler | runtime | experimental)`);
223
+ } else if (!VALID_TYPES.has(parsed.type)) {
224
+ error(`[yaml] ${name}/skill.yaml — invalid type '${parsed.type}' (expected instruction-only | compiler | runtime | experimental)`);
225
+ }
207
226
  if (false && !parsed.description) {
208
227
  // Some skills use block scalars — allow it, just warn
209
228
  warn(`[yaml] ${name}/skill.yaml — 'description:' not found or uses multiline block (check manually)`);
@@ -284,16 +303,6 @@ function checkDependencies(sourceSkills) {
284
303
  }
285
304
  }
286
305
 
287
- // externalNames: well-known external frameworks/tools that are valid in
288
- // conflicts:/optional: but are NOT ContextOS skills. We never error on these.
289
- const EXTERNAL_NAMES = new Set([
290
- 'vue', 'angular', 'svelte', 'remix', 'express', 'koa', 'hapi', 'sails',
291
- 'tailwind', 'prisma', 'drizzle', 'mongoose', 'sequelize', 'typeorm',
292
- 'next-auth', 'react-query', 'zustand', 'redux', 'mobx', 'jotai', 'valtio',
293
- 'vitest', 'jest', 'mocha', 'cypress', 'playwright', 'storybook',
294
- 'graphql', 'trpc', 'apollo', 'relay', 'urql',
295
- ]);
296
-
297
306
  let depChecked = 0;
298
307
 
299
308
  for (const [name, skill] of Object.entries(sourceSkills)) {
@@ -466,6 +475,90 @@ function checkMcpBundleSync() {
466
475
  }
467
476
  }
468
477
 
478
+ // ═════════════════════════════════════════════════════════════════════════════
479
+ // CHECK 10 — Resources Manifest Integrity
480
+ // ═════════════════════════════════════════════════════════════════════════════
481
+ function checkResourcesManifest(sourceSkills) {
482
+ let totalResources = 0;
483
+ let skillsWithResources = 0;
484
+
485
+ for (const [name, skill] of Object.entries(sourceSkills)) {
486
+ if (!skill.hasYaml) continue;
487
+
488
+ const text = fs.readFileSync(skill.yamlPath, 'utf8');
489
+ const parsed = parseSkillYaml(text);
490
+
491
+ if (!parsed.resources || parsed.resources.length === 0) {
492
+ warn(`[resources] ${name}/skill.yaml — no resource files declared in manifest`);
493
+ continue;
494
+ }
495
+
496
+ skillsWithResources++;
497
+ for (const res of parsed.resources) {
498
+ const fullPath = path.join(skill.dir, res);
499
+ if (!fs.existsSync(fullPath)) {
500
+ error(`[resources] ${name}/skill.yaml — declared resource not found on disk: '${res}'`);
501
+ } else {
502
+ totalResources++;
503
+ }
504
+ }
505
+ }
506
+
507
+ info(`[resources] ${totalResources} resource files verified across ${skillsWithResources} skills`);
508
+ }
509
+
510
+ // ═════════════════════════════════════════════════════════════════════════════
511
+ // CHECK 11 — Profiles Integrity
512
+ // ═════════════════════════════════════════════════════════════════════════════
513
+ function checkProfilesIntegrity(sourceSkills) {
514
+ if (!fs.existsSync(CORE_PROFILES)) return;
515
+
516
+ const knownIds = new Set();
517
+ for (const [name, skill] of Object.entries(sourceSkills)) {
518
+ knownIds.add(name);
519
+ if (skill.hasYaml) {
520
+ const text = fs.readFileSync(skill.yamlPath, 'utf8');
521
+ const id = yamlField(text, 'id');
522
+ if (id) knownIds.add(id);
523
+ }
524
+ }
525
+
526
+ let profilesValidated = 0;
527
+ const files = fs.readdirSync(CORE_PROFILES).filter(f => f.endsWith('.yaml') || f.endsWith('.yml'));
528
+ const profiles = require('./profiles.js');
529
+ const mockRegistry = { skills: Object.fromEntries(Array.from(knownIds).map(id => [id, true])) };
530
+
531
+ for (const file of files) {
532
+ const filePath = path.join(CORE_PROFILES, file);
533
+ const text = fs.readFileSync(filePath, 'utf8');
534
+
535
+ try {
536
+ const parsed = profiles.parseYamlProfile(text);
537
+ profiles.validateProfile(parsed, mockRegistry);
538
+ } catch (err) {
539
+ error(`[profiles] ${file} — validation failed: ${err.message}`);
540
+ }
541
+
542
+ const referenced = [
543
+ ...yamlList(text, 'skills'),
544
+ ...yamlBlockList(text, 'skills'),
545
+ ...yamlList(text, 'prefer_skills'),
546
+ ...yamlBlockList(text, 'prefer_skills'),
547
+ ...yamlList(text, 'exclude_skills'),
548
+ ...yamlBlockList(text, 'exclude_skills'),
549
+ ];
550
+
551
+ for (const skillName of referenced) {
552
+ if (!knownIds.has(skillName) && !EXTERNAL_NAMES.has(skillName)) {
553
+ error(`[profiles] ${file} — references unknown skill '${skillName}'`);
554
+ }
555
+ }
556
+ profilesValidated++;
557
+ }
558
+
559
+ info(`[profiles] ${profilesValidated} core profiles validated against skill registry`);
560
+ }
561
+
469
562
  // ═════════════════════════════════════════════════════════════════════════════
470
563
  // REPORT
471
564
  // ═════════════════════════════════════════════════════════════════════════════
@@ -515,6 +608,39 @@ function printReport() {
515
608
  return errors.length === 0;
516
609
  }
517
610
 
611
+ // ═════════════════════════════════════════════════════════════════════════════
612
+ // CHECK 12 — Compiled Registry v2 Validation
613
+ // ═════════════════════════════════════════════════════════════════════════════
614
+ function checkRegistryV2() {
615
+ const { ManifestCompiler } = require('./compiler/manifest-compiler.js');
616
+ const compiler = new ManifestCompiler();
617
+ const res = compiler.compile();
618
+
619
+ if (!res.success) {
620
+ for (const d of res.diagnostics) {
621
+ error(`[registry-v2] ${d.file}: ${d.message} (${d.code})`);
622
+ }
623
+ return;
624
+ }
625
+
626
+ const compiledFile = path.join(AGENTS_DIR, 'compiled', 'registry.v2.json');
627
+ if (!fs.existsSync(compiledFile)) {
628
+ warn('[registry-v2] .agents/compiled/registry.v2.json does not exist (run: node .agents/ctx.js compile)');
629
+ return;
630
+ }
631
+
632
+ try {
633
+ const onDisk = JSON.parse(fs.readFileSync(compiledFile, 'utf8'));
634
+ if (onDisk.sourceGraphHash !== res.registry.sourceGraphHash) {
635
+ warn('[registry-v2] Compiled registry is stale (hash mismatch, run: node .agents/ctx.js compile)');
636
+ } else {
637
+ info(`[registry-v2] Compiled registry v2 verified (${Object.keys(res.registry.skills).length} skills, hash ${res.registry.sourceGraphHash.slice(0, 20)}...)`);
638
+ }
639
+ } catch (err) {
640
+ error(`[registry-v2] Corrupt registry.v2.json: ${err.message}`);
641
+ }
642
+ }
643
+
518
644
  // ═════════════════════════════════════════════════════════════════════════════
519
645
  // MAIN
520
646
  // ═════════════════════════════════════════════════════════════════════════════
@@ -539,7 +665,10 @@ function run() {
539
665
  checkContentQuality(sourceSkills);
540
666
  checkCostarHeaders(sourceSkills);
541
667
  checkValidationJson(sourceSkills);
542
- checkMcpBundleSync();
668
+ // checkMcpBundleSync();
669
+ checkResourcesManifest(sourceSkills);
670
+ checkProfilesIntegrity(sourceSkills);
671
+ checkRegistryV2();
543
672
 
544
673
  const passed = printReport();
545
674
  process.exit(passed ? 0 : 1);