coding-tool-x 3.8.8 → 3.8.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (134) hide show
  1. package/README.md +56 -388
  2. package/dist/web/assets/AgentsDrawer-Bam7kBjG.js +1 -0
  3. package/dist/web/assets/Analytics-D5dUWXEa.js +1 -0
  4. package/dist/web/assets/AssetPathField-CLqalYv-.js +1 -0
  5. package/dist/web/assets/{ChatHistoryDrawer-CrfS0KYV.js → ChatHistoryDrawer-C1At65O3.js} +1 -1
  6. package/dist/web/assets/{CollapseItem-ClMsJuUu.js → CollapseItem-CVWojShK.js} +1 -1
  7. package/dist/web/assets/CommandsDrawer-BEoypGBf.js +1 -0
  8. package/dist/web/assets/ConfigExportDrawer-DBvFDDWK.js +1 -0
  9. package/dist/web/assets/ConfigTemplates-BpaWG-iC.js +1 -0
  10. package/dist/web/assets/{ConfigTemplatesDrawer-BqM32Im7.js → ConfigTemplatesDrawer-C2lvyKMf.js} +1 -1
  11. package/dist/web/assets/ConfigTemplatesPanel-CorOY7kY.js +1 -0
  12. package/dist/web/assets/{Divider-DsdbkHrG.js → Divider-BLLhMTSt.js} +1 -1
  13. package/dist/web/assets/FavoritesDrawer-uW88N6te.js +1 -0
  14. package/dist/web/assets/GatewayConvertDrawer-i5Wt9Dd9.js +1 -0
  15. package/dist/web/assets/Home-BIxWvm29.js +1 -0
  16. package/dist/web/assets/{MarkdownEditor-BMMUufSc.js → MarkdownEditor-Ul0bSGj-.js} +1 -1
  17. package/dist/web/assets/McpDrawer-Cc2xq77I.js +1 -0
  18. package/dist/web/assets/McpFormDrawer-DLHX_nrI.js +1 -0
  19. package/dist/web/assets/{PluginManager-C4kJlpVX.js → PluginManager-BGQ0xF2F.js} +1 -1
  20. package/dist/web/assets/{PluginsDrawer-05R4k15x.js → PluginsDrawer-STwHEqiF.js} +1 -1
  21. package/dist/web/assets/PluginsPanel-1zuNP7da.js +1 -0
  22. package/dist/web/assets/ProjectList-VbIYSHbH.css +1 -0
  23. package/dist/web/assets/ProjectList-_pe2nk9c.js +1 -0
  24. package/dist/web/assets/PromptsDrawer-CJN1xZk7.js +1 -0
  25. package/dist/web/assets/RecentSessionsDrawer-DX1HI8Nm.js +1 -0
  26. package/dist/web/assets/SessionCard-Op6PHvi0.js +1 -0
  27. package/dist/web/assets/SessionList-Da_TAEYr.js +1 -0
  28. package/dist/web/assets/SettingsDrawer-DKLd4Sjy.js +1 -0
  29. package/dist/web/assets/{SkillManager-D9jkNuRM.js → SkillManager-PcAa5EbF.js} +1 -1
  30. package/dist/web/assets/{SkillsDrawer-0Z4IefxC.js → SkillsDrawer-DPdU4p6C.js} +1 -1
  31. package/dist/web/assets/SkillsPanel-B9qzRqjd.js +1 -0
  32. package/dist/web/assets/Upload-e1M9Yp5z.js +1 -0
  33. package/dist/web/assets/{WorkspaceDrawer-eujtWpoq.js → WorkspaceDrawer-oS6mB1VZ.js} +1 -1
  34. package/dist/web/assets/{WorkspaceManager-CQ-8Ej68.js → WorkspaceManager-6VvRWe3r.js} +1 -1
  35. package/dist/web/assets/WorkspacePanel-CYq0Z8iY.js +1 -0
  36. package/dist/web/assets/client-BgcNg4Bt.js +1 -0
  37. package/dist/web/assets/headers-DbowkmZJ.js +1 -0
  38. package/dist/web/assets/{icons-DmFe4b5j.js → icons-B-AzZoeE.js} +1 -1
  39. package/dist/web/assets/index-BlUXw84U.js +2 -0
  40. package/dist/web/assets/index-Bn8BUnwP.css +1 -0
  41. package/dist/web/assets/{light-0eavxNvt.js → light-C2X7hegj.js} +1 -1
  42. package/dist/web/assets/platforms-DrzAtnjY.js +1 -0
  43. package/dist/web/assets/platforms-mqqe_82d.js +1 -0
  44. package/dist/web/assets/project-config-BVt5s-pH.js +1 -0
  45. package/dist/web/assets/sessions-53-Fr68H.js +1 -0
  46. package/dist/web/assets/{sessions-D4yQtfKb.js → sessions-CaWUaysM.js} +1 -1
  47. package/dist/web/assets/use-message-DBsCm7FJ.js +1 -0
  48. package/dist/web/assets/{useResponsiveDrawer-DZd5rNk5.js → useResponsiveDrawer-ChHZrTfl.js} +1 -1
  49. package/dist/web/assets/{workspaces-mjyPVGS8.js → workspaces-DQuZd4qw.js} +1 -1
  50. package/dist/web/index.html +8 -8
  51. package/package.json +4 -2
  52. package/src/commands/daemon.js +27 -4
  53. package/src/commands/export-config.js +17 -211
  54. package/src/config/model-metadata.json +180 -16
  55. package/src/platforms/channel-auth-registry.js +36 -6
  56. package/src/platforms/channel-auth-service.js +13 -3
  57. package/src/platforms/commands-service.js +28 -0
  58. package/src/platforms/driver-registry.js +1 -0
  59. package/src/platforms/drivers/claude/channels-implementation.js +79 -90
  60. package/src/platforms/drivers/claude/native-config-implementation.js +3 -4
  61. package/src/platforms/drivers/codex/channels-implementation.js +34 -49
  62. package/src/platforms/drivers/codex/native-config-implementation.js +3 -51
  63. package/src/platforms/drivers/dsh/api-operations.js +1 -1
  64. package/src/platforms/drivers/dsh/channels-implementation.js +28 -8
  65. package/src/platforms/drivers/dsh/channels.js +0 -18
  66. package/src/platforms/drivers/dsh/common.js +7 -0
  67. package/src/platforms/drivers/dsh/native-config.js +7 -2
  68. package/src/platforms/drivers/gemini/channels-implementation.js +47 -55
  69. package/src/platforms/drivers/gemini/native-config-implementation.js +8 -20
  70. package/src/platforms/drivers/generic-native-config.js +20 -0
  71. package/src/platforms/drivers/native-config-snapshot.js +30 -4
  72. package/src/platforms/drivers/omp/channels-implementation.js +51 -17
  73. package/src/platforms/drivers/omp/native-config-implementation.js +10 -17
  74. package/src/platforms/drivers/omp/prompts.js +58 -2
  75. package/src/platforms/drivers/omp/proxy-implementation.js +25 -1
  76. package/src/platforms/drivers/opencode/channels-implementation.js +31 -22
  77. package/src/platforms/drivers/opencode/channels.js +6 -1
  78. package/src/platforms/drivers/opencode/native-config-implementation.js +3 -67
  79. package/src/platforms/manifest-schema.js +35 -2
  80. package/src/platforms/manifests/claude.json +0 -8
  81. package/src/platforms/manifests/codex.json +0 -8
  82. package/src/platforms/manifests/dsh.json +6 -9
  83. package/src/platforms/manifests/gemini.json +0 -8
  84. package/src/platforms/manifests/omp.json +2 -9
  85. package/src/platforms/manifests/opencode.json +28 -8
  86. package/src/platforms/native-oauth-adapters.js +351 -51
  87. package/src/platforms/oauth-credentials-service.js +344 -13
  88. package/src/server/index.js +37 -1
  89. package/src/server/services/bounded-content.js +60 -0
  90. package/src/server/services/channel-balance.js +10 -4
  91. package/src/server/services/config-export-service.js +2 -2
  92. package/src/server/services/config-templates-service.js +5 -1
  93. package/src/server/services/plugins-service.js +162 -85
  94. package/src/server/services/session-history-maintenance-worker.js +71 -0
  95. package/src/server/services/session-history-maintenance.js +166 -0
  96. package/src/server/services/skill-service.js +23 -3
  97. package/src/server/services/speed-test.js +0 -72
  98. package/src/shared/channel-driver.js +16 -0
  99. package/src/shared/driver-factories/api.js +1 -0
  100. package/src/utils/native-config-patcher.js +474 -0
  101. package/dist/web/assets/AgentsDrawer-DRQuwi0m.js +0 -1
  102. package/dist/web/assets/Analytics-Cf5KwEdj.js +0 -1
  103. package/dist/web/assets/AssetPathField-DyniM0pF.js +0 -1
  104. package/dist/web/assets/CommandsDrawer-CzHelf56.js +0 -1
  105. package/dist/web/assets/ConfigExportDrawer-BEZ8wTby.js +0 -1
  106. package/dist/web/assets/ConfigTemplates-Crg3xWe5.js +0 -1
  107. package/dist/web/assets/ConfigTemplatesPanel-lTdutC8H.js +0 -1
  108. package/dist/web/assets/FavoritesDrawer-DDyWUBJR.js +0 -1
  109. package/dist/web/assets/GatewayConvertDrawer-Rigtt_5J.js +0 -1
  110. package/dist/web/assets/Home-tCSKmSHV.js +0 -1
  111. package/dist/web/assets/McpDrawer-CmE-d7VW.js +0 -1
  112. package/dist/web/assets/McpFormDrawer-ByvS18od.js +0 -1
  113. package/dist/web/assets/PluginsPanel-BCoEs7Og.js +0 -1
  114. package/dist/web/assets/ProjectList-BJt1OIaI.js +0 -1
  115. package/dist/web/assets/ProjectList-DG3yu8xZ.css +0 -1
  116. package/dist/web/assets/PromptsDrawer-DnwBf_oW.js +0 -1
  117. package/dist/web/assets/RecentSessionsDrawer-B7d-38wH.js +0 -1
  118. package/dist/web/assets/SessionCard-BUgjHQwX.js +0 -1
  119. package/dist/web/assets/SessionList-B-bXZRFk.js +0 -1
  120. package/dist/web/assets/SettingsDrawer-BITzjQLl.js +0 -1
  121. package/dist/web/assets/SkillsPanel-BKIVOj7n.js +0 -1
  122. package/dist/web/assets/SpeedTestDrawer-Bx1bYf5i.js +0 -1
  123. package/dist/web/assets/SpeedTestDrawer-Dc0WToJ_.css +0 -1
  124. package/dist/web/assets/Upload-CzC4rGI4.js +0 -1
  125. package/dist/web/assets/WorkspacePanel-Cql5qE2R.js +0 -1
  126. package/dist/web/assets/client-UDwXBP9i.js +0 -1
  127. package/dist/web/assets/headers-BqDmkMjy.js +0 -1
  128. package/dist/web/assets/index-Cmmwj3Fx.js +0 -2
  129. package/dist/web/assets/index-Cnbe696C.css +0 -1
  130. package/dist/web/assets/platforms-BmzzwnSw.js +0 -1
  131. package/dist/web/assets/platforms-DWXgmy2w.js +0 -1
  132. package/dist/web/assets/project-config-B2baPzYL.js +0 -1
  133. package/dist/web/assets/sessions-DqlbocLJ.js +0 -1
  134. package/dist/web/assets/use-message-DqCwefG6.js +0 -1
package/README.md CHANGED
@@ -1,441 +1,109 @@
1
1
  # coding-tool-x
2
2
 
3
- > 面向 Claude Code、Codex CLI、Gemini CLI、OpenCode、OMP 的统一增强控制台,并支持通过 Manifest 扩展兼容协议的 Coding CLI
4
- > Web UI + CLI + 多平台代理 + 配置托管 + 工作区编排 + 分析面板
5
-
6
- ![Node.js](https://img.shields.io/badge/Node.js-%3E%3D22.13.0-43853d?style=flat-square)
7
- ![License](https://img.shields.io/badge/License-MIT-blue?style=flat-square)
8
- ![Platforms](https://img.shields.io/badge/Platforms-Registry--driven-1f6feb?style=flat-square)
9
-
10
- ![Home Preview](docs/home.png)
11
-
12
- `coding-tool-x` 把多个 Coding CLI 的常用管理能力收拢到一套界面里: 会话查看、渠道代理、配置同步、工作区组织、MCP / Skills / Commands / Agents / Plugins 管理、OAuth 凭证托管、通知设置、统计分析和配置导入导出。
13
-
14
- 如果你同时在用 Claude Code、Codex CLI、Gemini CLI、OpenCode、OMP,这个项目的目标就是把这些分散在不同目录、不同配置文件、不同命令里的日常操作,尽量放回一个统一入口。
15
-
16
- ## 适合做什么
17
-
18
- - 统一查看已启用平台的项目和会话
19
- - 管理多渠道代理、测速、模型探测和健康状态
20
- - 集中托管 Prompts、Skills、Agents、Commands、MCP、Plugins 等常用配置项
21
- - 为多项目创建工作区,必要时自动创建 Git worktree
22
- - 统一查看请求量、Token、费用趋势与实时日志
23
- - 导入导出整套配置,包含原生配置快照
24
-
25
- ## 功能概览
26
-
27
- ### 会话与项目
28
-
29
- - 支持内置平台及已启用扩展平台的项目与会话列表;具体能力以平台 Manifest 为准
30
- - 支持项目排序、项目搜索、会话排序、会话搜索
31
- - 支持最近会话、收藏、别名、聊天记录查看
32
- - 支持新建会话、删除会话、复制启动命令
33
- - Claude / Codex / Gemini 会话支持格式转换
34
- - 支持将 Claude / Codex / Gemini 请求转换为 OpenCode 网关请求
35
-
36
- ### 多渠道代理
37
-
38
- - 具备渠道能力的平台支持独立代理端口和独立渠道配置
39
- - 支持渠道增删改查、启用 / 停用、权重、并发限制
40
- - 支持速度测试、模型可用性探测、健康检查与故障冻结
41
- - 支持模型重定向和默认测速模型配置
42
- - Web UI 与 CLI 都可查看代理状态和日志
43
-
44
- ### 配置与托管
45
-
46
- - 集中存储在 `~/.cc-tool`
47
- - 保留并同步各平台原生配置目录,而不是替代原生用法
48
- - 支持 Prompts 预设管理,并同步到声明 `prompts` capability 的平台提示文件;具体平台能力以 Manifest 为准
49
- - 支持 Skills、Agents、Commands、Plugins 的中心托管与按支持的平台启停
50
- - OMP Commands 按 OMP 原生语义管理为 slash commands,OMP Plugins 按 packages / extensions 管理
51
- - 支持 MCP 服务器配置、预设、连通性测试和多平台写入;OMP 写入原生 `mcp.json`
52
- - Skill 仓库只保存 source reference;手动刷新时下载仓库中发现的每个 Skill 完整目录,不保存仓库归档或 tree
53
- - 每个 CLI 使用独立的 Skill artifact 格式和目录:`claude-skill-v1`、`codex-skill-v1`、`gemini-skill-v1`、`opencode-skill-v1`、`omp-skill-v1`
54
- - Skill 页面进入、浏览器刷新和页面切换只扫描本地;只有用户点击“刷新远端”才创建异步网络任务
55
- - Skill `enabled` 控制实际 CLI/OMP 加载;关闭只移除 native projection,不删除本地 artifact
56
- - 新下载 Skill 默认 `trust=needs_review`、`enabled=false`,审批前不会进入实际运行面
57
- - 所有扫描到的 Skill 默认登记为 `managed=true`;`managed` 不等于已启用
58
- - OMP 可将提示词同步为原生 prompt templates;MCP/Skill activation、trust 和 secret reference 由同一有效控制面管理
59
- - 支持 Claude、Codex、Gemini、OpenCode 的 OAuth 凭证池管理与回写原生配置;OMP auth 通过原生配置导入导出保留
60
- - 支持 ZIP / JSON 配置导入导出
61
-
62
- ### 工作区与运维
63
-
64
- - 支持多项目工作区
65
- - 支持为 Git 仓库创建 worktree
66
- - 支持配置模板,将提示词、技能、命令、代理、MCP、插件组合成一套模板
67
- - 支持 Dashboard、Analytics、日志、统计导出、环境诊断
68
- - 支持面板访问密码
69
- - LAN 模式默认禁止远程写操作;只有显式设置 `CC_TOOL_ALLOW_REMOTE_WRITE=true` 才允许
70
-
71
- ### 通知
72
-
73
- - 支持 Claude、Codex、Gemini、OpenCode、OMP 的任务完成通知托管
74
- - 支持系统通知、浏览器通知和弹窗模式
75
- - 支持飞书机器人 Webhook 通知
76
-
77
- ## 能力矩阵
78
-
79
- | 能力 | Claude | Codex | Gemini | OpenCode | OMP |
80
- | --- | --- | --- | --- | --- | --- |
81
- | 项目 / 会话查看 | 支持 | 支持 | 支持 | 支持 | 支持 |
82
- | 渠道 / 代理管理 | 支持 | 支持 | 支持 | 支持 | 支持,含余额显示与批量测速 |
83
- | Prompts 预设同步 | 支持 | 支持 | 支持 | 支持 | 不提供集中式提示文件同步 |
84
- | Skills 管理 | 支持 | 支持 | 支持 | 支持 | 原生支持 |
85
- | Commands 管理 | 支持 | 支持 | 支持 | 支持 | 映射为 OMP commands |
86
- | Agents 管理 | 支持 | 用户级 | 支持 | 支持 | 不提供直接原生管理 |
87
- | Plugins 管理 | 支持 | 支持 | - | 支持 | 映射为 packages / extensions |
88
- | MCP 管理 | 支持 | 支持 | 支持 | 支持 | 写入 OMP `mcp.json` |
89
- | OAuth 凭证托管 | 支持 | 支持 | 支持 | 支持 | 原生 auth 导入导出,不提供 OAuth 抽屉托管 |
90
- | 通知托管 | 支持 | 支持 | 支持 | 支持 | 支持 |
91
- | 请求 / 会话统计 | 支持 | 支持 | 支持 | 支持 | 共享统计优先,空时回退到 OMP session usage |
92
-
93
- 补充说明:
94
-
95
- - Codex Agents 目前仅支持用户级代理
96
- - OpenCode 会话读取使用内置 `node:sqlite`,不再依赖本机 sqlite3 可执行文件
97
- - OMP 的原生资源轴包含 skills、commands、prompt templates、packages / extensions 和 MCP `mcp.json`;集中式 Prompts 预设不向 OMP 同步,Agents 暂不作为独立可写配置文件管理
98
- - OMP 平台键统一为 `omp`,不再保留 `omp` 平台键兼容
99
- - OMP OAuth 不在 OAuth Credentials 抽屉中直接增删改;`auth.json` 仍随 Config Export / Import 的 native config 快照迁移
100
-
101
- ## 配置驱动的平台扩展
102
-
103
- - 平台目录由 Registry 统一发布;用户 Manifest 放在 `~/.cc-tool/config/platforms.json`,修改后由服务重新加载。
104
- - 通用 CLI 必须提供有效 Manifest,并且只能使用项目 allowlist 中的通用 capability driver;声明式配置不会自动赋予任意 CLI 完整功能。
105
- - 非标准协议(例如特殊数据库、OAuth / keychain 或平台专有配置语义)必须由专用 capability driver 实现,不能仅靠 Manifest 拼接出等价行为。
106
- - 用户配置禁止加载任意 Node.js 模块、执行函数值或 shell 命令;Manifest 只能引用受控路径和已登记的 driver。
107
- - 现有 CLI/API facade、OMP managed mode、旧的 mock path 和测试 seam 会继续保留;配置驱动扩展不会替换已有平台专用实现。
3
+ > 面向多种 Coding CLI 的本地工作台:统一管理项目与会话、模型渠道、配置资源和使用统计。
108
4
 
109
- ## 安装
110
-
111
- ### 全局安装
112
-
113
- ```bash
114
- npm install -g coding-tool-x
115
- ```
116
-
117
- ### 国内镜像
118
-
119
- ```bash
120
- npm install -g coding-tool-x --registry=https://registry.npmmirror.com
121
- ```
122
-
123
- ### 从源码运行
124
-
125
- ```bash
126
- git clone https://github.com/ZeaoZhang/coding-tool.git
127
- cd coding-tool
128
- npm install
129
- npm run build:web
130
- npm link
131
- ```
5
+ [![npm version](https://img.shields.io/npm/v/coding-tool-x?style=flat-square)](https://www.npmjs.com/package/coding-tool-x)
6
+ [![Node.js](https://img.shields.io/badge/Node.js-%E2%89%A522.13.0-43853d?style=flat-square)](https://nodejs.org/)
7
+ [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg?style=flat-square)](LICENSE)
8
+ [![GitHub issues](https://img.shields.io/github/issues/ZeaoZhang/coding-tool-x?style=flat-square)](https://github.com/ZeaoZhang/coding-tool-x/issues)
132
9
 
133
- - Node.js `>= 22.13.0`
134
- - 建议至少运行过一次目标 CLI,以便生成原生配置目录
135
- - OpenCode 会话使用内置 `node:sqlite`,不再需要系统 sqlite3
10
+ ![coding-tool-x 首页预览](docs/home.png)
136
11
 
137
- ## 快速开始
12
+ `coding-tool-x` 将常用的 Coding CLI 管理功能放在一个本地 Web UI 和 `ctx` 命令行入口中。它支持 Claude Code、Codex CLI、Gemini CLI、OpenCode、OMP 和 DSH;各平台的具体功能取决于其内置 Manifest 和实际可用能力。
138
13
 
139
- ### 推荐方式
14
+ ## 功能
140
15
 
141
- ```bash
142
- ctx start
143
- ctx status
144
- ```
145
-
146
- 启动后默认访问:
147
-
148
- - Web UI: `http://localhost:19999`
16
+ - **OAuth 管理与切换**:同步支持平台的本地 OAuth 凭证,在渠道配置中选择或切换账户、检查授权状态,并查看可用额度。
17
+ - **Token 计数与统计**:跨平台汇总请求数、Token 用量和费用,支持按模型、渠道等维度查看趋势与导出分析数据。
18
+ - **全局与项目配置**:分别管理全局及项目级 Skills、MCP;并集中管理 Prompts、Commands、Agents、Plugins 等资源,按平台能力同步到原生配置。
19
+ - **OMP 与 DSH 服务**:支持独立启停代理服务、查看运行状态,并管理相应渠道与配置;具体能力依平台实现而异。
20
+ - **项目与会话**:跨平台查看项目和会话、搜索历史、收藏会话,并在支持的平台上复制、删除或 Fork 会话。
21
+ - **工作区与扩展**:组织多个项目,支持 Git worktree 和配置模板;也可通过校验后的 Manifest 与内置 capability driver 接入兼容 CLI。
149
22
 
150
- ### 前台运行
151
-
152
- ```bash
153
- ctx ui
154
- ```
23
+ ## 安装
155
24
 
156
- ### 本地 HTTPS
25
+ 需要 Node.js `>=22.13.0`。
157
26
 
158
27
  ```bash
159
- ctx ui --https
28
+ npm install -g coding-tool-x
160
29
  ```
161
30
 
162
- 如需后台运行 HTTPS 版本,可使用 `ctx ui start --https`。
163
-
164
- ### 开启局域网访问
31
+ 中国大陆网络环境也可以使用 npmmirror:
165
32
 
166
33
  ```bash
167
- ctx ui --host
34
+ npm install -g coding-tool-x --registry=https://registry.npmmirror.com
168
35
  ```
169
36
 
170
- LAN 模式说明:
171
-
172
- - 服务会监听 `0.0.0.0`
173
- - 默认禁止 LAN 远程写操作,保护 Skill/MCP/配置控制面
174
- - 如需允许远程写操作,必须显式设置:
37
+ 安装后启动本地服务:
175
38
 
176
39
  ```bash
177
- CC_TOOL_ALLOW_REMOTE_WRITE=true ctx ui --host
40
+ ctx start
178
41
  ```
179
42
 
180
- ### 单独控制平台代理
181
-
182
- ```bash
183
- ctx claude start
184
- ctx codex start
185
- ctx gemini start
186
- ctx opencode start
187
- ctx omp start
188
- ```
43
+ 打开 [http://localhost:19999](http://localhost:19999) 访问 Web UI。首次使用前,请先单独安装并初始化需要管理的 Coding CLI;`coding-tool-x` 不会替代这些 CLI 本身。
189
44
 
190
45
  ## 常用命令
191
46
 
192
- ### 服务
193
-
194
47
  | 命令 | 说明 |
195
48
  | --- | --- |
196
- | `ctx start` | 后台启动整套服务 |
197
- | `ctx stop` | 停止后台服务 |
198
- | `ctx restart` | 重启后台服务 |
199
- | `ctx status` | 查看后台服务状态 |
200
- | `ctx ui` | 前台启动 Web UI |
201
- | `ctx ui --https` | 前台启动本地 HTTPS Web UI |
202
- | `ctx ui start` | 后台启动 Web UI |
203
- | `ctx ui start --https` | 后台启动本地 HTTPS Web UI |
204
- | `ctx ui stop` | 停止后台 Web UI |
205
- | `ctx ui restart` | 重启后台 Web UI |
206
-
207
- ### 平台代理
208
-
209
- | 命令 | 说明 |
210
- | --- | --- |
211
- | `ctx claude start\|stop\|restart\|status` | Claude 代理管理 |
212
- | `ctx codex start\|stop\|restart\|status` | Codex 代理管理 |
213
- | `ctx gemini start\|stop\|restart\|status` | Gemini 代理管理 |
214
- | `ctx opencode start\|stop\|restart\|status` | OpenCode 代理管理 |
215
- | `ctx omp start\|stop\|restart\|status` | OMP 动态切换与单渠道直连管理 |
216
-
217
- ### 日志与统计
218
-
219
- | 命令 | 说明 |
220
- | --- | --- |
221
- | `ctx logs` | 查看所有日志 |
222
- | `ctx logs ui` | 查看 UI 日志 |
223
- | `ctx logs claude` | 查看 Claude 代理日志 |
224
- | `ctx logs omp` | 查看 OMP 相关 UI/server 日志 |
225
- | `ctx logs --follow` | 实时追踪日志 |
226
- | `ctx logs --lines 100` | 查看最近 100 行 |
227
- | `ctx logs --clear` | 清空日志 |
228
- | `ctx stats` | 查看总体统计 |
229
- | `ctx stats claude` | 查看单个平台统计 |
230
- | `ctx stats omp` | 查看 OMP 统计(内部兼容键仍为 `omp`) |
231
- | `ctx stats export` | 导出统计数据 |
232
- | `ctx doctor` | 运行环境诊断 |
233
-
234
- ### 其他
235
-
236
- | 命令 | 说明 |
237
- | --- | --- |
238
- | `ctx update` | 检查并更新版本 |
239
- | `ctx port` | 修改默认端口 |
240
- | `ctx reset` | 重置 `~/.cc-tool` 配置 |
241
- | `ctx security reset` | 关闭面板访问密码 |
242
- | `ctx plugin list` | 查看已安装插件 |
243
- | `ctx plugin install <git-url>` | 从 Git 安装插件 |
244
-
245
- 兼容说明:
246
-
247
- - `ctx proxy start|stop|status` 仍保留为旧入口
248
- - 新用法更推荐 `ctx claude ...`、`ctx codex ...`、`ctx gemini ...`、`ctx opencode ...`、`ctx omp ...`
249
-
250
- ## Web UI 主要模块
251
-
252
- ### Home / Dashboard
253
-
254
- - 五个平台可配置状态卡,默认保持四列展示
255
- - 新启动的平台默认前置展示
256
- - 展示代理状态、今日请求、Token、费用、项目数、会话数
257
-
258
- ### 项目与会话
259
-
260
- - 项目列表、会话列表
261
- - 全局搜索和项目内搜索
262
- - 聊天历史查看
263
- - 收藏、别名、删除、复制启动命令,部分平台支持 Fork
264
-
265
-
266
- #### 项目级配置
267
-
268
- 在项目历史会话页点击“项目配置”,可管理当前项目的项目指令、Skill 和 MCP。
269
- 项目级 Skill 页面只扫描本地 artifact/native roots;远端仓库不会因为打开页面、刷新浏览器或切换项目而拉取。
270
-
271
- 支持的项目级原生位置:
272
-
273
- | 平台 | 项目指令 | 项目 Skills | 项目 MCP |
274
- | --- | --- | --- | --- |
275
- | Claude | `CLAUDE.md` | `.claude/skills/` | `.mcp.json` |
276
- | Codex | `AGENTS.md` | `.agents/skills/`(读取兼容 `.codex/skills/`) | `.codex/config.toml` 的 `[mcp_servers]` |
277
- | Gemini | `GEMINI.md` | `.gemini/skills/` | `.gemini/settings.json` 的 `mcpServers` |
278
- | OpenCode | `.opencode/AGENTS.md`(以平台 Manifest 为准) | `.opencode/skills/` | `.opencode/opencode.json` |
279
- | OMP | 无单独项目指令文件 | `.omp/skills/` | `.omp/mcp.json` |
280
-
281
- 项目 Skill 关闭只移除该项目的 native projection,不删除 artifact;同名项目 Skill 优先于 inherited user Skill。
282
- 平台无法安全投影的 managed project Skill 返回 `projection: unsupported`,不伪造关闭成功。
283
- 静态 MCP 环境变量、Headers 或凭据禁止写入项目 Git;项目 MCP 只允许环境变量引用或 secret reference。
284
- ### 配置管理
285
-
286
- - Prompts
287
- - MCP
288
- - Skills
289
- - Commands
290
- - Agents
291
- - Plugins
292
- - OAuth Credentials
293
- - Config Export / Import
294
-
295
- ### 工作区与模板
296
-
297
- - Workspaces
298
- - Config Templates
299
- - Git worktree 组织
300
-
301
- ### Analytics
302
-
303
- - 多平台统计汇总
304
- - 模型 / 渠道 / 工具维度分析
305
- - 时间范围筛选
306
- - CSV / JSON 导出
307
-
308
- ## 默认端口
309
-
310
- | 服务 | 默认端口 |
311
- | --- | --- |
312
- | Web UI / WebSocket | `19999` |
313
- | Claude Proxy | `20088` |
314
- | Codex Proxy | `20089` |
315
- | Gemini Proxy | `20090` |
316
- | OpenCode Proxy | `20091` |
317
- | OMP Proxy | `20092` |
318
-
319
- 可通过 `ctx port` 修改。
320
-
321
- ## 数据目录
322
-
323
- ### 中央目录
324
-
325
- 默认位于:
326
-
327
- ```text
328
- ~/.cc-tool
329
- ```
330
-
331
- 常见内容:
332
-
333
- - `config/`: 主配置、Prompts、MCP、OAuth、工作区、模板等
334
- - `configs/`: 托管的 skills / commands / agents / plugins
335
- - `storage/`: 渠道、缓存、统计、内部运行数据
336
- - `logs/`: 服务与代理日志
337
- - `plugins/`: 插件安装与插件配置
338
-
339
- ### 原生配置目录
49
+ | `ctx start` | 后台启动服务 |
50
+ | `ctx stop` / `ctx restart` | 停止或重启服务 |
51
+ | `ctx status` | 查看服务状态 |
52
+ | `ctx ui` | 在前台启动 Web UI |
53
+ | `ctx ui --https` | 以前台 HTTPS 模式启动 Web UI |
54
+ | `ctx doctor` | 检查运行环境 |
55
+ | `ctx logs --follow` | 实时查看日志 |
56
+ | `ctx stats` | 查看使用统计 |
57
+ | `ctx update` | 检查并更新 CLI |
340
58
 
341
- 项目会继续读写各平台原生配置:
59
+ 平台代理可通过 `ctx <platform> start|stop|restart|status` 管理,例如 `ctx claude start`、`ctx codex start` 或 `ctx dsh start`。更多命令可运行 `ctx --help` 查看。
342
60
 
343
- - Claude: `~/.claude`
344
- - Codex: `${CODEX_HOME:-~/.codex}`
345
- - Gemini: `~/.gemini`
346
- - OpenCode:
347
- - 配置: `~/.config/opencode`
348
- - 数据: `~/.local/share/opencode`
349
- - OMP: `${OMP_CODING_AGENT_DIR:-~/.omp/agent}`(`OMP_PROFILE` 会落到 `~/.omp/profiles/<name>/agent`)
61
+ ## 网络访问与安全
350
62
 
351
- ## 开发
352
-
353
- ### 安装依赖
63
+ 服务默认只监听本机。使用 `ctx ui --host` 可开启局域网访问;LAN 模式默认禁止远程写操作。如确实需要远程修改配置,可显式设置:
354
64
 
355
65
  ```bash
356
- npm install
66
+ CC_TOOL_ALLOW_REMOTE_WRITE=true ctx ui --host
357
67
  ```
358
68
 
359
- ### 启动前端开发服务器
69
+ OAuth 凭证与项目配置由本地服务管理。请勿将密钥写入项目仓库或公开分享日志、配置导出文件。Skills、MCP 和项目级配置的具体行为见 [变更日志](CHANGELOG.md)。
360
70
 
361
- ```bash
362
- npm run dev:web
363
- ```
71
+ ## 数据与配置
364
72
 
365
- ### 启动后端开发模式
73
+ 应用数据默认保存在 `~/.cc-tool`。`coding-tool-x` 会读取或更新各 CLI 自己的原生配置;例如 Claude 使用 `~/.claude`、Codex 使用 `${CODEX_HOME:-~/.codex}`。原生目录和支持能力因平台而异。
366
74
 
367
- ```bash
368
- npm run dev:server
369
- ```
75
+ 平台 Manifest 位于 `~/.cc-tool/config/platforms.json`,原生路径覆盖位于 `~/.cc-tool/config/platform-paths.json`。扩展 Manifest 只能引用项目内置的 allowlisted driver,不支持加载任意 Node.js 模块或执行 shell 命令。
370
76
 
371
- ### 构建前端
77
+ ## 从源码运行
372
78
 
373
79
  ```bash
80
+ git clone https://github.com/ZeaoZhang/coding-tool-x.git
81
+ cd coding-tool-x
82
+ npm install
374
83
  npm run build:web
84
+ npm link
375
85
  ```
376
86
 
377
- ### 运行测试
87
+ 开发命令:
378
88
 
379
89
  ```bash
380
- npm test
90
+ npm run dev:server # 后端开发模式
91
+ npm run dev:web # 前端开发服务器
92
+ npm run build:web # 构建前端
93
+ npm test # 运行项目测试
381
94
  ```
382
95
 
383
- 当前仓库内置了基础命令、API 一致性、Codex Agents、Skills Provider、插件市场缓存等相关回归测试。
384
-
385
- ## 已知说明
96
+ ## 文档与支持
386
97
 
387
- - `ctx ui --host` 开启 LAN 访问后默认禁止远程写操作;只有显式设置 `CC_TOOL_ALLOW_REMOTE_WRITE=true` 才允许
388
- - Skill refresh 是异步网络任务;打开 Skill 面板、刷新浏览器和切换页面只扫描本地
389
- - Skill `enabled` 控制实际 CLI/OMP 加载;关闭不会删除 artifact;新远端 Skill 默认 needs_review/disabled
390
- - MCP/Skill 的 secret 不写入 control manifest、项目 Git、任务状态、日志或 API 响应
391
- - 项目 native Skill/MCP 若平台无法安全表达开关,会返回 `projection: unsupported` 或 `external`,不伪造关闭成功
392
-
393
- ## 可配置 CLI 平台
394
-
395
- 平台目录由 Registry 统一提供。用户扩展写入:
396
-
397
- ```text
398
- ~/.cc-tool/config/platforms.json
399
- ```
400
-
401
- 每个平台必须通过 Manifest 校验,并只能引用内置 allowlisted driver(例如 `generic-jsonl`、`generic-filesystem` 或 `generic-openai-compatible`)。配置文件不支持任意 Node.js 模块、`require`、函数值或 shell 命令;运行时不会从用户配置动态加载可执行代码。
402
-
403
- 声明稳定文件协议的平台可以直接复用 generic driver。特殊 SQLite schema、OAuth / keychain、非标准配置或特殊 fork 语义仍需要专用 capability driver;不能仅靠配置保证任意 CLI 获得完整功能对等。
404
-
405
- 现有 `ctx claude ...`、`ctx codex ...` 等 CLI/API 路径继续保留。`GET /api/platforms` 只返回安全的公共元数据;旧 facade、`require.resolve()` + `require.cache` 测试 seam 以及 OMP managed mode 都是有意保留的兼容契约。
406
-
407
- ### 原生路径覆盖
408
-
409
- 原生路径可以单独写入 `~/.cc-tool/config/platform-paths.json`,不需要修改平台 Manifest。路径配置只覆盖 `paths`,不会改变平台能力、Driver 或命令定义:
410
-
411
- ```json
412
- {
413
- "platforms": {
414
- "demo-cli": {
415
- "paths": {
416
- "home": "/opt/demo-cli",
417
- "sessions": "/opt/demo-cli/history",
418
- "settings": "/opt/demo-cli/settings.json",
419
- "channels": "/opt/demo-cli/cc-tool/channels.json"
420
- }
421
- }
422
- }
423
- }
424
- ```
425
-
426
- 路径值支持 `{home}` 和 `$ENV_VAR`;内置平台未配置覆盖时继续使用原有默认目录。配置变化不会自动搬迁已有数据;无效覆盖文件会被忽略并记录诊断信息。
427
-
428
- ## 相关文档
429
-
430
- - [CHANGELOG.md](CHANGELOG.md)
431
- - [docs/multi-channel-load-balancing.md](docs/multi-channel-load-balancing.md)
432
- - [src/web/README.md](src/web/README.md)
98
+ - [GitHub Releases](https://github.com/ZeaoZhang/coding-tool-x/releases)
99
+ - [变更日志](CHANGELOG.md)
100
+ - [多渠道负载均衡说明](docs/multi-channel-load-balancing.md)
101
+ - [报告问题或提出功能建议](https://github.com/ZeaoZhang/coding-tool-x/issues)
102
+ - [npm 包](https://www.npmjs.com/package/coding-tool-x)
433
103
 
434
104
  ## 致谢
435
105
 
436
- 特别感谢 [CooperJiang/coding-tool](https://github.com/CooperJiang/coding-tool) 提供的项目基础。`coding-tool-x` 在原有能力之上持续扩展,补齐了多平台支持、配置同步、扩展管理、工作区编排与分析面板等增强能力;没有上游项目打下的基础,这个增强型分支也很难持续演进。
437
-
438
- 也感谢所有在使用、反馈、测试和持续完善这个分支过程中提供帮助的贡献者与用户。正是这些真实场景下的需求、问题和建议,让这个项目逐步从单一工具发展成更完整的 Coding CLI 工作台。
106
+ 本项目基于 [CooperJiang/coding-tool](https://github.com/CooperJiang/coding-tool) 持续扩展。感谢上游项目以及所有提供反馈、测试和贡献的用户。
439
107
 
440
108
  ## License
441
109
 
@@ -0,0 +1 @@
1
+ import{i as e,s as a,t as l}from"./_plugin-vue_export-helper-BeLZJZij.js";import{C as t,D as s,K as n,O as i,S as o,V as u,W as c,Y as d,Z as r,_t as p,b as v,et as f,g,ht as m,m as y,mt as h,r as b,st as k,w as _,x as w}from"./vue-vendor-BqZbbXHA.js";import{t as C}from"./client-BgcNg4Bt.js";import{r as j,s as x,t as M}from"./platforms-mqqe_82d.js";import{$ as z,At as P,Nt as N,O as U,R as I,S as $,V as F,_ as O,f as B,g as L,j as D,m as S}from"./icons-B-AzZoeE.js";import{l as q}from"./light-C2X7hegj.js";import{a as R,c as A,i as T,o as E,r as V,s as G,t as H}from"./AssetPathField-CLqalYv-.js";import{n as W,t as Y}from"./useResponsiveDrawer-ChHZrTfl.js";import{t as Z}from"./DrawerContent-ChXgZ1Xm.js";import{$ as K,Et as X,I as J,L as Q,M as ee,T as ae,X as le,Y as te,Z as se,ct as ne,ft as ie,j as oe,k as ue,st as ce,ut as de,w as re}from"./index-BlUXw84U.js";import{t as pe}from"./MarkdownEditor-Ul0bSGj-.js";async function ve(e=null,a="claude",l={}){const t=re("agents",a,l.scope||"",e||"");return ae(t,l=>C.get("/agents",{params:e?{projectPath:e,platform:a}:{platform:a},signal:l}).then(e=>e.data),"agents",`agents:${a}`)}var fe={class:"asset-card-main"},ge={class:"asset-card-top"},me={class:"asset-card-title-stack"},ye={class:"asset-card-title-row"},he={class:"asset-name"},be={class:"asset-tags"},ke={key:0,class:"asset-description"},_e={class:"asset-meta"},we={key:0,class:"asset-meta-item"},Ce={key:1,class:"asset-meta-item"},je={class:"asset-card-actions"},xe={class:"asset-platform-strip"},Me=["onClick"],ze=l({__name:"AgentCard",props:{agent:{type:Object,required:!0},deleting:{type:Boolean,default:!1},registryInfo:{type:Object,default:null},toggling:{type:Boolean,default:!1}},emits:["click","edit","delete","toggle-enabled","toggle-platform"],setup(l,{emit:u}){const r=l,b=u,{byCapability:k}=X(),C=v(()=>k("agents"));return(u,v)=>{return c(),_("div",{class:m(["agent-card asset-card",{"is-project":"project"===l.agent.scope,"is-managed":l.registryInfo}]),onClick:v[4]||(v[4]=e=>b("click",l.agent))},[w("div",fe,[w("div",ge,[w("div",me,[w("div",ye,[w("span",{class:m(["asset-status-dot",{active:l.registryInfo?.enabled||"project"===l.agent.scope}])},null,2),w("span",he,p(l.agent.name),1)]),w("div",be,[i(h(de),{type:"user"===l.agent.scope?"info":"success",size:"tiny",bordered:!1},{default:f(()=>[s(p("user"===l.agent.scope?"用户级":"项目级"),1)]),_:1},8,["type"]),l.registryInfo?(c(),o(h(de),{key:0,type:"success",size:"tiny",bordered:!1},{default:f(()=>[...v[5]||(v[5]=[s("托管",-1)])]),_:1})):t("",!0),l.agent.model?(c(),o(h(de),{key:1,type:"warning",size:"tiny",bordered:!1},{default:f(()=>[s(p(l.agent.model),1)]),_:1})):t("",!0)])])]),l.agent.description?(c(),_("div",ke,p((j=l.agent.description,j?j.length>80?j.slice(0,80)+"...":j:"")),1)):t("",!0),w("div",_e,[l.agent.tools?(c(),_("span",we,[i(h(e),{size:"12"},{default:f(()=>[i(h(F))]),_:1}),s(" "+p((k=l.agent.tools,k?k.length>30?k.slice(0,30)+"...":k:"")),1)])):t("",!0),l.agent.permissionMode?(c(),_("span",Ce,[i(h(e),{size:"12"},{default:f(()=>[i(h(B))]),_:1}),s(" "+p(l.agent.permissionMode),1)])):t("",!0)])]),w("div",je,[l.registryInfo?(c(),_(g,{key:0},[i(h(te),{trigger:"hover"},{trigger:f(()=>[i(h(oe),{value:l.registryInfo.enabled,size:"small",loading:l.toggling,"onUpdate:value":v[0]||(v[0]=e=>b("toggle-enabled",l.agent,e)),onClick:v[1]||(v[1]=y(()=>{},["stop"]))},null,8,["value","loading"])]),default:f(()=>[s(" "+p(l.registryInfo.enabled?"已启用":"已禁用"),1)]),_:1}),w("div",xe,[(c(!0),_(g,null,n(C.value,a=>(c(),o(h(te),{key:a.key,trigger:"hover"},{trigger:f(()=>[w("span",{class:m(["asset-platform-icon",{active:l.registryInfo.platforms?.[a.key]}]),onClick:y(e=>b("toggle-platform",l.agent,a.key,!l.registryInfo.platforms?.[a.key]),["stop"])},[i(h(e),{size:"14"},{default:f(()=>[(c(),o(d(a.icon)))]),_:2},1024)],10,Me)]),default:f(()=>[s(" "+p(a.label||a.title||a.key)+" "+p(l.registryInfo.platforms?.[a.key]?"已启用":"未启用"),1)]),_:2},1024))),128))])],64)):(c(),_(g,{key:1},[i(h(a),{size:"tiny",tertiary:"",onClick:v[2]||(v[2]=y(e=>b("edit",l.agent),["stop"]))},{default:f(()=>[...v[6]||(v[6]=[s(" 编辑 ",-1)])]),_:1}),i(h(a),{size:"tiny",tertiary:"",type:"error",loading:r.deleting,onClick:v[3]||(v[3]=y(e=>b("delete",l.agent),["stop"]))},{default:f(()=>[...v[7]||(v[7]=[s(" 删除 ",-1)])]),_:1},8,["loading"])],64))])],2);var k,j}}},[["__scopeId","data-v-044e4192"]]),Pe={class:"asset-detail-drawer-header"},Ne={class:"asset-detail-identity"},Ue={class:"asset-detail-heading"},Ie={class:"asset-detail-name"},$e={class:"asset-detail-meta"},Fe={key:2,class:"asset-detail-subtle"},Oe={class:"asset-detail-body"},Be={key:0,class:"asset-detail-loading"},Le={class:"asset-detail-container"},De={class:"asset-detail-info-section"},Se={class:"asset-detail-description"},qe={class:"asset-detail-info-section"},Re={class:"asset-detail-list"},Ae={class:"asset-detail-row"},Te={class:"asset-detail-value"},Ee={key:0,class:"asset-detail-row"},Ve={class:"asset-detail-value mono"},Ge={key:1,class:"asset-detail-row"},He={class:"asset-detail-value mono"},We={key:2,class:"asset-detail-row"},Ye={class:"asset-detail-value"},Ze={key:3,class:"asset-detail-row"},Ke={class:"asset-detail-value"},Xe={key:4,class:"asset-detail-row"},Je={class:"asset-detail-value"},Qe={key:1,class:"asset-detail-info-section"},ea={class:"asset-detail-box"},aa={class:"asset-detail-code"},la={key:2,class:"asset-detail-empty"},ta={__name:"AgentDetailDrawer",props:{visible:{type:Boolean,default:!1},agent:{type:Object,default:null},platform:{type:String,default:"claude"},loading:{type:Boolean,default:!1}},emits:["update:visible"],setup(a,{emit:l}){const{drawerWidth:n}=Y(600),u=a,d=l,r=v({get:()=>u.visible,set:e=>d("update:visible",e)}),g={height:"100%",minHeight:0,overflow:"hidden"},m=v(()=>({claude:"Claude Code",codex:"Codex CLI",gemini:"Gemini CLI",opencode:"OpenCode"}[u.platform]||"")),y=v(()=>u.agent?.fileName?"codex"===u.platform?`[agents.${u.agent.fileName}]`:`${u.agent.fileName}.md`:""),b=v(()=>u.agent?"codex"===u.platform?u.agent.fullContent||"(无内容)":u.agent.systemPrompt||"(无内容)":"(无内容)"),k=v(()=>u.agent?.fullPath||u.agent?.path||"");function C(e){return"project"===e?"项目级":"用户级"}return(l,u)=>(c(),o(h(W),{show:r.value,"onUpdate:show":u[0]||(u[0]=e=>r.value=e),width:h(n),placement:"right","show-mask":!0},{default:f(()=>[i(h(Z),{closable:"","native-scrollbar":!1,"body-content-style":g},{header:f(()=>[w("div",Pe,[w("div",Ne,[i(h(e),{size:20,class:"asset-detail-icon"},{default:f(()=>[i(h(U))]),_:1}),w("div",Ue,[w("span",Ie,p(a.agent?.name||"代理详情"),1),w("div",$e,[a.agent?.scope?(c(),o(h(de),{key:0,type:"project"===a.agent.scope?"success":"info",size:"tiny",bordered:!1},{default:f(()=>[s(p(C(a.agent.scope)),1)]),_:1},8,["type"])):t("",!0),a.agent?.model?(c(),o(h(de),{key:1,type:"warning",size:"tiny",bordered:!1},{default:f(()=>[s(p(a.agent.model),1)]),_:1})):t("",!0),m.value?(c(),_("span",Fe,p(m.value),1)):t("",!0)])])])])]),default:f(()=>[w("div",Oe,[a.loading&&!a.agent?(c(),_("div",Be,[i(h(ee),{size:"medium"}),u[1]||(u[1]=w("p",null,"加载代理详情中...",-1))])):a.agent?(c(),o(h(G),{key:1,type:"line",animated:"",class:"asset-detail-tabs"},{default:f(()=>[i(h(A),{name:"overview",tab:"概览"},{default:f(()=>[w("div",Le,["codex"===a.platform&&a.agent.configReadError?(c(),o(h(ne),{key:0,type:"warning",bordered:!1},{default:f(()=>[s(p(a.agent.configReadError),1)]),_:1})):t("",!0),w("div",De,[u[2]||(u[2]=w("h3",{class:"asset-detail-section-title"},"描述",-1)),w("p",Se,p(a.agent.description||"暂无描述"),1)]),w("div",qe,[u[9]||(u[9]=w("h3",{class:"asset-detail-section-title"},"基础信息",-1)),w("div",Re,[w("div",Ae,[u[3]||(u[3]=w("span",{class:"asset-detail-label"},"作用域",-1)),w("span",Te,p(C(a.agent.scope)),1)]),a.agent.fileName?(c(),_("div",Ee,[u[4]||(u[4]=w("span",{class:"asset-detail-label"},"文件名",-1)),w("span",Ve,p(y.value),1)])):t("",!0),"codex"===a.platform&&a.agent.configFile?(c(),_("div",Ge,[u[5]||(u[5]=w("span",{class:"asset-detail-label"},"config_file",-1)),w("span",He,p(a.agent.configFile),1)])):t("",!0),a.agent.model?(c(),_("div",We,[u[6]||(u[6]=w("span",{class:"asset-detail-label"},"模型",-1)),w("span",Ye,p(a.agent.model),1)])):t("",!0),a.agent.permissionMode?(c(),_("div",Ze,[u[7]||(u[7]=w("span",{class:"asset-detail-label"},"权限模式",-1)),w("span",Ke,p(a.agent.permissionMode),1)])):t("",!0),a.agent.skills?(c(),_("div",Xe,[u[8]||(u[8]=w("span",{class:"asset-detail-label"},"技能",-1)),w("span",Je,p(a.agent.skills),1)])):t("",!0)])]),a.agent.tools?(c(),_("div",Qe,[u[10]||(u[10]=w("h3",{class:"asset-detail-section-title"},"可用工具",-1)),w("div",ea,[i(h(e),{size:16},{default:f(()=>[i(h(F))]),_:1}),w("code",null,p(a.agent.tools),1)])])):t("",!0),i(H,{path:k.value},null,8,["path"])])]),_:1}),i(h(A),{name:"content",tab:"codex"===a.platform?"配置":"提示词"},{default:f(()=>[w("pre",aa,p(b.value),1)]),_:1},8,["tab"])]),_:1})):(c(),_("div",la,[i(h(e),{size:44,class:"asset-detail-empty-icon"},{default:f(()=>[i(h(z))]),_:1}),u[11]||(u[11]=w("p",null,"未选择代理",-1))]))])]),_:1})]),_:1},8,["show","width"]))}},sa={class:"config-edit-header"},na={class:"config-edit-identity"},ia={class:"config-edit-icon"},oa={class:"config-edit-title-stack"},ua={class:"config-edit-kicker"},ca={class:"config-edit-title"},da={class:"config-edit-badges"},ra={class:"config-edit-section"},pa={class:"section-heading"},va={class:"field-grid"},fa={class:"scope-option"},ga={class:"scope-path"},ma={class:"scope-option"},ya={class:"scope-path"},ha={key:0,class:"platform-note"},ba={class:"config-edit-section"},ka={class:"section-heading"},_a={key:1,class:"empty-config-box"},wa={class:"field-grid"},Ca={key:0,class:"config-edit-section content-section"},ja={class:"section-heading"},xa={class:"modal-footer"},Ma=l({__name:"AgentFormModal",props:{visible:{type:Boolean,default:!1},agent:{type:Object,default:null},projectPath:{type:String,default:null},platform:{type:String,default:"claude"}},emits:["update:visible","saved"],setup(l,{emit:n}){const u=l,d=n,y=v({get:()=>u.visible,set:e=>d("update:visible",e)}),b=v(()=>!!u.agent),j=v(()=>"codex"===u.platform),x=v(()=>"claude"===u.platform),M=v(()=>"codex"===u.platform||"opencode"===u.platform),P=v(()=>b.value?"编辑代理":"创建代理"),N=v(()=>({claude:"Claude Code",codex:"Codex CLI",gemini:"Gemini CLI",opencode:"OpenCode"}[u.platform]||"Claude Code")),$=v(()=>"codex"===u.platform?"~/.codex/config.toml":"opencode"===u.platform?"~/.config/opencode/agents/":"gemini"===u.platform?"~/.gemini/agents/":"~/.claude/agents/"),F=v(()=>"opencode"===u.platform?".opencode/agents/":"gemini"===u.platform?".gemini/agents/":".claude/agents/"),B=v(()=>"project"===H.value.scope?"项目级":"用户级"),L=v(()=>G.find(e=>e.value===H.value.configMode)?.label||"配置"),R=k(null),A=k(!1),T={maxHeight:"calc(92vh - 134px)",overflowY:"auto",paddingBottom:"18px"},E=[{label:"Sonnet",value:"sonnet"},{label:"Opus",value:"opus"},{label:"Haiku",value:"haiku"},{label:"继承 (inherit)",value:"inherit"}],V=[{label:"默认 (default)",value:"default"},{label:"宽松 (permissive)",value:"permissive"},{label:"严格 (strict)",value:"strict"}],G=[{label:"仅描述",value:"none"},{label:"托管 TOML",value:"managed"},{label:"自定义路径",value:"custom"}],H=k({fileName:"",scope:"user",name:"",description:"",configMode:"none",configFile:"",configContent:"",tools:"",model:"",permissionMode:"",skills:"",systemPrompt:""}),W=v(()=>{const e={fileName:{required:!0,message:"请输入文件名",trigger:"blur"},scope:{required:!0,message:"请选择作用域",trigger:"change"},description:{required:!0,message:"请输入代理描述",trigger:"blur"}};return x.value&&(e.name={required:!0,message:"请输入代理名称",trigger:"blur"}),j.value&&(e.configMode={required:!0,message:"请选择配置模式",trigger:"change"},e.configFile={required:"custom"===H.value.configMode,message:"请输入自定义配置文件路径",trigger:"blur"}),e});function Y(){H.value={fileName:"",scope:"user",name:"",description:"",configMode:"none",configFile:"",configContent:"",tools:"",model:"",permissionMode:"",skills:"",systemPrompt:""}}function Z(){y.value=!1,Y()}async function X(){try{await(R.value?.validate())}catch{return}A.value=!0;try{const e={...H.value,projectPath:u.projectPath};j.value?("custom"===H.value.configMode?e.configFile=H.value.configFile:delete e.configFile,"managed"===H.value.configMode||"custom"===H.value.configMode?e.configContent=H.value.configContent||"":delete e.configContent):(delete e.configMode,delete e.configFile,delete e.configContent),b.value?(await async function(e,a,l,t="claude"){return(await C.put(`/agents/${a}/${e}`,{...l,platform:t})).data}(H.value.fileName,H.value.scope,e,u.platform),ue.success("代理更新成功")):(await async function(e,a="claude"){return(await C.post("/agents",{...e,platform:a})).data}(e,u.platform),ue.success("代理创建成功")),d("saved"),y.value=!1,Y()}catch(e){ue.error("操作失败: "+e.message)}finally{A.value=!1}}return r(()=>u.agent,e=>{if(e){const a=e.configMode||(e.configFile?String(e.configFile).includes("/.codex/agents/")?"managed":"custom":"none");H.value={fileName:e.fileName||"",scope:e.scope||"user",name:e.name||"",description:e.description||"",configMode:a,configFile:e.configFile||"",configContent:e.fullContent||"",tools:e.tools||"",model:e.model||"",permissionMode:e.permissionMode||"",skills:e.skills||"",systemPrompt:e.systemPrompt||""}}else Y()},{immediate:!0}),r(()=>u.platform,e=>{"codex"===e&&(H.value.scope="user",H.value.configMode||(H.value.configMode="none"))},{immediate:!0}),(l,n)=>(c(),o(h(q),{show:y.value,"onUpdate:show":n[13]||(n[13]=e=>y.value=e),preset:"card",title:P.value,style:{width:"min(940px, 96vw)","max-height":"92vh"},"content-style":T,"mask-closable":!1,class:"config-edit-modal"},{footer:f(()=>[w("div",xa,[i(h(a),{onClick:Z},{default:f(()=>[...n[21]||(n[21]=[s("取消",-1)])]),_:1}),i(h(a),{type:"primary",loading:A.value,onClick:X},{icon:f(()=>[i(h(e),null,{default:f(()=>[i(h(O))]),_:1})]),default:f(()=>[s(" "+p(b.value?"保存":"创建"),1)]),_:1},8,["loading"])])]),default:f(()=>[w("div",sa,[w("div",na,[w("span",ia,[i(h(e),{size:22},{default:f(()=>[i(h(U))]),_:1})]),w("div",oa,[w("span",ua,p(N.value),1),w("span",ca,p(b.value?H.value.fileName||"编辑代理":"创建新代理"),1)])]),w("div",da,[i(h(de),{size:"small",bordered:!1,type:"info"},{default:f(()=>[s(p(B.value),1)]),_:1}),j.value?(c(),o(h(de),{key:0,size:"small",bordered:!1,type:"success"},{default:f(()=>[...n[14]||(n[14]=[s("Codex 用户级",-1)])]),_:1})):t("",!0),j.value&&"none"!==H.value.configMode?(c(),o(h(de),{key:1,size:"small",bordered:!1,type:"warning"},{default:f(()=>[s(p(L.value),1)]),_:1})):t("",!0)])]),i(h(Q),{ref_key:"formRef",ref:R,model:H.value,rules:W.value,"label-placement":"top","require-mark-placement":"right-hanging",class:"config-edit-form"},{default:f(()=>[w("div",{class:m(["config-edit-grid",{"is-codex":j.value}])},[w("section",ra,[w("div",pa,[i(h(e),{size:16},{default:f(()=>[i(h(D))]),_:1}),n[15]||(n[15]=w("span",null,"基础信息",-1))]),w("div",va,[i(h(J),{label:"文件名",path:"fileName"},{default:f(()=>[i(h(ce),{value:H.value.fileName,"onUpdate:value":n[0]||(n[0]=e=>H.value.fileName=e),disabled:b.value,placeholder:"code-reviewer"},null,8,["value","disabled"])]),_:1}),x.value?(c(),o(h(J),{key:0,label:"显示名称",path:"name"},{default:f(()=>[i(h(ce),{value:H.value.name,"onUpdate:value":n[1]||(n[1]=e=>H.value.name=e),placeholder:"代理的显示名称"},null,8,["value"])]),_:1})):t("",!0)]),i(h(J),{label:"作用域",path:"scope"},{default:f(()=>[i(h(le),{value:H.value.scope,"onUpdate:value":n[2]||(n[2]=e=>H.value.scope=e),disabled:b.value,class:m(["scope-picker",{"single-option":j.value}])},{default:f(()=>[i(h(se),{value:"user"},{default:f(()=>[w("span",fa,[n[16]||(n[16]=w("span",{class:"scope-title"},"用户级",-1)),w("span",ga,p($.value),1)])]),_:1}),j.value?t("",!0):(c(),o(h(se),{key:0,value:"project"},{default:f(()=>[w("span",ma,[n[17]||(n[17]=w("span",{class:"scope-title"},"项目级",-1)),w("span",ya,p(F.value),1)])]),_:1}))]),_:1},8,["value","disabled","class"])]),_:1}),i(h(J),{label:"描述",path:"description"},{default:f(()=>[i(h(ce),{value:H.value.description,"onUpdate:value":n[3]||(n[3]=e=>H.value.description=e),type:"textarea",autosize:{minRows:3,maxRows:5},placeholder:"一句话说明这个代理什么时候该被调用"},null,8,["value"])]),_:1}),j.value?(c(),_("div",ha,[i(h(e),{size:16},{default:f(()=>[i(h(I))]),_:1}),n[18]||(n[18]=w("span",null,[s("Codex agents 写入用户级配置。描述会进入 "),w("code",null,"~/.codex/config.toml"),s(",TOML 配置可托管到 "),w("code",null,"~/.codex/agents/"),s("。")],-1))])):t("",!0)]),w("section",ba,[w("div",ka,[i(h(e),{size:16},{default:f(()=>[i(h(S))]),_:1}),w("span",null,p(j.value?"运行配置":"模型与权限"),1)]),j.value?(c(),_(g,{key:0},[i(h(J),{label:"配置模式",path:"configMode"},{default:f(()=>[i(h(K),{value:H.value.configMode,"onUpdate:value":n[4]||(n[4]=e=>H.value.configMode=e),options:G,placeholder:"选择配置模式"},null,8,["value"])]),_:1}),"custom"===H.value.configMode?(c(),o(h(J),{key:0,label:"配置文件路径",path:"configFile"},{default:f(()=>[i(h(ce),{value:H.value.configFile,"onUpdate:value":n[5]||(n[5]=e=>H.value.configFile=e),placeholder:"~/.omx/agents/my-agent.toml"},null,8,["value"])]),_:1})):t("",!0),"none"===H.value.configMode?(c(),_("div",_a,[i(h(e),{size:18},{default:f(()=>[i(h(z))]),_:1}),n[19]||(n[19]=w("span",null,"仅保存代理描述,不额外写入模型或工具配置。",-1))])):(c(),o(h(J),{key:2,label:"Agent Config (TOML)",path:"configContent",class:"editor-form-item"},{default:f(()=>[i(h(ce),{value:H.value.configContent,"onUpdate:value":n[6]||(n[6]=e=>H.value.configContent=e),type:"textarea",autosize:{minRows:14,maxRows:22},class:"toml-editor",placeholder:'model = "gpt-5.4"'},null,8,["value"])]),_:1}))],64)):(c(),_(g,{key:1},[i(h(J),{label:"可用工具",path:"tools"},{default:f(()=>[i(h(ce),{value:H.value.tools,"onUpdate:value":n[7]||(n[7]=e=>H.value.tools=e),placeholder:"Read, Edit, Bash"},null,8,["value"])]),_:1}),i(h(J),{label:"模型",path:"model"},{default:f(()=>[M.value?(c(),o(h(ce),{key:0,value:H.value.model,"onUpdate:value":n[8]||(n[8]=e=>H.value.model=e),placeholder:"gpt-5, claude-sonnet-4, openrouter/model"},null,8,["value"])):(c(),o(h(K),{key:1,value:H.value.model,"onUpdate:value":n[9]||(n[9]=e=>H.value.model=e),options:E,placeholder:"选择模型",clearable:""},null,8,["value"]))]),_:1}),w("div",wa,["opencode"!==u.platform?(c(),o(h(J),{key:0,label:"权限模式",path:"permissionMode"},{default:f(()=>[i(h(K),{value:H.value.permissionMode,"onUpdate:value":n[10]||(n[10]=e=>H.value.permissionMode=e),options:V,placeholder:"选择权限模式",clearable:""},null,8,["value"])]),_:1})):t("",!0),"opencode"!==u.platform?(c(),o(h(J),{key:1,label:"技能",path:"skills"},{default:f(()=>[i(h(ce),{value:H.value.skills,"onUpdate:value":n[11]||(n[11]=e=>H.value.skills=e),placeholder:"自动加载的技能,逗号分隔"},null,8,["value"])]),_:1})):t("",!0)])],64))]),j.value?t("",!0):(c(),_("section",Ca,[w("div",ja,[i(h(e),{size:16},{default:f(()=>[i(h(z))]),_:1}),n[20]||(n[20]=w("span",null,"系统提示词",-1))]),i(h(J),{path:"systemPrompt","show-label":!1,class:"editor-form-item"},{default:f(()=>[i(pe,{modelValue:H.value.systemPrompt,"onUpdate:modelValue":n[12]||(n[12]=e=>H.value.systemPrompt=e),rows:10,"min-height":240,placeholder:"定义代理的行为、边界和输出要求","default-editing":!b.value},null,8,["modelValue","default-editing"])]),_:1})]))],2)]),_:1},8,["model","rules"])]),_:1},8,["show","title"]))}},[["__scopeId","data-v-00915421"]]),za={key:0,class:"asset-panel-header"},Pa={class:"asset-title-group"},Na={class:"asset-heading"},Ua={class:"asset-title-row"},Ia={class:"asset-platform-pill"},$a={key:0,class:"asset-action-row"},Fa={key:1,class:"asset-drawer-toolbar"},Oa={key:0,class:"asset-action-row"},Ba={class:"asset-summary"},La={class:"asset-summary-item"},Da={class:"asset-summary-value"},Sa={class:"asset-summary-item"},qa={class:"asset-summary-value"},Ra={class:"asset-summary-item"},Aa={class:"asset-summary-value"},Ta={class:"asset-summary-item"},Ea={class:"asset-summary-value"},Va={class:"asset-filter-bar"},Ga={class:"asset-panel-content"},Ha={key:0,class:"asset-empty"},Wa={key:1,class:"asset-list"},Ya={class:"asset-footer"},Za=l({__name:"AgentsPanel",props:{hideBack:{type:Boolean,default:!1},inDrawer:{type:Boolean,default:!1},projectPath:{type:String,default:null},platform:{type:String,default:""}},emits:["back","updated"],setup(l,{emit:d}){const y=l,z=d,F=M(),O=b(),B=k([]),D=k(!1),S=k(""),q=k("all"),A=k(!1),G=k(!1),H=k(null),W=k(!1),Y=k(null),Z=k({}),J=k({}),Q=k({});let le=0;const{byCapability:te}=X(),se=v(()=>te("agents").map(e=>e.key)),ne=v(()=>se.value.includes(oe.value)),oe=v(()=>String(y.platform||j(O)||"").trim().toLowerCase()),de=v(()=>"opencode"===oe.value?"使用 @agent 或 Task 在 OpenCode 中调用":"gemini"===oe.value?"使用 @agent 调用 Gemini 自定义代理":"使用 Task tool 调用自定义代理"),pe=v(()=>{const e=F.get(oe.value)||x(oe.value);return e.label||e.title||"Claude Code"}),fe=[{label:"全部",value:"all"},{label:"用户级",value:"user"},{label:"项目级",value:"project"},{label:"已托管",value:"managed"}],ge=v(()=>B.value.filter(e=>"user"===e.scope).length),me=v(()=>B.value.filter(e=>"project"===e.scope).length),ye=v(()=>Object.keys(J.value).length);function he(e){if(!e)return"";const a="string"==typeof e.scope&&e.scope.trim()?e.scope.trim():"unknown",l="string"==typeof e.path&&e.path.trim()?e.path.trim():"",t="string"==typeof e.fileName&&e.fileName.trim()?e.fileName.trim():"";return`${a}:${l||t}`}function be(e){if(!e)return"";const a=[];if("string"==typeof e.path&&e.path.trim()&&a.push(e.path.trim()),"string"==typeof e.fileName&&e.fileName.trim()){const l=e.fileName.trim();a.push(`${l}.md`,l)}"string"==typeof e.name&&e.name.trim()&&a.push(e.name.trim());for(const l of a)if(J.value[l])return l;return a[0]||""}const ke=v(()=>{let e=B.value;if("user"===q.value?e=e.filter(e=>"user"===e.scope):"project"===q.value?e=e.filter(e=>"project"===e.scope):"managed"===q.value&&(e=e.filter(e=>J.value[be(e)])),S.value.trim()){const a=S.value.toLowerCase();e=e.filter(e=>e.name?.toLowerCase().includes(a)||e.description?.toLowerCase().includes(a)||e.fileName?.toLowerCase().includes(a))}return e}),_e=v(()=>S.value?"没有匹配的代理":"user"===q.value?"暂无用户级代理":"project"===q.value?"暂无项目级代理":"managed"===q.value?"暂无托管的代理":ne.value?"暂无自定义代理":`${pe.value} 暂未提供 Agents 能力`);async function we(){if(!ne.value)return B.value=[],J.value={},void(D.value=!1);D.value=!0;try{const[e,a]=await Promise.all([ve(y.projectPath,oe.value),V("agents",{platform:oe.value,projectPath:y.projectPath})]);if(e.success&&(B.value=e.agents||[]),a.success){J.value={};for(const[e,l]of Object.entries(a.items||{}))J.value[e]=l}}catch(e){ue.error("加载代理列表失败: "+e.message)}finally{D.value=!1}}async function Ce(e,a){const l=be(e);if(l){Q.value[l]=!0;try{(await R("agents",l,a)).success&&(ue.success(a?"已启用":"已禁用"),await we())}catch(t){ue.error("切换失败: "+t.message)}finally{delete Q.value[l]}}else ue.error("未找到代理对应的托管配置键")}async function je(e,a,l){const t=be(e);if(t){Q.value[t]=!0;try{(await E("agents",t,a,l)).success&&(ue.success(`${a} ${l?"已启用":"已禁用"}`),await we())}catch(s){ue.error("切换失败: "+s.message)}finally{delete Q.value[t]}}else ue.error("未找到代理对应的托管配置键")}async function xe(){D.value=!0;try{const e=await T("agents");e?.success||ue.warning(e?.message||"同步失败,已继续刷新列表")}catch(e){ue.warning("同步失败,已继续刷新列表: "+e.message)}await we()}function Me(){Y.value=null,A.value=!0}function Pe(e){A.value=e,e||(Y.value=null)}function Ne(e){Ie(e,!0)}async function Ue(e){const a=he(e);Z.value[a]=!0;try{(await async function(e,a,l=null,t="claude"){const s={};return t&&(s.platform=t),l&&(s.projectPath=l),(await C.delete(`/agents/${a}/${e}`,{params:s})).data}(e.fileName,e.scope,y.projectPath,oe.value)).success&&(ue.success("代理已删除"),await we(),z("updated"))}catch(l){ue.error("删除失败: "+l.message)}finally{delete Z.value[a]}}async function Ie(e,a=!1){if(!e)return;const l=++le;W.value=!0,a||(H.value=null,G.value=!0);try{const t=await async function(e,a,l=null,t="claude"){const s={};t&&(s.platform=t),l&&(s.projectPath=l);const n=re(`agent-detail:${e}`,t,a||"",l||"");return ae(n,l=>C.get(`/agents/${a}/${e}`,{params:s,signal:l}).then(e=>e.data),"agent-detail",`agent-detail:${t}`)}(e.fileName,e.scope,y.projectPath,oe.value);if(l!==le)return;const s=t?.agent||e;a?(Y.value=s,A.value=!0):H.value=s}catch(t){if(l!==le)return;ue.error("加载代理详情失败: "+t.message),a?(Y.value=e,A.value=!0):H.value=e}finally{l===le&&(W.value=!1)}}function $e(e){Ie(e,!1)}function Fe(){Y.value=null,we(),z("updated")}function Oe(){z("back")}return u(()=>{we()}),r(oe,()=>{le+=1,W.value=!1,H.value=null,we()}),(u,d)=>(c(),_("div",{class:m(["agents-panel asset-panel",{"in-drawer":y.inDrawer}])},[y.inDrawer?t("",!0):(c(),_("div",za,[w("div",Pa,[y.hideBack?t("",!0):(c(),o(h(a),{key:0,text:"",onClick:Oe,class:"back-btn"},{icon:f(()=>[i(h(e),null,{default:f(()=>[i(h(P))]),_:1})]),_:1})),w("div",Na,[w("div",Ua,[d[3]||(d[3]=w("span",{class:"asset-title"},"代理管理",-1)),w("span",Ia,p(pe.value),1)]),d[4]||(d[4]=w("div",{class:"asset-subtitle"},"维护自定义代理、工具权限和平台启用状态",-1))])]),ne.value?(c(),_("div",$a,[i(h(a),{text:"",onClick:Me,class:"action-btn"},{icon:f(()=>[i(h(e),null,{default:f(()=>[i(h(N))]),_:1})]),default:f(()=>[d[5]||(d[5]=s(" 创建 ",-1))]),_:1}),i(h(a),{text:"",onClick:xe,loading:D.value,class:"action-btn"},{icon:f(()=>[i(h(e),null,{default:f(()=>[i(h($))]),_:1})]),default:f(()=>[d[6]||(d[6]=s(" 刷新 ",-1))]),_:1},8,["loading"])])):t("",!0)])),y.inDrawer?(c(),_("div",Fa,[ne.value?(c(),_("div",Oa,[i(h(a),{text:"",onClick:Me,class:"action-btn"},{icon:f(()=>[i(h(e),null,{default:f(()=>[i(h(N))]),_:1})]),default:f(()=>[d[7]||(d[7]=s(" 创建 ",-1))]),_:1}),i(h(a),{text:"",onClick:xe,loading:D.value,class:"action-btn"},{icon:f(()=>[i(h(e),null,{default:f(()=>[i(h($))]),_:1})]),default:f(()=>[d[8]||(d[8]=s(" 刷新 ",-1))]),_:1},8,["loading"])])):t("",!0)])):t("",!0),w("div",Ba,[w("span",La,[d[9]||(d[9]=w("span",{class:"asset-summary-label"},"全部",-1)),w("span",Da,p(B.value.length),1)]),w("span",Sa,[d[10]||(d[10]=w("span",{class:"asset-summary-label"},"用户级",-1)),w("span",qa,p(ge.value),1)]),w("span",Ra,[d[11]||(d[11]=w("span",{class:"asset-summary-label"},"项目级",-1)),w("span",Aa,p(me.value),1)]),w("span",Ta,[d[12]||(d[12]=w("span",{class:"asset-summary-label"},"托管",-1)),w("span",Ea,p(ye.value),1)])]),w("div",Va,[i(h(ce),{value:S.value,"onUpdate:value":d[0]||(d[0]=e=>S.value=e),placeholder:"搜索代理、描述或文件名",clearable:"",size:"small",class:"asset-search"},{prefix:f(()=>[i(h(e),null,{default:f(()=>[i(h(L))]),_:1})]),_:1},8,["value"]),i(h(K),{value:q.value,"onUpdate:value":d[1]||(d[1]=e=>q.value=e),options:fe,size:"small",class:"asset-filter"},null,8,["value"])]),w("div",Ga,[i(h(ee),{show:D.value},{default:f(()=>[0!==ke.value.length||D.value?(c(),_("div",Wa,[(c(!0),_(g,null,n(ke.value,e=>(c(),o(ze,{key:he(e),agent:e,deleting:!!Z.value[he(e)],"registry-info":J.value[be(e)],toggling:!!Q.value[be(e)],onEdit:Ne,onDelete:Ue,onClick:$e,onToggleEnabled:Ce,onTogglePlatform:je},null,8,["agent","deleting","registry-info","toggling"]))),128))])):(c(),_("div",Ha,[i(h(ie),{description:_e.value},{icon:f(()=>[i(h(e),{size:"48",color:"var(--text-quaternary)"},{default:f(()=>[i(h(U))]),_:1})]),extra:f(()=>[ne.value?(c(),o(h(a),{key:0,size:"small",onClick:Me},{default:f(()=>[...d[13]||(d[13]=[s(" 创建第一个代理 ",-1)])]),_:1})):t("",!0)]),_:1},8,["description"])]))]),_:1},8,["show"])]),w("div",Ya,[i(h(e),{size:"14",class:"asset-info-icon"},{default:f(()=>[i(h(I))]),_:1}),w("span",null,p(de.value),1)]),i(Ma,{visible:A.value,"onUpdate:visible":Pe,agent:Y.value,"project-path":l.projectPath,platform:oe.value,onSaved:Fe},null,8,["visible","agent","project-path","platform"]),i(ta,{visible:G.value,"onUpdate:visible":d[2]||(d[2]=e=>G.value=e),agent:H.value,platform:oe.value,loading:W.value},null,8,["visible","agent","platform","loading"])],2))}},[["__scopeId","data-v-b673c699"]]),Ka=l({__name:"AgentsDrawer",props:{visible:Boolean,platform:{type:String,default:""}},emits:["update:visible"],setup(e,{emit:a}){const l=e,t=a,{drawerWidth:s}=Y(720),n=v({get:()=>l.visible,set:e=>t("update:visible",e)}),u={padding:0,display:"flex",flexDirection:"column",overflow:"hidden"};return(e,a)=>(c(),o(h(W),{show:n.value,"onUpdate:show":a[1]||(a[1]=e=>n.value=e),width:h(s),placement:"right","mask-closable":!0},{default:f(()=>[i(h(Z),{closable:"","native-scrollbar":!1,"body-content-style":u},{header:f(()=>[...a[2]||(a[2]=[w("div",{class:"drawer-header"},[w("span",null,"代理管理")],-1)])]),default:f(()=>[i(Za,{onBack:a[0]||(a[0]=e=>n.value=!1),"hide-back":!0,"in-drawer":!0,platform:l.platform},null,8,["platform"])]),_:1})]),_:1},8,["show","width"]))}},[["__scopeId","data-v-b9b7a7fa"]]);export{Ka as default};