tweakcc-fixed 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 +71 -0
- package/dist/config-CSt_7NDd.mjs +668 -0
- package/dist/content-B58roxpl.mjs +29 -0
- package/dist/index.d.mts +1 -0
- package/dist/index.mjs +29 -0
- package/dist/lib/index.d.mts +341 -0
- package/dist/lib/index.mjs +1 -0
- package/dist/nativeInstallation-KBHJW1y7.mjs +4 -0
- package/package.json +112 -0
|
@@ -0,0 +1,341 @@
|
|
|
1
|
+
//#region src/types.d.ts
|
|
2
|
+
interface Theme {
|
|
3
|
+
name: string;
|
|
4
|
+
id: string;
|
|
5
|
+
colors: {
|
|
6
|
+
autoAccept: string;
|
|
7
|
+
bashBorder: string;
|
|
8
|
+
claude: string;
|
|
9
|
+
claudeShimmer: string;
|
|
10
|
+
claudeBlue_FOR_SYSTEM_SPINNER: string;
|
|
11
|
+
claudeBlueShimmer_FOR_SYSTEM_SPINNER: string;
|
|
12
|
+
permission: string;
|
|
13
|
+
permissionShimmer: string;
|
|
14
|
+
planMode: string;
|
|
15
|
+
ide: string;
|
|
16
|
+
promptBorder: string;
|
|
17
|
+
promptBorderShimmer: string;
|
|
18
|
+
text: string;
|
|
19
|
+
inverseText: string;
|
|
20
|
+
inactive: string;
|
|
21
|
+
subtle: string;
|
|
22
|
+
suggestion: string;
|
|
23
|
+
remember: string;
|
|
24
|
+
background: string;
|
|
25
|
+
success: string;
|
|
26
|
+
error: string;
|
|
27
|
+
warning: string;
|
|
28
|
+
warningShimmer: string;
|
|
29
|
+
diffAdded: string;
|
|
30
|
+
diffRemoved: string;
|
|
31
|
+
diffAddedDimmed: string;
|
|
32
|
+
diffRemovedDimmed: string;
|
|
33
|
+
diffAddedWord: string;
|
|
34
|
+
diffRemovedWord: string;
|
|
35
|
+
diffAddedWordDimmed: string;
|
|
36
|
+
diffRemovedWordDimmed: string;
|
|
37
|
+
red_FOR_SUBAGENTS_ONLY: string;
|
|
38
|
+
blue_FOR_SUBAGENTS_ONLY: string;
|
|
39
|
+
green_FOR_SUBAGENTS_ONLY: string;
|
|
40
|
+
yellow_FOR_SUBAGENTS_ONLY: string;
|
|
41
|
+
purple_FOR_SUBAGENTS_ONLY: string;
|
|
42
|
+
orange_FOR_SUBAGENTS_ONLY: string;
|
|
43
|
+
pink_FOR_SUBAGENTS_ONLY: string;
|
|
44
|
+
cyan_FOR_SUBAGENTS_ONLY: string;
|
|
45
|
+
professionalBlue: string;
|
|
46
|
+
rainbow_red: string;
|
|
47
|
+
rainbow_orange: string;
|
|
48
|
+
rainbow_yellow: string;
|
|
49
|
+
rainbow_green: string;
|
|
50
|
+
rainbow_blue: string;
|
|
51
|
+
rainbow_indigo: string;
|
|
52
|
+
rainbow_violet: string;
|
|
53
|
+
rainbow_red_shimmer: string;
|
|
54
|
+
rainbow_orange_shimmer: string;
|
|
55
|
+
rainbow_yellow_shimmer: string;
|
|
56
|
+
rainbow_green_shimmer: string;
|
|
57
|
+
rainbow_blue_shimmer: string;
|
|
58
|
+
rainbow_indigo_shimmer: string;
|
|
59
|
+
rainbow_violet_shimmer: string;
|
|
60
|
+
clawd_body: string;
|
|
61
|
+
clawd_background: string;
|
|
62
|
+
userMessageBackground: string;
|
|
63
|
+
bashMessageBackgroundColor: string;
|
|
64
|
+
memoryBackgroundColor: string;
|
|
65
|
+
rate_limit_fill: string;
|
|
66
|
+
rate_limit_empty: string;
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
interface ThinkingVerbsConfig {
|
|
70
|
+
format: string;
|
|
71
|
+
verbs: string[];
|
|
72
|
+
}
|
|
73
|
+
interface ThinkingStyleConfig {
|
|
74
|
+
reverseMirror: boolean;
|
|
75
|
+
updateInterval: number;
|
|
76
|
+
phases: string[];
|
|
77
|
+
}
|
|
78
|
+
interface UserMessageDisplayConfig {
|
|
79
|
+
format: string;
|
|
80
|
+
styling: string[];
|
|
81
|
+
foregroundColor: string | 'default';
|
|
82
|
+
backgroundColor: string | 'default' | null;
|
|
83
|
+
borderStyle: 'none' | 'single' | 'double' | 'round' | 'bold' | 'singleDouble' | 'doubleSingle' | 'classic' | 'topBottomSingle' | 'topBottomDouble' | 'topBottomBold';
|
|
84
|
+
borderColor: string;
|
|
85
|
+
paddingX: number;
|
|
86
|
+
paddingY: number;
|
|
87
|
+
fitBoxToContent: boolean;
|
|
88
|
+
}
|
|
89
|
+
interface InputBoxConfig {
|
|
90
|
+
removeBorder: boolean;
|
|
91
|
+
}
|
|
92
|
+
type TableFormat = 'default' | 'ascii' | 'clean' | 'clean-top-bottom';
|
|
93
|
+
interface MiscConfig {
|
|
94
|
+
showTweakccVersion: boolean;
|
|
95
|
+
showPatchesApplied: boolean;
|
|
96
|
+
expandThinkingBlocks: boolean;
|
|
97
|
+
enableConversationTitle: boolean;
|
|
98
|
+
hideStartupBanner: boolean;
|
|
99
|
+
hideCtrlGToEdit: boolean;
|
|
100
|
+
hideStartupClawd: boolean;
|
|
101
|
+
increaseFileReadLimit: boolean;
|
|
102
|
+
suppressLineNumbers: boolean;
|
|
103
|
+
suppressRateLimitOptions: boolean;
|
|
104
|
+
mcpConnectionNonBlocking: boolean;
|
|
105
|
+
mcpServerBatchSize: number | null;
|
|
106
|
+
statuslineThrottleMs: number | null;
|
|
107
|
+
statuslineUseFixedInterval: boolean;
|
|
108
|
+
tableFormat: TableFormat;
|
|
109
|
+
enableSwarmMode: boolean;
|
|
110
|
+
enableSessionMemory: boolean;
|
|
111
|
+
enableRememberSkill: boolean;
|
|
112
|
+
tokenCountRounding: number | null;
|
|
113
|
+
autoAcceptPlanMode: boolean;
|
|
114
|
+
allowBypassPermissionsInSudo: boolean | null;
|
|
115
|
+
suppressNativeInstallerWarning: boolean;
|
|
116
|
+
filterScrollEscapeSequences: boolean;
|
|
117
|
+
enableWorktreeMode: boolean;
|
|
118
|
+
allowCustomAgentModels: boolean;
|
|
119
|
+
enableContextLimitOverride: boolean;
|
|
120
|
+
enableModelCustomizations: boolean;
|
|
121
|
+
enableVoiceMode: boolean;
|
|
122
|
+
enableVoiceConciseOutput: boolean;
|
|
123
|
+
enableChannelsMode: boolean;
|
|
124
|
+
}
|
|
125
|
+
interface InputPatternHighlighter {
|
|
126
|
+
name: string;
|
|
127
|
+
regex: string;
|
|
128
|
+
regexFlags: string;
|
|
129
|
+
format: string;
|
|
130
|
+
styling: string[];
|
|
131
|
+
foregroundColor: string | null;
|
|
132
|
+
backgroundColor: string | null;
|
|
133
|
+
enabled: boolean;
|
|
134
|
+
}
|
|
135
|
+
interface Toolset {
|
|
136
|
+
name: string;
|
|
137
|
+
allowedTools: string[] | '*';
|
|
138
|
+
}
|
|
139
|
+
interface SubagentModelsConfig {
|
|
140
|
+
plan: string | null;
|
|
141
|
+
explore: string | null;
|
|
142
|
+
generalPurpose: string | null;
|
|
143
|
+
}
|
|
144
|
+
interface Settings {
|
|
145
|
+
themes: Theme[];
|
|
146
|
+
thinkingVerbs: ThinkingVerbsConfig;
|
|
147
|
+
thinkingStyle: ThinkingStyleConfig;
|
|
148
|
+
userMessageDisplay: UserMessageDisplayConfig;
|
|
149
|
+
inputBox: InputBoxConfig;
|
|
150
|
+
misc: MiscConfig;
|
|
151
|
+
toolsets: Toolset[];
|
|
152
|
+
defaultToolset: string | null;
|
|
153
|
+
planModeToolset: string | null;
|
|
154
|
+
subagentModels: SubagentModelsConfig;
|
|
155
|
+
inputPatternHighlighters: InputPatternHighlighter[];
|
|
156
|
+
inputPatternHighlightersTestText: string;
|
|
157
|
+
claudeMdAltNames: string[] | null;
|
|
158
|
+
}
|
|
159
|
+
interface RemoteConfig {
|
|
160
|
+
sourceUrl: string;
|
|
161
|
+
dateFetched: string;
|
|
162
|
+
settings: Partial<Settings>;
|
|
163
|
+
}
|
|
164
|
+
interface TweakccConfig {
|
|
165
|
+
ccVersion: string;
|
|
166
|
+
ccInstallationDir?: string | null;
|
|
167
|
+
ccInstallationPath?: string | null;
|
|
168
|
+
lastModified: string;
|
|
169
|
+
changesApplied: boolean;
|
|
170
|
+
settings: Settings;
|
|
171
|
+
hidePiebaldAnnouncement?: boolean;
|
|
172
|
+
remoteConfig?: RemoteConfig;
|
|
173
|
+
}
|
|
174
|
+
//#endregion
|
|
175
|
+
//#region src/lib/types.d.ts
|
|
176
|
+
/**
|
|
177
|
+
* tweakcc Library Types
|
|
178
|
+
*
|
|
179
|
+
* These are the public types exposed by the library API.
|
|
180
|
+
*/
|
|
181
|
+
/**
|
|
182
|
+
* A Claude Code installation detected on the system.
|
|
183
|
+
*/
|
|
184
|
+
interface Installation {
|
|
185
|
+
/** Path to cli.js (npm) or native binary */
|
|
186
|
+
path: string;
|
|
187
|
+
/** Claude Code version, e.g., "2.1.0" */
|
|
188
|
+
version: string;
|
|
189
|
+
/** Type of installation */
|
|
190
|
+
kind: 'npm' | 'native';
|
|
191
|
+
}
|
|
192
|
+
//#endregion
|
|
193
|
+
//#region src/lib/detection.d.ts
|
|
194
|
+
/**
|
|
195
|
+
* Find all Claude Code installations on the system by searching in PATH and
|
|
196
|
+
* common install locations.
|
|
197
|
+
*/
|
|
198
|
+
declare function findAllInstallations(): Promise<Installation[]>;
|
|
199
|
+
/**
|
|
200
|
+
* Options for tryDetectInstallation()
|
|
201
|
+
*/
|
|
202
|
+
interface DetectInstallationOptions {
|
|
203
|
+
/** Explicit path to Claude Code - skips auto-detection */
|
|
204
|
+
path?: string;
|
|
205
|
+
/** Show interactive picker UI if multiple installations found (default: false) */
|
|
206
|
+
interactive?: boolean;
|
|
207
|
+
}
|
|
208
|
+
/**
|
|
209
|
+
* Attempts to detect the user's preferred Claude Code installation. Detection procedure:
|
|
210
|
+
* 0. options.path
|
|
211
|
+
* 1. Uses $TWEAKCC_CC_INSTALLATION_PATH if set.
|
|
212
|
+
* 2. Uses ccInstallationPath in tweakcc config.
|
|
213
|
+
* 3. Discovers installation from `claude` in PATH
|
|
214
|
+
* 4. Looks in hard-coded search paths:
|
|
215
|
+
* a. If the search yields one installation, uses it
|
|
216
|
+
* b. If it yields multiple and options.interactive is true, display a picker
|
|
217
|
+
* via showInteractiveInstallationPicker().
|
|
218
|
+
* @returns The selected installation.
|
|
219
|
+
* @throws If user cancels via Esc.
|
|
220
|
+
*/
|
|
221
|
+
declare function tryDetectInstallation(options?: DetectInstallationOptions): Promise<Installation>;
|
|
222
|
+
/**
|
|
223
|
+
* Prompts the user to select one of the specified Claude Code installations
|
|
224
|
+
* interactively using the same UI tweakcc uses, powered by [Ink + React](https://github.com/vadimdemedes/ink).
|
|
225
|
+
*/
|
|
226
|
+
declare function showInteractiveInstallationPicker(candidates: Installation[]): Promise<Installation | null>;
|
|
227
|
+
//#endregion
|
|
228
|
+
//#region src/lib/content.d.ts
|
|
229
|
+
/**
|
|
230
|
+
* Read Claude Code's JavaScript content.
|
|
231
|
+
*
|
|
232
|
+
* - npm installs: reads cli.js directly
|
|
233
|
+
* - native installs: extracts embedded JS from binary
|
|
234
|
+
*
|
|
235
|
+
* @param installation - The installation to read from
|
|
236
|
+
* @returns The JavaScript content as a string
|
|
237
|
+
*/
|
|
238
|
+
declare function readContent(installation: Installation): Promise<{
|
|
239
|
+
content: string;
|
|
240
|
+
clearBytecode: boolean;
|
|
241
|
+
}>;
|
|
242
|
+
/**
|
|
243
|
+
* Write modified JavaScript content back to Claude Code.
|
|
244
|
+
*
|
|
245
|
+
* - npm installs: writes to cli.js (handles permissions, hard links)
|
|
246
|
+
* - native installs: repacks JS into binary
|
|
247
|
+
*
|
|
248
|
+
* @param installation - The installation to write to
|
|
249
|
+
* @param content - The modified JavaScript content
|
|
250
|
+
*/
|
|
251
|
+
declare function writeContent(installation: Installation, content: string, clearBytecode: boolean): Promise<void>;
|
|
252
|
+
//#endregion
|
|
253
|
+
//#region src/lib/backup.d.ts
|
|
254
|
+
/**
|
|
255
|
+
* Backup & Restore Utilities
|
|
256
|
+
*
|
|
257
|
+
* Generic file backup/restore with proper handling of permissions and hard links.
|
|
258
|
+
* These are low-level utilities - the caller manages where backups are stored.
|
|
259
|
+
*/
|
|
260
|
+
/**
|
|
261
|
+
* Backup a file to a specified location.
|
|
262
|
+
*
|
|
263
|
+
* Creates parent directories if needed.
|
|
264
|
+
* Preserves the original file - this is a copy operation.
|
|
265
|
+
*
|
|
266
|
+
* @param sourcePath - Path to the file to backup
|
|
267
|
+
* @param backupPath - Where to store the backup
|
|
268
|
+
*/
|
|
269
|
+
declare function backupFile(sourcePath: string, backupPath: string): Promise<void>;
|
|
270
|
+
/**
|
|
271
|
+
* Restore a file from a backup.
|
|
272
|
+
*
|
|
273
|
+
* Handles:
|
|
274
|
+
* - Breaking hard links (common with pnpm installations)
|
|
275
|
+
* - Preserving file permissions
|
|
276
|
+
*
|
|
277
|
+
* @param backupPath - Path to the backup file
|
|
278
|
+
* @param targetPath - Where to restore the file
|
|
279
|
+
* @throws If backup file doesn't exist
|
|
280
|
+
*/
|
|
281
|
+
declare function restoreBackup(backupPath: string, targetPath: string): Promise<void>;
|
|
282
|
+
//#endregion
|
|
283
|
+
//#region src/lib/config.d.ts
|
|
284
|
+
/**
|
|
285
|
+
* Get tweakcc's config directory path.
|
|
286
|
+
*
|
|
287
|
+
* Respects TWEAKCC_CONFIG_DIR environment variable.
|
|
288
|
+
* Falls back to ~/.tweakcc, ~/.claude/tweakcc, or $XDG_CONFIG_HOME/tweakcc.
|
|
289
|
+
*
|
|
290
|
+
* @returns Absolute path to config directory
|
|
291
|
+
*/
|
|
292
|
+
declare function getTweakccConfigDir(): string;
|
|
293
|
+
/**
|
|
294
|
+
* Get tweakcc's config file path.
|
|
295
|
+
*/
|
|
296
|
+
declare function getTweakccConfigPath(): string;
|
|
297
|
+
/**
|
|
298
|
+
* Get tweakcc's system prompts directory.
|
|
299
|
+
*
|
|
300
|
+
* This is where tweakcc stores editable markdown files for system prompts.
|
|
301
|
+
*/
|
|
302
|
+
declare function getTweakccSystemPromptsDir(): string;
|
|
303
|
+
/**
|
|
304
|
+
* Read tweakcc's config file.
|
|
305
|
+
*/
|
|
306
|
+
declare function readTweakccConfig(): Promise<TweakccConfig>;
|
|
307
|
+
//#endregion
|
|
308
|
+
//#region src/lib/index.d.ts
|
|
309
|
+
/**
|
|
310
|
+
* Helper utilities for writing patches against minified code.
|
|
311
|
+
*
|
|
312
|
+
* Includes functions to find minified variable names and utilities for
|
|
313
|
+
* performing replacements with diff output.
|
|
314
|
+
*
|
|
315
|
+
* @example
|
|
316
|
+
* ```typescript
|
|
317
|
+
* const reactVar = helpers.getReactVar(content);
|
|
318
|
+
* if (reactVar) {
|
|
319
|
+
* content = content.replace(
|
|
320
|
+
* new RegExp(`${reactVar}\\.createElement`),
|
|
321
|
+
* // ...
|
|
322
|
+
* );
|
|
323
|
+
* }
|
|
324
|
+
*
|
|
325
|
+
* // Clear caches when processing multiple files
|
|
326
|
+
* helpers.clearCaches();
|
|
327
|
+
* ```
|
|
328
|
+
*/
|
|
329
|
+
declare const helpers: {
|
|
330
|
+
findChalkVar: (fileContents: string) => string | undefined;
|
|
331
|
+
getModuleLoaderFunction: (fileContents: string) => string | undefined;
|
|
332
|
+
getReactVar: (fileContents: string) => string | undefined;
|
|
333
|
+
getRequireFuncName: (fileContents: string) => string;
|
|
334
|
+
findTextComponent: (fileContents: string) => string | undefined;
|
|
335
|
+
findBoxComponent: (fileContents: string) => string | undefined;
|
|
336
|
+
clearCaches: () => void;
|
|
337
|
+
globalReplace: (content: string, pattern: RegExp, replacement: string | ((substring: string, ...args: unknown[]) => string)) => string;
|
|
338
|
+
showDiff: (oldFileContents: string, newFileContents: string, injectedText: string, startIndex: number, endIndex: number, numContextChars?: number) => void;
|
|
339
|
+
};
|
|
340
|
+
//#endregion
|
|
341
|
+
export { type DetectInstallationOptions, type Installation, type Settings, type TweakccConfig, backupFile, findAllInstallations, getTweakccConfigDir, getTweakccConfigPath, getTweakccSystemPromptsDir, helpers, readContent, readTweakccConfig, restoreBackup, showInteractiveInstallationPicker, tryDetectInstallation, writeContent };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{B as e,D as t,F as n,I as r,L as i,N as a,P as o,R as s,V as c,a as l,c as u,m as d,r as f,s as p,z as m}from"../config-CSt_7NDd.mjs";import{a as h,i as g,n as _,r as v,t as y}from"../content-B58roxpl.mjs";import*as b from"node:fs/promises";import*as x from"node:path";async function S(e,t){let n=x.dirname(t);await b.mkdir(n,{recursive:!0}),await b.copyFile(e,t)}async function C(e,n){if(!await d(e))throw Error(`Backup file does not exist: ${e}`);await t(n,await b.readFile(e),`restore`)}function w(){return p()}function T(){return f}function E(){return l}async function D(){return await u()}const O={findChalkVar:n,getModuleLoaderFunction:i,getReactVar:s,getRequireFuncName:m,findTextComponent:r,findBoxComponent:o,clearCaches:a,globalReplace:e,showDiff:c};export{S as backupFile,v as findAllInstallations,w as getTweakccConfigDir,T as getTweakccConfigPath,E as getTweakccSystemPromptsDir,O as helpers,y as readContent,D as readTweakccConfig,C as restoreBackup,g as showInteractiveInstallationPicker,h as tryDetectInstallation,_ as writeContent};
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import{S as e,f as t}from"./config-CSt_7NDd.mjs";import n from"node:os";import r from"node:fs";import i from"node:path";import{execFileSync as a,execSync as o}from"node:child_process";import s from"node-lief";function c(e){try{if(r.statSync(e).size>2e5)return null;s.logging.disable();let n=s.parse(e);if(!n.symbols().some(e=>{let t=e.name;return t===`execv`||t===`_execv`}))return t(`resolveNixBinaryWrapper: no execv import found, not a Nix wrapper`),null;t(`resolveNixBinaryWrapper: execv import found, checking for Nix wrapper DOCSTRING`);let i=null;if(n.format===`ELF`){let e=n.sections().find(e=>e.name===`.rodata`);e&&(i=e.content)}else if(n.format===`MachO`){let e=n.getSegment(`__TEXT`);if(e){let t=e.getSection(`__cstring`);t&&(i=t.content)}}if(!i||i.length===0)return t(`resolveNixBinaryWrapper: could not read string section`),null;let a=i.toString(`utf-8`),o=a.match(/makeCWrapper\s+'(\/nix\/store\/[^']+)'/);if(o){let e=o[1];return t(`resolveNixBinaryWrapper: found wrapped executable via DOCSTRING: ${e}`),e}let c=a.match(/makeCWrapper\s+(\/nix\/store\/\S+)/);if(c){let e=c[1];return t(`resolveNixBinaryWrapper: found wrapped executable via unquoted DOCSTRING: ${e}`),e}let l=a.match(/\/nix\/store\/[^\0\n\r]+/g);if(l){for(let e of l)if(e.includes(`/bin/`))return t(`resolveNixBinaryWrapper: found wrapped executable via /bin/ heuristic: ${e}`),e}return t(`resolveNixBinaryWrapper: has execv but no Nix store paths found`),null}catch(e){return t(`resolveNixBinaryWrapper: error during detection:`,e),null}}const l=Buffer.from(`
|
|
2
|
+
---- Bun! ----
|
|
3
|
+
`);function u(e,t){return e.subarray(t.offset,t.offset+t.length)}function d(e,t){return{offset:e.readUInt32LE(t),length:e.readUInt32LE(t+4)}}function f(e){return e.endsWith(`/claude`)||e===`claude`||e.endsWith(`/claude.exe`)||e===`claude.exe`||e.endsWith(`/src/entrypoints/cli.js`)||e===`src/entrypoints/cli.js`}function p(e){let n=e%52==0,r=e%36==0;return n&&!r?52:r&&!n?36:n&&r?(t(`detectModuleStructSize: Ambiguous module list length ${e}, assuming new format`),52):(t(`detectModuleStructSize: Module list length ${e} doesn't cleanly divide by either struct size, assuming new format`),52)}function m(e,t,n,r){let i=u(e,t.modulesPtr),a=Math.floor(i.length/n);for(let t=0;t<a;t++){let a=g(i,t*n,n),o=r(a,u(e,a.name).toString(`utf-8`),t);if(o!==void 0)return o}}function h(e){let t=0,n=e.readBigUInt64LE(t);t+=8;let r=d(e,t);t+=8;let i=e.readUInt32LE(t);t+=4;let a=d(e,t);return t+=8,{byteCount:n,modulesPtr:r,entryPointId:i,compileExecArgvPtr:a,flags:e.readUInt32LE(t)}}function g(e,t,n){let r=t,i=d(e,r);r+=8;let a=d(e,r);r+=8;let o=d(e,r);r+=8;let s=d(e,r);r+=8;let c,l;n===52?(c=d(e,r),r+=8,l=d(e,r),r+=8):(c={offset:0,length:0},l={offset:0,length:0});let u=e.readUInt8(r);r+=1;let f=e.readUInt8(r);r+=1;let p=e.readUInt8(r);r+=1;let m=e.readUInt8(r);return{name:i,contents:a,sourcemap:o,bytecode:s,moduleInfo:c,bytecodeOriginPath:l,encoding:u,loader:f,moduleFormat:p,side:m}}function _(e){if(e.length<32+l.length)throw Error(`BUN data is too small to contain trailer and offsets`);let n=e.length-l.length,r=e.subarray(n);if(t(`parseBunDataBlob: Expected trailer: ${l.toString(`hex`)}`),t(`parseBunDataBlob: Got trailer: ${r.toString(`hex`)}`),!r.equals(l))throw t(`Expected: ${l.toString(`hex`)}`),t(`Got: ${r.toString(`hex`)}`),Error(`BUN trailer bytes do not match trailer`);let i=e.length-32-l.length,a=h(e.subarray(i,i+32));return{bunOffsets:a,bunData:e,moduleStructSize:p(a.modulesPtr.length)}}function v(e){if(e.length<4)throw Error(`Section data too small`);t(`extractBunDataFromSection: sectionData.length=${e.length}`);let n=e.readUInt32LE(0),r=4+n,i=e.length>=8?Number(e.readBigUInt64LE(0)):0,a=8+i;t(`extractBunDataFromSection: u32 header would give size=${n}, expected total=${r}`),t(`extractBunDataFromSection: u64 header would give size=${i}, expected total=${a}`);let o,s;if(e.length>=8&&a<=e.length&&a>=e.length-4096)o=8,s=i,t(`extractBunDataFromSection: detected u64 header format (Bun >= 1.3.4)`);else if(r<=e.length&&r>=e.length-4096)o=4,s=n,t(`extractBunDataFromSection: detected u32 header format (Bun < 1.3.4)`);else throw Error(`Cannot determine section header format: sectionData.length=${e.length}, u64 would expect ${a}, u32 would expect ${r}`);t(`extractBunDataFromSection: bunDataSize from header=${s}`);let c=e.subarray(o,o+s);t(`extractBunDataFromSection: bunDataContent.length=${c.length}`);let{bunOffsets:l,bunData:u,moduleStructSize:d}=_(c);return{bunOffsets:l,bunData:u,sectionHeaderSize:o,moduleStructSize:d}}function y(e){try{let n=e.getSection(`.bun`);if(!n)return t(`extractBunDataFromELFSection: .bun section not found`),null;let r=n.content;if(r.length<8)return t(`extractBunDataFromELFSection: .bun section too small`),null;t(`extractBunDataFromELFSection: .bun section found, size=${r.length}`);let i=v(r);return t(`extractBunDataFromELFSection: successfully extracted data`),i}catch(e){return t(`extractBunDataFromELFSection: failed to extract:`,e),null}}function b(e){if(!e.hasOverlay)throw Error(`ELF binary has no overlay data`);let n=e.overlay;if(t(`extractBunDataFromELFOverlay: Overlay size=${n.length} bytes`),n.length<l.length+8+32)throw Error(`ELF overlay data is too small`);let r=n.readBigUInt64LE(n.length-8);if(t(`extractBunDataFromELFOverlay: Total byte count from tail=${r}`),r<4096n||r>2n**32n-1n)throw Error(`ELF total byte count is out of range: ${r}`);let i=n.length-8-l.length,a=n.subarray(i,n.length-8);if(t(`extractBunDataFromELFOverlay: Expected trailer: ${l.toString(`hex`)}`),t(`extractBunDataFromELFOverlay: Got trailer: ${a.toString(`hex`)}`),!a.equals(l))throw Error(`BUN trailer bytes do not match trailer`);let o=n.length-8-l.length-32,s=n.subarray(o,n.length-8-l.length),c=h(s);t(`extractBunDataFromELFOverlay: Offsets.byteCount=${c.byteCount}`);let u=typeof c.byteCount==`bigint`?c.byteCount:BigInt(c.byteCount);if(u>=r)throw Error(`ELF total byte count is out of range`);let d=8+l.length+32,f=n.length-d-Number(u),m=n.subarray(f,n.length-d);return t(`extractBunDataFromELFOverlay: Extracted ${m.length} bytes of data`),{bunOffsets:c,bunData:Buffer.concat([m,s,a]),moduleStructSize:p(c.modulesPtr.length)}}function x(e){let t=e.getSegment(`__BUN`);if(!t)throw Error(`__BUN segment not found`);let n=t.getSection(`__bun`);if(!n)throw Error(`__bun section not found`);return v(n.content)}function S(e){let t=e.sections().find(e=>e.name===`.bun`);if(!t)throw Error(`.bun section not found`);return v(t.content)}function C(e){switch(t(`getBunData: Binary format detected as ${e.format}`),e.format){case`MachO`:return x(e);case`PE`:return S(e);case`ELF`:{let n=e,r=y(n);return r?(t(`getBunData: Using new ELF .bun section format`),r):(t(`getBunData: Falling back to legacy ELF overlay format`),b(n))}default:{let t=e;throw Error(`Unsupported binary format: ${t.format}`)}}}function w(e){let o=r.mkdtempSync(i.join(n.tmpdir(),`tweakcc-npm-`));try{t(`fetchNpmSource: Downloading @anthropic-ai/claude-code@${e}`),a(`npm`,[`pack`,`@anthropic-ai/claude-code@${e}`,`--pack-destination`,o],{stdio:`pipe`,timeout:3e4,cwd:o});let n=r.readdirSync(o).find(e=>e.endsWith(`.tgz`));if(!n)return t(`fetchNpmSource: No .tgz file found after npm pack`),null;a(`tar`,[`xzf`,i.join(o,n),`package/cli.js`],{stdio:`pipe`,timeout:3e4,cwd:o});let s=i.join(o,`package`,`cli.js`);if(!r.existsSync(s))return t(`fetchNpmSource: cli.js not found in extracted package`),null;let c=r.readFileSync(s);return t(`fetchNpmSource: Got cli.js, ${c.length} bytes`),c}catch(e){return t(`fetchNpmSource: Failed to fetch npm source:`,e),null}finally{try{r.rmSync(o,{recursive:!0,force:!0})}catch{}}}function T(e,n){try{s.logging.disable();let{bunOffsets:r,bunData:i,moduleStructSize:a}=C(s.parse(e));t(`extractClaudeJsFromNativeInstallation: Got bunData, size=${i.length} bytes, moduleStructSize=${a}`);let o=m(i,r,a,(e,n,r)=>{if(t(`extractClaudeJsFromNativeInstallation: Module ${r}: ${n}`),!f(n))return;let a=u(i,e.contents);return t(`extractClaudeJsFromNativeInstallation: Found claude module, contents length=${a.length}`),a.length>0?a:void 0});if(o){if(o.subarray(0,30).toString(`utf8`).startsWith(`// @bun @bytecode`))if(t(`extractClaudeJsFromNativeInstallation: Extracted content is Bun bytecode — falling back to npm source`),n){let e=w(n);if(e)return t(`extractClaudeJsFromNativeInstallation: Using npm source (${e.length} bytes) instead of bytecode`),{data:e,clearBytecode:!0};t(`extractClaudeJsFromNativeInstallation: npm source fetch failed, returning bytecode content as-is`)}else t(`extractClaudeJsFromNativeInstallation: No version provided, cannot fetch npm source`);return{data:o,clearBytecode:!1}}return t(`extractClaudeJsFromNativeInstallation: claude module not found in any module`),{data:null,clearBytecode:!1}}catch(e){return t(`extractClaudeJsFromNativeInstallation: Error during extraction:`,e),{data:null,clearBytecode:!1}}}function E(e,t,n,r,i){let a=[],o=[];m(e,t,r,(t,s)=>{let c=u(e,t.name),l,d;n&&f(s)?(l=n,d=i?Buffer.alloc(0):u(e,t.bytecode)):(l=u(e,t.contents),d=u(e,t.bytecode));let p=u(e,t.sourcemap),m=u(e,t.moduleInfo),h=u(e,t.bytecodeOriginPath);o.push({name:c,contents:l,sourcemap:p,bytecode:d,moduleInfo:m,bytecodeOriginPath:h,encoding:t.encoding,loader:t.loader,moduleFormat:t.moduleFormat,side:t.side}),r===52?a.push(c,l,p,d,m,h):a.push(c,l,p,d)});let s=r===52?6:4,c=0,d=[];for(let e of a)d.push({offset:c,length:e.length}),c+=e.length+1;let p=c,h=o.length*r;c+=h;let g=u(e,t.compileExecArgvPtr),_=c,v=g.length;c+=v+1;let y=c;c+=32;let b=c;c+=l.length;let x=Buffer.allocUnsafe(c);x.fill(0);let S=0;for(let{offset:e,length:t}of d)t>0&&a[S].copy(x,e,0,t),x[e+t]=0,S++;v>0&&(g.copy(x,_,0,v),x[_+v]=0);for(let e=0;e<o.length;e++){let t=o[e],n=e*s,i={name:d[n],contents:d[n+1],sourcemap:d[n+2],bytecode:d[n+3],moduleInfo:r===52?d[n+4]:{offset:0,length:0},bytecodeOriginPath:r===52?d[n+5]:{offset:0,length:0},encoding:t.encoding,loader:t.loader,moduleFormat:t.moduleFormat,side:t.side},a=p+e*r;x.writeUInt32LE(i.name.offset,a),x.writeUInt32LE(i.name.length,a+4),a+=8,x.writeUInt32LE(i.contents.offset,a),x.writeUInt32LE(i.contents.length,a+4),a+=8,x.writeUInt32LE(i.sourcemap.offset,a),x.writeUInt32LE(i.sourcemap.length,a+4),a+=8,x.writeUInt32LE(i.bytecode.offset,a),x.writeUInt32LE(i.bytecode.length,a+4),a+=8,r===52&&(x.writeUInt32LE(i.moduleInfo.offset,a),x.writeUInt32LE(i.moduleInfo.length,a+4),a+=8,x.writeUInt32LE(i.bytecodeOriginPath.offset,a),x.writeUInt32LE(i.bytecodeOriginPath.length,a+4),a+=8),x.writeUInt8(i.encoding,a),x.writeUInt8(i.loader,a+1),x.writeUInt8(i.moduleFormat,a+2),x.writeUInt8(i.side,a+3)}let C={byteCount:y,modulesPtr:{offset:p,length:h},entryPointId:t.entryPointId,compileExecArgvPtr:{offset:_,length:v},flags:t.flags},w=y,T=typeof C.byteCount==`bigint`?C.byteCount:BigInt(C.byteCount);return x.writeBigUInt64LE(T,w),w+=8,x.writeUInt32LE(C.modulesPtr.offset,w),x.writeUInt32LE(C.modulesPtr.length,w+4),w+=8,x.writeUInt32LE(C.entryPointId,w),w+=4,x.writeUInt32LE(C.compileExecArgvPtr.offset,w),x.writeUInt32LE(C.compileExecArgvPtr.length,w+4),w+=8,x.writeUInt32LE(C.flags,w),l.copy(x,b),x}function D(e,t,n,i=!0){let a=t+`.tmp`;if(e.write(a),i){let e=r.statSync(n);r.chmodSync(a,e.mode)}try{r.renameSync(a,t)}catch(e){try{r.existsSync(a)&&r.unlinkSync(a)}catch{}throw e instanceof Error&&`code`in e&&(e.code===`ETXTBSY`||e.code===`EBUSY`||e.code===`EPERM`)?Error(`Cannot update the Claude executable while it is running.
|
|
4
|
+
Please close all Claude instances and try again.`):e}}function O(e,t=8){let n=Buffer.allocUnsafe(t+e.length);return t===8?n.writeBigUInt64LE(BigInt(e.length),0):n.writeUInt32LE(e.length,0),e.copy(n,t),n}function k(n,r,i,a,c){try{t(`repackMachO: Has code signature: ${n.hasCodeSignature}`),n.hasCodeSignature&&(t(`repackMachO: Removing code signature...`),n.removeSignature());let l=n.getSegment(`__BUN`);if(!l)throw Error(`__BUN segment not found`);let u=l.getSection(`__bun`);if(!u)throw Error(`__bun section not found`);let d=O(i,c);t(`repackMachO: Original section size: ${u.size}`),t(`repackMachO: Original segment fileSize: ${l.fileSize}`),t(`repackMachO: Original segment virtualSize: ${l.virtualSize}`),t(`repackMachO: New data size: ${d.length}`),t(`repackMachO: Using header size: ${c}`);let f=d.length-Number(u.size);if(f>0){let e=n.header.cpuType===s.MachO.Header.CPU_TYPE.ARM64,r=e?16384:4096,i=Math.ceil(f/r)*r;t(`repackMachO: CPU type: ${e?`ARM64`:`x86_64`}`),t(`repackMachO: Page size: ${r} bytes`),t(`repackMachO: Need to expand by ${f} bytes`),t(`repackMachO: Rounding up to page-aligned: ${i} bytes`);let a=n.extendSegment(l,i);if(t(`repackMachO: extendSegment returned: ${a}`),!a)throw Error(`Failed to extend __BUN segment`);t(`repackMachO: Section size after extend: ${u.size}`),t(`repackMachO: Segment fileSize after extend: ${l.fileSize}`),t(`repackMachO: Segment virtualSize after extend: ${l.virtualSize}`)}u.content=d,u.size=BigInt(d.length),t(`repackMachO: Final section size: ${u.size}`),t(`repackMachO: Writing modified binary to ${a}...`),D(n,a,r);try{t(`repackMachO: Re-signing binary with ad-hoc signature...`),o(`codesign -s - -f "${a}"`,{stdio:e()?`inherit`:`ignore`}),t(`repackMachO: Code signing completed successfully`)}catch(e){console.warn(`Warning: Failed to re-sign binary. The binary may not run correctly on macOS:`,e)}t(`repackMachO: Write completed successfully`)}catch(e){throw console.error(`repackMachO failed:`,e),e}}function A(e,n,r,i,a){try{let o=e.sections().find(e=>e.name===`.bun`);if(!o)throw Error(`.bun section not found`);let s=O(r,a);t(`repackPE: Original section size: ${o.size}, virtual size: ${o.virtualSize}`),t(`repackPE: New data size: ${s.length}`),t(`repackPE: Using header size: ${a}`),o.content=s,o.virtualSize=BigInt(s.length),o.size=BigInt(s.length),t(`repackPE: Writing modified binary to ${i}...`),D(e,i,n,!1),t(`repackPE: Write completed successfully`)}catch(e){throw console.error(`repackPE failed:`,e),e}}const j=16384;function M(e,n,r,i,a){try{let o=e.getSection(`.bun`);if(!o)throw Error(`.bun section not found`);let s=O(r,a);t(`repackELFSection: Original section size: ${o.size}`),t(`repackELFSection: New section data size: ${s.length}`);let c=o.virtualAddress,l=e.segments(),u=l.find(e=>e.type===`LOAD`&&e.flags===4&&e.virtualAddress===c);if(!u)throw Error(`.bun PT_LOAD segment not found (looking for LOAD with vaddr=0x${c.toString(16)})`);t(`repackELFSection: Found .bun segment: vaddr=0x${u.virtualAddress.toString(16)}, filesz=0x${u.fileSize.toString(16)}, memsz=0x${u.virtualSize.toString(16)}`);let d=Buffer.alloc(8);d.writeBigUInt64LE(c);let f=null,p=l.find(e=>e.type===`LOAD`&&(e.flags&2)!=0);if(p){let e=p.content,n=Number(p.virtualAddress),r=Math.ceil(n/j)*j;for(let i=r;i<n+e.length-8;i+=j){let r=i-n;if(e.subarray(r,r+8).equals(d)){f=BigInt(i),t(`repackELFSection: BUN_COMPILED at vaddr 0x${f.toString(16)} (offset ${r} in RW segment)`);break}}}if(f===null)throw Error(`Could not find original BUN_COMPILED location in binary`);o.content=s;let m=Number(u.alignment),h=BigInt(Math.ceil(s.length/m)*m);u.fileSize=h,u.virtualSize=h,t(`repackELFSection: Updated segment: filesz=0x${u.fileSize.toString(16)}, memsz=0x${u.virtualSize.toString(16)}`);let g=Buffer.alloc(8);g.writeBigUInt64LE(c),e.patchAddress(f,g),t(`repackELFSection: Patched BUN_COMPILED at vaddr 0x${f.toString(16)} -> 0x${c.toString(16)}`),D(e,i,n),t(`repackELFSection: Write completed successfully`)}catch(e){throw console.error(`repackELFSection failed:`,e),e}}function N(e,n,r,i){try{let a=Buffer.allocUnsafe(r.length+8);r.copy(a,0),a.writeBigUInt64LE(BigInt(r.length),r.length),t(`repackELFOverlay: Setting overlay data (${a.length} bytes)`),e.overlay=a,t(`repackELFOverlay: Writing modified binary to ${i}...`),D(e,i,n),t(`repackELFOverlay: Write completed successfully`)}catch(e){throw console.error(`repackELFOverlay failed:`,e),e}}function P(e,t,n,r){s.logging.disable();let i=s.parse(e),{bunOffsets:a,bunData:o,sectionHeaderSize:c,moduleStructSize:l}=C(i),u=E(o,a,t,l,r);switch(i.format){case`MachO`:if(!c)throw Error(`sectionHeaderSize is required for Mach-O binaries`);k(i,e,u,n,c);break;case`PE`:if(!c)throw Error(`sectionHeaderSize is required for PE binaries`);A(i,e,u,n,c);break;case`ELF`:c?M(i,e,u,n,c):N(i,e,u,n);break;default:{let e=i;throw Error(`Unsupported binary format: ${e.format}`)}}}export{T as extractClaudeJsFromNativeInstallation,P as repackNativeInstallation,c as resolveNixBinaryWrapper};
|
package/package.json
ADDED
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "tweakcc-fixed",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"description": "Temporary fork of tweakcc with pending upstream fixes cherry-picked and additional patches for Claude Code 2.1.113+ compatibility.",
|
|
6
|
+
"main": "dist/lib/index.mjs",
|
|
7
|
+
"types": "dist/lib/index.d.ts",
|
|
8
|
+
"bin": {
|
|
9
|
+
"tweakcc-fixed": "./dist/index.mjs"
|
|
10
|
+
},
|
|
11
|
+
"exports": {
|
|
12
|
+
".": {
|
|
13
|
+
"types": "./dist/lib/index.d.ts",
|
|
14
|
+
"default": "./dist/lib/index.mjs"
|
|
15
|
+
}
|
|
16
|
+
},
|
|
17
|
+
"scripts": {
|
|
18
|
+
"build": "tsc --noEmit && tsdown --minify --dts src/index.tsx src/lib/index.ts",
|
|
19
|
+
"build:dev": "tsdown --dts src/index.tsx src/lib/index.ts",
|
|
20
|
+
"watch": "tsdown --watch --dts src/index.tsx src/lib/index.ts",
|
|
21
|
+
"start": "node dist/index.mjs",
|
|
22
|
+
"lint": "tsc --noEmit && eslint src",
|
|
23
|
+
"test": "vitest run",
|
|
24
|
+
"test:dev": "vitest",
|
|
25
|
+
"format": "prettier --write src",
|
|
26
|
+
"prepare": "husky",
|
|
27
|
+
"prepublishOnly": "pnpm build"
|
|
28
|
+
},
|
|
29
|
+
"keywords": [
|
|
30
|
+
"cli",
|
|
31
|
+
"terminal",
|
|
32
|
+
"ink",
|
|
33
|
+
"react",
|
|
34
|
+
"typescript",
|
|
35
|
+
"claude",
|
|
36
|
+
"claude-code",
|
|
37
|
+
"customize",
|
|
38
|
+
"installation",
|
|
39
|
+
"theme",
|
|
40
|
+
"claude-code-theme",
|
|
41
|
+
"system-prompts",
|
|
42
|
+
"toolsets"
|
|
43
|
+
],
|
|
44
|
+
"author": {
|
|
45
|
+
"name": "Piebald LLC",
|
|
46
|
+
"email": "support@piebald.ai",
|
|
47
|
+
"url": "https://piebald.ai"
|
|
48
|
+
},
|
|
49
|
+
"contributors": [
|
|
50
|
+
{
|
|
51
|
+
"name": "Ben",
|
|
52
|
+
"email": "Ben@noreply.cathedral.gg",
|
|
53
|
+
"url": "https://github.com/BenIsLegit"
|
|
54
|
+
}
|
|
55
|
+
],
|
|
56
|
+
"license": "MIT",
|
|
57
|
+
"repository": {
|
|
58
|
+
"type": "git",
|
|
59
|
+
"url": "git+https://github.com/BenIsLegit/tweakcc-fixed.git"
|
|
60
|
+
},
|
|
61
|
+
"homepage": "https://github.com/BenIsLegit/tweakcc-fixed#readme",
|
|
62
|
+
"bugs": {
|
|
63
|
+
"url": "https://github.com/BenIsLegit/tweakcc-fixed/issues"
|
|
64
|
+
},
|
|
65
|
+
"files": [
|
|
66
|
+
"dist",
|
|
67
|
+
"README.md",
|
|
68
|
+
"LICENSE"
|
|
69
|
+
],
|
|
70
|
+
"publishConfig": {
|
|
71
|
+
"access": "public"
|
|
72
|
+
},
|
|
73
|
+
"devDependencies": {
|
|
74
|
+
"@eslint/js": "^9.33.0",
|
|
75
|
+
"@types/node": "^20.19.10",
|
|
76
|
+
"@types/react": "^18.3.23",
|
|
77
|
+
"@types/which": "^3.0.4",
|
|
78
|
+
"eslint": "^9.33.0",
|
|
79
|
+
"eslint-plugin-react": "^7.37.5",
|
|
80
|
+
"globals": "^16.3.0",
|
|
81
|
+
"husky": "^9.1.7",
|
|
82
|
+
"lint-staged": "^16.2.7",
|
|
83
|
+
"prettier": "^3.6.2",
|
|
84
|
+
"tsdown": "^0.18.4",
|
|
85
|
+
"tsx": "^4.20.3",
|
|
86
|
+
"typescript": "^5.9.2",
|
|
87
|
+
"typescript-eslint": "^8.39.0",
|
|
88
|
+
"vitest": "^3.2.4"
|
|
89
|
+
},
|
|
90
|
+
"lint-staged": {
|
|
91
|
+
"*.{ts,tsx}": "prettier --write",
|
|
92
|
+
"*.{json,md}": "prettier --write"
|
|
93
|
+
},
|
|
94
|
+
"dependencies": {
|
|
95
|
+
"chalk": "^5.5.0",
|
|
96
|
+
"cli-spinners": "^3.4.0",
|
|
97
|
+
"commander": "^14.0.0",
|
|
98
|
+
"diff": "^8.0.3",
|
|
99
|
+
"globby": "^14.1.0",
|
|
100
|
+
"gray-matter": "^4.0.3",
|
|
101
|
+
"ink": "^6.1.0",
|
|
102
|
+
"ink-link": "^4.1.0",
|
|
103
|
+
"node-lief": "^1.1.1",
|
|
104
|
+
"oxfmt": "^0.28.0",
|
|
105
|
+
"react": "^19.1.1",
|
|
106
|
+
"wasmagic": "^1.0.7",
|
|
107
|
+
"which": "^6.0.0"
|
|
108
|
+
},
|
|
109
|
+
"engines": {
|
|
110
|
+
"node": ">=20.0.0"
|
|
111
|
+
}
|
|
112
|
+
}
|