@growthub/cli 0.14.0 → 0.14.2

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 (40) hide show
  1. package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/app/api/workspace/helper/apply/route.js +99 -2
  2. package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/app/api/workspace/helper/query/route.js +1 -0
  3. package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/app/api/workspace/sandbox-agent-auth/login/route.js +3 -2
  4. package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/app/api/workspace/sandbox-agent-auth/logout/route.js +3 -2
  5. package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/app/api/workspace/sandbox-agent-auth/status/route.js +3 -2
  6. package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/app/api/workspace/sandbox-run/route.js +84 -10
  7. package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/app/components/WorkspaceHelperSetupModal.jsx +2 -2
  8. package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/app/data-model/components/AgentSwarmPanel.jsx +107 -34
  9. package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/app/data-model/components/DataModelShell.jsx +72 -15
  10. package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/app/data-model/components/HelperSidecar.jsx +264 -22
  11. package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/app/data-model/components/OrchestrationGraphCanvas.jsx +81 -10
  12. package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/app/data-model/components/OrchestrationNodeConfigPanel.jsx +179 -117
  13. package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/app/data-model/components/SandboxAgentAuthPanel.jsx +34 -14
  14. package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/app/data-model/components/SidecarExpandView.jsx +37 -0
  15. package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/app/data-model/components/SwarmRunCockpit.jsx +625 -0
  16. package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/app/data-model/components/helper-commands.js +150 -0
  17. package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/app/globals.css +136 -3
  18. package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/app/workflows/WorkflowSurface.jsx +61 -13
  19. package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/docs/sandbox-environment-primitive.md +26 -0
  20. package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/lib/adapters/sandboxes/adapters/local-intelligence-browser-access.js +516 -0
  21. package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/lib/adapters/sandboxes/default-local-agent-host.js +224 -11
  22. package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/lib/adapters/sandboxes/default-local-intelligence.js +4 -0
  23. package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/lib/adapters/sandboxes/default-local-process.js +3 -1
  24. package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/lib/adapters/sandboxes/index.js +1 -0
  25. package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/lib/adapters/sandboxes/sandbox-adapter-registry.js +5 -1
  26. package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/lib/data-model/field-contracts.js +1 -0
  27. package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/lib/orchestration-agent-swarm.js +254 -4
  28. package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/lib/orchestration-graph-runner.js +3 -0
  29. package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/lib/orchestration-graph.js +10 -2
  30. package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/lib/orchestration-run-console.js +412 -1
  31. package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/lib/sandbox-agent-auth.js +82 -27
  32. package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/lib/sandbox-serverless-flow.js +4 -2
  33. package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/lib/workspace-data-model.js +1 -0
  34. package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/lib/workspace-helper.js +23 -0
  35. package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/lib/workspace-metadata-store.js +8 -6
  36. package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/lib/workspace-schema.js +6 -0
  37. package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/lib/workspace-swarm-proposal.js +554 -0
  38. package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/package-lock.json +364 -0
  39. package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/package.json +1 -0
  40. package/package.json +1 -1
@@ -70,6 +70,7 @@ function deriveSandboxServerlessState(input = {}) {
70
70
 
71
71
  const locality = clean(row.runLocality).toLowerCase() === "serverless" ? "serverless" : "local";
72
72
  const isServerless = locality === "serverless";
73
+ const browserAccess = ["true", "1", "on", "yes"].includes(clean(row.browserAccess).toLowerCase());
73
74
  const adapterId = clean(row.adapter);
74
75
  const adapterChosen = Boolean(adapterId);
75
76
 
@@ -162,8 +163,8 @@ function deriveSandboxServerlessState(input = {}) {
162
163
  label: isServerless ? "Run on the scheduler" : "Run locally",
163
164
  status: "optional",
164
165
  description: isServerless
165
- ? "Once the scheduler, auth, and store are ready, run delegates to the serverless scheduler."
166
- : "Run this workflow in-process.",
166
+ ? `Once the scheduler, auth, and store are ready, run delegates to the serverless scheduler.${browserAccess ? " Browser access travels with the run in the growthub-sandbox-run-v1 envelope (sandbox.browserAccess), so the remote handler grants the same capability as a local run." : ""}`
167
+ : `Run this workflow in-process.${browserAccess ? (adapterId === "local-intelligence" ? " Browser access is executed by the local-intelligence browser bridge." : " Browser access is engaged through the selected agent host's first-party browser integration.") : ""}`,
167
168
  action: inline({ id: "run-sandbox", label: "Run" }),
168
169
  });
169
170
 
@@ -192,6 +193,7 @@ function deriveSandboxServerlessState(input = {}) {
192
193
  version: 1,
193
194
  locality,
194
195
  isServerless,
196
+ browserAccess,
195
197
  adapterChosen,
196
198
  schedulerLinked,
197
199
  schedulerHealthy,
@@ -881,6 +881,7 @@ const OBJECT_TYPE_PRESETS = {
881
881
  "envRefs",
882
882
  "networkAllow",
883
883
  "allowList",
884
+ "browserAccess",
884
885
  "instructions",
885
886
  "command",
886
887
  "timeoutMs",
@@ -40,6 +40,12 @@ const WORKSPACE_HELPER_PROPOSAL_TYPES = [
40
40
  // Server-file lane (AWaC: NOT a config PATCH field). Routed in helper/apply to
41
41
  // the confined, gated resolver write — never through writeWorkspaceConfig.
42
42
  "resolver.create",
43
+ // Swarm lane — governed sandbox-environment rows in the EXISTING dataModel
44
+ // patch field. Apply normalizes the intent payload into an agent-swarm-v1
45
+ // graph via buildDefaultAgentSwarmGraph; execution stays behind sandbox-run.
46
+ "swarm.run.propose",
47
+ "swarm.workflow.save",
48
+ "swarm.run.resume",
43
49
  ];
44
50
 
45
51
  const PROPOSAL_TYPE_TO_PATCH_FIELD = {
@@ -56,6 +62,10 @@ const PROPOSAL_TYPE_TO_PATCH_FIELD = {
56
62
  // Sentinel — resolver.create writes a server file, not a config field. It is
57
63
  // explicitly excluded from the PATCH allowlist and handled by its own lane.
58
64
  "resolver.create": "server-file",
65
+ // Swarm rows are dataModel rows. No new PATCH field is introduced.
66
+ "swarm.run.propose": "dataModel",
67
+ "swarm.workflow.save": "dataModel",
68
+ "swarm.run.resume": "dataModel",
59
69
  };
60
70
 
61
71
  const KNOWN_WIDGET_KINDS = ["chart", "view", "iframe", "rich-text"];
@@ -77,6 +87,8 @@ const INTENT_DESCRIPTIONS = {
77
87
  "Inspect the workspace snapshot for broken references, missing bindings, empty objects, or incomplete views. Propose the minimum changes needed to repair each issue.",
78
88
  explain:
79
89
  "Return a clear explanation of what one or more workspace objects, widgets, or configurations do. Use the explain.object proposal type — payload is { explanation: string }.",
90
+ swarm:
91
+ "Propose a governed agent swarm via swarm.run.propose. You are propose-only: do not execute, do not store credentials. Describe the swarm objective, agent roles, task prompts, tools, maxConcurrency, and outcomeCriteria as an intent payload — the server normalizes it into the governed agent-swarm-v1 graph and execution happens only through sandbox-run after the user applies the proposal.",
80
92
  };
81
93
 
82
94
  /**
@@ -91,6 +103,10 @@ const INTENT_DESCRIPTIONS = {
91
103
  * `create_object` when the prompt mentions both "object" and "API".
92
104
  */
93
105
  const INTENT_HEURISTIC_PATTERNS = [
106
+ { intent: "swarm", patterns: [
107
+ /\b(swarm|sub-?agents?|multi-?agent|agent\s+team|orchestrat(e|or|ion))\b/i,
108
+ /\b(run|launch|spawn|dispatch)\b.*\b(agents?|workers?)\b.*\b(parallel|swarm|workflow)\b/i,
109
+ ]},
94
110
  { intent: "register_api", patterns: [
95
111
  /\b(api|endpoint|webhook|integration|connector|oauth|bearer\s+token|auth\s+header)\b/i,
96
112
  /\b(register|connect|wire|hook\s*up)\b.*\b(api|endpoint|webhook|service|integration)\b/i,
@@ -202,6 +218,13 @@ function buildStableSystemPrompt(intent) {
202
218
  "- Reset invalid axis, filter, group, and sort settings when source changes.",
203
219
  "- Mark recomputed values as unsaved unless PATCH succeeds.",
204
220
  "",
221
+ "## When proposing agent swarms (swarm.run.propose)",
222
+ "- You may propose swarm.run.propose. You are propose-only. Do not execute. Do not store credentials.",
223
+ "- Describe the swarm objective, agent roles, tasks, tools, maxConcurrency, and outcomeCriteria.",
224
+ "- The server will normalize this into the governed agent-swarm graph; execution happens only through sandbox-run after apply.",
225
+ "- payload shape: { name, description?, objective, agents: [{ id?, role, description?, taskPrompt, tools?, required?, maxTokens?, timeoutMs? }], maxConcurrency?, outcomeCriteria?, runLocality?, agentHost?, adapter? }",
226
+ "- adapter, when set, must be local-agent-host or local-intelligence.",
227
+ "",
205
228
  "## Valid proposal types and their target patch field",
206
229
  WORKSPACE_HELPER_PROPOSAL_TYPES.map(
207
230
  (t) => ` ${t} → ${PROPOSAL_TYPE_TO_PATCH_FIELD[t]}`
@@ -545,8 +545,8 @@ function deriveWorkspaceWorkflowMetadataItems(workspaceConfig, objectItems) {
545
545
  const graphEdges = Array.isArray(graph?.edges) ? graph.edges : [];
546
546
  const workflowMetadataId = stableId("workflow", objectId, rowName);
547
547
  const sandboxMetadataId = stableId("sandbox", objectId, rowName);
548
- const agentHost = safeString(row.agentHost).trim();
549
- const adapter = safeString(row.adapter).trim();
548
+ const rowAgentHost = safeString(row.agentHost).trim();
549
+ const rowAdapter = safeString(row.adapter).trim();
550
550
  const inputSchema = graphNodes.length ? discoverRunInputSchema(graph) : { requiresInput: false, fields: [] };
551
551
  const inputFields = Array.isArray(inputSchema?.fields) ? inputSchema.fields : [];
552
552
 
@@ -560,8 +560,8 @@ function deriveWorkspaceWorkflowMetadataItems(workspaceConfig, objectItems) {
560
560
  lifecycleStatus: safeString(row.lifecycleStatus).trim() || "draft",
561
561
  version: safeString(row.version).trim() || "1",
562
562
  sandboxMetadataId,
563
- agentHost,
564
- adapter,
563
+ agentHost: rowAgentHost,
564
+ adapter: rowAdapter,
565
565
  runLocality: safeString(row.runLocality).trim(),
566
566
  nodeCount: graphNodes.length,
567
567
  edgeCount: graphEdges.length,
@@ -578,6 +578,8 @@ function deriveWorkspaceWorkflowMetadataItems(workspaceConfig, objectItems) {
578
578
  const sourceType = safeString(config.sourceType).trim();
579
579
  const sourceId = safeString(config.sourceId).trim();
580
580
  const integrationId = safeString(config.integrationId).trim();
581
+ const nodeAgentHost = safeString(config.agentHost || rowAgentHost).trim();
582
+ const nodeAdapter = safeString(config.adapter || rowAdapter).trim();
581
583
  const filterClauses = collectFilterClauses({ op: config.filterMode, clauses: config.filters });
582
584
  const writesObjectId = safeString(config.writeObjectId || config.targetObjectId).trim();
583
585
  const readsObjectId = sourceId || safeString(config.objectId).trim();
@@ -603,8 +605,8 @@ function deriveWorkspaceWorkflowMetadataItems(workspaceConfig, objectItems) {
603
605
  inputFieldCount: inputs.length,
604
606
  inputFieldIds: inputs.map((field) => field.id),
605
607
  sandboxMetadataId,
606
- agentHost,
607
- adapter,
608
+ agentHost: nodeAgentHost,
609
+ adapter: nodeAdapter,
608
610
  permissions: nodeType === "api-registry-call" ? ["integration:read"] : []
609
611
  });
610
612
  }
@@ -1044,6 +1044,12 @@ function validateSandboxEnvironmentRow(row, path, errors) {
1044
1044
  if (row.allowList !== undefined && typeof row.allowList !== "string" && !Array.isArray(row.allowList)) {
1045
1045
  errors.push(`${path}.allowList must be a comma-separated string or array of hostnames`);
1046
1046
  }
1047
+ if (row.browserAccess !== undefined) {
1048
+ const value = String(row.browserAccess).trim().toLowerCase();
1049
+ if (!["", "true", "false", "0", "1", "on", "off"].includes(value)) {
1050
+ errors.push(`${path}.browserAccess must coerce to a boolean (true/false/on/off)`);
1051
+ }
1052
+ }
1047
1053
  if (row.instructions !== undefined && typeof row.instructions !== "string") {
1048
1054
  errors.push(`${path}.instructions must be a string`);
1049
1055
  }