@wipcomputer/wip-ai-devops-toolbox 1.9.45 → 1.9.46

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/CHANGELOG.md CHANGED
@@ -31,6 +31,47 @@
31
31
 
32
32
 
33
33
 
34
+
35
+ ## 1.9.46 (2026-03-18)
36
+
37
+ # Release Notes: wip-ai-devops-toolbox v1.9.46
38
+
39
+ **Centralized worktree management: guard rule, wip-release prune, Dev Guide convention.**
40
+
41
+ ## What changed
42
+
43
+ ### Guard: worktree path warning (#212)
44
+ Branch guard now warns when `git worktree add` creates a worktree outside `_worktrees/`. Shows the convention and suggests `ldm worktree add`. Warning only, not a hard block.
45
+
46
+ ### wip-release: worktree prune (#212)
47
+ New step 12 in the release pipeline. After branch cleanup, prunes stale worktrees from `_worktrees/` whose branches are merged into main. Automatic cleanup after every release.
48
+
49
+ ### Dev Guide: _worktrees/ convention (#212)
50
+ Documents the centralized worktree convention:
51
+ - All worktrees go in `_worktrees/<repo-name>--<branch-suffix>/`
52
+ - Use `ldm worktree add` (auto-detects repo, creates in the right place)
53
+ - Guard warns about worktrees outside the convention
54
+ - `wip-release` auto-prunes merged worktrees
55
+
56
+ ## Why
57
+
58
+ Worktrees created as repo siblings confused iCloud sync, looked like real repos in directory listings, and were never cleaned up. This session alone created 10+ stale worktrees. The convention keeps them organized and the release pipeline cleans them automatically.
59
+
60
+ ## Issues closed
61
+
62
+ - #212
63
+ - #213
64
+
65
+ ## How to verify
66
+
67
+ ```bash
68
+ # Guard warning:
69
+ cd /path/to/repo
70
+ git worktree add ../my-worktree -b test # should warn about _worktrees/
71
+
72
+ # Correct path:
73
+ ldm worktree add cc-mini/test # creates _worktrees/<repo>--cc-mini--test/
74
+ ```
34
75
 
35
76
  ## 1.9.45 (2026-03-18)
36
77
 
@@ -524,16 +524,42 @@ gh api "repos/<org>/<repo>/branches/main/protection" -X PUT \
524
524
 
525
525
  The main working tree stays on `main` and is read-only in practice. All development happens in git worktrees. This keeps the primary clone clean, prevents accidental commits to main, and enables parallel work within a single agent.
526
526
 
527
+ ### Worktree Location Convention
528
+
529
+ **All worktrees go in `_worktrees/` as a sibling to the repos directory.** Never create worktrees as siblings to repos directly. They look like real repos, confuse iCloud sync, and are hard to find/clean.
530
+
531
+ **Convention:** `_worktrees/<repo-name>--<branch-suffix>/`
532
+
533
+ ```
534
+ repos/
535
+ ldm-os/
536
+ components/
537
+ memory-crystal-private/ <- real repo
538
+ devops/
539
+ wip-ai-devops-toolbox-private/ <- real repo
540
+ _worktrees/
541
+ memory-crystal-private--cc-mini--fix-search/ <- worktree
542
+ wip-ai-devops-toolbox-private--cc-mini--guard/ <- worktree
543
+ ```
544
+
527
545
  ### Starting a Worktree
528
546
 
529
- From Claude Code:
547
+ **Preferred:** Use the `ldm worktree` command:
548
+ ```bash
549
+ ldm worktree add cc-mini/fix-bug # auto-detects repo, creates in _worktrees/
550
+ ```
551
+
552
+ **From Claude Code:**
530
553
  ```bash
531
554
  claude --worktree <name>
532
555
  ```
533
556
 
534
- Or mid-session, say "work in a worktree" and the session will move into one.
557
+ **Manual:**
558
+ ```bash
559
+ git worktree add ../_worktrees/<repo>--<branch> -b <branch>
560
+ ```
535
561
 
536
- Worktrees live at `.claude/worktrees/` inside the repo. Each worktree gets its own directory with a full checkout on a separate branch.
562
+ The branch guard warns if you create worktrees outside `_worktrees/` or `.claude/worktrees/`.
537
563
 
538
564
  ### Branch Naming
539
565
 
package/SKILL.md CHANGED
@@ -5,7 +5,7 @@ license: MIT
5
5
  interface: [cli, module, mcp, skill, hook, plugin]
6
6
  metadata:
7
7
  display-name: "WIP AI DevOps Toolbox"
8
- version: "1.9.45"
8
+ version: "1.9.46"
9
9
  homepage: "https://github.com/wipcomputer/wip-ai-devops-toolbox"
10
10
  author: "Parker Todd Brooks"
11
11
  category: dev-tools
@@ -0,0 +1,28 @@
1
+ # Release Notes: wip-ai-devops-toolbox v1.9.41
2
+
3
+ **One-line summary of what this release does**
4
+
5
+ ## What changed
6
+
7
+ Describe the changes. Not a commit list. Explain:
8
+ - What was built or fixed
9
+ - Why it matters
10
+ - What the user should know
11
+
12
+ ## Why
13
+
14
+ What problem does this solve? What was broken or missing?
15
+
16
+ ## Issues closed
17
+
18
+ - #251
19
+ - #117
20
+ - #128
21
+ - #250
22
+ - #73
23
+
24
+ ## How to verify
25
+
26
+ ```bash
27
+ # Commands to test the changes
28
+ ```
@@ -0,0 +1,38 @@
1
+ # Release Notes: wip-ai-devops-toolbox v1.9.46
2
+
3
+ **Centralized worktree management: guard rule, wip-release prune, Dev Guide convention.**
4
+
5
+ ## What changed
6
+
7
+ ### Guard: worktree path warning (#212)
8
+ Branch guard now warns when `git worktree add` creates a worktree outside `_worktrees/`. Shows the convention and suggests `ldm worktree add`. Warning only, not a hard block.
9
+
10
+ ### wip-release: worktree prune (#212)
11
+ New step 12 in the release pipeline. After branch cleanup, prunes stale worktrees from `_worktrees/` whose branches are merged into main. Automatic cleanup after every release.
12
+
13
+ ### Dev Guide: _worktrees/ convention (#212)
14
+ Documents the centralized worktree convention:
15
+ - All worktrees go in `_worktrees/<repo-name>--<branch-suffix>/`
16
+ - Use `ldm worktree add` (auto-detects repo, creates in the right place)
17
+ - Guard warns about worktrees outside the convention
18
+ - `wip-release` auto-prunes merged worktrees
19
+
20
+ ## Why
21
+
22
+ Worktrees created as repo siblings confused iCloud sync, looked like real repos in directory listings, and were never cleaned up. This session alone created 10+ stale worktrees. The convention keeps them organized and the release pipeline cleans them automatically.
23
+
24
+ ## Issues closed
25
+
26
+ - #212
27
+ - #213
28
+
29
+ ## How to verify
30
+
31
+ ```bash
32
+ # Guard warning:
33
+ cd /path/to/repo
34
+ git worktree add ../my-worktree -b test # should warn about _worktrees/
35
+
36
+ # Correct path:
37
+ ldm worktree add cc-mini/test # creates _worktrees/<repo>--cc-mini--test/
38
+ ```
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wipcomputer/wip-ai-devops-toolbox",
3
- "version": "1.9.45",
3
+ "version": "1.9.46",
4
4
  "type": "module",
5
5
  "description": "The complete AI DevOps toolkit for AI-assisted development teams.",
6
6
  "license": "MIT",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wipcomputer/deploy-public",
3
- "version": "1.9.45",
3
+ "version": "1.9.46",
4
4
  "description": "Private-to-public repo sync. Excludes ai/ folder, creates PR, merges, cleans up branches.",
5
5
  "bin": {
6
6
  "deploy-public": "./deploy-public.sh"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wipcomputer/post-merge-rename",
3
- "version": "1.9.45",
3
+ "version": "1.9.46",
4
4
  "description": "Post-merge branch renaming. Appends --merged-YYYY-MM-DD to preserve history.",
5
5
  "bin": {
6
6
  "post-merge-rename": "./post-merge-rename.sh"
@@ -225,6 +225,21 @@ async function main() {
225
225
  }
226
226
  } catch {}
227
227
  }
228
+
229
+ // Warn when creating worktrees outside _worktrees/ (#212)
230
+ const wtMatch = cmd.match(/\bgit\s+worktree\s+add\s+["']?([^\s"']+)/);
231
+ if (wtMatch) {
232
+ const wtPath = wtMatch[1];
233
+ if (!wtPath.includes('_worktrees') && !wtPath.includes('.claude/worktrees')) {
234
+ deny(`WARNING: Creating worktree outside _worktrees/. Use: ldm worktree add <branch>
235
+
236
+ The convention is _worktrees/<repo>--<branch>/ so worktrees don't mix with real repos.
237
+ Manual equivalent: git worktree add ../_worktrees/<repo>--<branch> -b <branch>
238
+
239
+ This is a warning, not a block. If you need to create it here, retry.`);
240
+ process.exit(0);
241
+ }
242
+ }
228
243
  }
229
244
 
230
245
  // Determine which repo to check.
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wipcomputer/wip-branch-guard",
3
- "version": "1.9.45",
3
+ "version": "1.9.46",
4
4
  "description": "PreToolUse hook that blocks all writes on main branch. Forces agents to work on branches or worktrees.",
5
5
  "type": "module",
6
6
  "main": "guard.mjs",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wipcomputer/wip-file-guard",
3
- "version": "1.9.45",
3
+ "version": "1.9.46",
4
4
  "type": "module",
5
5
  "description": "Hook that blocks destructive edits to protected identity files. For Claude Code CLI and OpenClaw.",
6
6
  "main": "guard.mjs",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wipcomputer/wip-license-guard",
3
- "version": "1.9.45",
3
+ "version": "1.9.46",
4
4
  "description": "License compliance for your own repos. Ensures correct copyright, dual-license blocks, and LICENSE files.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wipcomputer/wip-license-hook",
3
- "version": "1.9.45",
3
+ "version": "1.9.46",
4
4
  "description": "License rug-pull detection and dependency license compliance for open source projects",
5
5
  "type": "module",
6
6
  "main": "dist/cli/index.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wipcomputer/wip-readme-format",
3
- "version": "1.9.45",
3
+ "version": "1.9.46",
4
4
  "description": "Reformat any repo's README to follow the WIP Computer standard. Agent-first, human-readable.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -1579,6 +1579,39 @@ export async function release({ repoPath, level, notes, notesSource, dryRun, noP
1579
1579
  console.log(` ! Branch prune skipped: ${e.message}`);
1580
1580
  }
1581
1581
 
1582
+ // 12. Prune stale worktrees (#212)
1583
+ try {
1584
+ execSync('git worktree prune', { cwd: repoPath, stdio: 'pipe' });
1585
+ // Also check _worktrees/ for dirs whose branches are now merged
1586
+ const worktreesDir = join(dirname(repoPath), '_worktrees');
1587
+ if (existsSync(worktreesDir)) {
1588
+ const repoBase = basename(repoPath);
1589
+ const wtDirs = readdirSync(worktreesDir, { withFileTypes: true })
1590
+ .filter(d => d.isDirectory() && d.name.startsWith(repoBase + '--'));
1591
+ let wtPruned = 0;
1592
+ for (const d of wtDirs) {
1593
+ const wtPath = join(worktreesDir, d.name);
1594
+ try {
1595
+ // Check if branch is merged into main
1596
+ const branch = execSync('git branch --show-current', {
1597
+ cwd: wtPath, encoding: 'utf8', timeout: 3000
1598
+ }).trim();
1599
+ if (branch) {
1600
+ execSync(`git merge-base --is-ancestor "${branch}" main`, {
1601
+ cwd: repoPath, stdio: 'pipe', timeout: 5000
1602
+ });
1603
+ // Branch is merged. Remove worktree.
1604
+ execSync(`git worktree remove "${wtPath}"`, { cwd: repoPath, stdio: 'pipe' });
1605
+ wtPruned++;
1606
+ }
1607
+ } catch {} // Branch not merged or other issue, leave it
1608
+ }
1609
+ if (wtPruned > 0) {
1610
+ console.log(` ✓ Pruned ${wtPruned} merged worktree(s) from _worktrees/`);
1611
+ }
1612
+ }
1613
+ } catch {}
1614
+
1582
1615
  // Write release marker so branch guard blocks immediate install (#73)
1583
1616
  try {
1584
1617
  const markerDir = join(process.env.HOME || '', '.ldm', 'state');
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wipcomputer/wip-release",
3
- "version": "1.9.45",
3
+ "version": "1.9.46",
4
4
  "type": "module",
5
5
  "description": "One-command release pipeline. Bumps version, updates changelog + SKILL.md, publishes to npm + GitHub.",
6
6
  "main": "core.mjs",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wipcomputer/wip-repo-init",
3
- "version": "1.9.45",
3
+ "version": "1.9.46",
4
4
  "description": "Scaffold the standard ai/ directory structure in any repo",
5
5
  "type": "module",
6
6
  "bin": {
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wipcomputer/wip-repo-permissions-hook",
3
- "version": "1.9.45",
3
+ "version": "1.9.46",
4
4
  "type": "module",
5
5
  "description": "Repo visibility guard. Blocks repos from going public without a -private counterpart.",
6
6
  "main": "core.mjs",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wipcomputer/wip-repos",
3
- "version": "1.9.45",
3
+ "version": "1.9.46",
4
4
  "type": "module",
5
5
  "description": "Repo manifest reconciler. Single source of truth for repo organization. Like prettier for folder structure.",
6
6
  "main": "core.mjs",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wipcomputer/universal-installer",
3
- "version": "1.9.45",
3
+ "version": "1.9.46",
4
4
  "type": "module",
5
5
  "description": "The Universal Interface specification for agent-native software. Teaches your AI how to build repos with every interface: CLI, Module, MCP Server, OpenClaw Plugin, Skill, Claude Code Hook.",
6
6
  "main": "detect.mjs",