@wipcomputer/wip-ai-devops-toolbox 1.9.31 → 1.9.32

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,29 @@
31
31
 
32
32
 
33
33
 
34
+
35
+ ## 1.9.32 (2026-03-15)
36
+
37
+ # --version on all CLIs + issue cleanup
38
+
39
+ **Date:** 2026-03-15
40
+ **Closes:** #190, #191, #169, #123, #119
41
+
42
+ ## What changed
43
+
44
+ All 7 CLI tools now support `--version` and `-v`. Each reads its own `package.json` and prints the version. Previously, `wip-release --version` printed the help text instead of a version number.
45
+
46
+ Tools updated: wip-release, wip-repos, wip-license-guard, wip-repo-permissions, wip-repo-init, wip-readme-format, wip-file-guard, wip-branch-guard.
47
+
48
+ wip-license-guard also got a proper README (#169) with all commands, config format, and integration docs.
49
+
50
+ ## Issues closed
51
+
52
+ - #190: wip-release --version should work
53
+ - #191: enforce --version on all CLI tools
54
+ - #169: wip-license-guard needs its own README
55
+ - #123: Merge/Deploy/Install conflated (enforced across v1.9.25-v1.9.30)
56
+ - #119: All destructive tools must have --dry-run (all confirmed)
34
57
 
35
58
  ## 1.9.31 (2026-03-15)
36
59
 
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.31"
8
+ version: "1.9.32"
9
9
  homepage: "https://github.com/wipcomputer/wip-ai-devops-toolbox"
10
10
  author: "Parker Todd Brooks"
11
11
  category: dev-tools
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wipcomputer/wip-ai-devops-toolbox",
3
- "version": "1.9.31",
3
+ "version": "1.9.32",
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.31",
3
+ "version": "1.9.32",
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.31",
3
+ "version": "1.9.32",
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"
@@ -5,8 +5,16 @@
5
5
  // Agents must work on branches or worktrees. Never on main.
6
6
 
7
7
  import { execSync } from 'node:child_process';
8
- import { dirname } from 'node:path';
9
- import { statSync } from 'node:fs';
8
+ import { dirname, join } from 'node:path';
9
+ import { statSync, readFileSync } from 'node:fs';
10
+ import { fileURLToPath } from 'node:url';
11
+
12
+ if (process.argv.includes('--version') || process.argv.includes('-v')) {
13
+ const __dirname = dirname(fileURLToPath(import.meta.url));
14
+ const pkg = JSON.parse(readFileSync(join(__dirname, 'package.json'), 'utf8'));
15
+ console.log(pkg.version);
16
+ process.exit(0);
17
+ }
10
18
 
11
19
  // Tools that modify files or git state
12
20
  const WRITE_TOOLS = new Set(['Write', 'Edit', 'NotebookEdit']);
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wipcomputer/wip-branch-guard",
3
- "version": "1.9.31",
3
+ "version": "1.9.32",
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",
@@ -5,8 +5,16 @@
5
5
  // - Blocks Write tool on protected files entirely
6
6
  // - Blocks Edit when net line removal > 2 lines
7
7
 
8
- import { basename } from 'node:path';
9
- import { existsSync } from 'node:fs';
8
+ import { basename, dirname, join } from 'node:path';
9
+ import { existsSync, readFileSync } from 'node:fs';
10
+ import { fileURLToPath } from 'node:url';
11
+
12
+ if (process.argv.includes('--version') || process.argv.includes('-v')) {
13
+ const __dirname = dirname(fileURLToPath(import.meta.url));
14
+ const pkg = JSON.parse(readFileSync(join(__dirname, 'package.json'), 'utf8'));
15
+ console.log(pkg.version);
16
+ process.exit(0);
17
+ }
10
18
 
11
19
  // Exact basename matches
12
20
  export const PROTECTED = new Set([
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wipcomputer/wip-file-guard",
3
- "version": "1.9.31",
3
+ "version": "1.9.32",
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",
@@ -2,31 +2,68 @@
2
2
 
3
3
  # License Guard
4
4
 
5
- Enforce licensing on every commit. Copyright, dual-license, CLA. Checked automatically.
5
+ Enforce licensing on every repo. Copyright, dual-license, CLA, README license section. Checked automatically on every release.
6
6
 
7
- ## What it does
7
+ ## Commands
8
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
9
+ ```bash
10
+ wip-license-guard check # audit current repo
11
+ wip-license-guard check --fix # audit and auto-fix issues
12
+ wip-license-guard init # interactive first-run setup
13
+ wip-license-guard init --from-standard # apply WIP Computer defaults without prompting
14
+ wip-license-guard readme-license # audit license blocks across all repos
15
+ wip-license-guard readme-license --fix # apply standard license block to all READMEs
16
+ wip-license-guard readme-license --dry-run # preview changes without writing
17
+ ```
15
18
 
16
- ## Usage
19
+ ## What it checks
17
20
 
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
+ - LICENSE file exists and matches configured license type
22
+ - Copyright line is correct and current year
23
+ - CLA.md exists (if configured)
24
+ - README has a `## License` section with the standard block
25
+ - For toolbox repos: checks every sub-tool in `tools/`
26
+
27
+ ## Config
28
+
29
+ `.license-guard.json` in repo root. Created by `init`. Contains copyright holder, license type, year, and what to enforce.
30
+
31
+ ```json
32
+ {
33
+ "copyright": "WIP Computer, Inc.",
34
+ "license": "MIT+AGPL",
35
+ "year": 2026,
36
+ "enforceCLA": true,
37
+ "enforceReadmeLicense": true
38
+ }
21
39
  ```
22
40
 
23
- ## Requirements
41
+ ## wip-release gate
42
+
43
+ Step 0 of wip-release reads `.license-guard.json` and runs the same checks. If compliance fails, the release is blocked.
24
44
 
25
- - node (18+)
26
- - git
45
+ ## `--from-standard` generates
46
+
47
+ - `.license-guard.json` with WIP Computer defaults
48
+ - `LICENSE` file (dual MIT+AGPL)
49
+ - `CLA.md`
50
+
51
+ ## readme-license
52
+
53
+ Scans all repos in a directory and applies a standard license block to every README. Removes duplicate license sections from sub-tool READMEs. Reads templates from `ai/wip-templates/readme/`.
54
+
55
+ ## Source
56
+
57
+ Pure JavaScript, no build step. Zero dependencies.
58
+
59
+ - `cli.mjs` ... CLI entry point
60
+ - `core.mjs` ... license checking and generation logic
61
+ - `hook.mjs` ... wip-release gate integration
27
62
 
28
63
  ## Interfaces
29
64
 
30
- - **CLI**: Command-line tool
65
+ - **CLI**: `wip-license-guard`
31
66
 
32
67
  ## Part of [AI DevOps Toolbox](https://github.com/wipcomputer/wip-ai-devops-toolbox)
68
+
69
+ Built by Parker Todd Brooks, Lēsa (OpenClaw, Claude Opus 4.6), Claude Code (Claude Opus 4.6).
@@ -4,10 +4,18 @@
4
4
  // Ensures correct copyright, dual-license blocks, and LICENSE files.
5
5
 
6
6
  import { existsSync, readFileSync, writeFileSync, readdirSync } from 'node:fs';
7
- import { join } from 'node:path';
7
+ import { join, dirname } from 'node:path';
8
+ import { fileURLToPath } from 'node:url';
8
9
  import { createInterface } from 'node:readline';
9
10
  import { generateLicense, generateCLA, generateReadmeBlock, replaceReadmeLicenseSection, removeReadmeLicenseSection } from './core.mjs';
10
11
 
12
+ if (process.argv.includes('--version') || process.argv.includes('-v')) {
13
+ const __dirname = dirname(fileURLToPath(import.meta.url));
14
+ const pkg = JSON.parse(readFileSync(join(__dirname, 'package.json'), 'utf8'));
15
+ console.log(pkg.version);
16
+ process.exit(0);
17
+ }
18
+
11
19
  const args = process.argv.slice(2);
12
20
  const HELP_FLAGS = ['--help', '-h', 'help'];
13
21
  const command = HELP_FLAGS.some(f => args.includes(f)) ? 'help' : (args.find(a => !a.startsWith('--')) || 'check');
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wipcomputer/wip-license-guard",
3
- "version": "1.9.31",
3
+ "version": "1.9.32",
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.31",
3
+ "version": "1.9.32",
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",
@@ -28,6 +28,13 @@ import { fileURLToPath } from 'node:url';
28
28
  import { detectInterfaces, detectToolbox } from '../wip-universal-installer/detect.mjs';
29
29
 
30
30
  const __dirname = dirname(fileURLToPath(import.meta.url));
31
+
32
+ if (process.argv.includes('--version') || process.argv.includes('-v')) {
33
+ const pkg = JSON.parse(readFileSync(join(__dirname, 'package.json'), 'utf8'));
34
+ console.log(pkg.version);
35
+ process.exit(0);
36
+ }
37
+
31
38
  const args = process.argv.slice(2);
32
39
  const DRY_RUN = args.includes('--dry-run');
33
40
  const CHECK = args.includes('--check');
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wipcomputer/wip-readme-format",
3
- "version": "1.9.31",
3
+ "version": "1.9.32",
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": {
@@ -98,6 +98,15 @@ let notesSource = (notes !== null && notes !== undefined && notes !== '') ? 'fla
98
98
  }
99
99
  }
100
100
 
101
+ if (args.includes('--version') || args.includes('-v')) {
102
+ const { readFileSync } = await import('node:fs');
103
+ const { join, dirname } = await import('node:path');
104
+ const { fileURLToPath } = await import('node:url');
105
+ const pkg = JSON.parse(readFileSync(join(dirname(fileURLToPath(import.meta.url)), 'package.json'), 'utf8'));
106
+ console.log(pkg.version);
107
+ process.exit(0);
108
+ }
109
+
101
110
  if (!level || args.includes('--help') || args.includes('-h')) {
102
111
  const cwd = process.cwd();
103
112
  let current = '';
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wipcomputer/wip-release",
3
- "version": "1.9.31",
3
+ "version": "1.9.32",
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",
@@ -9,12 +9,18 @@
9
9
  // 2. Moves old ai/ contents into ai/_sort/ai_old/
10
10
  // 3. You sort from there at your own pace.
11
11
 
12
- import { existsSync, mkdirSync, cpSync, renameSync, readdirSync, statSync } from 'node:fs';
12
+ import { existsSync, mkdirSync, cpSync, renameSync, readdirSync, statSync, readFileSync } from 'node:fs';
13
13
  import { join, resolve, dirname } from 'node:path';
14
14
  import { fileURLToPath } from 'node:url';
15
15
  import { createInterface } from 'node:readline';
16
16
 
17
17
  const __dirname = dirname(fileURLToPath(import.meta.url));
18
+
19
+ if (process.argv.includes('--version') || process.argv.includes('-v')) {
20
+ const pkg = JSON.parse(readFileSync(join(__dirname, 'package.json'), 'utf8'));
21
+ console.log(pkg.version);
22
+ process.exit(0);
23
+ }
18
24
  const TEMPLATE = join(__dirname, 'templates');
19
25
 
20
26
  const targetRepo = resolve(process.argv[2] || process.cwd());
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wipcomputer/wip-repo-init",
3
- "version": "1.9.31",
3
+ "version": "1.9.32",
4
4
  "description": "Scaffold the standard ai/ directory structure in any repo",
5
5
  "type": "module",
6
6
  "bin": {
@@ -9,8 +9,18 @@
9
9
  * wip-repo-permissions can-publish <org/repo> Alias for check
10
10
  */
11
11
 
12
+ import { readFileSync } from 'node:fs';
13
+ import { join, dirname } from 'node:path';
14
+ import { fileURLToPath } from 'node:url';
12
15
  import { checkPrivateCounterpart, auditOrg } from './core.mjs';
13
16
 
17
+ if (process.argv.includes('--version') || process.argv.includes('-v')) {
18
+ const __dirname = dirname(fileURLToPath(import.meta.url));
19
+ const pkg = JSON.parse(readFileSync(join(__dirname, 'package.json'), 'utf8'));
20
+ console.log(pkg.version);
21
+ process.exit(0);
22
+ }
23
+
14
24
  const args = process.argv.slice(2);
15
25
  const command = args[0];
16
26
  const target = args[1];
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wipcomputer/wip-repo-permissions-hook",
3
- "version": "1.9.31",
3
+ "version": "1.9.32",
4
4
  "type": "module",
5
5
  "description": "Repo visibility guard. Blocks repos from going public without a -private counterpart.",
6
6
  "main": "core.mjs",
@@ -12,7 +12,16 @@
12
12
  */
13
13
 
14
14
  import { check, planSync, executeSync, addRepo, moveRepo, generateReadmeTree, loadManifest } from './core.mjs';
15
- import { resolve, dirname } from 'node:path';
15
+ import { resolve, dirname, join } from 'node:path';
16
+ import { readFileSync } from 'node:fs';
17
+ import { fileURLToPath } from 'node:url';
18
+
19
+ if (process.argv.includes('--version') || process.argv.includes('-v')) {
20
+ const __dirname = dirname(fileURLToPath(import.meta.url));
21
+ const pkg = JSON.parse(readFileSync(join(__dirname, 'package.json'), 'utf8'));
22
+ console.log(pkg.version);
23
+ process.exit(0);
24
+ }
16
25
 
17
26
  const args = process.argv.slice(2);
18
27
  const command = args[0];
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wipcomputer/wip-repos",
3
- "version": "1.9.31",
3
+ "version": "1.9.32",
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.31",
3
+ "version": "1.9.32",
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",