claude-code-termux 1.0.0
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/LICENSE +21 -0
- package/README.md +198 -0
- package/bin/claude-termux.js +80 -0
- package/docs/INSTALLATION.md +136 -0
- package/docs/KNOWN-ISSUES.md +135 -0
- package/docs/TROUBLESHOOTING.md +225 -0
- package/package.json +50 -0
- package/postinstall.js +204 -0
- package/scripts/download-ripgrep.sh +55 -0
- package/scripts/setup-termux.sh +120 -0
- package/scripts/verify-install.js +188 -0
- package/src/binaries/README.md +29 -0
- package/src/patches/apply-all.js +45 -0
- package/src/patches/hook-events.js +108 -0
- package/src/patches/oauth-storage.js +163 -0
- package/src/patches/path-normalization.js +134 -0
- package/src/patches/ripgrep-fallback.js +95 -0
- package/src/patches/sharp-fallback.js +65 -0
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Ripgrep Fallback Patch
|
|
3
|
+
*
|
|
4
|
+
* This patch ensures ripgrep works on Termux by:
|
|
5
|
+
* 1. Setting up the correct binary path for android-arm64
|
|
6
|
+
* 2. Falling back to system ripgrep if available
|
|
7
|
+
* 3. Modifying spawn calls to use the correct binary
|
|
8
|
+
*
|
|
9
|
+
* Issue: https://github.com/anthropics/claude-code/issues/6244
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
'use strict';
|
|
13
|
+
|
|
14
|
+
const { spawn } = require('child_process');
|
|
15
|
+
const path = require('path');
|
|
16
|
+
const fs = require('fs');
|
|
17
|
+
|
|
18
|
+
// Detect if we're on Termux
|
|
19
|
+
const isTermux = process.platform === 'android' ||
|
|
20
|
+
process.env.PREFIX?.includes('com.termux') ||
|
|
21
|
+
process.env.HOME?.includes('com.termux');
|
|
22
|
+
|
|
23
|
+
let systemRipgrepPath = null;
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Find system ripgrep installation
|
|
27
|
+
*/
|
|
28
|
+
function findSystemRipgrep() {
|
|
29
|
+
const possiblePaths = [
|
|
30
|
+
// Termux paths
|
|
31
|
+
'/data/data/com.termux/files/usr/bin/rg',
|
|
32
|
+
path.join(process.env.PREFIX || '', 'bin', 'rg'),
|
|
33
|
+
// Standard Linux paths
|
|
34
|
+
'/usr/bin/rg',
|
|
35
|
+
'/usr/local/bin/rg',
|
|
36
|
+
];
|
|
37
|
+
|
|
38
|
+
for (const p of possiblePaths) {
|
|
39
|
+
if (fs.existsSync(p)) {
|
|
40
|
+
return p;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
return null;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Patch the child_process.spawn to intercept ripgrep calls
|
|
49
|
+
*/
|
|
50
|
+
function apply() {
|
|
51
|
+
if (!isTermux) {
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
// Find system ripgrep
|
|
56
|
+
systemRipgrepPath = findSystemRipgrep();
|
|
57
|
+
|
|
58
|
+
if (systemRipgrepPath) {
|
|
59
|
+
console.log(`[claude-code-termux] Found system ripgrep: ${systemRipgrepPath}`);
|
|
60
|
+
} else {
|
|
61
|
+
console.warn('[claude-code-termux] System ripgrep not found. Install with: pkg install ripgrep');
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
// Monkey-patch spawn to intercept ripgrep calls
|
|
65
|
+
const originalSpawn = spawn;
|
|
66
|
+
const child_process = require('child_process');
|
|
67
|
+
|
|
68
|
+
child_process.spawn = function(command, args, options) {
|
|
69
|
+
// Check if this is a ripgrep call that's failing
|
|
70
|
+
if (typeof command === 'string' && command.includes('ripgrep') && command.includes('arm64-android')) {
|
|
71
|
+
// Replace with system ripgrep if available
|
|
72
|
+
if (systemRipgrepPath) {
|
|
73
|
+
console.log('[claude-code-termux] Redirecting ripgrep call to system binary');
|
|
74
|
+
return originalSpawn(systemRipgrepPath, args, options);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
// Also intercept direct 'rg' calls with invalid paths
|
|
79
|
+
if (typeof command === 'string' && command.endsWith('/rg') && !fs.existsSync(command)) {
|
|
80
|
+
if (systemRipgrepPath) {
|
|
81
|
+
console.log('[claude-code-termux] Redirecting invalid rg path to system binary');
|
|
82
|
+
return originalSpawn(systemRipgrepPath, args, options);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
return originalSpawn(command, args, options);
|
|
87
|
+
};
|
|
88
|
+
|
|
89
|
+
// Also set environment variable to help Claude Code find ripgrep
|
|
90
|
+
if (systemRipgrepPath) {
|
|
91
|
+
process.env.RIPGREP_PATH = systemRipgrepPath;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
module.exports = { apply, findSystemRipgrep };
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Sharp WASM Fallback Patch
|
|
3
|
+
*
|
|
4
|
+
* This patch ensures the Sharp image library falls back to WebAssembly
|
|
5
|
+
* when running on Android ARM64 where native binaries aren't available.
|
|
6
|
+
*
|
|
7
|
+
* Issue: https://github.com/anthropics/claude-code/issues/2248
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
'use strict';
|
|
11
|
+
|
|
12
|
+
const Module = require('module');
|
|
13
|
+
|
|
14
|
+
// Store the original require
|
|
15
|
+
const originalRequire = Module.prototype.require;
|
|
16
|
+
|
|
17
|
+
// Detect if we need the fallback
|
|
18
|
+
const needsFallback = process.platform === 'android' ||
|
|
19
|
+
(process.arch === 'arm64' && process.platform !== 'darwin' && process.platform !== 'linux');
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Apply the Sharp WASM fallback
|
|
23
|
+
*/
|
|
24
|
+
function apply() {
|
|
25
|
+
if (!needsFallback) {
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
// Monkey-patch require to intercept sharp imports
|
|
30
|
+
Module.prototype.require = function(id) {
|
|
31
|
+
if (id === 'sharp') {
|
|
32
|
+
try {
|
|
33
|
+
// First, try to load the WASM version
|
|
34
|
+
return originalRequire.call(this, '@img/sharp-wasm32');
|
|
35
|
+
} catch (wasmErr) {
|
|
36
|
+
// If WASM version isn't available, try native anyway
|
|
37
|
+
try {
|
|
38
|
+
return originalRequire.call(this, id);
|
|
39
|
+
} catch (nativeErr) {
|
|
40
|
+
// Provide helpful error message
|
|
41
|
+
const error = new Error(
|
|
42
|
+
'Sharp module failed to load. On Termux/Android, install the WASM version:\n' +
|
|
43
|
+
' npm install @img/sharp-wasm32 --force\n' +
|
|
44
|
+
' npm install sharp --force'
|
|
45
|
+
);
|
|
46
|
+
error.code = 'SHARP_WASM_REQUIRED';
|
|
47
|
+
throw error;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
return originalRequire.call(this, id);
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
// Also set environment variable hint for sharp
|
|
55
|
+
process.env.SHARP_IGNORE_GLOBAL_LIBVIPS = '1';
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Restore original require (for testing)
|
|
60
|
+
*/
|
|
61
|
+
function restore() {
|
|
62
|
+
Module.prototype.require = originalRequire;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
module.exports = { apply, restore, needsFallback };
|