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