@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 +23 -0
- package/SKILL.md +1 -1
- package/package.json +1 -1
- package/tools/deploy-public/package.json +1 -1
- package/tools/post-merge-rename/package.json +1 -1
- package/tools/wip-branch-guard/guard.mjs +10 -2
- package/tools/wip-branch-guard/package.json +1 -1
- package/tools/wip-file-guard/guard.mjs +10 -2
- package/tools/wip-file-guard/package.json +1 -1
- package/tools/wip-license-guard/README.md +53 -16
- package/tools/wip-license-guard/cli.mjs +9 -1
- package/tools/wip-license-guard/package.json +1 -1
- package/tools/wip-license-hook/package.json +1 -1
- package/tools/wip-readme-format/format.mjs +7 -0
- package/tools/wip-readme-format/package.json +1 -1
- package/tools/wip-release/cli.js +9 -0
- package/tools/wip-release/package.json +1 -1
- package/tools/wip-repo-init/init.mjs +7 -1
- package/tools/wip-repo-init/package.json +1 -1
- package/tools/wip-repo-permissions-hook/cli.js +10 -0
- package/tools/wip-repo-permissions-hook/package.json +1 -1
- package/tools/wip-repos/cli.mjs +10 -1
- package/tools/wip-repos/package.json +1 -1
- package/tools/wip-universal-installer/package.json +1 -1
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.
|
|
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
|
@@ -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']);
|
|
@@ -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([
|
|
@@ -2,31 +2,68 @@
|
|
|
2
2
|
|
|
3
3
|
# License Guard
|
|
4
4
|
|
|
5
|
-
Enforce licensing on every
|
|
5
|
+
Enforce licensing on every repo. Copyright, dual-license, CLA, README license section. Checked automatically on every release.
|
|
6
6
|
|
|
7
|
-
##
|
|
7
|
+
## Commands
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
-
|
|
11
|
-
-
|
|
12
|
-
-
|
|
13
|
-
-
|
|
14
|
-
-
|
|
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
|
-
##
|
|
19
|
+
## What it checks
|
|
17
20
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
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
|
-
##
|
|
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
|
-
-
|
|
26
|
-
|
|
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**:
|
|
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');
|
|
@@ -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');
|
package/tools/wip-release/cli.js
CHANGED
|
@@ -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 = '';
|
|
@@ -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());
|
|
@@ -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];
|
package/tools/wip-repos/cli.mjs
CHANGED
|
@@ -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/universal-installer",
|
|
3
|
-
"version": "1.9.
|
|
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",
|