feat(settings): implement Prompts and Experimental tabs

This commit is contained in:
Mark IJbema
2026-02-12 15:12:47 +01:00
parent 1497d00b30
commit 8a3dde7af5
2 changed files with 347 additions and 27 deletions
@@ -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>
)