Skip to content

Commit 2c79484

Browse files
committed
Add system prompt patches for Claude Code 2.1.47
1 parent 020a6d5 commit 2c79484

File tree

132 files changed

+1950
-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.

132 files changed

+1950
-0
lines changed

system-prompt/2.1.47/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.47"
9+
EXPECTED_HASH="2f9b383151697cb6a4020d34ef18e114697fa03f34153f2a93369271cc116a32"
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: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
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+
}
53+
54+
function extractBunDataFromSection(sectionData) {
55+
// Try u64 header first (Bun >= 1.3.4), then u32
56+
const bunDataSizeU64 = sectionData.length >= 8 ? Number(sectionData.readBigUInt64LE(0)) : 0;
57+
const bunDataSizeU32 = sectionData.readUInt32LE(0);
58+
59+
let headerSize, bunDataSize;
60+
if (sectionData.length >= 8 && 8 + bunDataSizeU64 <= sectionData.length && 8 + bunDataSizeU64 >= sectionData.length - 4096) {
61+
headerSize = 8; bunDataSize = bunDataSizeU64;
62+
} else if (4 + bunDataSizeU32 <= sectionData.length && 4 + bunDataSizeU32 >= sectionData.length - 4096) {
63+
headerSize = 4; bunDataSize = bunDataSizeU32;
64+
} else {
65+
throw new Error("Cannot determine section header format");
66+
}
67+
68+
const bunDataContent = sectionData.subarray(headerSize, headerSize + bunDataSize);
69+
const trailerStart = bunDataContent.length - BUN_TRAILER.length;
70+
const offsetsStart = bunDataContent.length - SIZEOF_OFFSETS - BUN_TRAILER.length;
71+
const offsetsBytes = bunDataContent.subarray(offsetsStart, offsetsStart + SIZEOF_OFFSETS);
72+
73+
return { bunOffsets: parseOffsets(offsetsBytes), bunData: bunDataContent, sectionHeaderSize: headerSize };
74+
}
75+
76+
function extractFromELF(binary) {
77+
if (!binary.hasOverlay) throw new Error("ELF binary has no overlay data");
78+
const overlay = binary.overlay;
79+
const offsetsStart = overlay.length - 8 - BUN_TRAILER.length - SIZEOF_OFFSETS;
80+
const offsetsBytes = overlay.subarray(offsetsStart, overlay.length - 8 - BUN_TRAILER.length);
81+
const bunOffsets = parseOffsets(offsetsBytes);
82+
const tailDataLen = 8 + BUN_TRAILER.length + SIZEOF_OFFSETS;
83+
const dataStart = overlay.length - tailDataLen - Number(bunOffsets.byteCount);
84+
const dataRegion = overlay.subarray(dataStart, overlay.length - tailDataLen);
85+
const trailerBytes = overlay.subarray(overlay.length - 8 - BUN_TRAILER.length, overlay.length - 8);
86+
return { bunOffsets, bunData: Buffer.concat([dataRegion, offsetsBytes, trailerBytes]) };
87+
}
88+
89+
function extractFromMachO(binary) {
90+
const bunSegment = binary.getSegment("__BUN");
91+
if (!bunSegment) throw new Error("__BUN segment not found");
92+
const bunSection = bunSegment.getSection("__bun");
93+
if (!bunSection) throw new Error("__bun section not found");
94+
return extractBunDataFromSection(bunSection.content);
95+
}
96+
97+
function extract(binaryPath) {
98+
LIEF.logging.disable();
99+
const binary = LIEF.parse(binaryPath);
100+
101+
let bunData, bunOffsets;
102+
if (binary.format === "ELF") {
103+
({ bunData, bunOffsets } = extractFromELF(binary));
104+
} else if (binary.format === "MachO") {
105+
({ bunData, bunOffsets } = extractFromMachO(binary));
106+
} else {
107+
throw new Error(`Unsupported format: ${binary.format}`);
108+
}
109+
110+
const modulesListBytes = getStringPointerContent(bunData, bunOffsets.modulesPtr);
111+
const moduleSize = detectModuleSize(modulesListBytes.length);
112+
const modulesCount = Math.floor(modulesListBytes.length / moduleSize);
113+
114+
for (let i = 0; i < modulesCount; i++) {
115+
const module = parseModule(modulesListBytes, i * moduleSize);
116+
const moduleName = getStringPointerContent(bunData, module.name).toString("utf-8");
117+
if (isClaudeModule(moduleName)) {
118+
return getStringPointerContent(bunData, module.contents);
119+
}
120+
}
121+
throw new Error("Claude module not found");
122+
}
123+
124+
// Main
125+
const binaryPath = process.argv[2] || `${process.env.HOME}/.local/share/claude/versions/2.1.17`;
126+
const outputPath = process.argv[3] || "/tmp/native-cli.js";
127+
128+
try {
129+
console.log(`Extracting from: ${binaryPath}`);
130+
const cliJs = extract(binaryPath);
131+
fs.writeFileSync(outputPath, cliJs);
132+
console.log(`Extracted to: ${outputPath} (${cliJs.length} bytes)`);
133+
} catch (err) {
134+
console.error("Error:", err.message);
135+
process.exit(1);
136+
}

0 commit comments

Comments
 (0)