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
47 changes: 32 additions & 15 deletions content/guides/editor.md
Original file line number Diff line number Diff line change
Expand Up @@ -157,9 +157,14 @@ actual size.

Named buttons open the target file. **Run impact on this page** fills the
impact field and runs the same `boris impact` command as the Problems pane.
`Ctrl+K` also jumps to an entity by id or title (`Go to guides/intro`).
**Export graph** runs the fixed `boris graph` command (Mermaid by default,
Graphviz DOT as the documented second option) and offers copy or download of
that document. The map is not a second layout engine. `Ctrl+K` also jumps to
an entity by id or title (`Go to guides/intro`).

If diagnostics have not been built yet, the pane says so instead of guessing.
If diagnostics have not been built yet, the pane says so instead of guessing,
and Export graph stays disabled until **Build diagnostics** has produced a
graph.

- [[guides/building-pages|Building and writing pages]] — parent, children, and wiki links
- [[reference/relationships|Relationships]] — parent, children, and relations this pane displays
Expand Down Expand Up @@ -211,9 +216,11 @@ targets. That command does not compile or publish.

Local evidence at `dist/_boris/proof/proof-pack.json` is shown when a previous
HTML build left a Proof Pack. That pack is target-local presentation. It is
not deployment verification. GitHub Pages deploy stays in the official
Actions workflow; Standard.site publish stays on the CLI. The editor does not
store secrets or run a deployer.
not deployment verification. **Verify proof** runs the fixed
`boris proof verify --html-dir dist` command and surfaces the contracted
stderr verdict plus the compiler exit class. GitHub Pages deploy stays in the
official Actions workflow; Standard.site publish stays on the CLI. The editor
does not store secrets or run a deployer.

- [[guides/publishing|Publishing targets]] — profile, plan, and verified targets

Expand All @@ -224,16 +231,26 @@ store secrets or run a deployer.
The Problems pane runs a fixed allowlist of Boris invocations against saved
repository files. The UI cannot supply argv or a working directory, and all
controls are disabled while the active buffer is dirty (Boris reads files from
disk, not from your buffer).

| Button | Exact Boris invocation | Reads |
|---|---|---|
| Validate project | `boris validate --input content` | nothing |
| Build diagnostics | `boris build --input content --out .boris` | `build-report.json` |
| Build HTML | `boris build --input content --html-dir dist` | nothing yet (see below) |
| Check graph | `boris check --input content --format json --report .boris/editor-check.json` | Documentation Intelligence report |
| Run impact | `boris impact <id> --input content --format json --report .boris/editor-impact.json` | Documentation Intelligence report |
| Run publication plan | `boris plan --profile PATH` | stdout `boris-publication-plan` |
disk, not from your buffer). The table below is the standing CLI to editor
capability matrix — the map for what is in the editor, what is still missing,
and what is a deliberate non-goal. The developer copy lives in the
[editor README](https://github.com/drawmeanelephant/boris/blob/main/editor/README.md#cli-to-editor-capability-matrix).

| Button | Exact Boris invocation | Status | Reads |
|---|---|---|---|
| Validate project | `boris validate --input content` | done | HTML build report (daemon when `--watch` exists) |
| Build diagnostics | `boris build --input content --out .boris` | done | `build-report.json` |
| Build HTML | `boris build --input content --html-dir dist` | done | `html-build-report.json` |
| Check graph | `boris check --input content --format json --report .boris/editor-check.json` | done | Documentation Intelligence report |
| Run impact | `boris impact <id> --input content --format json --report .boris/editor-impact.json` | done | Documentation Intelligence report |
| Run publication plan | `boris plan --profile PATH` | done | stdout `boris-publication-plan` |
| Scale recipe | `boris recipe-scale --input content --id ID --factor FACTOR` | done | stdout `boris-recipe-scale` |
| Export graph | `boris graph --input content --format mermaid\|dot` | done | stdout Mermaid or DOT |
| Verify proof | `boris proof verify --html-dir dist` | done | contracted stderr verdict |
| Watch daemon | `boris watch --input content --html-dir dist --watch-json` | partial | NDJSON event stream |
| IR / RAG / context / llms / rss / sitemap | — | missing | stay on the CLI |
| `standard-site *` / `nostr *` publish or login | — | non-goal | no secrets, no deploy |
| `init`, full build flag matrix, `serve` | — | non-goal | preview is the `serve` fallback |

Boris exit codes stay distinct: **1** content/graph failure, **2**
usage/configuration failure, **3** I/O/system failure. The editor surfaces the
Expand Down
3 changes: 3 additions & 0 deletions docs/changelog.d/987-editor-cli-surface.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
### Added

- The editor now documents a CLI to editor capability matrix and allowlists two more read-only Boris commands: **Export graph** (`boris graph`, Mermaid by default or Graphviz DOT) and **Verify proof** (`boris proof verify --html-dir dist`), while conflict compare panes open at the top of both columns. Links: [the editor-host contract](/docs/contracts/editor-host.md), [the editor README matrix](/editor/README.md#cli-to-editor-capability-matrix), [#983](https://github.com/drawmeanelephant/boris/issues/983), [#984](https://github.com/drawmeanelephant/boris/issues/984), [#985](https://github.com/drawmeanelephant/boris/issues/985), [#986](https://github.com/drawmeanelephant/boris/issues/986).
21 changes: 18 additions & 3 deletions docs/contracts/editor-host.md
Original file line number Diff line number Diff line change
Expand Up @@ -408,7 +408,7 @@ project-keyed and stable: two projects never share a state root.
### 6.1 Fixed allowlist

The UI cannot supply argv or a working directory. `/api/commands/run` accepts
one of seven modes and the host builds the exact command; every child runs with
one of nine modes and the host builds the exact command; every child runs with
cwd = project root, a 120 s timeout, and 16 MiB stdout/stderr ceilings.

| `mode` | Fixed argv (prefixed by the resolved compiler path) |
Expand All @@ -420,9 +420,15 @@ cwd = project root, a 120 s timeout, and 16 MiB stdout/stderr ceilings.
| `impact` | `impact <impact_id> --input content --format json --report .boris/editor-impact.json` |
| `plan` | `plan --profile <profile>` |
| `recipe_scale` | `recipe-scale --input content --id <id> --factor <factor>` |
| `graph_export` | `graph --input content --format mermaid\|dot` |
| `proof_verify` | `proof verify --html-dir dist` |

The status of each CLI surface in the editor (done / partial / missing /
non-goal) lives in the [CLI to editor capability matrix](../../editor/README.md#cli-to-editor-capability-matrix).

When project discovery reports `input_mode: cooklang`, `--cooklang` is appended
to every mode except `plan` (mode parity with the one-shot CLI). A timeout or a
to every mode except `plan` and `proof_verify` (mode parity with the one-shot
CLI; proof verify reads committed checks and does not compile). A timeout or a
stdout/stderr overrun yields a `terminated` process problem, not an API error.

`validate` is served by the managed validation daemon whenever the compiler
Expand All @@ -437,6 +443,7 @@ which path answered.
| `impact_id` | Required for `impact`; forbidden for every other mode. 1–4096 bytes, valid UTF-8, no NUL/CR/LF, and must not start with `-` (so an id can never become an option). |
| `profile` | Required for `plan`; forbidden otherwise. Author-owned relative source path (≤1024 bytes), same option-injection guard. |
| `recipe_scale_id`, `recipe_scale_factor` | Required for `recipe_scale`; forbidden otherwise. Same guards; factor is trimmed, 1–64 bytes, and must not start with `-`. |
| `graph_format` | Optional for `graph_export` (`mermaid` or `dot`; omitted means `mermaid`); forbidden for every other mode. |

Violations are `400 invalid_command_request`.

Expand All @@ -448,7 +455,8 @@ The result payload is:
{"mode":"validate","exit_code":0,"failure_class":"success",
"compiler_id":"boris/0.8.2","report_version":"html-build-report-0.2.0",
"used_stderr_fallback":false,"problems":[],"findings":[],"impact":[],
"publication_plan":null,"recipe_scale_view":null}
"publication_plan":null,"recipe_scale_view":null,
"graph_document":null,"proof_report":null}
```

- `failure_class` maps the compiler's contracted exit convention —
Expand Down Expand Up @@ -477,6 +485,13 @@ The result payload is:
- `plan` and `recipe_scale` results carry `publication_plan` and
`recipe_scale_view` respectively, forwarded as parsed Boris documents,
only on a successful exit.
- `graph_export` results carry `graph_document`, the exact Mermaid or DOT
stdout from `boris graph`, only on a successful exit. The host does not
re-layout or rewrite that document.
- `proof_verify` results carry `proof_report`, a cleaned copy of the
contracted stderr verdict. `used_stderr_fallback` stays false: stderr is
the product report, not a compatibility fallback. The command mutates
nothing.

A stale artifact must never be mistaken for this run's output: the host deletes
the report named in the table above before spawning the child, for every mode
Expand Down
40 changes: 36 additions & 4 deletions editor/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -228,11 +228,40 @@ dialogs, conflict comparison, and recovered-state labeling.
M2 deliberately does not invoke Boris, parse frontmatter or Markdown, provide
completion, autosave, Git integration, diagnostics, or preview.

## CLI to editor capability matrix

The editor is a closed allowlist of Boris invocations, not a second compiler
or a deploy console. This table is the map for allowlist growth. Wire argv
lives in [`docs/contracts/editor-host.md`](../docs/contracts/editor-host.md)
§6; this table records whether a CLI surface has an editor entrypoint.

| CLI / surface | Editor entrypoint | Status | Notes |
|---|---|---|---|
| `validate` | Problems → Validate project | done | Served by the validation daemon when the compiler advertises `--watch`. |
| `build --out .boris` | Problems → Build diagnostics | done | Creates `graph.json` / completion for the Graph pane. |
| `build --html-dir dist` | Problems → Build HTML; Preview → Rebuild preview | done | Preview uses the fixed incremental rebuild, not the full flag matrix. |
| `check` | Problems → Check graph | done | |
| `impact` | Problems / Graph → Run impact | done | |
| `plan --profile` | Publication → Run publication plan | done | Declaration only; not a deploy. |
| `recipe-scale` | Recipe pane → Scale recipe | done | Compiler-owned view; the editor does not multiply amounts. |
| `graph` (Mermaid / DOT) | Graph → Export graph | done | Default Mermaid, optional Graphviz DOT. Boris remains the renderer. |
| Graph map of frozen `graph.json` | Graph pane map | related | Visual aid of the last IR graph; not the `boris graph` CLI. |
| `proof verify` | Problems / Publication → Verify proof | done | Read-only; default policy; no credentials. |
| `watch` / Watch daemon | Watch pane | partial | Host-managed start/stop/event stream for the fixed `boris watch --watch-json` argv. Not the full watch flag matrix. |
| IR / RAG / context / llms / rss / sitemap exports | — | missing | Stay on the CLI until a later allowlisted wrapper. |
| `standard-site *` / `nostr *` publish or login | — | non-goal | No secrets and no deploy in the editor. |
| `init` | — | non-goal | Project bootstrap stays a CLI / `boris init` concern. |
| Full `build` flag matrix | — | non-goal | Each mode has one host-fixed argv. |
| `serve` | Preview origin | non-goal | Loopback preview of committed `dist/` is the fallback while compiler-owned `boris serve` is in flight. |

Statuses are `done`, `partial`, `missing`, or `non-goal`. Non-goals stay
non-goals until a contract change says otherwise.

## M3 Boris commands and problems

The host exposes one authenticated `POST /api/commands/run` endpoint backed by
a fixed command allowlist: validate, IR build, HTML build, check, impact,
plan, and recipe-scale.
plan, recipe-scale, graph export, and proof verify.
The UI cannot supply argv or a working directory. Commands run against saved
repository files, so all controls are disabled while the active buffer is
dirty.
Expand Down Expand Up @@ -459,7 +488,9 @@ and node borders scale with topology (direct children plus incoming
references). The SVG is `aria-hidden` — it is a pointer convenience, and the
lists remain the keyboard path. The map viewport is a focusable scroll
container (wheel, touch, arrow keys), and its zoom controls fit the graph to
the pane width, zoom in and out, or restore actual size.
the pane width, zoom in and out, or restore actual size. **Export graph**
runs the fixed `boris graph` invocation (Mermaid by default, DOT as the
second option) and offers copy or download of that document.

The diagnostics integration gate deep-compares `/api/graph` with the real
compiler-generated `graph.json`. Playwright covers parent/backlink/wiki-link
Expand All @@ -472,8 +503,9 @@ model, heading-fragment navigation, or theme/layout diagnostics.
## M7 Cooklang / restaurant authoring

A content tree of only `.cook` pages is a Cooklang project. Health reports
`input_mode: cooklang`, and every fixed Boris invocation (validate, IR/HTML
build, check, impact, preview) adds `--cooklang`. Mixed trees stay mixed and
`input_mode: cooklang`, and every fixed Boris invocation that compiles the
tree (validate, IR/HTML build, check, impact, preview, graph export) adds
`--cooklang`. `plan` and `proof verify` do not. Mixed trees stay mixed and
fail the way Boris fails; the editor does not guess a dialect.

The Recipe pane is a read-only view of the compiler `recipe` facet on
Expand Down
23 changes: 23 additions & 0 deletions editor/scripts/test-diagnostics.sh
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,20 @@ node -e '
if (r.exit_code !== 0 || r.failure_class !== "success" || r.used_stderr_fallback || !r.report_version || !Array.isArray(r.findings)) throw Error("check artifact adaptation mismatch");
' "$work/check-valid.json"

run_command "$work/graph-export.json" '{"mode":"graph_export"}'
node -e '
const r = require(process.argv[1]);
if (r.mode !== "graph_export" || r.exit_code !== 0 || r.failure_class !== "success") throw Error("graph export failed: " + JSON.stringify({mode:r.mode,exit:r.exit_code,cls:r.failure_class}));
if (typeof r.graph_document !== "string" || r.graph_document.indexOf("graph TD") < 0) throw Error("expected mermaid document, got " + JSON.stringify(r.graph_document && r.graph_document.slice(0, 80)));
if (r.used_stderr_fallback) throw Error("graph export should not be a stderr fallback");
' "$work/graph-export.json"

run_command "$work/graph-export-dot.json" '{"mode":"graph_export","graph_format":"dot"}'
node -e '
const r = require(process.argv[1]);
if (r.exit_code !== 0 || typeof r.graph_document !== "string" || r.graph_document.indexOf("digraph") < 0) throw Error("expected DOT document");
' "$work/graph-export-dot.json"

run_command "$work/impact-missing.json" '{"mode":"impact","impact_id":"does-not-exist"}'
node -e '
const r = require(process.argv[1]);
Expand Down Expand Up @@ -133,4 +147,13 @@ node -e '
' "$work/html-valid.json" "$work/project/.boris/html-build-report.json"
[[ -f "$work/project/dist/index.html" ]]

run_command "$work/proof-verify.json" '{"mode":"proof_verify"}'
node -e '
const r = require(process.argv[1]);
if (r.mode !== "proof_verify") throw Error("proof verify mode not echoed: " + JSON.stringify(r));
if (r.used_stderr_fallback) throw Error("proof verify stderr is the contracted report, not a fallback");
if (typeof r.proof_report !== "string" || r.proof_report.indexOf("proof verify") < 0) throw Error("expected proof verify report, got " + JSON.stringify(r.proof_report));
if (![0, 1, 3].includes(r.exit_code)) throw Error("unexpected proof verify exit: " + r.exit_code);
' "$work/proof-verify.json"

echo "editor Boris diagnostics integration: ok"
Loading