contextos-agents 2.0.0 → 2.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (223) hide show
  1. package/.agents/AGENTS.md +53 -33
  2. package/.agents/adapters/aider/export.js +41 -14
  3. package/.agents/adapters/claude/export.js +54 -3
  4. package/.agents/adapters/copilot/export.js +1 -1
  5. package/.agents/adapters/cursor/export.js +1 -1
  6. package/.agents/adapters/drift-detector.js +86 -10
  7. package/.agents/adapters/gemini/export.js +1 -1
  8. package/.agents/adapters/pure-compiler.js +28 -6
  9. package/.agents/adapters/shared.js +13 -4
  10. package/.agents/adapters/zed/export.js +1 -1
  11. package/.agents/compiled/registry.v2.json +29 -25
  12. package/.agents/compiled/registry.v2.sha256 +1 -1
  13. package/.agents/core/skills/context-os/SKILL.md +34 -37
  14. package/.agents/core/skills/engineering-workflow/SKILL.md +24 -24
  15. package/.agents/core/skills/gemini-precision/EXAMPLES.md +72 -0
  16. package/.agents/core/skills/gemini-precision/SKILL.md +2 -1
  17. package/.agents/core/skills/gemini-precision/TROUBLESHOOTING.md +25 -0
  18. package/.agents/core/skills/gemini-precision/skill.yaml +2 -0
  19. package/.agents/core/skills/gstack-roles/SKILL.md +7 -6
  20. package/.agents/core/skills/security/SKILL.md +44 -16
  21. package/.agents/core/skills/security/skill.yaml +0 -1
  22. package/.agents/ctx.js +20 -14
  23. package/.agents/generated/claude/skills/context-os/SKILL.md +34 -37
  24. package/.agents/generated/claude/skills/engineering-workflow/SKILL.md +24 -24
  25. package/.agents/generated/claude/skills/gemini-precision/SKILL.md +102 -1
  26. package/.agents/generated/claude/skills/gstack-roles/SKILL.md +7 -6
  27. package/.agents/generated/claude/skills/security/SKILL.md +44 -16
  28. package/.agents/generated/gemini/skills/context-os/SKILL.md +34 -37
  29. package/.agents/generated/gemini/skills/engineering-workflow/SKILL.md +24 -24
  30. package/.agents/generated/gemini/skills/gemini-precision/SKILL.md +105 -1
  31. package/.agents/generated/gemini/skills/gstack-roles/SKILL.md +7 -6
  32. package/.agents/generated/gemini/skills/security/SKILL.md +44 -125
  33. package/.agents/plugins.js +105 -8
  34. package/.agents/profiles.js +32 -11
  35. package/.agents/resolver/canonical-resolver.js +7 -7
  36. package/.agents/validate.js +69 -1
  37. package/README.md +81 -24
  38. package/bin/commands/hook.js +167 -0
  39. package/bin/commands/scan.js +77 -0
  40. package/bin/commands.js +39 -1
  41. package/bin/index.js +151 -34
  42. package/bin/lib/gate.js +171 -0
  43. package/bin/lib/git-snapshot.js +214 -0
  44. package/bin/lib/scan.js +461 -0
  45. package/catalog/skills/adapters/EXAMPLES.md +19 -0
  46. package/catalog/skills/adapters/SKILL.md +101 -0
  47. package/catalog/skills/adapters/TROUBLESHOOTING.md +7 -0
  48. package/catalog/skills/adapters/VALIDATION.json +12 -0
  49. package/catalog/skills/adapters/skill.yaml +13 -0
  50. package/catalog/skills/api-design/EXAMPLES.md +91 -0
  51. package/catalog/skills/api-design/SKILL.md +63 -0
  52. package/catalog/skills/api-design/TROUBLESHOOTING.md +54 -0
  53. package/catalog/skills/api-design/VALIDATION.json +11 -0
  54. package/catalog/skills/api-design/skill.yaml +14 -0
  55. package/catalog/skills/architecture-diagrams/SKILL.md +108 -0
  56. package/catalog/skills/architecture-diagrams/VALIDATION.json +12 -0
  57. package/catalog/skills/architecture-diagrams/skill.yaml +9 -0
  58. package/catalog/skills/brutalist-design/EXAMPLES.md +59 -0
  59. package/catalog/skills/brutalist-design/SKILL.md +150 -0
  60. package/catalog/skills/brutalist-design/VALIDATION.json +12 -0
  61. package/catalog/skills/brutalist-design/skill.yaml +10 -0
  62. package/catalog/skills/ci-cd/EXAMPLES.md +79 -0
  63. package/catalog/skills/ci-cd/SKILL.md +69 -0
  64. package/catalog/skills/ci-cd/TROUBLESHOOTING.md +52 -0
  65. package/catalog/skills/ci-cd/VALIDATION.json +11 -0
  66. package/catalog/skills/ci-cd/skill.yaml +13 -0
  67. package/catalog/skills/database/EXAMPLES.md +74 -0
  68. package/catalog/skills/database/SKILL.md +101 -0
  69. package/catalog/skills/database/TROUBLESHOOTING.md +18 -0
  70. package/catalog/skills/database/VALIDATION.json +11 -0
  71. package/catalog/skills/database/skill.yaml +14 -0
  72. package/catalog/skills/ddd/EXAMPLES.md +42 -0
  73. package/catalog/skills/ddd/SKILL.md +247 -0
  74. package/catalog/skills/ddd/TROUBLESHOOTING.md +19 -0
  75. package/catalog/skills/ddd/VALIDATION.json +12 -0
  76. package/catalog/skills/ddd/skill.yaml +14 -0
  77. package/catalog/skills/decisions/EXAMPLES.md +35 -0
  78. package/catalog/skills/decisions/SKILL.md +90 -0
  79. package/catalog/skills/decisions/TROUBLESHOOTING.md +13 -0
  80. package/catalog/skills/decisions/VALIDATION.json +12 -0
  81. package/catalog/skills/decisions/skill.yaml +13 -0
  82. package/catalog/skills/docker/EXAMPLES.md +56 -0
  83. package/catalog/skills/docker/SKILL.md +169 -0
  84. package/catalog/skills/docker/TROUBLESHOOTING.md +18 -0
  85. package/catalog/skills/docker/VALIDATION.json +11 -0
  86. package/catalog/skills/docker/skill.yaml +13 -0
  87. package/catalog/skills/fastapi/EXAMPLES.md +36 -0
  88. package/catalog/skills/fastapi/SKILL.md +171 -0
  89. package/catalog/skills/fastapi/TROUBLESHOOTING.md +19 -0
  90. package/catalog/skills/fastapi/VALIDATION.json +12 -0
  91. package/catalog/skills/fastapi/skill.yaml +14 -0
  92. package/catalog/skills/generators/EXAMPLES.md +19 -0
  93. package/catalog/skills/generators/SKILL.md +110 -0
  94. package/catalog/skills/generators/TROUBLESHOOTING.md +7 -0
  95. package/catalog/skills/generators/VALIDATION.json +12 -0
  96. package/catalog/skills/generators/skill.yaml +22 -0
  97. package/catalog/skills/generators/templates/API.md +77 -0
  98. package/catalog/skills/generators/templates/ARCHITECTURE.md +70 -0
  99. package/catalog/skills/generators/templates/DATABASE.md +42 -0
  100. package/catalog/skills/generators/templates/DECISION.md +46 -0
  101. package/catalog/skills/generators/templates/PRD.md +67 -0
  102. package/catalog/skills/generators/templates/PROJECT_GRAPH.md +56 -0
  103. package/catalog/skills/generators/templates/ROADMAP.md +51 -0
  104. package/catalog/skills/generators/templates/TASKS.md +43 -0
  105. package/catalog/skills/generators/templates/UI.md +73 -0
  106. package/catalog/skills/graphify/EXAMPLES.md +73 -0
  107. package/catalog/skills/graphify/SKILL.md +130 -0
  108. package/catalog/skills/graphify/VALIDATION.json +12 -0
  109. package/catalog/skills/graphify/skill.yaml +13 -0
  110. package/catalog/skills/impeccable-design/EXAMPLES.md +26 -0
  111. package/catalog/skills/impeccable-design/SKILL.md +201 -0
  112. package/catalog/skills/impeccable-design/TROUBLESHOOTING.md +19 -0
  113. package/catalog/skills/impeccable-design/VALIDATION.json +12 -0
  114. package/catalog/skills/impeccable-design/skill.yaml +15 -0
  115. package/catalog/skills/interview-me/SKILL.md +97 -0
  116. package/catalog/skills/interview-me/VALIDATION.json +12 -0
  117. package/catalog/skills/interview-me/skill.yaml +9 -0
  118. package/catalog/skills/microservices/EXAMPLES.md +38 -0
  119. package/catalog/skills/microservices/SKILL.md +164 -0
  120. package/catalog/skills/microservices/TROUBLESHOOTING.md +19 -0
  121. package/catalog/skills/microservices/VALIDATION.json +12 -0
  122. package/catalog/skills/microservices/skill.yaml +14 -0
  123. package/catalog/skills/minimalist-design/EXAMPLES.md +58 -0
  124. package/catalog/skills/minimalist-design/SKILL.md +113 -0
  125. package/catalog/skills/minimalist-design/VALIDATION.json +12 -0
  126. package/catalog/skills/minimalist-design/skill.yaml +10 -0
  127. package/catalog/skills/nestjs/EXAMPLES.md +40 -0
  128. package/catalog/skills/nestjs/SKILL.md +139 -0
  129. package/catalog/skills/nestjs/TROUBLESHOOTING.md +19 -0
  130. package/catalog/skills/nestjs/VALIDATION.json +12 -0
  131. package/catalog/skills/nestjs/skill.yaml +14 -0
  132. package/catalog/skills/nextjs/EXAMPLES.md +40 -0
  133. package/catalog/skills/nextjs/SKILL.md +163 -0
  134. package/catalog/skills/nextjs/TROUBLESHOOTING.md +19 -0
  135. package/catalog/skills/nextjs/VALIDATION.json +12 -0
  136. package/catalog/skills/nextjs/skill.yaml +14 -0
  137. package/catalog/skills/node/EXAMPLES.md +80 -0
  138. package/catalog/skills/node/SKILL.md +128 -0
  139. package/catalog/skills/node/TROUBLESHOOTING.md +19 -0
  140. package/catalog/skills/node/VALIDATION.json +12 -0
  141. package/catalog/skills/node/skill.yaml +14 -0
  142. package/catalog/skills/performance/EXAMPLES.md +30 -0
  143. package/catalog/skills/performance/SKILL.md +75 -0
  144. package/catalog/skills/performance/TROUBLESHOOTING.md +19 -0
  145. package/catalog/skills/performance/VALIDATION.json +12 -0
  146. package/catalog/skills/performance/skill.yaml +14 -0
  147. package/catalog/skills/react/EXAMPLES.md +79 -0
  148. package/catalog/skills/react/SKILL.md +132 -0
  149. package/catalog/skills/react/TROUBLESHOOTING.md +19 -0
  150. package/catalog/skills/react/VALIDATION.json +12 -0
  151. package/catalog/skills/react/skill.yaml +14 -0
  152. package/catalog/skills/react-best-practices/SKILL.md +158 -0
  153. package/catalog/skills/react-best-practices/VALIDATION.json +12 -0
  154. package/catalog/skills/react-best-practices/skill.yaml +13 -0
  155. package/catalog/skills/redesign-audit/SKILL.md +117 -0
  156. package/catalog/skills/redesign-audit/VALIDATION.json +12 -0
  157. package/catalog/skills/redesign-audit/skill.yaml +9 -0
  158. package/catalog/skills/security-audit/EXAMPLES.md +79 -0
  159. package/catalog/skills/security-audit/SKILL.md +91 -0
  160. package/catalog/skills/security-audit/TROUBLESHOOTING.md +46 -0
  161. package/catalog/skills/security-audit/VALIDATION.json +11 -0
  162. package/catalog/skills/security-audit/skill.yaml +14 -0
  163. package/catalog/skills/soft-design/EXAMPLES.md +51 -0
  164. package/catalog/skills/soft-design/SKILL.md +108 -0
  165. package/catalog/skills/soft-design/VALIDATION.json +12 -0
  166. package/catalog/skills/soft-design/skill.yaml +10 -0
  167. package/catalog/skills/state-management/EXAMPLES.md +56 -0
  168. package/catalog/skills/state-management/SKILL.md +168 -0
  169. package/catalog/skills/state-management/TROUBLESHOOTING.md +18 -0
  170. package/catalog/skills/state-management/VALIDATION.json +11 -0
  171. package/catalog/skills/state-management/skill.yaml +14 -0
  172. package/catalog/skills/subagent-orchestrator/SKILL.md +117 -0
  173. package/catalog/skills/subagent-orchestrator/VALIDATION.json +12 -0
  174. package/catalog/skills/subagent-orchestrator/skill.yaml +9 -0
  175. package/catalog/skills/system-design/EXAMPLES.md +75 -0
  176. package/catalog/skills/system-design/SKILL.md +419 -0
  177. package/catalog/skills/system-design/TROUBLESHOOTING.md +19 -0
  178. package/catalog/skills/system-design/VALIDATION.json +12 -0
  179. package/catalog/skills/system-design/skill.yaml +14 -0
  180. package/catalog/skills/terraform/EXAMPLES.md +74 -0
  181. package/catalog/skills/terraform/SKILL.md +55 -0
  182. package/catalog/skills/terraform/TROUBLESHOOTING.md +53 -0
  183. package/catalog/skills/terraform/VALIDATION.json +11 -0
  184. package/catalog/skills/terraform/skill.yaml +14 -0
  185. package/catalog/skills/testing/EXAMPLES.md +122 -0
  186. package/catalog/skills/testing/SKILL.md +70 -0
  187. package/catalog/skills/testing/TROUBLESHOOTING.md +18 -0
  188. package/catalog/skills/testing/VALIDATION.json +11 -0
  189. package/catalog/skills/testing/skill.yaml +14 -0
  190. package/catalog/skills/typescript/EXAMPLES.md +64 -0
  191. package/catalog/skills/typescript/SKILL.md +112 -0
  192. package/catalog/skills/typescript/TROUBLESHOOTING.md +19 -0
  193. package/catalog/skills/typescript/VALIDATION.json +12 -0
  194. package/catalog/skills/typescript/skill.yaml +14 -0
  195. package/catalog/skills/ui-design/EXAMPLES.md +21 -0
  196. package/catalog/skills/ui-design/SKILL.md +124 -0
  197. package/catalog/skills/ui-design/TROUBLESHOOTING.md +19 -0
  198. package/catalog/skills/ui-design/VALIDATION.json +12 -0
  199. package/catalog/skills/ui-design/skill.yaml +16 -0
  200. package/catalog/skills/ui-ux-pro/EXAMPLES.md +62 -0
  201. package/catalog/skills/ui-ux-pro/SKILL.md +418 -0
  202. package/catalog/skills/ui-ux-pro/TROUBLESHOOTING.md +19 -0
  203. package/catalog/skills/ui-ux-pro/VALIDATION.json +12 -0
  204. package/catalog/skills/ui-ux-pro/skill.yaml +14 -0
  205. package/catalog/skills/ux-design/EXAMPLES.md +36 -0
  206. package/catalog/skills/ux-design/SKILL.md +116 -0
  207. package/catalog/skills/ux-design/TROUBLESHOOTING.md +19 -0
  208. package/catalog/skills/ux-design/VALIDATION.json +12 -0
  209. package/catalog/skills/ux-design/skill.yaml +16 -0
  210. package/catalog/skills/vercel-optimize/SKILL.md +83 -0
  211. package/catalog/skills/vercel-optimize/VALIDATION.json +12 -0
  212. package/catalog/skills/vercel-optimize/scripts/collect-signals.mjs +131 -0
  213. package/catalog/skills/vercel-optimize/scripts/gate-investigations.mjs +142 -0
  214. package/catalog/skills/vercel-optimize/scripts/merge-signals.mjs +143 -0
  215. package/catalog/skills/vercel-optimize/scripts/scan-codebase.mjs +174 -0
  216. package/catalog/skills/vercel-optimize/skill.yaml +15 -0
  217. package/catalog/skills/web-accessibility/EXAMPLES.md +39 -0
  218. package/catalog/skills/web-accessibility/SKILL.md +151 -0
  219. package/catalog/skills/web-accessibility/TROUBLESHOOTING.md +19 -0
  220. package/catalog/skills/web-accessibility/VALIDATION.json +12 -0
  221. package/catalog/skills/web-accessibility/skill.yaml +14 -0
  222. package/package.json +5 -2
  223. package/.agents/core/skills/security/security.md +0 -106
package/.agents/AGENTS.md CHANGED
@@ -1,4 +1,4 @@
1
- # ContextOS — Deterministic context compiler and policy engine for AI coding agents.
1
+ # ContextOS - Deterministic context compiler and policy engine for AI coding agents.
2
2
 
3
3
  You are working inside a project managed by **ContextOS**. This file is the **single source of truth** for how you must behave, think, and which skills to activate for every task.
4
4
 
@@ -6,7 +6,7 @@ You are working inside a project managed by **ContextOS**. This file is the **si
6
6
 
7
7
  ---
8
8
 
9
- ## Step 0 — Identify Before Acting
9
+ ## Step 0 - Identify Before Acting
10
10
 
11
11
  Before writing a single line of code or plan, stop and answer three questions:
12
12
 
@@ -28,12 +28,12 @@ Skills loaded: react, typescript, ui-ux-pro, ponytail-mindset
28
28
 
29
29
  ---
30
30
 
31
- ## Skill Architecture (Context Efficiency)
31
+ ## Skill Architecture (High Fidelity & Progressive Disclosure)
32
32
 
33
- Skills are loaded on-demand. To keep the agent context window efficient:
34
- 1. **Keep `SKILL.md` under 500 lines**: Put detailed reference material in separate files.
35
- 2. **Use progressive disclosure**: Use a `references/` directory for deep context and load those files only when specifically needed by the task.
36
- 3. **Use `scripts/`**: Place executable scripts in a `scripts/` directory alongside the skill.
33
+ Skills provide deep, production-ready engineering standards. To maximize instruction adherence:
34
+ 1. **High-Fidelity Guidance**: Skills must be complete, self-contained, and comprehensive. Never truncate essential rules, edge cases, or code examples for artificial brevity.
35
+ 2. **Progressive Disclosure**: Use a `references/` directory for deep domain specifications, detailed schemas, and specialized manuals, loading them when the task explicitly targets those areas.
36
+ 3. **Executable Scripts**: Place verification and automation scripts in a `scripts/` directory alongside the skill.
37
37
 
38
38
  ## Skill Registry
39
39
 
@@ -43,10 +43,10 @@ These 7 skills are always present in ContextOS Core:
43
43
 
44
44
  | Skill | File | Activate When |
45
45
  |-------|------|--------------|
46
- | **engineering-workflow** | `engineering-workflow/SKILL.md` | **Every task** — defines the DEFINE→PLAN→BUILD→VERIFY→REVIEW→SHIP pipeline |
47
- | **gstack-roles** | `gstack-roles/SKILL.md` | **Every task** — declare your specialist role before each phase |
48
- | **ponytail-mindset** | `ponytail-mindset/SKILL.md` | **Every BUILD phase** — run the 7-rung ladder before writing any code |
49
- | **gemini-precision** | `gemini-precision/SKILL.md` | **All Gemini tasks** — zero assumptions, zero placeholders, surgical blast radius, test proof |
46
+ | **engineering-workflow** | `engineering-workflow/SKILL.md` | **Every task** - defines the DEFINE→PLAN→BUILD→VERIFY→REVIEW→SHIP pipeline |
47
+ | **gstack-roles** | `gstack-roles/SKILL.md` | **Every task** - declare your specialist role before each phase |
48
+ | **ponytail-mindset** | `ponytail-mindset/SKILL.md` | **Every BUILD phase** - run the 7-rung ladder before writing any code |
49
+ | **gemini-precision** | `gemini-precision/SKILL.md` | **All Gemini tasks** - zero assumptions, zero placeholders, surgical blast radius, test proof |
50
50
  | **security** | `security/SKILL.md` | Any feature with auth, data access, user input, external integration |
51
51
  | **context-os** | `context-os/SKILL.md` | Managing context rules, compiler pipelines, project policies |
52
52
  | **context-manager** | `context-manager/SKILL.md` | Context selection, dynamic skill resolution, project graph traversal |
@@ -58,14 +58,14 @@ The following domain skills are available in the extended catalog and can be add
58
58
  | Domain | Skills | Install Command |
59
59
  |--------|--------|-----------------|
60
60
  | **Frontend** | `react`, `react-best-practices`, `nextjs`, `typescript`, `ui-ux-pro`, `impeccable-design`, `state-management`, `ui-design`, `ux-design`, `web-accessibility`, `brutalist-design`, `minimalist-design`, `soft-design`, `redesign-audit` | `contextos skill add <name>` |
61
- | **Backend** | `system-design`, `node`, `fastapi`, `nestjs`, `microservices`, `ddd`, `database` | `contextos skill add <name>` |
62
- | **Cross-Cutting** | `testing`, `docker`, `decisions`, `architecture-diagrams`, `adapters`, `generators`, `graphify`, `performance`, `vercel-optimize` | `contextos skill add <name>` |
61
+ | **Backend** | `system-design`, `api-design`, `node`, `fastapi`, `nestjs`, `microservices`, `ddd`, `database` | `contextos skill add <name>` |
62
+ | **Cross-Cutting** | `testing`, `docker`, `ci-cd`, `terraform`, `security-audit`, `decisions`, `architecture-diagrams`, `adapters`, `generators`, `graphify`, `performance`, `vercel-optimize` | `contextos skill add <name>` |
63
63
 
64
64
  ---
65
65
 
66
66
  ## Automatic Skill Activation Rules (Proactive Routing)
67
67
 
68
- The following rules are **deterministic** — no judgment needed. If the condition is true, the skill is loaded.
68
+ The following rules are **deterministic** - no judgment needed. If the condition is true, the skill is loaded.
69
69
 
70
70
  > **Availability Guard**: Load only skills that are physically installed in `.agents/core/skills/`. For uninstalled catalog skills, rely on core skills (`engineering-workflow`, `ponytail-mindset`, `gemini-precision`, `security`) and recommend `contextos skill add <name>` when deep domain checklists are needed.
71
71
 
@@ -159,6 +159,22 @@ role: Staff Engineer (Orchestrator)
159
159
  trigger: "graphify" OR "codebase graph" OR "project graph" OR "map codebase" OR "knowledge graph" OR "построй граф проекта"
160
160
  load: [graphify, system-design, context-manager]
161
161
  role: Architect
162
+
163
+ trigger: "security audit" OR "vulnerability" OR "pentest"
164
+ load: [security-audit, security, engineering-workflow]
165
+ role: Chief Security Officer (audit) -> Senior Developer (build)
166
+
167
+ trigger: "api design" OR "REST API" OR "contract" OR "openapi"
168
+ load: [api-design, system-design, engineering-workflow]
169
+ role: Architect (plan) -> Senior Developer (build)
170
+
171
+ trigger: "terraform" OR "opentofu" OR "iac" OR "infrastructure"
172
+ load: [terraform, decisions, engineering-workflow]
173
+ role: DevOps Engineer
174
+
175
+ trigger: "ci/cd" OR "github actions" OR "pipeline" OR "quality gates"
176
+ load: [ci-cd, engineering-workflow]
177
+ role: DevOps Engineer
162
178
  ```
163
179
 
164
180
  ### By Technology Detected in Codebase
@@ -178,7 +194,7 @@ files: "components/ui/*" present → shadcn detected, apply K9-K11 rules from im
178
194
 
179
195
  ---
180
196
 
181
- ## Pipeline — Phase-by-Phase Rules
197
+ ## Pipeline - Phase-by-Phase Rules
182
198
 
183
199
  Every task MUST follow these phases in order. No skipping.
184
200
 
@@ -191,7 +207,7 @@ Required output before proceeding:
191
207
  - Explicit in-scope / out-of-scope
192
208
  - List of files that will change
193
209
  - Acceptance criteria as testable statements
194
- - **STOP — do not write code until spec is reviewed**
210
+ - **STOP - do not write code until spec is reviewed**
195
211
 
196
212
  ---
197
213
 
@@ -205,7 +221,7 @@ Required output before proceeding:
205
221
  - Test requirement per task
206
222
  - Risk assessment
207
223
  - **If UI domain, read and incorporate `.interface-design/system.md` design memory**
208
- - **STOP — do not write code until plan is approved**
224
+ - **STOP - do not write code until plan is approved**
209
225
 
210
226
  ---
211
227
 
@@ -236,12 +252,12 @@ Rules:
236
252
  **Role**: `[ROLE: Staff Engineer]` + `[ROLE: Senior Designer]` if UI
237
253
  **Load**: `engineering-workflow` (code review checklist) + `impeccable-design` (if UI)
238
254
 
239
- For UI tasks — run the full impeccable-design audit:
240
- - Typography rules T1–T10
241
- - Color rules C1–C12
242
- - Layout rules L1–L11 (including z-index check)
243
- - Component rules K1–K11 (shadcn-first)
244
- - Animation rules A1–A8 (Framer Motion exception noted)
255
+ For UI tasks - run the full impeccable-design audit:
256
+ - Typography rules T1-T10
257
+ - Color rules C1-C12
258
+ - Layout rules L1-L11 (including z-index check)
259
+ - Component rules K1-K11 (shadcn-first)
260
+ - Animation rules A1-A8 (Framer Motion exception noted)
245
261
 
246
262
  ---
247
263
 
@@ -276,6 +292,10 @@ Use this table to instantly determine which skills to load:
276
292
  | Architecture visualization | `architecture-diagrams` + `system-design` | Architect |
277
293
  | Multi-agent parallel tasks | `subagent-orchestrator` + `engineering-workflow` | Staff Engineer (Orchestrator) |
278
294
  | Codebase graph / repo mapping | `graphify` + `context-manager` + `system-design` | Architect |
295
+ | Security audit / pen-test | `security-audit` + `security` + `engineering-workflow` | Chief Security Officer |
296
+ | API contract / interface design | `api-design` + `system-design` + `engineering-workflow` | Architect |
297
+ | Terraform / IaC | `terraform` + `decisions` + `engineering-workflow` | DevOps Engineer |
298
+ | CI/CD pipeline automation | `ci-cd` + `engineering-workflow` | DevOps Engineer |
279
299
 
280
300
  ---
281
301
 
@@ -326,18 +346,18 @@ These rules apply regardless of which skills are loaded:
326
346
 
327
347
  ### Code Quality
328
348
  - Business logic NEVER lives in API route handlers → always in `services/` or `use-cases/`
329
- - No `// TODO` in committed code — create a tracked issue instead
349
+ - No `// TODO` in committed code - create a tracked issue instead
330
350
  - All async operations have explicit error handling
331
- - No secrets hardcoded — use environment variables
351
+ - No secrets hardcoded - use environment variables
332
352
 
333
353
  ### Security
334
- - Auth check BEFORE any data access — no exceptions
354
+ - Auth check BEFORE any data access - no exceptions
335
355
  - All user input validated and sanitized before processing
336
- - SQL queries use parameterized form — no string concatenation
356
+ - SQL queries use parameterized form - no string concatenation
337
357
 
338
358
  ### Design
339
- - No arbitrary Tailwind values (`gap-[17px]`) — use scale utilities
340
- - No hardcoded z-indexes (`z-[999]`) — use Radix/shadcn Portals
359
+ - No arbitrary Tailwind values (`gap-[17px]`) - use scale utilities
360
+ - No hardcoded z-indexes (`z-[999]`) - use Radix/shadcn Portals
341
361
  - Every list/table/feed has a designed empty state
342
362
 
343
363
  ### Engineering
@@ -348,10 +368,10 @@ These rules apply regardless of which skills are loaded:
348
368
 
349
369
  ### Completion Protocol
350
370
  When finishing a workflow or task, always report your final status clearly using one of the following:
351
- - **DONE** — completed with evidence.
352
- - **DONE_WITH_CONCERNS** — completed, but list specific concerns.
353
- - **BLOCKED** — cannot proceed; state blocker and what was tried.
354
- - **NEEDS_CONTEXT** — missing info; state exactly what is needed.
371
+ - **DONE** - completed with evidence.
372
+ - **DONE_WITH_CONCERNS** - completed, but list specific concerns.
373
+ - **BLOCKED** - cannot proceed; state blocker and what was tried.
374
+ - **NEEDS_CONTEXT** - missing info; state exactly what is needed.
355
375
 
356
376
  ---
357
377
 
@@ -7,6 +7,7 @@ const fs = require('fs');
7
7
  const path = require('path');
8
8
  const { AGENTS_MD_PATH, collectSkillDirectories, extractYamlField, stripFrontmatter } = require('../shared.js');
9
9
  const { registerAdapter, applyArtifacts, createProvenanceHeader } = require('../pure-compiler.js');
10
+ const YAML = require('../../compiler/vendor/yaml.js');
10
11
 
11
12
  const GENERATOR_ID = 'aider@2';
12
13
 
@@ -43,7 +44,7 @@ function buildSkillSection(skillDir) {
43
44
  }
44
45
 
45
46
  const descLine = description ? `> ${description.replace(/\r?\n+/g, ' ').trim()}\n` : '';
46
- const skillRef = `*Source: \`.agents/skills/${skillName}/SKILL.md\` — Load via \`/read .agents/skills/${skillName}/SKILL.md\`*\n`;
47
+ const skillRef = `*Source: \`.agents/skills/${skillName}/SKILL.md\` - Load via \`/read .agents/skills/${skillName}/SKILL.md\`*\n`;
47
48
  return `\n## Skill: ${title}\n${descLine}${skillRef}`;
48
49
  }
49
50
 
@@ -68,23 +69,49 @@ function render(context) {
68
69
  }, 'markdown');
69
70
 
70
71
  // 1. .aider.conf.yml
71
- const aiderConfContent = [
72
- yamlProv,
73
- '# Load project conventions as a read-only context file on every session',
74
- 'read:',
75
- ' - CONVENTIONS.md',
76
- '',
77
- '# Auto commit edits with standard git format',
78
- 'auto-commits: true',
79
- 'dirty-commits: true',
80
- '',
81
- ].join('\n');
72
+ const existingAiderConfPath = path.join(projectRoot, '.aider.conf.yml');
73
+ let aiderConfContent = '';
74
+
75
+ if (fs.existsSync(existingAiderConfPath)) {
76
+ try {
77
+ const rawUserConf = fs.readFileSync(existingAiderConfPath, 'utf8');
78
+ const parsed = YAML.parse(rawUserConf) || {};
79
+
80
+ if (!parsed.read) {
81
+ parsed.read = ['CONVENTIONS.md'];
82
+ } else if (Array.isArray(parsed.read)) {
83
+ if (!parsed.read.includes('CONVENTIONS.md')) {
84
+ parsed.read.push('CONVENTIONS.md');
85
+ }
86
+ } else if (typeof parsed.read === 'string') {
87
+ if (parsed.read !== 'CONVENTIONS.md') {
88
+ parsed.read = [parsed.read, 'CONVENTIONS.md'];
89
+ }
90
+ }
91
+
92
+ aiderConfContent = yamlProv + '\n' + YAML.stringify(parsed);
93
+ } catch (err) {
94
+ throw new Error(`Failed to parse existing .aider.conf.yml: ${err.message}. Aborting to protect existing configuration from data loss.`);
95
+ }
96
+ } else {
97
+ aiderConfContent = [
98
+ yamlProv,
99
+ '# Load project conventions as a read-only context file on every session',
100
+ 'read:',
101
+ ' - CONVENTIONS.md',
102
+ '',
103
+ '# Auto commit edits with standard git format',
104
+ 'auto-commits: true',
105
+ 'dirty-commits: true',
106
+ '',
107
+ ].join('\n');
108
+ }
82
109
 
83
110
  // 2. CONVENTIONS.md
84
111
  const convSections = [];
85
112
  convSections.push(
86
113
  mdProv +
87
- `# ContextOS — Project Conventions for Aider\n\n` +
114
+ `# ContextOS - Project Conventions for Aider\n\n` +
88
115
  `> **Core law: Do not read everything. Read only what the current task requires.**\n\n`
89
116
  );
90
117
 
@@ -97,7 +124,7 @@ function render(context) {
97
124
  `Skills are loaded on demand. Use \`/read .agents/skills/<skill>/SKILL.md\` when needed.\n\n` +
98
125
  `### Skill Index\n`);
99
126
 
100
- const skills = collectSkillDirectories(context?.profile);
127
+ const skills = collectSkillDirectories(context?.profile, context?.projectRoot);
101
128
  for (const skill of skills) {
102
129
  const section = buildSkillSection(skill);
103
130
  if (section) convSections.push(section);
@@ -9,13 +9,15 @@ const { collectSkillDirectories, readMeaningfulMarkdown } = require('../shared.j
9
9
  const { registerAdapter, applyArtifacts } = require('../pure-compiler.js');
10
10
 
11
11
  const GENERATOR_ID = 'claude@2';
12
+ const CLAUDE_START_MARKER = '<!-- CONTEXTOS:START -->';
13
+ const CLAUDE_END_MARKER = '<!-- CONTEXTOS:END -->';
12
14
 
13
15
  function describe() {
14
16
  return {
15
17
  name: 'claude',
16
18
  version: '2.0.0',
17
- description: 'Compiles clean markdown skills for Claude Code CLI',
18
- targetPattern: '.agents/generated/claude/skills/**/SKILL.md',
19
+ description: 'Compiles clean markdown skills for Claude Code CLI and manages CLAUDE.md entrypoint',
20
+ targetPattern: '{CLAUDE.md,.agents/generated/claude/skills/**/SKILL.md}',
19
21
  };
20
22
  }
21
23
 
@@ -53,8 +55,52 @@ function renderClaudeSkill(skillDir, context) {
53
55
  };
54
56
  }
55
57
 
58
+ function renderClaudeRootIndex(skills, context) {
59
+ const projectRoot = context?.projectRoot || '.';
60
+ const claudePath = path.join(projectRoot, 'CLAUDE.md');
61
+ let existingContent = '';
62
+ if (fs.existsSync(claudePath)) {
63
+ try {
64
+ existingContent = fs.readFileSync(claudePath, 'utf8');
65
+ } catch {}
66
+ }
67
+
68
+ const skillEntries = skills.map(skillDir => {
69
+ const name = path.basename(skillDir);
70
+ return `- [${name}](.agents/generated/claude/skills/${name}/SKILL.md)`;
71
+ }).join('\n');
72
+
73
+ const managedBlock = `${CLAUDE_START_MARKER}
74
+ <!-- Do not edit this section directly. Synchronized by ContextOS. -->
75
+ # ContextOS Agent Governance
76
+
77
+ The following skills are managed by ContextOS:
78
+ ${skillEntries}
79
+ ${CLAUDE_END_MARKER}`;
80
+
81
+ let finalContent;
82
+ if (existingContent.includes(CLAUDE_START_MARKER)) {
83
+ const regex = new RegExp(`${CLAUDE_START_MARKER}[\\s\\S]*?${CLAUDE_END_MARKER}`);
84
+ finalContent = existingContent.replace(regex, managedBlock);
85
+ } else if (existingContent.trim()) {
86
+ finalContent = `${existingContent.trimEnd()}\n\n${managedBlock}\n`;
87
+ } else {
88
+ finalContent = `${managedBlock}\n`;
89
+ }
90
+
91
+ return {
92
+ path: 'CLAUDE.md',
93
+ content: finalContent.replace(/\r\n/g, '\n'),
94
+ mediaType: 'text/markdown',
95
+ kind: 'generated-adapter',
96
+ generator: GENERATOR_ID,
97
+ sourceSkillIds: skills.map(s => path.basename(s)),
98
+ inputsHash: context?.sourceGraphHash || 'none',
99
+ };
100
+ }
101
+
56
102
  function render(context) {
57
- const skills = collectSkillDirectories(context?.profile);
103
+ const skills = collectSkillDirectories(context?.profile, context?.projectRoot);
58
104
  const artifacts = [];
59
105
 
60
106
  for (const skill of skills) {
@@ -62,6 +108,11 @@ function render(context) {
62
108
  if (art) artifacts.push(art);
63
109
  }
64
110
 
111
+ if (skills.length > 0) {
112
+ const rootIndex = renderClaudeRootIndex(skills, context);
113
+ if (rootIndex) artifacts.push(rootIndex);
114
+ }
115
+
65
116
  return artifacts;
66
117
  }
67
118
 
@@ -79,7 +79,7 @@ function render(context) {
79
79
  `| --- | --- | --- |\n`
80
80
  );
81
81
 
82
- const skills = collectSkillDirectories(context?.profile);
82
+ const skills = collectSkillDirectories(context?.profile, context?.projectRoot);
83
83
  for (const skill of skills) {
84
84
  const skillName = path.basename(skill);
85
85
  const yamlPath = path.join(skill, 'skill.yaml');
@@ -187,7 +187,7 @@ ${agentsMd}
187
187
  });
188
188
  }
189
189
 
190
- const skills = collectSkillDirectories(context?.profile);
190
+ const skills = collectSkillDirectories(context?.profile, context?.projectRoot);
191
191
  for (const skill of skills) {
192
192
  const mdc = generateCursorMdc(skill);
193
193
  if (mdc) {
@@ -23,6 +23,9 @@ const DRIFT_STATES = {
23
23
  ORPHAN_MANAGED_OUTPUT: 'ORPHAN_MANAGED_OUTPUT',
24
24
  ADAPTER_VERSION_MISMATCH: 'ADAPTER_VERSION_MISMATCH',
25
25
  PROFILE_MISMATCH: 'PROFILE_MISMATCH',
26
+ CORRUPT_LOCKFILE: 'CORRUPT_LOCKFILE',
27
+ EMPTY_PROJECTION: 'EMPTY_PROJECTION',
28
+ CONFIG_ERROR: 'CONFIG_ERROR',
26
29
  };
27
30
 
28
31
  /**
@@ -67,9 +70,6 @@ function computeDiffSnippet(beforeStr, afterStr, maxLines = 15) {
67
70
  function detectDrift(projectRoot, adapters = 'all', options = {}) {
68
71
  const absRoot = path.resolve(projectRoot);
69
72
  const lockManager = new LockfileV2Manager(absRoot);
70
- const lockfile = lockManager.read();
71
-
72
- const { artifacts, collisions, context } = renderAdapters(absRoot, adapters, options);
73
73
 
74
74
  const findings = {
75
75
  [DRIFT_STATES.STALE_INPUT]: [],
@@ -78,11 +78,57 @@ function detectDrift(projectRoot, adapters = 'all', options = {}) {
78
78
  [DRIFT_STATES.ORPHAN_MANAGED_OUTPUT]: [],
79
79
  [DRIFT_STATES.ADAPTER_VERSION_MISMATCH]: [],
80
80
  [DRIFT_STATES.PROFILE_MISMATCH]: [],
81
+ [DRIFT_STATES.CORRUPT_LOCKFILE]: [],
82
+ [DRIFT_STATES.EMPTY_PROJECTION]: [],
83
+ [DRIFT_STATES.CONFIG_ERROR]: [],
81
84
  };
82
85
 
83
86
  const diffs = [];
84
87
 
85
- // 1. Check Profile Mismatch
88
+ // 0. Safe lockfile load with corrupt lockfile detection
89
+ let lockfile = null;
90
+ try {
91
+ lockfile = lockManager.read();
92
+ } catch (err) {
93
+ findings[DRIFT_STATES.CORRUPT_LOCKFILE].push({
94
+ reason: `Lockfile is corrupt: ${err.message}`,
95
+ });
96
+ }
97
+
98
+ // 1. Adapter rendering with error containment
99
+ let rendered;
100
+ try {
101
+ rendered = renderAdapters(absRoot, adapters, options);
102
+ } catch (err) {
103
+ findings[DRIFT_STATES.CONFIG_ERROR].push({
104
+ reason: err.message,
105
+ });
106
+ return {
107
+ hasDrift: true,
108
+ hasError: true,
109
+ code: 2,
110
+ totalFindings: 1,
111
+ findings,
112
+ collisions: [],
113
+ diffs: [],
114
+ projectedCount: 0,
115
+ error: err.message,
116
+ };
117
+ }
118
+
119
+ const { artifacts, collisions, context } = rendered;
120
+
121
+ // 2. Empty projection check
122
+ if (artifacts.length === 0) {
123
+ const hasAgentsDir = fs.existsSync(path.join(absRoot, '.agents'));
124
+ if (hasAgentsDir) {
125
+ findings[DRIFT_STATES.EMPTY_PROJECTION].push({
126
+ reason: 'Projected artifact set is empty while .agents directory exists',
127
+ });
128
+ }
129
+ }
130
+
131
+ // 3. Check Profile Mismatch
86
132
  if (lockfile && lockfile.profile) {
87
133
  if (context.profileId && lockfile.profile.id !== context.profileId) {
88
134
  findings[DRIFT_STATES.PROFILE_MISMATCH].push({
@@ -92,7 +138,7 @@ function detectDrift(projectRoot, adapters = 'all', options = {}) {
92
138
  }
93
139
  }
94
140
 
95
- // 2. Check Stale Input (Source Graph Hash)
141
+ // 4. Check Stale Input (Source Graph Hash)
96
142
  if (lockfile && lockfile.sourceGraphHash) {
97
143
  if (context.sourceGraphHash && lockfile.sourceGraphHash !== context.sourceGraphHash) {
98
144
  findings[DRIFT_STATES.STALE_INPUT].push({
@@ -104,7 +150,7 @@ function detectDrift(projectRoot, adapters = 'all', options = {}) {
104
150
 
105
151
  const projectedPaths = new Set(artifacts.map(a => a.path));
106
152
 
107
- // 3. Inspect each projected artifact against disk and lockfile
153
+ // 5. Inspect each projected artifact against disk and lockfile
108
154
  for (const art of artifacts) {
109
155
  const fullPath = path.resolve(absRoot, art.path);
110
156
  const projectedContent = art.content.toString('utf8');
@@ -124,10 +170,13 @@ function detectDrift(projectRoot, adapters = 'all', options = {}) {
124
170
  } else {
125
171
  const diskContent = fs.readFileSync(fullPath, 'utf8');
126
172
  const diskSemanticHash = computeSemanticHash(diskContent);
173
+ const lockRecord = lockfile?.managedFiles?.[art.path];
174
+
175
+ // Check if disk matches projected render and recorded lockfile
176
+ const matchesProjection = diskSemanticHash === projectedSemanticHash;
177
+ const matchesLock = lockRecord ? diskSemanticHash === lockRecord.semanticTextSha256 : matchesProjection;
127
178
 
128
- // Check if disk matches projected render
129
- if (diskSemanticHash !== projectedSemanticHash) {
130
- const lockRecord = lockfile?.managedFiles?.[art.path];
179
+ if (!matchesProjection || !matchesLock) {
131
180
  if (lockRecord && lockRecord.semanticTextSha256 !== diskSemanticHash) {
132
181
  findings[DRIFT_STATES.MODIFIED_MANAGED_OUTPUT].push({
133
182
  path: art.path,
@@ -151,14 +200,32 @@ function detectDrift(projectRoot, adapters = 'all', options = {}) {
151
200
  }
152
201
  }
153
202
 
154
- // 4. Check for orphan files recorded in lockfile but no longer projected
203
+ // 6. Check for orphan files recorded in lockfile but no longer projected
204
+ // Task 1.4: Scoped strictly to the active adapters being checked
155
205
  if (lockfile && lockfile.managedFiles) {
206
+ const targetGenerators = new Set(artifacts.map(a => a.generator));
207
+ const adapterList = adapters === 'all' ? null : (Array.isArray(adapters) ? adapters : [adapters]);
208
+ const allowedPrefixes = adapterList ? adapterList.map(a => `${a}@`) : null;
209
+
156
210
  for (const [recordedPath, meta] of Object.entries(lockfile.managedFiles)) {
211
+ if (meta && meta.generator && allowedPrefixes) {
212
+ const matchesTarget = targetGenerators.has(meta.generator) ||
213
+ allowedPrefixes.some(p => meta.generator.startsWith(p));
214
+ if (!matchesTarget) {
215
+ continue; // Skip files from adapters not currently being verified
216
+ }
217
+ }
218
+
219
+ if (meta && meta.kind && meta.kind !== 'generated-adapter') {
220
+ continue;
221
+ }
222
+
157
223
  if (!projectedPaths.has(recordedPath)) {
158
224
  const fullRecorded = path.resolve(absRoot, recordedPath);
159
225
  if (fs.existsSync(fullRecorded)) {
160
226
  findings[DRIFT_STATES.ORPHAN_MANAGED_OUTPUT].push({
161
227
  path: recordedPath,
228
+ generator: meta.generator,
162
229
  reason: 'File recorded in lockfile is no longer generated by active skills/profile',
163
230
  });
164
231
  diffs.push({
@@ -178,9 +245,18 @@ function detectDrift(projectRoot, adapters = 'all', options = {}) {
178
245
 
179
246
  const totalFindings = Object.values(findings).reduce((acc, list) => acc + list.length, 0);
180
247
  const hasDrift = totalFindings > 0 || collisions.length > 0;
248
+ const hasError = findings[DRIFT_STATES.CORRUPT_LOCKFILE].length > 0 ||
249
+ findings[DRIFT_STATES.EMPTY_PROJECTION].length > 0 ||
250
+ findings[DRIFT_STATES.CONFIG_ERROR].length > 0;
251
+ const code = hasError ? 2 : (hasDrift ? 1 : 0);
252
+ const status = hasError ? 'error' : (hasDrift ? 'drift' : 'pass');
181
253
 
182
254
  return {
255
+ schemaVersion: '2.0.0',
256
+ status,
183
257
  hasDrift,
258
+ hasError,
259
+ code,
184
260
  totalFindings,
185
261
  findings,
186
262
  collisions,
@@ -103,7 +103,7 @@ ${mergedContent.trimStart()}
103
103
  }
104
104
 
105
105
  function render(context) {
106
- const skills = collectSkillDirectories(context?.profile);
106
+ const skills = collectSkillDirectories(context?.profile, context?.projectRoot);
107
107
  const artifacts = [];
108
108
 
109
109
  for (const skill of skills) {
@@ -86,11 +86,22 @@ function loadCompilerContext(projectRoot, options = {}) {
86
86
 
87
87
  // 2. Profile v2
88
88
  let profile = null;
89
- try {
90
- const profiles = require('../profiles.js');
91
- profile = options.profile ? profiles.getProfile(options.profile, absRoot) : profiles.getActiveProfile(absRoot);
92
- } catch {
93
- profile = null;
89
+ const profiles = require('../profiles.js');
90
+ if (options.profile) {
91
+ try {
92
+ profile = profiles.getProfile(options.profile, absRoot);
93
+ } catch (err) {
94
+ throw new Error(`Failed to load profile '${options.profile}': ${err.message}`);
95
+ }
96
+ if (!profile) {
97
+ throw new Error(`Profile '${options.profile}' was specified but does not exist.`);
98
+ }
99
+ } else {
100
+ try {
101
+ profile = profiles.getActiveProfile(absRoot);
102
+ } catch {
103
+ profile = null;
104
+ }
94
105
  }
95
106
 
96
107
  // 3. Workspace Graph
@@ -139,6 +150,13 @@ function registerAdapter(name, adapter) {
139
150
  adaptersRegistry.set(name, adapter);
140
151
  }
141
152
 
153
+ /**
154
+ * Unregisters an adapter from the pure compiler registry.
155
+ */
156
+ function unregisterAdapter(name) {
157
+ adaptersRegistry.delete(name);
158
+ }
159
+
142
160
  /**
143
161
  * Retrieves a registered adapter.
144
162
  */
@@ -165,9 +183,10 @@ function listAdapters() {
165
183
  */
166
184
  function renderAdapters(projectRoot, adapterNames = 'all', options = {}) {
167
185
  const context = loadCompilerContext(projectRoot, options);
168
- const targets = adapterNames === 'all'
186
+ const rawTargets = adapterNames === 'all'
169
187
  ? listAdapters()
170
188
  : (Array.isArray(adapterNames) ? adapterNames : [adapterNames]);
189
+ const targets = rawTargets.flatMap(a => (typeof a === 'string' && a.includes(',') ? a.split(',').map(s => s.trim()).filter(Boolean) : a));
171
190
 
172
191
  const allArtifacts = [];
173
192
  const pathToArtifact = new Map();
@@ -436,8 +455,11 @@ module.exports = {
436
455
  createProvenanceHeader,
437
456
  loadCompilerContext,
438
457
  registerAdapter,
458
+ unregisterAdapter,
439
459
  getAdapter,
440
460
  listAdapters,
441
461
  renderAdapters,
442
462
  applyArtifacts,
463
+ computeExactHash,
464
+ computeSemanticHash,
443
465
  };
@@ -12,17 +12,26 @@ const AGENTS_MD_PATH = path.join(AGENTS_DIR, 'AGENTS.md');
12
12
  * Plugins intentionally live outside `core/skills`, so adapters must use this
13
13
  * helper rather than enumerate the core directory themselves.
14
14
  */
15
- function collectSkillDirectories(overrideProfile = null) {
15
+ function collectSkillDirectories(overrideProfile = null, projectRoot = null) {
16
+ let profile = overrideProfile;
17
+ let root = projectRoot;
18
+
19
+ if (overrideProfile && typeof overrideProfile === 'object') {
20
+ if (overrideProfile.projectRoot && !root) {
21
+ root = overrideProfile.projectRoot;
22
+ }
23
+ }
24
+
25
+ const effectiveRoot = root ? path.resolve(root) : process.cwd();
16
26
  const plugins = require(path.join(AGENTS_DIR, 'plugins.js'));
17
- let dirs = plugins.collectAllSkillDirs()
27
+ let dirs = plugins.collectAllSkillDirs(effectiveRoot)
18
28
  .filter(dir => fs.existsSync(dir) && fs.statSync(dir).isDirectory())
19
29
  .sort((a, b) => path.basename(a).localeCompare(path.basename(b)));
20
30
 
21
- let profile = overrideProfile;
22
31
  if (!profile) {
23
32
  try {
24
33
  const profilesEngine = require(path.join(AGENTS_DIR, 'profiles.js'));
25
- profile = profilesEngine.getActiveProfile();
34
+ profile = profilesEngine.getActiveProfile(effectiveRoot);
26
35
  } catch {
27
36
  profile = null;
28
37
  }
@@ -95,7 +95,7 @@ function render(context) {
95
95
  `### Available Skills\n`
96
96
  );
97
97
 
98
- const skills = collectSkillDirectories(context?.profile);
98
+ const skills = collectSkillDirectories(context?.profile, context?.projectRoot);
99
99
  for (const skill of skills) {
100
100
  const res = buildSkillSection(skill);
101
101
  if (res) {