experiments in a post-browser web
10
fork

Configure Feed

Select the types of activity you want to include in your feed.

docs(readme): refresh for tiles architecture; reference state machines + webtil.es comparison

README:
- Add explicit "State machines" section covering all three FSMs (tile
lifecycle, pubsub, cmd panel) with one-paragraph "what they replace"
framing and links to the per-FSM design docs.
- Add a Peek-tiles-vs-DASL/webtil.es teaser table (lifecycle,
capabilities, IPC, identity, sandbox, distribution) that points to
the full row-by-row comparison in docs/architecture.md.
- Drop the dead /autonome/peek/extension/ link from the history section
(the original browser-extension source is no longer in this repo).

DEVELOPMENT.md:
- Fix stale peek://ext/cmd/nouns.js → peek://cmd/nouns.js and
peek://ext/lex/home.html → peek://lex/home.html.
- Move noun-registry / nouns module paths from features/cmd/ to
app/cmd/ (cmd registry is in bgWindow / app/index.js, not a
feature tile).
- Rename "Editor Extension" / "Lexicon Studio extension" → "tile";
rename the noun "Converted extensions" table header to "Converted
tiles"; rename "Existing extensions" UI-migration prose to
"Existing tiles".
- Add a new Critical Rules entry on tile-preload.cts: it must remain
a CommonJS .cts file, because backend tsconfig emits ESM for plain
.ts and Electron's sandbox preload silently rejects ESM (empty
window.app, no thrown error, every tile broken).

No new docs created — all detail still lives in
docs/architecture.md, docs/pubsub-state-machine.md,
docs/cmd-state-machine.md, docs/tile-lifecycle-fsm.md,
docs/tiles-single-file.md, and docs/tile-preload-trimming-plan.md.

+46 -19
+22 -18
DEVELOPMENT.md
··· 242 242 243 243 **Architecture:** 244 244 ``` 245 - Extension → registerNoun() (nouns.js) 245 + Tile → registerNoun() (app/cmd/nouns.js) 246 246 → publishes noun metadata via pubsub 247 - → cmd background.js receives, generates commands via noun-registry.js 248 - → commands appear in palette like any other commands 247 + → bgWindow's cmd registry receives, generates commands via app/cmd/noun-registry.js 248 + → commands appear in the cmd palette like any other commands 249 249 → execution routes back via noun:{capability}:{name} pubsub 250 250 ``` 251 251 ··· 253 253 254 254 **Usage:** 255 255 ```javascript 256 - import { registerNoun, unregisterNoun } from 'peek://ext/cmd/nouns.js'; 256 + import { registerNoun, unregisterNoun } from 'peek://cmd/nouns.js'; 257 257 258 258 registerNoun({ 259 259 name: 'groups', // Plural (required) ··· 283 283 | `new group X` | create | create | 284 284 285 285 **Key files:** 286 - - `features/cmd/noun-registry.js` — Pure command generation (no deps) 287 - - `features/cmd/nouns.js` — Registration API (uses `window.app` pubsub) 288 - - `features/cmd/background.js` — Noun registry + command broadcasting 289 - - `features/cmd/commands.js` — Noun-aware proxy execution 286 + - `app/cmd/noun-registry.js` — Pure command generation (no deps) 287 + - `app/cmd/nouns.js` — Registration API (uses `window.app` pubsub) 288 + - `app/cmd/commands.js` — Noun-aware proxy execution 289 + - bgWindow (`app/index.js` → `initCmd()`) — owns the noun registry and command broadcasting 290 290 291 - **Converted extensions:** 291 + **Converted tiles:** 292 292 293 - | Extension | Capabilities | `skipBare` | Regular commands kept | 293 + | Tile | Capabilities | `skipBare` | Regular commands kept | 294 294 |-----------|-------------|------------|----------------------| 295 295 | tags | query, browse | true | tag, tags, untag, tagset | 296 296 | groups | query, browse, open, create | false | — | ··· 302 302 303 303 **When NOT to use nouns:** Panel-local commands (note, edit, history, url) that run directly in the panel window and don't go through pubsub. Also, action verbs that aren't standard CRUD (e.g., `refresh feeds`, `extract entities`). 304 304 305 - ### Editor Extension 305 + ### Editor tile 306 306 307 - The editor extension (`features/editor/`) is the canonical surface for creating, editing, and deleting items. It complements the tags extension, which focuses on browsing and tag management. 307 + The editor tile (`features/editor/`) is the canonical surface for creating, editing, and deleting items. It complements the tags tile, which focuses on browsing and tag management. 308 308 309 309 **Features:** 310 310 - Inline add with smart type detection (URLs auto-detected vs text notes) ··· 322 322 323 323 ### Lexicon Studio (AT Protocol Identity) 324 324 325 - The Lexicon Studio extension (`features/lex/`) connects Peek to the AT Protocol (Bluesky) network. It provides identity login, repo browsing, and record creation. 325 + The Lexicon Studio tile (`features/lex/`) connects Peek to the AT Protocol (Bluesky) network. It provides identity login, repo browsing, and record creation. 326 326 327 327 **Files:** 328 - - `background.js` — Extension lifecycle, session management, pubsub API for the home UI 328 + - `background.js` — Tile lifecycle, session management, pubsub API for the home UI 329 329 - `atproto.js` — AT Protocol helpers: OAuth (PKCE + DPoP via loopback server), XRPC requests, blob upload 330 330 - `home.js` / `home.html` — Main UI: login, sidebar navigation, three content panels 331 331 - `lexicon-ui.js` — Dynamic form generation from lexicon schemas with multi-layer resolution ··· 349 349 - `lex:search-lexicons` / `lex:search-lexicons:response` — Explore lexicon directory 350 350 - `lex:create-record` / `lex:create-record:response` — Create a record 351 351 352 - **Command:** `lexicon studio` — opens the identity panel window (`peek://ext/lex/home.html`). 352 + **Command:** `lexicon studio` — opens the identity panel window (`peek://lex/home.html`). 353 353 354 354 ### Cmd Commands (Item Creation) 355 355 ··· 474 474 475 475 #### Migration of Existing Code 476 476 477 - Existing extensions are being migrated to peek-components. When touching existing UI code: 477 + Existing tiles are being migrated to peek-components. When touching existing UI code: 478 478 479 479 1. **Check migration status** in `notes/migration-ui-componentry.md` 480 - 2. **Follow established patterns** from already-migrated extensions 480 + 2. **Follow established patterns** from already-migrated tiles 481 481 3. **Consider migrating** the code you're working on to components 482 482 4. **Ask first** if uncertain whether to migrate during your change 483 483 ··· 485 485 486 486 #### Benefits 487 487 488 - - **Consistency** across all extensions 488 + - **Consistency** across all tiles 489 489 - **Automatic theme support** via CSS custom properties 490 490 - **Built-in accessibility** (ARIA patterns, keyboard navigation) 491 491 - **Reduced code duplication** (~50% less UI code) ··· 527 527 ### Protected Directories 528 528 529 529 **NEVER modify files in `./app` without explicit review.** The `app/` directory is backend-agnostic - it must work unchanged with both Electron and Tauri backends. All backend-specific code belongs in `backend/{electron,tauri}/`. 530 + 531 + ### Tile preload must stay `.cts`, not `.ts` 532 + 533 + [`backend/electron/tile-preload.cts`](backend/electron/tile-preload.cts) — the capability-gated preload exposed as `window.app` to every tile renderer — **must** remain a CommonJS TypeScript file (`.cts`). The backend `tsconfig.json` uses `module: NodeNext`, which emits ESM for plain `.ts` files, and Electron's sandbox preload silently rejects ESM (no API surface, no thrown error — just an empty `window.app` and every tile broken). If you rename or convert this file, the entire app loses its API surface with no obvious failure. See [docs/architecture.md](docs/architecture.md) and [docs/tile-preload-trimming-plan.md](docs/tile-preload-trimming-plan.md). 530 534 531 535 ### Process Management 532 536
+24 -1
README.md
··· 202 202 203 203 Peek inverts the traditional browser model. Instead of a large monolithic core with an extension API bolted on, Peek has a minimal core with features that *are* the functionality. A feature is a **tile** — an HTML file in its own BrowserWindow, loaded through a capability-gated preload, talking to the main process over a strict `tile:*` IPC surface. Tiles are not extending something — they are the thing. For a full walkthrough of the tile model, the three runtime state machines, and a comparison to the [webtil.es / DASL Tiles](https://dasl.ing/tiles.html) spec, see [docs/architecture.md](docs/architecture.md). 204 204 205 + ### State machines 206 + 207 + Three explicit FSMs replace the ad-hoc timing code (sleeps, polling, retry hacks) that used to govern Peek's runtime. Each has its own design doc; the headlines: 208 + 209 + - **Tile lifecycle FSM** — owns *when a tile is alive*. States: `unregistered → registered → loading → ready → visible` plus `unloading` and `crashed`. Replaces the year-long bug class of "tile loaded but its commands haven't appeared yet" / "spinner hangs forever because the dispatch target was never live". Lives in [`backend/electron/tile-lifecycle.ts`](backend/electron/tile-lifecycle.ts) + [`backend/electron/tile-fsm.ts`](backend/electron/tile-fsm.ts); design in [docs/tile-lifecycle-fsm.md](docs/tile-lifecycle-fsm.md). 210 + - **PubSub state machine** — owns *what messages can flow between tiles in each state*. Every `tile:*` IPC frame runs through a 6-step validation pipeline (channel → sender frame → schema → token + grant → tile state → sender role) before any handler fires. Replaces "a publish was dropped somewhere in the fabric" as a debuggable bug class — if a message doesn't flow, the pipeline names which step rejected it. Lives in [`backend/electron/pubsub.ts`](backend/electron/pubsub.ts) + [`backend/electron/tile-ipc-gate.ts`](backend/electron/tile-ipc-gate.ts); design in [docs/pubsub-state-machine.md](docs/pubsub-state-machine.md). 211 + - **Cmd panel state machine** — owns the interactive command bar's UI states (`IDLE`, `TYPING`, `RESULTS_OPEN`, `PARAM_MODE`, `EXECUTING`, `OUTPUT_SELECTION`, `CHAIN_MODE`, `CHAIN_POPUP`, `ERROR`, `CLOSING`). Replaces the previous "every panel.js bug fix added another boolean flag" model — each prior regression cycle (param-mode escape, Tab-fills-vs-Enter-executes, output-selection cancel) collapses to one transition entry plus a test. Pure module in [`app/cmd/state-machine.js`](app/cmd/state-machine.js); design in [docs/cmd-state-machine.md](docs/cmd-state-machine.md). 212 + 213 + ### Peek tiles vs webtil.es / DASL Tiles 214 + 215 + Peek's tiles share the word and the instinct of the [DASL Tiles spec](https://dasl.ing/tiles.html) but sit at a different point in the design space: DASL is a **portable distribution format** (how a tile is identified, signed, and loaded into any host); Peek's tile is an **in-process runtime contract** (how a feature lives inside the Peek desktop app). A teaser: 216 + 217 + | Axis | DASL Tiles | Peek tiles | 218 + |---|---|---| 219 + | Lifecycle | Not specified | 7-state FSM + crash recovery | 220 + | Capabilities | Deferred to future spec; network locked off entirely | Required manifest declaration; per-domain / per-table allowlists; per-frame IPC gating | 221 + | Inter-tile messaging | "Future version" — not in current spec | First-class pubsub with subscribe-before-publish guarantees | 222 + | Identity | Content-addressed (CID) | String `id` unique within the install | 223 + | Sandbox | Browser-native (sandbox flags, CSP, COOP/COEP) | Electron-native (`sandbox: true`, `contextIsolation: true`, per-tile preload) | 224 + | Distribution | First-class (AT Protocol records, signed, fetchable from any PDS) | Local disk (built-in or installed); not yet portable | 225 + 226 + The two models are largely complementary — see [docs/architecture.md#peek-tiles-vs-webtiles--dasl-tiles](docs/architecture.md#peek-tiles-vs-webtiles--dasl-tiles) for the full row-by-row comparison and the terminology Peek could adopt from the spec. 227 + 205 228 A modular feature system for achieving "personal web workbench" requires a few things: 206 229 - UI modularity requires OS-level window capabilities beyond what the web allows today (also a baby step towards a minimal OS user interface) 207 230 - Data harvest/transform/process/publish requires a method of moving data between features (web apps) *locally*, cf Web Actions/Intents/Applets, MCP, pubsub, MQTT etc ··· 289 312 290 313 Peek was a browser extension that let you quickly peek at your favorite web pages without breaking your flow - loading pages mapped to keyboard shortcuts into a modal window with no controls, closable via the `Escape` key. 291 314 292 - However, as browser extension APIs became increasingly limited, it was not possible to create a decent user experience and I abandoned it. You can access the extension in this repo [in the extension directory](/autonome/peek/extension/). 315 + However, as browser extension APIs became increasingly limited, it was not possible to create a decent user experience and I abandoned it. The original extension source is no longer in this repo; see git history if you want to dig. 293 316 294 317 The only way to create the ideal user experience for a web user agent that *Does What I Want* is to make it a browser-ish application, and that's what Peek is now. 295 318