feat(lanes): lane runtime UI, docs, and env additions (A1+A2)

Client-side rendering for the per-lane runtime facts (slot, ports,
database, Redis index, service liveness) added in the server-side
A1/A2 work, plus the doc updates (README, CLAUDE.md, docs/API.md,
client/server READMEs) describing the new profile.env keys, hook
environment contract, and REST endpoints.
This commit is contained in:
2026-08-04 10:04:58 +07:00
parent 9d145865dd
commit 4d9a385c5e
14 changed files with 614 additions and 24 deletions
+35
View File
@@ -392,6 +392,7 @@ import type {
Lane,
LaneCounts,
LaneGitFacts,
LaneRuntime,
ModelPricing,
Session,
SessionDrillIn,
@@ -1932,6 +1933,40 @@ export const api = {
* readable git repository, which is a normal state rather than an error.
*/
git: (id: number) => request<LaneGitFacts>(`/lanes/${id}/git`),
/**
* GET /api/lanes/:id/runtime — the lane's own application stack: slot,
* ports, service liveness, and the last boot error.
*
* Its own endpoint rather than a field on the polled lane list because it
* probes ports and stats pid files. Like `/git`, a lane with no profile
* answers `available: false` with HTTP 200 — a normal state, not a fault.
* @param id The lane id.
* @returns {@link LaneRuntime}
*/
runtime: (id: number) => request<LaneRuntime>(`/lanes/${id}/runtime`),
/**
* POST /api/lanes/:id/up — boot the lane's stack through its profile hooks.
* Returns 202: the boot runs in the background and streams progress as
* `lane_hook_output`, finishing with a `lane_runtime` message.
* @param id The lane id.
* @param body `build: false` reuses an existing build.
*/
up: (id: number, body: { build?: boolean } = {}) =>
request<{ ok: true; laneId: number }>(`/lanes/${id}/up`, {
method: "POST",
body: JSON.stringify(body),
}),
/**
* POST /api/lanes/:id/down — stop the lane's stack. Idempotent, and a no-op
* for a lane that was never brought up.
* @param id The lane id.
* @returns The pids stopped and the resulting runtime facts.
*/
down: (id: number) =>
request<{ ok: true; killed: number[]; runtime: LaneRuntime }>(`/lanes/${id}/down`, {
method: "POST",
body: JSON.stringify({}),
}),
/**
* POST /api/lanes — create a new lane.
* @param body Optional lane initialization fields.