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
- 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:
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-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}`);
@@ -1,5 +1,5 @@
1
1
  var name = "svamp-cli";
2
- var version = "0.2.56";
2
+ var version = "0.2.57";
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.57",
4
4
  "description": "Svamp CLI — AI workspace daemon on Hypha Cloud",
5
5
  "author": "Amun AI AB",
6
6
  "license": "SEE LICENSE IN LICENSE",