gsd-codex-cli 1.20.11 → 1.20.12

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.
@@ -21,10 +21,14 @@ Use this skill to run `gsd-*` prompts under `Codex` while preserving upstream GS
21
21
  4. Preserve step ordering and gate behavior from workflow files.
22
22
  5. User-facing guidance should recommend `/prompts:gsd-*` prompts (Codex) and `/gsd:*` commands (Claude), not internal `node ... gsd-tools ...` plumbing.
23
23
 
24
- ## Mandatory codex translations
25
- - Replace each `Task(...)` with: `spawn_agent` + `wait`.
26
- - Replace Bash/JQ patterns with PowerShell and `ConvertFrom-Json`.
27
- - Replace AskUserQuestion interactions with direct user prompts in chat.
24
+ ## Mandatory codex translations
25
+ - Replace each `Task(...)` with: `spawn_agent` + `wait`.
26
+ - Replace Bash/JQ patterns with PowerShell and `ConvertFrom-Json`.
27
+ - Replace AskUserQuestion interactions with direct user prompts in chat.
28
+ - Translate resolved model aliases before Codex subagent spawn:
29
+ - `inherit` (opus tier) -> `gpt-5.3-codex` (`xhigh`)
30
+ - `sonnet` -> `gpt-5.3-spark` (`xhigh`)
31
+ - `haiku` -> `gpt-5.1-codex-mini` (`high`)
28
32
 
29
33
  ## Subagent lifecycle (required)
30
34
  - Spawn only when the upstream workflow explicitly defines a `Task(...)` role.
@@ -20,6 +20,10 @@
20
20
  - `subagent_type=gsd-*` maps to equivalent role contract in `.claude/agents/gsd-*.md`.
21
21
  - Unspecified `subagent_type` values default to command-context Codex agent behavior.
22
22
  - Do not pass `agent_type=gsd-*` to `spawn_agent`. Codex only accepts `default`, `explorer`, or `worker` (or omit `agent_type`).
23
+ - Translate GSD model aliases to Codex models when spawning:
24
+ - `inherit` (opus tier) -> `gpt-5.3-codex` with `xhigh` reasoning effort
25
+ - `sonnet` -> `gpt-5.3-spark` with `xhigh` reasoning effort
26
+ - `haiku` -> `gpt-5.1-codex-mini` with `high` reasoning effort
23
27
 
24
28
  ## Required GSD subagents
25
29
  - `gsd-project-researcher`
package/README.md CHANGED
@@ -4,11 +4,11 @@ This repository packages the get-shit-done (GSD) workflow for Codex. It installs
4
4
 
5
5
  Use this fork if you want the GSD workflow inside Codex with a simple installer that works for a single project or your home directory.
6
6
 
7
- ## Quick Install
8
-
9
- ```bash
10
- npx gsd-codex-cli@latest --path .
11
- ```
7
+ ## Quick Install
8
+
9
+ ```bash
10
+ npx gsd-codex-cli@latest --path .
11
+ ```
12
12
 
13
13
  Install globally (prompts available from any project):
14
14
 
@@ -50,13 +50,21 @@ Re-run the installer to update your local or global install. It overwrites the e
50
50
  npx gsd-codex-cli@latest --path . --global
51
51
  ```
52
52
 
53
- ## CLI Options
54
-
55
- ```
56
- --path <dir> Install into a specific directory (defaults to current directory)
57
- --global Also install to your home directory (~/.codex and ~/.claude)
58
- --help Show help
59
- ```
53
+ ## CLI Options
54
+
55
+ ```
56
+ --path <target-dir> Install into this directory (defaults to current directory)
57
+ --global Also install to your home directory
58
+ --help Show help
59
+ ```
60
+
61
+ ## Examples
62
+
63
+ ```bash
64
+ npx gsd-codex-cli@latest --path .
65
+ npx gsd-codex-cli@latest --global
66
+ npx gsd-codex-cli@latest --path . --global
67
+ ```
60
68
 
61
69
  ## Development
62
70
 
@@ -1,8 +1,8 @@
1
1
  #!/usr/bin/env node
2
2
 
3
- const fs = require('fs');
4
- const path = require('path');
5
- const os = require('os');
3
+ const fs = require('fs');
4
+ const path = require('path');
5
+ const os = require('os');
6
6
 
7
7
  const args = process.argv.slice(2);
8
8
  const pkg = require('../package.json');
@@ -11,13 +11,13 @@ const repoRoot = path.resolve(__dirname, '..');
11
11
  const helpText = `
12
12
  ${pkg.name} v${pkg.version}
13
13
 
14
- Usage:
15
- ${pkg.name} [--path <target-dir>] [--help]
16
-
17
- Options:
18
- --path <target-dir> Install into this directory (defaults to current directory)
19
- --global Also install .claude to your home directory (for manual sharing)
20
- --help, -h Show this help message
14
+ Usage:
15
+ ${pkg.name} [--path <target-dir>] [--global] [--help]
16
+
17
+ Options:
18
+ --path <target-dir> Install into this directory (defaults to current directory)
19
+ --global Also install .claude to your home directory (for manual sharing)
20
+ --help, -h Show this help message
21
21
 
22
22
  Examples:
23
23
  npx gsd-codex-cli@latest --path .
@@ -43,16 +43,16 @@ if (pathArgIndex !== -1) {
43
43
  targetDir = path.resolve(process.cwd(), userPath);
44
44
  }
45
45
 
46
- const installGlobal = args.includes('--global');
46
+ const installGlobal = args.includes('--global');
47
47
 
48
48
  function copyRecursive(source, destination) {
49
49
  if (!fs.existsSync(source)) return;
50
50
  fs.cpSync(source, destination, { recursive: true, force: true });
51
51
  }
52
52
 
53
- function ensureDir(dirPath) {
54
- fs.mkdirSync(dirPath, { recursive: true });
55
- }
53
+ function ensureDir(dirPath) {
54
+ fs.mkdirSync(dirPath, { recursive: true });
55
+ }
56
56
 
57
57
  function resolveSourceDir(repoRelative, fallbackRelative) {
58
58
  const primary = path.join(repoRoot, repoRelative);
@@ -87,21 +87,28 @@ function copyCodexToDirectory(baseDir) {
87
87
  fs.writeFileSync(codexVersionDest, `${pkg.version}\n`);
88
88
  }
89
89
 
90
- copyCodexToDirectory(targetDir);
91
-
92
- if (installGlobal) {
93
- // Global installs should place prompts at ~/.codex/prompts (not ~/.codex/.codex/prompts).
94
- const globalBase = os.homedir();
95
- copyCodexToDirectory(globalBase);
96
- }
97
-
98
- console.log(`\n${pkg.name}@${pkg.version} installed to:`);
99
- console.log(` local: ${targetDir}`);
100
- if (installGlobal) {
101
- console.log(' global: ~/.codex');
102
- }
103
- console.log('\nNext steps:');
104
- console.log(' 1) Open your project in Codex');
105
- console.log(' 2) Run /prompts:gsd-new-project, then /prompts:gsd-discuss-phase, /prompts:gsd-plan-phase, /prompts:gsd-execute-phase');
106
- console.log(' 3) If something looks off, run /prompts:gsd-doctor');
107
- console.log(' 4) Use .codex/prompts/* for all GSD commands in this fork');
90
+ async function main() {
91
+ copyCodexToDirectory(targetDir);
92
+
93
+ if (installGlobal) {
94
+ // Global installs should place prompts at ~/.codex/prompts (not ~/.codex/.codex/prompts).
95
+ const globalBase = os.homedir();
96
+ copyCodexToDirectory(globalBase);
97
+ }
98
+
99
+ console.log(`\n${pkg.name}@${pkg.version} installed to:`);
100
+ console.log(` local: ${targetDir}`);
101
+ if (installGlobal) {
102
+ console.log(' global: ~/.codex');
103
+ }
104
+ console.log('\nNext steps:');
105
+ console.log(' 1) Open your project in Codex');
106
+ console.log(' 2) Run /prompts:gsd-new-project, then /prompts:gsd-discuss-phase, /prompts:gsd-plan-phase, /prompts:gsd-execute-phase');
107
+ console.log(' 3) If something looks off, run /prompts:gsd-doctor');
108
+ console.log(' 4) Use .codex/prompts/* for all GSD commands in this fork');
109
+ }
110
+
111
+ main().catch((error) => {
112
+ console.error(error instanceof Error ? error.message : error);
113
+ process.exit(1);
114
+ });
@@ -129,29 +129,55 @@ const { execSync } = require('child_process');
129
129
 
130
130
  // ─── Model Profile Table ─────────────────────────────────────────────────────
131
131
 
132
- const MODEL_PROFILES = {
133
- 'gsd-planner': { quality: 'opus', balanced: 'opus', budget: 'sonnet' },
134
- 'gsd-roadmapper': { quality: 'opus', balanced: 'sonnet', budget: 'sonnet' },
135
- 'gsd-executor': { quality: 'opus', balanced: 'sonnet', budget: 'sonnet' },
132
+ const MODEL_PROFILES = {
133
+ 'gsd-planner': { quality: 'opus', balanced: 'opus', budget: 'sonnet' },
134
+ 'gsd-roadmapper': { quality: 'opus', balanced: 'sonnet', budget: 'sonnet' },
135
+ 'gsd-executor': { quality: 'opus', balanced: 'sonnet', budget: 'sonnet' },
136
136
  'gsd-phase-researcher': { quality: 'opus', balanced: 'sonnet', budget: 'haiku' },
137
137
  'gsd-project-researcher': { quality: 'opus', balanced: 'sonnet', budget: 'haiku' },
138
138
  'gsd-research-synthesizer': { quality: 'sonnet', balanced: 'sonnet', budget: 'haiku' },
139
139
  'gsd-debugger': { quality: 'opus', balanced: 'sonnet', budget: 'sonnet' },
140
140
  'gsd-codebase-mapper': { quality: 'sonnet', balanced: 'haiku', budget: 'haiku' },
141
141
  'gsd-verifier': { quality: 'sonnet', balanced: 'sonnet', budget: 'haiku' },
142
- 'gsd-plan-checker': { quality: 'sonnet', balanced: 'sonnet', budget: 'haiku' },
143
- 'gsd-integration-checker': { quality: 'sonnet', balanced: 'sonnet', budget: 'haiku' },
144
- };
142
+ 'gsd-plan-checker': { quality: 'sonnet', balanced: 'sonnet', budget: 'haiku' },
143
+ 'gsd-integration-checker': { quality: 'sonnet', balanced: 'sonnet', budget: 'haiku' },
144
+ };
145
+
146
+ const CODEX_MODEL_MAP = {
147
+ // Opus-tier aliases resolve to `inherit` in GSD, then map to Codex 5.3 at xhigh effort.
148
+ inherit: { model: 'gpt-5.3-codex', reasoning_effort: 'xhigh' },
149
+ // Sonnet-tier aliases map to Spark 5.3 at xhigh effort.
150
+ sonnet: { model: 'gpt-5.3-spark', reasoning_effort: 'xhigh' },
151
+ // Haiku-tier aliases map to codex-mini at high effort.
152
+ haiku: { model: 'gpt-5.1-codex-mini', reasoning_effort: 'high' },
153
+ };
145
154
 
146
155
  // ─── Helpers ──────────────────────────────────────────────────────────────────
147
156
 
148
- function parseIncludeFlag(args) {
157
+ function parseIncludeFlag(args) {
149
158
  const includeIndex = args.indexOf('--include');
150
159
  if (includeIndex === -1) return new Set();
151
160
  const includeValue = args[includeIndex + 1];
152
161
  if (!includeValue) return new Set();
153
162
  return new Set(includeValue.split(',').map(s => s.trim()));
154
- }
163
+ }
164
+
165
+ function codexModelSpecFromAlias(alias) {
166
+ if (!alias) return null;
167
+ const normalized = String(alias).toLowerCase() === 'opus' ? 'inherit' : String(alias).toLowerCase();
168
+ return CODEX_MODEL_MAP[normalized] || null;
169
+ }
170
+
171
+ function withCodexModelHints(result) {
172
+ for (const [key, value] of Object.entries(result)) {
173
+ if (!key.endsWith('_model') || typeof value !== 'string') continue;
174
+ const spec = codexModelSpecFromAlias(value);
175
+ if (!spec) continue;
176
+ result[`${key}_codex`] = spec.model;
177
+ result[`${key}_reasoning_effort`] = spec.reasoning_effort;
178
+ }
179
+ return result;
180
+ }
155
181
 
156
182
  function safeReadFile(filePath) {
157
183
  try {
@@ -1472,7 +1498,7 @@ function cmdStateRecordSession(cwd, options, raw) {
1472
1498
  }
1473
1499
  }
1474
1500
 
1475
- function cmdResolveModel(cwd, agentType, raw) {
1501
+ function cmdResolveModel(cwd, agentType, raw) {
1476
1502
  if (!agentType) {
1477
1503
  error('agent-type required');
1478
1504
  }
@@ -1480,18 +1506,31 @@ function cmdResolveModel(cwd, agentType, raw) {
1480
1506
  const config = loadConfig(cwd);
1481
1507
  const profile = config.model_profile || 'balanced';
1482
1508
 
1483
- const agentModels = MODEL_PROFILES[agentType];
1484
- if (!agentModels) {
1485
- const result = { model: 'sonnet', profile, unknown_agent: true };
1486
- output(result, raw, 'sonnet');
1487
- return;
1488
- }
1489
-
1490
- const resolved = agentModels[profile] || agentModels['balanced'] || 'sonnet';
1491
- const model = resolved === 'opus' ? 'inherit' : resolved;
1492
- const result = { model, profile };
1493
- output(result, raw, model);
1494
- }
1509
+ const agentModels = MODEL_PROFILES[agentType];
1510
+ if (!agentModels) {
1511
+ const codexSpec = codexModelSpecFromAlias('sonnet');
1512
+ const result = {
1513
+ model: 'sonnet',
1514
+ profile,
1515
+ unknown_agent: true,
1516
+ codex_model: codexSpec?.model || null,
1517
+ codex_reasoning_effort: codexSpec?.reasoning_effort || null,
1518
+ };
1519
+ output(result, raw, 'sonnet');
1520
+ return;
1521
+ }
1522
+
1523
+ const resolved = agentModels[profile] || agentModels['balanced'] || 'sonnet';
1524
+ const model = resolved === 'opus' ? 'inherit' : resolved;
1525
+ const codexSpec = codexModelSpecFromAlias(model);
1526
+ const result = {
1527
+ model,
1528
+ profile,
1529
+ codex_model: codexSpec?.model || null,
1530
+ codex_reasoning_effort: codexSpec?.reasoning_effort || null,
1531
+ };
1532
+ output(result, raw, model);
1533
+ }
1495
1534
 
1496
1535
  function cmdFindPhase(cwd, phase, raw) {
1497
1536
  if (!phase) {
@@ -1998,8 +2037,9 @@ function cmdPhasePlanIndex(cwd, phase, raw) {
1998
2037
  has_checkpoints: hasCheckpoints,
1999
2038
  };
2000
2039
 
2001
- output(result, raw);
2002
- }
2040
+ withCodexModelHints(result);
2041
+ output(result, raw);
2042
+ }
2003
2043
 
2004
2044
  function cmdStateSnapshot(cwd, raw) {
2005
2045
  const statePath = path.join(cwd, '.planning', 'STATE.md');
@@ -2099,8 +2139,9 @@ function cmdStateSnapshot(cwd, raw) {
2099
2139
  session,
2100
2140
  };
2101
2141
 
2102
- output(result, raw);
2103
- }
2142
+ withCodexModelHints(result);
2143
+ output(result, raw);
2144
+ }
2104
2145
 
2105
2146
  function cmdSummaryExtract(cwd, summaryPath, fields, raw) {
2106
2147
  if (!summaryPath) {
@@ -2703,8 +2744,9 @@ function cmdRoadmapAnalyze(cwd, raw) {
2703
2744
  missing_phase_details: missingDetails.length > 0 ? missingDetails : null,
2704
2745
  };
2705
2746
 
2706
- output(result, raw);
2707
- }
2747
+ withCodexModelHints(result);
2748
+ output(result, raw);
2749
+ }
2708
2750
 
2709
2751
  // ─── Phase Add ────────────────────────────────────────────────────────────────
2710
2752
 
@@ -3118,8 +3160,9 @@ function cmdPhaseRemove(cwd, targetPhase, options, raw) {
3118
3160
  state_updated: fs.existsSync(statePath),
3119
3161
  };
3120
3162
 
3121
- output(result, raw);
3122
- }
3163
+ withCodexModelHints(result);
3164
+ output(result, raw);
3165
+ }
3123
3166
 
3124
3167
  // ─── Roadmap Update Plan Progress ────────────────────────────────────────────
3125
3168
 
@@ -3365,8 +3408,9 @@ function cmdPhaseComplete(cwd, phaseNum, raw) {
3365
3408
  state_updated: fs.existsSync(statePath),
3366
3409
  };
3367
3410
 
3368
- output(result, raw);
3369
- }
3411
+ withCodexModelHints(result);
3412
+ output(result, raw);
3413
+ }
3370
3414
 
3371
3415
  // ─── Milestone Complete ───────────────────────────────────────────────────────
3372
3416
 
@@ -3502,8 +3546,9 @@ function cmdMilestoneComplete(cwd, version, options, raw) {
3502
3546
  state_updated: fs.existsSync(statePath),
3503
3547
  };
3504
3548
 
3505
- output(result, raw);
3506
- }
3549
+ withCodexModelHints(result);
3550
+ output(result, raw);
3551
+ }
3507
3552
 
3508
3553
  // ─── Validate Consistency ─────────────────────────────────────────────────────
3509
3554
 
@@ -4299,8 +4344,9 @@ function cmdInitExecutePhase(cwd, phase, includes, raw) {
4299
4344
  result.roadmap_content = safeReadFile(path.join(cwd, '.planning', 'ROADMAP.md'));
4300
4345
  }
4301
4346
 
4302
- output(result, raw);
4303
- }
4347
+ withCodexModelHints(result);
4348
+ output(result, raw);
4349
+ }
4304
4350
 
4305
4351
  function cmdInitPlanPhase(cwd, phase, includes, raw) {
4306
4352
  if (!phase) {
@@ -4395,10 +4441,11 @@ function cmdInitPlanPhase(cwd, phase, includes, raw) {
4395
4441
  } catch {}
4396
4442
  }
4397
4443
 
4398
- output(result, raw);
4399
- }
4444
+ withCodexModelHints(result);
4445
+ output(result, raw);
4446
+ }
4400
4447
 
4401
- function cmdInitNewProject(cwd, raw) {
4448
+ function cmdInitNewProject(cwd, raw) {
4402
4449
  const config = loadConfig(cwd);
4403
4450
 
4404
4451
  // Detect Brave Search API key availability
@@ -4451,10 +4498,11 @@ function cmdInitNewProject(cwd, raw) {
4451
4498
  brave_search_available: hasBraveSearch,
4452
4499
  };
4453
4500
 
4454
- output(result, raw);
4455
- }
4501
+ withCodexModelHints(result);
4502
+ output(result, raw);
4503
+ }
4456
4504
 
4457
- function cmdInitNewMilestone(cwd, raw) {
4505
+ function cmdInitNewMilestone(cwd, raw) {
4458
4506
  const config = loadConfig(cwd);
4459
4507
  const milestone = getMilestoneInfo(cwd);
4460
4508
 
@@ -4478,10 +4526,11 @@ function cmdInitNewMilestone(cwd, raw) {
4478
4526
  state_exists: pathExistsInternal(cwd, '.planning/STATE.md'),
4479
4527
  };
4480
4528
 
4481
- output(result, raw);
4482
- }
4529
+ withCodexModelHints(result);
4530
+ output(result, raw);
4531
+ }
4483
4532
 
4484
- function cmdInitQuick(cwd, description, raw) {
4533
+ function cmdInitQuick(cwd, description, raw) {
4485
4534
  const config = loadConfig(cwd);
4486
4535
  const now = new Date();
4487
4536
  const slug = description ? generateSlugInternal(description)?.substring(0, 40) : null;
@@ -4527,8 +4576,9 @@ function cmdInitQuick(cwd, description, raw) {
4527
4576
  planning_exists: pathExistsInternal(cwd, '.planning'),
4528
4577
  };
4529
4578
 
4530
- output(result, raw);
4531
- }
4579
+ withCodexModelHints(result);
4580
+ output(result, raw);
4581
+ }
4532
4582
 
4533
4583
  function cmdInitResume(cwd, raw) {
4534
4584
  const config = loadConfig(cwd);
@@ -4557,7 +4607,7 @@ function cmdInitResume(cwd, raw) {
4557
4607
  output(result, raw);
4558
4608
  }
4559
4609
 
4560
- function cmdInitVerifyWork(cwd, phase, raw) {
4610
+ function cmdInitVerifyWork(cwd, phase, raw) {
4561
4611
  if (!phase) {
4562
4612
  error('phase required for init verify-work');
4563
4613
  }
@@ -4583,8 +4633,9 @@ function cmdInitVerifyWork(cwd, phase, raw) {
4583
4633
  has_verification: phaseInfo?.has_verification || false,
4584
4634
  };
4585
4635
 
4586
- output(result, raw);
4587
- }
4636
+ withCodexModelHints(result);
4637
+ output(result, raw);
4638
+ }
4588
4639
 
4589
4640
  function cmdInitPhaseOp(cwd, phase, raw) {
4590
4641
  const config = loadConfig(cwd);
@@ -4759,7 +4810,7 @@ function cmdInitMilestoneOp(cwd, raw) {
4759
4810
  output(result, raw);
4760
4811
  }
4761
4812
 
4762
- function cmdInitMapCodebase(cwd, raw) {
4813
+ function cmdInitMapCodebase(cwd, raw) {
4763
4814
  const config = loadConfig(cwd);
4764
4815
 
4765
4816
  // Check for existing codebase maps
@@ -4790,10 +4841,11 @@ function cmdInitMapCodebase(cwd, raw) {
4790
4841
  codebase_dir_exists: pathExistsInternal(cwd, '.planning/codebase'),
4791
4842
  };
4792
4843
 
4793
- output(result, raw);
4794
- }
4844
+ withCodexModelHints(result);
4845
+ output(result, raw);
4846
+ }
4795
4847
 
4796
- function cmdInitProgress(cwd, includes, raw) {
4848
+ function cmdInitProgress(cwd, includes, raw) {
4797
4849
  const config = loadConfig(cwd);
4798
4850
  const milestone = getMilestoneInfo(cwd);
4799
4851
 
@@ -4897,8 +4949,9 @@ function cmdInitProgress(cwd, includes, raw) {
4897
4949
  result.config_content = safeReadFile(path.join(cwd, '.planning', 'config.json'));
4898
4950
  }
4899
4951
 
4900
- output(result, raw);
4901
- }
4952
+ withCodexModelHints(result);
4953
+ output(result, raw);
4954
+ }
4902
4955
 
4903
4956
  // ─── CLI Router ───────────────────────────────────────────────────────────────
4904
4957
 
@@ -24,11 +24,22 @@ Task(
24
24
  )
25
25
  ```
26
26
 
27
- **Note:** Opus-tier agents resolve to `"inherit"` (not `"opus"`). This causes the agent to use the parent session's model, avoiding conflicts with organization policies that may block specific opus versions.
27
+ **Note:** Opus-tier agents resolve to `"inherit"` (not `"opus"`). This causes the agent to use the parent session's model, avoiding conflicts with organization policies that may block specific opus versions.
28
+
29
+ ## Codex alias mapping
30
+
31
+ When running under Codex, map the resolved aliases to concrete Codex models:
32
+
33
+ | Alias | Codex model | Reasoning effort |
34
+ |-------|-------------|------------------|
35
+ | `inherit` (`opus` tier) | `gpt-5.3-codex` | `xhigh` |
36
+ | `sonnet` | `gpt-5.3-spark` | `xhigh` |
37
+ | `haiku` | `gpt-5.1-codex-mini` | `high` |
28
38
 
29
39
  ## Usage
30
40
 
31
41
  1. Resolve once at orchestration start
32
42
  2. Store the profile value
33
43
  3. Look up each agent's model from the table when spawning
34
- 4. Pass model parameter to each Task call (values: `"inherit"`, `"sonnet"`, `"haiku"`)
44
+ 4. Pass model parameter to each Task call (values: `"inherit"`, `"sonnet"`, `"haiku"`)
45
+ 5. In Codex mode, translate those aliases with the table above before spawning subagents
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "gsd-codex-cli",
3
- "version": "1.20.11",
3
+ "version": "1.20.12",
4
4
  "description": "Codex-native package for the get-shit-done workflow with native subagent orchestration.",
5
5
  "bin": {
6
6
  "gsd-codex-cli": "bin/install-codex.js",