contextos-agents 2.1.0 → 2.2.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/adapters/aider/export.js +2 -2
- package/.agents/adapters/claude/export.js +53 -2
- package/.agents/adapters/drift-detector.js +6 -3
- package/.agents/adapters/pure-compiler.js +18 -6
- package/.agents/ctx.js +13 -8
- package/.agents/plugins.js +347 -26
- package/.agents/profiles.js +32 -11
- package/README.md +38 -3
- package/bin/commands/hook.js +50 -12
- package/bin/commands/scan.js +10 -3
- package/bin/index.js +165 -53
- package/bin/lib/git-snapshot.js +70 -43
- package/bin/lib/scan.js +108 -27
- package/bin/lib/ui.js +140 -0
- package/catalog/skills/adapters/EXAMPLES.md +19 -0
- package/catalog/skills/adapters/SKILL.md +101 -0
- package/catalog/skills/adapters/TROUBLESHOOTING.md +7 -0
- package/catalog/skills/adapters/VALIDATION.json +12 -0
- package/catalog/skills/adapters/skill.yaml +13 -0
- package/catalog/skills/api-design/EXAMPLES.md +91 -0
- package/catalog/skills/api-design/SKILL.md +63 -0
- package/catalog/skills/api-design/TROUBLESHOOTING.md +54 -0
- package/catalog/skills/api-design/VALIDATION.json +11 -0
- package/catalog/skills/api-design/skill.yaml +14 -0
- package/catalog/skills/architecture-diagrams/SKILL.md +108 -0
- package/catalog/skills/architecture-diagrams/VALIDATION.json +12 -0
- package/catalog/skills/architecture-diagrams/skill.yaml +9 -0
- package/catalog/skills/brutalist-design/EXAMPLES.md +59 -0
- package/catalog/skills/brutalist-design/SKILL.md +150 -0
- package/catalog/skills/brutalist-design/VALIDATION.json +12 -0
- package/catalog/skills/brutalist-design/skill.yaml +10 -0
- package/catalog/skills/ci-cd/EXAMPLES.md +79 -0
- package/catalog/skills/ci-cd/SKILL.md +69 -0
- package/catalog/skills/ci-cd/TROUBLESHOOTING.md +52 -0
- package/catalog/skills/ci-cd/VALIDATION.json +11 -0
- package/catalog/skills/ci-cd/skill.yaml +13 -0
- package/catalog/skills/database/EXAMPLES.md +74 -0
- package/catalog/skills/database/SKILL.md +101 -0
- package/catalog/skills/database/TROUBLESHOOTING.md +18 -0
- package/catalog/skills/database/VALIDATION.json +11 -0
- package/catalog/skills/database/skill.yaml +14 -0
- package/catalog/skills/ddd/EXAMPLES.md +42 -0
- package/catalog/skills/ddd/SKILL.md +247 -0
- package/catalog/skills/ddd/TROUBLESHOOTING.md +19 -0
- package/catalog/skills/ddd/VALIDATION.json +12 -0
- package/catalog/skills/ddd/skill.yaml +14 -0
- package/catalog/skills/decisions/EXAMPLES.md +35 -0
- package/catalog/skills/decisions/SKILL.md +90 -0
- package/catalog/skills/decisions/TROUBLESHOOTING.md +13 -0
- package/catalog/skills/decisions/VALIDATION.json +12 -0
- package/catalog/skills/decisions/skill.yaml +13 -0
- package/catalog/skills/docker/EXAMPLES.md +56 -0
- package/catalog/skills/docker/SKILL.md +169 -0
- package/catalog/skills/docker/TROUBLESHOOTING.md +18 -0
- package/catalog/skills/docker/VALIDATION.json +11 -0
- package/catalog/skills/docker/skill.yaml +13 -0
- package/catalog/skills/fastapi/EXAMPLES.md +36 -0
- package/catalog/skills/fastapi/SKILL.md +171 -0
- package/catalog/skills/fastapi/TROUBLESHOOTING.md +19 -0
- package/catalog/skills/fastapi/VALIDATION.json +12 -0
- package/catalog/skills/fastapi/skill.yaml +14 -0
- package/catalog/skills/generators/EXAMPLES.md +19 -0
- package/catalog/skills/generators/SKILL.md +110 -0
- package/catalog/skills/generators/TROUBLESHOOTING.md +7 -0
- package/catalog/skills/generators/VALIDATION.json +12 -0
- package/catalog/skills/generators/skill.yaml +22 -0
- package/catalog/skills/generators/templates/API.md +77 -0
- package/catalog/skills/generators/templates/ARCHITECTURE.md +70 -0
- package/catalog/skills/generators/templates/DATABASE.md +42 -0
- package/catalog/skills/generators/templates/DECISION.md +46 -0
- package/catalog/skills/generators/templates/PRD.md +67 -0
- package/catalog/skills/generators/templates/PROJECT_GRAPH.md +56 -0
- package/catalog/skills/generators/templates/ROADMAP.md +51 -0
- package/catalog/skills/generators/templates/TASKS.md +43 -0
- package/catalog/skills/generators/templates/UI.md +73 -0
- package/catalog/skills/graphify/EXAMPLES.md +73 -0
- package/catalog/skills/graphify/SKILL.md +130 -0
- package/catalog/skills/graphify/VALIDATION.json +12 -0
- package/catalog/skills/graphify/skill.yaml +13 -0
- package/catalog/skills/impeccable-design/EXAMPLES.md +26 -0
- package/catalog/skills/impeccable-design/SKILL.md +201 -0
- package/catalog/skills/impeccable-design/TROUBLESHOOTING.md +19 -0
- package/catalog/skills/impeccable-design/VALIDATION.json +12 -0
- package/catalog/skills/impeccable-design/skill.yaml +15 -0
- package/catalog/skills/interview-me/SKILL.md +97 -0
- package/catalog/skills/interview-me/VALIDATION.json +12 -0
- package/catalog/skills/interview-me/skill.yaml +9 -0
- package/catalog/skills/microservices/EXAMPLES.md +38 -0
- package/catalog/skills/microservices/SKILL.md +164 -0
- package/catalog/skills/microservices/TROUBLESHOOTING.md +19 -0
- package/catalog/skills/microservices/VALIDATION.json +12 -0
- package/catalog/skills/microservices/skill.yaml +14 -0
- package/catalog/skills/minimalist-design/EXAMPLES.md +58 -0
- package/catalog/skills/minimalist-design/SKILL.md +113 -0
- package/catalog/skills/minimalist-design/VALIDATION.json +12 -0
- package/catalog/skills/minimalist-design/skill.yaml +10 -0
- package/catalog/skills/nestjs/EXAMPLES.md +40 -0
- package/catalog/skills/nestjs/SKILL.md +139 -0
- package/catalog/skills/nestjs/TROUBLESHOOTING.md +19 -0
- package/catalog/skills/nestjs/VALIDATION.json +12 -0
- package/catalog/skills/nestjs/skill.yaml +14 -0
- package/catalog/skills/nextjs/EXAMPLES.md +40 -0
- package/catalog/skills/nextjs/SKILL.md +163 -0
- package/catalog/skills/nextjs/TROUBLESHOOTING.md +19 -0
- package/catalog/skills/nextjs/VALIDATION.json +12 -0
- package/catalog/skills/nextjs/skill.yaml +14 -0
- package/catalog/skills/node/EXAMPLES.md +80 -0
- package/catalog/skills/node/SKILL.md +128 -0
- package/catalog/skills/node/TROUBLESHOOTING.md +19 -0
- package/catalog/skills/node/VALIDATION.json +12 -0
- package/catalog/skills/node/skill.yaml +14 -0
- package/catalog/skills/performance/EXAMPLES.md +30 -0
- package/catalog/skills/performance/SKILL.md +75 -0
- package/catalog/skills/performance/TROUBLESHOOTING.md +19 -0
- package/catalog/skills/performance/VALIDATION.json +12 -0
- package/catalog/skills/performance/skill.yaml +14 -0
- package/catalog/skills/react/EXAMPLES.md +79 -0
- package/catalog/skills/react/SKILL.md +132 -0
- package/catalog/skills/react/TROUBLESHOOTING.md +19 -0
- package/catalog/skills/react/VALIDATION.json +12 -0
- package/catalog/skills/react/skill.yaml +14 -0
- package/catalog/skills/react-best-practices/SKILL.md +158 -0
- package/catalog/skills/react-best-practices/VALIDATION.json +12 -0
- package/catalog/skills/react-best-practices/skill.yaml +13 -0
- package/catalog/skills/redesign-audit/SKILL.md +117 -0
- package/catalog/skills/redesign-audit/VALIDATION.json +12 -0
- package/catalog/skills/redesign-audit/skill.yaml +9 -0
- package/catalog/skills/security-audit/EXAMPLES.md +79 -0
- package/catalog/skills/security-audit/SKILL.md +91 -0
- package/catalog/skills/security-audit/TROUBLESHOOTING.md +46 -0
- package/catalog/skills/security-audit/VALIDATION.json +11 -0
- package/catalog/skills/security-audit/skill.yaml +14 -0
- package/catalog/skills/soft-design/EXAMPLES.md +51 -0
- package/catalog/skills/soft-design/SKILL.md +108 -0
- package/catalog/skills/soft-design/VALIDATION.json +12 -0
- package/catalog/skills/soft-design/skill.yaml +10 -0
- package/catalog/skills/state-management/EXAMPLES.md +56 -0
- package/catalog/skills/state-management/SKILL.md +168 -0
- package/catalog/skills/state-management/TROUBLESHOOTING.md +18 -0
- package/catalog/skills/state-management/VALIDATION.json +11 -0
- package/catalog/skills/state-management/skill.yaml +14 -0
- package/catalog/skills/subagent-orchestrator/SKILL.md +117 -0
- package/catalog/skills/subagent-orchestrator/VALIDATION.json +12 -0
- package/catalog/skills/subagent-orchestrator/skill.yaml +9 -0
- package/catalog/skills/system-design/EXAMPLES.md +75 -0
- package/catalog/skills/system-design/SKILL.md +419 -0
- package/catalog/skills/system-design/TROUBLESHOOTING.md +19 -0
- package/catalog/skills/system-design/VALIDATION.json +12 -0
- package/catalog/skills/system-design/skill.yaml +14 -0
- package/catalog/skills/terraform/EXAMPLES.md +74 -0
- package/catalog/skills/terraform/SKILL.md +55 -0
- package/catalog/skills/terraform/TROUBLESHOOTING.md +53 -0
- package/catalog/skills/terraform/VALIDATION.json +11 -0
- package/catalog/skills/terraform/skill.yaml +14 -0
- package/catalog/skills/testing/EXAMPLES.md +122 -0
- package/catalog/skills/testing/SKILL.md +70 -0
- package/catalog/skills/testing/TROUBLESHOOTING.md +18 -0
- package/catalog/skills/testing/VALIDATION.json +11 -0
- package/catalog/skills/testing/skill.yaml +14 -0
- package/catalog/skills/typescript/EXAMPLES.md +64 -0
- package/catalog/skills/typescript/SKILL.md +112 -0
- package/catalog/skills/typescript/TROUBLESHOOTING.md +19 -0
- package/catalog/skills/typescript/VALIDATION.json +12 -0
- package/catalog/skills/typescript/skill.yaml +14 -0
- package/catalog/skills/ui-design/EXAMPLES.md +21 -0
- package/catalog/skills/ui-design/SKILL.md +124 -0
- package/catalog/skills/ui-design/TROUBLESHOOTING.md +19 -0
- package/catalog/skills/ui-design/VALIDATION.json +12 -0
- package/catalog/skills/ui-design/skill.yaml +16 -0
- package/catalog/skills/ui-ux-pro/EXAMPLES.md +62 -0
- package/catalog/skills/ui-ux-pro/SKILL.md +418 -0
- package/catalog/skills/ui-ux-pro/TROUBLESHOOTING.md +19 -0
- package/catalog/skills/ui-ux-pro/VALIDATION.json +12 -0
- package/catalog/skills/ui-ux-pro/skill.yaml +14 -0
- package/catalog/skills/ux-design/EXAMPLES.md +36 -0
- package/catalog/skills/ux-design/SKILL.md +116 -0
- package/catalog/skills/ux-design/TROUBLESHOOTING.md +19 -0
- package/catalog/skills/ux-design/VALIDATION.json +12 -0
- package/catalog/skills/ux-design/skill.yaml +16 -0
- package/catalog/skills/vercel-optimize/SKILL.md +83 -0
- package/catalog/skills/vercel-optimize/VALIDATION.json +12 -0
- package/catalog/skills/vercel-optimize/scripts/collect-signals.mjs +131 -0
- package/catalog/skills/vercel-optimize/scripts/gate-investigations.mjs +142 -0
- package/catalog/skills/vercel-optimize/scripts/merge-signals.mjs +143 -0
- package/catalog/skills/vercel-optimize/scripts/scan-codebase.mjs +174 -0
- package/catalog/skills/vercel-optimize/skill.yaml +15 -0
- package/catalog/skills/web-accessibility/EXAMPLES.md +39 -0
- package/catalog/skills/web-accessibility/SKILL.md +151 -0
- package/catalog/skills/web-accessibility/TROUBLESHOOTING.md +19 -0
- package/catalog/skills/web-accessibility/VALIDATION.json +12 -0
- package/catalog/skills/web-accessibility/skill.yaml +14 -0
- package/package.json +3 -2
package/bin/commands/hook.js
CHANGED
|
@@ -17,7 +17,28 @@ const HOOK_MARKER_START = '# BEGIN CONTEXTOS HOOK';
|
|
|
17
17
|
const HOOK_MARKER_END = '# END CONTEXTOS HOOK';
|
|
18
18
|
|
|
19
19
|
const HOOK_PAYLOAD = `${HOOK_MARKER_START}
|
|
20
|
-
|
|
20
|
+
CTX_SCOPE_ARG=""
|
|
21
|
+
if [ -f ".agents/task-scope.json" ]; then
|
|
22
|
+
CTX_SCOPE_ARG="--scope .agents/task-scope.json"
|
|
23
|
+
fi
|
|
24
|
+
|
|
25
|
+
if [ -f "./node_modules/.bin/contextos" ]; then
|
|
26
|
+
./node_modules/.bin/contextos scan --staged --enforce --placeholders $CTX_SCOPE_ARG
|
|
27
|
+
CTX_STATUS=$?
|
|
28
|
+
elif [ -f "./node_modules/.bin/contextos-agents" ]; then
|
|
29
|
+
./node_modules/.bin/contextos-agents scan --staged --enforce --placeholders $CTX_SCOPE_ARG
|
|
30
|
+
CTX_STATUS=$?
|
|
31
|
+
elif [ -f "./bin/index.js" ] && [ -f "./package.json" ]; then
|
|
32
|
+
node ./bin/index.js scan --staged --enforce --placeholders $CTX_SCOPE_ARG
|
|
33
|
+
CTX_STATUS=$?
|
|
34
|
+
else
|
|
35
|
+
echo "[ERROR] ContextOS local runner not found. Install locally (npm i -D contextos-agents) before committing." >&2
|
|
36
|
+
exit 2
|
|
37
|
+
fi
|
|
38
|
+
|
|
39
|
+
if [ $CTX_STATUS -ne 0 ]; then
|
|
40
|
+
exit $CTX_STATUS
|
|
41
|
+
fi
|
|
21
42
|
${HOOK_MARKER_END}`;
|
|
22
43
|
|
|
23
44
|
function installHook(cwd = process.cwd()) {
|
|
@@ -37,19 +58,36 @@ function installHook(cwd = process.cwd()) {
|
|
|
37
58
|
if (fs.existsSync(hookFile)) {
|
|
38
59
|
const existing = fs.readFileSync(hookFile, 'utf8');
|
|
39
60
|
|
|
40
|
-
if
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
const
|
|
44
|
-
|
|
45
|
-
|
|
61
|
+
// Validate shebang if present
|
|
62
|
+
const shebangMatch = existing.match(/^#!([^\r\n]+)/);
|
|
63
|
+
if (shebangMatch) {
|
|
64
|
+
const interpreter = shebangMatch[1].toLowerCase();
|
|
65
|
+
const isShell = /\b(sh|bash|zsh|dash)\b/.test(interpreter);
|
|
66
|
+
if (!isShell) {
|
|
67
|
+
console.error(`[ERROR] Pre-commit hook uses non-shell interpreter (${shebangMatch[0]}). ContextOS pre-commit hook requires POSIX shell.`);
|
|
68
|
+
process.exit(1);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
// Strip any existing ContextOS block (e.g. legacy trailing block from v2.1.0)
|
|
73
|
+
const stripped = existing.includes(HOOK_MARKER_START)
|
|
74
|
+
? existing.replace(new RegExp(`\\n?${HOOK_MARKER_START}[\\s\\S]*?${HOOK_MARKER_END}\\n?`, 'g'), '').trim()
|
|
75
|
+
: existing.trim();
|
|
76
|
+
|
|
77
|
+
// Place HOOK_PAYLOAD right after shebang so it runs first and cannot be bypassed by user 'exit 0'
|
|
78
|
+
let updated;
|
|
79
|
+
const strippedShebangMatch = stripped.match(/^#!.*(?:\r?\n|$)/);
|
|
80
|
+
if (strippedShebangMatch) {
|
|
81
|
+
const shebang = strippedShebangMatch[0];
|
|
82
|
+
const rest = stripped.slice(shebang.length).trim();
|
|
83
|
+
const sep = rest ? '\n\n' : '\n';
|
|
84
|
+
updated = `${shebang.trimEnd()}\n\n${HOOK_PAYLOAD}${sep}${rest}`;
|
|
46
85
|
} else {
|
|
47
|
-
|
|
48
|
-
const separator = existing.endsWith('\n') ? '\n' : '\n\n';
|
|
49
|
-
const updated = existing + separator + HOOK_PAYLOAD + '\n';
|
|
50
|
-
fs.writeFileSync(hookFile, updated, 'utf8');
|
|
51
|
-
console.log(`✓ ContextOS pre-commit hook appended to existing hook in ${hookFile}`);
|
|
86
|
+
updated = `#!/bin/sh\n\n${HOOK_PAYLOAD}${stripped ? `\n\n${stripped}` : ''}`;
|
|
52
87
|
}
|
|
88
|
+
|
|
89
|
+
fs.writeFileSync(hookFile, updated.trimEnd() + '\n', 'utf8');
|
|
90
|
+
console.log(`✓ ContextOS pre-commit hook installed in ${hookFile}`);
|
|
53
91
|
} else {
|
|
54
92
|
// Fresh hook installation with shebang
|
|
55
93
|
const fresh = `#!/bin/sh\n\n${HOOK_PAYLOAD}\n`;
|
package/bin/commands/scan.js
CHANGED
|
@@ -7,9 +7,10 @@
|
|
|
7
7
|
|
|
8
8
|
'use strict';
|
|
9
9
|
|
|
10
|
+
const path = require('path');
|
|
10
11
|
const { runScan } = require('../lib/scan.js');
|
|
11
12
|
|
|
12
|
-
function scanCommand(args, flags) {
|
|
13
|
+
function scanCommand(args, flags = {}) {
|
|
13
14
|
const isJson = flags.json || args.includes('--json');
|
|
14
15
|
const enforce = flags.enforce || args.includes('--enforce');
|
|
15
16
|
const checkPlaceholders = flags.placeholders || args.includes('--placeholders');
|
|
@@ -18,8 +19,13 @@ function scanCommand(args, flags) {
|
|
|
18
19
|
const scopeIdx = args.indexOf('--scope');
|
|
19
20
|
const scopeFile = scopeIdx !== -1 && args[scopeIdx + 1] ? args[scopeIdx + 1] : null;
|
|
20
21
|
|
|
22
|
+
const projectIdx = args.indexOf('--project');
|
|
23
|
+
const projectArg = projectIdx !== -1 && args[projectIdx + 1] ? args[projectIdx + 1] : null;
|
|
24
|
+
const targetProject = flags.project || projectArg;
|
|
25
|
+
const projectDir = targetProject ? path.resolve(targetProject) : process.cwd();
|
|
26
|
+
|
|
21
27
|
const result = runScan({
|
|
22
|
-
cwd:
|
|
28
|
+
cwd: projectDir,
|
|
23
29
|
staged: true,
|
|
24
30
|
secrets: checkSecrets,
|
|
25
31
|
placeholders: checkPlaceholders,
|
|
@@ -43,6 +49,7 @@ function scanCommand(args, flags) {
|
|
|
43
49
|
|
|
44
50
|
console.log(` Staged Files Scanned : ${result.stats.stagedFilesCount}`);
|
|
45
51
|
console.log(` Enforcement Mode : ${enforce ? 'STRICT (fails on findings)' : 'ADVISORY (warnings only)'}`);
|
|
52
|
+
console.log(` Scope Containment : ${result.scope.status.toUpperCase()}`);
|
|
46
53
|
console.log(` Violations Found : ${result.stats.violationsCount}\n`);
|
|
47
54
|
|
|
48
55
|
if (result.findings.length > 0) {
|
|
@@ -58,7 +65,7 @@ function scanCommand(args, flags) {
|
|
|
58
65
|
|
|
59
66
|
console.log('──────────────────────────────────────────────────────');
|
|
60
67
|
if (result.ok) {
|
|
61
|
-
console.log(' RESULT: PASSED (
|
|
68
|
+
console.log(' RESULT: PASSED (Verification completed cleanly, no blocking violations)');
|
|
62
69
|
} else {
|
|
63
70
|
console.log(' RESULT: FAILED (Commit blocked due to staged violations)');
|
|
64
71
|
}
|
package/bin/index.js
CHANGED
|
@@ -7,6 +7,7 @@ const profiles = require('../.agents/profiles.js');
|
|
|
7
7
|
const { isKnownCommand, getStatus, formatStatusText } = require('./commands.js');
|
|
8
8
|
const { detectProjectAttributes } = require('./lib/detector.js');
|
|
9
9
|
const lockfileLib = require('./lib/lockfile.js');
|
|
10
|
+
const ui = require('./lib/ui.js');
|
|
10
11
|
|
|
11
12
|
// ── CLI argument parsing ──────────────────────────────────────────────────────
|
|
12
13
|
const args = process.argv.slice(2);
|
|
@@ -41,6 +42,27 @@ const flags = {
|
|
|
41
42
|
return i !== -1 && args[i + 1] && !args[i + 1].startsWith('-') ? args[i + 1] : null;
|
|
42
43
|
})(),
|
|
43
44
|
githubAnnotations: args.includes('--github-annotations'),
|
|
45
|
+
all: args.includes('--all') || args.includes('--full'),
|
|
46
|
+
preset: (() => {
|
|
47
|
+
const i = args.indexOf('--preset');
|
|
48
|
+
return i !== -1 && args[i + 1] && !args[i + 1].startsWith('-') ? args[i + 1].toLowerCase() : null;
|
|
49
|
+
})(),
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
const PRESETS = {
|
|
53
|
+
frontend: [
|
|
54
|
+
'react', 'react-best-practices', 'nextjs', 'typescript',
|
|
55
|
+
'ui-ux-pro', 'impeccable-design', 'state-management', 'web-accessibility'
|
|
56
|
+
],
|
|
57
|
+
backend: [
|
|
58
|
+
'node', 'fastapi', 'nestjs', 'system-design',
|
|
59
|
+
'api-design', 'microservices', 'ddd', 'database'
|
|
60
|
+
],
|
|
61
|
+
devops: [
|
|
62
|
+
'docker', 'ci-cd', 'terraform', 'security-audit'
|
|
63
|
+
],
|
|
64
|
+
full: null,
|
|
65
|
+
all: null,
|
|
44
66
|
};
|
|
45
67
|
|
|
46
68
|
// ── Help / Version ────────────────────────────────────────────────────────────
|
|
@@ -71,6 +93,8 @@ Options:
|
|
|
71
93
|
--dry-run Preview what will be copied without making changes
|
|
72
94
|
--force Overwrite an existing .agents/ folder
|
|
73
95
|
--minimal Install only 7 core skills (lightweight footprint)
|
|
96
|
+
--all, --full Install all 36 catalog skills alongside 7 core skills
|
|
97
|
+
--preset <name> Install domain preset (frontend, backend, devops, full)
|
|
74
98
|
--profile <name> Install a specific profile (mvp, startup, enterprise, frontend, backend)
|
|
75
99
|
--auto Auto-detect tech stack and apply recommended profile
|
|
76
100
|
--project <path> Specify target project root directory (default: current directory)
|
|
@@ -82,6 +106,7 @@ Options:
|
|
|
82
106
|
|
|
83
107
|
Commands:
|
|
84
108
|
init Install and configure .agents/ in target project
|
|
109
|
+
skill <subcmd> Manage skills (add, remove, list, search, override, diff, eject)
|
|
85
110
|
gate Run deterministic quality gate against adapter drift
|
|
86
111
|
status Display project configuration, active profile, and lockfile status
|
|
87
112
|
update Safely update skills without overwriting custom changes
|
|
@@ -119,9 +144,14 @@ Plugin ref formats:
|
|
|
119
144
|
@scope/npm-package A scoped npm skill package
|
|
120
145
|
|
|
121
146
|
Examples:
|
|
122
|
-
npx contextos-agents init Install
|
|
147
|
+
npx contextos-agents init Install Lean Core (7 foundational skills)
|
|
148
|
+
npx contextos-agents init --all Install ContextOS with all 43 skills
|
|
149
|
+
npx contextos-agents init --preset frontend Install ContextOS with frontend domain skills
|
|
123
150
|
npx contextos-agents init --agent auto Install and configure for detected stack & IDE
|
|
124
|
-
npx contextos
|
|
151
|
+
npx contextos skill add <name> Install a domain skill from catalog
|
|
152
|
+
npx contextos skill add --all Install all catalog skills into existing project
|
|
153
|
+
npx contextos skill list --available List all available catalog domain skills
|
|
154
|
+
npx contextos skill override <name> Create editable local copy of a skill
|
|
125
155
|
npx contextos status Show project configuration and lockfile status
|
|
126
156
|
npx contextos doctor Run project health check
|
|
127
157
|
npx contextos export gemini Compile skills for Gemini
|
|
@@ -178,7 +208,7 @@ if (mainCommand === 'detect') {
|
|
|
178
208
|
}, null, 2));
|
|
179
209
|
} else {
|
|
180
210
|
console.log('\n══════════════════════════════════════════');
|
|
181
|
-
console.log(' ContextOS
|
|
211
|
+
console.log(' ContextOS - Workspace Scoped Detection');
|
|
182
212
|
console.log('══════════════════════════════════════════\n');
|
|
183
213
|
console.log(` Scope Path : ${scopeArg}`);
|
|
184
214
|
if (nearestPkg) {
|
|
@@ -193,7 +223,7 @@ if (mainCommand === 'detect') {
|
|
|
193
223
|
if (evidence.length > 0) {
|
|
194
224
|
console.log('\n Scoped Evidence:');
|
|
195
225
|
for (const ev of evidence.slice(0, 10)) {
|
|
196
|
-
console.log(` • [${ev.source}] ${ev.target} (+${ev.weight})
|
|
226
|
+
console.log(` • [${ev.source}] ${ev.target} (+${ev.weight}) - ${ev.description}`);
|
|
197
227
|
}
|
|
198
228
|
if (evidence.length > 10) {
|
|
199
229
|
console.log(` ... and ${evidence.length - 10} more signals`);
|
|
@@ -212,7 +242,7 @@ if (mainCommand === 'detect') {
|
|
|
212
242
|
}, null, 2));
|
|
213
243
|
} else if (explain) {
|
|
214
244
|
console.log('\n══════════════════════════════════════════');
|
|
215
|
-
console.log(' ContextOS
|
|
245
|
+
console.log(' ContextOS - Workspace Evidence Graph');
|
|
216
246
|
console.log('══════════════════════════════════════════\n');
|
|
217
247
|
console.log(` Repository Root : ${graph.repositoryRoot}`);
|
|
218
248
|
console.log(` Fingerprint : ${graph.fingerprint}`);
|
|
@@ -234,7 +264,7 @@ if (mainCommand === 'detect') {
|
|
|
234
264
|
console.log('──────────────────────────────────────────\n');
|
|
235
265
|
} else {
|
|
236
266
|
const detection = detectProjectAttributes(process.cwd());
|
|
237
|
-
console.log('\nContextOS
|
|
267
|
+
console.log('\nContextOS - Tech Stack & Environment Detection\n');
|
|
238
268
|
console.log(` Repository Root : ${graph.repositoryRoot}`);
|
|
239
269
|
console.log(` Packages Detected : ${graph.packages.map(p => `${p.id} (${p.root})`).join(', ')}`);
|
|
240
270
|
console.log(` Detected Technologies : ${detection.summary.technologies.join(', ')}`);
|
|
@@ -270,7 +300,10 @@ if (mainCommand === 'recover') {
|
|
|
270
300
|
// Gate command (deterministic quality gate verification)
|
|
271
301
|
if (mainCommand === 'gate') {
|
|
272
302
|
const { runGate, emitGitHubAnnotations, writeGitHubSummary } = require('./lib/gate.js');
|
|
273
|
-
|
|
303
|
+
let target = flags.target || (args[1] && !args[1].startsWith('-') ? args[1] : 'all');
|
|
304
|
+
if (typeof target === 'string' && target.includes(',')) {
|
|
305
|
+
target = target.split(',').map(s => s.trim()).filter(Boolean);
|
|
306
|
+
}
|
|
274
307
|
const result = runGate(flags.project, {
|
|
275
308
|
target,
|
|
276
309
|
profile: flags.profile,
|
|
@@ -377,7 +410,7 @@ if (mainCommand === 'hook') {
|
|
|
377
410
|
|
|
378
411
|
// Proxy commands to trusted package .agents/ctx.js targeting flags.project
|
|
379
412
|
const PROXY_COMMANDS = [
|
|
380
|
-
'profile', 'export', 'validate', 'resolve', 'skill', 'index',
|
|
413
|
+
'profile', 'export', 'validate', 'audit', 'resolve', 'skill', 'index',
|
|
381
414
|
'clean-worktrees', 'stats', 'watch', 'compile', 'explain',
|
|
382
415
|
'thread'
|
|
383
416
|
];
|
|
@@ -477,7 +510,32 @@ if (mainCommand === 'install-skill') {
|
|
|
477
510
|
}).on('error', reject);
|
|
478
511
|
});
|
|
479
512
|
|
|
480
|
-
|
|
513
|
+
let registry;
|
|
514
|
+
try {
|
|
515
|
+
registry = await fetchRegistry();
|
|
516
|
+
} catch {
|
|
517
|
+
const catalogDir = path.join(__dirname, '..', 'catalog', 'skills');
|
|
518
|
+
if (fs.existsSync(catalogDir)) {
|
|
519
|
+
const catalogSkills = fs.readdirSync(catalogDir).filter(n => {
|
|
520
|
+
try {
|
|
521
|
+
return fs.statSync(path.join(catalogDir, n)).isDirectory();
|
|
522
|
+
} catch {
|
|
523
|
+
return false;
|
|
524
|
+
}
|
|
525
|
+
});
|
|
526
|
+
registry = {
|
|
527
|
+
skills: catalogSkills.map(name => ({
|
|
528
|
+
name,
|
|
529
|
+
description: `Domain catalog skill: ${name}`,
|
|
530
|
+
github: null,
|
|
531
|
+
npm: name,
|
|
532
|
+
})),
|
|
533
|
+
};
|
|
534
|
+
} else {
|
|
535
|
+
console.error('[ERROR] Could not fetch remote registry and local catalog is unavailable.');
|
|
536
|
+
process.exit(1);
|
|
537
|
+
}
|
|
538
|
+
}
|
|
481
539
|
const skillsList = (registry.skills || []).map((s, idx) => ({
|
|
482
540
|
idx: idx + 1,
|
|
483
541
|
name: s.name,
|
|
@@ -545,6 +603,9 @@ if (mainCommand === 'install-skill') {
|
|
|
545
603
|
console.error(' To use the MCP Bridge or execution runtime, install @contextos/mcp:');
|
|
546
604
|
console.error(' npm install @contextos/mcp --save-dev');
|
|
547
605
|
process.exit(1);
|
|
606
|
+
} else if (mainCommand && mainCommand !== 'init') {
|
|
607
|
+
console.error(`[ERROR] Unknown command: '${mainCommand}'. Run 'contextos --help' for available commands.`);
|
|
608
|
+
process.exit(1);
|
|
548
609
|
} else {
|
|
549
610
|
|
|
550
611
|
// ── Paths ─────────────────────────────────────────────────────────────────────
|
|
@@ -600,6 +661,13 @@ function installAtomically(source, target, options = {}) {
|
|
|
600
661
|
return true;
|
|
601
662
|
},
|
|
602
663
|
});
|
|
664
|
+
|
|
665
|
+
const catalogSrc = path.join(__dirname, '..', 'catalog');
|
|
666
|
+
const catalogDest = path.join(stagingPath, 'catalog');
|
|
667
|
+
if (fs.existsSync(catalogSrc)) {
|
|
668
|
+
fs.cpSync(catalogSrc, catalogDest, { recursive: true, force: true });
|
|
669
|
+
}
|
|
670
|
+
|
|
603
671
|
if (fs.existsSync(target)) {
|
|
604
672
|
fs.renameSync(target, backupPath);
|
|
605
673
|
movedExisting = true;
|
|
@@ -680,7 +748,7 @@ if (flags.dryRun) {
|
|
|
680
748
|
|
|
681
749
|
console.log('[DRY-RUN] No files will be written.\n');
|
|
682
750
|
if (fs.existsSync(targetPath)) {
|
|
683
|
-
console.log(`[WARN] .agents/ already exists
|
|
751
|
+
console.log(`[WARN] .agents/ already exists - would be overwritten with --force.`);
|
|
684
752
|
} else {
|
|
685
753
|
console.log(`[OK] Would create .agents/ in: ${process.cwd()}`);
|
|
686
754
|
}
|
|
@@ -700,7 +768,13 @@ if (flags.dryRun) {
|
|
|
700
768
|
|
|
701
769
|
// ── Main install ──────────────────────────────────────────────────────────────
|
|
702
770
|
if (!flags.json) {
|
|
703
|
-
|
|
771
|
+
ui.renderBanner(version);
|
|
772
|
+
ui.renderStep(1, 4, 'Analyzing project environment & tech stack',
|
|
773
|
+
stackDetection.detected.length > 0
|
|
774
|
+
? `Detected stack: ${stackDetection.detected.join(', ')}`
|
|
775
|
+
: 'Detected stack: Generic JavaScript environment'
|
|
776
|
+
);
|
|
777
|
+
console.log('');
|
|
704
778
|
}
|
|
705
779
|
|
|
706
780
|
try {
|
|
@@ -740,18 +814,14 @@ try {
|
|
|
740
814
|
}
|
|
741
815
|
|
|
742
816
|
if (!flags.json) {
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
}
|
|
752
|
-
if (ideDetection.detected.length > 0) {
|
|
753
|
-
console.log(`[OK] Detected developer environment: ${ideDetection.detected.join(', ')}`);
|
|
754
|
-
}
|
|
817
|
+
ui.renderStep(2, 4, 'Deploying Lean Core engine (.agents/)', [
|
|
818
|
+
'Installed 7 foundational core skills in .agents/core/skills/',
|
|
819
|
+
'Why 7? ContextOS uses a Lean Core to keep your AI context small, fast, and token-efficient.',
|
|
820
|
+
'To add domain skills (React, FastAPI, Docker, etc.): npx contextos skill add <name> (or --all)',
|
|
821
|
+
]);
|
|
822
|
+
console.log('');
|
|
823
|
+
ui.renderStep(3, 4, 'Generating lockfile & security governance', 'contextos.lock.json synchronized');
|
|
824
|
+
console.log('');
|
|
755
825
|
}
|
|
756
826
|
|
|
757
827
|
// ── Deprecation warning for --with-mcp ────────────────────────────────────────────────
|
|
@@ -765,7 +835,7 @@ try {
|
|
|
765
835
|
if (selectedProfile) {
|
|
766
836
|
try {
|
|
767
837
|
const applied = profiles.applyProfile(selectedProfile, process.cwd());
|
|
768
|
-
if (!flags.json) console.log(`[OK] Applied profile '${applied.name}' (excluded: ${(applied.exclude_skills || []).join(', ') || 'none'})`);
|
|
838
|
+
if (!flags.json) console.log(` [OK] Applied profile '${applied.name}' (excluded: ${(applied.exclude_skills || []).join(', ') || 'none'})\n`);
|
|
769
839
|
} catch (e) {
|
|
770
840
|
if (flags.json) {
|
|
771
841
|
console.error(JSON.stringify({ success: false, error: `Could not apply profile '${selectedProfile}': ${e.message}` }));
|
|
@@ -776,58 +846,112 @@ try {
|
|
|
776
846
|
}
|
|
777
847
|
}
|
|
778
848
|
|
|
779
|
-
if (!flags.json) {
|
|
780
|
-
console.log('[OK] Your AI assistant now has skills and rules configured.\n');
|
|
781
|
-
}
|
|
782
|
-
|
|
783
849
|
// ── Auto-compile skills for target agents ──────────────────────────────────
|
|
784
850
|
if (!flags.skipCompile) {
|
|
785
851
|
const ctxPath = path.join(targetPath, 'ctx.js');
|
|
786
852
|
if (fs.existsSync(ctxPath)) {
|
|
853
|
+
if (!flags.json) {
|
|
854
|
+
ui.renderStep(4, 4, 'Configuring AI assistants & compiling rules', `${targetAgents.join(', ')} synchronized`);
|
|
855
|
+
console.log('');
|
|
856
|
+
}
|
|
787
857
|
const { execFileSync } = require('child_process');
|
|
788
858
|
for (const ag of targetAgents) {
|
|
789
|
-
if (!flags.json) console.log(`Compiling skills for ${ag}...`);
|
|
790
859
|
try {
|
|
791
860
|
execFileSync(process.execPath, [ctxPath, 'export', ag], {
|
|
792
861
|
cwd: process.cwd(),
|
|
793
|
-
stdio:
|
|
862
|
+
stdio: 'ignore',
|
|
794
863
|
});
|
|
795
864
|
} catch (e) {
|
|
796
865
|
if (flags.json) {
|
|
797
866
|
console.error(JSON.stringify({ success: false, error: `Skill compilation for '${ag}' failed` }));
|
|
798
867
|
} else {
|
|
799
|
-
console.error(`[ERROR] Skill compilation for '${ag}' failed
|
|
868
|
+
console.error(` [ERROR] Skill compilation for '${ag}' failed - run manually: contextos export ${ag}`);
|
|
800
869
|
}
|
|
801
870
|
process.exit(1);
|
|
802
871
|
}
|
|
803
872
|
}
|
|
804
873
|
}
|
|
805
874
|
} else if (!flags.json) {
|
|
806
|
-
|
|
875
|
+
ui.renderStep(4, 4, 'Configuring AI assistants & compiling rules', [
|
|
876
|
+
'Skipped auto-compilation (--skip-compile)',
|
|
877
|
+
'Tip: Run `contextos export gemini` to compile skills when ready.',
|
|
878
|
+
]);
|
|
879
|
+
console.log('');
|
|
807
880
|
}
|
|
808
881
|
|
|
809
882
|
// ── --add-skill flag ────────────────────────────────────────────────────────
|
|
810
883
|
if (flags.addSkill) {
|
|
811
|
-
const
|
|
812
|
-
|
|
884
|
+
const packageCtxPath = path.join(__dirname, '..', '.agents', 'ctx.js');
|
|
885
|
+
const ctxScript = fs.existsSync(packageCtxPath) ? packageCtxPath : path.join(targetPath, 'ctx.js');
|
|
886
|
+
if (fs.existsSync(ctxScript)) {
|
|
813
887
|
if (!flags.json) console.log(`Installing plugin skill: ${flags.addSkill}`);
|
|
814
888
|
try {
|
|
815
889
|
const { execFileSync } = require('child_process');
|
|
816
|
-
|
|
890
|
+
const catalogDir = path.join(__dirname, '..', 'catalog', 'skills');
|
|
891
|
+
const subEnv = { ...process.env, CONTEXTOS_CATALOG_DIR: catalogDir };
|
|
892
|
+
execFileSync(process.execPath, [ctxScript, 'skill', 'add', flags.addSkill], {
|
|
817
893
|
cwd: process.cwd(),
|
|
818
894
|
stdio: flags.json ? 'ignore' : 'inherit',
|
|
895
|
+
env: subEnv,
|
|
819
896
|
});
|
|
820
897
|
} catch (e) {
|
|
821
898
|
if (flags.json) {
|
|
822
899
|
console.error(JSON.stringify({ success: false, error: `Skill install failed for ${flags.addSkill}` }));
|
|
823
900
|
} else {
|
|
824
|
-
console.error(`[ERROR] Skill install failed
|
|
901
|
+
console.error(`[ERROR] Skill install failed - run manually: node .agents/ctx.js skill add ${flags.addSkill}`);
|
|
825
902
|
}
|
|
826
903
|
process.exit(1);
|
|
827
904
|
}
|
|
828
905
|
}
|
|
829
906
|
}
|
|
830
907
|
|
|
908
|
+
// ── --all / --preset flags ──────────────────────────────────────────────────
|
|
909
|
+
if (flags.all || flags.preset) {
|
|
910
|
+
const packageCtxPath = path.join(__dirname, '..', '.agents', 'ctx.js');
|
|
911
|
+
const ctxScript = fs.existsSync(packageCtxPath) ? packageCtxPath : path.join(targetPath, 'ctx.js');
|
|
912
|
+
if (fs.existsSync(ctxScript)) {
|
|
913
|
+
const presetKey = flags.all ? 'full' : (flags.preset || 'full');
|
|
914
|
+
const { execFileSync } = require('child_process');
|
|
915
|
+
const catalogDir = path.join(__dirname, '..', 'catalog', 'skills');
|
|
916
|
+
const subEnv = { ...process.env, CONTEXTOS_CATALOG_DIR: catalogDir };
|
|
917
|
+
|
|
918
|
+
if (presetKey === 'full' || presetKey === 'all') {
|
|
919
|
+
if (!flags.json) console.log('\nInstalling all 36 catalog skills (--all)...');
|
|
920
|
+
try {
|
|
921
|
+
execFileSync(process.execPath, [ctxScript, 'skill', 'add', '--all'], {
|
|
922
|
+
cwd: process.cwd(),
|
|
923
|
+
stdio: flags.json ? 'ignore' : 'inherit',
|
|
924
|
+
env: subEnv,
|
|
925
|
+
});
|
|
926
|
+
} catch (e) {
|
|
927
|
+
if (!flags.json) console.error(' [WARN] Failed to install catalog skills:', e.message);
|
|
928
|
+
}
|
|
929
|
+
} else if (PRESETS[presetKey]) {
|
|
930
|
+
if (!flags.json) console.log(` Installing preset '${presetKey}' skills:`);
|
|
931
|
+
const totalSkills = PRESETS[presetKey].length;
|
|
932
|
+
let count = 0;
|
|
933
|
+
for (const skillName of PRESETS[presetKey]) {
|
|
934
|
+
count++;
|
|
935
|
+
if (!flags.json) {
|
|
936
|
+
ui.renderProgressBar(count, totalSkills, skillName);
|
|
937
|
+
}
|
|
938
|
+
try {
|
|
939
|
+
execFileSync(process.execPath, [ctxScript, 'skill', 'add', skillName], {
|
|
940
|
+
cwd: process.cwd(),
|
|
941
|
+
stdio: 'ignore',
|
|
942
|
+
env: subEnv,
|
|
943
|
+
});
|
|
944
|
+
} catch (e) {
|
|
945
|
+
if (!flags.json) console.error(`\n [WARN] Failed to install preset skill '${skillName}':`, e.message);
|
|
946
|
+
}
|
|
947
|
+
}
|
|
948
|
+
if (!flags.json) console.log('\n');
|
|
949
|
+
} else {
|
|
950
|
+
if (!flags.json) console.error(` [WARN] Unknown preset '${flags.preset}'. Supported presets: frontend, backend, devops, full`);
|
|
951
|
+
}
|
|
952
|
+
}
|
|
953
|
+
}
|
|
954
|
+
|
|
831
955
|
if (flags.json) {
|
|
832
956
|
console.log(JSON.stringify({
|
|
833
957
|
success: true,
|
|
@@ -838,27 +962,15 @@ try {
|
|
|
838
962
|
agents: targetAgents,
|
|
839
963
|
withMcp: flags.withMcp,
|
|
840
964
|
minimal: flags.minimal,
|
|
965
|
+
all: flags.all,
|
|
966
|
+
preset: flags.preset,
|
|
841
967
|
}, null, 2));
|
|
842
968
|
process.exit(0);
|
|
843
969
|
}
|
|
844
970
|
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
console.log(' 3. Inspect project health anytime:');
|
|
849
|
-
console.log(' contextos doctor');
|
|
850
|
-
console.log(' 4. Switch profiles anytime:');
|
|
851
|
-
console.log(' contextos profile list');
|
|
852
|
-
console.log(' contextos profile apply mvp');
|
|
853
|
-
console.log(' 5. Export to other AI tools:');
|
|
854
|
-
console.log(' contextos export cursor → .cursorrules & .cursor/rules');
|
|
855
|
-
console.log(' contextos export copilot → .github/copilot-instructions.md');
|
|
856
|
-
console.log(' contextos export aider → .aider.conf.yml + CONVENTIONS.md');
|
|
857
|
-
console.log(' 6. Add community skills (plugins):');
|
|
858
|
-
console.log(' contextos skill add username/my-skill');
|
|
859
|
-
console.log(' contextos skill list');
|
|
860
|
-
|
|
861
|
-
console.log('');
|
|
971
|
+
if (!flags.json) {
|
|
972
|
+
ui.renderSuccessCard();
|
|
973
|
+
}
|
|
862
974
|
|
|
863
975
|
} catch (error) {
|
|
864
976
|
if (flags.json) {
|