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
+15 -2
View File
@@ -96,6 +96,14 @@ const historyIdx = (): number => {
return typeof idx === "number" ? idx : 0;
};
/**
* How far Back moves: to the entry before the one Settings was entered at, and
* always at least one step — after a browser Back below that entry, the plain
* difference would be 0 (`history.go(0)`, a reload) or a step forward.
*/
export const backDelta = (current: number, entry: number): number =>
-Math.max(1, current - entry + 1);
/** An unknown section: say so, then show General. */
function UnknownSection({ name }: { name: string }) {
const { t } = useTranslation("settings");
@@ -142,7 +150,12 @@ export function SettingsHub() {
// Deep link to a row: scroll to the anchor once the page has rendered it
// (content loads async, so poll briefly) and highlight it for a moment.
useEffect(() => {
const id = decodeURIComponent(location.hash.slice(1));
let id = location.hash.slice(1);
try {
id = decodeURIComponent(id);
} catch {
// A malformed escape (`#%`): look the raw text up instead of crashing.
}
if (!id) return;
let timer: number | undefined;
let lit: Element | null = null;
@@ -363,7 +376,7 @@ export function SettingsHub() {
const back = (e: MouseEvent) => {
if (!canGoBack) return;
e.preventDefault();
navigate(-(historyIdx() - (entryIdx.current ?? 0) + 1));
navigate(backDelta(historyIdx(), entryIdx.current ?? 0));
};
return (