@esneiderbravo/speclaw 2.0.5 → 2.0.6

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/README.md CHANGED
@@ -4,12 +4,12 @@
4
4
 
5
5
  <br/>
6
6
 
7
- <a href="https://www.npmjs.com/package/@esneiderbravo/speclaw"><img src="https://img.shields.io/npm/v/@esneiderbravo/speclaw?color=0E8E8E&labelColor=0B0F10&style=flat-square&label=npm" alt="npm"></a>
8
- &nbsp;<a href="https://github.com/esneiderbravo/speclaw/actions/workflows/ci.yml"><img src="https://img.shields.io/github/actions/workflow/status/esneiderbravo/speclaw/ci.yml?branch=main&label=CI&labelColor=0B0F10&style=flat-square&color=0E8E8E" alt="CI"></a>
9
- &nbsp;<a href="https://www.npmjs.com/package/@esneiderbravo/speclaw?activeTab=versions"><img src="https://img.shields.io/badge/provenance-SLSA-0E8E8E?labelColor=0B0F10&style=flat-square" alt="npm provenance"></a>
10
- &nbsp;<a href="LICENSE"><img src="https://img.shields.io/badge/license-MIT-0E8E8E?labelColor=0B0F10&style=flat-square" alt="MIT"></a>
11
- &nbsp;<img src="https://img.shields.io/badge/node-%E2%89%A522.16-0E8E8E?labelColor=0B0F10&style=flat-square" alt="Node >= 22.16">
12
- &nbsp;<img src="https://img.shields.io/badge/v2.0-0E8E8E?labelColor=0B0F10&style=flat-square" alt="v2.0">
7
+ <a href="https://www.npmjs.com/package/@esneiderbravo/speclaw"><img src="https://img.shields.io/npm/v/@esneiderbravo/speclaw?color=00707f&labelColor=131313&style=flat-square&label=npm" alt="npm"></a>
8
+ &nbsp;<a href="https://github.com/esneiderbravo/speclaw/actions/workflows/ci.yml"><img src="https://img.shields.io/github/actions/workflow/status/esneiderbravo/speclaw/ci.yml?branch=main&label=CI&labelColor=131313&style=flat-square&color=00707f" alt="CI"></a>
9
+ &nbsp;<a href="https://www.npmjs.com/package/@esneiderbravo/speclaw?activeTab=versions"><img src="https://img.shields.io/badge/provenance-SLSA-00707f?labelColor=131313&style=flat-square" alt="npm provenance"></a>
10
+ &nbsp;<a href="LICENSE"><img src="https://img.shields.io/badge/license-MIT-00707f?labelColor=131313&style=flat-square" alt="MIT"></a>
11
+ &nbsp;<img src="https://img.shields.io/badge/node-%E2%89%A522.16-00707f?labelColor=131313&style=flat-square" alt="Node >= 22.16">
12
+ &nbsp;<img src="https://img.shields.io/badge/v2.0-00707f?labelColor=131313&style=flat-square" alt="v2.0">
13
13
 
14
14
  <br/><br/>
15
15
 
@@ -24,12 +24,12 @@ those laws hold in the editor, in CI, and in the PR.
24
24
  One command. No cloud, no LLM, no API keys — <b>everything runs on your machine.</b>
25
25
  </p>
26
26
 
27
- <img src="https://img.shields.io/badge/100%25_local-0E8E8E?labelColor=0B0F10&style=flat-square" alt="100% local">
28
- &nbsp;<img src="https://img.shields.io/badge/no_LLM_·_no_cloud-0E8E8E?labelColor=0B0F10&style=flat-square" alt="no LLM">
29
- &nbsp;<img src="https://img.shields.io/badge/CLI_+_MCP-0E8E8E?labelColor=0B0F10&style=flat-square" alt="CLI + MCP">
30
- &nbsp;<img src="https://img.shields.io/badge/9_canonical_tools-0E8E8E?labelColor=0B0F10&style=flat-square" alt="9 tools">
31
- &nbsp;<img src="https://img.shields.io/badge/Cortex-One_brain._Many_agents.-0E8E8E?labelColor=0B0F10&style=flat-square" alt="Cortex">
32
- &nbsp;<img src="https://img.shields.io/badge/any_agent-0E8E8E?labelColor=0B0F10&style=flat-square" alt="any agent">
27
+ <img src="https://img.shields.io/badge/100%25_local-00707f?labelColor=131313&style=flat-square" alt="100% local">
28
+ &nbsp;<img src="https://img.shields.io/badge/no_LLM_·_no_cloud-00707f?labelColor=131313&style=flat-square" alt="no LLM">
29
+ &nbsp;<img src="https://img.shields.io/badge/CLI_+_MCP-00707f?labelColor=131313&style=flat-square" alt="CLI + MCP">
30
+ &nbsp;<img src="https://img.shields.io/badge/9_canonical_tools-00707f?labelColor=131313&style=flat-square" alt="9 tools">
31
+ &nbsp;<img src="https://img.shields.io/badge/Cortex-One_brain._Many_agents.-00707f?labelColor=131313&style=flat-square" alt="Cortex">
32
+ &nbsp;<img src="https://img.shields.io/badge/any_agent-00707f?labelColor=131313&style=flat-square" alt="any agent">
33
33
 
34
34
  </div>
35
35
 
@@ -107,7 +107,7 @@ gh attestation verify <tarball> --owner esneiderbravo
107
107
  <img src="https://raw.githubusercontent.com/esneiderbravo/speclaw/main/brand/terminal-init.png" width="800" alt="speclaw init — terminal output">
108
108
  </p>
109
109
 
110
- <p align="center"><i>Teal steps, green checks, a live progress bar — themed with the speclaw palette.</i></p>
110
+ <p align="center"><i>Cyan steps, green checks, a live progress bar — themed with the speclaw palette.</i></p>
111
111
 
112
112
  <br/>
113
113
 
@@ -1,17 +1,21 @@
1
- // Brand-themed terminal UI. Colors come from the speclaw palette (cyan #2EE6E6
2
- // = the "law", cream text, muted gray, green/amber for status) rendered as
3
- // 24-bit truecolor ANSI — no dependency needed. Colors auto-disable when the
4
- // output is not a TTY or NO_COLOR is set.
1
+ // Brand-themed terminal UI. Colors come from the speclaw site's ink theme
2
+ // (`app/tokens.css` in speclaw-site): signal cyan #00E3FD = the "law" accent,
3
+ // ink #F4F4F3 primary text, ink-faint #999EA3 secondary text, deny #FF5C47 for
4
+ // errors, and green/amber re-tuned for success/warning. Every color holds at
5
+ // least 4.5:1 (WCAG 2.x) against the ink paper #131313. They render as 24-bit
6
+ // truecolor ANSI — no dependency needed — and auto-disable when the output is
7
+ // not a TTY or NO_COLOR is set.
5
8
  import { pkgVersion } from "../../shared/version.js";
6
- const PALETTE = {
7
- cyan: [46, 230, 230], // #2EE6E6 — the accent / "law"
8
- cyanDim: [23, 193, 193], // #17C1C1
9
- cream: [244, 241, 234], // #F4F1EA — primary text
10
- muted: [110, 123, 128], // #6E7B80 — secondary text
11
- green: [63, 185, 80], // #3FB950 — success
12
- amber: [227, 179, 65], // #E3B341 — warning
13
- red: [235, 90, 90],
14
- };
9
+ // Covers: req~brand-terminal-palette~1
10
+ export const PALETTE = Object.freeze({
11
+ cyan: [0, 227, 253], // #00E3FD — signal: the accent / "law"
12
+ cyanDim: [0, 227, 253], // #00E3FD — signal (the site has no mid cyan for text)
13
+ cream: [244, 244, 243], // #F4F4F3 — ink: primary text
14
+ muted: [153, 158, 163], // #999EA3 — ink-faint: secondary text
15
+ green: [62, 207, 122], // #3ECF7A — success (re-tuned)
16
+ amber: [245, 183, 61], // #F5B73D — warning (re-tuned)
17
+ red: [255, 92, 71], // #FF5C47 — deny: errors
18
+ });
15
19
  const colorOn = (Boolean(process.stdout.isTTY) || process.env.FORCE_COLOR === "1") && !process.env.NO_COLOR;
16
20
  // Whether the terminal reliably renders the unicode box/block glyphs the brand
17
21
  // output uses. Non-Windows terminals are assumed capable; a Windows console is
@@ -88,11 +88,14 @@ export function visualize(projectPath, opts = {}) {
88
88
  /**
89
89
  * Render the graph as a self-contained, offline HTML page: the data is embedded
90
90
  * as JSON and drawn by an inline canvas force-directed renderer (no CDN, no
91
- * dependencies).
91
+ * dependencies). Colors are the site's ink tokens (`app/tokens.css` in
92
+ * speclaw-site): paper #131313, sheet #1f2022, rule #303236, ink #f4f4f3,
93
+ * ink-faint #999ea3, signal #00e3fd. No retired-palette color may return here.
92
94
  *
93
95
  * @param data - The nodes/links/totals to embed.
94
96
  * @returns A complete HTML document as a string.
95
97
  */
98
+ // Covers: req~brand-viewer-palette~1
96
99
  export function renderHtml(data) {
97
100
  const payload = JSON.stringify(data);
98
101
  return `<!doctype html>
@@ -100,20 +103,20 @@ export function renderHtml(data) {
100
103
  <meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1">
101
104
  <title>speclaw · Compass graph</title>
102
105
  <style>
103
- :root { --cy:#17C1C1; --cr:#F4F1EA; --mu:#6E7B80; --bg:#0B0F10; }
106
+ :root { --cy:#00e3fd; --cr:#f4f4f3; --mu:#999ea3; --bg:#131313; --sh:#1f2022; --ru:#303236; }
104
107
  * { box-sizing:border-box; }
105
108
  html,body { margin:0; height:100%; background:var(--bg); color:var(--cr);
106
- font-family:'SF Mono','JetBrains Mono',Menlo,Consolas,monospace; overflow:hidden; }
109
+ font-family:'Chivo Mono','SFMono-Regular',Menlo,monospace; overflow:hidden; }
107
110
  canvas { display:block; cursor:grab; }
108
111
  canvas:active { cursor:grabbing; }
109
112
  .panel { position:fixed; top:16px; left:16px; padding:12px 14px; border-radius:10px;
110
- background:rgba(12,17,19,.82); border:1px solid #232A2D; font-size:12px; line-height:1.5; }
113
+ background:rgba(31,32,34,.82); border:1px solid var(--ru); font-size:12px; line-height:1.5; }
111
114
  .panel b { color:var(--cr); } .panel .sub { color:var(--mu); }
112
115
  .legend { position:fixed; bottom:16px; left:16px; font-size:11px; color:var(--mu);
113
- background:rgba(12,17,19,.82); border:1px solid #232A2D; border-radius:10px; padding:10px 12px; }
116
+ background:rgba(31,32,34,.82); border:1px solid var(--ru); border-radius:10px; padding:10px 12px; }
114
117
  .legend span { display:inline-flex; align-items:center; margin-right:12px; }
115
118
  .legend i { width:9px; height:9px; border-radius:50%; display:inline-block; margin-right:5px; }
116
- .tip { position:fixed; padding:6px 9px; border-radius:7px; background:#0E1517; border:1px solid #17C1C1;
119
+ .tip { position:fixed; padding:6px 9px; border-radius:7px; background:var(--sh); border:1px solid var(--cy);
117
120
  color:var(--cr); font-size:12px; pointer-events:none; opacity:0; transition:opacity .1s; white-space:nowrap; }
118
121
  .brand { color:var(--cy); font-weight:700; }
119
122
  </style></head><body>
@@ -127,9 +130,9 @@ export function renderHtml(data) {
127
130
  <div class="tip" id="tip"></div>
128
131
  <script>
129
132
  const DATA = ${payload};
130
- const KIND_COLORS = { function:'#17C1C1', method:'#3FB950', class:'#E3B341',
131
- interface:'#8B989E', type:'#8B989E', enum:'#8B989E' };
132
- const colorOf = k => KIND_COLORS[k] || '#6E7B80';
133
+ const KIND_COLORS = { function:'#00e3fd', method:'#3ecf7a', class:'#f5b73d',
134
+ interface:'#babdc1', type:'#babdc1', enum:'#babdc1' };
135
+ const colorOf = k => KIND_COLORS[k] || '#7c8083';
133
136
 
134
137
  const cv = document.getElementById('c'), ctx = cv.getContext('2d');
135
138
  const tip = document.getElementById('tip');
@@ -179,7 +182,7 @@ function draw(){
179
182
  ctx.lineWidth = 1;
180
183
  for(const l of L){ const a=toScreen(N[l.s]), b=toScreen(N[l.t]);
181
184
  const on = hover>=0 && (l.s===hover||l.t===hover);
182
- ctx.strokeStyle = on ? 'rgba(23,193,193,.7)' : 'rgba(110,123,128,.16)';
185
+ ctx.strokeStyle = on ? 'rgba(0,227,253,.7)' : 'rgba(124,128,131,.16)';
183
186
  ctx.beginPath(); ctx.moveTo(a.x,a.y); ctx.lineTo(b.x,b.y); ctx.stroke();
184
187
  }
185
188
  for(let i=0;i<N.length;i++){ const n=N[i], p=toScreen(n);
@@ -187,7 +190,7 @@ function draw(){
187
190
  ctx.globalAlpha = dim ? 0.28 : 1;
188
191
  ctx.beginPath(); ctx.arc(p.x,p.y,n.r*Math.sqrt(scale),0,7); ctx.fillStyle=colorOf(n.kind); ctx.fill();
189
192
  if((n.r>7 || i===hover || (hoverSet&&hoverSet.has(i))) && scale>0.5){
190
- ctx.globalAlpha = dim?0.4:0.9; ctx.fillStyle='#F4F1EA'; ctx.font='11px monospace';
193
+ ctx.globalAlpha = dim?0.4:0.9; ctx.fillStyle='#f4f4f3'; ctx.font="11px 'Chivo Mono','SFMono-Regular',Menlo,monospace";
191
194
  ctx.fillText(n.name, p.x+n.r+3, p.y+3);
192
195
  }
193
196
  }
@@ -208,7 +211,7 @@ addEventListener('mousemove', e=>{
208
211
  lastX=e.clientX; lastY=e.clientY;
209
212
  const i=pick(e.clientX,e.clientY); hover=i;
210
213
  if(i>=0){ const n=N[i]; tip.style.opacity=1; tip.style.left=(e.clientX+12)+'px'; tip.style.top=(e.clientY+12)+'px';
211
- tip.innerHTML='<b>'+n.name+'</b> <span style="color:#6E7B80">'+n.kind+' · '+n.file+':'+n.line+'</span>'; }
214
+ tip.innerHTML='<b>'+n.name+'</b> <span style="color:#999ea3">'+n.kind+' · '+n.file+':'+n.line+'</span>'; }
212
215
  else tip.style.opacity=0;
213
216
  });
214
217
  addEventListener('mouseup', ()=>{ dragging=null; panning=false; });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@esneiderbravo/speclaw",
3
- "version": "2.0.5",
3
+ "version": "2.0.6",
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },
@@ -59,6 +59,8 @@
59
59
  },
60
60
  "devDependencies": {
61
61
  "@eslint/js": "^10.0.1",
62
+ "@fontsource/chivo": "^5.3.0",
63
+ "@fontsource/chivo-mono": "^5.3.0",
62
64
  "@resvg/resvg-js": "^2.6.2",
63
65
  "@types/node": "^22.0.0",
64
66
  "eslint": "^10.8.0",
@@ -67,6 +69,7 @@
67
69
  "globals": "^17.9.0",
68
70
  "prettier": "^3.9.6",
69
71
  "typescript": "^5.6.0",
70
- "typescript-eslint": "^8.65.0"
72
+ "typescript-eslint": "^8.65.0",
73
+ "wawoff2": "^2.0.1"
71
74
  }
72
75
  }