@volter-ai-dev/supercode-ui 0.1.47 → 0.1.49

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 CHANGED
@@ -32,9 +32,12 @@ var EMPTY_UI_STATE = Object.freeze({
32
32
  canSend: false,
33
33
  canSteer: false,
34
34
  canResume: false,
35
+ supportsResume: false,
35
36
  continuationModes: Object.freeze([]),
36
37
  canBranch: false,
38
+ supportsBranch: false,
37
39
  canAttach: false,
40
+ supportsAttach: false,
38
41
  canDetach: false,
39
42
  canOpenTerminal: false,
40
43
  canExport: false,
@@ -712,9 +715,12 @@ function normalizeUiState(value) {
712
715
  canSend: raw.canSend === true,
713
716
  canSteer: raw.canSteer === true,
714
717
  canResume,
718
+ supportsResume: raw.supportsResume === true,
715
719
  continuationModes,
716
720
  canBranch: raw.canBranch === true,
721
+ supportsBranch: raw.supportsBranch === true,
717
722
  canAttach: raw.canAttach === true,
723
+ supportsAttach: raw.supportsAttach === true,
718
724
  canDetach: raw.canDetach === true,
719
725
  canOpenTerminal: raw.canOpenTerminal === true,
720
726
  canExport: raw.canExport === true,
package/components.mjs CHANGED
@@ -35,9 +35,12 @@ var EMPTY_UI_STATE = Object.freeze({
35
35
  canSend: false,
36
36
  canSteer: false,
37
37
  canResume: false,
38
+ supportsResume: false,
38
39
  continuationModes: Object.freeze([]),
39
40
  canBranch: false,
41
+ supportsBranch: false,
40
42
  canAttach: false,
43
+ supportsAttach: false,
41
44
  canDetach: false,
42
45
  canOpenTerminal: false,
43
46
  canExport: false,
@@ -724,9 +727,12 @@ function normalizeUiState(value) {
724
727
  canSend: raw.canSend === true,
725
728
  canSteer: raw.canSteer === true,
726
729
  canResume,
730
+ supportsResume: raw.supportsResume === true,
727
731
  continuationModes,
728
732
  canBranch: raw.canBranch === true,
733
+ supportsBranch: raw.supportsBranch === true,
729
734
  canAttach: raw.canAttach === true,
735
+ supportsAttach: raw.supportsAttach === true,
730
736
  canDetach: raw.canDetach === true,
731
737
  canOpenTerminal: raw.canOpenTerminal === true,
732
738
  canExport: raw.canExport === true,
@@ -1314,21 +1320,25 @@ function ContinuationBar({ state, adapter, labels = DEFAULT_LABELS }) {
1314
1320
  const attached = state.attached;
1315
1321
  const row = attached?.key ? state.sessions.find((item) => item.key === attached.key) : null;
1316
1322
  const activeElsewhere = row?.runtimeStatus === "running" || row?.runtimeStatus === "busy" || row?.runtimeStatus === "idle";
1317
- const resume = canContinueHere(state);
1318
- const join = state.canAttach;
1319
- const branch = state.canBranch;
1320
- if (!resume && !join && !branch) return /* @__PURE__ */ jsx3("div", { className: "scui-continuation", children: /* @__PURE__ */ jsxs3("span", { children: [
1323
+ const available = {
1324
+ resume: canContinueHere(state),
1325
+ join: state.canAttach,
1326
+ branch: state.canBranch
1327
+ };
1328
+ const continuation = state.supportsAttach ? "join" : state.supportsResume ? "resume" : state.supportsBranch ? "branch" : available.join ? "join" : available.resume ? "resume" : available.branch ? "branch" : null;
1329
+ if (!continuation) return /* @__PURE__ */ jsx3("div", { className: "scui-continuation", children: /* @__PURE__ */ jsxs3("span", { children: [
1321
1330
  /* @__PURE__ */ jsx3("strong", { children: activeElsewhere ? "Active elsewhere" : "Read-only" }),
1322
1331
  /* @__PURE__ */ jsx3("small", { children: "This session cannot be continued by an available harness." })
1323
1332
  ] }) });
1333
+ const enabled = available[continuation];
1324
1334
  return /* @__PURE__ */ jsxs3("div", { className: "scui-continuation", children: [
1325
1335
  /* @__PURE__ */ jsxs3("span", { children: [
1326
1336
  /* @__PURE__ */ jsx3("strong", { children: activeElsewhere ? "Active elsewhere" : "Read-only" }),
1327
- /* @__PURE__ */ jsx3("small", { children: join ? "Join the proven live runtime without taking it over." : resume ? `Resume this ${harnessDisplayName(state.harness)} session here.` : "Start an independent continuation." })
1337
+ /* @__PURE__ */ jsx3("small", { children: continuation === "join" ? "Join the proven live runtime without taking it over." : continuation === "resume" ? `Resume this ${harnessDisplayName(state.harness)} session here.` : "Start an independent continuation." })
1328
1338
  ] }),
1329
1339
  /* @__PURE__ */ jsxs3("span", { className: "scui-continuation-actions", children: [
1330
- !join && resume ? /* @__PURE__ */ jsx3(ExecutionModeSelect, { modes: continuationModes, value: executionMode, disabled: Boolean(state.operation), onChange: (mode) => setSelection({ key: state.attached?.key ?? null, mode }) }) : null,
1331
- /* @__PURE__ */ jsx3("button", { type: "button", disabled: Boolean(state.operation), onClick: () => dispatchConfirmedIntent(adapter, join ? { action: "join" } : resume ? { action: "resume", mode: executionMode } : { action: "branch" }), children: join ? labels.joinLive : resume ? labels.continueHere : labels.forkHere })
1340
+ continuation === "resume" ? /* @__PURE__ */ jsx3(ExecutionModeSelect, { modes: continuationModes, value: executionMode, disabled: Boolean(state.operation) || !enabled, onChange: (mode) => setSelection({ key: state.attached?.key ?? null, mode }) }) : null,
1341
+ /* @__PURE__ */ jsx3("button", { type: "button", disabled: Boolean(state.operation) || !enabled, onClick: () => dispatchConfirmedIntent(adapter, continuation === "join" ? { action: "join" } : continuation === "resume" ? { action: "resume", mode: executionMode } : { action: "branch" }), children: continuation === "join" ? labels.joinLive : continuation === "resume" ? labels.continueHere : labels.forkHere })
1332
1342
  ] })
1333
1343
  ] });
1334
1344
  }
@@ -2716,8 +2726,8 @@ function ChatHeader({ state, adapter, pendingStatus, actionPending, onBack, onNe
2716
2726
  if (state.mode === "mirror" && !state.canSend) back.current?.focus({ preventScroll: true });
2717
2727
  }, []);
2718
2728
  return /* @__PURE__ */ jsxs9("header", { className: "scui-head scui-chat-head", children: [
2719
- /* @__PURE__ */ jsx10("button", { ref: back, type: "button", "aria-label": "Back to chats", onClick: onBack, children: /* @__PURE__ */ jsx10(UiIcon, { name: "back", size: 18 }) }),
2720
- /* @__PURE__ */ jsx10(HarnessLogo, { id: harness, size: 28 }),
2729
+ /* @__PURE__ */ jsx10("button", { ref: back, type: "button", "aria-label": "Back to chats", onClick: onBack, children: /* @__PURE__ */ jsx10(UiIcon, { name: "back", size: 17 }) }),
2730
+ /* @__PURE__ */ jsx10(HarnessLogo, { id: harness, size: 24 }),
2721
2731
  /* @__PURE__ */ jsxs9("span", { className: "scui-head-copy", children: [
2722
2732
  /* @__PURE__ */ jsx10("strong", { children: title }),
2723
2733
  /* @__PURE__ */ jsxs9("small", { children: [
package/composer.mjs CHANGED
@@ -35,9 +35,12 @@ var EMPTY_UI_STATE = Object.freeze({
35
35
  canSend: false,
36
36
  canSteer: false,
37
37
  canResume: false,
38
+ supportsResume: false,
38
39
  continuationModes: Object.freeze([]),
39
40
  canBranch: false,
41
+ supportsBranch: false,
40
42
  canAttach: false,
43
+ supportsAttach: false,
41
44
  canDetach: false,
42
45
  canOpenTerminal: false,
43
46
  canExport: false,
@@ -311,21 +314,25 @@ function ContinuationBar({ state, adapter, labels = DEFAULT_LABELS }) {
311
314
  const attached = state.attached;
312
315
  const row = attached?.key ? state.sessions.find((item) => item.key === attached.key) : null;
313
316
  const activeElsewhere = row?.runtimeStatus === "running" || row?.runtimeStatus === "busy" || row?.runtimeStatus === "idle";
314
- const resume = canContinueHere(state);
315
- const join = state.canAttach;
316
- const branch = state.canBranch;
317
- if (!resume && !join && !branch) return /* @__PURE__ */ jsx3("div", { className: "scui-continuation", children: /* @__PURE__ */ jsxs3("span", { children: [
317
+ const available = {
318
+ resume: canContinueHere(state),
319
+ join: state.canAttach,
320
+ branch: state.canBranch
321
+ };
322
+ const continuation = state.supportsAttach ? "join" : state.supportsResume ? "resume" : state.supportsBranch ? "branch" : available.join ? "join" : available.resume ? "resume" : available.branch ? "branch" : null;
323
+ if (!continuation) return /* @__PURE__ */ jsx3("div", { className: "scui-continuation", children: /* @__PURE__ */ jsxs3("span", { children: [
318
324
  /* @__PURE__ */ jsx3("strong", { children: activeElsewhere ? "Active elsewhere" : "Read-only" }),
319
325
  /* @__PURE__ */ jsx3("small", { children: "This session cannot be continued by an available harness." })
320
326
  ] }) });
327
+ const enabled = available[continuation];
321
328
  return /* @__PURE__ */ jsxs3("div", { className: "scui-continuation", children: [
322
329
  /* @__PURE__ */ jsxs3("span", { children: [
323
330
  /* @__PURE__ */ jsx3("strong", { children: activeElsewhere ? "Active elsewhere" : "Read-only" }),
324
- /* @__PURE__ */ jsx3("small", { children: join ? "Join the proven live runtime without taking it over." : resume ? `Resume this ${harnessDisplayName(state.harness)} session here.` : "Start an independent continuation." })
331
+ /* @__PURE__ */ jsx3("small", { children: continuation === "join" ? "Join the proven live runtime without taking it over." : continuation === "resume" ? `Resume this ${harnessDisplayName(state.harness)} session here.` : "Start an independent continuation." })
325
332
  ] }),
326
333
  /* @__PURE__ */ jsxs3("span", { className: "scui-continuation-actions", children: [
327
- !join && resume ? /* @__PURE__ */ jsx3(ExecutionModeSelect, { modes: continuationModes, value: executionMode, disabled: Boolean(state.operation), onChange: (mode) => setSelection({ key: state.attached?.key ?? null, mode }) }) : null,
328
- /* @__PURE__ */ jsx3("button", { type: "button", disabled: Boolean(state.operation), onClick: () => dispatchConfirmedIntent(adapter, join ? { action: "join" } : resume ? { action: "resume", mode: executionMode } : { action: "branch" }), children: join ? labels.joinLive : resume ? labels.continueHere : labels.forkHere })
334
+ continuation === "resume" ? /* @__PURE__ */ jsx3(ExecutionModeSelect, { modes: continuationModes, value: executionMode, disabled: Boolean(state.operation) || !enabled, onChange: (mode) => setSelection({ key: state.attached?.key ?? null, mode }) }) : null,
335
+ /* @__PURE__ */ jsx3("button", { type: "button", disabled: Boolean(state.operation) || !enabled, onClick: () => dispatchConfirmedIntent(adapter, continuation === "join" ? { action: "join" } : continuation === "resume" ? { action: "resume", mode: executionMode } : { action: "branch" }), children: continuation === "join" ? labels.joinLive : continuation === "resume" ? labels.continueHere : labels.forkHere })
329
336
  ] })
330
337
  ] });
331
338
  }
package/controller.mjs CHANGED
@@ -436,6 +436,10 @@ function projectClientSnapshotInternal(snapshot, options, imageRegistry) {
436
436
  const now = Number.isFinite(options.now) ? options.now : Date.now();
437
437
  const busy = ['running', 'interrupting', 'reconciling'].includes(snapshot.turn?.state);
438
438
  const actions = snapshot.availableActions ?? {};
439
+ // Older clients did not expose operation-independent eligibility. Falling
440
+ // back preserves compatibility; current clients keep stable UI capability
441
+ // copy while an action temporarily makes every executable action false.
442
+ const eligibility = snapshot.actionEligibility ?? actions;
439
443
  const maxSessions = positiveInteger(options.maxSessions, DEFAULT_MAX_SESSIONS);
440
444
  const liveWindowMs = positiveInteger(options.liveWindowMs, DEFAULT_LIVE_WINDOW_MS);
441
445
  const snapshotSessions = (snapshot.sessions ?? []).slice(0, maxSessions).map((session) => ({
@@ -475,9 +479,12 @@ function projectClientSnapshotInternal(snapshot, options, imageRegistry) {
475
479
  canSend: actions.send === true,
476
480
  canSteer: actions.steer === true,
477
481
  canResume: actions.resume === true,
478
- continuationModes: options.continuationModes ?? (actions.resume === true ? ['headless'] : []),
482
+ supportsResume: eligibility.resume === true,
483
+ continuationModes: options.continuationModes ?? (eligibility.resume === true ? ['headless'] : []),
479
484
  canBranch: actions.branch === true,
485
+ supportsBranch: eligibility.branch === true,
480
486
  canAttach: actions.attach === true,
487
+ supportsAttach: eligibility.attach === true,
481
488
  canDetach: actions.detach === true,
482
489
  canOpenTerminal: actions.openTerminal === true,
483
490
  canExport: Boolean(options.exportBackTarget && snapshot.activeSessionKey),
@@ -517,13 +524,13 @@ function projectClientSnapshotInternal(snapshot, options, imageRegistry) {
517
524
  protocol: harness.protocol,
518
525
  repair: harness.repair ?? null,
519
526
  capabilities: {
520
- start: harness.availableActions?.start === true,
521
- resume: harness.availableActions?.resume === true,
522
- attach: harness.availableActions?.attach === true,
523
- send: harness.availableActions?.send === true,
524
- interrupt: harness.availableActions?.interrupt === true,
525
- steer: harness.availableActions?.steer === true,
526
- respond: harness.availableActions?.respond === true,
527
+ start: (harness.effective_capabilities ?? harness.capabilities)?.start_session === true,
528
+ resume: (harness.effective_capabilities ?? harness.capabilities)?.resume_session === true,
529
+ attach: (harness.effective_capabilities ?? harness.capabilities)?.attach_existing_process === true,
530
+ send: (harness.effective_capabilities ?? harness.capabilities)?.send_input === true,
531
+ interrupt: (harness.effective_capabilities ?? harness.capabilities)?.interrupt === true,
532
+ steer: (harness.effective_capabilities ?? harness.capabilities)?.steer === true,
533
+ respond: (harness.effective_capabilities ?? harness.capabilities)?.respond_to_requests === true,
527
534
  },
528
535
  })),
529
536
  history: {
package/conversation.mjs CHANGED
@@ -36,9 +36,12 @@ var EMPTY_UI_STATE = Object.freeze({
36
36
  canSend: false,
37
37
  canSteer: false,
38
38
  canResume: false,
39
+ supportsResume: false,
39
40
  continuationModes: Object.freeze([]),
40
41
  canBranch: false,
42
+ supportsBranch: false,
41
43
  canAttach: false,
44
+ supportsAttach: false,
42
45
  canDetach: false,
43
46
  canOpenTerminal: false,
44
47
  canExport: false,
package/core.mjs CHANGED
@@ -33,9 +33,12 @@ export const EMPTY_UI_STATE = Object.freeze({
33
33
  canSend: false,
34
34
  canSteer: false,
35
35
  canResume: false,
36
+ supportsResume: false,
36
37
  continuationModes: Object.freeze([]),
37
38
  canBranch: false,
39
+ supportsBranch: false,
38
40
  canAttach: false,
41
+ supportsAttach: false,
39
42
  canDetach: false,
40
43
  canOpenTerminal: false,
41
44
  canExport: false,
@@ -776,9 +779,12 @@ export function normalizeUiState(value) {
776
779
  canSend: raw.canSend === true,
777
780
  canSteer: raw.canSteer === true,
778
781
  canResume,
782
+ supportsResume: raw.supportsResume === true,
779
783
  continuationModes,
780
784
  canBranch: raw.canBranch === true,
785
+ supportsBranch: raw.supportsBranch === true,
781
786
  canAttach: raw.canAttach === true,
787
+ supportsAttach: raw.supportsAttach === true,
782
788
  canDetach: raw.canDetach === true,
783
789
  canOpenTerminal: raw.canOpenTerminal === true,
784
790
  canExport: raw.canExport === true,
package/embed.mjs CHANGED
@@ -38,9 +38,12 @@ var EMPTY_UI_STATE = Object.freeze({
38
38
  canSend: false,
39
39
  canSteer: false,
40
40
  canResume: false,
41
+ supportsResume: false,
41
42
  continuationModes: Object.freeze([]),
42
43
  canBranch: false,
44
+ supportsBranch: false,
43
45
  canAttach: false,
46
+ supportsAttach: false,
44
47
  canDetach: false,
45
48
  canOpenTerminal: false,
46
49
  canExport: false,
@@ -727,9 +730,12 @@ function normalizeUiState(value) {
727
730
  canSend: raw.canSend === true,
728
731
  canSteer: raw.canSteer === true,
729
732
  canResume,
733
+ supportsResume: raw.supportsResume === true,
730
734
  continuationModes,
731
735
  canBranch: raw.canBranch === true,
736
+ supportsBranch: raw.supportsBranch === true,
732
737
  canAttach: raw.canAttach === true,
738
+ supportsAttach: raw.supportsAttach === true,
733
739
  canDetach: raw.canDetach === true,
734
740
  canOpenTerminal: raw.canOpenTerminal === true,
735
741
  canExport: raw.canExport === true,
@@ -1277,21 +1283,25 @@ function ContinuationBar({ state, adapter, labels = DEFAULT_LABELS }) {
1277
1283
  const attached = state.attached;
1278
1284
  const row = attached?.key ? state.sessions.find((item) => item.key === attached.key) : null;
1279
1285
  const activeElsewhere = row?.runtimeStatus === "running" || row?.runtimeStatus === "busy" || row?.runtimeStatus === "idle";
1280
- const resume = canContinueHere(state);
1281
- const join = state.canAttach;
1282
- const branch = state.canBranch;
1283
- if (!resume && !join && !branch) return /* @__PURE__ */ jsx3("div", { className: "scui-continuation", children: /* @__PURE__ */ jsxs3("span", { children: [
1286
+ const available = {
1287
+ resume: canContinueHere(state),
1288
+ join: state.canAttach,
1289
+ branch: state.canBranch
1290
+ };
1291
+ const continuation = state.supportsAttach ? "join" : state.supportsResume ? "resume" : state.supportsBranch ? "branch" : available.join ? "join" : available.resume ? "resume" : available.branch ? "branch" : null;
1292
+ if (!continuation) return /* @__PURE__ */ jsx3("div", { className: "scui-continuation", children: /* @__PURE__ */ jsxs3("span", { children: [
1284
1293
  /* @__PURE__ */ jsx3("strong", { children: activeElsewhere ? "Active elsewhere" : "Read-only" }),
1285
1294
  /* @__PURE__ */ jsx3("small", { children: "This session cannot be continued by an available harness." })
1286
1295
  ] }) });
1296
+ const enabled = available[continuation];
1287
1297
  return /* @__PURE__ */ jsxs3("div", { className: "scui-continuation", children: [
1288
1298
  /* @__PURE__ */ jsxs3("span", { children: [
1289
1299
  /* @__PURE__ */ jsx3("strong", { children: activeElsewhere ? "Active elsewhere" : "Read-only" }),
1290
- /* @__PURE__ */ jsx3("small", { children: join ? "Join the proven live runtime without taking it over." : resume ? `Resume this ${harnessDisplayName(state.harness)} session here.` : "Start an independent continuation." })
1300
+ /* @__PURE__ */ jsx3("small", { children: continuation === "join" ? "Join the proven live runtime without taking it over." : continuation === "resume" ? `Resume this ${harnessDisplayName(state.harness)} session here.` : "Start an independent continuation." })
1291
1301
  ] }),
1292
1302
  /* @__PURE__ */ jsxs3("span", { className: "scui-continuation-actions", children: [
1293
- !join && resume ? /* @__PURE__ */ jsx3(ExecutionModeSelect, { modes: continuationModes, value: executionMode, disabled: Boolean(state.operation), onChange: (mode) => setSelection({ key: state.attached?.key ?? null, mode }) }) : null,
1294
- /* @__PURE__ */ jsx3("button", { type: "button", disabled: Boolean(state.operation), onClick: () => dispatchConfirmedIntent(adapter, join ? { action: "join" } : resume ? { action: "resume", mode: executionMode } : { action: "branch" }), children: join ? labels.joinLive : resume ? labels.continueHere : labels.forkHere })
1303
+ continuation === "resume" ? /* @__PURE__ */ jsx3(ExecutionModeSelect, { modes: continuationModes, value: executionMode, disabled: Boolean(state.operation) || !enabled, onChange: (mode) => setSelection({ key: state.attached?.key ?? null, mode }) }) : null,
1304
+ /* @__PURE__ */ jsx3("button", { type: "button", disabled: Boolean(state.operation) || !enabled, onClick: () => dispatchConfirmedIntent(adapter, continuation === "join" ? { action: "join" } : continuation === "resume" ? { action: "resume", mode: executionMode } : { action: "branch" }), children: continuation === "join" ? labels.joinLive : continuation === "resume" ? labels.continueHere : labels.forkHere })
1295
1305
  ] })
1296
1306
  ] });
1297
1307
  }
@@ -2633,8 +2643,8 @@ function ChatHeader({ state, adapter, pendingStatus, actionPending, onBack, onNe
2633
2643
  if (state.mode === "mirror" && !state.canSend) back.current?.focus({ preventScroll: true });
2634
2644
  }, []);
2635
2645
  return /* @__PURE__ */ jsxs8("header", { className: "scui-head scui-chat-head", children: [
2636
- /* @__PURE__ */ jsx9("button", { ref: back, type: "button", "aria-label": "Back to chats", onClick: onBack, children: /* @__PURE__ */ jsx9(UiIcon, { name: "back", size: 18 }) }),
2637
- /* @__PURE__ */ jsx9(HarnessLogo, { id: harness, size: 28 }),
2646
+ /* @__PURE__ */ jsx9("button", { ref: back, type: "button", "aria-label": "Back to chats", onClick: onBack, children: /* @__PURE__ */ jsx9(UiIcon, { name: "back", size: 17 }) }),
2647
+ /* @__PURE__ */ jsx9(HarnessLogo, { id: harness, size: 24 }),
2638
2648
  /* @__PURE__ */ jsxs8("span", { className: "scui-head-copy", children: [
2639
2649
  /* @__PURE__ */ jsx9("strong", { children: title }),
2640
2650
  /* @__PURE__ */ jsxs8("small", { children: [
package/index.d.ts CHANGED
@@ -267,10 +267,16 @@ export interface SupercodeUiState {
267
267
  canSend: boolean;
268
268
  canSteer: boolean;
269
269
  canResume: boolean;
270
+ /** Stable continuation eligibility while another controller action is in flight. */
271
+ supportsResume: boolean;
270
272
  /** Execution transports the current host can actually provide. */
271
273
  continuationModes: ContinuationMode[];
272
274
  canBranch: boolean;
275
+ /** Stable continuation eligibility while another controller action is in flight. */
276
+ supportsBranch: boolean;
273
277
  canAttach: boolean;
278
+ /** Stable continuation eligibility while another controller action is in flight. */
279
+ supportsAttach: boolean;
274
280
  canDetach: boolean;
275
281
  canOpenTerminal: boolean;
276
282
  canExport: boolean;
package/messenger.mjs CHANGED
@@ -35,9 +35,12 @@ var EMPTY_UI_STATE = Object.freeze({
35
35
  canSend: false,
36
36
  canSteer: false,
37
37
  canResume: false,
38
+ supportsResume: false,
38
39
  continuationModes: Object.freeze([]),
39
40
  canBranch: false,
41
+ supportsBranch: false,
40
42
  canAttach: false,
43
+ supportsAttach: false,
41
44
  canDetach: false,
42
45
  canOpenTerminal: false,
43
46
  canExport: false,
@@ -724,9 +727,12 @@ function normalizeUiState(value) {
724
727
  canSend: raw.canSend === true,
725
728
  canSteer: raw.canSteer === true,
726
729
  canResume,
730
+ supportsResume: raw.supportsResume === true,
727
731
  continuationModes,
728
732
  canBranch: raw.canBranch === true,
733
+ supportsBranch: raw.supportsBranch === true,
729
734
  canAttach: raw.canAttach === true,
735
+ supportsAttach: raw.supportsAttach === true,
730
736
  canDetach: raw.canDetach === true,
731
737
  canOpenTerminal: raw.canOpenTerminal === true,
732
738
  canExport: raw.canExport === true,
@@ -1274,21 +1280,25 @@ function ContinuationBar({ state, adapter, labels = DEFAULT_LABELS }) {
1274
1280
  const attached = state.attached;
1275
1281
  const row = attached?.key ? state.sessions.find((item) => item.key === attached.key) : null;
1276
1282
  const activeElsewhere = row?.runtimeStatus === "running" || row?.runtimeStatus === "busy" || row?.runtimeStatus === "idle";
1277
- const resume = canContinueHere(state);
1278
- const join = state.canAttach;
1279
- const branch = state.canBranch;
1280
- if (!resume && !join && !branch) return /* @__PURE__ */ jsx3("div", { className: "scui-continuation", children: /* @__PURE__ */ jsxs3("span", { children: [
1283
+ const available = {
1284
+ resume: canContinueHere(state),
1285
+ join: state.canAttach,
1286
+ branch: state.canBranch
1287
+ };
1288
+ const continuation = state.supportsAttach ? "join" : state.supportsResume ? "resume" : state.supportsBranch ? "branch" : available.join ? "join" : available.resume ? "resume" : available.branch ? "branch" : null;
1289
+ if (!continuation) return /* @__PURE__ */ jsx3("div", { className: "scui-continuation", children: /* @__PURE__ */ jsxs3("span", { children: [
1281
1290
  /* @__PURE__ */ jsx3("strong", { children: activeElsewhere ? "Active elsewhere" : "Read-only" }),
1282
1291
  /* @__PURE__ */ jsx3("small", { children: "This session cannot be continued by an available harness." })
1283
1292
  ] }) });
1293
+ const enabled = available[continuation];
1284
1294
  return /* @__PURE__ */ jsxs3("div", { className: "scui-continuation", children: [
1285
1295
  /* @__PURE__ */ jsxs3("span", { children: [
1286
1296
  /* @__PURE__ */ jsx3("strong", { children: activeElsewhere ? "Active elsewhere" : "Read-only" }),
1287
- /* @__PURE__ */ jsx3("small", { children: join ? "Join the proven live runtime without taking it over." : resume ? `Resume this ${harnessDisplayName(state.harness)} session here.` : "Start an independent continuation." })
1297
+ /* @__PURE__ */ jsx3("small", { children: continuation === "join" ? "Join the proven live runtime without taking it over." : continuation === "resume" ? `Resume this ${harnessDisplayName(state.harness)} session here.` : "Start an independent continuation." })
1288
1298
  ] }),
1289
1299
  /* @__PURE__ */ jsxs3("span", { className: "scui-continuation-actions", children: [
1290
- !join && resume ? /* @__PURE__ */ jsx3(ExecutionModeSelect, { modes: continuationModes, value: executionMode, disabled: Boolean(state.operation), onChange: (mode) => setSelection({ key: state.attached?.key ?? null, mode }) }) : null,
1291
- /* @__PURE__ */ jsx3("button", { type: "button", disabled: Boolean(state.operation), onClick: () => dispatchConfirmedIntent(adapter, join ? { action: "join" } : resume ? { action: "resume", mode: executionMode } : { action: "branch" }), children: join ? labels.joinLive : resume ? labels.continueHere : labels.forkHere })
1300
+ continuation === "resume" ? /* @__PURE__ */ jsx3(ExecutionModeSelect, { modes: continuationModes, value: executionMode, disabled: Boolean(state.operation) || !enabled, onChange: (mode) => setSelection({ key: state.attached?.key ?? null, mode }) }) : null,
1301
+ /* @__PURE__ */ jsx3("button", { type: "button", disabled: Boolean(state.operation) || !enabled, onClick: () => dispatchConfirmedIntent(adapter, continuation === "join" ? { action: "join" } : continuation === "resume" ? { action: "resume", mode: executionMode } : { action: "branch" }), children: continuation === "join" ? labels.joinLive : continuation === "resume" ? labels.continueHere : labels.forkHere })
1292
1302
  ] })
1293
1303
  ] });
1294
1304
  }
@@ -2630,8 +2640,8 @@ function ChatHeader({ state, adapter, pendingStatus, actionPending, onBack, onNe
2630
2640
  if (state.mode === "mirror" && !state.canSend) back.current?.focus({ preventScroll: true });
2631
2641
  }, []);
2632
2642
  return /* @__PURE__ */ jsxs8("header", { className: "scui-head scui-chat-head", children: [
2633
- /* @__PURE__ */ jsx9("button", { ref: back, type: "button", "aria-label": "Back to chats", onClick: onBack, children: /* @__PURE__ */ jsx9(UiIcon, { name: "back", size: 18 }) }),
2634
- /* @__PURE__ */ jsx9(HarnessLogo, { id: harness, size: 28 }),
2643
+ /* @__PURE__ */ jsx9("button", { ref: back, type: "button", "aria-label": "Back to chats", onClick: onBack, children: /* @__PURE__ */ jsx9(UiIcon, { name: "back", size: 17 }) }),
2644
+ /* @__PURE__ */ jsx9(HarnessLogo, { id: harness, size: 24 }),
2635
2645
  /* @__PURE__ */ jsxs8("span", { className: "scui-head-copy", children: [
2636
2646
  /* @__PURE__ */ jsx9("strong", { children: title }),
2637
2647
  /* @__PURE__ */ jsxs8("small", { children: [
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@volter-ai-dev/supercode-ui",
3
- "version": "0.1.47",
3
+ "version": "0.1.49",
4
4
  "type": "module",
5
5
  "description": "Composable default UI kit for Supercode-powered coding-agent experiences",
6
6
  "exports": {
@@ -32,9 +32,12 @@ var EMPTY_UI_STATE = Object.freeze({
32
32
  canSend: false,
33
33
  canSteer: false,
34
34
  canResume: false,
35
+ supportsResume: false,
35
36
  continuationModes: Object.freeze([]),
36
37
  canBranch: false,
38
+ supportsBranch: false,
37
39
  canAttach: false,
40
+ supportsAttach: false,
38
41
  canDetach: false,
39
42
  canOpenTerminal: false,
40
43
  canExport: false,
@@ -712,9 +715,12 @@ function normalizeUiState(value) {
712
715
  canSend: raw.canSend === true,
713
716
  canSteer: raw.canSteer === true,
714
717
  canResume,
718
+ supportsResume: raw.supportsResume === true,
715
719
  continuationModes,
716
720
  canBranch: raw.canBranch === true,
721
+ supportsBranch: raw.supportsBranch === true,
717
722
  canAttach: raw.canAttach === true,
723
+ supportsAttach: raw.supportsAttach === true,
718
724
  canDetach: raw.canDetach === true,
719
725
  canOpenTerminal: raw.canOpenTerminal === true,
720
726
  canExport: raw.canExport === true,
@@ -35,9 +35,12 @@ var EMPTY_UI_STATE = Object.freeze({
35
35
  canSend: false,
36
36
  canSteer: false,
37
37
  canResume: false,
38
+ supportsResume: false,
38
39
  continuationModes: Object.freeze([]),
39
40
  canBranch: false,
41
+ supportsBranch: false,
40
42
  canAttach: false,
43
+ supportsAttach: false,
41
44
  canDetach: false,
42
45
  canOpenTerminal: false,
43
46
  canExport: false,
@@ -724,9 +727,12 @@ function normalizeUiState(value) {
724
727
  canSend: raw.canSend === true,
725
728
  canSteer: raw.canSteer === true,
726
729
  canResume,
730
+ supportsResume: raw.supportsResume === true,
727
731
  continuationModes,
728
732
  canBranch: raw.canBranch === true,
733
+ supportsBranch: raw.supportsBranch === true,
729
734
  canAttach: raw.canAttach === true,
735
+ supportsAttach: raw.supportsAttach === true,
730
736
  canDetach: raw.canDetach === true,
731
737
  canOpenTerminal: raw.canOpenTerminal === true,
732
738
  canExport: raw.canExport === true,
@@ -1314,21 +1320,25 @@ function ContinuationBar({ state, adapter, labels = DEFAULT_LABELS }) {
1314
1320
  const attached = state.attached;
1315
1321
  const row = attached?.key ? state.sessions.find((item) => item.key === attached.key) : null;
1316
1322
  const activeElsewhere = row?.runtimeStatus === "running" || row?.runtimeStatus === "busy" || row?.runtimeStatus === "idle";
1317
- const resume = canContinueHere(state);
1318
- const join = state.canAttach;
1319
- const branch = state.canBranch;
1320
- if (!resume && !join && !branch) return /* @__PURE__ */ jsx3("div", { className: "scui-continuation", children: /* @__PURE__ */ jsxs3("span", { children: [
1323
+ const available = {
1324
+ resume: canContinueHere(state),
1325
+ join: state.canAttach,
1326
+ branch: state.canBranch
1327
+ };
1328
+ const continuation = state.supportsAttach ? "join" : state.supportsResume ? "resume" : state.supportsBranch ? "branch" : available.join ? "join" : available.resume ? "resume" : available.branch ? "branch" : null;
1329
+ if (!continuation) return /* @__PURE__ */ jsx3("div", { className: "scui-continuation", children: /* @__PURE__ */ jsxs3("span", { children: [
1321
1330
  /* @__PURE__ */ jsx3("strong", { children: activeElsewhere ? "Active elsewhere" : "Read-only" }),
1322
1331
  /* @__PURE__ */ jsx3("small", { children: "This session cannot be continued by an available harness." })
1323
1332
  ] }) });
1333
+ const enabled = available[continuation];
1324
1334
  return /* @__PURE__ */ jsxs3("div", { className: "scui-continuation", children: [
1325
1335
  /* @__PURE__ */ jsxs3("span", { children: [
1326
1336
  /* @__PURE__ */ jsx3("strong", { children: activeElsewhere ? "Active elsewhere" : "Read-only" }),
1327
- /* @__PURE__ */ jsx3("small", { children: join ? "Join the proven live runtime without taking it over." : resume ? `Resume this ${harnessDisplayName(state.harness)} session here.` : "Start an independent continuation." })
1337
+ /* @__PURE__ */ jsx3("small", { children: continuation === "join" ? "Join the proven live runtime without taking it over." : continuation === "resume" ? `Resume this ${harnessDisplayName(state.harness)} session here.` : "Start an independent continuation." })
1328
1338
  ] }),
1329
1339
  /* @__PURE__ */ jsxs3("span", { className: "scui-continuation-actions", children: [
1330
- !join && resume ? /* @__PURE__ */ jsx3(ExecutionModeSelect, { modes: continuationModes, value: executionMode, disabled: Boolean(state.operation), onChange: (mode) => setSelection({ key: state.attached?.key ?? null, mode }) }) : null,
1331
- /* @__PURE__ */ jsx3("button", { type: "button", disabled: Boolean(state.operation), onClick: () => dispatchConfirmedIntent(adapter, join ? { action: "join" } : resume ? { action: "resume", mode: executionMode } : { action: "branch" }), children: join ? labels.joinLive : resume ? labels.continueHere : labels.forkHere })
1340
+ continuation === "resume" ? /* @__PURE__ */ jsx3(ExecutionModeSelect, { modes: continuationModes, value: executionMode, disabled: Boolean(state.operation) || !enabled, onChange: (mode) => setSelection({ key: state.attached?.key ?? null, mode }) }) : null,
1341
+ /* @__PURE__ */ jsx3("button", { type: "button", disabled: Boolean(state.operation) || !enabled, onClick: () => dispatchConfirmedIntent(adapter, continuation === "join" ? { action: "join" } : continuation === "resume" ? { action: "resume", mode: executionMode } : { action: "branch" }), children: continuation === "join" ? labels.joinLive : continuation === "resume" ? labels.continueHere : labels.forkHere })
1332
1342
  ] })
1333
1343
  ] });
1334
1344
  }
@@ -2716,8 +2726,8 @@ function ChatHeader({ state, adapter, pendingStatus, actionPending, onBack, onNe
2716
2726
  if (state.mode === "mirror" && !state.canSend) back.current?.focus({ preventScroll: true });
2717
2727
  }, []);
2718
2728
  return /* @__PURE__ */ jsxs9("header", { className: "scui-head scui-chat-head", children: [
2719
- /* @__PURE__ */ jsx10("button", { ref: back, type: "button", "aria-label": "Back to chats", onClick: onBack, children: /* @__PURE__ */ jsx10(UiIcon, { name: "back", size: 18 }) }),
2720
- /* @__PURE__ */ jsx10(HarnessLogo, { id: harness, size: 28 }),
2729
+ /* @__PURE__ */ jsx10("button", { ref: back, type: "button", "aria-label": "Back to chats", onClick: onBack, children: /* @__PURE__ */ jsx10(UiIcon, { name: "back", size: 17 }) }),
2730
+ /* @__PURE__ */ jsx10(HarnessLogo, { id: harness, size: 24 }),
2721
2731
  /* @__PURE__ */ jsxs9("span", { className: "scui-head-copy", children: [
2722
2732
  /* @__PURE__ */ jsx10("strong", { children: title }),
2723
2733
  /* @__PURE__ */ jsxs9("small", { children: [
@@ -35,9 +35,12 @@ var EMPTY_UI_STATE = Object.freeze({
35
35
  canSend: false,
36
36
  canSteer: false,
37
37
  canResume: false,
38
+ supportsResume: false,
38
39
  continuationModes: Object.freeze([]),
39
40
  canBranch: false,
41
+ supportsBranch: false,
40
42
  canAttach: false,
43
+ supportsAttach: false,
41
44
  canDetach: false,
42
45
  canOpenTerminal: false,
43
46
  canExport: false,
@@ -311,21 +314,25 @@ function ContinuationBar({ state, adapter, labels = DEFAULT_LABELS }) {
311
314
  const attached = state.attached;
312
315
  const row = attached?.key ? state.sessions.find((item) => item.key === attached.key) : null;
313
316
  const activeElsewhere = row?.runtimeStatus === "running" || row?.runtimeStatus === "busy" || row?.runtimeStatus === "idle";
314
- const resume = canContinueHere(state);
315
- const join = state.canAttach;
316
- const branch = state.canBranch;
317
- if (!resume && !join && !branch) return /* @__PURE__ */ jsx3("div", { className: "scui-continuation", children: /* @__PURE__ */ jsxs3("span", { children: [
317
+ const available = {
318
+ resume: canContinueHere(state),
319
+ join: state.canAttach,
320
+ branch: state.canBranch
321
+ };
322
+ const continuation = state.supportsAttach ? "join" : state.supportsResume ? "resume" : state.supportsBranch ? "branch" : available.join ? "join" : available.resume ? "resume" : available.branch ? "branch" : null;
323
+ if (!continuation) return /* @__PURE__ */ jsx3("div", { className: "scui-continuation", children: /* @__PURE__ */ jsxs3("span", { children: [
318
324
  /* @__PURE__ */ jsx3("strong", { children: activeElsewhere ? "Active elsewhere" : "Read-only" }),
319
325
  /* @__PURE__ */ jsx3("small", { children: "This session cannot be continued by an available harness." })
320
326
  ] }) });
327
+ const enabled = available[continuation];
321
328
  return /* @__PURE__ */ jsxs3("div", { className: "scui-continuation", children: [
322
329
  /* @__PURE__ */ jsxs3("span", { children: [
323
330
  /* @__PURE__ */ jsx3("strong", { children: activeElsewhere ? "Active elsewhere" : "Read-only" }),
324
- /* @__PURE__ */ jsx3("small", { children: join ? "Join the proven live runtime without taking it over." : resume ? `Resume this ${harnessDisplayName(state.harness)} session here.` : "Start an independent continuation." })
331
+ /* @__PURE__ */ jsx3("small", { children: continuation === "join" ? "Join the proven live runtime without taking it over." : continuation === "resume" ? `Resume this ${harnessDisplayName(state.harness)} session here.` : "Start an independent continuation." })
325
332
  ] }),
326
333
  /* @__PURE__ */ jsxs3("span", { className: "scui-continuation-actions", children: [
327
- !join && resume ? /* @__PURE__ */ jsx3(ExecutionModeSelect, { modes: continuationModes, value: executionMode, disabled: Boolean(state.operation), onChange: (mode) => setSelection({ key: state.attached?.key ?? null, mode }) }) : null,
328
- /* @__PURE__ */ jsx3("button", { type: "button", disabled: Boolean(state.operation), onClick: () => dispatchConfirmedIntent(adapter, join ? { action: "join" } : resume ? { action: "resume", mode: executionMode } : { action: "branch" }), children: join ? labels.joinLive : resume ? labels.continueHere : labels.forkHere })
334
+ continuation === "resume" ? /* @__PURE__ */ jsx3(ExecutionModeSelect, { modes: continuationModes, value: executionMode, disabled: Boolean(state.operation) || !enabled, onChange: (mode) => setSelection({ key: state.attached?.key ?? null, mode }) }) : null,
335
+ /* @__PURE__ */ jsx3("button", { type: "button", disabled: Boolean(state.operation) || !enabled, onClick: () => dispatchConfirmedIntent(adapter, continuation === "join" ? { action: "join" } : continuation === "resume" ? { action: "resume", mode: executionMode } : { action: "branch" }), children: continuation === "join" ? labels.joinLive : continuation === "resume" ? labels.continueHere : labels.forkHere })
329
336
  ] })
330
337
  ] });
331
338
  }
@@ -36,9 +36,12 @@ var EMPTY_UI_STATE = Object.freeze({
36
36
  canSend: false,
37
37
  canSteer: false,
38
38
  canResume: false,
39
+ supportsResume: false,
39
40
  continuationModes: Object.freeze([]),
40
41
  canBranch: false,
42
+ supportsBranch: false,
41
43
  canAttach: false,
44
+ supportsAttach: false,
42
45
  canDetach: false,
43
46
  canOpenTerminal: false,
44
47
  canExport: false,
@@ -35,9 +35,12 @@ var EMPTY_UI_STATE = Object.freeze({
35
35
  canSend: false,
36
36
  canSteer: false,
37
37
  canResume: false,
38
+ supportsResume: false,
38
39
  continuationModes: Object.freeze([]),
39
40
  canBranch: false,
41
+ supportsBranch: false,
40
42
  canAttach: false,
43
+ supportsAttach: false,
41
44
  canDetach: false,
42
45
  canOpenTerminal: false,
43
46
  canExport: false,
@@ -724,9 +727,12 @@ function normalizeUiState(value) {
724
727
  canSend: raw.canSend === true,
725
728
  canSteer: raw.canSteer === true,
726
729
  canResume,
730
+ supportsResume: raw.supportsResume === true,
727
731
  continuationModes,
728
732
  canBranch: raw.canBranch === true,
733
+ supportsBranch: raw.supportsBranch === true,
729
734
  canAttach: raw.canAttach === true,
735
+ supportsAttach: raw.supportsAttach === true,
730
736
  canDetach: raw.canDetach === true,
731
737
  canOpenTerminal: raw.canOpenTerminal === true,
732
738
  canExport: raw.canExport === true,
@@ -1274,21 +1280,25 @@ function ContinuationBar({ state, adapter, labels = DEFAULT_LABELS }) {
1274
1280
  const attached = state.attached;
1275
1281
  const row = attached?.key ? state.sessions.find((item) => item.key === attached.key) : null;
1276
1282
  const activeElsewhere = row?.runtimeStatus === "running" || row?.runtimeStatus === "busy" || row?.runtimeStatus === "idle";
1277
- const resume = canContinueHere(state);
1278
- const join = state.canAttach;
1279
- const branch = state.canBranch;
1280
- if (!resume && !join && !branch) return /* @__PURE__ */ jsx3("div", { className: "scui-continuation", children: /* @__PURE__ */ jsxs3("span", { children: [
1283
+ const available = {
1284
+ resume: canContinueHere(state),
1285
+ join: state.canAttach,
1286
+ branch: state.canBranch
1287
+ };
1288
+ const continuation = state.supportsAttach ? "join" : state.supportsResume ? "resume" : state.supportsBranch ? "branch" : available.join ? "join" : available.resume ? "resume" : available.branch ? "branch" : null;
1289
+ if (!continuation) return /* @__PURE__ */ jsx3("div", { className: "scui-continuation", children: /* @__PURE__ */ jsxs3("span", { children: [
1281
1290
  /* @__PURE__ */ jsx3("strong", { children: activeElsewhere ? "Active elsewhere" : "Read-only" }),
1282
1291
  /* @__PURE__ */ jsx3("small", { children: "This session cannot be continued by an available harness." })
1283
1292
  ] }) });
1293
+ const enabled = available[continuation];
1284
1294
  return /* @__PURE__ */ jsxs3("div", { className: "scui-continuation", children: [
1285
1295
  /* @__PURE__ */ jsxs3("span", { children: [
1286
1296
  /* @__PURE__ */ jsx3("strong", { children: activeElsewhere ? "Active elsewhere" : "Read-only" }),
1287
- /* @__PURE__ */ jsx3("small", { children: join ? "Join the proven live runtime without taking it over." : resume ? `Resume this ${harnessDisplayName(state.harness)} session here.` : "Start an independent continuation." })
1297
+ /* @__PURE__ */ jsx3("small", { children: continuation === "join" ? "Join the proven live runtime without taking it over." : continuation === "resume" ? `Resume this ${harnessDisplayName(state.harness)} session here.` : "Start an independent continuation." })
1288
1298
  ] }),
1289
1299
  /* @__PURE__ */ jsxs3("span", { className: "scui-continuation-actions", children: [
1290
- !join && resume ? /* @__PURE__ */ jsx3(ExecutionModeSelect, { modes: continuationModes, value: executionMode, disabled: Boolean(state.operation), onChange: (mode) => setSelection({ key: state.attached?.key ?? null, mode }) }) : null,
1291
- /* @__PURE__ */ jsx3("button", { type: "button", disabled: Boolean(state.operation), onClick: () => dispatchConfirmedIntent(adapter, join ? { action: "join" } : resume ? { action: "resume", mode: executionMode } : { action: "branch" }), children: join ? labels.joinLive : resume ? labels.continueHere : labels.forkHere })
1300
+ continuation === "resume" ? /* @__PURE__ */ jsx3(ExecutionModeSelect, { modes: continuationModes, value: executionMode, disabled: Boolean(state.operation) || !enabled, onChange: (mode) => setSelection({ key: state.attached?.key ?? null, mode }) }) : null,
1301
+ /* @__PURE__ */ jsx3("button", { type: "button", disabled: Boolean(state.operation) || !enabled, onClick: () => dispatchConfirmedIntent(adapter, continuation === "join" ? { action: "join" } : continuation === "resume" ? { action: "resume", mode: executionMode } : { action: "branch" }), children: continuation === "join" ? labels.joinLive : continuation === "resume" ? labels.continueHere : labels.forkHere })
1292
1302
  ] })
1293
1303
  ] });
1294
1304
  }
@@ -2630,8 +2640,8 @@ function ChatHeader({ state, adapter, pendingStatus, actionPending, onBack, onNe
2630
2640
  if (state.mode === "mirror" && !state.canSend) back.current?.focus({ preventScroll: true });
2631
2641
  }, []);
2632
2642
  return /* @__PURE__ */ jsxs8("header", { className: "scui-head scui-chat-head", children: [
2633
- /* @__PURE__ */ jsx9("button", { ref: back, type: "button", "aria-label": "Back to chats", onClick: onBack, children: /* @__PURE__ */ jsx9(UiIcon, { name: "back", size: 18 }) }),
2634
- /* @__PURE__ */ jsx9(HarnessLogo, { id: harness, size: 28 }),
2643
+ /* @__PURE__ */ jsx9("button", { ref: back, type: "button", "aria-label": "Back to chats", onClick: onBack, children: /* @__PURE__ */ jsx9(UiIcon, { name: "back", size: 17 }) }),
2644
+ /* @__PURE__ */ jsx9(HarnessLogo, { id: harness, size: 24 }),
2635
2645
  /* @__PURE__ */ jsxs8("span", { className: "scui-head-copy", children: [
2636
2646
  /* @__PURE__ */ jsx9("strong", { children: title }),
2637
2647
  /* @__PURE__ */ jsxs8("small", { children: [
@@ -35,9 +35,12 @@ var EMPTY_UI_STATE = Object.freeze({
35
35
  canSend: false,
36
36
  canSteer: false,
37
37
  canResume: false,
38
+ supportsResume: false,
38
39
  continuationModes: Object.freeze([]),
39
40
  canBranch: false,
41
+ supportsBranch: false,
40
42
  canAttach: false,
43
+ supportsAttach: false,
41
44
  canDetach: false,
42
45
  canOpenTerminal: false,
43
46
  canExport: false,
@@ -35,9 +35,12 @@ var EMPTY_UI_STATE = Object.freeze({
35
35
  canSend: false,
36
36
  canSteer: false,
37
37
  canResume: false,
38
+ supportsResume: false,
38
39
  continuationModes: Object.freeze([]),
39
40
  canBranch: false,
41
+ supportsBranch: false,
40
42
  canAttach: false,
43
+ supportsAttach: false,
41
44
  canDetach: false,
42
45
  canOpenTerminal: false,
43
46
  canExport: false,
package/sessions.mjs CHANGED
@@ -35,9 +35,12 @@ var EMPTY_UI_STATE = Object.freeze({
35
35
  canSend: false,
36
36
  canSteer: false,
37
37
  canResume: false,
38
+ supportsResume: false,
38
39
  continuationModes: Object.freeze([]),
39
40
  canBranch: false,
41
+ supportsBranch: false,
40
42
  canAttach: false,
43
+ supportsAttach: false,
41
44
  canDetach: false,
42
45
  canOpenTerminal: false,
43
46
  canExport: false,
package/settings.mjs CHANGED
@@ -35,9 +35,12 @@ var EMPTY_UI_STATE = Object.freeze({
35
35
  canSend: false,
36
36
  canSteer: false,
37
37
  canResume: false,
38
+ supportsResume: false,
38
39
  continuationModes: Object.freeze([]),
39
40
  canBranch: false,
41
+ supportsBranch: false,
40
42
  canAttach: false,
43
+ supportsAttach: false,
41
44
  canDetach: false,
42
45
  canOpenTerminal: false,
43
46
  canExport: false,
package/styles.css CHANGED
@@ -13,6 +13,7 @@
13
13
  --scui-warning: #b26a00;
14
14
  --scui-danger: #b4232e;
15
15
  --scui-radius: 10px;
16
+ --scui-head-height: 42px;
16
17
  --scui-font: Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
17
18
  box-sizing: border-box;
18
19
  display: flex;
@@ -53,11 +54,11 @@
53
54
  .scui-sr-only { position:absolute; width:1px; height:1px; padding:0; overflow:hidden; clip:rect(0,0,0,0); white-space:nowrap; border:0 }
54
55
 
55
56
  .scui-list,.scui-chat { display:flex; flex:1; min-width:0; min-height:0; flex-direction:column }
56
- .scui-head { display:flex; flex:none; align-items:center; gap:8px; min-height:49px; padding:7px 8px 7px 12px; border-bottom:1px solid var(--scui-border); background:var(--scui-bg-raised) }
57
+ .scui-head { display:flex; flex:none; align-items:center; gap:5px; min-height:var(--scui-head-height); padding:4px 6px 4px 8px; border-bottom:1px solid var(--scui-border); background:var(--scui-bg-raised) }
57
58
  .scui-head > .scui-head-copy { display:grid; flex:1; min-width:0 }
58
- .scui-head strong { overflow:hidden; text-overflow:ellipsis; white-space:nowrap; font-size:13px }
59
- .scui-head small { overflow:hidden; color:var(--scui-muted); font-size:10.5px; text-overflow:ellipsis; white-space:nowrap }
60
- .scui-head > button,.scui-menu-trigger { display:grid; place-items:center; width:30px; height:30px; padding:0; border:0; border-radius:8px; background:transparent; color:inherit; cursor:pointer; font-size:18px }
59
+ .scui-head strong { overflow:hidden; text-overflow:ellipsis; white-space:nowrap; font-size:12px }
60
+ .scui-head small { overflow:hidden; color:var(--scui-muted); font-size:9.5px; text-overflow:ellipsis; white-space:nowrap }
61
+ .scui-head > button,.scui-menu-trigger { display:grid; place-items:center; width:28px; height:28px; padding:0; border:0; border-radius:7px; background:transparent; color:inherit; cursor:pointer; font-size:16px }
61
62
  .scui-head > button:hover,.scui-menu-trigger:hover,.scui-menu-trigger[aria-expanded="true"] { background:var(--scui-fill) }
62
63
  .scui-menu { position:relative }
63
64
  .scui-menu-panel { position:absolute; z-index:20; top:36px; right:0; display:grid; width:250px; max-height:300px; padding:5px; overflow:auto; border:1px solid var(--scui-border-strong); border-radius:10px; background:var(--scui-bg); box-shadow:0 10px 28px rgba(0,0,0,.22) }
@@ -207,7 +208,7 @@
207
208
  .scui-harness-manage { margin-top:4px; padding-top:4px; border-top:1px solid var(--scui-border) }.scui-harness-manage > summary { padding:6px 7px; color:var(--scui-muted); cursor:pointer; font-size:9.5px }.scui-harness-manage > div { display:grid; gap:1px }.scui-harness-manage section { display:grid; grid-template-columns:auto minmax(0,1fr) auto; min-height:36px; align-items:center; gap:8px; padding:5px 7px }.scui-harness-manage section > span { display:grid; min-width:0 }.scui-harness-manage section strong,.scui-harness-manage section small { overflow:hidden; text-overflow:ellipsis; white-space:nowrap }.scui-harness-manage section strong { font-size:10.5px; font-weight:600 }.scui-harness-manage section small { color:var(--scui-muted); font-size:8.5px }.scui-harness-manage section > button { padding:4px 6px; border:1px solid var(--scui-border); border-radius:6px; background:transparent; color:var(--scui-muted); cursor:pointer; font-size:8.5px }.scui-harness-manage section > button:hover { border-color:var(--scui-border-strong); color:var(--scui-fg) }
208
209
  .scui-readiness { margin:0 0 7px; border:1px solid var(--scui-border); border-radius:7px; background:var(--scui-bg) }.scui-readiness > summary { padding:6px 8px; color:var(--scui-muted); cursor:pointer; font-size:10px }.scui-readiness > div { display:grid; border-top:1px solid var(--scui-border) }.scui-readiness section { display:grid; grid-template-columns:auto minmax(0,1fr) auto; align-items:center; gap:7px; padding:7px 8px }.scui-readiness section + section { border-top:1px solid var(--scui-border) }.scui-readiness section > span { display:grid; min-width:0 }.scui-readiness section strong,.scui-readiness section small,.scui-readiness section em { overflow:hidden; text-overflow:ellipsis; white-space:nowrap }.scui-readiness section small { color:var(--scui-muted); font-size:9px }.scui-readiness section em { color:var(--scui-muted); font-size:8px; font-style:normal }.scui-readiness section button { padding:4px 6px; border:1px solid var(--scui-border); border-radius:6px; background:transparent; cursor:pointer; font-size:9px }
209
210
  .scui-new { display:grid; justify-items:center; gap:5px; margin:auto; padding:20px; color:var(--scui-muted); text-align:center }.scui-new > span { color:var(--scui-accent); font-size:28px }.scui-new strong { color:var(--scui-fg) }
210
- .scui-opening { position:absolute; z-index:30; inset:49px 0 0; display:flex; align-items:center; justify-content:center; gap:10px; padding:20px; background:var(--scui-bg) }.scui-opening > span { display:grid }.scui-opening small { color:var(--scui-muted) }.scui-opening > i { width:16px; height:16px; border:2px solid var(--scui-border); border-top-color:var(--scui-accent); border-radius:50%; animation:scui-spin .8s linear infinite }
211
+ .scui-opening { position:absolute; z-index:30; inset:var(--scui-head-height) 0 0; display:flex; align-items:center; justify-content:center; gap:10px; padding:20px; background:var(--scui-bg) }.scui-opening > span { display:grid }.scui-opening small { color:var(--scui-muted) }.scui-opening > i { width:16px; height:16px; border:2px solid var(--scui-border); border-top-color:var(--scui-accent); border-radius:50%; animation:scui-spin .8s linear infinite }
211
212
 
212
213
  @keyframes scui-spin { to { transform:rotate(360deg) } }
213
214
  @keyframes scui-breathe { 50% { transform:scale(.72); opacity:.5 } }
@@ -216,8 +217,8 @@
216
217
  @keyframes scui-session-dots { 50% { transform:translateY(-1px); opacity:.55 } }
217
218
  @media (prefers-reduced-motion:reduce) { .scui-root * { animation-duration:.001ms !important; animation-iteration-count:1 !important; transition:none !important } }
218
219
  @media (pointer:coarse) {
219
- .scui-head > button,.scui-menu-trigger { width:40px; height:40px }
220
- .scui-head { min-height:52px }
220
+ :where(.scui-root) { --scui-head-height:44px }
221
+ .scui-head > button,.scui-menu-trigger { width:36px; height:36px }
221
222
  .scui-menu-panel button,.scui-request-actions button,.scui-load { min-height:40px }
222
223
  .scui-send,.scui-stop { width:40px; height:40px }
223
224
  .scui-new-envelope-controls .scui-attach,.scui-harness-trigger { min-height:40px }