@bash0816/claude-code 2.1.245 → 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 +10 -0
- package/config/claude-native-audited-versions.json +167 -1
- package/config/claude-termux-release-manifest.json +3 -3
- package/lib/bunfs-esm-loader.mjs +234 -21
- package/lib/bunfs-esm-loader.test.js +1048 -14
- package/lib/native-validators.js +90 -0
- package/lib/native-validators.test.js +160 -0
- package/lib/prepare-native.js +5 -71
- package/lib/termux-run-claude-native.sh +55 -22
- package/lib/termux-run-claude-native.test.js +123 -0
- package/package.json +2 -2
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.
|
|
40
|
+
npm install -g @bash0816/claude-code@2.1.248
|
|
41
41
|
```
|
|
42
42
|
|
|
43
43
|
## Update / 更新
|
|
@@ -95,6 +95,51 @@ like `disable` or `Y` will silently turn protection off. Use exactly `0` to be s
|
|
|
95
95
|
`1`/`true`/`yes`/`on`(大文字小文字を区別しません)以外の値は全て機能を再有効化してしまうため、
|
|
96
96
|
`disable` や `Y` のような typo でも保護が黙って外れます。安全のため厳密に `0` を指定してください。
|
|
97
97
|
|
|
98
|
+
### Tool Search Disabled by Default / Tool Search は既定で無効化
|
|
99
|
+
|
|
100
|
+
This Termux wrapper disables the upstream's automatic tool discovery feature (`ENABLE_TOOL_SEARCH=false`
|
|
101
|
+
by default) to prevent unnecessary dynamic tool loading in normal conversations. Without this setting,
|
|
102
|
+
the model may spontaneously activate `ToolSearch` and trigger `WebSearch`/`WebFetch` calls, consuming
|
|
103
|
+
your conversation turn limit (`--max-turns`).
|
|
104
|
+
|
|
105
|
+
この Termux wrapper は、upstream の自動 tool discovery 機能を既定で無効化しています
|
|
106
|
+
(`ENABLE_TOOL_SEARCH=false`)。この設定がないと、モデルが通常の会話で自発的に `ToolSearch` を活動化させ、
|
|
107
|
+
`WebSearch`/`WebFetch` を呼び出し、会話の turn 上限(`--max-turns`)を消費するおそれがあります。
|
|
108
|
+
|
|
109
|
+
If you want to re-enable tool search (for example, if you explicitly use `--tools` and want the model
|
|
110
|
+
to load additional tools dynamically), set the variable before launching:
|
|
111
|
+
|
|
112
|
+
tool search を再有効化したい場合(例えば `--tools` を明示的に指定して、モデルが追加の tool を
|
|
113
|
+
動的にロードしてほしい場合)、起動前に環境変数を設定してください:
|
|
114
|
+
|
|
115
|
+
```sh
|
|
116
|
+
ENABLE_TOOL_SEARCH=true claude
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
or:
|
|
120
|
+
|
|
121
|
+
または:
|
|
122
|
+
|
|
123
|
+
```sh
|
|
124
|
+
ENABLE_TOOL_SEARCH=auto claude
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
**Note on `settings.json`:** If you want to configure this in `settings.json`, place `ENABLE_TOOL_SEARCH` in
|
|
128
|
+
the `env` block with the value `force`. The environment variable default (`false`) takes precedence over `true`,
|
|
129
|
+
so use the `env` block to force-enable it:
|
|
130
|
+
|
|
131
|
+
```json
|
|
132
|
+
{ "env": { "ENABLE_TOOL_SEARCH": "force" } }
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
**`settings.json` を使う場合の注意:** `settings.json` で設定する場合、`env` ブロック内に `ENABLE_TOOL_SEARCH`
|
|
136
|
+
を置いて、値を `force` にしてください。環境変数の既定値(`false`)が `true` より優先されるため、
|
|
137
|
+
force-enable するには `env` ブロックを使う必要があります:
|
|
138
|
+
|
|
139
|
+
```json
|
|
140
|
+
{ "env": { "ENABLE_TOOL_SEARCH": "force" } }
|
|
141
|
+
```
|
|
142
|
+
|
|
98
143
|
## Policy / 方針
|
|
99
144
|
|
|
100
145
|
- Only audited versions in `config/claude-native-audited-versions.json` can run.
|
package/bin/claude
CHANGED
|
@@ -16,6 +16,16 @@ NODE="${MAGI_NODE:-node}"
|
|
|
16
16
|
if [ -n "${MAGI_NODE:-}" ]; then
|
|
17
17
|
export PATH="$(dirname -- "$NODE"):$PATH"
|
|
18
18
|
fi
|
|
19
|
+
|
|
20
|
+
if ! "$NODE" -e '
|
|
21
|
+
const [major, minor] = process.versions.node.split(".").map(Number);
|
|
22
|
+
const ok = major > 23 || (major === 23 && minor >= 8) || (major === 22 && minor >= 15);
|
|
23
|
+
process.exit(ok ? 0 : 1);
|
|
24
|
+
'; then
|
|
25
|
+
echo "Error: claude-code requires Node.js >=22.15.0 <23.0.0 or >=23.8.0 (module.registerHooks() API + zlib zstd support). Detected: $("$NODE" --version)" >&2
|
|
26
|
+
exit 1
|
|
27
|
+
fi
|
|
28
|
+
|
|
19
29
|
CONFIG_FILE="${PACKAGE_DIR}/config/claude-native-audited-versions.json"
|
|
20
30
|
PACKAGE_VERSION=$("$NODE" -e 'const fs=require("fs"); const path=require("path"); const p=JSON.parse(fs.readFileSync(path.join(process.argv[1],"package.json"),"utf8")); process.stdout.write(p.version)' "${PACKAGE_DIR}")
|
|
21
31
|
CLAUDE_VERSION="${CLAUDE_TERMUX_CLAUDE_VERSION:-${PACKAGE_VERSION}}"
|
|
@@ -777,7 +777,173 @@
|
|
|
777
777
|
"entry_format": "esm-chunked",
|
|
778
778
|
"tarball_integrity": "sha512-Qbn5HnZbYeW4GdifVkDGfcVKqj3/f3U9sfVd3LEaUZh08CcS8D/ptJ76zuBfQUGHJHfToAdNVfak86uJ84b1Dg==",
|
|
779
779
|
"tarball_sha256": "668662e7b5d91a93cff6c75736e60f3d5d3bed4cbe077ae4feefc63ad1253f4d",
|
|
780
|
-
"
|
|
780
|
+
"cycle_hoists": [],
|
|
781
|
+
"status": "termux_verified"
|
|
782
|
+
},
|
|
783
|
+
"2.1.248": {
|
|
784
|
+
"wrapper_spec": "@anthropic-ai/claude-code@2.1.248",
|
|
785
|
+
"native_spec": "@anthropic-ai/claude-code-linux-arm64@2.1.248",
|
|
786
|
+
"entry_format": "esm-chunked",
|
|
787
|
+
"tarball_integrity": "sha512-2qwjgGuzlVfkJC7UWUjl86hiv5Ok5vtVxAZ/5fpdhzQKuBLlxrJJu3z5tVI+VrO/x/hcqx5kJuy9/O9K4eT+Kg==",
|
|
788
|
+
"tarball_sha256": "bd2e2b6ebace34039b073b0f586d521ec09c895fa2a39de8d1c86423ae5884ca",
|
|
789
|
+
"status": "termux_verified",
|
|
790
|
+
"num_modules": 1946,
|
|
791
|
+
"byte_count": 136124175,
|
|
792
|
+
"cycle_hoists": [
|
|
793
|
+
{
|
|
794
|
+
"file": "chunk-vmw9kxhv.js",
|
|
795
|
+
"targetModule": "chunk-y0jj307t.js",
|
|
796
|
+
"expectedOccurrences": 1,
|
|
797
|
+
"assertProperties": []
|
|
798
|
+
},
|
|
799
|
+
{
|
|
800
|
+
"file": "chunk-9n7t2tbt.js",
|
|
801
|
+
"targetModule": "chunk-ppd18hq1.js",
|
|
802
|
+
"expectedOccurrences": 1,
|
|
803
|
+
"assertProperties": [
|
|
804
|
+
"MonitorTool"
|
|
805
|
+
]
|
|
806
|
+
},
|
|
807
|
+
{
|
|
808
|
+
"file": "chunk-9n7t2tbt.js",
|
|
809
|
+
"targetModule": "chunk-830s9480.js",
|
|
810
|
+
"expectedOccurrences": 1,
|
|
811
|
+
"assertProperties": [
|
|
812
|
+
"EndConversationTool"
|
|
813
|
+
]
|
|
814
|
+
},
|
|
815
|
+
{
|
|
816
|
+
"file": "chunk-9n7t2tbt.js",
|
|
817
|
+
"targetModule": "chunk-m4hx5z9g.js",
|
|
818
|
+
"expectedOccurrences": 1,
|
|
819
|
+
"assertProperties": [
|
|
820
|
+
"ArtifactTool"
|
|
821
|
+
]
|
|
822
|
+
},
|
|
823
|
+
{
|
|
824
|
+
"file": "chunk-9n7t2tbt.js",
|
|
825
|
+
"targetModule": "chunk-eg121wbt.js",
|
|
826
|
+
"expectedOccurrences": 1,
|
|
827
|
+
"assertProperties": [
|
|
828
|
+
"WorkflowTool"
|
|
829
|
+
]
|
|
830
|
+
},
|
|
831
|
+
{
|
|
832
|
+
"file": "chunk-9n7t2tbt.js",
|
|
833
|
+
"targetModule": "chunk-prrm838s.js",
|
|
834
|
+
"expectedOccurrences": 1,
|
|
835
|
+
"assertProperties": []
|
|
836
|
+
},
|
|
837
|
+
{
|
|
838
|
+
"file": "chunk-9n7t2tbt.js",
|
|
839
|
+
"targetModule": "chunk-exvwsc2a.js",
|
|
840
|
+
"expectedOccurrences": 2,
|
|
841
|
+
"assertProperties": []
|
|
842
|
+
},
|
|
843
|
+
{
|
|
844
|
+
"file": "chunk-9n7t2tbt.js",
|
|
845
|
+
"targetModule": "chunk-s61yn21a.js",
|
|
846
|
+
"expectedOccurrences": 1,
|
|
847
|
+
"assertProperties": [
|
|
848
|
+
"default"
|
|
849
|
+
]
|
|
850
|
+
},
|
|
851
|
+
{
|
|
852
|
+
"file": "chunk-9n7t2tbt.js",
|
|
853
|
+
"targetModule": "chunk-040m9a9s.js",
|
|
854
|
+
"expectedOccurrences": 3,
|
|
855
|
+
"assertProperties": [
|
|
856
|
+
"getWorkflowCommands",
|
|
857
|
+
"invalidateWorkflowCache",
|
|
858
|
+
"warmWorkflows"
|
|
859
|
+
]
|
|
860
|
+
}
|
|
861
|
+
]
|
|
862
|
+
},
|
|
863
|
+
"2.1.251": {
|
|
864
|
+
"wrapper_spec": "@anthropic-ai/claude-code@2.1.251",
|
|
865
|
+
"native_spec": "@anthropic-ai/claude-code-linux-arm64@2.1.251",
|
|
866
|
+
"entry_format": "esm-chunked",
|
|
867
|
+
"tarball_integrity": "sha512-h4EXRyV25yJfez40cTIoBlJptJqccP8nIDPdDMO9TDPUzZ6e5Y3OO9AgrfdMRAgccaTRsKfJenh7lA2D40nzdw==",
|
|
868
|
+
"tarball_sha256": "50760f283bf289a8bfb6f25ab86276808fd038b8f724ba5eaffb9b195483846d",
|
|
869
|
+
"status": "offset_discovered",
|
|
870
|
+
"num_modules": 1971,
|
|
871
|
+
"byte_count": 126850982,
|
|
872
|
+
"cycle_hoists": [
|
|
873
|
+
{
|
|
874
|
+
"file": "chunk-5yrgn0qs.js",
|
|
875
|
+
"targetModule": "chunk-j108xzrz.js",
|
|
876
|
+
"expectedOccurrences": 1,
|
|
877
|
+
"assertProperties": []
|
|
878
|
+
},
|
|
879
|
+
{
|
|
880
|
+
"file": "chunk-82xr73g2.js",
|
|
881
|
+
"targetModule": "chunk-kqaa82qj.js",
|
|
882
|
+
"expectedOccurrences": 1,
|
|
883
|
+
"assertProperties": [
|
|
884
|
+
"MonitorTool"
|
|
885
|
+
]
|
|
886
|
+
},
|
|
887
|
+
{
|
|
888
|
+
"file": "chunk-82xr73g2.js",
|
|
889
|
+
"targetModule": "chunk-q6fxy93d.js",
|
|
890
|
+
"expectedOccurrences": 1,
|
|
891
|
+
"assertProperties": [
|
|
892
|
+
"EndConversationTool"
|
|
893
|
+
]
|
|
894
|
+
},
|
|
895
|
+
{
|
|
896
|
+
"file": "chunk-82xr73g2.js",
|
|
897
|
+
"targetModule": "chunk-dxpcqxe7.js",
|
|
898
|
+
"expectedOccurrences": 1,
|
|
899
|
+
"assertProperties": [
|
|
900
|
+
"ArtifactTool"
|
|
901
|
+
]
|
|
902
|
+
},
|
|
903
|
+
{
|
|
904
|
+
"file": "chunk-82xr73g2.js",
|
|
905
|
+
"targetModule": "chunk-be1dqpgt.js",
|
|
906
|
+
"expectedOccurrences": 1,
|
|
907
|
+
"assertProperties": [
|
|
908
|
+
"WorkflowTool"
|
|
909
|
+
]
|
|
910
|
+
},
|
|
911
|
+
{
|
|
912
|
+
"file": "chunk-82xr73g2.js",
|
|
913
|
+
"targetModule": "chunk-er5txax0.js",
|
|
914
|
+
"expectedOccurrences": 1,
|
|
915
|
+
"assertProperties": []
|
|
916
|
+
},
|
|
917
|
+
{
|
|
918
|
+
"file": "chunk-82xr73g2.js",
|
|
919
|
+
"targetModule": "chunk-nh8esxyc.js",
|
|
920
|
+
"expectedOccurrences": 2,
|
|
921
|
+
"assertProperties": []
|
|
922
|
+
},
|
|
923
|
+
{
|
|
924
|
+
"file": "chunk-82xr73g2.js",
|
|
925
|
+
"targetModule": "chunk-4agvbmxr.js",
|
|
926
|
+
"expectedOccurrences": 1,
|
|
927
|
+
"assertProperties": [
|
|
928
|
+
"default"
|
|
929
|
+
]
|
|
930
|
+
},
|
|
931
|
+
{
|
|
932
|
+
"file": "chunk-82xr73g2.js",
|
|
933
|
+
"targetModule": "chunk-4sfywf4e.js",
|
|
934
|
+
"expectedOccurrences": 3,
|
|
935
|
+
"assertProperties": [
|
|
936
|
+
"getWorkflowCommands",
|
|
937
|
+
"invalidateWorkflowCache",
|
|
938
|
+
"warmWorkflows"
|
|
939
|
+
]
|
|
940
|
+
}
|
|
941
|
+
],
|
|
942
|
+
"cycle_hoists_skipped_assets": [
|
|
943
|
+
"chart.umd.min.js",
|
|
944
|
+
"hljsBundle.generated.min.js",
|
|
945
|
+
"mermaid.min.js"
|
|
946
|
+
]
|
|
781
947
|
}
|
|
782
948
|
}
|
|
783
949
|
}
|
|
@@ -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.248",
|
|
5
|
+
"latest_candidate_version": "2.1.251",
|
|
6
|
+
"previous_stable_version": "2.1.245",
|
|
7
7
|
"stable_pinned_version": "2.1.220-2",
|
|
8
8
|
"manifest_url": "https://raw.githubusercontent.com/bash0816/ClaudeCode-Termux/main/config/claude-termux-release-manifest.json"
|
|
9
9
|
}
|
package/lib/bunfs-esm-loader.mjs
CHANGED
|
@@ -1,20 +1,105 @@
|
|
|
1
1
|
import { pathToFileURL, fileURLToPath } from 'node:url';
|
|
2
2
|
import { existsSync, readFileSync } from 'node:fs';
|
|
3
|
-
import { createRequire } from 'node:module';
|
|
3
|
+
import { createRequire, syncBuiltinESMExports } from 'node:module';
|
|
4
4
|
import path from 'node:path';
|
|
5
5
|
|
|
6
|
+
const require = createRequire(import.meta.url);
|
|
7
|
+
|
|
6
8
|
let PROCESS_OWNED_DIR = null;
|
|
7
9
|
let SOURCE_BIN = null;
|
|
8
10
|
let CHILD_PROCESS_GUARD_PATH = null;
|
|
9
11
|
let VM_GUARD_PATH = null;
|
|
10
12
|
let WS_STUB_PATH = null;
|
|
11
13
|
|
|
14
|
+
let CYCLE_HOISTS = [];
|
|
15
|
+
|
|
16
|
+
let REEXTRACT = null;
|
|
17
|
+
let reExtractConsecFailures = 0;
|
|
18
|
+
let lastReExtractMs = 0;
|
|
19
|
+
const MAX_CONSEC_FAILURES = 3;
|
|
20
|
+
const REEXTRACT_THROTTLE_MS = 3000;
|
|
21
|
+
|
|
22
|
+
function recoverMissing(realPath, now = Date.now()) {
|
|
23
|
+
if (existsSync(realPath)) return true;
|
|
24
|
+
if (!REEXTRACT || !SOURCE_BIN) return false;
|
|
25
|
+
if (reExtractConsecFailures >= MAX_CONSEC_FAILURES) return false;
|
|
26
|
+
if (now - lastReExtractMs < REEXTRACT_THROTTLE_MS) return existsSync(realPath);
|
|
27
|
+
lastReExtractMs = now;
|
|
28
|
+
try {
|
|
29
|
+
if (!existsSync(SOURCE_BIN)) { reExtractConsecFailures += 1; return false; }
|
|
30
|
+
REEXTRACT(SOURCE_BIN, PROCESS_OWNED_DIR);
|
|
31
|
+
console.error('[claude-code] recovered missing extracted module(s) by re-extracting from the native binary');
|
|
32
|
+
} catch (e) {
|
|
33
|
+
reExtractConsecFailures += 1;
|
|
34
|
+
console.error('[claude-code] re-extraction failed: ' + (e && e.message ? e.message : String(e)));
|
|
35
|
+
return false;
|
|
36
|
+
}
|
|
37
|
+
const ok = existsSync(realPath);
|
|
38
|
+
reExtractConsecFailures = ok ? 0 : reExtractConsecFailures + 1;
|
|
39
|
+
return ok;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
function resolveBunfsPath(id) {
|
|
43
|
+
if (typeof id !== 'string' || !id.startsWith('/$bunfs/root/')) return null;
|
|
44
|
+
const rel = id.slice('/$bunfs/root/'.length);
|
|
45
|
+
if (rel.includes('..') || path.isAbsolute(rel)) {
|
|
46
|
+
throw new Error(`bunfs: rejected specifier ${id}`);
|
|
47
|
+
}
|
|
48
|
+
const real = path.resolve(PROCESS_OWNED_DIR, rel);
|
|
49
|
+
if (path.relative(PROCESS_OWNED_DIR, real).startsWith('..')) {
|
|
50
|
+
throw new Error(`bunfs: path escapes process-owned dir: ${id}`);
|
|
51
|
+
}
|
|
52
|
+
return real;
|
|
53
|
+
}
|
|
54
|
+
|
|
12
55
|
export function initialize(data) {
|
|
13
56
|
PROCESS_OWNED_DIR = data.processOwnedDir;
|
|
14
57
|
SOURCE_BIN = data.sourceBin;
|
|
15
58
|
CHILD_PROCESS_GUARD_PATH = data.childProcessGuardPath;
|
|
16
59
|
VM_GUARD_PATH = data.vmGuardPath;
|
|
17
60
|
WS_STUB_PATH = data.wsStubPath;
|
|
61
|
+
CYCLE_HOISTS = Array.isArray(data.cycleHoists) ? data.cycleHoists : [];
|
|
62
|
+
REEXTRACT = typeof data.reExtract === 'function' ? data.reExtract : null;
|
|
63
|
+
globalThis.__bunfsRecoverMissing = recoverMissing;
|
|
64
|
+
globalThis.__bunfsResolvePath = resolveBunfsPath;
|
|
65
|
+
// 回復状態のリセット (テスト隔離・再 initialize 対応)
|
|
66
|
+
reExtractConsecFailures = 0;
|
|
67
|
+
lastReExtractMs = 0;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
function tryHoistCycleBreakingImports(filePath, source) {
|
|
71
|
+
const rel = path.relative(PROCESS_OWNED_DIR, filePath);
|
|
72
|
+
const records = CYCLE_HOISTS.filter((r) => r.file === rel);
|
|
73
|
+
if (records.length === 0) return null;
|
|
74
|
+
|
|
75
|
+
let hoistedImportLines = '';
|
|
76
|
+
let newSource = source;
|
|
77
|
+
let varIndex = 0;
|
|
78
|
+
const targetToVar = new Map();
|
|
79
|
+
|
|
80
|
+
for (const record of records) {
|
|
81
|
+
const literal = `import.meta.require("/$bunfs/root/${record.targetModule}")`;
|
|
82
|
+
const occurrences = newSource.split(literal).length - 1;
|
|
83
|
+
if (occurrences !== record.expectedOccurrences) continue;
|
|
84
|
+
|
|
85
|
+
const real = path.resolve(PROCESS_OWNED_DIR, record.targetModule);
|
|
86
|
+
if (path.relative(PROCESS_OWNED_DIR, real).startsWith('..')) continue;
|
|
87
|
+
if (!existsSync(real) && !recoverMissing(real)) continue;
|
|
88
|
+
|
|
89
|
+
let varName = targetToVar.get(record.targetModule);
|
|
90
|
+
if (!varName) {
|
|
91
|
+
varName = `__bunfsHoisted_${varIndex++}`;
|
|
92
|
+
targetToVar.set(record.targetModule, varName);
|
|
93
|
+
hoistedImportLines += `import * as ${varName} from ${JSON.stringify(pathToFileURL(real).href)};\n`;
|
|
94
|
+
if (record.assertProperties && record.assertProperties.length > 0) {
|
|
95
|
+
hoistedImportLines += `__bunfsAssertHoistedProps(${varName}, ${JSON.stringify(record.targetModule)}, ${JSON.stringify(record.assertProperties)});\n`;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
newSource = newSource.replaceAll(literal, varName);
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
if (!targetToVar.size) return null;
|
|
102
|
+
return { hoistedImportLine: hoistedImportLines, source: newSource };
|
|
18
103
|
}
|
|
19
104
|
|
|
20
105
|
function buildImportMetaRequirePolyfillPrelude(anchorUrl) {
|
|
@@ -22,35 +107,89 @@ function buildImportMetaRequirePolyfillPrelude(anchorUrl) {
|
|
|
22
107
|
`import __bunfsGuardedChildProcess from ${JSON.stringify(pathToFileURL(CHILD_PROCESS_GUARD_PATH).href)};\n` +
|
|
23
108
|
`import __bunfsGuardedVm from ${JSON.stringify(pathToFileURL(VM_GUARD_PATH).href)};\n` +
|
|
24
109
|
`import { createRequire as __bunfsCreateRequire } from "node:module";\n` +
|
|
110
|
+
`import __bunfsMetaRequirePath from "node:path";\n` +
|
|
111
|
+
`import { existsSync as __bunfsMetaRequireExistsSync } from "node:fs";\n` +
|
|
112
|
+
`import { readFileSync as __bunfsMetaRequireReadFileSync } from "node:fs";\n` +
|
|
113
|
+
`function __bunfsAssertHoistedProps(ns, targetModule, propNames) {\n` +
|
|
114
|
+
` for (const p of propNames) {\n` +
|
|
115
|
+
` let v;\n` +
|
|
116
|
+
` try {\n` +
|
|
117
|
+
` v = ns[p];\n` +
|
|
118
|
+
` } catch (e) {\n` +
|
|
119
|
+
` if (e instanceof ReferenceError) {\n` +
|
|
120
|
+
` throw new Error("bunfs cycle-hoist: accessing \\"" + p + "\\" on " + targetModule + " threw ReferenceError (TDZ) - evaluation-order regression");\n` +
|
|
121
|
+
` }\n` +
|
|
122
|
+
` throw e;\n` +
|
|
123
|
+
` }\n` +
|
|
124
|
+
` if (v === undefined) {\n` +
|
|
125
|
+
` throw new Error("bunfs cycle-hoist: \\"" + p + "\\" is undefined after hoisting from " + targetModule + " (evaluation-order regression?)");\n` +
|
|
126
|
+
` }\n` +
|
|
127
|
+
` }\n` +
|
|
128
|
+
`}\n` +
|
|
25
129
|
`const __bunfsRealRequire = __bunfsCreateRequire(${JSON.stringify(anchorUrl)});\n` +
|
|
130
|
+
`const __bunfsOwnedDir = ${JSON.stringify(PROCESS_OWNED_DIR)};\n` +
|
|
26
131
|
`const __bunfsMetaRequire = (id) => {\n` +
|
|
27
132
|
` if (id === "child_process" || id === "node:child_process") return __bunfsGuardedChildProcess;\n` +
|
|
28
133
|
` if (id === "vm" || id === "node:vm") return __bunfsGuardedVm;\n` +
|
|
134
|
+
` if (typeof id === "string" && id.startsWith("/$bunfs/root/")) {\n` +
|
|
135
|
+
` let real;\n` +
|
|
136
|
+
` try {\n` +
|
|
137
|
+
` real = globalThis.__bunfsResolvePath(id);\n` +
|
|
138
|
+
` } catch (_eResolve) {\n` +
|
|
139
|
+
` throw new Error("bunfs meta-require: " + _eResolve.message);\n` +
|
|
140
|
+
` }\n` +
|
|
141
|
+
` if (!__bunfsMetaRequireExistsSync(real)) {\n` +
|
|
142
|
+
` const _rec = (typeof globalThis.__bunfsRecoverMissing === "function") && globalThis.__bunfsRecoverMissing(real);\n` +
|
|
143
|
+
` if (!_rec) throw new Error("bunfs meta-require: missing extracted module " + id + " -> " + real);\n` +
|
|
144
|
+
` }\n` +
|
|
145
|
+
` const ext = __bunfsMetaRequirePath.extname(real);\n` +
|
|
146
|
+
` if (ext === ".md" || ext === ".txt") {\n` +
|
|
147
|
+
` try { return __bunfsMetaRequireReadFileSync(real, "utf8"); }\n` +
|
|
148
|
+
` catch (_e2) {\n` +
|
|
149
|
+
` if (_e2 && _e2.code === "ENOENT" && !__bunfsMetaRequireExistsSync(real) && typeof globalThis.__bunfsRecoverMissing === "function" && globalThis.__bunfsRecoverMissing(real)) {\n` +
|
|
150
|
+
` return __bunfsMetaRequireReadFileSync(real, "utf8");\n` +
|
|
151
|
+
` }\n` +
|
|
152
|
+
` throw _e2;\n` +
|
|
153
|
+
` }\n` +
|
|
154
|
+
` }\n` +
|
|
155
|
+
` try {\n` +
|
|
156
|
+
` return __bunfsRealRequire(real);\n` +
|
|
157
|
+
` } catch (_e) {\n` +
|
|
158
|
+
` if (!__bunfsMetaRequireExistsSync(real) && typeof globalThis.__bunfsRecoverMissing === "function" && globalThis.__bunfsRecoverMissing(real)) {\n` +
|
|
159
|
+
` return __bunfsRealRequire(real);\n` +
|
|
160
|
+
` }\n` +
|
|
161
|
+
` throw _e;\n` +
|
|
162
|
+
` }\n` +
|
|
163
|
+
` }\n` +
|
|
29
164
|
` return __bunfsRealRequire(id);\n` +
|
|
30
165
|
`};\n`
|
|
31
166
|
);
|
|
32
167
|
}
|
|
33
168
|
|
|
34
|
-
export
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
169
|
+
export function resolve(specifier, context, nextResolve) {
|
|
170
|
+
const parentURL = context && context.parentURL;
|
|
171
|
+
const ownedPrefix = pathToFileURL(PROCESS_OWNED_DIR + path.sep).href;
|
|
172
|
+
const fromChunk = typeof parentURL === 'string' && parentURL.startsWith(ownedPrefix);
|
|
173
|
+
|
|
174
|
+
if (fromChunk) {
|
|
175
|
+
if (specifier === 'child_process' || specifier === 'node:child_process') {
|
|
176
|
+
return { url: pathToFileURL(CHILD_PROCESS_GUARD_PATH).href, shortCircuit: true, format: 'module' };
|
|
177
|
+
}
|
|
178
|
+
if (specifier === 'vm' || specifier === 'node:vm') {
|
|
179
|
+
return { url: pathToFileURL(VM_GUARD_PATH).href, shortCircuit: true, format: 'module' };
|
|
180
|
+
}
|
|
181
|
+
if (specifier === 'ws') {
|
|
182
|
+
return { url: pathToFileURL(WS_STUB_PATH).href, shortCircuit: true, format: 'module' };
|
|
183
|
+
}
|
|
43
184
|
}
|
|
44
185
|
if (specifier.startsWith('/$bunfs/root/')) {
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
if (path.relative(PROCESS_OWNED_DIR, real).startsWith('..')) {
|
|
51
|
-
throw new Error(`bunfs resolve: path escapes process-owned dir: ${specifier}`);
|
|
186
|
+
let real;
|
|
187
|
+
try {
|
|
188
|
+
real = resolveBunfsPath(specifier);
|
|
189
|
+
} catch (e) {
|
|
190
|
+
throw new Error(`bunfs resolve: ${e.message}`);
|
|
52
191
|
}
|
|
53
|
-
if (!existsSync(real)) {
|
|
192
|
+
if (!existsSync(real) && !recoverMissing(real)) {
|
|
54
193
|
throw new Error(`bunfs resolve: missing extracted module ${specifier} -> ${real}`);
|
|
55
194
|
}
|
|
56
195
|
return { url: pathToFileURL(real).href, shortCircuit: true, format: 'module' };
|
|
@@ -58,17 +197,91 @@ export async function resolve(specifier, context, nextResolve) {
|
|
|
58
197
|
return nextResolve(specifier, context);
|
|
59
198
|
}
|
|
60
199
|
|
|
61
|
-
export
|
|
200
|
+
export function load(url, context, nextLoad) {
|
|
62
201
|
const ownedPrefix = pathToFileURL(PROCESS_OWNED_DIR + path.sep).href;
|
|
63
202
|
if (!url.startsWith(ownedPrefix)) {
|
|
64
203
|
return nextLoad(url, context);
|
|
65
204
|
}
|
|
66
205
|
const filePath = fileURLToPath(url);
|
|
67
|
-
let source
|
|
206
|
+
let source;
|
|
207
|
+
try {
|
|
208
|
+
source = readFileSync(filePath, 'utf8');
|
|
209
|
+
} catch (e) {
|
|
210
|
+
// filePath 自身が消えている場合のみ回復 (エラーコードだけに依存しない)
|
|
211
|
+
if (e && e.code === 'ENOENT' && !existsSync(filePath) && recoverMissing(filePath)) {
|
|
212
|
+
source = readFileSync(filePath, 'utf8');
|
|
213
|
+
} else {
|
|
214
|
+
throw e;
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
let hoistedImportLine = '';
|
|
219
|
+
const hoistResult = tryHoistCycleBreakingImports(filePath, source);
|
|
220
|
+
if (hoistResult) {
|
|
221
|
+
hoistedImportLine = hoistResult.hoistedImportLine;
|
|
222
|
+
source = hoistResult.source;
|
|
223
|
+
}
|
|
224
|
+
|
|
68
225
|
if (source.includes('import.meta.require')) {
|
|
69
226
|
const anchorUrl = pathToFileURL(SOURCE_BIN).href;
|
|
70
|
-
source =
|
|
227
|
+
source = hoistedImportLine +
|
|
228
|
+
buildImportMetaRequirePolyfillPrelude(anchorUrl) +
|
|
71
229
|
source.replaceAll('import.meta.require', '__bunfsMetaRequire');
|
|
230
|
+
} else if (hoistedImportLine) {
|
|
231
|
+
source = hoistedImportLine + source;
|
|
72
232
|
}
|
|
73
233
|
return { format: 'module', source, shortCircuit: true };
|
|
74
234
|
}
|
|
235
|
+
|
|
236
|
+
let FS_PATCHED = false;
|
|
237
|
+
function installFsBunfsInterception() {
|
|
238
|
+
if (FS_PATCHED) return;
|
|
239
|
+
const fsMod = require('node:fs');
|
|
240
|
+
const zlib = require('node:zlib');
|
|
241
|
+
if (typeof zlib.zstdDecompressSync !== 'function' || typeof zlib.zstdDecompress !== 'function') {
|
|
242
|
+
throw new Error('bunfs: Node.js zlib zstd support not found. Please upgrade to Node.js >=23.8.0 or >=22.15.0 (LTS).');
|
|
243
|
+
}
|
|
244
|
+
const origReadFileSync = fsMod.readFileSync;
|
|
245
|
+
const origReadFile = fsMod.readFile;
|
|
246
|
+
const origPromisesReadFile = fsMod.promises.readFile;
|
|
247
|
+
|
|
248
|
+
function resolveOrRecover(p) {
|
|
249
|
+
const real = resolveBunfsPath(p);
|
|
250
|
+
if (real === null) return null;
|
|
251
|
+
if (!existsSync(real)) {
|
|
252
|
+
const recovered = (typeof globalThis.__bunfsRecoverMissing === 'function') && globalThis.__bunfsRecoverMissing(real);
|
|
253
|
+
if (!recovered) throw new Error(`bunfs fs-intercept: missing extracted asset ${p} -> ${real}`);
|
|
254
|
+
}
|
|
255
|
+
const realOwned = fsMod.realpathSync(PROCESS_OWNED_DIR);
|
|
256
|
+
const realTarget = fsMod.realpathSync(real);
|
|
257
|
+
if (path.relative(realOwned, realTarget).startsWith('..')) {
|
|
258
|
+
throw new Error(`bunfs fs-intercept: resolved path escapes owned dir via symlink: ${p}`);
|
|
259
|
+
}
|
|
260
|
+
return real;
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
try {
|
|
264
|
+
fsMod.readFileSync = function (p, ...rest) {
|
|
265
|
+
const real = typeof p === 'string' ? resolveOrRecover(p) : null;
|
|
266
|
+
return Reflect.apply(origReadFileSync, this, [real !== null ? real : p, ...rest]);
|
|
267
|
+
};
|
|
268
|
+
fsMod.readFile = function (p, ...rest) {
|
|
269
|
+
const real = typeof p === 'string' ? resolveOrRecover(p) : null;
|
|
270
|
+
return Reflect.apply(origReadFile, this, [real !== null ? real : p, ...rest]);
|
|
271
|
+
};
|
|
272
|
+
fsMod.promises.readFile = function (p, ...rest) {
|
|
273
|
+
const real = typeof p === 'string' ? resolveOrRecover(p) : null;
|
|
274
|
+
return Reflect.apply(origPromisesReadFile, this, [real !== null ? real : p, ...rest]);
|
|
275
|
+
};
|
|
276
|
+
syncBuiltinESMExports();
|
|
277
|
+
} catch (e) {
|
|
278
|
+
fsMod.readFileSync = origReadFileSync;
|
|
279
|
+
fsMod.readFile = origReadFile;
|
|
280
|
+
fsMod.promises.readFile = origPromisesReadFile;
|
|
281
|
+
try { syncBuiltinESMExports(); } catch { /* 復元目的、失敗しても re-throw を優先 */ }
|
|
282
|
+
throw e;
|
|
283
|
+
}
|
|
284
|
+
FS_PATCHED = true;
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
export { recoverMissing, resolveBunfsPath, installFsBunfsInterception };
|