@bash0816/claude-code 2.1.219 → 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
@@ -37,7 +37,7 @@ npm が `claude` bin link を管理する状態になれば、通常の `npm ins
37
37
  Latest audited version / 最新監査済み版:
38
38
 
39
39
  ```sh
40
- npm install -g @bash0816/claude-code@2.1.218
40
+ npm install -g @bash0816/claude-code@2.1.220
41
41
  ```
42
42
 
43
43
  ## Update / 更新
@@ -571,6 +571,24 @@
571
571
  "entry_end_offset": 265451802,
572
572
  "tarball_integrity": "sha512-G5yLidk2u6djL5PPuBYXVwVhTsZY5zLoZwh1Jnrd/IRyYb0P0x4gKTzVvGlsGepkBrOp0H2k/KuicyNPrXt57Q==",
573
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",
574
592
  "status": "offset_discovered"
575
593
  }
576
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.218",
5
- "latest_candidate_version": "2.1.219",
6
- "previous_stable_version": "2.1.217",
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
  }
@@ -636,6 +636,12 @@ async function main() {
636
636
  function onAsyncError(error) {
637
637
  asyncErrors.push(error);
638
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
+ }
639
645
 
640
646
  try {
641
647
  process.once('uncaughtException', onAsyncError);
@@ -697,18 +703,15 @@ async function main() {
697
703
  process.exit = code => {
698
704
  throw new RequestedExit(code);
699
705
  };
700
-
701
- const printWaitMs = Number(process.env.CLAUDE_TERMUX_PRINT_WAIT_MS || 5000);
702
706
  const moduleLike = { exports: {} };
703
707
  const maybePromise = fn(moduleLike.exports, fakeRequire, moduleLike, extractedFile, workdir);
704
708
  if (maybePromise && typeof maybePromise.then === 'function') await maybePromise;
705
- if (Number.isFinite(printWaitMs) && printWaitMs > 0) {
706
- await new Promise(resolve => setTimeout(resolve, printWaitMs));
707
- }
709
+ await waitForPrintFlush();
708
710
  if (asyncErrors.length > 0) throw asyncErrors[0];
709
711
  } catch (error) {
710
712
  if (error instanceof RequestedExit) {
711
713
  process.exitCode = error.code;
714
+ await waitForPrintFlush();
712
715
  return;
713
716
  }
714
717
  throw error;
@@ -758,6 +761,7 @@ else
758
761
  _bootstrap=$(mktemp "${TERMUX_TMPDIR}/claude-bootstrap.XXXXXX.js")
759
762
  trap 'rm -f "$_bootstrap"' EXIT HUP INT TERM
760
763
  export CLAUDE_TERMUX_TUI="${_tui}"
764
+ export CLAUDE_TERMUX_PRINT_MODE="${_pf}"
761
765
  cat <<'NODE' > "$_bootstrap"
762
766
  const fs = require('fs');
763
767
  const path = require('path');
@@ -1329,6 +1333,13 @@ async function main() {
1329
1333
  function onAsyncError(error) {
1330
1334
  asyncErrors.push(error);
1331
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
+ }
1332
1343
 
1333
1344
  try {
1334
1345
  process.once('uncaughtException', onAsyncError);
@@ -1394,10 +1405,12 @@ async function main() {
1394
1405
  const moduleLike = { exports: {} };
1395
1406
  const maybePromise = fn(moduleLike.exports, fakeRequire, moduleLike, extractedFile, workdir);
1396
1407
  if (maybePromise && typeof maybePromise.then === 'function') await maybePromise;
1408
+ await waitForPrintFlushIfNeeded();
1397
1409
  if (asyncErrors.length > 0) throw asyncErrors[0];
1398
1410
  } catch (error) {
1399
1411
  if (error instanceof RequestedExit) {
1400
1412
  process.exitCode = error.code;
1413
+ await waitForPrintFlushIfNeeded();
1401
1414
  return;
1402
1415
  }
1403
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=');
@@ -544,3 +564,77 @@ test('tarball contents match the workspace runner and test file', { skip: !fs.ex
544
564
  test('CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC is never forced (regression guard)', () => {
545
565
  assert.equal(script.includes('CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC'), false);
546
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
+ });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bash0816/claude-code",
3
- "version": "2.1.219",
3
+ "version": "2.1.220-1",
4
4
  "description": "Unofficial Termux-native Claude Code wrapper with audited native replay",
5
5
  "license": "GPL-3.0-only",
6
6
  "bin": {