@bash0816/claude-code 2.1.157 → 2.1.159-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;
@@ -73,8 +89,20 @@ function ensureEntryFile() {
73
89
  return extractedFile;
74
90
  }
75
91
 
92
+ function stringWidth(value) {
93
+ const text = String(value ?? '');
94
+ if (typeof Intl !== 'undefined' && typeof Intl.Segmenter === 'function') {
95
+ const segmenter = new Intl.Segmenter('en', { granularity: 'grapheme' });
96
+ let width = 0;
97
+ for (const _segment of segmenter.segment(text)) width += 1;
98
+ return width;
99
+ }
100
+ return Array.from(text).length;
101
+ }
102
+
76
103
  function createFakeRequire(realRequire) {
77
104
  const realChild = realRequire('child_process');
105
+
78
106
  function rewriteArgs(args) {
79
107
  if (
80
108
  Array.isArray(args) &&
@@ -87,6 +115,18 @@ function createFakeRequire(realRequire) {
87
115
  return args;
88
116
  }
89
117
 
118
+ const guardedChild = createGuardedChildProcess(
119
+ {
120
+ spawn: (...args) => realChild.spawn(...rewriteArgs(args)),
121
+ execFile: (...args) => realChild.execFile(...args),
122
+ exec: (...args) => realChild.exec(...args),
123
+ spawnSync: (...args) => realChild.spawnSync(...rewriteArgs(args)),
124
+ execFileSync: (...args) => realChild.execFileSync(...args),
125
+ execSync: (...args) => realChild.execSync(...args),
126
+ },
127
+ value => process.stderr.write(value),
128
+ );
129
+
90
130
  return function fakeRequire(id) {
91
131
  if (id === 'ws') {
92
132
  class WS {
@@ -101,14 +141,11 @@ function createFakeRequire(realRequire) {
101
141
  }
102
142
 
103
143
  if (id === 'child_process') {
104
- return {
105
- spawn: (...args) => realChild.spawn(...rewriteArgs(args)),
106
- execFile: (...args) => realChild.execFile(...args),
107
- exec: (...args) => realChild.exec(...args),
108
- spawnSync: (...args) => realChild.spawnSync(...rewriteArgs(args)),
109
- execFileSync: (...args) => realChild.execFileSync(...args),
110
- execSync: (...args) => realChild.execSync(...args),
111
- };
144
+ return guardedChild;
145
+ }
146
+
147
+ if (id === 'node:child_process') {
148
+ return guardedChild;
112
149
  }
113
150
 
114
151
  if (id.startsWith('/$bunfs/root/')) {
@@ -119,336 +156,181 @@ function createFakeRequire(realRequire) {
119
156
  };
120
157
  }
121
158
 
122
- const ansiPattern =
123
- /[\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;
124
- const ansiPatternSingle = new RegExp(ansiPattern.source);
125
- const debugBunShim = process.env.CLAUDE_TERMUX_DEBUG_BUN_SHIM === '1';
126
-
127
- function stripANSI(text) {
128
- if (typeof text !== 'string' || text.length === 0) return '';
129
- return text.replace(ansiPattern, '');
130
- }
159
+ async function main() {
160
+ const extractedFile = ensureEntryFile();
161
+ const code = fs.readFileSync(extractedFile, 'utf8');
162
+ const fn = eval('(' + code);
131
163
 
132
- function codePointWidth(codePoint) {
133
- if (
134
- codePoint <= 0x1f ||
135
- (codePoint >= 0x7f && codePoint <= 0x9f) ||
136
- (codePoint >= 0x300 && codePoint <= 0x36f) ||
137
- (codePoint >= 0x200b && codePoint <= 0x200f) ||
138
- codePoint === 0xfeff ||
139
- (codePoint >= 0xfe00 && codePoint <= 0xfe0f)
140
- ) {
141
- return 0;
142
- }
164
+ const originalArgv = process.argv.slice();
165
+ const originalExit = process.exit;
166
+ const originalBun = process.versions.bun;
167
+ const hadGlobalBun = Object.prototype.hasOwnProperty.call(globalThis, 'Bun');
168
+ const originalGlobalBun = globalThis.Bun;
169
+ const asyncErrors = [];
143
170
 
144
- if (
145
- (codePoint >= 0x1100 && codePoint <= 0x115f) ||
146
- (codePoint >= 0x2329 && codePoint <= 0x232a) ||
147
- (codePoint >= 0x2e80 && codePoint <= 0xa4cf && codePoint !== 0x303f) ||
148
- (codePoint >= 0xac00 && codePoint <= 0xd7a3) ||
149
- (codePoint >= 0xf900 && codePoint <= 0xfaff) ||
150
- (codePoint >= 0xfe10 && codePoint <= 0xfe19) ||
151
- (codePoint >= 0xfe30 && codePoint <= 0xfe6f) ||
152
- (codePoint >= 0xff00 && codePoint <= 0xff60) ||
153
- (codePoint >= 0xffe0 && codePoint <= 0xffe6) ||
154
- (codePoint >= 0x1f300 && codePoint <= 0x1faf8) ||
155
- (codePoint >= 0x20000 && codePoint <= 0x3fffd)
156
- ) {
157
- return 2;
171
+ const fakeRequire = createFakeRequire(require);
172
+ function onAsyncError(error) {
173
+ asyncErrors.push(error);
158
174
  }
159
175
 
160
- return 1;
161
- }
176
+ try {
177
+ process.once('uncaughtException', onAsyncError);
178
+ process.once('unhandledRejection', onAsyncError);
179
+ Object.defineProperty(process.versions, 'bun', { value: '1.1.8', configurable: true });
180
+ globalThis.Bun = { version: '1.1.8', stringWidth };
181
+ process.argv = ['node', extractedFile, ...argv];
182
+ process.exit = code => {
183
+ throw new RequestedExit(code);
184
+ };
162
185
 
163
- function stringWidth(value) {
164
- const text = stripANSI(typeof value === 'string' ? value : String(value ?? ''));
165
- let width = 0;
166
- for (const char of text) {
167
- const codePoint = char.codePointAt(0);
168
- width += codePointWidth(codePoint);
186
+ const moduleLike = { exports: {} };
187
+ const maybePromise = fn(moduleLike.exports, fakeRequire, moduleLike, extractedFile, workdir);
188
+ if (maybePromise && typeof maybePromise.then === 'function') await maybePromise;
189
+ await new Promise(resolve => setTimeout(resolve, 200));
190
+ if (asyncErrors.length > 0) throw asyncErrors[0];
191
+ } catch (error) {
192
+ if (error instanceof RequestedExit) {
193
+ process.exitCode = error.code;
194
+ return;
195
+ }
196
+ throw error;
197
+ } finally {
198
+ process.removeListener('uncaughtException', onAsyncError);
199
+ process.removeListener('unhandledRejection', onAsyncError);
200
+ process.argv = originalArgv;
201
+ process.exit = originalExit;
202
+ try {
203
+ if (originalBun === undefined) {
204
+ delete process.versions.bun;
205
+ } else {
206
+ Object.defineProperty(process.versions, 'bun', { value: originalBun, configurable: true });
207
+ }
208
+ } catch {}
209
+ if (hadGlobalBun) globalThis.Bun = originalGlobalBun;
210
+ else delete globalThis.Bun;
169
211
  }
170
- return width;
171
212
  }
172
213
 
173
- function toHashBytes(value) {
174
- if (Buffer.isBuffer(value)) return Buffer.from(value);
175
- if (value instanceof Uint8Array) return Buffer.from(value.buffer, value.byteOffset, value.byteLength);
176
- if (value instanceof ArrayBuffer) return Buffer.from(value);
177
- if (ArrayBuffer.isView(value)) {
178
- return Buffer.from(value.buffer, value.byteOffset, value.byteLength);
214
+ main().catch(error => {
215
+ if (error && error.code === 'CLAUDE_TERMUX_OFFICIAL_UPDATE_BLOCKED') {
216
+ console.error(BLOCK_MESSAGE);
217
+ process.exit(error.status || 1);
179
218
  }
180
- return Buffer.from(String(value ?? ''));
181
- }
182
-
183
- function hashValue(value, seed = 0) {
184
- const FNV_OFFSET_BASIS_64 = 0xcbf29ce484222325n;
185
- const FNV_PRIME_64 = 0x100000001b3n;
186
- const MASK_64 = 0xffffffffffffffffn;
219
+ console.error(error && error.stack ? error.stack : String(error));
220
+ process.exit(1);
221
+ });
222
+ NODE
223
+ node "$_helper" "$@" </dev/null
224
+ _status=$?
225
+ rm -f "$_helper"
226
+ trap - EXIT HUP INT TERM
227
+ exit "$_status"
228
+ else
229
+ exec node - "$@" <<'NODE'
230
+ const fs = require('fs');
231
+ const path = require('path');
232
+ const {
233
+ BLOCK_MESSAGE,
234
+ createGuardedChildProcess,
235
+ } = require(path.join(process.env.CLAUDE_TERMUX_PACKAGE_DIR, 'lib', 'native-update-guard.js'));
187
236
 
188
- const seedNumber = typeof seed === 'bigint' ? Number(seed) : Number(seed);
189
- const seedValue = Number.isFinite(seedNumber) ? Math.trunc(seedNumber) : 0;
190
- let result = BigInt.asUintN(64, FNV_OFFSET_BASIS_64 ^ BigInt(seedValue));
237
+ const sourceBin = process.env.SOURCE_BIN;
238
+ const workdir = process.env.WORKDIR;
239
+ const entryJsOffset = Number(process.env.ENTRY_JS_OFFSET);
240
+ const entryEndOffset = Number(process.env.ENTRY_END_OFFSET);
241
+ const argv = process.argv.slice(2);
191
242
 
192
- const bytes = toHashBytes(value);
193
- for (const byte of bytes) {
194
- result ^= BigInt(byte);
195
- result = (result * FNV_PRIME_64) & MASK_64;
243
+ class RequestedExit extends Error {
244
+ constructor(code) {
245
+ super(`process.exit ${code}`);
246
+ this.name = 'RequestedExit';
247
+ this.code = code;
196
248
  }
197
-
198
- return BigInt(result);
199
249
  }
200
250
 
201
- function which(cmd) {
202
- const fs = require('fs');
203
- const path = require('path');
204
-
205
- if (typeof cmd !== 'string' || cmd.length === 0) return null;
251
+ function ensureEntryFile() {
252
+ const extractedFile = path.join(workdir, `cli.${entryJsOffset}.${entryEndOffset}.bare-path.js`);
253
+ if (fs.existsSync(extractedFile)) return extractedFile;
206
254
 
207
- const isExecutable = candidate => {
208
- try {
209
- fs.accessSync(candidate, fs.constants.X_OK);
210
- const stat = fs.statSync(candidate);
211
- return stat.isFile();
212
- } catch {
213
- return false;
214
- }
215
- };
255
+ const len = entryEndOffset - entryJsOffset;
256
+ if (!(len > 0)) throw new Error('invalid replay offsets');
216
257
 
217
- if (cmd.includes(path.sep)) {
218
- return isExecutable(cmd) ? path.resolve(cmd) : null;
219
- }
258
+ const fd = fs.openSync(sourceBin, 'r');
259
+ const buf = Buffer.alloc(len);
260
+ fs.readSync(fd, buf, 0, len, entryJsOffset);
261
+ fs.closeSync(fd);
220
262
 
221
- const searchPath = process.env.PATH || '';
222
- for (const entry of searchPath.split(path.delimiter)) {
223
- if (!entry) continue;
224
- const candidate = path.join(entry, cmd);
225
- if (isExecutable(candidate)) return candidate;
226
- }
227
- return null;
263
+ fs.writeFileSync(extractedFile, buf.toString('utf8').replace(/[\0\s]+$/g, ''));
264
+ return extractedFile;
228
265
  }
229
266
 
230
- function wrapAnsi(str, columns, options) {
231
- const input = typeof str === 'string' ? str : String(str ?? '');
232
- const widthLimit = Number(columns);
233
- if (!Number.isFinite(widthLimit) || widthLimit <= 0) return input;
234
-
235
- const wordWrap = !options || options.wordWrap !== false;
236
- const hard = !!(options && options.hard);
237
-
238
- if (!wordWrap || hard) {
239
- const result = [];
267
+ function stringWidth(value) {
268
+ const text = String(value ?? '');
269
+ if (typeof Intl !== 'undefined' && typeof Intl.Segmenter === 'function') {
270
+ const segmenter = new Intl.Segmenter('en', { granularity: 'grapheme' });
240
271
  let width = 0;
272
+ for (const _segment of segmenter.segment(text)) width += 1;
273
+ return width;
274
+ }
275
+ return Array.from(text).length;
276
+ }
241
277
 
242
- for (let i = 0; i < input.length; ) {
243
- const char = input[i];
244
-
245
- if (char === '\u001b' || char === '\u009b') {
246
- const match = input.slice(i).match(ansiPatternSingle);
247
- if (match && match.index === 0) {
248
- result.push(match[0]);
249
- i += match[0].length;
250
- continue;
251
- }
252
- }
253
-
254
- if (char === '\n') {
255
- result.push(char);
256
- width = 0;
257
- i += 1;
258
- continue;
259
- }
260
-
261
- const codePoint = input.codePointAt(i);
262
- const charText = String.fromCodePoint(codePoint);
263
- const charWidth = codePointWidth(codePoint);
264
-
265
- if (width > 0 && width + charWidth > widthLimit) {
266
- result.push('\n');
267
- width = 0;
268
- }
278
+ function createFakeRequire(realRequire) {
279
+ const realChild = realRequire('child_process');
269
280
 
270
- result.push(charText);
271
- width += charWidth;
272
- i += charText.length;
281
+ function rewriteArgs(args) {
282
+ if (
283
+ Array.isArray(args) &&
284
+ args[0] === 'xdg-open' &&
285
+ Array.isArray(args[1]) &&
286
+ typeof args[1][0] === 'string'
287
+ ) {
288
+ return ['termux-open-url', [args[1][0]], ...args.slice(2)];
273
289
  }
274
-
275
- return result.join('');
290
+ return args;
276
291
  }
277
292
 
278
- const result = [];
279
- let line = '';
280
- let lineWidth = 0;
281
- let pendingSpaces = '';
293
+ const guardedChild = createGuardedChildProcess(
294
+ {
295
+ spawn: (...args) => realChild.spawn(...rewriteArgs(args)),
296
+ execFile: (...args) => realChild.execFile(...args),
297
+ exec: (...args) => realChild.exec(...args),
298
+ spawnSync: (...args) => realChild.spawnSync(...rewriteArgs(args)),
299
+ execFileSync: (...args) => realChild.execFileSync(...args),
300
+ execSync: (...args) => realChild.execSync(...args),
301
+ },
302
+ value => process.stderr.write(value),
303
+ );
282
304
 
283
- for (let i = 0; i < input.length; ) {
284
- const char = input[i];
285
-
286
- if (char === '\u001b' || char === '\u009b') {
287
- const match = input.slice(i).match(ansiPatternSingle);
288
- if (match && match.index === 0) {
289
- line += match[0];
290
- i += match[0].length;
291
- continue;
305
+ return function fakeRequire(id) {
306
+ if (id === 'ws') {
307
+ class WS {
308
+ on() {}
309
+ once() {}
310
+ addEventListener() {}
311
+ close() {}
312
+ send() {}
313
+ ping() {}
292
314
  }
315
+ return { default: WS, WebSocket: WS };
293
316
  }
294
317
 
295
- if (char === '\n') {
296
- if (line.length > 0) result.push(line);
297
- result.push('\n');
298
- line = '';
299
- lineWidth = 0;
300
- pendingSpaces = '';
301
- i += 1;
302
- continue;
303
- }
304
-
305
- const codePoint = input.codePointAt(i);
306
- const charText = String.fromCodePoint(codePoint);
307
- if (charText === ' ' || charText === '\t') {
308
- pendingSpaces += charText;
309
- i += charText.length;
310
- continue;
311
- }
312
-
313
- let end = i + charText.length;
314
- while (end < input.length) {
315
- const nextChar = input[end];
316
- if (nextChar === '\n' || nextChar === ' ' || nextChar === '\t' || nextChar === '\u001b' || nextChar === '\u009b') {
317
- break;
318
- }
319
- const nextCodePoint = input.codePointAt(end);
320
- end += String.fromCodePoint(nextCodePoint).length;
318
+ if (id === 'child_process') {
319
+ return guardedChild;
321
320
  }
322
321
 
323
- const text = input.slice(i, end);
324
- const textWidth = stringWidth(text);
325
- const pendingWidth = pendingSpaces ? stringWidth(pendingSpaces) : 0;
326
-
327
- if (lineWidth > 0 && lineWidth + pendingWidth + textWidth > widthLimit) {
328
- result.push(line);
329
- result.push('\n');
330
- line = '';
331
- lineWidth = 0;
332
- pendingSpaces = '';
322
+ if (id === 'node:child_process') {
323
+ return guardedChild;
333
324
  }
334
325
 
335
- if (lineWidth > 0 && pendingSpaces) {
336
- line += pendingSpaces;
337
- lineWidth += pendingWidth;
326
+ if (id.startsWith('/$bunfs/root/')) {
327
+ throw new Error('bunfs require blocked: ' + id);
338
328
  }
339
- pendingSpaces = '';
340
-
341
- line += text;
342
- lineWidth += textWidth;
343
- i = end;
344
- }
345
329
 
346
- if (pendingSpaces && lineWidth > 0) {
347
- line += pendingSpaces;
348
- }
349
- if (line.length > 0) result.push(line);
350
-
351
- return result.join('');
352
- }
353
-
354
- const YAML = {
355
- parse(text) {
356
- try {
357
- const lines = String(text).split('\n');
358
- const result = {};
359
- for (const line of lines) {
360
- const m = line.match(/^([^:#]+):\s*(.*)$/);
361
- if (m) result[m[1].trim()] = m[2].trim().replace(/^['"]|['"]$/g, '');
362
- }
363
- return result;
364
- } catch { return {}; }
365
- },
366
- stringify(obj) {
367
- try {
368
- return Object.entries(obj || {}).map(([k, v]) => k + ': ' + v).join('\n') + '\n';
369
- } catch { return ''; }
370
- },
371
- };
372
-
373
- function parseSemverVersion(value) {
374
- const text = String(value ?? '').trim().replace(/^[v=]/, '');
375
- 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-]+)*)?$/);
376
- if (!match) return null;
377
- return {
378
- parts: [match[1], match[2] ?? '0', match[3] ?? '0'].map(Number),
379
- pre: match[4] ? match[4].split('.') : null,
330
+ return realRequire(id);
380
331
  };
381
332
  }
382
333
 
383
- function comparePrerelease(a, b) {
384
- const size = Math.max(a.length, b.length);
385
- for (let i = 0; i < size; i++) {
386
- if (a[i] === undefined) return -1;
387
- if (b[i] === undefined) return 1;
388
- const aNum = /^\d+$/.test(a[i]);
389
- const bNum = /^\d+$/.test(b[i]);
390
- if (aNum && bNum) { const d = Number(a[i]) - Number(b[i]); if (d) return d < 0 ? -1 : 1; }
391
- else if (aNum) return -1;
392
- else if (bNum) return 1;
393
- else if (a[i] < b[i]) return -1;
394
- else if (a[i] > b[i]) return 1;
395
- }
396
- return 0;
397
- }
398
-
399
- const semver = {
400
- order(left, right) {
401
- const a = parseSemverVersion(left), b = parseSemverVersion(right);
402
- if (!a || !b) return NaN;
403
- for (let i = 0; i < 3; i++) {
404
- const d = a.parts[i] - b.parts[i];
405
- if (d) return d < 0 ? -1 : 1;
406
- }
407
- if (a.pre && !b.pre) return -1;
408
- if (!a.pre && b.pre) return 1;
409
- if (a.pre && b.pre) return comparePrerelease(a.pre, b.pre);
410
- return 0;
411
- },
412
- satisfies(version, range) {
413
- if (!version || !range) return false;
414
- const v = String(version).replace(/^[v=]/, '');
415
- const clean = String(range).trim();
416
- if (!clean) return false;
417
- if (clean.includes('||')) return clean.split('||').some(r => semver.satisfies(v, r.trim()));
418
- const parts = clean.split(/\s+/).filter(Boolean);
419
- if (parts.length > 1) return parts.every(p => semver.satisfies(v, p));
420
- const caret = clean.match(/^\^([0-9].*)$/);
421
- if (caret) {
422
- const p = parseSemverVersion(caret[1]);
423
- if (!p) return false;
424
- const upper = p.parts[0] > 0 ? (p.parts[0] + 1) + '.0.0'
425
- : p.parts[1] > 0 ? '0.' + (p.parts[1] + 1) + '.0'
426
- : '0.0.' + (p.parts[2] + 1);
427
- return semver.satisfies(v, '>=' + caret[1]) && semver.satisfies(v, '<' + upper);
428
- }
429
- const tilde = clean.match(/^~([0-9].*)$/);
430
- if (tilde) {
431
- const p = parseSemverVersion(tilde[1]);
432
- if (!p) return false;
433
- const original = tilde[1].split('.');
434
- const upper = original.length >= 2
435
- ? p.parts[0] + '.' + (p.parts[1] + 1) + '.0'
436
- : (p.parts[0] + 1) + '.0.0';
437
- return semver.satisfies(v, '>=' + tilde[1]) && semver.satisfies(v, '<' + upper);
438
- }
439
- const m = clean.match(/^([><=!]{1,2})\s*([0-9].*)$/);
440
- if (m) {
441
- const cmp = semver.order(v, m[2]);
442
- if (!Number.isFinite(cmp)) return false;
443
- return m[1] === '>=' ? cmp >= 0 : m[1] === '>' ? cmp > 0 :
444
- m[1] === '<=' ? cmp <= 0 : m[1] === '<' ? cmp < 0 :
445
- m[1] === '=' || m[1] === '==' ? cmp === 0 : m[1] === '!=' ? cmp !== 0 : false;
446
- }
447
- const exact = parseSemverVersion(clean);
448
- return exact ? semver.order(v, clean) === 0 : false;
449
- },
450
- };
451
-
452
334
  async function main() {
453
335
  const extractedFile = ensureEntryFile();
454
336
  const code = fs.readFileSync(extractedFile, 'utf8');
@@ -470,33 +352,7 @@ async function main() {
470
352
  process.once('uncaughtException', onAsyncError);
471
353
  process.once('unhandledRejection', onAsyncError);
472
354
  Object.defineProperty(process.versions, 'bun', { value: '1.1.8', configurable: true });
473
- const BunShim = {
474
- version: '1.1.8',
475
- stringWidth,
476
- hash: hashValue,
477
- which,
478
- wrapAnsi,
479
- stripANSI,
480
- semver,
481
- YAML,
482
- gc: (sync) => {
483
- try {
484
- if (typeof global.gc === 'function') global.gc(sync === false ? false : true);
485
- } catch {}
486
- },
487
- stdin: { stream: null },
488
- embeddedFiles: [],
489
- };
490
- const BunProxy = new Proxy(BunShim, {
491
- get(target, key, receiver) {
492
- if (!(key in target) && typeof key !== 'symbol' && debugBunShim) {
493
- console.error('[BunShim missing]', key);
494
- }
495
- return Reflect.get(target, key, receiver);
496
- },
497
- });
498
- globalThis.Bun = BunProxy;
499
-
355
+ globalThis.Bun = { version: '1.1.8', stringWidth };
500
356
  process.argv = ['node', extractedFile, ...argv];
501
357
  process.exit = code => {
502
358
  throw new RequestedExit(code);
@@ -525,11 +381,18 @@ async function main() {
525
381
  Object.defineProperty(process.versions, 'bun', { value: originalBun, configurable: true });
526
382
  }
527
383
  } catch {}
384
+ if (hadGlobalBun) globalThis.Bun = originalGlobalBun;
385
+ else delete globalThis.Bun;
528
386
  }
529
387
  }
530
388
 
531
389
  main().catch(error => {
390
+ if (error && error.code === 'CLAUDE_TERMUX_OFFICIAL_UPDATE_BLOCKED') {
391
+ console.error(BLOCK_MESSAGE);
392
+ process.exit(error.status || 1);
393
+ }
532
394
  console.error(error && error.stack ? error.stack : String(error));
533
395
  process.exit(1);
534
396
  });
535
397
  NODE
398
+ fi
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bash0816/claude-code",
3
- "version": "2.1.157",
3
+ "version": "2.1.159-1",
4
4
  "description": "Termux-native Claude Code wrapper with audited native replay",
5
5
  "license": "MIT",
6
6
  "bin": {