@bash0816/claude-code 2.1.159-9 → 2.1.161
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +198 -0
- package/README.md +55 -14
- package/bin/claude +2 -2
- package/config/claude-native-audited-versions.json +48 -22
- package/config/claude-termux-release-manifest.json +3 -8
- package/lib/check-updates.js +13 -123
- package/lib/native-update-guard.js +257 -0
- package/lib/native-update-guard.test.js +310 -0
- package/lib/postinstall.js +1 -2
- package/lib/preinstall.js +0 -6
- package/lib/prepare-native.js +79 -9
- package/lib/termux-run-claude-native.sh +638 -511
- package/lib/version-utils.js +24 -0
- package/lib/version-utils.test.js +25 -0
- package/package.json +18 -7
|
@@ -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
|
-
|
|
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, '
|
|
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 === '
|
|
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
|
-
|
|
157
|
-
|
|
158
|
-
const
|
|
159
|
-
const
|
|
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
|
-
|
|
162
|
-
|
|
163
|
-
|
|
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
|
-
|
|
167
|
-
if (
|
|
168
|
-
|
|
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
|
-
|
|
179
|
-
(
|
|
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
|
-
|
|
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
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
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
|
-
|
|
208
|
-
if (
|
|
209
|
-
|
|
210
|
-
|
|
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
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
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
|
-
|
|
223
|
-
|
|
224
|
-
|
|
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
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
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
|
|
236
|
-
const
|
|
237
|
-
const
|
|
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
|
-
|
|
252
|
-
|
|
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
|
-
|
|
256
|
-
|
|
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
|
|
265
|
-
const
|
|
266
|
-
|
|
267
|
-
|
|
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
|
-
|
|
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
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
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
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
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
|
-
|
|
340
|
-
|
|
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
|
-
|
|
348
|
-
|
|
349
|
-
|
|
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
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
}
|
|
373
|
-
pendingSpaces = '';
|
|
583
|
+
if (current !== '') items.push(parseScalar(current));
|
|
584
|
+
return items;
|
|
585
|
+
}
|
|
374
586
|
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
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
|
-
|
|
381
|
-
|
|
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
|
-
|
|
384
|
-
|
|
385
|
-
return result.join('');
|
|
619
|
+
return lines.join('\n');
|
|
386
620
|
}
|
|
387
621
|
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
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
|
|
418
|
-
const
|
|
419
|
-
|
|
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
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
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
|
-
|
|
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
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
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
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
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
|
|
536
|
-
}
|
|
537
|
-
}
|
|
670
|
+
return { default: WS, WebSocket: WS };
|
|
671
|
+
}
|
|
538
672
|
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
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
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
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
|
-
|
|
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
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
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
|
|
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
|
|
773
|
+
const _realChild = require('child_process');
|
|
774
|
+
globalThis.Bun = {
|
|
679
775
|
version: '1.1.8',
|
|
680
776
|
stringWidth,
|
|
681
|
-
|
|
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
|
-
|
|
694
|
-
} catch {}
|
|
779
|
+
return _realChild.execFileSync('which', [String(cmd)], { encoding: 'utf8' }).trim() || null;
|
|
780
|
+
} catch { return null; }
|
|
695
781
|
},
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
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
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
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
|
-
|
|
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().
|
|
742
|
-
|
|
743
|
-
|
|
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
|