studiograph 1.3.48-next.262 → 1.3.48-next.264
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/dist/agent/skills/paged-documents/skill.md +52 -2
- package/dist/core/artifact-bundle.d.ts +69 -0
- package/dist/core/artifact-bundle.js +305 -0
- package/dist/core/artifact-bundle.js.map +1 -0
- package/dist/core/artifact-export.d.ts +83 -0
- package/dist/core/artifact-export.js +1567 -0
- package/dist/core/artifact-export.js.map +1 -0
- package/dist/core/artifact-frame-document.js +137 -27
- package/dist/core/artifact-frame-document.js.map +1 -1
- package/dist/core/artifact-frame-model.d.ts +63 -1
- package/dist/core/artifact-frame-model.js +177 -1
- package/dist/core/artifact-frame-model.js.map +1 -1
- package/dist/core/artifact-frame-selectors.d.ts +42 -0
- package/dist/core/artifact-frame-selectors.js +65 -0
- package/dist/core/artifact-frame-selectors.js.map +1 -0
- package/dist/core/artifact-paged-css.d.ts +64 -0
- package/dist/core/artifact-paged-css.js +253 -0
- package/dist/core/artifact-paged-css.js.map +1 -0
- package/dist/core/field-library.d.ts +62 -0
- package/dist/core/field-library.js +129 -0
- package/dist/core/field-library.js.map +1 -0
- package/dist/mcp/comment-virtual-entity.d.ts +36 -0
- package/dist/mcp/comment-virtual-entity.js +71 -0
- package/dist/mcp/comment-virtual-entity.js.map +1 -0
- package/dist/server/routes/chat-turn-outcome.d.ts +36 -0
- package/dist/server/routes/chat-turn-outcome.js +17 -0
- package/dist/server/routes/chat-turn-outcome.js.map +1 -0
- package/dist/server/routes/field-library-api.d.ts +28 -0
- package/dist/server/routes/field-library-api.js +126 -0
- package/dist/server/routes/field-library-api.js.map +1 -0
- package/dist/server/routes/import-batch.d.ts +24 -0
- package/dist/server/routes/import-batch.js +33 -0
- package/dist/server/routes/import-batch.js.map +1 -0
- package/dist/services/artifact-inspect-metadata.d.ts +21 -0
- package/dist/services/artifact-inspect-metadata.js +66 -0
- package/dist/services/artifact-inspect-metadata.js.map +1 -0
- package/dist/services/asset-upload-service.d.ts +56 -0
- package/dist/services/asset-upload-service.js +200 -0
- package/dist/services/asset-upload-service.js.map +1 -0
- package/dist/services/bookmark-import-service.d.ts +49 -0
- package/dist/services/bookmark-import-service.js +250 -0
- package/dist/services/bookmark-import-service.js.map +1 -0
- package/dist/web/_app/immutable/chunks/{DLFxzom2.js → -MYqXlc3.js} +1 -1
- package/dist/web/_app/immutable/chunks/1_BWKAKA2.js +23 -0
- package/dist/web/_app/immutable/chunks/{D74E7DtA.js → 2XBqwl26.js} +1 -1
- package/dist/web/_app/immutable/chunks/{G9YEWi42.js → 9OJ6vWhR.js} +1 -1
- package/dist/web/_app/immutable/chunks/{Ca57r8F-.js → B--2921V.js} +1 -1
- package/dist/web/_app/immutable/chunks/B2cjR0rG.js +83 -0
- package/dist/web/_app/immutable/chunks/{gwOFYscJ2.js → B8ec-CU82.js} +1 -1
- package/dist/web/_app/immutable/chunks/{DwvPlTQh.js → BGRYqafR.js} +1 -1
- package/dist/web/_app/immutable/chunks/{w53PifJt.js → BNpBXGf3.js} +1 -1
- package/dist/web/_app/immutable/chunks/{Ryiz4ZhP.js → BS6jW_1E.js} +2 -2
- package/dist/web/_app/immutable/chunks/{rSrKfaH92.js → BdG2LckY.js} +1 -1
- package/dist/web/_app/immutable/chunks/BiPmluZm.js +1 -0
- package/dist/web/_app/immutable/chunks/BnYohOts2.js +1 -0
- package/dist/web/_app/immutable/chunks/Bo3sQQpF.js +2 -0
- package/dist/web/_app/immutable/chunks/{B1pVemww.js → BovIfdi8.js} +1 -1
- package/dist/web/_app/immutable/chunks/{tvHn3XYh.js → BqoTHMIY.js} +1 -1
- package/dist/web/_app/immutable/chunks/{CRANgTjw2.js → BuyqlAop2.js} +1 -1
- package/dist/web/_app/immutable/chunks/{CmPtL-Rn.js → BvyVm7-j.js} +1 -1
- package/dist/web/_app/immutable/chunks/BxeOdaUQ.js +1 -0
- package/dist/web/_app/immutable/chunks/{BwZmyfEX.js → BxrzEXE8.js} +1 -1
- package/dist/web/_app/immutable/chunks/{Cf7pPlrJ2.js → Bze2Nm7W2.js} +2 -2
- package/dist/web/_app/immutable/chunks/C6d9nn3k.js +1 -0
- package/dist/web/_app/immutable/chunks/CB-t1Bv-.js +1 -0
- package/dist/web/_app/immutable/chunks/{DxPoYrW02.js → CBMYZbcl2.js} +1 -1
- package/dist/web/_app/immutable/chunks/CKGHeJzq.js +1 -0
- package/dist/web/_app/immutable/chunks/{B7WN6QF2.js → CKk-Yow2.js} +1 -1
- package/dist/web/_app/immutable/chunks/CL_APTyv.js +1 -0
- package/dist/web/_app/immutable/chunks/CXPMb3zd.js +1 -0
- package/dist/web/_app/immutable/chunks/CX_WuP2f.js +1 -0
- package/dist/web/_app/immutable/chunks/{DE5MFphK.js → CbLRjzOH.js} +1 -1
- package/dist/web/_app/immutable/chunks/{gIVpw0C1.js → CcuPL3sb.js} +1 -1
- package/dist/web/_app/immutable/chunks/{Bncd_2iV2.js → Cd5UQ7W92.js} +2 -2
- package/dist/web/_app/immutable/chunks/{DHtwYMGu2.js → Cf0BDsiX.js} +1 -1
- package/dist/web/_app/immutable/chunks/CgCz4Fj6.js +1 -0
- package/dist/web/_app/immutable/chunks/{CB2VdVc2.js → Ci4a4T50.js} +1 -1
- package/dist/web/_app/immutable/chunks/{B4K-yj0D2.js → CjKmFZqV2.js} +1 -1
- package/dist/web/_app/immutable/chunks/{DqGo4lyB2.js → CxETMVlJ.js} +1 -1
- package/dist/web/_app/immutable/chunks/{BBiZOxjN.js → D6Zmq_Vf.js} +1 -1
- package/dist/web/_app/immutable/chunks/DBGaXAP8.js +1 -0
- package/dist/web/_app/immutable/chunks/DDIkuU1k.js +1 -0
- package/dist/web/_app/immutable/chunks/{D_iZ9buk.js → DFctiAap.js} +1 -1
- package/dist/web/_app/immutable/chunks/{D3ZdQV1G2.js → DJZtsbIS2.js} +1 -1
- package/dist/web/_app/immutable/chunks/DO_V9Cgc.js +1 -0
- package/dist/web/_app/immutable/chunks/{Mozc9LAu.js → DPI7dnke.js} +3 -3
- package/dist/web/_app/immutable/chunks/{DOTPES0g.js → DVbddFPK.js} +1 -1
- package/dist/web/_app/immutable/chunks/{Cg5kjIaW.js → DXRSFdpY.js} +1 -1
- package/dist/web/_app/immutable/chunks/DZ2Zr5zb.js +1 -0
- package/dist/web/_app/immutable/chunks/{DtsNBsm82.js → DZ4I5v8B2.js} +1 -1
- package/dist/web/_app/immutable/chunks/DfQ5ljRL.js +2 -0
- package/dist/web/_app/immutable/chunks/{DJ61sY6B.js → DgP0Pxes.js} +1 -1
- package/dist/web/_app/immutable/chunks/{HdbzGSgU.js → DhAwsMYR.js} +1 -1
- package/dist/web/_app/immutable/chunks/DiiXREv7.js +1 -0
- package/dist/web/_app/immutable/chunks/{BeMEksa_2.js → DlCmb-Zk2.js} +1 -1
- package/dist/web/_app/immutable/chunks/{CnpFxw1N2.js → DsYgZ4i8.js} +1 -1
- package/dist/web/_app/immutable/chunks/DtHrXyaA.js +1 -0
- package/dist/web/_app/immutable/chunks/Dvj33Rn2.js +1 -0
- package/dist/web/_app/immutable/chunks/{CbnTIbQI2.js → DymlyZSI2.js} +139 -30
- package/dist/web/_app/immutable/chunks/{BNq2--8a.js → Oglnp7sm2.js} +1 -1
- package/dist/web/_app/immutable/chunks/{DqGcR20a.js → Ppj3RpKV.js} +3 -3
- package/dist/web/_app/immutable/chunks/{DnUROuxo.js → Uhg5bwWh.js} +1 -1
- package/dist/web/_app/immutable/chunks/{3Jf1z4Hy2.js → YeWwp33E2.js} +1 -1
- package/dist/web/_app/immutable/chunks/{HMuf07932.js → po6UjOMy2.js} +1 -1
- package/dist/web/_app/immutable/chunks/{CdvkVymz2.js → qv-0tTgx.js} +1 -1
- package/dist/web/_app/immutable/chunks/{DrD4p8T22.js → rwhdzZc0.js} +1 -1
- package/dist/web/_app/immutable/chunks/{DzBvLWrB2.js → wSqfNZxL2.js} +2 -2
- package/dist/web/_app/immutable/chunks/{CSkL5wO6.js → xYqcgCd5.js} +1 -1
- package/dist/web/_app/immutable/entry/app.Bp1QHFaO.js +2 -0
- package/dist/web/_app/immutable/entry/start.COjp-Cry.js +1 -0
- package/dist/web/_app/immutable/nodes/{0.GCsQhZXx.js → 0.DNjEZSGC.js} +2 -2
- package/dist/web/_app/immutable/nodes/{1.Bai1Q_j6.js → 1.UhJglbTS.js} +1 -1
- package/dist/web/_app/immutable/nodes/{10.Y-zXN2Lv.js → 10._yr1h5zS.js} +1 -1
- package/dist/web/_app/immutable/nodes/{11.BGLbrt6p.js → 11.DchZR5ci.js} +1 -1
- package/dist/web/_app/immutable/nodes/{12.kkg6EDtl.js → 12.BWydr3Cb.js} +1 -1
- package/dist/web/_app/immutable/nodes/{13.DVLmp3Ll.js → 13.BZpTnVPK.js} +1 -1
- package/dist/web/_app/immutable/nodes/{15.B6Aw4lhr.js → 15.BtU9o_gM.js} +1 -1
- package/dist/web/_app/immutable/nodes/{16.BvduImqP.js → 16.BQzW9P96.js} +1 -1
- package/dist/web/_app/immutable/nodes/{18.pwlJhpUE.js → 18.DCEsPk3H.js} +1 -1
- package/dist/web/_app/immutable/nodes/{19.CC1kL3Df.js → 19.wI_omLKL.js} +1 -1
- package/dist/web/_app/immutable/nodes/2.C-HXSFmG.js +124 -0
- package/dist/web/_app/immutable/nodes/{3.DBPrinvQ.js → 3.DJf8jgsj.js} +1 -1
- package/dist/web/_app/immutable/nodes/{4.A-1yULWB.js → 4.DZywRQDT.js} +3 -3
- package/dist/web/_app/immutable/nodes/{5.CN9jkFSb.js → 5.CH7XMZuy.js} +1 -1
- package/dist/web/_app/immutable/nodes/{6.B2TGmdUT.js → 6.D6BAIvrb.js} +1 -1
- package/dist/web/_app/immutable/nodes/{7.DQFIEPX4.js → 7.DIVkY4uO.js} +1 -1
- package/dist/web/_app/immutable/nodes/{8.CsTDHJ_M.js → 8.CwJ8O0_8.js} +1 -1
- package/dist/web/_app/immutable/nodes/{9.B9zlBMg4.js → 9.Ccuyl8Fo.js} +1 -1
- package/dist/web/_app/version.json +1 -1
- package/dist/web/index.html +18 -18
- package/package.json +1 -1
- package/dist/web/_app/immutable/chunks/2jM_FrdF.js +0 -1
- package/dist/web/_app/immutable/chunks/3e54b3S0.js +0 -1
- package/dist/web/_app/immutable/chunks/7pkBLE0o.js +0 -23
- package/dist/web/_app/immutable/chunks/AFZSy-Vk.js +0 -2
- package/dist/web/_app/immutable/chunks/B7P31uII.js +0 -1
- package/dist/web/_app/immutable/chunks/B7QhSEou.js +0 -1
- package/dist/web/_app/immutable/chunks/BH8Lm2ff.js +0 -1
- package/dist/web/_app/immutable/chunks/BLw5bIbe.js +0 -1
- package/dist/web/_app/immutable/chunks/BaEbafZv.js +0 -1
- package/dist/web/_app/immutable/chunks/BksI9pEP.js +0 -2
- package/dist/web/_app/immutable/chunks/Bo6vsMxZ.js +0 -1
- package/dist/web/_app/immutable/chunks/CGG26Xmx.js +0 -1
- package/dist/web/_app/immutable/chunks/C_vyTCDY.js +0 -1
- package/dist/web/_app/immutable/chunks/D2G8GgRX.js +0 -1
- package/dist/web/_app/immutable/chunks/D8nBN3-t.js +0 -1
- package/dist/web/_app/immutable/chunks/DGayKSDC.js +0 -1
- package/dist/web/_app/immutable/chunks/DIro3eQz.js +0 -1
- package/dist/web/_app/immutable/chunks/DWbRq2tL.js +0 -1
- package/dist/web/_app/immutable/chunks/Dm-W1U3E.js +0 -1
- package/dist/web/_app/immutable/chunks/DxQ5eC8d.js +0 -1
- package/dist/web/_app/immutable/chunks/nacCpTNj.js +0 -83
- package/dist/web/_app/immutable/entry/app.D9mnvkg5.js +0 -2
- package/dist/web/_app/immutable/entry/start.B1L019Jv.js +0 -1
- package/dist/web/_app/immutable/nodes/2.CvV_5gfw.js +0 -124
- /package/dist/web/_app/immutable/chunks/{B9KfEsQw.js → B9KfEsQw2.js} +0 -0
- /package/dist/web/_app/immutable/chunks/{BO6-nRV92.js → BO6-nRV9.js} +0 -0
- /package/dist/web/_app/immutable/chunks/{CcWaWbrI.js → CcWaWbrI2.js} +0 -0
- /package/dist/web/_app/immutable/chunks/{CsIWxmio.js → CsIWxmio2.js} +0 -0
- /package/dist/web/_app/immutable/chunks/{DQMWa2t72.js → DQMWa2t7.js} +0 -0
- /package/dist/web/_app/immutable/chunks/{MAYbL-xn.js → MAYbL-xn2.js} +0 -0
- /package/dist/web/_app/immutable/chunks/{MtN4vJa0.js → MtN4vJa02.js} +0 -0
|
@@ -27,8 +27,9 @@ ONE <pages> frame ──native columns──▶ page 1 │ page 2 │ page 3
|
|
|
27
27
|
|
|
28
28
|
- **Page SIZE is the frame `geometry` — ANY width × height, portrait, landscape, or arbitrary.** Common print presets (portrait; swap width↔height for landscape): US-Letter `816×1056`, Legal `816×1344`, Tabloid `1056×1632`, A4 `794×1123`, A3 `1123×1587`, A5 `559×794`. A custom size is equally valid (a landscape report `1056×816`, a square `1000×1000`). Pick the geometry the document calls for. Do NOT write `@page { size }` — it is ignored; geometry is the size.
|
|
29
29
|
- **`pageMargins`** (a `pages` frame field, px per side; absent sides default to top 96 / sides 72 / bottom 84) sets the page margins. The content area is `width − left − right` by `height − top − bottom`. Scale margins to the page size, and make the top/bottom big enough for the furniture (a tall letterhead needs a taller top margin — furniture is out-of-flow and can't reserve its own space).
|
|
30
|
-
- **
|
|
30
|
+
- **Page numbers** default to "Page N of M" bottom-right on every page, **in the document's own body type**; the **`pageNumbers`** frame field controls them — hide them (`{ "show": false }`), restyle the text (`"format": "{n}"` for a bare numeral; `{n}` = page, `{m}` = last page), move to any corner/edge (`"position": "top-center"`), skip the cover (`"showOnFirst": false`) or a trailing page such as a contact/colophon page (`"showOnLast": false`), pin near the page edge (`"offset"`), or override the numeral type (`"fontFamily"` / `"fontWeight"` / `"fontSize"` px / `"color"`). **The numeral inherits the document body's font / size / weight / color by default** — set those fields only to make it differ (e.g. a lighter, smaller running number); for a numeral that simply matches the body, set nothing. A `furniture.footer` clears the *default* bottom-right counter automatically; if you MOVE the number (e.g. `bottom-left`, `top-center`), make sure it doesn't collide with furniture in that same corner — clearance is only automatic for the default position.
|
|
31
31
|
- **ONE uniform page geometry per document.** Every page shares the same `geometry` + `pageMargins`. Per-section page margins (a different top margin for an appendix vs the cover) are NOT expressible under native columns — pick one geometry that works for the whole document. This is the one real constraint vs the old `@page`-per-section model.
|
|
32
|
+
- **The page-box model (know this — it explains margin behavior).** `pageMargins.top` reserves a band the **body cannot write into** (body starts at the content edge; content pushed above it is clipped, not drawn into the margin). Furniture by default anchors at that content edge, so with a deep top margin a header sits LOW (just above the body). To put a masthead HIGH while keeping a deep body margin, anchor the furniture to the page edge (`furniture.header.anchor: "page"`, below).
|
|
32
33
|
- **Fixed height is required to paginate.** A `pages` frame with a fixed height (e.g. `1056`) flows overflow onto more pages. `height: "auto"` does NOT paginate — it renders as one tall continuous page. Use `auto` only for a deliberately single, non-paginated scroll.
|
|
33
34
|
- **Cross-browser.** On-screen page breaks are computed by the *viewing* browser's native fragmentation, so a Safari/Firefox user may see breaks fall a line differently than Chrome. The exported PDF (always Chromium) is the **canonical** pagination. Content is correct everywhere; don't hand-tune to one browser's break positions.
|
|
34
35
|
|
|
@@ -48,8 +49,57 @@ ONE <pages> frame ──native columns──▶ page 1 │ page 2 │ page 3
|
|
|
48
49
|
|
|
49
50
|
- Put **real designed HTML** in furniture (a logo lockup, an address block, a rule) — aim for a designed letterhead, not a plain text line. Lay multi-part headers out with flex or absolute positioning inside the furniture HTML; it is normal in-margin HTML (no Paged.js clone caveats).
|
|
50
51
|
- Use **`first`** to vary page 1 (e.g. a fuller masthead on page 1, a slim running header on the rest) and **`last`** for a closing line.
|
|
52
|
+
- **`anchor` + `offset` per region** place it in the margin band: `"anchor": "content"` (default) hugs the body edge (a running header just above the text); `"anchor": "page"` pins it to the page's outer edge, `"offset"` px in. Use `header.anchor: "page"` for a **letterhead masthead that rides high** even with a deep `pageMargins.top` — the body keeps the deep margin while the masthead sits at the top edge. Put a final-page contact block in `header.last` with `anchor: "page"` to ride high on the last page only.
|
|
53
|
+
- **Per-page variation is first-class:** `first`/`middle`/`last` slots for different furniture per page, a `first`-only header for a masthead on page 1 only, and `pageNumbers.showOnFirst: false` / `showOnLast: false` to drop the number on a cover or a trailing page.
|
|
51
54
|
- **Full-bleed edge-to-edge bands are not supported in v1** — furniture insets to the content column. Keep letterhead within the margins.
|
|
52
|
-
|
|
55
|
+
|
|
56
|
+
### Letterhead the clean way (masthead high, body low, bare numeral up top)
|
|
57
|
+
|
|
58
|
+
A classic letter: deep top margin for the body, masthead riding high on page 1, a bare numeral top-center on pages 2+, contact block high on the last page.
|
|
59
|
+
|
|
60
|
+
```jsonc
|
|
61
|
+
"pageMargins": { "top": 192, "right": 96, "bottom": 96, "left": 96 }, // ~2in body margin
|
|
62
|
+
"furniture": {
|
|
63
|
+
"header": {
|
|
64
|
+
"first": "<div class=\"mast\">…masthead…</div>", // page 1 only
|
|
65
|
+
"last": "<div class=\"contact\">…contact block…</div>", // last page only (top-left)
|
|
66
|
+
"anchor": "page", "offset": 28 // both ride high at the top edge
|
|
67
|
+
}
|
|
68
|
+
},
|
|
69
|
+
"pageNumbers": { "position": "top-center", "format": "{n}", "showOnFirst": false, "showOnLast": false, "offset": 28 }
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
The body sits at the deep 2in margin on every page (uniform geometry, unchanged); the masthead/contact ride at the page edge via `anchor: "page"`; the numeral is a bare `{n}` top-center in the body type, skipped on both the cover and the contact-block last page (`showOnFirst`/`showOnLast: false`).
|
|
73
|
+
|
|
74
|
+
### Running headers that change by section (e.g. "Exhibit A" / "Exhibit B")
|
|
75
|
+
|
|
76
|
+
When the running header (or footer) text must change partway through — a contract whose interior is "Agreement Title" but whose exhibits read "Exhibit A", "Exhibit B" — use **per-section variants**. The header content stays in `furniture` (alongside `first`/`middle`/`last`); the BODY marks where each section begins.
|
|
77
|
+
|
|
78
|
+
- Add a **`sections`** map to the region: `{ "<name>": "<header HTML>" }`. Give each section the same markup/classes as `middle` so it renders consistently.
|
|
79
|
+
- In the body, mark the **start** of each section with `data-sg-section="<name>"` — put it on the element that begins the section (typically the one carrying `break-before: column`, so the section starts on a fresh page). From the page that element lands on, the region renders `sections[name]` instead of `middle`, until the next marker.
|
|
80
|
+
- An **empty** marker — `data-sg-section=""` — *clears* the region (no header/footer) from that page onward. Use it for a back cover with no running header.
|
|
81
|
+
- `first` (page 1) and `last` (final page) still win on their own pages — so to blank the final page with a clear marker, leave `last` unset. A marker name with no matching `sections` entry falls back to `middle` (a typo never blanks the header).
|
|
82
|
+
|
|
83
|
+
```jsonc
|
|
84
|
+
"furniture": {
|
|
85
|
+
"header": {
|
|
86
|
+
"first": "<div class=\"mast\">…masthead…</div>", // page 1
|
|
87
|
+
"middle": "<div class=\"rh\">Proprietary Information and Inventions Agreement</div>",
|
|
88
|
+
"sections": {
|
|
89
|
+
"exhibit-a": "<div class=\"rh\">Exhibit A</div>",
|
|
90
|
+
"exhibit-b": "<div class=\"rh\">Exhibit B</div>"
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
```
|
|
95
|
+
```html
|
|
96
|
+
<!-- body: mark each section's first element -->
|
|
97
|
+
<h1 style="break-before: column" data-sg-section="exhibit-a">Exhibit A</h1> …
|
|
98
|
+
<h1 style="break-before: column" data-sg-section="exhibit-b">Exhibit B</h1> …
|
|
99
|
+
<section style="break-before: column" data-sg-section="">Back cover…</section> <!-- no header from here -->
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
The interior pages read "Proprietary…Agreement"; the exhibit pages read "Exhibit A" / "Exhibit B"; the back cover has no running header. This is the **only** way to vary running-header text by page range — the body cannot write into the margin band, and a single `middle` covers every interior page.
|
|
53
103
|
|
|
54
104
|
## Break control (the craft that separates clean from sloppy)
|
|
55
105
|
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared contract for agent-produced canvas artifacts.
|
|
3
|
+
*
|
|
4
|
+
* V1 is deliberately text-only: HTML, CSS, JS, SVG, JSON, and plain text files.
|
|
5
|
+
* Binary assets and network-dependent files are follow-up work, because this
|
|
6
|
+
* bundle is persisted in chat message metadata and rendered in a sandboxed
|
|
7
|
+
* iframe.
|
|
8
|
+
*/
|
|
9
|
+
export declare const ARTIFACT_BUNDLE_SCHEMA_VERSION = 1;
|
|
10
|
+
export declare const ARTIFACT_BUNDLE_MAX_BYTES: number;
|
|
11
|
+
export declare const ARTIFACT_KINDS: readonly ["html", "document", "slides", "social", "app", "custom"];
|
|
12
|
+
export type ArtifactKind = typeof ARTIFACT_KINDS[number];
|
|
13
|
+
export declare const ARTIFACT_VIEWPORT_MODES: readonly ["fixed", "responsive", "paged"];
|
|
14
|
+
export type ArtifactViewportMode = typeof ARTIFACT_VIEWPORT_MODES[number];
|
|
15
|
+
export declare const ARTIFACT_FULLSCREEN_FITS: readonly ["contain", "width", "none"];
|
|
16
|
+
export type ArtifactFullscreenFit = typeof ARTIFACT_FULLSCREEN_FITS[number];
|
|
17
|
+
export declare const ARTIFACT_DISPLAY_BACKGROUNDS: readonly ["neutral", "transparent"];
|
|
18
|
+
export type ArtifactDisplayBackground = typeof ARTIFACT_DISPLAY_BACKGROUNDS[number];
|
|
19
|
+
export declare const ARTIFACT_LIBRARY_KEYS: readonly ["three", "d3", "motion"];
|
|
20
|
+
export type ArtifactLibraryKey = typeof ARTIFACT_LIBRARY_KEYS[number];
|
|
21
|
+
export interface ArtifactDisplayViewport {
|
|
22
|
+
width: number;
|
|
23
|
+
height: number;
|
|
24
|
+
}
|
|
25
|
+
export interface ArtifactDisplayStepperControl {
|
|
26
|
+
selector?: string;
|
|
27
|
+
label?: string;
|
|
28
|
+
}
|
|
29
|
+
export interface ArtifactDisplayControls {
|
|
30
|
+
stepper?: ArtifactDisplayStepperControl;
|
|
31
|
+
reset?: boolean;
|
|
32
|
+
}
|
|
33
|
+
export interface ArtifactViewport {
|
|
34
|
+
width: number;
|
|
35
|
+
height: number;
|
|
36
|
+
mode: ArtifactViewportMode;
|
|
37
|
+
}
|
|
38
|
+
export interface ArtifactDisplay {
|
|
39
|
+
fullscreenFit?: ArtifactFullscreenFit;
|
|
40
|
+
background?: ArtifactDisplayBackground;
|
|
41
|
+
fullscreenViewport?: ArtifactDisplayViewport;
|
|
42
|
+
controls?: ArtifactDisplayControls;
|
|
43
|
+
}
|
|
44
|
+
export interface ArtifactSource {
|
|
45
|
+
repo?: string;
|
|
46
|
+
entityType?: string;
|
|
47
|
+
entityId?: string;
|
|
48
|
+
skillId?: string;
|
|
49
|
+
}
|
|
50
|
+
export interface ArtifactBundle {
|
|
51
|
+
schemaVersion: typeof ARTIFACT_BUNDLE_SCHEMA_VERSION;
|
|
52
|
+
artifactId: string;
|
|
53
|
+
title: string;
|
|
54
|
+
kind: ArtifactKind;
|
|
55
|
+
viewport: ArtifactViewport;
|
|
56
|
+
display?: ArtifactDisplay;
|
|
57
|
+
libraries?: ArtifactLibraryKey[];
|
|
58
|
+
files: Record<string, string>;
|
|
59
|
+
entrypoint: string;
|
|
60
|
+
source?: ArtifactSource;
|
|
61
|
+
}
|
|
62
|
+
export interface ArtifactValidationResult {
|
|
63
|
+
ok: boolean;
|
|
64
|
+
bundle?: ArtifactBundle;
|
|
65
|
+
errors: string[];
|
|
66
|
+
byteSize: number;
|
|
67
|
+
}
|
|
68
|
+
export declare function validateArtifactBundle(input: unknown): ArtifactValidationResult;
|
|
69
|
+
export declare function assertArtifactBundle(input: unknown): ArtifactBundle;
|
|
@@ -0,0 +1,305 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared contract for agent-produced canvas artifacts.
|
|
3
|
+
*
|
|
4
|
+
* V1 is deliberately text-only: HTML, CSS, JS, SVG, JSON, and plain text files.
|
|
5
|
+
* Binary assets and network-dependent files are follow-up work, because this
|
|
6
|
+
* bundle is persisted in chat message metadata and rendered in a sandboxed
|
|
7
|
+
* iframe.
|
|
8
|
+
*/
|
|
9
|
+
export const ARTIFACT_BUNDLE_SCHEMA_VERSION = 1;
|
|
10
|
+
export const ARTIFACT_BUNDLE_MAX_BYTES = 512 * 1024;
|
|
11
|
+
export const ARTIFACT_KINDS = ['html', 'document', 'slides', 'social', 'app', 'custom'];
|
|
12
|
+
export const ARTIFACT_VIEWPORT_MODES = ['fixed', 'responsive', 'paged'];
|
|
13
|
+
export const ARTIFACT_FULLSCREEN_FITS = ['contain', 'width', 'none'];
|
|
14
|
+
export const ARTIFACT_DISPLAY_BACKGROUNDS = ['neutral', 'transparent'];
|
|
15
|
+
export const ARTIFACT_LIBRARY_KEYS = ['three', 'd3', 'motion'];
|
|
16
|
+
const TEXT_EXTENSIONS = new Set([
|
|
17
|
+
'.html', '.htm', '.css', '.js', '.mjs', '.svg', '.json', '.txt', '.md',
|
|
18
|
+
]);
|
|
19
|
+
const ID_RE = /^[a-zA-Z0-9][a-zA-Z0-9._:-]{0,127}$/;
|
|
20
|
+
const PATH_RE = /^[a-zA-Z0-9][a-zA-Z0-9._/-]{0,255}$/;
|
|
21
|
+
function isRecord(value) {
|
|
22
|
+
return !!value && typeof value === 'object' && !Array.isArray(value);
|
|
23
|
+
}
|
|
24
|
+
function byteLength(value) {
|
|
25
|
+
return new TextEncoder().encode(JSON.stringify(value)).length;
|
|
26
|
+
}
|
|
27
|
+
function extensionOf(path) {
|
|
28
|
+
const dot = path.lastIndexOf('.');
|
|
29
|
+
return dot === -1 ? '' : path.slice(dot).toLowerCase();
|
|
30
|
+
}
|
|
31
|
+
function isSafePath(path) {
|
|
32
|
+
if (!PATH_RE.test(path))
|
|
33
|
+
return false;
|
|
34
|
+
if (path.includes('..'))
|
|
35
|
+
return false;
|
|
36
|
+
if (path.includes('//'))
|
|
37
|
+
return false;
|
|
38
|
+
if (/^[a-z][a-z0-9+.-]*:/i.test(path))
|
|
39
|
+
return false;
|
|
40
|
+
return true;
|
|
41
|
+
}
|
|
42
|
+
function normalizeString(value) {
|
|
43
|
+
return typeof value === 'string' && value.trim() ? value.trim() : null;
|
|
44
|
+
}
|
|
45
|
+
function inferArtifactLibraries(files) {
|
|
46
|
+
const text = Object.entries(files)
|
|
47
|
+
.filter(([path]) => /\.(html?|m?js|css|svg)$/i.test(path))
|
|
48
|
+
.map(([, content]) => content)
|
|
49
|
+
.join('\n');
|
|
50
|
+
const inferred = [];
|
|
51
|
+
if (/\b(?:window\.)?THREE\b/.test(text) || /\bfrom\s+['"]three(?:\/[^'"]*)?['"]/.test(text)) {
|
|
52
|
+
inferred.push('three');
|
|
53
|
+
}
|
|
54
|
+
if (/\b(?:window\.)?d3\b/.test(text) || /\bfrom\s+['"]d3(?:\/[^'"]*)?['"]/.test(text)) {
|
|
55
|
+
inferred.push('d3');
|
|
56
|
+
}
|
|
57
|
+
if (/\b(?:window\.)?Motion\b/.test(text)
|
|
58
|
+
|| /\bmotion\.(?:animate|spring|inView|scroll)\b/.test(text)
|
|
59
|
+
|| /\bfrom\s+['"]motion(?:\/[^'"]*)?['"]/.test(text)) {
|
|
60
|
+
inferred.push('motion');
|
|
61
|
+
}
|
|
62
|
+
return inferred;
|
|
63
|
+
}
|
|
64
|
+
export function validateArtifactBundle(input) {
|
|
65
|
+
const errors = [];
|
|
66
|
+
const byteSize = byteLength(input);
|
|
67
|
+
if (byteSize > ARTIFACT_BUNDLE_MAX_BYTES) {
|
|
68
|
+
errors.push(`Artifact bundle exceeds ${ARTIFACT_BUNDLE_MAX_BYTES} bytes`);
|
|
69
|
+
}
|
|
70
|
+
if (!isRecord(input)) {
|
|
71
|
+
return { ok: false, errors: ['Artifact bundle must be an object', ...errors], byteSize };
|
|
72
|
+
}
|
|
73
|
+
if (input.schemaVersion !== ARTIFACT_BUNDLE_SCHEMA_VERSION) {
|
|
74
|
+
errors.push(`schemaVersion must be ${ARTIFACT_BUNDLE_SCHEMA_VERSION}`);
|
|
75
|
+
}
|
|
76
|
+
const artifactId = normalizeString(input.artifactId);
|
|
77
|
+
if (!artifactId || !ID_RE.test(artifactId)) {
|
|
78
|
+
errors.push('artifactId must be a stable alphanumeric id');
|
|
79
|
+
}
|
|
80
|
+
const title = normalizeString(input.title);
|
|
81
|
+
if (!title)
|
|
82
|
+
errors.push('title is required');
|
|
83
|
+
const kind = normalizeString(input.kind);
|
|
84
|
+
if (!kind || !ARTIFACT_KINDS.includes(kind)) {
|
|
85
|
+
errors.push(`kind must be one of: ${ARTIFACT_KINDS.join(', ')}`);
|
|
86
|
+
}
|
|
87
|
+
const viewport = input.viewport;
|
|
88
|
+
let normalizedViewport = null;
|
|
89
|
+
if (!isRecord(viewport)) {
|
|
90
|
+
errors.push('viewport is required');
|
|
91
|
+
}
|
|
92
|
+
else {
|
|
93
|
+
const width = viewport.width;
|
|
94
|
+
const height = viewport.height;
|
|
95
|
+
const mode = viewport.mode;
|
|
96
|
+
if (typeof width !== 'number' || !Number.isFinite(width) || width < 120 || width > 10000) {
|
|
97
|
+
errors.push('viewport.width must be between 120 and 10000');
|
|
98
|
+
}
|
|
99
|
+
if (typeof height !== 'number' || !Number.isFinite(height) || height < 120 || height > 10000) {
|
|
100
|
+
errors.push('viewport.height must be between 120 and 10000');
|
|
101
|
+
}
|
|
102
|
+
if (typeof mode !== 'string' || !ARTIFACT_VIEWPORT_MODES.includes(mode)) {
|
|
103
|
+
errors.push(`viewport.mode must be one of: ${ARTIFACT_VIEWPORT_MODES.join(', ')}`);
|
|
104
|
+
}
|
|
105
|
+
if (typeof width === 'number' && typeof height === 'number' && typeof mode === 'string') {
|
|
106
|
+
normalizedViewport = {
|
|
107
|
+
width: Math.round(width),
|
|
108
|
+
height: Math.round(height),
|
|
109
|
+
mode: mode,
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
const entrypoint = normalizeString(input.entrypoint);
|
|
114
|
+
if (!entrypoint || !isSafePath(entrypoint)) {
|
|
115
|
+
errors.push('entrypoint must be a safe relative file path');
|
|
116
|
+
}
|
|
117
|
+
const files = input.files;
|
|
118
|
+
const normalizedFiles = {};
|
|
119
|
+
if (!isRecord(files)) {
|
|
120
|
+
errors.push('files must be an object of text file paths to string contents');
|
|
121
|
+
}
|
|
122
|
+
else {
|
|
123
|
+
const entries = Object.entries(files);
|
|
124
|
+
if (entries.length === 0)
|
|
125
|
+
errors.push('files must contain at least one file');
|
|
126
|
+
for (const [path, content] of entries) {
|
|
127
|
+
if (!isSafePath(path)) {
|
|
128
|
+
errors.push(`file path "${path}" must be a safe relative path`);
|
|
129
|
+
continue;
|
|
130
|
+
}
|
|
131
|
+
const ext = extensionOf(path);
|
|
132
|
+
if (!TEXT_EXTENSIONS.has(ext)) {
|
|
133
|
+
errors.push(`file "${path}" must be a supported text file`);
|
|
134
|
+
}
|
|
135
|
+
if (typeof content !== 'string') {
|
|
136
|
+
errors.push(`file "${path}" must be a string`);
|
|
137
|
+
continue;
|
|
138
|
+
}
|
|
139
|
+
normalizedFiles[path] = content;
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
if (entrypoint && !Object.prototype.hasOwnProperty.call(normalizedFiles, entrypoint)) {
|
|
143
|
+
errors.push('entrypoint must exist in files');
|
|
144
|
+
}
|
|
145
|
+
const declaredLibraries = new Set();
|
|
146
|
+
if (input.libraries !== undefined) {
|
|
147
|
+
if (!Array.isArray(input.libraries)) {
|
|
148
|
+
errors.push('libraries must be an array when provided');
|
|
149
|
+
}
|
|
150
|
+
else {
|
|
151
|
+
for (const library of input.libraries) {
|
|
152
|
+
if (typeof library !== 'string' || !ARTIFACT_LIBRARY_KEYS.includes(library)) {
|
|
153
|
+
errors.push(`libraries must contain only: ${ARTIFACT_LIBRARY_KEYS.join(', ')}`);
|
|
154
|
+
continue;
|
|
155
|
+
}
|
|
156
|
+
declaredLibraries.add(library);
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
let display;
|
|
161
|
+
if (input.display !== undefined) {
|
|
162
|
+
if (!isRecord(input.display)) {
|
|
163
|
+
errors.push('display must be an object when provided');
|
|
164
|
+
}
|
|
165
|
+
else {
|
|
166
|
+
display = {};
|
|
167
|
+
if (input.display.fullscreenFit !== undefined) {
|
|
168
|
+
if (typeof input.display.fullscreenFit !== 'string'
|
|
169
|
+
|| !ARTIFACT_FULLSCREEN_FITS.includes(input.display.fullscreenFit)) {
|
|
170
|
+
errors.push(`display.fullscreenFit must be one of: ${ARTIFACT_FULLSCREEN_FITS.join(', ')}`);
|
|
171
|
+
}
|
|
172
|
+
else {
|
|
173
|
+
display.fullscreenFit = input.display.fullscreenFit;
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
if (input.display.background !== undefined) {
|
|
177
|
+
if (typeof input.display.background !== 'string'
|
|
178
|
+
|| !ARTIFACT_DISPLAY_BACKGROUNDS.includes(input.display.background)) {
|
|
179
|
+
errors.push(`display.background must be one of: ${ARTIFACT_DISPLAY_BACKGROUNDS.join(', ')}`);
|
|
180
|
+
}
|
|
181
|
+
else {
|
|
182
|
+
display.background = input.display.background;
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
if (input.display.fullscreenViewport !== undefined) {
|
|
186
|
+
if (!isRecord(input.display.fullscreenViewport)) {
|
|
187
|
+
errors.push('display.fullscreenViewport must be an object when provided');
|
|
188
|
+
}
|
|
189
|
+
else {
|
|
190
|
+
const width = input.display.fullscreenViewport.width;
|
|
191
|
+
const height = input.display.fullscreenViewport.height;
|
|
192
|
+
if (typeof width !== 'number' || !Number.isFinite(width) || width < 120 || width > 10000) {
|
|
193
|
+
errors.push('display.fullscreenViewport.width must be between 120 and 10000');
|
|
194
|
+
}
|
|
195
|
+
if (typeof height !== 'number' || !Number.isFinite(height) || height < 120 || height > 10000) {
|
|
196
|
+
errors.push('display.fullscreenViewport.height must be between 120 and 10000');
|
|
197
|
+
}
|
|
198
|
+
if (typeof width === 'number' && typeof height === 'number') {
|
|
199
|
+
display.fullscreenViewport = {
|
|
200
|
+
width: Math.round(width),
|
|
201
|
+
height: Math.round(height),
|
|
202
|
+
};
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
if (input.display.controls !== undefined) {
|
|
207
|
+
if (!isRecord(input.display.controls)) {
|
|
208
|
+
errors.push('display.controls must be an object when provided');
|
|
209
|
+
}
|
|
210
|
+
else {
|
|
211
|
+
const controls = {};
|
|
212
|
+
let hasControls = false;
|
|
213
|
+
if (input.display.controls.stepper !== undefined) {
|
|
214
|
+
if (!isRecord(input.display.controls.stepper)) {
|
|
215
|
+
errors.push('display.controls.stepper must be an object when provided');
|
|
216
|
+
}
|
|
217
|
+
else {
|
|
218
|
+
const stepper = {};
|
|
219
|
+
if (input.display.controls.stepper.selector !== undefined) {
|
|
220
|
+
const selector = normalizeString(input.display.controls.stepper.selector);
|
|
221
|
+
if (!selector || selector.length > 180) {
|
|
222
|
+
errors.push('display.controls.stepper.selector must be a non-empty string up to 180 characters');
|
|
223
|
+
}
|
|
224
|
+
else {
|
|
225
|
+
stepper.selector = selector;
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
if (input.display.controls.stepper.label !== undefined) {
|
|
229
|
+
const label = normalizeString(input.display.controls.stepper.label);
|
|
230
|
+
if (!label || label.length > 40) {
|
|
231
|
+
errors.push('display.controls.stepper.label must be a non-empty string up to 40 characters');
|
|
232
|
+
}
|
|
233
|
+
else {
|
|
234
|
+
stepper.label = label;
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
controls.stepper = stepper;
|
|
238
|
+
hasControls = true;
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
if (input.display.controls.reset !== undefined) {
|
|
242
|
+
if (typeof input.display.controls.reset !== 'boolean') {
|
|
243
|
+
errors.push('display.controls.reset must be a boolean when provided');
|
|
244
|
+
}
|
|
245
|
+
else {
|
|
246
|
+
controls.reset = input.display.controls.reset;
|
|
247
|
+
hasControls = true;
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
if (hasControls)
|
|
251
|
+
display.controls = controls;
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
if (Object.keys(display).length === 0)
|
|
255
|
+
display = undefined;
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
let source;
|
|
259
|
+
if (input.source !== undefined) {
|
|
260
|
+
if (!isRecord(input.source)) {
|
|
261
|
+
errors.push('source must be an object when provided');
|
|
262
|
+
}
|
|
263
|
+
else {
|
|
264
|
+
source = {};
|
|
265
|
+
for (const key of ['repo', 'entityType', 'entityId', 'skillId']) {
|
|
266
|
+
if (input.source[key] !== undefined) {
|
|
267
|
+
const value = normalizeString(input.source[key]);
|
|
268
|
+
if (!value)
|
|
269
|
+
errors.push(`source.${key} must be a non-empty string`);
|
|
270
|
+
else
|
|
271
|
+
source[key] = value;
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
if (errors.length > 0 || !artifactId || !title || !kind || !entrypoint || !normalizedViewport) {
|
|
277
|
+
return { ok: false, errors, byteSize };
|
|
278
|
+
}
|
|
279
|
+
const libraries = Array.from(new Set([...declaredLibraries, ...inferArtifactLibraries(normalizedFiles)]));
|
|
280
|
+
return {
|
|
281
|
+
ok: true,
|
|
282
|
+
errors: [],
|
|
283
|
+
byteSize,
|
|
284
|
+
bundle: {
|
|
285
|
+
schemaVersion: ARTIFACT_BUNDLE_SCHEMA_VERSION,
|
|
286
|
+
artifactId,
|
|
287
|
+
title,
|
|
288
|
+
kind: kind,
|
|
289
|
+
viewport: normalizedViewport,
|
|
290
|
+
...(display ? { display } : {}),
|
|
291
|
+
...(libraries.length > 0 ? { libraries } : {}),
|
|
292
|
+
files: normalizedFiles,
|
|
293
|
+
entrypoint,
|
|
294
|
+
...(source ? { source } : {}),
|
|
295
|
+
},
|
|
296
|
+
};
|
|
297
|
+
}
|
|
298
|
+
export function assertArtifactBundle(input) {
|
|
299
|
+
const result = validateArtifactBundle(input);
|
|
300
|
+
if (!result.ok || !result.bundle) {
|
|
301
|
+
throw new Error(result.errors.join('; ') || 'Invalid artifact bundle');
|
|
302
|
+
}
|
|
303
|
+
return result.bundle;
|
|
304
|
+
}
|
|
305
|
+
//# sourceMappingURL=artifact-bundle.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"artifact-bundle.js","sourceRoot":"","sources":["../../src/core/artifact-bundle.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import type { ArtifactBundle, ArtifactLibraryKey } from './artifact-bundle.js';
|
|
2
|
+
import { type AssetResolution } from './artifact-asset-resolution.js';
|
|
3
|
+
/** The neutral gray the hosted app presents artifacts on. The web stage rule
|
|
4
|
+
* (.artifact-stage[data-view-mode='fullscreen'] in ArtifactEntityView.svelte)
|
|
5
|
+
* must use the same value — a source-sync test pins it. */
|
|
6
|
+
export declare const ARTIFACT_PRESENT_BACKDROP = "#4a4a4a";
|
|
7
|
+
/** Shared dead-band for content-size churn, in px. Single-sourced HERE (core)
|
|
8
|
+
* so the iframe runtime — which interpolates it into its injected reporter
|
|
9
|
+
* script below — and the web host's per-slot recorder (which re-exports this
|
|
10
|
+
* through artifact-view-state.ts) can never drift apart: a tuning change one
|
|
11
|
+
* side silently filtered out would ship as a no-op. */
|
|
12
|
+
export declare const CONTENT_SIZE_DEAD_BAND_PX = 8;
|
|
13
|
+
export type ArtifactExportExtension = 'html' | 'png' | 'pdf';
|
|
14
|
+
/** Where this render runs (eng review D2 — host mode is EXPLICIT):
|
|
15
|
+
* - `iframe`: a live host owns the chrome (selection outlines, zoom/pan,
|
|
16
|
+
* overview scaling, presentation controls). The runtime is interactive and
|
|
17
|
+
* emits its state to the parent via postMessage. The in-app canvas + the
|
|
18
|
+
* public share/present page.
|
|
19
|
+
* - `none`: no host. The downloaded standalone HTML and the headless
|
|
20
|
+
* Playwright render. The runtime owns minimal self-contained chrome (step
|
|
21
|
+
* frames + self-fit), capability-frozen at today's export parity — a fence,
|
|
22
|
+
* not a growth surface. */
|
|
23
|
+
export type ArtifactRenderHost = 'iframe' | 'none';
|
|
24
|
+
export type ArtifactRenderContextName = 'editor' | 'fullscreen' | 'export';
|
|
25
|
+
export type ArtifactCanvasTool = 'pointer' | 'hand';
|
|
26
|
+
export type ArtifactLibrarySourceKey = ArtifactLibraryKey | 'threeCore';
|
|
27
|
+
export type ArtifactLibrarySources = Partial<Record<ArtifactLibrarySourceKey, string>>;
|
|
28
|
+
export declare function artifactExportFilename(bundle: Pick<ArtifactBundle, 'artifactId' | 'title'>, extension?: ArtifactExportExtension): string;
|
|
29
|
+
/** How workspace-asset refs resolve in THIS render — drives both the URL
|
|
30
|
+
* rewrite and the document CSP from one value (see
|
|
31
|
+
* artifact-asset-resolution.ts). */
|
|
32
|
+
export interface ArtifactRenderContext {
|
|
33
|
+
host: ArtifactRenderHost;
|
|
34
|
+
/** The render surface. Drives the `data-artifact-context` attribute + runtime
|
|
35
|
+
* gating. For host `iframe` it defaults to `editor`. For host `none` it may
|
|
36
|
+
* be left undefined — a plain self-contained export with no context chrome
|
|
37
|
+
* (the bare `buildArtifactHtmlExport(bundle)` case). */
|
|
38
|
+
context?: ArtifactRenderContextName;
|
|
39
|
+
tool?: ArtifactCanvasTool;
|
|
40
|
+
assets?: AssetResolution;
|
|
41
|
+
librarySources?: ArtifactLibrarySources;
|
|
42
|
+
/** Base URL for the headless (Playwright) render path so root-relative
|
|
43
|
+
* `/api/assets/...` URLs resolve in a `setContent` document. The CSP's
|
|
44
|
+
* `base-uri` is widened to exactly this origin. Never set on the standalone
|
|
45
|
+
* HTML export — a downloaded file must not phone home. (host: 'none' only) */
|
|
46
|
+
baseHref?: string;
|
|
47
|
+
/** Emit the render-host styles (export-frame flattening, print pagination,
|
|
48
|
+
* in-document present backdrop). The Playwright + standalone-export paths
|
|
49
|
+
* set it; the in-app iframe never does. (host: 'none' only) */
|
|
50
|
+
includeRenderHostStyles?: boolean;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* THE single artifact document builder (eng review D2). Every render context —
|
|
54
|
+
* in-app canvas, public share/present page, downloaded standalone HTML, and the
|
|
55
|
+
* headless Playwright render — produces its HTML here, from one set of
|
|
56
|
+
* content-processing helpers and one runtime. `host` selects the document SHAPE
|
|
57
|
+
* (a live-hosted iframe srcdoc vs a self-contained file) and the runtime's
|
|
58
|
+
* capabilities; the asset CSP + URL rewrite come from the one `assets` value.
|
|
59
|
+
*/
|
|
60
|
+
export declare function buildArtifactDocument(bundle: ArtifactBundle, ctx: ArtifactRenderContext): string;
|
|
61
|
+
export interface ArtifactHtmlExportOptions {
|
|
62
|
+
context?: 'editor' | 'fullscreen' | 'export';
|
|
63
|
+
/** Base URL for the headless (Playwright) render path so root-relative
|
|
64
|
+
* `/api/assets/...` URLs resolve in a `setContent` document. The CSP's
|
|
65
|
+
* `base-uri` is widened to exactly this origin. Never set on the
|
|
66
|
+
* standalone HTML export — a downloaded file must not phone home. */
|
|
67
|
+
baseHref?: string;
|
|
68
|
+
includeRenderHostStyles?: boolean;
|
|
69
|
+
librarySources?: ArtifactLibrarySources;
|
|
70
|
+
/** How workspace-asset refs resolve in THIS render — drives both the URL
|
|
71
|
+
* rewrite and the document CSP from one value (see
|
|
72
|
+
* artifact-asset-resolution.ts). Headless PNG/PDF passes token mode; the
|
|
73
|
+
* self-contained HTML export passes relative mode. Defaults to none
|
|
74
|
+
* (no asset access). */
|
|
75
|
+
assets?: AssetResolution;
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Self-contained HTML export + headless Playwright render. A thin adapter over
|
|
79
|
+
* {@link buildArtifactDocument} with `host: 'none'` — kept for its existing
|
|
80
|
+
* callers (the export route, MCP `export_artifact`, the render service). A
|
|
81
|
+
* bare call (no `context`) yields a plain self-contained file, unchanged.
|
|
82
|
+
*/
|
|
83
|
+
export declare function buildArtifactHtmlExport(bundle: ArtifactBundle, options?: ArtifactHtmlExportOptions): string;
|