From f669a199f1a14993f50d383044e0c55eae4ff9ab Mon Sep 17 00:00:00 2001 From: Vitaly Ostanin Date: Tue, 31 Mar 2026 14:28:26 +0300 Subject: [PATCH 1/5] feat: add /clear-screen slash command Clear screen without resetting conversation context. Recommended keybinding: ctrl+k ctrl+l (Chat context). How it works: 1. Exposes ink's forceRedraw() via globalThis.__tweakccForceRedraw by patching the app:redraw callback registration site 2. Registers /clear-screen as a local slash command that: - Clears messages via setMessages, keeping last assistant message with empty content to preserve context window usage (ctx%) - Clears terminal scrollback with \x1b[3J - Triggers ink repaint via forceRedraw() --- src/patches/clearScreen.test.ts | 55 +++++++++++++++++++++++++++++ src/patches/clearScreen.ts | 61 +++++++++++++++++++++++++++++++++ src/patches/index.ts | 10 ++++++ 3 files changed, 126 insertions(+) create mode 100644 src/patches/clearScreen.test.ts create mode 100644 src/patches/clearScreen.ts diff --git a/src/patches/clearScreen.test.ts b/src/patches/clearScreen.test.ts new file mode 100644 index 00000000..0889c7ce --- /dev/null +++ b/src/patches/clearScreen.test.ts @@ -0,0 +1,55 @@ +import { describe, expect, it } from 'vitest'; + +import { writeClearScreen } from './clearScreen'; + +const cmds = Array.from({ length: 31 }, (_, i) => `c${i}`).join(','); +const slashCommandArray = `=>[${cmds}]`; + +const makeInput = (delimiter = ';') => + 'const x=1' + + slashCommandArray + + `${delimiter}let Z=G_H.useCallback(()=>{Nw.get(process.stdout)?.forceRedraw()})`; + +describe('clearScreen', () => { + it('exposes forceRedraw and registers /clear-screen command', () => { + const result = writeClearScreen(makeInput()); + + expect(result).not.toBeNull(); + expect(result).toContain( + 'globalThis.__tweakccForceRedraw=()=>Nw.get(process.stdout)?.forceRedraw()' + ); + expect(result).toContain('name:"clear-screen"'); + expect(result).toContain('$.setMessages('); + expect(result).toContain('globalThis.__tweakccForceRedraw?.()'); + }); + + it('preserves original app:redraw callback', () => { + const result = writeClearScreen(makeInput()); + + expect(result).not.toBeNull(); + expect(result).toContain( + 'let Z=G_H.useCallback(()=>{Nw.get(process.stdout)?.forceRedraw()})' + ); + }); + + it('returns oldFile when already patched', () => { + const input = makeInput() + ',{name:"clear-screen"}'; + const result = writeClearScreen(input); + + expect(result).toBe(input); + }); + + it('returns null when app:redraw callback not found', () => { + const result = writeClearScreen('const x=1;'); + + expect(result).toBeNull(); + }); + + it('works with different delimiters before useCallback', () => { + for (const d of [',', ';', '}', '{']) { + const result = writeClearScreen(makeInput(d)); + expect(result).not.toBeNull(); + expect(result).toContain('globalThis.__tweakccForceRedraw'); + } + }); +}); diff --git a/src/patches/clearScreen.ts b/src/patches/clearScreen.ts new file mode 100644 index 00000000..c3334628 --- /dev/null +++ b/src/patches/clearScreen.ts @@ -0,0 +1,61 @@ +// Please see the note about writing patches in ./index + +import { debug } from '../utils'; +import { showDiff } from './index'; +import { writeSlashCommandDefinition } from './slashCommands'; + +export const writeClearScreen = (oldFile: string): string | null => { + const alreadyPatchedPattern = /name:"clear-screen"/; + if (alreadyPatchedPattern.test(oldFile)) { + return oldFile; + } + + const redrawPattern = + /([,;{}])(let [$\w]+=[$\w]+\.useCallback\(\(\)=>\{)([$\w]+)\.get\(process\.stdout\)\?\.forceRedraw\(\)\}/; + const redrawMatch = oldFile.match(redrawPattern); + if (!redrawMatch || redrawMatch.index === undefined) { + debug('patch: clearScreen: failed to find app:redraw callback'); + return null; + } + + const delimiter = redrawMatch[1]; + const mapVar = redrawMatch[3]; + const redrawReplacement = + `${delimiter}globalThis.__tweakccForceRedraw=()=>${mapVar}.get(process.stdout)?.forceRedraw();` + + redrawMatch[0].slice(1); + + const file = + oldFile.slice(0, redrawMatch.index) + + redrawReplacement + + oldFile.slice(redrawMatch.index + redrawMatch[0].length); + + showDiff( + oldFile, + file, + redrawReplacement, + redrawMatch.index, + redrawMatch.index + redrawMatch[0].length + ); + + const commandDef = + ',{type:"local",name:"clear-screen",' + + 'description:"Clear screen without resetting conversation context",' + + 'supportsNonInteractive:!1,' + + 'load:()=>Promise.resolve().then(()=>({call:(H,$)=>{' + + '$.setMessages(m=>{' + + 'for(let i=m.length-1;i>=0;i--)' + + 'if(m[i]?.type==="assistant"&&m[i].message?.usage)' + + 'return[{...m[i],message:{...m[i].message,content:[]}}];' + + 'return[]});' + + 'process.stdout.write("\\x1b[3J");' + + 'globalThis.__tweakccForceRedraw?.();' + + 'return{type:"skip"}}}))}'; + + const result = writeSlashCommandDefinition(file, commandDef); + if (!result) { + debug('patch: clearScreen: failed to register slash command'); + return null; + } + + return result; +}; diff --git a/src/patches/index.ts b/src/patches/index.ts index a1c69861..18dadc9b 100644 --- a/src/patches/index.ts +++ b/src/patches/index.ts @@ -73,6 +73,7 @@ import { writeWorktreeMode } from './worktreeMode'; import { writeAllowCustomAgentModels } from './allowCustomAgentModels'; import { writeVoiceMode } from './voiceMode'; import { writeChannelsMode } from './channelsMode'; +import { writeClearScreen } from './clearScreen'; import { restoreNativeBinaryFromBackup, restoreClijsFromBackup, @@ -174,6 +175,12 @@ const PATCH_DEFINITIONS = [ group: PatchGroup.ALWAYS_APPLIED, description: `Statusline updates will be properly throttled instead of queued (or debounced)`, }, + { + id: 'clear-screen', + name: 'Clear screen command', + group: PatchGroup.ALWAYS_APPLIED, + description: 'Register /clear-screen command (clear scrollback + redraw)', + }, // Misc Configurable { id: 'model-customizations', @@ -663,6 +670,9 @@ export const applyCustomization = async ( ), condition: config.settings.misc?.statuslineThrottleMs != null, }, + 'clear-screen': { + fn: c => writeClearScreen(c), + }, // Misc Configurable 'patches-applied-indication': { fn: c => From 683c0afc2af4bbb69b283e1c056df4a664565754 Mon Sep 17 00:00:00 2001 From: Vitaly Ostanin Date: Tue, 31 Mar 2026 15:18:42 +0300 Subject: [PATCH 2/5] Address review feedback: fallback for assistant without usage - setMessages now preserves the last assistant message as fallback when no assistant message has message.usage, instead of returning []. - Add edge-case test for the fallback behavior. - Keep vitest imports: coderabbitai suggested removing them since vitest.config.ts has globals:true, but tsconfig.json lacks "types": ["vitest/globals"], so tsc --noEmit (run by pre-commit hook via pnpm lint) fails without explicit imports. All other test files in the repo use explicit imports for the same reason. --- src/patches/clearScreen.test.ts | 7 +++++++ src/patches/clearScreen.ts | 9 +++++---- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/src/patches/clearScreen.test.ts b/src/patches/clearScreen.test.ts index 0889c7ce..a2753480 100644 --- a/src/patches/clearScreen.test.ts +++ b/src/patches/clearScreen.test.ts @@ -45,6 +45,13 @@ describe('clearScreen', () => { expect(result).toBeNull(); }); + it('preserves fallback for assistant messages without usage', () => { + const result = writeClearScreen(makeInput()); + + expect(result).not.toBeNull(); + expect(result).toContain('if(!k&&m[i]?.type==="assistant")k=m[i]'); + }); + it('works with different delimiters before useCallback', () => { for (const d of [',', ';', '}', '{']) { const result = writeClearScreen(makeInput(d)); diff --git a/src/patches/clearScreen.ts b/src/patches/clearScreen.ts index c3334628..ff776092 100644 --- a/src/patches/clearScreen.ts +++ b/src/patches/clearScreen.ts @@ -43,10 +43,11 @@ export const writeClearScreen = (oldFile: string): string | null => { 'supportsNonInteractive:!1,' + 'load:()=>Promise.resolve().then(()=>({call:(H,$)=>{' + '$.setMessages(m=>{' + - 'for(let i=m.length-1;i>=0;i--)' + - 'if(m[i]?.type==="assistant"&&m[i].message?.usage)' + - 'return[{...m[i],message:{...m[i].message,content:[]}}];' + - 'return[]});' + + 'let k=null;' + + 'for(let i=m.length-1;i>=0;i--){' + + 'if(m[i]?.type==="assistant"&&m[i].message?.usage){k=m[i];break}' + + 'if(!k&&m[i]?.type==="assistant")k=m[i]}' + + 'return k?[{...k,message:{...k.message,content:[]}}]:[]});' + 'process.stdout.write("\\x1b[3J");' + 'globalThis.__tweakccForceRedraw?.();' + 'return{type:"skip"}}}))}'; From 4eea75356629f26b8b21da418cf75ba1d30f53a2 Mon Sep 17 00:00:00 2001 From: Vitaly Ostanin Date: Tue, 31 Mar 2026 19:03:16 +0300 Subject: [PATCH 3/5] fix: preserve conversation context in /clear-screen MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The previous implementation replaced the messages array with a single empty-content assistant message to preserve prompt cache. This caused two problems: 1. Claude lost all conversation context and treated the next message as the start of a new session ("This is the first message...") 2. The prompt cache was not actually preserved — cache breakpoints are set via cache_control in the API request, and the usage field in the saved assistant message is a response from the previous call, not an instruction for the next one. The new implementation hides messages from the UI without removing them from the messages array: - On /clear-screen, all current message UUIDs (first 24 chars) are collected into a globalThis.__tweakccHiddenUUIDs Set. - The render filter function (g97) is patched to check this Set and skip messages whose UUID prefix matches. - Messages remain in the array and are sent to the API as usual, preserving full conversation context. UUID prefix (24 chars) is used because the render pipeline function lP() splits multi-content assistant messages into separate objects with modified UUIDs (original.slice(0,24) + hex index). Matching on the prefix ensures both original and split messages are hidden. The approach with a per-message flag (__tweakccHiddenFromUI) was tried first but failed: lP() creates new objects for assistant messages with a fixed set of fields, dropping custom properties. User messages worked because lP() uses object spread for string content, preserving extra fields — but assistant messages did not. After session resume, globalThis is empty, so previously hidden messages become visible again (acceptable trade-off). --- src/patches/clearScreen.test.ts | 75 ++++++++++++++++++++++++++++++--- src/patches/clearScreen.ts | 52 ++++++++++++++++++++--- 2 files changed, 114 insertions(+), 13 deletions(-) diff --git a/src/patches/clearScreen.test.ts b/src/patches/clearScreen.test.ts index a2753480..40772a40 100644 --- a/src/patches/clearScreen.test.ts +++ b/src/patches/clearScreen.test.ts @@ -1,12 +1,16 @@ import { describe, expect, it } from 'vitest'; -import { writeClearScreen } from './clearScreen'; +import { writeClearScreen, patchRenderFilter } from './clearScreen'; const cmds = Array.from({ length: 31 }, (_, i) => `c${i}`).join(','); const slashCommandArray = `=>[${cmds}]`; +const renderFilter = + 'function g97(H,$){if(H.type!=="user")return!0;if(H.isMeta){if(H.origin?.kind==="channel")return!0;return!1}if(H.isVisibleInTranscriptOnly&&!$)return!1;return!0}'; + const makeInput = (delimiter = ';') => 'const x=1' + + renderFilter + slashCommandArray + `${delimiter}let Z=G_H.useCallback(()=>{Nw.get(process.stdout)?.forceRedraw()})`; @@ -19,10 +23,30 @@ describe('clearScreen', () => { 'globalThis.__tweakccForceRedraw=()=>Nw.get(process.stdout)?.forceRedraw()' ); expect(result).toContain('name:"clear-screen"'); - expect(result).toContain('$.setMessages('); + expect(result).toContain('__tweakccHiddenUUIDs'); expect(result).toContain('globalThis.__tweakccForceRedraw?.()'); }); + it('preserves all messages for API context (hides via UUID set, does not remove)', () => { + const result = writeClearScreen(makeInput()); + + expect(result).not.toBeNull(); + expect(result).toContain('__tweakccHiddenUUIDs=new Set('); + expect(result).toContain('return[...m]'); + expect(result).not.toContain('content:[]'); + expect(result).not.toContain('return k?['); + expect(result).not.toContain('return[]'); + }); + + it('patches render filter to check __tweakccHiddenUUIDs', () => { + const result = writeClearScreen(makeInput()); + + expect(result).not.toBeNull(); + expect(result).toContain( + 'globalThis.__tweakccHiddenUUIDs?.has(H.uuid?.slice(0,24)))return!1;if(H.type!=="user")' + ); + }); + it('preserves original app:redraw callback', () => { const result = writeClearScreen(makeInput()); @@ -45,11 +69,14 @@ describe('clearScreen', () => { expect(result).toBeNull(); }); - it('preserves fallback for assistant messages without usage', () => { - const result = writeClearScreen(makeInput()); + it('returns null when render filter not found', () => { + const input = + 'const x=1' + + slashCommandArray + + ';let Z=G_H.useCallback(()=>{Nw.get(process.stdout)?.forceRedraw()})'; + const result = writeClearScreen(input); - expect(result).not.toBeNull(); - expect(result).toContain('if(!k&&m[i]?.type==="assistant")k=m[i]'); + expect(result).toBeNull(); }); it('works with different delimiters before useCallback', () => { @@ -60,3 +87,39 @@ describe('clearScreen', () => { } }); }); + +describe('patchRenderFilter', () => { + it('adds __tweakccHiddenUUIDs check at the start of the function', () => { + const result = patchRenderFilter(renderFilter); + + expect(result).not.toBeNull(); + expect(result).toContain( + 'function g97(H,$){if(globalThis.__tweakccHiddenUUIDs?.has(H.uuid?.slice(0,24)))return!1;if(H.type!=="user")' + ); + }); + + it('preserves the rest of the function', () => { + const result = patchRenderFilter(renderFilter); + + expect(result).not.toBeNull(); + expect(result).toContain('if(H.isMeta)'); + expect(result).toContain('if(H.isVisibleInTranscriptOnly&&!$)return!1'); + }); + + it('returns null when pattern not found', () => { + const result = patchRenderFilter('const x=1;'); + + expect(result).toBeNull(); + }); + + it('works with different function and argument names', () => { + const input = + 'function abc(X$,Y$){if(X$.type!=="user")return!0;if(X$.isMeta){if(X$.origin?.kind==="channel")return!0;return!1}return!0}'; + const result = patchRenderFilter(input); + + expect(result).not.toBeNull(); + expect(result).toContain( + 'if(globalThis.__tweakccHiddenUUIDs?.has(X$.uuid?.slice(0,24)))return!1;' + ); + }); +}); diff --git a/src/patches/clearScreen.ts b/src/patches/clearScreen.ts index ff776092..e6103d84 100644 --- a/src/patches/clearScreen.ts +++ b/src/patches/clearScreen.ts @@ -24,7 +24,7 @@ export const writeClearScreen = (oldFile: string): string | null => { `${delimiter}globalThis.__tweakccForceRedraw=()=>${mapVar}.get(process.stdout)?.forceRedraw();` + redrawMatch[0].slice(1); - const file = + let file = oldFile.slice(0, redrawMatch.index) + redrawReplacement + oldFile.slice(redrawMatch.index + redrawMatch[0].length); @@ -37,18 +37,22 @@ export const writeClearScreen = (oldFile: string): string | null => { redrawMatch.index + redrawMatch[0].length ); + const renderFilterResult = patchRenderFilter(file); + if (!renderFilterResult) { + debug('patch: clearScreen: failed to patch render filter g97'); + return null; + } + file = renderFilterResult; + const commandDef = ',{type:"local",name:"clear-screen",' + 'description:"Clear screen without resetting conversation context",' + 'supportsNonInteractive:!1,' + 'load:()=>Promise.resolve().then(()=>({call:(H,$)=>{' + '$.setMessages(m=>{' + - 'let k=null;' + - 'for(let i=m.length-1;i>=0;i--){' + - 'if(m[i]?.type==="assistant"&&m[i].message?.usage){k=m[i];break}' + - 'if(!k&&m[i]?.type==="assistant")k=m[i]}' + - 'return k?[{...k,message:{...k.message,content:[]}}]:[]});' + - 'process.stdout.write("\\x1b[3J");' + + 'globalThis.__tweakccHiddenUUIDs=new Set(m.map(x=>x.uuid?.slice(0,24)).filter(Boolean));' + + 'return[...m]});' + + 'process.stdout.write("\\x1b[2J\\x1b[H\\x1b[3J");' + 'globalThis.__tweakccForceRedraw?.();' + 'return{type:"skip"}}}))}'; @@ -60,3 +64,37 @@ export const writeClearScreen = (oldFile: string): string | null => { return result; }; + +export const patchRenderFilter = (oldFile: string): string | null => { + const pattern = + /(function [$\w]+\([$\w]+,[$\w]+\)\{)if\([$\w]+\.type!=="user"\)return!0;if\([$\w]+\.isMeta\)/; + const match = oldFile.match(pattern); + if (!match || match.index === undefined) { + return null; + } + + const funcPrefix = match[1]; + const firstArg = match[0].match(/function ([$\w]+)\(([$\w]+),/)?.[2]; + if (!firstArg) { + return null; + } + + const replacement = + `${funcPrefix}if(globalThis.__tweakccHiddenUUIDs?.has(${firstArg}.uuid?.slice(0,24)))return!1;` + + match[0].slice(funcPrefix.length); + + const result = + oldFile.slice(0, match.index) + + replacement + + oldFile.slice(match.index + match[0].length); + + showDiff( + oldFile, + result, + replacement, + match.index, + match.index + match[0].length + ); + + return result; +}; From 8458f266e20ebe7bb0664891cf7e318e49850bf2 Mon Sep 17 00:00:00 2001 From: Vitaly Ostanin Date: Sun, 5 Apr 2026 00:47:29 +0300 Subject: [PATCH 4/5] Add delimiter prefix to patchRenderFilter regex for V8 performance Anchor patchRenderFilter regex with [,;{}] literal delimiter before "function" keyword, matching the convention used by redrawPattern and other patches. Update tests to supply delimiter in test data and add delimiter variation coverage. --- src/patches/clearScreen.test.ts | 20 +++++++++++++++----- src/patches/clearScreen.ts | 9 +++++---- 2 files changed, 20 insertions(+), 9 deletions(-) diff --git a/src/patches/clearScreen.test.ts b/src/patches/clearScreen.test.ts index 40772a40..70a55e71 100644 --- a/src/patches/clearScreen.test.ts +++ b/src/patches/clearScreen.test.ts @@ -9,7 +9,7 @@ const renderFilter = 'function g97(H,$){if(H.type!=="user")return!0;if(H.isMeta){if(H.origin?.kind==="channel")return!0;return!1}if(H.isVisibleInTranscriptOnly&&!$)return!1;return!0}'; const makeInput = (delimiter = ';') => - 'const x=1' + + 'const x=1;' + renderFilter + slashCommandArray + `${delimiter}let Z=G_H.useCallback(()=>{Nw.get(process.stdout)?.forceRedraw()})`; @@ -90,16 +90,16 @@ describe('clearScreen', () => { describe('patchRenderFilter', () => { it('adds __tweakccHiddenUUIDs check at the start of the function', () => { - const result = patchRenderFilter(renderFilter); + const result = patchRenderFilter(';' + renderFilter); expect(result).not.toBeNull(); expect(result).toContain( - 'function g97(H,$){if(globalThis.__tweakccHiddenUUIDs?.has(H.uuid?.slice(0,24)))return!1;if(H.type!=="user")' + ';function g97(H,$){if(globalThis.__tweakccHiddenUUIDs?.has(H.uuid?.slice(0,24)))return!1;if(H.type!=="user")' ); }); it('preserves the rest of the function', () => { - const result = patchRenderFilter(renderFilter); + const result = patchRenderFilter(';' + renderFilter); expect(result).not.toBeNull(); expect(result).toContain('if(H.isMeta)'); @@ -112,9 +112,19 @@ describe('patchRenderFilter', () => { expect(result).toBeNull(); }); + it('works with different delimiters before function', () => { + for (const d of [',', ';', '}', '{']) { + const result = patchRenderFilter(d + renderFilter); + expect(result).not.toBeNull(); + expect(result).toContain( + 'if(globalThis.__tweakccHiddenUUIDs?.has(H.uuid?.slice(0,24)))return!1;' + ); + } + }); + it('works with different function and argument names', () => { const input = - 'function abc(X$,Y$){if(X$.type!=="user")return!0;if(X$.isMeta){if(X$.origin?.kind==="channel")return!0;return!1}return!0}'; + ';function abc(X$,Y$){if(X$.type!=="user")return!0;if(X$.isMeta){if(X$.origin?.kind==="channel")return!0;return!1}return!0}'; const result = patchRenderFilter(input); expect(result).not.toBeNull(); diff --git a/src/patches/clearScreen.ts b/src/patches/clearScreen.ts index e6103d84..10147be1 100644 --- a/src/patches/clearScreen.ts +++ b/src/patches/clearScreen.ts @@ -67,21 +67,22 @@ export const writeClearScreen = (oldFile: string): string | null => { export const patchRenderFilter = (oldFile: string): string | null => { const pattern = - /(function [$\w]+\([$\w]+,[$\w]+\)\{)if\([$\w]+\.type!=="user"\)return!0;if\([$\w]+\.isMeta\)/; + /([,;{}])(function [$\w]+\([$\w]+,[$\w]+\)\{)if\([$\w]+\.type!=="user"\)return!0;if\([$\w]+\.isMeta\)/; const match = oldFile.match(pattern); if (!match || match.index === undefined) { return null; } - const funcPrefix = match[1]; + const delimiter = match[1]; + const funcPrefix = match[2]; const firstArg = match[0].match(/function ([$\w]+)\(([$\w]+),/)?.[2]; if (!firstArg) { return null; } const replacement = - `${funcPrefix}if(globalThis.__tweakccHiddenUUIDs?.has(${firstArg}.uuid?.slice(0,24)))return!1;` + - match[0].slice(funcPrefix.length); + `${delimiter}${funcPrefix}if(globalThis.__tweakccHiddenUUIDs?.has(${firstArg}.uuid?.slice(0,24)))return!1;` + + match[0].slice(delimiter.length + funcPrefix.length); const result = oldFile.slice(0, match.index) + From b58ff14bf47ef51d2c3ad9c8f3c012d157c1439a Mon Sep 17 00:00:00 2001 From: Vitaly Ostanin Date: Sun, 5 Apr 2026 01:05:14 +0300 Subject: [PATCH 5/5] Tie render filter regex to first param via backreference Use backreference \3 to ensure type/isMeta checks reference the same identifier as the function's first parameter. Extract firstArg directly from match[3] instead of re-parsing match[0]. --- src/patches/clearScreen.ts | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/patches/clearScreen.ts b/src/patches/clearScreen.ts index 10147be1..66ae7c94 100644 --- a/src/patches/clearScreen.ts +++ b/src/patches/clearScreen.ts @@ -67,7 +67,7 @@ export const writeClearScreen = (oldFile: string): string | null => { export const patchRenderFilter = (oldFile: string): string | null => { const pattern = - /([,;{}])(function [$\w]+\([$\w]+,[$\w]+\)\{)if\([$\w]+\.type!=="user"\)return!0;if\([$\w]+\.isMeta\)/; + /([,;{}])(function [$\w]+\(([$\w]+),[$\w]+\)\{)if\(\3\.type!=="user"\)return!0;if\(\3\.isMeta\)/; const match = oldFile.match(pattern); if (!match || match.index === undefined) { return null; @@ -75,10 +75,7 @@ export const patchRenderFilter = (oldFile: string): string | null => { const delimiter = match[1]; const funcPrefix = match[2]; - const firstArg = match[0].match(/function ([$\w]+)\(([$\w]+),/)?.[2]; - if (!firstArg) { - return null; - } + const firstArg = match[3]; const replacement = `${delimiter}${funcPrefix}if(globalThis.__tweakccHiddenUUIDs?.has(${firstArg}.uuid?.slice(0,24)))return!1;` +