fix: event-loop freezes, plugin-install boot crash, tmux attach/scrollbar, Codex transcripts

- GET /api/workflows: one LEAD() window pass in a read worker (read-pool.js,
  workflow-stats.js); idx_events_session restored, idx_events_tool added
- compat-sqlite gains function/pluck/readonly so a plugin install without a
  better-sqlite3 build boots again; antigravity-usage uses db.js's Database
- install-hooks adds no checkout hooks while the agenthub plugin is enabled
  (events were doubled)
- terminal attach runs the live tmux server's own binary; the pane scrollbar
  gets a visible 2-column style, and claude panes start with
  CLAUDE_CODE_DISABLE_ALTERNATE_SCREEN=1 so tmux keeps history to scroll
- Codex sessions' conversation in GET /api/sessions/:id/transcript
- Codex/Antigravity sessions claimed by their workspace without hooks
- UI-audit follow-ups, docs and OpenAPI
This commit is contained in:
2026-10-05 17:01:05 +07:00
parent 442f133930
commit 198fbb7980
78 changed files with 2716 additions and 873 deletions
+35 -15
View File
@@ -1753,7 +1753,7 @@ components:
type: boolean
source:
type: string
description: Uploaded filename or server-side path read.
description: The uploaded file's name.
format:
type: string
nullable: true
@@ -6159,10 +6159,17 @@ paths:
tags:
- Workflows
summary: Get workflow intelligence aggregates
description: 'Returns the full workflow-intelligence aggregate powering the Workflows analytics page — 11 sections in one payload: `stats` (headline counters: sessions, agents, subagents, success rate, avg depth/duration, compactions, top tool flow), `orchestration` (subagent-type breakdown + delegation edges + outcomes), `toolFlow` (tool-to-tool transitions + tool counts), `effectiveness` (per-subagent-type success rate, avg duration, weekly trend), `patterns` (frequent subagent sequences + solo-session share), `modelDelegation` (model usage for main/sub agents + tokens by model), `errorPropagation` (errors by depth/type + error rate), `concurrency` (averaged agent swim-lane start/end), `complexity` (per-session agent/token/duration rows), `compaction` (compaction counts + tokens recovered), and `cooccurrence` (directed subagent-after-subagent pairs). The optional `status` query filter scopes every section to sessions of one status. Errors use the SHORT `{ error: { message } }` shape.'
description: 'Returns the full workflow-intelligence aggregate powering the Workflows analytics page — 11 sections in one payload: `stats` (headline counters: sessions, agents, subagents, success rate, avg depth/duration, compactions, top tool flow), `orchestration` (subagent-type breakdown + delegation edges + outcomes), `toolFlow` (tool-to-tool transitions + tool counts), `effectiveness` (per-subagent-type success rate, avg duration, weekly trend), `patterns` (frequent subagent sequences + solo-session share), `modelDelegation` (model usage for main/sub agents + tokens by model), `errorPropagation` (errors by depth/type + error rate), `concurrency` (averaged agent swim-lane start/end), `complexity` (per-session agent/token/duration rows), `compaction` (compaction counts + tokens recovered), and `cooccurrence` (directed subagent-after-subagent pairs). The optional `status` query filter scopes every section to sessions of one status, and `sections` computes and returns only the named ones (`stats.topFlow` is the head of `toolFlow.transitions`, one pass for both). The bundle is computed in a worker thread on its own read-only connection, so it never stalls other requests; identical requests in flight share one run, and one over `AGENTHUB_READ_TIMEOUT_MS` (default 60 s) answers 503 `EREADTIMEOUT`. Errors use the SHORT `{ error: { message } }` shape.'
operationId: getWorkflowIntelligence
parameters:
- $ref: '#/components/parameters/WorkflowStatusQuery'
- name: sections
in: query
required: false
description: 'Comma-separated subset of the bundle to compute: stats, orchestration, toolFlow, effectiveness, patterns, modelDelegation, errorPropagation, concurrency, complexity, compaction, cooccurrence. Unknown names are ignored; none known is a 400.'
schema:
type: string
example: stats,toolFlow
responses:
'200':
description: Workflow aggregate data
@@ -6306,6 +6313,16 @@ paths:
- source: Explore
target: general-purpose
weight: 142
'400':
description: '`sections` names no known section'
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
example:
error:
code: INVALID_SECTIONS
message: 'sections must name some of: stats, …'
'500':
description: Internal server error
content:
@@ -6315,6 +6332,16 @@ paths:
example:
error:
message: 'no such table: agents'
'503':
description: The aggregate ran past `AGENTHUB_READ_TIMEOUT_MS`
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
example:
error:
code: EREADTIMEOUT
message: read query took over 60000 ms
/api/workflows/session/{id}:
get:
tags:
@@ -13075,7 +13102,7 @@ paths:
tags:
- Settings
summary: Restore (import) a previously exported data bundle
description: 'Restores a bundle produced by GET /api/settings/export. Supply it either as `multipart/form-data` with a single `file` field (browser upload) or as a JSON body `{ "path": "<absolute path>" }` (the server reads the file from disk — used by the `agenthub import-data` CLI, and it also sidesteps the global 1 MB JSON body cap for large bundles). The restore is idempotent and NON-DESTRUCTIVE: it is session-atomic, so a session already present (matched by its UUID) is skipped whole together with its agents/events/token_usage/workflows, and independent config rows (dashboard_runs, alert_rules, model_pricing) are inserted only when absent. Nothing existing is overwritten — ideal for consolidating several machines into one dashboard. The response reports per-table counts.'
description: 'Restores a bundle produced by GET /api/settings/export, uploaded as `multipart/form-data` with a single `file` field (the dashboard''s Restore button and the `agenthub import-data` CLI both upload it; the server never reads a path named by a request). Same-origin only. At most 512 MB (`413 FILE_TOO_LARGE`); a file that is not JSON or not an export answers `400 INVALID_FORMAT` without echoing its text, no file `400 NO_FILE`. The restore is idempotent and NON-DESTRUCTIVE: it is session-atomic, so a session already present (matched by its UUID) is skipped whole together with its agents/events/token_usage/workflows, and independent config rows (dashboard_runs, alert_rules, model_pricing) are inserted only when absent. Restored event payloads are trimmed like every event insert (`trim_event_data`). Nothing existing is overwritten — ideal for consolidating several machines into one dashboard. The response reports per-table counts.'
operationId: importData
requestBody:
required: true
@@ -13088,17 +13115,6 @@ paths:
type: string
format: binary
description: The export .json file.
application/json:
schema:
type: object
required:
- path
properties:
path:
type: string
description: Absolute path (server-side) to an export .json file. `~` is expanded.
example:
path: /Users/you/agenthub-export-2026-06-26.json
responses:
'200':
description: Per-table restore counts
@@ -13121,5 +13137,9 @@ paths:
model_pricing: 0
errors: 0
'400':
description: Missing file, invalid JSON, or unrecognized export format
description: Missing file (NO_FILE), invalid JSON or unrecognized export format (INVALID_FORMAT)
'403':
description: Cross-origin request (EBADORIGIN)
'413':
description: The file is larger than 512 MB (FILE_TOO_LARGE)
x-issues-url: https://git.smartgift.io.vn/Smartgift-AI/AgentHub/issues