@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.
Files changed (42) hide show
  1. package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/app/api/workspace/metadata-graph/route.js +184 -0
  2. package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/app/api/workspace/refresh-sources/route.js +24 -2
  3. package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/app/api/workspace/route.js +14 -0
  4. package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/app/api/workspace/sandbox-agent-auth/login/route.js +74 -0
  5. package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/app/api/workspace/sandbox-agent-auth/logout/route.js +67 -0
  6. package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/app/api/workspace/sandbox-agent-auth/status/route.js +77 -0
  7. package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/app/api/workspace/sandbox-run/route.js +72 -4
  8. package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/app/data-model/components/AgentSwarmPanel.jsx +326 -0
  9. package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/app/data-model/components/DataModelShell.jsx +123 -27
  10. package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/app/data-model/components/OrchestrationGraphEmptyCanvas.jsx +6 -0
  11. package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/app/data-model/components/OrchestrationNodeConfigPanel.jsx +224 -1
  12. package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/app/data-model/components/OrchestrationRunTracePanel.jsx +754 -92
  13. package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/app/data-model/components/SandboxAgentAuthPanel.jsx +224 -0
  14. package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/app/data-model/components/SandboxRunPanel.jsx +32 -1
  15. package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/app/data-model/components/WorkspaceGraphInspectorPanel.jsx +226 -0
  16. package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/app/globals.css +530 -9
  17. package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/app/page.jsx +8 -1
  18. package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/app/settings/integrations/page.jsx +10 -7
  19. package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/app/workflows/RunSetupPanel.jsx +261 -0
  20. package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/app/workflows/WorkflowSurface.jsx +119 -9
  21. package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/app/workspace-builder.jsx +779 -138
  22. package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/app/workspace-rail.jsx +91 -14
  23. package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/docs/sandbox-environment-primitive.md +35 -0
  24. package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/lib/orchestration-agent-swarm.js +923 -0
  25. package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/lib/orchestration-graph-runner.js +28 -3
  26. package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/lib/orchestration-graph.js +216 -5
  27. package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/lib/orchestration-run-console.js +412 -0
  28. package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/lib/orchestration-run-inputs.js +366 -0
  29. package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/lib/orchestration-run-trace.js +34 -3
  30. package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/lib/sandbox-agent-auth-eligibility.js +50 -0
  31. package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/lib/sandbox-agent-auth-redaction.js +64 -0
  32. package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/lib/sandbox-agent-auth.js +665 -0
  33. package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/lib/sandbox-agent-host-catalog.js +168 -0
  34. package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/lib/workspace-chart-values.js +595 -0
  35. package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/lib/workspace-data-model.js +164 -7
  36. package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/lib/workspace-helper.js +11 -0
  37. package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/lib/workspace-metadata-graph.js +646 -0
  38. package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/lib/workspace-metadata-selectors.js +249 -0
  39. package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/lib/workspace-metadata-store.js +1186 -0
  40. package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/lib/workspace-schema.js +111 -1
  41. package/assets/worker-kits/growthub-custom-workspace-starter-v1/kit.json +14 -0
  42. 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
+ };