contextos-agents 1.6.0 → 1.6.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.
- package/.agents/core/profiles/mvp.yaml +1 -0
- package/.agents/ctx.js +31 -0
- package/.agents/mcp/server.mjs +1 -116
- package/.agents/validate.js +53 -0
- package/README.md +77 -47
- package/bin/index.js +99 -63
- package/package.json +2 -4
package/.agents/ctx.js
CHANGED
|
@@ -46,6 +46,10 @@ function printHelp() {
|
|
|
46
46
|
console.log(' audit Alias for validate (check skills)');
|
|
47
47
|
console.log(' validate Validate skill sources, frontmatter, deps & sync');
|
|
48
48
|
console.log(' clean-worktrees Clean up lingering .swarm-worktrees and swarm/* branches');
|
|
49
|
+
console.log(' doctor Run project diagnostic health check');
|
|
50
|
+
console.log(' stats Display token context savings report');
|
|
51
|
+
console.log(' watch Start continuous file watcher and auto-sync daemon');
|
|
52
|
+
console.log(' init Show initialization guide');
|
|
49
53
|
console.log(' install-skill <ref> Alias for skill add (install a plugin)');
|
|
50
54
|
console.log(' skill add <ref> Install a plugin skill (GitHub or npm)');
|
|
51
55
|
console.log(' skill remove <name> Uninstall a plugin skill');
|
|
@@ -363,6 +367,33 @@ if (command === 'export') {
|
|
|
363
367
|
|
|
364
368
|
console.log(`✓ Cleaned up ${dirCount} worktree directory(ies) and ${branchCount} swarm branch(es).`);
|
|
365
369
|
|
|
370
|
+
// ── doctor ────────────────────────────────────────────────────────────────────
|
|
371
|
+
} else if (command === 'doctor') {
|
|
372
|
+
const doctorModule = require('./doctor.js');
|
|
373
|
+
doctorModule.runDoctor(process.cwd());
|
|
374
|
+
|
|
375
|
+
// ── stats ─────────────────────────────────────────────────────────────────────
|
|
376
|
+
} else if (command === 'stats') {
|
|
377
|
+
const statsModule = require('./stats.js');
|
|
378
|
+
statsModule.runStats(process.cwd());
|
|
379
|
+
|
|
380
|
+
// ── watch ─────────────────────────────────────────────────────────────────────
|
|
381
|
+
} else if (command === 'watch') {
|
|
382
|
+
const watchModule = require('./watch.js');
|
|
383
|
+
watchModule.runWatch(process.cwd());
|
|
384
|
+
|
|
385
|
+
// ── init ──────────────────────────────────────────────────────────────────────
|
|
386
|
+
} else if (command === 'init') {
|
|
387
|
+
console.log('\nContextOS — Project Initialization Guide\n');
|
|
388
|
+
console.log('To set up ContextOS in your project:');
|
|
389
|
+
console.log(' npx contextos Install .agents/ with auto-detected profile');
|
|
390
|
+
console.log(' npx contextos --minimal Install with minimal core skills');
|
|
391
|
+
console.log(' npx contextos --profile <name> Install with specific profile (mvp, startup, enterprise, etc.)');
|
|
392
|
+
console.log(' npx contextos --with-mcp Install with MCP execution server enabled');
|
|
393
|
+
console.log('\nAfter setup, verify your installation:');
|
|
394
|
+
console.log(' node .agents/ctx.js doctor');
|
|
395
|
+
console.log(' node .agents/ctx.js stats\n');
|
|
396
|
+
|
|
366
397
|
// ── unknown ───────────────────────────────────────────────────────────────────
|
|
367
398
|
} else {
|
|
368
399
|
console.error(`Unknown command: ${command}`);
|
package/.agents/mcp/server.mjs
CHANGED
|
@@ -41570,121 +41570,6 @@ var require_browser = __commonJS({
|
|
|
41570
41570
|
}
|
|
41571
41571
|
});
|
|
41572
41572
|
|
|
41573
|
-
// ../node_modules/has-flag/index.js
|
|
41574
|
-
var require_has_flag = __commonJS({
|
|
41575
|
-
"../node_modules/has-flag/index.js"(exports, module) {
|
|
41576
|
-
"use strict";
|
|
41577
|
-
module.exports = (flag, argv = process.argv) => {
|
|
41578
|
-
const prefix = flag.startsWith("-") ? "" : flag.length === 1 ? "-" : "--";
|
|
41579
|
-
const position = argv.indexOf(prefix + flag);
|
|
41580
|
-
const terminatorPosition = argv.indexOf("--");
|
|
41581
|
-
return position !== -1 && (terminatorPosition === -1 || position < terminatorPosition);
|
|
41582
|
-
};
|
|
41583
|
-
}
|
|
41584
|
-
});
|
|
41585
|
-
|
|
41586
|
-
// ../node_modules/supports-color/index.js
|
|
41587
|
-
var require_supports_color = __commonJS({
|
|
41588
|
-
"../node_modules/supports-color/index.js"(exports, module) {
|
|
41589
|
-
"use strict";
|
|
41590
|
-
var os7 = __require("os");
|
|
41591
|
-
var tty = __require("tty");
|
|
41592
|
-
var hasFlag = require_has_flag();
|
|
41593
|
-
var { env } = process;
|
|
41594
|
-
var forceColor;
|
|
41595
|
-
if (hasFlag("no-color") || hasFlag("no-colors") || hasFlag("color=false") || hasFlag("color=never")) {
|
|
41596
|
-
forceColor = 0;
|
|
41597
|
-
} else if (hasFlag("color") || hasFlag("colors") || hasFlag("color=true") || hasFlag("color=always")) {
|
|
41598
|
-
forceColor = 1;
|
|
41599
|
-
}
|
|
41600
|
-
if ("FORCE_COLOR" in env) {
|
|
41601
|
-
if (env.FORCE_COLOR === "true") {
|
|
41602
|
-
forceColor = 1;
|
|
41603
|
-
} else if (env.FORCE_COLOR === "false") {
|
|
41604
|
-
forceColor = 0;
|
|
41605
|
-
} else {
|
|
41606
|
-
forceColor = env.FORCE_COLOR.length === 0 ? 1 : Math.min(parseInt(env.FORCE_COLOR, 10), 3);
|
|
41607
|
-
}
|
|
41608
|
-
}
|
|
41609
|
-
function translateLevel(level) {
|
|
41610
|
-
if (level === 0) {
|
|
41611
|
-
return false;
|
|
41612
|
-
}
|
|
41613
|
-
return {
|
|
41614
|
-
level,
|
|
41615
|
-
hasBasic: true,
|
|
41616
|
-
has256: level >= 2,
|
|
41617
|
-
has16m: level >= 3
|
|
41618
|
-
};
|
|
41619
|
-
}
|
|
41620
|
-
function supportsColor(haveStream, streamIsTTY) {
|
|
41621
|
-
if (forceColor === 0) {
|
|
41622
|
-
return 0;
|
|
41623
|
-
}
|
|
41624
|
-
if (hasFlag("color=16m") || hasFlag("color=full") || hasFlag("color=truecolor")) {
|
|
41625
|
-
return 3;
|
|
41626
|
-
}
|
|
41627
|
-
if (hasFlag("color=256")) {
|
|
41628
|
-
return 2;
|
|
41629
|
-
}
|
|
41630
|
-
if (haveStream && !streamIsTTY && forceColor === void 0) {
|
|
41631
|
-
return 0;
|
|
41632
|
-
}
|
|
41633
|
-
const min = forceColor || 0;
|
|
41634
|
-
if (env.TERM === "dumb") {
|
|
41635
|
-
return min;
|
|
41636
|
-
}
|
|
41637
|
-
if (process.platform === "win32") {
|
|
41638
|
-
const osRelease = os7.release().split(".");
|
|
41639
|
-
if (Number(osRelease[0]) >= 10 && Number(osRelease[2]) >= 10586) {
|
|
41640
|
-
return Number(osRelease[2]) >= 14931 ? 3 : 2;
|
|
41641
|
-
}
|
|
41642
|
-
return 1;
|
|
41643
|
-
}
|
|
41644
|
-
if ("CI" in env) {
|
|
41645
|
-
if (["TRAVIS", "CIRCLECI", "APPVEYOR", "GITLAB_CI", "GITHUB_ACTIONS", "BUILDKITE"].some((sign) => sign in env) || env.CI_NAME === "codeship") {
|
|
41646
|
-
return 1;
|
|
41647
|
-
}
|
|
41648
|
-
return min;
|
|
41649
|
-
}
|
|
41650
|
-
if ("TEAMCITY_VERSION" in env) {
|
|
41651
|
-
return /^(9\.(0*[1-9]\d*)\.|\d{2,}\.)/.test(env.TEAMCITY_VERSION) ? 1 : 0;
|
|
41652
|
-
}
|
|
41653
|
-
if (env.COLORTERM === "truecolor") {
|
|
41654
|
-
return 3;
|
|
41655
|
-
}
|
|
41656
|
-
if ("TERM_PROGRAM" in env) {
|
|
41657
|
-
const version2 = parseInt((env.TERM_PROGRAM_VERSION || "").split(".")[0], 10);
|
|
41658
|
-
switch (env.TERM_PROGRAM) {
|
|
41659
|
-
case "iTerm.app":
|
|
41660
|
-
return version2 >= 3 ? 3 : 2;
|
|
41661
|
-
case "Apple_Terminal":
|
|
41662
|
-
return 2;
|
|
41663
|
-
}
|
|
41664
|
-
}
|
|
41665
|
-
if (/-256(color)?$/i.test(env.TERM)) {
|
|
41666
|
-
return 2;
|
|
41667
|
-
}
|
|
41668
|
-
if (/^screen|^xterm|^vt100|^vt220|^rxvt|color|ansi|cygwin|linux/i.test(env.TERM)) {
|
|
41669
|
-
return 1;
|
|
41670
|
-
}
|
|
41671
|
-
if ("COLORTERM" in env) {
|
|
41672
|
-
return 1;
|
|
41673
|
-
}
|
|
41674
|
-
return min;
|
|
41675
|
-
}
|
|
41676
|
-
function getSupportLevel(stream2) {
|
|
41677
|
-
const level = supportsColor(stream2, stream2 && stream2.isTTY);
|
|
41678
|
-
return translateLevel(level);
|
|
41679
|
-
}
|
|
41680
|
-
module.exports = {
|
|
41681
|
-
supportsColor: getSupportLevel,
|
|
41682
|
-
stdout: translateLevel(supportsColor(true, tty.isatty(1))),
|
|
41683
|
-
stderr: translateLevel(supportsColor(true, tty.isatty(2)))
|
|
41684
|
-
};
|
|
41685
|
-
}
|
|
41686
|
-
});
|
|
41687
|
-
|
|
41688
41573
|
// node_modules/debug/src/node.js
|
|
41689
41574
|
var require_node = __commonJS({
|
|
41690
41575
|
"node_modules/debug/src/node.js"(exports, module) {
|
|
@@ -41703,7 +41588,7 @@ var require_node = __commonJS({
|
|
|
41703
41588
|
);
|
|
41704
41589
|
exports.colors = [6, 2, 3, 4, 5, 1];
|
|
41705
41590
|
try {
|
|
41706
|
-
const supportsColor =
|
|
41591
|
+
const supportsColor = __require("supports-color");
|
|
41707
41592
|
if (supportsColor && (supportsColor.stderr || supportsColor).level >= 2) {
|
|
41708
41593
|
exports.colors = [
|
|
41709
41594
|
20,
|
package/.agents/validate.js
CHANGED
|
@@ -414,6 +414,58 @@ function checkValidationJson(sourceSkills) {
|
|
|
414
414
|
info(`[validation] ${pass} VALIDATION.json files are valid`);
|
|
415
415
|
}
|
|
416
416
|
|
|
417
|
+
// ═════════════════════════════════════════════════════════════════════════════
|
|
418
|
+
// CHECK 9 — MCP Bundle Synchronization
|
|
419
|
+
// ═════════════════════════════════════════════════════════════════════════════
|
|
420
|
+
function checkMcpBundleSync() {
|
|
421
|
+
const mcpSrcDir = path.join(ROOT, 'contextos-mcp', 'src');
|
|
422
|
+
const bundlePath = path.join(AGENTS_DIR, 'mcp', 'server.mjs');
|
|
423
|
+
|
|
424
|
+
if (!fs.existsSync(mcpSrcDir)) {
|
|
425
|
+
return;
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
if (!fs.existsSync(bundlePath)) {
|
|
429
|
+
warn(`[mcp-sync] Missing compiled MCP server bundle at .agents/mcp/server.mjs. Run: cd contextos-mcp && npm run build:bundle`);
|
|
430
|
+
return;
|
|
431
|
+
}
|
|
432
|
+
|
|
433
|
+
const bundleStat = fs.statSync(bundlePath);
|
|
434
|
+
const bundleMtime = bundleStat.mtimeMs;
|
|
435
|
+
|
|
436
|
+
let newestSrcFile = null;
|
|
437
|
+
let newestSrcMtime = 0;
|
|
438
|
+
|
|
439
|
+
function walk(dir) {
|
|
440
|
+
let entries;
|
|
441
|
+
try {
|
|
442
|
+
entries = fs.readdirSync(dir, { withFileTypes: true });
|
|
443
|
+
} catch {
|
|
444
|
+
return;
|
|
445
|
+
}
|
|
446
|
+
for (const entry of entries) {
|
|
447
|
+
const full = path.join(dir, entry.name);
|
|
448
|
+
if (entry.isDirectory()) {
|
|
449
|
+
walk(full);
|
|
450
|
+
} else if (entry.isFile()) {
|
|
451
|
+
const stat = fs.statSync(full);
|
|
452
|
+
if (stat.mtimeMs > newestSrcMtime) {
|
|
453
|
+
newestSrcMtime = stat.mtimeMs;
|
|
454
|
+
newestSrcFile = path.relative(ROOT, full);
|
|
455
|
+
}
|
|
456
|
+
}
|
|
457
|
+
}
|
|
458
|
+
}
|
|
459
|
+
|
|
460
|
+
walk(mcpSrcDir);
|
|
461
|
+
|
|
462
|
+
if (newestSrcMtime > bundleMtime) {
|
|
463
|
+
warn(`[mcp-sync] Compiled MCP bundle (.agents/mcp/server.mjs) is older than source file ${newestSrcFile}. Run: cd contextos-mcp && npm run build:bundle`);
|
|
464
|
+
} else {
|
|
465
|
+
info(`[mcp-sync] Compiled MCP bundle (.agents/mcp/server.mjs) is up to date with contextos-mcp/src/`);
|
|
466
|
+
}
|
|
467
|
+
}
|
|
468
|
+
|
|
417
469
|
// ═════════════════════════════════════════════════════════════════════════════
|
|
418
470
|
// REPORT
|
|
419
471
|
// ═════════════════════════════════════════════════════════════════════════════
|
|
@@ -487,6 +539,7 @@ function run() {
|
|
|
487
539
|
checkContentQuality(sourceSkills);
|
|
488
540
|
checkCostarHeaders(sourceSkills);
|
|
489
541
|
checkValidationJson(sourceSkills);
|
|
542
|
+
checkMcpBundleSync();
|
|
490
543
|
|
|
491
544
|
const passed = printReport();
|
|
492
545
|
process.exit(passed ? 0 : 1);
|
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
|
package/bin/index.js
CHANGED
|
@@ -95,65 +95,69 @@ Examples:
|
|
|
95
95
|
// ── Top-level Commands & Proxy Routing ────────────────────────────────────────
|
|
96
96
|
const mainCommand = args[0] && !args[0].startsWith('-') ? args[0] : null;
|
|
97
97
|
|
|
98
|
-
//
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
98
|
+
// Proxy commands to .agents/ctx.js when executed in a ContextOS project
|
|
99
|
+
const PROXY_COMMANDS = [
|
|
100
|
+
'profile', 'export', 'validate', 'resolve', 'skill', 'index',
|
|
101
|
+
'clean-worktrees', 'doctor', 'stats', 'watch', 'init'
|
|
102
|
+
];
|
|
103
|
+
|
|
104
|
+
const ctxPath = path.join(process.cwd(), '.agents', 'ctx.js');
|
|
105
|
+
const hasLocalCtx = fs.existsSync(ctxPath);
|
|
106
|
+
|
|
107
|
+
if (mainCommand && PROXY_COMMANDS.includes(mainCommand) && hasLocalCtx) {
|
|
108
|
+
const { execFileSync } = require('child_process');
|
|
109
|
+
try {
|
|
110
|
+
execFileSync(process.execPath, [ctxPath, ...args], { stdio: 'inherit' });
|
|
111
|
+
} catch (e) {
|
|
112
|
+
process.exit(e.status || 1);
|
|
106
113
|
}
|
|
114
|
+
process.exit(0);
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
// Fallbacks when running outside an initialized .agents/ directory
|
|
118
|
+
if (mainCommand === 'doctor') {
|
|
119
|
+
const doctorModule = require('../.agents/doctor.js');
|
|
107
120
|
doctorModule.runDoctor(process.cwd());
|
|
108
121
|
process.exit(0);
|
|
109
122
|
}
|
|
110
123
|
|
|
111
|
-
// Context savings statistics report
|
|
112
124
|
if (mainCommand === 'stats') {
|
|
113
|
-
|
|
114
|
-
const localStats = path.join(process.cwd(), '.agents', 'stats.js');
|
|
115
|
-
if (fs.existsSync(localStats)) {
|
|
116
|
-
statsModule = require(localStats);
|
|
117
|
-
} else {
|
|
118
|
-
statsModule = require('../.agents/stats.js');
|
|
119
|
-
}
|
|
125
|
+
const statsModule = require('../.agents/stats.js');
|
|
120
126
|
statsModule.runStats(process.cwd());
|
|
121
127
|
process.exit(0);
|
|
122
128
|
}
|
|
123
129
|
|
|
124
|
-
// Background auto-sync file watcher daemon
|
|
125
130
|
if (mainCommand === 'watch') {
|
|
126
|
-
|
|
127
|
-
const localWatch = path.join(process.cwd(), '.agents', 'watch.js');
|
|
128
|
-
if (fs.existsSync(localWatch)) {
|
|
129
|
-
watchModule = require(localWatch);
|
|
130
|
-
} else {
|
|
131
|
-
watchModule = require('../.agents/watch.js');
|
|
132
|
-
}
|
|
131
|
+
const watchModule = require('../.agents/watch.js');
|
|
133
132
|
watchModule.runWatch(process.cwd());
|
|
134
133
|
}
|
|
135
134
|
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
}
|
|
135
|
+
if (mainCommand === 'init') {
|
|
136
|
+
console.log(`
|
|
137
|
+
ContextOS — Project Setup
|
|
138
|
+
|
|
139
|
+
Usage:
|
|
140
|
+
npx contextos Install .agents/ with auto-detected stack
|
|
141
|
+
npx contextos --profile <name> Install with specific profile (mvp, startup, enterprise, frontend, backend)
|
|
142
|
+
npx contextos --minimal Install only 5 core skills
|
|
143
|
+
npx contextos --with-mcp Install with MCP execution server enabled
|
|
144
|
+
|
|
145
|
+
Run:
|
|
146
|
+
contextos doctor Verify installation health
|
|
147
|
+
contextos stats Show token savings report
|
|
148
|
+
`);
|
|
151
149
|
process.exit(0);
|
|
152
150
|
}
|
|
153
151
|
|
|
152
|
+
const PROJECT_ONLY_COMMANDS = ['profile', 'export', 'validate', 'resolve', 'skill', 'index', 'clean-worktrees'];
|
|
153
|
+
if (mainCommand && PROJECT_ONLY_COMMANDS.includes(mainCommand) && !hasLocalCtx) {
|
|
154
|
+
console.error('[ERROR] .agents/ctx.js not found in current directory.');
|
|
155
|
+
console.error(' Are you in a ContextOS project? Run `contextos` or `npx contextos-agents` first.');
|
|
156
|
+
process.exit(1);
|
|
157
|
+
}
|
|
158
|
+
|
|
154
159
|
if (mainCommand === 'audit') {
|
|
155
|
-
|
|
156
|
-
if (!fs.existsSync(ctxPath)) {
|
|
160
|
+
if (!hasLocalCtx) {
|
|
157
161
|
console.error('[ERROR] .agents/ctx.js not found. Are you in a ContextOS project?');
|
|
158
162
|
process.exit(1);
|
|
159
163
|
}
|
|
@@ -198,10 +202,10 @@ if (mainCommand === 'install-skill') {
|
|
|
198
202
|
}
|
|
199
203
|
process.exit(0);
|
|
200
204
|
} else {
|
|
201
|
-
// Interactive menu
|
|
205
|
+
// Interactive menu using standard library readline
|
|
202
206
|
(async () => {
|
|
203
207
|
try {
|
|
204
|
-
const
|
|
208
|
+
const readline = require('readline');
|
|
205
209
|
const https = require('https');
|
|
206
210
|
|
|
207
211
|
console.log('Fetching community skills from registry...');
|
|
@@ -210,33 +214,68 @@ if (mainCommand === 'install-skill') {
|
|
|
210
214
|
https.get('https://raw.githubusercontent.com/kok-o/contextos-agents/main/registry.json', (res) => {
|
|
211
215
|
let data = '';
|
|
212
216
|
res.on('data', chunk => data += chunk);
|
|
213
|
-
res.on('end', () =>
|
|
217
|
+
res.on('end', () => {
|
|
218
|
+
try {
|
|
219
|
+
resolve(JSON.parse(data));
|
|
220
|
+
} catch (err) {
|
|
221
|
+
reject(err);
|
|
222
|
+
}
|
|
223
|
+
});
|
|
214
224
|
}).on('error', reject);
|
|
215
225
|
});
|
|
216
226
|
|
|
217
227
|
const registry = await fetchRegistry();
|
|
218
|
-
const
|
|
219
|
-
|
|
228
|
+
const skillsList = (registry.skills || []).map((s, idx) => ({
|
|
229
|
+
idx: idx + 1,
|
|
230
|
+
name: s.name,
|
|
231
|
+
desc: s.description || '',
|
|
220
232
|
value: s.github ? `${s.github}${s.path ? '/' + s.path : ''}` : s.npm
|
|
221
233
|
}));
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
type: 'checkbox',
|
|
226
|
-
name: 'selectedSkills',
|
|
227
|
-
message: 'Select skills to install:',
|
|
228
|
-
choices
|
|
229
|
-
}
|
|
230
|
-
]);
|
|
231
|
-
|
|
232
|
-
if (!answers.selectedSkills || answers.selectedSkills.length === 0) {
|
|
233
|
-
console.log('No skills selected.');
|
|
234
|
+
|
|
235
|
+
if (skillsList.length === 0) {
|
|
236
|
+
console.log('No community skills found in registry.');
|
|
234
237
|
process.exit(0);
|
|
235
238
|
}
|
|
236
|
-
|
|
239
|
+
|
|
240
|
+
console.log('\nAvailable community skills:\n');
|
|
241
|
+
for (const item of skillsList) {
|
|
242
|
+
console.log(` [${item.idx}] ${item.name.padEnd(20)} ${item.desc}`);
|
|
243
|
+
}
|
|
244
|
+
console.log('\nEnter skill numbers to install (comma-separated, e.g. 1, 3) or press Enter to cancel:');
|
|
245
|
+
|
|
246
|
+
const rl = readline.createInterface({
|
|
247
|
+
input: process.stdin,
|
|
248
|
+
output: process.stdout,
|
|
249
|
+
});
|
|
250
|
+
|
|
251
|
+
const answer = await new Promise((resolve) => {
|
|
252
|
+
rl.question('> ', (ans) => {
|
|
253
|
+
rl.close();
|
|
254
|
+
resolve(ans.trim());
|
|
255
|
+
});
|
|
256
|
+
});
|
|
257
|
+
|
|
258
|
+
if (!answer) {
|
|
259
|
+
console.log('No skills selected. Operation cancelled.');
|
|
260
|
+
process.exit(0);
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
const selectedIndices = answer
|
|
264
|
+
.split(/[\s,]+/)
|
|
265
|
+
.map(n => parseInt(n, 10))
|
|
266
|
+
.filter(n => !isNaN(n) && n >= 1 && n <= skillsList.length);
|
|
267
|
+
|
|
268
|
+
const selectedSkills = selectedIndices.map(n => skillsList[n - 1].value);
|
|
269
|
+
|
|
270
|
+
if (selectedSkills.length === 0) {
|
|
271
|
+
console.log('No valid skill numbers selected.');
|
|
272
|
+
process.exit(0);
|
|
273
|
+
}
|
|
274
|
+
|
|
237
275
|
const { execFileSync } = require('child_process');
|
|
238
|
-
for (const skillRef of
|
|
276
|
+
for (const skillRef of selectedSkills) {
|
|
239
277
|
try {
|
|
278
|
+
console.log(`\nInstalling ${skillRef}...`);
|
|
240
279
|
execFileSync(process.execPath, [ctxPath, 'skill', 'add', skillRef], { stdio: 'inherit' });
|
|
241
280
|
} catch (e) {
|
|
242
281
|
console.error(`Failed to install ${skillRef}`);
|
|
@@ -244,9 +283,6 @@ if (mainCommand === 'install-skill') {
|
|
|
244
283
|
}
|
|
245
284
|
} catch (error) {
|
|
246
285
|
console.error('Failed to run interactive installer:', error.message);
|
|
247
|
-
if (error.code === 'MODULE_NOT_FOUND' && error.message.includes('inquirer')) {
|
|
248
|
-
console.error('It seems inquirer is not installed. Did you run npm install?');
|
|
249
|
-
}
|
|
250
286
|
process.exit(1);
|
|
251
287
|
}
|
|
252
288
|
})();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "contextos-agents",
|
|
3
|
-
"version": "1.6.
|
|
3
|
+
"version": "1.6.1",
|
|
4
4
|
"description": "Install a .agents folder into your project to teach AI assistants best practices: UI/UX, architecture, security, and engineering workflow skills.",
|
|
5
5
|
"bin": {
|
|
6
6
|
"contextos": "./bin/index.js",
|
|
@@ -71,7 +71,5 @@
|
|
|
71
71
|
"devDependencies": {
|
|
72
72
|
"markdownlint-cli": "^0.43.0"
|
|
73
73
|
},
|
|
74
|
-
"dependencies": {
|
|
75
|
-
"inquirer": "^8.2.7"
|
|
76
|
-
}
|
|
74
|
+
"dependencies": {}
|
|
77
75
|
}
|