whale-igniter 1.1.0 → 1.2.1

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
@@ -1,4 +1,13 @@
1
- # Whale Igniter
1
+ <p align="center">
2
+ <img src="./brand/lockup.svg" alt="Whale Igniter" width="640">
3
+ </p>
4
+
5
+ <p align="center">
6
+ <a href="https://www.npmjs.com/package/whale-igniter"><img alt="npm" src="https://img.shields.io/npm/v/whale-igniter?color=%230034D3&labelColor=%23F2ECE1&style=flat-square"></a>
7
+ <a href="./LICENSE"><img alt="MIT" src="https://img.shields.io/badge/license-MIT-%230034D3?labelColor=%23F2ECE1&style=flat-square"></a>
8
+ <img alt="node" src="https://img.shields.io/badge/node-%E2%89%A520-%230034D3?labelColor=%23F2ECE1&style=flat-square">
9
+ <img alt="local first" src="https://img.shields.io/badge/local--first-agent%20memory-%230034D3?labelColor=%23F2ECE1&style=flat-square">
10
+ </p>
2
11
 
3
12
  **CLI-first operational intelligence for AI-assisted product workflows.**
4
13
 
@@ -23,6 +32,13 @@ npx whale-igniter ignite my-app
23
32
 
24
33
  Requires Node 20 or newer.
25
34
 
35
+ Whale's executable is `whale`:
36
+
37
+ ```bash
38
+ whale --version
39
+ whale ignite my-app
40
+ ```
41
+
26
42
  ---
27
43
 
28
44
  ## The two-minute version
@@ -54,7 +70,7 @@ opinionated default, `--minimal` skeleton, or `--interactive` wizard.
54
70
  ### 2. Adopts existing projects
55
71
 
56
72
  `whale adopt` parses your React/Tailwind source with a real AST, infers
57
- foundations (grid, radii, paleta), detects components, and stages
73
+ foundations (grid, radii, palette), detects components, and stages
58
74
  proposals you can review and accept. Idempotent — re-runs don't
59
75
  duplicate or overwrite your decisions.
60
76
 
@@ -133,6 +149,12 @@ Available client snippets: `--client claude-code | cursor | zed | raw`.
133
149
  | `whale adopt review` | Walk through pending proposals interactively. |
134
150
  | `whale adopt status` | List proposals without entering review. |
135
151
  | `whale sync` | Regenerate CLAUDE.md + wiki from `intelligence/*.json`. |
152
+ | `whale remember` | Friendly alias for `sync`: update project memory for AI assistants. |
153
+ | `whale check` | Friendly health check: run `validate` and then `insights`. |
154
+ | `whale improve` | Friendly Selene entry point: suggest project-wide improvements. |
155
+ | `whale explain` | Friendly docs entry point: generate reports and wiki/context. |
156
+ | `whale team` | Show active and available AI teammates. |
157
+ | `whale team add <name>` | Add atlas, forge, scribe, lighthouse, or selene as an AI teammate. |
136
158
  | `whale watch` | Auto-regenerate on changes. Flags: `--once`, `--verbose`, `--debounce`. |
137
159
  | `whale validate` | Run validators. Non-zero exit on errors. |
138
160
  | `whale insights` | Local analyzers + recommendations. Flags: `--json`, `--category`, `--min-severity`. |
@@ -227,6 +249,44 @@ don't need to opt in unless you want to override the default.
227
249
 
228
250
  ---
229
251
 
252
+ ## Brand kit
253
+
254
+ Whale ships its identity assets in `brand/` so the GitHub README, npm page,
255
+ demos and future splash surfaces all speak the same visual language.
256
+
257
+ ### Palette
258
+
259
+ | Token | Hex | Role |
260
+ | --- | --- | --- |
261
+ | `--wi-royal` | `#0034D3` | Primary ink, mark body, headings |
262
+ | `--wi-paper` | `#F2ECE1` | Page background, knockout fill |
263
+ | `--wi-sky` | `#99CCFF` | Soft accent and fills |
264
+ | `--wi-deep` | `#003087` | Dark surface and on-light text |
265
+
266
+ ### Typography
267
+
268
+ ```css
269
+ --wi-font-display: "Special Elite", ui-monospace, monospace;
270
+ --wi-font-mono: "JetBrains Mono", ui-monospace, monospace;
271
+ ```
272
+
273
+ - **Display** — `Special Elite`, used for the wordmark and expressive headings.
274
+ - **Mono** — `JetBrains Mono`, used for CLI surfaces and code samples.
275
+
276
+ ### Assets
277
+
278
+ | File | Use |
279
+ | --- | --- |
280
+ | `brand/logo.svg` | Primary mark |
281
+ | `brand/wordmark.svg` | Wordmark only |
282
+ | `brand/lockup.svg` | Mark + wordmark for README and docs |
283
+ | `brand/logo-on-paper.svg` | Mark on paper background |
284
+ | `brand/logo-on-royal.svg` | Knockout mark on royal |
285
+ | `brand/favicon.svg` | Light favicon |
286
+ | `brand/favicon-dark.svg` | Dark favicon |
287
+
288
+ ---
289
+
230
290
  ## CI usage
231
291
 
232
292
  ```yaml
@@ -256,7 +316,7 @@ for automated quality reports.
256
316
 
257
317
  ---
258
318
 
259
- ## What v1.1 doesn't do (and why)
319
+ ## What v1.2 doesn't do (and why)
260
320
 
261
321
  - **Vue / Svelte parsing.** Scanner is React + Tailwind only. Other
262
322
  frameworks need their own parsers; that's post-v1.0.
@@ -273,3 +333,8 @@ See [docs/ROADMAP.md](docs/ROADMAP.md) for what's planned next.
273
333
  ## License
274
334
 
275
335
  MIT. See [LICENSE](LICENSE).
336
+
337
+ <p align="center">
338
+ <img src="./brand/logo.svg" alt="" width="44"><br>
339
+ <sub><b>Whale Igniter</b> · local-first project memory for AI agents</sub>
340
+ </p>
@@ -0,0 +1,10 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64" width="64" height="64" fill="none">
2
+ <rect width="64" height="64" rx="14" fill="#0034D3"></rect>
3
+ <g transform="translate(4 12) scale(0.175)">
4
+ <path d="M 18 76 C 28 60, 70 54, 120 56 C 170 58, 220 70, 256 84 C 270 90, 280 96, 286 102 C 290 100, 294 92, 294 80 C 296 64, 300 46, 308 30 C 312 28, 316 32, 316 40 C 314 56, 308 72, 302 82 C 308 78, 314 76, 320 80 C 322 88, 318 100, 308 108 C 300 114, 292 116, 286 114 C 282 124, 270 132, 252 138 C 220 150, 180 156, 144 156 C 120 156, 108 158, 100 164 C 88 172, 70 172, 60 164 C 56 158, 60 150, 68 148 C 50 144, 32 134, 22 120 C 12 106, 10 90, 18 76 Z" fill="#F2ECE1"></path>
5
+ <path d="M 60 102 L 92 100 M 110 96 L 150 92 M 160 102 L 200 100 M 220 108 L 252 106" stroke="#0034D3" stroke-width="2.4" stroke-linecap="round"></path>
6
+ <path d="M 70 124 L 100 124 M 120 130 L 170 130 M 190 136 L 230 134" stroke="#0034D3" stroke-width="2.0" stroke-linecap="round"></path>
7
+ <circle cx="48" cy="108" r="3.4" fill="#0034D3"></circle>
8
+ <g transform="translate(150 30)"><path d="M 0 -22 L 4 -4 L 22 0 L 4 4 L 0 22 L -4 4 L -22 0 L -4 -4 Z" fill="#F2ECE1"></path><circle r="3" fill="#0034D3"></circle></g>
9
+ </g>
10
+ </svg>
@@ -0,0 +1,10 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64" width="64" height="64" fill="none">
2
+ <rect width="64" height="64" rx="14" fill="#0034D3"></rect>
3
+ <g transform="translate(4 12) scale(0.175)">
4
+ <path d="M 18 76 C 28 60, 70 54, 120 56 C 170 58, 220 70, 256 84 C 270 90, 280 96, 286 102 C 290 100, 294 92, 294 80 C 296 64, 300 46, 308 30 C 312 28, 316 32, 316 40 C 314 56, 308 72, 302 82 C 308 78, 314 76, 320 80 C 322 88, 318 100, 308 108 C 300 114, 292 116, 286 114 C 282 124, 270 132, 252 138 C 220 150, 180 156, 144 156 C 120 156, 108 158, 100 164 C 88 172, 70 172, 60 164 C 56 158, 60 150, 68 148 C 50 144, 32 134, 22 120 C 12 106, 10 90, 18 76 Z" fill="#F2ECE1"></path>
5
+ <path d="M 60 102 L 92 100 M 110 96 L 150 92 M 160 102 L 200 100 M 220 108 L 252 106" stroke="#0034D3" stroke-width="2.4" stroke-linecap="round"></path>
6
+ <path d="M 70 124 L 100 124 M 120 130 L 170 130 M 190 136 L 230 134" stroke="#0034D3" stroke-width="2.0" stroke-linecap="round"></path>
7
+ <circle cx="48" cy="108" r="3.4" fill="#0034D3"></circle>
8
+ <g transform="translate(150 30)"><path d="M 0 -22 L 4 -4 L 22 0 L 4 4 L 0 22 L -4 4 L -22 0 L -4 -4 Z" fill="#F2ECE1"></path><circle r="3" fill="#0034D3"></circle></g>
9
+ </g>
10
+ </svg>
@@ -0,0 +1,10 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64" width="64" height="64" fill="none">
2
+ <rect width="64" height="64" rx="14" fill="#F2ECE1"></rect>
3
+ <g transform="translate(4 12) scale(0.175)">
4
+ <path d="M 18 76 C 28 60, 70 54, 120 56 C 170 58, 220 70, 256 84 C 270 90, 280 96, 286 102 C 290 100, 294 92, 294 80 C 296 64, 300 46, 308 30 C 312 28, 316 32, 316 40 C 314 56, 308 72, 302 82 C 308 78, 314 76, 320 80 C 322 88, 318 100, 308 108 C 300 114, 292 116, 286 114 C 282 124, 270 132, 252 138 C 220 150, 180 156, 144 156 C 120 156, 108 158, 100 164 C 88 172, 70 172, 60 164 C 56 158, 60 150, 68 148 C 50 144, 32 134, 22 120 C 12 106, 10 90, 18 76 Z" fill="#0034D3"></path>
5
+ <path d="M 60 102 L 92 100 M 110 96 L 150 92 M 160 102 L 200 100 M 220 108 L 252 106" stroke="#F2ECE1" stroke-width="2.4" stroke-linecap="round"></path>
6
+ <path d="M 70 124 L 100 124 M 120 130 L 170 130 M 190 136 L 230 134" stroke="#F2ECE1" stroke-width="2.0" stroke-linecap="round"></path>
7
+ <circle cx="48" cy="108" r="3.4" fill="#F2ECE1"></circle>
8
+ <g transform="translate(150 30)"><path d="M 0 -22 L 4 -4 L 22 0 L 4 4 L 0 22 L -4 4 L -22 0 L -4 -4 Z" fill="#0034D3"></path><circle r="3" fill="#F2ECE1"></circle></g>
9
+ </g>
10
+ </svg>
@@ -0,0 +1,18 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 900 240" width="900" height="240" fill="none">
2
+ <rect width="900" height="240" fill="#0034D3"></rect>
3
+ <g transform="translate(20 10)">
4
+ <path d="M 18 76 C 28 60, 70 54, 120 56 C 170 58, 220 70, 256 84 C 270 90, 280 96, 286 102 C 290 100, 294 92, 294 80 C 296 64, 300 46, 308 30 C 312 28, 316 32, 316 40 C 314 56, 308 72, 302 82 C 308 78, 314 76, 320 80 C 322 88, 318 100, 308 108 C 300 114, 292 116, 286 114 C 282 124, 270 132, 252 138 C 220 150, 180 156, 144 156 C 120 156, 108 158, 100 164 C 88 172, 70 172, 60 164 C 56 158, 60 150, 68 148 C 50 144, 32 134, 22 120 C 12 106, 10 90, 18 76 Z" fill="#F2ECE1"></path>
5
+ <path d="M 60 102 L 92 100 M 110 96 L 150 92 M 160 102 L 200 100 M 220 108 L 252 106" stroke="#0034D3" stroke-width="1.6" stroke-linecap="round"></path>
6
+ <path d="M 70 124 L 100 124 M 120 130 L 170 130 M 190 136 L 230 134" stroke="#0034D3" stroke-width="1.4" stroke-linecap="round"></path>
7
+ <circle cx="48" cy="108" r="2.6" fill="#0034D3"></circle>
8
+ <path d="M 18 118 C 36 124, 60 130, 92 134" stroke="#0034D3" stroke-width="1.4" stroke-linecap="round" fill="none"></path>
9
+ <g transform="translate(150 30)"><path d="M 0 -22 L 4 -4 L 22 0 L 4 4 L 0 22 L -4 4 L -22 0 L -4 -4 Z" fill="#F2ECE1"></path><circle r="3" fill="#0034D3"></circle></g>
10
+ <g transform="translate(190 18)"><path d="M 0 -8 L 2 -1.5 L 8 0 L 2 1.5 L 0 8 L -2 1.5 L -8 0 L -2 -1.5 Z" fill="#F2ECE1"></path></g>
11
+ <g transform="translate(118 50)"><path d="M 0 -5 L 1.3 -1 L 5 0 L 1.3 1 L 0 5 L -1.3 1 L -5 0 L -1.3 -1 Z" fill="#F2ECE1"></path></g>
12
+ </g>
13
+ <g fill="#F2ECE1" font-family="&#39;Special Elite&#39;,&#39;JetBrains Mono&#39;,ui-monospace,monospace" font-size="84" letter-spacing="-2">
14
+ <text x="380" y="118">whale</text>
15
+ <text x="380" y="200">igniter</text>
16
+ </g>
17
+ <text x="380" y="230" fill="#F2ECE1" opacity="0.7" font-family="&#39;Special Elite&#39;,&#39;JetBrains Mono&#39;,ui-monospace,monospace" font-size="14" letter-spacing="4" text-transform="uppercase">A CLI FOR DESIGNERS WHO SHIP</text>
18
+ </svg>
@@ -0,0 +1,18 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 900 240" width="900" height="240" fill="none">
2
+ <rect width="900" height="240" fill="#F2ECE1"></rect>
3
+ <g transform="translate(20 10)">
4
+ <path d="M 18 76 C 28 60, 70 54, 120 56 C 170 58, 220 70, 256 84 C 270 90, 280 96, 286 102 C 290 100, 294 92, 294 80 C 296 64, 300 46, 308 30 C 312 28, 316 32, 316 40 C 314 56, 308 72, 302 82 C 308 78, 314 76, 320 80 C 322 88, 318 100, 308 108 C 300 114, 292 116, 286 114 C 282 124, 270 132, 252 138 C 220 150, 180 156, 144 156 C 120 156, 108 158, 100 164 C 88 172, 70 172, 60 164 C 56 158, 60 150, 68 148 C 50 144, 32 134, 22 120 C 12 106, 10 90, 18 76 Z" fill="#0034D3"></path>
5
+ <path d="M 60 102 L 92 100 M 110 96 L 150 92 M 160 102 L 200 100 M 220 108 L 252 106" stroke="#F2ECE1" stroke-width="1.6" stroke-linecap="round"></path>
6
+ <path d="M 70 124 L 100 124 M 120 130 L 170 130 M 190 136 L 230 134" stroke="#F2ECE1" stroke-width="1.4" stroke-linecap="round"></path>
7
+ <circle cx="48" cy="108" r="2.6" fill="#F2ECE1"></circle>
8
+ <path d="M 18 118 C 36 124, 60 130, 92 134" stroke="#F2ECE1" stroke-width="1.4" stroke-linecap="round" fill="none"></path>
9
+ <g transform="translate(150 30)"><path d="M 0 -22 L 4 -4 L 22 0 L 4 4 L 0 22 L -4 4 L -22 0 L -4 -4 Z" fill="#0034D3"></path><circle r="3" fill="#F2ECE1"></circle></g>
10
+ <g transform="translate(190 18)"><path d="M 0 -8 L 2 -1.5 L 8 0 L 2 1.5 L 0 8 L -2 1.5 L -8 0 L -2 -1.5 Z" fill="#0034D3"></path></g>
11
+ <g transform="translate(118 50)"><path d="M 0 -5 L 1.3 -1 L 5 0 L 1.3 1 L 0 5 L -1.3 1 L -5 0 L -1.3 -1 Z" fill="#0034D3"></path></g>
12
+ </g>
13
+ <g fill="#0034D3" font-family="&#39;Special Elite&#39;,&#39;JetBrains Mono&#39;,ui-monospace,monospace" font-size="84" letter-spacing="-2">
14
+ <text x="380" y="118">whale</text>
15
+ <text x="380" y="200">igniter</text>
16
+ </g>
17
+ <text x="380" y="230" fill="#0034D3" opacity="0.7" font-family="&#39;Special Elite&#39;,&#39;JetBrains Mono&#39;,ui-monospace,monospace" font-size="14" letter-spacing="4" text-transform="uppercase">A CLI FOR DESIGNERS WHO SHIP</text>
18
+ </svg>
@@ -0,0 +1,14 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 220" width="320" height="220" fill="none">
2
+
3
+ <path d="M 18 76 C 28 60, 70 54, 120 56 C 170 58, 220 70, 256 84 C 270 90, 280 96, 286 102 C 290 100, 294 92, 294 80 C 296 64, 300 46, 308 30 C 312 28, 316 32, 316 40 C 314 56, 308 72, 302 82 C 308 78, 314 76, 320 80 C 322 88, 318 100, 308 108 C 300 114, 292 116, 286 114 C 282 124, 270 132, 252 138 C 220 150, 180 156, 144 156 C 120 156, 108 158, 100 164 C 88 172, 70 172, 60 164 C 56 158, 60 150, 68 148 C 50 144, 32 134, 22 120 C 12 106, 10 90, 18 76 Z" fill="#000"></path>
4
+ <path d="M 60 102 L 92 100 M 110 96 L 150 92 M 160 102 L 200 100 M 220 108 L 252 106" stroke="#fff" stroke-width="1.6" stroke-linecap="round"></path>
5
+ <path d="M 70 124 L 100 124 M 120 130 L 170 130 M 190 136 L 230 134" stroke="#fff" stroke-width="1.4" stroke-linecap="round"></path>
6
+ <circle cx="48" cy="108" r="2.6" fill="#fff"></circle>
7
+ <path d="M 18 118 C 36 124, 60 130, 92 134" stroke="#fff" stroke-width="1.4" stroke-linecap="round" fill="none"></path>
8
+ <g transform="translate(150 30)">
9
+ <path d="M 0 -22 L 4 -4 L 22 0 L 4 4 L 0 22 L -4 4 L -22 0 L -4 -4 Z" fill="#000"></path>
10
+ <circle r="3" fill="#fff"></circle>
11
+ </g>
12
+ <g transform="translate(190 18)"><path d="M 0 -8 L 2 -1.5 L 8 0 L 2 1.5 L 0 8 L -2 1.5 L -8 0 L -2 -1.5 Z" fill="#000"></path></g>
13
+ <g transform="translate(118 50)"><path d="M 0 -5 L 1.3 -1 L 5 0 L 1.3 1 L 0 5 L -1.3 1 L -5 0 L -1.3 -1 Z" fill="#000"></path></g>
14
+ </svg>
@@ -0,0 +1,14 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 220" width="320" height="220" fill="none">
2
+ <rect width="320" height="220" fill="#003087"></rect>
3
+ <path d="M 18 76 C 28 60, 70 54, 120 56 C 170 58, 220 70, 256 84 C 270 90, 280 96, 286 102 C 290 100, 294 92, 294 80 C 296 64, 300 46, 308 30 C 312 28, 316 32, 316 40 C 314 56, 308 72, 302 82 C 308 78, 314 76, 320 80 C 322 88, 318 100, 308 108 C 300 114, 292 116, 286 114 C 282 124, 270 132, 252 138 C 220 150, 180 156, 144 156 C 120 156, 108 158, 100 164 C 88 172, 70 172, 60 164 C 56 158, 60 150, 68 148 C 50 144, 32 134, 22 120 C 12 106, 10 90, 18 76 Z" fill="#99CCFF"></path>
4
+ <path d="M 60 102 L 92 100 M 110 96 L 150 92 M 160 102 L 200 100 M 220 108 L 252 106" stroke="#003087" stroke-width="1.6" stroke-linecap="round"></path>
5
+ <path d="M 70 124 L 100 124 M 120 130 L 170 130 M 190 136 L 230 134" stroke="#003087" stroke-width="1.4" stroke-linecap="round"></path>
6
+ <circle cx="48" cy="108" r="2.6" fill="#003087"></circle>
7
+ <path d="M 18 118 C 36 124, 60 130, 92 134" stroke="#003087" stroke-width="1.4" stroke-linecap="round" fill="none"></path>
8
+ <g transform="translate(150 30)">
9
+ <path d="M 0 -22 L 4 -4 L 22 0 L 4 4 L 0 22 L -4 4 L -22 0 L -4 -4 Z" fill="#99CCFF"></path>
10
+ <circle r="3" fill="#003087"></circle>
11
+ </g>
12
+ <g transform="translate(190 18)"><path d="M 0 -8 L 2 -1.5 L 8 0 L 2 1.5 L 0 8 L -2 1.5 L -8 0 L -2 -1.5 Z" fill="#99CCFF"></path></g>
13
+ <g transform="translate(118 50)"><path d="M 0 -5 L 1.3 -1 L 5 0 L 1.3 1 L 0 5 L -1.3 1 L -5 0 L -1.3 -1 Z" fill="#99CCFF"></path></g>
14
+ </svg>
@@ -0,0 +1,14 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 220" width="320" height="220" fill="none">
2
+ <rect width="320" height="220" fill="#F2ECE1"></rect>
3
+ <path d="M 18 76 C 28 60, 70 54, 120 56 C 170 58, 220 70, 256 84 C 270 90, 280 96, 286 102 C 290 100, 294 92, 294 80 C 296 64, 300 46, 308 30 C 312 28, 316 32, 316 40 C 314 56, 308 72, 302 82 C 308 78, 314 76, 320 80 C 322 88, 318 100, 308 108 C 300 114, 292 116, 286 114 C 282 124, 270 132, 252 138 C 220 150, 180 156, 144 156 C 120 156, 108 158, 100 164 C 88 172, 70 172, 60 164 C 56 158, 60 150, 68 148 C 50 144, 32 134, 22 120 C 12 106, 10 90, 18 76 Z" fill="#0034D3"></path>
4
+ <path d="M 60 102 L 92 100 M 110 96 L 150 92 M 160 102 L 200 100 M 220 108 L 252 106" stroke="#F2ECE1" stroke-width="1.6" stroke-linecap="round"></path>
5
+ <path d="M 70 124 L 100 124 M 120 130 L 170 130 M 190 136 L 230 134" stroke="#F2ECE1" stroke-width="1.4" stroke-linecap="round"></path>
6
+ <circle cx="48" cy="108" r="2.6" fill="#F2ECE1"></circle>
7
+ <path d="M 18 118 C 36 124, 60 130, 92 134" stroke="#F2ECE1" stroke-width="1.4" stroke-linecap="round" fill="none"></path>
8
+ <g transform="translate(150 30)">
9
+ <path d="M 0 -22 L 4 -4 L 22 0 L 4 4 L 0 22 L -4 4 L -22 0 L -4 -4 Z" fill="#0034D3"></path>
10
+ <circle r="3" fill="#F2ECE1"></circle>
11
+ </g>
12
+ <g transform="translate(190 18)"><path d="M 0 -8 L 2 -1.5 L 8 0 L 2 1.5 L 0 8 L -2 1.5 L -8 0 L -2 -1.5 Z" fill="#0034D3"></path></g>
13
+ <g transform="translate(118 50)"><path d="M 0 -5 L 1.3 -1 L 5 0 L 1.3 1 L 0 5 L -1.3 1 L -5 0 L -1.3 -1 Z" fill="#0034D3"></path></g>
14
+ </svg>
@@ -0,0 +1,14 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 220" width="320" height="220" fill="none">
2
+ <rect width="320" height="220" fill="#0034D3"></rect>
3
+ <path d="M 18 76 C 28 60, 70 54, 120 56 C 170 58, 220 70, 256 84 C 270 90, 280 96, 286 102 C 290 100, 294 92, 294 80 C 296 64, 300 46, 308 30 C 312 28, 316 32, 316 40 C 314 56, 308 72, 302 82 C 308 78, 314 76, 320 80 C 322 88, 318 100, 308 108 C 300 114, 292 116, 286 114 C 282 124, 270 132, 252 138 C 220 150, 180 156, 144 156 C 120 156, 108 158, 100 164 C 88 172, 70 172, 60 164 C 56 158, 60 150, 68 148 C 50 144, 32 134, 22 120 C 12 106, 10 90, 18 76 Z" fill="#F2ECE1"></path>
4
+ <path d="M 60 102 L 92 100 M 110 96 L 150 92 M 160 102 L 200 100 M 220 108 L 252 106" stroke="#0034D3" stroke-width="1.6" stroke-linecap="round"></path>
5
+ <path d="M 70 124 L 100 124 M 120 130 L 170 130 M 190 136 L 230 134" stroke="#0034D3" stroke-width="1.4" stroke-linecap="round"></path>
6
+ <circle cx="48" cy="108" r="2.6" fill="#0034D3"></circle>
7
+ <path d="M 18 118 C 36 124, 60 130, 92 134" stroke="#0034D3" stroke-width="1.4" stroke-linecap="round" fill="none"></path>
8
+ <g transform="translate(150 30)">
9
+ <path d="M 0 -22 L 4 -4 L 22 0 L 4 4 L 0 22 L -4 4 L -22 0 L -4 -4 Z" fill="#F2ECE1"></path>
10
+ <circle r="3" fill="#0034D3"></circle>
11
+ </g>
12
+ <g transform="translate(190 18)"><path d="M 0 -8 L 2 -1.5 L 8 0 L 2 1.5 L 0 8 L -2 1.5 L -8 0 L -2 -1.5 Z" fill="#F2ECE1"></path></g>
13
+ <g transform="translate(118 50)"><path d="M 0 -5 L 1.3 -1 L 5 0 L 1.3 1 L 0 5 L -1.3 1 L -5 0 L -1.3 -1 Z" fill="#F2ECE1"></path></g>
14
+ </svg>
@@ -0,0 +1,14 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 220" width="320" height="220" fill="none">
2
+ <rect width="320" height="220" fill="#99CCFF"></rect>
3
+ <path d="M 18 76 C 28 60, 70 54, 120 56 C 170 58, 220 70, 256 84 C 270 90, 280 96, 286 102 C 290 100, 294 92, 294 80 C 296 64, 300 46, 308 30 C 312 28, 316 32, 316 40 C 314 56, 308 72, 302 82 C 308 78, 314 76, 320 80 C 322 88, 318 100, 308 108 C 300 114, 292 116, 286 114 C 282 124, 270 132, 252 138 C 220 150, 180 156, 144 156 C 120 156, 108 158, 100 164 C 88 172, 70 172, 60 164 C 56 158, 60 150, 68 148 C 50 144, 32 134, 22 120 C 12 106, 10 90, 18 76 Z" fill="#003087"></path>
4
+ <path d="M 60 102 L 92 100 M 110 96 L 150 92 M 160 102 L 200 100 M 220 108 L 252 106" stroke="#99CCFF" stroke-width="1.6" stroke-linecap="round"></path>
5
+ <path d="M 70 124 L 100 124 M 120 130 L 170 130 M 190 136 L 230 134" stroke="#99CCFF" stroke-width="1.4" stroke-linecap="round"></path>
6
+ <circle cx="48" cy="108" r="2.6" fill="#99CCFF"></circle>
7
+ <path d="M 18 118 C 36 124, 60 130, 92 134" stroke="#99CCFF" stroke-width="1.4" stroke-linecap="round" fill="none"></path>
8
+ <g transform="translate(150 30)">
9
+ <path d="M 0 -22 L 4 -4 L 22 0 L 4 4 L 0 22 L -4 4 L -22 0 L -4 -4 Z" fill="#003087"></path>
10
+ <circle r="3" fill="#99CCFF"></circle>
11
+ </g>
12
+ <g transform="translate(190 18)"><path d="M 0 -8 L 2 -1.5 L 8 0 L 2 1.5 L 0 8 L -2 1.5 L -8 0 L -2 -1.5 Z" fill="#003087"></path></g>
13
+ <g transform="translate(118 50)"><path d="M 0 -5 L 1.3 -1 L 5 0 L 1.3 1 L 0 5 L -1.3 1 L -5 0 L -1.3 -1 Z" fill="#003087"></path></g>
14
+ </svg>
@@ -0,0 +1,14 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 220" width="320" height="220" fill="none">
2
+
3
+ <path d="M 18 76 C 28 60, 70 54, 120 56 C 170 58, 220 70, 256 84 C 270 90, 280 96, 286 102 C 290 100, 294 92, 294 80 C 296 64, 300 46, 308 30 C 312 28, 316 32, 316 40 C 314 56, 308 72, 302 82 C 308 78, 314 76, 320 80 C 322 88, 318 100, 308 108 C 300 114, 292 116, 286 114 C 282 124, 270 132, 252 138 C 220 150, 180 156, 144 156 C 120 156, 108 158, 100 164 C 88 172, 70 172, 60 164 C 56 158, 60 150, 68 148 C 50 144, 32 134, 22 120 C 12 106, 10 90, 18 76 Z" fill="#fff"></path>
4
+ <path d="M 60 102 L 92 100 M 110 96 L 150 92 M 160 102 L 200 100 M 220 108 L 252 106" stroke="#000" stroke-width="1.6" stroke-linecap="round"></path>
5
+ <path d="M 70 124 L 100 124 M 120 130 L 170 130 M 190 136 L 230 134" stroke="#000" stroke-width="1.4" stroke-linecap="round"></path>
6
+ <circle cx="48" cy="108" r="2.6" fill="#000"></circle>
7
+ <path d="M 18 118 C 36 124, 60 130, 92 134" stroke="#000" stroke-width="1.4" stroke-linecap="round" fill="none"></path>
8
+ <g transform="translate(150 30)">
9
+ <path d="M 0 -22 L 4 -4 L 22 0 L 4 4 L 0 22 L -4 4 L -22 0 L -4 -4 Z" fill="#fff"></path>
10
+ <circle r="3" fill="#000"></circle>
11
+ </g>
12
+ <g transform="translate(190 18)"><path d="M 0 -8 L 2 -1.5 L 8 0 L 2 1.5 L 0 8 L -2 1.5 L -8 0 L -2 -1.5 Z" fill="#fff"></path></g>
13
+ <g transform="translate(118 50)"><path d="M 0 -5 L 1.3 -1 L 5 0 L 1.3 1 L 0 5 L -1.3 1 L -5 0 L -1.3 -1 Z" fill="#fff"></path></g>
14
+ </svg>
package/brand/logo.svg ADDED
@@ -0,0 +1,14 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 220" width="320" height="220" fill="none">
2
+
3
+ <path d="M 18 76 C 28 60, 70 54, 120 56 C 170 58, 220 70, 256 84 C 270 90, 280 96, 286 102 C 290 100, 294 92, 294 80 C 296 64, 300 46, 308 30 C 312 28, 316 32, 316 40 C 314 56, 308 72, 302 82 C 308 78, 314 76, 320 80 C 322 88, 318 100, 308 108 C 300 114, 292 116, 286 114 C 282 124, 270 132, 252 138 C 220 150, 180 156, 144 156 C 120 156, 108 158, 100 164 C 88 172, 70 172, 60 164 C 56 158, 60 150, 68 148 C 50 144, 32 134, 22 120 C 12 106, 10 90, 18 76 Z" fill="#0034D3"></path>
4
+ <path d="M 60 102 L 92 100 M 110 96 L 150 92 M 160 102 L 200 100 M 220 108 L 252 106" stroke="#F2ECE1" stroke-width="1.6" stroke-linecap="round"></path>
5
+ <path d="M 70 124 L 100 124 M 120 130 L 170 130 M 190 136 L 230 134" stroke="#F2ECE1" stroke-width="1.4" stroke-linecap="round"></path>
6
+ <circle cx="48" cy="108" r="2.6" fill="#F2ECE1"></circle>
7
+ <path d="M 18 118 C 36 124, 60 130, 92 134" stroke="#F2ECE1" stroke-width="1.4" stroke-linecap="round" fill="none"></path>
8
+ <g transform="translate(150 30)">
9
+ <path d="M 0 -22 L 4 -4 L 22 0 L 4 4 L 0 22 L -4 4 L -22 0 L -4 -4 Z" fill="#0034D3"></path>
10
+ <circle r="3" fill="#F2ECE1"></circle>
11
+ </g>
12
+ <g transform="translate(190 18)"><path d="M 0 -8 L 2 -1.5 L 8 0 L 2 1.5 L 0 8 L -2 1.5 L -8 0 L -2 -1.5 Z" fill="#0034D3"></path></g>
13
+ <g transform="translate(118 50)"><path d="M 0 -5 L 1.3 -1 L 5 0 L 1.3 1 L 0 5 L -1.3 1 L -5 0 L -1.3 -1 Z" fill="#0034D3"></path></g>
14
+ </svg>
@@ -0,0 +1,49 @@
1
+ /* whale-igniter · brand tokens
2
+ * Source of truth: cachalot/brand/palette.json
3
+ * License: MIT
4
+ */
5
+
6
+ :root {
7
+ /* Primary */
8
+ --wi-royal: #0034D3;
9
+ --wi-paper: #F2ECE1;
10
+
11
+ /* Accents */
12
+ --wi-sky: #99CCFF;
13
+ --wi-deep: #003087;
14
+
15
+ /* Royal scale */
16
+ --wi-royal-100: #E5EAFA;
17
+ --wi-royal-300: #7C95E8;
18
+ --wi-royal-500: #0034D3;
19
+ --wi-royal-700: #002BAA;
20
+ --wi-royal-900: #001A66;
21
+
22
+ /* Type */
23
+ --wi-font-display: "Special Elite", ui-monospace, monospace;
24
+ --wi-font-mono: "JetBrains Mono", ui-monospace, monospace;
25
+
26
+ /* Radii */
27
+ --wi-radius-tile: 26px;
28
+ --wi-radius-stick: 8px;
29
+ --wi-radius-pill: 999px;
30
+
31
+ /* Shadows */
32
+ --wi-shadow-card: 0 6px 14px rgba(0, 52, 211, 0.18);
33
+ --wi-shadow-lift: 0 12px 28px rgba(0, 48, 135, 0.22);
34
+ }
35
+
36
+ @media (prefers-color-scheme: dark) {
37
+ :root {
38
+ --wi-bg: var(--wi-deep);
39
+ --wi-fg: var(--wi-paper);
40
+ --wi-link: var(--wi-sky);
41
+ }
42
+ }
43
+ @media (prefers-color-scheme: light) {
44
+ :root {
45
+ --wi-bg: var(--wi-paper);
46
+ --wi-fg: var(--wi-deep);
47
+ --wi-link: var(--wi-royal);
48
+ }
49
+ }
@@ -0,0 +1,30 @@
1
+ {
2
+ "$schema": "https://json.schemastore.org/base.json",
3
+ "name": "whale-igniter",
4
+ "version": "0.1.0",
5
+ "description": "Brand identity & design tokens for whale-igniter — a CLI for designers who ship.",
6
+ "primary": {
7
+ "ink": { "name": "ROYAL", "hex": "#0034D3", "rgb": "0 52 211", "role": "primary ink, body of the mark, headings" },
8
+ "paper": { "name": "PAPER", "hex": "#F2ECE1", "rgb": "242 236 225", "role": "page background, knockout fill" }
9
+ },
10
+ "accent": {
11
+ "sky": { "name": "SKY", "hex": "#99CCFF", "rgb": "153 204 255", "role": "soft accent / fills" },
12
+ "deep": { "name": "DEEP", "hex": "#003087", "rgb": "0 48 135", "role": "dark surface / on-light text" }
13
+ },
14
+ "scale": {
15
+ "royal-100": "#E5EAFA",
16
+ "royal-300": "#7C95E8",
17
+ "royal-500": "#0034D3",
18
+ "royal-700": "#002BAA",
19
+ "royal-900": "#001A66"
20
+ },
21
+ "type": {
22
+ "display": { "family": "Special Elite", "fallback": "ui-monospace, monospace", "weights": [400] },
23
+ "monospace":{ "family": "JetBrains Mono", "fallback": "ui-monospace, monospace", "weights": [400, 600] }
24
+ },
25
+ "radii": { "tile": 26, "sticker": 8, "pill": 999 },
26
+ "shadow": {
27
+ "card": "0 6px 14px rgba(0, 52, 211, 0.18)",
28
+ "lift": "0 12px 28px rgba(0, 48, 135, 0.22)"
29
+ }
30
+ }
@@ -0,0 +1,7 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 520 230" width="520" height="230" fill="none">
2
+ <g fill="#F2ECE1" font-family="&#39;Special Elite&#39;,&#39;JetBrains Mono&#39;,ui-monospace,monospace" font-size="92" letter-spacing="-2">
3
+ <text x="10" y="100">whale</text>
4
+ <text x="10" y="190">igniter</text>
5
+ </g>
6
+ <text x="10" y="220" fill="#F2ECE1" opacity="0.7" font-family="&#39;Special Elite&#39;,&#39;JetBrains Mono&#39;,ui-monospace,monospace" font-size="15" letter-spacing="4">A CLI FOR DESIGNERS WHO SHIP</text>
7
+ </svg>
@@ -0,0 +1,7 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 520 230" width="520" height="230" fill="none">
2
+ <g fill="#0034D3" font-family="&#39;Special Elite&#39;,&#39;JetBrains Mono&#39;,ui-monospace,monospace" font-size="92" letter-spacing="-2">
3
+ <text x="10" y="100">whale</text>
4
+ <text x="10" y="190">igniter</text>
5
+ </g>
6
+ <text x="10" y="220" fill="#0034D3" opacity="0.7" font-family="&#39;Special Elite&#39;,&#39;JetBrains Mono&#39;,ui-monospace,monospace" font-size="15" letter-spacing="4">A CLI FOR DESIGNERS WHO SHIP</text>
7
+ </svg>
@@ -0,0 +1,39 @@
1
+ import { docsCommand } from "./docs.js";
2
+ import { insightsCommand } from "./insights.js";
3
+ import { seleneSuggestCommand } from "./selene.js";
4
+ import { syncCommand } from "./sync.js";
5
+ import { validateCommand } from "./validate.js";
6
+ import { wikiCommand } from "./wiki.js";
7
+ import { ui } from "../ui/index.js";
8
+ export async function rememberCommand(target) {
9
+ console.log();
10
+ console.log(ui.header("Whale Igniter", "remember"));
11
+ console.log(ui.muted("Updating project memory for AI assistants."));
12
+ await syncCommand(target);
13
+ }
14
+ export async function checkCommand(target) {
15
+ console.log();
16
+ console.log(ui.header("Whale Igniter", "check"));
17
+ console.log(ui.muted("Checking project health, then looking for useful recommendations."));
18
+ console.log();
19
+ await validateCommand(target);
20
+ const validationExit = process.exitCode;
21
+ await insightsCommand(target, {});
22
+ if (validationExit !== undefined) {
23
+ process.exitCode = validationExit;
24
+ }
25
+ }
26
+ export async function improveCommand() {
27
+ console.log();
28
+ console.log(ui.header("Whale Igniter", "improve"));
29
+ console.log(ui.muted("Asking Selene for project-wide improvement suggestions."));
30
+ await seleneSuggestCommand({ focus: "all" });
31
+ }
32
+ export async function explainCommand(target) {
33
+ console.log();
34
+ console.log(ui.header("Whale Igniter", "explain"));
35
+ console.log(ui.muted("Generating human-facing docs and AI-readable project context."));
36
+ console.log();
37
+ await docsCommand(target);
38
+ await wikiCommand(target);
39
+ }
@@ -0,0 +1,83 @@
1
+ import { resolveTarget } from "../utils/paths.js";
2
+ import { loadConfig, saveConfig } from "../utils/config.js";
3
+ import { getPack } from "../utils/registry.js";
4
+ import { ui } from "../ui/index.js";
5
+ const PERSONAS = {
6
+ atlas: {
7
+ role: "Product strategy",
8
+ verb: "decides",
9
+ next: "whale decision"
10
+ },
11
+ forge: {
12
+ role: "Implementation architecture",
13
+ verb: "builds",
14
+ next: "whale create component Hero"
15
+ },
16
+ scribe: {
17
+ role: "Documentation and project memory",
18
+ verb: "documents",
19
+ next: "whale explain"
20
+ },
21
+ lighthouse: {
22
+ role: "Quality and validation",
23
+ verb: "guards",
24
+ next: "whale check"
25
+ },
26
+ selene: {
27
+ role: "AI suggestions and audits",
28
+ verb: "enriches",
29
+ next: "whale improve"
30
+ }
31
+ };
32
+ function isPersonaName(name) {
33
+ return Object.prototype.hasOwnProperty.call(PERSONAS, name);
34
+ }
35
+ export async function teamListCommand(targetArg) {
36
+ const target = resolveTarget(targetArg);
37
+ const config = await loadConfig(target);
38
+ const installed = new Set(config.packs ?? []);
39
+ console.log();
40
+ console.log(ui.header("Whale Igniter", "team"));
41
+ console.log();
42
+ console.log(ui.section("Your AI team"));
43
+ for (const [name, persona] of Object.entries(PERSONAS)) {
44
+ const mark = installed.has(name) ? ui.ok(name) : ui.muted(`${ui.glyph.bullet} ${name}`);
45
+ const state = installed.has(name) ? ui.muted("active") : ui.muted("available");
46
+ console.log(` ${mark.padEnd(18)} ${persona.role} ${ui.muted("— " + persona.verb)} ${state}`);
47
+ }
48
+ console.log();
49
+ console.log(ui.next("whale team add atlas add a teammate"));
50
+ console.log(ui.next("whale remember update project memory"));
51
+ }
52
+ export async function teamAddCommand(name) {
53
+ const personaName = name.toLowerCase();
54
+ if (!isPersonaName(personaName)) {
55
+ console.log(ui.fail(`Unknown teammate: "${name}"`));
56
+ console.log(ui.muted("Available teammates: atlas, forge, scribe, lighthouse, selene"));
57
+ process.exitCode = 1;
58
+ return;
59
+ }
60
+ const target = resolveTarget();
61
+ const pack = getPack(personaName);
62
+ const persona = PERSONAS[personaName];
63
+ if (!pack) {
64
+ console.log(ui.fail(`No pack found for teammate "${personaName}".`));
65
+ process.exitCode = 1;
66
+ return;
67
+ }
68
+ const config = await loadConfig(target);
69
+ config.packs = config.packs ?? [];
70
+ if (config.packs.includes(personaName)) {
71
+ console.log(ui.warn(`${personaName} is already on your AI team.`));
72
+ console.log(ui.next(persona.next));
73
+ return;
74
+ }
75
+ config.packs.push(personaName);
76
+ await saveConfig(target, config);
77
+ console.log(ui.ok(`${ui.code(personaName)} joined your AI team`));
78
+ console.log(` ${ui.kv("role", persona.role, { keyWidth: 8 })}`);
79
+ console.log(` ${ui.kv("pack", pack.kind, { keyWidth: 8 })}`);
80
+ console.log();
81
+ console.log(ui.next(`${persona.next} ${ui.muted("try this next")}`));
82
+ console.log(ui.next(`whale remember ${ui.muted("update project memory for agents")}`));
83
+ }
package/dist/index.js CHANGED
@@ -17,6 +17,8 @@ import { createComponentCommand } from "./commands/createComponent.js";
17
17
  import { seleneDescribeCommand, seleneAuditCommand, seleneSuggestCommand, seleneApplyCommand, seleneStatusCommand, seleneCacheClearCommand } from "./commands/selene.js";
18
18
  import { mcpServeCommand, mcpConfigCommand } from "./commands/mcp.js";
19
19
  import { watchCommand } from "./commands/watch.js";
20
+ import { rememberCommand, checkCommand, improveCommand, explainCommand } from "./commands/friendly.js";
21
+ import { teamAddCommand, teamListCommand } from "./commands/team.js";
20
22
  import { PACKAGE_VERSION } from "./version.js";
21
23
  const program = new Command();
22
24
  program
@@ -40,6 +42,22 @@ program
40
42
  .command("sync [target]")
41
43
  .description("Regenerate CLAUDE.md and the LLM Wiki from intelligence/*.json.")
42
44
  .action(syncCommand);
45
+ program
46
+ .command("remember [target]")
47
+ .description("Update project memory for AI assistants (friendly alias for sync).")
48
+ .action((target) => rememberCommand(target));
49
+ program
50
+ .command("check [target]")
51
+ .description("Check project health and recommendations (validate + insights).")
52
+ .action((target) => checkCommand(target));
53
+ program
54
+ .command("improve")
55
+ .description("Ask Selene for project-wide improvement suggestions.")
56
+ .action(() => improveCommand());
57
+ program
58
+ .command("explain [target]")
59
+ .description("Generate human docs and AI-readable context (docs + wiki).")
60
+ .action((target) => explainCommand(target));
43
61
  program
44
62
  .command("add <pack>")
45
63
  .description("Install a Whale operational pack.")
@@ -190,6 +208,19 @@ component
190
208
  .command("list")
191
209
  .description("List components registered in the catalog.")
192
210
  .action(componentListCommand);
211
+ const team = program
212
+ .command("team")
213
+ .description("Manage your AI team (friendly layer for operational packs).");
214
+ team
215
+ .command("add <teammate>")
216
+ .description("Add atlas, forge, scribe, lighthouse, or selene to this project.")
217
+ .action((name) => teamAddCommand(name));
218
+ team
219
+ .command("list [target]")
220
+ .description("Show available and active teammates.")
221
+ .action((target) => teamListCommand(target));
222
+ team
223
+ .action(() => teamListCommand());
193
224
  const mcp = program
194
225
  .command("mcp")
195
226
  .description("Run or configure the Whale MCP server (for Claude Code, Cursor, Zed, etc.).");
package/dist/version.js CHANGED
@@ -1 +1 @@
1
- export const PACKAGE_VERSION = "1.1.0";
1
+ export const PACKAGE_VERSION = "1.2.1";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "whale-igniter",
3
- "version": "1.1.0",
3
+ "version": "1.2.1",
4
4
  "description": "CLI-first operational intelligence. Bootstraps and adopts AI-readable project context so agents like Claude Code, Codex and Cursor understand your design system from the first commit. Includes an MCP server, a file watcher, deterministic insights, and an opt-in AI bridge (Selene).",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -9,6 +9,7 @@
9
9
  },
10
10
  "files": [
11
11
  "dist",
12
+ "brand",
12
13
  "README.md",
13
14
  "LICENSE",
14
15
  "docs/ROADMAP.md"