docs: OpenAPI and API.md cover every route; drop removed endpoints; guard config writes

- openapi-extra/run.js describes tmux pane runs only: the removed
  POST /api/run/{id}/message and stream-json run_stream/run_input_ack are gone.
- 108 operations added to OpenAPI (lanes, run, settings, reports, cc-config,
  pets, ai-proxies, tool-profiles, ai-tools, snapshots, locks, ...);
  openapi.yaml regenerated.
- docs/API.md: 74 routes added, 4 endpoints that no longer exist removed.
- Role is `developer`, not `member` (CLI.md, DATABASE.md, OVERVIEW.md);
  `agenthub update` -> `update-check`; help lists `server install-system|tools`
  and `users provision`; ARCHITECTURE.md's stale paths and names fixed.
- cc-config/codex-config writes carry sameOriginGuard (an MCP server or plugin
  is code Claude runs later), with a test; `command -v` takes its name as $1.
This commit is contained in:
2026-10-22 12:17:18 +07:00
parent 50ac0f0daf
commit 57f02f0d89
19 changed files with 8345 additions and 1531 deletions
+57 -1
View File
@@ -6,7 +6,8 @@
* `LaneStageDetectionFields` schema for the stage-detection fields every lane
* response carries, and the idempotent `POST /api/lanes/ensure` lookup the
* Workspace page opens a directory with, and the Files tab's reads (tree,
* quick-open, download — also in a folder that is not a git repo) and upload.
* quick-open, download — also in a folder that is not a git repo) and upload,
* one lane's GET/DELETE, and the editor's whole-file save.
* @author Nguyễn Ngọc Trí Vĩ <vinnt@smartgift.vn>
*/
@@ -299,6 +300,30 @@ const paths = {
},
},
"/api/lanes/{id}": {
get: {
tags: ["Lanes"],
summary: "One workspace",
description: "The same lane payload `GET /api/lanes` lists.",
operationId: "getLane",
parameters: [{ name: "id", in: "path", required: true, schema: { type: "integer" } }],
responses: {
200: { description: "`{lane}`." },
404: { description: "ENOLANE — workspace not found." },
},
},
delete: {
tags: ["Lanes"],
summary: "Delete a workspace row",
description:
"Deletes the lane row only (its `lane_sources` rows cascade, and AgentHub's own copies of uploaded context files go with them). Stops nothing and never touches the folder, worktree or branch — `POST /api/lanes/{id}/remove` is the UI's path that also stops runs and stacks. Broadcasts `lane_update` with `{removed: id}`. Same-origin.",
operationId: "deleteLane",
parameters: [{ name: "id", in: "path", required: true, schema: { type: "integer" } }],
responses: {
200: { description: "`{ok: true}`." },
403: { description: "The browser request was not same-origin." },
404: { description: "ENOLANE — workspace not found." },
},
},
patch: {
tags: ["Lanes"],
summary: "Partially update a lane",
@@ -635,6 +660,37 @@ const paths = {
404: { description: "Lane not found." },
},
},
put: {
tags: ["Lanes"],
summary: "Save one text file from the viewer's editor",
description:
"lane-file-write.js: the read path's guards (lane confinement, secret refusal) plus existing-text-file-only (never creates a file or touches a binary) and a `baseSha` stale check. Answers the file re-read at rev `work`, fresh `sha` included. Same-origin.",
operationId: "writeLaneFile",
parameters: [{ name: "id", in: "path", required: true, schema: { type: "integer" } }],
requestBody: {
required: true,
content: {
"application/json": {
schema: {
type: "object",
required: ["path", "content", "baseSha"],
properties: {
path: { type: "string" },
content: { type: "string" },
baseSha: { type: "string", description: "The `sha` the file was opened at." },
},
},
},
},
},
responses: {
200: { description: "`{available: true, …}` — the same shape as the GET." },
400: { description: "EBADPATH, ENOFILE, EBADCONTENT, ETOOBIG or EBINARY." },
403: { description: "ESECRET or EFOREIGN, or not same-origin." },
404: { description: "Lane not found." },
409: { description: "ESTALE — the file changed since `baseSha`." },
},
},
},
"/api/lanes/{id}/git/blame": {
get: {