claude-context 1.2.4

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/README.md ADDED
@@ -0,0 +1,121 @@
1
+ # claude-context
2
+
3
+ CLI tools for managing Claude Context Engineering in your project.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ # Use directly with npx (recommended)
9
+ npx claude-context validate --all
10
+
11
+ # Or install globally
12
+ npm install -g claude-context
13
+ ```
14
+
15
+ ## Prerequisites
16
+
17
+ Run `npx create-claude-context` first to initialize context engineering in your project.
18
+
19
+ ## Commands
20
+
21
+ ### Validate
22
+
23
+ Validate your context engineering setup:
24
+
25
+ ```bash
26
+ # Run all validations
27
+ npx claude-context validate --all
28
+
29
+ # Specific validations
30
+ npx claude-context validate --schema # JSON schema validation
31
+ npx claude-context validate --links # Internal link validation
32
+ npx claude-context validate --placeholders # Check for unreplaced {{PLACEHOLDERS}}
33
+ npx claude-context validate --structure # Directory structure validation
34
+ npx claude-context validate --lines # Line number accuracy check
35
+
36
+ # With options
37
+ npx claude-context validate --all --verbose
38
+ npx claude-context validate --lines --threshold 70
39
+ ```
40
+
41
+ ### Sync
42
+
43
+ Synchronize documentation with code changes:
44
+
45
+ ```bash
46
+ # Check for drift
47
+ npx claude-context sync --check
48
+
49
+ # Auto-fix line number drift
50
+ npx claude-context sync --fix
51
+
52
+ # Rebuild CODE_TO_WORKFLOW_MAP
53
+ npx claude-context sync --rebuild-map
54
+
55
+ # Strict mode (fail on any drift)
56
+ npx claude-context sync --check --strict
57
+ ```
58
+
59
+ ### Hooks
60
+
61
+ Manage git hooks for automatic validation:
62
+
63
+ ```bash
64
+ # Install pre-commit and post-commit hooks
65
+ npx claude-context hooks install
66
+
67
+ # Uninstall hooks
68
+ npx claude-context hooks uninstall
69
+
70
+ # Install only pre-commit
71
+ npx claude-context hooks install --pre-commit
72
+ ```
73
+
74
+ ### Diagnose
75
+
76
+ Run diagnostics on your setup:
77
+
78
+ ```bash
79
+ # Run diagnostics
80
+ npx claude-context diagnose
81
+
82
+ # Auto-fix detected issues
83
+ npx claude-context diagnose --fix
84
+
85
+ # Verbose output
86
+ npx claude-context diagnose --verbose
87
+ ```
88
+
89
+ ### Generate
90
+
91
+ Generate or regenerate documentation:
92
+
93
+ ```bash
94
+ # Regenerate CODE_TO_WORKFLOW_MAP.md
95
+ npx claude-context generate --code-map
96
+
97
+ # Rebuild all indexes
98
+ npx claude-context generate --indexes
99
+
100
+ # Regenerate semantic anchors
101
+ npx claude-context generate --anchors
102
+ ```
103
+
104
+ ## CI/CD Integration
105
+
106
+ Add to your CI pipeline:
107
+
108
+ ```yaml
109
+ # GitHub Actions example
110
+ - name: Validate context engineering
111
+ run: npx claude-context validate --all --strict
112
+ ```
113
+
114
+ ## Related
115
+
116
+ - [create-claude-context](https://www.npmjs.com/package/create-claude-context) - Initial setup
117
+ - [claude-context-plugin](https://www.npmjs.com/package/claude-context-plugin) - Claude Code plugin
118
+
119
+ ## License
120
+
121
+ MIT
@@ -0,0 +1,144 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * Claude Context CLI
5
+ *
6
+ * Ongoing tools for managing Claude Context Engineering in your project.
7
+ * Use after initial setup with `npx create-claude-context`.
8
+ */
9
+
10
+ const { program } = require('commander');
11
+ const chalk = require('chalk');
12
+ const path = require('path');
13
+ const fs = require('fs');
14
+
15
+ const { validate } = require('../lib/validate');
16
+ const { sync } = require('../lib/sync');
17
+ const { hooks } = require('../lib/hooks');
18
+ const { diagnose } = require('../lib/diagnose');
19
+ const { generate } = require('../lib/generate');
20
+
21
+ const packageJson = require('../package.json');
22
+
23
+ // Check if we're in a project with .claude directory
24
+ function checkClaudeDir() {
25
+ const claudeDir = path.join(process.cwd(), '.claude');
26
+ if (!fs.existsSync(claudeDir)) {
27
+ console.error(chalk.red('\nError: No .claude directory found in current directory.'));
28
+ console.error(chalk.yellow('Run `npx create-claude-context` first to initialize.\n'));
29
+ process.exit(1);
30
+ }
31
+ return claudeDir;
32
+ }
33
+
34
+ program
35
+ .name('claude-context')
36
+ .description('CLI tools for Claude Context Engineering')
37
+ .version(packageJson.version);
38
+
39
+ // Validate command
40
+ program
41
+ .command('validate')
42
+ .description('Validate context engineering setup')
43
+ .option('-a, --all', 'Run all validations')
44
+ .option('-s, --schema', 'Validate JSON schemas')
45
+ .option('-l, --links', 'Validate internal links')
46
+ .option('-p, --placeholders', 'Check for unreplaced placeholders')
47
+ .option('-S, --structure', 'Validate directory structure')
48
+ .option('-L, --lines', 'Check line number accuracy')
49
+ .option('-t, --threshold <number>', 'Line accuracy threshold (default: 60)', '60')
50
+ .option('-v, --verbose', 'Show detailed output')
51
+ .action(async (options) => {
52
+ checkClaudeDir();
53
+ try {
54
+ const result = await validate(process.cwd(), options);
55
+ process.exit(result.success ? 0 : 1);
56
+ } catch (error) {
57
+ console.error(chalk.red(`Error: ${error.message}`));
58
+ process.exit(1);
59
+ }
60
+ });
61
+
62
+ // Sync command
63
+ program
64
+ .command('sync')
65
+ .description('Synchronize documentation with code')
66
+ .option('-c, --check', 'Check for drift without fixing')
67
+ .option('-f, --fix', 'Auto-fix shifted line numbers')
68
+ .option('--rebuild-map', 'Regenerate CODE_TO_WORKFLOW_MAP')
69
+ .option('--strict', 'Fail on any drift detected')
70
+ .action(async (options) => {
71
+ checkClaudeDir();
72
+ try {
73
+ const result = await sync(process.cwd(), options);
74
+ process.exit(result.success ? 0 : 1);
75
+ } catch (error) {
76
+ console.error(chalk.red(`Error: ${error.message}`));
77
+ process.exit(1);
78
+ }
79
+ });
80
+
81
+ // Hooks command
82
+ program
83
+ .command('hooks')
84
+ .description('Manage git hooks for context engineering')
85
+ .argument('<action>', 'install or uninstall')
86
+ .option('--pre-commit', 'Only pre-commit hook')
87
+ .option('--post-commit', 'Only post-commit hook')
88
+ .action(async (action, options) => {
89
+ checkClaudeDir();
90
+ if (!['install', 'uninstall'].includes(action)) {
91
+ console.error(chalk.red(`Unknown action: ${action}. Use 'install' or 'uninstall'.`));
92
+ process.exit(1);
93
+ }
94
+ try {
95
+ const result = await hooks(process.cwd(), action, options);
96
+ process.exit(result.success ? 0 : 1);
97
+ } catch (error) {
98
+ console.error(chalk.red(`Error: ${error.message}`));
99
+ process.exit(1);
100
+ }
101
+ });
102
+
103
+ // Diagnose command
104
+ program
105
+ .command('diagnose')
106
+ .description('Run diagnostics on context engineering setup')
107
+ .option('-f, --fix', 'Auto-fix detected issues')
108
+ .option('-v, --verbose', 'Show detailed output')
109
+ .action(async (options) => {
110
+ checkClaudeDir();
111
+ try {
112
+ const result = await diagnose(process.cwd(), options);
113
+ process.exit(result.success ? 0 : 1);
114
+ } catch (error) {
115
+ console.error(chalk.red(`Error: ${error.message}`));
116
+ process.exit(1);
117
+ }
118
+ });
119
+
120
+ // Generate command
121
+ program
122
+ .command('generate')
123
+ .description('Generate or regenerate documentation')
124
+ .option('--code-map', 'Regenerate CODE_TO_WORKFLOW_MAP.md')
125
+ .option('--indexes', 'Rebuild all indexes')
126
+ .option('--anchors', 'Regenerate semantic anchors')
127
+ .action(async (options) => {
128
+ checkClaudeDir();
129
+ try {
130
+ const result = await generate(process.cwd(), options);
131
+ process.exit(result.success ? 0 : 1);
132
+ } catch (error) {
133
+ console.error(chalk.red(`Error: ${error.message}`));
134
+ process.exit(1);
135
+ }
136
+ });
137
+
138
+ // Parse and run
139
+ program.parse();
140
+
141
+ // Show help if no command provided
142
+ if (!process.argv.slice(2).length) {
143
+ program.outputHelp();
144
+ }
@@ -0,0 +1,337 @@
1
+ /**
2
+ * Diagnostics module for Claude Context Engineering
3
+ */
4
+
5
+ const fs = require('fs');
6
+ const path = require('path');
7
+ const { glob } = require('glob');
8
+ const chalk = require('chalk');
9
+
10
+ /**
11
+ * Run diagnostics on context engineering setup
12
+ */
13
+ async function diagnose(projectRoot, options = {}) {
14
+ const claudeDir = path.join(projectRoot, '.claude');
15
+ const results = {
16
+ success: true,
17
+ checks: [],
18
+ issues: [],
19
+ fixed: 0
20
+ };
21
+
22
+ console.log(chalk.blue('\n🩺 Running diagnostics...\n'));
23
+
24
+ // Check 1: Directory structure
25
+ const structureCheck = checkStructure(claudeDir);
26
+ results.checks.push(structureCheck);
27
+ results.issues.push(...structureCheck.issues);
28
+
29
+ // Check 2: CLAUDE.md exists and is valid
30
+ const claudeMdCheck = checkClaudeMd(projectRoot);
31
+ results.checks.push(claudeMdCheck);
32
+ results.issues.push(...claudeMdCheck.issues);
33
+
34
+ // Check 3: Settings.json is valid
35
+ const settingsCheck = checkSettings(claudeDir);
36
+ results.checks.push(settingsCheck);
37
+ results.issues.push(...settingsCheck.issues);
38
+
39
+ // Check 4: Agent files are valid
40
+ const agentCheck = await checkAgents(claudeDir);
41
+ results.checks.push(agentCheck);
42
+ results.issues.push(...agentCheck.issues);
43
+
44
+ // Check 5: Command files are valid
45
+ const commandCheck = await checkCommands(claudeDir);
46
+ results.checks.push(commandCheck);
47
+ results.issues.push(...commandCheck.issues);
48
+
49
+ // Check 6: Workflow files exist
50
+ const workflowCheck = await checkWorkflows(claudeDir);
51
+ results.checks.push(workflowCheck);
52
+ results.issues.push(...workflowCheck.issues);
53
+
54
+ // Fix issues if requested
55
+ if (options.fix && results.issues.length > 0) {
56
+ results.fixed = await fixIssues(claudeDir, projectRoot, results.issues);
57
+ }
58
+
59
+ // Determine success
60
+ const criticalIssues = results.issues.filter(i => i.severity === 'error');
61
+ results.success = criticalIssues.length === 0;
62
+
63
+ // Print summary
64
+ printDiagnosticsSummary(results, options);
65
+
66
+ return results;
67
+ }
68
+
69
+ /**
70
+ * Check directory structure
71
+ */
72
+ function checkStructure(claudeDir) {
73
+ const check = { name: 'Directory Structure', passed: true, issues: [] };
74
+
75
+ const requiredDirs = ['agents', 'commands', 'context', 'indexes'];
76
+
77
+ for (const dir of requiredDirs) {
78
+ const dirPath = path.join(claudeDir, dir);
79
+ if (!fs.existsSync(dirPath)) {
80
+ check.passed = false;
81
+ check.issues.push({
82
+ type: 'missing_directory',
83
+ path: dir,
84
+ message: `Missing required directory: ${dir}`,
85
+ severity: 'error',
86
+ fix: () => fs.mkdirSync(dirPath, { recursive: true })
87
+ });
88
+ }
89
+ }
90
+
91
+ console.log(check.passed
92
+ ? chalk.green('✓ Directory structure: OK')
93
+ : chalk.red(`✗ Directory structure: ${check.issues.length} issues`));
94
+
95
+ return check;
96
+ }
97
+
98
+ /**
99
+ * Check CLAUDE.md
100
+ */
101
+ function checkClaudeMd(projectRoot) {
102
+ const check = { name: 'CLAUDE.md', passed: true, issues: [] };
103
+ const claudeMdPath = path.join(projectRoot, 'CLAUDE.md');
104
+
105
+ if (!fs.existsSync(claudeMdPath)) {
106
+ check.passed = false;
107
+ check.issues.push({
108
+ type: 'missing_file',
109
+ path: 'CLAUDE.md',
110
+ message: 'Missing CLAUDE.md at project root',
111
+ severity: 'error'
112
+ });
113
+ } else {
114
+ const content = fs.readFileSync(claudeMdPath, 'utf8');
115
+
116
+ // Check for unreplaced placeholders
117
+ const placeholders = content.match(/\{\{[A-Z_]+\}\}/g);
118
+ if (placeholders && placeholders.length > 10) {
119
+ check.passed = false;
120
+ check.issues.push({
121
+ type: 'too_many_placeholders',
122
+ path: 'CLAUDE.md',
123
+ message: `CLAUDE.md has ${placeholders.length} unreplaced placeholders`,
124
+ severity: 'warning'
125
+ });
126
+ }
127
+
128
+ // Check minimum content
129
+ if (content.length < 500) {
130
+ check.issues.push({
131
+ type: 'minimal_content',
132
+ path: 'CLAUDE.md',
133
+ message: 'CLAUDE.md seems too short',
134
+ severity: 'warning'
135
+ });
136
+ }
137
+ }
138
+
139
+ console.log(check.passed
140
+ ? chalk.green('✓ CLAUDE.md: OK')
141
+ : chalk.yellow(`⚠ CLAUDE.md: ${check.issues.length} issues`));
142
+
143
+ return check;
144
+ }
145
+
146
+ /**
147
+ * Check settings.json
148
+ */
149
+ function checkSettings(claudeDir) {
150
+ const check = { name: 'Settings', passed: true, issues: [] };
151
+ const settingsPath = path.join(claudeDir, 'settings.json');
152
+
153
+ if (!fs.existsSync(settingsPath)) {
154
+ check.issues.push({
155
+ type: 'missing_file',
156
+ path: 'settings.json',
157
+ message: 'Missing settings.json',
158
+ severity: 'warning'
159
+ });
160
+ } else {
161
+ try {
162
+ const content = fs.readFileSync(settingsPath, 'utf8');
163
+ JSON.parse(content);
164
+ } catch (e) {
165
+ check.passed = false;
166
+ check.issues.push({
167
+ type: 'invalid_json',
168
+ path: 'settings.json',
169
+ message: `Invalid JSON: ${e.message}`,
170
+ severity: 'error'
171
+ });
172
+ }
173
+ }
174
+
175
+ console.log(check.passed
176
+ ? chalk.green('✓ Settings: OK')
177
+ : chalk.red(`✗ Settings: ${check.issues.length} issues`));
178
+
179
+ return check;
180
+ }
181
+
182
+ /**
183
+ * Check agent files
184
+ */
185
+ async function checkAgents(claudeDir) {
186
+ const check = { name: 'Agents', passed: true, issues: [] };
187
+ const agentDir = path.join(claudeDir, 'agents');
188
+
189
+ if (!fs.existsSync(agentDir)) {
190
+ check.issues.push({
191
+ type: 'missing_directory',
192
+ path: 'agents',
193
+ message: 'No agents directory',
194
+ severity: 'warning'
195
+ });
196
+ return check;
197
+ }
198
+
199
+ const agentFiles = await glob('*.md', { cwd: agentDir });
200
+
201
+ if (agentFiles.length === 0) {
202
+ check.issues.push({
203
+ type: 'no_agents',
204
+ path: 'agents',
205
+ message: 'No agent files found',
206
+ severity: 'warning'
207
+ });
208
+ }
209
+
210
+ // Check each agent has required sections
211
+ for (const file of agentFiles) {
212
+ const content = fs.readFileSync(path.join(agentDir, file), 'utf8');
213
+
214
+ if (!content.includes('## Role') && !content.includes('## Purpose')) {
215
+ check.issues.push({
216
+ type: 'missing_section',
217
+ path: `agents/${file}`,
218
+ message: `Agent ${file} missing Role/Purpose section`,
219
+ severity: 'warning'
220
+ });
221
+ }
222
+ }
223
+
224
+ console.log(check.issues.length === 0
225
+ ? chalk.green(`✓ Agents: ${agentFiles.length} found`)
226
+ : chalk.yellow(`⚠ Agents: ${check.issues.length} issues`));
227
+
228
+ return check;
229
+ }
230
+
231
+ /**
232
+ * Check command files
233
+ */
234
+ async function checkCommands(claudeDir) {
235
+ const check = { name: 'Commands', passed: true, issues: [] };
236
+ const commandDir = path.join(claudeDir, 'commands');
237
+
238
+ if (!fs.existsSync(commandDir)) {
239
+ check.issues.push({
240
+ type: 'missing_directory',
241
+ path: 'commands',
242
+ message: 'No commands directory',
243
+ severity: 'warning'
244
+ });
245
+ return check;
246
+ }
247
+
248
+ const commandFiles = await glob('*.md', { cwd: commandDir });
249
+
250
+ if (commandFiles.length === 0) {
251
+ check.issues.push({
252
+ type: 'no_commands',
253
+ path: 'commands',
254
+ message: 'No command files found',
255
+ severity: 'warning'
256
+ });
257
+ }
258
+
259
+ console.log(check.issues.length === 0
260
+ ? chalk.green(`✓ Commands: ${commandFiles.length} found`)
261
+ : chalk.yellow(`⚠ Commands: ${check.issues.length} issues`));
262
+
263
+ return check;
264
+ }
265
+
266
+ /**
267
+ * Check workflow files
268
+ */
269
+ async function checkWorkflows(claudeDir) {
270
+ const check = { name: 'Workflows', passed: true, issues: [] };
271
+ const workflowDir = path.join(claudeDir, 'context', 'workflows');
272
+
273
+ if (!fs.existsSync(workflowDir)) {
274
+ check.issues.push({
275
+ type: 'missing_directory',
276
+ path: 'context/workflows',
277
+ message: 'No workflows directory',
278
+ severity: 'info'
279
+ });
280
+ console.log(chalk.gray('- Workflows: Not configured (run @context-engineer to create)'));
281
+ return check;
282
+ }
283
+
284
+ const workflowFiles = await glob('*.md', { cwd: workflowDir });
285
+
286
+ console.log(workflowFiles.length > 0
287
+ ? chalk.green(`✓ Workflows: ${workflowFiles.length} found`)
288
+ : chalk.gray('- Workflows: None yet'));
289
+
290
+ return check;
291
+ }
292
+
293
+ /**
294
+ * Fix detected issues
295
+ */
296
+ async function fixIssues(claudeDir, projectRoot, issues) {
297
+ let fixed = 0;
298
+
299
+ for (const issue of issues) {
300
+ if (issue.fix && typeof issue.fix === 'function') {
301
+ try {
302
+ issue.fix();
303
+ fixed++;
304
+ console.log(chalk.green(` ✓ Fixed: ${issue.message}`));
305
+ } catch (e) {
306
+ console.log(chalk.red(` ✗ Failed to fix: ${issue.message}`));
307
+ }
308
+ }
309
+ }
310
+
311
+ return fixed;
312
+ }
313
+
314
+ /**
315
+ * Print diagnostics summary
316
+ */
317
+ function printDiagnosticsSummary(results, options) {
318
+ const errors = results.issues.filter(i => i.severity === 'error').length;
319
+ const warnings = results.issues.filter(i => i.severity === 'warning').length;
320
+
321
+ console.log('\n' + chalk.bold('Diagnostics Summary:'));
322
+ console.log(` Checks run: ${results.checks.length}`);
323
+ console.log(` Errors: ${errors}`);
324
+ console.log(` Warnings: ${warnings}`);
325
+
326
+ if (options.fix) {
327
+ console.log(` Fixed: ${results.fixed}`);
328
+ }
329
+
330
+ if (results.success) {
331
+ console.log(chalk.green('\n✓ System healthy!\n'));
332
+ } else {
333
+ console.log(chalk.red('\n✗ Issues detected. Run with --fix to auto-repair.\n'));
334
+ }
335
+ }
336
+
337
+ module.exports = { diagnose };