@bash0816/claude-code 2.1.241 → 2.1.248

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
@@ -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.240
40
+ npm install -g @bash0816/claude-code@2.1.245
41
41
  ```
42
42
 
43
43
  ## Update / 更新
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 >= 5) || (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.5.0 (module.registerHooks() API). 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}}"
@@ -42,11 +52,18 @@ process.stdout.write(String(item[field]));
42
52
  ' "${CONFIG_FILE}" "${CLAUDE_VERSION}" "$1"
43
53
  }
44
54
 
45
- ENTRY_JS_OFFSET=$(json_field entry_js_offset)
46
- ENTRY_END_OFFSET=$(json_field entry_end_offset)
55
+ ENTRY_FORMAT=$(json_field entry_format || echo "legacy-cjs")
47
56
  CACHE_DIR="${CLAUDE_TERMUX_PACKAGE_CACHE:-${HOME}/.claude-termux-native-package}/versions/${CLAUDE_VERSION}"
48
57
  SOURCE_BIN="${CACHE_DIR}/app/node_modules/@anthropic-ai/claude-code-linux-arm64/claude"
49
58
 
59
+ if [ "${ENTRY_FORMAT}" = "esm-chunked" ]; then
60
+ ENTRY_JS_OFFSET=""
61
+ ENTRY_END_OFFSET=""
62
+ else
63
+ ENTRY_JS_OFFSET=$(json_field entry_js_offset)
64
+ ENTRY_END_OFFSET=$(json_field entry_end_offset)
65
+ fi
66
+
50
67
  if [ ! -f "${SOURCE_BIN}" ]; then
51
68
  "$NODE" "${PACKAGE_DIR}/lib/prepare-native.js" "${CLAUDE_VERSION}"
52
69
  fi
@@ -58,6 +75,7 @@ fi
58
75
 
59
76
  SOURCE_BIN="${SOURCE_BIN}" \
60
77
  WORKDIR="${CACHE_DIR}/launcher-workdir" \
78
+ ENTRY_FORMAT="${ENTRY_FORMAT}" \
61
79
  ENTRY_JS_OFFSET="${ENTRY_JS_OFFSET}" \
62
80
  ENTRY_END_OFFSET="${ENTRY_END_OFFSET}" \
63
81
  CURRENT_CLAUDE_VERSION="${CLAUDE_VERSION}" \
@@ -770,6 +770,36 @@
770
770
  "tarball_integrity": "sha512-tHsJhjwcoFyKTCQfYCclKjLtbnbbGKvcrzxUhMb6NDlPw9RrawmjSWUAdla7PtEVPaJsGkjGo4O2MQTlYIT+PA==",
771
771
  "tarball_sha256": "41de896e672667bc5b5060419d5a1ff5cfe15b77659d1418b10df5095e38419a",
772
772
  "status": "termux_verified"
773
+ },
774
+ "2.1.245": {
775
+ "wrapper_spec": "@anthropic-ai/claude-code@2.1.245",
776
+ "native_spec": "@anthropic-ai/claude-code-linux-arm64@2.1.245",
777
+ "entry_format": "esm-chunked",
778
+ "tarball_integrity": "sha512-Qbn5HnZbYeW4GdifVkDGfcVKqj3/f3U9sfVd3LEaUZh08CcS8D/ptJ76zuBfQUGHJHfToAdNVfak86uJ84b1Dg==",
779
+ "tarball_sha256": "668662e7b5d91a93cff6c75736e60f3d5d3bed4cbe077ae4feefc63ad1253f4d",
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": "offset_discovered",
790
+ "num_modules": 1946,
791
+ "byte_count": 136124175,
792
+ "cycle_hoists": [
793
+ { "file": "chunk-vmw9kxhv.js", "targetModule": "chunk-y0jj307t.js", "expectedOccurrences": 1, "assertProperties": [] },
794
+ { "file": "chunk-9n7t2tbt.js", "targetModule": "chunk-ppd18hq1.js", "expectedOccurrences": 1, "assertProperties": ["MonitorTool"] },
795
+ { "file": "chunk-9n7t2tbt.js", "targetModule": "chunk-830s9480.js", "expectedOccurrences": 1, "assertProperties": ["EndConversationTool"] },
796
+ { "file": "chunk-9n7t2tbt.js", "targetModule": "chunk-m4hx5z9g.js", "expectedOccurrences": 1, "assertProperties": ["ArtifactTool"] },
797
+ { "file": "chunk-9n7t2tbt.js", "targetModule": "chunk-eg121wbt.js", "expectedOccurrences": 1, "assertProperties": ["WorkflowTool"] },
798
+ { "file": "chunk-9n7t2tbt.js", "targetModule": "chunk-prrm838s.js", "expectedOccurrences": 1, "assertProperties": [] },
799
+ { "file": "chunk-9n7t2tbt.js", "targetModule": "chunk-exvwsc2a.js", "expectedOccurrences": 2, "assertProperties": [] },
800
+ { "file": "chunk-9n7t2tbt.js", "targetModule": "chunk-s61yn21a.js", "expectedOccurrences": 1, "assertProperties": ["default"] },
801
+ { "file": "chunk-9n7t2tbt.js", "targetModule": "chunk-040m9a9s.js", "expectedOccurrences": 3, "assertProperties": ["getWorkflowCommands", "invalidateWorkflowCache", "warmWorkflows"] }
802
+ ]
773
803
  }
774
804
  }
775
805
  }
@@ -1,9 +1,9 @@
1
1
  {
2
2
  "manifest_version": 1,
3
3
  "package_name": "@bash0816/claude-code",
4
- "latest_audited_version": "2.1.241",
5
- "latest_candidate_version": "2.1.241",
6
- "previous_stable_version": "2.1.240",
4
+ "latest_audited_version": "2.1.245",
5
+ "latest_candidate_version": "2.1.248",
6
+ "previous_stable_version": "2.1.241",
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
  }
@@ -0,0 +1,18 @@
1
+ import { createRequire } from 'node:module';
2
+
3
+ const require = createRequire(import.meta.url);
4
+ const realChildProcess = require('node:child_process');
5
+ const { createGuardedChildProcess } = require('./native-update-guard.js');
6
+ const guarded = createGuardedChildProcess(realChildProcess, (v) => process.stderr.write(v));
7
+
8
+ export const spawn = guarded.spawn;
9
+ export const execFile = guarded.execFile;
10
+ export const exec = guarded.exec;
11
+ export const spawnSync = guarded.spawnSync;
12
+ export const execFileSync = guarded.execFileSync;
13
+ export const execSync = guarded.execSync;
14
+ export const ChildProcess = realChildProcess.ChildProcess;
15
+ export const fork = realChildProcess.fork;
16
+ export const _forkChild = realChildProcess._forkChild;
17
+
18
+ export default Object.assign({}, realChildProcess, guarded);
@@ -0,0 +1,113 @@
1
+ 'use strict';
2
+
3
+ const test = require('node:test');
4
+ const assert = require('node:assert/strict');
5
+
6
+ test('bunfs-child-process-guard exports named exports for guarded methods', async () => {
7
+ const guard = await import('./bunfs-child-process-guard.mjs');
8
+
9
+ assert.equal(typeof guard.spawn, 'function');
10
+ assert.equal(typeof guard.execFile, 'function');
11
+ assert.equal(typeof guard.exec, 'function');
12
+ assert.equal(typeof guard.spawnSync, 'function');
13
+ assert.equal(typeof guard.execFileSync, 'function');
14
+ assert.equal(typeof guard.execSync, 'function');
15
+ });
16
+
17
+ test('bunfs-child-process-guard exports ChildProcess, fork, _forkChild', async () => {
18
+ const guard = await import('./bunfs-child-process-guard.mjs');
19
+
20
+ // ChildProcess is a class
21
+ assert.equal(typeof guard.ChildProcess, 'function');
22
+ // fork and _forkChild are functions
23
+ assert.equal(typeof guard.fork, 'function');
24
+ assert.equal(typeof guard._forkChild, 'function');
25
+ });
26
+
27
+ test('bunfs-child-process-guard provides default export with all methods', async () => {
28
+ const guard = await import('./bunfs-child-process-guard.mjs');
29
+ const defaultExport = guard.default;
30
+
31
+ assert.ok(defaultExport);
32
+ assert.equal(typeof defaultExport, 'object');
33
+ assert.equal(typeof defaultExport.spawn, 'function');
34
+ assert.equal(typeof defaultExport.execFile, 'function');
35
+ assert.equal(typeof defaultExport.exec, 'function');
36
+ assert.equal(typeof defaultExport.spawnSync, 'function');
37
+ assert.equal(typeof defaultExport.execFileSync, 'function');
38
+ assert.equal(typeof defaultExport.execSync, 'function');
39
+ assert.equal(typeof defaultExport.ChildProcess, 'function');
40
+ assert.equal(typeof defaultExport.fork, 'function');
41
+ assert.equal(typeof defaultExport._forkChild, 'function');
42
+ });
43
+
44
+ test('bunfs-child-process-guard blocks official package update via execFileSync', async () => {
45
+ const guard = await import('./bunfs-child-process-guard.mjs');
46
+
47
+ // Try to execute npm install of official package
48
+ try {
49
+ guard.execFileSync('npm', ['install', '-g', '@anthropic-ai/claude-code@latest']);
50
+ // If it doesn't throw, that's an error (should be blocked)
51
+ assert.fail('Expected execFileSync to block official package update');
52
+ } catch (err) {
53
+ // Should throw with CLAUDE_TERMUX_OFFICIAL_UPDATE_BLOCKED code
54
+ assert.ok(
55
+ err.code === 'CLAUDE_TERMUX_OFFICIAL_UPDATE_BLOCKED' ||
56
+ err.message.includes('disabled on Termux'),
57
+ `Expected block error, got: ${err.message}`,
58
+ );
59
+ }
60
+ });
61
+
62
+ test('bunfs-child-process-guard blocks official package update via execSync', async () => {
63
+ const guard = await import('./bunfs-child-process-guard.mjs');
64
+
65
+ // Try to execute npm install via exec
66
+ try {
67
+ guard.execSync('npm install -g @anthropic-ai/claude-code@latest');
68
+ // If it doesn't throw, that's an error (should be blocked)
69
+ assert.fail('Expected execSync to block official package update');
70
+ } catch (err) {
71
+ // Should throw with CLAUDE_TERMUX_OFFICIAL_UPDATE_BLOCKED code
72
+ assert.ok(
73
+ err.code === 'CLAUDE_TERMUX_OFFICIAL_UPDATE_BLOCKED' ||
74
+ err.message.includes('disabled on Termux'),
75
+ `Expected block error, got: ${err.message}`,
76
+ );
77
+ }
78
+ });
79
+
80
+ test('bunfs-child-process-guard allows harmless commands', async () => {
81
+ const guard = await import('./bunfs-child-process-guard.mjs');
82
+
83
+ // echo is a harmless command and should not be blocked
84
+ const result = guard.execFileSync('echo', ['hello']);
85
+ // Verify the command actually executed and produced output
86
+ assert.equal(result.toString().trim(), 'hello');
87
+ });
88
+
89
+ test('bunfs-child-process-guard spawn blocks official package install', async () => {
90
+ const guard = await import('./bunfs-child-process-guard.mjs');
91
+
92
+ // spawn should return a blocked child process (EventEmitter-like)
93
+ const child = guard.spawn('npm', ['install', '-g', '@anthropic-ai/claude-code']);
94
+
95
+ // Blocked spawn should have specific properties
96
+ assert.equal(child.stdout, null);
97
+ assert.equal(child.stderr, null);
98
+ assert.equal(child.stdin, null);
99
+ assert.equal(child.pid, 0);
100
+ assert.equal(child.killed, false);
101
+
102
+ // Verify it's event-like (has on method or can be used as event emitter)
103
+ assert.equal(typeof child.kill, 'function');
104
+ });
105
+
106
+ test('bunfs-child-process-guard does not block other package installs', async () => {
107
+ const guard = await import('./bunfs-child-process-guard.mjs');
108
+
109
+ // Installing a different package should not be blocked
110
+ const result = guard.execFileSync('echo', ['@bash0816/claude-code']);
111
+ // Verify the command actually executed and produced correct output
112
+ assert.equal(result.toString().trim(), '@bash0816/claude-code');
113
+ });
@@ -0,0 +1,167 @@
1
+ import { pathToFileURL, fileURLToPath } from 'node:url';
2
+ import { existsSync, readFileSync } from 'node:fs';
3
+ import { createRequire } from 'node:module';
4
+ import path from 'node:path';
5
+
6
+ let PROCESS_OWNED_DIR = null;
7
+ let SOURCE_BIN = null;
8
+ let CHILD_PROCESS_GUARD_PATH = null;
9
+ let VM_GUARD_PATH = null;
10
+ let WS_STUB_PATH = null;
11
+
12
+ let CYCLE_HOISTS = [];
13
+
14
+ export function initialize(data) {
15
+ PROCESS_OWNED_DIR = data.processOwnedDir;
16
+ SOURCE_BIN = data.sourceBin;
17
+ CHILD_PROCESS_GUARD_PATH = data.childProcessGuardPath;
18
+ VM_GUARD_PATH = data.vmGuardPath;
19
+ WS_STUB_PATH = data.wsStubPath;
20
+ CYCLE_HOISTS = Array.isArray(data.cycleHoists) ? data.cycleHoists : [];
21
+ }
22
+
23
+ function tryHoistCycleBreakingImports(filePath, source) {
24
+ const rel = path.relative(PROCESS_OWNED_DIR, filePath);
25
+ const records = CYCLE_HOISTS.filter((r) => r.file === rel);
26
+ if (records.length === 0) return null;
27
+
28
+ let hoistedImportLines = '';
29
+ let newSource = source;
30
+ let varIndex = 0;
31
+ const targetToVar = new Map();
32
+
33
+ for (const record of records) {
34
+ const literal = `import.meta.require("/$bunfs/root/${record.targetModule}")`;
35
+ const occurrences = newSource.split(literal).length - 1;
36
+ if (occurrences !== record.expectedOccurrences) continue;
37
+
38
+ const real = path.resolve(PROCESS_OWNED_DIR, record.targetModule);
39
+ if (path.relative(PROCESS_OWNED_DIR, real).startsWith('..')) continue;
40
+ if (!existsSync(real)) continue;
41
+
42
+ let varName = targetToVar.get(record.targetModule);
43
+ if (!varName) {
44
+ varName = `__bunfsHoisted_${varIndex++}`;
45
+ targetToVar.set(record.targetModule, varName);
46
+ hoistedImportLines += `import * as ${varName} from ${JSON.stringify(pathToFileURL(real).href)};\n`;
47
+ if (record.assertProperties && record.assertProperties.length > 0) {
48
+ hoistedImportLines += `__bunfsAssertHoistedProps(${varName}, ${JSON.stringify(record.targetModule)}, ${JSON.stringify(record.assertProperties)});\n`;
49
+ }
50
+ }
51
+ newSource = newSource.replaceAll(literal, varName);
52
+ }
53
+
54
+ if (!targetToVar.size) return null;
55
+ return { hoistedImportLine: hoistedImportLines, source: newSource };
56
+ }
57
+
58
+ function buildImportMetaRequirePolyfillPrelude(anchorUrl) {
59
+ return (
60
+ `import __bunfsGuardedChildProcess from ${JSON.stringify(pathToFileURL(CHILD_PROCESS_GUARD_PATH).href)};\n` +
61
+ `import __bunfsGuardedVm from ${JSON.stringify(pathToFileURL(VM_GUARD_PATH).href)};\n` +
62
+ `import { createRequire as __bunfsCreateRequire } from "node:module";\n` +
63
+ `import __bunfsMetaRequirePath from "node:path";\n` +
64
+ `import { existsSync as __bunfsMetaRequireExistsSync } from "node:fs";\n` +
65
+ `import { readFileSync as __bunfsMetaRequireReadFileSync } from "node:fs";\n` +
66
+ `function __bunfsAssertHoistedProps(ns, targetModule, propNames) {\n` +
67
+ ` for (const p of propNames) {\n` +
68
+ ` let v;\n` +
69
+ ` try {\n` +
70
+ ` v = ns[p];\n` +
71
+ ` } catch (e) {\n` +
72
+ ` if (e instanceof ReferenceError) {\n` +
73
+ ` throw new Error("bunfs cycle-hoist: accessing \\"" + p + "\\" on " + targetModule + " threw ReferenceError (TDZ) - evaluation-order regression");\n` +
74
+ ` }\n` +
75
+ ` throw e;\n` +
76
+ ` }\n` +
77
+ ` if (v === undefined) {\n` +
78
+ ` throw new Error("bunfs cycle-hoist: \\"" + p + "\\" is undefined after hoisting from " + targetModule + " (evaluation-order regression?)");\n` +
79
+ ` }\n` +
80
+ ` }\n` +
81
+ `}\n` +
82
+ `const __bunfsRealRequire = __bunfsCreateRequire(${JSON.stringify(anchorUrl)});\n` +
83
+ `const __bunfsOwnedDir = ${JSON.stringify(PROCESS_OWNED_DIR)};\n` +
84
+ `const __bunfsMetaRequire = (id) => {\n` +
85
+ ` if (id === "child_process" || id === "node:child_process") return __bunfsGuardedChildProcess;\n` +
86
+ ` if (id === "vm" || id === "node:vm") return __bunfsGuardedVm;\n` +
87
+ ` if (typeof id === "string" && id.startsWith("/$bunfs/root/")) {\n` +
88
+ ` const rel = id.slice("/$bunfs/root/".length);\n` +
89
+ ` if (rel.includes("..") || __bunfsMetaRequirePath.isAbsolute(rel)) {\n` +
90
+ ` throw new Error("bunfs meta-require: rejected specifier " + id);\n` +
91
+ ` }\n` +
92
+ ` const real = __bunfsMetaRequirePath.resolve(__bunfsOwnedDir, rel);\n` +
93
+ ` if (__bunfsMetaRequirePath.relative(__bunfsOwnedDir, real).startsWith("..")) {\n` +
94
+ ` throw new Error("bunfs meta-require: path escapes process-owned dir: " + id);\n` +
95
+ ` }\n` +
96
+ ` if (!__bunfsMetaRequireExistsSync(real)) {\n` +
97
+ ` throw new Error("bunfs meta-require: missing extracted module " + id + " -> " + real);\n` +
98
+ ` }\n` +
99
+ ` const ext = __bunfsMetaRequirePath.extname(real);\n` +
100
+ ` if (ext === ".md" || ext === ".txt") {\n` +
101
+ ` return __bunfsMetaRequireReadFileSync(real, "utf8");\n` +
102
+ ` }\n` +
103
+ ` return __bunfsRealRequire(real);\n` +
104
+ ` }\n` +
105
+ ` return __bunfsRealRequire(id);\n` +
106
+ `};\n`
107
+ );
108
+ }
109
+
110
+ export function resolve(specifier, context, nextResolve) {
111
+ const parentURL = context && context.parentURL;
112
+ const ownedPrefix = pathToFileURL(PROCESS_OWNED_DIR + path.sep).href;
113
+ const fromChunk = typeof parentURL === 'string' && parentURL.startsWith(ownedPrefix);
114
+
115
+ if (fromChunk) {
116
+ if (specifier === 'child_process' || specifier === 'node:child_process') {
117
+ return { url: pathToFileURL(CHILD_PROCESS_GUARD_PATH).href, shortCircuit: true, format: 'module' };
118
+ }
119
+ if (specifier === 'vm' || specifier === 'node:vm') {
120
+ return { url: pathToFileURL(VM_GUARD_PATH).href, shortCircuit: true, format: 'module' };
121
+ }
122
+ if (specifier === 'ws') {
123
+ return { url: pathToFileURL(WS_STUB_PATH).href, shortCircuit: true, format: 'module' };
124
+ }
125
+ }
126
+ if (specifier.startsWith('/$bunfs/root/')) {
127
+ const rel = specifier.slice('/$bunfs/root/'.length);
128
+ if (rel.includes('..') || path.isAbsolute(rel)) {
129
+ throw new Error(`bunfs resolve: rejected specifier ${specifier}`);
130
+ }
131
+ const real = path.resolve(PROCESS_OWNED_DIR, rel);
132
+ if (path.relative(PROCESS_OWNED_DIR, real).startsWith('..')) {
133
+ throw new Error(`bunfs resolve: path escapes process-owned dir: ${specifier}`);
134
+ }
135
+ if (!existsSync(real)) {
136
+ throw new Error(`bunfs resolve: missing extracted module ${specifier} -> ${real}`);
137
+ }
138
+ return { url: pathToFileURL(real).href, shortCircuit: true, format: 'module' };
139
+ }
140
+ return nextResolve(specifier, context);
141
+ }
142
+
143
+ export function load(url, context, nextLoad) {
144
+ const ownedPrefix = pathToFileURL(PROCESS_OWNED_DIR + path.sep).href;
145
+ if (!url.startsWith(ownedPrefix)) {
146
+ return nextLoad(url, context);
147
+ }
148
+ const filePath = fileURLToPath(url);
149
+ let source = readFileSync(filePath, 'utf8');
150
+
151
+ let hoistedImportLine = '';
152
+ const hoistResult = tryHoistCycleBreakingImports(filePath, source);
153
+ if (hoistResult) {
154
+ hoistedImportLine = hoistResult.hoistedImportLine;
155
+ source = hoistResult.source;
156
+ }
157
+
158
+ if (source.includes('import.meta.require')) {
159
+ const anchorUrl = pathToFileURL(SOURCE_BIN).href;
160
+ source = hoistedImportLine +
161
+ buildImportMetaRequirePolyfillPrelude(anchorUrl) +
162
+ source.replaceAll('import.meta.require', '__bunfsMetaRequire');
163
+ } else if (hoistedImportLine) {
164
+ source = hoistedImportLine + source;
165
+ }
166
+ return { format: 'module', source, shortCircuit: true };
167
+ }