uncompact 0.44.0

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/README.md ADDED
@@ -0,0 +1,284 @@
1
+ # Uncompact
2
+
3
+ [![context bomb](https://raw.githubusercontent.com/supermodeltools/Uncompact/main/assets/badge.svg)](https://github.com/supermodeltools/Uncompact)
4
+
5
+ > Stop Claude Code compaction from making your AI stupid.
6
+
7
+ Uncompact hooks into Claude Code's lifecycle to reinject a high-density "context bomb" after compaction. It's powered by the [Supermodel Public API](https://supermodeltools.com) and stores versioned project graphs locally in SQLite.
8
+
9
+ ---
10
+
11
+ ## ⭐ Star the Supermodel Ecosystem
12
+
13
+ If this is useful, please star our tools — it helps us grow:
14
+
15
+ [![mcp](https://img.shields.io/github/stars/supermodeltools/mcp?style=social)](https://github.com/supermodeltools/mcp)  [![mcpbr](https://img.shields.io/github/stars/supermodeltools/mcpbr?style=social)](https://github.com/supermodeltools/mcpbr)  [![typescript-sdk](https://img.shields.io/github/stars/supermodeltools/typescript-sdk?style=social)](https://github.com/supermodeltools/typescript-sdk)  [![arch-docs](https://img.shields.io/github/stars/supermodeltools/arch-docs?style=social)](https://github.com/supermodeltools/arch-docs)  [![dead-code-hunter](https://img.shields.io/github/stars/supermodeltools/dead-code-hunter?style=social)](https://github.com/supermodeltools/dead-code-hunter)  [![Uncompact](https://img.shields.io/github/stars/supermodeltools/Uncompact?style=social)](https://github.com/supermodeltools/Uncompact)  [![narsil-mcp](https://img.shields.io/github/stars/supermodeltools/narsil-mcp?style=social)](https://github.com/supermodeltools/narsil-mcp)
16
+
17
+ ---
18
+
19
+ ## How It Works
20
+
21
+ ```text
22
+ Claude Code compaction occurs
23
+
24
+ Stop hook fires → uncompact run
25
+
26
+ Check local SQLite cache (TTL: 15 min)
27
+ ↓ (cache miss or stale)
28
+ Zip repo → POST /v1/graphs/supermodel
29
+
30
+ Poll for result (async job)
31
+
32
+ Render token-budgeted Markdown context bomb
33
+
34
+ Claude Code receives context via stdout
35
+ ```
36
+
37
+ ## Claude Code Plugin
38
+
39
+ The fastest way to integrate Uncompact is via the Claude Code plugin system — no manual hook installation required.
40
+
41
+ ### Install the plugin
42
+
43
+ ```bash
44
+ /plugin marketplace add supermodeltools/Uncompact
45
+ /plugin install uncompact@supermodeltools-Uncompact
46
+ ```
47
+
48
+ This installs both hooks automatically:
49
+
50
+ - **`SessionStart`** — runs `scripts/setup.sh` which auto-installs the `uncompact` binary via `go install` if not already present.
51
+ - **`Stop`** — runs `scripts/uncompact-hook.sh` which reinjects context after every compaction event.
52
+
53
+ > **Note:** After plugin installation, authenticate once with `uncompact auth login` to connect your Supermodel API key. That's it — no manual binary install or hook setup required.
54
+
55
+ ### CI / GitHub Actions
56
+
57
+ In remote environments (`CLAUDE_CODE_REMOTE=true`), the hook automatically enables `--fallback` mode. Pass your API key via the `SUPERMODEL_API_KEY` environment variable:
58
+
59
+ ```yaml
60
+ env:
61
+ SUPERMODEL_API_KEY: ${{ secrets.SUPERMODEL_API_KEY }}
62
+ ```
63
+
64
+ ---
65
+
66
+ ## Quick Start
67
+
68
+ ### 1. Install
69
+
70
+ **Via npm (recommended):**
71
+
72
+ ```bash
73
+ npm install -g uncompact
74
+ ```
75
+
76
+ Or run without installing:
77
+
78
+ ```bash
79
+ npx uncompact --help
80
+ ```
81
+
82
+ **Via Go:**
83
+
84
+ ```bash
85
+ go install github.com/supermodeltools/uncompact@latest
86
+ ```
87
+
88
+ **Or download a binary** from [Releases](https://github.com/supermodeltools/Uncompact/releases).
89
+
90
+ ### 2. Authenticate
91
+
92
+ ```bash
93
+ uncompact auth login
94
+ ```
95
+
96
+ This opens [dashboard.supermodeltools.com](https://dashboard.supermodeltools.com) where you can subscribe and generate an API key.
97
+
98
+ ### 3. Install Claude Code Hooks
99
+
100
+ ```bash
101
+ uncompact install
102
+ ```
103
+
104
+ This auto-detects your Claude Code `settings.json`, shows a diff, and merges the hooks non-destructively.
105
+
106
+ ### 4. Verify
107
+
108
+ ```bash
109
+ uncompact verify-install
110
+ uncompact run --debug
111
+ ```
112
+
113
+ ## CLI Reference
114
+
115
+ ```text
116
+ uncompact auth login # Authenticate via dashboard.supermodeltools.com
117
+ uncompact auth status # Show auth status and API key validity
118
+ uncompact auth logout # Remove stored API key
119
+
120
+ uncompact install # Merge hooks into Claude Code settings.json (with diff preview)
121
+ uncompact install --dry-run # Preview changes without writing
122
+ uncompact verify-install # Check if hooks are correctly installed
123
+
124
+ uncompact run # Emit context bomb to stdout (used by the hook)
125
+ uncompact run --debug # Show debug output on stderr
126
+ uncompact run --force-refresh # Bypass cache and fetch fresh from API
127
+ uncompact run --max-tokens 1500 # Cap context bomb at 1500 tokens
128
+ uncompact run --fallback # Emit minimal static context on failure
129
+
130
+ uncompact dry-run # Preview context bomb without emitting it
131
+ uncompact status # Show last injection, cache state, auth status
132
+ uncompact logs # Show recent injection activity
133
+ uncompact logs --tail 50 # Show last 50 entries
134
+ uncompact stats # Token usage, cache hit rate, API call count
135
+
136
+ uncompact cache clear # Clear all cached graph data
137
+ uncompact cache clear --project # Clear only the current project's cache
138
+ ```
139
+
140
+ ## Configuration
141
+
142
+ ### Environment Variables
143
+
144
+ | Variable | Description |
145
+ |----------|-------------|
146
+ | `SUPERMODEL_API_KEY` | Supermodel API key (overrides config file) |
147
+
148
+ ### Config File
149
+
150
+ Located at `~/.config/uncompact/config.json` (Linux/macOS) or `%APPDATA%\uncompact\config.json` (Windows).
151
+
152
+ ```json
153
+ {
154
+ "api_key": "your-api-key-here",
155
+ "base_url": "https://api.supermodeltools.com",
156
+ "max_tokens": 2000
157
+ }
158
+ ```
159
+
160
+ ### CLI Flags (Global)
161
+
162
+ | Flag | Default | Description |
163
+ |------|---------|-------------|
164
+ | `--api-key` | | Override API key |
165
+ | `--max-tokens` | `2000` | Max tokens in context bomb |
166
+ | `--force-refresh` | `false` | Bypass cache |
167
+ | `--fallback` | `false` | Emit minimal static context on failure |
168
+ | `--debug` | `false` | Debug output to stderr |
169
+
170
+ ## Manual Hook Installation
171
+
172
+ If `uncompact install` doesn't work for your setup, add this to your Claude Code `settings.json`:
173
+
174
+ ```json
175
+ {
176
+ "hooks": {
177
+ "Stop": [
178
+ {
179
+ "hooks": [
180
+ {
181
+ "type": "command",
182
+ "command": "uncompact run"
183
+ }
184
+ ]
185
+ }
186
+ ]
187
+ }
188
+ }
189
+ ```
190
+
191
+ See the [Claude Code hooks guide](https://code.claude.com/docs/en/hooks-guide#re-inject-context-after-compaction) for more details.
192
+
193
+ ## Architecture
194
+
195
+ ```text
196
+ uncompact/
197
+ ├── main.go
198
+ ├── cmd/
199
+ │ ├── root.go # Root command, global flags
200
+ │ ├── run.go # Core hook command
201
+ │ ├── auth.go # auth login/status/logout
202
+ │ ├── install.go # install, verify-install
203
+ │ └── status.go # status, logs, stats, dry-run, cache
204
+ └── internal/
205
+ ├── api/
206
+ │ └── client.go # Supermodel API client (async 200/202 polling)
207
+ ├── cache/
208
+ │ └── store.go # SQLite cache (TTL, staleness, injection log)
209
+ ├── config/
210
+ │ └── config.go # Config loading (flag > env > file)
211
+ ├── hooks/
212
+ │ └── hooks.go # settings.json installer (non-destructive)
213
+ ├── project/
214
+ │ └── project.go # Git-aware project detection
215
+ ├── template/
216
+ │ └── render.go # Token-budgeted Markdown renderer
217
+ └── zip/
218
+ └── zip.go # Repo zipper (excludes .git, node_modules, etc.)
219
+ ```
220
+
221
+ ### Caching Strategy
222
+
223
+ | Concern | Policy |
224
+ |---------|--------|
225
+ | Default TTL | 15 minutes |
226
+ | Stale cache | Served with `⚠️ STALE` warning; fresh fetch attempted |
227
+ | API unavailable | Serve most recent cache entry silently |
228
+ | No cache + API down | Silent exit 0 (never blocks Claude Code) |
229
+ | Storage growth | Auto-prune entries older than 30 days |
230
+ | Force refresh | `--force-refresh` flag |
231
+
232
+ ### Context Bomb Design
233
+
234
+ The context bomb is capped at `--max-tokens` (default: 2,000) to avoid triggering the very compaction it's trying to prevent. Sections are rendered in priority order:
235
+
236
+ 1. **Required** (always included): Project overview, language, stats
237
+ 2. **Optional** (filled to token budget): Domain map, key files, dependencies
238
+
239
+ ### Fallback Chain
240
+
241
+ ```text
242
+ 1. Fresh cache hit → serve immediately
243
+ 2. Cache miss / stale → fetch from API → cache result
244
+ 3. API fails + stale cache exists → serve stale with warning
245
+ 4. API fails + no cache → silent exit 0 (or minimal static if --fallback)
246
+ ```
247
+
248
+ ## KPIs
249
+
250
+ | Metric | Target |
251
+ |--------|--------|
252
+ | Clarifying questions per session (proxy for context loss) | ↓ after Uncompact |
253
+ | Post-compaction task completion rate | ↑ after Uncompact |
254
+ | Token efficiency (useful tokens / injected tokens) | > 80% |
255
+ | 7-day retention | % of users who keep hooks enabled |
256
+
257
+ ## Building from Source
258
+
259
+ ```bash
260
+ git clone https://github.com/supermodeltools/Uncompact
261
+ cd Uncompact
262
+ go mod tidy
263
+ go build -o uncompact .
264
+ ```
265
+
266
+ Requires Go 1.22+.
267
+
268
+ ## Add to your project
269
+
270
+ Show that your project uses Uncompact by adding this badge to your README:
271
+
272
+ ```markdown
273
+ [![context bomb](https://raw.githubusercontent.com/supermodeltools/Uncompact/main/assets/badge.svg)](https://github.com/supermodeltools/Uncompact)
274
+ ```
275
+
276
+ Or with Shields.io:
277
+
278
+ ```markdown
279
+ [![context bomb](https://img.shields.io/badge/context--bomb-Uncompact-5b21b6)](https://github.com/supermodeltools/Uncompact)
280
+ ```
281
+
282
+ ## License
283
+
284
+ MIT
@@ -0,0 +1,80 @@
1
+ {
2
+ "hooks": {
3
+ "SessionStart": [
4
+ {
5
+ "matcher": "startup",
6
+ "hooks": [
7
+ {
8
+ "type": "command",
9
+ "command": "bash ${CLAUDE_PLUGIN_ROOT}/scripts/setup.sh",
10
+ "timeout": 60
11
+ },
12
+ {
13
+ "type": "command",
14
+ "command": "bash ${CLAUDE_PLUGIN_ROOT}/scripts/pregen-hook.sh",
15
+ "timeout": 10
16
+ }
17
+ ]
18
+ },
19
+ {
20
+ "matcher": "clear",
21
+ "hooks": [
22
+ {
23
+ "type": "command",
24
+ "command": "bash ${CLAUDE_PLUGIN_ROOT}/scripts/setup.sh",
25
+ "timeout": 60
26
+ },
27
+ {
28
+ "type": "command",
29
+ "command": "bash ${CLAUDE_PLUGIN_ROOT}/scripts/pregen-hook.sh",
30
+ "timeout": 10
31
+ }
32
+ ]
33
+ },
34
+ {
35
+ "matcher": "compact",
36
+ "hooks": [
37
+ {
38
+ "type": "command",
39
+ "command": "bash ${CLAUDE_PLUGIN_ROOT}/scripts/uncompact-hook.sh",
40
+ "timeout": 120
41
+ }
42
+ ]
43
+ }
44
+ ],
45
+ "PreCompact": [
46
+ {
47
+ "hooks": [
48
+ {
49
+ "type": "command",
50
+ "command": "bash ${CLAUDE_PLUGIN_ROOT}/scripts/pregen-hook.sh",
51
+ "timeout": 10
52
+ }
53
+ ]
54
+ }
55
+ ],
56
+ "PostToolUse": [
57
+ {
58
+ "matcher": "Write|Edit",
59
+ "hooks": [
60
+ {
61
+ "type": "command",
62
+ "command": "bash ${CLAUDE_PLUGIN_ROOT}/scripts/pregen-hook.sh",
63
+ "timeout": 10
64
+ }
65
+ ]
66
+ }
67
+ ],
68
+ "UserPromptSubmit": [
69
+ {
70
+ "hooks": [
71
+ {
72
+ "type": "command",
73
+ "command": "bash ${CLAUDE_PLUGIN_ROOT}/scripts/show-hook.sh",
74
+ "timeout": 5
75
+ }
76
+ ]
77
+ }
78
+ ]
79
+ }
80
+ }
package/npm/install.js ADDED
@@ -0,0 +1,183 @@
1
+ #!/usr/bin/env node
2
+
3
+ const https = require("https");
4
+ const fs = require("fs");
5
+ const path = require("path");
6
+ const { execSync, execFileSync } = require("child_process");
7
+ const os = require("os");
8
+
9
+ const REPO_OWNER = "supermodeltools";
10
+ const REPO_NAME = "Uncompact";
11
+ const BINARY_NAME = "uncompact";
12
+
13
+ function getPackageVersion() {
14
+ const pkgPath = path.join(__dirname, "..", "package.json");
15
+ const pkg = JSON.parse(fs.readFileSync(pkgPath, "utf8"));
16
+ return pkg.version;
17
+ }
18
+
19
+ function getPlatform() {
20
+ const platform = os.platform();
21
+ if (platform === "darwin") return "darwin";
22
+ if (platform === "linux") return "linux";
23
+ if (platform === "win32") return "windows";
24
+ throw new Error(`Unsupported platform: ${platform}`);
25
+ }
26
+
27
+ function getArch() {
28
+ const arch = os.arch();
29
+ if (arch === "x64") return "amd64";
30
+ if (arch === "arm64") return "arm64";
31
+ throw new Error(`Unsupported architecture: ${arch}`);
32
+ }
33
+
34
+ function getBinaryName(platform) {
35
+ return platform === "windows" ? `${BINARY_NAME}.exe` : BINARY_NAME;
36
+ }
37
+
38
+ function getAssetName(platform, arch) {
39
+ const ext = platform === "windows" ? ".zip" : ".tar.gz";
40
+ return `${BINARY_NAME}_${platform}_${arch}${ext}`;
41
+ }
42
+
43
+ function httpsGet(url) {
44
+ return new Promise((resolve, reject) => {
45
+ const request = https.get(url, { headers: { "User-Agent": "uncompact-npm" } }, (response) => {
46
+ if (response.statusCode >= 300 && response.statusCode < 400 && response.headers.location) {
47
+ httpsGet(response.headers.location).then(resolve).catch(reject);
48
+ return;
49
+ }
50
+ if (response.statusCode !== 200) {
51
+ reject(new Error(`HTTP ${response.statusCode}: ${url}`));
52
+ return;
53
+ }
54
+ const chunks = [];
55
+ response.on("data", (chunk) => chunks.push(chunk));
56
+ response.on("end", () => resolve(Buffer.concat(chunks)));
57
+ response.on("error", reject);
58
+ });
59
+ request.setTimeout(20000, () => {
60
+ request.destroy();
61
+ reject(new Error(`Request timed out: ${url}`));
62
+ });
63
+ request.on("error", reject);
64
+ });
65
+ }
66
+
67
+ function httpsGetJson(url) {
68
+ return httpsGet(url).then((buffer) => JSON.parse(buffer.toString()));
69
+ }
70
+
71
+ async function getRelease(version) {
72
+ if (version && version !== "0.0.0") {
73
+ const tag = version.startsWith("v") ? version : `v${version}`;
74
+ const url = `https://api.github.com/repos/${REPO_OWNER}/${REPO_NAME}/releases/tags/${tag}`;
75
+ return await httpsGetJson(url);
76
+ }
77
+ const url = `https://api.github.com/repos/${REPO_OWNER}/${REPO_NAME}/releases/latest`;
78
+ return httpsGetJson(url);
79
+ }
80
+
81
+ function extractTarGz(buffer, destDir, binaryName) {
82
+ const tarPath = path.join(destDir, "archive.tar.gz");
83
+ fs.writeFileSync(tarPath, buffer);
84
+ execFileSync("tar", ["-xzf", tarPath, "-C", destDir], { stdio: "pipe" });
85
+ fs.unlinkSync(tarPath);
86
+
87
+ const extracted = path.join(destDir, binaryName);
88
+ if (!fs.existsSync(extracted)) {
89
+ throw new Error(`Binary not found after extraction: ${extracted}`);
90
+ }
91
+ return extracted;
92
+ }
93
+
94
+ function extractZip(buffer, destDir, binaryName) {
95
+ const zipPath = path.join(destDir, "archive.zip");
96
+ fs.writeFileSync(zipPath, buffer);
97
+
98
+ if (process.platform === "win32") {
99
+ execFileSync("powershell", ["-Command", `Expand-Archive -Path '${zipPath}' -DestinationPath '${destDir}' -Force`], { stdio: "pipe" });
100
+ } else {
101
+ execFileSync("unzip", ["-o", zipPath, "-d", destDir], { stdio: "pipe" });
102
+ }
103
+ fs.unlinkSync(zipPath);
104
+
105
+ const extracted = path.join(destDir, binaryName);
106
+ if (!fs.existsSync(extracted)) {
107
+ throw new Error(`Binary not found after extraction: ${extracted}`);
108
+ }
109
+ return extracted;
110
+ }
111
+
112
+ async function main() {
113
+ const platform = getPlatform();
114
+ const arch = getArch();
115
+ const assetName = getAssetName(platform, arch);
116
+ const binaryName = getBinaryName(platform);
117
+ const binDir = path.join(__dirname, "bin");
118
+
119
+ console.log(`[uncompact] Installing ${BINARY_NAME} for ${platform}/${arch}...`);
120
+
121
+ if (!fs.existsSync(binDir)) {
122
+ fs.mkdirSync(binDir, { recursive: true });
123
+ }
124
+
125
+ const destPath = path.join(binDir, binaryName);
126
+
127
+ if (fs.existsSync(destPath)) {
128
+ console.log(`[uncompact] Binary already exists at ${destPath}`);
129
+ return;
130
+ }
131
+
132
+ const version = getPackageVersion();
133
+ let release;
134
+ try {
135
+ release = await getRelease(version);
136
+ } catch (err) {
137
+ console.error(`[uncompact] Failed to fetch release: ${err.message}`);
138
+ console.error(`[uncompact] You can install manually: go install github.com/${REPO_OWNER}/${REPO_NAME.toLowerCase()}@latest`);
139
+ process.exit(0);
140
+ }
141
+
142
+ const asset = release.assets.find((a) => a.name === assetName);
143
+ if (!asset) {
144
+ console.error(`[uncompact] No binary found for ${platform}/${arch} in release ${release.tag_name}`);
145
+ console.error(`[uncompact] Available assets: ${release.assets.map((a) => a.name).join(", ")}`);
146
+ console.error(`[uncompact] You can install manually: go install github.com/${REPO_OWNER}/${REPO_NAME.toLowerCase()}@latest`);
147
+ process.exit(0);
148
+ }
149
+
150
+ console.log(`[uncompact] Downloading ${asset.name}...`);
151
+
152
+ let buffer;
153
+ try {
154
+ buffer = await httpsGet(asset.browser_download_url);
155
+ } catch (err) {
156
+ console.error(`[uncompact] Failed to download: ${err.message}`);
157
+ process.exit(0);
158
+ }
159
+
160
+ console.log(`[uncompact] Extracting...`);
161
+
162
+ try {
163
+ if (platform === "windows") {
164
+ extractZip(buffer, binDir, binaryName);
165
+ } else {
166
+ extractTarGz(buffer, binDir, binaryName);
167
+ }
168
+ } catch (err) {
169
+ console.error(`[uncompact] Failed to extract: ${err.message}`);
170
+ process.exit(0);
171
+ }
172
+
173
+ if (platform !== "windows") {
174
+ fs.chmodSync(destPath, 0o755);
175
+ }
176
+
177
+ console.log(`[uncompact] Installed to ${destPath}`);
178
+ }
179
+
180
+ main().catch((err) => {
181
+ console.error(`[uncompact] Installation failed: ${err.message}`);
182
+ process.exit(0);
183
+ });
package/npm/run.js ADDED
@@ -0,0 +1,63 @@
1
+ #!/usr/bin/env node
2
+
3
+ const { spawn } = require("child_process");
4
+ const path = require("path");
5
+ const fs = require("fs");
6
+ const os = require("os");
7
+
8
+ const BINARY_NAME = os.platform() === "win32" ? "uncompact.exe" : "uncompact";
9
+
10
+ function findBinary() {
11
+ const localBin = path.join(__dirname, "bin", BINARY_NAME);
12
+ if (fs.existsSync(localBin)) {
13
+ return localBin;
14
+ }
15
+
16
+ const globalPaths = [
17
+ path.join(os.homedir(), "go", "bin", BINARY_NAME),
18
+ path.join(os.homedir(), ".local", "bin", BINARY_NAME),
19
+ "/usr/local/bin/" + BINARY_NAME,
20
+ "/opt/homebrew/bin/" + BINARY_NAME,
21
+ ];
22
+
23
+ for (const p of globalPaths) {
24
+ if (fs.existsSync(p)) {
25
+ return p;
26
+ }
27
+ }
28
+
29
+ return null;
30
+ }
31
+
32
+ function main() {
33
+ const binary = findBinary();
34
+
35
+ if (!binary) {
36
+ console.error("[uncompact] Binary not found. Try reinstalling:");
37
+ console.error(" npm install -g uncompact");
38
+ console.error("Or install via Go:");
39
+ console.error(" go install github.com/supermodeltools/uncompact@latest");
40
+ process.exit(1);
41
+ }
42
+
43
+ const args = process.argv.slice(2);
44
+ const child = spawn(binary, args, {
45
+ stdio: "inherit",
46
+ env: process.env,
47
+ });
48
+
49
+ child.on("error", (err) => {
50
+ console.error(`[uncompact] Failed to run binary: ${err.message}`);
51
+ process.exit(1);
52
+ });
53
+
54
+ child.on("close", (code, signal) => {
55
+ if (code === null && signal) {
56
+ process.kill(process.pid, signal);
57
+ } else {
58
+ process.exit(code ?? 0);
59
+ }
60
+ });
61
+ }
62
+
63
+ main();
package/package.json ADDED
@@ -0,0 +1,37 @@
1
+ {
2
+ "name": "uncompact",
3
+ "version": "0.44.0",
4
+ "description": "Stop Claude Code compaction from making your AI stupid. Re-inject project context after compaction via the Supermodel API.",
5
+ "author": "Supermodel <abe@supermodel.software>",
6
+ "license": "MIT",
7
+ "homepage": "https://github.com/supermodeltools/Uncompact",
8
+ "repository": {
9
+ "type": "git",
10
+ "url": "git+https://github.com/supermodeltools/Uncompact.git"
11
+ },
12
+ "bugs": {
13
+ "url": "https://github.com/supermodeltools/Uncompact/issues"
14
+ },
15
+ "keywords": [
16
+ "claude",
17
+ "claude-code",
18
+ "cli",
19
+ "ai",
20
+ "context",
21
+ "compaction",
22
+ "supermodel"
23
+ ],
24
+ "bin": {
25
+ "uncompact": "npm/run.js"
26
+ },
27
+ "scripts": {
28
+ "postinstall": "node npm/install.js"
29
+ },
30
+ "files": [
31
+ "npm/",
32
+ "hooks/"
33
+ ],
34
+ "engines": {
35
+ "node": ">=16"
36
+ }
37
+ }