@bash0816/claude-code 2.1.220 → 2.1.223
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
|
@@ -580,6 +580,60 @@
|
|
|
580
580
|
"entry_end_offset": 265457701,
|
|
581
581
|
"tarball_integrity": "sha512-VHFI8mKruIntKn7eq81sbyS19/KWmQcmJQsS/C+j9M/E+w0s4UytgsL7DADPjBE/GByNiKoRtLYDMntCjRlOdA==",
|
|
582
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",
|
|
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": "termux_verified"
|
|
602
|
+
},
|
|
603
|
+
"2.1.220-3": {
|
|
604
|
+
"wrapper_spec": "@anthropic-ai/claude-code@2.1.220",
|
|
605
|
+
"native_spec": "@anthropic-ai/claude-code-linux-arm64@2.1.220",
|
|
606
|
+
"entry_js_offset": 243831156,
|
|
607
|
+
"entry_end_offset": 265457701,
|
|
608
|
+
"tarball_integrity": "sha512-VHFI8mKruIntKn7eq81sbyS19/KWmQcmJQsS/C+j9M/E+w0s4UytgsL7DADPjBE/GByNiKoRtLYDMntCjRlOdA==",
|
|
609
|
+
"tarball_sha256": "e38454d73576a08a2e707f26539d73fc9ef33e890228ca5c58a2bbe810ac884d",
|
|
610
|
+
"status": "offset_discovered"
|
|
611
|
+
},
|
|
612
|
+
"2.1.222": {
|
|
613
|
+
"wrapper_spec": "@anthropic-ai/claude-code@2.1.222",
|
|
614
|
+
"native_spec": "@anthropic-ai/claude-code-linux-arm64@2.1.222",
|
|
615
|
+
"entry_js_offset": 256895476,
|
|
616
|
+
"entry_end_offset": 279849039,
|
|
617
|
+
"tarball_integrity": "sha512-EXSediF1ujcqQeElbXdCEe+uW3NUQAOjn1xHHAgvwzY08nzJeePjagn9+YS6bmhHxBgDKwlGu7pL8Kv7EpiFtg==",
|
|
618
|
+
"tarball_sha256": "1bb3c8364d652dd08a15856ee27c6600ecd1e45360243154fa846f240ce7a1df",
|
|
619
|
+
"status": "termux_verified"
|
|
620
|
+
},
|
|
621
|
+
"2.1.222-1": {
|
|
622
|
+
"wrapper_spec": "@anthropic-ai/claude-code@2.1.222",
|
|
623
|
+
"native_spec": "@anthropic-ai/claude-code-linux-arm64@2.1.222",
|
|
624
|
+
"entry_js_offset": 256895476,
|
|
625
|
+
"entry_end_offset": 279849039,
|
|
626
|
+
"tarball_integrity": "sha512-EXSediF1ujcqQeElbXdCEe+uW3NUQAOjn1xHHAgvwzY08nzJeePjagn9+YS6bmhHxBgDKwlGu7pL8Kv7EpiFtg==",
|
|
627
|
+
"tarball_sha256": "1bb3c8364d652dd08a15856ee27c6600ecd1e45360243154fa846f240ce7a1df",
|
|
628
|
+
"status": "offset_discovered"
|
|
629
|
+
},
|
|
630
|
+
"2.1.223": {
|
|
631
|
+
"wrapper_spec": "@anthropic-ai/claude-code@2.1.223",
|
|
632
|
+
"native_spec": "@anthropic-ai/claude-code-linux-arm64@2.1.223",
|
|
633
|
+
"entry_js_offset": 257987828,
|
|
634
|
+
"entry_end_offset": 281109040,
|
|
635
|
+
"tarball_integrity": "sha512-gh0n3fvUgzsrjeTqZraOhDKOzS7afB9U/qFvRY0FBpccogbJCk8otTYavPfdhAA2xESAoA0BaoVdzO4k4VkphA==",
|
|
636
|
+
"tarball_sha256": "29c49ec62bfbe995e5b1354a4c32d17101065d2c7722d5d0285cfa6a08d8c441",
|
|
583
637
|
"status": "offset_discovered"
|
|
584
638
|
}
|
|
585
639
|
}
|
|
@@ -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.222",
|
|
5
|
+
"latest_candidate_version": "2.1.223",
|
|
6
|
+
"previous_stable_version": "2.1.220-2",
|
|
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
|
}
|
|
@@ -79,6 +79,22 @@ const entryJsOffset = Number(process.env.ENTRY_JS_OFFSET);
|
|
|
79
79
|
const entryEndOffset = Number(process.env.ENTRY_END_OFFSET);
|
|
80
80
|
const argv = process.argv.slice(2);
|
|
81
81
|
|
|
82
|
+
function isStreamJsonPrintMode(argv) {
|
|
83
|
+
const dashDashIndex = argv.indexOf('--');
|
|
84
|
+
const ownArgs = dashDashIndex === -1 ? argv : argv.slice(0, dashDashIndex);
|
|
85
|
+
const hasPrintFlag = ownArgs.includes('-p') || ownArgs.includes('--print');
|
|
86
|
+
let hasStreamJsonFormat = false;
|
|
87
|
+
for (let i = 0; i < ownArgs.length; i++) {
|
|
88
|
+
const tok = ownArgs[i];
|
|
89
|
+
if (tok === '--output-format=stream-json') { hasStreamJsonFormat = true; break; }
|
|
90
|
+
if (tok === '--output-format' && ownArgs[i + 1] === 'stream-json') {
|
|
91
|
+
hasStreamJsonFormat = true;
|
|
92
|
+
break;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
return hasPrintFlag && hasStreamJsonFormat;
|
|
96
|
+
}
|
|
97
|
+
|
|
82
98
|
class RequestedExit extends Error {
|
|
83
99
|
constructor(code) {
|
|
84
100
|
super(`process.exit ${code}`);
|
|
@@ -583,6 +599,7 @@ function rewriteNativeChunkSource(source) {
|
|
|
583
599
|
const _bunPropertyAccessExpected = (() => {
|
|
584
600
|
const _ver = String(process.env.CURRENT_CLAUDE_VERSION || '');
|
|
585
601
|
const _m = _ver.match(/^(\d+)\.(\d+)\.(\d+)/);
|
|
602
|
+
if (_m && (Number(_m[1]) > 2 || Number(_m[2]) > 1 || Number(_m[3]) >= 223)) return 43;
|
|
586
603
|
if (_m && (Number(_m[1]) > 2 || Number(_m[2]) > 1 || Number(_m[3]) >= 219)) return 42;
|
|
587
604
|
if (_m && (Number(_m[1]) > 2 || Number(_m[2]) > 1 || Number(_m[3]) >= 216)) return 40;
|
|
588
605
|
if (_m && (Number(_m[1]) > 2 || Number(_m[2]) > 1 || Number(_m[3]) >= 214)) return 39;
|
|
@@ -611,6 +628,13 @@ function rewriteNativeChunkSource(source) {
|
|
|
611
628
|
'npmInstallDeprecated flag',
|
|
612
629
|
_npmInstallDeprecatedExpected,
|
|
613
630
|
);
|
|
631
|
+
patched = replaceRequired(
|
|
632
|
+
patched,
|
|
633
|
+
/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,
|
|
634
|
+
'function $1(){return undefined;$2',
|
|
635
|
+
'bg-pty-host factory disable',
|
|
636
|
+
1,
|
|
637
|
+
);
|
|
614
638
|
return patched;
|
|
615
639
|
}
|
|
616
640
|
|
|
@@ -623,10 +647,12 @@ async function main() {
|
|
|
623
647
|
|
|
624
648
|
const originalArgv = process.argv.slice();
|
|
625
649
|
const originalExit = process.exit;
|
|
650
|
+
const originalKill = process.kill;
|
|
626
651
|
const originalBun = process.versions.bun;
|
|
627
652
|
const hadGlobalBun = Object.prototype.hasOwnProperty.call(globalThis, 'Bun');
|
|
628
653
|
const originalGlobalBun = globalThis.Bun;
|
|
629
654
|
const asyncErrors = [];
|
|
655
|
+
let streamJsonWatcher = null;
|
|
630
656
|
|
|
631
657
|
globalThis.__claudeYaml = createYamlShim();
|
|
632
658
|
if (!globalThis.__claudeBunShim || typeof globalThis.__claudeBunShim !== 'object') {
|
|
@@ -636,6 +662,100 @@ async function main() {
|
|
|
636
662
|
function onAsyncError(error) {
|
|
637
663
|
asyncErrors.push(error);
|
|
638
664
|
}
|
|
665
|
+
const printWaitMs = Number(process.env.CLAUDE_TERMUX_PRINT_WAIT_MS || 5000);
|
|
666
|
+
|
|
667
|
+
function installStreamJsonTerminalWatcher() {
|
|
668
|
+
const hadOwnWrite = Object.prototype.hasOwnProperty.call(process.stdout, 'write');
|
|
669
|
+
const originalWriteDescriptor = hadOwnWrite ? Object.getOwnPropertyDescriptor(process.stdout, 'write') : undefined;
|
|
670
|
+
const originalWrite = process.stdout.write.bind(process.stdout);
|
|
671
|
+
const { StringDecoder } = require('string_decoder');
|
|
672
|
+
const decoder = new StringDecoder('utf8');
|
|
673
|
+
let lineBuffer = '';
|
|
674
|
+
let resultPromiseResolve = null;
|
|
675
|
+
let foundResult = false;
|
|
676
|
+
let restored = false;
|
|
677
|
+
|
|
678
|
+
process.stdout.write = function wrappedWrite(chunk, encoding, callback) {
|
|
679
|
+
let cb = callback;
|
|
680
|
+
let enc = encoding;
|
|
681
|
+
if (typeof encoding === 'function') {
|
|
682
|
+
cb = encoding;
|
|
683
|
+
enc = undefined;
|
|
684
|
+
}
|
|
685
|
+
const combinedCallback = (err) => {
|
|
686
|
+
if (!err && !foundResult) {
|
|
687
|
+
const chunkStr = typeof chunk === 'string'
|
|
688
|
+
? decoder.write(Buffer.from(chunk, typeof enc === 'string' ? enc : 'utf8'))
|
|
689
|
+
: decoder.write(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk));
|
|
690
|
+
lineBuffer += chunkStr;
|
|
691
|
+
const lines = lineBuffer.split('\n');
|
|
692
|
+
lineBuffer = lines[lines.length - 1];
|
|
693
|
+
for (let i = 0; i < lines.length - 1; i++) {
|
|
694
|
+
try {
|
|
695
|
+
const parsed = JSON.parse(lines[i]);
|
|
696
|
+
if (parsed && parsed.type === 'result') {
|
|
697
|
+
foundResult = true;
|
|
698
|
+
if (typeof resultPromiseResolve === 'function') resultPromiseResolve();
|
|
699
|
+
}
|
|
700
|
+
} catch {}
|
|
701
|
+
}
|
|
702
|
+
}
|
|
703
|
+
if (typeof cb === 'function') cb(err);
|
|
704
|
+
};
|
|
705
|
+
return originalWrite(chunk, enc, combinedCallback);
|
|
706
|
+
};
|
|
707
|
+
|
|
708
|
+
return {
|
|
709
|
+
waitForResult() {
|
|
710
|
+
if (foundResult) return Promise.resolve();
|
|
711
|
+
return new Promise((resolve, reject) => {
|
|
712
|
+
resultPromiseResolve = resolve;
|
|
713
|
+
});
|
|
714
|
+
},
|
|
715
|
+
restore() {
|
|
716
|
+
if (restored) return;
|
|
717
|
+
restored = true;
|
|
718
|
+
if (hadOwnWrite) {
|
|
719
|
+
Object.defineProperty(process.stdout, 'write', originalWriteDescriptor);
|
|
720
|
+
} else {
|
|
721
|
+
delete process.stdout.write;
|
|
722
|
+
}
|
|
723
|
+
},
|
|
724
|
+
};
|
|
725
|
+
}
|
|
726
|
+
|
|
727
|
+
function forceTimeoutExit(exitCode) {
|
|
728
|
+
try { if (streamJsonWatcher) streamJsonWatcher.restore(); } catch {}
|
|
729
|
+
if (extractedFile) {
|
|
730
|
+
try { fs.rmSync(extractedFile, { force: true }); } catch {}
|
|
731
|
+
}
|
|
732
|
+
originalExit(exitCode);
|
|
733
|
+
}
|
|
734
|
+
|
|
735
|
+
async function waitForPrintFlush() {
|
|
736
|
+
if (isStreamJsonPrintMode(argv) && streamJsonWatcher) {
|
|
737
|
+
let timedOut = false;
|
|
738
|
+
const rawResultTimeoutMs = Number(process.env.CLAUDE_TERMUX_PRINT_RESULT_TIMEOUT_MS);
|
|
739
|
+
const resultTimeoutMs = (Number.isFinite(rawResultTimeoutMs) && rawResultTimeoutMs > 0) ? rawResultTimeoutMs : 300000;
|
|
740
|
+
let timeoutHandle;
|
|
741
|
+
const timeoutPromise = new Promise(resolve => {
|
|
742
|
+
timeoutHandle = setTimeout(() => { timedOut = true; resolve(); }, resultTimeoutMs);
|
|
743
|
+
});
|
|
744
|
+
try {
|
|
745
|
+
await Promise.race([streamJsonWatcher.waitForResult(), timeoutPromise]);
|
|
746
|
+
} finally {
|
|
747
|
+
clearTimeout(timeoutHandle);
|
|
748
|
+
}
|
|
749
|
+
if (timedOut) {
|
|
750
|
+
forceTimeoutExit(1);
|
|
751
|
+
return;
|
|
752
|
+
}
|
|
753
|
+
return;
|
|
754
|
+
}
|
|
755
|
+
if (Number.isFinite(printWaitMs) && printWaitMs > 0) {
|
|
756
|
+
await new Promise(resolve => setTimeout(resolve, printWaitMs));
|
|
757
|
+
}
|
|
758
|
+
}
|
|
639
759
|
|
|
640
760
|
try {
|
|
641
761
|
process.once('uncaughtException', onAsyncError);
|
|
@@ -683,9 +803,47 @@ async function main() {
|
|
|
683
803
|
gte: (a, b) => _cmp(a, b) >= 0,
|
|
684
804
|
lt: (a, b) => _cmp(a, b) < 0,
|
|
685
805
|
lte: (a, b) => _cmp(a, b) <= 0,
|
|
686
|
-
|
|
806
|
+
};
|
|
687
807
|
})(),
|
|
688
808
|
YAML: globalThis.__claudeYaml,
|
|
809
|
+
spawn: (cmd, options) => {
|
|
810
|
+
const opts = options || {};
|
|
811
|
+
const stdioArrayRaw = opts.stdio;
|
|
812
|
+
const cmdArray = Array.isArray(cmd) ? cmd : [cmd];
|
|
813
|
+
const normalizeStdio = (v) => {
|
|
814
|
+
if (typeof v === 'number' && Number.isInteger(v) && v >= 0) return v;
|
|
815
|
+
return (v === 'ignore' || v === 'pipe' || v === 'inherit') ? v : 'pipe';
|
|
816
|
+
};
|
|
817
|
+
const stdioMapped = Array.isArray(stdioArrayRaw)
|
|
818
|
+
? stdioArrayRaw.map(normalizeStdio)
|
|
819
|
+
: [normalizeStdio(opts.stdin), normalizeStdio(opts.stdout), normalizeStdio(opts.stderr)];
|
|
820
|
+
const child = _realChild.spawn(cmdArray[0], cmdArray.slice(1), {
|
|
821
|
+
stdio: stdioMapped,
|
|
822
|
+
cwd: opts.cwd,
|
|
823
|
+
env: opts.env,
|
|
824
|
+
detached: !!opts.detached,
|
|
825
|
+
argv0: opts.argv0,
|
|
826
|
+
});
|
|
827
|
+
const stdoutChunks = [];
|
|
828
|
+
if (child.stdout) child.stdout.on('data', d => stdoutChunks.push(d));
|
|
829
|
+
let resolveExited;
|
|
830
|
+
const exited = new Promise(resolve => { resolveExited = resolve; });
|
|
831
|
+
child.on('exit', (code, signal) => resolveExited(code !== null ? code : (signal ? 128 : 0)));
|
|
832
|
+
child.on('error', () => resolveExited(1));
|
|
833
|
+
return {
|
|
834
|
+
pid: child.pid,
|
|
835
|
+
exited,
|
|
836
|
+
stdout: { text: async () => { await exited; return Buffer.concat(stdoutChunks).toString('utf8'); } },
|
|
837
|
+
unref: () => { try { child.unref(); } catch {} },
|
|
838
|
+
kill: (signal) => { try { child.kill(signal); } catch {} },
|
|
839
|
+
};
|
|
840
|
+
},
|
|
841
|
+
file: (path) => {
|
|
842
|
+
const err = new Error(`ENOENT: Bun.file(${String(path)}) is not supported by the Termux compatibility shim`);
|
|
843
|
+
err.code = 'ENOENT';
|
|
844
|
+
err.errno = -2;
|
|
845
|
+
throw err;
|
|
846
|
+
},
|
|
689
847
|
};
|
|
690
848
|
Object.assign(globalThis.__claudeBunShim, globalThis.Bun);
|
|
691
849
|
if (typeof globalThis.__claudeBunShim.gc !== 'function') {
|
|
@@ -694,21 +852,31 @@ async function main() {
|
|
|
694
852
|
globalThis.__claudeBun = globalThis.__claudeBunShim;
|
|
695
853
|
globalThis.Bun = globalThis.__claudeBunShim;
|
|
696
854
|
process.argv = ['node', extractedFile, ...argv];
|
|
855
|
+
let lastExitAttemptCode = 0;
|
|
697
856
|
process.exit = code => {
|
|
698
|
-
|
|
857
|
+
lastExitAttemptCode = code ?? 0;
|
|
858
|
+
throw new RequestedExit(lastExitAttemptCode);
|
|
859
|
+
};
|
|
860
|
+
process.kill = (pid, signal) => {
|
|
861
|
+
if (pid === process.pid && (signal === 'SIGKILL' || signal === 9)) {
|
|
862
|
+
throw new RequestedExit(lastExitAttemptCode);
|
|
863
|
+
}
|
|
864
|
+
return originalKill.call(process, pid, signal);
|
|
699
865
|
};
|
|
700
866
|
|
|
701
|
-
|
|
867
|
+
if (isStreamJsonPrintMode(argv)) {
|
|
868
|
+
streamJsonWatcher = installStreamJsonTerminalWatcher();
|
|
869
|
+
}
|
|
870
|
+
|
|
702
871
|
const moduleLike = { exports: {} };
|
|
703
872
|
const maybePromise = fn(moduleLike.exports, fakeRequire, moduleLike, extractedFile, workdir);
|
|
704
873
|
if (maybePromise && typeof maybePromise.then === 'function') await maybePromise;
|
|
705
|
-
|
|
706
|
-
await new Promise(resolve => setTimeout(resolve, printWaitMs));
|
|
707
|
-
}
|
|
874
|
+
await waitForPrintFlush();
|
|
708
875
|
if (asyncErrors.length > 0) throw asyncErrors[0];
|
|
709
876
|
} catch (error) {
|
|
710
877
|
if (error instanceof RequestedExit) {
|
|
711
878
|
process.exitCode = error.code;
|
|
879
|
+
await waitForPrintFlush();
|
|
712
880
|
return;
|
|
713
881
|
}
|
|
714
882
|
throw error;
|
|
@@ -722,6 +890,10 @@ async function main() {
|
|
|
722
890
|
}
|
|
723
891
|
process.argv = originalArgv;
|
|
724
892
|
process.exit = originalExit;
|
|
893
|
+
process.kill = originalKill;
|
|
894
|
+
if (streamJsonWatcher) {
|
|
895
|
+
try { streamJsonWatcher.restore(); } catch {}
|
|
896
|
+
}
|
|
725
897
|
try {
|
|
726
898
|
if (originalBun === undefined) {
|
|
727
899
|
delete process.versions.bun;
|
|
@@ -758,6 +930,7 @@ else
|
|
|
758
930
|
_bootstrap=$(mktemp "${TERMUX_TMPDIR}/claude-bootstrap.XXXXXX.js")
|
|
759
931
|
trap 'rm -f "$_bootstrap"' EXIT HUP INT TERM
|
|
760
932
|
export CLAUDE_TERMUX_TUI="${_tui}"
|
|
933
|
+
export CLAUDE_TERMUX_PRINT_MODE="${_pf}"
|
|
761
934
|
cat <<'NODE' > "$_bootstrap"
|
|
762
935
|
const fs = require('fs');
|
|
763
936
|
const path = require('path');
|
|
@@ -772,6 +945,22 @@ const entryJsOffset = Number(process.env.ENTRY_JS_OFFSET);
|
|
|
772
945
|
const entryEndOffset = Number(process.env.ENTRY_END_OFFSET);
|
|
773
946
|
const argv = process.argv.slice(2);
|
|
774
947
|
|
|
948
|
+
function isStreamJsonPrintMode(argv) {
|
|
949
|
+
const dashDashIndex = argv.indexOf('--');
|
|
950
|
+
const ownArgs = dashDashIndex === -1 ? argv : argv.slice(0, dashDashIndex);
|
|
951
|
+
const hasPrintFlag = ownArgs.includes('-p') || ownArgs.includes('--print');
|
|
952
|
+
let hasStreamJsonFormat = false;
|
|
953
|
+
for (let i = 0; i < ownArgs.length; i++) {
|
|
954
|
+
const tok = ownArgs[i];
|
|
955
|
+
if (tok === '--output-format=stream-json') { hasStreamJsonFormat = true; break; }
|
|
956
|
+
if (tok === '--output-format' && ownArgs[i + 1] === 'stream-json') {
|
|
957
|
+
hasStreamJsonFormat = true;
|
|
958
|
+
break;
|
|
959
|
+
}
|
|
960
|
+
}
|
|
961
|
+
return hasPrintFlag && hasStreamJsonFormat;
|
|
962
|
+
}
|
|
963
|
+
|
|
775
964
|
class RequestedExit extends Error {
|
|
776
965
|
constructor(code) {
|
|
777
966
|
super(`process.exit ${code}`);
|
|
@@ -1276,6 +1465,7 @@ function rewriteNativeChunkSource(source) {
|
|
|
1276
1465
|
const _bunPropertyAccessExpected = (() => {
|
|
1277
1466
|
const _ver = String(process.env.CURRENT_CLAUDE_VERSION || '');
|
|
1278
1467
|
const _m = _ver.match(/^(\d+)\.(\d+)\.(\d+)/);
|
|
1468
|
+
if (_m && (Number(_m[1]) > 2 || Number(_m[2]) > 1 || Number(_m[3]) >= 223)) return 43;
|
|
1279
1469
|
if (_m && (Number(_m[1]) > 2 || Number(_m[2]) > 1 || Number(_m[3]) >= 219)) return 42;
|
|
1280
1470
|
if (_m && (Number(_m[1]) > 2 || Number(_m[2]) > 1 || Number(_m[3]) >= 216)) return 40;
|
|
1281
1471
|
if (_m && (Number(_m[1]) > 2 || Number(_m[2]) > 1 || Number(_m[3]) >= 214)) return 39;
|
|
@@ -1304,6 +1494,13 @@ function rewriteNativeChunkSource(source) {
|
|
|
1304
1494
|
'npmInstallDeprecated flag',
|
|
1305
1495
|
_npmInstallDeprecatedExpected,
|
|
1306
1496
|
);
|
|
1497
|
+
patched = replaceRequired(
|
|
1498
|
+
patched,
|
|
1499
|
+
/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,
|
|
1500
|
+
'function $1(){return undefined;$2',
|
|
1501
|
+
'bg-pty-host factory disable',
|
|
1502
|
+
1,
|
|
1503
|
+
);
|
|
1307
1504
|
return patched;
|
|
1308
1505
|
}
|
|
1309
1506
|
|
|
@@ -1316,10 +1513,12 @@ async function main() {
|
|
|
1316
1513
|
|
|
1317
1514
|
const originalArgv = process.argv.slice();
|
|
1318
1515
|
const originalExit = process.exit;
|
|
1516
|
+
const originalKill = process.kill;
|
|
1319
1517
|
const originalBun = process.versions.bun;
|
|
1320
1518
|
const hadGlobalBun = Object.prototype.hasOwnProperty.call(globalThis, 'Bun');
|
|
1321
1519
|
const originalGlobalBun = globalThis.Bun;
|
|
1322
1520
|
const asyncErrors = [];
|
|
1521
|
+
let streamJsonWatcher = null;
|
|
1323
1522
|
|
|
1324
1523
|
globalThis.__claudeYaml = createYamlShim();
|
|
1325
1524
|
if (!globalThis.__claudeBunShim || typeof globalThis.__claudeBunShim !== 'object') {
|
|
@@ -1330,6 +1529,101 @@ async function main() {
|
|
|
1330
1529
|
asyncErrors.push(error);
|
|
1331
1530
|
}
|
|
1332
1531
|
|
|
1532
|
+
function installStreamJsonTerminalWatcher() {
|
|
1533
|
+
const hadOwnWrite = Object.prototype.hasOwnProperty.call(process.stdout, 'write');
|
|
1534
|
+
const originalWriteDescriptor = hadOwnWrite ? Object.getOwnPropertyDescriptor(process.stdout, 'write') : undefined;
|
|
1535
|
+
const originalWrite = process.stdout.write.bind(process.stdout);
|
|
1536
|
+
const { StringDecoder } = require('string_decoder');
|
|
1537
|
+
const decoder = new StringDecoder('utf8');
|
|
1538
|
+
let lineBuffer = '';
|
|
1539
|
+
let resultPromiseResolve = null;
|
|
1540
|
+
let foundResult = false;
|
|
1541
|
+
let restored = false;
|
|
1542
|
+
|
|
1543
|
+
process.stdout.write = function wrappedWrite(chunk, encoding, callback) {
|
|
1544
|
+
let cb = callback;
|
|
1545
|
+
let enc = encoding;
|
|
1546
|
+
if (typeof encoding === 'function') {
|
|
1547
|
+
cb = encoding;
|
|
1548
|
+
enc = undefined;
|
|
1549
|
+
}
|
|
1550
|
+
const combinedCallback = (err) => {
|
|
1551
|
+
if (!err && !foundResult) {
|
|
1552
|
+
const chunkStr = typeof chunk === 'string'
|
|
1553
|
+
? decoder.write(Buffer.from(chunk, typeof enc === 'string' ? enc : 'utf8'))
|
|
1554
|
+
: decoder.write(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk));
|
|
1555
|
+
lineBuffer += chunkStr;
|
|
1556
|
+
const lines = lineBuffer.split('\n');
|
|
1557
|
+
lineBuffer = lines[lines.length - 1];
|
|
1558
|
+
for (let i = 0; i < lines.length - 1; i++) {
|
|
1559
|
+
try {
|
|
1560
|
+
const parsed = JSON.parse(lines[i]);
|
|
1561
|
+
if (parsed && parsed.type === 'result') {
|
|
1562
|
+
foundResult = true;
|
|
1563
|
+
if (typeof resultPromiseResolve === 'function') resultPromiseResolve();
|
|
1564
|
+
}
|
|
1565
|
+
} catch {}
|
|
1566
|
+
}
|
|
1567
|
+
}
|
|
1568
|
+
if (typeof cb === 'function') cb(err);
|
|
1569
|
+
};
|
|
1570
|
+
return originalWrite(chunk, enc, combinedCallback);
|
|
1571
|
+
};
|
|
1572
|
+
|
|
1573
|
+
return {
|
|
1574
|
+
waitForResult() {
|
|
1575
|
+
if (foundResult) return Promise.resolve();
|
|
1576
|
+
return new Promise((resolve, reject) => {
|
|
1577
|
+
resultPromiseResolve = resolve;
|
|
1578
|
+
});
|
|
1579
|
+
},
|
|
1580
|
+
restore() {
|
|
1581
|
+
if (restored) return;
|
|
1582
|
+
restored = true;
|
|
1583
|
+
if (hadOwnWrite) {
|
|
1584
|
+
Object.defineProperty(process.stdout, 'write', originalWriteDescriptor);
|
|
1585
|
+
} else {
|
|
1586
|
+
delete process.stdout.write;
|
|
1587
|
+
}
|
|
1588
|
+
},
|
|
1589
|
+
};
|
|
1590
|
+
}
|
|
1591
|
+
|
|
1592
|
+
function forceTimeoutExit(exitCode) {
|
|
1593
|
+
try { if (streamJsonWatcher) streamJsonWatcher.restore(); } catch {}
|
|
1594
|
+
if (extractedFile) {
|
|
1595
|
+
try { fs.rmSync(extractedFile, { force: true }); } catch {}
|
|
1596
|
+
}
|
|
1597
|
+
originalExit(exitCode);
|
|
1598
|
+
}
|
|
1599
|
+
|
|
1600
|
+
async function waitForPrintFlushIfNeeded() {
|
|
1601
|
+
if (process.env.CLAUDE_TERMUX_PRINT_MODE !== '1') return;
|
|
1602
|
+
if (isStreamJsonPrintMode(argv) && streamJsonWatcher) {
|
|
1603
|
+
let timedOut = false;
|
|
1604
|
+
const rawResultTimeoutMs = Number(process.env.CLAUDE_TERMUX_PRINT_RESULT_TIMEOUT_MS);
|
|
1605
|
+
const resultTimeoutMs = (Number.isFinite(rawResultTimeoutMs) && rawResultTimeoutMs > 0) ? rawResultTimeoutMs : 300000;
|
|
1606
|
+
let timeoutHandle;
|
|
1607
|
+
const timeoutPromise = new Promise(resolve => {
|
|
1608
|
+
timeoutHandle = setTimeout(() => { timedOut = true; resolve(); }, resultTimeoutMs);
|
|
1609
|
+
});
|
|
1610
|
+
try {
|
|
1611
|
+
await Promise.race([streamJsonWatcher.waitForResult(), timeoutPromise]);
|
|
1612
|
+
} finally {
|
|
1613
|
+
clearTimeout(timeoutHandle);
|
|
1614
|
+
}
|
|
1615
|
+
if (timedOut) {
|
|
1616
|
+
forceTimeoutExit(1);
|
|
1617
|
+
return;
|
|
1618
|
+
}
|
|
1619
|
+
return;
|
|
1620
|
+
}
|
|
1621
|
+
const printWaitMs = Number(process.env.CLAUDE_TERMUX_PRINT_WAIT_MS || 5000);
|
|
1622
|
+
if (Number.isFinite(printWaitMs) && printWaitMs > 0) {
|
|
1623
|
+
await new Promise(resolve => setTimeout(resolve, printWaitMs));
|
|
1624
|
+
}
|
|
1625
|
+
}
|
|
1626
|
+
|
|
1333
1627
|
try {
|
|
1334
1628
|
process.once('uncaughtException', onAsyncError);
|
|
1335
1629
|
process.once('unhandledRejection', onAsyncError);
|
|
@@ -1379,6 +1673,44 @@ async function main() {
|
|
|
1379
1673
|
};
|
|
1380
1674
|
})(),
|
|
1381
1675
|
YAML: globalThis.__claudeYaml,
|
|
1676
|
+
spawn: (cmd, options) => {
|
|
1677
|
+
const opts = options || {};
|
|
1678
|
+
const stdioArrayRaw = opts.stdio;
|
|
1679
|
+
const cmdArray = Array.isArray(cmd) ? cmd : [cmd];
|
|
1680
|
+
const normalizeStdio = (v) => {
|
|
1681
|
+
if (typeof v === 'number' && Number.isInteger(v) && v >= 0) return v;
|
|
1682
|
+
return (v === 'ignore' || v === 'pipe' || v === 'inherit') ? v : 'pipe';
|
|
1683
|
+
};
|
|
1684
|
+
const stdioMapped = Array.isArray(stdioArrayRaw)
|
|
1685
|
+
? stdioArrayRaw.map(normalizeStdio)
|
|
1686
|
+
: [normalizeStdio(opts.stdin), normalizeStdio(opts.stdout), normalizeStdio(opts.stderr)];
|
|
1687
|
+
const child = _realChild.spawn(cmdArray[0], cmdArray.slice(1), {
|
|
1688
|
+
stdio: stdioMapped,
|
|
1689
|
+
cwd: opts.cwd,
|
|
1690
|
+
env: opts.env,
|
|
1691
|
+
detached: !!opts.detached,
|
|
1692
|
+
argv0: opts.argv0,
|
|
1693
|
+
});
|
|
1694
|
+
const stdoutChunks = [];
|
|
1695
|
+
if (child.stdout) child.stdout.on('data', d => stdoutChunks.push(d));
|
|
1696
|
+
let resolveExited;
|
|
1697
|
+
const exited = new Promise(resolve => { resolveExited = resolve; });
|
|
1698
|
+
child.on('exit', (code, signal) => resolveExited(code !== null ? code : (signal ? 128 : 0)));
|
|
1699
|
+
child.on('error', () => resolveExited(1));
|
|
1700
|
+
return {
|
|
1701
|
+
pid: child.pid,
|
|
1702
|
+
exited,
|
|
1703
|
+
stdout: { text: async () => { await exited; return Buffer.concat(stdoutChunks).toString('utf8'); } },
|
|
1704
|
+
unref: () => { try { child.unref(); } catch {} },
|
|
1705
|
+
kill: (signal) => { try { child.kill(signal); } catch {} },
|
|
1706
|
+
};
|
|
1707
|
+
},
|
|
1708
|
+
file: (path) => {
|
|
1709
|
+
const err = new Error(`ENOENT: Bun.file(${String(path)}) is not supported by the Termux compatibility shim`);
|
|
1710
|
+
err.code = 'ENOENT';
|
|
1711
|
+
err.errno = -2;
|
|
1712
|
+
throw err;
|
|
1713
|
+
},
|
|
1382
1714
|
};
|
|
1383
1715
|
Object.assign(globalThis.__claudeBunShim, globalThis.Bun);
|
|
1384
1716
|
if (typeof globalThis.__claudeBunShim.gc !== 'function') {
|
|
@@ -1387,17 +1719,31 @@ async function main() {
|
|
|
1387
1719
|
globalThis.__claudeBun = globalThis.__claudeBunShim;
|
|
1388
1720
|
globalThis.Bun = globalThis.__claudeBunShim;
|
|
1389
1721
|
process.argv = ['node', extractedFile, ...argv];
|
|
1722
|
+
let lastExitAttemptCode = 0;
|
|
1390
1723
|
process.exit = code => {
|
|
1391
|
-
|
|
1724
|
+
lastExitAttemptCode = code ?? 0;
|
|
1725
|
+
throw new RequestedExit(lastExitAttemptCode);
|
|
1726
|
+
};
|
|
1727
|
+
process.kill = (pid, signal) => {
|
|
1728
|
+
if (pid === process.pid && (signal === 'SIGKILL' || signal === 9)) {
|
|
1729
|
+
throw new RequestedExit(lastExitAttemptCode);
|
|
1730
|
+
}
|
|
1731
|
+
return originalKill.call(process, pid, signal);
|
|
1392
1732
|
};
|
|
1393
1733
|
|
|
1734
|
+
if (isStreamJsonPrintMode(argv)) {
|
|
1735
|
+
streamJsonWatcher = installStreamJsonTerminalWatcher();
|
|
1736
|
+
}
|
|
1737
|
+
|
|
1394
1738
|
const moduleLike = { exports: {} };
|
|
1395
1739
|
const maybePromise = fn(moduleLike.exports, fakeRequire, moduleLike, extractedFile, workdir);
|
|
1396
1740
|
if (maybePromise && typeof maybePromise.then === 'function') await maybePromise;
|
|
1741
|
+
await waitForPrintFlushIfNeeded();
|
|
1397
1742
|
if (asyncErrors.length > 0) throw asyncErrors[0];
|
|
1398
1743
|
} catch (error) {
|
|
1399
1744
|
if (error instanceof RequestedExit) {
|
|
1400
1745
|
process.exitCode = error.code;
|
|
1746
|
+
await waitForPrintFlushIfNeeded();
|
|
1401
1747
|
return;
|
|
1402
1748
|
}
|
|
1403
1749
|
throw error;
|
|
@@ -1406,6 +1752,10 @@ async function main() {
|
|
|
1406
1752
|
process.removeListener('unhandledRejection', onAsyncError);
|
|
1407
1753
|
process.argv = originalArgv;
|
|
1408
1754
|
process.exit = originalExit;
|
|
1755
|
+
process.kill = originalKill;
|
|
1756
|
+
if (streamJsonWatcher) {
|
|
1757
|
+
try { streamJsonWatcher.restore(); } catch {}
|
|
1758
|
+
}
|
|
1409
1759
|
process.once('exit', () => {
|
|
1410
1760
|
if (extractedFile) {
|
|
1411
1761
|
try {
|