codex-1up 0.3.10 → 0.3.12

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/dist/main.js CHANGED
@@ -1,23 +1,25 @@
1
- import{runMain as Fn}from"citty";import{defineCommand as Mn}from"citty";import{defineCommand as gn}from"citty";import{resolve as ut}from"path";import{promises as Zt}from"fs";import*as Be from"os";import*as eo from"toml";import*as F from"@clack/prompts";import Yo from"os";import{resolve as Jo}from"path";import{promises as Xo}from"fs";import*as Ut from"toml";import Ot from"fs-extra";import*as tt from"path";import*as Mt from"os";import{createWriteStream as go}from"fs";function Se(e){let t=null;try{t=go(e,{flags:"a",mode:384})}catch(n){}let o=(n,i)=>{let s=n?`${n} ${i}
1
+ import{runMain as Wn}from"citty";import{defineCommand as Fn}from"citty";import{defineCommand as hn}from"citty";import{resolve as ut}from"path";import{promises as eo}from"fs";import*as Be from"os";import*as to from"toml";import*as F from"@clack/prompts";import Jo from"os";import{resolve as Xo}from"path";import{promises as Qo}from"fs";import*as Vt from"toml";import Mt from"fs-extra";import*as tt from"path";import*as Ft from"os";import{createWriteStream as ho}from"fs";function Se(e){let t=null;try{t=ho(e,{flags:"a",mode:384})}catch(n){}let o=(n,i)=>{let s=n?`${n} ${i}
2
2
  `:`${i}
3
- `;process.stdout.write(s),t&&t.write(s)};return{log:n=>o("",n),info:n=>o("",n),ok:n=>o("\u2714",n),warn:n=>o("\u26A0",n),err:n=>o("\u2716",n)}}import{$ as ee}from"zx";import{which as ho,$ as wo}from"zx";import{spawn as yo}from"child_process";async function S(e){try{return await ho(e),!0}catch{return!1}}async function kt(){return await S("brew")?"brew":await S("apt-get")?"apt":await S("dnf")?"dnf":await S("pacman")?"pacman":await S("zypper")?"zypper":"none"}function de(e){return typeof process.getuid=="function"&&process.getuid()===0?{cmd:e,argsPrefix:[]}:{cmd:"sudo",argsPrefix:[e]}}async function vt(e){if(await S("pnpm"))try{let o=(await wo`pnpm bin -g`.quiet()).stdout.trim();return o?{pm:"pnpm",binDir:o}:(e?.warn('Detected pnpm but global bin dir is not configured; skipping global Node installs to avoid duplicates. Run "pnpm setup" then re-run.'),{pm:"none",reason:"pnpm-misconfigured"})}catch{return e?.warn('Detected pnpm but global bin dir is not configured; skipping global Node installs to avoid duplicates. Run "pnpm setup" then re-run.'),{pm:"none",reason:"pnpm-error"}}return await S("npm")?{pm:"npm",reason:"npm-default"}:{pm:"none",reason:"not-found"}}async function I(e,t,o={dryRun:!1}){if(o.dryRun){let i=[e,...t].map(s=>s.includes(" ")?`"${s}"`:s).join(" ");o.logger?.log(`[dry-run] ${i}`);return}let n=yo(e,t,{stdio:"inherit",cwd:o.cwd||process.cwd(),shell:!1});await new Promise((i,s)=>{n.on("error",s),n.on("exit",r=>{if(r===0)return i();s(new Error(`Command failed (${r}): ${e} ${t.join(" ")}`))})})}function O(e){let t=new Date().toISOString().replace(/[:.]/g,"-").slice(0,-5);return`${e}.backup.${t}`}import Ct from"fs-extra";import*as $e from"path";import*as ce from"os";import*as te from"@clack/prompts";async function St(e){let t=await S("node"),o=await S("npm");if(t&&o){let i=(await ee`node -v`).stdout.trim();e.logger.ok(`Node.js present (${i})`);return}switch(e.options.installNode){case"nvm":await bo(e);break;case"brew":await ko(e);break;case"skip":e.logger.warn("Skipping Node installation; please install Node 18+ manually");return}if(await S("node")){let i=(await ee`node -v`).stdout.trim();e.logger.ok(`Node.js installed (${i})`)}else throw e.logger.err("Node installation failed"),new Error("Node.js installation failed")}async function bo(e){if(e.logger.info("Installing Node.js via nvm"),e.options.dryRun){e.logger.log("[dry-run] install nvm + Node LTS");return}let t=process.stdout.isTTY&&!e.options.dryRun&&!e.options.skipConfirmation&&!e.options.assumeYes,o=$e.join(e.homeDir,".nvm");if(!await Ct.pathExists(o)){if(t){let i=await te.confirm({message:"This will download and run the nvm installer script (from GitHub) and then install Node LTS. Continue?",initialValue:!0});if(te.isCancel(i)||!i)throw new Error("Node installation aborted by user")}e.logger.info("Installing nvm..."),await ee`bash -c "curl -fsSL https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash"`}let n=`export NVM_DIR="${o}" && [ -s "$NVM_DIR/nvm.sh" ] && . "$NVM_DIR/nvm.sh" && nvm install --lts`;await ee`bash -c ${n}`}async function ko(e){e.logger.info("Installing Node.js via Homebrew");let t=process.stdout.isTTY&&!e.options.dryRun&&!e.options.skipConfirmation&&!e.options.assumeYes;if(!await S("brew"))if(ce.platform()==="darwin"){if(e.logger.info("Homebrew not found; installing Homebrew"),e.options.dryRun){e.logger.log("[dry-run] install Homebrew");return}if(t){let n=await te.confirm({message:"This will download and run the official Homebrew installer script (from GitHub). Continue?",initialValue:!0});if(te.isCancel(n)||!n)throw new Error("Homebrew installation aborted by user")}await ee`/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"`;let o=ce.platform()==="darwin"&&ce.arch()==="arm64"?"/opt/homebrew/bin/brew":"/usr/local/bin/brew";if(await Ct.pathExists(o)){let n=$e.dirname(o);process.env.PATH=`${n}:${process.env.PATH||""}`;try{let s=(await ee`${o} shellenv`).stdout.trim().match(/export PATH="([^"]+)"/);s&&(process.env.PATH=`${s[1]}:${process.env.PATH||""}`)}catch(i){}}}else throw new Error("Homebrew is only available on macOS");await I("brew",["install","node"],{dryRun:e.options.dryRun,logger:e.logger})}import*as oe from"@clack/prompts";import{$ as Ke}from"zx";var He="@openai/codex";async function xe(e){let t=await Co(),o=await vo(e),n=!!(t.found&&t.version&&o&&t.version!==o);return{found:t.found,version:t.version,latest:o,updateAvailable:n}}async function vo(e){try{let o=(await Ke`npm view ${He} version`.quiet()).stdout.trim();if(!o){e?.warn("Could not fetch latest Codex CLI version; skipping upgrade check");return}return o}catch(t){e?.warn(`Error checking latest Codex CLI version: ${t}`);return}}async function Co(){if(!await S("codex"))return{found:!1};let t="";try{let o=await Ke`codex --version`.quiet().nothrow();t=So(o.stdout||"")}catch(o){}if(!t)try{let o=await Ke`npm ls -g ${He} --depth=0 --json`.quiet().nothrow();t=JSON.parse(o.stdout||"{}").dependencies?.[He]?.version||""}catch(o){}return{found:!0,version:t||void 0}}function So(e){let t=e.match(/(\d+\.\d+\.\d+(?:[-+][0-9A-Za-z.-]+)?)/);return t?t[1]:""}import*as Ie from"@clack/prompts";async function Te(e){let t=await vt(e.logger);if(t.pm==="pnpm")return"pnpm";if(t.pm==="npm")return"npm";if(t.pm==="none"&&t.reason?.startsWith("pnpm-")){if(e.interactive){let o=await Ie.select({message:"pnpm is installed but its global bin is not configured. How should we proceed?",initialValue:"npm",options:[{value:"npm",label:"Use npm for global installs this run"},{value:"skip",label:'Skip global installs (run "pnpm setup" then re-run)'}]});return Ie.isCancel(o)||o==="skip"?(e.logger?.warn('Skipping global Node installs; pnpm is misconfigured. Run "pnpm setup" then re-run.'),"none"):(e.logger?.info("pnpm misconfigured; falling back to npm for global installs."),"npm")}return e.logger?.warn('pnpm detected but global bin dir is not configured; falling back to npm for this run. Run "pnpm setup" to use pnpm.'),"npm"}return"none"}var $t="@openai/codex";async function xt(e){if(e.options.installCodexCli==="no"){e.logger.info("Skipping Codex CLI install (user choice)");return}let t=process.stdout.isTTY&&!e.options.dryRun&&!e.options.skipConfirmation&&!e.options.assumeYes,o=await xe(e.logger);if(o.found){let a=o.version?`v${o.version}`:"unknown version";e.logger.info(`Found Codex CLI ${a}. Checking for newer version...`)}else e.logger.info("Codex CLI not found.");let n=!1,i=!1;if(o.found)if(o.updateAvailable){let a=o.latest?`v${o.latest}`:"a newer version";if(e.options.installCodexCli==="yes")i=!0;else if(t){let p=await oe.confirm({message:`Codex CLI ${o.version} found; latest is ${a}. Update now?`,initialValue:!0});oe.isCancel(p)?e.logger.info("Codex CLI update cancelled; keeping existing version."):p?i=!0:e.logger.info("Keeping existing Codex CLI version as requested.")}else i=!0}else o.found&&(o.latest&&o.version?e.logger.ok(`Codex CLI up-to-date (${o.version})`):e.logger.ok("Codex CLI found; unable to verify latest version."));else if(e.options.installCodexCli==="yes")n=!0;else if(t){let a=await oe.confirm({message:"Codex CLI not found. Install now?",initialValue:!0});oe.isCancel(a)?e.logger.info("Codex CLI install cancelled."):a?n=!0:e.logger.info("Skipping Codex CLI install.")}else n=!0;let s=[];if((n||i)&&(o.latest?s.push(`${$t}@${o.latest}`):s.push($t)),s.length===0)return;let r=await Te({logger:e.logger,interactive:process.stdout.isTTY&&!e.options.dryRun&&!e.options.skipConfirmation&&!e.options.assumeYes});r==="none"?e.logger.warn("Skipping global Node installs because no supported package manager was found."):r==="pnpm"?(e.logger.info("Installing/updating Codex CLI via pnpm"),await I("pnpm",["add","-g",...s],{dryRun:e.options.dryRun,logger:e.logger})):(e.logger.info("Installing/updating Codex CLI via npm"),await I("npm",["install","-g",...s],{dryRun:e.options.dryRun,logger:e.logger})),await S("codex")?e.logger.ok("Codex CLI installed"):e.logger.err("Codex CLI not found after install")}var It=[{id:"rg",label:"rg",bins:["rg"],packages:{brew:["ripgrep"],apt:["ripgrep"],dnf:["ripgrep"],pacman:["ripgrep"],zypper:["ripgrep"]}},{id:"fd",label:"fd",bins:["fd","fdfind"],packages:{brew:["fd"],apt:["fd-find"],dnf:["fd-find"],pacman:["fd"],zypper:["fd"]}},{id:"fzf",label:"fzf",bins:["fzf"],packages:{brew:["fzf"],apt:["fzf"],dnf:["fzf"],pacman:["fzf"],zypper:["fzf"]}},{id:"jq",label:"jq",bins:["jq"],packages:{brew:["jq"],apt:["jq"],dnf:["jq"],pacman:["jq"],zypper:["jq"]}},{id:"yq",label:"yq",bins:["yq"],packages:{brew:["yq"],apt:["yq"],dnf:["yq"],pacman:["yq"],zypper:["yq"]}},{id:"ast-grep",label:"ast-grep",bins:["ast-grep","sg"],packages:{brew:["ast-grep"],apt:["ast-grep"],dnf:["ast-grep"],pacman:["ast-grep"],zypper:["ast-grep"]}},{id:"bat",label:"bat",bins:["bat","batcat"],packages:{brew:["bat"],apt:["bat"],dnf:["bat"],pacman:["bat"],zypper:["bat"]}},{id:"git",label:"git",bins:["git"],packages:{brew:["git"],apt:["git"],dnf:["git"],pacman:["git"],zypper:["git"]}},{id:"git-delta",label:"git-delta",bins:["delta"],packages:{brew:["git-delta"],apt:["git-delta"],dnf:["git-delta"],pacman:["git-delta"],zypper:["git-delta"]}},{id:"gh",label:"gh",bins:["gh"],packages:{brew:["gh"],apt:["gh"],dnf:["gh"],pacman:["github-cli"],zypper:["gh"]}}],$o=new Set(It.map(e=>e.id));function Tt(e){return $o.has(e)}function ne(){return It}import*as Je from"path";import Ye from"fs-extra";import{which as xo}from"zx";async function Pe(e){if(e.options.installTools==="skip"){e.logger.info("Skipping developer tool installs (user choice)");return}let t=Io(e.options.installTools,e.options.toolsSelected);if(t.length===0){e.logger.info("Skipping developer tool installs (no tools selected)");return}let o=await kt();if(e.logger.info(`Detected package manager: ${o}`),o==="none"){e.logger.warn("Could not detect a supported package manager; please install tools manually");return}let n=ne().filter(s=>t.includes(s.id)),i=To(n,o);if(i.length>0)switch(o!=="brew"&&(typeof process.getuid=="function"&&process.getuid()===0||e.logger.warn("Package installation may require sudo password. Please enter it when prompted.")),o){case"brew":await I("brew",["update"],{dryRun:e.options.dryRun,logger:e.logger}),await I("brew",["install",...i],{dryRun:e.options.dryRun,logger:e.logger});break;case"apt":{t.includes("gh")&&!await S("gh")&&await Ao(e);let{cmd:s,argsPrefix:r}=de("apt-get");e.logger.info("Running apt-get update...");try{await I(s,[...r,"update","-y"],{dryRun:e.options.dryRun,logger:e.logger})}catch{e.logger.warn(`apt-get update failed; install tools manually: ${i.join(", ")}`);break}for(let a of i)try{await I(s,[...r,"install","-y",a],{dryRun:e.options.dryRun,logger:e.logger})}catch{e.logger.warn(`apt-get install failed for ${a}; install manually if needed.`)}}break;case"dnf":{let{cmd:s,argsPrefix:r}=de("dnf");await I(s,[...r,"install","-y",...i],{dryRun:e.options.dryRun,logger:e.logger}).catch(()=>{})}break;case"pacman":{let{cmd:s,argsPrefix:r}=de("pacman");await I(s,[...r,"-Sy","--noconfirm",...i],{dryRun:e.options.dryRun,logger:e.logger}).catch(()=>{})}break;case"zypper":{let{cmd:s,argsPrefix:r}=de("zypper");await I(s,[...r,"refresh"],{dryRun:e.options.dryRun,logger:e.logger}),await I(s,[...r,"install","-y",...i],{dryRun:e.options.dryRun,logger:e.logger}).catch(()=>{})}break}t.includes("fd")&&await Pt(e,"fdfind","fd"),t.includes("bat")&&await Pt(e,"batcat","bat"),await Po(e,n)}function Io(e,t){return e==="all"?ne().map(o=>o.id):e==="select"?t?[...t]:[]:[]}function To(e,t){let o=[];for(let n of e){let i=n.packages[t]||[];for(let s of i)o.includes(s)||o.push(s)}return o}async function Pt(e,t,o){if(!await S(t)||await S(o))return;let n=Je.join(e.homeDir,".local","bin");await Ye.ensureDir(n);let i=Je.join(n,o);if(await Ye.pathExists(i))return;let s=t;try{s=await xo(t)}catch(r){}if(e.options.dryRun){e.logger.log(`[dry-run] ln -s ${s} ${i}`);return}await Ye.symlink(s,i),e.logger.ok(`${o} alias created at ~/.local/bin/${o}`)}async function Po(e,t){for(let o of t)await Ro(o)?e.logger.ok(`${o.id} \u2713`):e.logger.warn(`${o.id} not detected after install`)}async function Ro(e){for(let t of e.bins)if(await S(t))return!0;return!1}async function Ao(e){let t=["set -euo pipefail","if [ -f /etc/apt/sources.list.d/github-cli.list ]; then exit 0; fi",'SUDO=""','if [ "$(id -u)" -ne 0 ]; then SUDO="sudo"; fi',"$SUDO mkdir -p -m 755 /etc/apt/keyrings","if command -v curl >/dev/null 2>&1; then"," curl -fsSL https://cli.github.com/packages/githubcli-archive-keyring.gpg | $SUDO tee /etc/apt/keyrings/githubcli-archive-keyring.gpg >/dev/null","elif command -v wget >/dev/null 2>&1; then"," wget -qO- https://cli.github.com/packages/githubcli-archive-keyring.gpg | $SUDO tee /etc/apt/keyrings/githubcli-archive-keyring.gpg >/dev/null","else",' echo "Missing curl/wget; cannot set up GitHub CLI apt repo automatically." 1>&2'," exit 0","fi","$SUDO chmod go+r /etc/apt/keyrings/githubcli-archive-keyring.gpg",'ARCH="$(dpkg --print-architecture)"','echo "deb [arch=${ARCH} signed-by=/etc/apt/keyrings/githubcli-archive-keyring.gpg] https://cli.github.com/packages stable main" | $SUDO tee /etc/apt/sources.list.d/github-cli.list >/dev/null'].join(`
4
- `);try{await I("bash",["-lc",t],{dryRun:e.options.dryRun,logger:e.logger})}catch{e.logger.warn("Failed to set up GitHub CLI apt repo; will still try apt-get install gh (may fail).")}}import fe from"fs-extra";import*as Ee from"path";var Xe={balanced:{root:[["approval_policy",'"on-request"'],["sandbox_mode",'"workspace-write"'],["model",'"gpt-5.2-codex"'],["model_reasoning_effort",'"medium"'],["model_reasoning_summary",'"detailed"']],features:[["web_search_request","true"]],tables:{sandbox_workspace_write:[["network_access","true"]]}},safe:{root:[["approval_policy",'"on-failure"'],["sandbox_mode",'"read-only"'],["model",'"gpt-5.2-codex"'],["model_reasoning_effort",'"medium"'],["model_reasoning_summary",'"detailed"']],features:[["web_search_request","false"]]},yolo:{root:[["approval_policy",'"never"'],["sandbox_mode",'"danger-full-access"'],["model",'"gpt-5.2-codex"'],["model_reasoning_effort",'"high"'],["model_reasoning_summary",'"detailed"']],features:[["web_search_request","true"]]}},Eo=`# ~/.codex/config.toml \u2014 managed by codex-1up (patch mode)
5
- `;async function Et(e){let t=Ee.join(e.homeDir,".codex","config.toml");await fe.ensureDir(Ee.dirname(t));let o=await fe.pathExists(t),n=o?await fe.readFile(t,"utf8"):Eo,i=Go(n),s=Mo(i.toml),r=new Qe(s.toml),a=i.changed||s.changed;if(a=No(r,e.options.profileScope,e.options.profile,e.options.profileMode,e.options.profilesSelected)||a,a=Lo(r,e.options.profile,e.options.setDefaultProfile)||a,a=Do(r,e.options.notificationSound)||a,a=_o(r)||a,!a){e.logger.info("Config already up to date; no changes needed.");return}let p=r.content();if(e.options.dryRun){e.logger.log(`[dry-run] write ${t}`),e.logger.log("[dry-run] config content omitted"),e.logger.log(`[dry-run] would write ${p.length} bytes`);return}if(o){let l=O(t);await fe.copy(t,l),e.logger.info(`Backed up current config to ${l}`)}await fe.writeFile(t,p,"utf8"),e.logger.ok("Updated ~/.codex/config.toml with requested settings.")}function No(e,t,o,n,i){let s=[];if(t==="all")s=Object.keys(Xe);else if(t==="selected")s=i||[];else{if(o==="skip")return!1;s=[o]}if(s.length===0)return!1;let r=!1;for(let a of s){let p=Xe[a];if(n==="overwrite"){r=e.replaceTable(`profiles.${a}`,p.root)||r,r=e.replaceTable(`profiles.${a}.features`,p.features)||r;for(let[l,c]of Object.entries(p.tables||{}))r=e.replaceTable(`profiles.${a}.${l}`,c)||r}else{e.ensureTable(`profiles.${a}`);for(let[l,c]of p.root)r=e.setKey(`profiles.${a}`,l,c,{mode:"if-missing"})||r;e.ensureTable(`profiles.${a}.features`);for(let[l,c]of p.features)r=e.setKey(`profiles.${a}.features`,l,c,{mode:"if-missing"})||r;for(let[l,c]of Object.entries(p.tables||{})){e.ensureTable(`profiles.${a}.${l}`);for(let[d,u]of c)r=e.setKey(`profiles.${a}.${l}`,d,u,{mode:"if-missing"})||r}}}return r}function Lo(e,t,o){return!o||t==="skip"?!1:e.setRootKey("profile",`"${t}"`,{mode:"force"})}function Do(e,t){if(!t||t==="none")return!1;e.ensureTable("tui");let o=e.getValue("tui","notifications");if(o){let n=o.trim().toLowerCase();if(n.startsWith("true")||n.startsWith("["))return!1}return e.setKey("tui","notifications","true",{mode:"force"})}var Qe=class{text;constructor(t){this.text=t||""}content(){return Oo(this.text)}ensureTable(t){if(this.hasTable(t))return!1;let o=this.text.length===0?"":Ae(this.text);return this.text=o+`[${t}]
6
- `,!0}setKey(t,o,n,i){let s=ie(this.text,t);if(!s)return this.ensureTable(t),this.setKey(t,o,n,i);let r=this.text.slice(s.start,s.end),p=new RegExp(`^\\s*${se(o)}\\s*=.*$`,"m").exec(r);if(p){if(i.mode==="if-missing")return!1;let C=this.text,A=s.start+p.index,D=A+p[0].length;return this.text=C.slice(0,A)+`${o} = ${n}`+C.slice(D),this.text!==C}let l=this.text,c=s.end,d=l.slice(0,c),u=l.slice(c),h=d.length>0&&!d.endsWith(`
7
- `),v=u.length>0&&!u.startsWith(`
3
+ `;process.stdout.write(s),t&&t.write(s)};return{log:n=>o("",n),info:n=>o("",n),ok:n=>o("\u2714",n),warn:n=>o("\u26A0",n),err:n=>o("\u2716",n)}}import{$ as ee}from"zx";import{which as wo,$ as yo}from"zx";import{spawn as bo}from"child_process";async function v(e){try{return await wo(e),!0}catch{return!1}}function kt(){return process.platform==="darwin"}async function vt(){return await v("brew")?"brew":await v("apt-get")?"apt":await v("dnf")?"dnf":await v("pacman")?"pacman":await v("zypper")?"zypper":"none"}function de(e){return typeof process.getuid=="function"&&process.getuid()===0?{cmd:e,argsPrefix:[]}:{cmd:"sudo",argsPrefix:[e]}}async function Ct(e){if(await v("pnpm"))try{let o=(await yo`pnpm bin -g`.quiet()).stdout.trim();return o?{pm:"pnpm",binDir:o}:(e?.warn('Detected pnpm but global bin dir is not configured; skipping global Node installs to avoid duplicates. Run "pnpm setup" then re-run.'),{pm:"none",reason:"pnpm-misconfigured"})}catch{return e?.warn('Detected pnpm but global bin dir is not configured; skipping global Node installs to avoid duplicates. Run "pnpm setup" then re-run.'),{pm:"none",reason:"pnpm-error"}}return await v("npm")?{pm:"npm",reason:"npm-default"}:{pm:"none",reason:"not-found"}}async function I(e,t,o={dryRun:!1}){if(o.dryRun){let i=[e,...t].map(s=>s.includes(" ")?`"${s}"`:s).join(" ");o.logger?.log(`[dry-run] ${i}`);return}let n=bo(e,t,{stdio:"inherit",cwd:o.cwd||process.cwd(),shell:!1});await new Promise((i,s)=>{n.on("error",s),n.on("exit",r=>{if(r===0)return i();s(new Error(`Command failed (${r}): ${e} ${t.join(" ")}`))})})}function O(e){let t=new Date().toISOString().replace(/[:.]/g,"-").slice(0,-5);return`${e}.backup.${t}`}import St from"fs-extra";import*as $e from"path";import*as ce from"os";import*as te from"@clack/prompts";async function $t(e){let t=await v("node"),o=await v("npm");if(t&&o){let i=(await ee`node -v`).stdout.trim();e.logger.ok(`Node.js present (${i})`);return}switch(e.options.installNode){case"nvm":await ko(e);break;case"brew":await vo(e);break;case"skip":e.logger.warn("Skipping Node installation; please install Node 18+ manually");return}if(await v("node")){let i=(await ee`node -v`).stdout.trim();e.logger.ok(`Node.js installed (${i})`)}else throw e.logger.err("Node installation failed"),new Error("Node.js installation failed")}async function ko(e){if(e.logger.info("Installing Node.js via nvm"),e.options.dryRun){e.logger.log("[dry-run] install nvm + Node LTS");return}let t=process.stdout.isTTY&&!e.options.dryRun&&!e.options.skipConfirmation&&!e.options.assumeYes,o=$e.join(e.homeDir,".nvm");if(!await St.pathExists(o)){if(t){let i=await te.confirm({message:"This will download and run the nvm installer script (from GitHub) and then install Node LTS. Continue?",initialValue:!0});if(te.isCancel(i)||!i)throw new Error("Node installation aborted by user")}e.logger.info("Installing nvm..."),await ee`bash -c "curl -fsSL https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash"`}let n=`export NVM_DIR="${o}" && [ -s "$NVM_DIR/nvm.sh" ] && . "$NVM_DIR/nvm.sh" && nvm install --lts`;await ee`bash -c ${n}`}async function vo(e){e.logger.info("Installing Node.js via Homebrew");let t=process.stdout.isTTY&&!e.options.dryRun&&!e.options.skipConfirmation&&!e.options.assumeYes;if(!await v("brew"))if(ce.platform()==="darwin"){if(e.logger.info("Homebrew not found; installing Homebrew"),e.options.dryRun){e.logger.log("[dry-run] install Homebrew");return}if(t){let n=await te.confirm({message:"This will download and run the official Homebrew installer script (from GitHub). Continue?",initialValue:!0});if(te.isCancel(n)||!n)throw new Error("Homebrew installation aborted by user")}await ee`/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"`;let o=ce.platform()==="darwin"&&ce.arch()==="arm64"?"/opt/homebrew/bin/brew":"/usr/local/bin/brew";if(await St.pathExists(o)){let n=$e.dirname(o);process.env.PATH=`${n}:${process.env.PATH||""}`;try{let s=(await ee`${o} shellenv`).stdout.trim().match(/export PATH="([^"]+)"/);s&&(process.env.PATH=`${s[1]}:${process.env.PATH||""}`)}catch(i){}}}else throw new Error("Homebrew is only available on macOS");await I("brew",["install","node"],{dryRun:e.options.dryRun,logger:e.logger})}import*as oe from"@clack/prompts";import{$ as Ke}from"zx";var He="@openai/codex";async function xe(e){let t=await So(),o=await Co(e),n=!!(t.found&&t.version&&o&&t.version!==o);return{found:t.found,version:t.version,latest:o,updateAvailable:n}}async function Co(e){try{let o=(await Ke`npm view ${He} version`.quiet()).stdout.trim();if(!o){e?.warn("Could not fetch latest Codex CLI version; skipping upgrade check");return}return o}catch(t){e?.warn(`Error checking latest Codex CLI version: ${t}`);return}}async function So(){if(!await v("codex"))return{found:!1};let t="";try{let o=await Ke`codex --version`.quiet().nothrow();t=$o(o.stdout||"")}catch(o){}if(!t)try{let o=await Ke`npm ls -g ${He} --depth=0 --json`.quiet().nothrow();t=JSON.parse(o.stdout||"{}").dependencies?.[He]?.version||""}catch(o){}return{found:!0,version:t||void 0}}function $o(e){let t=e.match(/(\d+\.\d+\.\d+(?:[-+][0-9A-Za-z.-]+)?)/);return t?t[1]:""}import*as Ie from"@clack/prompts";async function Te(e){let t=await Ct(e.logger);if(t.pm==="pnpm")return"pnpm";if(t.pm==="npm")return"npm";if(t.pm==="none"&&t.reason?.startsWith("pnpm-")){if(e.interactive){let o=await Ie.select({message:"pnpm is installed but its global bin is not configured. How should we proceed?",initialValue:"npm",options:[{value:"npm",label:"Use npm for global installs this run"},{value:"skip",label:'Skip global installs (run "pnpm setup" then re-run)'}]});return Ie.isCancel(o)||o==="skip"?(e.logger?.warn('Skipping global Node installs; pnpm is misconfigured. Run "pnpm setup" then re-run.'),"none"):(e.logger?.info("pnpm misconfigured; falling back to npm for global installs."),"npm")}return e.logger?.warn('pnpm detected but global bin dir is not configured; falling back to npm for this run. Run "pnpm setup" to use pnpm.'),"npm"}return"none"}var xt="@openai/codex";async function It(e){if(e.options.installCodexCli==="no"){e.logger.info("Skipping Codex CLI install (user choice)");return}let t=process.stdout.isTTY&&!e.options.dryRun&&!e.options.skipConfirmation&&!e.options.assumeYes,o=await xe(e.logger);if(o.found){let a=o.version?`v${o.version}`:"unknown version";e.logger.info(`Found Codex CLI ${a}. Checking for newer version...`)}else e.logger.info("Codex CLI not found.");let n=!1,i=!1;if(o.found)if(o.updateAvailable){let a=o.latest?`v${o.latest}`:"a newer version";if(e.options.installCodexCli==="yes")i=!0;else if(t){let p=await oe.confirm({message:`Codex CLI ${o.version} found; latest is ${a}. Update now?`,initialValue:!0});oe.isCancel(p)?e.logger.info("Codex CLI update cancelled; keeping existing version."):p?i=!0:e.logger.info("Keeping existing Codex CLI version as requested.")}else i=!0}else o.found&&(o.latest&&o.version?e.logger.ok(`Codex CLI up-to-date (${o.version})`):e.logger.ok("Codex CLI found; unable to verify latest version."));else if(e.options.installCodexCli==="yes")n=!0;else if(t){let a=await oe.confirm({message:"Codex CLI not found. Install now?",initialValue:!0});oe.isCancel(a)?e.logger.info("Codex CLI install cancelled."):a?n=!0:e.logger.info("Skipping Codex CLI install.")}else n=!0;let s=[];if((n||i)&&(o.latest?s.push(`${xt}@${o.latest}`):s.push(xt)),s.length===0)return;let r=await Te({logger:e.logger,interactive:process.stdout.isTTY&&!e.options.dryRun&&!e.options.skipConfirmation&&!e.options.assumeYes});r==="none"?e.logger.warn("Skipping global Node installs because no supported package manager was found."):r==="pnpm"?(e.logger.info("Installing/updating Codex CLI via pnpm"),await I("pnpm",["add","-g",...s],{dryRun:e.options.dryRun,logger:e.logger})):(e.logger.info("Installing/updating Codex CLI via npm"),await I("npm",["install","-g",...s],{dryRun:e.options.dryRun,logger:e.logger})),await v("codex")?e.logger.ok("Codex CLI installed"):e.logger.err("Codex CLI not found after install")}var Tt=[{id:"rg",label:"rg",bins:["rg"],packages:{brew:["ripgrep"],apt:["ripgrep"],dnf:["ripgrep"],pacman:["ripgrep"],zypper:["ripgrep"]}},{id:"fd",label:"fd",bins:["fd","fdfind"],packages:{brew:["fd"],apt:["fd-find"],dnf:["fd-find"],pacman:["fd"],zypper:["fd"]}},{id:"fzf",label:"fzf",bins:["fzf"],packages:{brew:["fzf"],apt:["fzf"],dnf:["fzf"],pacman:["fzf"],zypper:["fzf"]}},{id:"jq",label:"jq",bins:["jq"],packages:{brew:["jq"],apt:["jq"],dnf:["jq"],pacman:["jq"],zypper:["jq"]}},{id:"yq",label:"yq",bins:["yq"],packages:{brew:["yq"],apt:["yq"],dnf:["yq"],pacman:["yq"],zypper:["yq"]}},{id:"ast-grep",label:"ast-grep",bins:["ast-grep","sg"],packages:{brew:["ast-grep"],apt:["ast-grep"],dnf:["ast-grep"],pacman:["ast-grep"],zypper:["ast-grep"]}},{id:"bat",label:"bat",bins:["bat","batcat"],packages:{brew:["bat"],apt:["bat"],dnf:["bat"],pacman:["bat"],zypper:["bat"]}},{id:"git",label:"git",bins:["git"],packages:{brew:["git"],apt:["git"],dnf:["git"],pacman:["git"],zypper:["git"]}},{id:"git-delta",label:"git-delta",bins:["delta"],packages:{brew:["git-delta"],apt:["git-delta"],dnf:["git-delta"],pacman:["git-delta"],zypper:["git-delta"]}},{id:"gh",label:"gh",bins:["gh"],packages:{brew:["gh"],apt:["gh"],dnf:["gh"],pacman:["github-cli"],zypper:["gh"]}}],xo=new Set(Tt.map(e=>e.id));function Pt(e){return xo.has(e)}function ne(){return Tt}import*as Je from"path";import Ye from"fs-extra";import{which as Io}from"zx";async function Pe(e){if(e.options.installTools==="skip"){e.logger.info("Skipping developer tool installs (user choice)");return}let t=To(e.options.installTools,e.options.toolsSelected);if(t.length===0){e.logger.info("Skipping developer tool installs (no tools selected)");return}if(kt()&&!await v("brew")){e.logger.err(["Homebrew is required on macOS to install developer tools automatically, but `brew` was not found.","Please install Homebrew first, then re-run this command:","",'/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"',"","More info: https://brew.sh/"].join(`
4
+ `));return}let o=t.includes("gh")&&!await v("gh"),n=await vt();if(e.logger.info(`Detected package manager: ${n}`),n==="none"){e.logger.warn("Could not detect a supported package manager; please install tools manually");return}let i=ne().filter(r=>t.includes(r.id)),s=Po(i,n);if(s.length>0)switch(n!=="brew"&&(typeof process.getuid=="function"&&process.getuid()===0||e.logger.warn("Package installation may require sudo password. Please enter it when prompted.")),n){case"brew":await I("brew",["update"],{dryRun:e.options.dryRun,logger:e.logger}),await I("brew",["install",...s],{dryRun:e.options.dryRun,logger:e.logger});break;case"apt":{t.includes("gh")&&!await v("gh")&&await Eo(e);let{cmd:r,argsPrefix:a}=de("apt-get");e.logger.info("Running apt-get update...");try{await I(r,[...a,"update","-y"],{dryRun:e.options.dryRun,logger:e.logger})}catch{e.logger.warn(`apt-get update failed; install tools manually: ${s.join(", ")}`);break}for(let p of s)try{await I(r,[...a,"install","-y",p],{dryRun:e.options.dryRun,logger:e.logger})}catch{e.logger.warn(`apt-get install failed for ${p}; install manually if needed.`)}}break;case"dnf":{let{cmd:r,argsPrefix:a}=de("dnf");await I(r,[...a,"install","-y",...s],{dryRun:e.options.dryRun,logger:e.logger}).catch(()=>{})}break;case"pacman":{let{cmd:r,argsPrefix:a}=de("pacman");await I(r,[...a,"-Sy","--noconfirm",...s],{dryRun:e.options.dryRun,logger:e.logger}).catch(()=>{})}break;case"zypper":{let{cmd:r,argsPrefix:a}=de("zypper");await I(r,[...a,"refresh"],{dryRun:e.options.dryRun,logger:e.logger}),await I(r,[...a,"install","-y",...s],{dryRun:e.options.dryRun,logger:e.logger}).catch(()=>{})}break}t.includes("fd")&&await Rt(e,"fdfind","fd"),t.includes("bat")&&await Rt(e,"batcat","bat"),await Ro(e,i),o&&!e.options.dryRun&&e.logger.info(["GitHub CLI (gh) was not detected before installation.","You should likely do the following in a new terminal:","git --version && gh --version",'git config --global user.name "Your Name"','git config --global user.email "you@example.com"',"git config --global init.defaultBranch main","gh auth login"].join(`
5
+ `))}function To(e,t){return e==="all"?ne().map(o=>o.id):e==="select"?t?[...t]:[]:[]}function Po(e,t){let o=[];for(let n of e){let i=n.packages[t]||[];for(let s of i)o.includes(s)||o.push(s)}return o}async function Rt(e,t,o){if(!await v(t)||await v(o))return;let n=Je.join(e.homeDir,".local","bin");await Ye.ensureDir(n);let i=Je.join(n,o);if(await Ye.pathExists(i))return;let s=t;try{s=await Io(t)}catch(r){}if(e.options.dryRun){e.logger.log(`[dry-run] ln -s ${s} ${i}`);return}await Ye.symlink(s,i),e.logger.ok(`${o} alias created at ~/.local/bin/${o}`)}async function Ro(e,t){for(let o of t)await Ao(o)?e.logger.ok(`${o.id} \u2713`):e.logger.warn(`${o.id} not detected after install`)}async function Ao(e){for(let t of e.bins)if(await v(t))return!0;return!1}async function Eo(e){let t=["set -euo pipefail","if [ -f /etc/apt/sources.list.d/github-cli.list ]; then exit 0; fi",'SUDO=""','if [ "$(id -u)" -ne 0 ]; then SUDO="sudo"; fi',"$SUDO mkdir -p -m 755 /etc/apt/keyrings","if command -v curl >/dev/null 2>&1; then"," curl -fsSL https://cli.github.com/packages/githubcli-archive-keyring.gpg | $SUDO tee /etc/apt/keyrings/githubcli-archive-keyring.gpg >/dev/null","elif command -v wget >/dev/null 2>&1; then"," wget -qO- https://cli.github.com/packages/githubcli-archive-keyring.gpg | $SUDO tee /etc/apt/keyrings/githubcli-archive-keyring.gpg >/dev/null","else",' echo "Missing curl/wget; cannot set up GitHub CLI apt repo automatically." 1>&2'," exit 0","fi","$SUDO chmod go+r /etc/apt/keyrings/githubcli-archive-keyring.gpg",'ARCH="$(dpkg --print-architecture)"','echo "deb [arch=${ARCH} signed-by=/etc/apt/keyrings/githubcli-archive-keyring.gpg] https://cli.github.com/packages stable main" | $SUDO tee /etc/apt/sources.list.d/github-cli.list >/dev/null'].join(`
6
+ `);try{await I("bash",["-lc",t],{dryRun:e.options.dryRun,logger:e.logger})}catch{e.logger.warn("Failed to set up GitHub CLI apt repo; will still try apt-get install gh (may fail).")}}import fe from"fs-extra";import*as Ee from"path";var Xe={balanced:{root:[["approval_policy",'"on-request"'],["sandbox_mode",'"workspace-write"'],["model",'"gpt-5.2-codex"'],["model_reasoning_effort",'"medium"'],["model_reasoning_summary",'"detailed"']],features:[["web_search_request","true"]],tables:{sandbox_workspace_write:[["network_access","true"]]}},safe:{root:[["approval_policy",'"on-failure"'],["sandbox_mode",'"read-only"'],["model",'"gpt-5.2-codex"'],["model_reasoning_effort",'"medium"'],["model_reasoning_summary",'"detailed"']],features:[["web_search_request","false"]]},yolo:{root:[["approval_policy",'"never"'],["sandbox_mode",'"danger-full-access"'],["model",'"gpt-5.2-codex"'],["model_reasoning_effort",'"high"'],["model_reasoning_summary",'"detailed"']],features:[["web_search_request","true"]]}},No=`# ~/.codex/config.toml \u2014 managed by codex-1up (patch mode)
7
+ `;async function Nt(e){let t=Ee.join(e.homeDir,".codex","config.toml");await fe.ensureDir(Ee.dirname(t));let o=await fe.pathExists(t),n=o?await fe.readFile(t,"utf8"):No,i=Go(n),s=Fo(i.toml),r=new Qe(s.toml),a=i.changed||s.changed;if(a=Lo(r,e.options.profileScope,e.options.profile,e.options.profileMode,e.options.profilesSelected)||a,a=Do(r,e.options.profile,e.options.setDefaultProfile)||a,a=jo(r,e.options.notificationSound)||a,a=Oo(r)||a,!a){e.logger.info("Config already up to date; no changes needed.");return}let p=r.content();if(e.options.dryRun){e.logger.log(`[dry-run] write ${t}`),e.logger.log("[dry-run] config content omitted"),e.logger.log(`[dry-run] would write ${p.length} bytes`);return}if(o){let l=O(t);await fe.copy(t,l),e.logger.info(`Backed up current config to ${l}`)}await fe.writeFile(t,p,"utf8"),e.logger.ok("Updated ~/.codex/config.toml with requested settings.")}function Lo(e,t,o,n,i){let s=[];if(t==="all")s=Object.keys(Xe);else if(t==="selected")s=i||[];else{if(o==="skip")return!1;s=[o]}if(s.length===0)return!1;let r=!1;for(let a of s){let p=Xe[a];if(n==="overwrite"){r=e.replaceTable(`profiles.${a}`,p.root)||r,r=e.replaceTable(`profiles.${a}.features`,p.features)||r;for(let[l,c]of Object.entries(p.tables||{}))r=e.replaceTable(`profiles.${a}.${l}`,c)||r}else{e.ensureTable(`profiles.${a}`);for(let[l,c]of p.root)r=e.setKey(`profiles.${a}`,l,c,{mode:"if-missing"})||r;e.ensureTable(`profiles.${a}.features`);for(let[l,c]of p.features)r=e.setKey(`profiles.${a}.features`,l,c,{mode:"if-missing"})||r;for(let[l,c]of Object.entries(p.tables||{})){e.ensureTable(`profiles.${a}.${l}`);for(let[d,u]of c)r=e.setKey(`profiles.${a}.${l}`,d,u,{mode:"if-missing"})||r}}}return r}function Do(e,t,o){return!o||t==="skip"?!1:e.setRootKey("profile",`"${t}"`,{mode:"force"})}function jo(e,t){if(!t||t==="none")return!1;e.ensureTable("tui");let o=e.getValue("tui","notifications");if(o){let n=o.trim().toLowerCase();if(n.startsWith("true")||n.startsWith("["))return!1}return e.setKey("tui","notifications","true",{mode:"force"})}var Qe=class{text;constructor(t){this.text=t||""}content(){return Mo(this.text)}ensureTable(t){if(this.hasTable(t))return!1;let o=this.text.length===0?"":Ae(this.text);return this.text=o+`[${t}]
8
+ `,!0}setKey(t,o,n,i){let s=ie(this.text,t);if(!s)return this.ensureTable(t),this.setKey(t,o,n,i);let r=this.text.slice(s.start,s.end),p=new RegExp(`^\\s*${se(o)}\\s*=.*$`,"m").exec(r);if(p){if(i.mode==="if-missing")return!1;let S=this.text,A=s.start+p.index,D=A+p[0].length;return this.text=S.slice(0,A)+`${o} = ${n}`+S.slice(D),this.text!==S}let l=this.text,c=s.end,d=l.slice(0,c),u=l.slice(c),h=d.length>0&&!d.endsWith(`
9
+ `),C=u.length>0&&!u.startsWith(`
8
10
  `),k=`${h?`
9
11
  `:""}${o} = ${n}
10
- ${v?`
11
- `:""}`;return this.text=d+k+u,this.text!==l}getValue(t,o){let n=ie(this.text,t);if(!n)return;let i=this.text.slice(n.start,n.end),r=new RegExp(`^\\s*${se(o)}\\s*=\\s*(.+)$`,"m").exec(i);return r?r[1]:void 0}getRootValue(t){let o=Rt(this.text),n=this.text.slice(o.start,o.end),s=new RegExp(`^\\s*${se(t)}\\s*=\\s*(.+)$`,"m").exec(n);return s?s[1]:void 0}replaceTable(t,o){let n=o.map(([a,p])=>`${a} = ${p}`).join(`
12
+ ${C?`
13
+ `:""}`;return this.text=d+k+u,this.text!==l}getValue(t,o){let n=ie(this.text,t);if(!n)return;let i=this.text.slice(n.start,n.end),r=new RegExp(`^\\s*${se(o)}\\s*=\\s*(.+)$`,"m").exec(i);return r?r[1]:void 0}getRootValue(t){let o=At(this.text),n=this.text.slice(o.start,o.end),s=new RegExp(`^\\s*${se(t)}\\s*=\\s*(.+)$`,"m").exec(n);return s?s[1]:void 0}replaceTable(t,o){let n=o.map(([a,p])=>`${a} = ${p}`).join(`
12
14
  `),i=`[${t}]
13
15
  ${n}
14
16
 
15
- `,s=this.text,r=ie(this.text,t);if(!r){let a=s.length===0?"":Ae(s);return this.text=a+i,this.text!==s}return this.text=s.slice(0,r.start)+i+s.slice(r.end),this.text!==s}setRootKey(t,o,n){let i=Rt(this.text),s=this.text.slice(i.start,i.end),a=new RegExp(`^\\s*${se(t)}\\s*=.*$`,"m").exec(s);if(a){if(n.mode==="if-missing")return!1;let v=this.text,k=i.start+a.index,C=k+a[0].length;return this.text=v.slice(0,k)+`${t} = ${o}`+v.slice(C),this.text!==v}let p=this.text,l=i.end,c=l>0&&!p.slice(0,l).endsWith(`
17
+ `,s=this.text,r=ie(this.text,t);if(!r){let a=s.length===0?"":Ae(s);return this.text=a+i,this.text!==s}return this.text=s.slice(0,r.start)+i+s.slice(r.end),this.text!==s}setRootKey(t,o,n){let i=At(this.text),s=this.text.slice(i.start,i.end),a=new RegExp(`^\\s*${se(t)}\\s*=.*$`,"m").exec(s);if(a){if(n.mode==="if-missing")return!1;let C=this.text,k=i.start+a.index,S=k+a[0].length;return this.text=C.slice(0,k)+`${t} = ${o}`+C.slice(S),this.text!==C}let p=this.text,l=i.end,c=l>0&&!p.slice(0,l).endsWith(`
16
18
  `),d=p.slice(l),u=d.length>0&&!d.startsWith(`
17
19
  `),h=`${c?`
18
20
  `:""}${t} = ${o}
19
21
  ${u?`
20
- `:""}`;return this.text=p.slice(0,l)+h+d,this.text!==p}hasTable(t){return ie(this.text,t)!==null}};function ie(e,t){let o=/^\s*\[([^\]]+)\]\s*$/gm,n=[],i;for(;i=o.exec(e);)n.push({name:i[1].trim(),index:i.index});for(let s=0;s<n.length;s++)if(n[s].name===t){let r=n[s].index,a=n[s+1]?.index??e.length;return{start:r,end:a}}return null}function Rt(e){let o=/^\s*\[([^\]]+)\]\s*$/gm.exec(e);return o?{start:0,end:o.index}:{start:0,end:e.length}}function se(e){return e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}function jo(e){let t=/^\s*\[profiles\.([^. \]]+)\]\s*$/gm,o=new Set,n;for(;n=t.exec(e);){let i=n[1]?.trim();i&&o.add(i)}return[...o]}function Re(e){if(!e)return;let t=e.trim(),o=/^"([^"]*)"\s*(?:#.*)?$/.exec(t);return o?o[1]:void 0}function At(e){return e?e.endsWith("-codex"):!1}function _o(e){let t=!1,o=Re(e.getRootValue("model"));if(At(o)){let s=Re(e.getRootValue("model_reasoning_summary"));s&&s!=="detailed"&&(t=e.setRootKey("model_reasoning_summary",'"detailed"',{mode:"force"})||t)}let n=e.content(),i=new Set([...Object.keys(Xe),...jo(n)]);for(let s of i){let r=`profiles.${s}`,a=Re(e.getValue(r,"model"));if(!At(a))continue;let p=Re(e.getValue(r,"model_reasoning_summary"));p&&p!=="detailed"&&(t=e.setKey(r,"model_reasoning_summary",'"detailed"',{mode:"force"})||t)}return t}function Oo(e){return e.endsWith(`
22
+ `:""}`;return this.text=p.slice(0,l)+h+d,this.text!==p}hasTable(t){return ie(this.text,t)!==null}};function ie(e,t){let o=/^\s*\[([^\]]+)\]\s*$/gm,n=[],i;for(;i=o.exec(e);)n.push({name:i[1].trim(),index:i.index});for(let s=0;s<n.length;s++)if(n[s].name===t){let r=n[s].index,a=n[s+1]?.index??e.length;return{start:r,end:a}}return null}function At(e){let o=/^\s*\[([^\]]+)\]\s*$/gm.exec(e);return o?{start:0,end:o.index}:{start:0,end:e.length}}function se(e){return e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}function _o(e){let t=/^\s*\[profiles\.([^. \]]+)\]\s*$/gm,o=new Set,n;for(;n=t.exec(e);){let i=n[1]?.trim();i&&o.add(i)}return[...o]}function Re(e){if(!e)return;let t=e.trim(),o=/^"([^"]*)"\s*(?:#.*)?$/.exec(t);return o?o[1]:void 0}function Et(e){return e?e.endsWith("-codex"):!1}function Oo(e){let t=!1,o=Re(e.getRootValue("model"));if(Et(o)){let s=Re(e.getRootValue("model_reasoning_summary"));s&&s!=="detailed"&&(t=e.setRootKey("model_reasoning_summary",'"detailed"',{mode:"force"})||t)}let n=e.content(),i=new Set([...Object.keys(Xe),..._o(n)]);for(let s of i){let r=`profiles.${s}`,a=Re(e.getValue(r,"model"));if(!Et(a))continue;let p=Re(e.getValue(r,"model_reasoning_summary"));p&&p!=="detailed"&&(t=e.setKey(r,"model_reasoning_summary",'"detailed"',{mode:"force"})||t)}return t}function Mo(e){return e.endsWith(`
21
23
  `)?e:e+`
22
24
  `}function Ae(e){let t=e;return t.endsWith(`
23
25
  `)||(t+=`
@@ -25,53 +27,53 @@ ${u?`
25
27
 
26
28
  `)||(t+=`
27
29
  `),t}function Go(e){let t="enable_experimental_windows_sandbox",o="experimental_windows_sandbox";if(!e.includes(t))return{toml:e,changed:!1};let n=e.split(/\r?\n/),i="",s=d=>d==="features"||/^profiles\.[^.]+\.features$/.test(d),r=new Set;for(let d of n){let u=d.match(/^\s*\[([^\]]+)\]\s*$/);if(u){i=u[1].trim();continue}/^\s*#/.test(d)||s(i)&&new RegExp(`^\\s*${o}\\s*=`).test(d)&&r.add(i)}i="";let a=!1,p,l=[];for(let d of n){let u=d.match(/^\s*\[([^\]]+)\]\s*$/);if(u){i=u[1].trim(),l.push(d);continue}if(!/^\s*#/.test(d)){if(i===""){let h=d.match(new RegExp(`^\\s*${t}\\s*=\\s*(.+?)\\s*$`));if(h){p=h[1],a=!0;continue}}if(s(i)&&new RegExp(`^\\s*${t}\\s*=`).test(d)){if(r.has(i)){a=!0;continue}l.push(d.replace(new RegExp(`^(\\s*)${t}(\\s*=\\s*)`),`$1${o}$2`)),a=!0;continue}}l.push(d)}let c=l.join(`
28
- `);if(p!==void 0){let d=ie(c,"features");if(!(()=>{if(!d)return!1;let h=c.slice(d.start,d.end);return new RegExp(`^\\s*${o}\\s*=`,"m").test(h)})()){let h=`${o} = ${p}`;if(d){let v=c.slice(0,d.end),k=c.slice(d.end),C=v.length>0&&!v.endsWith(`
30
+ `);if(p!==void 0){let d=ie(c,"features");if(!(()=>{if(!d)return!1;let h=c.slice(d.start,d.end);return new RegExp(`^\\s*${o}\\s*=`,"m").test(h)})()){let h=`${o} = ${p}`;if(d){let C=c.slice(0,d.end),k=c.slice(d.end),S=C.length>0&&!C.endsWith(`
29
31
  `),A=k.length>0&&!k.startsWith(`
30
- `);c=v+`${C?`
32
+ `);c=C+`${S?`
31
33
  `:""}${h}
32
34
  ${A?`
33
35
  `:""}`+k}else c=(c.length===0?"":Ae(c))+`[features]
34
36
  ${h}
35
- `;a=!0}}return{toml:c,changed:a}}function Mo(e){let t=[{oldKey:"experimental_use_exec_command_tool",newKey:"streamable_shell"},{oldKey:"experimental_use_unified_exec_tool",newKey:"unified_exec"},{oldKey:"experimental_use_rmcp_client",newKey:"rmcp_client"},{oldKey:"include_apply_patch_tool",newKey:"apply_patch_freeform"}];if(!t.some(c=>e.includes(c.oldKey)))return{toml:e,changed:!1};function n(c){let d=c.trim(),u=/^(true|false)\b/i.exec(d);return u?u[1].toLowerCase():d||void 0}let i=e.split(/\r?\n/),s="",r={},a=[],p=!1;for(let c of i){let d=c.match(/^\s*\[([^\]]+)\]\s*$/);if(d){s=d[1].trim(),a.push(c);continue}if(s===""&&!/^\s*#/.test(c)){let u=!1;for(let{oldKey:h,newKey:v}of t){let k=c.match(new RegExp(`^\\s*${se(h)}\\s*=\\s*(.+?)\\s*$`));if(k){let C=n(k[1]);C!==void 0&&(r[v]=C),p=!0,u=!0;break}}if(u)continue}a.push(c)}let l=a.join(`
36
- `);if(Object.keys(r).length===0)return{toml:l,changed:p};for(let{newKey:c}of t){let d=r[c];if(d===void 0)continue;let u=ie(l,"features");if((()=>{if(!u)return!1;let k=l.slice(u.start,u.end);return new RegExp(`^\\s*${se(c)}\\s*=`,"m").test(k)})())continue;let v=`${c} = ${d}`;if(u){let k=l.slice(0,u.end),C=l.slice(u.end),A=k.length>0&&!k.endsWith(`
37
- `),D=C.length>0&&!C.startsWith(`
37
+ `;a=!0}}return{toml:c,changed:a}}function Fo(e){let t=[{oldKey:"experimental_use_exec_command_tool",newKey:"streamable_shell"},{oldKey:"experimental_use_unified_exec_tool",newKey:"unified_exec"},{oldKey:"experimental_use_rmcp_client",newKey:"rmcp_client"},{oldKey:"include_apply_patch_tool",newKey:"apply_patch_freeform"}];if(!t.some(c=>e.includes(c.oldKey)))return{toml:e,changed:!1};function n(c){let d=c.trim(),u=/^(true|false)\b/i.exec(d);return u?u[1].toLowerCase():d||void 0}let i=e.split(/\r?\n/),s="",r={},a=[],p=!1;for(let c of i){let d=c.match(/^\s*\[([^\]]+)\]\s*$/);if(d){s=d[1].trim(),a.push(c);continue}if(s===""&&!/^\s*#/.test(c)){let u=!1;for(let{oldKey:h,newKey:C}of t){let k=c.match(new RegExp(`^\\s*${se(h)}\\s*=\\s*(.+?)\\s*$`));if(k){let S=n(k[1]);S!==void 0&&(r[C]=S),p=!0,u=!0;break}}if(u)continue}a.push(c)}let l=a.join(`
38
+ `);if(Object.keys(r).length===0)return{toml:l,changed:p};for(let{newKey:c}of t){let d=r[c];if(d===void 0)continue;let u=ie(l,"features");if((()=>{if(!u)return!1;let k=l.slice(u.start,u.end);return new RegExp(`^\\s*${se(c)}\\s*=`,"m").test(k)})())continue;let C=`${c} = ${d}`;if(u){let k=l.slice(0,u.end),S=l.slice(u.end),A=k.length>0&&!k.endsWith(`
39
+ `),D=S.length>0&&!S.startsWith(`
38
40
  `);l=k+`${A?`
39
- `:""}${v}
41
+ `:""}${C}
40
42
  ${D?`
41
- `:""}`+C}else l=(l.length===0?"":Ae(l))+`[features]
42
- ${v}
43
- `;p=!0}return{toml:l,changed:p}}import G from"fs-extra";import*as re from"path";async function Nt(e){let t=re.join(e.homeDir,".codex","notify.sh"),o=re.join(e.rootDir,"templates","notification.sh");await G.ensureDir(re.dirname(t));let n=e.options.notify;if(n==="no"){e.logger.info("Skipping notify hook installation");return}if(!await G.pathExists(o)){e.logger.warn(`Notification template missing at ${o}; skipping notify hook install`);return}if(await G.pathExists(t))if(n==="yes"){let s=O(t);e.options.dryRun?e.logger.log(`[dry-run] cp ${t} ${s}`):await G.copy(t,s),e.options.dryRun?e.logger.log(`[dry-run] cp ${o} ${t}`):(await G.copy(o,t),await G.chmod(t,493)),e.logger.ok("Updated notify hook (backup created)")}else!e.options.assumeYes&&!e.options.skipConfirmation&&e.logger.info("Keeping existing notify hook");else e.options.dryRun?e.logger.log(`[dry-run] cp ${o} ${t}`):(await G.copy(o,t),await G.chmod(t,493)),e.logger.ok("Installed notify hook to ~/.codex/notify.sh");let i=re.join(e.homeDir,".codex","config.toml");await G.pathExists(i)?await Fo(i,t,e):e.logger.warn(`Config not found at ${i}; run again after config is created`)}async function Fo(e,t,o){if(o.options.dryRun){o.logger.log("[dry-run] update config notify and tui.notifications");return}let i=(await G.readFile(e,"utf8")).split(/\r?\n/),s="",r=null,a=null;for(let d=0;d<i.length;d++){let u=i[d],h=u.match(/^\s*\[([^\]]+)\]\s*$/);if(h){s=h[1],s==="tui"&&(a=d);continue}let v=/^\s*notify\s*=\s*\[/.test(u),k=/^\s*tui\.notifications\s*=/.test(u),C=/^\s*notifications\s*=/.test(u);v&&(s===""?r===null&&(r=d):/^profiles\.[^.]+\.features$/.test(s)&&(i.splice(d,1),d--)),k&&/^profiles\.[^.]+\.features$/.test(s)&&(i.splice(d,1),d--),C&&s===""&&(i.splice(d,1),d--)}function p(d){let u=0;for(;u<i.length&&/^\s*(#.*)?$/.test(i[u]);)u++;i.splice(u,0,d)}if(r!==null){let d=i[r].match(/^(\s*notify\s*=\s*\[)([^\]]*)\]/);if(d){let u=d[2].trim();if(!u.includes(JSON.stringify(t))){let v=u&&!u.endsWith(",")?", ":"";i[r]=`${d[1]}${u}${v}${JSON.stringify(t)}]`,o.logger.ok("Added notify hook to config")}}}else p(`notify = [${JSON.stringify(t)}]`),o.logger.ok("Enabled notify hook in config");let l=!1;if(a!==null){let d=a+1,u=!1;for(;d<i.length;d++){let h=i[d];if(/^\s*\[/.test(h))break;if(/^\s*notifications\s*=/.test(h)){i[d]="notifications = true",u=!0,l=!0;break}}u||(i.splice(a+1,0,"notifications = true"),l=!0)}l||p(`[tui]
44
- notifications = true`);let c=[];s="";for(let d=0;d<i.length;d++){let u=i[d],h=u.match(/^\s*\[([^\]]+)\]\s*$/);if(h){s=h[1],c.push(u);continue}/^\s*tui\.notifications\s*=/.test(u)||/^\s*notifications\s*=/.test(u)&&s!=="tui"||c.push(u)}await G.writeFile(e,c.join(`
45
- `),"utf8")}import V from"fs-extra";import*as N from"path";async function Lt(e){let t=N.join(e.rootDir,"sounds"),o=N.join(e.homeDir,".codex","sounds");await V.ensureDir(o);let n=e.options.notificationSound;if(n==="none"){let l=N.join(e.homeDir,".codex","notify.sh");if(await V.pathExists(l)){let c=await V.readFile(l,"utf8"),d=c.replace(/^DEFAULT_CODEX_SOUND=.*$/m,'DEFAULT_CODEX_SOUND=""');e.options.dryRun?e.logger.log(`[dry-run] patch ${l} DEFAULT_CODEX_SOUND -> empty`):d!==c&&await V.writeFile(l,d,"utf8")}e.logger.ok("Notification sound disabled");return}let i;if(n&&!N.isAbsolute(n)?i=N.join(t,n):n?i=n:e.options.mode==="recommended"&&(i=N.join(t,"noti_1.wav")),!i||!await V.pathExists(i)){e.logger.warn("No notification sound selected or file missing; skipping sound setup");return}let s=N.isAbsolute(i),r=i.startsWith(N.join(e.rootDir,"sounds")),a=!s||r?N.join(o,N.basename(i)):i;(!s||r)&&(e.options.dryRun?e.logger.log(`[dry-run] cp ${i} ${a}`):await V.copy(i,a));let p=N.join(e.homeDir,".codex","notify.sh");if(await V.pathExists(p)){let l=await V.readFile(p,"utf8"),c=`DEFAULT_CODEX_SOUND="${a}"`,d=l.replace(/^DEFAULT_CODEX_SOUND=.*$/m,c);d!==l&&(e.options.dryRun?e.logger.log(`[dry-run] patch ${p} DEFAULT_CODEX_SOUND -> ${a}`):await V.writeFile(p,d,"utf8"))}e.logger.ok("Notification sound configured")}import L from"fs-extra";import*as Y from"path";async function Dt(e){let t=Y.join(e.homeDir,".codex","AGENTS.md"),o=e.options.globalAgents;if(o==="skip"){e.logger.info("Skipping global AGENTS.md creation");return}let n=Y.join(e.rootDir,"templates","agent-templates","AGENTS-default.md");if(!await L.pathExists(n)){e.logger.warn(`Template not found at ${n}`);return}switch(o){case"create-default":{if(await L.pathExists(t)){e.logger.info("Global AGENTS.md already exists; leaving unchanged");return}await L.ensureDir(Y.dirname(t)),e.options.dryRun?e.logger.log(`[dry-run] cp ${n} ${t}`):await L.copy(n,t),e.logger.ok(`Wrote ${t}`);break}case"overwrite-default":{if(await L.ensureDir(Y.dirname(t)),await L.pathExists(t)){let i=O(t);e.options.dryRun?e.logger.log(`[dry-run] cp ${t} ${i}`):await L.copy(t,i),e.logger.info(`Backed up existing AGENTS.md to: ${i}`)}e.options.dryRun?e.logger.log(`[dry-run] cp ${n} ${t}`):await L.copy(n,t),e.logger.ok(`Wrote ${t}`);break}case"append-default":{if(await L.ensureDir(Y.dirname(t)),await L.pathExists(t)){let s=O(t);e.options.dryRun?e.logger.log(`[dry-run] cp ${t} ${s}`):await L.copy(t,s),e.logger.info(`Backed up existing AGENTS.md to: ${s}`)}let i=await L.readFile(n,"utf8");e.options.dryRun?e.logger.log(`[dry-run] append template to ${t}`):await L.appendFile(t,`
43
+ `:""}`+S}else l=(l.length===0?"":Ae(l))+`[features]
44
+ ${C}
45
+ `;p=!0}return{toml:l,changed:p}}import M from"fs-extra";import*as re from"path";async function Lt(e){let t=re.join(e.homeDir,".codex","notify.sh"),o=re.join(e.rootDir,"templates","notification.sh");await M.ensureDir(re.dirname(t));let n=e.options.notify;if(n==="no"){e.logger.info("Skipping notify hook installation");return}if(!await M.pathExists(o)){e.logger.warn(`Notification template missing at ${o}; skipping notify hook install`);return}if(await M.pathExists(t))if(n==="yes"){let s=O(t);e.options.dryRun?e.logger.log(`[dry-run] cp ${t} ${s}`):await M.copy(t,s),e.options.dryRun?e.logger.log(`[dry-run] cp ${o} ${t}`):(await M.copy(o,t),await M.chmod(t,493)),e.logger.ok("Updated notify hook (backup created)")}else!e.options.assumeYes&&!e.options.skipConfirmation&&e.logger.info("Keeping existing notify hook");else e.options.dryRun?e.logger.log(`[dry-run] cp ${o} ${t}`):(await M.copy(o,t),await M.chmod(t,493)),e.logger.ok("Installed notify hook to ~/.codex/notify.sh");let i=re.join(e.homeDir,".codex","config.toml");await M.pathExists(i)?await Wo(i,t,e):e.logger.warn(`Config not found at ${i}; run again after config is created`)}async function Wo(e,t,o){if(o.options.dryRun){o.logger.log("[dry-run] update config notify and tui.notifications");return}let i=(await M.readFile(e,"utf8")).split(/\r?\n/),s="",r=null,a=null;for(let d=0;d<i.length;d++){let u=i[d],h=u.match(/^\s*\[([^\]]+)\]\s*$/);if(h){s=h[1],s==="tui"&&(a=d);continue}let C=/^\s*notify\s*=\s*\[/.test(u),k=/^\s*tui\.notifications\s*=/.test(u),S=/^\s*notifications\s*=/.test(u);C&&(s===""?r===null&&(r=d):/^profiles\.[^.]+\.features$/.test(s)&&(i.splice(d,1),d--)),k&&/^profiles\.[^.]+\.features$/.test(s)&&(i.splice(d,1),d--),S&&s===""&&(i.splice(d,1),d--)}function p(d){let u=0;for(;u<i.length&&/^\s*(#.*)?$/.test(i[u]);)u++;i.splice(u,0,d)}if(r!==null){let d=i[r].match(/^(\s*notify\s*=\s*\[)([^\]]*)\]/);if(d){let u=d[2].trim();if(!u.includes(JSON.stringify(t))){let C=u&&!u.endsWith(",")?", ":"";i[r]=`${d[1]}${u}${C}${JSON.stringify(t)}]`,o.logger.ok("Added notify hook to config")}}}else p(`notify = [${JSON.stringify(t)}]`),o.logger.ok("Enabled notify hook in config");let l=!1;if(a!==null){let d=a+1,u=!1;for(;d<i.length;d++){let h=i[d];if(/^\s*\[/.test(h))break;if(/^\s*notifications\s*=/.test(h)){i[d]="notifications = true",u=!0,l=!0;break}}u||(i.splice(a+1,0,"notifications = true"),l=!0)}l||p(`[tui]
46
+ notifications = true`);let c=[];s="";for(let d=0;d<i.length;d++){let u=i[d],h=u.match(/^\s*\[([^\]]+)\]\s*$/);if(h){s=h[1],c.push(u);continue}/^\s*tui\.notifications\s*=/.test(u)||/^\s*notifications\s*=/.test(u)&&s!=="tui"||c.push(u)}await M.writeFile(e,c.join(`
47
+ `),"utf8")}import V from"fs-extra";import*as N from"path";async function Dt(e){let t=N.join(e.rootDir,"sounds"),o=N.join(e.homeDir,".codex","sounds");await V.ensureDir(o);let n=e.options.notificationSound;if(n==="none"){let l=N.join(e.homeDir,".codex","notify.sh");if(await V.pathExists(l)){let c=await V.readFile(l,"utf8"),d=c.replace(/^DEFAULT_CODEX_SOUND=.*$/m,'DEFAULT_CODEX_SOUND=""');e.options.dryRun?e.logger.log(`[dry-run] patch ${l} DEFAULT_CODEX_SOUND -> empty`):d!==c&&await V.writeFile(l,d,"utf8")}e.logger.ok("Notification sound disabled");return}let i;if(n&&!N.isAbsolute(n)?i=N.join(t,n):n?i=n:e.options.mode==="recommended"&&(i=N.join(t,"noti_1.wav")),!i||!await V.pathExists(i)){e.logger.warn("No notification sound selected or file missing; skipping sound setup");return}let s=N.isAbsolute(i),r=i.startsWith(N.join(e.rootDir,"sounds")),a=!s||r?N.join(o,N.basename(i)):i;(!s||r)&&(e.options.dryRun?e.logger.log(`[dry-run] cp ${i} ${a}`):await V.copy(i,a));let p=N.join(e.homeDir,".codex","notify.sh");if(await V.pathExists(p)){let l=await V.readFile(p,"utf8"),c=`DEFAULT_CODEX_SOUND="${a}"`,d=l.replace(/^DEFAULT_CODEX_SOUND=.*$/m,c);d!==l&&(e.options.dryRun?e.logger.log(`[dry-run] patch ${p} DEFAULT_CODEX_SOUND -> ${a}`):await V.writeFile(p,d,"utf8"))}e.logger.ok("Notification sound configured")}import L from"fs-extra";import*as Y from"path";async function jt(e){let t=Y.join(e.homeDir,".codex","AGENTS.md"),o=e.options.globalAgents;if(o==="skip"){e.logger.info("Skipping global AGENTS.md creation");return}let n=Y.join(e.rootDir,"templates","agent-templates","AGENTS-default.md");if(!await L.pathExists(n)){e.logger.warn(`Template not found at ${n}`);return}switch(o){case"create-default":{if(await L.pathExists(t)){e.logger.info("Global AGENTS.md already exists; leaving unchanged");return}await L.ensureDir(Y.dirname(t)),e.options.dryRun?e.logger.log(`[dry-run] cp ${n} ${t}`):await L.copy(n,t),e.logger.ok(`Wrote ${t}`);break}case"overwrite-default":{if(await L.ensureDir(Y.dirname(t)),await L.pathExists(t)){let i=O(t);e.options.dryRun?e.logger.log(`[dry-run] cp ${t} ${i}`):await L.copy(t,i),e.logger.info(`Backed up existing AGENTS.md to: ${i}`)}e.options.dryRun?e.logger.log(`[dry-run] cp ${n} ${t}`):await L.copy(n,t),e.logger.ok(`Wrote ${t}`);break}case"append-default":{if(await L.ensureDir(Y.dirname(t)),await L.pathExists(t)){let s=O(t);e.options.dryRun?e.logger.log(`[dry-run] cp ${t} ${s}`):await L.copy(t,s),e.logger.info(`Backed up existing AGENTS.md to: ${s}`)}let i=await L.readFile(n,"utf8");e.options.dryRun?e.logger.log(`[dry-run] append template to ${t}`):await L.appendFile(t,`
46
48
  ---
47
49
 
48
- ${i}`,"utf8"),e.logger.ok(`Appended template to ${t}`);break}default:e.options.skipConfirmation&&e.logger.info("Skipping global AGENTS.md creation (non-interactive mode)");break}}async function jt(e){if(e.options.noVscode)return;let t=e.options.vscodeId;if(!t){e.logger.info("VS Code extension id not provided. Use: --vscode <publisher.extension>");return}if(!await S("code")){e.logger.warn("'code' (VS Code) not in PATH; skipping extension install");return}if(e.options.dryRun){e.logger.log(`[dry-run] code --install-extension ${t}`);return}e.logger.info(`Installing VS Code extension: ${t}`),await I("code",["--install-extension",t,"--force"],{dryRun:!1,logger:e.logger}),e.logger.ok(`VS Code extension '${t}' installed (or already present)`)}import ue from"fs-extra";import*as me from"path";async function _t(e){let t=e.options.agentsMd;if(!t)return;let o=t;(await ue.stat(o).catch(()=>null))?.isDirectory()&&(o=me.join(o,"AGENTS.md"));let n=me.join(e.rootDir,"templates","agent-templates","AGENTS-default.md");if(await ue.pathExists(o)){e.logger.warn(`${o} already exists`);let i=O(o);e.options.dryRun?e.logger.log(`[dry-run] cp ${o} ${i}`):await ue.copy(o,i),e.logger.info(`Backed up existing AGENTS.md to: ${i}`)}e.logger.info(`Writing starter AGENTS.md to: ${o}`),e.options.dryRun?e.logger.log(`[dry-run] write AGENTS.md to ${o}`):(await ue.ensureDir(me.dirname(o)),await ue.copy(n,o),e.logger.ok("Wrote AGENTS.md"))}import ge from"fs-extra";import*as et from"path";import*as De from"@clack/prompts";import Ze from"fs-extra";import*as Ne from"path";async function Le(e){let t=Ne.join(e,"templates","skills"),o=await Ze.readdir(t,{withFileTypes:!0}).catch(()=>[]),n=[];for(let i of o){if(!i.isDirectory())continue;let s=i.name,r=Ne.join(t,s),a=Ne.join(r,"SKILL.md");if(!await Ze.pathExists(a))continue;let p=await Ze.readFile(a,"utf8").catch(()=>""),l=Wo(p);!l?.name||!l?.description||n.push({id:s,name:l.name,description:l.description,srcDir:r})}return n.sort((i,s)=>i.id.localeCompare(s.id)),n}function Wo(e){let t=e.split(/\r?\n/);if(t.length<3||t[0].trim()!=="---")return null;let o=[],n=-1;for(let s=1;s<t.length;s++){if(t[s].trim()==="---"){n=s;break}o.push(t[s])}if(n===-1)return null;let i={};for(let s of o){let r=s.trim();if(!r||r.startsWith("#"))continue;let a=r.indexOf(":");if(a===-1)continue;let p=r.slice(0,a).trim();if(!p)continue;let l=r.slice(a+1).trim();l&&(l=Uo(Bo(l)),i[p]=l)}return{name:i.name,description:i.description}}function Bo(e){let t=e.trim();if(!t||t.startsWith('"')||t.startsWith("'"))return t;let o=t.indexOf(" #");return o===-1?t:t.slice(0,o).trim()}function Uo(e){let t=e.trim();return t.length>=2&&(t.startsWith('"')&&t.endsWith('"')||t.startsWith("'")&&t.endsWith("'"))?t.slice(1,-1):t}async function je(e){let t=e.options.skills;if(t==="skip"){e.logger.info("Skipping bundled skills installation");return}let o=await Le(e.rootDir);if(o.length===0){e.logger.info("No bundled skills found; skipping");return}let n=(()=>{if(t==="all")return o;let r=new Set((e.options.skillsSelected||[]).map(a=>a.trim()).filter(Boolean));return o.filter(a=>r.has(a.id)||r.has(a.name))})();if(n.length===0){e.logger.info("No skills selected; skipping");return}let i=et.join(e.homeDir,".codex","skills"),s=process.stdout.isTTY&&!e.options.dryRun&&!e.options.skipConfirmation&&!e.options.assumeYes;e.options.dryRun?e.logger.log(`[dry-run] mkdir -p ${i}`):await ge.ensureDir(i),e.logger.info(`Installing ${n.length} skill(s) into: ${i}`);for(let r of n){let a=et.join(i,r.id);if(await ge.pathExists(a)){if(s){let c=await De.select({message:`Skill "${r.id}" already exists. Overwrite? (backup created)`,options:[{label:"Overwrite",value:"overwrite"},{label:"Skip",value:"skip"}],initialValue:"overwrite"});if(De.isCancel(c)||c==="skip"){e.logger.info(`Skipping existing skill: ${r.id}`);continue}}let l=O(a);e.options.dryRun?(e.logger.log(`[dry-run] cp -R ${a} ${l}`),e.logger.log(`[dry-run] rm -rf ${a}`)):(await ge.copy(a,l),await ge.remove(a)),e.logger.info(`Backed up existing skill ${r.id} to: ${l}`)}e.options.dryRun?e.logger.log(`[dry-run] cp -R ${r.srcDir} ${a}`):await ge.copy(r.srcDir,a),e.logger.ok(`Installed skill: ${r.id}`)}}var Gt="codex-1up";async function Ft(e,t){let o=Mt.homedir(),n=tt.join(o,`.${Gt}`);await Ot.ensureDir(n);try{await Ot.chmod(n,448)}catch{}let i=new Date().toISOString().replace(/[:.]/g,"-").slice(0,-5),s=tt.join(n,`install-${i}.log`),r=Se(s);r.info(`==> ${Gt} installer`),r.info(`Log: ${s}`);let a={cwd:process.cwd(),homeDir:o,rootDir:t,logDir:n,logFile:s,options:e,logger:r};try{await St(a),await xt(a),await Pe(a);let l=await S("codex")||a.options.installCodexCli==="yes";l||r.warn("Codex CLI not found and codex install was skipped; skipping config/notify setup until codex is installed."),l&&(await Et(a),await Nt(a),await Lt(a),await Dt(a)),await je(a),await jt(a),await _t(a),r.ok("All done. Open a new shell or 'source' your rc file to load aliases."),r.info("Next steps:"),r.info(" 1) codex # sign in; then ask it to plan a refactor"),r.info(" 2) ./bin/codex-1up agents --path $PWD # write a starter AGENTS.md to your repo"),r.info(" 3) Review ~/.codex/config.toml (see: https://github.com/openai/codex/blob/main/docs/config.md)")}catch(p){throw r.err(`Installation failed: ${p}`),p}}import Ko from"os";import*as nt from"path";import{promises as Wt}from"fs";import{accessSync as Vo}from"fs";import{dirname as qo,resolve as ot}from"path";import{fileURLToPath as zo}from"url";function T(e=import.meta.url){let t=qo(zo(e)),o=t;for(let n=0;n<6;n++){try{return Vo(ot(o,"templates","codex-config.toml")),o}catch{}o=ot(o,"..")}return ot(t,"..")}function Ho(){return{profile:"skip",profileScope:"selected",profileMode:"add",setDefaultProfile:!1,profilesSelected:void 0,installTools:"skip",toolsSelected:void 0,installCodexCli:"no",notify:"no",globalAgents:"skip",notificationSound:void 0,skills:"skip",skillsSelected:void 0,mode:"manual",installNode:"skip",shell:"auto",vscodeId:void 0,noVscode:!0,agentsMd:void 0,dryRun:!1,assumeYes:!1,skipConfirmation:!1}}async function ae(e={}){let t=Ko.homedir(),o=nt.join(t,".codex-1up");await Wt.mkdir(o,{recursive:!0});try{await Wt.chmod(o,448)}catch{}let n=new Date().toISOString().replace(/[:.]/g,"-").slice(0,-5),i=nt.join(o,`command-${n}.log`),s=Se(i),r=Ho();return{cwd:process.cwd(),homeDir:t,rootDir:T(),logDir:o,logFile:i,options:{...r,...e},logger:s}}function J(){return ne()}function X(e){return Tt(e)}function Bt(){return J().map(e=>e.id)}async function he(){let e=ne(),t=[];for(let o of e){let n=await st(o.bins);t.push({id:o.id,installed:n})}return t}async function it(e,t={}){let o=e==="all",n={installTools:o?"all":"select",toolsSelected:o?void 0:e,dryRun:!!t.dryRun},i=await ae(n);await Pe(i)}async function st(e){for(let t of e)if(await S(t))return!0;return!1}async function rt(e,t){let o=t||T();await Ft(e,o)}async function at(){let e=Yo.homedir(),t=Jo(e,".codex","config.toml"),o,n=[];try{let l=await Xo.readFile(t,"utf8"),c=Ut.parse(l);o=typeof c.profile=="string"?c.profile:void 0;let d=c.profiles&&typeof c.profiles=="object"?c.profiles:{};n=Object.keys(d)}catch(l){}let i=J(),s=[{id:"codex",bins:["codex"]},...i],a=(await Promise.all(s.map(async l=>{let c=await st(l.bins);return[l.id,c]}))).filter(([,l])=>l).map(([l])=>l),p=[];p.push(""),p.push("codex-1up: Installation summary"),p.push("\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"),p.push(`Config: ${t}${o?` (active profile: ${o})`:""}`),n.length&&p.push(`Profiles: ${n.join(", ")}`),p.push(`Tools detected: ${a.join(", ")||"none"}`),p.push(""),p.push("Usage:"),p.push(" - Switch profile for a session: codex --profile <name>"),p.push(" - List available profiles: codex-1up config profiles"),p.push(" - Persist active profile: codex-1up config set-profile <name>"),p.push(" - Write AGENTS.md to a repo: codex-1up agents --path ."),p.push(""),process.stdout.write(p.join(`
50
+ ${i}`,"utf8"),e.logger.ok(`Appended template to ${t}`);break}default:e.options.skipConfirmation&&e.logger.info("Skipping global AGENTS.md creation (non-interactive mode)");break}}async function _t(e){if(e.options.noVscode)return;let t=e.options.vscodeId;if(!t){e.logger.info("VS Code extension id not provided. Use: --vscode <publisher.extension>");return}if(!await v("code")){e.logger.warn("'code' (VS Code) not in PATH; skipping extension install");return}if(e.options.dryRun){e.logger.log(`[dry-run] code --install-extension ${t}`);return}e.logger.info(`Installing VS Code extension: ${t}`),await I("code",["--install-extension",t,"--force"],{dryRun:!1,logger:e.logger}),e.logger.ok(`VS Code extension '${t}' installed (or already present)`)}import ue from"fs-extra";import*as me from"path";async function Ot(e){let t=e.options.agentsMd;if(!t)return;let o=t;(await ue.stat(o).catch(()=>null))?.isDirectory()&&(o=me.join(o,"AGENTS.md"));let n=me.join(e.rootDir,"templates","agent-templates","AGENTS-default.md");if(await ue.pathExists(o)){e.logger.warn(`${o} already exists`);let i=O(o);e.options.dryRun?e.logger.log(`[dry-run] cp ${o} ${i}`):await ue.copy(o,i),e.logger.info(`Backed up existing AGENTS.md to: ${i}`)}e.logger.info(`Writing starter AGENTS.md to: ${o}`),e.options.dryRun?e.logger.log(`[dry-run] write AGENTS.md to ${o}`):(await ue.ensureDir(me.dirname(o)),await ue.copy(n,o),e.logger.ok("Wrote AGENTS.md"))}import ge from"fs-extra";import*as et from"path";import*as De from"@clack/prompts";import Ze from"fs-extra";import*as Ne from"path";async function Le(e){let t=Ne.join(e,"templates","skills"),o=await Ze.readdir(t,{withFileTypes:!0}).catch(()=>[]),n=[];for(let i of o){if(!i.isDirectory())continue;let s=i.name,r=Ne.join(t,s),a=Ne.join(r,"SKILL.md");if(!await Ze.pathExists(a))continue;let p=await Ze.readFile(a,"utf8").catch(()=>""),l=Bo(p);!l?.name||!l?.description||n.push({id:s,name:l.name,description:l.description,srcDir:r})}return n.sort((i,s)=>i.id.localeCompare(s.id)),n}function Bo(e){let t=e.split(/\r?\n/);if(t.length<3||t[0].trim()!=="---")return null;let o=[],n=-1;for(let s=1;s<t.length;s++){if(t[s].trim()==="---"){n=s;break}o.push(t[s])}if(n===-1)return null;let i={};for(let s of o){let r=s.trim();if(!r||r.startsWith("#"))continue;let a=r.indexOf(":");if(a===-1)continue;let p=r.slice(0,a).trim();if(!p)continue;let l=r.slice(a+1).trim();l&&(l=Vo(Uo(l)),i[p]=l)}return{name:i.name,description:i.description}}function Uo(e){let t=e.trim();if(!t||t.startsWith('"')||t.startsWith("'"))return t;let o=t.indexOf(" #");return o===-1?t:t.slice(0,o).trim()}function Vo(e){let t=e.trim();return t.length>=2&&(t.startsWith('"')&&t.endsWith('"')||t.startsWith("'")&&t.endsWith("'"))?t.slice(1,-1):t}async function je(e){let t=e.options.skills;if(t==="skip"){e.logger.info("Skipping bundled skills installation");return}let o=await Le(e.rootDir);if(o.length===0){e.logger.info("No bundled skills found; skipping");return}let n=(()=>{if(t==="all")return o;let r=new Set((e.options.skillsSelected||[]).map(a=>a.trim()).filter(Boolean));return o.filter(a=>r.has(a.id)||r.has(a.name))})();if(n.length===0){e.logger.info("No skills selected; skipping");return}let i=et.join(e.homeDir,".codex","skills"),s=process.stdout.isTTY&&!e.options.dryRun&&!e.options.skipConfirmation&&!e.options.assumeYes;e.options.dryRun?e.logger.log(`[dry-run] mkdir -p ${i}`):await ge.ensureDir(i),e.logger.info(`Installing ${n.length} skill(s) into: ${i}`);for(let r of n){let a=et.join(i,r.id);if(await ge.pathExists(a)){if(s){let c=await De.select({message:`Skill "${r.id}" already exists. Overwrite? (backup created)`,options:[{label:"Overwrite",value:"overwrite"},{label:"Skip",value:"skip"}],initialValue:"overwrite"});if(De.isCancel(c)||c==="skip"){e.logger.info(`Skipping existing skill: ${r.id}`);continue}}let l=O(a);e.options.dryRun?(e.logger.log(`[dry-run] cp -R ${a} ${l}`),e.logger.log(`[dry-run] rm -rf ${a}`)):(await ge.copy(a,l),await ge.remove(a)),e.logger.info(`Backed up existing skill ${r.id} to: ${l}`)}e.options.dryRun?e.logger.log(`[dry-run] cp -R ${r.srcDir} ${a}`):await ge.copy(r.srcDir,a),e.logger.ok(`Installed skill: ${r.id}`)}}var Gt="codex-1up";async function Wt(e,t){let o=Ft.homedir(),n=tt.join(o,`.${Gt}`);await Mt.ensureDir(n);try{await Mt.chmod(n,448)}catch{}let i=new Date().toISOString().replace(/[:.]/g,"-").slice(0,-5),s=tt.join(n,`install-${i}.log`),r=Se(s);r.info(`==> ${Gt} installer`),r.info(`Log: ${s}`);let a={cwd:process.cwd(),homeDir:o,rootDir:t,logDir:n,logFile:s,options:e,logger:r};try{await $t(a),await It(a),await Pe(a);let l=await v("codex")||a.options.installCodexCli==="yes";l||r.warn("Codex CLI not found and codex install was skipped; skipping config/notify setup until codex is installed."),l&&(await Nt(a),await Lt(a),await Dt(a),await jt(a)),await je(a),await _t(a),await Ot(a),r.ok("All done. Open a new shell or 'source' your rc file to load aliases."),r.info("Next steps:"),r.info(" 1) codex # sign in; then ask it to plan a refactor"),r.info(" 2) ./bin/codex-1up agents --path $PWD # write a starter AGENTS.md to your repo"),r.info(" 3) Review ~/.codex/config.toml (see: https://github.com/openai/codex/blob/main/docs/config.md)")}catch(p){throw r.err(`Installation failed: ${p}`),p}}import Ho from"os";import*as nt from"path";import{promises as Bt}from"fs";import{accessSync as qo}from"fs";import{dirname as zo,resolve as ot}from"path";import{fileURLToPath as Ko}from"url";function T(e=import.meta.url){let t=zo(Ko(e)),o=t;for(let n=0;n<6;n++){try{return qo(ot(o,"templates","codex-config.toml")),o}catch{}o=ot(o,"..")}return ot(t,"..")}function Yo(){return{profile:"skip",profileScope:"selected",profileMode:"add",setDefaultProfile:!1,profilesSelected:void 0,installTools:"skip",toolsSelected:void 0,installCodexCli:"no",notify:"no",globalAgents:"skip",notificationSound:void 0,skills:"skip",skillsSelected:void 0,mode:"manual",installNode:"skip",shell:"auto",vscodeId:void 0,noVscode:!0,agentsMd:void 0,dryRun:!1,assumeYes:!1,skipConfirmation:!1}}async function ae(e={}){let t=Ho.homedir(),o=nt.join(t,".codex-1up");await Bt.mkdir(o,{recursive:!0});try{await Bt.chmod(o,448)}catch{}let n=new Date().toISOString().replace(/[:.]/g,"-").slice(0,-5),i=nt.join(o,`command-${n}.log`),s=Se(i),r=Yo();return{cwd:process.cwd(),homeDir:t,rootDir:T(),logDir:o,logFile:i,options:{...r,...e},logger:s}}function J(){return ne()}function X(e){return Pt(e)}function Ut(){return J().map(e=>e.id)}async function he(){let e=ne(),t=[];for(let o of e){let n=await st(o.bins);t.push({id:o.id,installed:n})}return t}async function it(e,t={}){let o=e==="all",n={installTools:o?"all":"select",toolsSelected:o?void 0:e,dryRun:!!t.dryRun},i=await ae(n);await Pe(i)}async function st(e){for(let t of e)if(await v(t))return!0;return!1}async function rt(e,t){let o=t||T();await Wt(e,o)}async function at(){let e=Jo.homedir(),t=Xo(e,".codex","config.toml"),o,n=[];try{let l=await Qo.readFile(t,"utf8"),c=Vt.parse(l);o=typeof c.profile=="string"?c.profile:void 0;let d=c.profiles&&typeof c.profiles=="object"?c.profiles:{};n=Object.keys(d)}catch(l){}let i=J(),s=[{id:"codex",bins:["codex"]},...i],a=(await Promise.all(s.map(async l=>{let c=await st(l.bins);return[l.id,c]}))).filter(([,l])=>l).map(([l])=>l),p=[];p.push(""),p.push("codex-1up: Installation summary"),p.push("\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"),p.push(`Config: ${t}${o?` (active profile: ${o})`:""}`),n.length&&p.push(`Profiles: ${n.join(", ")}`),p.push(`Tools detected: ${a.join(", ")||"none"}`),p.push(""),p.push("Usage:"),p.push(" - Switch profile for a session: codex --profile <name>"),p.push(" - List available profiles: codex-1up config profiles"),p.push(" - Persist active profile: codex-1up config set-profile <name>"),p.push(" - Write AGENTS.md to a repo: codex-1up agents --path ."),p.push(""),process.stdout.write(p.join(`
49
51
  `)+`
50
- `)}import Qo from"fs-extra";import Zo from"os";import Vt from"path";async function lt(e){return Le(e)}var pt=lt;async function qt(){let e=Vt.join(Zo.homedir(),".codex","skills");return(await Qo.readdir(e,{withFileTypes:!0}).catch(()=>[])).filter(o=>o.isDirectory()).map(o=>({id:o.name,path:Vt.join(e,o.name)})).sort((o,n)=>o.id.localeCompare(n.id))}async function _e(e,t,o={}){let n=await ae({skills:e,skillsSelected:t,dryRun:!!o.dryRun});await je(n)}import{existsSync as en,readFileSync as tn}from"fs";import{dirname as Kt,join as zt}from"path";import{fileURLToPath as on}from"url";var nn=Kt(on(import.meta.url)),Ht=(e,t=!1)=>{try{return JSON.parse(tn(e,"utf-8"))}catch(o){if(t)return{};throw o}},sn=e=>!!(e.name==="codex-1up"||e.bin==="codex-1up"||e.bin&&typeof e.bin=="object"&&"codex-1up"in e.bin),rn=e=>{let t=e,o=null;for(;;){let n=zt(t,"package.json");if(en(n)){o||(o=n);let s=Ht(n,!0);if(sn(s))return n}let i=Kt(t);if(i===t)break;t=i}return o??zt(e,"package.json")},an=rn(nn),dt=Ht(an),Oe=dt.name||"codex-1up",le=dt.version||"0.0.0",Yt=dt.description||"Codex CLI helper";import{promises as ft}from"fs";import{resolve as ct}from"path";import*as f from"@clack/prompts";import{$ as we,which as ye}from"zx";import*as Ge from"@clack/prompts";async function ln(){let e=le,t=await pn(Oe),o=!!(t&&dn(t,e));return{current:e,latest:t,updateAvailable:o}}async function Me(e){let t=e.logger,o=await ln();if(!o.latest)return t?.warn("Unable to check for codex-1up updates right now."),"error";if(!o.updateAvailable)return t?.ok(`codex-1up is up-to-date (v${o.current}).`),"up-to-date";let n=e.interactive&&!e.assumeYes&&!e.skipConfirmation,i=e.assumeYes||e.skipConfirmation;if(n){let p=await Ge.confirm({message:`New codex-1up version available (v${o.latest}). Update now?`,initialValue:!0});if(Ge.isCancel(p))return t?.info("Update canceled."),"skipped";i=!!p}if(!i)return t?.info("Skipping codex-1up update."),"skipped";let s=await Te({logger:t,interactive:e.interactive&&!e.assumeYes&&!e.skipConfirmation});if(s==="none")return t?.warn("No supported Node package manager found; cannot update codex-1up."),"error";let r=o.latest?`${Oe}@${o.latest}`:Oe,a=!!e.dryRun;return s==="pnpm"?(t?.info("Updating codex-1up via pnpm"),await I("pnpm",["add","-g",r],{dryRun:a,logger:t})):(t?.info("Updating codex-1up via npm"),await I("npm",["install","-g",r],{dryRun:a,logger:t})),t?.ok(`codex-1up updated to v${o.latest}`),"updated"}async function pn(e){try{let t=await fetch(`https://registry.npmjs.org/${encodeURIComponent(e)}/latest`);return t.ok?(await t.json()).version:void 0}catch{return}}function dn(e,t){let o=Jt(e),n=Jt(t);if(!o||!n)return e!==t;for(let i=0;i<3;i++){if(o[i]>n[i])return!0;if(o[i]<n[i])return!1}return!1}function Jt(e){let t=e.match(/(\d+)\.(\d+)\.(\d+)/);return t?[Number(t[1]),Number(t[2]),Number(t[3])]:null}async function Xt(e){return xe(e)}var cn=["balanced","safe","yolo"];async function Qt(e){let{repoRoot:t,isUnixLike:o,globalAgentsExists:n,currentProfile:i,seededProfile:s,bundledSkills:r,availableTools:a,cliArgs:p}=e,{profileChoice:l,profileMode:c,profileScope:d,setDefaultProfile:u,profilesSelected:h,installTools:v,toolsSelected:k,installCodexCli:C,notifyAction:A,globalAgentsAction:D,notificationSound:q,skillsMode:K,skillsSelected:Q}=e.selections;await Me({interactive:!0,assumeYes:!1,skipConfirmation:!1,dryRun:!1,logger:{log:m=>f.log.info(m),info:m=>f.log.info(m),ok:m=>f.log.success(m),warn:m=>f.log.warn(m),err:m=>f.log.warn(m)}});let x=await Xt();if(x.found){let m=x.version?`v${x.version}`:"unknown version";x.latest?x.updateAvailable?f.log.info(`Codex CLI detected (${m}). Newer version available: v${x.latest}.`):f.log.info(`Codex CLI detected (${m}). Latest: v${x.latest}.`):f.log.info(`Codex CLI detected (${m}).`)}else f.log.info("Codex CLI not detected.");if(C==="no")x.found?x.updateAvailable&&f.log.info("Codex CLI update disabled by --codex-cli no."):f.log.info("Codex CLI install disabled by --codex-cli no.");else if(C==="auto")if(x.found){if(x.updateAvailable){let m=await f.confirm({message:`Codex CLI ${x.version} found; latest is ${x.latest}. Update now?`,initialValue:!0});if(f.isCancel(m))return R();C=m?"yes":"no"}}else{let m=await f.confirm({message:"Codex CLI not found. Install now?",initialValue:!0});if(f.isCancel(m))return R();C=m?"yes":"no"}if(o&&!p.toolsArg){let m=await he(),w=m.filter(y=>y.installed).map(y=>y.id),b=m.filter(y=>!y.installed).map(y=>y.id);for(f.log.info(`Tools detected: ${w.join(", ")||"none"}`),b.length&&f.log.info(`Missing tools: ${b.join(", ")}`);;){let y=await f.select({message:"Install/update developer tools",options:[{label:"Install/Update all",value:"all"},{label:"Select",value:"select"},{label:"Skip",value:"skip"}],initialValue:"all"});if(f.isCancel(y))return R();if(v=y,y!=="select"){k=void 0;break}f.log.info("Tip: press Esc to go back.");let E=await Fe({message:"Select tools to install",options:a.map(g=>{let $=w.includes(g.id);return{label:g.id,value:g.id,hint:$?"installed":"missing"}})});if(E==="back")continue;let j=Array.isArray(E)?E.map(g=>String(g).trim().toLowerCase()).filter(X):[];j.length===0?(v="skip",k=void 0):k=Array.from(new Set(j));break}}else!o&&!p.toolsArg&&(v="skip",k=void 0);let H=[{label:"Balanced (recommended)",value:"balanced",hint:"on-request approvals \xB7 workspace-write \xB7 web search on"},{label:"Safe",value:"safe",hint:"on-failure approvals \xB7 read-only \xB7 web search off"},{label:"YOLO",value:"yolo",hint:"never approvals \xB7 danger-full-access \xB7 gpt-5.2-codex"}];if(!p.profileScope)for(;;){let m=await f.select({message:"Install all profiles (balanced, safe, yolo)?",options:[{label:"Yes \u2014 install/update all profiles",value:"all"},{label:"Choose profiles\u2026",value:"selected"},{label:"No \u2014 don't install any profiles",value:"skip"}],initialValue:"all"});if(f.isCancel(m))return R();if(m==="skip"){d="selected",h=[],l="skip";break}if(m!=="selected"){d=m;break}f.log.info("Tip: press Esc to go back.");let w=await Fe({message:"Select profiles to install",options:H.map(E=>({label:E.label,value:E.value,hint:E.hint}))});if(w==="back")continue;let b=Array.isArray(w)?w.map(E=>String(E).trim().toLowerCase()).filter(be):[],y=Array.from(new Set(b));d="selected",y.length===0?(h=[],l="skip"):h=y;break}if(d!=="all"&&!p.profileChoice&&f.log.info(["Profiles:"," - Balanced: on-request approvals, workspace-write sandbox, web search on."," - Safe: on-failure approvals, read-only sandbox, web search off."," - YOLO: never approvals, danger-full-access, gpt-5.2-codex, high reasoning."].join(`
51
- `)),d==="single"){if(!p.profileChoice){let m=await f.select({message:"Choose a Codex profile to install",options:[...H,{label:"Skip (no profile changes)",value:"skip"}],initialValue:mn(i)});if(f.isCancel(m))return R();l=m}}else if(d==="selected"){if(h===void 0){f.log.info("Tip: press Esc to go back.");let m=await Fe({message:"Select profiles to install",options:H.map(w=>({label:w.label,value:w.value,hint:w.hint}))});if(m==="back")h=[],l="skip";else{let w=Array.isArray(m)?m.map(y=>String(y).trim().toLowerCase()).filter(be):[],b=Array.from(new Set(w));b.length===0?(h=[],l="skip"):h=b}}(h||[]).length>0&&be(l)&&!h.includes(l)&&(l=h[0])}else d==="all"&&l==="skip"&&(l=s);let P=d==="all"?[...cn]:d==="selected"?h||[]:l==="skip"?[]:[l];if(P.length>0&&!p.profileMode){let m=await f.select({message:d==="all"?"How should we write all profiles?":P.length>1?"How should we write selected profiles?":`How should we write profiles.${P[0]}?`,options:[{label:"Overwrite (use codex-1up defaults)",value:"overwrite"},{label:"Add Merge (add missing, keep your default settings)",value:"add"}],initialValue:c});if(f.isCancel(m))return R();c=m}if(P.length===0)u=!1;else if(P.length===1){let m=P[0],w=await f.confirm({message:`Wrote profiles.${m} to ~/.codex/config.toml (mode: ${c}). Set this as the default profile?`,initialValue:!0});if(f.isCancel(w))return R();u=!!w,u&&(l=m)}else{let m=[{label:"Keep current default (skip)",value:"skip"},...P.map(y=>({label:y==="balanced"?"Balanced":y==="safe"?"Safe":"YOLO",value:y}))],w=be(l)&&P.includes(l)?l:P[0],b=await f.select({message:"Select a default profile (optional)",options:m,initialValue:w});if(f.isCancel(b))return R();b==="skip"?u=!1:(u=!0,l=b)}if(!p.soundArg){let y=function(){return[{label:"Skip (leave current setup)",value:"skip"},{label:"None (disable sounds)",value:"none"},...w.map(g=>({label:g,value:g})),{label:"Custom path\u2026",value:"custom"}]};var Z=y;let m=ct(t,"sounds"),w=[];try{w=(await ft.readdir(m)).filter(g=>/\.(wav|mp3|ogg)$/i.test(g)).sort()}catch(g){}A="yes";let b=w.includes("noti_1.wav")?"noti_1.wav":w[0]||"none";async function E(g){let $=await f.text({message:"Enter absolute path to a .wav file",placeholder:g||"/absolute/path/to/sound.wav",validate(_){if(!_)return"Path required";if(!_.startsWith("/"))return"Use an absolute path";if(!/(\.wav|\.mp3|\.ogg)$/i.test(_))return"Supported: .wav, .mp3, .ogg"}});if(f.isCancel($))return null;try{await ft.access(String($))}catch{return f.log.warn("File not found. Try again."),await E(String($))}return String($)}let j=await f.select({message:"Notification sound",options:y(),initialValue:b});if(f.isCancel(j))return R();if(j==="skip")A="no",q=void 0;else if(j==="custom"){let g=await E();if(g===null)return R();b=g}else b=j;if(j!=="skip"){for(;;){let g=await f.select({message:`Selected: ${b}. What next?`,options:[{label:"Preview \u25B6 (press p then Enter)",value:"preview"},{label:"Use this",value:"use"},{label:"Choose another\u2026",value:"change"}],initialValue:"use"});if(f.isCancel(g))return R();if(g==="use")break;if(g==="change"){let $=await f.select({message:"Notification sound",options:y(),initialValue:b});if(f.isCancel($))return R();if($==="custom"){let _=await E();if(_===null)return R();b=_}else if($==="skip"){A="no",q=void 0;break}else b=$;continue}try{let $=b==="none"?"none":b.startsWith("/")?b:ct(t,"sounds",b);await fn($)}catch($){f.log.warn(String($))}}q===void 0&&(q=b)}}let W=["Global AGENTS.md is shared instructions Codex can reference in any repo.","We add a short starter guide (fd/ast-grep/jq/yq patterns, deterministic selects).","Backups will be created.","You can remove it later from ~/.codex/AGENTS.md."].join(`
52
- `),B=ct(t,"templates","agent-templates","AGENTS-default.md"),M=await(async m=>{for(;;){f.log.info(W);let w=await f.select({message:"Global ~/.codex/AGENTS.md (optional)",options:m?[{label:"Add to your existing AGENTS.md (keeps your content, adds ours; backup created)",value:"append-default"},{label:"Overwrite existing (replace with starter; backup created)",value:"overwrite-default"},{label:"Preview starter AGENTS.md",value:"preview"},{label:"Skip \u2014 leave as-is (you can run codex-1up agents later)",value:"skip"}]:[{label:"Create starter AGENTS.md (recommended; helps give Codex repo context everywhere)",value:"create-default"},{label:"Preview starter AGENTS.md",value:"preview"},{label:"Skip for now (you can add later with codex-1up agents --global)",value:"skip"}],initialValue:m?"append-default":"create-default"});if(f.isCancel(w))return null;if(w==="preview"){await un(B);continue}return w}})(n);if(!M)return R();if(D=M,!p.skillsArg&&r.length)for(f.log.info(["Agent Skills are optional, portable skill folders (SKILL.md + optional scripts/references).","codex-1up can install bundled skills into ~/.codex/skills so your agent can reference them.",`Bundled skills: ${r.map(m=>m.id).join(", ")}`].join(`
53
- `));;){let m=await f.select({message:"Install bundled Agent Skills (optional)",options:[{label:"None (do not install skills)",value:"skip"},{label:"Select skills\u2026",value:"select"},{label:"All (install every bundled skill)",value:"all"}],initialValue:"skip"});if(f.isCancel(m))return R();if(K=m,m!=="select")break;f.log.info("Tip: press Esc to go back.");let w=await Fe({message:"Select skills to install",options:r.map(y=>({label:y.id,value:y.id,hint:y.description.length>120?`${y.description.slice(0,117)}\u2026`:y.description}))});if(w==="back")continue;let b=Array.isArray(w)?w.map(y=>String(y).trim()).filter(Boolean):[];b.length===0?(K="skip",Q=void 0):Q=b;break}return{selections:{profileChoice:l,profileMode:c,profileScope:d,setDefaultProfile:u,profilesSelected:h,installTools:v,toolsSelected:k,installCodexCli:C,notifyAction:A,globalAgentsAction:D,notificationSound:q,skillsMode:K,skillsSelected:Q}}}async function fn(e){if(e.endsWith("/none")||e==="none")return;let t=[async o=>{await ye("afplay"),await we`afplay ${o}`},async o=>{await ye("paplay"),await we`paplay ${o}`},async o=>{await ye("aplay"),await we`aplay ${o}`},async o=>{await ye("mpg123"),await we`mpg123 -q ${o}`},async o=>{await ye("ffplay"),await we`ffplay -nodisp -autoexit -loglevel quiet ${o}`}];for(let o of t)try{await o(e);return}catch{}throw new Error("No audio player found (afplay/paplay/aplay/mpg123/ffplay)")}async function Fe(e){let o=await f.multiselect({message:e.message,options:e.options});return f.isCancel(o)?"back":Array.isArray(o)?o.map(i=>String(i)):[]}async function un(e){let o="";try{o=await ft.readFile(e,"utf8")}catch{f.log.warn(`Starter AGENTS template not found at ${e}`);return}let n=o.split(/\r?\n/);if(n.length===0||n.length===1&&n[0].trim()===""){f.log.warn("Starter AGENTS template is empty.");return}let i=n.filter(r=>/^#{1,3}\s+/.test(r)).map(r=>r.replace(/^#{1,3}\s+/,"").trim()).filter(Boolean).slice(0,12);f.log.info(`Preview: ${e}`),i.length&&f.log.info(`Sections: ${i.join(" | ")}`);let s=n.slice(0,40).join(`
52
+ `)}import Zo from"fs-extra";import en from"os";import qt from"path";async function lt(e){return Le(e)}var pt=lt;async function zt(){let e=qt.join(en.homedir(),".codex","skills");return(await Zo.readdir(e,{withFileTypes:!0}).catch(()=>[])).filter(o=>o.isDirectory()).map(o=>({id:o.name,path:qt.join(e,o.name)})).sort((o,n)=>o.id.localeCompare(n.id))}async function _e(e,t,o={}){let n=await ae({skills:e,skillsSelected:t,dryRun:!!o.dryRun});await je(n)}import{existsSync as tn,readFileSync as on}from"fs";import{dirname as Ht,join as Kt}from"path";import{fileURLToPath as nn}from"url";var sn=Ht(nn(import.meta.url)),Yt=(e,t=!1)=>{try{return JSON.parse(on(e,"utf-8"))}catch(o){if(t)return{};throw o}},rn=e=>!!(e.name==="codex-1up"||e.bin==="codex-1up"||e.bin&&typeof e.bin=="object"&&"codex-1up"in e.bin),an=e=>{let t=e,o=null;for(;;){let n=Kt(t,"package.json");if(tn(n)){o||(o=n);let s=Yt(n,!0);if(rn(s))return n}let i=Ht(t);if(i===t)break;t=i}return o??Kt(e,"package.json")},ln=an(sn),dt=Yt(ln),Oe=dt.name||"codex-1up",le=dt.version||"0.0.0",Jt=dt.description||"Codex CLI helper";import{promises as ft}from"fs";import{resolve as ct}from"path";import*as f from"@clack/prompts";import{$ as we,which as ye}from"zx";import*as Me from"@clack/prompts";async function pn(){let e=le,t=await dn(Oe),o=!!(t&&cn(t,e));return{current:e,latest:t,updateAvailable:o}}async function Ge(e){let t=e.logger,o=await pn();if(!o.latest)return t?.warn("Unable to check for codex-1up updates right now."),"error";if(!o.updateAvailable)return t?.ok(`codex-1up is up-to-date (v${o.current}).`),"up-to-date";let n=e.interactive&&!e.assumeYes&&!e.skipConfirmation,i=e.assumeYes||e.skipConfirmation;if(n){let p=await Me.confirm({message:`New codex-1up version available (v${o.latest}). Update now?`,initialValue:!0});if(Me.isCancel(p))return t?.info("Update canceled."),"skipped";i=!!p}if(!i)return t?.info("Skipping codex-1up update."),"skipped";let s=await Te({logger:t,interactive:e.interactive&&!e.assumeYes&&!e.skipConfirmation});if(s==="none")return t?.warn("No supported Node package manager found; cannot update codex-1up."),"error";let r=o.latest?`${Oe}@${o.latest}`:Oe,a=!!e.dryRun;return s==="pnpm"?(t?.info("Updating codex-1up via pnpm"),await I("pnpm",["add","-g",r],{dryRun:a,logger:t})):(t?.info("Updating codex-1up via npm"),await I("npm",["install","-g",r],{dryRun:a,logger:t})),t?.ok(`codex-1up updated to v${o.latest}`),"updated"}async function dn(e){try{let t=await fetch(`https://registry.npmjs.org/${encodeURIComponent(e)}/latest`);return t.ok?(await t.json()).version:void 0}catch{return}}function cn(e,t){let o=Xt(e),n=Xt(t);if(!o||!n)return e!==t;for(let i=0;i<3;i++){if(o[i]>n[i])return!0;if(o[i]<n[i])return!1}return!1}function Xt(e){let t=e.match(/(\d+)\.(\d+)\.(\d+)/);return t?[Number(t[1]),Number(t[2]),Number(t[3])]:null}async function Qt(e){return xe(e)}var fn=["balanced","safe","yolo"];async function Zt(e){let{repoRoot:t,isUnixLike:o,globalAgentsExists:n,currentProfile:i,seededProfile:s,bundledSkills:r,availableTools:a,cliArgs:p}=e,{profileChoice:l,profileMode:c,profileScope:d,setDefaultProfile:u,profilesSelected:h,installTools:C,toolsSelected:k,installCodexCli:S,notifyAction:A,globalAgentsAction:D,notificationSound:q,skillsMode:K,skillsSelected:Q}=e.selections;await Ge({interactive:!0,assumeYes:!1,skipConfirmation:!1,dryRun:!1,logger:{log:m=>f.log.info(m),info:m=>f.log.info(m),ok:m=>f.log.success(m),warn:m=>f.log.warn(m),err:m=>f.log.warn(m)}});let x=await Qt();if(x.found){let m=x.version?`v${x.version}`:"unknown version";x.latest?x.updateAvailable?f.log.info(`Codex CLI detected (${m}). Newer version available: v${x.latest}.`):f.log.info(`Codex CLI detected (${m}). Latest: v${x.latest}.`):f.log.info(`Codex CLI detected (${m}).`)}else f.log.info("Codex CLI not detected.");if(S==="no")x.found?x.updateAvailable&&f.log.info("Codex CLI update disabled by --codex-cli no."):f.log.info("Codex CLI install disabled by --codex-cli no.");else if(S==="auto")if(x.found){if(x.updateAvailable){let m=await f.confirm({message:`Codex CLI ${x.version} found; latest is ${x.latest}. Update now?`,initialValue:!0});if(f.isCancel(m))return R();S=m?"yes":"no"}}else{let m=await f.confirm({message:"Codex CLI not found. Install now?",initialValue:!0});if(f.isCancel(m))return R();S=m?"yes":"no"}if(o&&!p.toolsArg){let m=await he(),w=m.filter(y=>y.installed).map(y=>y.id),b=m.filter(y=>!y.installed).map(y=>y.id);for(f.log.info(`Tools detected: ${w.join(", ")||"none"}`),b.length&&f.log.info(`Missing tools: ${b.join(", ")}`);;){let y=await f.select({message:"Install/update developer tools",options:[{label:"Install/Update all",value:"all"},{label:"Select",value:"select"},{label:"Skip",value:"skip"}],initialValue:"all"});if(f.isCancel(y))return R();if(C=y,y!=="select"){k=void 0;break}f.log.info("Tip: press Esc to go back.");let E=await Fe({message:"Select tools to install",options:a.map(g=>{let $=w.includes(g.id);return{label:g.id,value:g.id,hint:$?"installed":"missing"}})});if(E==="back")continue;let j=Array.isArray(E)?E.map(g=>String(g).trim().toLowerCase()).filter(X):[];j.length===0?(C="skip",k=void 0):k=Array.from(new Set(j));break}}else!o&&!p.toolsArg&&(C="skip",k=void 0);let H=[{label:"Balanced (recommended)",value:"balanced",hint:"on-request approvals \xB7 workspace-write \xB7 web search on"},{label:"Safe",value:"safe",hint:"on-failure approvals \xB7 read-only \xB7 web search off"},{label:"YOLO",value:"yolo",hint:"never approvals \xB7 danger-full-access \xB7 gpt-5.2-codex"}];if(!p.profileScope)for(;;){let m=await f.select({message:"Install all profiles (balanced, safe, yolo)?",options:[{label:"Yes \u2014 install/update all profiles",value:"all"},{label:"Choose profiles\u2026",value:"selected"},{label:"No \u2014 don't install any profiles",value:"skip"}],initialValue:"all"});if(f.isCancel(m))return R();if(m==="skip"){d="selected",h=[],l="skip";break}if(m!=="selected"){d=m;break}f.log.info("Tip: press Esc to go back.");let w=await Fe({message:"Select profiles to install",options:H.map(E=>({label:E.label,value:E.value,hint:E.hint}))});if(w==="back")continue;let b=Array.isArray(w)?w.map(E=>String(E).trim().toLowerCase()).filter(be):[],y=Array.from(new Set(b));d="selected",y.length===0?(h=[],l="skip"):h=y;break}if(d!=="all"&&!p.profileChoice&&f.log.info(["Profiles:"," - Balanced: on-request approvals, workspace-write sandbox, web search on."," - Safe: on-failure approvals, read-only sandbox, web search off."," - YOLO: never approvals, danger-full-access, gpt-5.2-codex, high reasoning."].join(`
53
+ `)),d==="single"){if(!p.profileChoice){let m=await f.select({message:"Choose a Codex profile to install",options:[...H,{label:"Skip (no profile changes)",value:"skip"}],initialValue:gn(i)});if(f.isCancel(m))return R();l=m}}else if(d==="selected"){if(h===void 0){f.log.info("Tip: press Esc to go back.");let m=await Fe({message:"Select profiles to install",options:H.map(w=>({label:w.label,value:w.value,hint:w.hint}))});if(m==="back")h=[],l="skip";else{let w=Array.isArray(m)?m.map(y=>String(y).trim().toLowerCase()).filter(be):[],b=Array.from(new Set(w));b.length===0?(h=[],l="skip"):h=b}}(h||[]).length>0&&be(l)&&!h.includes(l)&&(l=h[0])}else d==="all"&&l==="skip"&&(l=s);let P=d==="all"?[...fn]:d==="selected"?h||[]:l==="skip"?[]:[l];if(P.length>0&&!p.profileMode){let m=await f.select({message:d==="all"?"How should we write all profiles?":P.length>1?"How should we write selected profiles?":`How should we write profiles.${P[0]}?`,options:[{label:"Overwrite (use codex-1up defaults)",value:"overwrite"},{label:"Add Merge (add missing, keep your default settings)",value:"add"}],initialValue:c});if(f.isCancel(m))return R();c=m}if(P.length===0)u=!1;else if(P.length===1){let m=P[0],w=await f.confirm({message:`Wrote profiles.${m} to ~/.codex/config.toml (mode: ${c}). Set this as the default profile?`,initialValue:!0});if(f.isCancel(w))return R();u=!!w,u&&(l=m)}else{let m=[{label:"Keep current default (skip)",value:"skip"},...P.map(y=>({label:y==="balanced"?"Balanced":y==="safe"?"Safe":"YOLO",value:y}))],w=be(l)&&P.includes(l)?l:P[0],b=await f.select({message:"Select a default profile (optional)",options:m,initialValue:w});if(f.isCancel(b))return R();b==="skip"?u=!1:(u=!0,l=b)}if(!p.soundArg){let y=function(){return[{label:"Skip (leave current setup)",value:"skip"},{label:"None (disable sounds)",value:"none"},...w.map(g=>({label:g,value:g})),{label:"Custom path\u2026",value:"custom"}]};var Z=y;let m=ct(t,"sounds"),w=[];try{w=(await ft.readdir(m)).filter(g=>/\.(wav|mp3|ogg)$/i.test(g)).sort()}catch(g){}A="yes";let b=w.includes("noti_1.wav")?"noti_1.wav":w[0]||"none";async function E(g){let $=await f.text({message:"Enter absolute path to a .wav file",placeholder:g||"/absolute/path/to/sound.wav",validate(_){if(!_)return"Path required";if(!_.startsWith("/"))return"Use an absolute path";if(!/(\.wav|\.mp3|\.ogg)$/i.test(_))return"Supported: .wav, .mp3, .ogg"}});if(f.isCancel($))return null;try{await ft.access(String($))}catch{return f.log.warn("File not found. Try again."),await E(String($))}return String($)}let j=await f.select({message:"Notification sound",options:y(),initialValue:b});if(f.isCancel(j))return R();if(j==="skip")A="no",q=void 0;else if(j==="custom"){let g=await E();if(g===null)return R();b=g}else b=j;if(j!=="skip"){for(;;){let g=await f.select({message:`Selected: ${b}. What next?`,options:[{label:"Preview \u25B6 (press p then Enter)",value:"preview"},{label:"Use this",value:"use"},{label:"Choose another\u2026",value:"change"}],initialValue:"use"});if(f.isCancel(g))return R();if(g==="use")break;if(g==="change"){let $=await f.select({message:"Notification sound",options:y(),initialValue:b});if(f.isCancel($))return R();if($==="custom"){let _=await E();if(_===null)return R();b=_}else if($==="skip"){A="no",q=void 0;break}else b=$;continue}try{let $=b==="none"?"none":b.startsWith("/")?b:ct(t,"sounds",b);await un($)}catch($){f.log.warn(String($))}}q===void 0&&(q=b)}}let W=["Global AGENTS.md is shared instructions Codex can reference in any repo.","We add a short starter guide (fd/ast-grep/jq/yq patterns, deterministic selects).","Backups will be created.","You can remove it later from ~/.codex/AGENTS.md."].join(`
54
+ `),B=ct(t,"templates","agent-templates","AGENTS-default.md"),G=await(async m=>{for(;;){f.log.info(W);let w=await f.select({message:"Global ~/.codex/AGENTS.md (optional)",options:m?[{label:"Add to your existing AGENTS.md (keeps your content, adds ours; backup created)",value:"append-default"},{label:"Overwrite existing (replace with starter; backup created)",value:"overwrite-default"},{label:"Preview starter AGENTS.md",value:"preview"},{label:"Skip \u2014 leave as-is (you can run codex-1up agents later)",value:"skip"}]:[{label:"Create starter AGENTS.md (recommended; helps give Codex repo context everywhere)",value:"create-default"},{label:"Preview starter AGENTS.md",value:"preview"},{label:"Skip for now (you can add later with codex-1up agents --global)",value:"skip"}],initialValue:m?"append-default":"create-default"});if(f.isCancel(w))return null;if(w==="preview"){await mn(B);continue}return w}})(n);if(!G)return R();if(D=G,!p.skillsArg&&r.length)for(f.log.info(["Agent Skills are optional, portable skill folders (SKILL.md + optional scripts/references).","codex-1up can install bundled skills into ~/.codex/skills so your agent can reference them.",`Bundled skills: ${r.map(m=>m.id).join(", ")}`].join(`
55
+ `));;){let m=await f.select({message:"Install bundled Agent Skills (optional)",options:[{label:"None (do not install skills)",value:"skip"},{label:"Select skills\u2026",value:"select"},{label:"All (install every bundled skill)",value:"all"}],initialValue:"skip"});if(f.isCancel(m))return R();if(K=m,m!=="select")break;f.log.info("Tip: press Esc to go back.");let w=await Fe({message:"Select skills to install",options:r.map(y=>({label:y.id,value:y.id,hint:y.description.length>120?`${y.description.slice(0,117)}\u2026`:y.description}))});if(w==="back")continue;let b=Array.isArray(w)?w.map(y=>String(y).trim()).filter(Boolean):[];b.length===0?(K="skip",Q=void 0):Q=b;break}return{selections:{profileChoice:l,profileMode:c,profileScope:d,setDefaultProfile:u,profilesSelected:h,installTools:C,toolsSelected:k,installCodexCli:S,notifyAction:A,globalAgentsAction:D,notificationSound:q,skillsMode:K,skillsSelected:Q}}}async function un(e){if(e.endsWith("/none")||e==="none")return;let t=[async o=>{await ye("afplay"),await we`afplay ${o}`},async o=>{await ye("paplay"),await we`paplay ${o}`},async o=>{await ye("aplay"),await we`aplay ${o}`},async o=>{await ye("mpg123"),await we`mpg123 -q ${o}`},async o=>{await ye("ffplay"),await we`ffplay -nodisp -autoexit -loglevel quiet ${o}`}];for(let o of t)try{await o(e);return}catch{}throw new Error("No audio player found (afplay/paplay/aplay/mpg123/ffplay)")}async function Fe(e){let o=await f.multiselect({message:e.message,options:e.options});return f.isCancel(o)?"back":Array.isArray(o)?o.map(i=>String(i)):[]}async function mn(e){let o="";try{o=await ft.readFile(e,"utf8")}catch{f.log.warn(`Starter AGENTS template not found at ${e}`);return}let n=o.split(/\r?\n/);if(n.length===0||n.length===1&&n[0].trim()===""){f.log.warn("Starter AGENTS template is empty.");return}let i=n.filter(r=>/^#{1,3}\s+/.test(r)).map(r=>r.replace(/^#{1,3}\s+/,"").trim()).filter(Boolean).slice(0,12);f.log.info(`Preview: ${e}`),i.length&&f.log.info(`Sections: ${i.join(" | ")}`);let s=n.slice(0,40).join(`
54
56
  `);process.stdout.write(s+`
55
- `),n.length>40&&f.log.info(`... (${n.length-40} more lines)`)}function mn(e){return be(e)?e:"balanced"}function be(e){return e==="balanced"||e==="safe"||e==="yolo"}function R(){return f.cancel("Install aborted"),null}var We=T(),hn=["balanced","safe","yolo"],to=gn({meta:{name:"install",description:"Run the codex-1up installer with validated flags"},args:{yes:{type:"boolean",description:"Non-interactive; accept safe defaults"},"dry-run":{type:"boolean",description:"Print actions without making changes"},"skip-confirmation":{type:"boolean",description:"Skip prompts"},shell:{type:"string",description:"auto|zsh|bash|fish"},vscode:{type:"string",description:"Install VS Code extension id"},"no-vscode":{type:"boolean",description:"Skip VS Code extension checks"},"install-node":{type:"string",description:"nvm|brew|skip"},tools:{type:"string",description:"all|skip|<comma-separated tool ids> (rg, fd, fzf, jq, yq, ast-grep, bat, git, git-delta, gh)"},"codex-cli":{type:"string",description:"yes|no install/upgrade Codex CLI + ast-grep globally"},"profiles-scope":{type:"string",description:"single|all (write one profile or all profiles)"},profile:{type:"string",description:"balanced|safe|yolo|skip (choose profile to write)"},"profile-mode":{type:"string",description:"add|overwrite (profile table merge strategy)"},sound:{type:"string",description:'Sound file, "none", or "skip" to leave unchanged'},"agents-md":{type:"string",description:"Write starter AGENTS.md to PATH (default PWD/AGENTS.md)",required:!1},skills:{type:"string",description:"Install bundled Agent Skills to ~/.codex/skills: all|skip|<comma-separated names>"}},async run({args:e,rawArgs:t}){let o=ut(Be.homedir(),".codex","config.toml"),n=await mt(o),i=ut(Be.homedir(),".codex","notify.sh"),s=await mt(i),r=ut(Be.homedir(),".codex","AGENTS.md"),a=await mt(r),p=n?await vn(o):void 0,l=process.stdout.isTTY&&!e["dry-run"]&&!e["skip-confirmation"]&&!e.yes,c=wn(e.profile),d=yn(e["profile-mode"]),u=bn(e["profiles-scope"]),h=kn(e["codex-cli"]),v=process.platform==="darwin"||process.platform==="linux",k=typeof e.sound>"u"?void 0:String(e.sound).trim(),C=typeof e.tools>"u"?void 0:String(e.tools).trim(),A=e,D=typeof A.skills>"u"?void 0:String(A.skills).trim();if(k==="")throw new Error('Invalid --sound value (expected path, "none", or "skip")');if(C==="")throw new Error("Invalid --tools value (expected all|skip|<comma-separated tool ids>)");if(D==="")throw new Error("Invalid --skills value (expected all|skip|<comma-separated skill names>)");let q=t.some(g=>g==="--no-vscode"||g.startsWith("--no-vscode=")),K=await lt(We),Q=J(),ze=(c&&c!=="skip"?c:gt(p)?p:void 0)||"balanced",x=ze,H=d||"add",P=u||"single",pe=!0,W,B=v?"all":"skip",Ce=h||"auto",M,Z,m,w="skip",b,y;if(k&&(g=>{let $=g.trim().toLowerCase();if($==="skip"){M="no",m=void 0;return}M="yes",m=$==="none"?"none":g})(k),D){let g=D.trim().toLowerCase();if(g==="all")w="all";else if(g==="skip"||g==="none")w="skip";else{let $=D.split(",").map(U=>U.trim()).filter(Boolean);if($.length===0)throw new Error("Invalid --skills value (expected all|skip|<comma-separated skill names>)");let _=new Set(K.map(U=>U.id)),z=$.filter(U=>!_.has(U));if(z.length){let U=K.map(mo=>mo.id).join(", ")||"(none)";throw new Error(`Unknown skill(s): ${z.join(", ")}. Available: ${U}`)}w="select",b=$}}if(C){let g=C.trim().toLowerCase();if(g==="all")B="all";else if(g==="skip"||g==="none")B="skip";else{let $=C.split(",").map(z=>z.trim().toLowerCase()).filter(Boolean);if($.length===0)throw new Error("Invalid --tools value (expected all|skip|<comma-separated tool ids>)");let _=$.filter(z=>!X(z));if(_.length){let z=Q.map(U=>U.id).join(", ")||"(none)";throw new Error(`Unknown tool(s): ${_.join(", ")}. Available: ${z}`)}B="select",y=Array.from(new Set($)).filter(X)}}else v||(B="skip");if(l){F.log.info(`Codex 1up v${le} - equips your coding agent with powerful tools`),F.log.info("Install wizard");let g=await Qt({repoRoot:We,isUnixLike:v,globalAgentsExists:a,currentProfile:p,seededProfile:ze,bundledSkills:K,availableTools:Q,cliArgs:{profileChoice:c,profileMode:d,profileScope:u,soundArg:k,toolsArg:C,skillsArg:D},selections:{profileChoice:x,profileMode:H,profileScope:P,setDefaultProfile:pe,profilesSelected:W,installTools:B,toolsSelected:y,installCodexCli:Ce,notifyAction:M,globalAgentsAction:Z,notificationSound:m,skillsMode:w,skillsSelected:b}});if(!g)return;({profileChoice:x,profileMode:H,profileScope:P,setDefaultProfile:pe,profilesSelected:W,installTools:B,toolsSelected:y,installCodexCli:Ce,notifyAction:M,globalAgentsAction:Z,notificationSound:m,skillsMode:w,skillsSelected:b}=g.selections)}l||(P==="selected"&&W?.length&&gt(x)&&!W.includes(x)&&(x=W[0]),(P==="all"?[...hn]:P==="selected"?W||[]:x==="skip"?[]:[x]).length===0&&(pe=!1),typeof M>"u"&&(M=s?"no":"yes"),typeof Z>"u"&&(Z="skip"));let j={profile:x,profileScope:P,profileMode:H,setDefaultProfile:pe,profilesSelected:W,installCodexCli:Ce,installTools:B,toolsSelected:y,notify:M??(s?"no":"yes"),globalAgents:Z??"skip",notificationSound:m,skills:w,skillsSelected:b,mode:"manual",installNode:e["install-node"]||"skip",shell:String(e.shell||"auto"),vscodeId:q?void 0:e.vscode?String(e.vscode):void 0,noVscode:q||e["no-vscode"]||!1,agentsMd:typeof e["agents-md"]<"u"?String(e["agents-md"]||process.cwd()):void 0,dryRun:e["dry-run"]||!1,assumeYes:e.yes||!1,skipConfirmation:e["skip-confirmation"]||!1};if(l){F.log.info("Installing prerequisites and writing config..."),F.log.warn("Some steps may require sudo password or confirmation prompts.");try{await rt(j,We),F.log.success("Base install complete"),F.log.success("Install finished")}catch(g){throw F.cancel(`Installation failed: ${g}`),g}await at();return}try{await rt(j,We),await at()}catch(g){throw F.cancel(`Installation failed: ${g}`),g}}});async function mt(e){try{return await Zt.access(e),!0}catch{return!1}}function wn(e){if(e==null)return;let t=String(e).toLowerCase();if(gt(t))return t;if(t==="skip")return"skip";throw new Error("Invalid --profile value (use balanced|safe|yolo|skip).")}function yn(e){if(e==null)return;let t=String(e).toLowerCase();if(t==="add"||t==="overwrite")return t;throw new Error("Invalid --profile-mode value (use add|overwrite).")}function bn(e){if(e==null)return;let t=String(e).toLowerCase();if(t==="single"||t==="all")return t;throw new Error("Invalid --profiles-scope value (use single|all).")}function kn(e){if(e==null)return;let t=String(e).toLowerCase();if(t==="yes"||t==="no")return t;throw new Error("Expected yes|no")}function gt(e){return e==="balanced"||e==="safe"||e==="yolo"}async function vn(e){try{let t=await Zt.readFile(e,"utf8"),n=eo.parse(t).profile;return typeof n=="string"?n:void 0}catch(t){return}}import{defineCommand as Cn}from"citty";import{promises as ke}from"fs";import{resolve as oo,dirname as Sn}from"path";var $n=T();async function ht(e){try{return await ke.access(e),!0}catch{return!1}}async function xn(e,t){if(await ht(t)){let n=`${t}.backup.${new Date().toISOString().replace(/[:.]/g,"").replace("T","_").slice(0,15)}`;await ke.copyFile(t,n)}await ke.mkdir(Sn(t),{recursive:!0}),await ke.copyFile(e,t)}var no=Cn({meta:{name:"agents",description:"Write an AGENTS.md template"},args:{path:{type:"string",required:!0,description:"Target repo path or file"}},async run({args:e}){let t=String(e.path),o=oo($n,"templates/agent-templates","AGENTS-default.md"),i=await ht(t).then(async s=>s&&(await ke.stat(t)).isDirectory()).catch(()=>!1)?oo(t,"AGENTS.md"):t;if(!await ht(o))throw new Error(`Template not found: ${o}`);await xn(o,i),process.stdout.write(`Wrote ${i}
56
- `)}});import{defineCommand as In}from"citty";import{$ as Tn}from"zx";import{resolve as Pn}from"path";var Rn=T(),io=In({meta:{name:"doctor",description:"Run environment checks"},async run(){await Tn`bash ${Pn(Rn,"scripts/doctor.sh")}`}});import{defineCommand as An}from"citty";import{$ as En}from"zx";import{resolve as Nn}from"path";var Ln=T(),so=An({meta:{name:"uninstall",description:"Clean up aliases and config created by this tool"},async run(){await En`bash ${Nn(Ln,"scripts/uninstall.sh")}`}});import{defineCommand as Ue}from"citty";import{promises as ve}from"fs";import{resolve as bt,dirname as Dn}from"path";import jn from"os";var _n=T();function wt(){let e=bt(jn.homedir(),".codex"),t=bt(e,"config.toml");return{CODEX_HOME:e,CFG:t}}async function yt(e){return ve.readFile(e,"utf8")}async function ro(e,t){await ve.mkdir(Dn(e),{recursive:!0}),await ve.writeFile(e,t,"utf8")}function ao(e){let t=/^\[profiles\.(.+?)\]/gm,o=[],n;for(;n=t.exec(e);)o.push(n[1]);return o}function On(e,t){let o=`profile = "${t}"`;if(/^profile\s*=\s*".*"/m.test(e))return e.replace(/^profile\s*=\s*".*"/m,o);let n=e.indexOf(`
57
+ `),n.length>40&&f.log.info(`... (${n.length-40} more lines)`)}function gn(e){return be(e)?e:"balanced"}function be(e){return e==="balanced"||e==="safe"||e==="yolo"}function R(){return f.cancel("Install aborted"),null}var We=T(),wn=["balanced","safe","yolo"],oo=hn({meta:{name:"install",description:"Run the codex-1up installer with validated flags"},args:{yes:{type:"boolean",description:"Non-interactive; accept safe defaults"},"dry-run":{type:"boolean",description:"Print actions without making changes"},"skip-confirmation":{type:"boolean",description:"Skip prompts"},shell:{type:"string",description:"auto|zsh|bash|fish"},vscode:{type:"string",description:"Install VS Code extension id"},"no-vscode":{type:"boolean",description:"Skip VS Code extension checks"},"install-node":{type:"string",description:"nvm|brew|skip"},tools:{type:"string",description:"all|skip|<comma-separated tool ids> (rg, fd, fzf, jq, yq, ast-grep, bat, git, git-delta, gh)"},"codex-cli":{type:"string",description:"yes|no install/upgrade Codex CLI + ast-grep globally"},"profiles-scope":{type:"string",description:"single|all (write one profile or all profiles)"},profile:{type:"string",description:"balanced|safe|yolo|skip (choose profile to write)"},"profile-mode":{type:"string",description:"add|overwrite (profile table merge strategy)"},sound:{type:"string",description:'Sound file, "none", or "skip" to leave unchanged'},"agents-md":{type:"string",description:"Write starter AGENTS.md to PATH (default PWD/AGENTS.md)",required:!1},skills:{type:"string",description:"Install bundled Agent Skills to ~/.codex/skills: all|skip|<comma-separated names>"}},async run({args:e,rawArgs:t}){let o=ut(Be.homedir(),".codex","config.toml"),n=await mt(o),i=ut(Be.homedir(),".codex","notify.sh"),s=await mt(i),r=ut(Be.homedir(),".codex","AGENTS.md"),a=await mt(r),p=n?await Cn(o):void 0,l=process.stdout.isTTY&&!e["dry-run"]&&!e["skip-confirmation"]&&!e.yes,c=yn(e.profile),d=bn(e["profile-mode"]),u=kn(e["profiles-scope"]),h=vn(e["codex-cli"]),C=process.platform==="darwin"||process.platform==="linux",k=typeof e.sound>"u"?void 0:String(e.sound).trim(),S=typeof e.tools>"u"?void 0:String(e.tools).trim(),A=e,D=typeof A.skills>"u"?void 0:String(A.skills).trim();if(k==="")throw new Error('Invalid --sound value (expected path, "none", or "skip")');if(S==="")throw new Error("Invalid --tools value (expected all|skip|<comma-separated tool ids>)");if(D==="")throw new Error("Invalid --skills value (expected all|skip|<comma-separated skill names>)");let q=t.some(g=>g==="--no-vscode"||g.startsWith("--no-vscode=")),K=await lt(We),Q=J(),ze=(c&&c!=="skip"?c:gt(p)?p:void 0)||"balanced",x=ze,H=d||"add",P=u||"single",pe=!0,W,B=C?"all":"skip",Ce=h||"auto",G,Z,m,w="skip",b,y;if(k&&(g=>{let $=g.trim().toLowerCase();if($==="skip"){G="no",m=void 0;return}G="yes",m=$==="none"?"none":g})(k),D){let g=D.trim().toLowerCase();if(g==="all")w="all";else if(g==="skip"||g==="none")w="skip";else{let $=D.split(",").map(U=>U.trim()).filter(Boolean);if($.length===0)throw new Error("Invalid --skills value (expected all|skip|<comma-separated skill names>)");let _=new Set(K.map(U=>U.id)),z=$.filter(U=>!_.has(U));if(z.length){let U=K.map(go=>go.id).join(", ")||"(none)";throw new Error(`Unknown skill(s): ${z.join(", ")}. Available: ${U}`)}w="select",b=$}}if(S){let g=S.trim().toLowerCase();if(g==="all")B="all";else if(g==="skip"||g==="none")B="skip";else{let $=S.split(",").map(z=>z.trim().toLowerCase()).filter(Boolean);if($.length===0)throw new Error("Invalid --tools value (expected all|skip|<comma-separated tool ids>)");let _=$.filter(z=>!X(z));if(_.length){let z=Q.map(U=>U.id).join(", ")||"(none)";throw new Error(`Unknown tool(s): ${_.join(", ")}. Available: ${z}`)}B="select",y=Array.from(new Set($)).filter(X)}}else C||(B="skip");if(l){F.log.info(`Codex 1up v${le} - equips your coding agent with powerful tools`),F.log.info("Install wizard");let g=await Zt({repoRoot:We,isUnixLike:C,globalAgentsExists:a,currentProfile:p,seededProfile:ze,bundledSkills:K,availableTools:Q,cliArgs:{profileChoice:c,profileMode:d,profileScope:u,soundArg:k,toolsArg:S,skillsArg:D},selections:{profileChoice:x,profileMode:H,profileScope:P,setDefaultProfile:pe,profilesSelected:W,installTools:B,toolsSelected:y,installCodexCli:Ce,notifyAction:G,globalAgentsAction:Z,notificationSound:m,skillsMode:w,skillsSelected:b}});if(!g)return;({profileChoice:x,profileMode:H,profileScope:P,setDefaultProfile:pe,profilesSelected:W,installTools:B,toolsSelected:y,installCodexCli:Ce,notifyAction:G,globalAgentsAction:Z,notificationSound:m,skillsMode:w,skillsSelected:b}=g.selections)}l||(P==="selected"&&W?.length&&gt(x)&&!W.includes(x)&&(x=W[0]),(P==="all"?[...wn]:P==="selected"?W||[]:x==="skip"?[]:[x]).length===0&&(pe=!1),typeof G>"u"&&(G=s?"no":"yes"),typeof Z>"u"&&(Z="skip"));let j={profile:x,profileScope:P,profileMode:H,setDefaultProfile:pe,profilesSelected:W,installCodexCli:Ce,installTools:B,toolsSelected:y,notify:G??(s?"no":"yes"),globalAgents:Z??"skip",notificationSound:m,skills:w,skillsSelected:b,mode:"manual",installNode:e["install-node"]||"skip",shell:String(e.shell||"auto"),vscodeId:q?void 0:e.vscode?String(e.vscode):void 0,noVscode:q||e["no-vscode"]||!1,agentsMd:typeof e["agents-md"]<"u"?String(e["agents-md"]||process.cwd()):void 0,dryRun:e["dry-run"]||!1,assumeYes:e.yes||!1,skipConfirmation:e["skip-confirmation"]||!1};if(l){F.log.info("Installing prerequisites and writing config..."),F.log.warn("Some steps may require sudo password or confirmation prompts.");try{await rt(j,We),F.log.success("Base install complete"),F.log.success("Install finished")}catch(g){throw F.cancel(`Installation failed: ${g}`),g}await at();return}try{await rt(j,We),await at()}catch(g){throw F.cancel(`Installation failed: ${g}`),g}}});async function mt(e){try{return await eo.access(e),!0}catch{return!1}}function yn(e){if(e==null)return;let t=String(e).toLowerCase();if(gt(t))return t;if(t==="skip")return"skip";throw new Error("Invalid --profile value (use balanced|safe|yolo|skip).")}function bn(e){if(e==null)return;let t=String(e).toLowerCase();if(t==="add"||t==="overwrite")return t;throw new Error("Invalid --profile-mode value (use add|overwrite).")}function kn(e){if(e==null)return;let t=String(e).toLowerCase();if(t==="single"||t==="all")return t;throw new Error("Invalid --profiles-scope value (use single|all).")}function vn(e){if(e==null)return;let t=String(e).toLowerCase();if(t==="yes"||t==="no")return t;throw new Error("Expected yes|no")}function gt(e){return e==="balanced"||e==="safe"||e==="yolo"}async function Cn(e){try{let t=await eo.readFile(e,"utf8"),n=to.parse(t).profile;return typeof n=="string"?n:void 0}catch(t){return}}import{defineCommand as Sn}from"citty";import{promises as ke}from"fs";import{resolve as no,dirname as $n}from"path";var xn=T();async function ht(e){try{return await ke.access(e),!0}catch{return!1}}async function In(e,t){if(await ht(t)){let n=`${t}.backup.${new Date().toISOString().replace(/[:.]/g,"").replace("T","_").slice(0,15)}`;await ke.copyFile(t,n)}await ke.mkdir($n(t),{recursive:!0}),await ke.copyFile(e,t)}var io=Sn({meta:{name:"agents",description:"Write an AGENTS.md template"},args:{path:{type:"string",required:!0,description:"Target repo path or file"}},async run({args:e}){let t=String(e.path),o=no(xn,"templates/agent-templates","AGENTS-default.md"),i=await ht(t).then(async s=>s&&(await ke.stat(t)).isDirectory()).catch(()=>!1)?no(t,"AGENTS.md"):t;if(!await ht(o))throw new Error(`Template not found: ${o}`);await In(o,i),process.stdout.write(`Wrote ${i}
58
+ `)}});import{defineCommand as Tn}from"citty";import{$ as Pn}from"zx";import{resolve as Rn}from"path";var An=T(),so=Tn({meta:{name:"doctor",description:"Run environment checks"},async run(){await Pn`bash ${Rn(An,"scripts/doctor.sh")}`}});import{defineCommand as En}from"citty";import{$ as Nn}from"zx";import{resolve as Ln}from"path";var Dn=T(),ro=En({meta:{name:"uninstall",description:"Clean up aliases and config created by this tool"},async run(){await Nn`bash ${Ln(Dn,"scripts/uninstall.sh")}`}});import{defineCommand as Ue}from"citty";import{promises as ve}from"fs";import{resolve as bt,dirname as jn}from"path";import _n from"os";var On=T();function wt(){let e=bt(_n.homedir(),".codex"),t=bt(e,"config.toml");return{CODEX_HOME:e,CFG:t}}async function yt(e){return ve.readFile(e,"utf8")}async function ao(e,t){await ve.mkdir(jn(e),{recursive:!0}),await ve.writeFile(e,t,"utf8")}function lo(e){let t=/^\[profiles\.(.+?)\]/gm,o=[],n;for(;n=t.exec(e);)o.push(n[1]);return o}function Mn(e,t){let o=`profile = "${t}"`;if(/^profile\s*=\s*".*"/m.test(e))return e.replace(/^profile\s*=\s*".*"/m,o);let n=e.indexOf(`
57
59
  `);return n===-1?o+`
58
60
  `+e:e.slice(0,n+1)+o+`
59
- `+e.slice(n+1)}var lo=Ue({meta:{name:"config",description:"Manage Codex config profiles"},subCommands:{init:Ue({meta:{name:"init",description:"Install unified config with multiple profiles"},args:{force:{type:"boolean",description:"Backup and overwrite if exists"}},async run({args:e}){let t=bt(_n,"templates/codex-config.toml"),o=await yt(t),{CFG:n}=wt(),i=await ve.access(n).then(()=>!0).catch(()=>!1);if(i&&!e.force){process.stdout.write(`${n} exists. Use --force to overwrite.
61
+ `+e.slice(n+1)}var po=Ue({meta:{name:"config",description:"Manage Codex config profiles"},subCommands:{init:Ue({meta:{name:"init",description:"Install unified config with multiple profiles"},args:{force:{type:"boolean",description:"Backup and overwrite if exists"}},async run({args:e}){let t=bt(On,"templates/codex-config.toml"),o=await yt(t),{CFG:n}=wt(),i=await ve.access(n).then(()=>!0).catch(()=>!1);if(i&&!e.force){process.stdout.write(`${n} exists. Use --force to overwrite.
60
62
  `);return}if(i){let s=`${n}.backup.${Date.now()}`;await ve.copyFile(n,s),process.stdout.write(`Backed up to ${s}
61
- `)}await ro(n,o),process.stdout.write(`Wrote ${n}
62
- `)}}),profiles:Ue({meta:{name:"profiles",description:"List profiles in the current config"},async run(){let{CFG:e}=wt(),t=await yt(e),o=ao(t);process.stdout.write(o.length?o.join(`
63
+ `)}await ao(n,o),process.stdout.write(`Wrote ${n}
64
+ `)}}),profiles:Ue({meta:{name:"profiles",description:"List profiles in the current config"},async run(){let{CFG:e}=wt(),t=await yt(e),o=lo(t);process.stdout.write(o.length?o.join(`
63
65
  `)+`
64
66
  `:`No profiles found
65
- `)}}),"set-profile":Ue({meta:{name:"set-profile",description:"Set the active profile in config.toml"},args:{name:{type:"positional",required:!0,description:"Profile name"}},async run({args:e}){let{CFG:t}=wt(),o=await yt(t),n=ao(o),i=String(e.name);if(!n.includes(i))throw new Error(`Unknown profile: ${i}`);let s=On(o,i);await ro(t,s),process.stdout.write(`profile set to ${i}
66
- `)}})}});import{defineCommand as Gn}from"citty";var po=Gn({meta:{name:"update",description:"Check for and apply codex-1up updates"},args:{yes:{type:"boolean",description:"Non-interactive; apply updates without prompting"},"dry-run":{type:"boolean",description:"Print actions without making changes"},"skip-confirmation":{type:"boolean",description:"Skip prompts"}},async run({args:e}){let t=await ae(),o=process.stdout.isTTY&&!e["dry-run"]&&!e["skip-confirmation"]&&!e.yes;await Me({interactive:o,assumeYes:!!e.yes,skipConfirmation:!!e["skip-confirmation"],dryRun:!!e["dry-run"],logger:t.logger})}});import{defineCommand as Ve}from"citty";var co=Ve({meta:{name:"tools",description:"Manage developer tools"},subCommands:{list:Ve({meta:{name:"list",description:"List known tools and installation status"},async run(){let e=await he();for(let t of e)process.stdout.write(`${t.id} ${t.installed?"\u2713":"\u2716"}
67
- `)}}),install:Ve({meta:{name:"install",description:"Install tools by id or all"},args:{tool:{type:"positional",required:!0,description:'Tool id or "all"'},"dry-run":{type:"boolean",description:"Print actions without making changes"}},async run({args:e}){let t=String(e.tool||"").trim().toLowerCase();if(!t)throw new Error("Tool id required");if(t==="all"){await it("all",{dryRun:!!e["dry-run"]});return}let o=t.split(",").map(s=>s.trim()).filter(Boolean),n=Array.from(new Set(o)),i=n.filter(s=>!X(s));if(i.length){let s=Bt().join(", ");throw new Error(`Unknown tool id(s): ${i.join(", ")}. Known: ${s}`)}await it(n,{dryRun:!!e["dry-run"]})}}),doctor:Ve({meta:{name:"doctor",description:"Show missing tools and hints"},async run(){let t=(await he()).filter(n=>!n.installed).map(n=>n.id);if(t.length===0){process.stdout.write(`All tools are installed.
67
+ `)}}),"set-profile":Ue({meta:{name:"set-profile",description:"Set the active profile in config.toml"},args:{name:{type:"positional",required:!0,description:"Profile name"}},async run({args:e}){let{CFG:t}=wt(),o=await yt(t),n=lo(o),i=String(e.name);if(!n.includes(i))throw new Error(`Unknown profile: ${i}`);let s=Mn(o,i);await ao(t,s),process.stdout.write(`profile set to ${i}
68
+ `)}})}});import{defineCommand as Gn}from"citty";var co=Gn({meta:{name:"update",description:"Check for and apply codex-1up updates"},args:{yes:{type:"boolean",description:"Non-interactive; apply updates without prompting"},"dry-run":{type:"boolean",description:"Print actions without making changes"},"skip-confirmation":{type:"boolean",description:"Skip prompts"}},async run({args:e}){let t=await ae(),o=process.stdout.isTTY&&!e["dry-run"]&&!e["skip-confirmation"]&&!e.yes;await Ge({interactive:o,assumeYes:!!e.yes,skipConfirmation:!!e["skip-confirmation"],dryRun:!!e["dry-run"],logger:t.logger})}});import{defineCommand as Ve}from"citty";var fo=Ve({meta:{name:"tools",description:"Manage developer tools"},subCommands:{list:Ve({meta:{name:"list",description:"List known tools and installation status"},async run(){let e=await he();for(let t of e)process.stdout.write(`${t.id} ${t.installed?"\u2713":"\u2716"}
69
+ `)}}),install:Ve({meta:{name:"install",description:"Install tools by id or all"},args:{tool:{type:"positional",required:!0,description:'Tool id or "all"'},"dry-run":{type:"boolean",description:"Print actions without making changes"}},async run({args:e}){let t=String(e.tool||"").trim().toLowerCase();if(!t)throw new Error("Tool id required");if(t==="all"){await it("all",{dryRun:!!e["dry-run"]});return}let o=t.split(",").map(s=>s.trim()).filter(Boolean),n=Array.from(new Set(o)),i=n.filter(s=>!X(s));if(i.length){let s=Ut().join(", ");throw new Error(`Unknown tool id(s): ${i.join(", ")}. Known: ${s}`)}await it(n,{dryRun:!!e["dry-run"]})}}),doctor:Ve({meta:{name:"doctor",description:"Show missing tools and hints"},async run(){let t=(await he()).filter(n=>!n.installed).map(n=>n.id);if(t.length===0){process.stdout.write(`All tools are installed.
68
70
  `);return}let o=J().map(n=>n.id).join(", ");process.stdout.write(`Missing tools: ${t.join(", ")}
69
71
  `),process.stdout.write(`Known tools: ${o}
70
- `)}})}});import{defineCommand as qe}from"citty";var fo=qe({meta:{name:"skills",description:"Manage bundled Agent Skills"},subCommands:{list:qe({meta:{name:"list",description:"List bundled and installed skills"},async run(){let e=T(),t=await pt(e),o=await qt();if(process.stdout.write(`Bundled skills:
72
+ `)}})}});import{defineCommand as qe}from"citty";var uo=qe({meta:{name:"skills",description:"Manage bundled Agent Skills"},subCommands:{list:qe({meta:{name:"list",description:"List bundled and installed skills"},async run(){let e=T(),t=await pt(e),o=await zt();if(process.stdout.write(`Bundled skills:
71
73
  `),t.length===0)process.stdout.write(` (none)
72
74
  `);else for(let n of t)process.stdout.write(` ${n.id} \u2014 ${n.description}
73
75
  `);if(process.stdout.write(`
74
76
  Installed skills:
75
77
  `),o.length===0)process.stdout.write(` (none)
76
78
  `);else for(let n of o)process.stdout.write(` ${n.id}
77
- `)}}),install:qe({meta:{name:"install",description:"Install bundled skills by id or all"},args:{name:{type:"positional",required:!0,description:'Skill id or "all"'},"dry-run":{type:"boolean",description:"Print actions without making changes"}},async run({args:e}){let t=String(e.name||"").trim();if(!t)throw new Error("Skill id required");if(t==="all"){await _e("all",void 0,{dryRun:!!e["dry-run"]});return}let o=T(),n=await pt(o),i=t.split(",").map(p=>p.trim()).filter(Boolean),s=new Set(n.map(p=>p.id)),r=new Set(n.map(p=>p.name)),a=i.filter(p=>!s.has(p)&&!r.has(p));if(a.length){let p=n.map(l=>l.id).join(", ")||"(none)";throw new Error(`Unknown skill(s): ${a.join(", ")}. Available: ${p}`)}await _e("select",i,{dryRun:!!e["dry-run"]})}}),refresh:qe({meta:{name:"refresh",description:"Reinstall bundled skills into ~/.codex/skills"},args:{"dry-run":{type:"boolean",description:"Print actions without making changes"}},async run({args:e}){await _e("all",void 0,{dryRun:!!e["dry-run"]})}})}});var uo=Mn({meta:{name:"codex-1up",version:le,description:Yt},subCommands:{install:to,agents:no,doctor:io,uninstall:so,config:lo,update:po,tools:co,skills:fo}});Fn(uo);
79
+ `)}}),install:qe({meta:{name:"install",description:"Install bundled skills by id or all"},args:{name:{type:"positional",required:!0,description:'Skill id or "all"'},"dry-run":{type:"boolean",description:"Print actions without making changes"}},async run({args:e}){let t=String(e.name||"").trim();if(!t)throw new Error("Skill id required");if(t==="all"){await _e("all",void 0,{dryRun:!!e["dry-run"]});return}let o=T(),n=await pt(o),i=t.split(",").map(p=>p.trim()).filter(Boolean),s=new Set(n.map(p=>p.id)),r=new Set(n.map(p=>p.name)),a=i.filter(p=>!s.has(p)&&!r.has(p));if(a.length){let p=n.map(l=>l.id).join(", ")||"(none)";throw new Error(`Unknown skill(s): ${a.join(", ")}. Available: ${p}`)}await _e("select",i,{dryRun:!!e["dry-run"]})}}),refresh:qe({meta:{name:"refresh",description:"Reinstall bundled skills into ~/.codex/skills"},args:{"dry-run":{type:"boolean",description:"Print actions without making changes"}},async run({args:e}){await _e("all",void 0,{dryRun:!!e["dry-run"]})}})}});var mo=Fn({meta:{name:"codex-1up",version:le,description:Jt},subCommands:{install:oo,agents:io,doctor:so,uninstall:ro,config:po,update:co,tools:fo,skills:uo}});Wn(mo);
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "codex-1up",
3
3
  "private": false,
4
4
  "type": "module",
5
- "version": "0.3.10",
5
+ "version": "0.3.12",
6
6
  "description": "TypeScript CLI for codex-1up (citty-based)",
7
7
  "bin": {
8
8
  "codex-1up": "bin/codex-1up.mjs"
@@ -40,6 +40,7 @@ const description = escapeRubyString(pkg.description || 'Command-line interface'
40
40
  const homepage = resolveHomepage(pkg.repository)
41
41
  const license = normalizeLicense(pkg.license)
42
42
  const binName = resolveBinName(pkg.bin, pkgName)
43
+ const binRelPath = resolveBinRelPath(pkg.bin, pkgName, binName)
43
44
 
44
45
  const formula = `class ${formulaClass} < Formula
45
46
  desc "${description}"
@@ -52,7 +53,10 @@ const formula = `class ${formulaClass} < Formula
52
53
 
53
54
  def install
54
55
  ENV["HOME"] = buildpath
55
- system "npm", "install", *std_npm_install_args
56
+ system "npm", "install", *std_npm_args
57
+ # npm install doesn't reliably create prefix/bin shims for ESM .mjs bins;
58
+ # install the package's bin entrypoint explicitly.
59
+ bin.install libexec/"lib/node_modules/${pkgName}/${binRelPath}" => "${binName}"
56
60
  end
57
61
 
58
62
  test do
@@ -117,3 +121,15 @@ function resolveBinName(bin, fallback) {
117
121
  }
118
122
  return fallback
119
123
  }
124
+
125
+ function resolveBinRelPath(bin, pkgName, binName) {
126
+ if (!bin) return `bin/${pkgName}.mjs`
127
+ if (typeof bin === 'string') return bin
128
+ if (typeof bin === 'object' && bin[binName]) return String(bin[binName])
129
+ // Fallback: first value in the map.
130
+ if (typeof bin === 'object') {
131
+ const values = Object.values(bin).map(String).filter(Boolean)
132
+ if (values.length > 0) return values[0]
133
+ }
134
+ return `bin/${pkgName}.mjs`
135
+ }