@shawnstack/quickforge 1.4.0 → 1.5.0

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 (65) hide show
  1. package/README.md +12 -12
  2. package/bin/quickforge.mjs +9 -0
  3. package/dist/assets/AgentProfilesPage-DUmXUxjA.js +1 -0
  4. package/dist/assets/ChatPanelHost-Syx0SSLe.js +242 -0
  5. package/dist/assets/PluginsPage-kiBq0gOT.js +1 -0
  6. package/dist/assets/ScheduledTasksPage-Dw4-tgp9.js +2 -0
  7. package/dist/assets/SharedConversationPage-CaE9bNb9.js +1 -0
  8. package/dist/assets/TerminalDock-BYJcp8Ts.js +2 -0
  9. package/dist/assets/WorkspaceInspector-Bzmv8Cvi.js +3 -0
  10. package/dist/assets/WorkspaceReaderDialog-BJo_KEWi.js +1 -0
  11. package/dist/assets/diff-line-counts-BZoYp5ai.js +10 -0
  12. package/dist/assets/icons-47L5YLKz.js +1 -0
  13. package/dist/assets/index-CqfScETb.js +1200 -0
  14. package/dist/assets/index-DzkBgHZf.css +3 -0
  15. package/dist/assets/{monaco-DG4TcBMc.js → monaco-CGq6uVF1.js} +1 -1
  16. package/dist/assets/{react-vendor-CiCXOLb5.js → react-vendor-DunfCFfp.js} +1 -1
  17. package/dist/favicon.svg +16 -1
  18. package/dist/index.html +5 -5
  19. package/dist/manifest.webmanifest +30 -30
  20. package/package.json +3 -2
  21. package/server/acp/server.mjs +921 -0
  22. package/server/agent-manager.mjs +283 -45
  23. package/server/agent-profile-files.mjs +179 -0
  24. package/server/agent-profiles.mjs +59 -5
  25. package/server/approval-store.mjs +13 -1
  26. package/server/auto-compaction.mjs +111 -112
  27. package/server/channels/process-channel.mjs +278 -0
  28. package/server/channels/providers/wechat.mjs +271 -0
  29. package/server/channels/registry.mjs +58 -0
  30. package/server/context-usage.mjs +108 -0
  31. package/server/custom-commands.mjs +157 -28
  32. package/server/frontmatter.mjs +167 -0
  33. package/server/index.mjs +52 -3
  34. package/server/mcp/registry.mjs +40 -0
  35. package/server/project-config.mjs +43 -6
  36. package/server/routes/agent-profiles.mjs +6 -2
  37. package/server/routes/agent.mjs +13 -2
  38. package/server/routes/channels.mjs +145 -0
  39. package/server/routes/mcp.mjs +7 -1
  40. package/server/routes/models.mjs +68 -0
  41. package/server/routes/project.mjs +34 -4
  42. package/server/routes/scheduled-tasks.mjs +6 -5
  43. package/server/routes/shared-conversation.mjs +1 -1
  44. package/server/routes/storage.mjs +4 -2
  45. package/server/routes/system.mjs +27 -0
  46. package/server/routes/tools.mjs +17 -6
  47. package/server/routes/workspace.mjs +138 -0
  48. package/server/session-utils.mjs +10 -2
  49. package/server/storage.mjs +30 -2
  50. package/server/subagents.mjs +8 -6
  51. package/server/system-prompt.mjs +3 -2
  52. package/server/tools/definitions.mjs +19 -1
  53. package/server/tools/index.mjs +83 -0
  54. package/server/utils/package-update.mjs +156 -0
  55. package/dist/assets/AgentProfilesPage-C79teCgh.js +0 -1
  56. package/dist/assets/ChatPanelHost-BjdIshtX.js +0 -195
  57. package/dist/assets/PluginsPage-Dt7Iiddo.js +0 -1
  58. package/dist/assets/ScheduledTasksPage-C047y3p3.js +0 -2
  59. package/dist/assets/SharedConversationPage-8X8kfztQ.js +0 -1
  60. package/dist/assets/TerminalDock-CEuJNf0m.js +0 -2
  61. package/dist/assets/WorkspaceInspector-BIa5gLVs.js +0 -3
  62. package/dist/assets/WorkspaceReaderDialog-bTeERaGd.js +0 -6
  63. package/dist/assets/icons-Dsc5yL3l.js +0 -1
  64. package/dist/assets/index-CPAWYhzz.css +0 -3
  65. package/dist/assets/index-YTL26wyJ.js +0 -814
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.4.0-blue" />
4
+ <img alt="Version" src="https://img.shields.io/badge/version-1.5.0-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" />
@@ -49,7 +49,7 @@ QuickForge 是一个运行在本机的 AI 对话与研发辅助工具。它保
49
49
  | MCP 集成 | 支持 stdio、SSE、Streamable HTTP (`http`) MCP Server,并将外部工具以命名空间形式注入到 Agent。 |
50
50
  | 自定义指令 | 自动合并 `~/.claude/CLAUDE.md`、`~/.opencode/AGENTS.md`、`~/.quickforge/AGENTS.md` 以及项目 `CLAUDE.md`、`AGENTS.md`、`.opencode/AGENTS.md`、`.quickforge/AGENTS.md`。 |
51
51
  | Agent Skills | 支持 Claude、opencode、共享、QuickForge 项目级和内置 Skills,用于加载专门的工作流说明、参考资料和工具使用规范。 |
52
- | 自定义命令 | 支持 `/plan`、`/review`、`/compact`、`/clear` 等内置命令,也可从项目 `.claude/commands/`、`.opencode/commands/`、`.ai/commands/` 或配置目录加载团队命令。`/plan <任务>` 只生成执行计划,本轮禁止写文件、改文件和运行命令,可调用受同样只读边界约束的 subagent 辅助调研;`/review [范围]` 用于提交前自检待提交代码,本轮禁止编辑文件。 |
52
+ | 自定义命令 | 支持 `/plan`、`/review`、`/summary`、`/compact`、`/clear`、`/help` 等内置命令,也可从用户级 `~/.quickforge/commands/` 或项目 `.claude/commands/`、`.opencode/commands/`、`.ai/commands/` 加载自定义命令。`/summary` 基于当前对话创建总结后的新对话;`/compact` 在当前对话内执行与自动压缩一致的滚动上下文压缩。`/help` 一键查看全部可用命令;`/plan <任务>` 只生成执行计划,本轮禁止写文件、改文件和运行命令,可调用受同样只读边界约束的 subagent 辅助调研;`/review [范围]` 用于提交前自检待提交代码,本轮禁止编辑文件。同名命令优先级:项目目录 > 用户级目录 > 插件命令。 |
53
53
  | 会话工作流 | 支持流式回复、复制、回滚、分支、草稿恢复、会话搜索、上下文用量提示和长对话压缩。 |
54
54
  | 定时任务 | 支持创建、编辑、手动触发、查看历史,并为任务选择模型与参数。 |
55
55
  | 对话分享 | 支持创建分享链接、只读/可操作权限、可选密码保护,以及撤销分享。 |
@@ -70,7 +70,7 @@ QuickForge 的工具能力很直接,因此也需要谨慎使用:
70
70
  #### 从 npm 安装
71
71
 
72
72
  ```bash
73
- npm install -g @shawnstack/quickforge@1.4.0
73
+ npm install -g @shawnstack/quickforge@1.5.0
74
74
  qf
75
75
 
76
76
  # CLI 工具
@@ -84,17 +84,17 @@ qf update
84
84
  当前版本的离线包:
85
85
 
86
86
  ```text
87
- package-offline/shawnstack-quickforge-1.4.0.tgz
87
+ package-offline/shawnstack-quickforge-1.5.0.tgz
88
88
  ```
89
89
 
90
90
  在安装了 Node.js 20+ 和 npm 的机器上执行:
91
91
 
92
92
  ```bash
93
- npm install -g ./package-offline/shawnstack-quickforge-1.4.0.tgz
93
+ npm install -g ./package-offline/shawnstack-quickforge-1.5.0.tgz
94
94
  qf
95
95
  ```
96
96
 
97
- 该包由 `v1.4.0` 标签生成,包含 QuickForge 运行时资源,依赖由 npm 安装。
97
+ 该包由 `v1.5.0` 标签生成,包含 QuickForge 运行时资源,依赖由 npm 安装。
98
98
 
99
99
  ### 本地开发
100
100
 
@@ -213,7 +213,7 @@ It is not meant to replace your IDE or promise fully autonomous software develop
213
213
  | MCP integration | Supports stdio, SSE, and Streamable HTTP (`http`) MCP servers. External tools are injected with namespaced tool names. |
214
214
  | Custom instructions | Automatically merges `~/.claude/CLAUDE.md`, `~/.opencode/AGENTS.md`, `~/.quickforge/AGENTS.md`, and project `CLAUDE.md`, `AGENTS.md`, `.opencode/AGENTS.md`, `.quickforge/AGENTS.md`. |
215
215
  | Agent Skills | Supports Claude, opencode, shared, QuickForge project-level, and bundled Skills for specialized workflows, references, and tool-use instructions. |
216
- | Custom commands | Includes built-in commands such as `/plan`, `/review`, `/compact`, and `/clear`, and can load project commands from `.claude/commands/`, `.opencode/commands/`, `.ai/commands/`, or configured directories. `/plan <task>` drafts an implementation plan without edits or commands, and may call subagents under the same read-only boundary; `/review [scope]` performs a pre-commit self-review without editing files. |
216
+ | Custom commands | Includes built-in commands such as `/plan`, `/review`, `/summary`, `/compact`, `/clear`, and `/help`, and can load custom commands from user-level `~/.quickforge/commands/` or project `.claude/commands/`, `.opencode/commands/`, `.ai/commands/`, or configured directories. `/summary` creates a new summarized chat from the current conversation; `/compact` compacts context in the current chat using the same rolling summary behavior as auto-compaction. `/help` lists all available commands; `/plan <task>` drafts an implementation plan without edits or commands, and may call subagents under the same read-only boundary; `/review [scope]` performs a pre-commit self-review without editing files. Precedence: project directories > user-level > plugins. |
217
217
  | Conversation workflow | Streaming responses, copy, rollback, fork, draft recovery, search, context usage indicator, and conversation compaction. |
218
218
  | Scheduled tasks | Create, edit, manually trigger, and inspect tasks, with model and parameter selection per task. |
219
219
  | Conversation sharing | Share conversations with read-only or operate permissions, optional password protection, and revocation support. |
@@ -234,7 +234,7 @@ QuickForge intentionally exposes powerful local capabilities, so the boundaries
234
234
  #### npm
235
235
 
236
236
  ```bash
237
- npm install -g @shawnstack/quickforge@1.4.0
237
+ npm install -g @shawnstack/quickforge@1.5.0
238
238
  qf
239
239
 
240
240
  # CLI utilities
@@ -245,20 +245,20 @@ qf update
245
245
 
246
246
  #### Offline tarball
247
247
 
248
- The offline release package for `v1.4.0` is:
248
+ The offline release package for `v1.5.0` is:
249
249
 
250
250
  ```text
251
- package-offline/shawnstack-quickforge-1.4.0.tgz
251
+ package-offline/shawnstack-quickforge-1.5.0.tgz
252
252
  ```
253
253
 
254
254
  Install it on a machine with Node.js 20+ and npm:
255
255
 
256
256
  ```bash
257
- npm install -g ./package-offline/shawnstack-quickforge-1.4.0.tgz
257
+ npm install -g ./package-offline/shawnstack-quickforge-1.5.0.tgz
258
258
  qf
259
259
  ```
260
260
 
261
- The package was generated from tag `v1.4.0` and includes QuickForge runtime assets and installs dependencies with npm.
261
+ The package was generated from tag `v1.5.0` and includes QuickForge runtime assets and installs dependencies with npm.
262
262
 
263
263
  ### Local development
264
264
 
@@ -667,6 +667,11 @@ async function cmdLogs() {
667
667
  }
668
668
  }
669
669
 
670
+ async function cmdAcp() {
671
+ const { runQuickForgeAcpStdio } = await import('../server/acp/server.mjs')
672
+ await runQuickForgeAcpStdio()
673
+ }
674
+
670
675
  async function main() {
671
676
  const command = process.argv[2] || 'start'
672
677
 
@@ -690,6 +695,9 @@ async function main() {
690
695
  case 'logs':
691
696
  await cmdLogs()
692
697
  break
698
+ case 'acp':
699
+ await cmdAcp()
700
+ break
693
701
  case '--version':
694
702
  case '-v':
695
703
  case 'version':
@@ -714,6 +722,7 @@ async function main() {
714
722
  console.log(' quickforge restart Restart the background service')
715
723
  console.log(' quickforge status Check if the service is running')
716
724
  console.log(' quickforge logs Watch today\'s server log')
725
+ console.log(' quickforge acp Run QuickForge as an ACP Agent over stdio')
717
726
  console.log(' quickforge version Show installed version')
718
727
  console.log(' quickforge --version Show installed version')
719
728
  console.log(' quickforge check-update Check npm for newer version')
@@ -0,0 +1 @@
1
+ import{i as e}from"./rolldown-runtime-DWdDZTNf.js";import{St as t,bt as n,c as r}from"./icons-47L5YLKz.js";import{n as i}from"./react-vendor-DunfCFfp.js";import{A as a,C as o,E as s,N as c,S as l,T as u,j as d,k as f,w as p}from"./index-CqfScETb.js";var m=e(t(),1),h=i();function g(){return{name:``,label:``,description:``,systemPrompt:``,allowedTools:[`read_file`,`grep_files`],maxRuntimeMs:`1800000`,maxToolCalls:`300`,enabledAsSubagent:!0}}function _(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 v(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 y(e){return!!(e.name.trim()&&e.label.trim()&&e.allowedTools.length>0)}async function b(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 x(){let[e,t]=(0,m.useState)([]),[i,x]=(0,m.useState)([]),[S,C]=(0,m.useState)(!1),[w,T]=(0,m.useState)(null),[E,D]=(0,m.useState)(()=>g()),[O,k]=(0,m.useState)(!1),[A,j]=(0,m.useState)(``),[M,N]=(0,m.useState)(!1),[P,F]=(0,m.useState)(),[I,L]=(0,m.useState)(`off`),[R,z]=(0,m.useState)(``);async function B(){let[e,n]=await Promise.all([b(`/api/agent-profiles`),b(`/api/agent-profiles/available-tools`)]);t(e.agents),x(n.tools)}(0,m.useEffect)(()=>{let e=!1;async function n(){try{let[n,r]=await Promise.all([b(`/api/agent-profiles`),b(`/api/agent-profiles/available-tools`)]);if(e)return;t(n.agents),x(r.tools)}catch(t){e||z(t instanceof Error?t.message:c(`requestFailed`))}}return n(),()=>{e=!0}},[]),(0,m.useEffect)(()=>{let e=!1;async function t(){try{let t=await p(),n=await o(t),r=await u(t),i=r.model??await s(t)??n[0];if(e)return;F(i),L(r.thinkingLevel??l(i))}catch{}}return t(),()=>{e=!0}},[]);let V=(0,m.useMemo)(()=>e.find(e=>e.id===w)??null,[e,w]);function H(e,t){D(n=>({...n,[e]:t}))}function U(e){D(t=>({...t,allowedTools:t.allowedTools.includes(e)?t.allowedTools.filter(t=>t!==e):[...t.allowedTools,e]}))}function W(){T(null),D(g()),j(``),z(``),C(!0)}function G(e){T(e.id),D(_(e)),j(``),z(``),C(!0)}function K(){O||M||(C(!1),T(null),D(g()),j(``))}async function q(){let e=A.trim();if(!e){z(c(`aiFillAgentInputRequired`));return}if(!P){z(c(`aiFillAgentNoModel`));return}N(!0),z(``);try{let t=await b(`/api/agent-profiles/ai-fill`,{method:`POST`,body:JSON.stringify({instruction:e,model:P,thinkingLevel:I})});D(e=>({...e,name:t.agent.name,label:t.agent.label,description:t.agent.description,systemPrompt:t.agent.systemPrompt}))}catch(e){z(e instanceof Error?e.message:c(`aiFillAgentFailed`))}finally{N(!1)}}async function J(){if(y(E)){k(!0),z(``);try{let e=v(E);w?await b(`/api/agent-profiles/${encodeURIComponent(w)}`,{method:`PATCH`,body:JSON.stringify(e)}):await b(`/api/agent-profiles`,{method:`POST`,body:JSON.stringify(e)}),K(),await B()}catch(e){z(e instanceof Error?e.message:c(`requestFailed`))}finally{k(!1)}}}async function Y(e){if(!(e.builtin||e.readonly)&&await f({description:c(`confirmDeleteAgent`),confirmLabel:c(`confirmDelete`),cancelLabel:c(`cancel`),variant:`destructive`})){z(``);try{await b(`/api/agent-profiles/${encodeURIComponent(e.id)}`,{method:`DELETE`}),await B()}catch(e){z(e instanceof Error?e.message:c(`requestFailed`))}}}return(0,h.jsxs)(`div`,{className:`flex min-h-0 flex-1 flex-col overflow-hidden bg-background`,children:[(0,h.jsx)(`div`,{className:`border-b border-border px-6 py-5`,children:(0,h.jsxs)(`div`,{className:`flex flex-wrap items-center justify-between gap-3`,children:[(0,h.jsxs)(`div`,{className:`flex items-center gap-3`,children:[(0,h.jsx)(`div`,{className:`flex size-10 items-center justify-center rounded-2xl bg-primary/10 text-primary`,children:(0,h.jsx)(n,{className:`size-5`})}),(0,h.jsx)(`div`,{children:(0,h.jsxs)(`h1`,{className:`inline-flex items-center gap-1.5 text-lg font-semibold text-foreground`,children:[c(`agentsTab`),(0,h.jsx)(a,{label:c(`agentsDescription`)})]})})]}),(0,h.jsx)(d,{onClick:W,children:c(`createAgent`)})]})}),(0,h.jsx)(`div`,{className:`min-h-0 flex-1 overflow-y-auto p-6`,children:(0,h.jsxs)(`div`,{className:`mx-auto max-w-5xl space-y-5`,children:[R&&!S?(0,h.jsx)(`div`,{className:`rounded-md border border-destructive/30 bg-destructive/10 px-3 py-2 text-sm text-destructive`,children:R}):null,(0,h.jsx)(`div`,{className:`grid gap-4 md:grid-cols-2`,children:e.map(e=>(0,h.jsxs)(`div`,{className:`rounded-xl border border-border bg-card p-4`,children:[(0,h.jsxs)(`div`,{className:`flex items-start justify-between gap-3`,children:[(0,h.jsxs)(`div`,{className:`min-w-0`,children:[(0,h.jsxs)(`div`,{className:`flex flex-wrap items-center gap-2`,children:[(0,h.jsx)(`h3`,{className:`truncate text-sm font-medium text-foreground/90`,children:e.label}),e.builtin?(0,h.jsx)(`span`,{className:`rounded-full bg-primary/10 px-2 py-0.5 text-xs text-primary`,children:c(`builtinAgent`)}):null,e.enabledAsSubagent?(0,h.jsx)(`span`,{className:`rounded-full bg-emerald-500/10 px-2 py-0.5 text-xs text-emerald-700`,children:c(`enabledAsSubagent`)}):null]}),(0,h.jsx)(`p`,{className:`mt-1 font-mono text-xs text-muted-foreground`,children:e.name}),e.source&&!e.builtin?(0,h.jsxs)(`p`,{className:`mt-1 text-xs text-muted-foreground`,children:[e.source,e.relativePath?` · ${e.relativePath}`:``]}):null,(0,h.jsx)(`p`,{className:`mt-2 text-sm text-muted-foreground`,children:e.description||c(`noDescription`)})]}),(0,h.jsxs)(`div`,{className:`flex shrink-0 gap-1`,children:[(0,h.jsx)(d,{variant:`outline`,size:`sm`,disabled:e.builtin||e.readonly,onClick:()=>G(e),children:c(`editTask`)}),(0,h.jsx)(d,{variant:`destructive`,size:`sm`,disabled:e.builtin||e.readonly,onClick:()=>void Y(e),children:c(`delete`)})]})]}),(0,h.jsx)(`div`,{className:`mt-3 flex flex-wrap gap-1`,children:e.allowedTools.map(e=>(0,h.jsx)(`span`,{className:`rounded-full bg-muted px-2 py-0.5 font-mono text-xs text-muted-foreground`,children:e},e))}),(0,h.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,h.jsxs)(`span`,{children:[c(`maxRuntimeMs`),e.maxRuntimeMs??`-`]}),(0,h.jsxs)(`span`,{children:[c(`maxToolCalls`),e.maxToolCalls??`-`]})]})]},e.id))})]})}),S?(0,h.jsx)(`div`,{className:`fixed inset-0 z-50 flex items-center justify-center bg-black/50 p-4`,onMouseDown:e=>{e.target===e.currentTarget&&K()},children:(0,h.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,h.jsxs)(`div`,{className:`shrink-0 border-b border-border px-5 py-4`,children:[(0,h.jsx)(`h2`,{className:`text-base font-medium text-foreground`,children:c(V?`editAgent`:`createAgent`)}),V?.readonly?(0,h.jsx)(`p`,{className:`mt-1 text-sm text-muted-foreground`,children:c(`builtinAgentReadonly`)}):null]}),(0,h.jsx)(`div`,{className:`min-h-0 flex-1 overflow-y-auto px-5 py-4`,children:(0,h.jsxs)(`div`,{className:`space-y-4`,children:[(0,h.jsxs)(`div`,{className:`rounded-2xl border border-border bg-muted/20 p-3`,children:[(0,h.jsxs)(`div`,{className:`mb-2 flex items-center gap-2 text-sm font-medium text-foreground`,children:[(0,h.jsx)(r,{className:`size-4 text-primary`}),c(`aiFillAgent`),(0,h.jsx)(a,{label:c(`aiFillAgentDescription`)})]}),(0,h.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:A,disabled:!!V?.readonly||M,onChange:e=>j(e.target.value),placeholder:c(`aiFillAgentPlaceholder`)}),(0,h.jsx)(`div`,{className:`mt-2 flex justify-end`,children:(0,h.jsxs)(d,{variant:`outline`,size:`sm`,onClick:()=>void q(),disabled:!!V?.readonly||M||!A.trim(),children:[(0,h.jsx)(r,{className:`mr-1 size-3.5`}),c(M?`aiFillAgentLoading`:`aiFillAgent`)]})})]}),(0,h.jsxs)(`div`,{className:`grid gap-3 sm:grid-cols-2`,children:[(0,h.jsxs)(`label`,{className:`block text-sm font-medium text-foreground`,children:[c(`agentName`),(0,h.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:E.name,disabled:!!V?.readonly,onChange:e=>H(`name`,e.target.value),placeholder:`reviewer`})]}),(0,h.jsxs)(`label`,{className:`block text-sm font-medium text-foreground`,children:[c(`agentLabel`),(0,h.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:E.label,disabled:!!V?.readonly,onChange:e=>H(`label`,e.target.value),placeholder:c(`agentLabelPlaceholder`)})]})]}),(0,h.jsxs)(`label`,{className:`block text-sm font-medium text-foreground`,children:[c(`agentDescription`),(0,h.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:E.description,disabled:!!V?.readonly,onChange:e=>H(`description`,e.target.value)})]}),(0,h.jsxs)(`label`,{className:`block text-sm font-medium text-foreground`,children:[c(`agentSystemPrompt`),(0,h.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:E.systemPrompt,disabled:!!V?.readonly,onChange:e=>H(`systemPrompt`,e.target.value)})]}),(0,h.jsxs)(`div`,{children:[(0,h.jsx)(`div`,{className:`mb-2 text-sm font-medium text-foreground`,children:c(`allowedTools`)}),(0,h.jsx)(`div`,{className:`grid gap-2 sm:grid-cols-2`,children:i.map(e=>(0,h.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,h.jsx)(`input`,{type:`checkbox`,className:`mt-1`,disabled:!!V?.readonly,checked:E.allowedTools.includes(e.name),onChange:()=>U(e.name)}),(0,h.jsxs)(`span`,{children:[(0,h.jsx)(`span`,{className:`font-medium text-foreground`,children:e.label}),(0,h.jsx)(`span`,{className:`ml-2 font-mono text-xs text-muted-foreground`,children:e.name}),e.riskLevel===`dangerous`?(0,h.jsx)(`span`,{className:`ml-2 rounded-full bg-amber-500/10 px-2 py-0.5 text-xs text-amber-700`,children:c(`highRiskTool`)}):null,(0,h.jsx)(`span`,{className:`mt-1 block text-xs text-muted-foreground`,children:e.description})]})]},e.name))})]}),(0,h.jsxs)(`div`,{className:`grid gap-3 sm:grid-cols-2`,children:[(0,h.jsxs)(`label`,{className:`block text-sm font-medium text-foreground`,children:[c(`maxRuntimeMs`),(0,h.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:E.maxRuntimeMs,disabled:!!V?.readonly,onChange:e=>H(`maxRuntimeMs`,e.target.value)})]}),(0,h.jsxs)(`label`,{className:`block text-sm font-medium text-foreground`,children:[c(`maxToolCalls`),(0,h.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:E.maxToolCalls,disabled:!!V?.readonly,onChange:e=>H(`maxToolCalls`,e.target.value)})]})]}),(0,h.jsxs)(`label`,{className:`flex items-center gap-2 text-sm text-foreground`,children:[(0,h.jsx)(`input`,{type:`checkbox`,checked:E.enabledAsSubagent,disabled:!!V?.readonly,onChange:e=>H(`enabledAsSubagent`,e.target.checked)}),c(`enabledAsSubagent`)]}),R?(0,h.jsx)(`div`,{className:`rounded-md border border-destructive/30 bg-destructive/10 px-3 py-2 text-sm text-destructive`,children:R}):null]})}),(0,h.jsx)(`div`,{className:`shrink-0 border-t border-border px-5 py-4`,children:(0,h.jsxs)(`div`,{className:`flex justify-end gap-2`,children:[(0,h.jsx)(d,{variant:`outline`,onClick:K,disabled:O||M,children:c(`cancel`)}),(0,h.jsx)(d,{onClick:J,disabled:O||M||!!V?.readonly||!y(E),children:c(`save`)})]})})]})}):null]})}export{x as AgentProfilesPage};