@jojonax/codex-copilot 1.0.1 → 1.0.3
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 +33 -22
- package/package.json +1 -1
- package/src/commands/init.js +89 -86
- package/src/commands/reset.js +10 -10
- package/src/commands/run.js +145 -118
- package/src/commands/status.js +22 -15
- package/src/utils/detect-prd.js +20 -20
- package/src/utils/git.js +26 -13
- package/src/utils/github.js +41 -22
- package/src/utils/logger.js +19 -13
- package/src/utils/prompt.js +7 -7
- package/src/utils/update-check.js +103 -0
package/bin/cli.js
CHANGED
|
@@ -1,31 +1,39 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
|
-
* codex-copilot CLI - PRD →
|
|
4
|
+
* codex-copilot CLI - PRD → Auto Dev → PR → Review → Fix → Merge
|
|
5
5
|
*
|
|
6
|
-
*
|
|
7
|
-
* codex-copilot init #
|
|
8
|
-
* codex-copilot run #
|
|
9
|
-
* codex-copilot status #
|
|
10
|
-
* codex-copilot reset #
|
|
6
|
+
* Usage:
|
|
7
|
+
* codex-copilot init # Initialize project (auto-detect PRD, generate tasks)
|
|
8
|
+
* codex-copilot run # Start automated development loop
|
|
9
|
+
* codex-copilot status # View current progress
|
|
10
|
+
* codex-copilot reset # Reset state (start over)
|
|
11
11
|
*/
|
|
12
12
|
|
|
13
|
-
import { resolve } from 'path';
|
|
14
|
-
import { existsSync } from 'fs';
|
|
13
|
+
import { resolve, dirname } from 'path';
|
|
14
|
+
import { existsSync, readFileSync } from 'fs';
|
|
15
|
+
import { fileURLToPath } from 'url';
|
|
15
16
|
|
|
16
17
|
import { init } from '../src/commands/init.js';
|
|
17
18
|
import { run } from '../src/commands/run.js';
|
|
18
19
|
import { status } from '../src/commands/status.js';
|
|
19
20
|
import { reset } from '../src/commands/reset.js';
|
|
20
21
|
import { log } from '../src/utils/logger.js';
|
|
22
|
+
import { checkForUpdates } from '../src/utils/update-check.js';
|
|
21
23
|
|
|
22
24
|
const command = process.argv[2];
|
|
23
25
|
const projectDir = process.cwd();
|
|
24
26
|
|
|
27
|
+
// Read version from package.json
|
|
28
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
29
|
+
const __dirname = dirname(__filename);
|
|
30
|
+
const pkg = JSON.parse(readFileSync(resolve(__dirname, '..', 'package.json'), 'utf-8'));
|
|
31
|
+
const version = pkg.version;
|
|
32
|
+
|
|
25
33
|
// Banner
|
|
26
34
|
console.log('');
|
|
27
35
|
console.log(' ╔══════════════════════════════════════════╗');
|
|
28
|
-
console.log(
|
|
36
|
+
console.log(` ║ 🤖 Codex-Copilot v${version.padEnd(18)}║`);
|
|
29
37
|
console.log(' ║ PRD-Driven Auto Development ║');
|
|
30
38
|
console.log(' ╚══════════════════════════════════════════╝');
|
|
31
39
|
console.log('');
|
|
@@ -39,7 +47,7 @@ async function main() {
|
|
|
39
47
|
|
|
40
48
|
case 'run':
|
|
41
49
|
if (!existsSync(resolve(projectDir, '.codex-copilot/tasks.json'))) {
|
|
42
|
-
log.error('
|
|
50
|
+
log.error('Not initialized. Run: codex-copilot init');
|
|
43
51
|
process.exit(1);
|
|
44
52
|
}
|
|
45
53
|
await run(projectDir);
|
|
@@ -47,7 +55,7 @@ async function main() {
|
|
|
47
55
|
|
|
48
56
|
case 'status':
|
|
49
57
|
if (!existsSync(resolve(projectDir, '.codex-copilot/tasks.json'))) {
|
|
50
|
-
log.error('
|
|
58
|
+
log.error('Not initialized. Run: codex-copilot init');
|
|
51
59
|
process.exit(1);
|
|
52
60
|
}
|
|
53
61
|
await status(projectDir);
|
|
@@ -58,26 +66,29 @@ async function main() {
|
|
|
58
66
|
break;
|
|
59
67
|
|
|
60
68
|
default:
|
|
61
|
-
console.log('
|
|
69
|
+
console.log(' Usage: codex-copilot <command>');
|
|
62
70
|
console.log('');
|
|
63
|
-
console.log('
|
|
64
|
-
console.log(' init
|
|
65
|
-
console.log(' run
|
|
66
|
-
console.log(' status
|
|
67
|
-
console.log(' reset
|
|
71
|
+
console.log(' Commands:');
|
|
72
|
+
console.log(' init Initialize project (auto-detect PRD, generate task queue)');
|
|
73
|
+
console.log(' run Start automated development loop');
|
|
74
|
+
console.log(' status View current task progress');
|
|
75
|
+
console.log(' reset Reset state and start over');
|
|
68
76
|
console.log('');
|
|
69
|
-
console.log('
|
|
70
|
-
console.log(' 1. cd
|
|
71
|
-
console.log(' 2. codex-copilot init (
|
|
72
|
-
console.log(' 3. codex-copilot run (
|
|
77
|
+
console.log(' Workflow:');
|
|
78
|
+
console.log(' 1. cd into your project directory');
|
|
79
|
+
console.log(' 2. codex-copilot init (auto-detect PRD and decompose tasks)');
|
|
80
|
+
console.log(' 3. codex-copilot run (start automated dev loop)');
|
|
73
81
|
console.log('');
|
|
74
82
|
break;
|
|
75
83
|
}
|
|
76
84
|
} catch (err) {
|
|
77
|
-
log.error(
|
|
85
|
+
log.error(`Execution failed: ${err.message}`);
|
|
78
86
|
if (process.env.DEBUG) console.error(err);
|
|
79
87
|
process.exit(1);
|
|
80
88
|
}
|
|
81
89
|
}
|
|
82
90
|
|
|
91
|
+
// Check for updates (non-blocking, cached 24h)
|
|
92
|
+
checkForUpdates(version);
|
|
93
|
+
|
|
83
94
|
main();
|
package/package.json
CHANGED
package/src/commands/init.js
CHANGED
|
@@ -1,15 +1,14 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* codex-copilot init -
|
|
2
|
+
* codex-copilot init - Initialize project
|
|
3
3
|
*
|
|
4
|
-
* 1.
|
|
5
|
-
* 2.
|
|
6
|
-
* 3.
|
|
7
|
-
* 4.
|
|
4
|
+
* 1. Auto-detect PRD document
|
|
5
|
+
* 2. Let user confirm/select PRD
|
|
6
|
+
* 3. Generate CodeX-executable task decomposition prompt
|
|
7
|
+
* 4. Create .codex-copilot/ directory structure
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
10
|
import { mkdirSync, writeFileSync, readFileSync, existsSync } from 'fs';
|
|
11
|
-
import { resolve
|
|
12
|
-
import { fileURLToPath } from 'url';
|
|
11
|
+
import { resolve } from 'path';
|
|
13
12
|
import { execSync } from 'child_process';
|
|
14
13
|
import { detectPRD, readPRD } from '../utils/detect-prd.js';
|
|
15
14
|
import { log } from '../utils/logger.js';
|
|
@@ -17,37 +16,35 @@ import { ask, confirm, select, closePrompt } from '../utils/prompt.js';
|
|
|
17
16
|
import { git } from '../utils/git.js';
|
|
18
17
|
import { github } from '../utils/github.js';
|
|
19
18
|
|
|
20
|
-
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
21
|
-
|
|
22
19
|
export async function init(projectDir) {
|
|
23
|
-
log.title('📋
|
|
20
|
+
log.title('📋 Initializing Codex-Copilot');
|
|
24
21
|
log.blank();
|
|
25
22
|
|
|
26
|
-
// =====
|
|
27
|
-
log.step('
|
|
23
|
+
// ===== Pre-flight checks =====
|
|
24
|
+
log.step('Checking environment...');
|
|
28
25
|
|
|
29
|
-
//
|
|
26
|
+
// Check if in a git repo
|
|
30
27
|
try {
|
|
31
28
|
git.currentBranch(projectDir);
|
|
32
|
-
log.info('Git
|
|
29
|
+
log.info('Git repository ✓');
|
|
33
30
|
} catch {
|
|
34
|
-
log.error('
|
|
31
|
+
log.error('Not a Git repository. Run: git init');
|
|
35
32
|
closePrompt();
|
|
36
33
|
process.exit(1);
|
|
37
34
|
}
|
|
38
35
|
|
|
39
|
-
//
|
|
36
|
+
// Check gh CLI
|
|
40
37
|
if (!github.checkGhAuth()) {
|
|
41
|
-
log.error('GitHub CLI
|
|
38
|
+
log.error('GitHub CLI not authenticated. Run: gh auth login');
|
|
42
39
|
closePrompt();
|
|
43
40
|
process.exit(1);
|
|
44
41
|
}
|
|
45
42
|
log.info('GitHub CLI ✓');
|
|
46
43
|
|
|
47
|
-
//
|
|
44
|
+
// Check GitHub remote
|
|
48
45
|
try {
|
|
49
46
|
const repo = git.getRepoInfo(projectDir);
|
|
50
|
-
log.info(`GitHub
|
|
47
|
+
log.info(`GitHub repo: ${repo.owner}/${repo.repo} ✓`);
|
|
51
48
|
} catch (err) {
|
|
52
49
|
log.error(err.message);
|
|
53
50
|
closePrompt();
|
|
@@ -56,51 +53,57 @@ export async function init(projectDir) {
|
|
|
56
53
|
|
|
57
54
|
log.blank();
|
|
58
55
|
|
|
59
|
-
// =====
|
|
60
|
-
log.step('
|
|
56
|
+
// ===== Detect PRD =====
|
|
57
|
+
log.step('Scanning for PRD documents...');
|
|
61
58
|
const candidates = detectPRD(projectDir);
|
|
62
59
|
|
|
63
60
|
let prdPath;
|
|
64
61
|
|
|
65
62
|
if (candidates.length === 0) {
|
|
66
|
-
log.warn('
|
|
67
|
-
const manualPath = await ask('
|
|
63
|
+
log.warn('No PRD document detected automatically');
|
|
64
|
+
const manualPath = await ask('Enter PRD file path (relative or absolute):');
|
|
68
65
|
prdPath = resolve(projectDir, manualPath);
|
|
66
|
+
// Prevent path traversal
|
|
67
|
+
if (!prdPath.startsWith(resolve(projectDir)) && !manualPath.startsWith('/')) {
|
|
68
|
+
log.error('PRD path is outside the project directory');
|
|
69
|
+
closePrompt();
|
|
70
|
+
process.exit(1);
|
|
71
|
+
}
|
|
69
72
|
if (!existsSync(prdPath)) {
|
|
70
|
-
log.error(
|
|
73
|
+
log.error(`File not found: ${prdPath}`);
|
|
71
74
|
closePrompt();
|
|
72
75
|
process.exit(1);
|
|
73
76
|
}
|
|
74
77
|
} else if (candidates.length === 1) {
|
|
75
78
|
prdPath = candidates[0].path;
|
|
76
|
-
log.info(
|
|
77
|
-
const ok = await confirm('
|
|
79
|
+
log.info(`Found PRD: ${candidates[0].relativePath}`);
|
|
80
|
+
const ok = await confirm('Use this file?');
|
|
78
81
|
if (!ok) {
|
|
79
|
-
const manualPath = await ask('
|
|
82
|
+
const manualPath = await ask('Enter PRD file path:');
|
|
80
83
|
prdPath = resolve(projectDir, manualPath);
|
|
81
84
|
}
|
|
82
85
|
} else {
|
|
83
|
-
log.info(
|
|
84
|
-
const choice = await select('
|
|
85
|
-
label: `${c.relativePath} (
|
|
86
|
+
log.info(`Found ${candidates.length} candidate PRD files:`);
|
|
87
|
+
const choice = await select('Select the PRD to use:', candidates.map(c => ({
|
|
88
|
+
label: `${c.relativePath} (score: ${c.score})`,
|
|
86
89
|
value: c.path,
|
|
87
90
|
})));
|
|
88
91
|
prdPath = choice.value;
|
|
89
92
|
}
|
|
90
93
|
|
|
91
|
-
log.info(
|
|
94
|
+
log.info(`Using PRD: ${prdPath}`);
|
|
92
95
|
log.blank();
|
|
93
96
|
|
|
94
|
-
// =====
|
|
97
|
+
// ===== Read PRD =====
|
|
95
98
|
const prdContent = readPRD(prdPath);
|
|
96
|
-
log.info(`PRD
|
|
99
|
+
log.info(`PRD size: ${(prdContent.length / 1024).toFixed(1)} KB`);
|
|
97
100
|
|
|
98
|
-
// =====
|
|
99
|
-
log.step('
|
|
101
|
+
// ===== Create .codex-copilot directory =====
|
|
102
|
+
log.step('Creating .codex-copilot/ directory...');
|
|
100
103
|
const copilotDir = resolve(projectDir, '.codex-copilot');
|
|
101
104
|
mkdirSync(copilotDir, { recursive: true });
|
|
102
105
|
|
|
103
|
-
//
|
|
106
|
+
// Write config file
|
|
104
107
|
const config = {
|
|
105
108
|
prd_path: prdPath,
|
|
106
109
|
base_branch: git.currentBranch(projectDir) || 'main',
|
|
@@ -111,7 +114,7 @@ export async function init(projectDir) {
|
|
|
111
114
|
};
|
|
112
115
|
writeFileSync(resolve(copilotDir, 'config.json'), JSON.stringify(config, null, 2));
|
|
113
116
|
|
|
114
|
-
//
|
|
117
|
+
// Write initial state
|
|
115
118
|
const state = {
|
|
116
119
|
current_task: 0,
|
|
117
120
|
current_pr: null,
|
|
@@ -120,28 +123,28 @@ export async function init(projectDir) {
|
|
|
120
123
|
};
|
|
121
124
|
writeFileSync(resolve(copilotDir, 'state.json'), JSON.stringify(state, null, 2));
|
|
122
125
|
|
|
123
|
-
//
|
|
124
|
-
const instructions = `# Codex-Copilot
|
|
126
|
+
// Write CodeX instruction template
|
|
127
|
+
const instructions = `# Codex-Copilot Development Instructions
|
|
125
128
|
|
|
126
|
-
##
|
|
127
|
-
|
|
129
|
+
## Role
|
|
130
|
+
You are an efficient automated development agent responsible for completing feature development according to task descriptions.
|
|
128
131
|
|
|
129
|
-
##
|
|
130
|
-
1.
|
|
131
|
-
2.
|
|
132
|
-
3. **Git
|
|
133
|
-
4.
|
|
134
|
-
5.
|
|
132
|
+
## Rules
|
|
133
|
+
1. **Follow the project tech stack**: Use the existing frameworks, tools, and code style
|
|
134
|
+
2. **Test first**: Ensure code compiles/runs before finishing
|
|
135
|
+
3. **Git conventions**: Commit message format \`feat(task-N): brief description\` or \`fix(task-N): brief description\`
|
|
136
|
+
4. **Don't modify unrelated files**: Only change files required by the current task
|
|
137
|
+
5. **Commit when done**: \`git add -A && git commit -m "..."\`
|
|
135
138
|
|
|
136
|
-
##
|
|
137
|
-
1.
|
|
138
|
-
2.
|
|
139
|
-
3.
|
|
140
|
-
4.
|
|
139
|
+
## Rules for fixing reviews
|
|
140
|
+
1. Read each review comment carefully
|
|
141
|
+
2. Distinguish between must-fix vs. suggestions
|
|
142
|
+
3. If you disagree with a comment, explain why in the commit message
|
|
143
|
+
4. Ensure fixes don't introduce new issues
|
|
141
144
|
`;
|
|
142
145
|
writeFileSync(resolve(copilotDir, 'codex-instructions.md'), instructions);
|
|
143
146
|
|
|
144
|
-
//
|
|
147
|
+
// Add .gitignore entries
|
|
145
148
|
const gitignorePath = resolve(projectDir, '.gitignore');
|
|
146
149
|
const gitignoreEntry = '\n# Codex-Copilot state\n.codex-copilot/state.json\n';
|
|
147
150
|
if (existsSync(gitignorePath)) {
|
|
@@ -151,50 +154,49 @@ export async function init(projectDir) {
|
|
|
151
154
|
}
|
|
152
155
|
}
|
|
153
156
|
|
|
154
|
-
log.info('.codex-copilot/
|
|
157
|
+
log.info('.codex-copilot/ directory created');
|
|
155
158
|
log.blank();
|
|
156
159
|
|
|
157
|
-
// =====
|
|
158
|
-
log.step('
|
|
160
|
+
// ===== Generate task decomposition prompt =====
|
|
161
|
+
log.step('Generating task decomposition prompt...');
|
|
159
162
|
|
|
160
163
|
const parsePrompt = buildParsePrompt(prdContent, copilotDir);
|
|
161
164
|
const promptPath = resolve(copilotDir, 'parse-prd-prompt.md');
|
|
162
165
|
writeFileSync(promptPath, parsePrompt);
|
|
163
166
|
|
|
164
|
-
log.info(
|
|
167
|
+
log.info('Task decomposition prompt saved to: .codex-copilot/parse-prd-prompt.md');
|
|
165
168
|
log.blank();
|
|
166
169
|
|
|
167
|
-
// =====
|
|
168
|
-
log.title('✅
|
|
170
|
+
// ===== Guide user to next steps =====
|
|
171
|
+
log.title('✅ Initialization complete!');
|
|
169
172
|
log.blank();
|
|
170
|
-
log.info('
|
|
173
|
+
log.info('Next steps:');
|
|
171
174
|
log.blank();
|
|
172
175
|
console.log(' ┌───────────────────────────────────────────────────┐');
|
|
173
|
-
console.log(' │ 1.
|
|
174
|
-
console.log(' │ 2.
|
|
176
|
+
console.log(' │ 1. Open CodeX Desktop │');
|
|
177
|
+
console.log(' │ 2. Paste the following file content into CodeX: │');
|
|
175
178
|
console.log(' │ .codex-copilot/parse-prd-prompt.md │');
|
|
176
|
-
console.log(' │ 3. CodeX
|
|
177
|
-
console.log(' │ 4.
|
|
179
|
+
console.log(' │ 3. CodeX will generate .codex-copilot/tasks.json │');
|
|
180
|
+
console.log(' │ 4. Confirm the task list, then run: │');
|
|
178
181
|
console.log(' │ codex-copilot run │');
|
|
179
182
|
console.log(' └───────────────────────────────────────────────────┘');
|
|
180
183
|
log.blank();
|
|
181
184
|
|
|
182
|
-
//
|
|
185
|
+
// Ask if user wants to auto-decompose (if codex CLI is available)
|
|
183
186
|
const hasCodexCLI = checkCodexCLI();
|
|
184
187
|
if (hasCodexCLI) {
|
|
185
|
-
log.info('
|
|
186
|
-
const autoparse = await confirm('
|
|
188
|
+
log.info('CodeX CLI detected!');
|
|
189
|
+
const autoparse = await confirm('Auto-invoke CodeX to decompose PRD?');
|
|
187
190
|
if (autoparse) {
|
|
188
|
-
log.step('
|
|
191
|
+
log.step('Invoking CodeX CLI to decompose PRD...');
|
|
189
192
|
try {
|
|
190
|
-
|
|
191
|
-
execSync(`codex -q "${parsePrompt.slice(0, 2000)}"`, {
|
|
193
|
+
execSync(`cat .codex-copilot/parse-prd-prompt.md | codex exec --full-auto -`, {
|
|
192
194
|
cwd: projectDir,
|
|
193
195
|
stdio: 'inherit',
|
|
194
196
|
});
|
|
195
|
-
log.info('CodeX
|
|
197
|
+
log.info('CodeX decomposition complete!');
|
|
196
198
|
} catch {
|
|
197
|
-
log.warn('CodeX CLI
|
|
199
|
+
log.warn('CodeX CLI invocation failed. Please run manually.');
|
|
198
200
|
}
|
|
199
201
|
}
|
|
200
202
|
}
|
|
@@ -204,7 +206,8 @@ export async function init(projectDir) {
|
|
|
204
206
|
|
|
205
207
|
function checkCodexCLI() {
|
|
206
208
|
try {
|
|
207
|
-
|
|
209
|
+
const cmd = process.platform === 'win32' ? 'where codex' : 'which codex';
|
|
210
|
+
execSync(cmd, { stdio: 'pipe' });
|
|
208
211
|
return true;
|
|
209
212
|
} catch {
|
|
210
213
|
return false;
|
|
@@ -212,27 +215,27 @@ function checkCodexCLI() {
|
|
|
212
215
|
}
|
|
213
216
|
|
|
214
217
|
function buildParsePrompt(prdContent, copilotDir) {
|
|
215
|
-
return
|
|
218
|
+
return `Read the following PRD document and break it down into independent development tasks.
|
|
216
219
|
|
|
217
|
-
##
|
|
218
|
-
1.
|
|
219
|
-
2.
|
|
220
|
-
3.
|
|
221
|
-
4.
|
|
220
|
+
## Requirements
|
|
221
|
+
1. Each task should be completable in a single PR (moderate granularity — not too large, not too small)
|
|
222
|
+
2. Each task must have clear acceptance criteria
|
|
223
|
+
3. Tasks should be ordered by dependency (dependent tasks first)
|
|
224
|
+
4. The first task is usually "Project initialization / base framework setup"
|
|
222
225
|
|
|
223
|
-
##
|
|
224
|
-
|
|
226
|
+
## Output Format
|
|
227
|
+
Write the result to \`.codex-copilot/tasks.json\` in the following format:
|
|
225
228
|
|
|
226
229
|
\`\`\`json
|
|
227
230
|
{
|
|
228
|
-
"project": "
|
|
231
|
+
"project": "Project Name",
|
|
229
232
|
"total": 5,
|
|
230
233
|
"tasks": [
|
|
231
234
|
{
|
|
232
235
|
"id": 1,
|
|
233
|
-
"title": "
|
|
234
|
-
"description": "
|
|
235
|
-
"acceptance": ["
|
|
236
|
+
"title": "Task title (brief)",
|
|
237
|
+
"description": "Detailed task description with specific features and technical details",
|
|
238
|
+
"acceptance": ["Acceptance criteria 1", "Acceptance criteria 2"],
|
|
236
239
|
"branch": "feature/001-task-slug",
|
|
237
240
|
"status": "pending",
|
|
238
241
|
"depends_on": []
|
|
@@ -250,7 +253,7 @@ function buildParsePrompt(prdContent, copilotDir) {
|
|
|
250
253
|
}
|
|
251
254
|
\`\`\`
|
|
252
255
|
|
|
253
|
-
## PRD
|
|
256
|
+
## PRD Document Content
|
|
254
257
|
|
|
255
258
|
${prdContent}
|
|
256
259
|
`;
|
package/src/commands/reset.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* codex-copilot reset -
|
|
2
|
+
* codex-copilot reset - Reset state
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
5
|
import { readFileSync, writeFileSync, existsSync, unlinkSync } from 'fs';
|
|
@@ -12,17 +12,17 @@ export async function reset(projectDir) {
|
|
|
12
12
|
const tasksPath = resolve(projectDir, '.codex-copilot/tasks.json');
|
|
13
13
|
|
|
14
14
|
if (!existsSync(statePath)) {
|
|
15
|
-
log.warn('
|
|
15
|
+
log.warn('Project not initialized, nothing to reset');
|
|
16
16
|
closePrompt();
|
|
17
17
|
return;
|
|
18
18
|
}
|
|
19
19
|
|
|
20
|
-
log.title('🔄
|
|
20
|
+
log.title('🔄 Resetting Codex-Copilot state');
|
|
21
21
|
log.blank();
|
|
22
22
|
|
|
23
|
-
const resetTasks = await confirm('
|
|
23
|
+
const resetTasks = await confirm('Also reset all task statuses to pending?', false);
|
|
24
24
|
|
|
25
|
-
//
|
|
25
|
+
// Reset state
|
|
26
26
|
const state = {
|
|
27
27
|
current_task: 0,
|
|
28
28
|
current_pr: null,
|
|
@@ -30,23 +30,23 @@ export async function reset(projectDir) {
|
|
|
30
30
|
status: 'initialized',
|
|
31
31
|
};
|
|
32
32
|
writeFileSync(statePath, JSON.stringify(state, null, 2));
|
|
33
|
-
log.info('
|
|
33
|
+
log.info('Execution state reset');
|
|
34
34
|
|
|
35
|
-
//
|
|
35
|
+
// Reset task statuses
|
|
36
36
|
if (resetTasks && existsSync(tasksPath)) {
|
|
37
37
|
const tasks = JSON.parse(readFileSync(tasksPath, 'utf-8'));
|
|
38
38
|
for (const task of tasks.tasks) {
|
|
39
39
|
task.status = 'pending';
|
|
40
40
|
}
|
|
41
41
|
writeFileSync(tasksPath, JSON.stringify(tasks, null, 2));
|
|
42
|
-
log.info('
|
|
42
|
+
log.info('Task statuses reset');
|
|
43
43
|
}
|
|
44
44
|
|
|
45
|
-
//
|
|
45
|
+
// Clean up temp files
|
|
46
46
|
const promptPath = resolve(projectDir, '.codex-copilot/_current_prompt.md');
|
|
47
47
|
if (existsSync(promptPath)) unlinkSync(promptPath);
|
|
48
48
|
|
|
49
49
|
log.blank();
|
|
50
|
-
log.info('✅
|
|
50
|
+
log.info('✅ Reset complete. You can now run: codex-copilot run');
|
|
51
51
|
closePrompt();
|
|
52
52
|
}
|