@growthub/cli 0.9.9 → 0.9.10
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/globals.css +710 -0
- package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/app/workspace-builder.jsx +1212 -67
- package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/lib/workspace-schema.js +182 -2
- package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/package-lock.json +10 -64
- package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/package.json +1 -0
- package/package.json +1 -1
|
@@ -40,7 +40,12 @@ const GRID_COLUMNS = 12;
|
|
|
40
40
|
const GRID_ROWS = 16;
|
|
41
41
|
const KNOWN_WIDGET_KINDS = ["chart", "view", "iframe", "rich-text"];
|
|
42
42
|
const KNOWN_FIELDS = ["dashboards", "widgetTypes", "canvas"];
|
|
43
|
-
const KNOWN_DATA_BINDING_MODES = ["manual", "json", "csv"];
|
|
43
|
+
const KNOWN_DATA_BINDING_MODES = ["manual", "json", "csv", "integration"];
|
|
44
|
+
const KNOWN_CHART_TYPES = ["bar-vertical", "bar-horizontal", "line", "pie", "sum", "gauge"];
|
|
45
|
+
const KNOWN_FILTER_OPERATORS = ["eq", "ne", "contains", "gt", "lt", "isEmpty", "isNotEmpty"];
|
|
46
|
+
const KNOWN_FILTER_CONJUNCTIONS = ["and", "or"];
|
|
47
|
+
const KNOWN_SORT_DIRECTIONS = ["asc", "desc"];
|
|
48
|
+
const KNOWN_AGGREGATIONS = ["sum", "avg", "count", "min", "max"];
|
|
44
49
|
const WORKSPACE_TEMPLATE_KIND = "growthub-workspace-template";
|
|
45
50
|
const WORKSPACE_TEMPLATE_VERSION = 1;
|
|
46
51
|
const WORKSPACE_TEMPLATE_SOURCE = "growthub-custom-workspace-starter-v1";
|
|
@@ -61,7 +66,12 @@ const WIDGET_SCHEMA_CONTRACTS = {
|
|
|
61
66
|
config: "kind-specific config object"
|
|
62
67
|
},
|
|
63
68
|
ChartWidgetConfig: {
|
|
64
|
-
values: "number[]",
|
|
69
|
+
values: "number[] (legacy preserved)",
|
|
70
|
+
chartType: `${KNOWN_CHART_TYPES.join(" | ")} optional, defaults to bar-vertical`,
|
|
71
|
+
xAxis: "ChartAxisConfig optional",
|
|
72
|
+
yAxis: "ChartAxisConfig optional",
|
|
73
|
+
style: "ChartStyleConfig optional",
|
|
74
|
+
filter: "FilterConfig optional",
|
|
65
75
|
binding: "StaticDataBinding optional"
|
|
66
76
|
},
|
|
67
77
|
ViewWidgetConfig: {
|
|
@@ -69,8 +79,42 @@ const WIDGET_SCHEMA_CONTRACTS = {
|
|
|
69
79
|
layout: "Table",
|
|
70
80
|
columns: "string[]",
|
|
71
81
|
rows: "record[]",
|
|
82
|
+
fieldSettings: "FieldSettingsConfig optional (hidden[], order[])",
|
|
83
|
+
sort: "SortClause[] optional ({ fieldId, direction })",
|
|
84
|
+
filter: "FilterConfig optional ({ op, clauses[] })",
|
|
72
85
|
binding: "StaticDataBinding optional"
|
|
73
86
|
},
|
|
87
|
+
ChartAxisConfig: {
|
|
88
|
+
field: "string optional",
|
|
89
|
+
sort: "string optional (asc | desc | position)",
|
|
90
|
+
aggregation: `${KNOWN_AGGREGATIONS.join(" | ")} optional`,
|
|
91
|
+
groupBy: "string optional",
|
|
92
|
+
omitZero: "boolean optional",
|
|
93
|
+
min: "string | number optional",
|
|
94
|
+
max: "string | number optional"
|
|
95
|
+
},
|
|
96
|
+
ChartStyleConfig: {
|
|
97
|
+
colors: "string optional (auto | manual swatch label)",
|
|
98
|
+
axisName: "string optional",
|
|
99
|
+
dataLabels: "boolean optional"
|
|
100
|
+
},
|
|
101
|
+
FieldSettingsConfig: {
|
|
102
|
+
hidden: "string[] of column names hidden from preview",
|
|
103
|
+
order: "string[] of column names defining custom order"
|
|
104
|
+
},
|
|
105
|
+
SortClause: {
|
|
106
|
+
fieldId: "non-empty string (column name)",
|
|
107
|
+
direction: KNOWN_SORT_DIRECTIONS.join(" | ")
|
|
108
|
+
},
|
|
109
|
+
FilterConfig: {
|
|
110
|
+
op: KNOWN_FILTER_CONJUNCTIONS.join(" | "),
|
|
111
|
+
clauses: "FilterClause[]"
|
|
112
|
+
},
|
|
113
|
+
FilterClause: {
|
|
114
|
+
fieldId: "non-empty string (column name)",
|
|
115
|
+
operator: KNOWN_FILTER_OPERATORS.join(" | "),
|
|
116
|
+
value: "string | number | boolean optional"
|
|
117
|
+
},
|
|
74
118
|
IframeWidgetConfig: {
|
|
75
119
|
url: "string"
|
|
76
120
|
},
|
|
@@ -333,6 +377,127 @@ function validateStaticDataBinding(binding, path, errors) {
|
|
|
333
377
|
if (binding.csv !== undefined && typeof binding.csv !== "string") {
|
|
334
378
|
errors.push(`${path}.csv must be a string`);
|
|
335
379
|
}
|
|
380
|
+
if (binding.integrationId !== undefined && typeof binding.integrationId !== "string") {
|
|
381
|
+
errors.push(`${path}.integrationId must be a string`);
|
|
382
|
+
}
|
|
383
|
+
if (binding.lane !== undefined && typeof binding.lane !== "string") {
|
|
384
|
+
errors.push(`${path}.lane must be a string`);
|
|
385
|
+
}
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
function validateFieldSettings(fieldSettings, path, errors) {
|
|
389
|
+
if (fieldSettings === undefined) return;
|
|
390
|
+
if (!isPlainObject(fieldSettings)) {
|
|
391
|
+
errors.push(`${path} must be a plain object`);
|
|
392
|
+
return;
|
|
393
|
+
}
|
|
394
|
+
if (fieldSettings.hidden !== undefined) validateStringArray(fieldSettings.hidden, `${path}.hidden`, errors);
|
|
395
|
+
if (fieldSettings.order !== undefined) validateStringArray(fieldSettings.order, `${path}.order`, errors);
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
function validateSortClauses(sort, path, errors) {
|
|
399
|
+
if (sort === undefined) return;
|
|
400
|
+
if (!Array.isArray(sort)) {
|
|
401
|
+
errors.push(`${path} must be an array`);
|
|
402
|
+
return;
|
|
403
|
+
}
|
|
404
|
+
sort.forEach((clause, index) => {
|
|
405
|
+
const prefix = `${path}[${index}]`;
|
|
406
|
+
if (!isPlainObject(clause)) {
|
|
407
|
+
errors.push(`${prefix} must be a plain object`);
|
|
408
|
+
return;
|
|
409
|
+
}
|
|
410
|
+
if (typeof clause.fieldId !== "string" || !clause.fieldId) {
|
|
411
|
+
errors.push(`${prefix}.fieldId must be a non-empty string`);
|
|
412
|
+
}
|
|
413
|
+
if (clause.direction !== undefined && !KNOWN_SORT_DIRECTIONS.includes(clause.direction)) {
|
|
414
|
+
errors.push(`${prefix}.direction must be one of ${KNOWN_SORT_DIRECTIONS.join(", ")}`);
|
|
415
|
+
}
|
|
416
|
+
});
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
function validateFilterClauses(filter, path, errors) {
|
|
420
|
+
if (filter === undefined) return;
|
|
421
|
+
if (!isPlainObject(filter)) {
|
|
422
|
+
errors.push(`${path} must be a plain object`);
|
|
423
|
+
return;
|
|
424
|
+
}
|
|
425
|
+
if (filter.op !== undefined && !KNOWN_FILTER_CONJUNCTIONS.includes(filter.op)) {
|
|
426
|
+
errors.push(`${path}.op must be one of ${KNOWN_FILTER_CONJUNCTIONS.join(", ")}`);
|
|
427
|
+
}
|
|
428
|
+
if (filter.clauses !== undefined) {
|
|
429
|
+
if (!Array.isArray(filter.clauses)) {
|
|
430
|
+
errors.push(`${path}.clauses must be an array`);
|
|
431
|
+
} else {
|
|
432
|
+
filter.clauses.forEach((clause, index) => {
|
|
433
|
+
const prefix = `${path}.clauses[${index}]`;
|
|
434
|
+
if (!isPlainObject(clause)) {
|
|
435
|
+
errors.push(`${prefix} must be a plain object`);
|
|
436
|
+
return;
|
|
437
|
+
}
|
|
438
|
+
if (typeof clause.fieldId !== "string" || !clause.fieldId) {
|
|
439
|
+
errors.push(`${prefix}.fieldId must be a non-empty string`);
|
|
440
|
+
}
|
|
441
|
+
if (clause.operator !== undefined && !KNOWN_FILTER_OPERATORS.includes(clause.operator)) {
|
|
442
|
+
errors.push(`${prefix}.operator must be one of ${KNOWN_FILTER_OPERATORS.join(", ")}`);
|
|
443
|
+
}
|
|
444
|
+
if (
|
|
445
|
+
clause.value !== undefined &&
|
|
446
|
+
typeof clause.value !== "string" &&
|
|
447
|
+
typeof clause.value !== "number" &&
|
|
448
|
+
typeof clause.value !== "boolean"
|
|
449
|
+
) {
|
|
450
|
+
errors.push(`${prefix}.value must be a string, number, or boolean`);
|
|
451
|
+
}
|
|
452
|
+
});
|
|
453
|
+
}
|
|
454
|
+
}
|
|
455
|
+
}
|
|
456
|
+
|
|
457
|
+
function validateChartAxis(axis, path, errors) {
|
|
458
|
+
if (axis === undefined) return;
|
|
459
|
+
if (!isPlainObject(axis)) {
|
|
460
|
+
errors.push(`${path} must be a plain object`);
|
|
461
|
+
return;
|
|
462
|
+
}
|
|
463
|
+
if (axis.field !== undefined && typeof axis.field !== "string") {
|
|
464
|
+
errors.push(`${path}.field must be a string`);
|
|
465
|
+
}
|
|
466
|
+
if (axis.sort !== undefined && typeof axis.sort !== "string") {
|
|
467
|
+
errors.push(`${path}.sort must be a string`);
|
|
468
|
+
}
|
|
469
|
+
if (axis.aggregation !== undefined && !KNOWN_AGGREGATIONS.includes(axis.aggregation)) {
|
|
470
|
+
errors.push(`${path}.aggregation must be one of ${KNOWN_AGGREGATIONS.join(", ")}`);
|
|
471
|
+
}
|
|
472
|
+
if (axis.groupBy !== undefined && typeof axis.groupBy !== "string") {
|
|
473
|
+
errors.push(`${path}.groupBy must be a string`);
|
|
474
|
+
}
|
|
475
|
+
if (axis.omitZero !== undefined && typeof axis.omitZero !== "boolean") {
|
|
476
|
+
errors.push(`${path}.omitZero must be a boolean`);
|
|
477
|
+
}
|
|
478
|
+
if (axis.min !== undefined && typeof axis.min !== "string" && typeof axis.min !== "number") {
|
|
479
|
+
errors.push(`${path}.min must be a string or number`);
|
|
480
|
+
}
|
|
481
|
+
if (axis.max !== undefined && typeof axis.max !== "string" && typeof axis.max !== "number") {
|
|
482
|
+
errors.push(`${path}.max must be a string or number`);
|
|
483
|
+
}
|
|
484
|
+
}
|
|
485
|
+
|
|
486
|
+
function validateChartStyle(style, path, errors) {
|
|
487
|
+
if (style === undefined) return;
|
|
488
|
+
if (!isPlainObject(style)) {
|
|
489
|
+
errors.push(`${path} must be a plain object`);
|
|
490
|
+
return;
|
|
491
|
+
}
|
|
492
|
+
if (style.colors !== undefined && typeof style.colors !== "string") {
|
|
493
|
+
errors.push(`${path}.colors must be a string`);
|
|
494
|
+
}
|
|
495
|
+
if (style.axisName !== undefined && typeof style.axisName !== "string") {
|
|
496
|
+
errors.push(`${path}.axisName must be a string`);
|
|
497
|
+
}
|
|
498
|
+
if (style.dataLabels !== undefined && typeof style.dataLabels !== "boolean") {
|
|
499
|
+
errors.push(`${path}.dataLabels must be a boolean`);
|
|
500
|
+
}
|
|
336
501
|
}
|
|
337
502
|
|
|
338
503
|
function validateWidgetConfig(kind, config, path, errors) {
|
|
@@ -353,6 +518,13 @@ function validateWidgetConfig(kind, config, path, errors) {
|
|
|
353
518
|
});
|
|
354
519
|
}
|
|
355
520
|
}
|
|
521
|
+
if (config.chartType !== undefined && !KNOWN_CHART_TYPES.includes(config.chartType)) {
|
|
522
|
+
errors.push(`${path}.chartType must be one of ${KNOWN_CHART_TYPES.join(", ")}`);
|
|
523
|
+
}
|
|
524
|
+
validateChartAxis(config.xAxis, `${path}.xAxis`, errors);
|
|
525
|
+
validateChartAxis(config.yAxis, `${path}.yAxis`, errors);
|
|
526
|
+
validateChartStyle(config.style, `${path}.style`, errors);
|
|
527
|
+
validateFilterClauses(config.filter, `${path}.filter`, errors);
|
|
356
528
|
validateStaticDataBinding(config.binding, `${path}.binding`, errors);
|
|
357
529
|
}
|
|
358
530
|
if (kind === "view") {
|
|
@@ -360,6 +532,9 @@ function validateWidgetConfig(kind, config, path, errors) {
|
|
|
360
532
|
if (config.layout !== undefined && config.layout !== "Table") errors.push(`${path}.layout must be Table`);
|
|
361
533
|
if (config.columns !== undefined) validateStringArray(config.columns, `${path}.columns`, errors);
|
|
362
534
|
if (config.rows !== undefined && !Array.isArray(config.rows)) errors.push(`${path}.rows must be an array`);
|
|
535
|
+
validateFieldSettings(config.fieldSettings, `${path}.fieldSettings`, errors);
|
|
536
|
+
validateSortClauses(config.sort, `${path}.sort`, errors);
|
|
537
|
+
validateFilterClauses(config.filter, `${path}.filter`, errors);
|
|
363
538
|
validateStaticDataBinding(config.binding, `${path}.binding`, errors);
|
|
364
539
|
}
|
|
365
540
|
if (kind === "iframe" && config.url !== undefined && typeof config.url !== "string") {
|
|
@@ -787,8 +962,13 @@ export {
|
|
|
787
962
|
DASHBOARD_TEMPLATES,
|
|
788
963
|
GRID_COLUMNS,
|
|
789
964
|
GRID_ROWS,
|
|
965
|
+
KNOWN_AGGREGATIONS,
|
|
966
|
+
KNOWN_CHART_TYPES,
|
|
790
967
|
KNOWN_DATA_BINDING_MODES,
|
|
791
968
|
KNOWN_FIELDS,
|
|
969
|
+
KNOWN_FILTER_CONJUNCTIONS,
|
|
970
|
+
KNOWN_FILTER_OPERATORS,
|
|
971
|
+
KNOWN_SORT_DIRECTIONS,
|
|
792
972
|
KNOWN_WIDGET_KINDS,
|
|
793
973
|
SAMPLE_DATA_BINDINGS,
|
|
794
974
|
SAMPLE_VIEW_ROWS,
|
package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/package-lock.json
CHANGED
|
@@ -8,15 +8,10 @@
|
|
|
8
8
|
"name": "growthub-workspace-app",
|
|
9
9
|
"version": "1.0.0",
|
|
10
10
|
"dependencies": {
|
|
11
|
+
"lucide-react": "^0.468.0",
|
|
11
12
|
"next": "16.2.4",
|
|
12
13
|
"react": "19.2.4",
|
|
13
14
|
"react-dom": "19.2.4"
|
|
14
|
-
},
|
|
15
|
-
"devDependencies": {
|
|
16
|
-
"@types/node": "^20",
|
|
17
|
-
"@types/react": "^19",
|
|
18
|
-
"@types/react-dom": "^19",
|
|
19
|
-
"typescript": "^5"
|
|
20
15
|
}
|
|
21
16
|
},
|
|
22
17
|
"node_modules/@emnapi/runtime": {
|
|
@@ -638,36 +633,6 @@
|
|
|
638
633
|
"tslib": "^2.8.0"
|
|
639
634
|
}
|
|
640
635
|
},
|
|
641
|
-
"node_modules/@types/node": {
|
|
642
|
-
"version": "20.19.39",
|
|
643
|
-
"resolved": "https://registry.npmjs.org/@types/node/-/node-20.19.39.tgz",
|
|
644
|
-
"integrity": "sha512-orrrD74MBUyK8jOAD/r0+lfa1I2MO6I+vAkmAWzMYbCcgrN4lCrmK52gRFQq/JRxfYPfonkr4b0jcY7Olqdqbw==",
|
|
645
|
-
"dev": true,
|
|
646
|
-
"license": "MIT",
|
|
647
|
-
"dependencies": {
|
|
648
|
-
"undici-types": "~6.21.0"
|
|
649
|
-
}
|
|
650
|
-
},
|
|
651
|
-
"node_modules/@types/react": {
|
|
652
|
-
"version": "19.2.14",
|
|
653
|
-
"resolved": "https://registry.npmjs.org/@types/react/-/react-19.2.14.tgz",
|
|
654
|
-
"integrity": "sha512-ilcTH/UniCkMdtexkoCN0bI7pMcJDvmQFPvuPvmEaYA/NSfFTAgdUSLAoVjaRJm7+6PvcM+q1zYOwS4wTYMF9w==",
|
|
655
|
-
"dev": true,
|
|
656
|
-
"license": "MIT",
|
|
657
|
-
"dependencies": {
|
|
658
|
-
"csstype": "^3.2.2"
|
|
659
|
-
}
|
|
660
|
-
},
|
|
661
|
-
"node_modules/@types/react-dom": {
|
|
662
|
-
"version": "19.2.3",
|
|
663
|
-
"resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-19.2.3.tgz",
|
|
664
|
-
"integrity": "sha512-jp2L/eY6fn+KgVVQAOqYItbF0VY/YApe5Mz2F0aykSO8gx31bYCZyvSeYxCHKvzHG5eZjc+zyaS5BrBWya2+kQ==",
|
|
665
|
-
"dev": true,
|
|
666
|
-
"license": "MIT",
|
|
667
|
-
"peerDependencies": {
|
|
668
|
-
"@types/react": "^19.2.0"
|
|
669
|
-
}
|
|
670
|
-
},
|
|
671
636
|
"node_modules/baseline-browser-mapping": {
|
|
672
637
|
"version": "2.10.21",
|
|
673
638
|
"resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.10.21.tgz",
|
|
@@ -706,13 +671,6 @@
|
|
|
706
671
|
"integrity": "sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==",
|
|
707
672
|
"license": "MIT"
|
|
708
673
|
},
|
|
709
|
-
"node_modules/csstype": {
|
|
710
|
-
"version": "3.2.3",
|
|
711
|
-
"resolved": "https://registry.npmjs.org/csstype/-/csstype-3.2.3.tgz",
|
|
712
|
-
"integrity": "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==",
|
|
713
|
-
"dev": true,
|
|
714
|
-
"license": "MIT"
|
|
715
|
-
},
|
|
716
674
|
"node_modules/detect-libc": {
|
|
717
675
|
"version": "2.1.2",
|
|
718
676
|
"resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz",
|
|
@@ -723,6 +681,15 @@
|
|
|
723
681
|
"node": ">=8"
|
|
724
682
|
}
|
|
725
683
|
},
|
|
684
|
+
"node_modules/lucide-react": {
|
|
685
|
+
"version": "0.468.0",
|
|
686
|
+
"resolved": "https://registry.npmjs.org/lucide-react/-/lucide-react-0.468.0.tgz",
|
|
687
|
+
"integrity": "sha512-6koYRhnM2N0GGZIdXzSeiNwguv1gt/FAjZOiPl76roBi3xKEXa4WmfpxgQwTTL4KipXjefrnf3oV4IsYhi4JFA==",
|
|
688
|
+
"license": "ISC",
|
|
689
|
+
"peerDependencies": {
|
|
690
|
+
"react": "^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0-rc"
|
|
691
|
+
}
|
|
692
|
+
},
|
|
726
693
|
"node_modules/nanoid": {
|
|
727
694
|
"version": "3.3.11",
|
|
728
695
|
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz",
|
|
@@ -950,27 +917,6 @@
|
|
|
950
917
|
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz",
|
|
951
918
|
"integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==",
|
|
952
919
|
"license": "0BSD"
|
|
953
|
-
},
|
|
954
|
-
"node_modules/typescript": {
|
|
955
|
-
"version": "5.9.3",
|
|
956
|
-
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz",
|
|
957
|
-
"integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==",
|
|
958
|
-
"dev": true,
|
|
959
|
-
"license": "Apache-2.0",
|
|
960
|
-
"bin": {
|
|
961
|
-
"tsc": "bin/tsc",
|
|
962
|
-
"tsserver": "bin/tsserver"
|
|
963
|
-
},
|
|
964
|
-
"engines": {
|
|
965
|
-
"node": ">=14.17"
|
|
966
|
-
}
|
|
967
|
-
},
|
|
968
|
-
"node_modules/undici-types": {
|
|
969
|
-
"version": "6.21.0",
|
|
970
|
-
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz",
|
|
971
|
-
"integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==",
|
|
972
|
-
"dev": true,
|
|
973
|
-
"license": "MIT"
|
|
974
920
|
}
|
|
975
921
|
}
|
|
976
922
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@growthub/cli",
|
|
3
|
-
"version": "0.9.
|
|
3
|
+
"version": "0.9.10",
|
|
4
4
|
"description": "Growthub Local is a control plane for forked worker kits. The CLI is the executor, the hosted app is the identity authority, the worker kit is the unit of portable agent infrastructure, and the fork is the operator's personal branch of that infrastructure — policy-governed, trace-backed, and self-healing.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|