spectoflow 0.16.1 → 0.16.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/spectoflow.js +63 -30
- package/package.json +1 -1
package/bin/spectoflow.js
CHANGED
|
@@ -20,38 +20,66 @@ const cmd = argv[0] || 'help';
|
|
|
20
20
|
// Tiny ANSI colouriser — no dependency; disabled when not a TTY or NO_COLOR is set.
|
|
21
21
|
const useColor = process.stdout.isTTY && !process.env.NO_COLOR;
|
|
22
22
|
const paint = (code) => (s) => (useColor ? `\x1b[${code}m${s}\x1b[0m` : String(s));
|
|
23
|
-
const c = { g: paint('32'), cy: paint('36'), b: paint('34'), y: paint('33'), dim: paint('2'), bold: paint('1'), amber: paint('38;5;179') };
|
|
23
|
+
const c = { g: paint('32'), cy: paint('36'), b: paint('34'), y: paint('33'), dim: paint('2'), bold: paint('1'), amber: paint('38;5;179'), white: paint('97') };
|
|
24
24
|
|
|
25
25
|
// ---- branding ---------------------------------------------------------------
|
|
26
|
-
// The spectoflow mark in ASCII:
|
|
27
|
-
//
|
|
26
|
+
// The spectoflow mark in ASCII: the brand hexagon around the flowing "S", drawn WHITE.
|
|
27
|
+
// The name is a compact figlet wordmark drawn AMBER, centered under the mark.
|
|
28
28
|
const LOGO = [
|
|
29
|
-
'
|
|
30
|
-
'
|
|
31
|
-
'
|
|
32
|
-
'
|
|
33
|
-
'
|
|
34
|
-
'
|
|
35
|
-
'
|
|
36
|
-
'
|
|
37
|
-
'
|
|
38
|
-
'
|
|
39
|
-
'
|
|
40
|
-
'
|
|
41
|
-
' ###
|
|
42
|
-
'
|
|
43
|
-
'
|
|
44
|
-
'
|
|
45
|
-
'
|
|
29
|
+
' ########',
|
|
30
|
+
' ###### #######',
|
|
31
|
+
' ####### ######',
|
|
32
|
+
' ###### ######',
|
|
33
|
+
' ###### #### ######',
|
|
34
|
+
' ##### ###### ####',
|
|
35
|
+
' #### ###### ####',
|
|
36
|
+
' #### ##### ####',
|
|
37
|
+
' #### #### ## ####',
|
|
38
|
+
' #### #### ######### ####',
|
|
39
|
+
' #### #### ####### ##### ####',
|
|
40
|
+
' #### ######## ### ####',
|
|
41
|
+
' #### ## ### ####',
|
|
42
|
+
' #### #### ####',
|
|
43
|
+
' #### ###### ####',
|
|
44
|
+
' #### ###### ####',
|
|
45
|
+
' #### ###### ####',
|
|
46
|
+
' ###### ### ######',
|
|
47
|
+
' ###### ######',
|
|
48
|
+
' ###### ######',
|
|
49
|
+
' ###### ######',
|
|
50
|
+
' ##########',
|
|
51
|
+
' ####',
|
|
46
52
|
];
|
|
47
|
-
const
|
|
48
|
-
|
|
53
|
+
const NAME = [
|
|
54
|
+
' _ __ _',
|
|
55
|
+
' ____ __ ___ __| |_ ___ / _| |_____ __ __',
|
|
56
|
+
" (_-< '_ \\/ -_) _| _/ _ \\ _| / _ \\ V V /",
|
|
57
|
+
' /__/ .__/\\___\\__|\\__\\___/_| |_\\___/\\_/\\_/',
|
|
58
|
+
' |_|',
|
|
59
|
+
];
|
|
60
|
+
const NAME_W = Math.max(...NAME.map((l) => l.length));
|
|
49
61
|
const TAGLINE = 'agent-agnostic spec-driven development · real-time control plane';
|
|
50
|
-
|
|
62
|
+
const INDENT = ' ';
|
|
63
|
+
|
|
64
|
+
// Amber wordmark, indented. `centerUnder` centres it below the hexagon's true midpoint.
|
|
65
|
+
function nameBlock(centerUnder) {
|
|
66
|
+
let pad = INDENT;
|
|
67
|
+
if (centerUnder) {
|
|
68
|
+
let lo = Infinity, hi = 0;
|
|
69
|
+
for (const l of LOGO) { const i = l.search(/#/); if (i >= 0) { lo = Math.min(lo, i); hi = Math.max(hi, l.length - 1); } }
|
|
70
|
+
const cx = INDENT.length + (lo + hi) / 2;
|
|
71
|
+
pad = ' '.repeat(Math.max(0, Math.round(cx - NAME_W / 2)));
|
|
72
|
+
}
|
|
73
|
+
return NAME.map((l) => pad + c.amber(l)).join('\n');
|
|
74
|
+
}
|
|
75
|
+
// Full logo — white hexagon + centered amber wordmark + version. For init and update.
|
|
51
76
|
function logo() {
|
|
52
|
-
const art = LOGO.map((l) =>
|
|
53
|
-
|
|
54
|
-
|
|
77
|
+
const art = LOGO.map((l) => INDENT + c.white(l)).join('\n');
|
|
78
|
+
return `\n${art}\n\n${nameBlock(true)}\n\n${INDENT}${c.dim('v' + VERSION + ' · ' + TAGLINE)}\n`;
|
|
79
|
+
}
|
|
80
|
+
// Just the amber wordmark + version. For help and the explore commands.
|
|
81
|
+
function wordmark() {
|
|
82
|
+
return `\n${nameBlock(false)}\n\n${INDENT}${c.dim('v' + VERSION + ' · ' + TAGLINE)}\n`;
|
|
55
83
|
}
|
|
56
84
|
// One-line brand — for the header of secondary command outputs.
|
|
57
85
|
const brandLine = () => `${c.amber('spectoflow')} ${c.dim('v' + VERSION)}`;
|
|
@@ -260,7 +288,7 @@ function update() {
|
|
|
260
288
|
const detail = note ? c.dim(note) : c.dim(list.slice(0, 6).join(', ') + (list.length > 6 ? ` +${list.length - 6} more` : ''));
|
|
261
289
|
console.log(` ${sym} ${painter(label.padEnd(9))} ${n} ${detail}`);
|
|
262
290
|
};
|
|
263
|
-
console.log(
|
|
291
|
+
console.log(logo());
|
|
264
292
|
console.log(` ${c.bold('spectoflow update')} ${c.dim(from)} ${c.amber('→')} ${c.bold(r.toVersion)}${dryRun ? c.dim(' (dry-run)') : ''}`);
|
|
265
293
|
console.log('');
|
|
266
294
|
row(c.g('✓'), 'refreshed', r.refreshed, c.g);
|
|
@@ -397,7 +425,7 @@ function printWorkflow(withBrand = true) {
|
|
|
397
425
|
}
|
|
398
426
|
function listAll() {
|
|
399
427
|
const { scope } = frameworkSource();
|
|
400
|
-
console.log(
|
|
428
|
+
console.log(wordmark());
|
|
401
429
|
console.log(`${c.bold('Agents')} ${c.dim('— stable team personas (' + scope + ')')}`);
|
|
402
430
|
printAgents(false);
|
|
403
431
|
console.log(`\n${c.bold('Skills')} ${c.dim('— evolving procedures')}`);
|
|
@@ -408,7 +436,7 @@ function listAll() {
|
|
|
408
436
|
}
|
|
409
437
|
|
|
410
438
|
// ---- help (global + per-command) --------------------------------------------
|
|
411
|
-
const help = () => console.log(`${
|
|
439
|
+
const help = () => console.log(`${wordmark()}
|
|
412
440
|
${c.dim('Usage:')} spectoflow ${c.g('<command>')} ${c.dim('[options]')} ${c.dim('· append -h to any command for its help')}
|
|
413
441
|
|
|
414
442
|
${c.bold('Project')}
|
|
@@ -467,7 +495,12 @@ const HELP = {
|
|
|
467
495
|
const showHelp = (name) => console.log('\n' + HELP[name].trim() + '\n');
|
|
468
496
|
|
|
469
497
|
// ---- dispatch ---------------------------------------------------------------
|
|
470
|
-
const fns = {
|
|
498
|
+
const fns = {
|
|
499
|
+
init, update, dashboard, stop: stopDashboard, status, list: listAll, help, version,
|
|
500
|
+
agents: () => { console.log(wordmark()); printAgents(false); },
|
|
501
|
+
skills: () => { console.log(wordmark()); printSkills(false); },
|
|
502
|
+
workflow: () => { console.log(wordmark()); printWorkflow(false); },
|
|
503
|
+
};
|
|
471
504
|
const wantsHelp = argv.slice(1).some((a) => a === '-h' || a === '--help');
|
|
472
505
|
|
|
473
506
|
if (['-v', '-V', '--version', 'version'].includes(cmd)) version();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "spectoflow",
|
|
3
|
-
"version": "0.16.
|
|
3
|
+
"version": "0.16.3",
|
|
4
4
|
"description": "Agent-agnostic spec-driven development framework + real-time local control plane. Markdown artifacts, intent router, workflow-by-scope.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"spec-driven-development",
|