claude-code-autoconfig 1.0.114 → 1.0.115

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,22 +1,23 @@
1
- <!-- @description Runs tests, then stages all changes, generates a conventional commit message, commits, and pushes. -->
2
-
3
- # Commit and Push
4
-
5
- Run tests, stage all changes, create a commit with a good message, and push to the current branch.
6
-
7
- ## Steps
8
-
9
- 1. Run the project's test suite (e.g., `npm test`)
10
- 2. **If tests fail, stop here.** Do not commit or push failing code.
11
- 3. Stage all changes (`git add -A`)
12
- 4. Generate a conventional commit message based on the diff
13
- 5. Commit the changes
14
- 6. Push to the current branch
15
-
16
- ## Commit Message Format
17
-
18
- Use conventional commits: `type(scope): description`
19
-
20
- Types: feat, fix, docs, style, refactor, test, chore
21
-
1
+ <!-- @description Runs tests, then stages all changes, generates a conventional commit message, commits, and pushes. -->
2
+ <!-- @version 1 -->
3
+
4
+ # Commit and Push
5
+
6
+ Run tests, stage all changes, create a commit with a good message, and push to the current branch.
7
+
8
+ ## Steps
9
+
10
+ 1. Run the project's test suite (e.g., `npm test`)
11
+ 2. **If tests fail, stop here.** Do not commit or push failing code.
12
+ 3. Stage all changes (`git add -A`)
13
+ 4. Generate a conventional commit message based on the diff
14
+ 5. Commit the changes
15
+ 6. Push to the current branch
16
+
17
+ ## Commit Message Format
18
+
19
+ Use conventional commits: `type(scope): description`
20
+
21
+ Types: feat, fix, docs, style, refactor, test, chore
22
+
22
23
  Keep the subject line under 50 chars. Add body if the change needs explanation.
@@ -1,4 +1,5 @@
1
1
  <!-- @description (Experimental) Enable Claude to log tech debt it encounters into .claude/retro. -->
2
+ <!-- @version 1 -->
2
3
 
3
4
  # Enable Retro
4
5
 
@@ -1,88 +1,89 @@
1
- <!-- @screenshotDir -->
2
- Get the latest screenshot(s) and display them.
3
-
4
- Usage:
5
- - `/gls` - Get and display the most recent screenshot
6
- - `/gls-2` - Get and display the 2 most recent screenshots
7
- - `/gls-3` - Get and display the 3 most recent screenshots
8
- - `/gls-N` - Get and display the N most recent screenshots
9
- - `/gls /path/to/dir` - Use a specific directory and save it
10
-
11
- ## Step 1: Check for saved path
12
-
13
- Check the `@screenshotDir` comment on line 1 of THIS file. If it has a path (not empty), use that path and skip to Step 3.
14
-
15
- If it's empty (i.e., `<!-- @screenshotDir -->`), continue to Step 2.
16
-
17
- ## Step 2: Detect screenshot directory
18
-
19
- If the user provides a path as an argument (e.g., `/gls /path/to/dir`), use that path and skip to Step 2b.
20
-
21
- Otherwise, detect the OS and find the screenshot directory. Run this **single Bash command** which finds all candidate directories and reports the newest screenshot in each:
22
-
23
- ```bash
24
- OS=$(uname -s); echo "OS=$OS"; for d in \
25
- "$HOME/OneDrive/Pictures/Screenshots"* \
26
- "$HOME/Pictures/Screenshots" \
27
- "$HOME/Desktop" \
28
- "$HOME/Pictures" \
29
- "$HOME/Videos/Captures"; do \
30
- [ -d "$d" ] || continue; \
31
- newest=$(ls -t "$d"/*.png "$d"/*.jpg "$d"/*.jpeg "$d"/*.bmp "$d"/*.webp "$d"/*.gif 2>/dev/null | head -1); \
32
- if [ -n "$newest" ]; then \
33
- echo "HAS_IMAGES: $d | newest: $newest"; \
34
- else \
35
- echo "EMPTY: $d"; \
36
- fi; \
37
- done; \
38
- [ "$OS" = "Darwin" ] && defaults read com.apple.screencapture location 2>/dev/null && echo "(macos-custom)"; \
39
- [ "$OS" = "Linux" ] && [ -n "$XDG_PICTURES_DIR" ] && [ -d "$XDG_PICTURES_DIR/Screenshots" ] && echo "EXISTS: $XDG_PICTURES_DIR/Screenshots"
40
- ```
41
-
42
- Pick the screenshot directory using these rules:
43
-
44
- 1. **macOS only**: If `(macos-custom)` appears in the output, prefer that path.
45
- 2. Among all `HAS_IMAGES` directories, pick the one whose newest screenshot has the **most recent modification time** (the file paths are shown after `newest:`— compare them).
46
- 3. If no directories have images, fall back to the first `EMPTY` directory (screenshots will land there eventually).
47
- 4. If there are no candidate directories at all, detection has failed.
48
-
49
- ### If detection fails
50
-
51
- Ask the user:
52
-
53
- > Unable to detect your screenshot directory. Please enter your screenshot path to continue:
54
-
55
- Wait for the user to respond with a path, then use that path.
56
-
57
- ### Step 2b: Save the path
58
-
59
- Use the Edit tool to update line 1 of THIS file, replacing the empty `@screenshotDir` tag with the detected (or user-provided) path. For example:
60
-
61
- `<!-- @screenshotDir /c/Users/jane/Pictures/Screenshots -->`
62
-
63
- This ensures detection only happens once per project.
64
-
65
- ## Step 3: List screenshots
66
-
67
- Run this command (substitute the resolved directory for `$DIR`):
68
-
69
- ```bash
70
- ls -t "$DIR"/*.png "$DIR"/*.jpg "$DIR"/*.jpeg "$DIR"/*.bmp "$DIR"/*.webp "$DIR"/*.gif 2>/dev/null | head -20
71
- ```
72
-
73
- If no images are found, tell the user the directory exists but contains no screenshots. Suggest taking a screenshot first or specifying a different directory with `/gls /path/to/dir`.
74
-
75
- ## Step 4: Select screenshots
76
-
77
- - `/gls` → 1 most recent
78
- - `/gls-N` (e.g., `/gls-2`) N most recent
79
-
80
- ## Step 5: Display
81
-
82
- Use the **Read tool** to display each screenshot file. Display in order from newest to oldest.
83
-
84
- IMPORTANT: Always use the Read tool — never use Bash cat/echo to display images.
85
-
86
- ## Step 6: Wait
87
-
88
- Wait for the user to tell you what to do with the screenshot(s). Do not make assumptions about what they want.
1
+ <!-- @screenshotDir -->
2
+ <!-- @version 1 -->
3
+ Get the latest screenshot(s) and display them.
4
+
5
+ Usage:
6
+ - `/gls` - Get and display the most recent screenshot
7
+ - `/gls-2` - Get and display the 2 most recent screenshots
8
+ - `/gls-3` - Get and display the 3 most recent screenshots
9
+ - `/gls-N` - Get and display the N most recent screenshots
10
+ - `/gls /path/to/dir` - Use a specific directory and save it
11
+
12
+ ## Step 1: Check for saved path
13
+
14
+ Check the `@screenshotDir` comment on line 1 of THIS file. If it has a path (not empty), use that path and skip to Step 3.
15
+
16
+ If it's empty (i.e., `<!-- @screenshotDir -->`), continue to Step 2.
17
+
18
+ ## Step 2: Detect screenshot directory
19
+
20
+ If the user provides a path as an argument (e.g., `/gls /path/to/dir`), use that path and skip to Step 2b.
21
+
22
+ Otherwise, detect the OS and find the screenshot directory. Run this **single Bash command** which finds all candidate directories and reports the newest screenshot in each:
23
+
24
+ ```bash
25
+ OS=$(uname -s); echo "OS=$OS"; for d in \
26
+ "$HOME/OneDrive/Pictures/Screenshots"* \
27
+ "$HOME/Pictures/Screenshots" \
28
+ "$HOME/Desktop" \
29
+ "$HOME/Pictures" \
30
+ "$HOME/Videos/Captures"; do \
31
+ [ -d "$d" ] || continue; \
32
+ newest=$(ls -t "$d"/*.png "$d"/*.jpg "$d"/*.jpeg "$d"/*.bmp "$d"/*.webp "$d"/*.gif 2>/dev/null | head -1); \
33
+ if [ -n "$newest" ]; then \
34
+ echo "HAS_IMAGES: $d | newest: $newest"; \
35
+ else \
36
+ echo "EMPTY: $d"; \
37
+ fi; \
38
+ done; \
39
+ [ "$OS" = "Darwin" ] && defaults read com.apple.screencapture location 2>/dev/null && echo "(macos-custom)"; \
40
+ [ "$OS" = "Linux" ] && [ -n "$XDG_PICTURES_DIR" ] && [ -d "$XDG_PICTURES_DIR/Screenshots" ] && echo "EXISTS: $XDG_PICTURES_DIR/Screenshots"
41
+ ```
42
+
43
+ Pick the screenshot directory using these rules:
44
+
45
+ 1. **macOS only**: If `(macos-custom)` appears in the output, prefer that path.
46
+ 2. Among all `HAS_IMAGES` directories, pick the one whose newest screenshot has the **most recent modification time** (the file paths are shown after `newest:`— compare them).
47
+ 3. If no directories have images, fall back to the first `EMPTY` directory (screenshots will land there eventually).
48
+ 4. If there are no candidate directories at all, detection has failed.
49
+
50
+ ### If detection fails
51
+
52
+ Ask the user:
53
+
54
+ > Unable to detect your screenshot directory. Please enter your screenshot path to continue:
55
+
56
+ Wait for the user to respond with a path, then use that path.
57
+
58
+ ### Step 2b: Save the path
59
+
60
+ Use the Edit tool to update line 1 of THIS file, replacing the empty `@screenshotDir` tag with the detected (or user-provided) path. For example:
61
+
62
+ `<!-- @screenshotDir /c/Users/jane/Pictures/Screenshots -->`
63
+
64
+ This ensures detection only happens once per project.
65
+
66
+ ## Step 3: List screenshots
67
+
68
+ Run this command (substitute the resolved directory for `$DIR`):
69
+
70
+ ```bash
71
+ ls -t "$DIR"/*.png "$DIR"/*.jpg "$DIR"/*.jpeg "$DIR"/*.bmp "$DIR"/*.webp "$DIR"/*.gif 2>/dev/null | head -20
72
+ ```
73
+
74
+ If no images are found, tell the user the directory exists but contains no screenshots. Suggest taking a screenshot first or specifying a different directory with `/gls /path/to/dir`.
75
+
76
+ ## Step 4: Select screenshots
77
+
78
+ - `/gls` → 1 most recent
79
+ - `/gls-N` (e.g., `/gls-2`) → N most recent
80
+
81
+ ## Step 5: Display
82
+
83
+ Use the **Read tool** to display each screenshot file. Display in order from newest to oldest.
84
+
85
+ IMPORTANT: Always use the Read tool — never use Bash cat/echo to display images.
86
+
87
+ ## Step 6: Wait
88
+
89
+ Wait for the user to tell you what to do with the screenshot(s). Do not make assumptions about what they want.
@@ -1,4 +1,5 @@
1
1
  <!-- @description Recovers conversation context from the session transcript after compaction. -->
2
+ <!-- @version 1 -->
2
3
  Recover recent conversation context from the raw session transcript on disk.
3
4
 
4
5
  Usage:
@@ -1,4 +1,5 @@
1
1
  <!-- @description Opens the interactive docs in your browser. -->
2
+ <!-- @version 1 -->
2
3
 
3
4
  # Show Docs
4
5
 
@@ -1,4 +1,5 @@
1
1
  <!-- @description Re-analyzes your project and updates CLAUDE.md to reflect current state. -->
2
+ <!-- @version 1 -->
2
3
 
3
4
  # Sync CLAUDE.md
4
5
 
@@ -1,11 +1,12 @@
1
- <!-- @description Runs your test suite. Auto-detects Jest, Vitest, Pytest, Go, RSpec, or falls back to npm test. -->
2
-
3
- # Run Tests
4
-
5
- Run tests for this project.
6
-
7
- **Scope:** $ARGUMENTS
8
-
9
- If no scope provided, run the full test suite. Otherwise run tests matching the scope (file, directory, or pattern).
10
-
1
+ <!-- @description Runs your test suite. Auto-detects Jest, Vitest, Pytest, Go, RSpec, or falls back to npm test. -->
2
+ <!-- @version 1 -->
3
+
4
+ # Run Tests
5
+
6
+ Run tests for this project.
7
+
8
+ **Scope:** $ARGUMENTS
9
+
10
+ If no scope provided, run the full test suite. Otherwise run tests matching the scope (file, directory, or pattern).
11
+
11
12
  Detect the test command from project config (package.json scripts, pytest, go test, etc.) and execute it.
@@ -32,6 +32,8 @@ The `.claude/updates/` directory is for updates that **require Claude to execute
32
32
 
33
33
  **Rule:** If the update is just a file → put it in the right directory and let the CLI copy it. If the update needs instructions → create a `NNN-*.md` update file.
34
34
 
35
+ **Command versioning:** Every command file must have a `<!-- @version N -->` comment (typically line 2, after `@description`). Bump the version number whenever you modify a command. The CLI parses this to show version transitions on upgrade (e.g., `↑ /recover-context (v1 → v2)`).
36
+
35
37
  ---
36
38
 
37
39
  ## Design Principles
package/bin/cli.js CHANGED
@@ -353,6 +353,12 @@ function copyDirIfMissing(src, dest) {
353
353
  }
354
354
  }
355
355
 
356
+ // Parse @version from command file content
357
+ function parseCommandVersion(content) {
358
+ const match = content.match(/<!-- @version (\d+) -->/);
359
+ return match ? parseInt(match[1], 10) : 0;
360
+ }
361
+
356
362
  // Track what commands are new/updated for summary
357
363
  const commandsDest = path.join(claudeDest, 'commands');
358
364
  const existingCommandContents = new Map();
@@ -379,17 +385,17 @@ if (fs.existsSync(commandsSrc)) {
379
385
  process.exit(1);
380
386
  }
381
387
 
382
- // Detect new and updated commands
388
+ // Detect new and updated commands (with version tracking)
383
389
  const newCommands = [];
384
- const updatedCommands = [];
390
+ const updatedCommands = []; // { file, oldVersion, newVersion }
385
391
  for (const f of fs.readdirSync(commandsDest).filter(f => f.endsWith('.md') && !DEV_ONLY_FILES.includes(f))) {
392
+ const newContent = fs.readFileSync(path.join(commandsDest, f), 'utf8');
386
393
  if (!existingCommandContents.has(f)) {
387
- newCommands.push(f);
388
- } else {
389
- const newContent = fs.readFileSync(path.join(commandsDest, f), 'utf8');
390
- if (newContent !== existingCommandContents.get(f)) {
391
- updatedCommands.push(f);
392
- }
394
+ newCommands.push({ file: f, version: parseCommandVersion(newContent) });
395
+ } else if (newContent !== existingCommandContents.get(f)) {
396
+ const oldVersion = parseCommandVersion(existingCommandContents.get(f));
397
+ const newVersion = parseCommandVersion(newContent);
398
+ updatedCommands.push({ file: f, oldVersion, newVersion });
393
399
  }
394
400
  }
395
401
 
@@ -448,13 +454,15 @@ console.log('\x1b[32m%s\x1b[0m', '✅ Prepared /autoconfig command');
448
454
  // Show what was installed/updated
449
455
  if (isUpgrade && (newCommands.length > 0 || updatedCommands.length > 0)) {
450
456
  console.log();
451
- for (const cmd of newCommands) {
452
- const name = cmd.replace('.md', '');
453
- console.log('\x1b[36m%s\x1b[0m', ` + /${name} (new)`);
457
+ for (const { file, version } of newCommands) {
458
+ const name = file.replace('.md', '');
459
+ const ver = version > 0 ? ` v${version}` : '';
460
+ console.log('\x1b[36m%s\x1b[0m', ` + /${name}${ver} (new)`);
454
461
  }
455
- for (const cmd of updatedCommands) {
456
- const name = cmd.replace('.md', '');
457
- console.log('\x1b[33m%s\x1b[0m', ` /${name} (updated)`);
462
+ for (const { file, oldVersion, newVersion } of updatedCommands) {
463
+ const name = file.replace('.md', '');
464
+ const ver = (oldVersion > 0 && newVersion > 0) ? ` (v${oldVersion} → v${newVersion})` : ' (updated)';
465
+ console.log('\x1b[33m%s\x1b[0m', ` ↑ /${name}${ver}`);
458
466
  }
459
467
  }
460
468
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "claude-code-autoconfig",
3
- "version": "1.0.114",
3
+ "version": "1.0.115",
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",