writethevision 7.0.2 → 7.0.4
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 +88 -24
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "writethevision",
|
|
3
|
-
"version": "7.0.
|
|
3
|
+
"version": "7.0.4",
|
|
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
|
@@ -402,6 +402,73 @@ function getAgentLocations() {
|
|
|
402
402
|
return locations;
|
|
403
403
|
}
|
|
404
404
|
|
|
405
|
+
const BLOCK_FONT_3X5 = {
|
|
406
|
+
A: ['███', '█ █', '███', '█ █', '█ █'],
|
|
407
|
+
B: ['██ ', '█ █', '██ ', '█ █', '██ '],
|
|
408
|
+
C: ['███', '█ ', '█ ', '█ ', '███'],
|
|
409
|
+
D: ['██ ', '█ █', '█ █', '█ █', '██ '],
|
|
410
|
+
E: ['███', '█ ', '██ ', '█ ', '███'],
|
|
411
|
+
F: ['███', '█ ', '██ ', '█ ', '█ '],
|
|
412
|
+
G: ['███', '█ ', '█ █', '█ █', '███'],
|
|
413
|
+
H: ['█ █', '█ █', '███', '█ █', '█ █'],
|
|
414
|
+
I: ['███', ' █ ', ' █ ', ' █ ', '███'],
|
|
415
|
+
J: [' ██', ' █', ' █', '█ █', '██ '],
|
|
416
|
+
K: ['█ █', '█ █', '██ ', '█ █', '█ █'],
|
|
417
|
+
L: ['█ ', '█ ', '█ ', '█ ', '███'],
|
|
418
|
+
M: ['█ █', '███', '███', '█ █', '█ █'],
|
|
419
|
+
N: ['█ █', '███', '███', '███', '█ █'],
|
|
420
|
+
O: ['███', '█ █', '█ █', '█ █', '███'],
|
|
421
|
+
P: ['███', '█ █', '███', '█ ', '█ '],
|
|
422
|
+
Q: ['███', '█ █', '█ █', '███', ' █'],
|
|
423
|
+
R: ['███', '█ █', '███', '█ █', '█ █'],
|
|
424
|
+
S: ['███', '█ ', '███', ' █', '███'],
|
|
425
|
+
T: ['███', ' █ ', ' █ ', ' █ ', ' █ '],
|
|
426
|
+
U: ['█ █', '█ █', '█ █', '█ █', '███'],
|
|
427
|
+
V: ['█ █', '█ █', '█ █', '█ █', ' █ '],
|
|
428
|
+
W: ['█ █', '█ █', '███', '███', '█ █'],
|
|
429
|
+
X: ['█ █', '█ █', ' █ ', '█ █', '█ █'],
|
|
430
|
+
Y: ['█ █', '█ █', ' █ ', ' █ ', ' █ '],
|
|
431
|
+
Z: ['███', ' █', ' █ ', '█ ', '███'],
|
|
432
|
+
' ': [' ', ' ', ' ', ' ', ' '],
|
|
433
|
+
'-': [' ', ' ', '███', ' ', ' '],
|
|
434
|
+
'?': ['███', ' █', ' ██', ' ', ' █ '],
|
|
435
|
+
};
|
|
436
|
+
|
|
437
|
+
function renderBlockText(text, { maxWidth = null, color = null, bold = false } = {}) {
|
|
438
|
+
const normalized = String(text || '').toUpperCase();
|
|
439
|
+
const glyphWidth = 3;
|
|
440
|
+
const letterGap = 1;
|
|
441
|
+
const maxCharsPerLine = maxWidth
|
|
442
|
+
? Math.max(1, Math.floor((maxWidth + letterGap) / (glyphWidth + letterGap)))
|
|
443
|
+
: normalized.length;
|
|
444
|
+
|
|
445
|
+
const chunks = [];
|
|
446
|
+
for (let i = 0; i < normalized.length; i += maxCharsPerLine) {
|
|
447
|
+
chunks.push(normalized.slice(i, i + maxCharsPerLine));
|
|
448
|
+
}
|
|
449
|
+
|
|
450
|
+
const renderedLines = [];
|
|
451
|
+
for (let chunkIndex = 0; chunkIndex < chunks.length; chunkIndex++) {
|
|
452
|
+
const chunk = chunks[chunkIndex];
|
|
453
|
+
for (let row = 0; row < 5; row++) {
|
|
454
|
+
const rowText = chunk
|
|
455
|
+
.split('')
|
|
456
|
+
.map(ch => (BLOCK_FONT_3X5[ch] ? BLOCK_FONT_3X5[ch][row] : BLOCK_FONT_3X5['?']?.[row] || '???'))
|
|
457
|
+
.join(' '.repeat(letterGap));
|
|
458
|
+
|
|
459
|
+
const prefix = color ? (bold ? color + c.bold : color) : '';
|
|
460
|
+
const suffix = color ? c.reset : '';
|
|
461
|
+
renderedLines.push(prefix + rowText + suffix);
|
|
462
|
+
}
|
|
463
|
+
|
|
464
|
+
if (chunkIndex !== chunks.length - 1) {
|
|
465
|
+
renderedLines.push('');
|
|
466
|
+
}
|
|
467
|
+
}
|
|
468
|
+
|
|
469
|
+
return renderedLines.join('\n');
|
|
470
|
+
}
|
|
471
|
+
|
|
405
472
|
function parseAgentFile(filePath) {
|
|
406
473
|
if (!existsSync(filePath)) return null;
|
|
407
474
|
|
|
@@ -1676,11 +1743,7 @@ async function meetTheTeam() {
|
|
|
1676
1743
|
console.log(` ${c.bold}${c.yellow}PAUL — THE MASTERBUILDER${c.reset}`);
|
|
1677
1744
|
console.log(` ${c.dim}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${c.reset}`);
|
|
1678
1745
|
const paulAgent = parseAgentFile(join(TEMPLATES_DIR, 'agents', 'paul.md'));
|
|
1679
|
-
|
|
1680
|
-
console.log(paulAgent.asciiArt);
|
|
1681
|
-
} else {
|
|
1682
|
-
console.log(AVATARS.paul);
|
|
1683
|
-
}
|
|
1746
|
+
console.log(AVATARS.paul || (paulAgent && paulAgent.asciiArt ? paulAgent.asciiArt : ''));
|
|
1684
1747
|
await sleep(shortPause);
|
|
1685
1748
|
console.log(`
|
|
1686
1749
|
${c.cyan}"According to the grace of God which is given unto me,${c.reset}
|
|
@@ -1710,11 +1773,7 @@ async function meetTheTeam() {
|
|
|
1710
1773
|
console.log(` ${artisan.color}${c.bold}${artisan.name}${c.reset}`);
|
|
1711
1774
|
const templatePath = join(TEMPLATES_DIR, 'agents', artisan.file);
|
|
1712
1775
|
const agent = parseAgentFile(templatePath);
|
|
1713
|
-
|
|
1714
|
-
console.log(agent.asciiArt);
|
|
1715
|
-
} else {
|
|
1716
|
-
console.log(AVATARS[artisan.id]);
|
|
1717
|
-
}
|
|
1776
|
+
console.log(AVATARS[artisan.id] || (agent && agent.asciiArt ? agent.asciiArt : ''));
|
|
1718
1777
|
console.log(` ${c.dim}${artisan.domain}${c.reset}`);
|
|
1719
1778
|
if (artisan.verse) {
|
|
1720
1779
|
console.log(` ${c.dim}${artisan.verse.ref}${c.reset} ${c.dim}"${artisan.verse.text}"${c.reset}`);
|
|
@@ -3205,12 +3264,14 @@ async function dashboard() {
|
|
|
3205
3264
|
|
|
3206
3265
|
// Header
|
|
3207
3266
|
console.log(
|
|
3208
|
-
` ${c.magenta}
|
|
3209
|
-
|
|
3210
|
-
|
|
3211
|
-
|
|
3212
|
-
|
|
3213
|
-
|
|
3267
|
+
` ${c.magenta}${c.bold}
|
|
3268
|
+
██╗ ██╗████████╗██╗ ██╗
|
|
3269
|
+
██║ ██║╚══██╔══╝██║ ██║
|
|
3270
|
+
██║ █╗ ██║ ██║ ██║ ██║
|
|
3271
|
+
██║███╗██║ ██║ ╚██╗ ██╔╝
|
|
3272
|
+
╚███╔███╔╝ ██║ ╚████╔╝
|
|
3273
|
+
╚══╝╚══╝ ╚═╝ ╚═══╝
|
|
3274
|
+
${c.reset}`
|
|
3214
3275
|
);
|
|
3215
3276
|
|
|
3216
3277
|
console.log(` ${c.dim}v${getVersion()} • ${tool.toUpperCase()} MODE${c.reset}\n`);
|
|
@@ -3284,11 +3345,12 @@ function dashboardStatic() {
|
|
|
3284
3345
|
// Banner
|
|
3285
3346
|
console.log('');
|
|
3286
3347
|
const wtvAscii = `
|
|
3287
|
-
${c.magenta}
|
|
3288
|
-
${c.magenta}
|
|
3289
|
-
${c.magenta}
|
|
3290
|
-
${c.magenta}
|
|
3291
|
-
${c.magenta}
|
|
3348
|
+
${c.magenta}${c.bold}██╗ ██╗████████╗██╗ ██╗${c.reset}
|
|
3349
|
+
${c.magenta}${c.bold}██║ ██║╚══██╔══╝██║ ██║${c.reset}
|
|
3350
|
+
${c.magenta}${c.bold}██║ █╗ ██║ ██║ ██║ ██║${c.reset}
|
|
3351
|
+
${c.magenta}${c.bold}██║███╗██║ ██║ ╚██╗ ██╔╝${c.reset}
|
|
3352
|
+
${c.magenta}${c.bold}╚███╔███╔╝ ██║ ╚████╔╝ ${c.reset}
|
|
3353
|
+
${c.magenta}${c.bold} ╚══╝╚══╝ ╚═╝ ╚═══╝ ${c.reset}`;
|
|
3292
3354
|
|
|
3293
3355
|
console.log(wtvAscii);
|
|
3294
3356
|
console.log(drawBox([
|
|
@@ -3510,13 +3572,15 @@ async function agentsInteractive() {
|
|
|
3510
3572
|
if (agent.wantsGlobal) statusText += c.blue + 'Global ' + c.reset;
|
|
3511
3573
|
if (!agent.wantsLocal && !agent.wantsGlobal) statusText = c.dim + 'None' + c.reset;
|
|
3512
3574
|
|
|
3575
|
+
const terminalWidth = process.stdout.columns || 80;
|
|
3576
|
+
const detailWidth = Math.max(20, terminalWidth - detailStartX - 1);
|
|
3577
|
+
const nameBanner = renderBlockText(agent.name, { maxWidth: detailWidth, color: c.magenta, bold: true });
|
|
3578
|
+
|
|
3513
3579
|
const details = [
|
|
3514
|
-
|
|
3580
|
+
nameBanner,
|
|
3515
3581
|
`Status: ${statusText}`,
|
|
3516
3582
|
'',
|
|
3517
3583
|
`${c.dim}${agent.description}${c.reset}`,
|
|
3518
|
-
'',
|
|
3519
|
-
agent.asciiArt ? agent.asciiArt : `${c.dim}[ No Portrait ]${c.reset}`
|
|
3520
3584
|
];
|
|
3521
3585
|
|
|
3522
3586
|
// Draw details
|