@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.
- package/.license-guard.json +7 -0
- package/.publish-skill.json +4 -0
- package/CHANGELOG.md +1120 -0
- package/CLA.md +19 -0
- package/DEV-GUIDE-GENERAL-PUBLIC.md +882 -0
- package/LICENSE +52 -0
- package/README.md +238 -0
- package/SKILL.md +728 -0
- package/TECHNICAL.md +282 -0
- package/UNIVERSAL-INTERFACE.md +180 -0
- package/_trash/RELEASE-NOTES-v1-8-0.md +29 -0
- package/_trash/RELEASE-NOTES-v1-8-1.md +7 -0
- package/_trash/RELEASE-NOTES-v1-8-2.md +7 -0
- package/_trash/RELEASE-NOTES-v1-9-0.md +37 -0
- package/_trash/RELEASE-NOTES-v1-9-1.md +38 -0
- package/_trash/RELEASE-NOTES-v1-9-10.md +40 -0
- package/_trash/RELEASE-NOTES-v1-9-2.md +40 -0
- package/_trash/RELEASE-NOTES-v1-9-6.md +72 -0
- package/_trash/RELEASE-NOTES-v1-9-7.md +23 -0
- package/_trash/RELEASE-NOTES-v1-9-9.md +75 -0
- package/_trash/guide 2/DEV-GUIDE.md +487 -0
- package/_trash/guide 2/scripts/deploy-public.sh +152 -0
- package/package.json +27 -0
- package/scripts/SKILL-deploy-public.md +61 -0
- package/scripts/SKILL-post-merge-rename.md +47 -0
- package/scripts/deploy-public.sh +264 -0
- package/scripts/post-merge-rename.sh +205 -0
- package/scripts/publish-skill.sh +134 -0
- package/tools/deploy-public/LICENSE +52 -0
- package/tools/deploy-public/README.md +31 -0
- package/tools/deploy-public/SKILL.md +71 -0
- package/tools/deploy-public/deploy-public.sh +264 -0
- package/tools/deploy-public/package.json +9 -0
- package/tools/ldm-jobs/LICENSE +52 -0
- package/tools/ldm-jobs/README.md +46 -0
- package/tools/ldm-jobs/backup.sh +16 -0
- package/tools/ldm-jobs/branch-protect.sh +39 -0
- package/tools/ldm-jobs/crystal-capture.sh +19 -0
- package/tools/ldm-jobs/setup-shell.sh +27 -0
- package/tools/ldm-jobs/visibility-audit.sh +27 -0
- package/tools/post-merge-rename/LICENSE +52 -0
- package/tools/post-merge-rename/README.md +29 -0
- package/tools/post-merge-rename/SKILL.md +57 -0
- package/tools/post-merge-rename/package.json +9 -0
- package/tools/post-merge-rename/post-merge-rename.sh +122 -0
- package/tools/wip-branch-guard/INSTALL.md +41 -0
- package/tools/wip-branch-guard/guard.mjs +259 -0
- package/tools/wip-branch-guard/package.json +11 -0
- package/tools/wip-file-guard/CHANGELOG.md +6 -0
- package/tools/wip-file-guard/LICENSE +52 -0
- package/tools/wip-file-guard/README.md +113 -0
- package/tools/wip-file-guard/REFERENCE.md +86 -0
- package/tools/wip-file-guard/SKILL.md +105 -0
- package/tools/wip-file-guard/guard.mjs +128 -0
- package/tools/wip-file-guard/openclaw.plugin.json +8 -0
- package/tools/wip-file-guard/package.json +27 -0
- package/tools/wip-file-guard/test.sh +119 -0
- package/tools/wip-license-guard/LICENSE +52 -0
- package/tools/wip-license-guard/README.md +32 -0
- package/tools/wip-license-guard/SKILL.md +65 -0
- package/tools/wip-license-guard/cli.mjs +464 -0
- package/tools/wip-license-guard/core.mjs +310 -0
- package/tools/wip-license-guard/hook.mjs +146 -0
- package/tools/wip-license-guard/package.json +15 -0
- package/tools/wip-license-hook/CHANGELOG.md +17 -0
- package/tools/wip-license-hook/LICENSE +52 -0
- package/tools/wip-license-hook/README.md +200 -0
- package/tools/wip-license-hook/SKILL.md +111 -0
- package/tools/wip-license-hook/dist/cli/index.d.ts +15 -0
- package/tools/wip-license-hook/dist/cli/index.js +170 -0
- package/tools/wip-license-hook/dist/cli/index.js.map +1 -0
- package/tools/wip-license-hook/dist/core/detector.d.ts +12 -0
- package/tools/wip-license-hook/dist/core/detector.js +104 -0
- package/tools/wip-license-hook/dist/core/detector.js.map +1 -0
- package/tools/wip-license-hook/dist/core/index.d.ts +4 -0
- package/tools/wip-license-hook/dist/core/index.js +5 -0
- package/tools/wip-license-hook/dist/core/index.js.map +1 -0
- package/tools/wip-license-hook/dist/core/ledger.d.ts +49 -0
- package/tools/wip-license-hook/dist/core/ledger.js +72 -0
- package/tools/wip-license-hook/dist/core/ledger.js.map +1 -0
- package/tools/wip-license-hook/dist/core/reporter.d.ts +14 -0
- package/tools/wip-license-hook/dist/core/reporter.js +227 -0
- package/tools/wip-license-hook/dist/core/reporter.js.map +1 -0
- package/tools/wip-license-hook/dist/core/scanner.d.ts +39 -0
- package/tools/wip-license-hook/dist/core/scanner.js +325 -0
- package/tools/wip-license-hook/dist/core/scanner.js.map +1 -0
- package/tools/wip-license-hook/hooks/pre-pull.sh +55 -0
- package/tools/wip-license-hook/hooks/pre-push.sh +51 -0
- package/tools/wip-license-hook/mcp-server.mjs +119 -0
- package/tools/wip-license-hook/package-lock.json +54 -0
- package/tools/wip-license-hook/package.json +43 -0
- package/tools/wip-license-hook/src/cli/index.ts +189 -0
- package/tools/wip-license-hook/src/core/detector.ts +130 -0
- package/tools/wip-license-hook/src/core/index.ts +4 -0
- package/tools/wip-license-hook/src/core/ledger.ts +116 -0
- package/tools/wip-license-hook/src/core/reporter.ts +255 -0
- package/tools/wip-license-hook/src/core/scanner.ts +367 -0
- package/tools/wip-license-hook/tsconfig.json +16 -0
- package/tools/wip-readme-format/README.md +49 -0
- package/tools/wip-readme-format/SKILL.md +84 -0
- package/tools/wip-readme-format/format.mjs +570 -0
- package/tools/wip-readme-format/package.json +15 -0
- package/tools/wip-release/CHANGELOG.md +42 -0
- package/tools/wip-release/LICENSE +52 -0
- package/tools/wip-release/README.md +45 -0
- package/tools/wip-release/REFERENCE.md +100 -0
- package/tools/wip-release/SKILL.md +139 -0
- package/tools/wip-release/cli.js +161 -0
- package/tools/wip-release/core.mjs +1174 -0
- package/tools/wip-release/mcp-server.mjs +109 -0
- package/tools/wip-release/package.json +36 -0
- package/tools/wip-repo-init/README.md +38 -0
- package/tools/wip-repo-init/SKILL.md +77 -0
- package/tools/wip-repo-init/init.mjs +142 -0
- package/tools/wip-repo-init/package.json +11 -0
- package/tools/wip-repo-permissions-hook/LICENSE +52 -0
- package/tools/wip-repo-permissions-hook/README.md +86 -0
- package/tools/wip-repo-permissions-hook/SKILL.md +73 -0
- package/tools/wip-repo-permissions-hook/cli.js +83 -0
- package/tools/wip-repo-permissions-hook/core.mjs +122 -0
- package/tools/wip-repo-permissions-hook/guard.mjs +64 -0
- package/tools/wip-repo-permissions-hook/mcp-server.mjs +92 -0
- package/tools/wip-repo-permissions-hook/openclaw.plugin.json +8 -0
- package/tools/wip-repo-permissions-hook/package.json +31 -0
- package/tools/wip-repos/LICENSE +52 -0
- package/tools/wip-repos/README.md +77 -0
- package/tools/wip-repos/SKILL.md +80 -0
- package/tools/wip-repos/cli.mjs +176 -0
- package/tools/wip-repos/core.mjs +290 -0
- package/tools/wip-repos/mcp-server.mjs +157 -0
- package/tools/wip-repos/package.json +34 -0
- package/tools/wip-universal-installer/CHANGELOG.md +57 -0
- package/tools/wip-universal-installer/LICENSE +52 -0
- package/tools/wip-universal-installer/README.md +81 -0
- package/tools/wip-universal-installer/REFERENCE.md +122 -0
- package/tools/wip-universal-installer/SKILL.md +87 -0
- package/tools/wip-universal-installer/SPEC.md +180 -0
- package/tools/wip-universal-installer/detect.mjs +130 -0
- package/tools/wip-universal-installer/examples/minimal/README.md +20 -0
- package/tools/wip-universal-installer/examples/minimal/SKILL.md +28 -0
- package/tools/wip-universal-installer/examples/minimal/cli.mjs +4 -0
- package/tools/wip-universal-installer/examples/minimal/core.mjs +8 -0
- package/tools/wip-universal-installer/examples/minimal/mcp-server.mjs +27 -0
- package/tools/wip-universal-installer/examples/minimal/package.json +12 -0
- package/tools/wip-universal-installer/install.js +930 -0
- package/tools/wip-universal-installer/package.json +36 -0
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
###### WIP Computer
|
|
2
|
+
|
|
3
|
+
[](https://www.npmjs.com/package/@wipcomputer/wip-license-hook) [](https://github.com/wipcomputer/wip-ai-devops-toolbox/blob/main/tools/wip-license-hook/cli.js) [](https://github.com/wipcomputer/wip-ai-devops-toolbox/blob/main/tools/wip-license-hook/mcp-server.mjs) [](https://github.com/wipcomputer/wip-ai-devops-toolbox/blob/main/tools/wip-license-hook/SKILL.md) [](https://github.com/wipcomputer/wip-ai-devops-toolbox/blob/main/tools/wip-universal-installer/SPEC.md)
|
|
4
|
+
|
|
5
|
+
# wip-license-hook
|
|
6
|
+
|
|
7
|
+
License rug-pull detection and dependency license compliance for open source projects.
|
|
8
|
+
|
|
9
|
+
## The Problem
|
|
10
|
+
|
|
11
|
+
You fork an MIT project. You build on it. Six months later, the upstream quietly changes to BSL or proprietary. You pull the update without checking. Now your project is poisoned.
|
|
12
|
+
|
|
13
|
+
This has happened. It will happen again.
|
|
14
|
+
|
|
15
|
+
## The Solution
|
|
16
|
+
|
|
17
|
+
A pre-merge hook + daily scanner + public dashboard that:
|
|
18
|
+
|
|
19
|
+
1. **Maintains a license ledger** of every dependency and fork at time of adoption
|
|
20
|
+
2. **Gates all upstream merges** — if the license changed, the merge is blocked
|
|
21
|
+
3. **Scans daily** — catches license drift before it reaches your codebase
|
|
22
|
+
4. **Publishes a dashboard** — public proof of license health for anyone using your forks
|
|
23
|
+
|
|
24
|
+
## How It Works
|
|
25
|
+
|
|
26
|
+
### Git Hooks (Always On)
|
|
27
|
+
|
|
28
|
+
**Two mandatory hooks. No bypass.**
|
|
29
|
+
|
|
30
|
+
**Pre-pull** — before pulling anything from upstream:
|
|
31
|
+
```
|
|
32
|
+
git pull upstream main
|
|
33
|
+
→ hook fires FIRST
|
|
34
|
+
→ fetch without merge
|
|
35
|
+
→ check LICENSE, package.json, SPDX headers
|
|
36
|
+
→ compare against ledger
|
|
37
|
+
→ SAME? → pull proceeds
|
|
38
|
+
→ CHANGED? → BLOCK. Flag. Document. Notify. Do NOT pull.
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
**Pre-push** — before pushing any commit to our branch:
|
|
42
|
+
```
|
|
43
|
+
git push origin main
|
|
44
|
+
→ hook fires FIRST
|
|
45
|
+
→ check upstream license status
|
|
46
|
+
→ compare against ledger
|
|
47
|
+
→ SAME? → push proceeds
|
|
48
|
+
→ CHANGED? → ALERT. Warn that upstream has drifted. Push still allowed (it's our code) but we know.
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
Pre-pull = hard gate (blocks).
|
|
52
|
+
Pre-push = alert (warns, doesn't block our own work).
|
|
53
|
+
|
|
54
|
+
### License Ledger
|
|
55
|
+
|
|
56
|
+
`LICENSE-LEDGER.json` tracks every dependency:
|
|
57
|
+
|
|
58
|
+
```json
|
|
59
|
+
{
|
|
60
|
+
"dependencies": [
|
|
61
|
+
{
|
|
62
|
+
"name": "openclaw",
|
|
63
|
+
"source": "github:openclaw/openclaw",
|
|
64
|
+
"type": "fork",
|
|
65
|
+
"license_at_adoption": "MIT",
|
|
66
|
+
"license_current": "MIT",
|
|
67
|
+
"adopted_date": "2026-02-05",
|
|
68
|
+
"last_checked": "2026-02-15",
|
|
69
|
+
"commit_at_adoption": "abc123",
|
|
70
|
+
"status": "clean"
|
|
71
|
+
}
|
|
72
|
+
],
|
|
73
|
+
"last_full_scan": "2026-02-15T08:00:00Z",
|
|
74
|
+
"alerts": []
|
|
75
|
+
}
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
Status values: `clean` | `changed` | `removed` | `unknown`
|
|
79
|
+
|
|
80
|
+
### LICENSE Snapshots
|
|
81
|
+
|
|
82
|
+
Physical copies of LICENSE files at adoption. Not just metadata. Proof that survives git history rewrites.
|
|
83
|
+
|
|
84
|
+
```
|
|
85
|
+
ledger/
|
|
86
|
+
snapshots/
|
|
87
|
+
openclaw/
|
|
88
|
+
LICENSE-2026-02-05.txt ← what it was when we forked
|
|
89
|
+
LICENSE-2026-02-15.txt ← latest check
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
If they rug-pull and rewrite history, we have the receipt on disk.
|
|
93
|
+
|
|
94
|
+
### Daily Cron Scan
|
|
95
|
+
|
|
96
|
+
Runs every morning:
|
|
97
|
+
|
|
98
|
+
1. For each fork: `git fetch upstream` (no merge), check LICENSE file
|
|
99
|
+
2. For each npm/pip dependency: check registry for current license metadata
|
|
100
|
+
3. Compare everything against the ledger
|
|
101
|
+
4. Generate report
|
|
102
|
+
5. If anything changed: alert immediately (message, email, or both)
|
|
103
|
+
|
|
104
|
+
### Public Dashboard
|
|
105
|
+
|
|
106
|
+
Static site (GitHub Pages or similar) generated from the ledger:
|
|
107
|
+
|
|
108
|
+
- List of all dependencies and forks
|
|
109
|
+
- License at adoption vs current license
|
|
110
|
+
- Last checked date
|
|
111
|
+
- Health status (green/yellow/red)
|
|
112
|
+
- Proof links (commit hashes, archived LICENSE files)
|
|
113
|
+
|
|
114
|
+
Anyone using our forks can verify: "WIP Computer adopted this when it was MIT, and it's still MIT."
|
|
115
|
+
|
|
116
|
+
## Detection Methods
|
|
117
|
+
|
|
118
|
+
### For Forks (git repos)
|
|
119
|
+
- Check `LICENSE` / `LICENSE.md` / `COPYING` file content
|
|
120
|
+
- Parse `package.json` license field
|
|
121
|
+
- Check for SPDX headers in source files
|
|
122
|
+
- Compare against known license text fingerprints
|
|
123
|
+
|
|
124
|
+
### For npm Dependencies
|
|
125
|
+
- `npm view <package> license`
|
|
126
|
+
- Compare against ledger
|
|
127
|
+
|
|
128
|
+
### For Python Dependencies
|
|
129
|
+
- `pip show <package>` license field
|
|
130
|
+
- PyPI API metadata
|
|
131
|
+
|
|
132
|
+
## Installation
|
|
133
|
+
|
|
134
|
+
### As an OpenClaw Skill
|
|
135
|
+
```bash
|
|
136
|
+
clawhub install wip-license-hook
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
### As a Git Hook
|
|
140
|
+
```bash
|
|
141
|
+
wip-license-hook install --repo .
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
### As a Cron Job
|
|
145
|
+
```bash
|
|
146
|
+
wip-license-hook scan --all --report
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
## Architecture
|
|
150
|
+
|
|
151
|
+
```
|
|
152
|
+
core/
|
|
153
|
+
scanner.ts — license detection logic
|
|
154
|
+
ledger.ts — ledger read/write/compare
|
|
155
|
+
detector.ts — license text fingerprinting
|
|
156
|
+
reporter.ts — generate reports and alerts
|
|
157
|
+
cli/
|
|
158
|
+
index.ts — CLI wrapper
|
|
159
|
+
skill/
|
|
160
|
+
SKILL.md — OpenClaw/agent skill definition
|
|
161
|
+
dashboard/
|
|
162
|
+
index.html — static dashboard generator
|
|
163
|
+
hooks/
|
|
164
|
+
pre-merge.sh — git hook script
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
## Commands
|
|
168
|
+
|
|
169
|
+
```bash
|
|
170
|
+
wip-license-hook init # Initialize ledger for current project
|
|
171
|
+
wip-license-hook scan # Scan all deps, update ledger
|
|
172
|
+
wip-license-hook check <dep> # Check specific dependency
|
|
173
|
+
wip-license-hook gate # Pre-merge license gate (for hooks)
|
|
174
|
+
wip-license-hook report # Generate report
|
|
175
|
+
wip-license-hook dashboard # Generate static dashboard
|
|
176
|
+
wip-license-hook alert # Send alerts for any changes
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
## Why This Matters
|
|
180
|
+
|
|
181
|
+
> "Been dubious of MIT open source. Seen too many pull it or hide non-MIT bins for it all to work."
|
|
182
|
+
|
|
183
|
+
This tool is the guardrail. The receipt. The proof.
|
|
184
|
+
|
|
185
|
+
If your dependency gets rug-pulled, you have:
|
|
186
|
+
- The exact commit where the license was what you agreed to
|
|
187
|
+
- Documentation of when and what changed
|
|
188
|
+
- A clean fork point to fall back to
|
|
189
|
+
- Public proof for anyone downstream of you
|
|
190
|
+
|
|
191
|
+
## License
|
|
192
|
+
|
|
193
|
+
```
|
|
194
|
+
CLI, MCP server, skills MIT (use anywhere, no restrictions)
|
|
195
|
+
Hosted or cloud service use AGPL (network service distribution)
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
AGPL for personal use is free.
|
|
199
|
+
|
|
200
|
+
Built by Parker Todd Brooks, Lēsa (OpenClaw, Claude Opus 4.6), Claude Code (Claude Opus 4.6).
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: wip-license-hook
|
|
3
|
+
description: License rug-pull detection. Scans dependencies and forks for license changes, gates upstream merges, maintains a license ledger, and generates a public compliance dashboard.
|
|
4
|
+
license: MIT
|
|
5
|
+
interface: [cli, module, mcp]
|
|
6
|
+
metadata:
|
|
7
|
+
display-name: "License Rug-Pull Detection"
|
|
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
|
+
- license-scanning
|
|
14
|
+
- rug-pull-detection
|
|
15
|
+
- compliance-gating
|
|
16
|
+
- license-ledger
|
|
17
|
+
requires:
|
|
18
|
+
bins: [node, git, npm]
|
|
19
|
+
openclaw:
|
|
20
|
+
requires:
|
|
21
|
+
bins: [node, git, npm]
|
|
22
|
+
install:
|
|
23
|
+
- id: node
|
|
24
|
+
kind: node
|
|
25
|
+
package: "@wipcomputer/wip-license-hook"
|
|
26
|
+
bins: [wip-license-hook]
|
|
27
|
+
label: "Install via npm"
|
|
28
|
+
emoji: "🛡️"
|
|
29
|
+
compatibility: Requires git, npm, node. Node.js 18+.
|
|
30
|
+
---
|
|
31
|
+
|
|
32
|
+
# wip-license-hook
|
|
33
|
+
|
|
34
|
+
Detect license rug-pulls before they reach your codebase.
|
|
35
|
+
|
|
36
|
+
## Commands
|
|
37
|
+
|
|
38
|
+
### Initialize ledger for a project
|
|
39
|
+
```bash
|
|
40
|
+
wip-license-hook init --repo /path/to/repo
|
|
41
|
+
```
|
|
42
|
+
Scans all current dependencies and forks, records their licenses, creates `LICENSE-LEDGER.json`.
|
|
43
|
+
|
|
44
|
+
### Scan all dependencies
|
|
45
|
+
```bash
|
|
46
|
+
wip-license-hook scan --all
|
|
47
|
+
```
|
|
48
|
+
Checks every dependency and fork against the ledger. Updates `last_checked`. Flags any changes.
|
|
49
|
+
|
|
50
|
+
### Pre-merge gate
|
|
51
|
+
```bash
|
|
52
|
+
wip-license-hook gate --upstream <remote>
|
|
53
|
+
```
|
|
54
|
+
Fetches upstream without merging. Checks license. Returns exit code 0 (safe) or 1 (changed/blocked).
|
|
55
|
+
|
|
56
|
+
Use in git hooks or CI.
|
|
57
|
+
|
|
58
|
+
### Generate report
|
|
59
|
+
```bash
|
|
60
|
+
wip-license-hook report
|
|
61
|
+
```
|
|
62
|
+
Outputs a human-readable license health report.
|
|
63
|
+
|
|
64
|
+
### Generate dashboard
|
|
65
|
+
```bash
|
|
66
|
+
wip-license-hook dashboard --output ./docs
|
|
67
|
+
```
|
|
68
|
+
Creates a static HTML dashboard from the ledger. Deploy to GitHub Pages.
|
|
69
|
+
|
|
70
|
+
## Daily Cron Usage
|
|
71
|
+
|
|
72
|
+
Add to HEARTBEAT.md or as a cron job:
|
|
73
|
+
```
|
|
74
|
+
wip-license-hook scan --all --alert
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
If any license changed, sends alert via configured channel (email, iMessage, Discord).
|
|
78
|
+
|
|
79
|
+
## What It Detects
|
|
80
|
+
|
|
81
|
+
- LICENSE file content changes
|
|
82
|
+
- package.json license field changes
|
|
83
|
+
- SPDX header changes
|
|
84
|
+
- License removal (file deleted)
|
|
85
|
+
- License downgrade (permissive → restrictive)
|
|
86
|
+
|
|
87
|
+
## What It Does NOT Do
|
|
88
|
+
|
|
89
|
+
- It does not legal advice make
|
|
90
|
+
- It does not auto-merge anything ever
|
|
91
|
+
- It does not modify upstream code
|
|
92
|
+
|
|
93
|
+
## Alert Levels
|
|
94
|
+
|
|
95
|
+
- 🟢 **Clean** — license unchanged since adoption
|
|
96
|
+
- 🟡 **Warning** — license metadata inconsistency (e.g., LICENSE file says MIT but package.json says ISC)
|
|
97
|
+
- 🔴 **Blocked** — license changed from what was adopted. Merge blocked. Human review required.
|
|
98
|
+
|
|
99
|
+
## MCP
|
|
100
|
+
|
|
101
|
+
Tools: `license_scan`, `license_audit`, `license_gate`, `license_ledger`
|
|
102
|
+
|
|
103
|
+
Add to `.mcp.json`:
|
|
104
|
+
```json
|
|
105
|
+
{
|
|
106
|
+
"wip-license-hook": {
|
|
107
|
+
"command": "node",
|
|
108
|
+
"args": ["/path/to/tools/wip-license-hook/mcp-server.mjs"]
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
```
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* wip-license-hook CLI
|
|
4
|
+
*
|
|
5
|
+
* Commands:
|
|
6
|
+
* init Initialize ledger for current project
|
|
7
|
+
* scan Scan all deps, update ledger
|
|
8
|
+
* check <dep> Check specific dependency
|
|
9
|
+
* gate Pre-merge license gate (for hooks)
|
|
10
|
+
* report Print ledger report
|
|
11
|
+
* dashboard Generate static dashboard HTML
|
|
12
|
+
* alert Print current alerts
|
|
13
|
+
* install Install git hooks in current repo
|
|
14
|
+
*/
|
|
15
|
+
export {};
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* wip-license-hook CLI
|
|
4
|
+
*
|
|
5
|
+
* Commands:
|
|
6
|
+
* init Initialize ledger for current project
|
|
7
|
+
* scan Scan all deps, update ledger
|
|
8
|
+
* check <dep> Check specific dependency
|
|
9
|
+
* gate Pre-merge license gate (for hooks)
|
|
10
|
+
* report Print ledger report
|
|
11
|
+
* dashboard Generate static dashboard HTML
|
|
12
|
+
* alert Print current alerts
|
|
13
|
+
* install Install git hooks in current repo
|
|
14
|
+
*/
|
|
15
|
+
import { resolve } from "node:path";
|
|
16
|
+
import { existsSync, mkdirSync, copyFileSync } from "node:fs";
|
|
17
|
+
import { readLedger, writeLedger, createEmptyLedger, findEntry, scanAndUpdate, gateCheck, formatScanReport, formatGateOutput, formatLedgerReport, writeDashboard, generateBadgeUrl, } from "../core/index.js";
|
|
18
|
+
const args = process.argv.slice(2);
|
|
19
|
+
const command = args[0];
|
|
20
|
+
const flags = new Set(args.filter((a) => a.startsWith("--")));
|
|
21
|
+
const positional = args.filter((a) => !a.startsWith("--")).slice(1);
|
|
22
|
+
const repoRoot = resolve(process.cwd());
|
|
23
|
+
const offline = flags.has("--offline");
|
|
24
|
+
const verbose = flags.has("--verbose");
|
|
25
|
+
function help() {
|
|
26
|
+
console.log(`
|
|
27
|
+
wip-license-hook — License rug-pull detection
|
|
28
|
+
|
|
29
|
+
Usage: wip-license-hook <command> [options]
|
|
30
|
+
|
|
31
|
+
Commands:
|
|
32
|
+
init Initialize LICENSE-LEDGER.json
|
|
33
|
+
scan Scan all dependencies, update ledger
|
|
34
|
+
check <name> Check a specific dependency
|
|
35
|
+
gate Pre-merge license gate (exit 1 if changed)
|
|
36
|
+
report Print ledger status
|
|
37
|
+
dashboard Generate static HTML dashboard
|
|
38
|
+
alert Show current alerts
|
|
39
|
+
install Install git hooks in .git/hooks/
|
|
40
|
+
badge Print shields.io badge URL
|
|
41
|
+
|
|
42
|
+
Options:
|
|
43
|
+
--offline Skip network calls (use cached data only)
|
|
44
|
+
--verbose Verbose output
|
|
45
|
+
--help Show this help
|
|
46
|
+
`);
|
|
47
|
+
}
|
|
48
|
+
async function main() {
|
|
49
|
+
if (!command || command === "--help" || flags.has("--help")) {
|
|
50
|
+
help();
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
switch (command) {
|
|
54
|
+
case "init": {
|
|
55
|
+
const ledgerPath = resolve(repoRoot, "LICENSE-LEDGER.json");
|
|
56
|
+
if (existsSync(ledgerPath)) {
|
|
57
|
+
console.log("⚠️ LICENSE-LEDGER.json already exists. Use 'scan' to update.");
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
60
|
+
writeLedger(repoRoot, createEmptyLedger());
|
|
61
|
+
mkdirSync(resolve(repoRoot, "ledger/snapshots"), { recursive: true });
|
|
62
|
+
console.log("✅ Initialized LICENSE-LEDGER.json and ledger/snapshots/");
|
|
63
|
+
console.log(" Run 'wip-license-hook scan' to populate.");
|
|
64
|
+
break;
|
|
65
|
+
}
|
|
66
|
+
case "scan": {
|
|
67
|
+
console.log(offline ? "📡 Scanning (offline mode)..." : "📡 Scanning dependencies...");
|
|
68
|
+
const results = scanAndUpdate({ repoRoot, offline, verbose });
|
|
69
|
+
console.log(formatScanReport(results));
|
|
70
|
+
break;
|
|
71
|
+
}
|
|
72
|
+
case "check": {
|
|
73
|
+
const name = positional[0];
|
|
74
|
+
if (!name) {
|
|
75
|
+
console.error("Usage: wip-license-hook check <dependency-name>");
|
|
76
|
+
process.exit(1);
|
|
77
|
+
}
|
|
78
|
+
const ledger = readLedger(repoRoot);
|
|
79
|
+
const entry = findEntry(ledger, name);
|
|
80
|
+
if (!entry) {
|
|
81
|
+
console.log(`❓ ${name} not found in ledger. Run 'scan' first.`);
|
|
82
|
+
process.exit(1);
|
|
83
|
+
}
|
|
84
|
+
console.log(`\n ${entry.status === "clean" ? "✅" : "🚫"} ${entry.name}`);
|
|
85
|
+
console.log(` Type: ${entry.type}`);
|
|
86
|
+
console.log(` Source: ${entry.source}`);
|
|
87
|
+
console.log(` Adopted: ${entry.license_at_adoption} on ${entry.adopted_date}`);
|
|
88
|
+
console.log(` Current: ${entry.license_current} (checked ${entry.last_checked})`);
|
|
89
|
+
console.log(` Status: ${entry.status}\n`);
|
|
90
|
+
break;
|
|
91
|
+
}
|
|
92
|
+
case "gate": {
|
|
93
|
+
if (offline) {
|
|
94
|
+
console.log("⚠️ Offline mode — skipping license gate (cannot verify upstream).");
|
|
95
|
+
console.log(" Your push will proceed, but licenses were NOT checked.");
|
|
96
|
+
process.exit(0);
|
|
97
|
+
}
|
|
98
|
+
const { safe, alerts } = gateCheck(repoRoot, offline);
|
|
99
|
+
console.log(formatGateOutput(safe, alerts));
|
|
100
|
+
if (!safe)
|
|
101
|
+
process.exit(1);
|
|
102
|
+
break;
|
|
103
|
+
}
|
|
104
|
+
case "report": {
|
|
105
|
+
const ledger = readLedger(repoRoot);
|
|
106
|
+
console.log(formatLedgerReport(ledger));
|
|
107
|
+
break;
|
|
108
|
+
}
|
|
109
|
+
case "dashboard": {
|
|
110
|
+
const outPath = writeDashboard(repoRoot);
|
|
111
|
+
console.log(`✅ Dashboard written to ${outPath}`);
|
|
112
|
+
break;
|
|
113
|
+
}
|
|
114
|
+
case "alert": {
|
|
115
|
+
const ledger = readLedger(repoRoot);
|
|
116
|
+
if (ledger.alerts.length === 0) {
|
|
117
|
+
console.log("✅ No active alerts.");
|
|
118
|
+
}
|
|
119
|
+
else {
|
|
120
|
+
console.log(`\n⚠️ ${ledger.alerts.length} alert(s):\n`);
|
|
121
|
+
for (const a of ledger.alerts) {
|
|
122
|
+
console.log(` ${a.message}`);
|
|
123
|
+
console.log(` Detected: ${a.detected}\n`);
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
break;
|
|
127
|
+
}
|
|
128
|
+
case "install": {
|
|
129
|
+
const hooksDir = resolve(repoRoot, ".git/hooks");
|
|
130
|
+
if (!existsSync(resolve(repoRoot, ".git"))) {
|
|
131
|
+
console.error("❌ Not a git repository. Run from a git repo root.");
|
|
132
|
+
process.exit(1);
|
|
133
|
+
}
|
|
134
|
+
mkdirSync(hooksDir, { recursive: true });
|
|
135
|
+
// Find hooks relative to the package
|
|
136
|
+
const pkgRoot = resolve(new URL(".", import.meta.url).pathname, "../../..");
|
|
137
|
+
const prePullSrc = resolve(pkgRoot, "hooks/pre-pull.sh");
|
|
138
|
+
const preCommitSrc = resolve(pkgRoot, "hooks/pre-push.sh");
|
|
139
|
+
for (const [src, dest] of [
|
|
140
|
+
[prePullSrc, resolve(hooksDir, "pre-merge-commit")],
|
|
141
|
+
[preCommitSrc, resolve(hooksDir, "pre-push")],
|
|
142
|
+
]) {
|
|
143
|
+
if (existsSync(src)) {
|
|
144
|
+
copyFileSync(src, dest);
|
|
145
|
+
const { chmodSync } = await import("node:fs");
|
|
146
|
+
chmodSync(dest, 0o755);
|
|
147
|
+
console.log(`✅ Installed ${dest}`);
|
|
148
|
+
}
|
|
149
|
+
else {
|
|
150
|
+
console.log(`⚠️ Hook source not found: ${src}`);
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
break;
|
|
154
|
+
}
|
|
155
|
+
case "badge": {
|
|
156
|
+
const ledger = readLedger(repoRoot);
|
|
157
|
+
console.log(generateBadgeUrl(ledger));
|
|
158
|
+
break;
|
|
159
|
+
}
|
|
160
|
+
default:
|
|
161
|
+
console.error(`Unknown command: ${command}`);
|
|
162
|
+
help();
|
|
163
|
+
process.exit(1);
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
main().catch((err) => {
|
|
167
|
+
console.error("Fatal error:", err.message);
|
|
168
|
+
process.exit(1);
|
|
169
|
+
});
|
|
170
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* License text fingerprinting — identifies license type from file content.
|
|
3
|
+
*/
|
|
4
|
+
export type LicenseId = "MIT" | "Apache-2.0" | "BSD-2-Clause" | "BSD-3-Clause" | "GPL-2.0" | "GPL-3.0" | "LGPL-2.1" | "LGPL-3.0" | "MPL-2.0" | "ISC" | "BSL-1.1" | "SSPL-1.0" | "Unlicense" | "AGPL-3.0" | "UNKNOWN";
|
|
5
|
+
/**
|
|
6
|
+
* Detect license type from raw license file text.
|
|
7
|
+
*/
|
|
8
|
+
export declare function detectLicenseFromText(text: string): LicenseId;
|
|
9
|
+
/**
|
|
10
|
+
* Normalize a license SPDX identifier from package metadata.
|
|
11
|
+
*/
|
|
12
|
+
export declare function normalizeSpdx(raw: string): LicenseId;
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* License text fingerprinting — identifies license type from file content.
|
|
3
|
+
*/
|
|
4
|
+
const FINGERPRINTS = [
|
|
5
|
+
{
|
|
6
|
+
id: "MIT",
|
|
7
|
+
markers: ["permission is hereby granted, free of charge", "the software is provided \"as is\""],
|
|
8
|
+
antiMarkers: ["apache", "gnu general public"],
|
|
9
|
+
},
|
|
10
|
+
{
|
|
11
|
+
id: "Apache-2.0",
|
|
12
|
+
markers: ["apache license", "version 2.0"],
|
|
13
|
+
},
|
|
14
|
+
{
|
|
15
|
+
id: "GPL-3.0",
|
|
16
|
+
markers: ["gnu general public license", "version 3"],
|
|
17
|
+
antiMarkers: ["lesser general public"],
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
id: "GPL-2.0",
|
|
21
|
+
markers: ["gnu general public license", "version 2"],
|
|
22
|
+
antiMarkers: ["lesser general public", "version 3"],
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
id: "LGPL-3.0",
|
|
26
|
+
markers: ["gnu lesser general public license", "version 3"],
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
id: "LGPL-2.1",
|
|
30
|
+
markers: ["gnu lesser general public license", "version 2.1"],
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
id: "AGPL-3.0",
|
|
34
|
+
markers: ["gnu affero general public license", "version 3"],
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
id: "BSD-3-Clause",
|
|
38
|
+
markers: ["redistribution and use in source and binary forms", "neither the name"],
|
|
39
|
+
},
|
|
40
|
+
{
|
|
41
|
+
id: "BSD-2-Clause",
|
|
42
|
+
markers: ["redistribution and use in source and binary forms"],
|
|
43
|
+
antiMarkers: ["neither the name"],
|
|
44
|
+
},
|
|
45
|
+
{
|
|
46
|
+
id: "MPL-2.0",
|
|
47
|
+
markers: ["mozilla public license", "version 2.0"],
|
|
48
|
+
},
|
|
49
|
+
{
|
|
50
|
+
id: "ISC",
|
|
51
|
+
markers: ["isc license", "permission to use, copy, modify"],
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
id: "BSL-1.1",
|
|
55
|
+
markers: ["business source license", "1.1"],
|
|
56
|
+
},
|
|
57
|
+
{
|
|
58
|
+
id: "SSPL-1.0",
|
|
59
|
+
markers: ["server side public license"],
|
|
60
|
+
},
|
|
61
|
+
{
|
|
62
|
+
id: "Unlicense",
|
|
63
|
+
markers: ["this is free and unencumbered software released into the public domain"],
|
|
64
|
+
},
|
|
65
|
+
];
|
|
66
|
+
/**
|
|
67
|
+
* Detect license type from raw license file text.
|
|
68
|
+
*/
|
|
69
|
+
export function detectLicenseFromText(text) {
|
|
70
|
+
const lower = text.toLowerCase();
|
|
71
|
+
for (const fp of FINGERPRINTS) {
|
|
72
|
+
const allMatch = fp.markers.every((m) => lower.includes(m));
|
|
73
|
+
const anyAnti = fp.antiMarkers?.some((m) => lower.includes(m)) ?? false;
|
|
74
|
+
if (allMatch && !anyAnti)
|
|
75
|
+
return fp.id;
|
|
76
|
+
}
|
|
77
|
+
return "UNKNOWN";
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Normalize a license SPDX identifier from package metadata.
|
|
81
|
+
*/
|
|
82
|
+
export function normalizeSpdx(raw) {
|
|
83
|
+
const map = {
|
|
84
|
+
mit: "MIT",
|
|
85
|
+
"apache-2.0": "Apache-2.0",
|
|
86
|
+
apache2: "Apache-2.0",
|
|
87
|
+
"bsd-2-clause": "BSD-2-Clause",
|
|
88
|
+
"bsd-3-clause": "BSD-3-Clause",
|
|
89
|
+
"gpl-2.0": "GPL-2.0",
|
|
90
|
+
"gpl-3.0": "GPL-3.0",
|
|
91
|
+
"gpl-3.0-only": "GPL-3.0",
|
|
92
|
+
"lgpl-2.1": "LGPL-2.1",
|
|
93
|
+
"lgpl-3.0": "LGPL-3.0",
|
|
94
|
+
"mpl-2.0": "MPL-2.0",
|
|
95
|
+
isc: "ISC",
|
|
96
|
+
"bsl-1.1": "BSL-1.1",
|
|
97
|
+
"sspl-1.0": "SSPL-1.0",
|
|
98
|
+
unlicense: "Unlicense",
|
|
99
|
+
"agpl-3.0": "AGPL-3.0",
|
|
100
|
+
"agpl-3.0-only": "AGPL-3.0",
|
|
101
|
+
};
|
|
102
|
+
return map[raw.toLowerCase().trim()] ?? "UNKNOWN";
|
|
103
|
+
}
|
|
104
|
+
//# sourceMappingURL=detector.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"detector.js","sourceRoot":"","sources":["../../src/core/detector.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export { detectLicenseFromText, normalizeSpdx, type LicenseId } from "./detector.js";
|
|
2
|
+
export { readLedger, writeLedger, createEmptyLedger, findEntry, upsertEntry, archiveSnapshot, hasLicenseChanged, addAlert, type Ledger, type LedgerEntry, type Alert, type DependencyType, type DependencyStatus } from "./ledger.js";
|
|
3
|
+
export { scanAll, scanAndUpdate, gateCheck, findLicenseFile, readLicenseFromDir, type ScanResult } from "./scanner.js";
|
|
4
|
+
export { formatScanReport, formatGateOutput, formatLedgerReport, generateDashboardHtml, generateBadgeUrl, writeDashboard } from "./reporter.js";
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export { detectLicenseFromText, normalizeSpdx } from "./detector.js";
|
|
2
|
+
export { readLedger, writeLedger, createEmptyLedger, findEntry, upsertEntry, archiveSnapshot, hasLicenseChanged, addAlert } from "./ledger.js";
|
|
3
|
+
export { scanAll, scanAndUpdate, gateCheck, findLicenseFile, readLicenseFromDir } from "./scanner.js";
|
|
4
|
+
export { formatScanReport, formatGateOutput, formatLedgerReport, generateDashboardHtml, generateBadgeUrl, writeDashboard } from "./reporter.js";
|
|
5
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/core/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,qBAAqB,EAAE,aAAa,EAAkB,MAAM,eAAe,CAAC;AACrF,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,iBAAiB,EAAE,SAAS,EAAE,WAAW,EAAE,eAAe,EAAE,iBAAiB,EAAE,QAAQ,EAAyF,MAAM,aAAa,CAAC;AACtO,OAAO,EAAE,OAAO,EAAE,aAAa,EAAE,SAAS,EAAE,eAAe,EAAE,kBAAkB,EAAmB,MAAM,cAAc,CAAC;AACvH,OAAO,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,qBAAqB,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC"}
|