Uh oh!
There was an error while loading. Please reload this page.
Dash-books: delete fixture mode + Phase 1 (catalog-query model, operator-config connection, CLI DX) - #7
Merged
Merged
Conversation
Removes the @modernrelay/notebook-fixture package and all fixture-mode wiring — the notebook now runs only against omnigraph-server via the SDK (no in-memory mock graph). Adds dash-books-canon.md as the project's source of truth (concept, key modules, current state, target shape) and refreshes CLAUDE/README/AGENTS to the server-only model. - delete packages/fixture; drop the notebook-fixture dep from tui/web/cli - remove top-level notebook.fixture selection + the example fixtures; tui/web/cli now build a ServerSource only - spec keeps the cell-level structured query DSL as the interim server query path (slated to become predefined-query `ref` per the canon) - docs: "server-backed runtime"; package map drops the fixture row Verified: pnpm -r build/typecheck/test green (62 tests); CLI validate/schema/catalog smoke-tested. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Move reads off the client-side query compiler and onto server-owned catalog queries invoked by name — the consistency-over-canon model from dash-books-canon.md §4.1. - spec: `query.ref` (catalog query, the default) + `query.rawGq` (gated raw-.gq escape hatch); delete the nodes/path/ego DSL + `query.fixture`; make Notebook/Cell/Query schemas `.strict()` (reject stale keys — internal tool, no version negotiation) - runtime: ReadRequest.queryRef; SourceCapabilities.namedQueries (drops structuredQueryKinds); compatibility checks ref→namedQueries, rawGq→rawGq; delete resolveFixtureQuery/resolveWhere - client: Client.invoke wraps og.queries.invoke; ServerSource routes ref→invoke / rawGq→query; delete translate.ts read translators + the ego decomposition planner (keep translateMutation for interim set_field) - demo: author examples/server/queries/*.gq (3) + register via `queries: ./queries/` in server-demo's cluster; migrate company-server.notebook.yaml cells to `query.ref` - tests rewritten for the ref/rawGq model + strict schema Read-only (Phase 1); writes stay on the interim set_field path. Verified: pnpm -r build/typecheck/test green (49 tests). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Add a Node-only resolver (`@modernrelay/notebook-client/node`) that reads omnigraph's RFC-011 operator config — so a notebook connects with zero flags once you've `omnigraph login`'d (dash-books-canon.md §4.7). - operator.ts: ~/.omnigraph/config.yaml (servers/defaults/profiles) + ~/.omnigraph/credentials (INI, 0600-enforced); `--server <name|URL>` resolves a name via the servers registry; token chain OMNIGRAPH_TOKEN_<SERVER> → credentials[server] → OMNIGRAPH_BEARER_TOKEN; honors OMNIGRAPH_HOME / OMNIGRAPH_PROFILE; drops the invented OMNIGRAPH_TOKEN / OMNIGRAPH_GRAPH_ID - exported via a /node subpath (uses node:fs; out of the browser bundle) - cli/source.ts + tui/index.tsx delegate to the shared resolver; both gain --profile. web/config.ts unchanged (browser uses the view proxy) - client gains a `yaml` dep + 7 resolver tests Verified: pnpm -r build/typecheck/test green (56 tests). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…se 1C) - `--version` / `-v` (reads packages/cli/package.json at runtime) - per-command `--help` (`notebook <cmd> --help`) with command-specific usage + the shared source-flags block; top-level HELP updated for the operator-config connection model (--server NAME|URL, --profile) - `render --watch` re-runs on notebook-file change (debounced; Ctrl-C to stop) - `omnigraph-notebook` bin alias (alongside notebook / mr-notebook) so a future Rust `omnigraph` plugin-dispatch resolves it - catalog command: replace the stale `queryKinds: [nodes,path,ego]` with the ref/rawGq query surface Deferred: live-reload `--watch` for view (browser) and tui (Ink) — needs websocket / reconciler work; tracked for a follow-up. Verified: pnpm -r build/typecheck/test green (56 tests); CLI --version/--help/validate/catalog/schema smoke-tested. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…on (Phase 1D) - CLAUDE.md / AGENTS.md: data-flow + Source sections describe `og.queries.invoke` by `ref` (and the `rawGq` escape hatch) instead of the deleted client-side DSL/translation; connection paragraph points at the shared @modernrelay/notebook-client/node operator-config resolver; drop the invented $OMNIGRAPH_GRAPH_ID; note the strict v1 schema - README.md: source-flags blurb covers --server NAME|URL + --profile and the flags → operator-config → notebook resolution order - dash-books-canon.md: tick off Phase 1 ledger items (query model, rawGq, strict schema, connection client, CLI DX, docs); mark the live-catalog validate and view/tui live-reload as partial, and the live-cluster e2e as pending Verified: pnpm -r build/typecheck/test green (56 tests). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Uh oh!
There was an error while loading. Please reload this page.
Comment on lines
67
to
+105
| @@ -172,13 +101,15 @@ const QuerySchema = z | |||
| * Shape mirrors a control cell minus `query` (controls don't fetch data; | |||
| * they read/write state via $bindState / on.press → setState). | |||
| */ | |||
| export const CellControlSchema = z.object({ | |||
| id: z.string().min(1).optional(), | |||
| lens: ControlKind, | |||
| props: z.record(z.string(), z.unknown()).default({}), | |||
| on: z.record(z.string().min(1), ActionBindingSchema).optional(), | |||
| visible: z.unknown().optional(), | |||
| }); | |||
| export const CellControlSchema = z | |||
| .object({ | |||
There was a problem hiding this comment.
query.name can be set alongside query.ref with no validation error, but is silently ignored
name is documented as "Selects a query within a multi-query rawGq payload" and is only consumed by ServerSource.read on the rawGq code path. When a cell uses query.ref, runtime.ts copies cell.query.name into ReadRequest.queryName, but ServerSource.invoke never reads it. An author who writes query: { ref: "foo", name: "bar" } will get no error and no effect. A refinement guarding name to the rawGq branch would make the constraint explicit.
Phase 2A: cell `display: drawer|modal` + `open_state` lifts detail cells into a host-shell overlay (web Drawer on base-ui Dialog; pure partitionCells in layout.ts groups cells sharing an open_state). Runtime/spec-nesting unchanged — reuses the /selected selection + applyStateChanges; the TUI stays layout-flat. Adds Timeline + Card lenses, click-to-select + wrap on Table, and fits tables to their container so the drawer doesn't overflow. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Two Phase 2 slices: - 2D in-flow grid: cell `width: full|half|third|two-thirds` maps to a span in the web host's responsive 6-column inline grid (layout.ts `widthToColSpan` → literal `md:col-span-*`; App.tsx stack → `grid md:grid-cols-6`). Default full = the old single-column stack; halves/thirds sit side-by-side. Host-shell only — the TUI stays layout-flat. - Quote lens: rows as a blockquote feed (`text_column` + a `source · meta…` citation) for highlights/annotations/comments — utterance-centric, distinct from Timeline. Web + Ink renderers; replaces the cramped highlights table. Both are host-shell/component-tier only — no runtime/spec-nesting/omnigraph change. Spec, catalog, tests, and canon updated. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Three security/canon-alignment fixes: - P1 (BFF): the `view` proxy is now authoritative for auth — it always strips client-supplied Authorization/Proxy-Authorization and injects only the server-side token; the browser no longer holds a default `devtoken`. - P2 (rawGq): the raw `.gq` escape hatch is capability-gated and off by default (`ServerSource.allowRawGq`). A notebook with a `rawGq` cell now fails compatibility unless the explicit dev/CLI hatch is enabled (`--allow-raw-gq`, threaded through args/source/view→URL/tui; web `?allowRawGq`). - P3: `Client` reads no env — dropped the invented `OMNIGRAPH_TOKEN` (and the redundant `OMNIGRAPH_BEARER_TOKEN`) fallback; token resolution lives only in the shared operator resolver. Tests + canon updated. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Evolves the web host into a single canvas of dependent cards: - Tier-1 arrange: drag-reorder (@dnd-kit) + drag-edge resize (1–6 cols), browser-local overrides in localStorage (layout-overrides.ts); @formkit/ auto-animate eases cards into place; min-w-0 so content reflows without blowing out the grid; rAF-coalesced resize. - Retire the overlay tier: remove cell `display`/`open_state` + the drawer primitive; master-detail is now in-flow dependent cards reacting to $state. - Layout: drop the redundant cell-list sidebar, widen the canvas (max-w-[96rem]), sticky header, less-rounded cards. - view server: bare URL redirects to the served notebook (no more bundled-default cross-origin CORS failure). Spec/runtime/TUI essentially unchanged (TUI ignores layout); web-host only. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Uh oh!
There was an error while loading. Please reload this page.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for freeto join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Implements
dash-books-canon.mdthrough Phase 1 (read-only). Five reviewable commits: a fixture-deletion baseline, then Phase 1A–1D.Baseline — delete fixture mode + canon (
4431942)@modernrelay/notebook-fixtureand all fixture-mode wiring; the notebook runs only against omnigraph-server via the SDK (no in-memory mock).dash-books-canon.md(concept, modules, current state, target shape, phased ledger).Phase 1A — query model (
5f94d13)Consistency over canon (§4.1): cells bind to server-owned catalog queries by name.
query.ref→og.queries.invoke(the default);query.rawGq→ ad-hocog.query(gated escape hatch).translate.tsread path, the ego planner, thenodes/path/egoDSL..gqqueries + register them in the demo cluster; migratecompany-server.notebook.yamltoref.Phase 1B — operator-config connection (
7fb956c)@modernrelay/notebook-client/noderesolver:~/.omnigraph/config.yaml+credentials(0600), named servers, keyed-token chain (OMNIGRAPH_TOKEN_<SERVER>→ credentials →OMNIGRAPH_BEARER_TOKEN), profiles. Wired into CLI + TUI; web stays on theviewproxy.Phase 1C — CLI DX (
7977709)--version, per-command--help,render --watch,omnigraph-notebookbin alias.Phase 1D — docs (
451d251)ref/rawGq+ operator-config model.Verification
pnpm -r build/typecheck/testgreen — 56 tests.validate/catalog/schema/--version/--help) smoke-tested.Deferred (tracked in the canon ledger)
notebook validate(ref/param checks viaog.queries.list()).view/tuilive-reload--watch(needs websocket / Ink-reconciler work).🤖 Generated with Claude Code
Greptile Summary
This PR implements Phase 1 of
dash-books-canon.md: it removes fixture mode entirely, migrates the cell query model from a client-side compiled DSL to server-owned catalog queries (query.ref→og.queries.invoke) with a capability-gated raw.gqescape hatch (query.rawGq), adds the Node-only operator-config resolver (~/.omnigraph/config.yaml+credentials), and delivers CLI DX improvements (--version, per-command--help,render --watch).@modernrelay/notebook-fixturewiring removed from CLI, TUI, and web;NotebookSchema/CellSchema/QuerySchemaall gain.strict()and drop thefixture/sourcekeys.packages/client/src/operator.ts): reads~/.omnigraph/config.yaml+credentials(0600-enforced), resolves named servers, profiles, and a keyed-token chain;Clientno longer reads env for tokens.App.tsxreplaced by a responsive 6-column grid with dnd-kit drag-reorder and resize;proxy.tsnow explicitly drops client-suppliedAuthorizationbefore injecting the server-side token.Confidence Score: 5/5
Safe to merge — a large but coherent refactor with no active data paths broken and 56 tests green.
The fixture-removal and query-model migration are complete end-to-end: schema, runtime, source, CLI, TUI, and web all move together. The operator-config resolver is new but isolated to Node-only entry points and has its own test coverage. The only non-trivial concern is the
as SdkReadtype assertion ininvoke(), which is a type-safety trade-off rather than a correctness issue at runtime given theexpectMutation: falseserver-side guard.packages/client/src/http.ts — the invoke() cast warrants a second look once the SDK exposes a narrowed return type.
Important Files Changed
as SdkReadcast in invoke() is the only concern.Sequence Diagram
%%{init: {'theme': 'neutral'}}%% sequenceDiagram participant CLI as CLI / TUI participant OpRes as operator.ts resolveConnection participant Config as ~/.omnigraph/config.yaml + credentials participant Client as Client (http.ts) participant Source as ServerSource participant Server as omnigraph-server CLI->>OpRes: flags + notebook.server/graph OpRes->>Config: loadOperatorConfig() + loadCredentials() Config-->>OpRes: servers, profiles, defaults, tokens OpRes-->>CLI: ResolvedConnection CLI->>Client: new Client CLI->>Source: new ServerSource Note over Source,Server: query.ref path (canonical) Source->>Client: invoke(name, params) Client->>Server: "POST /graphs/{id}/queries/{name}" Server-->>Client: Read response Client-->>Source: ReadOutput Note over Source,Server: query.rawGq path (escape hatch, gated) Source->>Client: "query({ query: rawGq })" Client->>Server: "POST /graphs/{id}/query" Server-->>Client: Read response Client-->>Source: ReadOutput%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%% sequenceDiagram participant CLI as CLI / TUI participant OpRes as operator.ts resolveConnection participant Config as ~/.omnigraph/config.yaml + credentials participant Client as Client (http.ts) participant Source as ServerSource participant Server as omnigraph-server CLI->>OpRes: flags + notebook.server/graph OpRes->>Config: loadOperatorConfig() + loadCredentials() Config-->>OpRes: servers, profiles, defaults, tokens OpRes-->>CLI: ResolvedConnection CLI->>Client: new Client CLI->>Source: new ServerSource Note over Source,Server: query.ref path (canonical) Source->>Client: invoke(name, params) Client->>Server: "POST /graphs/{id}/queries/{name}" Server-->>Client: Read response Client-->>Source: ReadOutput Note over Source,Server: query.rawGq path (escape hatch, gated) Source->>Client: "query({ query: rawGq })" Client->>Server: "POST /graphs/{id}/query" Server-->>Client: Read response Client-->>Source: ReadOutputComments Outside Diff (1)
packages/web/src/config.ts, line 35-47 (link)notebook.servercan now be an operator-config name, producing a confusing error in the browserNotebookSchema.serverwas widened fromz.url()toz.string().min(1)to allow operator-config server names (e.g.server: prod). InbuildConfig,notebook.serveris the fallback when no?server=URL param is present. If a CLI-targeted notebook hasserver: "prod", this code passes"prod"tonew Client({ baseUrl: "prod" }), which fails at the SDK layer with an opaque fetch error rather than a clear schema validation message. The previousz.url()constraint would have caught this at parse time.Reviews (4): Last reviewed commit: "Interactive canvas: drag/resize tiles, r..." | Re-trigger Greptile