thebird 1.2.78 → 1.2.80

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.
Files changed (78) hide show
  1. package/.github/workflows/publish.yml +9 -1
  2. package/CHANGELOG.md +226 -0
  3. package/CLAUDE.md +16 -0
  4. package/docs/agent-chat.js +7 -4
  5. package/docs/app.js +14 -11
  6. package/docs/defaults.json +1 -1
  7. package/docs/index.html +23 -6
  8. package/docs/kilo-http-stream.js +24 -0
  9. package/docs/node-builtins.js +194 -0
  10. package/docs/preview/index.html +32 -0
  11. package/docs/preview-sw-client.js +37 -6
  12. package/docs/preview-sw.js +55 -51
  13. package/docs/shell-awk.js +113 -0
  14. package/docs/shell-builtins-extra.js +121 -0
  15. package/docs/shell-builtins-text.js +109 -0
  16. package/docs/shell-builtins-util.js +112 -0
  17. package/docs/shell-builtins.js +183 -0
  18. package/docs/shell-bun.js +45 -0
  19. package/docs/shell-control.js +132 -0
  20. package/docs/shell-deno.js +54 -0
  21. package/docs/shell-exec.js +85 -0
  22. package/docs/shell-expand.js +164 -0
  23. package/docs/shell-fd.js +86 -0
  24. package/docs/shell-jobs.js +86 -0
  25. package/docs/shell-node-advanced.js +86 -0
  26. package/docs/shell-node-brotli.js +22 -0
  27. package/docs/shell-node-busnet.js +90 -0
  28. package/docs/shell-node-cipher.js +61 -0
  29. package/docs/shell-node-cluster.js +33 -0
  30. package/docs/shell-node-coreutils.js +36 -0
  31. package/docs/shell-node-crypto.js +137 -0
  32. package/docs/shell-node-dns.js +41 -0
  33. package/docs/shell-node-extras.js +148 -0
  34. package/docs/shell-node-firefox.js +95 -0
  35. package/docs/shell-node-git.js +60 -0
  36. package/docs/shell-node-inspector.js +39 -0
  37. package/docs/shell-node-io.js +131 -0
  38. package/docs/shell-node-ipc.js +15 -0
  39. package/docs/shell-node-keyobject.js +60 -0
  40. package/docs/shell-node-modules.js +157 -0
  41. package/docs/shell-node-native.js +31 -0
  42. package/docs/shell-node-net.js +71 -0
  43. package/docs/shell-node-observe.js +80 -0
  44. package/docs/shell-node-opfs.js +54 -0
  45. package/docs/shell-node-procfs.js +42 -0
  46. package/docs/shell-node-profiler.js +50 -0
  47. package/docs/shell-node-registry.js +24 -0
  48. package/docs/shell-node-resolve.js +147 -0
  49. package/docs/shell-node-runtime.js +83 -0
  50. package/docs/shell-node-srcmap.js +52 -0
  51. package/docs/shell-node-stdlib.js +103 -0
  52. package/docs/shell-node-streams.js +66 -0
  53. package/docs/shell-node-tar.js +47 -0
  54. package/docs/shell-node-testrunner.js +35 -0
  55. package/docs/shell-node-util-extras.js +66 -0
  56. package/docs/shell-node.js +188 -97
  57. package/docs/shell-npm.js +173 -0
  58. package/docs/shell-parser.js +122 -0
  59. package/docs/shell-pm-layout.js +62 -0
  60. package/docs/shell-pm.js +39 -0
  61. package/docs/shell-posix.js +70 -0
  62. package/docs/shell-procsub.js +65 -0
  63. package/docs/shell-readline.js +59 -4
  64. package/docs/shell-runtime.js +37 -0
  65. package/docs/shell-sed.js +83 -0
  66. package/docs/shell-signals.js +54 -0
  67. package/docs/shell-sw-jobs.js +76 -0
  68. package/docs/shell-ts.js +30 -0
  69. package/docs/shell.js +159 -167
  70. package/docs/terminal.js +9 -11
  71. package/docs/todo.html +211 -0
  72. package/package.json +1 -1
  73. package/server.js +43 -4
  74. package/start-kilo.js +17 -0
  75. package/test.js +199 -0
  76. package/.codeinsight +0 -73
  77. package/docs/acp-stream.js +0 -102
  78. package/docs/coi-serviceworker.js +0 -2
@@ -0,0 +1,147 @@
1
+ const toKey = p => p.replace(/^\//, '');
2
+
3
+ const CONDITIONS = ['node', 'import', 'require', 'default', 'browser'];
4
+ function pickCondition(cond) {
5
+ if (typeof cond === 'string') return cond;
6
+ if (Array.isArray(cond)) { for (const c of cond) { const r = pickCondition(c); if (r) return r; } return null; }
7
+ if (!cond || typeof cond !== 'object') return null;
8
+ for (const k of CONDITIONS) if (k in cond) { const r = pickCondition(cond[k]); if (r) return r; }
9
+ return null;
10
+ }
11
+ function matchPattern(patternKey, target) {
12
+ if (!patternKey.includes('*')) return null;
13
+ const [pre, post] = patternKey.split('*');
14
+ if (target.startsWith(pre) && target.endsWith(post)) return target.slice(pre.length, target.length - post.length);
15
+ return null;
16
+ }
17
+ export function resolveExports(pkgJson, subpath) {
18
+ const exp = pkgJson.exports;
19
+ if (!exp) return null;
20
+ if (typeof exp === 'string') return subpath === '.' ? exp : null;
21
+ const key = subpath === '.' ? '.' : './' + subpath.replace(/^\.\//, '');
22
+ if (exp[key]) return pickCondition(exp[key]);
23
+ if (subpath === '.' && !('.' in exp) && !Object.keys(exp).some(k => k.startsWith('.'))) return pickCondition(exp);
24
+ for (const pk of Object.keys(exp)) { const m = matchPattern(pk, key); if (m !== null) { const t = pickCondition(exp[pk]); return t ? t.replace('*', m) : null; } }
25
+ return null;
26
+ }
27
+ export function rewriteSpecifier(id) {
28
+ if (id.startsWith('jsr:')) return 'https://esm.sh/jsr/' + id.slice(4);
29
+ if (id.startsWith('npm:')) return 'https://esm.sh/' + id.slice(4);
30
+ if (id.startsWith('https://') || id.startsWith('http://')) return id;
31
+ return null;
32
+ }
33
+
34
+ export function resolveImports(pkgJson, subpath) {
35
+ const imps = pkgJson.imports;
36
+ if (!imps || !subpath.startsWith('#')) return null;
37
+ if (imps[subpath]) return pickCondition(imps[subpath]);
38
+ for (const pk of Object.keys(imps)) { const m = matchPattern(pk, subpath); if (m !== null) { const t = pickCondition(imps[pk]); return t ? t.replace('*', m) : null; } }
39
+ return null;
40
+ }
41
+
42
+ export function walkUpNodeModules(snap, startDir, pkgName) {
43
+ let dir = startDir.replace(/\/$/, '') || '/';
44
+ while (true) {
45
+ const candidate = (dir === '/' ? '' : dir) + '/node_modules/' + pkgName;
46
+ const candKey = toKey(candidate);
47
+ if ((candKey + '/package.json') in snap || (candKey + '/index.js') in snap || (candKey + '.js') in snap) return candidate;
48
+ if (dir === '/' || dir === '') return null;
49
+ const up = dir.slice(0, dir.lastIndexOf('/')) || '/';
50
+ if (up === dir) return null;
51
+ dir = up;
52
+ }
53
+ }
54
+
55
+ export function resolvePackageEntry(snap, pkgDir) {
56
+ const pjKey = toKey(pkgDir) + '/package.json';
57
+ if (!(pjKey in snap)) return null;
58
+ let pj;
59
+ try { pj = JSON.parse(snap[pjKey]); } catch { return null; }
60
+ const resolved = resolveExports(pj, '.');
61
+ if (resolved) return pkgDir + '/' + resolved.replace(/^\.\//, '');
62
+ return pkgDir + '/' + (pj.main || 'index.js').replace(/^\.\//, '');
63
+ }
64
+
65
+ export function makeModuleModule(requireFn, MODULES) {
66
+ return {
67
+ builtinModules: Object.keys(MODULES).filter(k => !k.startsWith('node:')).sort(),
68
+ createRequire: () => requireFn,
69
+ _resolveFilename: (id, parent) => requireFn.resolve(id),
70
+ _cache: requireFn.cache,
71
+ _pathCache: {},
72
+ Module: class Module { constructor(id) { this.id = id; this.exports = {}; this.filename = id; this.loaded = false; this.children = []; this.paths = []; } },
73
+ syncBuiltinESMExports: () => {},
74
+ wrap: s => '(function (exports, require, module, __filename, __dirname) { ' + s + '\n});',
75
+ wrapper: ['(function (exports, require, module, __filename, __dirname) { ', '\n});'],
76
+ };
77
+ }
78
+
79
+ export function makeModuleNotFoundError(id, requireStack) {
80
+ const err = new Error("Cannot find module '" + id + "'" + (requireStack ? '\nRequire stack:\n- ' + requireStack.join('\n- ') : ''));
81
+ err.code = 'MODULE_NOT_FOUND';
82
+ err.requireStack = requireStack || [];
83
+ return err;
84
+ }
85
+
86
+ export function makeFsPromises(fsSync) {
87
+ const wrap = fn => async (...args) => fn(...args);
88
+ return {
89
+ readFile: async (p, enc) => fsSync.readFileSync(p, enc),
90
+ writeFile: async (p, d) => fsSync.writeFileSync(p, d),
91
+ appendFile: async (p, d) => fsSync.appendFileSync(p, d),
92
+ access: async p => fsSync.accessSync(p),
93
+ stat: async p => fsSync.statSync(p),
94
+ readdir: async p => fsSync.readdirSync(p),
95
+ mkdir: async (p, o) => fsSync.mkdirSync(p, o),
96
+ rm: async (p, o) => fsSync.rmSync(p, o),
97
+ rmdir: async (p, o) => fsSync.rmdirSync(p, o),
98
+ unlink: async p => fsSync.unlinkSync(p),
99
+ rename: async (o, n) => fsSync.renameSync(o, n),
100
+ copyFile: async (s, d) => fsSync.copyFileSync(s, d),
101
+ realpath: async p => fsSync.realpathSync(p),
102
+ open: async p => ({ close: async () => {}, readFile: async enc => fsSync.readFileSync(p, enc), writeFile: async d => fsSync.writeFileSync(p, d) }),
103
+ };
104
+ }
105
+
106
+ export function makeFsWatch() {
107
+ return (path, opts, listener) => {
108
+ if (typeof opts === 'function') { listener = opts; opts = {}; }
109
+ const handlers = { change: listener ? [listener] : [], error: [], close: [] };
110
+ const w = {
111
+ on: (ev, fn) => { (handlers[ev] = handlers[ev] || []).push(fn); return w; },
112
+ close: () => { for (const h of handlers.close) h(); },
113
+ ref: () => w, unref: () => w,
114
+ };
115
+ return w;
116
+ };
117
+ }
118
+
119
+ export function makeNetStub() {
120
+ return {
121
+ Socket: class Socket { constructor() { throw new Error('net.Socket: not supported in browser — use fetch() or WebSocket'); } },
122
+ createServer: () => { throw new Error('net.createServer: not supported in browser — use express via http builtin'); },
123
+ connect: () => { throw new Error('net.connect: not supported in browser'); },
124
+ isIP: ip => /^\d+\.\d+\.\d+\.\d+$/.test(ip) ? 4 : ip.includes(':') ? 6 : 0,
125
+ isIPv4: ip => /^\d+\.\d+\.\d+\.\d+$/.test(ip),
126
+ isIPv6: ip => ip.includes(':'),
127
+ };
128
+ }
129
+
130
+ export function makeDgramStub() {
131
+ return {
132
+ createSocket: () => { throw new Error('dgram.createSocket: UDP not available in browser'); },
133
+ Socket: class { constructor() { throw new Error('dgram.Socket: UDP not available in browser'); } },
134
+ };
135
+ }
136
+
137
+ export function makeWorkerThreadsStub() {
138
+ return {
139
+ Worker: class { constructor() { throw new Error('worker_threads.Worker: not supported — use Web Worker via new Worker(url)'); } },
140
+ isMainThread: true,
141
+ parentPort: null,
142
+ workerData: null,
143
+ threadId: 0,
144
+ MessageChannel: globalThis.MessageChannel,
145
+ MessagePort: globalThis.MessagePort,
146
+ };
147
+ }
@@ -0,0 +1,83 @@
1
+ export function makeWorkerThreads(snap,Buf){
2
+ class Worker{
3
+ constructor(scriptPath,opts={}){
4
+ const src=snap()[scriptPath.replace(/^\.?\//,'')]||scriptPath;
5
+ const preamble=`const workerData=${JSON.stringify(opts.workerData||null)};const parentPort={postMessage:(m,t)=>self.postMessage(m,t),on:(ev,fn)=>{if(ev==='message')self.addEventListener('message',e=>fn(e.data));if(ev==='close')self.addEventListener('close',fn);},close:()=>self.close()};`;
6
+ const blob=new Blob([preamble+'\n'+src],{type:'application/javascript'});
7
+ this._url=URL.createObjectURL(blob);
8
+ this._worker=new globalThis.Worker(this._url,{type:'module'});
9
+ this._handlers={message:[],error:[],exit:[],online:[]};
10
+ this._worker.addEventListener('message',e=>{for(const f of this._handlers.message)f(e.data);});
11
+ this._worker.addEventListener('error',e=>{for(const f of this._handlers.error)f(e);});
12
+ queueMicrotask(()=>{for(const f of this._handlers.online)f();});
13
+ this.threadId=Math.floor(Math.random()*1e9);
14
+ }
15
+ on(ev,fn){(this._handlers[ev]=this._handlers[ev]||[]).push(fn);return this;}
16
+ once(ev,fn){const w=(...a)=>{this.off(ev,w);fn(...a);};return this.on(ev,w);}
17
+ off(ev,fn){this._handlers[ev]=(this._handlers[ev]||[]).filter(x=>x!==fn);return this;}
18
+ postMessage(msg,transfer){this._worker.postMessage(msg,transfer);}
19
+ terminate(){this._worker.terminate();URL.revokeObjectURL(this._url);for(const f of this._handlers.exit)f(0);return Promise.resolve(0);}
20
+ ref(){return this;}
21
+ unref(){return this;}
22
+ }
23
+ return{
24
+ Worker,
25
+ isMainThread:true,
26
+ parentPort:null,
27
+ workerData:null,
28
+ threadId:0,
29
+ MessageChannel:globalThis.MessageChannel,
30
+ MessagePort:globalThis.MessagePort,
31
+ BroadcastChannel:globalThis.BroadcastChannel,
32
+ SHARE_ENV:Symbol('SHARE_ENV'),
33
+ setEnvironmentData(){},
34
+ getEnvironmentData(){},
35
+ markAsUntransferable(){},
36
+ moveMessagePortToContext(){throw new Error('moveMessagePortToContext: not supported');},
37
+ resourceLimits:{maxOldGenerationSizeMb:0,maxYoungGenerationSizeMb:0,codeRangeSizeMb:0,stackSizeMb:0},
38
+ };
39
+ }
40
+
41
+ export function makeChildProcessReal(Buf,streamMod){
42
+ const getWc=()=>globalThis.__webcontainer||window.__webcontainer||null;
43
+ const mkProc=async(cmd,args,opts={})=>{const wc=getWc();if(!wc)throw new Error('child_process: WebContainer not available — spawn requires window.__webcontainer');const p=await wc.spawn(cmd,args||[],{cwd:opts.cwd,env:opts.env});const handlers={exit:[],close:[],error:[]};const stdout=new streamMod.Readable();const stderr=new streamMod.Readable();p.output.pipeTo(new WritableStream({write(chunk){stdout.push(Buf.from(chunk));}}));const exitPromise=p.exit.then(code=>{stdout.push(null);stderr.push(null);for(const f of handlers.exit)f(code);for(const f of handlers.close)f(code);return code;});return{pid:Math.floor(Math.random()*1e6),stdout,stderr,stdin:{write:d=>p.input.getWriter().write(d),end:()=>{}},on(ev,fn){(handlers[ev]=handlers[ev]||[]).push(fn);return this;},kill(){p.kill?.();},exitPromise};};
44
+ return{
45
+ exec(cmd,opts,cb){if(typeof opts==='function'){cb=opts;opts={};}const parts=cmd.split(/\s+/);mkProc(parts[0],parts.slice(1),opts).then(p=>{const chunks=[];p.stdout.on('data',c=>chunks.push(c));p.exitPromise.then(code=>{const out=Buf.concat(chunks).toString();if(cb)code===0?cb(null,out,''):cb(Object.assign(new Error('exit '+code),{code}),out,'');});},e=>cb&&cb(e));},
46
+ spawn(cmd,args,opts){let proc=null;const emitter={on(){return this;},_pending:true};mkProc(cmd,args,opts).then(p=>{proc=p;Object.assign(emitter,p);},e=>{for(const f of emitter._errorHandlers||[])f(e);});return new Proxy(emitter,{get(t,k){return proc?proc[k]:t[k];}});},
47
+ execFile(f,args,opts,cb){if(typeof opts==='function'){cb=opts;opts={};}return this.exec([f,...(args||[])].join(' '),opts,cb);},
48
+ execSync(){throw new Error('child_process.execSync: synchronous subprocess not available in browser');},
49
+ spawnSync(){throw new Error('child_process.spawnSync: synchronous subprocess not available');},
50
+ fork(){throw new Error('child_process.fork: not supported — use Worker');},
51
+ };
52
+ }
53
+
54
+ export function makeRepl(ctx,term,nodeEval){
55
+ const history=[];
56
+ let buffer='';
57
+ let lastResult=undefined;
58
+ const commands={
59
+ '.clear':()=>{buffer='';term.write('\r\n');},
60
+ '.exit':()=>{throw Object.assign(new Error('repl exit'),{__nodeExit:true,code:0});},
61
+ '.help':()=>{term.write('Commands: .clear .exit .help .load .save .editor\r\n');},
62
+ '.load':async path=>{const snap=window.__debug?.idbSnapshot||{};const content=snap[path.replace(/^\/+/,'')];if(!content)throw new Error('file not found: '+path);return nodeEval(content);},
63
+ '.save':path=>{const snap=window.__debug?.idbSnapshot||{};window.__debug.idbSnapshot={...snap,[path.replace(/^\/+/,'')]:history.join('\n')};term.write('saved\r\n');},
64
+ '.editor':()=>{term.write('(type ^D to execute, ^C to cancel)\r\n');buffer='__editor__';},
65
+ };
66
+ const isIncomplete=code=>{let depth=0,inStr=null,inTmpl=false,prev='';for(let i=0;i<code.length;i++){const c=code[i];if(inStr){if(c==='\\'){i++;continue;}if(c===inStr)inStr=null;continue;}if(inTmpl){if(c==='\\'){i++;continue;}if(c==='`')inTmpl=false;else if(c==='$'&&code[i+1]==='{'){depth++;i++;}continue;}if(c==="'"||c==='"')inStr=c;else if(c==='`')inTmpl=true;else if(c==='('||c==='['||c==='{')depth++;else if(c===')'||c===']'||c==='}')depth--;prev=c;}return depth>0||inStr!==null||inTmpl;};
67
+ return{
68
+ commands,
69
+ isIncomplete,
70
+ async eval(line){
71
+ const trimmed=line.trim();
72
+ if(trimmed.startsWith('.')){const[cmd,...rest]=trimmed.split(/\s+/);if(commands[cmd])return commands[cmd](rest.join(' '));}
73
+ buffer=buffer?buffer+'\n'+line:line;
74
+ if(isIncomplete(buffer))return{continuation:true};
75
+ const code=buffer;buffer='';
76
+ history.unshift(code);if(history.length>1000)history.pop();
77
+ const src='const _=arguments[0];'+(code.startsWith('var ')||code.startsWith('let ')||code.startsWith('const ')||code.includes(';')||code.includes('\n')?code:'return ('+code+');');
78
+ try{const fn=new Function(src);const r=fn(lastResult);if(r!==undefined)lastResult=r;return{result:r};}catch(e){return{error:e};}
79
+ },
80
+ getHistory(){return history;},
81
+ get lastResult(){return lastResult;},
82
+ };
83
+ }
@@ -0,0 +1,52 @@
1
+ let smMod=null;let smPromise=null;const consumers=new Map();const CAP=5;
2
+
3
+ async function loadSm(){
4
+ if(!smPromise)smPromise=import('https://esm.sh/source-map-js@1.2.1/es2022/source-map-js.mjs').then(m=>m.default||m);
5
+ return smPromise;
6
+ }
7
+
8
+ export async function preloadSourceMap(){smMod=await loadSm();return smMod;}
9
+
10
+ async function consumerFor(url,snapFn){
11
+ if(consumers.has(url))return consumers.get(url);
12
+ if(consumers.size>50){const first=consumers.keys().next().value;consumers.delete(first);}
13
+ if(!smMod)await loadSm();
14
+ let src='';
15
+ try{
16
+ if(url.startsWith('data:application/json;base64,'))src=atob(url.slice(29));
17
+ else if(url.startsWith('data:application/json,'))src=decodeURIComponent(url.slice(22));
18
+ else if(url.startsWith('http'))src=await (await fetch(url)).text();
19
+ else{const snap=snapFn();const key=url.replace(/^file:\/\/\/?/,'').replace(/^\//,'');src=snap[key]||snap[key+'.map']||'';}
20
+ }catch{return null;}
21
+ if(!src)return null;
22
+ try{const raw=JSON.parse(src);const c=new smMod.SourceMapConsumer(raw);consumers.set(url,c);return c;}catch{return null;}
23
+ }
24
+
25
+ function extractMapUrl(source){
26
+ if(!source)return null;
27
+ const m=source.match(/\/\/[#@]\s*sourceMappingURL=(\S+)/);
28
+ return m?m[1]:null;
29
+ }
30
+
31
+ export function installSourceMapStacks(snapFn){
32
+ if(Error._smHooked)return;Error._smHooked=true;
33
+ const origFormatter=Error.prepareStackTrace;
34
+ Error.prepareStackTrace=(err,frames)=>{
35
+ if(!smMod)return origFormatter?origFormatter(err,frames):err.toString()+'\n'+frames.map(f=>' at '+f.toString()).join('\n');
36
+ let depth=0;
37
+ const mapped=frames.map(f=>{
38
+ if(depth>=CAP)return f;
39
+ const file=f.getFileName?.();if(!file)return f;
40
+ const snap=snapFn();const src=snap[file.replace(/^file:\/\/\/?/,'').replace(/^\//,'')]||'';
41
+ const mapUrl=extractMapUrl(src);if(!mapUrl)return f;
42
+ depth++;
43
+ const c=consumers.get(mapUrl);if(!c)return f;
44
+ const line=f.getLineNumber?.(),col=f.getColumnNumber?.();if(!line)return f;
45
+ try{const orig=c.originalPositionFor({line,column:col||0});if(!orig.source)return f;return{...f,getFileName:()=>orig.source,getLineNumber:()=>orig.line,getColumnNumber:()=>orig.column,getFunctionName:()=>orig.name||f.getFunctionName?.(),toString:()=>` at ${orig.name||'<anonymous>'} (${orig.source}:${orig.line}:${orig.column})`};}catch{return f;}
46
+ });
47
+ return origFormatter?origFormatter(err,mapped):err.toString()+'\n'+mapped.map(f=>' at '+(f.toString?.()||f)).join('\n');
48
+ };
49
+ Promise.resolve().then(async()=>{await loadSm();const snap=snapFn();for(const [key,src] of Object.entries(snap)){const mapUrl=extractMapUrl(src);if(mapUrl)await consumerFor(mapUrl,snapFn);}});
50
+ }
51
+
52
+ export function clearSourceMapCache(){consumers.clear();}
@@ -0,0 +1,103 @@
1
+ const COLORS = { string: '\x1b[32m', number: '\x1b[33m', boolean: '\x1b[33m', bigint: '\x1b[33m', null: '\x1b[1m', undefined: '\x1b[90m', symbol: '\x1b[35m', regexp: '\x1b[31m', date: '\x1b[35m', special: '\x1b[36m' };
2
+ const RESET = '\x1b[0m';
3
+ const paint = (s, c, on) => on ? c + s + RESET : s;
4
+
5
+ function inspectPrimitive(v, colors) {
6
+ if (v === null) return paint('null', COLORS.null, colors);
7
+ if (v === undefined) return paint('undefined', COLORS.undefined, colors);
8
+ const t = typeof v;
9
+ if (t === 'string') return paint("'" + v.replace(/\\/g, '\\\\').replace(/'/g, "\\'") + "'", COLORS.string, colors);
10
+ if (t === 'bigint') return paint(String(v) + 'n', COLORS.bigint, colors);
11
+ if (t === 'number' || t === 'boolean') return paint(String(v), COLORS[t], colors);
12
+ if (t === 'symbol') return paint(v.toString(), COLORS.symbol, colors);
13
+ if (t === 'function') return paint('[Function' + (v.name ? ': ' + v.name : ' (anonymous)') + ']', COLORS.special, colors);
14
+ return null;
15
+ }
16
+
17
+ export function inspect(v, opts = {}, depth = 0, seen = new Map(), refCount = { n: 0 }) {
18
+ const colors = !!opts.colors;
19
+ const prim = inspectPrimitive(v, colors);
20
+ if (prim !== null) return prim;
21
+ if (v instanceof Date) return paint(v.toISOString(), COLORS.date, colors);
22
+ if (v instanceof RegExp) return paint(v.toString(), COLORS.regexp, colors);
23
+ if (v instanceof Error) return v.stack || (v.name + ': ' + v.message);
24
+ if (seen.has(v)) { const id = seen.get(v); if (id.ref == null) id.ref = ++refCount.n; return '[Circular *' + id.ref + ']'; }
25
+ const entry = { ref: null }; seen.set(v, entry);
26
+ const maxDepth = opts.depth ?? 2;
27
+ if (depth > maxDepth) return Array.isArray(v) ? '[Array]' : '[Object]';
28
+ if (Array.isArray(v)) {
29
+ if (!v.length) return '[]';
30
+ return '[ ' + v.map(x => inspect(x, opts, depth + 1, seen, refCount)).join(', ') + ' ]';
31
+ }
32
+ if (v instanceof Map) {
33
+ const entries = [...v.entries()].map(([k, val]) => inspect(k, opts, depth + 1, seen, refCount) + ' => ' + inspect(val, opts, depth + 1, seen, refCount));
34
+ return 'Map(' + v.size + ')' + (v.size ? ' { ' + entries.join(', ') + ' }' : ' {}');
35
+ }
36
+ if (v instanceof Set) {
37
+ const items = [...v].map(x => inspect(x, opts, depth + 1, seen, refCount));
38
+ return 'Set(' + v.size + ')' + (v.size ? ' { ' + items.join(', ') + ' }' : ' {}');
39
+ }
40
+ if (v instanceof Uint8Array) {
41
+ const hex = [...v.slice(0, 16)].map(b => b.toString(16).padStart(2, '0')).join(' ');
42
+ return '<Buffer ' + hex + (v.length > 16 ? ' ... ' + (v.length - 16) + ' more bytes' : '') + '>';
43
+ }
44
+ const keys = opts.showHidden ? Object.getOwnPropertyNames(v) : Object.keys(v);
45
+ const syms = Object.getOwnPropertySymbols(v);
46
+ if (!keys.length && !syms.length) return '{}';
47
+ const parts = keys.map(k => {
48
+ const ks = /^[A-Za-z_$][A-Za-z0-9_$]*$/.test(k) ? k : "'" + k + "'";
49
+ return ks + ': ' + inspect(v[k], opts, depth + 1, seen, refCount);
50
+ }).concat(syms.map(s => '[' + s.toString() + ']: ' + inspect(v[s], opts, depth + 1, seen, refCount)));
51
+ const ctor = v.constructor && v.constructor !== Object ? v.constructor.name + ' ' : '';
52
+ const body = ctor + '{ ' + parts.join(', ') + ' }';
53
+ return entry.ref != null ? '<ref *' + entry.ref + '> ' + body : body;
54
+ }
55
+
56
+ export function format(...args) {
57
+ if (!args.length) return '';
58
+ const fmt = args[0];
59
+ if (typeof fmt !== 'string') return args.map(a => typeof a === 'object' ? inspect(a) : String(a)).join(' ');
60
+ let i = 1;
61
+ const out = fmt.replace(/%[sdifjoO%]/g, m => {
62
+ if (m === '%%') return '%';
63
+ if (i >= args.length) return m;
64
+ const a = args[i++];
65
+ if (m === '%s') return String(a);
66
+ if (m === '%d' || m === '%i') return String(parseInt(a, 10));
67
+ if (m === '%f') return String(parseFloat(a));
68
+ if (m === '%j') return JSON.stringify(a);
69
+ if (m === '%o' || m === '%O') return inspect(a);
70
+ return m;
71
+ });
72
+ const extra = args.slice(i).map(a => typeof a === 'object' ? inspect(a) : String(a));
73
+ return extra.length ? out + ' ' + extra.join(' ') : out;
74
+ }
75
+
76
+ export { createHash } from './shell-node-crypto.js';
77
+
78
+ let fflatePromise = null;
79
+ async function getFflate() {
80
+ if (!fflatePromise) fflatePromise = import('https://esm.sh/fflate@0.8.2/es2022/fflate.mjs').then(m => m.gzipSync ? m : (m.default && m.default.gzipSync ? m.default : m));
81
+ return fflatePromise;
82
+ }
83
+ let fflateSync = null;
84
+ export async function preloadFflate() { fflateSync = await getFflate(); return fflateSync; }
85
+
86
+ export function createZlib(Buf) {
87
+ const need = () => { if (!fflateSync) throw new Error('zlib sync: preloadFflate() must run before sync zlib calls (auto-preloaded on node entry)'); return fflateSync; };
88
+ return {
89
+ gzipSync: b => Buf.from(need().gzipSync(b instanceof Uint8Array ? b : new TextEncoder().encode(String(b)))),
90
+ gunzipSync: b => Buf.from(need().gunzipSync(b)),
91
+ deflateSync: b => Buf.from(need().deflateSync(b instanceof Uint8Array ? b : new TextEncoder().encode(String(b)))),
92
+ inflateSync: b => Buf.from(need().inflateSync(b)),
93
+ deflateRawSync: b => Buf.from(need().deflateSync(b, { raw: true }) || need().deflateSync(b)),
94
+ inflateRawSync: b => Buf.from(need().inflateSync(b, { raw: true }) || need().inflateSync(b)),
95
+ gzip: async (buf, cb) => { try { const p = await getFflate(); const out = Buf.from(p.gzipSync(buf instanceof Uint8Array ? buf : new TextEncoder().encode(String(buf)))); if (cb) cb(null, out); return out; } catch (e) { if (cb) cb(e); else throw e; } },
96
+ gunzip: async (buf, cb) => { try { const p = await getFflate(); const out = Buf.from(p.gunzipSync(buf)); if (cb) cb(null, out); return out; } catch (e) { if (cb) cb(e); else throw e; } },
97
+ deflate: async (buf, cb) => { const p = await getFflate(); const out = Buf.from(p.deflateSync(buf instanceof Uint8Array ? buf : new TextEncoder().encode(String(buf)))); if (cb) cb(null, out); return out; },
98
+ inflate: async (buf, cb) => { const p = await getFflate(); const out = Buf.from(p.inflateSync(buf)); if (cb) cb(null, out); return out; },
99
+ createGzip: () => ({ pipe: () => {}, on: () => {}, write: () => {}, end: () => {} }),
100
+ createGunzip: () => ({ pipe: () => {}, on: () => {}, write: () => {}, end: () => {} }),
101
+ constants: { Z_NO_FLUSH: 0, Z_PARTIAL_FLUSH: 1, Z_SYNC_FLUSH: 2, Z_FULL_FLUSH: 3, Z_FINISH: 4, Z_BLOCK: 5, Z_TREES: 6, Z_OK: 0, Z_STREAM_END: 1 },
102
+ };
103
+ }
@@ -0,0 +1,66 @@
1
+ function makeEmitter(){
2
+ const h={};
3
+ return {
4
+ on(e,f){(h[e]=h[e]||[]).push(f);return this;},
5
+ once(e,f){const w=(...a)=>{this.off(e,w);f(...a);};return this.on(e,w);},
6
+ off(e,f){h[e]=(h[e]||[]).filter(x=>x!==f);return this;},
7
+ removeListener(e,f){return this.off(e,f);},
8
+ removeAllListeners(e){if(e)delete h[e];else for(const k of Object.keys(h))delete h[k];return this;},
9
+ emit(e,...a){for(const f of(h[e]||[]).slice())f(...a);return(h[e]||[]).length>0;},
10
+ listenerCount(e){return(h[e]||[]).length;},
11
+ _h:h,
12
+ };
13
+ }
14
+
15
+ class Readable{
16
+ constructor(opts={}){
17
+ Object.assign(this,makeEmitter());
18
+ this._q=[];this._ended=false;this._flowing=null;this._paused=false;this._destroyed=false;
19
+ this.readable=true;this.readableHighWaterMark=opts.highWaterMark??16384;this.readableEnded=false;this.readableObjectMode=!!opts.objectMode;
20
+ this._read=opts.read||(()=>{});this._encoding=null;
21
+ }
22
+ push(chunk){if(chunk===null){this._ended=true;queueMicrotask(()=>this._drain());return false;}this._q.push(chunk);queueMicrotask(()=>this._drain());return this._q.length<this.readableHighWaterMark;}
23
+ read(n){if(!this._q.length)return null;return n?this._q.shift():this._q.shift();}
24
+ _drain(){if(this._paused||this._destroyed)return;while(this._q.length){const c=this._q.shift();const data=this._encoding&&c instanceof Uint8Array?new TextDecoder(this._encoding).decode(c):c;this.emit('data',data);}if(this._ended&&!this.readableEnded){this.readableEnded=true;this.emit('end');}}
25
+ pause(){this._paused=true;return this;}
26
+ resume(){this._paused=false;queueMicrotask(()=>this._drain());return this;}
27
+ pipe(dest){this.on('data',c=>{if(dest.write(c)===false)this.pause();});this.on('end',()=>dest.end?.());dest.on?.('drain',()=>this.resume());return dest;}
28
+ unpipe(){return this;}
29
+ setEncoding(enc){this._encoding=enc;return this;}
30
+ destroy(e){this._destroyed=true;if(e)this.emit('error',e);this.emit('close');return this;}
31
+ [Symbol.asyncIterator](){const self=this;return{async next(){if(self._q.length)return{value:self._q.shift(),done:false};if(self._ended)return{value:undefined,done:true};return new Promise(r=>{const onData=c=>{self.off('data',onData);self.off('end',onEnd);r({value:c,done:false});};const onEnd=()=>{self.off('data',onData);r({value:undefined,done:true});};self.on('data',onData);self.once('end',onEnd);});}};}
32
+ }
33
+
34
+ class Writable{
35
+ constructor(opts={}){
36
+ Object.assign(this,makeEmitter());
37
+ this._write=opts.write||((c,e,cb)=>cb());this.writable=true;this.writableEnded=false;this.writableFinished=false;this.writableHighWaterMark=opts.highWaterMark??16384;this._pending=0;
38
+ }
39
+ write(chunk,enc,cb){if(typeof enc==='function'){cb=enc;enc=null;}if(this.writableEnded){const e=Object.assign(new Error('write after end'),{code:'ERR_STREAM_WRITE_AFTER_END'});queueMicrotask(()=>cb?.(e));return false;}this._pending++;this._write(chunk,enc,err=>{this._pending--;cb?.(err);if(this._pending===0)this.emit('drain');});return this._pending<this.writableHighWaterMark;}
40
+ end(chunk,enc,cb){if(chunk!=null)this.write(chunk,enc);this.writableEnded=true;queueMicrotask(()=>{this.writableFinished=true;this.emit('finish');this.emit('close');cb?.();});return this;}
41
+ destroy(e){if(e)this.emit('error',e);this.emit('close');return this;}
42
+ }
43
+
44
+ class Duplex extends Readable{constructor(opts={}){super(opts);Object.assign(this,new Writable(opts));this._write=opts.write||((c,e,cb)=>cb());}write(...a){return Writable.prototype.write.call(this,...a);}end(...a){return Writable.prototype.end.call(this,...a);}}
45
+
46
+ class Transform extends Duplex{
47
+ constructor(opts={}){super(opts);this._transform=opts.transform||((c,e,cb)=>cb(null,c));this._flush=opts.flush||(cb=>cb());this._write=(c,e,cb)=>{this._transform(c,e,(err,out)=>{if(err)return cb(err);if(out!=null)this.push(out);cb();});};const origEnd=this.end.bind(this);this.end=(...a)=>{this._flush((err,out)=>{if(out!=null)this.push(out);this.push(null);});return origEnd(...a);};}
48
+ }
49
+
50
+ class PassThrough extends Transform{constructor(opts){super({...opts,transform:(c,e,cb)=>cb(null,c)});}}
51
+
52
+ function pipeline(...args){const cb=typeof args[args.length-1]==='function'?args.pop():null;const streams=args;let done=false;const fin=e=>{if(done)return;done=true;cb?.(e);};for(let i=0;i<streams.length-1;i++){const src=streams[i],dst=streams[i+1];src.on('error',fin);src.pipe(dst);}streams[streams.length-1].on('finish',()=>fin(null));streams[streams.length-1].on('error',fin);return streams[streams.length-1];}
53
+
54
+ function finished(stream,cb){const onFin=()=>cb();const onErr=e=>cb(e);stream.on?.('finish',onFin);stream.on?.('end',onFin);stream.on?.('error',onErr);return()=>{stream.off?.('finish',onFin);stream.off?.('end',onFin);stream.off?.('error',onErr);};}
55
+
56
+ export function makeStream(){
57
+ const mod={Readable,Writable,Duplex,Transform,PassThrough,pipeline,finished,promises:{pipeline:(...a)=>new Promise((res,rej)=>pipeline(...a,e=>e?rej(e):res())),finished:s=>new Promise((res,rej)=>finished(s,e=>e?rej(e):res()))}};
58
+ Readable.from=iter=>{const r=new Readable();(async()=>{try{for await(const c of iter)r.push(c);r.push(null);}catch(e){r.destroy(e);}})();return r;};
59
+ return mod;
60
+ }
61
+
62
+ export function extendFsStreams(fs,Buf){
63
+ fs.createReadStream=(path,opts={})=>{const r=new Readable();queueMicrotask(()=>{try{const data=fs.readFileSync(path);const buf=typeof data==='string'?Buf.from(data):data;const start=opts.start||0;const end=opts.end??buf.length;r.push(buf.slice(start,end));r.push(null);}catch(e){r.destroy(e);}});return r;};
64
+ fs.createWriteStream=(path,opts={})=>{const chunks=[];const w=new Writable({write:(c,e,cb)=>{chunks.push(typeof c==='string'?Buf.from(c):c);cb();}});w.on('finish',()=>{try{fs.writeFileSync(path,Buf.concat(chunks));}catch(e){w.emit('error',e);}});return w;};
65
+ return fs;
66
+ }
@@ -0,0 +1,47 @@
1
+ const BLOCK=512;
2
+ const readStr=(buf,o,len)=>{let e=o;while(e<o+len&&buf[e]!==0)e++;return new TextDecoder().decode(buf.slice(o,e));};
3
+ const readOctal=(buf,o,len)=>{const s=readStr(buf,o,len).trim();return s?parseInt(s,8):0;};
4
+
5
+ export function untar(data){
6
+ const buf=data instanceof Uint8Array?data:new Uint8Array(data);
7
+ const entries=[];let off=0;
8
+ while(off+BLOCK<=buf.length){
9
+ if(buf[off]===0&&buf[off+BLOCK-1]===0){off+=BLOCK;continue;}
10
+ const name=readStr(buf,off,100);
11
+ if(!name)break;
12
+ const mode=readOctal(buf,off+100,8);
13
+ const size=readOctal(buf,off+124,12);
14
+ const mtime=readOctal(buf,off+136,12);
15
+ const type=String.fromCharCode(buf[off+156]||0x30);
16
+ const prefix=readStr(buf,off+345,155);
17
+ const fullName=prefix?prefix+'/'+name:name;
18
+ const dataStart=off+BLOCK;
19
+ const dataEnd=dataStart+size;
20
+ const body=type==='0'||type==='\0'?buf.slice(dataStart,dataEnd):null;
21
+ entries.push({name:fullName,mode,size,mtime,type,data:body});
22
+ const padded=Math.ceil(size/BLOCK)*BLOCK;
23
+ off=dataStart+padded;
24
+ }
25
+ return entries;
26
+ }
27
+
28
+ export function makeTar(fs,fflate,Buf){
29
+ return{
30
+ async extract(data,dest='/'){
31
+ let bytes=data instanceof Uint8Array?data:new Uint8Array(data);
32
+ if(bytes[0]===0x1f&&bytes[1]===0x8b){bytes=fflate?.gunzipSync?fflate.gunzipSync(bytes):bytes;}
33
+ const entries=untar(bytes);
34
+ const out=[];
35
+ for(const e of entries){
36
+ if(!e.data&&e.type!=='5')continue;
37
+ const target=(dest.replace(/\/$/,'')+'/'+e.name).replace(/^\/+/,'/');
38
+ if(e.type==='5'){try{fs.mkdirSync(target,{recursive:true});}catch{}}
39
+ else{const parts=target.split('/');for(let i=1;i<parts.length;i++){const d=parts.slice(0,i).join('/');if(d&&!fs.existsSync(d)){try{fs.mkdirSync(d,{recursive:true});}catch{}}}fs.writeFileSync(target,Buf.from(e.data));}
40
+ out.push(target);
41
+ }
42
+ return out;
43
+ },
44
+ async list(data){let bytes=data instanceof Uint8Array?data:new Uint8Array(data);if(bytes[0]===0x1f&&bytes[1]===0x8b)bytes=fflate?.gunzipSync?fflate.gunzipSync(bytes):bytes;return untar(bytes).map(e=>e.name);},
45
+ untar,
46
+ };
47
+ }
@@ -0,0 +1,35 @@
1
+ export function makeTestRunner(term){
2
+ const suites=[];let current=null;const results={pass:0,fail:0,skip:0,failures:[]};
3
+ const write=term?(s=>term.write(s)):(s=>console.log(s.replace(/\r\n/g,'')));
4
+ const color=(c,s)=>`\x1b[${c}m${s}\x1b[0m`;
5
+ async function runOne(name,fn,parentPath=''){
6
+ const path=(parentPath?parentPath+' > ':'')+name;
7
+ if(!fn){results.skip++;write(color(33,' - '+path+' (skip)')+'\r\n');return;}
8
+ const t0=performance.now();
9
+ try{await fn(tctx(name,path));results.pass++;write(color(32,' ✓ '+path)+` ${(performance.now()-t0).toFixed(1)}ms\r\n`);}
10
+ catch(e){results.fail++;results.failures.push({path,error:e});write(color(31,' ✗ '+path+' — '+e.message)+'\r\n');}
11
+ }
12
+ function tctx(name,path){return{name,fullName:path,diagnostic(m){write(color(90,' # '+m)+'\r\n');},skip(){throw Object.assign(new Error('skip'),{__skip:true});},todo(){throw Object.assign(new Error('todo'),{__todo:true});},signal:new AbortController().signal,plan(n){}};}
13
+ function test(name,optsOrFn,maybeFn){const fn=typeof optsOrFn==='function'?optsOrFn:maybeFn;const opts=typeof optsOrFn==='object'?optsOrFn:{};if(opts.skip)return runOne(name,null);if(opts.only){}if(current){current.tests.push({name,fn});return Promise.resolve();}return runOne(name,fn);}
14
+ function describe(name,fn){const prev=current;current={name,tests:[],parentPath:prev?prev.fullPath:'',fullPath:(prev?prev.fullPath+' > ':'')+name};try{fn(current);}finally{const c=current;current=prev;return(async()=>{for(const t of c.tests)await runOne(t.name,t.fn,c.fullPath);})();}}
15
+ const mock={
16
+ fn(impl){const calls=[];const mk=function(...a){calls.push({arguments:a,result:undefined,error:undefined,target:this});try{const r=impl?impl.apply(this,a):undefined;calls[calls.length-1].result=r;return r;}catch(e){calls[calls.length-1].error=e;throw e;}};mk.mock={calls,callCount(){return calls.length;},resetCalls(){calls.length=0;},restore(){}};return mk;},
17
+ method(obj,key,impl){const orig=obj[key];const m=mock.fn(impl||orig);obj[key]=m;m.mock.restore=()=>{obj[key]=orig;};return m;},
18
+ timers:{enable(){},reset(){},runAll(){},tick(){},restore(){}},
19
+ };
20
+ const api={test,describe,it:test,before:fn=>fn?.(),after:fn=>fn?.(),beforeEach:()=>{},afterEach:()=>{},mock,run(){},results,
21
+ async summarize(){write('\r\n'+color(1,`# tests ${results.pass+results.fail+results.skip}`)+'\r\n');write(color(32,`# pass ${results.pass}`)+'\r\n');write(color(31,`# fail ${results.fail}`)+'\r\n');write(color(33,`# skip ${results.skip}`)+'\r\n');return results.fail===0;},
22
+ };
23
+ return api;
24
+ }
25
+
26
+ export function makeTapReporter(term){
27
+ const w=term?(s=>term.write(s)):(s=>console.log(s));
28
+ let n=0;
29
+ return{
30
+ ok(name){w(`ok ${++n} - ${name}\r\n`);},
31
+ notOk(name,msg){w(`not ok ${++n} - ${name}\r\n ---\r\n error: ${msg}\r\n ...\r\n`);},
32
+ plan(total){w(`1..${total}\r\n`);},
33
+ comment(m){w(`# ${m}\r\n`);},
34
+ };
35
+ }
@@ -0,0 +1,66 @@
1
+ const ANSI_RE=/\x1b\[[0-9;]*[a-zA-Z]/g;
2
+ const STYLE_CODES={reset:0,bold:1,dim:2,italic:3,underline:4,inverse:7,hidden:8,strikethrough:9,black:30,red:31,green:32,yellow:33,blue:34,magenta:35,cyan:36,white:37,gray:90,bgBlack:40,bgRed:41,bgGreen:42,bgYellow:43,bgBlue:44,bgMagenta:45,bgCyan:46,bgWhite:47};
3
+
4
+ export function styleText(styles,text){
5
+ const arr=Array.isArray(styles)?styles:[styles];
6
+ const codes=arr.map(s=>STYLE_CODES[s]).filter(c=>c!=null);
7
+ if(!codes.length)return text;
8
+ return `\x1b[${codes.join(';')}m${text}\x1b[0m`;
9
+ }
10
+
11
+ export function stripVTControlCharacters(s){return String(s).replace(ANSI_RE,'');}
12
+
13
+ export function getCallSites(frames=10){
14
+ const e=new Error();const lines=(e.stack||'').split('\n').slice(2,2+frames);
15
+ return lines.map(l=>{const m=l.match(/at\s+(?:(.+?)\s+\()?(.+?):(\d+):(\d+)\)?/);return{functionName:m?.[1]||'<anonymous>',scriptName:m?.[2]||'',lineNumber:m?+m[3]:0,column:m?+m[4]:0,scriptId:'0'};});
16
+ }
17
+
18
+ export class MIMEType{
19
+ constructor(input){
20
+ const [essence,...paramParts]=String(input).split(';');
21
+ const [type,subtype]=essence.trim().split('/');
22
+ if(!type||!subtype)throw new TypeError('Invalid MIME: '+input);
23
+ this._type=type.toLowerCase();this._sub=subtype.toLowerCase();
24
+ this._params=new MIMEParams();
25
+ for(const p of paramParts){const [k,v]=p.split('=');if(k&&v)this._params.set(k.trim().toLowerCase(),v.trim().replace(/^["']|["']$/g,''));}
26
+ }
27
+ get type(){return this._type;}set type(v){this._type=String(v).toLowerCase();}
28
+ get subtype(){return this._sub;}set subtype(v){this._sub=String(v).toLowerCase();}
29
+ get essence(){return `${this._type}/${this._sub}`;}
30
+ get params(){return this._params;}
31
+ toString(){const p=[...this._params].map(([k,v])=>`${k}=${v}`).join(';');return this.essence+(p?';'+p:'');}
32
+ }
33
+
34
+ export class MIMEParams{
35
+ constructor(){this._m=new Map();}
36
+ get(k){return this._m.get(k);}
37
+ set(k,v){this._m.set(String(k).toLowerCase(),String(v));return this;}
38
+ delete(k){return this._m.delete(k);}
39
+ has(k){return this._m.has(k);}
40
+ *entries(){yield*this._m.entries();}
41
+ *keys(){yield*this._m.keys();}
42
+ *values(){yield*this._m.values();}
43
+ [Symbol.iterator](){return this._m[Symbol.iterator]();}
44
+ }
45
+
46
+ export function makeConsoleExtras(origConsole,term){
47
+ const write=term?(s=>term.write(s)):(s=>origConsole.log(s));
48
+ const timers=new Map();const counters=new Map();let groupDepth=0;const ind=()=>' '.repeat(groupDepth);
49
+ return{
50
+ table(data,columns){if(!data||typeof data!=='object')return origConsole.log(data);const rows=Array.isArray(data)?data:Object.entries(data).map(([k,v])=>({'(index)':k,...(typeof v==='object'?v:{Values:v})}));if(!rows.length)return;const cols=columns||[...new Set(rows.flatMap(r=>Object.keys(r)))];const w=cols.map(c=>Math.max(c.length,...rows.map(r=>String(r[c]??'').length)));const line=(cells,pad)=>'│ '+cells.map((c,i)=>String(c??'').padEnd(w[i]))+' │\r\n';const sep=s=>s+cols.map((_,i)=>'─'.repeat(w[i]+2)).join(s==='├'?'┼':'─')+(s==='├'?'┤':'╯')+'\r\n';write('╭'+cols.map((_,i)=>'─'.repeat(w[i]+2)).join('─')+'╮\r\n');write('│ '+cols.map((c,i)=>c.padEnd(w[i])).join(' │ ')+' │\r\n');write('├'+cols.map((_,i)=>'─'.repeat(w[i]+2)).join('┼')+'┤\r\n');for(const r of rows)write('│ '+cols.map((c,i)=>String(r[c]??'').padEnd(w[i])).join(' │ ')+' │\r\n');write('╰'+cols.map((_,i)=>'─'.repeat(w[i]+2)).join('─')+'╯\r\n');},
51
+ group(label){if(label)write(ind()+label+'\r\n');groupDepth++;},
52
+ groupCollapsed(label){this.group(label);},
53
+ groupEnd(){groupDepth=Math.max(0,groupDepth-1);},
54
+ time(label='default'){timers.set(label,performance.now());},
55
+ timeEnd(label='default'){const t=timers.get(label);if(t==null)return;timers.delete(label);write(`${label}: ${(performance.now()-t).toFixed(3)}ms\r\n`);},
56
+ timeLog(label='default',...rest){const t=timers.get(label);if(t==null)return;write(`${label}: ${(performance.now()-t).toFixed(3)}ms ${rest.join(' ')}\r\n`);},
57
+ count(label='default'){const n=(counters.get(label)||0)+1;counters.set(label,n);write(`${label}: ${n}\r\n`);},
58
+ countReset(label='default'){counters.set(label,0);},
59
+ dir(v){write(JSON.stringify(v,null,2)+'\r\n');},
60
+ dirxml(v){this.dir(v);},
61
+ trace(...a){write('Trace: '+a.join(' ')+'\r\n'+new Error().stack+'\r\n');},
62
+ assert(cond,...msg){if(!cond)write('Assertion failed: '+msg.join(' ')+'\r\n');},
63
+ clear(){write('\x1b[2J\x1b[H');},
64
+ profile(){},profileEnd(){},timeStamp(){},
65
+ };
66
+ }