@bash0816/claude-code 2.1.159-1 → 2.1.159-10
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 +3 -3
- package/config/claude-native-audited-versions.json +45 -0
- package/config/claude-termux-release-manifest.json +3 -3
- package/lib/check-updates.js +1 -11
- package/lib/termux-run-claude-native.sh +103 -5
- package/lib/version-utils.js +24 -0
- package/lib/version-utils.test.js +25 -0
- package/package.json +15 -9
package/README.md
CHANGED
|
@@ -43,7 +43,7 @@ Current quick examples:
|
|
|
43
43
|
現在の quick example:
|
|
44
44
|
|
|
45
45
|
```sh
|
|
46
|
-
npm install -g @bash0816/claude-code@2.1.
|
|
46
|
+
npm install -g @bash0816/claude-code@2.1.159-10
|
|
47
47
|
```
|
|
48
48
|
|
|
49
49
|
## Update / 更新
|
|
@@ -68,8 +68,8 @@ Normal launch also checks the same manifest with a short timeout and prints a no
|
|
|
68
68
|
|
|
69
69
|
- Only audited versions in `config/claude-native-audited-versions.json` can run.
|
|
70
70
|
- `config/claude-native-audited-versions.json` にある監査済み version だけを実行できます。
|
|
71
|
-
- `2.1.
|
|
72
|
-
- `2.1.
|
|
71
|
+
- `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`, `2.1.150`, `2.1.150-1`, `2.1.150-2`, `2.1.150-3`, `2.1.153`, `2.1.153-1`, `2.1.153-2`, `2.1.153-3`, `2.1.153-4`, `2.1.157`, `2.1.159-4`, `2.1.159-8`, `2.1.159-10` are included in the package metadata.
|
|
72
|
+
- `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`、`2.1.150`、`2.1.150-1`、`2.1.150-2`、`2.1.150-3`、`2.1.153`、`2.1.153-1`、`2.1.153-2`、`2.1.153-3`、`2.1.153-4`、`2.1.157`、`2.1.159-4`、`2.1.159-8`、`2.1.159-10` を package metadata に含めています。
|
|
73
73
|
- The metadata file is the source of truth for the currently audited set.
|
|
74
74
|
- 現在の監査済み version 集合の source of truth は metadata file です。
|
|
75
75
|
- Native artifacts are cached under `${HOME}/.claude-termux-native-package`.
|
|
@@ -181,6 +181,51 @@
|
|
|
181
181
|
"entry_js_offset": 223210916,
|
|
182
182
|
"entry_end_offset": 238725072,
|
|
183
183
|
"status": "termux_verified"
|
|
184
|
+
},
|
|
185
|
+
"2.1.159-2": {
|
|
186
|
+
"wrapper_spec": "@anthropic-ai/claude-code@2.1.159",
|
|
187
|
+
"native_spec": "@anthropic-ai/claude-code-linux-arm64@2.1.159",
|
|
188
|
+
"entry_js_offset": 223232708,
|
|
189
|
+
"entry_end_offset": 238749397,
|
|
190
|
+
"tarball_integrity": "sha512-c8dXbuQdrotGWll46GlnXm5IPpORK2VrBSosCmI6f8t7Snc/3F58fX0MbIjJ/ycXpY0aaKuOnufCuxf7wi1Xqw==",
|
|
191
|
+
"tarball_sha256": "0b551634f11742310ba3b6344fb7912ba1ed8ee0ef4702eab0099d31b4eeb070",
|
|
192
|
+
"status": "offset_discovered"
|
|
193
|
+
},
|
|
194
|
+
"2.1.159-4": {
|
|
195
|
+
"wrapper_spec": "@anthropic-ai/claude-code@2.1.159",
|
|
196
|
+
"native_spec": "@anthropic-ai/claude-code-linux-arm64@2.1.159",
|
|
197
|
+
"entry_js_offset": 223232708,
|
|
198
|
+
"entry_end_offset": 238749397,
|
|
199
|
+
"tarball_integrity": "sha512-c8dXbuQdrotGWll46GlnXm5IPpORK2VrBSosCmI6f8t7Snc/3F58fX0MbIjJ/ycXpY0aaKuOnufCuxf7wi1Xqw==",
|
|
200
|
+
"tarball_sha256": "0b551634f11742310ba3b6344fb7912ba1ed8ee0ef4702eab0099d31b4eeb070",
|
|
201
|
+
"status": "termux_verified"
|
|
202
|
+
},
|
|
203
|
+
"2.1.159-5": {
|
|
204
|
+
"wrapper_spec": "@anthropic-ai/claude-code@2.1.159",
|
|
205
|
+
"native_spec": "@anthropic-ai/claude-code-linux-arm64@2.1.159",
|
|
206
|
+
"entry_js_offset": 223232708,
|
|
207
|
+
"entry_end_offset": 238749397,
|
|
208
|
+
"tarball_integrity": "sha512-c8dXbuQdrotGWll46GlnXm5IPpORK2VrBSosCmI6f8t7Snc/3F58fX0MbIjJ/ycXpY0aaKuOnufCuxf7wi1Xqw==",
|
|
209
|
+
"tarball_sha256": "0b551634f11742310ba3b6344fb7912ba1ed8ee0ef4702eab0099d31b4eeb070",
|
|
210
|
+
"status": "offset_discovered"
|
|
211
|
+
},
|
|
212
|
+
"2.1.159-8": {
|
|
213
|
+
"wrapper_spec": "@anthropic-ai/claude-code@2.1.159",
|
|
214
|
+
"native_spec": "@anthropic-ai/claude-code-linux-arm64@2.1.159",
|
|
215
|
+
"entry_js_offset": 223232708,
|
|
216
|
+
"entry_end_offset": 238749397,
|
|
217
|
+
"tarball_integrity": "sha512-c8dXbuQdrotGWll46GlnXm5IPpORK2VrBSosCmI6f8t7Snc/3F58fX0MbIjJ/ycXpY0aaKuOnufCuxf7wi1Xqw==",
|
|
218
|
+
"tarball_sha256": "0b551634f11742310ba3b6344fb7912ba1ed8ee0ef4702eab0099d31b4eeb070",
|
|
219
|
+
"status": "termux_verified"
|
|
220
|
+
},
|
|
221
|
+
"2.1.159-10": {
|
|
222
|
+
"wrapper_spec": "@anthropic-ai/claude-code@2.1.159",
|
|
223
|
+
"native_spec": "@anthropic-ai/claude-code-linux-arm64@2.1.159",
|
|
224
|
+
"entry_js_offset": 223232708,
|
|
225
|
+
"entry_end_offset": 238749397,
|
|
226
|
+
"tarball_integrity": "sha512-c8dXbuQdrotGWll46GlnXm5IPpORK2VrBSosCmI6f8t7Snc/3F58fX0MbIjJ/ycXpY0aaKuOnufCuxf7wi1Xqw==",
|
|
227
|
+
"tarball_sha256": "0b551634f11742310ba3b6344fb7912ba1ed8ee0ef4702eab0099d31b4eeb070",
|
|
228
|
+
"status": "termux_verified"
|
|
184
229
|
}
|
|
185
230
|
}
|
|
186
231
|
}
|
|
@@ -1,8 +1,8 @@
|
|
|
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.159-10",
|
|
5
|
+
"latest_candidate_version": "2.1.159-10",
|
|
6
|
+
"previous_stable_version": "2.1.159-8",
|
|
7
7
|
"manifest_url": "https://raw.githubusercontent.com/bash0816/ClaudeCode-Termux/main/config/claude-termux-release-manifest.json"
|
|
8
8
|
}
|
package/lib/check-updates.js
CHANGED
|
@@ -10,6 +10,7 @@ const path = require('path');
|
|
|
10
10
|
const packageDir = path.resolve(__dirname, '..');
|
|
11
11
|
const pkg = require(path.join(packageDir, 'package.json'));
|
|
12
12
|
const localManifest = require(path.join(packageDir, 'config', 'claude-termux-release-manifest.json'));
|
|
13
|
+
const { compareVersions } = require('./version-utils');
|
|
13
14
|
const mode = process.argv[2] || 'notify';
|
|
14
15
|
const currentVersion = process.argv[3] || pkg.version;
|
|
15
16
|
const dryRun = process.argv.includes('--dry-run');
|
|
@@ -20,17 +21,6 @@ const ttlMs = Number(process.env.CLAUDE_TERMUX_UPDATE_CACHE_TTL_MS || String(24
|
|
|
20
21
|
const skipCheck = process.env.CLAUDE_TERMUX_SKIP_UPDATE_CHECK === '1';
|
|
21
22
|
const manifestUrl = process.env.CLAUDE_TERMUX_MANIFEST_URL || localManifest.manifest_url;
|
|
22
23
|
|
|
23
|
-
function compareVersions(a, b) {
|
|
24
|
-
const aParts = String(a).split('.').map(Number);
|
|
25
|
-
const bParts = String(b).split('.').map(Number);
|
|
26
|
-
const len = Math.max(aParts.length, bParts.length);
|
|
27
|
-
for (let index = 0; index < len; index += 1) {
|
|
28
|
-
const diff = (aParts[index] || 0) - (bParts[index] || 0);
|
|
29
|
-
if (diff !== 0) return diff;
|
|
30
|
-
}
|
|
31
|
-
return 0;
|
|
32
|
-
}
|
|
33
|
-
|
|
34
24
|
function readCache() {
|
|
35
25
|
try {
|
|
36
26
|
return JSON.parse(fs.readFileSync(cacheFile, 'utf8'));
|
|
@@ -177,7 +177,52 @@ async function main() {
|
|
|
177
177
|
process.once('uncaughtException', onAsyncError);
|
|
178
178
|
process.once('unhandledRejection', onAsyncError);
|
|
179
179
|
Object.defineProperty(process.versions, 'bun', { value: '1.1.8', configurable: true });
|
|
180
|
-
|
|
180
|
+
const _realChild = require('child_process');
|
|
181
|
+
globalThis.Bun = {
|
|
182
|
+
version: '1.1.8',
|
|
183
|
+
stringWidth,
|
|
184
|
+
which: (cmd) => {
|
|
185
|
+
try {
|
|
186
|
+
return _realChild.execFileSync('which', [String(cmd)], { encoding: 'utf8' }).trim() || null;
|
|
187
|
+
} catch { return null; }
|
|
188
|
+
},
|
|
189
|
+
semver: (() => {
|
|
190
|
+
const _cmp = (a, b) => {
|
|
191
|
+
const pa = String(a).replace(/[^0-9.]/g,'').split('.').map(Number);
|
|
192
|
+
const pb = String(b).replace(/[^0-9.]/g,'').split('.').map(Number);
|
|
193
|
+
for (let i = 0; i < 3; i++) { const d = (pa[i]||0)-(pb[i]||0); if (d) return d > 0 ? 1 : -1; }
|
|
194
|
+
return 0;
|
|
195
|
+
};
|
|
196
|
+
const _satisfies = (ver, range) => {
|
|
197
|
+
const s = String(range).trim();
|
|
198
|
+
const m = s.match(/^([><=!]{1,2})\s*([\d]+(?:\.[\d]+){0,2})$/);
|
|
199
|
+
if (m) {
|
|
200
|
+
const op = m[1], c = _cmp(ver, m[2]);
|
|
201
|
+
if (op === '>') return c > 0;
|
|
202
|
+
if (op === '>=') return c >= 0;
|
|
203
|
+
if (op === '<') return c < 0;
|
|
204
|
+
if (op === '<=') return c <= 0;
|
|
205
|
+
if (op === '=' || op === '==') return c === 0;
|
|
206
|
+
if (op === '!=') return c !== 0;
|
|
207
|
+
}
|
|
208
|
+
if (/^[\d]+(?:\.[\d]+){0,2}$/.test(s)) return _cmp(ver, s) === 0;
|
|
209
|
+
return false;
|
|
210
|
+
};
|
|
211
|
+
return {
|
|
212
|
+
order: (a, b) => _cmp(a, b),
|
|
213
|
+
compare: (a, b) => _cmp(a, b),
|
|
214
|
+
satisfies: (ver, range) => _satisfies(ver, range),
|
|
215
|
+
gt: (a, b) => _cmp(a, b) > 0,
|
|
216
|
+
gte: (a, b) => _cmp(a, b) >= 0,
|
|
217
|
+
lt: (a, b) => _cmp(a, b) < 0,
|
|
218
|
+
lte: (a, b) => _cmp(a, b) <= 0,
|
|
219
|
+
};
|
|
220
|
+
})(),
|
|
221
|
+
YAML: {
|
|
222
|
+
parse: () => undefined,
|
|
223
|
+
stringify: (obj) => (typeof obj === 'string' ? obj : ''),
|
|
224
|
+
},
|
|
225
|
+
};
|
|
181
226
|
process.argv = ['node', extractedFile, ...argv];
|
|
182
227
|
process.exit = code => {
|
|
183
228
|
throw new RequestedExit(code);
|
|
@@ -220,13 +265,18 @@ main().catch(error => {
|
|
|
220
265
|
process.exit(1);
|
|
221
266
|
});
|
|
222
267
|
NODE
|
|
268
|
+
export CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC="${CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC:-1}"
|
|
269
|
+
export ENABLE_CLAUDEAI_MCP_SERVERS="${ENABLE_CLAUDEAI_MCP_SERVERS:-0}"
|
|
270
|
+
export CLAUDE_CODE_SIMPLE="${CLAUDE_CODE_SIMPLE:-1}"
|
|
223
271
|
node "$_helper" "$@" </dev/null
|
|
224
272
|
_status=$?
|
|
225
273
|
rm -f "$_helper"
|
|
226
274
|
trap - EXIT HUP INT TERM
|
|
227
275
|
exit "$_status"
|
|
228
276
|
else
|
|
229
|
-
|
|
277
|
+
_bootstrap=$(mktemp "${TMPDIR:-/tmp}/claude-bootstrap.XXXXXX.js")
|
|
278
|
+
trap 'rm -f "$_bootstrap"' EXIT HUP INT TERM
|
|
279
|
+
cat <<'NODE' > "$_bootstrap"
|
|
230
280
|
const fs = require('fs');
|
|
231
281
|
const path = require('path');
|
|
232
282
|
const {
|
|
@@ -352,7 +402,48 @@ async function main() {
|
|
|
352
402
|
process.once('uncaughtException', onAsyncError);
|
|
353
403
|
process.once('unhandledRejection', onAsyncError);
|
|
354
404
|
Object.defineProperty(process.versions, 'bun', { value: '1.1.8', configurable: true });
|
|
355
|
-
|
|
405
|
+
const _realChild = require('child_process');
|
|
406
|
+
globalThis.Bun = {
|
|
407
|
+
version: '1.1.8',
|
|
408
|
+
stringWidth,
|
|
409
|
+
which: (cmd) => {
|
|
410
|
+
try {
|
|
411
|
+
return _realChild.execFileSync('which', [String(cmd)], { encoding: 'utf8' }).trim() || null;
|
|
412
|
+
} catch { return null; }
|
|
413
|
+
},
|
|
414
|
+
semver: (() => {
|
|
415
|
+
const _cmp = (a, b) => {
|
|
416
|
+
const pa = String(a).replace(/[^0-9.]/g,'').split('.').map(Number);
|
|
417
|
+
const pb = String(b).replace(/[^0-9.]/g,'').split('.').map(Number);
|
|
418
|
+
for (let i = 0; i < 3; i++) { const d = (pa[i]||0)-(pb[i]||0); if (d) return d > 0 ? 1 : -1; }
|
|
419
|
+
return 0;
|
|
420
|
+
};
|
|
421
|
+
const _satisfies = (ver, range) => {
|
|
422
|
+
const s = String(range).trim();
|
|
423
|
+
const m = s.match(/^([><=!]{1,2})\s*([\d]+(?:\.[\d]+){0,2})$/);
|
|
424
|
+
if (m) {
|
|
425
|
+
const op = m[1], c = _cmp(ver, m[2]);
|
|
426
|
+
if (op === '>') return c > 0;
|
|
427
|
+
if (op === '>=') return c >= 0;
|
|
428
|
+
if (op === '<') return c < 0;
|
|
429
|
+
if (op === '<=') return c <= 0;
|
|
430
|
+
if (op === '=' || op === '==') return c === 0;
|
|
431
|
+
if (op === '!=') return c !== 0;
|
|
432
|
+
}
|
|
433
|
+
if (/^[\d]+(?:\.[\d]+){0,2}$/.test(s)) return _cmp(ver, s) === 0;
|
|
434
|
+
return false;
|
|
435
|
+
};
|
|
436
|
+
return {
|
|
437
|
+
order: (a, b) => _cmp(a, b),
|
|
438
|
+
compare: (a, b) => _cmp(a, b),
|
|
439
|
+
satisfies: (ver, range) => _satisfies(ver, range),
|
|
440
|
+
gt: (a, b) => _cmp(a, b) > 0,
|
|
441
|
+
gte: (a, b) => _cmp(a, b) >= 0,
|
|
442
|
+
lt: (a, b) => _cmp(a, b) < 0,
|
|
443
|
+
lte: (a, b) => _cmp(a, b) <= 0,
|
|
444
|
+
};
|
|
445
|
+
})(),
|
|
446
|
+
};
|
|
356
447
|
process.argv = ['node', extractedFile, ...argv];
|
|
357
448
|
process.exit = code => {
|
|
358
449
|
throw new RequestedExit(code);
|
|
@@ -361,7 +452,8 @@ async function main() {
|
|
|
361
452
|
const moduleLike = { exports: {} };
|
|
362
453
|
const maybePromise = fn(moduleLike.exports, fakeRequire, moduleLike, extractedFile, workdir);
|
|
363
454
|
if (maybePromise && typeof maybePromise.then === 'function') await maybePromise;
|
|
364
|
-
|
|
455
|
+
const _waitMs = process.stdin.isTTY ? 1200 : 200;
|
|
456
|
+
await new Promise(resolve => setTimeout(resolve, _waitMs));
|
|
365
457
|
if (asyncErrors.length > 0) throw asyncErrors[0];
|
|
366
458
|
} catch (error) {
|
|
367
459
|
if (error instanceof RequestedExit) {
|
|
@@ -382,7 +474,6 @@ async function main() {
|
|
|
382
474
|
}
|
|
383
475
|
} catch {}
|
|
384
476
|
if (hadGlobalBun) globalThis.Bun = originalGlobalBun;
|
|
385
|
-
else delete globalThis.Bun;
|
|
386
477
|
}
|
|
387
478
|
}
|
|
388
479
|
|
|
@@ -395,4 +486,11 @@ main().catch(error => {
|
|
|
395
486
|
process.exit(1);
|
|
396
487
|
});
|
|
397
488
|
NODE
|
|
489
|
+
export CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC="${CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC:-1}"
|
|
490
|
+
export ENABLE_CLAUDEAI_MCP_SERVERS="${ENABLE_CLAUDEAI_MCP_SERVERS:-0}"
|
|
491
|
+
node "$_bootstrap" "$@"
|
|
492
|
+
_status=$?
|
|
493
|
+
rm -f "$_bootstrap"
|
|
494
|
+
trap - EXIT HUP INT TERM
|
|
495
|
+
exit "$_status"
|
|
398
496
|
fi
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
function parseVersion(v) {
|
|
4
|
+
const str = String(v);
|
|
5
|
+
const dashIdx = str.lastIndexOf('-');
|
|
6
|
+
if (dashIdx !== -1) {
|
|
7
|
+
const base = str.slice(0, dashIdx);
|
|
8
|
+
const suffix = Number(str.slice(dashIdx + 1));
|
|
9
|
+
return { parts: base.split('.').map(Number), suffix: isNaN(suffix) ? 0 : suffix };
|
|
10
|
+
}
|
|
11
|
+
return { parts: str.split('.').map(Number), suffix: 0 };
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
function compareVersions(a, b) {
|
|
15
|
+
const ap = parseVersion(a), bp = parseVersion(b);
|
|
16
|
+
const len = Math.max(ap.parts.length, bp.parts.length);
|
|
17
|
+
for (let i = 0; i < len; i++) {
|
|
18
|
+
const diff = (ap.parts[i] || 0) - (bp.parts[i] || 0);
|
|
19
|
+
if (diff !== 0) return diff;
|
|
20
|
+
}
|
|
21
|
+
return ap.suffix - bp.suffix;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
module.exports = { parseVersion, compareVersions };
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const test = require('node:test');
|
|
4
|
+
const assert = require('node:assert/strict');
|
|
5
|
+
|
|
6
|
+
const { parseVersion, compareVersions } = require('./version-utils');
|
|
7
|
+
|
|
8
|
+
test('parseVersion splits suffix versions', () => {
|
|
9
|
+
assert.deepEqual(parseVersion('2.1.159-2'), {
|
|
10
|
+
parts: [2, 1, 159],
|
|
11
|
+
suffix: 2,
|
|
12
|
+
});
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
test('compareVersions orders suffix versions after the base release', () => {
|
|
16
|
+
assert.equal(compareVersions('2.1.159', '2.1.159-1') < 0, true);
|
|
17
|
+
assert.equal(compareVersions('2.1.159-1', '2.1.159-2') < 0, true);
|
|
18
|
+
assert.equal(compareVersions('2.1.159-2', '2.1.159') > 0, true);
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
test('compareVersions preserves numeric ordering across patch versions', () => {
|
|
22
|
+
assert.equal(compareVersions('2.1.136', '2.1.137') < 0, true);
|
|
23
|
+
assert.equal(compareVersions('2.1.137', '2.1.136') > 0, true);
|
|
24
|
+
assert.equal(compareVersions('2.1.137', '2.1.137'), 0);
|
|
25
|
+
});
|
package/package.json
CHANGED
|
@@ -1,22 +1,28 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bash0816/claude-code",
|
|
3
|
-
"version": "2.1.159-
|
|
4
|
-
"description": "Termux-native Claude Code wrapper with audited native replay",
|
|
3
|
+
"version": "2.1.159-10",
|
|
4
|
+
"description": "Unofficial Termux-native Claude Code wrapper with audited native replay",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"bin": {
|
|
7
7
|
"claude": "bin/claude"
|
|
8
8
|
},
|
|
9
|
-
"scripts": {
|
|
10
|
-
"preinstall": "node lib/preinstall.js",
|
|
11
|
-
"postinstall": "node lib/postinstall.js"
|
|
12
|
-
},
|
|
9
|
+
"scripts": {},
|
|
13
10
|
"files": [
|
|
14
|
-
"bin",
|
|
15
|
-
"lib",
|
|
16
|
-
"config",
|
|
11
|
+
"bin/",
|
|
12
|
+
"lib/",
|
|
13
|
+
"config/",
|
|
17
14
|
"README.md"
|
|
18
15
|
],
|
|
19
16
|
"engines": {
|
|
20
17
|
"node": ">=18"
|
|
18
|
+
},
|
|
19
|
+
"keywords": [
|
|
20
|
+
"claude-code",
|
|
21
|
+
"termux",
|
|
22
|
+
"android",
|
|
23
|
+
"wrapper"
|
|
24
|
+
],
|
|
25
|
+
"publishConfig": {
|
|
26
|
+
"access": "public"
|
|
21
27
|
}
|
|
22
28
|
}
|