@bash0816/claude-code 2.1.157 → 2.1.159-10
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/README.md +17 -23
- package/bin/claude +2 -2
- package/config/claude-native-audited-versions.json +45 -14
- package/config/claude-termux-release-manifest.json +3 -8
- package/lib/check-updates.js +13 -101
- 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 +51 -9
- package/lib/termux-run-claude-native.sh +285 -324
- package/lib/version-utils.js +24 -0
- package/lib/version-utils.test.js +25 -0
- package/package.json +15 -9
|
@@ -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;
|
|
@@ -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
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
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,231 @@ function createFakeRequire(realRequire) {
|
|
|
119
156
|
};
|
|
120
157
|
}
|
|
121
158
|
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
const
|
|
125
|
-
const
|
|
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
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
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
|
-
|
|
145
|
-
|
|
146
|
-
(
|
|
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
|
-
|
|
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
|
+
const _realChild = require('child_process');
|
|
181
|
+
globalThis.Bun = {
|
|
182
|
+
version: '1.1.8',
|
|
183
|
+
stringWidth,
|
|
184
|
+
which: (cmd) => {
|
|
185
|
+
try {
|
|
186
|
+
return _realChild.execFileSync('which', [String(cmd)], { encoding: 'utf8' }).trim() || null;
|
|
187
|
+
} catch { return null; }
|
|
188
|
+
},
|
|
189
|
+
semver: (() => {
|
|
190
|
+
const _cmp = (a, b) => {
|
|
191
|
+
const pa = String(a).replace(/[^0-9.]/g,'').split('.').map(Number);
|
|
192
|
+
const pb = String(b).replace(/[^0-9.]/g,'').split('.').map(Number);
|
|
193
|
+
for (let i = 0; i < 3; i++) { const d = (pa[i]||0)-(pb[i]||0); if (d) return d > 0 ? 1 : -1; }
|
|
194
|
+
return 0;
|
|
195
|
+
};
|
|
196
|
+
const _satisfies = (ver, range) => {
|
|
197
|
+
const s = String(range).trim();
|
|
198
|
+
const m = s.match(/^([><=!]{1,2})\s*([\d]+(?:\.[\d]+){0,2})$/);
|
|
199
|
+
if (m) {
|
|
200
|
+
const op = m[1], c = _cmp(ver, m[2]);
|
|
201
|
+
if (op === '>') return c > 0;
|
|
202
|
+
if (op === '>=') return c >= 0;
|
|
203
|
+
if (op === '<') return c < 0;
|
|
204
|
+
if (op === '<=') return c <= 0;
|
|
205
|
+
if (op === '=' || op === '==') return c === 0;
|
|
206
|
+
if (op === '!=') return c !== 0;
|
|
207
|
+
}
|
|
208
|
+
if (/^[\d]+(?:\.[\d]+){0,2}$/.test(s)) return _cmp(ver, s) === 0;
|
|
209
|
+
return false;
|
|
210
|
+
};
|
|
211
|
+
return {
|
|
212
|
+
order: (a, b) => _cmp(a, b),
|
|
213
|
+
compare: (a, b) => _cmp(a, b),
|
|
214
|
+
satisfies: (ver, range) => _satisfies(ver, range),
|
|
215
|
+
gt: (a, b) => _cmp(a, b) > 0,
|
|
216
|
+
gte: (a, b) => _cmp(a, b) >= 0,
|
|
217
|
+
lt: (a, b) => _cmp(a, b) < 0,
|
|
218
|
+
lte: (a, b) => _cmp(a, b) <= 0,
|
|
219
|
+
};
|
|
220
|
+
})(),
|
|
221
|
+
YAML: {
|
|
222
|
+
parse: () => undefined,
|
|
223
|
+
stringify: (obj) => (typeof obj === 'string' ? obj : ''),
|
|
224
|
+
},
|
|
225
|
+
};
|
|
226
|
+
process.argv = ['node', extractedFile, ...argv];
|
|
227
|
+
process.exit = code => {
|
|
228
|
+
throw new RequestedExit(code);
|
|
229
|
+
};
|
|
162
230
|
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
231
|
+
const moduleLike = { exports: {} };
|
|
232
|
+
const maybePromise = fn(moduleLike.exports, fakeRequire, moduleLike, extractedFile, workdir);
|
|
233
|
+
if (maybePromise && typeof maybePromise.then === 'function') await maybePromise;
|
|
234
|
+
await new Promise(resolve => setTimeout(resolve, 200));
|
|
235
|
+
if (asyncErrors.length > 0) throw asyncErrors[0];
|
|
236
|
+
} catch (error) {
|
|
237
|
+
if (error instanceof RequestedExit) {
|
|
238
|
+
process.exitCode = error.code;
|
|
239
|
+
return;
|
|
240
|
+
}
|
|
241
|
+
throw error;
|
|
242
|
+
} finally {
|
|
243
|
+
process.removeListener('uncaughtException', onAsyncError);
|
|
244
|
+
process.removeListener('unhandledRejection', onAsyncError);
|
|
245
|
+
process.argv = originalArgv;
|
|
246
|
+
process.exit = originalExit;
|
|
247
|
+
try {
|
|
248
|
+
if (originalBun === undefined) {
|
|
249
|
+
delete process.versions.bun;
|
|
250
|
+
} else {
|
|
251
|
+
Object.defineProperty(process.versions, 'bun', { value: originalBun, configurable: true });
|
|
252
|
+
}
|
|
253
|
+
} catch {}
|
|
254
|
+
if (hadGlobalBun) globalThis.Bun = originalGlobalBun;
|
|
255
|
+
else delete globalThis.Bun;
|
|
169
256
|
}
|
|
170
|
-
return width;
|
|
171
257
|
}
|
|
172
258
|
|
|
173
|
-
|
|
174
|
-
if (
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
if (ArrayBuffer.isView(value)) {
|
|
178
|
-
return Buffer.from(value.buffer, value.byteOffset, value.byteLength);
|
|
259
|
+
main().catch(error => {
|
|
260
|
+
if (error && error.code === 'CLAUDE_TERMUX_OFFICIAL_UPDATE_BLOCKED') {
|
|
261
|
+
console.error(BLOCK_MESSAGE);
|
|
262
|
+
process.exit(error.status || 1);
|
|
179
263
|
}
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
264
|
+
console.error(error && error.stack ? error.stack : String(error));
|
|
265
|
+
process.exit(1);
|
|
266
|
+
});
|
|
267
|
+
NODE
|
|
268
|
+
export CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC="${CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC:-1}"
|
|
269
|
+
export ENABLE_CLAUDEAI_MCP_SERVERS="${ENABLE_CLAUDEAI_MCP_SERVERS:-0}"
|
|
270
|
+
export CLAUDE_CODE_SIMPLE="${CLAUDE_CODE_SIMPLE:-1}"
|
|
271
|
+
node "$_helper" "$@" </dev/null
|
|
272
|
+
_status=$?
|
|
273
|
+
rm -f "$_helper"
|
|
274
|
+
trap - EXIT HUP INT TERM
|
|
275
|
+
exit "$_status"
|
|
276
|
+
else
|
|
277
|
+
_bootstrap=$(mktemp "${TMPDIR:-/tmp}/claude-bootstrap.XXXXXX.js")
|
|
278
|
+
trap 'rm -f "$_bootstrap"' EXIT HUP INT TERM
|
|
279
|
+
cat <<'NODE' > "$_bootstrap"
|
|
280
|
+
const fs = require('fs');
|
|
281
|
+
const path = require('path');
|
|
282
|
+
const {
|
|
283
|
+
BLOCK_MESSAGE,
|
|
284
|
+
createGuardedChildProcess,
|
|
285
|
+
} = require(path.join(process.env.CLAUDE_TERMUX_PACKAGE_DIR, 'lib', 'native-update-guard.js'));
|
|
187
286
|
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
287
|
+
const sourceBin = process.env.SOURCE_BIN;
|
|
288
|
+
const workdir = process.env.WORKDIR;
|
|
289
|
+
const entryJsOffset = Number(process.env.ENTRY_JS_OFFSET);
|
|
290
|
+
const entryEndOffset = Number(process.env.ENTRY_END_OFFSET);
|
|
291
|
+
const argv = process.argv.slice(2);
|
|
191
292
|
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
293
|
+
class RequestedExit extends Error {
|
|
294
|
+
constructor(code) {
|
|
295
|
+
super(`process.exit ${code}`);
|
|
296
|
+
this.name = 'RequestedExit';
|
|
297
|
+
this.code = code;
|
|
196
298
|
}
|
|
197
|
-
|
|
198
|
-
return BigInt(result);
|
|
199
299
|
}
|
|
200
300
|
|
|
201
|
-
function
|
|
202
|
-
const
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
if (typeof cmd !== 'string' || cmd.length === 0) return null;
|
|
301
|
+
function ensureEntryFile() {
|
|
302
|
+
const extractedFile = path.join(workdir, `cli.${entryJsOffset}.${entryEndOffset}.bare-path.js`);
|
|
303
|
+
if (fs.existsSync(extractedFile)) return extractedFile;
|
|
206
304
|
|
|
207
|
-
const
|
|
208
|
-
|
|
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
|
-
};
|
|
305
|
+
const len = entryEndOffset - entryJsOffset;
|
|
306
|
+
if (!(len > 0)) throw new Error('invalid replay offsets');
|
|
216
307
|
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
308
|
+
const fd = fs.openSync(sourceBin, 'r');
|
|
309
|
+
const buf = Buffer.alloc(len);
|
|
310
|
+
fs.readSync(fd, buf, 0, len, entryJsOffset);
|
|
311
|
+
fs.closeSync(fd);
|
|
220
312
|
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
if (!entry) continue;
|
|
224
|
-
const candidate = path.join(entry, cmd);
|
|
225
|
-
if (isExecutable(candidate)) return candidate;
|
|
226
|
-
}
|
|
227
|
-
return null;
|
|
313
|
+
fs.writeFileSync(extractedFile, buf.toString('utf8').replace(/[\0\s]+$/g, ''));
|
|
314
|
+
return extractedFile;
|
|
228
315
|
}
|
|
229
316
|
|
|
230
|
-
function
|
|
231
|
-
const
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
const wordWrap = !options || options.wordWrap !== false;
|
|
236
|
-
const hard = !!(options && options.hard);
|
|
237
|
-
|
|
238
|
-
if (!wordWrap || hard) {
|
|
239
|
-
const result = [];
|
|
317
|
+
function stringWidth(value) {
|
|
318
|
+
const text = String(value ?? '');
|
|
319
|
+
if (typeof Intl !== 'undefined' && typeof Intl.Segmenter === 'function') {
|
|
320
|
+
const segmenter = new Intl.Segmenter('en', { granularity: 'grapheme' });
|
|
240
321
|
let width = 0;
|
|
322
|
+
for (const _segment of segmenter.segment(text)) width += 1;
|
|
323
|
+
return width;
|
|
324
|
+
}
|
|
325
|
+
return Array.from(text).length;
|
|
326
|
+
}
|
|
241
327
|
|
|
242
|
-
|
|
243
|
-
|
|
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
|
-
}
|
|
328
|
+
function createFakeRequire(realRequire) {
|
|
329
|
+
const realChild = realRequire('child_process');
|
|
269
330
|
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
331
|
+
function rewriteArgs(args) {
|
|
332
|
+
if (
|
|
333
|
+
Array.isArray(args) &&
|
|
334
|
+
args[0] === 'xdg-open' &&
|
|
335
|
+
Array.isArray(args[1]) &&
|
|
336
|
+
typeof args[1][0] === 'string'
|
|
337
|
+
) {
|
|
338
|
+
return ['termux-open-url', [args[1][0]], ...args.slice(2)];
|
|
273
339
|
}
|
|
274
|
-
|
|
275
|
-
return result.join('');
|
|
340
|
+
return args;
|
|
276
341
|
}
|
|
277
342
|
|
|
278
|
-
const
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
343
|
+
const guardedChild = createGuardedChildProcess(
|
|
344
|
+
{
|
|
345
|
+
spawn: (...args) => realChild.spawn(...rewriteArgs(args)),
|
|
346
|
+
execFile: (...args) => realChild.execFile(...args),
|
|
347
|
+
exec: (...args) => realChild.exec(...args),
|
|
348
|
+
spawnSync: (...args) => realChild.spawnSync(...rewriteArgs(args)),
|
|
349
|
+
execFileSync: (...args) => realChild.execFileSync(...args),
|
|
350
|
+
execSync: (...args) => realChild.execSync(...args),
|
|
351
|
+
},
|
|
352
|
+
value => process.stderr.write(value),
|
|
353
|
+
);
|
|
285
354
|
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
355
|
+
return function fakeRequire(id) {
|
|
356
|
+
if (id === 'ws') {
|
|
357
|
+
class WS {
|
|
358
|
+
on() {}
|
|
359
|
+
once() {}
|
|
360
|
+
addEventListener() {}
|
|
361
|
+
close() {}
|
|
362
|
+
send() {}
|
|
363
|
+
ping() {}
|
|
292
364
|
}
|
|
365
|
+
return { default: WS, WebSocket: WS };
|
|
293
366
|
}
|
|
294
367
|
|
|
295
|
-
if (
|
|
296
|
-
|
|
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;
|
|
368
|
+
if (id === 'child_process') {
|
|
369
|
+
return guardedChild;
|
|
321
370
|
}
|
|
322
371
|
|
|
323
|
-
|
|
324
|
-
|
|
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 = '';
|
|
372
|
+
if (id === 'node:child_process') {
|
|
373
|
+
return guardedChild;
|
|
333
374
|
}
|
|
334
375
|
|
|
335
|
-
if (
|
|
336
|
-
|
|
337
|
-
lineWidth += pendingWidth;
|
|
376
|
+
if (id.startsWith('/$bunfs/root/')) {
|
|
377
|
+
throw new Error('bunfs require blocked: ' + id);
|
|
338
378
|
}
|
|
339
|
-
pendingSpaces = '';
|
|
340
|
-
|
|
341
|
-
line += text;
|
|
342
|
-
lineWidth += textWidth;
|
|
343
|
-
i = end;
|
|
344
|
-
}
|
|
345
379
|
|
|
346
|
-
|
|
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,
|
|
380
|
+
return realRequire(id);
|
|
380
381
|
};
|
|
381
382
|
}
|
|
382
383
|
|
|
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
384
|
async function main() {
|
|
453
385
|
const extractedFile = ensureEntryFile();
|
|
454
386
|
const code = fs.readFileSync(extractedFile, 'utf8');
|
|
@@ -470,33 +402,48 @@ async function main() {
|
|
|
470
402
|
process.once('uncaughtException', onAsyncError);
|
|
471
403
|
process.once('unhandledRejection', onAsyncError);
|
|
472
404
|
Object.defineProperty(process.versions, 'bun', { value: '1.1.8', configurable: true });
|
|
473
|
-
const
|
|
405
|
+
const _realChild = require('child_process');
|
|
406
|
+
globalThis.Bun = {
|
|
474
407
|
version: '1.1.8',
|
|
475
408
|
stringWidth,
|
|
476
|
-
|
|
477
|
-
which,
|
|
478
|
-
wrapAnsi,
|
|
479
|
-
stripANSI,
|
|
480
|
-
semver,
|
|
481
|
-
YAML,
|
|
482
|
-
gc: (sync) => {
|
|
409
|
+
which: (cmd) => {
|
|
483
410
|
try {
|
|
484
|
-
|
|
485
|
-
} catch {}
|
|
411
|
+
return _realChild.execFileSync('which', [String(cmd)], { encoding: 'utf8' }).trim() || null;
|
|
412
|
+
} catch { return null; }
|
|
486
413
|
},
|
|
487
|
-
|
|
488
|
-
|
|
414
|
+
semver: (() => {
|
|
415
|
+
const _cmp = (a, b) => {
|
|
416
|
+
const pa = String(a).replace(/[^0-9.]/g,'').split('.').map(Number);
|
|
417
|
+
const pb = String(b).replace(/[^0-9.]/g,'').split('.').map(Number);
|
|
418
|
+
for (let i = 0; i < 3; i++) { const d = (pa[i]||0)-(pb[i]||0); if (d) return d > 0 ? 1 : -1; }
|
|
419
|
+
return 0;
|
|
420
|
+
};
|
|
421
|
+
const _satisfies = (ver, range) => {
|
|
422
|
+
const s = String(range).trim();
|
|
423
|
+
const m = s.match(/^([><=!]{1,2})\s*([\d]+(?:\.[\d]+){0,2})$/);
|
|
424
|
+
if (m) {
|
|
425
|
+
const op = m[1], c = _cmp(ver, m[2]);
|
|
426
|
+
if (op === '>') return c > 0;
|
|
427
|
+
if (op === '>=') return c >= 0;
|
|
428
|
+
if (op === '<') return c < 0;
|
|
429
|
+
if (op === '<=') return c <= 0;
|
|
430
|
+
if (op === '=' || op === '==') return c === 0;
|
|
431
|
+
if (op === '!=') return c !== 0;
|
|
432
|
+
}
|
|
433
|
+
if (/^[\d]+(?:\.[\d]+){0,2}$/.test(s)) return _cmp(ver, s) === 0;
|
|
434
|
+
return false;
|
|
435
|
+
};
|
|
436
|
+
return {
|
|
437
|
+
order: (a, b) => _cmp(a, b),
|
|
438
|
+
compare: (a, b) => _cmp(a, b),
|
|
439
|
+
satisfies: (ver, range) => _satisfies(ver, range),
|
|
440
|
+
gt: (a, b) => _cmp(a, b) > 0,
|
|
441
|
+
gte: (a, b) => _cmp(a, b) >= 0,
|
|
442
|
+
lt: (a, b) => _cmp(a, b) < 0,
|
|
443
|
+
lte: (a, b) => _cmp(a, b) <= 0,
|
|
444
|
+
};
|
|
445
|
+
})(),
|
|
489
446
|
};
|
|
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
|
-
|
|
500
447
|
process.argv = ['node', extractedFile, ...argv];
|
|
501
448
|
process.exit = code => {
|
|
502
449
|
throw new RequestedExit(code);
|
|
@@ -505,7 +452,8 @@ async function main() {
|
|
|
505
452
|
const moduleLike = { exports: {} };
|
|
506
453
|
const maybePromise = fn(moduleLike.exports, fakeRequire, moduleLike, extractedFile, workdir);
|
|
507
454
|
if (maybePromise && typeof maybePromise.then === 'function') await maybePromise;
|
|
508
|
-
|
|
455
|
+
const _waitMs = process.stdin.isTTY ? 1200 : 200;
|
|
456
|
+
await new Promise(resolve => setTimeout(resolve, _waitMs));
|
|
509
457
|
if (asyncErrors.length > 0) throw asyncErrors[0];
|
|
510
458
|
} catch (error) {
|
|
511
459
|
if (error instanceof RequestedExit) {
|
|
@@ -525,11 +473,24 @@ async function main() {
|
|
|
525
473
|
Object.defineProperty(process.versions, 'bun', { value: originalBun, configurable: true });
|
|
526
474
|
}
|
|
527
475
|
} catch {}
|
|
476
|
+
if (hadGlobalBun) globalThis.Bun = originalGlobalBun;
|
|
528
477
|
}
|
|
529
478
|
}
|
|
530
479
|
|
|
531
480
|
main().catch(error => {
|
|
481
|
+
if (error && error.code === 'CLAUDE_TERMUX_OFFICIAL_UPDATE_BLOCKED') {
|
|
482
|
+
console.error(BLOCK_MESSAGE);
|
|
483
|
+
process.exit(error.status || 1);
|
|
484
|
+
}
|
|
532
485
|
console.error(error && error.stack ? error.stack : String(error));
|
|
533
486
|
process.exit(1);
|
|
534
487
|
});
|
|
535
488
|
NODE
|
|
489
|
+
export CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC="${CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC:-1}"
|
|
490
|
+
export ENABLE_CLAUDEAI_MCP_SERVERS="${ENABLE_CLAUDEAI_MCP_SERVERS:-0}"
|
|
491
|
+
node "$_bootstrap" "$@"
|
|
492
|
+
_status=$?
|
|
493
|
+
rm -f "$_bootstrap"
|
|
494
|
+
trap - EXIT HUP INT TERM
|
|
495
|
+
exit "$_status"
|
|
496
|
+
fi
|