feat: AI commit messages, change tree, router behavesAs, sidebar times (v2.2.0)

- Changes panel: Files and Changes merged into one panel; the overview's
  groups drawn as a folder tree (compacted chains, file counts, fold,
  stage/unstage a whole folder)
- AI-suggested commit message for what is staged
  (POST /api/lanes/:id/git/commit-message, claude -p --safe-mode, haiku)
- AI Router: optional "Behaves as" Claude model id, written as
  modelPicker options into the router's --settings file (issue #56)
- Sidebar: session rows show last activity, live rows their start time;
  a closed Terminal row can be removed (DELETE /api/run/history/:id)
- Every pane's CLI starts only once a client is attached; claude panes
  no longer forced inline; tmux scrollbar one column wide
- Update notifier: "Check for updates" reopens a closed notice
This commit is contained in:
2026-10-06 12:36:06 +07:00
parent 6c605849d8
commit f0500dc592
41 changed files with 1201 additions and 249 deletions
+31
View File
@@ -674,6 +674,37 @@ const paths = {
},
},
},
"/api/lanes/{id}/git/commit-message": {
post: {
tags: ["Lanes"],
summary: "Suggest a commit message for the staged changes",
description:
"Runs the user's `claude` CLI (`-p --safe-mode --no-session-persistence --tools \"\" --model haiku`) on the STAGED diff of the lane's cwd (or `?session=` worktree), sent on stdin with the last ten commit subjects; a `settings.local.json` is never included. Reads only — nothing is staged or committed, no tool runs and no session is saved. Same-origin, since each call spends the user's Claude quota. 400 ENOSTAGED when nothing is staged, 400 ENOTOOL when `claude` is not on PATH, 502 EAI when the CLI fails, answers empty or runs past 120 s.",
operationId: "suggestLaneCommitMessage",
parameters: [
{ name: "id", in: "path", required: true, schema: { type: "integer" } },
{ name: "session", in: "query", required: false, schema: { type: "string" } },
],
responses: {
200: {
description: "The suggested message",
content: {
"application/json": {
schema: {
type: "object",
properties: { message: { type: "string" } },
required: ["message"],
},
},
},
},
400: { description: "ENOSTAGED / ENOTOOL / ENOWORKTREE" },
403: { description: "Cross-origin request refused" },
404: { description: "No such workspace" },
502: { description: "EAI — the claude CLI failed" },
},
},
},
"/api/lanes/{id}/git/{action}": {
post: {
tags: ["Lanes"],