svamp-cli 0.2.56 → 0.2.57
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.
|
@@ -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
|
-
|
|
26
|
+
Four options, pick the lightest that works:
|
|
27
27
|
|
|
28
28
|
| Mechanism | When |
|
|
29
29
|
|---|---|
|
|
30
|
-
| **Inline `<artifact
|
|
31
|
-
| **
|
|
32
|
-
| **
|
|
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.
|
|
37
|
-
3.
|
|
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" <!--
|
|
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
|
-
|
|
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:
|
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-
|
|
317
|
+
const pkg = await import('./package-DUJlW79s.mjs').catch(() => ({ default: { version: "unknown" } }));
|
|
318
318
|
console.log(`svamp version: ${pkg.default.version}`);
|
|
319
319
|
} else {
|
|
320
320
|
console.error(`Unknown command: ${subcommand}`);
|