{"owner":"kuaifan","repo":"dootask","hasSkills":true,"totalSkillsCount":5,"totalTokensCount":5236,"categories":["claude-rule","root-instruction","mcp-config","marketplace","plugin-manifest"],"hasMcp":true,"mcpConfig":{"mcpServers":{"dootask":{"command":"npx","args":["-y","@modelcontextprotocol/server-dootask"]}}},"found":["CLAUDE.md","AGENTS.md",".cursor/mcp.json",".claude-plugin/marketplace.json",".claude-plugin/plugin.json"],"skills":{"CLAUDE.md":"## 项目概述\n\nLaravel 13 (LaravelS/Swoole, PHP 8.4) + Vue 2 (Vite) + Electron。开源任务/项目管理系统。\n\n## 开发命令\n\n所有命令通过 `./cmd` 脚本执行（不要直接运行 `php artisan` 等）：\n\n- `./cmd artisan ...` / `./cmd composer ...` / `./cmd php ...` — PHP 相关命令\n\n### AI 不要主动执行的命令\n\n以下命令仅由用户人工触发，AI 不要主动跑——包括\"任务完成后 sanity check\"、\"看下能不能编译\"等场景：\n\n- `./cmd dev` — 用户已自行运行 dev server，改完会自己 reload；AI 再跑会争抢进程\n- `./cmd prod` / `./cmd build` — 发版才用，走 `/release` 流程\n\n前端代码改动只做 Edit/Write，不要为了\"验证\"启动 dev server。用户明确说\"跑一下 / 出包\"时除外。\n\n### 质量门禁（改完代码必须自查，CI 同步在跑，见 .github/workflows/tests.yml）\n\n- `./cmd composer stan` — phpstan（level 1 + baseline，存量已封存，新增错误必须清零）\n- `npm run lint` — ESLint（error 必须为 0；warn 是存量遗留，见 eslint.config.mjs 注释）\n- `npm run check:lang` — 校验前端 `$L()` 字面量是否已登记到 `language/original-web.txt`\n- 改动控制器 public 方法或路由后跑 `./cmd artisan doc:api-map` 重新生成对照表\n\n## 代码检索地图（先查表，再 grep）\n\n- API URL ↔ 控制器方法对照：`routes/api-map.md`（生成式文件，勿手改）\n- 前端事件总线（mitt）收发对照：`docs/events-map.md`（`npm run events:map` 重新生成）\n- `$A` / `$L` 全局工具类型声明：`types/dootask-globals.d.ts`（新增 `$A` 方法须同步此文件）\n\n## 架构增量规则（只约束新增代码，存量\"动到哪迁到哪\"）\n\n- **巨型文件冻结**：不再往 `ProjectController`、`UsersController`、`DialogController`、`app/Module/Base.php`、`resources/assets/js/store/actions.js` 新增方法/函数；新功能领域开新控制器或新模块文件（动态路由天然支持多控制器）\n- **业务编排归层**：跨模型的业务流程写在 `app/Module/`（或 `app/Services/`），模型只保留数据访问与自身状态变更；Swoole Task 只做投递与调用，不直接编排业务\n- **配置读取**：业务代码禁止直接 `env()`，统一走 `config()`（项目自有配置集中在 `config/dootask.php`）\n\n## Gotchas\n\n### LaravelS/Swoole\n\n- **避免在静态属性、单例、全局变量中存储请求级状态**——请求间共享进程，会导致数据串联和内存泄漏\n  - 要存请求级状态，用 `RequestContext::save('key', $value)` / `RequestContext::get('key')`（参考 `User::authInfo()` 的用法，见 `app/Services/RequestContext.php`）\n- 构造函数、服务提供者、`boot()` 方法不会在每个请求重新执行\n- 配置/路由变更需要 `./cmd php restart` 或容器重启才能生效\n- 长生命周期逻辑（WebSocket、定时器）应复用现有模式，避免阻塞协程/事件循环\n\n### 后端\n\n- **非 REST 路由**：API 控制器（继承 `InvokeController`）在 `routes/web.php` 按资源注册路由，URL 段映射为控制器方法（如 `api/project/lists` → `lists()`，带 action 则用双下划线：`api/project/invite/join` → `invite__join()`）\n  - 路由最多两段：方法名最多一个双下划线（`method__action`），不支持 `method__action__xxx`（无对应路由，访问 404）\n- **响应格式**：统一使用 `Base::retSuccess($msg, $data)` / `Base::retError($msg)`，返回 `{\"ret\": 1, \"msg\": \"...\", \"data\": {...}}`——不要用 `response()->json()`\n- 业务异常通过 `App\\Exceptions\\ApiException` 抛出，不要用通用 Exception\n- 模型继承 `AbstractModel`，使用 `Model::createInstance($params)` 创建——不要用 `new Model()` 或 `Model::create()`\n- 认证使用 `Doo::userId()`——不要用 `auth()->user()`\n- 参数校验在控制器方法中手动进行——不要创建 FormRequest 类\n- 异步任务使用 Swoole Task（`app/Tasks/`）——不要用 Laravel Queue\n- `app/Module/` 存放跨控制器/跨模型的业务逻辑（非标准 Laravel 目录）\n- 所有表结构变更必须通过 Laravel migration，禁止直接改库\n\n### 前端\n\n- API 调用使用 `store.dispatch(\"call\", params)`，不要在组件中直接 axios/fetch\n- `$A.modalXXX`、`$A.messageXXX`、`$A.noticeXXX` 内部自动处理 `$L` 翻译，调用方不要额外包 `$L`。仅当传入 `language: false` 时由调用方自行处理翻译\n\n### 国际化\n\n- 新增用户可见文本须追加原文（简体中文）到：前端 `language/original-web.txt`，后端 `language/original-api.txt`（去重）\n- 前端翻译用 `$L(\"文本\")`，动态值用 `(*)` 占位：`$L('共(*)条', n)`——禁止拼接翻译\n- 单字或短词因上下文不同可能产生歧义时，使用 `[lower_snake_case].原文` 上下文键，例如 `$L('[weekday].一')`、`$L('[task_unit].个')`；前缀只参与翻译查找，界面仍显示原文。此类键须完整登记到 `original-web.txt`，且 `translate.json` 的 `zh` 必须填写去除前缀后的原文；普通键的 `zh` 仍留空\n\n## ai-kb 同步规则\n\n`resources/ai-kb/` 是产品内 AI 助手 RAG 检索的功能知识库（目录结构、写作规范、索引机制见其 `README.md` 与 `_schema/`）。\n\n- **同步时机**：改动用户可见的功能/菜单/按钮/流程/字段、API 行为（错误码、参数含义、返回结构）、插件/微应用、权限/角色定义时，必须在同一次提交中同步更新 ai-kb，不要把 ai-kb 改动单独拆成一个提交\n- **怎么改**：在 `_meta/feature-map.yaml` 找到对应 feature 的 chunk 清单，按 `_schema/chunk-style.md` 与 `_schema/frontmatter.md` 修改或新建 chunk，并把 frontmatter 的 `last_verified` 更新为当前主程序版本号\n- **改完即止**：无需触发任何索引操作，插件容器启动时会自动对账收敛\n\n## Playwright 测试\n\n- Playwright 测试结果放在 `tests/playwright-results/`，包含测试环境、测试用例、结果截图等信息\n\n## 交互规范\n\n- **提问时附带建议**：当需要向用户提问或请求澄清时，应同时提供具体的建议选项或推荐方案，帮助用户快速决策，而非仅抛出开放式问题\n\n## 语言偏好\n\n- 回复一律使用简体中文，除非用户明确要求其他语言\n","AGENTS.md":"## 项目概述\n\nLaravel 13 (LaravelS/Swoole, PHP 8.4) + Vue 2 (Vite) + Electron。开源任务/项目管理系统。\n\n## 开发命令\n\n所有命令通过 `./cmd` 脚本执行（不要直接运行 `php artisan` 等）：\n\n- `./cmd artisan ...` / `./cmd composer ...` / `./cmd php ...` — PHP 相关命令\n\n### AI 不要主动执行的命令\n\n以下命令仅由用户人工触发，AI 不要主动跑——包括\"任务完成后 sanity check\"、\"看下能不能编译\"等场景：\n\n- `./cmd dev` — 用户已自行运行 dev server，改完会自己 reload；AI 再跑会争抢进程\n- `./cmd prod` / `./cmd build` — 发版才用，走 `/release` 流程\n\n前端代码改动只做 Edit/Write，不要为了\"验证\"启动 dev server。用户明确说\"跑一下 / 出包\"时除外。\n\n### 质量门禁（改完代码必须自查，CI 同步在跑，见 .github/workflows/tests.yml）\n\n- `./cmd composer stan` — phpstan（level 1 + baseline，存量已封存，新增错误必须清零）\n- `npm run lint` — ESLint（error 必须为 0；warn 是存量遗留，见 eslint.config.mjs 注释）\n- `npm run check:lang` — 校验前端 `$L()` 字面量是否已登记到 `language/original-web.txt`\n- 改动控制器 public 方法或路由后跑 `./cmd artisan doc:api-map` 重新生成对照表\n\n## 代码检索地图（先查表，再 grep）\n\n- API URL ↔ 控制器方法对照：`routes/api-map.md`（生成式文件，勿手改）\n- 前端事件总线（mitt）收发对照：`docs/events-map.md`（`npm run events:map` 重新生成）\n- `$A` / `$L` 全局工具类型声明：`types/dootask-globals.d.ts`（新增 `$A` 方法须同步此文件）\n\n## 架构增量规则（只约束新增代码，存量\"动到哪迁到哪\"）\n\n- **巨型文件冻结**：不再往 `ProjectController`、`UsersController`、`DialogController`、`app/Module/Base.php`、`resources/assets/js/store/actions.js` 新增方法/函数；新功能领域开新控制器或新模块文件（动态路由天然支持多控制器）\n- **业务编排归层**：跨模型的业务流程写在 `app/Module/`（或 `app/Services/`），模型只保留数据访问与自身状态变更；Swoole Task 只做投递与调用，不直接编排业务\n- **配置读取**：业务代码禁止直接 `env()`，统一走 `config()`（项目自有配置集中在 `config/dootask.php`）\n\n## Gotchas\n\n### LaravelS/Swoole\n\n- **避免在静态属性、单例、全局变量中存储请求级状态**——请求间共享进程，会导致数据串联和内存泄漏\n  - 要存请求级状态，用 `RequestContext::save('key', $value)` / `RequestContext::get('key')`（参考 `User::authInfo()` 的用法，见 `app/Services/RequestContext.php`）\n- 构造函数、服务提供者、`boot()` 方法不会在每个请求重新执行\n- 配置/路由变更需要 `./cmd php restart` 或容器重启才能生效\n- 长生命周期逻辑（WebSocket、定时器）应复用现有模式，避免阻塞协程/事件循环\n\n### 后端\n\n- **非 REST 路由**：API 控制器（继承 `InvokeController`）在 `routes/web.php` 按资源注册路由，URL 段映射为控制器方法（如 `api/project/lists` → `lists()`，带 action 则用双下划线：`api/project/invite/join` → `invite__join()`）\n  - 路由最多两段：方法名最多一个双下划线（`method__action`），不支持 `method__action__xxx`（无对应路由，访问 404）\n- **响应格式**：统一使用 `Base::retSuccess($msg, $data)` / `Base::retError($msg)`，返回 `{\"ret\": 1, \"msg\": \"...\", \"data\": {...}}`——不要用 `response()->json()`\n- 业务异常通过 `App\\Exceptions\\ApiException` 抛出，不要用通用 Exception\n- 模型继承 `AbstractModel`，使用 `Model::createInstance($params)` 创建——不要用 `new Model()` 或 `Model::create()`\n- 认证使用 `Doo::userId()`——不要用 `auth()->user()`\n- 参数校验在控制器方法中手动进行——不要创建 FormRequest 类\n- 异步任务使用 Swoole Task（`app/Tasks/`）——不要用 Laravel Queue\n- `app/Module/` 存放跨控制器/跨模型的业务逻辑（非标准 Laravel 目录）\n- 所有表结构变更必须通过 Laravel migration，禁止直接改库\n\n### 前端\n\n- API 调用使用 `store.dispatch(\"call\", params)`，不要在组件中直接 axios/fetch\n- `$A.modalXXX`、`$A.messageXXX`、`$A.noticeXXX` 内部自动处理 `$L` 翻译，调用方不要额外包 `$L`。仅当传入 `language: false` 时由调用方自行处理翻译\n\n### 国际化\n\n- 新增用户可见文本须追加原文（简体中文）到：前端 `language/original-web.txt`，后端 `language/original-api.txt`（去重）\n- 前端翻译用 `$L(\"文本\")`，动态值用 `(*)` 占位：`$L('共(*)条', n)`——禁止拼接翻译\n- 单字或短词因上下文不同可能产生歧义时，使用 `[lower_snake_case].原文` 上下文键，例如 `$L('[weekday].一')`、`$L('[task_unit].个')`；前缀只参与翻译查找，界面仍显示原文。此类键须完整登记到 `original-web.txt`，且 `translate.json` 的 `zh` 必须填写去除前缀后的原文；普通键的 `zh` 仍留空\n\n## ai-kb 同步规则\n\n`resources/ai-kb/` 是产品内 AI 助手 RAG 检索的功能知识库（目录结构、写作规范、索引机制见其 `README.md` 与 `_schema/`）。\n\n- **同步时机**：改动用户可见的功能/菜单/按钮/流程/字段、API 行为（错误码、参数含义、返回结构）、插件/微应用、权限/角色定义时，必须在同一次提交中同步更新 ai-kb，不要把 ai-kb 改动单独拆成一个提交\n- **怎么改**：在 `_meta/feature-map.yaml` 找到对应 feature 的 chunk 清单，按 `_schema/chunk-style.md` 与 `_schema/frontmatter.md` 修改或新建 chunk，并把 frontmatter 的 `last_verified` 更新为当前主程序版本号\n- **改完即止**：无需触发任何索引操作，插件容器启动时会自动对账收敛\n\n## Playwright 测试\n\n- Playwright 测试结果放在 `tests/playwright-results/`，包含测试环境、测试用例、结果截图等信息\n\n## 交互规范\n\n- **提问时附带建议**：当需要向用户提问或请求澄清时，应同时提供具体的建议选项或推荐方案，帮助用户快速决策，而非仅抛出开放式问题\n\n## 语言偏好\n\n- 回复一律使用简体中文，除非用户明确要求其他语言\n",".cursor/mcp.json":"# Model Context Protocol (MCP) Configuration\n\nPath: `.cursor/mcp.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/kuaifan/dootask/HEAD/.cursor/mcp.json)",".claude-plugin/marketplace.json":"# Claude Plugin Marketplace Catalog\n\nPath: `.claude-plugin/marketplace.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/kuaifan/dootask/HEAD/.claude-plugin/marketplace.json)",".claude-plugin/plugin.json":"# claude-plugin Plugin Manifest\n\nPath: `.claude-plugin/plugin.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/kuaifan/dootask/HEAD/.claude-plugin/plugin.json)"},"files":{"CLAUDE.md":"## 项目概述\n\nLaravel 13 (LaravelS/Swoole, PHP 8.4) + Vue 2 (Vite) + Electron。开源任务/项目管理系统。\n\n## 开发命令\n\n所有命令通过 `./cmd` 脚本执行（不要直接运行 `php artisan` 等）：\n\n- `./cmd artisan ...` / `./cmd composer ...` / `./cmd php ...` — PHP 相关命令\n\n### AI 不要主动执行的命令\n\n以下命令仅由用户人工触发，AI 不要主动跑——包括\"任务完成后 sanity check\"、\"看下能不能编译\"等场景：\n\n- `./cmd dev` — 用户已自行运行 dev server，改完会自己 reload；AI 再跑会争抢进程\n- `./cmd prod` / `./cmd build` — 发版才用，走 `/release` 流程\n\n前端代码改动只做 Edit/Write，不要为了\"验证\"启动 dev server。用户明确说\"跑一下 / 出包\"时除外。\n\n### 质量门禁（改完代码必须自查，CI 同步在跑，见 .github/workflows/tests.yml）\n\n- `./cmd composer stan` — phpstan（level 1 + baseline，存量已封存，新增错误必须清零）\n- `npm run lint` — ESLint（error 必须为 0；warn 是存量遗留，见 eslint.config.mjs 注释）\n- `npm run check:lang` — 校验前端 `$L()` 字面量是否已登记到 `language/original-web.txt`\n- 改动控制器 public 方法或路由后跑 `./cmd artisan doc:api-map` 重新生成对照表\n\n## 代码检索地图（先查表，再 grep）\n\n- API URL ↔ 控制器方法对照：`routes/api-map.md`（生成式文件，勿手改）\n- 前端事件总线（mitt）收发对照：`docs/events-map.md`（`npm run events:map` 重新生成）\n- `$A` / `$L` 全局工具类型声明：`types/dootask-globals.d.ts`（新增 `$A` 方法须同步此文件）\n\n## 架构增量规则（只约束新增代码，存量\"动到哪迁到哪\"）\n\n- **巨型文件冻结**：不再往 `ProjectController`、`UsersController`、`DialogController`、`app/Module/Base.php`、`resources/assets/js/store/actions.js` 新增方法/函数；新功能领域开新控制器或新模块文件（动态路由天然支持多控制器）\n- **业务编排归层**：跨模型的业务流程写在 `app/Module/`（或 `app/Services/`），模型只保留数据访问与自身状态变更；Swoole Task 只做投递与调用，不直接编排业务\n- **配置读取**：业务代码禁止直接 `env()`，统一走 `config()`（项目自有配置集中在 `config/dootask.php`）\n\n## Gotchas\n\n### LaravelS/Swoole\n\n- **避免在静态属性、单例、全局变量中存储请求级状态**——请求间共享进程，会导致数据串联和内存泄漏\n  - 要存请求级状态，用 `RequestContext::save('key', $value)` / `RequestContext::get('key')`（参考 `User::authInfo()` 的用法，见 `app/Services/RequestContext.php`）\n- 构造函数、服务提供者、`boot()` 方法不会在每个请求重新执行\n- 配置/路由变更需要 `./cmd php restart` 或容器重启才能生效\n- 长生命周期逻辑（WebSocket、定时器）应复用现有模式，避免阻塞协程/事件循环\n\n### 后端\n\n- **非 REST 路由**：API 控制器（继承 `InvokeController`）在 `routes/web.php` 按资源注册路由，URL 段映射为控制器方法（如 `api/project/lists` → `lists()`，带 action 则用双下划线：`api/project/invite/join` → `invite__join()`）\n  - 路由最多两段：方法名最多一个双下划线（`method__action`），不支持 `method__action__xxx`（无对应路由，访问 404）\n- **响应格式**：统一使用 `Base::retSuccess($msg, $data)` / `Base::retError($msg)`，返回 `{\"ret\": 1, \"msg\": \"...\", \"data\": {...}}`——不要用 `response()->json()`\n- 业务异常通过 `App\\Exceptions\\ApiException` 抛出，不要用通用 Exception\n- 模型继承 `AbstractModel`，使用 `Model::createInstance($params)` 创建——不要用 `new Model()` 或 `Model::create()`\n- 认证使用 `Doo::userId()`——不要用 `auth()->user()`\n- 参数校验在控制器方法中手动进行——不要创建 FormRequest 类\n- 异步任务使用 Swoole Task（`app/Tasks/`）——不要用 Laravel Queue\n- `app/Module/` 存放跨控制器/跨模型的业务逻辑（非标准 Laravel 目录）\n- 所有表结构变更必须通过 Laravel migration，禁止直接改库\n\n### 前端\n\n- API 调用使用 `store.dispatch(\"call\", params)`，不要在组件中直接 axios/fetch\n- `$A.modalXXX`、`$A.messageXXX`、`$A.noticeXXX` 内部自动处理 `$L` 翻译，调用方不要额外包 `$L`。仅当传入 `language: false` 时由调用方自行处理翻译\n\n### 国际化\n\n- 新增用户可见文本须追加原文（简体中文）到：前端 `language/original-web.txt`，后端 `language/original-api.txt`（去重）\n- 前端翻译用 `$L(\"文本\")`，动态值用 `(*)` 占位：`$L('共(*)条', n)`——禁止拼接翻译\n- 单字或短词因上下文不同可能产生歧义时，使用 `[lower_snake_case].原文` 上下文键，例如 `$L('[weekday].一')`、`$L('[task_unit].个')`；前缀只参与翻译查找，界面仍显示原文。此类键须完整登记到 `original-web.txt`，且 `translate.json` 的 `zh` 必须填写去除前缀后的原文；普通键的 `zh` 仍留空\n\n## ai-kb 同步规则\n\n`resources/ai-kb/` 是产品内 AI 助手 RAG 检索的功能知识库（目录结构、写作规范、索引机制见其 `README.md` 与 `_schema/`）。\n\n- **同步时机**：改动用户可见的功能/菜单/按钮/流程/字段、API 行为（错误码、参数含义、返回结构）、插件/微应用、权限/角色定义时，必须在同一次提交中同步更新 ai-kb，不要把 ai-kb 改动单独拆成一个提交\n- **怎么改**：在 `_meta/feature-map.yaml` 找到对应 feature 的 chunk 清单，按 `_schema/chunk-style.md` 与 `_schema/frontmatter.md` 修改或新建 chunk，并把 frontmatter 的 `last_verified` 更新为当前主程序版本号\n- **改完即止**：无需触发任何索引操作，插件容器启动时会自动对账收敛\n\n## Playwright 测试\n\n- Playwright 测试结果放在 `tests/playwright-results/`，包含测试环境、测试用例、结果截图等信息\n\n## 交互规范\n\n- **提问时附带建议**：当需要向用户提问或请求澄清时，应同时提供具体的建议选项或推荐方案，帮助用户快速决策，而非仅抛出开放式问题\n\n## 语言偏好\n\n- 回复一律使用简体中文，除非用户明确要求其他语言\n","AGENTS.md":"## 项目概述\n\nLaravel 13 (LaravelS/Swoole, PHP 8.4) + Vue 2 (Vite) + Electron。开源任务/项目管理系统。\n\n## 开发命令\n\n所有命令通过 `./cmd` 脚本执行（不要直接运行 `php artisan` 等）：\n\n- `./cmd artisan ...` / `./cmd composer ...` / `./cmd php ...` — PHP 相关命令\n\n### AI 不要主动执行的命令\n\n以下命令仅由用户人工触发，AI 不要主动跑——包括\"任务完成后 sanity check\"、\"看下能不能编译\"等场景：\n\n- `./cmd dev` — 用户已自行运行 dev server，改完会自己 reload；AI 再跑会争抢进程\n- `./cmd prod` / `./cmd build` — 发版才用，走 `/release` 流程\n\n前端代码改动只做 Edit/Write，不要为了\"验证\"启动 dev server。用户明确说\"跑一下 / 出包\"时除外。\n\n### 质量门禁（改完代码必须自查，CI 同步在跑，见 .github/workflows/tests.yml）\n\n- `./cmd composer stan` — phpstan（level 1 + baseline，存量已封存，新增错误必须清零）\n- `npm run lint` — ESLint（error 必须为 0；warn 是存量遗留，见 eslint.config.mjs 注释）\n- `npm run check:lang` — 校验前端 `$L()` 字面量是否已登记到 `language/original-web.txt`\n- 改动控制器 public 方法或路由后跑 `./cmd artisan doc:api-map` 重新生成对照表\n\n## 代码检索地图（先查表，再 grep）\n\n- API URL ↔ 控制器方法对照：`routes/api-map.md`（生成式文件，勿手改）\n- 前端事件总线（mitt）收发对照：`docs/events-map.md`（`npm run events:map` 重新生成）\n- `$A` / `$L` 全局工具类型声明：`types/dootask-globals.d.ts`（新增 `$A` 方法须同步此文件）\n\n## 架构增量规则（只约束新增代码，存量\"动到哪迁到哪\"）\n\n- **巨型文件冻结**：不再往 `ProjectController`、`UsersController`、`DialogController`、`app/Module/Base.php`、`resources/assets/js/store/actions.js` 新增方法/函数；新功能领域开新控制器或新模块文件（动态路由天然支持多控制器）\n- **业务编排归层**：跨模型的业务流程写在 `app/Module/`（或 `app/Services/`），模型只保留数据访问与自身状态变更；Swoole Task 只做投递与调用，不直接编排业务\n- **配置读取**：业务代码禁止直接 `env()`，统一走 `config()`（项目自有配置集中在 `config/dootask.php`）\n\n## Gotchas\n\n### LaravelS/Swoole\n\n- **避免在静态属性、单例、全局变量中存储请求级状态**——请求间共享进程，会导致数据串联和内存泄漏\n  - 要存请求级状态，用 `RequestContext::save('key', $value)` / `RequestContext::get('key')`（参考 `User::authInfo()` 的用法，见 `app/Services/RequestContext.php`）\n- 构造函数、服务提供者、`boot()` 方法不会在每个请求重新执行\n- 配置/路由变更需要 `./cmd php restart` 或容器重启才能生效\n- 长生命周期逻辑（WebSocket、定时器）应复用现有模式，避免阻塞协程/事件循环\n\n### 后端\n\n- **非 REST 路由**：API 控制器（继承 `InvokeController`）在 `routes/web.php` 按资源注册路由，URL 段映射为控制器方法（如 `api/project/lists` → `lists()`，带 action 则用双下划线：`api/project/invite/join` → `invite__join()`）\n  - 路由最多两段：方法名最多一个双下划线（`method__action`），不支持 `method__action__xxx`（无对应路由，访问 404）\n- **响应格式**：统一使用 `Base::retSuccess($msg, $data)` / `Base::retError($msg)`，返回 `{\"ret\": 1, \"msg\": \"...\", \"data\": {...}}`——不要用 `response()->json()`\n- 业务异常通过 `App\\Exceptions\\ApiException` 抛出，不要用通用 Exception\n- 模型继承 `AbstractModel`，使用 `Model::createInstance($params)` 创建——不要用 `new Model()` 或 `Model::create()`\n- 认证使用 `Doo::userId()`——不要用 `auth()->user()`\n- 参数校验在控制器方法中手动进行——不要创建 FormRequest 类\n- 异步任务使用 Swoole Task（`app/Tasks/`）——不要用 Laravel Queue\n- `app/Module/` 存放跨控制器/跨模型的业务逻辑（非标准 Laravel 目录）\n- 所有表结构变更必须通过 Laravel migration，禁止直接改库\n\n### 前端\n\n- API 调用使用 `store.dispatch(\"call\", params)`，不要在组件中直接 axios/fetch\n- `$A.modalXXX`、`$A.messageXXX`、`$A.noticeXXX` 内部自动处理 `$L` 翻译，调用方不要额外包 `$L`。仅当传入 `language: false` 时由调用方自行处理翻译\n\n### 国际化\n\n- 新增用户可见文本须追加原文（简体中文）到：前端 `language/original-web.txt`，后端 `language/original-api.txt`（去重）\n- 前端翻译用 `$L(\"文本\")`，动态值用 `(*)` 占位：`$L('共(*)条', n)`——禁止拼接翻译\n- 单字或短词因上下文不同可能产生歧义时，使用 `[lower_snake_case].原文` 上下文键，例如 `$L('[weekday].一')`、`$L('[task_unit].个')`；前缀只参与翻译查找，界面仍显示原文。此类键须完整登记到 `original-web.txt`，且 `translate.json` 的 `zh` 必须填写去除前缀后的原文；普通键的 `zh` 仍留空\n\n## ai-kb 同步规则\n\n`resources/ai-kb/` 是产品内 AI 助手 RAG 检索的功能知识库（目录结构、写作规范、索引机制见其 `README.md` 与 `_schema/`）。\n\n- **同步时机**：改动用户可见的功能/菜单/按钮/流程/字段、API 行为（错误码、参数含义、返回结构）、插件/微应用、权限/角色定义时，必须在同一次提交中同步更新 ai-kb，不要把 ai-kb 改动单独拆成一个提交\n- **怎么改**：在 `_meta/feature-map.yaml` 找到对应 feature 的 chunk 清单，按 `_schema/chunk-style.md` 与 `_schema/frontmatter.md` 修改或新建 chunk，并把 frontmatter 的 `last_verified` 更新为当前主程序版本号\n- **改完即止**：无需触发任何索引操作，插件容器启动时会自动对账收敛\n\n## Playwright 测试\n\n- Playwright 测试结果放在 `tests/playwright-results/`，包含测试环境、测试用例、结果截图等信息\n\n## 交互规范\n\n- **提问时附带建议**：当需要向用户提问或请求澄清时，应同时提供具体的建议选项或推荐方案，帮助用户快速决策，而非仅抛出开放式问题\n\n## 语言偏好\n\n- 回复一律使用简体中文，除非用户明确要求其他语言\n",".cursor/mcp.json":"# Model Context Protocol (MCP) Configuration\n\nPath: `.cursor/mcp.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/kuaifan/dootask/HEAD/.cursor/mcp.json)",".claude-plugin/marketplace.json":"# Claude Plugin Marketplace Catalog\n\nPath: `.claude-plugin/marketplace.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/kuaifan/dootask/HEAD/.claude-plugin/marketplace.json)",".claude-plugin/plugin.json":"# claude-plugin Plugin Manifest\n\nPath: `.claude-plugin/plugin.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/kuaifan/dootask/HEAD/.claude-plugin/plugin.json)"},"items":[{"name":"AGENTS.md","path":"AGENTS.md","rawUrl":"https://raw.githubusercontent.com/kuaifan/dootask/HEAD/AGENTS.md","title":"AI Agent Protocol & Instructions","category":"root-instruction","format":"markdown","content":"## 项目概述\n\nLaravel 13 (LaravelS/Swoole, PHP 8.4) + Vue 2 (Vite) + Electron。开源任务/项目管理系统。\n\n## 开发命令\n\n所有命令通过 `./cmd` 脚本执行（不要直接运行 `php artisan` 等）：\n\n- `./cmd artisan ...` / `./cmd composer ...` / `./cmd php ...` — PHP 相关命令\n\n### AI 不要主动执行的命令\n\n以下命令仅由用户人工触发，AI 不要主动跑——包括\"任务完成后 sanity check\"、\"看下能不能编译\"等场景：\n\n- `./cmd dev` — 用户已自行运行 dev server，改完会自己 reload；AI 再跑会争抢进程\n- `./cmd prod` / `./cmd build` — 发版才用，走 `/release` 流程\n\n前端代码改动只做 Edit/Write，不要为了\"验证\"启动 dev server。用户明确说\"跑一下 / 出包\"时除外。\n\n### 质量门禁（改完代码必须自查，CI 同步在跑，见 .github/workflows/tests.yml）\n\n- `./cmd composer stan` — phpstan（level 1 + baseline，存量已封存，新增错误必须清零）\n- `npm run lint` — ESLint（error 必须为 0；warn 是存量遗留，见 eslint.config.mjs 注释）\n- `npm run check:lang` — 校验前端 `$L()` 字面量是否已登记到 `language/original-web.txt`\n- 改动控制器 public 方法或路由后跑 `./cmd artisan doc:api-map` 重新生成对照表\n\n## 代码检索地图（先查表，再 grep）\n\n- API URL ↔ 控制器方法对照：`routes/api-map.md`（生成式文件，勿手改）\n- 前端事件总线（mitt）收发对照：`docs/events-map.md`（`npm run events:map` 重新生成）\n- `$A` / `$L` 全局工具类型声明：`types/dootask-globals.d.ts`（新增 `$A` 方法须同步此文件）\n\n## 架构增量规则（只约束新增代码，存量\"动到哪迁到哪\"）\n\n- **巨型文件冻结**：不再往 `ProjectController`、`UsersController`、`DialogController`、`app/Module/Base.php`、`resources/assets/js/store/actions.js` 新增方法/函数；新功能领域开新控制器或新模块文件（动态路由天然支持多控制器）\n- **业务编排归层**：跨模型的业务流程写在 `app/Module/`（或 `app/Services/`），模型只保留数据访问与自身状态变更；Swoole Task 只做投递与调用，不直接编排业务\n- **配置读取**：业务代码禁止直接 `env()`，统一走 `config()`（项目自有配置集中在 `config/dootask.php`）\n\n## Gotchas\n\n### LaravelS/Swoole\n\n- **避免在静态属性、单例、全局变量中存储请求级状态**——请求间共享进程，会导致数据串联和内存泄漏\n  - 要存请求级状态，用 `RequestContext::save('key', $value)` / `RequestContext::get('key')`（参考 `User::authInfo()` 的用法，见 `app/Services/RequestContext.php`）\n- 构造函数、服务提供者、`boot()` 方法不会在每个请求重新执行\n- 配置/路由变更需要 `./cmd php restart` 或容器重启才能生效\n- 长生命周期逻辑（WebSocket、定时器）应复用现有模式，避免阻塞协程/事件循环\n\n### 后端\n\n- **非 REST 路由**：API 控制器（继承 `InvokeController`）在 `routes/web.php` 按资源注册路由，URL 段映射为控制器方法（如 `api/project/lists` → `lists()`，带 action 则用双下划线：`api/project/invite/join` → `invite__join()`）\n  - 路由最多两段：方法名最多一个双下划线（`method__action`），不支持 `method__action__xxx`（无对应路由，访问 404）\n- **响应格式**：统一使用 `Base::retSuccess($msg, $data)` / `Base::retError($msg)`，返回 `{\"ret\": 1, \"msg\": \"...\", \"data\": {...}}`——不要用 `response()->json()`\n- 业务异常通过 `App\\Exceptions\\ApiException` 抛出，不要用通用 Exception\n- 模型继承 `AbstractModel`，使用 `Model::createInstance($params)` 创建——不要用 `new Model()` 或 `Model::create()`\n- 认证使用 `Doo::userId()`——不要用 `auth()->user()`\n- 参数校验在控制器方法中手动进行——不要创建 FormRequest 类\n- 异步任务使用 Swoole Task（`app/Tasks/`）——不要用 Laravel Queue\n- `app/Module/` 存放跨控制器/跨模型的业务逻辑（非标准 Laravel 目录）\n- 所有表结构变更必须通过 Laravel migration，禁止直接改库\n\n### 前端\n\n- API 调用使用 `store.dispatch(\"call\", params)`，不要在组件中直接 axios/fetch\n- `$A.modalXXX`、`$A.messageXXX`、`$A.noticeXXX` 内部自动处理 `$L` 翻译，调用方不要额外包 `$L`。仅当传入 `language: false` 时由调用方自行处理翻译\n\n### 国际化\n\n- 新增用户可见文本须追加原文（简体中文）到：前端 `language/original-web.txt`，后端 `language/original-api.txt`（去重）\n- 前端翻译用 `$L(\"文本\")`，动态值用 `(*)` 占位：`$L('共(*)条', n)`——禁止拼接翻译\n- 单字或短词因上下文不同可能产生歧义时，使用 `[lower_snake_case].原文` 上下文键，例如 `$L('[weekday].一')`、`$L('[task_unit].个')`；前缀只参与翻译查找，界面仍显示原文。此类键须完整登记到 `original-web.txt`，且 `translate.json` 的 `zh` 必须填写去除前缀后的原文；普通键的 `zh` 仍留空\n\n## ai-kb 同步规则\n\n`resources/ai-kb/` 是产品内 AI 助手 RAG 检索的功能知识库（目录结构、写作规范、索引机制见其 `README.md` 与 `_schema/`）。\n\n- **同步时机**：改动用户可见的功能/菜单/按钮/流程/字段、API 行为（错误码、参数含义、返回结构）、插件/微应用、权限/角色定义时，必须在同一次提交中同步更新 ai-kb，不要把 ai-kb 改动单独拆成一个提交\n- **怎么改**：在 `_meta/feature-map.yaml` 找到对应 feature 的 chunk 清单，按 `_schema/chunk-style.md` 与 `_schema/frontmatter.md` 修改或新建 chunk，并把 frontmatter 的 `last_verified` 更新为当前主程序版本号\n- **改完即止**：无需触发任何索引操作，插件容器启动时会自动对账收敛\n\n## Playwright 测试\n\n- Playwright 测试结果放在 `tests/playwright-results/`，包含测试环境、测试用例、结果截图等信息\n\n## 交互规范\n\n- **提问时附带建议**：当需要向用户提问或请求澄清时，应同时提供具体的建议选项或推荐方案，帮助用户快速决策，而非仅抛出开放式问题\n\n## 语言偏好\n\n- 回复一律使用简体中文，除非用户明确要求其他语言\n","isInternal":false,"tokens":2168,"sizeBytes":6345},{"name":"CLAUDE.md","path":"CLAUDE.md","rawUrl":"https://raw.githubusercontent.com/kuaifan/dootask/HEAD/CLAUDE.md","title":"Claude Agent Guidelines & System Prompt","category":"claude-rule","format":"markdown","content":"## 项目概述\n\nLaravel 13 (LaravelS/Swoole, PHP 8.4) + Vue 2 (Vite) + Electron。开源任务/项目管理系统。\n\n## 开发命令\n\n所有命令通过 `./cmd` 脚本执行（不要直接运行 `php artisan` 等）：\n\n- `./cmd artisan ...` / `./cmd composer ...` / `./cmd php ...` — PHP 相关命令\n\n### AI 不要主动执行的命令\n\n以下命令仅由用户人工触发，AI 不要主动跑——包括\"任务完成后 sanity check\"、\"看下能不能编译\"等场景：\n\n- `./cmd dev` — 用户已自行运行 dev server，改完会自己 reload；AI 再跑会争抢进程\n- `./cmd prod` / `./cmd build` — 发版才用，走 `/release` 流程\n\n前端代码改动只做 Edit/Write，不要为了\"验证\"启动 dev server。用户明确说\"跑一下 / 出包\"时除外。\n\n### 质量门禁（改完代码必须自查，CI 同步在跑，见 .github/workflows/tests.yml）\n\n- `./cmd composer stan` — phpstan（level 1 + baseline，存量已封存，新增错误必须清零）\n- `npm run lint` — ESLint（error 必须为 0；warn 是存量遗留，见 eslint.config.mjs 注释）\n- `npm run check:lang` — 校验前端 `$L()` 字面量是否已登记到 `language/original-web.txt`\n- 改动控制器 public 方法或路由后跑 `./cmd artisan doc:api-map` 重新生成对照表\n\n## 代码检索地图（先查表，再 grep）\n\n- API URL ↔ 控制器方法对照：`routes/api-map.md`（生成式文件，勿手改）\n- 前端事件总线（mitt）收发对照：`docs/events-map.md`（`npm run events:map` 重新生成）\n- `$A` / `$L` 全局工具类型声明：`types/dootask-globals.d.ts`（新增 `$A` 方法须同步此文件）\n\n## 架构增量规则（只约束新增代码，存量\"动到哪迁到哪\"）\n\n- **巨型文件冻结**：不再往 `ProjectController`、`UsersController`、`DialogController`、`app/Module/Base.php`、`resources/assets/js/store/actions.js` 新增方法/函数；新功能领域开新控制器或新模块文件（动态路由天然支持多控制器）\n- **业务编排归层**：跨模型的业务流程写在 `app/Module/`（或 `app/Services/`），模型只保留数据访问与自身状态变更；Swoole Task 只做投递与调用，不直接编排业务\n- **配置读取**：业务代码禁止直接 `env()`，统一走 `config()`（项目自有配置集中在 `config/dootask.php`）\n\n## Gotchas\n\n### LaravelS/Swoole\n\n- **避免在静态属性、单例、全局变量中存储请求级状态**——请求间共享进程，会导致数据串联和内存泄漏\n  - 要存请求级状态，用 `RequestContext::save('key', $value)` / `RequestContext::get('key')`（参考 `User::authInfo()` 的用法，见 `app/Services/RequestContext.php`）\n- 构造函数、服务提供者、`boot()` 方法不会在每个请求重新执行\n- 配置/路由变更需要 `./cmd php restart` 或容器重启才能生效\n- 长生命周期逻辑（WebSocket、定时器）应复用现有模式，避免阻塞协程/事件循环\n\n### 后端\n\n- **非 REST 路由**：API 控制器（继承 `InvokeController`）在 `routes/web.php` 按资源注册路由，URL 段映射为控制器方法（如 `api/project/lists` → `lists()`，带 action 则用双下划线：`api/project/invite/join` → `invite__join()`）\n  - 路由最多两段：方法名最多一个双下划线（`method__action`），不支持 `method__action__xxx`（无对应路由，访问 404）\n- **响应格式**：统一使用 `Base::retSuccess($msg, $data)` / `Base::retError($msg)`，返回 `{\"ret\": 1, \"msg\": \"...\", \"data\": {...}}`——不要用 `response()->json()`\n- 业务异常通过 `App\\Exceptions\\ApiException` 抛出，不要用通用 Exception\n- 模型继承 `AbstractModel`，使用 `Model::createInstance($params)` 创建——不要用 `new Model()` 或 `Model::create()`\n- 认证使用 `Doo::userId()`——不要用 `auth()->user()`\n- 参数校验在控制器方法中手动进行——不要创建 FormRequest 类\n- 异步任务使用 Swoole Task（`app/Tasks/`）——不要用 Laravel Queue\n- `app/Module/` 存放跨控制器/跨模型的业务逻辑（非标准 Laravel 目录）\n- 所有表结构变更必须通过 Laravel migration，禁止直接改库\n\n### 前端\n\n- API 调用使用 `store.dispatch(\"call\", params)`，不要在组件中直接 axios/fetch\n- `$A.modalXXX`、`$A.messageXXX`、`$A.noticeXXX` 内部自动处理 `$L` 翻译，调用方不要额外包 `$L`。仅当传入 `language: false` 时由调用方自行处理翻译\n\n### 国际化\n\n- 新增用户可见文本须追加原文（简体中文）到：前端 `language/original-web.txt`，后端 `language/original-api.txt`（去重）\n- 前端翻译用 `$L(\"文本\")`，动态值用 `(*)` 占位：`$L('共(*)条', n)`——禁止拼接翻译\n- 单字或短词因上下文不同可能产生歧义时，使用 `[lower_snake_case].原文` 上下文键，例如 `$L('[weekday].一')`、`$L('[task_unit].个')`；前缀只参与翻译查找，界面仍显示原文。此类键须完整登记到 `original-web.txt`，且 `translate.json` 的 `zh` 必须填写去除前缀后的原文；普通键的 `zh` 仍留空\n\n## ai-kb 同步规则\n\n`resources/ai-kb/` 是产品内 AI 助手 RAG 检索的功能知识库（目录结构、写作规范、索引机制见其 `README.md` 与 `_schema/`）。\n\n- **同步时机**：改动用户可见的功能/菜单/按钮/流程/字段、API 行为（错误码、参数含义、返回结构）、插件/微应用、权限/角色定义时，必须在同一次提交中同步更新 ai-kb，不要把 ai-kb 改动单独拆成一个提交\n- **怎么改**：在 `_meta/feature-map.yaml` 找到对应 feature 的 chunk 清单，按 `_schema/chunk-style.md` 与 `_schema/frontmatter.md` 修改或新建 chunk，并把 frontmatter 的 `last_verified` 更新为当前主程序版本号\n- **改完即止**：无需触发任何索引操作，插件容器启动时会自动对账收敛\n\n## Playwright 测试\n\n- Playwright 测试结果放在 `tests/playwright-results/`，包含测试环境、测试用例、结果截图等信息\n\n## 交互规范\n\n- **提问时附带建议**：当需要向用户提问或请求澄清时，应同时提供具体的建议选项或推荐方案，帮助用户快速决策，而非仅抛出开放式问题\n\n## 语言偏好\n\n- 回复一律使用简体中文，除非用户明确要求其他语言\n","isInternal":false,"tokens":2168,"sizeBytes":6345},{"name":"marketplace.json","path":".claude-plugin/marketplace.json","rawUrl":"https://raw.githubusercontent.com/kuaifan/dootask/HEAD/.claude-plugin/marketplace.json","title":"Claude Plugin Marketplace Catalog","category":"marketplace","format":"json","content":"# Claude Plugin Marketplace Catalog\n\nPath: `.claude-plugin/marketplace.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/kuaifan/dootask/HEAD/.claude-plugin/marketplace.json)","tokens":300,"sizeBytes":194},{"name":"plugin.json","path":".claude-plugin/plugin.json","rawUrl":"https://raw.githubusercontent.com/kuaifan/dootask/HEAD/.claude-plugin/plugin.json","title":"claude-plugin Plugin Manifest","category":"plugin-manifest","format":"json","content":"# claude-plugin Plugin Manifest\n\nPath: `.claude-plugin/plugin.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/kuaifan/dootask/HEAD/.claude-plugin/plugin.json)","tokens":300,"sizeBytes":180},{"name":"mcp.json","path":".cursor/mcp.json","rawUrl":"https://raw.githubusercontent.com/kuaifan/dootask/HEAD/.cursor/mcp.json","title":"Model Context Protocol (MCP) Configuration","category":"mcp-config","format":"json","content":"# Model Context Protocol (MCP) Configuration\n\nPath: `.cursor/mcp.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/kuaifan/dootask/HEAD/.cursor/mcp.json)","tokens":300,"sizeBytes":173}],"systemPromptSnippet":"<yakaai_skills repo=\"kuaifan/dootask\">\n<!-- File: AGENTS.md (Tokens: ~2168 | Category: root-instruction) -->\n## 项目概述\n\nLaravel 13 (LaravelS/Swoole, PHP 8.4) + Vue 2 (Vite) + Electron。开源任务/项目管理系统。\n\n## 开发命令\n\n所有命令通过 `./cmd` 脚本执行（不要直接运行 `php artisan` 等）：\n\n- `./cmd artisan ...` / `./cmd composer ...` / `./cmd php ...` — PHP 相关命令\n\n### AI 不要主动执行的命令\n\n以下命令仅由用户人工触发，AI 不要主动跑——包括\"任务完成后 sanity check\"、\"看下能不能编译\"等场景：\n\n- `./cmd dev` — 用户已自行运行 dev server，改完会自己 reload；AI 再跑会争抢进程\n- `./cmd prod` / `./cmd build` — 发版才用，走 `/release` 流程\n\n前端代码改动只做 Edit/Write，不要为了\"验证\"启动 dev server。用户明确说\"跑一下 / 出包\"时除外。\n\n### 质量门禁（改完代码必须自查，CI 同步在跑，见 .github/workflows/tests.yml）\n\n- `./cmd composer stan` — phpstan（level 1 + baseline，存量已封存，新增错误必须清零）\n- `npm run lint` — ESLint（error 必须为 0；warn 是存量遗留，见 eslint.config.mjs 注释）\n- `npm run check:lang` — 校验前端 `$L()` 字面量是否已登记到 `language/original-web.txt`\n- 改动控制器 public 方法或路由后跑 `./cmd artisan doc:api-map` 重新生成对照表\n\n## 代码检索地图（先查表，再 grep）\n\n- API URL ↔ 控制器方法对照：`routes/api-map.md`（生成式文件，勿手改）\n- 前端事件总线（mitt）收发对照：`docs/events-map.md`（`npm run events:map` 重新生成）\n- `$A` / `$L` 全局工具类型声明：`types/dootask-globals.d.ts`（新增 `$A` 方法须同步此文件）\n\n## 架构增量规则（只约束新增代码，存量\"动到哪迁到哪\"）\n\n- **巨型文件冻结**：不再往 `ProjectController`、`UsersController`、`DialogController`、`app/Module/Base.php`、`resources/assets/js/store/actions.js` 新增方法/函数；新功能领域开新控制器或新模块文件（动态路由天然支持多控制器）\n- **业务编排归层**：跨模型的业务流程写在 `app/Module/`（或 `app/Services/`），模型只保留数据访问与自身状态变更；Swoole Task 只做投递与调用，不直接编排业务\n- **配置读取**：业务代码禁止直接 `env()`，统一走 `config()`（项目自有配置集中在 `config/dootask.php`）\n\n## Gotchas\n\n### LaravelS/Swoole\n\n- **避免在静态属性、单例、全局变量中存储请求级状态**——请求间共享进程，会导致数据串联和内存泄漏\n  - 要存请求级状态，用 `RequestContext::save('key', $value)` / `RequestContext::get('key')`（参考 `User::authInfo()` 的用法，见 `app/Services/RequestContext.php`）\n- 构造函数、服务提供者、`boot()` 方法不会在每个请求重新执行\n- 配置/路由变更需要 `./cmd php restart` 或容器重启才能生效\n- 长生命周期逻辑（WebSocket、定时器）应复用现有模式，避免阻塞协程/事件循环\n\n### 后端\n\n- **非 REST 路由**：API 控制器（继承 `InvokeController`）在 `routes/web.php` 按资源注册路由，URL 段映射为控制器方法（如 `api/project/lists` → `lists()`，带 action 则用双下划线：`api/project/invite/join` → `invite__join()`）\n  - 路由最多两段：方法名最多一个双下划线（`method__action`），不支持 `method__action__xxx`（无对应路由，访问 404）\n- **响应格式**：统一使用 `Base::retSuccess($msg, $data)` / `Base::retError($msg)`，返回 `{\"ret\": 1, \"msg\": \"...\", \"data\": {...}}`——不要用 `response()->json()`\n- 业务异常通过 `App\\Exceptions\\ApiException` 抛出，不要用通用 Exception\n- 模型继承 `AbstractModel`，使用 `Model::createInstance($params)` 创建——不要用 `new Model()` 或 `Model::create()`\n- 认证使用 `Doo::userId()`——不要用 `auth()->user()`\n- 参数校验在控制器方法中手动进行——不要创建 FormRequest 类\n- 异步任务使用 Swoole Task（`app/Tasks/`）——不要用 Laravel Queue\n- `app/Module/` 存放跨控制器/跨模型的业务逻辑（非标准 Laravel 目录）\n- 所有表结构变更必须通过 Laravel migration，禁止直接改库\n\n### 前端\n\n- API 调用使用 `store.dispatch(\"call\", params)`，不要在组件中直接 axios/fetch\n- `$A.modalXXX`、`$A.messageXXX`、`$A.noticeXXX` 内部自动处理 `$L` 翻译，调用方不要额外包 `$L`。仅当传入 `language: false` 时由调用方自行处理翻译\n\n### 国际化\n\n- 新增用户可见文本须追加原文（简体中文）到：前端 `language/original-web.txt`，后端 `language/original-api.txt`（去重）\n- 前端翻译用 `$L(\"文本\")`，动态值用 `(*)` 占位：`$L('共(*)条', n)`——禁止拼接翻译\n- 单字或短词因上下文不同可能产生歧义时，使用 `[lower_snake_case].原文` 上下文键，例如 `$L('[weekday].一')`、`$L('[task_unit].个')`；前缀只参与翻译查找，界面仍显示原文。此类键须完整登记到 `original-web.txt`，且 `translate.json` 的 `zh` 必须填写去除前缀后的原文；普通键的 `zh` 仍留空\n\n## ai-kb 同步规则\n\n`resources/ai-kb/` 是产品内 AI 助手 RAG 检索的功能知识库（目录结构、写作规范、索引机制见其 `README.md` 与 `_schema/`）。\n\n- **同步时机**：改动用户可见的功能/菜单/按钮/流程/字段、API 行为（错误码、参数含义、返回结构）、插件/微应用、权限/角色定义时，必须在同一次提交中同步更新 ai-kb，不要把 ai-kb 改动单独拆成一个提交\n- **怎么改**：在 `_meta/feature-map.yaml` 找到对应 feature 的 chunk 清单，按 `_schema/chunk-style.md` 与 `_schema/frontmatter.md` 修改或新建 chunk，并把 frontmatter 的 `last_verified` 更新为当前主程序版本号\n- **改完即止**：无需触发任何索引操作，插件容器启动时会自动对账收敛\n\n## Playwright 测试\n\n- Playwright 测试结果放在 `tests/playwright-results/`，包含测试环境、测试用例、结果截图等信息\n\n## 交互规范\n\n- **提问时附带建议**：当需要向用户提问或请求澄清时，应同时提供具体的建议选项或推荐方案，帮助用户快速决策，而非仅抛出开放式问题\n\n## 语言偏好\n\n- 回复一律使用简体中文，除非用户明确要求其他语言\n\n<!-- File: CLAUDE.md (Tokens: ~2168 | Category: claude-rule) -->\n## 项目概述\n\nLaravel 13 (LaravelS/Swoole, PHP 8.4) + Vue 2 (Vite) + Electron。开源任务/项目管理系统。\n\n## 开发命令\n\n所有命令通过 `./cmd` 脚本执行（不要直接运行 `php artisan` 等）：\n\n- `./cmd artisan ...` / `./cmd composer ...` / `./cmd php ...` — PHP 相关命令\n\n### AI 不要主动执行的命令\n\n以下命令仅由用户人工触发，AI 不要主动跑——包括\"任务完成后 sanity check\"、\"看下能不能编译\"等场景：\n\n- `./cmd dev` — 用户已自行运行 dev server，改完会自己 reload；AI 再跑会争抢进程\n- `./cmd prod` / `./cmd build` — 发版才用，走 `/release` 流程\n\n前端代码改动只做 Edit/Write，不要为了\"验证\"启动 dev server。用户明确说\"跑一下 / 出包\"时除外。\n\n### 质量门禁（改完代码必须自查，CI 同步在跑，见 .github/workflows/tests.yml）\n\n- `./cmd composer stan` — phpstan（level 1 + baseline，存量已封存，新增错误必须清零）\n- `npm run lint` — ESLint（error 必须为 0；warn 是存量遗留，见 eslint.config.mjs 注释）\n- `npm run check:lang` — 校验前端 `$L()` 字面量是否已登记到 `language/original-web.txt`\n- 改动控制器 public 方法或路由后跑 `./cmd artisan doc:api-map` 重新生成对照表\n\n## 代码检索地图（先查表，再 grep）\n\n- API URL ↔ 控制器方法对照：`routes/api-map.md`（生成式文件，勿手改）\n- 前端事件总线（mitt）收发对照：`docs/events-map.md`（`npm run events:map` 重新生成）\n- `$A` / `$L` 全局工具类型声明：`types/dootask-globals.d.ts`（新增 `$A` 方法须同步此文件）\n\n## 架构增量规则（只约束新增代码，存量\"动到哪迁到哪\"）\n\n- **巨型文件冻结**：不再往 `ProjectController`、`UsersController`、`DialogController`、`app/Module/Base.php`、`resources/assets/js/store/actions.js` 新增方法/函数；新功能领域开新控制器或新模块文件（动态路由天然支持多控制器）\n- **业务编排归层**：跨模型的业务流程写在 `app/Module/`（或 `app/Services/`），模型只保留数据访问与自身状态变更；Swoole Task 只做投递与调用，不直接编排业务\n- **配置读取**：业务代码禁止直接 `env()`，统一走 `config()`（项目自有配置集中在 `config/dootask.php`）\n\n## Gotchas\n\n### LaravelS/Swoole\n\n- **避免在静态属性、单例、全局变量中存储请求级状态**——请求间共享进程，会导致数据串联和内存泄漏\n  - 要存请求级状态，用 `RequestContext::save('key', $value)` / `RequestContext::get('key')`（参考 `User::authInfo()` 的用法，见 `app/Services/RequestContext.php`）\n- 构造函数、服务提供者、`boot()` 方法不会在每个请求重新执行\n- 配置/路由变更需要 `./cmd php restart` 或容器重启才能生效\n- 长生命周期逻辑（WebSocket、定时器）应复用现有模式，避免阻塞协程/事件循环\n\n### 后端\n\n- **非 REST 路由**：API 控制器（继承 `InvokeController`）在 `routes/web.php` 按资源注册路由，URL 段映射为控制器方法（如 `api/project/lists` → `lists()`，带 action 则用双下划线：`api/project/invite/join` → `invite__join()`）\n  - 路由最多两段：方法名最多一个双下划线（`method__action`），不支持 `method__action__xxx`（无对应路由，访问 404）\n- **响应格式**：统一使用 `Base::retSuccess($msg, $data)` / `Base::retError($msg)`，返回 `{\"ret\": 1, \"msg\": \"...\", \"data\": {...}}`——不要用 `response()->json()`\n- 业务异常通过 `App\\Exceptions\\ApiException` 抛出，不要用通用 Exception\n- 模型继承 `AbstractModel`，使用 `Model::createInstance($params)` 创建——不要用 `new Model()` 或 `Model::create()`\n- 认证使用 `Doo::userId()`——不要用 `auth()->user()`\n- 参数校验在控制器方法中手动进行——不要创建 FormRequest 类\n- 异步任务使用 Swoole Task（`app/Tasks/`）——不要用 Laravel Queue\n- `app/Module/` 存放跨控制器/跨模型的业务逻辑（非标准 Laravel 目录）\n- 所有表结构变更必须通过 Laravel migration，禁止直接改库\n\n### 前端\n\n- API 调用使用 `store.dispatch(\"call\", params)`，不要在组件中直接 axios/fetch\n- `$A.modalXXX`、`$A.messageXXX`、`$A.noticeXXX` 内部自动处理 `$L` 翻译，调用方不要额外包 `$L`。仅当传入 `language: false` 时由调用方自行处理翻译\n\n### 国际化\n\n- 新增用户可见文本须追加原文（简体中文）到：前端 `language/original-web.txt`，后端 `language/original-api.txt`（去重）\n- 前端翻译用 `$L(\"文本\")`，动态值用 `(*)` 占位：`$L('共(*)条', n)`——禁止拼接翻译\n- 单字或短词因上下文不同可能产生歧义时，使用 `[lower_snake_case].原文` 上下文键，例如 `$L('[weekday].一')`、`$L('[task_unit].个')`；前缀只参与翻译查找，界面仍显示原文。此类键须完整登记到 `original-web.txt`，且 `translate.json` 的 `zh` 必须填写去除前缀后的原文；普通键的 `zh` 仍留空\n\n## ai-kb 同步规则\n\n`resources/ai-kb/` 是产品内 AI 助手 RAG 检索的功能知识库（目录结构、写作规范、索引机制见其 `README.md` 与 `_schema/`）。\n\n- **同步时机**：改动用户可见的功能/菜单/按钮/流程/字段、API 行为（错误码、参数含义、返回结构）、插件/微应用、权限/角色定义时，必须在同一次提交中同步更新 ai-kb，不要把 ai-kb 改动单独拆成一个提交\n- **怎么改**：在 `_meta/feature-map.yaml` 找到对应 feature 的 chunk 清单，按 `_schema/chunk-style.md` 与 `_schema/frontmatter.md` 修改或新建 chunk，并把 frontmatter 的 `last_verified` 更新为当前主程序版本号\n- **改完即止**：无需触发任何索引操作，插件容器启动时会自动对账收敛\n\n## Playwright 测试\n\n- Playwright 测试结果放在 `tests/playwright-results/`，包含测试环境、测试用例、结果截图等信息\n\n## 交互规范\n\n- **提问时附带建议**：当需要向用户提问或请求澄清时，应同时提供具体的建议选项或推荐方案，帮助用户快速决策，而非仅抛出开放式问题\n\n## 语言偏好\n\n- 回复一律使用简体中文，除非用户明确要求其他语言\n\n<!-- File: .claude-plugin/marketplace.json (Tokens: ~300 | Category: marketplace) -->\n# Claude Plugin Marketplace Catalog\n\nPath: `.claude-plugin/marketplace.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/kuaifan/dootask/HEAD/.claude-plugin/marketplace.json)\n\n<!-- File: .claude-plugin/plugin.json (Tokens: ~300 | Category: plugin-manifest) -->\n# claude-plugin Plugin Manifest\n\nPath: `.claude-plugin/plugin.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/kuaifan/dootask/HEAD/.claude-plugin/plugin.json)\n\n<!-- File: .cursor/mcp.json (Tokens: ~300 | Category: mcp-config) -->\n# Model Context Protocol (MCP) Configuration\n\nPath: `.cursor/mcp.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/kuaifan/dootask/HEAD/.cursor/mcp.json)\n</yakaai_skills>"}