Renderable code blocks, doc-to-doc linking, and quiet groundwork for skills
This release is a mix: one genuinely new product capability (live HTML/CSS/JS inside docs), one piece of infrastructure agents will lean on heavily (linking docs to each other), and a few small things that make the docs surface feel more deliberate.
Renderable code blocks in docs
Any fenced code block marked html-render now executes inline in a sandboxed iframe instead of rendering as typeset code. The browser is the runtime — no extra setup, no bundler, no library to add.
```html-render
<button onclick="alert('it works')">click me</button>
<style>button { padding: 8px 16px; }</style>
```
Save the doc and the block renders as a working button between the surrounding prose. Three things this unlocks today:
- Prototype demos as docs. Paste output from Claude/v0/Cursor into a doc and the doc itself becomes the interactive prototype. Stakeholders click through the actual thing instead of reading screenshots.
- Tiny one-off dashboards. Pull data via
fetch, render with canvas or vanilla HTML. The doc is the dashboard.
- Better changelog entries. A release note can embed an actual working component showing what just shipped instead of describing it.
What's supported: any browser-native JavaScript — DOM APIs, fetch, localStorage, canvas, WebGL, web audio. You can even import npm packages from esm.sh as ES modules. What's not supported in this version: React/JSX with imports (no transform layer), TypeScript (no transpilation), Node APIs (browser-only by definition). A more capable tier using Sandpack is the planned follow-up if customers want React component embedding.
Sandboxing is real: iframe sandbox="allow-scripts" with no allow-same-origin. The block can run JavaScript inside the iframe but can't reach the parent page's cookies, localStorage, or DOM. Standard browser primitive.
Doc-to-doc linking
Until this release, you could link a doc to a card, a person, an org — but not to another doc. That was a real gap, because feedback items and release notes are both docs in Simple Product (stored with type="feedback" and type="release"). The doc-to-doc linking gap meant a feedback summary doc couldn't formally link to the underlying feedback items, and a release note couldn't link to its design doc.
Now it can. Three new MCP tools for AI agents:
link_doc_to_doc(docId1, docId2) — symmetric, idempotent. Doesn't matter which doc you list first.
unlink_doc_from_doc(docId1, docId2) — remove the link.
get_linked_docs(docId) — get every doc linked to a given doc, with title, type, excerpt, and last-update time.
The underlying junction table works the same way as the existing card↔card links. Workspace-scoped, deduped, no cross-workspace linking.
This is the kind of feature that's invisible until you need it, then suddenly powers a class of workflow. The first place it lands naturally: AI-drafted customer feedback summaries that need to point back at the specific feedback items they cover.
skill is now a recognized doc type
We didn't ship skills as a feature yet. But we added skill to the list of doc types that AI agents recognize when creating new docs. Drafts for skill specs and skill prompts now land with the right type marker, ready for the actual skills runtime that's coming next.
UI: "Category" is now "Type"
The doc type field had been labeled "Category" in the UI but called type everywhere else (API, schema, MCP). The mismatch was creating quiet confusion when reading code or talking about doc types. Renamed across the doc detail menu, the type dialog, and the publishing popover so the UI matches the underlying contract.
Unrelated "category" concepts (integrations, GSD setup actions) are unaffected.
Architecture footnote: typeOrigin discriminator
For the curious. We added a typeOrigin: "system" | "workspace" field to docs. It distinguishes system-defined types (feedback, release, blog, docs, skill — types with built-in product behavior) from workspace-defined custom categories (anything else, including categories that happen to share a name with a system type).
This is the protection layer that means a workspace can now create a custom category called "blog" without those docs accidentally appearing in the public blog feed. The discriminator gates which docs participate in system surfaces; user categories pass through cleanly. It also future-proofs us — when we ship more system types (skills with execution semantics, automation primitives, etc.), there's no name-collision risk with whatever customers have already named their own categories.
Backfill ran cleanly across existing data; nothing else changes from your perspective.
Have fun
If you've been using SP daily, the most visible thing this week is probably the renderable code blocks — drop an HTML demo into your next doc and see what comes out. It's surprising how much vanilla HTML/CSS/JS can do once the browser is the runtime.