| import { useEffect, useState } from "react"; |
| import type { AdapterConfigFieldsProps } from "./types"; |
| import { Field, help } from "../components/agent-config-primitives"; |
|
|
| |
| const SHOW_EXPERIMENTAL_ISSUE_WORKTREE_UI = false; |
|
|
| const inputClass = |
| "w-full rounded-md border border-border px-2.5 py-1.5 bg-transparent outline-none text-sm font-mono placeholder:text-muted-foreground/40"; |
|
|
| function asRecord(value: unknown): Record<string, unknown> { |
| return typeof value === "object" && value !== null && !Array.isArray(value) |
| ? (value as Record<string, unknown>) |
| : {}; |
| } |
|
|
| function formatJsonObject(value: unknown): string { |
| const record = asRecord(value); |
| return Object.keys(record).length > 0 ? JSON.stringify(record, null, 2) : ""; |
| } |
|
|
| function updateJsonConfig( |
| isCreate: boolean, |
| key: "runtimeServicesJson" | "payloadTemplateJson", |
| next: string, |
| set: AdapterConfigFieldsProps["set"], |
| mark: AdapterConfigFieldsProps["mark"], |
| configKey: string, |
| ) { |
| if (isCreate) { |
| set?.({ [key]: next }); |
| return; |
| } |
|
|
| const trimmed = next.trim(); |
| if (!trimmed) { |
| mark("adapterConfig", configKey, undefined); |
| return; |
| } |
|
|
| try { |
| const parsed = JSON.parse(trimmed); |
| if (typeof parsed === "object" && parsed !== null && !Array.isArray(parsed)) { |
| mark("adapterConfig", configKey, parsed); |
| } |
| } catch { |
| |
| } |
| } |
|
|
| type JsonFieldProps = Pick< |
| AdapterConfigFieldsProps, |
| "isCreate" | "values" | "set" | "config" | "mark" |
| >; |
|
|
| export function RuntimeServicesJsonField({ |
| isCreate, |
| values, |
| set, |
| config, |
| mark, |
| }: JsonFieldProps) { |
| if (!SHOW_EXPERIMENTAL_ISSUE_WORKTREE_UI) { |
| return null; |
| } |
|
|
| const existing = formatJsonObject(config.workspaceRuntime); |
| const [draft, setDraft] = useState(existing); |
|
|
| useEffect(() => { |
| if (!isCreate) setDraft(existing); |
| }, [existing, isCreate]); |
|
|
| const value = isCreate ? values?.runtimeServicesJson ?? "" : draft; |
|
|
| return ( |
| <Field label="Runtime services JSON" hint={help.runtimeServicesJson}> |
| <textarea |
| className={`${inputClass} min-h-[148px]`} |
| value={value} |
| onChange={(e) => { |
| const next = e.target.value; |
| if (!isCreate) setDraft(next); |
| updateJsonConfig(isCreate, "runtimeServicesJson", next, set, mark, "workspaceRuntime"); |
| }} |
| placeholder={`{\n "services": [\n {\n "name": "preview",\n "lifecycle": "ephemeral",\n "metadata": {\n "purpose": "remote preview"\n }\n }\n ]\n}`} |
| /> |
| </Field> |
| ); |
| } |
|
|
| export function PayloadTemplateJsonField({ |
| isCreate, |
| values, |
| set, |
| config, |
| mark, |
| }: JsonFieldProps) { |
| const existing = formatJsonObject(config.payloadTemplate); |
| const [draft, setDraft] = useState(existing); |
|
|
| useEffect(() => { |
| if (!isCreate) setDraft(existing); |
| }, [existing, isCreate]); |
|
|
| const value = isCreate ? values?.payloadTemplateJson ?? "" : draft; |
|
|
| return ( |
| <Field label="Payload template JSON" hint={help.payloadTemplateJson}> |
| <textarea |
| className={`${inputClass} min-h-[132px]`} |
| value={value} |
| onChange={(e) => { |
| const next = e.target.value; |
| if (!isCreate) setDraft(next); |
| updateJsonConfig(isCreate, "payloadTemplateJson", next, set, mark, "payloadTemplate"); |
| }} |
| placeholder={`{\n "agentId": "remote-agent-123",\n "metadata": {\n "team": "platform"\n }\n}`} |
| /> |
| </Field> |
| ); |
| } |
|
|