fix: biome format issues (12 errors)
This commit is contained in:
@@ -3,8 +3,8 @@ import { printCliError, printCliLine } from "./cli-output.js";
|
|||||||
import { getCommandRegistry } from "./cli-registry.js";
|
import { getCommandRegistry } from "./cli-registry.js";
|
||||||
import { formatCliUsage as formatCliUsageWithGroups } from "./cli-usage.js";
|
import { formatCliUsage as formatCliUsageWithGroups } from "./cli-usage.js";
|
||||||
import { createCasDispatcher } from "./commands/cas/index.js";
|
import { createCasDispatcher } from "./commands/cas/index.js";
|
||||||
import { createInitDispatcher } from "./commands/init/index.js";
|
|
||||||
import { dispatchConnect } from "./commands/connect/index.js";
|
import { dispatchConnect } from "./commands/connect/index.js";
|
||||||
|
import { createInitDispatcher } from "./commands/init/index.js";
|
||||||
import { dispatchSetup } from "./commands/setup/index.js";
|
import { dispatchSetup } from "./commands/setup/index.js";
|
||||||
import { createThreadDispatcher, dispatchLive, dispatchRun } from "./commands/thread/index.js";
|
import { createThreadDispatcher, dispatchLive, dispatchRun } from "./commands/thread/index.js";
|
||||||
import { createWorkflowDispatcher } from "./commands/workflow/index.js";
|
import { createWorkflowDispatcher } from "./commands/workflow/index.js";
|
||||||
|
|||||||
@@ -48,11 +48,13 @@ async function handleGatewayMessage(
|
|||||||
const headers = new Headers(req.headers);
|
const headers = new Headers(req.headers);
|
||||||
let resp: Response;
|
let resp: Response;
|
||||||
try {
|
try {
|
||||||
resp = await params.appFetch(new Request(localUrl, {
|
resp = await params.appFetch(
|
||||||
method: req.method,
|
new Request(localUrl, {
|
||||||
headers,
|
method: req.method,
|
||||||
body: req.body === null ? undefined : req.body,
|
headers,
|
||||||
}));
|
body: req.body === null ? undefined : req.body,
|
||||||
|
}),
|
||||||
|
);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
params.log("R4N7BQ3C", `app.fetch failed: ${String(e)}`);
|
params.log("R4N7BQ3C", `app.fetch failed: ${String(e)}`);
|
||||||
const errBody: WsResponse = {
|
const errBody: WsResponse = {
|
||||||
|
|||||||
@@ -12,7 +12,8 @@ import { useHashRoute } from "./use-hash-route.ts";
|
|||||||
|
|
||||||
export function App() {
|
export function App() {
|
||||||
const [authed, setAuthed] = useState(hasApiKey());
|
const [authed, setAuthed] = useState(hasApiKey());
|
||||||
const { view, client, threadId, workflowName, setView, setClient, setThreadId, setWorkflowName } = useHashRoute();
|
const { view, client, threadId, workflowName, setView, setClient, setThreadId, setWorkflowName } =
|
||||||
|
useHashRoute();
|
||||||
const [showRun, setShowRun] = useState(false);
|
const [showRun, setShowRun] = useState(false);
|
||||||
|
|
||||||
if (!authed) {
|
if (!authed) {
|
||||||
@@ -51,7 +52,11 @@ export function App() {
|
|||||||
<WorkflowList client={client} onSelect={setWorkflowName} />
|
<WorkflowList client={client} onSelect={setWorkflowName} />
|
||||||
)}
|
)}
|
||||||
{client && view === "workflows" && workflowName !== null && (
|
{client && view === "workflows" && workflowName !== null && (
|
||||||
<WorkflowDetail client={client} workflowName={workflowName} onBack={() => setWorkflowName(null)} />
|
<WorkflowDetail
|
||||||
|
client={client}
|
||||||
|
workflowName={workflowName}
|
||||||
|
onBack={() => setWorkflowName(null)}
|
||||||
|
/>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
</main>
|
</main>
|
||||||
|
|||||||
@@ -96,42 +96,45 @@ export function ThreadDetail({ client, threadId, onBack }: Props) {
|
|||||||
// Track which occurrence to jump to next per role (cycling)
|
// Track which occurrence to jump to next per role (cycling)
|
||||||
const clickCycleRef = useRef<Map<string, number>>(new Map());
|
const clickCycleRef = useRef<Map<string, number>>(new Map());
|
||||||
|
|
||||||
const handleGraphNodeClick = useCallback((nodeId: string) => {
|
const handleGraphNodeClick = useCallback(
|
||||||
// Only allow clicks on lit (non-default) nodes
|
(nodeId: string) => {
|
||||||
if (nodeStates.get(nodeId) === undefined || nodeStates.get(nodeId) === "default") return;
|
// Only allow clicks on lit (non-default) nodes
|
||||||
|
if (nodeStates.get(nodeId) === undefined || nodeStates.get(nodeId) === "default") return;
|
||||||
|
|
||||||
// __start__: scroll to the first record (thread-start prompt)
|
// __start__: scroll to the first record (thread-start prompt)
|
||||||
if (nodeId === "__start__") {
|
if (nodeId === "__start__") {
|
||||||
const firstCard = document.querySelector('[data-record-index="0"]');
|
const firstCard = document.querySelector('[data-record-index="0"]');
|
||||||
if (firstCard !== null) firstCard.scrollIntoView({ behavior: "smooth", block: "center" });
|
if (firstCard !== null) firstCard.scrollIntoView({ behavior: "smooth", block: "center" });
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// __end__: scroll to bottom
|
// __end__: scroll to bottom
|
||||||
if (nodeId === "__end__") {
|
if (nodeId === "__end__") {
|
||||||
recordsEndRef.current?.scrollIntoView({ behavior: "smooth", block: "end" });
|
recordsEndRef.current?.scrollIntoView({ behavior: "smooth", block: "end" });
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Role nodes: cycle through occurrences
|
// Role nodes: cycle through occurrences
|
||||||
const indices = indicesByRole.get(nodeId);
|
const indices = indicesByRole.get(nodeId);
|
||||||
if (indices === undefined || indices.length === 0) return;
|
if (indices === undefined || indices.length === 0) return;
|
||||||
|
|
||||||
const cycle = clickCycleRef.current.get(nodeId) ?? 0;
|
const cycle = clickCycleRef.current.get(nodeId) ?? 0;
|
||||||
const idx = indices[cycle % indices.length];
|
const idx = indices[cycle % indices.length];
|
||||||
clickCycleRef.current.set(nodeId, cycle + 1);
|
clickCycleRef.current.set(nodeId, cycle + 1);
|
||||||
|
|
||||||
const el = document.querySelector(`[data-record-index="${idx}"]`);
|
const el = document.querySelector(`[data-record-index="${idx}"]`);
|
||||||
if (el !== null) {
|
if (el !== null) {
|
||||||
el.scrollIntoView({ behavior: "smooth", block: "center" });
|
el.scrollIntoView({ behavior: "smooth", block: "center" });
|
||||||
if (highlightTimerRef.current !== null) clearTimeout(highlightTimerRef.current);
|
if (highlightTimerRef.current !== null) clearTimeout(highlightTimerRef.current);
|
||||||
setHighlightedRole(nodeId);
|
setHighlightedRole(nodeId);
|
||||||
highlightTimerRef.current = setTimeout(() => {
|
highlightTimerRef.current = setTimeout(() => {
|
||||||
setHighlightedRole(null);
|
setHighlightedRole(null);
|
||||||
highlightTimerRef.current = null;
|
highlightTimerRef.current = null;
|
||||||
}, 1500);
|
}, 1500);
|
||||||
}
|
}
|
||||||
}, [nodeStates, indicesByRole]);
|
},
|
||||||
|
[nodeStates, indicesByRole],
|
||||||
|
);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
return () => {
|
return () => {
|
||||||
@@ -285,7 +288,11 @@ export function ThreadDetail({ client, threadId, onBack }: Props) {
|
|||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
return <div key={key} data-record-index={i}><RecordCard record={r} highlighted={false} /></div>;
|
return (
|
||||||
|
<div key={key} data-record-index={i}>
|
||||||
|
<RecordCard record={r} highlighted={false} />
|
||||||
|
</div>
|
||||||
|
);
|
||||||
})}
|
})}
|
||||||
<div ref={recordsEndRef} aria-hidden />
|
<div ref={recordsEndRef} aria-hidden />
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -76,7 +76,14 @@ function flattenSchema(
|
|||||||
);
|
);
|
||||||
for (const [pName, pDef] of Object.entries(variantProps)) {
|
for (const [pName, pDef] of Object.entries(variantProps)) {
|
||||||
if (pDef.const !== undefined) continue;
|
if (pDef.const !== undefined) continue;
|
||||||
const subRows = flattenProperty(pName, pDef, depth + 1, childPrefix, `${keyPrefix}v${vi}-`, variantRequired);
|
const subRows = flattenProperty(
|
||||||
|
pName,
|
||||||
|
pDef,
|
||||||
|
depth + 1,
|
||||||
|
childPrefix,
|
||||||
|
`${keyPrefix}v${vi}-`,
|
||||||
|
variantRequired,
|
||||||
|
);
|
||||||
rows.push(...subRows);
|
rows.push(...subRows);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -121,7 +128,14 @@ function flattenProperty(
|
|||||||
|
|
||||||
if (prop.type === "object" && prop.properties !== undefined) {
|
if (prop.type === "object" && prop.properties !== undefined) {
|
||||||
const childPrefix = depth > 0 ? `${parentPrefix} ` : " ";
|
const childPrefix = depth > 0 ? `${parentPrefix} ` : " ";
|
||||||
rows.push(...flattenSchema(prop as Record<string, unknown>, depth + 1, childPrefix, `${keyPrefix}${name}-`));
|
rows.push(
|
||||||
|
...flattenSchema(
|
||||||
|
prop as Record<string, unknown>,
|
||||||
|
depth + 1,
|
||||||
|
childPrefix,
|
||||||
|
`${keyPrefix}${name}-`,
|
||||||
|
),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (prop.type === "array") {
|
if (prop.type === "array") {
|
||||||
@@ -134,7 +148,14 @@ function flattenProperty(
|
|||||||
|
|
||||||
if (hasOneOf) {
|
if (hasOneOf) {
|
||||||
const childPrefix = depth > 0 ? `${parentPrefix} ` : " ";
|
const childPrefix = depth > 0 ? `${parentPrefix} ` : " ";
|
||||||
rows.push(...flattenSchema(prop as Record<string, unknown>, depth + 1, childPrefix, `${keyPrefix}${name}-`));
|
rows.push(
|
||||||
|
...flattenSchema(
|
||||||
|
prop as Record<string, unknown>,
|
||||||
|
depth + 1,
|
||||||
|
childPrefix,
|
||||||
|
`${keyPrefix}${name}-`,
|
||||||
|
),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return rows;
|
return rows;
|
||||||
@@ -142,13 +163,7 @@ function flattenProperty(
|
|||||||
|
|
||||||
// ── Components ──────────────────────────────────────────────────────
|
// ── Components ──────────────────────────────────────────────────────
|
||||||
|
|
||||||
function RoleCard({
|
function RoleCard({ roleName, role }: { roleName: string; role: WorkflowRoleDescriptor }) {
|
||||||
roleName,
|
|
||||||
role,
|
|
||||||
}: {
|
|
||||||
roleName: string;
|
|
||||||
role: WorkflowRoleDescriptor;
|
|
||||||
}) {
|
|
||||||
const rows = flattenSchema(role.schema, 0, "", `${roleName}-`);
|
const rows = flattenSchema(role.schema, 0, "", `${roleName}-`);
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
@@ -156,10 +171,7 @@ function RoleCard({
|
|||||||
className="rounded-lg border p-4"
|
className="rounded-lg border p-4"
|
||||||
style={{ borderColor: "var(--color-border)", background: "var(--color-surface)" }}
|
style={{ borderColor: "var(--color-border)", background: "var(--color-surface)" }}
|
||||||
>
|
>
|
||||||
<h4
|
<h4 className="text-sm font-semibold font-mono mb-1" style={{ color: "var(--color-text)" }}>
|
||||||
className="text-sm font-semibold font-mono mb-1"
|
|
||||||
style={{ color: "var(--color-text)" }}
|
|
||||||
>
|
|
||||||
{roleName}
|
{roleName}
|
||||||
</h4>
|
</h4>
|
||||||
{role.description !== "" && (
|
{role.description !== "" && (
|
||||||
@@ -178,9 +190,24 @@ function RoleCard({
|
|||||||
<table className="w-full text-xs" style={{ borderCollapse: "collapse" }}>
|
<table className="w-full text-xs" style={{ borderCollapse: "collapse" }}>
|
||||||
<thead>
|
<thead>
|
||||||
<tr style={{ borderBottom: "1px solid var(--color-border)" }}>
|
<tr style={{ borderBottom: "1px solid var(--color-border)" }}>
|
||||||
<th className="text-left py-1 pr-3 font-medium" style={{ color: "var(--color-text-muted)" }}>Field</th>
|
<th
|
||||||
<th className="text-left py-1 pr-3 font-medium" style={{ color: "var(--color-text-muted)" }}>Type</th>
|
className="text-left py-1 pr-3 font-medium"
|
||||||
<th className="text-left py-1 font-medium" style={{ color: "var(--color-text-muted)" }}>Description</th>
|
style={{ color: "var(--color-text-muted)" }}
|
||||||
|
>
|
||||||
|
Field
|
||||||
|
</th>
|
||||||
|
<th
|
||||||
|
className="text-left py-1 pr-3 font-medium"
|
||||||
|
style={{ color: "var(--color-text-muted)" }}
|
||||||
|
>
|
||||||
|
Type
|
||||||
|
</th>
|
||||||
|
<th
|
||||||
|
className="text-left py-1 font-medium"
|
||||||
|
style={{ color: "var(--color-text-muted)" }}
|
||||||
|
>
|
||||||
|
Description
|
||||||
|
</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
@@ -200,8 +227,12 @@ function RoleCard({
|
|||||||
>
|
>
|
||||||
{r.name}
|
{r.name}
|
||||||
</td>
|
</td>
|
||||||
<td className="py-1 pr-3 font-mono" style={{ color: "var(--color-text-muted)" }}>{r.type}</td>
|
<td className="py-1 pr-3 font-mono" style={{ color: "var(--color-text-muted)" }}>
|
||||||
<td className="py-1" style={{ color: "var(--color-text)" }}>{r.description || (r.isVariantHeader ? "" : "—")}</td>
|
{r.type}
|
||||||
|
</td>
|
||||||
|
<td className="py-1" style={{ color: "var(--color-text)" }}>
|
||||||
|
{r.description || (r.isVariantHeader ? "" : "—")}
|
||||||
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
))}
|
))}
|
||||||
</tbody>
|
</tbody>
|
||||||
@@ -274,12 +305,8 @@ export function WorkflowDetail({ client, workflowName, onBack }: Props) {
|
|||||||
|
|
||||||
<h2 className="text-xl font-semibold mb-4 font-mono">{workflowName}</h2>
|
<h2 className="text-xl font-semibold mb-4 font-mono">{workflowName}</h2>
|
||||||
|
|
||||||
{status === "loading" && (
|
{status === "loading" && <p style={{ color: "var(--color-text-muted)" }}>Loading...</p>}
|
||||||
<p style={{ color: "var(--color-text-muted)" }}>Loading...</p>
|
{status === "error" && <p style={{ color: "var(--color-error)" }}>Error: {error}</p>}
|
||||||
)}
|
|
||||||
{status === "error" && (
|
|
||||||
<p style={{ color: "var(--color-error)" }}>Error: {error}</p>
|
|
||||||
)}
|
|
||||||
|
|
||||||
{detail !== null && (
|
{detail !== null && (
|
||||||
<div className="flex gap-4" style={{ minHeight: "calc(100vh - 160px)" }}>
|
<div className="flex gap-4" style={{ minHeight: "calc(100vh - 160px)" }}>
|
||||||
@@ -327,7 +354,10 @@ export function WorkflowDetail({ client, workflowName, onBack }: Props) {
|
|||||||
className="rounded-lg border p-4"
|
className="rounded-lg border p-4"
|
||||||
style={{ borderColor: "var(--color-border)", background: "var(--color-surface)" }}
|
style={{ borderColor: "var(--color-border)", background: "var(--color-surface)" }}
|
||||||
>
|
>
|
||||||
<p className="text-sm whitespace-pre-wrap mb-3" style={{ color: "var(--color-text)" }}>
|
<p
|
||||||
|
className="text-sm whitespace-pre-wrap mb-3"
|
||||||
|
style={{ color: "var(--color-text)" }}
|
||||||
|
>
|
||||||
{descriptor !== null && descriptor.description !== ""
|
{descriptor !== null && descriptor.description !== ""
|
||||||
? descriptor.description
|
? descriptor.description
|
||||||
: "—"}
|
: "—"}
|
||||||
|
|||||||
@@ -10,7 +10,13 @@ const FEEDBACK_RADIUS = 16;
|
|||||||
* Build an SVG path for a feedback (back) edge that routes to the given side of the nodes.
|
* Build an SVG path for a feedback (back) edge that routes to the given side of the nodes.
|
||||||
* The path goes: source → arc → vertical up → arc → target
|
* The path goes: source → arc → vertical up → arc → target
|
||||||
*/
|
*/
|
||||||
function feedbackPath(sourceX: number, sourceY: number, targetX: number, targetY: number, side: "right" | "left"): string {
|
function feedbackPath(
|
||||||
|
sourceX: number,
|
||||||
|
sourceY: number,
|
||||||
|
targetX: number,
|
||||||
|
targetY: number,
|
||||||
|
side: "right" | "left",
|
||||||
|
): string {
|
||||||
const d = side === "right" ? 1 : -1;
|
const d = side === "right" ? 1 : -1;
|
||||||
const offsetX =
|
const offsetX =
|
||||||
side === "right"
|
side === "right"
|
||||||
@@ -88,12 +94,7 @@ export function ConditionEdge(props: EdgeProps) {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<BaseEdge
|
<BaseEdge id={id} path={path} markerEnd={markerEnd} style={{ stroke, strokeWidth: 1.5 }} />
|
||||||
id={id}
|
|
||||||
path={path}
|
|
||||||
markerEnd={markerEnd}
|
|
||||||
style={{ stroke, strokeWidth: 1.5 }}
|
|
||||||
/>
|
|
||||||
{label !== "" && (
|
{label !== "" && (
|
||||||
<EdgeLabelRenderer>
|
<EdgeLabelRenderer>
|
||||||
<div
|
<div
|
||||||
|
|||||||
@@ -45,11 +45,41 @@ export function RoleNode(props: NodeProps) {
|
|||||||
}}
|
}}
|
||||||
title={data.description}
|
title={data.description}
|
||||||
>
|
>
|
||||||
<Handle type="target" position={Position.Top} id="top-in" style={handleStyle} isConnectable={false} />
|
<Handle
|
||||||
<Handle type="target" position={Position.Left} id="left-in" style={handleStyle} isConnectable={false} />
|
type="target"
|
||||||
<Handle type="target" position={Position.Right} id="right-in" style={handleStyle} isConnectable={false} />
|
position={Position.Top}
|
||||||
<Handle type="source" position={Position.Left} id="left-out" style={handleStyle} isConnectable={false} />
|
id="top-in"
|
||||||
<Handle type="source" position={Position.Right} id="right-out" style={handleStyle} isConnectable={false} />
|
style={handleStyle}
|
||||||
|
isConnectable={false}
|
||||||
|
/>
|
||||||
|
<Handle
|
||||||
|
type="target"
|
||||||
|
position={Position.Left}
|
||||||
|
id="left-in"
|
||||||
|
style={handleStyle}
|
||||||
|
isConnectable={false}
|
||||||
|
/>
|
||||||
|
<Handle
|
||||||
|
type="target"
|
||||||
|
position={Position.Right}
|
||||||
|
id="right-in"
|
||||||
|
style={handleStyle}
|
||||||
|
isConnectable={false}
|
||||||
|
/>
|
||||||
|
<Handle
|
||||||
|
type="source"
|
||||||
|
position={Position.Left}
|
||||||
|
id="left-out"
|
||||||
|
style={handleStyle}
|
||||||
|
isConnectable={false}
|
||||||
|
/>
|
||||||
|
<Handle
|
||||||
|
type="source"
|
||||||
|
position={Position.Right}
|
||||||
|
id="right-out"
|
||||||
|
style={handleStyle}
|
||||||
|
isConnectable={false}
|
||||||
|
/>
|
||||||
<div className="flex items-center gap-1.5 font-mono">
|
<div className="flex items-center gap-1.5 font-mono">
|
||||||
{icon !== null && (
|
{icon !== null && (
|
||||||
<span
|
<span
|
||||||
@@ -67,7 +97,13 @@ export function RoleNode(props: NodeProps) {
|
|||||||
{data.description}
|
{data.description}
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
<Handle type="source" position={Position.Bottom} id="bottom-out" style={handleStyle} isConnectable={false} />
|
<Handle
|
||||||
|
type="source"
|
||||||
|
position={Position.Bottom}
|
||||||
|
id="bottom-out"
|
||||||
|
style={handleStyle}
|
||||||
|
isConnectable={false}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -50,7 +50,13 @@ export function TerminalNode(props: NodeProps) {
|
|||||||
isConnectable={false}
|
isConnectable={false}
|
||||||
/>
|
/>
|
||||||
) : (
|
) : (
|
||||||
<Handle type="target" position={Position.Top} id="top-in" style={handleStyle} isConnectable={false} />
|
<Handle
|
||||||
|
type="target"
|
||||||
|
position={Position.Top}
|
||||||
|
id="top-in"
|
||||||
|
style={handleStyle}
|
||||||
|
isConnectable={false}
|
||||||
|
/>
|
||||||
)}
|
)}
|
||||||
{isStart ? "▶" : "■"}
|
{isStart ? "▶" : "■"}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -216,7 +216,11 @@ function computeLayout(input: LayoutInput): LayoutResult {
|
|||||||
id: edgeKey(e),
|
id: edgeKey(e),
|
||||||
source: e.from,
|
source: e.from,
|
||||||
target: e.to,
|
target: e.to,
|
||||||
sourceHandle: isFeedback ? (feedbackSide === "left" ? "left-out" : "right-out") : "bottom-out",
|
sourceHandle: isFeedback
|
||||||
|
? feedbackSide === "left"
|
||||||
|
? "left-out"
|
||||||
|
: "right-out"
|
||||||
|
: "bottom-out",
|
||||||
targetHandle: isFeedback ? (feedbackSide === "left" ? "left-in" : "right-in") : "top-in",
|
targetHandle: isFeedback ? (feedbackSide === "left" ? "left-in" : "right-in") : "top-in",
|
||||||
type: "condition",
|
type: "condition",
|
||||||
data: {
|
data: {
|
||||||
|
|||||||
@@ -28,7 +28,11 @@ export function WorkflowList({ client, onSelect }: Props) {
|
|||||||
type="button"
|
type="button"
|
||||||
onClick={() => onSelect(w.name)}
|
onClick={() => onSelect(w.name)}
|
||||||
className="w-full text-left p-4 rounded-lg border hover:opacity-90"
|
className="w-full text-left p-4 rounded-lg border hover:opacity-90"
|
||||||
style={{ background: "var(--color-surface)", borderColor: "var(--color-border)", color: "var(--color-text)" }}
|
style={{
|
||||||
|
background: "var(--color-surface)",
|
||||||
|
borderColor: "var(--color-border)",
|
||||||
|
color: "var(--color-text)",
|
||||||
|
}}
|
||||||
>
|
>
|
||||||
<div className="flex items-center gap-2">
|
<div className="flex items-center gap-2">
|
||||||
<span className="font-medium">{w.name}</span>
|
<span className="font-medium">{w.name}</span>
|
||||||
@@ -40,10 +44,7 @@ export function WorkflowList({ client, onSelect }: Props) {
|
|||||||
{w.hash !== null ? w.hash : "—"}
|
{w.hash !== null ? w.hash : "—"}
|
||||||
</code>
|
</code>
|
||||||
{w.timestamp !== null ? (
|
{w.timestamp !== null ? (
|
||||||
<span
|
<span className="text-xs mt-1 block" style={{ color: "var(--color-text-muted)" }}>
|
||||||
className="text-xs mt-1 block"
|
|
||||||
style={{ color: "var(--color-text-muted)" }}
|
|
||||||
>
|
|
||||||
Updated {new Date(w.timestamp).toLocaleString()}
|
Updated {new Date(w.timestamp).toLocaleString()}
|
||||||
</span>
|
</span>
|
||||||
) : null}
|
) : null}
|
||||||
|
|||||||
@@ -80,17 +80,20 @@ export function useHashRoute(): {
|
|||||||
);
|
);
|
||||||
|
|
||||||
const setClient = useCallback(
|
const setClient = useCallback(
|
||||||
(a: string | null) => navigate({ view: route.view, client: a, threadId: null, workflowName: null }),
|
(a: string | null) =>
|
||||||
|
navigate({ view: route.view, client: a, threadId: null, workflowName: null }),
|
||||||
[navigate, route.view],
|
[navigate, route.view],
|
||||||
);
|
);
|
||||||
|
|
||||||
const setThreadId = useCallback(
|
const setThreadId = useCallback(
|
||||||
(id: string | null) => navigate({ view: "threads", client: route.client, threadId: id, workflowName: null }),
|
(id: string | null) =>
|
||||||
|
navigate({ view: "threads", client: route.client, threadId: id, workflowName: null }),
|
||||||
[navigate, route.client],
|
[navigate, route.client],
|
||||||
);
|
);
|
||||||
|
|
||||||
const setWorkflowName = useCallback(
|
const setWorkflowName = useCallback(
|
||||||
(name: string | null) => navigate({ view: "workflows", client: route.client, threadId: null, workflowName: name }),
|
(name: string | null) =>
|
||||||
|
navigate({ view: "workflows", client: route.client, threadId: null, workflowName: name }),
|
||||||
[navigate, route.client],
|
[navigate, route.client],
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@@ -305,7 +305,12 @@ app.all("/api/clients/:client/*", async (c) => {
|
|||||||
headers: forwardRecord,
|
headers: forwardRecord,
|
||||||
body: bodyStr,
|
body: bodyStr,
|
||||||
};
|
};
|
||||||
const proxyResp = await fetchThroughClientSocket(c.env, client, c.env.GATEWAY_SECRET, wsRequest);
|
const proxyResp = await fetchThroughClientSocket(
|
||||||
|
c.env,
|
||||||
|
client,
|
||||||
|
c.env.GATEWAY_SECRET,
|
||||||
|
wsRequest,
|
||||||
|
);
|
||||||
if (proxyResp.status !== 503) {
|
if (proxyResp.status !== 503) {
|
||||||
return new Response(proxyResp.body, {
|
return new Response(proxyResp.body, {
|
||||||
status: proxyResp.status,
|
status: proxyResp.status,
|
||||||
|
|||||||
Reference in New Issue
Block a user