Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
31 changes: 12 additions & 19 deletions .github/copilot-instructions.md
Original file line number Diff line number Diff line change
Expand Up @@ -129,15 +129,17 @@ Every code change ships with tests. No exceptions.
The `docs/` directory is a VitePress site for external developers consuming WebUI.

- Any change to user-visible behavior, CLI usage, or public API **must** include a corresponding docs update in the same PR.
- New features get a guide page (`docs/guide/`) or tutorial (`docs/tutorials/`).
- **User-facing docs show template syntax, state, and rendered output only.** Never expose protocol internals (fragment types, proto fields, stream IDs) in `/docs`. Protocol details belong in `DESIGN.md` and `docs/guide/advanced/protocol.md`.
- Verify with `cd docs && pnpm build` when possible.
- For the full docs synchronization workflow, use the skill: `skills/docs-sync/SKILL.md`.

---

## Skills

- **Pull request** — `.github/skills/pr/SKILL.md`
- **Pull request** — `skills/pr/SKILL.md`
- **Quality gate** — `skills/quality-gate/SKILL.md`
- **FFI boundary** — `skills/ffi/SKILL.md`
- **Protobuf schema evolution** — `skills/protobuf/SKILL.md`
- **Docs synchronization** — `skills/docs-sync/SKILL.md`

---

Expand All @@ -160,27 +162,18 @@ The `docs/` directory is a VitePress site for external developers consuming WebU

## FFI boundary (`webui-ffi`)

The FFI crate exposes WebUI to **any** host language (C, C#, Go, Ruby, Python, Node.js, etc.) via a C-compatible ABI. Treat it as the project's most sensitive surface.
The FFI crate exposes WebUI to many host languages via a C-compatible ABI and remains a high-sensitivity surface.

- Every `pub extern "C" fn` must have a `# Safety` doc section explaining pointer validity, lifetime, and ownership expectations.
- All `unsafe` blocks require a `// SAFETY:` comment. No exceptions.
- Assume callers are in a different language with no Rust safety net — validate every input (null pointers, invalid UTF-8, out-of-range values) before dereferencing or converting.
- Never panic across the FFI boundary. Catch all errors and return them as error codes or null pointers. A panic in FFI is undefined behavior.
- C header generation is handled by `cbindgen` in `build.rs`. After changing any `#[no_mangle]` function signature, verify the generated header in `include/webui_ffi.h` is correct.
- Keep the FFI surface minimal and stable — additions are easy, removals break every consumer.
- Platform-specific code must be gated behind `#[cfg(target_os = "...")]` and every platform path must be tested or at least compile-checked.
- Design for ABI stability: prefer opaque pointers and integer error codes over exposing Rust struct layouts.
- Treat all FFI changes as safety- and compatibility-critical.
- Use the full workflow and checklist in: `skills/ffi/SKILL.md`.

---

## Protobuf schema evolution

The protocol is defined in `crates/webui-protocol/proto/webui.proto` and compiled by `prost` via `build.rs`. Schema changes cascade through the entire stack: **protocol → handler → FFI → CLI**.
Schema changes cascade through protocol → handler → FFI → CLI and should optimize runtime performance first.

- Never remove or renumber existing proto fields — mark them `reserved` instead.
- Add new fields as optional with sensible defaults so older serialized data remains decodable.
- After any `.proto` change, rebuild the full workspace (`cargo xtask build`) and run all tests — not just the protocol crate.
- Update `DESIGN.md` protocol section in the same commit.
- Use the protocol evolution workflow in: `skills/protobuf/SKILL.md`.

---

Expand Down Expand Up @@ -234,7 +227,7 @@ Before finishing any task, confirm **all** of these:
- [ ] No new `unwrap`/`expect` in library code.
- [ ] No unnecessary allocations introduced; buffers reused where possible.
- [ ] FFI changes include `# Safety` docs and never panic across the boundary.
- [ ] Proto schema changes are backward-compatible and cascade-tested.
- [ ] Proto schema changes prioritize performance and are cascade-tested.
- [ ] New dependencies use `workspace = true` and pass `cargo deny check`.
- [ ] Commit is on a feature branch, not `main`.
- [ ] Commit message is imperative with Copilot co-author trailer.
37 changes: 37 additions & 0 deletions .github/skills/docs-sync/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
---
name: docs-sync
description: Keep user-facing docs and DESIGN specification aligned with behavior and API changes.
---

# Docs Synchronization Workflow

Use this skill for user-visible behavior changes or API/contract changes.

## DESIGN.md (spec) requirements

Update `DESIGN.md` in the same change when modifying:

- public APIs
- protocol fields
- behavioral contracts
- error variants

Treat `DESIGN.md` as the implementation specification.

## docs/ requirements

Update `docs/` in the same change when behavior is user-visible:

- CLI usage changes
- template syntax/state/render output changes
- integration behavior that external users depend on

Keep protocol internals out of general user docs unless placed in advanced protocol documentation.

## Optional validation

When docs are changed substantially, validate with:

```bash
cd docs && pnpm build
```
30 changes: 30 additions & 0 deletions .github/skills/ffi/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
---
name: ffi
description: Rules and checklist for safe, stable changes to the webui-ffi C ABI boundary.
---

# FFI Boundary Workflow

Use this skill when touching `crates/webui-ffi` or C ABI signatures.

## Mandatory safety rules

- Every `pub extern "C" fn` must include a `# Safety` doc section.
- Every `unsafe` block must include a `// SAFETY:` justification comment.
- Never allow panic to cross the FFI boundary.
- Validate all foreign inputs before dereferencing or conversion:
- null pointers
- invalid UTF-8
- out-of-range values

## ABI stability expectations

- Keep exported surface minimal and stable.
- Prefer opaque pointers and integer error codes over exposing Rust layouts.
- Use `#[cfg(target_os = "...")]` for platform-specific code paths.

## Header sync

If any `#[no_mangle]` signature changes, verify generated header output in:

- `crates/webui-ffi/include/webui_ffi.h`
6 changes: 6 additions & 0 deletions .github/skills/pr/SKILL.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
---
name: pr
description: Guidance for branch naming, commit messages, and PR titles.
---

# Pull Request Conventions

## Branch discipline
Expand All @@ -15,6 +20,7 @@ PR titles must use a [Conventional Commits](https://www.conventionalcommits.org/
| `fix:` | Bug fix | `fix: render missing signals as empty` |
| `chore:` | Maintenance, refactoring, CI, docs, dependencies | `chore: move shared files to examples/app` |


The prefix is **lowercase**, followed by a colon and a space, then a short imperative description.

## Linking PRs to issues
Expand Down
34 changes: 34 additions & 0 deletions .github/skills/protobuf/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
---
name: protobuf
description: Performance-first protobuf schema workflow for WebUI protocol changes.
---

# Protobuf Evolution Workflow

Use this skill when modifying `crates/webui-protocol/proto/webui.proto`.

## Performance-first schema rules

- Prioritize decode speed, memory layout, and smaller payloads over wire compatibility.
- Breaking field changes are allowed when they improve performance measurably.
- When introducing a breaking schema, update all affected layers in one change:
- protocol
- handler
- FFI
- CLI
- Remove unused fields and message shapes that add decode overhead.

## Required validation

After schema updates, run:

```bash
cargo xtask build
cargo xtask test
```

Schema changes affect the whole stack: protocol → handler → FFI → CLI. Keep the stack synchronized in the same change.

## Documentation sync

When protocol behavior changes, update `DESIGN.md` protocol sections in the same change.
35 changes: 35 additions & 0 deletions .github/skills/quality-gate/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
---
name: quality-gate
description: Required verification workflow for formatting, linting, tests, dependency audits, and builds.
---

# Quality Gate Workflow

Use this skill whenever work changes code, tests, dependencies, or docs in this repository.

## Required gate

Before any commit, run:

```bash
cargo xtask check
```

This runs, in order: `fmt → clippy → deny → test → build → doc`.

Work is not complete until it passes cleanly.

## Fast iteration sequence

When iterating locally, use this order:

1. Targeted crate checks first (for faster feedback):
- `cargo test -p <crate>`
2. Then full gate:
- `cargo xtask check`

## Expectations

- Fix reported issues rather than suppressing them.
- Do not merge or commit with a failing gate.
- Keep fixes minimal and scoped to the task.
1 change: 1 addition & 0 deletions crates/webui-test-utils/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
[package]
name = "webui-test-utils"
description = "Test utilities for WebUI framework"
publish = false
version.workspace = true
edition.workspace = true
authors.workspace = true
Expand Down
16 changes: 14 additions & 2 deletions deny.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,24 @@ allow = [
"Apache-2.0",
"MPL-2.0",
"Unicode-3.0",
"Unicode-DFS-2016",
]
confidence-threshold = 0.8

[licenses.private]
ignore = true

[bans]
multiple-versions = "warn"
multiple-versions = "deny"
skip = [
{ name = "wasi" },
{ name = "windows-sys" },
{ name = "windows-targets" },
{ name = "windows_aarch64_gnullvm" },
{ name = "windows_aarch64_msvc" },
{ name = "windows_i686_gnu" },
{ name = "windows_i686_gnullvm" },
{ name = "windows_i686_msvc" },
{ name = "windows_x86_64_gnu" },
{ name = "windows_x86_64_gnullvm" },
{ name = "windows_x86_64_msvc" },
]
1 change: 1 addition & 0 deletions examples/integration/hyper/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
name = "webui-hyper-integration"
version = "0.1.0"
edition = "2021"
publish = false

[[bin]]
name = "webui-hyper-integration"
Expand Down
1 change: 1 addition & 0 deletions examples/integration/tiny_http/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
name = "webui-tiny-http-integration"
version = "0.1.0"
edition = "2021"
publish = false

[[bin]]
name = "webui-tiny-http-integration"
Expand Down
26 changes: 25 additions & 1 deletion xtask/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,11 @@ fn main() -> ExitCode {
Some("clippy") => run_steps(&[Step::CLIPPY]),
Some("deny") => run_steps(&[Step::DENY]),
Some("test") => run_steps(&[Step::TEST]),
Some("build") => run_steps(&[Step::BUILD]),
Some("build") => run_steps(&[
Step::BUILD,
Step::BUILD_INTEGRATION_HYPER,
Step::BUILD_INTEGRATION_TINY_HTTP,
]),
Some("docs") => run_steps(&[Step::DOCS]),
_ => usage(),
}
Expand Down Expand Up @@ -37,6 +41,8 @@ fn check() -> ExitCode {
Step::DENY,
Step::TEST,
Step::BUILD,
Step::BUILD_INTEGRATION_HYPER,
Step::BUILD_INTEGRATION_TINY_HTTP,
Step::DOCS,
])
}
Expand Down Expand Up @@ -73,6 +79,24 @@ impl Step {
cmd: "cargo",
args: &["build", "--workspace"],
};
const BUILD_INTEGRATION_HYPER: Self = Self {
name: "build (integration/hyper)",
cmd: "cargo",
args: &[
"build",
"--manifest-path",
"examples/integration/hyper/Cargo.toml",
],
};
const BUILD_INTEGRATION_TINY_HTTP: Self = Self {
name: "build (integration/tiny_http)",
cmd: "cargo",
args: &[
"build",
"--manifest-path",
"examples/integration/tiny_http/Cargo.toml",
],
};
const DOCS: Self = Self {
name: "docs",
cmd: "pnpm",
Expand Down