@pymodel/niblet 0.3.0 → 0.3.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 +9 -4
- package/assets/niblet-mascot-celebration.svg +20 -0
- package/assets/niblet-mascot-focused.svg +20 -0
- package/assets/niblet-mascot-thinking.svg +20 -0
- package/assets/niblet-step-build.svg +29 -0
- package/assets/niblet-step-check.svg +29 -0
- package/assets/niblet-step-contract.svg +29 -0
- package/package.json +1 -1
- package/skill/niblet/references/connection.md +6 -2
- package/src/server.mjs +24 -5
package/README.md
CHANGED
|
@@ -9,16 +9,19 @@
|
|
|
9
9
|
|
|
10
10
|
<p align="center">
|
|
11
11
|
<a href="https://www.npmjs.com/package/@pymodel/niblet"><img alt="npm" src="https://img.shields.io/npm/v/%40pymodel%2Fniblet?logo=npm&logoColor=white&label=npm&color=e8a33d&labelColor=0f1110"></a>
|
|
12
|
-
<a href="https://www.npmjs.com/package/@pymodel/niblet"><img alt="Downloads" src="https://img.shields.io/npm/dm/%40pymodel%2Fniblet?logo=npm&logoColor=white&label=downloads&color=30363d&labelColor=0f1110"></a>
|
|
13
12
|
<a href="https://nodejs.org"><img alt="Node 24.15+" src="https://img.shields.io/badge/node-24.15%2B-30363d?logo=nodedotjs&logoColor=white&labelColor=0f1110"></a>
|
|
14
13
|
<a href="https://modelcontextprotocol.io"><img alt="MCP" src="https://img.shields.io/badge/mcp-server-30363d?logo=anthropic&logoColor=white&labelColor=0f1110"></a>
|
|
15
|
-
<a href="https://github.com/PyModel/niblet-skill-mcp/stargazers"><img alt="Stars" src="https://img.shields.io/github/stars/PyModel/niblet-skill-mcp?logo=github&logoColor=white&label=stars&color=30363d&labelColor=0f1110"></a>
|
|
14
|
+
<a href="https://github.com/PyModel/niblet-skill-mcp/stargazers"><img alt="Stars" src="https://img.shields.io/github/stars/PyModel/niblet-skill-mcp?style=flat&logo=github&logoColor=white&label=stars&color=30363d&labelColor=0f1110"></a>
|
|
16
15
|
<a href="https://github.com/PyModel/niblet-skill-mcp/blob/main/LICENSE"><img alt="License: Apache-2.0" src="https://img.shields.io/badge/license-Apache--2.0-30363d?labelColor=0f1110"></a>
|
|
17
16
|
<a href="https://hits.sh/github.com/PyModel/niblet-skill-mcp/"><img alt="Visitors" src="https://hits.sh/github.com/PyModel/niblet-skill-mcp.svg?label=visitors&color=30363d&labelColor=0f1110"></a>
|
|
18
17
|
</p>
|
|
19
18
|
|
|
20
19
|
<p align="center">
|
|
21
|
-
<img src="https://raw.githubusercontent.com/PyModel/niblet-skill-mcp/main/assets/niblet-
|
|
20
|
+
<img src="https://raw.githubusercontent.com/PyModel/niblet-skill-mcp/main/assets/niblet-step-contract.svg" alt="Settle the contract" width="210">
|
|
21
|
+
<b>→</b>
|
|
22
|
+
<img src="https://raw.githubusercontent.com/PyModel/niblet-skill-mcp/main/assets/niblet-step-build.svg" alt="Build from your system" width="210">
|
|
23
|
+
<b>→</b>
|
|
24
|
+
<img src="https://raw.githubusercontent.com/PyModel/niblet-skill-mcp/main/assets/niblet-step-check.svg" alt="Check the rendered screen" width="210">
|
|
22
25
|
</p>
|
|
23
26
|
|
|
24
27
|
<p align="center">
|
|
@@ -27,6 +30,8 @@
|
|
|
27
30
|
|
|
28
31
|
A coding agent building UI gets two things here: a design skill that keeps it working from your product rather than a generic template, and real screen references from the [Niblet](https://niblet.com) catalogue when a specific visual question is still open.
|
|
29
32
|
|
|
33
|
+
The skill settles the screen's job, its real states, and what counts as done before writing anything; it builds from the tokens and components already in your codebase; and it finishes by rendering the surface and exercising it, so a green build alone is not a pass.
|
|
34
|
+
|
|
30
35
|
The skill works alone. The server is optional and needs a token.
|
|
31
36
|
|
|
32
37
|
## Install the skill
|
|
@@ -76,7 +81,7 @@ Or the equivalent in any host's MCP config file:
|
|
|
76
81
|
}
|
|
77
82
|
```
|
|
78
83
|
|
|
79
|
-
Node.js 24.15+; npx fetches the package on first launch.
|
|
84
|
+
Node.js 24.15+; npx fetches the package on first launch. Create an account at [niblet.com/sign-up](https://www.niblet.com/sign-up), confirm the emailed code, then create a key at [niblet.com/account](https://www.niblet.com/account). It is shown once. Keep it in your host's environment, never in a committed file or a chat message.
|
|
80
85
|
|
|
81
86
|
Saving the config does not register the server, so confirm it worked. `niblet_status` reports the configured origins, whether a usable token is present, and whether the API answers:
|
|
82
87
|
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="512" height="512" viewBox="0 0 512 512" role="img" aria-labelledby="nb-title nb-desc">
|
|
3
|
+
<title id="nb-title">Niblet elf wizard mascot: celebration</title><desc id="nb-desc">Editable native SVG artwork. No embedded raster images.</desc>
|
|
4
|
+
<defs>
|
|
5
|
+
<linearGradient id="nb-hat" x1="0" y1="0.65" x2="0.9" y2="0.15" gradientUnits="objectBoundingBox"><stop stop-color="#115999"/><stop offset="0.46" stop-color="#1796B1"/><stop offset="0.8" stop-color="#25CBBB"/><stop offset="1" stop-color="#89F3D8"/></linearGradient>
|
|
6
|
+
<linearGradient id="nb-hat-fold" x1="0" y1="0.2" x2="1" y2="0.8"><stop stop-color="#0C5E8D"/><stop offset="0.62" stop-color="#117B90"/><stop offset="1" stop-color="#00A59F"/></linearGradient>
|
|
7
|
+
<linearGradient id="nb-brim" x1="0" y1="1" x2="1" y2="0"><stop stop-color="#2278D3"/><stop offset="0.5" stop-color="#28AADA"/><stop offset="1" stop-color="#67EAD0"/></linearGradient>
|
|
8
|
+
<radialGradient id="nb-face" cx="45%" cy="35%" r="70%"><stop stop-color="#FFF1CF"/><stop offset="0.65" stop-color="#FFDFBA"/><stop offset="1" stop-color="#F4AF91"/></radialGradient>
|
|
9
|
+
<linearGradient id="nb-ear" x1="0" y1="0" x2="0.8" y2="1"><stop stop-color="#FFD7B5"/><stop offset="1" stop-color="#F2A185"/></linearGradient>
|
|
10
|
+
<linearGradient id="nb-ear-inner" x1="0" y1="0" x2="1" y2="1"><stop stop-color="#E98072"/><stop offset="1" stop-color="#F6B797"/></linearGradient>
|
|
11
|
+
<radialGradient id="nb-orb" cx="30%" cy="23%" r="80%"><stop stop-color="#ABFFEC"/><stop offset="0.4" stop-color="#16D7C5"/><stop offset="1" stop-color="#078899"/></radialGradient>
|
|
12
|
+
<linearGradient id="nb-cloak" x1="0" y1="0" x2="1" y2="1"><stop stop-color="#169EAF"/><stop offset="0.5" stop-color="#08718D"/><stop offset="1" stop-color="#0A344F"/></linearGradient>
|
|
13
|
+
<linearGradient id="nb-app" x1="0" y1="1" x2="0.9" y2="0"><stop stop-color="#7360FF"/><stop offset="0.44" stop-color="#2E8BFF"/><stop offset="1" stop-color="#08DBC2"/></linearGradient>
|
|
14
|
+
<linearGradient id="nb-magic" x1="0" y1="1" x2="1" y2="0"><stop stop-color="#8B5CF6"/><stop offset="0.55" stop-color="#2E8BFF"/><stop offset="1" stop-color="#00D1B2"/></linearGradient>
|
|
15
|
+
<linearGradient id="nb-soft" x1="0" y1="0" x2="1" y2="1"><stop stop-color="#EEF5FF"/><stop offset="0.6" stop-color="#F7F4FF"/><stop offset="1" stop-color="#E8FAF8"/></linearGradient>
|
|
16
|
+
<linearGradient id="nb-dark-surface" x1="0" y1="0" x2="1" y2="1"><stop stop-color="#142A42"/><stop offset="1" stop-color="#0A1628"/></linearGradient>
|
|
17
|
+
<radialGradient id="nb-halo"><stop stop-color="#A8EEE7" stop-opacity="0.55"/><stop offset="1" stop-color="#DFEFFE" stop-opacity="0"/></radialGradient>
|
|
18
|
+
</defs>
|
|
19
|
+
<g id="mascot-cloak"><path d="M170 359C187 378 220 389 255 388C288 389 322 378 343 360L349 400L310 426L299 464L268 454L239 466L218 454L186 459L183 423L153 401Z" fill="url(#nb-cloak)" /><path d="M169 382Q244 432 335 384L320 411Q242 447 177 407Z" fill="#084E67" /><path d="M188 427L238 445L212 453L188 449Z" fill="#20A9B1" /><path d="M268 426L288 460L264 449L242 460L244 441Z" fill="#0D405E" /></g><g id="mascot-ears"><path d="M153 282C126 264 98 251 59 248C65 285 91 320 127 334L161 316Z" fill="url(#nb-ear)" /><path d="M350 277C377 248 404 232 448 221C441 267 418 306 380 326L350 311Z" fill="url(#nb-ear)" /><path d="M137 292Q115 273 79 264Q94 295 132 314Z" fill="url(#nb-ear-inner)" /><path d="M371 285Q395 255 429 240Q417 281 382 307Z" fill="url(#nb-ear-inner)" /></g><g id="mascot-hood"><path d="M118 276C127 219 151 166 183 112C217 55 258 29 303 44C344 58 365 87 386 109C359 101 337 112 325 137C331 177 361 210 367 248C392 276 391 320 368 353C345 390 304 407 252 407C191 405 149 388 126 353C109 327 108 299 118 276Z" fill="url(#nb-hat)" /><path d="M183 113C216 65 253 35 295 52C250 57 222 100 217 139C207 178 225 207 234 228L136 260C143 216 160 166 183 113Z" fill="#72E5D4" opacity="0.18"/><path d="M284 59C328 61 358 89 384 109C358 100 337 113 325 138C325 167 348 203 359 228C319 209 292 170 282 129C275 98 277 77 284 59Z" fill="url(#nb-hat-fold)" /><path d="M179 117C205 75 234 52 263 47" fill="none" stroke="#C2FFF0" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" opacity="0.66"/><path d="M135 256C197 224 296 222 362 255" fill="none" stroke="#076E91" stroke-width="6" stroke-linecap="round" stroke-linejoin="round" /></g><g id="mascot-face"><path d="M137 290C153 265 189 252 245 251C301 247 340 260 362 288L365 325C361 371 315 397 253 397C192 397 146 375 139 337Z" fill="url(#nb-face)" /></g><g id="mascot-hatband"><path d="M120 279C142 245 181 228 239 224C292 219 336 231 364 252L369 289C333 261 293 251 245 255C191 256 150 273 131 308Z" fill="url(#nb-brim)" /><path d="M136 276C166 248 207 238 251 236C295 235 330 245 351 260" fill="none" stroke="#A5FBE8" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" opacity="0.65"/><path d="M225 254L242 268L257 252Z" fill="#19C6B8" /></g><g id="mascot-expression"><path d="M190 311Q203 293 216 311M283 311Q296 293 309 311" fill="none" stroke="#0A1628" stroke-width="6" stroke-linecap="round" stroke-linejoin="round" /><path d="M187 280Q199 271 211 279M285 278Q297 268 309 278" fill="none" stroke="#0A1628" stroke-width="4.5" stroke-linecap="round" stroke-linejoin="round" /><path d="M231 341Q254 352 277 340Q269 366 253 366Q239 365 231 341Z" fill="#0A1628" /><path d="M241 360Q253 352 266 359Q255 370 241 360Z" fill="#FA948C" /><ellipse cx="178" cy="343" rx="17" ry="10" fill="#F58E85" opacity="0.38"/><ellipse cx="321" cy="341" rx="17" ry="10" fill="#F58E85" opacity="0.38"/><path d="M250 322Q256 328 250 330" fill="none" stroke="#ECA58E" stroke-width="3" stroke-linecap="round" stroke-linejoin="round" /></g><g id="mascot-hat-orb"><path d="M382 108Q392 111 394 121" fill="none" stroke="#148E9D" stroke-width="7" stroke-linecap="round" stroke-linejoin="round" /><circle cx="395" cy="126" r="18" fill="url(#nb-orb)" /><path d="M385 117Q392 110 402 116" fill="none" stroke="#D1FFF5" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" opacity="0.8"/></g><g id="mascot-magic"><g transform="translate(77 142) scale(1)" transform-origin="0 0"><rect x="-3" y="-9" width="6" height="18" rx="3" fill="#FF6B6B" /></g><g transform="translate(113 80) scale(1)" transform-origin="0 0"><rect x="-3" y="-9" width="6" height="18" rx="3" fill="#8B5CF6" /></g><g transform="translate(446 162) scale(1)" transform-origin="0 0"><rect x="-3" y="-9" width="6" height="18" rx="3" fill="#00D1B2" /></g><g transform="translate(431 82) scale(1)" transform-origin="0 0"><rect x="-3" y="-9" width="6" height="18" rx="3" fill="#F4B400" /></g><path d="M85 185C87.25 197.0 88.0 197.75 100 200C88.0 202.25 87.25 203.0 85 215C82.75 203.0 82.0 202.25 70 200C82.0 197.75 82.75 197.0 85 185Z" fill="#F4B400" /><path d="M444 342C446.4 354.8 447.2 355.6 460 358C447.2 360.4 446.4 361.2 444 374C441.6 361.2 440.8 360.4 428 358C440.8 355.6 441.6 354.8 444 342Z" fill="#2E8BFF" /><path d="M361 46C362.35 53.2 362.8 53.65 370 55C362.8 56.35 362.35 56.8 361 64C359.65 56.8 359.2 56.35 352 55C359.2 53.65 359.65 53.2 361 46Z" fill="#8B5CF6" /></g>
|
|
20
|
+
</svg>
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="512" height="512" viewBox="0 0 512 512" role="img" aria-labelledby="nb-title nb-desc">
|
|
3
|
+
<title id="nb-title">Niblet elf wizard mascot: focused</title><desc id="nb-desc">Editable native SVG artwork. No embedded raster images.</desc>
|
|
4
|
+
<defs>
|
|
5
|
+
<linearGradient id="nb-hat" x1="0" y1="0.65" x2="0.9" y2="0.15" gradientUnits="objectBoundingBox"><stop stop-color="#115999"/><stop offset="0.46" stop-color="#1796B1"/><stop offset="0.8" stop-color="#25CBBB"/><stop offset="1" stop-color="#89F3D8"/></linearGradient>
|
|
6
|
+
<linearGradient id="nb-hat-fold" x1="0" y1="0.2" x2="1" y2="0.8"><stop stop-color="#0C5E8D"/><stop offset="0.62" stop-color="#117B90"/><stop offset="1" stop-color="#00A59F"/></linearGradient>
|
|
7
|
+
<linearGradient id="nb-brim" x1="0" y1="1" x2="1" y2="0"><stop stop-color="#2278D3"/><stop offset="0.5" stop-color="#28AADA"/><stop offset="1" stop-color="#67EAD0"/></linearGradient>
|
|
8
|
+
<radialGradient id="nb-face" cx="45%" cy="35%" r="70%"><stop stop-color="#FFF1CF"/><stop offset="0.65" stop-color="#FFDFBA"/><stop offset="1" stop-color="#F4AF91"/></radialGradient>
|
|
9
|
+
<linearGradient id="nb-ear" x1="0" y1="0" x2="0.8" y2="1"><stop stop-color="#FFD7B5"/><stop offset="1" stop-color="#F2A185"/></linearGradient>
|
|
10
|
+
<linearGradient id="nb-ear-inner" x1="0" y1="0" x2="1" y2="1"><stop stop-color="#E98072"/><stop offset="1" stop-color="#F6B797"/></linearGradient>
|
|
11
|
+
<radialGradient id="nb-orb" cx="30%" cy="23%" r="80%"><stop stop-color="#ABFFEC"/><stop offset="0.4" stop-color="#16D7C5"/><stop offset="1" stop-color="#078899"/></radialGradient>
|
|
12
|
+
<linearGradient id="nb-cloak" x1="0" y1="0" x2="1" y2="1"><stop stop-color="#169EAF"/><stop offset="0.5" stop-color="#08718D"/><stop offset="1" stop-color="#0A344F"/></linearGradient>
|
|
13
|
+
<linearGradient id="nb-app" x1="0" y1="1" x2="0.9" y2="0"><stop stop-color="#7360FF"/><stop offset="0.44" stop-color="#2E8BFF"/><stop offset="1" stop-color="#08DBC2"/></linearGradient>
|
|
14
|
+
<linearGradient id="nb-magic" x1="0" y1="1" x2="1" y2="0"><stop stop-color="#8B5CF6"/><stop offset="0.55" stop-color="#2E8BFF"/><stop offset="1" stop-color="#00D1B2"/></linearGradient>
|
|
15
|
+
<linearGradient id="nb-soft" x1="0" y1="0" x2="1" y2="1"><stop stop-color="#EEF5FF"/><stop offset="0.6" stop-color="#F7F4FF"/><stop offset="1" stop-color="#E8FAF8"/></linearGradient>
|
|
16
|
+
<linearGradient id="nb-dark-surface" x1="0" y1="0" x2="1" y2="1"><stop stop-color="#142A42"/><stop offset="1" stop-color="#0A1628"/></linearGradient>
|
|
17
|
+
<radialGradient id="nb-halo"><stop stop-color="#A8EEE7" stop-opacity="0.55"/><stop offset="1" stop-color="#DFEFFE" stop-opacity="0"/></radialGradient>
|
|
18
|
+
</defs>
|
|
19
|
+
<g id="mascot-cloak"><path d="M170 359C187 378 220 389 255 388C288 389 322 378 343 360L349 400L310 426L299 464L268 454L239 466L218 454L186 459L183 423L153 401Z" fill="url(#nb-cloak)" /><path d="M169 382Q244 432 335 384L320 411Q242 447 177 407Z" fill="#084E67" /><path d="M188 427L238 445L212 453L188 449Z" fill="#20A9B1" /><path d="M268 426L288 460L264 449L242 460L244 441Z" fill="#0D405E" /></g><g id="mascot-ears"><path d="M153 282C126 264 98 251 59 248C65 285 91 320 127 334L161 316Z" fill="url(#nb-ear)" /><path d="M350 277C377 248 404 232 448 221C441 267 418 306 380 326L350 311Z" fill="url(#nb-ear)" /><path d="M137 292Q115 273 79 264Q94 295 132 314Z" fill="url(#nb-ear-inner)" /><path d="M371 285Q395 255 429 240Q417 281 382 307Z" fill="url(#nb-ear-inner)" /></g><g id="mascot-hood"><path d="M118 276C127 219 151 166 183 112C217 55 258 29 303 44C344 58 365 87 386 109C359 101 337 112 325 137C331 177 361 210 367 248C392 276 391 320 368 353C345 390 304 407 252 407C191 405 149 388 126 353C109 327 108 299 118 276Z" fill="url(#nb-hat)" /><path d="M183 113C216 65 253 35 295 52C250 57 222 100 217 139C207 178 225 207 234 228L136 260C143 216 160 166 183 113Z" fill="#72E5D4" opacity="0.18"/><path d="M284 59C328 61 358 89 384 109C358 100 337 113 325 138C325 167 348 203 359 228C319 209 292 170 282 129C275 98 277 77 284 59Z" fill="url(#nb-hat-fold)" /><path d="M179 117C205 75 234 52 263 47" fill="none" stroke="#C2FFF0" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" opacity="0.66"/><path d="M135 256C197 224 296 222 362 255" fill="none" stroke="#076E91" stroke-width="6" stroke-linecap="round" stroke-linejoin="round" /></g><g id="mascot-face"><path d="M137 290C153 265 189 252 245 251C301 247 340 260 362 288L365 325C361 371 315 397 253 397C192 397 146 375 139 337Z" fill="url(#nb-face)" /></g><g id="mascot-hatband"><path d="M120 279C142 245 181 228 239 224C292 219 336 231 364 252L369 289C333 261 293 251 245 255C191 256 150 273 131 308Z" fill="url(#nb-brim)" /><path d="M136 276C166 248 207 238 251 236C295 235 330 245 351 260" fill="none" stroke="#A5FBE8" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" opacity="0.65"/><path d="M225 254L242 268L257 252Z" fill="#19C6B8" /></g><g id="mascot-expression"><path d="M189 298L216 305M285 304L310 297" fill="none" stroke="#0A1628" stroke-width="5" stroke-linecap="round" stroke-linejoin="round" /><ellipse cx="204" cy="318" rx="10" ry="14" fill="#0A1628"/><ellipse cx="296" cy="318" rx="10" ry="14" fill="#0A1628"/><circle cx="200" cy="305" r="4.1" fill="#FFFFFF" /><circle cx="292" cy="305" r="4.1" fill="#FFFFFF" /><path d="M241 350Q253 355 265 348" fill="none" stroke="#0A1628" stroke-width="4.5" stroke-linecap="round" stroke-linejoin="round" /><ellipse cx="178" cy="343" rx="17" ry="10" fill="#F58E85" opacity="0.38"/><ellipse cx="321" cy="341" rx="17" ry="10" fill="#F58E85" opacity="0.38"/><path d="M250 322Q256 328 250 330" fill="none" stroke="#ECA58E" stroke-width="3" stroke-linecap="round" stroke-linejoin="round" /></g><g id="mascot-hat-orb"><path d="M382 108Q392 111 394 121" fill="none" stroke="#148E9D" stroke-width="7" stroke-linecap="round" stroke-linejoin="round" /><circle cx="395" cy="126" r="18" fill="url(#nb-orb)" /><path d="M385 117Q392 110 402 116" fill="none" stroke="#D1FFF5" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" opacity="0.8"/></g><g id="mascot-magic"><rect x="163" y="397" width="187" height="95" rx="12" fill="#132C46" /><rect x="174" y="408" width="165" height="67" rx="5" fill="#24516B" /><path d="M257 426C259.4 438.8 260.2 439.6 273 442C260.2 444.4 259.4 445.2 257 458C254.6 445.2 253.8 444.4 241 442C253.8 439.6 254.6 438.8 257 426Z" fill="#00D1B2" /><path d="M147 486H363L350 498H162Z" fill="#244C64" /></g>
|
|
20
|
+
</svg>
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="512" height="512" viewBox="0 0 512 512" role="img" aria-labelledby="nb-title nb-desc">
|
|
3
|
+
<title id="nb-title">Niblet elf wizard mascot: thinking</title><desc id="nb-desc">Editable native SVG artwork. No embedded raster images.</desc>
|
|
4
|
+
<defs>
|
|
5
|
+
<linearGradient id="nb-hat" x1="0" y1="0.65" x2="0.9" y2="0.15" gradientUnits="objectBoundingBox"><stop stop-color="#115999"/><stop offset="0.46" stop-color="#1796B1"/><stop offset="0.8" stop-color="#25CBBB"/><stop offset="1" stop-color="#89F3D8"/></linearGradient>
|
|
6
|
+
<linearGradient id="nb-hat-fold" x1="0" y1="0.2" x2="1" y2="0.8"><stop stop-color="#0C5E8D"/><stop offset="0.62" stop-color="#117B90"/><stop offset="1" stop-color="#00A59F"/></linearGradient>
|
|
7
|
+
<linearGradient id="nb-brim" x1="0" y1="1" x2="1" y2="0"><stop stop-color="#2278D3"/><stop offset="0.5" stop-color="#28AADA"/><stop offset="1" stop-color="#67EAD0"/></linearGradient>
|
|
8
|
+
<radialGradient id="nb-face" cx="45%" cy="35%" r="70%"><stop stop-color="#FFF1CF"/><stop offset="0.65" stop-color="#FFDFBA"/><stop offset="1" stop-color="#F4AF91"/></radialGradient>
|
|
9
|
+
<linearGradient id="nb-ear" x1="0" y1="0" x2="0.8" y2="1"><stop stop-color="#FFD7B5"/><stop offset="1" stop-color="#F2A185"/></linearGradient>
|
|
10
|
+
<linearGradient id="nb-ear-inner" x1="0" y1="0" x2="1" y2="1"><stop stop-color="#E98072"/><stop offset="1" stop-color="#F6B797"/></linearGradient>
|
|
11
|
+
<radialGradient id="nb-orb" cx="30%" cy="23%" r="80%"><stop stop-color="#ABFFEC"/><stop offset="0.4" stop-color="#16D7C5"/><stop offset="1" stop-color="#078899"/></radialGradient>
|
|
12
|
+
<linearGradient id="nb-cloak" x1="0" y1="0" x2="1" y2="1"><stop stop-color="#169EAF"/><stop offset="0.5" stop-color="#08718D"/><stop offset="1" stop-color="#0A344F"/></linearGradient>
|
|
13
|
+
<linearGradient id="nb-app" x1="0" y1="1" x2="0.9" y2="0"><stop stop-color="#7360FF"/><stop offset="0.44" stop-color="#2E8BFF"/><stop offset="1" stop-color="#08DBC2"/></linearGradient>
|
|
14
|
+
<linearGradient id="nb-magic" x1="0" y1="1" x2="1" y2="0"><stop stop-color="#8B5CF6"/><stop offset="0.55" stop-color="#2E8BFF"/><stop offset="1" stop-color="#00D1B2"/></linearGradient>
|
|
15
|
+
<linearGradient id="nb-soft" x1="0" y1="0" x2="1" y2="1"><stop stop-color="#EEF5FF"/><stop offset="0.6" stop-color="#F7F4FF"/><stop offset="1" stop-color="#E8FAF8"/></linearGradient>
|
|
16
|
+
<linearGradient id="nb-dark-surface" x1="0" y1="0" x2="1" y2="1"><stop stop-color="#142A42"/><stop offset="1" stop-color="#0A1628"/></linearGradient>
|
|
17
|
+
<radialGradient id="nb-halo"><stop stop-color="#A8EEE7" stop-opacity="0.55"/><stop offset="1" stop-color="#DFEFFE" stop-opacity="0"/></radialGradient>
|
|
18
|
+
</defs>
|
|
19
|
+
<g id="mascot-cloak"><path d="M170 359C187 378 220 389 255 388C288 389 322 378 343 360L349 400L310 426L299 464L268 454L239 466L218 454L186 459L183 423L153 401Z" fill="url(#nb-cloak)" /><path d="M169 382Q244 432 335 384L320 411Q242 447 177 407Z" fill="#084E67" /><path d="M188 427L238 445L212 453L188 449Z" fill="#20A9B1" /><path d="M268 426L288 460L264 449L242 460L244 441Z" fill="#0D405E" /></g><g id="mascot-ears"><path d="M153 282C126 264 98 251 59 248C65 285 91 320 127 334L161 316Z" fill="url(#nb-ear)" /><path d="M350 277C377 248 404 232 448 221C441 267 418 306 380 326L350 311Z" fill="url(#nb-ear)" /><path d="M137 292Q115 273 79 264Q94 295 132 314Z" fill="url(#nb-ear-inner)" /><path d="M371 285Q395 255 429 240Q417 281 382 307Z" fill="url(#nb-ear-inner)" /></g><g id="mascot-hood"><path d="M118 276C127 219 151 166 183 112C217 55 258 29 303 44C344 58 365 87 386 109C359 101 337 112 325 137C331 177 361 210 367 248C392 276 391 320 368 353C345 390 304 407 252 407C191 405 149 388 126 353C109 327 108 299 118 276Z" fill="url(#nb-hat)" /><path d="M183 113C216 65 253 35 295 52C250 57 222 100 217 139C207 178 225 207 234 228L136 260C143 216 160 166 183 113Z" fill="#72E5D4" opacity="0.18"/><path d="M284 59C328 61 358 89 384 109C358 100 337 113 325 138C325 167 348 203 359 228C319 209 292 170 282 129C275 98 277 77 284 59Z" fill="url(#nb-hat-fold)" /><path d="M179 117C205 75 234 52 263 47" fill="none" stroke="#C2FFF0" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" opacity="0.66"/><path d="M135 256C197 224 296 222 362 255" fill="none" stroke="#076E91" stroke-width="6" stroke-linecap="round" stroke-linejoin="round" /></g><g id="mascot-face"><path d="M137 290C153 265 189 252 245 251C301 247 340 260 362 288L365 325C361 371 315 397 253 397C192 397 146 375 139 337Z" fill="url(#nb-face)" /></g><g id="mascot-hatband"><path d="M120 279C142 245 181 228 239 224C292 219 336 231 364 252L369 289C333 261 293 251 245 255C191 256 150 273 131 308Z" fill="url(#nb-brim)" /><path d="M136 276C166 248 207 238 251 236C295 235 330 245 351 260" fill="none" stroke="#A5FBE8" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" opacity="0.65"/><path d="M225 254L242 268L257 252Z" fill="#19C6B8" /></g><g id="mascot-expression"><ellipse cx="208" cy="312" rx="12" ry="19" fill="#0A1628"/><ellipse cx="300" cy="312" rx="12" ry="19" fill="#0A1628"/><circle cx="205" cy="305" r="4.1" fill="#FFFFFF" /><circle cx="297" cy="305" r="4.1" fill="#FFFFFF" /><path d="M187 280Q199 271 211 279M285 278Q297 268 309 278" fill="none" stroke="#0A1628" stroke-width="4.5" stroke-linecap="round" stroke-linejoin="round" /><path d="M239 350Q249 343 259 349" fill="none" stroke="#0A1628" stroke-width="4.5" stroke-linecap="round" stroke-linejoin="round" /><ellipse cx="178" cy="343" rx="17" ry="10" fill="#F58E85" opacity="0.38"/><ellipse cx="321" cy="341" rx="17" ry="10" fill="#F58E85" opacity="0.38"/><path d="M250 322Q256 328 250 330" fill="none" stroke="#ECA58E" stroke-width="3" stroke-linecap="round" stroke-linejoin="round" /></g><g id="mascot-hat-orb"><path d="M382 108Q392 111 394 121" fill="none" stroke="#148E9D" stroke-width="7" stroke-linecap="round" stroke-linejoin="round" /><circle cx="395" cy="126" r="18" fill="url(#nb-orb)" /><path d="M385 117Q392 110 402 116" fill="none" stroke="#D1FFF5" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" opacity="0.8"/></g><g id="mascot-magic"><g fill="#2E8BFF" transform="translate(409 193) scale(0.0283203 -0.0283203)"><path d="M418 439H683V502C683 618 752 668 877 751C1010 840 1078 962 1078 1112C1078 1346 874 1512 581 1512C271 1512 64 1314 64 1033H347C347 1180 435 1271 578 1271C708 1271 791 1198 791 1086C791 1008 750 934 648 872C492 781 418 721 418 522ZM554 -18C648 -18 724 57 724 152C724 246 648 322 554 322C460 322 384 246 384 152C384 57 460 -18 554 -18Z" transform="translate(0 0)"/></g><circle cx="374" cy="205" r="4" fill="#00D1B2" /></g>
|
|
20
|
+
</svg>
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="210" height="112" viewBox="0 0 210 112" role="img" aria-label="Build from your system">
|
|
2
|
+
<title>Build from your system</title>
|
|
3
|
+
<style>
|
|
4
|
+
/* GitHub renders the README on white or on #0d1117 and gives an img no way to inherit either,
|
|
5
|
+
so the card asks the viewer directly. Both values are GitHub's own body text colours. */
|
|
6
|
+
.nb-caption { fill: #1f2328; }
|
|
7
|
+
@media (prefers-color-scheme: dark) { .nb-caption { fill: #e6edf3; } }
|
|
8
|
+
</style>
|
|
9
|
+
<g transform="translate(62 2) scale(0.16796875)">
|
|
10
|
+
<defs>
|
|
11
|
+
<linearGradient id="nb-hat" x1="0" y1="0.65" x2="0.9" y2="0.15" gradientUnits="objectBoundingBox"><stop stop-color="#115999"/><stop offset="0.46" stop-color="#1796B1"/><stop offset="0.8" stop-color="#25CBBB"/><stop offset="1" stop-color="#89F3D8"/></linearGradient>
|
|
12
|
+
<linearGradient id="nb-hat-fold" x1="0" y1="0.2" x2="1" y2="0.8"><stop stop-color="#0C5E8D"/><stop offset="0.62" stop-color="#117B90"/><stop offset="1" stop-color="#00A59F"/></linearGradient>
|
|
13
|
+
<linearGradient id="nb-brim" x1="0" y1="1" x2="1" y2="0"><stop stop-color="#2278D3"/><stop offset="0.5" stop-color="#28AADA"/><stop offset="1" stop-color="#67EAD0"/></linearGradient>
|
|
14
|
+
<radialGradient id="nb-face" cx="45%" cy="35%" r="70%"><stop stop-color="#FFF1CF"/><stop offset="0.65" stop-color="#FFDFBA"/><stop offset="1" stop-color="#F4AF91"/></radialGradient>
|
|
15
|
+
<linearGradient id="nb-ear" x1="0" y1="0" x2="0.8" y2="1"><stop stop-color="#FFD7B5"/><stop offset="1" stop-color="#F2A185"/></linearGradient>
|
|
16
|
+
<linearGradient id="nb-ear-inner" x1="0" y1="0" x2="1" y2="1"><stop stop-color="#E98072"/><stop offset="1" stop-color="#F6B797"/></linearGradient>
|
|
17
|
+
<radialGradient id="nb-orb" cx="30%" cy="23%" r="80%"><stop stop-color="#ABFFEC"/><stop offset="0.4" stop-color="#16D7C5"/><stop offset="1" stop-color="#078899"/></radialGradient>
|
|
18
|
+
<linearGradient id="nb-cloak" x1="0" y1="0" x2="1" y2="1"><stop stop-color="#169EAF"/><stop offset="0.5" stop-color="#08718D"/><stop offset="1" stop-color="#0A344F"/></linearGradient>
|
|
19
|
+
<linearGradient id="nb-app" x1="0" y1="1" x2="0.9" y2="0"><stop stop-color="#7360FF"/><stop offset="0.44" stop-color="#2E8BFF"/><stop offset="1" stop-color="#08DBC2"/></linearGradient>
|
|
20
|
+
<linearGradient id="nb-magic" x1="0" y1="1" x2="1" y2="0"><stop stop-color="#8B5CF6"/><stop offset="0.55" stop-color="#2E8BFF"/><stop offset="1" stop-color="#00D1B2"/></linearGradient>
|
|
21
|
+
<linearGradient id="nb-soft" x1="0" y1="0" x2="1" y2="1"><stop stop-color="#EEF5FF"/><stop offset="0.6" stop-color="#F7F4FF"/><stop offset="1" stop-color="#E8FAF8"/></linearGradient>
|
|
22
|
+
<linearGradient id="nb-dark-surface" x1="0" y1="0" x2="1" y2="1"><stop stop-color="#142A42"/><stop offset="1" stop-color="#0A1628"/></linearGradient>
|
|
23
|
+
<radialGradient id="nb-halo"><stop stop-color="#A8EEE7" stop-opacity="0.55"/><stop offset="1" stop-color="#DFEFFE" stop-opacity="0"/></radialGradient>
|
|
24
|
+
</defs>
|
|
25
|
+
<g id="mascot-cloak"><path d="M170 359C187 378 220 389 255 388C288 389 322 378 343 360L349 400L310 426L299 464L268 454L239 466L218 454L186 459L183 423L153 401Z" fill="url(#nb-cloak)" /><path d="M169 382Q244 432 335 384L320 411Q242 447 177 407Z" fill="#084E67" /><path d="M188 427L238 445L212 453L188 449Z" fill="#20A9B1" /><path d="M268 426L288 460L264 449L242 460L244 441Z" fill="#0D405E" /></g><g id="mascot-ears"><path d="M153 282C126 264 98 251 59 248C65 285 91 320 127 334L161 316Z" fill="url(#nb-ear)" /><path d="M350 277C377 248 404 232 448 221C441 267 418 306 380 326L350 311Z" fill="url(#nb-ear)" /><path d="M137 292Q115 273 79 264Q94 295 132 314Z" fill="url(#nb-ear-inner)" /><path d="M371 285Q395 255 429 240Q417 281 382 307Z" fill="url(#nb-ear-inner)" /></g><g id="mascot-hood"><path d="M118 276C127 219 151 166 183 112C217 55 258 29 303 44C344 58 365 87 386 109C359 101 337 112 325 137C331 177 361 210 367 248C392 276 391 320 368 353C345 390 304 407 252 407C191 405 149 388 126 353C109 327 108 299 118 276Z" fill="url(#nb-hat)" /><path d="M183 113C216 65 253 35 295 52C250 57 222 100 217 139C207 178 225 207 234 228L136 260C143 216 160 166 183 113Z" fill="#72E5D4" opacity="0.18"/><path d="M284 59C328 61 358 89 384 109C358 100 337 113 325 138C325 167 348 203 359 228C319 209 292 170 282 129C275 98 277 77 284 59Z" fill="url(#nb-hat-fold)" /><path d="M179 117C205 75 234 52 263 47" fill="none" stroke="#C2FFF0" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" opacity="0.66"/><path d="M135 256C197 224 296 222 362 255" fill="none" stroke="#076E91" stroke-width="6" stroke-linecap="round" stroke-linejoin="round" /></g><g id="mascot-face"><path d="M137 290C153 265 189 252 245 251C301 247 340 260 362 288L365 325C361 371 315 397 253 397C192 397 146 375 139 337Z" fill="url(#nb-face)" /></g><g id="mascot-hatband"><path d="M120 279C142 245 181 228 239 224C292 219 336 231 364 252L369 289C333 261 293 251 245 255C191 256 150 273 131 308Z" fill="url(#nb-brim)" /><path d="M136 276C166 248 207 238 251 236C295 235 330 245 351 260" fill="none" stroke="#A5FBE8" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" opacity="0.65"/><path d="M225 254L242 268L257 252Z" fill="#19C6B8" /></g><g id="mascot-expression"><path d="M189 298L216 305M285 304L310 297" fill="none" stroke="#0A1628" stroke-width="5" stroke-linecap="round" stroke-linejoin="round" /><ellipse cx="204" cy="318" rx="10" ry="14" fill="#0A1628"/><ellipse cx="296" cy="318" rx="10" ry="14" fill="#0A1628"/><circle cx="200" cy="305" r="4.1" fill="#FFFFFF" /><circle cx="292" cy="305" r="4.1" fill="#FFFFFF" /><path d="M241 350Q253 355 265 348" fill="none" stroke="#0A1628" stroke-width="4.5" stroke-linecap="round" stroke-linejoin="round" /><ellipse cx="178" cy="343" rx="17" ry="10" fill="#F58E85" opacity="0.38"/><ellipse cx="321" cy="341" rx="17" ry="10" fill="#F58E85" opacity="0.38"/><path d="M250 322Q256 328 250 330" fill="none" stroke="#ECA58E" stroke-width="3" stroke-linecap="round" stroke-linejoin="round" /></g><g id="mascot-hat-orb"><path d="M382 108Q392 111 394 121" fill="none" stroke="#148E9D" stroke-width="7" stroke-linecap="round" stroke-linejoin="round" /><circle cx="395" cy="126" r="18" fill="url(#nb-orb)" /><path d="M385 117Q392 110 402 116" fill="none" stroke="#D1FFF5" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" opacity="0.8"/></g><g id="mascot-magic"><rect x="163" y="397" width="187" height="95" rx="12" fill="#132C46" /><rect x="174" y="408" width="165" height="67" rx="5" fill="#24516B" /><path d="M257 426C259.4 438.8 260.2 439.6 273 442C260.2 444.4 259.4 445.2 257 458C254.6 445.2 253.8 444.4 241 442C253.8 439.6 254.6 438.8 257 426Z" fill="#00D1B2" /><path d="M147 486H363L350 498H162Z" fill="#244C64" /></g>
|
|
26
|
+
</g>
|
|
27
|
+
<text class="nb-caption" x="105" y="103" text-anchor="middle" font-size="14.5" font-weight="700"
|
|
28
|
+
font-family="-apple-system, BlinkMacSystemFont, 'Segoe UI', 'Noto Sans', Helvetica, Arial, sans-serif">Build from your system</text>
|
|
29
|
+
</svg>
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="210" height="112" viewBox="0 0 210 112" role="img" aria-label="Check the rendered screen">
|
|
2
|
+
<title>Check the rendered screen</title>
|
|
3
|
+
<style>
|
|
4
|
+
/* GitHub renders the README on white or on #0d1117 and gives an img no way to inherit either,
|
|
5
|
+
so the card asks the viewer directly. Both values are GitHub's own body text colours. */
|
|
6
|
+
.nb-caption { fill: #1f2328; }
|
|
7
|
+
@media (prefers-color-scheme: dark) { .nb-caption { fill: #e6edf3; } }
|
|
8
|
+
</style>
|
|
9
|
+
<g transform="translate(62 2) scale(0.16796875)">
|
|
10
|
+
<defs>
|
|
11
|
+
<linearGradient id="nb-hat" x1="0" y1="0.65" x2="0.9" y2="0.15" gradientUnits="objectBoundingBox"><stop stop-color="#115999"/><stop offset="0.46" stop-color="#1796B1"/><stop offset="0.8" stop-color="#25CBBB"/><stop offset="1" stop-color="#89F3D8"/></linearGradient>
|
|
12
|
+
<linearGradient id="nb-hat-fold" x1="0" y1="0.2" x2="1" y2="0.8"><stop stop-color="#0C5E8D"/><stop offset="0.62" stop-color="#117B90"/><stop offset="1" stop-color="#00A59F"/></linearGradient>
|
|
13
|
+
<linearGradient id="nb-brim" x1="0" y1="1" x2="1" y2="0"><stop stop-color="#2278D3"/><stop offset="0.5" stop-color="#28AADA"/><stop offset="1" stop-color="#67EAD0"/></linearGradient>
|
|
14
|
+
<radialGradient id="nb-face" cx="45%" cy="35%" r="70%"><stop stop-color="#FFF1CF"/><stop offset="0.65" stop-color="#FFDFBA"/><stop offset="1" stop-color="#F4AF91"/></radialGradient>
|
|
15
|
+
<linearGradient id="nb-ear" x1="0" y1="0" x2="0.8" y2="1"><stop stop-color="#FFD7B5"/><stop offset="1" stop-color="#F2A185"/></linearGradient>
|
|
16
|
+
<linearGradient id="nb-ear-inner" x1="0" y1="0" x2="1" y2="1"><stop stop-color="#E98072"/><stop offset="1" stop-color="#F6B797"/></linearGradient>
|
|
17
|
+
<radialGradient id="nb-orb" cx="30%" cy="23%" r="80%"><stop stop-color="#ABFFEC"/><stop offset="0.4" stop-color="#16D7C5"/><stop offset="1" stop-color="#078899"/></radialGradient>
|
|
18
|
+
<linearGradient id="nb-cloak" x1="0" y1="0" x2="1" y2="1"><stop stop-color="#169EAF"/><stop offset="0.5" stop-color="#08718D"/><stop offset="1" stop-color="#0A344F"/></linearGradient>
|
|
19
|
+
<linearGradient id="nb-app" x1="0" y1="1" x2="0.9" y2="0"><stop stop-color="#7360FF"/><stop offset="0.44" stop-color="#2E8BFF"/><stop offset="1" stop-color="#08DBC2"/></linearGradient>
|
|
20
|
+
<linearGradient id="nb-magic" x1="0" y1="1" x2="1" y2="0"><stop stop-color="#8B5CF6"/><stop offset="0.55" stop-color="#2E8BFF"/><stop offset="1" stop-color="#00D1B2"/></linearGradient>
|
|
21
|
+
<linearGradient id="nb-soft" x1="0" y1="0" x2="1" y2="1"><stop stop-color="#EEF5FF"/><stop offset="0.6" stop-color="#F7F4FF"/><stop offset="1" stop-color="#E8FAF8"/></linearGradient>
|
|
22
|
+
<linearGradient id="nb-dark-surface" x1="0" y1="0" x2="1" y2="1"><stop stop-color="#142A42"/><stop offset="1" stop-color="#0A1628"/></linearGradient>
|
|
23
|
+
<radialGradient id="nb-halo"><stop stop-color="#A8EEE7" stop-opacity="0.55"/><stop offset="1" stop-color="#DFEFFE" stop-opacity="0"/></radialGradient>
|
|
24
|
+
</defs>
|
|
25
|
+
<g id="mascot-cloak"><path d="M170 359C187 378 220 389 255 388C288 389 322 378 343 360L349 400L310 426L299 464L268 454L239 466L218 454L186 459L183 423L153 401Z" fill="url(#nb-cloak)" /><path d="M169 382Q244 432 335 384L320 411Q242 447 177 407Z" fill="#084E67" /><path d="M188 427L238 445L212 453L188 449Z" fill="#20A9B1" /><path d="M268 426L288 460L264 449L242 460L244 441Z" fill="#0D405E" /></g><g id="mascot-ears"><path d="M153 282C126 264 98 251 59 248C65 285 91 320 127 334L161 316Z" fill="url(#nb-ear)" /><path d="M350 277C377 248 404 232 448 221C441 267 418 306 380 326L350 311Z" fill="url(#nb-ear)" /><path d="M137 292Q115 273 79 264Q94 295 132 314Z" fill="url(#nb-ear-inner)" /><path d="M371 285Q395 255 429 240Q417 281 382 307Z" fill="url(#nb-ear-inner)" /></g><g id="mascot-hood"><path d="M118 276C127 219 151 166 183 112C217 55 258 29 303 44C344 58 365 87 386 109C359 101 337 112 325 137C331 177 361 210 367 248C392 276 391 320 368 353C345 390 304 407 252 407C191 405 149 388 126 353C109 327 108 299 118 276Z" fill="url(#nb-hat)" /><path d="M183 113C216 65 253 35 295 52C250 57 222 100 217 139C207 178 225 207 234 228L136 260C143 216 160 166 183 113Z" fill="#72E5D4" opacity="0.18"/><path d="M284 59C328 61 358 89 384 109C358 100 337 113 325 138C325 167 348 203 359 228C319 209 292 170 282 129C275 98 277 77 284 59Z" fill="url(#nb-hat-fold)" /><path d="M179 117C205 75 234 52 263 47" fill="none" stroke="#C2FFF0" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" opacity="0.66"/><path d="M135 256C197 224 296 222 362 255" fill="none" stroke="#076E91" stroke-width="6" stroke-linecap="round" stroke-linejoin="round" /></g><g id="mascot-face"><path d="M137 290C153 265 189 252 245 251C301 247 340 260 362 288L365 325C361 371 315 397 253 397C192 397 146 375 139 337Z" fill="url(#nb-face)" /></g><g id="mascot-hatband"><path d="M120 279C142 245 181 228 239 224C292 219 336 231 364 252L369 289C333 261 293 251 245 255C191 256 150 273 131 308Z" fill="url(#nb-brim)" /><path d="M136 276C166 248 207 238 251 236C295 235 330 245 351 260" fill="none" stroke="#A5FBE8" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" opacity="0.65"/><path d="M225 254L242 268L257 252Z" fill="#19C6B8" /></g><g id="mascot-expression"><path d="M190 311Q203 293 216 311M283 311Q296 293 309 311" fill="none" stroke="#0A1628" stroke-width="6" stroke-linecap="round" stroke-linejoin="round" /><path d="M187 280Q199 271 211 279M285 278Q297 268 309 278" fill="none" stroke="#0A1628" stroke-width="4.5" stroke-linecap="round" stroke-linejoin="round" /><path d="M231 341Q254 352 277 340Q269 366 253 366Q239 365 231 341Z" fill="#0A1628" /><path d="M241 360Q253 352 266 359Q255 370 241 360Z" fill="#FA948C" /><ellipse cx="178" cy="343" rx="17" ry="10" fill="#F58E85" opacity="0.38"/><ellipse cx="321" cy="341" rx="17" ry="10" fill="#F58E85" opacity="0.38"/><path d="M250 322Q256 328 250 330" fill="none" stroke="#ECA58E" stroke-width="3" stroke-linecap="round" stroke-linejoin="round" /></g><g id="mascot-hat-orb"><path d="M382 108Q392 111 394 121" fill="none" stroke="#148E9D" stroke-width="7" stroke-linecap="round" stroke-linejoin="round" /><circle cx="395" cy="126" r="18" fill="url(#nb-orb)" /><path d="M385 117Q392 110 402 116" fill="none" stroke="#D1FFF5" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" opacity="0.8"/></g><g id="mascot-magic"><g transform="translate(77 142) scale(1)" transform-origin="0 0"><rect x="-3" y="-9" width="6" height="18" rx="3" fill="#FF6B6B" /></g><g transform="translate(113 80) scale(1)" transform-origin="0 0"><rect x="-3" y="-9" width="6" height="18" rx="3" fill="#8B5CF6" /></g><g transform="translate(446 162) scale(1)" transform-origin="0 0"><rect x="-3" y="-9" width="6" height="18" rx="3" fill="#00D1B2" /></g><g transform="translate(431 82) scale(1)" transform-origin="0 0"><rect x="-3" y="-9" width="6" height="18" rx="3" fill="#F4B400" /></g><path d="M85 185C87.25 197.0 88.0 197.75 100 200C88.0 202.25 87.25 203.0 85 215C82.75 203.0 82.0 202.25 70 200C82.0 197.75 82.75 197.0 85 185Z" fill="#F4B400" /><path d="M444 342C446.4 354.8 447.2 355.6 460 358C447.2 360.4 446.4 361.2 444 374C441.6 361.2 440.8 360.4 428 358C440.8 355.6 441.6 354.8 444 342Z" fill="#2E8BFF" /><path d="M361 46C362.35 53.2 362.8 53.65 370 55C362.8 56.35 362.35 56.8 361 64C359.65 56.8 359.2 56.35 352 55C359.2 53.65 359.65 53.2 361 46Z" fill="#8B5CF6" /></g>
|
|
26
|
+
</g>
|
|
27
|
+
<text class="nb-caption" x="105" y="103" text-anchor="middle" font-size="14.5" font-weight="700"
|
|
28
|
+
font-family="-apple-system, BlinkMacSystemFont, 'Segoe UI', 'Noto Sans', Helvetica, Arial, sans-serif">Check the rendered screen</text>
|
|
29
|
+
</svg>
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="210" height="112" viewBox="0 0 210 112" role="img" aria-label="Settle the contract">
|
|
2
|
+
<title>Settle the contract</title>
|
|
3
|
+
<style>
|
|
4
|
+
/* GitHub renders the README on white or on #0d1117 and gives an img no way to inherit either,
|
|
5
|
+
so the card asks the viewer directly. Both values are GitHub's own body text colours. */
|
|
6
|
+
.nb-caption { fill: #1f2328; }
|
|
7
|
+
@media (prefers-color-scheme: dark) { .nb-caption { fill: #e6edf3; } }
|
|
8
|
+
</style>
|
|
9
|
+
<g transform="translate(62 2) scale(0.16796875)">
|
|
10
|
+
<defs>
|
|
11
|
+
<linearGradient id="nb-hat" x1="0" y1="0.65" x2="0.9" y2="0.15" gradientUnits="objectBoundingBox"><stop stop-color="#115999"/><stop offset="0.46" stop-color="#1796B1"/><stop offset="0.8" stop-color="#25CBBB"/><stop offset="1" stop-color="#89F3D8"/></linearGradient>
|
|
12
|
+
<linearGradient id="nb-hat-fold" x1="0" y1="0.2" x2="1" y2="0.8"><stop stop-color="#0C5E8D"/><stop offset="0.62" stop-color="#117B90"/><stop offset="1" stop-color="#00A59F"/></linearGradient>
|
|
13
|
+
<linearGradient id="nb-brim" x1="0" y1="1" x2="1" y2="0"><stop stop-color="#2278D3"/><stop offset="0.5" stop-color="#28AADA"/><stop offset="1" stop-color="#67EAD0"/></linearGradient>
|
|
14
|
+
<radialGradient id="nb-face" cx="45%" cy="35%" r="70%"><stop stop-color="#FFF1CF"/><stop offset="0.65" stop-color="#FFDFBA"/><stop offset="1" stop-color="#F4AF91"/></radialGradient>
|
|
15
|
+
<linearGradient id="nb-ear" x1="0" y1="0" x2="0.8" y2="1"><stop stop-color="#FFD7B5"/><stop offset="1" stop-color="#F2A185"/></linearGradient>
|
|
16
|
+
<linearGradient id="nb-ear-inner" x1="0" y1="0" x2="1" y2="1"><stop stop-color="#E98072"/><stop offset="1" stop-color="#F6B797"/></linearGradient>
|
|
17
|
+
<radialGradient id="nb-orb" cx="30%" cy="23%" r="80%"><stop stop-color="#ABFFEC"/><stop offset="0.4" stop-color="#16D7C5"/><stop offset="1" stop-color="#078899"/></radialGradient>
|
|
18
|
+
<linearGradient id="nb-cloak" x1="0" y1="0" x2="1" y2="1"><stop stop-color="#169EAF"/><stop offset="0.5" stop-color="#08718D"/><stop offset="1" stop-color="#0A344F"/></linearGradient>
|
|
19
|
+
<linearGradient id="nb-app" x1="0" y1="1" x2="0.9" y2="0"><stop stop-color="#7360FF"/><stop offset="0.44" stop-color="#2E8BFF"/><stop offset="1" stop-color="#08DBC2"/></linearGradient>
|
|
20
|
+
<linearGradient id="nb-magic" x1="0" y1="1" x2="1" y2="0"><stop stop-color="#8B5CF6"/><stop offset="0.55" stop-color="#2E8BFF"/><stop offset="1" stop-color="#00D1B2"/></linearGradient>
|
|
21
|
+
<linearGradient id="nb-soft" x1="0" y1="0" x2="1" y2="1"><stop stop-color="#EEF5FF"/><stop offset="0.6" stop-color="#F7F4FF"/><stop offset="1" stop-color="#E8FAF8"/></linearGradient>
|
|
22
|
+
<linearGradient id="nb-dark-surface" x1="0" y1="0" x2="1" y2="1"><stop stop-color="#142A42"/><stop offset="1" stop-color="#0A1628"/></linearGradient>
|
|
23
|
+
<radialGradient id="nb-halo"><stop stop-color="#A8EEE7" stop-opacity="0.55"/><stop offset="1" stop-color="#DFEFFE" stop-opacity="0"/></radialGradient>
|
|
24
|
+
</defs>
|
|
25
|
+
<g id="mascot-cloak"><path d="M170 359C187 378 220 389 255 388C288 389 322 378 343 360L349 400L310 426L299 464L268 454L239 466L218 454L186 459L183 423L153 401Z" fill="url(#nb-cloak)" /><path d="M169 382Q244 432 335 384L320 411Q242 447 177 407Z" fill="#084E67" /><path d="M188 427L238 445L212 453L188 449Z" fill="#20A9B1" /><path d="M268 426L288 460L264 449L242 460L244 441Z" fill="#0D405E" /></g><g id="mascot-ears"><path d="M153 282C126 264 98 251 59 248C65 285 91 320 127 334L161 316Z" fill="url(#nb-ear)" /><path d="M350 277C377 248 404 232 448 221C441 267 418 306 380 326L350 311Z" fill="url(#nb-ear)" /><path d="M137 292Q115 273 79 264Q94 295 132 314Z" fill="url(#nb-ear-inner)" /><path d="M371 285Q395 255 429 240Q417 281 382 307Z" fill="url(#nb-ear-inner)" /></g><g id="mascot-hood"><path d="M118 276C127 219 151 166 183 112C217 55 258 29 303 44C344 58 365 87 386 109C359 101 337 112 325 137C331 177 361 210 367 248C392 276 391 320 368 353C345 390 304 407 252 407C191 405 149 388 126 353C109 327 108 299 118 276Z" fill="url(#nb-hat)" /><path d="M183 113C216 65 253 35 295 52C250 57 222 100 217 139C207 178 225 207 234 228L136 260C143 216 160 166 183 113Z" fill="#72E5D4" opacity="0.18"/><path d="M284 59C328 61 358 89 384 109C358 100 337 113 325 138C325 167 348 203 359 228C319 209 292 170 282 129C275 98 277 77 284 59Z" fill="url(#nb-hat-fold)" /><path d="M179 117C205 75 234 52 263 47" fill="none" stroke="#C2FFF0" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" opacity="0.66"/><path d="M135 256C197 224 296 222 362 255" fill="none" stroke="#076E91" stroke-width="6" stroke-linecap="round" stroke-linejoin="round" /></g><g id="mascot-face"><path d="M137 290C153 265 189 252 245 251C301 247 340 260 362 288L365 325C361 371 315 397 253 397C192 397 146 375 139 337Z" fill="url(#nb-face)" /></g><g id="mascot-hatband"><path d="M120 279C142 245 181 228 239 224C292 219 336 231 364 252L369 289C333 261 293 251 245 255C191 256 150 273 131 308Z" fill="url(#nb-brim)" /><path d="M136 276C166 248 207 238 251 236C295 235 330 245 351 260" fill="none" stroke="#A5FBE8" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" opacity="0.65"/><path d="M225 254L242 268L257 252Z" fill="#19C6B8" /></g><g id="mascot-expression"><ellipse cx="208" cy="312" rx="12" ry="19" fill="#0A1628"/><ellipse cx="300" cy="312" rx="12" ry="19" fill="#0A1628"/><circle cx="205" cy="305" r="4.1" fill="#FFFFFF" /><circle cx="297" cy="305" r="4.1" fill="#FFFFFF" /><path d="M187 280Q199 271 211 279M285 278Q297 268 309 278" fill="none" stroke="#0A1628" stroke-width="4.5" stroke-linecap="round" stroke-linejoin="round" /><path d="M239 350Q249 343 259 349" fill="none" stroke="#0A1628" stroke-width="4.5" stroke-linecap="round" stroke-linejoin="round" /><ellipse cx="178" cy="343" rx="17" ry="10" fill="#F58E85" opacity="0.38"/><ellipse cx="321" cy="341" rx="17" ry="10" fill="#F58E85" opacity="0.38"/><path d="M250 322Q256 328 250 330" fill="none" stroke="#ECA58E" stroke-width="3" stroke-linecap="round" stroke-linejoin="round" /></g><g id="mascot-hat-orb"><path d="M382 108Q392 111 394 121" fill="none" stroke="#148E9D" stroke-width="7" stroke-linecap="round" stroke-linejoin="round" /><circle cx="395" cy="126" r="18" fill="url(#nb-orb)" /><path d="M385 117Q392 110 402 116" fill="none" stroke="#D1FFF5" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" opacity="0.8"/></g><g id="mascot-magic"><g fill="#2E8BFF" transform="translate(409 193) scale(0.0283203 -0.0283203)"><path d="M418 439H683V502C683 618 752 668 877 751C1010 840 1078 962 1078 1112C1078 1346 874 1512 581 1512C271 1512 64 1314 64 1033H347C347 1180 435 1271 578 1271C708 1271 791 1198 791 1086C791 1008 750 934 648 872C492 781 418 721 418 522ZM554 -18C648 -18 724 57 724 152C724 246 648 322 554 322C460 322 384 246 384 152C384 57 460 -18 554 -18Z" transform="translate(0 0)"/></g><circle cx="374" cy="205" r="4" fill="#00D1B2" /></g>
|
|
26
|
+
</g>
|
|
27
|
+
<text class="nb-caption" x="105" y="103" text-anchor="middle" font-size="14.5" font-weight="700"
|
|
28
|
+
font-family="-apple-system, BlinkMacSystemFont, 'Segoe UI', 'Noto Sans', Helvetica, Arial, sans-serif">Settle the contract</text>
|
|
29
|
+
</svg>
|
package/package.json
CHANGED
|
@@ -8,7 +8,7 @@ The skill can work from the repository, product brief, and supplied screenshots
|
|
|
8
8
|
|
|
9
9
|
## Local stdio MCP package
|
|
10
10
|
|
|
11
|
-
Prerequisites: Node.js **24.15 or later**, this package with its dependencies installed, and a Niblet API
|
|
11
|
+
Prerequisites: Node.js **24.15 or later**, this package with its dependencies installed, and a Niblet API key (`niblet_at_…`, created at `https://www.niblet.com/account`) for catalogue tool calls. The client launches the process locally and communicates over stdio; it is not a local HTTP service.
|
|
12
12
|
|
|
13
13
|
From the package root, run `npm ci --ignore-scripts` to install the locked dependencies. Then configure the MCP host below; it launches the server itself. To run manually with an environment file, use `node --env-file=/absolute/path/to/private.env src/index.mjs`. Plain `npm start` inherits the process environment and does not automatically load `.env`.
|
|
14
14
|
|
|
@@ -34,7 +34,7 @@ For a host using the common `mcpServers` JSON configuration shape:
|
|
|
34
34
|
}
|
|
35
35
|
```
|
|
36
36
|
|
|
37
|
-
Replace the absolute path and token placeholder locally. Adapt the shape to the host's documented configuration if it differs. Prefer a host-managed secret/environment facility where supported; keep tokens out of repository commits, screenshots, queries, and chat. A token is a prerequisite, not something this package creates
|
|
37
|
+
Replace the absolute path and token placeholder locally. Adapt the shape to the host's documented configuration if it differs. Prefer a host-managed secret/environment facility where supported; keep tokens out of repository commits, screenshots, queries, and chat. A token is a prerequisite, not something this package creates: the person creates one for themselves at `https://www.niblet.com/sign-up`, confirms the six-digit code emailed to them, and then creates keys at `https://www.niblet.com/account`. The key's plaintext is shown once, at creation, and can be revoked from the same page.
|
|
38
38
|
|
|
39
39
|
The bundled `mcp.json` is a template: replace both `/absolute/path/to/niblet-skill-mcp/...` placeholders with the real checkout path. It loads an optional `.env` beside the package, so copy `.env.example` to `.env` and supply the token privately, or set `NIBLET_TOKEN` in the host environment. Plain `npm start` still only inherits its environment.
|
|
40
40
|
|
|
@@ -50,6 +50,7 @@ Tool arguments use **`query`**, not `q`. The adapter translates `query` to the R
|
|
|
50
50
|
| --- | --- | --- | --- |
|
|
51
51
|
| `find_ui_references` | `query`: string, 1–240 characters | `platform`: `ios` or `web`; `limit`: integer 1–3, default 2; `selectedIds`: one to three screen IDs, each 1–160 characters; `clientSkillVersion`: string, 1–64 characters | Reference lines with app, screen type, platform, pixel size, ID, summary, and inspect URL, plus one inline image per reference |
|
|
52
52
|
| `find_ui_materials` | `query`: string, 1–240 characters; `kind`: `font`, `icon`, `animated_icon`, or `pack` | `platform`: `ios` or `web`; `limit`: integer 1–3, default 2; `selectedId`: string, 1–160 characters; `userConfirmed`: `true`; `clientSkillVersion`: string, 1–64 characters | Numbered materials with name, recorded license, description, and URL |
|
|
53
|
+
| `get_design_reference` | one of `screenId` (from a reference) or `packSlug` | `clientSkillVersion`: string, 1–64 characters | The pack's style reference as markdown: colours with their roles, typography, and component inventory |
|
|
53
54
|
|
|
54
55
|
Without `selectedIds`, `find_ui_references` searches and attaches thumbnail images. With `selectedIds`, it reads those exact screens and attaches inspection-quality images; an ID the catalogue does not hold is skipped rather than failing the call. `query` is required in both cases.
|
|
55
56
|
|
|
@@ -57,6 +58,8 @@ Without `selectedIds`, `find_ui_references` searches and attaches thumbnail imag
|
|
|
57
58
|
|
|
58
59
|
Screen IDs are nonempty strings up to 160 characters. They reject dot segments, slash, backslash, percent characters, control characters, and malformed Unicode. Use IDs returned by a previous search rather than deriving them from display names. The client URL-encodes accepted identifiers.
|
|
59
60
|
|
|
61
|
+
Only web screens belong to a design pack. A web search says so in its own text; call `get_design_reference` with that screen's ID to read the system behind it. An iOS screen returns a plain "Only web screens have one" rather than an error, so treat a missing reference as an answer and continue from the local design system.
|
|
62
|
+
|
|
60
63
|
Empty results are ordinary text, not failures: `find_ui_references` returns "No relevant references. Continue with the product brief and existing design system." and `find_ui_materials` returns "No <kind> materials matched." Continue from local evidence in both cases.
|
|
61
64
|
|
|
62
65
|
Example tool arguments:
|
|
@@ -95,6 +98,7 @@ This existing remote service exposes **only**:
|
|
|
95
98
|
|
|
96
99
|
- `find_ui_references`
|
|
97
100
|
- `find_ui_materials`
|
|
101
|
+
- `get_design_reference`
|
|
98
102
|
|
|
99
103
|
Its schemas match the local adapter. Both require `query` (1–240 characters), accept `limit` from 1–3 with default 2, and accept optional `platform` (`ios` or `web`). Materials also require `kind` (`font`, `icon`, `animated_icon`, or `pack`); neither deployment supplies packs.
|
|
100
104
|
|
package/src/server.mjs
CHANGED
|
@@ -39,9 +39,25 @@ function textResult(text) {
|
|
|
39
39
|
return { content: [{ type: 'text', text }] };
|
|
40
40
|
}
|
|
41
41
|
|
|
42
|
-
|
|
42
|
+
/**
|
|
43
|
+
* A 401 is nearly always a token mismatch on the user's machine, so the message
|
|
44
|
+
* says exactly what to check and asks the agent to relay it. The token itself is
|
|
45
|
+
* never shown; its length is enough to tell two credentials apart.
|
|
46
|
+
*/
|
|
47
|
+
function authenticationFailed(token, apiOrigin) {
|
|
48
|
+
const length = typeof token === 'string' ? token.trim().length : 0;
|
|
49
|
+
return [
|
|
50
|
+
`Niblet API authentication failed (HTTP 401): ${apiOrigin} rejected the configured NIBLET_TOKEN (${length} characters, not shown).`,
|
|
51
|
+
'Tell the user: the token this MCP server is running with is not one the API accepts.',
|
|
52
|
+
'Most often a NIBLET_TOKEN exported in the shell (e.g. ~/.zshrc, ~/.zshrc.local) overrides the one in the MCP .env file, because node --env-file never replaces a variable that is already set.',
|
|
53
|
+
'To fix: make the shell export and the .env file agree (or remove the export), confirm the token matches the API at that origin, then restart the MCP server so it re-reads its environment.',
|
|
54
|
+
'Run niblet_status to confirm the fix.',
|
|
55
|
+
].join(' ');
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
function httpError(status, context = {}) {
|
|
43
59
|
if (status >= 300 && status < 400) return 'Niblet API redirects are not allowed.';
|
|
44
|
-
if (status === 401) return
|
|
60
|
+
if (status === 401) return authenticationFailed(context.token, context.apiOrigin);
|
|
45
61
|
if (status === 403) return 'Niblet API access denied (HTTP 403).';
|
|
46
62
|
if (status === 404) return 'The requested Niblet resource was not found (HTTP 404).';
|
|
47
63
|
if (status === 429) return 'Niblet API rate limit reached (HTTP 429). No retry was attempted.';
|
|
@@ -196,7 +212,7 @@ export function createServer({
|
|
|
196
212
|
});
|
|
197
213
|
signal.throwIfAborted();
|
|
198
214
|
if (response.redirected) throw new ApiError('Niblet API redirects are not allowed.');
|
|
199
|
-
if (!response.ok) return { ok: false, message: httpError(response.status), status: response.status };
|
|
215
|
+
if (!response.ok) return { ok: false, message: httpError(response.status, { token, apiOrigin: API_ORIGIN }), status: response.status };
|
|
200
216
|
const data = await readJson(response);
|
|
201
217
|
signal.throwIfAborted();
|
|
202
218
|
return { ok: true, data };
|
|
@@ -434,7 +450,7 @@ export function createServer({
|
|
|
434
450
|
}
|
|
435
451
|
lines.push('', 'Reference documents (read as MCP resources):');
|
|
436
452
|
for (const [slug, doc] of Object.entries(SKILL_DOCS)) lines.push(` ${uriFor(slug)} — ${doc.title}`);
|
|
437
|
-
lines.push('', 'Catalogue tools: find_ui_references (real full-screen references), find_ui_materials (license-recorded fonts and icons).
|
|
453
|
+
lines.push('', 'Catalogue tools: find_ui_references (real full-screen references), find_ui_materials (license-recorded fonts and icons), get_design_reference (the recorded colors, typography, and components behind a web screen). All three need NIBLET_TOKEN; run niblet_status to check. Reference retrieval is optional and never a prerequisite to useful work.');
|
|
438
454
|
lines.push('With no target or command, present this menu and wait for a choice rather than making changes.');
|
|
439
455
|
return textResult(lines.join('\n'));
|
|
440
456
|
});
|
|
@@ -465,7 +481,10 @@ export function createServer({
|
|
|
465
481
|
}));
|
|
466
482
|
const readable = docs.filter(Boolean);
|
|
467
483
|
lines.push(`Documents: ${readable.length}/${Object.keys(SKILL_DOCS).length} readable (${readable.map(uriFor).join(', ')}).`);
|
|
468
|
-
|
|
484
|
+
// Read back what this server actually advertises, so the diagnostic cannot drift
|
|
485
|
+
// from the registrations the way a hand-written list does.
|
|
486
|
+
const advertised = Object.keys(server._registeredTools ?? {});
|
|
487
|
+
lines.push(`Tools: ${advertised.length ? advertised.join(', ') : 'none registered'}.`);
|
|
469
488
|
|
|
470
489
|
if (!input.probe) {
|
|
471
490
|
lines.push('', 'API not contacted (probe disabled).');
|