@volter-ai-dev/supercode-ui 0.1.54 → 0.1.56
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/activity.mjs +19 -1
- package/components.d.ts +1 -0
- package/components.mjs +392 -240
- package/composer.mjs +7 -0
- package/controller.d.ts +8 -0
- package/controller.mjs +48 -1
- package/conversation.mjs +7 -0
- package/core.mjs +28 -2
- package/embed.mjs +393 -242
- package/icon.mjs +6 -0
- package/index.d.ts +24 -3
- package/messenger.mjs +391 -240
- package/package.json +11 -1
- package/react/activity.mjs +19 -1
- package/react/components.mjs +392 -240
- package/react/composer.mjs +7 -0
- package/react/conversation.mjs +7 -0
- package/react/icon.mjs +6 -0
- package/react/index.d.ts +3 -2
- package/react/messenger.mjs +391 -240
- package/react/sessions.d.ts +1 -1
- package/react/sessions.mjs +41 -25
- package/react/settings.mjs +7 -0
- package/react/subagents.d.ts +2 -0
- package/react/subagents.mjs +1512 -0
- package/sessions.d.ts +1 -1
- package/sessions.mjs +41 -25
- package/settings.mjs +7 -0
- package/styles.css +6 -1
- package/subagents.d.ts +2 -0
- package/subagents.mjs +1512 -0
package/embed.mjs
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import { render } from "preact";
|
|
3
3
|
|
|
4
4
|
// src/messenger.jsx
|
|
5
|
-
import { useEffect as
|
|
5
|
+
import { useEffect as useEffect9, useId as useId3, useMemo as useMemo3, useRef as useRef8, useState as useState7 } from "preact/hooks";
|
|
6
6
|
|
|
7
7
|
// core.mjs
|
|
8
8
|
var HARNESS_NAMES = Object.freeze({
|
|
@@ -68,6 +68,7 @@ var EMPTY_UI_STATE = Object.freeze({
|
|
|
68
68
|
savedDraft: "",
|
|
69
69
|
attention: Object.freeze([]),
|
|
70
70
|
sessions: Object.freeze([]),
|
|
71
|
+
subagentInspector: null,
|
|
71
72
|
attached: null,
|
|
72
73
|
owned: null,
|
|
73
74
|
attachError: null
|
|
@@ -574,10 +575,25 @@ function readSessions(value) {
|
|
|
574
575
|
active: row.active === true,
|
|
575
576
|
writable: row.writable === true,
|
|
576
577
|
live: row.live === true,
|
|
577
|
-
runtimeStatus: row.runtimeStatus === "running" || row.runtimeStatus === "busy" || row.runtimeStatus === "idle" ? row.runtimeStatus : null
|
|
578
|
+
runtimeStatus: row.runtimeStatus === "running" || row.runtimeStatus === "busy" || row.runtimeStatus === "idle" ? row.runtimeStatus : null,
|
|
579
|
+
...Number.isSafeInteger(row.subagentCount) && row.subagentCount > 0 ? { subagentCount: row.subagentCount } : {},
|
|
580
|
+
activity: ACTIVITY_PRIORITY[row.activity] !== void 0 ? row.activity : void 0
|
|
578
581
|
}];
|
|
579
582
|
});
|
|
580
583
|
}
|
|
584
|
+
function readSubagentInspector(value) {
|
|
585
|
+
const inspector = record(value);
|
|
586
|
+
if (!inspector || typeof inspector.parentKey !== "string" || !inspector.parentKey) return null;
|
|
587
|
+
return {
|
|
588
|
+
parentKey: inspector.parentKey,
|
|
589
|
+
parentTitle: boundedString(string(inspector.parentTitle), 500),
|
|
590
|
+
status: ["loading", "ready", "error"].includes(inspector.status) ? inspector.status : "loading",
|
|
591
|
+
items: readSessions(inspector.items).slice(0, 100),
|
|
592
|
+
selectedKey: typeof inspector.selectedKey === "string" && inspector.selectedKey ? inspector.selectedKey : null,
|
|
593
|
+
transcript: readTranscript(inspector.transcript).slice(-120),
|
|
594
|
+
error: typeof inspector.error === "string" ? boundedString(inspector.error) : null
|
|
595
|
+
};
|
|
596
|
+
}
|
|
581
597
|
function readAttached(value) {
|
|
582
598
|
const item = record(value);
|
|
583
599
|
if (!item || typeof item.harness !== "string") return null;
|
|
@@ -792,6 +808,7 @@ function normalizeUiState(value) {
|
|
|
792
808
|
return item && typeof item.key === "string" && ["unseen", "finished", "failed"].includes(item.kind) ? [{ key: item.key, kind: item.kind, ...typeof item.preview === "string" ? { preview: item.preview } : {}, ...Number.isSafeInteger(item.afterMessages) && item.afterMessages >= 0 ? { afterMessages: item.afterMessages } : {}, ...Number.isSafeInteger(item.unreadCount) && item.unreadCount > 0 ? { unreadCount: item.unreadCount } : {} }] : [];
|
|
793
809
|
}) : [],
|
|
794
810
|
sessions: readSessions(raw.sessions),
|
|
811
|
+
subagentInspector: readSubagentInspector(raw.subagentInspector),
|
|
795
812
|
attached: readAttached(raw.attached),
|
|
796
813
|
owned: readAttached(raw.owned),
|
|
797
814
|
attachError: attachError && typeof attachError.key === "string" && typeof attachError.message === "string" ? { key: attachError.key, message: attachError.message } : null
|
|
@@ -805,6 +822,7 @@ function sessionDisplayName(session) {
|
|
|
805
822
|
return title && title !== session.name ? title : session.name || "Untitled chat";
|
|
806
823
|
}
|
|
807
824
|
function sessionActivity(state, row) {
|
|
825
|
+
if (row.activity && ACTIVITY_PRIORITY[row.activity] !== void 0) return row.activity;
|
|
808
826
|
if (state.needsInput && row.active) return "needs-input";
|
|
809
827
|
if (state.busy && row.active) return "working";
|
|
810
828
|
if (row.runtimeStatus === "busy") return "working";
|
|
@@ -907,6 +925,12 @@ function boundedSet(map, key, value) {
|
|
|
907
925
|
// src/icon.jsx
|
|
908
926
|
import { Fragment, jsx, jsxs } from "preact/jsx-runtime";
|
|
909
927
|
var ICONS = {
|
|
928
|
+
agents: () => /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
929
|
+
/* @__PURE__ */ jsx("circle", { cx: "6", cy: "6.5", r: "2" }),
|
|
930
|
+
/* @__PURE__ */ jsx("path", { d: "M2.75 13c.45-2 1.55-3 3.25-3s2.8 1 3.25 3" }),
|
|
931
|
+
/* @__PURE__ */ jsx("circle", { cx: "12.25", cy: "7", r: "1.5" }),
|
|
932
|
+
/* @__PURE__ */ jsx("path", { d: "M10.5 10.75c1.95-.65 3.45.1 4 2.25" })
|
|
933
|
+
] }),
|
|
910
934
|
attach: () => /* @__PURE__ */ jsx("path", { d: "M6.25 9.75 10.6 5.4a2.1 2.1 0 0 1 2.97 2.97l-5.4 5.4a3.3 3.3 0 0 1-4.67-4.66l5.52-5.52" }),
|
|
911
935
|
back: () => /* @__PURE__ */ jsx("path", { d: "m11.5 4.5-4.5 4.5 4.5 4.5" }),
|
|
912
936
|
check: () => /* @__PURE__ */ jsx("path", { d: "m4 9 3.25 3.25L14 5.5" }),
|
|
@@ -2224,7 +2248,7 @@ function sessionPathParts(value) {
|
|
|
2224
2248
|
trailing: complete.slice(boundary + 1)
|
|
2225
2249
|
};
|
|
2226
2250
|
}
|
|
2227
|
-
function SessionRow({ row, state, onOpen, now = Date.now() }) {
|
|
2251
|
+
function SessionRow({ row, state, onOpen, onOpenSubagents, now = Date.now() }) {
|
|
2228
2252
|
const activity = sessionActivity(state, row);
|
|
2229
2253
|
const working = activity === "working";
|
|
2230
2254
|
const attention = state.attention.find((item) => item.key === row.key);
|
|
@@ -2234,32 +2258,40 @@ function SessionRow({ row, state, onOpen, now = Date.now() }) {
|
|
|
2234
2258
|
const unreadCount = attention?.unreadCount ?? 0;
|
|
2235
2259
|
const unreadLabel = unreadCount > 99 ? "99+" : String(unreadCount);
|
|
2236
2260
|
const age = relativeAge(row.previewUpdatedAt ?? row.updatedAt, now) || row.age;
|
|
2237
|
-
return /* @__PURE__ */ jsxs6("
|
|
2238
|
-
/* @__PURE__ */
|
|
2239
|
-
|
|
2240
|
-
/* @__PURE__ */ jsxs6("span", { className: "scui-session-
|
|
2241
|
-
/* @__PURE__ */
|
|
2242
|
-
|
|
2243
|
-
|
|
2244
|
-
|
|
2245
|
-
/* @__PURE__ */
|
|
2246
|
-
|
|
2247
|
-
|
|
2248
|
-
|
|
2249
|
-
working || preview || unreadCount ? /* @__PURE__ */ jsxs6("span", { className: "scui-session-preview", children: [
|
|
2250
|
-
working ? /* @__PURE__ */ jsxs6("span", { className: "scui-session-working", "aria-hidden": "true", children: [
|
|
2251
|
-
/* @__PURE__ */ jsx7("i", {}),
|
|
2252
|
-
/* @__PURE__ */ jsx7("i", {}),
|
|
2253
|
-
/* @__PURE__ */ jsx7("i", {})
|
|
2261
|
+
return /* @__PURE__ */ jsxs6("article", { className: "scui-session", "data-active": row.active, "data-activity": activity, "data-writable": row.writable, children: [
|
|
2262
|
+
/* @__PURE__ */ jsxs6("button", { className: "scui-session-main", "data-session-key": row.key, type: "button", "aria-label": `${title} \xB7 ${harnessDisplayName(row.harness)}${row.writable ? "" : " \xB7 Read-only"}${working ? " \xB7 Working" : ""}${path.complete ? ` \xB7 ${path.complete}` : ""}${preview ? ` \xB7 ${preview}` : ""}${unreadCount ? ` \xB7 ${unreadCount} unread` : ""}${age ? ` \xB7 ${age}` : ""}`, "aria-current": row.active ? "true" : void 0, onClick: () => onOpen(row), children: [
|
|
2263
|
+
/* @__PURE__ */ jsx7(HarnessLogo, { id: row.harness, activity, size: 34 }),
|
|
2264
|
+
/* @__PURE__ */ jsxs6("span", { className: "scui-session-copy", children: [
|
|
2265
|
+
/* @__PURE__ */ jsxs6("span", { className: "scui-session-title", children: [
|
|
2266
|
+
/* @__PURE__ */ jsx7("strong", { children: title }),
|
|
2267
|
+
/* @__PURE__ */ jsx7("span", { className: "scui-session-meta", children: age ? /* @__PURE__ */ jsx7("time", { children: age }) : null })
|
|
2268
|
+
] }),
|
|
2269
|
+
path.complete ? /* @__PURE__ */ jsxs6("small", { className: "scui-session-path", title: row.cwd, children: [
|
|
2270
|
+
/* @__PURE__ */ jsx7("span", { className: "scui-session-path-leading", children: path.leading }),
|
|
2271
|
+
path.separator ? /* @__PURE__ */ jsx7("span", { className: "scui-session-path-separator", children: path.separator }) : null,
|
|
2272
|
+
path.trailing ? /* @__PURE__ */ jsx7("span", { className: "scui-session-path-trailing", children: path.trailing }) : null
|
|
2254
2273
|
] }) : null,
|
|
2255
|
-
preview ||
|
|
2256
|
-
|
|
2257
|
-
|
|
2258
|
-
|
|
2259
|
-
|
|
2274
|
+
working || preview || unreadCount ? /* @__PURE__ */ jsxs6("span", { className: "scui-session-preview", children: [
|
|
2275
|
+
working ? /* @__PURE__ */ jsxs6("span", { className: "scui-session-working", "aria-hidden": "true", children: [
|
|
2276
|
+
/* @__PURE__ */ jsx7("i", {}),
|
|
2277
|
+
/* @__PURE__ */ jsx7("i", {}),
|
|
2278
|
+
/* @__PURE__ */ jsx7("i", {})
|
|
2279
|
+
] }) : null,
|
|
2280
|
+
preview || working ? /* @__PURE__ */ jsx7("small", { children: preview || "Working\u2026" }) : null,
|
|
2281
|
+
unreadCount ? /* @__PURE__ */ jsx7("b", { "aria-label": `${unreadCount} unread messages`, children: unreadLabel }) : null
|
|
2282
|
+
] }) : null,
|
|
2283
|
+
state.attachError?.key === row.key ? /* @__PURE__ */ jsx7("em", { children: state.attachError.message }) : null
|
|
2284
|
+
] })
|
|
2285
|
+
] }),
|
|
2286
|
+
row.subagentCount ? /* @__PURE__ */ jsxs6("button", { className: "scui-session-agents", type: "button", "aria-label": `Inspect ${row.subagentCount} subagents in ${title}`, onClick: () => onOpenSubagents?.(row), children: [
|
|
2287
|
+
/* @__PURE__ */ jsx7(UiIcon, { name: "agents", size: 14 }),
|
|
2288
|
+
row.subagentCount,
|
|
2289
|
+
" ",
|
|
2290
|
+
row.subagentCount === 1 ? "agent" : "agents"
|
|
2291
|
+
] }) : null
|
|
2260
2292
|
] });
|
|
2261
2293
|
}
|
|
2262
|
-
function SessionList({ state, adapter, onOpen, onNew, onClose, components = {}, slots = {}, labels = DEFAULT_LABELS, focusKey = null, memoryKey = state.workspace || "@default", headerActions: HeaderActions }) {
|
|
2294
|
+
function SessionList({ state, adapter, onOpen, onOpenSubagents, onNew, onClose, components = {}, slots = {}, labels = DEFAULT_LABELS, focusKey = null, memoryKey = state.workspace || "@default", headerActions: HeaderActions }) {
|
|
2263
2295
|
const remembered = sessionListMemory.get(memoryKey) ?? { query: "", top: 0 };
|
|
2264
2296
|
const [query, setQuery] = useState4(remembered.query);
|
|
2265
2297
|
const [loadingMore, setLoadingMore] = useState4(false);
|
|
@@ -2325,26 +2357,132 @@ function SessionList({ state, adapter, onOpen, onNew, onClose, components = {},
|
|
|
2325
2357
|
/* @__PURE__ */ jsxs6("div", { className: "scui-session-rows", ref: rowScroller, onScroll: (event) => boundedSet(sessionListMemory, memoryKey, { query, top: event.currentTarget.scrollTop }), children: [
|
|
2326
2358
|
BeforeSessions ? /* @__PURE__ */ jsx7(BeforeSessions, { state, adapter, value: { query, rows } }) : null,
|
|
2327
2359
|
!rows.length && state.startup === "ready" ? /* @__PURE__ */ jsx7("div", { className: "scui-empty", children: query ? "No chats match your search." : state.error ?? "No coding chats found." }) : null,
|
|
2328
|
-
rows.map((row) => /* @__PURE__ */ jsx7(Row, { value: row, row, state, adapter, onOpen, now }, row.key)),
|
|
2360
|
+
rows.map((row) => /* @__PURE__ */ jsx7(Row, { value: row, row, state, adapter, onOpen, onOpenSubagents, now }, row.key)),
|
|
2329
2361
|
state.history.hasMoreSessions ? /* @__PURE__ */ jsx7("button", { className: "scui-load", type: "button", disabled: loadingMore, onClick: loadMore, children: loadingMore ? "Loading older chats\u2026" : "Load older chats" }) : null,
|
|
2330
2362
|
AfterSessions ? /* @__PURE__ */ jsx7(AfterSessions, { state, adapter, value: { query, rows } }) : null
|
|
2331
2363
|
] })
|
|
2332
2364
|
] });
|
|
2333
2365
|
}
|
|
2334
2366
|
|
|
2335
|
-
// src/
|
|
2336
|
-
import { useEffect as useEffect7,
|
|
2367
|
+
// src/subagents.jsx
|
|
2368
|
+
import { useEffect as useEffect7, useRef as useRef6, useState as useState5 } from "preact/hooks";
|
|
2337
2369
|
import { jsx as jsx8, jsxs as jsxs7 } from "preact/jsx-runtime";
|
|
2370
|
+
var ATTENTION_ACTIVITY = /* @__PURE__ */ new Set(["needs-input", "failed", "unseen"]);
|
|
2371
|
+
var ACTIVE_ACTIVITY = /* @__PURE__ */ new Set(["working", "running", "recent"]);
|
|
2372
|
+
function activityLabel(activity, age) {
|
|
2373
|
+
if (activity === "needs-input") return "Needs input";
|
|
2374
|
+
if (activity === "failed") return "Failed";
|
|
2375
|
+
if (activity === "unseen") return "New update";
|
|
2376
|
+
if (activity === "working") return "Working";
|
|
2377
|
+
if (activity === "running") return "Running";
|
|
2378
|
+
if (activity === "recent") return "Recent";
|
|
2379
|
+
if (activity === "finished") return "Finished";
|
|
2380
|
+
return age;
|
|
2381
|
+
}
|
|
2382
|
+
function SubagentRow({ row, inspector, adapter }) {
|
|
2383
|
+
return /* @__PURE__ */ jsxs7("button", { className: "scui-subagent-row", type: "button", "data-activity": row.activity ?? "idle", onClick: () => adapter.onIntent({ action: "openSubagent", parentKey: inspector.parentKey, key: row.key }), children: [
|
|
2384
|
+
/* @__PURE__ */ jsx8(HarnessLogo, { id: row.harness, activity: row.activity, size: 30 }),
|
|
2385
|
+
/* @__PURE__ */ jsxs7("span", { children: [
|
|
2386
|
+
/* @__PURE__ */ jsx8("strong", { children: sessionDisplayName(row) }),
|
|
2387
|
+
/* @__PURE__ */ jsx8("small", { children: row.preview || (row.activity === "working" ? "Working\u2026" : row.cwd) })
|
|
2388
|
+
] }),
|
|
2389
|
+
/* @__PURE__ */ jsxs7("span", { children: [
|
|
2390
|
+
/* @__PURE__ */ jsx8("small", { children: activityLabel(row.activity, row.age) }),
|
|
2391
|
+
/* @__PURE__ */ jsx8(UiIcon, { name: "chevron", size: 14 })
|
|
2392
|
+
] })
|
|
2393
|
+
] });
|
|
2394
|
+
}
|
|
2395
|
+
function SubagentSection({ label, rows, inspector, adapter }) {
|
|
2396
|
+
if (!rows.length) return null;
|
|
2397
|
+
return /* @__PURE__ */ jsxs7("section", { className: "scui-subagent-section", "aria-labelledby": `scui-subagents-${label.toLowerCase().replaceAll(" ", "-")}`, children: [
|
|
2398
|
+
/* @__PURE__ */ jsx8("h2", { id: `scui-subagents-${label.toLowerCase().replaceAll(" ", "-")}`, children: label }),
|
|
2399
|
+
rows.map((row) => /* @__PURE__ */ jsx8(SubagentRow, { row, inspector, adapter }, row.key))
|
|
2400
|
+
] });
|
|
2401
|
+
}
|
|
2402
|
+
function SubagentInspectorContent({ state, adapter, onClose, inspector }) {
|
|
2403
|
+
const selected = inspector.items.find((row) => row.key === inspector.selectedKey) ?? null;
|
|
2404
|
+
const attention = inspector.items.filter((row) => ATTENTION_ACTIVITY.has(row.activity));
|
|
2405
|
+
const active = inspector.items.filter((row) => ACTIVE_ACTIVITY.has(row.activity));
|
|
2406
|
+
const finished = inspector.items.filter((row) => !ATTENTION_ACTIVITY.has(row.activity) && !ACTIVE_ACTIVITY.has(row.activity));
|
|
2407
|
+
const [finishedOpen, setFinishedOpen] = useState5(false);
|
|
2408
|
+
const backButton = useRef6(null);
|
|
2409
|
+
useEffect7(() => {
|
|
2410
|
+
if (inspector.status === "ready" && !attention.length && !active.length) setFinishedOpen(true);
|
|
2411
|
+
}, [inspector.parentKey, inspector.status]);
|
|
2412
|
+
useEffect7(() => {
|
|
2413
|
+
backButton.current?.focus({ preventScroll: true });
|
|
2414
|
+
}, [selected?.key]);
|
|
2415
|
+
const detailState = selected ? {
|
|
2416
|
+
...state,
|
|
2417
|
+
transcript: inspector.transcript,
|
|
2418
|
+
busy: selected.activity === "working",
|
|
2419
|
+
needsInput: selected.activity === "needs-input",
|
|
2420
|
+
harness: selected.harness,
|
|
2421
|
+
mode: "mirror",
|
|
2422
|
+
canSend: false,
|
|
2423
|
+
canSteer: false,
|
|
2424
|
+
canInterrupt: false,
|
|
2425
|
+
canRespond: false,
|
|
2426
|
+
taskPlan: { source: "none", items: [], residueCount: 0, observedAt: null },
|
|
2427
|
+
semantics: { fidelity: null, residue: [], residueCount: 0, parseErrors: 0, rawRecords: 0, subagents: [] },
|
|
2428
|
+
history: { ...state.history, hasEarlier: false }
|
|
2429
|
+
} : null;
|
|
2430
|
+
const leave = () => {
|
|
2431
|
+
adapter.onIntent({ action: "closeSubagents" });
|
|
2432
|
+
onClose();
|
|
2433
|
+
};
|
|
2434
|
+
const back = () => selected ? adapter.onIntent({ action: "openSubagents", key: inspector.parentKey }) : leave();
|
|
2435
|
+
return /* @__PURE__ */ jsxs7("section", { className: "scui-subagents", "aria-label": `Agents for ${inspector.parentTitle}`, children: [
|
|
2436
|
+
/* @__PURE__ */ jsxs7("header", { className: "scui-head", children: [
|
|
2437
|
+
/* @__PURE__ */ jsx8("button", { ref: backButton, type: "button", "aria-label": selected ? "Back to agents" : "Back to chats", onClick: back, children: /* @__PURE__ */ jsx8(UiIcon, { name: "back", size: 17 }) }),
|
|
2438
|
+
selected ? /* @__PURE__ */ jsx8(HarnessLogo, { id: selected.harness, activity: selected.activity, size: 24 }) : /* @__PURE__ */ jsx8(UiIcon, { name: "agents", size: 20 }),
|
|
2439
|
+
/* @__PURE__ */ jsxs7("span", { className: "scui-head-copy", children: [
|
|
2440
|
+
/* @__PURE__ */ jsx8("strong", { children: selected ? sessionDisplayName(selected) : `${inspector.items.length || ""} ${inspector.items.length === 1 ? "agent" : "agents"}`.trim() }),
|
|
2441
|
+
/* @__PURE__ */ jsx8("small", { children: selected ? `${harnessDisplayName(selected.harness)} \xB7 Read-only` : inspector.parentTitle })
|
|
2442
|
+
] })
|
|
2443
|
+
] }),
|
|
2444
|
+
inspector.status === "loading" ? /* @__PURE__ */ jsxs7("div", { className: "scui-subagents-loading", role: "status", children: [
|
|
2445
|
+
/* @__PURE__ */ jsx8("i", {}),
|
|
2446
|
+
/* @__PURE__ */ jsxs7("span", { children: [
|
|
2447
|
+
/* @__PURE__ */ jsx8("strong", { children: selected ? "Loading subagent" : "Finding subagents" }),
|
|
2448
|
+
/* @__PURE__ */ jsx8("small", { children: selected ? "Reading a bounded recent transcript\u2026" : "Reading native session relationships\u2026" })
|
|
2449
|
+
] })
|
|
2450
|
+
] }) : null,
|
|
2451
|
+
inspector.error ? /* @__PURE__ */ jsx8("div", { className: "scui-error", role: "alert", children: inspector.error }) : null,
|
|
2452
|
+
!selected && inspector.status === "ready" && inspector.items.length ? /* @__PURE__ */ jsxs7("div", { className: "scui-subagent-rows", children: [
|
|
2453
|
+
/* @__PURE__ */ jsx8(SubagentSection, { label: "Needs attention", rows: attention, inspector, adapter }),
|
|
2454
|
+
/* @__PURE__ */ jsx8(SubagentSection, { label: "Active", rows: active, inspector, adapter }),
|
|
2455
|
+
finished.length ? /* @__PURE__ */ jsxs7("details", { className: "scui-subagent-history", open: finishedOpen, onToggle: (event) => setFinishedOpen(event.currentTarget.open), children: [
|
|
2456
|
+
/* @__PURE__ */ jsxs7("summary", { children: [
|
|
2457
|
+
/* @__PURE__ */ jsx8("span", { children: "Finished" }),
|
|
2458
|
+
/* @__PURE__ */ jsx8("small", { children: finished.length }),
|
|
2459
|
+
/* @__PURE__ */ jsx8(UiIcon, { name: "chevron", size: 14 })
|
|
2460
|
+
] }),
|
|
2461
|
+
/* @__PURE__ */ jsx8("div", { children: finished.map((row) => /* @__PURE__ */ jsx8(SubagentRow, { row, inspector, adapter }, row.key)) })
|
|
2462
|
+
] }) : null
|
|
2463
|
+
] }) : null,
|
|
2464
|
+
!selected && inspector.status === "ready" && !inspector.items.length ? /* @__PURE__ */ jsx8("div", { className: "scui-empty", children: "No native child sessions were found." }) : null,
|
|
2465
|
+
selected && inspector.status === "ready" && detailState ? /* @__PURE__ */ jsx8(Conversation, { state: detailState, adapter, memoryKey: `subagent:${selected.key}` }) : null
|
|
2466
|
+
] });
|
|
2467
|
+
}
|
|
2468
|
+
function SubagentInspector({ state, adapter, onClose }) {
|
|
2469
|
+
if (!state.subagentInspector) return null;
|
|
2470
|
+
return /* @__PURE__ */ jsx8(SubagentInspectorContent, { state, adapter, onClose, inspector: state.subagentInspector });
|
|
2471
|
+
}
|
|
2472
|
+
|
|
2473
|
+
// src/settings.jsx
|
|
2474
|
+
import { useEffect as useEffect8, useId as useId2, useMemo as useMemo2, useRef as useRef7, useState as useState6 } from "preact/hooks";
|
|
2475
|
+
import { jsx as jsx9, jsxs as jsxs8 } from "preact/jsx-runtime";
|
|
2338
2476
|
function HarnessAdvisory({ state, onReview }) {
|
|
2339
2477
|
const advisory = state.interopSettings?.advisories[0];
|
|
2340
2478
|
if (!advisory && !state.interopSettingsError) return null;
|
|
2341
|
-
return /* @__PURE__ */
|
|
2342
|
-
/* @__PURE__ */
|
|
2343
|
-
/* @__PURE__ */
|
|
2344
|
-
/* @__PURE__ */
|
|
2345
|
-
/* @__PURE__ */
|
|
2479
|
+
return /* @__PURE__ */ jsxs8("div", { className: "scui-advisory", "data-severity": advisory?.severity ?? "error", role: advisory?.severity === "error" || !advisory ? "alert" : "status", children: [
|
|
2480
|
+
/* @__PURE__ */ jsx9("span", { "aria-hidden": "true", children: "!" }),
|
|
2481
|
+
/* @__PURE__ */ jsxs8("span", { children: [
|
|
2482
|
+
/* @__PURE__ */ jsx9("strong", { children: advisory?.title ?? "Could not inspect harness settings" }),
|
|
2483
|
+
/* @__PURE__ */ jsx9("small", { children: advisory?.message ?? state.interopSettingsError })
|
|
2346
2484
|
] }),
|
|
2347
|
-
advisory && state.canConfigureSettings ? /* @__PURE__ */
|
|
2485
|
+
advisory && state.canConfigureSettings ? /* @__PURE__ */ jsx9("button", { type: "button", onClick: () => onReview(advisory.recommendation.change), children: "Review" }) : null
|
|
2348
2486
|
] });
|
|
2349
2487
|
}
|
|
2350
2488
|
function initialValues(report, recommendedChange) {
|
|
@@ -2356,12 +2494,12 @@ function initialValues(report, recommendedChange) {
|
|
|
2356
2494
|
function HarnessSettingsPanel({ state, adapter, onClose, recommendedChange = null }) {
|
|
2357
2495
|
const report = state.interopSettings;
|
|
2358
2496
|
const titleId = useId2();
|
|
2359
|
-
const panel =
|
|
2497
|
+
const panel = useRef7(null);
|
|
2360
2498
|
const valuesKey = `${report?.revision ?? ""}:${recommendedChange?.key ?? ""}:${recommendedChange?.value ?? ""}`;
|
|
2361
2499
|
const defaults = useMemo2(() => report ? initialValues(report, recommendedChange) : {}, [valuesKey]);
|
|
2362
|
-
const [values, setValues] =
|
|
2363
|
-
|
|
2364
|
-
|
|
2500
|
+
const [values, setValues] = useState6(defaults);
|
|
2501
|
+
useEffect8(() => setValues(defaults), [defaults]);
|
|
2502
|
+
useEffect8(() => {
|
|
2365
2503
|
panel.current?.querySelector("select, button")?.focus({ preventScroll: true });
|
|
2366
2504
|
const dismiss = (event) => {
|
|
2367
2505
|
if (event.key === "Escape") {
|
|
@@ -2372,11 +2510,11 @@ function HarnessSettingsPanel({ state, adapter, onClose, recommendedChange = nul
|
|
|
2372
2510
|
document.addEventListener("keydown", dismiss);
|
|
2373
2511
|
return () => document.removeEventListener("keydown", dismiss);
|
|
2374
2512
|
}, [onClose]);
|
|
2375
|
-
if (!report) return /* @__PURE__ */
|
|
2376
|
-
/* @__PURE__ */
|
|
2377
|
-
/* @__PURE__ */
|
|
2378
|
-
/* @__PURE__ */
|
|
2379
|
-
/* @__PURE__ */
|
|
2513
|
+
if (!report) return /* @__PURE__ */ jsx9("section", { ref: panel, className: "scui-settings", role: "dialog", "aria-modal": "true", "aria-labelledby": titleId, children: /* @__PURE__ */ jsxs8("header", { children: [
|
|
2514
|
+
/* @__PURE__ */ jsx9("button", { type: "button", "aria-label": "Close settings", onClick: onClose, children: /* @__PURE__ */ jsx9(UiIcon, { name: "close", size: 18 }) }),
|
|
2515
|
+
/* @__PURE__ */ jsxs8("span", { children: [
|
|
2516
|
+
/* @__PURE__ */ jsx9("strong", { id: titleId, children: "Harness settings" }),
|
|
2517
|
+
/* @__PURE__ */ jsx9("small", { children: state.interopSettingsError ?? "No interoperability controls are available." })
|
|
2380
2518
|
] })
|
|
2381
2519
|
] }) });
|
|
2382
2520
|
const changed = report.controls.flatMap((control) => values[control.key] !== (control.configuredValue ?? control.effectiveValue ?? control.choices[0]?.value ?? null) ? [{ key: control.key, value: values[control.key] ?? null }] : []);
|
|
@@ -2385,45 +2523,45 @@ function HarnessSettingsPanel({ state, adapter, onClose, recommendedChange = nul
|
|
|
2385
2523
|
if (!changed.length || !state.canConfigureSettings) return;
|
|
2386
2524
|
adapter.onIntent({ action: "configureHarness", harness: report.harness, changes: changed, expectedRevision: report.revision });
|
|
2387
2525
|
};
|
|
2388
|
-
return /* @__PURE__ */
|
|
2389
|
-
/* @__PURE__ */
|
|
2390
|
-
/* @__PURE__ */
|
|
2391
|
-
/* @__PURE__ */
|
|
2392
|
-
/* @__PURE__ */
|
|
2526
|
+
return /* @__PURE__ */ jsxs8("section", { ref: panel, className: "scui-settings", role: "dialog", "aria-modal": "true", "aria-labelledby": titleId, children: [
|
|
2527
|
+
/* @__PURE__ */ jsxs8("header", { children: [
|
|
2528
|
+
/* @__PURE__ */ jsx9("button", { type: "button", "aria-label": "Close settings", onClick: onClose, children: /* @__PURE__ */ jsx9(UiIcon, { name: "close", size: 18 }) }),
|
|
2529
|
+
/* @__PURE__ */ jsxs8("span", { children: [
|
|
2530
|
+
/* @__PURE__ */ jsxs8("strong", { id: titleId, children: [
|
|
2393
2531
|
harnessDisplayName(report.harness),
|
|
2394
2532
|
" interoperability"
|
|
2395
2533
|
] }),
|
|
2396
|
-
/* @__PURE__ */
|
|
2534
|
+
/* @__PURE__ */ jsx9("small", { children: "Native harness settings used by Supercode" })
|
|
2397
2535
|
] })
|
|
2398
2536
|
] }),
|
|
2399
|
-
/* @__PURE__ */
|
|
2537
|
+
/* @__PURE__ */ jsxs8("form", { onSubmit: submit, children: [
|
|
2400
2538
|
report.controls.map((control) => {
|
|
2401
2539
|
const choice = control.choices.find((item) => item.value === values[control.key]);
|
|
2402
2540
|
const recommendation = report.advisories.map((advisory) => advisory.recommendation).find((item) => item.change.key === control.key && item.change.value === values[control.key]);
|
|
2403
2541
|
const consequence = choice?.risk ?? recommendation?.consequence;
|
|
2404
|
-
return /* @__PURE__ */
|
|
2405
|
-
/* @__PURE__ */
|
|
2406
|
-
/* @__PURE__ */
|
|
2407
|
-
/* @__PURE__ */
|
|
2542
|
+
return /* @__PURE__ */ jsxs8("fieldset", { disabled: !control.writable || Boolean(state.operation), children: [
|
|
2543
|
+
/* @__PURE__ */ jsxs8("label", { htmlFor: `scui-setting-${control.key}`, children: [
|
|
2544
|
+
/* @__PURE__ */ jsx9("strong", { children: control.label }),
|
|
2545
|
+
/* @__PURE__ */ jsx9("small", { children: control.description })
|
|
2408
2546
|
] }),
|
|
2409
|
-
/* @__PURE__ */
|
|
2410
|
-
control.resettable ? /* @__PURE__ */
|
|
2411
|
-
control.choices.map((item) => /* @__PURE__ */
|
|
2547
|
+
/* @__PURE__ */ jsxs8("select", { id: `scui-setting-${control.key}`, value: values[control.key] ?? "@default", onChange: (event) => setValues((current) => ({ ...current, [control.key]: event.currentTarget.value === "@default" ? null : event.currentTarget.value })), children: [
|
|
2548
|
+
control.resettable ? /* @__PURE__ */ jsx9("option", { value: "@default", children: "Use harness default" }) : null,
|
|
2549
|
+
control.choices.map((item) => /* @__PURE__ */ jsx9("option", { value: item.value, children: item.label }, item.value))
|
|
2412
2550
|
] }),
|
|
2413
|
-
choice ? /* @__PURE__ */
|
|
2414
|
-
consequence ? /* @__PURE__ */
|
|
2415
|
-
/* @__PURE__ */
|
|
2551
|
+
choice ? /* @__PURE__ */ jsx9("p", { children: choice.description }) : null,
|
|
2552
|
+
consequence ? /* @__PURE__ */ jsxs8("p", { className: "scui-setting-risk", children: [
|
|
2553
|
+
/* @__PURE__ */ jsx9("strong", { children: "Security consequence" }),
|
|
2416
2554
|
consequence
|
|
2417
2555
|
] }) : null,
|
|
2418
|
-
/* @__PURE__ */
|
|
2556
|
+
/* @__PURE__ */ jsxs8("small", { className: "scui-setting-source", children: [
|
|
2419
2557
|
control.effectiveNote,
|
|
2420
2558
|
control.sourcePath ? ` Source: ${control.sourcePath}` : ""
|
|
2421
2559
|
] })
|
|
2422
2560
|
] }, control.key);
|
|
2423
2561
|
}),
|
|
2424
|
-
/* @__PURE__ */
|
|
2425
|
-
/* @__PURE__ */
|
|
2426
|
-
/* @__PURE__ */
|
|
2562
|
+
/* @__PURE__ */ jsxs8("footer", { children: [
|
|
2563
|
+
/* @__PURE__ */ jsx9("button", { type: "button", onClick: onClose, children: "Cancel" }),
|
|
2564
|
+
/* @__PURE__ */ jsx9("button", { type: "submit", disabled: !changed.length || !state.canConfigureSettings || Boolean(state.operation), children: state.operation === "configureHarness" ? "Applying\u2026" : "Apply changes" })
|
|
2427
2565
|
] })
|
|
2428
2566
|
] })
|
|
2429
2567
|
] });
|
|
@@ -2431,29 +2569,29 @@ function HarnessSettingsPanel({ state, adapter, onClose, recommendedChange = nul
|
|
|
2431
2569
|
function HarnessReadiness({ harnesses, adapter }) {
|
|
2432
2570
|
const blocked = harnesses.filter((item) => !item.startable);
|
|
2433
2571
|
if (!blocked.length || harnesses.some((item) => item.startable)) return null;
|
|
2434
|
-
return /* @__PURE__ */
|
|
2435
|
-
/* @__PURE__ */
|
|
2436
|
-
/* @__PURE__ */
|
|
2437
|
-
/* @__PURE__ */
|
|
2438
|
-
/* @__PURE__ */
|
|
2439
|
-
/* @__PURE__ */
|
|
2440
|
-
/* @__PURE__ */
|
|
2441
|
-
item.protocol ? /* @__PURE__ */
|
|
2572
|
+
return /* @__PURE__ */ jsxs8("details", { className: "scui-readiness", open: true, children: [
|
|
2573
|
+
/* @__PURE__ */ jsx9("summary", { children: "No coding harness is ready" }),
|
|
2574
|
+
/* @__PURE__ */ jsx9("div", { children: blocked.map((item) => /* @__PURE__ */ jsxs8("section", { children: [
|
|
2575
|
+
/* @__PURE__ */ jsx9(HarnessLogo, { id: item.id, size: 25 }),
|
|
2576
|
+
/* @__PURE__ */ jsxs8("span", { children: [
|
|
2577
|
+
/* @__PURE__ */ jsx9("strong", { children: item.label }),
|
|
2578
|
+
/* @__PURE__ */ jsx9("small", { children: item.reason || (item.auth === "required" ? "Authentication required" : "Unavailable") }),
|
|
2579
|
+
item.protocol ? /* @__PURE__ */ jsxs8("em", { children: [
|
|
2442
2580
|
item.protocol,
|
|
2443
2581
|
" \xB7 ",
|
|
2444
2582
|
item.runtime
|
|
2445
2583
|
] }) : null
|
|
2446
2584
|
] }),
|
|
2447
|
-
item.repair ? /* @__PURE__ */
|
|
2585
|
+
item.repair ? /* @__PURE__ */ jsx9("button", { type: "button", onClick: () => adapter.copyText?.(item.repair), children: "Copy fix" }) : null
|
|
2448
2586
|
] }, item.id)) })
|
|
2449
2587
|
] });
|
|
2450
2588
|
}
|
|
2451
2589
|
function HarnessPicker({ harnesses, value, disabled = false, adapter, onChange, logo: Logo = HarnessLogo }) {
|
|
2452
|
-
const [open, setOpen] =
|
|
2590
|
+
const [open, setOpen] = useState6(false);
|
|
2453
2591
|
const menuId = useId2();
|
|
2454
|
-
const root =
|
|
2455
|
-
const trigger =
|
|
2456
|
-
const panel =
|
|
2592
|
+
const root = useRef7(null);
|
|
2593
|
+
const trigger = useRef7(null);
|
|
2594
|
+
const panel = useRef7(null);
|
|
2457
2595
|
const available = harnesses.filter((item) => item.startable);
|
|
2458
2596
|
const unavailable = harnesses.filter((item) => !item.startable);
|
|
2459
2597
|
const selected = available.find((item) => item.id === value) ?? available[0] ?? null;
|
|
@@ -2461,7 +2599,7 @@ function HarnessPicker({ harnesses, value, disabled = false, adapter, onChange,
|
|
|
2461
2599
|
setOpen(false);
|
|
2462
2600
|
trigger.current?.focus({ preventScroll: true });
|
|
2463
2601
|
};
|
|
2464
|
-
|
|
2602
|
+
useEffect8(() => {
|
|
2465
2603
|
if (!open) return;
|
|
2466
2604
|
panel.current?.querySelector('[aria-selected="true"], [role="option"]')?.focus({ preventScroll: true });
|
|
2467
2605
|
const dismiss = (event) => {
|
|
@@ -2492,30 +2630,30 @@ function HarnessPicker({ harnesses, value, disabled = false, adapter, onChange,
|
|
|
2492
2630
|
onChange(id);
|
|
2493
2631
|
close();
|
|
2494
2632
|
};
|
|
2495
|
-
return /* @__PURE__ */
|
|
2633
|
+
return /* @__PURE__ */ jsxs8("div", { className: "scui-harness-menu", ref: root, onBlur: (event) => {
|
|
2496
2634
|
if (event.relatedTarget && !event.currentTarget.contains(event.relatedTarget)) setOpen(false);
|
|
2497
2635
|
}, children: [
|
|
2498
|
-
/* @__PURE__ */
|
|
2499
|
-
selected ? /* @__PURE__ */
|
|
2500
|
-
/* @__PURE__ */
|
|
2501
|
-
/* @__PURE__ */
|
|
2636
|
+
/* @__PURE__ */ jsxs8("button", { ref: trigger, className: "scui-harness-trigger", type: "button", disabled: disabled || !selected, "aria-label": selected ? `Coding harness: ${selected.label}` : "No coding harness available", "aria-haspopup": "dialog", "aria-expanded": open, "aria-controls": open ? menuId : void 0, onClick: () => setOpen((current) => !current), children: [
|
|
2637
|
+
selected ? /* @__PURE__ */ jsx9(Logo, { id: selected.id, size: 20 }) : null,
|
|
2638
|
+
/* @__PURE__ */ jsx9("strong", { children: selected?.label ?? "No harness available" }),
|
|
2639
|
+
/* @__PURE__ */ jsx9(UiIcon, { name: "chevron", size: 13 })
|
|
2502
2640
|
] }),
|
|
2503
|
-
open ? /* @__PURE__ */
|
|
2504
|
-
/* @__PURE__ */
|
|
2505
|
-
/* @__PURE__ */
|
|
2506
|
-
/* @__PURE__ */
|
|
2507
|
-
/* @__PURE__ */
|
|
2508
|
-
/* @__PURE__ */
|
|
2641
|
+
open ? /* @__PURE__ */ jsxs8("div", { ref: panel, id: menuId, className: "scui-harness-popover", role: "dialog", "aria-label": "Choose coding harness", onKeyDown: navigate, children: [
|
|
2642
|
+
/* @__PURE__ */ jsx9("strong", { className: "scui-harness-popover-title", children: "Choose coding harness" }),
|
|
2643
|
+
/* @__PURE__ */ jsx9("div", { className: "scui-harness-options", role: "listbox", "aria-label": "Available coding harnesses", children: available.map((item) => /* @__PURE__ */ jsxs8("button", { type: "button", role: "option", "aria-selected": item.id === selected?.id, onClick: () => select(item.id), children: [
|
|
2644
|
+
/* @__PURE__ */ jsx9(Logo, { id: item.id, size: 24 }),
|
|
2645
|
+
/* @__PURE__ */ jsx9("strong", { children: item.label }),
|
|
2646
|
+
/* @__PURE__ */ jsx9("span", { children: item.id === selected?.id ? /* @__PURE__ */ jsx9(UiIcon, { name: "check", size: 15 }) : null })
|
|
2509
2647
|
] }, item.id)) }),
|
|
2510
|
-
unavailable.length ? /* @__PURE__ */
|
|
2511
|
-
/* @__PURE__ */
|
|
2512
|
-
/* @__PURE__ */
|
|
2513
|
-
/* @__PURE__ */
|
|
2514
|
-
/* @__PURE__ */
|
|
2515
|
-
/* @__PURE__ */
|
|
2516
|
-
/* @__PURE__ */
|
|
2648
|
+
unavailable.length ? /* @__PURE__ */ jsxs8("details", { className: "scui-harness-manage", children: [
|
|
2649
|
+
/* @__PURE__ */ jsx9("summary", { children: "Manage additional harnesses" }),
|
|
2650
|
+
/* @__PURE__ */ jsx9("div", { children: unavailable.map((item) => /* @__PURE__ */ jsxs8("section", { children: [
|
|
2651
|
+
/* @__PURE__ */ jsx9(Logo, { id: item.id, size: 24 }),
|
|
2652
|
+
/* @__PURE__ */ jsxs8("span", { children: [
|
|
2653
|
+
/* @__PURE__ */ jsx9("strong", { children: item.label }),
|
|
2654
|
+
/* @__PURE__ */ jsx9("small", { children: item.reason || (item.auth === "required" ? "Authentication required" : "Unavailable") })
|
|
2517
2655
|
] }),
|
|
2518
|
-
item.repair ? /* @__PURE__ */
|
|
2656
|
+
item.repair ? /* @__PURE__ */ jsx9("button", { type: "button", onClick: () => adapter?.copyText?.(item.repair), children: "Copy fix" }) : null
|
|
2519
2657
|
] }, item.id)) })
|
|
2520
2658
|
] }) : null
|
|
2521
2659
|
] }) : null
|
|
@@ -2523,16 +2661,16 @@ function HarnessPicker({ harnesses, value, disabled = false, adapter, onChange,
|
|
|
2523
2661
|
}
|
|
2524
2662
|
|
|
2525
2663
|
// src/messenger.jsx
|
|
2526
|
-
import { jsx as
|
|
2664
|
+
import { Fragment as Fragment5, jsx as jsx10, jsxs as jsxs9 } from "preact/jsx-runtime";
|
|
2527
2665
|
var pendingMessageMemory = /* @__PURE__ */ new Map();
|
|
2528
2666
|
var messengerViewMemory = /* @__PURE__ */ new Map();
|
|
2529
2667
|
var newChatMemory = /* @__PURE__ */ new Map();
|
|
2530
2668
|
var TRACKED_ACTIONS = /* @__PURE__ */ new Set(["resume", "join", "detach", "branch", "reduce", "terminal", "export", "steer", "interrupt", "respond", "configureHarness", "refresh", "loadEarlier", "loadSessions"]);
|
|
2531
2669
|
function Receipt({ state, adapter }) {
|
|
2532
2670
|
const receipt = state.reductionReceipt;
|
|
2533
|
-
if (receipt) return /* @__PURE__ */
|
|
2534
|
-
/* @__PURE__ */
|
|
2535
|
-
/* @__PURE__ */
|
|
2671
|
+
if (receipt) return /* @__PURE__ */ jsx10("div", { className: "scui-receipt", children: /* @__PURE__ */ jsxs9("span", { children: [
|
|
2672
|
+
/* @__PURE__ */ jsx10("strong", { children: "Reduced and verified" }),
|
|
2673
|
+
/* @__PURE__ */ jsxs9("small", { children: [
|
|
2536
2674
|
receipt.sourceTokens.toLocaleString(),
|
|
2537
2675
|
" \u2192 ",
|
|
2538
2676
|
receipt.reducedTokens.toLocaleString(),
|
|
@@ -2541,35 +2679,35 @@ function Receipt({ state, adapter }) {
|
|
|
2541
2679
|
"\xD7 \xB7 reversible"
|
|
2542
2680
|
] })
|
|
2543
2681
|
] }) });
|
|
2544
|
-
if (state.exportReceipt) return /* @__PURE__ */
|
|
2545
|
-
/* @__PURE__ */
|
|
2546
|
-
/* @__PURE__ */
|
|
2682
|
+
if (state.exportReceipt) return /* @__PURE__ */ jsxs9("div", { className: "scui-receipt", children: [
|
|
2683
|
+
/* @__PURE__ */ jsxs9("span", { children: [
|
|
2684
|
+
/* @__PURE__ */ jsxs9("strong", { children: [
|
|
2547
2685
|
"Lossless export ready \xB7 ",
|
|
2548
2686
|
harnessDisplayName(state.exportReceipt.targetHarness)
|
|
2549
2687
|
] }),
|
|
2550
|
-
/* @__PURE__ */
|
|
2688
|
+
/* @__PURE__ */ jsxs9("small", { children: [
|
|
2551
2689
|
state.exportReceipt.path,
|
|
2552
2690
|
" \xB7 ",
|
|
2553
2691
|
state.exportReceipt.files,
|
|
2554
2692
|
" files"
|
|
2555
2693
|
] })
|
|
2556
2694
|
] }),
|
|
2557
|
-
/* @__PURE__ */
|
|
2695
|
+
/* @__PURE__ */ jsx10("button", { type: "button", onClick: () => adapter.copyText?.(state.exportReceipt.path), children: "Copy path" })
|
|
2558
2696
|
] });
|
|
2559
|
-
if (state.terminalHandoff) return /* @__PURE__ */
|
|
2560
|
-
/* @__PURE__ */
|
|
2561
|
-
/* @__PURE__ */
|
|
2562
|
-
/* @__PURE__ */
|
|
2697
|
+
if (state.terminalHandoff) return /* @__PURE__ */ jsxs9("div", { className: "scui-receipt", children: [
|
|
2698
|
+
/* @__PURE__ */ jsxs9("span", { children: [
|
|
2699
|
+
/* @__PURE__ */ jsx10("strong", { children: "Terminal handoff ready" }),
|
|
2700
|
+
/* @__PURE__ */ jsx10("small", { children: state.terminalHandoff.cwd })
|
|
2563
2701
|
] }),
|
|
2564
|
-
/* @__PURE__ */
|
|
2702
|
+
/* @__PURE__ */ jsx10("button", { type: "button", onClick: () => adapter.copyText?.(terminalCommand(state.terminalHandoff)), children: "Copy command" })
|
|
2565
2703
|
] });
|
|
2566
2704
|
return null;
|
|
2567
2705
|
}
|
|
2568
2706
|
function ConversationActions({ state, adapter, actionPending, onNew, onSettings }) {
|
|
2569
|
-
const [open, setOpen] =
|
|
2570
|
-
const root =
|
|
2571
|
-
const panel =
|
|
2572
|
-
const trigger =
|
|
2707
|
+
const [open, setOpen] = useState7(false);
|
|
2708
|
+
const root = useRef8(null);
|
|
2709
|
+
const panel = useRef8(null);
|
|
2710
|
+
const trigger = useRef8(null);
|
|
2573
2711
|
const menuId = useId3();
|
|
2574
2712
|
const targets = state.harnesses.filter((item) => item.startable);
|
|
2575
2713
|
const groups = [
|
|
@@ -2593,7 +2731,7 @@ function ConversationActions({ state, adapter, actionPending, onNew, onSettings
|
|
|
2593
2731
|
items: state.canBranch ? targets.map((target) => ({ key: `branch:${target.id}`, label: target.id === state.harness ? `Fork in ${target.label}` : `Continue with ${target.label}`, intent: { action: "branch", targetHarness: target.id } })) : []
|
|
2594
2732
|
}
|
|
2595
2733
|
].filter((group) => group.items.length);
|
|
2596
|
-
|
|
2734
|
+
useEffect9(() => {
|
|
2597
2735
|
if (!open) return;
|
|
2598
2736
|
panel.current?.querySelector("button:not(:disabled)")?.focus({ preventScroll: true });
|
|
2599
2737
|
const dismiss = (event) => {
|
|
@@ -2633,64 +2771,64 @@ function ConversationActions({ state, adapter, actionPending, onNew, onSettings
|
|
|
2633
2771
|
const index = event.key === "Home" ? 0 : event.key === "End" ? items.length - 1 : event.key === "ArrowDown" ? (current + 1) % items.length : (current <= 0 ? items.length : current) - 1;
|
|
2634
2772
|
items[index].focus({ preventScroll: true });
|
|
2635
2773
|
};
|
|
2636
|
-
return /* @__PURE__ */
|
|
2774
|
+
return /* @__PURE__ */ jsxs9("div", { className: "scui-menu", ref: root, onBlur: (event) => {
|
|
2637
2775
|
if (event.relatedTarget && !event.currentTarget.contains(event.relatedTarget)) setOpen(false);
|
|
2638
2776
|
}, children: [
|
|
2639
|
-
/* @__PURE__ */
|
|
2640
|
-
open ? /* @__PURE__ */
|
|
2641
|
-
/* @__PURE__ */
|
|
2642
|
-
group.items.map((item) => /* @__PURE__ */
|
|
2777
|
+
/* @__PURE__ */ jsx10("button", { ref: trigger, className: "scui-menu-trigger", type: "button", "aria-label": "Conversation actions", "aria-haspopup": "menu", "aria-expanded": open, "aria-controls": open ? menuId : void 0, onClick: () => setOpen((value) => !value), children: /* @__PURE__ */ jsx10(UiIcon, { name: "menu", size: 18 }) }),
|
|
2778
|
+
open ? /* @__PURE__ */ jsx10("div", { ref: panel, id: menuId, className: "scui-menu-panel", role: "menu", "aria-label": "Conversation actions", onKeyDown: navigate, children: groups.map((group) => /* @__PURE__ */ jsxs9("section", { role: "group", "aria-label": group.label, children: [
|
|
2779
|
+
/* @__PURE__ */ jsx10("strong", { children: group.label }),
|
|
2780
|
+
group.items.map((item) => /* @__PURE__ */ jsx10("button", { role: "menuitem", type: "button", disabled: actionPending, onClick: () => dispatch(item), children: item.label }, item.key))
|
|
2643
2781
|
] }, group.label)) }) : null
|
|
2644
2782
|
] });
|
|
2645
2783
|
}
|
|
2646
2784
|
function ChatHeader({ state, adapter, pendingStatus, actionPending, onBack, onNew, onClose, onSettings, headerActions: HeaderActions }) {
|
|
2647
|
-
const back =
|
|
2785
|
+
const back = useRef8(null);
|
|
2648
2786
|
const harness = state.attached?.harness ?? state.harness;
|
|
2649
2787
|
const title = state.attached ? sessionDisplayName(state.attached) : harnessDisplayName(harness) || "Agent chat";
|
|
2650
2788
|
const status = state.needsInput ? "Needs input" : pendingStatus === "failed" ? "Send failed" : state.busy ? "Working" : pendingStatus === "sending" ? "Sending" : pendingStatus === "editing" ? "Editing message" : state.messaging === "live_peer" ? "Live" : state.mode === "mirror" ? "Read-only" : "Ready";
|
|
2651
|
-
|
|
2789
|
+
useEffect9(() => {
|
|
2652
2790
|
if (state.mode === "mirror" && !state.canSend) back.current?.focus({ preventScroll: true });
|
|
2653
2791
|
}, []);
|
|
2654
|
-
return /* @__PURE__ */
|
|
2655
|
-
/* @__PURE__ */
|
|
2656
|
-
/* @__PURE__ */
|
|
2657
|
-
/* @__PURE__ */
|
|
2658
|
-
/* @__PURE__ */
|
|
2659
|
-
/* @__PURE__ */
|
|
2792
|
+
return /* @__PURE__ */ jsxs9("header", { className: "scui-head scui-chat-head", children: [
|
|
2793
|
+
/* @__PURE__ */ jsx10("button", { ref: back, type: "button", "aria-label": "Back to chats", onClick: onBack, children: /* @__PURE__ */ jsx10(UiIcon, { name: "back", size: 17 }) }),
|
|
2794
|
+
/* @__PURE__ */ jsx10(HarnessLogo, { id: harness, size: 24 }),
|
|
2795
|
+
/* @__PURE__ */ jsxs9("span", { className: "scui-head-copy", children: [
|
|
2796
|
+
/* @__PURE__ */ jsx10("strong", { children: title }),
|
|
2797
|
+
/* @__PURE__ */ jsxs9("small", { children: [
|
|
2660
2798
|
harnessDisplayName(harness),
|
|
2661
2799
|
" \xB7 ",
|
|
2662
2800
|
status
|
|
2663
2801
|
] })
|
|
2664
2802
|
] }),
|
|
2665
|
-
HeaderActions ? /* @__PURE__ */
|
|
2666
|
-
/* @__PURE__ */
|
|
2667
|
-
onClose ? /* @__PURE__ */
|
|
2803
|
+
HeaderActions ? /* @__PURE__ */ jsx10(HeaderActions, { state, adapter, value: "chat" }) : null,
|
|
2804
|
+
/* @__PURE__ */ jsx10(ConversationActions, { state, adapter, actionPending, onNew, onSettings }),
|
|
2805
|
+
onClose ? /* @__PURE__ */ jsx10("button", { type: "button", "aria-label": "Close", onClick: onClose, children: /* @__PURE__ */ jsx10(UiIcon, { name: "close", size: 18 }) }) : null
|
|
2668
2806
|
] });
|
|
2669
2807
|
}
|
|
2670
2808
|
function Chat({ state, adapter, onBack, onNew, onClose, components, slots, labels, contextCandidates, navigation, composerCommand }) {
|
|
2671
2809
|
const Header = slots.header;
|
|
2672
2810
|
const HeaderActions = slots.headerActions;
|
|
2673
2811
|
const memoryKey = state.attached?.key || `${state.harness}:${state.workspace}`;
|
|
2674
|
-
const [pending, setPendingState] =
|
|
2675
|
-
const [pendingAction, setPendingAction] =
|
|
2676
|
-
const [restoreDraft, setRestoreDraft] =
|
|
2677
|
-
const [settings, setSettings] =
|
|
2678
|
-
const restoreSequence =
|
|
2679
|
-
const actionSequence =
|
|
2680
|
-
const lastNavigation =
|
|
2681
|
-
const acknowledged =
|
|
2812
|
+
const [pending, setPendingState] = useState7(() => pendingMessageMemory.get(memoryKey) ?? null);
|
|
2813
|
+
const [pendingAction, setPendingAction] = useState7(null);
|
|
2814
|
+
const [restoreDraft, setRestoreDraft] = useState7(null);
|
|
2815
|
+
const [settings, setSettings] = useState7(null);
|
|
2816
|
+
const restoreSequence = useRef8(0);
|
|
2817
|
+
const actionSequence = useRef8(0);
|
|
2818
|
+
const lastNavigation = useRef8(null);
|
|
2819
|
+
const acknowledged = useRef8(/* @__PURE__ */ new Set());
|
|
2682
2820
|
const setPending = (update) => setPendingState((current) => {
|
|
2683
2821
|
const next = typeof update === "function" ? update(current) : update;
|
|
2684
2822
|
if (next) boundedSet(pendingMessageMemory, memoryKey, next);
|
|
2685
2823
|
else pendingMessageMemory.delete(memoryKey);
|
|
2686
2824
|
return next;
|
|
2687
2825
|
});
|
|
2688
|
-
|
|
2826
|
+
useEffect9(() => {
|
|
2689
2827
|
setPendingState(pendingMessageMemory.get(memoryKey) ?? null);
|
|
2690
2828
|
setPendingAction(null);
|
|
2691
2829
|
setRestoreDraft(null);
|
|
2692
2830
|
}, [memoryKey]);
|
|
2693
|
-
|
|
2831
|
+
useEffect9(() => {
|
|
2694
2832
|
if (!navigation || navigation.id === lastNavigation.current) return;
|
|
2695
2833
|
lastNavigation.current = navigation.id;
|
|
2696
2834
|
if (navigation.draft === void 0 && !navigation.context?.length && !navigation.images?.length) return;
|
|
@@ -2701,7 +2839,7 @@ function Chat({ state, adapter, onBack, onNew, onClose, components, slots, label
|
|
|
2701
2839
|
images: navigation.images
|
|
2702
2840
|
});
|
|
2703
2841
|
}, [navigation]);
|
|
2704
|
-
|
|
2842
|
+
useEffect9(() => {
|
|
2705
2843
|
if (!pending) return;
|
|
2706
2844
|
if (state.transcript.some((entry) => entry.role === "user" && entry.text.trim() === pending.text.trim() && !pending.baselineIds.includes(entry.id))) {
|
|
2707
2845
|
setPending(null);
|
|
@@ -2730,7 +2868,7 @@ function Chat({ state, adapter, onBack, onNew, onClose, components, slots, label
|
|
|
2730
2868
|
setRestoreDraft({ id: restoreSequence.current, text: pending.text, context: pending.context, images: pending.images });
|
|
2731
2869
|
setPending({ ...pending, status: "editing" });
|
|
2732
2870
|
};
|
|
2733
|
-
|
|
2871
|
+
useEffect9(() => {
|
|
2734
2872
|
const key = state.attached?.key;
|
|
2735
2873
|
if (!key || !state.attention.some((item) => item.key === key)) {
|
|
2736
2874
|
if (key) acknowledged.current.delete(key);
|
|
@@ -2765,7 +2903,7 @@ function Chat({ state, adapter, onBack, onNew, onClose, components, slots, label
|
|
|
2765
2903
|
return result;
|
|
2766
2904
|
}
|
|
2767
2905
|
}), [adapter, state.error]);
|
|
2768
|
-
|
|
2906
|
+
useEffect9(() => {
|
|
2769
2907
|
if (!pendingAction) return;
|
|
2770
2908
|
if (state.operation && !pendingAction.seenOperation) {
|
|
2771
2909
|
setPendingAction({ ...pendingAction, seenOperation: true });
|
|
@@ -2780,40 +2918,40 @@ function Chat({ state, adapter, onBack, onNew, onClose, components, slots, label
|
|
|
2780
2918
|
const unreadAfterMessages = state.attention.find((item) => item.key === state.attached?.key)?.afterMessages ?? null;
|
|
2781
2919
|
const Advisory = components.HarnessAdvisory ?? HarnessAdvisory;
|
|
2782
2920
|
const SettingsPanel = components.HarnessSettingsPanel ?? HarnessSettingsPanel;
|
|
2783
|
-
return /* @__PURE__ */
|
|
2784
|
-
Header ? /* @__PURE__ */
|
|
2785
|
-
actionLabel ? /* @__PURE__ */
|
|
2786
|
-
/* @__PURE__ */
|
|
2921
|
+
return /* @__PURE__ */ jsxs9("section", { className: "scui-chat", children: [
|
|
2922
|
+
Header ? /* @__PURE__ */ jsx10(Header, { state: actionState, adapter: trackedAdapter, value: null }) : /* @__PURE__ */ jsx10(ChatHeader, { state: actionState, adapter: trackedAdapter, pendingStatus: pending?.status ?? null, actionPending: Boolean(action), onBack, onNew, onClose, onSettings: () => setSettings({ recommendedChange: null }), headerActions: HeaderActions }),
|
|
2923
|
+
actionLabel ? /* @__PURE__ */ jsxs9("div", { className: "scui-operation", role: "status", children: [
|
|
2924
|
+
/* @__PURE__ */ jsx10("i", {}),
|
|
2787
2925
|
actionLabel
|
|
2788
2926
|
] }) : null,
|
|
2789
|
-
state.error ? /* @__PURE__ */
|
|
2790
|
-
/* @__PURE__ */
|
|
2791
|
-
state.recoverable ? /* @__PURE__ */
|
|
2927
|
+
state.error ? /* @__PURE__ */ jsxs9("div", { className: "scui-error", role: "alert", children: [
|
|
2928
|
+
/* @__PURE__ */ jsx10("span", { children: state.error }),
|
|
2929
|
+
state.recoverable ? /* @__PURE__ */ jsx10("button", { type: "button", disabled: Boolean(action), onClick: () => trackedAdapter.onIntent({ action: "refresh" }), children: "Retry" }) : null
|
|
2792
2930
|
] }) : null,
|
|
2793
|
-
/* @__PURE__ */
|
|
2794
|
-
/* @__PURE__ */
|
|
2795
|
-
/* @__PURE__ */
|
|
2796
|
-
/* @__PURE__ */
|
|
2797
|
-
state.mode !== "mirror" || state.canSend ? /* @__PURE__ */
|
|
2798
|
-
settings ? /* @__PURE__ */
|
|
2931
|
+
/* @__PURE__ */ jsx10(Receipt, { state, adapter }),
|
|
2932
|
+
/* @__PURE__ */ jsx10(Conversation, { state: actionState, adapter: trackedAdapter, components, slots, memoryKey, pending: pendingMessage, unreadAfterMessages }, memoryKey),
|
|
2933
|
+
/* @__PURE__ */ jsx10(ContinuationBar, { state: actionState, adapter: trackedAdapter, labels }),
|
|
2934
|
+
/* @__PURE__ */ jsx10(Advisory, { state: actionState, adapter: trackedAdapter, value: state.interopSettings?.advisories[0] ?? null, onReview: (recommendedChange) => setSettings({ recommendedChange }) }),
|
|
2935
|
+
state.mode !== "mirror" || state.canSend ? /* @__PURE__ */ jsx10(Composer, { state: actionState, adapter: trackedAdapter, labels, memoryKey, pendingStatus: pending?.status ?? null, restoreDraft, command: composerCommand, contextCandidates, components, onDraftRestored: (id) => setRestoreDraft((value) => value?.id === id ? null : value), onPending: beginPending }, memoryKey) : null,
|
|
2936
|
+
settings ? /* @__PURE__ */ jsx10(SettingsPanel, { state: actionState, adapter: trackedAdapter, value: state.interopSettings, recommendedChange: settings.recommendedChange, onClose: () => setSettings(null) }) : null
|
|
2799
2937
|
] });
|
|
2800
2938
|
}
|
|
2801
2939
|
function NewChat({ state, adapter, onBack, onClose, onStarted, labels, memoryKey, headerActions: HeaderActions, contextCandidates, components, navigation, composerCommand }) {
|
|
2802
2940
|
const startable = state.harnesses.filter((item) => item.startable);
|
|
2803
2941
|
const startableKey = startable.map((item) => `${item.id}:${item.launchModes?.join(",")}:${item.preferredLaunchMode ?? ""}`).join("\0");
|
|
2804
2942
|
const remembered = newChatMemory.get(memoryKey) ?? { harness: startable[0]?.id ?? "", draft: "", context: [], images: [], modes: {} };
|
|
2805
|
-
const [harness, setHarness] =
|
|
2806
|
-
const [draft, setDraft] =
|
|
2807
|
-
const [context, setContext] =
|
|
2808
|
-
const [images, setImages] =
|
|
2809
|
-
const [modes, setModes] =
|
|
2810
|
-
const [starting, setStarting] =
|
|
2811
|
-
const [picking, setPicking] =
|
|
2812
|
-
const [dragging, setDragging] =
|
|
2813
|
-
const [pickerError, setPickerError] =
|
|
2814
|
-
const startSequence =
|
|
2815
|
-
const lastComposerCommand =
|
|
2816
|
-
const textarea =
|
|
2943
|
+
const [harness, setHarness] = useState7(remembered.harness);
|
|
2944
|
+
const [draft, setDraft] = useState7(remembered.draft);
|
|
2945
|
+
const [context, setContext] = useState7(remembered.context);
|
|
2946
|
+
const [images, setImages] = useState7(remembered.images ?? []);
|
|
2947
|
+
const [modes, setModes] = useState7(remembered.modes ?? {});
|
|
2948
|
+
const [starting, setStarting] = useState7(null);
|
|
2949
|
+
const [picking, setPicking] = useState7(false);
|
|
2950
|
+
const [dragging, setDragging] = useState7(false);
|
|
2951
|
+
const [pickerError, setPickerError] = useState7(null);
|
|
2952
|
+
const startSequence = useRef8(0);
|
|
2953
|
+
const lastComposerCommand = useRef8(null);
|
|
2954
|
+
const textarea = useRef8(null);
|
|
2817
2955
|
const selectedHarness = startable.find((item) => item.id === harness) ?? null;
|
|
2818
2956
|
const Picker = components.HarnessPicker ?? HarnessPicker;
|
|
2819
2957
|
const Readiness = components.HarnessReadiness ?? HarnessReadiness;
|
|
@@ -2824,13 +2962,13 @@ function NewChat({ state, adapter, onBack, onClose, onStarted, labels, memoryKey
|
|
|
2824
2962
|
const terminalAttachments = mode === "terminal" && (context.length > 0 || images.length > 0);
|
|
2825
2963
|
const remember = (overrides = {}) => boundedSet(newChatMemory, memoryKey, { harness, draft, context, images, modes, ...overrides });
|
|
2826
2964
|
useAutosizeTextarea(textarea, draft);
|
|
2827
|
-
|
|
2965
|
+
useEffect9(() => {
|
|
2828
2966
|
if (startable.some((item) => item.id === harness)) return;
|
|
2829
2967
|
const next = startable[0]?.id ?? "";
|
|
2830
2968
|
setHarness(next);
|
|
2831
2969
|
remember({ harness: next });
|
|
2832
2970
|
}, [harness, startableKey]);
|
|
2833
|
-
|
|
2971
|
+
useEffect9(() => {
|
|
2834
2972
|
if (!starting || starting.mode === "terminal") return;
|
|
2835
2973
|
const sessionChanged = (state.attached?.key ?? null) !== starting.attachedKey;
|
|
2836
2974
|
const beganWorking = !starting.busy && state.busy;
|
|
@@ -2838,13 +2976,13 @@ function NewChat({ state, adapter, onBack, onClose, onStarted, labels, memoryKey
|
|
|
2838
2976
|
newChatMemory.delete(memoryKey);
|
|
2839
2977
|
onStarted("headless");
|
|
2840
2978
|
}, [memoryKey, onStarted, starting, state.attached?.key, state.busy]);
|
|
2841
|
-
|
|
2979
|
+
useEffect9(() => {
|
|
2842
2980
|
if (starting && state.error !== starting.initialError && !state.busy && !state.operation) setStarting(null);
|
|
2843
2981
|
}, [starting, state.busy, state.error, state.operation]);
|
|
2844
|
-
|
|
2982
|
+
useEffect9(() => {
|
|
2845
2983
|
textarea.current?.focus({ preventScroll: true });
|
|
2846
2984
|
}, []);
|
|
2847
|
-
|
|
2985
|
+
useEffect9(() => {
|
|
2848
2986
|
if (!navigation) return;
|
|
2849
2987
|
const nextHarness = startable.some((item) => item.id === navigation.harness) ? navigation.harness : harness;
|
|
2850
2988
|
const nextDraft = typeof navigation.draft === "string" ? navigation.draft : draft;
|
|
@@ -2857,7 +2995,7 @@ function NewChat({ state, adapter, onBack, onClose, onStarted, labels, memoryKey
|
|
|
2857
2995
|
remember({ harness: nextHarness, draft: nextDraft, context: nextContext, images: nextImages });
|
|
2858
2996
|
textarea.current?.focus({ preventScroll: true });
|
|
2859
2997
|
}, [navigation?.id]);
|
|
2860
|
-
|
|
2998
|
+
useEffect9(() => {
|
|
2861
2999
|
if (!composerCommand || composerCommand.id === lastComposerCommand.current) return;
|
|
2862
3000
|
lastComposerCommand.current = composerCommand.id;
|
|
2863
3001
|
if (composerCommand.action === "attach") {
|
|
@@ -2958,40 +3096,40 @@ function NewChat({ state, adapter, onBack, onClose, onStarted, labels, memoryKey
|
|
|
2958
3096
|
Promise.resolve(result).catch(() => setStarting((current) => current?.id === id ? null : current));
|
|
2959
3097
|
}
|
|
2960
3098
|
};
|
|
2961
|
-
return /* @__PURE__ */
|
|
2962
|
-
/* @__PURE__ */
|
|
2963
|
-
/* @__PURE__ */
|
|
2964
|
-
/* @__PURE__ */
|
|
2965
|
-
/* @__PURE__ */
|
|
2966
|
-
/* @__PURE__ */
|
|
3099
|
+
return /* @__PURE__ */ jsxs9("section", { className: "scui-chat", children: [
|
|
3100
|
+
/* @__PURE__ */ jsxs9("header", { className: "scui-head", children: [
|
|
3101
|
+
/* @__PURE__ */ jsx10("button", { type: "button", "aria-label": "Back", onClick: onBack, children: /* @__PURE__ */ jsx10(UiIcon, { name: "back", size: 18 }) }),
|
|
3102
|
+
/* @__PURE__ */ jsxs9("span", { className: "scui-head-copy", children: [
|
|
3103
|
+
/* @__PURE__ */ jsx10("strong", { children: labels.newChat }),
|
|
3104
|
+
/* @__PURE__ */ jsx10("small", { children: "No session is created until you send" })
|
|
2967
3105
|
] }),
|
|
2968
|
-
HeaderActions ? /* @__PURE__ */
|
|
2969
|
-
onClose ? /* @__PURE__ */
|
|
3106
|
+
HeaderActions ? /* @__PURE__ */ jsx10(HeaderActions, { state, adapter, value: "new" }) : null,
|
|
3107
|
+
onClose ? /* @__PURE__ */ jsx10("button", { type: "button", "aria-label": "Close", onClick: onClose, children: /* @__PURE__ */ jsx10(UiIcon, { name: "close", size: 18 }) }) : null
|
|
2970
3108
|
] }),
|
|
2971
|
-
starting ? /* @__PURE__ */
|
|
2972
|
-
/* @__PURE__ */
|
|
3109
|
+
starting ? /* @__PURE__ */ jsxs9("div", { className: "scui-operation", role: "status", children: [
|
|
3110
|
+
/* @__PURE__ */ jsx10("i", {}),
|
|
2973
3111
|
mode === "terminal" ? "Opening terminal\u2026" : operationLabel("start")
|
|
2974
3112
|
] }) : null,
|
|
2975
|
-
/* @__PURE__ */
|
|
2976
|
-
/* @__PURE__ */
|
|
2977
|
-
/* @__PURE__ */
|
|
2978
|
-
/* @__PURE__ */
|
|
3113
|
+
/* @__PURE__ */ jsxs9("div", { className: "scui-new", children: [
|
|
3114
|
+
/* @__PURE__ */ jsx10("span", { "aria-hidden": "true", children: "\u2726" }),
|
|
3115
|
+
/* @__PURE__ */ jsx10("strong", { children: "What should the agent build or fix?" }),
|
|
3116
|
+
/* @__PURE__ */ jsx10("small", { children: "Choose a coding harness and send the first message." })
|
|
2979
3117
|
] }),
|
|
2980
|
-
/* @__PURE__ */
|
|
2981
|
-
/* @__PURE__ */
|
|
2982
|
-
mode !== "terminal" ? /* @__PURE__ */
|
|
2983
|
-
/* @__PURE__ */
|
|
3118
|
+
/* @__PURE__ */ jsxs9("div", { className: "scui-compose", children: [
|
|
3119
|
+
/* @__PURE__ */ jsx10(Readiness, { harnesses: state.harnesses, state, adapter }),
|
|
3120
|
+
mode !== "terminal" ? /* @__PURE__ */ jsx10(ContextCandidates, { items: contextCandidates, context, images, state, adapter, onAttach: attachCandidate, component: components.ContextCandidate }) : null,
|
|
3121
|
+
/* @__PURE__ */ jsx10(ImageTray, { items: images, onRemove: (index) => setImages((items) => {
|
|
2984
3122
|
const next = items.filter((_, itemIndex) => itemIndex !== index);
|
|
2985
3123
|
remember({ images: next });
|
|
2986
3124
|
return next;
|
|
2987
3125
|
}) }),
|
|
2988
|
-
/* @__PURE__ */
|
|
3126
|
+
/* @__PURE__ */ jsx10(ContextTray, { items: context, onRemove: (index) => setContext((items) => {
|
|
2989
3127
|
const next = items.filter((_, itemIndex) => itemIndex !== index);
|
|
2990
3128
|
remember({ context: next });
|
|
2991
3129
|
return next;
|
|
2992
3130
|
}) }),
|
|
2993
|
-
terminalAttachments ? /* @__PURE__ */
|
|
2994
|
-
/* @__PURE__ */
|
|
3131
|
+
terminalAttachments ? /* @__PURE__ */ jsx10("small", { className: "scui-context-error", role: "alert", children: "Terminal starts currently accept text only. Remove attachments or choose Headless." }) : pickerError ? /* @__PURE__ */ jsx10("small", { className: "scui-context-error", role: "alert", children: pickerError }) : null,
|
|
3132
|
+
/* @__PURE__ */ jsxs9("div", { className: `scui-envelope scui-new-envelope${dragging ? " scui-drop-target" : ""}`, onDragEnter: (event) => {
|
|
2995
3133
|
if (Array.from(event.dataTransfer?.types ?? []).includes("Files")) {
|
|
2996
3134
|
event.preventDefault();
|
|
2997
3135
|
setDragging(true);
|
|
@@ -3001,7 +3139,7 @@ function NewChat({ state, adapter, onBack, onClose, onStarted, labels, memoryKey
|
|
|
3001
3139
|
}, onDragLeave: (event) => {
|
|
3002
3140
|
if (!event.currentTarget.contains(event.relatedTarget)) setDragging(false);
|
|
3003
3141
|
}, onDrop: dropImages, children: [
|
|
3004
|
-
/* @__PURE__ */
|
|
3142
|
+
/* @__PURE__ */ jsx10("textarea", { ref: textarea, rows: 3, "aria-label": "Message coding agent", placeholder: startable.length ? "What should the agent do?" : "No coding harness is available", value: draft, disabled: !startable.length || Boolean(starting), onPaste: pasteImages, onInput: (event) => {
|
|
3005
3143
|
const value = event.currentTarget.value;
|
|
3006
3144
|
setDraft(value);
|
|
3007
3145
|
remember({ draft: value });
|
|
@@ -3011,19 +3149,19 @@ function NewChat({ state, adapter, onBack, onClose, onStarted, labels, memoryKey
|
|
|
3011
3149
|
send();
|
|
3012
3150
|
}
|
|
3013
3151
|
} }),
|
|
3014
|
-
/* @__PURE__ */
|
|
3015
|
-
adapter.pickContext ? /* @__PURE__ */
|
|
3016
|
-
/* @__PURE__ */
|
|
3152
|
+
/* @__PURE__ */ jsxs9("footer", { className: "scui-new-envelope-controls", children: [
|
|
3153
|
+
adapter.pickContext ? /* @__PURE__ */ jsx10("button", { className: "scui-attach", type: "button", "aria-label": labels.attachContext ?? DEFAULT_LABELS.attachContext, disabled: mode === "terminal" || picking || context.length >= MAX_CONTEXT_ITEMS && images.length >= MAX_IMAGE_ITEMS || Boolean(starting), onClick: pickContext, children: picking ? /* @__PURE__ */ jsx10("i", { className: "scui-control-spinner" }) : /* @__PURE__ */ jsx10(UiIcon, { name: "attach", size: 17 }) }) : null,
|
|
3154
|
+
/* @__PURE__ */ jsx10(Picker, { harnesses: state.harnesses, value: harness, disabled: Boolean(starting), adapter, logo: components.HarnessLogo, onChange: (value) => {
|
|
3017
3155
|
setHarness(value);
|
|
3018
3156
|
remember({ harness: value });
|
|
3019
3157
|
} }),
|
|
3020
|
-
/* @__PURE__ */
|
|
3158
|
+
/* @__PURE__ */ jsx10(ExecutionModeSelect, { modes: launchModes, value: mode, disabled: Boolean(starting) || mode !== requestedMode, onChange: (item) => {
|
|
3021
3159
|
const next = { ...modes, [harness]: item };
|
|
3022
3160
|
setModes(next);
|
|
3023
3161
|
setPickerError(null);
|
|
3024
3162
|
remember({ modes: next });
|
|
3025
3163
|
} }),
|
|
3026
|
-
/* @__PURE__ */
|
|
3164
|
+
/* @__PURE__ */ jsx10("span", { children: /* @__PURE__ */ jsx10("button", { type: "button", className: "scui-send", "aria-label": mode === "terminal" ? "Start terminal session" : "Start headless session", disabled: !draft.trim() && !images.length || !harness || Boolean(starting) || terminalAttachments || mode === "terminal" && !draft.trim(), onClick: send, children: starting ? /* @__PURE__ */ jsx10("i", { className: "scui-control-spinner" }) : /* @__PURE__ */ jsx10(UiIcon, { name: "send", size: 17 }) }) })
|
|
3027
3165
|
] })
|
|
3028
3166
|
] })
|
|
3029
3167
|
] })
|
|
@@ -3034,18 +3172,19 @@ function SupercodeMessenger({ state: stateInput, adapter, class: className = "",
|
|
|
3034
3172
|
const contextCandidates = useMemo3(() => normalizeAttachmentCandidates(candidatesInput), [candidatesInput]);
|
|
3035
3173
|
const copy = { ...DEFAULT_LABELS, ...labels };
|
|
3036
3174
|
const memoryKey = state.workspace || "@default";
|
|
3037
|
-
const [view, setViewState] =
|
|
3038
|
-
const [opening, setOpening] =
|
|
3039
|
-
const [newNavigation, setNewNavigation] =
|
|
3040
|
-
const [chatNavigation, setChatNavigation] =
|
|
3041
|
-
const [listFocus, setListFocus] =
|
|
3042
|
-
const
|
|
3175
|
+
const [view, setViewState] = useState7(initialView ?? (state.attention.length ? "list" : messengerViewMemory.get(memoryKey) ?? (state.attached || state.transcript.length ? "chat" : "list")));
|
|
3176
|
+
const [opening, setOpening] = useState7(null);
|
|
3177
|
+
const [newNavigation, setNewNavigation] = useState7(null);
|
|
3178
|
+
const [chatNavigation, setChatNavigation] = useState7(null);
|
|
3179
|
+
const [listFocus, setListFocus] = useState7(null);
|
|
3180
|
+
const [inspecting, setInspecting] = useState7(null);
|
|
3181
|
+
const lastNavigation = useRef8(null);
|
|
3043
3182
|
const setView = (next) => {
|
|
3044
3183
|
boundedSet(messengerViewMemory, memoryKey, next);
|
|
3045
3184
|
setViewState(next);
|
|
3046
3185
|
onViewChange?.(next);
|
|
3047
3186
|
};
|
|
3048
|
-
|
|
3187
|
+
useEffect9(() => {
|
|
3049
3188
|
if (!navigation || navigation.id === lastNavigation.current) return;
|
|
3050
3189
|
lastNavigation.current = navigation.id;
|
|
3051
3190
|
if (navigation.view === "list") {
|
|
@@ -3075,7 +3214,7 @@ function SupercodeMessenger({ state: stateInput, adapter, class: className = "",
|
|
|
3075
3214
|
adapter.onIntent({ action: "attach", key: navigation.sessionKey });
|
|
3076
3215
|
}
|
|
3077
3216
|
}, [adapter, navigation, state.attached?.key, state.sessions]);
|
|
3078
|
-
|
|
3217
|
+
useEffect9(() => {
|
|
3079
3218
|
if (!opening) return;
|
|
3080
3219
|
if (state.attached?.key === opening.key) {
|
|
3081
3220
|
setOpening(null);
|
|
@@ -3090,47 +3229,59 @@ function SupercodeMessenger({ state: stateInput, adapter, class: className = "",
|
|
|
3090
3229
|
setOpening(row);
|
|
3091
3230
|
adapter.onIntent({ action: "attach", key: row.key });
|
|
3092
3231
|
};
|
|
3232
|
+
const openSubagents = (row) => {
|
|
3233
|
+
setListFocus(row.key);
|
|
3234
|
+
setInspecting(row);
|
|
3235
|
+
adapter.onIntent({ action: "openSubagents", key: row.key });
|
|
3236
|
+
};
|
|
3093
3237
|
const close = () => adapter.onClose?.();
|
|
3094
3238
|
const Footer = slots.footer;
|
|
3095
3239
|
const HeaderActions = slots.headerActions;
|
|
3096
|
-
|
|
3097
|
-
|
|
3098
|
-
|
|
3099
|
-
|
|
3100
|
-
|
|
3101
|
-
|
|
3102
|
-
|
|
3103
|
-
|
|
3104
|
-
|
|
3105
|
-
|
|
3106
|
-
|
|
3107
|
-
|
|
3108
|
-
|
|
3109
|
-
|
|
3110
|
-
|
|
3111
|
-
|
|
3112
|
-
|
|
3113
|
-
|
|
3114
|
-
|
|
3115
|
-
|
|
3116
|
-
|
|
3117
|
-
|
|
3118
|
-
|
|
3240
|
+
const inspectorParent = inspecting ?? (state.subagentInspector ? state.sessions.find((row) => row.key === state.subagentInspector.parentKey) ?? { key: state.subagentInspector.parentKey, title: state.subagentInspector.parentTitle } : null);
|
|
3241
|
+
const inspectorState = inspectorParent ? {
|
|
3242
|
+
...state,
|
|
3243
|
+
subagentInspector: state.subagentInspector?.parentKey === inspectorParent.key ? state.subagentInspector : { parentKey: inspectorParent.key, parentTitle: sessionDisplayName(inspectorParent), status: "loading", items: [], selectedKey: null, transcript: [], error: null }
|
|
3244
|
+
} : null;
|
|
3245
|
+
return /* @__PURE__ */ jsxs9("main", { className: `scui-root ${className}`, "data-view": inspectorState ? "agents" : view, "data-mode": state.mode, "aria-label": "Supercode messenger", children: [
|
|
3246
|
+
inspectorState ? /* @__PURE__ */ jsx10(SubagentInspector, { state: inspectorState, adapter, onClose: () => setInspecting(null) }) : /* @__PURE__ */ jsxs9(Fragment5, { children: [
|
|
3247
|
+
view === "list" ? /* @__PURE__ */ jsx10(SessionList, { state, adapter, focusKey: listFocus, onOpen: open, onOpenSubagents: openSubagents, onNew: () => {
|
|
3248
|
+
setListFocus("@new");
|
|
3249
|
+
setChatNavigation(null);
|
|
3250
|
+
setNewNavigation(null);
|
|
3251
|
+
setView("new");
|
|
3252
|
+
}, onClose: adapter.onClose ? close : void 0, components, labels: copy, memoryKey, slots, headerActions: HeaderActions }) : null,
|
|
3253
|
+
view === "new" ? /* @__PURE__ */ jsx10(NewChat, { state, adapter, onBack: () => setView("list"), onClose: adapter.onClose ? close : void 0, onStarted: (mode) => setView(mode === "terminal" ? "list" : "chat"), labels: copy, memoryKey, headerActions: HeaderActions, contextCandidates, components, navigation: newNavigation, composerCommand }) : null,
|
|
3254
|
+
view === "chat" ? /* @__PURE__ */ jsx10(Chat, { state, adapter, onBack: () => {
|
|
3255
|
+
setListFocus(state.attached?.key ?? listFocus);
|
|
3256
|
+
setView("list");
|
|
3257
|
+
}, onNew: () => {
|
|
3258
|
+
setListFocus("@new");
|
|
3259
|
+
setChatNavigation(null);
|
|
3260
|
+
setNewNavigation(null);
|
|
3261
|
+
setView("new");
|
|
3262
|
+
}, onClose: adapter.onClose ? close : void 0, components, slots, labels: copy, contextCandidates, navigation: chatNavigation?.sessionKey === state.attached?.key ? chatNavigation : null, composerCommand }) : null,
|
|
3263
|
+
opening ? /* @__PURE__ */ jsxs9("div", { className: "scui-opening", role: "status", "aria-busy": "true", children: [
|
|
3264
|
+
/* @__PURE__ */ jsx10(HarnessLogo, { id: opening.harness, size: 34 }),
|
|
3265
|
+
/* @__PURE__ */ jsxs9("span", { children: [
|
|
3266
|
+
/* @__PURE__ */ jsxs9("strong", { children: [
|
|
3267
|
+
"Opening ",
|
|
3268
|
+
sessionDisplayName(opening)
|
|
3269
|
+
] }),
|
|
3270
|
+
/* @__PURE__ */ jsx10("small", { children: "Loading the latest transcript window\u2026" })
|
|
3119
3271
|
] }),
|
|
3120
|
-
/* @__PURE__ */
|
|
3121
|
-
] })
|
|
3122
|
-
|
|
3123
|
-
|
|
3124
|
-
Footer ? /* @__PURE__ */ jsx9(Footer, { state, adapter, value: copy }) : null
|
|
3272
|
+
/* @__PURE__ */ jsx10("i", {})
|
|
3273
|
+
] }) : null
|
|
3274
|
+
] }),
|
|
3275
|
+
Footer ? /* @__PURE__ */ jsx10(Footer, { state, adapter, value: copy }) : null
|
|
3125
3276
|
] });
|
|
3126
3277
|
}
|
|
3127
3278
|
|
|
3128
3279
|
// src/embed.jsx
|
|
3129
|
-
import { jsx as
|
|
3280
|
+
import { jsx as jsx11 } from "preact/jsx-runtime";
|
|
3130
3281
|
function mountSupercodeMessenger(element, options) {
|
|
3131
3282
|
if (!(element instanceof Element)) throw new TypeError("mountSupercodeMessenger requires an Element");
|
|
3132
3283
|
let state = options.state;
|
|
3133
|
-
const draw = () => render(/* @__PURE__ */
|
|
3284
|
+
const draw = () => render(/* @__PURE__ */ jsx11(SupercodeMessenger, { ...options, state }), element);
|
|
3134
3285
|
options.adapter.onIntent({ action: "mounted" });
|
|
3135
3286
|
draw();
|
|
3136
3287
|
return {
|