Files
kintone-customize-manager/AGENTS.md
2026-03-12 12:27:16 +08:00

293 lines
7.0 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# AGENTS.md
Kintone Customize Manager - Electron + React 应用,用于管理 Kintone 自定义资源。
## 1. 构建命令
```bash
# 开发HMR + 热重载)
npm run dev
# 类型检查
npx tsc --noEmit
# 构建
npm run build
# 打包
npm run package:win # Windows
npm run package:mac # macOS
npm run package:linux # Linux
# 代码质量
npm run lint # ESLint 检查
npm run format # Prettier 格式化
```
**注意**: 无测试框架,项目暂无测试文件。
## 2. 项目架构
```
src/
├── main/ # Electron 主进程
│ ├── index.ts # 入口,创建窗口
│ ├── ipc-handlers.ts # IPC 处理器(所有通信入口)
│ ├── storage.ts # 文件存储 + 密码加密
│ └── kintone-api.ts # Kintone REST API 封装
├── preload/ # Preload 脚本
│ ├── index.ts # 暴露 API 到渲染进程
│ └── index.d.ts # 类型声明
└── renderer/ # React 渲染进程
└── src/
├── main.tsx # React 入口
├── App.tsx # 根组件
├── components/ # React 组件
├── stores/ # Zustand Stores
└── types/ # TypeScript 类型
```
## 3. 路径别名
| 别名 | 路径 |
| ------------- | -------------------- |
| `@renderer/*` | `src/renderer/src/*` |
| `@main/*` | `src/main/*` |
| `@preload/*` | `src/preload/*` |
## 4. 代码风格
### 导入顺序
```typescript
// 1. Node.js 内置模块
import { join } from "path";
import { app, BrowserWindow } from "electron";
// 2. 第三方库
import React, { useState, useEffect } from "react";
import { Button, Layout } from "antd";
// 3. 项目内部模块(别名)
import { useDomainStore } from "@renderer/stores";
// 4. 相对导入
import "./styles.css";
```
### 命名规范
- 组件文件/名: `PascalCase` (e.g., `DomainManager.tsx`)
- 工具函数文件: `camelCase` (e.g., `formatDate.ts`)
- Store 文件: `camelCase + Store` (e.g., `domainStore.ts`)
- 函数/变量: `camelCase` (e.g., `handleSubmit`)
- 常量: `UPPER_SNAKE_CASE` (e.g., `MAX_FILE_SIZE`)
- 类型/接口: `PascalCase` (e.g., `DomainConfig`)
### TypeScript 规范
```typescript
// 显式类型定义,避免 any
interface DomainConfig {
id: string;
name: string;
authType: "password" | "api_token"; // 使用字面量联合类型
}
// 异步函数返回 Promise
async function fetchDomains(): Promise<Domain[]> {}
// 使用类型守卫处理 unknown
function parseResponse(data: unknown): DomainConfig {
if (typeof data !== "object" || data === null) {
throw new Error("Invalid response");
}
return data as DomainConfig;
}
```
### React 组件规范
```typescript
interface DomainListProps {
domains: Domain[]
onSelect: (domain: Domain) => void
}
function DomainList({ domains, onSelect }: DomainListProps) {
const [selectedId, setSelectedId] = useState<string | null>(null)
// Hooks 放在组件顶部
// 事件处理函数使用 useCallback
const handleClick = useCallback((domain: Domain) => {
setSelectedId(domain.id)
onSelect(domain)
}, [onSelect])
return <div>...</div>
}
export default DomainList
```
### Zustand Store 规范
```typescript
import { create } from "zustand";
import { persist } from "zustand/middleware";
interface DomainState {
domains: Domain[];
addDomain: (domain: Domain) => void;
}
export const useDomainStore = create<DomainState>()(
persist(
(set) => ({
domains: [],
addDomain: (domain) =>
set((state) => ({
domains: [...state.domains, domain],
})),
}),
{ name: "domain-storage" },
),
);
```
## 5. IPC 通信规范
### Result 模式(所有 IPC 返回)
```typescript
type Result<T> = { success: true; data: T } | { success: false; error: string };
```
### Preload 暴露 API
```typescript
const api = {
// 双向通信使用 invoke
fetchDomains: () => ipcRenderer.invoke("fetch-domains"),
// 单向通信使用 send
notify: (message: string) => ipcRenderer.send("notify", message),
};
contextBridge.exposeInMainWorld("api", api);
```
### 类型定义
```typescript
// preload/index.d.ts
declare global {
interface Window {
api: ElectronAPI;
}
}
```
## 6. UI 组件规范
使用 **Ant Design 6** + **antd-style**(不用 Tailwind
```typescript
import { createStyles } from 'antd-style'
const useStyles = createStyles(({ token, css }) => ({
container: css`
padding: ${token.paddingLG}px;
background: ${token.colorBgContainer};
border-radius: ${token.borderRadiusLG}px;
`
}))
function MyComponent() {
const { styles } = useStyles()
return <div className={styles.container}>...</div>
}
```
国际化:使用中文默认 `import zhCN from 'antd/locale/zh_CN'`
## 7. 安全规范
### 密码存储
```typescript
import { safeStorage } from "electron";
// 加密
const encrypted = safeStorage.encryptString(password);
// 解密
const decrypted = safeStorage.decryptString(encrypted);
```
### WebPreferences
必须启用:`contextIsolation: true`, `nodeIntegration: false`, `sandbox: false`
## 8. 错误处理
```typescript
// 主进程 IPC
ipcMain.handle("fetch-domains", async () => {
try {
const domains = await fetchDomainsFromApi();
return { success: true, data: domains };
} catch (error) {
return {
success: false,
error: error instanceof Error ? error.message : "Unknown error",
};
}
});
// 渲染进程调用
const result = await window.api.fetchDomains();
if (!result.success) {
message.error(result.error);
}
```
## 9. fnm 环境配置
所有 npm/npx 命令需加载 fnm 环境:
```bash
eval "$(fnm env --use-on-cd)" && npm run dev
```
## 10. 注意事项
1. **ESM Only**: LobeHub UI 仅支持 ESM
2. **React 19**: 使用 `@types/react@^19.0.0`
3. **CSS 方案**: 使用 `antd-style`,禁止 Tailwind
4. **禁止 `as any`**: 使用类型守卫或 `unknown`
5. **函数组件优先**: 禁止 class 组件
## 11. MVP Phase - Breaking Changes
**This is MVP phase - breaking changes are acceptable for better design.** However, you MUST:
- **Explain what will break and why**: Document which components/APIs/workflows will be affected
- **Compare old vs new approach**: Show the differences and improvements
- **Document the tradeoffs**: What are the pros and cons of this change
- **Ask for confirmation**: If the change is significant (affects multiple modules or core architecture)
**Examples of acceptable breaking changes during MVP**:
- Refactoring data structures for better type safety
- Changing IPC communication patterns
- Restructuring component hierarchy
- Modifying store architecture
- Updating API interfaces
**Process for breaking changes**:
1. Identify the change and its impact scope
2. Document the breaking change in code comments
3. Explain the reasoning and benefits
4. If significant, ask user for confirmation before implementing
5. Update related documentation after implementation