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

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,34 @@
31
31
 
32
32
 
33
33
 
34
+
35
+ ## 1.9.45 (2026-03-18)
36
+
37
+ # Release Notes: wip-ai-devops-toolbox v1.9.45
38
+
39
+ **Guard now teaches the workflow instead of just blocking.**
40
+
41
+ ## What changed
42
+
43
+ - **Branch guard error messages overhauled (#213).** When the guard blocks a write on main, it now shows the full 8-step process: worktree, branch, commit, push, PR, merge, wip-release, deploy-public. Includes the lesson that release notes go on the feature branch, not as a separate PR.
44
+ - **Separate error for "on branch but not in worktree."** Tells the agent to go back to main and create a worktree properly.
45
+ - **CLAUDE.md added to shared state allowlist.** Was patched in the deployed guard but missing from source. Now in sync.
46
+
47
+ ## Why
48
+
49
+ Agents kept getting blocked by the guard and then trying workarounds instead of following the process. The error message said "Use a worktree" but didn't explain the full workflow. Today's session hit this 5+ times. The guard works. The gap was agent knowledge.
50
+
51
+ ## Issues closed
52
+
53
+ - #213
54
+ - #256
55
+
56
+ ## How to verify
57
+
58
+ ```bash
59
+ # In any repo on main, try to edit a file. The error should show the full workflow.
60
+ # In any repo on a branch (not worktree), try to edit. Should show worktree instructions.
61
+ ```
34
62
 
35
63
  ## 1.9.44 (2026-03-17)
36
64
 
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.44"
8
+ version: "1.9.45"
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,25 @@
1
+ # Release Notes: wip-ai-devops-toolbox v1.9.45
2
+
3
+ **Guard now teaches the workflow instead of just blocking.**
4
+
5
+ ## What changed
6
+
7
+ - **Branch guard error messages overhauled (#213).** When the guard blocks a write on main, it now shows the full 8-step process: worktree, branch, commit, push, PR, merge, wip-release, deploy-public. Includes the lesson that release notes go on the feature branch, not as a separate PR.
8
+ - **Separate error for "on branch but not in worktree."** Tells the agent to go back to main and create a worktree properly.
9
+ - **CLAUDE.md added to shared state allowlist.** Was patched in the deployed guard but missing from source. Now in sync.
10
+
11
+ ## Why
12
+
13
+ Agents kept getting blocked by the guard and then trying workarounds instead of following the process. The error message said "Use a worktree" but didn't explain the full workflow. Today's session hit this 5+ times. The guard works. The gap was agent knowledge.
14
+
15
+ ## Issues closed
16
+
17
+ - #213
18
+ - #256
19
+
20
+ ## How to verify
21
+
22
+ ```bash
23
+ # In any repo on main, try to edit a file. The error should show the full workflow.
24
+ # In any repo on a branch (not worktree), try to edit. Should show worktree instructions.
25
+ ```
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wipcomputer/wip-ai-devops-toolbox",
3
- "version": "1.9.44",
3
+ "version": "1.9.45",
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.44",
3
+ "version": "1.9.45",
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.44",
3
+ "version": "1.9.45",
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"
@@ -91,6 +91,28 @@ const ALLOWED_BASH_PATTERNS = [
91
91
  /\bclaude\s+mcp\b/, // MCP registration, not repo files
92
92
  ];
93
93
 
94
+ // Workflow steps for error messages (#213)
95
+ const WORKFLOW_ON_MAIN = `
96
+ The process: worktree -> branch -> commit -> push -> PR -> merge -> wip-release -> deploy-public.
97
+
98
+ Step 1: git worktree add ../my-worktree -b cc-mini/your-feature
99
+ Step 2: Edit files in the worktree
100
+ Step 3: git add + git commit (with co-authors)
101
+ Step 4: git push -u origin cc-mini/your-feature
102
+ Step 5: gh pr create, then gh pr merge --merge --delete-branch
103
+ Step 6: Back in main repo: git pull
104
+ Step 7: wip-release patch (with RELEASE-NOTES on the branch, not after)
105
+ Step 8: deploy-public.sh to sync public repo
106
+
107
+ Release notes go ON the feature branch, committed with the code. Not as a separate PR.`.trim();
108
+
109
+ const WORKFLOW_NOT_WORKTREE = `
110
+ You're on a branch but not in a worktree. Use a worktree so the main working tree stays clean.
111
+
112
+ Step 1: git checkout main (go back to main first)
113
+ Step 2: git worktree add ../my-worktree -b your-branch-name
114
+ Step 3: Edit files in the worktree directory`.trim();
115
+
94
116
  function deny(reason) {
95
117
  const output = {
96
118
  hookSpecificOutput: {
@@ -265,17 +287,31 @@ async function main() {
265
287
  BLOCKED_BASH_PATTERNS.some(p => p.test(command)) &&
266
288
  !ALLOWED_BASH_PATTERNS.some(p => p.test(command)));
267
289
  if (isWriteOp) {
268
- deny(`BLOCKED: On branch "${branch}" but not in a worktree. Use: git worktree add ../my-worktree -b ${branch}`);
290
+ deny(`BLOCKED: On branch "${branch}" but not in a worktree.\n\n${WORKFLOW_NOT_WORKTREE}`);
269
291
  process.exit(0);
270
292
  }
271
293
  process.exit(0);
272
294
  }
273
295
 
274
- // We're on main. Check if this is a write operation.
296
+ // We're on main. Check if this is a shared state file (always writable).
297
+ // These are not code. They're shared context between agents.
298
+ const SHARED_STATE_PATTERNS = [
299
+ /CLAUDE\.md$/,
300
+ /workspace\/SHARED-CONTEXT\.md$/,
301
+ /workspace\/memory\/.*\.md$/,
302
+ /\.ldm\/agents\/.*\/memory\/daily\/.*\.md$/,
303
+ /\.ldm\/memory\/shared-log\.jsonl$/,
304
+ /\.ldm\/memory\/daily\/.*\.md$/,
305
+ /\.ldm\/logs\//,
306
+ ];
307
+
308
+ if (filePath && SHARED_STATE_PATTERNS.some(p => p.test(filePath))) {
309
+ process.exit(0); // Shared state, always allow
310
+ }
275
311
 
276
312
  // Block Write/Edit tools entirely on main
277
313
  if (WRITE_TOOLS.has(toolName)) {
278
- deny(`BLOCKED: Cannot ${toolName} while on main branch. Use a worktree: git worktree add ../my-worktree -b cc-mini/your-feature`);
314
+ deny(`BLOCKED: Cannot ${toolName} while on main branch.\n\n${WORKFLOW_ON_MAIN}`);
279
315
  process.exit(0);
280
316
  }
281
317
 
@@ -297,7 +333,7 @@ async function main() {
297
333
  if (ap.test(command)) { isAllowed = true; break; }
298
334
  }
299
335
  if (!isAllowed) {
300
- deny(`BLOCKED: Cannot run "${command.substring(0, 60)}..." on main branch. Use a worktree: git worktree add ../my-worktree -b cc-mini/your-feature`);
336
+ deny(`BLOCKED: Cannot run "${command.substring(0, 60)}..." on main branch.\n\n${WORKFLOW_ON_MAIN}`);
301
337
  process.exit(0);
302
338
  }
303
339
  }
@@ -312,7 +348,7 @@ async function main() {
312
348
  if (ap.test(command)) { isAllowed = true; break; }
313
349
  }
314
350
  if (!isAllowed) {
315
- deny(`BLOCKED: Cannot run file-modifying command on main branch. Use a worktree: git worktree add ../my-worktree -b cc-mini/your-feature`);
351
+ deny(`BLOCKED: Cannot run file-modifying command on main branch.\n\n${WORKFLOW_ON_MAIN}`);
316
352
  process.exit(0);
317
353
  }
318
354
  }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wipcomputer/wip-branch-guard",
3
- "version": "1.9.44",
3
+ "version": "1.9.45",
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",
@@ -36,6 +36,26 @@ export const PROTECTED_PATTERNS = [
36
36
  /daily.*log/i,
37
37
  ];
38
38
 
39
+ // Shared state files: protected from Write but allow larger Edit replacements.
40
+ // These are actively edited by both agents every session.
41
+ const SHARED_STATE_FILES = new Set([
42
+ 'SHARED-CONTEXT.md',
43
+ ]);
44
+
45
+ // Daily logs and workspace memory: allow creation and larger edits
46
+ const SHARED_STATE_PATHS = [
47
+ /workspace\/memory\/\d{4}-\d{2}-\d{2}\.md$/,
48
+ /\.ldm\/agents\/.*\/memory\/daily\/.*\.md$/,
49
+ /\.ldm\/memory\/daily\/.*\.md$/,
50
+ /\.ldm\/memory\/shared-log\.jsonl$/,
51
+ ];
52
+
53
+ function isSharedState(filePath) {
54
+ const name = basename(filePath);
55
+ if (SHARED_STATE_FILES.has(name)) return true;
56
+ return SHARED_STATE_PATHS.some(p => p.test(filePath));
57
+ }
58
+
39
59
  function isProtected(filePath) {
40
60
  const name = basename(filePath);
41
61
  if (PROTECTED.has(name)) return name;
@@ -116,14 +136,19 @@ async function main() {
116
136
  const newLines = countLines(newString);
117
137
  const removed = oldLines - newLines;
118
138
 
119
- // Block net removal of more than 2 lines
120
- if (removed > 2) {
139
+ // Shared state files get higher limits (updated every session by both agents)
140
+ const isShared = isSharedState(filePath);
141
+ const maxRemoval = isShared ? 20 : 2;
142
+ const maxReplace = isShared ? 30 : 4;
143
+
144
+ // Block net removal beyond limit
145
+ if (removed > maxRemoval) {
121
146
  deny(`BLOCKED: You are removing ${removed} lines from ${match} (old: ${oldLines} lines, new: ${newLines} lines). Re-read the file and add content instead of replacing it.`);
122
147
  process.exit(0);
123
148
  }
124
149
 
125
150
  // Block large replacements (swapping big chunks even if line count is similar)
126
- if (oldLines > 4 && oldString !== newString) {
151
+ if (oldLines > maxReplace && oldString !== newString) {
127
152
  deny(`BLOCKED: You are replacing ${oldLines} lines in ${match}. Edit smaller sections or append new content instead of replacing existing content.`);
128
153
  process.exit(0);
129
154
  }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wipcomputer/wip-file-guard",
3
- "version": "1.9.44",
3
+ "version": "1.9.45",
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.44",
3
+ "version": "1.9.45",
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.44",
3
+ "version": "1.9.45",
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.44",
3
+ "version": "1.9.45",
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": {
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wipcomputer/wip-release",
3
- "version": "1.9.44",
3
+ "version": "1.9.45",
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.44",
3
+ "version": "1.9.45",
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.44",
3
+ "version": "1.9.45",
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.44",
3
+ "version": "1.9.45",
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.44",
3
+ "version": "1.9.45",
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",