writethevision 7.0.8 → 7.0.9

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.
Files changed (2) hide show
  1. package/package.json +1 -1
  2. package/src/cli.js +71 -3
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "writethevision",
3
- "version": "7.0.8",
3
+ "version": "7.0.9",
4
4
  "description": "Write The Vision (WTV): vision-driven development with the Habakkuk workflow. 10 agents + 21 skills for Claude Code, Codex CLI, and OpenCode.",
5
5
  "author": "Christopher Hogg",
6
6
  "license": "MIT",
package/src/cli.js CHANGED
@@ -3366,7 +3366,7 @@ Task to implement (ONLY this task):
3366
3366
 
3367
3367
  Rules:
3368
3368
  - Implement ONLY the task above.
3369
- - Update PRD.md: change that exact task from '- [ ]' to '- [x]'.
3369
+ - Update PRD.md: change that exact task from '- [ ]' to '- [x]' (lowercase x).
3370
3370
  - Append a short checkpoint entry to progress.txt.
3371
3371
  - Do NOT run git commit.
3372
3372
  - Do NOT run git push.
@@ -3382,6 +3382,23 @@ Stop after completing this one task.`;
3382
3382
 
3383
3383
  const progressBefore = existsSync(progressPath) ? readFileSync(progressPath, 'utf8') : '';
3384
3384
 
3385
+ const workDir = dirname(prdPath);
3386
+ const gitProbe = spawnSync('git', ['rev-parse', '--is-inside-work-tree'], {
3387
+ cwd: workDir,
3388
+ encoding: 'utf8',
3389
+ stdio: ['ignore', 'pipe', 'pipe'],
3390
+ });
3391
+ const hasGit = gitProbe.status === 0 && String(gitProbe.stdout || '').trim() === 'true';
3392
+ const statusBefore = hasGit
3393
+ ? String(
3394
+ spawnSync('git', ['status', '--porcelain'], {
3395
+ cwd: workDir,
3396
+ encoding: 'utf8',
3397
+ stdio: ['ignore', 'pipe', 'pipe'],
3398
+ }).stdout || '',
3399
+ )
3400
+ : '';
3401
+
3385
3402
  const runFn = _runEngine || runEngine;
3386
3403
  const code = await runFn(engine, promptText);
3387
3404
  if (code !== 0) {
@@ -3391,10 +3408,61 @@ Stop after completing this one task.`;
3391
3408
  const afterPrd = readFileSync(prdPath, 'utf8');
3392
3409
  const afterUnchecked = countUncheckedPrdTasks(afterPrd);
3393
3410
 
3394
- const stillUnchecked = afterPrd.includes(`- [ ] ${taskText}`);
3395
- const nowChecked = afterPrd.includes(`- [x] ${taskText}`);
3411
+ const escaped = taskText.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
3412
+ const uncheckedRe = new RegExp(`^\\s*- \\[ \\]\\s+${escaped}\\s*$`, 'm');
3413
+ const checkedRe = new RegExp(`^\\s*- \\[[xX]\\]\\s+${escaped}\\s*$`, 'm');
3414
+
3415
+ let stillUnchecked = uncheckedRe.test(afterPrd);
3416
+ let nowChecked = checkedRe.test(afterPrd);
3396
3417
 
3397
3418
  if (stillUnchecked || (!nowChecked && afterUnchecked >= beforeUnchecked)) {
3419
+ const statusAfter = hasGit
3420
+ ? String(
3421
+ spawnSync('git', ['status', '--porcelain'], {
3422
+ cwd: workDir,
3423
+ encoding: 'utf8',
3424
+ stdio: ['ignore', 'pipe', 'pipe'],
3425
+ }).stdout || '',
3426
+ )
3427
+ : '';
3428
+
3429
+ // Best-effort repair: if the engine changed files but forgot PRD.md, run a
3430
+ // follow-up pass that ONLY updates PRD.md and progress.txt.
3431
+ const hasAnyChanges = hasGit ? statusAfter !== statusBefore : false;
3432
+ if (hasAnyChanges) {
3433
+ const repairPrompt = `You previously completed this PRD task but did NOT update the checklist.
3434
+
3435
+ Fix it now by editing ONLY these files:
3436
+ - PRD.md
3437
+ - progress.txt
3438
+
3439
+ Rules:
3440
+ - Do NOT change any other files.
3441
+ - In PRD.md, find the exact checkbox line for this task and change '- [ ]' to '- [x]':
3442
+ ${taskText}
3443
+ - Append a single new line to progress.txt: "[ISO_TIMESTAMP] Completed: ${taskText}"
3444
+ - Then stop.`;
3445
+
3446
+ const repairCode = await runFn(engine, repairPrompt);
3447
+ if (repairCode !== 0) {
3448
+ throw new Error(`Engine exited with code ${repairCode}`);
3449
+ }
3450
+
3451
+ const repairedPrd = readFileSync(prdPath, 'utf8');
3452
+ const repairedUnchecked = countUncheckedPrdTasks(repairedPrd);
3453
+ stillUnchecked = uncheckedRe.test(repairedPrd);
3454
+ nowChecked = checkedRe.test(repairedPrd);
3455
+
3456
+ if (!stillUnchecked && (nowChecked || repairedUnchecked < beforeUnchecked)) {
3457
+ const repairedProgress = existsSync(progressPath) ? readFileSync(progressPath, 'utf8') : '';
3458
+ if (repairedProgress === progressBefore) {
3459
+ const stamp = new Date().toISOString();
3460
+ writeFileSync(progressPath, repairedProgress + `\n[${stamp}] Completed: ${taskText}\n`);
3461
+ }
3462
+ return;
3463
+ }
3464
+ }
3465
+
3398
3466
  throw new Error('PRD.md was not updated to mark the task complete');
3399
3467
  }
3400
3468