@bash0816/claude-code 2.1.220-1 → 2.1.220-2

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.
@@ -590,6 +590,15 @@
590
590
  "tarball_integrity": "sha512-VHFI8mKruIntKn7eq81sbyS19/KWmQcmJQsS/C+j9M/E+w0s4UytgsL7DADPjBE/GByNiKoRtLYDMntCjRlOdA==",
591
591
  "tarball_sha256": "e38454d73576a08a2e707f26539d73fc9ef33e890228ca5c58a2bbe810ac884d",
592
592
  "status": "offset_discovered"
593
+ },
594
+ "2.1.220-2": {
595
+ "wrapper_spec": "@anthropic-ai/claude-code@2.1.220",
596
+ "native_spec": "@anthropic-ai/claude-code-linux-arm64@2.1.220",
597
+ "entry_js_offset": 243831156,
598
+ "entry_end_offset": 265457701,
599
+ "tarball_integrity": "sha512-VHFI8mKruIntKn7eq81sbyS19/KWmQcmJQsS/C+j9M/E+w0s4UytgsL7DADPjBE/GByNiKoRtLYDMntCjRlOdA==",
600
+ "tarball_sha256": "e38454d73576a08a2e707f26539d73fc9ef33e890228ca5c58a2bbe810ac884d",
601
+ "status": "offset_discovered"
593
602
  }
594
603
  }
595
604
  }
@@ -2,7 +2,7 @@
2
2
  "manifest_version": 1,
3
3
  "package_name": "@bash0816/claude-code",
4
4
  "latest_audited_version": "2.1.220",
5
- "latest_candidate_version": "2.1.220-1",
5
+ "latest_candidate_version": "2.1.220-2",
6
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"
@@ -623,6 +623,7 @@ async function main() {
623
623
 
624
624
  const originalArgv = process.argv.slice();
625
625
  const originalExit = process.exit;
626
+ const originalKill = process.kill;
626
627
  const originalBun = process.versions.bun;
627
628
  const hadGlobalBun = Object.prototype.hasOwnProperty.call(globalThis, 'Bun');
628
629
  const originalGlobalBun = globalThis.Bun;
@@ -700,8 +701,16 @@ async function main() {
700
701
  globalThis.__claudeBun = globalThis.__claudeBunShim;
701
702
  globalThis.Bun = globalThis.__claudeBunShim;
702
703
  process.argv = ['node', extractedFile, ...argv];
704
+ let lastExitAttemptCode = 0;
703
705
  process.exit = code => {
704
- throw new RequestedExit(code);
706
+ lastExitAttemptCode = code ?? 0;
707
+ throw new RequestedExit(lastExitAttemptCode);
708
+ };
709
+ process.kill = (pid, signal) => {
710
+ if (pid === process.pid && (signal === 'SIGKILL' || signal === 9)) {
711
+ throw new RequestedExit(lastExitAttemptCode);
712
+ }
713
+ return originalKill.call(process, pid, signal);
705
714
  };
706
715
  const moduleLike = { exports: {} };
707
716
  const maybePromise = fn(moduleLike.exports, fakeRequire, moduleLike, extractedFile, workdir);
@@ -725,6 +734,7 @@ async function main() {
725
734
  }
726
735
  process.argv = originalArgv;
727
736
  process.exit = originalExit;
737
+ process.kill = originalKill;
728
738
  try {
729
739
  if (originalBun === undefined) {
730
740
  delete process.versions.bun;
@@ -1320,6 +1330,7 @@ async function main() {
1320
1330
 
1321
1331
  const originalArgv = process.argv.slice();
1322
1332
  const originalExit = process.exit;
1333
+ const originalKill = process.kill;
1323
1334
  const originalBun = process.versions.bun;
1324
1335
  const hadGlobalBun = Object.prototype.hasOwnProperty.call(globalThis, 'Bun');
1325
1336
  const originalGlobalBun = globalThis.Bun;
@@ -1398,8 +1409,16 @@ async function main() {
1398
1409
  globalThis.__claudeBun = globalThis.__claudeBunShim;
1399
1410
  globalThis.Bun = globalThis.__claudeBunShim;
1400
1411
  process.argv = ['node', extractedFile, ...argv];
1412
+ let lastExitAttemptCode = 0;
1401
1413
  process.exit = code => {
1402
- throw new RequestedExit(code);
1414
+ lastExitAttemptCode = code ?? 0;
1415
+ throw new RequestedExit(lastExitAttemptCode);
1416
+ };
1417
+ process.kill = (pid, signal) => {
1418
+ if (pid === process.pid && (signal === 'SIGKILL' || signal === 9)) {
1419
+ throw new RequestedExit(lastExitAttemptCode);
1420
+ }
1421
+ return originalKill.call(process, pid, signal);
1403
1422
  };
1404
1423
 
1405
1424
  const moduleLike = { exports: {} };
@@ -1419,6 +1438,7 @@ async function main() {
1419
1438
  process.removeListener('unhandledRejection', onAsyncError);
1420
1439
  process.argv = originalArgv;
1421
1440
  process.exit = originalExit;
1441
+ process.kill = originalKill;
1422
1442
  process.once('exit', () => {
1423
1443
  if (extractedFile) {
1424
1444
  try {
@@ -577,6 +577,39 @@ function buildScenarioFixtureSource() {
577
577
  setTimeout(() => { process.stdout.write('ok'); }, 100).unref();
578
578
  return;
579
579
  }
580
+ if (scenario === 'self-sigkill-fallback-string') {
581
+ try {
582
+ process.exit(17);
583
+ } catch (e) {
584
+ process.kill(process.pid, 'SIGKILL');
585
+ }
586
+ return;
587
+ }
588
+ if (scenario === 'self-sigkill-fallback-numeric') {
589
+ try {
590
+ process.exit(17);
591
+ } catch (e) {
592
+ process.kill(process.pid, 9);
593
+ }
594
+ return;
595
+ }
596
+ if (scenario === 'self-sigkill-fallback-no-code') {
597
+ try {
598
+ process.exit();
599
+ } catch (e) {
600
+ process.kill(process.pid, 'SIGKILL');
601
+ }
602
+ return;
603
+ }
604
+ if (scenario === 'other-process-kill') {
605
+ const cp = require('child_process');
606
+ const child = cp.spawn('node', ['-e', 'setTimeout(() => {}, 5000)']);
607
+ const childPid = child.pid;
608
+ process.kill(childPid, 0);
609
+ child.kill();
610
+ process.stdout.write('ok');
611
+ return;
612
+ }
580
613
  process.stdout.write('ok');
581
614
  }`;
582
615
  }
@@ -620,6 +653,45 @@ function runScenario({ printMode, stdinInherit, scenario }) {
620
653
  return { ...result, elapsedMs };
621
654
  }
622
655
 
656
+ test('helper and bootstrap intercept process.kill(self, SIGKILL) statically', () => {
657
+ const helperBlock = extractBlock('cat <<\'NODE\' > "$_helper"', '\n export ENABLE_CLAUDEAI_MCP_SERVERS=');
658
+ const bootstrapBlock = extractBlock('cat <<\'NODE\' > "$_bootstrap"', '\n export ENABLE_CLAUDEAI_MCP_SERVERS=');
659
+
660
+ // Check helper branch
661
+ const helperOriginalKillIdx = helperBlock.indexOf('const originalKill = process.kill;');
662
+ assert.ok(helperOriginalKillIdx > -1, 'helper: missing originalKill declaration');
663
+
664
+ const helperProcessKillIdx = helperBlock.indexOf('process.kill = (pid, signal) => {', helperOriginalKillIdx);
665
+ assert.ok(helperProcessKillIdx > helperOriginalKillIdx, 'helper: process.kill override must come after originalKill declaration');
666
+
667
+ const helperRestoreIdx = helperBlock.indexOf('process.kill = originalKill;', helperProcessKillIdx);
668
+ assert.ok(helperRestoreIdx > helperProcessKillIdx, 'helper: process.kill restoration must come after override');
669
+
670
+ // Verify SIGKILL check within the override
671
+ const helperKillOverrideEnd = helperBlock.indexOf('};', helperProcessKillIdx);
672
+ const helperKillOverride = helperBlock.slice(helperProcessKillIdx, helperKillOverrideEnd);
673
+ assert.ok(helperKillOverride.includes('signal === \'SIGKILL\''), 'helper: process.kill must check for SIGKILL string');
674
+ assert.ok(helperKillOverride.includes('signal === 9'), 'helper: process.kill must check for SIGKILL numeric value');
675
+ assert.ok(helperKillOverride.includes('throw new RequestedExit'), 'helper: process.kill must throw RequestedExit for self SIGKILL');
676
+
677
+ // Check bootstrap branch
678
+ const bootstrapOriginalKillIdx = bootstrapBlock.indexOf('const originalKill = process.kill;');
679
+ assert.ok(bootstrapOriginalKillIdx > -1, 'bootstrap: missing originalKill declaration');
680
+
681
+ const bootstrapProcessKillIdx = bootstrapBlock.indexOf('process.kill = (pid, signal) => {', bootstrapOriginalKillIdx);
682
+ assert.ok(bootstrapProcessKillIdx > bootstrapOriginalKillIdx, 'bootstrap: process.kill override must come after originalKill declaration');
683
+
684
+ const bootstrapRestoreIdx = bootstrapBlock.indexOf('process.kill = originalKill;', bootstrapProcessKillIdx);
685
+ assert.ok(bootstrapRestoreIdx > bootstrapProcessKillIdx, 'bootstrap: process.kill restoration must come after override');
686
+
687
+ // Verify SIGKILL check within the override
688
+ const bootstrapKillOverrideEnd = bootstrapBlock.indexOf('};', bootstrapProcessKillIdx);
689
+ const bootstrapKillOverride = bootstrapBlock.slice(bootstrapProcessKillIdx, bootstrapKillOverrideEnd);
690
+ assert.ok(bootstrapKillOverride.includes('signal === \'SIGKILL\''), 'bootstrap: process.kill must check for SIGKILL string');
691
+ assert.ok(bootstrapKillOverride.includes('signal === 9'), 'bootstrap: process.kill must check for SIGKILL numeric value');
692
+ assert.ok(bootstrapKillOverride.includes('throw new RequestedExit'), 'bootstrap: process.kill must throw RequestedExit for self SIGKILL');
693
+ });
694
+
623
695
  test('helper branch (CLI -p, no stdin inherit): normal/sync-exit/async-exit all produce output', () => {
624
696
  for (const scenario of ['normal', 'sync-exit', 'async-exit']) {
625
697
  const r = runScenario({ printMode: true, stdinInherit: false, scenario });
@@ -638,3 +710,27 @@ test('bootstrap branch (-p + CLAUDE_TERMUX_STDIN=inherit): normal/sync-exit/asyn
638
710
  }
639
711
  }
640
712
  });
713
+
714
+ test('helper branch intercepts self-directed SIGKILL (string signal) and exits with proper code', () => {
715
+ const r = runScenario({ printMode: true, stdinInherit: false, scenario: 'self-sigkill-fallback-string' });
716
+ assert.equal(r.status, 17, `expected status 17, got ${r.status}; stderr=${r.stderr}`);
717
+ assert.ok(!r.signal, `expected clean exit (no signal), but got signal: ${r.signal}`);
718
+ });
719
+
720
+ test('helper branch intercepts self-directed SIGKILL (numeric signal 9) and exits with proper code', () => {
721
+ const r = runScenario({ printMode: true, stdinInherit: false, scenario: 'self-sigkill-fallback-numeric' });
722
+ assert.equal(r.status, 17, `expected status 17, got ${r.status}; stderr=${r.stderr}`);
723
+ assert.ok(!r.signal, `expected clean exit (no signal), but got signal: ${r.signal}`);
724
+ });
725
+
726
+ test('helper branch intercepts self-directed SIGKILL with process.exit() (no code) and defaults to 0', () => {
727
+ const r = runScenario({ printMode: true, stdinInherit: false, scenario: 'self-sigkill-fallback-no-code' });
728
+ assert.equal(r.status, 0, `expected status 0, got ${r.status}; stderr=${r.stderr}`);
729
+ assert.ok(!r.signal, `expected clean exit (no signal), but got signal: ${r.signal}`);
730
+ });
731
+
732
+ test('helper branch allows process.kill to other processes (signal 0, passthrough)', () => {
733
+ const r = runScenario({ printMode: true, stdinInherit: false, scenario: 'other-process-kill' });
734
+ assert.ok((r.stdout || '').includes('ok'), `expected ok output, got stdout=${r.stdout} stderr=${r.stderr}`);
735
+ assert.equal(r.status, 0, `expected status 0, got ${r.status}; stderr=${r.stderr}`);
736
+ });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bash0816/claude-code",
3
- "version": "2.1.220-1",
3
+ "version": "2.1.220-2",
4
4
  "description": "Unofficial Termux-native Claude Code wrapper with audited native replay",
5
5
  "license": "GPL-3.0-only",
6
6
  "bin": {