{"owner":"anyproto","repo":"anytype-ts","hasSkills":true,"hasMcp":false,"mcpConfig":null,"found":["AGENTS.md","CLAUDE.md"],"skills":{"AGENTS.md":"\n# agents.md\n\n## Overview\n\nThis document outlines the architecture and implementation details of the Electron application built with React, TypeScript, and MobX. It covers the project's structure, state management, inter-process communication, and other essential aspects to facilitate understanding and contribution.\n\n## Table of Contents\n\n1. [Project Structure](#project-structure)\n2. [State Management with MobX](#state-management-with-mobx)\n3. [Electron Integration](#electron-integration)\n4. [Inter-Process Communication (IPC)](#inter-process-communication-ipc)\n5. [Routing](#routing)\n6. [Internationalization (i18n)](#internationalization-i18n)\n7. [Testing](#testing)\n8. [Build and Packaging](#build-and-packaging)\n9. [Development Workflow](#development-workflow)\n10. [References](#references)\n\n---\n\n## Project Structure\n\nThe project follows a modular structure to separate concerns and enhance maintainability:\n\n```\nproject-root/\n├── public/\n├── src/\n│   ├── main/               # Electron main process\n│   │   └── main.ts\n│   ├── renderer/           # React application\n│   │   ├── components/     # Reusable UI components\n│   │   ├── pages/          # Page components\n│   │   ├── stores/         # MobX stores\n│   │   ├── utils/          # Utility functions\n│   │   ├── App.tsx         # Root component\n│   │   └── index.tsx       # Entry point\n├── package.json\n├── tsconfig.json\n├── webpack.config.js\n└── ...\n```\n\n---\n\n## State Management with MobX\n\nMobX is utilized for state management, providing a simple and scalable solution.\n\n- **Store Initialization**: Each domain has its own store class, decorated with `makeAutoObservable` to enable reactivity.\n\n```typescript\nimport { makeAutoObservable } from 'mobx';\n\nclass TodoStore {\n  todos = [];\n\n  constructor() {\n    makeAutoObservable(this);\n  }\n\n  addTodo(todo) {\n    this.todos.push(todo);\n  }\n}\n\nexport const todoStore = new TodoStore();\n```\n\n- **Context Provider**: Stores are provided to React components via Context API.\n\n```typescript\nimport React from 'react';\nimport { todoStore } from './stores/TodoStore';\n\nexport const StoreContext = React.createContext({\n  todoStore,\n});\n```\n\n- **Usage in Components**: Components consume stores using the `useContext` hook and are wrapped with `observer`.\n\n```typescript\nimport React, { useContext } from 'react';\nimport { observer } from 'mobx-react-lite';\nimport { StoreContext } from '../StoreContext';\n\nconst TodoList = observer(() => {\n  const { todoStore } = useContext(StoreContext);\n\n  return (\n    <ul>\n      {todoStore.todos.map(todo => (\n        <li key={todo.id}>{todo.title}</li>\n      ))}\n    </ul>\n  );\n});\n\nexport default TodoList;\n```\n\n---\n\n## Electron Integration\n\nElectron enables the creation of cross-platform desktop applications using web technologies.\n\n- **Main Process**:\n\n```typescript\nimport { app, BrowserWindow } from 'electron';\n\nfunction createWindow() {\n  const win = new BrowserWindow({\n    width: 800,\n    height: 600,\n    webPreferences: {\n      preload: path.join(__dirname, 'preload.js'),\n    },\n  });\n\n  win.loadURL('http://localhost:3000');\n}\n\napp.whenReady().then(createWindow);\n```\n\n- **Preload Script**:\n\n```typescript\nimport { contextBridge, ipcRenderer } from 'electron';\n\ncontextBridge.exposeInMainWorld('api', {\n  send: (channel, data) => ipcRenderer.send(channel, data),\n  receive: (channel, func) => ipcRenderer.on(channel, (event, ...args) => func(...args)),\n});\n```\n\n---\n\n## Inter-Process Communication (IPC)\n\nIPC facilitates communication between the main and renderer processes.\n\n- **Renderer Process**:\n\n```typescript\nwindow.api.send('channel-name', data);\n```\n\n- **Main Process**:\n\n```typescript\nipcMain.on('channel-name', (event, data) => {\n  event.reply('channel-name-response', responseData);\n});\n```\n\n---\n\n## Routing\n\nReact Router is employed for client-side routing within the renderer process.\n\n```typescript\nimport { BrowserRouter as Router, Route, Switch } from 'react-router-dom';\n\nconst App = () => (\n  <Router>\n    <Switch>\n      <Route path=\"/\" exact component={HomePage} />\n      <Route path=\"/about\" component={AboutPage} />\n    </Switch>\n  </Router>\n);\n```\n\n---\n\n## Internationalization (i18n)\n\nThe application supports multiple languages using `react-intl`.\n\n- **Provider Setup**:\n\n```typescript\nimport { IntlProvider } from 'react-intl';\nimport messages_en from './translations/en.json';\nimport messages_de from './translations/de.json';\n\nconst messages = {\n  en: messages_en,\n  de: messages_de,\n};\n\nconst language = navigator.language.split(/[-_]/)[0];\n\nconst App = () => (\n  <IntlProvider locale={language} messages={messages[language]}>\n    {/* Application components */}\n  </IntlProvider>\n);\n```\n\n- **Usage in Components**:\n\n```typescript\nimport { FormattedMessage } from 'react-intl';\n\nconst Greeting = () => (\n  <p>\n    <FormattedMessage id=\"app.greeting\" defaultMessage=\"Hello, World!\" />\n  </p>\n);\n```\n\n---\n\n## Testing\n\nTesting ensures the reliability of the application.\n\n- **Unit Testing**:\n\n```typescript\ntest('adds two numbers', () => {\n  expect(add(2, 3)).toBe(5);\n});\n```\n\n- **Component Testing**:\n\n```typescript\nimport { render, screen } from '@testing-library/react';\nimport TodoList from './TodoList';\n\ntest('renders todo items', () => {\n  render(<TodoList />);\n  expect(screen.getByText(/Sample Todo/i)).toBeInTheDocument();\n});\n```\n\n---\n\n## Build and Packaging\n\n- **Development Build**:\n\n```bash\nnpm run dev\n```\n\n- **Production Build**:\n\n```bash\nnpm run build\n```\n\n- **Packaging**:\n\n```bash\nnpm run dist\n```\n\n---\n\n## Development Workflow\n\n1. **Install Dependencies**:\n\n```bash\nnpm install\n```\n\n2. **Start Development Server**:\n\n```bash\nnpm run dev\n```\n\n3. **Start Electron**:\n\n```bash\nnpm run electron\n```\n\n4. **Run Tests**:\n\n```bash\nnpm test\n```\n\n---\n\n## References\n\n- [Electron Documentation](https://www.electronjs.org/docs)\n- [React Documentation](https://reactjs.org/docs/getting-started.html)\n- [MobX Documentation](https://mobx.js.org/README.html)\n- [TypeScript Documentation](https://www.typescriptlang.org/docs/)\n- [React Router Documentation](https://reactrouter.com/)\n- [react-intl Documentation](https://formatjs.io/docs/react-intl/)\n","CLAUDE.md":"# CLAUDE.md\n\nThis file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.\n\n## Development Commands\n\n### Core Commands\n- `npm run start:dev` - Start development with hot reload (macOS/Linux)\n- `npm run start:dev-win` - Start development with hot reload (Windows)\n- `npm run build` - Production build\n- `npm run build:dev` - Development build\n- `npm run typecheck` - Run TypeScript type checking\n- `npm run lint` - Run ESLint\n\n### Testing and Quality\n- `npm run precommit` - Run pre-commit checks (lint-staged)\n- Always run `npm run typecheck` and `npm run lint` after making changes\n\n### Distribution\n- `npm run dist:mac` - Build macOS distribution\n- `npm run dist:win` - Build Windows distribution  \n- `npm run dist:linux` - Build Linux distribution\n\n### Development Setup\nBefore development, you need the anytype-heart middleware:\n1. Run `./update.sh <platform> <arch>` to fetch middleware\n2. Start anytypeHelper binary in background\n3. Use `SERVER_PORT` env var to specify gRPC port\n\n## Architecture Overview\n\n### High-Level Structure\nAnytype is an Electron-based desktop application with TypeScript/React frontend communicating with a Go-based middleware (anytype-heart) via gRPC.\n\n**Key Components:**\n- **Electron Main Process** (`electron.js`) - Window management, IPC, system integration\n- **React Frontend** (`src/ts/`) - UI components and business logic\n- **gRPC Middleware** - Backend logic (separate anytype-heart repository)\n- **Block-based Editor** - Document editing with composable blocks\n\n### Frontend Architecture (src/ts/)\n\n**Entry Points:**\n- `entry.tsx` - Application entry point\n- `app.tsx` - Main React application component\n\n**Core Libraries (`lib/`):**\n- `api/` - gRPC communication (dispatcher, commands, mapper)\n- `keyboard.ts` - Keyboard shortcuts and input handling\n- `storage.ts` - Local storage management\n- `renderer.ts` - Electron IPC communication\n- `util/` - Utility functions (common, data, router, etc.)\n\n**State Management (`store/`):**\n- MobX-based stores for different domains:\n- `common.ts` - Global application state\n- `auth.ts` - Authentication state\n- `block.ts` - Document block state\n- `detail.ts` - Object detail state\n- `menu.ts`, `popup.ts` - UI state\n\n**Component Structure (`component/`):**\n- `block/` - Document block components (text, dataview, media, etc.)\n- `page/` - Page-level components (auth, main, settings)\n- `menu/` - Context menus and dropdowns\n- `popup/` - Modal dialogs\n- `sidebar/` - Left/right sidebars\n- `util/` - Reusable UI utilities\n\n### Key Architectural Patterns\n\n**Block-Based Documents:**\n- Documents are composed of blocks (text, images, databases, etc.)\n- Each block type has corresponding model, content, and component\n- Block operations handled via gRPC commands\n\n**MobX State Management:**\n- Reactive state with MobX stores\n- Components observe store changes automatically\n- Stores organized by domain (auth, blocks, UI, etc.)\n\n**gRPC Communication:**\n- Frontend communicates with middleware via gRPC\n- Commands in `lib/api/command.ts`\n- Response mapping in `lib/api/mapper.ts`\n- Real-time updates via gRPC streaming\n\n**Electron Integration:**\n- Main process handles system integration\n- Renderer process handles UI\n- IPC communication for file operations, updates, etc.\n\n## Development Workflow\n\n### Making Changes\n1. Identify the relevant component in `src/ts/component/`\n2. Check corresponding interfaces in `src/ts/interface/`\n3. Look for related stores in `src/ts/store/`\n4. Update models in `src/ts/model/` if needed\n5. Add gRPC commands in `src/ts/lib/api/` if backend changes needed\n\n### File Organization\n- **Components**: UI components in `src/ts/component/`\n- **Styles**: SCSS files in `src/scss/` (organized to match components)\n- **Assets**: Images and icons in `src/img/`\n- **Configuration**: Electron config in `electron/`\n- **Build**: Rspack configuration in `rspack.config.js`\n\n### Key Development Notes\n- Uses Rspack for bundling (faster Webpack alternative)\n- TypeScript with React 17\n- MobX for state management\n- Custom block-based editor system\n- gRPC for backend communication\n- Electron for desktop app packaging\n- CSS supports native nesting - use nested selectors instead of flat/inline selectors\n- Do not use `cursor: pointer` in CSS - the app does not use custom cursors\n\n### Code Style\n- Write `else if` with a linebreak before `if`:\n  ```typescript\n  if (condition) {\n      // ...\n  } else\n  if (anotherCondition) {\n      // ...\n  }\n  ```\n\n### Important Patterns\n- All UI text should use `translate()` function for i18n\n- Translation keys are defined in `src/json/text.json`\n- Block operations should go through the command system\n- Use existing utility functions in `lib/util/` before creating new ones\n- Follow existing component patterns in `component/` directory\n- Store updates should trigger UI re-renders automatically via MobX\n\n## Web Mode Development\n\nRun in browser without Electron: `npm run start:web` (starts anytypeHelper + dev server). Use `ANYTYPE_USE_SIDE_SERVER=http://...` to skip helper start. See `src/ts/lib/web/README.md` for details.\n\n## Linear API Integration\n\nUse the `LINEAR_API_KEY` environment variable to fetch issue details from Linear.\n\n**Fetch issue by ID:**\n```bash\ncurl -s -X POST \"https://api.linear.app/graphql\" \\\n  --header \"Content-Type: application/json\" \\\n  --header \"Authorization: $(printenv LINEAR_API_KEY)\" \\\n  --data '{\"query\":\"query{issue(id:\\\"JS-1234\\\"){title description state{name}priority labels{nodes{name}}comments{nodes{body createdAt}}}}\"}' | jq .\n```\n\n**Important:** Use `$(printenv LINEAR_API_KEY)` instead of `$LINEAR_API_KEY` directly in curl commands to avoid shell expansion issues.\n\n## Figma MCP Integration\n\nUse the Figma MCP tools to fetch design context and screenshots from Figma files.\n\n**Available tools:**\n- `mcp__figma__get_design_context` - Get UI code/design context for a Figma node (preferred)\n- `mcp__figma__get_screenshot` - Get a screenshot of a Figma node\n- `mcp__figma__get_metadata` - Get metadata/structure of a Figma node\n\n**Extract parameters from Figma URLs:**\n- URL format: `https://www.figma.com/design/:fileKey/:fileName?node-id=:nodeId`\n- `fileKey` is the ID after `/design/`\n- `nodeId` is in the `node-id` query parameter (convert `-` to `:` for the API)\n\n**Example usage:**\nFor URL `https://www.figma.com/design/uWka9aJ7IOdvHch60rIRlb/MyFile?node-id=12769-19003`:\n- `fileKey`: `uWka9aJ7IOdvHch60rIRlb`\n- `nodeId`: `12769:19003`"},"files":{"AGENTS.md":"\n# agents.md\n\n## Overview\n\nThis document outlines the architecture and implementation details of the Electron application built with React, TypeScript, and MobX. It covers the project's structure, state management, inter-process communication, and other essential aspects to facilitate understanding and contribution.\n\n## Table of Contents\n\n1. [Project Structure](#project-structure)\n2. [State Management with MobX](#state-management-with-mobx)\n3. [Electron Integration](#electron-integration)\n4. [Inter-Process Communication (IPC)](#inter-process-communication-ipc)\n5. [Routing](#routing)\n6. [Internationalization (i18n)](#internationalization-i18n)\n7. [Testing](#testing)\n8. [Build and Packaging](#build-and-packaging)\n9. [Development Workflow](#development-workflow)\n10. [References](#references)\n\n---\n\n## Project Structure\n\nThe project follows a modular structure to separate concerns and enhance maintainability:\n\n```\nproject-root/\n├── public/\n├── src/\n│   ├── main/               # Electron main process\n│   │   └── main.ts\n│   ├── renderer/           # React application\n│   │   ├── components/     # Reusable UI components\n│   │   ├── pages/          # Page components\n│   │   ├── stores/         # MobX stores\n│   │   ├── utils/          # Utility functions\n│   │   ├── App.tsx         # Root component\n│   │   └── index.tsx       # Entry point\n├── package.json\n├── tsconfig.json\n├── webpack.config.js\n└── ...\n```\n\n---\n\n## State Management with MobX\n\nMobX is utilized for state management, providing a simple and scalable solution.\n\n- **Store Initialization**: Each domain has its own store class, decorated with `makeAutoObservable` to enable reactivity.\n\n```typescript\nimport { makeAutoObservable } from 'mobx';\n\nclass TodoStore {\n  todos = [];\n\n  constructor() {\n    makeAutoObservable(this);\n  }\n\n  addTodo(todo) {\n    this.todos.push(todo);\n  }\n}\n\nexport const todoStore = new TodoStore();\n```\n\n- **Context Provider**: Stores are provided to React components via Context API.\n\n```typescript\nimport React from 'react';\nimport { todoStore } from './stores/TodoStore';\n\nexport const StoreContext = React.createContext({\n  todoStore,\n});\n```\n\n- **Usage in Components**: Components consume stores using the `useContext` hook and are wrapped with `observer`.\n\n```typescript\nimport React, { useContext } from 'react';\nimport { observer } from 'mobx-react-lite';\nimport { StoreContext } from '../StoreContext';\n\nconst TodoList = observer(() => {\n  const { todoStore } = useContext(StoreContext);\n\n  return (\n    <ul>\n      {todoStore.todos.map(todo => (\n        <li key={todo.id}>{todo.title}</li>\n      ))}\n    </ul>\n  );\n});\n\nexport default TodoList;\n```\n\n---\n\n## Electron Integration\n\nElectron enables the creation of cross-platform desktop applications using web technologies.\n\n- **Main Process**:\n\n```typescript\nimport { app, BrowserWindow } from 'electron';\n\nfunction createWindow() {\n  const win = new BrowserWindow({\n    width: 800,\n    height: 600,\n    webPreferences: {\n      preload: path.join(__dirname, 'preload.js'),\n    },\n  });\n\n  win.loadURL('http://localhost:3000');\n}\n\napp.whenReady().then(createWindow);\n```\n\n- **Preload Script**:\n\n```typescript\nimport { contextBridge, ipcRenderer } from 'electron';\n\ncontextBridge.exposeInMainWorld('api', {\n  send: (channel, data) => ipcRenderer.send(channel, data),\n  receive: (channel, func) => ipcRenderer.on(channel, (event, ...args) => func(...args)),\n});\n```\n\n---\n\n## Inter-Process Communication (IPC)\n\nIPC facilitates communication between the main and renderer processes.\n\n- **Renderer Process**:\n\n```typescript\nwindow.api.send('channel-name', data);\n```\n\n- **Main Process**:\n\n```typescript\nipcMain.on('channel-name', (event, data) => {\n  event.reply('channel-name-response', responseData);\n});\n```\n\n---\n\n## Routing\n\nReact Router is employed for client-side routing within the renderer process.\n\n```typescript\nimport { BrowserRouter as Router, Route, Switch } from 'react-router-dom';\n\nconst App = () => (\n  <Router>\n    <Switch>\n      <Route path=\"/\" exact component={HomePage} />\n      <Route path=\"/about\" component={AboutPage} />\n    </Switch>\n  </Router>\n);\n```\n\n---\n\n## Internationalization (i18n)\n\nThe application supports multiple languages using `react-intl`.\n\n- **Provider Setup**:\n\n```typescript\nimport { IntlProvider } from 'react-intl';\nimport messages_en from './translations/en.json';\nimport messages_de from './translations/de.json';\n\nconst messages = {\n  en: messages_en,\n  de: messages_de,\n};\n\nconst language = navigator.language.split(/[-_]/)[0];\n\nconst App = () => (\n  <IntlProvider locale={language} messages={messages[language]}>\n    {/* Application components */}\n  </IntlProvider>\n);\n```\n\n- **Usage in Components**:\n\n```typescript\nimport { FormattedMessage } from 'react-intl';\n\nconst Greeting = () => (\n  <p>\n    <FormattedMessage id=\"app.greeting\" defaultMessage=\"Hello, World!\" />\n  </p>\n);\n```\n\n---\n\n## Testing\n\nTesting ensures the reliability of the application.\n\n- **Unit Testing**:\n\n```typescript\ntest('adds two numbers', () => {\n  expect(add(2, 3)).toBe(5);\n});\n```\n\n- **Component Testing**:\n\n```typescript\nimport { render, screen } from '@testing-library/react';\nimport TodoList from './TodoList';\n\ntest('renders todo items', () => {\n  render(<TodoList />);\n  expect(screen.getByText(/Sample Todo/i)).toBeInTheDocument();\n});\n```\n\n---\n\n## Build and Packaging\n\n- **Development Build**:\n\n```bash\nnpm run dev\n```\n\n- **Production Build**:\n\n```bash\nnpm run build\n```\n\n- **Packaging**:\n\n```bash\nnpm run dist\n```\n\n---\n\n## Development Workflow\n\n1. **Install Dependencies**:\n\n```bash\nnpm install\n```\n\n2. **Start Development Server**:\n\n```bash\nnpm run dev\n```\n\n3. **Start Electron**:\n\n```bash\nnpm run electron\n```\n\n4. **Run Tests**:\n\n```bash\nnpm test\n```\n\n---\n\n## References\n\n- [Electron Documentation](https://www.electronjs.org/docs)\n- [React Documentation](https://reactjs.org/docs/getting-started.html)\n- [MobX Documentation](https://mobx.js.org/README.html)\n- [TypeScript Documentation](https://www.typescriptlang.org/docs/)\n- [React Router Documentation](https://reactrouter.com/)\n- [react-intl Documentation](https://formatjs.io/docs/react-intl/)\n","CLAUDE.md":"# CLAUDE.md\n\nThis file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.\n\n## Development Commands\n\n### Core Commands\n- `npm run start:dev` - Start development with hot reload (macOS/Linux)\n- `npm run start:dev-win` - Start development with hot reload (Windows)\n- `npm run build` - Production build\n- `npm run build:dev` - Development build\n- `npm run typecheck` - Run TypeScript type checking\n- `npm run lint` - Run ESLint\n\n### Testing and Quality\n- `npm run precommit` - Run pre-commit checks (lint-staged)\n- Always run `npm run typecheck` and `npm run lint` after making changes\n\n### Distribution\n- `npm run dist:mac` - Build macOS distribution\n- `npm run dist:win` - Build Windows distribution  \n- `npm run dist:linux` - Build Linux distribution\n\n### Development Setup\nBefore development, you need the anytype-heart middleware:\n1. Run `./update.sh <platform> <arch>` to fetch middleware\n2. Start anytypeHelper binary in background\n3. Use `SERVER_PORT` env var to specify gRPC port\n\n## Architecture Overview\n\n### High-Level Structure\nAnytype is an Electron-based desktop application with TypeScript/React frontend communicating with a Go-based middleware (anytype-heart) via gRPC.\n\n**Key Components:**\n- **Electron Main Process** (`electron.js`) - Window management, IPC, system integration\n- **React Frontend** (`src/ts/`) - UI components and business logic\n- **gRPC Middleware** - Backend logic (separate anytype-heart repository)\n- **Block-based Editor** - Document editing with composable blocks\n\n### Frontend Architecture (src/ts/)\n\n**Entry Points:**\n- `entry.tsx` - Application entry point\n- `app.tsx` - Main React application component\n\n**Core Libraries (`lib/`):**\n- `api/` - gRPC communication (dispatcher, commands, mapper)\n- `keyboard.ts` - Keyboard shortcuts and input handling\n- `storage.ts` - Local storage management\n- `renderer.ts` - Electron IPC communication\n- `util/` - Utility functions (common, data, router, etc.)\n\n**State Management (`store/`):**\n- MobX-based stores for different domains:\n- `common.ts` - Global application state\n- `auth.ts` - Authentication state\n- `block.ts` - Document block state\n- `detail.ts` - Object detail state\n- `menu.ts`, `popup.ts` - UI state\n\n**Component Structure (`component/`):**\n- `block/` - Document block components (text, dataview, media, etc.)\n- `page/` - Page-level components (auth, main, settings)\n- `menu/` - Context menus and dropdowns\n- `popup/` - Modal dialogs\n- `sidebar/` - Left/right sidebars\n- `util/` - Reusable UI utilities\n\n### Key Architectural Patterns\n\n**Block-Based Documents:**\n- Documents are composed of blocks (text, images, databases, etc.)\n- Each block type has corresponding model, content, and component\n- Block operations handled via gRPC commands\n\n**MobX State Management:**\n- Reactive state with MobX stores\n- Components observe store changes automatically\n- Stores organized by domain (auth, blocks, UI, etc.)\n\n**gRPC Communication:**\n- Frontend communicates with middleware via gRPC\n- Commands in `lib/api/command.ts`\n- Response mapping in `lib/api/mapper.ts`\n- Real-time updates via gRPC streaming\n\n**Electron Integration:**\n- Main process handles system integration\n- Renderer process handles UI\n- IPC communication for file operations, updates, etc.\n\n## Development Workflow\n\n### Making Changes\n1. Identify the relevant component in `src/ts/component/`\n2. Check corresponding interfaces in `src/ts/interface/`\n3. Look for related stores in `src/ts/store/`\n4. Update models in `src/ts/model/` if needed\n5. Add gRPC commands in `src/ts/lib/api/` if backend changes needed\n\n### File Organization\n- **Components**: UI components in `src/ts/component/`\n- **Styles**: SCSS files in `src/scss/` (organized to match components)\n- **Assets**: Images and icons in `src/img/`\n- **Configuration**: Electron config in `electron/`\n- **Build**: Rspack configuration in `rspack.config.js`\n\n### Key Development Notes\n- Uses Rspack for bundling (faster Webpack alternative)\n- TypeScript with React 17\n- MobX for state management\n- Custom block-based editor system\n- gRPC for backend communication\n- Electron for desktop app packaging\n- CSS supports native nesting - use nested selectors instead of flat/inline selectors\n- Do not use `cursor: pointer` in CSS - the app does not use custom cursors\n\n### Code Style\n- Write `else if` with a linebreak before `if`:\n  ```typescript\n  if (condition) {\n      // ...\n  } else\n  if (anotherCondition) {\n      // ...\n  }\n  ```\n\n### Important Patterns\n- All UI text should use `translate()` function for i18n\n- Translation keys are defined in `src/json/text.json`\n- Block operations should go through the command system\n- Use existing utility functions in `lib/util/` before creating new ones\n- Follow existing component patterns in `component/` directory\n- Store updates should trigger UI re-renders automatically via MobX\n\n## Web Mode Development\n\nRun in browser without Electron: `npm run start:web` (starts anytypeHelper + dev server). Use `ANYTYPE_USE_SIDE_SERVER=http://...` to skip helper start. See `src/ts/lib/web/README.md` for details.\n\n## Linear API Integration\n\nUse the `LINEAR_API_KEY` environment variable to fetch issue details from Linear.\n\n**Fetch issue by ID:**\n```bash\ncurl -s -X POST \"https://api.linear.app/graphql\" \\\n  --header \"Content-Type: application/json\" \\\n  --header \"Authorization: $(printenv LINEAR_API_KEY)\" \\\n  --data '{\"query\":\"query{issue(id:\\\"JS-1234\\\"){title description state{name}priority labels{nodes{name}}comments{nodes{body createdAt}}}}\"}' | jq .\n```\n\n**Important:** Use `$(printenv LINEAR_API_KEY)` instead of `$LINEAR_API_KEY` directly in curl commands to avoid shell expansion issues.\n\n## Figma MCP Integration\n\nUse the Figma MCP tools to fetch design context and screenshots from Figma files.\n\n**Available tools:**\n- `mcp__figma__get_design_context` - Get UI code/design context for a Figma node (preferred)\n- `mcp__figma__get_screenshot` - Get a screenshot of a Figma node\n- `mcp__figma__get_metadata` - Get metadata/structure of a Figma node\n\n**Extract parameters from Figma URLs:**\n- URL format: `https://www.figma.com/design/:fileKey/:fileName?node-id=:nodeId`\n- `fileKey` is the ID after `/design/`\n- `nodeId` is in the `node-id` query parameter (convert `-` to `:` for the API)\n\n**Example usage:**\nFor URL `https://www.figma.com/design/uWka9aJ7IOdvHch60rIRlb/MyFile?node-id=12769-19003`:\n- `fileKey`: `uWka9aJ7IOdvHch60rIRlb`\n- `nodeId`: `12769:19003`"},"items":[{"name":"AGENTS.md","path":"AGENTS.md","title":"AGENTS.md","content":"\n# agents.md\n\n## Overview\n\nThis document outlines the architecture and implementation details of the Electron application built with React, TypeScript, and MobX. It covers the project's structure, state management, inter-process communication, and other essential aspects to facilitate understanding and contribution.\n\n## Table of Contents\n\n1. [Project Structure](#project-structure)\n2. [State Management with MobX](#state-management-with-mobx)\n3. [Electron Integration](#electron-integration)\n4. [Inter-Process Communication (IPC)](#inter-process-communication-ipc)\n5. [Routing](#routing)\n6. [Internationalization (i18n)](#internationalization-i18n)\n7. [Testing](#testing)\n8. [Build and Packaging](#build-and-packaging)\n9. [Development Workflow](#development-workflow)\n10. [References](#references)\n\n---\n\n## Project Structure\n\nThe project follows a modular structure to separate concerns and enhance maintainability:\n\n```\nproject-root/\n├── public/\n├── src/\n│   ├── main/               # Electron main process\n│   │   └── main.ts\n│   ├── renderer/           # React application\n│   │   ├── components/     # Reusable UI components\n│   │   ├── pages/          # Page components\n│   │   ├── stores/         # MobX stores\n│   │   ├── utils/          # Utility functions\n│   │   ├── App.tsx         # Root component\n│   │   └── index.tsx       # Entry point\n├── package.json\n├── tsconfig.json\n├── webpack.config.js\n└── ...\n```\n\n---\n\n## State Management with MobX\n\nMobX is utilized for state management, providing a simple and scalable solution.\n\n- **Store Initialization**: Each domain has its own store class, decorated with `makeAutoObservable` to enable reactivity.\n\n```typescript\nimport { makeAutoObservable } from 'mobx';\n\nclass TodoStore {\n  todos = [];\n\n  constructor() {\n    makeAutoObservable(this);\n  }\n\n  addTodo(todo) {\n    this.todos.push(todo);\n  }\n}\n\nexport const todoStore = new TodoStore();\n```\n\n- **Context Provider**: Stores are provided to React components via Context API.\n\n```typescript\nimport React from 'react';\nimport { todoStore } from './stores/TodoStore';\n\nexport const StoreContext = React.createContext({\n  todoStore,\n});\n```\n\n- **Usage in Components**: Components consume stores using the `useContext` hook and are wrapped with `observer`.\n\n```typescript\nimport React, { useContext } from 'react';\nimport { observer } from 'mobx-react-lite';\nimport { StoreContext } from '../StoreContext';\n\nconst TodoList = observer(() => {\n  const { todoStore } = useContext(StoreContext);\n\n  return (\n    <ul>\n      {todoStore.todos.map(todo => (\n        <li key={todo.id}>{todo.title}</li>\n      ))}\n    </ul>\n  );\n});\n\nexport default TodoList;\n```\n\n---\n\n## Electron Integration\n\nElectron enables the creation of cross-platform desktop applications using web technologies.\n\n- **Main Process**:\n\n```typescript\nimport { app, BrowserWindow } from 'electron';\n\nfunction createWindow() {\n  const win = new BrowserWindow({\n    width: 800,\n    height: 600,\n    webPreferences: {\n      preload: path.join(__dirname, 'preload.js'),\n    },\n  });\n\n  win.loadURL('http://localhost:3000');\n}\n\napp.whenReady().then(createWindow);\n```\n\n- **Preload Script**:\n\n```typescript\nimport { contextBridge, ipcRenderer } from 'electron';\n\ncontextBridge.exposeInMainWorld('api', {\n  send: (channel, data) => ipcRenderer.send(channel, data),\n  receive: (channel, func) => ipcRenderer.on(channel, (event, ...args) => func(...args)),\n});\n```\n\n---\n\n## Inter-Process Communication (IPC)\n\nIPC facilitates communication between the main and renderer processes.\n\n- **Renderer Process**:\n\n```typescript\nwindow.api.send('channel-name', data);\n```\n\n- **Main Process**:\n\n```typescript\nipcMain.on('channel-name', (event, data) => {\n  event.reply('channel-name-response', responseData);\n});\n```\n\n---\n\n## Routing\n\nReact Router is employed for client-side routing within the renderer process.\n\n```typescript\nimport { BrowserRouter as Router, Route, Switch } from 'react-router-dom';\n\nconst App = () => (\n  <Router>\n    <Switch>\n      <Route path=\"/\" exact component={HomePage} />\n      <Route path=\"/about\" component={AboutPage} />\n    </Switch>\n  </Router>\n);\n```\n\n---\n\n## Internationalization (i18n)\n\nThe application supports multiple languages using `react-intl`.\n\n- **Provider Setup**:\n\n```typescript\nimport { IntlProvider } from 'react-intl';\nimport messages_en from './translations/en.json';\nimport messages_de from './translations/de.json';\n\nconst messages = {\n  en: messages_en,\n  de: messages_de,\n};\n\nconst language = navigator.language.split(/[-_]/)[0];\n\nconst App = () => (\n  <IntlProvider locale={language} messages={messages[language]}>\n    {/* Application components */}\n  </IntlProvider>\n);\n```\n\n- **Usage in Components**:\n\n```typescript\nimport { FormattedMessage } from 'react-intl';\n\nconst Greeting = () => (\n  <p>\n    <FormattedMessage id=\"app.greeting\" defaultMessage=\"Hello, World!\" />\n  </p>\n);\n```\n\n---\n\n## Testing\n\nTesting ensures the reliability of the application.\n\n- **Unit Testing**:\n\n```typescript\ntest('adds two numbers', () => {\n  expect(add(2, 3)).toBe(5);\n});\n```\n\n- **Component Testing**:\n\n```typescript\nimport { render, screen } from '@testing-library/react';\nimport TodoList from './TodoList';\n\ntest('renders todo items', () => {\n  render(<TodoList />);\n  expect(screen.getByText(/Sample Todo/i)).toBeInTheDocument();\n});\n```\n\n---\n\n## Build and Packaging\n\n- **Development Build**:\n\n```bash\nnpm run dev\n```\n\n- **Production Build**:\n\n```bash\nnpm run build\n```\n\n- **Packaging**:\n\n```bash\nnpm run dist\n```\n\n---\n\n## Development Workflow\n\n1. **Install Dependencies**:\n\n```bash\nnpm install\n```\n\n2. **Start Development Server**:\n\n```bash\nnpm run dev\n```\n\n3. **Start Electron**:\n\n```bash\nnpm run electron\n```\n\n4. **Run Tests**:\n\n```bash\nnpm test\n```\n\n---\n\n## References\n\n- [Electron Documentation](https://www.electronjs.org/docs)\n- [React Documentation](https://reactjs.org/docs/getting-started.html)\n- [MobX Documentation](https://mobx.js.org/README.html)\n- [TypeScript Documentation](https://www.typescriptlang.org/docs/)\n- [React Router Documentation](https://reactrouter.com/)\n- [react-intl Documentation](https://formatjs.io/docs/react-intl/)\n","category":"root","tokens":1537},{"name":"CLAUDE.md","path":"CLAUDE.md","title":"CLAUDE.md","content":"# CLAUDE.md\n\nThis file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.\n\n## Development Commands\n\n### Core Commands\n- `npm run start:dev` - Start development with hot reload (macOS/Linux)\n- `npm run start:dev-win` - Start development with hot reload (Windows)\n- `npm run build` - Production build\n- `npm run build:dev` - Development build\n- `npm run typecheck` - Run TypeScript type checking\n- `npm run lint` - Run ESLint\n\n### Testing and Quality\n- `npm run precommit` - Run pre-commit checks (lint-staged)\n- Always run `npm run typecheck` and `npm run lint` after making changes\n\n### Distribution\n- `npm run dist:mac` - Build macOS distribution\n- `npm run dist:win` - Build Windows distribution  \n- `npm run dist:linux` - Build Linux distribution\n\n### Development Setup\nBefore development, you need the anytype-heart middleware:\n1. Run `./update.sh <platform> <arch>` to fetch middleware\n2. Start anytypeHelper binary in background\n3. Use `SERVER_PORT` env var to specify gRPC port\n\n## Architecture Overview\n\n### High-Level Structure\nAnytype is an Electron-based desktop application with TypeScript/React frontend communicating with a Go-based middleware (anytype-heart) via gRPC.\n\n**Key Components:**\n- **Electron Main Process** (`electron.js`) - Window management, IPC, system integration\n- **React Frontend** (`src/ts/`) - UI components and business logic\n- **gRPC Middleware** - Backend logic (separate anytype-heart repository)\n- **Block-based Editor** - Document editing with composable blocks\n\n### Frontend Architecture (src/ts/)\n\n**Entry Points:**\n- `entry.tsx` - Application entry point\n- `app.tsx` - Main React application component\n\n**Core Libraries (`lib/`):**\n- `api/` - gRPC communication (dispatcher, commands, mapper)\n- `keyboard.ts` - Keyboard shortcuts and input handling\n- `storage.ts` - Local storage management\n- `renderer.ts` - Electron IPC communication\n- `util/` - Utility functions (common, data, router, etc.)\n\n**State Management (`store/`):**\n- MobX-based stores for different domains:\n- `common.ts` - Global application state\n- `auth.ts` - Authentication state\n- `block.ts` - Document block state\n- `detail.ts` - Object detail state\n- `menu.ts`, `popup.ts` - UI state\n\n**Component Structure (`component/`):**\n- `block/` - Document block components (text, dataview, media, etc.)\n- `page/` - Page-level components (auth, main, settings)\n- `menu/` - Context menus and dropdowns\n- `popup/` - Modal dialogs\n- `sidebar/` - Left/right sidebars\n- `util/` - Reusable UI utilities\n\n### Key Architectural Patterns\n\n**Block-Based Documents:**\n- Documents are composed of blocks (text, images, databases, etc.)\n- Each block type has corresponding model, content, and component\n- Block operations handled via gRPC commands\n\n**MobX State Management:**\n- Reactive state with MobX stores\n- Components observe store changes automatically\n- Stores organized by domain (auth, blocks, UI, etc.)\n\n**gRPC Communication:**\n- Frontend communicates with middleware via gRPC\n- Commands in `lib/api/command.ts`\n- Response mapping in `lib/api/mapper.ts`\n- Real-time updates via gRPC streaming\n\n**Electron Integration:**\n- Main process handles system integration\n- Renderer process handles UI\n- IPC communication for file operations, updates, etc.\n\n## Development Workflow\n\n### Making Changes\n1. Identify the relevant component in `src/ts/component/`\n2. Check corresponding interfaces in `src/ts/interface/`\n3. Look for related stores in `src/ts/store/`\n4. Update models in `src/ts/model/` if needed\n5. Add gRPC commands in `src/ts/lib/api/` if backend changes needed\n\n### File Organization\n- **Components**: UI components in `src/ts/component/`\n- **Styles**: SCSS files in `src/scss/` (organized to match components)\n- **Assets**: Images and icons in `src/img/`\n- **Configuration**: Electron config in `electron/`\n- **Build**: Rspack configuration in `rspack.config.js`\n\n### Key Development Notes\n- Uses Rspack for bundling (faster Webpack alternative)\n- TypeScript with React 17\n- MobX for state management\n- Custom block-based editor system\n- gRPC for backend communication\n- Electron for desktop app packaging\n- CSS supports native nesting - use nested selectors instead of flat/inline selectors\n- Do not use `cursor: pointer` in CSS - the app does not use custom cursors\n\n### Code Style\n- Write `else if` with a linebreak before `if`:\n  ```typescript\n  if (condition) {\n      // ...\n  } else\n  if (anotherCondition) {\n      // ...\n  }\n  ```\n\n### Important Patterns\n- All UI text should use `translate()` function for i18n\n- Translation keys are defined in `src/json/text.json`\n- Block operations should go through the command system\n- Use existing utility functions in `lib/util/` before creating new ones\n- Follow existing component patterns in `component/` directory\n- Store updates should trigger UI re-renders automatically via MobX\n\n## Web Mode Development\n\nRun in browser without Electron: `npm run start:web` (starts anytypeHelper + dev server). Use `ANYTYPE_USE_SIDE_SERVER=http://...` to skip helper start. See `src/ts/lib/web/README.md` for details.\n\n## Linear API Integration\n\nUse the `LINEAR_API_KEY` environment variable to fetch issue details from Linear.\n\n**Fetch issue by ID:**\n```bash\ncurl -s -X POST \"https://api.linear.app/graphql\" \\\n  --header \"Content-Type: application/json\" \\\n  --header \"Authorization: $(printenv LINEAR_API_KEY)\" \\\n  --data '{\"query\":\"query{issue(id:\\\"JS-1234\\\"){title description state{name}priority labels{nodes{name}}comments{nodes{body createdAt}}}}\"}' | jq .\n```\n\n**Important:** Use `$(printenv LINEAR_API_KEY)` instead of `$LINEAR_API_KEY` directly in curl commands to avoid shell expansion issues.\n\n## Figma MCP Integration\n\nUse the Figma MCP tools to fetch design context and screenshots from Figma files.\n\n**Available tools:**\n- `mcp__figma__get_design_context` - Get UI code/design context for a Figma node (preferred)\n- `mcp__figma__get_screenshot` - Get a screenshot of a Figma node\n- `mcp__figma__get_metadata` - Get metadata/structure of a Figma node\n\n**Extract parameters from Figma URLs:**\n- URL format: `https://www.figma.com/design/:fileKey/:fileName?node-id=:nodeId`\n- `fileKey` is the ID after `/design/`\n- `nodeId` is in the `node-id` query parameter (convert `-` to `:` for the API)\n\n**Example usage:**\nFor URL `https://www.figma.com/design/uWka9aJ7IOdvHch60rIRlb/MyFile?node-id=12769-19003`:\n- `fileKey`: `uWka9aJ7IOdvHch60rIRlb`\n- `nodeId`: `12769:19003`","category":"root","tokens":1617}]}