architecture
The architecture skill determines correct file placement and structure within an Electron multi-process project by applying a decision tree that routes UI code to the renderer layer, IPC handlers to bridges, business logic to services, and specialized tasks to agent platforms, worker threads, common utilities, webservers, extensions, or messaging channels. Use this skill when adding new features to ensure code lands in the appropriate directory and respects process boundary constraints.
git clone --depth 1 https://github.com/iOfficeAI/AionUi /tmp/architecture && cp -r /tmp/architecture/.claude/skills/architecture ~/.claude/skills/architectureSKILL.md
# Architecture Skill
Determine correct file placement and structure for an Electron multi-process project.
## Detailed References
- **Renderer layer** (components, hooks, utils, pages, CSS): [references/renderer.md](references/renderer.md)
- **Main process & shared layer** (bridges, services, worker, preload): [references/process.md](references/process.md)
- **Project root & monorepo layout** (directory structure, migration status): [references/project-layout.md](references/project-layout.md)
---
## Decision Tree — Where Does New Code Go?
```
Is it UI (React components, hooks, pages)?
└── YES → packages/desktop/src/renderer/ → see references/renderer.md
Is it an IPC handler responding to renderer calls?
└── YES → packages/desktop/src/process/bridge/ → see references/process.md
Is it business logic running in the main process?
└── YES → packages/desktop/src/process/services/ → see references/process.md
Is it an AI platform connection (API client, message protocol)?
└── YES → packages/desktop/src/process/agent/<platform>/
Is it a background task that runs in a worker thread?
└── YES → packages/desktop/src/process/worker/
Is it used by BOTH main and renderer processes?
└── YES → packages/desktop/src/common/
Is it an HTTP/WebSocket endpoint?
└── YES → packages/desktop/src/process/webserver/
Is it a plugin/extension resolver or loader?
└── YES → packages/desktop/src/process/extensions/
Is it a messaging channel (Lark, DingTalk, Telegram)?
└── YES → packages/desktop/src/process/channels/
```
---
## Process Boundary Rules
**Hard rules — violating them causes runtime crashes.**
| Process | Can use | Cannot use |
| --------------------------------------------------- | ---------------------------------------------------------- | ----------------------------------------------- |
| **Main** (`packages/desktop/src/process/`) | Node.js, Electron main APIs, `fs`, `path`, `child_process` | DOM APIs (`document`, `window`, React) |
| **Renderer** (`packages/desktop/src/renderer/`) | DOM APIs, React, browser APIs | Node.js APIs (`fs`, `path`), Electron main APIs |
| **Worker** (`packages/desktop/src/process/worker/`) | Node.js APIs | DOM APIs, Electron APIs |
| **Preload** (`packages/desktop/src/preload/`) | `contextBridge`, `ipcRenderer` | DOM manipulation, Node.js `fs` |
Cross-process communication:
- Main ↔ Renderer: IPC via `packages/desktop/src/preload/` + `packages/desktop/src/process/bridge/*.ts`
- Main ↔ Worker: fork protocol via `packages/desktop/src/process/worker/WorkerProtocol.ts`
```typescript
// NEVER in renderer
import { something } from '@process/services/foo'; // crashes at runtime
// Use IPC instead
const result = await window.api.someMethod(); // goes through preload
```
---
## Naming Conventions
### Directories
| Scope | Convention | Reason |
| ---------------------------------- | ---------- | ------------------------------------------------------- |
| **Renderer** component/module dirs | PascalCase | React convention — dir name = component name |
| **Everything else** | lowercase | Node.js convention |
| **Categorical dirs** (everywhere) | lowercase | `components/`, `hooks/`, `utils/`, `services/` |
| **Platform dirs** (everywhere) | lowercase | `acp/`, `codex/`, `gemini/` — cross-process consistency |
> Quick test: "Inside `packages/desktop/src/renderer/` AND represents a specific component/feature (not a category)?" → PascalCase. Otherwise → lowercase.
### Files
| Content | Convention | Examples |
| ------------------------- | ------------------------------- | ------------------------------------- |
| React components, classes | PascalCase | `SettingsModal.tsx`, `CronService.ts` |
| Hooks | camelCase with `use` prefix | `useTheme.ts`, `useCronJobs.ts` |
| Utilities, helpers | camelCase | `formatDate.ts`, `cronUtils.ts` |
| Entry points | `index.ts` / `index.tsx` | Required for directory-based modules |
| Config, types, constants | camelCase | `types.ts`, `constants.ts` |
| Styles | kebab-case or `Name.module.css` | `chat-layout.css` |
---
## Structural Rules
1. **Directory size limit**: Max **10** direct children. Split into subdirectories by responsibility when approaching.
2. **No single-file directories**: Merge into parent or related directory.
3. **Single file vs directory**: If a component needs a private sub-component or hook, convert to a directory with `index.tsx`.
4. **Page-private first**: Start code in `pages/<PageName>/`. Promote to shared only when a second consumer appears.
## Test File Mapping
Tests mirror source files in `tests/` subdirectories:
| Source | Test |
| ------------------------------------------------------------ | ----------------------------------------------- |
| `packages/desktop/src/process/services/CronService.ts` | `tests/unit/cronService.test.ts` |
| `packages/desktop/src/renderer/hooks/ui/useAutoScroll.ts` | `tests/unit/useAutoScroll.dom.test.ts` |
| `packages/desktop/src/process/extensions/ExtensionLoader.ts` | `tests/unit/extensions/extensionLoader.test.ts` |
When `tests/unit/` exceeds 10 direct children, group into subdirectories matching soUse when bumping the AionUi version: query AionCore release, verify artifacts, update package.json, generate CHANGELOG, branch, commit, push, create PR, auto-merge, tag release.
|
|
|
Use when creating a pull request, after committing changes, or when user invokes /oss-pr. Covers branch management, quality checks, commit, push, and PR creation.
|
|
|