@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.
@@ -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
  function relativeAge(updatedAt, now = Date.now()) {
75
84
  if (typeof updatedAt !== "number" || !Number.isFinite(updatedAt) || updatedAt <= 0) return "";
@@ -155,7 +164,11 @@ function languageLabel(info) {
155
164
  }
156
165
  function frameCode(render, tokens, index, options, env, self) {
157
166
  const label = markdown.utils.escapeHtml(languageLabel(tokens[index]?.info ?? ""));
158
- 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>`;
167
+ const body = render(tokens, index, options, env, self).replace(
168
+ "<pre>",
169
+ `<pre tabindex="0" role="region" aria-label="${label} code">`
170
+ );
171
+ 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>`;
159
172
  }
160
173
  for (const kind of ["fence", "code_block"]) {
161
174
  const render = markdown.renderer.rules[kind];
@@ -170,6 +183,12 @@ markdown.renderer.rules.link_open = (tokens, index, options, env, self) => {
170
183
 
171
184
  // src/memory.js
172
185
  var MEMORY_LIMIT = 100;
186
+ var registry = /* @__PURE__ */ new Set();
187
+ function uiMemory() {
188
+ const map = /* @__PURE__ */ new Map();
189
+ registry.add(map);
190
+ return map;
191
+ }
173
192
  function boundedSet(map, key, value) {
174
193
  map.delete(key);
175
194
  map.set(key, value);
@@ -259,6 +278,7 @@ function LoadingStatus({ state, compact = false }) {
259
278
  /* @__PURE__ */ jsx4("span", { className: "scui-progress", "aria-hidden": "true", children: [1, 2, 3].map((step) => /* @__PURE__ */ jsx4("i", { "data-progress": step <= copy[2] ? "done" : step === copy[2] + 1 ? "current" : "waiting" }, step)) })
260
279
  ] });
261
280
  }
281
+ var conversationMemory = uiMemory();
262
282
 
263
283
  // src/logo.jsx
264
284
  import { useEffect as useEffect4 } from "react";
@@ -326,7 +346,7 @@ function HarnessLogo({ id, activity, size = 28, onMissingLogo }) {
326
346
 
327
347
  // src/sessions.jsx
328
348
  import { jsx as jsx6, jsxs as jsxs5 } from "react/jsx-runtime";
329
- var sessionListMemory = /* @__PURE__ */ new Map();
349
+ var sessionListMemory = uiMemory();
330
350
  function sessionPathParts(value) {
331
351
  const complete = String(value ?? "").replaceAll("\\", "/");
332
352
  const boundary = complete.lastIndexOf("/");
@@ -348,11 +368,55 @@ function SessionRow({ row, state, onOpen, onOpenSubagents, now = Date.now() }) {
348
368
  const unreadCount = attention?.unreadCount ?? 0;
349
369
  const unreadLabel = unreadCount > 99 ? "99+" : String(unreadCount);
350
370
  const age = relativeAge(row.previewUpdatedAt ?? row.updatedAt, now) || row.age;
351
- return /* @__PURE__ */ jsxs5("article", { className: "scui-session", "data-active": row.active, "data-activity": activity, "data-writable": row.writable, children: [
371
+ const nounBadges = [];
372
+ if (row.trigger && row.trigger.kind !== "manual" && row.trigger.kind !== "human") {
373
+ const runs = row.recurring?.runs;
374
+ const detail = row.trigger.label || row.trigger.surface || "";
375
+ nounBadges.push(
376
+ /* @__PURE__ */ jsxs5("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: [
377
+ row.trigger.kind,
378
+ detail ? ` \xB7 ${detail}` : "",
379
+ runs && runs > 1 ? ` \xB7 \xD7${runs}` : ""
380
+ ] }, "trigger")
381
+ );
382
+ }
383
+ if (row.crossSurface) {
384
+ nounBadges.push(
385
+ /* @__PURE__ */ jsxs5("small", { className: "scui-session-noun", "data-noun": "cross-surface", "data-state": row.crossSurface.state, title: row.crossSurface.error ?? void 0, children: [
386
+ "\u2192",
387
+ row.crossSurface.platform ?? "elsewhere",
388
+ " \xB7 ",
389
+ row.crossSurface.state
390
+ ] }, "cross-surface")
391
+ );
392
+ }
393
+ if (row.participant && row.participant.kind !== "local-user") {
394
+ nounBadges.push(
395
+ /* @__PURE__ */ jsx6("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")
396
+ );
397
+ }
398
+ if (row.mirror) {
399
+ nounBadges.push(
400
+ /* @__PURE__ */ jsxs5("small", { className: "scui-session-noun", "data-noun": "mirror", "data-truncated": row.mirror.truncated, children: [
401
+ "mirror of ",
402
+ harnessDisplayName(row.mirror.canonicalHarness)
403
+ ] }, "mirror")
404
+ );
405
+ }
406
+ if (row.workspaceRef?.kind === "channel") {
407
+ nounBadges.push(
408
+ /* @__PURE__ */ jsxs5("small", { className: "scui-session-noun", "data-noun": "workspace", "data-kind": "channel", children: [
409
+ "#",
410
+ row.workspaceRef.value ?? "channel"
411
+ ] }, "workspace")
412
+ );
413
+ }
414
+ return /* @__PURE__ */ jsxs5("article", { className: "scui-session", "data-active": row.active, "data-activity": activity, "data-writable": row.writable, "data-workspace-kind": row.workspaceRef?.kind, children: [
352
415
  /* @__PURE__ */ jsxs5("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: [
353
416
  /* @__PURE__ */ jsx6(HarnessLogo, { id: row.harness, activity, size: 34 }),
354
417
  /* @__PURE__ */ jsxs5("span", { className: "scui-session-copy", children: [
355
418
  /* @__PURE__ */ jsx6("span", { className: "scui-session-title", children: /* @__PURE__ */ jsx6("strong", { children: title }) }),
419
+ nounBadges.length ? /* @__PURE__ */ jsx6("span", { className: "scui-session-nouns", children: nounBadges }) : null,
356
420
  path.complete ? /* @__PURE__ */ jsxs5("small", { className: "scui-session-path", title: row.cwd, children: [
357
421
  /* @__PURE__ */ jsx6("span", { className: "scui-session-path-leading", children: path.leading }),
358
422
  path.separator ? /* @__PURE__ */ jsx6("span", { className: "scui-session-path-separator", children: path.separator }) : null,
@@ -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
  function harnessDisplayName(id) {
75
84
  return HARNESS_NAMES[id] ?? id;
@@ -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 TOOL_CATEGORIES = /* @__PURE__ */ new Set(["read", "search", "edit", "command", "test", "web", "agent", "plan", "other"]);
75
84
  var MAX_TOOL_FIELDS = 8;
@@ -537,7 +546,11 @@ function languageLabel(info) {
537
546
  }
538
547
  function frameCode(render, tokens, index, options, env, self) {
539
548
  const label = markdown.utils.escapeHtml(languageLabel(tokens[index]?.info ?? ""));
540
- 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>`;
549
+ const body = render(tokens, index, options, env, self).replace(
550
+ "<pre>",
551
+ `<pre tabindex="0" role="region" aria-label="${label} code">`
552
+ );
553
+ 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>`;
541
554
  }
542
555
  for (const kind of ["fence", "code_block"]) {
543
556
  const render = markdown.renderer.rules[kind];
@@ -595,6 +608,12 @@ function Markdown({ value, copyText }) {
595
608
 
596
609
  // src/memory.js
597
610
  var MEMORY_LIMIT = 100;
611
+ var registry = /* @__PURE__ */ new Set();
612
+ function uiMemory() {
613
+ const map = /* @__PURE__ */ new Map();
614
+ registry.add(map);
615
+ return map;
616
+ }
598
617
  function boundedSet(map, key, value) {
599
618
  map.delete(key);
600
619
  map.set(key, value);
@@ -1098,6 +1117,26 @@ function TechnicalDetails({ entry }) {
1098
1117
  ] });
1099
1118
  }
1100
1119
  function TranscriptEntry({ entry, state, adapter }) {
1120
+ if (entry.role === "opaque") {
1121
+ return /* @__PURE__ */ jsxs3("article", { className: "scui-message scui-opaque", "data-role": "opaque", "data-kind": entry.kind, "aria-label": "Unrecognized entry", children: [
1122
+ /* @__PURE__ */ jsxs3("div", { className: "scui-notice", "data-code": "opaque-entry", children: [
1123
+ "Unrecognized entry kind ",
1124
+ /* @__PURE__ */ jsx4("code", { children: entry.kind }),
1125
+ " \u2014 kept as-is, nothing dropped"
1126
+ ] }),
1127
+ entry.text ? /* @__PURE__ */ jsx4(Markdown, { value: entry.text, copyText: adapter?.copyText }) : null,
1128
+ entry.raw ? /* @__PURE__ */ jsxs3("details", { className: "scui-tool-technical", children: [
1129
+ /* @__PURE__ */ jsx4("summary", { children: "Technical details" }),
1130
+ /* @__PURE__ */ jsx4("div", { children: /* @__PURE__ */ jsxs3("section", { children: [
1131
+ /* @__PURE__ */ jsx4("strong", { children: "Raw entry" }),
1132
+ /* @__PURE__ */ jsxs3("pre", { children: [
1133
+ entry.raw,
1134
+ entry.truncated ? "\n[truncated]" : ""
1135
+ ] })
1136
+ ] }) })
1137
+ ] }) : null
1138
+ ] });
1139
+ }
1101
1140
  if (entry.role === "request") return /* @__PURE__ */ jsx4(RequestCard, { entry, adapter, canRespond: state.canRespond });
1102
1141
  if (entry.role === "reasoning") {
1103
1142
  return /* @__PURE__ */ jsxs3("details", { className: "scui-reasoning", open: entry.streaming, children: [
@@ -1227,7 +1266,7 @@ function SessionDetails({ semantics }) {
1227
1266
  ] })
1228
1267
  ] });
1229
1268
  }
1230
- var conversationMemory = /* @__PURE__ */ new Map();
1269
+ var conversationMemory = uiMemory();
1231
1270
  function ConversationAnnouncements({ state }) {
1232
1271
  const previousBusy = useRef3(state.busy);
1233
1272
  const [announcement, setAnnouncement] = useState2("");
package/sessions.mjs CHANGED
@@ -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
  function relativeAge(updatedAt, now = Date.now()) {
75
84
  if (typeof updatedAt !== "number" || !Number.isFinite(updatedAt) || updatedAt <= 0) return "";
@@ -155,7 +164,11 @@ function languageLabel(info) {
155
164
  }
156
165
  function frameCode(render, tokens, index, options, env, self) {
157
166
  const label = markdown.utils.escapeHtml(languageLabel(tokens[index]?.info ?? ""));
158
- 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>`;
167
+ const body = render(tokens, index, options, env, self).replace(
168
+ "<pre>",
169
+ `<pre tabindex="0" role="region" aria-label="${label} code">`
170
+ );
171
+ 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>`;
159
172
  }
160
173
  for (const kind of ["fence", "code_block"]) {
161
174
  const render = markdown.renderer.rules[kind];
@@ -170,6 +183,12 @@ markdown.renderer.rules.link_open = (tokens, index, options, env, self) => {
170
183
 
171
184
  // src/memory.js
172
185
  var MEMORY_LIMIT = 100;
186
+ var registry = /* @__PURE__ */ new Set();
187
+ function uiMemory() {
188
+ const map = /* @__PURE__ */ new Map();
189
+ registry.add(map);
190
+ return map;
191
+ }
173
192
  function boundedSet(map, key, value) {
174
193
  map.delete(key);
175
194
  map.set(key, value);
@@ -259,6 +278,7 @@ function LoadingStatus({ state, compact = false }) {
259
278
  /* @__PURE__ */ jsx4("span", { className: "scui-progress", "aria-hidden": "true", children: [1, 2, 3].map((step) => /* @__PURE__ */ jsx4("i", { "data-progress": step <= copy[2] ? "done" : step === copy[2] + 1 ? "current" : "waiting" }, step)) })
260
279
  ] });
261
280
  }
281
+ var conversationMemory = uiMemory();
262
282
 
263
283
  // src/logo.jsx
264
284
  import { useEffect as useEffect4 } from "preact/hooks";
@@ -326,7 +346,7 @@ function HarnessLogo({ id, activity, size = 28, onMissingLogo }) {
326
346
 
327
347
  // src/sessions.jsx
328
348
  import { jsx as jsx6, jsxs as jsxs5 } from "preact/jsx-runtime";
329
- var sessionListMemory = /* @__PURE__ */ new Map();
349
+ var sessionListMemory = uiMemory();
330
350
  function sessionPathParts(value) {
331
351
  const complete = String(value ?? "").replaceAll("\\", "/");
332
352
  const boundary = complete.lastIndexOf("/");
@@ -348,11 +368,55 @@ function SessionRow({ row, state, onOpen, onOpenSubagents, now = Date.now() }) {
348
368
  const unreadCount = attention?.unreadCount ?? 0;
349
369
  const unreadLabel = unreadCount > 99 ? "99+" : String(unreadCount);
350
370
  const age = relativeAge(row.previewUpdatedAt ?? row.updatedAt, now) || row.age;
351
- return /* @__PURE__ */ jsxs5("article", { className: "scui-session", "data-active": row.active, "data-activity": activity, "data-writable": row.writable, children: [
371
+ const nounBadges = [];
372
+ if (row.trigger && row.trigger.kind !== "manual" && row.trigger.kind !== "human") {
373
+ const runs = row.recurring?.runs;
374
+ const detail = row.trigger.label || row.trigger.surface || "";
375
+ nounBadges.push(
376
+ /* @__PURE__ */ jsxs5("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: [
377
+ row.trigger.kind,
378
+ detail ? ` \xB7 ${detail}` : "",
379
+ runs && runs > 1 ? ` \xB7 \xD7${runs}` : ""
380
+ ] }, "trigger")
381
+ );
382
+ }
383
+ if (row.crossSurface) {
384
+ nounBadges.push(
385
+ /* @__PURE__ */ jsxs5("small", { className: "scui-session-noun", "data-noun": "cross-surface", "data-state": row.crossSurface.state, title: row.crossSurface.error ?? void 0, children: [
386
+ "\u2192",
387
+ row.crossSurface.platform ?? "elsewhere",
388
+ " \xB7 ",
389
+ row.crossSurface.state
390
+ ] }, "cross-surface")
391
+ );
392
+ }
393
+ if (row.participant && row.participant.kind !== "local-user") {
394
+ nounBadges.push(
395
+ /* @__PURE__ */ jsx6("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")
396
+ );
397
+ }
398
+ if (row.mirror) {
399
+ nounBadges.push(
400
+ /* @__PURE__ */ jsxs5("small", { className: "scui-session-noun", "data-noun": "mirror", "data-truncated": row.mirror.truncated, children: [
401
+ "mirror of ",
402
+ harnessDisplayName(row.mirror.canonicalHarness)
403
+ ] }, "mirror")
404
+ );
405
+ }
406
+ if (row.workspaceRef?.kind === "channel") {
407
+ nounBadges.push(
408
+ /* @__PURE__ */ jsxs5("small", { className: "scui-session-noun", "data-noun": "workspace", "data-kind": "channel", children: [
409
+ "#",
410
+ row.workspaceRef.value ?? "channel"
411
+ ] }, "workspace")
412
+ );
413
+ }
414
+ return /* @__PURE__ */ jsxs5("article", { className: "scui-session", "data-active": row.active, "data-activity": activity, "data-writable": row.writable, "data-workspace-kind": row.workspaceRef?.kind, children: [
352
415
  /* @__PURE__ */ jsxs5("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: [
353
416
  /* @__PURE__ */ jsx6(HarnessLogo, { id: row.harness, activity, size: 34 }),
354
417
  /* @__PURE__ */ jsxs5("span", { className: "scui-session-copy", children: [
355
418
  /* @__PURE__ */ jsx6("span", { className: "scui-session-title", children: /* @__PURE__ */ jsx6("strong", { children: title }) }),
419
+ nounBadges.length ? /* @__PURE__ */ jsx6("span", { className: "scui-session-nouns", children: nounBadges }) : null,
356
420
  path.complete ? /* @__PURE__ */ jsxs5("small", { className: "scui-session-path", title: row.cwd, children: [
357
421
  /* @__PURE__ */ jsx6("span", { className: "scui-session-path-leading", children: path.leading }),
358
422
  path.separator ? /* @__PURE__ */ jsx6("span", { className: "scui-session-path-separator", children: path.separator }) : null,
package/settings.mjs CHANGED
@@ -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
  function harnessDisplayName(id) {
75
84
  return HARNESS_NAMES[id] ?? id;
package/styles.css CHANGED
@@ -145,7 +145,8 @@
145
145
  .scui-pending[data-status="failed"] { border-color:color-mix(in srgb,var(--scui-danger) 45%,var(--scui-border)); background:color-mix(in srgb,var(--scui-danger) 7%,var(--scui-fill)); opacity:1 }
146
146
  .scui-pending > footer { display:flex; align-items:center; gap:8px; margin-top:5px }.scui-pending > footer small { color:var(--scui-muted) }.scui-pending[data-status="failed"] > footer small { color:var(--scui-danger) }
147
147
  .scui-pending > footer > span { display:flex; gap:4px; margin-left:auto }.scui-pending > footer button { padding:2px 6px; border:1px solid var(--scui-border-strong); border-radius:5px; background:transparent; color:var(--scui-fg); cursor:pointer; font:inherit; font-size:9.5px }
148
- .scui-pending { opacity:.7 }.scui-pending > small { display:block; margin-top:3px; color:var(--scui-muted); font-size:9.5px }
148
+ /* Muted color, not opacity: opacity crushed the footer text below the 4.5:1 contrast floor (axe color-contrast). */
149
+ .scui-pending { color:var(--scui-muted) }.scui-pending > small { display:block; margin-top:3px; color:var(--scui-muted); font-size:9.5px }
149
150
  .scui-markdown { min-width:0; font-size:12.5px; line-height:1.55 }.scui-markdown > :first-child { margin-top:0 }.scui-markdown > :last-child { margin-bottom:0 }
150
151
  .scui-markdown p { margin:0 0 8px }.scui-markdown h1,.scui-markdown h2,.scui-markdown h3 { margin:12px 0 5px; line-height:1.25 }.scui-markdown h1 { font-size:17px }.scui-markdown h2 { font-size:15px }.scui-markdown h3 { font-size:13px }
151
152
  .scui-markdown ul,.scui-markdown ol { margin:5px 0 9px; padding-left:20px }.scui-markdown blockquote { margin:8px 0; padding-left:9px; border-left:2px solid var(--scui-border-strong); color:var(--scui-muted) }
@@ -163,6 +164,15 @@
163
164
  .scui-context p,.scui-details p { display:grid; margin:0 }.scui-context strong,.scui-details strong { color:var(--scui-fg) }
164
165
  .scui-truncated { display:block; margin-top:5px; color:var(--scui-warning) }
165
166
  .scui-notice { align-self:center; max-width:90%; padding:5px 8px; border-radius:7px; background:var(--scui-bg-raised); color:var(--scui-muted); font-size:10.5px; text-align:center }
167
+ .scui-noun-banners { display:grid; gap:4px; padding:6px 8px 0 }
168
+ .scui-noun-banner { display:flex; align-items:center; justify-content:center; gap:8px; align-self:center; max-width:92%; margin:0 auto }
169
+ .scui-noun-banner strong { color:var(--scui-fg) }
170
+ .scui-noun-banner button { flex:none; padding:3px 8px; border:1px solid var(--scui-border-strong); border-radius:6px; background:var(--scui-bg); color:var(--scui-fg); cursor:pointer; font-size:10.5px }
171
+ .scui-noun-banner button:hover { background:var(--scui-fill) }
172
+ .scui-session-nouns { display:flex; flex-wrap:wrap; gap:4px }
173
+ .scui-session-noun { padding:0 5px; border:1px solid var(--scui-border); border-radius:5px; color:var(--scui-muted); font-size:9.5px; line-height:15px; white-space:nowrap }
174
+ .scui-session-noun[data-noun="trigger"][data-status="failed"] { border-color:color-mix(in srgb,var(--scui-danger) 48%,var(--scui-border)); color:var(--scui-danger) }
175
+ .scui-session-noun[data-noun="mirror"] { font-style:italic }
166
176
  .scui-unread-divider { display:flex; align-items:center; gap:7px; color:var(--scui-accent); font-size:9.5px; font-weight:650 }.scui-unread-divider::before,.scui-unread-divider::after { content:""; flex:1; height:1px; background:color-mix(in srgb,var(--scui-accent) 45%,var(--scui-border)) }.scui-unread-divider span { flex:none }
167
177
 
168
178
  .scui-activity { min-width:0; color:var(--scui-muted) }
package/subagents.mjs CHANGED
@@ -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 TOOL_CATEGORIES = /* @__PURE__ */ new Set(["read", "search", "edit", "command", "test", "web", "agent", "plan", "other"]);
75
84
  var MAX_TOOL_FIELDS = 8;
@@ -537,7 +546,11 @@ function languageLabel(info) {
537
546
  }
538
547
  function frameCode(render, tokens, index, options, env, self) {
539
548
  const label = markdown.utils.escapeHtml(languageLabel(tokens[index]?.info ?? ""));
540
- 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>`;
549
+ const body = render(tokens, index, options, env, self).replace(
550
+ "<pre>",
551
+ `<pre tabindex="0" role="region" aria-label="${label} code">`
552
+ );
553
+ 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>`;
541
554
  }
542
555
  for (const kind of ["fence", "code_block"]) {
543
556
  const render = markdown.renderer.rules[kind];
@@ -595,6 +608,12 @@ function Markdown({ value, copyText }) {
595
608
 
596
609
  // src/memory.js
597
610
  var MEMORY_LIMIT = 100;
611
+ var registry = /* @__PURE__ */ new Set();
612
+ function uiMemory() {
613
+ const map = /* @__PURE__ */ new Map();
614
+ registry.add(map);
615
+ return map;
616
+ }
598
617
  function boundedSet(map, key, value) {
599
618
  map.delete(key);
600
619
  map.set(key, value);
@@ -1098,6 +1117,26 @@ function TechnicalDetails({ entry }) {
1098
1117
  ] });
1099
1118
  }
1100
1119
  function TranscriptEntry({ entry, state, adapter }) {
1120
+ if (entry.role === "opaque") {
1121
+ return /* @__PURE__ */ jsxs3("article", { className: "scui-message scui-opaque", "data-role": "opaque", "data-kind": entry.kind, "aria-label": "Unrecognized entry", children: [
1122
+ /* @__PURE__ */ jsxs3("div", { className: "scui-notice", "data-code": "opaque-entry", children: [
1123
+ "Unrecognized entry kind ",
1124
+ /* @__PURE__ */ jsx4("code", { children: entry.kind }),
1125
+ " \u2014 kept as-is, nothing dropped"
1126
+ ] }),
1127
+ entry.text ? /* @__PURE__ */ jsx4(Markdown, { value: entry.text, copyText: adapter?.copyText }) : null,
1128
+ entry.raw ? /* @__PURE__ */ jsxs3("details", { className: "scui-tool-technical", children: [
1129
+ /* @__PURE__ */ jsx4("summary", { children: "Technical details" }),
1130
+ /* @__PURE__ */ jsx4("div", { children: /* @__PURE__ */ jsxs3("section", { children: [
1131
+ /* @__PURE__ */ jsx4("strong", { children: "Raw entry" }),
1132
+ /* @__PURE__ */ jsxs3("pre", { children: [
1133
+ entry.raw,
1134
+ entry.truncated ? "\n[truncated]" : ""
1135
+ ] })
1136
+ ] }) })
1137
+ ] }) : null
1138
+ ] });
1139
+ }
1101
1140
  if (entry.role === "request") return /* @__PURE__ */ jsx4(RequestCard, { entry, adapter, canRespond: state.canRespond });
1102
1141
  if (entry.role === "reasoning") {
1103
1142
  return /* @__PURE__ */ jsxs3("details", { className: "scui-reasoning", open: entry.streaming, children: [
@@ -1227,7 +1266,7 @@ function SessionDetails({ semantics }) {
1227
1266
  ] })
1228
1267
  ] });
1229
1268
  }
1230
- var conversationMemory = /* @__PURE__ */ new Map();
1269
+ var conversationMemory = uiMemory();
1231
1270
  function ConversationAnnouncements({ state }) {
1232
1271
  const previousBusy = useRef3(state.busy);
1233
1272
  const [announcement, setAnnouncement] = useState2("");