contextos-agents 1.5.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/bin/index.js CHANGED
@@ -14,6 +14,7 @@ const flags = {
14
14
  force: args.includes('--force'),
15
15
  skipCompile: args.includes('--skip-compile'),
16
16
  auto: args.includes('--auto'),
17
+ minimal: args.includes('--minimal'),
17
18
  withMcp: args.includes('--with-mcp') || args.includes('--mcp'),
18
19
  profile: (() => {
19
20
  const i = args.indexOf('--profile');
@@ -33,17 +34,19 @@ if (flags.ver) {
33
34
 
34
35
  if (flags.help) {
35
36
  console.log(`
36
- contextos-agents v${version}
37
+ contextos / contextos-agents v${version}
37
38
  Install AI assistant skills and rules into your project.
38
39
 
39
40
  Usage:
40
- npx contextos-agents [options]
41
+ npx contextos [options]
42
+ contextos <command> [args...]
41
43
 
42
44
  Options:
43
45
  --help, -h Show this help message
44
46
  --version, -v Show version number
45
47
  --dry-run Preview what will be copied without making changes
46
48
  --force Overwrite an existing .agents/ folder
49
+ --minimal Install only 5 core skills (lightweight footprint)
47
50
  --profile <name> Install a specific profile (mvp, startup, enterprise, frontend, backend)
48
51
  --auto Auto-detect tech stack and apply recommended profile
49
52
  --with-mcp, --mcp Install with MCP execution server enabled (.agents/mcp/ & mcp_config.json)
@@ -51,7 +54,14 @@ Options:
51
54
  --add-skill <ref> Install a community plugin skill after setup
52
55
 
53
56
  Commands:
57
+ doctor Run full project diagnostic health check
54
58
  audit Validate local skills (alias for validate)
59
+ validate Validate local skills, frontmatter, and sync
60
+ profile <subcmd> Manage profiles (list, apply, show, remove)
61
+ export <target> Export skills (gemini, claude, cursor, copilot, aider, zed, all)
62
+ resolve <prompt> Dynamically resolve minimal skills for a prompt or files
63
+ stats Display token context savings report
64
+ watch Start continuous file watcher and auto-sync daemon
55
65
  detect Analyze project and display detected tech stack
56
66
  install-skill Interactive skill installer (or pass <ref> / --from-repo)
57
67
  setup-mcp Add MCP execution server to an existing .agents/ project
@@ -72,35 +82,82 @@ Plugin ref formats:
72
82
  @scope/npm-package A scoped npm skill package
73
83
 
74
84
  Examples:
75
- npx contextos-agents Install .agents/ into current project
76
- npx contextos-agents --profile mvp Install with MVP profile
77
- npx contextos-agents --auto Auto-detect tech stack and configure
78
- npx contextos-agents --dry-run Preview files that would be copied
79
- npx contextos-agents --add-skill alice/my-skill
80
-
81
- Export skills to your AI tool:
82
- node .agents/ctx.js export gemini → .agents/generated/gemini/ (Gemini / Antigravity)
83
- node .agents/ctx.js export claude → .agents/generated/claude/ (Claude Code)
84
- node .agents/ctx.js export cursor → .cursorrules & .cursor/rules (Cursor IDE)
85
- node .agents/ctx.js export copilot → .github/copilot-instructions.md
86
- node .agents/ctx.js export aider → .aider.conf.yml + CONVENTIONS.md
87
- node .agents/ctx.js export zed → .zed/rules.md & .zed/prompts/ (Zed IDE)
88
- node .agents/ctx.js export all → all of the above
89
-
90
- Profile commands (after installation):
91
- node .agents/ctx.js profile list List available profiles
92
- node .agents/ctx.js profile apply <name> Switch project profile
93
- node .agents/ctx.js detect Detect project tech stack
85
+ npx contextos Install .agents/ into current project
86
+ npx contextos --minimal Install only 5 core essential skills
87
+ npx contextos --profile startup Install with startup profile
88
+ contextos doctor Run project health check
89
+ contextos export gemini Compile skills for Gemini
90
+ contextos profile list List available profiles
94
91
  `);
95
92
  process.exit(0);
96
93
  }
97
94
 
98
- // ── Top-level Commands ────────────────────────────────────────────────────────
95
+ // ── Top-level Commands & Proxy Routing ────────────────────────────────────────
99
96
  const mainCommand = args[0] && !args[0].startsWith('-') ? args[0] : null;
100
97
 
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);
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');
120
+ doctorModule.runDoctor(process.cwd());
121
+ process.exit(0);
122
+ }
123
+
124
+ if (mainCommand === 'stats') {
125
+ const statsModule = require('../.agents/stats.js');
126
+ statsModule.runStats(process.cwd());
127
+ process.exit(0);
128
+ }
129
+
130
+ if (mainCommand === 'watch') {
131
+ const watchModule = require('../.agents/watch.js');
132
+ watchModule.runWatch(process.cwd());
133
+ }
134
+
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
+ `);
149
+ process.exit(0);
150
+ }
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
+
101
159
  if (mainCommand === 'audit') {
102
- const ctxPath = path.join(process.cwd(), '.agents', 'ctx.js');
103
- if (!fs.existsSync(ctxPath)) {
160
+ if (!hasLocalCtx) {
104
161
  console.error('[ERROR] .agents/ctx.js not found. Are you in a ContextOS project?');
105
162
  process.exit(1);
106
163
  }
@@ -145,10 +202,10 @@ if (mainCommand === 'install-skill') {
145
202
  }
146
203
  process.exit(0);
147
204
  } else {
148
- // Interactive menu
205
+ // Interactive menu using standard library readline
149
206
  (async () => {
150
207
  try {
151
- const inquirer = require('inquirer');
208
+ const readline = require('readline');
152
209
  const https = require('https');
153
210
 
154
211
  console.log('Fetching community skills from registry...');
@@ -157,33 +214,68 @@ if (mainCommand === 'install-skill') {
157
214
  https.get('https://raw.githubusercontent.com/kok-o/contextos-agents/main/registry.json', (res) => {
158
215
  let data = '';
159
216
  res.on('data', chunk => data += chunk);
160
- res.on('end', () => resolve(JSON.parse(data)));
217
+ res.on('end', () => {
218
+ try {
219
+ resolve(JSON.parse(data));
220
+ } catch (err) {
221
+ reject(err);
222
+ }
223
+ });
161
224
  }).on('error', reject);
162
225
  });
163
226
 
164
227
  const registry = await fetchRegistry();
165
- const choices = registry.skills.map(s => ({
166
- name: `${s.name} - ${s.description}`,
228
+ const skillsList = (registry.skills || []).map((s, idx) => ({
229
+ idx: idx + 1,
230
+ name: s.name,
231
+ desc: s.description || '',
167
232
  value: s.github ? `${s.github}${s.path ? '/' + s.path : ''}` : s.npm
168
233
  }));
169
-
170
- const answers = await inquirer.prompt([
171
- {
172
- type: 'checkbox',
173
- name: 'selectedSkills',
174
- message: 'Select skills to install:',
175
- choices
176
- }
177
- ]);
178
-
179
- if (!answers.selectedSkills || answers.selectedSkills.length === 0) {
180
- console.log('No skills selected.');
234
+
235
+ if (skillsList.length === 0) {
236
+ console.log('No community skills found in registry.');
181
237
  process.exit(0);
182
238
  }
183
-
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
+
184
275
  const { execFileSync } = require('child_process');
185
- for (const skillRef of answers.selectedSkills) {
276
+ for (const skillRef of selectedSkills) {
186
277
  try {
278
+ console.log(`\nInstalling ${skillRef}...`);
187
279
  execFileSync(process.execPath, [ctxPath, 'skill', 'add', skillRef], { stdio: 'inherit' });
188
280
  } catch (e) {
189
281
  console.error(`Failed to install ${skillRef}`);
@@ -191,9 +283,6 @@ if (mainCommand === 'install-skill') {
191
283
  }
192
284
  } catch (error) {
193
285
  console.error('Failed to run interactive installer:', error.message);
194
- if (error.code === 'MODULE_NOT_FOUND' && error.message.includes('inquirer')) {
195
- console.error('It seems inquirer is not installed. Did you run npm install?');
196
- }
197
286
  process.exit(1);
198
287
  }
199
288
  })();
@@ -245,6 +334,14 @@ if (mainCommand === 'install-skill') {
245
334
  const sourcePath = path.join(__dirname, '..', '.agents');
246
335
  const targetPath = path.join(process.cwd(), '.agents');
247
336
 
337
+ const MINIMAL_SKILLS = new Set([
338
+ 'engineering-workflow',
339
+ 'ponytail-mindset',
340
+ 'gstack-roles',
341
+ 'gemini-precision',
342
+ 'react',
343
+ ]);
344
+
248
345
  function uniqueSiblingPath(basePath, suffix) {
249
346
  let candidate = `${basePath}.${suffix}`;
250
347
  let index = 1;
@@ -267,12 +364,22 @@ function installAtomically(source, target, options = {}) {
267
364
  recursive: true,
268
365
  force: true,
269
366
  filter: (src) => {
367
+ const norm = src.replace(/\\/g, '/');
270
368
  if (!options.withMcp) {
271
- const norm = src.replace(/\\/g, '/');
272
369
  if (norm.endsWith('/mcp') || norm.includes('/mcp/') || norm.endsWith('/mcp_config.json')) {
273
370
  return false;
274
371
  }
275
372
  }
373
+ if (options.minimal) {
374
+ const skillMatch = norm.match(/\/core\/skills\/([^/]+)/);
375
+ if (skillMatch && !MINIMAL_SKILLS.has(skillMatch[1])) {
376
+ return false;
377
+ }
378
+ const genMatch = norm.match(/\/generated\/gemini\/skills\/([^/]+)/);
379
+ if (genMatch && !MINIMAL_SKILLS.has(genMatch[1])) {
380
+ return false;
381
+ }
382
+ }
276
383
  return true;
277
384
  },
278
385
  });
@@ -311,12 +418,22 @@ if (flags.dryRun) {
311
418
  let count = 0;
312
419
  for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {
313
420
  const full = path.join(dir, entry.name);
421
+ const norm = full.replace(/\\/g, '/');
314
422
  if (!flags.withMcp) {
315
- const norm = full.replace(/\\/g, '/');
316
423
  if (norm.endsWith('/mcp') || norm.includes('/mcp/') || norm.endsWith('/mcp_config.json')) {
317
424
  continue;
318
425
  }
319
426
  }
427
+ if (flags.minimal) {
428
+ const skillMatch = norm.match(/\/core\/skills\/([^/]+)/);
429
+ if (skillMatch && !MINIMAL_SKILLS.has(skillMatch[1])) {
430
+ continue;
431
+ }
432
+ const genMatch = norm.match(/\/generated\/gemini\/skills\/([^/]+)/);
433
+ if (genMatch && !MINIMAL_SKILLS.has(genMatch[1])) {
434
+ continue;
435
+ }
436
+ }
320
437
  count += entry.isDirectory() ? countFiles(full) : 1;
321
438
  }
322
439
  return count;
@@ -330,6 +447,9 @@ if (flags.dryRun) {
330
447
  console.log(`[INFO] Detected stack: ${stackDetection.detected.length ? stackDetection.detected.join(', ') : 'Generic JavaScript'}`);
331
448
  const targetProfile = flags.profile || (flags.auto ? stackDetection.recommendedProfile : 'none');
332
449
  console.log(`[INFO] Selected profile: ${targetProfile}`);
450
+ if (flags.minimal) {
451
+ console.log(`[INFO] Minimal mode: copying only 5 core essential skills`);
452
+ }
333
453
  console.log(`[INFO] ${total} files would be copied from the package.`);
334
454
  console.log('\nRun without --dry-run to apply changes.');
335
455
  process.exit(0);
@@ -355,9 +475,14 @@ try {
355
475
  process.exit(1);
356
476
  }
357
477
 
358
- installAtomically(sourcePath, targetPath, { withMcp: flags.withMcp });
478
+ installAtomically(sourcePath, targetPath, { withMcp: flags.withMcp, minimal: flags.minimal });
359
479
 
360
480
  console.log('[OK] .agents/ successfully installed in your project!');
481
+ if (flags.minimal) {
482
+ console.log('[OK] Minimal profile: 5 core skills installed.');
483
+ console.log(' (engineering-workflow, ponytail-mindset, gstack-roles, gemini-precision, react)');
484
+ console.log(' Tip: Add more skills anytime with: contextos skill add <name>');
485
+ }
361
486
  if (stackDetection.detected.length > 0) {
362
487
  console.log(`[OK] Detected project stack: ${stackDetection.detected.join(', ')}`);
363
488
  }
@@ -405,30 +530,31 @@ try {
405
530
  });
406
531
  } catch (e) {
407
532
  console.warn('[WARN] Skill compilation failed — run manually:');
408
- console.warn(' node .agents/ctx.js export gemini');
533
+ console.warn(' contextos export gemini');
409
534
  }
410
535
  }
411
536
  } else {
412
- console.log('Tip: Run `node .agents/ctx.js export gemini` to compile skills.');
537
+ console.log('Tip: Run `contextos export gemini` to compile skills.');
413
538
  }
414
539
 
415
540
  console.log('\n Next steps:');
416
541
  console.log(' 1. Open your project in your AI assistant');
417
542
  console.log(' 2. The assistant will automatically load .agents/AGENTS.md');
418
- console.log(' 3. Skills are pre-compiled in .agents/generated/gemini/skills/');
543
+ console.log(' 3. Inspect project health anytime:');
544
+ console.log(' contextos doctor');
419
545
  console.log(' 4. Switch profiles anytime:');
420
- console.log(' node .agents/ctx.js profile list');
421
- console.log(' node .agents/ctx.js profile apply mvp');
546
+ console.log(' contextos profile list');
547
+ console.log(' contextos profile apply mvp');
422
548
  console.log(' 5. Export to other AI tools:');
423
- console.log(' node .agents/ctx.js export cursor → .cursorrules & .cursor/rules');
424
- console.log(' node .agents/ctx.js export copilot → .github/copilot-instructions.md');
425
- console.log(' node .agents/ctx.js export aider → .aider.conf.yml + CONVENTIONS.md');
549
+ console.log(' contextos export cursor → .cursorrules & .cursor/rules');
550
+ console.log(' contextos export copilot → .github/copilot-instructions.md');
551
+ console.log(' contextos export aider → .aider.conf.yml + CONVENTIONS.md');
426
552
  console.log(' 6. Add community skills (plugins):');
427
- console.log(' node .agents/ctx.js skill add username/my-skill');
428
- console.log(' node .agents/ctx.js skill list');
553
+ console.log(' contextos skill add username/my-skill');
554
+ console.log(' contextos skill list');
429
555
  if (!flags.withMcp) {
430
556
  console.log(' 7. Enable MCP parallel subagents & worktrees (optional):');
431
- console.log(' npx contextos-agents setup-mcp');
557
+ console.log(' contextos setup-mcp');
432
558
  }
433
559
  console.log('');
434
560
 
package/package.json CHANGED
@@ -1,8 +1,9 @@
1
1
  {
2
2
  "name": "contextos-agents",
3
- "version": "1.5.0",
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
+ "contextos": "./bin/index.js",
6
7
  "contextos-agents": "./bin/index.js",
7
8
  "koko-contextos-agents": "./bin/index.js"
8
9
  },
@@ -17,6 +18,9 @@
17
18
  ".agents/plugins.js",
18
19
  ".agents/profiles.js",
19
20
  ".agents/resolver.js",
21
+ ".agents/doctor.js",
22
+ ".agents/stats.js",
23
+ ".agents/watch.js",
20
24
  ".agents/skills-index.json",
21
25
  ".agents/adapters",
22
26
  ".agents/core",
@@ -32,6 +36,9 @@
32
36
  "benchmark:live": "node benchmarks/run-live-benchmark.js",
33
37
  "benchmark:runtime": "node benchmarks/run-runtime-benchmark.js",
34
38
  "lint:md": "markdownlint README.md CONTRIBUTING.md .agents/core/skills/**/*.md --ignore .agents/generated/** --config .markdownlint.json",
39
+ "check:secrets": "node scripts/check-secrets.js --all",
40
+ "setup:hooks": "node scripts/install-hooks.js",
41
+ "watch": "node .agents/watch.js",
35
42
  "test": "node --test --test-concurrency=1 tests/install.test.js tests/export.test.js tests/skills.test.js tests/validate.test.js tests/plugins.test.js tests/benchmark.test.js tests/profile.test.js tests/resolver.test.js",
36
43
  "prepublishOnly": "npm run validate && cd contextos-mcp && npm install && npm run build:bundle && cd .. && npm run build"
37
44
  },
@@ -59,12 +66,10 @@
59
66
  "url": "https://github.com/kok-o/contextos-agents/issues"
60
67
  },
61
68
  "engines": {
62
- "node": ">=16.7.0"
69
+ "node": ">=18.0.0"
63
70
  },
64
71
  "devDependencies": {
65
72
  "markdownlint-cli": "^0.43.0"
66
73
  },
67
- "dependencies": {
68
- "inquirer": "^8.2.7"
69
- }
74
+ "dependencies": {}
70
75
  }