@bash0816/claude-code 2.1.159-9 → 2.1.161-1

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.
@@ -6,6 +6,7 @@ WORKDIR="${WORKDIR:-${HOME}/.claude-termux-native-package/launcher-workdir}"
6
6
  ENTRY_JS_OFFSET="${ENTRY_JS_OFFSET:?ENTRY_JS_OFFSET is required}"
7
7
  ENTRY_END_OFFSET="${ENTRY_END_OFFSET:?ENTRY_END_OFFSET is required}"
8
8
  CURRENT_CLAUDE_VERSION="${CURRENT_CLAUDE_VERSION:?CURRENT_CLAUDE_VERSION is required}"
9
+ CLAUDE_TERMUX_PACKAGE_DIR="${CLAUDE_TERMUX_PACKAGE_DIR:?CLAUDE_TERMUX_PACKAGE_DIR is required}"
9
10
  TERMUX_TMPDIR="${TMPDIR:-/data/data/com.termux/files/usr/tmp}"
10
11
  SSL_CERT_DIR="${SSL_CERT_DIR:-/data/data/com.termux/files/usr/etc/tls}"
11
12
  SSL_CERT_FILE="${SSL_CERT_FILE:-/data/data/com.termux/files/usr/etc/tls/cert.pem}"
@@ -39,9 +40,24 @@ export ENTRY_JS_OFFSET
39
40
  export ENTRY_END_OFFSET
40
41
  export CURRENT_CLAUDE_VERSION
41
42
 
42
- node - "$@" <<'NODE'
43
+ _pf=0
44
+ for _a in "$@"; do
45
+ case "$_a" in
46
+ -p|--print) _pf=1; break ;;
47
+ --) break ;;
48
+ esac
49
+ done
50
+
51
+ if [ "$_pf" = "1" ] && [ "${CLAUDE_TERMUX_STDIN:-}" != "inherit" ]; then
52
+ _helper=$(mktemp "${TMPDIR:-/tmp}/claude-helper.XXXXXX.js")
53
+ trap 'rm -f "$_helper"' EXIT HUP INT TERM
54
+ cat <<'NODE' > "$_helper"
43
55
  const fs = require('fs');
44
56
  const path = require('path');
57
+ const {
58
+ BLOCK_MESSAGE,
59
+ createGuardedChildProcess,
60
+ } = require(path.join(process.env.CLAUDE_TERMUX_PACKAGE_DIR, 'lib', 'native-update-guard.js'));
45
61
 
46
62
  const sourceBin = process.env.SOURCE_BIN;
47
63
  const workdir = process.env.WORKDIR;
@@ -59,8 +75,6 @@ class RequestedExit extends Error {
59
75
 
60
76
  function ensureEntryFile() {
61
77
  const extractedFile = path.join(workdir, `cli.${entryJsOffset}.${entryEndOffset}.bare-path.js`);
62
- if (fs.existsSync(extractedFile)) return extractedFile;
63
-
64
78
  const len = entryEndOffset - entryJsOffset;
65
79
  if (!(len > 0)) throw new Error('invalid replay offsets');
66
80
 
@@ -73,13 +87,157 @@ function ensureEntryFile() {
73
87
  return extractedFile;
74
88
  }
75
89
 
90
+ function stringWidth(value) {
91
+ const text = String(value ?? '');
92
+ if (typeof Intl !== 'undefined' && typeof Intl.Segmenter === 'function') {
93
+ const segmenter = new Intl.Segmenter('en', { granularity: 'grapheme' });
94
+ let width = 0;
95
+ for (const _segment of segmenter.segment(text)) width += 1;
96
+ return width;
97
+ }
98
+ return Array.from(text).length;
99
+ }
100
+
101
+ function parseScalar(value) {
102
+ const text = String(value ?? '').trim();
103
+ if (text === '') return '';
104
+ if (text === 'true') return true;
105
+ if (text === 'false') return false;
106
+ if (text === 'null' || text === '~') return null;
107
+ if (/^-?(?:0|[1-9]\d*)(?:\.\d+)?$/.test(text)) return Number(text);
108
+ if (
109
+ (text.startsWith('"') && text.endsWith('"')) ||
110
+ (text.startsWith("'") && text.endsWith("'"))
111
+ ) {
112
+ return text.slice(1, -1);
113
+ }
114
+ return text;
115
+ }
116
+
117
+ function parseInlineArray(value) {
118
+ const inner = String(value ?? '').trim().slice(1, -1).trim();
119
+ if (inner === '') return [];
120
+ const items = [];
121
+ let current = '';
122
+ let quote = null;
123
+
124
+ for (let i = 0; i < inner.length; i += 1) {
125
+ const ch = inner[i];
126
+ if (quote) {
127
+ if (ch === quote && inner[i - 1] !== '\\') quote = null;
128
+ current += ch;
129
+ continue;
130
+ }
131
+ if (ch === '"' || ch === "'") {
132
+ quote = ch;
133
+ current += ch;
134
+ continue;
135
+ }
136
+ if (ch === ',') {
137
+ items.push(parseScalar(current));
138
+ current = '';
139
+ continue;
140
+ }
141
+ current += ch;
142
+ }
143
+
144
+ if (current !== '') items.push(parseScalar(current));
145
+ return items;
146
+ }
147
+
148
+ function yamlParse(text) {
149
+ const source = String(text ?? '');
150
+ const result = {};
151
+ for (const rawLine of source.split(/\r?\n/)) {
152
+ const line = rawLine.trim();
153
+ if (!line || line.startsWith('#')) continue;
154
+ const idx = line.indexOf(':');
155
+ if (idx < 0) continue;
156
+ const key = line.slice(0, idx).trim();
157
+ const rawValue = line.slice(idx + 1).trim();
158
+ if (!key) continue;
159
+ result[key] = rawValue.startsWith('[') && rawValue.endsWith(']')
160
+ ? parseInlineArray(rawValue)
161
+ : parseScalar(rawValue);
162
+ }
163
+ return result;
164
+ }
165
+
166
+ function yamlStringify(value) {
167
+ if (!value || typeof value !== 'object') return String(value ?? '');
168
+ const lines = [];
169
+ for (const [key, raw] of Object.entries(value)) {
170
+ if (Array.isArray(raw)) {
171
+ lines.push(`${key}: [${raw.map(item => JSON.stringify(String(item))).join(', ')}]`);
172
+ } else if (raw === null) {
173
+ lines.push(`${key}: null`);
174
+ } else if (typeof raw === 'string') {
175
+ lines.push(`${key}: ${JSON.stringify(raw)}`);
176
+ } else {
177
+ lines.push(`${key}: ${String(raw)}`);
178
+ }
179
+ }
180
+ return lines.join('\n');
181
+ }
182
+
183
+ function createYamlShim() {
184
+ const yaml = {
185
+ parse: yamlParse,
186
+ stringify: yamlStringify,
187
+ };
188
+ yaml.YAML = yaml;
189
+ yaml.default = yaml;
190
+ return yaml;
191
+ }
192
+
76
193
  function createFakeRequire(realRequire) {
194
+ const realChild = realRequire('child_process');
77
195
  const realVm = realRequire('vm');
78
196
 
79
197
  function injectBunIntoContext(context) {
80
198
  if (!context || typeof context !== 'object') return context;
81
199
  try {
82
- if (!Object.prototype.hasOwnProperty.call(context, 'Bun')) {
200
+ if (!Object.prototype.hasOwnProperty.call(context, '__claudeYaml')) {
201
+ Object.defineProperty(context, '__claudeYaml', {
202
+ value: globalThis.__claudeYaml,
203
+ configurable: true,
204
+ writable: true,
205
+ });
206
+ }
207
+ if (!Object.prototype.hasOwnProperty.call(context, '__claudeBunShim')) {
208
+ Object.defineProperty(context, '__claudeBunShim', {
209
+ value: globalThis.__claudeBunShim,
210
+ configurable: true,
211
+ writable: true,
212
+ });
213
+ }
214
+ if (!Object.prototype.hasOwnProperty.call(context, '__claudeBun')) {
215
+ Object.defineProperty(context, '__claudeBun', {
216
+ value: globalThis.__claudeBunShim,
217
+ configurable: true,
218
+ writable: true,
219
+ });
220
+ }
221
+ if (Object.prototype.hasOwnProperty.call(context, 'Bun')) {
222
+ if (context.Bun && typeof context.Bun === 'object' && context.Bun !== globalThis.Bun) {
223
+ try {
224
+ context.Bun = globalThis.Bun;
225
+ } catch {
226
+ Object.defineProperty(context, 'Bun', {
227
+ value: globalThis.Bun,
228
+ configurable: true,
229
+ writable: true,
230
+ });
231
+ }
232
+ }
233
+ if (!context.Bun || typeof context.Bun !== 'object') {
234
+ Object.defineProperty(context, 'Bun', {
235
+ value: globalThis.Bun,
236
+ configurable: true,
237
+ writable: true,
238
+ });
239
+ }
240
+ } else {
83
241
  Object.defineProperty(context, 'Bun', {
84
242
  value: globalThis.Bun,
85
243
  configurable: true,
@@ -90,23 +248,6 @@ function createFakeRequire(realRequire) {
90
248
  return context;
91
249
  }
92
250
 
93
- if (!realVm.__bunShimPatched) {
94
- const origCreateContext = realVm.createContext.bind(realVm);
95
- const origRunInNewContext = realVm.runInNewContext.bind(realVm);
96
- realVm.createContext = (ctx, ...rest) => origCreateContext(injectBunIntoContext(ctx), ...rest);
97
- realVm.runInNewContext = (code, ctx, ...rest) => origRunInNewContext(code, injectBunIntoContext(ctx), ...rest);
98
- const ScriptProto = realVm.Script && realVm.Script.prototype;
99
- if (ScriptProto && !ScriptProto.__bunShimPatched) {
100
- const origRunInContext = ScriptProto.runInContext;
101
- const origRunInNewCtx = ScriptProto.runInNewContext;
102
- ScriptProto.runInContext = function(ctx, ...rest) { return origRunInContext.call(this, injectBunIntoContext(ctx), ...rest); };
103
- ScriptProto.runInNewContext = function(ctx, ...rest) { return origRunInNewCtx.call(this, injectBunIntoContext(ctx), ...rest); };
104
- Object.defineProperty(ScriptProto, '__bunShimPatched', { value: true });
105
- }
106
- Object.defineProperty(realVm, '__bunShimPatched', { value: true });
107
- }
108
-
109
- const realChild = realRequire('child_process');
110
251
  function rewriteArgs(args) {
111
252
  if (
112
253
  Array.isArray(args) &&
@@ -119,6 +260,18 @@ function createFakeRequire(realRequire) {
119
260
  return args;
120
261
  }
121
262
 
263
+ const guardedChild = createGuardedChildProcess(
264
+ {
265
+ spawn: (...args) => realChild.spawn(...rewriteArgs(args)),
266
+ execFile: (...args) => realChild.execFile(...args),
267
+ exec: (...args) => realChild.exec(...args),
268
+ spawnSync: (...args) => realChild.spawnSync(...rewriteArgs(args)),
269
+ execFileSync: (...args) => realChild.execFileSync(...args),
270
+ execSync: (...args) => realChild.execSync(...args),
271
+ },
272
+ value => process.stderr.write(value),
273
+ );
274
+
122
275
  return function fakeRequire(id) {
123
276
  if (id === 'ws') {
124
277
  class WS {
@@ -132,18 +285,56 @@ function createFakeRequire(realRequire) {
132
285
  return { default: WS, WebSocket: WS };
133
286
  }
134
287
 
288
+ if (id === 'vm' || id === 'node:vm') {
289
+ if (!realVm.__claudeBunShimPatched) {
290
+ const originalCreateContext = realVm.createContext.bind(realVm);
291
+ const originalRunInNewContext = realVm.runInNewContext.bind(realVm);
292
+ const originalRunInContext = realVm.runInContext.bind(realVm);
293
+ const originalRunInThisContext = realVm.runInThisContext && realVm.runInThisContext.bind(realVm);
294
+ const scriptProto = realVm.Script && realVm.Script.prototype;
295
+
296
+ realVm.createContext = (contextObject, ...rest) =>
297
+ originalCreateContext(injectBunIntoContext(contextObject), ...rest);
298
+ realVm.runInNewContext = (code, contextObject, ...rest) =>
299
+ originalRunInNewContext(code, injectBunIntoContext(contextObject), ...rest);
300
+ realVm.runInContext = (code, contextObject, ...rest) =>
301
+ originalRunInContext(code, injectBunIntoContext(contextObject), ...rest);
302
+ if (originalRunInThisContext) {
303
+ realVm.runInThisContext = (code, ...rest) => originalRunInThisContext(code, ...rest);
304
+ }
305
+
306
+ if (scriptProto && !scriptProto.__claudeBunShimPatched) {
307
+ const originalScriptRunInContext = scriptProto.runInContext;
308
+ const originalScriptRunInNewContext = scriptProto.runInNewContext;
309
+ const originalScriptRunInThisContext = scriptProto.runInThisContext;
310
+
311
+ scriptProto.runInContext = function (contextObject, ...rest) {
312
+ return originalScriptRunInContext.call(this, injectBunIntoContext(contextObject), ...rest);
313
+ };
314
+ scriptProto.runInNewContext = function (contextObject, ...rest) {
315
+ return originalScriptRunInNewContext.call(this, injectBunIntoContext(contextObject), ...rest);
316
+ };
317
+ if (originalScriptRunInThisContext) {
318
+ scriptProto.runInThisContext = function (...rest) {
319
+ return originalScriptRunInThisContext.call(this, ...rest);
320
+ };
321
+ }
322
+
323
+ Object.defineProperty(scriptProto, '__claudeBunShimPatched', { value: true });
324
+ }
325
+
326
+ Object.defineProperty(realVm, '__claudeBunShimPatched', { value: true });
327
+ }
328
+ return realVm;
329
+ }
330
+
135
331
  if (id === 'child_process') {
136
- return {
137
- spawn: (...args) => realChild.spawn(...rewriteArgs(args)),
138
- execFile: (...args) => realChild.execFile(...args),
139
- exec: (...args) => realChild.exec(...args),
140
- spawnSync: (...args) => realChild.spawnSync(...rewriteArgs(args)),
141
- execFileSync: (...args) => realChild.execFileSync(...args),
142
- execSync: (...args) => realChild.execSync(...args),
143
- };
332
+ return guardedChild;
144
333
  }
145
334
 
146
- if (id === 'vm') return realVm;
335
+ if (id === 'node:child_process') {
336
+ return guardedChild;
337
+ }
147
338
 
148
339
  if (id.startsWith('/$bunfs/root/')) {
149
340
  throw new Error('bunfs require blocked: ' + id);
@@ -153,511 +344,411 @@ function createFakeRequire(realRequire) {
153
344
  };
154
345
  }
155
346
 
156
- const ansiPattern =
157
- /[\u001B\u009B][[\]()#;?]*(?:(?:(?:;[-a-zA-Z\d\/\#&.:=?%@~_]+)*|[a-zA-Z\d]+(?:;[-a-zA-Z\d\/\#&.:=?%@~_]*)*)?(?:\u0007|\u001B\u005C|\u009C)|(?:(?:\d{1,4}(?:;\d{0,4})*)?[\dA-PR-TZcf-nq-uy=><~]))/g;
158
- const ansiPatternSingle = new RegExp(ansiPattern.source);
159
- const debugBunShim = process.env.CLAUDE_TERMUX_DEBUG_BUN_SHIM === '1';
347
+ async function main() {
348
+ const extractedFile = ensureEntryFile();
349
+ const code = fs.readFileSync(extractedFile, 'utf8');
350
+ const patchedCode = code.replace(
351
+ /^function\(exports, require, module, __filename, __dirname\) \{/,
352
+ 'function(exports, require, module, __filename, __dirname) {var __claudeBun = globalThis.__claudeBunShim;',
353
+ ).replace(
354
+ /\btypeof Bun\b/g,
355
+ 'typeof __claudeBun',
356
+ ).replace(
357
+ /\bBun\./g,
358
+ '__claudeBun.',
359
+ ).replace(
360
+ /function t5q\(q\)\{return Bun\.YAML\.parse\(q\)\}/g,
361
+ 'function t5q(q){return globalThis.__claudeYaml.parse(q)}',
362
+ ).replace(
363
+ /function VK6\(q\)\{return Bun\.YAML\.stringify\(q,null,2\)\+`/g,
364
+ 'function VK6(q){return globalThis.__claudeYaml.stringify(q,null,2)+`',
365
+ );
366
+ const fn = eval('(' + patchedCode.replace(/\)\s*$/, '') + ')');
160
367
 
161
- function stripANSI(text) {
162
- if (typeof text !== 'string' || text.length === 0) return '';
163
- return text.replace(ansiPattern, '');
164
- }
368
+ const originalArgv = process.argv.slice();
369
+ const originalExit = process.exit;
370
+ const originalBun = process.versions.bun;
371
+ const hadGlobalBun = Object.prototype.hasOwnProperty.call(globalThis, 'Bun');
372
+ const originalGlobalBun = globalThis.Bun;
373
+ const asyncErrors = [];
165
374
 
166
- function codePointWidth(codePoint) {
167
- if (
168
- codePoint <= 0x1f ||
169
- (codePoint >= 0x7f && codePoint <= 0x9f) ||
170
- (codePoint >= 0x300 && codePoint <= 0x36f) ||
171
- (codePoint >= 0x200b && codePoint <= 0x200f) ||
172
- codePoint === 0xfeff ||
173
- (codePoint >= 0xfe00 && codePoint <= 0xfe0f)
174
- ) {
175
- return 0;
375
+ globalThis.__claudeYaml = createYamlShim();
376
+ if (!globalThis.__claudeBunShim || typeof globalThis.__claudeBunShim !== 'object') {
377
+ globalThis.__claudeBunShim = {};
176
378
  }
177
-
178
- if (
179
- (codePoint >= 0x1100 && codePoint <= 0x115f) ||
180
- (codePoint >= 0x2329 && codePoint <= 0x232a) ||
181
- (codePoint >= 0x2e80 && codePoint <= 0xa4cf && codePoint !== 0x303f) ||
182
- (codePoint >= 0xac00 && codePoint <= 0xd7a3) ||
183
- (codePoint >= 0xf900 && codePoint <= 0xfaff) ||
184
- (codePoint >= 0xfe10 && codePoint <= 0xfe19) ||
185
- (codePoint >= 0xfe30 && codePoint <= 0xfe6f) ||
186
- (codePoint >= 0xff00 && codePoint <= 0xff60) ||
187
- (codePoint >= 0xffe0 && codePoint <= 0xffe6) ||
188
- (codePoint >= 0x1f300 && codePoint <= 0x1faf8) ||
189
- (codePoint >= 0x20000 && codePoint <= 0x3fffd)
190
- ) {
191
- return 2;
379
+ const fakeRequire = createFakeRequire(require);
380
+ function onAsyncError(error) {
381
+ asyncErrors.push(error);
192
382
  }
193
383
 
194
- return 1;
195
- }
384
+ try {
385
+ process.once('uncaughtException', onAsyncError);
386
+ process.once('unhandledRejection', onAsyncError);
387
+ Object.defineProperty(process.versions, 'bun', { value: '1.1.8', configurable: true });
388
+ const _realChild = require('child_process');
389
+ globalThis.Bun = {
390
+ version: '1.1.8',
391
+ stringWidth,
392
+ which: (cmd) => {
393
+ try {
394
+ return _realChild.execFileSync('which', [String(cmd)], { encoding: 'utf8' }).trim() || null;
395
+ } catch { return null; }
396
+ },
397
+ semver: (() => {
398
+ const _cmp = (a, b) => {
399
+ const pa = String(a).replace(/[^0-9.]/g,'').split('.').map(Number);
400
+ const pb = String(b).replace(/[^0-9.]/g,'').split('.').map(Number);
401
+ for (let i = 0; i < 3; i++) { const d = (pa[i]||0)-(pb[i]||0); if (d) return d > 0 ? 1 : -1; }
402
+ return 0;
403
+ };
404
+ const _satisfies = (ver, range) => {
405
+ const s = String(range).trim();
406
+ const m = s.match(/^([><=!]{1,2})\s*([\d]+(?:\.[\d]+){0,2})$/);
407
+ if (m) {
408
+ const op = m[1], c = _cmp(ver, m[2]);
409
+ if (op === '>') return c > 0;
410
+ if (op === '>=') return c >= 0;
411
+ if (op === '<') return c < 0;
412
+ if (op === '<=') return c <= 0;
413
+ if (op === '=' || op === '==') return c === 0;
414
+ if (op === '!=') return c !== 0;
415
+ }
416
+ if (/^[\d]+(?:\.[\d]+){0,2}$/.test(s)) return _cmp(ver, s) === 0;
417
+ return false;
418
+ };
419
+ return {
420
+ order: (a, b) => _cmp(a, b),
421
+ compare: (a, b) => _cmp(a, b),
422
+ satisfies: (ver, range) => _satisfies(ver, range),
423
+ gt: (a, b) => _cmp(a, b) > 0,
424
+ gte: (a, b) => _cmp(a, b) >= 0,
425
+ lt: (a, b) => _cmp(a, b) < 0,
426
+ lte: (a, b) => _cmp(a, b) <= 0,
427
+ };
428
+ })(),
429
+ YAML: globalThis.__claudeYaml,
430
+ };
431
+ Object.assign(globalThis.__claudeBunShim, globalThis.Bun);
432
+ if (typeof globalThis.__claudeBunShim.gc !== 'function') {
433
+ globalThis.__claudeBunShim.gc = () => {};
434
+ }
435
+ globalThis.__claudeBun = globalThis.__claudeBunShim;
436
+ globalThis.Bun = globalThis.__claudeBunShim;
437
+ process.argv = ['node', extractedFile, ...argv];
438
+ process.exit = code => {
439
+ throw new RequestedExit(code);
440
+ };
196
441
 
197
- function stringWidth(value) {
198
- const text = stripANSI(typeof value === 'string' ? value : String(value ?? ''));
199
- let width = 0;
200
- for (const char of text) {
201
- const codePoint = char.codePointAt(0);
202
- width += codePointWidth(codePoint);
442
+ const moduleLike = { exports: {} };
443
+ const maybePromise = fn(moduleLike.exports, fakeRequire, moduleLike, extractedFile, workdir);
444
+ if (maybePromise && typeof maybePromise.then === 'function') await maybePromise;
445
+ await new Promise(resolve => setTimeout(resolve, 5000));
446
+ if (asyncErrors.length > 0) throw asyncErrors[0];
447
+ } catch (error) {
448
+ if (error instanceof RequestedExit) {
449
+ process.exitCode = error.code;
450
+ return;
451
+ }
452
+ throw error;
453
+ } finally {
454
+ process.removeListener('uncaughtException', onAsyncError);
455
+ process.removeListener('unhandledRejection', onAsyncError);
456
+ process.argv = originalArgv;
457
+ process.exit = originalExit;
458
+ try {
459
+ if (originalBun === undefined) {
460
+ delete process.versions.bun;
461
+ } else {
462
+ Object.defineProperty(process.versions, 'bun', { value: originalBun, configurable: true });
463
+ }
464
+ } catch {}
465
+ delete globalThis.__claudeYaml;
466
+ delete globalThis.__claudeBunShim;
467
+ delete globalThis.__claudeBun;
468
+ if (hadGlobalBun) globalThis.Bun = originalGlobalBun;
469
+ else delete globalThis.Bun;
203
470
  }
204
- return width;
205
471
  }
206
472
 
207
- function toHashBytes(value) {
208
- if (Buffer.isBuffer(value)) return Buffer.from(value);
209
- if (value instanceof Uint8Array) return Buffer.from(value.buffer, value.byteOffset, value.byteLength);
210
- if (value instanceof ArrayBuffer) return Buffer.from(value);
211
- if (ArrayBuffer.isView(value)) {
212
- return Buffer.from(value.buffer, value.byteOffset, value.byteLength);
473
+ main().catch(error => {
474
+ if (error && error.code === 'CLAUDE_TERMUX_OFFICIAL_UPDATE_BLOCKED') {
475
+ console.error(BLOCK_MESSAGE);
476
+ process.exit(error.status || 1);
213
477
  }
214
- return Buffer.from(String(value ?? ''));
215
- }
216
-
217
- function hashValue(value, seed = 0) {
218
- const FNV_OFFSET_BASIS_64 = 0xcbf29ce484222325n;
219
- const FNV_PRIME_64 = 0x100000001b3n;
220
- const MASK_64 = 0xffffffffffffffffn;
478
+ console.error(error && error.stack ? error.stack : String(error));
479
+ process.exit(1);
480
+ });
481
+ NODE
482
+ export CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC="${CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC:-1}"
483
+ export ENABLE_CLAUDEAI_MCP_SERVERS="${ENABLE_CLAUDEAI_MCP_SERVERS:-0}"
484
+ export CLAUDE_CODE_SIMPLE="${CLAUDE_CODE_SIMPLE:-0}"
485
+ node "$_helper" "$@" </dev/null
486
+ _status=$?
487
+ rm -f "$_helper"
488
+ trap - EXIT HUP INT TERM
489
+ exit "$_status"
490
+ else
491
+ _bootstrap=$(mktemp "${TMPDIR:-/tmp}/claude-bootstrap.XXXXXX.js")
492
+ trap 'rm -f "$_bootstrap"' EXIT HUP INT TERM
493
+ cat <<'NODE' > "$_bootstrap"
494
+ const fs = require('fs');
495
+ const path = require('path');
496
+ const {
497
+ BLOCK_MESSAGE,
498
+ createGuardedChildProcess,
499
+ } = require(path.join(process.env.CLAUDE_TERMUX_PACKAGE_DIR, 'lib', 'native-update-guard.js'));
221
500
 
222
- const seedNumber = typeof seed === 'bigint' ? Number(seed) : Number(seed);
223
- const seedValue = Number.isFinite(seedNumber) ? Math.trunc(seedNumber) : 0;
224
- let result = BigInt.asUintN(64, FNV_OFFSET_BASIS_64 ^ BigInt(seedValue));
501
+ const sourceBin = process.env.SOURCE_BIN;
502
+ const workdir = process.env.WORKDIR;
503
+ const entryJsOffset = Number(process.env.ENTRY_JS_OFFSET);
504
+ const entryEndOffset = Number(process.env.ENTRY_END_OFFSET);
505
+ const argv = process.argv.slice(2);
225
506
 
226
- const bytes = toHashBytes(value);
227
- for (const byte of bytes) {
228
- result ^= BigInt(byte);
229
- result = (result * FNV_PRIME_64) & MASK_64;
507
+ class RequestedExit extends Error {
508
+ constructor(code) {
509
+ super(`process.exit ${code}`);
510
+ this.name = 'RequestedExit';
511
+ this.code = code;
230
512
  }
231
-
232
- return BigInt(result);
233
513
  }
234
514
 
235
- function which(cmd) {
236
- const fs = require('fs');
237
- const path = require('path');
238
-
239
- if (typeof cmd !== 'string' || cmd.length === 0) return null;
240
-
241
- const isExecutable = candidate => {
242
- try {
243
- fs.accessSync(candidate, fs.constants.X_OK);
244
- const stat = fs.statSync(candidate);
245
- return stat.isFile();
246
- } catch {
247
- return false;
248
- }
249
- };
515
+ function ensureEntryFile() {
516
+ const extractedFile = path.join(workdir, `cli.${entryJsOffset}.${entryEndOffset}.bare-path.js`);
517
+ const len = entryEndOffset - entryJsOffset;
518
+ if (!(len > 0)) throw new Error('invalid replay offsets');
250
519
 
251
- if (cmd.includes(path.sep)) {
252
- return isExecutable(cmd) ? path.resolve(cmd) : null;
253
- }
520
+ const fd = fs.openSync(sourceBin, 'r');
521
+ const buf = Buffer.alloc(len);
522
+ fs.readSync(fd, buf, 0, len, entryJsOffset);
523
+ fs.closeSync(fd);
254
524
 
255
- const searchPath = process.env.PATH || '';
256
- for (const entry of searchPath.split(path.delimiter)) {
257
- if (!entry) continue;
258
- const candidate = path.join(entry, cmd);
259
- if (isExecutable(candidate)) return candidate;
260
- }
261
- return null;
525
+ fs.writeFileSync(extractedFile, buf.toString('utf8').replace(/[\0\s]+$/g, ''));
526
+ return extractedFile;
262
527
  }
263
528
 
264
- function wrapAnsi(str, columns, options) {
265
- const input = typeof str === 'string' ? str : String(str ?? '');
266
- const widthLimit = Number(columns);
267
- if (!Number.isFinite(widthLimit) || widthLimit <= 0) return input;
268
-
269
- const wordWrap = !options || options.wordWrap !== false;
270
- const hard = !!(options && options.hard);
271
-
272
- if (!wordWrap || hard) {
273
- const result = [];
529
+ function stringWidth(value) {
530
+ const text = String(value ?? '');
531
+ if (typeof Intl !== 'undefined' && typeof Intl.Segmenter === 'function') {
532
+ const segmenter = new Intl.Segmenter('en', { granularity: 'grapheme' });
274
533
  let width = 0;
275
-
276
- for (let i = 0; i < input.length; ) {
277
- const char = input[i];
278
-
279
- if (char === '\u001b' || char === '\u009b') {
280
- const match = input.slice(i).match(ansiPatternSingle);
281
- if (match && match.index === 0) {
282
- result.push(match[0]);
283
- i += match[0].length;
284
- continue;
285
- }
286
- }
287
-
288
- if (char === '\n') {
289
- result.push(char);
290
- width = 0;
291
- i += 1;
292
- continue;
293
- }
294
-
295
- const codePoint = input.codePointAt(i);
296
- const charText = String.fromCodePoint(codePoint);
297
- const charWidth = codePointWidth(codePoint);
298
-
299
- if (width > 0 && width + charWidth > widthLimit) {
300
- result.push('\n');
301
- width = 0;
302
- }
303
-
304
- result.push(charText);
305
- width += charWidth;
306
- i += charText.length;
307
- }
308
-
309
- return result.join('');
534
+ for (const _segment of segmenter.segment(text)) width += 1;
535
+ return width;
310
536
  }
537
+ return Array.from(text).length;
538
+ }
311
539
 
312
- const result = [];
313
- let line = '';
314
- let lineWidth = 0;
315
- let pendingSpaces = '';
316
-
317
- for (let i = 0; i < input.length; ) {
318
- const char = input[i];
319
-
320
- if (char === '\u001b' || char === '\u009b') {
321
- const match = input.slice(i).match(ansiPatternSingle);
322
- if (match && match.index === 0) {
323
- line += match[0];
324
- i += match[0].length;
325
- continue;
326
- }
327
- }
540
+ function parseScalar(value) {
541
+ const text = String(value ?? '').trim();
542
+ if (text === '') return '';
543
+ if (text === 'true') return true;
544
+ if (text === 'false') return false;
545
+ if (text === 'null' || text === '~') return null;
546
+ if (/^-?(?:0|[1-9]\d*)(?:\.\d+)?$/.test(text)) return Number(text);
547
+ if (
548
+ (text.startsWith('"') && text.endsWith('"')) ||
549
+ (text.startsWith("'") && text.endsWith("'"))
550
+ ) {
551
+ return text.slice(1, -1);
552
+ }
553
+ return text;
554
+ }
328
555
 
329
- if (char === '\n') {
330
- if (line.length > 0) result.push(line);
331
- result.push('\n');
332
- line = '';
333
- lineWidth = 0;
334
- pendingSpaces = '';
335
- i += 1;
556
+ function parseInlineArray(value) {
557
+ const inner = String(value ?? '').trim().slice(1, -1).trim();
558
+ if (inner === '') return [];
559
+ const items = [];
560
+ let current = '';
561
+ let quote = null;
562
+
563
+ for (let i = 0; i < inner.length; i += 1) {
564
+ const ch = inner[i];
565
+ if (quote) {
566
+ if (ch === quote && inner[i - 1] !== '\\') quote = null;
567
+ current += ch;
336
568
  continue;
337
569
  }
338
-
339
- const codePoint = input.codePointAt(i);
340
- const charText = String.fromCodePoint(codePoint);
341
- if (charText === ' ' || charText === '\t') {
342
- pendingSpaces += charText;
343
- i += charText.length;
570
+ if (ch === '"' || ch === "'") {
571
+ quote = ch;
572
+ current += ch;
344
573
  continue;
345
574
  }
346
-
347
- let end = i + charText.length;
348
- while (end < input.length) {
349
- const nextChar = input[end];
350
- if (nextChar === '\n' || nextChar === ' ' || nextChar === '\t' || nextChar === '\u001b' || nextChar === '\u009b') {
351
- break;
352
- }
353
- const nextCodePoint = input.codePointAt(end);
354
- end += String.fromCodePoint(nextCodePoint).length;
355
- }
356
-
357
- const text = input.slice(i, end);
358
- const textWidth = stringWidth(text);
359
- const pendingWidth = pendingSpaces ? stringWidth(pendingSpaces) : 0;
360
-
361
- if (lineWidth > 0 && lineWidth + pendingWidth + textWidth > widthLimit) {
362
- result.push(line);
363
- result.push('\n');
364
- line = '';
365
- lineWidth = 0;
366
- pendingSpaces = '';
575
+ if (ch === ',') {
576
+ items.push(parseScalar(current));
577
+ current = '';
578
+ continue;
367
579
  }
580
+ current += ch;
581
+ }
368
582
 
369
- if (lineWidth > 0 && pendingSpaces) {
370
- line += pendingSpaces;
371
- lineWidth += pendingWidth;
372
- }
373
- pendingSpaces = '';
583
+ if (current !== '') items.push(parseScalar(current));
584
+ return items;
585
+ }
374
586
 
375
- line += text;
376
- lineWidth += textWidth;
377
- i = end;
587
+ function yamlParse(text) {
588
+ const source = String(text ?? '');
589
+ const result = {};
590
+ for (const rawLine of source.split(/\r?\n/)) {
591
+ const line = rawLine.trim();
592
+ if (!line || line.startsWith('#')) continue;
593
+ const idx = line.indexOf(':');
594
+ if (idx < 0) continue;
595
+ const key = line.slice(0, idx).trim();
596
+ const rawValue = line.slice(idx + 1).trim();
597
+ if (!key) continue;
598
+ result[key] = rawValue.startsWith('[') && rawValue.endsWith(']')
599
+ ? parseInlineArray(rawValue)
600
+ : parseScalar(rawValue);
378
601
  }
602
+ return result;
603
+ }
379
604
 
380
- if (pendingSpaces && lineWidth > 0) {
381
- line += pendingSpaces;
605
+ function yamlStringify(value) {
606
+ if (!value || typeof value !== 'object') return String(value ?? '');
607
+ const lines = [];
608
+ for (const [key, raw] of Object.entries(value)) {
609
+ if (Array.isArray(raw)) {
610
+ lines.push(`${key}: [${raw.map(item => JSON.stringify(String(item))).join(', ')}]`);
611
+ } else if (raw === null) {
612
+ lines.push(`${key}: null`);
613
+ } else if (typeof raw === 'string') {
614
+ lines.push(`${key}: ${JSON.stringify(raw)}`);
615
+ } else {
616
+ lines.push(`${key}: ${String(raw)}`);
617
+ }
382
618
  }
383
- if (line.length > 0) result.push(line);
384
-
385
- return result.join('');
619
+ return lines.join('\n');
386
620
  }
387
621
 
388
- const YAML = {
389
- parse(text) {
390
- try {
391
- const lines = String(text).split('\n');
392
- const result = {};
393
- for (const line of lines) {
394
- const m = line.match(/^([^:#]+):\s*(.*)$/);
395
- if (m) result[m[1].trim()] = m[2].trim().replace(/^['"]|['"]$/g, '');
396
- }
397
- return result;
398
- } catch { return {}; }
399
- },
400
- stringify(obj) {
401
- try {
402
- return Object.entries(obj || {}).map(([k, v]) => k + ': ' + v).join('\n') + '\n';
403
- } catch { return ''; }
404
- },
405
- };
406
-
407
- function parseSemverVersion(value) {
408
- const text = String(value ?? '').trim().replace(/^[v=]/, '');
409
- const match = text.match(/^(0|[1-9]\d*)(?:\.(0|[1-9]\d*))?(?:\.(0|[1-9]\d*))?(?:-([0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*))?(?:\+[0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*)?$/);
410
- if (!match) return null;
411
- return {
412
- parts: [match[1], match[2] ?? '0', match[3] ?? '0'].map(Number),
413
- pre: match[4] ? match[4].split('.') : null,
622
+ function createYamlShim() {
623
+ const yaml = {
624
+ parse: yamlParse,
625
+ stringify: yamlStringify,
414
626
  };
627
+ yaml.YAML = yaml;
628
+ yaml.default = yaml;
629
+ return yaml;
415
630
  }
416
631
 
417
- function comparePrerelease(a, b) {
418
- const size = Math.max(a.length, b.length);
419
- for (let i = 0; i < size; i++) {
420
- if (a[i] === undefined) return -1;
421
- if (b[i] === undefined) return 1;
422
- const aNum = /^\d+$/.test(a[i]);
423
- const bNum = /^\d+$/.test(b[i]);
424
- if (aNum && bNum) { const d = Number(a[i]) - Number(b[i]); if (d) return d < 0 ? -1 : 1; }
425
- else if (aNum) return -1;
426
- else if (bNum) return 1;
427
- else if (a[i] < b[i]) return -1;
428
- else if (a[i] > b[i]) return 1;
429
- }
430
- return 0;
431
- }
632
+ function createFakeRequire(realRequire) {
633
+ const realChild = realRequire('child_process');
634
+ const realVm = realRequire('vm');
432
635
 
433
- const semver = {
434
- order(left, right) {
435
- const a = parseSemverVersion(left), b = parseSemverVersion(right);
436
- if (!a || !b) return NaN;
437
- for (let i = 0; i < 3; i++) {
438
- const d = a.parts[i] - b.parts[i];
439
- if (d) return d < 0 ? -1 : 1;
440
- }
441
- if (a.pre && !b.pre) return -1;
442
- if (!a.pre && b.pre) return 1;
443
- if (a.pre && b.pre) return comparePrerelease(a.pre, b.pre);
444
- return 0;
445
- },
446
- satisfies(version, range) {
447
- if (!version || !range) return false;
448
- const v = String(version).replace(/^[v=]/, '');
449
- const clean = String(range).trim();
450
- if (!clean) return false;
451
- if (clean.includes('||')) return clean.split('||').some(r => semver.satisfies(v, r.trim()));
452
- const parts = clean.split(/\s+/).filter(Boolean);
453
- if (parts.length > 1) return parts.every(p => semver.satisfies(v, p));
454
- const caret = clean.match(/^\^([0-9].*)$/);
455
- if (caret) {
456
- const p = parseSemverVersion(caret[1]);
457
- if (!p) return false;
458
- const upper = p.parts[0] > 0 ? (p.parts[0] + 1) + '.0.0'
459
- : p.parts[1] > 0 ? '0.' + (p.parts[1] + 1) + '.0'
460
- : '0.0.' + (p.parts[2] + 1);
461
- return semver.satisfies(v, '>=' + caret[1]) && semver.satisfies(v, '<' + upper);
462
- }
463
- const tilde = clean.match(/^~([0-9].*)$/);
464
- if (tilde) {
465
- const p = parseSemverVersion(tilde[1]);
466
- if (!p) return false;
467
- const original = tilde[1].split('.');
468
- const upper = original.length >= 2
469
- ? p.parts[0] + '.' + (p.parts[1] + 1) + '.0'
470
- : (p.parts[0] + 1) + '.0.0';
471
- return semver.satisfies(v, '>=' + tilde[1]) && semver.satisfies(v, '<' + upper);
472
- }
473
- const m = clean.match(/^([><=!]{1,2})\s*([0-9].*)$/);
474
- if (m) {
475
- const cmp = semver.order(v, m[2]);
476
- if (!Number.isFinite(cmp)) return false;
477
- return m[1] === '>=' ? cmp >= 0 : m[1] === '>' ? cmp > 0 :
478
- m[1] === '<=' ? cmp <= 0 : m[1] === '<' ? cmp < 0 :
479
- m[1] === '=' || m[1] === '==' ? cmp === 0 : m[1] === '!=' ? cmp !== 0 : false;
636
+ function rewriteArgs(args) {
637
+ if (
638
+ Array.isArray(args) &&
639
+ args[0] === 'xdg-open' &&
640
+ Array.isArray(args[1]) &&
641
+ typeof args[1][0] === 'string'
642
+ ) {
643
+ return ['termux-open-url', [args[1][0]], ...args.slice(2)];
480
644
  }
481
- const exact = parseSemverVersion(clean);
482
- return exact ? semver.order(v, clean) === 0 : false;
483
- },
484
- };
485
-
486
- function bunSpawn(argv, options) {
487
- const childProcess = require('child_process');
488
- options = options || {};
489
- if (!Array.isArray(argv) || argv.length === 0) {
490
- throw new TypeError('Bun.spawn expects a non-empty argv array');
491
- }
492
- const command = argv[0];
493
- const args = argv.slice(1);
494
- const terminal = options.terminal || null;
495
-
496
- function resolveStdio(val, fallback) {
497
- if (val === 'ignore' || val === 'inherit' || val === 'pipe') return val;
498
- return fallback;
645
+ return args;
499
646
  }
500
647
 
501
- let stdioSpec;
502
- if (terminal) {
503
- stdioSpec = ['pipe', 'pipe', 'pipe'];
504
- } else if (Array.isArray(options.stdio)) {
505
- stdioSpec = options.stdio.map(function(s) { return resolveStdio(s, 'pipe'); });
506
- } else {
507
- stdioSpec = [
508
- resolveStdio(options.stdin, 'pipe'),
509
- resolveStdio(options.stdout, 'pipe'),
510
- resolveStdio(options.stderr, 'pipe'),
511
- ];
512
- }
648
+ const guardedChild = createGuardedChildProcess(
649
+ {
650
+ spawn: (...args) => realChild.spawn(...rewriteArgs(args)),
651
+ execFile: (...args) => realChild.execFile(...args),
652
+ exec: (...args) => realChild.exec(...args),
653
+ spawnSync: (...args) => realChild.spawnSync(...rewriteArgs(args)),
654
+ execFileSync: (...args) => realChild.execFileSync(...args),
655
+ execSync: (...args) => realChild.execSync(...args),
656
+ },
657
+ value => process.stderr.write(value),
658
+ );
513
659
 
514
- const nodeChild = childProcess.spawn(command, args, {
515
- cwd: options.cwd,
516
- env: options.env || process.env,
517
- detached: options.detached,
518
- windowsHide: options.windowsHide,
519
- stdio: stdioSpec,
520
- });
521
-
522
- if (terminal) {
523
- const fireData = function(chunk) {
524
- if (!terminal._closed && terminal._options && typeof terminal._options.data === 'function') {
525
- terminal._options.data(terminal, Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk));
526
- }
527
- };
528
- if (nodeChild.stdout) nodeChild.stdout.on('data', fireData);
529
- if (nodeChild.stderr) nodeChild.stderr.on('data', fireData);
530
- const origWrite = terminal.write.bind(terminal);
531
- terminal.write = function(data) {
532
- if (nodeChild.stdin && !nodeChild.stdin.destroyed) {
533
- nodeChild.stdin.write(Buffer.isBuffer(data) ? data : Buffer.from(data));
660
+ return function fakeRequire(id) {
661
+ if (id === 'ws') {
662
+ class WS {
663
+ on() {}
664
+ once() {}
665
+ addEventListener() {}
666
+ close() {}
667
+ send() {}
668
+ ping() {}
534
669
  }
535
- return origWrite(data);
536
- };
537
- }
670
+ return { default: WS, WebSocket: WS };
671
+ }
538
672
 
539
- nodeChild.exited = new Promise(function(resolve) {
540
- nodeChild.once('exit', function(code, signal) {
541
- resolve(code != null ? code : (signal ? 1 : 0));
542
- });
543
- });
544
-
545
- function makeTextReader(stream) {
546
- return {
547
- text: function() {
548
- return new Promise(function(resolve, reject) {
549
- if (!stream) return resolve('');
550
- const chunks = [];
551
- stream.on('data', function(chunk) { chunks.push(chunk); });
552
- stream.on('end', function() { resolve(Buffer.concat(chunks).toString('utf8')); });
553
- stream.on('error', reject);
554
- });
555
- },
556
- };
557
- }
558
- if (nodeChild.stdout) Object.assign(nodeChild.stdout, makeTextReader(nodeChild.stdout));
559
- if (nodeChild.stderr) Object.assign(nodeChild.stderr, makeTextReader(nodeChild.stderr));
560
- return nodeChild;
561
- }
673
+ if (id === 'vm' || id === 'node:vm') {
674
+ if (!realVm.__claudeBunShimPatched) {
675
+ const originalCreateContext = realVm.createContext.bind(realVm);
676
+ const originalRunInNewContext = realVm.runInNewContext.bind(realVm);
677
+ const originalRunInContext = realVm.runInContext.bind(realVm);
678
+ const originalRunInThisContext = realVm.runInThisContext && realVm.runInThisContext.bind(realVm);
679
+ const scriptProto = realVm.Script && realVm.Script.prototype;
680
+
681
+ realVm.createContext = (contextObject, ...rest) =>
682
+ originalCreateContext(injectBunIntoContext(contextObject), ...rest);
683
+ realVm.runInNewContext = (code, contextObject, ...rest) =>
684
+ originalRunInNewContext(code, injectBunIntoContext(contextObject), ...rest);
685
+ realVm.runInContext = (code, contextObject, ...rest) =>
686
+ originalRunInContext(code, injectBunIntoContext(contextObject), ...rest);
687
+ if (originalRunInThisContext) {
688
+ realVm.runInThisContext = (code, ...rest) => originalRunInThisContext(code, ...rest);
689
+ }
562
690
 
563
- class TerminalShim {
564
- constructor(options) {
565
- options = options || {};
566
- this._options = options;
567
- this._cols = options.cols || 80;
568
- this._rows = options.rows || 24;
569
- this._closed = false;
570
- }
571
- write(data) {
572
- if (this._closed) return;
573
- if (this._options.data) this._options.data(this, Buffer.isBuffer(data) ? data : Buffer.from(data));
574
- }
575
- resize(cols, rows) {
576
- this._cols = cols;
577
- this._rows = rows;
578
- }
579
- close() {
580
- this._closed = true;
581
- }
582
- }
691
+ if (scriptProto && !scriptProto.__claudeBunShimPatched) {
692
+ const originalScriptRunInContext = scriptProto.runInContext;
693
+ const originalScriptRunInNewContext = scriptProto.runInNewContext;
694
+ const originalScriptRunInThisContext = scriptProto.runInThisContext;
695
+
696
+ scriptProto.runInContext = function (contextObject, ...rest) {
697
+ return originalScriptRunInContext.call(this, injectBunIntoContext(contextObject), ...rest);
698
+ };
699
+ scriptProto.runInNewContext = function (contextObject, ...rest) {
700
+ return originalScriptRunInNewContext.call(this, injectBunIntoContext(contextObject), ...rest);
701
+ };
702
+ if (originalScriptRunInThisContext) {
703
+ scriptProto.runInThisContext = function (...rest) {
704
+ return originalScriptRunInThisContext.call(this, ...rest);
705
+ };
706
+ }
707
+
708
+ Object.defineProperty(scriptProto, '__claudeBunShimPatched', { value: true });
709
+ }
583
710
 
584
- function bunListen(options) {
585
- const net = require('net');
586
- options = options || {};
587
- const sockets = new Set();
588
- const server = net.createServer(function(socket) {
589
- sockets.add(socket);
590
- const connection = {
591
- data: undefined,
592
- write: function(chunk) {
593
- const buffer = Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk);
594
- const ok = socket.write(buffer);
595
- return ok ? buffer.length : 0;
596
- },
597
- end: function(chunk) { socket.end(chunk); },
598
- destroy: function(error) { socket.destroy(error); },
599
- };
600
- socket.on('data', function(chunk) {
601
- if (options.socket && typeof options.socket.data === 'function') {
602
- options.socket.data(connection, chunk);
603
- }
604
- });
605
- socket.on('drain', function() {
606
- if (options.socket && typeof options.socket.drain === 'function') {
607
- options.socket.drain(connection);
608
- }
609
- });
610
- socket.on('close', function() {
611
- sockets.delete(socket);
612
- if (options.socket && typeof options.socket.close === 'function') {
613
- options.socket.close(connection);
614
- }
615
- });
616
- socket.on('error', function(error) {
617
- if (options.socket && typeof options.socket.error === 'function') {
618
- options.socket.error(connection, error);
711
+ Object.defineProperty(realVm, '__claudeBunShimPatched', { value: true });
619
712
  }
620
- });
621
- if (options.socket && typeof options.socket.open === 'function') {
622
- options.socket.open(connection);
713
+ return realVm;
623
714
  }
624
- });
625
- server.listen(options.port || 0, options.hostname || '127.0.0.1');
626
- return {
627
- get port() {
628
- const address = server.address();
629
- return address && typeof address === 'object' ? address.port : 0;
630
- },
631
- stop: function(closeConnections) {
632
- server.close();
633
- if (closeConnections) {
634
- for (const socket of sockets) socket.destroy();
635
- }
636
- },
637
- };
638
- }
639
715
 
640
- class BunTranspiler {
641
- constructor(_options) {}
642
- transformSync(code) { return typeof code === 'string' ? code : ''; }
643
- scanImports(code) {
644
- const imports = [];
645
- const str = String(code);
646
- const reStatic = /(?:^|[^.])import\s+(?:[^'"]+\s+from\s+)?['"]([^'"]+)['"]/gm;
647
- const reDynamic = /import\s*\(\s*['"]([^'"]+)['"]\s*\)/g;
648
- const reRequire = /require\s*\(\s*['"]([^'"]+)['"]\s*\)/g;
649
- let m;
650
- while ((m = reStatic.exec(str)) !== null) imports.push({ path: m[1], kind: 'import-statement' });
651
- while ((m = reDynamic.exec(str)) !== null) imports.push({ path: m[1], kind: 'dynamic-import' });
652
- while ((m = reRequire.exec(str)) !== null) imports.push({ path: m[1], kind: 'require-call' });
653
- return imports;
654
- }
716
+ if (id === 'child_process') {
717
+ return guardedChild;
718
+ }
719
+
720
+ if (id === 'node:child_process') {
721
+ return guardedChild;
722
+ }
723
+
724
+ if (id.startsWith('/$bunfs/root/')) {
725
+ throw new Error('bunfs require blocked: ' + id);
726
+ }
727
+
728
+ return realRequire(id);
729
+ };
655
730
  }
656
731
 
657
732
  async function main() {
658
733
  const extractedFile = ensureEntryFile();
659
734
  const code = fs.readFileSync(extractedFile, 'utf8');
660
- const fn = eval('(' + code);
735
+ const patchedCode = code.replace(
736
+ /^function\(exports, require, module, __filename, __dirname\) \{/,
737
+ 'function(exports, require, module, __filename, __dirname) {var __claudeBun = globalThis.__claudeBunShim;',
738
+ ).replace(
739
+ /\btypeof Bun\b/g,
740
+ 'typeof __claudeBun',
741
+ ).replace(
742
+ /\bBun\./g,
743
+ '__claudeBun.',
744
+ ).replace(
745
+ /function t5q\(q\)\{return Bun\.YAML\.parse\(q\)\}/g,
746
+ 'function t5q(q){return globalThis.__claudeYaml.parse(q)}',
747
+ ).replace(
748
+ /function VK6\(q\)\{return Bun\.YAML\.stringify\(q,null,2\)\+`/g,
749
+ 'function VK6(q){return globalThis.__claudeYaml.stringify(q,null,2)+`',
750
+ );
751
+ const fn = eval('(' + patchedCode.replace(/\)\s*$/, '') + ')');
661
752
 
662
753
  const originalArgv = process.argv.slice();
663
754
  const originalExit = process.exit;
@@ -666,6 +757,10 @@ async function main() {
666
757
  const originalGlobalBun = globalThis.Bun;
667
758
  const asyncErrors = [];
668
759
 
760
+ globalThis.__claudeYaml = createYamlShim();
761
+ if (!globalThis.__claudeBunShim || typeof globalThis.__claudeBunShim !== 'object') {
762
+ globalThis.__claudeBunShim = {};
763
+ }
669
764
  const fakeRequire = createFakeRequire(require);
670
765
  function onAsyncError(error) {
671
766
  asyncErrors.push(error);
@@ -675,38 +770,55 @@ async function main() {
675
770
  process.once('uncaughtException', onAsyncError);
676
771
  process.once('unhandledRejection', onAsyncError);
677
772
  Object.defineProperty(process.versions, 'bun', { value: '1.1.8', configurable: true });
678
- const BunShim = {
773
+ const _realChild = require('child_process');
774
+ globalThis.Bun = {
679
775
  version: '1.1.8',
680
776
  stringWidth,
681
- hash: hashValue,
682
- which,
683
- spawn: bunSpawn,
684
- wrapAnsi,
685
- stripANSI,
686
- semver,
687
- Terminal: TerminalShim,
688
- listen: bunListen,
689
- Transpiler: BunTranspiler,
690
- YAML,
691
- gc: (sync) => {
777
+ which: (cmd) => {
692
778
  try {
693
- if (typeof global.gc === 'function') global.gc(sync === false ? false : true);
694
- } catch {}
779
+ return _realChild.execFileSync('which', [String(cmd)], { encoding: 'utf8' }).trim() || null;
780
+ } catch { return null; }
695
781
  },
696
- generateHeapSnapshot: () => Buffer.alloc(0),
697
- stdin: { stream: null },
698
- embeddedFiles: [],
782
+ semver: (() => {
783
+ const _cmp = (a, b) => {
784
+ const pa = String(a).replace(/[^0-9.]/g,'').split('.').map(Number);
785
+ const pb = String(b).replace(/[^0-9.]/g,'').split('.').map(Number);
786
+ for (let i = 0; i < 3; i++) { const d = (pa[i]||0)-(pb[i]||0); if (d) return d > 0 ? 1 : -1; }
787
+ return 0;
788
+ };
789
+ const _satisfies = (ver, range) => {
790
+ const s = String(range).trim();
791
+ const m = s.match(/^([><=!]{1,2})\s*([\d]+(?:\.[\d]+){0,2})$/);
792
+ if (m) {
793
+ const op = m[1], c = _cmp(ver, m[2]);
794
+ if (op === '>') return c > 0;
795
+ if (op === '>=') return c >= 0;
796
+ if (op === '<') return c < 0;
797
+ if (op === '<=') return c <= 0;
798
+ if (op === '=' || op === '==') return c === 0;
799
+ if (op === '!=') return c !== 0;
800
+ }
801
+ if (/^[\d]+(?:\.[\d]+){0,2}$/.test(s)) return _cmp(ver, s) === 0;
802
+ return false;
803
+ };
804
+ return {
805
+ order: (a, b) => _cmp(a, b),
806
+ compare: (a, b) => _cmp(a, b),
807
+ satisfies: (ver, range) => _satisfies(ver, range),
808
+ gt: (a, b) => _cmp(a, b) > 0,
809
+ gte: (a, b) => _cmp(a, b) >= 0,
810
+ lt: (a, b) => _cmp(a, b) < 0,
811
+ lte: (a, b) => _cmp(a, b) <= 0,
812
+ };
813
+ })(),
814
+ YAML: globalThis.__claudeYaml,
699
815
  };
700
- const BunProxy = new Proxy(BunShim, {
701
- get(target, key, receiver) {
702
- if (!(key in target) && typeof key !== 'symbol' && debugBunShim) {
703
- console.error('[BunShim missing]', key);
704
- }
705
- return Reflect.get(target, key, receiver);
706
- },
707
- });
708
- globalThis.Bun = BunProxy;
709
-
816
+ Object.assign(globalThis.__claudeBunShim, globalThis.Bun);
817
+ if (typeof globalThis.__claudeBunShim.gc !== 'function') {
818
+ globalThis.__claudeBunShim.gc = () => {};
819
+ }
820
+ globalThis.__claudeBun = globalThis.__claudeBunShim;
821
+ globalThis.Bun = globalThis.__claudeBunShim;
710
822
  process.argv = ['node', extractedFile, ...argv];
711
823
  process.exit = code => {
712
824
  throw new RequestedExit(code);
@@ -715,7 +827,8 @@ async function main() {
715
827
  const moduleLike = { exports: {} };
716
828
  const maybePromise = fn(moduleLike.exports, fakeRequire, moduleLike, extractedFile, workdir);
717
829
  if (maybePromise && typeof maybePromise.then === 'function') await maybePromise;
718
- await new Promise(resolve => setTimeout(resolve, 200));
830
+ const _waitMs = Number(process.env.CLAUDE_TERMUX_PRINT_WAIT_MS || 200);
831
+ await new Promise(resolve => setTimeout(resolve, _waitMs));
719
832
  if (asyncErrors.length > 0) throw asyncErrors[0];
720
833
  } catch (error) {
721
834
  if (error instanceof RequestedExit) {
@@ -735,13 +848,27 @@ async function main() {
735
848
  Object.defineProperty(process.versions, 'bun', { value: originalBun, configurable: true });
736
849
  }
737
850
  } catch {}
851
+ delete globalThis.__claudeYaml;
852
+ delete globalThis.__claudeBunShim;
853
+ delete globalThis.__claudeBun;
854
+ if (hadGlobalBun) globalThis.Bun = originalGlobalBun;
738
855
  }
739
856
  }
740
857
 
741
- main().then(() => {
742
- process.exit(process.exitCode ?? 0);
743
- }).catch(error => {
858
+ main().catch(error => {
859
+ if (error && error.code === 'CLAUDE_TERMUX_OFFICIAL_UPDATE_BLOCKED') {
860
+ console.error(BLOCK_MESSAGE);
861
+ process.exit(error.status || 1);
862
+ }
744
863
  console.error(error && error.stack ? error.stack : String(error));
745
864
  process.exit(1);
746
865
  });
747
866
  NODE
867
+ export CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC="${CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC:-1}"
868
+ export ENABLE_CLAUDEAI_MCP_SERVERS="${ENABLE_CLAUDEAI_MCP_SERVERS:-0}"
869
+ node "$_bootstrap" "$@"
870
+ _status=$?
871
+ rm -f "$_bootstrap"
872
+ trap - EXIT HUP INT TERM
873
+ exit "$_status"
874
+ fi