codex-1up 0.3.9 → 0.3.10
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 +2 -2
- package/dist/main.js +37 -36
- package/package.json +1 -1
- package/templates/agent-templates/AGENTS-default.md +36 -19
- package/templates/codex-config.toml +2 -2
package/README.md
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
**Codex 1UP** equips your Codex CLI coding agent with powerful tools.
|
|
7
7
|
|
|
8
8
|
- ✅ Installs/updates **Codex CLI** (`@openai/codex`)
|
|
9
|
-
- ✅ Adds fast shell power tools: `rg`, `fd`, `fzf`, `jq`, `yq`, `ast-grep`, `bat`, `git`, `git-delta`, `gh`
|
|
9
|
+
- ✅ Adds fast shell power tools: `rg`, `fd`, `fzf`, `jq`, `yq`, `ast-grep`, `bat`, `git`, `git-delta`, `gh` (GitHub CLI)
|
|
10
10
|
- ✅ **AGENTS.md** template with tool selection guide
|
|
11
11
|
- ✅ Unified **Codex config** with multiple profiles: `balanced` / `safe` / `yolo`
|
|
12
12
|
- ✅ 🔊 **Notification sounds** with customizable audio alerts for Codex events
|
|
@@ -53,7 +53,7 @@ codex-1up install
|
|
|
53
53
|
| **bat** | Better `cat` with syntax highlighting. |
|
|
54
54
|
| **git** | Version control CLI (required for many workflows). |
|
|
55
55
|
| **git-delta** | Better `git diff` output formatting. |
|
|
56
|
-
| **gh** | GitHub CLI for repo and PR workflows.
|
|
56
|
+
| **gh** | GitHub CLI for repo and PR workflows (installed/updated by `codex-1up` in the tools step). |
|
|
57
57
|
| **\~/.codex/config.toml** | Single template with multiple profiles. Active profile is chosen during install (default: `balanced`). See [Codex config reference](https://github.com/openai/codex/blob/main/docs/config.md). |
|
|
58
58
|
| **AGENTS.md** | Minimal per‑repo rubric; installer can also create global `~/.codex/AGENTS.md`. |
|
|
59
59
|
| **\~/.codex/skills** | Optional bundled Agent Skills (portable folders with `SKILL.md` + scripts/references). |
|
package/dist/main.js
CHANGED
|
@@ -1,76 +1,77 @@
|
|
|
1
|
-
import{runMain as
|
|
1
|
+
import{runMain as Fn}from"citty";import{defineCommand as Mn}from"citty";import{defineCommand as gn}from"citty";import{resolve as ut}from"path";import{promises as Zt}from"fs";import*as Be from"os";import*as eo from"toml";import*as F from"@clack/prompts";import Yo from"os";import{resolve as Jo}from"path";import{promises as Xo}from"fs";import*as Ut from"toml";import Ot from"fs-extra";import*as tt from"path";import*as Mt from"os";import{createWriteStream as go}from"fs";function Se(e){let t=null;try{t=go(e,{flags:"a",mode:384})}catch(n){}let o=(n,i)=>{let s=n?`${n} ${i}
|
|
2
2
|
`:`${i}
|
|
3
|
-
`;process.stdout.write(s),t&&t.write(s)};return{log:n=>o("",n),info:n=>o("",n),ok:n=>o("\u2714",n),warn:n=>o("\u26A0",n),err:n=>o("\u2716",n)}}import{$ as ee}from"zx";import{which as uo,$ as mo}from"zx";import{spawn as go}from"child_process";async function $(e){try{return await uo(e),!0}catch{return!1}}async function yt(){return await $("brew")?"brew":await $("apt-get")?"apt":await $("dnf")?"dnf":await $("pacman")?"pacman":await $("zypper")?"zypper":"none"}function pe(e){return typeof process.getuid=="function"&&process.getuid()===0?{cmd:e,argsPrefix:[]}:{cmd:"sudo",argsPrefix:[e]}}async function bt(e){if(await $("pnpm"))try{let o=(await mo`pnpm bin -g`.quiet()).stdout.trim();return o?{pm:"pnpm",binDir:o}:(e?.warn('Detected pnpm but global bin dir is not configured; skipping global Node installs to avoid duplicates. Run "pnpm setup" then re-run.'),{pm:"none",reason:"pnpm-misconfigured"})}catch{return e?.warn('Detected pnpm but global bin dir is not configured; skipping global Node installs to avoid duplicates. Run "pnpm setup" then re-run.'),{pm:"none",reason:"pnpm-error"}}return await $("npm")?{pm:"npm",reason:"npm-default"}:{pm:"none",reason:"not-found"}}async function I(e,t,o={dryRun:!1}){if(o.dryRun){let i=[e,...t].map(s=>s.includes(" ")?`"${s}"`:s).join(" ");o.logger?.log(`[dry-run] ${i}`);return}let n=go(e,t,{stdio:"inherit",cwd:o.cwd||process.cwd(),shell:!1});await new Promise((i,s)=>{n.on("error",s),n.on("exit",r=>{if(r===0)return i();s(new Error(`Command failed (${r}): ${e} ${t.join(" ")}`))})})}function O(e){let t=new Date().toISOString().replace(/[:.]/g,"-").slice(0,-5);return`${e}.backup.${t}`}import kt from"fs-extra";import*as $e from"path";import*as de from"os";import*as te from"@clack/prompts";async function vt(e){let t=await $("node"),o=await $("npm");if(t&&o){let i=(await ee`node -v`).stdout.trim();e.logger.ok(`Node.js present (${i})`);return}switch(e.options.installNode){case"nvm":await wo(e);break;case"brew":await ho(e);break;case"skip":e.logger.warn("Skipping Node installation; please install Node 18+ manually");return}if(await $("node")){let i=(await ee`node -v`).stdout.trim();e.logger.ok(`Node.js installed (${i})`)}else throw e.logger.err("Node installation failed"),new Error("Node.js installation failed")}async function wo(e){if(e.logger.info("Installing Node.js via nvm"),e.options.dryRun){e.logger.log("[dry-run] install nvm + Node LTS");return}let t=process.stdout.isTTY&&!e.options.dryRun&&!e.options.skipConfirmation&&!e.options.assumeYes,o=$e.join(e.homeDir,".nvm");if(!await kt.pathExists(o)){if(t){let i=await te.confirm({message:"This will download and run the nvm installer script (from GitHub) and then install Node LTS. Continue?",initialValue:!0});if(te.isCancel(i)||!i)throw new Error("Node installation aborted by user")}e.logger.info("Installing nvm..."),await ee`bash -c "curl -fsSL https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash"`}let n=`export NVM_DIR="${o}" && [ -s "$NVM_DIR/nvm.sh" ] && . "$NVM_DIR/nvm.sh" && nvm install --lts`;await ee`bash -c ${n}`}async function ho(e){e.logger.info("Installing Node.js via Homebrew");let t=process.stdout.isTTY&&!e.options.dryRun&&!e.options.skipConfirmation&&!e.options.assumeYes;if(!await $("brew"))if(de.platform()==="darwin"){if(e.logger.info("Homebrew not found; installing Homebrew"),e.options.dryRun){e.logger.log("[dry-run] install Homebrew");return}if(t){let n=await te.confirm({message:"This will download and run the official Homebrew installer script (from GitHub). Continue?",initialValue:!0});if(te.isCancel(n)||!n)throw new Error("Homebrew installation aborted by user")}await ee`/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"`;let o=de.platform()==="darwin"&&de.arch()==="arm64"?"/opt/homebrew/bin/brew":"/usr/local/bin/brew";if(await kt.pathExists(o)){let n=$e.dirname(o);process.env.PATH=`${n}:${process.env.PATH||""}`;try{let s=(await ee`${o} shellenv`).stdout.trim().match(/export PATH="([^"]+)"/);s&&(process.env.PATH=`${s[1]}:${process.env.PATH||""}`)}catch(i){}}}else throw new Error("Homebrew is only available on macOS");await I("brew",["install","node"],{dryRun:e.options.dryRun,logger:e.logger})}import*as oe from"@clack/prompts";import{$ as Ve}from"zx";var Ke="@openai/codex";async function xe(e){let t=await bo(),o=await yo(e),n=!!(t.found&&t.version&&o&&t.version!==o);return{found:t.found,version:t.version,latest:o,updateAvailable:n}}async function yo(e){try{let o=(await Ve`npm view ${Ke} version`.quiet()).stdout.trim();if(!o){e?.warn("Could not fetch latest Codex CLI version; skipping upgrade check");return}return o}catch(t){e?.warn(`Error checking latest Codex CLI version: ${t}`);return}}async function bo(){if(!await $("codex"))return{found:!1};let t="";try{let o=await Ve`codex --version`.quiet().nothrow();t=ko(o.stdout||"")}catch(o){}if(!t)try{let o=await Ve`npm ls -g ${Ke} --depth=0 --json`.quiet().nothrow();t=JSON.parse(o.stdout||"{}").dependencies?.[Ke]?.version||""}catch(o){}return{found:!0,version:t||void 0}}function ko(e){let t=e.match(/(\d+\.\d+\.\d+(?:[-+][0-9A-Za-z.-]+)?)/);return t?t[1]:""}import*as Ie from"@clack/prompts";async function Te(e){let t=await bt(e.logger);if(t.pm==="pnpm")return"pnpm";if(t.pm==="npm")return"npm";if(t.pm==="none"&&t.reason?.startsWith("pnpm-")){if(e.interactive){let o=await Ie.select({message:"pnpm is installed but its global bin is not configured. How should we proceed?",initialValue:"npm",options:[{value:"npm",label:"Use npm for global installs this run"},{value:"skip",label:'Skip global installs (run "pnpm setup" then re-run)'}]});return Ie.isCancel(o)||o==="skip"?(e.logger?.warn('Skipping global Node installs; pnpm is misconfigured. Run "pnpm setup" then re-run.'),"none"):(e.logger?.info("pnpm misconfigured; falling back to npm for global installs."),"npm")}return e.logger?.warn('pnpm detected but global bin dir is not configured; falling back to npm for this run. Run "pnpm setup" to use pnpm.'),"npm"}return"none"}var Ct="@openai/codex";async function St(e){if(e.options.installCodexCli==="no"){e.logger.info("Skipping Codex CLI install (user choice)");return}let t=process.stdout.isTTY&&!e.options.dryRun&&!e.options.skipConfirmation&&!e.options.assumeYes,o=await xe(e.logger);if(o.found){let a=o.version?`v${o.version}`:"unknown version";e.logger.info(`Found Codex CLI ${a}. Checking for newer version...`)}else e.logger.info("Codex CLI not found.");let n=!1,i=!1;if(o.found)if(o.updateAvailable){let a=o.latest?`v${o.latest}`:"a newer version";if(e.options.installCodexCli==="yes")i=!0;else if(t){let p=await oe.confirm({message:`Codex CLI ${o.version} found; latest is ${a}. Update now?`,initialValue:!0});oe.isCancel(p)?e.logger.info("Codex CLI update cancelled; keeping existing version."):p?i=!0:e.logger.info("Keeping existing Codex CLI version as requested.")}else i=!0}else o.found&&(o.latest&&o.version?e.logger.ok(`Codex CLI up-to-date (${o.version})`):e.logger.ok("Codex CLI found; unable to verify latest version."));else if(e.options.installCodexCli==="yes")n=!0;else if(t){let a=await oe.confirm({message:"Codex CLI not found. Install now?",initialValue:!0});oe.isCancel(a)?e.logger.info("Codex CLI install cancelled."):a?n=!0:e.logger.info("Skipping Codex CLI install.")}else n=!0;let s=[];if((n||i)&&(o.latest?s.push(`${Ct}@${o.latest}`):s.push(Ct)),s.length===0)return;let r=await Te({logger:e.logger,interactive:process.stdout.isTTY&&!e.options.dryRun&&!e.options.skipConfirmation&&!e.options.assumeYes});r==="none"?e.logger.warn("Skipping global Node installs because no supported package manager was found."):r==="pnpm"?(e.logger.info("Installing/updating Codex CLI via pnpm"),await I("pnpm",["add","-g",...s],{dryRun:e.options.dryRun,logger:e.logger})):(e.logger.info("Installing/updating Codex CLI via npm"),await I("npm",["install","-g",...s],{dryRun:e.options.dryRun,logger:e.logger})),await $("codex")?e.logger.ok("Codex CLI installed"):e.logger.err("Codex CLI not found after install")}var $t=[{id:"rg",label:"rg",bins:["rg"],packages:{brew:["ripgrep"],apt:["ripgrep"],dnf:["ripgrep"],pacman:["ripgrep"],zypper:["ripgrep"]}},{id:"fd",label:"fd",bins:["fd","fdfind"],packages:{brew:["fd"],apt:["fd-find"],dnf:["fd-find"],pacman:["fd"],zypper:["fd"]}},{id:"fzf",label:"fzf",bins:["fzf"],packages:{brew:["fzf"],apt:["fzf"],dnf:["fzf"],pacman:["fzf"],zypper:["fzf"]}},{id:"jq",label:"jq",bins:["jq"],packages:{brew:["jq"],apt:["jq"],dnf:["jq"],pacman:["jq"],zypper:["jq"]}},{id:"yq",label:"yq",bins:["yq"],packages:{brew:["yq"],apt:["yq"],dnf:["yq"],pacman:["yq"],zypper:["yq"]}},{id:"ast-grep",label:"ast-grep",bins:["ast-grep","sg"],packages:{brew:["ast-grep"],apt:["ast-grep"],dnf:["ast-grep"],pacman:["ast-grep"],zypper:["ast-grep"]}},{id:"bat",label:"bat",bins:["bat","batcat"],packages:{brew:["bat"],apt:["bat"],dnf:["bat"],pacman:["bat"],zypper:["bat"]}},{id:"git",label:"git",bins:["git"],packages:{brew:["git"],apt:["git"],dnf:["git"],pacman:["git"],zypper:["git"]}},{id:"git-delta",label:"git-delta",bins:["delta"],packages:{brew:["git-delta"],apt:["git-delta"],dnf:["git-delta"],pacman:["git-delta"],zypper:["git-delta"]}},{id:"gh",label:"gh",bins:["gh"],packages:{brew:["gh"],apt:["gh"],dnf:["gh"],pacman:["github-cli"],zypper:["gh"]}}],vo=new Set($t.map(e=>e.id));function xt(e){return vo.has(e)}function ne(){return $t}import*as He from"path";import Ye from"fs-extra";import{which as Co}from"zx";async function Pe(e){if(e.options.installTools==="skip"){e.logger.info("Skipping developer tool installs (user choice)");return}let t=So(e.options.installTools,e.options.toolsSelected);if(t.length===0){e.logger.info("Skipping developer tool installs (no tools selected)");return}let o=await yt();if(e.logger.info(`Detected package manager: ${o}`),o==="none"){e.logger.warn("Could not detect a supported package manager; please install tools manually");return}let n=ne().filter(s=>t.includes(s.id)),i=$o(n,o);if(i.length>0)switch(o!=="brew"&&(typeof process.getuid=="function"&&process.getuid()===0||e.logger.warn("Package installation may require sudo password. Please enter it when prompted.")),o){case"brew":await I("brew",["update"],{dryRun:e.options.dryRun,logger:e.logger}),await I("brew",["install",...i],{dryRun:e.options.dryRun,logger:e.logger});break;case"apt":{let{cmd:s,argsPrefix:r}=pe("apt-get");e.logger.info("Running apt-get update...");try{await I(s,[...r,"update","-y"],{dryRun:e.options.dryRun,logger:e.logger})}catch{e.logger.warn(`apt-get update failed; install tools manually: ${i.join(", ")}`);break}for(let a of i)try{await I(s,[...r,"install","-y",a],{dryRun:e.options.dryRun,logger:e.logger})}catch{e.logger.warn(`apt-get install failed for ${a}; install manually if needed.`)}}break;case"dnf":{let{cmd:s,argsPrefix:r}=pe("dnf");await I(s,[...r,"install","-y",...i],{dryRun:e.options.dryRun,logger:e.logger}).catch(()=>{})}break;case"pacman":{let{cmd:s,argsPrefix:r}=pe("pacman");await I(s,[...r,"-Sy","--noconfirm",...i],{dryRun:e.options.dryRun,logger:e.logger}).catch(()=>{})}break;case"zypper":{let{cmd:s,argsPrefix:r}=pe("zypper");await I(s,[...r,"refresh"],{dryRun:e.options.dryRun,logger:e.logger}),await I(s,[...r,"install","-y",...i],{dryRun:e.options.dryRun,logger:e.logger}).catch(()=>{})}break}t.includes("fd")&&await It(e,"fdfind","fd"),t.includes("bat")&&await It(e,"batcat","bat"),await xo(e,n)}function So(e,t){return e==="all"?ne().map(o=>o.id):e==="select"?t?[...t]:[]:[]}function $o(e,t){let o=[];for(let n of e){let i=n.packages[t]||[];for(let s of i)o.includes(s)||o.push(s)}return o}async function It(e,t,o){if(!await $(t)||await $(o))return;let n=He.join(e.homeDir,".local","bin");await Ye.ensureDir(n);let i=He.join(n,o);if(await Ye.pathExists(i))return;let s=t;try{s=await Co(t)}catch(r){}if(e.options.dryRun){e.logger.log(`[dry-run] ln -s ${s} ${i}`);return}await Ye.symlink(s,i),e.logger.ok(`${o} alias created at ~/.local/bin/${o}`)}async function xo(e,t){for(let o of t)await Io(o)?e.logger.ok(`${o.id} \u2713`):e.logger.warn(`${o.id} not detected after install`)}async function Io(e){for(let t of e.bins)if(await $(t))return!0;return!1}import ce from"fs-extra";import*as Re from"path";var Tt={balanced:{root:[["approval_policy",'"on-request"'],["sandbox_mode",'"workspace-write"'],["model",'"gpt-5.2-codex"'],["model_reasoning_effort",'"medium"'],["model_reasoning_summary",'"concise"']],features:[["web_search_request","true"]],tables:{sandbox_workspace_write:[["network_access","true"]]}},safe:{root:[["approval_policy",'"on-failure"'],["sandbox_mode",'"read-only"'],["model",'"gpt-5.2-codex"'],["model_reasoning_effort",'"medium"'],["model_reasoning_summary",'"concise"']],features:[["web_search_request","false"]]},yolo:{root:[["approval_policy",'"never"'],["sandbox_mode",'"danger-full-access"'],["model",'"gpt-5.2-codex"'],["model_reasoning_effort",'"high"'],["model_reasoning_summary",'"detailed"']],features:[["web_search_request","true"]]}},To=`# ~/.codex/config.toml \u2014 managed by codex-1up (patch mode)
|
|
4
|
-
|
|
5
|
-
|
|
3
|
+
`;process.stdout.write(s),t&&t.write(s)};return{log:n=>o("",n),info:n=>o("",n),ok:n=>o("\u2714",n),warn:n=>o("\u26A0",n),err:n=>o("\u2716",n)}}import{$ as ee}from"zx";import{which as ho,$ as wo}from"zx";import{spawn as yo}from"child_process";async function S(e){try{return await ho(e),!0}catch{return!1}}async function kt(){return await S("brew")?"brew":await S("apt-get")?"apt":await S("dnf")?"dnf":await S("pacman")?"pacman":await S("zypper")?"zypper":"none"}function de(e){return typeof process.getuid=="function"&&process.getuid()===0?{cmd:e,argsPrefix:[]}:{cmd:"sudo",argsPrefix:[e]}}async function vt(e){if(await S("pnpm"))try{let o=(await wo`pnpm bin -g`.quiet()).stdout.trim();return o?{pm:"pnpm",binDir:o}:(e?.warn('Detected pnpm but global bin dir is not configured; skipping global Node installs to avoid duplicates. Run "pnpm setup" then re-run.'),{pm:"none",reason:"pnpm-misconfigured"})}catch{return e?.warn('Detected pnpm but global bin dir is not configured; skipping global Node installs to avoid duplicates. Run "pnpm setup" then re-run.'),{pm:"none",reason:"pnpm-error"}}return await S("npm")?{pm:"npm",reason:"npm-default"}:{pm:"none",reason:"not-found"}}async function I(e,t,o={dryRun:!1}){if(o.dryRun){let i=[e,...t].map(s=>s.includes(" ")?`"${s}"`:s).join(" ");o.logger?.log(`[dry-run] ${i}`);return}let n=yo(e,t,{stdio:"inherit",cwd:o.cwd||process.cwd(),shell:!1});await new Promise((i,s)=>{n.on("error",s),n.on("exit",r=>{if(r===0)return i();s(new Error(`Command failed (${r}): ${e} ${t.join(" ")}`))})})}function O(e){let t=new Date().toISOString().replace(/[:.]/g,"-").slice(0,-5);return`${e}.backup.${t}`}import Ct from"fs-extra";import*as $e from"path";import*as ce from"os";import*as te from"@clack/prompts";async function St(e){let t=await S("node"),o=await S("npm");if(t&&o){let i=(await ee`node -v`).stdout.trim();e.logger.ok(`Node.js present (${i})`);return}switch(e.options.installNode){case"nvm":await bo(e);break;case"brew":await ko(e);break;case"skip":e.logger.warn("Skipping Node installation; please install Node 18+ manually");return}if(await S("node")){let i=(await ee`node -v`).stdout.trim();e.logger.ok(`Node.js installed (${i})`)}else throw e.logger.err("Node installation failed"),new Error("Node.js installation failed")}async function bo(e){if(e.logger.info("Installing Node.js via nvm"),e.options.dryRun){e.logger.log("[dry-run] install nvm + Node LTS");return}let t=process.stdout.isTTY&&!e.options.dryRun&&!e.options.skipConfirmation&&!e.options.assumeYes,o=$e.join(e.homeDir,".nvm");if(!await Ct.pathExists(o)){if(t){let i=await te.confirm({message:"This will download and run the nvm installer script (from GitHub) and then install Node LTS. Continue?",initialValue:!0});if(te.isCancel(i)||!i)throw new Error("Node installation aborted by user")}e.logger.info("Installing nvm..."),await ee`bash -c "curl -fsSL https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash"`}let n=`export NVM_DIR="${o}" && [ -s "$NVM_DIR/nvm.sh" ] && . "$NVM_DIR/nvm.sh" && nvm install --lts`;await ee`bash -c ${n}`}async function ko(e){e.logger.info("Installing Node.js via Homebrew");let t=process.stdout.isTTY&&!e.options.dryRun&&!e.options.skipConfirmation&&!e.options.assumeYes;if(!await S("brew"))if(ce.platform()==="darwin"){if(e.logger.info("Homebrew not found; installing Homebrew"),e.options.dryRun){e.logger.log("[dry-run] install Homebrew");return}if(t){let n=await te.confirm({message:"This will download and run the official Homebrew installer script (from GitHub). Continue?",initialValue:!0});if(te.isCancel(n)||!n)throw new Error("Homebrew installation aborted by user")}await ee`/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"`;let o=ce.platform()==="darwin"&&ce.arch()==="arm64"?"/opt/homebrew/bin/brew":"/usr/local/bin/brew";if(await Ct.pathExists(o)){let n=$e.dirname(o);process.env.PATH=`${n}:${process.env.PATH||""}`;try{let s=(await ee`${o} shellenv`).stdout.trim().match(/export PATH="([^"]+)"/);s&&(process.env.PATH=`${s[1]}:${process.env.PATH||""}`)}catch(i){}}}else throw new Error("Homebrew is only available on macOS");await I("brew",["install","node"],{dryRun:e.options.dryRun,logger:e.logger})}import*as oe from"@clack/prompts";import{$ as Ke}from"zx";var He="@openai/codex";async function xe(e){let t=await Co(),o=await vo(e),n=!!(t.found&&t.version&&o&&t.version!==o);return{found:t.found,version:t.version,latest:o,updateAvailable:n}}async function vo(e){try{let o=(await Ke`npm view ${He} version`.quiet()).stdout.trim();if(!o){e?.warn("Could not fetch latest Codex CLI version; skipping upgrade check");return}return o}catch(t){e?.warn(`Error checking latest Codex CLI version: ${t}`);return}}async function Co(){if(!await S("codex"))return{found:!1};let t="";try{let o=await Ke`codex --version`.quiet().nothrow();t=So(o.stdout||"")}catch(o){}if(!t)try{let o=await Ke`npm ls -g ${He} --depth=0 --json`.quiet().nothrow();t=JSON.parse(o.stdout||"{}").dependencies?.[He]?.version||""}catch(o){}return{found:!0,version:t||void 0}}function So(e){let t=e.match(/(\d+\.\d+\.\d+(?:[-+][0-9A-Za-z.-]+)?)/);return t?t[1]:""}import*as Ie from"@clack/prompts";async function Te(e){let t=await vt(e.logger);if(t.pm==="pnpm")return"pnpm";if(t.pm==="npm")return"npm";if(t.pm==="none"&&t.reason?.startsWith("pnpm-")){if(e.interactive){let o=await Ie.select({message:"pnpm is installed but its global bin is not configured. How should we proceed?",initialValue:"npm",options:[{value:"npm",label:"Use npm for global installs this run"},{value:"skip",label:'Skip global installs (run "pnpm setup" then re-run)'}]});return Ie.isCancel(o)||o==="skip"?(e.logger?.warn('Skipping global Node installs; pnpm is misconfigured. Run "pnpm setup" then re-run.'),"none"):(e.logger?.info("pnpm misconfigured; falling back to npm for global installs."),"npm")}return e.logger?.warn('pnpm detected but global bin dir is not configured; falling back to npm for this run. Run "pnpm setup" to use pnpm.'),"npm"}return"none"}var $t="@openai/codex";async function xt(e){if(e.options.installCodexCli==="no"){e.logger.info("Skipping Codex CLI install (user choice)");return}let t=process.stdout.isTTY&&!e.options.dryRun&&!e.options.skipConfirmation&&!e.options.assumeYes,o=await xe(e.logger);if(o.found){let a=o.version?`v${o.version}`:"unknown version";e.logger.info(`Found Codex CLI ${a}. Checking for newer version...`)}else e.logger.info("Codex CLI not found.");let n=!1,i=!1;if(o.found)if(o.updateAvailable){let a=o.latest?`v${o.latest}`:"a newer version";if(e.options.installCodexCli==="yes")i=!0;else if(t){let p=await oe.confirm({message:`Codex CLI ${o.version} found; latest is ${a}. Update now?`,initialValue:!0});oe.isCancel(p)?e.logger.info("Codex CLI update cancelled; keeping existing version."):p?i=!0:e.logger.info("Keeping existing Codex CLI version as requested.")}else i=!0}else o.found&&(o.latest&&o.version?e.logger.ok(`Codex CLI up-to-date (${o.version})`):e.logger.ok("Codex CLI found; unable to verify latest version."));else if(e.options.installCodexCli==="yes")n=!0;else if(t){let a=await oe.confirm({message:"Codex CLI not found. Install now?",initialValue:!0});oe.isCancel(a)?e.logger.info("Codex CLI install cancelled."):a?n=!0:e.logger.info("Skipping Codex CLI install.")}else n=!0;let s=[];if((n||i)&&(o.latest?s.push(`${$t}@${o.latest}`):s.push($t)),s.length===0)return;let r=await Te({logger:e.logger,interactive:process.stdout.isTTY&&!e.options.dryRun&&!e.options.skipConfirmation&&!e.options.assumeYes});r==="none"?e.logger.warn("Skipping global Node installs because no supported package manager was found."):r==="pnpm"?(e.logger.info("Installing/updating Codex CLI via pnpm"),await I("pnpm",["add","-g",...s],{dryRun:e.options.dryRun,logger:e.logger})):(e.logger.info("Installing/updating Codex CLI via npm"),await I("npm",["install","-g",...s],{dryRun:e.options.dryRun,logger:e.logger})),await S("codex")?e.logger.ok("Codex CLI installed"):e.logger.err("Codex CLI not found after install")}var It=[{id:"rg",label:"rg",bins:["rg"],packages:{brew:["ripgrep"],apt:["ripgrep"],dnf:["ripgrep"],pacman:["ripgrep"],zypper:["ripgrep"]}},{id:"fd",label:"fd",bins:["fd","fdfind"],packages:{brew:["fd"],apt:["fd-find"],dnf:["fd-find"],pacman:["fd"],zypper:["fd"]}},{id:"fzf",label:"fzf",bins:["fzf"],packages:{brew:["fzf"],apt:["fzf"],dnf:["fzf"],pacman:["fzf"],zypper:["fzf"]}},{id:"jq",label:"jq",bins:["jq"],packages:{brew:["jq"],apt:["jq"],dnf:["jq"],pacman:["jq"],zypper:["jq"]}},{id:"yq",label:"yq",bins:["yq"],packages:{brew:["yq"],apt:["yq"],dnf:["yq"],pacman:["yq"],zypper:["yq"]}},{id:"ast-grep",label:"ast-grep",bins:["ast-grep","sg"],packages:{brew:["ast-grep"],apt:["ast-grep"],dnf:["ast-grep"],pacman:["ast-grep"],zypper:["ast-grep"]}},{id:"bat",label:"bat",bins:["bat","batcat"],packages:{brew:["bat"],apt:["bat"],dnf:["bat"],pacman:["bat"],zypper:["bat"]}},{id:"git",label:"git",bins:["git"],packages:{brew:["git"],apt:["git"],dnf:["git"],pacman:["git"],zypper:["git"]}},{id:"git-delta",label:"git-delta",bins:["delta"],packages:{brew:["git-delta"],apt:["git-delta"],dnf:["git-delta"],pacman:["git-delta"],zypper:["git-delta"]}},{id:"gh",label:"gh",bins:["gh"],packages:{brew:["gh"],apt:["gh"],dnf:["gh"],pacman:["github-cli"],zypper:["gh"]}}],$o=new Set(It.map(e=>e.id));function Tt(e){return $o.has(e)}function ne(){return It}import*as Je from"path";import Ye from"fs-extra";import{which as xo}from"zx";async function Pe(e){if(e.options.installTools==="skip"){e.logger.info("Skipping developer tool installs (user choice)");return}let t=Io(e.options.installTools,e.options.toolsSelected);if(t.length===0){e.logger.info("Skipping developer tool installs (no tools selected)");return}let o=await kt();if(e.logger.info(`Detected package manager: ${o}`),o==="none"){e.logger.warn("Could not detect a supported package manager; please install tools manually");return}let n=ne().filter(s=>t.includes(s.id)),i=To(n,o);if(i.length>0)switch(o!=="brew"&&(typeof process.getuid=="function"&&process.getuid()===0||e.logger.warn("Package installation may require sudo password. Please enter it when prompted.")),o){case"brew":await I("brew",["update"],{dryRun:e.options.dryRun,logger:e.logger}),await I("brew",["install",...i],{dryRun:e.options.dryRun,logger:e.logger});break;case"apt":{t.includes("gh")&&!await S("gh")&&await Ao(e);let{cmd:s,argsPrefix:r}=de("apt-get");e.logger.info("Running apt-get update...");try{await I(s,[...r,"update","-y"],{dryRun:e.options.dryRun,logger:e.logger})}catch{e.logger.warn(`apt-get update failed; install tools manually: ${i.join(", ")}`);break}for(let a of i)try{await I(s,[...r,"install","-y",a],{dryRun:e.options.dryRun,logger:e.logger})}catch{e.logger.warn(`apt-get install failed for ${a}; install manually if needed.`)}}break;case"dnf":{let{cmd:s,argsPrefix:r}=de("dnf");await I(s,[...r,"install","-y",...i],{dryRun:e.options.dryRun,logger:e.logger}).catch(()=>{})}break;case"pacman":{let{cmd:s,argsPrefix:r}=de("pacman");await I(s,[...r,"-Sy","--noconfirm",...i],{dryRun:e.options.dryRun,logger:e.logger}).catch(()=>{})}break;case"zypper":{let{cmd:s,argsPrefix:r}=de("zypper");await I(s,[...r,"refresh"],{dryRun:e.options.dryRun,logger:e.logger}),await I(s,[...r,"install","-y",...i],{dryRun:e.options.dryRun,logger:e.logger}).catch(()=>{})}break}t.includes("fd")&&await Pt(e,"fdfind","fd"),t.includes("bat")&&await Pt(e,"batcat","bat"),await Po(e,n)}function Io(e,t){return e==="all"?ne().map(o=>o.id):e==="select"?t?[...t]:[]:[]}function To(e,t){let o=[];for(let n of e){let i=n.packages[t]||[];for(let s of i)o.includes(s)||o.push(s)}return o}async function Pt(e,t,o){if(!await S(t)||await S(o))return;let n=Je.join(e.homeDir,".local","bin");await Ye.ensureDir(n);let i=Je.join(n,o);if(await Ye.pathExists(i))return;let s=t;try{s=await xo(t)}catch(r){}if(e.options.dryRun){e.logger.log(`[dry-run] ln -s ${s} ${i}`);return}await Ye.symlink(s,i),e.logger.ok(`${o} alias created at ~/.local/bin/${o}`)}async function Po(e,t){for(let o of t)await Ro(o)?e.logger.ok(`${o.id} \u2713`):e.logger.warn(`${o.id} not detected after install`)}async function Ro(e){for(let t of e.bins)if(await S(t))return!0;return!1}async function Ao(e){let t=["set -euo pipefail","if [ -f /etc/apt/sources.list.d/github-cli.list ]; then exit 0; fi",'SUDO=""','if [ "$(id -u)" -ne 0 ]; then SUDO="sudo"; fi',"$SUDO mkdir -p -m 755 /etc/apt/keyrings","if command -v curl >/dev/null 2>&1; then"," curl -fsSL https://cli.github.com/packages/githubcli-archive-keyring.gpg | $SUDO tee /etc/apt/keyrings/githubcli-archive-keyring.gpg >/dev/null","elif command -v wget >/dev/null 2>&1; then"," wget -qO- https://cli.github.com/packages/githubcli-archive-keyring.gpg | $SUDO tee /etc/apt/keyrings/githubcli-archive-keyring.gpg >/dev/null","else",' echo "Missing curl/wget; cannot set up GitHub CLI apt repo automatically." 1>&2'," exit 0","fi","$SUDO chmod go+r /etc/apt/keyrings/githubcli-archive-keyring.gpg",'ARCH="$(dpkg --print-architecture)"','echo "deb [arch=${ARCH} signed-by=/etc/apt/keyrings/githubcli-archive-keyring.gpg] https://cli.github.com/packages stable main" | $SUDO tee /etc/apt/sources.list.d/github-cli.list >/dev/null'].join(`
|
|
4
|
+
`);try{await I("bash",["-lc",t],{dryRun:e.options.dryRun,logger:e.logger})}catch{e.logger.warn("Failed to set up GitHub CLI apt repo; will still try apt-get install gh (may fail).")}}import fe from"fs-extra";import*as Ee from"path";var Xe={balanced:{root:[["approval_policy",'"on-request"'],["sandbox_mode",'"workspace-write"'],["model",'"gpt-5.2-codex"'],["model_reasoning_effort",'"medium"'],["model_reasoning_summary",'"detailed"']],features:[["web_search_request","true"]],tables:{sandbox_workspace_write:[["network_access","true"]]}},safe:{root:[["approval_policy",'"on-failure"'],["sandbox_mode",'"read-only"'],["model",'"gpt-5.2-codex"'],["model_reasoning_effort",'"medium"'],["model_reasoning_summary",'"detailed"']],features:[["web_search_request","false"]]},yolo:{root:[["approval_policy",'"never"'],["sandbox_mode",'"danger-full-access"'],["model",'"gpt-5.2-codex"'],["model_reasoning_effort",'"high"'],["model_reasoning_summary",'"detailed"']],features:[["web_search_request","true"]]}},Eo=`# ~/.codex/config.toml \u2014 managed by codex-1up (patch mode)
|
|
5
|
+
`;async function Et(e){let t=Ee.join(e.homeDir,".codex","config.toml");await fe.ensureDir(Ee.dirname(t));let o=await fe.pathExists(t),n=o?await fe.readFile(t,"utf8"):Eo,i=Go(n),s=Mo(i.toml),r=new Qe(s.toml),a=i.changed||s.changed;if(a=No(r,e.options.profileScope,e.options.profile,e.options.profileMode,e.options.profilesSelected)||a,a=Lo(r,e.options.profile,e.options.setDefaultProfile)||a,a=Do(r,e.options.notificationSound)||a,a=_o(r)||a,!a){e.logger.info("Config already up to date; no changes needed.");return}let p=r.content();if(e.options.dryRun){e.logger.log(`[dry-run] write ${t}`),e.logger.log("[dry-run] config content omitted"),e.logger.log(`[dry-run] would write ${p.length} bytes`);return}if(o){let l=O(t);await fe.copy(t,l),e.logger.info(`Backed up current config to ${l}`)}await fe.writeFile(t,p,"utf8"),e.logger.ok("Updated ~/.codex/config.toml with requested settings.")}function No(e,t,o,n,i){let s=[];if(t==="all")s=Object.keys(Xe);else if(t==="selected")s=i||[];else{if(o==="skip")return!1;s=[o]}if(s.length===0)return!1;let r=!1;for(let a of s){let p=Xe[a];if(n==="overwrite"){r=e.replaceTable(`profiles.${a}`,p.root)||r,r=e.replaceTable(`profiles.${a}.features`,p.features)||r;for(let[l,c]of Object.entries(p.tables||{}))r=e.replaceTable(`profiles.${a}.${l}`,c)||r}else{e.ensureTable(`profiles.${a}`);for(let[l,c]of p.root)r=e.setKey(`profiles.${a}`,l,c,{mode:"if-missing"})||r;e.ensureTable(`profiles.${a}.features`);for(let[l,c]of p.features)r=e.setKey(`profiles.${a}.features`,l,c,{mode:"if-missing"})||r;for(let[l,c]of Object.entries(p.tables||{})){e.ensureTable(`profiles.${a}.${l}`);for(let[d,u]of c)r=e.setKey(`profiles.${a}.${l}`,d,u,{mode:"if-missing"})||r}}}return r}function Lo(e,t,o){return!o||t==="skip"?!1:e.setRootKey("profile",`"${t}"`,{mode:"force"})}function Do(e,t){if(!t||t==="none")return!1;e.ensureTable("tui");let o=e.getValue("tui","notifications");if(o){let n=o.trim().toLowerCase();if(n.startsWith("true")||n.startsWith("["))return!1}return e.setKey("tui","notifications","true",{mode:"force"})}var Qe=class{text;constructor(t){this.text=t||""}content(){return Oo(this.text)}ensureTable(t){if(this.hasTable(t))return!1;let o=this.text.length===0?"":Ae(this.text);return this.text=o+`[${t}]
|
|
6
|
+
`,!0}setKey(t,o,n,i){let s=ie(this.text,t);if(!s)return this.ensureTable(t),this.setKey(t,o,n,i);let r=this.text.slice(s.start,s.end),p=new RegExp(`^\\s*${se(o)}\\s*=.*$`,"m").exec(r);if(p){if(i.mode==="if-missing")return!1;let C=this.text,A=s.start+p.index,D=A+p[0].length;return this.text=C.slice(0,A)+`${o} = ${n}`+C.slice(D),this.text!==C}let l=this.text,c=s.end,d=l.slice(0,c),u=l.slice(c),h=d.length>0&&!d.endsWith(`
|
|
6
7
|
`),v=u.length>0&&!u.startsWith(`
|
|
7
|
-
`),k=`${
|
|
8
|
+
`),k=`${h?`
|
|
8
9
|
`:""}${o} = ${n}
|
|
9
10
|
${v?`
|
|
10
|
-
`:""}`;return this.text=d+k+u,this.text!==l}getValue(t,o){let n=ie(this.text,t);if(!n)return;let i=this.text.slice(n.start,n.end),r=new RegExp(`^\\s*${
|
|
11
|
+
`:""}`;return this.text=d+k+u,this.text!==l}getValue(t,o){let n=ie(this.text,t);if(!n)return;let i=this.text.slice(n.start,n.end),r=new RegExp(`^\\s*${se(o)}\\s*=\\s*(.+)$`,"m").exec(i);return r?r[1]:void 0}getRootValue(t){let o=Rt(this.text),n=this.text.slice(o.start,o.end),s=new RegExp(`^\\s*${se(t)}\\s*=\\s*(.+)$`,"m").exec(n);return s?s[1]:void 0}replaceTable(t,o){let n=o.map(([a,p])=>`${a} = ${p}`).join(`
|
|
11
12
|
`),i=`[${t}]
|
|
12
13
|
${n}
|
|
13
14
|
|
|
14
|
-
`,s=this.text,r=ie(this.text,t);if(!r){let a=s.length===0?"":Ae(s);return this.text=a+i,this.text!==s}return this.text=s.slice(0,r.start)+i+s.slice(r.end),this.text!==s}setRootKey(t,o,n){let i=
|
|
15
|
+
`,s=this.text,r=ie(this.text,t);if(!r){let a=s.length===0?"":Ae(s);return this.text=a+i,this.text!==s}return this.text=s.slice(0,r.start)+i+s.slice(r.end),this.text!==s}setRootKey(t,o,n){let i=Rt(this.text),s=this.text.slice(i.start,i.end),a=new RegExp(`^\\s*${se(t)}\\s*=.*$`,"m").exec(s);if(a){if(n.mode==="if-missing")return!1;let v=this.text,k=i.start+a.index,C=k+a[0].length;return this.text=v.slice(0,k)+`${t} = ${o}`+v.slice(C),this.text!==v}let p=this.text,l=i.end,c=l>0&&!p.slice(0,l).endsWith(`
|
|
15
16
|
`),d=p.slice(l),u=d.length>0&&!d.startsWith(`
|
|
16
|
-
`),
|
|
17
|
+
`),h=`${c?`
|
|
17
18
|
`:""}${t} = ${o}
|
|
18
19
|
${u?`
|
|
19
|
-
`:""}`;return this.text=p.slice(0,l)+
|
|
20
|
+
`:""}`;return this.text=p.slice(0,l)+h+d,this.text!==p}hasTable(t){return ie(this.text,t)!==null}};function ie(e,t){let o=/^\s*\[([^\]]+)\]\s*$/gm,n=[],i;for(;i=o.exec(e);)n.push({name:i[1].trim(),index:i.index});for(let s=0;s<n.length;s++)if(n[s].name===t){let r=n[s].index,a=n[s+1]?.index??e.length;return{start:r,end:a}}return null}function Rt(e){let o=/^\s*\[([^\]]+)\]\s*$/gm.exec(e);return o?{start:0,end:o.index}:{start:0,end:e.length}}function se(e){return e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}function jo(e){let t=/^\s*\[profiles\.([^. \]]+)\]\s*$/gm,o=new Set,n;for(;n=t.exec(e);){let i=n[1]?.trim();i&&o.add(i)}return[...o]}function Re(e){if(!e)return;let t=e.trim(),o=/^"([^"]*)"\s*(?:#.*)?$/.exec(t);return o?o[1]:void 0}function At(e){return e?e.endsWith("-codex"):!1}function _o(e){let t=!1,o=Re(e.getRootValue("model"));if(At(o)){let s=Re(e.getRootValue("model_reasoning_summary"));s&&s!=="detailed"&&(t=e.setRootKey("model_reasoning_summary",'"detailed"',{mode:"force"})||t)}let n=e.content(),i=new Set([...Object.keys(Xe),...jo(n)]);for(let s of i){let r=`profiles.${s}`,a=Re(e.getValue(r,"model"));if(!At(a))continue;let p=Re(e.getValue(r,"model_reasoning_summary"));p&&p!=="detailed"&&(t=e.setKey(r,"model_reasoning_summary",'"detailed"',{mode:"force"})||t)}return t}function Oo(e){return e.endsWith(`
|
|
20
21
|
`)?e:e+`
|
|
21
22
|
`}function Ae(e){let t=e;return t.endsWith(`
|
|
22
23
|
`)||(t+=`
|
|
23
24
|
`),t.endsWith(`
|
|
24
25
|
|
|
25
26
|
`)||(t+=`
|
|
26
|
-
`),t}function
|
|
27
|
-
`);if(p!==void 0){let d=ie(c,"features");if(!(()=>{if(!d)return!1;let
|
|
28
|
-
`),
|
|
27
|
+
`),t}function Go(e){let t="enable_experimental_windows_sandbox",o="experimental_windows_sandbox";if(!e.includes(t))return{toml:e,changed:!1};let n=e.split(/\r?\n/),i="",s=d=>d==="features"||/^profiles\.[^.]+\.features$/.test(d),r=new Set;for(let d of n){let u=d.match(/^\s*\[([^\]]+)\]\s*$/);if(u){i=u[1].trim();continue}/^\s*#/.test(d)||s(i)&&new RegExp(`^\\s*${o}\\s*=`).test(d)&&r.add(i)}i="";let a=!1,p,l=[];for(let d of n){let u=d.match(/^\s*\[([^\]]+)\]\s*$/);if(u){i=u[1].trim(),l.push(d);continue}if(!/^\s*#/.test(d)){if(i===""){let h=d.match(new RegExp(`^\\s*${t}\\s*=\\s*(.+?)\\s*$`));if(h){p=h[1],a=!0;continue}}if(s(i)&&new RegExp(`^\\s*${t}\\s*=`).test(d)){if(r.has(i)){a=!0;continue}l.push(d.replace(new RegExp(`^(\\s*)${t}(\\s*=\\s*)`),`$1${o}$2`)),a=!0;continue}}l.push(d)}let c=l.join(`
|
|
28
|
+
`);if(p!==void 0){let d=ie(c,"features");if(!(()=>{if(!d)return!1;let h=c.slice(d.start,d.end);return new RegExp(`^\\s*${o}\\s*=`,"m").test(h)})()){let h=`${o} = ${p}`;if(d){let v=c.slice(0,d.end),k=c.slice(d.end),C=v.length>0&&!v.endsWith(`
|
|
29
|
+
`),A=k.length>0&&!k.startsWith(`
|
|
29
30
|
`);c=v+`${C?`
|
|
30
|
-
`:""}${
|
|
31
|
-
${
|
|
31
|
+
`:""}${h}
|
|
32
|
+
${A?`
|
|
32
33
|
`:""}`+k}else c=(c.length===0?"":Ae(c))+`[features]
|
|
33
|
-
${
|
|
34
|
-
`;a=!0}}return{toml:c,changed:a}}function
|
|
35
|
-
`);if(Object.keys(r).length===0)return{toml:l,changed:p};for(let{newKey:c}of t){let d=r[c];if(d===void 0)continue;let u=ie(l,"features");if((()=>{if(!u)return!1;let k=l.slice(u.start,u.end);return new RegExp(`^\\s*${
|
|
34
|
+
${h}
|
|
35
|
+
`;a=!0}}return{toml:c,changed:a}}function Mo(e){let t=[{oldKey:"experimental_use_exec_command_tool",newKey:"streamable_shell"},{oldKey:"experimental_use_unified_exec_tool",newKey:"unified_exec"},{oldKey:"experimental_use_rmcp_client",newKey:"rmcp_client"},{oldKey:"include_apply_patch_tool",newKey:"apply_patch_freeform"}];if(!t.some(c=>e.includes(c.oldKey)))return{toml:e,changed:!1};function n(c){let d=c.trim(),u=/^(true|false)\b/i.exec(d);return u?u[1].toLowerCase():d||void 0}let i=e.split(/\r?\n/),s="",r={},a=[],p=!1;for(let c of i){let d=c.match(/^\s*\[([^\]]+)\]\s*$/);if(d){s=d[1].trim(),a.push(c);continue}if(s===""&&!/^\s*#/.test(c)){let u=!1;for(let{oldKey:h,newKey:v}of t){let k=c.match(new RegExp(`^\\s*${se(h)}\\s*=\\s*(.+?)\\s*$`));if(k){let C=n(k[1]);C!==void 0&&(r[v]=C),p=!0,u=!0;break}}if(u)continue}a.push(c)}let l=a.join(`
|
|
36
|
+
`);if(Object.keys(r).length===0)return{toml:l,changed:p};for(let{newKey:c}of t){let d=r[c];if(d===void 0)continue;let u=ie(l,"features");if((()=>{if(!u)return!1;let k=l.slice(u.start,u.end);return new RegExp(`^\\s*${se(c)}\\s*=`,"m").test(k)})())continue;let v=`${c} = ${d}`;if(u){let k=l.slice(0,u.end),C=l.slice(u.end),A=k.length>0&&!k.endsWith(`
|
|
36
37
|
`),D=C.length>0&&!C.startsWith(`
|
|
37
|
-
`);l=k+`${
|
|
38
|
+
`);l=k+`${A?`
|
|
38
39
|
`:""}${v}
|
|
39
40
|
${D?`
|
|
40
41
|
`:""}`+C}else l=(l.length===0?"":Ae(l))+`[features]
|
|
41
42
|
${v}
|
|
42
|
-
`;p=!0}return{toml:l,changed:p}}import G from"fs-extra";import*as
|
|
43
|
-
notifications = true`);let c=[];s="";for(let d=0;d<i.length;d++){let u=i[d],
|
|
44
|
-
`),"utf8")}import
|
|
43
|
+
`;p=!0}return{toml:l,changed:p}}import G from"fs-extra";import*as re from"path";async function Nt(e){let t=re.join(e.homeDir,".codex","notify.sh"),o=re.join(e.rootDir,"templates","notification.sh");await G.ensureDir(re.dirname(t));let n=e.options.notify;if(n==="no"){e.logger.info("Skipping notify hook installation");return}if(!await G.pathExists(o)){e.logger.warn(`Notification template missing at ${o}; skipping notify hook install`);return}if(await G.pathExists(t))if(n==="yes"){let s=O(t);e.options.dryRun?e.logger.log(`[dry-run] cp ${t} ${s}`):await G.copy(t,s),e.options.dryRun?e.logger.log(`[dry-run] cp ${o} ${t}`):(await G.copy(o,t),await G.chmod(t,493)),e.logger.ok("Updated notify hook (backup created)")}else!e.options.assumeYes&&!e.options.skipConfirmation&&e.logger.info("Keeping existing notify hook");else e.options.dryRun?e.logger.log(`[dry-run] cp ${o} ${t}`):(await G.copy(o,t),await G.chmod(t,493)),e.logger.ok("Installed notify hook to ~/.codex/notify.sh");let i=re.join(e.homeDir,".codex","config.toml");await G.pathExists(i)?await Fo(i,t,e):e.logger.warn(`Config not found at ${i}; run again after config is created`)}async function Fo(e,t,o){if(o.options.dryRun){o.logger.log("[dry-run] update config notify and tui.notifications");return}let i=(await G.readFile(e,"utf8")).split(/\r?\n/),s="",r=null,a=null;for(let d=0;d<i.length;d++){let u=i[d],h=u.match(/^\s*\[([^\]]+)\]\s*$/);if(h){s=h[1],s==="tui"&&(a=d);continue}let v=/^\s*notify\s*=\s*\[/.test(u),k=/^\s*tui\.notifications\s*=/.test(u),C=/^\s*notifications\s*=/.test(u);v&&(s===""?r===null&&(r=d):/^profiles\.[^.]+\.features$/.test(s)&&(i.splice(d,1),d--)),k&&/^profiles\.[^.]+\.features$/.test(s)&&(i.splice(d,1),d--),C&&s===""&&(i.splice(d,1),d--)}function p(d){let u=0;for(;u<i.length&&/^\s*(#.*)?$/.test(i[u]);)u++;i.splice(u,0,d)}if(r!==null){let d=i[r].match(/^(\s*notify\s*=\s*\[)([^\]]*)\]/);if(d){let u=d[2].trim();if(!u.includes(JSON.stringify(t))){let v=u&&!u.endsWith(",")?", ":"";i[r]=`${d[1]}${u}${v}${JSON.stringify(t)}]`,o.logger.ok("Added notify hook to config")}}}else p(`notify = [${JSON.stringify(t)}]`),o.logger.ok("Enabled notify hook in config");let l=!1;if(a!==null){let d=a+1,u=!1;for(;d<i.length;d++){let h=i[d];if(/^\s*\[/.test(h))break;if(/^\s*notifications\s*=/.test(h)){i[d]="notifications = true",u=!0,l=!0;break}}u||(i.splice(a+1,0,"notifications = true"),l=!0)}l||p(`[tui]
|
|
44
|
+
notifications = true`);let c=[];s="";for(let d=0;d<i.length;d++){let u=i[d],h=u.match(/^\s*\[([^\]]+)\]\s*$/);if(h){s=h[1],c.push(u);continue}/^\s*tui\.notifications\s*=/.test(u)||/^\s*notifications\s*=/.test(u)&&s!=="tui"||c.push(u)}await G.writeFile(e,c.join(`
|
|
45
|
+
`),"utf8")}import V from"fs-extra";import*as N from"path";async function Lt(e){let t=N.join(e.rootDir,"sounds"),o=N.join(e.homeDir,".codex","sounds");await V.ensureDir(o);let n=e.options.notificationSound;if(n==="none"){let l=N.join(e.homeDir,".codex","notify.sh");if(await V.pathExists(l)){let c=await V.readFile(l,"utf8"),d=c.replace(/^DEFAULT_CODEX_SOUND=.*$/m,'DEFAULT_CODEX_SOUND=""');e.options.dryRun?e.logger.log(`[dry-run] patch ${l} DEFAULT_CODEX_SOUND -> empty`):d!==c&&await V.writeFile(l,d,"utf8")}e.logger.ok("Notification sound disabled");return}let i;if(n&&!N.isAbsolute(n)?i=N.join(t,n):n?i=n:e.options.mode==="recommended"&&(i=N.join(t,"noti_1.wav")),!i||!await V.pathExists(i)){e.logger.warn("No notification sound selected or file missing; skipping sound setup");return}let s=N.isAbsolute(i),r=i.startsWith(N.join(e.rootDir,"sounds")),a=!s||r?N.join(o,N.basename(i)):i;(!s||r)&&(e.options.dryRun?e.logger.log(`[dry-run] cp ${i} ${a}`):await V.copy(i,a));let p=N.join(e.homeDir,".codex","notify.sh");if(await V.pathExists(p)){let l=await V.readFile(p,"utf8"),c=`DEFAULT_CODEX_SOUND="${a}"`,d=l.replace(/^DEFAULT_CODEX_SOUND=.*$/m,c);d!==l&&(e.options.dryRun?e.logger.log(`[dry-run] patch ${p} DEFAULT_CODEX_SOUND -> ${a}`):await V.writeFile(p,d,"utf8"))}e.logger.ok("Notification sound configured")}import L from"fs-extra";import*as Y from"path";async function Dt(e){let t=Y.join(e.homeDir,".codex","AGENTS.md"),o=e.options.globalAgents;if(o==="skip"){e.logger.info("Skipping global AGENTS.md creation");return}let n=Y.join(e.rootDir,"templates","agent-templates","AGENTS-default.md");if(!await L.pathExists(n)){e.logger.warn(`Template not found at ${n}`);return}switch(o){case"create-default":{if(await L.pathExists(t)){e.logger.info("Global AGENTS.md already exists; leaving unchanged");return}await L.ensureDir(Y.dirname(t)),e.options.dryRun?e.logger.log(`[dry-run] cp ${n} ${t}`):await L.copy(n,t),e.logger.ok(`Wrote ${t}`);break}case"overwrite-default":{if(await L.ensureDir(Y.dirname(t)),await L.pathExists(t)){let i=O(t);e.options.dryRun?e.logger.log(`[dry-run] cp ${t} ${i}`):await L.copy(t,i),e.logger.info(`Backed up existing AGENTS.md to: ${i}`)}e.options.dryRun?e.logger.log(`[dry-run] cp ${n} ${t}`):await L.copy(n,t),e.logger.ok(`Wrote ${t}`);break}case"append-default":{if(await L.ensureDir(Y.dirname(t)),await L.pathExists(t)){let s=O(t);e.options.dryRun?e.logger.log(`[dry-run] cp ${t} ${s}`):await L.copy(t,s),e.logger.info(`Backed up existing AGENTS.md to: ${s}`)}let i=await L.readFile(n,"utf8");e.options.dryRun?e.logger.log(`[dry-run] append template to ${t}`):await L.appendFile(t,`
|
|
45
46
|
---
|
|
46
47
|
|
|
47
|
-
${i}`,"utf8"),e.logger.ok(`Appended template to ${t}`);break}default:e.options.skipConfirmation&&e.logger.info("Skipping global AGENTS.md creation (non-interactive mode)");break}}async function
|
|
48
|
+
${i}`,"utf8"),e.logger.ok(`Appended template to ${t}`);break}default:e.options.skipConfirmation&&e.logger.info("Skipping global AGENTS.md creation (non-interactive mode)");break}}async function jt(e){if(e.options.noVscode)return;let t=e.options.vscodeId;if(!t){e.logger.info("VS Code extension id not provided. Use: --vscode <publisher.extension>");return}if(!await S("code")){e.logger.warn("'code' (VS Code) not in PATH; skipping extension install");return}if(e.options.dryRun){e.logger.log(`[dry-run] code --install-extension ${t}`);return}e.logger.info(`Installing VS Code extension: ${t}`),await I("code",["--install-extension",t,"--force"],{dryRun:!1,logger:e.logger}),e.logger.ok(`VS Code extension '${t}' installed (or already present)`)}import ue from"fs-extra";import*as me from"path";async function _t(e){let t=e.options.agentsMd;if(!t)return;let o=t;(await ue.stat(o).catch(()=>null))?.isDirectory()&&(o=me.join(o,"AGENTS.md"));let n=me.join(e.rootDir,"templates","agent-templates","AGENTS-default.md");if(await ue.pathExists(o)){e.logger.warn(`${o} already exists`);let i=O(o);e.options.dryRun?e.logger.log(`[dry-run] cp ${o} ${i}`):await ue.copy(o,i),e.logger.info(`Backed up existing AGENTS.md to: ${i}`)}e.logger.info(`Writing starter AGENTS.md to: ${o}`),e.options.dryRun?e.logger.log(`[dry-run] write AGENTS.md to ${o}`):(await ue.ensureDir(me.dirname(o)),await ue.copy(n,o),e.logger.ok("Wrote AGENTS.md"))}import ge from"fs-extra";import*as et from"path";import*as De from"@clack/prompts";import Ze from"fs-extra";import*as Ne from"path";async function Le(e){let t=Ne.join(e,"templates","skills"),o=await Ze.readdir(t,{withFileTypes:!0}).catch(()=>[]),n=[];for(let i of o){if(!i.isDirectory())continue;let s=i.name,r=Ne.join(t,s),a=Ne.join(r,"SKILL.md");if(!await Ze.pathExists(a))continue;let p=await Ze.readFile(a,"utf8").catch(()=>""),l=Wo(p);!l?.name||!l?.description||n.push({id:s,name:l.name,description:l.description,srcDir:r})}return n.sort((i,s)=>i.id.localeCompare(s.id)),n}function Wo(e){let t=e.split(/\r?\n/);if(t.length<3||t[0].trim()!=="---")return null;let o=[],n=-1;for(let s=1;s<t.length;s++){if(t[s].trim()==="---"){n=s;break}o.push(t[s])}if(n===-1)return null;let i={};for(let s of o){let r=s.trim();if(!r||r.startsWith("#"))continue;let a=r.indexOf(":");if(a===-1)continue;let p=r.slice(0,a).trim();if(!p)continue;let l=r.slice(a+1).trim();l&&(l=Uo(Bo(l)),i[p]=l)}return{name:i.name,description:i.description}}function Bo(e){let t=e.trim();if(!t||t.startsWith('"')||t.startsWith("'"))return t;let o=t.indexOf(" #");return o===-1?t:t.slice(0,o).trim()}function Uo(e){let t=e.trim();return t.length>=2&&(t.startsWith('"')&&t.endsWith('"')||t.startsWith("'")&&t.endsWith("'"))?t.slice(1,-1):t}async function je(e){let t=e.options.skills;if(t==="skip"){e.logger.info("Skipping bundled skills installation");return}let o=await Le(e.rootDir);if(o.length===0){e.logger.info("No bundled skills found; skipping");return}let n=(()=>{if(t==="all")return o;let r=new Set((e.options.skillsSelected||[]).map(a=>a.trim()).filter(Boolean));return o.filter(a=>r.has(a.id)||r.has(a.name))})();if(n.length===0){e.logger.info("No skills selected; skipping");return}let i=et.join(e.homeDir,".codex","skills"),s=process.stdout.isTTY&&!e.options.dryRun&&!e.options.skipConfirmation&&!e.options.assumeYes;e.options.dryRun?e.logger.log(`[dry-run] mkdir -p ${i}`):await ge.ensureDir(i),e.logger.info(`Installing ${n.length} skill(s) into: ${i}`);for(let r of n){let a=et.join(i,r.id);if(await ge.pathExists(a)){if(s){let c=await De.select({message:`Skill "${r.id}" already exists. Overwrite? (backup created)`,options:[{label:"Overwrite",value:"overwrite"},{label:"Skip",value:"skip"}],initialValue:"overwrite"});if(De.isCancel(c)||c==="skip"){e.logger.info(`Skipping existing skill: ${r.id}`);continue}}let l=O(a);e.options.dryRun?(e.logger.log(`[dry-run] cp -R ${a} ${l}`),e.logger.log(`[dry-run] rm -rf ${a}`)):(await ge.copy(a,l),await ge.remove(a)),e.logger.info(`Backed up existing skill ${r.id} to: ${l}`)}e.options.dryRun?e.logger.log(`[dry-run] cp -R ${r.srcDir} ${a}`):await ge.copy(r.srcDir,a),e.logger.ok(`Installed skill: ${r.id}`)}}var Gt="codex-1up";async function Ft(e,t){let o=Mt.homedir(),n=tt.join(o,`.${Gt}`);await Ot.ensureDir(n);try{await Ot.chmod(n,448)}catch{}let i=new Date().toISOString().replace(/[:.]/g,"-").slice(0,-5),s=tt.join(n,`install-${i}.log`),r=Se(s);r.info(`==> ${Gt} installer`),r.info(`Log: ${s}`);let a={cwd:process.cwd(),homeDir:o,rootDir:t,logDir:n,logFile:s,options:e,logger:r};try{await St(a),await xt(a),await Pe(a);let l=await S("codex")||a.options.installCodexCli==="yes";l||r.warn("Codex CLI not found and codex install was skipped; skipping config/notify setup until codex is installed."),l&&(await Et(a),await Nt(a),await Lt(a),await Dt(a)),await je(a),await jt(a),await _t(a),r.ok("All done. Open a new shell or 'source' your rc file to load aliases."),r.info("Next steps:"),r.info(" 1) codex # sign in; then ask it to plan a refactor"),r.info(" 2) ./bin/codex-1up agents --path $PWD # write a starter AGENTS.md to your repo"),r.info(" 3) Review ~/.codex/config.toml (see: https://github.com/openai/codex/blob/main/docs/config.md)")}catch(p){throw r.err(`Installation failed: ${p}`),p}}import Ko from"os";import*as nt from"path";import{promises as Wt}from"fs";import{accessSync as Vo}from"fs";import{dirname as qo,resolve as ot}from"path";import{fileURLToPath as zo}from"url";function T(e=import.meta.url){let t=qo(zo(e)),o=t;for(let n=0;n<6;n++){try{return Vo(ot(o,"templates","codex-config.toml")),o}catch{}o=ot(o,"..")}return ot(t,"..")}function Ho(){return{profile:"skip",profileScope:"selected",profileMode:"add",setDefaultProfile:!1,profilesSelected:void 0,installTools:"skip",toolsSelected:void 0,installCodexCli:"no",notify:"no",globalAgents:"skip",notificationSound:void 0,skills:"skip",skillsSelected:void 0,mode:"manual",installNode:"skip",shell:"auto",vscodeId:void 0,noVscode:!0,agentsMd:void 0,dryRun:!1,assumeYes:!1,skipConfirmation:!1}}async function ae(e={}){let t=Ko.homedir(),o=nt.join(t,".codex-1up");await Wt.mkdir(o,{recursive:!0});try{await Wt.chmod(o,448)}catch{}let n=new Date().toISOString().replace(/[:.]/g,"-").slice(0,-5),i=nt.join(o,`command-${n}.log`),s=Se(i),r=Ho();return{cwd:process.cwd(),homeDir:t,rootDir:T(),logDir:o,logFile:i,options:{...r,...e},logger:s}}function J(){return ne()}function X(e){return Tt(e)}function Bt(){return J().map(e=>e.id)}async function he(){let e=ne(),t=[];for(let o of e){let n=await st(o.bins);t.push({id:o.id,installed:n})}return t}async function it(e,t={}){let o=e==="all",n={installTools:o?"all":"select",toolsSelected:o?void 0:e,dryRun:!!t.dryRun},i=await ae(n);await Pe(i)}async function st(e){for(let t of e)if(await S(t))return!0;return!1}async function rt(e,t){let o=t||T();await Ft(e,o)}async function at(){let e=Yo.homedir(),t=Jo(e,".codex","config.toml"),o,n=[];try{let l=await Xo.readFile(t,"utf8"),c=Ut.parse(l);o=typeof c.profile=="string"?c.profile:void 0;let d=c.profiles&&typeof c.profiles=="object"?c.profiles:{};n=Object.keys(d)}catch(l){}let i=J(),s=[{id:"codex",bins:["codex"]},...i],a=(await Promise.all(s.map(async l=>{let c=await st(l.bins);return[l.id,c]}))).filter(([,l])=>l).map(([l])=>l),p=[];p.push(""),p.push("codex-1up: Installation summary"),p.push("\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"),p.push(`Config: ${t}${o?` (active profile: ${o})`:""}`),n.length&&p.push(`Profiles: ${n.join(", ")}`),p.push(`Tools detected: ${a.join(", ")||"none"}`),p.push(""),p.push("Usage:"),p.push(" - Switch profile for a session: codex --profile <name>"),p.push(" - List available profiles: codex-1up config profiles"),p.push(" - Persist active profile: codex-1up config set-profile <name>"),p.push(" - Write AGENTS.md to a repo: codex-1up agents --path ."),p.push(""),process.stdout.write(p.join(`
|
|
48
49
|
`)+`
|
|
49
|
-
`)}import
|
|
50
|
-
`)),d==="single"){if(!p.profileChoice){let m=await f.select({message:"Choose a Codex profile to install",options:[...
|
|
51
|
-
`),B=
|
|
52
|
-
`));;){let m=await f.select({message:"Install bundled Agent Skills (optional)",options:[{label:"None (do not install skills)",value:"skip"},{label:"Select skills\u2026",value:"select"},{label:"All (install every bundled skill)",value:"all"}],initialValue:"skip"});if(f.isCancel(m))return
|
|
50
|
+
`)}import Qo from"fs-extra";import Zo from"os";import Vt from"path";async function lt(e){return Le(e)}var pt=lt;async function qt(){let e=Vt.join(Zo.homedir(),".codex","skills");return(await Qo.readdir(e,{withFileTypes:!0}).catch(()=>[])).filter(o=>o.isDirectory()).map(o=>({id:o.name,path:Vt.join(e,o.name)})).sort((o,n)=>o.id.localeCompare(n.id))}async function _e(e,t,o={}){let n=await ae({skills:e,skillsSelected:t,dryRun:!!o.dryRun});await je(n)}import{existsSync as en,readFileSync as tn}from"fs";import{dirname as Kt,join as zt}from"path";import{fileURLToPath as on}from"url";var nn=Kt(on(import.meta.url)),Ht=(e,t=!1)=>{try{return JSON.parse(tn(e,"utf-8"))}catch(o){if(t)return{};throw o}},sn=e=>!!(e.name==="codex-1up"||e.bin==="codex-1up"||e.bin&&typeof e.bin=="object"&&"codex-1up"in e.bin),rn=e=>{let t=e,o=null;for(;;){let n=zt(t,"package.json");if(en(n)){o||(o=n);let s=Ht(n,!0);if(sn(s))return n}let i=Kt(t);if(i===t)break;t=i}return o??zt(e,"package.json")},an=rn(nn),dt=Ht(an),Oe=dt.name||"codex-1up",le=dt.version||"0.0.0",Yt=dt.description||"Codex CLI helper";import{promises as ft}from"fs";import{resolve as ct}from"path";import*as f from"@clack/prompts";import{$ as we,which as ye}from"zx";import*as Ge from"@clack/prompts";async function ln(){let e=le,t=await pn(Oe),o=!!(t&&dn(t,e));return{current:e,latest:t,updateAvailable:o}}async function Me(e){let t=e.logger,o=await ln();if(!o.latest)return t?.warn("Unable to check for codex-1up updates right now."),"error";if(!o.updateAvailable)return t?.ok(`codex-1up is up-to-date (v${o.current}).`),"up-to-date";let n=e.interactive&&!e.assumeYes&&!e.skipConfirmation,i=e.assumeYes||e.skipConfirmation;if(n){let p=await Ge.confirm({message:`New codex-1up version available (v${o.latest}). Update now?`,initialValue:!0});if(Ge.isCancel(p))return t?.info("Update canceled."),"skipped";i=!!p}if(!i)return t?.info("Skipping codex-1up update."),"skipped";let s=await Te({logger:t,interactive:e.interactive&&!e.assumeYes&&!e.skipConfirmation});if(s==="none")return t?.warn("No supported Node package manager found; cannot update codex-1up."),"error";let r=o.latest?`${Oe}@${o.latest}`:Oe,a=!!e.dryRun;return s==="pnpm"?(t?.info("Updating codex-1up via pnpm"),await I("pnpm",["add","-g",r],{dryRun:a,logger:t})):(t?.info("Updating codex-1up via npm"),await I("npm",["install","-g",r],{dryRun:a,logger:t})),t?.ok(`codex-1up updated to v${o.latest}`),"updated"}async function pn(e){try{let t=await fetch(`https://registry.npmjs.org/${encodeURIComponent(e)}/latest`);return t.ok?(await t.json()).version:void 0}catch{return}}function dn(e,t){let o=Jt(e),n=Jt(t);if(!o||!n)return e!==t;for(let i=0;i<3;i++){if(o[i]>n[i])return!0;if(o[i]<n[i])return!1}return!1}function Jt(e){let t=e.match(/(\d+)\.(\d+)\.(\d+)/);return t?[Number(t[1]),Number(t[2]),Number(t[3])]:null}async function Xt(e){return xe(e)}var cn=["balanced","safe","yolo"];async function Qt(e){let{repoRoot:t,isUnixLike:o,globalAgentsExists:n,currentProfile:i,seededProfile:s,bundledSkills:r,availableTools:a,cliArgs:p}=e,{profileChoice:l,profileMode:c,profileScope:d,setDefaultProfile:u,profilesSelected:h,installTools:v,toolsSelected:k,installCodexCli:C,notifyAction:A,globalAgentsAction:D,notificationSound:q,skillsMode:K,skillsSelected:Q}=e.selections;await Me({interactive:!0,assumeYes:!1,skipConfirmation:!1,dryRun:!1,logger:{log:m=>f.log.info(m),info:m=>f.log.info(m),ok:m=>f.log.success(m),warn:m=>f.log.warn(m),err:m=>f.log.warn(m)}});let x=await Xt();if(x.found){let m=x.version?`v${x.version}`:"unknown version";x.latest?x.updateAvailable?f.log.info(`Codex CLI detected (${m}). Newer version available: v${x.latest}.`):f.log.info(`Codex CLI detected (${m}). Latest: v${x.latest}.`):f.log.info(`Codex CLI detected (${m}).`)}else f.log.info("Codex CLI not detected.");if(C==="no")x.found?x.updateAvailable&&f.log.info("Codex CLI update disabled by --codex-cli no."):f.log.info("Codex CLI install disabled by --codex-cli no.");else if(C==="auto")if(x.found){if(x.updateAvailable){let m=await f.confirm({message:`Codex CLI ${x.version} found; latest is ${x.latest}. Update now?`,initialValue:!0});if(f.isCancel(m))return R();C=m?"yes":"no"}}else{let m=await f.confirm({message:"Codex CLI not found. Install now?",initialValue:!0});if(f.isCancel(m))return R();C=m?"yes":"no"}if(o&&!p.toolsArg){let m=await he(),w=m.filter(y=>y.installed).map(y=>y.id),b=m.filter(y=>!y.installed).map(y=>y.id);for(f.log.info(`Tools detected: ${w.join(", ")||"none"}`),b.length&&f.log.info(`Missing tools: ${b.join(", ")}`);;){let y=await f.select({message:"Install/update developer tools",options:[{label:"Install/Update all",value:"all"},{label:"Select",value:"select"},{label:"Skip",value:"skip"}],initialValue:"all"});if(f.isCancel(y))return R();if(v=y,y!=="select"){k=void 0;break}f.log.info("Tip: press Esc to go back.");let E=await Fe({message:"Select tools to install",options:a.map(g=>{let $=w.includes(g.id);return{label:g.id,value:g.id,hint:$?"installed":"missing"}})});if(E==="back")continue;let j=Array.isArray(E)?E.map(g=>String(g).trim().toLowerCase()).filter(X):[];j.length===0?(v="skip",k=void 0):k=Array.from(new Set(j));break}}else!o&&!p.toolsArg&&(v="skip",k=void 0);let H=[{label:"Balanced (recommended)",value:"balanced",hint:"on-request approvals \xB7 workspace-write \xB7 web search on"},{label:"Safe",value:"safe",hint:"on-failure approvals \xB7 read-only \xB7 web search off"},{label:"YOLO",value:"yolo",hint:"never approvals \xB7 danger-full-access \xB7 gpt-5.2-codex"}];if(!p.profileScope)for(;;){let m=await f.select({message:"Install all profiles (balanced, safe, yolo)?",options:[{label:"Yes \u2014 install/update all profiles",value:"all"},{label:"Choose profiles\u2026",value:"selected"},{label:"No \u2014 don't install any profiles",value:"skip"}],initialValue:"all"});if(f.isCancel(m))return R();if(m==="skip"){d="selected",h=[],l="skip";break}if(m!=="selected"){d=m;break}f.log.info("Tip: press Esc to go back.");let w=await Fe({message:"Select profiles to install",options:H.map(E=>({label:E.label,value:E.value,hint:E.hint}))});if(w==="back")continue;let b=Array.isArray(w)?w.map(E=>String(E).trim().toLowerCase()).filter(be):[],y=Array.from(new Set(b));d="selected",y.length===0?(h=[],l="skip"):h=y;break}if(d!=="all"&&!p.profileChoice&&f.log.info(["Profiles:"," - Balanced: on-request approvals, workspace-write sandbox, web search on."," - Safe: on-failure approvals, read-only sandbox, web search off."," - YOLO: never approvals, danger-full-access, gpt-5.2-codex, high reasoning."].join(`
|
|
51
|
+
`)),d==="single"){if(!p.profileChoice){let m=await f.select({message:"Choose a Codex profile to install",options:[...H,{label:"Skip (no profile changes)",value:"skip"}],initialValue:mn(i)});if(f.isCancel(m))return R();l=m}}else if(d==="selected"){if(h===void 0){f.log.info("Tip: press Esc to go back.");let m=await Fe({message:"Select profiles to install",options:H.map(w=>({label:w.label,value:w.value,hint:w.hint}))});if(m==="back")h=[],l="skip";else{let w=Array.isArray(m)?m.map(y=>String(y).trim().toLowerCase()).filter(be):[],b=Array.from(new Set(w));b.length===0?(h=[],l="skip"):h=b}}(h||[]).length>0&&be(l)&&!h.includes(l)&&(l=h[0])}else d==="all"&&l==="skip"&&(l=s);let P=d==="all"?[...cn]:d==="selected"?h||[]:l==="skip"?[]:[l];if(P.length>0&&!p.profileMode){let m=await f.select({message:d==="all"?"How should we write all profiles?":P.length>1?"How should we write selected profiles?":`How should we write profiles.${P[0]}?`,options:[{label:"Overwrite (use codex-1up defaults)",value:"overwrite"},{label:"Add Merge (add missing, keep your default settings)",value:"add"}],initialValue:c});if(f.isCancel(m))return R();c=m}if(P.length===0)u=!1;else if(P.length===1){let m=P[0],w=await f.confirm({message:`Wrote profiles.${m} to ~/.codex/config.toml (mode: ${c}). Set this as the default profile?`,initialValue:!0});if(f.isCancel(w))return R();u=!!w,u&&(l=m)}else{let m=[{label:"Keep current default (skip)",value:"skip"},...P.map(y=>({label:y==="balanced"?"Balanced":y==="safe"?"Safe":"YOLO",value:y}))],w=be(l)&&P.includes(l)?l:P[0],b=await f.select({message:"Select a default profile (optional)",options:m,initialValue:w});if(f.isCancel(b))return R();b==="skip"?u=!1:(u=!0,l=b)}if(!p.soundArg){let y=function(){return[{label:"Skip (leave current setup)",value:"skip"},{label:"None (disable sounds)",value:"none"},...w.map(g=>({label:g,value:g})),{label:"Custom path\u2026",value:"custom"}]};var Z=y;let m=ct(t,"sounds"),w=[];try{w=(await ft.readdir(m)).filter(g=>/\.(wav|mp3|ogg)$/i.test(g)).sort()}catch(g){}A="yes";let b=w.includes("noti_1.wav")?"noti_1.wav":w[0]||"none";async function E(g){let $=await f.text({message:"Enter absolute path to a .wav file",placeholder:g||"/absolute/path/to/sound.wav",validate(_){if(!_)return"Path required";if(!_.startsWith("/"))return"Use an absolute path";if(!/(\.wav|\.mp3|\.ogg)$/i.test(_))return"Supported: .wav, .mp3, .ogg"}});if(f.isCancel($))return null;try{await ft.access(String($))}catch{return f.log.warn("File not found. Try again."),await E(String($))}return String($)}let j=await f.select({message:"Notification sound",options:y(),initialValue:b});if(f.isCancel(j))return R();if(j==="skip")A="no",q=void 0;else if(j==="custom"){let g=await E();if(g===null)return R();b=g}else b=j;if(j!=="skip"){for(;;){let g=await f.select({message:`Selected: ${b}. What next?`,options:[{label:"Preview \u25B6 (press p then Enter)",value:"preview"},{label:"Use this",value:"use"},{label:"Choose another\u2026",value:"change"}],initialValue:"use"});if(f.isCancel(g))return R();if(g==="use")break;if(g==="change"){let $=await f.select({message:"Notification sound",options:y(),initialValue:b});if(f.isCancel($))return R();if($==="custom"){let _=await E();if(_===null)return R();b=_}else if($==="skip"){A="no",q=void 0;break}else b=$;continue}try{let $=b==="none"?"none":b.startsWith("/")?b:ct(t,"sounds",b);await fn($)}catch($){f.log.warn(String($))}}q===void 0&&(q=b)}}let W=["Global AGENTS.md is shared instructions Codex can reference in any repo.","We add a short starter guide (fd/ast-grep/jq/yq patterns, deterministic selects).","Backups will be created.","You can remove it later from ~/.codex/AGENTS.md."].join(`
|
|
52
|
+
`),B=ct(t,"templates","agent-templates","AGENTS-default.md"),M=await(async m=>{for(;;){f.log.info(W);let w=await f.select({message:"Global ~/.codex/AGENTS.md (optional)",options:m?[{label:"Add to your existing AGENTS.md (keeps your content, adds ours; backup created)",value:"append-default"},{label:"Overwrite existing (replace with starter; backup created)",value:"overwrite-default"},{label:"Preview starter AGENTS.md",value:"preview"},{label:"Skip \u2014 leave as-is (you can run codex-1up agents later)",value:"skip"}]:[{label:"Create starter AGENTS.md (recommended; helps give Codex repo context everywhere)",value:"create-default"},{label:"Preview starter AGENTS.md",value:"preview"},{label:"Skip for now (you can add later with codex-1up agents --global)",value:"skip"}],initialValue:m?"append-default":"create-default"});if(f.isCancel(w))return null;if(w==="preview"){await un(B);continue}return w}})(n);if(!M)return R();if(D=M,!p.skillsArg&&r.length)for(f.log.info(["Agent Skills are optional, portable skill folders (SKILL.md + optional scripts/references).","codex-1up can install bundled skills into ~/.codex/skills so your agent can reference them.",`Bundled skills: ${r.map(m=>m.id).join(", ")}`].join(`
|
|
53
|
+
`));;){let m=await f.select({message:"Install bundled Agent Skills (optional)",options:[{label:"None (do not install skills)",value:"skip"},{label:"Select skills\u2026",value:"select"},{label:"All (install every bundled skill)",value:"all"}],initialValue:"skip"});if(f.isCancel(m))return R();if(K=m,m!=="select")break;f.log.info("Tip: press Esc to go back.");let w=await Fe({message:"Select skills to install",options:r.map(y=>({label:y.id,value:y.id,hint:y.description.length>120?`${y.description.slice(0,117)}\u2026`:y.description}))});if(w==="back")continue;let b=Array.isArray(w)?w.map(y=>String(y).trim()).filter(Boolean):[];b.length===0?(K="skip",Q=void 0):Q=b;break}return{selections:{profileChoice:l,profileMode:c,profileScope:d,setDefaultProfile:u,profilesSelected:h,installTools:v,toolsSelected:k,installCodexCli:C,notifyAction:A,globalAgentsAction:D,notificationSound:q,skillsMode:K,skillsSelected:Q}}}async function fn(e){if(e.endsWith("/none")||e==="none")return;let t=[async o=>{await ye("afplay"),await we`afplay ${o}`},async o=>{await ye("paplay"),await we`paplay ${o}`},async o=>{await ye("aplay"),await we`aplay ${o}`},async o=>{await ye("mpg123"),await we`mpg123 -q ${o}`},async o=>{await ye("ffplay"),await we`ffplay -nodisp -autoexit -loglevel quiet ${o}`}];for(let o of t)try{await o(e);return}catch{}throw new Error("No audio player found (afplay/paplay/aplay/mpg123/ffplay)")}async function Fe(e){let o=await f.multiselect({message:e.message,options:e.options});return f.isCancel(o)?"back":Array.isArray(o)?o.map(i=>String(i)):[]}async function un(e){let o="";try{o=await ft.readFile(e,"utf8")}catch{f.log.warn(`Starter AGENTS template not found at ${e}`);return}let n=o.split(/\r?\n/);if(n.length===0||n.length===1&&n[0].trim()===""){f.log.warn("Starter AGENTS template is empty.");return}let i=n.filter(r=>/^#{1,3}\s+/.test(r)).map(r=>r.replace(/^#{1,3}\s+/,"").trim()).filter(Boolean).slice(0,12);f.log.info(`Preview: ${e}`),i.length&&f.log.info(`Sections: ${i.join(" | ")}`);let s=n.slice(0,40).join(`
|
|
53
54
|
`);process.stdout.write(s+`
|
|
54
|
-
`),n.length>40&&f.log.info(`... (${n.length-40} more lines)`)}function
|
|
55
|
-
`)}});import{defineCommand as
|
|
55
|
+
`),n.length>40&&f.log.info(`... (${n.length-40} more lines)`)}function mn(e){return be(e)?e:"balanced"}function be(e){return e==="balanced"||e==="safe"||e==="yolo"}function R(){return f.cancel("Install aborted"),null}var We=T(),hn=["balanced","safe","yolo"],to=gn({meta:{name:"install",description:"Run the codex-1up installer with validated flags"},args:{yes:{type:"boolean",description:"Non-interactive; accept safe defaults"},"dry-run":{type:"boolean",description:"Print actions without making changes"},"skip-confirmation":{type:"boolean",description:"Skip prompts"},shell:{type:"string",description:"auto|zsh|bash|fish"},vscode:{type:"string",description:"Install VS Code extension id"},"no-vscode":{type:"boolean",description:"Skip VS Code extension checks"},"install-node":{type:"string",description:"nvm|brew|skip"},tools:{type:"string",description:"all|skip|<comma-separated tool ids> (rg, fd, fzf, jq, yq, ast-grep, bat, git, git-delta, gh)"},"codex-cli":{type:"string",description:"yes|no install/upgrade Codex CLI + ast-grep globally"},"profiles-scope":{type:"string",description:"single|all (write one profile or all profiles)"},profile:{type:"string",description:"balanced|safe|yolo|skip (choose profile to write)"},"profile-mode":{type:"string",description:"add|overwrite (profile table merge strategy)"},sound:{type:"string",description:'Sound file, "none", or "skip" to leave unchanged'},"agents-md":{type:"string",description:"Write starter AGENTS.md to PATH (default PWD/AGENTS.md)",required:!1},skills:{type:"string",description:"Install bundled Agent Skills to ~/.codex/skills: all|skip|<comma-separated names>"}},async run({args:e,rawArgs:t}){let o=ut(Be.homedir(),".codex","config.toml"),n=await mt(o),i=ut(Be.homedir(),".codex","notify.sh"),s=await mt(i),r=ut(Be.homedir(),".codex","AGENTS.md"),a=await mt(r),p=n?await vn(o):void 0,l=process.stdout.isTTY&&!e["dry-run"]&&!e["skip-confirmation"]&&!e.yes,c=wn(e.profile),d=yn(e["profile-mode"]),u=bn(e["profiles-scope"]),h=kn(e["codex-cli"]),v=process.platform==="darwin"||process.platform==="linux",k=typeof e.sound>"u"?void 0:String(e.sound).trim(),C=typeof e.tools>"u"?void 0:String(e.tools).trim(),A=e,D=typeof A.skills>"u"?void 0:String(A.skills).trim();if(k==="")throw new Error('Invalid --sound value (expected path, "none", or "skip")');if(C==="")throw new Error("Invalid --tools value (expected all|skip|<comma-separated tool ids>)");if(D==="")throw new Error("Invalid --skills value (expected all|skip|<comma-separated skill names>)");let q=t.some(g=>g==="--no-vscode"||g.startsWith("--no-vscode=")),K=await lt(We),Q=J(),ze=(c&&c!=="skip"?c:gt(p)?p:void 0)||"balanced",x=ze,H=d||"add",P=u||"single",pe=!0,W,B=v?"all":"skip",Ce=h||"auto",M,Z,m,w="skip",b,y;if(k&&(g=>{let $=g.trim().toLowerCase();if($==="skip"){M="no",m=void 0;return}M="yes",m=$==="none"?"none":g})(k),D){let g=D.trim().toLowerCase();if(g==="all")w="all";else if(g==="skip"||g==="none")w="skip";else{let $=D.split(",").map(U=>U.trim()).filter(Boolean);if($.length===0)throw new Error("Invalid --skills value (expected all|skip|<comma-separated skill names>)");let _=new Set(K.map(U=>U.id)),z=$.filter(U=>!_.has(U));if(z.length){let U=K.map(mo=>mo.id).join(", ")||"(none)";throw new Error(`Unknown skill(s): ${z.join(", ")}. Available: ${U}`)}w="select",b=$}}if(C){let g=C.trim().toLowerCase();if(g==="all")B="all";else if(g==="skip"||g==="none")B="skip";else{let $=C.split(",").map(z=>z.trim().toLowerCase()).filter(Boolean);if($.length===0)throw new Error("Invalid --tools value (expected all|skip|<comma-separated tool ids>)");let _=$.filter(z=>!X(z));if(_.length){let z=Q.map(U=>U.id).join(", ")||"(none)";throw new Error(`Unknown tool(s): ${_.join(", ")}. Available: ${z}`)}B="select",y=Array.from(new Set($)).filter(X)}}else v||(B="skip");if(l){F.log.info(`Codex 1up v${le} - equips your coding agent with powerful tools`),F.log.info("Install wizard");let g=await Qt({repoRoot:We,isUnixLike:v,globalAgentsExists:a,currentProfile:p,seededProfile:ze,bundledSkills:K,availableTools:Q,cliArgs:{profileChoice:c,profileMode:d,profileScope:u,soundArg:k,toolsArg:C,skillsArg:D},selections:{profileChoice:x,profileMode:H,profileScope:P,setDefaultProfile:pe,profilesSelected:W,installTools:B,toolsSelected:y,installCodexCli:Ce,notifyAction:M,globalAgentsAction:Z,notificationSound:m,skillsMode:w,skillsSelected:b}});if(!g)return;({profileChoice:x,profileMode:H,profileScope:P,setDefaultProfile:pe,profilesSelected:W,installTools:B,toolsSelected:y,installCodexCli:Ce,notifyAction:M,globalAgentsAction:Z,notificationSound:m,skillsMode:w,skillsSelected:b}=g.selections)}l||(P==="selected"&&W?.length&>(x)&&!W.includes(x)&&(x=W[0]),(P==="all"?[...hn]:P==="selected"?W||[]:x==="skip"?[]:[x]).length===0&&(pe=!1),typeof M>"u"&&(M=s?"no":"yes"),typeof Z>"u"&&(Z="skip"));let j={profile:x,profileScope:P,profileMode:H,setDefaultProfile:pe,profilesSelected:W,installCodexCli:Ce,installTools:B,toolsSelected:y,notify:M??(s?"no":"yes"),globalAgents:Z??"skip",notificationSound:m,skills:w,skillsSelected:b,mode:"manual",installNode:e["install-node"]||"skip",shell:String(e.shell||"auto"),vscodeId:q?void 0:e.vscode?String(e.vscode):void 0,noVscode:q||e["no-vscode"]||!1,agentsMd:typeof e["agents-md"]<"u"?String(e["agents-md"]||process.cwd()):void 0,dryRun:e["dry-run"]||!1,assumeYes:e.yes||!1,skipConfirmation:e["skip-confirmation"]||!1};if(l){F.log.info("Installing prerequisites and writing config..."),F.log.warn("Some steps may require sudo password or confirmation prompts.");try{await rt(j,We),F.log.success("Base install complete"),F.log.success("Install finished")}catch(g){throw F.cancel(`Installation failed: ${g}`),g}await at();return}try{await rt(j,We),await at()}catch(g){throw F.cancel(`Installation failed: ${g}`),g}}});async function mt(e){try{return await Zt.access(e),!0}catch{return!1}}function wn(e){if(e==null)return;let t=String(e).toLowerCase();if(gt(t))return t;if(t==="skip")return"skip";throw new Error("Invalid --profile value (use balanced|safe|yolo|skip).")}function yn(e){if(e==null)return;let t=String(e).toLowerCase();if(t==="add"||t==="overwrite")return t;throw new Error("Invalid --profile-mode value (use add|overwrite).")}function bn(e){if(e==null)return;let t=String(e).toLowerCase();if(t==="single"||t==="all")return t;throw new Error("Invalid --profiles-scope value (use single|all).")}function kn(e){if(e==null)return;let t=String(e).toLowerCase();if(t==="yes"||t==="no")return t;throw new Error("Expected yes|no")}function gt(e){return e==="balanced"||e==="safe"||e==="yolo"}async function vn(e){try{let t=await Zt.readFile(e,"utf8"),n=eo.parse(t).profile;return typeof n=="string"?n:void 0}catch(t){return}}import{defineCommand as Cn}from"citty";import{promises as ke}from"fs";import{resolve as oo,dirname as Sn}from"path";var $n=T();async function ht(e){try{return await ke.access(e),!0}catch{return!1}}async function xn(e,t){if(await ht(t)){let n=`${t}.backup.${new Date().toISOString().replace(/[:.]/g,"").replace("T","_").slice(0,15)}`;await ke.copyFile(t,n)}await ke.mkdir(Sn(t),{recursive:!0}),await ke.copyFile(e,t)}var no=Cn({meta:{name:"agents",description:"Write an AGENTS.md template"},args:{path:{type:"string",required:!0,description:"Target repo path or file"}},async run({args:e}){let t=String(e.path),o=oo($n,"templates/agent-templates","AGENTS-default.md"),i=await ht(t).then(async s=>s&&(await ke.stat(t)).isDirectory()).catch(()=>!1)?oo(t,"AGENTS.md"):t;if(!await ht(o))throw new Error(`Template not found: ${o}`);await xn(o,i),process.stdout.write(`Wrote ${i}
|
|
56
|
+
`)}});import{defineCommand as In}from"citty";import{$ as Tn}from"zx";import{resolve as Pn}from"path";var Rn=T(),io=In({meta:{name:"doctor",description:"Run environment checks"},async run(){await Tn`bash ${Pn(Rn,"scripts/doctor.sh")}`}});import{defineCommand as An}from"citty";import{$ as En}from"zx";import{resolve as Nn}from"path";var Ln=T(),so=An({meta:{name:"uninstall",description:"Clean up aliases and config created by this tool"},async run(){await En`bash ${Nn(Ln,"scripts/uninstall.sh")}`}});import{defineCommand as Ue}from"citty";import{promises as ve}from"fs";import{resolve as bt,dirname as Dn}from"path";import jn from"os";var _n=T();function wt(){let e=bt(jn.homedir(),".codex"),t=bt(e,"config.toml");return{CODEX_HOME:e,CFG:t}}async function yt(e){return ve.readFile(e,"utf8")}async function ro(e,t){await ve.mkdir(Dn(e),{recursive:!0}),await ve.writeFile(e,t,"utf8")}function ao(e){let t=/^\[profiles\.(.+?)\]/gm,o=[],n;for(;n=t.exec(e);)o.push(n[1]);return o}function On(e,t){let o=`profile = "${t}"`;if(/^profile\s*=\s*".*"/m.test(e))return e.replace(/^profile\s*=\s*".*"/m,o);let n=e.indexOf(`
|
|
56
57
|
`);return n===-1?o+`
|
|
57
58
|
`+e:e.slice(0,n+1)+o+`
|
|
58
|
-
`+e.slice(n+1)}var
|
|
59
|
+
`+e.slice(n+1)}var lo=Ue({meta:{name:"config",description:"Manage Codex config profiles"},subCommands:{init:Ue({meta:{name:"init",description:"Install unified config with multiple profiles"},args:{force:{type:"boolean",description:"Backup and overwrite if exists"}},async run({args:e}){let t=bt(_n,"templates/codex-config.toml"),o=await yt(t),{CFG:n}=wt(),i=await ve.access(n).then(()=>!0).catch(()=>!1);if(i&&!e.force){process.stdout.write(`${n} exists. Use --force to overwrite.
|
|
59
60
|
`);return}if(i){let s=`${n}.backup.${Date.now()}`;await ve.copyFile(n,s),process.stdout.write(`Backed up to ${s}
|
|
60
|
-
`)}await
|
|
61
|
-
`)}}),profiles:
|
|
61
|
+
`)}await ro(n,o),process.stdout.write(`Wrote ${n}
|
|
62
|
+
`)}}),profiles:Ue({meta:{name:"profiles",description:"List profiles in the current config"},async run(){let{CFG:e}=wt(),t=await yt(e),o=ao(t);process.stdout.write(o.length?o.join(`
|
|
62
63
|
`)+`
|
|
63
64
|
`:`No profiles found
|
|
64
|
-
`)}}),"set-profile":
|
|
65
|
-
`)}})}});import{defineCommand as
|
|
66
|
-
`)}}),install:
|
|
65
|
+
`)}}),"set-profile":Ue({meta:{name:"set-profile",description:"Set the active profile in config.toml"},args:{name:{type:"positional",required:!0,description:"Profile name"}},async run({args:e}){let{CFG:t}=wt(),o=await yt(t),n=ao(o),i=String(e.name);if(!n.includes(i))throw new Error(`Unknown profile: ${i}`);let s=On(o,i);await ro(t,s),process.stdout.write(`profile set to ${i}
|
|
66
|
+
`)}})}});import{defineCommand as Gn}from"citty";var po=Gn({meta:{name:"update",description:"Check for and apply codex-1up updates"},args:{yes:{type:"boolean",description:"Non-interactive; apply updates without prompting"},"dry-run":{type:"boolean",description:"Print actions without making changes"},"skip-confirmation":{type:"boolean",description:"Skip prompts"}},async run({args:e}){let t=await ae(),o=process.stdout.isTTY&&!e["dry-run"]&&!e["skip-confirmation"]&&!e.yes;await Me({interactive:o,assumeYes:!!e.yes,skipConfirmation:!!e["skip-confirmation"],dryRun:!!e["dry-run"],logger:t.logger})}});import{defineCommand as Ve}from"citty";var co=Ve({meta:{name:"tools",description:"Manage developer tools"},subCommands:{list:Ve({meta:{name:"list",description:"List known tools and installation status"},async run(){let e=await he();for(let t of e)process.stdout.write(`${t.id} ${t.installed?"\u2713":"\u2716"}
|
|
67
|
+
`)}}),install:Ve({meta:{name:"install",description:"Install tools by id or all"},args:{tool:{type:"positional",required:!0,description:'Tool id or "all"'},"dry-run":{type:"boolean",description:"Print actions without making changes"}},async run({args:e}){let t=String(e.tool||"").trim().toLowerCase();if(!t)throw new Error("Tool id required");if(t==="all"){await it("all",{dryRun:!!e["dry-run"]});return}let o=t.split(",").map(s=>s.trim()).filter(Boolean),n=Array.from(new Set(o)),i=n.filter(s=>!X(s));if(i.length){let s=Bt().join(", ");throw new Error(`Unknown tool id(s): ${i.join(", ")}. Known: ${s}`)}await it(n,{dryRun:!!e["dry-run"]})}}),doctor:Ve({meta:{name:"doctor",description:"Show missing tools and hints"},async run(){let t=(await he()).filter(n=>!n.installed).map(n=>n.id);if(t.length===0){process.stdout.write(`All tools are installed.
|
|
67
68
|
`);return}let o=J().map(n=>n.id).join(", ");process.stdout.write(`Missing tools: ${t.join(", ")}
|
|
68
69
|
`),process.stdout.write(`Known tools: ${o}
|
|
69
|
-
`)}})}});import{defineCommand as
|
|
70
|
+
`)}})}});import{defineCommand as qe}from"citty";var fo=qe({meta:{name:"skills",description:"Manage bundled Agent Skills"},subCommands:{list:qe({meta:{name:"list",description:"List bundled and installed skills"},async run(){let e=T(),t=await pt(e),o=await qt();if(process.stdout.write(`Bundled skills:
|
|
70
71
|
`),t.length===0)process.stdout.write(` (none)
|
|
71
72
|
`);else for(let n of t)process.stdout.write(` ${n.id} \u2014 ${n.description}
|
|
72
73
|
`);if(process.stdout.write(`
|
|
73
74
|
Installed skills:
|
|
74
75
|
`),o.length===0)process.stdout.write(` (none)
|
|
75
76
|
`);else for(let n of o)process.stdout.write(` ${n.id}
|
|
76
|
-
`)}}),install:
|
|
77
|
+
`)}}),install:qe({meta:{name:"install",description:"Install bundled skills by id or all"},args:{name:{type:"positional",required:!0,description:'Skill id or "all"'},"dry-run":{type:"boolean",description:"Print actions without making changes"}},async run({args:e}){let t=String(e.name||"").trim();if(!t)throw new Error("Skill id required");if(t==="all"){await _e("all",void 0,{dryRun:!!e["dry-run"]});return}let o=T(),n=await pt(o),i=t.split(",").map(p=>p.trim()).filter(Boolean),s=new Set(n.map(p=>p.id)),r=new Set(n.map(p=>p.name)),a=i.filter(p=>!s.has(p)&&!r.has(p));if(a.length){let p=n.map(l=>l.id).join(", ")||"(none)";throw new Error(`Unknown skill(s): ${a.join(", ")}. Available: ${p}`)}await _e("select",i,{dryRun:!!e["dry-run"]})}}),refresh:qe({meta:{name:"refresh",description:"Reinstall bundled skills into ~/.codex/skills"},args:{"dry-run":{type:"boolean",description:"Print actions without making changes"}},async run({args:e}){await _e("all",void 0,{dryRun:!!e["dry-run"]})}})}});var uo=Mn({meta:{name:"codex-1up",version:le,description:Yt},subCommands:{install:to,agents:no,doctor:io,uninstall:so,config:lo,update:po,tools:co,skills:fo}});Fn(uo);
|
package/package.json
CHANGED
|
@@ -1,24 +1,41 @@
|
|
|
1
|
-
|
|
1
|
+
## Non-negotiables
|
|
2
|
+
- Ship production-grade, scalable (>1000 users) implementations; avoid MVP/minimal shortcuts.
|
|
3
|
+
- Optimize for long-term sustainability: maintainable, reliable designs.
|
|
4
|
+
- Make changes the single canonical implementation in the primary codepath; delete legacy/dead/duplicate paths as part of delivery.
|
|
5
|
+
- Use direct, first-class integrations; do not introduce shims, wrappers, glue code, or adapter layers.
|
|
6
|
+
- Keep a single source of truth for business rules/policy (validation, enums, flags, constants, config).
|
|
7
|
+
- Clean API invariants: define required inputs, validate up front, fail fast.
|
|
8
|
+
- Use latest stable libs/docs; if unsure, do a web search.
|
|
9
|
+
## Codex behaviour
|
|
10
|
+
- If files change unexpectedly, assume parallel edits and continue; keep your diff scoped. Stop only for conflicts/breakage, then ask the user.
|
|
11
|
+
- When web searching, prefer 2026 (latest) sources/docs unless an older version is explicitly needed.
|
|
2
12
|
|
|
3
|
-
##
|
|
4
|
-
-
|
|
5
|
-
-
|
|
6
|
-
- List files in a directory: `fd . <directory>`
|
|
7
|
-
- Find files with extension and pattern: `fd -e <extension> <pattern>`
|
|
13
|
+
## Codex Prompts & Skills
|
|
14
|
+
- Skills live in repo `.codex/skills` and global `~/.codex/skills`; if `$<myskill>` isn’t found locally, explicitly load `~/.codex/skills/<myskill>/SKILL.md` (plus any `references/`/`scripts/`).
|
|
15
|
+
- Prompts live in `~/.codex/prompts/*.md`
|
|
8
16
|
|
|
9
|
-
##
|
|
10
|
-
-
|
|
11
|
-
-
|
|
12
|
-
- Prefer `ast-grep` over `rg`/`grep` when you need syntax-aware matching
|
|
17
|
+
## Coding Style
|
|
18
|
+
- Target <=500 LOC (hard cap 750; imports/types excluded).
|
|
19
|
+
- Keep UI/markup nesting <=3 levels; extract components/helpers when JSX/templating repeats, responsibilities pile up, or variant/conditional switches grow.
|
|
13
20
|
|
|
14
|
-
##
|
|
15
|
-
-
|
|
16
|
-
-
|
|
21
|
+
## Security guards
|
|
22
|
+
- No delete/move/overwrite without explicit user request; for deletions prefer `trash` over `rm`.
|
|
23
|
+
- Don’t expose secrets in code/logs; use env/secret stores.
|
|
24
|
+
- Validate/sanitize untrusted input to prevent injection, path traversal, SSRF, and unsafe uploads.
|
|
25
|
+
- Enforce AuthN/AuthZ and tenant boundaries; least privilege.
|
|
26
|
+
- Be cautious with new dependencies; flag supply-chain/CVE risk.
|
|
17
27
|
|
|
18
|
-
##
|
|
19
|
-
-
|
|
20
|
-
-
|
|
28
|
+
## Git operations
|
|
29
|
+
- Use `gh` CLI for GitHub operations (issues/PRs/releases).
|
|
30
|
+
- Ask before any `git push`.
|
|
31
|
+
- Prefer Conventional Commits (`feat:`, `fix:`, `docs:`, `refactor:`, etc.).
|
|
21
32
|
|
|
22
|
-
##
|
|
23
|
-
-
|
|
24
|
-
|
|
33
|
+
## Pull requests
|
|
34
|
+
- Keep PRs short and structured: **Why** (1–2 bullets), **How** (1–3 bullets), **Tests** (commands run + results).
|
|
35
|
+
- Create/manage PRs via `gh pr ...`.
|
|
36
|
+
- Avoid noise (logs/dumps); include only key context, risks, and screenshots when UX changes.
|
|
37
|
+
|
|
38
|
+
## When using the shell:
|
|
39
|
+
- Prefer built-in tools (e.g. `read_file`/`list_dir`/`grep_files`) over ad-hoc shell plumbing when available.
|
|
40
|
+
- For shell-based search: `fd` (files), `rg` (text), `ast-grep` (syntax-aware), `jq`/`yq` (extract/transform).
|
|
41
|
+
- Keep it deterministic and non-interactive; limit output (e.g. `head`) and pick a single result consistently.
|
|
@@ -42,7 +42,7 @@ approval_policy = "on-request"
|
|
|
42
42
|
sandbox_mode = "workspace-write"
|
|
43
43
|
model = "gpt-5.2-codex"
|
|
44
44
|
model_reasoning_effort = "medium"
|
|
45
|
-
model_reasoning_summary = "
|
|
45
|
+
model_reasoning_summary = "detailed"
|
|
46
46
|
[profiles.balanced.features]
|
|
47
47
|
web_search_request = true
|
|
48
48
|
|
|
@@ -51,7 +51,7 @@ approval_policy = "on-failure"
|
|
|
51
51
|
sandbox_mode = "read-only"
|
|
52
52
|
model = "gpt-5.2-codex"
|
|
53
53
|
model_reasoning_effort = "medium"
|
|
54
|
-
model_reasoning_summary = "
|
|
54
|
+
model_reasoning_summary = "detailed"
|
|
55
55
|
[profiles.safe.features]
|
|
56
56
|
web_search_request = false
|
|
57
57
|
|