@growthub/cli 0.9.3 → 0.9.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 (46) hide show
  1. package/assets/worker-kits/growthub-agency-portal-starter-v1/apps/agency-portal/growthub.config.json +112 -0
  2. package/assets/worker-kits/growthub-agency-portal-starter-v1/apps/agency-portal/package.json +1 -1
  3. package/assets/worker-kits/growthub-agency-portal-starter-v1/bundles/growthub-agency-portal-starter-v1.json +1 -0
  4. package/assets/worker-kits/growthub-agency-portal-starter-v1/kit.json +2 -0
  5. package/assets/worker-kits/growthub-creative-video-pipeline-v1/apps/creative-video-pipeline/package.json +1 -1
  6. package/assets/worker-kits/growthub-custom-workspace-starter-v1/SKILL.md +35 -1
  7. package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/.env.example +41 -0
  8. package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/README.md +38 -0
  9. package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/app/api/settings/integrations/route.js +13 -0
  10. package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/app/api/workspace/route.js +91 -0
  11. package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/app/globals.css +912 -0
  12. package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/app/layout.jsx +14 -0
  13. package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/app/page.jsx +23 -0
  14. package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/app/settings/integrations/page.jsx +105 -0
  15. package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/app/workspace-builder.jsx +680 -0
  16. package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/growthub.config.json +53 -0
  17. package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/jsconfig.json +8 -0
  18. package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/lib/adapters/auth/index.js +21 -0
  19. package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/lib/adapters/env.js +28 -0
  20. package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/lib/adapters/integrations/growthub-connection-normalizer.js +95 -0
  21. package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/lib/adapters/integrations/index.js +198 -0
  22. package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/lib/adapters/payments/index.js +13 -0
  23. package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/lib/adapters/persistence/index.js +13 -0
  24. package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/lib/adapters/persistence/postgres.js +16 -0
  25. package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/lib/adapters/persistence/provider-managed.js +16 -0
  26. package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/lib/adapters/persistence/qstash-kv.js +16 -0
  27. package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/lib/domain/integrations.js +185 -0
  28. package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/lib/domain/portal.js +150 -0
  29. package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/lib/workspace-config.js +232 -0
  30. package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/next.config.js +10 -0
  31. package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/package-lock.json +976 -0
  32. package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/package.json +17 -0
  33. package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/postcss.config.mjs +3 -0
  34. package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/vercel.json +5 -0
  35. package/assets/worker-kits/growthub-custom-workspace-starter-v1/bundles/growthub-custom-workspace-starter-v1.json +13 -0
  36. package/assets/worker-kits/growthub-custom-workspace-starter-v1/docs/adapter-contracts.md +86 -0
  37. package/assets/worker-kits/growthub-custom-workspace-starter-v1/docs/vercel-serverless-deployment.md +46 -0
  38. package/assets/worker-kits/growthub-custom-workspace-starter-v1/growthub.config.json +49 -0
  39. package/assets/worker-kits/growthub-custom-workspace-starter-v1/helpers/check-self-improving-health.sh +60 -0
  40. package/assets/worker-kits/growthub-custom-workspace-starter-v1/helpers/promote-capability.mjs +37 -0
  41. package/assets/worker-kits/growthub-custom-workspace-starter-v1/helpers/propose-capability.mjs +38 -0
  42. package/assets/worker-kits/growthub-custom-workspace-starter-v1/kit.json +45 -0
  43. package/assets/worker-kits/growthub-custom-workspace-starter-v1/templates/deployment-handoff.md +61 -0
  44. package/assets/worker-kits/growthub-custom-workspace-starter-v1/templates/supabase-setup-plan.md +26 -0
  45. package/dist/index.js +2903 -1596
  46. package/package.json +2 -1
@@ -0,0 +1,112 @@
1
+ {
2
+ "id": "agency-portal-default",
3
+ "name": "Agency Portal Dashboard",
4
+ "description": "Default no-code composition shipped by growthub-agency-portal-starter-v1. It stitches the production portal capabilities catalog and Growthub MCP, BYO, and static integration lanes into a composable widget grid. Forks can edit ids, layouts, and bindings to tailor this composition to their governed workspace.",
5
+ "capabilities": [
6
+ "dashboard",
7
+ "clients",
8
+ "pipeline",
9
+ "content",
10
+ "tasks",
11
+ "finance",
12
+ "reports",
13
+ "metrics",
14
+ "client-results",
15
+ "operations",
16
+ "settings"
17
+ ],
18
+ "pipelines": [],
19
+ "integrations": [
20
+ "windsor-ai",
21
+ "google-sheets-blended-data",
22
+ "google-analytics",
23
+ "shopify",
24
+ "meta-ads"
25
+ ],
26
+ "canvas": {
27
+ "id": "agency-canvas",
28
+ "name": "Agency operating dashboard",
29
+ "scope": "workspace",
30
+ "layout": {
31
+ "columns": 12,
32
+ "rowHeight": 64,
33
+ "gap": 16,
34
+ "responsive": true
35
+ },
36
+ "widgets": [
37
+ {
38
+ "id": "mrr",
39
+ "kind": "chart-metric",
40
+ "title": "MRR",
41
+ "chart": "number",
42
+ "aggregate": "sum",
43
+ "slug": "agencyMetric",
44
+ "bindings": { "field": "mrr" },
45
+ "position": { "x": 0, "y": 0, "w": 3, "h": 2 }
46
+ },
47
+ {
48
+ "id": "pipeline-by-stage",
49
+ "kind": "chart-metric",
50
+ "title": "Pipeline by stage",
51
+ "chart": "bar",
52
+ "aggregate": "sum",
53
+ "slug": "opportunity",
54
+ "bindings": { "groupBy": "stage", "field": "value" },
55
+ "position": { "x": 3, "y": 0, "w": 6, "h": 4 }
56
+ },
57
+ {
58
+ "id": "client-health",
59
+ "kind": "fields",
60
+ "title": "Client health",
61
+ "slug": "client",
62
+ "bindings": { "fields": ["healthScore", "stage", "renewalDate"] },
63
+ "position": { "x": 9, "y": 0, "w": 3, "h": 2 }
64
+ },
65
+ {
66
+ "id": "windsor-status",
67
+ "kind": "integration-card",
68
+ "title": "Windsor AI",
69
+ "slug": "windsor-ai",
70
+ "bindings": { "lane": "data-source", "adapter": "growthub-bridge" },
71
+ "position": { "x": 0, "y": 2, "w": 3, "h": 2 }
72
+ },
73
+ {
74
+ "id": "open-tasks",
75
+ "kind": "table",
76
+ "title": "Open tasks",
77
+ "slug": "task",
78
+ "bindings": { "filters": [{ "field": "done", "op": "eq", "value": false }] },
79
+ "position": { "x": 9, "y": 2, "w": 3, "h": 2 }
80
+ },
81
+ {
82
+ "id": "agent-chat",
83
+ "kind": "chat-session",
84
+ "title": "Agent chat",
85
+ "position": { "x": 0, "y": 4, "w": 4, "h": 4 }
86
+ },
87
+ {
88
+ "id": "active-workflow",
89
+ "kind": "workflow-runner",
90
+ "title": "Active pipeline",
91
+ "position": { "x": 4, "y": 4, "w": 4, "h": 4 }
92
+ },
93
+ {
94
+ "id": "recent-artifacts",
95
+ "kind": "artifact-viewer",
96
+ "title": "Recent reports",
97
+ "mediaPreview": true,
98
+ "position": { "x": 8, "y": 4, "w": 4, "h": 4 }
99
+ }
100
+ ],
101
+ "bindings": {
102
+ "chatToCanvas": true,
103
+ "workflowOutputsToArtifacts": true,
104
+ "sessionContext": true,
105
+ "portalCapabilities": true
106
+ }
107
+ },
108
+ "provenance": {
109
+ "createdBy": "cli",
110
+ "note": "Shipped with growthub-agency-portal-starter-v1; safe to edit inside a governed fork and validate through the starter export smoke path."
111
+ }
112
+ }
@@ -5,7 +5,7 @@
5
5
  "type": "module",
6
6
  "scripts": {
7
7
  "dev": "next dev",
8
- "build": "next build",
8
+ "build": "next build --webpack",
9
9
  "start": "next start",
10
10
  "lint": "next lint"
11
11
  },
@@ -54,6 +54,7 @@
54
54
  "apps/agency-portal/package.json",
55
55
  "apps/agency-portal/package-lock.json",
56
56
  "apps/agency-portal/next.config.js",
57
+ "apps/agency-portal/growthub.config.json",
57
58
  "apps/agency-portal/app/settings/integrations/page.jsx",
58
59
  "apps/agency-portal/lib/adapters/env.js",
59
60
  "apps/agency-portal/lib/adapters/integrations/index.js",
@@ -71,6 +71,7 @@
71
71
  "apps/agency-portal/next.config.js",
72
72
  "apps/agency-portal/postcss.config.mjs",
73
73
  "apps/agency-portal/vercel.json",
74
+ "apps/agency-portal/growthub.config.json",
74
75
  "apps/agency-portal/app/layout.jsx",
75
76
  "apps/agency-portal/app/page.jsx",
76
77
  "apps/agency-portal/app/globals.css",
@@ -118,6 +119,7 @@
118
119
  "apps/agency-portal",
119
120
  "apps/agency-portal/package-lock.json",
120
121
  "apps/agency-portal/next.config.js",
122
+ "apps/agency-portal/growthub.config.json",
121
123
  "apps/agency-portal/lib/adapters",
122
124
  "templates",
123
125
  "templates/project.md",
@@ -5,7 +5,7 @@
5
5
  "type": "module",
6
6
  "scripts": {
7
7
  "dev": "next dev",
8
- "build": "next build",
8
+ "build": "next build --webpack",
9
9
  "start": "next start",
10
10
  "lint": "next lint"
11
11
  },
@@ -19,7 +19,16 @@ selfEval:
19
19
  - Operator contract read before any material change.
20
20
  maxRetries: 3
21
21
  traceTo: .growthub-fork/trace.jsonl
22
- helpers: []
22
+ helpers:
23
+ - path: helpers/propose-capability.mjs
24
+ verb: propose-capability
25
+ description: Propose a reusable capability from a pipeline run (self-improving feature).
26
+ - path: helpers/promote-capability.mjs
27
+ verb: promote-capability
28
+ description: Promote a capability proposal to the active library.
29
+ - path: helpers/check-self-improving-health.sh
30
+ verb: check-self-improving-health
31
+ description: Validate self-improving workspace primitives and proposal dirs.
23
32
  subSkills: []
24
33
  mcpTools: []
25
34
  ---
@@ -91,6 +100,31 @@ Helpers live under `helpers/`. When an existing shell snippet in `skills.md` is
91
100
 
92
101
  (None declared at the baseline; see `helpers/README.md` for the pattern.)
93
102
 
103
+ ## Self-improving feature (optional extension)
104
+
105
+ Any governed workspace can activate the self-improving loop — no separate kit required.
106
+
107
+ After a successful pipeline or orchestrator run, propose a reusable capability:
108
+
109
+ ```bash
110
+ # Propose a capability from a run (anchors to trace.jsonl event)
111
+ node helpers/propose-capability.mjs --from-run <run-id> --summary "what this run produced"
112
+ # or directly:
113
+ growthub workspace improve propose --from-run <run-id>
114
+
115
+ # Review proposals
116
+ growthub workspace improve list
117
+ growthub workspace improve inspect <slug>
118
+ growthub workspace improve promote <slug>
119
+
120
+ # Health check (includes self-improving feature checks)
121
+ bash helpers/check-self-improving-health.sh
122
+ ```
123
+
124
+ Proposals are governed writes to `.growthub-fork/capabilities/proposals/`. Every proposal references the originating `trace.jsonl` event by trace-event ID — no duplicated schema. Each lifecycle transition (`proposed → promoted | rejected`) appends a typed trace event (`capability_proposed`, `capability_promoted`, `capability_rejected`).
125
+
126
+ This is an **optional feature extension** on the base governed workspace primitive, not a separate workspace type.
127
+
94
128
  ## MCP routing (optional)
95
129
 
96
130
  If a concrete MCP server is available for this fork, list its tool IDs in `mcpTools[]`. Growthub's baseline ships declarative-only routing vocabulary — the CLI does not run an MCP server at v1. This field lets future MCP integration light up additively without a breaking change.
@@ -0,0 +1,41 @@
1
+ # Core adapter selectors
2
+ AGENCY_PORTAL_DEPLOY_TARGET=vercel
3
+ AGENCY_PORTAL_DATA_ADAPTER=provider-managed
4
+ AGENCY_PORTAL_AUTH_ADAPTER=provider-managed
5
+ AGENCY_PORTAL_PAYMENT_ADAPTER=none
6
+
7
+ # Integration mode
8
+ # - growthub-bridge: hosted Growthub account authority
9
+ # - byo-api-key: workspace-owned connection metadata
10
+ # - static: local starter catalog only
11
+ AGENCY_PORTAL_INTEGRATION_ADAPTER=growthub-bridge
12
+
13
+ # Hosted bridge authority
14
+ GROWTHUB_BRIDGE_BASE_URL=https://www.growthub.ai
15
+ GROWTHUB_BRIDGE_INTEGRATIONS_PATH=/api/mcp/accounts
16
+ GROWTHUB_BRIDGE_ACCESS_TOKEN=
17
+ GROWTHUB_BRIDGE_USER_ID=
18
+
19
+ # Optional Windsor reporting lane.
20
+ # Hybrid first boot: keep growthub-bridge authority and set WINDSOR_API_KEY
21
+ # to mark Windsor AI + Google Sheets blended data connected locally.
22
+ AGENCY_PORTAL_REPORTING_ADAPTER=windsor
23
+ WINDSOR_API_KEY=
24
+
25
+ # Optional BYO connection metadata
26
+ AGENCY_PORTAL_BYO_CONNECTIONS_JSON=
27
+
28
+ # Optional payment/auth/database env selected by adapter values above
29
+ DATABASE_URL=
30
+ QSTASH_KV_REST_URL=
31
+ QSTASH_KV_REST_TOKEN=
32
+ AUTH_SECRET=
33
+ AUTH_ISSUER=
34
+ AUTH_CLIENT_ID=
35
+ AUTH_CLIENT_SECRET=
36
+ PAYMENT_SECRET_KEY=
37
+ PAYMENT_WEBHOOK_SECRET=
38
+
39
+ # Optional app settings
40
+ CRON_SECRET=
41
+ PORTAL_USER_ID=
@@ -0,0 +1,38 @@
1
+ # Growthub Workspace App
2
+
3
+ This app is the Vercel/serverless runtime payload for `growthub-workspace-starter-v1`.
4
+
5
+ It intentionally depends on adapter contracts:
6
+
7
+ - `AGENCY_PORTAL_DATA_ADAPTER`
8
+ - `AGENCY_PORTAL_AUTH_ADAPTER`
9
+ - `AGENCY_PORTAL_PAYMENT_ADAPTER`
10
+ - `AGENCY_PORTAL_INTEGRATION_ADAPTER`
11
+ - `GROWTHUB_BRIDGE_BASE_URL`
12
+ - `GROWTHUB_BRIDGE_INTEGRATIONS_PATH`
13
+ - `GROWTHUB_BRIDGE_ACCESS_TOKEN`
14
+ - `GROWTHUB_BRIDGE_USER_ID`
15
+ - `AGENCY_PORTAL_BYO_CONNECTIONS_JSON`
16
+
17
+ The Growthub local-first operator shell remains at `../../studio`.
18
+
19
+ Settings exposes two integration lanes:
20
+
21
+ - Data sources: Windsor AI, Google Sheets blended data, Google Analytics, Shopify, Meta Facebook/Instagram.
22
+ - Workspace integrations: Asana, Slack, GoHighLevel, Google Drive, Notion.
23
+
24
+ Use `AGENCY_PORTAL_INTEGRATION_ADAPTER=growthub-bridge` when the deployed app should read connection state from the Growthub GH app MCP bridge. The reusable primitive is `lib/adapters/integrations/growthub-connection-normalizer.js`; it accepts SDK/profile-style `integrations[]` payloads and GH app MCP `accounts[]` payloads, then emits the same normalized object shape used by `byo-api-key`. Keep provider tokens in the hosted authority layer or named env vars; this app consumes normalized connection metadata only.
25
+
26
+ For first boot, the bundled app also supports a hybrid path: keep `AGENCY_PORTAL_INTEGRATION_ADAPTER=growthub-bridge` and set `WINDSOR_API_KEY` locally. That overlays connected state for Windsor AI and Google Sheets blended data without moving the rest of the portal off the hosted bridge authority path.
27
+
28
+ ## Run
29
+
30
+ ```bash
31
+ npm install
32
+ npm run dev
33
+ npm run build
34
+ ```
35
+
36
+ ## Deploy
37
+
38
+ Use this directory as the Vercel project root.
@@ -0,0 +1,13 @@
1
+ import { NextResponse } from "next/server";
2
+ import { describeIntegrationAdapter, listAgencyPortalIntegrations } from "@/lib/adapters/integrations";
3
+ import { groupIntegrationsByLane } from "@/lib/domain/integrations";
4
+ async function GET() {
5
+ const integrations = await listAgencyPortalIntegrations();
6
+ return NextResponse.json({
7
+ adapter: describeIntegrationAdapter(),
8
+ ...groupIntegrationsByLane(integrations)
9
+ });
10
+ }
11
+ export {
12
+ GET
13
+ };
@@ -0,0 +1,91 @@
1
+ import { NextResponse } from "next/server";
2
+ import { describeAuthAdapter } from "@/lib/adapters/auth";
3
+ import { readAdapterConfig } from "@/lib/adapters/env";
4
+ import { describeIntegrationAdapter, listAgencyPortalIntegrations } from "@/lib/adapters/integrations";
5
+ import { describePaymentAdapter } from "@/lib/adapters/payments";
6
+ import { describePersistenceAdapter } from "@/lib/adapters/persistence";
7
+ import { groupIntegrationsByLane } from "@/lib/domain/integrations";
8
+ import { buildPortalWorkspace, portalCapabilities } from "@/lib/domain/portal";
9
+ import {
10
+ describePersistenceMode,
11
+ readWorkspaceConfig,
12
+ writeWorkspaceConfig
13
+ } from "@/lib/workspace-config";
14
+
15
+ const ALLOWED_PATCH_FIELDS = new Set(["dashboards", "widgetTypes", "canvas"]);
16
+
17
+ async function GET() {
18
+ const integrations = await listAgencyPortalIntegrations();
19
+ const config = readAdapterConfig();
20
+ const adapters = {
21
+ persistence: describePersistenceAdapter(),
22
+ auth: describeAuthAdapter(),
23
+ payments: describePaymentAdapter(),
24
+ integrations: describeIntegrationAdapter()
25
+ };
26
+ const settings = {
27
+ integrations: groupIntegrationsByLane(integrations)
28
+ };
29
+ const workspaceConfig = await readWorkspaceConfig();
30
+ const persistence = describePersistenceMode();
31
+ return NextResponse.json({
32
+ config,
33
+ adapters,
34
+ capabilities: portalCapabilities,
35
+ settings,
36
+ workspace: buildPortalWorkspace({ config, adapters, integrations: settings.integrations }),
37
+ workspaceConfig,
38
+ workspaceConfigPersistence: persistence
39
+ });
40
+ }
41
+
42
+ async function PATCH(request) {
43
+ let patch;
44
+ try {
45
+ patch = await request.json();
46
+ } catch {
47
+ return NextResponse.json({ error: "invalid json body" }, { status: 400 });
48
+ }
49
+ if (!patch || typeof patch !== "object" || Array.isArray(patch)) {
50
+ return NextResponse.json({ error: "patch must be a plain object" }, { status: 400 });
51
+ }
52
+ const unknown = Object.keys(patch).filter((key) => !ALLOWED_PATCH_FIELDS.has(key));
53
+ if (unknown.length) {
54
+ return NextResponse.json(
55
+ { error: "patch contains unknown fields", details: unknown, allowed: Array.from(ALLOWED_PATCH_FIELDS) },
56
+ { status: 400 }
57
+ );
58
+ }
59
+ const sanitized = {};
60
+ for (const key of ALLOWED_PATCH_FIELDS) {
61
+ if (Object.prototype.hasOwnProperty.call(patch, key)) {
62
+ sanitized[key] = patch[key];
63
+ }
64
+ }
65
+ try {
66
+ const next = await writeWorkspaceConfig(sanitized);
67
+ return NextResponse.json({ workspaceConfig: next });
68
+ } catch (error) {
69
+ if (error.code === "WORKSPACE_PERSISTENCE_READ_ONLY") {
70
+ return NextResponse.json(
71
+ {
72
+ error: "workspace config is read-only in this runtime",
73
+ reason: error.message,
74
+ adapter: error.adapter,
75
+ guidance:
76
+ "Edit growthub.config.json locally, or set WORKSPACE_CONFIG_ALLOW_FS_WRITE=true on a writable runtime."
77
+ },
78
+ { status: 409 }
79
+ );
80
+ }
81
+ if (error.code === "WORKSPACE_PERSISTENCE_PATH_REFUSED") {
82
+ return NextResponse.json({ error: error.message }, { status: 500 });
83
+ }
84
+ if (error.code === "INVALID_WORKSPACE_CONFIG") {
85
+ return NextResponse.json({ error: error.message, details: error.details }, { status: 400 });
86
+ }
87
+ return NextResponse.json({ error: error.message || "failed to write workspace config" }, { status: 500 });
88
+ }
89
+ }
90
+
91
+ export { GET, PATCH };