@growthub/cli 0.13.2 → 0.13.5
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/metadata-graph/route.js +184 -0
- package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/app/api/workspace/refresh-sources/route.js +24 -2
- package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/app/api/workspace/route.js +14 -0
- package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/app/api/workspace/sandbox-agent-auth/login/route.js +74 -0
- package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/app/api/workspace/sandbox-agent-auth/logout/route.js +67 -0
- package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/app/api/workspace/sandbox-agent-auth/status/route.js +77 -0
- package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/app/api/workspace/sandbox-run/route.js +72 -4
- package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/app/data-model/components/AgentSwarmPanel.jsx +326 -0
- package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/app/data-model/components/DataModelShell.jsx +123 -27
- package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/app/data-model/components/OrchestrationGraphEmptyCanvas.jsx +6 -0
- package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/app/data-model/components/OrchestrationNodeConfigPanel.jsx +224 -1
- package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/app/data-model/components/OrchestrationRunTracePanel.jsx +754 -92
- package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/app/data-model/components/SandboxAgentAuthPanel.jsx +224 -0
- package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/app/data-model/components/SandboxRunPanel.jsx +32 -1
- package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/app/data-model/components/WorkspaceGraphInspectorPanel.jsx +226 -0
- package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/app/globals.css +530 -9
- package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/app/page.jsx +8 -1
- package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/app/settings/integrations/page.jsx +10 -7
- package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/app/workflows/RunSetupPanel.jsx +261 -0
- package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/app/workflows/WorkflowSurface.jsx +119 -9
- package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/app/workspace-builder.jsx +779 -138
- package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/app/workspace-rail.jsx +91 -14
- package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/docs/sandbox-environment-primitive.md +35 -0
- package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/lib/orchestration-agent-swarm.js +923 -0
- package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/lib/orchestration-graph-runner.js +28 -3
- package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/lib/orchestration-graph.js +216 -5
- package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/lib/orchestration-run-console.js +412 -0
- package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/lib/orchestration-run-inputs.js +366 -0
- package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/lib/orchestration-run-trace.js +34 -3
- package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/lib/sandbox-agent-auth-eligibility.js +50 -0
- package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/lib/sandbox-agent-auth-redaction.js +64 -0
- package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/lib/sandbox-agent-auth.js +665 -0
- package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/lib/sandbox-agent-host-catalog.js +168 -0
- package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/lib/workspace-chart-values.js +595 -0
- package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/lib/workspace-data-model.js +164 -7
- package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/lib/workspace-helper.js +11 -0
- package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/lib/workspace-metadata-graph.js +646 -0
- package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/lib/workspace-metadata-selectors.js +249 -0
- package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/lib/workspace-metadata-store.js +1186 -0
- package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/lib/workspace-schema.js +111 -1
- package/assets/worker-kits/growthub-custom-workspace-starter-v1/kit.json +14 -0
- package/package.json +1 -1
|
@@ -0,0 +1,249 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Growthub Workspace Metadata Graph V1 — reusable selectors.
|
|
3
|
+
*
|
|
4
|
+
* Pure functions that operate on the metadata store + graph envelopes.
|
|
5
|
+
* Centralising selection here avoids re-deriving widget required fields,
|
|
6
|
+
* workflow input schemas, or stale-group decisions inside UI components.
|
|
7
|
+
*
|
|
8
|
+
* Each selector is read-only and side-effect free. None of them call fetch,
|
|
9
|
+
* mutate the workspace config, or read secrets.
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
import { findDependents } from "./workspace-metadata-graph.js";
|
|
13
|
+
|
|
14
|
+
function safeString(value) {
|
|
15
|
+
if (value == null) return "";
|
|
16
|
+
return typeof value === "string" ? value : String(value);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
function widgetById(metadataStore, widgetId) {
|
|
20
|
+
const id = safeString(widgetId).trim();
|
|
21
|
+
if (!id) return null;
|
|
22
|
+
return (metadataStore?.widgets || []).find((widget) => widget.id === id) || null;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
function workflowNodeByMetadataId(metadataStore, workflowNodeMetadataId) {
|
|
26
|
+
const id = safeString(workflowNodeMetadataId).trim();
|
|
27
|
+
if (!id) return null;
|
|
28
|
+
return (metadataStore?.workflowNodes || []).find((node) => node.metadataId === id) || null;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
function objectById(metadataStore, objectId) {
|
|
32
|
+
const id = safeString(objectId).trim();
|
|
33
|
+
if (!id) return null;
|
|
34
|
+
return (metadataStore?.objects || []).find((object) => object.id === id) || null;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
function fieldsForObject(metadataStore, objectId) {
|
|
38
|
+
const id = safeString(objectId).trim();
|
|
39
|
+
if (!id) return [];
|
|
40
|
+
return (metadataStore?.fields || []).filter((field) => field.objectId === id);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Required fields for a widget — the typed dependency contract the chart
|
|
45
|
+
* hydration pipeline consumes (x/y axis + groupBy + sort/filter fields).
|
|
46
|
+
*
|
|
47
|
+
* Returns:
|
|
48
|
+
* {
|
|
49
|
+
* required: string[] axis fields the chart needs to compute values
|
|
50
|
+
* filter: string[] fields referenced by filter clauses
|
|
51
|
+
* sort: string[] fields used for ordering
|
|
52
|
+
* aggregation: string[] numeric fields the operation consumes
|
|
53
|
+
* warnings: string[] widget-level warnings
|
|
54
|
+
* }
|
|
55
|
+
*/
|
|
56
|
+
function selectWidgetRequiredFields(metadataStore, widgetId) {
|
|
57
|
+
const widget = widgetById(metadataStore, widgetId);
|
|
58
|
+
if (!widget) {
|
|
59
|
+
return { required: [], filter: [], sort: [], aggregation: [], warnings: ["widget not found"] };
|
|
60
|
+
}
|
|
61
|
+
return {
|
|
62
|
+
required: widget.requiredFields.slice(),
|
|
63
|
+
filter: widget.filterFields.slice(),
|
|
64
|
+
sort: widget.sortFields.slice(),
|
|
65
|
+
aggregation: widget.aggregationFields.slice(),
|
|
66
|
+
warnings: widget.warnings.slice()
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Input schema for a workflow node — typed, redacted, ready for sidecar
|
|
72
|
+
* rendering. Returns `{ fields, requiresInput }` shaped like the manual
|
|
73
|
+
* run-input contract.
|
|
74
|
+
*/
|
|
75
|
+
function selectWorkflowNodeInputSchema(metadataStore, workflowNodeMetadataId) {
|
|
76
|
+
const node = workflowNodeByMetadataId(metadataStore, workflowNodeMetadataId);
|
|
77
|
+
if (!node) return { fields: [], requiresInput: false };
|
|
78
|
+
if (!node.requiresHumanInput) return { fields: [], requiresInput: false };
|
|
79
|
+
const fields = (metadataStore.runInputs || []).filter((input) => input.workflowMetadataId === node.workflowMetadataId);
|
|
80
|
+
return {
|
|
81
|
+
requiresInput: fields.length > 0,
|
|
82
|
+
fields: fields.map((field) => ({
|
|
83
|
+
id: field.id,
|
|
84
|
+
label: field.label,
|
|
85
|
+
type: field.type,
|
|
86
|
+
required: field.required,
|
|
87
|
+
isSecret: field.isSecret,
|
|
88
|
+
secretRefOnly: field.secretRefOnly
|
|
89
|
+
}))
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
function selectObjectFilterableFields(metadataStore, objectId) {
|
|
94
|
+
return fieldsForObject(metadataStore, objectId).filter((field) => field.isFilterable);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
function selectObjectSortableFields(metadataStore, objectId) {
|
|
98
|
+
return fieldsForObject(metadataStore, objectId).filter((field) => field.isSortable);
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
function selectObjectAggregatableFields(metadataStore, objectId) {
|
|
102
|
+
return fieldsForObject(metadataStore, objectId).filter((field) => field.isAggregatable);
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* Lineage for a single run: workflow / sandbox / agent host / inputs / output
|
|
107
|
+
* artifact. Returns flat IDs the UI can resolve through the metadata store.
|
|
108
|
+
*/
|
|
109
|
+
function selectRunLineage(metadataStore, runId) {
|
|
110
|
+
const id = safeString(runId).trim();
|
|
111
|
+
if (!id) return null;
|
|
112
|
+
const run = (metadataStore?.runs || []).find((entry) => entry.runId === id || entry.id === id);
|
|
113
|
+
if (!run) return null;
|
|
114
|
+
const workflow = (metadataStore.workflows || []).find((entry) => entry.metadataId === run.workflowMetadataId);
|
|
115
|
+
const sandbox = (metadataStore.sandboxes || []).find((entry) => entry.metadataId === run.sandboxMetadataId);
|
|
116
|
+
const agentHost = (metadataStore.agentHosts || []).find((entry) => entry.id === run.agentHost);
|
|
117
|
+
const artifacts = (metadataStore.outputArtifacts || []).filter((entry) => entry.runMetadataId === run.metadataId);
|
|
118
|
+
return {
|
|
119
|
+
run,
|
|
120
|
+
workflow: workflow || null,
|
|
121
|
+
sandbox: sandbox || null,
|
|
122
|
+
agentHost: agentHost || null,
|
|
123
|
+
artifacts,
|
|
124
|
+
inputFieldCount: run.inputFieldCount
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
/**
|
|
129
|
+
* Compute which metadata groups become stale given a change event.
|
|
130
|
+
*
|
|
131
|
+
* `changeEvent` shape:
|
|
132
|
+
* { kind: "object" | "field" | "sourceRecord" | "workflow" | "agentHost" | "widget", id: string }
|
|
133
|
+
*
|
|
134
|
+
* The reasoning mirrors Twenty's `useLoadStaleMetadataEntities`:
|
|
135
|
+
* widgets become stale when fields they read change; workflows become
|
|
136
|
+
* stale when input schemas or agent hosts change; dashboards become stale
|
|
137
|
+
* when their widgets do; etc.
|
|
138
|
+
*
|
|
139
|
+
* Returns:
|
|
140
|
+
* { groups: string[], reasons: string[] }
|
|
141
|
+
*/
|
|
142
|
+
function selectStaleMetadataGroups(metadataStore, changeEvent) {
|
|
143
|
+
if (!metadataStore || !changeEvent || typeof changeEvent !== "object") {
|
|
144
|
+
return { groups: [], reasons: [] };
|
|
145
|
+
}
|
|
146
|
+
const kind = safeString(changeEvent.kind).trim();
|
|
147
|
+
const id = safeString(changeEvent.id).trim();
|
|
148
|
+
if (!kind || !id) return { groups: [], reasons: [] };
|
|
149
|
+
const groups = new Set();
|
|
150
|
+
const reasons = [];
|
|
151
|
+
|
|
152
|
+
const widgetsByObject = (objectId) => (metadataStore.widgets || []).filter((widget) => widget.objectId === objectId);
|
|
153
|
+
const widgetsByField = (objectId, fieldId) => (metadataStore.widgets || []).filter((widget) =>
|
|
154
|
+
widget.objectId === objectId && (
|
|
155
|
+
widget.requiredFields.includes(fieldId) ||
|
|
156
|
+
widget.filterFields.includes(fieldId) ||
|
|
157
|
+
widget.sortFields.includes(fieldId)
|
|
158
|
+
)
|
|
159
|
+
);
|
|
160
|
+
const workflowNodesByObject = (objectId) => (metadataStore.workflowNodes || []).filter((node) =>
|
|
161
|
+
node.readsObjectId === objectId || node.writesObjectId === objectId
|
|
162
|
+
);
|
|
163
|
+
|
|
164
|
+
if (kind === "object") {
|
|
165
|
+
const widgets = widgetsByObject(id);
|
|
166
|
+
if (widgets.length) {
|
|
167
|
+
groups.add("workspaceWidgetMetadataItems");
|
|
168
|
+
groups.add("workspaceDashboardMetadataItems");
|
|
169
|
+
groups.add("workspaceFilterMetadataItems");
|
|
170
|
+
groups.add("workspaceSortMetadataItems");
|
|
171
|
+
reasons.push(`${widgets.length} widget(s) bound to object "${id}"`);
|
|
172
|
+
}
|
|
173
|
+
const nodes = workflowNodesByObject(id);
|
|
174
|
+
if (nodes.length) {
|
|
175
|
+
groups.add("workspaceWorkflowMetadataItems");
|
|
176
|
+
groups.add("workspaceWorkflowNodeMetadataItems");
|
|
177
|
+
reasons.push(`${nodes.length} workflow node(s) reference object "${id}"`);
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
if (kind === "field") {
|
|
182
|
+
const [objectId, fieldId] = id.split("::");
|
|
183
|
+
if (objectId && fieldId) {
|
|
184
|
+
const widgets = widgetsByField(objectId, fieldId);
|
|
185
|
+
if (widgets.length) {
|
|
186
|
+
groups.add("workspaceWidgetMetadataItems");
|
|
187
|
+
groups.add("workspaceDashboardMetadataItems");
|
|
188
|
+
reasons.push(`${widgets.length} widget(s) reference field "${objectId}.${fieldId}"`);
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
if (kind === "sourceRecord") {
|
|
194
|
+
const widgets = (metadataStore.widgets || []).filter((widget) => widget.sourceRecordKey === id);
|
|
195
|
+
if (widgets.length) {
|
|
196
|
+
groups.add("workspaceWidgetMetadataItems");
|
|
197
|
+
groups.add("workspaceSourceRecordMetadataItems");
|
|
198
|
+
reasons.push(`${widgets.length} widget(s) backed by source record "${id}"`);
|
|
199
|
+
}
|
|
200
|
+
const objects = (metadataStore.objects || []).filter((object) => object.sourceId === id);
|
|
201
|
+
if (objects.length) {
|
|
202
|
+
groups.add("workspaceObjectMetadataItems");
|
|
203
|
+
reasons.push(`${objects.length} object(s) backed by source record "${id}"`);
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
if (kind === "workflow") {
|
|
208
|
+
groups.add("workspaceWorkflowMetadataItems");
|
|
209
|
+
groups.add("workspaceWorkflowNodeMetadataItems");
|
|
210
|
+
groups.add("workspaceRunInputMetadataItems");
|
|
211
|
+
reasons.push(`workflow "${id}" graph changed — run inputs and node dependencies may be stale`);
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
if (kind === "agentHost") {
|
|
215
|
+
groups.add("workspaceAgentHostMetadataItems");
|
|
216
|
+
groups.add("workspaceSandboxMetadataItems");
|
|
217
|
+
groups.add("workspaceWorkflowMetadataItems");
|
|
218
|
+
reasons.push(`agent host "${id}" readiness changed — sandbox readiness may be stale`);
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
if (kind === "widget") {
|
|
222
|
+
groups.add("workspaceWidgetMetadataItems");
|
|
223
|
+
groups.add("workspaceDashboardMetadataItems");
|
|
224
|
+
reasons.push(`widget "${id}" changed`);
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
return { groups: Array.from(groups), reasons };
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
/**
|
|
231
|
+
* Convenience selector: nodes affected by removing a node from the graph.
|
|
232
|
+
* Used by the inspector to warn the user before they delete a field /
|
|
233
|
+
* source / widget the rest of the workspace depends on.
|
|
234
|
+
*/
|
|
235
|
+
function selectImpactedNodes(graph, nodeId) {
|
|
236
|
+
if (!graph || !nodeId) return [];
|
|
237
|
+
return findDependents(graph, nodeId);
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
export {
|
|
241
|
+
selectWidgetRequiredFields,
|
|
242
|
+
selectWorkflowNodeInputSchema,
|
|
243
|
+
selectObjectFilterableFields,
|
|
244
|
+
selectObjectSortableFields,
|
|
245
|
+
selectObjectAggregatableFields,
|
|
246
|
+
selectRunLineage,
|
|
247
|
+
selectStaleMetadataGroups,
|
|
248
|
+
selectImpactedNodes
|
|
249
|
+
};
|