@ogygia/cli 0.11.0 → 0.12.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/ai/SKILL.md +2 -2
- package/package.json +7 -7
package/README.md
CHANGED
|
@@ -25,4 +25,4 @@ It is not a plugin: nothing goes in vite.config for it.
|
|
|
25
25
|
- `ogygia perf`: render pages under the profiler and judge them against a budget in CI.
|
|
26
26
|
- `ogygia keys <name>`: make an Ed25519 key pair for federation. `ogygia fragments <origin>`: typed stubs for a peer's widgets.
|
|
27
27
|
|
|
28
|
-
Docs: [ogygiajs.dev](https://ogygiajs.dev).
|
|
28
|
+
Docs: [@ogygia/cli](https://ogygiajs.dev/docs/cli/overview), with every [command](https://ogygiajs.dev/docs/cli/commands).
|
package/ai/SKILL.md
CHANGED
|
@@ -147,7 +147,7 @@ Each island is its own hydration root. Props cross by **value** (devalue), never
|
|
|
147
147
|
## Timing and nesting
|
|
148
148
|
|
|
149
149
|
- `interaction` on an island: zero JS until first pointer/key/focus **inside** the region. The waking click is captured and replayed; typing survives; hover prefetches the chunk. Caveat: the replayed event is not a trusted gesture — `window.open`/clipboard/fullscreen will be blocked; detect with `hydratedBy() === 'interaction'` and render e.g. a real `<a target="_blank">`.
|
|
150
|
-
- `interaction` on a server island = an **on-demand hole**: zero bytes until the visitor shows intent inside it — the first hover (`pointerover`, which bubbles through the boxless `display:contents` wrapper from a child), focus, touch, or key — then ONE fetch, **morphed** in so what the visitor already opened in the static fallback stays open (no click capture/replay — the fallback handles the gesture natively). Hover is the trigger, so the HTML is usually there before the visitor reaches a submenu. To have it there BEFORE the first hover, add `prefetch: 'idle'` (or `load` / `visible` / a media query — deferred-only, never `interaction`): the HTML is warmed into the frame store at that schedule and the hover swaps from it with no request. The shape for a
|
|
150
|
+
- `interaction` on a server island = an **on-demand hole**: zero bytes until the visitor shows intent inside it — the first hover (`pointerover`, which bubbles through the boxless `display:contents` wrapper from a child), focus, touch, or key — then ONE fetch, **morphed** in so what the visitor already opened in the static fallback stays open (no click capture/replay — the fallback handles the gesture natively). Hover is the trigger, so the HTML is usually there before the visitor reaches a submenu. To have it there BEFORE the first hover, add `prefetch: 'idle'` (or `load` / `visible` / a media query — deferred-only, never `interaction`): the HTML is warmed into the frame store at that schedule and the hover swaps from it with no request. The shape for a nav menu: fallback = the menu's L1/L2 (today's SSR HTML, byte-identical), hole = the same menu with L3/L4 rendered on the server — no L4 in the initial HTML, no menu JS, no feed download in the browser.
|
|
151
151
|
- Nesting — one rule, **closest marked parent decides**: island-in-island shares the parent's JS (one tree, child's schedule ignored, dev warns); lake-in-island stays static; island-in-lake wakes on its own; server-island-in-island renders inline (`deferred` ignored); an island inside a server island's `ogygiaFallback` is a full region that wakes on its own (the fallback belongs to the page, and a `keepFallback()`-kept fallback stays interactive).
|
|
152
152
|
- **An island hydrates against its own server markup.** The element keeps the HTML it connected with; if another script edited the island while it slept (a design-system runtime stripping whitespace, an A/B tool, a translator) and Svelte's walk mismatches on wake, the runtime puts the server markup back and hydrates that (`data-og-healed`, dev warning) instead of re-rendering client-side; only a second failure falls back to Svelte's recovery (`data-og-recovered`). Foreign scripts should still leave `<ogygia-region>` subtrees alone — whatever they added is gone after a heal.
|
|
153
153
|
- **A lake on a csr=true (Kit-hydrated) page is adopted, not hydrated.** Kit's pass keeps the lake's SSR element as opaque DOM (its component ships no client JS — not even in Kit's bundle), and everything authored INSIDE the lake stays in ogygia's world: islands and server islands there emit real regions and wake on the runtime. This is how a site header (static markup + `render: 'deferred'` personal holes + a `wake: 'interaction'` search) stays zero-JS-for-anonymous on csr=true pages too: mark the header import `with { wake: 'none' }` in the layout. Caveat: a lake first mounted during a Kit client-side navigation has no server HTML and renders empty (dev warns) — keep chrome lakes in a layout that persists, or serve the route csr=false. A hole rendered OUTSIDE a lake on a csr=true page is Kit-hydrated around; if Kit gives up hydrating the document (`Failed to hydrate`: a component threw) and mounts it fresh, the hole is rendered again with no address — the runtime restores it from the document's holes record (by identity, `data-og-hole`), so it still fetches; a hole rendered only in the browser has no record and keeps its fallback.
|
|
@@ -304,7 +304,7 @@ Env: `OGYGIA_SECRET` (stable MACs + island-id salt across deploys; required for
|
|
|
304
304
|
|
|
305
305
|
Event layer: `ogygia/events` (`add_sink`, `snapshot`), compiled in only when a plugin asks (devtools does). Tests: `@ogygia/testing` (`withOgygia(test, expect)`; the server under test lists `devtools()`).
|
|
306
306
|
|
|
307
|
-
**Writing a plugin (first-party only, UNSTABLE — no promise to outside authors):** `definePlugin({ name: '<package name>', server?: import.meta.resolve('./server.ts'), client?: import.meta.resolve('./client.ts'), options /* JSON */, enforce?, build(b) })` from `'ogygia/vite'` — it RETURNS a Vite plugin the app lists beside `ogygia()`; a factory that needs Vite hooks of its own returns `[definePlugin({…}), itsVitePlugin]`; `b.routeConfig(key)` (a key inside Kit's `config` page option, read at build, answered by `ctx.routeConfig(key)`) · `b.foreignHydrate()` · `b.macro(name, fn)` · `b.markup(source)` · `b.events({ lazy })` · `b.measure()` · `b.files(scan)` · `b.pageModules({ importers, files })`. Realms are NAMED by the plugin (no package export needed): the `server` module default-exports `defineServer({ setup(app), state(), handle(ctx, next), request, page, response, done, …sharedHooks })` from `'ogygia/plugin'` (hooks: `request`/`page` first-Response-wins, `response` may replace, `done` always, `handle` wraps all); shared hooks via `app.notify.x()` / `app.ask.x()` (core names: `invalidate`, `invalidated`, `lastBuild`; declaration-merge `ServerHooks`); `ctx.facts` (`storable`, `perVisitor`, `streamed`, `private`, `answerForm`, `sources`, `assignments`; merge `RequestFacts`); the `client` module default-exports `defineClient({ boot({ kitPage }), regionMount(el, { entry, urls }), regionUnmount(el, { entry }) })` from `'ogygia/plugin/client'`. Helpers: `ogygia/plugin/utils`, `ogygia/plugin/css`, `ogygia/plugin/testing` (`startPlugin`). Docs: /docs/
|
|
307
|
+
**Writing a plugin (first-party only, UNSTABLE — no promise to outside authors):** `definePlugin({ name: '<package name>', server?: import.meta.resolve('./server.ts'), client?: import.meta.resolve('./client.ts'), options /* JSON */, enforce?, build(b) })` from `'ogygia/vite'` — it RETURNS a Vite plugin the app lists beside `ogygia()`; a factory that needs Vite hooks of its own returns `[definePlugin({…}), itsVitePlugin]`; `b.routeConfig(key)` (a key inside Kit's `config` page option, read at build, answered by `ctx.routeConfig(key)`) · `b.foreignHydrate()` · `b.macro(name, fn)` · `b.markup(source)` · `b.events({ lazy })` · `b.measure()` · `b.files(scan)` · `b.pageModules({ importers, files })`. Realms are NAMED by the plugin (no package export needed): the `server` module default-exports `defineServer({ setup(app), state(), handle(ctx, next), request, page, response, done, …sharedHooks })` from `'ogygia/plugin'` (hooks: `request`/`page` first-Response-wins, `response` may replace, `done` always, `handle` wraps all); shared hooks via `app.notify.x()` / `app.ask.x()` (core names: `invalidate`, `invalidated`, `lastBuild`; declaration-merge `ServerHooks`); `ctx.facts` (`storable`, `perVisitor`, `streamed`, `private`, `answerForm`, `sources`, `assignments`; merge `RequestFacts`); the `client` module default-exports `defineClient({ boot({ kitPage }), regionMount(el, { entry, urls }), regionUnmount(el, { entry }) })` from `'ogygia/plugin/client'`. Helpers: `ogygia/plugin/utils`, `ogygia/plugin/css`, `ogygia/plugin/testing` (`startPlugin`). Docs: /docs/core/plugins.
|
|
308
308
|
|
|
309
309
|
CLI (`@ogygia/cli`; `npx ogygia …` runs it): `npx ogygia init` · `site init` · `keys [name]` (Ed25519 pair to stdout, never a file) · `fragments <origin> [--out f|--check f]` (typed widget stubs; `--check` exits 1 on drift) · `ai` (installs this skill + MCP into `.claude/`) · `mcp` (stdio server).
|
|
310
310
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ogygia/cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.12.0",
|
|
4
4
|
"description": "The ogygia command line: init and site scaffolds, the AI skill, the MCP server, perf budgets and bisect, federation keys and catalogs",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"cli",
|
|
@@ -33,21 +33,21 @@
|
|
|
33
33
|
"access": "public"
|
|
34
34
|
},
|
|
35
35
|
"devDependencies": {
|
|
36
|
+
"@ogygia/core": "0.12.0",
|
|
37
|
+
"@ogygia/devtools": "0.12.0",
|
|
38
|
+
"@ogygia/tooling": "0.0.0",
|
|
36
39
|
"@sveltejs/sv-utils": "^0.3.3",
|
|
37
40
|
"@types/node": "^26.1.2",
|
|
38
41
|
"@typescript/native": "npm:typescript@^7.0.2",
|
|
39
42
|
"svelte": "5.56.8",
|
|
40
43
|
"tsdown": "^0.23.4",
|
|
41
44
|
"typescript": "^6.0.3",
|
|
42
|
-
"vitest": "^4.1.12"
|
|
43
|
-
"@ogygia/core": "0.11.0",
|
|
44
|
-
"@ogygia/devtools": "0.11.0",
|
|
45
|
-
"@ogygia/tooling": "0.0.0"
|
|
45
|
+
"vitest": "^4.1.12"
|
|
46
46
|
},
|
|
47
47
|
"peerDependencies": {
|
|
48
|
+
"@ogygia/core": "^0.12.0",
|
|
48
49
|
"playwright": "^1.62.0",
|
|
49
|
-
"svelte": "^5.56.8"
|
|
50
|
-
"@ogygia/core": "^0.11.0"
|
|
50
|
+
"svelte": "^5.56.8"
|
|
51
51
|
},
|
|
52
52
|
"peerDependenciesMeta": {
|
|
53
53
|
"playwright": {
|