From fd7386a407b7555b9f586aee5f286937dcaa5b68 Mon Sep 17 00:00:00 2001 From: Christopher Tso Date: Tue, 3 Feb 2026 13:23:04 +0000 Subject: [PATCH] fix(deps): patch @clack/core to restore stdin raw mode on Windows The block() function in @clack/core intentionally skips restoring stdin from raw mode on Windows, leaving it stuck after spinner stop(). This causes the TUI to freeze after repeated spinner usage as keypresses are consumed as raw data instead of generating proper events. Upstream: bombshell-dev/clack#408, PR bombshell-dev/clack#424 Co-Authored-By: Claude Opus 4.5 --- bun.lock | 3 +++ package.json | 3 +++ patches/@clack%2Fcore@1.0.0.patch | 13 +++++++++++++ 3 files changed, 19 insertions(+) create mode 100644 patches/@clack%2Fcore@1.0.0.patch diff --git a/bun.lock b/bun.lock index a63222a..9aee301 100644 --- a/bun.lock +++ b/bun.lock @@ -25,6 +25,9 @@ }, }, }, + "patchedDependencies": { + "@clack/core@1.0.0": "patches/@clack%2Fcore@1.0.0.patch", + }, "packages": { "@biomejs/biome": ["@biomejs/biome@1.9.4", "", { "optionalDependencies": { "@biomejs/cli-darwin-arm64": "1.9.4", "@biomejs/cli-darwin-x64": "1.9.4", "@biomejs/cli-linux-arm64": "1.9.4", "@biomejs/cli-linux-arm64-musl": "1.9.4", "@biomejs/cli-linux-x64": "1.9.4", "@biomejs/cli-linux-x64-musl": "1.9.4", "@biomejs/cli-win32-arm64": "1.9.4", "@biomejs/cli-win32-x64": "1.9.4" }, "bin": { "biome": "bin/biome" } }, "sha512-1rkd7G70+o9KkTn5KLmDYXihGoTaIGO9PIIN2ZB7UJxFrWw04CZHPYiMRjYsaDvVV7hP1dYNRLxSANLaBFGpog=="], diff --git a/package.json b/package.json index 1628756..43381d6 100644 --- a/package.json +++ b/package.json @@ -62,5 +62,8 @@ "engines": { "node": ">=18.0.0", "bun": ">=1.0.0" + }, + "patchedDependencies": { + "@clack/core@1.0.0": "patches/@clack%2Fcore@1.0.0.patch" } } diff --git a/patches/@clack%2Fcore@1.0.0.patch b/patches/@clack%2Fcore@1.0.0.patch new file mode 100644 index 0000000..2ce4cdf --- /dev/null +++ b/patches/@clack%2Fcore@1.0.0.patch @@ -0,0 +1,13 @@ +diff --git a/dist/index.mjs b/dist/index.mjs +index 13b8d4d0dcc3a9ec92cc711c11bbdf2a5e43a599..af62036e2d9e7641f7a8cc19c003a40d9cdd1b35 100644 +--- a/dist/index.mjs ++++ b/dist/index.mjs +@@ -7,7 +7,7 @@ import w from"picocolors";import{stdout as R,stdin as q}from"node:process";impor + `).map(i=>Et(i,e,s)).join(` + `)}const At=["up","down","left","right","space","enter","cancel"],_={actions:new Set(At),aliases:new Map([["k","up"],["j","down"],["h","left"],["l","right"],["","cancel"],["escape","cancel"]]),messages:{cancel:"Canceled",error:"Something went wrong"},withGuide:!0};function It(t){if(t.aliases!==void 0){const e=t.aliases;for(const s in e){if(!Object.hasOwn(e,s))continue;const i=e[s];_.actions.has(i)&&(_.aliases.has(s)||_.aliases.set(s,i))}}if(t.messages!==void 0){const e=t.messages;e.cancel!==void 0&&(_.messages.cancel=e.cancel),e.error!==void 0&&(_.messages.error=e.error)}t.withGuide!==void 0&&(_.withGuide=t.withGuide!==!1)}function H(t,e){if(typeof t=="string")return _.aliases.get(t)===e;for(const s of t)if(s!==void 0&&H(s,e))return!0;return!1}function _t(t,e){if(t===e)return;const s=t.split(` + `),i=e.split(` +-`),r=Math.max(s.length,i.length),n=[];for(let u=0;u{const E=String(u);if(H([E,a,l],"cancel")){i&&e.write(I.show),process.exit(0);return}if(!s)return;const g=a==="return"?0:-1,m=a==="return"?-1:0;k.moveCursor(e,g,m,()=>{k.clearLine(e,1,()=>{t.once("keypress",n)})})};return i&&e.write(I.hide),t.once("keypress",n),()=>{t.off("keypress",n),i&&e.write(I.show),t instanceof J&&t.isTTY&&!bt&&t.setRawMode(!1),r.terminal=!1,r.close()}}const rt=t=>"columns"in t&&typeof t.columns=="number"?t.columns:80,nt=t=>"rows"in t&&typeof t.rows=="number"?t.rows:20;function Bt(t,e,s,i=s){const r=rt(t??R);return K(e,r-s.length,{hard:!0,trim:!1}).split(` ++`),r=Math.max(s.length,i.length),n=[];for(let u=0;u{const E=String(u);if(H([E,a,l],"cancel")){i&&e.write(I.show),process.exit(0);return}if(!s)return;const g=a==="return"?0:-1,m=a==="return"?-1:0;k.moveCursor(e,g,m,()=>{k.clearLine(e,1,()=>{t.once("keypress",n)})})};return i&&e.write(I.hide),t.once("keypress",n),()=>{t.off("keypress",n),i&&e.write(I.show),t instanceof J&&t.isTTY&&t.setRawMode(!1),r.terminal=!1,r.close()}}const rt=t=>"columns"in t&&typeof t.columns=="number"?t.columns:80,nt=t=>"rows"in t&&typeof t.rows=="number"?t.rows:20;function Bt(t,e,s,i=s){const r=rt(t??R);return K(e,r-s.length,{hard:!0,trim:!1}).split(` + `).map((n,u)=>`${u===0?i:s}${n}`).join(` + `)}class x{input;output;_abortSignal;rl;opts;_render;_track=!1;_prevFrame="";_subscribers=new Map;_cursor=0;state="initial";error="";value;userInput="";constructor(e,s=!0){const{input:i=q,output:r=R,render:n,signal:u,...a}=e;this.opts=a,this.onKeypress=this.onKeypress.bind(this),this.close=this.close.bind(this),this.render=this.render.bind(this),this._render=n.bind(this),this._track=s,this._abortSignal=u,this.input=i,this.output=r}unsubscribe(){this._subscribers.clear()}setSubscriber(e,s){const i=this._subscribers.get(e)??[];i.push(s),this._subscribers.set(e,i)}on(e,s){this.setSubscriber(e,{cb:s})}once(e,s){this.setSubscriber(e,{cb:s,once:!0})}emit(e,...s){const i=this._subscribers.get(e)??[],r=[];for(const n of i)n.cb(...s),n.once&&r.push(()=>i.splice(i.indexOf(n),1));for(const n of r)n()}prompt(){return new Promise(e=>{if(this._abortSignal){if(this._abortSignal.aborted)return this.state="cancel",this.close(),e(z);this._abortSignal.addEventListener("abort",()=>{this.state="cancel",this.close()},{once:!0})}this.rl=ot.createInterface({input:this.input,tabSize:2,prompt:"",escapeCodeTimeout:50,terminal:!0}),this.rl.prompt(),this.opts.initialUserInput!==void 0&&this._setUserInput(this.opts.initialUserInput,!0),this.input.on("keypress",this.onKeypress),T(this.input,!0),this.output.on("resize",this.render),this.render(),this.once("submit",()=>{this.output.write(I.show),this.output.off("resize",this.render),T(this.input,!1),e(this.value)}),this.once("cancel",()=>{this.output.write(I.show),this.output.off("resize",this.render),T(this.input,!1),e(z)})})}_isActionKey(e,s){return e===" "}_setValue(e){this.value=e,this.emit("value",this.value)}_setUserInput(e,s){this.userInput=e??"",this.emit("userInput",this.userInput),s&&this._track&&this.rl&&(this.rl.write(this.userInput),this._cursor=this.rl.cursor)}_clearUserInput(){this.rl?.write(null,{ctrl:!0,name:"u"}),this._setUserInput("")}onKeypress(e,s){if(this._track&&s.name!=="return"&&(s.name&&this._isActionKey(e,s)&&this.rl?.write(null,{ctrl:!0,name:"h"}),this._cursor=this.rl?.cursor??0,this._setUserInput(this.rl?.line)),this.state==="error"&&(this.state="active"),s?.name&&(!this._track&&_.aliases.has(s.name)&&this.emit("cursor",_.aliases.get(s.name)),_.actions.has(s.name)&&this.emit("cursor",s.name)),e&&(e.toLowerCase()==="y"||e.toLowerCase()==="n")&&this.emit("confirm",e.toLowerCase()==="y"),this.emit("key",e?.toLowerCase(),s),s?.name==="return"){if(this.opts.validate){const i=this.opts.validate(this.value);i&&(this.error=i instanceof Error?i.message:i,this.state="error",this.rl?.write(this.userInput))}this.state!=="error"&&(this.state="submit")}H([e,s?.name,s?.sequence],"cancel")&&(this.state="cancel"),(this.state==="submit"||this.state==="cancel")&&this.emit("finalize"),this.render(),(this.state==="submit"||this.state==="cancel")&&this.close()}close(){this.input.unpipe(),this.input.removeListener("keypress",this.onKeypress),this.output.write(` + `),T(this.input,!1),this.rl?.close(),this.rl=void 0,this.emit(`${this.state}`,this.value),this.unsubscribe()}restoreCursor(){const e=K(this._prevFrame,process.stdout.columns,{hard:!0,trim:!1}).split(`