{"_id":"@4pii4/cordex","_rev":"15-823a876e3d2c0b174a5cc1f601285eb5","name":"@4pii4/cordex","dist-tags":{"latest":"0.3.0"},"versions":{"0.1.0":{"name":"@4pii4/cordex","version":"0.1.0","keywords":["openai","codex","discord","bot","cli","developer-tools","automation"],"license":"GPL-3.0-only","_id":"@4pii4/cordex@0.1.0","maintainers":[{"name":"4pii4","email":"naivenevaii@gmail.com"}],"bin":{"cordex":"dist/cli.js"},"dist":{"shasum":"21d78109054ffcea41ccb8f82ec332c2385606a0","tarball":"https://registry.npmjs.org/@4pii4/cordex/-/cordex-0.1.0.tgz","fileCount":76,"integrity":"sha512-0TaKX19CRYR2FAf0Xok0l4dO/WpC89NUwZntWn4oI2vdiR4ddqZKE1RHEj2u4GQzMYJrUibL5qT4aH9cqLHWqg==","signatures":[{"sig":"MEUCICimu4tismmQXwAHN5dpQAmUKWgYFiUOfiCt9otXqeoxAiEA0xlnVLzBVQdVrAK+nxJyAxb5A/QxJwb6U7SOndd5QL8=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":644954},"type":"module","engines":{"node":">=22"},"gitHead":"681eb426ecffb057ed992daf0fc84a5eb78d3a18","private":false,"scripts":{"dev":"tsx src/cli.ts start","test":"node --import tsx --test test/*.test.ts","build":"npm run clean && tsc -p tsconfig.json","check":"npm run build && npm run typecheck:test && npm test","clean":"node --input-type=module -e \"import { rmSync } from 'node:fs'; rmSync('dist', { recursive: true, force: true })\"","start":"node dist/cli.js start","prepack":"npm run build","test:live":"cross-env CORDEX_LIVE_TEST=1 CORDEX_INPUT_TEST=1 CORDEX_WORKTREE_TEST=1 CORDEX_SCHEDULER_TEST=1 node --import tsx --test test/live-codex*.test.ts","test:live-all":"npm run test:live && npm run test:live-review && npm run test:live-approval && npm run test:live-login && npm run test:live-account && npm run test:live-mcp-config && npm run test:live-subagent && npm run test:live-action-buttons","prepublishOnly":"npm run check","typecheck:test":"tsc -p tsconfig.test.json","test:live-input":"cross-env CORDEX_INPUT_TEST=1 node --import tsx --test test/live-codex-input.test.ts","test:live-login":"cross-env CORDEX_LOGIN_TEST=1 node --import tsx --test test/live-codex-login.test.ts","test:live-review":"cross-env CORDEX_REVIEW_TEST=1 node --import tsx --test test/live-codex-review.test.ts","test:live-account":"cross-env CORDEX_ACCOUNT_TEST=1 node --import tsx --test test/live-codex-account.test.ts","test:live-approval":"cross-env CORDEX_APPROVAL_TEST=1 node --import tsx --test test/live-codex-approval.test.ts","test:live-subagent":"cross-env CORDEX_SUBAGENT_TEST=1 node --import tsx --test test/live-codex-subagent.test.ts","test:live-scheduler":"cross-env CORDEX_SCHEDULER_TEST=1 node --import tsx --test test/live-codex-scheduler.test.ts","test:live-mcp-config":"cross-env CORDEX_MCP_CONFIG_TEST=1 node --import tsx --test test/live-codex-mcp-config.test.ts","test:live-action-buttons":"cross-env CORDEX_ACTION_BUTTONS_TEST=1 node --import tsx --test test/live-codex-action-buttons.test.ts"},"_npmUser":{"name":"4pii4","email":"naivenevaii@gmail.com"},"_npmVersion":"10.9.7","description":"Control OpenAI Codex from Discord with persistent projects, sessions, approvals, and live output","directories":{},"_nodeVersion":"22.22.2","dependencies":{"discord.js":"^14.26.3"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsx":"^4.20.6","cross-env":"^10.1.0","typescript":"^5.9.3","@types/node":"^22.20.1"},"_npmOperationalInternal":{"tmp":"tmp/cordex_0.1.0_1784229872950_0.5929586937095015","host":"s3://npm-registry-packages-npm-production"}},"0.1.1":{"name":"@4pii4/cordex","version":"0.1.1","keywords":["openai","codex","discord","bot","cli","developer-tools","automation"],"license":"GPL-3.0-only","_id":"@4pii4/cordex@0.1.1","maintainers":[{"name":"4pii4","email":"naivenevaii@gmail.com"}],"bin":{"cordex":"dist/cli.js"},"dist":{"shasum":"d868cb09f5e51c6e3f83f08bc7e1726e26460803","tarball":"https://registry.npmjs.org/@4pii4/cordex/-/cordex-0.1.1.tgz","fileCount":76,"integrity":"sha512-jK6q/imjBsqosGWAd5hv87C/5yOpQpCRXXy0FGu2gYHzZkWND0+dxL0Ni4mr5DzSvyg6s2wWe32p8JrdSMbwMg==","signatures":[{"sig":"MEUCIBRlpZ5vtM3c1IrZlgUOmQwONW39JopQbcyjIabyzk2xAiEA5f40Ns0mbJ6GSWbvUs7Po8pQvXi95gkUpAsBTvAtNHc=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":646377},"type":"module","engines":{"node":">=22"},"gitHead":"65aa0076dfca2dffa705e2415c1a3991f2ae8dac","private":false,"scripts":{"dev":"tsx src/cli.ts start","test":"node --import tsx --test test/*.test.ts","build":"npm run clean && tsc -p tsconfig.json","check":"npm run build && npm run typecheck:test && npm test","clean":"node --input-type=module -e \"import { rmSync } from 'node:fs'; rmSync('dist', { recursive: true, force: true })\"","start":"node dist/cli.js start","prepack":"npm run build","test:live":"cross-env CORDEX_LIVE_TEST=1 CORDEX_INPUT_TEST=1 CORDEX_WORKTREE_TEST=1 CORDEX_SCHEDULER_TEST=1 node --import tsx --test test/live-codex*.test.ts","test:live-all":"npm run test:live && npm run test:live-review && npm run test:live-approval && npm run test:live-login && npm run test:live-account && npm run test:live-mcp-config && npm run test:live-subagent && npm run test:live-action-buttons","prepublishOnly":"npm run check","typecheck:test":"tsc -p tsconfig.test.json","test:live-input":"cross-env CORDEX_INPUT_TEST=1 node --import tsx --test test/live-codex-input.test.ts","test:live-login":"cross-env CORDEX_LOGIN_TEST=1 node --import tsx --test test/live-codex-login.test.ts","test:live-review":"cross-env CORDEX_REVIEW_TEST=1 node --import tsx --test test/live-codex-review.test.ts","test:live-account":"cross-env CORDEX_ACCOUNT_TEST=1 node --import tsx --test test/live-codex-account.test.ts","test:live-approval":"cross-env CORDEX_APPROVAL_TEST=1 node --import tsx --test test/live-codex-approval.test.ts","test:live-subagent":"cross-env CORDEX_SUBAGENT_TEST=1 node --import tsx --test test/live-codex-subagent.test.ts","test:live-scheduler":"cross-env CORDEX_SCHEDULER_TEST=1 node --import tsx --test test/live-codex-scheduler.test.ts","test:live-mcp-config":"cross-env CORDEX_MCP_CONFIG_TEST=1 node --import tsx --test test/live-codex-mcp-config.test.ts","test:live-action-buttons":"cross-env CORDEX_ACTION_BUTTONS_TEST=1 node --import tsx --test test/live-codex-action-buttons.test.ts"},"_npmUser":{"name":"4pii4","email":"naivenevaii@gmail.com"},"_npmVersion":"10.9.7","description":"Control OpenAI Codex from Discord with persistent projects, sessions, approvals, and live output","directories":{},"_nodeVersion":"22.22.2","dependencies":{"discord.js":"^14.26.3"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsx":"^4.20.6","cross-env":"^10.1.0","typescript":"^5.9.3","@types/node":"^22.20.1"},"_npmOperationalInternal":{"tmp":"tmp/cordex_0.1.1_1784261548992_0.42389780928921716","host":"s3://npm-registry-packages-npm-production"}},"0.1.2":{"name":"@4pii4/cordex","version":"0.1.2","keywords":["openai","codex","discord","bot","cli","developer-tools","automation"],"license":"GPL-3.0-only","_id":"@4pii4/cordex@0.1.2","maintainers":[{"name":"4pii4","email":"naivenevaii@gmail.com"}],"bin":{"cordex":"dist/cli.js"},"dist":{"shasum":"5e39d7921f535900cbffba54ee11e4d0741de447","tarball":"https://registry.npmjs.org/@4pii4/cordex/-/cordex-0.1.2.tgz","fileCount":88,"integrity":"sha512-rIA5e+xM1frROvyC26I56aCjYS6eqaQqBUFFhvCMRT2NOxxLVzifmzGuDqRhucePGQxzeHTW/WUjKrLpFwmkWw==","signatures":[{"sig":"MEYCIQCdUHFtk0pRv7fJruX0q52/tWdmLHwBuRlHR10v+jdj4QIhAKn3f5CUk3a8JioGQq0bZTTQoCSMJD48ajIjAFuqhHg2","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":1187667},"type":"module","engines":{"node":">=22"},"private":false,"scripts":{"dev":"tsx src/cli.ts start","test":"node --import tsx --test test/*.test.ts","build":"npm run clean && tsc -p tsconfig.json","check":"npm run build && npm run typecheck:test && npm test","clean":"node --input-type=module -e \"import { rmSync } from 'node:fs'; rmSync('dist', { recursive: true, force: true })\"","start":"node dist/cli.js start","prepack":"npm run build","test:live":"cross-env CORDEX_LIVE_TEST=1 CORDEX_INPUT_TEST=1 CORDEX_WORKTREE_TEST=1 CORDEX_SCHEDULER_TEST=1 node --import tsx --test test/live-codex*.test.ts","test:live-all":"npm run test:live && npm run test:live-review && npm run test:live-approval && npm run test:live-login && npm run test:live-account && npm run test:live-mcp-config && npm run test:live-subagent && npm run test:live-action-buttons","prepublishOnly":"npm run check","typecheck:test":"tsc -p tsconfig.test.json","test:live-input":"cross-env CORDEX_INPUT_TEST=1 node --import tsx --test test/live-codex-input.test.ts","test:live-login":"cross-env CORDEX_LOGIN_TEST=1 node --import tsx --test test/live-codex-login.test.ts","test:live-review":"cross-env CORDEX_REVIEW_TEST=1 node --import tsx --test test/live-codex-review.test.ts","test:live-account":"cross-env CORDEX_ACCOUNT_TEST=1 node --import tsx --test test/live-codex-account.test.ts","test:live-approval":"cross-env CORDEX_APPROVAL_TEST=1 node --import tsx --test test/live-codex-approval.test.ts","test:live-subagent":"cross-env CORDEX_SUBAGENT_TEST=1 node --import tsx --test test/live-codex-subagent.test.ts","test:live-scheduler":"cross-env CORDEX_SCHEDULER_TEST=1 node --import tsx --test test/live-codex-scheduler.test.ts","test:live-mcp-config":"cross-env CORDEX_MCP_CONFIG_TEST=1 node --import tsx --test test/live-codex-mcp-config.test.ts","test:live-action-buttons":"cross-env CORDEX_ACTION_BUTTONS_TEST=1 node --import tsx --test test/live-codex-action-buttons.test.ts"},"_npmUser":{"name":"4pii4","email":"naivenevaii@gmail.com"},"_npmVersion":"10.9.7","description":"Control OpenAI Codex from Discord with persistent projects, sessions, approvals, and live output","directories":{},"_nodeVersion":"22.22.2","dependencies":{"discord.js":"^14.26.3"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsx":"^4.20.6","cross-env":"^10.1.0","typescript":"^5.9.3","@types/node":"^22.20.1"},"_npmOperationalInternal":{"tmp":"tmp/cordex_0.1.2_1784375964450_0.9040972893552275","host":"s3://npm-registry-packages-npm-production"}},"0.1.3":{"name":"@4pii4/cordex","version":"0.1.3","keywords":["openai","codex","discord","bot","cli","developer-tools","automation"],"license":"GPL-3.0-only","_id":"@4pii4/cordex@0.1.3","maintainers":[{"name":"4pii4","email":"naivenevaii@gmail.com"}],"bin":{"cordex":"dist/cli.js"},"dist":{"shasum":"8dfc6e8a9fb1e42396a1a38644fc2ef05a97536b","tarball":"https://registry.npmjs.org/@4pii4/cordex/-/cordex-0.1.3.tgz","fileCount":94,"integrity":"sha512-APhWu4ZEeq7Qdd6xbZrlaVaV3UpIpJY8RjKq3u/64qJNJ5vVCi1sMzY5MHUustLG3NAax4+RLzVvYyr2XPZUuA==","signatures":[{"sig":"MEUCIH3A6bCjEl8zZwcyQSHPXjc8jNjS/uDsRfVw88jYvH0wAiEA70z7ynrq+n/Y14jgsgmsIj+OebQ2Oxg8OfGnjwQSatU=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":1419449},"type":"module","engines":{"node":">=22"},"private":false,"scripts":{"dev":"tsx src/cli.ts start","test":"node --import tsx --test test/*.test.ts","build":"npm run clean && tsc -p tsconfig.json","check":"npm run build && npm run typecheck:test && npm test","clean":"node --input-type=module -e \"import { rmSync } from 'node:fs'; rmSync('dist', { recursive: true, force: true })\"","start":"node dist/cli.js start","prepack":"npm run build","test:live":"cross-env CORDEX_LIVE_TEST=1 CORDEX_INPUT_TEST=1 CORDEX_WORKTREE_TEST=1 CORDEX_SCHEDULER_TEST=1 node --import tsx --test test/live-codex*.test.ts","test:live-all":"npm run test:live && npm run test:live-review && npm run test:live-approval && npm run test:live-login && npm run test:live-account && npm run test:live-mcp-config && npm run test:live-subagent && npm run test:live-action-buttons","prepublishOnly":"npm run check","typecheck:test":"tsc -p tsconfig.test.json","test:live-input":"cross-env CORDEX_INPUT_TEST=1 node --import tsx --test test/live-codex-input.test.ts","test:live-login":"cross-env CORDEX_LOGIN_TEST=1 node --import tsx --test test/live-codex-login.test.ts","test:live-review":"cross-env CORDEX_REVIEW_TEST=1 node --import tsx --test test/live-codex-review.test.ts","test:live-account":"cross-env CORDEX_ACCOUNT_TEST=1 node --import tsx --test test/live-codex-account.test.ts","test:live-approval":"cross-env CORDEX_APPROVAL_TEST=1 node --import tsx --test test/live-codex-approval.test.ts","test:live-subagent":"cross-env CORDEX_SUBAGENT_TEST=1 node --import tsx --test test/live-codex-subagent.test.ts","test:live-scheduler":"cross-env CORDEX_SCHEDULER_TEST=1 node --import tsx --test test/live-codex-scheduler.test.ts","test:live-mcp-config":"cross-env CORDEX_MCP_CONFIG_TEST=1 node --import tsx --test test/live-codex-mcp-config.test.ts","test:live-action-buttons":"cross-env CORDEX_ACTION_BUTTONS_TEST=1 node --import tsx --test test/live-codex-action-buttons.test.ts"},"_npmUser":{"name":"4pii4","email":"naivenevaii@gmail.com"},"_npmVersion":"10.9.7","description":"Control OpenAI Codex from Discord with persistent projects, sessions, approvals, and live output","directories":{},"_nodeVersion":"22.22.2","dependencies":{"discord.js":"^14.26.3"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsx":"^4.20.6","cross-env":"^10.1.0","typescript":"^5.9.3","@types/node":"^22.20.1"},"_npmOperationalInternal":{"tmp":"tmp/cordex_0.1.3_1784400843684_0.12040786613975651","host":"s3://npm-registry-packages-npm-production"}},"0.1.4":{"name":"@4pii4/cordex","version":"0.1.4","keywords":["openai","codex","discord","bot","cli","developer-tools","automation"],"license":"GPL-3.0-only","_id":"@4pii4/cordex@0.1.4","maintainers":[{"name":"4pii4","email":"naivenevaii@gmail.com"}],"bin":{"cordex":"dist/cli.js"},"dist":{"shasum":"3c34cef5a6d45c240f0eda489f1c1c7a891ca3a4","tarball":"https://registry.npmjs.org/@4pii4/cordex/-/cordex-0.1.4.tgz","fileCount":97,"integrity":"sha512-dRxnkpy7u1ufbbyxPQCqZ1fzUXE2V0pYzu+C92Y0/8iWM/Wfd3/2o1WhDgETdS65zPoWiXQ/yJGW0COY9QG/Uw==","signatures":[{"sig":"MEUCIQCLxJZ0HBdyjUOTGSYYlTLHCUnM7VRf5UJ63RISicPilgIgQ8eTnYhFsTmyFBXjy/bZvpUon0TymXRBw8XRjhLcbtA=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":1521756},"type":"module","engines":{"node":">=22"},"private":false,"scripts":{"dev":"tsx src/cli.ts start","test":"node --import tsx --test test/*.test.ts","build":"npm run clean && tsc -p tsconfig.json","check":"npm run build && npm run typecheck:test && npm test","clean":"node --input-type=module -e \"import { rmSync } from 'node:fs'; rmSync('dist', { recursive: true, force: true })\"","start":"node dist/cli.js start","prepack":"npm run build","test:live":"cross-env CORDEX_LIVE_TEST=1 CORDEX_INPUT_TEST=1 CORDEX_WORKTREE_TEST=1 CORDEX_SCHEDULER_TEST=1 node --import tsx --test test/live-codex*.test.ts","test:live-all":"npm run test:live && npm run test:live-review && npm run test:live-approval && npm run test:live-login && npm run test:live-account && npm run test:live-mcp-config && npm run test:live-subagent && npm run test:live-action-buttons","prepublishOnly":"npm run check","typecheck:test":"tsc -p tsconfig.test.json","test:live-input":"cross-env CORDEX_INPUT_TEST=1 node --import tsx --test test/live-codex-input.test.ts","test:live-login":"cross-env CORDEX_LOGIN_TEST=1 node --import tsx --test test/live-codex-login.test.ts","test:live-review":"cross-env CORDEX_REVIEW_TEST=1 node --import tsx --test test/live-codex-review.test.ts","test:live-account":"cross-env CORDEX_ACCOUNT_TEST=1 node --import tsx --test test/live-codex-account.test.ts","test:live-approval":"cross-env CORDEX_APPROVAL_TEST=1 node --import tsx --test test/live-codex-approval.test.ts","test:live-subagent":"cross-env CORDEX_SUBAGENT_TEST=1 node --import tsx --test test/live-codex-subagent.test.ts","test:live-scheduler":"cross-env CORDEX_SCHEDULER_TEST=1 node --import tsx --test test/live-codex-scheduler.test.ts","test:live-mcp-config":"cross-env CORDEX_MCP_CONFIG_TEST=1 node --import tsx --test test/live-codex-mcp-config.test.ts","test:live-action-buttons":"cross-env CORDEX_ACTION_BUTTONS_TEST=1 node --import tsx --test test/live-codex-action-buttons.test.ts"},"_npmUser":{"name":"4pii4","email":"naivenevaii@gmail.com"},"_npmVersion":"10.9.7","description":"Control OpenAI Codex from Discord with persistent projects, sessions, approvals, and live output","directories":{},"_nodeVersion":"22.22.2","dependencies":{"discord.js":"^14.26.3"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsx":"^4.20.6","cross-env":"^10.1.0","typescript":"^5.9.3","@types/node":"^22.20.1"},"_npmOperationalInternal":{"tmp":"tmp/cordex_0.1.4_1784403238292_0.5339187633303732","host":"s3://npm-registry-packages-npm-production"}},"0.1.5":{"name":"@4pii4/cordex","version":"0.1.5","keywords":["openai","codex","discord","bot","cli","developer-tools","automation"],"license":"GPL-3.0-only","_id":"@4pii4/cordex@0.1.5","maintainers":[{"name":"4pii4","email":"naivenevaii@gmail.com"}],"bin":{"cordex":"dist/cli.js"},"dist":{"shasum":"831a77c6a883225efd99c5af07a1a586b1d57c0f","tarball":"https://registry.npmjs.org/@4pii4/cordex/-/cordex-0.1.5.tgz","fileCount":97,"integrity":"sha512-pBnGkGdqSafic2RSla111f0NniEzEoPiuOmg/Wn3/8F6HqwFsNSBpnTWNFz4Pc+SfbJHbnlhN3zb7qSreMEM1g==","signatures":[{"sig":"MEQCIFs7GchloTf77AFJ0Db4cGD2UjN1u+dKOHY3EeVy/4GkAiARKvpG7Nsifh9RQRRdIuRLVpg2o+Jwu+ifF/GYUU9Heg==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":1525721},"type":"module","engines":{"node":">=22"},"private":false,"scripts":{"dev":"tsx src/cli.ts start","test":"node --import tsx --test test/*.test.ts","build":"npm run clean && tsc -p tsconfig.json","check":"npm run build && npm run typecheck:test && npm test","clean":"node --input-type=module -e \"import { rmSync } from 'node:fs'; rmSync('dist', { recursive: true, force: true })\"","start":"node dist/cli.js start","prepack":"npm run build","test:live":"cross-env CORDEX_LIVE_TEST=1 CORDEX_INPUT_TEST=1 CORDEX_WORKTREE_TEST=1 CORDEX_SCHEDULER_TEST=1 node --import tsx --test test/live-codex*.test.ts","test:live-all":"npm run test:live && npm run test:live-review && npm run test:live-approval && npm run test:live-login && npm run test:live-account && npm run test:live-mcp-config && npm run test:live-subagent && npm run test:live-action-buttons","prepublishOnly":"npm run check","typecheck:test":"tsc -p tsconfig.test.json","test:live-input":"cross-env CORDEX_INPUT_TEST=1 node --import tsx --test test/live-codex-input.test.ts","test:live-login":"cross-env CORDEX_LOGIN_TEST=1 node --import tsx --test test/live-codex-login.test.ts","test:live-review":"cross-env CORDEX_REVIEW_TEST=1 node --import tsx --test test/live-codex-review.test.ts","test:live-account":"cross-env CORDEX_ACCOUNT_TEST=1 node --import tsx --test test/live-codex-account.test.ts","test:live-approval":"cross-env CORDEX_APPROVAL_TEST=1 node --import tsx --test test/live-codex-approval.test.ts","test:live-subagent":"cross-env CORDEX_SUBAGENT_TEST=1 node --import tsx --test test/live-codex-subagent.test.ts","test:live-scheduler":"cross-env CORDEX_SCHEDULER_TEST=1 node --import tsx --test test/live-codex-scheduler.test.ts","test:live-mcp-config":"cross-env CORDEX_MCP_CONFIG_TEST=1 node --import tsx --test test/live-codex-mcp-config.test.ts","test:live-action-buttons":"cross-env CORDEX_ACTION_BUTTONS_TEST=1 node --import tsx --test test/live-codex-action-buttons.test.ts"},"_npmUser":{"name":"4pii4","email":"naivenevaii@gmail.com"},"_npmVersion":"10.9.7","description":"Control OpenAI Codex from Discord with persistent projects, sessions, approvals, and live output","directories":{},"_nodeVersion":"22.22.2","dependencies":{"discord.js":"^14.26.3"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsx":"^4.20.6","cross-env":"^10.1.0","typescript":"^5.9.3","@types/node":"^22.20.1"},"_npmOperationalInternal":{"tmp":"tmp/cordex_0.1.5_1784404699845_0.5948694683174887","host":"s3://npm-registry-packages-npm-production"}},"0.1.6":{"name":"@4pii4/cordex","version":"0.1.6","keywords":["openai","codex","discord","bot","cli","developer-tools","automation"],"license":"GPL-3.0-only","_id":"@4pii4/cordex@0.1.6","maintainers":[{"name":"4pii4","email":"naivenevaii@gmail.com"}],"bin":{"cordex":"dist/cli.js"},"dist":{"shasum":"24a3fa3c411ce25575127d1e2104844d5542c4e0","tarball":"https://registry.npmjs.org/@4pii4/cordex/-/cordex-0.1.6.tgz","fileCount":97,"integrity":"sha512-oZ+AwoG8AfvAJwGGm3eqMh/hog7lYP7gzPytp4NwPw/zoFCxVmNuU5+0hscs6vGbpnZrrOQGDFDIs23tBINNSQ==","signatures":[{"sig":"MEUCIQC3SYEr6tNuxNS9sC4p2kZN2yYM2d3rw9GU3vFEhmooXAIgR0hBzxzVwCrwe5bxCe9ytfxOTVDz2USOeA0pEPY1ViA=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":1526630},"type":"module","engines":{"node":">=22"},"gitHead":"a6b82cfbebd8ce5cb55cb018e4b8869c45f12b73","private":false,"scripts":{"dev":"tsx src/cli.ts start","test":"node --import tsx --test test/*.test.ts","build":"npm run clean && tsc -p tsconfig.json","check":"npm run build && npm run typecheck:test && npm test","clean":"node --input-type=module -e \"import { rmSync } from 'node:fs'; rmSync('dist', { recursive: true, force: true })\"","start":"node dist/cli.js start","prepack":"npm run build","test:live":"cross-env CORDEX_LIVE_TEST=1 CORDEX_INPUT_TEST=1 CORDEX_WORKTREE_TEST=1 CORDEX_SCHEDULER_TEST=1 node --import tsx --test test/live-codex*.test.ts","test:live-all":"npm run test:live && npm run test:live-review && npm run test:live-approval && npm run test:live-login && npm run test:live-account && npm run test:live-mcp-config && npm run test:live-subagent && npm run test:live-action-buttons","prepublishOnly":"npm run check","typecheck:test":"tsc -p tsconfig.test.json","test:live-input":"cross-env CORDEX_INPUT_TEST=1 node --import tsx --test test/live-codex-input.test.ts","test:live-login":"cross-env CORDEX_LOGIN_TEST=1 node --import tsx --test test/live-codex-login.test.ts","test:live-review":"cross-env CORDEX_REVIEW_TEST=1 node --import tsx --test test/live-codex-review.test.ts","test:live-account":"cross-env CORDEX_ACCOUNT_TEST=1 node --import tsx --test test/live-codex-account.test.ts","test:live-approval":"cross-env CORDEX_APPROVAL_TEST=1 node --import tsx --test test/live-codex-approval.test.ts","test:live-subagent":"cross-env CORDEX_SUBAGENT_TEST=1 node --import tsx --test test/live-codex-subagent.test.ts","test:live-scheduler":"cross-env CORDEX_SCHEDULER_TEST=1 node --import tsx --test test/live-codex-scheduler.test.ts","test:live-mcp-config":"cross-env CORDEX_MCP_CONFIG_TEST=1 node --import tsx --test test/live-codex-mcp-config.test.ts","test:live-action-buttons":"cross-env CORDEX_ACTION_BUTTONS_TEST=1 node --import tsx --test test/live-codex-action-buttons.test.ts"},"_npmUser":{"name":"4pii4","email":"naivenevaii@gmail.com"},"_npmVersion":"10.9.7","description":"Control OpenAI Codex from Discord with persistent projects, sessions, approvals, and live output","directories":{},"_nodeVersion":"22.22.2","dependencies":{"discord.js":"^14.26.3"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsx":"^4.20.6","cross-env":"^10.1.0","typescript":"^5.9.3","@types/node":"^22.20.1"},"_npmOperationalInternal":{"tmp":"tmp/cordex_0.1.6_1785562768779_0.5951419424094506","host":"s3://npm-registry-packages-npm-production"}},"0.1.7":{"name":"@4pii4/cordex","version":"0.1.7","keywords":["openai","codex","discord","bot","cli","developer-tools","automation"],"license":"GPL-3.0-only","_id":"@4pii4/cordex@0.1.7","maintainers":[{"name":"4pii4","email":"naivenevaii@gmail.com"}],"bin":{"cordex":"dist/cli.js"},"dist":{"shasum":"0ea62c97d4a424cd4fbeda42ab28913cf971114e","tarball":"https://registry.npmjs.org/@4pii4/cordex/-/cordex-0.1.7.tgz","fileCount":100,"integrity":"sha512-Td0ehDxvfV1VfwI18FFz8lvuMNxhe5R8LLm6cvE/AeFzUOlR+JxVKngvPNI589FwOcfNyuCokEAv6mLSn5GsEA==","signatures":[{"sig":"MEYCIQCs8yfXnbK5aPyDK6h8LHLDrcPu3A0kPf77MxyeFWVC3gIhAIkmp4srlyXDxOu+a2AmeAqk5TFp3pdaklvufpkiQXJ4","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":1632540},"type":"module","engines":{"node":">=22"},"gitHead":"1f69ba876997b322c30e42114f77deba4f9649d2","private":false,"scripts":{"dev":"tsx src/cli.ts start","test":"node --import tsx --test test/*.test.ts","build":"npm run clean && tsc -p tsconfig.json","check":"npm run build && npm run typecheck:test && npm test","clean":"node --input-type=module -e \"import { rmSync } from 'node:fs'; rmSync('dist', { recursive: true, force: true })\"","start":"node dist/cli.js start","prepack":"npm run build","test:live":"cross-env CORDEX_LIVE_TEST=1 CORDEX_INPUT_TEST=1 CORDEX_WORKTREE_TEST=1 CORDEX_SCHEDULER_TEST=1 node --import tsx --test test/live-codex*.test.ts","test:live-all":"npm run test:live && npm run test:live-review && npm run test:live-approval && npm run test:live-login && npm run test:live-account && npm run test:live-mcp-config && npm run test:live-subagent && npm run test:live-action-buttons","prepublishOnly":"npm run check","typecheck:test":"tsc -p tsconfig.test.json","test:live-input":"cross-env CORDEX_INPUT_TEST=1 node --import tsx --test test/live-codex-input.test.ts","test:live-login":"cross-env CORDEX_LOGIN_TEST=1 node --import tsx --test test/live-codex-login.test.ts","test:live-review":"cross-env CORDEX_REVIEW_TEST=1 node --import tsx --test test/live-codex-review.test.ts","test:live-account":"cross-env CORDEX_ACCOUNT_TEST=1 node --import tsx --test test/live-codex-account.test.ts","test:live-approval":"cross-env CORDEX_APPROVAL_TEST=1 node --import tsx --test test/live-codex-approval.test.ts","test:live-subagent":"cross-env CORDEX_SUBAGENT_TEST=1 node --import tsx --test test/live-codex-subagent.test.ts","test:live-scheduler":"cross-env CORDEX_SCHEDULER_TEST=1 node --import tsx --test test/live-codex-scheduler.test.ts","test:live-mcp-config":"cross-env CORDEX_MCP_CONFIG_TEST=1 node --import tsx --test test/live-codex-mcp-config.test.ts","test:live-action-buttons":"cross-env CORDEX_ACTION_BUTTONS_TEST=1 node --import tsx --test test/live-codex-action-buttons.test.ts"},"_npmUser":{"name":"4pii4","email":"naivenevaii@gmail.com"},"_npmVersion":"10.9.7","description":"Control OpenAI Codex from Discord with persistent projects, sessions, approvals, and live output","directories":{},"_nodeVersion":"22.22.2","dependencies":{"discord.js":"^14.26.3"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsx":"^4.20.6","cross-env":"^10.1.0","typescript":"^5.9.3","@types/node":"^22.20.1"},"_npmOperationalInternal":{"tmp":"tmp/cordex_0.1.7_1785570683290_0.3271805461503283","host":"s3://npm-registry-packages-npm-production"}},"0.2.0":{"name":"@4pii4/cordex","version":"0.2.0","keywords":["openai","codex","discord","bot","cli","developer-tools","automation"],"license":"GPL-3.0-only","_id":"@4pii4/cordex@0.2.0","maintainers":[{"name":"4pii4","email":"naivenevaii@gmail.com"}],"bin":{"cordex":"dist/cli.js"},"dist":{"shasum":"2b4c7b46671b11a7dcd1e212761179ce24e01f8e","tarball":"https://registry.npmjs.org/@4pii4/cordex/-/cordex-0.2.0.tgz","fileCount":7,"integrity":"sha512-BTYmN4hg/Ue0puMGhZRHnNlFKEKKRi7+cA2PPsxxZeFeTFH00iA6ORNjMrZdGp6hN2yOxoawlZu41bWszy7jDg==","signatures":[{"sig":"MEQCIFG1PWyohoYonSKspKqK7PjtbPrOUWTVzJDfzug2oNqiAiBsD4eTFv7k1zEyudV7M1wqSu88w0oQMZdFVg0fCc3peA==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"sig":"MEQCIGk6lTHgSHW/2gYeMvmg2FWwqLJc4SvNoxgPV7aoInQFAiApH2KfaC+amwkgRt6Bj0gMQatpbuAv/kHq2e7/22bpRA==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":94304},"type":"module","engines":{"node":">=22"},"gitHead":"aa0e19751f05e9c17741ae2a02b2fbc2e07484e4","private":false,"scripts":{"dev":"tsx src/cli.ts start","test":"node --import tsx --test test/*.test.ts","build":"npm run clean && tsc -p tsconfig.json","check":"npm run build && npm run typecheck:test && npm test","clean":"node --input-type=module -e \"import { rmSync } from 'node:fs'; rmSync('dist', { recursive: true, force: true })\"","start":"node dist/cli.js start","prepack":"npm run build","test:live":"cross-env CORDEX_LIVE_TEST=1 CORDEX_INPUT_TEST=1 CORDEX_WORKTREE_TEST=1 CORDEX_SCHEDULER_TEST=1 node --import tsx --test test/live-codex*.test.ts","test:live-all":"npm run test:live && npm run test:live-review && npm run test:live-approval && npm run test:live-discord-controls && npm run test:live-login && npm run test:live-account && npm run test:live-mcp-config && npm run test:live-mcp-reload && npm run test:live-mcp-elicitation && npm run test:live-subagent && npm run test:live-action-buttons && npm run test:live-output-retry && npm run test:live-progress && npm run test:live-startup-progress && npm run test:live-direct-recovery && npm run test:live-ambiguous-delivery && npm run test:live-model-notices && npm run test:live-status && npm run test:live-generated-image && npm run test:live-file-upload && npm run test:live-file-upload-tool && npm run test:live-background-notice && npm run test:live-session-history && npm run test:live-extensions && npm run test:live-plugin-lifecycle && npm run test:live-lifecycle","prepublishOnly":"npm run check","typecheck:test":"tsc -p tsconfig.test.json","test:live-input":"cross-env CORDEX_INPUT_TEST=1 node --import tsx --test test/live-codex-input.test.ts","test:live-login":"cross-env CORDEX_LOGIN_TEST=1 node --import tsx --test test/live-codex-login.test.ts","test:live-review":"cross-env CORDEX_REVIEW_TEST=1 node --import tsx --test test/live-codex-review.test.ts","test:live-status":"cross-env CORDEX_STATUS_TEST=1 node --import tsx --test test/live-codex-status.test.ts","test:live-account":"cross-env CORDEX_ACCOUNT_TEST=1 node --import tsx --test test/live-codex-account.test.ts","test:live-approval":"cross-env CORDEX_APPROVAL_TEST=1 node --import tsx --test test/live-codex-approval.test.ts","test:live-evidence":"node scripts/live-e2e-runner.mjs start","test:live-progress":"cross-env CORDEX_SILENT_PROGRESS_TEST=1 node --import tsx --test test/live-codex-silent-progress.test.ts","test:live-subagent":"cross-env CORDEX_SUBAGENT_TEST=1 node --import tsx --test test/live-codex-subagent.test.ts","test:live-lifecycle":"cross-env CORDEX_LIFECYCLE_TEST=1 node --import tsx --test test/live-codex-lifecycle.test.ts","test:live-scheduler":"cross-env CORDEX_SCHEDULER_TEST=1 node --import tsx --test test/live-codex-scheduler.test.ts","test:live-extensions":"cross-env CORDEX_EXTENSIONS_TEST=1 node --import tsx --test test/live-codex-extensions.test.ts","test:live-mcp-config":"cross-env CORDEX_MCP_CONFIG_TEST=1 node --import tsx --test test/live-codex-mcp-config.test.ts","test:live-mcp-reload":"cross-env CORDEX_MCP_RELOAD_TEST=1 node --import tsx --test test/live-codex-mcp-reload.test.ts","test:live-file-upload":"cross-env CORDEX_FILE_UPLOAD_TEST=1 node --import tsx --test test/live-codex-file-upload.test.ts","test:live-output-retry":"cross-env CORDEX_OUTPUT_RETRY_TEST=1 node --import tsx --test test/live-codex-output-retry.test.ts","test:live-model-notices":"cross-env CORDEX_MODEL_NOTICES_TEST=1 node --import tsx --test test/live-codex-model-notices.test.ts","test:live-action-buttons":"cross-env CORDEX_ACTION_BUTTONS_TEST=1 node --import tsx --test test/live-codex-action-buttons.test.ts","test:live-direct-recovery":"cross-env CORDEX_DIRECT_RECOVERY_TEST=1 node --import tsx --test test/live-codex-direct-recovery.test.ts","test:live-generated-image":"cross-env CORDEX_GENERATED_IMAGE_TEST=1 node --import tsx --test test/live-codex-generated-image.test.ts","test:live-mcp-elicitation":"cross-env CORDEX_MCP_ELICITATION_TEST=1 node --import tsx --test test/live-codex-mcp-elicitation.test.ts","test:live-session-history":"cross-env CORDEX_SESSION_HISTORY_TEST=1 node --import tsx --test test/live-codex-session-history.test.ts","test:live-discord-controls":"cross-env CORDEX_DISCORD_CONTROLS_TEST=1 node --import tsx --test test/live-codex-discord-controls.test.ts","test:live-file-upload-tool":"cross-env CORDEX_FILE_UPLOAD_TOOL_TEST=1 node --import tsx --test test/live-codex-file-upload-tool.test.ts","test:live-plugin-lifecycle":"cross-env CORDEX_PLUGIN_LIFECYCLE_TEST=1 node --import tsx --test test/live-codex-plugin-lifecycle.test.ts","test:live-startup-progress":"cross-env CORDEX_STARTUP_PROGRESS_TEST=1 node --import tsx --test test/live-codex-startup-progress.test.ts","test:live-background-notice":"cross-env CORDEX_BACKGROUND_NOTICE_TEST=1 node --import tsx --test test/live-codex-background-notice.test.ts","test:live-ambiguous-delivery":"cross-env CORDEX_AMBIGUOUS_DELIVERY_TEST=1 node --import tsx --test test/live-codex-ambiguous-delivery.test.ts"},"_npmUser":{"name":"4pii4","email":"naivenevaii@gmail.com"},"deprecated":"Broken npm tarball: compiled dist files are missing. Use 0.2.1.","_npmVersion":"10.9.8","description":"Control OpenAI Codex from Discord with persistent projects, sessions, approvals, and live output","directories":{},"_nodeVersion":"22.23.1","dependencies":{"discord.js":"^14.26.3"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsx":"^4.20.6","cross-env":"^10.1.0","typescript":"^5.9.3","@types/node":"^22.20.1"},"_npmOperationalInternal":{"tmp":"tmp/cordex_0.2.0_1790610969152_0.9866175387756071","host":"s3://npm-registry-packages-npm-production"}},"0.2.1":{"name":"@4pii4/cordex","version":"0.2.1","keywords":["openai","codex","discord","bot","cli","developer-tools","automation"],"license":"GPL-3.0-only","_id":"@4pii4/cordex@0.2.1","maintainers":[{"name":"4pii4","email":"naivenevaii@gmail.com"}],"bin":{"cordex":"dist/cli.js"},"dist":{"shasum":"3b29c86f48cddc4902ca21b1c67b85b62af1ed5e","tarball":"https://registry.npmjs.org/@4pii4/cordex/-/cordex-0.2.1.tgz","fileCount":112,"integrity":"sha512-BAV8zKZpVNlEpKBGs/M6T2nUzGOqhTU25Z38yznd8YWGGeNUV0Cihpi68gfGHQqGMM46xDZ5xs9MxNPcH1MKiA==","signatures":[{"sig":"MEUCIQCVb3B3HXe5XKc5RibnHgQcZiHsrMEqomg1EexPnhv3FQIgDZcweCFNFiwg41+JeNnxA+YVMspoBBNi+PBJj/KBV3Q=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"sig":"MEUCICNLOw5Tp7++4RiwtGPK2Unl+aVHagdPB4llOaKLVWXNAiEAupCE8GggbidqtPxzyGFU8EkfulULtMcyeU3dfbiS12Q=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":1973925},"type":"module","_from":"file:/tmp/cordex-pack-021-jn4qAU/4pii4-cordex-0.2.1.tgz","engines":{"node":">=22"},"private":false,"scripts":{"dev":"tsx src/cli.ts start","test":"node --import tsx --test test/*.test.ts","build":"npm run clean && tsc -p tsconfig.json","check":"npm run build && npm run typecheck:test && npm test","clean":"node --input-type=module -e \"import { rmSync } from 'node:fs'; rmSync('dist', { recursive: true, force: true })\"","start":"node dist/cli.js start","prepack":"npm run build","test:live":"cross-env CORDEX_LIVE_TEST=1 CORDEX_INPUT_TEST=1 CORDEX_WORKTREE_TEST=1 CORDEX_SCHEDULER_TEST=1 node --import tsx --test test/live-codex*.test.ts","test:live-all":"npm run test:live && npm run test:live-review && npm run test:live-approval && npm run test:live-discord-controls && npm run test:live-login && npm run test:live-account && npm run test:live-mcp-config && npm run test:live-mcp-reload && npm run test:live-mcp-elicitation && npm run test:live-subagent && npm run test:live-action-buttons && npm run test:live-output-retry && npm run test:live-progress && npm run test:live-startup-progress && npm run test:live-direct-recovery && npm run test:live-ambiguous-delivery && npm run test:live-model-notices && npm run test:live-status && npm run test:live-generated-image && npm run test:live-file-upload && npm run test:live-file-upload-tool && npm run test:live-background-notice && npm run test:live-session-history && npm run test:live-extensions && npm run test:live-plugin-lifecycle && npm run test:live-lifecycle","prepublishOnly":"npm run check","typecheck:test":"tsc -p tsconfig.test.json","test:live-input":"cross-env CORDEX_INPUT_TEST=1 node --import tsx --test test/live-codex-input.test.ts","test:live-login":"cross-env CORDEX_LOGIN_TEST=1 node --import tsx --test test/live-codex-login.test.ts","test:live-review":"cross-env CORDEX_REVIEW_TEST=1 node --import tsx --test test/live-codex-review.test.ts","test:live-status":"cross-env CORDEX_STATUS_TEST=1 node --import tsx --test test/live-codex-status.test.ts","test:live-account":"cross-env CORDEX_ACCOUNT_TEST=1 node --import tsx --test test/live-codex-account.test.ts","test:live-approval":"cross-env CORDEX_APPROVAL_TEST=1 node --import tsx --test test/live-codex-approval.test.ts","test:live-evidence":"node scripts/live-e2e-runner.mjs start","test:live-progress":"cross-env CORDEX_SILENT_PROGRESS_TEST=1 node --import tsx --test test/live-codex-silent-progress.test.ts","test:live-subagent":"cross-env CORDEX_SUBAGENT_TEST=1 node --import tsx --test test/live-codex-subagent.test.ts","test:live-lifecycle":"cross-env CORDEX_LIFECYCLE_TEST=1 node --import tsx --test test/live-codex-lifecycle.test.ts","test:live-scheduler":"cross-env CORDEX_SCHEDULER_TEST=1 node --import tsx --test test/live-codex-scheduler.test.ts","test:live-extensions":"cross-env CORDEX_EXTENSIONS_TEST=1 node --import tsx --test test/live-codex-extensions.test.ts","test:live-mcp-config":"cross-env CORDEX_MCP_CONFIG_TEST=1 node --import tsx --test test/live-codex-mcp-config.test.ts","test:live-mcp-reload":"cross-env CORDEX_MCP_RELOAD_TEST=1 node --import tsx --test test/live-codex-mcp-reload.test.ts","test:live-file-upload":"cross-env CORDEX_FILE_UPLOAD_TEST=1 node --import tsx --test test/live-codex-file-upload.test.ts","test:live-output-retry":"cross-env CORDEX_OUTPUT_RETRY_TEST=1 node --import tsx --test test/live-codex-output-retry.test.ts","test:live-model-notices":"cross-env CORDEX_MODEL_NOTICES_TEST=1 node --import tsx --test test/live-codex-model-notices.test.ts","test:live-action-buttons":"cross-env CORDEX_ACTION_BUTTONS_TEST=1 node --import tsx --test test/live-codex-action-buttons.test.ts","test:live-direct-recovery":"cross-env CORDEX_DIRECT_RECOVERY_TEST=1 node --import tsx --test test/live-codex-direct-recovery.test.ts","test:live-generated-image":"cross-env CORDEX_GENERATED_IMAGE_TEST=1 node --import tsx --test test/live-codex-generated-image.test.ts","test:live-mcp-elicitation":"cross-env CORDEX_MCP_ELICITATION_TEST=1 node --import tsx --test test/live-codex-mcp-elicitation.test.ts","test:live-session-history":"cross-env CORDEX_SESSION_HISTORY_TEST=1 node --import tsx --test test/live-codex-session-history.test.ts","test:live-discord-controls":"cross-env CORDEX_DISCORD_CONTROLS_TEST=1 node --import tsx --test test/live-codex-discord-controls.test.ts","test:live-file-upload-tool":"cross-env CORDEX_FILE_UPLOAD_TOOL_TEST=1 node --import tsx --test test/live-codex-file-upload-tool.test.ts","test:live-plugin-lifecycle":"cross-env CORDEX_PLUGIN_LIFECYCLE_TEST=1 node --import tsx --test test/live-codex-plugin-lifecycle.test.ts","test:live-startup-progress":"cross-env CORDEX_STARTUP_PROGRESS_TEST=1 node --import tsx --test test/live-codex-startup-progress.test.ts","test:live-background-notice":"cross-env CORDEX_BACKGROUND_NOTICE_TEST=1 node --import tsx --test test/live-codex-background-notice.test.ts","test:live-ambiguous-delivery":"cross-env CORDEX_AMBIGUOUS_DELIVERY_TEST=1 node --import tsx --test test/live-codex-ambiguous-delivery.test.ts"},"_npmUser":{"name":"4pii4","email":"naivenevaii@gmail.com"},"_resolved":"/tmp/cordex-pack-021-jn4qAU/4pii4-cordex-0.2.1.tgz","_integrity":"sha512-BAV8zKZpVNlEpKBGs/M6T2nUzGOqhTU25Z38yznd8YWGGeNUV0Cihpi68gfGHQqGMM46xDZ5xs9MxNPcH1MKiA==","_npmVersion":"10.9.8","description":"Control OpenAI Codex from Discord with persistent projects, sessions, approvals, and live output","directories":{},"_nodeVersion":"22.23.1","dependencies":{"discord.js":"^14.26.3"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"tsx":"^4.20.6","cross-env":"^10.1.0","typescript":"^5.9.3","@types/node":"^22.20.1"},"_npmOperationalInternal":{"tmp":"tmp/cordex_0.2.1_1790611333487_0.8542666228702991","host":"s3://npm-registry-packages-npm-production"}},"0.3.0":{"_id":"@4pii4/cordex@0.3.0","bin":{"cordex":"dist/cli.js"},"dist":{"shasum":"daa3b8f549bdc520ef3233aa207a4275bb53a3f4","tarball":"https://registry.npmjs.org/@4pii4/cordex/-/cordex-0.3.0.tgz","fileCount":121,"integrity":"sha512-c691aYguR8tGwv6fOli2j0ICNTeHisJekGNvNqThO5fuhoNHnqZQ7p3Z6v86mvO8GnOwOYKA4qzyXEWVibzV+Q==","signatures":[{"sig":"MEUCIA1qROUvGldLMgpwz0Dr1Si1qNXqv9haPtWUQhluR6+bAiEAnFG+nEU2Gz9gZsHawGv+hCCf+FoAaooIXrgpMFKZNLc=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEQCIAz5D9+KNQSO9Xu4jVlGDqg8u/n4YYHhK/OlKGRaV6TFAiAGQ96QT54oWUTrVLL/FaW9hhoffu5ub0gMyQI7XlR3IQ=="}],"unpackedSize":2079325},"name":"@4pii4/cordex","type":"module","_from":"file:/tmp/cordex-release-030-OAD1QD/4pii4-cordex-0.3.0.tgz","engines":{"node":">=22"},"license":"GPL-3.0-only","private":false,"scripts":{"dev":"tsx src/cli.ts start","test":"node scripts/run-tests-isolated.mjs","build":"npm run clean && tsc -p tsconfig.json","check":"npm run build && npm run typecheck:test && npm test","clean":"node --input-type=module -e \"import { rmSync } from 'node:fs'; rmSync('dist', { recursive: true, force: true })\"","start":"node dist/cli.js start","prepack":"npm run build","test:live":"cross-env CORDEX_LIVE_TEST=1 CORDEX_INPUT_TEST=1 CORDEX_WORKTREE_TEST=1 CORDEX_SCHEDULER_TEST=1 node --import tsx --test test/live-codex*.test.ts","test:live-all":"npm run test:live && npm run test:live-review && npm run test:live-approval && npm run test:live-discord-controls && npm run test:live-login && npm run test:live-account && npm run test:live-mcp-config && npm run test:live-mcp-reload && npm run test:live-mcp-elicitation && npm run test:live-subagent && npm run test:live-action-buttons && npm run test:live-output-retry && npm run test:live-progress && npm run test:live-startup-progress && npm run test:live-direct-recovery && npm run test:live-ambiguous-delivery && npm run test:live-model-notices && npm run test:live-status && npm run test:live-generated-image && npm run test:live-file-upload && npm run test:live-file-upload-tool && npm run test:live-background-notice && npm run test:live-session-history && npm run test:live-extensions && npm run test:live-plugin-lifecycle && npm run test:live-lifecycle","prepublishOnly":"npm run check","typecheck:test":"tsc -p tsconfig.test.json","test:live-input":"cross-env CORDEX_INPUT_TEST=1 node --import tsx --test test/live-codex-input.test.ts","test:live-login":"cross-env CORDEX_LOGIN_TEST=1 node --import tsx --test test/live-codex-login.test.ts","test:live-review":"cross-env CORDEX_REVIEW_TEST=1 node --import tsx --test test/live-codex-review.test.ts","test:live-status":"cross-env CORDEX_STATUS_TEST=1 node --import tsx --test test/live-codex-status.test.ts","test:live-account":"cross-env CORDEX_ACCOUNT_TEST=1 node --import tsx --test test/live-codex-account.test.ts","test:live-approval":"cross-env CORDEX_APPROVAL_TEST=1 node --import tsx --test test/live-codex-approval.test.ts","test:live-evidence":"node scripts/live-e2e-runner.mjs start","test:live-progress":"cross-env CORDEX_SILENT_PROGRESS_TEST=1 node --import tsx --test test/live-codex-silent-progress.test.ts","test:live-subagent":"cross-env CORDEX_SUBAGENT_TEST=1 node --import tsx --test test/live-codex-subagent.test.ts","test:live-lifecycle":"cross-env CORDEX_LIFECYCLE_TEST=1 node --import tsx --test test/live-codex-lifecycle.test.ts","test:live-scheduler":"cross-env CORDEX_SCHEDULER_TEST=1 node --import tsx --test test/live-codex-scheduler.test.ts","test:live-extensions":"cross-env CORDEX_EXTENSIONS_TEST=1 node --import tsx --test test/live-codex-extensions.test.ts","test:live-mcp-config":"cross-env CORDEX_MCP_CONFIG_TEST=1 node --import tsx --test test/live-codex-mcp-config.test.ts","test:live-mcp-reload":"cross-env CORDEX_MCP_RELOAD_TEST=1 node --import tsx --test test/live-codex-mcp-reload.test.ts","test:live-file-upload":"cross-env CORDEX_FILE_UPLOAD_TEST=1 node --import tsx --test test/live-codex-file-upload.test.ts","test:live-output-retry":"cross-env CORDEX_OUTPUT_RETRY_TEST=1 node --import tsx --test test/live-codex-output-retry.test.ts","test:live-model-notices":"cross-env CORDEX_MODEL_NOTICES_TEST=1 node --import tsx --test test/live-codex-model-notices.test.ts","test:live-action-buttons":"cross-env CORDEX_ACTION_BUTTONS_TEST=1 node --import tsx --test test/live-codex-action-buttons.test.ts","test:live-direct-recovery":"cross-env CORDEX_DIRECT_RECOVERY_TEST=1 node --import tsx --test test/live-codex-direct-recovery.test.ts","test:live-generated-image":"cross-env CORDEX_GENERATED_IMAGE_TEST=1 node --import tsx --test test/live-codex-generated-image.test.ts","test:live-mcp-elicitation":"cross-env CORDEX_MCP_ELICITATION_TEST=1 node --import tsx --test test/live-codex-mcp-elicitation.test.ts","test:live-session-history":"cross-env CORDEX_SESSION_HISTORY_TEST=1 node --import tsx --test test/live-codex-session-history.test.ts","test:live-discord-controls":"cross-env CORDEX_DISCORD_CONTROLS_TEST=1 node --import tsx --test test/live-codex-discord-controls.test.ts","test:live-file-upload-tool":"cross-env CORDEX_FILE_UPLOAD_TOOL_TEST=1 node --import tsx --test test/live-codex-file-upload-tool.test.ts","test:live-plugin-lifecycle":"cross-env CORDEX_PLUGIN_LIFECYCLE_TEST=1 node --import tsx --test test/live-codex-plugin-lifecycle.test.ts","test:live-startup-progress":"cross-env CORDEX_STARTUP_PROGRESS_TEST=1 node --import tsx --test test/live-codex-startup-progress.test.ts","test:live-background-notice":"cross-env CORDEX_BACKGROUND_NOTICE_TEST=1 node --import tsx --test test/live-codex-background-notice.test.ts","test:live-ambiguous-delivery":"cross-env CORDEX_AMBIGUOUS_DELIVERY_TEST=1 node --import tsx --test test/live-codex-ambiguous-delivery.test.ts"},"version":"0.3.0","_npmUser":{"name":"4pii4","email":"naivenevaii@gmail.com"},"keywords":["openai","codex","discord","bot","cli","developer-tools","automation"],"_resolved":"/tmp/cordex-release-030-OAD1QD/4pii4-cordex-0.3.0.tgz","_integrity":"sha512-c691aYguR8tGwv6fOli2j0ICNTeHisJekGNvNqThO5fuhoNHnqZQ7p3Z6v86mvO8GnOwOYKA4qzyXEWVibzV+Q==","_npmVersion":"10.9.8","description":"Control OpenAI Codex from Discord with persistent projects, sessions, approvals, and live output","directories":{},"maintainers":[{"name":"4pii4","email":"naivenevaii@gmail.com"}],"_nodeVersion":"22.23.1","dependencies":{"discord.js":"^14.26.3"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsx":"^4.20.6","cross-env":"^10.1.0","typescript":"^5.9.3","@types/node":"^22.20.1"},"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/cordex_0.3.0_1790793957138_0.3899635420782126"}}},"time":{"created":"2026-07-16T19:24:32.797Z","modified":"2026-09-30T18:45:57.461Z","0.1.0":"2026-07-16T19:24:33.115Z","0.1.1":"2026-07-17T04:12:29.152Z","0.1.2":"2026-07-18T11:59:24.627Z","0.1.3":"2026-07-18T18:54:03.852Z","0.1.4":"2026-07-18T19:33:58.467Z","0.1.5":"2026-07-18T19:58:20.007Z","0.1.6":"2026-08-01T05:39:28.935Z","0.1.7":"2026-08-01T07:51:23.464Z","0.2.0":"2026-09-28T15:56:09.248Z","0.2.1":"2026-09-28T16:02:13.598Z","0.3.0":"2026-09-30T18:45:57.247Z"},"license":"GPL-3.0-only","keywords":["openai","codex","discord","bot","cli","developer-tools","automation"],"description":"Control OpenAI Codex from Discord with persistent projects, sessions, approvals, and live output","maintainers":[{"name":"4pii4","email":"naivenevaii@gmail.com"}],"readme":"<div align=\"center\">\n  <h1>Cordex</h1>\n  <p>Run persistent OpenAI Codex sessions from Discord.</p>\n</div>\n\nCordex turns Discord into a control surface for\n[OpenAI Codex](https://developers.openai.com/codex/cli/). Each Discord channel\nmaps to a local project, and each thread is a persistent Codex session. Send a\nmessage and Codex can read, edit, test, and run commands on the machine hosting\nCordex.\n\n> [!WARNING]\n> Cordex can read and modify local files, run shell commands, and—when explicitly\n> enabled—run Codex without approvals or sandboxing. Run it on a machine and in a\n> Discord server you control, restrict access to trusted members, and keep the\n> default `workspace-write` sandbox with `on-request` approvals unless you fully\n> understand the consequences.\n\n## Quick Start\n\nRequires Node.js 22 or newer and Git.\n\n1. Install the Codex CLI, then authenticate it on the machine that will run\n   Cordex:\n\n   ```bash\n   npm install -g @openai/codex\n   codex login\n   codex --version\n   ```\n\n2. Create a Discord application and collect its bot token, application ID, and\n   server ID using the [Discord bot setup](#discord-bot-setup) below.\n\n3. Start Cordex with one command:\n\n   ```bash\n   npx -y @4pii4/cordex@latest\n   ```\n\n   On the first run, Cordex asks for the three Discord values, saves its config,\n   registers the slash commands, and starts the bot. Keep this process running.\n\n4. As the Discord server owner, open the managed general channel (`#cordex` when\n   the bot is named Cordex) and send a task. Cordex creates a thread for the new\n   Codex session. Add an existing repository with `/add-project` or from another\n   terminal:\n\n   ```bash\n   npx -y @4pii4/cordex@latest project add /absolute/path/to/project\n   ```\n\nFor a permanent `cordex` command, install the package globally:\n\n```bash\nnpm install -g @4pii4/cordex\ncordex\n```\n\n## What is Cordex?\n\nCordex maps Discord's project and conversation structure directly onto the local\nCodex runtime:\n\n| Discord | Local Codex runtime |\n| --- | --- |\n| Project channel | Local project directory |\n| Thread in that channel | Persistent Codex session |\n\nSend a message in a project channel to start a session thread. Continue chatting\nin that thread to keep working in the same Codex context. Switch projects by\nswitching channels, and switch tasks by switching threads.\n\n## Core Features\n\n- Remote Codex prompting from Discord with persistent, resumable sessions\n- Live responses, compact tool activity, approvals, and structured user questions\n- Dedicated Discord channels for local projects and optional git worktree isolation\n- Project- or session-level model, reasoning, collaboration mode, and permission controls\n- Queued and scheduled prompts with restart recovery\n- Native Codex skill invocation plus MCP, authentication, account, rate-limit, and context diagnostics\n- Codex plugin discovery and management, plus read-only hook trust and app state\n- Reply-aware text and image input, code review, diffs, rollback, and controlled shell execution\n\n## Setup\n\n### Requirements\n\n- Node.js 22 or newer\n- A Codex CLI installation with app-server support\n- A Discord application and bot added to a server you control\n- Git (Cordex initializes its managed root repository at startup and also uses\n  Git for project creation and worktree features)\n\nAuthenticate Codex on the host before starting Cordex:\n\n```bash\ncodex login\ncodex --version\n```\n\nCordex uses Codex's app-server interface, which is currently experimental. A\nCodex CLI update can therefore require a corresponding Cordex update.\n\n### Discord bot setup\n\n1. Create an application in the [Discord Developer Portal](https://discord.com/developers/applications).\n2. Open **Bot**, create the bot user, and enable the **Message Content Intent**.\n3. In the OAuth2 URL generator, select the `bot` and `applications.commands` scopes.\n4. Grant the bot these permissions:\n\n   - View Channels\n   - Send Messages\n   - Send Messages in Threads\n   - Create Public Threads\n   - Manage Threads\n   - Manage Channels\n   - Manage Roles (shown as **Manage Permissions** in some Discord clients)\n   - Read Message History\n   - Attach Files\n\n   The combined permission integer is `326686051344`. To skip selecting each\n   permission manually, replace `APPLICATION_ID` in this invite URL:\n\n   ```text\n   https://discord.com/oauth2/authorize?client_id=APPLICATION_ID&permissions=326686051344&scope=bot%20applications.commands\n   ```\n5. Install the bot into the intended Discord server.\n6. Copy the bot token, application ID, and server ID for `cordex init`. Enable\n   Discord Developer Mode if you need to copy the server ID.\n\nTreat the bot token like a password. Never commit it, paste it into a Discord\nchannel, or expose it in logs.\n\n### Install\n\nInstall the published CLI globally:\n\n```bash\nnpm install -g @4pii4/cordex\ncordex --version\n```\n\nOr run it without a global install:\n\n```bash\nnpx -y @4pii4/cordex@latest --version\nnpx -y @4pii4/cordex@latest init\nnpx -y @4pii4/cordex@latest start\n```\n\nThe remaining examples use the global `cordex` command for brevity. Without a\nglobal install, replace it with `npx -y @4pii4/cordex@latest`.\n\n### Initialize and run\n\nIf you installed Cordex globally, the explicit setup flow is:\n\n```bash\ncordex init\ncordex doctor\ncordex start\n```\n\n`cordex init` prompts for the Discord bot token, application ID, and server ID.\nRerunning it preserves existing settings when prompts are left blank. Changing\nthe server ID clears guild-scoped mappings, sessions, access grants, and direct\nshell access so state from the previous server cannot carry over.\nRunning bare `cordex` also initializes the configuration when necessary and then\nstarts the bot. On startup, Cordex registers its slash commands and creates a\nmanaged category with a general project channel. Name the Discord bot `Cordex`\nto use the default `Cordex` category and `#cordex` channel; other bot names are\nappended so multiple installations can coexist.\n\nAdd an existing local project from the terminal:\n\n```bash\ncordex project add /absolute/path/to/project\n```\n\nAlternatively, use `/add-project` in Discord. Use `/create-new-project` to create\na new git repository, Discord channel, and initial session together. Then send a\nnormal message in the project channel; Cordex creates a thread and starts Codex.\n\nUseful terminal project commands include:\n\n```bash\ncordex project add .\ncordex project create my-app --projects-dir ~/src\ncordex project list --json\ncordex project list --all --prune\ncordex project open-in-discord\ncordex project remove DISCORD_CHANNEL_ID\n```\n\n`cordex project remove` removes the local mapping without deleting project files.\nDiscord `/remove-project` deletes the selected managed Discord channel after its\nsafety checks.\n\nWhile `cordex start` is running, another local process owned by the same operating-\nsystem user can durably submit a prompt to an existing Cordex session thread:\n\n```bash\ncordex send --thread DISCORD_THREAD_ID \"Run the focused tests\"\ncordex send --thread DISCORD_THREAD_ID --file ./failure.log \"Diagnose this failure\"\ncordex send --thread DISCORD_THREAD_ID --file ./error.log --file ./screenshot.png \"Investigate these artifacts\"\n```\n\nThe daemon reads up to ten repeated `--file` values itself and accepts mixed UTF-8\ntext plus PNG, JPEG, GIF, and WebP images within the same per-file and aggregate\nlimits as Discord input. Byte-identical images are sent to Codex once. It listens\non a mode-`0600` Unix socket under `~/.cordex/ipc` and authenticates each request\nwith a per-start mode-`0600` token. Accepted prompts enter the durable direct-\ndelivery ledger before the CLI reports success. Safe channel or session creation\nis not yet exposed by this boundary; use `--thread` with an existing Cordex thread.\n\nTo post files back to Discord without starting another Codex turn:\n\n```bash\ncordex upload-to-discord --session CODEX_SESSION_ID ./screenshot-1.png ./screenshot-2.png\ncordex upload-to-discord --thread DISCORD_THREAD_ID ./report.csv\n```\n\nUploads keep up to ten files in one Discord message (an image grid for multiple\nimages), with an 8 MiB aggregate safety limit. Paths must resolve inside that\nsession's current directory by default, including after symlinks are resolved.\nUse `--allow-outside-project` only for an explicit path you intend to disclose;\n`--request-id ID` makes a retry idempotent. The daemon copies accepted bytes\ninto a private cache and retries Discord delivery across network failures and\nbot restarts. Permanent Discord file rejection produces a visible text notice\ninstead of retrying the invalid upload forever. New Codex sessions also expose\n`cordex_upload_files`, which lets\nthe agent deliver verified project files without connecting to the daemon\nsocket from its sandbox. Older sessions can use the CLI with a one-time Codex\ncommand approval until they are recreated with the new tool.\n\nInside an existing Cordex thread, a message beginning with a mention of another\nDiscord user is stored as passive model context without starting or steering a\nCodex turn. The next real prompt can use that user-to-user discussion.\n\nFor detailed backend logging, run:\n\n```bash\ncordex start --verbose\n```\n\nVerbose logs can include prompts, tool calls, commands, file paths, and Codex\nprotocol traffic. Store and share them accordingly.\n\n## Commands\n\nSlash commands are registered in the configured Discord server.\n\n| Command | Description |\n| --- | --- |\n| `/add-project` | Map an existing local repository to a Discord channel |\n| `/new-session` | Start another session, inheriting the current checkout when used in a thread |\n| `/resume` | Reopen a previous active or archived Codex session |\n| `/abort` | Interrupt the current Codex turn and warn if a command remains running |\n| `/ps` / `/stop` | Inspect or terminate background commands left in the session |\n| `/delete` | Permanently delete the current Codex transcript after exact-ID confirmation |\n| `/plugins` / `/hooks` / `/apps` | Inspect extension availability and trust state |\n| `/plugin` | Inspect, install, enable, disable, or uninstall a Codex plugin |\n| `/subagents` / `/fork-subagent` | Inspect child agents or continue one in a new thread |\n| `/model` | Change the model and reasoning settings for a channel or session |\n| `/permissions` | List or select a Codex permission profile for the current session |\n| `/queue` | Run a prompt after the current turn finishes |\n| `/pending-prompts` / `/resolve-pending` | Privately review a prompt with uncertain Codex delivery, then retry or discard its exact ID |\n| `/btw` | Fork the current context into a side session |\n| `/new-worktree` | Fork the current session into an isolated Git worktree |\n| `/merge-worktree` | Merge a completed worktree back into its target branch |\n| `/diff` | Show or attach the complete current Git patch |\n| `/status` | Show the working directory, current/next model, requested policy, context usage, and queue |\n| `/debug-config` | Privately inspect Codex config layers, safe effective defaults, and managed policy presence |\n\n<details>\n<summary>Full command inventory and behavior</summary>\n\n### Commands by area\n\n| Area | Commands |\n| --- | --- |\n| Projects | `/add-project`, `/create-new-project`, `/remove-project`, `/project`, `/init` |\n| Sessions | `/new-session`, `/resume`, `/rename`, `/fork`, `/subagents`, `/fork-subagent`, `/btw`, `/abort`, `/ps`, `/stop`, `/archive`, `/delete`, `/compact`, `/last-sessions`, `/session-id`, `/status`, `/debug-config` |\n| Models and runtime | `/model`, `/model-variant`, `/unset-model-override`, `/mode`, `/fast`, `/permissions`, `/add-dir`, `/verbosity`, `/context-usage` |\n| Goals | `/goal`, `/clear-goal` |\n| Git and worktrees | `/diff`, `/review`, `/rollback`, `/new-worktree`, `/merge-worktree`, `/delete-worktree`, `/toggle-worktrees`, `/worktrees` |\n| Automation | `/queue`, `/clear-queue`, `/pending-prompts`, `/resolve-pending`, `/schedule`, `/tasks`, `/cancel-task` |\n| Codex services | `/skill`, `/skills`, `/skill-toggle`, `/skill-roots`, `/plugins`, `/plugin`, `/hooks`, `/apps`, `/mcp`, `/mcp-status`, `/mcp-login`, `/auth-status`, `/rate-limits`, `/account-usage`, `/login` |\n| Host control | `/run-shell-command`, `!command`, `/yolo`, `/restart` |\n\n`/diff` renders small patches inline and attaches the complete binary-capable\npatch when it exceeds Discord message limits.\n\nDiscord `/init` asks Codex to generate repository-specific contributor guidance\nin `AGENTS.md` in the current session directory. In a project channel, it starts\na session using the normal worktree preference. Existing guides require explicit\n`update=true`; refreshes preserve their instructions, and linked or non-file\ntargets are rejected. Optional `instructions` adds project-specific guidance.\nCodex reports generation through its normal progress/output path. Start a fresh\nsession with `/new-session` to load the updated guide. `/init` warns when\n`AGENTS.override.md` is present and leaves it untouched. In live Codex 0.159.0,\neven a zero-byte override prevented automatic loading of `AGENTS.md`; review\nthe override before assuming the generated guide is active. This differs from the terminal\n`cordex init` command, which configures the Discord bot.\n\n`/permissions reviewer=auto_review` routes eligible approval requests to Codex's\nautomatic reviewer; `reviewer=user` restores human approvals, and\n`reviewer=default` restores the current project-configured reviewer. A `profile`\nmay be selected in the same command. Reviewer preferences apply to subsequent\nturns and persist across session resume/fork and bot restart. They do not expand\nfilesystem or network access, and full access or `approval_policy=never` can\nbypass review. Automatic-review notices distinguish approval from execution,\nshow separate denied/aborted/timed-out results, and omit rationale and action\ndetails in `text_only` mode. Stricter-review requirements are surfaced without\nclaiming approval. Legacy-warning fallbacks share the thread's notification\nqueue and are suppressed only after the structured notice is durable or sent.\nA completion first received after its legacy fallback was already posted can\nstill produce a second notice; that legacy warning carries no review ID.\n`/approve` privately lists up to ten recent native denials in this session.\n`/approve review:<exact ID>` records approval context for one retry using the\nnative `thread/approveGuardianDeniedAction` RPC and the official TUI's event\nconversion. It does not start a turn, execute the action, change permissions,\ndisable review, or remember a command rule. Ask Codex to retry the exact action;\nthe reviewer can still deny it. Consumed/foreign IDs and unsupported native\npayloads fail closed. Entries are in memory and expire when the native thread\ncloses, the runtime is replaced, or the session is deleted.\nAn uncertain RPC acceptance is not automatically resent. Approval commands and\ntheir diagnostics have no public-output fallback.\n\n`/review` supports uncommitted changes, a base branch, a specific commit, or\ncustom instructions. For `target=commit`, supply `commit` as a SHA, abbreviated\nSHA, tag, or other Git revision; Cordex resolves it to an immutable commit in\nthe current session checkout and shows the full SHA when the review starts.\nThe optional `title` applies only to commit reviews. Review preserves project\nfiles and the Git index.\n\nDuring quiet turns, Cordex posts a status after about six seconds and then at\nmost once a minute without visible output. It reports the current activity\nwithout exposing command details in `text_only` mode. Undelivered status\nnotices are superseded by newer progress or the final answer when Discord\nreconnects. Cordex warns when a completed turn leaves a background command\nrunning. `/abort` interrupts the Codex turn; a command that outlives it can be\ninspected with `/ps` and ended with `/stop`.\n\nMessages ending in `. queue` are queued behind the active turn. Removing that\nsuffix in an edit dequeues the message. In an existing session, punctuation\nfollowed by a final `btw` suffix, such as `check the API too. btw`, forks the\nmessage into a side session like `/btw`. `/mcp` enable and disable actions update\nthe global Codex configuration, not only the current Discord project. `/mcp`\nreload rereads configuration without changing it and queues loaded-session\ntool refreshes for subsequent turns.\n`/archive` keeps the Discord-to-Codex mapping and session settings so `/resume`\ncan reopen the same thread; active goals, turns, queued prompts, and scheduled\ntasks, plus any prompt delivery still awaiting recovery, must be resolved first.\n`/rename` keeps the Discord and Codex titles in sync.\n`/last-sessions` accepts a case-sensitive title fragment and can include archived\nsessions. `/delete` requires the exact ID shown by `/session-id`; it permanently\nremoves the Codex transcript and spawned descendants, but keeps project files\nand Discord history, then archives the Discord thread. Finish active work and\nclear queued or scheduled work and background terminals before deleting.\n`/plugins` browses the stable Codex CLI catalog; `/plugin` uses an exact plugin\nID to inspect, install, enable, disable, or uninstall a plugin in global Codex\nconfiguration. Every change requires repeating that ID in\n`confirm-plugin-id`. Managed or unavailable plugin policies cannot be\noverridden. Installing or enabling a plugin does not automatically trust its\nhooks, and a new Codex session may be needed to use its tools or skills.\n`/hooks` and `/apps` inspect app-server state for the current project or\nsession; hook trust changes and app invocation are not yet available through\nDiscord.\n`/subagents` lists known child threads and their current recorded status;\n`/fork-subagent` lets you continue a selected child in a new Discord thread.\n`/skill` invokes an enabled skill from the current session directory and accepts an\noptional prompt; Cordex resolves the skill path from Codex metadata at submission time.\n`/skill-toggle` updates a skill's enabled state through Codex configuration, while\n`/skill-roots` replaces the runtime-only extra skill discovery directories.\n`/tasks` includes bounded Run now, Cancel, and Delete controls. Scheduled occurrences\nare persisted before execution, retain stable delivery IDs across restart, and do not\nreappear after a concurrent cancellation or deletion.\n\nStandard MCP `form` elicitations render in Discord with validated strings, dates,\nURLs, numbers, booleans, and single- or multi-select enums. Empty approval forms can\noffer session or permanent persistence when Codex explicitly advertises those choices.\nMCP URL elicitations require credential-free HTTPS links, with stricter ChatGPT-host\nvalidation for Codex Apps. Arbitrary `openai/form` schemas remain disabled and are\ndeclined rather than rendered approximately.\n\nReplies include a bounded quote and the referenced Discord author. Text\nattachments use a MIME allowlist; PNG, JPEG, GIF, and WebP images are downloaded\nto a bounded local cache before being sent to Codex. Unsupported, oversized, or\ntimed-out attachments are reported in the session instead of being silently\nignored. The final rendered text input also has an independent aggregate character\nlimit so multiple attachments and forwarded context cannot create an unbounded prompt.\n\nGenerated PNG, JPEG, and WebP images are validated from Codex's app-server\noutput and sent back as Discord attachments, including at text-only verbosity.\nCordex keeps pending uploads in a private, content-addressed cache and retries\nthem through the durable Discord outbox. If an image is unavailable or exceeds\nthe 8 MiB upload safety limit, the thread receives an explicit notice; project\nassets saved by Codex are not removed with the upload cache.\n\nModel choices use Codex's model catalog when available. Reasoning effort is validated\nper model, including `max`, and `/fast` selects the model's advertised priority tier\ninstead of assuming one fixed service-tier name. Model, effort, Fast, permission, and\nYOLO changes are persisted before they are applied to a live Codex thread.\n`/status` distinguishes the active turn's model and effort from next-turn settings,\nreports the requested sandbox and approval policy (or named profile), and shows\nworking directory, writable roots, and context usage when available.\n`/debug-config` requests the effective config for that project or worktree,\nshows Codex's resolved layers from lowest to highest precedence, and reports\nmanaged requirements separately. It sends only setting names and selected\nnon-secret defaults in a private Discord reply; it never dumps raw config\nvalues such as MCP environment variables.\n\n`/goal` with an objective creates or updates Codex's persistent thread goal.\nActive goal turns, including continuations started directly by Codex, stream to\nthe linked Discord thread, resume when Cordex restarts, and can accept queued or\nfollow-up messages. Omitted status and token-budget options preserve their\nexisting values.\n\nIf the Codex app-server exits unexpectedly, Cordex retries it with bounded\nexponential backoff, clears controls belonging to the failed process, reloads\npersistent goal sessions, and resumes eligible queued work. Initialization and\nRPC watchdogs also recycle a child that remains alive but stops responding.\nAfter an ambiguous turn start or steer failure, Cordex checks Codex's persisted\nclient message IDs. That ID is a correlation field, not a guaranteed\nidempotency key in the current Codex app-server. An unconfirmed turn RPC does\nnot cause an automatic client-ID replay: direct and queued prompts with\nuncertain delivery require explicit review, including after a restart.\nOnce Codex returns a new thread ID, Cordex persists that session mapping and\nits first prompt together before starting a turn. Existing-session messages,\n`/skill`, queued prompts, scheduled occurrences, and post-conflict recovery\ninstructions are likewise persisted before Codex delivery and stay recorded\nuntil that acceptance is confirmed. A scheduled task found in `running`\nstate after restart reuses its occurrence ID. If no queue entry survives,\nCordex holds that occurrence for review unless persisted Codex history proves\nacceptance; the ID alone does not guarantee Codex-side idempotency.\nBefore Codex returns a new thread ID, Cordex also saves the intended first\nprompt and session settings as a pending start. If creation is interrupted,\nDiscord shows a durable warning; later messages are saved behind that prompt.\nUse private `/pending-prompts` and exact-ID `/resolve-pending` to Retry into a\nnew saved Codex thread or Discard the selected prompt. An unanswered\n`thread/start` may have created an empty orphan thread; Cordex does not guess\nits ID or claim that the prompt ran.\nWhen `/new-session` fails after this save, its command reply links the\npreserved Discord thread rather than deleting that thread or its automatic\nworktree. A project with unresolved pending starts cannot be removed until\nthe saved work is reviewed.\nIf a newly mapped Codex thread has no persisted rollout after a restart,\nCordex still posts the pending-prompt warning. `/resolve-pending` Retry first\nsaves a replacement Codex thread, then submits only the exact selected prompt;\nDiscard leaves later queued work held for its own review. A lost `thread/start`\nresponse before Cordex learns the thread ID remains a separate orphan-thread\ncase.\nIf Codex cannot supply full stored history, Cordex holds saved work for\nreview instead of treating a status-only response as proof that delivery is\nsafe to repeat.\nIf Cordex restarts during a turn with saved prompts, it announces reconciliation\nin the Discord thread before attempting automatic delivery. A prompt already\naccepted by Codex is not sent again. If a prompt's acceptance is still\nuncertain, Cordex holds it and later queued work, posts a durable warning,\nand requires `/pending-prompts` followed by `/resolve-pending` with its exact\nsource ID. Retrying may duplicate side effects if Codex accepted the prompt\nwithout persisting it yet; inspect the thread and files before choosing.\nCompleted Discord output and run footers use a separate durable outbox, so a partial\nsend or bot restart resumes only missing chunks and does not block the next queued turn.\nActive turns also surface account-verification requirements, visible safety\nbuffering, model reroutes, slow lifecycle hooks, and retry warnings without\nexposing internal classifier labels or hook source paths. A staged message\ncounts as visible activity only after Discord accepts it; offline progress is\nsuperseded by newer real output before reconnect delivery.\nDuplicate events that produce no new message do not reset the quiet-turn clock.\nReconnect sends count for their owning active turn, not a newer turn, and nonce\nretries retain the message's original creation time for visibility accounting.\nBefore a turn exists, slow session creation and existing-session recovery send\nnon-notifying startup progress after a short grace period. The bot retries a\nfailed startup notice with the same nonce and stops that timer when the real\nturn starts, fails, or the Discord thread is removed.\nArchive and resume operations persist lifecycle intents before mutating Codex and\nreconcile those intents against complete active and archived thread listings on\nstartup. A crash after either side accepts the operation therefore converges instead\nof leaving Discord state permanently split from Codex.\n\nAt startup, Cordex refetches the Discord messages backing `. queue` entries so\noffline edits replace the stored input and offline deletions remove it. Transient\nDiscord or attachment failures retain the last durable input, block that thread's\nqueued delivery, and retry reconciliation with capped backoff.\n\nDiscord prompt ingress is serialized per thread. Slash commands acknowledge\nbefore waiting behind earlier messages, `/abort` stays on a priority path, and a\ndeleted thread is tombstoned and interrupted immediately so blocked preprocessing\ncannot dispatch work after deletion. Startup also removes persisted sessions whose\nDiscord thread disappeared while Cordex was offline.\nDuring shutdown, Cordex stops admitting new Discord and local-daemon requests, drains\nalready accepted interactions, scheduled work, Codex requests and notifications,\nstate/outbox queues, and deletion cleanup, then closes Codex and Discord. Concurrent\nshutdown signals share the same drain instead of racing teardown.\n\n`/yolo` switches the selected scope to approval-free `danger-full-access` mode.\n`/run-shell-command` and the `!command` shortcut execute through the host shell in\nthe active project or session directory when `allowShellCommands` is enabled.\nThat directory may be an isolated worktree. Restrict both capabilities to\ntrusted users.\n\nStarting `/new-session` inside an existing thread inherits that session's directory\nand extra workspace roots without claiming ownership of its worktree. Worktree creation\nrefreshes configured remotes, prefers a strictly newer remote ref, and initializes\nsubmodules recursively. `/merge-worktree` blocks while another live or starting session\nshares the checkout; successful and no-op merges leave the session checkout detached at\nthe merged target commit. `/delete-worktree` then removes only that exact registered,\nclean, merged checkout after confirming its feature branch is gone and no active,\narchived, or starting session still references it. A persisted removal intent lets\nstartup finish an interruption between Git deletion and the final state update, after\nwhich the session reloads at the mapped project root.\n\n</details>\n\n## Troubleshooting\n\n- Run `cordex doctor` to confirm the config file, Codex executable, and mapped\n  project directories can be read.\n- Run `codex login` again if Codex itself reports an authentication failure.\n- Rerun `cordex init` to update the Discord bot token, application ID, or server ID.\n- Check that **Message Content Intent** is enabled and the bot has every permission\n  listed in [Discord bot setup](#discord-bot-setup).\n- Run `cordex start --verbose` when diagnosing startup, Discord, or Codex app-server\n  failures. Verbose logs can contain prompts, commands, and local file paths.\n\n## Configuration\n\nThe default home is `~/.cordex`. Cordex stores its configuration in\n`~/.cordex/config.json` and runtime state alongside it. Configuration files are\nwritten with restrictive filesystem permissions, but they still contain the\nDiscord bot token and must not be shared.\n\nA representative configuration is:\n\n```json\n{\n  \"token\": \"DISCORD_BOT_TOKEN\",\n  \"applicationId\": \"DISCORD_APPLICATION_ID\",\n  \"guildId\": \"DISCORD_SERVER_ID\",\n  \"sandbox\": \"workspace-write\",\n  \"approvalPolicy\": \"on-request\",\n  \"approvalTimeoutMinutes\": 10,\n  \"allowAllUsers\": false,\n  \"allowShellCommands\": false,\n  \"allowedUserIds\": [\"TRUSTED_DISCORD_USER_ID\"],\n  \"allowedRoleIds\": [\"TRUSTED_DISCORD_ROLE_ID\"],\n  \"runtimeRestartUserIds\": [\"HOST_OPERATOR_DISCORD_USER_ID\"],\n  \"projectsDirectory\": \"/absolute/path/for/new/projects\",\n  \"projects\": {}\n}\n```\n\nProject mappings are normally managed by Cordex. Optional `defaultModel` and\n`defaultEffort` fields can set initial preferences; available models come from\nthe installed Codex runtime. Valid configured effort values are\n`minimal`, `low`, `medium`, `high`, `xhigh`, `max`, and `ultra`.\n`approvalTimeoutMinutes` controls how long Discord approval buttons remain active\nbefore Cordex denies the request and lets Codex continue; it defaults to 10.\n\nCordex also persists an internal `categoryId` after creating its managed Discord\ncategory. Do not edit or remove it manually; if it is missing or invalid, Cordex\ncreates a new managed category and re-synchronizes its channels there.\n\nOnly one Cordex runtime may use a `CORDEX_HOME` at a time. A process-lifetime\n`runtime.lock` fails fast on duplicate starts and is reclaimed when its recorded\nprocess no longer exists.\n\nEnvironment variables override the corresponding configuration or runtime path.\nCredential overrides cannot bootstrap a missing config file; create one with\n`cordex init` or create the file referenced by `CORDEX_CONFIG` first.\n\n| Variable | Purpose |\n| --- | --- |\n| `CORDEX_DISCORD_TOKEN` | Discord bot token |\n| `CORDEX_APPLICATION_ID` | Discord application ID |\n| `CORDEX_GUILD_ID` | Discord server ID |\n| `CORDEX_ALLOWED_USER_IDS` | Comma-separated trusted Discord user IDs |\n| `CORDEX_ALLOWED_ROLE_IDS` | Comma-separated trusted Discord role IDs |\n| `CORDEX_HOME` | Cordex state and configuration directory |\n| `CORDEX_CONFIG` | Explicit configuration file path |\n| `CORDEX_PROJECTS_DIR` | Default directory for newly created projects |\n| `CORDEX_CODEX_BIN` | Alternate Codex executable |\n| `CORDEX_VERBOSE=1` | Enable verbose backend logging |\n\nSupported sandbox values are `read-only`, `workspace-write`, and\n`danger-full-access`. Supported approval policies are `untrusted`, `on-request`,\nand `never`.\n\nDirect `/run-shell-command` and `!command` execution is disabled by default.\nSet `allowShellCommands` to `true` only when every authorized Cordex operator is\nalso trusted with the full operating-system permissions of the Cordex process.\n\n## Access control\n\nBy default, only the Discord server owner can use Cordex. Grant access by adding\nimmutable Discord user IDs to `allowedUserIds` or role IDs to `allowedRoleIds`.\nThe matching `CORDEX_ALLOWED_USER_IDS` and `CORDEX_ALLOWED_ROLE_IDS` environment\nvariables accept comma-separated overrides. Role names are intentionally not an\naccess boundary because they can be renamed or recreated. The `@everyone` role\nID is ignored; use `allowAllUsers` for an intentional server-wide grant.\n\nConfigure non-owner operator IDs before their first use. Restart Cordex after\nchanging access or direct-shell settings; live configuration refresh only\nreloads project mappings and managed channel metadata.\n\nCordex-managed categories are private by default. On startup, Cordex synchronizes\nthe category so it is visible to the server owner, the bot, and configured user\nor role IDs. Discord administrators can still bypass channel visibility rules.\nSetting `allowAllUsers` to `true` removes the managed visibility restriction and\nlets every server member invoke Cordex. Replies and command results are generally\npublic to anyone who can view the channel, so do not map Cordex to a public\nchannel or weaken the managed category permissions casually.\n\n### Managed runtime restart\n\n`/restart` is disabled unless the exact requesting Discord user ID appears in\n`runtimeRestartUserIds` (or `CORDEX_RUNTIME_RESTART_USER_IDS`). It works only in\na linked session thread, first reports readiness, and then requires the current\nCodex session ID as `confirm`. Cordex refuses the handoff while turns, queued or\nuncertain prompts, running schedules, approvals, background terminals, lifecycle\nmutations, or undelivered output remain.\n\nAfter confirmation, Cordex acknowledges the interaction, stages a durable\nreplacement-ready message without sending it, shuts down cleanly, releases its\nIPC/runtime lock, and exits with code `75`. An external supervisor must restart\nnonzero exits, for example a systemd service with `Restart=on-failure`. The\nreplacement's normal outbox recovery sends the completion exactly once. This\ncommand does not install updates; update the Codex/Cordex packages separately,\nthen use the handoff to load them.\n\nFor safer deployments, run Cordex under a dedicated operating-system account,\ngrant the bot only the required Discord permissions, map only intended projects,\nand keep backups or version control for writable files.\n\n## Development\n\nInstall dependencies and run the build plus local test suite:\n\n```bash\nnpm ci\nnpm run check\nnpm link\n```\n\n`npm link` makes the checkout's `cordex` command available on the current machine.\nThe default `npm test` and `npm run check` commands always run with an isolated,\ntemporary `CORDEX_HOME`; an ambient live `CORDEX_HOME` is ignored. For retained\ndebug state, provide an empty safe directory through `CORDEX_TEST_HOME`, or set\n`CORDEX_TEST_KEEP_HOME=1` to retain a generated directory after success. Live\nintegration scripts remain separate and opt-in.\n\nThe live suites launch real Codex integrations and may create Discord messages,\nchannels, sessions, worktrees, files, or account flows:\n\n```bash\nnpm run test:live-all\n```\n\nFor a long run that survives an interrupted terminal observation and writes a\nprivate log plus a verifiable JSON result, use `npm run test:live-evidence`.\nIt prints a run directory; query that exact directory with\n`node scripts/live-e2e-runner.mjs status <run-directory>`. Do not start another\nrun merely because a status poll times out.\n\nRun live tests only with an authenticated test account, a dedicated Discord\nserver, and projects where those side effects are acceptable. Individual\n`test:live-*` scripts are available for narrower integration checks. Some\naccount diagnostics skip when no compatible ChatGPT login is active.\n\nSee [CONTRIBUTING.md](CONTRIBUTING.md) for contribution expectations and\n[SECURITY.md](SECURITY.md) for private vulnerability reporting guidance.\n\n## Limitations\n\n- Codex app-server is experimental and its protocol can change between CLI versions.\n- Task output is normally public within its channel. Authentication, account,\n  session-ID, and other sensitive diagnostic commands use ephemeral replies.\n- `/rollback` continues the Discord session from an earlier Codex turn in a new\n  Codex session. The previous session remains available, and local files are unchanged.\n- Worktree automation requires mapped projects to be git repositories.\n- MCP enable/disable actions affect the global Codex configuration.\n- Cordex does not currently provide hosted session sharing, voice transcription,\n  screen sharing, browser-hosted VS Code, remote diff hosting, Slack bridging,\n  tunnels, or self-update/restart management.\n\n## Kimaki attribution\n\nCordex ports the core Discord workflow of\n[Kimaki](https://github.com/remorses/kimaki) from OpenCode to Codex. Kimaki's\noriginal work is MIT-licensed, and its required copyright and license notices\nare retained with this project. OpenCode-specific providers, plugins, commands,\nand agents are not presented as Cordex features; Codex supplies its own models,\nauthentication, skills, plugins, MCP servers, and durable sessions.\n\nCordex is an independent community project and is not affiliated with or\nendorsed by OpenAI or Discord.\n\n## License\n\nCopyright (C) 2026 Cordex contributors. Cordex is licensed under the GNU General\nPublic License version 3 only (`GPL-3.0-only`). See [LICENSE](LICENSE).\n","readmeFilename":"README.md"}