/api/pages
27 routes under /api/pages.
Cockpit server REST reference, next.
All routes sit below the Cockpit server's session gate (app.use('/api', auth.requireSession)) except /api/health. Generated from the real route table in ui/server/src.
GET /api/pages#
Source: ui/server/src/index.mjs.
GET /api/pages/all#
every page of the project for the Pages screen's Browser list (read-only).
Source: ui/server/src/index.mjs.
POST /api/pages/automap#
| Parameter | In | Type |
|---|---|---|
feature |
body | — |
file |
body | — |
nodeId |
body | — |
propNames |
body | — |
contentHash |
body | — |
Source: ui/server/src/index.mjs.
GET /api/pages/changes#
last external change to a page file, as a diff. The client polls this; each poll observes the file, so a write from an agent/CLI/other editor (anything that didn't go through saveAndRespond) shows up here. Same resolvePageFile scope guard as every other route.
Source: ui/server/src/index.mjs.
POST /api/pages/changes/dismiss#
| Parameter | In | Type |
|---|---|---|
feature |
body | — |
file |
body | — |
Source: ui/server/src/index.mjs.
GET /api/pages/features#
Source: ui/server/src/index.mjs.
GET /api/pages/git-status#
tree-row dot -- whether the open page file differs from main (packages/engine/gitTrees.mjs, the same read-only block prHealth already uses).
Source: ui/server/src/index.mjs.
GET /api/pages/impact#
Inspector "Impact" section -- which other features are reached if this page file changes (packages/engine/impact.mjs, the same block componentUsedBy already seeds with one file).
Source: ui/server/src/index.mjs.
POST /api/pages/lint#
live diagnostics for an unsaved buffer in the code drill-down (the Monaco source view's "type an edit, see the marker without saving" ask).
| Parameter | In | Type |
|---|---|---|
feature |
body | — |
file |
body | — |
source |
body | — |
Source: ui/server/src/index.mjs.
GET /api/pages/node#
Source: ui/server/src/index.mjs.
POST /api/pages/node#
| Parameter | In | Type |
|---|---|---|
feature |
body | — |
file |
body | — |
nodeId |
body | — |
snippet |
body | — |
contentHash |
body | — |
Source: ui/server/src/index.mjs.
GET /api/pages/palette#
(Slice 1 of 's design) -- read-only Palette tab: the Providers/Expressions/Components pages in this feature could actually import, computed from the real canImport graph (packages/engine/palette.mjs). Feature-scoped, not file-scoped: identical for every page in the same feature, so the client recomputes it only when the open feature changes.
Source: ui/server/src/index.mjs.
POST /api/pages/palette/insert#
(Slice 2 of 's design) -- click a Component/Provider entry in the read-only Palette to insert its real import + usage at the end of the currently open page. kind/name/path are only a LOOKUP KEY: the actual entry inserted is re-derived from a fresh buildPalette call for this page's own feature (never the client-sent object verbatim), the same "never trust a client-named path directly" discipline componentsApi.mjs's pick() already uses. Goes through the same enforcement gate (saveAndRespond) as every other Pages editor write.
| Parameter | In | Type |
|---|---|---|
feature |
body | — |
file |
body | — |
kind |
body | — |
name |
body | — |
path |
body | — |
contentHash |
body | — |
Source: ui/server/src/index.mjs.
POST /api/pages/palette/wrap#
confirm ("Approve") one Wrap-with: re-derives the same flagged hit from nodeId (never a client-sent range/offset) and calls the real, non-dry-run extractExpression(), which writes the page plus a new Expression (and, if native markup was hoisted out, one or more new Components). No checkEnforcement gate here (unlike every other Pages editor write): extractExpression.mjs's own contract is to satisfy EXPR-004/005/006 BY CONSTRUCTION, and checkEnforcement itself assumes the file it patches already exists on disk, which a brand-new Expression/Component file does not -- construct refactor extract-expression's CLI form validates and reports the same way (writes, then reports any violation found), which this mirrors instead of inventing a second gate shape.
| Parameter | In | Type |
|---|---|---|
feature |
body | — |
file |
body | — |
nodeId |
body | — |
name |
body | — |
contentHash |
body | — |
Source: ui/server/src/index.mjs.
GET /api/pages/palette/wrap-suggest#
(Slice 3 of 's design, docs/design/block-palette.md section 3) -- "Wrap with...": given a JSX selection (nodeId, from the same tree/preview selection every other tab already uses), does it fall inside a PAGE-008-flagged conditional/loop, does an existing Expression in scope structurally fit it, and -- once a name is available -- a real dry-run preview of exactly what construct refactor extract-expression would write. Read-only: dryRun: true throughout, nothing here ever touches disk (the write is the separate POST below, reached only from Approve).
Source: ui/server/src/index.mjs.
GET /api/pages/props#
Source: ui/server/src/index.mjs.
POST /api/pages/props#
| Parameter | In | Type |
|---|---|---|
feature |
body | — |
file |
body | — |
nodeId |
body | — |
propName |
body | — |
kind |
body | — |
value |
body | — |
contentHash |
body | — |
index |
body | — |
Source: ui/server/src/index.mjs.
POST /api/pages/quickfix#
one quick fix for one diagnostic: "mechanical" (the rule's own deterministic transform) or "ai" (a model call scoped to the violation). Returns the fixed buffer for the client to diff and review; never writes.
| Parameter | In | Type |
|---|---|---|
feature |
body | — |
file |
body | — |
source |
body | — |
rule |
body | — |
mode |
body | — |
Source: ui/server/src/index.mjs.
GET /api/pages/scope-links#
which page-scope names flow into which of this element's props (path-scoped to pages/; cross-origin browser reads are refused by the global CORS policy above).
Source: ui/server/src/index.mjs.
POST /api/pages/snippet-add-child#
| Parameter | In | Type |
|---|---|---|
snippet |
body | — |
parentId |
body | — |
Source: ui/server/src/index.mjs.
POST /api/pages/snippet-move-node#
| Parameter | In | Type |
|---|---|---|
snippet |
body | — |
nodeId |
body | — |
direction |
body | — |
Source: ui/server/src/index.mjs.
POST /api/pages/snippet-remove-node#
Ticket F.3 epic the visual composer's structural node edits. Same contract as snippet-rewire above: the snippet's own current text in, a rewritten snippet (or a rejection reason) out, never a disk write here — the client hands the result to the existing save-back-to- source + diff-preview flow itself.
| Parameter | In | Type |
|---|---|---|
snippet |
body | — |
nodeId |
body | — |
Source: ui/server/src/index.mjs.
POST /api/pages/snippet-rewire#
Ticket F.2 epic the visual composer's wire-rewrite. Body carries the snippet's own current text (not feature/file) plus the wire's endpoints; the response is the new snippet text (or a rejection reason), never a disk write — the client hands the result to the existing save-back-to-source + diff-preview flow itself.
| Parameter | In | Type |
|---|---|---|
snippet |
body | — |
parentId |
body | — |
propName |
body | — |
fromChildId |
body | — |
toChildId |
body | — |
Source: ui/server/src/index.mjs.
POST /api/pages/snippet-tree#
Ticket F.1 epic the visual composer's live parse. POST (not GET) since a snippet's text can be long/contain query-unsafe characters; no feature/file/disk access at all here — pure text in, tree out, so the graph the client renders is always derived fresh from whatever text is currently in the editor, never a cached/persisted layout.
| Parameter | In | Type |
|---|---|---|
snippet |
body | — |
Source: ui/server/src/index.mjs.
GET /api/pages/source#
Read-only source view: the whole page file + TypeScript/architecture diagnostics (core src/engine/diagnostics.mjs), scoped by resolvePageFile.
Source: ui/server/src/index.mjs.
GET /api/pages/tree#
Source: ui/server/src/index.mjs.
GET /api/pages/unmapped#
Source: ui/server/src/index.mjs.