@kb-labs/shared-command-kit 1.0.0
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/LICENSE +22 -0
- package/README.md +1030 -0
- package/dist/analytics/index.d.ts +111 -0
- package/dist/analytics/index.js +56 -0
- package/dist/analytics/index.js.map +1 -0
- package/dist/errors/index.d.ts +227 -0
- package/dist/errors/index.js +276 -0
- package/dist/errors/index.js.map +1 -0
- package/dist/flags/index.d.ts +196 -0
- package/dist/flags/index.js +288 -0
- package/dist/flags/index.js.map +1 -0
- package/dist/helpers/index.d.ts +650 -0
- package/dist/helpers/index.js +274 -0
- package/dist/helpers/index.js.map +1 -0
- package/dist/index.d.ts +1696 -0
- package/dist/index.js +1543 -0
- package/dist/index.js.map +1 -0
- package/dist/studio/index.js +178 -0
- package/dist/studio/index.js.map +1 -0
- package/package.json +76 -0
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
// src/studio/index.ts
|
|
2
|
+
function toDataSource(shorthand) {
|
|
3
|
+
if (!shorthand) {
|
|
4
|
+
return { type: "static" };
|
|
5
|
+
}
|
|
6
|
+
if ("rest" in shorthand) {
|
|
7
|
+
return { type: "rest", routeId: shorthand.rest, method: shorthand.method };
|
|
8
|
+
}
|
|
9
|
+
if ("mock" in shorthand) {
|
|
10
|
+
return { type: "mock", fixtureId: shorthand.mock };
|
|
11
|
+
}
|
|
12
|
+
return { type: "static", value: shorthand.static };
|
|
13
|
+
}
|
|
14
|
+
function collectWidgets(nodes) {
|
|
15
|
+
const widgets = [];
|
|
16
|
+
const rootIds = [];
|
|
17
|
+
for (const node of nodes) {
|
|
18
|
+
if (typeof node === "string") {
|
|
19
|
+
rootIds.push(node);
|
|
20
|
+
continue;
|
|
21
|
+
}
|
|
22
|
+
rootIds.push(node.id);
|
|
23
|
+
if (node.kind === "tabs") {
|
|
24
|
+
const tabsNode = node;
|
|
25
|
+
const allChildWidgets = [];
|
|
26
|
+
const tabChildIds = {};
|
|
27
|
+
for (const tab of tabsNode.tabs) {
|
|
28
|
+
const { widgets: tabWidgets, rootIds: tabRootIds } = collectWidgets(tab.children);
|
|
29
|
+
allChildWidgets.push(...tabWidgets);
|
|
30
|
+
tabChildIds[tab.id] = tabRootIds;
|
|
31
|
+
}
|
|
32
|
+
widgets.push(...allChildWidgets);
|
|
33
|
+
widgets.push({
|
|
34
|
+
id: tabsNode.id,
|
|
35
|
+
kind: "tabs",
|
|
36
|
+
title: tabsNode.title,
|
|
37
|
+
description: tabsNode.description,
|
|
38
|
+
data: { source: toDataSource(tabsNode.source) },
|
|
39
|
+
options: {
|
|
40
|
+
...tabsNode.options,
|
|
41
|
+
tabs: tabsNode.tabs.map((t) => ({ id: t.id, label: t.label, icon: t.icon })),
|
|
42
|
+
tabChildren: tabChildIds
|
|
43
|
+
},
|
|
44
|
+
children: Object.values(tabChildIds).flat(),
|
|
45
|
+
layoutHint: tabsNode.layout,
|
|
46
|
+
actions: tabsNode.actions,
|
|
47
|
+
events: tabsNode.events,
|
|
48
|
+
visibility: tabsNode.visibility,
|
|
49
|
+
pollingMs: tabsNode.pollingMs,
|
|
50
|
+
order: tabsNode.order
|
|
51
|
+
});
|
|
52
|
+
} else if ("children" in node && Array.isArray(node.children)) {
|
|
53
|
+
const compositeNode = node;
|
|
54
|
+
const { widgets: childWidgets, rootIds: childIds } = collectWidgets(compositeNode.children);
|
|
55
|
+
widgets.push(...childWidgets);
|
|
56
|
+
widgets.push({
|
|
57
|
+
id: compositeNode.id,
|
|
58
|
+
kind: compositeNode.kind,
|
|
59
|
+
title: compositeNode.title,
|
|
60
|
+
description: compositeNode.description,
|
|
61
|
+
data: { source: toDataSource(compositeNode.source) },
|
|
62
|
+
options: compositeNode.options,
|
|
63
|
+
children: childIds,
|
|
64
|
+
layoutHint: compositeNode.layout,
|
|
65
|
+
actions: compositeNode.actions,
|
|
66
|
+
events: compositeNode.events,
|
|
67
|
+
visibility: compositeNode.visibility,
|
|
68
|
+
pollingMs: compositeNode.pollingMs,
|
|
69
|
+
order: compositeNode.order
|
|
70
|
+
});
|
|
71
|
+
} else {
|
|
72
|
+
const leafNode = node;
|
|
73
|
+
widgets.push({
|
|
74
|
+
id: leafNode.id,
|
|
75
|
+
kind: leafNode.kind,
|
|
76
|
+
title: leafNode.title,
|
|
77
|
+
description: leafNode.description,
|
|
78
|
+
data: { source: toDataSource(leafNode.source) },
|
|
79
|
+
options: leafNode.options,
|
|
80
|
+
layoutHint: leafNode.layout,
|
|
81
|
+
actions: leafNode.actions,
|
|
82
|
+
events: leafNode.events,
|
|
83
|
+
visibility: leafNode.visibility,
|
|
84
|
+
pollingMs: leafNode.pollingMs,
|
|
85
|
+
order: leafNode.order
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
return { widgets, rootIds };
|
|
90
|
+
}
|
|
91
|
+
function definePage(config) {
|
|
92
|
+
const { widgets, rootIds } = collectWidgets(config.children);
|
|
93
|
+
return {
|
|
94
|
+
layout: {
|
|
95
|
+
id: config.id,
|
|
96
|
+
kind: config.layout ?? "grid",
|
|
97
|
+
title: config.title,
|
|
98
|
+
description: config.description,
|
|
99
|
+
icon: config.icon,
|
|
100
|
+
widgets: rootIds,
|
|
101
|
+
actions: config.actions,
|
|
102
|
+
visibility: config.visibility,
|
|
103
|
+
order: config.order
|
|
104
|
+
},
|
|
105
|
+
widgets
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
function defineMenu(config) {
|
|
109
|
+
return config;
|
|
110
|
+
}
|
|
111
|
+
function defineStudio(config) {
|
|
112
|
+
const allWidgets = [];
|
|
113
|
+
const layouts = [];
|
|
114
|
+
const menus = [];
|
|
115
|
+
for (const page of config.pages ?? []) {
|
|
116
|
+
const result = definePage(page);
|
|
117
|
+
layouts.push(result.layout);
|
|
118
|
+
allWidgets.push(...result.widgets);
|
|
119
|
+
}
|
|
120
|
+
if (config.widgets?.length) {
|
|
121
|
+
const { widgets } = collectWidgets(config.widgets);
|
|
122
|
+
allWidgets.push(...widgets);
|
|
123
|
+
}
|
|
124
|
+
for (const menu2 of config.menus ?? []) {
|
|
125
|
+
menus.push(defineMenu(menu2));
|
|
126
|
+
}
|
|
127
|
+
return { widgets: allWidgets, layouts, menus };
|
|
128
|
+
}
|
|
129
|
+
function createWidgetFactory(kind) {
|
|
130
|
+
return (config) => ({
|
|
131
|
+
...config,
|
|
132
|
+
kind
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
var metric = createWidgetFactory("metric");
|
|
136
|
+
var metricGroup = createWidgetFactory("metric-group");
|
|
137
|
+
var table = createWidgetFactory("table");
|
|
138
|
+
var card = createWidgetFactory("card");
|
|
139
|
+
var cardlist = createWidgetFactory("cardlist");
|
|
140
|
+
var chartLine = createWidgetFactory("chart-line");
|
|
141
|
+
var chartBar = createWidgetFactory("chart-bar");
|
|
142
|
+
var chartPie = createWidgetFactory("chart-pie");
|
|
143
|
+
var chartArea = createWidgetFactory("chart-area");
|
|
144
|
+
var timeline = createWidgetFactory("timeline");
|
|
145
|
+
var tree = createWidgetFactory("tree");
|
|
146
|
+
var json = createWidgetFactory("json");
|
|
147
|
+
var diff = createWidgetFactory("diff");
|
|
148
|
+
var logs = createWidgetFactory("logs");
|
|
149
|
+
var form = createWidgetFactory("form");
|
|
150
|
+
var input = createWidgetFactory("input");
|
|
151
|
+
var select = createWidgetFactory("select");
|
|
152
|
+
var checkboxGroup = createWidgetFactory("checkbox-group");
|
|
153
|
+
var switchWidget = createWidgetFactory("switch");
|
|
154
|
+
var datePicker = createWidgetFactory("date-picker");
|
|
155
|
+
var breadcrumb = createWidgetFactory("breadcrumb");
|
|
156
|
+
var stepper = createWidgetFactory("stepper");
|
|
157
|
+
var menu = createWidgetFactory("menu");
|
|
158
|
+
var alert = createWidgetFactory("alert");
|
|
159
|
+
var confirm = createWidgetFactory("confirm");
|
|
160
|
+
function section(config) {
|
|
161
|
+
return { ...config, kind: "section" };
|
|
162
|
+
}
|
|
163
|
+
function grid(config) {
|
|
164
|
+
return { ...config, kind: "grid" };
|
|
165
|
+
}
|
|
166
|
+
function stack(config) {
|
|
167
|
+
return { ...config, kind: "stack" };
|
|
168
|
+
}
|
|
169
|
+
function tabs(config) {
|
|
170
|
+
return { ...config, kind: "tabs" };
|
|
171
|
+
}
|
|
172
|
+
function modal(config) {
|
|
173
|
+
return { ...config, kind: "modal" };
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
export { alert, breadcrumb, card, cardlist, chartArea, chartBar, chartLine, chartPie, checkboxGroup, confirm, datePicker, defineMenu, definePage, defineStudio, diff, form, grid, input, json, logs, menu, metric, metricGroup, modal, section, select, stack, stepper, switchWidget, table, tabs, timeline, tree };
|
|
177
|
+
//# sourceMappingURL=index.js.map
|
|
178
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/studio/index.ts"],"names":["menu"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * @module @kb-labs/shared-command-kit/studio\n * SDK helpers for defining Studio widgets, pages, and layouts.\n *\n * @example\n * ```typescript\n * import { defineStudio, definePage, section, metric, table } from '@kb-labs/shared-command-kit/studio';\n *\n * export const studioConfig = defineStudio({\n * pages: [\n * definePage({\n * id: 'release.dashboard',\n * title: 'Release Dashboard',\n * children: [\n * section({\n * id: 'overview',\n * title: 'Overview',\n * children: [\n * metric({ id: 'total', source: { rest: 'release/metrics' } }),\n * table({ id: 'plans', source: { rest: 'release/plans' }, columns: [...] }),\n * ],\n * }),\n * ],\n * }),\n * ],\n * menus: [\n * { id: 'release', label: 'Release', icon: 'rocket', target: 'release.dashboard' },\n * ],\n * });\n * ```\n */\n\nimport type {\n StudioWidgetDecl,\n StudioLayoutDecl,\n StudioMenuDecl,\n StudioConfig,\n StudioWidgetKind,\n CompositeWidgetKind,\n DataSource,\n WidgetAction,\n WidgetEventConfig,\n LayoutHint,\n VisibilityRule,\n WidgetOptionsMap,\n} from '@kb-labs/studio-contracts';\n\n// =============================================================================\n// Data Source Shorthand\n// =============================================================================\n\n/**\n * Shorthand for data source definition.\n * Allows concise syntax in widget definitions.\n */\nexport type DataSourceShorthand =\n | { rest: string; method?: 'GET' | 'POST' }\n | { mock: string }\n | { static: unknown }\n | undefined;\n\n/**\n * Convert shorthand to canonical DataSource.\n */\nfunction toDataSource(shorthand: DataSourceShorthand): DataSource {\n if (!shorthand) {\n return { type: 'static' };\n }\n if ('rest' in shorthand) {\n return { type: 'rest', routeId: shorthand.rest, method: shorthand.method };\n }\n if ('mock' in shorthand) {\n return { type: 'mock', fixtureId: shorthand.mock };\n }\n return { type: 'static', value: shorthand.static };\n}\n\n// =============================================================================\n// Widget Node Types\n// =============================================================================\n\n/**\n * Base widget config (shared by all widgets).\n */\ninterface BaseWidgetConfig {\n id: string;\n title?: string;\n description?: string;\n source?: DataSourceShorthand;\n layout?: LayoutHint;\n actions?: WidgetAction[];\n events?: WidgetEventConfig;\n visibility?: VisibilityRule;\n pollingMs?: number;\n order?: number;\n}\n\n/**\n * Leaf widget config (no children).\n */\nexport interface LeafWidgetConfig<K extends Exclude<StudioWidgetKind, CompositeWidgetKind>>\n extends BaseWidgetConfig {\n kind: K;\n options?: WidgetOptionsMap[K];\n}\n\n/**\n * Widget node in tree (leaf, composite, or ID reference).\n */\nexport type WidgetNode =\n | LeafWidgetConfig<Exclude<StudioWidgetKind, CompositeWidgetKind>>\n | SectionConfig\n | GridConfig\n | StackConfig\n | TabsConfig\n | ModalConfig\n | string; // ID reference\n\n// =============================================================================\n// Composite Widget Configs\n// =============================================================================\n\n/**\n * Section widget config.\n */\nexport interface SectionConfig extends BaseWidgetConfig {\n kind: 'section';\n options?: WidgetOptionsMap['section'];\n children: WidgetNode[];\n}\n\n/**\n * Grid widget config.\n */\nexport interface GridConfig extends BaseWidgetConfig {\n kind: 'grid';\n options?: WidgetOptionsMap['grid'];\n children: WidgetNode[];\n}\n\n/**\n * Stack widget config.\n */\nexport interface StackConfig extends BaseWidgetConfig {\n kind: 'stack';\n options?: WidgetOptionsMap['stack'];\n children: WidgetNode[];\n}\n\n/**\n * Tab definition for tabs widget.\n */\nexport interface TabConfig {\n id: string;\n label: string;\n icon?: string;\n children: WidgetNode[];\n}\n\n/**\n * Tabs widget config.\n */\nexport interface TabsConfig extends BaseWidgetConfig {\n kind: 'tabs';\n options?: Omit<WidgetOptionsMap['tabs'], 'tabs' | 'tabChildren'>;\n tabs: TabConfig[];\n}\n\n/**\n * Modal widget config.\n */\nexport interface ModalConfig extends BaseWidgetConfig {\n kind: 'modal';\n options?: WidgetOptionsMap['modal'];\n children: WidgetNode[];\n}\n\n// =============================================================================\n// Recursive Widget Collection\n// =============================================================================\n\ninterface CollectResult {\n widgets: StudioWidgetDecl[];\n rootIds: string[];\n}\n\n/**\n * Recursively collect all widgets from a tree of nodes.\n * Returns flat list of widgets and list of root IDs.\n */\nfunction collectWidgets(nodes: WidgetNode[]): CollectResult {\n const widgets: StudioWidgetDecl[] = [];\n const rootIds: string[] = [];\n\n for (const node of nodes) {\n // ID reference - just add to rootIds\n if (typeof node === 'string') {\n rootIds.push(node);\n continue;\n }\n\n rootIds.push(node.id);\n\n // Check for composite widgets\n if (node.kind === 'tabs') {\n // Tabs - special case with tabChildren mapping\n const tabsNode = node as TabsConfig;\n const allChildWidgets: StudioWidgetDecl[] = [];\n const tabChildIds: Record<string, string[]> = {};\n\n for (const tab of tabsNode.tabs) {\n const { widgets: tabWidgets, rootIds: tabRootIds } = collectWidgets(tab.children);\n allChildWidgets.push(...tabWidgets);\n tabChildIds[tab.id] = tabRootIds;\n }\n\n widgets.push(...allChildWidgets);\n widgets.push({\n id: tabsNode.id,\n kind: 'tabs',\n title: tabsNode.title,\n description: tabsNode.description,\n data: { source: toDataSource(tabsNode.source) },\n options: {\n ...tabsNode.options,\n tabs: tabsNode.tabs.map((t) => ({ id: t.id, label: t.label, icon: t.icon })),\n tabChildren: tabChildIds,\n },\n children: Object.values(tabChildIds).flat(),\n layoutHint: tabsNode.layout,\n actions: tabsNode.actions,\n events: tabsNode.events,\n visibility: tabsNode.visibility,\n pollingMs: tabsNode.pollingMs,\n order: tabsNode.order,\n } as StudioWidgetDecl);\n } else if ('children' in node && Array.isArray(node.children)) {\n // Other composite widgets (section, grid, stack, modal)\n const compositeNode = node as SectionConfig | GridConfig | StackConfig | ModalConfig;\n const { widgets: childWidgets, rootIds: childIds } = collectWidgets(compositeNode.children);\n widgets.push(...childWidgets);\n\n widgets.push({\n id: compositeNode.id,\n kind: compositeNode.kind,\n title: compositeNode.title,\n description: compositeNode.description,\n data: { source: toDataSource(compositeNode.source) },\n options: compositeNode.options,\n children: childIds,\n layoutHint: compositeNode.layout,\n actions: compositeNode.actions,\n events: compositeNode.events,\n visibility: compositeNode.visibility,\n pollingMs: compositeNode.pollingMs,\n order: compositeNode.order,\n } as StudioWidgetDecl);\n } else {\n // Leaf widget\n const leafNode = node as LeafWidgetConfig<Exclude<StudioWidgetKind, CompositeWidgetKind>>;\n widgets.push({\n id: leafNode.id,\n kind: leafNode.kind,\n title: leafNode.title,\n description: leafNode.description,\n data: { source: toDataSource(leafNode.source) },\n options: leafNode.options,\n layoutHint: leafNode.layout,\n actions: leafNode.actions,\n events: leafNode.events,\n visibility: leafNode.visibility,\n pollingMs: leafNode.pollingMs,\n order: leafNode.order,\n } as StudioWidgetDecl);\n }\n }\n\n return { widgets, rootIds };\n}\n\n// =============================================================================\n// definePage\n// =============================================================================\n\n/**\n * Page configuration.\n */\nexport interface PageConfig {\n id: string;\n title: string;\n description?: string;\n icon?: string;\n layout?: 'grid' | 'stack';\n children: WidgetNode[];\n actions?: WidgetAction[];\n visibility?: VisibilityRule;\n order?: number;\n}\n\n/**\n * Define a Studio page.\n * Collects all widgets recursively and returns layout + widgets.\n */\nexport function definePage(config: PageConfig): {\n layout: StudioLayoutDecl;\n widgets: StudioWidgetDecl[];\n} {\n const { widgets, rootIds } = collectWidgets(config.children);\n\n return {\n layout: {\n id: config.id,\n kind: config.layout ?? 'grid',\n title: config.title,\n description: config.description,\n icon: config.icon,\n widgets: rootIds,\n actions: config.actions,\n visibility: config.visibility,\n order: config.order,\n },\n widgets,\n };\n}\n\n// =============================================================================\n// defineMenu\n// =============================================================================\n\n/**\n * Menu configuration.\n */\nexport interface MenuConfig {\n id: string;\n label: string;\n icon?: string;\n target: string;\n order?: number;\n parentId?: string;\n visibility?: VisibilityRule;\n badge?: string;\n badgeVariant?: 'default' | 'primary' | 'danger';\n}\n\n/**\n * Define a menu item.\n */\nexport function defineMenu(config: MenuConfig): StudioMenuDecl {\n return config;\n}\n\n// =============================================================================\n// defineStudio\n// =============================================================================\n\n/**\n * Studio manifest configuration.\n */\nexport interface StudioManifestConfig {\n pages?: PageConfig[];\n widgets?: WidgetNode[];\n menus?: MenuConfig[];\n}\n\n/**\n * Define a complete Studio configuration.\n * Main entry point for plugin authors.\n */\nexport function defineStudio(config: StudioManifestConfig): StudioConfig {\n const allWidgets: StudioWidgetDecl[] = [];\n const layouts: StudioLayoutDecl[] = [];\n const menus: StudioMenuDecl[] = [];\n\n // Process pages -> layouts + widgets\n for (const page of config.pages ?? []) {\n const result = definePage(page);\n layouts.push(result.layout);\n allWidgets.push(...result.widgets);\n }\n\n // Add standalone widgets (also supports nesting)\n if (config.widgets?.length) {\n const { widgets } = collectWidgets(config.widgets);\n allWidgets.push(...widgets);\n }\n\n // Add menus\n for (const menu of config.menus ?? []) {\n menus.push(defineMenu(menu));\n }\n\n return { widgets: allWidgets, layouts, menus };\n}\n\n// =============================================================================\n// Widget Factory Helpers\n// =============================================================================\n\ntype LeafKind = Exclude<StudioWidgetKind, CompositeWidgetKind>;\n\n/**\n * Create a widget config factory for a specific kind.\n */\nfunction createWidgetFactory<K extends LeafKind>(kind: K) {\n return (\n config: Omit<LeafWidgetConfig<K>, 'kind'> & { options?: WidgetOptionsMap[K] }\n ): LeafWidgetConfig<K> => ({\n ...config,\n kind,\n });\n}\n\n// Display widgets (14)\nexport const metric = createWidgetFactory('metric');\nexport const metricGroup = createWidgetFactory('metric-group');\nexport const table = createWidgetFactory('table');\nexport const card = createWidgetFactory('card');\nexport const cardlist = createWidgetFactory('cardlist');\nexport const chartLine = createWidgetFactory('chart-line');\nexport const chartBar = createWidgetFactory('chart-bar');\nexport const chartPie = createWidgetFactory('chart-pie');\nexport const chartArea = createWidgetFactory('chart-area');\nexport const timeline = createWidgetFactory('timeline');\nexport const tree = createWidgetFactory('tree');\nexport const json = createWidgetFactory('json');\nexport const diff = createWidgetFactory('diff');\nexport const logs = createWidgetFactory('logs');\n\n// Form widgets (6)\nexport const form = createWidgetFactory('form');\nexport const input = createWidgetFactory('input');\nexport const select = createWidgetFactory('select');\nexport const checkboxGroup = createWidgetFactory('checkbox-group');\nexport const switchWidget = createWidgetFactory('switch');\nexport const datePicker = createWidgetFactory('date-picker');\n\n// Navigation widgets (3)\nexport const breadcrumb = createWidgetFactory('breadcrumb');\nexport const stepper = createWidgetFactory('stepper');\nexport const menu = createWidgetFactory('menu');\n\n// Feedback widgets (2)\nexport const alert = createWidgetFactory('alert');\nexport const confirm = createWidgetFactory('confirm');\n\n// =============================================================================\n// Composite Widget Factories\n// =============================================================================\n\n/**\n * Create a section widget.\n */\nexport function section(\n config: Omit<SectionConfig, 'kind'> & { options?: WidgetOptionsMap['section'] }\n): SectionConfig {\n return { ...config, kind: 'section' };\n}\n\n/**\n * Create a grid widget.\n */\nexport function grid(\n config: Omit<GridConfig, 'kind'> & { options?: WidgetOptionsMap['grid'] }\n): GridConfig {\n return { ...config, kind: 'grid' };\n}\n\n/**\n * Create a stack widget.\n */\nexport function stack(\n config: Omit<StackConfig, 'kind'> & { options?: WidgetOptionsMap['stack'] }\n): StackConfig {\n return { ...config, kind: 'stack' };\n}\n\n/**\n * Create a tabs widget.\n */\nexport function tabs(\n config: Omit<TabsConfig, 'kind'> & { options?: Omit<WidgetOptionsMap['tabs'], 'tabs' | 'tabChildren'> }\n): TabsConfig {\n return { ...config, kind: 'tabs' };\n}\n\n/**\n * Create a modal widget.\n */\nexport function modal(\n config: Omit<ModalConfig, 'kind'> & { options?: WidgetOptionsMap['modal'] }\n): ModalConfig {\n return { ...config, kind: 'modal' };\n}\n\n// =============================================================================\n// Re-exports from studio-contracts\n// =============================================================================\n\nexport type {\n StudioWidgetDecl,\n StudioLayoutDecl,\n StudioMenuDecl,\n StudioConfig,\n StudioWidgetKind,\n CompositeWidgetKind,\n DataSource,\n WidgetAction,\n WidgetEventConfig,\n LayoutHint,\n VisibilityRule,\n WidgetOptionsMap,\n} from '@kb-labs/studio-contracts';\n"]}
|
package/package.json
ADDED
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@kb-labs/shared-command-kit",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"description": "Command Kit for KB Labs CLI - utilities and high-level API for building commands",
|
|
6
|
+
"main": "./dist/index.js",
|
|
7
|
+
"types": "./dist/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"import": "./dist/index.js",
|
|
11
|
+
"types": "./dist/index.d.ts"
|
|
12
|
+
},
|
|
13
|
+
"./flags": {
|
|
14
|
+
"import": "./dist/flags/index.js",
|
|
15
|
+
"types": "./dist/flags/index.d.ts"
|
|
16
|
+
},
|
|
17
|
+
"./analytics": {
|
|
18
|
+
"import": "./dist/analytics/index.js",
|
|
19
|
+
"types": "./dist/analytics/index.d.ts"
|
|
20
|
+
},
|
|
21
|
+
"./errors": {
|
|
22
|
+
"import": "./dist/errors/index.js",
|
|
23
|
+
"types": "./dist/errors/index.d.ts"
|
|
24
|
+
},
|
|
25
|
+
"./helpers": {
|
|
26
|
+
"import": "./dist/helpers/index.js",
|
|
27
|
+
"types": "./dist/helpers/index.d.ts"
|
|
28
|
+
},
|
|
29
|
+
"./studio": {
|
|
30
|
+
"import": "./dist/studio/index.js",
|
|
31
|
+
"types": "./dist/studio/index.d.ts"
|
|
32
|
+
}
|
|
33
|
+
},
|
|
34
|
+
"files": [
|
|
35
|
+
"dist",
|
|
36
|
+
"README.md",
|
|
37
|
+
"LICENSE"
|
|
38
|
+
],
|
|
39
|
+
"sideEffects": false,
|
|
40
|
+
"dependencies": {
|
|
41
|
+
"@kb-labs/core-platform": "link:../../../kb-labs-core/packages/core-platform",
|
|
42
|
+
"@kb-labs/core-resource-broker": "link:../../../kb-labs-core/packages/core-resource-broker",
|
|
43
|
+
"@kb-labs/core-runtime": "link:../../../kb-labs-core/packages/core-runtime",
|
|
44
|
+
"@kb-labs/plugin-contracts": "link:../../../kb-labs-plugin/packages/plugin-contracts",
|
|
45
|
+
"@kb-labs/plugin-runtime": "link:../../../kb-labs-plugin/packages/plugin-runtime",
|
|
46
|
+
"@kb-labs/studio-contracts": "link:../../../kb-labs-studio/packages/studio-contracts",
|
|
47
|
+
"zod": "^3.23.8",
|
|
48
|
+
"glob": "^11.0.0",
|
|
49
|
+
"@kb-labs/shared-cli-ui": "1.0.0"
|
|
50
|
+
},
|
|
51
|
+
"devDependencies": {
|
|
52
|
+
"@kb-labs/devkit": "link:../../../kb-labs-devkit",
|
|
53
|
+
"@types/node": "^24.3.3",
|
|
54
|
+
"rimraf": "^6.0.1",
|
|
55
|
+
"tsup": "^8.5.0",
|
|
56
|
+
"typescript": "^5.6.3",
|
|
57
|
+
"vitest": "^3.2.4"
|
|
58
|
+
},
|
|
59
|
+
"engines": {
|
|
60
|
+
"node": ">=20.0.0",
|
|
61
|
+
"pnpm": ">=9.0.0"
|
|
62
|
+
},
|
|
63
|
+
"publishConfig": {
|
|
64
|
+
"access": "public"
|
|
65
|
+
},
|
|
66
|
+
"scripts": {
|
|
67
|
+
"clean": "rimraf dist",
|
|
68
|
+
"build": "tsup --config tsup.config.ts",
|
|
69
|
+
"dev": "tsup --config tsup.config.ts --watch",
|
|
70
|
+
"lint": "eslint src",
|
|
71
|
+
"lint:fix": "eslint src --fix",
|
|
72
|
+
"type-check": "tsc --noEmit",
|
|
73
|
+
"test": "vitest run --passWithNoTests",
|
|
74
|
+
"test:watch": "vitest"
|
|
75
|
+
}
|
|
76
|
+
}
|