Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
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
6 changes: 3 additions & 3 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ This file provides guidance to Codex (Codex.ai/code) when working with code in t

Turn an OmniGraph graph database into a **read-and-act dashboard you describe in one YAML file** — rendered identically in a terminal and a browser.

Normally you inspect a graph by writing queries and reading JSON, or by building a bespoke UI. A notebook is the layer between: a YAML file that *declares what slices of the graph to show and what actions to allow*, not code. Each cell is a typed lens (`Table`/`Path`/`Subgraph`/`ActionList`) fed by a structured query, or a control (`Select`/`Toggle`/`Button`) that filters state or mutates the graph. See `examples/company-server.notebook.yaml`: a status filter, a decisions table, a `Signal → Decision → Actor` path, an ego subgraph, and a clause list with inline Approve/Reject buttons — no UI code anywhere.
Normally you inspect a graph by writing queries and reading JSON, or by building a bespoke UI. A notebook is the layer between: a YAML file that *declares what slices of the graph to show and what actions to allow*, not code. Each data cell is a typed lens (`Table`/`Path`/`Subgraph`/`ActionList`/`Timeline`/`Card`/`Quote`/`Text`) fed by `query.ref` to a server-owned `.gq` catalog query, or a control (`Select`/`Toggle`/`Button`) that filters state or dispatches actions. See `examples/company-server.notebook.yaml`: a clause review list with inline Approve/Reject buttons, a decisions table, and a `Signal → Decision` path — no UI code anywhere.

Two bets make it work:

Expand All @@ -30,7 +30,7 @@ pnpm --filter @modernrelay/notebook-<pkg> test -- <pattern> # single test file/n
pnpm tui examples/company-server.notebook.yaml # Ink TUI, server mode — server URL + graph id
# come from the notebook (run server-demo.sh first)
pnpm --filter @modernrelay/notebook-web dev # Vite dev server at 127.0.0.1:5173
# add ?mode=server&server=/og (same-origin proxy)
# add ?server=/og&graph=company (same-origin proxy)
pnpm --filter @modernrelay/notebook-web build # tsc + vite production build

scripts/server-demo.sh # build omnigraph v0.7.0 CLI/server, boot a local
Expand All @@ -48,7 +48,7 @@ The TUI consumes built `dist/` from sibling workspace packages — **always run
| Package | Role |
|---|---|
| `@modernrelay/notebook-core` | The engine — start here. One package, three internal modules: `spec` (Zod schemas + YAML parser, query model — `ref`/`rawGq` — mutation specs), `catalog` (component+action definitions shared by both renderers; `assembleLensSpec` / `assembleControlSpec` produce json-render specs), `runtime` (capability-aware execution, state mirror, dependency invalidation, action dispatch, mutation lifecycle, optimistic reconciliation). The `@json-render/core` analog. |
| `@modernrelay/notebook-client` | **The only data source.** `ServerSource` + `translate` (structured DSL → `.gq`) + a `Client` facade over the `@modernrelay/omnigraph` SDK (`/query` + `/mutate`, graph-scoped). |
| `@modernrelay/notebook-client` | **The only data source.** `ServerSource` + a `Client` facade over the `@modernrelay/omnigraph` SDK (`/queries/{name}` + `/query` escape hatch + `/mutate`, graph-scoped). `translateMutation` exists only for the interim `set_field` write path. |
| `@modernrelay/notebook-tui` | Ink renderer + CLI entry (`bin/omnigraph-tui.js`); host shell for terminal. |
| `@modernrelay/notebook-web` | Vite + React + Tailwind renderer; host shell for browser. |
| `@modernrelay/notebook` (`packages/cli`) | The published front-door CLI. Bundles every `@modernrelay/notebook-*` lib (tsup, `noExternal`) and ships the built web SPA in `web-dist/`. Subcommands: `view` (browser — static server + `/og` BFF proxy with server-side token injection, reusing `web/src/config.ts`'s URL-param contract), `tui` (calls `@modernrelay/notebook-tui` `main`), `validate`/`render`/`catalog`/`schema` (agent-DX, JSON out; schema via Zod 4 `z.toJSONSchema`). The workspace root is the private `notebook-workspace`; `@modernrelay/notebook` is the CLI, not the root. |
Expand Down
6 changes: 3 additions & 3 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co

Turn an OmniGraph graph database into a **read-and-act dashboard you describe in one YAML file** — rendered identically in a terminal and a browser.

Normally you inspect a graph by writing queries and reading JSON, or by building a bespoke UI. A notebook is the layer between: a YAML file that *declares what slices of the graph to show and what actions to allow*, not code. Each cell is a typed lens (`Table`/`Path`/`Subgraph`/`ActionList`) fed by a structured query, or a control (`Select`/`Toggle`/`Button`) that filters state or mutates the graph. See `examples/company-server.notebook.yaml`: a status filter, a decisions table, a `Signal → Decision → Actor` path, an ego subgraph, and a clause list with inline Approve/Reject buttons — no UI code anywhere.
Normally you inspect a graph by writing queries and reading JSON, or by building a bespoke UI. A notebook is the layer between: a YAML file that *declares what slices of the graph to show and what actions to allow*, not code. Each data cell is a typed lens (`Table`/`Path`/`Subgraph`/`ActionList`/`Timeline`/`Card`/`Quote`/`Text`) fed by `query.ref` to a server-owned `.gq` catalog query, or a control (`Select`/`Toggle`/`Button`) that filters state or dispatches actions. See `examples/company-server.notebook.yaml`: a clause review list with inline Approve/Reject buttons, a decisions table, and a `Signal → Decision` path — no UI code anywhere.

Two bets make it work:

Expand All @@ -30,7 +30,7 @@ pnpm --filter @modernrelay/notebook-<pkg> test -- <pattern> # single test file/n
pnpm tui examples/company-server.notebook.yaml # Ink TUI, server mode — server URL + graph id
# come from the notebook (run server-demo.sh first)
pnpm --filter @modernrelay/notebook-web dev # Vite dev server at 127.0.0.1:5173
# add ?mode=server&server=/og (same-origin proxy)
# add ?server=/og&graph=company (same-origin proxy)
pnpm --filter @modernrelay/notebook-web build # tsc + vite production build

scripts/server-demo.sh # build omnigraph v0.7.0 CLI/server, boot a local
Expand All @@ -48,7 +48,7 @@ The TUI consumes built `dist/` from sibling workspace packages — **always run
| Package | Role |
|---|---|
| `@modernrelay/notebook-core` | The engine — start here. One package, three internal modules: `spec` (Zod schemas + YAML parser, query model — `ref`/`rawGq` — mutation specs), `catalog` (component+action definitions shared by both renderers; `assembleLensSpec` / `assembleControlSpec` produce json-render specs), `runtime` (capability-aware execution, state mirror, dependency invalidation, action dispatch, mutation lifecycle, optimistic reconciliation). The `@json-render/core` analog. |
| `@modernrelay/notebook-client` | **The only data source.** `ServerSource` + `translate` (structured DSL → `.gq`) + a `Client` facade over the `@modernrelay/omnigraph` SDK (`/query` + `/mutate`, graph-scoped). |
| `@modernrelay/notebook-client` | **The only data source.** `ServerSource` + a `Client` facade over the `@modernrelay/omnigraph` SDK (`/queries/{name}` + `/query` escape hatch + `/mutate`, graph-scoped). `translateMutation` exists only for the interim `set_field` write path. |
| `@modernrelay/notebook-tui` | Ink renderer + CLI entry (`bin/omnigraph-tui.js`); host shell for terminal. |
| `@modernrelay/notebook-web` | Vite + React + Tailwind renderer; host shell for browser. |
| `@modernrelay/notebook` (`packages/cli`) | The published front-door CLI. Bundles every `@modernrelay/notebook-*` lib (tsup, `noExternal`) and ships the built web SPA in `web-dist/`. Subcommands: `view` (browser — static server + `/og` BFF proxy with server-side token injection, reusing `web/src/config.ts`'s URL-param contract), `tui` (calls `@modernrelay/notebook-tui` `main`), `validate`/`render`/`catalog`/`schema` (agent-DX, JSON out; schema via Zod 4 `z.toJSONSchema`). The workspace root is the private `notebook-workspace`; `@modernrelay/notebook` is the CLI, not the root. |
Expand Down
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,15 @@
npm i -g @modernrelay/notebook # or: npx @modernrelay/notebook view my.notebook.yaml
```

Notebook UI for [OmniGraph](https://github.com/ModernRelay/omnigraph). Each notebook cell is a typed *lens primitive* (Table, Path, Subgraph) rendered from a structured query — not a generic graph viewer.
Notebook UI for [OmniGraph](https://github.com/ModernRelay/omnigraph). Each notebook cell is a typed *lens primitive* (Table, Path, Subgraph) rendered from a server-owned catalog query — not a generic graph viewer.

One catalog of components, two renderers (terminal and web), one server-backed runtime.

## What it's for

Turn an OmniGraph graph database into a **read-and-act dashboard you describe in one YAML file** — rendered identically in a terminal and a browser.

Normally you inspect a graph by writing queries and reading JSON, or by building a bespoke UI. A notebook is the layer between: a YAML file that *declares what slices of the graph to show and what actions to allow*, not code. Each cell is a typed lens (`Table`/`Path`/`Subgraph`/`ActionList`) fed by a structured query, or a control (`Select`/`Toggle`/`Button`) that filters state or mutates the graph. See `examples/company-server.notebook.yaml`: a status filter, a decisions table, a `Signal → Decision → Actor` path, an ego subgraph, and a clause list with inline Approve/Reject buttons — no UI code anywhere.
Normally you inspect a graph by writing queries and reading JSON, or by building a bespoke UI. A notebook is the layer between: a YAML file that *declares what slices of the graph to show and what actions to allow*, not code. Each data cell is a typed lens (`Table`/`Path`/`Subgraph`/`ActionList`/`Timeline`/`Card`/`Quote`/`Text`) fed by `query.ref` to a server-owned `.gq` catalog query, or a control (`Select`/`Toggle`/`Button`) that filters state or dispatches actions. See `examples/company-server.notebook.yaml`: a clause review list with inline Approve/Reject buttons, a decisions table, and a `Signal → Decision` path — no UI code anywhere.

Two bets make it work:

Expand Down Expand Up @@ -77,7 +77,7 @@ pnpm --filter @modernrelay/notebook build # bundle the CLI (tsup) + web-d

| Package | Purpose |
|---|---|
| `@modernrelay/notebook-core` | The engine — start here. Three modules behind one entry: `spec` (Zod YAML schemas + query DSL), `catalog` (`lensComponents`/`lensActions` + `assembleLensSpec`), `runtime` (capability-aware execution, state, mutations). The `@json-render/core` analog. |
| `@modernrelay/notebook-core` | The engine — start here. Three modules behind one entry: `spec` (Zod YAML schemas + `ref`/`rawGq` query model), `catalog` (`lensComponents`/`lensActions` + `assembleLensSpec`), `runtime` (capability-aware execution, state, mutations). The `@json-render/core` analog. |
| `@modernrelay/notebook-client` | The only data source — `ServerSource` + a `Client` facade over the `@modernrelay/omnigraph` SDK. |
| `@modernrelay/notebook-tui` | Ink renderer + the `omnigraph-tui` binary. |
| `@modernrelay/notebook-web` | Vite + React + Tailwind v4 SPA. |
Expand Down
20 changes: 12 additions & 8 deletions dash-books-canon.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
one typed result contract in a browser and a terminal.**

A "dash-book" is a notebook: a YAML document whose cells are typed **lenses** (`Table`, `Path`,
`Subgraph`, `ActionList`, `Timeline`, `Card`, `Quote`) and **controls** (`Button`, `Toggle`, `Select`). You declare *what slice of
`Subgraph`, `ActionList`, `Timeline`, `Card`, `Quote`, `Text`) and **controls** (`Button`, `Toggle`, `Select`). You declare *what slice of
the graph to show and what actions to allow*; you never write UI code. The same YAML drives a
React/Tailwind web renderer and an Ink terminal renderer from one shared result contract. The browser
is the first-class rich renderer; the terminal is a useful degradation over the same data and action
Expand Down Expand Up @@ -68,11 +68,10 @@ json-render spec each renderer draws.
- **0.7 cluster-only.** omnigraph-server 0.7.0+ serves every graph under `/graphs/{graph}/…`, so server
mode requires a graph id. Connection today is ad-hoc: `--server <URL>` / `--graph` / `--token`
(+ a few env vars).
- **Interim wart — client still generates queries.** Cells still carry the structured query DSL
(`query.fixture` = `nodes`/`path`/`ego`), which `ServerSource` compiles to ad-hoc `.gq` via
`translate.ts` (incl. ego decomposition + identifier-sanitizing regexes) and ships as
`og.query({ query })`. This is the thing §4 removes. The field is still named `fixture` for
historical reasons; that rename rides along with the §4 work.
- **Named-query reads by default.** Cells bind to server-owned catalog queries with `query.ref`;
`ServerSource` invokes them via `og.queries.invoke`. The removed `nodes`/`path`/`ego` DSL no
longer exists. Inline `rawGq` is a capability-gated escape hatch, off by default. The remaining
client-side `.gq` compiler is only the deferred interim `set_field` mutation path.

---

Expand Down Expand Up @@ -264,8 +263,9 @@ strict, single-version schema is safe; no version negotiation or legacy-v1 suppo
`Authorization`/`Proxy-Authorization` and injects only the server-side token; the browser holds no
default token (no `devtoken`); the `Client` reads no env (resolution lives only in the operator
resolver — `OMNIGRAPH_TOKEN`/`OMNIGRAPH_GRAPH_ID` are gone).
- [~] `notebook validate` parses + capability-checks; resolving `ref`/params against the live catalog
(`og.queries.list()`) is still TODO (needs a reachable server).
- [x] `notebook validate` parses + capability-checks and resolves `ref`/literal params against the
live catalog (`og.queries.list()`); dynamic `$state` params are checked for presence, with
literal defaults type-checked when present.
- [x] Strict schema; rejects stale fixture-mode keys (internal tool — no version support).
- [x] Operator-config connection client (shared `@modernrelay/notebook-client/node` resolver:
config.yaml + credentials, named servers, keyed tokens, profiles; browser uses the `view` proxy).
Expand Down Expand Up @@ -299,6 +299,10 @@ the auto tier and output-binding validation; until it ships, v1 uses author-decl
- [x] **Quote lens.** Renders rows as a blockquote feed — `text_column` + a `source_column · meta…`
citation (`refs/r2.jpg`) — for highlights/annotations/comments. Utterance-centric, distinct from
Timeline (event feed). Replaces the cramped 2-column highlights table; web + Ink renderers.
- [x] **Text lens.** Renders the first row's `text_column` as **Markdown** (`title_column` optional
heading) — a node's definition/notes/body as a prose block. Web uses `react-markdown` (raw HTML
off → XSS-safe; links open in a new tab); the TUI shows the raw Markdown source. Distinct from
Card (labeled fields) and Quote (citation feed).
- [x] **Interactive arrange (Tier 1).** An "Edit layout" toggle lets you drag-reorder cells (a handle;
`@dnd-kit` sortable) and drag a cell's right edge to resize its column span (1–6; raw pointer
events). It's a **browser-local override** of the declared order/`width`, persisted to
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"name": "notebook-workspace",
"version": "0.0.1",
"private": true,
"description": "Monorepo for @modernrelay/notebook — typed lens primitives over an omnigraph fixture or live cluster, rendered to terminal and web from one json-render catalog. The published CLI lives in packages/cli.",
"description": "Monorepo for @modernrelay/notebook — typed lens primitives over server-owned omnigraph catalog queries, rendered to terminal and web from one json-render catalog. The published CLI lives in packages/cli.",
"license": "Apache-2.0",
"packageManager": "pnpm@10.30.3",
"engines": {
Expand Down
4 changes: 4 additions & 0 deletions packages/cli/src/commands/catalog.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ import {
TableAuthorPropsSchema,
TimelineAuthorPropsSchema,
CardAuthorPropsSchema,
QuoteAuthorPropsSchema,
TextAuthorPropsSchema,
} from "@modernrelay/notebook-core";
import type { ZodType } from "zod";
import { z } from "zod";
Expand All @@ -22,6 +24,8 @@ const AUTHOR_PROPS: Record<string, ZodType> = {
ActionList: ActionListAuthorPropsSchema,
Timeline: TimelineAuthorPropsSchema,
Card: CardAuthorPropsSchema,
Quote: QuoteAuthorPropsSchema,
Text: TextAuthorPropsSchema,
};

/**
Expand Down
Loading
Loading