@shawnstack/quickforge 1.5.3 → 1.5.5
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.
- package/README.md +108 -12
- package/dist/assets/{AgentProfilesPage-BToo_R3Y.js → AgentProfilesPage-nVhgwanY.js} +1 -1
- package/dist/assets/ChatPanelHost-u0K5IWMF.js +242 -0
- package/dist/assets/{PluginsPage-DwzV2vQ4.js → PluginsPage-BVRTC0rz.js} +1 -1
- package/dist/assets/ScheduledTasksPage-D37TE2cM.js +2 -0
- package/dist/assets/{SharedConversationPage-CHE9qABz.js → SharedConversationPage-D5hnzsZC.js} +1 -1
- package/dist/assets/TerminalDock-NvH9esAS.js +2 -0
- package/dist/assets/WorkspaceInspector-DbnO1fei.js +3 -0
- package/dist/assets/{WorkspaceReaderDialog-Bai7v3V0.js → WorkspaceReaderDialog-BcxIbNBq.js} +1 -1
- package/dist/assets/diff-line-counts-N83e7__F.js +10 -0
- package/dist/assets/{icons-DzxBk7tb.js → icons-Uo4Gd-eK.js} +1 -1
- package/dist/assets/index-DiaCCmXE.js +1482 -0
- package/dist/assets/index-KdiXReMI.css +3 -0
- package/dist/assets/{monaco-dMY7_GLO.js → monaco-DtXl4zfe.js} +1 -1
- package/dist/assets/{react-vendor-DsAeMFcm.js → react-vendor-BjDQPVuK.js} +1 -1
- package/dist/assets/useAppTheme-Bm6HIzLF.js +1 -0
- package/dist/favicon.svg +16 -16
- package/dist/index.html +4 -4
- package/dist/pwa-icon-192.png +0 -0
- package/dist/pwa-icon-512.png +0 -0
- package/dist/pwa-maskable-512.png +0 -0
- package/dist/sw.js +1 -1
- package/package.json +2 -1
- package/server/agent-manager.mjs +8 -1
- package/server/index.mjs +76 -6
- package/server/public-api.mjs +196 -0
- package/server/routes/system.mjs +2 -1
- package/server/update-supervisor.mjs +121 -0
- package/dist/assets/ChatPanelHost-BTqhhkWK.js +0 -242
- package/dist/assets/ScheduledTasksPage-Cbm6LVk3.js +0 -2
- package/dist/assets/TerminalDock-Loi8A4pJ.js +0 -2
- package/dist/assets/WorkspaceInspector-Nf5xELW7.js +0 -3
- package/dist/assets/diff-line-counts-CCPYa_e0.js +0 -10
- package/dist/assets/index-Bt_dRvdG.js +0 -1476
- package/dist/assets/index-BzaZg9Br.css +0 -3
package/README.md
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# 速构 QuickForge
|
|
2
2
|
|
|
3
3
|
<p align="center">
|
|
4
|
-
<img alt="Version" src="https://img.shields.io/badge/version-1.5.
|
|
4
|
+
<img alt="Version" src="https://img.shields.io/badge/version-1.5.5-blue" />
|
|
5
5
|
<img alt="License" src="https://img.shields.io/badge/license-MIT-green" />
|
|
6
6
|
<img alt="Node" src="https://img.shields.io/badge/node-%3E%3D20-brightgreen" />
|
|
7
7
|
<img alt="React" src="https://img.shields.io/badge/react-19-61DAFB?logo=react" />
|
|
@@ -27,6 +27,8 @@
|
|
|
27
27
|
|
|
28
28
|
QuickForge 是一个运行在本机的 AI 对话与研发辅助工具。它保留 ChatGPT 类产品的对话体验,同时把会话、项目目录、模型配置和工具调用放在本地服务中管理。你可以用它做普通问答,也可以把它绑定到一个代码仓库,让模型在明确授权后阅读文件、搜索代码、编辑内容并运行命令。
|
|
29
29
|
|
|
30
|
+
同一套核心服务支持三种入口:`qf` / `quickforge` CLI、npm 包 `import` 的 SDK 入口,以及用于本地构建 Windows/macOS/Linux 桌面应用的 Electron 入口。
|
|
31
|
+
|
|
30
32
|
它的目标不是替代 IDE,也不是承诺“全自动开发”,而是提供一个可控的本地 AI 工作流入口:先理解项目,再制定计划,最后在你信任的范围内执行改动和验证。
|
|
31
33
|
|
|
32
34
|
### 适合用来做什么
|
|
@@ -53,7 +55,8 @@ QuickForge 是一个运行在本机的 AI 对话与研发辅助工具。它保
|
|
|
53
55
|
| 会话工作流 | 支持流式回复、复制、回滚、分支、草稿恢复、会话搜索、上下文用量提示和长对话压缩。 |
|
|
54
56
|
| 定时任务 | 支持创建、编辑、手动触发、查看历史,并为任务选择模型与参数。 |
|
|
55
57
|
| 对话分享 | 支持创建分享链接、只读/可操作权限、可选密码保护,以及撤销分享。 |
|
|
56
|
-
| CLI 与离线包 | 提供 `qf` / `quickforge`
|
|
58
|
+
| CLI、SDK 与离线包 | 提供 `qf` / `quickforge` 命令、npm `import` 启动 API、版本检查、更新命令和离线 tarball 安装。 |
|
|
59
|
+
| 桌面端构建入口 | 提供 Electron 桌面壳入口,可在本仓库内构建 Windows/macOS/Linux 桌面应用;Electron 仅作为开发依赖,不进入 npm runtime 包。 |
|
|
57
60
|
|
|
58
61
|
### 安全边界
|
|
59
62
|
|
|
@@ -70,7 +73,7 @@ QuickForge 的工具能力很直接,因此也需要谨慎使用:
|
|
|
70
73
|
#### 从 npm 安装
|
|
71
74
|
|
|
72
75
|
```bash
|
|
73
|
-
npm install -g @shawnstack/quickforge@1.5.
|
|
76
|
+
npm install -g @shawnstack/quickforge@1.5.5
|
|
74
77
|
qf
|
|
75
78
|
|
|
76
79
|
# CLI 工具
|
|
@@ -79,22 +82,39 @@ qf check-update
|
|
|
79
82
|
qf update
|
|
80
83
|
```
|
|
81
84
|
|
|
85
|
+
#### SDK 入口
|
|
86
|
+
|
|
87
|
+
QuickForge 也可以作为 npm 包在 Node.js 项目中启动本地服务:
|
|
88
|
+
|
|
89
|
+
```js
|
|
90
|
+
import { startQuickForge } from '@shawnstack/quickforge'
|
|
91
|
+
|
|
92
|
+
const app = await startQuickForge({
|
|
93
|
+
host: '127.0.0.1',
|
|
94
|
+
port: 5176,
|
|
95
|
+
})
|
|
96
|
+
|
|
97
|
+
console.log(app.url)
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
该入口使用 `package.json` 的 `main` 字段提供,不会改变 `qf` / `quickforge` CLI 发布方式。
|
|
101
|
+
|
|
82
102
|
#### 离线安装
|
|
83
103
|
|
|
84
104
|
当前版本的离线包:
|
|
85
105
|
|
|
86
106
|
```text
|
|
87
|
-
package-offline/shawnstack-quickforge-1.5.
|
|
107
|
+
package-offline/shawnstack-quickforge-1.5.5.tgz
|
|
88
108
|
```
|
|
89
109
|
|
|
90
110
|
在安装了 Node.js 20+ 和 npm 的机器上执行:
|
|
91
111
|
|
|
92
112
|
```bash
|
|
93
|
-
npm install -g ./package-offline/shawnstack-quickforge-1.5.
|
|
113
|
+
npm install -g ./package-offline/shawnstack-quickforge-1.5.5.tgz
|
|
94
114
|
qf
|
|
95
115
|
```
|
|
96
116
|
|
|
97
|
-
该包由 `v1.5.
|
|
117
|
+
该包由 `v1.5.5` 标签生成,包含 QuickForge 运行时资源,依赖由 npm 安装。
|
|
98
118
|
|
|
99
119
|
### 本地开发
|
|
100
120
|
|
|
@@ -117,6 +137,32 @@ Windows 用户也可以双击:
|
|
|
117
137
|
- `dev-quickforge.bat`:开发模式
|
|
118
138
|
- `start-quickforge.bat`:生产模式
|
|
119
139
|
|
|
140
|
+
#### 桌面端开发与构建
|
|
141
|
+
|
|
142
|
+
桌面端入口位于 `desktop/electron-main.mjs`,复用同一套本地服务和前端构建产物。
|
|
143
|
+
|
|
144
|
+
```bash
|
|
145
|
+
# 桌面端开发启动
|
|
146
|
+
npm run desktop:dev
|
|
147
|
+
|
|
148
|
+
# 构建当前平台桌面包
|
|
149
|
+
npm run desktop:build
|
|
150
|
+
|
|
151
|
+
# 分别构建三端桌面包
|
|
152
|
+
npm run desktop:build:win
|
|
153
|
+
npm run desktop:build:mac
|
|
154
|
+
npm run desktop:build:linux
|
|
155
|
+
|
|
156
|
+
# 本地尝试一键构建三端包(跨平台构建受本机环境限制)
|
|
157
|
+
npm run desktop:build:all
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
桌面构建产物输出到 `desktop-dist/`。该目录和 Electron 相关依赖只用于本地桌面包构建,不包含在 npm runtime 发布白名单中。
|
|
161
|
+
|
|
162
|
+
桌面端支持系统托盘:Windows 会显示在右下角系统托盘,macOS 会显示在顶部菜单栏。关闭窗口默认隐藏到托盘,使用托盘菜单中的退出操作才会真正退出并停止桌面端启动的本地服务。托盘菜单文案会优先跟随 QuickForge 设置中的界面语言(中文/英文),读取不到时回退系统语言。
|
|
163
|
+
|
|
164
|
+
GitHub Actions 提供 `Desktop Build` 工作流,可手动触发或在推送 `v*` 标签时按 Windows/macOS/Linux runner 分别构建桌面包,并上传为 workflow artifacts;该流程不会自动创建 GitHub Release,也不会发布 npm。
|
|
165
|
+
|
|
120
166
|
### 首次配置模型
|
|
121
167
|
|
|
122
168
|
QuickForge 不内置默认模型。首次打开时,如果没有配置任何模型,聊天区会显示配置引导。
|
|
@@ -167,7 +213,9 @@ API Key: 按你的 LiteLLM 配置填写,可为空
|
|
|
167
213
|
|
|
168
214
|
```text
|
|
169
215
|
├── bin/quickforge.mjs # CLI 入口
|
|
216
|
+
├── desktop/ # Electron 桌面端入口(构建 Windows/macOS/Linux 桌面包)
|
|
170
217
|
├── server/ # 本地 API、存储、Agent、工具、MCP、分享与任务服务
|
|
218
|
+
│ └── public-api.mjs # npm import / Desktop 复用的启动 API
|
|
171
219
|
├── src/ # React 前端
|
|
172
220
|
├── skills/ # 内置 Agent Skills
|
|
173
221
|
├── scripts/ # 打包与发布辅助脚本
|
|
@@ -191,6 +239,8 @@ API Key: 按你的 LiteLLM 配置填写,可为空
|
|
|
191
239
|
|
|
192
240
|
QuickForge is a local-first AI chat and development workspace. It keeps the familiar chat experience, but connects it to local projects, local storage, configurable model providers, workspace tools, MCP servers, Agent Skills, and scheduled tasks.
|
|
193
241
|
|
|
242
|
+
The same core runtime now supports three entry points: the `qf` / `quickforge` CLI, an npm-importable SDK entry, and an Electron entry for building Windows/macOS/Linux desktop apps locally.
|
|
243
|
+
|
|
194
244
|
It is not meant to replace your IDE or promise fully autonomous software development. The practical goal is narrower: give you a controllable place where an AI assistant can understand a project, propose a plan, make focused changes when authorized, and run the checks you ask for.
|
|
195
245
|
|
|
196
246
|
### What it is good for
|
|
@@ -217,7 +267,8 @@ It is not meant to replace your IDE or promise fully autonomous software develop
|
|
|
217
267
|
| Conversation workflow | Streaming responses, copy, rollback, fork, draft recovery, search, context usage indicator, and conversation compaction. |
|
|
218
268
|
| Scheduled tasks | Create, edit, manually trigger, and inspect tasks, with model and parameter selection per task. |
|
|
219
269
|
| Conversation sharing | Share conversations with read-only or operate permissions, optional password protection, and revocation support. |
|
|
220
|
-
| CLI and offline package | Provides `qf` / `quickforge` commands, update checks, update command, and offline tarball installation. |
|
|
270
|
+
| CLI, SDK, and offline package | Provides `qf` / `quickforge` commands, an npm-importable startup API, update checks, update command, and offline tarball installation. |
|
|
271
|
+
| Desktop build entry | Provides an Electron desktop wrapper for building Windows/macOS/Linux desktop apps from this repository. Electron stays in dev dependencies and is not included in the npm runtime package. |
|
|
221
272
|
|
|
222
273
|
### Safety model
|
|
223
274
|
|
|
@@ -234,7 +285,7 @@ QuickForge intentionally exposes powerful local capabilities, so the boundaries
|
|
|
234
285
|
#### npm
|
|
235
286
|
|
|
236
287
|
```bash
|
|
237
|
-
npm install -g @shawnstack/quickforge@1.5.
|
|
288
|
+
npm install -g @shawnstack/quickforge@1.5.5
|
|
238
289
|
qf
|
|
239
290
|
|
|
240
291
|
# CLI utilities
|
|
@@ -243,22 +294,39 @@ qf check-update
|
|
|
243
294
|
qf update
|
|
244
295
|
```
|
|
245
296
|
|
|
297
|
+
#### SDK entry
|
|
298
|
+
|
|
299
|
+
QuickForge can also be started from a Node.js project as an npm package:
|
|
300
|
+
|
|
301
|
+
```js
|
|
302
|
+
import { startQuickForge } from '@shawnstack/quickforge'
|
|
303
|
+
|
|
304
|
+
const app = await startQuickForge({
|
|
305
|
+
host: '127.0.0.1',
|
|
306
|
+
port: 5176,
|
|
307
|
+
})
|
|
308
|
+
|
|
309
|
+
console.log(app.url)
|
|
310
|
+
```
|
|
311
|
+
|
|
312
|
+
This entry is exposed through the `main` field in `package.json` and does not change the `qf` / `quickforge` CLI publishing path.
|
|
313
|
+
|
|
246
314
|
#### Offline tarball
|
|
247
315
|
|
|
248
|
-
The offline release package for `v1.5.
|
|
316
|
+
The offline release package for `v1.5.5` is:
|
|
249
317
|
|
|
250
318
|
```text
|
|
251
|
-
package-offline/shawnstack-quickforge-1.5.
|
|
319
|
+
package-offline/shawnstack-quickforge-1.5.5.tgz
|
|
252
320
|
```
|
|
253
321
|
|
|
254
322
|
Install it on a machine with Node.js 20+ and npm:
|
|
255
323
|
|
|
256
324
|
```bash
|
|
257
|
-
npm install -g ./package-offline/shawnstack-quickforge-1.5.
|
|
325
|
+
npm install -g ./package-offline/shawnstack-quickforge-1.5.5.tgz
|
|
258
326
|
qf
|
|
259
327
|
```
|
|
260
328
|
|
|
261
|
-
The package was generated from tag `v1.5.
|
|
329
|
+
The package was generated from tag `v1.5.5` and includes QuickForge runtime assets and installs dependencies with npm.
|
|
262
330
|
|
|
263
331
|
### Local development
|
|
264
332
|
|
|
@@ -281,6 +349,32 @@ On Windows, you can also double-click:
|
|
|
281
349
|
- `dev-quickforge.bat` for development mode
|
|
282
350
|
- `start-quickforge.bat` for production mode
|
|
283
351
|
|
|
352
|
+
#### Desktop development and builds
|
|
353
|
+
|
|
354
|
+
The desktop entry lives at `desktop/electron-main.mjs` and reuses the same local service and frontend build output.
|
|
355
|
+
|
|
356
|
+
```bash
|
|
357
|
+
# Start desktop app in development
|
|
358
|
+
npm run desktop:dev
|
|
359
|
+
|
|
360
|
+
# Build a desktop package for the current platform
|
|
361
|
+
npm run desktop:build
|
|
362
|
+
|
|
363
|
+
# Build desktop packages by platform
|
|
364
|
+
npm run desktop:build:win
|
|
365
|
+
npm run desktop:build:mac
|
|
366
|
+
npm run desktop:build:linux
|
|
367
|
+
|
|
368
|
+
# Try to build all desktop targets locally (cross-platform builds depend on local tooling)
|
|
369
|
+
npm run desktop:build:all
|
|
370
|
+
```
|
|
371
|
+
|
|
372
|
+
Desktop artifacts are written to `desktop-dist/`. This directory and Electron dependencies are only for local desktop builds and are not part of the npm runtime publish whitelist.
|
|
373
|
+
|
|
374
|
+
The desktop app supports a system tray: Windows uses the bottom-right system tray and macOS uses the top menu bar. Closing the window hides it to the tray; use the quit action from the tray menu to fully exit and stop the local service started by the desktop app. Tray menu labels follow the QuickForge display language setting when available, and fall back to the system language.
|
|
375
|
+
|
|
376
|
+
GitHub Actions provides a `Desktop Build` workflow. It can be run manually or by pushing a `v*` tag, builds on Windows/macOS/Linux runners, and uploads workflow artifacts. It does not create GitHub Releases or publish npm automatically.
|
|
377
|
+
|
|
284
378
|
### First model setup
|
|
285
379
|
|
|
286
380
|
QuickForge does not ship with a default model. If no model is configured on first launch, the chat area shows a setup guide.
|
|
@@ -331,7 +425,9 @@ Located under `~/.quickforge/` by default (`%USERPROFILE%\.quickforge` on Window
|
|
|
331
425
|
|
|
332
426
|
```text
|
|
333
427
|
├── bin/quickforge.mjs # CLI entry point
|
|
428
|
+
├── desktop/ # Electron desktop entry for Windows/macOS/Linux builds
|
|
334
429
|
├── server/ # Local API, storage, agents, tools, MCP, sharing, and task service
|
|
430
|
+
│ └── public-api.mjs # startup API reused by npm import and Desktop
|
|
335
431
|
├── src/ # React frontend
|
|
336
432
|
├── skills/ # Bundled Agent Skills
|
|
337
433
|
├── scripts/ # Build and packaging helpers
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{i as e}from"./rolldown-runtime-DWdDZTNf.js";import{T as t,a as n,c as r,tt as i,wt as a,xt as o}from"./icons-DzxBk7tb.js";import{n as s}from"./react-vendor-DsAeMFcm.js";import{D as c,E as l,F as u,I as d,M as f,N as p,O as m,P as h,T as g,k as _}from"./index-Bt_dRvdG.js";var v=e(a(),1),y=s();function b(){return{name:``,label:``,description:``,systemPrompt:``,allowedTools:[`read_file`,`grep_files`],maxRuntimeMs:`1800000`,maxToolCalls:`300`,enabledAsSubagent:!0}}function x(e){return{name:e.name,label:e.label,description:e.description??``,systemPrompt:e.systemPrompt??``,allowedTools:e.allowedTools??[],maxRuntimeMs:String(e.maxRuntimeMs??18e5),maxToolCalls:String(e.maxToolCalls??300),enabledAsSubagent:e.enabledAsSubagent}}function S(e){return{name:e.name.trim().toLowerCase(),label:e.label.trim(),description:e.description.trim(),systemPrompt:e.systemPrompt.trim(),allowedTools:e.allowedTools,maxRuntimeMs:Number(e.maxRuntimeMs||18e5),maxToolCalls:Number(e.maxToolCalls||300),enabledAsSubagent:e.enabledAsSubagent}}function C(e){return!!(e.name.trim()&&e.label.trim()&&e.allowedTools.length>0)}async function w(e,t){let n=await fetch(e,{...t,headers:{"content-type":`application/json`,...t?.headers}}),r=await n.json().catch(()=>null);if(!n.ok)throw Error(r?.error||`请求失败`);return r}function T(){let[e,a]=(0,v.useState)([]),[s,T]=(0,v.useState)([]),[E,D]=(0,v.useState)(!1),[O,k]=(0,v.useState)(null),[A,j]=(0,v.useState)(()=>b()),[M,N]=(0,v.useState)(!1),[P,F]=(0,v.useState)(``),[I,L]=(0,v.useState)(!1),[R,z]=(0,v.useState)(),[B,V]=(0,v.useState)(`off`),[H,U]=(0,v.useState)(``),[W,G]=(0,v.useState)(null);async function K(){let[e,t]=await Promise.all([w(`/api/agent-profiles`),w(`/api/agent-profiles/available-tools`)]);a(e.agents),T(t.tools)}(0,v.useEffect)(()=>{let e=!1;async function t(){try{let[t,n]=await Promise.all([w(`/api/agent-profiles`),w(`/api/agent-profiles/available-tools`)]);if(e)return;a(t.agents),T(n.tools)}catch(t){e||U(t instanceof Error?t.message:d(`requestFailed`))}}return t(),()=>{e=!0}},[]),(0,v.useEffect)(()=>{let e=!1;async function t(){try{let t=await c(),n=await l(t),r=await m(t),i=r.model??await _(t)??n[0];if(e)return;z(i),V(r.thinkingLevel??g(i))}catch{}}return t(),()=>{e=!0}},[]),(0,v.useEffect)(()=>{if(!W)return;let e=()=>G(null);return window.addEventListener(`click`,e),window.addEventListener(`blur`,e),()=>{window.removeEventListener(`click`,e),window.removeEventListener(`blur`,e)}},[W]);let q=(0,v.useMemo)(()=>e.find(e=>e.id===O)??null,[e,O]);function J(e,t){j(n=>({...n,[e]:t}))}function Y(e){j(t=>({...t,allowedTools:t.allowedTools.includes(e)?t.allowedTools.filter(t=>t!==e):[...t.allowedTools,e]}))}function X(){k(null),j(b()),F(``),U(``),D(!0)}function Z(e){k(e.id),j(x(e)),F(``),U(``),D(!0)}function Q(){M||I||(D(!1),k(null),j(b()),F(``))}async function $(){let e=P.trim();if(!e){U(d(`aiFillAgentInputRequired`));return}if(!R){U(d(`aiFillAgentNoModel`));return}L(!0),U(``);try{let t=await w(`/api/agent-profiles/ai-fill`,{method:`POST`,body:JSON.stringify({instruction:e,model:R,thinkingLevel:B})});j(e=>({...e,name:t.agent.name,label:t.agent.label,description:t.agent.description,systemPrompt:t.agent.systemPrompt}))}catch(e){U(e instanceof Error?e.message:d(`aiFillAgentFailed`))}finally{L(!1)}}async function ee(){if(C(A)){N(!0),U(``);try{let e=S(A);O?await w(`/api/agent-profiles/${encodeURIComponent(O)}`,{method:`PATCH`,body:JSON.stringify(e)}):await w(`/api/agent-profiles`,{method:`POST`,body:JSON.stringify(e)}),Q(),await K()}catch(e){U(e instanceof Error?e.message:d(`requestFailed`))}finally{N(!1)}}}async function te(e){if(e.builtin||e.readonly)return;let t=!e.enabledAsSubagent,n=e.enabledAsSubagent;a(n=>n.map(n=>n.id===e.id?{...n,enabledAsSubagent:t}:n)),G(null);try{await w(`/api/agent-profiles/${encodeURIComponent(e.id)}`,{method:`PATCH`,body:JSON.stringify({enabledAsSubagent:t})})}catch(t){a(t=>t.map(t=>t.id===e.id?{...t,enabledAsSubagent:n}:t)),U(t instanceof Error?t.message:d(`requestFailed`))}}async function ne(e){if(!(e.builtin||e.readonly)&&await f({description:d(`confirmDeleteAgent`),confirmLabel:d(`confirmDelete`),cancelLabel:d(`cancel`),variant:`destructive`})){U(``);try{await w(`/api/agent-profiles/${encodeURIComponent(e.id)}`,{method:`DELETE`}),await K()}catch(e){U(e instanceof Error?e.message:d(`requestFailed`))}}}return(0,y.jsxs)(`div`,{className:`flex min-h-0 flex-1 flex-col overflow-hidden bg-background`,children:[(0,y.jsx)(`div`,{className:`border-b border-border px-6 py-5`,children:(0,y.jsxs)(`div`,{className:`flex flex-wrap items-center justify-between gap-3`,children:[(0,y.jsxs)(`div`,{className:`flex items-center gap-3`,children:[(0,y.jsx)(`div`,{className:`flex size-10 items-center justify-center rounded-2xl bg-primary/10 text-primary`,children:(0,y.jsx)(o,{className:`size-5`})}),(0,y.jsx)(`div`,{children:(0,y.jsxs)(`h1`,{className:`inline-flex items-center gap-1.5 text-lg font-semibold text-foreground`,children:[d(`agentsTab`),(0,y.jsx)(p,{label:d(`agentsDescription`)})]})})]}),(0,y.jsx)(h,{onClick:X,children:d(`createAgent`)})]})}),(0,y.jsx)(`div`,{className:`min-h-0 flex-1 overflow-y-auto p-6`,children:(0,y.jsxs)(`div`,{className:`mx-auto max-w-5xl space-y-5`,children:[H&&!E?(0,y.jsx)(`div`,{className:`rounded-md border border-destructive/30 bg-destructive/10 px-3 py-2 text-sm text-destructive`,children:H}):null,(0,y.jsx)(`div`,{className:`grid gap-4 md:grid-cols-2`,children:e.map(e=>(0,y.jsxs)(`div`,{className:`rounded-xl border border-border bg-card p-4`,children:[(0,y.jsxs)(`div`,{className:`flex items-start justify-between gap-3`,children:[(0,y.jsxs)(`div`,{className:`min-w-0`,children:[(0,y.jsxs)(`div`,{className:`flex flex-wrap items-center gap-2`,children:[(0,y.jsx)(`h3`,{className:u(`truncate text-sm font-medium`,e.enabledAsSubagent?`text-foreground/90`:`text-muted-foreground`),children:e.label}),e.builtin?(0,y.jsx)(`span`,{className:`rounded-full bg-primary/10 px-2 py-0.5 text-xs text-primary`,children:d(`builtinAgent`)}):null]}),(0,y.jsx)(`p`,{className:`mt-1 font-mono text-xs text-muted-foreground`,children:e.name}),e.source&&!e.builtin?(0,y.jsxs)(`p`,{className:`mt-1 text-xs text-muted-foreground`,children:[e.source,e.relativePath?` · ${e.relativePath}`:``]}):null,(0,y.jsx)(`p`,{className:`mt-2 text-sm text-muted-foreground`,children:e.description||d(`noDescription`)})]}),(0,y.jsxs)(`div`,{className:`flex shrink-0 items-center gap-2`,onClick:e=>e.stopPropagation(),children:[(0,y.jsx)(`button`,{type:`button`,role:`switch`,"aria-checked":e.enabledAsSubagent,disabled:e.builtin||e.readonly,className:u(`relative h-6 w-11 rounded-full transition-colors disabled:cursor-not-allowed disabled:opacity-60`,e.enabledAsSubagent?`bg-emerald-500`:`bg-muted-foreground/30`),onClick:()=>void te(e),title:e.enabledAsSubagent?d(`disableAsSubagent`):d(`enableAsSubagent`),children:(0,y.jsx)(`span`,{className:u(`absolute left-0.5 top-0.5 size-5 rounded-full bg-white shadow transition-transform`,e.enabledAsSubagent?`translate-x-5`:`translate-x-0`)})}),(0,y.jsxs)(`div`,{className:`relative`,children:[(0,y.jsx)(h,{variant:`ghost`,size:`icon`,onClick:()=>G(W===e.id?null:e.id),title:d(`moreActions`),children:(0,y.jsx)(i,{className:`size-4`})}),W===e.id?(0,y.jsxs)(`div`,{className:`absolute right-0 z-20 mt-1 w-36 overflow-hidden rounded-xl border border-border bg-popover py-1 text-sm shadow-quickforge`,children:[(0,y.jsxs)(`button`,{className:`flex w-full items-center gap-2 px-3 py-2 text-left hover:bg-muted disabled:cursor-not-allowed disabled:opacity-50`,disabled:e.builtin||e.readonly,onClick:()=>{G(null),Z(e)},children:[(0,y.jsx)(t,{className:`size-3.5`}),d(`editTask`)]}),(0,y.jsxs)(`button`,{className:`flex w-full items-center gap-2 px-3 py-2 text-left text-destructive hover:bg-muted disabled:cursor-not-allowed disabled:opacity-50`,disabled:e.builtin||e.readonly,onClick:()=>{G(null),ne(e)},children:[(0,y.jsx)(n,{className:`size-3.5`}),d(`delete`)]})]}):null]})]})]}),(0,y.jsx)(`div`,{className:`mt-3 flex flex-wrap gap-1`,children:e.allowedTools.map(e=>(0,y.jsx)(`span`,{className:`rounded-full bg-muted px-2 py-0.5 font-mono text-xs text-muted-foreground`,children:e},e))}),(0,y.jsxs)(`div`,{className:`mt-3 grid gap-2 border-t border-border pt-3 text-xs text-muted-foreground sm:grid-cols-2`,children:[(0,y.jsxs)(`span`,{children:[d(`maxRuntimeMs`),e.maxRuntimeMs??`-`]}),(0,y.jsxs)(`span`,{children:[d(`maxToolCalls`),e.maxToolCalls??`-`]})]})]},e.id))})]})}),E?(0,y.jsx)(`div`,{className:`fixed inset-0 z-50 flex items-center justify-center bg-black/50 p-4`,onMouseDown:e=>{e.target===e.currentTarget&&Q()},children:(0,y.jsxs)(`div`,{className:`flex max-h-[90vh] w-full max-w-3xl flex-col overflow-hidden rounded-2xl border border-border bg-background shadow-quickforge`,onMouseDown:e=>e.stopPropagation(),children:[(0,y.jsxs)(`div`,{className:`shrink-0 border-b border-border px-5 py-4`,children:[(0,y.jsx)(`h2`,{className:`text-base font-medium text-foreground`,children:d(q?`editAgent`:`createAgent`)}),q?.readonly?(0,y.jsx)(`p`,{className:`mt-1 text-sm text-muted-foreground`,children:d(`builtinAgentReadonly`)}):null]}),(0,y.jsx)(`div`,{className:`min-h-0 flex-1 overflow-y-auto px-5 py-4`,children:(0,y.jsxs)(`div`,{className:`space-y-4`,children:[(0,y.jsxs)(`div`,{className:`rounded-2xl border border-border bg-muted/20 p-3`,children:[(0,y.jsxs)(`div`,{className:`mb-2 flex items-center gap-2 text-sm font-medium text-foreground`,children:[(0,y.jsx)(r,{className:`size-4 text-primary`}),d(`aiFillAgent`),(0,y.jsx)(p,{label:d(`aiFillAgentDescription`)})]}),(0,y.jsx)(`textarea`,{className:`min-h-20 w-full resize-y rounded-xl border border-input bg-background px-3 py-2 text-sm outline-none transition-colors placeholder:text-muted-foreground/65 focus:border-ring disabled:opacity-60`,value:P,disabled:!!q?.readonly||I,onChange:e=>F(e.target.value),placeholder:d(`aiFillAgentPlaceholder`)}),(0,y.jsx)(`div`,{className:`mt-2 flex justify-end`,children:(0,y.jsxs)(h,{variant:`outline`,size:`sm`,onClick:()=>void $(),disabled:!!q?.readonly||I||!P.trim(),children:[(0,y.jsx)(r,{className:`mr-1 size-3.5`}),d(I?`aiFillAgentLoading`:`aiFillAgent`)]})})]}),(0,y.jsxs)(`div`,{className:`grid gap-3 sm:grid-cols-2`,children:[(0,y.jsxs)(`label`,{className:`block text-sm font-medium text-foreground`,children:[d(`agentName`),(0,y.jsx)(`input`,{className:`mt-1 h-10 w-full rounded-md border border-input bg-background px-3 text-sm outline-none focus:border-ring disabled:opacity-60`,value:A.name,disabled:!!q?.readonly,onChange:e=>J(`name`,e.target.value),placeholder:`reviewer`})]}),(0,y.jsxs)(`label`,{className:`block text-sm font-medium text-foreground`,children:[d(`agentLabel`),(0,y.jsx)(`input`,{className:`mt-1 h-10 w-full rounded-md border border-input bg-background px-3 text-sm outline-none focus:border-ring disabled:opacity-60`,value:A.label,disabled:!!q?.readonly,onChange:e=>J(`label`,e.target.value),placeholder:d(`agentLabelPlaceholder`)})]})]}),(0,y.jsxs)(`label`,{className:`block text-sm font-medium text-foreground`,children:[d(`agentDescription`),(0,y.jsx)(`input`,{className:`mt-1 h-10 w-full rounded-md border border-input bg-background px-3 text-sm outline-none focus:border-ring disabled:opacity-60`,value:A.description,disabled:!!q?.readonly,onChange:e=>J(`description`,e.target.value)})]}),(0,y.jsxs)(`label`,{className:`block text-sm font-medium text-foreground`,children:[d(`agentSystemPrompt`),(0,y.jsx)(`textarea`,{className:`mt-1 min-h-36 w-full resize-y rounded-xl border border-input bg-background px-3 py-2 text-sm outline-none focus:border-ring disabled:opacity-60`,value:A.systemPrompt,disabled:!!q?.readonly,onChange:e=>J(`systemPrompt`,e.target.value)})]}),(0,y.jsxs)(`div`,{children:[(0,y.jsx)(`div`,{className:`mb-2 text-sm font-medium text-foreground`,children:d(`allowedTools`)}),(0,y.jsx)(`div`,{className:`grid gap-2 sm:grid-cols-2`,children:s.map(e=>(0,y.jsxs)(`label`,{className:`flex items-start gap-2 rounded-xl border border-border bg-muted/20 p-3 text-sm disabled:opacity-60`,children:[(0,y.jsx)(`input`,{type:`checkbox`,className:`mt-1`,disabled:!!q?.readonly,checked:A.allowedTools.includes(e.name),onChange:()=>Y(e.name)}),(0,y.jsxs)(`span`,{children:[(0,y.jsx)(`span`,{className:`font-medium text-foreground`,children:e.label}),(0,y.jsx)(`span`,{className:`ml-2 font-mono text-xs text-muted-foreground`,children:e.name}),e.riskLevel===`dangerous`?(0,y.jsx)(`span`,{className:`ml-2 rounded-full bg-amber-500/10 px-2 py-0.5 text-xs text-amber-700`,children:d(`highRiskTool`)}):null,(0,y.jsx)(`span`,{className:`mt-1 block text-xs text-muted-foreground`,children:e.description})]})]},e.name))})]}),(0,y.jsxs)(`div`,{className:`grid gap-3 sm:grid-cols-2`,children:[(0,y.jsxs)(`label`,{className:`block text-sm font-medium text-foreground`,children:[d(`maxRuntimeMs`),(0,y.jsx)(`input`,{type:`number`,className:`mt-1 h-10 w-full rounded-md border border-input bg-background px-3 text-sm outline-none focus:border-ring disabled:opacity-60`,value:A.maxRuntimeMs,disabled:!!q?.readonly,onChange:e=>J(`maxRuntimeMs`,e.target.value)})]}),(0,y.jsxs)(`label`,{className:`block text-sm font-medium text-foreground`,children:[d(`maxToolCalls`),(0,y.jsx)(`input`,{type:`number`,className:`mt-1 h-10 w-full rounded-md border border-input bg-background px-3 text-sm outline-none focus:border-ring disabled:opacity-60`,value:A.maxToolCalls,disabled:!!q?.readonly,onChange:e=>J(`maxToolCalls`,e.target.value)})]})]}),(0,y.jsxs)(`label`,{className:`flex items-center gap-2 text-sm text-foreground`,children:[(0,y.jsx)(`input`,{type:`checkbox`,checked:A.enabledAsSubagent,disabled:!!q?.readonly,onChange:e=>J(`enabledAsSubagent`,e.target.checked)}),d(`enabledAsSubagent`)]}),H?(0,y.jsx)(`div`,{className:`rounded-md border border-destructive/30 bg-destructive/10 px-3 py-2 text-sm text-destructive`,children:H}):null]})}),(0,y.jsx)(`div`,{className:`shrink-0 border-t border-border px-5 py-4`,children:(0,y.jsxs)(`div`,{className:`flex justify-end gap-2`,children:[(0,y.jsx)(h,{variant:`outline`,onClick:Q,disabled:M||I,children:d(`cancel`)}),(0,y.jsx)(h,{onClick:ee,disabled:M||I||!!q?.readonly||!C(A),children:d(`save`)})]})})]})}):null]})}export{T as AgentProfilesPage};
|
|
1
|
+
import{i as e}from"./rolldown-runtime-DWdDZTNf.js";import{Ct as t,Et as n,T as r,a as i,c as a,rt as o}from"./icons-Uo4Gd-eK.js";import{n as s}from"./react-vendor-BjDQPVuK.js";import{D as c,E as l,F as u,I as d,M as f,N as p,O as m,P as h,T as g,k as _}from"./index-DiaCCmXE.js";var v=e(n(),1),y=s();function b(){return{name:``,label:``,description:``,systemPrompt:``,allowedTools:[`read_file`,`grep_files`],maxRuntimeMs:`1800000`,maxToolCalls:`300`,enabledAsSubagent:!0}}function x(e){return{name:e.name,label:e.label,description:e.description??``,systemPrompt:e.systemPrompt??``,allowedTools:e.allowedTools??[],maxRuntimeMs:String(e.maxRuntimeMs??18e5),maxToolCalls:String(e.maxToolCalls??300),enabledAsSubagent:e.enabledAsSubagent}}function S(e){return{name:e.name.trim().toLowerCase(),label:e.label.trim(),description:e.description.trim(),systemPrompt:e.systemPrompt.trim(),allowedTools:e.allowedTools,maxRuntimeMs:Number(e.maxRuntimeMs||18e5),maxToolCalls:Number(e.maxToolCalls||300),enabledAsSubagent:e.enabledAsSubagent}}function C(e){return!!(e.name.trim()&&e.label.trim()&&e.allowedTools.length>0)}async function w(e,t){let n=await fetch(e,{...t,headers:{"content-type":`application/json`,...t?.headers}}),r=await n.json().catch(()=>null);if(!n.ok)throw Error(r?.error||`请求失败`);return r}function T(){let[e,n]=(0,v.useState)([]),[s,T]=(0,v.useState)([]),[E,D]=(0,v.useState)(!1),[O,k]=(0,v.useState)(null),[A,j]=(0,v.useState)(()=>b()),[M,N]=(0,v.useState)(!1),[P,F]=(0,v.useState)(``),[I,L]=(0,v.useState)(!1),[R,z]=(0,v.useState)(),[B,V]=(0,v.useState)(`off`),[H,U]=(0,v.useState)(``),[W,G]=(0,v.useState)(null);async function K(){let[e,t]=await Promise.all([w(`/api/agent-profiles`),w(`/api/agent-profiles/available-tools`)]);n(e.agents),T(t.tools)}(0,v.useEffect)(()=>{let e=!1;async function t(){try{let[t,r]=await Promise.all([w(`/api/agent-profiles`),w(`/api/agent-profiles/available-tools`)]);if(e)return;n(t.agents),T(r.tools)}catch(t){e||U(t instanceof Error?t.message:d(`requestFailed`))}}return t(),()=>{e=!0}},[]),(0,v.useEffect)(()=>{let e=!1;async function t(){try{let t=await c(),n=await l(t),r=await m(t),i=r.model??await _(t)??n[0];if(e)return;z(i),V(r.thinkingLevel??g(i))}catch{}}return t(),()=>{e=!0}},[]),(0,v.useEffect)(()=>{if(!W)return;let e=()=>G(null);return window.addEventListener(`click`,e),window.addEventListener(`blur`,e),()=>{window.removeEventListener(`click`,e),window.removeEventListener(`blur`,e)}},[W]);let q=(0,v.useMemo)(()=>e.find(e=>e.id===O)??null,[e,O]);function J(e,t){j(n=>({...n,[e]:t}))}function Y(e){j(t=>({...t,allowedTools:t.allowedTools.includes(e)?t.allowedTools.filter(t=>t!==e):[...t.allowedTools,e]}))}function X(){k(null),j(b()),F(``),U(``),D(!0)}function Z(e){k(e.id),j(x(e)),F(``),U(``),D(!0)}function Q(){M||I||(D(!1),k(null),j(b()),F(``))}async function $(){let e=P.trim();if(!e){U(d(`aiFillAgentInputRequired`));return}if(!R){U(d(`aiFillAgentNoModel`));return}L(!0),U(``);try{let t=await w(`/api/agent-profiles/ai-fill`,{method:`POST`,body:JSON.stringify({instruction:e,model:R,thinkingLevel:B})});j(e=>({...e,name:t.agent.name,label:t.agent.label,description:t.agent.description,systemPrompt:t.agent.systemPrompt}))}catch(e){U(e instanceof Error?e.message:d(`aiFillAgentFailed`))}finally{L(!1)}}async function ee(){if(C(A)){N(!0),U(``);try{let e=S(A);O?await w(`/api/agent-profiles/${encodeURIComponent(O)}`,{method:`PATCH`,body:JSON.stringify(e)}):await w(`/api/agent-profiles`,{method:`POST`,body:JSON.stringify(e)}),Q(),await K()}catch(e){U(e instanceof Error?e.message:d(`requestFailed`))}finally{N(!1)}}}async function te(e){if(e.builtin||e.readonly)return;let t=!e.enabledAsSubagent,r=e.enabledAsSubagent;n(n=>n.map(n=>n.id===e.id?{...n,enabledAsSubagent:t}:n)),G(null);try{await w(`/api/agent-profiles/${encodeURIComponent(e.id)}`,{method:`PATCH`,body:JSON.stringify({enabledAsSubagent:t})})}catch(t){n(t=>t.map(t=>t.id===e.id?{...t,enabledAsSubagent:r}:t)),U(t instanceof Error?t.message:d(`requestFailed`))}}async function ne(e){if(!(e.builtin||e.readonly)&&await f({description:d(`confirmDeleteAgent`),confirmLabel:d(`confirmDelete`),cancelLabel:d(`cancel`),variant:`destructive`})){U(``);try{await w(`/api/agent-profiles/${encodeURIComponent(e.id)}`,{method:`DELETE`}),await K()}catch(e){U(e instanceof Error?e.message:d(`requestFailed`))}}}return(0,y.jsxs)(`div`,{className:`flex min-h-0 flex-1 flex-col overflow-hidden bg-background`,children:[(0,y.jsx)(`div`,{className:`border-b border-border px-6 py-5`,children:(0,y.jsxs)(`div`,{className:`flex flex-wrap items-center justify-between gap-3`,children:[(0,y.jsxs)(`div`,{className:`flex items-center gap-3`,children:[(0,y.jsx)(`div`,{className:`flex size-10 items-center justify-center rounded-2xl bg-primary/10 text-primary`,children:(0,y.jsx)(t,{className:`size-5`})}),(0,y.jsx)(`div`,{children:(0,y.jsxs)(`h1`,{className:`inline-flex items-center gap-1.5 text-lg font-semibold text-foreground`,children:[d(`agentsTab`),(0,y.jsx)(p,{label:d(`agentsDescription`)})]})})]}),(0,y.jsx)(h,{onClick:X,children:d(`createAgent`)})]})}),(0,y.jsx)(`div`,{className:`min-h-0 flex-1 overflow-y-auto p-6`,children:(0,y.jsxs)(`div`,{className:`mx-auto max-w-5xl space-y-5`,children:[H&&!E?(0,y.jsx)(`div`,{className:`rounded-md border border-destructive/30 bg-destructive/10 px-3 py-2 text-sm text-destructive`,children:H}):null,(0,y.jsx)(`div`,{className:`grid gap-4 md:grid-cols-2`,children:e.map(e=>(0,y.jsxs)(`div`,{className:`rounded-xl border border-border bg-card p-4`,children:[(0,y.jsxs)(`div`,{className:`flex items-start justify-between gap-3`,children:[(0,y.jsxs)(`div`,{className:`min-w-0`,children:[(0,y.jsxs)(`div`,{className:`flex flex-wrap items-center gap-2`,children:[(0,y.jsx)(`h3`,{className:u(`truncate text-sm font-medium`,e.enabledAsSubagent?`text-foreground/90`:`text-muted-foreground`),children:e.label}),e.builtin?(0,y.jsx)(`span`,{className:`rounded-full bg-primary/10 px-2 py-0.5 text-xs text-primary`,children:d(`builtinAgent`)}):null]}),(0,y.jsx)(`p`,{className:`mt-1 font-mono text-xs text-muted-foreground`,children:e.name}),e.source&&!e.builtin?(0,y.jsxs)(`p`,{className:`mt-1 text-xs text-muted-foreground`,children:[e.source,e.relativePath?` · ${e.relativePath}`:``]}):null,(0,y.jsx)(`p`,{className:`mt-2 text-sm text-muted-foreground`,children:e.description||d(`noDescription`)})]}),(0,y.jsxs)(`div`,{className:`flex shrink-0 items-center gap-2`,onClick:e=>e.stopPropagation(),children:[(0,y.jsx)(`button`,{type:`button`,role:`switch`,"aria-checked":e.enabledAsSubagent,disabled:e.builtin||e.readonly,className:u(`relative h-6 w-11 rounded-full transition-colors disabled:cursor-not-allowed disabled:opacity-60`,e.enabledAsSubagent?`bg-emerald-500`:`bg-muted-foreground/30`),onClick:()=>void te(e),title:e.enabledAsSubagent?d(`disableAsSubagent`):d(`enableAsSubagent`),children:(0,y.jsx)(`span`,{className:u(`absolute left-0.5 top-0.5 size-5 rounded-full bg-white shadow transition-transform`,e.enabledAsSubagent?`translate-x-5`:`translate-x-0`)})}),(0,y.jsxs)(`div`,{className:`relative`,children:[(0,y.jsx)(h,{variant:`ghost`,size:`icon`,onClick:()=>G(W===e.id?null:e.id),title:d(`moreActions`),children:(0,y.jsx)(o,{className:`size-4`})}),W===e.id?(0,y.jsxs)(`div`,{className:`absolute right-0 z-20 mt-1 w-36 overflow-hidden rounded-xl border border-border bg-popover py-1 text-sm shadow-quickforge`,children:[(0,y.jsxs)(`button`,{className:`flex w-full items-center gap-2 px-3 py-2 text-left hover:bg-muted disabled:cursor-not-allowed disabled:opacity-50`,disabled:e.builtin||e.readonly,onClick:()=>{G(null),Z(e)},children:[(0,y.jsx)(r,{className:`size-3.5`}),d(`editTask`)]}),(0,y.jsxs)(`button`,{className:`flex w-full items-center gap-2 px-3 py-2 text-left text-destructive hover:bg-muted disabled:cursor-not-allowed disabled:opacity-50`,disabled:e.builtin||e.readonly,onClick:()=>{G(null),ne(e)},children:[(0,y.jsx)(i,{className:`size-3.5`}),d(`delete`)]})]}):null]})]})]}),(0,y.jsx)(`div`,{className:`mt-3 flex flex-wrap gap-1`,children:e.allowedTools.map(e=>(0,y.jsx)(`span`,{className:`rounded-full bg-muted px-2 py-0.5 font-mono text-xs text-muted-foreground`,children:e},e))}),(0,y.jsxs)(`div`,{className:`mt-3 grid gap-2 border-t border-border pt-3 text-xs text-muted-foreground sm:grid-cols-2`,children:[(0,y.jsxs)(`span`,{children:[d(`maxRuntimeMs`),e.maxRuntimeMs??`-`]}),(0,y.jsxs)(`span`,{children:[d(`maxToolCalls`),e.maxToolCalls??`-`]})]})]},e.id))})]})}),E?(0,y.jsx)(`div`,{className:`fixed inset-0 z-50 flex items-center justify-center bg-black/50 p-4`,onMouseDown:e=>{e.target===e.currentTarget&&Q()},children:(0,y.jsxs)(`div`,{className:`flex max-h-[90vh] w-full max-w-3xl flex-col overflow-hidden rounded-2xl border border-border bg-background shadow-quickforge`,onMouseDown:e=>e.stopPropagation(),children:[(0,y.jsxs)(`div`,{className:`shrink-0 border-b border-border px-5 py-4`,children:[(0,y.jsx)(`h2`,{className:`text-base font-medium text-foreground`,children:d(q?`editAgent`:`createAgent`)}),q?.readonly?(0,y.jsx)(`p`,{className:`mt-1 text-sm text-muted-foreground`,children:d(`builtinAgentReadonly`)}):null]}),(0,y.jsx)(`div`,{className:`min-h-0 flex-1 overflow-y-auto px-5 py-4`,children:(0,y.jsxs)(`div`,{className:`space-y-4`,children:[(0,y.jsxs)(`div`,{className:`rounded-2xl border border-border bg-muted/20 p-3`,children:[(0,y.jsxs)(`div`,{className:`mb-2 flex items-center gap-2 text-sm font-medium text-foreground`,children:[(0,y.jsx)(a,{className:`size-4 text-primary`}),d(`aiFillAgent`),(0,y.jsx)(p,{label:d(`aiFillAgentDescription`)})]}),(0,y.jsx)(`textarea`,{className:`min-h-20 w-full resize-y rounded-xl border border-input bg-background px-3 py-2 text-sm outline-none transition-colors placeholder:text-muted-foreground/65 focus:border-ring disabled:opacity-60`,value:P,disabled:!!q?.readonly||I,onChange:e=>F(e.target.value),placeholder:d(`aiFillAgentPlaceholder`)}),(0,y.jsx)(`div`,{className:`mt-2 flex justify-end`,children:(0,y.jsxs)(h,{variant:`outline`,size:`sm`,onClick:()=>void $(),disabled:!!q?.readonly||I||!P.trim(),children:[(0,y.jsx)(a,{className:`mr-1 size-3.5`}),d(I?`aiFillAgentLoading`:`aiFillAgent`)]})})]}),(0,y.jsxs)(`div`,{className:`grid gap-3 sm:grid-cols-2`,children:[(0,y.jsxs)(`label`,{className:`block text-sm font-medium text-foreground`,children:[d(`agentName`),(0,y.jsx)(`input`,{className:`mt-1 h-10 w-full rounded-md border border-input bg-background px-3 text-sm outline-none focus:border-ring disabled:opacity-60`,value:A.name,disabled:!!q?.readonly,onChange:e=>J(`name`,e.target.value),placeholder:`reviewer`})]}),(0,y.jsxs)(`label`,{className:`block text-sm font-medium text-foreground`,children:[d(`agentLabel`),(0,y.jsx)(`input`,{className:`mt-1 h-10 w-full rounded-md border border-input bg-background px-3 text-sm outline-none focus:border-ring disabled:opacity-60`,value:A.label,disabled:!!q?.readonly,onChange:e=>J(`label`,e.target.value),placeholder:d(`agentLabelPlaceholder`)})]})]}),(0,y.jsxs)(`label`,{className:`block text-sm font-medium text-foreground`,children:[d(`agentDescription`),(0,y.jsx)(`input`,{className:`mt-1 h-10 w-full rounded-md border border-input bg-background px-3 text-sm outline-none focus:border-ring disabled:opacity-60`,value:A.description,disabled:!!q?.readonly,onChange:e=>J(`description`,e.target.value)})]}),(0,y.jsxs)(`label`,{className:`block text-sm font-medium text-foreground`,children:[d(`agentSystemPrompt`),(0,y.jsx)(`textarea`,{className:`mt-1 min-h-36 w-full resize-y rounded-xl border border-input bg-background px-3 py-2 text-sm outline-none focus:border-ring disabled:opacity-60`,value:A.systemPrompt,disabled:!!q?.readonly,onChange:e=>J(`systemPrompt`,e.target.value)})]}),(0,y.jsxs)(`div`,{children:[(0,y.jsx)(`div`,{className:`mb-2 text-sm font-medium text-foreground`,children:d(`allowedTools`)}),(0,y.jsx)(`div`,{className:`grid gap-2 sm:grid-cols-2`,children:s.map(e=>(0,y.jsxs)(`label`,{className:`flex items-start gap-2 rounded-xl border border-border bg-muted/20 p-3 text-sm disabled:opacity-60`,children:[(0,y.jsx)(`input`,{type:`checkbox`,className:`mt-1`,disabled:!!q?.readonly,checked:A.allowedTools.includes(e.name),onChange:()=>Y(e.name)}),(0,y.jsxs)(`span`,{children:[(0,y.jsx)(`span`,{className:`font-medium text-foreground`,children:e.label}),(0,y.jsx)(`span`,{className:`ml-2 font-mono text-xs text-muted-foreground`,children:e.name}),e.riskLevel===`dangerous`?(0,y.jsx)(`span`,{className:`ml-2 rounded-full bg-amber-500/10 px-2 py-0.5 text-xs text-amber-700`,children:d(`highRiskTool`)}):null,(0,y.jsx)(`span`,{className:`mt-1 block text-xs text-muted-foreground`,children:e.description})]})]},e.name))})]}),(0,y.jsxs)(`div`,{className:`grid gap-3 sm:grid-cols-2`,children:[(0,y.jsxs)(`label`,{className:`block text-sm font-medium text-foreground`,children:[d(`maxRuntimeMs`),(0,y.jsx)(`input`,{type:`number`,className:`mt-1 h-10 w-full rounded-md border border-input bg-background px-3 text-sm outline-none focus:border-ring disabled:opacity-60`,value:A.maxRuntimeMs,disabled:!!q?.readonly,onChange:e=>J(`maxRuntimeMs`,e.target.value)})]}),(0,y.jsxs)(`label`,{className:`block text-sm font-medium text-foreground`,children:[d(`maxToolCalls`),(0,y.jsx)(`input`,{type:`number`,className:`mt-1 h-10 w-full rounded-md border border-input bg-background px-3 text-sm outline-none focus:border-ring disabled:opacity-60`,value:A.maxToolCalls,disabled:!!q?.readonly,onChange:e=>J(`maxToolCalls`,e.target.value)})]})]}),(0,y.jsxs)(`label`,{className:`flex items-center gap-2 text-sm text-foreground`,children:[(0,y.jsx)(`input`,{type:`checkbox`,checked:A.enabledAsSubagent,disabled:!!q?.readonly,onChange:e=>J(`enabledAsSubagent`,e.target.checked)}),d(`enabledAsSubagent`)]}),H?(0,y.jsx)(`div`,{className:`rounded-md border border-destructive/30 bg-destructive/10 px-3 py-2 text-sm text-destructive`,children:H}):null]})}),(0,y.jsx)(`div`,{className:`shrink-0 border-t border-border px-5 py-4`,children:(0,y.jsxs)(`div`,{className:`flex justify-end gap-2`,children:[(0,y.jsx)(h,{variant:`outline`,onClick:Q,disabled:M||I,children:d(`cancel`)}),(0,y.jsx)(h,{onClick:ee,disabled:M||I||!!q?.readonly||!C(A),children:d(`save`)})]})})]})}):null]})}export{T as AgentProfilesPage};
|