@volter-ai-dev/supercode-ui 0.1.67 → 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.
- package/activity.mjs +113 -2
- package/components.d.ts +3 -0
- package/components.mjs +246 -12
- package/composer.mjs +12 -2
- package/conversation.mjs +36 -2
- package/core.d.ts +6 -0
- package/core.mjs +215 -1
- package/embed.mjs +241 -11
- package/index.d.ts +103 -0
- package/messenger.mjs +241 -11
- package/package.json +1 -1
- package/react/activity.mjs +113 -2
- package/react/components.mjs +246 -12
- package/react/composer.mjs +12 -2
- package/react/conversation.mjs +36 -2
- package/react/messenger.mjs +241 -11
- package/react/sessions.mjs +62 -3
- package/react/settings.mjs +4 -0
- package/react/subagents.mjs +36 -2
- package/sessions.mjs +62 -3
- package/settings.mjs +4 -0
- package/styles.css +11 -1
- package/subagents.mjs +36 -2
package/core.d.ts
CHANGED
|
@@ -18,6 +18,10 @@ export type {
|
|
|
18
18
|
SessionMode,
|
|
19
19
|
SessionRowModel,
|
|
20
20
|
SessionSemanticsModel,
|
|
21
|
+
CrossSurfaceModel,
|
|
22
|
+
HarnessSessionDescriptorModel,
|
|
23
|
+
TriggerKind,
|
|
24
|
+
TriggerModel,
|
|
21
25
|
StartupPhase,
|
|
22
26
|
SupercodeUiIntent,
|
|
23
27
|
SupercodeUiState,
|
|
@@ -49,6 +53,8 @@ export {
|
|
|
49
53
|
relativeAge,
|
|
50
54
|
sessionActivity,
|
|
51
55
|
sessionDisplayName,
|
|
56
|
+
sessionRowsFromDescriptors,
|
|
57
|
+
surfaceLabel,
|
|
52
58
|
selectContributions,
|
|
53
59
|
terminalCommand,
|
|
54
60
|
toolCategory,
|
package/core.mjs
CHANGED
|
@@ -30,6 +30,10 @@ export const EMPTY_UI_STATE = Object.freeze({
|
|
|
30
30
|
harness: '',
|
|
31
31
|
mode: 'none',
|
|
32
32
|
strategy: null,
|
|
33
|
+
participant: Object.freeze({ kind: 'local-user', label: null, origin: null }),
|
|
34
|
+
workspaceRef: Object.freeze({ kind: 'none', value: null }),
|
|
35
|
+
mirror: null,
|
|
36
|
+
holder: null,
|
|
33
37
|
canSend: false,
|
|
34
38
|
canSteer: false,
|
|
35
39
|
canResume: false,
|
|
@@ -672,12 +676,58 @@ function readToolPresentation(value, entry) {
|
|
|
672
676
|
};
|
|
673
677
|
}
|
|
674
678
|
|
|
679
|
+
// Fast-churning upstreams will emit entry kinds this messenger has never
|
|
680
|
+
// seen. Dropping them silently misrepresents the session, so an addressable
|
|
681
|
+
// entry (a record with a string id) whose role or shape is unrecognized is
|
|
682
|
+
// kept as a safe OPAQUE entry: the original kind is preserved as a label and
|
|
683
|
+
// the raw payload stays available under technical details (UNI-13, the
|
|
684
|
+
// messenger counterpart of the TUI's opaque-line rule). Only an entry with no
|
|
685
|
+
// usable identity is still skipped — it cannot be keyed stably across
|
|
686
|
+
// re-renders.
|
|
687
|
+
const OPAQUE_RAW_CHARS = 4_000;
|
|
688
|
+
|
|
689
|
+
function opaqueEntry(item) {
|
|
690
|
+
// An entry that is ALREADY opaque re-normalizes to itself (state flows
|
|
691
|
+
// through normalization more than once: host fixtures, the messenger's own
|
|
692
|
+
// read, mirrors), so the original kind and raw capture must survive
|
|
693
|
+
// instead of being re-wrapped under kind "opaque".
|
|
694
|
+
const previouslyOpaque = item.role === 'opaque';
|
|
695
|
+
let raw;
|
|
696
|
+
if (previouslyOpaque && typeof item.raw === 'string') {
|
|
697
|
+
raw = item.raw;
|
|
698
|
+
} else {
|
|
699
|
+
try {
|
|
700
|
+
raw = JSON.stringify(item, null, 2) ?? '';
|
|
701
|
+
} catch {
|
|
702
|
+
raw = '[unserializable entry payload]';
|
|
703
|
+
}
|
|
704
|
+
}
|
|
705
|
+
const kind = previouslyOpaque && typeof item.kind === 'string'
|
|
706
|
+
? item.kind
|
|
707
|
+
: typeof item.role === 'string'
|
|
708
|
+
? item.role
|
|
709
|
+
: '';
|
|
710
|
+
return {
|
|
711
|
+
id: item.id,
|
|
712
|
+
role: 'opaque',
|
|
713
|
+
kind: boundedString(kind, 120) || 'unknown',
|
|
714
|
+
text: typeof item.text === 'string' ? boundedString(item.text, OPAQUE_RAW_CHARS) : '',
|
|
715
|
+
ts: nullableNumber(item.ts),
|
|
716
|
+
truncated: item.truncated === true || raw.length > OPAQUE_RAW_CHARS,
|
|
717
|
+
raw: boundedString(raw, OPAQUE_RAW_CHARS),
|
|
718
|
+
};
|
|
719
|
+
}
|
|
720
|
+
|
|
675
721
|
function readTranscript(value) {
|
|
676
722
|
if (!Array.isArray(value)) return [];
|
|
677
723
|
const result = [];
|
|
678
724
|
for (const candidate of value) {
|
|
679
725
|
const item = record(candidate);
|
|
680
|
-
if (!item || typeof item.id !== 'string'
|
|
726
|
+
if (!item || typeof item.id !== 'string') continue;
|
|
727
|
+
if (typeof item.text !== 'string' || !ROLES.has(item.role)) {
|
|
728
|
+
result.push(opaqueEntry(item));
|
|
729
|
+
continue;
|
|
730
|
+
}
|
|
681
731
|
const entry = {
|
|
682
732
|
id: item.id,
|
|
683
733
|
role: item.role,
|
|
@@ -742,6 +792,105 @@ function readTranscript(value) {
|
|
|
742
792
|
return result;
|
|
743
793
|
}
|
|
744
794
|
|
|
795
|
+
// ---- UNI-8..UNI-12: the universal-layer UI nouns ---------------------------
|
|
796
|
+
|
|
797
|
+
/// UNI-8: WHOSE conversation a session is. The messenger's historical implicit
|
|
798
|
+
/// model is you-and-agent-in-a-workspace; Hermes/OpenClaw channel sessions are
|
|
799
|
+
/// someone-else-and-agent. `kind` is the honest tri-state; `label` is the
|
|
800
|
+
/// human ("@jane"), `origin` the surface ("slack", "telegram", "acp").
|
|
801
|
+
function readParticipant(value) {
|
|
802
|
+
const participant = record(value);
|
|
803
|
+
if (!participant) return { kind: 'local-user', label: null, origin: null };
|
|
804
|
+
return {
|
|
805
|
+
kind: ['local-user', 'foreign', 'unknown'].includes(participant.kind) ? participant.kind : 'unknown',
|
|
806
|
+
label: typeof participant.label === 'string' && participant.label ? boundedString(participant.label, 200) : null,
|
|
807
|
+
origin: typeof participant.origin === 'string' && participant.origin ? boundedString(participant.origin, 100) : null,
|
|
808
|
+
};
|
|
809
|
+
}
|
|
810
|
+
|
|
811
|
+
/// UNI-9: a TYPED workspace. `repo` carries a path, `channel` carries a
|
|
812
|
+
/// channel label, `none` is a first-class value (Hermes assistant chats) —
|
|
813
|
+
/// not an empty string pretending to be a path.
|
|
814
|
+
function readWorkspaceRef(value, fallbackPath = '') {
|
|
815
|
+
const ref = record(value);
|
|
816
|
+
if (ref && ['repo', 'none', 'channel'].includes(ref.kind)) {
|
|
817
|
+
return {
|
|
818
|
+
kind: ref.kind,
|
|
819
|
+
value: ref.kind === 'none' ? null : typeof ref.value === 'string' && ref.value ? boundedString(ref.value, 500) : null,
|
|
820
|
+
};
|
|
821
|
+
}
|
|
822
|
+
// Legacy hosts send only the string path.
|
|
823
|
+
return fallbackPath
|
|
824
|
+
? { kind: 'repo', value: boundedString(fallbackPath, 500) }
|
|
825
|
+
: { kind: 'none', value: null };
|
|
826
|
+
}
|
|
827
|
+
|
|
828
|
+
/// UNI-10: canonical-elsewhere. A bounded/truncated MIRROR of a session whose
|
|
829
|
+
/// canonical record lives in another store (OpenClaw supervising codex, ...).
|
|
830
|
+
function readMirror(value) {
|
|
831
|
+
const mirror = record(value);
|
|
832
|
+
if (!mirror || typeof mirror.canonicalHarness !== 'string' || !mirror.canonicalHarness) return null;
|
|
833
|
+
return {
|
|
834
|
+
canonicalHarness: boundedString(mirror.canonicalHarness, 100),
|
|
835
|
+
canonicalKey: typeof mirror.canonicalKey === 'string' && mirror.canonicalKey ? boundedString(mirror.canonicalKey, 300) : null,
|
|
836
|
+
bounded: mirror.bounded === true,
|
|
837
|
+
truncated: mirror.truncated === true,
|
|
838
|
+
origin: typeof mirror.origin === 'string' && mirror.origin ? boundedString(mirror.origin, 200) : null,
|
|
839
|
+
};
|
|
840
|
+
}
|
|
841
|
+
|
|
842
|
+
/// UNI-11: which surface HOLDS this session now. `surface: 'supercode'` =
|
|
843
|
+
/// held here (writable path); any other string = held by that surface
|
|
844
|
+
/// (take-over is the transition, behind confirmIntent); null holder = unheld.
|
|
845
|
+
function readHolder(value) {
|
|
846
|
+
const holder = record(value);
|
|
847
|
+
if (!holder) return null;
|
|
848
|
+
const surface = typeof holder.surface === 'string' && holder.surface ? boundedString(holder.surface, 100) : null;
|
|
849
|
+
return {
|
|
850
|
+
surface,
|
|
851
|
+
canTakeOver: holder.canTakeOver === true && surface !== null && surface !== 'supercode',
|
|
852
|
+
};
|
|
853
|
+
}
|
|
854
|
+
|
|
855
|
+
/// UNI-12/ORCH-6: WHY a session exists. Trigger provenance for unattended
|
|
856
|
+
/// work, over the server's own `Trigger` enum. `manual` is the pre-ORCH-6
|
|
857
|
+
/// spelling of `human` and stays accepted so existing hosts keep working.
|
|
858
|
+
const TRIGGER_KINDS = ['human', 'channel', 'cron', 'heartbeat', 'webhook', 'parent', 'api', 'unknown'];
|
|
859
|
+
function readTrigger(value) {
|
|
860
|
+
const trigger = record(value);
|
|
861
|
+
if (!trigger) return null;
|
|
862
|
+
const kind = trigger.kind === 'manual' ? 'human' : trigger.kind;
|
|
863
|
+
return {
|
|
864
|
+
kind: TRIGGER_KINDS.includes(kind) ? kind : 'unknown',
|
|
865
|
+
label: typeof trigger.label === 'string' && trigger.label ? boundedString(trigger.label, 200) : null,
|
|
866
|
+
surface: typeof trigger.surface === 'string' && trigger.surface ? boundedString(trigger.surface, 300) : null,
|
|
867
|
+
};
|
|
868
|
+
}
|
|
869
|
+
|
|
870
|
+
/// ORCH-6: a conversation that moved to another surface (Hermes `handoff_*`).
|
|
871
|
+
function readCrossSurface(value) {
|
|
872
|
+
const moved = record(value);
|
|
873
|
+
if (!moved || typeof moved.state !== 'string' || !moved.state) return null;
|
|
874
|
+
return {
|
|
875
|
+
state: boundedString(moved.state, 100),
|
|
876
|
+
platform: typeof moved.platform === 'string' && moved.platform ? boundedString(moved.platform, 100) : null,
|
|
877
|
+
error: typeof moved.error === 'string' && moved.error ? boundedString(moved.error, 500) : null,
|
|
878
|
+
};
|
|
879
|
+
}
|
|
880
|
+
|
|
881
|
+
/// UNI-12: recurring-run grouping. A row that REPRESENTS a group of runs of
|
|
882
|
+
/// the same recurring trigger, so the inventory shows one line, not N.
|
|
883
|
+
function readRecurring(value) {
|
|
884
|
+
const recurring = record(value);
|
|
885
|
+
if (!recurring || typeof recurring.groupKey !== 'string' || !recurring.groupKey) return null;
|
|
886
|
+
const runs = Number.isSafeInteger(recurring.runs) && recurring.runs > 0 ? recurring.runs : 1;
|
|
887
|
+
return {
|
|
888
|
+
groupKey: boundedString(recurring.groupKey, 300),
|
|
889
|
+
runs,
|
|
890
|
+
lastStatus: ['ok', 'failed', 'mixed'].includes(recurring.lastStatus) ? recurring.lastStatus : null,
|
|
891
|
+
};
|
|
892
|
+
}
|
|
893
|
+
|
|
745
894
|
function readSessions(value) {
|
|
746
895
|
if (!Array.isArray(value)) return [];
|
|
747
896
|
return value.flatMap((raw) => {
|
|
@@ -764,6 +913,12 @@ function readSessions(value) {
|
|
|
764
913
|
runtimeStatus: row.runtimeStatus === 'running' || row.runtimeStatus === 'busy' || row.runtimeStatus === 'idle' ? row.runtimeStatus : null,
|
|
765
914
|
...(Number.isSafeInteger(row.subagentCount) && row.subagentCount > 0 ? { subagentCount: row.subagentCount } : {}),
|
|
766
915
|
activity: ACTIVITY_PRIORITY[row.activity] !== undefined ? row.activity : undefined,
|
|
916
|
+
...(row.participant !== undefined ? { participant: readParticipant(row.participant) } : {}),
|
|
917
|
+
workspaceRef: readWorkspaceRef(row.workspaceRef, string(row.cwd)),
|
|
918
|
+
...(readMirror(row.mirror) ? { mirror: readMirror(row.mirror) } : {}),
|
|
919
|
+
...(readTrigger(row.trigger) ? { trigger: readTrigger(row.trigger) } : {}),
|
|
920
|
+
...(readRecurring(row.recurring) ? { recurring: readRecurring(row.recurring) } : {}),
|
|
921
|
+
...(readCrossSurface(row.crossSurface) ? { crossSurface: readCrossSurface(row.crossSurface) } : {}),
|
|
767
922
|
}];
|
|
768
923
|
});
|
|
769
924
|
}
|
|
@@ -1004,6 +1159,10 @@ export function normalizeUiState(value) {
|
|
|
1004
1159
|
canConfigureSettings: raw.canConfigureSettings === true,
|
|
1005
1160
|
messaging: raw.messaging === 'live_peer' ? 'live_peer' : null,
|
|
1006
1161
|
workspace: string(raw.workspace),
|
|
1162
|
+
workspaceRef: readWorkspaceRef(raw.workspaceRef, string(raw.workspace)),
|
|
1163
|
+
participant: readParticipant(raw.participant),
|
|
1164
|
+
mirror: readMirror(raw.mirror),
|
|
1165
|
+
holder: readHolder(raw.holder),
|
|
1007
1166
|
taskPlan: readTaskPlan(raw.taskPlan),
|
|
1008
1167
|
semantics: readSemantics(raw.semantics),
|
|
1009
1168
|
terminalHandoff: readTerminalHandoff(raw.terminalHandoff),
|
|
@@ -1078,6 +1237,61 @@ export function harnessDisplayName(id) {
|
|
|
1078
1237
|
return HARNESS_NAMES[id] ?? id;
|
|
1079
1238
|
}
|
|
1080
1239
|
|
|
1240
|
+
/// ORCH-6: the compact surface key a person reads —
|
|
1241
|
+
/// `telegram:dm:123456`, `slack:channel:C1`, `acp`. Empty for a surface with
|
|
1242
|
+
/// nothing to say (a terminal session).
|
|
1243
|
+
export function surfaceLabel(value) {
|
|
1244
|
+
const surface = record(value);
|
|
1245
|
+
if (!surface) return '';
|
|
1246
|
+
const parts = [surface.platform, surface.kind, surface.chat_id, surface.thread_id]
|
|
1247
|
+
.filter((part) => typeof part === 'string' && part);
|
|
1248
|
+
return parts.length ? boundedString(parts.join(':'), 300) : '';
|
|
1249
|
+
}
|
|
1250
|
+
|
|
1251
|
+
/// ORCH-6: project `harness.v1.sessions.discover` / `sessions.load` rows into
|
|
1252
|
+
/// list rows. This is the ONE client-side mapping from the service's wire
|
|
1253
|
+
/// shape to {@link SessionRowModel}: the conversation nouns
|
|
1254
|
+
/// (`trigger`/`surface`/`profile`/`recurrence`/`cross_surface`/`workspace`)
|
|
1255
|
+
/// are read straight off the server's derivation, never re-derived here.
|
|
1256
|
+
export function sessionRowsFromDescriptors(value) {
|
|
1257
|
+
if (!Array.isArray(value)) return [];
|
|
1258
|
+
return readSessions(value.flatMap((raw) => {
|
|
1259
|
+
const descriptor = record(raw);
|
|
1260
|
+
const locator = record(descriptor?.locator);
|
|
1261
|
+
if (!locator || typeof locator.harness !== 'string' || typeof locator.session_id !== 'string') return [];
|
|
1262
|
+
const surface = record(descriptor.surface);
|
|
1263
|
+
const label = surfaceLabel(surface);
|
|
1264
|
+
const cwd = typeof descriptor.cwd === 'string' ? descriptor.cwd : '';
|
|
1265
|
+
const title = typeof descriptor.title === 'string' ? descriptor.title : '';
|
|
1266
|
+
const recurrence = record(descriptor.recurrence);
|
|
1267
|
+
return [{
|
|
1268
|
+
key: `${locator.harness}:${locator.session_id}`,
|
|
1269
|
+
harness: locator.harness,
|
|
1270
|
+
name: label || cwd.split(/[\\/]/).filter(Boolean).pop() || locator.session_id,
|
|
1271
|
+
cwd,
|
|
1272
|
+
title,
|
|
1273
|
+
updatedAt: descriptor.updated_at_ms ?? null,
|
|
1274
|
+
messages: descriptor.message_count ?? null,
|
|
1275
|
+
active: false,
|
|
1276
|
+
writable: false,
|
|
1277
|
+
live: false,
|
|
1278
|
+
runtimeStatus: null,
|
|
1279
|
+
subagentCount: descriptor.child_session_count,
|
|
1280
|
+
workspaceRef: descriptor.workspace,
|
|
1281
|
+
trigger: { kind: descriptor.trigger ?? 'unknown', label: recurrence?.job_id ?? descriptor.profile ?? null, surface: label || null },
|
|
1282
|
+
// One fire is one row: supercode renders the grouping a harness
|
|
1283
|
+
// publishes, it never invents a run count it has not counted.
|
|
1284
|
+
...(recurrence?.job_id ? { recurring: { groupKey: recurrence.job_id, runs: 1, lastStatus: null } } : {}),
|
|
1285
|
+
...(descriptor.cross_surface ? { crossSurface: descriptor.cross_surface } : {}),
|
|
1286
|
+
// A channel surface names the person who reached the agent; a terminal
|
|
1287
|
+
// session has no platform and stays the local user.
|
|
1288
|
+
...(surface?.platform && surface?.participant_id
|
|
1289
|
+
? { participant: { kind: 'foreign', label: surface.participant_id, origin: surface.platform } }
|
|
1290
|
+
: {}),
|
|
1291
|
+
}];
|
|
1292
|
+
}));
|
|
1293
|
+
}
|
|
1294
|
+
|
|
1081
1295
|
export function sessionDisplayName(session) {
|
|
1082
1296
|
const title = session.title?.trim();
|
|
1083
1297
|
return title && title !== session.name ? title : session.name || 'Untitled chat';
|
package/embed.mjs
CHANGED
|
@@ -35,6 +35,10 @@ var EMPTY_UI_STATE = Object.freeze({
|
|
|
35
35
|
harness: "",
|
|
36
36
|
mode: "none",
|
|
37
37
|
strategy: null,
|
|
38
|
+
participant: Object.freeze({ kind: "local-user", label: null, origin: null }),
|
|
39
|
+
workspaceRef: Object.freeze({ kind: "none", value: null }),
|
|
40
|
+
mirror: null,
|
|
41
|
+
holder: null,
|
|
38
42
|
canSend: false,
|
|
39
43
|
canSteer: false,
|
|
40
44
|
canResume: false,
|
|
@@ -644,12 +648,40 @@ function readToolPresentation(value, entry) {
|
|
|
644
648
|
matches: nullableNumber(item.matches) ?? generated.matches
|
|
645
649
|
};
|
|
646
650
|
}
|
|
651
|
+
var OPAQUE_RAW_CHARS = 4e3;
|
|
652
|
+
function opaqueEntry(item) {
|
|
653
|
+
const previouslyOpaque = item.role === "opaque";
|
|
654
|
+
let raw;
|
|
655
|
+
if (previouslyOpaque && typeof item.raw === "string") {
|
|
656
|
+
raw = item.raw;
|
|
657
|
+
} else {
|
|
658
|
+
try {
|
|
659
|
+
raw = JSON.stringify(item, null, 2) ?? "";
|
|
660
|
+
} catch {
|
|
661
|
+
raw = "[unserializable entry payload]";
|
|
662
|
+
}
|
|
663
|
+
}
|
|
664
|
+
const kind = previouslyOpaque && typeof item.kind === "string" ? item.kind : typeof item.role === "string" ? item.role : "";
|
|
665
|
+
return {
|
|
666
|
+
id: item.id,
|
|
667
|
+
role: "opaque",
|
|
668
|
+
kind: boundedString(kind, 120) || "unknown",
|
|
669
|
+
text: typeof item.text === "string" ? boundedString(item.text, OPAQUE_RAW_CHARS) : "",
|
|
670
|
+
ts: nullableNumber(item.ts),
|
|
671
|
+
truncated: item.truncated === true || raw.length > OPAQUE_RAW_CHARS,
|
|
672
|
+
raw: boundedString(raw, OPAQUE_RAW_CHARS)
|
|
673
|
+
};
|
|
674
|
+
}
|
|
647
675
|
function readTranscript(value) {
|
|
648
676
|
if (!Array.isArray(value)) return [];
|
|
649
677
|
const result = [];
|
|
650
678
|
for (const candidate of value) {
|
|
651
679
|
const item = record(candidate);
|
|
652
|
-
if (!item || typeof item.id !== "string"
|
|
680
|
+
if (!item || typeof item.id !== "string") continue;
|
|
681
|
+
if (typeof item.text !== "string" || !ROLES.has(item.role)) {
|
|
682
|
+
result.push(opaqueEntry(item));
|
|
683
|
+
continue;
|
|
684
|
+
}
|
|
653
685
|
const entry = {
|
|
654
686
|
id: item.id,
|
|
655
687
|
role: item.role,
|
|
@@ -707,6 +739,75 @@ function readTranscript(value) {
|
|
|
707
739
|
}
|
|
708
740
|
return result;
|
|
709
741
|
}
|
|
742
|
+
function readParticipant(value) {
|
|
743
|
+
const participant = record(value);
|
|
744
|
+
if (!participant) return { kind: "local-user", label: null, origin: null };
|
|
745
|
+
return {
|
|
746
|
+
kind: ["local-user", "foreign", "unknown"].includes(participant.kind) ? participant.kind : "unknown",
|
|
747
|
+
label: typeof participant.label === "string" && participant.label ? boundedString(participant.label, 200) : null,
|
|
748
|
+
origin: typeof participant.origin === "string" && participant.origin ? boundedString(participant.origin, 100) : null
|
|
749
|
+
};
|
|
750
|
+
}
|
|
751
|
+
function readWorkspaceRef(value, fallbackPath = "") {
|
|
752
|
+
const ref = record(value);
|
|
753
|
+
if (ref && ["repo", "none", "channel"].includes(ref.kind)) {
|
|
754
|
+
return {
|
|
755
|
+
kind: ref.kind,
|
|
756
|
+
value: ref.kind === "none" ? null : typeof ref.value === "string" && ref.value ? boundedString(ref.value, 500) : null
|
|
757
|
+
};
|
|
758
|
+
}
|
|
759
|
+
return fallbackPath ? { kind: "repo", value: boundedString(fallbackPath, 500) } : { kind: "none", value: null };
|
|
760
|
+
}
|
|
761
|
+
function readMirror(value) {
|
|
762
|
+
const mirror = record(value);
|
|
763
|
+
if (!mirror || typeof mirror.canonicalHarness !== "string" || !mirror.canonicalHarness) return null;
|
|
764
|
+
return {
|
|
765
|
+
canonicalHarness: boundedString(mirror.canonicalHarness, 100),
|
|
766
|
+
canonicalKey: typeof mirror.canonicalKey === "string" && mirror.canonicalKey ? boundedString(mirror.canonicalKey, 300) : null,
|
|
767
|
+
bounded: mirror.bounded === true,
|
|
768
|
+
truncated: mirror.truncated === true,
|
|
769
|
+
origin: typeof mirror.origin === "string" && mirror.origin ? boundedString(mirror.origin, 200) : null
|
|
770
|
+
};
|
|
771
|
+
}
|
|
772
|
+
function readHolder(value) {
|
|
773
|
+
const holder = record(value);
|
|
774
|
+
if (!holder) return null;
|
|
775
|
+
const surface = typeof holder.surface === "string" && holder.surface ? boundedString(holder.surface, 100) : null;
|
|
776
|
+
return {
|
|
777
|
+
surface,
|
|
778
|
+
canTakeOver: holder.canTakeOver === true && surface !== null && surface !== "supercode"
|
|
779
|
+
};
|
|
780
|
+
}
|
|
781
|
+
var TRIGGER_KINDS = ["human", "channel", "cron", "heartbeat", "webhook", "parent", "api", "unknown"];
|
|
782
|
+
function readTrigger(value) {
|
|
783
|
+
const trigger = record(value);
|
|
784
|
+
if (!trigger) return null;
|
|
785
|
+
const kind = trigger.kind === "manual" ? "human" : trigger.kind;
|
|
786
|
+
return {
|
|
787
|
+
kind: TRIGGER_KINDS.includes(kind) ? kind : "unknown",
|
|
788
|
+
label: typeof trigger.label === "string" && trigger.label ? boundedString(trigger.label, 200) : null,
|
|
789
|
+
surface: typeof trigger.surface === "string" && trigger.surface ? boundedString(trigger.surface, 300) : null
|
|
790
|
+
};
|
|
791
|
+
}
|
|
792
|
+
function readCrossSurface(value) {
|
|
793
|
+
const moved = record(value);
|
|
794
|
+
if (!moved || typeof moved.state !== "string" || !moved.state) return null;
|
|
795
|
+
return {
|
|
796
|
+
state: boundedString(moved.state, 100),
|
|
797
|
+
platform: typeof moved.platform === "string" && moved.platform ? boundedString(moved.platform, 100) : null,
|
|
798
|
+
error: typeof moved.error === "string" && moved.error ? boundedString(moved.error, 500) : null
|
|
799
|
+
};
|
|
800
|
+
}
|
|
801
|
+
function readRecurring(value) {
|
|
802
|
+
const recurring = record(value);
|
|
803
|
+
if (!recurring || typeof recurring.groupKey !== "string" || !recurring.groupKey) return null;
|
|
804
|
+
const runs = Number.isSafeInteger(recurring.runs) && recurring.runs > 0 ? recurring.runs : 1;
|
|
805
|
+
return {
|
|
806
|
+
groupKey: boundedString(recurring.groupKey, 300),
|
|
807
|
+
runs,
|
|
808
|
+
lastStatus: ["ok", "failed", "mixed"].includes(recurring.lastStatus) ? recurring.lastStatus : null
|
|
809
|
+
};
|
|
810
|
+
}
|
|
710
811
|
function readSessions(value) {
|
|
711
812
|
if (!Array.isArray(value)) return [];
|
|
712
813
|
return value.flatMap((raw) => {
|
|
@@ -728,7 +829,13 @@ function readSessions(value) {
|
|
|
728
829
|
live: row.live === true,
|
|
729
830
|
runtimeStatus: row.runtimeStatus === "running" || row.runtimeStatus === "busy" || row.runtimeStatus === "idle" ? row.runtimeStatus : null,
|
|
730
831
|
...Number.isSafeInteger(row.subagentCount) && row.subagentCount > 0 ? { subagentCount: row.subagentCount } : {},
|
|
731
|
-
activity: ACTIVITY_PRIORITY[row.activity] !== void 0 ? row.activity : void 0
|
|
832
|
+
activity: ACTIVITY_PRIORITY[row.activity] !== void 0 ? row.activity : void 0,
|
|
833
|
+
...row.participant !== void 0 ? { participant: readParticipant(row.participant) } : {},
|
|
834
|
+
workspaceRef: readWorkspaceRef(row.workspaceRef, string(row.cwd)),
|
|
835
|
+
...readMirror(row.mirror) ? { mirror: readMirror(row.mirror) } : {},
|
|
836
|
+
...readTrigger(row.trigger) ? { trigger: readTrigger(row.trigger) } : {},
|
|
837
|
+
...readRecurring(row.recurring) ? { recurring: readRecurring(row.recurring) } : {},
|
|
838
|
+
...readCrossSurface(row.crossSurface) ? { crossSurface: readCrossSurface(row.crossSurface) } : {}
|
|
732
839
|
}];
|
|
733
840
|
});
|
|
734
841
|
}
|
|
@@ -912,6 +1019,10 @@ function normalizeUiState(value) {
|
|
|
912
1019
|
canConfigureSettings: raw.canConfigureSettings === true,
|
|
913
1020
|
messaging: raw.messaging === "live_peer" ? "live_peer" : null,
|
|
914
1021
|
workspace: string(raw.workspace),
|
|
1022
|
+
workspaceRef: readWorkspaceRef(raw.workspaceRef, string(raw.workspace)),
|
|
1023
|
+
participant: readParticipant(raw.participant),
|
|
1024
|
+
mirror: readMirror(raw.mirror),
|
|
1025
|
+
holder: readHolder(raw.holder),
|
|
915
1026
|
taskPlan: readTaskPlan(raw.taskPlan),
|
|
916
1027
|
semantics: readSemantics(raw.semantics),
|
|
917
1028
|
terminalHandoff: readTerminalHandoff(raw.terminalHandoff),
|
|
@@ -1073,6 +1184,12 @@ import { useEffect as useEffect2, useRef as useRef2, useState as useState2 } fro
|
|
|
1073
1184
|
|
|
1074
1185
|
// src/memory.js
|
|
1075
1186
|
var MEMORY_LIMIT = 100;
|
|
1187
|
+
var registry = /* @__PURE__ */ new Set();
|
|
1188
|
+
function uiMemory() {
|
|
1189
|
+
const map = /* @__PURE__ */ new Map();
|
|
1190
|
+
registry.add(map);
|
|
1191
|
+
return map;
|
|
1192
|
+
}
|
|
1076
1193
|
function boundedSet(map, key, value) {
|
|
1077
1194
|
map.delete(key);
|
|
1078
1195
|
map.set(key, value);
|
|
@@ -1426,7 +1543,7 @@ function MessageImages({ items, adapter }) {
|
|
|
1426
1543
|
}
|
|
1427
1544
|
|
|
1428
1545
|
// src/intent.js
|
|
1429
|
-
var CONFIRMABLE_ACTIONS = /* @__PURE__ */ new Set(["resume", "join", "branch", "reduce", "export"]);
|
|
1546
|
+
var CONFIRMABLE_ACTIONS = /* @__PURE__ */ new Set(["resume", "join", "branch", "reduce", "export", "take_over"]);
|
|
1430
1547
|
async function dispatchConfirmedIntent(adapter, intent) {
|
|
1431
1548
|
if (CONFIRMABLE_ACTIONS.has(intent.action) && adapter.confirmIntent) {
|
|
1432
1549
|
const confirmed = await adapter.confirmIntent(intent);
|
|
@@ -1451,7 +1568,7 @@ function useAutosizeTextarea(ref, value) {
|
|
|
1451
1568
|
|
|
1452
1569
|
// src/composer.jsx
|
|
1453
1570
|
import { jsx as jsx3, jsxs as jsxs3 } from "preact/jsx-runtime";
|
|
1454
|
-
var composerMemory =
|
|
1571
|
+
var composerMemory = uiMemory();
|
|
1455
1572
|
function ExecutionModeSelect({ modes = [], value, onChange, disabled = false, label = "Run in" }) {
|
|
1456
1573
|
if (modes.length < 2) return null;
|
|
1457
1574
|
return /* @__PURE__ */ jsxs3("label", { className: "scui-execution-mode", title: disabled ? void 0 : `${label}: ${value}`, children: [
|
|
@@ -1747,7 +1864,11 @@ function languageLabel(info) {
|
|
|
1747
1864
|
}
|
|
1748
1865
|
function frameCode(render2, tokens, index, options, env, self) {
|
|
1749
1866
|
const label = markdown.utils.escapeHtml(languageLabel(tokens[index]?.info ?? ""));
|
|
1750
|
-
|
|
1867
|
+
const body = render2(tokens, index, options, env, self).replace(
|
|
1868
|
+
"<pre>",
|
|
1869
|
+
`<pre tabindex="0" role="region" aria-label="${label} code">`
|
|
1870
|
+
);
|
|
1871
|
+
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>`;
|
|
1751
1872
|
}
|
|
1752
1873
|
for (const kind of ["fence", "code_block"]) {
|
|
1753
1874
|
const render2 = markdown.renderer.rules[kind];
|
|
@@ -2084,6 +2205,26 @@ function TechnicalDetails({ entry }) {
|
|
|
2084
2205
|
] });
|
|
2085
2206
|
}
|
|
2086
2207
|
function TranscriptEntry({ entry, state, adapter }) {
|
|
2208
|
+
if (entry.role === "opaque") {
|
|
2209
|
+
return /* @__PURE__ */ jsxs4("article", { className: "scui-message scui-opaque", "data-role": "opaque", "data-kind": entry.kind, "aria-label": "Unrecognized entry", children: [
|
|
2210
|
+
/* @__PURE__ */ jsxs4("div", { className: "scui-notice", "data-code": "opaque-entry", children: [
|
|
2211
|
+
"Unrecognized entry kind ",
|
|
2212
|
+
/* @__PURE__ */ jsx5("code", { children: entry.kind }),
|
|
2213
|
+
" \u2014 kept as-is, nothing dropped"
|
|
2214
|
+
] }),
|
|
2215
|
+
entry.text ? /* @__PURE__ */ jsx5(Markdown, { value: entry.text, copyText: adapter?.copyText }) : null,
|
|
2216
|
+
entry.raw ? /* @__PURE__ */ jsxs4("details", { className: "scui-tool-technical", children: [
|
|
2217
|
+
/* @__PURE__ */ jsx5("summary", { children: "Technical details" }),
|
|
2218
|
+
/* @__PURE__ */ jsx5("div", { children: /* @__PURE__ */ jsxs4("section", { children: [
|
|
2219
|
+
/* @__PURE__ */ jsx5("strong", { children: "Raw entry" }),
|
|
2220
|
+
/* @__PURE__ */ jsxs4("pre", { children: [
|
|
2221
|
+
entry.raw,
|
|
2222
|
+
entry.truncated ? "\n[truncated]" : ""
|
|
2223
|
+
] })
|
|
2224
|
+
] }) })
|
|
2225
|
+
] }) : null
|
|
2226
|
+
] });
|
|
2227
|
+
}
|
|
2087
2228
|
if (entry.role === "request") return /* @__PURE__ */ jsx5(RequestCard, { entry, adapter, canRespond: state.canRespond });
|
|
2088
2229
|
if (entry.role === "reasoning") {
|
|
2089
2230
|
return /* @__PURE__ */ jsxs4("details", { className: "scui-reasoning", open: entry.streaming, children: [
|
|
@@ -2213,7 +2354,7 @@ function SessionDetails({ semantics }) {
|
|
|
2213
2354
|
] })
|
|
2214
2355
|
] });
|
|
2215
2356
|
}
|
|
2216
|
-
var conversationMemory =
|
|
2357
|
+
var conversationMemory = uiMemory();
|
|
2217
2358
|
function ConversationAnnouncements({ state }) {
|
|
2218
2359
|
const previousBusy = useRef4(state.busy);
|
|
2219
2360
|
const [announcement, setAnnouncement] = useState3("");
|
|
@@ -2393,7 +2534,7 @@ function HarnessLogo({ id, activity, size = 28, onMissingLogo }) {
|
|
|
2393
2534
|
// src/sessions.jsx
|
|
2394
2535
|
import { useEffect as useEffect6, useLayoutEffect as useLayoutEffect3, useRef as useRef5, useState as useState4 } from "preact/hooks";
|
|
2395
2536
|
import { jsx as jsx7, jsxs as jsxs6 } from "preact/jsx-runtime";
|
|
2396
|
-
var sessionListMemory =
|
|
2537
|
+
var sessionListMemory = uiMemory();
|
|
2397
2538
|
function sessionPathParts(value) {
|
|
2398
2539
|
const complete = String(value ?? "").replaceAll("\\", "/");
|
|
2399
2540
|
const boundary = complete.lastIndexOf("/");
|
|
@@ -2415,11 +2556,55 @@ function SessionRow({ row, state, onOpen, onOpenSubagents, now = Date.now() }) {
|
|
|
2415
2556
|
const unreadCount = attention?.unreadCount ?? 0;
|
|
2416
2557
|
const unreadLabel = unreadCount > 99 ? "99+" : String(unreadCount);
|
|
2417
2558
|
const age = relativeAge(row.previewUpdatedAt ?? row.updatedAt, now) || row.age;
|
|
2418
|
-
|
|
2559
|
+
const nounBadges = [];
|
|
2560
|
+
if (row.trigger && row.trigger.kind !== "manual" && row.trigger.kind !== "human") {
|
|
2561
|
+
const runs = row.recurring?.runs;
|
|
2562
|
+
const detail = row.trigger.label || row.trigger.surface || "";
|
|
2563
|
+
nounBadges.push(
|
|
2564
|
+
/* @__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: [
|
|
2565
|
+
row.trigger.kind,
|
|
2566
|
+
detail ? ` \xB7 ${detail}` : "",
|
|
2567
|
+
runs && runs > 1 ? ` \xB7 \xD7${runs}` : ""
|
|
2568
|
+
] }, "trigger")
|
|
2569
|
+
);
|
|
2570
|
+
}
|
|
2571
|
+
if (row.crossSurface) {
|
|
2572
|
+
nounBadges.push(
|
|
2573
|
+
/* @__PURE__ */ jsxs6("small", { className: "scui-session-noun", "data-noun": "cross-surface", "data-state": row.crossSurface.state, title: row.crossSurface.error ?? void 0, children: [
|
|
2574
|
+
"\u2192",
|
|
2575
|
+
row.crossSurface.platform ?? "elsewhere",
|
|
2576
|
+
" \xB7 ",
|
|
2577
|
+
row.crossSurface.state
|
|
2578
|
+
] }, "cross-surface")
|
|
2579
|
+
);
|
|
2580
|
+
}
|
|
2581
|
+
if (row.participant && row.participant.kind !== "local-user") {
|
|
2582
|
+
nounBadges.push(
|
|
2583
|
+
/* @__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")
|
|
2584
|
+
);
|
|
2585
|
+
}
|
|
2586
|
+
if (row.mirror) {
|
|
2587
|
+
nounBadges.push(
|
|
2588
|
+
/* @__PURE__ */ jsxs6("small", { className: "scui-session-noun", "data-noun": "mirror", "data-truncated": row.mirror.truncated, children: [
|
|
2589
|
+
"mirror of ",
|
|
2590
|
+
harnessDisplayName(row.mirror.canonicalHarness)
|
|
2591
|
+
] }, "mirror")
|
|
2592
|
+
);
|
|
2593
|
+
}
|
|
2594
|
+
if (row.workspaceRef?.kind === "channel") {
|
|
2595
|
+
nounBadges.push(
|
|
2596
|
+
/* @__PURE__ */ jsxs6("small", { className: "scui-session-noun", "data-noun": "workspace", "data-kind": "channel", children: [
|
|
2597
|
+
"#",
|
|
2598
|
+
row.workspaceRef.value ?? "channel"
|
|
2599
|
+
] }, "workspace")
|
|
2600
|
+
);
|
|
2601
|
+
}
|
|
2602
|
+
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: [
|
|
2419
2603
|
/* @__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: [
|
|
2420
2604
|
/* @__PURE__ */ jsx7(HarnessLogo, { id: row.harness, activity, size: 34 }),
|
|
2421
2605
|
/* @__PURE__ */ jsxs6("span", { className: "scui-session-copy", children: [
|
|
2422
2606
|
/* @__PURE__ */ jsx7("span", { className: "scui-session-title", children: /* @__PURE__ */ jsx7("strong", { children: title }) }),
|
|
2607
|
+
nounBadges.length ? /* @__PURE__ */ jsx7("span", { className: "scui-session-nouns", children: nounBadges }) : null,
|
|
2423
2608
|
path.complete ? /* @__PURE__ */ jsxs6("small", { className: "scui-session-path", title: row.cwd, children: [
|
|
2424
2609
|
/* @__PURE__ */ jsx7("span", { className: "scui-session-path-leading", children: path.leading }),
|
|
2425
2610
|
path.separator ? /* @__PURE__ */ jsx7("span", { className: "scui-session-path-separator", children: path.separator }) : null,
|
|
@@ -2834,10 +3019,54 @@ function HarnessPicker({ harnesses, state, value, disabled = false, adapter, onC
|
|
|
2834
3019
|
|
|
2835
3020
|
// src/messenger.jsx
|
|
2836
3021
|
import { Fragment as Fragment5, jsx as jsx10, jsxs as jsxs9 } from "preact/jsx-runtime";
|
|
2837
|
-
var pendingMessageMemory =
|
|
2838
|
-
var messengerViewMemory =
|
|
2839
|
-
var newChatMemory =
|
|
3022
|
+
var pendingMessageMemory = uiMemory();
|
|
3023
|
+
var messengerViewMemory = uiMemory();
|
|
3024
|
+
var newChatMemory = uiMemory();
|
|
2840
3025
|
var TRACKED_ACTIONS = /* @__PURE__ */ new Set(["resume", "join", "detach", "branch", "reduce", "terminal", "export", "steer", "interrupt", "respond", "configureHarness", "refresh", "loadEarlier", "loadSessions"]);
|
|
3026
|
+
function UniversalNouns({ state, adapter }) {
|
|
3027
|
+
const banners = [];
|
|
3028
|
+
if (state.participant && state.participant.kind !== "local-user") {
|
|
3029
|
+
banners.push(
|
|
3030
|
+
/* @__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: [
|
|
3031
|
+
"This is ",
|
|
3032
|
+
/* @__PURE__ */ jsx10("strong", { children: state.participant.label ?? "someone else's" }),
|
|
3033
|
+
" conversation",
|
|
3034
|
+
state.participant.origin ? /* @__PURE__ */ jsxs9(Fragment5, { children: [
|
|
3035
|
+
" via ",
|
|
3036
|
+
state.participant.origin
|
|
3037
|
+
] }) : null,
|
|
3038
|
+
"."
|
|
3039
|
+
] }) : /* @__PURE__ */ jsx10(Fragment5, { children: "Unknown participant \u2014 this conversation was not started here." }) }, "participant")
|
|
3040
|
+
);
|
|
3041
|
+
}
|
|
3042
|
+
if (state.mirror) {
|
|
3043
|
+
banners.push(
|
|
3044
|
+
/* @__PURE__ */ jsxs9("div", { className: "scui-notice scui-noun-banner", "data-noun": "mirror", "data-truncated": state.mirror.truncated, children: [
|
|
3045
|
+
state.mirror.bounded ? "Bounded mirror" : "Mirror",
|
|
3046
|
+
" of a ",
|
|
3047
|
+
/* @__PURE__ */ jsx10("strong", { children: harnessDisplayName(state.mirror.canonicalHarness) }),
|
|
3048
|
+
" session \u2014 the canonical record lives in its own store",
|
|
3049
|
+
state.mirror.truncated ? " (truncated here)" : "",
|
|
3050
|
+
".",
|
|
3051
|
+
state.mirror.canonicalKey ? /* @__PURE__ */ jsx10("button", { type: "button", onClick: () => adapter.onIntent({ action: "open_session", key: state.mirror.canonicalKey }), children: "Open canonical session" }) : null
|
|
3052
|
+
] }, "mirror")
|
|
3053
|
+
);
|
|
3054
|
+
}
|
|
3055
|
+
if (state.holder && state.holder.surface !== "supercode") {
|
|
3056
|
+
banners.push(
|
|
3057
|
+
/* @__PURE__ */ jsxs9("div", { className: "scui-notice scui-noun-banner", "data-noun": "holder", "data-surface": state.holder.surface ?? "unheld", children: [
|
|
3058
|
+
state.holder.surface ? /* @__PURE__ */ jsxs9(Fragment5, { children: [
|
|
3059
|
+
"Held by ",
|
|
3060
|
+
/* @__PURE__ */ jsx10("strong", { children: state.holder.surface }),
|
|
3061
|
+
" right now."
|
|
3062
|
+
] }) : /* @__PURE__ */ jsx10(Fragment5, { children: "No surface holds this session right now." }),
|
|
3063
|
+
state.holder.canTakeOver ? /* @__PURE__ */ jsx10("button", { type: "button", onClick: () => dispatchConfirmedIntent(adapter, { action: "take_over" }), children: "Take over" }) : null
|
|
3064
|
+
] }, "holder")
|
|
3065
|
+
);
|
|
3066
|
+
}
|
|
3067
|
+
if (!banners.length) return null;
|
|
3068
|
+
return /* @__PURE__ */ jsx10("div", { className: "scui-noun-banners", children: banners });
|
|
3069
|
+
}
|
|
2841
3070
|
function Receipt({ state, adapter }) {
|
|
2842
3071
|
const receipt = state.reductionReceipt;
|
|
2843
3072
|
if (receipt) return /* @__PURE__ */ jsx10("div", { className: "scui-receipt", children: /* @__PURE__ */ jsxs9("span", { children: [
|
|
@@ -3101,6 +3330,7 @@ function Chat({ state, adapter, onBack, onNew, onClose, components, slots, label
|
|
|
3101
3330
|
state.recoverable ? /* @__PURE__ */ jsx10("button", { type: "button", disabled: Boolean(action), onClick: () => trackedAdapter.onIntent({ action: "refresh" }), children: "Retry" }) : null
|
|
3102
3331
|
] }) : null,
|
|
3103
3332
|
/* @__PURE__ */ jsx10(Receipt, { state, adapter }),
|
|
3333
|
+
/* @__PURE__ */ jsx10(UniversalNouns, { state: actionState, adapter: trackedAdapter }),
|
|
3104
3334
|
/* @__PURE__ */ jsx10(Conversation, { state: actionState, adapter: trackedAdapter, components, slots, memoryKey, pending: pendingMessage, unreadAfterMessages }, memoryKey),
|
|
3105
3335
|
/* @__PURE__ */ jsx10(ContinuationBar, { state: actionState, adapter: trackedAdapter, labels }),
|
|
3106
3336
|
/* @__PURE__ */ jsx10(Advisory, { state: actionState, adapter: trackedAdapter, value: state.interopSettings?.advisories[0] ?? null, onReview: (recommendedChange) => setSettings({ recommendedChange }) }),
|