{"owner":"netease-youdao","repo":"LobsterAI","hasSkills":true,"hasMcp":false,"mcpConfig":null,"found":["AGENTS.md"],"skills":{"AGENTS.md":"# AGENTS.md\n\nThis file gives coding agents the current working model for this repository.\nTreat source code and `package.json` as the authority when something here\nappears stale.\n\n## Instruction Scope\n\nThis root `AGENTS.md` is repository-level guidance for LobsterAI. Codex may also\nload more specific `AGENTS.md` or `AGENTS.override.md` files from subdirectories\nwhen the current working directory is inside those subtrees. More specific\ninstructions override broader ones.\n\nDo not treat generated runtime workspaces, bundled OpenClaw output, or old\nClaude memory notes as authoritative project instructions. Use them only as\nhistorical context and verify against the current source.\n\n## Project Snapshot\n\nLobsterAI is an Electron + React desktop application. Its core user-facing\nproduct is a desktop agent experience that can work with local projects,\nfiles, browser previews, IM channels, skills, MCP servers, scheduled tasks,\nand rich artifacts.\n\n### Cowork vs OpenClaw\n\n`Cowork` is LobsterAI's product/session layer. The name is historical: it\nstarted as a Claude Code-like in-house coding assistant, but in the current\ncodebase it means the LobsterAI layer that owns sessions, messages,\npermissions, UI state, local persistence, context usage, artifacts, and IPC\ncontracts.\n\n`OpenClaw` is the only agent runtime/gateway. `CoworkAgentEngine` is currently\n`'openclaw'` only. Legacy names such as `cowork:*` IPC channels,\n`claude_session_id`, and some \"cowork\" filenames are compatibility/history\nnames, not evidence of another active runtime.\n\nDo not reintroduce or design around `yd_cowork`; it has been removed as a\nruntime. If old docs mention it as switchable, verify against current source\nbefore acting.\n\n## Commands\n\n```bash\n# First development run: build/sync the pinned OpenClaw runtime, then start app\nnpm run electron:dev:openclaw\n\n# Daily development after runtime exists: Vite on port 5175 + Electron\nnpm run electron:dev\n\n# Production renderer bundle\nnpm run build\n\n# Electron main/preload TypeScript build\nnpm run compile:electron\n\n# Full ESLint across src; may fail on existing legacy debt\nnpm run lint\n\n# CI-equivalent lint for touched TypeScript files\nnpx eslint --ext ts,tsx --report-unused-disable-directives --max-warnings 0 <files>\n\n# Official test entry used by GitHub CI\nnpm test\n\n# Filter Vitest tests\nnpm test -- logger\nnpm test -- cowork\n\n# Package for distribution\nnpm run dist:mac\nnpm run dist:win\nnpm run dist:linux\n\n# Build current-platform OpenClaw runtime manually\nnpm run openclaw:runtime:host\n```\n\nRequirements:\n- Node.js `>=24.15.0 <25`.\n- Windows builds may need bundled/portable Git setup: `npm run setup:mingit`.\n- Windows packaging also sets up the Python runtime via\n  `npm run setup:python-runtime`.\n\nOpenClaw environment variables:\n- `OPENCLAW_SRC`: override the OpenClaw source checkout path. Default is\n  `../openclaw` relative to this repo.\n- `OPENCLAW_SKIP_ENSURE=1`: skip automatic OpenClaw tag checkout. Use this only\n  when intentionally developing OpenClaw locally.\n- `OPENCLAW_FORCE_BUILD=1`: force runtime rebuild where supported by scripts.\n\n## Testing\n\nThe current official test path is Vitest:\n- `package.json` defines `npm test` as `vitest run`.\n- `vitest.config.ts` includes `src/**/*.test.ts` and `tests/**/*.test.ts`.\n- GitHub CI runs `npm test`.\n\nPrefer new tests as `.test.ts` files colocated with the source they cover.\nImport from Vitest:\n\n```ts\nimport { describe, expect, test } from 'vitest';\n```\n\nThere are legacy `tests/*.test.mjs` files that use Node's built-in\n`node:test`. They are not part of the default `npm test` run. Only run them\nexplicitly, e.g. `node --test tests/<file>.test.mjs`, when touching that\nlegacy coverage.\n\nAvoid importing Electron-only APIs such as `electron-log` directly in tests.\nInline or extract pure logic instead.\n\nFor UI/Electron behavior, manually validate with `npm run electron:dev` or\n`npm run electron:dev:openclaw` when the OpenClaw runtime is involved.\n\n## Quality Gates\n\nGitHub CI lints changed TypeScript files only. The repository has existing\nlegacy lint debt; do not attempt a broad lint cleanup unless the user explicitly\nasks for it.\n\nWhen adding or modifying TypeScript/TSX files, leave every touched file free of\nESLint errors and warnings under the same rules CI uses:\n\n```bash\nnpx eslint --ext ts,tsx --report-unused-disable-directives --max-warnings 0 <files>\n```\n\nIf full `npm run lint` fails because of unrelated legacy files, report that\nclearly and include the changed-file lint result. Do not use broad\n`eslint-disable` comments to bypass new issues; use narrow disables only when\nthere is a specific technical reason.\n\nVerification expectations:\n- Docs-only changes: no test run is required; state that tests were not run\n  because only documentation changed.\n- Renderer/UI changes: run relevant Vitest coverage when available and manually\n  validate with `npm run electron:dev` for behavior that tests cannot cover.\n- Main process, IPC, runtime, or preload changes: run targeted tests plus\n  `npm run compile:electron` or `npm run build` as appropriate.\n- OpenClaw integration changes: verify runtime startup, config sync, gateway\n  behavior, and relevant logs.\n- Before handing off, review the diff for unrelated churn, risky broad\n  refactors, generated files, and user-visible string/i18n mistakes.\n\n## OpenClaw Integration\n\nThe pinned OpenClaw version and plugin list live in `package.json` under\n`openclaw`. The current runtime is built under `vendor/openclaw-runtime/`;\n`vendor/openclaw-runtime/current` points to the platform runtime. Packaged apps\nbundle the runtime under `Resources/cfmind`.\n\nMain integration points:\n- `scripts/ensure-openclaw-version.cjs`: clone/fetch/checkout the pinned\n  OpenClaw tag.\n- `scripts/apply-openclaw-patches.cjs`: apply version-scoped patches.\n- `scripts/run-build-openclaw-runtime.cjs`: build a platform runtime.\n- `scripts/sync-openclaw-runtime-current.cjs`: point `current` at the built\n  runtime.\n- `scripts/bundle-openclaw-gateway.cjs`: create the gateway bundle.\n- `scripts/ensure-openclaw-plugins.cjs`: install third-party OpenClaw plugins.\n- `scripts/sync-local-openclaw-extensions.cjs`: sync local extensions.\n- `scripts/precompile-openclaw-extensions.cjs`: precompile extensions.\n- `scripts/install-openclaw-channel-deps.cjs`: install channel dependencies.\n- `scripts/prune-openclaw-runtime.cjs`: remove unused runtime/plugin content.\n\n### Patch Policy\n\nWhen changing OpenClaw-related behavior, first look for a LobsterAI-side\nintegration point: adapter code, config sync, plugin configuration, runtime\npackaging, UI handling, or local data-layer handling. Prefer changing\nLobsterAI when the behavior is product-specific or can be expressed cleanly at\nthe integration boundary.\n\nUse version-scoped OpenClaw patches only when the required behavior is inside\nOpenClaw and there is no clean LobsterAI-side hook. Do not avoid a patch by\nadding brittle or contorted LobsterAI workarounds.\n\nPatches live under `scripts/patches/<openclaw.version>/` and are applied by\n`npm run openclaw:patch`. Do not leave manual edits in the sibling OpenClaw\nsource tree as the final state; convert them into a small, documented patch\ntied to the pinned version.\n\n## Architecture Map\n\n### Main Process\n\n`src/main/main.ts` wires Electron lifecycle, IPC, auth, logging, OpenClaw\nstartup, Cowork routing, IM gateways, scheduled tasks, skills, MCP, updates,\nartifact preview/share handlers, and shell/dialog bridges.\n\nKey modules:\n- `src/main/libs/openclawEngineManager.ts`: manages the bundled OpenClaw\n  gateway process, state directory, config path, ports, tokens, gateway logs,\n  restart/repair behavior, and runtime readiness.\n- `src/main/libs/openclawConfigSync.ts`: renders LobsterAI state into\n  OpenClaw config: providers/models, agents, IM bindings, plugins, MCP servers,\n  skills extra dirs, sandbox mode, and managed workspace `AGENTS.md` sections.\n- `src/main/libs/agentEngine/openclawRuntimeAdapter.ts`: translates between\n  OpenClaw gateway events and Cowork stream events.\n- `src/main/libs/agentEngine/coworkEngineRouter.ts`: Cowork-facing runtime\n  router. It currently routes to OpenClaw only.\n- `src/main/coworkStore.ts`: Cowork sessions, messages, config, agents, memory\n  metadata, and related CRUD over SQLite.\n- `src/main/sqliteStore.ts`: database initialization and migrations.\n- `src/main/agentManager.ts`: agent CRUD and preset installation wrapper.\n- `src/main/skillManager.ts`: bundled/user skill sync, install/upgrade,\n  security scan, enable state, and routing prompt support.\n- `src/main/im/`: IM gateway config, status, delivery, session mapping, media,\n  pairing, and platform-specific handling.\n- `src/scheduledTask/`: scheduled task model, cron gateway service, policies,\n  migrations, and local metadata.\n- `src/main/mcp/`: MCP server storage, runtime, marketplace, and launch\n  resolution.\n\nSecurity model:\n- Renderer uses `src/main/preload.ts` and `contextBridge`.\n- `contextIsolation` is enabled, `nodeIntegration` is disabled, and sandboxing\n  is enabled for renderer windows.\n- Renderer-to-main communication must go through IPC bridge APIs.\n\n### Renderer\n\nThe renderer is React + Redux Toolkit + Tailwind.\n\nMain areas:\n- `src/renderer/App.tsx`: top-level app state and view routing.\n- `src/renderer/services/cowork.ts`: Cowork IPC wrapper, Redux integration, and\n  stream listener orchestration.\n- `src/renderer/store/slices/coworkSlice.ts`: Cowork session and streaming\n  state.\n- `src/renderer/store/slices/agentSlice.ts`: agent state.\n- `src/renderer/store/slices/artifactSlice.ts`: artifact state.\n- `src/renderer/components/cowork/`: main Cowork UI, prompt input, session\n  detail, permissions, thinking/tool display, context usage, forks, media, and\n  voice input.\n- `src/renderer/components/agent/`: agent creation and settings UI.\n- `src/renderer/components/agentSidebar/`: agent/session tree and subagent\n  session UI.\n- `src/renderer/components/artifacts/`: artifact panel, badges, preview cards,\n  renderers, and file directory view.\n- `src/renderer/components/scheduledTasks/`: scheduled task list, form, detail,\n  run history, and template UI.\n- `src/renderer/components/im/`: IM platform settings and multi-instance UI.\n- `src/renderer/components/skills/`: skill management UI.\n- `src/renderer/components/mcp/`: MCP management UI.\n- `src/renderer/services/i18n.ts`: renderer i18n dictionary and `t()` helper.\n\n### Shared Code\n\nUse `src/shared/*/constants.ts` for cross-process constants such as IPC channel\nnames, status values, discriminants, protocols, and stable string IDs. Prefer\nshared constants over duplicated string literals.\n\nUseful shared areas:\n- `src/shared/agent/`\n- `src/shared/auth/`\n- `src/shared/cowork/`\n- `src/shared/artifactPreview/`\n- `src/shared/mcp/`\n- `src/shared/providers/`\n- `src/shared/platform/`\n- `src/scheduledTask/constants.ts`\n\n## Data Model\n\nSQLite lives in Electron `app.getPath('userData')` as `lobsterai.sqlite`.\n\nImportant tables:\n- `kv`: app-wide JSON values, including auth/config flags.\n- `cowork_sessions`: local Cowork session records. Some column names are\n  historical, e.g. `claude_session_id`.\n- `cowork_messages`: local session messages.\n- `cowork_session_capsules`: continuity/context capsules for sessions.\n- `cowork_config`: Cowork settings such as working directory, execution mode,\n  agent engine, memory, dreaming, embedding, and related options.\n- `agents`: custom/preset agents, model, identity, skill IDs, per-agent working\n  directory, enable state, and pinning.\n- `user_memories`, `user_memory_sources`: legacy/local memory tracking used for\n  migration and source metadata.\n- `im_config`: IM platform configuration.\n- `im_session_mappings`: IM conversation to Cowork/OpenClaw session mapping,\n  including agent ID and OpenClaw session key.\n- `mcp_servers`, `mcp_launch_resolutions`: MCP server configuration and resolved\n  launch metadata.\n- `user_plugins`: user-installed OpenClaw plugins and enabled/config state.\n- `subagent_runs`, `subagent_messages`: subagent run tracking and fetched\n  conversation history.\n- `scheduled_task_meta`: local origin/binding metadata for OpenClaw cron jobs.\n  Actual scheduled task definitions and run history are managed through\n  OpenClaw cron APIs/state.\n\nMigrations are mostly ad-hoc `PRAGMA table_info()` checks in\n`src/main/sqliteStore.ts` and feature-specific migration modules.\n\n## OpenClaw State, Workspaces, And Memory\n\nOpenClaw runtime state is under Electron `userData/openclaw`.\n\nImportant paths:\n- `%APPDATA%/LobsterAI/openclaw/state/openclaw.json` on Windows: generated\n  OpenClaw config.\n- `%APPDATA%/LobsterAI/openclaw/state/workspace-main`: main agent workspace.\n- `%APPDATA%/LobsterAI/openclaw/state/workspace-{agentId}`: non-main agent\n  workspaces.\n\nThe main workspace path is resolved by `getMainAgentWorkspacePath()`.\nNon-main agent workspaces follow OpenClaw's state-dir fallback and are synced by\n`openclawConfigSync.ts`.\n\nWorkspace files include:\n- `AGENTS.md`: OpenClaw workspace instructions with a LobsterAI-managed section.\n- `MEMORY.md`: durable memory facts.\n- `memory/YYYY-MM-DD.md`: daily notes.\n- `USER.md`: user profile/context.\n- `SOUL.md`: agent/system prompt.\n- `IDENTITY.md`: agent identity.\n\nThe user-visible working directory is the session cwd. Do not confuse it with\nthe OpenClaw agent workspace.\n\n## Logs\n\nMain process logging uses `electron-log` via `src/main/logger.ts`, which\nintercepts `console.*`.\n\nMain logs:\n- Windows: `%APPDATA%/LobsterAI/logs/main-YYYY-MM-DD.log`\n- macOS: `~/Library/Logs/LobsterAI/main-YYYY-MM-DD.log`\n- Linux: `~/.config/LobsterAI/logs/main-YYYY-MM-DD.log`\n\nMain log retention is 7 days. Max file size is 80 MB; overflow rotates to\n`.old.log`.\n\nOpenClaw gateway capture logs:\n- Windows: `%APPDATA%/LobsterAI/openclaw/logs/gateway-YYYY-MM-DD.log`\n- Retention is 3 days.\n\nOpenClaw's own daily logs may also exist in a temp directory. On Windows,\n`openclawEngineManager.getOpenClawDailyLogDir()` prefers the runtime drive's\n`D:/tmp/openclaw` style path when present, otherwise the system temp fallback.\n\nLogs can be large. Use `rg`, `Select-String`, `Get-Content -Tail`, or targeted\nfilters instead of reading entire log files.\n\nLogging rules:\n- Use `console.error` for failures that need investigation. Pass the caught\n  error object last.\n- Use `console.warn` for unexpected but recoverable situations.\n- Use `console.log` for meaningful lifecycle events.\n- Use `console.debug` for high-frequency or diagnostic detail.\n- Do not add info-level logs inside polling loops, per-message hot paths, or\n  routine function entries.\n- Log messages should be English, concise, and start with a module tag such as\n  `[OpenClaw]`.\n\n## Coding Style\n\n- TypeScript is the default.\n- React components are functional components with hooks.\n- Use 2-space indentation, single quotes, and semicolons.\n- Use `PascalCase` for components, `camelCase` for functions/variables, and\n  `*Slice.ts` for Redux slices.\n- Tailwind is the primary styling approach; prefer existing utility patterns\n  before adding bespoke CSS.\n- Keep business logic in `src/renderer/services/`, `src/main/libs/`, or domain\n  modules rather than embedding it in UI components.\n- Prefer existing local helpers and patterns over new abstractions.\n\n## Legacy Debt And Large Files\n\nThis repository contains oversized legacy files. Do not perform broad\nfile-splitting or architectural cleanup as drive-by work.\n\nWhen a requested change touches a very large file, keep the immediate change\nscoped. If the change would add meaningful complexity to that file, first\nsuggest a focused extraction/refactor plan to the developer instead of doing the\nrefactor directly.\n\nA useful proposal should name:\n- the feature or responsibility being extracted;\n- the candidate new module/file boundaries;\n- the public functions/types that would move;\n- the migration and test steps;\n- risks or behavior that must remain unchanged.\n\nProceed with the refactor only after the developer confirms. Avoid sweeping\nrenames, formatting churn, or unrelated cleanup while making the original\nchange.\n\n## String Constants\n\nDo not use bare string literals for values that act as discriminants, status\ncodes, IPC channel names, mode selectors, protocol names, or strings compared\nor switched against in multiple places.\n\nUse a centralized `as const` object and derive the type:\n\n```ts\nexport const SessionTarget = {\n  Main: 'main',\n  Isolated: 'isolated',\n} as const;\nexport type SessionTarget = typeof SessionTarget[keyof typeof SessionTarget];\n```\n\nRules:\n- One source of truth per module.\n- Consumers import both the value object and type.\n- IPC channel names must be constants when adding or touching a channel.\n- Tests should use the same constants.\n- Discriminated union interface fields may keep literal `kind` declarations.\n\nDo not constantize one-off error messages, CSS class names, HTML attributes, or\nexternal platform IDs passed through from user/platform config unless the code\ncompares them in multiple places.\n\n## Internationalization\n\nDo not hardcode user-visible UI strings.\n\nRenderer:\n- Use `t('key')` from `src/renderer/services/i18n.ts`.\n- Add both `zh` and `en` translations.\n\nMain process:\n- Use `t('key')` from `src/main/i18n.ts` for user-visible tray/menu/session\n  titles/notifications.\n- Add both `zh` and `en` translations.\n\nDeveloper-only logs and DevTools-only diagnostics are exempt.\n\n## Artifacts\n\nArtifacts are parsed by `src/renderer/services/artifactParser.ts` and rendered\nunder `src/renderer/components/artifacts/`.\n\nCurrent previewable artifact types include:\n- `html`\n- `svg`\n- `image`\n- `video`\n- `mermaid`\n- `code`\n- `markdown`\n- `text`\n- `document`\n- `local-service`\n\nHTML file artifacts use a local preview server for fidelity. Inline HTML uses\nan iframe sandbox. SVG and file previews must remain sanitized/isolated.\nDocument/office-style renderers live under `components/artifacts/renderers/`.\n\n## IM, Agents, MCP, And Scheduled Tasks\n\nAgents:\n- Main agent ID is `main`.\n- Agents can be custom or preset.\n- Agent data includes identity, system prompt, model, skill IDs, icon, enabled\n  state, pinning, and optional working directory.\n- IM channels can bind to specific agents.\n\nIM:\n- IM config is stored in SQLite and synced into OpenClaw config where the\n  channel is OpenClaw-backed.\n- Multi-instance platforms include DingTalk, Feishu/Lark, QQ, Telegram,\n  Discord, WeCom, NIM, POPO, and email.\n- Weixin and NetEase Bee have single-instance style config.\n- IM session mappings preserve conversation/session/agent relationships.\n\nMCP:\n- User-configured MCP servers live in `mcp_servers`.\n- Resolved launch metadata lives in `mcp_launch_resolutions`.\n- OpenClaw config sync writes enabled servers into native `mcp.servers`.\n\nScheduled tasks:\n- The UI and local policy code live in `src/scheduledTask/` and\n  `src/renderer/components/scheduledTasks/`.\n- Execution uses OpenClaw cron APIs through `CronJobService`.\n- `scheduled_task_meta` stores only local origin/binding data that OpenClaw cron\n  jobs do not support as custom fields.\n\n## Branches, Commits, And PRs\n\nUse branch names like `feat/...` or `fix/...`. Do not use a `codex/...` prefix\nunless the user explicitly asks for it.\n\nDo not create commits until the user has tested and confirmed, unless they\nexplicitly asked you to commit.\n\nCommit messages must follow Conventional Commits and be written in English:\n\n```text\nfeat(cowork): add streaming progress indicator\nfix(sqlite): prevent duplicate session insert on retry\nchore: bump version to 2026.6.18\n```\n\nDo not add `Co-Authored-By` trailers unless explicitly requested.\n\nFor PRs, include a concise description, linked issue when relevant, screenshots\nfor UI changes, and call out Electron-specific behavior changes such as IPC,\nstorage, runtime, windowing, or OpenClaw config/restart behavior.\n\n## Practical Guidance\n\n- Prefer `rg` for search.\n- Verify historical notes against current source before acting.\n- Ignore stale docs that conflict with `package.json`, `src/main`, `src/shared`,\n  and current tests.\n- Do not edit bundled runtime output or generated vendor files unless the task\n  is explicitly about packaging/runtime generation.\n- Keep changes scoped. Avoid opportunistic refactors when fixing product bugs.\n- For oversized files, propose a scoped extraction plan before doing structural\n  refactors.\n- If a file has unrelated user changes, work around them and do not revert them.\n"},"files":{"AGENTS.md":"# AGENTS.md\n\nThis file gives coding agents the current working model for this repository.\nTreat source code and `package.json` as the authority when something here\nappears stale.\n\n## Instruction Scope\n\nThis root `AGENTS.md` is repository-level guidance for LobsterAI. Codex may also\nload more specific `AGENTS.md` or `AGENTS.override.md` files from subdirectories\nwhen the current working directory is inside those subtrees. More specific\ninstructions override broader ones.\n\nDo not treat generated runtime workspaces, bundled OpenClaw output, or old\nClaude memory notes as authoritative project instructions. Use them only as\nhistorical context and verify against the current source.\n\n## Project Snapshot\n\nLobsterAI is an Electron + React desktop application. Its core user-facing\nproduct is a desktop agent experience that can work with local projects,\nfiles, browser previews, IM channels, skills, MCP servers, scheduled tasks,\nand rich artifacts.\n\n### Cowork vs OpenClaw\n\n`Cowork` is LobsterAI's product/session layer. The name is historical: it\nstarted as a Claude Code-like in-house coding assistant, but in the current\ncodebase it means the LobsterAI layer that owns sessions, messages,\npermissions, UI state, local persistence, context usage, artifacts, and IPC\ncontracts.\n\n`OpenClaw` is the only agent runtime/gateway. `CoworkAgentEngine` is currently\n`'openclaw'` only. Legacy names such as `cowork:*` IPC channels,\n`claude_session_id`, and some \"cowork\" filenames are compatibility/history\nnames, not evidence of another active runtime.\n\nDo not reintroduce or design around `yd_cowork`; it has been removed as a\nruntime. If old docs mention it as switchable, verify against current source\nbefore acting.\n\n## Commands\n\n```bash\n# First development run: build/sync the pinned OpenClaw runtime, then start app\nnpm run electron:dev:openclaw\n\n# Daily development after runtime exists: Vite on port 5175 + Electron\nnpm run electron:dev\n\n# Production renderer bundle\nnpm run build\n\n# Electron main/preload TypeScript build\nnpm run compile:electron\n\n# Full ESLint across src; may fail on existing legacy debt\nnpm run lint\n\n# CI-equivalent lint for touched TypeScript files\nnpx eslint --ext ts,tsx --report-unused-disable-directives --max-warnings 0 <files>\n\n# Official test entry used by GitHub CI\nnpm test\n\n# Filter Vitest tests\nnpm test -- logger\nnpm test -- cowork\n\n# Package for distribution\nnpm run dist:mac\nnpm run dist:win\nnpm run dist:linux\n\n# Build current-platform OpenClaw runtime manually\nnpm run openclaw:runtime:host\n```\n\nRequirements:\n- Node.js `>=24.15.0 <25`.\n- Windows builds may need bundled/portable Git setup: `npm run setup:mingit`.\n- Windows packaging also sets up the Python runtime via\n  `npm run setup:python-runtime`.\n\nOpenClaw environment variables:\n- `OPENCLAW_SRC`: override the OpenClaw source checkout path. Default is\n  `../openclaw` relative to this repo.\n- `OPENCLAW_SKIP_ENSURE=1`: skip automatic OpenClaw tag checkout. Use this only\n  when intentionally developing OpenClaw locally.\n- `OPENCLAW_FORCE_BUILD=1`: force runtime rebuild where supported by scripts.\n\n## Testing\n\nThe current official test path is Vitest:\n- `package.json` defines `npm test` as `vitest run`.\n- `vitest.config.ts` includes `src/**/*.test.ts` and `tests/**/*.test.ts`.\n- GitHub CI runs `npm test`.\n\nPrefer new tests as `.test.ts` files colocated with the source they cover.\nImport from Vitest:\n\n```ts\nimport { describe, expect, test } from 'vitest';\n```\n\nThere are legacy `tests/*.test.mjs` files that use Node's built-in\n`node:test`. They are not part of the default `npm test` run. Only run them\nexplicitly, e.g. `node --test tests/<file>.test.mjs`, when touching that\nlegacy coverage.\n\nAvoid importing Electron-only APIs such as `electron-log` directly in tests.\nInline or extract pure logic instead.\n\nFor UI/Electron behavior, manually validate with `npm run electron:dev` or\n`npm run electron:dev:openclaw` when the OpenClaw runtime is involved.\n\n## Quality Gates\n\nGitHub CI lints changed TypeScript files only. The repository has existing\nlegacy lint debt; do not attempt a broad lint cleanup unless the user explicitly\nasks for it.\n\nWhen adding or modifying TypeScript/TSX files, leave every touched file free of\nESLint errors and warnings under the same rules CI uses:\n\n```bash\nnpx eslint --ext ts,tsx --report-unused-disable-directives --max-warnings 0 <files>\n```\n\nIf full `npm run lint` fails because of unrelated legacy files, report that\nclearly and include the changed-file lint result. Do not use broad\n`eslint-disable` comments to bypass new issues; use narrow disables only when\nthere is a specific technical reason.\n\nVerification expectations:\n- Docs-only changes: no test run is required; state that tests were not run\n  because only documentation changed.\n- Renderer/UI changes: run relevant Vitest coverage when available and manually\n  validate with `npm run electron:dev` for behavior that tests cannot cover.\n- Main process, IPC, runtime, or preload changes: run targeted tests plus\n  `npm run compile:electron` or `npm run build` as appropriate.\n- OpenClaw integration changes: verify runtime startup, config sync, gateway\n  behavior, and relevant logs.\n- Before handing off, review the diff for unrelated churn, risky broad\n  refactors, generated files, and user-visible string/i18n mistakes.\n\n## OpenClaw Integration\n\nThe pinned OpenClaw version and plugin list live in `package.json` under\n`openclaw`. The current runtime is built under `vendor/openclaw-runtime/`;\n`vendor/openclaw-runtime/current` points to the platform runtime. Packaged apps\nbundle the runtime under `Resources/cfmind`.\n\nMain integration points:\n- `scripts/ensure-openclaw-version.cjs`: clone/fetch/checkout the pinned\n  OpenClaw tag.\n- `scripts/apply-openclaw-patches.cjs`: apply version-scoped patches.\n- `scripts/run-build-openclaw-runtime.cjs`: build a platform runtime.\n- `scripts/sync-openclaw-runtime-current.cjs`: point `current` at the built\n  runtime.\n- `scripts/bundle-openclaw-gateway.cjs`: create the gateway bundle.\n- `scripts/ensure-openclaw-plugins.cjs`: install third-party OpenClaw plugins.\n- `scripts/sync-local-openclaw-extensions.cjs`: sync local extensions.\n- `scripts/precompile-openclaw-extensions.cjs`: precompile extensions.\n- `scripts/install-openclaw-channel-deps.cjs`: install channel dependencies.\n- `scripts/prune-openclaw-runtime.cjs`: remove unused runtime/plugin content.\n\n### Patch Policy\n\nWhen changing OpenClaw-related behavior, first look for a LobsterAI-side\nintegration point: adapter code, config sync, plugin configuration, runtime\npackaging, UI handling, or local data-layer handling. Prefer changing\nLobsterAI when the behavior is product-specific or can be expressed cleanly at\nthe integration boundary.\n\nUse version-scoped OpenClaw patches only when the required behavior is inside\nOpenClaw and there is no clean LobsterAI-side hook. Do not avoid a patch by\nadding brittle or contorted LobsterAI workarounds.\n\nPatches live under `scripts/patches/<openclaw.version>/` and are applied by\n`npm run openclaw:patch`. Do not leave manual edits in the sibling OpenClaw\nsource tree as the final state; convert them into a small, documented patch\ntied to the pinned version.\n\n## Architecture Map\n\n### Main Process\n\n`src/main/main.ts` wires Electron lifecycle, IPC, auth, logging, OpenClaw\nstartup, Cowork routing, IM gateways, scheduled tasks, skills, MCP, updates,\nartifact preview/share handlers, and shell/dialog bridges.\n\nKey modules:\n- `src/main/libs/openclawEngineManager.ts`: manages the bundled OpenClaw\n  gateway process, state directory, config path, ports, tokens, gateway logs,\n  restart/repair behavior, and runtime readiness.\n- `src/main/libs/openclawConfigSync.ts`: renders LobsterAI state into\n  OpenClaw config: providers/models, agents, IM bindings, plugins, MCP servers,\n  skills extra dirs, sandbox mode, and managed workspace `AGENTS.md` sections.\n- `src/main/libs/agentEngine/openclawRuntimeAdapter.ts`: translates between\n  OpenClaw gateway events and Cowork stream events.\n- `src/main/libs/agentEngine/coworkEngineRouter.ts`: Cowork-facing runtime\n  router. It currently routes to OpenClaw only.\n- `src/main/coworkStore.ts`: Cowork sessions, messages, config, agents, memory\n  metadata, and related CRUD over SQLite.\n- `src/main/sqliteStore.ts`: database initialization and migrations.\n- `src/main/agentManager.ts`: agent CRUD and preset installation wrapper.\n- `src/main/skillManager.ts`: bundled/user skill sync, install/upgrade,\n  security scan, enable state, and routing prompt support.\n- `src/main/im/`: IM gateway config, status, delivery, session mapping, media,\n  pairing, and platform-specific handling.\n- `src/scheduledTask/`: scheduled task model, cron gateway service, policies,\n  migrations, and local metadata.\n- `src/main/mcp/`: MCP server storage, runtime, marketplace, and launch\n  resolution.\n\nSecurity model:\n- Renderer uses `src/main/preload.ts` and `contextBridge`.\n- `contextIsolation` is enabled, `nodeIntegration` is disabled, and sandboxing\n  is enabled for renderer windows.\n- Renderer-to-main communication must go through IPC bridge APIs.\n\n### Renderer\n\nThe renderer is React + Redux Toolkit + Tailwind.\n\nMain areas:\n- `src/renderer/App.tsx`: top-level app state and view routing.\n- `src/renderer/services/cowork.ts`: Cowork IPC wrapper, Redux integration, and\n  stream listener orchestration.\n- `src/renderer/store/slices/coworkSlice.ts`: Cowork session and streaming\n  state.\n- `src/renderer/store/slices/agentSlice.ts`: agent state.\n- `src/renderer/store/slices/artifactSlice.ts`: artifact state.\n- `src/renderer/components/cowork/`: main Cowork UI, prompt input, session\n  detail, permissions, thinking/tool display, context usage, forks, media, and\n  voice input.\n- `src/renderer/components/agent/`: agent creation and settings UI.\n- `src/renderer/components/agentSidebar/`: agent/session tree and subagent\n  session UI.\n- `src/renderer/components/artifacts/`: artifact panel, badges, preview cards,\n  renderers, and file directory view.\n- `src/renderer/components/scheduledTasks/`: scheduled task list, form, detail,\n  run history, and template UI.\n- `src/renderer/components/im/`: IM platform settings and multi-instance UI.\n- `src/renderer/components/skills/`: skill management UI.\n- `src/renderer/components/mcp/`: MCP management UI.\n- `src/renderer/services/i18n.ts`: renderer i18n dictionary and `t()` helper.\n\n### Shared Code\n\nUse `src/shared/*/constants.ts` for cross-process constants such as IPC channel\nnames, status values, discriminants, protocols, and stable string IDs. Prefer\nshared constants over duplicated string literals.\n\nUseful shared areas:\n- `src/shared/agent/`\n- `src/shared/auth/`\n- `src/shared/cowork/`\n- `src/shared/artifactPreview/`\n- `src/shared/mcp/`\n- `src/shared/providers/`\n- `src/shared/platform/`\n- `src/scheduledTask/constants.ts`\n\n## Data Model\n\nSQLite lives in Electron `app.getPath('userData')` as `lobsterai.sqlite`.\n\nImportant tables:\n- `kv`: app-wide JSON values, including auth/config flags.\n- `cowork_sessions`: local Cowork session records. Some column names are\n  historical, e.g. `claude_session_id`.\n- `cowork_messages`: local session messages.\n- `cowork_session_capsules`: continuity/context capsules for sessions.\n- `cowork_config`: Cowork settings such as working directory, execution mode,\n  agent engine, memory, dreaming, embedding, and related options.\n- `agents`: custom/preset agents, model, identity, skill IDs, per-agent working\n  directory, enable state, and pinning.\n- `user_memories`, `user_memory_sources`: legacy/local memory tracking used for\n  migration and source metadata.\n- `im_config`: IM platform configuration.\n- `im_session_mappings`: IM conversation to Cowork/OpenClaw session mapping,\n  including agent ID and OpenClaw session key.\n- `mcp_servers`, `mcp_launch_resolutions`: MCP server configuration and resolved\n  launch metadata.\n- `user_plugins`: user-installed OpenClaw plugins and enabled/config state.\n- `subagent_runs`, `subagent_messages`: subagent run tracking and fetched\n  conversation history.\n- `scheduled_task_meta`: local origin/binding metadata for OpenClaw cron jobs.\n  Actual scheduled task definitions and run history are managed through\n  OpenClaw cron APIs/state.\n\nMigrations are mostly ad-hoc `PRAGMA table_info()` checks in\n`src/main/sqliteStore.ts` and feature-specific migration modules.\n\n## OpenClaw State, Workspaces, And Memory\n\nOpenClaw runtime state is under Electron `userData/openclaw`.\n\nImportant paths:\n- `%APPDATA%/LobsterAI/openclaw/state/openclaw.json` on Windows: generated\n  OpenClaw config.\n- `%APPDATA%/LobsterAI/openclaw/state/workspace-main`: main agent workspace.\n- `%APPDATA%/LobsterAI/openclaw/state/workspace-{agentId}`: non-main agent\n  workspaces.\n\nThe main workspace path is resolved by `getMainAgentWorkspacePath()`.\nNon-main agent workspaces follow OpenClaw's state-dir fallback and are synced by\n`openclawConfigSync.ts`.\n\nWorkspace files include:\n- `AGENTS.md`: OpenClaw workspace instructions with a LobsterAI-managed section.\n- `MEMORY.md`: durable memory facts.\n- `memory/YYYY-MM-DD.md`: daily notes.\n- `USER.md`: user profile/context.\n- `SOUL.md`: agent/system prompt.\n- `IDENTITY.md`: agent identity.\n\nThe user-visible working directory is the session cwd. Do not confuse it with\nthe OpenClaw agent workspace.\n\n## Logs\n\nMain process logging uses `electron-log` via `src/main/logger.ts`, which\nintercepts `console.*`.\n\nMain logs:\n- Windows: `%APPDATA%/LobsterAI/logs/main-YYYY-MM-DD.log`\n- macOS: `~/Library/Logs/LobsterAI/main-YYYY-MM-DD.log`\n- Linux: `~/.config/LobsterAI/logs/main-YYYY-MM-DD.log`\n\nMain log retention is 7 days. Max file size is 80 MB; overflow rotates to\n`.old.log`.\n\nOpenClaw gateway capture logs:\n- Windows: `%APPDATA%/LobsterAI/openclaw/logs/gateway-YYYY-MM-DD.log`\n- Retention is 3 days.\n\nOpenClaw's own daily logs may also exist in a temp directory. On Windows,\n`openclawEngineManager.getOpenClawDailyLogDir()` prefers the runtime drive's\n`D:/tmp/openclaw` style path when present, otherwise the system temp fallback.\n\nLogs can be large. Use `rg`, `Select-String`, `Get-Content -Tail`, or targeted\nfilters instead of reading entire log files.\n\nLogging rules:\n- Use `console.error` for failures that need investigation. Pass the caught\n  error object last.\n- Use `console.warn` for unexpected but recoverable situations.\n- Use `console.log` for meaningful lifecycle events.\n- Use `console.debug` for high-frequency or diagnostic detail.\n- Do not add info-level logs inside polling loops, per-message hot paths, or\n  routine function entries.\n- Log messages should be English, concise, and start with a module tag such as\n  `[OpenClaw]`.\n\n## Coding Style\n\n- TypeScript is the default.\n- React components are functional components with hooks.\n- Use 2-space indentation, single quotes, and semicolons.\n- Use `PascalCase` for components, `camelCase` for functions/variables, and\n  `*Slice.ts` for Redux slices.\n- Tailwind is the primary styling approach; prefer existing utility patterns\n  before adding bespoke CSS.\n- Keep business logic in `src/renderer/services/`, `src/main/libs/`, or domain\n  modules rather than embedding it in UI components.\n- Prefer existing local helpers and patterns over new abstractions.\n\n## Legacy Debt And Large Files\n\nThis repository contains oversized legacy files. Do not perform broad\nfile-splitting or architectural cleanup as drive-by work.\n\nWhen a requested change touches a very large file, keep the immediate change\nscoped. If the change would add meaningful complexity to that file, first\nsuggest a focused extraction/refactor plan to the developer instead of doing the\nrefactor directly.\n\nA useful proposal should name:\n- the feature or responsibility being extracted;\n- the candidate new module/file boundaries;\n- the public functions/types that would move;\n- the migration and test steps;\n- risks or behavior that must remain unchanged.\n\nProceed with the refactor only after the developer confirms. Avoid sweeping\nrenames, formatting churn, or unrelated cleanup while making the original\nchange.\n\n## String Constants\n\nDo not use bare string literals for values that act as discriminants, status\ncodes, IPC channel names, mode selectors, protocol names, or strings compared\nor switched against in multiple places.\n\nUse a centralized `as const` object and derive the type:\n\n```ts\nexport const SessionTarget = {\n  Main: 'main',\n  Isolated: 'isolated',\n} as const;\nexport type SessionTarget = typeof SessionTarget[keyof typeof SessionTarget];\n```\n\nRules:\n- One source of truth per module.\n- Consumers import both the value object and type.\n- IPC channel names must be constants when adding or touching a channel.\n- Tests should use the same constants.\n- Discriminated union interface fields may keep literal `kind` declarations.\n\nDo not constantize one-off error messages, CSS class names, HTML attributes, or\nexternal platform IDs passed through from user/platform config unless the code\ncompares them in multiple places.\n\n## Internationalization\n\nDo not hardcode user-visible UI strings.\n\nRenderer:\n- Use `t('key')` from `src/renderer/services/i18n.ts`.\n- Add both `zh` and `en` translations.\n\nMain process:\n- Use `t('key')` from `src/main/i18n.ts` for user-visible tray/menu/session\n  titles/notifications.\n- Add both `zh` and `en` translations.\n\nDeveloper-only logs and DevTools-only diagnostics are exempt.\n\n## Artifacts\n\nArtifacts are parsed by `src/renderer/services/artifactParser.ts` and rendered\nunder `src/renderer/components/artifacts/`.\n\nCurrent previewable artifact types include:\n- `html`\n- `svg`\n- `image`\n- `video`\n- `mermaid`\n- `code`\n- `markdown`\n- `text`\n- `document`\n- `local-service`\n\nHTML file artifacts use a local preview server for fidelity. Inline HTML uses\nan iframe sandbox. SVG and file previews must remain sanitized/isolated.\nDocument/office-style renderers live under `components/artifacts/renderers/`.\n\n## IM, Agents, MCP, And Scheduled Tasks\n\nAgents:\n- Main agent ID is `main`.\n- Agents can be custom or preset.\n- Agent data includes identity, system prompt, model, skill IDs, icon, enabled\n  state, pinning, and optional working directory.\n- IM channels can bind to specific agents.\n\nIM:\n- IM config is stored in SQLite and synced into OpenClaw config where the\n  channel is OpenClaw-backed.\n- Multi-instance platforms include DingTalk, Feishu/Lark, QQ, Telegram,\n  Discord, WeCom, NIM, POPO, and email.\n- Weixin and NetEase Bee have single-instance style config.\n- IM session mappings preserve conversation/session/agent relationships.\n\nMCP:\n- User-configured MCP servers live in `mcp_servers`.\n- Resolved launch metadata lives in `mcp_launch_resolutions`.\n- OpenClaw config sync writes enabled servers into native `mcp.servers`.\n\nScheduled tasks:\n- The UI and local policy code live in `src/scheduledTask/` and\n  `src/renderer/components/scheduledTasks/`.\n- Execution uses OpenClaw cron APIs through `CronJobService`.\n- `scheduled_task_meta` stores only local origin/binding data that OpenClaw cron\n  jobs do not support as custom fields.\n\n## Branches, Commits, And PRs\n\nUse branch names like `feat/...` or `fix/...`. Do not use a `codex/...` prefix\nunless the user explicitly asks for it.\n\nDo not create commits until the user has tested and confirmed, unless they\nexplicitly asked you to commit.\n\nCommit messages must follow Conventional Commits and be written in English:\n\n```text\nfeat(cowork): add streaming progress indicator\nfix(sqlite): prevent duplicate session insert on retry\nchore: bump version to 2026.6.18\n```\n\nDo not add `Co-Authored-By` trailers unless explicitly requested.\n\nFor PRs, include a concise description, linked issue when relevant, screenshots\nfor UI changes, and call out Electron-specific behavior changes such as IPC,\nstorage, runtime, windowing, or OpenClaw config/restart behavior.\n\n## Practical Guidance\n\n- Prefer `rg` for search.\n- Verify historical notes against current source before acting.\n- Ignore stale docs that conflict with `package.json`, `src/main`, `src/shared`,\n  and current tests.\n- Do not edit bundled runtime output or generated vendor files unless the task\n  is explicitly about packaging/runtime generation.\n- Keep changes scoped. Avoid opportunistic refactors when fixing product bugs.\n- For oversized files, propose a scoped extraction plan before doing structural\n  refactors.\n- If a file has unrelated user changes, work around them and do not revert them.\n"},"items":[{"name":"AGENTS.md","path":"AGENTS.md","title":"AGENTS.md","content":"# AGENTS.md\n\nThis file gives coding agents the current working model for this repository.\nTreat source code and `package.json` as the authority when something here\nappears stale.\n\n## Instruction Scope\n\nThis root `AGENTS.md` is repository-level guidance for LobsterAI. Codex may also\nload more specific `AGENTS.md` or `AGENTS.override.md` files from subdirectories\nwhen the current working directory is inside those subtrees. More specific\ninstructions override broader ones.\n\nDo not treat generated runtime workspaces, bundled OpenClaw output, or old\nClaude memory notes as authoritative project instructions. Use them only as\nhistorical context and verify against the current source.\n\n## Project Snapshot\n\nLobsterAI is an Electron + React desktop application. Its core user-facing\nproduct is a desktop agent experience that can work with local projects,\nfiles, browser previews, IM channels, skills, MCP servers, scheduled tasks,\nand rich artifacts.\n\n### Cowork vs OpenClaw\n\n`Cowork` is LobsterAI's product/session layer. The name is historical: it\nstarted as a Claude Code-like in-house coding assistant, but in the current\ncodebase it means the LobsterAI layer that owns sessions, messages,\npermissions, UI state, local persistence, context usage, artifacts, and IPC\ncontracts.\n\n`OpenClaw` is the only agent runtime/gateway. `CoworkAgentEngine` is currently\n`'openclaw'` only. Legacy names such as `cowork:*` IPC channels,\n`claude_session_id`, and some \"cowork\" filenames are compatibility/history\nnames, not evidence of another active runtime.\n\nDo not reintroduce or design around `yd_cowork`; it has been removed as a\nruntime. If old docs mention it as switchable, verify against current source\nbefore acting.\n\n## Commands\n\n```bash\n# First development run: build/sync the pinned OpenClaw runtime, then start app\nnpm run electron:dev:openclaw\n\n# Daily development after runtime exists: Vite on port 5175 + Electron\nnpm run electron:dev\n\n# Production renderer bundle\nnpm run build\n\n# Electron main/preload TypeScript build\nnpm run compile:electron\n\n# Full ESLint across src; may fail on existing legacy debt\nnpm run lint\n\n# CI-equivalent lint for touched TypeScript files\nnpx eslint --ext ts,tsx --report-unused-disable-directives --max-warnings 0 <files>\n\n# Official test entry used by GitHub CI\nnpm test\n\n# Filter Vitest tests\nnpm test -- logger\nnpm test -- cowork\n\n# Package for distribution\nnpm run dist:mac\nnpm run dist:win\nnpm run dist:linux\n\n# Build current-platform OpenClaw runtime manually\nnpm run openclaw:runtime:host\n```\n\nRequirements:\n- Node.js `>=24.15.0 <25`.\n- Windows builds may need bundled/portable Git setup: `npm run setup:mingit`.\n- Windows packaging also sets up the Python runtime via\n  `npm run setup:python-runtime`.\n\nOpenClaw environment variables:\n- `OPENCLAW_SRC`: override the OpenClaw source checkout path. Default is\n  `../openclaw` relative to this repo.\n- `OPENCLAW_SKIP_ENSURE=1`: skip automatic OpenClaw tag checkout. Use this only\n  when intentionally developing OpenClaw locally.\n- `OPENCLAW_FORCE_BUILD=1`: force runtime rebuild where supported by scripts.\n\n## Testing\n\nThe current official test path is Vitest:\n- `package.json` defines `npm test` as `vitest run`.\n- `vitest.config.ts` includes `src/**/*.test.ts` and `tests/**/*.test.ts`.\n- GitHub CI runs `npm test`.\n\nPrefer new tests as `.test.ts` files colocated with the source they cover.\nImport from Vitest:\n\n```ts\nimport { describe, expect, test } from 'vitest';\n```\n\nThere are legacy `tests/*.test.mjs` files that use Node's built-in\n`node:test`. They are not part of the default `npm test` run. Only run them\nexplicitly, e.g. `node --test tests/<file>.test.mjs`, when touching that\nlegacy coverage.\n\nAvoid importing Electron-only APIs such as `electron-log` directly in tests.\nInline or extract pure logic instead.\n\nFor UI/Electron behavior, manually validate with `npm run electron:dev` or\n`npm run electron:dev:openclaw` when the OpenClaw runtime is involved.\n\n## Quality Gates\n\nGitHub CI lints changed TypeScript files only. The repository has existing\nlegacy lint debt; do not attempt a broad lint cleanup unless the user explicitly\nasks for it.\n\nWhen adding or modifying TypeScript/TSX files, leave every touched file free of\nESLint errors and warnings under the same rules CI uses:\n\n```bash\nnpx eslint --ext ts,tsx --report-unused-disable-directives --max-warnings 0 <files>\n```\n\nIf full `npm run lint` fails because of unrelated legacy files, report that\nclearly and include the changed-file lint result. Do not use broad\n`eslint-disable` comments to bypass new issues; use narrow disables only when\nthere is a specific technical reason.\n\nVerification expectations:\n- Docs-only changes: no test run is required; state that tests were not run\n  because only documentation changed.\n- Renderer/UI changes: run relevant Vitest coverage when available and manually\n  validate with `npm run electron:dev` for behavior that tests cannot cover.\n- Main process, IPC, runtime, or preload changes: run targeted tests plus\n  `npm run compile:electron` or `npm run build` as appropriate.\n- OpenClaw integration changes: verify runtime startup, config sync, gateway\n  behavior, and relevant logs.\n- Before handing off, review the diff for unrelated churn, risky broad\n  refactors, generated files, and user-visible string/i18n mistakes.\n\n## OpenClaw Integration\n\nThe pinned OpenClaw version and plugin list live in `package.json` under\n`openclaw`. The current runtime is built under `vendor/openclaw-runtime/`;\n`vendor/openclaw-runtime/current` points to the platform runtime. Packaged apps\nbundle the runtime under `Resources/cfmind`.\n\nMain integration points:\n- `scripts/ensure-openclaw-version.cjs`: clone/fetch/checkout the pinned\n  OpenClaw tag.\n- `scripts/apply-openclaw-patches.cjs`: apply version-scoped patches.\n- `scripts/run-build-openclaw-runtime.cjs`: build a platform runtime.\n- `scripts/sync-openclaw-runtime-current.cjs`: point `current` at the built\n  runtime.\n- `scripts/bundle-openclaw-gateway.cjs`: create the gateway bundle.\n- `scripts/ensure-openclaw-plugins.cjs`: install third-party OpenClaw plugins.\n- `scripts/sync-local-openclaw-extensions.cjs`: sync local extensions.\n- `scripts/precompile-openclaw-extensions.cjs`: precompile extensions.\n- `scripts/install-openclaw-channel-deps.cjs`: install channel dependencies.\n- `scripts/prune-openclaw-runtime.cjs`: remove unused runtime/plugin content.\n\n### Patch Policy\n\nWhen changing OpenClaw-related behavior, first look for a LobsterAI-side\nintegration point: adapter code, config sync, plugin configuration, runtime\npackaging, UI handling, or local data-layer handling. Prefer changing\nLobsterAI when the behavior is product-specific or can be expressed cleanly at\nthe integration boundary.\n\nUse version-scoped OpenClaw patches only when the required behavior is inside\nOpenClaw and there is no clean LobsterAI-side hook. Do not avoid a patch by\nadding brittle or contorted LobsterAI workarounds.\n\nPatches live under `scripts/patches/<openclaw.version>/` and are applied by\n`npm run openclaw:patch`. Do not leave manual edits in the sibling OpenClaw\nsource tree as the final state; convert them into a small, documented patch\ntied to the pinned version.\n\n## Architecture Map\n\n### Main Process\n\n`src/main/main.ts` wires Electron lifecycle, IPC, auth, logging, OpenClaw\nstartup, Cowork routing, IM gateways, scheduled tasks, skills, MCP, updates,\nartifact preview/share handlers, and shell/dialog bridges.\n\nKey modules:\n- `src/main/libs/openclawEngineManager.ts`: manages the bundled OpenClaw\n  gateway process, state directory, config path, ports, tokens, gateway logs,\n  restart/repair behavior, and runtime readiness.\n- `src/main/libs/openclawConfigSync.ts`: renders LobsterAI state into\n  OpenClaw config: providers/models, agents, IM bindings, plugins, MCP servers,\n  skills extra dirs, sandbox mode, and managed workspace `AGENTS.md` sections.\n- `src/main/libs/agentEngine/openclawRuntimeAdapter.ts`: translates between\n  OpenClaw gateway events and Cowork stream events.\n- `src/main/libs/agentEngine/coworkEngineRouter.ts`: Cowork-facing runtime\n  router. It currently routes to OpenClaw only.\n- `src/main/coworkStore.ts`: Cowork sessions, messages, config, agents, memory\n  metadata, and related CRUD over SQLite.\n- `src/main/sqliteStore.ts`: database initialization and migrations.\n- `src/main/agentManager.ts`: agent CRUD and preset installation wrapper.\n- `src/main/skillManager.ts`: bundled/user skill sync, install/upgrade,\n  security scan, enable state, and routing prompt support.\n- `src/main/im/`: IM gateway config, status, delivery, session mapping, media,\n  pairing, and platform-specific handling.\n- `src/scheduledTask/`: scheduled task model, cron gateway service, policies,\n  migrations, and local metadata.\n- `src/main/mcp/`: MCP server storage, runtime, marketplace, and launch\n  resolution.\n\nSecurity model:\n- Renderer uses `src/main/preload.ts` and `contextBridge`.\n- `contextIsolation` is enabled, `nodeIntegration` is disabled, and sandboxing\n  is enabled for renderer windows.\n- Renderer-to-main communication must go through IPC bridge APIs.\n\n### Renderer\n\nThe renderer is React + Redux Toolkit + Tailwind.\n\nMain areas:\n- `src/renderer/App.tsx`: top-level app state and view routing.\n- `src/renderer/services/cowork.ts`: Cowork IPC wrapper, Redux integration, and\n  stream listener orchestration.\n- `src/renderer/store/slices/coworkSlice.ts`: Cowork session and streaming\n  state.\n- `src/renderer/store/slices/agentSlice.ts`: agent state.\n- `src/renderer/store/slices/artifactSlice.ts`: artifact state.\n- `src/renderer/components/cowork/`: main Cowork UI, prompt input, session\n  detail, permissions, thinking/tool display, context usage, forks, media, and\n  voice input.\n- `src/renderer/components/agent/`: agent creation and settings UI.\n- `src/renderer/components/agentSidebar/`: agent/session tree and subagent\n  session UI.\n- `src/renderer/components/artifacts/`: artifact panel, badges, preview cards,\n  renderers, and file directory view.\n- `src/renderer/components/scheduledTasks/`: scheduled task list, form, detail,\n  run history, and template UI.\n- `src/renderer/components/im/`: IM platform settings and multi-instance UI.\n- `src/renderer/components/skills/`: skill management UI.\n- `src/renderer/components/mcp/`: MCP management UI.\n- `src/renderer/services/i18n.ts`: renderer i18n dictionary and `t()` helper.\n\n### Shared Code\n\nUse `src/shared/*/constants.ts` for cross-process constants such as IPC channel\nnames, status values, discriminants, protocols, and stable string IDs. Prefer\nshared constants over duplicated string literals.\n\nUseful shared areas:\n- `src/shared/agent/`\n- `src/shared/auth/`\n- `src/shared/cowork/`\n- `src/shared/artifactPreview/`\n- `src/shared/mcp/`\n- `src/shared/providers/`\n- `src/shared/platform/`\n- `src/scheduledTask/constants.ts`\n\n## Data Model\n\nSQLite lives in Electron `app.getPath('userData')` as `lobsterai.sqlite`.\n\nImportant tables:\n- `kv`: app-wide JSON values, including auth/config flags.\n- `cowork_sessions`: local Cowork session records. Some column names are\n  historical, e.g. `claude_session_id`.\n- `cowork_messages`: local session messages.\n- `cowork_session_capsules`: continuity/context capsules for sessions.\n- `cowork_config`: Cowork settings such as working directory, execution mode,\n  agent engine, memory, dreaming, embedding, and related options.\n- `agents`: custom/preset agents, model, identity, skill IDs, per-agent working\n  directory, enable state, and pinning.\n- `user_memories`, `user_memory_sources`: legacy/local memory tracking used for\n  migration and source metadata.\n- `im_config`: IM platform configuration.\n- `im_session_mappings`: IM conversation to Cowork/OpenClaw session mapping,\n  including agent ID and OpenClaw session key.\n- `mcp_servers`, `mcp_launch_resolutions`: MCP server configuration and resolved\n  launch metadata.\n- `user_plugins`: user-installed OpenClaw plugins and enabled/config state.\n- `subagent_runs`, `subagent_messages`: subagent run tracking and fetched\n  conversation history.\n- `scheduled_task_meta`: local origin/binding metadata for OpenClaw cron jobs.\n  Actual scheduled task definitions and run history are managed through\n  OpenClaw cron APIs/state.\n\nMigrations are mostly ad-hoc `PRAGMA table_info()` checks in\n`src/main/sqliteStore.ts` and feature-specific migration modules.\n\n## OpenClaw State, Workspaces, And Memory\n\nOpenClaw runtime state is under Electron `userData/openclaw`.\n\nImportant paths:\n- `%APPDATA%/LobsterAI/openclaw/state/openclaw.json` on Windows: generated\n  OpenClaw config.\n- `%APPDATA%/LobsterAI/openclaw/state/workspace-main`: main agent workspace.\n- `%APPDATA%/LobsterAI/openclaw/state/workspace-{agentId}`: non-main agent\n  workspaces.\n\nThe main workspace path is resolved by `getMainAgentWorkspacePath()`.\nNon-main agent workspaces follow OpenClaw's state-dir fallback and are synced by\n`openclawConfigSync.ts`.\n\nWorkspace files include:\n- `AGENTS.md`: OpenClaw workspace instructions with a LobsterAI-managed section.\n- `MEMORY.md`: durable memory facts.\n- `memory/YYYY-MM-DD.md`: daily notes.\n- `USER.md`: user profile/context.\n- `SOUL.md`: agent/system prompt.\n- `IDENTITY.md`: agent identity.\n\nThe user-visible working directory is the session cwd. Do not confuse it with\nthe OpenClaw agent workspace.\n\n## Logs\n\nMain process logging uses `electron-log` via `src/main/logger.ts`, which\nintercepts `console.*`.\n\nMain logs:\n- Windows: `%APPDATA%/LobsterAI/logs/main-YYYY-MM-DD.log`\n- macOS: `~/Library/Logs/LobsterAI/main-YYYY-MM-DD.log`\n- Linux: `~/.config/LobsterAI/logs/main-YYYY-MM-DD.log`\n\nMain log retention is 7 days. Max file size is 80 MB; overflow rotates to\n`.old.log`.\n\nOpenClaw gateway capture logs:\n- Windows: `%APPDATA%/LobsterAI/openclaw/logs/gateway-YYYY-MM-DD.log`\n- Retention is 3 days.\n\nOpenClaw's own daily logs may also exist in a temp directory. On Windows,\n`openclawEngineManager.getOpenClawDailyLogDir()` prefers the runtime drive's\n`D:/tmp/openclaw` style path when present, otherwise the system temp fallback.\n\nLogs can be large. Use `rg`, `Select-String`, `Get-Content -Tail`, or targeted\nfilters instead of reading entire log files.\n\nLogging rules:\n- Use `console.error` for failures that need investigation. Pass the caught\n  error object last.\n- Use `console.warn` for unexpected but recoverable situations.\n- Use `console.log` for meaningful lifecycle events.\n- Use `console.debug` for high-frequency or diagnostic detail.\n- Do not add info-level logs inside polling loops, per-message hot paths, or\n  routine function entries.\n- Log messages should be English, concise, and start with a module tag such as\n  `[OpenClaw]`.\n\n## Coding Style\n\n- TypeScript is the default.\n- React components are functional components with hooks.\n- Use 2-space indentation, single quotes, and semicolons.\n- Use `PascalCase` for components, `camelCase` for functions/variables, and\n  `*Slice.ts` for Redux slices.\n- Tailwind is the primary styling approach; prefer existing utility patterns\n  before adding bespoke CSS.\n- Keep business logic in `src/renderer/services/`, `src/main/libs/`, or domain\n  modules rather than embedding it in UI components.\n- Prefer existing local helpers and patterns over new abstractions.\n\n## Legacy Debt And Large Files\n\nThis repository contains oversized legacy files. Do not perform broad\nfile-splitting or architectural cleanup as drive-by work.\n\nWhen a requested change touches a very large file, keep the immediate change\nscoped. If the change would add meaningful complexity to that file, first\nsuggest a focused extraction/refactor plan to the developer instead of doing the\nrefactor directly.\n\nA useful proposal should name:\n- the feature or responsibility being extracted;\n- the candidate new module/file boundaries;\n- the public functions/types that would move;\n- the migration and test steps;\n- risks or behavior that must remain unchanged.\n\nProceed with the refactor only after the developer confirms. Avoid sweeping\nrenames, formatting churn, or unrelated cleanup while making the original\nchange.\n\n## String Constants\n\nDo not use bare string literals for values that act as discriminants, status\ncodes, IPC channel names, mode selectors, protocol names, or strings compared\nor switched against in multiple places.\n\nUse a centralized `as const` object and derive the type:\n\n```ts\nexport const SessionTarget = {\n  Main: 'main',\n  Isolated: 'isolated',\n} as const;\nexport type SessionTarget = typeof SessionTarget[keyof typeof SessionTarget];\n```\n\nRules:\n- One source of truth per module.\n- Consumers import both the value object and type.\n- IPC channel names must be constants when adding or touching a channel.\n- Tests should use the same constants.\n- Discriminated union interface fields may keep literal `kind` declarations.\n\nDo not constantize one-off error messages, CSS class names, HTML attributes, or\nexternal platform IDs passed through from user/platform config unless the code\ncompares them in multiple places.\n\n## Internationalization\n\nDo not hardcode user-visible UI strings.\n\nRenderer:\n- Use `t('key')` from `src/renderer/services/i18n.ts`.\n- Add both `zh` and `en` translations.\n\nMain process:\n- Use `t('key')` from `src/main/i18n.ts` for user-visible tray/menu/session\n  titles/notifications.\n- Add both `zh` and `en` translations.\n\nDeveloper-only logs and DevTools-only diagnostics are exempt.\n\n## Artifacts\n\nArtifacts are parsed by `src/renderer/services/artifactParser.ts` and rendered\nunder `src/renderer/components/artifacts/`.\n\nCurrent previewable artifact types include:\n- `html`\n- `svg`\n- `image`\n- `video`\n- `mermaid`\n- `code`\n- `markdown`\n- `text`\n- `document`\n- `local-service`\n\nHTML file artifacts use a local preview server for fidelity. Inline HTML uses\nan iframe sandbox. SVG and file previews must remain sanitized/isolated.\nDocument/office-style renderers live under `components/artifacts/renderers/`.\n\n## IM, Agents, MCP, And Scheduled Tasks\n\nAgents:\n- Main agent ID is `main`.\n- Agents can be custom or preset.\n- Agent data includes identity, system prompt, model, skill IDs, icon, enabled\n  state, pinning, and optional working directory.\n- IM channels can bind to specific agents.\n\nIM:\n- IM config is stored in SQLite and synced into OpenClaw config where the\n  channel is OpenClaw-backed.\n- Multi-instance platforms include DingTalk, Feishu/Lark, QQ, Telegram,\n  Discord, WeCom, NIM, POPO, and email.\n- Weixin and NetEase Bee have single-instance style config.\n- IM session mappings preserve conversation/session/agent relationships.\n\nMCP:\n- User-configured MCP servers live in `mcp_servers`.\n- Resolved launch metadata lives in `mcp_launch_resolutions`.\n- OpenClaw config sync writes enabled servers into native `mcp.servers`.\n\nScheduled tasks:\n- The UI and local policy code live in `src/scheduledTask/` and\n  `src/renderer/components/scheduledTasks/`.\n- Execution uses OpenClaw cron APIs through `CronJobService`.\n- `scheduled_task_meta` stores only local origin/binding data that OpenClaw cron\n  jobs do not support as custom fields.\n\n## Branches, Commits, And PRs\n\nUse branch names like `feat/...` or `fix/...`. Do not use a `codex/...` prefix\nunless the user explicitly asks for it.\n\nDo not create commits until the user has tested and confirmed, unless they\nexplicitly asked you to commit.\n\nCommit messages must follow Conventional Commits and be written in English:\n\n```text\nfeat(cowork): add streaming progress indicator\nfix(sqlite): prevent duplicate session insert on retry\nchore: bump version to 2026.6.18\n```\n\nDo not add `Co-Authored-By` trailers unless explicitly requested.\n\nFor PRs, include a concise description, linked issue when relevant, screenshots\nfor UI changes, and call out Electron-specific behavior changes such as IPC,\nstorage, runtime, windowing, or OpenClaw config/restart behavior.\n\n## Practical Guidance\n\n- Prefer `rg` for search.\n- Verify historical notes against current source before acting.\n- Ignore stale docs that conflict with `package.json`, `src/main`, `src/shared`,\n  and current tests.\n- Do not edit bundled runtime output or generated vendor files unless the task\n  is explicitly about packaging/runtime generation.\n- Keep changes scoped. Avoid opportunistic refactors when fixing product bugs.\n- For oversized files, propose a scoped extraction plan before doing structural\n  refactors.\n- If a file has unrelated user changes, work around them and do not revert them.\n","category":"root","tokens":5113}]}