Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
111 changes: 111 additions & 0 deletions .agents/skills/summon/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
---
name: summon
description: "Build, debug, or integrate Summon sandboxed generative UI: SurfacePlan contracts, contract-first prompts, JSONL protocol streaming, host-owned capabilities/resources, PolicyEngine grants, StreamGraph diagnostics, safety smoke tests, and adoption docs. Use when working in the Summon repo, adding capabilities/resources/workers/approval actions, debugging validation or sandbox behavior, or creating agent-authored Summon UIs."
---

# Summon

Use this skill when working inside the Summon repo or integrating Summon into a
host app.

## Start Here

1. Read `README.md` for the current adoption flow and package map.
2. Read `docs/adoption/quickstart.md` for the local golden path.
3. Read `docs/adoption/integration.md` before wiring a host or server.
4. Read `docs/adoption/package-consumption.md` before importing packages,
publishing packages, or choosing between React/frameworkless/server APIs.
5. Read `docs/adoption/mobile-webviews.md` before discussing mobile WebView or
native-wrapper behavior.
6. Read `docs/adoption/security.md` before changing sandbox, CSP, grants,
script policy, worker, approval, or production-tier behavior.
7. Read `docs/adoption/debugging.md` before changing validation, repair,
stream graph, protocol, Devtools, or sandbox diagnostics.

## Core Architecture

Follow this path unless the user explicitly asks for a runtime redesign:

```txt
host capability registry
-> SurfacePlan: purpose/runtime/data/authority/persistence
-> createCapabilityRegistry(...).toContract()
-> compileSystemContracts()
-> protocol hardener and repair feedback
-> SectionAccumulator and StreamGraph
-> PolicyEngine and spawnSandbox()
```

Capabilities are host-owned. The model sees the contract; the host owns
handlers, network, credentials, state, grants, and the selected `SurfacePlan`.
Generated artifacts must not emit or widen `/surface-plan`.

New generation servers should prefer `runSurfaceGeneration(input, emit)` from
`@summon/server`; `generateSurfaceStream()` remains available for existing
async-generator integrations. Applications should consume built package exports,
not `src/*.ts` paths.

Use `defineAction` and `defineDataResource` for common host-backed
interactivity. Use `defineWorkerAction` / `defineWorkerResource` for host-owned
background work and `defineApprovalAction` when an operation must pass through a
host approval adapter.

## Safe Output Rules

- Keep the iframe null-origin. Do not add `allow-same-origin`.
- Grant intents and capabilities from the host with `grantedIntents` and
`grantedCapabilities`; never trust artifact-declared intents or capabilities
as permission.
- Prefer declarative interactive surfaces with `scriptPolicy: "forbid"` and
`data-summon-*` bindings. Treat `scriptPolicy: "allow"` as an escalation for
hosts that intentionally permit custom artifact scripts.
- Use `defineDataResource` for host-backed async data, with loading, error, and
data state keys.
- Resource UIs must render loading, error, and data states.
- Do not introduce external URLs, unsafe tags, inline handlers, ambient storage,
parent DOM access, or network access in generated artifacts.
- Keep runtime protocol/API changes out of adoption-doc work unless requested.

## Debug Loop

For generation failures, inspect `/error`, `/validation-summary`,
`/validation-blocked`, `/repair-feedback`, `/repair-summary`,
`/stream-graph-summary`, `/protocol-skip`, `/surface-plan`, `/shape`,
`/token-overrides`, `/screen-synthesized`, and `/mode-upgraded`.

For client behavior, inspect Devtools events: `surface-plan`, `protocol-line`,
`protocol-parse-error`, `sandbox-ready`, `render`, `intent-emitted`,
`intent-rejected`, `intent-dispatched`, `intent-settled`, `state-pushed`,
`stream-graph`, and `sandbox-fatal`.

Use `ContractIssue` plus `hintsForContractIssue(issue)` when feeding validation
problems back to a model or another agent. For surface problems, check whether
the requested runtime, data source, or authority exceeds the selected
`SurfacePlan`.

## Commands

```sh
pnpm typecheck
pnpm test
pnpm test:safety
pnpm build
pnpm pack:dry-run
pnpm dev:all
pnpm port-direction <path-to-expression.md> [id]
pnpm eval-directions [--prompts N] [--directions id,id] [--seed N] [--dry]
```

`pnpm test:safety` runs the Playwright Chromium and WebKit smoke suite for
sandbox containment, bootstrap fatal checks, strict input, and generate-page
boot. It starts only the Vite demo app and does not require
`ANTHROPIC_API_KEY`.

Manual smoke path: open `http://localhost:5173/generate.html`, choose the
**Host-resource search** showcase scenario, keep **Free layout**, confirm the
contract cockpit shows `explore/declarative/host-resource/read/replayable` and
`Grants 1: search`, run the scenario, submit a generated search such as
`chicken pasta`, inspect the Stream and Devtools drawers, replay from Saved
surfaces, then open `http://localhost:5173/adversarial.html`. Use `batch.html`,
`strict.html`, and `fatal.html` for prompt/token health, trusted input overlay,
and sandbox startup failure checks.
44 changes: 44 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
name: CI

on:
push:
branches: [main]
pull_request:
branches: [main]

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

jobs:
verify:
name: Typecheck, Test, Build
runs-on: ubuntu-latest
timeout-minutes: 20
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- uses: pnpm/action-setup@fc06bc1257f339d1d5d8b3a19a8cae5388b55320 # v4.4.0
- uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
with:
node-version: 22
cache: pnpm
- run: pnpm install --frozen-lockfile
- run: pnpm typecheck
- run: pnpm test
- run: pnpm build
- run: pnpm pack:dry-run

safety:
name: Browser Safety Smoke
runs-on: ubuntu-latest
timeout-minutes: 20
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- uses: pnpm/action-setup@fc06bc1257f339d1d5d8b3a19a8cae5388b55320 # v4.4.0
- uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
with:
node-version: 22
cache: pnpm
- run: pnpm install --frozen-lockfile
- run: pnpm exec playwright install --with-deps chromium webkit
- run: pnpm test:safety
9 changes: 9 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
node_modules
dist
.DS_Store
*.log
.env
.env.local
.vite
test-results
playwright-report
1 change: 1 addition & 0 deletions .npmrc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
registry=https://registry.npmjs.org/
154 changes: 130 additions & 24 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,36 +1,142 @@
# Summon README
# Summon

Congrats, project leads! You got a new project to grow!
Sandboxed, self-contained generative UI. An LLM streams HTML, CSS, and
JavaScript into a locked-down iframe; the UI communicates with the host only
through a typed intent bridge. Data in, data out, nothing leaks.

This stub is meant to help you form a strong community around your work. It's yours to adapt, and may
diverge from this initial structure. Just keep the files seeded in this repo, and the rest is yours to evolve!
Summon is also an adoption architecture. Hosts declare capabilities, compile
prompt and validation contracts, harden the streamed protocol, and render only
accepted output inside the sandbox. The model can propose UI, but the host owns
network, credentials, state, handlers, grants, and persistence.

## Introduction
## Project Status: Beta

Orient users to the project here. This is a good place to start with an assumption
that the user knows very little - so start with the Big Picture and show how this
project fits into it.
Summon is pre-1.0 and under active development. The protocol, package layout,
workspace package names, generated-surface contract, and public JavaScript
exports may change before a stable release.

Then maybe a dive into what this project does.
This initial public import keeps the existing `@summon/*` workspace package
names. Public npm packaging will be introduced in a follow-up change.

Diagrams and other visuals are helpful here. Perhaps code snippets showing usage.
## Quickstart

Project leads should complete, alongside this `README`:
```sh
pnpm install
cp apps/server/.env.example apps/server/.env
# edit apps/server/.env and set ANTHROPIC_API_KEY
pnpm dev:all
```

* [CODEOWNERS](./CODEOWNERS) - set project lead(s)
* [CONTRIBUTING.md](./CONTRIBUTING.md) - Fill out how to: install prereqs, build, test, run, access CI, chat, discuss, file issues
* [Bug-report.md](.github/ISSUE_TEMPLATE/bug-report.md) - Fill out `Assignees` add codeowners @names
* [config.yml](.github/ISSUE_TEMPLATE/config.yml) - remove "(/add your discord channel..)" and replace the url with your Discord channel if applicable
Open `http://localhost:5173/generate.html`.

The other files in this template repo may be used as-is:
1. Choose the **Host-resource search** showcase scenario.
2. Confirm the contract cockpit shows
`explore/declarative/host-resource/read/replayable` with the `search` grant.
3. Run it, submit a generated search, then inspect the **Stream** and
**Devtools** drawers.
4. Open `http://localhost:5173/adversarial.html` and confirm the sandbox
boundary still holds.

* [GOVERNANCE.md](./GOVERNANCE.md)
* [LICENSE](./LICENSE)
The full guided path lives in
[docs/adoption/quickstart.md](docs/adoption/quickstart.md).

## Project Resources
## Architecture

| Resource | Description |
| ------------------------------------------ | ------------------------------------------------------------------------------ |
| [CODEOWNERS](./CODEOWNERS) | Outlines the project lead(s) |
| [GOVERNANCE.md](./GOVERNANCE.md) | Project governance |
| [LICENSE](./LICENSE) | Apache License, Version 2.0 |
Summon's supported integration path is intentionally narrow:

```txt
host capability registry
-> SurfacePlan: purpose/runtime/data/authority/persistence
-> createCapabilityRegistry(...).toContract()
-> compileSystemContracts()
-> protocol hardener + repair feedback
-> SectionAccumulator + StreamGraph
-> PolicyEngine + spawnSandbox()
```

No generated artifact gets to mint permissions for itself. Artifact-declared
intents are advisory; execution is governed by host grants.

Surface planning is Summon's lifecycle layer. A host can declare the minimum
safe surface across purpose, runtime, data, authority, and persistence before
generation starts. The model sees that plan as a contract but cannot widen it.

## Demo Map

- `/generate.html` - contract cockpit with scenario grants, surface plans,
static/declarative/scripted/worker tiers, component islands, host resources,
token overrides, repair diagnostics, edit/replay, Ghost steering, Devtools,
and stream graph events.
- `/batch.html` - parallel prompt harness for prompt coverage, intent wiring,
direction-token visual coverage, throughput, and consistency checks.
- `/adversarial.html` - sandbox boundary checks for network, storage, parent
access, and ungranted intents.
- `/strict.html` - trusted host overlay for sensitive input inside an outer
sandbox description.
- `/fatal.html` - sandbox startup failure handling.

## Workspace Map

- `packages/sandbox-runtime` - built `bootstrap.js`, `tokens.css`, and
`@summon/sandbox-runtime/assets` string exports for non-Vite consumers.
- `packages/host` - policy, capability registry, envelope helpers, and the
browser-only `spawnSandbox` iframe primitive.
- `packages/engine` - protocol constants/parsers, `SectionAccumulator`,
`StreamGraph`, contract compilers, protocol hardener, token validation, and
parser-based runtime validation.
- `packages/devtools` - `EventStore` and typed lifecycle, protocol, intent,
state, render, and stream-graph events.
- `packages/react` - controlled `SummonSurface` component for React hosts.
- `packages/server` - provider-neutral generation primitives; no Express
routes.
- `apps/server` - Anthropic-backed demo server, direction loading, repair
feedback, and demo backing routes.
- `apps/demo` - Vite host app for generation, batch runs, adversarial checks,
strict input, and fatal sandbox testing.

## Adoption Docs

- [Quickstart](docs/adoption/quickstart.md) - one golden end-to-end path.
- [Integration](docs/adoption/integration.md) - minimal host/server wiring with
current APIs.
- [Package Consumption](docs/adoption/package-consumption.md) - how React apps
and frameworkless hosts should import built Summon packages.
- [Mobile WebViews](docs/adoption/mobile-webviews.md) - web-first requirements
for iOS/Android WebView embedding.
- [Security Posture](docs/adoption/security.md) - production tiers, host rules,
and browser-test expectations.
- [Debugging](docs/adoption/debugging.md) - validation, repair, stream graph,
and Devtools diagnostics.
- [Agent skill](.agents/skills/summon/SKILL.md) - repo-local operating guide
for AI agents working on Summon.

## Security Boundary

Summon renders generated UI in a null-origin iframe with a restrictive CSP and a
typed postMessage bridge. The host grants intents and capabilities explicitly;
artifact-declared permissions are never executable authority.

Run the safety harness before changing iframe sandbox attributes, CSP,
postMessage routing, bootstrap startup checks, or script execution behavior:

```sh
pnpm test:safety
```

## Useful Commands

```sh
pnpm typecheck
pnpm test
pnpm test:safety
pnpm build
pnpm pack:dry-run
pnpm dev:all
pnpm port-direction <path-to-expression.md> [id]
pnpm eval-directions [--prompts N] [--directions id,id] [--seed N] [--dry]
```

`pnpm test:safety` runs the Playwright Chromium and WebKit smoke suite for
sandbox containment, bootstrap fatal checks, strict input, and generate-page
boot. It starts only the Vite demo app and does not require
`ANTHROPIC_API_KEY`.
33 changes: 33 additions & 0 deletions apps/demo/adversarial.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Summon — adversarial harness</title>
<link rel="stylesheet" href="/summon.css">
</head>
<body>
<nav class="summon-nav">
<a class="summon-brand" href="/">summon</a>
<a href="/generate.html">Generate</a>
<a href="/batch.html">Batch</a>
</nav>

<h1 class="page-title">Phase 1 adversarial harness</h1>
<p class="lede">Loads a sandbox with a deliberately malicious artifact. Each attempt that fails is a win.</p>

<div class="layout cols-2">
<div class="pane">
<header>Sandbox iframe</header>
<iframe id="sandbox" class="h-320" title="Summon sandbox"></iframe>
</div>
<div class="pane">
<header>Test results</header>
<div id="results" class="log h-320"></div>
<div class="summary" id="summary">Running…</div>
</div>
</div>

<script type="module" src="/src/main.ts"></script>
</body>
</html>
Loading
Loading