@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/components.mjs
CHANGED
|
@@ -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";
|
|
@@ -944,6 +962,12 @@ function boundedSet(map, key, value) {
|
|
|
944
962
|
// src/icon.jsx
|
|
945
963
|
import { Fragment, jsx, jsxs } from "preact/jsx-runtime";
|
|
946
964
|
var ICONS = {
|
|
965
|
+
agents: () => /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
966
|
+
/* @__PURE__ */ jsx("circle", { cx: "6", cy: "6.5", r: "2" }),
|
|
967
|
+
/* @__PURE__ */ jsx("path", { d: "M2.75 13c.45-2 1.55-3 3.25-3s2.8 1 3.25 3" }),
|
|
968
|
+
/* @__PURE__ */ jsx("circle", { cx: "12.25", cy: "7", r: "1.5" }),
|
|
969
|
+
/* @__PURE__ */ jsx("path", { d: "M10.5 10.75c1.95-.65 3.45.1 4 2.25" })
|
|
970
|
+
] }),
|
|
947
971
|
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" }),
|
|
948
972
|
back: () => /* @__PURE__ */ jsx("path", { d: "m11.5 4.5-4.5 4.5 4.5 4.5" }),
|
|
949
973
|
check: () => /* @__PURE__ */ jsx("path", { d: "m4 9 3.25 3.25L14 5.5" }),
|
|
@@ -2290,7 +2314,7 @@ function Conversation({ state, adapter, components = {}, slots = {}, memoryKey =
|
|
|
2290
2314
|
}
|
|
2291
2315
|
|
|
2292
2316
|
// src/messenger.jsx
|
|
2293
|
-
import { useEffect as
|
|
2317
|
+
import { useEffect as useEffect9, useId as useId3, useMemo as useMemo3, useRef as useRef8, useState as useState7 } from "preact/hooks";
|
|
2294
2318
|
|
|
2295
2319
|
// src/sessions.jsx
|
|
2296
2320
|
import { useEffect as useEffect6, useLayoutEffect as useLayoutEffect3, useRef as useRef5, useState as useState4 } from "preact/hooks";
|
|
@@ -2307,7 +2331,7 @@ function sessionPathParts(value) {
|
|
|
2307
2331
|
trailing: complete.slice(boundary + 1)
|
|
2308
2332
|
};
|
|
2309
2333
|
}
|
|
2310
|
-
function SessionRow({ row, state, onOpen, now = Date.now() }) {
|
|
2334
|
+
function SessionRow({ row, state, onOpen, onOpenSubagents, now = Date.now() }) {
|
|
2311
2335
|
const activity = sessionActivity(state, row);
|
|
2312
2336
|
const working = activity === "working";
|
|
2313
2337
|
const attention = state.attention.find((item) => item.key === row.key);
|
|
@@ -2317,32 +2341,40 @@ function SessionRow({ row, state, onOpen, now = Date.now() }) {
|
|
|
2317
2341
|
const unreadCount = attention?.unreadCount ?? 0;
|
|
2318
2342
|
const unreadLabel = unreadCount > 99 ? "99+" : String(unreadCount);
|
|
2319
2343
|
const age = relativeAge(row.previewUpdatedAt ?? row.updatedAt, now) || row.age;
|
|
2320
|
-
return /* @__PURE__ */ jsxs7("
|
|
2321
|
-
/* @__PURE__ */
|
|
2322
|
-
|
|
2323
|
-
/* @__PURE__ */ jsxs7("span", { className: "scui-session-
|
|
2324
|
-
/* @__PURE__ */
|
|
2325
|
-
|
|
2326
|
-
|
|
2327
|
-
|
|
2328
|
-
/* @__PURE__ */
|
|
2329
|
-
|
|
2330
|
-
|
|
2331
|
-
|
|
2332
|
-
working || preview || unreadCount ? /* @__PURE__ */ jsxs7("span", { className: "scui-session-preview", children: [
|
|
2333
|
-
working ? /* @__PURE__ */ jsxs7("span", { className: "scui-session-working", "aria-hidden": "true", children: [
|
|
2334
|
-
/* @__PURE__ */ jsx8("i", {}),
|
|
2335
|
-
/* @__PURE__ */ jsx8("i", {}),
|
|
2336
|
-
/* @__PURE__ */ jsx8("i", {})
|
|
2344
|
+
return /* @__PURE__ */ jsxs7("article", { className: "scui-session", "data-active": row.active, "data-activity": activity, "data-writable": row.writable, children: [
|
|
2345
|
+
/* @__PURE__ */ jsxs7("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: [
|
|
2346
|
+
/* @__PURE__ */ jsx8(HarnessLogo, { id: row.harness, activity, size: 34 }),
|
|
2347
|
+
/* @__PURE__ */ jsxs7("span", { className: "scui-session-copy", children: [
|
|
2348
|
+
/* @__PURE__ */ jsxs7("span", { className: "scui-session-title", children: [
|
|
2349
|
+
/* @__PURE__ */ jsx8("strong", { children: title }),
|
|
2350
|
+
/* @__PURE__ */ jsx8("span", { className: "scui-session-meta", children: age ? /* @__PURE__ */ jsx8("time", { children: age }) : null })
|
|
2351
|
+
] }),
|
|
2352
|
+
path.complete ? /* @__PURE__ */ jsxs7("small", { className: "scui-session-path", title: row.cwd, children: [
|
|
2353
|
+
/* @__PURE__ */ jsx8("span", { className: "scui-session-path-leading", children: path.leading }),
|
|
2354
|
+
path.separator ? /* @__PURE__ */ jsx8("span", { className: "scui-session-path-separator", children: path.separator }) : null,
|
|
2355
|
+
path.trailing ? /* @__PURE__ */ jsx8("span", { className: "scui-session-path-trailing", children: path.trailing }) : null
|
|
2337
2356
|
] }) : null,
|
|
2338
|
-
preview ||
|
|
2339
|
-
|
|
2340
|
-
|
|
2341
|
-
|
|
2342
|
-
|
|
2357
|
+
working || preview || unreadCount ? /* @__PURE__ */ jsxs7("span", { className: "scui-session-preview", children: [
|
|
2358
|
+
working ? /* @__PURE__ */ jsxs7("span", { className: "scui-session-working", "aria-hidden": "true", children: [
|
|
2359
|
+
/* @__PURE__ */ jsx8("i", {}),
|
|
2360
|
+
/* @__PURE__ */ jsx8("i", {}),
|
|
2361
|
+
/* @__PURE__ */ jsx8("i", {})
|
|
2362
|
+
] }) : null,
|
|
2363
|
+
preview || working ? /* @__PURE__ */ jsx8("small", { children: preview || "Working\u2026" }) : null,
|
|
2364
|
+
unreadCount ? /* @__PURE__ */ jsx8("b", { "aria-label": `${unreadCount} unread messages`, children: unreadLabel }) : null
|
|
2365
|
+
] }) : null,
|
|
2366
|
+
state.attachError?.key === row.key ? /* @__PURE__ */ jsx8("em", { children: state.attachError.message }) : null
|
|
2367
|
+
] })
|
|
2368
|
+
] }),
|
|
2369
|
+
row.subagentCount ? /* @__PURE__ */ jsxs7("button", { className: "scui-session-agents", type: "button", "aria-label": `Inspect ${row.subagentCount} subagents in ${title}`, onClick: () => onOpenSubagents?.(row), children: [
|
|
2370
|
+
/* @__PURE__ */ jsx8(UiIcon, { name: "agents", size: 14 }),
|
|
2371
|
+
row.subagentCount,
|
|
2372
|
+
" ",
|
|
2373
|
+
row.subagentCount === 1 ? "agent" : "agents"
|
|
2374
|
+
] }) : null
|
|
2343
2375
|
] });
|
|
2344
2376
|
}
|
|
2345
|
-
function SessionList({ state, adapter, onOpen, onNew, onClose, components = {}, slots = {}, labels = DEFAULT_LABELS, focusKey = null, memoryKey = state.workspace || "@default", headerActions: HeaderActions }) {
|
|
2377
|
+
function SessionList({ state, adapter, onOpen, onOpenSubagents, onNew, onClose, components = {}, slots = {}, labels = DEFAULT_LABELS, focusKey = null, memoryKey = state.workspace || "@default", headerActions: HeaderActions }) {
|
|
2346
2378
|
const remembered = sessionListMemory.get(memoryKey) ?? { query: "", top: 0 };
|
|
2347
2379
|
const [query, setQuery] = useState4(remembered.query);
|
|
2348
2380
|
const [loadingMore, setLoadingMore] = useState4(false);
|
|
@@ -2408,26 +2440,132 @@ function SessionList({ state, adapter, onOpen, onNew, onClose, components = {},
|
|
|
2408
2440
|
/* @__PURE__ */ jsxs7("div", { className: "scui-session-rows", ref: rowScroller, onScroll: (event) => boundedSet(sessionListMemory, memoryKey, { query, top: event.currentTarget.scrollTop }), children: [
|
|
2409
2441
|
BeforeSessions ? /* @__PURE__ */ jsx8(BeforeSessions, { state, adapter, value: { query, rows } }) : null,
|
|
2410
2442
|
!rows.length && state.startup === "ready" ? /* @__PURE__ */ jsx8("div", { className: "scui-empty", children: query ? "No chats match your search." : state.error ?? "No coding chats found." }) : null,
|
|
2411
|
-
rows.map((row) => /* @__PURE__ */ jsx8(Row, { value: row, row, state, adapter, onOpen, now }, row.key)),
|
|
2443
|
+
rows.map((row) => /* @__PURE__ */ jsx8(Row, { value: row, row, state, adapter, onOpen, onOpenSubagents, now }, row.key)),
|
|
2412
2444
|
state.history.hasMoreSessions ? /* @__PURE__ */ jsx8("button", { className: "scui-load", type: "button", disabled: loadingMore, onClick: loadMore, children: loadingMore ? "Loading older chats\u2026" : "Load older chats" }) : null,
|
|
2413
2445
|
AfterSessions ? /* @__PURE__ */ jsx8(AfterSessions, { state, adapter, value: { query, rows } }) : null
|
|
2414
2446
|
] })
|
|
2415
2447
|
] });
|
|
2416
2448
|
}
|
|
2417
2449
|
|
|
2418
|
-
// src/
|
|
2419
|
-
import { useEffect as useEffect7,
|
|
2450
|
+
// src/subagents.jsx
|
|
2451
|
+
import { useEffect as useEffect7, useRef as useRef6, useState as useState5 } from "preact/hooks";
|
|
2420
2452
|
import { jsx as jsx9, jsxs as jsxs8 } from "preact/jsx-runtime";
|
|
2453
|
+
var ATTENTION_ACTIVITY = /* @__PURE__ */ new Set(["needs-input", "failed", "unseen"]);
|
|
2454
|
+
var ACTIVE_ACTIVITY = /* @__PURE__ */ new Set(["working", "running", "recent"]);
|
|
2455
|
+
function activityLabel(activity, age) {
|
|
2456
|
+
if (activity === "needs-input") return "Needs input";
|
|
2457
|
+
if (activity === "failed") return "Failed";
|
|
2458
|
+
if (activity === "unseen") return "New update";
|
|
2459
|
+
if (activity === "working") return "Working";
|
|
2460
|
+
if (activity === "running") return "Running";
|
|
2461
|
+
if (activity === "recent") return "Recent";
|
|
2462
|
+
if (activity === "finished") return "Finished";
|
|
2463
|
+
return age;
|
|
2464
|
+
}
|
|
2465
|
+
function SubagentRow({ row, inspector, adapter }) {
|
|
2466
|
+
return /* @__PURE__ */ jsxs8("button", { className: "scui-subagent-row", type: "button", "data-activity": row.activity ?? "idle", onClick: () => adapter.onIntent({ action: "openSubagent", parentKey: inspector.parentKey, key: row.key }), children: [
|
|
2467
|
+
/* @__PURE__ */ jsx9(HarnessLogo, { id: row.harness, activity: row.activity, size: 30 }),
|
|
2468
|
+
/* @__PURE__ */ jsxs8("span", { children: [
|
|
2469
|
+
/* @__PURE__ */ jsx9("strong", { children: sessionDisplayName(row) }),
|
|
2470
|
+
/* @__PURE__ */ jsx9("small", { children: row.preview || (row.activity === "working" ? "Working\u2026" : row.cwd) })
|
|
2471
|
+
] }),
|
|
2472
|
+
/* @__PURE__ */ jsxs8("span", { children: [
|
|
2473
|
+
/* @__PURE__ */ jsx9("small", { children: activityLabel(row.activity, row.age) }),
|
|
2474
|
+
/* @__PURE__ */ jsx9(UiIcon, { name: "chevron", size: 14 })
|
|
2475
|
+
] })
|
|
2476
|
+
] });
|
|
2477
|
+
}
|
|
2478
|
+
function SubagentSection({ label, rows, inspector, adapter }) {
|
|
2479
|
+
if (!rows.length) return null;
|
|
2480
|
+
return /* @__PURE__ */ jsxs8("section", { className: "scui-subagent-section", "aria-labelledby": `scui-subagents-${label.toLowerCase().replaceAll(" ", "-")}`, children: [
|
|
2481
|
+
/* @__PURE__ */ jsx9("h2", { id: `scui-subagents-${label.toLowerCase().replaceAll(" ", "-")}`, children: label }),
|
|
2482
|
+
rows.map((row) => /* @__PURE__ */ jsx9(SubagentRow, { row, inspector, adapter }, row.key))
|
|
2483
|
+
] });
|
|
2484
|
+
}
|
|
2485
|
+
function SubagentInspectorContent({ state, adapter, onClose, inspector }) {
|
|
2486
|
+
const selected = inspector.items.find((row) => row.key === inspector.selectedKey) ?? null;
|
|
2487
|
+
const attention = inspector.items.filter((row) => ATTENTION_ACTIVITY.has(row.activity));
|
|
2488
|
+
const active = inspector.items.filter((row) => ACTIVE_ACTIVITY.has(row.activity));
|
|
2489
|
+
const finished = inspector.items.filter((row) => !ATTENTION_ACTIVITY.has(row.activity) && !ACTIVE_ACTIVITY.has(row.activity));
|
|
2490
|
+
const [finishedOpen, setFinishedOpen] = useState5(false);
|
|
2491
|
+
const backButton = useRef6(null);
|
|
2492
|
+
useEffect7(() => {
|
|
2493
|
+
if (inspector.status === "ready" && !attention.length && !active.length) setFinishedOpen(true);
|
|
2494
|
+
}, [inspector.parentKey, inspector.status]);
|
|
2495
|
+
useEffect7(() => {
|
|
2496
|
+
backButton.current?.focus({ preventScroll: true });
|
|
2497
|
+
}, [selected?.key]);
|
|
2498
|
+
const detailState = selected ? {
|
|
2499
|
+
...state,
|
|
2500
|
+
transcript: inspector.transcript,
|
|
2501
|
+
busy: selected.activity === "working",
|
|
2502
|
+
needsInput: selected.activity === "needs-input",
|
|
2503
|
+
harness: selected.harness,
|
|
2504
|
+
mode: "mirror",
|
|
2505
|
+
canSend: false,
|
|
2506
|
+
canSteer: false,
|
|
2507
|
+
canInterrupt: false,
|
|
2508
|
+
canRespond: false,
|
|
2509
|
+
taskPlan: { source: "none", items: [], residueCount: 0, observedAt: null },
|
|
2510
|
+
semantics: { fidelity: null, residue: [], residueCount: 0, parseErrors: 0, rawRecords: 0, subagents: [] },
|
|
2511
|
+
history: { ...state.history, hasEarlier: false }
|
|
2512
|
+
} : null;
|
|
2513
|
+
const leave = () => {
|
|
2514
|
+
adapter.onIntent({ action: "closeSubagents" });
|
|
2515
|
+
onClose();
|
|
2516
|
+
};
|
|
2517
|
+
const back = () => selected ? adapter.onIntent({ action: "openSubagents", key: inspector.parentKey }) : leave();
|
|
2518
|
+
return /* @__PURE__ */ jsxs8("section", { className: "scui-subagents", "aria-label": `Agents for ${inspector.parentTitle}`, children: [
|
|
2519
|
+
/* @__PURE__ */ jsxs8("header", { className: "scui-head", children: [
|
|
2520
|
+
/* @__PURE__ */ jsx9("button", { ref: backButton, type: "button", "aria-label": selected ? "Back to agents" : "Back to chats", onClick: back, children: /* @__PURE__ */ jsx9(UiIcon, { name: "back", size: 17 }) }),
|
|
2521
|
+
selected ? /* @__PURE__ */ jsx9(HarnessLogo, { id: selected.harness, activity: selected.activity, size: 24 }) : /* @__PURE__ */ jsx9(UiIcon, { name: "agents", size: 20 }),
|
|
2522
|
+
/* @__PURE__ */ jsxs8("span", { className: "scui-head-copy", children: [
|
|
2523
|
+
/* @__PURE__ */ jsx9("strong", { children: selected ? sessionDisplayName(selected) : `${inspector.items.length || ""} ${inspector.items.length === 1 ? "agent" : "agents"}`.trim() }),
|
|
2524
|
+
/* @__PURE__ */ jsx9("small", { children: selected ? `${harnessDisplayName(selected.harness)} \xB7 Read-only` : inspector.parentTitle })
|
|
2525
|
+
] })
|
|
2526
|
+
] }),
|
|
2527
|
+
inspector.status === "loading" ? /* @__PURE__ */ jsxs8("div", { className: "scui-subagents-loading", role: "status", children: [
|
|
2528
|
+
/* @__PURE__ */ jsx9("i", {}),
|
|
2529
|
+
/* @__PURE__ */ jsxs8("span", { children: [
|
|
2530
|
+
/* @__PURE__ */ jsx9("strong", { children: selected ? "Loading subagent" : "Finding subagents" }),
|
|
2531
|
+
/* @__PURE__ */ jsx9("small", { children: selected ? "Reading a bounded recent transcript\u2026" : "Reading native session relationships\u2026" })
|
|
2532
|
+
] })
|
|
2533
|
+
] }) : null,
|
|
2534
|
+
inspector.error ? /* @__PURE__ */ jsx9("div", { className: "scui-error", role: "alert", children: inspector.error }) : null,
|
|
2535
|
+
!selected && inspector.status === "ready" && inspector.items.length ? /* @__PURE__ */ jsxs8("div", { className: "scui-subagent-rows", children: [
|
|
2536
|
+
/* @__PURE__ */ jsx9(SubagentSection, { label: "Needs attention", rows: attention, inspector, adapter }),
|
|
2537
|
+
/* @__PURE__ */ jsx9(SubagentSection, { label: "Active", rows: active, inspector, adapter }),
|
|
2538
|
+
finished.length ? /* @__PURE__ */ jsxs8("details", { className: "scui-subagent-history", open: finishedOpen, onToggle: (event) => setFinishedOpen(event.currentTarget.open), children: [
|
|
2539
|
+
/* @__PURE__ */ jsxs8("summary", { children: [
|
|
2540
|
+
/* @__PURE__ */ jsx9("span", { children: "Finished" }),
|
|
2541
|
+
/* @__PURE__ */ jsx9("small", { children: finished.length }),
|
|
2542
|
+
/* @__PURE__ */ jsx9(UiIcon, { name: "chevron", size: 14 })
|
|
2543
|
+
] }),
|
|
2544
|
+
/* @__PURE__ */ jsx9("div", { children: finished.map((row) => /* @__PURE__ */ jsx9(SubagentRow, { row, inspector, adapter }, row.key)) })
|
|
2545
|
+
] }) : null
|
|
2546
|
+
] }) : null,
|
|
2547
|
+
!selected && inspector.status === "ready" && !inspector.items.length ? /* @__PURE__ */ jsx9("div", { className: "scui-empty", children: "No native child sessions were found." }) : null,
|
|
2548
|
+
selected && inspector.status === "ready" && detailState ? /* @__PURE__ */ jsx9(Conversation, { state: detailState, adapter, memoryKey: `subagent:${selected.key}` }) : null
|
|
2549
|
+
] });
|
|
2550
|
+
}
|
|
2551
|
+
function SubagentInspector({ state, adapter, onClose }) {
|
|
2552
|
+
if (!state.subagentInspector) return null;
|
|
2553
|
+
return /* @__PURE__ */ jsx9(SubagentInspectorContent, { state, adapter, onClose, inspector: state.subagentInspector });
|
|
2554
|
+
}
|
|
2555
|
+
|
|
2556
|
+
// src/settings.jsx
|
|
2557
|
+
import { useEffect as useEffect8, useId as useId2, useMemo as useMemo2, useRef as useRef7, useState as useState6 } from "preact/hooks";
|
|
2558
|
+
import { jsx as jsx10, jsxs as jsxs9 } from "preact/jsx-runtime";
|
|
2421
2559
|
function HarnessAdvisory({ state, onReview }) {
|
|
2422
2560
|
const advisory = state.interopSettings?.advisories[0];
|
|
2423
2561
|
if (!advisory && !state.interopSettingsError) return null;
|
|
2424
|
-
return /* @__PURE__ */
|
|
2425
|
-
/* @__PURE__ */
|
|
2426
|
-
/* @__PURE__ */
|
|
2427
|
-
/* @__PURE__ */
|
|
2428
|
-
/* @__PURE__ */
|
|
2562
|
+
return /* @__PURE__ */ jsxs9("div", { className: "scui-advisory", "data-severity": advisory?.severity ?? "error", role: advisory?.severity === "error" || !advisory ? "alert" : "status", children: [
|
|
2563
|
+
/* @__PURE__ */ jsx10("span", { "aria-hidden": "true", children: "!" }),
|
|
2564
|
+
/* @__PURE__ */ jsxs9("span", { children: [
|
|
2565
|
+
/* @__PURE__ */ jsx10("strong", { children: advisory?.title ?? "Could not inspect harness settings" }),
|
|
2566
|
+
/* @__PURE__ */ jsx10("small", { children: advisory?.message ?? state.interopSettingsError })
|
|
2429
2567
|
] }),
|
|
2430
|
-
advisory && state.canConfigureSettings ? /* @__PURE__ */
|
|
2568
|
+
advisory && state.canConfigureSettings ? /* @__PURE__ */ jsx10("button", { type: "button", onClick: () => onReview(advisory.recommendation.change), children: "Review" }) : null
|
|
2431
2569
|
] });
|
|
2432
2570
|
}
|
|
2433
2571
|
function initialValues(report, recommendedChange) {
|
|
@@ -2439,12 +2577,12 @@ function initialValues(report, recommendedChange) {
|
|
|
2439
2577
|
function HarnessSettingsPanel({ state, adapter, onClose, recommendedChange = null }) {
|
|
2440
2578
|
const report = state.interopSettings;
|
|
2441
2579
|
const titleId = useId2();
|
|
2442
|
-
const panel =
|
|
2580
|
+
const panel = useRef7(null);
|
|
2443
2581
|
const valuesKey = `${report?.revision ?? ""}:${recommendedChange?.key ?? ""}:${recommendedChange?.value ?? ""}`;
|
|
2444
2582
|
const defaults = useMemo2(() => report ? initialValues(report, recommendedChange) : {}, [valuesKey]);
|
|
2445
|
-
const [values, setValues] =
|
|
2446
|
-
|
|
2447
|
-
|
|
2583
|
+
const [values, setValues] = useState6(defaults);
|
|
2584
|
+
useEffect8(() => setValues(defaults), [defaults]);
|
|
2585
|
+
useEffect8(() => {
|
|
2448
2586
|
panel.current?.querySelector("select, button")?.focus({ preventScroll: true });
|
|
2449
2587
|
const dismiss = (event) => {
|
|
2450
2588
|
if (event.key === "Escape") {
|
|
@@ -2455,11 +2593,11 @@ function HarnessSettingsPanel({ state, adapter, onClose, recommendedChange = nul
|
|
|
2455
2593
|
document.addEventListener("keydown", dismiss);
|
|
2456
2594
|
return () => document.removeEventListener("keydown", dismiss);
|
|
2457
2595
|
}, [onClose]);
|
|
2458
|
-
if (!report) return /* @__PURE__ */
|
|
2459
|
-
/* @__PURE__ */
|
|
2460
|
-
/* @__PURE__ */
|
|
2461
|
-
/* @__PURE__ */
|
|
2462
|
-
/* @__PURE__ */
|
|
2596
|
+
if (!report) return /* @__PURE__ */ jsx10("section", { ref: panel, className: "scui-settings", role: "dialog", "aria-modal": "true", "aria-labelledby": titleId, children: /* @__PURE__ */ jsxs9("header", { children: [
|
|
2597
|
+
/* @__PURE__ */ jsx10("button", { type: "button", "aria-label": "Close settings", onClick: onClose, children: /* @__PURE__ */ jsx10(UiIcon, { name: "close", size: 18 }) }),
|
|
2598
|
+
/* @__PURE__ */ jsxs9("span", { children: [
|
|
2599
|
+
/* @__PURE__ */ jsx10("strong", { id: titleId, children: "Harness settings" }),
|
|
2600
|
+
/* @__PURE__ */ jsx10("small", { children: state.interopSettingsError ?? "No interoperability controls are available." })
|
|
2463
2601
|
] })
|
|
2464
2602
|
] }) });
|
|
2465
2603
|
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 }] : []);
|
|
@@ -2468,45 +2606,45 @@ function HarnessSettingsPanel({ state, adapter, onClose, recommendedChange = nul
|
|
|
2468
2606
|
if (!changed.length || !state.canConfigureSettings) return;
|
|
2469
2607
|
adapter.onIntent({ action: "configureHarness", harness: report.harness, changes: changed, expectedRevision: report.revision });
|
|
2470
2608
|
};
|
|
2471
|
-
return /* @__PURE__ */
|
|
2472
|
-
/* @__PURE__ */
|
|
2473
|
-
/* @__PURE__ */
|
|
2474
|
-
/* @__PURE__ */
|
|
2475
|
-
/* @__PURE__ */
|
|
2609
|
+
return /* @__PURE__ */ jsxs9("section", { ref: panel, className: "scui-settings", role: "dialog", "aria-modal": "true", "aria-labelledby": titleId, children: [
|
|
2610
|
+
/* @__PURE__ */ jsxs9("header", { children: [
|
|
2611
|
+
/* @__PURE__ */ jsx10("button", { type: "button", "aria-label": "Close settings", onClick: onClose, children: /* @__PURE__ */ jsx10(UiIcon, { name: "close", size: 18 }) }),
|
|
2612
|
+
/* @__PURE__ */ jsxs9("span", { children: [
|
|
2613
|
+
/* @__PURE__ */ jsxs9("strong", { id: titleId, children: [
|
|
2476
2614
|
harnessDisplayName(report.harness),
|
|
2477
2615
|
" interoperability"
|
|
2478
2616
|
] }),
|
|
2479
|
-
/* @__PURE__ */
|
|
2617
|
+
/* @__PURE__ */ jsx10("small", { children: "Native harness settings used by Supercode" })
|
|
2480
2618
|
] })
|
|
2481
2619
|
] }),
|
|
2482
|
-
/* @__PURE__ */
|
|
2620
|
+
/* @__PURE__ */ jsxs9("form", { onSubmit: submit, children: [
|
|
2483
2621
|
report.controls.map((control) => {
|
|
2484
2622
|
const choice = control.choices.find((item) => item.value === values[control.key]);
|
|
2485
2623
|
const recommendation = report.advisories.map((advisory) => advisory.recommendation).find((item) => item.change.key === control.key && item.change.value === values[control.key]);
|
|
2486
2624
|
const consequence = choice?.risk ?? recommendation?.consequence;
|
|
2487
|
-
return /* @__PURE__ */
|
|
2488
|
-
/* @__PURE__ */
|
|
2489
|
-
/* @__PURE__ */
|
|
2490
|
-
/* @__PURE__ */
|
|
2625
|
+
return /* @__PURE__ */ jsxs9("fieldset", { disabled: !control.writable || Boolean(state.operation), children: [
|
|
2626
|
+
/* @__PURE__ */ jsxs9("label", { htmlFor: `scui-setting-${control.key}`, children: [
|
|
2627
|
+
/* @__PURE__ */ jsx10("strong", { children: control.label }),
|
|
2628
|
+
/* @__PURE__ */ jsx10("small", { children: control.description })
|
|
2491
2629
|
] }),
|
|
2492
|
-
/* @__PURE__ */
|
|
2493
|
-
control.resettable ? /* @__PURE__ */
|
|
2494
|
-
control.choices.map((item) => /* @__PURE__ */
|
|
2630
|
+
/* @__PURE__ */ jsxs9("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: [
|
|
2631
|
+
control.resettable ? /* @__PURE__ */ jsx10("option", { value: "@default", children: "Use harness default" }) : null,
|
|
2632
|
+
control.choices.map((item) => /* @__PURE__ */ jsx10("option", { value: item.value, children: item.label }, item.value))
|
|
2495
2633
|
] }),
|
|
2496
|
-
choice ? /* @__PURE__ */
|
|
2497
|
-
consequence ? /* @__PURE__ */
|
|
2498
|
-
/* @__PURE__ */
|
|
2634
|
+
choice ? /* @__PURE__ */ jsx10("p", { children: choice.description }) : null,
|
|
2635
|
+
consequence ? /* @__PURE__ */ jsxs9("p", { className: "scui-setting-risk", children: [
|
|
2636
|
+
/* @__PURE__ */ jsx10("strong", { children: "Security consequence" }),
|
|
2499
2637
|
consequence
|
|
2500
2638
|
] }) : null,
|
|
2501
|
-
/* @__PURE__ */
|
|
2639
|
+
/* @__PURE__ */ jsxs9("small", { className: "scui-setting-source", children: [
|
|
2502
2640
|
control.effectiveNote,
|
|
2503
2641
|
control.sourcePath ? ` Source: ${control.sourcePath}` : ""
|
|
2504
2642
|
] })
|
|
2505
2643
|
] }, control.key);
|
|
2506
2644
|
}),
|
|
2507
|
-
/* @__PURE__ */
|
|
2508
|
-
/* @__PURE__ */
|
|
2509
|
-
/* @__PURE__ */
|
|
2645
|
+
/* @__PURE__ */ jsxs9("footer", { children: [
|
|
2646
|
+
/* @__PURE__ */ jsx10("button", { type: "button", onClick: onClose, children: "Cancel" }),
|
|
2647
|
+
/* @__PURE__ */ jsx10("button", { type: "submit", disabled: !changed.length || !state.canConfigureSettings || Boolean(state.operation), children: state.operation === "configureHarness" ? "Applying\u2026" : "Apply changes" })
|
|
2510
2648
|
] })
|
|
2511
2649
|
] })
|
|
2512
2650
|
] });
|
|
@@ -2514,29 +2652,29 @@ function HarnessSettingsPanel({ state, adapter, onClose, recommendedChange = nul
|
|
|
2514
2652
|
function HarnessReadiness({ harnesses, adapter }) {
|
|
2515
2653
|
const blocked = harnesses.filter((item) => !item.startable);
|
|
2516
2654
|
if (!blocked.length || harnesses.some((item) => item.startable)) return null;
|
|
2517
|
-
return /* @__PURE__ */
|
|
2518
|
-
/* @__PURE__ */
|
|
2519
|
-
/* @__PURE__ */
|
|
2520
|
-
/* @__PURE__ */
|
|
2521
|
-
/* @__PURE__ */
|
|
2522
|
-
/* @__PURE__ */
|
|
2523
|
-
/* @__PURE__ */
|
|
2524
|
-
item.protocol ? /* @__PURE__ */
|
|
2655
|
+
return /* @__PURE__ */ jsxs9("details", { className: "scui-readiness", open: true, children: [
|
|
2656
|
+
/* @__PURE__ */ jsx10("summary", { children: "No coding harness is ready" }),
|
|
2657
|
+
/* @__PURE__ */ jsx10("div", { children: blocked.map((item) => /* @__PURE__ */ jsxs9("section", { children: [
|
|
2658
|
+
/* @__PURE__ */ jsx10(HarnessLogo, { id: item.id, size: 25 }),
|
|
2659
|
+
/* @__PURE__ */ jsxs9("span", { children: [
|
|
2660
|
+
/* @__PURE__ */ jsx10("strong", { children: item.label }),
|
|
2661
|
+
/* @__PURE__ */ jsx10("small", { children: item.reason || (item.auth === "required" ? "Authentication required" : "Unavailable") }),
|
|
2662
|
+
item.protocol ? /* @__PURE__ */ jsxs9("em", { children: [
|
|
2525
2663
|
item.protocol,
|
|
2526
2664
|
" \xB7 ",
|
|
2527
2665
|
item.runtime
|
|
2528
2666
|
] }) : null
|
|
2529
2667
|
] }),
|
|
2530
|
-
item.repair ? /* @__PURE__ */
|
|
2668
|
+
item.repair ? /* @__PURE__ */ jsx10("button", { type: "button", onClick: () => adapter.copyText?.(item.repair), children: "Copy fix" }) : null
|
|
2531
2669
|
] }, item.id)) })
|
|
2532
2670
|
] });
|
|
2533
2671
|
}
|
|
2534
2672
|
function HarnessPicker({ harnesses, value, disabled = false, adapter, onChange, logo: Logo = HarnessLogo }) {
|
|
2535
|
-
const [open, setOpen] =
|
|
2673
|
+
const [open, setOpen] = useState6(false);
|
|
2536
2674
|
const menuId = useId2();
|
|
2537
|
-
const root =
|
|
2538
|
-
const trigger =
|
|
2539
|
-
const panel =
|
|
2675
|
+
const root = useRef7(null);
|
|
2676
|
+
const trigger = useRef7(null);
|
|
2677
|
+
const panel = useRef7(null);
|
|
2540
2678
|
const available = harnesses.filter((item) => item.startable);
|
|
2541
2679
|
const unavailable = harnesses.filter((item) => !item.startable);
|
|
2542
2680
|
const selected = available.find((item) => item.id === value) ?? available[0] ?? null;
|
|
@@ -2544,7 +2682,7 @@ function HarnessPicker({ harnesses, value, disabled = false, adapter, onChange,
|
|
|
2544
2682
|
setOpen(false);
|
|
2545
2683
|
trigger.current?.focus({ preventScroll: true });
|
|
2546
2684
|
};
|
|
2547
|
-
|
|
2685
|
+
useEffect8(() => {
|
|
2548
2686
|
if (!open) return;
|
|
2549
2687
|
panel.current?.querySelector('[aria-selected="true"], [role="option"]')?.focus({ preventScroll: true });
|
|
2550
2688
|
const dismiss = (event) => {
|
|
@@ -2575,30 +2713,30 @@ function HarnessPicker({ harnesses, value, disabled = false, adapter, onChange,
|
|
|
2575
2713
|
onChange(id);
|
|
2576
2714
|
close();
|
|
2577
2715
|
};
|
|
2578
|
-
return /* @__PURE__ */
|
|
2716
|
+
return /* @__PURE__ */ jsxs9("div", { className: "scui-harness-menu", ref: root, onBlur: (event) => {
|
|
2579
2717
|
if (event.relatedTarget && !event.currentTarget.contains(event.relatedTarget)) setOpen(false);
|
|
2580
2718
|
}, children: [
|
|
2581
|
-
/* @__PURE__ */
|
|
2582
|
-
selected ? /* @__PURE__ */
|
|
2583
|
-
/* @__PURE__ */
|
|
2584
|
-
/* @__PURE__ */
|
|
2719
|
+
/* @__PURE__ */ jsxs9("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: [
|
|
2720
|
+
selected ? /* @__PURE__ */ jsx10(Logo, { id: selected.id, size: 20 }) : null,
|
|
2721
|
+
/* @__PURE__ */ jsx10("strong", { children: selected?.label ?? "No harness available" }),
|
|
2722
|
+
/* @__PURE__ */ jsx10(UiIcon, { name: "chevron", size: 13 })
|
|
2585
2723
|
] }),
|
|
2586
|
-
open ? /* @__PURE__ */
|
|
2587
|
-
/* @__PURE__ */
|
|
2588
|
-
/* @__PURE__ */
|
|
2589
|
-
/* @__PURE__ */
|
|
2590
|
-
/* @__PURE__ */
|
|
2591
|
-
/* @__PURE__ */
|
|
2724
|
+
open ? /* @__PURE__ */ jsxs9("div", { ref: panel, id: menuId, className: "scui-harness-popover", role: "dialog", "aria-label": "Choose coding harness", onKeyDown: navigate, children: [
|
|
2725
|
+
/* @__PURE__ */ jsx10("strong", { className: "scui-harness-popover-title", children: "Choose coding harness" }),
|
|
2726
|
+
/* @__PURE__ */ jsx10("div", { className: "scui-harness-options", role: "listbox", "aria-label": "Available coding harnesses", children: available.map((item) => /* @__PURE__ */ jsxs9("button", { type: "button", role: "option", "aria-selected": item.id === selected?.id, onClick: () => select(item.id), children: [
|
|
2727
|
+
/* @__PURE__ */ jsx10(Logo, { id: item.id, size: 24 }),
|
|
2728
|
+
/* @__PURE__ */ jsx10("strong", { children: item.label }),
|
|
2729
|
+
/* @__PURE__ */ jsx10("span", { children: item.id === selected?.id ? /* @__PURE__ */ jsx10(UiIcon, { name: "check", size: 15 }) : null })
|
|
2592
2730
|
] }, item.id)) }),
|
|
2593
|
-
unavailable.length ? /* @__PURE__ */
|
|
2594
|
-
/* @__PURE__ */
|
|
2595
|
-
/* @__PURE__ */
|
|
2596
|
-
/* @__PURE__ */
|
|
2597
|
-
/* @__PURE__ */
|
|
2598
|
-
/* @__PURE__ */
|
|
2599
|
-
/* @__PURE__ */
|
|
2731
|
+
unavailable.length ? /* @__PURE__ */ jsxs9("details", { className: "scui-harness-manage", children: [
|
|
2732
|
+
/* @__PURE__ */ jsx10("summary", { children: "Manage additional harnesses" }),
|
|
2733
|
+
/* @__PURE__ */ jsx10("div", { children: unavailable.map((item) => /* @__PURE__ */ jsxs9("section", { children: [
|
|
2734
|
+
/* @__PURE__ */ jsx10(Logo, { id: item.id, size: 24 }),
|
|
2735
|
+
/* @__PURE__ */ jsxs9("span", { children: [
|
|
2736
|
+
/* @__PURE__ */ jsx10("strong", { children: item.label }),
|
|
2737
|
+
/* @__PURE__ */ jsx10("small", { children: item.reason || (item.auth === "required" ? "Authentication required" : "Unavailable") })
|
|
2600
2738
|
] }),
|
|
2601
|
-
item.repair ? /* @__PURE__ */
|
|
2739
|
+
item.repair ? /* @__PURE__ */ jsx10("button", { type: "button", onClick: () => adapter?.copyText?.(item.repair), children: "Copy fix" }) : null
|
|
2602
2740
|
] }, item.id)) })
|
|
2603
2741
|
] }) : null
|
|
2604
2742
|
] }) : null
|
|
@@ -2606,16 +2744,16 @@ function HarnessPicker({ harnesses, value, disabled = false, adapter, onChange,
|
|
|
2606
2744
|
}
|
|
2607
2745
|
|
|
2608
2746
|
// src/messenger.jsx
|
|
2609
|
-
import { jsx as
|
|
2747
|
+
import { Fragment as Fragment5, jsx as jsx11, jsxs as jsxs10 } from "preact/jsx-runtime";
|
|
2610
2748
|
var pendingMessageMemory = /* @__PURE__ */ new Map();
|
|
2611
2749
|
var messengerViewMemory = /* @__PURE__ */ new Map();
|
|
2612
2750
|
var newChatMemory = /* @__PURE__ */ new Map();
|
|
2613
2751
|
var TRACKED_ACTIONS = /* @__PURE__ */ new Set(["resume", "join", "detach", "branch", "reduce", "terminal", "export", "steer", "interrupt", "respond", "configureHarness", "refresh", "loadEarlier", "loadSessions"]);
|
|
2614
2752
|
function Receipt({ state, adapter }) {
|
|
2615
2753
|
const receipt = state.reductionReceipt;
|
|
2616
|
-
if (receipt) return /* @__PURE__ */
|
|
2617
|
-
/* @__PURE__ */
|
|
2618
|
-
/* @__PURE__ */
|
|
2754
|
+
if (receipt) return /* @__PURE__ */ jsx11("div", { className: "scui-receipt", children: /* @__PURE__ */ jsxs10("span", { children: [
|
|
2755
|
+
/* @__PURE__ */ jsx11("strong", { children: "Reduced and verified" }),
|
|
2756
|
+
/* @__PURE__ */ jsxs10("small", { children: [
|
|
2619
2757
|
receipt.sourceTokens.toLocaleString(),
|
|
2620
2758
|
" \u2192 ",
|
|
2621
2759
|
receipt.reducedTokens.toLocaleString(),
|
|
@@ -2624,35 +2762,35 @@ function Receipt({ state, adapter }) {
|
|
|
2624
2762
|
"\xD7 \xB7 reversible"
|
|
2625
2763
|
] })
|
|
2626
2764
|
] }) });
|
|
2627
|
-
if (state.exportReceipt) return /* @__PURE__ */
|
|
2628
|
-
/* @__PURE__ */
|
|
2629
|
-
/* @__PURE__ */
|
|
2765
|
+
if (state.exportReceipt) return /* @__PURE__ */ jsxs10("div", { className: "scui-receipt", children: [
|
|
2766
|
+
/* @__PURE__ */ jsxs10("span", { children: [
|
|
2767
|
+
/* @__PURE__ */ jsxs10("strong", { children: [
|
|
2630
2768
|
"Lossless export ready \xB7 ",
|
|
2631
2769
|
harnessDisplayName(state.exportReceipt.targetHarness)
|
|
2632
2770
|
] }),
|
|
2633
|
-
/* @__PURE__ */
|
|
2771
|
+
/* @__PURE__ */ jsxs10("small", { children: [
|
|
2634
2772
|
state.exportReceipt.path,
|
|
2635
2773
|
" \xB7 ",
|
|
2636
2774
|
state.exportReceipt.files,
|
|
2637
2775
|
" files"
|
|
2638
2776
|
] })
|
|
2639
2777
|
] }),
|
|
2640
|
-
/* @__PURE__ */
|
|
2778
|
+
/* @__PURE__ */ jsx11("button", { type: "button", onClick: () => adapter.copyText?.(state.exportReceipt.path), children: "Copy path" })
|
|
2641
2779
|
] });
|
|
2642
|
-
if (state.terminalHandoff) return /* @__PURE__ */
|
|
2643
|
-
/* @__PURE__ */
|
|
2644
|
-
/* @__PURE__ */
|
|
2645
|
-
/* @__PURE__ */
|
|
2780
|
+
if (state.terminalHandoff) return /* @__PURE__ */ jsxs10("div", { className: "scui-receipt", children: [
|
|
2781
|
+
/* @__PURE__ */ jsxs10("span", { children: [
|
|
2782
|
+
/* @__PURE__ */ jsx11("strong", { children: "Terminal handoff ready" }),
|
|
2783
|
+
/* @__PURE__ */ jsx11("small", { children: state.terminalHandoff.cwd })
|
|
2646
2784
|
] }),
|
|
2647
|
-
/* @__PURE__ */
|
|
2785
|
+
/* @__PURE__ */ jsx11("button", { type: "button", onClick: () => adapter.copyText?.(terminalCommand(state.terminalHandoff)), children: "Copy command" })
|
|
2648
2786
|
] });
|
|
2649
2787
|
return null;
|
|
2650
2788
|
}
|
|
2651
2789
|
function ConversationActions({ state, adapter, actionPending, onNew, onSettings }) {
|
|
2652
|
-
const [open, setOpen] =
|
|
2653
|
-
const root =
|
|
2654
|
-
const panel =
|
|
2655
|
-
const trigger =
|
|
2790
|
+
const [open, setOpen] = useState7(false);
|
|
2791
|
+
const root = useRef8(null);
|
|
2792
|
+
const panel = useRef8(null);
|
|
2793
|
+
const trigger = useRef8(null);
|
|
2656
2794
|
const menuId = useId3();
|
|
2657
2795
|
const targets = state.harnesses.filter((item) => item.startable);
|
|
2658
2796
|
const groups = [
|
|
@@ -2676,7 +2814,7 @@ function ConversationActions({ state, adapter, actionPending, onNew, onSettings
|
|
|
2676
2814
|
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 } })) : []
|
|
2677
2815
|
}
|
|
2678
2816
|
].filter((group) => group.items.length);
|
|
2679
|
-
|
|
2817
|
+
useEffect9(() => {
|
|
2680
2818
|
if (!open) return;
|
|
2681
2819
|
panel.current?.querySelector("button:not(:disabled)")?.focus({ preventScroll: true });
|
|
2682
2820
|
const dismiss = (event) => {
|
|
@@ -2716,64 +2854,64 @@ function ConversationActions({ state, adapter, actionPending, onNew, onSettings
|
|
|
2716
2854
|
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;
|
|
2717
2855
|
items[index].focus({ preventScroll: true });
|
|
2718
2856
|
};
|
|
2719
|
-
return /* @__PURE__ */
|
|
2857
|
+
return /* @__PURE__ */ jsxs10("div", { className: "scui-menu", ref: root, onBlur: (event) => {
|
|
2720
2858
|
if (event.relatedTarget && !event.currentTarget.contains(event.relatedTarget)) setOpen(false);
|
|
2721
2859
|
}, children: [
|
|
2722
|
-
/* @__PURE__ */
|
|
2723
|
-
open ? /* @__PURE__ */
|
|
2724
|
-
/* @__PURE__ */
|
|
2725
|
-
group.items.map((item) => /* @__PURE__ */
|
|
2860
|
+
/* @__PURE__ */ jsx11("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__ */ jsx11(UiIcon, { name: "menu", size: 18 }) }),
|
|
2861
|
+
open ? /* @__PURE__ */ jsx11("div", { ref: panel, id: menuId, className: "scui-menu-panel", role: "menu", "aria-label": "Conversation actions", onKeyDown: navigate, children: groups.map((group) => /* @__PURE__ */ jsxs10("section", { role: "group", "aria-label": group.label, children: [
|
|
2862
|
+
/* @__PURE__ */ jsx11("strong", { children: group.label }),
|
|
2863
|
+
group.items.map((item) => /* @__PURE__ */ jsx11("button", { role: "menuitem", type: "button", disabled: actionPending, onClick: () => dispatch(item), children: item.label }, item.key))
|
|
2726
2864
|
] }, group.label)) }) : null
|
|
2727
2865
|
] });
|
|
2728
2866
|
}
|
|
2729
2867
|
function ChatHeader({ state, adapter, pendingStatus, actionPending, onBack, onNew, onClose, onSettings, headerActions: HeaderActions }) {
|
|
2730
|
-
const back =
|
|
2868
|
+
const back = useRef8(null);
|
|
2731
2869
|
const harness = state.attached?.harness ?? state.harness;
|
|
2732
2870
|
const title = state.attached ? sessionDisplayName(state.attached) : harnessDisplayName(harness) || "Agent chat";
|
|
2733
2871
|
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";
|
|
2734
|
-
|
|
2872
|
+
useEffect9(() => {
|
|
2735
2873
|
if (state.mode === "mirror" && !state.canSend) back.current?.focus({ preventScroll: true });
|
|
2736
2874
|
}, []);
|
|
2737
|
-
return /* @__PURE__ */
|
|
2738
|
-
/* @__PURE__ */
|
|
2739
|
-
/* @__PURE__ */
|
|
2740
|
-
/* @__PURE__ */
|
|
2741
|
-
/* @__PURE__ */
|
|
2742
|
-
/* @__PURE__ */
|
|
2875
|
+
return /* @__PURE__ */ jsxs10("header", { className: "scui-head scui-chat-head", children: [
|
|
2876
|
+
/* @__PURE__ */ jsx11("button", { ref: back, type: "button", "aria-label": "Back to chats", onClick: onBack, children: /* @__PURE__ */ jsx11(UiIcon, { name: "back", size: 17 }) }),
|
|
2877
|
+
/* @__PURE__ */ jsx11(HarnessLogo, { id: harness, size: 24 }),
|
|
2878
|
+
/* @__PURE__ */ jsxs10("span", { className: "scui-head-copy", children: [
|
|
2879
|
+
/* @__PURE__ */ jsx11("strong", { children: title }),
|
|
2880
|
+
/* @__PURE__ */ jsxs10("small", { children: [
|
|
2743
2881
|
harnessDisplayName(harness),
|
|
2744
2882
|
" \xB7 ",
|
|
2745
2883
|
status
|
|
2746
2884
|
] })
|
|
2747
2885
|
] }),
|
|
2748
|
-
HeaderActions ? /* @__PURE__ */
|
|
2749
|
-
/* @__PURE__ */
|
|
2750
|
-
onClose ? /* @__PURE__ */
|
|
2886
|
+
HeaderActions ? /* @__PURE__ */ jsx11(HeaderActions, { state, adapter, value: "chat" }) : null,
|
|
2887
|
+
/* @__PURE__ */ jsx11(ConversationActions, { state, adapter, actionPending, onNew, onSettings }),
|
|
2888
|
+
onClose ? /* @__PURE__ */ jsx11("button", { type: "button", "aria-label": "Close", onClick: onClose, children: /* @__PURE__ */ jsx11(UiIcon, { name: "close", size: 18 }) }) : null
|
|
2751
2889
|
] });
|
|
2752
2890
|
}
|
|
2753
2891
|
function Chat({ state, adapter, onBack, onNew, onClose, components, slots, labels, contextCandidates, navigation, composerCommand }) {
|
|
2754
2892
|
const Header = slots.header;
|
|
2755
2893
|
const HeaderActions = slots.headerActions;
|
|
2756
2894
|
const memoryKey = state.attached?.key || `${state.harness}:${state.workspace}`;
|
|
2757
|
-
const [pending, setPendingState] =
|
|
2758
|
-
const [pendingAction, setPendingAction] =
|
|
2759
|
-
const [restoreDraft, setRestoreDraft] =
|
|
2760
|
-
const [settings, setSettings] =
|
|
2761
|
-
const restoreSequence =
|
|
2762
|
-
const actionSequence =
|
|
2763
|
-
const lastNavigation =
|
|
2764
|
-
const acknowledged =
|
|
2895
|
+
const [pending, setPendingState] = useState7(() => pendingMessageMemory.get(memoryKey) ?? null);
|
|
2896
|
+
const [pendingAction, setPendingAction] = useState7(null);
|
|
2897
|
+
const [restoreDraft, setRestoreDraft] = useState7(null);
|
|
2898
|
+
const [settings, setSettings] = useState7(null);
|
|
2899
|
+
const restoreSequence = useRef8(0);
|
|
2900
|
+
const actionSequence = useRef8(0);
|
|
2901
|
+
const lastNavigation = useRef8(null);
|
|
2902
|
+
const acknowledged = useRef8(/* @__PURE__ */ new Set());
|
|
2765
2903
|
const setPending = (update) => setPendingState((current) => {
|
|
2766
2904
|
const next = typeof update === "function" ? update(current) : update;
|
|
2767
2905
|
if (next) boundedSet(pendingMessageMemory, memoryKey, next);
|
|
2768
2906
|
else pendingMessageMemory.delete(memoryKey);
|
|
2769
2907
|
return next;
|
|
2770
2908
|
});
|
|
2771
|
-
|
|
2909
|
+
useEffect9(() => {
|
|
2772
2910
|
setPendingState(pendingMessageMemory.get(memoryKey) ?? null);
|
|
2773
2911
|
setPendingAction(null);
|
|
2774
2912
|
setRestoreDraft(null);
|
|
2775
2913
|
}, [memoryKey]);
|
|
2776
|
-
|
|
2914
|
+
useEffect9(() => {
|
|
2777
2915
|
if (!navigation || navigation.id === lastNavigation.current) return;
|
|
2778
2916
|
lastNavigation.current = navigation.id;
|
|
2779
2917
|
if (navigation.draft === void 0 && !navigation.context?.length && !navigation.images?.length) return;
|
|
@@ -2784,7 +2922,7 @@ function Chat({ state, adapter, onBack, onNew, onClose, components, slots, label
|
|
|
2784
2922
|
images: navigation.images
|
|
2785
2923
|
});
|
|
2786
2924
|
}, [navigation]);
|
|
2787
|
-
|
|
2925
|
+
useEffect9(() => {
|
|
2788
2926
|
if (!pending) return;
|
|
2789
2927
|
if (state.transcript.some((entry) => entry.role === "user" && entry.text.trim() === pending.text.trim() && !pending.baselineIds.includes(entry.id))) {
|
|
2790
2928
|
setPending(null);
|
|
@@ -2813,7 +2951,7 @@ function Chat({ state, adapter, onBack, onNew, onClose, components, slots, label
|
|
|
2813
2951
|
setRestoreDraft({ id: restoreSequence.current, text: pending.text, context: pending.context, images: pending.images });
|
|
2814
2952
|
setPending({ ...pending, status: "editing" });
|
|
2815
2953
|
};
|
|
2816
|
-
|
|
2954
|
+
useEffect9(() => {
|
|
2817
2955
|
const key = state.attached?.key;
|
|
2818
2956
|
if (!key || !state.attention.some((item) => item.key === key)) {
|
|
2819
2957
|
if (key) acknowledged.current.delete(key);
|
|
@@ -2848,7 +2986,7 @@ function Chat({ state, adapter, onBack, onNew, onClose, components, slots, label
|
|
|
2848
2986
|
return result;
|
|
2849
2987
|
}
|
|
2850
2988
|
}), [adapter, state.error]);
|
|
2851
|
-
|
|
2989
|
+
useEffect9(() => {
|
|
2852
2990
|
if (!pendingAction) return;
|
|
2853
2991
|
if (state.operation && !pendingAction.seenOperation) {
|
|
2854
2992
|
setPendingAction({ ...pendingAction, seenOperation: true });
|
|
@@ -2863,40 +3001,40 @@ function Chat({ state, adapter, onBack, onNew, onClose, components, slots, label
|
|
|
2863
3001
|
const unreadAfterMessages = state.attention.find((item) => item.key === state.attached?.key)?.afterMessages ?? null;
|
|
2864
3002
|
const Advisory = components.HarnessAdvisory ?? HarnessAdvisory;
|
|
2865
3003
|
const SettingsPanel = components.HarnessSettingsPanel ?? HarnessSettingsPanel;
|
|
2866
|
-
return /* @__PURE__ */
|
|
2867
|
-
Header ? /* @__PURE__ */
|
|
2868
|
-
actionLabel ? /* @__PURE__ */
|
|
2869
|
-
/* @__PURE__ */
|
|
3004
|
+
return /* @__PURE__ */ jsxs10("section", { className: "scui-chat", children: [
|
|
3005
|
+
Header ? /* @__PURE__ */ jsx11(Header, { state: actionState, adapter: trackedAdapter, value: null }) : /* @__PURE__ */ jsx11(ChatHeader, { state: actionState, adapter: trackedAdapter, pendingStatus: pending?.status ?? null, actionPending: Boolean(action), onBack, onNew, onClose, onSettings: () => setSettings({ recommendedChange: null }), headerActions: HeaderActions }),
|
|
3006
|
+
actionLabel ? /* @__PURE__ */ jsxs10("div", { className: "scui-operation", role: "status", children: [
|
|
3007
|
+
/* @__PURE__ */ jsx11("i", {}),
|
|
2870
3008
|
actionLabel
|
|
2871
3009
|
] }) : null,
|
|
2872
|
-
state.error ? /* @__PURE__ */
|
|
2873
|
-
/* @__PURE__ */
|
|
2874
|
-
state.recoverable ? /* @__PURE__ */
|
|
3010
|
+
state.error ? /* @__PURE__ */ jsxs10("div", { className: "scui-error", role: "alert", children: [
|
|
3011
|
+
/* @__PURE__ */ jsx11("span", { children: state.error }),
|
|
3012
|
+
state.recoverable ? /* @__PURE__ */ jsx11("button", { type: "button", disabled: Boolean(action), onClick: () => trackedAdapter.onIntent({ action: "refresh" }), children: "Retry" }) : null
|
|
2875
3013
|
] }) : null,
|
|
2876
|
-
/* @__PURE__ */
|
|
2877
|
-
/* @__PURE__ */
|
|
2878
|
-
/* @__PURE__ */
|
|
2879
|
-
/* @__PURE__ */
|
|
2880
|
-
state.mode !== "mirror" || state.canSend ? /* @__PURE__ */
|
|
2881
|
-
settings ? /* @__PURE__ */
|
|
3014
|
+
/* @__PURE__ */ jsx11(Receipt, { state, adapter }),
|
|
3015
|
+
/* @__PURE__ */ jsx11(Conversation, { state: actionState, adapter: trackedAdapter, components, slots, memoryKey, pending: pendingMessage, unreadAfterMessages }, memoryKey),
|
|
3016
|
+
/* @__PURE__ */ jsx11(ContinuationBar, { state: actionState, adapter: trackedAdapter, labels }),
|
|
3017
|
+
/* @__PURE__ */ jsx11(Advisory, { state: actionState, adapter: trackedAdapter, value: state.interopSettings?.advisories[0] ?? null, onReview: (recommendedChange) => setSettings({ recommendedChange }) }),
|
|
3018
|
+
state.mode !== "mirror" || state.canSend ? /* @__PURE__ */ jsx11(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,
|
|
3019
|
+
settings ? /* @__PURE__ */ jsx11(SettingsPanel, { state: actionState, adapter: trackedAdapter, value: state.interopSettings, recommendedChange: settings.recommendedChange, onClose: () => setSettings(null) }) : null
|
|
2882
3020
|
] });
|
|
2883
3021
|
}
|
|
2884
3022
|
function NewChat({ state, adapter, onBack, onClose, onStarted, labels, memoryKey, headerActions: HeaderActions, contextCandidates, components, navigation, composerCommand }) {
|
|
2885
3023
|
const startable = state.harnesses.filter((item) => item.startable);
|
|
2886
3024
|
const startableKey = startable.map((item) => `${item.id}:${item.launchModes?.join(",")}:${item.preferredLaunchMode ?? ""}`).join("\0");
|
|
2887
3025
|
const remembered = newChatMemory.get(memoryKey) ?? { harness: startable[0]?.id ?? "", draft: "", context: [], images: [], modes: {} };
|
|
2888
|
-
const [harness, setHarness] =
|
|
2889
|
-
const [draft, setDraft] =
|
|
2890
|
-
const [context, setContext] =
|
|
2891
|
-
const [images, setImages] =
|
|
2892
|
-
const [modes, setModes] =
|
|
2893
|
-
const [starting, setStarting] =
|
|
2894
|
-
const [picking, setPicking] =
|
|
2895
|
-
const [dragging, setDragging] =
|
|
2896
|
-
const [pickerError, setPickerError] =
|
|
2897
|
-
const startSequence =
|
|
2898
|
-
const lastComposerCommand =
|
|
2899
|
-
const textarea =
|
|
3026
|
+
const [harness, setHarness] = useState7(remembered.harness);
|
|
3027
|
+
const [draft, setDraft] = useState7(remembered.draft);
|
|
3028
|
+
const [context, setContext] = useState7(remembered.context);
|
|
3029
|
+
const [images, setImages] = useState7(remembered.images ?? []);
|
|
3030
|
+
const [modes, setModes] = useState7(remembered.modes ?? {});
|
|
3031
|
+
const [starting, setStarting] = useState7(null);
|
|
3032
|
+
const [picking, setPicking] = useState7(false);
|
|
3033
|
+
const [dragging, setDragging] = useState7(false);
|
|
3034
|
+
const [pickerError, setPickerError] = useState7(null);
|
|
3035
|
+
const startSequence = useRef8(0);
|
|
3036
|
+
const lastComposerCommand = useRef8(null);
|
|
3037
|
+
const textarea = useRef8(null);
|
|
2900
3038
|
const selectedHarness = startable.find((item) => item.id === harness) ?? null;
|
|
2901
3039
|
const Picker = components.HarnessPicker ?? HarnessPicker;
|
|
2902
3040
|
const Readiness = components.HarnessReadiness ?? HarnessReadiness;
|
|
@@ -2907,13 +3045,13 @@ function NewChat({ state, adapter, onBack, onClose, onStarted, labels, memoryKey
|
|
|
2907
3045
|
const terminalAttachments = mode === "terminal" && (context.length > 0 || images.length > 0);
|
|
2908
3046
|
const remember = (overrides = {}) => boundedSet(newChatMemory, memoryKey, { harness, draft, context, images, modes, ...overrides });
|
|
2909
3047
|
useAutosizeTextarea(textarea, draft);
|
|
2910
|
-
|
|
3048
|
+
useEffect9(() => {
|
|
2911
3049
|
if (startable.some((item) => item.id === harness)) return;
|
|
2912
3050
|
const next = startable[0]?.id ?? "";
|
|
2913
3051
|
setHarness(next);
|
|
2914
3052
|
remember({ harness: next });
|
|
2915
3053
|
}, [harness, startableKey]);
|
|
2916
|
-
|
|
3054
|
+
useEffect9(() => {
|
|
2917
3055
|
if (!starting || starting.mode === "terminal") return;
|
|
2918
3056
|
const sessionChanged = (state.attached?.key ?? null) !== starting.attachedKey;
|
|
2919
3057
|
const beganWorking = !starting.busy && state.busy;
|
|
@@ -2921,13 +3059,13 @@ function NewChat({ state, adapter, onBack, onClose, onStarted, labels, memoryKey
|
|
|
2921
3059
|
newChatMemory.delete(memoryKey);
|
|
2922
3060
|
onStarted("headless");
|
|
2923
3061
|
}, [memoryKey, onStarted, starting, state.attached?.key, state.busy]);
|
|
2924
|
-
|
|
3062
|
+
useEffect9(() => {
|
|
2925
3063
|
if (starting && state.error !== starting.initialError && !state.busy && !state.operation) setStarting(null);
|
|
2926
3064
|
}, [starting, state.busy, state.error, state.operation]);
|
|
2927
|
-
|
|
3065
|
+
useEffect9(() => {
|
|
2928
3066
|
textarea.current?.focus({ preventScroll: true });
|
|
2929
3067
|
}, []);
|
|
2930
|
-
|
|
3068
|
+
useEffect9(() => {
|
|
2931
3069
|
if (!navigation) return;
|
|
2932
3070
|
const nextHarness = startable.some((item) => item.id === navigation.harness) ? navigation.harness : harness;
|
|
2933
3071
|
const nextDraft = typeof navigation.draft === "string" ? navigation.draft : draft;
|
|
@@ -2940,7 +3078,7 @@ function NewChat({ state, adapter, onBack, onClose, onStarted, labels, memoryKey
|
|
|
2940
3078
|
remember({ harness: nextHarness, draft: nextDraft, context: nextContext, images: nextImages });
|
|
2941
3079
|
textarea.current?.focus({ preventScroll: true });
|
|
2942
3080
|
}, [navigation?.id]);
|
|
2943
|
-
|
|
3081
|
+
useEffect9(() => {
|
|
2944
3082
|
if (!composerCommand || composerCommand.id === lastComposerCommand.current) return;
|
|
2945
3083
|
lastComposerCommand.current = composerCommand.id;
|
|
2946
3084
|
if (composerCommand.action === "attach") {
|
|
@@ -3041,40 +3179,40 @@ function NewChat({ state, adapter, onBack, onClose, onStarted, labels, memoryKey
|
|
|
3041
3179
|
Promise.resolve(result).catch(() => setStarting((current) => current?.id === id ? null : current));
|
|
3042
3180
|
}
|
|
3043
3181
|
};
|
|
3044
|
-
return /* @__PURE__ */
|
|
3045
|
-
/* @__PURE__ */
|
|
3046
|
-
/* @__PURE__ */
|
|
3047
|
-
/* @__PURE__ */
|
|
3048
|
-
/* @__PURE__ */
|
|
3049
|
-
/* @__PURE__ */
|
|
3182
|
+
return /* @__PURE__ */ jsxs10("section", { className: "scui-chat", children: [
|
|
3183
|
+
/* @__PURE__ */ jsxs10("header", { className: "scui-head", children: [
|
|
3184
|
+
/* @__PURE__ */ jsx11("button", { type: "button", "aria-label": "Back", onClick: onBack, children: /* @__PURE__ */ jsx11(UiIcon, { name: "back", size: 18 }) }),
|
|
3185
|
+
/* @__PURE__ */ jsxs10("span", { className: "scui-head-copy", children: [
|
|
3186
|
+
/* @__PURE__ */ jsx11("strong", { children: labels.newChat }),
|
|
3187
|
+
/* @__PURE__ */ jsx11("small", { children: "No session is created until you send" })
|
|
3050
3188
|
] }),
|
|
3051
|
-
HeaderActions ? /* @__PURE__ */
|
|
3052
|
-
onClose ? /* @__PURE__ */
|
|
3189
|
+
HeaderActions ? /* @__PURE__ */ jsx11(HeaderActions, { state, adapter, value: "new" }) : null,
|
|
3190
|
+
onClose ? /* @__PURE__ */ jsx11("button", { type: "button", "aria-label": "Close", onClick: onClose, children: /* @__PURE__ */ jsx11(UiIcon, { name: "close", size: 18 }) }) : null
|
|
3053
3191
|
] }),
|
|
3054
|
-
starting ? /* @__PURE__ */
|
|
3055
|
-
/* @__PURE__ */
|
|
3192
|
+
starting ? /* @__PURE__ */ jsxs10("div", { className: "scui-operation", role: "status", children: [
|
|
3193
|
+
/* @__PURE__ */ jsx11("i", {}),
|
|
3056
3194
|
mode === "terminal" ? "Opening terminal\u2026" : operationLabel("start")
|
|
3057
3195
|
] }) : null,
|
|
3058
|
-
/* @__PURE__ */
|
|
3059
|
-
/* @__PURE__ */
|
|
3060
|
-
/* @__PURE__ */
|
|
3061
|
-
/* @__PURE__ */
|
|
3196
|
+
/* @__PURE__ */ jsxs10("div", { className: "scui-new", children: [
|
|
3197
|
+
/* @__PURE__ */ jsx11("span", { "aria-hidden": "true", children: "\u2726" }),
|
|
3198
|
+
/* @__PURE__ */ jsx11("strong", { children: "What should the agent build or fix?" }),
|
|
3199
|
+
/* @__PURE__ */ jsx11("small", { children: "Choose a coding harness and send the first message." })
|
|
3062
3200
|
] }),
|
|
3063
|
-
/* @__PURE__ */
|
|
3064
|
-
/* @__PURE__ */
|
|
3065
|
-
mode !== "terminal" ? /* @__PURE__ */
|
|
3066
|
-
/* @__PURE__ */
|
|
3201
|
+
/* @__PURE__ */ jsxs10("div", { className: "scui-compose", children: [
|
|
3202
|
+
/* @__PURE__ */ jsx11(Readiness, { harnesses: state.harnesses, state, adapter }),
|
|
3203
|
+
mode !== "terminal" ? /* @__PURE__ */ jsx11(ContextCandidates, { items: contextCandidates, context, images, state, adapter, onAttach: attachCandidate, component: components.ContextCandidate }) : null,
|
|
3204
|
+
/* @__PURE__ */ jsx11(ImageTray, { items: images, onRemove: (index) => setImages((items) => {
|
|
3067
3205
|
const next = items.filter((_, itemIndex) => itemIndex !== index);
|
|
3068
3206
|
remember({ images: next });
|
|
3069
3207
|
return next;
|
|
3070
3208
|
}) }),
|
|
3071
|
-
/* @__PURE__ */
|
|
3209
|
+
/* @__PURE__ */ jsx11(ContextTray, { items: context, onRemove: (index) => setContext((items) => {
|
|
3072
3210
|
const next = items.filter((_, itemIndex) => itemIndex !== index);
|
|
3073
3211
|
remember({ context: next });
|
|
3074
3212
|
return next;
|
|
3075
3213
|
}) }),
|
|
3076
|
-
terminalAttachments ? /* @__PURE__ */
|
|
3077
|
-
/* @__PURE__ */
|
|
3214
|
+
terminalAttachments ? /* @__PURE__ */ jsx11("small", { className: "scui-context-error", role: "alert", children: "Terminal starts currently accept text only. Remove attachments or choose Headless." }) : pickerError ? /* @__PURE__ */ jsx11("small", { className: "scui-context-error", role: "alert", children: pickerError }) : null,
|
|
3215
|
+
/* @__PURE__ */ jsxs10("div", { className: `scui-envelope scui-new-envelope${dragging ? " scui-drop-target" : ""}`, onDragEnter: (event) => {
|
|
3078
3216
|
if (Array.from(event.dataTransfer?.types ?? []).includes("Files")) {
|
|
3079
3217
|
event.preventDefault();
|
|
3080
3218
|
setDragging(true);
|
|
@@ -3084,7 +3222,7 @@ function NewChat({ state, adapter, onBack, onClose, onStarted, labels, memoryKey
|
|
|
3084
3222
|
}, onDragLeave: (event) => {
|
|
3085
3223
|
if (!event.currentTarget.contains(event.relatedTarget)) setDragging(false);
|
|
3086
3224
|
}, onDrop: dropImages, children: [
|
|
3087
|
-
/* @__PURE__ */
|
|
3225
|
+
/* @__PURE__ */ jsx11("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) => {
|
|
3088
3226
|
const value = event.currentTarget.value;
|
|
3089
3227
|
setDraft(value);
|
|
3090
3228
|
remember({ draft: value });
|
|
@@ -3094,19 +3232,19 @@ function NewChat({ state, adapter, onBack, onClose, onStarted, labels, memoryKey
|
|
|
3094
3232
|
send();
|
|
3095
3233
|
}
|
|
3096
3234
|
} }),
|
|
3097
|
-
/* @__PURE__ */
|
|
3098
|
-
adapter.pickContext ? /* @__PURE__ */
|
|
3099
|
-
/* @__PURE__ */
|
|
3235
|
+
/* @__PURE__ */ jsxs10("footer", { className: "scui-new-envelope-controls", children: [
|
|
3236
|
+
adapter.pickContext ? /* @__PURE__ */ jsx11("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__ */ jsx11("i", { className: "scui-control-spinner" }) : /* @__PURE__ */ jsx11(UiIcon, { name: "attach", size: 17 }) }) : null,
|
|
3237
|
+
/* @__PURE__ */ jsx11(Picker, { harnesses: state.harnesses, value: harness, disabled: Boolean(starting), adapter, logo: components.HarnessLogo, onChange: (value) => {
|
|
3100
3238
|
setHarness(value);
|
|
3101
3239
|
remember({ harness: value });
|
|
3102
3240
|
} }),
|
|
3103
|
-
/* @__PURE__ */
|
|
3241
|
+
/* @__PURE__ */ jsx11(ExecutionModeSelect, { modes: launchModes, value: mode, disabled: Boolean(starting) || mode !== requestedMode, onChange: (item) => {
|
|
3104
3242
|
const next = { ...modes, [harness]: item };
|
|
3105
3243
|
setModes(next);
|
|
3106
3244
|
setPickerError(null);
|
|
3107
3245
|
remember({ modes: next });
|
|
3108
3246
|
} }),
|
|
3109
|
-
/* @__PURE__ */
|
|
3247
|
+
/* @__PURE__ */ jsx11("span", { children: /* @__PURE__ */ jsx11("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__ */ jsx11("i", { className: "scui-control-spinner" }) : /* @__PURE__ */ jsx11(UiIcon, { name: "send", size: 17 }) }) })
|
|
3110
3248
|
] })
|
|
3111
3249
|
] })
|
|
3112
3250
|
] })
|
|
@@ -3117,18 +3255,19 @@ function SupercodeMessenger({ state: stateInput, adapter, class: className = "",
|
|
|
3117
3255
|
const contextCandidates = useMemo3(() => normalizeAttachmentCandidates(candidatesInput), [candidatesInput]);
|
|
3118
3256
|
const copy = { ...DEFAULT_LABELS, ...labels };
|
|
3119
3257
|
const memoryKey = state.workspace || "@default";
|
|
3120
|
-
const [view, setViewState] =
|
|
3121
|
-
const [opening, setOpening] =
|
|
3122
|
-
const [newNavigation, setNewNavigation] =
|
|
3123
|
-
const [chatNavigation, setChatNavigation] =
|
|
3124
|
-
const [listFocus, setListFocus] =
|
|
3125
|
-
const
|
|
3258
|
+
const [view, setViewState] = useState7(initialView ?? (state.attention.length ? "list" : messengerViewMemory.get(memoryKey) ?? (state.attached || state.transcript.length ? "chat" : "list")));
|
|
3259
|
+
const [opening, setOpening] = useState7(null);
|
|
3260
|
+
const [newNavigation, setNewNavigation] = useState7(null);
|
|
3261
|
+
const [chatNavigation, setChatNavigation] = useState7(null);
|
|
3262
|
+
const [listFocus, setListFocus] = useState7(null);
|
|
3263
|
+
const [inspecting, setInspecting] = useState7(null);
|
|
3264
|
+
const lastNavigation = useRef8(null);
|
|
3126
3265
|
const setView = (next) => {
|
|
3127
3266
|
boundedSet(messengerViewMemory, memoryKey, next);
|
|
3128
3267
|
setViewState(next);
|
|
3129
3268
|
onViewChange?.(next);
|
|
3130
3269
|
};
|
|
3131
|
-
|
|
3270
|
+
useEffect9(() => {
|
|
3132
3271
|
if (!navigation || navigation.id === lastNavigation.current) return;
|
|
3133
3272
|
lastNavigation.current = navigation.id;
|
|
3134
3273
|
if (navigation.view === "list") {
|
|
@@ -3158,7 +3297,7 @@ function SupercodeMessenger({ state: stateInput, adapter, class: className = "",
|
|
|
3158
3297
|
adapter.onIntent({ action: "attach", key: navigation.sessionKey });
|
|
3159
3298
|
}
|
|
3160
3299
|
}, [adapter, navigation, state.attached?.key, state.sessions]);
|
|
3161
|
-
|
|
3300
|
+
useEffect9(() => {
|
|
3162
3301
|
if (!opening) return;
|
|
3163
3302
|
if (state.attached?.key === opening.key) {
|
|
3164
3303
|
setOpening(null);
|
|
@@ -3173,38 +3312,50 @@ function SupercodeMessenger({ state: stateInput, adapter, class: className = "",
|
|
|
3173
3312
|
setOpening(row);
|
|
3174
3313
|
adapter.onIntent({ action: "attach", key: row.key });
|
|
3175
3314
|
};
|
|
3315
|
+
const openSubagents = (row) => {
|
|
3316
|
+
setListFocus(row.key);
|
|
3317
|
+
setInspecting(row);
|
|
3318
|
+
adapter.onIntent({ action: "openSubagents", key: row.key });
|
|
3319
|
+
};
|
|
3176
3320
|
const close = () => adapter.onClose?.();
|
|
3177
3321
|
const Footer = slots.footer;
|
|
3178
3322
|
const HeaderActions = slots.headerActions;
|
|
3179
|
-
|
|
3180
|
-
|
|
3181
|
-
|
|
3182
|
-
|
|
3183
|
-
|
|
3184
|
-
|
|
3185
|
-
|
|
3186
|
-
|
|
3187
|
-
|
|
3188
|
-
|
|
3189
|
-
|
|
3190
|
-
|
|
3191
|
-
|
|
3192
|
-
|
|
3193
|
-
|
|
3194
|
-
|
|
3195
|
-
|
|
3196
|
-
|
|
3197
|
-
|
|
3198
|
-
|
|
3199
|
-
|
|
3200
|
-
|
|
3201
|
-
|
|
3323
|
+
const inspectorParent = inspecting ?? (state.subagentInspector ? state.sessions.find((row) => row.key === state.subagentInspector.parentKey) ?? { key: state.subagentInspector.parentKey, title: state.subagentInspector.parentTitle } : null);
|
|
3324
|
+
const inspectorState = inspectorParent ? {
|
|
3325
|
+
...state,
|
|
3326
|
+
subagentInspector: state.subagentInspector?.parentKey === inspectorParent.key ? state.subagentInspector : { parentKey: inspectorParent.key, parentTitle: sessionDisplayName(inspectorParent), status: "loading", items: [], selectedKey: null, transcript: [], error: null }
|
|
3327
|
+
} : null;
|
|
3328
|
+
return /* @__PURE__ */ jsxs10("main", { className: `scui-root ${className}`, "data-view": inspectorState ? "agents" : view, "data-mode": state.mode, "aria-label": "Supercode messenger", children: [
|
|
3329
|
+
inspectorState ? /* @__PURE__ */ jsx11(SubagentInspector, { state: inspectorState, adapter, onClose: () => setInspecting(null) }) : /* @__PURE__ */ jsxs10(Fragment5, { children: [
|
|
3330
|
+
view === "list" ? /* @__PURE__ */ jsx11(SessionList, { state, adapter, focusKey: listFocus, onOpen: open, onOpenSubagents: openSubagents, onNew: () => {
|
|
3331
|
+
setListFocus("@new");
|
|
3332
|
+
setChatNavigation(null);
|
|
3333
|
+
setNewNavigation(null);
|
|
3334
|
+
setView("new");
|
|
3335
|
+
}, onClose: adapter.onClose ? close : void 0, components, labels: copy, memoryKey, slots, headerActions: HeaderActions }) : null,
|
|
3336
|
+
view === "new" ? /* @__PURE__ */ jsx11(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,
|
|
3337
|
+
view === "chat" ? /* @__PURE__ */ jsx11(Chat, { state, adapter, onBack: () => {
|
|
3338
|
+
setListFocus(state.attached?.key ?? listFocus);
|
|
3339
|
+
setView("list");
|
|
3340
|
+
}, onNew: () => {
|
|
3341
|
+
setListFocus("@new");
|
|
3342
|
+
setChatNavigation(null);
|
|
3343
|
+
setNewNavigation(null);
|
|
3344
|
+
setView("new");
|
|
3345
|
+
}, onClose: adapter.onClose ? close : void 0, components, slots, labels: copy, contextCandidates, navigation: chatNavigation?.sessionKey === state.attached?.key ? chatNavigation : null, composerCommand }) : null,
|
|
3346
|
+
opening ? /* @__PURE__ */ jsxs10("div", { className: "scui-opening", role: "status", "aria-busy": "true", children: [
|
|
3347
|
+
/* @__PURE__ */ jsx11(HarnessLogo, { id: opening.harness, size: 34 }),
|
|
3348
|
+
/* @__PURE__ */ jsxs10("span", { children: [
|
|
3349
|
+
/* @__PURE__ */ jsxs10("strong", { children: [
|
|
3350
|
+
"Opening ",
|
|
3351
|
+
sessionDisplayName(opening)
|
|
3352
|
+
] }),
|
|
3353
|
+
/* @__PURE__ */ jsx11("small", { children: "Loading the latest transcript window\u2026" })
|
|
3202
3354
|
] }),
|
|
3203
|
-
/* @__PURE__ */
|
|
3204
|
-
] })
|
|
3205
|
-
|
|
3206
|
-
|
|
3207
|
-
Footer ? /* @__PURE__ */ jsx10(Footer, { state, adapter, value: copy }) : null
|
|
3355
|
+
/* @__PURE__ */ jsx11("i", {})
|
|
3356
|
+
] }) : null
|
|
3357
|
+
] }),
|
|
3358
|
+
Footer ? /* @__PURE__ */ jsx11(Footer, { state, adapter, value: copy }) : null
|
|
3208
3359
|
] });
|
|
3209
3360
|
}
|
|
3210
3361
|
export {
|
|
@@ -3228,6 +3379,7 @@ export {
|
|
|
3228
3379
|
SessionDetails,
|
|
3229
3380
|
SessionList,
|
|
3230
3381
|
SessionRow,
|
|
3382
|
+
SubagentInspector,
|
|
3231
3383
|
SupercodeMessenger,
|
|
3232
3384
|
TaskPlan,
|
|
3233
3385
|
ToolRow,
|