contextos-agents 1.6.1 → 2.0.0-beta.2
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 +6 -1
- package/.agents/adapters/aider/export.js +117 -97
- package/.agents/adapters/claude/export.js +68 -26
- package/.agents/adapters/copilot/export.js +90 -51
- package/.agents/adapters/cursor/export.js +83 -68
- package/.agents/adapters/drift-detector.js +196 -0
- package/.agents/adapters/gemini/export.js +76 -45
- package/.agents/adapters/pure-compiler.js +443 -0
- package/.agents/adapters/zed/export.js +109 -62
- package/.agents/compiled/registry.v2.json +504 -0
- package/.agents/compiled/registry.v2.sha256 +1 -0
- package/.agents/compiler/manifest-compiler.js +963 -0
- package/.agents/compiler/vendor/yaml.LICENSE.txt +13 -0
- package/.agents/compiler/vendor/yaml.SBOM.json +6 -0
- package/.agents/compiler/vendor/yaml.js +139 -0
- package/.agents/core/profiles/init.yaml +25 -0
- package/.agents/core/skills/context-manager/references/context-rules.md +59 -0
- package/.agents/core/skills/context-manager/skill.yaml +10 -5
- package/.agents/core/skills/context-os/SKILL.md +3 -6
- package/.agents/core/skills/context-os/skill.yaml +14 -8
- package/.agents/core/skills/engineering-workflow/SKILL.md +1 -1
- package/.agents/core/skills/engineering-workflow/skill.yaml +7 -7
- package/.agents/core/skills/gemini-precision/SKILL.md +4 -0
- package/.agents/core/skills/gemini-precision/skill.yaml +5 -6
- package/.agents/core/skills/gstack-roles/SKILL.md +3 -1
- package/.agents/core/skills/gstack-roles/skill.yaml +9 -6
- package/.agents/core/skills/ponytail-mindset/skill.yaml +7 -7
- package/.agents/core/skills/security/skill.yaml +21 -2
- package/.agents/ctx.js +587 -111
- package/.agents/customization-dx.js +282 -0
- package/.agents/doctor.js +877 -33
- package/.agents/filesystem/index.js +71 -0
- package/.agents/filesystem/journaled-transaction.js +451 -0
- package/.agents/filesystem/lockfile-v2.js +275 -0
- package/.agents/filesystem/platform-hardening.js +222 -0
- package/.agents/filesystem/project-lock.js +218 -0
- package/.agents/filesystem/safe-path.js +256 -0
- package/.agents/generated/claude/skills/context-os/SKILL.md +1 -1
- 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/gstack-roles/SKILL.md +3 -1
- package/.agents/generated/gemini/skills/context-os/SKILL.md +2 -2
- 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/gstack-roles/SKILL.md +3 -1
- package/.agents/plugins/contextos/hooks.json +25 -0
- package/.agents/plugins/contextos/plugin.json +19 -0
- package/.agents/plugins.js +432 -73
- package/.agents/profiles.js +507 -46
- package/.agents/resolver.js +50 -414
- package/.agents/schemas/attestation.review.v1.json +111 -0
- package/.agents/schemas/attestation.verification.v1.json +85 -0
- package/.agents/schemas/lockfile.v2.schema.json +134 -0
- package/.agents/schemas/profile.v2.schema.json +114 -0
- package/.agents/schemas/runtime.thread.v1.json +192 -0
- package/.agents/schemas/skill.manifest.v2.json +177 -0
- package/.agents/schemas/verification.spec.v1.json +39 -0
- package/.agents/schemas/workspace.graph.schema.json +106 -0
- package/.agents/stats.js +22 -9
- package/.agents/transaction-core/event-store.js +288 -0
- package/.agents/transaction-core/idempotency.js +129 -0
- package/.agents/transaction-core/ipc-lock.js +311 -0
- package/.agents/transaction-core/plugin-supply-chain-bundle.js +436 -0
- package/.agents/validate.js +143 -14
- package/.agents/watch.js +354 -102
- package/.agents/workspace/workspace-graph.js +778 -0
- package/README.md +59 -387
- package/benchmarks/v2/analysis/statistics.js +140 -0
- package/benchmarks/v2/analysis/stats.js +69 -0
- package/benchmarks/v2/arms/arm-definitions.js +79 -0
- package/benchmarks/v2/dataset.schema.json +34 -0
- package/benchmarks/v2/evaluators/index.js +25 -0
- package/benchmarks/v2/evaluators/verified-success.js +116 -0
- package/benchmarks/v2/harness/runner.js +88 -0
- package/benchmarks/v2/pilot-tasks.json +392 -0
- package/bin/commands/recover.js +88 -0
- package/bin/commands/uninstall.js +207 -0
- package/bin/commands/update.js +325 -0
- package/bin/commands.js +342 -0
- package/bin/index.js +326 -149
- package/bin/lib/detector.js +106 -0
- package/bin/lib/lockfile.js +253 -0
- package/bin/lib/safe-writer.js +290 -0
- package/package.json +85 -73
- package/registry.json +15 -7
- package/registry.schema.json +3 -1
- package/registry.v2.schema.json +86 -0
- package/.agents/core/profiles/backend.yaml +0 -47
- package/.agents/core/profiles/enterprise.yaml +0 -46
- package/.agents/core/profiles/frontend.yaml +0 -46
- package/.agents/core/profiles/hackathon.yaml +0 -45
- package/.agents/core/profiles/mvp.yaml +0 -44
- package/.agents/core/profiles/startup.yaml +0 -48
- package/.agents/core/skills/adapters/EXAMPLES.md +0 -19
- package/.agents/core/skills/adapters/SKILL.md +0 -105
- package/.agents/core/skills/adapters/TROUBLESHOOTING.md +0 -7
- package/.agents/core/skills/adapters/VALIDATION.json +0 -12
- package/.agents/core/skills/adapters/skill.yaml +0 -10
- package/.agents/core/skills/architecture-diagrams/SKILL.md +0 -108
- package/.agents/core/skills/architecture-diagrams/VALIDATION.json +0 -12
- package/.agents/core/skills/architecture-diagrams/skill.yaml +0 -8
- package/.agents/core/skills/brutalist-design/SKILL.md +0 -150
- package/.agents/core/skills/brutalist-design/VALIDATION.json +0 -12
- package/.agents/core/skills/brutalist-design/skill.yaml +0 -8
- package/.agents/core/skills/database/EXAMPLES.md +0 -74
- package/.agents/core/skills/database/SKILL.md +0 -101
- package/.agents/core/skills/database/TROUBLESHOOTING.md +0 -18
- package/.agents/core/skills/database/VALIDATION.json +0 -11
- package/.agents/core/skills/database/skill.yaml +0 -25
- package/.agents/core/skills/ddd/EXAMPLES.md +0 -42
- package/.agents/core/skills/ddd/SKILL.md +0 -247
- package/.agents/core/skills/ddd/TROUBLESHOOTING.md +0 -19
- package/.agents/core/skills/ddd/VALIDATION.json +0 -12
- package/.agents/core/skills/ddd/ddd.md +0 -178
- package/.agents/core/skills/ddd/skill.yaml +0 -10
- package/.agents/core/skills/decisions/EXAMPLES.md +0 -35
- package/.agents/core/skills/decisions/SKILL.md +0 -90
- package/.agents/core/skills/decisions/TROUBLESHOOTING.md +0 -13
- package/.agents/core/skills/decisions/VALIDATION.json +0 -12
- package/.agents/core/skills/decisions/skill.yaml +0 -10
- package/.agents/core/skills/docker/EXAMPLES.md +0 -56
- package/.agents/core/skills/docker/SKILL.md +0 -63
- package/.agents/core/skills/docker/TROUBLESHOOTING.md +0 -18
- package/.agents/core/skills/docker/VALIDATION.json +0 -11
- package/.agents/core/skills/docker/skill.yaml +0 -23
- package/.agents/core/skills/fastapi/EXAMPLES.md +0 -36
- package/.agents/core/skills/fastapi/SKILL.md +0 -148
- package/.agents/core/skills/fastapi/TROUBLESHOOTING.md +0 -19
- package/.agents/core/skills/fastapi/VALIDATION.json +0 -12
- package/.agents/core/skills/fastapi/fastapi.md +0 -112
- package/.agents/core/skills/fastapi/skill.yaml +0 -10
- package/.agents/core/skills/generators/EXAMPLES.md +0 -19
- package/.agents/core/skills/generators/SKILL.md +0 -112
- package/.agents/core/skills/generators/TROUBLESHOOTING.md +0 -7
- package/.agents/core/skills/generators/VALIDATION.json +0 -12
- package/.agents/core/skills/generators/skill.yaml +0 -10
- package/.agents/core/skills/generators/templates/API.md +0 -77
- package/.agents/core/skills/generators/templates/ARCHITECTURE.md +0 -70
- package/.agents/core/skills/generators/templates/DATABASE.md +0 -42
- package/.agents/core/skills/generators/templates/DECISION.md +0 -46
- package/.agents/core/skills/generators/templates/PRD.md +0 -67
- package/.agents/core/skills/generators/templates/PROJECT_GRAPH.md +0 -56
- package/.agents/core/skills/generators/templates/ROADMAP.md +0 -51
- package/.agents/core/skills/generators/templates/TASKS.md +0 -43
- package/.agents/core/skills/generators/templates/UI.md +0 -73
- package/.agents/core/skills/graphify/EXAMPLES.md +0 -73
- package/.agents/core/skills/graphify/SKILL.md +0 -130
- package/.agents/core/skills/graphify/VALIDATION.json +0 -12
- package/.agents/core/skills/graphify/skill.yaml +0 -13
- package/.agents/core/skills/impeccable-design/EXAMPLES.md +0 -26
- package/.agents/core/skills/impeccable-design/SKILL.md +0 -201
- package/.agents/core/skills/impeccable-design/TROUBLESHOOTING.md +0 -19
- package/.agents/core/skills/impeccable-design/VALIDATION.json +0 -12
- package/.agents/core/skills/impeccable-design/skill.yaml +0 -14
- package/.agents/core/skills/interview-me/SKILL.md +0 -97
- package/.agents/core/skills/interview-me/VALIDATION.json +0 -12
- package/.agents/core/skills/interview-me/skill.yaml +0 -8
- package/.agents/core/skills/microservices/EXAMPLES.md +0 -38
- package/.agents/core/skills/microservices/SKILL.md +0 -164
- package/.agents/core/skills/microservices/TROUBLESHOOTING.md +0 -19
- package/.agents/core/skills/microservices/VALIDATION.json +0 -12
- package/.agents/core/skills/microservices/microservices.md +0 -119
- package/.agents/core/skills/microservices/skill.yaml +0 -10
- package/.agents/core/skills/minimalist-design/SKILL.md +0 -113
- package/.agents/core/skills/minimalist-design/VALIDATION.json +0 -12
- package/.agents/core/skills/minimalist-design/skill.yaml +0 -8
- package/.agents/core/skills/nestjs/EXAMPLES.md +0 -40
- package/.agents/core/skills/nestjs/SKILL.md +0 -139
- package/.agents/core/skills/nestjs/TROUBLESHOOTING.md +0 -19
- package/.agents/core/skills/nestjs/VALIDATION.json +0 -12
- package/.agents/core/skills/nestjs/nestjs.md +0 -103
- package/.agents/core/skills/nestjs/skill.yaml +0 -10
- package/.agents/core/skills/nextjs/EXAMPLES.md +0 -40
- package/.agents/core/skills/nextjs/SKILL.md +0 -163
- package/.agents/core/skills/nextjs/TROUBLESHOOTING.md +0 -19
- package/.agents/core/skills/nextjs/VALIDATION.json +0 -12
- package/.agents/core/skills/nextjs/nextjs.md +0 -67
- package/.agents/core/skills/nextjs/skill.yaml +0 -10
- package/.agents/core/skills/node/EXAMPLES.md +0 -80
- package/.agents/core/skills/node/SKILL.md +0 -128
- package/.agents/core/skills/node/TROUBLESHOOTING.md +0 -19
- package/.agents/core/skills/node/VALIDATION.json +0 -12
- package/.agents/core/skills/node/node.md +0 -87
- package/.agents/core/skills/node/skill.yaml +0 -10
- package/.agents/core/skills/performance/EXAMPLES.md +0 -30
- package/.agents/core/skills/performance/SKILL.md +0 -75
- package/.agents/core/skills/performance/TROUBLESHOOTING.md +0 -19
- package/.agents/core/skills/performance/VALIDATION.json +0 -12
- package/.agents/core/skills/performance/performance.md +0 -52
- package/.agents/core/skills/performance/skill.yaml +0 -10
- package/.agents/core/skills/react/EXAMPLES.md +0 -79
- package/.agents/core/skills/react/SKILL.md +0 -132
- package/.agents/core/skills/react/TROUBLESHOOTING.md +0 -19
- package/.agents/core/skills/react/VALIDATION.json +0 -12
- package/.agents/core/skills/react/react.md +0 -93
- package/.agents/core/skills/react/skill.yaml +0 -10
- package/.agents/core/skills/react-best-practices/SKILL.md +0 -155
- package/.agents/core/skills/react-best-practices/VALIDATION.json +0 -12
- package/.agents/core/skills/react-best-practices/skill.yaml +0 -10
- package/.agents/core/skills/redesign-audit/SKILL.md +0 -117
- package/.agents/core/skills/redesign-audit/VALIDATION.json +0 -12
- package/.agents/core/skills/redesign-audit/skill.yaml +0 -8
- package/.agents/core/skills/soft-design/SKILL.md +0 -108
- package/.agents/core/skills/soft-design/VALIDATION.json +0 -12
- package/.agents/core/skills/soft-design/skill.yaml +0 -8
- package/.agents/core/skills/state-management/EXAMPLES.md +0 -56
- package/.agents/core/skills/state-management/SKILL.md +0 -48
- package/.agents/core/skills/state-management/TROUBLESHOOTING.md +0 -18
- package/.agents/core/skills/state-management/VALIDATION.json +0 -11
- package/.agents/core/skills/state-management/skill.yaml +0 -22
- package/.agents/core/skills/subagent-orchestrator/SKILL.md +0 -100
- package/.agents/core/skills/subagent-orchestrator/VALIDATION.json +0 -12
- package/.agents/core/skills/subagent-orchestrator/skill.yaml +0 -8
- package/.agents/core/skills/system-design/EXAMPLES.md +0 -75
- package/.agents/core/skills/system-design/SKILL.md +0 -419
- package/.agents/core/skills/system-design/TROUBLESHOOTING.md +0 -19
- package/.agents/core/skills/system-design/VALIDATION.json +0 -12
- package/.agents/core/skills/system-design/skill.yaml +0 -13
- package/.agents/core/skills/system-design/system-design.md +0 -112
- package/.agents/core/skills/testing/EXAMPLES.md +0 -71
- package/.agents/core/skills/testing/SKILL.md +0 -70
- package/.agents/core/skills/testing/TROUBLESHOOTING.md +0 -18
- package/.agents/core/skills/testing/VALIDATION.json +0 -11
- package/.agents/core/skills/testing/skill.yaml +0 -26
- package/.agents/core/skills/typescript/EXAMPLES.md +0 -64
- package/.agents/core/skills/typescript/SKILL.md +0 -112
- package/.agents/core/skills/typescript/TROUBLESHOOTING.md +0 -19
- package/.agents/core/skills/typescript/VALIDATION.json +0 -12
- package/.agents/core/skills/typescript/skill.yaml +0 -10
- package/.agents/core/skills/typescript/typescript.md +0 -71
- package/.agents/core/skills/ui-design/EXAMPLES.md +0 -21
- package/.agents/core/skills/ui-design/SKILL.md +0 -124
- package/.agents/core/skills/ui-design/TROUBLESHOOTING.md +0 -19
- package/.agents/core/skills/ui-design/VALIDATION.json +0 -12
- package/.agents/core/skills/ui-design/skill.yaml +0 -10
- package/.agents/core/skills/ui-design/ui.md +0 -88
- package/.agents/core/skills/ui-ux-pro/EXAMPLES.md +0 -62
- package/.agents/core/skills/ui-ux-pro/SKILL.md +0 -375
- package/.agents/core/skills/ui-ux-pro/TROUBLESHOOTING.md +0 -19
- package/.agents/core/skills/ui-ux-pro/VALIDATION.json +0 -12
- package/.agents/core/skills/ui-ux-pro/skill.yaml +0 -13
- package/.agents/core/skills/ux-design/EXAMPLES.md +0 -36
- package/.agents/core/skills/ux-design/SKILL.md +0 -116
- package/.agents/core/skills/ux-design/TROUBLESHOOTING.md +0 -19
- package/.agents/core/skills/ux-design/VALIDATION.json +0 -12
- package/.agents/core/skills/ux-design/skill.yaml +0 -10
- package/.agents/core/skills/ux-design/ux.md +0 -80
- package/.agents/core/skills/vercel-optimize/SKILL.md +0 -83
- package/.agents/core/skills/vercel-optimize/VALIDATION.json +0 -12
- package/.agents/core/skills/vercel-optimize/skill.yaml +0 -10
- package/.agents/core/skills/web-accessibility/EXAMPLES.md +0 -39
- package/.agents/core/skills/web-accessibility/SKILL.md +0 -170
- package/.agents/core/skills/web-accessibility/TROUBLESHOOTING.md +0 -19
- package/.agents/core/skills/web-accessibility/VALIDATION.json +0 -12
- package/.agents/core/skills/web-accessibility/accessibility.md +0 -63
- package/.agents/core/skills/web-accessibility/skill.yaml +0 -10
- package/.agents/generated/claude/skills/adapters/SKILL.md +0 -126
- package/.agents/generated/claude/skills/architecture-diagrams/SKILL.md +0 -101
- package/.agents/generated/claude/skills/brutalist-design/SKILL.md +0 -145
- package/.agents/generated/claude/skills/database/SKILL.md +0 -191
- package/.agents/generated/claude/skills/ddd/SKILL.md +0 -305
- package/.agents/generated/claude/skills/decisions/SKILL.md +0 -134
- package/.agents/generated/claude/skills/docker/SKILL.md +0 -135
- package/.agents/generated/claude/skills/fastapi/SKILL.md +0 -200
- package/.agents/generated/claude/skills/generators/SKILL.md +0 -133
- package/.agents/generated/claude/skills/graphify/SKILL.md +0 -198
- package/.agents/generated/claude/skills/impeccable-design/SKILL.md +0 -241
- package/.agents/generated/claude/skills/interview-me/SKILL.md +0 -90
- package/.agents/generated/claude/skills/microservices/SKILL.md +0 -218
- package/.agents/generated/claude/skills/minimalist-design/SKILL.md +0 -108
- package/.agents/generated/claude/skills/nestjs/SKILL.md +0 -195
- package/.agents/generated/claude/skills/nextjs/SKILL.md +0 -219
- package/.agents/generated/claude/skills/node/SKILL.md +0 -224
- package/.agents/generated/claude/skills/performance/SKILL.md +0 -121
- package/.agents/generated/claude/skills/react/SKILL.md +0 -227
- package/.agents/generated/claude/skills/react-best-practices/SKILL.md +0 -146
- package/.agents/generated/claude/skills/redesign-audit/SKILL.md +0 -112
- package/.agents/generated/claude/skills/soft-design/SKILL.md +0 -103
- package/.agents/generated/claude/skills/state-management/SKILL.md +0 -120
- package/.agents/generated/claude/skills/subagent-orchestrator/SKILL.md +0 -93
- package/.agents/generated/claude/skills/system-design/SKILL.md +0 -507
- package/.agents/generated/claude/skills/testing/SKILL.md +0 -157
- package/.agents/generated/claude/skills/typescript/SKILL.md +0 -192
- package/.agents/generated/claude/skills/ui-design/SKILL.md +0 -161
- package/.agents/generated/claude/skills/ui-ux-pro/SKILL.md +0 -451
- package/.agents/generated/claude/skills/ux-design/SKILL.md +0 -168
- package/.agents/generated/claude/skills/vercel-optimize/SKILL.md +0 -76
- package/.agents/generated/claude/skills/web-accessibility/SKILL.md +0 -225
- package/.agents/generated/gemini/skills/adapters/SKILL.md +0 -135
- package/.agents/generated/gemini/skills/architecture-diagrams/SKILL.md +0 -107
- package/.agents/generated/gemini/skills/brutalist-design/SKILL.md +0 -151
- package/.agents/generated/gemini/skills/database/SKILL.md +0 -200
- package/.agents/generated/gemini/skills/ddd/SKILL.md +0 -314
- package/.agents/generated/gemini/skills/decisions/SKILL.md +0 -143
- package/.agents/generated/gemini/skills/docker/SKILL.md +0 -144
- package/.agents/generated/gemini/skills/fastapi/SKILL.md +0 -209
- package/.agents/generated/gemini/skills/generators/SKILL.md +0 -142
- package/.agents/generated/gemini/skills/graphify/SKILL.md +0 -205
- package/.agents/generated/gemini/skills/impeccable-design/SKILL.md +0 -250
- package/.agents/generated/gemini/skills/interview-me/SKILL.md +0 -96
- package/.agents/generated/gemini/skills/microservices/SKILL.md +0 -227
- package/.agents/generated/gemini/skills/minimalist-design/SKILL.md +0 -114
- package/.agents/generated/gemini/skills/nestjs/SKILL.md +0 -204
- package/.agents/generated/gemini/skills/nextjs/SKILL.md +0 -298
- package/.agents/generated/gemini/skills/node/SKILL.md +0 -323
- package/.agents/generated/gemini/skills/performance/SKILL.md +0 -185
- package/.agents/generated/gemini/skills/react/SKILL.md +0 -332
- package/.agents/generated/gemini/skills/react-best-practices/SKILL.md +0 -152
- package/.agents/generated/gemini/skills/redesign-audit/SKILL.md +0 -118
- package/.agents/generated/gemini/skills/soft-design/SKILL.md +0 -109
- package/.agents/generated/gemini/skills/state-management/SKILL.md +0 -129
- package/.agents/generated/gemini/skills/subagent-orchestrator/SKILL.md +0 -99
- package/.agents/generated/gemini/skills/system-design/SKILL.md +0 -631
- package/.agents/generated/gemini/skills/testing/SKILL.md +0 -166
- package/.agents/generated/gemini/skills/typescript/SKILL.md +0 -275
- package/.agents/generated/gemini/skills/ui-design/SKILL.md +0 -170
- package/.agents/generated/gemini/skills/ui-ux-pro/SKILL.md +0 -460
- package/.agents/generated/gemini/skills/ux-design/SKILL.md +0 -177
- package/.agents/generated/gemini/skills/vercel-optimize/SKILL.md +0 -82
- package/.agents/generated/gemini/skills/web-accessibility/SKILL.md +0 -300
- package/.agents/mcp/runtime.py +0 -470
- package/.agents/mcp/server.mjs +0 -189271
- package/benchmarks/gemini-issues.js +0 -533
|
@@ -0,0 +1,325 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* bin/commands/update.js
|
|
3
|
+
* ContextOS CLI — Safe Update Command
|
|
4
|
+
*
|
|
5
|
+
* Updates ContextOS installation non-destructively:
|
|
6
|
+
* - Scans distribution package against target project .agents directory
|
|
7
|
+
* - Plans all mutations: CREATE, UPDATE, CONFLICT, SKIP, DELETE
|
|
8
|
+
* - Never overwrites user-customized files (generates .contextos.new conflicts)
|
|
9
|
+
* - Never touches or deletes unmanaged user files or custom skills
|
|
10
|
+
* - Supports --dry-run to preview changes without modifying filesystem
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
const fs = require('fs');
|
|
14
|
+
const path = require('path');
|
|
15
|
+
const {
|
|
16
|
+
LockfileV2Manager,
|
|
17
|
+
ProjectMutationLock,
|
|
18
|
+
JournaledTransaction,
|
|
19
|
+
computeExactHash,
|
|
20
|
+
computeSemanticHash,
|
|
21
|
+
} = require('../../.agents/filesystem/index.js');
|
|
22
|
+
const {
|
|
23
|
+
loadLockfile,
|
|
24
|
+
saveLockfile,
|
|
25
|
+
recordManagedFile,
|
|
26
|
+
migrateExistingInstallation,
|
|
27
|
+
} = require('../lib/lockfile.js');
|
|
28
|
+
const {
|
|
29
|
+
planFileWrite,
|
|
30
|
+
planFileDelete,
|
|
31
|
+
cleanEmptyParentDirectories,
|
|
32
|
+
} = require('../lib/safe-writer.js');
|
|
33
|
+
|
|
34
|
+
const pkg = require('../../package.json');
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Collect all distributable files from the source .agents directory.
|
|
38
|
+
*/
|
|
39
|
+
function collectDistributionFiles(sourceAgentsDir, options = {}) {
|
|
40
|
+
const files = [];
|
|
41
|
+
const excludedSkills = new Set(options.excludedSkills || []);
|
|
42
|
+
|
|
43
|
+
function walk(currentDir) {
|
|
44
|
+
let entries;
|
|
45
|
+
try {
|
|
46
|
+
entries = fs.readdirSync(currentDir, { withFileTypes: true });
|
|
47
|
+
} catch {
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
for (const entry of entries) {
|
|
52
|
+
const full = path.join(currentDir, entry.name);
|
|
53
|
+
if (entry.isDirectory()) {
|
|
54
|
+
// Skip .git or temp dirs if any
|
|
55
|
+
if (entry.name === '.git' || entry.name === 'node_modules') continue;
|
|
56
|
+
|
|
57
|
+
// Skip excluded skills by profile
|
|
58
|
+
const relToAgents = path.relative(sourceAgentsDir, full).replace(/\\/g, '/');
|
|
59
|
+
const coreMatch = relToAgents.match(/^core\/skills\/([^/]+)$/);
|
|
60
|
+
if (coreMatch && excludedSkills.has(coreMatch[1])) {
|
|
61
|
+
continue;
|
|
62
|
+
}
|
|
63
|
+
const genMatch = relToAgents.match(/^generated\/[^/]+\/skills\/([^/]+)$/);
|
|
64
|
+
if (genMatch && excludedSkills.has(genMatch[1])) {
|
|
65
|
+
continue;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
walk(full);
|
|
69
|
+
} else if (entry.isFile()) {
|
|
70
|
+
// Do not distribute lockfile itself or backup files
|
|
71
|
+
if (entry.name === 'contextos.lock.json' || entry.name.endsWith('.bak')) continue;
|
|
72
|
+
|
|
73
|
+
const relToAgents = path.relative(sourceAgentsDir, full).replace(/\\/g, '/');
|
|
74
|
+
files.push({
|
|
75
|
+
relPath: `.agents/${relToAgents}`,
|
|
76
|
+
fullSourcePath: full,
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
walk(sourceAgentsDir);
|
|
83
|
+
return files;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Plan the update operations for a project.
|
|
88
|
+
*/
|
|
89
|
+
function planUpdate(projectDir, sourceAgentsDir, options = {}) {
|
|
90
|
+
const targetAgentsDir = path.join(projectDir, '.agents');
|
|
91
|
+
if (!fs.existsSync(targetAgentsDir)) {
|
|
92
|
+
return {
|
|
93
|
+
ok: false,
|
|
94
|
+
error: 'NO_AGENTS_DIR',
|
|
95
|
+
message: 'No .agents/ directory found in the target project. Run `contextos` to install first.',
|
|
96
|
+
plans: [],
|
|
97
|
+
summary: { create: 0, update: 0, conflict: 0, skip: 0, delete: 0 },
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
// Load existing lockfile or safely migrate
|
|
102
|
+
let lockData = loadLockfile(projectDir);
|
|
103
|
+
let migrated = false;
|
|
104
|
+
if (!lockData) {
|
|
105
|
+
lockData = migrateExistingInstallation(projectDir, sourceAgentsDir, {
|
|
106
|
+
dryRun: Boolean(options.dryRun),
|
|
107
|
+
version: pkg.version,
|
|
108
|
+
});
|
|
109
|
+
migrated = true;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
// Determine active profile exclusions if available
|
|
113
|
+
let excludedSkills = [];
|
|
114
|
+
try {
|
|
115
|
+
const profilesPath = path.join(projectDir, '.agents', 'profiles.js');
|
|
116
|
+
if (fs.existsSync(profilesPath)) {
|
|
117
|
+
const profilesModule = require(profilesPath);
|
|
118
|
+
const active = profilesModule.getActiveProfile(projectDir);
|
|
119
|
+
if (active && Array.isArray(active.exclude_skills)) {
|
|
120
|
+
excludedSkills = active.exclude_skills;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
} catch {}
|
|
124
|
+
|
|
125
|
+
const distFiles = collectDistributionFiles(sourceAgentsDir, { excludedSkills });
|
|
126
|
+
const distRelPaths = new Set(distFiles.map(f => f.relPath));
|
|
127
|
+
|
|
128
|
+
const plans = [];
|
|
129
|
+
|
|
130
|
+
// 1. Plan writes for distribution files
|
|
131
|
+
for (const item of distFiles) {
|
|
132
|
+
try {
|
|
133
|
+
const content = fs.readFileSync(item.fullSourcePath, 'utf8');
|
|
134
|
+
const plan = planFileWrite({
|
|
135
|
+
projectDir,
|
|
136
|
+
relPath: item.relPath,
|
|
137
|
+
content,
|
|
138
|
+
lockData,
|
|
139
|
+
});
|
|
140
|
+
plans.push(plan);
|
|
141
|
+
} catch {}
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
// 2. Plan deletions for stale managed files that no longer exist in distribution
|
|
145
|
+
if (lockData && lockData.managedFiles) {
|
|
146
|
+
for (const managedRel of Object.keys(lockData.managedFiles)) {
|
|
147
|
+
if (managedRel.startsWith('.agents/') && !distRelPaths.has(managedRel)) {
|
|
148
|
+
const delPlan = planFileDelete({
|
|
149
|
+
projectDir,
|
|
150
|
+
relPath: managedRel,
|
|
151
|
+
lockData,
|
|
152
|
+
});
|
|
153
|
+
plans.push(delPlan);
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
const summary = {
|
|
159
|
+
create: plans.filter(p => p.action === 'CREATE').length,
|
|
160
|
+
update: plans.filter(p => p.action === 'UPDATE').length,
|
|
161
|
+
conflict: plans.filter(p => p.action === 'CONFLICT').length,
|
|
162
|
+
skip: plans.filter(p => p.action === 'SKIP').length,
|
|
163
|
+
delete: plans.filter(p => p.action === 'DELETE').length,
|
|
164
|
+
};
|
|
165
|
+
|
|
166
|
+
return {
|
|
167
|
+
ok: true,
|
|
168
|
+
lockData,
|
|
169
|
+
migrated,
|
|
170
|
+
plans,
|
|
171
|
+
summary,
|
|
172
|
+
};
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
/**
|
|
176
|
+
* Run the update command against a target project.
|
|
177
|
+
*/
|
|
178
|
+
function runUpdate(projectDir = process.cwd(), options = {}) {
|
|
179
|
+
const sourceAgentsDir = options.sourceAgentsDir || path.join(__dirname, '..', '..', '.agents');
|
|
180
|
+
const dryRun = Boolean(options.dryRun);
|
|
181
|
+
|
|
182
|
+
console.log(`\nContextOS Safe Update ${dryRun ? '[DRY-RUN]' : ''}`);
|
|
183
|
+
console.log(`Target: ${projectDir}`);
|
|
184
|
+
|
|
185
|
+
const planned = planUpdate(projectDir, sourceAgentsDir, options);
|
|
186
|
+
if (!planned.ok) {
|
|
187
|
+
console.error(`\n[ERROR] ${planned.message}`);
|
|
188
|
+
return planned;
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
const { lockData, plans, summary } = planned;
|
|
192
|
+
|
|
193
|
+
// Print classified plan preview
|
|
194
|
+
console.log('\nPlanned Actions:');
|
|
195
|
+
for (const item of plans) {
|
|
196
|
+
if (item.action === 'CREATE') {
|
|
197
|
+
console.log(` + CREATE ${item.relPath}`);
|
|
198
|
+
} else if (item.action === 'UPDATE') {
|
|
199
|
+
console.log(` ~ UPDATE ${item.relPath}`);
|
|
200
|
+
} else if (item.action === 'CONFLICT') {
|
|
201
|
+
console.log(` ! CONFLICT ${item.relPath} → ${item.conflictPath || item.relPath + '.contextos.new'} (customized by user)`);
|
|
202
|
+
} else if (item.action === 'DELETE') {
|
|
203
|
+
console.log(` - DELETE ${item.relPath} (stale managed file)`);
|
|
204
|
+
} else if (item.action === 'SKIP' && item.reason === 'UNMANAGED_USER_FILE') {
|
|
205
|
+
console.log(` = PRESERVE ${item.relPath} (unmanaged user file)`);
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
console.log('\nSummary:');
|
|
210
|
+
console.log(` Created: ${summary.create}`);
|
|
211
|
+
console.log(` Updated: ${summary.update}`);
|
|
212
|
+
console.log(` Conflicts: ${summary.conflict} (written as .contextos.new)`);
|
|
213
|
+
console.log(` Deleted: ${summary.delete}`);
|
|
214
|
+
console.log(` Skipped: ${summary.skip}`);
|
|
215
|
+
|
|
216
|
+
if (dryRun) {
|
|
217
|
+
console.log('\n[DRY-RUN] No changes were written to disk.');
|
|
218
|
+
return { ...planned, executed: false };
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
// Execute plans
|
|
222
|
+
let executedCount = 0;
|
|
223
|
+
|
|
224
|
+
const lock = new ProjectMutationLock(projectDir);
|
|
225
|
+
const lockToken = lock.acquire({ command: 'update' });
|
|
226
|
+
|
|
227
|
+
try {
|
|
228
|
+
const tx = new JournaledTransaction(projectDir);
|
|
229
|
+
|
|
230
|
+
for (const item of plans) {
|
|
231
|
+
if (item.action === 'CREATE' || item.action === 'UPDATE' || item.action === 'CONFLICT') {
|
|
232
|
+
const targetRel = item.action === 'CONFLICT' ? (item.conflictPath || `${item.relPath}.contextos.new`) : item.relPath;
|
|
233
|
+
tx.stageWrite(targetRel, item.newContent);
|
|
234
|
+
if (item.action !== 'SKIP') executedCount++;
|
|
235
|
+
} else if (item.action === 'DELETE') {
|
|
236
|
+
tx.stageDelete(item.relPath);
|
|
237
|
+
executedCount++;
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
const txResult = tx.commit();
|
|
242
|
+
|
|
243
|
+
// Clean up empty directories left behind by deletions
|
|
244
|
+
for (const item of plans) {
|
|
245
|
+
if (item.action === 'DELETE') {
|
|
246
|
+
cleanEmptyParentDirectories(path.join(projectDir, item.relPath));
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
// Update lockfile metadata via V2 Manager
|
|
251
|
+
const lockfileManager = new LockfileV2Manager(projectDir);
|
|
252
|
+
let lockfileData = lockfileManager.read();
|
|
253
|
+
|
|
254
|
+
if (!lockfileData) {
|
|
255
|
+
lockfileData = lockfileManager.createEmpty({ packageVersion: options.packageVersion || pkg.version });
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
for (const item of plans) {
|
|
259
|
+
if (item.action === 'CREATE' || item.action === 'UPDATE') {
|
|
260
|
+
lockfileManager.recordManagedFile(lockfileData, item.relPath, {
|
|
261
|
+
exactSha256: computeExactHash(item.newContent),
|
|
262
|
+
semanticTextSha256: computeSemanticHash(item.newContent),
|
|
263
|
+
kind: 'distribution-skill',
|
|
264
|
+
generator: 'update',
|
|
265
|
+
lastTransaction: txResult.txId,
|
|
266
|
+
});
|
|
267
|
+
} else if (item.action === 'DELETE') {
|
|
268
|
+
if (lockfileData.managedFiles && lockfileData.managedFiles[item.relPath]) {
|
|
269
|
+
delete lockfileData.managedFiles[item.relPath];
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
lockfileData.package.version = options.packageVersion || pkg.version;
|
|
275
|
+
// We update the timestamp equivalent in v2
|
|
276
|
+
lockfileManager.write(lockfileData);
|
|
277
|
+
|
|
278
|
+
if (lockData) {
|
|
279
|
+
for (const item of plans) {
|
|
280
|
+
if (item.action === 'CREATE' || item.action === 'UPDATE') {
|
|
281
|
+
recordManagedFile(lockData, item.relPath, item.newContent);
|
|
282
|
+
} else if (item.action === 'DELETE') {
|
|
283
|
+
if (lockData.managedFiles) delete lockData.managedFiles[item.relPath];
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
lockData.version = options.packageVersion || pkg.version;
|
|
287
|
+
saveLockfile(projectDir, lockData);
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
} finally {
|
|
291
|
+
lock.release(lockToken);
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
console.log(`\n[OK] ContextOS successfully updated!`);
|
|
295
|
+
if (summary.conflict > 0) {
|
|
296
|
+
console.warn(`[WARN] ${summary.conflict} customized file(s) had upstream changes.`);
|
|
297
|
+
console.warn(' Inspect the .contextos.new file(s) to merge upstream updates.');
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
// Re-compile if ctx.js exists and not skipped
|
|
301
|
+
if (!options.skipCompile) {
|
|
302
|
+
const ctxPath = path.join(projectDir, '.agents', 'ctx.js');
|
|
303
|
+
if (fs.existsSync(ctxPath)) {
|
|
304
|
+
try {
|
|
305
|
+
const { execFileSync } = require('child_process');
|
|
306
|
+
console.log('\nRecompiling skills...');
|
|
307
|
+
execFileSync(process.execPath, [ctxPath, 'export', 'gemini'], {
|
|
308
|
+
cwd: projectDir,
|
|
309
|
+
stdio: 'inherit',
|
|
310
|
+
});
|
|
311
|
+
} catch (err) {
|
|
312
|
+
console.error(`[ERROR] Post-update compilation failed: ${err.message}`);
|
|
313
|
+
process.exit(1);
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
return { ...planned, executed: true, executedCount };
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
module.exports = {
|
|
322
|
+
planUpdate,
|
|
323
|
+
runUpdate,
|
|
324
|
+
collectDistributionFiles,
|
|
325
|
+
};
|
package/bin/commands.js
ADDED
|
@@ -0,0 +1,342 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* bin/commands.js
|
|
3
|
+
* ContextOS — Declarative CLI Command Registry & Status Engine
|
|
4
|
+
*
|
|
5
|
+
* Defines the canonical registry of CLI commands, options, and handlers.
|
|
6
|
+
* Supports structured execution and machine-readable --json output.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
'use strict';
|
|
10
|
+
|
|
11
|
+
const fs = require('fs');
|
|
12
|
+
const path = require('path');
|
|
13
|
+
const { version } = require('../package.json');
|
|
14
|
+
const profiles = require('../.agents/profiles.js');
|
|
15
|
+
const lockfileLib = require('./lib/lockfile.js');
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Collects holistic status metadata for a target project.
|
|
19
|
+
*
|
|
20
|
+
* @param {string} [projectDir=process.cwd()] - Project directory
|
|
21
|
+
* @returns {Object} Structured project status
|
|
22
|
+
*/
|
|
23
|
+
function getStatus(projectDir = process.cwd()) {
|
|
24
|
+
const agentsDir = path.join(projectDir, '.agents');
|
|
25
|
+
const hasAgents = fs.existsSync(agentsDir);
|
|
26
|
+
const lockData = lockfileLib.loadLockfile(projectDir);
|
|
27
|
+
const activeProfile = hasAgents ? profiles.getActiveProfile(projectDir) : null;
|
|
28
|
+
|
|
29
|
+
let skillsCount = 0;
|
|
30
|
+
const skillsDir = path.join(agentsDir, 'core', 'skills');
|
|
31
|
+
if (fs.existsSync(skillsDir)) {
|
|
32
|
+
try {
|
|
33
|
+
skillsCount = fs.readdirSync(skillsDir, { withFileTypes: true })
|
|
34
|
+
.filter(d => d.isDirectory() && fs.existsSync(path.join(skillsDir, d.name, 'SKILL.md')))
|
|
35
|
+
.length;
|
|
36
|
+
} catch {
|
|
37
|
+
skillsCount = 0;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
const mcpServerPath = path.join(agentsDir, 'mcp', 'server.mjs');
|
|
42
|
+
const mcpInstalled = fs.existsSync(mcpServerPath);
|
|
43
|
+
|
|
44
|
+
// Check compiled adapter outputs
|
|
45
|
+
const compiledAdapters = [];
|
|
46
|
+
if (fs.existsSync(path.join(agentsDir, 'generated', 'gemini', 'skills'))) compiledAdapters.push('gemini');
|
|
47
|
+
if (fs.existsSync(path.join(agentsDir, 'generated', 'claude', 'skills'))) compiledAdapters.push('claude');
|
|
48
|
+
if (fs.existsSync(path.join(projectDir, '.cursorrules')) || fs.existsSync(path.join(projectDir, '.cursor', 'rules'))) compiledAdapters.push('cursor');
|
|
49
|
+
if (fs.existsSync(path.join(projectDir, '.github', 'copilot-instructions.md'))) compiledAdapters.push('copilot');
|
|
50
|
+
if (fs.existsSync(path.join(projectDir, '.aider.conf.yml'))) compiledAdapters.push('aider');
|
|
51
|
+
if (fs.existsSync(path.join(projectDir, '.zed', 'rules.md'))) compiledAdapters.push('zed');
|
|
52
|
+
|
|
53
|
+
return {
|
|
54
|
+
package: 'contextos-agents',
|
|
55
|
+
version,
|
|
56
|
+
projectDir,
|
|
57
|
+
initialized: hasAgents,
|
|
58
|
+
activeProfile: activeProfile ? activeProfile.profile : (lockData?.selectedProfile || 'none'),
|
|
59
|
+
skillsCount,
|
|
60
|
+
mcpInstalled,
|
|
61
|
+
compiledAdapters,
|
|
62
|
+
lockfile: lockData ? {
|
|
63
|
+
schemaVersion: lockData.schemaVersion,
|
|
64
|
+
version: lockData.version,
|
|
65
|
+
managedFilesCount: Object.keys(lockData.managedFiles || {}).length,
|
|
66
|
+
selectedProfile: lockData.selectedProfile,
|
|
67
|
+
installedAt: lockData.installedAt,
|
|
68
|
+
updatedAt: lockData.updatedAt,
|
|
69
|
+
} : null,
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* Formats status object as human-readable text.
|
|
75
|
+
*
|
|
76
|
+
* @param {Object} status - Status object
|
|
77
|
+
* @returns {string} Formatted text
|
|
78
|
+
*/
|
|
79
|
+
function formatStatusText(status) {
|
|
80
|
+
const lines = [
|
|
81
|
+
`ContextOS Project Status (v${status.version})`,
|
|
82
|
+
`──────────────────────────────────────────────`,
|
|
83
|
+
` Project Dir : ${status.projectDir}`,
|
|
84
|
+
` Initialized : ${status.initialized ? 'Yes (.agents/ found)' : 'No (run: npx contextos-agents init)'}`,
|
|
85
|
+
` Active Profile : ${status.activeProfile}`,
|
|
86
|
+
` Skills Installed : ${status.skillsCount}`,
|
|
87
|
+
` MCP Server : ${status.mcpInstalled ? 'Installed (.agents/mcp/)' : 'Not installed'}`,
|
|
88
|
+
` Adapters Compiled : ${status.compiledAdapters.length ? status.compiledAdapters.join(', ') : 'none'}`,
|
|
89
|
+
];
|
|
90
|
+
|
|
91
|
+
if (status.lockfile) {
|
|
92
|
+
lines.push(` Lockfile : Valid (${status.lockfile.managedFilesCount} managed files, v${status.lockfile.version})`);
|
|
93
|
+
} else if (status.initialized) {
|
|
94
|
+
lines.push(` Lockfile : Missing (.agents/contextos.lock.json)`);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
return lines.join('\n');
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* Registry of canonical ContextOS CLI commands.
|
|
102
|
+
*/
|
|
103
|
+
const COMMAND_REGISTRY = {
|
|
104
|
+
init: {
|
|
105
|
+
name: 'init',
|
|
106
|
+
description: 'Compile and govern engineering context across AI coding agents.',
|
|
107
|
+
usage: 'npx contextos-agents init [options]',
|
|
108
|
+
requiresProject: false,
|
|
109
|
+
options: [
|
|
110
|
+
{ flag: '--agent <target>', desc: 'Target agent (gemini, claude, cursor, auto)' },
|
|
111
|
+
{ flag: '--profile <name>', desc: 'Apply specific profile (mvp, startup, enterprise, etc.)' },
|
|
112
|
+
{ flag: '--auto', desc: 'Auto-detect tech stack and recommended profile' },
|
|
113
|
+
{ flag: '--minimal', desc: 'Install the 7-skill neutral bootstrap.' },
|
|
114
|
+
{ flag: '--force', desc: 'Overwrite existing installation' },
|
|
115
|
+
{ flag: '--dry-run', desc: 'Preview installation actions without writing' },
|
|
116
|
+
{ flag: '--skip-compile', desc: 'Skip auto-compiling skills after install' },
|
|
117
|
+
],
|
|
118
|
+
},
|
|
119
|
+
status: {
|
|
120
|
+
name: 'status',
|
|
121
|
+
description: 'Display project configuration, active profile, and lockfile status',
|
|
122
|
+
usage: 'contextos status [--json]',
|
|
123
|
+
requiresProject: false,
|
|
124
|
+
options: [
|
|
125
|
+
{ flag: '--json', desc: 'Output status in JSON format' },
|
|
126
|
+
],
|
|
127
|
+
},
|
|
128
|
+
update: {
|
|
129
|
+
name: 'update',
|
|
130
|
+
description: 'Safely update skills without overwriting user custom changes',
|
|
131
|
+
usage: 'contextos update [--dry-run] [--profile <name>] [--json]',
|
|
132
|
+
requiresProject: true,
|
|
133
|
+
options: [
|
|
134
|
+
{ flag: '--dry-run', desc: 'Preview updates without modifying disk' },
|
|
135
|
+
{ flag: '--profile <name>', desc: 'Switch profile during update' },
|
|
136
|
+
{ flag: '--json', desc: 'Output results in JSON format' },
|
|
137
|
+
],
|
|
138
|
+
},
|
|
139
|
+
uninstall: {
|
|
140
|
+
name: 'uninstall',
|
|
141
|
+
description: 'Safely uninstall managed ContextOS files (preserves user custom skills)',
|
|
142
|
+
usage: 'contextos uninstall [--dry-run] [--json]',
|
|
143
|
+
requiresProject: true,
|
|
144
|
+
options: [
|
|
145
|
+
{ flag: '--dry-run', desc: 'Preview deletions without modifying disk' },
|
|
146
|
+
{ flag: '--json', desc: 'Output results in JSON format' },
|
|
147
|
+
],
|
|
148
|
+
},
|
|
149
|
+
doctor: {
|
|
150
|
+
name: 'doctor',
|
|
151
|
+
description: 'Run project diagnostic health check (Doctor v2)',
|
|
152
|
+
usage: 'contextos doctor [--fix] [--strict] [--json]',
|
|
153
|
+
requiresProject: false,
|
|
154
|
+
options: [
|
|
155
|
+
{ flag: '--fix', desc: 'Automatically remediate safe diagnostic issues and clean caches' },
|
|
156
|
+
{ flag: '--strict', desc: 'Exit with non-zero code on any warning' },
|
|
157
|
+
{ flag: '--json', desc: 'Output health report in versioned JSON format' },
|
|
158
|
+
],
|
|
159
|
+
},
|
|
160
|
+
recover: {
|
|
161
|
+
name: 'recover',
|
|
162
|
+
description: 'List, rollback, or resume stuck filesystem transactions',
|
|
163
|
+
usage: 'contextos recover [--list] [--rollback <txId>] [--resume <txId>]',
|
|
164
|
+
requiresProject: true,
|
|
165
|
+
options: [
|
|
166
|
+
{ flag: '--list', desc: 'List pending or broken transactions requiring recovery' },
|
|
167
|
+
{ flag: '--rollback <txId>', desc: 'Rollback a broken transaction' },
|
|
168
|
+
{ flag: '--resume <txId>', desc: 'Resume and complete a stuck transaction' },
|
|
169
|
+
],
|
|
170
|
+
},
|
|
171
|
+
compile: {
|
|
172
|
+
name: 'compile',
|
|
173
|
+
description: 'Compile skill manifests into deterministic registry v2 (registry.v2.json)',
|
|
174
|
+
usage: 'contextos compile [--check] [--sarif] [--json]',
|
|
175
|
+
requiresProject: true,
|
|
176
|
+
options: [
|
|
177
|
+
{ flag: '--check', desc: 'Validate manifests without writing to disk' },
|
|
178
|
+
{ flag: '--sarif', desc: 'Output diagnostics in SARIF 2.1.0 format' },
|
|
179
|
+
{ flag: '--json', desc: 'Output result in JSON format' },
|
|
180
|
+
],
|
|
181
|
+
},
|
|
182
|
+
validate: {
|
|
183
|
+
name: 'validate',
|
|
184
|
+
description: 'Validate skill sources, frontmatter, dependency graph, and adapter sync',
|
|
185
|
+
usage: 'contextos validate',
|
|
186
|
+
requiresProject: true,
|
|
187
|
+
aliases: ['audit'],
|
|
188
|
+
options: [],
|
|
189
|
+
},
|
|
190
|
+
audit: {
|
|
191
|
+
name: 'audit',
|
|
192
|
+
target: 'validate',
|
|
193
|
+
description: 'Alias for validate (check skills and sync)',
|
|
194
|
+
usage: 'contextos audit',
|
|
195
|
+
requiresProject: true,
|
|
196
|
+
options: [],
|
|
197
|
+
},
|
|
198
|
+
export: {
|
|
199
|
+
name: 'export',
|
|
200
|
+
description: 'Compile skills for target agent (gemini, claude, cursor, copilot, aider, zed, all)',
|
|
201
|
+
usage: 'contextos export <target> [--profile <name>]',
|
|
202
|
+
requiresProject: true,
|
|
203
|
+
options: [
|
|
204
|
+
{ flag: '--profile <name>', desc: 'Apply profile for this export run' },
|
|
205
|
+
],
|
|
206
|
+
},
|
|
207
|
+
profile: {
|
|
208
|
+
name: 'profile',
|
|
209
|
+
description: 'Manage project profiles (list, show, explain, apply, remove)',
|
|
210
|
+
usage: 'contextos profile <list|show|explain|apply|remove> [name] [--scope <pkg>] [--no-export] [--json]',
|
|
211
|
+
requiresProject: true,
|
|
212
|
+
options: [
|
|
213
|
+
{ flag: '--scope <path>', desc: 'Scope profile application or removal to specific package' },
|
|
214
|
+
{ flag: '--no-export', desc: 'Skip re-exporting adapter skills after applying profile' },
|
|
215
|
+
{ flag: '--json', desc: 'Output profile information in JSON format' },
|
|
216
|
+
],
|
|
217
|
+
},
|
|
218
|
+
resolve: {
|
|
219
|
+
name: 'resolve',
|
|
220
|
+
description: 'Dynamically resolve minimal skills needed for a prompt or files',
|
|
221
|
+
usage: 'contextos resolve <prompt> [--files <a,b>] [--phase <p>] [--explain] [--budget <n>] [--json]',
|
|
222
|
+
requiresProject: true,
|
|
223
|
+
options: [
|
|
224
|
+
{ flag: '--files <list>', desc: 'Comma-separated list of touched files' },
|
|
225
|
+
{ flag: '--phase <name>', desc: 'Lifecycle phase (Define, Plan, Build, Verify, Review, Ship)' },
|
|
226
|
+
{ flag: '--explain', desc: 'Display evidence scoring and decision breakdown' },
|
|
227
|
+
{ flag: '--budget <tokens>', desc: 'Context token budget limit (default: 8000)' },
|
|
228
|
+
{ flag: '--json', desc: 'Output resolution in JSON format' },
|
|
229
|
+
],
|
|
230
|
+
},
|
|
231
|
+
explain: {
|
|
232
|
+
name: 'explain',
|
|
233
|
+
description: 'Inspect rule catalog, enforcement levels, and automated checkers',
|
|
234
|
+
usage: 'contextos explain [ruleId|skillId] [--rules] [--checkers] [--json]',
|
|
235
|
+
requiresProject: true,
|
|
236
|
+
options: [
|
|
237
|
+
{ flag: '--rules', desc: 'Display all declared rules with enforcement levels' },
|
|
238
|
+
{ flag: '--checkers', desc: 'Display all registered automated enforcement checkers' },
|
|
239
|
+
{ flag: '--json', desc: 'Output rule and enforcement data in JSON format' },
|
|
240
|
+
],
|
|
241
|
+
},
|
|
242
|
+
stats: {
|
|
243
|
+
name: 'stats',
|
|
244
|
+
description: 'Display token context savings report',
|
|
245
|
+
usage: 'contextos stats [--json]',
|
|
246
|
+
requiresProject: true,
|
|
247
|
+
options: [
|
|
248
|
+
{ flag: '--json', desc: 'Output context savings in JSON format' },
|
|
249
|
+
],
|
|
250
|
+
},
|
|
251
|
+
watch: {
|
|
252
|
+
name: 'watch',
|
|
253
|
+
description: 'Start continuous file watcher and auto-sync daemon',
|
|
254
|
+
usage: 'contextos watch',
|
|
255
|
+
requiresProject: true,
|
|
256
|
+
options: [],
|
|
257
|
+
},
|
|
258
|
+
detect: {
|
|
259
|
+
name: 'detect',
|
|
260
|
+
description: 'Auto-detect project tech stack, workspace evidence graph, and scope',
|
|
261
|
+
usage: 'contextos detect [--scope <path>] [--explain] [--json]',
|
|
262
|
+
requiresProject: false,
|
|
263
|
+
options: [
|
|
264
|
+
{ flag: '--scope <path>', desc: 'Scope detection to nearest package of specific file or directory' },
|
|
265
|
+
{ flag: '--explain', desc: 'Display evidence signals, internal dependencies, and stack breakdown' },
|
|
266
|
+
{ flag: '--json', desc: 'Output workspace graph and detection in JSON format' },
|
|
267
|
+
],
|
|
268
|
+
},
|
|
269
|
+
'install-skill': {
|
|
270
|
+
name: 'install-skill',
|
|
271
|
+
description: 'Interactive community skill installer or install by reference',
|
|
272
|
+
usage: 'contextos install-skill [<ref> | --from-repo <ref>]',
|
|
273
|
+
requiresProject: true,
|
|
274
|
+
options: [
|
|
275
|
+
{ flag: '--from-repo <ref>', desc: 'Install directly from repository ref' },
|
|
276
|
+
],
|
|
277
|
+
},
|
|
278
|
+
skill: {
|
|
279
|
+
name: 'skill',
|
|
280
|
+
description: 'Manage community plugin skills (add, remove, list, search)',
|
|
281
|
+
usage: 'contextos skill <add|remove|list|search> [args...]',
|
|
282
|
+
requiresProject: true,
|
|
283
|
+
options: [],
|
|
284
|
+
},
|
|
285
|
+
recover: {
|
|
286
|
+
name: 'recover',
|
|
287
|
+
description: 'Recover from interrupted or failed multi-file transactions',
|
|
288
|
+
usage: 'contextos recover [--status] [--rollback [txId]] [--continue [txId]]',
|
|
289
|
+
requiresProject: true,
|
|
290
|
+
options: [
|
|
291
|
+
{ flag: '--status', desc: 'Inspect pending uncommitted transaction journals' },
|
|
292
|
+
{ flag: '--rollback [txId]', desc: 'Roll back uncommitted or failed transaction' },
|
|
293
|
+
{ flag: '--continue [txId]', desc: 'Attempt to resume and complete prepared transaction' },
|
|
294
|
+
],
|
|
295
|
+
},
|
|
296
|
+
};
|
|
297
|
+
|
|
298
|
+
/**
|
|
299
|
+
* Resolves a command name or alias to canonical command definition.
|
|
300
|
+
*
|
|
301
|
+
* @param {string} name - Command name or alias
|
|
302
|
+
* @returns {Object|null} Command definition or null if unknown
|
|
303
|
+
*/
|
|
304
|
+
function getCommand(name) {
|
|
305
|
+
if (!name) return null;
|
|
306
|
+
const lower = name.toLowerCase().trim();
|
|
307
|
+
if (COMMAND_REGISTRY[lower]) {
|
|
308
|
+
const cmd = COMMAND_REGISTRY[lower];
|
|
309
|
+
if (cmd.target && COMMAND_REGISTRY[cmd.target]) {
|
|
310
|
+
return COMMAND_REGISTRY[cmd.target];
|
|
311
|
+
}
|
|
312
|
+
return cmd;
|
|
313
|
+
}
|
|
314
|
+
// Check aliases
|
|
315
|
+
for (const cmd of Object.values(COMMAND_REGISTRY)) {
|
|
316
|
+
if (cmd.aliases && cmd.aliases.includes(lower)) {
|
|
317
|
+
if (cmd.target && COMMAND_REGISTRY[cmd.target]) {
|
|
318
|
+
return COMMAND_REGISTRY[cmd.target];
|
|
319
|
+
}
|
|
320
|
+
return cmd;
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
return null;
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
/**
|
|
327
|
+
* Checks if a command name is recognized by the registry.
|
|
328
|
+
*
|
|
329
|
+
* @param {string} name - Command name to check
|
|
330
|
+
* @returns {boolean} True if known
|
|
331
|
+
*/
|
|
332
|
+
function isKnownCommand(name) {
|
|
333
|
+
return getCommand(name) !== null;
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
module.exports = {
|
|
337
|
+
COMMAND_REGISTRY,
|
|
338
|
+
getCommand,
|
|
339
|
+
isKnownCommand,
|
|
340
|
+
getStatus,
|
|
341
|
+
formatStatusText,
|
|
342
|
+
};
|