@volter-ai-dev/supercode-ui 0.1.66 → 0.1.68

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.
@@ -33,6 +33,10 @@ var EMPTY_UI_STATE = Object.freeze({
33
33
  harness: "",
34
34
  mode: "none",
35
35
  strategy: null,
36
+ participant: Object.freeze({ kind: "local-user", label: null, origin: null }),
37
+ workspaceRef: Object.freeze({ kind: "none", value: null }),
38
+ mirror: null,
39
+ holder: null,
36
40
  canSend: false,
37
41
  canSteer: false,
38
42
  canResume: false,
@@ -70,7 +74,12 @@ var EMPTY_UI_STATE = Object.freeze({
70
74
  subagentInspector: null,
71
75
  attached: null,
72
76
  owned: null,
73
- attachError: null
77
+ attachError: null,
78
+ agentPackage: null,
79
+ contributions: Object.freeze([]),
80
+ agentPackageError: null,
81
+ agentPackageCapabilityState: null,
82
+ agentPackageCapabilityError: null
74
83
  });
75
84
  var TOOL_CATEGORIES = /* @__PURE__ */ new Set(["read", "search", "edit", "command", "test", "web", "agent", "plan", "other"]);
76
85
  var MAX_TOOL_FIELDS = 8;
@@ -530,7 +539,11 @@ function languageLabel(info) {
530
539
  }
531
540
  function frameCode(render, tokens, index, options, env, self) {
532
541
  const label = markdown.utils.escapeHtml(languageLabel(tokens[index]?.info ?? ""));
533
- return `<div class="scui-code-block"><div class="scui-code-head"><span>${label}</span><button class="scui-code-copy" type="button" aria-label="Copy code" title="Copy code">${COPY_ICON}<span>Copy</span></button></div>${render(tokens, index, options, env, self)}</div>`;
542
+ const body = render(tokens, index, options, env, self).replace(
543
+ "<pre>",
544
+ `<pre tabindex="0" role="region" aria-label="${label} code">`
545
+ );
546
+ return `<div class="scui-code-block"><div class="scui-code-head"><span>${label}</span><button class="scui-code-copy" type="button" aria-label="Copy code" title="Copy code">${COPY_ICON}<span>Copy</span></button></div>${body}</div>`;
534
547
  }
535
548
  for (const kind of ["fence", "code_block"]) {
536
549
  const render = markdown.renderer.rules[kind];
@@ -588,6 +601,12 @@ function Markdown({ value, copyText }) {
588
601
 
589
602
  // src/memory.js
590
603
  var MEMORY_LIMIT = 100;
604
+ var registry = /* @__PURE__ */ new Set();
605
+ function uiMemory() {
606
+ const map = /* @__PURE__ */ new Map();
607
+ registry.add(map);
608
+ return map;
609
+ }
591
610
  function boundedSet(map, key, value) {
592
611
  map.delete(key);
593
612
  map.set(key, value);
@@ -1091,6 +1110,26 @@ function TechnicalDetails({ entry }) {
1091
1110
  ] });
1092
1111
  }
1093
1112
  function TranscriptEntry({ entry, state, adapter }) {
1113
+ if (entry.role === "opaque") {
1114
+ return /* @__PURE__ */ jsxs3("article", { className: "scui-message scui-opaque", "data-role": "opaque", "data-kind": entry.kind, "aria-label": "Unrecognized entry", children: [
1115
+ /* @__PURE__ */ jsxs3("div", { className: "scui-notice", "data-code": "opaque-entry", children: [
1116
+ "Unrecognized entry kind ",
1117
+ /* @__PURE__ */ jsx4("code", { children: entry.kind }),
1118
+ " \u2014 kept as-is, nothing dropped"
1119
+ ] }),
1120
+ entry.text ? /* @__PURE__ */ jsx4(Markdown, { value: entry.text, copyText: adapter?.copyText }) : null,
1121
+ entry.raw ? /* @__PURE__ */ jsxs3("details", { className: "scui-tool-technical", children: [
1122
+ /* @__PURE__ */ jsx4("summary", { children: "Technical details" }),
1123
+ /* @__PURE__ */ jsx4("div", { children: /* @__PURE__ */ jsxs3("section", { children: [
1124
+ /* @__PURE__ */ jsx4("strong", { children: "Raw entry" }),
1125
+ /* @__PURE__ */ jsxs3("pre", { children: [
1126
+ entry.raw,
1127
+ entry.truncated ? "\n[truncated]" : ""
1128
+ ] })
1129
+ ] }) })
1130
+ ] }) : null
1131
+ ] });
1132
+ }
1094
1133
  if (entry.role === "request") return /* @__PURE__ */ jsx4(RequestCard, { entry, adapter, canRespond: state.canRespond });
1095
1134
  if (entry.role === "reasoning") {
1096
1135
  return /* @__PURE__ */ jsxs3("details", { className: "scui-reasoning", open: entry.streaming, children: [
@@ -1220,7 +1259,7 @@ function SessionDetails({ semantics }) {
1220
1259
  ] })
1221
1260
  ] });
1222
1261
  }
1223
- var conversationMemory = /* @__PURE__ */ new Map();
1262
+ var conversationMemory = uiMemory();
1224
1263
  function ConversationAnnouncements({ state }) {
1225
1264
  const previousBusy = useRef3(state.busy);
1226
1265
  const [announcement, setAnnouncement] = useState2("");
@@ -32,6 +32,10 @@ var EMPTY_UI_STATE = Object.freeze({
32
32
  harness: "",
33
33
  mode: "none",
34
34
  strategy: null,
35
+ participant: Object.freeze({ kind: "local-user", label: null, origin: null }),
36
+ workspaceRef: Object.freeze({ kind: "none", value: null }),
37
+ mirror: null,
38
+ holder: null,
35
39
  canSend: false,
36
40
  canSteer: false,
37
41
  canResume: false,
@@ -69,7 +73,12 @@ var EMPTY_UI_STATE = Object.freeze({
69
73
  subagentInspector: null,
70
74
  attached: null,
71
75
  owned: null,
72
- attachError: null
76
+ attachError: null,
77
+ agentPackage: null,
78
+ contributions: Object.freeze([]),
79
+ agentPackageError: null,
80
+ agentPackageCapabilityState: null,
81
+ agentPackageCapabilityError: null
73
82
  });
74
83
  var ROLES = /* @__PURE__ */ new Set(["system", "user", "assistant", "tool", "reasoning", "request", "notice"]);
75
84
  var MODES = /* @__PURE__ */ new Set(["none", "control", "mirror"]);
@@ -82,6 +91,10 @@ var AUTHENTICATION_PHASES = /* @__PURE__ */ new Set(["idle", "checking", "requir
82
91
  var MAX_TOOL_FIELDS = 8;
83
92
  var MAX_TOOL_FIELD_CHARS = 800;
84
93
  var MAX_TOOL_PREVIEW_CHARS = 4e3;
94
+ var MAX_CONTRIBUTIONS = 64;
95
+ var MAX_CONTRIBUTION_JSON_DEPTH = 12;
96
+ var MAX_CONTRIBUTION_COLLECTION = 100;
97
+ var MAX_CONTRIBUTION_STRING_CHARS = 16e3;
85
98
  function record(value) {
86
99
  return value !== null && typeof value === "object" && !Array.isArray(value) ? value : null;
87
100
  }
@@ -114,6 +127,126 @@ function number(value, fallback = 0) {
114
127
  function nullableNumber(value) {
115
128
  return typeof value === "number" && Number.isFinite(value) ? value : null;
116
129
  }
130
+ function relativeContributionPath(value) {
131
+ if (typeof value !== "string" || value.startsWith("/") || /^[a-z]:[\\/]/i.test(value)) return null;
132
+ return value.replaceAll("\\", "/").split("/").some((segment) => segment === "..") ? null : boundedString(value, 1e3);
133
+ }
134
+ function contributionJson(value, depth = 0, seen = /* @__PURE__ */ new WeakSet()) {
135
+ if (value === null || typeof value === "boolean" || typeof value === "string") {
136
+ return typeof value === "string" ? boundedString(value, MAX_CONTRIBUTION_STRING_CHARS) : value;
137
+ }
138
+ if (typeof value === "number") return Number.isFinite(value) ? value : void 0;
139
+ if (depth >= MAX_CONTRIBUTION_JSON_DEPTH || !value || typeof value !== "object" || seen.has(value)) {
140
+ return void 0;
141
+ }
142
+ seen.add(value);
143
+ if (Array.isArray(value)) {
144
+ const result2 = [];
145
+ for (const item of value.slice(0, MAX_CONTRIBUTION_COLLECTION)) {
146
+ const normalized = contributionJson(item, depth + 1, seen);
147
+ if (normalized !== void 0) result2.push(normalized);
148
+ }
149
+ seen.delete(value);
150
+ return result2;
151
+ }
152
+ const source = record(value);
153
+ if (!source) return void 0;
154
+ const result = {};
155
+ for (const [key, item] of Object.entries(source).slice(0, MAX_CONTRIBUTION_COLLECTION)) {
156
+ const normalized = contributionJson(item, depth + 1, seen);
157
+ if (normalized !== void 0) result[boundedString(key, 200)] = normalized;
158
+ }
159
+ seen.delete(value);
160
+ return result;
161
+ }
162
+ function normalizeContributions(value) {
163
+ if (!Array.isArray(value)) return [];
164
+ return value.slice(0, MAX_CONTRIBUTIONS).flatMap((candidate) => {
165
+ const item = record(candidate);
166
+ const placement = record(item?.placement);
167
+ const source = relativeContributionPath(item?.source);
168
+ if (item?.schema !== "supercode/contribution-v1" || typeof item.id !== "string" || !item.id.trim() || typeof item.kind !== "string" || !item.kind.trim() || source === null) return [];
169
+ const data = contributionJson(item.data);
170
+ if (data === void 0) return [];
171
+ return [{
172
+ schema: "supercode/contribution-v1",
173
+ id: boundedString(item.id, 200),
174
+ kind: boundedString(item.kind, 100),
175
+ ...typeof item.title === "string" ? { title: boundedString(item.title, 500) } : {},
176
+ ...placement ? { placement: {
177
+ ...typeof placement.surface === "string" ? { surface: boundedString(placement.surface, 100) } : {},
178
+ ...typeof placement.region === "string" ? { region: boundedString(placement.region, 100) } : {}
179
+ } } : {},
180
+ data,
181
+ source
182
+ }];
183
+ });
184
+ }
185
+ function readAgentPackage(value) {
186
+ const agentPackage = record(value);
187
+ const capabilities = record(agentPackage?.capabilities);
188
+ const storage = record(agentPackage?.storage);
189
+ const relativePath = relativeContributionPath(storage?.relativePath);
190
+ if (agentPackage?.schemaVersion !== 1 || typeof agentPackage.id !== "string" || typeof agentPackage.name !== "string" || typeof agentPackage.version !== "string" || !capabilities || !Array.isArray(capabilities.required) || !Array.isArray(capabilities.optional) || !storage || relativePath === null) return null;
191
+ const resources = record(agentPackage.resources);
192
+ return {
193
+ id: boundedString(agentPackage.id, 200),
194
+ name: boundedString(agentPackage.name, 500),
195
+ version: boundedString(agentPackage.version, 100),
196
+ description: typeof agentPackage.description === "string" ? boundedString(agentPackage.description, 2e3) : null,
197
+ capabilities: {
198
+ required: capabilities.required.filter((item) => typeof item === "string").slice(0, 100).map((item) => boundedString(item, 200)),
199
+ optional: capabilities.optional.filter((item) => typeof item === "string").slice(0, 100).map((item) => boundedString(item, 200))
200
+ },
201
+ storage: { relativePath },
202
+ resources: resources ? Object.fromEntries(Object.entries(resources).flatMap(([id, candidate]) => {
203
+ const state = record(candidate);
204
+ if (state?.schema !== "supercode/package-resource-state-v1") return [];
205
+ if (state.status === "absent" && typeof state.contributionId === "string") {
206
+ return [[boundedString(id, 200), {
207
+ schema: "supercode/package-resource-state-v1",
208
+ status: "absent",
209
+ contributionId: boundedString(state.contributionId, 200)
210
+ }]];
211
+ }
212
+ if (state.status === "error" && typeof state.contributionId === "string" && typeof state.message === "string") {
213
+ return [[boundedString(id, 200), {
214
+ schema: "supercode/package-resource-state-v1",
215
+ status: "error",
216
+ contributionId: boundedString(state.contributionId, 200),
217
+ message: boundedString(state.message)
218
+ }]];
219
+ }
220
+ const resource = record(state?.resource);
221
+ const data = contributionJson(resource?.data);
222
+ if (state?.status !== "ready" || resource?.schema !== "supercode/package-resource-v1" || typeof resource.contributionId !== "string" || !["json", "text"].includes(resource.format) || typeof resource.mediaType !== "string" || data === void 0) return [];
223
+ return [[boundedString(id, 200), {
224
+ schema: "supercode/package-resource-state-v1",
225
+ status: "ready",
226
+ resource: {
227
+ schema: "supercode/package-resource-v1",
228
+ contributionId: boundedString(resource.contributionId, 200),
229
+ format: resource.format,
230
+ mediaType: boundedString(resource.mediaType, 200),
231
+ data
232
+ }
233
+ }]];
234
+ })) : {}
235
+ };
236
+ }
237
+ function readAgentPackageCapabilityState(value) {
238
+ const state = record(value);
239
+ if (!state) return null;
240
+ const fields = ["availableRequired", "missingRequired", "enabledOptional", "unavailableOptional"];
241
+ if (!fields.every((field) => Array.isArray(state[field]))) return null;
242
+ return {
243
+ ready: state.ready === true,
244
+ ...Object.fromEntries(fields.map((field) => [
245
+ field,
246
+ state[field].filter((item) => typeof item === "string").slice(0, 100).map((item) => boundedString(item, 200))
247
+ ]))
248
+ };
249
+ }
117
250
  function relativeAge(updatedAt, now = Date.now()) {
118
251
  if (typeof updatedAt !== "number" || !Number.isFinite(updatedAt) || updatedAt <= 0) return "";
119
252
  const delta = Math.max(0, now - updatedAt);
@@ -512,12 +645,40 @@ function readToolPresentation(value, entry) {
512
645
  matches: nullableNumber(item.matches) ?? generated.matches
513
646
  };
514
647
  }
648
+ var OPAQUE_RAW_CHARS = 4e3;
649
+ function opaqueEntry(item) {
650
+ const previouslyOpaque = item.role === "opaque";
651
+ let raw;
652
+ if (previouslyOpaque && typeof item.raw === "string") {
653
+ raw = item.raw;
654
+ } else {
655
+ try {
656
+ raw = JSON.stringify(item, null, 2) ?? "";
657
+ } catch {
658
+ raw = "[unserializable entry payload]";
659
+ }
660
+ }
661
+ const kind = previouslyOpaque && typeof item.kind === "string" ? item.kind : typeof item.role === "string" ? item.role : "";
662
+ return {
663
+ id: item.id,
664
+ role: "opaque",
665
+ kind: boundedString(kind, 120) || "unknown",
666
+ text: typeof item.text === "string" ? boundedString(item.text, OPAQUE_RAW_CHARS) : "",
667
+ ts: nullableNumber(item.ts),
668
+ truncated: item.truncated === true || raw.length > OPAQUE_RAW_CHARS,
669
+ raw: boundedString(raw, OPAQUE_RAW_CHARS)
670
+ };
671
+ }
515
672
  function readTranscript(value) {
516
673
  if (!Array.isArray(value)) return [];
517
674
  const result = [];
518
675
  for (const candidate of value) {
519
676
  const item = record(candidate);
520
- if (!item || typeof item.id !== "string" || typeof item.text !== "string" || !ROLES.has(item.role)) continue;
677
+ if (!item || typeof item.id !== "string") continue;
678
+ if (typeof item.text !== "string" || !ROLES.has(item.role)) {
679
+ result.push(opaqueEntry(item));
680
+ continue;
681
+ }
521
682
  const entry = {
522
683
  id: item.id,
523
684
  role: item.role,
@@ -575,6 +736,75 @@ function readTranscript(value) {
575
736
  }
576
737
  return result;
577
738
  }
739
+ function readParticipant(value) {
740
+ const participant = record(value);
741
+ if (!participant) return { kind: "local-user", label: null, origin: null };
742
+ return {
743
+ kind: ["local-user", "foreign", "unknown"].includes(participant.kind) ? participant.kind : "unknown",
744
+ label: typeof participant.label === "string" && participant.label ? boundedString(participant.label, 200) : null,
745
+ origin: typeof participant.origin === "string" && participant.origin ? boundedString(participant.origin, 100) : null
746
+ };
747
+ }
748
+ function readWorkspaceRef(value, fallbackPath = "") {
749
+ const ref = record(value);
750
+ if (ref && ["repo", "none", "channel"].includes(ref.kind)) {
751
+ return {
752
+ kind: ref.kind,
753
+ value: ref.kind === "none" ? null : typeof ref.value === "string" && ref.value ? boundedString(ref.value, 500) : null
754
+ };
755
+ }
756
+ return fallbackPath ? { kind: "repo", value: boundedString(fallbackPath, 500) } : { kind: "none", value: null };
757
+ }
758
+ function readMirror(value) {
759
+ const mirror = record(value);
760
+ if (!mirror || typeof mirror.canonicalHarness !== "string" || !mirror.canonicalHarness) return null;
761
+ return {
762
+ canonicalHarness: boundedString(mirror.canonicalHarness, 100),
763
+ canonicalKey: typeof mirror.canonicalKey === "string" && mirror.canonicalKey ? boundedString(mirror.canonicalKey, 300) : null,
764
+ bounded: mirror.bounded === true,
765
+ truncated: mirror.truncated === true,
766
+ origin: typeof mirror.origin === "string" && mirror.origin ? boundedString(mirror.origin, 200) : null
767
+ };
768
+ }
769
+ function readHolder(value) {
770
+ const holder = record(value);
771
+ if (!holder) return null;
772
+ const surface = typeof holder.surface === "string" && holder.surface ? boundedString(holder.surface, 100) : null;
773
+ return {
774
+ surface,
775
+ canTakeOver: holder.canTakeOver === true && surface !== null && surface !== "supercode"
776
+ };
777
+ }
778
+ var TRIGGER_KINDS = ["human", "channel", "cron", "heartbeat", "webhook", "parent", "api", "unknown"];
779
+ function readTrigger(value) {
780
+ const trigger = record(value);
781
+ if (!trigger) return null;
782
+ const kind = trigger.kind === "manual" ? "human" : trigger.kind;
783
+ return {
784
+ kind: TRIGGER_KINDS.includes(kind) ? kind : "unknown",
785
+ label: typeof trigger.label === "string" && trigger.label ? boundedString(trigger.label, 200) : null,
786
+ surface: typeof trigger.surface === "string" && trigger.surface ? boundedString(trigger.surface, 300) : null
787
+ };
788
+ }
789
+ function readCrossSurface(value) {
790
+ const moved = record(value);
791
+ if (!moved || typeof moved.state !== "string" || !moved.state) return null;
792
+ return {
793
+ state: boundedString(moved.state, 100),
794
+ platform: typeof moved.platform === "string" && moved.platform ? boundedString(moved.platform, 100) : null,
795
+ error: typeof moved.error === "string" && moved.error ? boundedString(moved.error, 500) : null
796
+ };
797
+ }
798
+ function readRecurring(value) {
799
+ const recurring = record(value);
800
+ if (!recurring || typeof recurring.groupKey !== "string" || !recurring.groupKey) return null;
801
+ const runs = Number.isSafeInteger(recurring.runs) && recurring.runs > 0 ? recurring.runs : 1;
802
+ return {
803
+ groupKey: boundedString(recurring.groupKey, 300),
804
+ runs,
805
+ lastStatus: ["ok", "failed", "mixed"].includes(recurring.lastStatus) ? recurring.lastStatus : null
806
+ };
807
+ }
578
808
  function readSessions(value) {
579
809
  if (!Array.isArray(value)) return [];
580
810
  return value.flatMap((raw) => {
@@ -596,7 +826,13 @@ function readSessions(value) {
596
826
  live: row.live === true,
597
827
  runtimeStatus: row.runtimeStatus === "running" || row.runtimeStatus === "busy" || row.runtimeStatus === "idle" ? row.runtimeStatus : null,
598
828
  ...Number.isSafeInteger(row.subagentCount) && row.subagentCount > 0 ? { subagentCount: row.subagentCount } : {},
599
- activity: ACTIVITY_PRIORITY[row.activity] !== void 0 ? row.activity : void 0
829
+ activity: ACTIVITY_PRIORITY[row.activity] !== void 0 ? row.activity : void 0,
830
+ ...row.participant !== void 0 ? { participant: readParticipant(row.participant) } : {},
831
+ workspaceRef: readWorkspaceRef(row.workspaceRef, string(row.cwd)),
832
+ ...readMirror(row.mirror) ? { mirror: readMirror(row.mirror) } : {},
833
+ ...readTrigger(row.trigger) ? { trigger: readTrigger(row.trigger) } : {},
834
+ ...readRecurring(row.recurring) ? { recurring: readRecurring(row.recurring) } : {},
835
+ ...readCrossSurface(row.crossSurface) ? { crossSurface: readCrossSurface(row.crossSurface) } : {}
600
836
  }];
601
837
  });
602
838
  }
@@ -780,6 +1016,10 @@ function normalizeUiState(value) {
780
1016
  canConfigureSettings: raw.canConfigureSettings === true,
781
1017
  messaging: raw.messaging === "live_peer" ? "live_peer" : null,
782
1018
  workspace: string(raw.workspace),
1019
+ workspaceRef: readWorkspaceRef(raw.workspaceRef, string(raw.workspace)),
1020
+ participant: readParticipant(raw.participant),
1021
+ mirror: readMirror(raw.mirror),
1022
+ holder: readHolder(raw.holder),
783
1023
  taskPlan: readTaskPlan(raw.taskPlan),
784
1024
  semantics: readSemantics(raw.semantics),
785
1025
  terminalHandoff: readTerminalHandoff(raw.terminalHandoff),
@@ -831,7 +1071,12 @@ function normalizeUiState(value) {
831
1071
  subagentInspector: readSubagentInspector(raw.subagentInspector),
832
1072
  attached: readAttached(raw.attached),
833
1073
  owned: readAttached(raw.owned),
834
- attachError: attachError && typeof attachError.key === "string" && typeof attachError.message === "string" ? { key: attachError.key, message: attachError.message } : null
1074
+ attachError: attachError && typeof attachError.key === "string" && typeof attachError.message === "string" ? { key: attachError.key, message: attachError.message } : null,
1075
+ agentPackage: readAgentPackage(raw.agentPackage),
1076
+ contributions: normalizeContributions(raw.contributions),
1077
+ agentPackageError: typeof raw.agentPackageError === "string" ? boundedString(raw.agentPackageError) : null,
1078
+ agentPackageCapabilityState: readAgentPackageCapabilityState(raw.agentPackageCapabilityState),
1079
+ agentPackageCapabilityError: typeof raw.agentPackageCapabilityError === "string" ? boundedString(raw.agentPackageCapabilityError) : null
835
1080
  };
836
1081
  }
837
1082
  function harnessDisplayName(id) {
@@ -936,6 +1181,12 @@ import { useEffect as useEffect2, useRef as useRef2, useState as useState2 } fro
936
1181
 
937
1182
  // src/memory.js
938
1183
  var MEMORY_LIMIT = 100;
1184
+ var registry = /* @__PURE__ */ new Set();
1185
+ function uiMemory() {
1186
+ const map = /* @__PURE__ */ new Map();
1187
+ registry.add(map);
1188
+ return map;
1189
+ }
939
1190
  function boundedSet(map, key, value) {
940
1191
  map.delete(key);
941
1192
  map.set(key, value);
@@ -1289,7 +1540,7 @@ function MessageImages({ items, adapter }) {
1289
1540
  }
1290
1541
 
1291
1542
  // src/intent.js
1292
- var CONFIRMABLE_ACTIONS = /* @__PURE__ */ new Set(["resume", "join", "branch", "reduce", "export"]);
1543
+ var CONFIRMABLE_ACTIONS = /* @__PURE__ */ new Set(["resume", "join", "branch", "reduce", "export", "take_over"]);
1293
1544
  async function dispatchConfirmedIntent(adapter, intent) {
1294
1545
  if (CONFIRMABLE_ACTIONS.has(intent.action) && adapter.confirmIntent) {
1295
1546
  const confirmed = await adapter.confirmIntent(intent);
@@ -1314,7 +1565,7 @@ function useAutosizeTextarea(ref, value) {
1314
1565
 
1315
1566
  // src/composer.jsx
1316
1567
  import { jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
1317
- var composerMemory = /* @__PURE__ */ new Map();
1568
+ var composerMemory = uiMemory();
1318
1569
  function ExecutionModeSelect({ modes = [], value, onChange, disabled = false, label = "Run in" }) {
1319
1570
  if (modes.length < 2) return null;
1320
1571
  return /* @__PURE__ */ jsxs3("label", { className: "scui-execution-mode", title: disabled ? void 0 : `${label}: ${value}`, children: [
@@ -1610,7 +1861,11 @@ function languageLabel(info) {
1610
1861
  }
1611
1862
  function frameCode(render, tokens, index, options, env, self) {
1612
1863
  const label = markdown.utils.escapeHtml(languageLabel(tokens[index]?.info ?? ""));
1613
- return `<div class="scui-code-block"><div class="scui-code-head"><span>${label}</span><button class="scui-code-copy" type="button" aria-label="Copy code" title="Copy code">${COPY_ICON}<span>Copy</span></button></div>${render(tokens, index, options, env, self)}</div>`;
1864
+ const body = render(tokens, index, options, env, self).replace(
1865
+ "<pre>",
1866
+ `<pre tabindex="0" role="region" aria-label="${label} code">`
1867
+ );
1868
+ return `<div class="scui-code-block"><div class="scui-code-head"><span>${label}</span><button class="scui-code-copy" type="button" aria-label="Copy code" title="Copy code">${COPY_ICON}<span>Copy</span></button></div>${body}</div>`;
1614
1869
  }
1615
1870
  for (const kind of ["fence", "code_block"]) {
1616
1871
  const render = markdown.renderer.rules[kind];
@@ -1947,6 +2202,26 @@ function TechnicalDetails({ entry }) {
1947
2202
  ] });
1948
2203
  }
1949
2204
  function TranscriptEntry({ entry, state, adapter }) {
2205
+ if (entry.role === "opaque") {
2206
+ return /* @__PURE__ */ jsxs4("article", { className: "scui-message scui-opaque", "data-role": "opaque", "data-kind": entry.kind, "aria-label": "Unrecognized entry", children: [
2207
+ /* @__PURE__ */ jsxs4("div", { className: "scui-notice", "data-code": "opaque-entry", children: [
2208
+ "Unrecognized entry kind ",
2209
+ /* @__PURE__ */ jsx5("code", { children: entry.kind }),
2210
+ " \u2014 kept as-is, nothing dropped"
2211
+ ] }),
2212
+ entry.text ? /* @__PURE__ */ jsx5(Markdown, { value: entry.text, copyText: adapter?.copyText }) : null,
2213
+ entry.raw ? /* @__PURE__ */ jsxs4("details", { className: "scui-tool-technical", children: [
2214
+ /* @__PURE__ */ jsx5("summary", { children: "Technical details" }),
2215
+ /* @__PURE__ */ jsx5("div", { children: /* @__PURE__ */ jsxs4("section", { children: [
2216
+ /* @__PURE__ */ jsx5("strong", { children: "Raw entry" }),
2217
+ /* @__PURE__ */ jsxs4("pre", { children: [
2218
+ entry.raw,
2219
+ entry.truncated ? "\n[truncated]" : ""
2220
+ ] })
2221
+ ] }) })
2222
+ ] }) : null
2223
+ ] });
2224
+ }
1950
2225
  if (entry.role === "request") return /* @__PURE__ */ jsx5(RequestCard, { entry, adapter, canRespond: state.canRespond });
1951
2226
  if (entry.role === "reasoning") {
1952
2227
  return /* @__PURE__ */ jsxs4("details", { className: "scui-reasoning", open: entry.streaming, children: [
@@ -2076,7 +2351,7 @@ function SessionDetails({ semantics }) {
2076
2351
  ] })
2077
2352
  ] });
2078
2353
  }
2079
- var conversationMemory = /* @__PURE__ */ new Map();
2354
+ var conversationMemory = uiMemory();
2080
2355
  function ConversationAnnouncements({ state }) {
2081
2356
  const previousBusy = useRef4(state.busy);
2082
2357
  const [announcement, setAnnouncement] = useState3("");
@@ -2256,7 +2531,7 @@ function HarnessLogo({ id, activity, size = 28, onMissingLogo }) {
2256
2531
  // src/sessions.jsx
2257
2532
  import { useEffect as useEffect6, useLayoutEffect as useLayoutEffect3, useRef as useRef5, useState as useState4 } from "react";
2258
2533
  import { jsx as jsx7, jsxs as jsxs6 } from "react/jsx-runtime";
2259
- var sessionListMemory = /* @__PURE__ */ new Map();
2534
+ var sessionListMemory = uiMemory();
2260
2535
  function sessionPathParts(value) {
2261
2536
  const complete = String(value ?? "").replaceAll("\\", "/");
2262
2537
  const boundary = complete.lastIndexOf("/");
@@ -2278,11 +2553,55 @@ function SessionRow({ row, state, onOpen, onOpenSubagents, now = Date.now() }) {
2278
2553
  const unreadCount = attention?.unreadCount ?? 0;
2279
2554
  const unreadLabel = unreadCount > 99 ? "99+" : String(unreadCount);
2280
2555
  const age = relativeAge(row.previewUpdatedAt ?? row.updatedAt, now) || row.age;
2281
- return /* @__PURE__ */ jsxs6("article", { className: "scui-session", "data-active": row.active, "data-activity": activity, "data-writable": row.writable, children: [
2556
+ const nounBadges = [];
2557
+ if (row.trigger && row.trigger.kind !== "manual" && row.trigger.kind !== "human") {
2558
+ const runs = row.recurring?.runs;
2559
+ const detail = row.trigger.label || row.trigger.surface || "";
2560
+ nounBadges.push(
2561
+ /* @__PURE__ */ jsxs6("small", { className: "scui-session-noun", "data-noun": "trigger", "data-kind": row.trigger.kind, "data-surface": row.trigger.surface ?? void 0, "data-status": row.recurring?.lastStatus ?? void 0, children: [
2562
+ row.trigger.kind,
2563
+ detail ? ` \xB7 ${detail}` : "",
2564
+ runs && runs > 1 ? ` \xB7 \xD7${runs}` : ""
2565
+ ] }, "trigger")
2566
+ );
2567
+ }
2568
+ if (row.crossSurface) {
2569
+ nounBadges.push(
2570
+ /* @__PURE__ */ jsxs6("small", { className: "scui-session-noun", "data-noun": "cross-surface", "data-state": row.crossSurface.state, title: row.crossSurface.error ?? void 0, children: [
2571
+ "\u2192",
2572
+ row.crossSurface.platform ?? "elsewhere",
2573
+ " \xB7 ",
2574
+ row.crossSurface.state
2575
+ ] }, "cross-surface")
2576
+ );
2577
+ }
2578
+ if (row.participant && row.participant.kind !== "local-user") {
2579
+ nounBadges.push(
2580
+ /* @__PURE__ */ jsx7("small", { className: "scui-session-noun", "data-noun": "participant", "data-kind": row.participant.kind, children: row.participant.kind === "foreign" ? `${row.participant.label ?? "someone else"}${row.participant.origin ? ` via ${row.participant.origin}` : ""}` : "unknown participant" }, "participant")
2581
+ );
2582
+ }
2583
+ if (row.mirror) {
2584
+ nounBadges.push(
2585
+ /* @__PURE__ */ jsxs6("small", { className: "scui-session-noun", "data-noun": "mirror", "data-truncated": row.mirror.truncated, children: [
2586
+ "mirror of ",
2587
+ harnessDisplayName(row.mirror.canonicalHarness)
2588
+ ] }, "mirror")
2589
+ );
2590
+ }
2591
+ if (row.workspaceRef?.kind === "channel") {
2592
+ nounBadges.push(
2593
+ /* @__PURE__ */ jsxs6("small", { className: "scui-session-noun", "data-noun": "workspace", "data-kind": "channel", children: [
2594
+ "#",
2595
+ row.workspaceRef.value ?? "channel"
2596
+ ] }, "workspace")
2597
+ );
2598
+ }
2599
+ return /* @__PURE__ */ jsxs6("article", { className: "scui-session", "data-active": row.active, "data-activity": activity, "data-writable": row.writable, "data-workspace-kind": row.workspaceRef?.kind, children: [
2282
2600
  /* @__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: [
2283
2601
  /* @__PURE__ */ jsx7(HarnessLogo, { id: row.harness, activity, size: 34 }),
2284
2602
  /* @__PURE__ */ jsxs6("span", { className: "scui-session-copy", children: [
2285
2603
  /* @__PURE__ */ jsx7("span", { className: "scui-session-title", children: /* @__PURE__ */ jsx7("strong", { children: title }) }),
2604
+ nounBadges.length ? /* @__PURE__ */ jsx7("span", { className: "scui-session-nouns", children: nounBadges }) : null,
2286
2605
  path.complete ? /* @__PURE__ */ jsxs6("small", { className: "scui-session-path", title: row.cwd, children: [
2287
2606
  /* @__PURE__ */ jsx7("span", { className: "scui-session-path-leading", children: path.leading }),
2288
2607
  path.separator ? /* @__PURE__ */ jsx7("span", { className: "scui-session-path-separator", children: path.separator }) : null,
@@ -2697,10 +3016,54 @@ function HarnessPicker({ harnesses, state, value, disabled = false, adapter, onC
2697
3016
 
2698
3017
  // src/messenger.jsx
2699
3018
  import { Fragment as Fragment5, jsx as jsx10, jsxs as jsxs9 } from "react/jsx-runtime";
2700
- var pendingMessageMemory = /* @__PURE__ */ new Map();
2701
- var messengerViewMemory = /* @__PURE__ */ new Map();
2702
- var newChatMemory = /* @__PURE__ */ new Map();
3019
+ var pendingMessageMemory = uiMemory();
3020
+ var messengerViewMemory = uiMemory();
3021
+ var newChatMemory = uiMemory();
2703
3022
  var TRACKED_ACTIONS = /* @__PURE__ */ new Set(["resume", "join", "detach", "branch", "reduce", "terminal", "export", "steer", "interrupt", "respond", "configureHarness", "refresh", "loadEarlier", "loadSessions"]);
3023
+ function UniversalNouns({ state, adapter }) {
3024
+ const banners = [];
3025
+ if (state.participant && state.participant.kind !== "local-user") {
3026
+ banners.push(
3027
+ /* @__PURE__ */ jsx10("div", { className: "scui-notice scui-noun-banner", "data-noun": "participant", "data-kind": state.participant.kind, children: state.participant.kind === "foreign" ? /* @__PURE__ */ jsxs9(Fragment5, { children: [
3028
+ "This is ",
3029
+ /* @__PURE__ */ jsx10("strong", { children: state.participant.label ?? "someone else's" }),
3030
+ " conversation",
3031
+ state.participant.origin ? /* @__PURE__ */ jsxs9(Fragment5, { children: [
3032
+ " via ",
3033
+ state.participant.origin
3034
+ ] }) : null,
3035
+ "."
3036
+ ] }) : /* @__PURE__ */ jsx10(Fragment5, { children: "Unknown participant \u2014 this conversation was not started here." }) }, "participant")
3037
+ );
3038
+ }
3039
+ if (state.mirror) {
3040
+ banners.push(
3041
+ /* @__PURE__ */ jsxs9("div", { className: "scui-notice scui-noun-banner", "data-noun": "mirror", "data-truncated": state.mirror.truncated, children: [
3042
+ state.mirror.bounded ? "Bounded mirror" : "Mirror",
3043
+ " of a ",
3044
+ /* @__PURE__ */ jsx10("strong", { children: harnessDisplayName(state.mirror.canonicalHarness) }),
3045
+ " session \u2014 the canonical record lives in its own store",
3046
+ state.mirror.truncated ? " (truncated here)" : "",
3047
+ ".",
3048
+ state.mirror.canonicalKey ? /* @__PURE__ */ jsx10("button", { type: "button", onClick: () => adapter.onIntent({ action: "open_session", key: state.mirror.canonicalKey }), children: "Open canonical session" }) : null
3049
+ ] }, "mirror")
3050
+ );
3051
+ }
3052
+ if (state.holder && state.holder.surface !== "supercode") {
3053
+ banners.push(
3054
+ /* @__PURE__ */ jsxs9("div", { className: "scui-notice scui-noun-banner", "data-noun": "holder", "data-surface": state.holder.surface ?? "unheld", children: [
3055
+ state.holder.surface ? /* @__PURE__ */ jsxs9(Fragment5, { children: [
3056
+ "Held by ",
3057
+ /* @__PURE__ */ jsx10("strong", { children: state.holder.surface }),
3058
+ " right now."
3059
+ ] }) : /* @__PURE__ */ jsx10(Fragment5, { children: "No surface holds this session right now." }),
3060
+ state.holder.canTakeOver ? /* @__PURE__ */ jsx10("button", { type: "button", onClick: () => dispatchConfirmedIntent(adapter, { action: "take_over" }), children: "Take over" }) : null
3061
+ ] }, "holder")
3062
+ );
3063
+ }
3064
+ if (!banners.length) return null;
3065
+ return /* @__PURE__ */ jsx10("div", { className: "scui-noun-banners", children: banners });
3066
+ }
2704
3067
  function Receipt({ state, adapter }) {
2705
3068
  const receipt = state.reductionReceipt;
2706
3069
  if (receipt) return /* @__PURE__ */ jsx10("div", { className: "scui-receipt", children: /* @__PURE__ */ jsxs9("span", { children: [
@@ -2964,6 +3327,7 @@ function Chat({ state, adapter, onBack, onNew, onClose, components, slots, label
2964
3327
  state.recoverable ? /* @__PURE__ */ jsx10("button", { type: "button", disabled: Boolean(action), onClick: () => trackedAdapter.onIntent({ action: "refresh" }), children: "Retry" }) : null
2965
3328
  ] }) : null,
2966
3329
  /* @__PURE__ */ jsx10(Receipt, { state, adapter }),
3330
+ /* @__PURE__ */ jsx10(UniversalNouns, { state: actionState, adapter: trackedAdapter }),
2967
3331
  /* @__PURE__ */ jsx10(Conversation, { state: actionState, adapter: trackedAdapter, components, slots, memoryKey, pending: pendingMessage, unreadAfterMessages }, memoryKey),
2968
3332
  /* @__PURE__ */ jsx10(ContinuationBar, { state: actionState, adapter: trackedAdapter, labels }),
2969
3333
  /* @__PURE__ */ jsx10(Advisory, { state: actionState, adapter: trackedAdapter, value: state.interopSettings?.advisories[0] ?? null, onReview: (recommendedChange) => setSettings({ recommendedChange }) }),