diff --git a/package.json b/package.json index 5b670a3..1d05479 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "@kevisual/cnb-center", "private": true, - "version": "0.0.7", + "version": "0.0.8", "type": "module", "basename": "/root/cnb-center", "scripts": { @@ -9,7 +9,7 @@ "build": "vite build", "preview": "vite preview", "ui": "pnpm dlx shadcn@latest add ", - "pub": "envision deploy ./dist -k cnb-center -v 0.0.7 -y y -u" + "pub": "envision deploy ./dist -k cnb-center -v 0.0.8 -y y -u" }, "files": [ "dist" diff --git a/src/agents/app.ts b/src/agents/app.ts index 8029c5e..e0ae7c8 100644 --- a/src/agents/app.ts +++ b/src/agents/app.ts @@ -1,28 +1,9 @@ import { QueryRouterServer } from '@kevisual/router/browser' - import { useContextKey } from '@kevisual/context' -import { useConfigStore } from '@/pages/config/store' import { useGiteaConfigStore } from '@/pages/config/gitea/store' -import { CNB } from '@kevisual/cnb' import { Gitea } from '@kevisual/gitea'; export const app = useContextKey('app', new QueryRouterServer()) -export const cnb: CNB = useContextKey('cnb', () => { - const state = useConfigStore.getState() - const config = state.config || {} - const cors: any = {} - if (config.ENABLE_CORS) { - cors.baseUrl = config.CNB_CORS_URL || 'https://cors.kevisual.cn' - } - console.log('state', state) - // if(state.config.) - return new CNB({ - token: config.CNB_API_KEY, - cookie: config.CNB_COOKIE, - cors - }) -}) - // import '@kevisual/cnb-ai' const url = 'https://kevisual.cn/root/cnb-ai/dist/app.js' diff --git a/src/modules/cnb-api.ts b/src/modules/cnb-api.ts new file mode 100644 index 0000000..20088bf --- /dev/null +++ b/src/modules/cnb-api.ts @@ -0,0 +1,1227 @@ +import { createQueryApi } from '@kevisual/query/api'; +const api = { + "cnb": { + /** + * 调用cnb的知识库ai对话功能进行聊天,基于cnb提供的ai能力 + * + * @param data - Request parameters + * @param data.question - {string} 用户输入的消息内容 + * @param data.repo - {string} 知识库仓库ID,默认为空表示使用默认知识库 + */ + "cnb-ai-chat": { + "path": "cnb", + "key": "cnb-ai-chat", + "description": "调用cnb的知识库ai对话功能进行聊天", + "metadata": { + "tags": [ + "opencode" + ], + "args": { + "question": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "type": "string", + "description": "用户输入的消息内容" + }, + "repo": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "description": "知识库仓库ID,默认为空表示使用默认知识库", + "type": "string", + "optional": true + } + }, + "skill": "cnb-ai-chat", + "title": "调用cnb的知识库ai对话功能进行聊天", + "summary": "调用cnb的知识库ai对话功能进行聊天,基于cnb提供的ai能力", + "url": "/api/router", + "source": "query-proxy-api" + } + }, + /** + * 调用cnb的知识库RAG查询功能进行问答,基于cnb提供的知识库能力 + * + * @param data - Request parameters + * @param data.question - {string} 用户输入的消息内容 + * @param data.repo - {string} 知识库仓库ID,默认为空表示使用默认知识库 + */ + "cnb-rag-query": { + "path": "cnb", + "key": "cnb-rag-query", + "description": "调用cnb的知识库RAG查询功能进行问答", + "metadata": { + "tags": [ + "opencode" + ], + "args": { + "question": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "type": "string", + "description": "用户输入的消息内容" + }, + "repo": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "description": "知识库仓库ID,默认为空表示使用默认知识库", + "type": "string", + "optional": true + } + }, + "skill": "cnb-rag-query", + "title": "调用cnb的知识库RAG查询功能进行问答", + "summary": "调用cnb的知识库RAG查询功能进行问答,基于cnb提供的知识库能力", + "url": "/api/router", + "source": "query-proxy-api" + } + }, + /** + * 获取当前cnb工作空间的port代理uri,用于端口转发 + * + * @param data - Request parameters + * @param data.port - {number} 端口号,默认为51515 + */ + "get-cnb-port-uri": { + "path": "cnb", + "key": "get-cnb-port-uri", + "description": "获取当前cnb工作空间的port代理uri", + "metadata": { + "tags": [ + "opencode" + ], + "args": { + "port": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "description": "端口号,默认为51515", + "type": "number", + "optional": true + } + }, + "skill": "get-cnb-port-uri", + "title": "获取当前cnb工作空间的port代理uri", + "summary": "获取当前cnb工作空间的port代理uri,用于端口转发", + "url": "/api/router", + "source": "query-proxy-api" + } + }, + /** + * 设置当前cnb工作空间的cookie环境变量,用于界面操作定制模块功能,例子:CNBSESSION=xxxx;csrfkey=2222xxxx; + * + * @param data - Request parameters + * @param data.cookie - {string} cnb的cookie值 + */ + "set-cnb-cookie": { + "path": "cnb", + "key": "set-cnb-cookie", + "description": "设置当前cnb工作空间的cookie环境变量", + "metadata": { + "tags": [ + "opencode" + ], + "args": { + "cookie": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "type": "string", + "description": "cnb的cookie值" + } + }, + "skill": "set-cnb-cookie", + "title": "设置当前cnb工作空间的cookie环境变量", + "summary": "设置当前cnb工作空间的cookie环境变量,用于界面操作定制模块功能,例子:CNBSESSION=xxxx;csrfkey=2222xxxx;", + "url": "/api/router", + "source": "query-proxy-api" + } + }, + /** + * 获取当前cnb工作空间的cookie环境变量,用于界面操作定制模块功能 + */ + "get-cnb-cookie": { + "path": "cnb", + "key": "get-cnb-cookie", + "description": "获取当前cnb工作空间的cookie环境变量", + "metadata": { + "tags": [ + "opencode" + ], + "args": {}, + "skill": "get-cnb-cookie", + "title": "获取当前cnb工作空间的cookie环境变量", + "summary": "获取当前cnb工作空间的cookie环境变量,用于界面操作定制模块功能", + "url": "/api/router", + "source": "query-proxy-api" + } + }, + /** + * 获取当前cnb工作空间的vscode代理uri,用于在浏览器中访问vscode,包含多种访问方式,如web、vscode、codebuddy、cursor、ssh + * + * @param data - Request parameters + * @param data.web - {boolean} 是否获取vscode web的访问uri,默认为false + * @param data.vscode - {boolean} 是否获取vscode的代理uri,默认为true + * @param data.codebuddy - {boolean} 是否获取codebuddy的代理uri,默认为false + * @param data.cursor - {boolean} 是否获取cursor的代理uri,默认为false + * @param data.ssh - {boolean} 是否获取vscode remote ssh的连接字符串,默认为false + */ + "get-cnb-vscode-uri": { + "path": "cnb", + "key": "get-cnb-vscode-uri", + "description": "获取当前cnb工作空间的vscode代理uri, 包括多种访问方式, 如web、vscode、codebuddy、cursor、ssh", + "metadata": { + "tags": [ + "opencode" + ], + "args": { + "web": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "description": "是否获取vscode web的访问uri,默认为false", + "type": "boolean", + "optional": true + }, + "vscode": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "description": "是否获取vscode的代理uri,默认为true", + "type": "boolean", + "optional": true + }, + "codebuddy": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "description": "是否获取codebuddy的代理uri,默认为false", + "type": "boolean", + "optional": true + }, + "cursor": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "description": "是否获取cursor的代理uri,默认为false", + "type": "boolean", + "optional": true + }, + "ssh": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "description": "是否获取vscode remote ssh的连接字符串,默认为false", + "type": "boolean", + "optional": true + } + }, + "skill": "get-cnb-vscode-uri", + "title": "获取当前cnb工作空间的编辑器访问地址", + "summary": "获取当前cnb工作空间的vscode代理uri,用于在浏览器中访问vscode,包含多种访问方式,如web、vscode、codebuddy、cursor、ssh", + "url": "/api/router", + "source": "query-proxy-api" + } + }, + /** + * 获取cnb工作空间中部署的各个助手的访问地址 + * + * @param data - Request parameters + * @param data.more - {boolean} 需要更多信息 + */ + "get-assistant-url": { + "path": "cnb", + "key": "get-assistant-url", + "description": "获取cnb工作空间中部署的各个助手的访问地址", + "metadata": { + "args": { + "more": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "type": "boolean", + "description": "需要更多信息" + } + }, + "url": "/api/router", + "source": "query-proxy-api" + } + }, + /** + * 清理我的cnb-manager记录 + */ + "clear-me-manager": { + "path": "cnb", + "key": "clear-me-manager", + "description": "清理我的cnb-manager记录", + "metadata": { + "url": "/api/router", + "source": "query-proxy-api" + } + }, + /** + * 获取我的cnb配置 + */ + "get-my-config": { + "path": "cnb", + "key": "get-my-config", + "description": "获取我的cnb配置", + "metadata": { + "url": "/api/router", + "source": "query-proxy-api" + } + }, + /** + * 批量删除已停止的cnb工作空间,释放资源 + */ + "clean-closed-workspace": { + "path": "cnb", + "key": "clean-closed-workspace", + "description": "批量删除已停止的cnb工作空间", + "metadata": { + "tags": [ + "opencode" + ], + "args": {}, + "skill": "clean-closed-workspace", + "title": "清理已关闭的cnb工作空间", + "summary": "批量删除已停止的cnb工作空间,释放资源", + "url": "/api/router", + "source": "query-proxy-api" + } + }, + /** + * 列出cnb工作空间列表,支持按状态过滤, status 可选值 running 或 closed + * + * @param data - Request parameters + * @param data.status - {string} 开发环境状态,running: 运行中,closed: 已关闭和停止的 + * @param data.page - {number} 分页页码,默认 1 + * @param data.pageSize - {number} 分页大小,默认 20,最大 100 + * @param data.slug - {string} 仓库路径,例如 groupname/reponame + * @param data.branch - {string} 分支名称 + */ + "list-workspace": { + "path": "cnb", + "key": "list-workspace", + "description": "获取cnb开发工作空间列表,可选参数 status=running 获取运行中的环境", + "metadata": { + "tags": [ + "opencode" + ], + "args": { + "status": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "description": "开发环境状态,running: 运行中,closed: 已关闭和停止的", + "type": "string", + "optional": true + }, + "page": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "description": "分页页码,默认 1", + "type": "number", + "optional": true + }, + "pageSize": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "description": "分页大小,默认 20,最大 100", + "type": "number", + "optional": true + }, + "slug": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "description": "仓库路径,例如 groupname/reponame", + "type": "string", + "optional": true + }, + "branch": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "description": "分支名称", + "type": "string", + "optional": true + } + }, + "skill": "list-workspace", + "title": "列出cnb工作空间", + "summary": "列出cnb工作空间列表,支持按状态过滤, status 可选值 running 或 closed", + "url": "/api/router", + "source": "query-proxy-api" + } + }, + /** + * 验证 CNB 登录信息是否有效 + * + * @param data - Request parameters + * @param data.checkToken - {boolean} 是否检查 Token 的有效性 + * @param data.checkCookie - {boolean} 是否检查 Cookie 的有效性 + */ + "user-check": { + "path": "cnb", + "key": "user-check", + "description": "检查用户登录状态,参数checkToken,default true; checkCookie, default false", + "metadata": { + "tags": [ + "opencode" + ], + "args": { + "checkToken": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "default": true, + "type": "boolean", + "description": "是否检查 Token 的有效性", + "optional": true + }, + "checkCookie": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "default": false, + "type": "boolean", + "description": "是否检查 Cookie 的有效性", + "optional": true + } + }, + "skill": "cnb-login-verify", + "title": "CNB 登录验证信息", + "summary": "验证 CNB 登录信息是否有效", + "url": "/api/router", + "source": "query-proxy-api" + } + }, + /** + * 列出cnb代码仓库, 可选flags参数,如 KnowledgeBase + * + * @param data - Request parameters + * @param data.search - {string} 搜索关键词 + * @param data.pageSize - {number} 每页数量,默认999 + * @param data.flags - {string} 仓库标记,如果是知识库则填写 KnowledgeBase + */ + "list-repos": { + "path": "cnb", + "key": "list-repos", + "description": "列出我的代码仓库", + "metadata": { + "tags": [ + "opencode" + ], + "args": { + "search": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "description": "搜索关键词", + "type": "string", + "optional": true + }, + "pageSize": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "description": "每页数量,默认999", + "type": "number", + "optional": true + }, + "flags": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "description": "仓库标记,如果是知识库则填写 KnowledgeBase", + "type": "string", + "optional": true + } + }, + "skill": "list-repos", + "title": "列出cnb代码仓库", + "summary": "列出cnb代码仓库, 可选flags参数,如 KnowledgeBase", + "url": "/api/router", + "source": "query-proxy-api" + } + }, + /** + * 创建一个新的代码仓库 + * + * @param data - Request parameters + * @param data.name - {string} 代码仓库名称, 如 my-user/my-repo + * @param data.visibility - {string} 代码仓库可见性, public 或 private + * @param data.description - {string} 代码仓库描述 + */ + "create-repo": { + "path": "cnb", + "key": "create-repo", + "description": "创建代码仓库, 参数name, visibility, description", + "metadata": { + "tags": [ + "opencode" + ], + "args": { + "name": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "type": "string", + "description": "代码仓库名称, 如 my-user/my-repo" + }, + "visibility": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "default": "public", + "type": "string", + "description": "代码仓库可见性, public 或 private", + "optional": true + }, + "description": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "type": "string", + "description": "代码仓库描述" + } + }, + "skill": "create-repo", + "title": "创建代码仓库", + "summary": "创建一个新的代码仓库", + "url": "/api/router", + "source": "query-proxy-api" + } + }, + /** + * 获取代码仓库详情, 参数name + * + * @param data - Request parameters + * @param data.name - {string} 代码仓库名称, 如 my-user/my-repo + */ + "get-repo": { + "path": "cnb", + "key": "get-repo", + "description": "获取代码仓库详情, 参数name", + "metadata": { + "args": { + "name": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "type": "string", + "description": "代码仓库名称, 如 my-user/my-repo" + } + }, + "url": "/api/router", + "source": "query-proxy-api" + } + }, + /** + * 在代码仓库中创建文件, encoding 可选,默认 raw + * + * @param data - Request parameters + * @param data.repoName - {string} 代码仓库名称, 如 my-user/my-repo + * @param data.filePath - {string} 文件路径, 如 src/index.ts + * @param data.content - {string} 文本的字符串的内容 + * @param data.encoding - {string} 编码方式,如 raw + */ + "create-repo-file": { + "path": "cnb", + "key": "create-repo-file", + "description": "在代码仓库中创建文件, repoName, filePath, content, encoding。使用CNB_COOKIE进行鉴权", + "metadata": { + "tags": [ + "opencode" + ], + "args": { + "repoName": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "type": "string", + "description": "代码仓库名称, 如 my-user/my-repo" + }, + "filePath": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "type": "string", + "description": "文件路径, 如 src/index.ts" + }, + "content": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "type": "string", + "description": "文本的字符串的内容" + }, + "encoding": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "type": "string", + "description": "编码方式,如 raw", + "optional": true + } + }, + "skill": "create-repo-file", + "title": "在代码仓库中创建文件", + "summary": "在代码仓库中创建文件, encoding 可选,默认 raw", + "url": "/api/router", + "source": "query-proxy-api" + } + }, + /** + * 删除一个代码仓库 + * + * @param data - Request parameters + * @param data.name - {string} 代码仓库名称 + */ + "delete-repo": { + "path": "cnb", + "key": "delete-repo", + "description": "删除代码仓库, 参数name", + "metadata": { + "tags": [ + "opencode" + ], + "args": { + "name": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "type": "string", + "description": "代码仓库名称" + } + }, + "skill": "delete-repo", + "title": "删除代码仓库", + "summary": "删除一个代码仓库", + "url": "/api/router", + "source": "query-proxy-api" + } + }, + /** + * 更新代码仓库的信息 + * + * @param data - Request parameters + * @param data.name - {string} 代码仓库名称 + * @param data.description - {string} 代码仓库描述 + * @param data.license - {string} 代码仓库许可证类型,如 MIT + * @param data.site - {string} 代码仓库主页链接 + * @param data.topics - {array} 代码仓库话题标签列表 + */ + "update-repo-info": { + "path": "cnb", + "key": "update-repo-info", + "description": "更新代码仓库信息, 参数name, description", + "metadata": { + "tags": [ + "opencode" + ], + "args": { + "name": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "type": "string", + "description": "代码仓库名称" + }, + "description": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "type": "string", + "description": "代码仓库描述" + }, + "license": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "type": "string", + "description": "代码仓库许可证类型,如 MIT", + "optional": true + }, + "site": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "type": "string", + "description": "代码仓库主页链接", + "optional": true + }, + "topics": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "type": "array", + "items": { + "type": "string" + }, + "description": "代码仓库话题标签列表", + "optional": true + } + }, + "skill": "update-repo-info", + "title": "更新代码仓库信息", + "summary": "更新代码仓库的信息", + "url": "/api/router", + "source": "query-proxy-api" + } + }, + /** + * 保持工作空间存活技能,参数repo:代码仓库路径,例如 user/repo,pipelineId:流水线ID,例如 cnb-708-1ji9sog7o-001 + * + * @param data - Request parameters + * @param data.repo - {string} 代码仓库路径,例如 user/repo + * @param data.pipelineId - {string} 流水线ID,例如 cnb-708-1ji9sog7o-001 + */ + "keep-workspace-alive": { + "path": "cnb", + "key": "keep-workspace-alive", + "description": "保持工作空间存活技能,参数repo:代码仓库路径,例如 user/repo,pipelineId:流水线ID,例如 cnb-708-1ji9sog7o-001", + "metadata": { + "tags": [], + "args": { + "repo": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "type": "string", + "description": "代码仓库路径,例如 user/repo" + }, + "pipelineId": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "type": "string", + "description": "流水线ID,例如 cnb-708-1ji9sog7o-001" + } + }, + "url": "/api/router", + "source": "query-proxy-api" + } + }, + /** + * 停止保持工作空间存活技能, 参数repo:代码仓库路径,例如 user/repo,pipelineId:流水线ID,例如 cnb-708-1ji9sog7o-001 + * + * @param data - Request parameters + * @param data.repo - {string} 代码仓库路径,例如 user/repo + * @param data.pipelineId - {string} 流水线ID,例如 cnb-708-1ji9sog7o-001 + */ + "stop-keep-workspace-alive": { + "path": "cnb", + "key": "stop-keep-workspace-alive", + "description": "停止保持工作空间存活技能, 参数repo:代码仓库路径,例如 user/repo,pipelineId:流水线ID,例如 cnb-708-1ji9sog7o-001", + "metadata": { + "tags": [], + "args": { + "repo": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "type": "string", + "description": "代码仓库路径,例如 user/repo" + }, + "pipelineId": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "type": "string", + "description": "流水线ID,例如 cnb-708-1ji9sog7o-001" + } + }, + "url": "/api/router", + "source": "query-proxy-api" + } + }, + /** + * 保持当前工作空间存活,防止被关闭或释放资源 + */ + "keep-alive-current-workspace": { + "path": "cnb", + "key": "keep-alive-current-workspace", + "description": "保持当前工作空间存活技能", + "metadata": { + "tags": [ + "opencode" + ], + "skill": "keep-alive-current-workspace", + "title": "保持当前工作空间存活", + "summary": "保持当前工作空间存活,防止被关闭或释放资源", + "url": "/api/router", + "source": "query-proxy-api" + } + }, + /** + * 在云端构建代码仓库,参数包括 event, repo, branch, ref, config, env + * + * @param data - Request parameters + * @param data.env - {unknown} 构建环境变量,格式为 { "KEY": "VALUE" } + * @param data.event - {string} 触发事件类型,例如 api_trigger_event + * @param data.branch - {string} 分支名称,默认主分支 + * @param data.config - {string} 构建config文件内容,例如 cloudbuild.yaml对应的yml的内容 + * @param data.repo - {string} 代码仓库路径,例如 user/repo + */ + "cloud-build": { + "path": "cnb", + "key": "cloud-build", + "description": "云端构建,参数 event, repo, branch, ref, config, env", + "metadata": { + "tags": [ + "opencode" + ], + "args": { + "env": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "description": "构建环境变量,格式为 { \"KEY\": \"VALUE\" }", + "optional": true + }, + "event": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "description": "触发事件类型,例如 api_trigger_event", + "type": "string", + "optional": true + }, + "branch": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "description": "分支名称,默认主分支", + "type": "string", + "optional": true + }, + "config": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "type": "string", + "description": "构建config文件内容,例如 cloudbuild.yaml对应的yml的内容" + }, + "repo": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "type": "string", + "description": "代码仓库路径,例如 user/repo" + } + }, + "skill": "cloud-build", + "title": "云端构建", + "summary": "在云端构建代码仓库,参数包括 event, repo, branch, ref, config, env", + "url": "/api/router", + "source": "query-proxy-api" + } + }, + /** + * 启动cnb工作空间 + * + * @param data - Request parameters + * @param data.repo - {string} 代码仓库路径,例如 user/repo + * @param data.branch - {string} 分支名称,默认主分支 + * @param data.ref - {string} 提交引用,例如 commit sha + */ + "start-workspace": { + "path": "cnb", + "key": "start-workspace", + "description": "启动开发工作空间, 参数 repo", + "metadata": { + "tags": [ + "opencode" + ], + "args": { + "repo": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "type": "string", + "description": "代码仓库路径,例如 user/repo" + }, + "branch": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "description": "分支名称,默认主分支", + "type": "string", + "optional": true + }, + "ref": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "description": "提交引用,例如 commit sha", + "type": "string", + "optional": true + } + }, + "skill": "start-workspace", + "title": "启动cnb工作空间", + "summary": "启动cnb工作空间", + "url": "/api/router", + "source": "query-proxy-api" + } + }, + /** + * 获取工作空间详细信息 + * + * @param data - Request parameters + * @param data.repo - {string} 代码仓库路径,例如 user/repo + * @param data.sn - {string} 工作空间流水线的 sn + */ + "get-workspace": { + "path": "cnb", + "key": "get-workspace", + "description": "获取工作空间详情,通过 repo 和 sn 获取", + "metadata": { + "tags": [ + "opencode" + ], + "args": { + "repo": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "type": "string", + "description": "代码仓库路径,例如 user/repo" + }, + "sn": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "type": "string", + "description": "工作空间流水线的 sn" + } + }, + "skill": "get-workspace", + "title": "获取工作空间详情", + "summary": "获取工作空间详细信息", + "url": "/api/router", + "source": "query-proxy-api" + } + }, + /** + * 删除工作空间,pipelineId 和 sn 二选一 + * + * @param data - Request parameters + * @param data.pipelineId - {string} 流水线 ID,优先使用 + * @param data.sn - {string} 流水线构建号 + * @param data.sns - {array} 批量流水线构建号 + */ + "delete-workspace": { + "path": "cnb", + "key": "delete-workspace", + "description": "删除工作空间,通过 pipelineId 或 sn", + "metadata": { + "tags": [ + "opencode" + ], + "args": { + "pipelineId": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "description": "流水线 ID,优先使用", + "type": "string", + "optional": true + }, + "sn": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "description": "流水线构建号", + "type": "string", + "optional": true + }, + "sns": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "description": "批量流水线构建号", + "type": "array", + "items": { + "type": "string" + }, + "optional": true + } + }, + "skill": "delete-workspace", + "title": "删除工作空间", + "summary": "删除工作空间,pipelineId 和 sn 二选一", + "url": "/api/router", + "source": "query-proxy-api" + } + }, + /** + * 停止运行中的工作空间 + * + * @param data - Request parameters + * @param data.pipelineId - {string} 流水线 ID,优先使用 + * @param data.sn - {string} 流水线构建号 + */ + "stop-workspace": { + "path": "cnb", + "key": "stop-workspace", + "description": "停止工作空间,通过 pipelineId 或 sn", + "metadata": { + "tags": [ + "opencode" + ], + "args": { + "pipelineId": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "description": "流水线 ID,优先使用", + "type": "string", + "optional": true + }, + "sn": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "description": "流水线构建号", + "type": "string", + "optional": true + } + }, + "skill": "stop-workspace", + "title": "停止工作空间", + "summary": "停止运行中的工作空间", + "url": "/api/router", + "source": "query-proxy-api" + } + }, + /** + * 查询 Issue 列表 + * + * @param data - Request parameters + * @param data.repo - {string} 代码仓库名称, 如 my-user/my-repo + * @param data.state - {string} Issue 状态:open 或 closed + * @param data.keyword - {string} 问题搜索关键词 + * @param data.labels - {string} 问题标签,多个用逗号分隔 + * @param data.page - {number} 分页页码,默认: 1 + * @param data.page_size - {number} 分页每页大小,默认: 30 + * @param data.order_by - {string} 排序方式,如 created_at, -updated_at + */ + "list-issues": { + "path": "cnb", + "key": "list-issues", + "description": "查询 Issue 列表, 参数 repo, state, keyword, labels, page, page_size 等", + "metadata": { + "tags": [ + "opencode" + ], + "args": { + "repo": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "type": "string", + "description": "代码仓库名称, 如 my-user/my-repo" + }, + "state": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "description": "Issue 状态:open 或 closed", + "type": "string", + "optional": true + }, + "keyword": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "description": "问题搜索关键词", + "type": "string", + "optional": true + }, + "labels": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "description": "问题标签,多个用逗号分隔", + "type": "string", + "optional": true + }, + "page": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "description": "分页页码,默认: 1", + "type": "number", + "optional": true + }, + "page_size": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "description": "分页每页大小,默认: 30", + "type": "number", + "optional": true + }, + "order_by": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "description": "排序方式,如 created_at, -updated_at", + "type": "string", + "optional": true + } + }, + "skill": "list-issues", + "title": "查询 Issue 列表", + "summary": "查询 Issue 列表", + "url": "/api/router", + "source": "query-proxy-api" + } + }, + /** + * 创建一个新的 Issue + * + * @param data - Request parameters + * @param data.repo - {string} 代码仓库名称, 如 my-user/my-repo + * @param data.title - {string} Issue 标题 + * @param data.body - {string} Issue 描述内容 + * @param data.assignees - {array} 指派人列表 + * @param data.labels - {array} 标签列表 + * @param data.priority - {string} 优先级 + */ + "create-issue": { + "path": "cnb", + "key": "create-issue", + "description": "创建 Issue, 参数 repo, title, body, assignees, labels, priority", + "metadata": { + "tags": [ + "opencode" + ], + "args": { + "repo": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "type": "string", + "description": "代码仓库名称, 如 my-user/my-repo" + }, + "title": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "type": "string", + "description": "Issue 标题" + }, + "body": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "description": "Issue 描述内容", + "type": "string", + "optional": true + }, + "assignees": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "description": "指派人列表", + "type": "array", + "items": { + "type": "string" + }, + "optional": true + }, + "labels": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "description": "标签列表", + "type": "array", + "items": { + "type": "string" + }, + "optional": true + }, + "priority": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "description": "优先级", + "type": "string", + "optional": true + } + }, + "skill": "create-issue", + "title": "创建 Issue", + "summary": "创建一个新的 Issue", + "url": "/api/router", + "source": "query-proxy-api" + } + }, + /** + * 完成一个 Issue(将 state 改为 closed) + * + * @param data - Request parameters + * @param data.repo - {string} 代码仓库名称, 如 my-user/my-repo + * @param data.issueNumber - {unknown} Issue 编号 + * @param data.state - {string} Issue 状态,默认为 closed + */ + "complete-issue": { + "path": "cnb", + "key": "complete-issue", + "description": "完成 Issue, 参数 repo, issueNumber", + "metadata": { + "tags": [ + "opencode" + ], + "args": { + "repo": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "type": "string", + "description": "代码仓库名称, 如 my-user/my-repo" + }, + "issueNumber": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + } + ], + "description": "Issue 编号" + }, + "state": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "description": "Issue 状态,默认为 closed", + "type": "string", + "optional": true + } + }, + "skill": "complete-issue", + "title": "完成 CNB的任务Issue", + "summary": "完成一个 Issue(将 state 改为 closed)", + "url": "/api/router", + "source": "query-proxy-api" + } + } + }, + "cnb_board": { + /** + * cnb的工作环境退出程序 + */ + "exit": { + "path": "cnb_board", + "key": "exit", + "description": "cnb的工作环境退出程序", + "metadata": { + "url": "/api/router", + "source": "query-proxy-api" + } + }, + /** + * 检查是否是 cnb-board 环境 + */ + "is-cnb-board": { + "path": "cnb_board", + "key": "is-cnb-board", + "description": "检查是否是 cnb-board 环境", + "metadata": { + "url": "/api/router", + "source": "query-proxy-api" + } + }, + /** + * 获取cnb-board live的mdContent内容 + * + * @param data - Request parameters + * @param data.more - {boolean} 是否获取更多系统信息,默认false + */ + "live": { + "path": "cnb_board", + "key": "live", + "description": "获取cnb-board live的mdContent内容", + "metadata": { + "args": { + "more": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "description": "是否获取更多系统信息,默认false", + "type": "boolean", + "optional": true + } + }, + "url": "/api/router", + "source": "query-proxy-api" + } + }, + /** + * 获取cnb-board live的repo信息 + */ + "live_repo_info": { + "path": "cnb_board", + "key": "live_repo_info", + "description": "获取cnb-board live的repo信息", + "metadata": { + "url": "/api/router", + "source": "query-proxy-api" + } + }, + /** + * 获取cnb-board live的构建信息 + */ + "live_build_info": { + "path": "cnb_board", + "key": "live_build_info", + "description": "获取cnb-board live的构建信息", + "metadata": { + "url": "/api/router", + "source": "query-proxy-api" + } + }, + /** + * 获取cnb-board live的PR信息 + */ + "live_pull_info": { + "path": "cnb_board", + "key": "live_pull_info", + "description": "获取cnb-board live的PR信息", + "metadata": { + "url": "/api/router", + "source": "query-proxy-api" + } + }, + /** + * 获取cnb-board live的NPC信息 + */ + "live_npc_info": { + "path": "cnb_board", + "key": "live_npc_info", + "description": "获取cnb-board live的NPC信息", + "metadata": { + "url": "/api/router", + "source": "query-proxy-api" + } + }, + /** + * 获取cnb-board live的评论信息 + */ + "live_comment_info": { + "path": "cnb_board", + "key": "live_comment_info", + "description": "获取cnb-board live的评论信息", + "metadata": { + "url": "/api/router", + "source": "query-proxy-api" + } + } + }, + "user": { + /** + * cnb登陆, 根据 CNB_TOKEN 获取用户信息 + * + * @param data - Request parameters + * @param data.data - {object} + */ + "cnb-login": { + "path": "user", + "key": "cnb-login", + "description": "cnb登陆, 根据 CNB_TOKEN 获取用户信息", + "metadata": { + "args": { + "data": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "type": "object", + "properties": { + "cnbToken": { + "type": "string", + "description": "cnb token" + } + }, + "required": [ + "cnbToken" + ], + "additionalProperties": false + } + }, + "url": "/api/router", + "source": "query-proxy-api" + } + } + } +} as const; +const queryApi = createQueryApi({ api }); + +export { queryApi }; diff --git a/src/pages/config/page.tsx b/src/pages/config/page.tsx index d6dc43e..c9d15cc 100644 --- a/src/pages/config/page.tsx +++ b/src/pages/config/page.tsx @@ -3,28 +3,14 @@ import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/com import { Input } from '@/components/ui/input'; import { Label } from '@/components/ui/label'; import { Button } from '@/components/ui/button'; -import { Checkbox } from '@/components/ui/checkbox'; import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from '@/components/ui/tooltip'; import { Info } from 'lucide-react'; -import { configSchema } from './store/schema'; -import { toast } from 'sonner'; -import { useLayoutStore } from '../auth/store'; -import { useShallow } from 'zustand/shallow'; export const ConfigPage = () => { - const { config, setConfig, resetConfig, saveToRemote, loadFromRemote } = useConfigStore(); - const layoutStore = useLayoutStore(useShallow(state => ({ me: state.me }))) + const { config, setConfig, saveToRemote, loadFromRemote } = useConfigStore(); const handleSubmit = (e: React.FormEvent) => { e.preventDefault(); - const result = configSchema.safeParse(config); - if (result.success) { - toast.success('配置已保存') - setTimeout(() => { - location.reload() - }, 400) - } else { - console.error('验证错误:', result.error.format()); - } + saveToRemote(); }; const handleChange = (field: keyof typeof config, value: string | boolean) => { @@ -105,87 +91,13 @@ export const ConfigPage = () => { /> -
- - handleChange('CNB_CORS_URL', e.target.value)} - placeholder="https://cors.example.com" - /> -
- -
- handleChange('ENABLE_CORS', checked === true)} - /> - -
- -
- - handleChange('AI_BASE_URL', e.target.value)} - placeholder="请输入 AI 基础地址" - /> -
- -
- - handleChange('AI_MODEL', e.target.value)} - placeholder="请输入 AI 模型名称" - /> -
- -
-
- - - - - - -

- 如果使用 CNB 的 AI,密钥和 API 密钥一样即可 -

-
-
-
- handleChange('AI_API_KEY', e.target.value)} - placeholder="请输入您的 AI API 密钥" - /> -
-
- - + - {layoutStore.me && <> - - - - }
diff --git a/src/pages/config/store/index.ts b/src/pages/config/store/index.ts index 95af886..2ba49b0 100644 --- a/src/pages/config/store/index.ts +++ b/src/pages/config/store/index.ts @@ -1,6 +1,6 @@ import { create } from 'zustand'; import { persist } from 'zustand/middleware'; -import type { Config, defaultConfig } from './schema'; +import type { Config, } from './schema'; import { queryLogin } from '@/modules/query'; import { toast } from 'sonner'; @@ -18,11 +18,6 @@ const STORAGE_KEY = 'cnb-config'; const DEFAULT_CONFIG = { CNB_API_KEY: '', CNB_COOKIE: '', - CNB_CORS_URL: 'https://cors.kevisual.cn', - ENABLE_CORS: true, - AI_BASE_URL: 'https://api.cnb.cool/kevisual/cnb-ai/-/ai/', - AI_MODEL: 'CNB-Models', - AI_API_KEY: '' } const loadInitialConfig = (): Config => { try { diff --git a/src/pages/config/store/schema.ts b/src/pages/config/store/schema.ts index 68f8cbc..9ca8478 100644 --- a/src/pages/config/store/schema.ts +++ b/src/pages/config/store/schema.ts @@ -3,11 +3,6 @@ import { z } from 'zod'; export const configSchema = z.object({ CNB_API_KEY: z.string().min(1, 'API Key is required'), CNB_COOKIE: z.string().min(1, 'Cookie is required'), - CNB_CORS_URL: z.url('Must be a valid URL'), - ENABLE_CORS: z.boolean(), - AI_BASE_URL: z.url('Must be a valid URL'), - AI_MODEL: z.string().min(1, 'AI Model is required'), - AI_API_KEY: z.string().min(1, 'AI API Key is required'), }); export type Config = z.infer; @@ -15,9 +10,4 @@ export type Config = z.infer; export const defaultConfig: Config = { CNB_API_KEY: '', CNB_COOKIE: '', - CNB_CORS_URL: 'https://cors.kevisual.cn', - ENABLE_CORS: true, - AI_BASE_URL: '', - AI_MODEL: '', - AI_API_KEY: '' }; diff --git a/src/pages/repos/components/RepoCard.tsx b/src/pages/repos/components/RepoCard.tsx index 4da44ea..5b40991 100644 --- a/src/pages/repos/components/RepoCard.tsx +++ b/src/pages/repos/components/RepoCard.tsx @@ -18,7 +18,7 @@ import { useRepoStore } from '../store' import { useMemo, useState } from 'react' import { useShallow } from 'zustand/shallow' import { myOrgs } from '../store/build' -import { app, cnb } from '@/agents/app' +import { app } from '@/agents/app' import { toast } from 'sonner' import { useNavigate } from '@tanstack/react-router' import clsx from 'clsx' diff --git a/src/pages/repos/modules/EditRepoDialog.tsx b/src/pages/repos/modules/EditRepoDialog.tsx index 9cbd2c4..eb84300 100644 --- a/src/pages/repos/modules/EditRepoDialog.tsx +++ b/src/pages/repos/modules/EditRepoDialog.tsx @@ -64,7 +64,7 @@ export function EditRepoDialog({ open, onOpenChange, repo }: EditRepoDialogProps path: repo.path, description: data.description?.trim() || '', site: data.site?.trim() || '', - topics: tags.join(','), + topics: tags as any, license: data.license?.trim() || '', }) diff --git a/src/pages/repos/store/index.ts b/src/pages/repos/store/index.ts index 3883ccf..acc6a14 100644 --- a/src/pages/repos/store/index.ts +++ b/src/pages/repos/store/index.ts @@ -1,11 +1,10 @@ import { create } from 'zustand'; import { query } from '@/modules/query'; import { toast } from 'sonner'; -import { cnb } from '@/agents/app' +import { queryApi as cnbApi } from '@/modules/cnb-api' import { WorkspaceInfo } from '@kevisual/cnb' import { createBuildConfig, createCommitBlankConfig, createDevConfig } from './build'; import { useLayoutStore } from '@/pages/auth/store'; -import { useConfigStore } from '@/pages/config/store'; interface DisplayModule { activity: boolean; contributors: boolean; @@ -77,7 +76,7 @@ type State = { showCreateDialog: boolean; setShowCreateDialog: (show: boolean) => void; getList: (params?: { search?: string }, silent?: boolean) => Promise; - updateRepoInfo: (data: Partial) => Promise; + updateRepoInfo: (data: Partial) => Promise; createRepo: (data: { visibility: any, path: string, description: string, license: string }) => Promise; deleteItem: (repo: string) => Promise; workspaceList: WorkspaceInfo[]; @@ -236,9 +235,10 @@ export const useRepoStore = create((set, get) => { toast.error('请先保存构建配置'); return; } - const res = await cnb.build.startBuild(config.repo, { + const res = await cnbApi.cnb['cloud-build']({ + repo: config.repo, branch: config.branch, - env: {}, + env: {} as any, event: config.event, config: config.config, }) @@ -252,7 +252,7 @@ export const useRepoStore = create((set, get) => { const { setLoading } = get(); setLoading(true); try { - const res = await cnb.repo.getRepo(repo) + const res = await cnbApi.cnb['get-repo']({ name: repo }) if (res.code === 200) { const data = res.data!; set({ editRepo: data }) @@ -275,9 +275,9 @@ export const useRepoStore = create((set, get) => { search: params.search } } - const res = await cnb.repo.getRepoList(opts) + const res = await cnbApi.cnb['list-repos'](opts) if (res.code === 200) { - const list = res.data! || [] + const list = res.data?.list || [] set({ list }); } else { toast.error(res.message || '请求失败'); @@ -291,7 +291,7 @@ export const useRepoStore = create((set, get) => { }, updateRepoInfo: async (data) => { const repo = data.path!; - let topics = data.topics?.split?.(','); + let topics = data.topics as string[]; if (Array.isArray(topics)) { topics = topics.map(t => t.trim()).filter(Boolean); } @@ -299,12 +299,12 @@ export const useRepoStore = create((set, get) => { topics.push('cnb-center') } const updateData = { - description: data.description, + description: data.description!, license: data?.license as any, site: data.site, topics: topics } - const res = await cnb.repo.updateRepoInfo(repo, updateData) + const res = await cnbApi.cnb['update-repo-info']({ name: repo, ...updateData }) if (res.code === 200) { toast.success('更新成功'); } else { @@ -314,7 +314,7 @@ export const useRepoStore = create((set, get) => { refresh: async (opts?: { message?: string, showTips?: boolean, search?: string }) => { const getList = get().getList({ search: opts?.search }, true); - + const getWorkspaceList = get().getWorkspaceList(); await Promise.all([getList, getWorkspaceList]); if (opts?.showTips !== false) { @@ -329,7 +329,7 @@ export const useRepoStore = create((set, get) => { description: data.description || '', license: data?.license as any, }; - const res = await cnb.repo.createRepo(createData); + const res = await cnbApi.cnb['create-repo'](createData); console.log('res', res) // if (res.code === 200) { // toast.success('仓库创建成功'); @@ -345,7 +345,7 @@ export const useRepoStore = create((set, get) => { }, deleteItem: async (repo: string) => { try { - const res = await cnb.repo.deleteRepoCookie(repo) + const res = await cnbApi.cnb['delete-repo']({ name: repo }); if (res.code === 200) { toast.success('删除成功'); // 刷新列表 @@ -367,7 +367,8 @@ export const useRepoStore = create((set, get) => { }, workspaceList: [], getWorkspaceList: async () => { - const res = await cnb.workspace.list({ + // const res = await cnb.workspace.list({ + const res = await cnbApi.cnb['list-workspace']({ status: 'running', pageSize: 100 }) @@ -381,9 +382,7 @@ export const useRepoStore = create((set, get) => { startWorkspace: async (data, params = { open: true, branch: 'main' }) => { const repo = data.path; const checkOpen = async () => { - const res = await cnb.workspace.startWorkspace(repo!, { - branch: params.branch || 'main' - }) + const res = await cnbApi.cnb['start-workspace']({ repo: repo!, branch: params.branch || 'main' }); if (res.code === 200) { if (!res?.data?.sn) { const url = res.data?.url! || ''; @@ -456,7 +455,7 @@ export const useRepoStore = create((set, get) => { toast.error('未选择工作区'); return; } - const res = await cnb.workspace.stopWorkspace({ sn }); + const res = await cnbApi.cnb['stop-workspace']({ sn }) // @ts-ignore if (res?.code === 200) { toast.success('工作区已停止'); @@ -469,7 +468,7 @@ export const useRepoStore = create((set, get) => { }, selectWorkspace: undefined, getWorkspaceDetail: async (workspaceInfo) => { - const res = await cnb.workspace.getDetail(workspaceInfo.slug, workspaceInfo.sn) as any; + const res = await cnbApi.cnb['get-workspace']({ repo: workspaceInfo.slug, sn: workspaceInfo.sn }) as any; if (res.code === 200) { set({ workspaceLink: res.data, @@ -488,9 +487,10 @@ export const useRepoStore = create((set, get) => { return; } let event = toRepo ? 'api_trigger_sync_to_gitea' : 'api_trigger_sync_from_gitea'; - const res = await cnb.build.startBuild(repo, { + const res = await cnbApi.cnb['cloud-build']({ + repo: toRepo! || fromRepo!, branch: 'main', - env: {}, + env: {} as any, event: event, config: createBuildConfig({ repo: toRepo! || fromRepo! }), }) @@ -501,9 +501,10 @@ export const useRepoStore = create((set, get) => { } }, buildUpdate: async (data) => { - const res = await cnb.build.startBuild(data.path!, { + const res = await cnbApi.cnb['cloud-build']({ + repo: data.path!, branch: 'main', - env: {}, + env: {} as any, event: 'api_trigger_event', config: createCommitBlankConfig({ repo: data.path!, event: 'api_trigger_event' }), }) diff --git a/src/pages/store/index.ts b/src/pages/store/index.ts deleted file mode 100644 index af2993c..0000000 --- a/src/pages/store/index.ts +++ /dev/null @@ -1,130 +0,0 @@ -import { create } from 'zustand'; -import { query } from '@/modules/query'; -import { toast } from 'sonner'; -import { cnb } from '@/agents/app' - -interface DisplayModule { - activity: boolean; - contributors: boolean; - release: boolean; -} - -interface Languages { - language: string; - color: string; -} - -interface Data { - id: string; - name: string; - freeze: boolean; - status: number; - visibility_level: string; - flags: string; - created_at: string; - updated_at: string; - description: string; - site: string; - topics: string; - license: string; - display_module: DisplayModule; - star_count: number; - fork_count: number; - mark_count: number; - last_updated_at?: string | null; - web_url: string; - path: string; - tags: any; - open_issue_count: number; - open_pull_request_count: number; - languages: Languages; - second_languages: Languages; - last_update_username: string; - last_update_nickname: string; - access: string; - stared: boolean; - star_time: string; - pinned: boolean; - pinned_time: string; -} - -type State = { - formData: Record; - setFormData: (data: Record) => void; - showEdit: boolean; - setShowEdit: (showEdit: boolean) => void; - loading: boolean; - setLoading: (loading: boolean) => void; - list: Data[]; - editRepo: Data | null; - setEditRepo: (repo: Data | null) => void; - showEditDialog: boolean; - setShowEditDialog: (show: boolean) => void; - getList: () => Promise; - updateRepoInfo: (data: Partial) => Promise; -} - -export const useRepoStore = create((set, get) => { - return { - formData: {}, - setFormData: (data) => set({ formData: data }), - showEdit: false, - setShowEdit: (showEdit) => set({ showEdit }), - loading: false, - setLoading: (loading) => set({ loading }), - list: [], - editRepo: null, - setEditRepo: (repo) => set({ editRepo: repo }), - showEditDialog: false, - setShowEditDialog: (show) => set({ showEditDialog: show }), - getItem: async (id) => { - const { setLoading } = get(); - setLoading(true); - try { - const res = await query.post({ - path: 'demo', - key: 'item', - data: { id } - }) - if (res.code === 200) { - return res; - } else { - toast.error(res.message || '请求失败'); - } - } finally { - setLoading(false); - } - }, - getList: async () => { - const { setLoading } = get(); - setLoading(true); - try { - const res = await cnb.repo.getRepoList({}) - if (res.code === 200) { - const list = res.data! || [] - set({ list }); - } else { - toast.error(res.message || '请求失败'); - } - return res; - } finally { - setLoading(false); - } - }, - updateRepoInfo: async (data) => { - const repo = data.path!; - const updateData = { - description: data.description, - license: data?.license as any, - site: data.site, - topics: data.topics?.split?.(','), - } - const res = await cnb.repo.updateRepoInfo(repo, updateData) - if (res.code === 200) { - toast.success('更新成功'); - } else { - toast.error(res.message || '更新失败'); - } - }, - } -}) \ No newline at end of file