contextos-agents 1.6.0 → 1.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (88) hide show
  1. package/.agents/AGENTS.md +5 -0
  2. package/.agents/adapters/aider/export.js +4 -2
  3. package/.agents/adapters/copilot/export.js +4 -2
  4. package/.agents/adapters/cursor/export.js +48 -12
  5. package/.agents/adapters/zed/export.js +53 -14
  6. package/.agents/core/profiles/mvp.yaml +1 -0
  7. package/.agents/core/skills/adapters/skill.yaml +6 -0
  8. package/.agents/core/skills/architecture-diagrams/skill.yaml +4 -0
  9. package/.agents/core/skills/brutalist-design/skill.yaml +4 -0
  10. package/.agents/core/skills/context-manager/references/context-rules.md +59 -0
  11. package/.agents/core/skills/context-manager/skill.yaml +7 -0
  12. package/.agents/core/skills/context-os/skill.yaml +11 -0
  13. package/.agents/core/skills/database/skill.yaml +6 -0
  14. package/.agents/core/skills/ddd/skill.yaml +7 -0
  15. package/.agents/core/skills/decisions/skill.yaml +6 -0
  16. package/.agents/core/skills/docker/skill.yaml +6 -0
  17. package/.agents/core/skills/engineering-workflow/SKILL.md +1 -1
  18. package/.agents/core/skills/engineering-workflow/skill.yaml +6 -0
  19. package/.agents/core/skills/fastapi/skill.yaml +7 -0
  20. package/.agents/core/skills/gemini-precision/SKILL.md +4 -0
  21. package/.agents/core/skills/gemini-precision/skill.yaml +4 -0
  22. package/.agents/core/skills/generators/skill.yaml +15 -0
  23. package/.agents/core/skills/graphify/SKILL.md +2 -2
  24. package/.agents/core/skills/graphify/skill.yaml +6 -1
  25. package/.agents/core/skills/gstack-roles/SKILL.md +3 -1
  26. package/.agents/core/skills/gstack-roles/skill.yaml +6 -0
  27. package/.agents/core/skills/impeccable-design/skill.yaml +6 -0
  28. package/.agents/core/skills/interview-me/skill.yaml +4 -0
  29. package/.agents/core/skills/microservices/skill.yaml +7 -0
  30. package/.agents/core/skills/minimalist-design/skill.yaml +4 -0
  31. package/.agents/core/skills/nestjs/skill.yaml +7 -0
  32. package/.agents/core/skills/nextjs/skill.yaml +7 -0
  33. package/.agents/core/skills/node/skill.yaml +7 -0
  34. package/.agents/core/skills/performance/skill.yaml +7 -0
  35. package/.agents/core/skills/ponytail-mindset/skill.yaml +6 -0
  36. package/.agents/core/skills/react/skill.yaml +7 -0
  37. package/.agents/core/skills/react-best-practices/skill.yaml +4 -0
  38. package/.agents/core/skills/redesign-audit/skill.yaml +4 -0
  39. package/.agents/core/skills/security/skill.yaml +7 -0
  40. package/.agents/core/skills/soft-design/skill.yaml +4 -0
  41. package/.agents/core/skills/state-management/skill.yaml +6 -0
  42. package/.agents/core/skills/subagent-orchestrator/SKILL.md +17 -0
  43. package/.agents/core/skills/subagent-orchestrator/skill.yaml +4 -0
  44. package/.agents/core/skills/system-design/skill.yaml +7 -0
  45. package/.agents/core/skills/testing/skill.yaml +6 -0
  46. package/.agents/core/skills/typescript/skill.yaml +7 -0
  47. package/.agents/core/skills/ui-design/skill.yaml +7 -0
  48. package/.agents/core/skills/ui-ux-pro/skill.yaml +6 -0
  49. package/.agents/core/skills/ux-design/skill.yaml +7 -0
  50. package/.agents/core/skills/vercel-optimize/scripts/collect-signals.mjs +131 -0
  51. package/.agents/core/skills/vercel-optimize/scripts/gate-investigations.mjs +142 -0
  52. package/.agents/core/skills/vercel-optimize/scripts/merge-signals.mjs +143 -0
  53. package/.agents/core/skills/vercel-optimize/scripts/scan-codebase.mjs +174 -0
  54. package/.agents/core/skills/vercel-optimize/skill.yaml +8 -0
  55. package/.agents/core/skills/web-accessibility/skill.yaml +7 -0
  56. package/.agents/ctx.js +44 -0
  57. package/.agents/doctor.js +193 -4
  58. package/.agents/generated/claude/skills/engineering-workflow/SKILL.md +1 -1
  59. package/.agents/generated/claude/skills/gemini-precision/SKILL.md +4 -0
  60. package/.agents/generated/claude/skills/graphify/SKILL.md +1 -1
  61. package/.agents/generated/claude/skills/gstack-roles/SKILL.md +3 -1
  62. package/.agents/generated/claude/skills/subagent-orchestrator/SKILL.md +17 -0
  63. package/.agents/generated/gemini/skills/engineering-workflow/SKILL.md +1 -1
  64. package/.agents/generated/gemini/skills/gemini-precision/SKILL.md +4 -0
  65. package/.agents/generated/gemini/skills/graphify/SKILL.md +2 -2
  66. package/.agents/generated/gemini/skills/gstack-roles/SKILL.md +3 -1
  67. package/.agents/generated/gemini/skills/subagent-orchestrator/SKILL.md +17 -0
  68. package/.agents/plugins/contextos/hooks.json +25 -0
  69. package/.agents/plugins/contextos/plugin.json +19 -0
  70. package/.agents/plugins.js +180 -20
  71. package/.agents/profiles.js +26 -0
  72. package/.agents/resolver.js +150 -30
  73. package/.agents/stats.js +22 -9
  74. package/.agents/validate.js +152 -13
  75. package/README.md +77 -47
  76. package/bin/commands/uninstall.js +207 -0
  77. package/bin/commands/update.js +262 -0
  78. package/bin/commands.js +305 -0
  79. package/bin/index.js +275 -119
  80. package/bin/lib/detector.js +106 -0
  81. package/bin/lib/lockfile.js +251 -0
  82. package/bin/lib/safe-writer.js +259 -0
  83. package/package.json +6 -9
  84. package/registry.json +13 -5
  85. package/registry.schema.json +3 -1
  86. package/.agents/mcp/runtime.py +0 -470
  87. package/.agents/mcp/server.mjs +0 -189386
  88. package/benchmarks/gemini-issues.js +0 -533
package/README.md CHANGED
@@ -12,7 +12,8 @@ This is an open-source set of skills and behavioral rules for AI assistants. The
12
12
  You do not need to clone anything manually. Just open your terminal in the root of your project and run:
13
13
 
14
14
  ```bash
15
- npx contextos-agents
15
+ npx contextos
16
+ # or: npx contextos-agents
16
17
  ```
17
18
 
18
19
  The script will automatically detect your project tech stack, create the `.agents` folder, configure skills, and compile them for your AI agent.
@@ -20,15 +21,16 @@ The script will automatically detect your project tech stack, create the `.agent
20
21
  ### Options
21
22
 
22
23
  ```bash
23
- npx contextos-agents --help # Show all options
24
- npx contextos-agents --version # Show version
25
- npx contextos-agents --profile mvp # Install with specific profile (mvp, startup, enterprise, frontend, backend)
26
- npx contextos-agents --auto # Auto-detect tech stack and apply recommended profile
27
- npx contextos-agents --with-mcp # Install with MCP execution server enabled (.agents/mcp/)
28
- npx contextos-agents setup-mcp # Add MCP server to an existing .agents/ project
29
- npx contextos-agents --dry-run # Preview what will be installed
30
- npx contextos-agents --force # Overwrite an existing .agents/ folder
31
- npx contextos-agents --skip-compile # Skip auto-compilation step
24
+ npx contextos --help # Show all options
25
+ npx contextos --version # Show version
26
+ npx contextos --minimal # Install only 5 core skills (lightweight footprint)
27
+ npx contextos --profile mvp # Install with specific profile (mvp, startup, enterprise, frontend, backend)
28
+ npx contextos --auto # Auto-detect tech stack and apply recommended profile
29
+ npx contextos --with-mcp # Install with MCP execution server enabled (.agents/mcp/)
30
+ npx contextos setup-mcp # Add MCP server to an existing .agents/ project
31
+ npx contextos --dry-run # Preview what will be installed
32
+ npx contextos --force # Overwrite an existing .agents/ folder
33
+ npx contextos --skip-compile # Skip auto-compilation step
32
34
  ```
33
35
 
34
36
  ## Why ContextOS?
@@ -70,16 +72,17 @@ ContextOS allows you to tailor your AI rules to the project lifecycle and archit
70
72
 
71
73
  ```bash
72
74
  # Auto-detect tech stack in the current project
73
- node .agents/ctx.js detect
75
+ contextos detect
76
+ # or: node .agents/ctx.js detect
74
77
 
75
78
  # List available profiles and current active profile
76
- node .agents/ctx.js profile list
79
+ contextos profile list
77
80
 
78
81
  # Apply a profile
79
- node .agents/ctx.js profile apply mvp
82
+ contextos profile apply mvp
80
83
 
81
84
  # Recompile all agent exports for the active profile
82
- node .agents/ctx.js export all
85
+ contextos export all
83
86
  ```
84
87
 
85
88
  ## What's Inside?
@@ -146,9 +149,9 @@ ContextOS maps development phases directly to slash commands in your AI chat:
146
149
  | `/review` | Staff Engineer + Designer | 5-axis quality gate (correctness, architecture, security, performance, design) |
147
150
  | `/ship` | Release Engineer | Verify clean CI, lint checks, docs, and rollback plan before merging |
148
151
 
149
- ## Dynamic Skill Resolution & CLI (`ctx.js`)
152
+ ## Dynamic Skill Resolution & Unified CLI (`contextos` / `ctx.js`)
150
153
 
151
- The `.agents/ctx.js` file is the **Context Engine** — it resolves minimal skills on the fly and compiles exports for AI assistants.
154
+ ContextOS provides a unified CLI (`contextos` or `npx contextos`) and local engine (`.agents/ctx.js`) to resolve minimal skills on the fly, run health diagnostics, and compile exports for AI assistants.
152
155
 
153
156
  ### Dynamic Skill Resolution (`resolve` & `index`)
154
157
 
@@ -156,48 +159,74 @@ To prevent context bloat, ContextOS dynamically resolves the exact 2–4 skills
156
159
 
157
160
  ```bash
158
161
  # Resolve skills for a task description (English):
159
- node .agents/ctx.js resolve "Build an accessible modal component with React and Tailwind"
162
+ contextos resolve "Build an accessible modal component with React and Tailwind"
160
163
 
161
164
  # Output:
162
165
  # [DOMAIN: Frontend] [PHASE: Build] [ROLE: Senior Developer]
163
166
  # Skills loaded: ponytail-mindset, engineering-workflow, react, ui-ux-pro, web-accessibility
164
167
 
165
168
  # Multilingual support (Russian):
166
- node .agents/ctx.js resolve "создай модальное окно авторизации и напиши юнит-тесты"
169
+ contextos resolve "создай модальное окно авторизации и напиши юнит-тесты"
167
170
 
168
171
  # Output:
169
172
  # [DOMAIN: Frontend] [PHASE: Build] [ROLE: Senior Developer]
170
173
  # Skills loaded: ponytail-mindset, engineering-workflow, react, ui-ux-pro, security, testing
171
174
 
172
- # Resolve skills based on active files:
173
- node .agents/ctx.js resolve --files "app/api/auth/route.ts"
175
+ # Resolve skills based on active files (hybrid AST & config analysis):
176
+ contextos resolve --files "app/api/auth/route.ts"
174
177
 
175
178
  # Generate/update progressive lightweight skills index:
176
- node .agents/ctx.js index
179
+ contextos index
177
180
 
178
181
  # Clean up lingering .swarm-worktrees directories and orphaned swarm/* git branches:
179
- node .agents/ctx.js clean-worktrees
182
+ contextos clean-worktrees
183
+ ```
184
+
185
+ ### Diagnostic Health Check (`contextos doctor`)
186
+
187
+ Run a comprehensive pre-flight verification across your repository to ensure valid skills, profile alignment, symlinks, git worktree status, and compiler synchronization:
188
+
189
+ ```bash
190
+ contextos doctor
191
+ # or: npx contextos doctor
192
+ ```
193
+
194
+ ### Context Savings Analytics (`contextos stats`)
195
+
196
+ Measure your real token savings. Compares monolithic prompt injection against ContextOS dynamic skill resolution across frontend, backend, security, and full-stack tasks:
197
+
198
+ ```bash
199
+ contextos stats
200
+ ```
201
+
202
+ ### Continuous Auto-Sync Daemon (`contextos watch`)
203
+
204
+ Watch your source skills in `.agents/core/skills/` and automatically recompile adapter outputs (`.cursorrules`, `.zed/rules.md`, `.github/copilot-instructions.md`, etc.) upon saving:
205
+
206
+ ```bash
207
+ contextos watch
208
+ # or: npm run watch
180
209
  ```
181
210
 
182
211
  ### Supported Agents & Compilation
183
212
 
184
213
  | Agent | Command | Output Format |
185
214
  |-------|---------|---------------|
186
- | **Gemini / Antigravity** | `export gemini` | `.agents/generated/gemini/skills/` |
187
- | **Claude Code** | `export claude` | `.agents/generated/claude/skills/` |
188
- | **Cursor IDE** | `export cursor` | `.cursor/rules/*.mdc` (modular globs) + `.cursorrules` |
189
- | **GitHub Copilot** | `export copilot` | `.github/copilot-instructions.md` |
190
- | **Aider** | `export aider` | `.aider.conf.yml` + `CONVENTIONS.md` |
191
- | **Zed IDE** | `export zed` | `.zed/rules.md` + `.zed/prompts/*.md` |
215
+ | **Gemini / Antigravity** | `contextos export gemini` | `.agents/generated/gemini/skills/` |
216
+ | **Claude Code** | `contextos export claude` | `.agents/generated/claude/skills/` |
217
+ | **Cursor IDE** | `contextos export cursor` | `.cursor/rules/*.mdc` (modular globs) + `.cursorrules` |
218
+ | **GitHub Copilot** | `contextos export copilot` | `.github/copilot-instructions.md` |
219
+ | **Aider** | `contextos export aider` | `.aider.conf.yml` + `CONVENTIONS.md` |
220
+ | **Zed IDE** | `contextos export zed` | `.zed/rules.md` + `.zed/prompts/*.md` |
192
221
 
193
222
  ```bash
194
- node .agents/ctx.js export all # Compile for all agents
195
- node .agents/ctx.js export gemini # Compile for Gemini / Antigravity
196
- node .agents/ctx.js export claude # Compile for Claude Code
197
- node .agents/ctx.js export cursor # Compile for Cursor (.cursor/rules/*.mdc)
198
- node .agents/ctx.js export copilot # Compile for GitHub Copilot
199
- node .agents/ctx.js export aider # Compile for Aider
200
- node .agents/ctx.js export zed # Compile for Zed IDE
223
+ contextos export all # Compile for all agents (or: node .agents/ctx.js export all)
224
+ contextos export gemini # Compile for Gemini / Antigravity
225
+ contextos export claude # Compile for Claude Code
226
+ contextos export cursor # Compile for Cursor (.cursor/rules/*.mdc)
227
+ contextos export copilot # Compile for GitHub Copilot
228
+ contextos export aider # Compile for Aider
229
+ contextos export zed # Compile for Zed IDE
201
230
  ```
202
231
 
203
232
  ### Pre-Compiled Artifacts & Git Architecture
@@ -241,13 +270,14 @@ You can expand your `.agents` folder with community plugins or validate your own
241
270
 
242
271
  ```bash
243
272
  # Launch the interactive skill installer to browse and install community skills
244
- npx contextos-agents install-skill
273
+ contextos install-skill
274
+ # or: npx contextos install-skill
245
275
 
246
276
  # Or install a specific skill from a GitHub repository automatically
247
- npx contextos-agents install-skill --from-repo kok-o/awesome-skill
277
+ contextos install-skill --from-repo kok-o/awesome-skill
248
278
 
249
279
  # Validate your local skills (checks frontmatter, dependencies, and sync)
250
- npx contextos-agents audit
280
+ contextos audit
251
281
  ```
252
282
 
253
283
  ## ContextOS MCP Server & Autonomous Multi-Agent Swarm
@@ -312,39 +342,39 @@ Add ContextOS to your IDE's MCP settings (e.g. in `.agents/mcp_config.json`):
312
342
 
313
343
  Tests use the **Node.js built-in test runner** for the core framework and **Vitest** for the MCP engine — zero external test bloat.
314
344
 
315
- ### 1. Root Test Suite (121 tests)
345
+ ### 1. Root Test Suite (131 tests)
316
346
 
317
347
  ```bash
318
348
  npm test
319
349
  ```
320
350
 
321
351
  ```text
322
- # tests 121
352
+ # tests 131
323
353
  # suites 27
324
- # pass 121
354
+ # pass 131
325
355
  # fail 0
326
356
  ```
327
357
 
328
- ### 2. MCP Server Test Suite (428 tests)
358
+ ### 2. MCP Server Test Suite (440 tests)
329
359
 
330
360
  ```bash
331
361
  cd contextos-mcp && npm test
332
362
  ```
333
363
 
334
364
  ```text
335
- Test Files 24 passed (24)
336
- Tests 428 passed (428)
365
+ Test Files 25 passed | 1 skipped (26)
366
+ Tests 440 passed | 13 skipped (453)
337
367
  ```
338
368
 
339
369
  **Test coverage:**
340
370
 
341
- - `tests/install.test.js` — installer CLI flags (--help, --dry-run, --force)
342
- - `tests/export.test.js` — ctx.js export for gemini, claude, cursor (.mdc rules), copilot, aider
371
+ - `tests/install.test.js` — installer CLI flags (--help, --minimal, --dry-run, --force)
372
+ - `tests/export.test.js` — ctx.js export for gemini, claude, cursor (.mdc rules), copilot, aider, zed
343
373
  - `tests/skills.test.js` — validates all skill source files and frontmatter
344
374
  - `tests/profile.test.js` — profile resolution, stack auto-detection, and skill filtering
345
375
  - `tests/validate.test.js` — validator rules, dependency graph, and sync checks
346
376
  - `tests/plugins.test.js` — plugin lockfile, registry fetching, and security checks
347
- - `tests/resolver.test.js` — dynamic skill resolution, progressive index, and bilingual prompt matching
377
+ - `tests/resolver.test.js` — dynamic skill resolution, AST import graph analysis, progressive index, and bilingual prompt matching
348
378
  - `tests/benchmark.test.js` — benchmark scoring engine, static AST checks, runtime sandbox, and reporters
349
379
  - `contextos-mcp/tests/unit/session-persistence.test.ts` — session disk persistence, thread state tracking, and orphan purge
350
380
  - `contextos-mcp/tests/unit/contextos-tools.test.ts` — all 6 MCP tool handlers and validation
@@ -0,0 +1,207 @@
1
+ /**
2
+ * bin/commands/uninstall.js
3
+ * ContextOS CLI — Safe Uninstall Command
4
+ *
5
+ * Removes ContextOS artifacts safely:
6
+ * - Only deletes clean managed files (content matches installation hash)
7
+ * - Never deletes user-modified managed files (USER_MODIFIED_PRESERVED)
8
+ * - Never deletes user-created custom skills or unmanaged files
9
+ * - Preserves .agents/ directory if user files remain
10
+ * - Removes .agents/ cleanly if no user files remain
11
+ * - Supports --dry-run
12
+ */
13
+
14
+ const fs = require('fs');
15
+ const path = require('path');
16
+ const {
17
+ loadLockfile,
18
+ migrateExistingInstallation,
19
+ } = require('../lib/lockfile.js');
20
+ const {
21
+ planFileDelete,
22
+ executeFileDelete,
23
+ } = require('../lib/safe-writer.js');
24
+
25
+ /**
26
+ * Recursively count all files remaining in a directory (excluding specified skip names).
27
+ */
28
+ function countFiles(dir, skipNames = new Set()) {
29
+ let count = 0;
30
+ if (!fs.existsSync(dir)) return 0;
31
+
32
+ try {
33
+ for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {
34
+ if (skipNames.has(entry.name)) continue;
35
+ const full = path.join(dir, entry.name);
36
+ if (entry.isDirectory()) {
37
+ count += countFiles(full, skipNames);
38
+ } else if (entry.isFile()) {
39
+ count++;
40
+ }
41
+ }
42
+ } catch {
43
+ return 0;
44
+ }
45
+ return count;
46
+ }
47
+
48
+ /**
49
+ * Plan uninstallation for a target project.
50
+ */
51
+ function planUninstall(projectDir, options = {}) {
52
+ const targetAgentsDir = path.join(projectDir, '.agents');
53
+ if (!fs.existsSync(targetAgentsDir)) {
54
+ return {
55
+ ok: false,
56
+ error: 'NO_AGENTS_DIR',
57
+ message: 'No .agents/ directory found in the target project. Nothing to uninstall.',
58
+ plans: [],
59
+ summary: { delete: 0, skipModified: 0, skipUnmanaged: 0, missing: 0 },
60
+ };
61
+ }
62
+
63
+ const sourceAgentsDir = options.sourceAgentsDir || path.join(__dirname, '..', '..', '.agents');
64
+
65
+ // Load existing lockfile or build migration plan
66
+ let lockData = loadLockfile(projectDir);
67
+ if (!lockData) {
68
+ lockData = migrateExistingInstallation(projectDir, sourceAgentsDir, {
69
+ dryRun: true,
70
+ inMemory: true,
71
+ });
72
+ }
73
+
74
+ const plans = [];
75
+ if (lockData && lockData.managedFiles) {
76
+ for (const relPath of Object.keys(lockData.managedFiles)) {
77
+ const plan = planFileDelete({
78
+ projectDir,
79
+ relPath,
80
+ lockData,
81
+ });
82
+ plans.push(plan);
83
+ }
84
+ }
85
+
86
+ // Count unmanaged files in .agents that are not in lockData
87
+ const managedSet = new Set(Object.keys(lockData?.managedFiles || {}));
88
+ let unmanagedFilesCount = 0;
89
+
90
+ function findUnmanaged(currentDir) {
91
+ let entries;
92
+ try {
93
+ entries = fs.readdirSync(currentDir, { withFileTypes: true });
94
+ } catch {
95
+ return;
96
+ }
97
+
98
+ for (const entry of entries) {
99
+ const full = path.join(currentDir, entry.name);
100
+ if (entry.isDirectory()) {
101
+ findUnmanaged(full);
102
+ } else if (entry.isFile()) {
103
+ if (entry.name === 'contextos.lock.json') continue;
104
+ const rel = path.relative(projectDir, full).replace(/\\/g, '/');
105
+ if (!managedSet.has(rel)) {
106
+ unmanagedFilesCount++;
107
+ }
108
+ }
109
+ }
110
+ }
111
+
112
+ findUnmanaged(targetAgentsDir);
113
+
114
+ const summary = {
115
+ delete: plans.filter(p => p.action === 'DELETE').length,
116
+ skipModified: plans.filter(p => p.action === 'SKIP' && p.reason === 'USER_MODIFIED_PRESERVED').length,
117
+ missing: plans.filter(p => p.action === 'SKIP' && p.reason === 'ALREADY_MISSING').length,
118
+ skipUnmanaged: unmanagedFilesCount,
119
+ };
120
+
121
+ return {
122
+ ok: true,
123
+ plans,
124
+ summary,
125
+ lockData,
126
+ };
127
+ }
128
+
129
+ /**
130
+ * Run safe uninstall against a target project.
131
+ */
132
+ function runUninstall(projectDir = process.cwd(), options = {}) {
133
+ const dryRun = Boolean(options.dryRun);
134
+
135
+ console.log(`\nContextOS Safe Uninstall ${dryRun ? '[DRY-RUN]' : ''}`);
136
+ console.log(`Target: ${projectDir}`);
137
+
138
+ const planned = planUninstall(projectDir, options);
139
+ if (!planned.ok) {
140
+ console.error(`\n[ERROR] ${planned.message}`);
141
+ return planned;
142
+ }
143
+
144
+ const { lockData, plans, summary } = planned;
145
+
146
+ console.log('\nPlanned Actions:');
147
+ for (const item of plans) {
148
+ if (item.action === 'DELETE') {
149
+ console.log(` - DELETE ${item.relPath}`);
150
+ } else if (item.reason === 'USER_MODIFIED_PRESERVED') {
151
+ console.log(` = PRESERVE ${item.relPath} (modified by user — will NOT delete)`);
152
+ }
153
+ }
154
+
155
+ if (summary.skipUnmanaged > 0) {
156
+ console.log(` = PRESERVE ${summary.skipUnmanaged} unmanaged user file(s)/skill(s) in .agents/`);
157
+ }
158
+
159
+ console.log('\nSummary:');
160
+ console.log(` To delete: ${summary.delete}`);
161
+ console.log(` Preserved: ${summary.skipModified} (user-modified) + ${summary.skipUnmanaged} (user-created)`);
162
+
163
+ if (dryRun) {
164
+ console.log('\n[DRY-RUN] No files were deleted.');
165
+ return { ...planned, executed: false };
166
+ }
167
+
168
+ // Execute deletions
169
+ let deletedCount = 0;
170
+ for (const item of plans) {
171
+ if (item.action === 'DELETE') {
172
+ const res = executeFileDelete(item, lockData, { dryRun: false });
173
+ if (res.executed) deletedCount++;
174
+ }
175
+ }
176
+
177
+ const targetAgentsDir = path.join(projectDir, '.agents');
178
+ const lockfilePath = path.join(targetAgentsDir, 'contextos.lock.json');
179
+
180
+ // Count remaining files in .agents (excluding lockfile)
181
+ const remainingFiles = countFiles(targetAgentsDir, new Set(['contextos.lock.json']));
182
+
183
+ if (remainingFiles === 0) {
184
+ // Completely clean, remove lockfile and .agents directory
185
+ try {
186
+ if (fs.existsSync(lockfilePath)) fs.unlinkSync(lockfilePath);
187
+ fs.rmSync(targetAgentsDir, { recursive: true, force: true });
188
+ console.log('\n[OK] ContextOS completely uninstalled. .agents/ removed.');
189
+ } catch (err) {
190
+ console.warn(`[WARN] Could not remove .agents directory: ${err.message}`);
191
+ }
192
+ } else {
193
+ // User files or modified files remain — remove lockfile or keep remaining?
194
+ try {
195
+ if (fs.existsSync(lockfilePath)) fs.unlinkSync(lockfilePath);
196
+ } catch {}
197
+ console.log(`\n[OK] Clean ContextOS artifacts uninstalled (${deletedCount} removed).`);
198
+ console.log(`[INFO] .agents/ preserved because ${remainingFiles} user-modified or custom file(s) remain.`);
199
+ }
200
+
201
+ return { ...planned, executed: true, deletedCount, remainingFiles };
202
+ }
203
+
204
+ module.exports = {
205
+ planUninstall,
206
+ runUninstall,
207
+ };