@bash0816/claude-code 2.1.248 → 2.1.251
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 +46 -1
- package/bin/claude +2 -2
- package/config/claude-native-audited-versions.json +154 -10
- package/config/claude-termux-release-manifest.json +3 -3
- package/lib/bunfs-esm-loader.mjs +141 -21
- package/lib/bunfs-esm-loader.test.js +875 -0
- package/lib/termux-run-claude-native.sh +13 -2
- package/lib/termux-run-claude-native.test.js +123 -0
- package/package.json +2 -2
|
@@ -55,6 +55,7 @@ export ENTRY_FORMAT
|
|
|
55
55
|
export ENTRY_JS_OFFSET
|
|
56
56
|
export ENTRY_END_OFFSET
|
|
57
57
|
export CURRENT_CLAUDE_VERSION
|
|
58
|
+
export ENABLE_TOOL_SEARCH="${ENABLE_TOOL_SEARCH:-false}"
|
|
58
59
|
|
|
59
60
|
_pf=0
|
|
60
61
|
for _a in "$@"; do
|
|
@@ -664,7 +665,7 @@ function rewriteNativeChunkSource(source) {
|
|
|
664
665
|
}
|
|
665
666
|
|
|
666
667
|
async function esmChunkedMain() {
|
|
667
|
-
const { prepareProcessOwnedDir } = require(path.join(process.env.CLAUDE_TERMUX_PACKAGE_DIR, 'lib', 'bunfs-extract.js'));
|
|
668
|
+
const { prepareProcessOwnedDir, extractToProcessOwnedDir } = require(path.join(process.env.CLAUDE_TERMUX_PACKAGE_DIR, 'lib', 'bunfs-extract.js'));
|
|
668
669
|
const { registerHooks } = require('node:module');
|
|
669
670
|
const { pathToFileURL } = require('node:url');
|
|
670
671
|
|
|
@@ -685,6 +686,9 @@ async function esmChunkedMain() {
|
|
|
685
686
|
},
|
|
686
687
|
gc: () => {},
|
|
687
688
|
YAML: globalThis.__claudeYaml,
|
|
689
|
+
zstdDecompressSync: (buf) => require('node:zlib').zstdDecompressSync(buf),
|
|
690
|
+
zstdDecompress: (buf) => new Promise((res, rej) =>
|
|
691
|
+
require('node:zlib').zstdDecompress(buf, (e, r) => (e ? rej(e) : res(r)))),
|
|
688
692
|
};
|
|
689
693
|
Object.defineProperty(process.versions, 'bun', { value: '1.1.8', configurable: true });
|
|
690
694
|
globalThis.__claudeBunShim = globalThis.Bun;
|
|
@@ -709,7 +713,9 @@ async function esmChunkedMain() {
|
|
|
709
713
|
vmGuardPath: path.join(libDir, 'bunfs-vm-guard.mjs'),
|
|
710
714
|
wsStubPath: path.join(libDir, 'bunfs-ws-stub.mjs'),
|
|
711
715
|
cycleHoists,
|
|
716
|
+
reExtract: (sb, od) => extractToProcessOwnedDir(sb, od),
|
|
712
717
|
});
|
|
718
|
+
loaderMod.installFsBunfsInterception();
|
|
713
719
|
registerHooks({ resolve: loaderMod.resolve, load: loaderMod.load });
|
|
714
720
|
|
|
715
721
|
const entryUrl = pathToFileURL(path.join(ownedDir, entryRelPath)).href;
|
|
@@ -1689,7 +1695,7 @@ function rewriteNativeChunkSource(source) {
|
|
|
1689
1695
|
}
|
|
1690
1696
|
|
|
1691
1697
|
async function esmChunkedMain() {
|
|
1692
|
-
const { prepareProcessOwnedDir } = require(path.join(process.env.CLAUDE_TERMUX_PACKAGE_DIR, 'lib', 'bunfs-extract.js'));
|
|
1698
|
+
const { prepareProcessOwnedDir, extractToProcessOwnedDir } = require(path.join(process.env.CLAUDE_TERMUX_PACKAGE_DIR, 'lib', 'bunfs-extract.js'));
|
|
1693
1699
|
const { registerHooks } = require('node:module');
|
|
1694
1700
|
const { pathToFileURL } = require('node:url');
|
|
1695
1701
|
|
|
@@ -1710,6 +1716,9 @@ async function esmChunkedMain() {
|
|
|
1710
1716
|
},
|
|
1711
1717
|
gc: () => {},
|
|
1712
1718
|
YAML: globalThis.__claudeYaml,
|
|
1719
|
+
zstdDecompressSync: (buf) => require('node:zlib').zstdDecompressSync(buf),
|
|
1720
|
+
zstdDecompress: (buf) => new Promise((res, rej) =>
|
|
1721
|
+
require('node:zlib').zstdDecompress(buf, (e, r) => (e ? rej(e) : res(r)))),
|
|
1713
1722
|
};
|
|
1714
1723
|
Object.defineProperty(process.versions, 'bun', { value: '1.1.8', configurable: true });
|
|
1715
1724
|
globalThis.__claudeBunShim = globalThis.Bun;
|
|
@@ -1734,7 +1743,9 @@ async function esmChunkedMain() {
|
|
|
1734
1743
|
vmGuardPath: path.join(libDir, 'bunfs-vm-guard.mjs'),
|
|
1735
1744
|
wsStubPath: path.join(libDir, 'bunfs-ws-stub.mjs'),
|
|
1736
1745
|
cycleHoists,
|
|
1746
|
+
reExtract: (sb, od) => extractToProcessOwnedDir(sb, od),
|
|
1737
1747
|
});
|
|
1748
|
+
loaderMod.installFsBunfsInterception();
|
|
1738
1749
|
registerHooks({ resolve: loaderMod.resolve, load: loaderMod.load });
|
|
1739
1750
|
|
|
1740
1751
|
const entryUrl = pathToFileURL(path.join(ownedDir, entryRelPath)).href;
|
|
@@ -1692,3 +1692,126 @@ test('Bun.spawn forwards top-level stdin in the first stdio position', () => {
|
|
|
1692
1692
|
}
|
|
1693
1693
|
}
|
|
1694
1694
|
});
|
|
1695
|
+
|
|
1696
|
+
// New tests for fs interception and zstd support
|
|
1697
|
+
|
|
1698
|
+
// esmChunkedMain() (esm-chunked 形式、今回の fs-intercept 修正の対象) の関数本体だけを抽出する。
|
|
1699
|
+
// legacyCjsMain() の Bun shim (zstd 非対応でよい、意図的に無変更) を誤って対象に含めないため、
|
|
1700
|
+
// 「both esmChunkedMain blocks have correct hook registration order」テストと同じ境界抽出方式を使う。
|
|
1701
|
+
function extractEsmChunkedMainBlocks() {
|
|
1702
|
+
const marker = 'async function esmChunkedMain()';
|
|
1703
|
+
const blocks = [];
|
|
1704
|
+
let offset = 0;
|
|
1705
|
+
while ((offset = script.indexOf(marker, offset)) !== -1) {
|
|
1706
|
+
const blockStart = offset;
|
|
1707
|
+
const blockEnd = script.indexOf('\nasync function', offset + 1);
|
|
1708
|
+
const actualBlockEnd = blockEnd !== -1 ? blockEnd : script.length;
|
|
1709
|
+
blocks.push(script.slice(blockStart, actualBlockEnd));
|
|
1710
|
+
offset = actualBlockEnd;
|
|
1711
|
+
}
|
|
1712
|
+
return blocks;
|
|
1713
|
+
}
|
|
1714
|
+
|
|
1715
|
+
test('both esmChunkedMain Bun shim blocks contain zstdDecompressSync and zstdDecompress fields', () => {
|
|
1716
|
+
const blocks = extractEsmChunkedMainBlocks();
|
|
1717
|
+
assert.ok(blocks.length >= 2, 'should have at least 2 esmChunkedMain blocks (helper and bootstrap)');
|
|
1718
|
+
|
|
1719
|
+
for (let i = 0; i < blocks.length; i++) {
|
|
1720
|
+
const block = blocks[i];
|
|
1721
|
+
assert.ok(
|
|
1722
|
+
block.includes('zstdDecompressSync:'),
|
|
1723
|
+
`Block ${i}: missing zstdDecompressSync field`,
|
|
1724
|
+
);
|
|
1725
|
+
assert.ok(
|
|
1726
|
+
block.includes('zstdDecompress:'),
|
|
1727
|
+
`Block ${i}: missing zstdDecompress field`,
|
|
1728
|
+
);
|
|
1729
|
+
}
|
|
1730
|
+
});
|
|
1731
|
+
|
|
1732
|
+
test('zstd functions are properly defined for sync decompression', () => {
|
|
1733
|
+
const blocks = extractEsmChunkedMainBlocks();
|
|
1734
|
+
assert.ok(blocks.length >= 1, 'should have at least 1 esmChunkedMain block');
|
|
1735
|
+
|
|
1736
|
+
for (let i = 0; i < blocks.length; i++) {
|
|
1737
|
+
const block = blocks[i];
|
|
1738
|
+
const syncMatch = block.match(/zstdDecompressSync:\s*\([^)]*\)\s*=>\s*require\('node:zlib'\)\.zstdDecompressSync\([^)]*\)/);
|
|
1739
|
+
assert.ok(syncMatch, `Block ${i}: zstdDecompressSync should call require("node:zlib").zstdDecompressSync`);
|
|
1740
|
+
|
|
1741
|
+
const asyncMatch = block.match(/zstdDecompress:\s*\([^)]*\)\s*=>\s*new Promise/);
|
|
1742
|
+
assert.ok(asyncMatch, `Block ${i}: zstdDecompress should return a Promise`);
|
|
1743
|
+
}
|
|
1744
|
+
});
|
|
1745
|
+
|
|
1746
|
+
test('zstd decompression works with real zlib.zstd APIs', async () => {
|
|
1747
|
+
const zlib = require('node:zlib');
|
|
1748
|
+
|
|
1749
|
+
// Skip if zstd not available
|
|
1750
|
+
if (typeof zlib.zstdCompressSync !== 'function') {
|
|
1751
|
+
return;
|
|
1752
|
+
}
|
|
1753
|
+
|
|
1754
|
+
const testData = Buffer.from('Hello, compression world!');
|
|
1755
|
+
const compressed = zlib.zstdCompressSync(testData);
|
|
1756
|
+
|
|
1757
|
+
// Test sync decompression
|
|
1758
|
+
const decompressedSync = zlib.zstdDecompressSync(compressed);
|
|
1759
|
+
assert.deepEqual(decompressedSync, testData);
|
|
1760
|
+
|
|
1761
|
+
// Test async decompression
|
|
1762
|
+
const decompressedAsync = await new Promise((resolve, reject) => {
|
|
1763
|
+
zlib.zstdDecompress(compressed, (err, result) => {
|
|
1764
|
+
if (err) reject(err);
|
|
1765
|
+
else resolve(result);
|
|
1766
|
+
});
|
|
1767
|
+
});
|
|
1768
|
+
assert.deepEqual(decompressedAsync, testData);
|
|
1769
|
+
});
|
|
1770
|
+
|
|
1771
|
+
test('both esmChunkedMain blocks have correct hook registration order', () => {
|
|
1772
|
+
const esmChunkedMarker = 'async function esmChunkedMain()';
|
|
1773
|
+
let blockCount = 0;
|
|
1774
|
+
let offset = 0;
|
|
1775
|
+
|
|
1776
|
+
while ((offset = script.indexOf(esmChunkedMarker, offset)) !== -1) {
|
|
1777
|
+
blockCount++;
|
|
1778
|
+
const blockStart = offset;
|
|
1779
|
+
const blockEnd = script.indexOf('\nasync function', offset + 1);
|
|
1780
|
+
const actualBlockEnd = blockEnd !== -1 ? blockEnd : script.length;
|
|
1781
|
+
const block = script.slice(blockStart, actualBlockEnd);
|
|
1782
|
+
|
|
1783
|
+
// Find the three key operations
|
|
1784
|
+
const initIdx = block.indexOf('loaderMod.initialize({');
|
|
1785
|
+
const interceptIdx = block.indexOf('loaderMod.installFsBunfsInterception()');
|
|
1786
|
+
const registerIdx = block.indexOf('registerHooks({');
|
|
1787
|
+
|
|
1788
|
+
assert.ok(initIdx !== -1, `Block ${blockCount}: missing initialize call`);
|
|
1789
|
+
assert.ok(interceptIdx !== -1, `Block ${blockCount}: missing installFsBunfsInterception call`);
|
|
1790
|
+
assert.ok(registerIdx !== -1, `Block ${blockCount}: missing registerHooks call`);
|
|
1791
|
+
|
|
1792
|
+
// Verify order: initialize < installFsBunfsInterception < registerHooks
|
|
1793
|
+
assert.ok(
|
|
1794
|
+
initIdx < interceptIdx && interceptIdx < registerIdx,
|
|
1795
|
+
`Block ${blockCount}: initialization order incorrect (initialize=${initIdx}, intercept=${interceptIdx}, register=${registerIdx})`,
|
|
1796
|
+
);
|
|
1797
|
+
|
|
1798
|
+
offset = actualBlockEnd;
|
|
1799
|
+
}
|
|
1800
|
+
|
|
1801
|
+
assert.ok(blockCount >= 2, 'should have at least 2 esmChunkedMain blocks');
|
|
1802
|
+
});
|
|
1803
|
+
|
|
1804
|
+
test('termux-run-claude-native.sh maintains compatibility with new zstd fields', () => {
|
|
1805
|
+
// Verify that the script structure is preserved
|
|
1806
|
+
const hasSourceBin = script.includes('SOURCE_BIN=');
|
|
1807
|
+
const hasWorkdir = script.includes('WORKDIR=');
|
|
1808
|
+
const hasGlobalThis = script.includes('globalThis');
|
|
1809
|
+
|
|
1810
|
+
assert.ok(hasSourceBin, 'script should set SOURCE_BIN');
|
|
1811
|
+
assert.ok(hasWorkdir, 'script should set WORKDIR');
|
|
1812
|
+
assert.ok(hasGlobalThis, 'script should manipulate globalThis');
|
|
1813
|
+
|
|
1814
|
+
// Verify both blocks exist and are distinct
|
|
1815
|
+
const blocks = (script.match(/globalThis\.Bun\s*=\s*{/g) || []);
|
|
1816
|
+
assert.ok(blocks.length >= 2, 'should have at least 2 Bun initializations for helper and bootstrap');
|
|
1817
|
+
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bash0816/claude-code",
|
|
3
|
-
"version": "2.1.
|
|
3
|
+
"version": "2.1.251",
|
|
4
4
|
"description": "Unofficial Termux-native Claude Code wrapper with audited native replay",
|
|
5
5
|
"license": "GPL-3.0-only",
|
|
6
6
|
"bin": {
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
"LICENSE"
|
|
16
16
|
],
|
|
17
17
|
"engines": {
|
|
18
|
-
"node": ">=22.15.0 <23.0.0 || >=23.
|
|
18
|
+
"node": ">=22.15.0 <23.0.0 || >=23.8.0"
|
|
19
19
|
},
|
|
20
20
|
"keywords": [
|
|
21
21
|
"claude-code",
|