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

101 lines
6.9 KiB
Markdown

# 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](../../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](../../docs/architecture/windows-platform-support.md)
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](../../docs/architecture/agent-gui-node.md); also read
[Agent Activity Packages](../../docs/architecture/agent-activity-packages.md)
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
## Related docs
- [docs/conventions/README.md](../../docs/conventions/README.md)
- [docs/conventions/desktop-layering.md](../../docs/conventions/desktop-layering.md)
- [docs/conventions/desktop-visual-language.md](../../docs/conventions/desktop-visual-language.md)
- [docs/architecture/desktop-transport.md](../../docs/architecture/desktop-transport.md)
- [docs/architecture/desktop-windows.md](../../docs/architecture/desktop-windows.md)
- [docs/architecture/windows-platform-support.md](../../docs/architecture/windows-platform-support.md)
- [docs/conventions/logging.md](../../docs/conventions/logging.md)
- [docs/conventions/tuttid-layering.md](../../docs/conventions/tuttid-layering.md)
- [packages/ui/system/ui-system.md](../../packages/ui/system/ui-system.md)