@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 CHANGED
@@ -1,17 +1,19 @@
1
- # @bash0816/claude-code
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
- This package is the current Termux wrapper package line.
7
+ Legacy compatibility package:
8
8
 
9
- この package は現行の Termux wrapper package 系です。
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/claude-code@latest
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/claude-code@latest
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 versions:
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/claude-code@2.1.118
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
- `claude update` は最新の監査済み package version install します。
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
- - `2.1.118`, `2.1.119`, `2.1.121`, `2.1.122`, `2.1.123`, `2.1.126`, `2.1.128`, `2.1.136`, `2.1.137`, `2.1.138`, `2.1.139`, `2.1.140`, `2.1.141`, `2.1.142`, `2.1.143`, `2.1.144` are included in the package metadata.
87
- - `2.1.118`、`2.1.119`、`2.1.121`、`2.1.122`、`2.1.123`、`2.1.126`、`2.1.128`、`2.1.136`、`2.1.137`、`2.1.138`、`2.1.139`、`2.1.140`、`2.1.141`、`2.1.142`、`2.1.143`、`2.1.144` package metadata に含めています。
88
- - The metadata file is the source of truth for the currently audited set.
89
- - 現在の監査済み version 集合の source of truth metadata file です。
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
- CLAUDE_VERSION="${CLAUDE_TERMUX_CLAUDE_VERSION:-${PACKAGE_VERSION}}"
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
- "latest_audited_version": "2.1.150",
5
- "latest_candidate_version": "2.1.150",
6
- "previous_stable_version": "2.1.144",
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
  }
@@ -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 aParts = String(a).split('.').map(Number);
25
- const bParts = String(b).split('.').map(Number);
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 updateNoticeCache(cache, latestVersion) {
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 = `${pkg.name}@${targetVersion}`;
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 { manifest, cache } = await resolveManifest(false);
144
- const latest = manifest.latest_audited_version || localManifest.latest_audited_version || pkg.version;
145
- if (compareVersions(currentVersion, latest) >= 0) return 0;
146
- if (!shouldNotify(cache, latest)) return 0;
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 { manifest } = await resolveManifest(true);
156
- const target = manifest.latest_audited_version || localManifest.latest_audited_version || pkg.version;
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
- return installTarget(target);
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() {
@@ -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');
@@ -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 version = process.argv[2] || pkg.version;
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(), `claude-code-${version}-`));
32
+ const packDir = fs.mkdtempSync(path.join(os.tmpdir(), `cluade-code-${version}-`));
35
33
 
36
34
  try {
37
- const tgzPath = fetchNativeTarball(item.native_spec, packDir);
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', tgzPath, '-C', extractDir]);
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);