@wipcomputer/wip-ai-devops-toolbox 1.9.20

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.
Files changed (146) hide show
  1. package/.license-guard.json +7 -0
  2. package/.publish-skill.json +4 -0
  3. package/CHANGELOG.md +1120 -0
  4. package/CLA.md +19 -0
  5. package/DEV-GUIDE-GENERAL-PUBLIC.md +882 -0
  6. package/LICENSE +52 -0
  7. package/README.md +238 -0
  8. package/SKILL.md +728 -0
  9. package/TECHNICAL.md +282 -0
  10. package/UNIVERSAL-INTERFACE.md +180 -0
  11. package/_trash/RELEASE-NOTES-v1-8-0.md +29 -0
  12. package/_trash/RELEASE-NOTES-v1-8-1.md +7 -0
  13. package/_trash/RELEASE-NOTES-v1-8-2.md +7 -0
  14. package/_trash/RELEASE-NOTES-v1-9-0.md +37 -0
  15. package/_trash/RELEASE-NOTES-v1-9-1.md +38 -0
  16. package/_trash/RELEASE-NOTES-v1-9-10.md +40 -0
  17. package/_trash/RELEASE-NOTES-v1-9-2.md +40 -0
  18. package/_trash/RELEASE-NOTES-v1-9-6.md +72 -0
  19. package/_trash/RELEASE-NOTES-v1-9-7.md +23 -0
  20. package/_trash/RELEASE-NOTES-v1-9-9.md +75 -0
  21. package/_trash/guide 2/DEV-GUIDE.md +487 -0
  22. package/_trash/guide 2/scripts/deploy-public.sh +152 -0
  23. package/package.json +27 -0
  24. package/scripts/SKILL-deploy-public.md +61 -0
  25. package/scripts/SKILL-post-merge-rename.md +47 -0
  26. package/scripts/deploy-public.sh +264 -0
  27. package/scripts/post-merge-rename.sh +205 -0
  28. package/scripts/publish-skill.sh +134 -0
  29. package/tools/deploy-public/LICENSE +52 -0
  30. package/tools/deploy-public/README.md +31 -0
  31. package/tools/deploy-public/SKILL.md +71 -0
  32. package/tools/deploy-public/deploy-public.sh +264 -0
  33. package/tools/deploy-public/package.json +9 -0
  34. package/tools/ldm-jobs/LICENSE +52 -0
  35. package/tools/ldm-jobs/README.md +46 -0
  36. package/tools/ldm-jobs/backup.sh +16 -0
  37. package/tools/ldm-jobs/branch-protect.sh +39 -0
  38. package/tools/ldm-jobs/crystal-capture.sh +19 -0
  39. package/tools/ldm-jobs/setup-shell.sh +27 -0
  40. package/tools/ldm-jobs/visibility-audit.sh +27 -0
  41. package/tools/post-merge-rename/LICENSE +52 -0
  42. package/tools/post-merge-rename/README.md +29 -0
  43. package/tools/post-merge-rename/SKILL.md +57 -0
  44. package/tools/post-merge-rename/package.json +9 -0
  45. package/tools/post-merge-rename/post-merge-rename.sh +122 -0
  46. package/tools/wip-branch-guard/INSTALL.md +41 -0
  47. package/tools/wip-branch-guard/guard.mjs +259 -0
  48. package/tools/wip-branch-guard/package.json +11 -0
  49. package/tools/wip-file-guard/CHANGELOG.md +6 -0
  50. package/tools/wip-file-guard/LICENSE +52 -0
  51. package/tools/wip-file-guard/README.md +113 -0
  52. package/tools/wip-file-guard/REFERENCE.md +86 -0
  53. package/tools/wip-file-guard/SKILL.md +105 -0
  54. package/tools/wip-file-guard/guard.mjs +128 -0
  55. package/tools/wip-file-guard/openclaw.plugin.json +8 -0
  56. package/tools/wip-file-guard/package.json +27 -0
  57. package/tools/wip-file-guard/test.sh +119 -0
  58. package/tools/wip-license-guard/LICENSE +52 -0
  59. package/tools/wip-license-guard/README.md +32 -0
  60. package/tools/wip-license-guard/SKILL.md +65 -0
  61. package/tools/wip-license-guard/cli.mjs +464 -0
  62. package/tools/wip-license-guard/core.mjs +310 -0
  63. package/tools/wip-license-guard/hook.mjs +146 -0
  64. package/tools/wip-license-guard/package.json +15 -0
  65. package/tools/wip-license-hook/CHANGELOG.md +17 -0
  66. package/tools/wip-license-hook/LICENSE +52 -0
  67. package/tools/wip-license-hook/README.md +200 -0
  68. package/tools/wip-license-hook/SKILL.md +111 -0
  69. package/tools/wip-license-hook/dist/cli/index.d.ts +15 -0
  70. package/tools/wip-license-hook/dist/cli/index.js +170 -0
  71. package/tools/wip-license-hook/dist/cli/index.js.map +1 -0
  72. package/tools/wip-license-hook/dist/core/detector.d.ts +12 -0
  73. package/tools/wip-license-hook/dist/core/detector.js +104 -0
  74. package/tools/wip-license-hook/dist/core/detector.js.map +1 -0
  75. package/tools/wip-license-hook/dist/core/index.d.ts +4 -0
  76. package/tools/wip-license-hook/dist/core/index.js +5 -0
  77. package/tools/wip-license-hook/dist/core/index.js.map +1 -0
  78. package/tools/wip-license-hook/dist/core/ledger.d.ts +49 -0
  79. package/tools/wip-license-hook/dist/core/ledger.js +72 -0
  80. package/tools/wip-license-hook/dist/core/ledger.js.map +1 -0
  81. package/tools/wip-license-hook/dist/core/reporter.d.ts +14 -0
  82. package/tools/wip-license-hook/dist/core/reporter.js +227 -0
  83. package/tools/wip-license-hook/dist/core/reporter.js.map +1 -0
  84. package/tools/wip-license-hook/dist/core/scanner.d.ts +39 -0
  85. package/tools/wip-license-hook/dist/core/scanner.js +325 -0
  86. package/tools/wip-license-hook/dist/core/scanner.js.map +1 -0
  87. package/tools/wip-license-hook/hooks/pre-pull.sh +55 -0
  88. package/tools/wip-license-hook/hooks/pre-push.sh +51 -0
  89. package/tools/wip-license-hook/mcp-server.mjs +119 -0
  90. package/tools/wip-license-hook/package-lock.json +54 -0
  91. package/tools/wip-license-hook/package.json +43 -0
  92. package/tools/wip-license-hook/src/cli/index.ts +189 -0
  93. package/tools/wip-license-hook/src/core/detector.ts +130 -0
  94. package/tools/wip-license-hook/src/core/index.ts +4 -0
  95. package/tools/wip-license-hook/src/core/ledger.ts +116 -0
  96. package/tools/wip-license-hook/src/core/reporter.ts +255 -0
  97. package/tools/wip-license-hook/src/core/scanner.ts +367 -0
  98. package/tools/wip-license-hook/tsconfig.json +16 -0
  99. package/tools/wip-readme-format/README.md +49 -0
  100. package/tools/wip-readme-format/SKILL.md +84 -0
  101. package/tools/wip-readme-format/format.mjs +570 -0
  102. package/tools/wip-readme-format/package.json +15 -0
  103. package/tools/wip-release/CHANGELOG.md +42 -0
  104. package/tools/wip-release/LICENSE +52 -0
  105. package/tools/wip-release/README.md +45 -0
  106. package/tools/wip-release/REFERENCE.md +100 -0
  107. package/tools/wip-release/SKILL.md +139 -0
  108. package/tools/wip-release/cli.js +161 -0
  109. package/tools/wip-release/core.mjs +1174 -0
  110. package/tools/wip-release/mcp-server.mjs +109 -0
  111. package/tools/wip-release/package.json +36 -0
  112. package/tools/wip-repo-init/README.md +38 -0
  113. package/tools/wip-repo-init/SKILL.md +77 -0
  114. package/tools/wip-repo-init/init.mjs +142 -0
  115. package/tools/wip-repo-init/package.json +11 -0
  116. package/tools/wip-repo-permissions-hook/LICENSE +52 -0
  117. package/tools/wip-repo-permissions-hook/README.md +86 -0
  118. package/tools/wip-repo-permissions-hook/SKILL.md +73 -0
  119. package/tools/wip-repo-permissions-hook/cli.js +83 -0
  120. package/tools/wip-repo-permissions-hook/core.mjs +122 -0
  121. package/tools/wip-repo-permissions-hook/guard.mjs +64 -0
  122. package/tools/wip-repo-permissions-hook/mcp-server.mjs +92 -0
  123. package/tools/wip-repo-permissions-hook/openclaw.plugin.json +8 -0
  124. package/tools/wip-repo-permissions-hook/package.json +31 -0
  125. package/tools/wip-repos/LICENSE +52 -0
  126. package/tools/wip-repos/README.md +77 -0
  127. package/tools/wip-repos/SKILL.md +80 -0
  128. package/tools/wip-repos/cli.mjs +176 -0
  129. package/tools/wip-repos/core.mjs +290 -0
  130. package/tools/wip-repos/mcp-server.mjs +157 -0
  131. package/tools/wip-repos/package.json +34 -0
  132. package/tools/wip-universal-installer/CHANGELOG.md +57 -0
  133. package/tools/wip-universal-installer/LICENSE +52 -0
  134. package/tools/wip-universal-installer/README.md +81 -0
  135. package/tools/wip-universal-installer/REFERENCE.md +122 -0
  136. package/tools/wip-universal-installer/SKILL.md +87 -0
  137. package/tools/wip-universal-installer/SPEC.md +180 -0
  138. package/tools/wip-universal-installer/detect.mjs +130 -0
  139. package/tools/wip-universal-installer/examples/minimal/README.md +20 -0
  140. package/tools/wip-universal-installer/examples/minimal/SKILL.md +28 -0
  141. package/tools/wip-universal-installer/examples/minimal/cli.mjs +4 -0
  142. package/tools/wip-universal-installer/examples/minimal/core.mjs +8 -0
  143. package/tools/wip-universal-installer/examples/minimal/mcp-server.mjs +27 -0
  144. package/tools/wip-universal-installer/examples/minimal/package.json +12 -0
  145. package/tools/wip-universal-installer/install.js +930 -0
  146. package/tools/wip-universal-installer/package.json +36 -0
@@ -0,0 +1,105 @@
1
+ ---
2
+ name: wip-file-guard
3
+ description: Hook that blocks destructive edits to protected identity files. For Claude Code CLI and OpenClaw.
4
+ license: MIT
5
+ interface: [cli, module, hook, plugin, skill]
6
+ metadata:
7
+ display-name: "Identity File Protection"
8
+ version: "1.0.1"
9
+ homepage: "https://github.com/wipcomputer/wip-file-guard"
10
+ author: "Parker Todd Brooks"
11
+ category: dev-tools
12
+ capabilities:
13
+ - file-protection
14
+ - edit-blocking
15
+ - identity-guard
16
+ requires:
17
+ bins: [node]
18
+ openclaw:
19
+ requires:
20
+ bins: [node]
21
+ install:
22
+ - id: node
23
+ kind: node
24
+ package: "@wipcomputer/wip-file-guard"
25
+ bins: [wip-file-guard]
26
+ label: "Install via npm"
27
+ emoji: "🛡️"
28
+ compatibility: Requires node. Node.js 18+.
29
+ ---
30
+
31
+ # wip-file-guard
32
+
33
+ Hook that blocks destructive edits to protected identity files. For Claude Code CLI and OpenClaw.
34
+
35
+ ## When to Use This Skill
36
+
37
+ **Use wip-file-guard for:**
38
+ - Protecting CLAUDE.md, SOUL.md, IDENTITY.md, MEMORY.md, and other identity files from being overwritten
39
+ - Blocking AI agents from replacing file content instead of extending it
40
+ - Surviving context compaction (behavioral rules get erased, but hooks don't)
41
+
42
+ **This is a technical guardrail, not a prompt.** It blocks the operation before it happens.
43
+
44
+ ### Do NOT Use For
45
+
46
+ - Protecting binary files or images
47
+ - Blocking all edits (it allows small edits, only blocks destructive ones)
48
+ - Repos without identity files
49
+
50
+ ## How It Works
51
+
52
+ Two rules:
53
+
54
+ 1. **Write is blocked** on protected files. Always. Use Edit instead.
55
+ 2. **Edit is blocked** when it removes more than 2 net lines from a protected file.
56
+
57
+ ### Protected Files
58
+
59
+ CLAUDE.md, SHARED-CONTEXT.md, SOUL.md, IDENTITY.md, CONTEXT.md, TOOLS.md, MEMORY.md
60
+
61
+ ### Protected Patterns
62
+
63
+ Any file matching: memory, memories, journal, diary, daily log
64
+
65
+ ## API Reference
66
+
67
+ ### CLI
68
+
69
+ ```bash
70
+ node guard.mjs --list # list protected files
71
+ bash test.sh # run test suite
72
+ ```
73
+
74
+ ### Claude Code Hook
75
+
76
+ Add to `~/.claude/settings.json`:
77
+
78
+ ```json
79
+ {
80
+ "hooks": {
81
+ "PreToolUse": [
82
+ {
83
+ "matcher": "Edit|Write",
84
+ "hooks": [
85
+ {
86
+ "type": "command",
87
+ "command": "node \"/path/to/wip-file-guard/guard.mjs\"",
88
+ "timeout": 5
89
+ }
90
+ ]
91
+ }
92
+ ]
93
+ }
94
+ }
95
+ ```
96
+
97
+ ## Troubleshooting
98
+
99
+ ### Agent keeps trying to Write
100
+
101
+ The deny message tells the agent to re-read the file and use Edit instead. If the agent ignores it, it's likely post-compaction and has lost context. The hook will keep blocking.
102
+
103
+ ### Edit blocked unexpectedly
104
+
105
+ Check the net line removal. Edits that remove more than 2 lines from a protected file are blocked. Small edits (adding or replacing 1-2 lines) are allowed.
@@ -0,0 +1,128 @@
1
+ #!/usr/bin/env node
2
+ // cc-file-guard/guard.mjs
3
+ // PreToolUse hook for Claude Code.
4
+ // Blocks destructive edits to protected files.
5
+ // - Blocks Write tool on protected files entirely
6
+ // - Blocks Edit when net line removal > 2 lines
7
+
8
+ import { basename } from 'node:path';
9
+ import { existsSync } from 'node:fs';
10
+
11
+ // Exact basename matches
12
+ export const PROTECTED = new Set([
13
+ 'CLAUDE.md',
14
+ 'SHARED-CONTEXT.md',
15
+ 'SOUL.md',
16
+ 'IDENTITY.md',
17
+ 'CONTEXT.md',
18
+ 'TOOLS.md',
19
+ 'MEMORY.md',
20
+ ]);
21
+
22
+ // Pattern matches (case-insensitive, checked against full path and basename)
23
+ export const PROTECTED_PATTERNS = [
24
+ /memory/i,
25
+ /memories/i,
26
+ /journal/i,
27
+ /diary/i,
28
+ /daily.*log/i,
29
+ ];
30
+
31
+ function isProtected(filePath) {
32
+ const name = basename(filePath);
33
+ if (PROTECTED.has(name)) return name;
34
+ for (const pattern of PROTECTED_PATTERNS) {
35
+ if (pattern.test(filePath)) return name + ` (matched pattern: ${pattern})`;
36
+ }
37
+ return null;
38
+ }
39
+
40
+ function deny(reason) {
41
+ const output = {
42
+ hookSpecificOutput: {
43
+ hookEventName: 'PreToolUse',
44
+ permissionDecision: 'deny',
45
+ permissionDecisionReason: reason,
46
+ },
47
+ };
48
+ process.stdout.write(JSON.stringify(output));
49
+ }
50
+
51
+ function countLines(str) {
52
+ if (!str) return 0;
53
+ return str.split('\n').length;
54
+ }
55
+
56
+ // CLI mode: node guard.mjs --list
57
+ if (process.argv.includes('--list')) {
58
+ console.log('Protected files (exact):');
59
+ for (const f of PROTECTED) console.log(` ${f}`);
60
+ console.log('Protected patterns:');
61
+ for (const p of PROTECTED_PATTERNS) console.log(` ${p}`);
62
+ process.exit(0);
63
+ }
64
+
65
+ async function main() {
66
+ let raw = '';
67
+ for await (const chunk of process.stdin) {
68
+ raw += chunk;
69
+ }
70
+
71
+ let input;
72
+ try {
73
+ input = JSON.parse(raw);
74
+ } catch {
75
+ // Can't parse input, allow by default
76
+ process.exit(0);
77
+ }
78
+
79
+ const toolName = input.tool_name || '';
80
+ const toolInput = input.tool_input || {};
81
+ const filePath = toolInput.file_path || toolInput.filePath || '';
82
+ const fileName = basename(filePath);
83
+
84
+ // Only check protected files
85
+ const match = isProtected(filePath);
86
+ if (!match) {
87
+ process.exit(0);
88
+ }
89
+
90
+ // Block Write on protected files
91
+ // Exact matches: always block Write (use Edit instead)
92
+ // Pattern matches: only block if file already exists (allow creating new files)
93
+ if (toolName === 'Write') {
94
+ const isExactMatch = PROTECTED.has(fileName);
95
+ if (isExactMatch || existsSync(filePath)) {
96
+ deny(`BLOCKED: Write tool on ${match} is not allowed. Use Edit to make specific changes. Never overwrite protected files.`);
97
+ process.exit(0);
98
+ }
99
+ // Pattern match but file doesn't exist yet — allow creation
100
+ process.exit(0);
101
+ }
102
+
103
+ // For Edit, check line removal AND large replacements
104
+ if (toolName === 'Edit') {
105
+ const oldString = toolInput.old_string || '';
106
+ const newString = toolInput.new_string || '';
107
+ const oldLines = countLines(oldString);
108
+ const newLines = countLines(newString);
109
+ const removed = oldLines - newLines;
110
+
111
+ // Block net removal of more than 2 lines
112
+ if (removed > 2) {
113
+ 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.`);
114
+ process.exit(0);
115
+ }
116
+
117
+ // Block large replacements (swapping big chunks even if line count is similar)
118
+ if (oldLines > 4 && oldString !== newString) {
119
+ deny(`BLOCKED: You are replacing ${oldLines} lines in ${match}. Edit smaller sections or append new content instead of replacing existing content.`);
120
+ process.exit(0);
121
+ }
122
+ }
123
+
124
+ // Allow
125
+ process.exit(0);
126
+ }
127
+
128
+ main().catch(() => process.exit(0));
@@ -0,0 +1,8 @@
1
+ {
2
+ "name": "wip-file-guard",
3
+ "version": "1.0.0",
4
+ "description": "Blocks destructive edits to protected files (CLAUDE.md, SHARED-CONTEXT.md, SOUL.md, etc.)",
5
+ "lifecycle": {
6
+ "before_tool_use": "./guard.mjs"
7
+ }
8
+ }
@@ -0,0 +1,27 @@
1
+ {
2
+ "name": "@wipcomputer/wip-file-guard",
3
+ "version": "1.9.20",
4
+ "type": "module",
5
+ "description": "Hook that blocks destructive edits to protected identity files. For Claude Code CLI and OpenClaw.",
6
+ "main": "guard.mjs",
7
+ "bin": {
8
+ "wip-file-guard": "./guard.mjs"
9
+ },
10
+ "scripts": {
11
+ "test": "bash test.sh"
12
+ },
13
+ "keywords": [
14
+ "claude-code",
15
+ "openclaw",
16
+ "hook",
17
+ "file-guard",
18
+ "ai-safety",
19
+ "pretooluse"
20
+ ],
21
+ "author": "Parker Todd Brooks",
22
+ "license": "MIT",
23
+ "repository": {
24
+ "type": "git",
25
+ "url": "git+https://github.com/wipcomputer/wip-file-guard.git"
26
+ }
27
+ }
@@ -0,0 +1,119 @@
1
+ #!/bin/bash
2
+ # test.sh - Test wip-file-guard hook
3
+ # Run: bash test.sh
4
+
5
+ SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
6
+ GUARD="$SCRIPT_DIR/guard.mjs"
7
+ PASS=0
8
+ FAIL=0
9
+
10
+ check() {
11
+ local desc="$1"
12
+ local input="$2"
13
+ local expect="$3" # "block" or "allow"
14
+
15
+ local output
16
+ output=$(echo "$input" | node "$GUARD" 2>/dev/null)
17
+ local code=$?
18
+
19
+ if [ "$expect" = "block" ]; then
20
+ if echo "$output" | grep -q "deny"; then
21
+ echo "PASS: $desc"
22
+ ((PASS++))
23
+ else
24
+ echo "FAIL: $desc (expected block, got allow)"
25
+ ((FAIL++))
26
+ fi
27
+ else
28
+ if [ -z "$output" ] && [ $code -eq 0 ]; then
29
+ echo "PASS: $desc"
30
+ ((PASS++))
31
+ else
32
+ echo "FAIL: $desc (expected allow, got: $output)"
33
+ ((FAIL++))
34
+ fi
35
+ fi
36
+ }
37
+
38
+ echo "wip-file-guard tests"
39
+ echo "==================="
40
+ echo ""
41
+
42
+ # Write tests
43
+ check "Block Write to CLAUDE.md" \
44
+ '{"tool_name":"Write","tool_input":{"file_path":"/foo/CLAUDE.md","content":"new"}}' \
45
+ "block"
46
+
47
+ check "Block Write to SHARED-CONTEXT.md" \
48
+ '{"tool_name":"Write","tool_input":{"file_path":"/bar/workspace/SHARED-CONTEXT.md","content":"new"}}' \
49
+ "block"
50
+
51
+ check "Allow Write to random file" \
52
+ '{"tool_name":"Write","tool_input":{"file_path":"/foo/bar.js","content":"new"}}' \
53
+ "allow"
54
+
55
+ # Edit tests - line removal
56
+ check "Block Edit removing 5 lines from CLAUDE.md" \
57
+ '{"tool_name":"Edit","tool_input":{"file_path":"/foo/CLAUDE.md","old_string":"a\nb\nc\nd\ne\nf","new_string":"replaced"}}' \
58
+ "block"
59
+
60
+ check "Allow Edit adding lines to CLAUDE.md" \
61
+ '{"tool_name":"Edit","tool_input":{"file_path":"/foo/CLAUDE.md","old_string":"a","new_string":"a\nb\nc"}}' \
62
+ "allow"
63
+
64
+ check "Allow Edit on non-protected file (even removing lines)" \
65
+ '{"tool_name":"Edit","tool_input":{"file_path":"/foo/bar.js","old_string":"a\nb\nc\nd\ne","new_string":"x"}}' \
66
+ "allow"
67
+
68
+ check "Allow Edit with small removal (2 lines)" \
69
+ '{"tool_name":"Edit","tool_input":{"file_path":"/foo/SOUL.md","old_string":"a\nb\nc","new_string":"x"}}' \
70
+ "allow"
71
+
72
+ check "Block Edit with 4 line removal from SOUL.md" \
73
+ '{"tool_name":"Edit","tool_input":{"file_path":"/foo/SOUL.md","old_string":"a\nb\nc\nd\ne\nf","new_string":"x\ny"}}' \
74
+ "block"
75
+
76
+ # Protected file coverage
77
+ check "Block Write to IDENTITY.md" \
78
+ '{"tool_name":"Write","tool_input":{"file_path":"/any/path/IDENTITY.md","content":"new"}}' \
79
+ "block"
80
+
81
+ check "Block Write to TOOLS.md" \
82
+ '{"tool_name":"Write","tool_input":{"file_path":"/any/path/TOOLS.md","content":"new"}}' \
83
+ "block"
84
+
85
+ # Large replacement (same line count, different content)
86
+ check "Block Edit replacing 8 lines with 8 different lines in SHARED-CONTEXT.md" \
87
+ '{"tool_name":"Edit","tool_input":{"file_path":"/foo/SHARED-CONTEXT.md","old_string":"line1\nline2\nline3\nline4\nline5\nline6\nline7\nline8","new_string":"new1\nnew2\nnew3\nnew4\nnew5\nnew6\nnew7\nnew8"}}' \
88
+ "block"
89
+
90
+ check "Allow Edit replacing 3 lines in CLAUDE.md" \
91
+ '{"tool_name":"Edit","tool_input":{"file_path":"/foo/CLAUDE.md","old_string":"a\nb\nc","new_string":"x\ny\nz"}}' \
92
+ "allow"
93
+
94
+ # Pattern matching - Write
95
+ # Pattern-matched files: allow Write for NEW files, block for existing files
96
+ check "Allow Write to NEW file in memory/ directory (file doesn't exist)" \
97
+ '{"tool_name":"Write","tool_input":{"file_path":"/nonexistent/memory/2099-01-01.md","content":"new"}}' \
98
+ "allow"
99
+
100
+ check "Allow Write to NEW journal file (file doesn't exist)" \
101
+ '{"tool_name":"Write","tool_input":{"file_path":"/nonexistent/journals/new-entry.md","content":"new"}}' \
102
+ "allow"
103
+
104
+ # Pattern matching - Edit (existing files still protected from destructive edits)
105
+ check "Block Edit removing lines from daily log" \
106
+ '{"tool_name":"Edit","tool_input":{"file_path":"/memory/daily/2026-02-19.md","old_string":"a\nb\nc\nd\ne","new_string":"x"}}' \
107
+ "block"
108
+
109
+ # Block Write to pattern-matched file that EXISTS on disk
110
+ check "Block Write to existing test.sh (matched pattern: memory in path)" \
111
+ "{\"tool_name\":\"Write\",\"tool_input\":{\"file_path\":\"$SCRIPT_DIR/test.sh\",\"content\":\"new\"}}" \
112
+ "allow"
113
+
114
+ check "Allow Write to unrelated file with no pattern match" \
115
+ '{"tool_name":"Write","tool_input":{"file_path":"/src/utils/helper.js","content":"new"}}' \
116
+ "allow"
117
+
118
+ echo ""
119
+ echo "Results: $PASS passed, $FAIL failed"
@@ -0,0 +1,52 @@
1
+ Dual License: MIT + AGPLv3
2
+
3
+ Copyright (c) 2026 WIP Computer, Inc.
4
+
5
+
6
+ 1. MIT License (local and personal use)
7
+ ---------------------------------------
8
+
9
+ Permission is hereby granted, free of charge, to any person obtaining a copy
10
+ of this software and associated documentation files (the "Software"), to deal
11
+ in the Software without restriction, including without limitation the rights
12
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13
+ copies of the Software, and to permit persons to whom the Software is
14
+ furnished to do so, subject to the following conditions:
15
+
16
+ The above copyright notice and this permission notice shall be included in all
17
+ copies or substantial portions of the Software.
18
+
19
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
25
+ SOFTWARE.
26
+
27
+
28
+ 2. GNU Affero General Public License v3.0 (commercial and cloud use)
29
+ --------------------------------------------------------------------
30
+
31
+ If you run this software as part of a hosted service, cloud platform,
32
+ marketplace listing, or any network-accessible offering for commercial
33
+ purposes, the AGPLv3 terms apply. You must either:
34
+
35
+ a) Release your complete source code under AGPLv3, or
36
+ b) Obtain a commercial license.
37
+
38
+ This program is free software: you can redistribute it and/or modify
39
+ it under the terms of the GNU Affero General Public License as published
40
+ by the Free Software Foundation, either version 3 of the License, or
41
+ (at your option) any later version.
42
+
43
+ This program is distributed in the hope that it will be useful,
44
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
45
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
46
+ GNU Affero General Public License for more details.
47
+
48
+ You should have received a copy of the GNU Affero General Public License
49
+ along with this program. If not, see <https://www.gnu.org/licenses/>.
50
+
51
+
52
+ AGPLv3 for personal use is free. Commercial licenses available.
@@ -0,0 +1,32 @@
1
+ ###### WIP Computer
2
+
3
+ # License Guard
4
+
5
+ Enforce licensing on every commit. Copyright, dual-license, CLA. Checked automatically.
6
+
7
+ ## What it does
8
+
9
+ - Ensures your own repos have correct copyright, license type, and LICENSE files
10
+ - Interactive first-run setup
11
+ - Toolbox-aware: checks every sub-tool
12
+ - Auto-fix mode repairs issues
13
+ - `readme-license` scans all your repos and applies a standard license block to every README in one command
14
+ - Removes duplicate license sections from sub-tool READMEs
15
+
16
+ ## Usage
17
+
18
+ ```bash
19
+ node tools/wip-license-guard/cli.mjs /path/to/repo
20
+ node tools/wip-license-guard/cli.mjs /path/to/repo --fix
21
+ ```
22
+
23
+ ## Requirements
24
+
25
+ - node (18+)
26
+ - git
27
+
28
+ ## Interfaces
29
+
30
+ - **CLI**: Command-line tool
31
+
32
+ ## Part of [AI DevOps Toolbox](https://github.com/wipcomputer/wip-ai-devops-toolbox)
@@ -0,0 +1,65 @@
1
+ ---
2
+ name: wip-license-guard
3
+ description: License compliance for your own repos. Ensures correct copyright headers, dual-license blocks, and LICENSE files across all source files.
4
+ license: MIT
5
+ interface: [cli, skill]
6
+ metadata:
7
+ display-name: "License Guard"
8
+ version: "1.0.0"
9
+ homepage: "https://github.com/wipcomputer/wip-ai-devops-toolbox"
10
+ author: "Parker Todd Brooks"
11
+ category: dev-tools
12
+ capabilities:
13
+ - copyright-enforcement
14
+ - license-compliance
15
+ - license-file-check
16
+ requires:
17
+ bins: [node, git]
18
+ openclaw:
19
+ requires:
20
+ bins: [node, git]
21
+ install:
22
+ - id: node
23
+ kind: node
24
+ package: "@wipcomputer/wip-license-guard"
25
+ bins: [wip-license-guard]
26
+ label: "Install via npm"
27
+ emoji: "📜"
28
+ ---
29
+
30
+ # wip-license-guard
31
+
32
+ License compliance for your own repos. Ensures correct copyright, dual-license blocks, LICENSE files, and README license sections.
33
+
34
+ ## When to Use This Skill
35
+
36
+ - Before a release, to verify all files have correct license headers
37
+ - After adding new source files to a repo
38
+ - To enforce the MIT/AGPL dual-license pattern
39
+ - To standardize README license sections across all your repos
40
+
41
+ ## CLI
42
+
43
+ ```bash
44
+ wip-license-guard check [path] # audit repo against config
45
+ wip-license-guard check --fix [path] # auto-fix LICENSE, CLA, copyright issues
46
+ wip-license-guard init [path] # interactive setup
47
+ wip-license-guard init --from-standard # apply WIP Computer defaults (no prompts)
48
+ wip-license-guard readme-license [path] # audit README license sections
49
+ wip-license-guard readme-license --dry-run # preview what would change
50
+ wip-license-guard readme-license --fix # apply standard block to all READMEs
51
+ ```
52
+
53
+ ### readme-license
54
+
55
+ Scans all repos for README license sections. Three modes:
56
+
57
+ - **No flags**: audit only. Reports non-standard, missing, and sub-tool READMEs that shouldn't have license sections.
58
+ - **--dry-run**: preview. Shows what each README has now and what would change. No files touched.
59
+ - **--fix**: apply. Replaces non-standard sections with the standard dual MIT/AGPLv3 block. Removes license sections from sub-tool READMEs.
60
+
61
+ Works on a single repo or a directory of repos:
62
+ ```bash
63
+ wip-license-guard readme-license /path/to/one-repo
64
+ wip-license-guard readme-license /path/to/directory-of-repos
65
+ ```