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,963 @@
1
+ /**
2
+ * .agents/compiler/manifest-compiler.js
3
+ * ContextOS — Manifest Compiler & Registry v2 Generator
4
+ *
5
+ * Compiles skill manifests (v1 and v2) into a unified, deterministic,
6
+ * cryptographically verified registry (registry.v2.json) with:
7
+ * - Strict schema validation (fail-closed, additionalProperties: false)
8
+ * - Frontmatter parity enforcement between SKILL.md and manifest
9
+ * - Dependency closure, cycle detection, self-dependency and conflict validation
10
+ * - Resource tree verification & path traversal / symlink escape guards
11
+ * - SHA-256 content hashing (entrypointHash, resourceTreeHash, sourceGraphHash)
12
+ * - Standardized error contracts & SARIF 2.1.0 reporting
13
+ * - Zero install-time runtime dependencies (pure Node.js)
14
+ */
15
+
16
+ 'use strict';
17
+
18
+ const fs = require('fs');
19
+ const path = require('path');
20
+ const crypto = require('crypto');
21
+
22
+ // Standard error codes for manifest diagnostics
23
+ const CODES = {
24
+ PARSE_ERROR: 'CTX_MANIFEST_PARSE_ERROR',
25
+ SCHEMA_ERROR: 'CTX_MANIFEST_SCHEMA_ERROR',
26
+ UNKNOWN_DEPENDENCY: 'CTX_MANIFEST_UNKNOWN_DEPENDENCY',
27
+ CYCLE_DETECTED: 'CTX_MANIFEST_CYCLE_DETECTED',
28
+ SELF_DEPENDENCY: 'CTX_MANIFEST_SELF_DEPENDENCY',
29
+ CONFLICT_VIOLATION: 'CTX_MANIFEST_CONFLICT_VIOLATION',
30
+ FRONTMATTER_MISMATCH: 'CTX_MANIFEST_FRONTMATTER_MISMATCH',
31
+ MISSING_ENTRYPOINT: 'CTX_MANIFEST_MISSING_ENTRYPOINT',
32
+ MISSING_RESOURCE: 'CTX_MANIFEST_MISSING_RESOURCE',
33
+ INVALID_PATH: 'CTX_MANIFEST_INVALID_PATH',
34
+ DUPLICATE_ID: 'CTX_MANIFEST_DUPLICATE_ID',
35
+ DUPLICATE_ALIAS: 'CTX_MANIFEST_DUPLICATE_ALIAS',
36
+ MISSING_RULE_CHECKER: 'CTX_MANIFEST_MISSING_RULE_CHECKER',
37
+ INVALID_RULE: 'CTX_MANIFEST_INVALID_RULE',
38
+ };
39
+
40
+ // Default signals by skill ID (extracted from canonical resolver patterns for v1 backward compatibility)
41
+ const DEFAULT_SIGNALS = {
42
+ nextjs: {
43
+ aliases: ['next', 'next.js', 'nextjs'],
44
+ keywords: [
45
+ { value: 'next', weight: 40 },
46
+ { value: 'next.js', weight: 40 },
47
+ { value: 'app router', weight: 35 },
48
+ { value: 'server actions', weight: 30 },
49
+ { value: 'rsc', weight: 30 },
50
+ { value: 'некст', locale: 'ru', weight: 35 },
51
+ ],
52
+ fileGlobs: [
53
+ { value: 'app/**/*.{tsx,jsx,ts,js}', weight: 30 },
54
+ { value: '**/next.config.{js,mjs,ts}', weight: 35 },
55
+ ],
56
+ packages: [{ ecosystem: 'npm', name: 'next', weight: 35 }],
57
+ },
58
+ react: {
59
+ aliases: ['react', 'reactjs'],
60
+ keywords: [
61
+ { value: 'react', weight: 40 },
62
+ { value: 'useOptimistic', weight: 30 },
63
+ { value: 'component', weight: 20 },
64
+ { value: 'hooks', weight: 25 },
65
+ { value: 'компонент', locale: 'ru', weight: 30 },
66
+ { value: 'хук', locale: 'ru', weight: 30 },
67
+ ],
68
+ fileGlobs: [{ value: '**/*.{tsx,jsx}', weight: 25 }],
69
+ packages: [{ ecosystem: 'npm', name: 'react', weight: 35 }],
70
+ },
71
+ typescript: {
72
+ aliases: ['ts', 'typescript'],
73
+ keywords: [
74
+ { value: 'typescript', weight: 40 },
75
+ { value: 'type-safe', weight: 30 },
76
+ { value: 'generics', weight: 25 },
77
+ { value: 'tsconfig', weight: 30 },
78
+ { value: 'тайпскрипт', locale: 'ru', weight: 35 },
79
+ { value: 'типизац', locale: 'ru', weight: 30 },
80
+ ],
81
+ fileGlobs: [
82
+ { value: '**/*.tsx?', weight: 20 },
83
+ { value: '**/tsconfig.json', weight: 35 },
84
+ ],
85
+ packages: [{ ecosystem: 'npm', name: 'typescript', weight: 35 }],
86
+ },
87
+ security: {
88
+ aliases: ['sec', 'auth', 'security'],
89
+ keywords: [
90
+ { value: 'security', weight: 40 },
91
+ { value: 'auth', weight: 35 },
92
+ { value: 'jwt', weight: 30 },
93
+ { value: 'csrf', weight: 30 },
94
+ { value: 'xss', weight: 30 },
95
+ { value: 'безопасност', locale: 'ru', weight: 35 },
96
+ { value: 'авториз', locale: 'ru', weight: 30 },
97
+ { value: 'парол', locale: 'ru', weight: 30 },
98
+ ],
99
+ fileGlobs: [
100
+ { value: '**/*auth*', weight: 25 },
101
+ { value: '**/*security*', weight: 25 },
102
+ ],
103
+ packages: [],
104
+ },
105
+ database: {
106
+ aliases: ['db', 'database', 'sql'],
107
+ keywords: [
108
+ { value: 'database', weight: 40 },
109
+ { value: 'sql', weight: 35 },
110
+ { value: 'postgres', weight: 35 },
111
+ { value: 'prisma', weight: 35 },
112
+ { value: 'drizzle', weight: 35 },
113
+ { value: 'migration', weight: 30 },
114
+ { value: 'баз.*данн', locale: 'ru', weight: 35 },
115
+ { value: 'миграц', locale: 'ru', weight: 30 },
116
+ ],
117
+ fileGlobs: [
118
+ { value: '**/*.prisma', weight: 35 },
119
+ { value: '**/drizzle.config.*', weight: 35 },
120
+ { value: '**/migrations/**/*.sql', weight: 30 },
121
+ ],
122
+ packages: [
123
+ { ecosystem: 'npm', name: 'prisma', weight: 30 },
124
+ { ecosystem: 'npm', name: 'drizzle-orm', weight: 30 },
125
+ ],
126
+ },
127
+ testing: {
128
+ aliases: ['test', 'tests', 'testing'],
129
+ keywords: [
130
+ { value: 'vitest', weight: 40 },
131
+ { value: 'jest', weight: 40 },
132
+ { value: 'playwright', weight: 40 },
133
+ { value: 'tdd', weight: 35 },
134
+ { value: 'bdd', weight: 30 },
135
+ { value: 'тестирован', locale: 'ru', weight: 35 },
136
+ { value: 'юнит', locale: 'ru', weight: 30 },
137
+ ],
138
+ fileGlobs: [
139
+ { value: '**/*.{test,spec}.{ts,js,tsx,jsx}', weight: 35 },
140
+ { value: '**/vitest.config.*', weight: 35 },
141
+ { value: '**/playwright.config.*', weight: 35 },
142
+ ],
143
+ packages: [],
144
+ },
145
+ 'ui-ux-pro': {
146
+ aliases: ['ui', 'ux', 'ui-ux'],
147
+ keywords: [
148
+ { value: 'ui', weight: 35 },
149
+ { value: 'ux', weight: 35 },
150
+ { value: 'tailwind', weight: 35 },
151
+ { value: 'styling', weight: 30 },
152
+ { value: 'дизайн', locale: 'ru', weight: 35 },
153
+ { value: 'интерфейс', locale: 'ru', weight: 30 },
154
+ ],
155
+ fileGlobs: [
156
+ { value: '**/*.{css,scss,sass}', weight: 25 },
157
+ { value: '**/tailwind.config.*', weight: 35 },
158
+ ],
159
+ packages: [{ ecosystem: 'npm', name: 'tailwindcss', weight: 30 }],
160
+ },
161
+ node: {
162
+ aliases: ['nodejs', 'node'],
163
+ keywords: [
164
+ { value: 'node', weight: 35 },
165
+ { value: 'nodejs', weight: 35 },
166
+ { value: 'express', weight: 30 },
167
+ { value: 'fastify', weight: 30 },
168
+ ],
169
+ fileGlobs: [{ value: '**/package.json', weight: 15 }],
170
+ packages: [],
171
+ },
172
+ fastapi: {
173
+ aliases: ['fastapi'],
174
+ keywords: [
175
+ { value: 'fastapi', weight: 45 },
176
+ { value: 'pydantic', weight: 35 },
177
+ { value: 'uvicorn', weight: 30 },
178
+ ],
179
+ fileGlobs: [
180
+ { value: '**/main.py', weight: 20 },
181
+ { value: '**/requirements.txt', weight: 15 },
182
+ ],
183
+ packages: [{ ecosystem: 'pypi', name: 'fastapi', weight: 40 }],
184
+ },
185
+ nestjs: {
186
+ aliases: ['nestjs', 'nest'],
187
+ keywords: [
188
+ { value: 'nestjs', weight: 45 },
189
+ { value: 'nest.js', weight: 40 },
190
+ { value: 'injectable', weight: 25 },
191
+ ],
192
+ fileGlobs: [{ value: '**/nest-cli.json', weight: 40 }],
193
+ packages: [{ ecosystem: 'npm', name: '@nestjs/core', weight: 40 }],
194
+ },
195
+ docker: {
196
+ aliases: ['docker'],
197
+ keywords: [
198
+ { value: 'docker', weight: 45 },
199
+ { value: 'dockerfile', weight: 45 },
200
+ { value: 'compose', weight: 30 },
201
+ { value: 'докер', locale: 'ru', weight: 40 },
202
+ { value: 'container', weight: 5 },
203
+ { value: 'контейнер', locale: 'ru', weight: 5 },
204
+ ],
205
+ fileGlobs: [
206
+ { value: '**/Dockerfile*', weight: 40 },
207
+ { value: '**/docker-compose*.yml', weight: 40 },
208
+ ],
209
+ packages: [],
210
+ },
211
+ };
212
+
213
+ /**
214
+ * Diagnostic error object.
215
+ */
216
+ class DiagnosticError extends Error {
217
+ /**
218
+ * @param {Object} diag - Diagnostic payload
219
+ */
220
+ constructor(diag) {
221
+ super(diag.message);
222
+ this.name = 'DiagnosticError';
223
+ this.diag = diag;
224
+ }
225
+ }
226
+
227
+ const yaml = require('./vendor/yaml.js');
228
+
229
+ /**
230
+ * Robust zero-dep YAML parser for skill manifests.
231
+ * Handles scalars, inline arrays, block lists, nested maps, and quoted multiline strings.
232
+ */
233
+ function parseYaml(yamlText) {
234
+ if (typeof yamlText !== 'string' || !yamlText.trim()) return {};
235
+ const doc = yaml.parseDocument(yamlText, { merge: true, strict: true, uniqueKeys: true });
236
+ if (doc.errors && doc.errors.length > 0) {
237
+ throw new DiagnosticError({
238
+ message: `YAML Parse Error: ${doc.errors[0].message}`,
239
+ code: CODES.PARSE_ERROR
240
+ });
241
+ }
242
+ return doc.toJS() || {};
243
+ }
244
+
245
+ /**
246
+ * ManifestCompiler class.
247
+ */
248
+ class ManifestCompiler {
249
+ constructor(options = {}) {
250
+ this.rootDir = options.rootDir || process.cwd();
251
+ this.agentsDir = options.agentsDir || path.join(this.rootDir, '.agents');
252
+ this.coreSkillsDir = options.coreSkillsDir || path.join(this.agentsDir, 'core', 'skills');
253
+ this.compiledDir = options.compiledDir || path.join(this.agentsDir, 'compiled');
254
+ this.diagnostics = [];
255
+ }
256
+
257
+ addDiagnostic(code, message, options = {}) {
258
+ const diag = {
259
+ code,
260
+ severity: options.severity || 'error',
261
+ component: 'manifest-compiler',
262
+ file: options.file || '',
263
+ path: options.path || '',
264
+ line: options.line,
265
+ column: options.column,
266
+ message,
267
+ remediation: options.remediation || 'Correct the manifest according to the schema specification.',
268
+ };
269
+ this.diagnostics.push(diag);
270
+ return diag;
271
+ }
272
+
273
+ /**
274
+ * Reads and parses frontmatter from a markdown file.
275
+ */
276
+ readFrontmatter(filePath) {
277
+ if (!fs.existsSync(filePath)) return null;
278
+ const content = fs.readFileSync(filePath, 'utf8');
279
+ if (!content.startsWith('---')) return null;
280
+ const endIdx = content.indexOf('---', 3);
281
+ if (endIdx === -1) return { malformed: true };
282
+ const rawYaml = content.slice(3, endIdx).trim();
283
+ const parsed = parseYaml(rawYaml);
284
+ return {
285
+ raw: rawYaml,
286
+ parsed,
287
+ contentWithoutFrontmatter: content.slice(endIdx + 3).trim(),
288
+ };
289
+ }
290
+
291
+ /**
292
+ * Normalizes a v1 or v2 manifest into canonical SkillManifestV2 format.
293
+ */
294
+ normalizeManifest(skillDir, rawYamlText) {
295
+ const parsed = parseYaml(rawYamlText);
296
+ const skillId = parsed.id || parsed.name || path.basename(skillDir);
297
+ const displayName = parsed.displayName || parsed.name || skillId;
298
+ const isV2 = parsed.schemaVersion === 2;
299
+
300
+ const entrypoint = parsed.entrypoint || 'SKILL.md';
301
+ const version = parsed.version ? String(parsed.version) : '1.0.0';
302
+ const description = parsed.description || `ContextOS skill for ${displayName}`;
303
+ const type = parsed.type || 'instruction-only';
304
+ const category = parsed.category || 'general';
305
+
306
+ // Normalizing dependencies
307
+ const requires = Array.isArray(parsed.dependencies?.requires)
308
+ ? parsed.dependencies.requires
309
+ : (Array.isArray(parsed.requires) ? parsed.requires : []);
310
+ const optional = Array.isArray(parsed.dependencies?.optional)
311
+ ? parsed.dependencies.optional
312
+ : (Array.isArray(parsed.optional) ? parsed.optional : []);
313
+ const conflicts = Array.isArray(parsed.dependencies?.conflicts)
314
+ ? parsed.dependencies.conflicts
315
+ : (Array.isArray(parsed.conflicts) ? parsed.conflicts : []);
316
+
317
+ // Read SKILL.md frontmatter name if present to ensure alias parity
318
+ const discoveredAliases = [];
319
+ const entrypointFile = path.join(skillDir, entrypoint);
320
+ if (fs.existsSync(entrypointFile)) {
321
+ const fm = this.readFrontmatter(entrypointFile);
322
+ if (fm && fm.parsed && fm.parsed.name) {
323
+ const fmSlug = String(fm.parsed.name).trim().toLowerCase().replace(/\s+/g, '-');
324
+ discoveredAliases.push(fmSlug);
325
+ }
326
+ }
327
+
328
+ // Normalizing signals (merge provided signals with default signals for known skills)
329
+ const defaults = DEFAULT_SIGNALS[skillId] || {};
330
+ const signals = {
331
+ aliases: Array.from(new Set([
332
+ ...(parsed.signals?.aliases || []),
333
+ ...(defaults.aliases || []),
334
+ ...discoveredAliases,
335
+ skillId
336
+ ])),
337
+ keywords: parsed.signals?.keywords || defaults.keywords || [],
338
+ fileGlobs: parsed.signals?.fileGlobs || defaults.fileGlobs || [],
339
+ packages: parsed.signals?.packages || defaults.packages || [],
340
+ };
341
+
342
+ // Normalizing context
343
+ const priority = parsed.context?.priority !== undefined
344
+ ? parsed.context.priority
345
+ : (parsed.weight !== undefined ? parsed.weight * 10 : 50);
346
+
347
+ // Normalizing resources
348
+ let resources = [];
349
+ if (Array.isArray(parsed.resources)) {
350
+ resources = parsed.resources.map(r => {
351
+ if (typeof r === 'string') return { path: r, mode: 'on-demand' };
352
+ return { path: r.path, mode: r.mode || 'on-demand' };
353
+ });
354
+ }
355
+
356
+ const deprecated = Boolean(parsed.deprecated);
357
+ const canonical = typeof parsed.canonical === 'string' ? parsed.canonical : null;
358
+ const rules = Array.isArray(parsed.rules) ? parsed.rules : [];
359
+
360
+ return {
361
+ schemaVersion: 2,
362
+ id: skillId,
363
+ displayName,
364
+ version,
365
+ description,
366
+ type,
367
+ category,
368
+ entrypoint,
369
+ signals,
370
+ dependencies: {
371
+ requires: Array.from(new Set(requires)),
372
+ optional: Array.from(new Set(optional)),
373
+ conflicts: Array.from(new Set(conflicts)),
374
+ },
375
+ context: {
376
+ priority,
377
+ estimatedTokens: 0, // Calculated during compilation
378
+ },
379
+ resources,
380
+ deprecated,
381
+ canonical,
382
+ rules,
383
+ _raw: parsed,
384
+ _isV2: isV2,
385
+ };
386
+ }
387
+
388
+ /**
389
+ * Validates a single manifest against strict security, schema and filesystem rules.
390
+ */
391
+ validateSingleManifest(skillDir, manifest, manifestFile) {
392
+ const relManifestPath = path.relative(this.rootDir, manifestFile);
393
+
394
+ // 0. Strict Schema Validation (additionalProperties: false)
395
+ const allowedKeys = new Set([
396
+ 'schemaVersion', 'id', 'name', 'displayName', 'entrypoint', 'version',
397
+ 'description', 'type', 'category', 'dependencies', 'requires', 'optional',
398
+ 'conflicts', 'signals', 'context', 'weight', 'resources', 'deprecated',
399
+ 'canonical', 'rules'
400
+ ]);
401
+ if (manifest._raw) {
402
+ for (const key of Object.keys(manifest._raw)) {
403
+ if (!allowedKeys.has(key)) {
404
+ this.addDiagnostic(
405
+ CODES.SCHEMA_ERROR,
406
+ `Strict Schema Validation Failed: Unknown property '${key}' is not allowed in schemaVersion 2.`,
407
+ { file: relManifestPath, path: `/${key}` }
408
+ );
409
+ }
410
+ }
411
+ }
412
+
413
+ // 1. Check ID format
414
+ if (!manifest.id || !/^[a-z0-9-]+$/.test(manifest.id)) {
415
+ this.addDiagnostic(
416
+ CODES.SCHEMA_ERROR,
417
+ `Invalid skill id '${manifest.id}'. Must contain only lowercase alphanumeric characters and hyphens.`,
418
+ { file: relManifestPath, path: '/id' }
419
+ );
420
+ }
421
+
422
+ // 2. Check entrypoint on disk
423
+ if (manifest.entrypoint.includes('..') || manifest.entrypoint.startsWith('/') || manifest.entrypoint.startsWith('\\') || manifest.entrypoint.includes('\0')) {
424
+ this.addDiagnostic(
425
+ CODES.INVALID_PATH,
426
+ `Entrypoint path '${manifest.entrypoint}' contains invalid characters or directory traversal.`,
427
+ { file: relManifestPath, path: '/entrypoint' }
428
+ );
429
+ } else {
430
+ const fullEntrypoint = path.join(skillDir, manifest.entrypoint);
431
+ if (!fs.existsSync(fullEntrypoint)) {
432
+ this.addDiagnostic(
433
+ CODES.MISSING_ENTRYPOINT,
434
+ `Required entrypoint file '${manifest.entrypoint}' does not exist on disk.`,
435
+ { file: relManifestPath, path: '/entrypoint', remediation: `Create ${manifest.entrypoint} in ${path.relative(this.rootDir, skillDir)}` }
436
+ );
437
+ }
438
+ }
439
+
440
+ // 3. Frontmatter parity check with SKILL.md
441
+ const skillMdPath = path.join(skillDir, manifest.entrypoint);
442
+ if (fs.existsSync(skillMdPath)) {
443
+ const fm = this.readFrontmatter(skillMdPath);
444
+ if (fm && fm.parsed && fm.parsed.name) {
445
+ const fmName = String(fm.parsed.name).trim().toLowerCase();
446
+ const idMatches = manifest.id.toLowerCase() === fmName;
447
+ const displayNameMatches = manifest.displayName.toLowerCase() === fmName;
448
+ const aliasMatches = manifest.signals && Array.isArray(manifest.signals.aliases)
449
+ ? manifest.signals.aliases.some(a => a.toLowerCase() === fmName || a.toLowerCase() === fmName.replace(/\s+/g, '-'))
450
+ : false;
451
+
452
+ if (!idMatches && !displayNameMatches && !aliasMatches) {
453
+ this.addDiagnostic(
454
+ CODES.FRONTMATTER_MISMATCH,
455
+ `Frontmatter name '${fm.parsed.name}' in ${manifest.entrypoint} does not match manifest id '${manifest.id}', displayName '${manifest.displayName}', or registered aliases.`,
456
+ { file: relManifestPath, path: '/displayName', remediation: `Update ${manifest.entrypoint} frontmatter name to match manifest displayName '${manifest.displayName}' or add '${fm.parsed.name}' to aliases.` }
457
+ );
458
+ }
459
+ }
460
+ }
461
+
462
+ // 4. Resource paths validation
463
+ const realSkillDir = fs.realpathSync(skillDir);
464
+ for (let i = 0; i < manifest.resources.length; i++) {
465
+ const res = manifest.resources[i];
466
+ const resPath = res.path;
467
+ if (!resPath || resPath.includes('..') || path.isAbsolute(resPath) || resPath.includes('\0')) {
468
+ this.addDiagnostic(
469
+ CODES.INVALID_PATH,
470
+ `Resource path '${resPath}' is invalid or attempts path traversal.`,
471
+ { file: relManifestPath, path: `/resources/${i}/path` }
472
+ );
473
+ continue;
474
+ }
475
+
476
+ const fullResPath = path.join(skillDir, resPath);
477
+ if (!fs.existsSync(fullResPath)) {
478
+ this.addDiagnostic(
479
+ CODES.MISSING_RESOURCE,
480
+ `Resource file '${resPath}' listed in manifest does not exist.`,
481
+ { file: relManifestPath, path: `/resources/${i}/path`, remediation: `Create the file or remove it from resources.` }
482
+ );
483
+ } else {
484
+ // Symlink escape check
485
+ const realResPath = fs.realpathSync(fullResPath);
486
+ if (!realResPath.startsWith(realSkillDir)) {
487
+ this.addDiagnostic(
488
+ CODES.INVALID_PATH,
489
+ `Resource file '${resPath}' resolves outside skill directory (symlink escape).`,
490
+ { file: relManifestPath, path: `/resources/${i}/path` }
491
+ );
492
+ }
493
+ }
494
+ }
495
+
496
+ // 5. Check self-dependency
497
+ if (manifest.dependencies.requires.includes(manifest.id)) {
498
+ this.addDiagnostic(
499
+ CODES.SELF_DEPENDENCY,
500
+ `Skill '${manifest.id}' cannot require itself.`,
501
+ { file: relManifestPath, path: '/dependencies/requires' }
502
+ );
503
+ }
504
+
505
+ // 6. Validate declared rules and checkers
506
+ if (Array.isArray(manifest.rules)) {
507
+ const { AUTOMATED_CHECKERS } = require('../rules/rule-catalog.js');
508
+ for (let i = 0; i < manifest.rules.length; i++) {
509
+ const rule = manifest.rules[i];
510
+ if (!rule.id || !/^[A-Z0-9_-]+$/.test(rule.id)) {
511
+ this.addDiagnostic(
512
+ CODES.SCHEMA_ERROR,
513
+ `Rule [${i}] in '${manifest.id}' has invalid ID '${rule.id}'. Must match pattern ^[A-Z0-9_-]+$.`,
514
+ { file: relManifestPath, path: `/rules/${i}/id` }
515
+ );
516
+ }
517
+ if (!['must', 'should', 'may'].includes(rule.level)) {
518
+ this.addDiagnostic(
519
+ CODES.SCHEMA_ERROR,
520
+ `Rule '${rule.id}' has invalid level '${rule.level}'. Must be 'must', 'should', or 'may'.`,
521
+ { file: relManifestPath, path: `/rules/${i}/level` }
522
+ );
523
+ }
524
+ if (!['runtime', 'linter', 'prompt-guidance', 'reference', 'example'].includes(rule.enforcement)) {
525
+ this.addDiagnostic(
526
+ CODES.SCHEMA_ERROR,
527
+ `Rule '${rule.id}' has invalid enforcement '${rule.enforcement}'.`,
528
+ { file: relManifestPath, path: `/rules/${i}/enforcement` }
529
+ );
530
+ }
531
+ if (['runtime', 'linter'].includes(rule.enforcement)) {
532
+ if (!rule.checker) {
533
+ this.addDiagnostic(
534
+ CODES.MISSING_RULE_CHECKER,
535
+ `Rule '${rule.id}' marked enforcement '${rule.enforcement}' requires an automated checker, but none was provided.`,
536
+ { file: relManifestPath, path: `/rules/${i}/checker` }
537
+ );
538
+ } else if (!AUTOMATED_CHECKERS[rule.checker]) {
539
+ this.addDiagnostic(
540
+ CODES.MISSING_RULE_CHECKER,
541
+ `Rule '${rule.id}' references unknown automated checker '${rule.checker}'.`,
542
+ { file: relManifestPath, path: `/rules/${i}/checker` }
543
+ );
544
+ }
545
+ }
546
+ }
547
+ }
548
+ }
549
+
550
+ /**
551
+ * Validates cross-skill dependency graph (closure, cycles, conflicts).
552
+ */
553
+ validateDependencyGraph(manifestsById) {
554
+ const knownIds = new Set(Object.keys(manifestsById));
555
+
556
+ // Well-known external frameworks (not internal skills)
557
+ const EXTERNAL_NAMES = new Set([
558
+ 'vue', 'angular', 'svelte', 'remix', 'express', 'koa', 'hapi', 'sails',
559
+ 'tailwind', 'prisma', 'drizzle', 'mongoose', 'sequelize', 'typeorm',
560
+ 'next-auth', 'react-query', 'zustand', 'redux', 'mobx', 'jotai', 'valtio',
561
+ 'vitest', 'jest', 'mocha', 'cypress', 'playwright', 'storybook',
562
+ 'graphql', 'trpc', 'apollo', 'relay', 'urql',
563
+ 'sqlite', 'simple-auth', 'kubernetes', 'monitoring', 'cicd', 'cqrs',
564
+ 'redis', 'postgres', 'postgresql', 'jwt', 'auth'
565
+ ]);
566
+
567
+ // 1. Unknown dependencies & direct conflict violations
568
+ for (const [id, m] of Object.entries(manifestsById)) {
569
+ for (const req of m.dependencies.requires) {
570
+ if (!knownIds.has(req)) {
571
+ this.addDiagnostic(
572
+ CODES.UNKNOWN_DEPENDENCY,
573
+ `Skill '${id}' requires unknown skill '${req}'.`,
574
+ { file: m.source, path: '/dependencies/requires', remediation: `Ensure skill '${req}' is present in .agents/core/skills.` }
575
+ );
576
+ }
577
+
578
+ // Direct conflict violation
579
+ if (m.dependencies.conflicts.includes(req)) {
580
+ this.addDiagnostic(
581
+ CODES.CONFLICT_VIOLATION,
582
+ `Skill '${id}' both requires and conflicts with '${req}'.`,
583
+ { file: m.source, path: '/dependencies/conflicts' }
584
+ );
585
+ }
586
+
587
+ const reqManifest = manifestsById[req];
588
+ if (reqManifest && reqManifest.dependencies.conflicts.includes(id)) {
589
+ this.addDiagnostic(
590
+ CODES.CONFLICT_VIOLATION,
591
+ `Skill '${id}' requires '${req}', but '${req}' conflicts with '${id}'.`,
592
+ { file: m.source, path: '/dependencies/requires' }
593
+ );
594
+ }
595
+ }
596
+ }
597
+
598
+ // 2. Cycle detection via DFS
599
+ const visited = new Map(); // id -> 'unvisited' | 'visiting' | 'visited'
600
+ for (const id of knownIds) visited.set(id, 'unvisited');
601
+
602
+ const checkCycle = (curr, stack) => {
603
+ visited.set(curr, 'visiting');
604
+ stack.push(curr);
605
+
606
+ const m = manifestsById[curr];
607
+ if (m) {
608
+ for (const dep of m.dependencies.requires) {
609
+ if (!knownIds.has(dep)) continue;
610
+ const status = visited.get(dep);
611
+ if (status === 'visiting') {
612
+ const cyclePath = [...stack.slice(stack.indexOf(dep)), dep].join(' -> ');
613
+ this.addDiagnostic(
614
+ CODES.CYCLE_DETECTED,
615
+ `Dependency cycle detected: ${cyclePath}`,
616
+ { file: m.source, path: '/dependencies/requires' }
617
+ );
618
+ } else if (status === 'unvisited') {
619
+ checkCycle(dep, stack);
620
+ }
621
+ }
622
+ }
623
+
624
+ stack.pop();
625
+ visited.set(curr, 'visited');
626
+ };
627
+
628
+ for (const id of knownIds) {
629
+ if (visited.get(id) === 'unvisited') {
630
+ checkCycle(id, []);
631
+ }
632
+ }
633
+ }
634
+
635
+ /**
636
+ * Computes sha256 hash for a file.
637
+ */
638
+ hashFile(filePath) {
639
+ if (!fs.existsSync(filePath)) return null;
640
+ const content = fs.readFileSync(filePath);
641
+ return 'sha256:' + crypto.createHash('sha256').update(content).digest('hex');
642
+ }
643
+
644
+ /**
645
+ * Computes sha256 hash for a string.
646
+ */
647
+ hashString(str) {
648
+ return 'sha256:' + crypto.createHash('sha256').update(str, 'utf8').digest('hex');
649
+ }
650
+
651
+ /**
652
+ * Compiles all skills in coreSkillsDir and plugins.
653
+ * Generates deterministic CompiledRegistryV2 structure.
654
+ */
655
+ compile() {
656
+ this.diagnostics = [];
657
+ const manifestsById = {};
658
+ const skillDirs = [];
659
+
660
+ // 1. Discover skill directories
661
+ if (fs.existsSync(this.coreSkillsDir)) {
662
+ const entries = fs.readdirSync(this.coreSkillsDir, { withFileTypes: true });
663
+ for (const entry of entries) {
664
+ if (entry.isDirectory()) {
665
+ skillDirs.push(path.join(this.coreSkillsDir, entry.name));
666
+ }
667
+ }
668
+ }
669
+
670
+ // Also check plugins
671
+ const pluginsDir = path.join(this.agentsDir, 'plugins');
672
+ if (fs.existsSync(pluginsDir)) {
673
+ const pluginEntries = fs.readdirSync(pluginsDir, { withFileTypes: true });
674
+ for (const pe of pluginEntries) {
675
+ if (pe.isDirectory()) {
676
+ const pSkills = path.join(pluginsDir, pe.name, 'skills');
677
+ if (fs.existsSync(pSkills)) {
678
+ const subs = fs.readdirSync(pSkills, { withFileTypes: true });
679
+ for (const sub of subs) {
680
+ if (sub.isDirectory()) skillDirs.push(path.join(pSkills, sub.name));
681
+ }
682
+ }
683
+ }
684
+ }
685
+ }
686
+
687
+ // Sort skill directories for determinism
688
+ skillDirs.sort();
689
+
690
+ // 2. Parse and normalize manifests
691
+ for (const dir of skillDirs) {
692
+ const v2File = path.join(dir, 'skill.v2.yaml');
693
+ const v1File = path.join(dir, 'skill.yaml');
694
+ const manifestFile = fs.existsSync(v2File) ? v2File : (fs.existsSync(v1File) ? v1File : null);
695
+
696
+ if (!manifestFile) {
697
+ // Synthesize minimal manifest from directory name & SKILL.md
698
+ const id = path.basename(dir);
699
+ const norm = this.normalizeManifest(dir, `id: ${id}\nname: ${id}\n`);
700
+ norm.source = path.relative(this.rootDir, dir).replace(/\\/g, '/');
701
+ manifestsById[id] = norm;
702
+ continue;
703
+ }
704
+
705
+ try {
706
+ const rawYaml = fs.readFileSync(manifestFile, 'utf8');
707
+ const norm = this.normalizeManifest(dir, rawYaml);
708
+ norm.source = path.relative(this.rootDir, manifestFile).replace(/\\/g, '/');
709
+
710
+ if (manifestsById[norm.id]) {
711
+ this.addDiagnostic(
712
+ CODES.DUPLICATE_ID,
713
+ `Duplicate skill id '${norm.id}' found in ${norm.source}`,
714
+ { file: norm.source, path: '/id' }
715
+ );
716
+ }
717
+
718
+ manifestsById[norm.id] = norm;
719
+ this.validateSingleManifest(dir, norm, manifestFile);
720
+ } catch (err) {
721
+ this.addDiagnostic(
722
+ err.diag ? err.diag.code : CODES.PARSE_ERROR,
723
+ `Failed to parse manifest at ${path.relative(this.rootDir, manifestFile)}: ${err.message}`,
724
+ {
725
+ file: path.relative(this.rootDir, manifestFile),
726
+ line: err.diag ? err.diag.line : undefined,
727
+ column: err.diag ? err.diag.column : undefined
728
+ }
729
+ );
730
+ }
731
+ }
732
+
733
+ // 3. Cross-skill dependency graph validation
734
+ this.validateDependencyGraph(manifestsById);
735
+
736
+ // If any errors exist, stop and return diagnostics
737
+ const hasErrors = this.diagnostics.some(d => d.severity === 'error');
738
+ if (hasErrors) {
739
+ return {
740
+ success: false,
741
+ diagnostics: this.diagnostics,
742
+ registry: null,
743
+ };
744
+ }
745
+
746
+ // 4. Compute hashes, estimated tokens, aliases and packageMap
747
+ const compiledSkills = {};
748
+ const aliases = {};
749
+ const deprecatedAliases = {};
750
+ const packageMap = {};
751
+ const dependencyGraph = {};
752
+ const rules = {};
753
+
754
+ const sortedIds = Object.keys(manifestsById).sort();
755
+
756
+ for (const id of sortedIds) {
757
+ const m = manifestsById[id];
758
+ const dir = path.join(this.rootDir, path.dirname(m.source));
759
+ const entrypointFile = path.join(dir, m.entrypoint);
760
+
761
+ // Entrypoint hash
762
+ const entrypointHash = this.hashFile(entrypointFile) || 'sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855';
763
+
764
+ // Estimated tokens: entrypoint character length / 3.8
765
+ let estimatedTokens = 1000;
766
+ if (fs.existsSync(entrypointFile)) {
767
+ const chars = fs.readFileSync(entrypointFile, 'utf8').length;
768
+ estimatedTokens = Math.max(100, Math.ceil(chars / 3.8));
769
+ }
770
+
771
+ // Resource tree hash
772
+ const resHashes = [];
773
+ for (const res of m.resources) {
774
+ const rFile = path.join(dir, res.path);
775
+ const rHash = this.hashFile(rFile);
776
+ if (rHash) resHashes.push(`${res.path}:${rHash}`);
777
+ }
778
+ resHashes.sort();
779
+ const resourceTreeHash = this.hashString(resHashes.join('\n'));
780
+
781
+ compiledSkills[id] = {
782
+ id: m.id,
783
+ displayName: m.displayName,
784
+ version: m.version,
785
+ description: m.description,
786
+ category: m.category,
787
+ type: m.type,
788
+ entrypoint: m.entrypoint,
789
+ entrypointHash,
790
+ resourceTreeHash,
791
+ estimatedTokens,
792
+ source: m.source,
793
+ signals: {
794
+ aliases: m.signals.aliases.sort(),
795
+ keywords: m.signals.keywords,
796
+ fileGlobs: m.signals.fileGlobs,
797
+ packages: m.signals.packages,
798
+ },
799
+ dependencies: {
800
+ requires: m.dependencies.requires.sort(),
801
+ optional: m.dependencies.optional.sort(),
802
+ conflicts: m.dependencies.conflicts.sort(),
803
+ },
804
+ context: {
805
+ priority: m.context.priority,
806
+ estimatedTokens,
807
+ },
808
+ resources: m.resources,
809
+ deprecated: m.deprecated || false,
810
+ canonical: m.canonical || null,
811
+ rules: m.rules || [],
812
+ };
813
+
814
+ // Register deprecated alias mapping
815
+ if (m.deprecated && m.canonical) {
816
+ deprecatedAliases[id] = m.canonical;
817
+ }
818
+
819
+ // Register rules
820
+ if (Array.isArray(m.rules)) {
821
+ for (const r of m.rules) {
822
+ rules[r.id] = {
823
+ ...r,
824
+ sourceSkill: id,
825
+ };
826
+ }
827
+ }
828
+
829
+ // Register aliases
830
+ for (const alias of m.signals.aliases) {
831
+ if (!aliases[alias]) {
832
+ aliases[alias] = id;
833
+ }
834
+ }
835
+
836
+ // Register packageMap
837
+ for (const pkg of m.signals.packages) {
838
+ packageMap[`${pkg.ecosystem}:${pkg.name}`] = id;
839
+ }
840
+
841
+ // Register dependencyGraph
842
+ dependencyGraph[id] = m.dependencies.requires.sort();
843
+ }
844
+
845
+ // Overall sourceGraphHash
846
+ const sourceGraphHash = this.hashString(JSON.stringify({
847
+ skills: compiledSkills,
848
+ dependencyGraph,
849
+ }));
850
+
851
+ const registry = {
852
+ schemaVersion: 2,
853
+ compilerVersion: '2.0.0',
854
+ sourceGraphHash,
855
+ skills: compiledSkills,
856
+ aliases: sortObjectKeys(aliases),
857
+ deprecatedAliases: sortObjectKeys(deprecatedAliases),
858
+ packageMap: sortObjectKeys(packageMap),
859
+ dependencyGraph: sortObjectKeys(dependencyGraph),
860
+ rules: sortObjectKeys(rules),
861
+ };
862
+
863
+ return {
864
+ success: true,
865
+ diagnostics: this.diagnostics,
866
+ registry,
867
+ };
868
+ }
869
+
870
+ /**
871
+ * Compiles and writes .agents/compiled/registry.v2.json and .agents/compiled/registry.v2.sha256.
872
+ */
873
+ compileAndWrite() {
874
+ const result = this.compile();
875
+ if (!result.success) {
876
+ return result;
877
+ }
878
+
879
+ if (!fs.existsSync(this.compiledDir)) {
880
+ fs.mkdirSync(this.compiledDir, { recursive: true });
881
+ }
882
+
883
+ const registryJsonPath = path.join(this.compiledDir, 'registry.v2.json');
884
+ const shaPath = path.join(this.compiledDir, 'registry.v2.sha256');
885
+
886
+ const jsonString = JSON.stringify(result.registry, null, 2) + '\n';
887
+ fs.writeFileSync(registryJsonPath, jsonString, 'utf8');
888
+
889
+ const shaContent = result.registry.sourceGraphHash + ' registry.v2.json\n';
890
+ fs.writeFileSync(shaPath, shaContent, 'utf8');
891
+
892
+ return {
893
+ ...result,
894
+ registryJsonPath,
895
+ shaPath,
896
+ };
897
+ }
898
+
899
+ /**
900
+ * Formats diagnostics as SARIF 2.1.0 output.
901
+ */
902
+ formatSarif() {
903
+ const rules = [];
904
+ const results = [];
905
+
906
+ const ruleIds = new Set(this.diagnostics.map(d => d.code));
907
+ for (const code of ruleIds) {
908
+ rules.push({
909
+ id: code,
910
+ name: code,
911
+ shortDescription: { text: `ContextOS Manifest Rule ${code}` },
912
+ });
913
+ }
914
+
915
+ for (const d of this.diagnostics) {
916
+ results.push({
917
+ ruleId: d.code,
918
+ level: d.severity === 'error' ? 'error' : 'warning',
919
+ message: { text: d.message },
920
+ locations: [
921
+ {
922
+ physicalLocation: {
923
+ artifactLocation: { uri: d.file.replace(/\\/g, '/') },
924
+ ...(d.line ? { region: { startLine: d.line, ...(d.column ? { startColumn: d.column } : {}) } } : {})
925
+ },
926
+ },
927
+ ],
928
+ });
929
+ }
930
+
931
+ return {
932
+ $schema: 'https://raw.githubusercontent.com/oasis-tcs/sarif-spec/master/Schemata/sarif-schema-2.1.0.json',
933
+ version: '2.1.0',
934
+ runs: [
935
+ {
936
+ tool: {
937
+ driver: {
938
+ name: 'contextos-manifest-compiler',
939
+ version: '2.0.0',
940
+ rules,
941
+ },
942
+ },
943
+ results,
944
+ },
945
+ ],
946
+ };
947
+ }
948
+ }
949
+
950
+ function sortObjectKeys(obj) {
951
+ const sorted = {};
952
+ for (const k of Object.keys(obj).sort()) {
953
+ sorted[k] = obj[k];
954
+ }
955
+ return sorted;
956
+ }
957
+
958
+ module.exports = {
959
+ ManifestCompiler,
960
+ DiagnosticError,
961
+ CODES,
962
+ parseYaml,
963
+ };