OverviewFilesCommitsIssuesDocsReleasesPeers

keet-cli commits / 87d4da2

keet-cli: add extract-bundle.cjs — bare-union-bundle extractor for Keet 4.16+ packaging era
Keet 4.16.3 stopped shipping @holepunchto packages unpacked under node_modules; they're now compiled into bare-union-bundle worker files (core-worker.bundle etc.). keet-audit.cjs (which cp's node_modules) can no longer find them. extract-bundle.cjs parses the flat bundle format (<decimal-len>\n<json-manifest>\n<binary-tail>, files indexed by manifest.files[path].{offset,length}) and writes a readable source tree. Used to produce hyper-fleeky/keet-audit-4.16/ (keet-core 4.16.5). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
87d4da2a5fd72f28a8db7c1bdadca91272aa3a84
by plankatron <fleeky@gmail.com> · 2026-06-16T00:42:15.000Z

Changed files (1) +48 -0

tools/extract-bundle.cjs +48 -0
……@@ -0,0 +1,48 @@
1#!/usr/bin/env node
2// Extract a bare-union-bundle flat .bundle file into a readable source tree.
3// Format: <decimal-len>\n <json-manifest> <binary-tail>
4// manifest.files = { "<path>": { offset, length, mode } } indexed into tail.
5'use strict'
6const fs = require('fs')
7const path = require('path')
8
9const bundlePath = process.argv[2]
10const outDir = process.argv[3]
11if (!bundlePath || !outDir) { console.error('usage: extract-bundle.cjs <bundle> <outdir>'); process.exit(1) }
12
13const buf = fs.readFileSync(bundlePath)
14const nl = buf.indexOf(10)
15// String-aware brace counter to find the end of the JSON manifest.
16let i = nl + 1
17let depth = 0, inStr = false, esc = false, start = -1
18for (; i < buf.length; i++) {
19 const c = buf[i]
20 if (start === -1) { if (c === 0x7b) { start = i; depth = 1 } continue }
21 if (inStr) {
22 if (esc) esc = false
23 else if (c === 0x5c) esc = true
24 else if (c === 0x22) inStr = false
25 } else {
26 if (c === 0x22) inStr = true
27 else if (c === 0x7b) depth++
28 else if (c === 0x7d) { depth--; if (depth === 0) { i++; break } }
29 }
30}
31const manifest = JSON.parse(buf.slice(start, i).toString('utf8'))
32const tailStart = i
33const files = manifest.files || {}
34const paths = Object.keys(files)
35console.log('manifest keys:', Object.keys(manifest).join(','))
36console.log('files:', paths.length, '| tailStart:', tailStart, '| sample:', paths[0], JSON.stringify(files[paths[0]]))
37
38let written = 0
39for (const p of paths) {
40 const f = files[p]
41 if (typeof f.offset !== 'number' || typeof f.length !== 'number') continue
42 const data = buf.slice(tailStart + f.offset, tailStart + f.offset + f.length)
43 const dest = path.join(outDir, p)
44 fs.mkdirSync(path.dirname(dest), { recursive: true })
45 fs.writeFileSync(dest, data)
46 written++
47}
48console.log('wrote', written, 'files to', outDir)