Files
makelore/.project-docs/30-worklog/tasks/20260813-ai-hardware-client-9c7e.md

9.9 KiB

Task: Add top-level AI hardware module to Makelore client

Identity

  • Task ID: 20260813-ai-hardware-client-9c7e
  • Mode: Feature
  • Branch: codex/20260813-ai-hardware-client-9c7e-ai-hardware-client
  • Worktree: D:\Datas\OthersProjects\makelore-ai-hardware-client-9c7e
  • Base commit: 0148b91a15
  • Owner: codex
  • Status: Ready for Integration

Scope

  • Enable the existing fourth top-level Makelore Robot | AI 机器 module beside AI programming, AI design, and AI learning, and connect it to the AI hardware service. The user explicitly clarified that Hardware and Robot are the same product module, so no separate Hardware card remains.
  • Add a dedicated Robot Renderer page for overview, agent creation/configuration, device activation binding, and device reassignment.
  • Add a Main-owned Works Square proxy for /api/ai-hardware that owns authentication, idempotency, revision headers, response validation, and safe error projection.
  • Keep the Robot workspace isolated from AI programming project state and the project-initialization gate.
  • Add focused navigation, route, API, page, and Electron navigation verification while reusing the existing Robot cover asset.

Intent And Constraints

  • Renderer must not receive Works Square credentials, Xiaozhi credentials, raw upstream headers, raw problem bodies, or activation-code history.
  • Renderer uses public local resource IDs and numeric revisions only; Electron Main converts revisions to strong If-Match values and derives provider idempotency keys from an explicit per-intent client operation ID.
  • Reuse the existing single light Makelore visual system, module chooser, module switcher, UI primitives, Host API, and Works Square session.
  • Treat feature-disabled, first-use empty, recoverable service failure, credential recovery, and revision conflict as distinct user states.
  • Preserve unrelated work, do not change authentication behavior, and keep all work in the isolated owned worktree.

Outcome

  • Enabled the remote branch's existing Makelore Robot | AI 机器 fourth top-level card and connected it to the protected /ai-hardware technical route; there is no separate Hardware product card or module ID.
  • Isolated Robot and Canvas routes from AI programming project loads, provider refreshes, project dialogs, and the project-initialization gate. Provider initialization now uses an explicit Programming-route allowlist rather than treating every non-Canvas path as Programming.
  • Added a dedicated Robot page with explicit loading, disabled, unavailable, provisioning, credential-recovery, invalid, empty, and active states. First use can create an agent and implicitly provision the account; the active workspace supports further agent creation, six-digit activation binding, selected-agent configuration editing, field-level optimistic-revision conflict recovery, and device reassignment.
  • Added a strict Renderer API that validates local envelopes and public DTOs and never sends Works credentials, idempotency headers, or ETags from Renderer code.
  • Added a dedicated Electron Main route that maps only the fixed /api/works/ai-hardware surface to Works Square /api/ai-hardware, obtains and refreshes the Main-owned Works token, generates idempotency keys, converts numeric revisions to strong If-Match values, validates bounded JSON responses and strong ETags, and projects stable redacted errors.
  • Added stable mutation operation identities. A transport failure, token refresh, or explicit operation_in_progress result retains the same operation ID and provider idempotency key; editing the intent creates a new ID. The Main route performs one bounded in-progress retry with the exact same request.
  • For six-digit device activation, the code remains only in an uncontrolled DOM input and function-local variables. Ambiguous retries are matched using a dialog-lifetime, non-extractable random HMAC key and an in-memory fingerprint; the same code can reuse its operation ID, while a changed code starts a new operation on its first submission without retaining a reversible code value.
  • Completed the Robot configuration UI for every public server field, including advanced ASR/VAD/LLM/SLM/VLLM/TTS/memory/intent settings and explicit clear_fields semantics, with revision-conflict rebase that preserves only the user's attempted changes.
  • Added the credential-recovery UI and typed API. Recovery never exposes a provider token or private key to Renderer state, reuses an operation ID after uncertain failure, and refreshes the current overview when recovery is no longer needed.
  • Added a real loopback HTTP contract against a uvicorn-hosted Works Square FastAPI app, covering paths, Bearer ownership, response DTOs, status codes, ETags/If-Match, idempotency replay/conflict, in-progress retry, and recovery.
  • Hardened the generic Host API IPC proxy so case variants of Renderer-supplied authorization and capability headers cannot coexist with Main-owned values.
  • Updated README and repository guidance to describe three enabled modules (Code, Canvas, Robot) plus the disabled Learning entry.
  • Fetched the latest remote origin/main and semantically merged its Robot entry, horizontal module-card layout, Canvas overlay/full-height behavior, profile/avatar work, and related tests with this task. After the user's product clarification, the resulting chooser retains four entries: Code, Canvas, Learning, and the now-enabled Robot.

Verification

  • Focused Robot route/API/page suites: 62 tests passed; the credential-recovery, advanced-configuration, and activation-intent page suite alone passes 24 tests.
  • Provider/module isolation regression: 4 files and 28 tests passed, including direct Robot, Canvas, module chooser, and Programming route behavior.
  • Cross-repository Makelore-to-Works-Square loopback contract: 8 tests passed.
  • Final full unit suite after the remote fast-forward, semantic conflict resolution, Robot/Hardware unification, activation-intent hardening, and provider-route gate: 156 files passed, 1681 tests passed via corepack pnpm test. An earlier pre-final run had one unrelated OpenCode queue timing failure; the isolated test and the subsequent full runs passed.
  • TypeScript: corepack pnpm run typecheck passed.
  • ESLint: corepack pnpm run lint:check passed with six pre-existing warnings and no errors; warnings are in unrelated Chat, Home, and Makelore files.
  • Production build: corepack pnpm run build:vite passed; existing chunk-size and mixed dynamic/static import warnings remain.
  • Packaged Electron navigation smoke after the Robot/Hardware unification: 2 tests passed via corepack pnpm exec playwright test tests/e2e/main-navigation.spec.ts.
  • git diff --check passed; Git emitted only line-ending conversion warnings.
  • Final source-task closeout rechecked all 25 dirty paths and confirmed that each belongs to the Robot/AI Hardware implementation, its Programming-only provider route gate, security hardening, focused verification, or this task record; no unrelated work was adopted.
  • Final closeout focused verification: 8 files passed, 72 tests passed via corepack pnpm exec vitest run across the Robot API/page/routes/registration, provider route gate, Host API header hardening, initialization gate, and module navigation suites.
  • Final closeout TypeScript verification: corepack pnpm run typecheck passed. A fresh git diff --check also passed with only Git's existing LF-to-CRLF conversion warnings.

Follow-ups

  • The Works Square and Xiaozhi source contracts were verified in their current worktrees, but this client task did not verify that either service snapshot is deployed, that the backend feature flag is enabled, or that production credentials are provisioned. Run a signed-in staging smoke with a real activation code before release.
  • Operation IDs survive the current interactive retry flow but are not persisted across application restarts. A future offline queue must durably persist the operation ID together with the exact method, path, body, and revision.
  • Existing application-wide build chunk-size warnings and six unrelated lint warnings were not expanded into this feature scope.

Promotion Candidates

  • Target canonical document: .project-docs/20-architecture/system-overview.md and module map. Proposal: record Robot as the enabled fourth top-level client module backed by the AI hardware service, and document that only Programming consumes project/provider state. Evidence: src/lib/ai-modules.ts, src/components/layout/MainLayout.tsx, src/components/layout/Sidebar.tsx, and navigation tests. Future impact: Robot and Hardware must not be modeled as separate product modules; new modules must opt into Programming state explicitly rather than inherit it as a fallback. Semantic conflicts: current canonical documents predate the enabled Robot module. Human confirmation required: no; the user explicitly resolved the naming conflict in this task.
  • Target canonical document: .project-docs/20-architecture/data-flow.md and trust-boundary decision material. Proposal: record the Hardware request path Renderer typed API -> authenticated loopback Host API -> Main-owned Works session -> Works Square AI Hardware API, with numeric revisions converted to strong ETags and idempotency keys generated in Main. Evidence: src/lib/ai-hardware.ts, electron/api/routes/ai-hardware.ts, and route/API tests. Future impact: credentials, raw upstream problems, activation-code history, and response headers remain outside Renderer state. Semantic conflicts: none identified. Human confirmation required: no, once accepted.
  • Target canonical document: security/Host API decision material. Proposal: record case-insensitive stripping of Renderer-supplied authorization and renderer-capability headers before Main injects trusted values. Evidence: electron/main/ipc/host-api-proxy.ts and tests/unit/host-api-proxy.test.ts. Future impact: all future protected headers must be normalized case-insensitively. Semantic conflicts: none identified. Human confirmation required: no.