dsh-wsr-execution 0.2.1 → 0.2.3
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/README.md +1 -1
- package/lib/client.js +415 -112
- package/package.json +4 -4
- package/src/action-presentation/model.js +29 -12
- package/src/action-presentation/view.js +178 -20
- package/src/client/browser-entry.js +23 -4
- package/src/client/delivery/control-plane-port.js +11 -2
- package/src/client/delivery/session-delivery-view.js +148 -37
- package/src/client/delivery-inventory/model.js +17 -3
- package/src/host/delivery-control-plane.js +39 -12
- package/src/intake/binding-repository.js +118 -41
- package/src/intake/command.js +17 -1
- package/src/intake/plugin.js +140 -42
package/lib/client.js
CHANGED
|
@@ -2517,7 +2517,7 @@ var KINDS = /* @__PURE__ */ new Set([
|
|
|
2517
2517
|
"terminal-result",
|
|
2518
2518
|
"error"
|
|
2519
2519
|
]);
|
|
2520
|
-
var ACTION_STATES = /* @__PURE__ */ new Set(["running", "completed", "failed", "cancelled", "waiting", "recovering"]);
|
|
2520
|
+
var ACTION_STATES = /* @__PURE__ */ new Set(["running", "completed", "failed", "cancelled", "waiting", "recovering", "uncertain", "unresolved"]);
|
|
2521
2521
|
var TERMINAL_OUTCOMES = /* @__PURE__ */ new Set(["SUCCEEDED", "FAILED", "CANCELLED"]);
|
|
2522
2522
|
var DELIVERY_STATES = /* @__PURE__ */ new Set([
|
|
2523
2523
|
"BOUND",
|
|
@@ -2567,11 +2567,15 @@ function hasValidTypedData(value) {
|
|
|
2567
2567
|
return typeof state === "string" && ACTION_STATES.has(state) && (channel === "action" || channel === "tool");
|
|
2568
2568
|
}
|
|
2569
2569
|
if (value.kind === "terminal-result") {
|
|
2570
|
-
const
|
|
2570
|
+
const hasFinalOutput = Object.hasOwn(value.data, "finalOutput");
|
|
2571
|
+
const hasSummary = Object.hasOwn(value.data, "summary");
|
|
2572
|
+
const outputValid = hasFinalOutput ? typeof value.data.finalOutput === "string" && value.data.finalOutput.length > 0 : hasSummary ? typeof value.data.summary === "string" && value.data.summary.length > 0 : value.data.outcome === "SUCCEEDED";
|
|
2571
2573
|
return typeof value.data.outcome === "string" && TERMINAL_OUTCOMES.has(value.data.outcome) && outputValid;
|
|
2572
2574
|
}
|
|
2573
2575
|
if (value.kind === "delivery-running" || value.kind === "delivery-status") {
|
|
2574
|
-
|
|
2576
|
+
const diagnostic2 = value.data.diagnostic;
|
|
2577
|
+
const diagnosticValid = diagnostic2 === void 0 || diagnostic2 !== null && typeof diagnostic2 === "object" && !Array.isArray(diagnostic2) && Object.keys(diagnostic2).sort().join(",") === "causeCode,stage" && typeof diagnostic2.stage === "string" && /^[A-Z][A-Z0-9_]{0,63}$/u.test(diagnostic2.stage) && typeof diagnostic2.causeCode === "string" && /^[A-Z][A-Z0-9_]{0,127}$/u.test(diagnostic2.causeCode);
|
|
2578
|
+
return diagnosticValid && (value.data.state === void 0 || typeof value.data.state === "string" && DELIVERY_STATES.has(value.data.state));
|
|
2575
2579
|
}
|
|
2576
2580
|
return true;
|
|
2577
2581
|
}
|
|
@@ -2610,8 +2614,10 @@ function normalizedLifecycle(value, fallback) {
|
|
|
2610
2614
|
if (["cancelled", "canceled"].includes(normalized)) return "cancelled";
|
|
2611
2615
|
if (["waiting", "awaiting-input"].includes(normalized)) return "waiting";
|
|
2612
2616
|
if (["start-failed"].includes(normalized)) return "failed";
|
|
2613
|
-
if (
|
|
2614
|
-
if (
|
|
2617
|
+
if (normalized === "start-uncertain") return "uncertain";
|
|
2618
|
+
if (normalized === "result-unresolved") return "unresolved";
|
|
2619
|
+
if (["recovering", "recovery", "terminal-handling"].includes(normalized)) return "recovering";
|
|
2620
|
+
if (["running", "accepted", "running-correlated", "bound"].includes(normalized)) return "running";
|
|
2615
2621
|
return fallback;
|
|
2616
2622
|
}
|
|
2617
2623
|
var STATE_LABELS = Object.freeze({
|
|
@@ -2620,7 +2626,9 @@ var STATE_LABELS = Object.freeze({
|
|
|
2620
2626
|
failed: "Failed",
|
|
2621
2627
|
cancelled: "Cancelled",
|
|
2622
2628
|
waiting: "Waiting for input",
|
|
2623
|
-
recovering: "Recovering"
|
|
2629
|
+
recovering: "Recovering",
|
|
2630
|
+
uncertain: "Start uncertain",
|
|
2631
|
+
unresolved: "Result unresolved"
|
|
2624
2632
|
});
|
|
2625
2633
|
function model(input) {
|
|
2626
2634
|
return deepFreeze(input);
|
|
@@ -2638,7 +2646,7 @@ function projectExecutionPresentation(event) {
|
|
|
2638
2646
|
title: "Final result",
|
|
2639
2647
|
summary: data.outcome[0] + data.outcome.slice(1).toLowerCase(),
|
|
2640
2648
|
body,
|
|
2641
|
-
defaultOpen:
|
|
2649
|
+
defaultOpen: false,
|
|
2642
2650
|
focusPolicy: "none",
|
|
2643
2651
|
role: "article",
|
|
2644
2652
|
compatibility: typeof data.finalOutput === "string" ? "current" : "legacy-summary"
|
|
@@ -2667,7 +2675,7 @@ function projectExecutionPresentation(event) {
|
|
|
2667
2675
|
title: typeof data.label === "string" ? data.label : "Workflow Action",
|
|
2668
2676
|
summary: STATE_LABELS[state2],
|
|
2669
2677
|
body: text(data.content) ?? "WSR content unavailable",
|
|
2670
|
-
defaultOpen:
|
|
2678
|
+
defaultOpen: false,
|
|
2671
2679
|
focusPolicy: "none",
|
|
2672
2680
|
role: "status",
|
|
2673
2681
|
compatibility: "current"
|
|
@@ -2681,7 +2689,7 @@ function projectExecutionPresentation(event) {
|
|
|
2681
2689
|
title: "Workflow presentation",
|
|
2682
2690
|
summary: typeof data.code === "string" ? data.code : "WSR_ERROR",
|
|
2683
2691
|
body: typeof data.message === "string" ? data.message : "WSR presentation unavailable",
|
|
2684
|
-
defaultOpen:
|
|
2692
|
+
defaultOpen: false,
|
|
2685
2693
|
focusPolicy: "none",
|
|
2686
2694
|
role: "alert",
|
|
2687
2695
|
compatibility: "current"
|
|
@@ -2689,14 +2697,15 @@ function projectExecutionPresentation(event) {
|
|
|
2689
2697
|
}
|
|
2690
2698
|
const state = event.kind === "delivery-running" ? normalizedLifecycle(data.state, "running") : normalizedLifecycle(data.state, event.kind === "command-accepted" ? "running" : "running");
|
|
2691
2699
|
const deliveryId = typeof data.deliveryId === "string" ? data.deliveryId : void 0;
|
|
2700
|
+
const diagnostic2 = data.diagnostic;
|
|
2692
2701
|
return model({
|
|
2693
2702
|
correlation,
|
|
2694
2703
|
layer: "progress",
|
|
2695
2704
|
state,
|
|
2696
2705
|
title: "Workflow delivery",
|
|
2697
2706
|
summary: `${STATE_LABELS[state]}${deliveryId === void 0 ? "" : ` \xB7 ${deliveryId}`}`,
|
|
2698
|
-
body: void 0
|
|
2699
|
-
defaultOpen:
|
|
2707
|
+
body: diagnostic2 === void 0 ? void 0 : `${diagnostic2.stage} \xB7 ${diagnostic2.causeCode}`,
|
|
2708
|
+
defaultOpen: false,
|
|
2700
2709
|
focusPolicy: "none",
|
|
2701
2710
|
role: "status",
|
|
2702
2711
|
compatibility: "current"
|
|
@@ -2705,61 +2714,54 @@ function projectExecutionPresentation(event) {
|
|
|
2705
2714
|
function resolveDisclosureOpen({ current, previousState, nextState, containsFocus }) {
|
|
2706
2715
|
if (nextState === "waiting") return true;
|
|
2707
2716
|
if (nextState === "completed" && previousState !== "completed") return containsFocus ? true : false;
|
|
2708
|
-
if (["running", "recovering", "failed", "cancelled"].includes(nextState) && nextState !== previousState) return true;
|
|
2709
2717
|
return current;
|
|
2710
2718
|
}
|
|
2711
|
-
function createExecutionPresentationDefinition() {
|
|
2712
|
-
return Object.freeze({
|
|
2713
|
-
kind: "wsr-execution-presentation",
|
|
2714
|
-
target: "chat",
|
|
2715
|
-
match(event) {
|
|
2716
|
-
if (event?.type === "command/run" && event.data?.name === "wsr" && event.data?.source?.kind === "plugin" && event.data?.source?.plugin === "workflow-execution" && typeof event.data?.commandId === "string") {
|
|
2717
|
-
return { id: event.data.commandId, role: "start" };
|
|
2718
|
-
}
|
|
2719
|
-
return event?.type === "command/done" && typeof event.data?.commandId === "string" ? { id: event.data.commandId, role: "update" } : null;
|
|
2720
|
-
},
|
|
2721
|
-
start(_context, match) {
|
|
2722
|
-
return Object.freeze({ seq: match.event.seq, presentation: void 0 });
|
|
2723
|
-
},
|
|
2724
|
-
update(context, match) {
|
|
2725
|
-
const event = parseExecutionPresentation(match.event?.data?.text);
|
|
2726
|
-
if (event.kind === "delivery-list") {
|
|
2727
|
-
return Object.freeze({ ...context.state, presentation: void 0 });
|
|
2728
|
-
}
|
|
2729
|
-
return Object.freeze({ ...context.state, presentation: projectExecutionPresentation(event) });
|
|
2730
|
-
},
|
|
2731
|
-
buildViewNode(context) {
|
|
2732
|
-
if (context.state?.presentation === void 0) return null;
|
|
2733
|
-
return Object.freeze({
|
|
2734
|
-
key: context.key,
|
|
2735
|
-
kind: "wsr-execution-presentation",
|
|
2736
|
-
id: context.id,
|
|
2737
|
-
target: "chat",
|
|
2738
|
-
anchorSeq: context.state.seq,
|
|
2739
|
-
location: context.start?.location ?? { kind: "unresolved" },
|
|
2740
|
-
visibility: "visible",
|
|
2741
|
-
data: context.state.presentation
|
|
2742
|
-
});
|
|
2743
|
-
}
|
|
2744
|
-
});
|
|
2745
|
-
}
|
|
2746
2719
|
|
|
2747
2720
|
// packages/execution/src/action-presentation/view.js
|
|
2748
2721
|
var DOT_STATE = Object.freeze({
|
|
2749
2722
|
running: "ongoing",
|
|
2750
2723
|
recovering: "ongoing",
|
|
2724
|
+
uncertain: "warning",
|
|
2725
|
+
unresolved: "warning",
|
|
2751
2726
|
completed: "done",
|
|
2752
2727
|
waiting: "warning",
|
|
2753
2728
|
failed: "error",
|
|
2754
2729
|
cancelled: "error"
|
|
2755
2730
|
});
|
|
2756
|
-
|
|
2731
|
+
var ACTIONS_STYLE_ID = "dsh-wsr-execution-final-actions";
|
|
2732
|
+
var ACTIONS_CSS = ".wsr-answer-actions{align-items:center;gap:10px;height:28px;margin-top:16px;margin-left:-6px;display:flex}.wsr-answer-action{width:28px;height:28px;color:var(--dsw-alias-label-tertiary);cursor:pointer;background:transparent;border:none;border-radius:28px;justify-content:center;align-items:center;padding:6px;display:inline-flex}.wsr-answer-action:hover{background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-secondary)}";
|
|
2733
|
+
function installActionPresentationStyle() {
|
|
2734
|
+
if (typeof document === "undefined" || document.getElementById(ACTIONS_STYLE_ID) !== null) return;
|
|
2735
|
+
const tag = document.createElement("style");
|
|
2736
|
+
tag.id = ACTIONS_STYLE_ID;
|
|
2737
|
+
tag.dataset.plugin = "dsh-wsr-execution";
|
|
2738
|
+
tag.textContent = ACTIONS_CSS;
|
|
2739
|
+
document.head.append(tag);
|
|
2740
|
+
}
|
|
2741
|
+
function createActionPresentationView({
|
|
2742
|
+
React: React2,
|
|
2743
|
+
DisclosureRow: DisclosureRow2,
|
|
2744
|
+
MessageText: MessageText2,
|
|
2745
|
+
StateDot: StateDot2,
|
|
2746
|
+
JsonTree: JsonTree2,
|
|
2747
|
+
Tooltip: Tooltip2,
|
|
2748
|
+
IconCopyOutline16: IconCopyOutline162,
|
|
2749
|
+
IconCheckOutline16: IconCheckOutline162,
|
|
2750
|
+
writeClipboard: writeClipboard2,
|
|
2751
|
+
observe = () => void 0
|
|
2752
|
+
}) {
|
|
2757
2753
|
if (typeof DisclosureRow2 !== "function") throw new TypeError("DSH_DISCLOSURE_ROW_REQUIRED");
|
|
2758
|
-
|
|
2754
|
+
installActionPresentationStyle();
|
|
2755
|
+
return function WsrExecutionPresentationView({ node, technicalDetails }) {
|
|
2759
2756
|
const presentation = node.data;
|
|
2757
|
+
const presentationKind = typeof technicalDetails?.kind === "string" ? technicalDetails.kind : presentation.layer === "final" ? "terminal-result" : presentation.state === "waiting" ? "action-input-request" : ["action", "tool"].includes(presentation.layer) ? "action-output" : presentation.state === "failed" && presentation.title === "Workflow presentation" ? "error" : presentation.layer === "progress" && presentation.state === "running" ? "command-accepted" : "delivery-status";
|
|
2760
2758
|
const [open, setOpen] = React2.useState(presentation.defaultOpen);
|
|
2759
|
+
const [copyState, setCopyState] = React2.useState("idle");
|
|
2761
2760
|
const bodyRef = React2.useRef(null);
|
|
2762
2761
|
const previousState = React2.useRef(presentation.state);
|
|
2762
|
+
const copyPending = React2.useRef(false);
|
|
2763
|
+
const copyEpoch = React2.useRef(0);
|
|
2764
|
+
const copyTimer = React2.useRef(null);
|
|
2763
2765
|
React2.useEffect(() => {
|
|
2764
2766
|
setOpen((current) => resolveDisclosureOpen({
|
|
2765
2767
|
current,
|
|
@@ -2769,23 +2771,70 @@ function createActionPresentationView({ React: React2, DisclosureRow: Disclosure
|
|
|
2769
2771
|
}));
|
|
2770
2772
|
previousState.current = presentation.state;
|
|
2771
2773
|
}, [presentation.state]);
|
|
2774
|
+
React2.useEffect(() => {
|
|
2775
|
+
copyEpoch.current += 1;
|
|
2776
|
+
copyPending.current = false;
|
|
2777
|
+
if (copyTimer.current !== null) clearTimeout(copyTimer.current);
|
|
2778
|
+
copyTimer.current = null;
|
|
2779
|
+
setCopyState("idle");
|
|
2780
|
+
return () => {
|
|
2781
|
+
copyEpoch.current += 1;
|
|
2782
|
+
copyPending.current = false;
|
|
2783
|
+
if (copyTimer.current !== null) clearTimeout(copyTimer.current);
|
|
2784
|
+
};
|
|
2785
|
+
}, [presentation.body, presentation.correlation]);
|
|
2772
2786
|
observe(presentation);
|
|
2773
|
-
if (presentation.layer === "final") {
|
|
2774
|
-
|
|
2775
|
-
|
|
2776
|
-
"
|
|
2777
|
-
|
|
2778
|
-
|
|
2779
|
-
|
|
2780
|
-
|
|
2781
|
-
|
|
2782
|
-
|
|
2787
|
+
if (presentation.layer === "final" && presentation.state === "completed") {
|
|
2788
|
+
const label = copyState === "copied" ? "Copied" : copyState === "failed" ? "Copy failed" : "Copy";
|
|
2789
|
+
const onCopy = async () => {
|
|
2790
|
+
if (copyState === "copied" || copyPending.current) return;
|
|
2791
|
+
const epoch = copyEpoch.current;
|
|
2792
|
+
copyPending.current = true;
|
|
2793
|
+
let accepted = false;
|
|
2794
|
+
try {
|
|
2795
|
+
accepted = await writeClipboard2(presentation.body);
|
|
2796
|
+
} catch {
|
|
2797
|
+
accepted = false;
|
|
2798
|
+
}
|
|
2799
|
+
if (epoch !== copyEpoch.current) return;
|
|
2800
|
+
copyPending.current = false;
|
|
2801
|
+
setCopyState(accepted ? "copied" : "failed");
|
|
2802
|
+
copyTimer.current = globalThis.setTimeout(() => {
|
|
2803
|
+
copyTimer.current = null;
|
|
2804
|
+
setCopyState("idle");
|
|
2805
|
+
}, 1e3);
|
|
2806
|
+
};
|
|
2807
|
+
return React2.createElement(
|
|
2808
|
+
"article",
|
|
2809
|
+
{
|
|
2810
|
+
"data-wsr-presentation": "true",
|
|
2811
|
+
"data-wsr-kind": presentationKind,
|
|
2812
|
+
"data-wsr-surface": "chat",
|
|
2813
|
+
"data-wsr-layer": "final",
|
|
2814
|
+
"data-wsr-state": presentation.state,
|
|
2815
|
+
"data-wsr-correlation": presentation.correlation,
|
|
2816
|
+
"data-wsr-chat-role": "assistant",
|
|
2817
|
+
"data-wsr-compatibility": presentation.compatibility,
|
|
2818
|
+
"aria-label": presentation.title
|
|
2819
|
+
},
|
|
2820
|
+
React2.createElement(MessageText2, { text: presentation.body }),
|
|
2821
|
+
React2.createElement("div", {
|
|
2822
|
+
className: "wsr-answer-actions",
|
|
2823
|
+
"data-wsr-answer-actions": "true"
|
|
2824
|
+
}, React2.createElement(Tooltip2, { label, side: "bottom" }, React2.createElement("button", {
|
|
2825
|
+
type: "button",
|
|
2826
|
+
className: "wsr-answer-action",
|
|
2827
|
+
"aria-label": label,
|
|
2828
|
+
"data-copy-state": copyState,
|
|
2829
|
+
onClick: onCopy
|
|
2830
|
+
}, React2.createElement(copyState === "copied" ? IconCheckOutline162 : IconCopyOutline162, null))))
|
|
2831
|
+
);
|
|
2783
2832
|
}
|
|
2784
2833
|
const waiting = presentation.state === "waiting";
|
|
2785
|
-
const expandable = presentation.body !== void 0 && !waiting;
|
|
2786
|
-
const body = presentation.body === void 0 ? void 0 : React2.createElement("div", {
|
|
2834
|
+
const expandable = (presentation.body !== void 0 || technicalDetails !== void 0) && !waiting;
|
|
2835
|
+
const body = presentation.body === void 0 && technicalDetails === void 0 ? void 0 : React2.createElement("div", {
|
|
2787
2836
|
ref: bodyRef,
|
|
2788
|
-
"data-wsr-presentation": "true",
|
|
2837
|
+
"data-wsr-presentation-body": "true",
|
|
2789
2838
|
"data-wsr-layer": presentation.layer,
|
|
2790
2839
|
"data-wsr-state": presentation.state,
|
|
2791
2840
|
"data-wsr-correlation": presentation.correlation,
|
|
@@ -2794,9 +2843,14 @@ function createActionPresentationView({ React: React2, DisclosureRow: Disclosure
|
|
|
2794
2843
|
tabIndex: waiting ? 0 : void 0,
|
|
2795
2844
|
"aria-label": waiting ? presentation.summary : void 0,
|
|
2796
2845
|
"aria-live": waiting ? "polite" : void 0
|
|
2797
|
-
}, React2.createElement("pre", {
|
|
2846
|
+
}, presentation.body === void 0 ? null : React2.createElement("pre", {
|
|
2798
2847
|
style: { margin: 0, maxHeight: "20rem", overflow: "auto", whiteSpace: "pre-wrap", wordBreak: "break-word" }
|
|
2799
|
-
}, presentation.body)
|
|
2848
|
+
}, presentation.body), technicalDetails === void 0 ? null : React2.createElement(
|
|
2849
|
+
"details",
|
|
2850
|
+
null,
|
|
2851
|
+
React2.createElement("summary", null, "Technical details"),
|
|
2852
|
+
JsonTree2 === void 0 ? React2.createElement("pre", null, JSON.stringify(technicalDetails, null, 2)) : React2.createElement(JsonTree2, { data: technicalDetails, label: "WSR presentation", copyable: true, expandTopLevel: true })
|
|
2853
|
+
));
|
|
2800
2854
|
return React2.createElement(DisclosureRow2, {
|
|
2801
2855
|
icon: React2.createElement(StateDot2, { state: DOT_STATE[presentation.state], size: 10 }),
|
|
2802
2856
|
title: presentation.title,
|
|
@@ -2811,21 +2865,101 @@ function createActionPresentationView({ React: React2, DisclosureRow: Disclosure
|
|
|
2811
2865
|
keepContentWhenOpen: true,
|
|
2812
2866
|
collapsedContent: React2.createElement("span", {
|
|
2813
2867
|
role: presentation.role,
|
|
2868
|
+
"data-wsr-presentation": "true",
|
|
2869
|
+
"data-wsr-kind": presentationKind,
|
|
2870
|
+
"data-wsr-surface": "chat",
|
|
2871
|
+
"data-wsr-chat-role": "assistant",
|
|
2872
|
+
"data-wsr-correlation": presentation.correlation,
|
|
2873
|
+
"data-wsr-state": presentation.state,
|
|
2814
2874
|
"aria-live": ["running", "recovering", "waiting"].includes(presentation.state) ? "polite" : void 0
|
|
2815
2875
|
}, presentation.summary)
|
|
2816
2876
|
}, body);
|
|
2817
2877
|
};
|
|
2818
2878
|
}
|
|
2879
|
+
var TERMINAL_PRESENTATION = Object.freeze({
|
|
2880
|
+
SUCCEEDED: Object.freeze({ state: "completed", label: "Succeeded" }),
|
|
2881
|
+
FAILED: Object.freeze({ state: "failed", label: "Failed" }),
|
|
2882
|
+
CANCELLED: Object.freeze({ state: "cancelled", label: "Cancelled" })
|
|
2883
|
+
});
|
|
2884
|
+
function reconcileDeliveryPresentation(presentation, admitted, inventoryState) {
|
|
2885
|
+
const deliveryId = admitted?.kind === "delivery-running" && typeof admitted.data.deliveryId === "string" ? admitted.data.deliveryId : void 0;
|
|
2886
|
+
const deliveries = ["ready", "reconnecting"].includes(inventoryState?.kind) && Array.isArray(inventoryState.snapshot?.deliveries) ? inventoryState.snapshot.deliveries : [];
|
|
2887
|
+
const matches = deliveryId === void 0 ? [] : deliveries.filter((delivery) => delivery?.deliveryId === deliveryId);
|
|
2888
|
+
const exact = matches.length === 1 ? matches[0] : void 0;
|
|
2889
|
+
const terminal = exact?.lifecycle === "TERMINAL" ? TERMINAL_PRESENTATION[exact?.terminal?.outcome] : void 0;
|
|
2890
|
+
if (terminal !== void 0) return Object.freeze({
|
|
2891
|
+
...presentation,
|
|
2892
|
+
state: terminal.state,
|
|
2893
|
+
summary: `${terminal.label} \xB7 ${deliveryId}`,
|
|
2894
|
+
defaultOpen: false
|
|
2895
|
+
});
|
|
2896
|
+
if (exact === void 0 || typeof exact.lifecycle !== "string") return presentation;
|
|
2897
|
+
const lifecycle = /* @__PURE__ */ new Set(["BOUND", "START_UNCERTAIN", "RUNNING_CORRELATED", "START_FAILED", "RESULT_UNRESOLVED", "TERMINAL_HANDLING"]);
|
|
2898
|
+
return lifecycle.has(exact.lifecycle) ? projectExecutionPresentation({
|
|
2899
|
+
correlation: presentation.correlation,
|
|
2900
|
+
kind: "delivery-status",
|
|
2901
|
+
data: {
|
|
2902
|
+
deliveryId,
|
|
2903
|
+
state: exact.lifecycle,
|
|
2904
|
+
...admitted?.data?.diagnostic === void 0 ? {} : { diagnostic: admitted.data.diagnostic }
|
|
2905
|
+
}
|
|
2906
|
+
}) : presentation;
|
|
2907
|
+
}
|
|
2908
|
+
function commandPresentation(node, admitted, inventoryState) {
|
|
2909
|
+
if (node.outcome === null) return Object.freeze({
|
|
2910
|
+
correlation: String(node.commandId),
|
|
2911
|
+
layer: "progress",
|
|
2912
|
+
state: "running",
|
|
2913
|
+
title: "Workflow delivery",
|
|
2914
|
+
summary: "Running",
|
|
2915
|
+
body: void 0,
|
|
2916
|
+
defaultOpen: false,
|
|
2917
|
+
focusPolicy: "none",
|
|
2918
|
+
role: "status",
|
|
2919
|
+
compatibility: "current"
|
|
2920
|
+
});
|
|
2921
|
+
const event = admitted ?? parseExecutionPresentation(node.outcome?.text);
|
|
2922
|
+
if (event.kind === "delivery-list") {
|
|
2923
|
+
const count = Array.isArray(event.data.items) ? event.data.items.length : 0;
|
|
2924
|
+
return Object.freeze({
|
|
2925
|
+
correlation: event.correlation,
|
|
2926
|
+
layer: "progress",
|
|
2927
|
+
state: "completed",
|
|
2928
|
+
title: "Delivery list",
|
|
2929
|
+
summary: `${count} ${count === 1 ? "delivery" : "deliveries"}`,
|
|
2930
|
+
body: count === 0 ? "No deliveries." : JSON.stringify(event.data.items, null, 2),
|
|
2931
|
+
defaultOpen: false,
|
|
2932
|
+
focusPolicy: "none",
|
|
2933
|
+
role: "status",
|
|
2934
|
+
compatibility: "current"
|
|
2935
|
+
});
|
|
2936
|
+
}
|
|
2937
|
+
return reconcileDeliveryPresentation(projectExecutionPresentation(event), event, inventoryState);
|
|
2938
|
+
}
|
|
2939
|
+
function createWsrCommandView(options) {
|
|
2940
|
+
const View = createActionPresentationView(options);
|
|
2941
|
+
const { React: React2, inventory } = options;
|
|
2942
|
+
return function WsrCommandView({ node }) {
|
|
2943
|
+
const admitted = node.outcome === null ? void 0 : parseExecutionPresentation(node.outcome?.text);
|
|
2944
|
+
const inventoryState = inventory === void 0 ? void 0 : React2.useSyncExternalStore(inventory.subscribe, inventory.getSnapshot, inventory.getSnapshot);
|
|
2945
|
+
return View({ node: { data: commandPresentation(node, admitted, inventoryState) }, technicalDetails: admitted });
|
|
2946
|
+
};
|
|
2947
|
+
}
|
|
2819
2948
|
function registerActionPresentation(ctx, View) {
|
|
2820
|
-
ctx.
|
|
2821
|
-
|
|
2822
|
-
name: "conversation.chat.
|
|
2823
|
-
|
|
2824
|
-
}, View));
|
|
2949
|
+
ctx.slots.inject("conversation.chat.commandview", () => {
|
|
2950
|
+
ctx.slots.register({ name: "conversation.chat.commandview", key: "wsr" }, () => null);
|
|
2951
|
+
ctx.slots.register({ name: "conversation.chat.commandview", key: "wsr-presentation" }, View);
|
|
2952
|
+
});
|
|
2825
2953
|
}
|
|
2826
2954
|
|
|
2827
2955
|
// packages/execution/src/client/delivery/control-plane-port.js
|
|
2828
2956
|
var CHANNEL = "/wsr-execution";
|
|
2957
|
+
var ERROR_CODES = /* @__PURE__ */ new Set([
|
|
2958
|
+
"DELIVERY_PROJECTION_CORRUPT",
|
|
2959
|
+
"DELIVERY_PROJECTION_STALE_BINDING",
|
|
2960
|
+
"DELIVERY_PROJECTION_RECOVERY_MISMATCH",
|
|
2961
|
+
"DELIVERY_PROJECTION_UNAVAILABLE"
|
|
2962
|
+
]);
|
|
2829
2963
|
function createStore(initial) {
|
|
2830
2964
|
let snapshot = initial;
|
|
2831
2965
|
const listeners = /* @__PURE__ */ new Set();
|
|
@@ -2850,7 +2984,9 @@ function createDeliveryControlPlaneClient(rpc) {
|
|
|
2850
2984
|
const sessions = /* @__PURE__ */ new Map();
|
|
2851
2985
|
const read = async (endpoint, payload) => {
|
|
2852
2986
|
const result = await rpc.call(CHANNEL, endpoint, payload);
|
|
2853
|
-
if (result?.ok !== true) throw new Error(message(result?.error))
|
|
2987
|
+
if (result?.ok !== true) throw Object.assign(new Error(message(result?.error)), {
|
|
2988
|
+
code: ERROR_CODES.has(result?.error?.code) ? result.error.code : "DELIVERY_PROJECTION_UNAVAILABLE"
|
|
2989
|
+
});
|
|
2854
2990
|
return result.value;
|
|
2855
2991
|
};
|
|
2856
2992
|
const client = {
|
|
@@ -2864,6 +3000,7 @@ function createDeliveryControlPlaneClient(rpc) {
|
|
|
2864
3000
|
const previous = inventory.getSnapshot();
|
|
2865
3001
|
inventory.publish({
|
|
2866
3002
|
kind: previous.kind === "ready" ? "reconnecting" : "error",
|
|
3003
|
+
code: typeof error?.code === "string" ? error.code : "DELIVERY_PROJECTION_UNAVAILABLE",
|
|
2867
3004
|
message: message(error),
|
|
2868
3005
|
...previous.kind === "ready" ? { snapshot: previous.snapshot } : {}
|
|
2869
3006
|
});
|
|
@@ -2882,7 +3019,7 @@ function createDeliveryControlPlaneClient(rpc) {
|
|
|
2882
3019
|
try {
|
|
2883
3020
|
store.publish({ kind: "ready", view: await read("session/read", { sessionCorrelation }) });
|
|
2884
3021
|
} catch (error) {
|
|
2885
|
-
store.publish({ kind: "error", code: "DELIVERY_PROJECTION_UNAVAILABLE", message: message(error) });
|
|
3022
|
+
store.publish({ kind: "error", code: typeof error?.code === "string" ? error.code : "DELIVERY_PROJECTION_UNAVAILABLE", message: message(error) });
|
|
2886
3023
|
}
|
|
2887
3024
|
}
|
|
2888
3025
|
});
|
|
@@ -2906,6 +3043,38 @@ var LIFECYCLES = /* @__PURE__ */ new Set([
|
|
|
2906
3043
|
"TERMINAL_HANDLING",
|
|
2907
3044
|
"TERMINAL"
|
|
2908
3045
|
]);
|
|
3046
|
+
var DELIVERY_STYLE_ID = "dsh-wsr-execution-delivery-view";
|
|
3047
|
+
var DELIVERY_CSS = `
|
|
3048
|
+
.wsr-delivery-view { box-sizing: border-box; width: 100%; max-width: 960px; margin: 0 auto; padding: 20px; color: var(--dsw-alias-label-primary); }
|
|
3049
|
+
.wsr-delivery-heading { margin: 0 0 16px; font-size: 20px; line-height: 28px; }
|
|
3050
|
+
.wsr-delivery-summary { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 180px), 1fr)); gap: 8px; margin: 0 0 16px; }
|
|
3051
|
+
.wsr-delivery-summary-item { min-width: 0; padding: 10px 12px; border: 1px solid var(--dsw-alias-border-l2); border-radius: 8px; background: var(--dsw-alias-bg-layer-1); }
|
|
3052
|
+
.wsr-delivery-summary-item dt, .wsr-delivery-identity dt { margin: 0 0 3px; color: var(--dsw-alias-label-tertiary); font-size: 12px; line-height: 16px; }
|
|
3053
|
+
.wsr-delivery-summary-item dd, .wsr-delivery-identity dd { min-width: 0; margin: 0; font-size: 13px; line-height: 20px; overflow-wrap: anywhere; }
|
|
3054
|
+
.wsr-delivery-status { display: inline-flex; min-width: 0; align-items: center; gap: 6px; }
|
|
3055
|
+
.wsr-delivery-status > span:last-child { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
|
3056
|
+
.wsr-delivery-identities { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 260px), 1fr)); gap: 8px 16px; margin: 8px 0 0; }
|
|
3057
|
+
.wsr-delivery-identity { min-width: 0; margin: 0; }
|
|
3058
|
+
.wsr-delivery-identity dd { display: grid; grid-template-columns: minmax(0, 1fr) auto; align-items: center; gap: 6px; }
|
|
3059
|
+
.wsr-delivery-identity code { display: block; min-width: 0; max-width: 100%; color: inherit; font-family: var(--dsw-font-family-mono, ui-monospace, monospace); overflow-wrap: anywhere; white-space: normal; }
|
|
3060
|
+
.wsr-delivery-preview { display: block; min-width: 0; max-width: 100%; margin-inline-start: 8px; overflow: hidden; color: var(--dsw-alias-label-tertiary); text-overflow: ellipsis; white-space: nowrap; }
|
|
3061
|
+
.wsr-delivery-copy-feedback { min-height: 20px; margin: 8px 0 0; color: var(--dsw-alias-label-secondary); font-size: 12px; line-height: 20px; }
|
|
3062
|
+
.wsr-delivery-condition { margin-top: 12px; padding: 10px 12px; border-left: 3px solid var(--dsw-alias-state-warn-primary); border-radius: 4px; background: var(--dsw-alias-bg-layer-1); }
|
|
3063
|
+
.wsr-delivery-condition h3 { margin: 0 0 4px; font-size: 13px; line-height: 20px; }
|
|
3064
|
+
.wsr-delivery-condition code, .wsr-delivery-state code { overflow-wrap: anywhere; }
|
|
3065
|
+
.wsr-delivery-state { display: grid; gap: 8px; }
|
|
3066
|
+
.wsr-delivery-state p { margin: 0; }
|
|
3067
|
+
@media (max-width: 720px) { .wsr-delivery-summary { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
|
|
3068
|
+
@media (max-width: 420px) { .wsr-delivery-view { padding: 12px; } .wsr-delivery-summary, .wsr-delivery-identities { grid-template-columns: minmax(0, 1fr); } }
|
|
3069
|
+
@media (prefers-reduced-motion: reduce) { .wsr-delivery-view, .wsr-delivery-view * { scroll-behavior: auto !important; transition: none !important; } }
|
|
3070
|
+
`;
|
|
3071
|
+
function ensureDeliveryStyles() {
|
|
3072
|
+
if (typeof document === "undefined" || document.getElementById(DELIVERY_STYLE_ID) !== null) return;
|
|
3073
|
+
const tag = document.createElement("style");
|
|
3074
|
+
tag.id = DELIVERY_STYLE_ID;
|
|
3075
|
+
tag.textContent = DELIVERY_CSS;
|
|
3076
|
+
document.head.appendChild(tag);
|
|
3077
|
+
}
|
|
2909
3078
|
function nonEmpty(value) {
|
|
2910
3079
|
return typeof value === "string" && value.length > 0;
|
|
2911
3080
|
}
|
|
@@ -2932,88 +3101,187 @@ function safeSubscribe(source, notify) {
|
|
|
2932
3101
|
return () => void 0;
|
|
2933
3102
|
}
|
|
2934
3103
|
}
|
|
2935
|
-
function
|
|
2936
|
-
return
|
|
2937
|
-
|
|
2938
|
-
|
|
2939
|
-
|
|
3104
|
+
function summaryItem(React2, label, value, extra = {}) {
|
|
3105
|
+
return React2.createElement(
|
|
3106
|
+
"div",
|
|
3107
|
+
{ className: "wsr-delivery-summary-item", ...extra },
|
|
3108
|
+
React2.createElement("dt", null, label),
|
|
3109
|
+
React2.createElement("dd", null, value)
|
|
3110
|
+
);
|
|
2940
3111
|
}
|
|
2941
|
-
function statePanel(React2, role, code, message2) {
|
|
3112
|
+
function statePanel(React2, StateDot2, role, code, message2) {
|
|
2942
3113
|
return React2.createElement(
|
|
2943
3114
|
"section",
|
|
2944
3115
|
{
|
|
3116
|
+
className: "wsr-delivery-view wsr-delivery-state",
|
|
2945
3117
|
"aria-labelledby": "wsr-delivery-view-title",
|
|
2946
3118
|
"aria-live": role === "alert" ? "assertive" : "polite",
|
|
2947
3119
|
"data-wsr-delivery-view": "true",
|
|
2948
3120
|
role
|
|
2949
3121
|
},
|
|
2950
|
-
React2.createElement("h2", { id: "wsr-delivery-view-title" }, "Delivery"),
|
|
2951
|
-
React2.createElement(
|
|
3122
|
+
React2.createElement("h2", { className: "wsr-delivery-heading", id: "wsr-delivery-view-title" }, "Delivery"),
|
|
3123
|
+
React2.createElement(
|
|
3124
|
+
"p",
|
|
3125
|
+
null,
|
|
3126
|
+
React2.createElement(StateDot2, { state: role === "alert" ? "error" : "ongoing", size: 10 }),
|
|
3127
|
+
" ",
|
|
3128
|
+
message2
|
|
3129
|
+
),
|
|
2952
3130
|
code === void 0 ? null : React2.createElement("code", null, code)
|
|
2953
3131
|
);
|
|
2954
3132
|
}
|
|
2955
|
-
function
|
|
3133
|
+
function statusState(delivery, failed) {
|
|
3134
|
+
if (failed) return "error";
|
|
3135
|
+
if (delivery.terminal?.outcome === "SUCCEEDED") return "done";
|
|
3136
|
+
if (delivery.terminal !== null || ["START_UNCERTAIN", "RESULT_UNRESOLVED", "START_FAILED"].includes(delivery.lifecycle)) return "warning";
|
|
3137
|
+
return "ongoing";
|
|
3138
|
+
}
|
|
3139
|
+
function identityCard(React2, primitives, label, value, displayValue = value) {
|
|
3140
|
+
const { Button: Button2, IconCheckOutline16: IconCheckOutline162, IconCopyOutline16: IconCopyOutline162, Tooltip: Tooltip2, onCopy, copiedLabel } = primitives;
|
|
3141
|
+
const exact = React2.createElement("code", {
|
|
3142
|
+
"aria-label": `${label}: ${value}`,
|
|
3143
|
+
"data-wsr-delivery-identity": label,
|
|
3144
|
+
title: value
|
|
3145
|
+
}, displayValue);
|
|
3146
|
+
const copied = copiedLabel === label;
|
|
3147
|
+
const control = React2.createElement(
|
|
3148
|
+
Tooltip2,
|
|
3149
|
+
{ label: copied ? `${label} copied` : `Copy ${label}`, side: "bottom" },
|
|
3150
|
+
React2.createElement(Button2, {
|
|
3151
|
+
"aria-label": `Copy ${label}`,
|
|
3152
|
+
icon: React2.createElement(copied ? IconCheckOutline162 : IconCopyOutline162, null),
|
|
3153
|
+
onClick: () => onCopy(label, value),
|
|
3154
|
+
size: "sm",
|
|
3155
|
+
type: "button",
|
|
3156
|
+
variant: "toolbar"
|
|
3157
|
+
}, copied ? "Copied" : "Copy")
|
|
3158
|
+
);
|
|
3159
|
+
return React2.createElement(
|
|
3160
|
+
"div",
|
|
3161
|
+
{ className: "wsr-delivery-identity", key: label },
|
|
3162
|
+
React2.createElement("dt", null, label),
|
|
3163
|
+
React2.createElement("dd", null, exact, control)
|
|
3164
|
+
);
|
|
3165
|
+
}
|
|
3166
|
+
function createSessionDeliveryView(React2, primitives = {}) {
|
|
2956
3167
|
if (typeof React2?.createElement !== "function" || typeof React2?.useSyncExternalStore !== "function") {
|
|
2957
3168
|
throw new TypeError("DELIVERY_VIEW_REACT_INVALID");
|
|
2958
3169
|
}
|
|
3170
|
+
const DisclosureRow2 = primitives.DisclosureRow ?? "div";
|
|
3171
|
+
const Button2 = primitives.Button ?? "button";
|
|
3172
|
+
const IconCheckOutline162 = primitives.IconCheckOutline16 ?? "span";
|
|
3173
|
+
const IconCopyOutline162 = primitives.IconCopyOutline16 ?? "span";
|
|
3174
|
+
const Pill2 = primitives.Pill ?? "span";
|
|
3175
|
+
const StateDot2 = primitives.StateDot ?? "span";
|
|
3176
|
+
const Tooltip2 = primitives.Tooltip ?? "span";
|
|
3177
|
+
const writeClipboard2 = primitives.writeClipboard ?? (async () => false);
|
|
3178
|
+
ensureDeliveryStyles();
|
|
2959
3179
|
return function SessionDeliveryView({ sessionId, source }) {
|
|
3180
|
+
const [identitiesOpen, setIdentitiesOpen] = typeof React2.useState === "function" ? React2.useState(false) : [false, () => void 0];
|
|
3181
|
+
const [copiedLabel, setCopiedLabel] = typeof React2.useState === "function" ? React2.useState("") : ["", () => void 0];
|
|
2960
3182
|
const state = React2.useSyncExternalStore(
|
|
2961
3183
|
(notify) => safeSubscribe(source, notify),
|
|
2962
3184
|
() => safeSnapshot(source),
|
|
2963
3185
|
() => safeSnapshot(source)
|
|
2964
3186
|
);
|
|
2965
|
-
if (state.kind === "loading") return statePanel(React2, "status", void 0, "Loading Delivery\u2026");
|
|
2966
|
-
if (state.kind === "error") return statePanel(React2, "alert", state.code ?? "DELIVERY_PROJECTION_UNAVAILABLE", state.message ?? "Execution projection unavailable");
|
|
3187
|
+
if (state.kind === "loading") return statePanel(React2, StateDot2, "status", void 0, "Loading Delivery\u2026");
|
|
3188
|
+
if (state.kind === "error") return statePanel(React2, StateDot2, "alert", state.code ?? "DELIVERY_PROJECTION_UNAVAILABLE", state.message ?? "Execution projection unavailable");
|
|
2967
3189
|
const view = state.view;
|
|
2968
3190
|
if (state.kind !== "ready" || view?.sessionCorrelation !== sessionId) {
|
|
2969
|
-
return statePanel(React2, "alert", "DELIVERY_PROJECTION_CORRUPT", "Delivery projection invalid");
|
|
3191
|
+
return statePanel(React2, StateDot2, "alert", "DELIVERY_PROJECTION_CORRUPT", "Delivery projection invalid");
|
|
2970
3192
|
}
|
|
2971
|
-
if (view.kind === "UNBOUND") return statePanel(React2, "status", void 0, "No Delivery bound to this Session");
|
|
3193
|
+
if (view.kind === "UNBOUND") return statePanel(React2, StateDot2, "status", void 0, "No Delivery bound to this Session");
|
|
2972
3194
|
if (view.kind !== "BOUND" || !validDelivery(view.delivery, sessionId)) {
|
|
2973
|
-
return statePanel(React2, "alert", "DELIVERY_PROJECTION_CORRUPT", "Delivery projection invalid");
|
|
3195
|
+
return statePanel(React2, StateDot2, "alert", "DELIVERY_PROJECTION_CORRUPT", "Delivery projection invalid");
|
|
2974
3196
|
}
|
|
2975
3197
|
const delivery = view.delivery;
|
|
2976
3198
|
const failed = delivery.terminal?.outcome === "FAILED" || delivery.error !== null;
|
|
2977
3199
|
const identityRows = [
|
|
2978
|
-
|
|
2979
|
-
|
|
2980
|
-
|
|
2981
|
-
|
|
2982
|
-
|
|
2983
|
-
|
|
2984
|
-
|
|
2985
|
-
|
|
3200
|
+
["Delivery", delivery.deliveryId],
|
|
3201
|
+
["Task", delivery.task.identity, delivery.task.displayName === null ? delivery.task.identity : `${delivery.task.displayName} \xB7 ${delivery.task.identity}`],
|
|
3202
|
+
["Workflow", delivery.workflow.identity],
|
|
3203
|
+
["Package", `${delivery.workflow.packageName}@${delivery.workflow.exactPackageVersion}`],
|
|
3204
|
+
["Package digest", delivery.workflow.packageDigest],
|
|
3205
|
+
["Snapshot", delivery.workflow.snapshotIdentity],
|
|
3206
|
+
["Snapshot digest", delivery.workflow.snapshotDigest],
|
|
3207
|
+
["Binding", delivery.deliveryBindingIdentity],
|
|
3208
|
+
...nonEmpty(delivery.worktree) ? [["Worktree", delivery.worktree]] : []
|
|
2986
3209
|
];
|
|
2987
|
-
const
|
|
2988
|
-
|
|
2989
|
-
|
|
2990
|
-
|
|
2991
|
-
|
|
2992
|
-
|
|
2993
|
-
|
|
2994
|
-
|
|
2995
|
-
|
|
2996
|
-
|
|
2997
|
-
...delivery.
|
|
3210
|
+
const statusLabel = delivery.terminal?.outcome ?? delivery.lifecycle;
|
|
3211
|
+
const workflowLabel = `${delivery.workflow.identity} \xB7 ${delivery.workflow.packageName}@${delivery.workflow.exactPackageVersion}`;
|
|
3212
|
+
const summary = [
|
|
3213
|
+
summaryItem(React2, "Status", React2.createElement(
|
|
3214
|
+
"span",
|
|
3215
|
+
{ className: "wsr-delivery-status" },
|
|
3216
|
+
React2.createElement(StateDot2, { state: statusState(delivery, failed), size: 10 }),
|
|
3217
|
+
React2.createElement(Pill2, { "aria-label": `Delivery status ${statusLabel}` }, statusLabel)
|
|
3218
|
+
)),
|
|
3219
|
+
summaryItem(React2, "Workflow", workflowLabel),
|
|
3220
|
+
...delivery.current === null ? [] : [summaryItem(
|
|
3221
|
+
React2,
|
|
3222
|
+
delivery.current.kind === "ACTION" ? "Current Action" : "Current Intervention",
|
|
3223
|
+
delivery.current.identity,
|
|
3224
|
+
{ "data-wsr-delivery-conditional": "current" }
|
|
3225
|
+
)],
|
|
3226
|
+
...delivery.terminal === null ? [] : [summaryItem(React2, "Outcome", delivery.terminal.outcome, { "data-wsr-delivery-conditional": "terminal" })],
|
|
3227
|
+
summaryItem(React2, "Elapsed", duration(delivery.timing.elapsedMs)),
|
|
3228
|
+
summaryItem(React2, "Started", new Date(delivery.timing.startedAt).toISOString()),
|
|
3229
|
+
...delivery.terminal === null ? [] : [summaryItem(React2, "Ended", new Date(delivery.terminal.finishedAt).toISOString())]
|
|
2998
3230
|
];
|
|
2999
3231
|
return React2.createElement(
|
|
3000
3232
|
"section",
|
|
3001
3233
|
{
|
|
3234
|
+
className: "wsr-delivery-view",
|
|
3002
3235
|
"aria-labelledby": "wsr-delivery-view-title",
|
|
3003
3236
|
"aria-live": failed ? "assertive" : "polite",
|
|
3004
3237
|
"data-wsr-delivery-id": delivery.deliveryId,
|
|
3005
3238
|
"data-wsr-delivery-view": "true",
|
|
3006
3239
|
role: failed ? "alert" : "region"
|
|
3007
3240
|
},
|
|
3008
|
-
React2.createElement("h2", { id: "wsr-delivery-view-title" }, "Delivery"),
|
|
3009
|
-
React2.createElement("dl", { "aria-label": "Delivery
|
|
3010
|
-
React2.createElement(
|
|
3241
|
+
React2.createElement("h2", { className: "wsr-delivery-heading", id: "wsr-delivery-view-title" }, "Delivery"),
|
|
3242
|
+
React2.createElement("dl", { "aria-label": "Delivery summary", "data-wsr-delivery-summary": "true", className: "wsr-delivery-summary" }, summary),
|
|
3243
|
+
React2.createElement(
|
|
3244
|
+
DisclosureRow2,
|
|
3245
|
+
{
|
|
3246
|
+
title: "Identity details",
|
|
3247
|
+
icon: React2.createElement(StateDot2, { state: statusState(delivery, failed), size: 10 }),
|
|
3248
|
+
open: identitiesOpen,
|
|
3249
|
+
expandable: true,
|
|
3250
|
+
expandOnRowClick: true,
|
|
3251
|
+
onToggle: () => setIdentitiesOpen((open) => !open),
|
|
3252
|
+
collapsedContent: React2.createElement("code", { className: "wsr-delivery-preview" }, delivery.deliveryId)
|
|
3253
|
+
},
|
|
3254
|
+
React2.createElement(
|
|
3255
|
+
"dl",
|
|
3256
|
+
{ "aria-label": "Delivery identity", className: "wsr-delivery-identities" },
|
|
3257
|
+
identityRows.map(([label, value, displayValue]) => identityCard(React2, {
|
|
3258
|
+
Button: Button2,
|
|
3259
|
+
IconCheckOutline16: IconCheckOutline162,
|
|
3260
|
+
IconCopyOutline16: IconCopyOutline162,
|
|
3261
|
+
Tooltip: Tooltip2,
|
|
3262
|
+
copiedLabel,
|
|
3263
|
+
async onCopy(copyLabel, value2) {
|
|
3264
|
+
setCopiedLabel(await writeClipboard2(value2) ? copyLabel : `${copyLabel} copy failed`);
|
|
3265
|
+
}
|
|
3266
|
+
}, label, value, displayValue))
|
|
3267
|
+
),
|
|
3268
|
+
React2.createElement("p", {
|
|
3269
|
+
"aria-live": "polite",
|
|
3270
|
+
className: "wsr-delivery-copy-feedback",
|
|
3271
|
+
role: "status"
|
|
3272
|
+
}, copiedLabel === "" ? "" : copiedLabel.endsWith("copy failed") ? copiedLabel : `${copiedLabel} copied`)
|
|
3273
|
+
),
|
|
3274
|
+
delivery.error === null ? null : React2.createElement("section", {
|
|
3275
|
+
className: "wsr-delivery-condition",
|
|
3276
|
+
"data-wsr-delivery-conditional": "error",
|
|
3277
|
+
role: "alert"
|
|
3278
|
+
}, React2.createElement("h3", null, "Failure diagnostic"), React2.createElement("code", null, delivery.error.code))
|
|
3011
3279
|
);
|
|
3012
3280
|
};
|
|
3013
3281
|
}
|
|
3014
3282
|
function registerSessionDeliveryView(ctx, options) {
|
|
3015
3283
|
if (typeof ctx?.slots?.inject !== "function" || typeof ctx?.slots?.register !== "function" || typeof options?.bindProjection !== "function") throw new TypeError("DELIVERY_VIEW_REGISTRATION_INVALID");
|
|
3016
|
-
const View = createSessionDeliveryView(options.React);
|
|
3284
|
+
const View = createSessionDeliveryView(options.React, options);
|
|
3017
3285
|
ctx.slots.inject("conversation.view", () => ctx.slots.register({
|
|
3018
3286
|
name: "conversation.view",
|
|
3019
3287
|
id: DELIVERY_VIEW_ID,
|
|
@@ -3034,9 +3302,18 @@ var LIFECYCLES2 = /* @__PURE__ */ new Set([
|
|
|
3034
3302
|
"TERMINAL_HANDLING",
|
|
3035
3303
|
"TERMINAL"
|
|
3036
3304
|
]);
|
|
3305
|
+
var ERROR_CODES2 = /* @__PURE__ */ new Set([
|
|
3306
|
+
"DELIVERY_PROJECTION_CORRUPT",
|
|
3307
|
+
"DELIVERY_PROJECTION_STALE_BINDING",
|
|
3308
|
+
"DELIVERY_PROJECTION_RECOVERY_MISMATCH",
|
|
3309
|
+
"DELIVERY_PROJECTION_UNAVAILABLE"
|
|
3310
|
+
]);
|
|
3037
3311
|
function errorView(label = "Delivery inventory unavailable") {
|
|
3038
3312
|
return Object.freeze({ kind: "error", role: "alert", label, rows: Object.freeze([]) });
|
|
3039
3313
|
}
|
|
3314
|
+
function diagnostic(state, label) {
|
|
3315
|
+
return typeof state?.code === "string" && ERROR_CODES2.has(state.code) ? `${state.code}: ${label}` : label;
|
|
3316
|
+
}
|
|
3040
3317
|
function validString(value) {
|
|
3041
3318
|
return typeof value === "string" && value.length > 0 && value.length <= 512;
|
|
3042
3319
|
}
|
|
@@ -3066,13 +3343,21 @@ function rowsFrom(deliveries, selectedSessionId) {
|
|
|
3066
3343
|
}
|
|
3067
3344
|
function projectDeliveryInventory(state, { selectedSessionId } = {}) {
|
|
3068
3345
|
if (state?.kind === "loading") return Object.freeze({ kind: "loading", role: "status", label: "Loading Deliveries", rows: Object.freeze([]) });
|
|
3069
|
-
if (state?.kind === "error")
|
|
3346
|
+
if (state?.kind === "error") {
|
|
3347
|
+
const label = validString(state.message) ? state.message : "Delivery inventory unavailable";
|
|
3348
|
+
return errorView(diagnostic(state, label));
|
|
3349
|
+
}
|
|
3070
3350
|
if (!(/* @__PURE__ */ new Set(["ready", "reconnecting"])).has(state?.kind)) return errorView();
|
|
3071
3351
|
const snapshot = state.snapshot;
|
|
3072
3352
|
if (snapshot === null || typeof snapshot !== "object" || Array.isArray(snapshot) || snapshot.schemaVersion !== CONTROL_PLANE_SCHEMA || !Number.isSafeInteger(snapshot.generation) || snapshot.generation < 1) return errorView();
|
|
3073
3353
|
const rows = rowsFrom(snapshot.deliveries, selectedSessionId);
|
|
3074
3354
|
if (rows === void 0) return errorView();
|
|
3075
|
-
if (state.kind === "reconnecting") return Object.freeze({
|
|
3355
|
+
if (state.kind === "reconnecting") return Object.freeze({
|
|
3356
|
+
kind: "reconnecting",
|
|
3357
|
+
role: "status",
|
|
3358
|
+
label: diagnostic(state, "Reconnecting to Delivery inventory"),
|
|
3359
|
+
rows
|
|
3360
|
+
});
|
|
3076
3361
|
if (rows.length === 0) return Object.freeze({ kind: "empty", role: "status", label: "No Deliveries", rows });
|
|
3077
3362
|
return Object.freeze({ kind: "ready", role: "list", label: "Deliveries", rows });
|
|
3078
3363
|
}
|
|
@@ -3180,7 +3465,6 @@ function applyDeliverySidebar(ctx, { React: React2, workspaceUi: workspaceUi2, i
|
|
|
3180
3465
|
var name = "wsr-execution-client";
|
|
3181
3466
|
var inject = Object.freeze([
|
|
3182
3467
|
"connection",
|
|
3183
|
-
"conversationEvents",
|
|
3184
3468
|
"sessions",
|
|
3185
3469
|
"slots",
|
|
3186
3470
|
"workspaces",
|
|
@@ -3197,13 +3481,32 @@ function apply(ctx) {
|
|
|
3197
3481
|
applyDeliverySidebar(ctx, { React: import_react.default, workspaceUi, inventory: controlPlane.inventory });
|
|
3198
3482
|
registerSessionDeliveryView(ctx, {
|
|
3199
3483
|
React: import_react.default,
|
|
3484
|
+
Button: import_dsh_client_ui_primitives.Button,
|
|
3485
|
+
DisclosureRow: import_dsh_client_ui_primitives.DisclosureRow,
|
|
3486
|
+
IconCheckOutline16: import_dsh_client_ui_primitives.IconCheckOutline16,
|
|
3487
|
+
IconCopyOutline16: import_dsh_client_ui_primitives.IconCopyOutline16,
|
|
3488
|
+
Pill: import_dsh_client_ui_primitives.Pill,
|
|
3489
|
+
StateDot: import_dsh_client_ui_primitives.StateDot,
|
|
3490
|
+
Tooltip: import_dsh_client_ui_primitives.Tooltip,
|
|
3491
|
+
writeClipboard: import_dsh_client_ui_primitives.writeClipboard,
|
|
3200
3492
|
bindProjection(sessionId) {
|
|
3201
3493
|
const source = controlPlane.bindSession(String(sessionId));
|
|
3202
3494
|
void source.refresh();
|
|
3203
3495
|
return source;
|
|
3204
3496
|
}
|
|
3205
3497
|
});
|
|
3206
|
-
registerActionPresentation(ctx,
|
|
3498
|
+
registerActionPresentation(ctx, createWsrCommandView({
|
|
3499
|
+
React: import_react.default,
|
|
3500
|
+
DisclosureRow: import_dsh_client_ui_primitives.DisclosureRow,
|
|
3501
|
+
IconCheckOutline16: import_dsh_client_ui_primitives.IconCheckOutline16,
|
|
3502
|
+
IconCopyOutline16: import_dsh_client_ui_primitives.IconCopyOutline16,
|
|
3503
|
+
JsonTree: import_dsh_client_ui_primitives.JsonTree,
|
|
3504
|
+
MessageText: import_dsh_client_ui_primitives.MessageText,
|
|
3505
|
+
StateDot: import_dsh_client_ui_primitives.StateDot,
|
|
3506
|
+
Tooltip: import_dsh_client_ui_primitives.Tooltip,
|
|
3507
|
+
writeClipboard: import_dsh_client_ui_primitives.writeClipboard,
|
|
3508
|
+
inventory: controlPlane.inventory
|
|
3509
|
+
}));
|
|
3207
3510
|
}
|
|
3208
3511
|
|
|
3209
3512
|
return module.exports;
|