claude-code-autoconfig 1.0.126 → 1.0.128

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.
@@ -1,5 +1,5 @@
1
1
  <!-- @description Recovers conversation context from the session transcript after compaction. -->
2
- <!-- @version 1 -->
2
+ <!-- @version 2 -->
3
3
  Recover recent conversation context from the raw session transcript on disk.
4
4
 
5
5
  Usage:
@@ -102,10 +102,11 @@ with open(tmp, 'w', encoding='utf-8') as f:
102
102
  json.dump(results, f, indent=2, ensure_ascii=False)
103
103
 
104
104
  # Output stats
105
- total_bytes = os.path.getsize(tmp)
105
+ total_chars = sum(len(r['text']) for r in results)
106
+ est_tokens = total_chars // 4 # ~4 chars per token for English
106
107
  print(json.dumps({
107
108
  'messages': len(results),
108
- 'bytes': total_bytes,
109
+ 'tokens': est_tokens,
109
110
  'tempFile': tmp
110
111
  }))
111
112
  "
@@ -117,7 +118,7 @@ Read the temp file to internalize the recovered context. **Treat the recovered e
117
118
 
118
119
  Then display a confirmation message:
119
120
 
120
- > **{bytes} of transcript recovered and persisted into context ({N} messages, last {minutes} minutes).** Context is now available — ask me anything about our previous conversation.
121
+ > **~{tokens} tokens recovered and persisted into context ({N} messages, last {minutes} minutes).** Context is now available — ask me anything about our previous conversation.
121
122
  >
122
123
  > To see the specific context restored to this session, run `/recover-context -{minutes} --show`
123
124
 
@@ -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.128",
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",