svamp-cli 0.2.56 → 0.2.58

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.
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: artifact
3
- version: 1.0.0
3
+ version: 1.2.0
4
4
  description: Embed a rendered HTML file or live URL inline in chat via a single self-closing `<artifact src="..." />` tag — the Svamp client renders it as a sandboxed iframe with modes for inline, card, bare, and immersive.
5
5
  tags:
6
6
  - svamp
@@ -23,24 +23,28 @@ The client reads the file, inlines relative refs (`./image.png` etc.) as data UR
23
23
 
24
24
  ## Strategy: which mechanism?
25
25
 
26
- Three options, pick the lightest that works:
26
+ Four options, pick the lightest that works:
27
27
 
28
28
  | Mechanism | When |
29
29
  |---|---|
30
- | **Inline `<artifact src="./viz.html" />`** | Self-contained visualization. Cards, charts, animations, prototypes. Files live on disk; the chat marker is tiny. |
31
- | **URL `<artifact src="https://my-app.example.com/" height="540" />`** | Embed a live server you're running, or any external site. Like a Canvas panel inline. |
32
- | **Standalone server (`svamp serve` / `svamp service expose`)** | Real apps with backend, database, multi-user state. Post the URL as a normal markdown link. |
30
+ | **Inline body** `<artifact title="…">…html…</artifact>` | Tiny self-contained widgets: a styled metric card, an SVG diagram, a small Chart.js plot. No file needed; the HTML lives in the chat message. Keep under ~10 KB. |
31
+ | **File `<artifact src="./viz.html" />`** | Substantial visualization (dashboards, 3D scenes, multi-section explorers). Persists on disk, supports relative-ref inlining for `./image.png`, can be `svamp serve`-shared as a stable URL, iterates cleanly via singleton dedupe. |
32
+ | **URL `<artifact src="https://my-app.example.com/" height="540" />`** | Embed a live server you're running, or any external site. Canvas-panel-style. |
33
+ | **Standalone server (`svamp serve` / `svamp service expose`)** | Real apps with backend, database, multi-user state. Post the URL as a normal markdown link, no artifact tag needed. |
33
34
 
34
35
  **Decision tree:**
35
36
  1. Need a backend / database / persistent state? → standalone server.
36
- 2. Iterating on a single artifact (HTML file, dashboard, dataviz)? → write to file, emit `<artifact src="..." />`.
37
- 3. Want to embed a running server inline (preview a dev server, show a deployed app)? → URL src.
37
+ 2. ~10 KB or less, throwaway widget? → **inline body** (`<artifact>...html...</artifact>`).
38
+ 3. Will you iterate on it across messages? **file** (write file, emit `<artifact src="..." />`).
39
+ 4. Embed a running server or external site? → **URL src**.
40
+
41
+ While the agent is still emitting the body content (closing `</artifact>` not yet received), the client shows a "Generating… N chars" placeholder. The iframe only mounts once the close tag arrives — no flashing of half-rendered HTML.
38
42
 
39
43
  ## Attributes
40
44
 
41
45
  ```html
42
46
  <artifact
43
- src="./outputs/viz.html" <!-- REQUIRED: relative file path or absolute URL -->
47
+ src="./outputs/viz.html" <!-- file path OR absolute URL; OR omit and use inline body -->
44
48
  title="Dashboard" <!-- header label -->
45
49
  height="540" <!-- fixed pixel height (10..4000); default = auto-size for files -->
46
50
  wide <!-- extend beyond bubble width -->
@@ -50,7 +54,7 @@ Three options, pick the lightest that works:
50
54
  />
51
55
  ```
52
56
 
53
- Only `src` is required.
57
+ Either `src` or an inline body is required. All other attributes optional.
54
58
 
55
59
  ### Modes
56
60
 
@@ -75,6 +79,28 @@ In `default` and `bare` modes, the user gets a header (or hover bar) with three
75
79
  - **Fullscreen** (⛶) — toggles iframe fullscreen. Hidden automatically on browsers that don't support it (some mobile WebViews).
76
80
  - **⋮ menu** — *Open in new window* (standalone tab), *Reload* (same as the icon), *Show as card* (only when the agent originally emitted `mode="card"` and the user expanded it).
77
81
 
82
+ ## Going inline (no file)
83
+
84
+ For widgets that don't deserve a file — a metric card, a small SVG diagram, a single Chart.js plot — omit `src` and put the HTML directly inside the tag:
85
+
86
+ ```
87
+ <artifact title="Quarterly revenue">
88
+ <div style="font-family:system-ui;padding:16px;background:var(--svamp-surface);border-radius:8px;color:var(--svamp-text)">
89
+ <div style="font-size:11px;color:var(--svamp-text-secondary);text-transform:uppercase;letter-spacing:0.05em">Q4 revenue</div>
90
+ <div style="font-size:28px;font-weight:600;margin-top:4px">$4.2M</div>
91
+ <div style="font-size:12px;color:#059669;margin-top:2px">↑ 18% vs Q3</div>
92
+ </div>
93
+ </artifact>
94
+ ```
95
+
96
+ Inline body works exactly like file content — same sandbox, same theme bridge, same CSP, same auto-resize, same modes. Differences:
97
+
98
+ - **No relative file refs.** Inline body has no associated directory, so `<img src="./local.png">` won't resolve. If you need files, use `src=`.
99
+ - **Bloats chat history.** Inline content lives in the message JSONL, so every replay/sync sends it. Keep under ~10 KB. For anything substantial, write to a file.
100
+ - **No `svamp serve`-style stable URL.** Inline blobs are ephemeral. Use `src=` to a file if you want shareable URLs.
101
+
102
+ When in doubt: inline for tiny standalone widgets, file for anything you might iterate on or share.
103
+
78
104
  ## Writing the file
79
105
 
80
106
  Use the standard Write tool. Two storage conventions:
@@ -190,16 +216,153 @@ if (req.method === 'OPTIONS') return res.end();
190
216
 
191
217
  If the iframe console shows `CORS error`, your server is missing one of these headers.
192
218
 
193
- ## Style philosophy
219
+ ## Style & design system
220
+
221
+ These are **recommendations, not rules**. They produce coherent, polished output by default; deviate when the content calls for it (artistic visualizations, branded posters, deliberately moody experiences).
222
+
223
+ ### Philosophy
224
+
225
+ - **Seamless** — the artifact should feel like it belongs in the chat, not a foreign embed. Use `var(--svamp-bg)` / `var(--svamp-text)` so the visual flips with the host theme.
226
+ - **Flat** — solid fills only by default. Skip gradients, shadows, glow, neon unless the content explicitly calls for them. Use **borders OR shadows, not both**.
227
+ - **Warm minimal** — clean geometric layouts with soft rounded corners (8–12 px). Indigo or sky as primary accent. Slate / zinc / stone for structural neutrals.
228
+ - **Diverse** — pick the visualization type that fits the content: flowchart, timeline, hierarchy, cycle, comparison, chart, calculator. Don't default to one.
229
+ - **Text outside, visuals inside** — prose explanation goes in markdown *around* the artifact, not inside it.
230
+
231
+ ### Typography
232
+
233
+ - Base 14–16 px, line-height ~1.5, system-ui font stack (`system-ui, -apple-system, "Segoe UI", Roboto, sans-serif`).
234
+ - Font weights **400 / 500 / 600** only. Skip 700+ unless it's deliberately punchy.
235
+ - Sentence case for titles. No ALL CAPS labels unless they're tiny (10–11 px) UI labels with letter-spacing.
236
+ - Never set font-size below 11 px — unreadable on mobile.
237
+ - Round every displayed number (`$4.2M`, not `$4218354.97`).
238
+
239
+ ### Spacing
240
+
241
+ Use a 4-px rhythm: 4 / 8 / 12 / 16 / 24 / 32 / 48 px. Pick one scale and stick to it — sloppy spacing reads as noise even when individual elements look fine.
242
+
243
+ ### Color palette (when you need accents)
244
+
245
+ A handy ramp library — five shades per ramp. Use 2–3 ramps per artifact max. Indigo / sky for the primary accent, slate / zinc as structural neutrals.
246
+
247
+ | Ramp | 50 (fill) | 200 (stroke) | 400 (accent) | 600 (subtitle) | 800 (title) |
248
+ |------|-----------|-------------|-------------|----------------|-------------|
249
+ | Indigo | `#EEF2FF` | `#C7D2FE` | `#818CF8` | `#4F46E5` | `#3730A3` |
250
+ | Sky | `#F0F9FF` | `#BAE6FD` | `#38BDF8` | `#0284C7` | `#075985` |
251
+ | Emerald | `#ECFDF5` | `#A7F3D0` | `#34D399` | `#059669` | `#065F46` |
252
+ | Amber | `#FFFBEB` | `#FDE68A` | `#FBBF24` | `#D97706` | `#92400E` |
253
+ | Rose | `#FFF1F2` | `#FECDD3` | `#FB7185` | `#E11D48` | `#9F1239` |
254
+ | Slate | `#F8FAFC` | `#E2E8F0` | `#94A3B8` | `#64748B` | `#334155` |
255
+
256
+ - Text on a 50-fill: use 800 from the same ramp. Never pure black.
257
+ - SVG defaults: 50 fill + 200 stroke + 800 title + 600 subtitle.
258
+ - Chart.js: 400 for `borderColor`, 400 with 0.1 alpha for `backgroundColor`.
259
+
260
+ For inline widgets, you can still reference `var(--svamp-accent)` etc. and skip the ramps — both approaches are fine.
261
+
262
+ ### Animation
263
+
264
+ Animation should *convey* state change, not decorate. Entry animations: 200–400 ms ease-out, stagger child elements by 60–100 ms. Anything longer feels slow.
265
+
266
+ ### Streaming-friendly write order
267
+
268
+ If you're emitting an inline artifact body that the agent generates token-by-token (the user will see streaming progress in the placeholder, but if they ever see partial HTML rendered, this order minimizes flashing):
269
+
270
+ - **SVG**: open `<svg>`, emit `<defs>` (markers, gradients) first, then visual elements top-to-bottom.
271
+ - **HTML**: `<style>` block first, then content, then `<script>` last. Solid fills work even mid-stream; gradients can flash during DOM diffs.
272
+
273
+ ### Mobile-first
274
+
275
+ Single column by default. Widen at media queries (`@media (min-width: 768px)`) only when there's information that benefits from columns. Test by mentally resizing to 320 px wide.
276
+
277
+ ## Chart.js patterns
278
+
279
+ Chart.js is the go-to for data viz. Recommended setup:
280
+
281
+ ```html
282
+ <div style="position:relative;width:100%;height:300px">
283
+ <canvas id="c"></canvas>
284
+ </div>
285
+ <script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
286
+ <script>
287
+ const chart = new Chart(document.getElementById('c'), {
288
+ type: 'line',
289
+ data: {
290
+ labels: ['Jan','Feb','Mar','Apr','May'],
291
+ datasets: [{
292
+ data: [30, 45, 28, 50, 42],
293
+ borderColor: '#818CF8',
294
+ backgroundColor: 'rgba(129,140,248,0.1)',
295
+ fill: true,
296
+ tension: 0.3,
297
+ }],
298
+ },
299
+ options: {
300
+ responsive: true,
301
+ maintainAspectRatio: false,
302
+ plugins: { legend: { display: false } },
303
+ scales: {
304
+ y: { grid: { color: 'rgba(0,0,0,0.06)' } },
305
+ x: { grid: { display: false } },
306
+ },
307
+ },
308
+ });
309
+ </script>
310
+ ```
311
+
312
+ Rules of thumb:
313
+ - Wrapper `<div>` owns the height (Chart.js can't size to a parent that has `auto` height). `width: 100%; height: <N>px`.
314
+ - `responsive: true` + `maintainAspectRatio: false` so the canvas fills the wrapper.
315
+ - Hide the legend by default (`legend: { display: false }`) — adds noise more often than information. Show it only when there are 2+ datasets.
316
+ - Bars: `borderRadius: 6`. Lines: `tension: 0.3` for smooth, `0` for stepped.
317
+ - Multiple charts on one artifact: unique `canvas` IDs.
318
+ - Interactive controls **must** call `chart.update()` after mutating `chart.data`.
319
+
320
+ ```js
321
+ function refresh() {
322
+ const v = +document.getElementById('slider').value;
323
+ chart.data.datasets[0].data = base.map(d => Math.round(d * v / 50));
324
+ chart.update();
325
+ }
326
+ ```
327
+
328
+ ## SVG patterns
329
+
330
+ For flowcharts, timelines, hierarchy diagrams, comparisons:
331
+
332
+ ```html
333
+ <svg width="100%" viewBox="0 0 680 H" style="display:block">
334
+ <defs>
335
+ <marker id="arrow" viewBox="0 0 10 10" refX="9" refY="5"
336
+ markerWidth="6" markerHeight="6" orient="auto">
337
+ <path d="M0,0 L10,5 L0,10 z" fill="#94A3B8"/>
338
+ </marker>
339
+ </defs>
340
+ <!-- nodes & connectors here -->
341
+ </svg>
342
+ ```
343
+
344
+ ViewBox sizing:
345
+ - Fix width at **680** for a comfortable column. Adjust `H` to fit content + 40 px bottom buffer.
346
+ - Keep all content within `x = 0..680`. `text-anchor="end"` extends left from the x coord.
347
+ - `width="100%"` on the `<svg>` element so it scales to bubble width on mobile.
348
+
349
+ Recommended defaults for diagram shapes:
350
+ - Node fill: ramp **50** (light), stroke: ramp **200**, stroke-width 1 or 1.5.
351
+ - Node title text: ramp **800**, weight 500, size 14 px.
352
+ - Node subtitle: ramp **600**, weight 400, size 11–12 px.
353
+ - Connector lines: `#94A3B8` (slate-400) with an arrow marker.
354
+
355
+ ## Common UI patterns
194
356
 
195
- Lean on what HTML does well flow layout, typography, animation without overengineering.
357
+ A short catalog. Pick the one that fits, don't force a single template.
196
358
 
197
- - **Restrained palette.** 1–2 accent colors, lots of neutrals. Slate / zinc / stone ramps work well.
198
- - **Type first.** 14–16px base, 1.5 line-height, system-ui font.
199
- - **Spacing rhythm.** 4 / 8 / 12 / 16 / 24 / 32 / 48 (Tailwind's scale).
200
- - **Borders or shadows, not both.**
201
- - **Animation conveys, not decorates.** 200–400 ms ease-out on entry; longer is noise.
202
- - **Mobile-first.** Single column by default; widen at `md:` only when columns add information.
359
+ - **Metric dashboard** grid of small stat cards (label / number / delta). 4-col on desktop, 2-col on tablet, 1-col on mobile. See the "Quarterly metrics" template below.
360
+ - **Comparison** side-by-side panels, the recommended option bordered in the accent color with a small label badge.
361
+ - **Calculator** labeled `<input type="range">` sliders + live result display. Slider inputs must call `chart.update()` (or update the DOM directly) on every `input` event.
362
+ - **Timeline** — vertical or horizontal sequence with dates, dots, and connector lines.
363
+ - **Flowchart** boxes + arrows in SVG; arrow markers via `<defs>`. Use a `viewBox` for crisp scaling.
364
+ - **Bar comparison** horizontal bars with labels left, value right, bar fills indigo-200, value text indigo-800.
365
+ - **Toggle / select** — segmented buttons or a `<select>` to flip between dataset views.
203
366
 
204
367
  ## Templates
205
368
 
package/dist/cli.mjs CHANGED
@@ -314,7 +314,7 @@ async function main() {
314
314
  } else if (!subcommand || subcommand === "start") {
315
315
  await handleInteractiveCommand();
316
316
  } else if (subcommand === "--version" || subcommand === "-v") {
317
- const pkg = await import('./package-DUYA_zrl.mjs').catch(() => ({ default: { version: "unknown" } }));
317
+ const pkg = await import('./package-GG73qTsa.mjs').catch(() => ({ default: { version: "unknown" } }));
318
318
  console.log(`svamp version: ${pkg.default.version}`);
319
319
  } else {
320
320
  console.error(`Unknown command: ${subcommand}`);
@@ -1,5 +1,5 @@
1
1
  var name = "svamp-cli";
2
- var version = "0.2.56";
2
+ var version = "0.2.58";
3
3
  var description = "Svamp CLI — AI workspace daemon on Hypha Cloud";
4
4
  var author = "Amun AI AB";
5
5
  var license = "SEE LICENSE IN LICENSE";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "svamp-cli",
3
- "version": "0.2.56",
3
+ "version": "0.2.58",
4
4
  "description": "Svamp CLI — AI workspace daemon on Hypha Cloud",
5
5
  "author": "Amun AI AB",
6
6
  "license": "SEE LICENSE IN LICENSE",