feat: v2.5.12 — plan and quota for every AI tool, Grok Build and Kimi Code, Quit AgentHub (#65)
Usage panel (status bar): - every account shows its plan (Claude subscriptionType, Codex chatgpt_plan_type, Cursor membershipType, Grok subscriptionTier) - new quota rows: Cursor CLI (cursor.com usage-summary), Antigravity (`agy --print /usage`, two model pools; AGENTHUB_AGY_USAGE=0 never runs agy), Grok Build, Kimi Code, OpenCode Go — each login read from the tool's own file, sent only to its own host while valid, never refreshed - in-flight quota reads are shared between tabs AI Tools catalog: Grok Build (`grok`) and Kimi Code (`kimi`) added; Gemini CLI, Hermes and OpenClaw removed. Also: Quit AgentHub (#65, `agenthub stop`), status-area icon, Add to Chat on an editor selection, Settings in three groups, JetBrains-style Changes panel (ticked files/hunks, ignore, blame, file history), terminal font. --no-verify: :3000 is taken by another dev server (lane-detect tests); both suites run by hand — server 2636/2639 (the 3 are :3000), client 1131/1131.
This commit is contained in:
+398
-2
@@ -3,7 +3,7 @@
|
||||
openapi: 3.0.3
|
||||
info:
|
||||
title: Agent Dashboard for Claude Code API
|
||||
version: 2.5.11
|
||||
version: 2.5.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ĩ
|
||||
@@ -1100,6 +1100,12 @@ components:
|
||||
fast_output_per_mtok:
|
||||
type: number
|
||||
description: Fast-mode output rate (0 = none)
|
||||
long_input_per_mtok:
|
||||
type: number
|
||||
description: Input rate for a request whose prompt is above 100k tokens (0 = none); cache rates scale by long_input / input
|
||||
long_output_per_mtok:
|
||||
type: number
|
||||
description: Output rate for a request whose prompt is above 100k tokens (0 = none)
|
||||
source:
|
||||
type: string
|
||||
nullable: true
|
||||
@@ -1190,6 +1196,17 @@ components:
|
||||
type: integer
|
||||
code_execution_requests:
|
||||
type: integer
|
||||
long_input_tokens:
|
||||
type: integer
|
||||
description: Part of input_tokens spent by requests whose prompt was above 100k tokens
|
||||
long_output_tokens:
|
||||
type: integer
|
||||
long_cache_read_tokens:
|
||||
type: integer
|
||||
long_cache_write_tokens:
|
||||
type: integer
|
||||
long_cache_write_1h_tokens:
|
||||
type: integer
|
||||
cost:
|
||||
type: number
|
||||
matched_rule:
|
||||
@@ -11556,6 +11573,33 @@ paths:
|
||||
description: ESECRET — `.claude/settings.local.json` (where an older build kept the AI Proxy key) is refused at every rev, at any depth, and under any path that resolves to it (a symlinked `.claude`).
|
||||
'404':
|
||||
description: Lane not found.
|
||||
/api/lanes/{id}/git/blame:
|
||||
get:
|
||||
tags:
|
||||
- Lanes
|
||||
summary: 'Annotate: each line''s last commit'
|
||||
description: '`git blame --porcelain` of the working-tree file, for the Changes panel''s Annotate gutter. Same lexical lane guard and secret refusal as /git/file, capped at 1 MB. A line nobody committed yet is null. An untracked file (no history) answers {available:false}. Read-only, no same-origin guard.'
|
||||
operationId: blameLaneFile
|
||||
parameters:
|
||||
- name: id
|
||||
in: path
|
||||
required: true
|
||||
schema:
|
||||
type: integer
|
||||
- name: path
|
||||
in: query
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
responses:
|
||||
'200':
|
||||
description: '{available, path, commits: {<sha>: {short, author, date, summary}}, lines: [<sha>|null]}.'
|
||||
'400':
|
||||
description: EBADPATH, ENOFILE or ETOOBIG.
|
||||
'403':
|
||||
description: ESECRET.
|
||||
'404':
|
||||
description: Lane not found.
|
||||
/api/lanes/{id}/git/raw:
|
||||
get:
|
||||
tags:
|
||||
@@ -11745,6 +11789,7 @@ paths:
|
||||
- revert
|
||||
- undo-commit
|
||||
- amend
|
||||
- ignore
|
||||
requestBody:
|
||||
required: false
|
||||
content:
|
||||
@@ -11779,10 +11824,24 @@ paths:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
description: stage, unstage, discard; each must be a path git reports changed.
|
||||
description: 'stage, unstage, discard, ignore (untracked only, else 400 ETRACKED; appends an anchored line to the workspace''s .gitignore); each must be a path git reports changed. commit and amend: commit exactly these files'' working-tree content (`git commit --only`), an untracked one included, leaving every other change — staged or not — uncommitted; a conflicted one is 409 ECONFLICTS. amend with an empty list rewords only (a message is then required, else 400 ENOCHANGES).'
|
||||
path:
|
||||
type: string
|
||||
description: stage-hunk, discard-hunk; a path git reports changed (not untracked).
|
||||
hunks:
|
||||
type: object
|
||||
additionalProperties:
|
||||
type: array
|
||||
items:
|
||||
type: object
|
||||
properties:
|
||||
hunk:
|
||||
type: string
|
||||
blocks:
|
||||
type: array
|
||||
items:
|
||||
type: integer
|
||||
description: 'commit, amend (optional): the hunk-level commit — per tracked, non-renamed path, only these change blocks of these hunks (`@@` lines as the diff at `context` returned them). Built in a temporary index from git''s own fresh diff and committed from it; the real index entries of the committed paths are then reset to the new HEAD, the rest of a partial file left as an unstaged change. A hunk no longer in the diff is 409 EHUNKGONE, an untracked path 400 EUNTRACKED, a bad shape 400 EBADPATH.'
|
||||
hunk:
|
||||
type: string
|
||||
description: stage-hunk, discard-hunk; the hunk's `@@` line as the diff returned it. The server re-reads the diff and applies git's own text of that hunk; a hunk no longer present is 409 EHUNKGONE.
|
||||
@@ -12706,6 +12765,75 @@ paths:
|
||||
description: 'EBADORIGIN: another site asked'
|
||||
'409':
|
||||
description: 'EFOREIGN: a unit named agenthub that AgentHub did not write'
|
||||
/api/settings/tray:
|
||||
get:
|
||||
tags:
|
||||
- Settings
|
||||
summary: Whether AgentHub's icon shows in the OS status area
|
||||
operationId: getTray
|
||||
responses:
|
||||
'200':
|
||||
description: Status-area icon state
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
required:
|
||||
- available
|
||||
- enabled
|
||||
- running
|
||||
properties:
|
||||
available:
|
||||
type: boolean
|
||||
description: False in server mode, or on Linux with no graphical session
|
||||
enabled:
|
||||
type: boolean
|
||||
description: On by default
|
||||
running:
|
||||
type: boolean
|
||||
description: The icon process is heartbeating
|
||||
put:
|
||||
tags:
|
||||
- Settings
|
||||
summary: Show or hide the status-area icon
|
||||
description: Clears or writes `<data dir>/runtime/tray-off` and starts or stops the icon process. Never touches the server. Same-origin only.
|
||||
operationId: setTray
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
required:
|
||||
- enabled
|
||||
properties:
|
||||
enabled:
|
||||
type: boolean
|
||||
responses:
|
||||
'200':
|
||||
description: The new state
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
required:
|
||||
- available
|
||||
- enabled
|
||||
- running
|
||||
properties:
|
||||
available:
|
||||
type: boolean
|
||||
description: False in server mode, or on Linux with no graphical session
|
||||
enabled:
|
||||
type: boolean
|
||||
description: On by default
|
||||
running:
|
||||
type: boolean
|
||||
description: The icon process is heartbeating
|
||||
'400':
|
||||
description: 'EBADVALUE: `enabled` is not a boolean'
|
||||
'403':
|
||||
description: 'EBADORIGIN: another site asked'
|
||||
/api/settings/codex-hooks:
|
||||
get:
|
||||
tags:
|
||||
@@ -13426,6 +13554,274 @@ paths:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/ErrorResponse'
|
||||
post:
|
||||
tags:
|
||||
- Auth
|
||||
operationId: createServerUser
|
||||
summary: 'Admin: add an account. Needs the admin''s own password again (currentPassword); audited'
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
required:
|
||||
- username
|
||||
- password
|
||||
- currentPassword
|
||||
properties:
|
||||
username:
|
||||
type: string
|
||||
password:
|
||||
type: string
|
||||
minLength: 8
|
||||
role:
|
||||
type: string
|
||||
enum:
|
||||
- admin
|
||||
- analyst
|
||||
- member
|
||||
default: member
|
||||
currentPassword:
|
||||
type: string
|
||||
responses:
|
||||
'201':
|
||||
description: Created
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
user:
|
||||
$ref: '#/components/schemas/AuthUser'
|
||||
'400':
|
||||
description: EBADUSER / EBADPASSWORD / EBADROLE
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/ErrorResponse'
|
||||
'403':
|
||||
description: EREAUTH (own password wrong) / EREADONLY / EADMIN / ELOCALMODE
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/ErrorResponse'
|
||||
'409':
|
||||
description: EEXISTS
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/ErrorResponse'
|
||||
'429':
|
||||
description: ETOOMANY — 10 wrong passwords in 15 minutes
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/ErrorResponse'
|
||||
/api/users/{id}:
|
||||
patch:
|
||||
tags:
|
||||
- Auth
|
||||
operationId: updateServerUser
|
||||
summary: 'Admin: change a role and/or disable (ending every login) or enable. Never your own (ESELF)'
|
||||
parameters:
|
||||
- name: id
|
||||
in: path
|
||||
required: true
|
||||
schema:
|
||||
type: integer
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
required:
|
||||
- currentPassword
|
||||
properties:
|
||||
role:
|
||||
type: string
|
||||
enum:
|
||||
- admin
|
||||
- analyst
|
||||
- member
|
||||
disabled:
|
||||
type: boolean
|
||||
currentPassword:
|
||||
type: string
|
||||
responses:
|
||||
'200':
|
||||
description: Changed
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
user:
|
||||
$ref: '#/components/schemas/AuthUser'
|
||||
'400':
|
||||
description: EBADPASSWORD / EBADROLE / EBADFIELD
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/ErrorResponse'
|
||||
'403':
|
||||
description: EREAUTH (own password wrong) / EREADONLY / EADMIN / ELOCALMODE
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/ErrorResponse'
|
||||
'404':
|
||||
description: ENOUSER / ENOLANE
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/ErrorResponse'
|
||||
'409':
|
||||
description: ESELF — your own role or disable
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/ErrorResponse'
|
||||
'429':
|
||||
description: ETOOMANY — 10 wrong passwords in 15 minutes
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/ErrorResponse'
|
||||
/api/users/{id}/password:
|
||||
post:
|
||||
tags:
|
||||
- Auth
|
||||
operationId: resetServerUserPassword
|
||||
summary: 'Admin: a new password for that user; every login of theirs ends'
|
||||
parameters:
|
||||
- name: id
|
||||
in: path
|
||||
required: true
|
||||
schema:
|
||||
type: integer
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
required:
|
||||
- password
|
||||
- currentPassword
|
||||
properties:
|
||||
password:
|
||||
type: string
|
||||
minLength: 8
|
||||
currentPassword:
|
||||
type: string
|
||||
responses:
|
||||
'200':
|
||||
description: Changed
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
user:
|
||||
$ref: '#/components/schemas/AuthUser'
|
||||
'400':
|
||||
description: EBADPASSWORD / EBADROLE / EBADFIELD
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/ErrorResponse'
|
||||
'403':
|
||||
description: EREAUTH (own password wrong) / EREADONLY / EADMIN / ELOCALMODE
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/ErrorResponse'
|
||||
'404':
|
||||
description: ENOUSER / ENOLANE
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/ErrorResponse'
|
||||
'409':
|
||||
description: ESELF — your own role or disable
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/ErrorResponse'
|
||||
'429':
|
||||
description: ETOOMANY — 10 wrong passwords in 15 minutes
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/ErrorResponse'
|
||||
/api/users/{id}/workspaces:
|
||||
post:
|
||||
tags:
|
||||
- Auth
|
||||
operationId: assignServerUserWorkspace
|
||||
summary: 'Admin: make that user the owner of a workspace (lane)'
|
||||
parameters:
|
||||
- name: id
|
||||
in: path
|
||||
required: true
|
||||
schema:
|
||||
type: integer
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
required:
|
||||
- laneId
|
||||
- currentPassword
|
||||
properties:
|
||||
laneId:
|
||||
type: integer
|
||||
currentPassword:
|
||||
type: string
|
||||
responses:
|
||||
'200':
|
||||
description: Changed
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
user:
|
||||
$ref: '#/components/schemas/AuthUser'
|
||||
'400':
|
||||
description: EBADPASSWORD / EBADROLE / EBADFIELD
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/ErrorResponse'
|
||||
'403':
|
||||
description: EREAUTH (own password wrong) / EREADONLY / EADMIN / ELOCALMODE
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/ErrorResponse'
|
||||
'404':
|
||||
description: ENOUSER / ENOLANE
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/ErrorResponse'
|
||||
'409':
|
||||
description: ESELF — your own role or disable
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/ErrorResponse'
|
||||
'429':
|
||||
description: ETOOMANY — 10 wrong passwords in 15 minutes
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/ErrorResponse'
|
||||
/api/users/audit:
|
||||
get:
|
||||
tags:
|
||||
|
||||
Reference in New Issue
Block a user