codex-1up 0.2.0 → 0.2.1

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 (2) hide show
  1. package/dist/main.js +17 -17
  2. package/package.json +1 -1
package/dist/main.js CHANGED
@@ -1,47 +1,47 @@
1
- import{runMain as Qt}from"citty";import{defineCommand as Yt}from"citty";import{defineCommand as wt}from"citty";import{fileURLToPath as yt}from"url";import{dirname as bt,resolve as T}from"path";import{promises as Z}from"fs";import*as B from"os";import{accessSync as $t}from"fs";import*as Ge from"toml";import*as p from"@clack/prompts";import{which as O,$ as z}from"zx";import ht from"fs-extra";import*as pe from"path";import*as xe from"os";import{createWriteStream as Qe}from"fs";function me(e){let t=null;try{t=Qe(e,{flags:"a"})}catch{}let n=(i,o)=>{let r=i?`${i} ${o}
1
+ import{runMain as rn}from"citty";import{defineCommand as Yt}from"citty";import{readFileSync as Qt}from"fs";import{fileURLToPath as Zt}from"url";import{dirname as en,join as tn}from"path";import{defineCommand as wt}from"citty";import{fileURLToPath as yt}from"url";import{dirname as bt,resolve as T}from"path";import{promises as Z}from"fs";import*as B from"os";import{accessSync as $t}from"fs";import*as Ge from"toml";import*as p from"@clack/prompts";import{which as O,$ as z}from"zx";import ht from"fs-extra";import*as pe from"path";import*as xe from"os";import{createWriteStream as Qe}from"fs";function me(e){let t=null;try{t=Qe(e,{flags:"a"})}catch{}let n=(i,o)=>{let r=i?`${i} ${o}
2
2
  `:`${o}
3
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 x}from"zx";import{which as Ze,$ as et}from"zx";import{spawn as tt}from"child_process";async function d(e){try{return await Ze(e),!0}catch{return!1}}async function he(){return await d("brew")?"brew":await d("apt-get")?"apt":await d("dnf")?"dnf":await d("pacman")?"pacman":await d("zypper")?"zypper":"none"}async function we(e){if(await d("pnpm"))try{if((await et`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 d("pnpm")?"none":"npm"}async function h(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=tt(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 P(e){let t=new Date().toISOString().replace(/[:.]/g,"-").slice(0,-5);return`${e}.backup.${t}`}import ye from"fs-extra";import*as L from"path";import*as U from"os";async function be(e){let t=await d("node"),n=await d("npm");if(t&&n){let o=(await x`node -v`).stdout.trim();e.logger.ok(`Node.js present (${o})`);return}switch(e.options.installNode){case"nvm":await nt(e);break;case"brew":await ot(e);break;case"skip":e.logger.warn("Skipping Node installation; please install Node 18+ manually");return}if(await d("node")){let o=(await x`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 nt(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=L.join(e.homeDir,".nvm"),n=L.join(t,"nvm.sh");await ye.pathExists(t)||(e.logger.info("Installing nvm..."),await x`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 x`bash -c ${i}`}async function ot(e){if(e.logger.info("Installing Node.js via Homebrew"),!await d("brew"))if(U.platform()==="darwin"){if(e.logger.info("Homebrew not found; installing Homebrew"),e.options.dryRun){e.logger.log("[dry-run] install Homebrew");return}await x`/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"`;let t=U.platform()==="darwin"&&U.arch()==="arm64"?"/opt/homebrew/bin/brew":"/usr/local/bin/brew";if(await ye.pathExists(t)){let n=L.dirname(t);process.env.PATH=`${n}:${process.env.PATH||""}`;try{let o=(await x`${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 h("brew",["install","node"],{dryRun:e.options.dryRun,logger:e.logger})}import{$ as re}from"zx";var it=["@openai/codex","@ast-grep/cli"],rt="@ast-grep/cli",st="@openai/codex";async function at(){return await d("sg")||await d("ast-grep")}async function $e(e){e.logger.info("Checking global packages (@openai/codex, @ast-grep/cli)");let t=[];for(let n of it)try{if(n===st&&await d("codex")){e.logger.ok("codex found on PATH; skipping global install/upgrade");continue}let o=(await re`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 re`npm ls -g ${n} --depth=0 --json`.quiet().nothrow(),s="";try{s=JSON.parse(r.stdout||"{}").dependencies?.[n]?.version||""}catch{s=""}if(n===rt&&await at()&&!s){e.logger.ok("ast-grep already installed (found sg/ast-grep on PATH); skipping npm install");continue}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 re`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 we(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 h("pnpm",["add","-g",...t],{dryRun:e.options.dryRun,logger:e.logger})):(e.logger.info("Installing/updating global packages via npm"),await h("npm",["install","-g",...t],{dryRun:e.options.dryRun,logger:e.logger}))}else e.logger.ok("Global packages are up-to-date");await d("codex")?e.logger.ok("Codex CLI installed"):e.logger.err("Codex CLI not found after install"),await d("ast-grep")?e.logger.ok("ast-grep installed"):e.logger.warn("ast-grep not found; check npm global path")}import{$ as lt}from"zx";import*as ae from"path";import se from"fs-extra";var pt={brew:["fd","ripgrep","fzf","jq","yq","difftastic"],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 ke(e){let t=await he();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=pt[t]||[];if(n.length>0)switch(t){case"brew":await h("brew",["update"],{dryRun:e.options.dryRun,logger:e.logger}),await h("brew",["install",...n],{dryRun:e.options.dryRun,logger:e.logger});break;case"apt":await h("sudo",["apt-get","update","-y"],{dryRun:e.options.dryRun,logger:e.logger}),await h("sudo",["apt-get","install","-y",...n],{dryRun:e.options.dryRun,logger:e.logger}).catch(()=>{}),await d("fd")||await h("sudo",["apt-get","install","-y","fd-find"],{dryRun:e.options.dryRun,logger:e.logger}).catch(()=>{});break;case"dnf":await h("sudo",["dnf","install","-y",...n],{dryRun:e.options.dryRun,logger:e.logger}).catch(()=>{});break;case"pacman":await h("sudo",["pacman","-Sy","--noconfirm",...n],{dryRun:e.options.dryRun,logger:e.logger}).catch(()=>{});break;case"zypper":await h("sudo",["zypper","refresh"],{dryRun:e.options.dryRun,logger:e.logger}),await h("sudo",["zypper","install","-y",...n],{dryRun:e.options.dryRun,logger:e.logger}).catch(()=>{});break}if(!await d("difft")&&!await d("difftastic")&&(await d("cargo")?(e.logger.info("Installing difftastic via cargo"),await h("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 d("fdfind")&&!await d("fd")){let o=ae.join(e.homeDir,".local","bin");await se.ensureDir(o);let r=(await lt`command -v fdfind`).stdout.trim(),s=ae.join(o,"fd");await se.pathExists(s)||(e.options.dryRun?e.logger.log(`[dry-run] ln -s ${r} ${s}`):await se.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 d(o)&&e.logger.ok(`${o} \u2713`)}import q from"fs-extra";import*as Y from"path";var ve={balanced:{root:[["approval_policy",'"on-request"'],["sandbox_mode",'"workspace-write"']],features:[["web_search_request","true"]]},safe:{root:[["approval_policy",'"on-failure"'],["sandbox_mode",'"workspace-write"']],features:[["web_search_request","false"]]},minimal:{root:[["model_reasoning_effort",'"minimal"']],features:[["web_search_request","false"]]},yolo:{root:[["approval_policy",'"never"'],["sandbox_mode",'"danger-full-access"']],features:[["web_search_request","true"]]}},ft=`# ~/.codex/config.toml \u2014 managed by codex-1up (patch mode)
4
- `;async function Ee(e){let t=Y.join(e.homeDir,".codex","config.toml");await q.ensureDir(Y.dirname(t));let n=await q.pathExists(t),i=n?await q.readFile(t,"utf8"):ft,o=new le(i),r=!1;if(r=ct(o,e.options.profilesAction)||r,r=dt(o,e.options.reasoning)||r,r=ut(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=P(t);await q.copy(t,a),e.logger.info(`Backed up current config to ${a}`)}await q.writeFile(t,s,"utf8"),e.logger.ok("Updated ~/.codex/config.toml with requested settings.")}function ct(e,t){if(t==="skip")return!1;let n=!1;for(let i of Object.keys(ve)){let o=ve[i];if(t==="overwrite")n=e.replaceTable(`profiles.${i}`,o.root)||n,n=e.replaceTable(`profiles.${i}.features`,o.features)||n;else{e.ensureTable(`profiles.${i}`);for(let[r,s]of o.root)n=e.setKey(`profiles.${i}`,r,s,{mode:"if-missing"})||n;e.ensureTable(`profiles.${i}.features`);for(let[r,s]of o.features)n=e.setKey(`profiles.${i}.features`,r,s,{mode:"if-missing"})||n}}return n}function dt(e,t){if(t==="off")return!1;e.ensureTable("tui");let n=e.setKey("tui","show_raw_agent_reasoning","true",{mode:"force"}),i=e.setKey("tui","hide_agent_reasoning","false",{mode:"force"});return n||i}function ut(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 le=class{text;constructor(t){this.text=t||""}content(){return gt(this.text)}ensureTable(t){if(this.hasTable(t))return!1;let n=this.text.length===0?"":Se(this.text);return this.text=n+`[${t}]
5
- `,!0}setKey(t,n,i,o){let r=J(this.text,t);if(!r)return this.ensureTable(t),this.setKey(t,n,i,o);let s=this.text.slice(r.start,r.end),c=new RegExp(`^\\s*${Ce(n)}\\s*=.*$`,"m").exec(s);if(c){if(o.mode==="if-missing")return!1;let D=this.text,I=r.start+c.index,X=I+c[0].length;return this.text=D.slice(0,I)+`${n} = ${i}`+D.slice(X),this.text!==D}let $=this.text,w=r.end,y=$.slice(0,w),v=$.slice(w),l=y.length>0&&!y.endsWith(`
4
+ `;async function Ee(e){let t=Y.join(e.homeDir,".codex","config.toml");await q.ensureDir(Y.dirname(t));let n=await q.pathExists(t),i=n?await q.readFile(t,"utf8"):ft,o=new le(i),r=!1;if(r=ct(o,e.options.profilesAction)||r,r=dt(o,e.options.reasoning)||r,r=ut(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=P(t);await q.copy(t,a),e.logger.info(`Backed up current config to ${a}`)}await q.writeFile(t,s,"utf8"),e.logger.ok("Updated ~/.codex/config.toml with requested settings.")}function ct(e,t){if(t==="skip")return!1;let n=!1;for(let i of Object.keys(ve)){let o=ve[i];if(t==="overwrite")n=e.replaceTable(`profiles.${i}`,o.root)||n,n=e.replaceTable(`profiles.${i}.features`,o.features)||n;else{e.ensureTable(`profiles.${i}`);for(let[r,s]of o.root)n=e.setKey(`profiles.${i}`,r,s,{mode:"if-missing"})||n;e.ensureTable(`profiles.${i}.features`);for(let[r,s]of o.features)n=e.setKey(`profiles.${i}.features`,r,s,{mode:"if-missing"})||n}}return n}function dt(e,t){if(t==="off")return!1;e.ensureTable("tui");let n=e.setKey("tui","show_raw_agent_reasoning","true",{mode:"force"}),i=e.setKey("tui","hide_agent_reasoning","false",{mode:"force"});return n||i}function ut(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 le=class{text;constructor(t){this.text=t||""}content(){return gt(this.text)}ensureTable(t){if(this.hasTable(t))return!1;let n=this.text.length===0?"":Ce(this.text);return this.text=n+`[${t}]
5
+ `,!0}setKey(t,n,i,o){let r=X(this.text,t);if(!r)return this.ensureTable(t),this.setKey(t,n,i,o);let s=this.text.slice(r.start,r.end),c=new RegExp(`^\\s*${Se(n)}\\s*=.*$`,"m").exec(s);if(c){if(o.mode==="if-missing")return!1;let D=this.text,I=r.start+c.index,J=I+c[0].length;return this.text=D.slice(0,I)+`${n} = ${i}`+D.slice(J),this.text!==D}let $=this.text,w=r.end,y=$.slice(0,w),v=$.slice(w),l=y.length>0&&!y.endsWith(`
6
6
  `),f=v.length>0&&!v.startsWith(`
7
7
  `),u=`${l?`
8
8
  `:""}${n} = ${i}
9
9
  ${f?`
10
- `:""}`;return this.text=y+u+v,this.text!==$}getValue(t,n){let i=J(this.text,t);if(!i)return;let o=this.text.slice(i.start,i.end),s=new RegExp(`^\\s*${Ce(n)}\\s*=\\s*(.+)$`,"m").exec(o);return s?s[1]:void 0}replaceTable(t,n){let i=n.map(([a,c])=>`${a} = ${c}`).join(`
10
+ `:""}`;return this.text=y+u+v,this.text!==$}getValue(t,n){let i=X(this.text,t);if(!i)return;let o=this.text.slice(i.start,i.end),s=new RegExp(`^\\s*${Se(n)}\\s*=\\s*(.+)$`,"m").exec(o);return s?s[1]:void 0}replaceTable(t,n){let i=n.map(([a,c])=>`${a} = ${c}`).join(`
11
11
  `),o=`[${t}]
12
12
  ${i}
13
13
 
14
- `,r=this.text,s=J(this.text,t);if(!s){let a=r.length===0?"":Se(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}hasTable(t){return J(this.text,t)!==null}};function J(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 Ce(e){return e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}function gt(e){return e.endsWith(`
14
+ `,r=this.text,s=X(this.text,t);if(!s){let a=r.length===0?"":Ce(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}hasTable(t){return X(this.text,t)!==null}};function X(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 Se(e){return e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}function gt(e){return e.endsWith(`
15
15
  `)?e:e+`
16
- `}function Se(e){let t=e;return t.endsWith(`
16
+ `}function Ce(e){let t=e;return t.endsWith(`
17
17
  `)||(t+=`
18
18
  `),t.endsWith(`
19
19
 
20
20
  `)||(t+=`
21
- `),t}import R from"fs-extra";import*as j from"path";async function Re(e){let t=j.join(e.homeDir,".codex","notify.sh"),n=j.join(e.rootDir,"templates","notification.sh");await R.ensureDir(j.dirname(t));let i=e.options.notify;if(i==="no"){e.logger.info("Skipping notify hook installation");return}if(!await R.pathExists(n)){e.logger.warn(`Notification template missing at ${n}; skipping notify hook install`);return}if(await R.pathExists(t))if(i==="yes"){let r=P(t);e.options.dryRun?e.logger.log(`[dry-run] cp ${t} ${r}`):await R.copy(t,r),e.options.dryRun?e.logger.log(`[dry-run] cp ${n} ${t}`):(await R.copy(n,t),await R.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 R.copy(n,t),await R.chmod(t,493)),e.logger.ok("Installed notify hook to ~/.codex/notify.sh");let o=j.join(e.homeDir,".codex","config.toml");await R.pathExists(o)?await mt(o,t,e):e.logger.warn(`Config not found at ${o}; run again after config is created`)}async function mt(e,t,n){if(n.options.dryRun){n.logger.log("[dry-run] update config notify and tui.notifications");return}let o=(await R.readFile(e,"utf8")).split(/\r?\n/),r="",s=null,a=null,c=!1,$=!1;for(let l=0;l<o.length;l++){let f=o[l],u=f.match(/^\s*\[([^\]]+)\]\s*$/);if(u){r=u[1],r==="tui"&&(a=l);continue}let D=/^\s*notify\s*=\s*\[/.test(f),I=/^\s*tui\.notifications\s*=/.test(f),X=/^\s*notifications\s*=/.test(f);D&&(r===""?s===null&&(s=l):/^profiles\.[^.]+\.features$/.test(r)&&(o.splice(l,1),l--,c=!0)),I&&/^profiles\.[^.]+\.features$/.test(r)&&(o.splice(l,1),l--,$=!0),X&&r===""&&(o.splice(l,1),l--,$=!0)}function w(l){let f=0;for(;f<o.length&&/^\s*(#.*)?$/.test(o[f]);)f++;o.splice(f,0,l)}if(s!==null){let l=o[s].match(/^(\s*notify\s*=\s*\[)([^\]]*)\]/);if(l){let f=l[2].trim();if(!f.includes(JSON.stringify(t))){let D=f&&!f.endsWith(",")?", ":"";o[s]=`${l[1]}${f}${D}${JSON.stringify(t)}]`,n.logger.ok("Added notify hook to config")}}}else w(`notify = [${JSON.stringify(t)}]`),n.logger.ok("Enabled notify hook in config");let y=!1;if(a!==null){let l=a+1,f=!1;for(;l<o.length;l++){let u=o[l];if(/^\s*\[/.test(u))break;if(/^\s*notifications\s*=/.test(u)){o[l]="notifications = true",f=!0,y=!0;break}}f||(o.splice(a+1,0,"notifications = true"),y=!0)}y||w(`[tui]
21
+ `),t}import R from"fs-extra";import*as j from"path";async function Re(e){let t=j.join(e.homeDir,".codex","notify.sh"),n=j.join(e.rootDir,"templates","notification.sh");await R.ensureDir(j.dirname(t));let i=e.options.notify;if(i==="no"){e.logger.info("Skipping notify hook installation");return}if(!await R.pathExists(n)){e.logger.warn(`Notification template missing at ${n}; skipping notify hook install`);return}if(await R.pathExists(t))if(i==="yes"){let r=P(t);e.options.dryRun?e.logger.log(`[dry-run] cp ${t} ${r}`):await R.copy(t,r),e.options.dryRun?e.logger.log(`[dry-run] cp ${n} ${t}`):(await R.copy(n,t),await R.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 R.copy(n,t),await R.chmod(t,493)),e.logger.ok("Installed notify hook to ~/.codex/notify.sh");let o=j.join(e.homeDir,".codex","config.toml");await R.pathExists(o)?await mt(o,t,e):e.logger.warn(`Config not found at ${o}; run again after config is created`)}async function mt(e,t,n){if(n.options.dryRun){n.logger.log("[dry-run] update config notify and tui.notifications");return}let o=(await R.readFile(e,"utf8")).split(/\r?\n/),r="",s=null,a=null,c=!1,$=!1;for(let l=0;l<o.length;l++){let f=o[l],u=f.match(/^\s*\[([^\]]+)\]\s*$/);if(u){r=u[1],r==="tui"&&(a=l);continue}let D=/^\s*notify\s*=\s*\[/.test(f),I=/^\s*tui\.notifications\s*=/.test(f),J=/^\s*notifications\s*=/.test(f);D&&(r===""?s===null&&(s=l):/^profiles\.[^.]+\.features$/.test(r)&&(o.splice(l,1),l--,c=!0)),I&&/^profiles\.[^.]+\.features$/.test(r)&&(o.splice(l,1),l--,$=!0),J&&r===""&&(o.splice(l,1),l--,$=!0)}function w(l){let f=0;for(;f<o.length&&/^\s*(#.*)?$/.test(o[f]);)f++;o.splice(f,0,l)}if(s!==null){let l=o[s].match(/^(\s*notify\s*=\s*\[)([^\]]*)\]/);if(l){let f=l[2].trim();if(!f.includes(JSON.stringify(t))){let D=f&&!f.endsWith(",")?", ":"";o[s]=`${l[1]}${f}${D}${JSON.stringify(t)}]`,n.logger.ok("Added notify hook to config")}}}else w(`notify = [${JSON.stringify(t)}]`),n.logger.ok("Enabled notify hook in config");let y=!1;if(a!==null){let l=a+1,f=!1;for(;l<o.length;l++){let u=o[l];if(/^\s*\[/.test(u))break;if(/^\s*notifications\s*=/.test(u)){o[l]="notifications = true",f=!0,y=!0;break}}f||(o.splice(a+1,0,"notifications = true"),y=!0)}y||w(`[tui]
22
22
  notifications = true`);let v=[];r="";for(let l=0;l<o.length;l++){let f=o[l],u=f.match(/^\s*\[([^\]]+)\]\s*$/);if(u){r=u[1],v.push(f);continue}/^\s*tui\.notifications\s*=/.test(f)||/^\s*notifications\s*=/.test(f)&&r!=="tui"||v.push(f)}await R.writeFile(e,v.join(`
23
- `),"utf8")}import C from"fs-extra";import*as m from"path";async function Te(e){let t=m.join(e.rootDir,"sounds"),n=m.join(e.homeDir,".codex","sounds");await C.ensureDir(n);let i=e.options.notificationSound;if(i==="none"){let y=await Ne(e);e.options.dryRun?e.logger.log(`[dry-run] update ${y}`):await Pe(y,`# Notification sound (disabled)
23
+ `),"utf8")}import S from"fs-extra";import*as m from"path";async function Te(e){let t=m.join(e.rootDir,"sounds"),n=m.join(e.homeDir,".codex","sounds");await S.ensureDir(n);let i=e.options.notificationSound;if(i==="none"){let y=await Ne(e);e.options.dryRun?e.logger.log(`[dry-run] update ${y}`):await Pe(y,`# Notification sound (disabled)
24
24
  export CODEX_DISABLE_SOUND=1
25
25
  export CODEX_CUSTOM_SOUND=""
26
- `,e);let l=m.join(e.homeDir,".codex","notify.sh");if(await C.pathExists(l)){let f=await C.readFile(l,"utf8"),u=f.replace(/^DEFAULT_CODEX_SOUND=.*$/m,'DEFAULT_CODEX_SOUND=""');e.options.dryRun?e.logger.log(`[dry-run] patch ${l} DEFAULT_CODEX_SOUND -> empty`):u!==f&&await C.writeFile(l,u,"utf8")}e.logger.ok("Notification sound disabled");return}let o;if(i&&!m.isAbsolute(i)?o=m.join(t,i):i?o=i:e.options.mode==="recommended"&&(o=m.join(t,"noti_1.wav")),!o||!await C.pathExists(o)){e.logger.warn("No notification sound selected or file missing; skipping sound setup");return}let r=m.isAbsolute(o),s=o.startsWith(m.join(e.rootDir,"sounds")),a=!r||s?m.join(n,m.basename(o)):o;(!r||s)&&(e.options.dryRun?e.logger.log(`[dry-run] cp ${o} ${a}`):await C.copy(o,a));let c=await Ne(e),$=`# Notification sound
26
+ `,e);let l=m.join(e.homeDir,".codex","notify.sh");if(await S.pathExists(l)){let f=await S.readFile(l,"utf8"),u=f.replace(/^DEFAULT_CODEX_SOUND=.*$/m,'DEFAULT_CODEX_SOUND=""');e.options.dryRun?e.logger.log(`[dry-run] patch ${l} DEFAULT_CODEX_SOUND -> empty`):u!==f&&await S.writeFile(l,u,"utf8")}e.logger.ok("Notification sound disabled");return}let o;if(i&&!m.isAbsolute(i)?o=m.join(t,i):i?o=i:e.options.mode==="recommended"&&(o=m.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=m.isAbsolute(o),s=o.startsWith(m.join(e.rootDir,"sounds")),a=!r||s?m.join(n,m.basename(o)):o;(!r||s)&&(e.options.dryRun?e.logger.log(`[dry-run] cp ${o} ${a}`):await S.copy(o,a));let c=await Ne(e),$=`# Notification sound
27
27
  export CODEX_DISABLE_SOUND=0
28
28
  export CODEX_CUSTOM_SOUND="${a}"
29
- `;e.options.dryRun?e.logger.log(`[dry-run] update ${c}`):await Pe(c,$,e),e.logger.ok("Notification sound configured. Open a new shell or source your rc to apply.");let w=m.join(e.homeDir,".codex","notify.sh");if(await C.pathExists(w)){let y=await C.readFile(w,"utf8"),v=`DEFAULT_CODEX_SOUND="${a}"`,l=y.replace(/^DEFAULT_CODEX_SOUND=.*$/m,v);l!==y&&(e.options.dryRun?e.logger.log(`[dry-run] patch ${w} DEFAULT_CODEX_SOUND -> ${a}`):await C.writeFile(w,l,"utf8"))}}async function Ne(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 m.join(e.homeDir,".zshrc");case"fish":return m.join(e.homeDir,".config","fish","config.fish");default:return m.join(e.homeDir,".bashrc")}}async function Pe(e,t,n){let i="codex-1up";await C.ensureDir(m.dirname(e));let o="";if(await C.pathExists(e)){o=await C.readFile(e,"utf8");let s=`>>> ${i} >>>`,a=`<<< ${i} <<<`,c=new RegExp(`${s}[\\s\\S]*?${a}\\n?`,"g");o=o.replace(c,"")}let r=`>>> ${i} >>>
29
+ `;e.options.dryRun?e.logger.log(`[dry-run] update ${c}`):await Pe(c,$,e),e.logger.ok("Notification sound configured. Open a new shell or source your rc to apply.");let w=m.join(e.homeDir,".codex","notify.sh");if(await S.pathExists(w)){let y=await S.readFile(w,"utf8"),v=`DEFAULT_CODEX_SOUND="${a}"`,l=y.replace(/^DEFAULT_CODEX_SOUND=.*$/m,v);l!==y&&(e.options.dryRun?e.logger.log(`[dry-run] patch ${w} DEFAULT_CODEX_SOUND -> ${a}`):await S.writeFile(w,l,"utf8"))}}async function Ne(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 m.join(e.homeDir,".zshrc");case"fish":return m.join(e.homeDir,".config","fish","config.fish");default:return m.join(e.homeDir,".bashrc")}}async function Pe(e,t,n){let i="codex-1up";await S.ensureDir(m.dirname(e));let o="";if(await S.pathExists(e)){o=await S.readFile(e,"utf8");let s=`>>> ${i} >>>`,a=`<<< ${i} <<<`,c=new RegExp(`${s}[\\s\\S]*?${a}\\n?`,"g");o=o.replace(c,"")}let r=`>>> ${i} >>>
30
30
  ${t}<<< ${i} <<<
31
- `;await C.writeFile(e,o+r,"utf8")}import S from"fs-extra";import*as A from"path";async function De(e){let t=A.join(e.homeDir,".codex","AGENTS.md"),n=e.options.globalAgents;if(n==="skip"){e.logger.info("Skipping global AGENTS.md creation");return}let i=A.join(e.rootDir,"templates","agent-templates","AGENTS-default.md");if(!await S.pathExists(i)){e.logger.warn(`Template not found at ${i}`);return}switch(n){case"create-default":if(await S.pathExists(t)){e.logger.info("Global AGENTS.md already exists; leaving unchanged");return}await S.ensureDir(A.dirname(t)),e.options.dryRun?e.logger.log(`[dry-run] cp ${i} ${t}`):await S.copy(i,t),e.logger.ok(`Wrote ${t}`);break;case"overwrite-default":if(await S.ensureDir(A.dirname(t)),await S.pathExists(t)){let r=P(t);e.options.dryRun?e.logger.log(`[dry-run] cp ${t} ${r}`):await S.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 S.copy(i,t),e.logger.ok(`Wrote ${t}`);break;case"append-default":if(await S.ensureDir(A.dirname(t)),await S.pathExists(t)){let r=P(t);e.options.dryRun?e.logger.log(`[dry-run] cp ${t} ${r}`):await S.copy(t,r),e.logger.info(`Backed up existing AGENTS.md to: ${r}`)}let o=await S.readFile(i,"utf8");e.options.dryRun?e.logger.log(`[dry-run] append template to ${t}`):await S.appendFile(t,`
31
+ `;await S.writeFile(e,o+r,"utf8")}import C from"fs-extra";import*as A from"path";async function De(e){let t=A.join(e.homeDir,".codex","AGENTS.md"),n=e.options.globalAgents;if(n==="skip"){e.logger.info("Skipping global AGENTS.md creation");return}let i=A.join(e.rootDir,"templates","agent-templates","AGENTS-default.md");if(!await C.pathExists(i)){e.logger.warn(`Template not found at ${i}`);return}switch(n){case"create-default":if(await C.pathExists(t)){e.logger.info("Global AGENTS.md already exists; leaving unchanged");return}await C.ensureDir(A.dirname(t)),e.options.dryRun?e.logger.log(`[dry-run] cp ${i} ${t}`):await C.copy(i,t),e.logger.ok(`Wrote ${t}`);break;case"overwrite-default":if(await C.ensureDir(A.dirname(t)),await C.pathExists(t)){let r=P(t);e.options.dryRun?e.logger.log(`[dry-run] cp ${t} ${r}`):await C.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 C.copy(i,t),e.logger.ok(`Wrote ${t}`);break;case"append-default":if(await C.ensureDir(A.dirname(t)),await C.pathExists(t)){let r=P(t);e.options.dryRun?e.logger.log(`[dry-run] cp ${t} ${r}`):await C.copy(t,r),e.logger.info(`Backed up existing AGENTS.md to: ${r}`)}let o=await C.readFile(i,"utf8");e.options.dryRun?e.logger.log(`[dry-run] append template to ${t}`):await C.appendFile(t,`
32
32
  ---
33
33
 
34
- ${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 Ie(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 d("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 h("code",["--install-extension",t,"--force"],{dryRun:!1,logger:e.logger}),e.logger.ok(`VS Code extension '${t}' installed (or already present)`)}import W from"fs-extra";import*as M from"path";async function Ae(e){let t=e.options.agentsMd;if(!t)return;let n=t;(await W.stat(n).catch(()=>null))?.isDirectory()&&(n=M.join(n,"AGENTS.md"));let i=M.join(e.rootDir,"templates","agent-templates","AGENTS-default.md");if(await W.pathExists(n)){e.logger.warn(`${n} already exists`);let o=P(n);e.options.dryRun?e.logger.log(`[dry-run] cp ${n} ${o}`):await W.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 W.ensureDir(M.dirname(n)),await W.copy(i,n),e.logger.ok("Wrote AGENTS.md"))}var _e="codex-1up";async function fe(e,t){let n=xe.homedir(),i=pe.join(n,`.${_e}`);await ht.ensureDir(i);let o=new Date().toISOString().replace(/[:.]/g,"-").slice(0,-5),r=pe.join(i,`install-${o}.log`),s=me(r);s.info(`==> ${_e} installer`),s.info(`Log: ${r}`);let a={cwd:process.cwd(),homeDir:n,rootDir:t,logDir:i,logFile:r,options:e,logger:s};try{await be(a),await $e(a),await ke(a),await Ee(a),await Re(a),await Te(a),await De(a),await Ie(a),await Ae(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(c){throw s.err(`Installation failed: ${c}`),c}}var je=bt(yt(import.meta.url));function kt(){let e=je;for(let t=0;t<6;t++){try{return $t(T(e,"templates","codex-config.toml")),e}catch{}e=T(e,"..")}return T(je,"..")}var Q=kt(),Fe=wt({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"},profiles:{type:"string",description:"add|overwrite|skip (installer config profiles)"},reasoning:{type:"string",description:"on|off for reasoning steps visibility"},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=T(B.homedir(),".codex","config.toml"),n=await ce(t),i=T(B.homedir(),".codex","notify.sh"),o=await ce(i),r=T(B.homedir(),".codex","AGENTS.md"),s=await ce(r),a=process.stdout.isTTY&&!e["dry-run"]&&!e["skip-confirmation"]&&!e.yes,c=Ct(e.profiles),$=St(e.reasoning),w=typeof e.sound>"u"?void 0:String(e.sound).trim();if(w==="")throw new Error('Invalid --sound value (expected path, "none", or "skip")');let y=c||"add",v=$||"on",l,f,u;if(w&&(g=>{let N=g.trim().toLowerCase();if(N==="skip"){l="no",u=void 0;return}l="yes",u=N==="none"?"none":g})(w),a){if(p.intro("codex-1up \xB7 Install"),!c){let g=await p.select({message:"Install codex profiles (balanced, safe, minimal, yolo)?",options:[{label:"Add / merge (recommended)",value:"add"},{label:"Overwrite codex profiles",value:"overwrite"},{label:"Skip profiles",value:"skip"}],initialValue:"add"});if(p.isCancel(g))return p.cancel("Install aborted");y=g}if(!$){let g=await p.confirm({message:"Enable reasoning steps (show raw agent reasoning)?",initialValue:!0});if(p.isCancel(g))return p.cancel("Install aborted");v=g?"on":"off"}if(!w){let oe=function(E){return[{label:"Skip (leave current setup)",value:"skip"},{label:"None (disable sounds)",value:"none"},...N.map(b=>({label:b,value:b})),{label:"Custom path\u2026",value:"custom"}]};var X=oe;let g=T(Q,"sounds"),N=[];try{N=(await Z.readdir(g)).filter(E=>/\.(wav|mp3|ogg)$/i.test(E)).sort()}catch{}l="yes";let k=N.includes("noti_1.wav")?"noti_1.wav":N[0]||"none";async function ie(E){let b=await p.text({message:"Enter absolute path to a .wav file",placeholder:E||"/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(p.isCancel(b))return null;try{await Z.access(String(b))}catch{return p.log.warn("File not found. Try again."),await ie(String(b))}return String(b)}let F=await p.select({message:"Notification sound",options:oe(k),initialValue:k});if(p.isCancel(F))return p.cancel("Install aborted");if(F==="skip")l="no",u=void 0;else if(F==="custom"){let E=await ie();if(E===null)return p.cancel("Install aborted");k=E}else k=F;if(F!=="skip"){for(;;){let E=await p.select({message:`Selected: ${k}. 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(p.isCancel(E))return p.cancel("Install aborted");if(E==="use")break;if(E==="change"){let b=await p.select({message:"Notification sound",options:oe(k),initialValue:k});if(p.isCancel(b))return p.cancel("Install aborted");if(b==="custom"){let _=await ie();if(_===null)return p.cancel("Install aborted");k=_}else if(b==="skip"){l="no",u=void 0;break}else k=b;continue}try{let b=k==="none"?"none":k.startsWith("/")?k:T(Q,"sounds",k);await vt(b)}catch(b){p.log.warn(String(b))}}u===void 0&&(u=k)}}if(s){let g=await p.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(p.isCancel(g))return p.cancel("Install aborted");f=g}else f="skip"}a||(typeof l>"u"&&(l=o?"no":"yes"),typeof f>"u"&&(f="skip"));let I={profilesAction:y,reasoning:v,notify:l??(o?"no":"yes"),globalAgents:f??"skip",notificationSound:u,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(a){let g=p.spinner();g.start("Installing prerequisites and writing config");try{await fe(I,Q),g.stop("Base install complete"),p.outro("Install finished")}catch(N){throw g.stop("Installation failed"),p.cancel(`Installation failed: ${N}`),N}await Oe();return}try{await fe(I,Q),await Oe()}catch(g){throw p.cancel(`Installation failed: ${g}`),g}}});async function Oe(){let e=B.homedir(),t=T(e,".codex","config.toml"),n,i=[];try{let c=await Z.readFile(t,"utf8"),$=Ge.parse(c);n=$.profile;let w=$.profiles||{};i=Object.keys(w)}catch{}let o=["codex","ast-grep","fd","rg","fzf","jq","yq","difft","difftastic"],s=(await Promise.all(o.map(async c=>{try{return await O(c),[c,!0]}catch{return[c,!1]}}))).filter(([,c])=>c).map(([c])=>c),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(`
34
+ ${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 Ie(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 d("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 h("code",["--install-extension",t,"--force"],{dryRun:!1,logger:e.logger}),e.logger.ok(`VS Code extension '${t}' installed (or already present)`)}import W from"fs-extra";import*as M from"path";async function Ae(e){let t=e.options.agentsMd;if(!t)return;let n=t;(await W.stat(n).catch(()=>null))?.isDirectory()&&(n=M.join(n,"AGENTS.md"));let i=M.join(e.rootDir,"templates","agent-templates","AGENTS-default.md");if(await W.pathExists(n)){e.logger.warn(`${n} already exists`);let o=P(n);e.options.dryRun?e.logger.log(`[dry-run] cp ${n} ${o}`):await W.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 W.ensureDir(M.dirname(n)),await W.copy(i,n),e.logger.ok("Wrote AGENTS.md"))}var _e="codex-1up";async function fe(e,t){let n=xe.homedir(),i=pe.join(n,`.${_e}`);await ht.ensureDir(i);let o=new Date().toISOString().replace(/[:.]/g,"-").slice(0,-5),r=pe.join(i,`install-${o}.log`),s=me(r);s.info(`==> ${_e} installer`),s.info(`Log: ${r}`);let a={cwd:process.cwd(),homeDir:n,rootDir:t,logDir:i,logFile:r,options:e,logger:s};try{await be(a),await $e(a),await ke(a),await Ee(a),await Re(a),await Te(a),await De(a),await Ie(a),await Ae(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(c){throw s.err(`Installation failed: ${c}`),c}}var je=bt(yt(import.meta.url));function kt(){let e=je;for(let t=0;t<6;t++){try{return $t(T(e,"templates","codex-config.toml")),e}catch{}e=T(e,"..")}return T(je,"..")}var Q=kt(),Fe=wt({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"},profiles:{type:"string",description:"add|overwrite|skip (installer config profiles)"},reasoning:{type:"string",description:"on|off for reasoning steps visibility"},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=T(B.homedir(),".codex","config.toml"),n=await ce(t),i=T(B.homedir(),".codex","notify.sh"),o=await ce(i),r=T(B.homedir(),".codex","AGENTS.md"),s=await ce(r),a=process.stdout.isTTY&&!e["dry-run"]&&!e["skip-confirmation"]&&!e.yes,c=St(e.profiles),$=Ct(e.reasoning),w=typeof e.sound>"u"?void 0:String(e.sound).trim();if(w==="")throw new Error('Invalid --sound value (expected path, "none", or "skip")');let y=c||"add",v=$||"on",l,f,u;if(w&&(g=>{let N=g.trim().toLowerCase();if(N==="skip"){l="no",u=void 0;return}l="yes",u=N==="none"?"none":g})(w),a){if(p.intro("codex-1up \xB7 Install"),!c){let g=await p.select({message:"Install codex profiles (balanced, safe, minimal, yolo)?",options:[{label:"Add / merge (recommended)",value:"add"},{label:"Overwrite codex profiles",value:"overwrite"},{label:"Skip profiles",value:"skip"}],initialValue:"add"});if(p.isCancel(g))return p.cancel("Install aborted");y=g}if(!$){let g=await p.confirm({message:"Enable reasoning steps (show raw agent reasoning)?",initialValue:!0});if(p.isCancel(g))return p.cancel("Install aborted");v=g?"on":"off"}if(!w){let oe=function(E){return[{label:"Skip (leave current setup)",value:"skip"},{label:"None (disable sounds)",value:"none"},...N.map(b=>({label:b,value:b})),{label:"Custom path\u2026",value:"custom"}]};var J=oe;let g=T(Q,"sounds"),N=[];try{N=(await Z.readdir(g)).filter(E=>/\.(wav|mp3|ogg)$/i.test(E)).sort()}catch{}l="yes";let k=N.includes("noti_1.wav")?"noti_1.wav":N[0]||"none";async function ie(E){let b=await p.text({message:"Enter absolute path to a .wav file",placeholder:E||"/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(p.isCancel(b))return null;try{await Z.access(String(b))}catch{return p.log.warn("File not found. Try again."),await ie(String(b))}return String(b)}let F=await p.select({message:"Notification sound",options:oe(k),initialValue:k});if(p.isCancel(F))return p.cancel("Install aborted");if(F==="skip")l="no",u=void 0;else if(F==="custom"){let E=await ie();if(E===null)return p.cancel("Install aborted");k=E}else k=F;if(F!=="skip"){for(;;){let E=await p.select({message:`Selected: ${k}. 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(p.isCancel(E))return p.cancel("Install aborted");if(E==="use")break;if(E==="change"){let b=await p.select({message:"Notification sound",options:oe(k),initialValue:k});if(p.isCancel(b))return p.cancel("Install aborted");if(b==="custom"){let _=await ie();if(_===null)return p.cancel("Install aborted");k=_}else if(b==="skip"){l="no",u=void 0;break}else k=b;continue}try{let b=k==="none"?"none":k.startsWith("/")?k:T(Q,"sounds",k);await vt(b)}catch(b){p.log.warn(String(b))}}u===void 0&&(u=k)}}if(s){let g=await p.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(p.isCancel(g))return p.cancel("Install aborted");f=g}else f="skip"}a||(typeof l>"u"&&(l=o?"no":"yes"),typeof f>"u"&&(f="skip"));let I={profilesAction:y,reasoning:v,notify:l??(o?"no":"yes"),globalAgents:f??"skip",notificationSound:u,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(a){let g=p.spinner();g.start("Installing prerequisites and writing config");try{await fe(I,Q),g.stop("Base install complete"),p.outro("Install finished")}catch(N){throw g.stop("Installation failed"),p.cancel(`Installation failed: ${N}`),N}await Oe();return}try{await fe(I,Q),await Oe()}catch(g){throw p.cancel(`Installation failed: ${g}`),g}}});async function Oe(){let e=B.homedir(),t=T(e,".codex","config.toml"),n,i=[];try{let c=await Z.readFile(t,"utf8"),$=Ge.parse(c);n=$.profile;let w=$.profiles||{};i=Object.keys(w)}catch{}let o=["codex","ast-grep","fd","rg","fzf","jq","yq","difft","difftastic"],s=(await Promise.all(o.map(async c=>{try{return await O(c),[c,!0]}catch{return[c,!1]}}))).filter(([,c])=>c).map(([c])=>c),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(`
35
35
  `)+`
36
- `)}async function vt(e){if(e.endsWith("/none")||e==="none")return;let t=[async n=>{await O("afplay"),await z`afplay ${n}`},async n=>{await O("paplay"),await z`paplay ${n}`},async n=>{await O("aplay"),await z`aplay ${n}`},async n=>{await O("mpg123"),await z`mpg123 -q ${n}`},async n=>{await O("ffplay"),await z`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 ce(e){try{return await Z.access(e),!0}catch{return!1}}function Ct(e){if(e==null)return;let t=String(e).toLowerCase();if(t==="add"||t==="overwrite"||t==="skip")return t;if(t==="no")return"skip";throw new Error("Invalid --profiles value (use add|overwrite|skip|no).")}function St(e){if(e==null)return;let t=String(e).toLowerCase();if(["on","true","yes"].includes(t))return"on";if(["off","false","no"].includes(t))return"off";throw new Error("Invalid --reasoning value (use on|off).")}import{defineCommand as Et}from"citty";import{promises as V}from"fs";import{accessSync as Rt}from"fs";import{resolve as H,dirname as Ue}from"path";import{fileURLToPath as Nt}from"url";var Le=Ue(Nt(import.meta.url));function Pt(){let e=Le;for(let t=0;t<6;t++){try{return Rt(H(e,"templates","codex-config.toml")),e}catch{}e=H(e,"..")}return H(Le,"..")}var Tt=Pt();async function de(e){try{return await V.access(e),!0}catch{return!1}}async function Dt(e,t){if(await de(t)){let i=`${t}.backup.${new Date().toISOString().replace(/[:.]/g,"").replace("T","_").slice(0,15)}`;await V.copyFile(t,i)}await V.mkdir(Ue(t),{recursive:!0}),await V.copyFile(e,t)}var qe=Et({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=H(Tt,"templates/agent-templates","AGENTS-default.md"),o=await de(t).then(async r=>r&&(await V.stat(t)).isDirectory()).catch(()=>!1)?H(t,"AGENTS.md"):t;if(!await de(n))throw new Error(`Template not found: ${n}`);await Dt(n,o),process.stdout.write(`Wrote ${o}
37
- `)}});import{defineCommand as It}from"citty";import{$ as At}from"zx";import{fileURLToPath as _t}from"url";import{accessSync as xt}from"fs";import{dirname as jt,resolve as ee}from"path";var We=jt(_t(import.meta.url));function Ot(){let e=We;for(let t=0;t<6;t++){try{return xt(ee(e,"templates","codex-config.toml")),e}catch{}e=ee(e,"..")}return ee(We,"..")}var Gt=Ot(),Me=It({meta:{name:"doctor",description:"Run environment checks"},async run(){await At`bash ${ee(Gt,"scripts/doctor.sh")}`}});import{defineCommand as Ft}from"citty";import{$ as Lt}from"zx";import{fileURLToPath as Ut}from"url";import{accessSync as qt}from"fs";import{dirname as Wt,resolve as te}from"path";var ze=Wt(Ut(import.meta.url));function Mt(){let e=ze;for(let t=0;t<6;t++){try{return qt(te(e,"templates","codex-config.toml")),e}catch{}e=te(e,"..")}return te(ze,"..")}var zt=Mt(),Be=Ft({meta:{name:"uninstall",description:"Clean up aliases and config created by this tool"},async run(){await Lt`bash ${te(zt,"scripts/uninstall.sh")}`}});import{defineCommand as ne}from"citty";import{promises as K}from"fs";import{resolve as G,dirname as Xe}from"path";import{fileURLToPath as Bt}from"url";import{accessSync as Vt}from"fs";import Ht from"os";var Ve=Xe(Bt(import.meta.url));function Kt(){let e=Ve;for(let t=0;t<6;t++){try{return Vt(G(e,"templates","codex-config.toml")),e}catch{}e=G(e,"..")}return G(Ve,"..")}var Xt=Kt();function ue(){let e=G(Ht.homedir(),".codex"),t=G(e,"config.toml");return{CODEX_HOME:e,CFG:t}}async function ge(e){return K.readFile(e,"utf8")}async function He(e,t){await K.mkdir(Xe(e),{recursive:!0}),await K.writeFile(e,t,"utf8")}function Ke(e){let t=/^\[profiles\.(.+?)\]/gm,n=[],i;for(;i=t.exec(e);)n.push(i[1]);return n}function Jt(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(`
36
+ `)}async function vt(e){if(e.endsWith("/none")||e==="none")return;let t=[async n=>{await O("afplay"),await z`afplay ${n}`},async n=>{await O("paplay"),await z`paplay ${n}`},async n=>{await O("aplay"),await z`aplay ${n}`},async n=>{await O("mpg123"),await z`mpg123 -q ${n}`},async n=>{await O("ffplay"),await z`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 ce(e){try{return await Z.access(e),!0}catch{return!1}}function St(e){if(e==null)return;let t=String(e).toLowerCase();if(t==="add"||t==="overwrite"||t==="skip")return t;if(t==="no")return"skip";throw new Error("Invalid --profiles value (use add|overwrite|skip|no).")}function Ct(e){if(e==null)return;let t=String(e).toLowerCase();if(["on","true","yes"].includes(t))return"on";if(["off","false","no"].includes(t))return"off";throw new Error("Invalid --reasoning value (use on|off).")}import{defineCommand as Et}from"citty";import{promises as V}from"fs";import{accessSync as Rt}from"fs";import{resolve as H,dirname as Ue}from"path";import{fileURLToPath as Nt}from"url";var Le=Ue(Nt(import.meta.url));function Pt(){let e=Le;for(let t=0;t<6;t++){try{return Rt(H(e,"templates","codex-config.toml")),e}catch{}e=H(e,"..")}return H(Le,"..")}var Tt=Pt();async function de(e){try{return await V.access(e),!0}catch{return!1}}async function Dt(e,t){if(await de(t)){let i=`${t}.backup.${new Date().toISOString().replace(/[:.]/g,"").replace("T","_").slice(0,15)}`;await V.copyFile(t,i)}await V.mkdir(Ue(t),{recursive:!0}),await V.copyFile(e,t)}var qe=Et({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=H(Tt,"templates/agent-templates","AGENTS-default.md"),o=await de(t).then(async r=>r&&(await V.stat(t)).isDirectory()).catch(()=>!1)?H(t,"AGENTS.md"):t;if(!await de(n))throw new Error(`Template not found: ${n}`);await Dt(n,o),process.stdout.write(`Wrote ${o}
37
+ `)}});import{defineCommand as It}from"citty";import{$ as At}from"zx";import{fileURLToPath as _t}from"url";import{accessSync as xt}from"fs";import{dirname as jt,resolve as ee}from"path";var We=jt(_t(import.meta.url));function Ot(){let e=We;for(let t=0;t<6;t++){try{return xt(ee(e,"templates","codex-config.toml")),e}catch{}e=ee(e,"..")}return ee(We,"..")}var Gt=Ot(),Me=It({meta:{name:"doctor",description:"Run environment checks"},async run(){await At`bash ${ee(Gt,"scripts/doctor.sh")}`}});import{defineCommand as Ft}from"citty";import{$ as Lt}from"zx";import{fileURLToPath as Ut}from"url";import{accessSync as qt}from"fs";import{dirname as Wt,resolve as te}from"path";var ze=Wt(Ut(import.meta.url));function Mt(){let e=ze;for(let t=0;t<6;t++){try{return qt(te(e,"templates","codex-config.toml")),e}catch{}e=te(e,"..")}return te(ze,"..")}var zt=Mt(),Be=Ft({meta:{name:"uninstall",description:"Clean up aliases and config created by this tool"},async run(){await Lt`bash ${te(zt,"scripts/uninstall.sh")}`}});import{defineCommand as ne}from"citty";import{promises as K}from"fs";import{resolve as G,dirname as Je}from"path";import{fileURLToPath as Bt}from"url";import{accessSync as Vt}from"fs";import Ht from"os";var Ve=Je(Bt(import.meta.url));function Kt(){let e=Ve;for(let t=0;t<6;t++){try{return Vt(G(e,"templates","codex-config.toml")),e}catch{}e=G(e,"..")}return G(Ve,"..")}var Jt=Kt();function ue(){let e=G(Ht.homedir(),".codex"),t=G(e,"config.toml");return{CODEX_HOME:e,CFG:t}}async function ge(e){return K.readFile(e,"utf8")}async function He(e,t){await K.mkdir(Je(e),{recursive:!0}),await K.writeFile(e,t,"utf8")}function Ke(e){let t=/^\[profiles\.(.+?)\]/gm,n=[],i;for(;i=t.exec(e);)n.push(i[1]);return n}function Xt(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(`
38
38
  `);return i===-1?n+`
39
39
  `+e:e.slice(0,i+1)+n+`
40
- `+e.slice(i+1)}var Je=ne({meta:{name:"config",description:"Manage Codex config profiles"},subCommands:{init:ne({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=G(Xt,"templates/codex-config.toml"),n=await ge(t),{CFG:i}=ue(),o=await K.access(i).then(()=>!0).catch(()=>!1);if(o&&!e.force){process.stdout.write(`${i} exists. Use --force to overwrite.
40
+ `+e.slice(i+1)}var Xe=ne({meta:{name:"config",description:"Manage Codex config profiles"},subCommands:{init:ne({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=G(Jt,"templates/codex-config.toml"),n=await ge(t),{CFG:i}=ue(),o=await K.access(i).then(()=>!0).catch(()=>!1);if(o&&!e.force){process.stdout.write(`${i} exists. Use --force to overwrite.
41
41
  `);return}if(o){let r=`${i}.backup.${Date.now()}`;await K.copyFile(i,r),process.stdout.write(`Backed up to ${r}
42
42
  `)}await He(i,n),process.stdout.write(`Wrote ${i}
43
43
  `)}}),profiles:ne({meta:{name:"profiles",description:"List profiles in the current config"},async run(){let{CFG:e}=ue(),t=await ge(e),n=Ke(t);process.stdout.write(n.length?n.join(`
44
44
  `)+`
45
45
  `:`No profiles found
46
- `)}}),"set-profile":ne({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}=ue(),n=await ge(t),i=Ke(n),o=String(e.name);if(!i.includes(o))throw new Error(`Unknown profile: ${o}`);let r=Jt(n,o);await He(t,r),process.stdout.write(`profile set to ${o}
47
- `)}})}});var Ye=Yt({meta:{name:"codex-1up",version:"0.1.0",description:"Power up Codex CLI with clean profiles config and helpers"},subCommands:{install:Fe,agents:qe,doctor:Me,uninstall:Be,config:Je}});Qt(Ye);
46
+ `)}}),"set-profile":ne({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}=ue(),n=await ge(t),i=Ke(n),o=String(e.name);if(!i.includes(o))throw new Error(`Unknown profile: ${o}`);let r=Xt(n,o);await He(t,r),process.stdout.write(`profile set to ${o}
47
+ `)}})}});var nn=en(Zt(import.meta.url)),on=JSON.parse(Qt(tn(nn,"../package.json"),"utf-8")),Ye=Yt({meta:{name:"codex-1up",version:on.version,description:"Power up Codex CLI with clean profiles config and helpers"},subCommands:{install:Fe,agents:qe,doctor:Me,uninstall:Be,config:Xe}});rn(Ye);
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.0",
5
+ "version": "0.2.1",
6
6
  "description": "TypeScript CLI for codex-1up (citty-based)",
7
7
  "bin": {
8
8
  "codex-1up": "bin/codex-1up.mjs"