contextos-agents 1.7.0 → 2.0.0-beta.3

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 (313) hide show
  1. package/.agents/AGENTS.md +16 -50
  2. package/.agents/adapters/aider/export.js +117 -99
  3. package/.agents/adapters/claude/export.js +68 -26
  4. package/.agents/adapters/copilot/export.js +90 -53
  5. package/.agents/adapters/cursor/export.js +100 -104
  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 +104 -96
  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/skill.yaml +3 -5
  18. package/.agents/core/skills/context-os/SKILL.md +3 -6
  19. package/.agents/core/skills/context-os/skill.yaml +3 -8
  20. package/.agents/core/skills/engineering-workflow/skill.yaml +1 -7
  21. package/.agents/core/skills/gemini-precision/skill.yaml +1 -6
  22. package/.agents/core/skills/gstack-roles/skill.yaml +3 -6
  23. package/.agents/core/skills/ponytail-mindset/skill.yaml +1 -7
  24. package/.agents/core/skills/security/skill.yaml +15 -3
  25. package/.agents/ctx.js +537 -112
  26. package/.agents/customization-dx.js +282 -0
  27. package/.agents/doctor.js +855 -66
  28. package/.agents/filesystem/index.js +71 -0
  29. package/.agents/filesystem/journaled-transaction.js +451 -0
  30. package/.agents/filesystem/lockfile-v2.js +275 -0
  31. package/.agents/filesystem/platform-hardening.js +222 -0
  32. package/.agents/filesystem/project-lock.js +218 -0
  33. package/.agents/filesystem/safe-path.js +256 -0
  34. package/.agents/generated/claude/skills/context-os/SKILL.md +1 -1
  35. package/.agents/generated/gemini/skills/context-os/SKILL.md +2 -2
  36. package/.agents/plugins/contextos/plugin.json +1 -1
  37. package/.agents/plugins.js +278 -64
  38. package/.agents/profiles.js +486 -51
  39. package/.agents/resolver/canonical-resolver.js +1348 -0
  40. package/.agents/resolver.js +50 -534
  41. package/.agents/rules/rule-catalog.js +525 -0
  42. package/.agents/schemas/attestation.review.v1.json +111 -0
  43. package/.agents/schemas/attestation.verification.v1.json +85 -0
  44. package/.agents/schemas/lockfile.v2.schema.json +134 -0
  45. package/.agents/schemas/profile.v2.schema.json +114 -0
  46. package/.agents/schemas/runtime.thread.v1.json +192 -0
  47. package/.agents/schemas/skill.manifest.v2.json +177 -0
  48. package/.agents/schemas/verification.spec.v1.json +39 -0
  49. package/.agents/schemas/workspace.graph.schema.json +106 -0
  50. package/.agents/skills-index.json +6 -166
  51. package/.agents/stats.js +9 -9
  52. package/.agents/transaction-core/event-store.js +288 -0
  53. package/.agents/transaction-core/idempotency.js +129 -0
  54. package/.agents/transaction-core/ipc-lock.js +311 -0
  55. package/.agents/transaction-core/plugin-supply-chain-bundle.js +436 -0
  56. package/.agents/validate.js +44 -1
  57. package/.agents/watch.js +354 -102
  58. package/.agents/workspace/workspace-graph.js +778 -0
  59. package/README.md +59 -387
  60. package/benchmarks/v2/analysis/statistics.js +140 -0
  61. package/benchmarks/v2/analysis/stats.js +69 -0
  62. package/benchmarks/v2/arms/arm-definitions.js +79 -0
  63. package/benchmarks/v2/dataset.schema.json +34 -0
  64. package/benchmarks/v2/evaluators/index.js +25 -0
  65. package/benchmarks/v2/evaluators/verified-success.js +116 -0
  66. package/benchmarks/v2/harness/runner.js +88 -0
  67. package/benchmarks/v2/pilot-tasks.json +392 -0
  68. package/bin/commands/recover.js +88 -0
  69. package/bin/commands/update.js +80 -17
  70. package/bin/commands.js +62 -25
  71. package/bin/index.js +138 -81
  72. package/bin/lib/lockfile.js +5 -3
  73. package/bin/lib/safe-writer.js +34 -3
  74. package/package.json +87 -72
  75. package/registry.json +2 -2
  76. package/registry.v2.schema.json +86 -0
  77. package/.agents/core/profiles/backend.yaml +0 -47
  78. package/.agents/core/profiles/enterprise.yaml +0 -46
  79. package/.agents/core/profiles/frontend.yaml +0 -46
  80. package/.agents/core/profiles/hackathon.yaml +0 -45
  81. package/.agents/core/profiles/mvp.yaml +0 -44
  82. package/.agents/core/profiles/startup.yaml +0 -48
  83. package/.agents/core/skills/adapters/EXAMPLES.md +0 -19
  84. package/.agents/core/skills/adapters/SKILL.md +0 -105
  85. package/.agents/core/skills/adapters/TROUBLESHOOTING.md +0 -7
  86. package/.agents/core/skills/adapters/VALIDATION.json +0 -12
  87. package/.agents/core/skills/adapters/skill.yaml +0 -16
  88. package/.agents/core/skills/architecture-diagrams/SKILL.md +0 -108
  89. package/.agents/core/skills/architecture-diagrams/VALIDATION.json +0 -12
  90. package/.agents/core/skills/architecture-diagrams/skill.yaml +0 -12
  91. package/.agents/core/skills/brutalist-design/SKILL.md +0 -150
  92. package/.agents/core/skills/brutalist-design/VALIDATION.json +0 -12
  93. package/.agents/core/skills/brutalist-design/skill.yaml +0 -12
  94. package/.agents/core/skills/database/EXAMPLES.md +0 -74
  95. package/.agents/core/skills/database/SKILL.md +0 -101
  96. package/.agents/core/skills/database/TROUBLESHOOTING.md +0 -18
  97. package/.agents/core/skills/database/VALIDATION.json +0 -11
  98. package/.agents/core/skills/database/skill.yaml +0 -31
  99. package/.agents/core/skills/ddd/EXAMPLES.md +0 -42
  100. package/.agents/core/skills/ddd/SKILL.md +0 -247
  101. package/.agents/core/skills/ddd/TROUBLESHOOTING.md +0 -19
  102. package/.agents/core/skills/ddd/VALIDATION.json +0 -12
  103. package/.agents/core/skills/ddd/ddd.md +0 -178
  104. package/.agents/core/skills/ddd/skill.yaml +0 -17
  105. package/.agents/core/skills/decisions/EXAMPLES.md +0 -35
  106. package/.agents/core/skills/decisions/SKILL.md +0 -90
  107. package/.agents/core/skills/decisions/TROUBLESHOOTING.md +0 -13
  108. package/.agents/core/skills/decisions/VALIDATION.json +0 -12
  109. package/.agents/core/skills/decisions/skill.yaml +0 -16
  110. package/.agents/core/skills/docker/EXAMPLES.md +0 -56
  111. package/.agents/core/skills/docker/SKILL.md +0 -63
  112. package/.agents/core/skills/docker/TROUBLESHOOTING.md +0 -18
  113. package/.agents/core/skills/docker/VALIDATION.json +0 -11
  114. package/.agents/core/skills/docker/skill.yaml +0 -29
  115. package/.agents/core/skills/fastapi/EXAMPLES.md +0 -36
  116. package/.agents/core/skills/fastapi/SKILL.md +0 -148
  117. package/.agents/core/skills/fastapi/TROUBLESHOOTING.md +0 -19
  118. package/.agents/core/skills/fastapi/VALIDATION.json +0 -12
  119. package/.agents/core/skills/fastapi/fastapi.md +0 -112
  120. package/.agents/core/skills/fastapi/skill.yaml +0 -17
  121. package/.agents/core/skills/generators/EXAMPLES.md +0 -19
  122. package/.agents/core/skills/generators/SKILL.md +0 -112
  123. package/.agents/core/skills/generators/TROUBLESHOOTING.md +0 -7
  124. package/.agents/core/skills/generators/VALIDATION.json +0 -12
  125. package/.agents/core/skills/generators/skill.yaml +0 -25
  126. package/.agents/core/skills/generators/templates/API.md +0 -77
  127. package/.agents/core/skills/generators/templates/ARCHITECTURE.md +0 -70
  128. package/.agents/core/skills/generators/templates/DATABASE.md +0 -42
  129. package/.agents/core/skills/generators/templates/DECISION.md +0 -46
  130. package/.agents/core/skills/generators/templates/PRD.md +0 -67
  131. package/.agents/core/skills/generators/templates/PROJECT_GRAPH.md +0 -56
  132. package/.agents/core/skills/generators/templates/ROADMAP.md +0 -51
  133. package/.agents/core/skills/generators/templates/TASKS.md +0 -43
  134. package/.agents/core/skills/generators/templates/UI.md +0 -73
  135. package/.agents/core/skills/graphify/EXAMPLES.md +0 -73
  136. package/.agents/core/skills/graphify/SKILL.md +0 -130
  137. package/.agents/core/skills/graphify/VALIDATION.json +0 -12
  138. package/.agents/core/skills/graphify/skill.yaml +0 -18
  139. package/.agents/core/skills/impeccable-design/EXAMPLES.md +0 -26
  140. package/.agents/core/skills/impeccable-design/SKILL.md +0 -201
  141. package/.agents/core/skills/impeccable-design/TROUBLESHOOTING.md +0 -19
  142. package/.agents/core/skills/impeccable-design/VALIDATION.json +0 -12
  143. package/.agents/core/skills/impeccable-design/skill.yaml +0 -20
  144. package/.agents/core/skills/interview-me/SKILL.md +0 -97
  145. package/.agents/core/skills/interview-me/VALIDATION.json +0 -12
  146. package/.agents/core/skills/interview-me/skill.yaml +0 -12
  147. package/.agents/core/skills/microservices/EXAMPLES.md +0 -38
  148. package/.agents/core/skills/microservices/SKILL.md +0 -164
  149. package/.agents/core/skills/microservices/TROUBLESHOOTING.md +0 -19
  150. package/.agents/core/skills/microservices/VALIDATION.json +0 -12
  151. package/.agents/core/skills/microservices/microservices.md +0 -119
  152. package/.agents/core/skills/microservices/skill.yaml +0 -17
  153. package/.agents/core/skills/minimalist-design/SKILL.md +0 -113
  154. package/.agents/core/skills/minimalist-design/VALIDATION.json +0 -12
  155. package/.agents/core/skills/minimalist-design/skill.yaml +0 -12
  156. package/.agents/core/skills/nestjs/EXAMPLES.md +0 -40
  157. package/.agents/core/skills/nestjs/SKILL.md +0 -139
  158. package/.agents/core/skills/nestjs/TROUBLESHOOTING.md +0 -19
  159. package/.agents/core/skills/nestjs/VALIDATION.json +0 -12
  160. package/.agents/core/skills/nestjs/nestjs.md +0 -103
  161. package/.agents/core/skills/nestjs/skill.yaml +0 -17
  162. package/.agents/core/skills/nextjs/EXAMPLES.md +0 -40
  163. package/.agents/core/skills/nextjs/SKILL.md +0 -163
  164. package/.agents/core/skills/nextjs/TROUBLESHOOTING.md +0 -19
  165. package/.agents/core/skills/nextjs/VALIDATION.json +0 -12
  166. package/.agents/core/skills/nextjs/nextjs.md +0 -67
  167. package/.agents/core/skills/nextjs/skill.yaml +0 -17
  168. package/.agents/core/skills/node/EXAMPLES.md +0 -80
  169. package/.agents/core/skills/node/SKILL.md +0 -128
  170. package/.agents/core/skills/node/TROUBLESHOOTING.md +0 -19
  171. package/.agents/core/skills/node/VALIDATION.json +0 -12
  172. package/.agents/core/skills/node/node.md +0 -87
  173. package/.agents/core/skills/node/skill.yaml +0 -17
  174. package/.agents/core/skills/performance/EXAMPLES.md +0 -30
  175. package/.agents/core/skills/performance/SKILL.md +0 -75
  176. package/.agents/core/skills/performance/TROUBLESHOOTING.md +0 -19
  177. package/.agents/core/skills/performance/VALIDATION.json +0 -12
  178. package/.agents/core/skills/performance/performance.md +0 -52
  179. package/.agents/core/skills/performance/skill.yaml +0 -17
  180. package/.agents/core/skills/react/EXAMPLES.md +0 -79
  181. package/.agents/core/skills/react/SKILL.md +0 -132
  182. package/.agents/core/skills/react/TROUBLESHOOTING.md +0 -19
  183. package/.agents/core/skills/react/VALIDATION.json +0 -12
  184. package/.agents/core/skills/react/react.md +0 -93
  185. package/.agents/core/skills/react/skill.yaml +0 -17
  186. package/.agents/core/skills/react-best-practices/SKILL.md +0 -155
  187. package/.agents/core/skills/react-best-practices/VALIDATION.json +0 -12
  188. package/.agents/core/skills/react-best-practices/skill.yaml +0 -14
  189. package/.agents/core/skills/redesign-audit/SKILL.md +0 -117
  190. package/.agents/core/skills/redesign-audit/VALIDATION.json +0 -12
  191. package/.agents/core/skills/redesign-audit/skill.yaml +0 -12
  192. package/.agents/core/skills/soft-design/SKILL.md +0 -108
  193. package/.agents/core/skills/soft-design/VALIDATION.json +0 -12
  194. package/.agents/core/skills/soft-design/skill.yaml +0 -12
  195. package/.agents/core/skills/state-management/EXAMPLES.md +0 -56
  196. package/.agents/core/skills/state-management/SKILL.md +0 -48
  197. package/.agents/core/skills/state-management/TROUBLESHOOTING.md +0 -18
  198. package/.agents/core/skills/state-management/VALIDATION.json +0 -11
  199. package/.agents/core/skills/state-management/skill.yaml +0 -28
  200. package/.agents/core/skills/subagent-orchestrator/SKILL.md +0 -117
  201. package/.agents/core/skills/subagent-orchestrator/VALIDATION.json +0 -12
  202. package/.agents/core/skills/subagent-orchestrator/skill.yaml +0 -12
  203. package/.agents/core/skills/system-design/EXAMPLES.md +0 -75
  204. package/.agents/core/skills/system-design/SKILL.md +0 -419
  205. package/.agents/core/skills/system-design/TROUBLESHOOTING.md +0 -19
  206. package/.agents/core/skills/system-design/VALIDATION.json +0 -12
  207. package/.agents/core/skills/system-design/skill.yaml +0 -20
  208. package/.agents/core/skills/system-design/system-design.md +0 -112
  209. package/.agents/core/skills/testing/EXAMPLES.md +0 -71
  210. package/.agents/core/skills/testing/SKILL.md +0 -70
  211. package/.agents/core/skills/testing/TROUBLESHOOTING.md +0 -18
  212. package/.agents/core/skills/testing/VALIDATION.json +0 -11
  213. package/.agents/core/skills/testing/skill.yaml +0 -32
  214. package/.agents/core/skills/typescript/EXAMPLES.md +0 -64
  215. package/.agents/core/skills/typescript/SKILL.md +0 -112
  216. package/.agents/core/skills/typescript/TROUBLESHOOTING.md +0 -19
  217. package/.agents/core/skills/typescript/VALIDATION.json +0 -12
  218. package/.agents/core/skills/typescript/skill.yaml +0 -17
  219. package/.agents/core/skills/typescript/typescript.md +0 -71
  220. package/.agents/core/skills/ui-design/EXAMPLES.md +0 -21
  221. package/.agents/core/skills/ui-design/SKILL.md +0 -124
  222. package/.agents/core/skills/ui-design/TROUBLESHOOTING.md +0 -19
  223. package/.agents/core/skills/ui-design/VALIDATION.json +0 -12
  224. package/.agents/core/skills/ui-design/skill.yaml +0 -17
  225. package/.agents/core/skills/ui-design/ui.md +0 -88
  226. package/.agents/core/skills/ui-ux-pro/EXAMPLES.md +0 -62
  227. package/.agents/core/skills/ui-ux-pro/SKILL.md +0 -375
  228. package/.agents/core/skills/ui-ux-pro/TROUBLESHOOTING.md +0 -19
  229. package/.agents/core/skills/ui-ux-pro/VALIDATION.json +0 -12
  230. package/.agents/core/skills/ui-ux-pro/skill.yaml +0 -19
  231. package/.agents/core/skills/ux-design/EXAMPLES.md +0 -36
  232. package/.agents/core/skills/ux-design/SKILL.md +0 -116
  233. package/.agents/core/skills/ux-design/TROUBLESHOOTING.md +0 -19
  234. package/.agents/core/skills/ux-design/VALIDATION.json +0 -12
  235. package/.agents/core/skills/ux-design/skill.yaml +0 -17
  236. package/.agents/core/skills/ux-design/ux.md +0 -80
  237. package/.agents/core/skills/vercel-optimize/SKILL.md +0 -83
  238. package/.agents/core/skills/vercel-optimize/VALIDATION.json +0 -12
  239. package/.agents/core/skills/vercel-optimize/scripts/collect-signals.mjs +0 -131
  240. package/.agents/core/skills/vercel-optimize/scripts/gate-investigations.mjs +0 -142
  241. package/.agents/core/skills/vercel-optimize/scripts/merge-signals.mjs +0 -143
  242. package/.agents/core/skills/vercel-optimize/scripts/scan-codebase.mjs +0 -174
  243. package/.agents/core/skills/vercel-optimize/skill.yaml +0 -18
  244. package/.agents/core/skills/web-accessibility/EXAMPLES.md +0 -39
  245. package/.agents/core/skills/web-accessibility/SKILL.md +0 -170
  246. package/.agents/core/skills/web-accessibility/TROUBLESHOOTING.md +0 -19
  247. package/.agents/core/skills/web-accessibility/VALIDATION.json +0 -12
  248. package/.agents/core/skills/web-accessibility/accessibility.md +0 -63
  249. package/.agents/core/skills/web-accessibility/skill.yaml +0 -17
  250. package/.agents/generated/claude/skills/adapters/SKILL.md +0 -126
  251. package/.agents/generated/claude/skills/architecture-diagrams/SKILL.md +0 -101
  252. package/.agents/generated/claude/skills/brutalist-design/SKILL.md +0 -145
  253. package/.agents/generated/claude/skills/database/SKILL.md +0 -191
  254. package/.agents/generated/claude/skills/ddd/SKILL.md +0 -305
  255. package/.agents/generated/claude/skills/decisions/SKILL.md +0 -134
  256. package/.agents/generated/claude/skills/docker/SKILL.md +0 -135
  257. package/.agents/generated/claude/skills/fastapi/SKILL.md +0 -200
  258. package/.agents/generated/claude/skills/generators/SKILL.md +0 -133
  259. package/.agents/generated/claude/skills/graphify/SKILL.md +0 -198
  260. package/.agents/generated/claude/skills/impeccable-design/SKILL.md +0 -241
  261. package/.agents/generated/claude/skills/interview-me/SKILL.md +0 -90
  262. package/.agents/generated/claude/skills/microservices/SKILL.md +0 -218
  263. package/.agents/generated/claude/skills/minimalist-design/SKILL.md +0 -108
  264. package/.agents/generated/claude/skills/nestjs/SKILL.md +0 -195
  265. package/.agents/generated/claude/skills/nextjs/SKILL.md +0 -219
  266. package/.agents/generated/claude/skills/node/SKILL.md +0 -224
  267. package/.agents/generated/claude/skills/performance/SKILL.md +0 -121
  268. package/.agents/generated/claude/skills/react/SKILL.md +0 -227
  269. package/.agents/generated/claude/skills/react-best-practices/SKILL.md +0 -146
  270. package/.agents/generated/claude/skills/redesign-audit/SKILL.md +0 -112
  271. package/.agents/generated/claude/skills/soft-design/SKILL.md +0 -103
  272. package/.agents/generated/claude/skills/state-management/SKILL.md +0 -120
  273. package/.agents/generated/claude/skills/subagent-orchestrator/SKILL.md +0 -110
  274. package/.agents/generated/claude/skills/system-design/SKILL.md +0 -507
  275. package/.agents/generated/claude/skills/testing/SKILL.md +0 -157
  276. package/.agents/generated/claude/skills/typescript/SKILL.md +0 -192
  277. package/.agents/generated/claude/skills/ui-design/SKILL.md +0 -161
  278. package/.agents/generated/claude/skills/ui-ux-pro/SKILL.md +0 -451
  279. package/.agents/generated/claude/skills/ux-design/SKILL.md +0 -168
  280. package/.agents/generated/claude/skills/vercel-optimize/SKILL.md +0 -76
  281. package/.agents/generated/claude/skills/web-accessibility/SKILL.md +0 -225
  282. package/.agents/generated/gemini/skills/adapters/SKILL.md +0 -135
  283. package/.agents/generated/gemini/skills/architecture-diagrams/SKILL.md +0 -107
  284. package/.agents/generated/gemini/skills/brutalist-design/SKILL.md +0 -151
  285. package/.agents/generated/gemini/skills/database/SKILL.md +0 -200
  286. package/.agents/generated/gemini/skills/ddd/SKILL.md +0 -314
  287. package/.agents/generated/gemini/skills/decisions/SKILL.md +0 -143
  288. package/.agents/generated/gemini/skills/docker/SKILL.md +0 -144
  289. package/.agents/generated/gemini/skills/fastapi/SKILL.md +0 -209
  290. package/.agents/generated/gemini/skills/generators/SKILL.md +0 -142
  291. package/.agents/generated/gemini/skills/graphify/SKILL.md +0 -205
  292. package/.agents/generated/gemini/skills/impeccable-design/SKILL.md +0 -250
  293. package/.agents/generated/gemini/skills/interview-me/SKILL.md +0 -96
  294. package/.agents/generated/gemini/skills/microservices/SKILL.md +0 -227
  295. package/.agents/generated/gemini/skills/minimalist-design/SKILL.md +0 -114
  296. package/.agents/generated/gemini/skills/nestjs/SKILL.md +0 -204
  297. package/.agents/generated/gemini/skills/nextjs/SKILL.md +0 -298
  298. package/.agents/generated/gemini/skills/node/SKILL.md +0 -323
  299. package/.agents/generated/gemini/skills/performance/SKILL.md +0 -185
  300. package/.agents/generated/gemini/skills/react/SKILL.md +0 -332
  301. package/.agents/generated/gemini/skills/react-best-practices/SKILL.md +0 -152
  302. package/.agents/generated/gemini/skills/redesign-audit/SKILL.md +0 -118
  303. package/.agents/generated/gemini/skills/soft-design/SKILL.md +0 -109
  304. package/.agents/generated/gemini/skills/state-management/SKILL.md +0 -129
  305. package/.agents/generated/gemini/skills/subagent-orchestrator/SKILL.md +0 -116
  306. package/.agents/generated/gemini/skills/system-design/SKILL.md +0 -631
  307. package/.agents/generated/gemini/skills/testing/SKILL.md +0 -166
  308. package/.agents/generated/gemini/skills/typescript/SKILL.md +0 -275
  309. package/.agents/generated/gemini/skills/ui-design/SKILL.md +0 -170
  310. package/.agents/generated/gemini/skills/ui-ux-pro/SKILL.md +0 -460
  311. package/.agents/generated/gemini/skills/ux-design/SKILL.md +0 -177
  312. package/.agents/generated/gemini/skills/vercel-optimize/SKILL.md +0 -82
  313. package/.agents/generated/gemini/skills/web-accessibility/SKILL.md +0 -300
@@ -1,28 +1,47 @@
1
+ /**
2
+ * .agents/adapters/cursor/export.js
3
+ * ContextOS Cursor Pure Adapter (.cursorrules and .cursor/rules/*.mdc)
4
+ */
5
+
1
6
  const fs = require('fs');
2
7
  const path = require('path');
3
8
  const { AGENTS_MD_PATH, collectSkillDirectories, extractYamlField, stripFrontmatter, readMeaningfulMarkdown } = require('../shared.js');
9
+ const { registerAdapter, applyArtifacts, createProvenanceHeader } = require('../pure-compiler.js');
4
10
 
5
- // Output paths
6
- const OUTPUT_FILE = path.join(process.cwd(), '.cursorrules');
7
- const CURSOR_RULES_DIR = path.join(process.cwd(), '.cursor', 'rules');
11
+ const GENERATOR_ID = 'cursor@2';
8
12
 
9
- /**
10
- * Cursor adapter — export.js
11
- *
12
- * Generates:
13
- * 1. Modern modular Cursor rules in `.cursor/rules/<skill>.mdc` with glob filters
14
- * 2. Flat `.cursorrules` at project root for backwards compatibility
15
- *
16
- * Format spec: https://docs.cursor.com/context/rules-for-ai
17
- */
13
+ function describe() {
14
+ return {
15
+ name: 'cursor',
16
+ version: '2.0.0',
17
+ description: 'Compiles modular rules for Cursor (.cursor/rules/*.mdc and legacy .cursorrules)',
18
+ targetPattern: '.cursor/rules/*.mdc',
19
+ };
20
+ }
18
21
 
19
- function getSkillGlobsAndFlags(skillName) {
20
- const ALWAYS_APPLY_SKILLS = ['engineering-workflow', 'gstack-roles', 'ponytail-mindset'];
22
+ function getSkillGlobsAndFlags(skillName, skillDir = null) {
23
+ const ALWAYS_APPLY_SKILLS = ['engineering-workflow', 'gstack-roles', 'ponytail-mindset', 'gemini-precision'];
21
24
  if (ALWAYS_APPLY_SKILLS.includes(skillName)) {
22
25
  return { globs: '', alwaysApply: true };
23
26
  }
24
27
 
25
- // Precise surgical globs mapping to prevent context flooding
28
+ // 1. Dynamic extraction from skill.yaml if available
29
+ if (skillDir) {
30
+ const yamlPath = path.join(skillDir, 'skill.yaml');
31
+ if (fs.existsSync(yamlPath)) {
32
+ try {
33
+ const yamlContent = fs.readFileSync(yamlPath, 'utf8');
34
+ const match = yamlContent.match(/(?:fileGlobs|triggers\s*:\s*(?:files|globs)|globs)\s*:\s*\[?([^\r\n\]]+)\]?/i);
35
+ if (match && match[1]) {
36
+ const globsVal = match[1].replace(/['"]/g, '').trim();
37
+ if (globsVal) {
38
+ return { globs: globsVal, alwaysApply: false };
39
+ }
40
+ }
41
+ } catch {}
42
+ }
43
+ }
44
+
26
45
  const GLOB_MAP = {
27
46
  'react': '**/*.{tsx,jsx}',
28
47
  'react-best-practices': '**/*.{tsx,jsx}',
@@ -58,9 +77,9 @@ function getSkillGlobsAndFlags(skillName) {
58
77
  }
59
78
 
60
79
  function buildSkillSection(skillDir) {
61
- const skillName = path.basename(skillDir);
62
- const skillMdPath = path.join(skillDir, 'SKILL.md');
63
- const yamlPath = path.join(skillDir, 'skill.yaml');
80
+ const skillName = path.basename(skillDir);
81
+ const skillMdPath = path.join(skillDir, 'SKILL.md');
82
+ const yamlPath = path.join(skillDir, 'skill.yaml');
64
83
 
65
84
  let title = skillName;
66
85
  let description = '';
@@ -70,9 +89,7 @@ function buildSkillSection(skillDir) {
70
89
  description = extractYamlField(yaml, 'description') || '';
71
90
  }
72
91
 
73
- if (!fs.existsSync(skillMdPath)) {
74
- return null;
75
- }
92
+ if (!fs.existsSync(skillMdPath)) return null;
76
93
 
77
94
  const raw = fs.readFileSync(skillMdPath, 'utf8');
78
95
  const body = stripFrontmatter(raw);
@@ -110,7 +127,7 @@ function generateCursorMdc(skillDir) {
110
127
  if (troubleshooting) raw += '\n\n' + troubleshooting;
111
128
 
112
129
  const body = stripFrontmatter(raw);
113
- const { globs, alwaysApply } = getSkillGlobsAndFlags(skillName);
130
+ const { globs, alwaysApply } = getSkillGlobsAndFlags(skillName, skillDir);
114
131
 
115
132
  let cleanDescription = description.replace(/\r?\n+/g, ' ').replace(/"/g, "'").trim();
116
133
  if (!globs && !alwaysApply) {
@@ -130,34 +147,22 @@ ${body}
130
147
  return { skillName, mdcContent };
131
148
  }
132
149
 
133
- function run() {
134
- console.log('Starting Cursor adapter export...');
135
-
136
- const outputFile = path.join(process.cwd(), '.cursorrules');
137
- const cursorRulesDir = path.join(process.cwd(), '.cursor', 'rules');
138
- const agentsMdPath = fs.existsSync(path.join(process.cwd(), '.agents', 'AGENTS.md'))
139
- ? path.join(process.cwd(), '.agents', 'AGENTS.md')
150
+ function render(context) {
151
+ const projectRoot = context?.projectRoot || '.';
152
+ const agentsMdPath = fs.existsSync(path.join(projectRoot, '.agents', 'AGENTS.md'))
153
+ ? path.join(projectRoot, '.agents', 'AGENTS.md')
140
154
  : AGENTS_MD_PATH;
141
155
 
142
- const sections = [];
143
-
144
- // ── Header ──────────────────────────────────────────────────────────────────
145
- sections.push(
146
- `# ContextOS — AI Rules for Cursor\n` +
147
- `# Auto-generated by: node .agents/ctx.js export cursor\n` +
148
- `# Source: .agents/core/skills/ · Do not edit manually.\n\n` +
149
- `> **Core law: Do not read everything. Read only what the current task requires.**\n\n` +
150
- `Detailed rules are modularized in \`.cursor/rules/*.mdc\` with file-glob activation.\n` +
151
- `Core orchestration is handled by \`.cursor/rules/00-project-rules.mdc\`.\n`
152
- );
156
+ const artifacts = [];
153
157
 
154
- // Prepare .cursor/rules directory
155
- fs.mkdirSync(cursorRulesDir, { recursive: true });
158
+ const prov = createProvenanceHeader({
159
+ generator: GENERATOR_ID,
160
+ sourceGraphHash: context?.sourceGraphHash,
161
+ profileId: context?.profileId,
162
+ profileHash: context?.profileHash,
163
+ });
156
164
 
157
- let count = 0;
158
- let mdcCount = 0;
159
-
160
- // Write 00-project-rules.mdc
165
+ // 1. 00-project-rules.mdc
161
166
  if (fs.existsSync(agentsMdPath)) {
162
167
  const agentsMd = fs.readFileSync(agentsMdPath, 'utf8');
163
168
  const projectMdc = `---
@@ -166,78 +171,69 @@ globs: ""
166
171
  alwaysApply: true
167
172
  ---
168
173
 
174
+ ${prov}
169
175
  # ContextOS — Project Operating System Rules
170
176
 
171
177
  ${agentsMd}
172
178
  `;
173
- fs.writeFileSync(path.join(cursorRulesDir, '00-project-rules.mdc'), projectMdc);
174
- mdcCount++;
179
+ artifacts.push({
180
+ path: '.cursor/rules/00-project-rules.mdc',
181
+ content: projectMdc.replace(/\r\n/g, '\n'),
182
+ mediaType: 'text/markdown',
183
+ kind: 'generated-adapter',
184
+ generator: GENERATOR_ID,
185
+ sourceSkillIds: ['project-rules'],
186
+ inputsHash: context?.sourceGraphHash || 'none',
187
+ });
175
188
  }
176
189
 
177
- // ── Skills Index ─────────────────────────────────────────────────────────────
178
- sections.push('\n---\n\n# Skills Index (Loaded On-Demand)\n\n' +
179
- 'The following specialist skills are configured as `.cursor/rules/<skill>.mdc`:\n');
180
- const skills = collectSkillDirectories();
181
- const activeMdcFiles = new Set(['00-project-rules.mdc']);
182
-
190
+ const skills = collectSkillDirectories(context?.profile);
183
191
  for (const skill of skills) {
184
- const section = buildSkillSection(skill);
185
- if (section) {
186
- sections.push(section);
187
- count++;
188
- }
189
-
190
192
  const mdc = generateCursorMdc(skill);
191
193
  if (mdc) {
192
- const mdcFileName = `${mdc.skillName}.mdc`;
193
- activeMdcFiles.add(mdcFileName);
194
- fs.writeFileSync(path.join(cursorRulesDir, mdcFileName), mdc.mdcContent);
195
- mdcCount++;
194
+ const fullMdc = mdc.mdcContent.replace(/\r\n/g, '\n');
195
+ artifacts.push({
196
+ path: `.cursor/rules/${mdc.skillName}.mdc`,
197
+ content: fullMdc,
198
+ mediaType: 'text/markdown',
199
+ kind: 'generated-adapter',
200
+ generator: GENERATOR_ID,
201
+ sourceSkillIds: [mdc.skillName],
202
+ inputsHash: context?.sourceGraphHash || 'none',
203
+ });
196
204
  }
197
205
  }
198
206
 
199
- // Clean up stale .mdc rules from uninstalled skills/plugins safely (provenance-verified only)
200
- if (fs.existsSync(cursorRulesDir)) {
201
- const lockfilePath = path.join(process.cwd(), '.agents', 'contextos.lock.json');
202
- let lockData = null;
203
- try {
204
- if (fs.existsSync(lockfilePath)) {
205
- lockData = JSON.parse(fs.readFileSync(lockfilePath, 'utf8'));
206
- }
207
- } catch {}
208
-
209
- for (const file of fs.readdirSync(cursorRulesDir)) {
210
- if (file.endsWith('.mdc') && !activeMdcFiles.has(file)) {
211
- const fullFilePath = path.join(cursorRulesDir, file);
212
- const relPath = path.relative(process.cwd(), fullFilePath).replace(/\\/g, '/');
213
-
214
- // Deletion permitted ONLY if recorded in lockfile OR content carries explicit ContextOS provenance
215
- const isManagedInLock = Boolean(lockData?.managedFiles?.[relPath]?.managed);
216
- let hasContextosMarker = false;
217
- try {
218
- const content = fs.readFileSync(fullFilePath, 'utf8');
219
- hasContextosMarker =
220
- content.includes('<!-- Auto-generated by: node .agents/ctx.js export cursor -->') ||
221
- content.includes('ContextOS rules for') ||
222
- content.includes('ContextOS — Project Operating System Rules');
223
- } catch {}
224
-
225
- if (isManagedInLock || hasContextosMarker) {
226
- fs.unlinkSync(fullFilePath);
227
- if (lockData?.managedFiles?.[relPath]) {
228
- delete lockData.managedFiles[relPath];
229
- try {
230
- fs.writeFileSync(lockfilePath, JSON.stringify(lockData, null, 2) + '\n', 'utf8');
231
- } catch {}
232
- }
233
- }
234
- }
207
+ return artifacts;
208
+ }
209
+
210
+ function validate(artifacts) {
211
+ const diagnostics = [];
212
+ for (const art of artifacts) {
213
+ if (!art.content || art.content.length === 0) {
214
+ diagnostics.push({ path: art.path, message: 'Empty artifact content' });
235
215
  }
236
216
  }
217
+ return diagnostics;
218
+ }
237
219
 
238
- fs.writeFileSync(outputFile, sections.join('\n'));
239
- console.log(`Generated .cursorrules (${count} skills) → ${outputFile}`);
240
- console.log(`Generated .cursor/rules/*.mdc (${mdcCount} rules) → ${cursorRulesDir}`);
220
+ function run(options = {}) {
221
+ const { loadCompilerContext } = require('../pure-compiler.js');
222
+ const projectRoot = options.projectRoot || '.';
223
+ const context = loadCompilerContext(projectRoot, options);
224
+ const artifacts = render(context);
225
+ const result = applyArtifacts(projectRoot, artifacts, { command: 'export cursor', context });
226
+ console.log(`✓ Cursor export complete: ${result.appliedCount} files applied (tx: ${result.txId})`);
227
+ return result;
241
228
  }
242
229
 
243
- module.exports = { run };
230
+ const adapter = {
231
+ describe,
232
+ render,
233
+ validate,
234
+ run,
235
+ };
236
+
237
+ registerAdapter('cursor', adapter);
238
+
239
+ module.exports = adapter;
@@ -0,0 +1,196 @@
1
+ /**
2
+ * .agents/adapters/drift-detector.js
3
+ * ContextOS Adapter Output Drift & Out-of-Sync Detector
4
+ *
5
+ * Implements Section 12.4 drift states:
6
+ * - STALE_INPUT: Source graph or profile modified since last compile
7
+ * - MISSING_OUTPUT: Planned or recorded file absent from disk
8
+ * - MODIFIED_MANAGED_OUTPUT: Disk content differs from lockfile (user edits)
9
+ * - ORPHAN_MANAGED_OUTPUT: Lockfile records file no longer rendered
10
+ * - ADAPTER_VERSION_MISMATCH: Generator version differs
11
+ * - PROFILE_MISMATCH: Active profile differs from lockfile profile
12
+ */
13
+
14
+ const fs = require('fs');
15
+ const path = require('path');
16
+ const { LockfileV2Manager, computeExactHash, computeSemanticHash } = require('../filesystem/index.js');
17
+ const { renderAdapters } = require('./pure-compiler.js');
18
+
19
+ const DRIFT_STATES = {
20
+ STALE_INPUT: 'STALE_INPUT',
21
+ MISSING_OUTPUT: 'MISSING_OUTPUT',
22
+ MODIFIED_MANAGED_OUTPUT: 'MODIFIED_MANAGED_OUTPUT',
23
+ ORPHAN_MANAGED_OUTPUT: 'ORPHAN_MANAGED_OUTPUT',
24
+ ADAPTER_VERSION_MISMATCH: 'ADAPTER_VERSION_MISMATCH',
25
+ PROFILE_MISMATCH: 'PROFILE_MISMATCH',
26
+ };
27
+
28
+ /**
29
+ * Computes a unified textual diff snippet between before and after strings.
30
+ */
31
+ function computeDiffSnippet(beforeStr, afterStr, maxLines = 15) {
32
+ const beforeLines = beforeStr.split(/\r?\n/);
33
+ const afterLines = afterStr.split(/\r?\n/);
34
+ const diffLines = [];
35
+
36
+ let lineCount = 0;
37
+ for (let i = 0; i < Math.max(beforeLines.length, afterLines.length); i++) {
38
+ const b = beforeLines[i];
39
+ const a = afterLines[i];
40
+ if (b !== a) {
41
+ if (b !== undefined) {
42
+ diffLines.push(`- ${b}`);
43
+ lineCount++;
44
+ }
45
+ if (a !== undefined) {
46
+ diffLines.push(`+ ${a}`);
47
+ lineCount++;
48
+ }
49
+ }
50
+ if (lineCount >= maxLines) {
51
+ diffLines.push('... (diff truncated)');
52
+ break;
53
+ }
54
+ }
55
+
56
+ return diffLines.join('\n');
57
+ }
58
+
59
+ /**
60
+ * Analyzes drift between current project state, Lockfile v2, and projected adapter render.
61
+ *
62
+ * @param {string} projectRoot
63
+ * @param {string[]|string} [adapters='all']
64
+ * @param {object} [options]
65
+ * @returns {object} Structured drift report
66
+ */
67
+ function detectDrift(projectRoot, adapters = 'all', options = {}) {
68
+ const absRoot = path.resolve(projectRoot);
69
+ const lockManager = new LockfileV2Manager(absRoot);
70
+ const lockfile = lockManager.read();
71
+
72
+ const { artifacts, collisions, context } = renderAdapters(absRoot, adapters, options);
73
+
74
+ const findings = {
75
+ [DRIFT_STATES.STALE_INPUT]: [],
76
+ [DRIFT_STATES.MISSING_OUTPUT]: [],
77
+ [DRIFT_STATES.MODIFIED_MANAGED_OUTPUT]: [],
78
+ [DRIFT_STATES.ORPHAN_MANAGED_OUTPUT]: [],
79
+ [DRIFT_STATES.ADAPTER_VERSION_MISMATCH]: [],
80
+ [DRIFT_STATES.PROFILE_MISMATCH]: [],
81
+ };
82
+
83
+ const diffs = [];
84
+
85
+ // 1. Check Profile Mismatch
86
+ if (lockfile && lockfile.profile) {
87
+ if (context.profileId && lockfile.profile.id !== context.profileId) {
88
+ findings[DRIFT_STATES.PROFILE_MISMATCH].push({
89
+ expected: context.profileId,
90
+ actual: lockfile.profile.id,
91
+ });
92
+ }
93
+ }
94
+
95
+ // 2. Check Stale Input (Source Graph Hash)
96
+ if (lockfile && lockfile.sourceGraphHash) {
97
+ if (context.sourceGraphHash && lockfile.sourceGraphHash !== context.sourceGraphHash) {
98
+ findings[DRIFT_STATES.STALE_INPUT].push({
99
+ expected: context.sourceGraphHash,
100
+ actual: lockfile.sourceGraphHash,
101
+ });
102
+ }
103
+ }
104
+
105
+ const projectedPaths = new Set(artifacts.map(a => a.path));
106
+
107
+ // 3. Inspect each projected artifact against disk and lockfile
108
+ for (const art of artifacts) {
109
+ const fullPath = path.resolve(absRoot, art.path);
110
+ const projectedContent = art.content.toString('utf8');
111
+ const projectedExactHash = computeExactHash(art.content);
112
+ const projectedSemanticHash = computeSemanticHash(art.content);
113
+
114
+ if (!fs.existsSync(fullPath)) {
115
+ findings[DRIFT_STATES.MISSING_OUTPUT].push({
116
+ path: art.path,
117
+ reason: 'Projected artifact does not exist on disk',
118
+ });
119
+ diffs.push({
120
+ path: art.path,
121
+ type: 'missing',
122
+ diff: `+ (new file, ${projectedContent.length} bytes)`,
123
+ });
124
+ } else {
125
+ const diskContent = fs.readFileSync(fullPath, 'utf8');
126
+ const diskSemanticHash = computeSemanticHash(diskContent);
127
+
128
+ // Check if disk matches projected render
129
+ if (diskSemanticHash !== projectedSemanticHash) {
130
+ const lockRecord = lockfile?.managedFiles?.[art.path];
131
+ if (lockRecord && lockRecord.semanticTextSha256 !== diskSemanticHash) {
132
+ findings[DRIFT_STATES.MODIFIED_MANAGED_OUTPUT].push({
133
+ path: art.path,
134
+ reason: 'Managed file was modified by user on disk',
135
+ diskHash: diskSemanticHash,
136
+ lockHash: lockRecord.semanticTextSha256,
137
+ });
138
+ } else {
139
+ findings[DRIFT_STATES.STALE_INPUT].push({
140
+ path: art.path,
141
+ reason: 'Generated artifact differs from source skills projection',
142
+ });
143
+ }
144
+
145
+ diffs.push({
146
+ path: art.path,
147
+ type: 'modified',
148
+ diff: computeDiffSnippet(diskContent, projectedContent),
149
+ });
150
+ }
151
+ }
152
+ }
153
+
154
+ // 4. Check for orphan files recorded in lockfile but no longer projected
155
+ if (lockfile && lockfile.managedFiles) {
156
+ for (const [recordedPath, meta] of Object.entries(lockfile.managedFiles)) {
157
+ if (!projectedPaths.has(recordedPath)) {
158
+ const fullRecorded = path.resolve(absRoot, recordedPath);
159
+ if (fs.existsSync(fullRecorded)) {
160
+ findings[DRIFT_STATES.ORPHAN_MANAGED_OUTPUT].push({
161
+ path: recordedPath,
162
+ reason: 'File recorded in lockfile is no longer generated by active skills/profile',
163
+ });
164
+ diffs.push({
165
+ path: recordedPath,
166
+ type: 'orphan',
167
+ diff: `- (orphan file on disk, ${meta.kind})`,
168
+ });
169
+ }
170
+ }
171
+ }
172
+ }
173
+
174
+ if (diffs.length === 0 && findings[DRIFT_STATES.ORPHAN_MANAGED_OUTPUT].length === 0) {
175
+ findings[DRIFT_STATES.STALE_INPUT] = [];
176
+ findings[DRIFT_STATES.PROFILE_MISMATCH] = [];
177
+ }
178
+
179
+ const totalFindings = Object.values(findings).reduce((acc, list) => acc + list.length, 0);
180
+ const hasDrift = totalFindings > 0 || collisions.length > 0;
181
+
182
+ return {
183
+ hasDrift,
184
+ totalFindings,
185
+ findings,
186
+ collisions,
187
+ diffs,
188
+ projectedCount: artifacts.length,
189
+ };
190
+ }
191
+
192
+ module.exports = {
193
+ detectDrift,
194
+ computeDiffSnippet,
195
+ DRIFT_STATES,
196
+ };
@@ -1,18 +1,31 @@
1
+ /**
2
+ * .agents/adapters/gemini/export.js
3
+ * ContextOS Gemini & Antigravity IDE Pure Adapter
4
+ */
5
+
1
6
  const fs = require('fs');
2
7
  const path = require('path');
3
- const { collectSkillDirectories, resetDirectory, readMeaningfulMarkdown, extractYamlField } = require('../shared.js');
4
-
5
- const GENERATED_SKILLS_PATH = path.join(__dirname, '..', '..', 'generated', 'gemini', 'skills');
8
+ const { collectSkillDirectories, readMeaningfulMarkdown, extractYamlField } = require('../shared.js');
9
+ const { registerAdapter, applyArtifacts } = require('../pure-compiler.js');
10
+
11
+ const GENERATOR_ID = 'gemini@2';
12
+
13
+ function describe() {
14
+ return {
15
+ name: 'gemini',
16
+ version: '2.0.0',
17
+ description: 'Compiles modular skills for Gemini 3.8 and Google Antigravity IDE',
18
+ targetPattern: '.agents/generated/gemini/skills/**/SKILL.md',
19
+ };
20
+ }
6
21
 
7
- function generateGeminiSkill(skillDir) {
22
+ function renderGeminiSkill(skillDir, context) {
8
23
  const skillName = path.basename(skillDir);
9
24
  const yamlPath = path.join(skillDir, 'skill.yaml');
10
25
  const existingSkillMdPath = path.join(skillDir, 'SKILL.md');
11
- const outputDir = path.join(GENERATED_SKILLS_PATH, skillName);
12
26
 
13
27
  if (!fs.existsSync(existingSkillMdPath) && !fs.existsSync(yamlPath)) {
14
- console.log(`Skipping ${skillName} (no skill.yaml or SKILL.md)`);
15
- return;
28
+ return [];
16
29
  }
17
30
 
18
31
  let name = skillName;
@@ -30,11 +43,9 @@ function generateGeminiSkill(skillDir) {
30
43
  }
31
44
  description = description || `ContextOS skill for ${name}`;
32
45
 
33
- // Find all .md files in the skill directory deterministically
34
46
  const files = fs.readdirSync(skillDir).sort((a, b) => a.localeCompare(b, 'en', { sensitivity: 'base' }));
35
47
  const mdFiles = files.filter(f => f.endsWith('.md'));
36
48
 
37
- // Primary skill content first: SKILL.md is canonical; fallback to <skillName>.md
38
49
  const primaryMd = mdFiles.includes('SKILL.md')
39
50
  ? 'SKILL.md'
40
51
  : (mdFiles.find(f => f === `${skillName}.md`) || mdFiles[0]);
@@ -42,22 +53,16 @@ function generateGeminiSkill(skillDir) {
42
53
  let mergedContent = '';
43
54
  if (primaryMd) {
44
55
  let primaryText = fs.readFileSync(path.join(skillDir, primaryMd), 'utf8');
45
- // Strip existing frontmatter from source so we don't double-nest
46
56
  primaryText = primaryText.replace(/^---[\s\S]*?---\r?\n/, '');
47
57
  mergedContent += primaryText;
48
58
  }
49
59
 
50
- // Partition supplemental markdown files for deterministic, logical ordering:
51
- // 1. Specific topic / reference docs (e.g. accessibility.md), sorted alphabetically
52
- // 2. EXAMPLES.md
53
- // 3. TROUBLESHOOTING.md
54
60
  const otherTopicFiles = mdFiles.filter(f => f !== primaryMd && f !== 'EXAMPLES.md' && f !== 'TROUBLESHOOTING.md');
55
61
  const orderedExtras = [...otherTopicFiles];
56
62
  if (mdFiles.includes('EXAMPLES.md') && primaryMd !== 'EXAMPLES.md') orderedExtras.push('EXAMPLES.md');
57
63
  if (mdFiles.includes('TROUBLESHOOTING.md') && primaryMd !== 'TROUBLESHOOTING.md') orderedExtras.push('TROUBLESHOOTING.md');
58
64
 
59
65
  for (const mdFile of orderedExtras) {
60
- // Avoid re-appending content that was already inlined via Source comments in SKILL.md
61
66
  if (mergedContent.includes(`<!-- Source: ${mdFile} -->`)) continue;
62
67
  const extraContent = readMeaningfulMarkdown(path.join(skillDir, mdFile));
63
68
  if (extraContent) {
@@ -65,7 +70,6 @@ function generateGeminiSkill(skillDir) {
65
70
  }
66
71
  }
67
72
 
68
- // Construct Gemini SKILL.md format (normalizing line endings to \n)
69
73
  const outputContent = `---
70
74
  name: ${name}
71
75
  description: >
@@ -74,42 +78,69 @@ description: >
74
78
  ${mergedContent.trimStart()}
75
79
  `.replace(/\r\n/g, '\n');
76
80
 
77
- fs.mkdirSync(outputDir, { recursive: true });
78
- fs.writeFileSync(path.join(outputDir, 'SKILL.md'), outputContent);
81
+ const artifacts = [
82
+ {
83
+ path: `.agents/generated/gemini/skills/${skillName}/SKILL.md`,
84
+ content: outputContent,
85
+ mediaType: 'text/markdown',
86
+ kind: 'generated-adapter',
87
+ generator: GENERATOR_ID,
88
+ sourceSkillIds: [skillName],
89
+ inputsHash: context?.sourceGraphHash || 'none',
90
+ },
91
+ {
92
+ path: `.agents/skills/${skillName}/SKILL.md`,
93
+ content: outputContent,
94
+ mediaType: 'text/markdown',
95
+ kind: 'generated-adapter',
96
+ generator: GENERATOR_ID,
97
+ sourceSkillIds: [skillName],
98
+ inputsHash: context?.sourceGraphHash || 'none',
99
+ },
100
+ ];
101
+
102
+ return artifacts;
103
+ }
104
+
105
+ function render(context) {
106
+ const skills = collectSkillDirectories(context?.profile);
107
+ const artifacts = [];
108
+
109
+ for (const skill of skills) {
110
+ const rendered = renderGeminiSkill(skill, context);
111
+ artifacts.push(...rendered);
112
+ }
79
113
 
80
- console.log(`Generated SKILL.md for ${skillName}`);
114
+ return artifacts;
81
115
  }
82
116
 
83
- const ANTIGRAVITY_SKILLS_PATH = path.join(__dirname, '..', '..', 'skills');
84
-
85
- function copyFolderRecursiveSync(source, target) {
86
- if (!fs.existsSync(target)) fs.mkdirSync(target, { recursive: true });
87
- const files = fs.readdirSync(source).sort((a, b) => a.localeCompare(b, 'en', { sensitivity: 'base' }));
88
- for (const file of files) {
89
- const curSource = path.join(source, file);
90
- const curTarget = path.join(target, file);
91
- if (fs.statSync(curSource).isDirectory()) {
92
- copyFolderRecursiveSync(curSource, curTarget);
93
- } else {
94
- fs.copyFileSync(curSource, curTarget);
117
+ function validate(artifacts) {
118
+ const diagnostics = [];
119
+ for (const art of artifacts) {
120
+ if (!art.content || art.content.length === 0) {
121
+ diagnostics.push({ path: art.path, message: 'Empty artifact content' });
95
122
  }
96
123
  }
124
+ return diagnostics;
97
125
  }
98
126
 
99
- function run() {
100
- console.log('Starting Gemini adapter export...');
101
- resetDirectory(GENERATED_SKILLS_PATH);
102
-
103
- const skills = collectSkillDirectories();
104
- for (const skill of skills) {
105
- generateGeminiSkill(skill);
106
- }
127
+ function run(options = {}) {
128
+ const { loadCompilerContext } = require('../pure-compiler.js');
129
+ const projectRoot = options.projectRoot || '.';
130
+ const context = loadCompilerContext(projectRoot, options);
131
+ const artifacts = render(context);
132
+ const result = applyArtifacts(projectRoot, artifacts, { command: 'export gemini', context });
133
+ console.log(`✓ Gemini export complete: ${result.appliedCount} files applied (tx: ${result.txId})`);
134
+ return result;
135
+ }
107
136
 
108
- // Also sync to .agents/skills for Antigravity IDE native discovery
109
- resetDirectory(ANTIGRAVITY_SKILLS_PATH);
110
- copyFolderRecursiveSync(GENERATED_SKILLS_PATH, ANTIGRAVITY_SKILLS_PATH);
137
+ const adapter = {
138
+ describe,
139
+ render,
140
+ validate,
141
+ run,
142
+ };
111
143
 
112
- console.log('Export complete. Skills are in generated/gemini/skills and .agents/skills');
113
- }
144
+ registerAdapter('gemini', adapter);
114
145
 
115
- module.exports = { run };
146
+ module.exports = adapter;