Skip to content

Commit e1d5f79

Browse files
committed
Add system prompt patches for Claude Code 2.1.71
1 parent 82de630 commit e1d5f79

File tree

120 files changed

+1789
-0
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

120 files changed

+1789
-0
lines changed

system-prompt/2.1.71/backup-cli.sh

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
#!/bin/bash
2+
# Backup script for Claude Code CLI bundle
3+
# Only backs up if the file matches the known original hash
4+
5+
set -e
6+
7+
# Known original - update these when Claude Code updates
8+
EXPECTED_VERSION="2.1.71"
9+
EXPECTED_HASH="d530df70cc88313ae4992bb2ede73c0448ab449840766e0a3224aea85fbc7995"
10+
11+
# Find claude CLI using which and common locations
12+
get_claude_cli() {
13+
# Method 1: Use 'which claude' and follow symlinks
14+
local claude_bin=$(which claude 2>/dev/null)
15+
if [ -n "$claude_bin" ]; then
16+
local real_path=$(realpath "$claude_bin")
17+
local cli_path=$(dirname "$real_path")/cli.js
18+
if [ -f "$cli_path" ]; then
19+
echo "$cli_path"
20+
return 0
21+
fi
22+
fi
23+
24+
# Method 2: Check common npm global locations
25+
for loc in "/opt/homebrew/lib/node_modules/@anthropic-ai/claude-code/cli.js" \
26+
"/usr/local/lib/node_modules/@anthropic-ai/claude-code/cli.js"; do
27+
if [ -f "$loc" ]; then
28+
echo "$loc"
29+
return 0
30+
fi
31+
done
32+
33+
# Method 3: Check local install location
34+
local claude_launcher="$HOME/.claude/local/claude"
35+
if [ -f "$claude_launcher" ]; then
36+
local bin_path=$(grep 'exec' "$claude_launcher" | head -1 | sed 's/.*exec "\([^"]*\)".*/\1/')
37+
[ -n "$bin_path" ] && realpath "$bin_path"
38+
return 0
39+
fi
40+
41+
return 1
42+
}
43+
44+
# Allow custom path for testing, otherwise find it dynamically
45+
if [ -n "$1" ]; then
46+
CLI_PATH="$1"
47+
else
48+
CLI_PATH=$(get_claude_cli)
49+
if [ -z "$CLI_PATH" ]; then
50+
echo "Error: Could not find claude CLI. Is claude installed?"
51+
exit 1
52+
fi
53+
fi
54+
BACKUP_PATH="$CLI_PATH.backup"
55+
56+
# Check if backup already exists
57+
if [ -f "$BACKUP_PATH" ]; then
58+
echo "Error: Backup already exists at $BACKUP_PATH"
59+
echo "Delete it manually if you want to create a new backup."
60+
exit 1
61+
fi
62+
63+
# Check if cli.js exists
64+
if [ ! -f "$CLI_PATH" ]; then
65+
echo "Error: CLI not found at $CLI_PATH"
66+
exit 1
67+
fi
68+
69+
# Compute current hash
70+
CURRENT_HASH=$(shasum -a 256 "$CLI_PATH" | cut -d' ' -f1)
71+
72+
# Compare hashes
73+
if [ "$CURRENT_HASH" != "$EXPECTED_HASH" ]; then
74+
echo "Error: Hash mismatch - file may be modified or different version"
75+
echo ""
76+
echo "Expected (v$EXPECTED_VERSION): $EXPECTED_HASH"
77+
echo "Current: $CURRENT_HASH"
78+
echo ""
79+
echo "If Claude Code was updated, update EXPECTED_VERSION and EXPECTED_HASH in this script."
80+
exit 1
81+
fi
82+
83+
# Create backup
84+
cp "$CLI_PATH" "$BACKUP_PATH"
85+
echo "Backup created: $BACKUP_PATH"
86+
echo "Version: $EXPECTED_VERSION"
87+
echo "Hash: $EXPECTED_HASH"
Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
#!/usr/bin/env node
2+
/**
3+
* Extract cli.js from Claude Code native binary
4+
* Supports ELF (Linux) and Mach-O (macOS) formats
5+
*/
6+
7+
const LIEF = require("node-lief");
8+
const fs = require("fs");
9+
10+
const BUN_TRAILER = Buffer.from("\n---- Bun! ----\n");
11+
const SIZEOF_OFFSETS = 32;
12+
const SIZEOF_STRING_POINTER = 8;
13+
const SIZEOF_MODULE_V1 = 4 * SIZEOF_STRING_POINTER + 4; // 36 bytes (Bun < 1.3.9)
14+
const SIZEOF_MODULE_V2 = 4 * SIZEOF_STRING_POINTER + 4 + 16; // 52 bytes (Bun >= 1.3.9, added extra field)
15+
16+
function detectModuleSize(modulesListLength) {
17+
if (modulesListLength % SIZEOF_MODULE_V2 === 0) return SIZEOF_MODULE_V2;
18+
if (modulesListLength % SIZEOF_MODULE_V1 === 0) return SIZEOF_MODULE_V1;
19+
return SIZEOF_MODULE_V1; // fallback
20+
}
21+
22+
function parseStringPointer(buffer, offset) {
23+
return { offset: buffer.readUInt32LE(offset), length: buffer.readUInt32LE(offset + 4) };
24+
}
25+
26+
function parseOffsets(buffer) {
27+
let pos = 0;
28+
const byteCount = buffer.readBigUInt64LE(pos); pos += 8;
29+
const modulesPtr = parseStringPointer(buffer, pos); pos += 8;
30+
const entryPointId = buffer.readUInt32LE(pos); pos += 4;
31+
const compileExecArgvPtr = parseStringPointer(buffer, pos);
32+
return { byteCount, modulesPtr, entryPointId, compileExecArgvPtr };
33+
}
34+
35+
function getStringPointerContent(buffer, sp) {
36+
return buffer.subarray(sp.offset, sp.offset + sp.length);
37+
}
38+
39+
function parseModule(buffer, offset) {
40+
let pos = offset;
41+
return {
42+
name: parseStringPointer(buffer, pos), contents: parseStringPointer(buffer, pos + 8),
43+
sourcemap: parseStringPointer(buffer, pos + 16), bytecode: parseStringPointer(buffer, pos + 24),
44+
encoding: buffer.readUInt8(pos + 32), loader: buffer.readUInt8(pos + 33),
45+
moduleFormat: buffer.readUInt8(pos + 34), side: buffer.readUInt8(pos + 35)
46+
};
47+
}
48+
49+
function isClaudeModule(name) {
50+
return name.endsWith("/claude") || name === "claude" ||
51+
name.endsWith("/claude.exe") || name === "claude.exe" ||
52+
name.endsWith("/cli.js");
53+
}
54+
55+
function extractBunDataFromSection(sectionData) {
56+
// Try u64 header first (Bun >= 1.3.4), then u32
57+
const bunDataSizeU64 = sectionData.length >= 8 ? Number(sectionData.readBigUInt64LE(0)) : 0;
58+
const bunDataSizeU32 = sectionData.readUInt32LE(0);
59+
60+
let headerSize, bunDataSize;
61+
if (sectionData.length >= 8 && 8 + bunDataSizeU64 <= sectionData.length && 8 + bunDataSizeU64 >= sectionData.length - 4096) {
62+
headerSize = 8; bunDataSize = bunDataSizeU64;
63+
} else if (4 + bunDataSizeU32 <= sectionData.length && 4 + bunDataSizeU32 >= sectionData.length - 4096) {
64+
headerSize = 4; bunDataSize = bunDataSizeU32;
65+
} else {
66+
throw new Error("Cannot determine section header format");
67+
}
68+
69+
const bunDataContent = sectionData.subarray(headerSize, headerSize + bunDataSize);
70+
const trailerStart = bunDataContent.length - BUN_TRAILER.length;
71+
const offsetsStart = bunDataContent.length - SIZEOF_OFFSETS - BUN_TRAILER.length;
72+
const offsetsBytes = bunDataContent.subarray(offsetsStart, offsetsStart + SIZEOF_OFFSETS);
73+
74+
return { bunOffsets: parseOffsets(offsetsBytes), bunData: bunDataContent, sectionHeaderSize: headerSize };
75+
}
76+
77+
function extractFromELF(binary) {
78+
if (!binary.hasOverlay) throw new Error("ELF binary has no overlay data");
79+
const overlay = binary.overlay;
80+
const offsetsStart = overlay.length - 8 - BUN_TRAILER.length - SIZEOF_OFFSETS;
81+
const offsetsBytes = overlay.subarray(offsetsStart, overlay.length - 8 - BUN_TRAILER.length);
82+
const bunOffsets = parseOffsets(offsetsBytes);
83+
const tailDataLen = 8 + BUN_TRAILER.length + SIZEOF_OFFSETS;
84+
const dataStart = overlay.length - tailDataLen - Number(bunOffsets.byteCount);
85+
const dataRegion = overlay.subarray(dataStart, overlay.length - tailDataLen);
86+
const trailerBytes = overlay.subarray(overlay.length - 8 - BUN_TRAILER.length, overlay.length - 8);
87+
return { bunOffsets, bunData: Buffer.concat([dataRegion, offsetsBytes, trailerBytes]) };
88+
}
89+
90+
function extractFromMachO(binary) {
91+
const bunSegment = binary.getSegment("__BUN");
92+
if (!bunSegment) throw new Error("__BUN segment not found");
93+
const bunSection = bunSegment.getSection("__bun");
94+
if (!bunSection) throw new Error("__bun section not found");
95+
return extractBunDataFromSection(bunSection.content);
96+
}
97+
98+
function extract(binaryPath) {
99+
LIEF.logging.disable();
100+
const binary = LIEF.parse(binaryPath);
101+
102+
let bunData, bunOffsets;
103+
if (binary.format === "ELF") {
104+
({ bunData, bunOffsets } = extractFromELF(binary));
105+
} else if (binary.format === "MachO") {
106+
({ bunData, bunOffsets } = extractFromMachO(binary));
107+
} else {
108+
throw new Error(`Unsupported format: ${binary.format}`);
109+
}
110+
111+
const modulesListBytes = getStringPointerContent(bunData, bunOffsets.modulesPtr);
112+
const moduleSize = detectModuleSize(modulesListBytes.length);
113+
const modulesCount = Math.floor(modulesListBytes.length / moduleSize);
114+
115+
for (let i = 0; i < modulesCount; i++) {
116+
const module = parseModule(modulesListBytes, i * moduleSize);
117+
const moduleName = getStringPointerContent(bunData, module.name).toString("utf-8");
118+
if (isClaudeModule(moduleName)) {
119+
return getStringPointerContent(bunData, module.contents);
120+
}
121+
}
122+
throw new Error("Claude module not found");
123+
}
124+
125+
// Main
126+
const binaryPath = process.argv[2] || `${process.env.HOME}/.local/share/claude/versions/2.1.17`;
127+
const outputPath = process.argv[3] || "/tmp/native-cli.js";
128+
129+
try {
130+
console.log(`Extracting from: ${binaryPath}`);
131+
const cliJs = extract(binaryPath);
132+
fs.writeFileSync(outputPath, cliJs);
133+
console.log(`Extracted to: ${outputPath} (${cliJs.length} bytes)`);
134+
} catch (err) {
135+
console.error("Error:", err.message);
136+
process.exit(1);
137+
}

0 commit comments

Comments
 (0)