@growthub/cli 0.13.9 → 0.14.1
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/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/app/api/workspace/env-status/route.js +31 -0
- package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/app/api/workspace/helper/apply/route.js +227 -5
- package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/app/api/workspace/helper/query/route.js +1 -0
- package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/app/api/workspace/sandbox-run/route.js +70 -9
- package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/app/components/WorkspaceActivationPanel.jsx +17 -1
- package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/app/components/WorkspaceHelperSetupModal.jsx +6 -3
- package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/app/data-model/components/AgentSwarmPanel.jsx +61 -35
- package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/app/data-model/components/ApiRegistryCreationCockpit.jsx +200 -0
- package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/app/data-model/components/DataModelShell.jsx +414 -9
- package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/app/data-model/components/HelperSidecar.jsx +339 -77
- package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/app/data-model/components/OrchestrationGraphCanvas.jsx +81 -10
- package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/app/data-model/components/OrchestrationNodeConfigPanel.jsx +70 -85
- package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/app/data-model/components/ReferencePicker.jsx +2 -2
- package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/app/data-model/components/SidecarExpandView.jsx +37 -0
- package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/app/data-model/components/SwarmRunCockpit.jsx +625 -0
- package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/app/data-model/components/helper-commands.js +150 -0
- package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/app/globals.css +229 -9
- package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/app/workflows/WorkflowSurface.jsx +224 -14
- package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/lib/adapters/integrations/resolver-loader.js +2 -4
- package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/lib/adapters/sandboxes/default-local-agent-host.js +139 -4
- package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/lib/adapters/sandboxes/default-local-intelligence.js +4 -0
- package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/lib/api-registry-creation-flow.js +317 -0
- package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/lib/api-response-profile.js +207 -0
- package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/lib/creation-error-recovery.js +103 -0
- package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/lib/env-status.js +100 -0
- package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/lib/orchestration-agent-swarm.js +246 -4
- package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/lib/orchestration-graph.js +69 -0
- package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/lib/orchestration-run-console.js +411 -1
- package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/lib/sandbox-serverless-flow.js +215 -0
- package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/lib/server-resolver-write.js +67 -0
- package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/lib/serverless-upgrade.js +89 -0
- package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/lib/workspace-activation.js +11 -4
- package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/lib/workspace-data-model.js +8 -1
- package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/lib/workspace-helper.js +30 -1
- package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/lib/workspace-metadata-store.js +8 -6
- package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/lib/workspace-resolver-proposal.js +200 -0
- package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/lib/workspace-swarm-proposal.js +551 -0
- package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/package.json +1 -1
- package/package.json +1 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
|
|
3
|
-
import { useMemo, useState } from "react";
|
|
3
|
+
import { useCallback, useMemo, useRef, useState } from "react";
|
|
4
4
|
import {
|
|
5
5
|
ArrowDownToLine,
|
|
6
6
|
Bot,
|
|
@@ -53,6 +53,15 @@ const CONNECTOR_OPTIONS = [
|
|
|
53
53
|
{ id: "preview", label: "Preview output" }
|
|
54
54
|
];
|
|
55
55
|
|
|
56
|
+
const MIN_ZOOM = 0.45;
|
|
57
|
+
const MAX_ZOOM = 1.4;
|
|
58
|
+
const NODE_BLOCK_HEIGHT = 98;
|
|
59
|
+
const FIT_VIEW_PADDING = 128;
|
|
60
|
+
|
|
61
|
+
function clampZoom(value) {
|
|
62
|
+
return Math.min(MAX_ZOOM, Math.max(MIN_ZOOM, Number(value.toFixed(2))));
|
|
63
|
+
}
|
|
64
|
+
|
|
56
65
|
function nodeSubtitle(node) {
|
|
57
66
|
const config = node?.config || {};
|
|
58
67
|
if (node?.subtitle) return String(node.subtitle);
|
|
@@ -111,8 +120,61 @@ export function OrchestrationGraphCanvas({
|
|
|
111
120
|
const [internalSelected, setInternalSelected] = useState(null);
|
|
112
121
|
const [connectorPopover, setConnectorPopover] = useState(null);
|
|
113
122
|
const [zoom, setZoom] = useState(1);
|
|
123
|
+
const [pan, setPan] = useState({ x: 0, y: 0 });
|
|
124
|
+
const canvasRef = useRef(null);
|
|
125
|
+
const dragRef = useRef(null);
|
|
114
126
|
const activeId = selectedNodeId ?? internalSelected;
|
|
115
127
|
|
|
128
|
+
function edgeBetween(fromId, toId) {
|
|
129
|
+
return edges.find((e) => String(e.from) === fromId && String(e.to) === toId);
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
const zoomBy = useCallback((delta) => {
|
|
133
|
+
setZoom((value) => clampZoom(value + delta));
|
|
134
|
+
}, []);
|
|
135
|
+
|
|
136
|
+
const fitView = useCallback(() => {
|
|
137
|
+
const rect = canvasRef.current?.getBoundingClientRect();
|
|
138
|
+
const availableHeight = Math.max(240, (rect?.height || 720) - FIT_VIEW_PADDING);
|
|
139
|
+
const graphHeight = Math.max(NODE_BLOCK_HEIGHT, nodes.length * NODE_BLOCK_HEIGHT);
|
|
140
|
+
const nextZoom = clampZoom(Math.min(1, availableHeight / graphHeight));
|
|
141
|
+
setZoom(nextZoom);
|
|
142
|
+
setPan({ x: 0, y: 0 });
|
|
143
|
+
}, [nodes.length]);
|
|
144
|
+
|
|
145
|
+
const handleWheel = useCallback((event) => {
|
|
146
|
+
event.preventDefault();
|
|
147
|
+
const direction = event.deltaY > 0 ? -0.08 : 0.08;
|
|
148
|
+
zoomBy(direction);
|
|
149
|
+
}, [zoomBy]);
|
|
150
|
+
|
|
151
|
+
const handlePointerDown = useCallback((event) => {
|
|
152
|
+
if (event.button !== 0) return;
|
|
153
|
+
if (event.target.closest("button, .dm-orchestration-node, .dm-orchestration-connector__popover")) return;
|
|
154
|
+
dragRef.current = {
|
|
155
|
+
pointerId: event.pointerId,
|
|
156
|
+
startX: event.clientX,
|
|
157
|
+
startY: event.clientY,
|
|
158
|
+
originX: pan.x,
|
|
159
|
+
originY: pan.y
|
|
160
|
+
};
|
|
161
|
+
event.currentTarget.setPointerCapture?.(event.pointerId);
|
|
162
|
+
}, [pan.x, pan.y]);
|
|
163
|
+
|
|
164
|
+
const handlePointerMove = useCallback((event) => {
|
|
165
|
+
const drag = dragRef.current;
|
|
166
|
+
if (!drag || drag.pointerId !== event.pointerId) return;
|
|
167
|
+
event.preventDefault();
|
|
168
|
+
setPan({
|
|
169
|
+
x: drag.originX + event.clientX - drag.startX,
|
|
170
|
+
y: drag.originY + event.clientY - drag.startY
|
|
171
|
+
});
|
|
172
|
+
}, []);
|
|
173
|
+
|
|
174
|
+
const endDrag = useCallback((event) => {
|
|
175
|
+
if (dragRef.current?.pointerId === event.pointerId) dragRef.current = null;
|
|
176
|
+
}, []);
|
|
177
|
+
|
|
116
178
|
if (!nodes.length) {
|
|
117
179
|
return (
|
|
118
180
|
<div className="dm-orchestration-canvas dm-orchestration-canvas--empty">
|
|
@@ -121,12 +183,18 @@ export function OrchestrationGraphCanvas({
|
|
|
121
183
|
);
|
|
122
184
|
}
|
|
123
185
|
|
|
124
|
-
function edgeBetween(fromId, toId) {
|
|
125
|
-
return edges.find((e) => String(e.from) === fromId && String(e.to) === toId);
|
|
126
|
-
}
|
|
127
|
-
|
|
128
186
|
return (
|
|
129
|
-
<div
|
|
187
|
+
<div
|
|
188
|
+
ref={canvasRef}
|
|
189
|
+
className="dm-orchestration-canvas"
|
|
190
|
+
aria-label="Orchestration graph field editor"
|
|
191
|
+
onWheel={handleWheel}
|
|
192
|
+
onPointerDown={handlePointerDown}
|
|
193
|
+
onPointerMove={handlePointerMove}
|
|
194
|
+
onPointerUp={endDrag}
|
|
195
|
+
onPointerCancel={endDrag}
|
|
196
|
+
onPointerLeave={endDrag}
|
|
197
|
+
>
|
|
130
198
|
<span className={`dm-orchestration-canvas__badge is-${String(statusLabel || "draft").toLowerCase()}`}>{statusLabel}</span>
|
|
131
199
|
<div className="dm-orchestration-floating-tools" aria-label="Canvas tools">
|
|
132
200
|
<button type="button" title="Add node" aria-label="Add node" onClick={() => onConnectorAction?.({ action: "add-step", from: String(nodes[nodes.length - 1]?.id || ""), to: "" })}>
|
|
@@ -135,17 +203,20 @@ export function OrchestrationGraphCanvas({
|
|
|
135
203
|
<button type="button" title="Tidy workflow" aria-label="Tidy workflow">
|
|
136
204
|
<Settings size={14} />
|
|
137
205
|
</button>
|
|
138
|
-
<button type="button" title="Zoom in" aria-label="Zoom in" onClick={() =>
|
|
206
|
+
<button type="button" title="Zoom in" aria-label="Zoom in" onClick={() => zoomBy(0.1)}>
|
|
139
207
|
<ZoomIn size={14} />
|
|
140
208
|
</button>
|
|
141
|
-
<button type="button" title="Zoom out" aria-label="Zoom out" onClick={() =>
|
|
209
|
+
<button type="button" title="Zoom out" aria-label="Zoom out" onClick={() => zoomBy(-0.1)}>
|
|
142
210
|
<ZoomOut size={14} />
|
|
143
211
|
</button>
|
|
144
|
-
<button type="button" title="
|
|
212
|
+
<button type="button" title="Fit view" aria-label="Fit view" onClick={fitView}>
|
|
145
213
|
<Maximize2 size={14} />
|
|
146
214
|
</button>
|
|
147
215
|
</div>
|
|
148
|
-
<div
|
|
216
|
+
<div
|
|
217
|
+
className="dm-orchestration-canvas__viewport"
|
|
218
|
+
style={{ transform: `translate3d(${pan.x}px, ${pan.y}px, 0) scale(${zoom})` }}
|
|
219
|
+
>
|
|
149
220
|
{nodes.map((node, index) => {
|
|
150
221
|
const id = String(node.id || "");
|
|
151
222
|
const isSelected = activeId === id;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
|
|
3
3
|
import { useMemo, useState } from "react";
|
|
4
|
+
import { Check } from "lucide-react";
|
|
4
5
|
import {
|
|
5
6
|
detectFieldIdsFromLastResponse,
|
|
6
7
|
FILTER_CONJUNCTIONS,
|
|
@@ -28,6 +29,23 @@ const EMPTY_AGENT_AUTH_PATCH = {
|
|
|
28
29
|
agentAuthLastLoginUrl: ""
|
|
29
30
|
};
|
|
30
31
|
|
|
32
|
+
function WorkflowCheckbox({ checked, disabled, onChange, children, title }) {
|
|
33
|
+
return (
|
|
34
|
+
<label className="dm-orchestration-config__field dm-orchestration-config__field-inline dm-workflow-check" title={title}>
|
|
35
|
+
<input
|
|
36
|
+
type="checkbox"
|
|
37
|
+
checked={checked}
|
|
38
|
+
disabled={disabled}
|
|
39
|
+
onChange={(event) => onChange?.(event.target.checked)}
|
|
40
|
+
/>
|
|
41
|
+
<span className="dm-workflow-check__box" aria-hidden="true">
|
|
42
|
+
{checked ? <Check size={13} strokeWidth={2.4} /> : null}
|
|
43
|
+
</span>
|
|
44
|
+
<span>{children}</span>
|
|
45
|
+
</label>
|
|
46
|
+
);
|
|
47
|
+
}
|
|
48
|
+
|
|
31
49
|
function getAgentHostOptions() {
|
|
32
50
|
return Object.entries(HOST_AUTH_CATALOG || {}).map(([slug, host]) => ({
|
|
33
51
|
value: slug,
|
|
@@ -696,24 +714,20 @@ export function OrchestrationNodeConfigPanel({
|
|
|
696
714
|
Latest registry test: {registryRow.status}
|
|
697
715
|
</span>
|
|
698
716
|
)}
|
|
699
|
-
<
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
onChange={(e) => patchConfig({ writeSourceRecord: e.target.checked })}
|
|
714
|
-
/>
|
|
715
|
-
<span>Write source record history</span>
|
|
716
|
-
</label>
|
|
717
|
+
<WorkflowCheckbox
|
|
718
|
+
checked={config.writeLastResponse !== false}
|
|
719
|
+
disabled={disabled}
|
|
720
|
+
onChange={(checked) => patchConfig({ writeLastResponse: checked })}
|
|
721
|
+
>
|
|
722
|
+
Write lastResponse on success
|
|
723
|
+
</WorkflowCheckbox>
|
|
724
|
+
<WorkflowCheckbox
|
|
725
|
+
checked={config.writeSourceRecord !== false}
|
|
726
|
+
disabled={disabled}
|
|
727
|
+
onChange={(checked) => patchConfig({ writeSourceRecord: checked })}
|
|
728
|
+
>
|
|
729
|
+
Write source record history
|
|
730
|
+
</WorkflowCheckbox>
|
|
717
731
|
<label className="dm-orchestration-config__field">
|
|
718
732
|
<span>Success HTTP codes</span>
|
|
719
733
|
<input
|
|
@@ -882,15 +896,13 @@ export function OrchestrationNodeConfigPanel({
|
|
|
882
896
|
)}
|
|
883
897
|
</div>
|
|
884
898
|
)}
|
|
885
|
-
<
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
<span>Require confirmation before destructive or version-changing execution</span>
|
|
893
|
-
</label>
|
|
899
|
+
<WorkflowCheckbox
|
|
900
|
+
checked={config.confirmationRequired === true}
|
|
901
|
+
disabled={disabled || config.destructive === true}
|
|
902
|
+
onChange={(checked) => patchConfig({ confirmationRequired: checked })}
|
|
903
|
+
>
|
|
904
|
+
Require confirmation before destructive or version-changing execution
|
|
905
|
+
</WorkflowCheckbox>
|
|
894
906
|
<p className="dm-orchestration-config__hint">
|
|
895
907
|
Data actions bind only to this workspace data model. Execution resolves the latest object schema at run time.
|
|
896
908
|
</p>
|
|
@@ -960,27 +972,21 @@ export function OrchestrationNodeConfigPanel({
|
|
|
960
972
|
))}
|
|
961
973
|
</select>
|
|
962
974
|
</label>
|
|
963
|
-
<
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
className="dm-orchestration-config__field dm-orchestration-config__field-inline"
|
|
975
|
+
<WorkflowCheckbox
|
|
976
|
+
checked={config.required !== false}
|
|
977
|
+
disabled={disabled}
|
|
978
|
+
onChange={(checked) => patchConfig({ required: checked })}
|
|
979
|
+
>
|
|
980
|
+
Required
|
|
981
|
+
</WorkflowCheckbox>
|
|
982
|
+
<WorkflowCheckbox
|
|
983
|
+
checked={config.networkAccess === true}
|
|
984
|
+
disabled={disabled}
|
|
974
985
|
title="Network is granted only when both this and the row's networkAllow are on."
|
|
986
|
+
onChange={(checked) => patchConfig({ networkAccess: checked })}
|
|
975
987
|
>
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
checked={config.networkAccess === true}
|
|
979
|
-
disabled={disabled}
|
|
980
|
-
onChange={(e) => patchConfig({ networkAccess: e.target.checked })}
|
|
981
|
-
/>
|
|
982
|
-
<span>Network</span>
|
|
983
|
-
</label>
|
|
988
|
+
Network
|
|
989
|
+
</WorkflowCheckbox>
|
|
984
990
|
</div>
|
|
985
991
|
)}
|
|
986
992
|
|
|
@@ -1013,33 +1019,15 @@ export function OrchestrationNodeConfigPanel({
|
|
|
1013
1019
|
</label>
|
|
1014
1020
|
<div className="dm-orchestration-config__section">
|
|
1015
1021
|
<span>Permissions</span>
|
|
1016
|
-
<
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
</
|
|
1025
|
-
<label className="dm-orchestration-config__field dm-orchestration-config__field-inline">
|
|
1026
|
-
<input
|
|
1027
|
-
type="checkbox"
|
|
1028
|
-
checked={config.canWriteDraft === true}
|
|
1029
|
-
disabled={disabled}
|
|
1030
|
-
onChange={(e) => patchConfig({ canWriteDraft: e.target.checked })}
|
|
1031
|
-
/>
|
|
1032
|
-
<span>Write draft changes only</span>
|
|
1033
|
-
</label>
|
|
1034
|
-
<label className="dm-orchestration-config__field dm-orchestration-config__field-inline">
|
|
1035
|
-
<input
|
|
1036
|
-
type="checkbox"
|
|
1037
|
-
checked={config.networkAccess === true}
|
|
1038
|
-
disabled={disabled}
|
|
1039
|
-
onChange={(e) => patchConfig({ networkAccess: e.target.checked })}
|
|
1040
|
-
/>
|
|
1041
|
-
<span>Allow network access</span>
|
|
1042
|
-
</label>
|
|
1022
|
+
<WorkflowCheckbox checked={config.canReadWorkspace !== false} disabled={disabled} onChange={(checked) => patchConfig({ canReadWorkspace: checked })}>
|
|
1023
|
+
Read workspace data
|
|
1024
|
+
</WorkflowCheckbox>
|
|
1025
|
+
<WorkflowCheckbox checked={config.canWriteDraft === true} disabled={disabled} onChange={(checked) => patchConfig({ canWriteDraft: checked })}>
|
|
1026
|
+
Write draft changes only
|
|
1027
|
+
</WorkflowCheckbox>
|
|
1028
|
+
<WorkflowCheckbox checked={config.networkAccess === true} disabled={disabled} onChange={(checked) => patchConfig({ networkAccess: checked })}>
|
|
1029
|
+
Allow network access
|
|
1030
|
+
</WorkflowCheckbox>
|
|
1043
1031
|
</div>
|
|
1044
1032
|
<KeyValueRows
|
|
1045
1033
|
label="Output fields"
|
|
@@ -1176,10 +1164,9 @@ export function OrchestrationNodeConfigPanel({
|
|
|
1176
1164
|
<span>Message</span>
|
|
1177
1165
|
<textarea rows={6} value={config.message || ""} disabled={disabled} onChange={(e) => patchConfig({ message: e.target.value })} />
|
|
1178
1166
|
</label>
|
|
1179
|
-
<
|
|
1180
|
-
|
|
1181
|
-
|
|
1182
|
-
</label>
|
|
1167
|
+
<WorkflowCheckbox checked={config.requireApproval !== false} disabled={disabled} onChange={(checked) => patchConfig({ requireApproval: checked })}>
|
|
1168
|
+
Require approval before sending
|
|
1169
|
+
</WorkflowCheckbox>
|
|
1183
1170
|
</>
|
|
1184
1171
|
)}
|
|
1185
1172
|
{config.action === "code-function" && (
|
|
@@ -1216,10 +1203,9 @@ export function OrchestrationNodeConfigPanel({
|
|
|
1216
1203
|
valuePlaceholder="Field type or help text"
|
|
1217
1204
|
onChange={(fields) => patchConfig({ fields })}
|
|
1218
1205
|
/>
|
|
1219
|
-
<
|
|
1220
|
-
|
|
1221
|
-
|
|
1222
|
-
</label>
|
|
1206
|
+
<WorkflowCheckbox checked={config.required !== false} disabled={disabled} onChange={(checked) => patchConfig({ required: checked })}>
|
|
1207
|
+
Require response before continuing
|
|
1208
|
+
</WorkflowCheckbox>
|
|
1223
1209
|
</div>
|
|
1224
1210
|
)}
|
|
1225
1211
|
|
|
@@ -1233,10 +1219,9 @@ export function OrchestrationNodeConfigPanel({
|
|
|
1233
1219
|
<span>Sample response</span>
|
|
1234
1220
|
<textarea rows={5} value={config.sampleResponse || ""} disabled={disabled} onChange={(e) => patchConfig({ sampleResponse: e.target.value })} />
|
|
1235
1221
|
</label>
|
|
1236
|
-
<
|
|
1237
|
-
|
|
1238
|
-
|
|
1239
|
-
</label>
|
|
1222
|
+
<WorkflowCheckbox checked={config.blockPublishOnFailure !== false} disabled={disabled} onChange={(checked) => patchConfig({ blockPublishOnFailure: checked })}>
|
|
1223
|
+
Block Publish unless this step passes
|
|
1224
|
+
</WorkflowCheckbox>
|
|
1240
1225
|
</div>
|
|
1241
1226
|
)}
|
|
1242
1227
|
|
|
@@ -202,9 +202,9 @@ export function ReferencePicker({
|
|
|
202
202
|
<div className="dm-reference-picker">
|
|
203
203
|
{error && <p className="dm-field-error" style={{ fontSize: 11 }}>{error}</p>}
|
|
204
204
|
{showRepair && (
|
|
205
|
-
<p className="dm-
|
|
205
|
+
<p className="dm-reference-picker-warning">
|
|
206
206
|
<AlertTriangle size={12} aria-hidden />
|
|
207
|
-
<span>
|
|
207
|
+
<span>Missing reference. Pick a row or test the API Registry.</span>
|
|
208
208
|
</p>
|
|
209
209
|
)}
|
|
210
210
|
<SearchableSelect
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* SidecarExpandView — full-width takeover WITHIN the existing helper sidecar
|
|
5
|
+
* system (SWARM_RUN_CONTRACT_V1, Phase 5).
|
|
6
|
+
*
|
|
7
|
+
* Not a modal and not a route: the parent HelperSidecar widens its own aside
|
|
8
|
+
* while this view is active and renders this wrapper inside the same body.
|
|
9
|
+
* Back returns to the prior sidecar view; Esc collapses (handled by the
|
|
10
|
+
* parent so it composes with the sidecar's existing Esc-to-close); the
|
|
11
|
+
* sidecar close button keeps closing the whole sidecar.
|
|
12
|
+
*
|
|
13
|
+
* Reuses the existing sidecar header/body grammar — no new modal stack, no
|
|
14
|
+
* new visual language.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
import { ArrowLeft } from "lucide-react";
|
|
18
|
+
|
|
19
|
+
export function SidecarExpandView({ title, onBack, children }) {
|
|
20
|
+
return (
|
|
21
|
+
<div className="dm-swarm-expand" data-sidecar-expand="">
|
|
22
|
+
<div className="dm-sidecar-header dm-swarm-expand-head">
|
|
23
|
+
<button
|
|
24
|
+
type="button"
|
|
25
|
+
className="dm-sidecar-icon-btn"
|
|
26
|
+
onClick={onBack}
|
|
27
|
+
aria-label="Back"
|
|
28
|
+
title="Back (Esc)"
|
|
29
|
+
>
|
|
30
|
+
<ArrowLeft size={14} />
|
|
31
|
+
</button>
|
|
32
|
+
<span className="dm-sidecar-title">{title}</span>
|
|
33
|
+
</div>
|
|
34
|
+
<div className="dm-swarm-expand-body">{children}</div>
|
|
35
|
+
</div>
|
|
36
|
+
);
|
|
37
|
+
}
|