@bash0816/claude-code 2.1.159-10 → 2.1.159-13

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 CHANGED
@@ -43,7 +43,7 @@ Current quick examples:
43
43
  現在の quick example:
44
44
 
45
45
  ```sh
46
- npm install -g @bash0816/claude-code@2.1.159-10
46
+ npm install -g @bash0816/claude-code@2.1.159-13
47
47
  ```
48
48
 
49
49
  ## Update / 更新
@@ -68,8 +68,8 @@ Normal launch also checks the same manifest with a short timeout and prints a no
68
68
 
69
69
  - Only audited versions in `config/claude-native-audited-versions.json` can run.
70
70
  - `config/claude-native-audited-versions.json` にある監査済み version だけを実行できます。
71
- - `2.1.118`, `2.1.119`, `2.1.121`, `2.1.122`, `2.1.123`, `2.1.126`, `2.1.128`, `2.1.136`, `2.1.137`, `2.1.138`, `2.1.139`, `2.1.140`, `2.1.141`, `2.1.142`, `2.1.143`, `2.1.144`, `2.1.150`, `2.1.150-1`, `2.1.150-2`, `2.1.150-3`, `2.1.153`, `2.1.153-1`, `2.1.153-2`, `2.1.153-3`, `2.1.153-4`, `2.1.157`, `2.1.159-4`, `2.1.159-8`, `2.1.159-10` are included in the package metadata.
72
- - `2.1.118`、`2.1.119`、`2.1.121`、`2.1.122`、`2.1.123`、`2.1.126`、`2.1.128`、`2.1.136`、`2.1.137`、`2.1.138`、`2.1.139`、`2.1.140`、`2.1.141`、`2.1.142`、`2.1.143`、`2.1.144`、`2.1.150`、`2.1.150-1`、`2.1.150-2`、`2.1.150-3`、`2.1.153`、`2.1.153-1`、`2.1.153-2`、`2.1.153-3`、`2.1.153-4`、`2.1.157`、`2.1.159-4`、`2.1.159-8`、`2.1.159-10` を package metadata に含めています。
71
+ - `2.1.118`, `2.1.119`, `2.1.121`, `2.1.122`, `2.1.123`, `2.1.126`, `2.1.128`, `2.1.136`, `2.1.137`, `2.1.138`, `2.1.139`, `2.1.140`, `2.1.141`, `2.1.142`, `2.1.143`, `2.1.144`, `2.1.150`, `2.1.150-1`, `2.1.150-2`, `2.1.150-3`, `2.1.153`, `2.1.153-1`, `2.1.153-2`, `2.1.153-3`, `2.1.153-4`, `2.1.157`, `2.1.159-4`, `2.1.159-8`, `2.1.159-10`, `2.1.159-13` are included in the package metadata.
72
+ - `2.1.118`、`2.1.119`、`2.1.121`、`2.1.122`、`2.1.123`、`2.1.126`、`2.1.128`、`2.1.136`、`2.1.137`、`2.1.138`、`2.1.139`、`2.1.140`、`2.1.141`、`2.1.142`、`2.1.143`、`2.1.144`、`2.1.150`、`2.1.150-1`、`2.1.150-2`、`2.1.150-3`、`2.1.153`、`2.1.153-1`、`2.1.153-2`、`2.1.153-3`、`2.1.153-4`、`2.1.157`、`2.1.159-4`、`2.1.159-8`、`2.1.159-10`、`2.1.159-13` を package metadata に含めています。
73
73
  - The metadata file is the source of truth for the currently audited set.
74
74
  - 現在の監査済み version 集合の source of truth は metadata file です。
75
75
  - Native artifacts are cached under `${HOME}/.claude-termux-native-package`.
@@ -226,6 +226,24 @@
226
226
  "tarball_integrity": "sha512-c8dXbuQdrotGWll46GlnXm5IPpORK2VrBSosCmI6f8t7Snc/3F58fX0MbIjJ/ycXpY0aaKuOnufCuxf7wi1Xqw==",
227
227
  "tarball_sha256": "0b551634f11742310ba3b6344fb7912ba1ed8ee0ef4702eab0099d31b4eeb070",
228
228
  "status": "termux_verified"
229
+ },
230
+ "2.1.159-12": {
231
+ "wrapper_spec": "@anthropic-ai/claude-code@2.1.159",
232
+ "native_spec": "@anthropic-ai/claude-code-linux-arm64@2.1.159",
233
+ "entry_js_offset": 223232708,
234
+ "entry_end_offset": 238749397,
235
+ "tarball_integrity": "sha512-c8dXbuQdrotGWll46GlnXm5IPpORK2VrBSosCmI6f8t7Snc/3F58fX0MbIjJ/ycXpY0aaKuOnufCuxf7wi1Xqw==",
236
+ "tarball_sha256": "0b551634f11742310ba3b6344fb7912ba1ed8ee0ef4702eab0099d31b4eeb070",
237
+ "status": "offset_discovered"
238
+ },
239
+ "2.1.159-13": {
240
+ "wrapper_spec": "@anthropic-ai/claude-code@2.1.159",
241
+ "native_spec": "@anthropic-ai/claude-code-linux-arm64@2.1.159",
242
+ "entry_js_offset": 223232708,
243
+ "entry_end_offset": 238749397,
244
+ "tarball_integrity": "sha512-c8dXbuQdrotGWll46GlnXm5IPpORK2VrBSosCmI6f8t7Snc/3F58fX0MbIjJ/ycXpY0aaKuOnufCuxf7wi1Xqw==",
245
+ "tarball_sha256": "0b551634f11742310ba3b6344fb7912ba1ed8ee0ef4702eab0099d31b4eeb070",
246
+ "status": "termux_verified"
229
247
  }
230
248
  }
231
249
  }
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "manifest_version": 1,
3
3
  "package_name": "@bash0816/claude-code",
4
- "latest_audited_version": "2.1.159-10",
5
- "latest_candidate_version": "2.1.159-10",
6
- "previous_stable_version": "2.1.159-8",
4
+ "latest_audited_version": "2.1.159-13",
5
+ "latest_candidate_version": "2.1.159-13",
6
+ "previous_stable_version": "2.1.159-10",
7
7
  "manifest_url": "https://raw.githubusercontent.com/bash0816/ClaudeCode-Termux/main/config/claude-termux-release-manifest.json"
8
8
  }
@@ -6,7 +6,6 @@ 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}"
10
9
  TERMUX_TMPDIR="${TMPDIR:-/data/data/com.termux/files/usr/tmp}"
11
10
  SSL_CERT_DIR="${SSL_CERT_DIR:-/data/data/com.termux/files/usr/etc/tls}"
12
11
  SSL_CERT_FILE="${SSL_CERT_FILE:-/data/data/com.termux/files/usr/etc/tls/cert.pem}"
@@ -39,31 +38,30 @@ export WORKDIR
39
38
  export ENTRY_JS_OFFSET
40
39
  export ENTRY_END_OFFSET
41
40
  export CURRENT_CLAUDE_VERSION
41
+ export CLAUDE_TERMUX_PACKAGE_DIR="${CLAUDE_TERMUX_PACKAGE_DIR:-}"
42
+ export CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC="${CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC:-1}"
43
+ export ENABLE_CLAUDEAI_MCP_SERVERS="${ENABLE_CLAUDEAI_MCP_SERVERS:-0}"
42
44
 
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"
45
+ node - "$@" <<'NODE'
55
46
  const fs = require('fs');
56
47
  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'));
61
48
 
62
49
  const sourceBin = process.env.SOURCE_BIN;
63
50
  const workdir = process.env.WORKDIR;
64
51
  const entryJsOffset = Number(process.env.ENTRY_JS_OFFSET);
65
52
  const entryEndOffset = Number(process.env.ENTRY_END_OFFSET);
66
53
  const argv = process.argv.slice(2);
54
+ const packageDir = process.env.CLAUDE_TERMUX_PACKAGE_DIR || "";
55
+ function loadNativeUpdateGuard() {
56
+ if (!packageDir) return null;
57
+ const guardPath = path.join(packageDir, 'lib', 'native-update-guard.js');
58
+ if (!fs.existsSync(guardPath)) return null;
59
+ try { return require(guardPath); } catch (e) {
60
+ process.stderr.write('[termux] native-update-guard load failed: ' + e.message + '\n');
61
+ return null;
62
+ }
63
+ }
64
+ const _nativeUpdateGuard = loadNativeUpdateGuard();
67
65
 
68
66
  class RequestedExit extends Error {
69
67
  constructor(code) {
@@ -100,257 +98,244 @@ function stringWidth(value) {
100
98
  return Array.from(text).length;
101
99
  }
102
100
 
103
- function createFakeRequire(realRequire) {
104
- const realChild = realRequire('child_process');
105
-
106
- function rewriteArgs(args) {
107
- if (
108
- Array.isArray(args) &&
109
- args[0] === 'xdg-open' &&
110
- Array.isArray(args[1]) &&
111
- typeof args[1][0] === 'string'
112
- ) {
113
- return ['termux-open-url', [args[1][0]], ...args.slice(2)];
114
- }
115
- return args;
116
- }
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
-
130
- return function fakeRequire(id) {
131
- if (id === 'ws') {
132
- class WS {
133
- on() {}
134
- once() {}
135
- addEventListener() {}
136
- close() {}
137
- send() {}
138
- ping() {}
139
- }
140
- return { default: WS, WebSocket: WS };
141
- }
142
-
143
- if (id === 'child_process') {
144
- return guardedChild;
145
- }
101
+ function stripANSI(text) {
102
+ return String(text ?? '').replace(/\u001B\[[0-9;]*m/g, '');
103
+ }
146
104
 
147
- if (id === 'node:child_process') {
148
- return guardedChild;
105
+ function wrapAnsi(text, columns) {
106
+ const value = String(text ?? '');
107
+ const width = Number(columns);
108
+ if (!Number.isFinite(width) || width <= 0) return value;
109
+
110
+ let lineWidth = 0;
111
+ let result = '';
112
+ for (const ch of value) {
113
+ if (ch === '\n') {
114
+ result += ch;
115
+ lineWidth = 0;
116
+ continue;
149
117
  }
150
118
 
151
- if (id.startsWith('/$bunfs/root/')) {
152
- throw new Error('bunfs require blocked: ' + id);
119
+ const chWidth = stringWidth(ch);
120
+ if (lineWidth > 0 && lineWidth + chWidth > width) {
121
+ result += '\n';
122
+ lineWidth = 0;
153
123
  }
154
124
 
155
- return realRequire(id);
156
- };
125
+ result += ch;
126
+ lineWidth += chWidth;
127
+ }
128
+ return result;
157
129
  }
158
130
 
159
- async function main() {
160
- const extractedFile = ensureEntryFile();
161
- const code = fs.readFileSync(extractedFile, 'utf8');
162
- const fn = eval('(' + code);
131
+ function hash(value) {
132
+ const crypto = require('crypto');
133
+ const digest = crypto.createHash('sha256').update(String(value ?? '')).digest();
134
+ return digest.readUInt32LE(0);
135
+ }
163
136
 
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 = [];
137
+ function compareSemver(left, right) {
138
+ const a = String(left).replace(/^[^0-9]*/, '').split('.').map(Number);
139
+ const b = String(right).replace(/^[^0-9]*/, '').split('.').map(Number);
140
+ const size = Math.max(a.length, b.length);
141
+ for (let i = 0; i < size; i += 1) {
142
+ const diff = (a[i] || 0) - (b[i] || 0);
143
+ if (diff !== 0) return diff > 0 ? 1 : -1;
144
+ }
145
+ return 0;
146
+ }
170
147
 
171
- const fakeRequire = createFakeRequire(require);
172
- function onAsyncError(error) {
173
- asyncErrors.push(error);
148
+ function satisfiesSemver(version, range) {
149
+ const cleanRange = String(range ?? '').trim();
150
+ const match = cleanRange.match(/^([><=!]{1,2})\s*([0-9][^\s]*)$/);
151
+ if (!match) {
152
+ return /^[0-9]+(?:\.[0-9]+){0,2}$/.test(cleanRange)
153
+ ? compareSemver(version, cleanRange) === 0
154
+ : true;
174
155
  }
175
156
 
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
- };
157
+ const [, op, target] = match;
158
+ const cmp = compareSemver(version, target);
159
+ if (op === '>') return cmp > 0;
160
+ if (op === '>=') return cmp >= 0;
161
+ if (op === '<') return cmp < 0;
162
+ if (op === '<=') return cmp <= 0;
163
+ if (op === '=' || op === '==') return cmp === 0;
164
+ if (op === '!=') return cmp !== 0;
165
+ return true;
166
+ }
230
167
 
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;
168
+ function createSemverShim() {
169
+ return {
170
+ order: compareSemver,
171
+ compare: compareSemver,
172
+ satisfies: satisfiesSemver,
173
+ gt: (left, right) => compareSemver(left, right) > 0,
174
+ gte: (left, right) => compareSemver(left, right) >= 0,
175
+ lt: (left, right) => compareSemver(left, right) < 0,
176
+ lte: (left, right) => compareSemver(left, right) <= 0,
177
+ };
178
+ }
179
+
180
+ function parseScalar(value) {
181
+ const text = String(value ?? '').trim();
182
+ if (text === '') return '';
183
+ if (text === 'true') return true;
184
+ if (text === 'false') return false;
185
+ if (text === 'null' || text === '~') return null;
186
+ if (/^-?(?:0|[1-9]\d*)(?:\.\d+)?$/.test(text)) return Number(text);
187
+ if (
188
+ (text.startsWith('"') && text.endsWith('"')) ||
189
+ (text.startsWith("'") && text.endsWith("'"))
190
+ ) {
191
+ return text.slice(1, -1);
256
192
  }
193
+ return text;
257
194
  }
258
195
 
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);
196
+ function parseInlineArray(value) {
197
+ const inner = String(value ?? '').trim().slice(1, -1).trim();
198
+ if (inner === '') return [];
199
+ const items = [];
200
+ let current = '';
201
+ let quote = null;
202
+
203
+ for (let i = 0; i < inner.length; i += 1) {
204
+ const ch = inner[i];
205
+ if (quote) {
206
+ if (ch === quote && inner[i - 1] !== '\\') quote = null;
207
+ current += ch;
208
+ continue;
209
+ }
210
+ if (ch === '"' || ch === "'") {
211
+ quote = ch;
212
+ current += ch;
213
+ continue;
214
+ }
215
+ if (ch === ',') {
216
+ items.push(parseScalar(current));
217
+ current = '';
218
+ continue;
219
+ }
220
+ current += ch;
263
221
  }
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'));
286
222
 
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);
223
+ if (current !== '') items.push(parseScalar(current));
224
+ return items;
225
+ }
292
226
 
293
- class RequestedExit extends Error {
294
- constructor(code) {
295
- super(`process.exit ${code}`);
296
- this.name = 'RequestedExit';
297
- this.code = code;
227
+ function yamlParse(text) {
228
+ const source = String(text ?? '');
229
+ const result = {};
230
+ for (const rawLine of source.split(/\r?\n/)) {
231
+ const line = rawLine.trim();
232
+ if (!line || line.startsWith('#')) continue;
233
+ const idx = line.indexOf(':');
234
+ if (idx < 0) continue;
235
+ const key = line.slice(0, idx).trim();
236
+ const rawValue = line.slice(idx + 1).trim();
237
+ if (!key) continue;
238
+ result[key] = rawValue.startsWith('[') && rawValue.endsWith(']')
239
+ ? parseInlineArray(rawValue)
240
+ : parseScalar(rawValue);
298
241
  }
242
+ return result;
299
243
  }
300
244
 
301
- function ensureEntryFile() {
302
- const extractedFile = path.join(workdir, `cli.${entryJsOffset}.${entryEndOffset}.bare-path.js`);
303
- if (fs.existsSync(extractedFile)) return extractedFile;
304
-
305
- const len = entryEndOffset - entryJsOffset;
306
- if (!(len > 0)) throw new Error('invalid replay offsets');
307
-
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);
312
-
313
- fs.writeFileSync(extractedFile, buf.toString('utf8').replace(/[\0\s]+$/g, ''));
314
- return extractedFile;
245
+ function yamlStringify(value) {
246
+ if (!value || typeof value !== 'object') return String(value ?? '');
247
+ const lines = [];
248
+ for (const [key, raw] of Object.entries(value)) {
249
+ if (Array.isArray(raw)) {
250
+ lines.push(`${key}: [${raw.map(item => JSON.stringify(String(item))).join(', ')}]`);
251
+ } else if (raw === null) {
252
+ lines.push(`${key}: null`);
253
+ } else if (typeof raw === 'string') {
254
+ lines.push(`${key}: ${JSON.stringify(raw)}`);
255
+ } else {
256
+ lines.push(`${key}: ${String(raw)}`);
257
+ }
258
+ }
259
+ return lines.join('\n');
315
260
  }
316
261
 
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' });
321
- let width = 0;
322
- for (const _segment of segmenter.segment(text)) width += 1;
323
- return width;
324
- }
325
- return Array.from(text).length;
262
+ function createYamlShim() {
263
+ const yaml = {
264
+ parse: yamlParse,
265
+ stringify: yamlStringify,
266
+ };
267
+ yaml.YAML = yaml;
268
+ yaml.default = yaml;
269
+ return yaml;
326
270
  }
327
271
 
328
272
  function createFakeRequire(realRequire) {
329
273
  const realChild = realRequire('child_process');
330
-
274
+ const realVm = realRequire('vm');
331
275
  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
- ) {
276
+ if (Array.isArray(args) && args[0] === 'xdg-open' && Array.isArray(args[1]) && typeof args[1][0] === 'string') {
338
277
  return ['termux-open-url', [args[1][0]], ...args.slice(2)];
339
278
  }
340
279
  return args;
341
280
  }
281
+ const _baseChild = {
282
+ spawn: (...args) => realChild.spawn(...rewriteArgs(args)),
283
+ execFile: (...args) => realChild.execFile(...args),
284
+ exec: (...args) => realChild.exec(...args),
285
+ spawnSync: (...args) => realChild.spawnSync(...rewriteArgs(args)),
286
+ execFileSync: (...args) => realChild.execFileSync(...args),
287
+ execSync: (...args) => realChild.execSync(...args),
288
+ };
289
+ const guardedChild = _nativeUpdateGuard
290
+ ? _nativeUpdateGuard.createGuardedChildProcess(_baseChild, v => process.stderr.write(v))
291
+ : _baseChild;
342
292
 
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
- );
293
+ function injectBunIntoContext(context) {
294
+ if (!context || typeof context !== 'object') return context;
295
+ try {
296
+ if (!Object.prototype.hasOwnProperty.call(context, '__claudeBunShim')) {
297
+ Object.defineProperty(context, '__claudeBunShim', {
298
+ value: globalThis.__claudeBunShim,
299
+ configurable: true,
300
+ writable: true,
301
+ });
302
+ }
303
+ if (!Object.prototype.hasOwnProperty.call(context, '__claudeYaml')) {
304
+ Object.defineProperty(context, '__claudeYaml', {
305
+ value: globalThis.__claudeYaml,
306
+ configurable: true,
307
+ writable: true,
308
+ });
309
+ }
310
+ if (Object.prototype.hasOwnProperty.call(context, 'Bun')) {
311
+ if (context.Bun && typeof context.Bun === 'object' && context.Bun !== globalThis.Bun) {
312
+ try {
313
+ context.Bun = globalThis.Bun;
314
+ } catch {
315
+ Object.defineProperty(context, 'Bun', {
316
+ value: globalThis.Bun,
317
+ configurable: true,
318
+ writable: true,
319
+ });
320
+ }
321
+ }
322
+ if (!context.Bun || typeof context.Bun !== 'object') {
323
+ Object.defineProperty(context, 'Bun', {
324
+ value: globalThis.Bun,
325
+ configurable: true,
326
+ writable: true,
327
+ });
328
+ }
329
+ } else {
330
+ Object.defineProperty(context, 'Bun', {
331
+ value: globalThis.Bun,
332
+ configurable: true,
333
+ writable: true,
334
+ });
335
+ }
336
+ } catch {}
337
+ return context;
338
+ }
354
339
 
355
340
  return function fakeRequire(id) {
356
341
  if (id === 'ws') {
@@ -365,6 +350,36 @@ function createFakeRequire(realRequire) {
365
350
  return { default: WS, WebSocket: WS };
366
351
  }
367
352
 
353
+ if (id === 'vm') {
354
+ if (!realVm.__bunShimPatched) {
355
+ const originalCreateContext = realVm.createContext.bind(realVm);
356
+ const originalRunInNewContext = realVm.runInNewContext.bind(realVm);
357
+ const ScriptProto = realVm.Script && realVm.Script.prototype;
358
+
359
+ realVm.createContext = (contextObject, ...rest) =>
360
+ originalCreateContext(injectBunIntoContext(contextObject), ...rest);
361
+ realVm.runInNewContext = (code, contextObject, ...rest) =>
362
+ originalRunInNewContext(code, injectBunIntoContext(contextObject), ...rest);
363
+
364
+ if (ScriptProto && !ScriptProto.__bunShimPatched) {
365
+ const originalRunInContext = ScriptProto.runInContext;
366
+ const originalRunInNewContext = ScriptProto.runInNewContext;
367
+
368
+ ScriptProto.runInContext = function (contextObject, ...rest) {
369
+ return originalRunInContext.call(this, injectBunIntoContext(contextObject), ...rest);
370
+ };
371
+ ScriptProto.runInNewContext = function (contextObject, ...rest) {
372
+ return originalRunInNewContext.call(this, injectBunIntoContext(contextObject), ...rest);
373
+ };
374
+
375
+ Object.defineProperty(ScriptProto, '__bunShimPatched', { value: true });
376
+ }
377
+
378
+ Object.defineProperty(realVm, '__bunShimPatched', { value: true });
379
+ }
380
+ return realVm;
381
+ }
382
+
368
383
  if (id === 'child_process') {
369
384
  return guardedChild;
370
385
  }
@@ -373,6 +388,14 @@ function createFakeRequire(realRequire) {
373
388
  return guardedChild;
374
389
  }
375
390
 
391
+ if (id === 'yaml' || id === 'yamljs' || id === 'js-yaml') {
392
+ return createYamlShim();
393
+ }
394
+
395
+ if (id === 'vm' || id === 'node:vm') {
396
+ return realVm;
397
+ }
398
+
376
399
  if (id.startsWith('/$bunfs/root/')) {
377
400
  throw new Error('bunfs require blocked: ' + id);
378
401
  }
@@ -382,8 +405,31 @@ function createFakeRequire(realRequire) {
382
405
  }
383
406
 
384
407
  async function main() {
408
+ let bunShim;
385
409
  const extractedFile = ensureEntryFile();
386
- const code = fs.readFileSync(extractedFile, 'utf8');
410
+ let code = fs.readFileSync(extractedFile, 'utf8');
411
+ globalThis.__claudeYaml = createYamlShim();
412
+ if (!globalThis.__claudeBunShim || typeof globalThis.__claudeBunShim !== 'object') {
413
+ globalThis.__claudeBunShim = {};
414
+ }
415
+ code = code.replace(
416
+ /^function\(exports, require, module, __filename, __dirname\) \{/,
417
+ 'function(exports, require, module, __filename, __dirname) {var __claudeBun = globalThis.__claudeBunShim;',
418
+ );
419
+ const patchedCode = code.replace(
420
+ /\btypeof Bun\b/g,
421
+ 'typeof __claudeBun',
422
+ ).replace(
423
+ /\bBun\./g,
424
+ '__claudeBun.',
425
+ ).replace(
426
+ /function t5q\(q\)\{return Bun\.YAML\.parse\(q\)\}/g,
427
+ 'function t5q(q){return globalThis.__claudeYaml.parse(q)}',
428
+ ).replace(
429
+ /function VK6\(q\)\{return Bun\.YAML\.stringify\(q,null,2\)\+`/g,
430
+ 'function VK6(q){return globalThis.__claudeYaml.stringify(q,null,2)+`',
431
+ );
432
+ code = patchedCode;
387
433
  const fn = eval('(' + code);
388
434
 
389
435
  const originalArgv = process.argv.slice();
@@ -402,48 +448,26 @@ async function main() {
402
448
  process.once('uncaughtException', onAsyncError);
403
449
  process.once('unhandledRejection', onAsyncError);
404
450
  Object.defineProperty(process.versions, 'bun', { value: '1.1.8', configurable: true });
405
- const _realChild = require('child_process');
406
451
  globalThis.Bun = {
407
452
  version: '1.1.8',
453
+ gc: () => {},
454
+ hash,
455
+ stripANSI,
456
+ YAML: createYamlShim(),
408
457
  stringWidth,
409
- which: (cmd) => {
458
+ which: cmd => {
410
459
  try {
411
- return _realChild.execFileSync('which', [String(cmd)], { encoding: 'utf8' }).trim() || null;
412
- } catch { return null; }
460
+ return require('child_process').execFileSync('which', [String(cmd)], { encoding: 'utf8' }).trim() || null;
461
+ } catch {
462
+ return null;
463
+ }
413
464
  },
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
- })(),
465
+ wrapAnsi,
466
+ semver: createSemverShim(),
446
467
  };
468
+ Object.assign(globalThis.__claudeBunShim, globalThis.Bun);
469
+ globalThis.Bun = globalThis.__claudeBunShim;
470
+ bunShim = globalThis.Bun;
447
471
  process.argv = ['node', extractedFile, ...argv];
448
472
  process.exit = code => {
449
473
  throw new RequestedExit(code);
@@ -452,10 +476,14 @@ async function main() {
452
476
  const moduleLike = { exports: {} };
453
477
  const maybePromise = fn(moduleLike.exports, fakeRequire, moduleLike, extractedFile, workdir);
454
478
  if (maybePromise && typeof maybePromise.then === 'function') await maybePromise;
455
- const _waitMs = process.stdin.isTTY ? 1200 : 200;
456
- await new Promise(resolve => setTimeout(resolve, _waitMs));
479
+ await new Promise(resolve => setTimeout(resolve, Number(process.env.CLAUDE_TERMUX_PRINT_WAIT_MS || 1000)));
457
480
  if (asyncErrors.length > 0) throw asyncErrors[0];
458
481
  } catch (error) {
482
+ if (_nativeUpdateGuard && error && error.code === 'CLAUDE_TERMUX_OFFICIAL_UPDATE_BLOCKED') {
483
+ console.error(_nativeUpdateGuard.BLOCK_MESSAGE);
484
+ process.exitCode = error.status || 1;
485
+ return;
486
+ }
459
487
  if (error instanceof RequestedExit) {
460
488
  process.exitCode = error.code;
461
489
  return;
@@ -473,24 +501,15 @@ async function main() {
473
501
  Object.defineProperty(process.versions, 'bun', { value: originalBun, configurable: true });
474
502
  }
475
503
  } catch {}
504
+ delete globalThis.__claudeYaml;
505
+ delete globalThis.__claudeBunShim;
506
+ delete globalThis.Bun;
476
507
  if (hadGlobalBun) globalThis.Bun = originalGlobalBun;
477
508
  }
478
509
  }
479
510
 
480
511
  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
- }
485
512
  console.error(error && error.stack ? error.stack : String(error));
486
513
  process.exit(1);
487
514
  });
488
515
  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
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bash0816/claude-code",
3
- "version": "2.1.159-10",
3
+ "version": "2.1.159-13",
4
4
  "description": "Unofficial Termux-native Claude Code wrapper with audited native replay",
5
5
  "license": "MIT",
6
6
  "bin": {