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.
- package/package.json +1 -1
- package/src/cli.js +71 -3
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "writethevision",
|
|
3
|
-
"version": "7.0.
|
|
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
|
|
3395
|
-
const
|
|
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
|
|