chore: v2.8.12 — clone queue and progress, session defaults, chat agents, drops as @ mentions

Whole tree from parallel sessions, plus the version bump:
- Clone: a queue with live progress (Add workspace and extra folders),
  clones run under nice/ionice so the machine stays responsive.
- Settings → AI tools → Session defaults: a new session's default
  permission mode / bypass per account.
- Chat lists the background subagents that have not reported back yet.
- A file pasted or dropped into a claude pane goes in as an @ mention.
- Changes panel: say why amend/undo is refused on a pushed commit.
- openapi.yaml regenerated (Artifacts, Host, resumeById).
This commit is contained in:
2026-10-19 17:19:41 +07:00
parent 1a6b550e89
commit 49f87c4da3
61 changed files with 2824 additions and 114 deletions
+676 -2
View File
@@ -3,7 +3,7 @@
openapi: 3.0.3
info:
title: Agent Dashboard for Claude Code API
version: 2.8.11
version: 2.8.12
description: HTTP API for real-time Claude Code session monitoring, agent lifecycle tracking, analytics, pricing, hooks ingestion, and workflow intelligence.
contact:
name: Nguyễn Ngọc Trí Vĩ
@@ -68,6 +68,10 @@ tags:
description: 'The File Explorer on a workspace or a user''s home: list, make, rename, move, copy, delete into a restorable trash, streamed upload, zip download. Writes run as the folder''s account; a taken name is settled by `conflict`.'
- name: Git identity
description: A user's own SSH key and HTTPS logins and commit author, and cloning a repository into a new workspace with them.
- name: Artifacts
description: 'What agents produced, shared as a SNAPSHOT: a claude.ai page link, a pinned or uploaded file, a skill or a plugin. A viewer reads only the snapshot copy (sandbox CSP, nosniff); an install writes into the caller''s own account only. Every write is same-origin.'
- name: Host
description: 'Administration → Server: the machine''s hardware, load, disks and each user''s share of CPU and memory. Read-only, staff only in server mode.'
components:
parameters:
SessionIdPath:
@@ -3859,7 +3863,7 @@ components:
example: claude-opus-4-8
resumeSessionId:
type: string
description: Optional Claude session id to resume via `--resume`. Must match /^[A-Za-z0-9-]{8,}$/ and requires conversation mode, else EBADSESSION / EBADMODE.
description: Optional Claude session id to resume via `--resume`. Must match /^[A-Za-z0-9_-]{8,}$/ and requires conversation mode, else EBADSESSION / EBADMODE.
example: a1b2c3d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d
effort:
type: string
@@ -4218,6 +4222,9 @@ components:
resume:
type: boolean
description: Offers Resume last session
resumeById:
type: boolean
description: Can resume a named session (Claude, Codex, a catalog `resumeById` such as omp)
bypass:
type: boolean
description: Offers the per-run Bypass permissions switch
@@ -4928,6 +4935,71 @@ components:
- replace
default: fail
description: 'A taken name: `fail` answers 409 EEXISTS with the names, `skip` leaves it, `keep` uses a free `name (1).ext`, `replace` sends the old one to the trash first.'
Artifact:
type: object
properties:
id:
type: string
kind:
type: string
enum:
- page
- file
- skill
- plugin
title:
type: string
description:
type: string
nullable: true
ownerId:
type: integer
nullable: true
owner:
type: string
nullable: true
description: Display name or username.
mine:
type: boolean
canChange:
type: boolean
laneId:
type: integer
nullable: true
sessionId:
type: string
nullable: true
source:
type: string
nullable: true
description: 'Plugin: `name@marketplace`.'
market:
type: string
nullable: true
description: 'Plugin: owner/repo, git URL or marketplace.json URL.'
url:
type: string
nullable: true
description: 'Page: a https://claude.ai/… link.'
files:
type: array
items:
type: object
description: The files the snapshot recorded.
size:
type: integer
nullable: true
shared:
type: boolean
sharedAt:
type: string
nullable: true
installs:
type: integer
createdAt:
type: string
updatedAt:
type: string
paths:
/api/health:
get:
@@ -16290,9 +16362,34 @@ paths:
type: string
remember:
type: boolean
partial:
type: boolean
description: 'Blobless clone (`--filter=blob:none`): file contents fetched on checkout.'
progressToken:
type: string
pattern: ^[A-Za-z0-9_-]{16,64}$
description: The caller's name for this clone, to poll `/api/lanes/clone/progress/{token}`.
responses:
'201':
description: '{lane, created: true, path}'
/api/lanes/clone/progress/{token}:
get:
tags:
- Git identity
summary: A clone's place in the queue, then git's progress
description: Clones run a few at a time machine-wide (`AGENTHUB_CLONE_CONCURRENCY`). Only the user who started the clone sees it; kept 60 s after it ends.
operationId: cloneProgress
parameters:
- name: token
in: path
required: true
schema:
type: string
responses:
'200':
description: '{state: queued|running|done|failed, position, running, waiting, limit, phase: remote|receiving|resolving|checkout|other|null, label, percent, detail}'
'404':
description: ENOTFOUND
/api/me/git:
get:
tags:
@@ -16491,6 +16588,583 @@ paths:
description: The identity.
'400':
description: EBADAUTHOR
/api/artifacts:
get:
tags:
- Artifacts
summary: List artifacts
operationId: listArtifacts
description: A developer sees their own rows plus shared ones; staff see every row in `hub` scope.
parameters:
- name: scope
in: query
schema:
type: string
enum:
- mine
- hub
- name: kind
in: query
schema:
type: string
enum:
- page
- file
- skill
- plugin
- name: q
in: query
schema:
type: string
- name: laneId
in: query
required: false
schema:
type: integer
- name: sessionId
in: query
schema:
type: string
responses:
'200':
description: '`{items}`.'
content:
application/json:
schema:
type: object
properties:
items:
type: array
items:
$ref: '#/components/schemas/Artifact'
/api/artifacts/settings:
get:
tags:
- Artifacts
summary: Hub switches and what the caller may do
operationId: getArtifactSettings
responses:
'200':
description: '`{serverMode, canShare, installsEnabled, canManage}`.'
content:
application/json:
schema:
type: object
properties:
serverMode:
type: boolean
canShare:
type: boolean
installsEnabled:
type: boolean
canManage:
type: boolean
put:
tags:
- Artifacts
summary: Turn installs on or off (admin; any caller in local mode)
operationId: setArtifactSettings
description: Audited in server mode (Settings → AI tools → Artifacts Hub).
requestBody:
required: true
content:
application/json:
schema:
type: object
required:
- installsEnabled
properties:
installsEnabled:
type: boolean
responses:
'200':
description: '`{installsEnabled}`.'
'400':
description: EBADFIELD
'403':
description: EADMIN / EBADORIGIN
/api/artifacts/candidates:
get:
tags:
- Artifacts
summary: Documents a workspace's sessions wrote (to pin)
operationId: listArtifactCandidates
parameters:
- name: laneId
in: query
required: false
schema:
type: integer
responses:
'200':
description: '`{items: [{path, sessionId, at, exists, pinned}]}`.'
'404':
description: 'Error `{error:{code,message}}`: 400 EBADURL/EBADPATH/EBADNAME/ENOSKILLMD/ENODESCRIPTION/EBADFIELD/EBADUPLOAD, 403 EFORBIDDEN/ESECRET/EFOREIGN/EINSTALLSOFF/EADMIN, 404 ENOTFOUND/ENOLANE/ENOFILE, 409 EEXISTS/ENOTSHARED/ENOACCOUNT/EUPGRADE, 413 ETOOBIG, 502 EPLUGIN/EMARKETFETCH/ENEEDLOGIN.'
/api/artifacts/skills:
get:
tags:
- Artifacts
summary: Skills the caller can share (user + workspace)
operationId: listArtifactSkills
parameters:
- name: laneId
in: query
required: false
schema:
type: integer
responses:
'200':
description: '`{items: [{name, from: "user"|"workspace"}]}`.'
/api/artifacts/page:
post:
tags:
- Artifacts
summary: Add a claude.ai page link
operationId: addArtifactPage
description: Only `https://claude.ai/…` is accepted; one row per owner and link.
requestBody:
required: true
content:
application/json:
schema:
type: object
required:
- url
properties:
url:
type: string
title:
type: string
description:
type: string
responses:
'201':
description: Created.
content:
application/json:
schema:
type: object
properties:
item:
$ref: '#/components/schemas/Artifact'
'400':
description: 'Error `{error:{code,message}}`: 400 EBADURL/EBADPATH/EBADNAME/ENOSKILLMD/ENODESCRIPTION/EBADFIELD/EBADUPLOAD, 403 EFORBIDDEN/ESECRET/EFOREIGN/EINSTALLSOFF/EADMIN, 404 ENOTFOUND/ENOLANE/ENOFILE, 409 EEXISTS/ENOTSHARED/ENOACCOUNT/EUPGRADE, 413 ETOOBIG, 502 EPLUGIN/EMARKETFETCH/ENEEDLOGIN.'
/api/artifacts/file:
post:
tags:
- Artifacts
summary: Pin a workspace file (snapshotted)
operationId: pinArtifactFile
description: Read under the download route's guards (`lanePath`, `resolveInLane`, `ESECRET`, ≤ 25 MB) and copied once.
requestBody:
required: true
content:
application/json:
schema:
type: object
required:
- laneId
- path
properties:
laneId:
type: integer
path:
type: string
title:
type: string
sessionId:
type: string
responses:
'201':
description: Created.
content:
application/json:
schema:
type: object
properties:
item:
$ref: '#/components/schemas/Artifact'
'400':
description: 'Error `{error:{code,message}}`: 400 EBADURL/EBADPATH/EBADNAME/ENOSKILLMD/ENODESCRIPTION/EBADFIELD/EBADUPLOAD, 403 EFORBIDDEN/ESECRET/EFOREIGN/EINSTALLSOFF/EADMIN, 404 ENOTFOUND/ENOLANE/ENOFILE, 409 EEXISTS/ENOTSHARED/ENOACCOUNT/EUPGRADE, 413 ETOOBIG, 502 EPLUGIN/EMARKETFETCH/ENEEDLOGIN.'
/api/artifacts/file/upload:
post:
tags:
- Artifacts
summary: Keep one uploaded file (≤ 25 MB)
operationId: uploadArtifactFile
requestBody:
required: true
content:
multipart/form-data:
schema:
type: object
required:
- files
properties:
files:
type: string
format: binary
title:
type: string
description:
type: string
responses:
'201':
description: Created.
content:
application/json:
schema:
type: object
properties:
item:
$ref: '#/components/schemas/Artifact'
'400':
description: 'Error `{error:{code,message}}`: 400 EBADURL/EBADPATH/EBADNAME/ENOSKILLMD/ENODESCRIPTION/EBADFIELD/EBADUPLOAD, 403 EFORBIDDEN/ESECRET/EFOREIGN/EINSTALLSOFF/EADMIN, 404 ENOTFOUND/ENOLANE/ENOFILE, 409 EEXISTS/ENOTSHARED/ENOACCOUNT/EUPGRADE, 413 ETOOBIG, 502 EPLUGIN/EMARKETFETCH/ENEEDLOGIN.'
/api/artifacts/skill:
post:
tags:
- Artifacts
summary: Share an existing skill
operationId: addArtifactSkill
requestBody:
required: true
content:
application/json:
schema:
type: object
required:
- name
properties:
name:
type: string
laneId:
type: integer
title:
type: string
description:
type: string
responses:
'201':
description: Created.
content:
application/json:
schema:
type: object
properties:
item:
$ref: '#/components/schemas/Artifact'
'400':
description: 'Error `{error:{code,message}}`: 400 EBADURL/EBADPATH/EBADNAME/ENOSKILLMD/ENODESCRIPTION/EBADFIELD/EBADUPLOAD, 403 EFORBIDDEN/ESECRET/EFOREIGN/EINSTALLSOFF/EADMIN, 404 ENOTFOUND/ENOLANE/ENOFILE, 409 EEXISTS/ENOTSHARED/ENOACCOUNT/EUPGRADE, 413 ETOOBIG, 502 EPLUGIN/EMARKETFETCH/ENEEDLOGIN.'
/api/artifacts/skill/upload:
post:
tags:
- Artifacts
summary: 'Skills from files: a file, a folder, a .zip/.skill or several skills'
operationId: uploadArtifactSkills
description: '`paths` is a JSON array of each file''s relative path. Zip sizes are read before inflating; nothing is stored if any skill fails.'
requestBody:
required: true
content:
multipart/form-data:
schema:
type: object
required:
- files
properties:
files:
type: array
items:
type: string
format: binary
paths:
type: string
name:
type: string
title:
type: string
description:
type: string
responses:
'201':
description: Created.
content:
application/json:
schema:
type: object
properties:
items:
type: array
items:
$ref: '#/components/schemas/Artifact'
'400':
description: 'Error `{error:{code,message}}`: 400 EBADURL/EBADPATH/EBADNAME/ENOSKILLMD/ENODESCRIPTION/EBADFIELD/EBADUPLOAD, 403 EFORBIDDEN/ESECRET/EFOREIGN/EINSTALLSOFF/EADMIN, 404 ENOTFOUND/ENOLANE/ENOFILE, 409 EEXISTS/ENOTSHARED/ENOACCOUNT/EUPGRADE, 413 ETOOBIG, 502 EPLUGIN/EMARKETFETCH/ENEEDLOGIN.'
/api/artifacts/skill/new:
post:
tags:
- Artifacts
summary: Write a skill in the dialog
operationId: writeArtifactSkill
requestBody:
required: true
content:
application/json:
schema:
type: object
required:
- name
- description
- content
properties:
name:
type: string
description:
type: string
content:
type: string
title:
type: string
responses:
'201':
description: Created.
content:
application/json:
schema:
type: object
properties:
item:
$ref: '#/components/schemas/Artifact'
items:
type: array
items:
$ref: '#/components/schemas/Artifact'
'400':
description: 'Error `{error:{code,message}}`: 400 EBADURL/EBADPATH/EBADNAME/ENOSKILLMD/ENODESCRIPTION/EBADFIELD/EBADUPLOAD, 403 EFORBIDDEN/ESECRET/EFOREIGN/EINSTALLSOFF/EADMIN, 404 ENOTFOUND/ENOLANE/ENOFILE, 409 EEXISTS/ENOTSHARED/ENOACCOUNT/EUPGRADE, 413 ETOOBIG, 502 EPLUGIN/EMARKETFETCH/ENEEDLOGIN.'
/api/artifacts/plugin/inspect:
post:
tags:
- Artifacts
summary: Read a marketplace's plugin list
operationId: inspectArtifactMarket
description: Clones a user-named https link only to read `marketplace.json`; no credential is ever sent.
requestBody:
required: true
content:
application/json:
schema:
type: object
required:
- market
properties:
market:
type: string
responses:
'200':
description: '`{market, name, description, plugins: [{name, key, description, version, category}]}`.'
'502':
description: 'Error `{error:{code,message}}`: 400 EBADURL/EBADPATH/EBADNAME/ENOSKILLMD/ENODESCRIPTION/EBADFIELD/EBADUPLOAD, 403 EFORBIDDEN/ESECRET/EFOREIGN/EINSTALLSOFF/EADMIN, 404 ENOTFOUND/ENOLANE/ENOFILE, 409 EEXISTS/ENOTSHARED/ENOACCOUNT/EUPGRADE, 413 ETOOBIG, 502 EPLUGIN/EMARKETFETCH/ENEEDLOGIN.'
/api/artifacts/plugin:
post:
tags:
- Artifacts
summary: Share a plugin from a marketplace
operationId: addArtifactPlugin
requestBody:
required: true
content:
application/json:
schema:
type: object
required:
- key
- market
properties:
key:
type: string
description: '`name@marketplace`.'
market:
type: string
title:
type: string
description:
type: string
responses:
'201':
description: Created.
content:
application/json:
schema:
type: object
properties:
item:
$ref: '#/components/schemas/Artifact'
'400':
description: 'Error `{error:{code,message}}`: 400 EBADURL/EBADPATH/EBADNAME/ENOSKILLMD/ENODESCRIPTION/EBADFIELD/EBADUPLOAD, 403 EFORBIDDEN/ESECRET/EFOREIGN/EINSTALLSOFF/EADMIN, 404 ENOTFOUND/ENOLANE/ENOFILE, 409 EEXISTS/ENOTSHARED/ENOACCOUNT/EUPGRADE, 413 ETOOBIG, 502 EPLUGIN/EMARKETFETCH/ENEEDLOGIN.'
/api/artifacts/{id}:
get:
tags:
- Artifacts
summary: One artifact
operationId: getArtifact
parameters:
- name: id
in: path
required: true
schema:
type: string
responses:
'200':
description: '`{item}`.'
content:
application/json:
schema:
type: object
properties:
item:
$ref: '#/components/schemas/Artifact'
'404':
description: 'Error `{error:{code,message}}`: 400 EBADURL/EBADPATH/EBADNAME/ENOSKILLMD/ENODESCRIPTION/EBADFIELD/EBADUPLOAD, 403 EFORBIDDEN/ESECRET/EFOREIGN/EINSTALLSOFF/EADMIN, 404 ENOTFOUND/ENOLANE/ENOFILE, 409 EEXISTS/ENOTSHARED/ENOACCOUNT/EUPGRADE, 413 ETOOBIG, 502 EPLUGIN/EMARKETFETCH/ENEEDLOGIN.'
patch:
tags:
- Artifacts
summary: Rename, describe, share or unshare (owner or admin)
operationId: updateArtifact
parameters:
- name: id
in: path
required: true
schema:
type: string
requestBody:
required: true
content:
application/json:
schema:
type: object
required: []
properties:
title:
type: string
description:
type: string
shared:
type: boolean
source:
type: string
description: Plugin only.
market:
type: string
description: Plugin only.
responses:
'200':
description: '`{item}`.'
content:
application/json:
schema:
type: object
properties:
item:
$ref: '#/components/schemas/Artifact'
'403':
description: 'Error `{error:{code,message}}`: 400 EBADURL/EBADPATH/EBADNAME/ENOSKILLMD/ENODESCRIPTION/EBADFIELD/EBADUPLOAD, 403 EFORBIDDEN/ESECRET/EFOREIGN/EINSTALLSOFF/EADMIN, 404 ENOTFOUND/ENOLANE/ENOFILE, 409 EEXISTS/ENOTSHARED/ENOACCOUNT/EUPGRADE, 413 ETOOBIG, 502 EPLUGIN/EMARKETFETCH/ENEEDLOGIN.'
'404':
description: 'Error `{error:{code,message}}`: 400 EBADURL/EBADPATH/EBADNAME/ENOSKILLMD/ENODESCRIPTION/EBADFIELD/EBADUPLOAD, 403 EFORBIDDEN/ESECRET/EFOREIGN/EINSTALLSOFF/EADMIN, 404 ENOTFOUND/ENOLANE/ENOFILE, 409 EEXISTS/ENOTSHARED/ENOACCOUNT/EUPGRADE, 413 ETOOBIG, 502 EPLUGIN/EMARKETFETCH/ENEEDLOGIN.'
delete:
tags:
- Artifacts
summary: Delete an artifact and its snapshot (owner or admin)
operationId: deleteArtifact
parameters:
- name: id
in: path
required: true
schema:
type: string
responses:
'200':
description: '`{ok: true}`.'
'403':
description: 'Error `{error:{code,message}}`: 400 EBADURL/EBADPATH/EBADNAME/ENOSKILLMD/ENODESCRIPTION/EBADFIELD/EBADUPLOAD, 403 EFORBIDDEN/ESECRET/EFOREIGN/EINSTALLSOFF/EADMIN, 404 ENOTFOUND/ENOLANE/ENOFILE, 409 EEXISTS/ENOTSHARED/ENOACCOUNT/EUPGRADE, 413 ETOOBIG, 502 EPLUGIN/EMARKETFETCH/ENEEDLOGIN.'
'404':
description: 'Error `{error:{code,message}}`: 400 EBADURL/EBADPATH/EBADNAME/ENOSKILLMD/ENODESCRIPTION/EBADFIELD/EBADUPLOAD, 403 EFORBIDDEN/ESECRET/EFOREIGN/EINSTALLSOFF/EADMIN, 404 ENOTFOUND/ENOLANE/ENOFILE, 409 EEXISTS/ENOTSHARED/ENOACCOUNT/EUPGRADE, 413 ETOOBIG, 502 EPLUGIN/EMARKETFETCH/ENEEDLOGIN.'
/api/artifacts/{id}/raw:
get:
tags:
- Artifacts
summary: One recorded file of a snapshot
operationId: getArtifactRaw
description: Always served under a `sandbox` CSP with `nosniff`; an unlisted type, or `download=1`, is an attachment. Only a file the snapshot recorded can be named.
parameters:
- name: id
in: path
required: true
schema:
type: string
- name: path
in: query
required: true
schema:
type: string
- name: download
in: query
schema:
type: string
enum:
- '1'
responses:
'200':
description: The file bytes.
'400':
description: 'Error `{error:{code,message}}`: 400 EBADURL/EBADPATH/EBADNAME/ENOSKILLMD/ENODESCRIPTION/EBADFIELD/EBADUPLOAD, 403 EFORBIDDEN/ESECRET/EFOREIGN/EINSTALLSOFF/EADMIN, 404 ENOTFOUND/ENOLANE/ENOFILE, 409 EEXISTS/ENOTSHARED/ENOACCOUNT/EUPGRADE, 413 ETOOBIG, 502 EPLUGIN/EMARKETFETCH/ENEEDLOGIN.'
'404':
description: 'Error `{error:{code,message}}`: 400 EBADURL/EBADPATH/EBADNAME/ENOSKILLMD/ENODESCRIPTION/EBADFIELD/EBADUPLOAD, 403 EFORBIDDEN/ESECRET/EFOREIGN/EINSTALLSOFF/EADMIN, 404 ENOTFOUND/ENOLANE/ENOFILE, 409 EEXISTS/ENOTSHARED/ENOACCOUNT/EUPGRADE, 413 ETOOBIG, 502 EPLUGIN/EMARKETFETCH/ENEEDLOGIN.'
/api/artifacts/{id}/install:
post:
tags:
- Artifacts
summary: Install a shared skill or plugin into the caller's own account
operationId: installArtifact
description: A skill goes to the caller's `~/.claude/skills/` (never over an existing one without `replace`; the old one is moved aside). A plugin runs `claude plugin install --scope user` as the caller.
parameters:
- name: id
in: path
required: true
schema:
type: string
requestBody:
required: true
content:
application/json:
schema:
type: object
required: []
properties:
replace:
type: boolean
responses:
'200':
description: '`{installed, replaced?}`.'
'403':
description: 'Error `{error:{code,message}}`: 400 EBADURL/EBADPATH/EBADNAME/ENOSKILLMD/ENODESCRIPTION/EBADFIELD/EBADUPLOAD, 403 EFORBIDDEN/ESECRET/EFOREIGN/EINSTALLSOFF/EADMIN, 404 ENOTFOUND/ENOLANE/ENOFILE, 409 EEXISTS/ENOTSHARED/ENOACCOUNT/EUPGRADE, 413 ETOOBIG, 502 EPLUGIN/EMARKETFETCH/ENEEDLOGIN.'
'409':
description: 'Error `{error:{code,message}}`: 400 EBADURL/EBADPATH/EBADNAME/ENOSKILLMD/ENODESCRIPTION/EBADFIELD/EBADUPLOAD, 403 EFORBIDDEN/ESECRET/EFOREIGN/EINSTALLSOFF/EADMIN, 404 ENOTFOUND/ENOLANE/ENOFILE, 409 EEXISTS/ENOTSHARED/ENOACCOUNT/EUPGRADE, 413 ETOOBIG, 502 EPLUGIN/EMARKETFETCH/ENEEDLOGIN.'
'502':
description: 'Error `{error:{code,message}}`: 400 EBADURL/EBADPATH/EBADNAME/ENOSKILLMD/ENODESCRIPTION/EBADFIELD/EBADUPLOAD, 403 EFORBIDDEN/ESECRET/EFOREIGN/EINSTALLSOFF/EADMIN, 404 ENOTFOUND/ENOLANE/ENOFILE, 409 EEXISTS/ENOTSHARED/ENOACCOUNT/EUPGRADE, 413 ETOOBIG, 502 EPLUGIN/EMARKETFETCH/ENEEDLOGIN.'
/api/host:
get:
tags:
- Host
summary: The machine and each user's live share of it
operationId: getHost
description: 'Cached 3 s. `usage` is null off Linux. Server mode: admin/analyst only (403 EADMIN for a developer).'
responses:
'200':
description: '`{at, hostname, os, uptime, cpu, memory, disks, homesMount, gpus, usage}` — see docs/API.md.'
content:
application/json:
schema:
type: object
'500':
description: EHOST
/api/settings/import:
post:
tags: