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