Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions config/claude-native-audited-versions.json
Original file line number Diff line number Diff line change
Expand Up @@ -617,6 +617,15 @@
"tarball_integrity": "sha512-EXSediF1ujcqQeElbXdCEe+uW3NUQAOjn1xHHAgvwzY08nzJeePjagn9+YS6bmhHxBgDKwlGu7pL8Kv7EpiFtg==",
"tarball_sha256": "1bb3c8364d652dd08a15856ee27c6600ecd1e45360243154fa846f240ce7a1df",
"status": "termux_verified"
},
"2.1.222-1": {
"wrapper_spec": "@anthropic-ai/claude-code@2.1.222",
"native_spec": "@anthropic-ai/claude-code-linux-arm64@2.1.222",
"entry_js_offset": 256895476,
"entry_end_offset": 279849039,
"tarball_integrity": "sha512-EXSediF1ujcqQeElbXdCEe+uW3NUQAOjn1xHHAgvwzY08nzJeePjagn9+YS6bmhHxBgDKwlGu7pL8Kv7EpiFtg==",
"tarball_sha256": "1bb3c8364d652dd08a15856ee27c6600ecd1e45360243154fa846f240ce7a1df",
"status": "offset_discovered"
}
}
}
2 changes: 1 addition & 1 deletion config/claude-termux-release-manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"manifest_version": 1,
"package_name": "@bash0816/claude-code",
"latest_audited_version": "2.1.222",
"latest_candidate_version": "2.1.222",
"latest_candidate_version": "2.1.222-1",
"previous_stable_version": "2.1.220-2",
"stable_pinned_version": "2.1.193",
"manifest_url": "https://raw.githubusercontent.com/bash0816/ClaudeCode-Termux/main/config/claude-termux-release-manifest.json"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -617,6 +617,15 @@
"tarball_integrity": "sha512-EXSediF1ujcqQeElbXdCEe+uW3NUQAOjn1xHHAgvwzY08nzJeePjagn9+YS6bmhHxBgDKwlGu7pL8Kv7EpiFtg==",
"tarball_sha256": "1bb3c8364d652dd08a15856ee27c6600ecd1e45360243154fa846f240ce7a1df",
"status": "termux_verified"
},
"2.1.222-1": {
"wrapper_spec": "@anthropic-ai/claude-code@2.1.222",
"native_spec": "@anthropic-ai/claude-code-linux-arm64@2.1.222",
"entry_js_offset": 256895476,
"entry_end_offset": 279849039,
"tarball_integrity": "sha512-EXSediF1ujcqQeElbXdCEe+uW3NUQAOjn1xHHAgvwzY08nzJeePjagn9+YS6bmhHxBgDKwlGu7pL8Kv7EpiFtg==",
"tarball_sha256": "1bb3c8364d652dd08a15856ee27c6600ecd1e45360243154fa846f240ce7a1df",
"status": "offset_discovered"
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"manifest_version": 1,
"package_name": "@bash0816/claude-code",
"latest_audited_version": "2.1.222",
"latest_candidate_version": "2.1.222",
"latest_candidate_version": "2.1.222-1",
"previous_stable_version": "2.1.220-2",
"stable_pinned_version": "2.1.193",
"manifest_url": "https://raw.githubusercontent.com/bash0816/ClaudeCode-Termux/main/config/claude-termux-release-manifest.json"
Expand Down
92 changes: 91 additions & 1 deletion packages/claude-code/lib/termux-run-claude-native.sh
Original file line number Diff line number Diff line change
Expand Up @@ -627,6 +627,13 @@ function rewriteNativeChunkSource(source) {
'npmInstallDeprecated flag',
_npmInstallDeprecatedExpected,
);
patched = replaceRequired(
patched,
/function ([A-Za-z_$][\w$]*)\(\)\{(return\([A-Za-z_$][\w$]*,[A-Za-z_$][\w$]*,[A-Za-z_$][\w$]*\)=>\{let\{cmd:([A-Za-z_$][\w$]*),prefixArgs:([A-Za-z_$][\w$]*)\}=[A-Za-z_$][\w$]*\(\{pinToCurrentBinary:!0\}\),[A-Za-z_$][\w$]*=\[\3,\.\.\.\4,"--bg-pty-host")/g,
'function $1(){return undefined;$2',
'bg-pty-host factory disable',
1,
);
return patched;
}

Expand Down Expand Up @@ -795,9 +802,47 @@ async function main() {
gte: (a, b) => _cmp(a, b) >= 0,
lt: (a, b) => _cmp(a, b) < 0,
lte: (a, b) => _cmp(a, b) <= 0,
};
};
})(),
YAML: globalThis.__claudeYaml,
spawn: (cmd, options) => {
const opts = options || {};
const stdioArrayRaw = opts.stdio;
const cmdArray = Array.isArray(cmd) ? cmd : [cmd];
const normalizeStdio = (v) => {
if (typeof v === 'number' && Number.isInteger(v) && v >= 0) return v;
return (v === 'ignore' || v === 'pipe' || v === 'inherit') ? v : 'pipe';
};
const stdioMapped = Array.isArray(stdioArrayRaw)
? stdioArrayRaw.map(normalizeStdio)
: [normalizeStdio(opts.stdin), normalizeStdio(opts.stdout), normalizeStdio(opts.stderr)];
const child = _realChild.spawn(cmdArray[0], cmdArray.slice(1), {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Route Bun.spawn through the update guard

When the upstream bundle uses the new Bun.spawn shim to launch an npm/pnpm/yarn/npx update path, this delegates straight to the real child_process.spawn instead of the guarded child-process wrapper that blocks official self-updates. That creates a second process-spawning API which bypasses native-update-guard.js, so the same command blocked through require('child_process') can run if reached through Bun.spawn; build the shim on the guarded child process object instead.

Useful? React with 👍 / 👎.

stdio: stdioMapped,
cwd: opts.cwd,
env: opts.env,
detached: !!opts.detached,
argv0: opts.argv0,
});
const stdoutChunks = [];
if (child.stdout) child.stdout.on('data', d => stdoutChunks.push(d));
let resolveExited;
const exited = new Promise(resolve => { resolveExited = resolve; });
child.on('exit', (code, signal) => resolveExited(code !== null ? code : (signal ? 128 : 0)));
child.on('error', () => resolveExited(1));
Comment on lines +830 to +831

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Wait for stdio close before resolving spawned output

When a spawned command writes stdout that can still be draining after the process exits, resolving exited from the child exit event lets stdout.text() return before the stdout pipe has emitted all data. Since Node's close event is the point where stdio streams are closed, this can truncate output for Bun.spawn(...).stdout.text() callers; resolve the text reader after stdout/child close rather than just process exit.

Useful? React with 👍 / 👎.

return {
pid: child.pid,
exited,
stdout: { text: async () => { await exited; return Buffer.concat(stdoutChunks).toString('utf8'); } },
unref: () => { try { child.unref(); } catch {} },
kill: (signal) => { try { child.kill(signal); } catch {} },
};
},
file: (path) => {
const err = new Error(`ENOENT: Bun.file(${String(path)}) is not supported by the Termux compatibility shim`);
err.code = 'ENOENT';
err.errno = -2;
throw err;
},
};
Object.assign(globalThis.__claudeBunShim, globalThis.Bun);
if (typeof globalThis.__claudeBunShim.gc !== 'function') {
Expand Down Expand Up @@ -1447,6 +1492,13 @@ function rewriteNativeChunkSource(source) {
'npmInstallDeprecated flag',
_npmInstallDeprecatedExpected,
);
patched = replaceRequired(
patched,
/function ([A-Za-z_$][\w$]*)\(\)\{(return\([A-Za-z_$][\w$]*,[A-Za-z_$][\w$]*,[A-Za-z_$][\w$]*\)=>\{let\{cmd:([A-Za-z_$][\w$]*),prefixArgs:([A-Za-z_$][\w$]*)\}=[A-Za-z_$][\w$]*\(\{pinToCurrentBinary:!0\}\),[A-Za-z_$][\w$]*=\[\3,\.\.\.\4,"--bg-pty-host")/g,
'function $1(){return undefined;$2',
'bg-pty-host factory disable',
1,
);
return patched;
}

Expand Down Expand Up @@ -1619,6 +1671,44 @@ async function main() {
};
})(),
YAML: globalThis.__claudeYaml,
spawn: (cmd, options) => {
const opts = options || {};
const stdioArrayRaw = opts.stdio;
const cmdArray = Array.isArray(cmd) ? cmd : [cmd];
const normalizeStdio = (v) => {
if (typeof v === 'number' && Number.isInteger(v) && v >= 0) return v;
return (v === 'ignore' || v === 'pipe' || v === 'inherit') ? v : 'pipe';
};
const stdioMapped = Array.isArray(stdioArrayRaw)
? stdioArrayRaw.map(normalizeStdio)
: [normalizeStdio(opts.stdin), normalizeStdio(opts.stdout), normalizeStdio(opts.stderr)];
const child = _realChild.spawn(cmdArray[0], cmdArray.slice(1), {
stdio: stdioMapped,
cwd: opts.cwd,
env: opts.env,
detached: !!opts.detached,
argv0: opts.argv0,
});
const stdoutChunks = [];
if (child.stdout) child.stdout.on('data', d => stdoutChunks.push(d));
let resolveExited;
const exited = new Promise(resolve => { resolveExited = resolve; });
child.on('exit', (code, signal) => resolveExited(code !== null ? code : (signal ? 128 : 0)));
child.on('error', () => resolveExited(1));
return {
pid: child.pid,
exited,
stdout: { text: async () => { await exited; return Buffer.concat(stdoutChunks).toString('utf8'); } },
unref: () => { try { child.unref(); } catch {} },
kill: (signal) => { try { child.kill(signal); } catch {} },
};
},
file: (path) => {
const err = new Error(`ENOENT: Bun.file(${String(path)}) is not supported by the Termux compatibility shim`);
err.code = 'ENOENT';
err.errno = -2;
throw err;
},
};
Object.assign(globalThis.__claudeBunShim, globalThis.Bun);
if (typeof globalThis.__claudeBunShim.gc !== 'function') {
Expand Down
Loading