codex-1up 0.2.4 → 0.2.5

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.
Files changed (3) hide show
  1. package/README.md +1 -1
  2. package/dist/main.js +42 -34
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -65,7 +65,7 @@ You can keep a global guidance file at `~/.codex/AGENTS.md` that Codex will use
65
65
  ```bash
66
66
  # Create the directory if needed and write the template there
67
67
  mkdir -p ~/.codex
68
- ./bin/codex-1up agents --path ~/.codex
68
+ codex-1up agents --path ~/.codex
69
69
  # This writes ~/.codex/AGENTS.md
70
70
  ```
71
71
 
package/dist/main.js CHANGED
@@ -1,53 +1,61 @@
1
- import{runMain as hn}from"citty";import{defineCommand as pn}from"citty";import{readFileSync as fn}from"fs";import{fileURLToPath as dn}from"url";import{dirname as cn,join as un}from"path";import{defineCommand as St}from"citty";import{fileURLToPath as Rt}from"url";import{dirname as Et,resolve as D}from"path";import{promises as X}from"fs";import*as J from"os";import{accessSync as Pt}from"fs";import*as ye from"toml";import*as l from"@clack/prompts";import{which as G,$ as K}from"zx";import Ct from"fs-extra";import*as me from"path";import*as qe from"os";import{createWriteStream as it}from"fs";function Re(e){let t=null;try{t=it(e,{flags:"a"})}catch{}let n=(i,o)=>{let r=i?`${i} ${o}
2
- `:`${o}
3
- `;process.stdout.write(r),t&&t.write(r)};return{log:i=>n("",i),info:i=>n("",i),ok:i=>n("\u2714",i),warn:i=>n("\u26A0",i),err:i=>n("\u2716",i)}}import{$ as L}from"zx";import{which as rt,$ as st}from"zx";import{spawn as at}from"child_process";async function c(e){try{return await rt(e),!0}catch{return!1}}async function Ee(){return await c("brew")?"brew":await c("apt-get")?"apt":await c("dnf")?"dnf":await c("pacman")?"pacman":await c("zypper")?"zypper":"none"}async function ee(e){if(await c("pnpm"))try{if((await st`pnpm bin -g`.quiet()).stdout.trim())return"pnpm";e?.warn('Detected pnpm but global bin dir is not configured; skipping global Node installs to avoid duplicates. Run "pnpm setup" then re-run.')}catch{e?.warn('Detected pnpm but global bin dir is not configured; skipping global Node installs to avoid duplicates. Run "pnpm setup" then re-run.')}return await c("pnpm")?"none":"npm"}async function g(e,t,n={dryRun:!1}){if(n.dryRun){let o=[e,...t].map(r=>r.includes(" ")?`"${r}"`:r).join(" ");n.logger?.log(`[dry-run] ${o}`);return}let i=at(e,t,{stdio:"inherit",cwd:n.cwd||process.cwd(),shell:!1});await new Promise((o,r)=>{i.on("error",r),i.on("exit",s=>{if(s===0)return o();r(new Error(`Command failed (${s}): ${e} ${t.join(" ")}`))})})}function T(e){let t=new Date().toISOString().replace(/[:.]/g,"-").slice(0,-5);return`${e}.backup.${t}`}import Pe from"fs-extra";import*as U from"path";import*as z from"os";async function Ie(e){let t=await c("node"),n=await c("npm");if(t&&n){let o=(await L`node -v`).stdout.trim();e.logger.ok(`Node.js present (${o})`);return}switch(e.options.installNode){case"nvm":await lt(e);break;case"brew":await pt(e);break;case"skip":e.logger.warn("Skipping Node installation; please install Node 18+ manually");return}if(await c("node")){let o=(await L`node -v`).stdout.trim();e.logger.ok(`Node.js installed (${o})`)}else throw e.logger.err("Node installation failed"),new Error("Node.js installation failed")}async function lt(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=U.join(e.homeDir,".nvm"),n=U.join(t,"nvm.sh");await Pe.pathExists(t)||(e.logger.info("Installing nvm..."),await L`bash -c "curl -fsSL https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash"`);let i=`export NVM_DIR="${t}" && [ -s "$NVM_DIR/nvm.sh" ] && . "$NVM_DIR/nvm.sh" && nvm install --lts`;await L`bash -c ${i}`}async function pt(e){if(e.logger.info("Installing Node.js via Homebrew"),!await c("brew"))if(z.platform()==="darwin"){if(e.logger.info("Homebrew not found; installing Homebrew"),e.options.dryRun){e.logger.log("[dry-run] install Homebrew");return}await L`/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"`;let t=z.platform()==="darwin"&&z.arch()==="arm64"?"/opt/homebrew/bin/brew":"/usr/local/bin/brew";if(await Pe.pathExists(t)){let n=U.dirname(t);process.env.PATH=`${n}:${process.env.PATH||""}`;try{let o=(await L`${t} shellenv`).stdout.trim().match(/export PATH="([^"]+)"/);o&&(process.env.PATH=`${o[1]}:${process.env.PATH||""}`)}catch{}}}else throw new Error("Homebrew is only available on macOS");await g("brew",["install","node"],{dryRun:e.options.dryRun,logger:e.logger})}import{$ as fe}from"zx";var ft=["@openai/codex"],dt="@openai/codex";async function Ne(e){if(e.options.installCodexCli==="no"){e.logger.info("Skipping Codex CLI install (user choice)");return}e.logger.info("Checking global packages (@openai/codex)");let t=[];for(let n of ft)try{if(n===dt&&await c("codex")){e.logger.ok("codex found on PATH; skipping global install/upgrade");continue}let o=(await fe`npm view ${n} version`.quiet()).stdout.trim();if(!o){e.logger.warn(`Could not fetch latest version for ${n}; skipping upgrade check`);continue}let r=await fe`npm ls -g ${n} --depth=0 --json`.quiet().nothrow(),s="";try{s=JSON.parse(r.stdout||"{}").dependencies?.[n]?.version||""}catch{s=""}s?s!==o?(e.logger.info(`${n} ${s} -> ${o}`),t.push(`${n}@${o}`)):e.logger.ok(`${n} up-to-date (${s})`):(e.logger.info(`${n} not installed; will install @${o}`),t.push(`${n}@${o}`))}catch(i){e.logger.warn(`Error checking ${n}: ${i}`);let o=await fe`npm ls -g ${n} --depth=0 --json`.quiet().nothrow(),r="";try{r=JSON.parse(o.stdout||"{}").dependencies?.[n]?.version||""}catch{r=""}r||t.push(n)}if(t.length>0){let n=await ee(e.logger);n==="none"?e.logger.warn('Skipping global Node installs because pnpm is detected but not configured. Run "pnpm setup" and re-run the installer.'):n==="pnpm"?(e.logger.info("Installing/updating global packages via pnpm"),await g("pnpm",["add","-g",...t],{dryRun:e.options.dryRun,logger:e.logger})):(e.logger.info("Installing/updating global packages via npm"),await g("npm",["install","-g",...t],{dryRun:e.options.dryRun,logger:e.logger}))}else e.logger.ok("Global packages are up-to-date");await c("codex")?e.logger.ok("Codex CLI installed"):e.logger.err("Codex CLI not found after install")}import{$ as ct}from"zx";import*as ce from"path";import de from"fs-extra";var ut={brew:["fd","ripgrep","fzf","jq","yq","difftastic","ast-grep"],apt:["ripgrep","fzf","jq","yq","git-delta"],dnf:["ripgrep","fd-find","fzf","jq","yq","git-delta"],pacman:["ripgrep","fd","fzf","jq","yq","git-delta"],zypper:["ripgrep","fd","fzf","jq","yq","git-delta"],none:[]};async function Te(e){if(e.options.installTools==="no"){e.logger.info("Skipping developer tool installs (user choice)");return}let t=await Ee();if(e.logger.info(`Detected package manager: ${t}`),t==="none"){e.logger.warn("Could not detect a supported package manager; please install tools manually");return}let n=ut[t]||[];if(n.length>0)switch(t){case"brew":await g("brew",["update"],{dryRun:e.options.dryRun,logger:e.logger}),await g("brew",["install",...n],{dryRun:e.options.dryRun,logger:e.logger});break;case"apt":await g("sudo",["apt-get","update","-y"],{dryRun:e.options.dryRun,logger:e.logger}),await g("sudo",["apt-get","install","-y",...n],{dryRun:e.options.dryRun,logger:e.logger}).catch(()=>{}),await c("fd")||await g("sudo",["apt-get","install","-y","fd-find"],{dryRun:e.options.dryRun,logger:e.logger}).catch(()=>{});break;case"dnf":await g("sudo",["dnf","install","-y",...n],{dryRun:e.options.dryRun,logger:e.logger}).catch(()=>{});break;case"pacman":await g("sudo",["pacman","-Sy","--noconfirm",...n],{dryRun:e.options.dryRun,logger:e.logger}).catch(()=>{});break;case"zypper":await g("sudo",["zypper","refresh"],{dryRun:e.options.dryRun,logger:e.logger}),await g("sudo",["zypper","install","-y",...n],{dryRun:e.options.dryRun,logger:e.logger}).catch(()=>{});break}if(!await c("difft")&&!await c("difftastic")&&(await c("cargo")?(e.logger.info("Installing difftastic via cargo"),await g("cargo",["install","difftastic"],{dryRun:e.options.dryRun,logger:e.logger})):e.logger.warn("difftastic not found and Rust/cargo missing; falling back to git-delta")),await gt(e,t),await c("fdfind")&&!await c("fd")){let o=ce.join(e.homeDir,".local","bin");await de.ensureDir(o);let r=(await ct`command -v fdfind`).stdout.trim(),s=ce.join(o,"fd");await de.pathExists(s)||(e.options.dryRun?e.logger.log(`[dry-run] ln -s ${r} ${s}`):await de.symlink(r,s),e.logger.ok("fd alias created at ~/.local/bin/fd"))}let i=["fd","fdfind","rg","fzf","jq","yq","difft","difftastic","delta","ast-grep"];for(let o of i)await c(o)&&e.logger.ok(`${o} \u2713`)}async function gt(e,t){if(await c("sg")||await c("ast-grep"))return;let i=await(async()=>{switch(t){case"brew":return await g("brew",["install","ast-grep"],{dryRun:e.options.dryRun,logger:e.logger}),!0;case"apt":return await g("sudo",["apt-get","install","-y","ast-grep"],{dryRun:e.options.dryRun,logger:e.logger}).catch(()=>{}),!0;case"dnf":return await g("sudo",["dnf","install","-y","ast-grep"],{dryRun:e.options.dryRun,logger:e.logger}).catch(()=>{}),!0;case"pacman":return await g("sudo",["pacman","-Sy","--noconfirm","ast-grep"],{dryRun:e.options.dryRun,logger:e.logger}).catch(()=>{}),!0;case"zypper":return await g("sudo",["zypper","install","-y","ast-grep"],{dryRun:e.options.dryRun,logger:e.logger}).catch(()=>{}),!0;default:return!1}})();if(await c("sg")||await c("ast-grep"))return;let o=await ee(e.logger);o==="pnpm"?(e.logger.info("Installing ast-grep via pnpm -g"),await g("pnpm",["add","-g","@ast-grep/cli"],{dryRun:e.options.dryRun,logger:e.logger})):o==="npm"?(e.logger.info("Installing ast-grep via npm -g"),await g("npm",["install","-g","@ast-grep/cli"],{dryRun:e.options.dryRun,logger:e.logger})):i||e.logger.warn("ast-grep not installed (no supported package manager or global npm). Install manually from https://ast-grep.github.io/")}import V from"fs-extra";import*as ne from"path";var mt={balanced:{root:[["approval_policy",'"on-request"'],["sandbox_mode",'"workspace-write"'],["model",'"gpt-5.1-codex"'],["model_reasoning_effort",'"medium"']],features:[["web_search_request","true"]]},safe:{root:[["approval_policy",'"on-failure"'],["sandbox_mode",'"workspace-write"'],["model",'"gpt-5.1-codex"'],["model_reasoning_effort",'"medium"']],features:[["web_search_request","false"]]},minimal:{root:[["model",'"gpt-5.1-codex"'],["model_reasoning_effort",'"medium"']],features:[["web_search_request","false"]]},yolo:{root:[["approval_policy",'"never"'],["sandbox_mode",'"danger-full-access"'],["model",'"gpt-5.1-codex"'],["model_reasoning_effort",'"medium"'],["model_reasoning_summary",'"detailed"'],["model_verbosity",'"high"'],["tool_output_token_limit","25000"]],features:[["web_search_request","true"]]}},ht=`# ~/.codex/config.toml \u2014 managed by codex-1up (patch mode)
4
- `;async function xe(e){let t=ne.join(e.homeDir,".codex","config.toml");await V.ensureDir(ne.dirname(t));let n=await V.pathExists(t),i=n?await V.readFile(t,"utf8"):ht,o=new ge(i),r=!1;if(r=wt(o,e.options.profile,e.options.profileMode)||r,r=yt(o,e.options.profile,e.options.setDefaultProfile)||r,r=bt(o,e.options.notificationSound)||r,!r){e.logger.info("Config already up to date; no changes needed.");return}let s=o.content();if(e.options.dryRun){e.logger.log(`[dry-run] write ${t}`),e.logger.log(s);return}if(n){let a=T(t);await V.copy(t,a),e.logger.info(`Backed up current config to ${a}`)}await V.writeFile(t,s,"utf8"),e.logger.ok("Updated ~/.codex/config.toml with requested settings.")}function wt(e,t,n){if(t==="skip")return!1;let i=mt[t],o=!1;if(n==="overwrite")o=e.replaceTable(`profiles.${t}`,i.root)||o,o=e.replaceTable(`profiles.${t}.features`,i.features)||o;else{e.ensureTable(`profiles.${t}`);for(let[r,s]of i.root)o=e.setKey(`profiles.${t}`,r,s,{mode:"if-missing"})||o;e.ensureTable(`profiles.${t}.features`);for(let[r,s]of i.features)o=e.setKey(`profiles.${t}.features`,r,s,{mode:"if-missing"})||o}return o}function yt(e,t,n){return!n||t==="skip"?!1:e.setRootKey("profile",`"${t}"`,{mode:"force"})}function bt(e,t){if(!t||t==="none")return!1;e.ensureTable("tui");let n=e.getValue("tui","notifications");if(n){let i=n.trim().toLowerCase();if(i.startsWith("true")||i.startsWith("["))return!1}return e.setKey("tui","notifications","true",{mode:"force"})}var ge=class{text;constructor(t){this.text=t||""}content(){return $t(this.text)}ensureTable(t){if(this.hasTable(t))return!1;let n=this.text.length===0?"":De(this.text);return this.text=n+`[${t}]
5
- `,!0}setKey(t,n,i,o){let r=te(this.text,t);if(!r)return this.ensureTable(t),this.setKey(t,n,i,o);let s=this.text.slice(r.start,r.end),d=new RegExp(`^\\s*${ue(n)}\\s*=.*$`,"m").exec(s);if(d){if(o.mode==="if-missing")return!1;let k=this.text,N=r.start+d.index,x=N+d[0].length;return this.text=k.slice(0,N)+`${n} = ${i}`+k.slice(x),this.text!==k}let m=this.text,b=r.end,h=m.slice(0,b),v=m.slice(b),p=h.length>0&&!h.endsWith(`
6
- `),f=v.length>0&&!v.startsWith(`
1
+ import{runMain as ho}from"citty";import{defineCommand as lo}from"citty";import{readFileSync as po}from"fs";import{fileURLToPath as co}from"url";import{dirname as fo,join as uo}from"path";import{defineCommand as St}from"citty";import{fileURLToPath as Rt}from"url";import{dirname as Et,resolve as x}from"path";import{promises as X}from"fs";import*as J from"os";import{accessSync as Pt}from"fs";import*as ye from"toml";import*as l from"@clack/prompts";import{which as F,$ as K}from"zx";import Ct from"fs-extra";import*as me from"path";import*as Me from"os";import{createWriteStream as it}from"fs";function Re(e){let t=null;try{t=it(e,{flags:"a"})}catch{}let o=(i,n)=>{let r=i?`${i} ${n}
2
+ `:`${n}
3
+ `;process.stdout.write(r),t&&t.write(r)};return{log:i=>o("",i),info:i=>o("",i),ok:i=>o("\u2714",i),warn:i=>o("\u26A0",i),err:i=>o("\u2716",i)}}import{$ as L}from"zx";import{which as rt,$ as at}from"zx";import{spawn as st}from"child_process";async function u(e){try{return await rt(e),!0}catch{return!1}}async function Ee(){return await u("brew")?"brew":await u("apt-get")?"apt":await u("dnf")?"dnf":await u("pacman")?"pacman":await u("zypper")?"zypper":"none"}async function ee(e){if(await u("pnpm"))try{if((await at`pnpm bin -g`.quiet()).stdout.trim())return"pnpm";e?.warn('Detected pnpm but global bin dir is not configured; skipping global Node installs to avoid duplicates. Run "pnpm setup" then re-run.')}catch{e?.warn('Detected pnpm but global bin dir is not configured; skipping global Node installs to avoid duplicates. Run "pnpm setup" then re-run.')}return await u("pnpm")?"none":"npm"}async function g(e,t,o={dryRun:!1}){if(o.dryRun){let n=[e,...t].map(r=>r.includes(" ")?`"${r}"`:r).join(" ");o.logger?.log(`[dry-run] ${n}`);return}let i=st(e,t,{stdio:"inherit",cwd:o.cwd||process.cwd(),shell:!1});await new Promise((n,r)=>{i.on("error",r),i.on("exit",a=>{if(a===0)return n();r(new Error(`Command failed (${a}): ${e} ${t.join(" ")}`))})})}function T(e){let t=new Date().toISOString().replace(/[:.]/g,"-").slice(0,-5);return`${e}.backup.${t}`}import Pe from"fs-extra";import*as U from"path";import*as z from"os";async function Ie(e){let t=await u("node"),o=await u("npm");if(t&&o){let n=(await L`node -v`).stdout.trim();e.logger.ok(`Node.js present (${n})`);return}switch(e.options.installNode){case"nvm":await lt(e);break;case"brew":await pt(e);break;case"skip":e.logger.warn("Skipping Node installation; please install Node 18+ manually");return}if(await u("node")){let n=(await L`node -v`).stdout.trim();e.logger.ok(`Node.js installed (${n})`)}else throw e.logger.err("Node installation failed"),new Error("Node.js installation failed")}async function lt(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=U.join(e.homeDir,".nvm"),o=U.join(t,"nvm.sh");await Pe.pathExists(t)||(e.logger.info("Installing nvm..."),await L`bash -c "curl -fsSL https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash"`);let i=`export NVM_DIR="${t}" && [ -s "$NVM_DIR/nvm.sh" ] && . "$NVM_DIR/nvm.sh" && nvm install --lts`;await L`bash -c ${i}`}async function pt(e){if(e.logger.info("Installing Node.js via Homebrew"),!await u("brew"))if(z.platform()==="darwin"){if(e.logger.info("Homebrew not found; installing Homebrew"),e.options.dryRun){e.logger.log("[dry-run] install Homebrew");return}await L`/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"`;let t=z.platform()==="darwin"&&z.arch()==="arm64"?"/opt/homebrew/bin/brew":"/usr/local/bin/brew";if(await Pe.pathExists(t)){let o=U.dirname(t);process.env.PATH=`${o}:${process.env.PATH||""}`;try{let n=(await L`${t} shellenv`).stdout.trim().match(/export PATH="([^"]+)"/);n&&(process.env.PATH=`${n[1]}:${process.env.PATH||""}`)}catch{}}}else throw new Error("Homebrew is only available on macOS");await g("brew",["install","node"],{dryRun:e.options.dryRun,logger:e.logger})}import{$ as de}from"zx";var dt=["@openai/codex"],ct="@openai/codex";async function Ne(e){if(e.options.installCodexCli==="no"){e.logger.info("Skipping Codex CLI install (user choice)");return}e.logger.info("Checking global packages (@openai/codex)");let t=[];for(let o of dt)try{if(o===ct&&await u("codex")){e.logger.ok("codex found on PATH; skipping global install/upgrade");continue}let n=(await de`npm view ${o} version`.quiet()).stdout.trim();if(!n){e.logger.warn(`Could not fetch latest version for ${o}; skipping upgrade check`);continue}let r=await de`npm ls -g ${o} --depth=0 --json`.quiet().nothrow(),a="";try{a=JSON.parse(r.stdout||"{}").dependencies?.[o]?.version||""}catch{a=""}a?a!==n?(e.logger.info(`${o} ${a} -> ${n}`),t.push(`${o}@${n}`)):e.logger.ok(`${o} up-to-date (${a})`):(e.logger.info(`${o} not installed; will install @${n}`),t.push(`${o}@${n}`))}catch(i){e.logger.warn(`Error checking ${o}: ${i}`);let n=await de`npm ls -g ${o} --depth=0 --json`.quiet().nothrow(),r="";try{r=JSON.parse(n.stdout||"{}").dependencies?.[o]?.version||""}catch{r=""}r||t.push(o)}if(t.length>0){let o=await ee(e.logger);o==="none"?e.logger.warn('Skipping global Node installs because pnpm is detected but not configured. Run "pnpm setup" and re-run the installer.'):o==="pnpm"?(e.logger.info("Installing/updating global packages via pnpm"),await g("pnpm",["add","-g",...t],{dryRun:e.options.dryRun,logger:e.logger})):(e.logger.info("Installing/updating global packages via npm"),await g("npm",["install","-g",...t],{dryRun:e.options.dryRun,logger:e.logger}))}else e.logger.ok("Global packages are up-to-date");await u("codex")?e.logger.ok("Codex CLI installed"):e.logger.err("Codex CLI not found after install")}import{$ as ft}from"zx";import*as fe from"path";import ce from"fs-extra";var ut={brew:["fd","ripgrep","fzf","jq","yq","difftastic","ast-grep"],apt:["ripgrep","fzf","jq","yq","git-delta"],dnf:["ripgrep","fd-find","fzf","jq","yq","git-delta"],pacman:["ripgrep","fd","fzf","jq","yq","git-delta"],zypper:["ripgrep","fd","fzf","jq","yq","git-delta"],none:[]};async function Te(e){if(e.options.installTools==="no"){e.logger.info("Skipping developer tool installs (user choice)");return}let t=await Ee();if(e.logger.info(`Detected package manager: ${t}`),t==="none"){e.logger.warn("Could not detect a supported package manager; please install tools manually");return}let o=ut[t]||[];if(o.length>0)switch(t){case"brew":await g("brew",["update"],{dryRun:e.options.dryRun,logger:e.logger}),await g("brew",["install",...o],{dryRun:e.options.dryRun,logger:e.logger});break;case"apt":await g("sudo",["apt-get","update","-y"],{dryRun:e.options.dryRun,logger:e.logger}),await g("sudo",["apt-get","install","-y",...o],{dryRun:e.options.dryRun,logger:e.logger}).catch(()=>{}),await u("fd")||await g("sudo",["apt-get","install","-y","fd-find"],{dryRun:e.options.dryRun,logger:e.logger}).catch(()=>{});break;case"dnf":await g("sudo",["dnf","install","-y",...o],{dryRun:e.options.dryRun,logger:e.logger}).catch(()=>{});break;case"pacman":await g("sudo",["pacman","-Sy","--noconfirm",...o],{dryRun:e.options.dryRun,logger:e.logger}).catch(()=>{});break;case"zypper":await g("sudo",["zypper","refresh"],{dryRun:e.options.dryRun,logger:e.logger}),await g("sudo",["zypper","install","-y",...o],{dryRun:e.options.dryRun,logger:e.logger}).catch(()=>{});break}if(!await u("difft")&&!await u("difftastic")&&(await u("cargo")?(e.logger.info("Installing difftastic via cargo"),await g("cargo",["install","difftastic"],{dryRun:e.options.dryRun,logger:e.logger})):e.logger.warn("difftastic not found and Rust/cargo missing; falling back to git-delta")),await gt(e,t),await u("fdfind")&&!await u("fd")){let n=fe.join(e.homeDir,".local","bin");await ce.ensureDir(n);let r=(await ft`command -v fdfind`).stdout.trim(),a=fe.join(n,"fd");await ce.pathExists(a)||(e.options.dryRun?e.logger.log(`[dry-run] ln -s ${r} ${a}`):await ce.symlink(r,a),e.logger.ok("fd alias created at ~/.local/bin/fd"))}let i=["fd","fdfind","rg","fzf","jq","yq","difft","difftastic","delta","ast-grep"];for(let n of i)await u(n)&&e.logger.ok(`${n} \u2713`)}async function gt(e,t){if(await u("sg")||await u("ast-grep"))return;let i=await(async()=>{switch(t){case"brew":return await g("brew",["install","ast-grep"],{dryRun:e.options.dryRun,logger:e.logger}),!0;case"apt":return await g("sudo",["apt-get","install","-y","ast-grep"],{dryRun:e.options.dryRun,logger:e.logger}).catch(()=>{}),!0;case"dnf":return await g("sudo",["dnf","install","-y","ast-grep"],{dryRun:e.options.dryRun,logger:e.logger}).catch(()=>{}),!0;case"pacman":return await g("sudo",["pacman","-Sy","--noconfirm","ast-grep"],{dryRun:e.options.dryRun,logger:e.logger}).catch(()=>{}),!0;case"zypper":return await g("sudo",["zypper","install","-y","ast-grep"],{dryRun:e.options.dryRun,logger:e.logger}).catch(()=>{}),!0;default:return!1}})();if(await u("sg")||await u("ast-grep"))return;let n=await ee(e.logger);n==="pnpm"?(e.logger.info("Installing ast-grep via pnpm -g"),await g("pnpm",["add","-g","@ast-grep/cli"],{dryRun:e.options.dryRun,logger:e.logger})):n==="npm"?(e.logger.info("Installing ast-grep via npm -g"),await g("npm",["install","-g","@ast-grep/cli"],{dryRun:e.options.dryRun,logger:e.logger})):i||e.logger.warn("ast-grep not installed (no supported package manager or global npm). Install manually from https://ast-grep.github.io/")}import V from"fs-extra";import*as oe from"path";var mt={balanced:{root:[["approval_policy",'"on-request"'],["sandbox_mode",'"workspace-write"'],["model",'"gpt-5.1-codex"'],["model_reasoning_effort",'"medium"']],features:[["web_search_request","true"]]},safe:{root:[["approval_policy",'"on-failure"'],["sandbox_mode",'"workspace-write"'],["model",'"gpt-5.1-codex"'],["model_reasoning_effort",'"medium"']],features:[["web_search_request","false"]]},minimal:{root:[["model",'"gpt-5.1-codex"'],["model_reasoning_effort",'"medium"']],features:[["web_search_request","false"]]},yolo:{root:[["approval_policy",'"never"'],["sandbox_mode",'"danger-full-access"'],["model",'"gpt-5.1-codex"'],["model_reasoning_effort",'"medium"'],["model_reasoning_summary",'"detailed"'],["model_verbosity",'"high"'],["tool_output_token_limit","25000"]],features:[["web_search_request","true"]]}},ht=`# ~/.codex/config.toml \u2014 managed by codex-1up (patch mode)
4
+ `;async function De(e){let t=oe.join(e.homeDir,".codex","config.toml");await V.ensureDir(oe.dirname(t));let o=await V.pathExists(t),i=o?await V.readFile(t,"utf8"):ht,n=new ge(i),r=!1;if(r=wt(n,e.options.profile,e.options.profileMode)||r,r=yt(n,e.options.profile,e.options.setDefaultProfile)||r,r=bt(n,e.options.notificationSound)||r,!r){e.logger.info("Config already up to date; no changes needed.");return}let a=n.content();if(e.options.dryRun){e.logger.log(`[dry-run] write ${t}`),e.logger.log(a);return}if(o){let s=T(t);await V.copy(t,s),e.logger.info(`Backed up current config to ${s}`)}await V.writeFile(t,a,"utf8"),e.logger.ok("Updated ~/.codex/config.toml with requested settings.")}function wt(e,t,o){if(t==="skip")return!1;let i=mt[t],n=!1;if(o==="overwrite")n=e.replaceTable(`profiles.${t}`,i.root)||n,n=e.replaceTable(`profiles.${t}.features`,i.features)||n;else{e.ensureTable(`profiles.${t}`);for(let[r,a]of i.root)n=e.setKey(`profiles.${t}`,r,a,{mode:"if-missing"})||n;e.ensureTable(`profiles.${t}.features`);for(let[r,a]of i.features)n=e.setKey(`profiles.${t}.features`,r,a,{mode:"if-missing"})||n}return n}function yt(e,t,o){return!o||t==="skip"?!1:e.setRootKey("profile",`"${t}"`,{mode:"force"})}function bt(e,t){if(!t||t==="none")return!1;e.ensureTable("tui");let o=e.getValue("tui","notifications");if(o){let i=o.trim().toLowerCase();if(i.startsWith("true")||i.startsWith("["))return!1}return e.setKey("tui","notifications","true",{mode:"force"})}var ge=class{text;constructor(t){this.text=t||""}content(){return $t(this.text)}ensureTable(t){if(this.hasTable(t))return!1;let o=this.text.length===0?"":xe(this.text);return this.text=o+`[${t}]
5
+ `,!0}setKey(t,o,i,n){let r=te(this.text,t);if(!r)return this.ensureTable(t),this.setKey(t,o,i,n);let a=this.text.slice(r.start,r.end),c=new RegExp(`^\\s*${ue(o)}\\s*=.*$`,"m").exec(a);if(c){if(n.mode==="if-missing")return!1;let k=this.text,N=r.start+c.index,D=N+c[0].length;return this.text=k.slice(0,N)+`${o} = ${i}`+k.slice(D),this.text!==k}let m=this.text,b=r.end,h=m.slice(0,b),v=m.slice(b),p=h.length>0&&!h.endsWith(`
6
+ `),d=v.length>0&&!v.startsWith(`
7
7
  `),y=`${p?`
8
- `:""}${n} = ${i}
9
- ${f?`
10
- `:""}`;return this.text=h+y+v,this.text!==m}getValue(t,n){let i=te(this.text,t);if(!i)return;let o=this.text.slice(i.start,i.end),s=new RegExp(`^\\s*${ue(n)}\\s*=\\s*(.+)$`,"m").exec(o);return s?s[1]:void 0}replaceTable(t,n){let i=n.map(([a,d])=>`${a} = ${d}`).join(`
11
- `),o=`[${t}]
8
+ `:""}${o} = ${i}
9
+ ${d?`
10
+ `:""}`;return this.text=h+y+v,this.text!==m}getValue(t,o){let i=te(this.text,t);if(!i)return;let n=this.text.slice(i.start,i.end),a=new RegExp(`^\\s*${ue(o)}\\s*=\\s*(.+)$`,"m").exec(n);return a?a[1]:void 0}replaceTable(t,o){let i=o.map(([s,c])=>`${s} = ${c}`).join(`
11
+ `),n=`[${t}]
12
12
  ${i}
13
13
 
14
- `,r=this.text,s=te(this.text,t);if(!s){let a=r.length===0?"":De(r);return this.text=a+o,this.text!==r}return this.text=r.slice(0,s.start)+o+r.slice(s.end),this.text!==r}setRootKey(t,n,i){let o=kt(this.text),r=this.text.slice(o.start,o.end),a=new RegExp(`^\\s*${ue(t)}\\s*=.*$`,"m").exec(r);if(a){if(i.mode==="if-missing")return!1;let f=this.text,y=o.start+a.index,k=y+a[0].length;return this.text=f.slice(0,y)+`${t} = ${n}`+f.slice(k),this.text!==f}let d=this.text,m=o.end,b=m>0&&!d.slice(0,m).endsWith(`
15
- `),h=d.slice(m),v=h.length>0&&!h.startsWith(`
14
+ `,r=this.text,a=te(this.text,t);if(!a){let s=r.length===0?"":xe(r);return this.text=s+n,this.text!==r}return this.text=r.slice(0,a.start)+n+r.slice(a.end),this.text!==r}setRootKey(t,o,i){let n=kt(this.text),r=this.text.slice(n.start,n.end),s=new RegExp(`^\\s*${ue(t)}\\s*=.*$`,"m").exec(r);if(s){if(i.mode==="if-missing")return!1;let d=this.text,y=n.start+s.index,k=y+s[0].length;return this.text=d.slice(0,y)+`${t} = ${o}`+d.slice(k),this.text!==d}let c=this.text,m=n.end,b=m>0&&!c.slice(0,m).endsWith(`
15
+ `),h=c.slice(m),v=h.length>0&&!h.startsWith(`
16
16
  `),p=`${b?`
17
- `:""}${t} = ${n}
17
+ `:""}${t} = ${o}
18
18
  ${v?`
19
- `:""}`;return this.text=d.slice(0,m)+p+h,this.text!==d}hasTable(t){return te(this.text,t)!==null}};function te(e,t){let n=/^\s*\[([^\]]+)\]\s*$/gm,i=[],o;for(;o=n.exec(e);)i.push({name:o[1].trim(),index:o.index});for(let r=0;r<i.length;r++)if(i[r].name===t){let s=i[r].index,a=i[r+1]?.index??e.length;return{start:s,end:a}}return null}function kt(e){let n=/^\s*\[([^\]]+)\]\s*$/gm.exec(e);return n?{start:0,end:n.index}:{start:0,end:e.length}}function ue(e){return e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}function $t(e){return e.endsWith(`
19
+ `:""}`;return this.text=c.slice(0,m)+p+h,this.text!==c}hasTable(t){return te(this.text,t)!==null}};function te(e,t){let o=/^\s*\[([^\]]+)\]\s*$/gm,i=[],n;for(;n=o.exec(e);)i.push({name:n[1].trim(),index:n.index});for(let r=0;r<i.length;r++)if(i[r].name===t){let a=i[r].index,s=i[r+1]?.index??e.length;return{start:a,end:s}}return null}function kt(e){let o=/^\s*\[([^\]]+)\]\s*$/gm.exec(e);return o?{start:0,end:o.index}:{start:0,end:e.length}}function ue(e){return e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}function $t(e){return e.endsWith(`
20
20
  `)?e:e+`
21
- `}function De(e){let t=e;return t.endsWith(`
21
+ `}function xe(e){let t=e;return t.endsWith(`
22
22
  `)||(t+=`
23
23
  `),t.endsWith(`
24
24
 
25
25
  `)||(t+=`
26
- `),t}import P from"fs-extra";import*as F from"path";async function Ae(e){let t=F.join(e.homeDir,".codex","notify.sh"),n=F.join(e.rootDir,"templates","notification.sh");await P.ensureDir(F.dirname(t));let i=e.options.notify;if(i==="no"){e.logger.info("Skipping notify hook installation");return}if(!await P.pathExists(n)){e.logger.warn(`Notification template missing at ${n}; skipping notify hook install`);return}if(await P.pathExists(t))if(i==="yes"){let r=T(t);e.options.dryRun?e.logger.log(`[dry-run] cp ${t} ${r}`):await P.copy(t,r),e.options.dryRun?e.logger.log(`[dry-run] cp ${n} ${t}`):(await P.copy(n,t),await P.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 ${n} ${t}`):(await P.copy(n,t),await P.chmod(t,493)),e.logger.ok("Installed notify hook to ~/.codex/notify.sh");let o=F.join(e.homeDir,".codex","config.toml");await P.pathExists(o)?await vt(o,t,e):e.logger.warn(`Config not found at ${o}; run again after config is created`)}async function vt(e,t,n){if(n.options.dryRun){n.logger.log("[dry-run] update config notify and tui.notifications");return}let o=(await P.readFile(e,"utf8")).split(/\r?\n/),r="",s=null,a=null,d=!1,m=!1;for(let p=0;p<o.length;p++){let f=o[p],y=f.match(/^\s*\[([^\]]+)\]\s*$/);if(y){r=y[1],r==="tui"&&(a=p);continue}let k=/^\s*notify\s*=\s*\[/.test(f),N=/^\s*tui\.notifications\s*=/.test(f),x=/^\s*notifications\s*=/.test(f);k&&(r===""?s===null&&(s=p):/^profiles\.[^.]+\.features$/.test(r)&&(o.splice(p,1),p--,d=!0)),N&&/^profiles\.[^.]+\.features$/.test(r)&&(o.splice(p,1),p--,m=!0),x&&r===""&&(o.splice(p,1),p--,m=!0)}function b(p){let f=0;for(;f<o.length&&/^\s*(#.*)?$/.test(o[f]);)f++;o.splice(f,0,p)}if(s!==null){let p=o[s].match(/^(\s*notify\s*=\s*\[)([^\]]*)\]/);if(p){let f=p[2].trim();if(!f.includes(JSON.stringify(t))){let k=f&&!f.endsWith(",")?", ":"";o[s]=`${p[1]}${f}${k}${JSON.stringify(t)}]`,n.logger.ok("Added notify hook to config")}}}else b(`notify = [${JSON.stringify(t)}]`),n.logger.ok("Enabled notify hook in config");let h=!1;if(a!==null){let p=a+1,f=!1;for(;p<o.length;p++){let y=o[p];if(/^\s*\[/.test(y))break;if(/^\s*notifications\s*=/.test(y)){o[p]="notifications = true",f=!0,h=!0;break}}f||(o.splice(a+1,0,"notifications = true"),h=!0)}h||b(`[tui]
27
- notifications = true`);let v=[];r="";for(let p=0;p<o.length;p++){let f=o[p],y=f.match(/^\s*\[([^\]]+)\]\s*$/);if(y){r=y[1],v.push(f);continue}/^\s*tui\.notifications\s*=/.test(f)||/^\s*notifications\s*=/.test(f)&&r!=="tui"||v.push(f)}await P.writeFile(e,v.join(`
28
- `),"utf8")}import S from"fs-extra";import*as w from"path";async function Oe(e){let t=w.join(e.rootDir,"sounds"),n=w.join(e.homeDir,".codex","sounds");await S.ensureDir(n);let i=e.options.notificationSound;if(i==="none"){let h=await _e(e);e.options.dryRun?e.logger.log(`[dry-run] update ${h}`):await je(h,`# Notification sound (disabled)
26
+ `),t}import P from"fs-extra";import*as G from"path";async function Ae(e){let t=G.join(e.homeDir,".codex","notify.sh"),o=G.join(e.rootDir,"templates","notification.sh");await P.ensureDir(G.dirname(t));let i=e.options.notify;if(i==="no"){e.logger.info("Skipping notify hook installation");return}if(!await P.pathExists(o)){e.logger.warn(`Notification template missing at ${o}; skipping notify hook install`);return}if(await P.pathExists(t))if(i==="yes"){let r=T(t);e.options.dryRun?e.logger.log(`[dry-run] cp ${t} ${r}`):await P.copy(t,r),e.options.dryRun?e.logger.log(`[dry-run] cp ${o} ${t}`):(await P.copy(o,t),await P.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 P.copy(o,t),await P.chmod(t,493)),e.logger.ok("Installed notify hook to ~/.codex/notify.sh");let n=G.join(e.homeDir,".codex","config.toml");await P.pathExists(n)?await vt(n,t,e):e.logger.warn(`Config not found at ${n}; run again after config is created`)}async function vt(e,t,o){if(o.options.dryRun){o.logger.log("[dry-run] update config notify and tui.notifications");return}let n=(await P.readFile(e,"utf8")).split(/\r?\n/),r="",a=null,s=null,c=!1,m=!1;for(let p=0;p<n.length;p++){let d=n[p],y=d.match(/^\s*\[([^\]]+)\]\s*$/);if(y){r=y[1],r==="tui"&&(s=p);continue}let k=/^\s*notify\s*=\s*\[/.test(d),N=/^\s*tui\.notifications\s*=/.test(d),D=/^\s*notifications\s*=/.test(d);k&&(r===""?a===null&&(a=p):/^profiles\.[^.]+\.features$/.test(r)&&(n.splice(p,1),p--,c=!0)),N&&/^profiles\.[^.]+\.features$/.test(r)&&(n.splice(p,1),p--,m=!0),D&&r===""&&(n.splice(p,1),p--,m=!0)}function b(p){let d=0;for(;d<n.length&&/^\s*(#.*)?$/.test(n[d]);)d++;n.splice(d,0,p)}if(a!==null){let p=n[a].match(/^(\s*notify\s*=\s*\[)([^\]]*)\]/);if(p){let d=p[2].trim();if(!d.includes(JSON.stringify(t))){let k=d&&!d.endsWith(",")?", ":"";n[a]=`${p[1]}${d}${k}${JSON.stringify(t)}]`,o.logger.ok("Added notify hook to config")}}}else b(`notify = [${JSON.stringify(t)}]`),o.logger.ok("Enabled notify hook in config");let h=!1;if(s!==null){let p=s+1,d=!1;for(;p<n.length;p++){let y=n[p];if(/^\s*\[/.test(y))break;if(/^\s*notifications\s*=/.test(y)){n[p]="notifications = true",d=!0,h=!0;break}}d||(n.splice(s+1,0,"notifications = true"),h=!0)}h||b(`[tui]
27
+ notifications = true`);let v=[];r="";for(let p=0;p<n.length;p++){let d=n[p],y=d.match(/^\s*\[([^\]]+)\]\s*$/);if(y){r=y[1],v.push(d);continue}/^\s*tui\.notifications\s*=/.test(d)||/^\s*notifications\s*=/.test(d)&&r!=="tui"||v.push(d)}await P.writeFile(e,v.join(`
28
+ `),"utf8")}import S from"fs-extra";import*as w from"path";async function Oe(e){let t=w.join(e.rootDir,"sounds"),o=w.join(e.homeDir,".codex","sounds");await S.ensureDir(o);let i=e.options.notificationSound;if(i==="none"){let h=await _e(e);e.options.dryRun?e.logger.log(`[dry-run] update ${h}`):await je(h,`# Notification sound (disabled)
29
29
  export CODEX_DISABLE_SOUND=1
30
30
  export CODEX_CUSTOM_SOUND=""
31
- `,e);let p=w.join(e.homeDir,".codex","notify.sh");if(await S.pathExists(p)){let f=await S.readFile(p,"utf8"),y=f.replace(/^DEFAULT_CODEX_SOUND=.*$/m,'DEFAULT_CODEX_SOUND=""');e.options.dryRun?e.logger.log(`[dry-run] patch ${p} DEFAULT_CODEX_SOUND -> empty`):y!==f&&await S.writeFile(p,y,"utf8")}e.logger.ok("Notification sound disabled");return}let o;if(i&&!w.isAbsolute(i)?o=w.join(t,i):i?o=i:e.options.mode==="recommended"&&(o=w.join(t,"noti_1.wav")),!o||!await S.pathExists(o)){e.logger.warn("No notification sound selected or file missing; skipping sound setup");return}let r=w.isAbsolute(o),s=o.startsWith(w.join(e.rootDir,"sounds")),a=!r||s?w.join(n,w.basename(o)):o;(!r||s)&&(e.options.dryRun?e.logger.log(`[dry-run] cp ${o} ${a}`):await S.copy(o,a));let d=await _e(e),m=`# Notification sound
31
+ `,e);let p=w.join(e.homeDir,".codex","notify.sh");if(await S.pathExists(p)){let d=await S.readFile(p,"utf8"),y=d.replace(/^DEFAULT_CODEX_SOUND=.*$/m,'DEFAULT_CODEX_SOUND=""');e.options.dryRun?e.logger.log(`[dry-run] patch ${p} DEFAULT_CODEX_SOUND -> empty`):y!==d&&await S.writeFile(p,y,"utf8")}e.logger.ok("Notification sound disabled");return}let n;if(i&&!w.isAbsolute(i)?n=w.join(t,i):i?n=i:e.options.mode==="recommended"&&(n=w.join(t,"noti_1.wav")),!n||!await S.pathExists(n)){e.logger.warn("No notification sound selected or file missing; skipping sound setup");return}let r=w.isAbsolute(n),a=n.startsWith(w.join(e.rootDir,"sounds")),s=!r||a?w.join(o,w.basename(n)):n;(!r||a)&&(e.options.dryRun?e.logger.log(`[dry-run] cp ${n} ${s}`):await S.copy(n,s));let c=await _e(e),m=`# Notification sound
32
32
  export CODEX_DISABLE_SOUND=0
33
- export CODEX_CUSTOM_SOUND="${a}"
34
- `;e.options.dryRun?e.logger.log(`[dry-run] update ${d}`):await je(d,m,e),e.logger.ok("Notification sound configured. Open a new shell or source your rc to apply.");let b=w.join(e.homeDir,".codex","notify.sh");if(await S.pathExists(b)){let h=await S.readFile(b,"utf8"),v=`DEFAULT_CODEX_SOUND="${a}"`,p=h.replace(/^DEFAULT_CODEX_SOUND=.*$/m,v);p!==h&&(e.options.dryRun?e.logger.log(`[dry-run] patch ${b} DEFAULT_CODEX_SOUND -> ${a}`):await S.writeFile(b,p,"utf8"))}}async function _e(e){let t=e.options.shell||process.env.SHELL||"",n="auto";switch(n==="auto"&&(t.includes("zsh")?n="zsh":t.includes("fish")?n="fish":n="bash"),n){case"zsh":return w.join(e.homeDir,".zshrc");case"fish":return w.join(e.homeDir,".config","fish","config.fish");default:return w.join(e.homeDir,".bashrc")}}async function je(e,t,n){let i="codex-1up";await S.ensureDir(w.dirname(e));let o="";if(await S.pathExists(e)){o=await S.readFile(e,"utf8");let s=`>>> ${i} >>>`,a=`<<< ${i} <<<`,d=new RegExp(`${s}[\\s\\S]*?${a}\\n?`,"g");o=o.replace(d,"")}let r=`>>> ${i} >>>
33
+ export CODEX_CUSTOM_SOUND="${s}"
34
+ `;e.options.dryRun?e.logger.log(`[dry-run] update ${c}`):await je(c,m,e),e.logger.ok("Notification sound configured. Open a new shell or source your rc to apply.");let b=w.join(e.homeDir,".codex","notify.sh");if(await S.pathExists(b)){let h=await S.readFile(b,"utf8"),v=`DEFAULT_CODEX_SOUND="${s}"`,p=h.replace(/^DEFAULT_CODEX_SOUND=.*$/m,v);p!==h&&(e.options.dryRun?e.logger.log(`[dry-run] patch ${b} DEFAULT_CODEX_SOUND -> ${s}`):await S.writeFile(b,p,"utf8"))}}async function _e(e){let t=e.options.shell||process.env.SHELL||"",o="auto";switch(o==="auto"&&(t.includes("zsh")?o="zsh":t.includes("fish")?o="fish":o="bash"),o){case"zsh":return w.join(e.homeDir,".zshrc");case"fish":return w.join(e.homeDir,".config","fish","config.fish");default:return w.join(e.homeDir,".bashrc")}}async function je(e,t,o){let i="codex-1up";await S.ensureDir(w.dirname(e));let n="";if(await S.pathExists(e)){n=await S.readFile(e,"utf8");let a=`>>> ${i} >>>`,s=`<<< ${i} <<<`,c=new RegExp(`${a}[\\s\\S]*?${s}\\n?`,"g");n=n.replace(c,"")}let r=`>>> ${i} >>>
35
35
  ${t}<<< ${i} <<<
36
- `;await S.writeFile(e,o+r,"utf8")}import R from"fs-extra";import*as j from"path";async function Le(e){let t=j.join(e.homeDir,".codex","AGENTS.md"),n=e.options.globalAgents;if(n==="skip"){e.logger.info("Skipping global AGENTS.md creation");return}let i=j.join(e.rootDir,"templates","agent-templates","AGENTS-default.md");if(!await R.pathExists(i)){e.logger.warn(`Template not found at ${i}`);return}switch(n){case"create-default":if(await R.pathExists(t)){e.logger.info("Global AGENTS.md already exists; leaving unchanged");return}await R.ensureDir(j.dirname(t)),e.options.dryRun?e.logger.log(`[dry-run] cp ${i} ${t}`):await R.copy(i,t),e.logger.ok(`Wrote ${t}`);break;case"overwrite-default":if(await R.ensureDir(j.dirname(t)),await R.pathExists(t)){let r=T(t);e.options.dryRun?e.logger.log(`[dry-run] cp ${t} ${r}`):await R.copy(t,r),e.logger.info(`Backed up existing AGENTS.md to: ${r}`)}e.options.dryRun?e.logger.log(`[dry-run] cp ${i} ${t}`):await R.copy(i,t),e.logger.ok(`Wrote ${t}`);break;case"append-default":if(await R.ensureDir(j.dirname(t)),await R.pathExists(t)){let r=T(t);e.options.dryRun?e.logger.log(`[dry-run] cp ${t} ${r}`):await R.copy(t,r),e.logger.info(`Backed up existing AGENTS.md to: ${r}`)}let o=await R.readFile(i,"utf8");e.options.dryRun?e.logger.log(`[dry-run] append template to ${t}`):await R.appendFile(t,`
36
+ `;await S.writeFile(e,n+r,"utf8")}import R from"fs-extra";import*as j from"path";async function Le(e){let t=j.join(e.homeDir,".codex","AGENTS.md"),o=e.options.globalAgents;if(o==="skip"){e.logger.info("Skipping global AGENTS.md creation");return}let i=j.join(e.rootDir,"templates","agent-templates","AGENTS-default.md");if(!await R.pathExists(i)){e.logger.warn(`Template not found at ${i}`);return}switch(o){case"create-default":if(await R.pathExists(t)){e.logger.info("Global AGENTS.md already exists; leaving unchanged");return}await R.ensureDir(j.dirname(t)),e.options.dryRun?e.logger.log(`[dry-run] cp ${i} ${t}`):await R.copy(i,t),e.logger.ok(`Wrote ${t}`);break;case"overwrite-default":if(await R.ensureDir(j.dirname(t)),await R.pathExists(t)){let r=T(t);e.options.dryRun?e.logger.log(`[dry-run] cp ${t} ${r}`):await R.copy(t,r),e.logger.info(`Backed up existing AGENTS.md to: ${r}`)}e.options.dryRun?e.logger.log(`[dry-run] cp ${i} ${t}`):await R.copy(i,t),e.logger.ok(`Wrote ${t}`);break;case"append-default":if(await R.ensureDir(j.dirname(t)),await R.pathExists(t)){let r=T(t);e.options.dryRun?e.logger.log(`[dry-run] cp ${t} ${r}`):await R.copy(t,r),e.logger.info(`Backed up existing AGENTS.md to: ${r}`)}let n=await R.readFile(i,"utf8");e.options.dryRun?e.logger.log(`[dry-run] append template to ${t}`):await R.appendFile(t,`
37
37
  ---
38
38
 
39
- ${o}`,"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 Fe(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 c("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 g("code",["--install-extension",t,"--force"],{dryRun:!1,logger:e.logger}),e.logger.ok(`VS Code extension '${t}' installed (or already present)`)}import B from"fs-extra";import*as H from"path";async function Ge(e){let t=e.options.agentsMd;if(!t)return;let n=t;(await B.stat(n).catch(()=>null))?.isDirectory()&&(n=H.join(n,"AGENTS.md"));let i=H.join(e.rootDir,"templates","agent-templates","AGENTS-default.md");if(await B.pathExists(n)){e.logger.warn(`${n} already exists`);let o=T(n);e.options.dryRun?e.logger.log(`[dry-run] cp ${n} ${o}`):await B.copy(n,o),e.logger.info(`Backed up existing AGENTS.md to: ${o}`)}e.logger.info(`Writing starter AGENTS.md to: ${n}`),e.options.dryRun?e.logger.log(`[dry-run] write AGENTS.md to ${n}`):(await B.ensureDir(H.dirname(n)),await B.copy(i,n),e.logger.ok("Wrote AGENTS.md"))}var Me="codex-1up";async function he(e,t){let n=qe.homedir(),i=me.join(n,`.${Me}`);await Ct.ensureDir(i);let o=new Date().toISOString().replace(/[:.]/g,"-").slice(0,-5),r=me.join(i,`install-${o}.log`),s=Re(r);s.info(`==> ${Me} installer`),s.info(`Log: ${r}`);let a={cwd:process.cwd(),homeDir:n,rootDir:t,logDir:i,logFile:r,options:e,logger:s};try{await Ie(a),await Ne(a),await Te(a);let m=await c("codex")||a.options.installCodexCli==="yes";m||s.warn("Codex CLI not found and codex install was skipped; skipping config/notify setup until codex is installed."),m&&(await xe(a),await Ae(a),await Oe(a),await Le(a)),await Fe(a),await Ge(a),s.ok("All done. Open a new shell or 'source' your rc file to load aliases."),s.info("Next steps:"),s.info(" 1) codex # sign in; then ask it to plan a refactor"),s.info(" 2) ./bin/codex-1up agents --path $PWD # write a starter AGENTS.md to your repo"),s.info(" 3) Review ~/.codex/config.toml (see: https://github.com/openai/codex/blob/main/docs/config.md)")}catch(d){throw s.err(`Installation failed: ${d}`),d}}var We=Et(Rt(import.meta.url));function It(){let e=We;for(let t=0;t<6;t++){try{return Pt(D(e,"templates","codex-config.toml")),e}catch{}e=D(e,"..")}return D(We,"..")}var oe=It(),ze=St({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"},"git-external-diff":{type:"boolean",description:"Set difftastic as git external diff"},"install-node":{type:"string",description:"nvm|brew|skip"},tools:{type:"string",description:"yes|no install/upgrade core CLI tools (rg, fd, fzf, jq, yq, difftastic)"},"codex-cli":{type:"string",description:"yes|no install/upgrade Codex CLI + ast-grep globally"},profile:{type:"string",description:"balanced|safe|minimal|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}},async run({args:e}){let t=D(J.homedir(),".codex","config.toml"),n=await we(t),i=D(J.homedir(),".codex","notify.sh"),o=await we(i),r=D(J.homedir(),".codex","AGENTS.md"),s=await we(r),a=n?await jt(t):void 0,d=process.stdout.isTTY&&!e["dry-run"]&&!e["skip-confirmation"]&&!e.yes,m=Tt(e.profile),b=Dt(e["profile-mode"]),h=xt(e.tools),v=At(e["codex-cli"]),p=process.platform==="darwin"||process.platform==="linux",f=typeof e.sound>"u"?void 0:String(e.sound).trim();if(f==="")throw new Error('Invalid --sound value (expected path, "none", or "skip")');let k=m||(be(a)?a:void 0)||"balanced",N=b||"add",x=!0,ae=h||(p?"yes":"no"),Ce=v||"yes",A,q,_;if(f&&(u=>{let I=u.trim().toLowerCase();if(I==="skip"){A="no",_=void 0;return}A="yes",_=I==="none"?"none":u})(f),d){if(l.intro("codex-1up \xB7 Install"),!v){let u=await l.confirm({message:"Install/update Codex CLI globally?",initialValue:!0});if(l.isCancel(u))return l.cancel("Install aborted");Ce=u?"yes":"no"}if(p&&!h){l.note("We can install/update developer tools (rg, fd, fzf, jq, yq, difftastic, ast-grep) using your package manager (macOS/Linux).");let u=await l.confirm({message:"Install/update these CLI tools?",initialValue:!0});if(l.isCancel(u))return l.cancel("Install aborted");ae=u?"yes":"no"}else!p&&!h&&(ae="no");if(!m){l.note(["Profiles:"," \u2022 Balanced: on-request approvals, workspace-write sandbox, web search on."," \u2022 Safe: on-failure approvals, workspace-write, web search off."," \u2022 Minimal: lean settings, minimal reasoning effort, web search off."," \u2022 YOLO: never approvals, danger-full-access, web search on, verbose."].join(`
40
- `));let u=await l.select({message:"Choose a Codex profile to install",options:[{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 workspace-write \xB7 web search off"},{label:"Minimal",value:"minimal",hint:"lean defaults \xB7 minimal reasoning effort \xB7 web search off"},{label:"YOLO",value:"yolo",hint:"never approvals \xB7 danger-full-access \xB7 web search on"},{label:"Skip (no profile changes)",value:"skip"}],initialValue:_t(a)});if(l.isCancel(u))return l.cancel("Install aborted");k=u}if(k!=="skip"&&!b){let u=await l.select({message:`How should we write profiles.${k}?`,options:[{label:"Add / merge (preserve custom keys)",value:"add"},{label:"Overwrite codex profile (replace table)",value:"overwrite"}],initialValue:N});if(l.isCancel(u))return l.cancel("Install aborted");N=u}if(k==="skip")x=!1;else{let u=await l.confirm({message:`Wrote profiles.${k} to ~/.codex/config.toml (mode: ${N}). Set this as the default profile?`,initialValue:!0});if(l.isCancel(u))return l.cancel("Install aborted");x=!!u}if(!f){let le=function(E){return[{label:"Skip (leave current setup)",value:"skip"},{label:"None (disable sounds)",value:"none"},...I.map($=>({label:$,value:$})),{label:"Custom path\u2026",value:"custom"}]};var yn=le;let u=D(oe,"sounds"),I=[];try{I=(await X.readdir(u)).filter(E=>/\.(wav|mp3|ogg)$/i.test(E)).sort()}catch{}A="yes";let C=I.includes("noti_1.wav")?"noti_1.wav":I[0]||"none";async function pe(E){let $=await l.text({message:"Enter absolute path to a .wav file",placeholder:E||"/absolute/path/to/sound.wav",validate(O){if(!O)return"Path required";if(!O.startsWith("/"))return"Use an absolute path";if(!/(\.wav|\.mp3|\.ogg)$/i.test(O))return"Supported: .wav, .mp3, .ogg"}});if(l.isCancel($))return null;try{await X.access(String($))}catch{return l.log.warn("File not found. Try again."),await pe(String($))}return String($)}let W=await l.select({message:"Notification sound",options:le(C),initialValue:C});if(l.isCancel(W))return l.cancel("Install aborted");if(W==="skip")A="no",_=void 0;else if(W==="custom"){let E=await pe();if(E===null)return l.cancel("Install aborted");C=E}else C=W;if(W!=="skip"){for(;;){let E=await l.select({message:`Selected: ${C}. 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(l.isCancel(E))return l.cancel("Install aborted");if(E==="use")break;if(E==="change"){let $=await l.select({message:"Notification sound",options:le(C),initialValue:C});if(l.isCancel($))return l.cancel("Install aborted");if($==="custom"){let O=await pe();if(O===null)return l.cancel("Install aborted");C=O}else if($==="skip"){A="no",_=void 0;break}else C=$;continue}try{let $=C==="none"?"none":C.startsWith("/")?C:D(oe,"sounds",C);await Nt($)}catch($){l.log.warn(String($))}}_===void 0&&(_=C)}}if(s){let u=await l.select({message:"Global ~/.codex/AGENTS.md",options:[{label:"Add to your existing AGENTS.md (Backup will be created)",value:"append-default"},{label:"Overwrite existing (Backup will be created)",value:"overwrite-default"},{label:"Skip \u2014 leave as-is",value:"skip"}],initialValue:"append-default"});if(l.isCancel(u))return l.cancel("Install aborted");q=u}else q="skip"}d||(k==="skip"&&(x=!1),typeof A>"u"&&(A=o?"no":"yes"),typeof q>"u"&&(q="skip"));let Se={profile:k,profileMode:N,setDefaultProfile:x,installCodexCli:Ce,installTools:ae,notify:A??(o?"no":"yes"),globalAgents:q??"skip",notificationSound:_,mode:"manual",installNode:e["install-node"]||"nvm",shell:String(e.shell||"auto"),vscodeId:e.vscode?String(e.vscode):void 0,noVscode: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(d){let u=l.spinner();u.start("Installing prerequisites and writing config");try{await he(Se,oe),u.stop("Base install complete"),l.outro("Install finished")}catch(I){throw u.stop("Installation failed"),l.cancel(`Installation failed: ${I}`),I}await Ue();return}try{await he(Se,oe),await Ue()}catch(u){throw l.cancel(`Installation failed: ${u}`),u}}});async function Ue(){let e=J.homedir(),t=D(e,".codex","config.toml"),n,i=[];try{let d=await X.readFile(t,"utf8"),m=ye.parse(d);n=m.profile;let b=m.profiles||{};i=Object.keys(b)}catch{}let o=["codex","ast-grep","fd","rg","fzf","jq","yq","difft","difftastic"],s=(await Promise.all(o.map(async d=>{try{return await G(d),[d,!0]}catch{return[d,!1]}}))).filter(([,d])=>d).map(([d])=>d),a=[];a.push(""),a.push("codex-1up: Installation summary"),a.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"),a.push(`Config: ${t}${n?` (active profile: ${n})`:""}`),i.length&&a.push(`Profiles: ${i.join(", ")}`),a.push(`Tools detected: ${s.join(", ")||"none"}`),a.push(""),a.push("Usage:"),a.push(" - Switch profile for a session: codex --profile <name>"),a.push(" - List available profiles: codex-1up config profiles"),a.push(" - Persist active profile: codex-1up config set-profile <name>"),a.push(" - Write AGENTS.md to a repo: codex-1up agents --path . --template default"),a.push(""),process.stdout.write(a.join(`
39
+ ${n}`,"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 Ge(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 u("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 g("code",["--install-extension",t,"--force"],{dryRun:!1,logger:e.logger}),e.logger.ok(`VS Code extension '${t}' installed (or already present)`)}import B from"fs-extra";import*as H from"path";async function Fe(e){let t=e.options.agentsMd;if(!t)return;let o=t;(await B.stat(o).catch(()=>null))?.isDirectory()&&(o=H.join(o,"AGENTS.md"));let i=H.join(e.rootDir,"templates","agent-templates","AGENTS-default.md");if(await B.pathExists(o)){e.logger.warn(`${o} already exists`);let n=T(o);e.options.dryRun?e.logger.log(`[dry-run] cp ${o} ${n}`):await B.copy(o,n),e.logger.info(`Backed up existing AGENTS.md to: ${n}`)}e.logger.info(`Writing starter AGENTS.md to: ${o}`),e.options.dryRun?e.logger.log(`[dry-run] write AGENTS.md to ${o}`):(await B.ensureDir(H.dirname(o)),await B.copy(i,o),e.logger.ok("Wrote AGENTS.md"))}var qe="codex-1up";async function he(e,t){let o=Me.homedir(),i=me.join(o,`.${qe}`);await Ct.ensureDir(i);let n=new Date().toISOString().replace(/[:.]/g,"-").slice(0,-5),r=me.join(i,`install-${n}.log`),a=Re(r);a.info(`==> ${qe} installer`),a.info(`Log: ${r}`);let s={cwd:process.cwd(),homeDir:o,rootDir:t,logDir:i,logFile:r,options:e,logger:a};try{await Ie(s),await Ne(s),await Te(s);let m=await u("codex")||s.options.installCodexCli==="yes";m||a.warn("Codex CLI not found and codex install was skipped; skipping config/notify setup until codex is installed."),m&&(await De(s),await Ae(s),await Oe(s),await Le(s)),await Ge(s),await Fe(s),a.ok("All done. Open a new shell or 'source' your rc file to load aliases."),a.info("Next steps:"),a.info(" 1) codex # sign in; then ask it to plan a refactor"),a.info(" 2) ./bin/codex-1up agents --path $PWD # write a starter AGENTS.md to your repo"),a.info(" 3) Review ~/.codex/config.toml (see: https://github.com/openai/codex/blob/main/docs/config.md)")}catch(c){throw a.err(`Installation failed: ${c}`),c}}var We=Et(Rt(import.meta.url));function It(){let e=We;for(let t=0;t<6;t++){try{return Pt(x(e,"templates","codex-config.toml")),e}catch{}e=x(e,"..")}return x(We,"..")}var ne=It(),ze=St({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"},"git-external-diff":{type:"boolean",description:"Set difftastic as git external diff"},"install-node":{type:"string",description:"nvm|brew|skip"},tools:{type:"string",description:"yes|no install/upgrade core CLI tools (rg, fd, fzf, jq, yq, difftastic)"},"codex-cli":{type:"string",description:"yes|no install/upgrade Codex CLI + ast-grep globally"},profile:{type:"string",description:"balanced|safe|minimal|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}},async run({args:e}){let t=x(J.homedir(),".codex","config.toml"),o=await we(t),i=x(J.homedir(),".codex","notify.sh"),n=await we(i),r=x(J.homedir(),".codex","AGENTS.md"),a=await we(r),s=o?await jt(t):void 0,c=process.stdout.isTTY&&!e["dry-run"]&&!e["skip-confirmation"]&&!e.yes,m=Tt(e.profile),b=xt(e["profile-mode"]),h=Dt(e.tools),v=At(e["codex-cli"]),p=process.platform==="darwin"||process.platform==="linux",d=typeof e.sound>"u"?void 0:String(e.sound).trim();if(d==="")throw new Error('Invalid --sound value (expected path, "none", or "skip")');let k=m||(be(s)?s:void 0)||"balanced",N=b||"add",D=!0,se=h||(p?"yes":"no"),Ce=v||"yes",A,M,_;if(d&&(f=>{let I=f.trim().toLowerCase();if(I==="skip"){A="no",_=void 0;return}A="yes",_=I==="none"?"none":f})(d),c){if(l.intro("codex-1up \xB7 Install"),!v){let f=await l.confirm({message:"Install/update Codex CLI globally?",initialValue:!0});if(l.isCancel(f))return l.cancel("Install aborted");Ce=f?"yes":"no"}if(p&&!h){l.note("We can install/update developer tools (rg, fd, fzf, jq, yq, difftastic, ast-grep) using your package manager (macOS/Linux).");let f=await l.confirm({message:"Install/update these CLI tools?",initialValue:!0});if(l.isCancel(f))return l.cancel("Install aborted");se=f?"yes":"no"}else!p&&!h&&(se="no");if(!m){l.note(["Profiles:"," \u2022 Balanced: on-request approvals, workspace-write sandbox, web search on."," \u2022 Safe: on-failure approvals, workspace-write, web search off."," \u2022 Minimal: lean settings, minimal reasoning effort, web search off."," \u2022 YOLO: never approvals, danger-full-access, web search on, verbose."].join(`
40
+ `));let f=await l.select({message:"Choose a Codex profile to install",options:[{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 workspace-write \xB7 web search off"},{label:"Minimal",value:"minimal",hint:"lean defaults \xB7 minimal reasoning effort \xB7 web search off"},{label:"YOLO",value:"yolo",hint:"never approvals \xB7 danger-full-access \xB7 web search on"},{label:"Skip (no profile changes)",value:"skip"}],initialValue:_t(s)});if(l.isCancel(f))return l.cancel("Install aborted");k=f}if(k!=="skip"&&!b){let f=await l.select({message:`How should we write profiles.${k}?`,options:[{label:"Add / merge (preserve custom keys)",value:"add"},{label:"Overwrite codex profile (replace table)",value:"overwrite"}],initialValue:N});if(l.isCancel(f))return l.cancel("Install aborted");N=f}if(k==="skip")D=!1;else{let f=await l.confirm({message:`Wrote profiles.${k} to ~/.codex/config.toml (mode: ${N}). Set this as the default profile?`,initialValue:!0});if(l.isCancel(f))return l.cancel("Install aborted");D=!!f}if(!d){let le=function(E){return[{label:"Skip (leave current setup)",value:"skip"},{label:"None (disable sounds)",value:"none"},...I.map($=>({label:$,value:$})),{label:"Custom path\u2026",value:"custom"}]};var yo=le;let f=x(ne,"sounds"),I=[];try{I=(await X.readdir(f)).filter(E=>/\.(wav|mp3|ogg)$/i.test(E)).sort()}catch{}A="yes";let C=I.includes("noti_1.wav")?"noti_1.wav":I[0]||"none";async function pe(E){let $=await l.text({message:"Enter absolute path to a .wav file",placeholder:E||"/absolute/path/to/sound.wav",validate(O){if(!O)return"Path required";if(!O.startsWith("/"))return"Use an absolute path";if(!/(\.wav|\.mp3|\.ogg)$/i.test(O))return"Supported: .wav, .mp3, .ogg"}});if(l.isCancel($))return null;try{await X.access(String($))}catch{return l.log.warn("File not found. Try again."),await pe(String($))}return String($)}let W=await l.select({message:"Notification sound",options:le(C),initialValue:C});if(l.isCancel(W))return l.cancel("Install aborted");if(W==="skip")A="no",_=void 0;else if(W==="custom"){let E=await pe();if(E===null)return l.cancel("Install aborted");C=E}else C=W;if(W!=="skip"){for(;;){let E=await l.select({message:`Selected: ${C}. 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(l.isCancel(E))return l.cancel("Install aborted");if(E==="use")break;if(E==="change"){let $=await l.select({message:"Notification sound",options:le(C),initialValue:C});if(l.isCancel($))return l.cancel("Install aborted");if($==="custom"){let O=await pe();if(O===null)return l.cancel("Install aborted");C=O}else if($==="skip"){A="no",_=void 0;break}else C=$;continue}try{let $=C==="none"?"none":C.startsWith("/")?C:x(ne,"sounds",C);await Nt($)}catch($){l.log.warn(String($))}}_===void 0&&(_=C)}}if(a){l.note(`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).
41
+
42
+ - Backups will be created
43
+ - If you think codex works worse with this instructions, you can remove them from ~/.codex/AGENTS.md anytime.
44
+ `);let f=await l.select({message:"Global ~/.codex/AGENTS.md (optional)",options:[{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:"Skip \u2014 leave as-is (you can run codex-1up agents later)",value:"skip"}],initialValue:"append-default"});if(l.isCancel(f))return l.cancel("Install aborted");M=f}else{l.note(`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).
45
+
46
+ - Backups will be created
47
+ - If you think codex works worse with this instructions, you can remove them from ~/.codex/AGENTS.md anytime.
48
+ `);let f=await l.select({message:"Global ~/.codex/AGENTS.md (optional)",options:[{label:"Create starter AGENTS.md (recommended; helps give Codex repo context everywhere)",value:"create-default"},{label:"Skip for now (you can add later with codex-1up agents --global)",value:"skip"}],initialValue:"create-default"});if(l.isCancel(f))return l.cancel("Install aborted");M=f}}c||(k==="skip"&&(D=!1),typeof A>"u"&&(A=n?"no":"yes"),typeof M>"u"&&(M="skip"));let Se={profile:k,profileMode:N,setDefaultProfile:D,installCodexCli:Ce,installTools:se,notify:A??(n?"no":"yes"),globalAgents:M??"skip",notificationSound:_,mode:"manual",installNode:e["install-node"]||"nvm",shell:String(e.shell||"auto"),vscodeId:e.vscode?String(e.vscode):void 0,noVscode: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(c){let f=l.spinner();f.start("Installing prerequisites and writing config");try{await he(Se,ne),f.stop("Base install complete"),l.outro("Install finished")}catch(I){throw f.stop("Installation failed"),l.cancel(`Installation failed: ${I}`),I}await Ue();return}try{await he(Se,ne),await Ue()}catch(f){throw l.cancel(`Installation failed: ${f}`),f}}});async function Ue(){let e=J.homedir(),t=x(e,".codex","config.toml"),o,i=[];try{let c=await X.readFile(t,"utf8"),m=ye.parse(c);o=m.profile;let b=m.profiles||{};i=Object.keys(b)}catch{}let n=["codex","ast-grep","fd","rg","fzf","jq","yq","difft","difftastic"],a=(await Promise.all(n.map(async c=>{try{return await F(c),[c,!0]}catch{return[c,!1]}}))).filter(([,c])=>c).map(([c])=>c),s=[];s.push(""),s.push("codex-1up: Installation summary"),s.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"),s.push(`Config: ${t}${o?` (active profile: ${o})`:""}`),i.length&&s.push(`Profiles: ${i.join(", ")}`),s.push(`Tools detected: ${a.join(", ")||"none"}`),s.push(""),s.push("Usage:"),s.push(" - Switch profile for a session: codex --profile <name>"),s.push(" - List available profiles: codex-1up config profiles"),s.push(" - Persist active profile: codex-1up config set-profile <name>"),s.push(" - Write AGENTS.md to a repo: codex-1up agents --path . --template default"),s.push(""),process.stdout.write(s.join(`
41
49
  `)+`
42
- `)}async function Nt(e){if(e.endsWith("/none")||e==="none")return;let t=[async n=>{await G("afplay"),await K`afplay ${n}`},async n=>{await G("paplay"),await K`paplay ${n}`},async n=>{await G("aplay"),await K`aplay ${n}`},async n=>{await G("mpg123"),await K`mpg123 -q ${n}`},async n=>{await G("ffplay"),await K`ffplay -nodisp -autoexit -loglevel quiet ${n}`}];for(let n of t)try{await n(e);return}catch{}throw new Error("No audio player found (afplay/paplay/aplay/mpg123/ffplay)")}async function we(e){try{return await X.access(e),!0}catch{return!1}}function Tt(e){if(e==null)return;let t=String(e).toLowerCase();if(be(t))return t;if(t==="skip")return"skip";throw new Error("Invalid --profile value (use balanced|safe|minimal|yolo|skip).")}function Dt(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 xt(e){if(e==null)return;let t=String(e).toLowerCase();if(t==="yes"||t==="no")return t;throw new Error("Invalid --tools value (use yes|no).")}function At(e){if(e==null)return;let t=String(e).toLowerCase();if(t==="yes"||t==="no")return t;throw new Error("Expected yes|no")}function be(e){return e==="balanced"||e==="safe"||e==="minimal"||e==="yolo"}function _t(e){return be(e)?e:"balanced"}async function jt(e){try{let t=await X.readFile(e,"utf8"),i=ye.parse(t).profile;return typeof i=="string"?i:void 0}catch{return}}import{defineCommand as Ot}from"citty";import{promises as Y}from"fs";import{accessSync as Lt}from"fs";import{resolve as Q,dirname as Be}from"path";import{fileURLToPath as Ft}from"url";var Ve=Be(Ft(import.meta.url));function Gt(){let e=Ve;for(let t=0;t<6;t++){try{return Lt(Q(e,"templates","codex-config.toml")),e}catch{}e=Q(e,"..")}return Q(Ve,"..")}var Mt=Gt();async function ke(e){try{return await Y.access(e),!0}catch{return!1}}async function qt(e,t){if(await ke(t)){let i=`${t}.backup.${new Date().toISOString().replace(/[:.]/g,"").replace("T","_").slice(0,15)}`;await Y.copyFile(t,i)}await Y.mkdir(Be(t),{recursive:!0}),await Y.copyFile(e,t)}var He=Ot({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),n=Q(Mt,"templates/agent-templates","AGENTS-default.md"),o=await ke(t).then(async r=>r&&(await Y.stat(t)).isDirectory()).catch(()=>!1)?Q(t,"AGENTS.md"):t;if(!await ke(n))throw new Error(`Template not found: ${n}`);await qt(n,o),process.stdout.write(`Wrote ${o}
43
- `)}});import{defineCommand as Wt}from"citty";import{$ as Ut}from"zx";import{fileURLToPath as zt}from"url";import{accessSync as Vt}from"fs";import{dirname as Bt,resolve as ie}from"path";var Ke=Bt(zt(import.meta.url));function Ht(){let e=Ke;for(let t=0;t<6;t++){try{return Vt(ie(e,"templates","codex-config.toml")),e}catch{}e=ie(e,"..")}return ie(Ke,"..")}var Kt=Ht(),Je=Wt({meta:{name:"doctor",description:"Run environment checks"},async run(){await Ut`bash ${ie(Kt,"scripts/doctor.sh")}`}});import{defineCommand as Jt}from"citty";import{$ as Xt}from"zx";import{fileURLToPath as Yt}from"url";import{accessSync as Qt}from"fs";import{dirname as Zt,resolve as re}from"path";var Xe=Zt(Yt(import.meta.url));function en(){let e=Xe;for(let t=0;t<6;t++){try{return Qt(re(e,"templates","codex-config.toml")),e}catch{}e=re(e,"..")}return re(Xe,"..")}var tn=en(),Ye=Jt({meta:{name:"uninstall",description:"Clean up aliases and config created by this tool"},async run(){await Xt`bash ${re(tn,"scripts/uninstall.sh")}`}});import{defineCommand as se}from"citty";import{promises as Z}from"fs";import{resolve as M,dirname as tt}from"path";import{fileURLToPath as nn}from"url";import{accessSync as on}from"fs";import rn from"os";var Qe=tt(nn(import.meta.url));function sn(){let e=Qe;for(let t=0;t<6;t++){try{return on(M(e,"templates","codex-config.toml")),e}catch{}e=M(e,"..")}return M(Qe,"..")}var an=sn();function $e(){let e=M(rn.homedir(),".codex"),t=M(e,"config.toml");return{CODEX_HOME:e,CFG:t}}async function ve(e){return Z.readFile(e,"utf8")}async function Ze(e,t){await Z.mkdir(tt(e),{recursive:!0}),await Z.writeFile(e,t,"utf8")}function et(e){let t=/^\[profiles\.(.+?)\]/gm,n=[],i;for(;i=t.exec(e);)n.push(i[1]);return n}function ln(e,t){let n=`profile = "${t}"`;if(/^profile\s*=\s*".*"/m.test(e))return e.replace(/^profile\s*=\s*".*"/m,n);let i=e.indexOf(`
44
- `);return i===-1?n+`
45
- `+e:e.slice(0,i+1)+n+`
46
- `+e.slice(i+1)}var nt=se({meta:{name:"config",description:"Manage Codex config profiles"},subCommands:{init:se({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=M(an,"templates/codex-config.toml"),n=await ve(t),{CFG:i}=$e(),o=await Z.access(i).then(()=>!0).catch(()=>!1);if(o&&!e.force){process.stdout.write(`${i} exists. Use --force to overwrite.
47
- `);return}if(o){let r=`${i}.backup.${Date.now()}`;await Z.copyFile(i,r),process.stdout.write(`Backed up to ${r}
48
- `)}await Ze(i,n),process.stdout.write(`Wrote ${i}
49
- `)}}),profiles:se({meta:{name:"profiles",description:"List profiles in the current config"},async run(){let{CFG:e}=$e(),t=await ve(e),n=et(t);process.stdout.write(n.length?n.join(`
50
+ `)}async function Nt(e){if(e.endsWith("/none")||e==="none")return;let t=[async o=>{await F("afplay"),await K`afplay ${o}`},async o=>{await F("paplay"),await K`paplay ${o}`},async o=>{await F("aplay"),await K`aplay ${o}`},async o=>{await F("mpg123"),await K`mpg123 -q ${o}`},async o=>{await F("ffplay"),await K`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 we(e){try{return await X.access(e),!0}catch{return!1}}function Tt(e){if(e==null)return;let t=String(e).toLowerCase();if(be(t))return t;if(t==="skip")return"skip";throw new Error("Invalid --profile value (use balanced|safe|minimal|yolo|skip).")}function xt(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 Dt(e){if(e==null)return;let t=String(e).toLowerCase();if(t==="yes"||t==="no")return t;throw new Error("Invalid --tools value (use yes|no).")}function At(e){if(e==null)return;let t=String(e).toLowerCase();if(t==="yes"||t==="no")return t;throw new Error("Expected yes|no")}function be(e){return e==="balanced"||e==="safe"||e==="minimal"||e==="yolo"}function _t(e){return be(e)?e:"balanced"}async function jt(e){try{let t=await X.readFile(e,"utf8"),i=ye.parse(t).profile;return typeof i=="string"?i:void 0}catch{return}}import{defineCommand as Ot}from"citty";import{promises as Y}from"fs";import{accessSync as Lt}from"fs";import{resolve as Q,dirname as Be}from"path";import{fileURLToPath as Gt}from"url";var Ve=Be(Gt(import.meta.url));function Ft(){let e=Ve;for(let t=0;t<6;t++){try{return Lt(Q(e,"templates","codex-config.toml")),e}catch{}e=Q(e,"..")}return Q(Ve,"..")}var qt=Ft();async function ke(e){try{return await Y.access(e),!0}catch{return!1}}async function Mt(e,t){if(await ke(t)){let i=`${t}.backup.${new Date().toISOString().replace(/[:.]/g,"").replace("T","_").slice(0,15)}`;await Y.copyFile(t,i)}await Y.mkdir(Be(t),{recursive:!0}),await Y.copyFile(e,t)}var He=Ot({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=Q(qt,"templates/agent-templates","AGENTS-default.md"),n=await ke(t).then(async r=>r&&(await Y.stat(t)).isDirectory()).catch(()=>!1)?Q(t,"AGENTS.md"):t;if(!await ke(o))throw new Error(`Template not found: ${o}`);await Mt(o,n),process.stdout.write(`Wrote ${n}
51
+ `)}});import{defineCommand as Wt}from"citty";import{$ as Ut}from"zx";import{fileURLToPath as zt}from"url";import{accessSync as Vt}from"fs";import{dirname as Bt,resolve as ie}from"path";var Ke=Bt(zt(import.meta.url));function Ht(){let e=Ke;for(let t=0;t<6;t++){try{return Vt(ie(e,"templates","codex-config.toml")),e}catch{}e=ie(e,"..")}return ie(Ke,"..")}var Kt=Ht(),Je=Wt({meta:{name:"doctor",description:"Run environment checks"},async run(){await Ut`bash ${ie(Kt,"scripts/doctor.sh")}`}});import{defineCommand as Jt}from"citty";import{$ as Xt}from"zx";import{fileURLToPath as Yt}from"url";import{accessSync as Qt}from"fs";import{dirname as Zt,resolve as re}from"path";var Xe=Zt(Yt(import.meta.url));function eo(){let e=Xe;for(let t=0;t<6;t++){try{return Qt(re(e,"templates","codex-config.toml")),e}catch{}e=re(e,"..")}return re(Xe,"..")}var to=eo(),Ye=Jt({meta:{name:"uninstall",description:"Clean up aliases and config created by this tool"},async run(){await Xt`bash ${re(to,"scripts/uninstall.sh")}`}});import{defineCommand as ae}from"citty";import{promises as Z}from"fs";import{resolve as q,dirname as tt}from"path";import{fileURLToPath as oo}from"url";import{accessSync as no}from"fs";import io from"os";var Qe=tt(oo(import.meta.url));function ro(){let e=Qe;for(let t=0;t<6;t++){try{return no(q(e,"templates","codex-config.toml")),e}catch{}e=q(e,"..")}return q(Qe,"..")}var ao=ro();function $e(){let e=q(io.homedir(),".codex"),t=q(e,"config.toml");return{CODEX_HOME:e,CFG:t}}async function ve(e){return Z.readFile(e,"utf8")}async function Ze(e,t){await Z.mkdir(tt(e),{recursive:!0}),await Z.writeFile(e,t,"utf8")}function et(e){let t=/^\[profiles\.(.+?)\]/gm,o=[],i;for(;i=t.exec(e);)o.push(i[1]);return o}function so(e,t){let o=`profile = "${t}"`;if(/^profile\s*=\s*".*"/m.test(e))return e.replace(/^profile\s*=\s*".*"/m,o);let i=e.indexOf(`
52
+ `);return i===-1?o+`
53
+ `+e:e.slice(0,i+1)+o+`
54
+ `+e.slice(i+1)}var ot=ae({meta:{name:"config",description:"Manage Codex config profiles"},subCommands:{init:ae({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=q(ao,"templates/codex-config.toml"),o=await ve(t),{CFG:i}=$e(),n=await Z.access(i).then(()=>!0).catch(()=>!1);if(n&&!e.force){process.stdout.write(`${i} exists. Use --force to overwrite.
55
+ `);return}if(n){let r=`${i}.backup.${Date.now()}`;await Z.copyFile(i,r),process.stdout.write(`Backed up to ${r}
56
+ `)}await Ze(i,o),process.stdout.write(`Wrote ${i}
57
+ `)}}),profiles:ae({meta:{name:"profiles",description:"List profiles in the current config"},async run(){let{CFG:e}=$e(),t=await ve(e),o=et(t);process.stdout.write(o.length?o.join(`
50
58
  `)+`
51
59
  `:`No profiles found
52
- `)}}),"set-profile":se({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}=$e(),n=await ve(t),i=et(n),o=String(e.name);if(!i.includes(o))throw new Error(`Unknown profile: ${o}`);let r=ln(n,o);await Ze(t,r),process.stdout.write(`profile set to ${o}
53
- `)}})}});var gn=cn(dn(import.meta.url)),mn=JSON.parse(fn(un(gn,"../package.json"),"utf-8")),ot=pn({meta:{name:"codex-1up",version:mn.version,description:"Power up Codex CLI with clean profiles config and helpers"},subCommands:{install:ze,agents:He,doctor:Je,uninstall:Ye,config:nt}});hn(ot);
60
+ `)}}),"set-profile":ae({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}=$e(),o=await ve(t),i=et(o),n=String(e.name);if(!i.includes(n))throw new Error(`Unknown profile: ${n}`);let r=so(o,n);await Ze(t,r),process.stdout.write(`profile set to ${n}
61
+ `)}})}});var go=fo(co(import.meta.url)),mo=JSON.parse(po(uo(go,"../package.json"),"utf-8")),nt=lo({meta:{name:"codex-1up",version:mo.version,description:"Power up Codex CLI with clean profiles config and helpers"},subCommands:{install:ze,agents:He,doctor:Je,uninstall:Ye,config:ot}});ho(nt);
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "codex-1up",
3
3
  "private": false,
4
4
  "type": "module",
5
- "version": "0.2.4",
5
+ "version": "0.2.5",
6
6
  "description": "TypeScript CLI for codex-1up (citty-based)",
7
7
  "bin": {
8
8
  "codex-1up": "bin/codex-1up.mjs"