@jojonax/codex-copilot 1.5.2 → 1.5.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jojonax/codex-copilot",
3
- "version": "1.5.2",
3
+ "version": "1.5.3",
4
4
  "description": "PRD-driven automated development orchestrator for CodeX / Cursor",
5
5
  "bin": {
6
6
  "codex-copilot": "./bin/cli.js"
@@ -206,6 +206,24 @@ export async function run(projectDir) {
206
206
  }
207
207
  }
208
208
 
209
+ // ===== Ensure task has all required fields =====
210
+ // Auto-generate branch name if missing (common after corruption recovery)
211
+ if (!task.branch) {
212
+ // Try to recover from checkpoint state
213
+ if (state.current_task === task.id && state.branch) {
214
+ task.branch = state.branch;
215
+ log.dim(` ↳ Recovered branch name from checkpoint: ${task.branch}`);
216
+ } else {
217
+ const slug = (task.title || `task-${task.id}`)
218
+ .toLowerCase().replace(/[^a-z0-9]+/g, '-').replace(/^-|-$/g, '').substring(0, 40);
219
+ task.branch = `feature/${String(task.id).padStart(3, '0')}-${slug}`;
220
+ log.dim(` ↳ Generated branch name: ${task.branch}`);
221
+ }
222
+ }
223
+ if (!task.depends_on) task.depends_on = [];
224
+ if (!task.acceptance) task.acceptance = [];
225
+ if (!task.description) task.description = task.title;
226
+
209
227
  // Mark task as in_progress
210
228
  task.status = 'in_progress';
211
229
  const isRetry = (task.retry_count || 0) > 0;
package/src/utils/json.js CHANGED
@@ -43,8 +43,15 @@ export function readJSON(filePath) {
43
43
  * @returns {any|null} Parsed data or null if all strategies fail
44
44
  */
45
45
  function tryRepair(raw) {
46
+ // Strategy 0: Strip git conflict markers (<<<<<<, ======, >>>>>>)
47
+ // Keep the "ours" side (before =======) and discard "theirs" (after =======)
48
+ let cleaned = raw.replace(
49
+ /^<{4,}[^\n]*\n((?:(?!^={4,})[\s\S])*?)^={4,}[^\n]*\n(?:(?:(?!^>{4,})[\s\S])*?)^>{4,}[^\n]*/gm,
50
+ '$1'
51
+ );
52
+
46
53
  // Strategy 1: Basic cleanup (trailing commas, control chars)
47
- let cleaned = raw
54
+ cleaned = cleaned
48
55
  .replace(/,\s*([}\]])/g, '$1')
49
56
  .replace(/[\x00-\x08\x0E-\x1F]/g, '')
50
57
  .trim();