@bash0816/claude-code 2.1.150 → 2.1.153-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.
- package/README.md +23 -32
- package/bin/claude +2 -2
- package/config/claude-native-audited-versions.json +42 -0
- package/config/claude-termux-release-manifest.json +8 -3
- package/lib/check-updates.js +94 -15
- package/lib/postinstall.js +2 -1
- package/lib/preinstall.js +6 -0
- package/lib/prepare-native.js +9 -51
- package/lib/termux-run-claude-native.sh +321 -39
- package/package.json +2 -2
- package/lib/native-update-guard.js +0 -257
- package/lib/native-update-guard.test.js +0 -310
package/README.md
CHANGED
|
@@ -1,17 +1,19 @@
|
|
|
1
|
-
# @bash0816/
|
|
1
|
+
# @bash0816/cluade-code
|
|
2
2
|
|
|
3
3
|
Termux-native Claude Code wrapper package.
|
|
4
4
|
|
|
5
5
|
Termux 向け Claude Code native wrapper package です。
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
Legacy compatibility package:
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
互換維持用の legacy package:
|
|
10
|
+
|
|
11
|
+
- canonical package: `@bash0816/claude-code`
|
|
10
12
|
|
|
11
13
|
## Install / インストール
|
|
12
14
|
|
|
13
15
|
```sh
|
|
14
|
-
npm install -g @bash0816/
|
|
16
|
+
npm install -g @bash0816/cluade-code@latest
|
|
15
17
|
```
|
|
16
18
|
|
|
17
19
|
If an older audited launcher from this repository already exists at `$PREFIX/bin/claude`, migrate through the updated launcher.
|
|
@@ -27,38 +29,19 @@ If npm reports `EEXIST` before package scripts run, use a one-time forced migrat
|
|
|
27
29
|
package script 実行前に npm が `EEXIST` を返す場合は、初回だけ forced migration を使います。
|
|
28
30
|
|
|
29
31
|
```sh
|
|
30
|
-
npm install -g --force @bash0816/
|
|
32
|
+
npm install -g --force @bash0816/cluade-code@latest
|
|
31
33
|
```
|
|
32
34
|
|
|
33
35
|
After npm owns the `claude` bin link, normal `npm install -g` updates work.
|
|
34
36
|
|
|
35
37
|
npm が `claude` bin link を管理する状態になれば、通常の `npm install -g` 更新が使えます。
|
|
36
38
|
|
|
37
|
-
Specific audited
|
|
39
|
+
Specific audited version:
|
|
38
40
|
|
|
39
41
|
監査済みの固定 version:
|
|
40
42
|
|
|
41
|
-
Current quick examples:
|
|
42
|
-
|
|
43
|
-
現在の quick example:
|
|
44
|
-
|
|
45
43
|
```sh
|
|
46
|
-
npm install -g @bash0816/
|
|
47
|
-
npm install -g @bash0816/claude-code@2.1.119
|
|
48
|
-
npm install -g @bash0816/claude-code@2.1.121
|
|
49
|
-
npm install -g @bash0816/claude-code@2.1.122
|
|
50
|
-
npm install -g @bash0816/claude-code@2.1.123
|
|
51
|
-
npm install -g @bash0816/claude-code@2.1.126
|
|
52
|
-
npm install -g @bash0816/claude-code@2.1.128
|
|
53
|
-
npm install -g @bash0816/claude-code@2.1.136
|
|
54
|
-
npm install -g @bash0816/claude-code@2.1.137
|
|
55
|
-
npm install -g @bash0816/claude-code@2.1.138
|
|
56
|
-
npm install -g @bash0816/claude-code@2.1.139
|
|
57
|
-
npm install -g @bash0816/claude-code@2.1.140
|
|
58
|
-
npm install -g @bash0816/claude-code@2.1.141
|
|
59
|
-
npm install -g @bash0816/claude-code@2.1.142
|
|
60
|
-
npm install -g @bash0816/claude-code@2.1.143
|
|
61
|
-
npm install -g @bash0816/claude-code@2.1.144
|
|
44
|
+
npm install -g @bash0816/cluade-code@2.1.123
|
|
62
45
|
```
|
|
63
46
|
|
|
64
47
|
## Update / 更新
|
|
@@ -67,9 +50,17 @@ npm install -g @bash0816/claude-code@2.1.144
|
|
|
67
50
|
claude update
|
|
68
51
|
```
|
|
69
52
|
|
|
70
|
-
`claude update` installs the latest audited package version.
|
|
53
|
+
`claude update` checks the GitHub release manifest and installs the latest audited package version.
|
|
54
|
+
|
|
55
|
+
`claude update` は GitHub release manifest を確認し、最新の監査済み package version を install します。
|
|
56
|
+
|
|
57
|
+
For the final legacy bridge release, `claude update` migrates this typo package to the canonical package.
|
|
58
|
+
|
|
59
|
+
最終 legacy bridge release では、`claude update` がこの typo package から canonical package へ移行します。
|
|
60
|
+
|
|
61
|
+
This final bridge package is frozen at package version `2.1.123` and launches audited native `2.1.150` by default from the synced metadata set.
|
|
71
62
|
|
|
72
|
-
|
|
63
|
+
この最終 bridge package は package version `2.1.123` で凍結し、同期済み metadata 集合から既定では監査済み native `2.1.150` を起動します。
|
|
73
64
|
|
|
74
65
|
```sh
|
|
75
66
|
npm install -g @bash0816/claude-code@<latest_audited_version>
|
|
@@ -83,10 +74,10 @@ Normal launch also checks the same manifest with a short timeout and prints a no
|
|
|
83
74
|
|
|
84
75
|
- Only audited versions in `config/claude-native-audited-versions.json` can run.
|
|
85
76
|
- `config/claude-native-audited-versions.json` にある監査済み version だけを実行できます。
|
|
86
|
-
-
|
|
87
|
-
- `2.1.
|
|
88
|
-
- The metadata file
|
|
89
|
-
-
|
|
77
|
+
- This legacy package is frozen at `2.1.123` and exists only as a migration bridge to `@bash0816/claude-code`.
|
|
78
|
+
- この legacy package は `2.1.123` で凍結しており、`@bash0816/claude-code` への migration bridge としてのみ存在します。
|
|
79
|
+
- The metadata file remains the source of truth for the audited version set.
|
|
80
|
+
- 監査済み version 集合の source of truth は引き続き metadata file です。
|
|
90
81
|
- Native artifacts are cached under `${HOME}/.claude-termux-native-package`.
|
|
91
82
|
- native artifact は `${HOME}/.claude-termux-native-package` に cache します。
|
|
92
83
|
- If native preparation fails, the command exits with an error.
|
package/bin/claude
CHANGED
|
@@ -14,7 +14,8 @@ done
|
|
|
14
14
|
PACKAGE_DIR=$(CDPATH= cd -- "$(dirname -- "${SELF}")/.." && pwd)
|
|
15
15
|
CONFIG_FILE="${PACKAGE_DIR}/config/claude-native-audited-versions.json"
|
|
16
16
|
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}")
|
|
17
|
-
|
|
17
|
+
DEFAULT_NATIVE_VERSION=$(node -e 'const fs=require("fs"); const path=require("path"); const p=JSON.parse(fs.readFileSync(path.join(process.argv[1],"config","claude-termux-release-manifest.json"),"utf8")); process.stdout.write(String(p.default_native_version || p.latest_audited_version || ""))' "${PACKAGE_DIR}")
|
|
18
|
+
CLAUDE_VERSION="${CLAUDE_TERMUX_CLAUDE_VERSION:-${DEFAULT_NATIVE_VERSION:-${PACKAGE_VERSION}}}"
|
|
18
19
|
UPDATE_HELPER="${PACKAGE_DIR}/lib/check-updates.js"
|
|
19
20
|
|
|
20
21
|
if [ "${1:-}" = "update" ]; then
|
|
@@ -57,6 +58,5 @@ WORKDIR="${CACHE_DIR}/launcher-workdir" \
|
|
|
57
58
|
ENTRY_JS_OFFSET="${ENTRY_JS_OFFSET}" \
|
|
58
59
|
ENTRY_END_OFFSET="${ENTRY_END_OFFSET}" \
|
|
59
60
|
CURRENT_CLAUDE_VERSION="${CLAUDE_VERSION}" \
|
|
60
|
-
CLAUDE_TERMUX_PACKAGE_DIR="${PACKAGE_DIR}" \
|
|
61
61
|
CLAUDE_NATIVE_UPDATE_CHECK=0 \
|
|
62
62
|
exec sh "${PACKAGE_DIR}/lib/termux-run-claude-native.sh" "$@"
|
|
@@ -118,6 +118,48 @@
|
|
|
118
118
|
"entry_js_offset": 221278436,
|
|
119
119
|
"entry_end_offset": 236586147,
|
|
120
120
|
"status": "termux_verified"
|
|
121
|
+
},
|
|
122
|
+
"2.1.150-1": {
|
|
123
|
+
"wrapper_spec": "@anthropic-ai/claude-code@2.1.150",
|
|
124
|
+
"native_spec": "@anthropic-ai/claude-code-linux-arm64@2.1.150",
|
|
125
|
+
"entry_js_offset": 221278436,
|
|
126
|
+
"entry_end_offset": 236586147,
|
|
127
|
+
"status": "termux_verified"
|
|
128
|
+
},
|
|
129
|
+
"2.1.150-2": {
|
|
130
|
+
"wrapper_spec": "@anthropic-ai/claude-code@2.1.150",
|
|
131
|
+
"native_spec": "@anthropic-ai/claude-code-linux-arm64@2.1.150",
|
|
132
|
+
"entry_js_offset": 221278436,
|
|
133
|
+
"entry_end_offset": 236586147,
|
|
134
|
+
"status": "termux_verified"
|
|
135
|
+
},
|
|
136
|
+
"2.1.150-3": {
|
|
137
|
+
"wrapper_spec": "@anthropic-ai/claude-code@2.1.150",
|
|
138
|
+
"native_spec": "@anthropic-ai/claude-code-linux-arm64@2.1.150",
|
|
139
|
+
"entry_js_offset": 221278436,
|
|
140
|
+
"entry_end_offset": 236586147,
|
|
141
|
+
"status": "termux_verified"
|
|
142
|
+
},
|
|
143
|
+
"2.1.153": {
|
|
144
|
+
"wrapper_spec": "@anthropic-ai/claude-code@2.1.153",
|
|
145
|
+
"native_spec": "@anthropic-ai/claude-code-linux-arm64@2.1.153",
|
|
146
|
+
"entry_js_offset": 222525028,
|
|
147
|
+
"entry_end_offset": 237958345,
|
|
148
|
+
"status": "termux_verified"
|
|
149
|
+
},
|
|
150
|
+
"2.1.153-1": {
|
|
151
|
+
"wrapper_spec": "@anthropic-ai/claude-code@2.1.153",
|
|
152
|
+
"native_spec": "@anthropic-ai/claude-code-linux-arm64@2.1.153",
|
|
153
|
+
"entry_js_offset": 222525028,
|
|
154
|
+
"entry_end_offset": 237958345,
|
|
155
|
+
"status": "termux_verified"
|
|
156
|
+
},
|
|
157
|
+
"2.1.153-2": {
|
|
158
|
+
"wrapper_spec": "@anthropic-ai/claude-code@2.1.153",
|
|
159
|
+
"native_spec": "@anthropic-ai/claude-code-linux-arm64@2.1.153",
|
|
160
|
+
"entry_js_offset": 222525028,
|
|
161
|
+
"entry_end_offset": 237958345,
|
|
162
|
+
"status": "termux_verified"
|
|
121
163
|
}
|
|
122
164
|
}
|
|
123
165
|
}
|
|
@@ -1,8 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"manifest_version": 1,
|
|
3
3
|
"package_name": "@bash0816/claude-code",
|
|
4
|
-
"
|
|
5
|
-
"
|
|
6
|
-
"
|
|
4
|
+
"canonical_package_name": "@bash0816/claude-code",
|
|
5
|
+
"canonical_manifest_url": "https://raw.githubusercontent.com/bash0816/ClaudeCode-Termux/main/config/claude-termux-release-manifest.json",
|
|
6
|
+
"canonical_repository_url": "https://github.com/bash0816/ClaudeCode-Termux",
|
|
7
|
+
"bridge_package_version": "2.1.123",
|
|
8
|
+
"default_native_version": "2.1.153-2",
|
|
9
|
+
"latest_audited_version": "2.1.153-2",
|
|
10
|
+
"latest_candidate_version": "2.1.153-2",
|
|
11
|
+
"previous_stable_version": "2.1.153-1",
|
|
7
12
|
"manifest_url": "https://raw.githubusercontent.com/bash0816/ClaudeCode-Termux/main/config/claude-termux-release-manifest.json"
|
|
8
13
|
}
|
package/lib/check-updates.js
CHANGED
|
@@ -19,10 +19,19 @@ const timeoutMs = Number(process.env.CLAUDE_TERMUX_UPDATE_TIMEOUT_MS || '1200');
|
|
|
19
19
|
const ttlMs = Number(process.env.CLAUDE_TERMUX_UPDATE_CACHE_TTL_MS || String(24 * 60 * 60 * 1000));
|
|
20
20
|
const skipCheck = process.env.CLAUDE_TERMUX_SKIP_UPDATE_CHECK === '1';
|
|
21
21
|
const manifestUrl = process.env.CLAUDE_TERMUX_MANIFEST_URL || localManifest.manifest_url;
|
|
22
|
+
const canonicalManifestUrl = process.env.CLAUDE_TERMUX_CANONICAL_MANIFEST_URL || localManifest.canonical_manifest_url || '';
|
|
23
|
+
const canonicalPackageName = process.env.CLAUDE_TERMUX_CANONICAL_PACKAGE_NAME || localManifest.canonical_package_name || '';
|
|
24
|
+
const canonicalRepositoryUrl = process.env.CLAUDE_TERMUX_CANONICAL_REPOSITORY_URL || localManifest.canonical_repository_url || '';
|
|
22
25
|
|
|
23
26
|
function compareVersions(a, b) {
|
|
24
|
-
const
|
|
25
|
-
|
|
27
|
+
const parse = v => {
|
|
28
|
+
const [main, patch] = String(v).split('-');
|
|
29
|
+
const parts = main.split('.').map(Number);
|
|
30
|
+
parts.push(patch !== undefined ? Number(patch) : 0);
|
|
31
|
+
return parts;
|
|
32
|
+
};
|
|
33
|
+
const aParts = parse(a);
|
|
34
|
+
const bParts = parse(b);
|
|
26
35
|
const len = Math.max(aParts.length, bParts.length);
|
|
27
36
|
for (let index = 0; index < len; index += 1) {
|
|
28
37
|
const diff = (aParts[index] || 0) - (bParts[index] || 0);
|
|
@@ -102,10 +111,64 @@ async function resolveManifest(forceRefresh) {
|
|
|
102
111
|
}
|
|
103
112
|
}
|
|
104
113
|
|
|
105
|
-
function
|
|
114
|
+
async function resolveCanonicalManifest() {
|
|
115
|
+
if (!canonicalManifestUrl || !canonicalPackageName || canonicalPackageName === pkg.name) {
|
|
116
|
+
return null;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
if (skipCheck) {
|
|
120
|
+
return {
|
|
121
|
+
packageName: canonicalPackageName,
|
|
122
|
+
latestVersion: localManifest.latest_audited_version || pkg.version,
|
|
123
|
+
repositoryUrl: canonicalRepositoryUrl,
|
|
124
|
+
};
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
try {
|
|
128
|
+
const manifest = await fetchManifest(canonicalManifestUrl);
|
|
129
|
+
return {
|
|
130
|
+
packageName: manifest.package_name || canonicalPackageName,
|
|
131
|
+
latestVersion: manifest.latest_audited_version || localManifest.latest_audited_version || pkg.version,
|
|
132
|
+
repositoryUrl: canonicalRepositoryUrl,
|
|
133
|
+
};
|
|
134
|
+
} catch {
|
|
135
|
+
return {
|
|
136
|
+
packageName: canonicalPackageName,
|
|
137
|
+
latestVersion: localManifest.latest_audited_version || pkg.version,
|
|
138
|
+
repositoryUrl: canonicalRepositoryUrl,
|
|
139
|
+
};
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
async function resolveTarget(forceRefresh) {
|
|
144
|
+
const base = await resolveManifest(forceRefresh);
|
|
145
|
+
const canonical = await resolveCanonicalManifest();
|
|
146
|
+
if (!canonical) {
|
|
147
|
+
return {
|
|
148
|
+
manifest: base.manifest,
|
|
149
|
+
cache: base.cache,
|
|
150
|
+
packageName: base.manifest.package_name || pkg.name,
|
|
151
|
+
targetVersion: base.manifest.latest_audited_version || localManifest.latest_audited_version || pkg.version,
|
|
152
|
+
repositoryUrl: '',
|
|
153
|
+
migration: false,
|
|
154
|
+
};
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
return {
|
|
158
|
+
manifest: base.manifest,
|
|
159
|
+
cache: base.cache,
|
|
160
|
+
packageName: canonical.packageName,
|
|
161
|
+
targetVersion: canonical.latestVersion,
|
|
162
|
+
repositoryUrl: canonical.repositoryUrl,
|
|
163
|
+
migration: canonical.packageName !== pkg.name,
|
|
164
|
+
};
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
function updateNoticeCache(cache, packageName, latestVersion) {
|
|
106
168
|
const nextCache = {
|
|
107
169
|
...cache,
|
|
108
170
|
last_notice: {
|
|
171
|
+
package_name: packageName,
|
|
109
172
|
current_version: currentVersion,
|
|
110
173
|
latest_audited_version: latestVersion,
|
|
111
174
|
notified_at: Date.now(),
|
|
@@ -114,16 +177,17 @@ function updateNoticeCache(cache, latestVersion) {
|
|
|
114
177
|
writeCache(nextCache);
|
|
115
178
|
}
|
|
116
179
|
|
|
117
|
-
function shouldNotify(cache, latestVersion) {
|
|
180
|
+
function shouldNotify(cache, packageName, latestVersion) {
|
|
118
181
|
const lastNotice = cache.last_notice;
|
|
119
182
|
if (!lastNotice) return true;
|
|
183
|
+
if (lastNotice.package_name !== packageName) return true;
|
|
120
184
|
if (lastNotice.current_version !== currentVersion) return true;
|
|
121
185
|
if (lastNotice.latest_audited_version !== latestVersion) return true;
|
|
122
186
|
return Date.now() - Number(lastNotice.notified_at || 0) >= ttlMs;
|
|
123
187
|
}
|
|
124
188
|
|
|
125
|
-
function installTarget(targetVersion) {
|
|
126
|
-
const spec = `${
|
|
189
|
+
function installTarget(packageName, targetVersion) {
|
|
190
|
+
const spec = `${packageName}@${targetVersion}`;
|
|
127
191
|
const command = `npm install -g ${spec}`;
|
|
128
192
|
|
|
129
193
|
if (dryRun) {
|
|
@@ -140,25 +204,40 @@ function installTarget(targetVersion) {
|
|
|
140
204
|
}
|
|
141
205
|
|
|
142
206
|
async function runNotify() {
|
|
143
|
-
const
|
|
144
|
-
const latest =
|
|
145
|
-
|
|
146
|
-
|
|
207
|
+
const target = await resolveTarget(false);
|
|
208
|
+
const latest = target.targetVersion;
|
|
209
|
+
const packageName = target.packageName;
|
|
210
|
+
const migration = target.migration;
|
|
211
|
+
if (!migration && compareVersions(currentVersion, latest) >= 0) return 0;
|
|
212
|
+
if (!shouldNotify(target.cache, packageName, latest)) return 0;
|
|
213
|
+
|
|
214
|
+
if (migration) {
|
|
215
|
+
console.error(`Legacy package detected: ${pkg.name}`);
|
|
216
|
+
console.error(`Canonical package available: ${packageName}@${latest}`);
|
|
217
|
+
if (target.repositoryUrl) {
|
|
218
|
+
console.error(`Canonical repository: ${target.repositoryUrl}`);
|
|
219
|
+
}
|
|
220
|
+
console.error('Run: claude update');
|
|
221
|
+
updateNoticeCache(target.cache, packageName, latest);
|
|
222
|
+
return 0;
|
|
223
|
+
}
|
|
147
224
|
|
|
148
225
|
console.error(`Audited update available: ${currentVersion} -> ${latest}`);
|
|
149
226
|
console.error('Run: claude update');
|
|
150
|
-
updateNoticeCache(cache, latest);
|
|
227
|
+
updateNoticeCache(target.cache, packageName, latest);
|
|
151
228
|
return 0;
|
|
152
229
|
}
|
|
153
230
|
|
|
154
231
|
async function runUpdate() {
|
|
155
|
-
const
|
|
156
|
-
|
|
157
|
-
if (compareVersions(currentVersion, target) >= 0) {
|
|
232
|
+
const target = await resolveTarget(true);
|
|
233
|
+
if (!target.migration && compareVersions(currentVersion, target.targetVersion) >= 0) {
|
|
158
234
|
console.error(`Already on latest audited version: ${currentVersion}`);
|
|
159
235
|
return 0;
|
|
160
236
|
}
|
|
161
|
-
|
|
237
|
+
if (target.migration) {
|
|
238
|
+
console.error(`Migrating from legacy package ${pkg.name} to canonical package ${target.packageName}@${target.targetVersion}`);
|
|
239
|
+
}
|
|
240
|
+
return installTarget(target.packageName, target.targetVersion);
|
|
162
241
|
}
|
|
163
242
|
|
|
164
243
|
async function main() {
|
package/lib/postinstall.js
CHANGED
|
@@ -10,8 +10,9 @@ if (process.env.CLAUDE_TERMUX_SKIP_POSTINSTALL === '1') {
|
|
|
10
10
|
|
|
11
11
|
const packageDir = path.resolve(__dirname, '..');
|
|
12
12
|
const pkg = require(path.join(packageDir, 'package.json'));
|
|
13
|
+
const manifest = require(path.join(packageDir, 'config', 'claude-termux-release-manifest.json'));
|
|
13
14
|
const script = path.join(__dirname, 'prepare-native.js');
|
|
14
|
-
const version = process.env.CLAUDE_TERMUX_CLAUDE_VERSION || pkg.version;
|
|
15
|
+
const version = process.env.CLAUDE_TERMUX_CLAUDE_VERSION || manifest.default_native_version || manifest.latest_audited_version || pkg.version;
|
|
15
16
|
|
|
16
17
|
const result = cp.spawnSync(process.execPath, [script, version], {
|
|
17
18
|
stdio: 'inherit',
|
package/lib/preinstall.js
CHANGED
|
@@ -1,6 +1,12 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
'use strict';
|
|
3
3
|
|
|
4
|
+
const [_nodeMajor] = process.versions.node.split('.').map(Number);
|
|
5
|
+
if (_nodeMajor < 20) {
|
|
6
|
+
process.stderr.write('@bash0816/claude-code requires Node.js v20 or later. Found: v' + process.versions.node + '\n');
|
|
7
|
+
process.exit(1);
|
|
8
|
+
}
|
|
9
|
+
|
|
4
10
|
const cp = require('child_process');
|
|
5
11
|
const fs = require('fs');
|
|
6
12
|
const os = require('os');
|
package/lib/prepare-native.js
CHANGED
|
@@ -9,11 +9,9 @@ const path = require('path');
|
|
|
9
9
|
const packageDir = path.resolve(__dirname, '..');
|
|
10
10
|
const config = require(path.join(packageDir, 'config', 'claude-native-audited-versions.json'));
|
|
11
11
|
const pkg = require(path.join(packageDir, 'package.json'));
|
|
12
|
-
const
|
|
12
|
+
const manifest = require(path.join(packageDir, 'config', 'claude-termux-release-manifest.json'));
|
|
13
|
+
const version = process.argv[2] || manifest.default_native_version || manifest.latest_audited_version || pkg.version;
|
|
13
14
|
const item = config.versions[version];
|
|
14
|
-
const curlRetries = process.env.CLAUDE_TERMUX_FETCH_RETRIES || '4';
|
|
15
|
-
const curlConnectTimeout = process.env.CLAUDE_TERMUX_FETCH_CONNECT_TIMEOUT || '20';
|
|
16
|
-
const curlMaxTime = process.env.CLAUDE_TERMUX_FETCH_MAX_TIME || '300';
|
|
17
15
|
|
|
18
16
|
if (!item) {
|
|
19
17
|
console.error(`Unsupported audited Claude Code version: ${version}`);
|
|
@@ -31,14 +29,18 @@ if (fs.existsSync(sourceBin)) {
|
|
|
31
29
|
}
|
|
32
30
|
|
|
33
31
|
fs.mkdirSync(versionDir, { recursive: true });
|
|
34
|
-
const packDir = fs.mkdtempSync(path.join(os.tmpdir(), `
|
|
32
|
+
const packDir = fs.mkdtempSync(path.join(os.tmpdir(), `cluade-code-${version}-`));
|
|
35
33
|
|
|
36
34
|
try {
|
|
37
|
-
|
|
35
|
+
run('npm', ['pack', item.native_spec, '--pack-destination', packDir]);
|
|
36
|
+
const tgz = fs.readdirSync(packDir).find(name => name.endsWith('.tgz'));
|
|
37
|
+
if (!tgz) {
|
|
38
|
+
throw new Error('npm pack did not produce a tgz');
|
|
39
|
+
}
|
|
38
40
|
|
|
39
41
|
const extractDir = path.join(packDir, 'native');
|
|
40
42
|
fs.mkdirSync(extractDir, { recursive: true });
|
|
41
|
-
run('tar', ['-xzf',
|
|
43
|
+
run('tar', ['-xzf', path.join(packDir, tgz), '-C', extractDir]);
|
|
42
44
|
|
|
43
45
|
fs.rmSync(nativeDest, { recursive: true, force: true });
|
|
44
46
|
fs.mkdirSync(path.dirname(nativeDest), { recursive: true });
|
|
@@ -55,50 +57,6 @@ function run(command, args) {
|
|
|
55
57
|
}
|
|
56
58
|
}
|
|
57
59
|
|
|
58
|
-
function runCapture(command, args) {
|
|
59
|
-
const result = cp.spawnSync(command, args, {
|
|
60
|
-
stdio: ['ignore', 'pipe', 'inherit'],
|
|
61
|
-
encoding: 'utf8',
|
|
62
|
-
});
|
|
63
|
-
if (result.status !== 0) {
|
|
64
|
-
throw new Error(`${command} ${args.join(' ')} failed`);
|
|
65
|
-
}
|
|
66
|
-
return result.stdout.trim();
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
function fetchNativeTarball(spec, packDir) {
|
|
70
|
-
const directTarball = path.join(packDir, 'native-package.tgz');
|
|
71
|
-
|
|
72
|
-
try {
|
|
73
|
-
const tarballUrl = runCapture('npm', ['view', spec, 'dist.tarball', '--json']).replace(/^"|"$/g, '');
|
|
74
|
-
if (!tarballUrl) {
|
|
75
|
-
throw new Error(`npm view did not return dist.tarball for ${spec}`);
|
|
76
|
-
}
|
|
77
|
-
run('curl', [
|
|
78
|
-
'--fail',
|
|
79
|
-
'--location',
|
|
80
|
-
'--retry', String(curlRetries),
|
|
81
|
-
'--connect-timeout', String(curlConnectTimeout),
|
|
82
|
-
'--max-time', String(curlMaxTime),
|
|
83
|
-
'--output', directTarball,
|
|
84
|
-
tarballUrl,
|
|
85
|
-
]);
|
|
86
|
-
if (fs.existsSync(directTarball)) {
|
|
87
|
-
return directTarball;
|
|
88
|
-
}
|
|
89
|
-
} catch (error) {
|
|
90
|
-
console.error(`Direct tarball fetch failed for ${spec}; falling back to npm pack.`);
|
|
91
|
-
console.error(error && error.message ? error.message : String(error));
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
run('npm', ['pack', spec, '--pack-destination', packDir]);
|
|
95
|
-
const tgz = fs.readdirSync(packDir).find(name => name.endsWith('.tgz'));
|
|
96
|
-
if (!tgz) {
|
|
97
|
-
throw new Error('npm pack did not produce a tgz');
|
|
98
|
-
}
|
|
99
|
-
return path.join(packDir, tgz);
|
|
100
|
-
}
|
|
101
|
-
|
|
102
60
|
function validateOffsets(file, audited) {
|
|
103
61
|
const buf = fs.readFileSync(file);
|
|
104
62
|
const start = Number(audited.entry_js_offset);
|