claude-code-autoconfig 1.0.126 → 1.0.127

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.
@@ -0,0 +1,73 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * @name Feedback to Discoveries Migration
5
+ * @description On session start, migrates custom FEEDBACK.md content to
6
+ * CLAUDE.md Discoveries section. One-time, idempotent.
7
+ * @trigger SessionStart
8
+ */
9
+
10
+ const fs = require('fs');
11
+ const path = require('path');
12
+
13
+ const cwd = process.cwd();
14
+ const claudeMdPath = path.join(cwd, 'CLAUDE.md');
15
+ const feedbackPath = path.join(cwd, '.claude', 'feedback', 'FEEDBACK.md');
16
+
17
+ // Read hook input from stdin (required by hook protocol)
18
+ let input = '';
19
+ process.stdin.setEncoding('utf8');
20
+ process.stdin.on('data', chunk => input += chunk);
21
+ process.stdin.on('end', () => {
22
+ try {
23
+ migrate();
24
+ } catch (err) {
25
+ // Silent exit on any error
26
+ }
27
+ process.exit(0);
28
+ });
29
+
30
+ function migrate() {
31
+ if (!fs.existsSync(claudeMdPath) || !fs.existsSync(feedbackPath)) return;
32
+
33
+ const claudeMd = fs.readFileSync(claudeMdPath, 'utf8');
34
+
35
+ // Skip if Discoveries section already exists
36
+ if (claudeMd.includes('## Discoveries')) return;
37
+
38
+ const feedback = fs.readFileSync(feedbackPath, 'utf8');
39
+ const lines = feedback.split(/\r?\n/);
40
+
41
+ // Find first --- separator
42
+ let sepIdx = -1;
43
+ for (let i = 0; i < lines.length; i++) {
44
+ if (lines[i].trim() === '---') {
45
+ sepIdx = i;
46
+ break;
47
+ }
48
+ }
49
+
50
+ if (sepIdx < 0) return;
51
+
52
+ const customContent = lines.slice(sepIdx + 1).join('\n').trim();
53
+ if (!customContent) return;
54
+
55
+ // Append Discoveries section to CLAUDE.md
56
+ const discoveries = `\n\n## Discoveries\n<!-- Claude: append project-specific learnings, gotchas, and context below. This section persists across /autoconfig runs. -->\n\n${customContent}\n`;
57
+ fs.writeFileSync(claudeMdPath, claudeMd + discoveries);
58
+
59
+ // Reset FEEDBACK.md
60
+ const template = [
61
+ '<!-- @description Human-authored corrections and guidance for Claude. Reserved for team feedback only \u2014 Claude must not write here. This directory persists across /autoconfig runs. -->',
62
+ '',
63
+ '# Team Feedback',
64
+ '',
65
+ '**This file is for human-authored corrections and guidance only.**',
66
+ 'Claude reads this file but must never write to it. When Claude discovers project context, gotchas, or learnings, it should append to the `## Discoveries` section in CLAUDE.md instead.',
67
+ '',
68
+ '---',
69
+ '',
70
+ ''
71
+ ].join('\n');
72
+ fs.writeFileSync(feedbackPath, template);
73
+ }
@@ -3,6 +3,17 @@
3
3
  "CLAUDE_CODE_DISABLE_AUTO_MEMORY": "0"
4
4
  },
5
5
  "hooks": {
6
+ "SessionStart": [
7
+ {
8
+ "matcher": "",
9
+ "hooks": [
10
+ {
11
+ "type": "command",
12
+ "command": "node .claude/hooks/migrate-feedback.js"
13
+ }
14
+ ]
15
+ }
16
+ ],
6
17
  "PostToolUse": [
7
18
  {
8
19
  "matcher": "Edit|Write",
package/bin/cli.js CHANGED
@@ -442,11 +442,49 @@ if (fs.existsSync(updatesSrc)) {
442
442
  copyDirIfMissing(updatesSrc, path.join(claudeDest, 'updates'));
443
443
  }
444
444
 
445
- // Copy settings.json (only if user doesn't have one - preserves existing config)
445
+ // Copy settings.json fresh install gets full copy, upgrades get hooks merged
446
446
  const settingsSrc = path.join(packageDir, '.claude', 'settings.json');
447
447
  const settingsDest = path.join(claudeDest, 'settings.json');
448
- if (fs.existsSync(settingsSrc) && (forceMode || !fs.existsSync(settingsDest))) {
449
- fs.copyFileSync(settingsSrc, settingsDest);
448
+ if (fs.existsSync(settingsSrc)) {
449
+ if (forceMode || !fs.existsSync(settingsDest)) {
450
+ fs.copyFileSync(settingsSrc, settingsDest);
451
+ } else {
452
+ // Merge hooks from package into existing settings
453
+ try {
454
+ const pkgSettings = JSON.parse(fs.readFileSync(settingsSrc, 'utf8'));
455
+ const userSettings = JSON.parse(fs.readFileSync(settingsDest, 'utf8'));
456
+ if (pkgSettings.hooks) {
457
+ if (!userSettings.hooks) userSettings.hooks = {};
458
+ for (const [event, matchers] of Object.entries(pkgSettings.hooks)) {
459
+ if (!userSettings.hooks[event]) {
460
+ userSettings.hooks[event] = matchers;
461
+ } else {
462
+ // Add any hook commands that don't already exist
463
+ for (const matcher of matchers) {
464
+ for (const hook of matcher.hooks || []) {
465
+ const exists = userSettings.hooks[event].some(m =>
466
+ (m.hooks || []).some(h => h.command === hook.command)
467
+ );
468
+ if (!exists) {
469
+ // Find matching matcher or create new one
470
+ const existingMatcher = userSettings.hooks[event].find(m => m.matcher === matcher.matcher);
471
+ if (existingMatcher) {
472
+ existingMatcher.hooks = existingMatcher.hooks || [];
473
+ existingMatcher.hooks.push(hook);
474
+ } else {
475
+ userSettings.hooks[event].push(matcher);
476
+ }
477
+ }
478
+ }
479
+ }
480
+ }
481
+ }
482
+ fs.writeFileSync(settingsDest, JSON.stringify(userSettings, null, 2));
483
+ }
484
+ } catch (err) {
485
+ // If merge fails, don't break the install
486
+ }
487
+ }
450
488
  }
451
489
 
452
490
  console.log('\x1b[32m%s\x1b[0m', '✅ Prepared /autoconfig command');
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "claude-code-autoconfig",
3
- "version": "1.0.126",
3
+ "version": "1.0.127",
4
4
  "description": "Intelligent, self-configuring setup for Claude Code. One command analyzes your project, configures Claude, and shows you what it did.",
5
5
  "author": "ADAC 1001 <info@adac1001.com>",
6
6
  "license": "MIT",