@bash0816/claude-code 2.1.218 → 2.1.220-1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md
CHANGED
|
@@ -562,6 +562,33 @@
|
|
|
562
562
|
"entry_end_offset": 263624682,
|
|
563
563
|
"tarball_integrity": "sha512-CcbVQCzXd9EnlktCEPrkElhdBZuqIWhkeinRGxUuZa6aal4h6J+8Dbo+OnfchBEzd1mahRDQK8BckGBAYozv2g==",
|
|
564
564
|
"tarball_sha256": "1d3cb5e12f0b653929e34ba046a7ba0a4f5c01eb25ea57b478dbac27e4af9619",
|
|
565
|
+
"status": "termux_verified"
|
|
566
|
+
},
|
|
567
|
+
"2.1.219": {
|
|
568
|
+
"wrapper_spec": "@anthropic-ai/claude-code@2.1.219",
|
|
569
|
+
"native_spec": "@anthropic-ai/claude-code-linux-arm64@2.1.219",
|
|
570
|
+
"entry_js_offset": 243825700,
|
|
571
|
+
"entry_end_offset": 265451802,
|
|
572
|
+
"tarball_integrity": "sha512-G5yLidk2u6djL5PPuBYXVwVhTsZY5zLoZwh1Jnrd/IRyYb0P0x4gKTzVvGlsGepkBrOp0H2k/KuicyNPrXt57Q==",
|
|
573
|
+
"tarball_sha256": "cf4ae671f08b91ac75ea63c8497e7ff4e3bdbe522b0f83bff2de162d44e0eb15",
|
|
574
|
+
"status": "termux_verified"
|
|
575
|
+
},
|
|
576
|
+
"2.1.220": {
|
|
577
|
+
"wrapper_spec": "@anthropic-ai/claude-code@2.1.220",
|
|
578
|
+
"native_spec": "@anthropic-ai/claude-code-linux-arm64@2.1.220",
|
|
579
|
+
"entry_js_offset": 243831156,
|
|
580
|
+
"entry_end_offset": 265457701,
|
|
581
|
+
"tarball_integrity": "sha512-VHFI8mKruIntKn7eq81sbyS19/KWmQcmJQsS/C+j9M/E+w0s4UytgsL7DADPjBE/GByNiKoRtLYDMntCjRlOdA==",
|
|
582
|
+
"tarball_sha256": "e38454d73576a08a2e707f26539d73fc9ef33e890228ca5c58a2bbe810ac884d",
|
|
583
|
+
"status": "termux_verified"
|
|
584
|
+
},
|
|
585
|
+
"2.1.220-1": {
|
|
586
|
+
"wrapper_spec": "@anthropic-ai/claude-code@2.1.220",
|
|
587
|
+
"native_spec": "@anthropic-ai/claude-code-linux-arm64@2.1.220",
|
|
588
|
+
"entry_js_offset": 243831156,
|
|
589
|
+
"entry_end_offset": 265457701,
|
|
590
|
+
"tarball_integrity": "sha512-VHFI8mKruIntKn7eq81sbyS19/KWmQcmJQsS/C+j9M/E+w0s4UytgsL7DADPjBE/GByNiKoRtLYDMntCjRlOdA==",
|
|
591
|
+
"tarball_sha256": "e38454d73576a08a2e707f26539d73fc9ef33e890228ca5c58a2bbe810ac884d",
|
|
565
592
|
"status": "offset_discovered"
|
|
566
593
|
}
|
|
567
594
|
}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
{
|
|
2
2
|
"manifest_version": 1,
|
|
3
3
|
"package_name": "@bash0816/claude-code",
|
|
4
|
-
"latest_audited_version": "2.1.
|
|
5
|
-
"latest_candidate_version": "2.1.
|
|
6
|
-
"previous_stable_version": "2.1.
|
|
4
|
+
"latest_audited_version": "2.1.220",
|
|
5
|
+
"latest_candidate_version": "2.1.220-1",
|
|
6
|
+
"previous_stable_version": "2.1.219",
|
|
7
7
|
"stable_pinned_version": "2.1.193",
|
|
8
8
|
"manifest_url": "https://raw.githubusercontent.com/bash0816/ClaudeCode-Termux/main/config/claude-termux-release-manifest.json"
|
|
9
9
|
}
|
|
@@ -583,6 +583,7 @@ function rewriteNativeChunkSource(source) {
|
|
|
583
583
|
const _bunPropertyAccessExpected = (() => {
|
|
584
584
|
const _ver = String(process.env.CURRENT_CLAUDE_VERSION || '');
|
|
585
585
|
const _m = _ver.match(/^(\d+)\.(\d+)\.(\d+)/);
|
|
586
|
+
if (_m && (Number(_m[1]) > 2 || Number(_m[2]) > 1 || Number(_m[3]) >= 219)) return 42;
|
|
586
587
|
if (_m && (Number(_m[1]) > 2 || Number(_m[2]) > 1 || Number(_m[3]) >= 216)) return 40;
|
|
587
588
|
if (_m && (Number(_m[1]) > 2 || Number(_m[2]) > 1 || Number(_m[3]) >= 214)) return 39;
|
|
588
589
|
if (_m && (Number(_m[1]) > 2 || Number(_m[2]) > 1 || Number(_m[3]) >= 205)) return 38;
|
|
@@ -635,6 +636,12 @@ async function main() {
|
|
|
635
636
|
function onAsyncError(error) {
|
|
636
637
|
asyncErrors.push(error);
|
|
637
638
|
}
|
|
639
|
+
const printWaitMs = Number(process.env.CLAUDE_TERMUX_PRINT_WAIT_MS || 5000);
|
|
640
|
+
async function waitForPrintFlush() {
|
|
641
|
+
if (Number.isFinite(printWaitMs) && printWaitMs > 0) {
|
|
642
|
+
await new Promise(resolve => setTimeout(resolve, printWaitMs));
|
|
643
|
+
}
|
|
644
|
+
}
|
|
638
645
|
|
|
639
646
|
try {
|
|
640
647
|
process.once('uncaughtException', onAsyncError);
|
|
@@ -696,18 +703,15 @@ async function main() {
|
|
|
696
703
|
process.exit = code => {
|
|
697
704
|
throw new RequestedExit(code);
|
|
698
705
|
};
|
|
699
|
-
|
|
700
|
-
const printWaitMs = Number(process.env.CLAUDE_TERMUX_PRINT_WAIT_MS || 5000);
|
|
701
706
|
const moduleLike = { exports: {} };
|
|
702
707
|
const maybePromise = fn(moduleLike.exports, fakeRequire, moduleLike, extractedFile, workdir);
|
|
703
708
|
if (maybePromise && typeof maybePromise.then === 'function') await maybePromise;
|
|
704
|
-
|
|
705
|
-
await new Promise(resolve => setTimeout(resolve, printWaitMs));
|
|
706
|
-
}
|
|
709
|
+
await waitForPrintFlush();
|
|
707
710
|
if (asyncErrors.length > 0) throw asyncErrors[0];
|
|
708
711
|
} catch (error) {
|
|
709
712
|
if (error instanceof RequestedExit) {
|
|
710
713
|
process.exitCode = error.code;
|
|
714
|
+
await waitForPrintFlush();
|
|
711
715
|
return;
|
|
712
716
|
}
|
|
713
717
|
throw error;
|
|
@@ -757,6 +761,7 @@ else
|
|
|
757
761
|
_bootstrap=$(mktemp "${TERMUX_TMPDIR}/claude-bootstrap.XXXXXX.js")
|
|
758
762
|
trap 'rm -f "$_bootstrap"' EXIT HUP INT TERM
|
|
759
763
|
export CLAUDE_TERMUX_TUI="${_tui}"
|
|
764
|
+
export CLAUDE_TERMUX_PRINT_MODE="${_pf}"
|
|
760
765
|
cat <<'NODE' > "$_bootstrap"
|
|
761
766
|
const fs = require('fs');
|
|
762
767
|
const path = require('path');
|
|
@@ -1275,6 +1280,7 @@ function rewriteNativeChunkSource(source) {
|
|
|
1275
1280
|
const _bunPropertyAccessExpected = (() => {
|
|
1276
1281
|
const _ver = String(process.env.CURRENT_CLAUDE_VERSION || '');
|
|
1277
1282
|
const _m = _ver.match(/^(\d+)\.(\d+)\.(\d+)/);
|
|
1283
|
+
if (_m && (Number(_m[1]) > 2 || Number(_m[2]) > 1 || Number(_m[3]) >= 219)) return 42;
|
|
1278
1284
|
if (_m && (Number(_m[1]) > 2 || Number(_m[2]) > 1 || Number(_m[3]) >= 216)) return 40;
|
|
1279
1285
|
if (_m && (Number(_m[1]) > 2 || Number(_m[2]) > 1 || Number(_m[3]) >= 214)) return 39;
|
|
1280
1286
|
if (_m && (Number(_m[1]) > 2 || Number(_m[2]) > 1 || Number(_m[3]) >= 205)) return 38;
|
|
@@ -1327,6 +1333,13 @@ async function main() {
|
|
|
1327
1333
|
function onAsyncError(error) {
|
|
1328
1334
|
asyncErrors.push(error);
|
|
1329
1335
|
}
|
|
1336
|
+
async function waitForPrintFlushIfNeeded() {
|
|
1337
|
+
if (process.env.CLAUDE_TERMUX_PRINT_MODE !== '1') return;
|
|
1338
|
+
const printWaitMs = Number(process.env.CLAUDE_TERMUX_PRINT_WAIT_MS || 5000);
|
|
1339
|
+
if (Number.isFinite(printWaitMs) && printWaitMs > 0) {
|
|
1340
|
+
await new Promise(resolve => setTimeout(resolve, printWaitMs));
|
|
1341
|
+
}
|
|
1342
|
+
}
|
|
1330
1343
|
|
|
1331
1344
|
try {
|
|
1332
1345
|
process.once('uncaughtException', onAsyncError);
|
|
@@ -1392,10 +1405,12 @@ async function main() {
|
|
|
1392
1405
|
const moduleLike = { exports: {} };
|
|
1393
1406
|
const maybePromise = fn(moduleLike.exports, fakeRequire, moduleLike, extractedFile, workdir);
|
|
1394
1407
|
if (maybePromise && typeof maybePromise.then === 'function') await maybePromise;
|
|
1408
|
+
await waitForPrintFlushIfNeeded();
|
|
1395
1409
|
if (asyncErrors.length > 0) throw asyncErrors[0];
|
|
1396
1410
|
} catch (error) {
|
|
1397
1411
|
if (error instanceof RequestedExit) {
|
|
1398
1412
|
process.exitCode = error.code;
|
|
1413
|
+
await waitForPrintFlushIfNeeded();
|
|
1399
1414
|
return;
|
|
1400
1415
|
}
|
|
1401
1416
|
throw error;
|
|
@@ -191,12 +191,32 @@ test('print path does not defer cleanup to exit', () => {
|
|
|
191
191
|
test('bootstrap path defers cleanup to exit', () => {
|
|
192
192
|
const bootstrapBlock = extractBlock('cat <<\'NODE\' > "$_bootstrap"', '\n export ENABLE_CLAUDEAI_MCP_SERVERS=');
|
|
193
193
|
|
|
194
|
-
assert.equal(bootstrapBlock.includes('CLAUDE_TERMUX_PRINT_WAIT_MS'), false);
|
|
195
|
-
assert.equal(bootstrapBlock.includes('setTimeout(resolve, printWaitMs)'), false);
|
|
196
194
|
assert.equal(bootstrapBlock.includes('process.once(\'exit\''), true);
|
|
197
195
|
assert.equal(bootstrapBlock.includes('process.removeListener(\'uncaughtException\''), true);
|
|
198
196
|
});
|
|
199
197
|
|
|
198
|
+
test('bootstrap branch exports CLAUDE_TERMUX_PRINT_MODE before invoking node', () => {
|
|
199
|
+
const bootstrapShellRegion = extractFunction(
|
|
200
|
+
script,
|
|
201
|
+
'export CLAUDE_TERMUX_TUI="${_tui}"',
|
|
202
|
+
'cat <<\'NODE\' > "$_bootstrap"',
|
|
203
|
+
);
|
|
204
|
+
assert.equal(bootstrapShellRegion.includes('export CLAUDE_TERMUX_PRINT_MODE="${_pf}"'), true);
|
|
205
|
+
});
|
|
206
|
+
|
|
207
|
+
test('helper and bootstrap wait for print flush, including the RequestedExit path', () => {
|
|
208
|
+
const helperBlock = extractBlock('cat <<\'NODE\' > "$_helper"', '\n export ENABLE_CLAUDEAI_MCP_SERVERS=');
|
|
209
|
+
const bootstrapBlock = extractBlock('cat <<\'NODE\' > "$_bootstrap"', '\n export ENABLE_CLAUDEAI_MCP_SERVERS=');
|
|
210
|
+
|
|
211
|
+
assert.equal(helperBlock.includes('async function waitForPrintFlush()'), true);
|
|
212
|
+
assert.equal(helperBlock.includes('await waitForPrintFlush();\n if (asyncErrors.length > 0) throw asyncErrors[0];'), true);
|
|
213
|
+
assert.equal(helperBlock.includes('process.exitCode = error.code;\n await waitForPrintFlush();\n return;'), true);
|
|
214
|
+
|
|
215
|
+
assert.equal(bootstrapBlock.includes('async function waitForPrintFlushIfNeeded()'), true);
|
|
216
|
+
assert.equal(bootstrapBlock.includes('await waitForPrintFlushIfNeeded();\n if (asyncErrors.length > 0) throw asyncErrors[0];'), true);
|
|
217
|
+
assert.equal(bootstrapBlock.includes('process.exitCode = error.code;\n await waitForPrintFlushIfNeeded();\n return;'), true);
|
|
218
|
+
});
|
|
219
|
+
|
|
200
220
|
test('entry extraction uses a process-unique filename', () => {
|
|
201
221
|
const helperBlock = extractBlock('cat <<\'NODE\' > "$_helper"', '\n export ENABLE_CLAUDEAI_MCP_SERVERS=');
|
|
202
222
|
const bootstrapBlock = extractBlock('cat <<\'NODE\' > "$_bootstrap"', '\n export ENABLE_CLAUDEAI_MCP_SERVERS=');
|
|
@@ -478,6 +498,43 @@ test('rewriteNativeChunkSource rejects stale Bun property access count for versi
|
|
|
478
498
|
}
|
|
479
499
|
});
|
|
480
500
|
|
|
501
|
+
test('rewriteNativeChunkSource rewrites the synthetic bundle slice (version 2.1.219)', () => {
|
|
502
|
+
process.env.CURRENT_CLAUDE_VERSION = '2.1.219';
|
|
503
|
+
try {
|
|
504
|
+
const { rewriteNativeChunkSource } = loadHelperApi();
|
|
505
|
+
const typeofBun = Array.from({ length: 7 }, () => 'typeof Bun').join('; ');
|
|
506
|
+
const bunProps = Array.from({ length: 42 }, (_, index) => `Bun.p${index}`).join('; ');
|
|
507
|
+
const source = `function(exports, require, module, __filename, __dirname) { ${typeofBun}; typeof globalThis.Bun; globalThis.Bun; ${bunProps}; npmInstallDeprecated:!0; npmInstallDeprecated:!0 }`;
|
|
508
|
+
const patched = rewriteNativeChunkSource(source);
|
|
509
|
+
|
|
510
|
+
assert.match(patched, /var __claudeBun = globalThis\.__claudeBunShim;/);
|
|
511
|
+
assert.match(patched, /typeof __claudeBun/);
|
|
512
|
+
assert.match(patched, /typeof globalThis\.__claudeBun/);
|
|
513
|
+
assert.match(patched, /globalThis\.__claudeBun/);
|
|
514
|
+
assert.match(patched, /__claudeBun\./);
|
|
515
|
+
assert.equal((patched.match(/__claudeBun\./g) || []).length, 42);
|
|
516
|
+
} finally {
|
|
517
|
+
delete process.env.CURRENT_CLAUDE_VERSION;
|
|
518
|
+
}
|
|
519
|
+
});
|
|
520
|
+
|
|
521
|
+
test('rewriteNativeChunkSource rejects stale Bun property access count for version 2.1.219', () => {
|
|
522
|
+
process.env.CURRENT_CLAUDE_VERSION = '2.1.219';
|
|
523
|
+
try {
|
|
524
|
+
const { rewriteNativeChunkSource } = loadHelperApi();
|
|
525
|
+
const typeofBun = Array.from({ length: 7 }, () => 'typeof Bun').join('; ');
|
|
526
|
+
const bunProps = Array.from({ length: 41 }, (_, index) => `Bun.p${index}`).join('; ');
|
|
527
|
+
const source = `function(exports, require, module, __filename, __dirname) { ${typeofBun}; typeof globalThis.Bun; globalThis.Bun; ${bunProps}; npmInstallDeprecated:!0; npmInstallDeprecated:!0 }`;
|
|
528
|
+
|
|
529
|
+
assert.throws(
|
|
530
|
+
() => rewriteNativeChunkSource(source),
|
|
531
|
+
/unexpected Bun property access count 41/,
|
|
532
|
+
);
|
|
533
|
+
} finally {
|
|
534
|
+
delete process.env.CURRENT_CLAUDE_VERSION;
|
|
535
|
+
}
|
|
536
|
+
});
|
|
537
|
+
|
|
481
538
|
test('rewriteNativeChunkSource rejects unexpected replacement counts', () => {
|
|
482
539
|
const { rewriteNativeChunkSource } = loadHelperApi();
|
|
483
540
|
const source = buildSyntheticBundleSource().replace('Bun.p30;', '');
|
|
@@ -507,3 +564,77 @@ test('tarball contents match the workspace runner and test file', { skip: !fs.ex
|
|
|
507
564
|
test('CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC is never forced (regression guard)', () => {
|
|
508
565
|
assert.equal(script.includes('CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC'), false);
|
|
509
566
|
});
|
|
567
|
+
|
|
568
|
+
function buildScenarioFixtureSource() {
|
|
569
|
+
const typeofBun = Array.from({ length: 7 }, () => 'typeof Bun').join('; ');
|
|
570
|
+
const bunProps = Array.from({ length: 42 }, (_, i) => `Bun.p${i}`).join('; ');
|
|
571
|
+
return `function(exports, require, module, __filename, __dirname) {
|
|
572
|
+
${typeofBun}; typeof globalThis.Bun; globalThis.Bun; ${bunProps};
|
|
573
|
+
npmInstallDeprecated:!0; npmInstallDeprecated:!0;
|
|
574
|
+
const scenario = process.env.TEST_SCENARIO;
|
|
575
|
+
if (scenario === 'sync-exit') { process.stdout.write('ok'); process.exit(0); return; }
|
|
576
|
+
if (scenario === 'async-exit') {
|
|
577
|
+
setTimeout(() => { process.stdout.write('ok'); }, 100).unref();
|
|
578
|
+
return;
|
|
579
|
+
}
|
|
580
|
+
process.stdout.write('ok');
|
|
581
|
+
}`;
|
|
582
|
+
}
|
|
583
|
+
|
|
584
|
+
function runScenario({ printMode, stdinInherit, scenario }) {
|
|
585
|
+
const tmpBase = fs.mkdtempSync(path.join(os.tmpdir(), 'claude-stdin-test-'));
|
|
586
|
+
const sourceBin = path.join(tmpBase, 'fake-source.js');
|
|
587
|
+
const fixtureSource = buildScenarioFixtureSource();
|
|
588
|
+
fs.writeFileSync(sourceBin, fixtureSource, 'utf8');
|
|
589
|
+
const entryJsOffset = 0;
|
|
590
|
+
const entryEndOffset = Buffer.byteLength(fixtureSource, 'utf8');
|
|
591
|
+
const workdir = path.join(tmpBase, 'workdir');
|
|
592
|
+
fs.mkdirSync(workdir, { recursive: true });
|
|
593
|
+
|
|
594
|
+
const env = {
|
|
595
|
+
...process.env,
|
|
596
|
+
SOURCE_BIN: sourceBin,
|
|
597
|
+
WORKDIR: workdir,
|
|
598
|
+
ENTRY_JS_OFFSET: String(entryJsOffset),
|
|
599
|
+
ENTRY_END_OFFSET: String(entryEndOffset),
|
|
600
|
+
CURRENT_CLAUDE_VERSION: '2.1.220',
|
|
601
|
+
CLAUDE_TERMUX_PACKAGE_DIR: path.join(__dirname, '..'),
|
|
602
|
+
MAGI_ENV: '1',
|
|
603
|
+
CLAUDE_TERMUX_PRINT_WAIT_MS: '300',
|
|
604
|
+
TMPDIR: tmpBase,
|
|
605
|
+
TEST_SCENARIO: scenario,
|
|
606
|
+
};
|
|
607
|
+
if (stdinInherit) env.CLAUDE_TERMUX_STDIN = 'inherit';
|
|
608
|
+
else delete env.CLAUDE_TERMUX_STDIN;
|
|
609
|
+
|
|
610
|
+
const args = printMode ? ['-p', 'x'] : [];
|
|
611
|
+
const start = Date.now();
|
|
612
|
+
const result = child_process.spawnSync('sh', [scriptPath, ...args], {
|
|
613
|
+
env,
|
|
614
|
+
input: 'test input\n',
|
|
615
|
+
encoding: 'utf8',
|
|
616
|
+
timeout: 10000,
|
|
617
|
+
});
|
|
618
|
+
const elapsedMs = Date.now() - start;
|
|
619
|
+
fs.rmSync(tmpBase, { recursive: true, force: true });
|
|
620
|
+
return { ...result, elapsedMs };
|
|
621
|
+
}
|
|
622
|
+
|
|
623
|
+
test('helper branch (CLI -p, no stdin inherit): normal/sync-exit/async-exit all produce output', () => {
|
|
624
|
+
for (const scenario of ['normal', 'sync-exit', 'async-exit']) {
|
|
625
|
+
const r = runScenario({ printMode: true, stdinInherit: false, scenario });
|
|
626
|
+
assert.ok((r.stdout || '').includes('ok'), `scenario=${scenario} stdout=${r.stdout} stderr=${r.stderr}`);
|
|
627
|
+
assert.equal(r.status, 0, `scenario=${scenario} status=${r.status} stderr=${r.stderr}`);
|
|
628
|
+
}
|
|
629
|
+
});
|
|
630
|
+
|
|
631
|
+
test('bootstrap branch (-p + CLAUDE_TERMUX_STDIN=inherit): normal/sync-exit/async-exit all produce output', () => {
|
|
632
|
+
for (const scenario of ['normal', 'sync-exit', 'async-exit']) {
|
|
633
|
+
const r = runScenario({ printMode: true, stdinInherit: true, scenario });
|
|
634
|
+
assert.ok((r.stdout || '').includes('ok'), `scenario=${scenario} stdout=${r.stdout} stderr=${r.stderr}`);
|
|
635
|
+
assert.equal(r.status, 0, `scenario=${scenario} status=${r.status} stderr=${r.stderr}`);
|
|
636
|
+
if (scenario === 'async-exit') {
|
|
637
|
+
assert.ok(r.elapsedMs >= 250, `expected wait >= 250ms, got ${r.elapsedMs}ms`);
|
|
638
|
+
}
|
|
639
|
+
}
|
|
640
|
+
});
|