Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
5394631
Make the cross-arm append conflict test deterministic
vinniefalco Sep 12, 2026
c7fa896
Add architecture rules, xtask checks, and crate scaffolder
vinniefalco Sep 12, 2026
66f4053
Extract workshop protocol, support, and registry crates
vinniefalco Sep 12, 2026
f19e3df
Extract workshop gateway, status, and menu crates
vinniefalco Sep 12, 2026
08370dd
Extract workshop sessions and workspace feature crates
vinniefalco Sep 12, 2026
6ab28ff
Split workshop SPA into feature directories with tokens
vinniefalco Sep 12, 2026
d79046c
Split SPA panels and menus behind lazy registries
vinniefalco Sep 12, 2026
cc12a37
Add typed SPA errors, headless assets, bundle hashing
vinniefalco Sep 12, 2026
3bb9aaa
Keep the shell gateway supervisor; step 9 is rulebook-only
vinniefalco Sep 12, 2026
0180ac9
Add workshop architecture and SPA workspace rules
vinniefalco Sep 12, 2026
d41df14
Close plan: workshop-server-decomposition
vinniefalco Sep 12, 2026
4afa3c8
Stop advertising user_input as a model-visible tool
vinniefalco Sep 13, 2026
310804c
Size the lazy panel shell so the agent feed scrolls
vinniefalco Sep 13, 2026
7e28ae0
Seed workshop debt plan and fix the Observer doc link
vinniefalco Sep 13, 2026
b38ab29
Enforce facade-only crate roots and tidy scope
vinniefalco Sep 13, 2026
8752d3a
Redesign the registry as contribution collections
vinniefalco Sep 13, 2026
03ccc51
Add build drift test; drop redundant eager CSS imports
vinniefalco Sep 13, 2026
0938ee3
Correct the decomposition records
vinniefalco Sep 13, 2026
82cd96c
Close plan: workshop debt removal
vinniefalco Sep 13, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
1 change: 1 addition & 0 deletions .cargo/config.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,4 @@ rustflags = ["-C", "target-feature=+crt-static"]

[alias]
workshop = "run -p build-workshop --"
xtask = "run -p xtask --"
25 changes: 25 additions & 0 deletions .cursor/rules/workshop-architecture.mdc
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
---
description: Workshop server crate architecture invariants - one-way dependency tiers, registry self-registration, 500-line file ceiling
globs: crates/workshop*/**
alwaysApply: false
---

# Workshop Architecture Invariants

## One-way dependency graph

- Dependencies flow one way: shell -> features -> services -> vocabulary. Never add a dependency from a lower tier to a higher one. If Cargo rejects a cycle, the design is wrong, not the graph.
- Tiers: vocabulary (`workshop-protocol`, `workshop-support`, `workshop-registry`) <- services (`workshop-gateway`, `workshop-status`, `workshop-menu`) <- features (`workshop-sessions`, `workshop-workspace`) <- shell (`workshop-server`).
- Crates in the same tier never depend on each other. They meet through `workshop-protocol` wire types and `workshop-registry` proxy slots.
- Every `workshop-*` crate's `lib.rs` opens with a `//!` doc carrying a `## Invariants` marker that lists what the crate may depend on and what it may not. Read it before adding an import.
- `lib.rs` is a facade only: crate docs, crate-level attributes, `mod` declarations, and `pub use` re-exports. No logic.

## Registry pattern

- Subsystems self-register into `workshop-registry` proxy slots: routes, state handles, background tasks, push channels, and shutdown handles. The shell composes the registry; it does not wire subsystems by name.
- Unregistered slots are graceful no-ops. Never add a hard dependency on an optional subsystem.
- Registration handles are `#[must_use]`; registry traits are sealed so only workshop crates implement them.

## File ceiling

- No file exceeds 500 lines. If an edit would push a file past 500, split first, then edit. `cargo test -p xtask` enforces the ceiling, the tier graph, and lint inheritance over the Rust files in the workshop crates carrying the marker; the Tauri shell (the `workshop` crate) is exempt until the headless agent mode plan.
21 changes: 21 additions & 0 deletions .cursor/rules/workshop-spa.mdc
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
---
description: Workshop SPA conventions - feature directories, barrel exports, lazy loading, CSS colocation, token-only values
globs: crates/workshop-server/ui/**
alwaysApply: false
---

# Workshop SPA Conventions

## Feature directories and lazy loading

- Feature-based directories under `ui/` (`ui/agent/`, `ui/editor/`, `ui/layout/`, `ui/menu/`, `ui/take/`, `ui/stt/`, `ui/chrome/`, `ui/status/`, `ui/workspace/`, `ui/gateway/`). Shared code lives in `services/` or `base/`; shared UI assets (boot-loaded icons) live in `ui/shared/`; design tokens live in `tokens/`.
- Barrel exports: every directory has an `index.ts`. Lazy directories export `register()` installing commands, menu items, panel factories, and socket subscriptions.
- The boot shell (`main.ts`, `services/`, `base/`) loads immediately. Feature directories load via dynamic `import()` on first activation. Lazy-loaded panels never import the boot shell.
- Registration, not central wiring: panel types, menu items, services, socket handlers, keyboard shortcuts, and lifecycle disposal self-register through the panel, menu/command, and service registries.

## CSS colocation and tokens

- CSS lives beside its TypeScript, imported as a side-effect. Never a separate `styles/` tree. Every feature directory is self-contained: `.ts`, `.css`, and `index.ts` together. A designer finds the styles for the agent chat at `ui/agent/agent-session.css`, not by grepping a flat directory.
- No raw color, size, or spacing values in component CSS. Use `--ws-*` tokens from `tokens/`. Primitives go in `tokens/base.css`, intent aliases in `tokens/semantic.css`, per-component overrides in `tokens/component.css`. A designer themes the app by editing `semantic.css`.
- CSS classes use the `.ws-` project prefix (`.ws-agent-toolbar`). Design tokens use the `--ws-` prefix (`--ws-color-bg-surface`).
- Directories and files are kebab-case (`agent-session-view.ts`, `agent-session.css`).
6 changes: 6 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,12 @@ jobs:
- name: Test (workshop, concurrent via nextest)
run: cargo nextest run --locked -p workshop -p workshop-server

# The headless feature swaps the webview asset layer for a no-op so
# server-only integration tests run without the UI bundle. It is not
# a default feature, so it needs its own invocation.
- name: Test (workshop-server headless)
run: cargo nextest run --locked -p workshop-server --features headless

# nextest does not run doctests; the workspace doctest step in the
# `test` job excludes both workshop crates, so cover them here.
- name: Doctests (workshop)
Expand Down
11 changes: 11 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,3 +37,14 @@ Multi-crate Rust workspace for the PromptForge pipeline runtime, inference gatew
- Long-running work reports through `shared-progress`. Producers report operation state, hosts forward it, and renderers format it.
- Unsafe code stays in its explicitly owned boundary. Every unsafe block documents its safety invariants immediately before the block.
- Comments explain a non-obvious constraint, ordering requirement, or workaround. Every platform or external-bug workaround cites its upstream issue URL in the explanatory comment.

## Structural Rules

- Dependencies flow one way: shell -> features -> services -> vocabulary. Never add a dependency from a lower tier to a higher one. If Cargo rejects a cycle, the design is wrong, not the graph. On the SPA side, lazy-loaded panels never import the boot shell; shared code lives in services/ or base/.
- Every workshop-* crate's lib.rs opens with a //! doc carrying a `## Invariants` marker that lists what the crate may depend on and what it may not. Read it before adding an import. Every SPA concern directory (ui/editor/, ui/agent/, etc.) has the same in its index.ts.
- No file exceeds 500 lines. If an edit would push a file past 500, split first, then edit. `cargo test -p xtask` enforces the tier graph, the lint inheritance, and the ceiling over the Rust files in the workshop crates carrying the marker; the Tauri shell (the `workshop` crate) is exempt until the headless agent mode plan.

## SPA and CSS Rules

- CSS lives beside its TypeScript, never in a separate styles/ tree. A designer finds the styles for the agent chat at ui/agent/agent-session.css, not by grepping a flat directory. Every feature directory is self-contained: .ts, .css, and index.ts together.
- No raw color, size, or spacing values in component CSS. Use --ws-* tokens from tokens/. Primitives go in tokens/base.css, intent aliases in tokens/semantic.css, per-component overrides in tokens/component.css. A designer themes the app by editing semantic.css.
159 changes: 152 additions & 7 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 8 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,14 @@ gateway-stt-backend-whisper = { path = "crates/gateway-stt-backend-whisper", ver
promptforge-web-search = { path = "crates/promptforge-web-search", version = "0.3.0" }
gateway-web-search = { path = "crates/gateway-web-search", version = "0.3.0" }
workshop-server = { path = "crates/workshop-server", version = "0.3.0" }
workshop-gateway = { path = "crates/workshop-gateway", version = "0.0.0" }
workshop-menu = { path = "crates/workshop-menu", version = "0.0.0" }
workshop-protocol = { path = "crates/workshop-protocol", version = "0.0.0" }
workshop-status = { path = "crates/workshop-status", version = "0.0.0" }
workshop-support = { path = "crates/workshop-support", version = "0.0.0" }
workshop-registry = { path = "crates/workshop-registry", version = "0.0.0" }
workshop-sessions = { path = "crates/workshop-sessions", version = "0.0.0" }
workshop-workspace = { path = "crates/workshop-workspace", version = "0.0.0" }
gateway-whisper-ffi = { path = "crates/gateway-whisper-ffi", version = "0.3.0" }
promptforge-agent = { path = "crates/promptforge-agent", version = "0.3.0" }
pulldown-cmark = "0.12"
Expand Down
3 changes: 3 additions & 0 deletions crates/build-ui/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,8 @@ description = "Build-script helper that bundles a crate's ui/ sources with esbui
[dependencies]
anyhow.workspace = true

[dev-dependencies]
tempfile.workspace = true

[lints]
workspace = true
Loading
Loading