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.
- package/.agents/AGENTS.md +5 -0
- package/.agents/adapters/aider/export.js +4 -2
- package/.agents/adapters/copilot/export.js +4 -2
- package/.agents/adapters/cursor/export.js +48 -12
- package/.agents/adapters/zed/export.js +53 -14
- package/.agents/core/profiles/mvp.yaml +1 -0
- package/.agents/core/skills/adapters/skill.yaml +6 -0
- package/.agents/core/skills/architecture-diagrams/skill.yaml +4 -0
- package/.agents/core/skills/brutalist-design/skill.yaml +4 -0
- package/.agents/core/skills/context-manager/references/context-rules.md +59 -0
- package/.agents/core/skills/context-manager/skill.yaml +7 -0
- package/.agents/core/skills/context-os/skill.yaml +11 -0
- package/.agents/core/skills/database/skill.yaml +6 -0
- package/.agents/core/skills/ddd/skill.yaml +7 -0
- package/.agents/core/skills/decisions/skill.yaml +6 -0
- package/.agents/core/skills/docker/skill.yaml +6 -0
- package/.agents/core/skills/engineering-workflow/SKILL.md +1 -1
- package/.agents/core/skills/engineering-workflow/skill.yaml +6 -0
- package/.agents/core/skills/fastapi/skill.yaml +7 -0
- package/.agents/core/skills/gemini-precision/SKILL.md +4 -0
- package/.agents/core/skills/gemini-precision/skill.yaml +4 -0
- package/.agents/core/skills/generators/skill.yaml +15 -0
- package/.agents/core/skills/graphify/SKILL.md +2 -2
- package/.agents/core/skills/graphify/skill.yaml +6 -1
- package/.agents/core/skills/gstack-roles/SKILL.md +3 -1
- package/.agents/core/skills/gstack-roles/skill.yaml +6 -0
- package/.agents/core/skills/impeccable-design/skill.yaml +6 -0
- package/.agents/core/skills/interview-me/skill.yaml +4 -0
- package/.agents/core/skills/microservices/skill.yaml +7 -0
- package/.agents/core/skills/minimalist-design/skill.yaml +4 -0
- package/.agents/core/skills/nestjs/skill.yaml +7 -0
- package/.agents/core/skills/nextjs/skill.yaml +7 -0
- package/.agents/core/skills/node/skill.yaml +7 -0
- package/.agents/core/skills/performance/skill.yaml +7 -0
- package/.agents/core/skills/ponytail-mindset/skill.yaml +6 -0
- package/.agents/core/skills/react/skill.yaml +7 -0
- package/.agents/core/skills/react-best-practices/skill.yaml +4 -0
- package/.agents/core/skills/redesign-audit/skill.yaml +4 -0
- package/.agents/core/skills/security/skill.yaml +7 -0
- package/.agents/core/skills/soft-design/skill.yaml +4 -0
- package/.agents/core/skills/state-management/skill.yaml +6 -0
- package/.agents/core/skills/subagent-orchestrator/SKILL.md +17 -0
- package/.agents/core/skills/subagent-orchestrator/skill.yaml +4 -0
- package/.agents/core/skills/system-design/skill.yaml +7 -0
- package/.agents/core/skills/testing/skill.yaml +6 -0
- package/.agents/core/skills/typescript/skill.yaml +7 -0
- package/.agents/core/skills/ui-design/skill.yaml +7 -0
- package/.agents/core/skills/ui-ux-pro/skill.yaml +6 -0
- package/.agents/core/skills/ux-design/skill.yaml +7 -0
- package/.agents/core/skills/vercel-optimize/scripts/collect-signals.mjs +131 -0
- package/.agents/core/skills/vercel-optimize/scripts/gate-investigations.mjs +142 -0
- package/.agents/core/skills/vercel-optimize/scripts/merge-signals.mjs +143 -0
- package/.agents/core/skills/vercel-optimize/scripts/scan-codebase.mjs +174 -0
- package/.agents/core/skills/vercel-optimize/skill.yaml +8 -0
- package/.agents/core/skills/web-accessibility/skill.yaml +7 -0
- package/.agents/ctx.js +44 -0
- package/.agents/doctor.js +193 -4
- package/.agents/generated/claude/skills/engineering-workflow/SKILL.md +1 -1
- package/.agents/generated/claude/skills/gemini-precision/SKILL.md +4 -0
- package/.agents/generated/claude/skills/graphify/SKILL.md +1 -1
- package/.agents/generated/claude/skills/gstack-roles/SKILL.md +3 -1
- package/.agents/generated/claude/skills/subagent-orchestrator/SKILL.md +17 -0
- package/.agents/generated/gemini/skills/engineering-workflow/SKILL.md +1 -1
- package/.agents/generated/gemini/skills/gemini-precision/SKILL.md +4 -0
- package/.agents/generated/gemini/skills/graphify/SKILL.md +2 -2
- package/.agents/generated/gemini/skills/gstack-roles/SKILL.md +3 -1
- package/.agents/generated/gemini/skills/subagent-orchestrator/SKILL.md +17 -0
- package/.agents/plugins/contextos/hooks.json +25 -0
- package/.agents/plugins/contextos/plugin.json +19 -0
- package/.agents/plugins.js +180 -20
- package/.agents/profiles.js +26 -0
- package/.agents/resolver.js +150 -30
- package/.agents/stats.js +22 -9
- package/.agents/validate.js +152 -13
- package/README.md +77 -47
- package/bin/commands/uninstall.js +207 -0
- package/bin/commands/update.js +262 -0
- package/bin/commands.js +305 -0
- package/bin/index.js +275 -119
- package/bin/lib/detector.js +106 -0
- package/bin/lib/lockfile.js +251 -0
- package/bin/lib/safe-writer.js +259 -0
- package/package.json +6 -9
- package/registry.json +13 -5
- package/registry.schema.json +3 -1
- package/.agents/mcp/runtime.py +0 -470
- package/.agents/mcp/server.mjs +0 -189386
- 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
|
|
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
|
|
24
|
-
npx contextos
|
|
25
|
-
npx contextos
|
|
26
|
-
npx contextos
|
|
27
|
-
npx contextos
|
|
28
|
-
npx contextos
|
|
29
|
-
npx contextos
|
|
30
|
-
npx contextos
|
|
31
|
-
npx contextos
|
|
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
|
-
|
|
75
|
+
contextos detect
|
|
76
|
+
# or: node .agents/ctx.js detect
|
|
74
77
|
|
|
75
78
|
# List available profiles and current active profile
|
|
76
|
-
|
|
79
|
+
contextos profile list
|
|
77
80
|
|
|
78
81
|
# Apply a profile
|
|
79
|
-
|
|
82
|
+
contextos profile apply mvp
|
|
80
83
|
|
|
81
84
|
# Recompile all agent exports for the active profile
|
|
82
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
179
|
+
contextos index
|
|
177
180
|
|
|
178
181
|
# Clean up lingering .swarm-worktrees directories and orphaned swarm/* git branches:
|
|
179
|
-
|
|
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
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
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
|
-
|
|
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
|
-
|
|
277
|
+
contextos install-skill --from-repo kok-o/awesome-skill
|
|
248
278
|
|
|
249
279
|
# Validate your local skills (checks frontmatter, dependencies, and sync)
|
|
250
|
-
|
|
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 (
|
|
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
|
|
352
|
+
# tests 131
|
|
323
353
|
# suites 27
|
|
324
|
-
# pass
|
|
354
|
+
# pass 131
|
|
325
355
|
# fail 0
|
|
326
356
|
```
|
|
327
357
|
|
|
328
|
-
### 2. MCP Server Test Suite (
|
|
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
|
|
336
|
-
Tests
|
|
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
|
+
};
|