@shawnstack/quickforge 1.4.1 → 1.5.1
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 +12 -12
- package/bin/quickforge.mjs +9 -0
- package/dist/assets/AgentProfilesPage-BIwd5Nzg.js +1 -0
- package/dist/assets/ChatPanelHost-De-DMjx5.js +242 -0
- package/dist/assets/PluginsPage-kRzB5k8J.js +1 -0
- package/dist/assets/ScheduledTasksPage-ZnjohaPS.js +2 -0
- package/dist/assets/SharedConversationPage-EQdZgWCM.js +1 -0
- package/dist/assets/TerminalDock-P2pJH_tx.js +2 -0
- package/dist/assets/WorkspaceInspector-CkLAqYQ6.js +3 -0
- package/dist/assets/WorkspaceReaderDialog-BwzZ8Tgv.js +1 -0
- package/dist/assets/diff-line-counts-CeZC7b0z.js +10 -0
- package/dist/assets/icons-DJqt-rnw.js +1 -0
- package/dist/assets/index-CcGy4TXo.js +1354 -0
- package/dist/assets/index-DuTUuAMk.css +3 -0
- package/dist/assets/{monaco-evITXh-m.js → monaco-CNEfYIy1.js} +1 -1
- package/dist/assets/{react-vendor-Mthyt1p4.js → react-vendor-CZCcjpSR.js} +1 -1
- package/dist/favicon.svg +16 -1
- package/dist/index.html +5 -5
- package/dist/manifest.webmanifest +30 -30
- package/package.json +3 -2
- package/server/acp/server.mjs +921 -0
- package/server/agent-manager.mjs +200 -34
- package/server/agent-profile-files.mjs +179 -0
- package/server/agent-profiles.mjs +59 -5
- package/server/auto-compaction.mjs +82 -39
- package/server/channels/process-channel.mjs +278 -0
- package/server/channels/providers/wechat.mjs +271 -0
- package/server/channels/registry.mjs +58 -0
- package/server/custom-commands.mjs +13 -1
- package/server/frontmatter.mjs +167 -0
- package/server/index.mjs +52 -3
- package/server/project-config.mjs +43 -6
- package/server/routes/agent-profiles.mjs +6 -2
- package/server/routes/agent.mjs +12 -1
- package/server/routes/channels.mjs +145 -0
- package/server/routes/models.mjs +68 -0
- package/server/routes/project.mjs +2 -2
- package/server/routes/scheduled-tasks.mjs +6 -5
- package/server/routes/storage.mjs +4 -2
- package/server/routes/system.mjs +27 -0
- package/server/routes/tools.mjs +17 -6
- package/server/routes/workspace.mjs +142 -20
- package/server/session-utils.mjs +10 -2
- package/server/storage.mjs +29 -2
- package/server/system-prompt.mjs +1 -0
- package/server/tools/definitions.mjs +18 -0
- package/server/tools/index.mjs +86 -0
- package/server/utils/package-update.mjs +156 -0
- package/server/utils/workspace.mjs +1 -1
- package/dist/assets/AgentProfilesPage-CNK5PxA3.js +0 -1
- package/dist/assets/ChatPanelHost-FqPQwwMO.js +0 -217
- package/dist/assets/PluginsPage-BCu1Ept0.js +0 -1
- package/dist/assets/ScheduledTasksPage-Bx04rjui.js +0 -2
- package/dist/assets/SharedConversationPage-55vX9sqe.js +0 -1
- package/dist/assets/TerminalDock-DLN_pLkJ.js +0 -2
- package/dist/assets/WorkspaceInspector-DoemHHnY.js +0 -3
- package/dist/assets/WorkspaceReaderDialog-C6xUHBCw.js +0 -6
- package/dist/assets/icons-BWtivFsx.js +0 -1
- package/dist/assets/index-CxOHP41X.css +0 -3
- package/dist/assets/index-Dcf73EL8.js +0 -895
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
import { spawn } from 'node:child_process'
|
|
2
|
+
import { promises as fs } from 'node:fs'
|
|
3
|
+
import path from 'node:path'
|
|
4
|
+
|
|
5
|
+
function normalizeRepositoryUrl(value) {
|
|
6
|
+
if (!value || typeof value !== 'string') return ''
|
|
7
|
+
return value
|
|
8
|
+
.replace(/^git\+/i, '')
|
|
9
|
+
.replace(/^git@github\.com:/i, 'https://github.com/')
|
|
10
|
+
.replace(/\.git$/i, '')
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export async function getPackageInfo(projectRoot) {
|
|
14
|
+
const packageJsonPath = path.join(projectRoot, 'package.json')
|
|
15
|
+
try {
|
|
16
|
+
const text = await fs.readFile(packageJsonPath, 'utf8')
|
|
17
|
+
const pkg = JSON.parse(text)
|
|
18
|
+
const repositoryUrl = normalizeRepositoryUrl(
|
|
19
|
+
typeof pkg.repository === 'string' ? pkg.repository : pkg.repository?.url,
|
|
20
|
+
)
|
|
21
|
+
|
|
22
|
+
return {
|
|
23
|
+
name: pkg.name || 'quickforge',
|
|
24
|
+
version: pkg.version || '0.0.0',
|
|
25
|
+
repositoryUrl,
|
|
26
|
+
homepage: pkg.homepage || repositoryUrl,
|
|
27
|
+
bugsUrl: typeof pkg.bugs === 'string' ? pkg.bugs : pkg.bugs?.url || '',
|
|
28
|
+
}
|
|
29
|
+
} catch (error) {
|
|
30
|
+
throw new Error(`Unable to read package metadata: ${error.message}`)
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
function normalizeVersion(version) {
|
|
35
|
+
return String(version || '').trim().replace(/^v/i, '')
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
function parseVersion(version) {
|
|
39
|
+
const [main, prerelease = ''] = normalizeVersion(version).split('-', 2)
|
|
40
|
+
const numbers = main.split('.').slice(0, 3).map((part) => {
|
|
41
|
+
const value = Number(part)
|
|
42
|
+
return Number.isFinite(value) ? value : 0
|
|
43
|
+
})
|
|
44
|
+
|
|
45
|
+
while (numbers.length < 3) numbers.push(0)
|
|
46
|
+
return { numbers, prerelease }
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
function comparePrerelease(left, right) {
|
|
50
|
+
if (left === right) return 0
|
|
51
|
+
if (!left) return 1
|
|
52
|
+
if (!right) return -1
|
|
53
|
+
|
|
54
|
+
const leftParts = left.split('.')
|
|
55
|
+
const rightParts = right.split('.')
|
|
56
|
+
const maxLength = Math.max(leftParts.length, rightParts.length)
|
|
57
|
+
|
|
58
|
+
for (let i = 0; i < maxLength; i += 1) {
|
|
59
|
+
const leftPart = leftParts[i]
|
|
60
|
+
const rightPart = rightParts[i]
|
|
61
|
+
if (leftPart === rightPart) continue
|
|
62
|
+
if (leftPart === undefined) return -1
|
|
63
|
+
if (rightPart === undefined) return 1
|
|
64
|
+
|
|
65
|
+
const leftNumber = /^\d+$/.test(leftPart) ? Number(leftPart) : null
|
|
66
|
+
const rightNumber = /^\d+$/.test(rightPart) ? Number(rightPart) : null
|
|
67
|
+
|
|
68
|
+
if (leftNumber !== null && rightNumber !== null) return leftNumber > rightNumber ? 1 : -1
|
|
69
|
+
if (leftNumber !== null) return -1
|
|
70
|
+
if (rightNumber !== null) return 1
|
|
71
|
+
|
|
72
|
+
return leftPart > rightPart ? 1 : -1
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
return 0
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
export function compareVersions(left, right) {
|
|
79
|
+
const parsedLeft = parseVersion(left)
|
|
80
|
+
const parsedRight = parseVersion(right)
|
|
81
|
+
|
|
82
|
+
for (let i = 0; i < 3; i += 1) {
|
|
83
|
+
if (parsedLeft.numbers[i] > parsedRight.numbers[i]) return 1
|
|
84
|
+
if (parsedLeft.numbers[i] < parsedRight.numbers[i]) return -1
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
return comparePrerelease(parsedLeft.prerelease, parsedRight.prerelease)
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
function getRegistryPackageUrl(packageName) {
|
|
91
|
+
const registry = (process.env.npm_config_registry || 'https://registry.npmjs.org/').replace(/\/+$/, '')
|
|
92
|
+
return `${registry}/${encodeURIComponent(packageName)}`
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
export async function fetchLatestVersion(packageName) {
|
|
96
|
+
const controller = new AbortController()
|
|
97
|
+
const timeout = setTimeout(() => controller.abort(), 5000)
|
|
98
|
+
|
|
99
|
+
try {
|
|
100
|
+
const response = await fetch(getRegistryPackageUrl(packageName), {
|
|
101
|
+
headers: { accept: 'application/json' },
|
|
102
|
+
signal: controller.signal,
|
|
103
|
+
})
|
|
104
|
+
|
|
105
|
+
if (!response.ok) throw new Error(`registry returned HTTP ${response.status}`)
|
|
106
|
+
|
|
107
|
+
const metadata = await response.json()
|
|
108
|
+
const latest = metadata?.['dist-tags']?.latest
|
|
109
|
+
if (!latest || typeof latest !== 'string') throw new Error('latest version not found in registry response')
|
|
110
|
+
return latest
|
|
111
|
+
} catch (error) {
|
|
112
|
+
if (error.name === 'AbortError') throw new Error('request timeout')
|
|
113
|
+
throw error
|
|
114
|
+
} finally {
|
|
115
|
+
clearTimeout(timeout)
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
export async function checkForUpdates(projectRoot) {
|
|
120
|
+
const pkg = await getPackageInfo(projectRoot)
|
|
121
|
+
const latestVersion = await fetchLatestVersion(pkg.name)
|
|
122
|
+
const comparison = compareVersions(pkg.version, latestVersion)
|
|
123
|
+
return {
|
|
124
|
+
...pkg,
|
|
125
|
+
currentVersion: pkg.version,
|
|
126
|
+
latestVersion,
|
|
127
|
+
updateAvailable: comparison < 0,
|
|
128
|
+
localVersionIsNewer: comparison > 0,
|
|
129
|
+
installCommand: `npm install -g ${pkg.name}@latest`,
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
function getNpmCommand() {
|
|
134
|
+
return process.platform === 'win32' ? 'npm.cmd' : 'npm'
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
export async function installLatestVersion(packageName, options = {}) {
|
|
138
|
+
const target = `${packageName}@latest`
|
|
139
|
+
const child = spawn(getNpmCommand(), ['install', '-g', target], {
|
|
140
|
+
cwd: options.cwd,
|
|
141
|
+
stdio: 'ignore',
|
|
142
|
+
shell: process.platform === 'win32',
|
|
143
|
+
windowsHide: true,
|
|
144
|
+
})
|
|
145
|
+
|
|
146
|
+
return new Promise((resolve, reject) => {
|
|
147
|
+
child.on('error', reject)
|
|
148
|
+
child.on('exit', (code) => {
|
|
149
|
+
if (code === 0) {
|
|
150
|
+
resolve()
|
|
151
|
+
return
|
|
152
|
+
}
|
|
153
|
+
reject(new Error(`npm install exited with code ${code}`))
|
|
154
|
+
})
|
|
155
|
+
})
|
|
156
|
+
}
|
|
@@ -76,7 +76,7 @@ async function realpathNearestExistingParent(inputPath) {
|
|
|
76
76
|
}
|
|
77
77
|
|
|
78
78
|
export async function assertSafeWorkspacePath(fullPath, context, options = {}) {
|
|
79
|
-
if (isSensitiveWorkspacePath(fullPath, context)) {
|
|
79
|
+
if (!options.allowSensitive && isSensitiveWorkspacePath(fullPath, context)) {
|
|
80
80
|
const error = new Error(`Access to sensitive path is blocked: ${toWorkspaceRelative(fullPath, context)}`)
|
|
81
81
|
error.statusCode = 403
|
|
82
82
|
throw error
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{i as e}from"./rolldown-runtime-DWdDZTNf.js";import{ct as t,s as n,ut as r}from"./icons-BWtivFsx.js";import{n as i}from"./react-vendor-Mthyt1p4.js";import{E as a,O as o,S as s,T as c,b as l,v as u,x as d,y as f}from"./index-Dcf73EL8.js";var p=e(r(),1),m=i();function h(){return{name:``,label:``,description:``,systemPrompt:``,allowedTools:[`read_file`,`grep_files`],maxRuntimeMs:`1800000`,maxToolCalls:`300`,enabledAsSubagent:!0}}function g(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 _(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 v(e){return!!(e.name.trim()&&e.label.trim()&&e.allowedTools.length>0)}async function y(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 b(){let[e,r]=(0,p.useState)([]),[i,b]=(0,p.useState)([]),[x,S]=(0,p.useState)(!1),[C,w]=(0,p.useState)(null),[T,E]=(0,p.useState)(()=>h()),[D,O]=(0,p.useState)(!1),[k,A]=(0,p.useState)(``),[j,M]=(0,p.useState)(!1),[N,P]=(0,p.useState)(),[F,I]=(0,p.useState)(`off`),[L,R]=(0,p.useState)(``);async function z(){let[e,t]=await Promise.all([y(`/api/agent-profiles`),y(`/api/agent-profiles/available-tools`)]);r(e.agents),b(t.tools)}(0,p.useEffect)(()=>{let e=!1;async function t(){try{let[t,n]=await Promise.all([y(`/api/agent-profiles`),y(`/api/agent-profiles/available-tools`)]);if(e)return;r(t.agents),b(n.tools)}catch(t){e||R(t instanceof Error?t.message:o(`requestFailed`))}}return t(),()=>{e=!0}},[]),(0,p.useEffect)(()=>{let e=!1;async function t(){try{let t=await l(),n=await f(t),r=await d(t),i=r.model??await s(t)??n[0];if(e)return;P(i),I(r.thinkingLevel??u(i))}catch{}}return t(),()=>{e=!0}},[]);let B=(0,p.useMemo)(()=>e.find(e=>e.id===C)??null,[e,C]);function V(e,t){E(n=>({...n,[e]:t}))}function H(e){E(t=>({...t,allowedTools:t.allowedTools.includes(e)?t.allowedTools.filter(t=>t!==e):[...t.allowedTools,e]}))}function U(){w(null),E(h()),A(``),R(``),S(!0)}function W(e){w(e.id),E(g(e)),A(``),R(``),S(!0)}function G(){D||j||(S(!1),w(null),E(h()),A(``))}async function K(){let e=k.trim();if(!e){R(o(`aiFillAgentInputRequired`));return}if(!N){R(o(`aiFillAgentNoModel`));return}M(!0),R(``);try{let t=await y(`/api/agent-profiles/ai-fill`,{method:`POST`,body:JSON.stringify({instruction:e,model:N,thinkingLevel:F})});E(e=>({...e,name:t.agent.name,label:t.agent.label,description:t.agent.description,systemPrompt:t.agent.systemPrompt}))}catch(e){R(e instanceof Error?e.message:o(`aiFillAgentFailed`))}finally{M(!1)}}async function q(){if(v(T)){O(!0),R(``);try{let e=_(T);C?await y(`/api/agent-profiles/${encodeURIComponent(C)}`,{method:`PATCH`,body:JSON.stringify(e)}):await y(`/api/agent-profiles`,{method:`POST`,body:JSON.stringify(e)}),G(),await z()}catch(e){R(e instanceof Error?e.message:o(`requestFailed`))}finally{O(!1)}}}async function J(e){if(!e.builtin&&await c({description:o(`confirmDeleteAgent`),confirmLabel:o(`confirmDelete`),cancelLabel:o(`cancel`),variant:`destructive`})){R(``);try{await y(`/api/agent-profiles/${encodeURIComponent(e.id)}`,{method:`DELETE`}),await z()}catch(e){R(e instanceof Error?e.message:o(`requestFailed`))}}}return(0,m.jsxs)(`div`,{className:`flex min-h-0 flex-1 flex-col overflow-hidden bg-background`,children:[(0,m.jsx)(`div`,{className:`border-b border-border px-6 py-5`,children:(0,m.jsxs)(`div`,{className:`flex flex-wrap items-center justify-between gap-3`,children:[(0,m.jsxs)(`div`,{className:`flex items-center gap-3`,children:[(0,m.jsx)(`div`,{className:`flex size-10 items-center justify-center rounded-2xl bg-primary/10 text-primary`,children:(0,m.jsx)(t,{className:`size-5`})}),(0,m.jsxs)(`div`,{children:[(0,m.jsx)(`h1`,{className:`text-lg font-semibold text-foreground`,children:o(`agentsTab`)}),(0,m.jsx)(`p`,{className:`text-sm text-muted-foreground`,children:o(`agentsDescription`)})]})]}),(0,m.jsx)(a,{onClick:U,children:o(`createAgent`)})]})}),(0,m.jsx)(`div`,{className:`min-h-0 flex-1 overflow-y-auto p-6`,children:(0,m.jsxs)(`div`,{className:`mx-auto max-w-5xl space-y-5`,children:[L&&!x?(0,m.jsx)(`div`,{className:`rounded-md border border-destructive/30 bg-destructive/10 px-3 py-2 text-sm text-destructive`,children:L}):null,(0,m.jsx)(`div`,{className:`grid gap-4 md:grid-cols-2`,children:e.map(e=>(0,m.jsxs)(`div`,{className:`rounded-2xl border border-border bg-card p-4 shadow-sm`,children:[(0,m.jsxs)(`div`,{className:`flex items-start justify-between gap-3`,children:[(0,m.jsxs)(`div`,{className:`min-w-0`,children:[(0,m.jsxs)(`div`,{className:`flex flex-wrap items-center gap-2`,children:[(0,m.jsx)(`h3`,{className:`truncate text-base font-semibold text-foreground`,children:e.label}),e.builtin?(0,m.jsx)(`span`,{className:`rounded-full bg-primary/10 px-2 py-0.5 text-xs text-primary`,children:o(`builtinAgent`)}):null,e.enabledAsSubagent?(0,m.jsx)(`span`,{className:`rounded-full bg-emerald-500/10 px-2 py-0.5 text-xs text-emerald-700`,children:o(`enabledAsSubagent`)}):null]}),(0,m.jsx)(`p`,{className:`mt-1 font-mono text-xs text-muted-foreground`,children:e.name}),(0,m.jsx)(`p`,{className:`mt-2 text-sm text-muted-foreground`,children:e.description||o(`noDescription`)})]}),(0,m.jsxs)(`div`,{className:`flex shrink-0 gap-1`,children:[(0,m.jsx)(a,{variant:`outline`,size:`sm`,disabled:e.builtin,onClick:()=>W(e),children:o(`editTask`)}),(0,m.jsx)(a,{variant:`destructive`,size:`sm`,disabled:e.builtin,onClick:()=>void J(e),children:o(`delete`)})]})]}),(0,m.jsx)(`div`,{className:`mt-3 flex flex-wrap gap-1`,children:e.allowedTools.map(e=>(0,m.jsx)(`span`,{className:`rounded-full bg-muted px-2 py-0.5 font-mono text-xs text-muted-foreground`,children:e},e))}),(0,m.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,m.jsxs)(`span`,{children:[o(`maxRuntimeMs`),e.maxRuntimeMs??`-`]}),(0,m.jsxs)(`span`,{children:[o(`maxToolCalls`),e.maxToolCalls??`-`]})]})]},e.id))})]})}),x?(0,m.jsx)(`div`,{className:`fixed inset-0 z-50 flex items-center justify-center bg-black/50 p-4`,onMouseDown:e=>{e.target===e.currentTarget&&G()},children:(0,m.jsxs)(`div`,{className:`flex max-h-[90vh] w-full max-w-3xl flex-col overflow-hidden rounded-2xl border border-border bg-background shadow-2xl`,onMouseDown:e=>e.stopPropagation(),children:[(0,m.jsxs)(`div`,{className:`shrink-0 border-b border-border px-5 py-4`,children:[(0,m.jsx)(`h2`,{className:`text-base font-semibold text-foreground`,children:o(B?`editAgent`:`createAgent`)}),B?.builtin?(0,m.jsx)(`p`,{className:`mt-1 text-sm text-muted-foreground`,children:o(`builtinAgentReadonly`)}):null]}),(0,m.jsx)(`div`,{className:`min-h-0 flex-1 overflow-y-auto px-5 py-4`,children:(0,m.jsxs)(`div`,{className:`space-y-4`,children:[(0,m.jsxs)(`div`,{className:`rounded-2xl border border-border bg-muted/20 p-3`,children:[(0,m.jsxs)(`div`,{className:`mb-2 flex items-center gap-2 text-sm font-medium text-foreground`,children:[(0,m.jsx)(n,{className:`size-4 text-primary`}),o(`aiFillAgent`)]}),(0,m.jsx)(`p`,{className:`mb-2 text-xs text-muted-foreground`,children:o(`aiFillAgentDescription`)}),(0,m.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:k,disabled:!!B?.builtin||j,onChange:e=>A(e.target.value),placeholder:o(`aiFillAgentPlaceholder`)}),(0,m.jsx)(`div`,{className:`mt-2 flex justify-end`,children:(0,m.jsxs)(a,{variant:`outline`,size:`sm`,onClick:()=>void K(),disabled:!!B?.builtin||j||!k.trim(),children:[(0,m.jsx)(n,{className:`mr-1 size-3.5`}),o(j?`aiFillAgentLoading`:`aiFillAgent`)]})})]}),(0,m.jsxs)(`div`,{className:`grid gap-3 sm:grid-cols-2`,children:[(0,m.jsxs)(`label`,{className:`block text-sm font-medium text-foreground`,children:[o(`agentName`),(0,m.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:T.name,disabled:!!B?.builtin,onChange:e=>V(`name`,e.target.value),placeholder:`reviewer`})]}),(0,m.jsxs)(`label`,{className:`block text-sm font-medium text-foreground`,children:[o(`agentLabel`),(0,m.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:T.label,disabled:!!B?.builtin,onChange:e=>V(`label`,e.target.value),placeholder:o(`agentLabelPlaceholder`)})]})]}),(0,m.jsxs)(`label`,{className:`block text-sm font-medium text-foreground`,children:[o(`agentDescription`),(0,m.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:T.description,disabled:!!B?.builtin,onChange:e=>V(`description`,e.target.value)})]}),(0,m.jsxs)(`label`,{className:`block text-sm font-medium text-foreground`,children:[o(`agentSystemPrompt`),(0,m.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:T.systemPrompt,disabled:!!B?.builtin,onChange:e=>V(`systemPrompt`,e.target.value)})]}),(0,m.jsxs)(`div`,{children:[(0,m.jsx)(`div`,{className:`mb-2 text-sm font-medium text-foreground`,children:o(`allowedTools`)}),(0,m.jsx)(`div`,{className:`grid gap-2 sm:grid-cols-2`,children:i.map(e=>(0,m.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,m.jsx)(`input`,{type:`checkbox`,className:`mt-1`,disabled:!!B?.builtin,checked:T.allowedTools.includes(e.name),onChange:()=>H(e.name)}),(0,m.jsxs)(`span`,{children:[(0,m.jsx)(`span`,{className:`font-medium text-foreground`,children:e.label}),(0,m.jsx)(`span`,{className:`ml-2 font-mono text-xs text-muted-foreground`,children:e.name}),e.riskLevel===`dangerous`?(0,m.jsx)(`span`,{className:`ml-2 rounded-full bg-amber-500/10 px-2 py-0.5 text-xs text-amber-700`,children:o(`highRiskTool`)}):null,(0,m.jsx)(`span`,{className:`mt-1 block text-xs text-muted-foreground`,children:e.description})]})]},e.name))})]}),(0,m.jsxs)(`div`,{className:`grid gap-3 sm:grid-cols-2`,children:[(0,m.jsxs)(`label`,{className:`block text-sm font-medium text-foreground`,children:[o(`maxRuntimeMs`),(0,m.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:T.maxRuntimeMs,disabled:!!B?.builtin,onChange:e=>V(`maxRuntimeMs`,e.target.value)})]}),(0,m.jsxs)(`label`,{className:`block text-sm font-medium text-foreground`,children:[o(`maxToolCalls`),(0,m.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:T.maxToolCalls,disabled:!!B?.builtin,onChange:e=>V(`maxToolCalls`,e.target.value)})]})]}),(0,m.jsxs)(`label`,{className:`flex items-center gap-2 text-sm text-foreground`,children:[(0,m.jsx)(`input`,{type:`checkbox`,checked:T.enabledAsSubagent,disabled:!!B?.builtin,onChange:e=>V(`enabledAsSubagent`,e.target.checked)}),o(`enabledAsSubagent`)]}),L?(0,m.jsx)(`div`,{className:`rounded-md border border-destructive/30 bg-destructive/10 px-3 py-2 text-sm text-destructive`,children:L}):null]})}),(0,m.jsx)(`div`,{className:`shrink-0 border-t border-border px-5 py-4`,children:(0,m.jsxs)(`div`,{className:`flex justify-end gap-2`,children:[(0,m.jsx)(a,{variant:`outline`,onClick:G,disabled:D||j,children:o(`cancel`)}),(0,m.jsx)(a,{onClick:q,disabled:D||j||!!B?.builtin||!v(T),children:o(`save`)})]})})]})}):null]})}export{b as AgentProfilesPage};
|