@jojonax/codex-copilot 1.0.3 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/bin/cli.js CHANGED
@@ -79,6 +79,11 @@ async function main() {
79
79
  console.log(' 2. codex-copilot init (auto-detect PRD and decompose tasks)');
80
80
  console.log(' 3. codex-copilot run (start automated dev loop)');
81
81
  console.log('');
82
+ console.log(' Update:');
83
+ console.log(' npm install -g @jojonax/codex-copilot@latest');
84
+ console.log('');
85
+ console.log(' \x1b[36mⓘ This is a help page. Exit and run the commands above directly in your terminal.\x1b[0m');
86
+ console.log('');
82
87
  break;
83
88
  }
84
89
  } catch (err) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jojonax/codex-copilot",
3
- "version": "1.0.3",
3
+ "version": "1.2.0",
4
4
  "description": "PRD-driven automated development orchestrator for CodeX / Cursor",
5
5
  "bin": {
6
6
  "codex-copilot": "./bin/cli.js"
@@ -3,18 +3,19 @@
3
3
  *
4
4
  * 1. Auto-detect PRD document
5
5
  * 2. Let user confirm/select PRD
6
- * 3. Generate CodeX-executable task decomposition prompt
7
- * 4. Create .codex-copilot/ directory structure
6
+ * 3. Select AI provider (Codex, Claude Code, Cursor, etc.)
7
+ * 4. Generate task decomposition prompt
8
+ * 5. Create .codex-copilot/ directory structure
8
9
  */
9
10
 
10
11
  import { mkdirSync, writeFileSync, readFileSync, existsSync } from 'fs';
11
12
  import { resolve } from 'path';
12
- import { execSync } from 'child_process';
13
13
  import { detectPRD, readPRD } from '../utils/detect-prd.js';
14
14
  import { log } from '../utils/logger.js';
15
15
  import { ask, confirm, select, closePrompt } from '../utils/prompt.js';
16
16
  import { git } from '../utils/git.js';
17
17
  import { github } from '../utils/github.js';
18
+ import { provider } from '../utils/provider.js';
18
19
 
19
20
  export async function init(projectDir) {
20
21
  log.title('📋 Initializing Codex-Copilot');
@@ -98,6 +99,16 @@ export async function init(projectDir) {
98
99
  const prdContent = readPRD(prdPath);
99
100
  log.info(`PRD size: ${(prdContent.length / 1024).toFixed(1)} KB`);
100
101
 
102
+ // ===== Select AI Provider =====
103
+ log.step('Select AI coding tool...');
104
+ log.blank();
105
+ const providerChoices = provider.buildProviderChoices();
106
+ const selectedProvider = await select('Which AI tool will you use?', providerChoices);
107
+ const providerId = selectedProvider.value;
108
+ const providerInfo = provider.getProvider(providerId);
109
+ log.info(`Selected: ${providerInfo.name}`);
110
+ log.blank();
111
+
101
112
  // ===== Create .codex-copilot directory =====
102
113
  log.step('Creating .codex-copilot/ directory...');
103
114
  const copilotDir = resolve(projectDir, '.codex-copilot');
@@ -105,6 +116,7 @@ export async function init(projectDir) {
105
116
 
106
117
  // Write config file
107
118
  const config = {
119
+ provider: providerId,
108
120
  prd_path: prdPath,
109
121
  base_branch: git.currentBranch(projectDir) || 'main',
110
122
  max_review_rounds: 2,
@@ -114,12 +126,16 @@ export async function init(projectDir) {
114
126
  };
115
127
  writeFileSync(resolve(copilotDir, 'config.json'), JSON.stringify(config, null, 2));
116
128
 
117
- // Write initial state
129
+ // Write initial state (matches checkpoint.js schema)
118
130
  const state = {
119
131
  current_task: 0,
132
+ phase: null,
133
+ phase_step: null,
120
134
  current_pr: null,
121
135
  review_round: 0,
136
+ branch: null,
122
137
  status: 'initialized',
138
+ last_updated: new Date().toISOString(),
123
139
  };
124
140
  writeFileSync(resolve(copilotDir, 'state.json'), JSON.stringify(state, null, 2));
125
141
 
@@ -170,48 +186,40 @@ You are an efficient automated development agent responsible for completing feat
170
186
  // ===== Guide user to next steps =====
171
187
  log.title('✅ Initialization complete!');
172
188
  log.blank();
173
- log.info('Next steps:');
174
- log.blank();
175
- console.log(' ┌───────────────────────────────────────────────────┐');
176
- console.log(' │ 1. Open CodeX Desktop │');
177
- console.log(' │ 2. Paste the following file content into CodeX: │');
178
- console.log(' │ .codex-copilot/parse-prd-prompt.md │');
179
- console.log(' │ 3. CodeX will generate .codex-copilot/tasks.json │');
180
- console.log(' │ 4. Confirm the task list, then run: │');
181
- console.log(' │ codex-copilot run │');
182
- console.log(' └───────────────────────────────────────────────────┘');
189
+ log.info(`AI Provider: ${providerInfo.name}`);
183
190
  log.blank();
184
191
 
185
- // Ask if user wants to auto-decompose (if codex CLI is available)
186
- const hasCodexCLI = checkCodexCLI();
187
- if (hasCodexCLI) {
188
- log.info('CodeX CLI detected!');
189
- const autoparse = await confirm('Auto-invoke CodeX to decompose PRD?');
192
+ if (providerInfo.type === 'cli') {
193
+ // CLI provider: offer auto-decompose
194
+ const autoparse = await confirm(`Auto-invoke ${providerInfo.name} to decompose PRD?`);
190
195
  if (autoparse) {
191
- log.step('Invoking CodeX CLI to decompose PRD...');
192
- try {
193
- execSync(`cat .codex-copilot/parse-prd-prompt.md | codex exec --full-auto -`, {
194
- cwd: projectDir,
195
- stdio: 'inherit',
196
- });
197
- log.info('CodeX decomposition complete!');
198
- } catch {
199
- log.warn('CodeX CLI invocation failed. Please run manually.');
196
+ log.step(`Invoking ${providerInfo.name} to decompose PRD...`);
197
+ const ok = await provider.executePrompt(providerId, promptPath, projectDir);
198
+ if (ok) {
199
+ log.info('PRD decomposition complete!');
200
200
  }
201
+ } else {
202
+ showManualInstructions(providerInfo);
201
203
  }
204
+ } else {
205
+ // IDE provider: show manual instructions
206
+ showManualInstructions(providerInfo);
202
207
  }
203
208
 
204
209
  closePrompt();
205
210
  }
206
211
 
207
- function checkCodexCLI() {
208
- try {
209
- const cmd = process.platform === 'win32' ? 'where codex' : 'which codex';
210
- execSync(cmd, { stdio: 'pipe' });
211
- return true;
212
- } catch {
213
- return false;
214
- }
212
+ function showManualInstructions(providerInfo) {
213
+ log.info('Next steps:');
214
+ log.blank();
215
+ console.log(' ┌───────────────────────────────────────────────────┐');
216
+ console.log(` │ 1. Open ${providerInfo.name.padEnd(40)}│`);
217
+ console.log(' │ 2. Paste the file content: │');
218
+ console.log(' │ .codex-copilot/parse-prd-prompt.md │');
219
+ console.log(' │ 3. AI will generate .codex-copilot/tasks.json │');
220
+ console.log(' │ 4. Then run: codex-copilot run │');
221
+ console.log(' └───────────────────────────────────────────────────┘');
222
+ log.blank();
215
223
  }
216
224
 
217
225
  function buildParsePrompt(prdContent, copilotDir) {
@@ -6,6 +6,7 @@ import { readFileSync, writeFileSync, existsSync, unlinkSync } from 'fs';
6
6
  import { resolve } from 'path';
7
7
  import { log } from '../utils/logger.js';
8
8
  import { confirm, closePrompt } from '../utils/prompt.js';
9
+ import { createCheckpoint } from '../utils/checkpoint.js';
9
10
 
10
11
  export async function reset(projectDir) {
11
12
  const statePath = resolve(projectDir, '.codex-copilot/state.json');
@@ -20,16 +21,19 @@ export async function reset(projectDir) {
20
21
  log.title('🔄 Resetting Codex-Copilot state');
21
22
  log.blank();
22
23
 
24
+ const checkpoint = createCheckpoint(projectDir);
25
+ const state = checkpoint.load();
26
+
27
+ // Show current checkpoint before reset
28
+ if (state.phase) {
29
+ log.info(`Current checkpoint: Task #${state.current_task} — ${state.phase} → ${state.phase_step}`);
30
+ log.blank();
31
+ }
32
+
23
33
  const resetTasks = await confirm('Also reset all task statuses to pending?', false);
24
34
 
25
- // Reset state
26
- const state = {
27
- current_task: 0,
28
- current_pr: null,
29
- review_round: 0,
30
- status: 'initialized',
31
- };
32
- writeFileSync(statePath, JSON.stringify(state, null, 2));
35
+ // Reset state using checkpoint manager
36
+ checkpoint.reset();
33
37
  log.info('Execution state reset');
34
38
 
35
39
  // Reset task statuses
@@ -46,6 +50,10 @@ export async function reset(projectDir) {
46
50
  const promptPath = resolve(projectDir, '.codex-copilot/_current_prompt.md');
47
51
  if (existsSync(promptPath)) unlinkSync(promptPath);
48
52
 
53
+ // Clean up temp state file if exists
54
+ const tempPath = resolve(projectDir, '.codex-copilot/state.json.tmp');
55
+ if (existsSync(tempPath)) unlinkSync(tempPath);
56
+
49
57
  log.blank();
50
58
  log.info('✅ Reset complete. You can now run: codex-copilot run');
51
59
  closePrompt();