@growthub/cli 0.13.5 → 0.13.6
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/QUICKSTART.md +19 -0
- package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/.env.example +8 -0
- package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/README.md +4 -0
- package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/app/api/workspace/integrations/nango/action/execute/route.js +60 -0
- package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/app/api/workspace/integrations/nango/actions/route.js +50 -0
- package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/app/api/workspace/integrations/nango/connect-session/route.js +68 -0
- package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/app/api/workspace/integrations/nango/connection-status/route.js +56 -0
- package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/app/api/workspace/integrations/nango/proxy/route.js +67 -0
- package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/app/api/workspace/integrations/nango/status/route.js +50 -0
- package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/app/data-model/components/DataModelShell.jsx +161 -50
- package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/app/data-model/components/NangoConnectionPanel.jsx +496 -0
- package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/app/globals.css +104 -17
- package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/app/settings/integrations/nango/page.jsx +167 -0
- package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/app/settings/integrations/page.jsx +1 -0
- package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/app/workflows/WorkflowSurface.jsx +18 -7
- package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/app/workspace-builder.jsx +17 -9
- package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/app/workspace-rail.jsx +16 -14
- package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/lib/adapters/env.js +7 -0
- package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/lib/adapters/integrations/nango/index.js +38 -0
- package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/lib/adapters/integrations/nango/nango-adapter.js +552 -0
- package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/lib/adapters/integrations/nango/nango-config-loader.js +202 -0
- package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/lib/adapters/integrations/nango/nango-schema.js +303 -0
- package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/lib/adapters/integrations/resolver-loader.js +49 -10
- package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/lib/adapters/integrations/source-resolver-registry.js +1 -1
- package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/lib/adapters/integrations/templates/nango.js +49 -0
- package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/lib/adapters/integrations/templates/template-registry.js +4 -2
- package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/lib/orchestration-graph.js +2 -2
- package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/lib/workspace-data-model.js +2 -1
- package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/lib/workspace-schema.js +102 -3
- package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/package.json +1 -0
- package/assets/worker-kits/growthub-custom-workspace-starter-v1/bundles/growthub-custom-workspace-starter-v1.json +1 -0
- package/assets/worker-kits/growthub-custom-workspace-starter-v1/kit.json +2 -0
- package/assets/worker-kits/growthub-custom-workspace-starter-v1/templates/seeded-configs/project-management.config.json +276 -0
- package/dist/index.js +127 -44
- package/package.json +1 -1
|
@@ -305,7 +305,7 @@ function findSandboxRowsForRegistry(workspaceConfig, integrationId) {
|
|
|
305
305
|
if (!sandboxObject) return [];
|
|
306
306
|
const rows = Array.isArray(sandboxObject.rows) ? sandboxObject.rows : [];
|
|
307
307
|
return rows.filter((row) => {
|
|
308
|
-
const graph = parseOrchestrationGraph(row?.orchestrationGraph);
|
|
308
|
+
const graph = parseOrchestrationGraph(row?.orchestrationConfig || row?.orchestrationGraph);
|
|
309
309
|
if (!graph?.nodes) return String(row?.schedulerRegistryId || "").trim() === id;
|
|
310
310
|
return graph.nodes.some(
|
|
311
311
|
(node) => node?.type === "api-registry-call"
|
|
@@ -359,7 +359,7 @@ function buildSandboxRowFromApiRegistry(workspaceConfig, registryRow, options =
|
|
|
359
359
|
lastRunId: "",
|
|
360
360
|
lastSourceId: "",
|
|
361
361
|
lastResponse: "",
|
|
362
|
-
|
|
362
|
+
orchestrationConfig: serializeOrchestrationGraph(graph),
|
|
363
363
|
description: String(options.description || registryRow?.description || "").trim()
|
|
364
364
|
};
|
|
365
365
|
}
|
|
@@ -417,6 +417,7 @@ function deriveManualObjectTable(object, options = {}) {
|
|
|
417
417
|
source,
|
|
418
418
|
objectType: object.objectType || "custom",
|
|
419
419
|
icon: object.icon || null,
|
|
420
|
+
locked: object.locked !== undefined ? Boolean(object.locked) : Boolean(object.objectType && object.objectType !== "custom"),
|
|
420
421
|
pickerHidden: Boolean(object.pickerHidden),
|
|
421
422
|
columns: hydratedColumns,
|
|
422
423
|
rows: hydratedRows,
|
|
@@ -888,7 +889,7 @@ const OBJECT_TYPE_PRESETS = {
|
|
|
888
889
|
"lastRunId",
|
|
889
890
|
"lastSourceId",
|
|
890
891
|
"lastResponse",
|
|
891
|
-
"
|
|
892
|
+
"orchestrationConfig",
|
|
892
893
|
"description",
|
|
893
894
|
"resolverTemplateId",
|
|
894
895
|
"connectorKind",
|
|
@@ -96,6 +96,15 @@ const KNOWN_SANDBOX_AGENT_HOSTS = [
|
|
|
96
96
|
];
|
|
97
97
|
|
|
98
98
|
const NORMALIZED_OBJECT_FIELD_IDS = ["id", "label", "secondaryLabel", "entityType", "provider", "lane", "status"];
|
|
99
|
+
|
|
100
|
+
// API Registry V1 — Nango binding fields are additive and OPTIONAL on the
|
|
101
|
+
// existing `objectType: "api-registry"` row shape (whose canonical columns
|
|
102
|
+
// are owned by `lib/workspace-data-model.js`). They only carry meaning when
|
|
103
|
+
// the row's `connectorKind === "nango"`. The HTTP, MCP, Chrome, and tool
|
|
104
|
+
// connectorKinds keep working unchanged.
|
|
105
|
+
const KNOWN_NANGO_MODES = ["cloud", "self-hosted"];
|
|
106
|
+
const NANGO_PROVIDER_CONFIG_KEY_MAX = 64;
|
|
107
|
+
const NANGO_PROVIDER_CONFIG_KEY_PATTERN = /^[A-Za-z0-9][A-Za-z0-9_.-]*$/;
|
|
99
108
|
const WORKSPACE_TEMPLATE_KIND = "growthub-workspace-template";
|
|
100
109
|
const WORKSPACE_TEMPLATE_VERSION = 1;
|
|
101
110
|
const WORKSPACE_TEMPLATE_SOURCE = "growthub-custom-workspace-starter-v1";
|
|
@@ -1016,9 +1025,11 @@ function validateSandboxEnvironmentRow(row, path, errors) {
|
|
|
1016
1025
|
errors.push(`${path}.intelligenceAdapterMode must be one of ${INTELLIGENCE_ADAPTER_MODES.join(", ")}`);
|
|
1017
1026
|
}
|
|
1018
1027
|
}
|
|
1019
|
-
|
|
1020
|
-
if (
|
|
1021
|
-
|
|
1028
|
+
for (const field of ["orchestrationConfig", "orchestrationGraph"]) {
|
|
1029
|
+
if (row[field] !== undefined && row[field] !== null && row[field] !== "") {
|
|
1030
|
+
if (typeof row[field] !== "string" && (typeof row[field] !== "object" || Array.isArray(row[field]))) {
|
|
1031
|
+
errors.push(`${path}.${field} must be a JSON string or plain object`);
|
|
1032
|
+
}
|
|
1022
1033
|
}
|
|
1023
1034
|
}
|
|
1024
1035
|
if (row.envRefs !== undefined && typeof row.envRefs !== "string" && !Array.isArray(row.envRefs)) {
|
|
@@ -1115,6 +1126,88 @@ function validateSandboxEnvironmentRow(row, path, errors) {
|
|
|
1115
1126
|
}
|
|
1116
1127
|
}
|
|
1117
1128
|
|
|
1129
|
+
/**
|
|
1130
|
+
* Validate the OPTIONAL Nango binding fields that may appear on an
|
|
1131
|
+
* `objectType: "api-registry"` row when `connectorKind === "nango"`.
|
|
1132
|
+
*
|
|
1133
|
+
* The canonical api-registry columns (`integrationId`, `authRef`, `baseUrl`,
|
|
1134
|
+
* `endpoint`, `method`, `status`, `connectorKind`, `resolverTemplateId`, ...)
|
|
1135
|
+
* are owned by `lib/workspace-data-model.js` and validated by their own
|
|
1136
|
+
* shape. This function only inspects the Nango extension fields and is a
|
|
1137
|
+
* no-op for HTTP / MCP / Chrome / tool / custom rows.
|
|
1138
|
+
*/
|
|
1139
|
+
function validateApiRegistryRow(row, path, errors) {
|
|
1140
|
+
if (!isPlainObject(row)) return;
|
|
1141
|
+
// Defensive: any api-registry row is forbidden from persisting raw
|
|
1142
|
+
// credentials. The auth ref lives in `authRef` (an env-ref name) and the
|
|
1143
|
+
// actual secret stays in env. This guard applies to ALL connectorKinds.
|
|
1144
|
+
const FORBIDDEN_TOKEN_FIELDS = [
|
|
1145
|
+
"secret",
|
|
1146
|
+
"secretKey",
|
|
1147
|
+
"apiKey",
|
|
1148
|
+
"token",
|
|
1149
|
+
"authToken",
|
|
1150
|
+
"accessToken",
|
|
1151
|
+
"refreshToken",
|
|
1152
|
+
"bearer",
|
|
1153
|
+
"password"
|
|
1154
|
+
];
|
|
1155
|
+
for (const forbidden of FORBIDDEN_TOKEN_FIELDS) {
|
|
1156
|
+
if (Object.prototype.hasOwnProperty.call(row, forbidden)) {
|
|
1157
|
+
errors.push(`${path}.${forbidden} is not allowed on an api-registry row — store the env-ref name in authRef and keep the secret in env`);
|
|
1158
|
+
}
|
|
1159
|
+
}
|
|
1160
|
+
if (row.connectorKind !== "nango") return;
|
|
1161
|
+
// Nango-specific binding fields. All are optional individually, but
|
|
1162
|
+
// `providerConfigKey` must resolve at runtime — either explicitly or by
|
|
1163
|
+
// falling back to `integrationId`. Validate format only when present.
|
|
1164
|
+
if (row.providerConfigKey !== undefined && row.providerConfigKey !== null && row.providerConfigKey !== "") {
|
|
1165
|
+
if (
|
|
1166
|
+
typeof row.providerConfigKey !== "string"
|
|
1167
|
+
|| row.providerConfigKey.length > NANGO_PROVIDER_CONFIG_KEY_MAX
|
|
1168
|
+
|| !NANGO_PROVIDER_CONFIG_KEY_PATTERN.test(row.providerConfigKey)
|
|
1169
|
+
) {
|
|
1170
|
+
errors.push(`${path}.providerConfigKey must be alphanumeric (with _.- separators), starting alphanumeric, and <= ${NANGO_PROVIDER_CONFIG_KEY_MAX} chars`);
|
|
1171
|
+
}
|
|
1172
|
+
}
|
|
1173
|
+
if (row.nangoMode !== undefined && row.nangoMode !== "" && !KNOWN_NANGO_MODES.includes(row.nangoMode)) {
|
|
1174
|
+
errors.push(`${path}.nangoMode must be one of ${KNOWN_NANGO_MODES.join(", ")}`);
|
|
1175
|
+
}
|
|
1176
|
+
if (row.nangoHostUrl !== undefined && row.nangoHostUrl !== null && row.nangoHostUrl !== "" && typeof row.nangoHostUrl !== "string") {
|
|
1177
|
+
errors.push(`${path}.nangoHostUrl must be a string when present`);
|
|
1178
|
+
}
|
|
1179
|
+
if (row.nangoEnvironment !== undefined && row.nangoEnvironment !== null && row.nangoEnvironment !== "" && typeof row.nangoEnvironment !== "string") {
|
|
1180
|
+
errors.push(`${path}.nangoEnvironment must be a string when present`);
|
|
1181
|
+
}
|
|
1182
|
+
if (row.connectionIds !== undefined) {
|
|
1183
|
+
if (typeof row.connectionIds === "string") {
|
|
1184
|
+
// Allow comma-separated form for hand-edits — splitting/normalization
|
|
1185
|
+
// happens at the resolver boundary, not in the validator.
|
|
1186
|
+
} else if (!Array.isArray(row.connectionIds)) {
|
|
1187
|
+
errors.push(`${path}.connectionIds must be a comma-separated string or an array of strings`);
|
|
1188
|
+
} else {
|
|
1189
|
+
row.connectionIds.forEach((value, index) => {
|
|
1190
|
+
if (typeof value !== "string" || !value.trim()) {
|
|
1191
|
+
errors.push(`${path}.connectionIds[${index}] must be a non-empty string`);
|
|
1192
|
+
}
|
|
1193
|
+
});
|
|
1194
|
+
}
|
|
1195
|
+
}
|
|
1196
|
+
if (row.enabledActions !== undefined) {
|
|
1197
|
+
if (typeof row.enabledActions === "string") {
|
|
1198
|
+
// Comma-separated form is allowed.
|
|
1199
|
+
} else if (!Array.isArray(row.enabledActions)) {
|
|
1200
|
+
errors.push(`${path}.enabledActions must be a comma-separated string or an array of strings`);
|
|
1201
|
+
} else {
|
|
1202
|
+
row.enabledActions.forEach((value, index) => {
|
|
1203
|
+
if (typeof value !== "string" || !value.trim()) {
|
|
1204
|
+
errors.push(`${path}.enabledActions[${index}] must be a non-empty string`);
|
|
1205
|
+
}
|
|
1206
|
+
});
|
|
1207
|
+
}
|
|
1208
|
+
}
|
|
1209
|
+
}
|
|
1210
|
+
|
|
1118
1211
|
const NAV_FOLDERS_OBJECT_ID = "nav-folders";
|
|
1119
1212
|
const NAV_FOLDER_NAME_MAX = 60;
|
|
1120
1213
|
const NAV_ITEM_LABEL_MAX = 80;
|
|
@@ -1265,6 +1358,9 @@ function validateDataModelConfig(dataModel, errors) {
|
|
|
1265
1358
|
if (object.objectType === "sandbox-environment") {
|
|
1266
1359
|
validateSandboxEnvironmentRow(row, `${prefix}.rows[${rowIndex}]`, errors);
|
|
1267
1360
|
}
|
|
1361
|
+
if (object.objectType === "api-registry") {
|
|
1362
|
+
validateApiRegistryRow(row, `${prefix}.rows[${rowIndex}]`, errors);
|
|
1363
|
+
}
|
|
1268
1364
|
if (object.id === NAV_FOLDERS_OBJECT_ID) {
|
|
1269
1365
|
validateNavFolderRow(row, `${prefix}.rows[${rowIndex}]`, errors);
|
|
1270
1366
|
}
|
|
@@ -1536,11 +1632,14 @@ export {
|
|
|
1536
1632
|
KNOWN_FIELDS,
|
|
1537
1633
|
KNOWN_FILTER_CONJUNCTIONS,
|
|
1538
1634
|
KNOWN_FILTER_OPERATORS,
|
|
1635
|
+
KNOWN_NANGO_MODES,
|
|
1539
1636
|
KNOWN_SANDBOX_AGENT_HOSTS,
|
|
1540
1637
|
KNOWN_SANDBOX_RUN_LOCALITY,
|
|
1541
1638
|
KNOWN_SANDBOX_RUNTIMES,
|
|
1542
1639
|
KNOWN_SORT_DIRECTIONS,
|
|
1543
1640
|
KNOWN_WIDGET_KINDS,
|
|
1641
|
+
NANGO_PROVIDER_CONFIG_KEY_MAX,
|
|
1642
|
+
NANGO_PROVIDER_CONFIG_KEY_PATTERN,
|
|
1544
1643
|
DEFAULT_SANDBOX_ADAPTER,
|
|
1545
1644
|
SANDBOX_DEFAULT_TIMEOUT_MS,
|
|
1546
1645
|
SANDBOX_MAX_TIMEOUT_MS,
|
|
@@ -44,6 +44,7 @@
|
|
|
44
44
|
"templates/project.md",
|
|
45
45
|
"templates/self-eval.md",
|
|
46
46
|
"templates/seeded-configs/alignment-loop.config.json",
|
|
47
|
+
"templates/seeded-configs/project-management.config.json",
|
|
47
48
|
"helpers/README.md",
|
|
48
49
|
"helpers/propose-capability.mjs",
|
|
49
50
|
"helpers/promote-capability.mjs",
|
|
@@ -169,6 +170,7 @@
|
|
|
169
170
|
"templates/deployment-handoff.md",
|
|
170
171
|
"templates/supabase-setup-plan.md",
|
|
171
172
|
"templates/seeded-configs/alignment-loop.config.json",
|
|
173
|
+
"templates/seeded-configs/project-management.config.json",
|
|
172
174
|
"helpers",
|
|
173
175
|
"helpers/README.md",
|
|
174
176
|
"helpers/propose-capability.mjs",
|
|
@@ -0,0 +1,276 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "Project Management Workspace Template",
|
|
3
|
+
"description": "Opinionated project-management workspace template for API-backed task workflows. This seed is sanitized: it stores no provider secrets, no OAuth connection ids, and no user task data.",
|
|
4
|
+
"dataModel": {
|
|
5
|
+
"objects": [
|
|
6
|
+
{
|
|
7
|
+
"id": "api-registry",
|
|
8
|
+
"label": "API Registry",
|
|
9
|
+
"source": "API Registry",
|
|
10
|
+
"objectType": "api-registry",
|
|
11
|
+
"icon": "Code2",
|
|
12
|
+
"locked": true,
|
|
13
|
+
"columns": [
|
|
14
|
+
"integrationId",
|
|
15
|
+
"authRef",
|
|
16
|
+
"baseUrl",
|
|
17
|
+
"endpoint",
|
|
18
|
+
"method",
|
|
19
|
+
"status",
|
|
20
|
+
"lastTested",
|
|
21
|
+
"lastResponse",
|
|
22
|
+
"entityTypes",
|
|
23
|
+
"description",
|
|
24
|
+
"connectorKind",
|
|
25
|
+
"resolverTemplateId",
|
|
26
|
+
"schemaVersion",
|
|
27
|
+
"capabilities",
|
|
28
|
+
"executionLane",
|
|
29
|
+
"providerConfigKey",
|
|
30
|
+
"connectionIds",
|
|
31
|
+
"nangoMode",
|
|
32
|
+
"nangoEnvironment"
|
|
33
|
+
],
|
|
34
|
+
"records": [
|
|
35
|
+
{
|
|
36
|
+
"integrationId": "asana-active-tasks",
|
|
37
|
+
"authRef": "NANGO_SECRET_KEY",
|
|
38
|
+
"baseUrl": "http://127.0.0.1:3000",
|
|
39
|
+
"endpoint": "/api/workspace/integrations/nango/proxy",
|
|
40
|
+
"method": "POST",
|
|
41
|
+
"status": "template",
|
|
42
|
+
"lastTested": "",
|
|
43
|
+
"lastResponse": "",
|
|
44
|
+
"entityTypes": "tasks",
|
|
45
|
+
"description": "Template API Registry row for pulling active project tasks through a provider-auth proxy. Set providerConfigKey and connectionIds in the exported workspace after OAuth.",
|
|
46
|
+
"connectorKind": "nango",
|
|
47
|
+
"resolverTemplateId": "nango-proxy-v1",
|
|
48
|
+
"schemaVersion": "1",
|
|
49
|
+
"capabilities": "read:tasks",
|
|
50
|
+
"executionLane": "project-management",
|
|
51
|
+
"providerConfigKey": "asana",
|
|
52
|
+
"connectionIds": "",
|
|
53
|
+
"nangoMode": "cloud",
|
|
54
|
+
"nangoEnvironment": "dev"
|
|
55
|
+
}
|
|
56
|
+
],
|
|
57
|
+
"binding": {
|
|
58
|
+
"mode": "manual",
|
|
59
|
+
"source": "Data Model"
|
|
60
|
+
},
|
|
61
|
+
"fieldSettings": {
|
|
62
|
+
"hidden": [
|
|
63
|
+
"lastResponse"
|
|
64
|
+
]
|
|
65
|
+
}
|
|
66
|
+
},
|
|
67
|
+
{
|
|
68
|
+
"id": "project-task-source",
|
|
69
|
+
"label": "Project Task Source",
|
|
70
|
+
"source": "Project Task Source",
|
|
71
|
+
"objectType": "data-source",
|
|
72
|
+
"icon": "Globe",
|
|
73
|
+
"locked": true,
|
|
74
|
+
"columns": [
|
|
75
|
+
"Name",
|
|
76
|
+
"registryId",
|
|
77
|
+
"endpoint",
|
|
78
|
+
"authRef",
|
|
79
|
+
"baseUrl",
|
|
80
|
+
"method",
|
|
81
|
+
"status",
|
|
82
|
+
"lastTested",
|
|
83
|
+
"lastResponse",
|
|
84
|
+
"sourceStorage",
|
|
85
|
+
"sourceId",
|
|
86
|
+
"entityType",
|
|
87
|
+
"description"
|
|
88
|
+
],
|
|
89
|
+
"records": [
|
|
90
|
+
{
|
|
91
|
+
"Name": "Active project tasks",
|
|
92
|
+
"registryId": "asana-active-tasks",
|
|
93
|
+
"endpoint": "/api/workspace/integrations/nango/proxy",
|
|
94
|
+
"authRef": "NANGO_SECRET_KEY",
|
|
95
|
+
"baseUrl": "http://127.0.0.1:3000",
|
|
96
|
+
"method": "POST",
|
|
97
|
+
"status": "template",
|
|
98
|
+
"lastTested": "",
|
|
99
|
+
"lastResponse": "",
|
|
100
|
+
"sourceStorage": "workspace-source-records",
|
|
101
|
+
"sourceId": "project-active-tasks",
|
|
102
|
+
"entityType": "tasks",
|
|
103
|
+
"description": "Source binding for task deltas returned by the project-management workflow."
|
|
104
|
+
}
|
|
105
|
+
],
|
|
106
|
+
"binding": {
|
|
107
|
+
"mode": "manual",
|
|
108
|
+
"source": "Data Model"
|
|
109
|
+
},
|
|
110
|
+
"fieldSettings": {
|
|
111
|
+
"hidden": [
|
|
112
|
+
"lastResponse"
|
|
113
|
+
]
|
|
114
|
+
}
|
|
115
|
+
},
|
|
116
|
+
{
|
|
117
|
+
"id": "sandbox-environments",
|
|
118
|
+
"label": "Sandbox Environments",
|
|
119
|
+
"source": "Sandbox Environments",
|
|
120
|
+
"objectType": "sandbox-environment",
|
|
121
|
+
"icon": "Terminal",
|
|
122
|
+
"locked": true,
|
|
123
|
+
"columns": [
|
|
124
|
+
"Name",
|
|
125
|
+
"lifecycleStatus",
|
|
126
|
+
"version",
|
|
127
|
+
"runLocality",
|
|
128
|
+
"schedulerRegistryId",
|
|
129
|
+
"runtime",
|
|
130
|
+
"adapter",
|
|
131
|
+
"agentHost",
|
|
132
|
+
"localModel",
|
|
133
|
+
"localEndpoint",
|
|
134
|
+
"intelligenceAdapterMode",
|
|
135
|
+
"envRefs",
|
|
136
|
+
"networkAllow",
|
|
137
|
+
"allowList",
|
|
138
|
+
"instructions",
|
|
139
|
+
"command",
|
|
140
|
+
"timeoutMs",
|
|
141
|
+
"status",
|
|
142
|
+
"lastTested",
|
|
143
|
+
"lastRunId",
|
|
144
|
+
"lastSourceId",
|
|
145
|
+
"lastResponse",
|
|
146
|
+
"orchestrationConfig",
|
|
147
|
+
"description"
|
|
148
|
+
],
|
|
149
|
+
"records": [
|
|
150
|
+
{
|
|
151
|
+
"Name": "project-active-tasks-workflow",
|
|
152
|
+
"lifecycleStatus": "draft",
|
|
153
|
+
"version": "1",
|
|
154
|
+
"runLocality": "local",
|
|
155
|
+
"schedulerRegistryId": "",
|
|
156
|
+
"runtime": "node",
|
|
157
|
+
"adapter": "local-process",
|
|
158
|
+
"agentHost": "",
|
|
159
|
+
"localModel": "",
|
|
160
|
+
"localEndpoint": "",
|
|
161
|
+
"intelligenceAdapterMode": "",
|
|
162
|
+
"envRefs": "NANGO_SECRET_KEY",
|
|
163
|
+
"networkAllow": "true",
|
|
164
|
+
"allowList": "127.0.0.1,localhost,api.nango.dev,app.asana.com",
|
|
165
|
+
"instructions": "Template workflow for pulling active tasks from a project-management provider through API Registry. Fill projectGid, workspaceGid, providerConfigKey, and connectionIds in the exported workspace before running.",
|
|
166
|
+
"command": "",
|
|
167
|
+
"timeoutMs": "60000",
|
|
168
|
+
"status": "template",
|
|
169
|
+
"lastTested": "",
|
|
170
|
+
"lastRunId": "",
|
|
171
|
+
"lastSourceId": "",
|
|
172
|
+
"lastResponse": "",
|
|
173
|
+
"orchestrationConfig": "{\n \"version\": 1,\n \"provider\": \"growthub-native\",\n \"nodes\": [\n {\n \"id\": \"input\",\n \"type\": \"input\",\n \"label\": \"Project input\",\n \"config\": {\n \"inputMode\": \"manual\",\n \"samplePayload\": {\n \"projectGid\": \"PROJECT_GID_PLACEHOLDER\",\n \"workspaceGid\": \"WORKSPACE_GID_PLACEHOLDER\"\n }\n }\n },\n {\n \"id\": \"active-tasks-call\",\n \"type\": \"api-registry-call\",\n \"label\": \"Pull active project tasks\",\n \"config\": {\n \"registryId\": \"asana-active-tasks\",\n \"integrationId\": \"asana-active-tasks\",\n \"method\": \"POST\",\n \"baseUrl\": \"http://127.0.0.1:3000\",\n \"endpoint\": \"/api/workspace/integrations/nango/proxy\",\n \"authRef\": \"NANGO_SECRET_KEY\",\n \"bodyTemplate\": {\n \"providerConfigKey\": \"asana\",\n \"connectionId\": \"CONNECTION_ID_PLACEHOLDER\",\n \"method\": \"GET\",\n \"path\": \"/api/1.0/projects/{{input.projectGid}}/tasks\",\n \"params\": {\n \"completed_since\": \"now\",\n \"limit\": \"20\",\n \"opt_fields\": \"gid,name,completed,assignee.name,due_on,permalink_url,created_at,modified_at,memberships.section.name\"\n }\n },\n \"deltaTags\": [\n \"routing\",\n \"input\",\n \"output\"\n ]\n }\n },\n {\n \"id\": \"normalize-active-tasks\",\n \"type\": \"transform-filter\",\n \"label\": \"Normalize active tasks\",\n \"config\": {\n \"rootPath\": \"data\",\n \"filter\": {\n \"completed\": false\n },\n \"fieldMap\": {\n \"gid\": \"gid\",\n \"name\": \"name\",\n \"completed\": \"completed\",\n \"assignee\": \"assignee.name\",\n \"due_on\": \"due_on\",\n \"section\": \"memberships.0.section.name\",\n \"permalink_url\": \"permalink_url\",\n \"modified_at\": \"modified_at\"\n },\n \"deltaTags\": [\n \"evaluation\",\n \"output\"\n ]\n }\n },\n {\n \"id\": \"result\",\n \"type\": \"tool-result\",\n \"label\": \"Persist task response\",\n \"config\": {\n \"saveStatus\": true,\n \"saveResponse\": true,\n \"sourceId\": \"project-active-tasks\",\n \"deltaTags\": [\n \"output\"\n ]\n }\n }\n ],\n \"edges\": [\n {\n \"from\": \"input\",\n \"to\": \"active-tasks-call\",\n \"passes\": \"input\"\n },\n {\n \"from\": \"active-tasks-call\",\n \"to\": \"normalize-active-tasks\",\n \"passes\": \"response\"\n },\n {\n \"from\": \"normalize-active-tasks\",\n \"to\": \"result\",\n \"passes\": \"normalized-output\"\n }\n ]\n}",
|
|
174
|
+
"description": "Draft project-management workflow template. No secrets or provider data are stored in this row."
|
|
175
|
+
}
|
|
176
|
+
],
|
|
177
|
+
"binding": {
|
|
178
|
+
"mode": "manual",
|
|
179
|
+
"source": "Data Model"
|
|
180
|
+
},
|
|
181
|
+
"fieldSettings": {
|
|
182
|
+
"hidden": [
|
|
183
|
+
"lastResponse"
|
|
184
|
+
]
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
]
|
|
188
|
+
},
|
|
189
|
+
"dashboards": [
|
|
190
|
+
{
|
|
191
|
+
"id": "project-management-template",
|
|
192
|
+
"name": "Project Management",
|
|
193
|
+
"description": "Template dashboard for active project tasks. Run the workflow after configuring provider OAuth to hydrate real rows.",
|
|
194
|
+
"tabs": [
|
|
195
|
+
{
|
|
196
|
+
"id": "tab-project-tasks",
|
|
197
|
+
"label": "Active Tasks",
|
|
198
|
+
"widgets": [
|
|
199
|
+
{
|
|
200
|
+
"id": "project-active-tasks-view",
|
|
201
|
+
"kind": "view",
|
|
202
|
+
"title": "Active project tasks",
|
|
203
|
+
"position": {
|
|
204
|
+
"x": 0,
|
|
205
|
+
"y": 0,
|
|
206
|
+
"w": 9,
|
|
207
|
+
"h": 8
|
|
208
|
+
},
|
|
209
|
+
"config": {
|
|
210
|
+
"source": "Project Task Source",
|
|
211
|
+
"layout": "Table",
|
|
212
|
+
"columns": [
|
|
213
|
+
"gid",
|
|
214
|
+
"name",
|
|
215
|
+
"assignee",
|
|
216
|
+
"due_on",
|
|
217
|
+
"section",
|
|
218
|
+
"modified_at",
|
|
219
|
+
"permalink_url"
|
|
220
|
+
],
|
|
221
|
+
"rows": []
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
]
|
|
225
|
+
}
|
|
226
|
+
],
|
|
227
|
+
"activeTabId": "tab-project-tasks",
|
|
228
|
+
"version": "1"
|
|
229
|
+
}
|
|
230
|
+
],
|
|
231
|
+
"canvas": {
|
|
232
|
+
"id": "workspace-canvas",
|
|
233
|
+
"name": "Project Management",
|
|
234
|
+
"scope": "workspace",
|
|
235
|
+
"layout": {
|
|
236
|
+
"columns": 12,
|
|
237
|
+
"rowHeight": 64,
|
|
238
|
+
"gap": 16,
|
|
239
|
+
"responsive": true
|
|
240
|
+
},
|
|
241
|
+
"widgets": [
|
|
242
|
+
{
|
|
243
|
+
"id": "project-active-tasks-view",
|
|
244
|
+
"kind": "view",
|
|
245
|
+
"title": "Active project tasks",
|
|
246
|
+
"position": {
|
|
247
|
+
"x": 0,
|
|
248
|
+
"y": 0,
|
|
249
|
+
"w": 9,
|
|
250
|
+
"h": 8
|
|
251
|
+
},
|
|
252
|
+
"config": {
|
|
253
|
+
"source": "Project Task Source",
|
|
254
|
+
"layout": "Table",
|
|
255
|
+
"columns": [
|
|
256
|
+
"gid",
|
|
257
|
+
"name",
|
|
258
|
+
"assignee",
|
|
259
|
+
"due_on",
|
|
260
|
+
"section",
|
|
261
|
+
"modified_at",
|
|
262
|
+
"permalink_url"
|
|
263
|
+
],
|
|
264
|
+
"rows": []
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
]
|
|
268
|
+
},
|
|
269
|
+
"provenance": {
|
|
270
|
+
"mirrors": "growthub-custom-workspace-starter-v1",
|
|
271
|
+
"template": "project-management",
|
|
272
|
+
"templateKind": "workspace-template",
|
|
273
|
+
"privacy": "sanitized-no-secrets-no-provider-data",
|
|
274
|
+
"note": "Official Workspace 2 seed. Configure provider OAuth and project identifiers after export."
|
|
275
|
+
}
|
|
276
|
+
}
|