Skip to content

feat(desktop): add Bazel-only Loopal Desktop workbench#205

Merged
yishuiliunian merged 10 commits into
mainfrom
wt-20260711-072251-24130
Jul 15, 2026
Merged

feat(desktop): add Bazel-only Loopal Desktop workbench#205
yishuiliunian merged 10 commits into
mainfrom
wt-20260711-072251-24130

Conversation

@yishuiliunian

Copy link
Copy Markdown
Contributor

Summary

Ship the first production-shaped Loopal Desktop: a conversation-first Electron workbench that bundles the Bazel-built loopal CLI as its supervised runtime sidecar. This establishes a typed Desktop/Host boundary, Session-first information architecture, MetaHub Federation, deterministic provider fixtures, and repository ownership that can scale toward a full Loopal-powered workbench.

What changed

Desktop architecture and runtime

  • Add an Electron 43 / React workbench under apps/desktop, split into base, shared, platform, main, preload, and feature-owned workbench layers.
  • Keep the Renderer sandboxed and Node-free; Preload exposes a narrow schema-validated loopalDesktop facade, while Main owns dialogs, process handles, credentials, and OS access.
  • Run Rust through the stable loopal desktop serve --parent-pid ... [--resume ...] sidecar entry point with versioned startup phases, bounded IPC framing, cancellation/control lanes, generation-aware restart, authoritative resync, and stale-generation rejection.
  • Bundle the Bazel-built Loopal binary outside app.asar; add Bazel targets for development, staging smoke, and platform packaging.

Conversation-first product

  • Make Sessions the navigation root across all directories, with live recency and historical search instead of Workspace grouping.
  • Create Sessions through a native directory picker, using a direct directory or an isolated Git Worktree pinned to the inspected full HEAD OID.
  • Render Loopal as an ordered conversation monitor: safe Markdown/GFM, streaming text, thinking, tools, images, errors, usage, compaction, cancellation, Runtime notices, and per-Agent drafts.
  • Add slash commands, permissions, questions, plan approval, Skills, child/remote Agent topology and controls, and a dynamic horizontal Context Dock whose panels appear only when authoritative state exists.
  • Add English and Simplified Chinese catalogs, persisted language selection, keyboard/focus behavior, draggable macOS title regions, responsive layouts, and hidden/unfocused Electron E2E operation.
  • Remove placeholder Explorer, workspace search, SCM/editor, terminal/PTY, and standalone Worktree surfaces.

Federation and MetaHub

  • Make Federation an independent application surface.
  • Add a managed local MetaHub coordinator, persisted launch/join settings, and per-Session join/leave actions.
  • Extend Hub/MetaHub routing with qualified remote identity, remote relay, topology aggregation, completion tombstones, reconnect/degraded state, and strict Session/Runtime/generation ownership.
  • Cover cross-Hub Agent spawn, status, result, interrupt, question, completion, and conversation projection.

Settings, Skills, Plugins, and MCP

  • Add a VS Code-style two-level Settings overlay grouped by Desktop, Loopal, Session, and Federation.
  • Persist Desktop preferences in Electron user data and real Loopal/provider settings atomically in ~/.loopal/settings.json, preserving unknown fields and redacting credentials in responses.
  • Add scoped MCP definition editing, secret patches, validation, and project-local storage.
  • Add global Skill CRUD with revision checks, effective Skill projection, argument expansion, and Plugin inventory.

Bazel and repository layout

  • Make Bazel the only Desktop build/test/E2E/staging/package entry; pnpm supplies the checked-in dependency lock only.
  • Add loopal-workspace for bounded workspace/Worktree operations and loopal-mock-llm for deterministic Anthropic, OpenAI Responses, OpenAI-compatible, and Google streaming scenarios.
  • Reorganize root bootstrap, CLI, and test ownership without changing the public //:loopal binary target.
  • Extend CI with Desktop E2E, optimized staging smoke, and distribution build jobs.

Validation

  • bazel build //...
  • bazel test //... --config=ci --test_output=errors — 103/103 targets
  • bazel build //... --config=clippy
  • bazel build //... --config=rustfmt
  • bazel test //apps/desktop:unit — 651 tests
  • bazel test //apps/desktop:coverage — 95.17% statements, 90.40% branches, 94.85% functions, 96.55% lines
  • bazel test //apps/desktop:e2e — fake Electron suite
  • bazel test //apps/desktop:e2e_host — real Loopal Host suite
  • bazel test //apps/desktop:e2e_llm_backend --nocache_test_results — 72/72 real provider-boundary tests, no retries
  • Federation matcher hardening — 8/8 repeated cross/multi-Hub regression runs
  • bazel test //apps/desktop:staging_smoke -c opt --nocache_test_results
  • bazel build //apps/desktop:dist -c opt

Reviewer and migration notes

  • Desktop is new; existing Loopal CLI/TUI Session storage remains authoritative and is resumed rather than copied.
  • Saving Loopal/provider settings intentionally updates the real global Loopal configuration. Language and MetaHub bootstrap data remain Desktop-owned; tests isolate HOME.
  • Node >=22.12 <23 is required for dependency resolution. Use Bazel labels rather than invoking Vite, Vitest, Playwright, or electron-builder directly.
  • Desktop IPC is strict and versioned (protocol_version = 1, unknown fields rejected, 64 MiB frame cap).
  • Git Worktree creation refuses branch collisions, pins a full start OID, and cleanup does not force-delete unknown or unmerged work.
  • Physical bootstrap, CLI, and root-test paths moved; see docs/repository-layout.md.
  • Packaging currently emits only the host platform/architecture. Signing and notarization remain release-environment responsibilities.

Build a conversation-first Electron workbench around the supervised Loopal CLI sidecar, with typed IPC, sessions, MetaHub federation, settings, skills, plugins, and worktree-aware launch.

Add Bazel-only build, unit, coverage, real Host/provider E2E, staging smoke, packaging, and reorganized repository ownership.
Enable the Windows runfiles tree required by rules_js and rules_ts launchers so TypeScript validation can locate its entry point.
Disable only the rules_ts attribute validator on Windows, where its js_binary launcher cannot resolve the generated entry point. The tsc no-emit action still runs on every platform, while Linux and macOS retain the additional configuration validation.
Run the workspace TypeScript 5.9.3 binary through a Bazel js_run_binary action and preserve the Desktop tsconfig no-emit check. This avoids the rules_ts Windows launcher path bug without weakening the Windows build.
Compare the lock owner as a string slice and scope Unix-only imports and parameters to their platform. This preserves the file-lock behavior while keeping the Windows build warning-free.
Avoid Result equality because std::io::Error is not comparable; only compare lock owner contents after a successful read.
@yishuiliunian
yishuiliunian merged commit 834db52 into main Jul 15, 2026
5 checks passed
@yishuiliunian
yishuiliunian deleted the wt-20260711-072251-24130 branch July 15, 2026 10:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant