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.
Files changed (2) hide show
  1. package/bin/spectoflow.js +63 -30
  2. 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: a flat-top hexagon around the angular "S" (flow), rasterized to fit
27
- // a terminal. Shown at the reading moments (init / help / list); secondary outputs use brandLine().
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 LOGO_W = 41; // widest logo line, for centering the wordmark under it
48
- const NAME = 's p e c t o f l o w';
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
- // Full logo block — hexagon mark + centered wordmark + version. For init, help and list.
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) => ' ' + c.amber(l)).join('\n');
53
- const pad = ' '.repeat(Math.max(0, Math.round((2 + LOGO_W - NAME.length) / 2)));
54
- return `\n${art}\n\n${pad}${c.bold(c.amber(NAME))}\n ${c.dim('v' + VERSION + ' · ' + TAGLINE)}\n`;
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(logo());
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(`${logo()}
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 = { init, update, dashboard, stop: stopDashboard, status, list: listAll, agents: () => printAgents(), skills: () => printSkills(), workflow: () => printWorkflow(), help, version };
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.1",
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",