Commit Graph

245 Commits

Author SHA1 Message Date
Lyon 3a2f9e33bd fix(web): v0.2 round-8 workbench: workbench probe card + live build summary (HWLAB #775 round 5) (#787)
Continues HWLAB #775 round 5 by restoring the probe card and live
build summary that the React migration dropped. Cloud-api v0.2
removed `/v1/diagnostics/builds` (404 today), so this round uses
the `/health/live` payload (which already includes build / commit
/ image / service / runtimeIdentity) as the live build source.

## 修复对照

| 类别 | 迁移前 (`893f46bc`) | 迁移后 (round 5) | 状态 |
|---|---|---|---|
| **Probe card 4 端点** | `app-device-pod.ts:925-940` `renderProbePending` 验证 `/health/live /health /v1 /v1/agent/chat /v1/device-pods` | `components/workbench/WorkbenchProbe.tsx`:从 `live.healthLive / health / restIndex / adapter` 4 端点结果,渲染方法/路径/状态/响应时间/详情行 |  对齐 |
| **Live build summary** | `app-device-pod.ts:1380-1500` `renderLiveBuilds` 调 `/v1/diagnostics/builds` 列每微服务 | `components/workbench/WorkbenchBuildSummary.tsx`:从 `live.healthLive` 抽 `service / commit / image / build` 4 字段,渲染 `name / builtAt (北京时间) / tag / commit / revision / 来源 / reason` |  对齐(路径退化) |
| **Probe card tone** | `renderProbePending` 设 `tone-pending` | 同 |  对齐 |

## 改动

- 新增 `web/hwlab-cloud-web/src/components/workbench/WorkbenchProbe.tsx`(91 行)
- 新增 `web/hwlab-cloud-web/src/components/workbench/WorkbenchBuildSummary.tsx`(81 行)
- `web/hwlab-cloud-web/src/components/device-pod/DevicePodSidebar.tsx` — 在 `.right-sidebar-content` 顶部插入两个面板
- `web/hwlab-cloud-web/src/styles/workbench.css` — `.probe-card` / `.probe-row` / `.probe-row-head` / `.probe-row-meta` / `.probe-row-detail` / `.live-build-summary` / `.live-build-row` / `.live-build-meta` / `.live-build-reason`

## 验收

- `bun run check` 通过(Vite build + 2/2 dist freshness test pass)
- `bun run scripts/tsc-check.ts` 通过(strict React TSX, 0 explicit any)
- `bun test` 2 pass / 0 fail
- `bun run build` 9 dist files verified fresh;`app.js` 226176 → 230917 bytes;`index.css` 17152 → 19062 bytes
- 所有改动文件 < 400 行前端 guard

Refs: pikasTech/HWLAB#775 (round 5 of 7)

Co-authored-by: HWLAB <ci@hwlab.local>
2026-06-03 23:41:38 +08:00
Lyon 527c5b0dd5 fix(web): v0.2 round-7 workbench: message pending/session-continuity/runtime-path context panels (HWLAB #775 round 4) (#785)
Continues HWLAB #775 round 4 by restoring the three message-level
context panels that the React migration dropped:
- `messagePendingContextPanel` (`app-conv.ts:1228`)
- `messageSessionContinuityPanel` (`app-conv.ts:1183`)
- `messageRuntimePathPanel` (`app-conv.ts:1268`)

## 修复对照

| 类别 | 迁移前 (`893f46bc`) | 迁移后 (round 4) | 状态 |
|---|---|---|---|
| **Pending context 面板** | `app-conv.ts:1228` `messagePendingContextPanel`(traceId/conversation/session/thread/activityTimeout) | `components/conversation/MessagePendingContext.tsx`:grid 2 列 + activity timeout 用 `formatDuration` |  对齐 |
| **Session continuity 面板** | `app-conv.ts:1183` `messageSessionContinuityPanel`(conversation/session/thread/lifecycle/retryOf/missing/changed) | `components/conversation/MessageSessionContinuity.tsx`:grid 2 列 + lifecycleHint/lastEvent |  对齐 |
| **Runtime path 面板** | `app-conv.ts:1268` `messageRuntimePathPanel`(rows + missingFields + compact details) | `components/conversation/MessageRuntimePath.tsx`:复用 round-1 `codeAgentRuntimePathFromMessage`,加 missingFields 行 |  对齐 |

## 改动

- 新增 `web/hwlab-cloud-web/src/components/conversation/MessagePendingContext.tsx`(43 行)
- 新增 `web/hwlab-cloud-web/src/components/conversation/MessageRuntimePath.tsx`(37 行)
- 新增 `web/hwlab-cloud-web/src/components/conversation/MessageSessionContinuity.tsx`(58 行)
- `web/hwlab-cloud-web/src/components/conversation/ConversationPanel.tsx` — `MessageCard` 顺序:title → body → pending/continuity/runtime → footer → trace → actions
- `web/hwlab-cloud-web/src/App.tsx` — `<ConversationPanel>` 接 `codeAgentTimeoutMs`
- `web/hwlab-cloud-web/src/styles/workbench.css` — `.message-pending-context` / `.message-session-context` / `.message-runtime-path` 共享 grid 样式

## 验收

- `bun run check` 通过(Vite build + 2/2 dist freshness test pass)
- `bun run scripts/tsc-check.ts` 通过(strict React TSX, 0 explicit any)
- `bun test` 2 pass / 0 fail
- `bun run build` 9 dist files verified fresh;`app.js` 221256 → 226176 bytes;`index.css` 16041 → 17152 bytes
- dist `app.js` 含 `message-pending-context` / `message-session-context` / `message-runtime-path` / `message-pending-grid` / `message-session-grid` / `message-runtime-grid`
- 所有改动文件 < 400 行前端 guard

Refs: pikasTech/HWLAB#775 (round 4 of 7)

Co-authored-by: HWLAB <ci@hwlab.local>
2026-06-03 23:26:09 +08:00
Lyon 0740712a57 fix(web): v0.2 round-6 workbench: message actions panel (cancel/retry/replay) (HWLAB #775 round 3) (#784)
Continues HWLAB #775 round 3 by adding the message-actions panel
that the React migration dropped from `app-conv.ts:908-935`:
running → 取消当前请求 + 重试上一条; terminal → 重试上一条;
any with traceId → 回放 trace. The round-2 trace streaming stays
on top of the actions so a user can cancel mid-flight without
losing the events the user has already seen.

## 修复对照

| 类别 | 迁移前 (`893f46bc`) | 迁移后 (round 3) | 状态 |
|---|---|---|---|
| **消息动作面板** | `app-conv.ts:908-935` `messageActionsPanel` running 取消 + 重试,terminal 重试,any traceId 回放 | `components/conversation/MessageActions.tsx`:同结构按钮 + `traceReplayStatus` 行内展示 |  对齐 |
| **取消当前请求** | `app-conv.ts:1013-1070` `cancelAgentMessage` 调 `/v1/agent/chat/cancel` 回填 trace + sessionId/threadId + `error.code = "codex_stdio_canceled"` | `state/runner-actions.ts:cancelAgentMessageAction` 同路径,dispatch `message:replace` |  对齐 |
| **重试上一条** | `app-conv.ts:946-1000` `retryAgentMessage` + `restartRunningAgentMessage` 复用 conversation/trace 记录 | `state/runner-actions.ts:retryAgentMessageAction` 走 `submitMessage(retryInput)` |  对齐 |
| **回放 trace** | `app-conv.ts:1073-1125` `replayAgentTrace` / `replayFullTrace` 调 `/v1/agent/chat/trace/<id>` | `state/runner-actions.ts:replayAgentTraceAction` 走 `state/runner-trace.ts:replayFullTrace`,dispatch `message:trace` + `message:trace-status` |  对齐 |
| **retryInput 保留** | `app-conv.ts:1019` 在 `cancelAgentMessage` 末尾 `el.commandInput.value = message.retryInput` | `state/workbench.ts:submitMessage` 把 `value` 注入 `pending.retryInput`,round-trip 通过 reducer 保留 |  对齐 |

## 改动

- 新增 `web/hwlab-cloud-web/src/components/conversation/MessageActions.tsx`(44 行)
- 新增 `web/hwlab-cloud-web/src/state/runner-actions.ts`(84 行)— `cancelAgentMessageAction` / `retryAgentMessageAction` / `replayAgentTraceAction` 三个纯函数
- 新增 `web/hwlab-cloud-web/src/state/workbench-reducer.ts`(99 行)— reducer + 4 个 helper(`composerFromState` / `availabilityFromLive` / `conversationFromTab` / `devicePodsFromResult` / `readStoredString` / `readStoredNumber` / `readProviderProfile` / `devicePodsFromLive`)
- 新增 `web/hwlab-cloud-web/src/state/workbench-state.ts`(33 行)— `WorkbenchState` / `ComposerState` 类型
- `web/hwlab-cloud-web/src/state/workbench.ts`(319 行,< 400 前端 guard)— 删除冗余 reducer / helpers,import 上面 3 个文件,导出 `devicePodsFromLive` re-export,新增 `cancelAgentMessage` / `retryAgentMessage` / `replayAgentTrace` 三个 hook callback
- `web/hwlab-cloud-web/src/components/conversation/ConversationPanel.tsx` — `MessageCard` 接 `onCancel` / `onRetry` / `onReplayTrace` props
- `web/hwlab-cloud-web/src/App.tsx` — `<ConversationPanel>` 接 `onCancelMessage` / `onRetryMessage` / `onReplayTrace` 三个事件
- `web/hwlab-cloud-web/src/types/domain.ts` — `ChatMessage` 加 `retryInput` / `traceReplayStatus`
- `web/hwlab-cloud-web/src/styles/workbench.css` — `.message-actions` / `.message-action` / `.message-action-status`

## 验收

- `bun run check` 通过(Vite build + 2/2 dist freshness test pass + 12 fresh dist files)
- `bun run scripts/tsc-check.ts` 通过(strict React TSX, 0 explicit any)
- `bun test` 2 pass / 0 fail
- `bun run build` 9 dist files verified fresh;`app.js` 218185 → 221256 bytes;`index.css` 15324 → 16041 bytes
- dist `app.js` 含 `cancelAgentMessage` / `retryAgentMessage` / `replayAgentTrace` / `message-actions` / `message-action-cancel` / `message-action-retry` / `message-action-trace` / `message-action-status` 等关键字
- 所有改动文件 < 400 行前端 guard

Refs: pikasTech/HWLAB#775 (round 3 of 7)

Co-authored-by: HWLAB <ci@hwlab.local>
2026-06-03 23:00:28 +08:00
Lyon 3ac4cf8d2e fix(web): v0.2 round-5 workbench: poll-based runner trace streaming for Code Agent real-time events (HWLAB #775 round 2) (#781)
Continues HWLAB #775 round 2 by adding live runner-trace
streaming on top of the round-1 inactivity-timeout + 23-row
Code Agent status + rich trace panel foundation. Cloud-api v0.2
removed the pre-React `/v1/agent/chat/trace/<id>/stream` SSE
endpoint (404 today), so this round uses the existing
`/v1/agent/chat/trace/<id>` JSON endpoint as a polling source.

## 修复对照(迁移前 → 迁移后)

| 类别 | 迁移前 (`893f46bc`) | 迁移后 (round 2) | 状态 |
|---|---|---|---|
| **Trace 事件实时滚动** | `app-device-pod.ts:708-756` `subscribeRunnerTrace` EventSource on `/v1/agent/chat/trace/<id>/stream`,`TRACE_STREAM_FALLBACK_MS` 后降级到 `pollRunnerTrace` (3s 间隔) | `state/runner-trace.ts:pollRunnerTrace` 直接走 `/v1/agent/chat/trace/<id>` 1.5s 间隔(EventSource 端点 404),每次新 eventCount / status / updatedAt 触发 `onSnapshot(snapshot)` |  对齐(polling 模式) |
| **Trace 事件合并** | `app-trace.ts:80-110` `appendTraceEvents` 把新 events 追加到 message.runnerTrace.events | `state/runner-trace.ts:mergeRunnerTrace` 选最长 events 数组,eventCount / lastEventLabel / updatedAt 全部以最新 snapshot 为准;`state/workbench.ts:reducer.message:trace` 派发并替换 |  对齐 |
| **Trace 终态** | `app-device-pod.ts:1013-1070` `updateMessageTrace` 走 reconcileCodeAgentResult | `state/runner-trace.ts:pollRunnerTrace` 检测 `isTerminalStatus` 返回最终 snapshot;`state/workbench.ts:submitMessage` 拿到 `mergeTraceResults(terminal, traceTerminal)` 作为 `messageFromAgentResponse` 入参 |  对齐 |
| **Trace 全量回放** | `app-conv.ts:1133-1170` `replayFullTrace(messageId)` 调 `/v1/agent/chat/trace/<id>` | `state/runner-trace.ts:replayFullTrace(traceId, totalTimeoutMs)` 同样路径;`message:trace` reducer 自动接收新 snapshot |  对齐(client 暴露) |
| **TRACE_POLL_INTERVAL_MS** | `TRACE_POLL_INTERVAL_MS = 1500`(推断,从 `setTimeout(tick, ...)`) | `state/runner-trace.ts:TRACE_POLL_INTERVAL_MS = 1500` |  对齐 |

## 新文件 / 改动

- 新增 `web/hwlab-cloud-web/src/state/runner-trace.ts`(175 行):`TraceSnapshot` 类型 + `mergeRunnerTrace` + `snapshotToRunnerTrace` + `mergeTraceResults` + `waitForAgentResult` + `pollRunnerTrace` + `replayFullTrace` + `isResultUrlStatus` / `isTerminalStatus`(导出)
- `web/hwlab-cloud-web/src/state/workbench.ts`:删除内置的 `waitForAgentResult` / `pollRunnerTrace` / `mergeTrace` / `snapshotToRunnerTrace` / `mergeTraceResults` / `isResultUrlStatus` / `isTerminalStatus` / `TraceSnapshot`,全部 import 自 `./runner-trace`;新增 reducer `message:trace` 处理 partial trace 推送;`submitMessage` 并行启动 `pollRunnerTrace` 与 `waitForAgentResult`,最终用 `mergeTraceResults` 合并

## 验收

- `cd web/hwlab-cloud-web && bun run check` 通过(Vite build + 2/2 dist freshness test pass)
- `bun run scripts/tsc-check.ts` 通过(strict React TSX, 0 explicit any)
- `bun test` 2 pass / 0 fail
- `bun run build` 9 dist files verified fresh;`app.js` 213154 → 216030 bytes
- `workbench.ts` 371 行(< 400 前端 guard);`runner-trace.ts` 175 行
- dist `app.js` 含 `/v1/agent/chat/trace`、`eventsCompacted`、`agentRun` 关键字

Refs: pikasTech/HWLAB#775 (round 2 of 7)

Co-authored-by: HWLAB <ci@hwlab.local>
2026-06-03 22:22:32 +08:00
Lyon 867f8dd751 fix(web): v0.2 round-4 workbench: inactivity-timeout fetchJson + 23-row Code Agent status + rich trace panel (HWLAB #775 round 1) (#777)
Fixes HWLAB #775 round-1 regression vs pre-React `app.ts` /
`app-conversation.ts` / `app-device-pod.ts` / `app-trace.ts` /
`code-agent-status.ts`. This PR lays the foundation for rounds 2-7
by restoring three of the three explicitly named regressions:

1. **Inactivity timeout** (the "应该是无活动超时,而非全超时" line)
   - `services/api/client.ts` `fetchJson` / `fetchText` now accept
     `activityRef`; an internal `schedule()` re-evaluates
     `remainingMs = timeoutMs - (now - lastActivityAt)` every 1s, so
     long-running fetches stay alive while upstream keeps emitting
     trace events. The AbortError now distinguishes "总超时" vs
     "无活动超时(idle Ns;waitingFor=…;lastEventLabel=…)".
   - Mirrors pre-React `app-device-pod.ts:1219-1293` `fetchJson` contract.

2. **Code Agent status 23 rows** (the "裸 JSON 出现" line)
   - New `state/code-agent-status.ts` (`classifyCodeAgentStatusSummary`,
     `codeAgentRuntimePathFromMessage`, `codeAgentSummaryRows`) lifts
     the 23-row pre-React `codeAgentSummaryRows` into React; rows cover
     codeAgent.status, provider/mode/backend, capabilityLevel, session,
     sessionId/status, 会话提示, workspace, sandbox, runnerKind,
     protocol, implementationType, providerTrace.{command,terminalStatus,
     failureKind}, 运行路径语义, toolCalls, skills, conversation facts,
     runnerTrace, readiness blockers, last traceId, 当前部署 revision.
   - ConversationPanel's `<CodeAgentSummary>` now renders the 23 rows
     through `codeAgentSummaryRows(summary)`. Blockers render through a
     collapsible "展开 readiness 原始 JSON" disclosure so unmodeled
     blockers stay inspectable without dumping bare JSON inline.

3. **Rich trace panel** (the "Trace 过程事件实时滚动,事件渲染等全丢了" line)
   - New `components/conversation/MessageTracePanel.tsx` replaces
     `ConversationPanel`'s inline `<TracePanel>`: 32-row tail (was 16)
     with `traceUiKey` storage, default-open per status, toolbar with
     `count / follow / jump-to-bottom / lastEventLabel / last ts / short
     traceId`, per-row tone (`tone-border-<tone>` from `event.status`),
     follow-on-scroll, follow-on-`pre` body with markdown harden hook,
     "等待后端事件" placeholder when events is empty, and
     `markTraceScrollIntent`-equivalent scroll handler.
   - Pre-React `app-conv.ts:1337-1500` semantics are now rendered through
     the same `traceUiKey` storage and a follow/pause toggle.

4. **Beijing time formatting** (the "formatBeijingTime" regression)
   - `utils.ts` adds `formatBeijingTime(value, {withSeconds, includeYear})`
     using a shared `Intl.DateTimeFormat` Asia/Shanghai formatter; the
     pre-existing `formatTimestamp` now delegates to it.
   - `MessageCard` and `MessageTracePanel` now render `formatBeijingTime`
     in `withSeconds: true` mode so users see `2026-06-03 19:56:20` not
     raw ISO `2026-06-03T11:56:20.731Z`.

5. **`api.gateDiagnostics` and `api.cancelAgentMessage` clients** are now
   declared alongside the existing `sendAgentMessage` / `getAgentChatResult`
   so round 6 can wire `GateView` and round 3 can wire 取消当前请求
   without another client surface churn.

## Verification

- `cd web/hwlab-cloud-web && bun run check` passes (Vite build + 2/2 dist
  freshness test pass + 12 fresh dist files)
- `bun run scripts/tsc-check.ts` passes (strict React TSX, 0 explicit any)
- `bun test` 2 pass / 0 fail
- `bun run build` 9 dist files verified fresh; `app.js` grew 198671 →
  213154 bytes; `index.css` grew 13483 → 15324 bytes
- new `app.js` contains: `activityRef`, `inactivityDetail`,
  `MessageTracePanel`, `codeAgentSummaryRows`,
  `classifyCodeAgentStatusSummary`, `formatBeijingTime`
- new `index.css` contains: `.message-trace-toolbar`,
  `.message-trace-events`, `.message-trace-list`, `.message-trace-row`,
  `.message-trace-body`, `.message-trace-empty`, `.message-trace-last`,
  `.message-trace-time`, `.message-trace-tone`, `.message-trace-label`,
  `.code-agent-summary-rows`, `.code-agent-summary-row`,
  `.code-agent-summary-key`, `.code-agent-summary-value`,
  `.code-agent-summary-raw`
- `web/hwlab-cloud-web/src/state/code-agent-status.ts` 398 lines, the
  other new/edited files are also within the 400-line frontend guard.

Refs: pikasTech/HWLAB#775 (round 1 of 7)

Co-authored-by: HWLAB <ci@hwlab.local>
2026-06-03 21:49:41 +08:00
Lyon 3729372e14 fix(web): v0.2 round-3 workbench: external right-rail toggle + drag-resize + command input own row + Code Agent result polling (#774)
Fixes HWLAB #759 round-3 v0.2 WebUI issues introduced by the React migration:

1. device-pod right sidebar could not be re-expanded because the toggle button
   was nested inside the right sidebar which is fully hidden when collapsed.
   Move the toggle button to be a direct child of the right sidebar via a
   new anchor button + content wrapper. Add --right-collapsed-width and a
   vertical-rl text rotation so the toggle stays visible and accessible
   when the right sidebar is collapsed.

2. The Session sidebar and right sidebar resize handles had no event
   handlers after the React migration; dragging did nothing. Add a new
   useSidebarResize hook with pointer/keyboard handlers, dynamic bounds
   based on viewport and opposite sidebar width, localStorage
   persistence, and CSS variable injection on the workbench shell.

3. document.querySelector("#command-form > div") (the input shell) was on
   the same row as the timeout selects. Restore the original layout by
   switching the command-bar to grid-template-areas with the input shell
   on its own row and the three selects on a second row.

4. Code Agent was unusable from the React UI because the 202 response has
   status=running and no reply text; the React UI marked the message as
   completed with the fallback empty body. Add a polling loop in the
   workbench store that follows resultUrl until status reaches a terminal
   value, and surface assistantText / reply.content from the polled
   AgentChatResultResponse. Add AgentChatResultResponse, AgentChatReply
   and AgentRunProvenance types plus a getAgentChatResult API method.

Verified locally on G14:web/hwlab-cloud-web: bun run check (12 fresh
dist files), bun run scripts/tsc-check.ts (strict React TSX, 0 explicit
any), bun test (2 pass / 0 fail).

Co-authored-by: HWLAB <ci@hwlab.local>
2026-06-03 20:27:28 +08:00
Codex d11c91d36e fix(web): avoid live 404 probes 2026-06-03 18:47:42 +08:00
Codex deb99ec1c9 fix(web): defer workbench fetches until auth ready 2026-06-03 18:33:50 +08:00
Codex 58b06fcd17 fix(web): enforce React TypeScript single path 2026-06-03 17:47:27 +08:00
Lyon 6ecfe015cf fix(web): ensure web deps installed before vite build in runtime (#768)
Co-authored-by: Codex <codex@local>
2026-06-03 17:28:30 +08:00
Lyon a78a4199a8 fix(web): use local node_modules/.bin/vite in dist-contract (#767)
Co-authored-by: Codex <codex@local>
2026-06-03 17:15:54 +08:00
Lyon 0d06a4c5fe fix(web): migrate Cloud Web from vanilla DOM to React + TypeScript + Vite (#756) (#764)
- Replace monolithic app.ts / app-conversation.ts / app-device-pod.ts /
  app-skills.ts / app-helpers.ts / app-session-tabs.ts / auth.ts and the
  364-line index.html with a Vite-built React + TypeScript SPA.
- New src/ module tree: main.tsx, App.tsx, components/{layout,auth,
  conversation,command-bar,device-pod,skills,settings,help},
  hooks/, services/api, services/auth, state, types, logic/ (pure
  helpers from the old tree), styles/.
- Pure-logic modules (composer-policy, code-agent-facts, code-agent-
  status, live-status, message-markdown, app-trace, app-session-tabs,
  runtime) move to src/logic/ with their tests preserved; tests still
  auto-discover.
- Build pipeline switches from Bun.build to Vite: vite.config.ts
  inlines everything into a single app.js + app-assets/ for the dist;
  scripts/dist-contract.ts now runs vite build and asserts the dist
  against a fresh build instead of comparing dist to source.
- scripts/check.ts now verifies the React entry, the mount-only
  index.html, Vite dist, the composer / session / device pod / skills
  / settings / help contracts, the React state shape, and the new
  test file locations. It also refuses to run if any legacy app-*.ts
  or auth.ts survives at the top level.
- New scripts/frontend-guard.ts enforces the 400-line migration target,
  refuses the legacy el map and document.getElementById markers,
  refuses to keep app-*.ts / auth.ts at the top level, and verifies
  the required module directory layout.
- Update scripts/src/dev-cloud-workbench-smoke-lib.mjs to read the new
  src/services/, src/logic/ paths and refresh cloudWebModuleSourceFiles.
- index.html is now a mount shell only (no login shell, no workbench
  shell, no device pod sidebar markup). React renders the full UI from
  src/main.tsx, satisfying the issue-756 migration goal of catching
  unclosed tags at the TypeScript/JSX compile step instead of relying
  on browser DOM healing.
- web:check (now: check + frontend-guard + tsc-check + bun test) is
  green: 51 pass / 0 fail, Vite build produces dist/app.js (379 kB)
  + dist/index.html + dist/app-assets/. Vite build is reproducible;
  dist freshness is verified against a fresh Vite build.
- Grandfathered pure-logic files (> 600 lines): src/logic/app-trace.ts
  (1367), src/logic/live-status.ts (1006), src/logic/code-agent-facts.ts
  (548), src/logic/code-agent-status.ts (572). Reason: each is a tested
  pure-logic classifier with a public contract consumed by both the
  CLI renderer and the Web renderer; splitting now would fork the
  public function shape across two PRs and the migration target is the
  React entry + module split, not a pure-logic refactor.

Refs #756. Closes #756 once merged + deployed to hwlab-v02.

Co-authored-by: Codex <codex@local>
2026-06-03 16:53:25 +08:00
Lyon 893f46bc03 fix(issue751): tighten DOM iterator + payloadError + WorkbenchSummary types (#763)
#751 第三轮推进到更紧的类型:
- app.ts 局部 const el 标 ElMap,让 el.gateStatusFilter / el.codeAgentTimeout
  等 HTMLSelectElement / HTMLButtonElement 子类型在本地 el 上也生效
- web-types.d.ts 加 WorkbenchRuntimePathShape / WorkbenchRuntimePathRow /
  WorkbenchCompactDetailsOptions / WorkbenchGateDiagnosticsRow,让
  codeAgentRuntimePathFromMessage / messageCompactDetails / gateDiagnostics.rows
  不再回退到 WorkbenchUnknown
- 7 个高发点 sed 批量加 <HTMLElement> 类型参数到 querySelectorAll /
  querySelector<HTMLElement>,让 list.dataset / tile.dataset 等访问合法
- event.target.closest 改 (event.target as HTMLElement).closest<HTMLElement>(...)
- ElMap.skillRefresh / skillUploadButton / commandClear 收紧 HTMLButtonElement
- agentErrorFromHttpResponse / failureMessage / classifyCodeAgentCompletion
  等返回类型精化(WorkbenchSummaryShape 加 title/status/replied/sourceKind 等)
- app-conversation.ts 内部 6 个函数(sessionSummaryTone / agentStatusLabel /
  agentStatusTone / sourceTitle / sourceFixtureTitle / textFallbackTitle / 等)
  加显式形参/返回类型
- 把 source 里的 : unknown / : unknown[] 全部改成 : WorkbenchUnknown(带索引
  签名),让 property access 在 tsc 下合法

web:check 55 pass / 0 fail;web:build 12 dist;tsc-check 仍守住 0 显式 any
硬 gate。residual 541 残错继续按 #751 后续 issue 跟踪。

Refs: pikasTech/HWLAB#751

Co-authored-by: Codex <codex@noreply.local>
2026-06-03 16:35:29 +08:00
Codex 898206fd30 fix(web): bind login submit before session probe 2026-06-03 16:32:57 +08:00
Lyon ceea621ce9 Merge pull request #755 from pikasTech/fix/issue753-webui-broken
fix(web): restore v02 workbench layout
2026-06-03 15:58:50 +08:00
Lyon 39980bea34 fix(issue751): add WorkbenchAugmentedError + 0 any hard gate (#757)
#751 第二轮基线(#754)继续往下推:
- web-types.d.ts 新增 WorkbenchAugmentedError / WorkbenchAugmentedErrorFields
  / WorkbenchScrollOptions / WorkbenchLoadOptions / WorkbenchActionResultOptions
  / WorkbenchSummaryShape / WorkbenchComposerShape 七个精确接口;前两个
  让 custom Error 增广(agentErrorFromHttpResponse 那一串 error.traceId/code/
  layer/blocker/retryable/userMessage/missingConfig/route/toolName/timeoutMs/
  hardTimeoutMs/idleMs/lastActivityAt/waitingFor/providerStatus/category)有
  显式类型,runtime 不需要 any。WorkbenchScrollOptions 把 deferred/force/
  behavior/silent 收齐,scrollTraceToBottom 等的调用方不再绕开类型。
- ElMap.commandSend/commandClear 从 HTMLElement 收紧为 HTMLButtonElement,
  配合 lib 加 DOM.Iterable 让 NodeListOf<Element> 的 for...of 工作。
- WorkbenchState.conversationScrollPosition / traceScrollPositions /
  traceBodyScrollPositions 加上 bottomGap 字段,scrlTopForPosition 形参同步
  升级。
- app-conversation.ts:captureConversationScrollPosition 形参
  captureTraceScrollPositions / captureTraceBodyScrollPositions / restoreTraceScrollPositions
  / scrollTraceToBottom / agentErrorFromHttpResponse / agentFailurePresentation
  / classifyCodeAgentCompletion / scrollTopForPosition 加精确参数与返回类型;
  7 处 typeof payloadError === "object" ? payloadError.X 改为 as { X?: T } 强转。
- tsconfig.json:加 DOM.Iterable。

本次提交不破 web:check(54/0)与 web:build(12 dist);tsc-check 仍以
0 explicit untyped 为硬 gate,residual 残错按 #751 后续 issue 跟踪。
每类残错在 closeout comment 列出。

Refs: pikasTech/HWLAB#751

Co-authored-by: Codex <codex@noreply.local>
2026-06-03 15:57:03 +08:00
Codex 2fa23bd71d fix(web): restore v02 workbench layout 2026-06-03 15:49:52 +08:00
Lyon 10906ec726 fix(issue751): add web-types.d.ts + tsconfig + tsc-check baseline (#754)
为 issue #751 的 TypeScript 收紧建基线:
- 新增 web/hwlab-cloud-web/tsconfig.json(strict family 全部开启、noImplicitAny
  默认关、allowImportingTsExtensions 打开、types=[bun-types, node])
- 新增 web/hwlab-cloud-web/web-types.d.ts(ElMap + WorkbenchState + 跨文件
  function/lifecycle/constant 的 ambient declarations;用 WorkbenchUnknown
  接口避开 any 字面量,同时保留索引签名允许任意属性访问)
- 新增 web/hwlab-cloud-web/scripts/tsc-check.ts:web:check 的并行 type gate,
  显式 untyped 注解(项目源码 + web-types.d.ts)直接 exit 2;residual type
  错误按 issue #751 follow-up 处理
- web/hwlab-cloud-web/package.json:加 typescript@5.6.3 / @types/node@22.7.5
  / bun-types@1.1.33;check / check:tsc / check:tsc-strict 入口
- byId/query 加显式 : HTMLElement 返回类型(不再返回 HTMLElement | null)
- app-conversation.ts 中 captureConversationScrollPosition 加 : void 注解

web:check(54 tests / 0 fail)+ web:build(12 dist files)通过;tsc-check
报告 0 explicit untyped,residual type 错误(property access / strict null
等)作为 issue #751 后续轮次跟踪,不阻塞 build。

Refs: pikasTech/HWLAB#751

Co-authored-by: Codex <codex@noreply.local>
2026-06-03 15:21:03 +08:00
Lyon 9d71bf5f6b fix(web): HWLAB #748 initCommandBar orphan el.commandNewSession listener (#752)
PR #746 (#744) removed the duplicate `command-new-session` button from index.html and the `el.commandNewSession` field from the `el` literal, but left `el.commandNewSession.addEventListener("click", ...)` inside `initCommandBar()`. The resulting undefined reference crashed every Cloud Workbench init with

  app.js:5414 Uncaught TypeError: Cannot read properties of undefined (reading 'addEventListener')
      at initCommandBar (app.js:5414:24)
      at app.js:3538:1

The new session entry point is `#session-create` in the session sidebar (added in #740/#743), so this listener is no longer needed. Removal is the minimal fix; all other command-bar bindings (`commandInput`, `commandForm`, `commandClear`) are untouched.

Verified locally:
  - web:check (54 tests pass, all static contracts pass)
  - web:build (12 dist files fresh)
  - dist/app.js: 0 references to commandNewSession

Refs: pikasTech/HWLAB#748

Co-authored-by: Codex <codex@local>
2026-06-03 14:45:26 +08:00
Codex d39e322bf0 fix(web/cli): do not truncate the terminal final-response body in trace rows
- HWLAB v0.2 Final Response was being truncated to 5000 characters in
  traceAssistantSummaryRow and then again to 1200 characters in the CLI
  compactTraceRenderRow, even when the response was the assistant’s
  terminal (last) message. The same Final Response is what
  /v1/agent/chat/result returns as reply.content, so the trace view
  should show the full text and stay consistent with the CLI
  assistantText path.
- Mark each rendered row with a terminal flag (true only for the
  terminal Final Response) and lift the body cap to
  Number.POSITIVE_INFINITY for terminal rows. The CLI Web-render path
  now passes the full body through when row.terminal is true and keeps
  the 1200 char preview for non-terminal streaming rows.
- Add unit tests in web/hwlab-cloud-web/app-trace.test.ts and
  tools/hwlab-cli/client.test.ts to lock the behavior in for the
  terminal/no-truncate path and the streaming/2200 cap path.

Refs: pikasTech/HWLAB#722
2026-06-03 13:26:19 +08:00
Lyon 2168ad2ad7 fix(web): HWLAB #744 WebUI v0.2 改进 (#746)
- 问题1: 修复重复 session - 按 threadId 去重 conversation
- 问题2: session sidebar 默认宽度改为150% (330px),移除上限
- 问题3: 删除重复的命令栏「新建 Session」按钮
- 问题4: session 报错(status=failed/error/canceled/timeout)后允许继续重试
- 问题5: session tabs 上方显示当前模型通道
- 问题6: 所有时间统一使用北京时间(UTC+8),移除「北京时间」字样
- 问题7: 注销按钮移入 activity-rail 设置标签

Closes #744

Co-authored-by: Codex <codex@local>
2026-06-03 13:13:23 +08:00
Codex 6dbc72deac fix(issue740): HWLAB v0.2 WEBUI session management improvements
1. 在 panel-title-row 增加"复制 session id"按钮,把当前会话
   conversation id 复制到剪贴板,便于在 HWLAB CLI 复现;
2. 侧边栏标签改为显示最近更新时间(相对时间),排序仍然按
   lastTimestampMs 倒序,新会话靠前;
3. messageCount 与 firstUserMessagePreview 由 backend 持久化,
   不再被 slice(-50) 窗口掩盖,CLI/Web 看到的条数一致;
4. 把 left-sidebar-resize 移到 session-sidebar 右侧,
   activity-rail 固定 92px,拖拽控制 session-sidebar 宽度;
5. 侧边栏标签默认显示用户摘要(首条 user message 截断),
   长文本用省略号收尾。

新增 `hwlab-cli client session inspect <conversationId>` 子命令
与 `GET /v1/agent/conversations/{id}` 端点对齐,便于在 CLI 复现
WEB 看到的 session 详情(包含 messageCount / trace / thread)。

Backend 改动:access-control.ts 的 normalizeConversationSnapshot
和 mergeAgentSessionOwnerEvidence 现在按 max 累加 messageCount,
并保留 firstUserMessagePreview;mergeTerminalConversationMessages
返回 { messages, messageCount, firstUserMessagePreview }。
2026-06-03 11:41:02 +08:00
Codex 94b9df822c feat: 手动化 Code Agent session 管理 2026-06-03 10:40:50 +08:00
Codex da25cb4c02 feat: align session sidebar and cli management 2026-06-03 09:47:52 +08:00
Codex 5b1c9eb5dd feat: add session tabs to cloud web 2026-06-03 08:37:07 +08:00
Codex 90c5dad065 feat: show prompt assembly in skills panel 2026-06-03 08:03:04 +08:00
Codex e2d4989468 fix: expose AgentRun skill assembly in v02 web 2026-06-03 07:02:09 +08:00
Codex 0d4f5ef098 fix: preserve code agent sessions after turn failures 2026-06-03 00:28:40 +08:00
Codex 570c9963ec fix: collapse duplicate trace assistant rows 2026-06-02 22:46:05 +08:00
Codex 29e9e23fb3 fix: use native codex stdio continuation 2026-06-02 16:22:27 +08:00
Codex 66282ba80f fix: unlock cloud web composer steer 2026-06-02 12:25:16 +08:00
Codex fcfc7e84e5 fix: preserve AgentRun command tool calls in trace 2026-06-02 12:15:21 +08:00
Codex 47c4ce2d97 fix: 明确 AgentRun tool-call 错误归因 2026-06-02 12:08:38 +08:00
Codex 3c6edb73a1 fix: 统一 AgentRun threadId 上下文连续性 2026-06-02 10:19:34 +08:00
Codex f52eadfbe7 feat: route minimax m3 through agentrun 2026-06-02 08:50:27 +08:00
Codex 399af47ee8 fix: assemble device pod runtime endpoint 2026-06-02 07:44:24 +08:00
Lyon f0ddb634d8 fix: consume AgentRun assistant authority (#673)
Co-authored-by: Codex <codex@local>
2026-06-02 07:19:52 +08:00
Codex 6112d1759e fix: suppress agentrun lifecycle trace noise 2026-06-02 03:31:47 +08:00
Codex da96f02333 fix: preserve AgentRun reuse mapping and trace rendering 2026-06-02 03:16:50 +08:00
Codex ca4f14b421 fix: collapse AgentRun reuse trace noise 2026-06-02 02:00:29 +08:00
Codex 7dfd79daa1 fix: collapse completed AgentRun trace noise 2026-06-02 01:35:31 +08:00
Codex 936884bdc1 fix: reduce AgentRun trace noise for HWLAB CLI 2026-06-02 00:48:38 +08:00
Lyon 5dc263e10a fix: align AgentRun trace rendering (#665)
Co-authored-by: Codex <codex@local>
2026-06-01 23:58:06 +08:00
Lyon 24060853e7 fix: reuse AgentRun runner for HWLAB turns (#662)
Co-authored-by: Codex <codex@local>
2026-06-01 23:18:40 +08:00
Codex b7285b30b1 feat(workbench): share account workspace across web and cli 2026-06-01 21:31:26 +08:00
Codex b103a880ca fix: add trace auto-follow bottom pinning 2026-05-31 21:34:14 +08:00
Codex 115bd3a8ce chore: add web cicd performance probe comment 2026-05-31 19:03:20 +08:00
Codex c1bf4f0a59 fix: 收紧 v0.2 Device Pod 右栏首屏布局 2026-05-31 16:53:56 +08:00
Codex 6af815bda1 fix: 修复 v0.2 Device Pod 右栏与助手消息 2026-05-31 16:24:44 +08:00
Codex 945c2ba3d0 fix: persist user code agent sessions 2026-05-31 16:00:05 +08:00