Files
agent-radar 2ed3415fb7
Publish Claude Code Binaries / Stage and publish binaries (push) Canceled after 0s
Publish Tutti App Runtime / Build darwin-arm64 (push) Canceled after 0s
Publish Tutti App Runtime / Build darwin-amd64 (push) Canceled after 0s
Publish Tutti App Runtime / Build linux-amd64 (push) Canceled after 0s
Publish Tutti App Runtime / Build windows-amd64 (push) Canceled after 0s
Sync Tutti Agent Skills / sync (push) Canceled after 0s
Windows Agent Adapters / Test Windows agent adapters (push) Canceled after 0s
Windows Daemon Adapters / Test Windows daemon adapters (push) Canceled after 0s
Publish Tutti App Runtime / Publish runtime catalog (push) Canceled after 0s
源码快照 @ 2026-09-01 (source-only, 剔除非源码素材)
2026-09-01 20:17:27 +08:00

6.9 KiB

AGENTS.md

Scope

This file applies to apps/desktop/*.

apps/desktop owns:

  • Electron main-process lifecycle
  • preload bridge and IPC exposure
  • renderer UI
  • native desktop integration
  • starting, monitoring, and reconnecting to tuttid

apps/desktop must not become a second business core.

Setup commands

  • Start desktop development: pnpm --filter @tutti-os/desktop dev. On Windows, its predev hook prepares the pinned managed POSIX shell and the Electron main process injects it into the tuttid child environment.
  • Windows staging/E2E acceptance: corepack pnpm@10.11.0 dev:windows:e2e:clean (or dev:windows:e2e when reusing the isolated state). Do not use the low-level dev loop as an acceptance substitute because it does not provide E2E cleanup, state isolation, or readiness checks.
  • Build desktop: pnpm --filter @tutti-os/desktop build
  • Typecheck desktop: pnpm --filter @tutti-os/desktop typecheck

Directory guide

  • src/main/*: Electron main-process code, including transport, host access, IPC, update, logging, and window creation Current composition is layered through bootstrap.ts, desktopAppServices.ts, desktopDaemonRuntime.ts, desktopHostServices.ts, and desktopAppLifecycle.ts.
  • src/preload/*: safe bridge surface exposed to the renderer
  • src/renderer/src/app/windows/*: renderer window composition shells
  • src/renderer/src/features/*: reusable renderer feature modules; services/internal/** stays private to the owning feature
  • src/shared/*: desktop-local contracts, shared error helpers, and i18n resources shared across main, preload, and renderer

The authoritative desktop directory shape lives in docs/conventions/desktop-layering.md. Keep this file focused on change-time rules and checks rather than repeating the full structure spec.

Current naming guidance:

  • use workspaceWindow for the primary in-workspace shell window
  • use dashboardWindow for the no-context launcher window
  • prefer view=workspace and view=dashboard over vague names such as main

Action rules

  • keep business rules out of renderer, preload, and main-process code
  • when changing Microsoft Windows packaging or native resources, read Windows Platform Support and keep platform selection at packaging or desktop composition boundaries
  • inject platform-native resources such as the managed POSIX shell through the daemon launch environment; daemon consumers must depend on their capability contract rather than importing desktop packaging details
  • prefer calling tuttid or desktop IPC adapters instead of re-implementing workflows in Electron
  • for workspace-agent activity adapters, reconcile bridges, or AgentGUI Workbench integration, read Agent GUI Node; also read Agent Activity Packages when changing the runtime/engine/package boundary
  • keep preload surfaces narrow and explicit
  • keep webview guest preload entries self-contained at runtime. Avoid runtime imports from shared contracts or helpers in src/preload/entries/browserNodeGuest.ts, src/preload/entries/workspaceApp.ts, and directly imported guest-preload helpers unless the build output proves they are inlined. import type is fine.
  • keep Electron-only concerns in src/main/* and renderer window composition under src/renderer/src/app/windows/*
  • keep managed-daemon shutdown deterministic; when quit flow depends on daemon cleanup, gate app exit instead of firing cleanup in the background
  • keep renderer feature logic in feature-local services; services assemble commands, adapters, request flow, and side effects
  • treat window.tutti as a renderer window-composition input; feature UI and feature services must not read it directly
  • render UI from state-library snapshots and selectors; React handles DOM events, subscriptions, and rendering rather than feature orchestration
  • treat fewer useEffect calls as an architecture constraint; move feature data flow into services, stores, reducers, or selectors when possible
  • do not import another feature's services/internal/**
  • do not mutate feature stores outside their owning service
  • route desktop-owned user-visible copy through src/shared/i18n; this includes renderer product text, Electron dialog labels, status copy, empty states, host-owned workbench text, and user-facing error messages
  • keep reusable package default i18n resources with the owning package; the renderer app-level i18n runtime should merge package defaults with desktop-owned resources instead of copying package strings back into src/shared/i18n
  • prefer consuming shared visuals from @tutti-os/ui-system instead of growing a second token or primitive layer in renderer
  • use @tutti-os/ui-system components wherever practical for renderer React UI, especially components under src/renderer/src/features/*/ui
  • load @tutti-os/ui-system/styles.css once from the renderer style entrypoint rather than per component
  • keep launcher surfaces lighter and more welcoming, while workspace surfaces stay denser and more workbench-like

Testing defaults

  • Run pnpm --filter @tutti-os/desktop typecheck
  • Run pnpm --filter @tutti-os/desktop test when changing lifecycle, host access, or update-access helpers
  • Run pnpm check:electron-runtime-boundaries for Electron main/preload runtime import changes or shared package-import changes that can affect those execution paths
  • Run pnpm check:i18n for renderer UI text, Electron dialog labels, empty states, status copy, or user-facing error messages
  • Run pnpm --filter @tutti-os/desktop build for desktop-facing behavior changes
  • For webview guest preload changes, verify the build succeeds with the self-contained guest preload guard and that guest preload output does not contain relative chunk requires such as require("./ipc-*.cjs")
  • If a change affects @tutti-os/ui-system consumption or renderer import shape, also run pnpm check:ui-boundaries
  • If a change affects renderer feature structure or imports, also run pnpm check:renderer-boundaries
  • If a change affects daemon interaction, also run the relevant services/tuttid checks