mirror of
https://github.com/Kilo-Org/kilocode.git
synced 2026-10-24 01:24:18 +08:00
feat(settings): implement Prompts and Experimental tabs
This commit is contained in:
@@ -1,30 +1,228 @@
|
||||
import { Component } from "solid-js"
|
||||
import { Component, For, Show, createMemo } from "solid-js"
|
||||
import { useConfig } from "../../context/config"
|
||||
|
||||
const selectStyle = {
|
||||
padding: "4px 8px",
|
||||
"border-radius": "4px",
|
||||
border: "1px solid var(--vscode-dropdown-border, var(--vscode-panel-border))",
|
||||
background: "var(--vscode-dropdown-background)",
|
||||
color: "var(--vscode-dropdown-foreground)",
|
||||
"font-size": "12px",
|
||||
"font-family": "var(--vscode-font-family)",
|
||||
cursor: "pointer",
|
||||
outline: "none",
|
||||
"min-width": "100px",
|
||||
}
|
||||
|
||||
const inputStyle = {
|
||||
padding: "4px 8px",
|
||||
"border-radius": "4px",
|
||||
border: "1px solid var(--vscode-input-border, var(--vscode-panel-border))",
|
||||
background: "var(--vscode-input-background)",
|
||||
color: "var(--vscode-input-foreground)",
|
||||
"font-size": "12px",
|
||||
"font-family": "var(--vscode-font-family)",
|
||||
outline: "none",
|
||||
width: "100px",
|
||||
}
|
||||
|
||||
interface SettingRowProps {
|
||||
label: string
|
||||
description: string
|
||||
last?: boolean
|
||||
children: any
|
||||
}
|
||||
|
||||
const SettingRow: Component<SettingRowProps> = (props) => (
|
||||
<div
|
||||
style={{
|
||||
display: "flex",
|
||||
"align-items": "center",
|
||||
"justify-content": "space-between",
|
||||
padding: "10px 12px",
|
||||
background: "var(--vscode-editor-background)",
|
||||
"border-bottom": props.last ? "none" : "1px solid var(--vscode-panel-border)",
|
||||
}}
|
||||
>
|
||||
<div style={{ flex: 1, "min-width": 0, "margin-right": "12px" }}>
|
||||
<div style={{ "font-size": "12px", "font-weight": "500", color: "var(--vscode-foreground)" }}>{props.label}</div>
|
||||
<div style={{ "font-size": "11px", color: "var(--vscode-descriptionForeground)", "margin-top": "2px" }}>
|
||||
{props.description}
|
||||
</div>
|
||||
</div>
|
||||
{props.children}
|
||||
</div>
|
||||
)
|
||||
|
||||
const ExperimentalTab: Component = () => {
|
||||
const { config, updateConfig } = useConfig()
|
||||
|
||||
const experimental = createMemo(() => config().experimental ?? {})
|
||||
|
||||
const updateExperimental = (key: string, value: unknown) => {
|
||||
updateConfig({
|
||||
experimental: { ...experimental(), [key]: value },
|
||||
})
|
||||
}
|
||||
|
||||
return (
|
||||
<div>
|
||||
<div
|
||||
style={{
|
||||
background: "var(--vscode-editor-background)",
|
||||
border: "1px solid var(--vscode-panel-border)",
|
||||
"border-radius": "4px",
|
||||
padding: "16px",
|
||||
overflow: "hidden",
|
||||
}}
|
||||
>
|
||||
<p
|
||||
{/* Share mode */}
|
||||
<SettingRow label="Share Mode" description="How session sharing behaves">
|
||||
<select
|
||||
style={selectStyle}
|
||||
value={config().share ?? "manual"}
|
||||
onChange={(e) => updateConfig({ share: e.currentTarget.value as "manual" | "auto" | "disabled" })}
|
||||
>
|
||||
<option value="manual">Manual</option>
|
||||
<option value="auto">Auto</option>
|
||||
<option value="disabled">Disabled</option>
|
||||
</select>
|
||||
</SettingRow>
|
||||
|
||||
{/* Formatter */}
|
||||
<SettingRow label="Formatter" description="Enable the automatic code formatter">
|
||||
<label style={{ display: "flex", "align-items": "center", cursor: "pointer" }}>
|
||||
<input
|
||||
type="checkbox"
|
||||
checked={config().formatter !== false}
|
||||
onChange={(e) => updateConfig({ formatter: e.currentTarget.checked ? {} : false })}
|
||||
style={{ cursor: "pointer" }}
|
||||
/>
|
||||
</label>
|
||||
</SettingRow>
|
||||
|
||||
{/* LSP */}
|
||||
<SettingRow label="LSP" description="Enable language server protocol integration">
|
||||
<label style={{ display: "flex", "align-items": "center", cursor: "pointer" }}>
|
||||
<input
|
||||
type="checkbox"
|
||||
checked={config().lsp !== false}
|
||||
onChange={(e) => updateConfig({ lsp: e.currentTarget.checked ? {} : false })}
|
||||
style={{ cursor: "pointer" }}
|
||||
/>
|
||||
</label>
|
||||
</SettingRow>
|
||||
|
||||
{/* Disable paste summary */}
|
||||
<SettingRow label="Disable Paste Summary" description="Don't summarize large pasted content">
|
||||
<label style={{ display: "flex", "align-items": "center", cursor: "pointer" }}>
|
||||
<input
|
||||
type="checkbox"
|
||||
checked={experimental().disable_paste_summary ?? false}
|
||||
onChange={(e) => updateExperimental("disable_paste_summary", e.currentTarget.checked)}
|
||||
style={{ cursor: "pointer" }}
|
||||
/>
|
||||
</label>
|
||||
</SettingRow>
|
||||
|
||||
{/* Batch tool */}
|
||||
<SettingRow label="Batch Tool" description="Enable batching of multiple tool calls">
|
||||
<label style={{ display: "flex", "align-items": "center", cursor: "pointer" }}>
|
||||
<input
|
||||
type="checkbox"
|
||||
checked={experimental().batch_tool ?? false}
|
||||
onChange={(e) => updateExperimental("batch_tool", e.currentTarget.checked)}
|
||||
style={{ cursor: "pointer" }}
|
||||
/>
|
||||
</label>
|
||||
</SettingRow>
|
||||
|
||||
{/* Continue loop on deny */}
|
||||
<SettingRow label="Continue on Deny" description="Continue the agent loop when a permission is denied">
|
||||
<label style={{ display: "flex", "align-items": "center", cursor: "pointer" }}>
|
||||
<input
|
||||
type="checkbox"
|
||||
checked={experimental().continue_loop_on_deny ?? false}
|
||||
onChange={(e) => updateExperimental("continue_loop_on_deny", e.currentTarget.checked)}
|
||||
style={{ cursor: "pointer" }}
|
||||
/>
|
||||
</label>
|
||||
</SettingRow>
|
||||
|
||||
{/* MCP timeout */}
|
||||
<SettingRow label="MCP Timeout (ms)" description="Timeout for MCP server requests in milliseconds" last>
|
||||
<input
|
||||
type="number"
|
||||
style={inputStyle}
|
||||
value={experimental().mcp_timeout ?? 60000}
|
||||
onChange={(e) => {
|
||||
const value = parseInt(e.currentTarget.value, 10)
|
||||
if (!isNaN(value) && value > 0) {
|
||||
updateExperimental("mcp_timeout", value)
|
||||
}
|
||||
}}
|
||||
/>
|
||||
</SettingRow>
|
||||
</div>
|
||||
|
||||
{/* Tool toggles */}
|
||||
<Show when={config().tools && Object.keys(config().tools ?? {}).length > 0}>
|
||||
<h4
|
||||
style={{
|
||||
"font-size": "12px",
|
||||
color: "var(--vscode-descriptionForeground)",
|
||||
margin: 0,
|
||||
"line-height": "1.5",
|
||||
"font-size": "13px",
|
||||
"margin-top": "16px",
|
||||
"margin-bottom": "8px",
|
||||
color: "var(--vscode-foreground)",
|
||||
}}
|
||||
>
|
||||
<strong style={{ color: "var(--vscode-foreground)" }}>This section is not implemented yet.</strong> It will
|
||||
contain configuration options and explanatory text related to the selected settings category. During
|
||||
reimplementation, use this space to validate layout, spacing, scrolling behavior, and navigation state before
|
||||
wiring up real controls.
|
||||
</p>
|
||||
</div>
|
||||
Tool Toggles
|
||||
</h4>
|
||||
<div
|
||||
style={{
|
||||
border: "1px solid var(--vscode-panel-border)",
|
||||
"border-radius": "4px",
|
||||
overflow: "hidden",
|
||||
}}
|
||||
>
|
||||
<For each={Object.entries(config().tools ?? {})}>
|
||||
{([name, enabled], index) => (
|
||||
<div
|
||||
style={{
|
||||
display: "flex",
|
||||
"align-items": "center",
|
||||
"justify-content": "space-between",
|
||||
padding: "8px 12px",
|
||||
background: "var(--vscode-editor-background)",
|
||||
"border-bottom":
|
||||
index() < Object.keys(config().tools ?? {}).length - 1
|
||||
? "1px solid var(--vscode-panel-border)"
|
||||
: "none",
|
||||
}}
|
||||
>
|
||||
<span
|
||||
style={{
|
||||
"font-size": "12px",
|
||||
"font-family": "var(--vscode-editor-font-family, monospace)",
|
||||
color: "var(--vscode-foreground)",
|
||||
}}
|
||||
>
|
||||
{name}
|
||||
</span>
|
||||
<label style={{ display: "flex", "align-items": "center", cursor: "pointer" }}>
|
||||
<input
|
||||
type="checkbox"
|
||||
checked={enabled}
|
||||
onChange={(e) => {
|
||||
updateConfig({
|
||||
tools: { ...config().tools, [name]: e.currentTarget.checked },
|
||||
})
|
||||
}}
|
||||
style={{ cursor: "pointer" }}
|
||||
/>
|
||||
</label>
|
||||
</div>
|
||||
)}
|
||||
</For>
|
||||
</div>
|
||||
</Show>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1,29 +1,151 @@
|
||||
import { Component } from "solid-js"
|
||||
import { Component, For, createSignal } from "solid-js"
|
||||
import { useConfig } from "../../context/config"
|
||||
|
||||
const inputStyle = {
|
||||
padding: "4px 8px",
|
||||
"border-radius": "4px",
|
||||
border: "1px solid var(--vscode-input-border, var(--vscode-panel-border))",
|
||||
background: "var(--vscode-input-background)",
|
||||
color: "var(--vscode-input-foreground)",
|
||||
"font-size": "12px",
|
||||
"font-family": "var(--vscode-font-family)",
|
||||
outline: "none",
|
||||
flex: "1",
|
||||
}
|
||||
|
||||
const PromptsTab: Component = () => {
|
||||
const { config, updateConfig } = useConfig()
|
||||
const [newInstruction, setNewInstruction] = createSignal("")
|
||||
|
||||
const instructions = () => config().instructions ?? []
|
||||
|
||||
const addInstruction = () => {
|
||||
const value = newInstruction().trim()
|
||||
if (!value) {
|
||||
return
|
||||
}
|
||||
const current = [...instructions()]
|
||||
if (!current.includes(value)) {
|
||||
current.push(value)
|
||||
updateConfig({ instructions: current })
|
||||
}
|
||||
setNewInstruction("")
|
||||
}
|
||||
|
||||
const removeInstruction = (index: number) => {
|
||||
const current = [...instructions()]
|
||||
current.splice(index, 1)
|
||||
updateConfig({ instructions: current })
|
||||
}
|
||||
|
||||
return (
|
||||
<div>
|
||||
{/* Instructions file paths */}
|
||||
<div
|
||||
style={{
|
||||
background: "var(--vscode-editor-background)",
|
||||
border: "1px solid var(--vscode-panel-border)",
|
||||
"border-radius": "4px",
|
||||
padding: "16px",
|
||||
overflow: "hidden",
|
||||
}}
|
||||
>
|
||||
<p
|
||||
<div
|
||||
style={{
|
||||
"font-size": "12px",
|
||||
color: "var(--vscode-descriptionForeground)",
|
||||
margin: 0,
|
||||
"line-height": "1.5",
|
||||
padding: "10px 12px",
|
||||
background: "var(--vscode-editor-background)",
|
||||
"border-bottom": "1px solid var(--vscode-panel-border)",
|
||||
}}
|
||||
>
|
||||
<strong style={{ color: "var(--vscode-foreground)" }}>This section is not implemented yet.</strong> It will
|
||||
contain configuration options and explanatory text related to the selected settings category. During
|
||||
reimplementation, use this space to validate layout, spacing, scrolling behavior, and navigation state before
|
||||
wiring up real controls.
|
||||
</p>
|
||||
<div style={{ "font-size": "12px", "font-weight": "500", color: "var(--vscode-foreground)" }}>
|
||||
Additional Instruction Files
|
||||
</div>
|
||||
<div
|
||||
style={{
|
||||
"font-size": "11px",
|
||||
color: "var(--vscode-descriptionForeground)",
|
||||
"margin-top": "2px",
|
||||
}}
|
||||
>
|
||||
Paths to additional instruction files that are included in the system prompt
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Add new instruction path */}
|
||||
<div
|
||||
style={{
|
||||
display: "flex",
|
||||
gap: "8px",
|
||||
padding: "8px 12px",
|
||||
background: "var(--vscode-editor-background)",
|
||||
"border-bottom": instructions().length > 0 ? "1px solid var(--vscode-panel-border)" : "none",
|
||||
}}
|
||||
>
|
||||
<input
|
||||
type="text"
|
||||
style={inputStyle}
|
||||
value={newInstruction()}
|
||||
placeholder="e.g. ./INSTRUCTIONS.md"
|
||||
onInput={(e) => setNewInstruction(e.currentTarget.value)}
|
||||
onKeyDown={(e) => {
|
||||
if (e.key === "Enter") {
|
||||
addInstruction()
|
||||
}
|
||||
}}
|
||||
/>
|
||||
<button
|
||||
onClick={addInstruction}
|
||||
style={{
|
||||
padding: "4px 12px",
|
||||
"border-radius": "4px",
|
||||
border: "1px solid var(--vscode-button-border, transparent)",
|
||||
background: "var(--vscode-button-background)",
|
||||
color: "var(--vscode-button-foreground)",
|
||||
"font-size": "12px",
|
||||
cursor: "pointer",
|
||||
}}
|
||||
>
|
||||
Add
|
||||
</button>
|
||||
</div>
|
||||
|
||||
{/* Instructions list */}
|
||||
<For each={instructions()}>
|
||||
{(path, index) => (
|
||||
<div
|
||||
style={{
|
||||
display: "flex",
|
||||
"align-items": "center",
|
||||
"justify-content": "space-between",
|
||||
padding: "6px 12px",
|
||||
background: "var(--vscode-editor-background)",
|
||||
"border-bottom": index() < instructions().length - 1 ? "1px solid var(--vscode-panel-border)" : "none",
|
||||
}}
|
||||
>
|
||||
<span
|
||||
style={{
|
||||
"font-size": "12px",
|
||||
"font-family": "var(--vscode-editor-font-family, monospace)",
|
||||
color: "var(--vscode-foreground)",
|
||||
}}
|
||||
>
|
||||
{path}
|
||||
</span>
|
||||
<button
|
||||
onClick={() => removeInstruction(index())}
|
||||
style={{
|
||||
padding: "2px 8px",
|
||||
"border-radius": "4px",
|
||||
border: "1px solid var(--vscode-panel-border)",
|
||||
background: "transparent",
|
||||
color: "var(--vscode-descriptionForeground)",
|
||||
"font-size": "11px",
|
||||
cursor: "pointer",
|
||||
}}
|
||||
>
|
||||
✕
|
||||
</button>
|
||||
</div>
|
||||
)}
|
||||
</For>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user