@xemahq/ui-kernel 0.3.0 → 0.4.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.
@@ -0,0 +1,22 @@
1
+ import type { FrontendBiome } from './frontend-biome';
2
+ export declare enum CompositionDiagnosticSeverity {
3
+ Error = "error",
4
+ Warning = "warning"
5
+ }
6
+ export declare enum CompositionDiagnosticCode {
7
+ DuplicateRoutePath = "duplicate_route_path",
8
+ DuplicateNavId = "duplicate_nav_id",
9
+ UnknownSlot = "unknown_slot",
10
+ OrphanedPanelSlot = "orphaned_panel_slot"
11
+ }
12
+ export interface CompositionDiagnostic {
13
+ readonly code: CompositionDiagnosticCode;
14
+ readonly severity: CompositionDiagnosticSeverity;
15
+ readonly biomeIds: readonly string[];
16
+ readonly message: string;
17
+ }
18
+ export interface ValidateBiomeCompositionOptions {
19
+ readonly knownSlots: ReadonlySet<string>;
20
+ }
21
+ export declare function validateBiomeComposition(biomes: readonly FrontendBiome[], options: ValidateBiomeCompositionOptions): readonly CompositionDiagnostic[];
22
+ //# sourceMappingURL=composition-validation.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"composition-validation.d.ts","sourceRoot":"","sources":["../../../src/lib/biome-host/composition-validation.ts"],"names":[],"mappings":"AAqBA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAGtD,oBAAY,6BAA6B;IAMvC,KAAK,UAAU;IAOf,OAAO,YAAY;CACpB;AAGD,oBAAY,yBAAyB;IAEnC,kBAAkB,yBAAyB;IAE3C,cAAc,qBAAqB;IAKnC,WAAW,iBAAiB;IAK5B,iBAAiB,wBAAwB;CAC1C;AAED,MAAM,WAAW,qBAAqB;IACpC,QAAQ,CAAC,IAAI,EAAE,yBAAyB,CAAC;IACzC,QAAQ,CAAC,QAAQ,EAAE,6BAA6B,CAAC;IAEjD,QAAQ,CAAC,QAAQ,EAAE,SAAS,MAAM,EAAE,CAAC;IAErC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,+BAA+B;IAM9C,QAAQ,CAAC,UAAU,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;CAC1C;AAwBD,wBAAgB,wBAAwB,CACtC,MAAM,EAAE,SAAS,aAAa,EAAE,EAChC,OAAO,EAAE,+BAA+B,GACvC,SAAS,qBAAqB,EAAE,CA6FlC"}
@@ -0,0 +1,127 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.CompositionDiagnosticCode = exports.CompositionDiagnosticSeverity = void 0;
4
+ exports.validateBiomeComposition = validateBiomeComposition;
5
+ var CompositionDiagnosticSeverity;
6
+ (function (CompositionDiagnosticSeverity) {
7
+ CompositionDiagnosticSeverity["Error"] = "error";
8
+ CompositionDiagnosticSeverity["Warning"] = "warning";
9
+ })(CompositionDiagnosticSeverity || (exports.CompositionDiagnosticSeverity = CompositionDiagnosticSeverity = {}));
10
+ var CompositionDiagnosticCode;
11
+ (function (CompositionDiagnosticCode) {
12
+ CompositionDiagnosticCode["DuplicateRoutePath"] = "duplicate_route_path";
13
+ CompositionDiagnosticCode["DuplicateNavId"] = "duplicate_nav_id";
14
+ CompositionDiagnosticCode["UnknownSlot"] = "unknown_slot";
15
+ CompositionDiagnosticCode["OrphanedPanelSlot"] = "orphaned_panel_slot";
16
+ })(CompositionDiagnosticCode || (exports.CompositionDiagnosticCode = CompositionDiagnosticCode = {}));
17
+ function biomeOwnedSlotOwner(slot) {
18
+ const slashIndex = slot.indexOf('/');
19
+ if (slashIndex <= 0)
20
+ return null;
21
+ if (slot.indexOf('/', slashIndex + 1) !== -1)
22
+ return null;
23
+ const owner = slot.slice(0, slashIndex);
24
+ const name = slot.slice(slashIndex + 1);
25
+ if (owner.length === 0 || name.length === 0)
26
+ return null;
27
+ return owner;
28
+ }
29
+ function validateBiomeComposition(biomes, options) {
30
+ const diagnostics = [];
31
+ const biomeIds = new Set(biomes.map((b) => b.id));
32
+ const routeOwners = new Map();
33
+ for (const biome of biomes) {
34
+ for (const route of biome.routes ?? []) {
35
+ const scope = route.projectScoped ? 'project' : 'root';
36
+ const key = `${scope}:${route.path}`;
37
+ const owners = routeOwners.get(key);
38
+ if (owners)
39
+ owners.push(biome.id);
40
+ else
41
+ routeOwners.set(key, [biome.id]);
42
+ }
43
+ }
44
+ for (const [key, owners] of routeOwners) {
45
+ if (owners.length < 2)
46
+ continue;
47
+ const [scope, path] = splitFirst(key, ':');
48
+ diagnostics.push({
49
+ code: CompositionDiagnosticCode.DuplicateRoutePath,
50
+ severity: CompositionDiagnosticSeverity.Error,
51
+ biomeIds: owners,
52
+ message: `Route path '${path}' (${scope}-scoped) is contributed by multiple biomes: ` +
53
+ `${owners.join(', ')}. Each route must be unique within its scope — ` +
54
+ `only one would mount and the others would be unreachable.`,
55
+ });
56
+ }
57
+ const navOwners = new Map();
58
+ for (const biome of biomes) {
59
+ for (const navItem of biome.navItems ?? []) {
60
+ const owners = navOwners.get(navItem.id);
61
+ if (owners)
62
+ owners.push(biome.id);
63
+ else
64
+ navOwners.set(navItem.id, [biome.id]);
65
+ }
66
+ }
67
+ for (const [navId, owners] of navOwners) {
68
+ if (owners.length < 2)
69
+ continue;
70
+ diagnostics.push({
71
+ code: CompositionDiagnosticCode.DuplicateNavId,
72
+ severity: CompositionDiagnosticSeverity.Error,
73
+ biomeIds: owners,
74
+ message: `Nav id '${navId}' is contributed by multiple biomes: ${owners.join(', ')}. ` +
75
+ `Nav ids must be unique — a duplicate silently overwrites the ` +
76
+ `feature-route mapping and collides as a render key.`,
77
+ });
78
+ }
79
+ for (const biome of biomes) {
80
+ for (const panel of biome.panels ?? []) {
81
+ if (options.knownSlots.has(panel.slot))
82
+ continue;
83
+ const owner = biomeOwnedSlotOwner(panel.slot);
84
+ if (owner === null) {
85
+ diagnostics.push({
86
+ code: CompositionDiagnosticCode.UnknownSlot,
87
+ severity: CompositionDiagnosticSeverity.Warning,
88
+ biomeIds: [biome.id],
89
+ message: `Biome '${biome.id}' panel '${panel.id}' targets slot '${panel.slot}', ` +
90
+ `which is neither a known host slot nor a well-formed ` +
91
+ `'<owner>/<name>' biome-owned slot. It will never render — ` +
92
+ `check for a typo against the host slot catalog.`,
93
+ });
94
+ continue;
95
+ }
96
+ if (!biomeIds.has(owner)) {
97
+ diagnostics.push({
98
+ code: CompositionDiagnosticCode.OrphanedPanelSlot,
99
+ severity: CompositionDiagnosticSeverity.Warning,
100
+ biomeIds: [biome.id],
101
+ message: `Biome '${biome.id}' panel '${panel.id}' targets biome-owned slot ` +
102
+ `'${panel.slot}', but its owner biome '${owner}' is not registered. ` +
103
+ `The panel will never render until '${owner}' is enabled.`,
104
+ });
105
+ }
106
+ }
107
+ }
108
+ return sortDiagnostics(diagnostics);
109
+ }
110
+ function splitFirst(value, sep) {
111
+ const idx = value.indexOf(sep);
112
+ if (idx === -1)
113
+ return [value, ''];
114
+ return [value.slice(0, idx), value.slice(idx + sep.length)];
115
+ }
116
+ function sortDiagnostics(diagnostics) {
117
+ return diagnostics.slice().sort((a, b) => {
118
+ if (a.code !== b.code)
119
+ return a.code.localeCompare(b.code);
120
+ const ai = a.biomeIds.join(',');
121
+ const bi = b.biomeIds.join(',');
122
+ if (ai !== bi)
123
+ return ai.localeCompare(bi);
124
+ return a.message.localeCompare(b.message);
125
+ });
126
+ }
127
+ //# sourceMappingURL=composition-validation.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"composition-validation.js","sourceRoot":"","sources":["../../../src/lib/biome-host/composition-validation.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,30 @@
1
+ import type { FrontendBiome, FrontendBiomeFactory, RouteAccess } from './frontend-biome';
2
+ import type { ComponentType } from 'react';
3
+ export interface WebBiomePage {
4
+ readonly slug: string;
5
+ readonly id?: string;
6
+ readonly label: string;
7
+ readonly icon?: ComponentType<{
8
+ className?: string | undefined;
9
+ }>;
10
+ readonly category?: string;
11
+ readonly scope?: 'org' | 'project';
12
+ readonly access?: RouteAccess;
13
+ readonly load: () => Promise<{
14
+ default: ComponentType<unknown>;
15
+ }>;
16
+ readonly weight?: number;
17
+ readonly navHidden?: boolean;
18
+ }
19
+ export interface DefineWebBiomeOptions {
20
+ readonly id: string;
21
+ readonly displayName: string;
22
+ readonly init?: FrontendBiome['init'];
23
+ readonly dispose?: FrontendBiome['dispose'];
24
+ readonly pages: readonly WebBiomePage[];
25
+ readonly panels?: FrontendBiome['panels'];
26
+ readonly session?: FrontendBiome['session'];
27
+ readonly outputRenderers?: FrontendBiome['outputRenderers'];
28
+ }
29
+ export declare function defineWebBiome(options: DefineWebBiomeOptions): FrontendBiomeFactory;
30
+ //# sourceMappingURL=define-web-biome.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"define-web-biome.d.ts","sourceRoot":"","sources":["../../../src/lib/biome-host/define-web-biome.ts"],"names":[],"mappings":"AA0CA,OAAO,KAAK,EACV,aAAa,EACb,oBAAoB,EAEpB,WAAW,EAEZ,MAAM,kBAAkB,CAAC;AAC1B,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,OAAO,CAAC;AAE3C,MAAM,WAAW,YAAY;IAM3B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAOtB,QAAQ,CAAC,EAAE,CAAC,EAAE,MAAM,CAAC;IAErB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IAEvB,QAAQ,CAAC,IAAI,CAAC,EAAE,aAAa,CAAC;QAAE,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;KAAE,CAAC,CAAC;IAMlE,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAK3B,QAAQ,CAAC,KAAK,CAAC,EAAE,KAAK,GAAG,SAAS,CAAC;IAEnC,QAAQ,CAAC,MAAM,CAAC,EAAE,WAAW,CAAC;IAE9B,QAAQ,CAAC,IAAI,EAAE,MAAM,OAAO,CAAC;QAAE,OAAO,EAAE,aAAa,CAAC,OAAO,CAAC,CAAA;KAAE,CAAC,CAAC;IAKlE,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IAKzB,QAAQ,CAAC,SAAS,CAAC,EAAE,OAAO,CAAC;CAC9B;AAED,MAAM,WAAW,qBAAqB;IAEpC,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IAEpB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAE7B,QAAQ,CAAC,IAAI,CAAC,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC;IAEtC,QAAQ,CAAC,OAAO,CAAC,EAAE,aAAa,CAAC,SAAS,CAAC,CAAC;IAE5C,QAAQ,CAAC,KAAK,EAAE,SAAS,YAAY,EAAE,CAAC;IAExC,QAAQ,CAAC,MAAM,CAAC,EAAE,aAAa,CAAC,QAAQ,CAAC,CAAC;IAE1C,QAAQ,CAAC,OAAO,CAAC,EAAE,aAAa,CAAC,SAAS,CAAC,CAAC;IAE5C,QAAQ,CAAC,eAAe,CAAC,EAAE,aAAa,CAAC,iBAAiB,CAAC,CAAC;CAC7D;AAMD,wBAAgB,cAAc,CAC5B,OAAO,EAAE,qBAAqB,GAC7B,oBAAoB,CAuCtB"}
@@ -0,0 +1,42 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.defineWebBiome = defineWebBiome;
4
+ const biome_builders_1 = require("./biome-builders");
5
+ function defineWebBiome(options) {
6
+ return () => {
7
+ const navItems = [];
8
+ const routes = [];
9
+ for (const page of options.pages) {
10
+ routes.push({
11
+ path: page.slug,
12
+ projectScoped: page.scope === 'project',
13
+ element: (0, biome_builders_1.lazyRoute)(page.load),
14
+ ...(page.access ? { access: page.access } : {}),
15
+ });
16
+ if (!page.navHidden) {
17
+ navItems.push({
18
+ id: page.id ?? page.slug,
19
+ label: page.label,
20
+ route: page.slug,
21
+ ...(page.icon ? { icon: page.icon } : {}),
22
+ ...(page.category !== undefined ? { category: page.category } : {}),
23
+ ...(page.weight !== undefined ? { weight: page.weight } : {}),
24
+ });
25
+ }
26
+ }
27
+ return {
28
+ id: options.id,
29
+ displayName: options.displayName,
30
+ navItems,
31
+ routes,
32
+ ...(options.init ? { init: options.init } : {}),
33
+ ...(options.dispose ? { dispose: options.dispose } : {}),
34
+ ...(options.panels ? { panels: options.panels } : {}),
35
+ ...(options.session ? { session: options.session } : {}),
36
+ ...(options.outputRenderers
37
+ ? { outputRenderers: options.outputRenderers }
38
+ : {}),
39
+ };
40
+ };
41
+ }
42
+ //# sourceMappingURL=define-web-biome.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"define-web-biome.js","sourceRoot":"","sources":["../../../src/lib/biome-host/define-web-biome.ts"],"names":[],"mappings":";;AAuHA,wCAyCC;AAxHD,qDAA6C;AA+E7C,SAAgB,cAAc,CAC5B,OAA8B;IAE9B,OAAO,GAAG,EAAE;QACV,MAAM,QAAQ,GAA0B,EAAE,CAAC;QAC3C,MAAM,MAAM,GAAwB,EAAE,CAAC;QAEvC,KAAK,MAAM,IAAI,IAAI,OAAO,CAAC,KAAK,EAAE,CAAC;YACjC,MAAM,CAAC,IAAI,CAAC;gBACV,IAAI,EAAE,IAAI,CAAC,IAAI;gBACf,aAAa,EAAE,IAAI,CAAC,KAAK,KAAK,SAAS;gBACvC,OAAO,EAAE,IAAA,0BAAS,EAAC,IAAI,CAAC,IAAI,CAAC;gBAC7B,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;aAChD,CAAC,CAAC;YAEH,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC;gBACpB,QAAQ,CAAC,IAAI,CAAC;oBACZ,EAAE,EAAE,IAAI,CAAC,EAAE,IAAI,IAAI,CAAC,IAAI;oBACxB,KAAK,EAAE,IAAI,CAAC,KAAK;oBACjB,KAAK,EAAE,IAAI,CAAC,IAAI;oBAChB,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;oBACzC,GAAG,CAAC,IAAI,CAAC,QAAQ,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;oBACnE,GAAG,CAAC,IAAI,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;iBAC9D,CAAC,CAAC;YACL,CAAC;QACH,CAAC;QAED,OAAO;YACL,EAAE,EAAE,OAAO,CAAC,EAAE;YACd,WAAW,EAAE,OAAO,CAAC,WAAW;YAChC,QAAQ;YACR,MAAM;YACN,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YAC/C,GAAG,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACxD,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACrD,GAAG,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACxD,GAAG,CAAC,OAAO,CAAC,eAAe;gBACzB,CAAC,CAAC,EAAE,eAAe,EAAE,OAAO,CAAC,eAAe,EAAE;gBAC9C,CAAC,CAAC,EAAE,CAAC;SACR,CAAC;IACJ,CAAC,CAAC;AACJ,CAAC"}
@@ -8,6 +8,7 @@ export interface NavItemContribution {
8
8
  readonly icon?: ComponentType<{
9
9
  className?: string | undefined;
10
10
  }>;
11
+ readonly category?: string;
11
12
  readonly section?: string;
12
13
  readonly weight?: number;
13
14
  }
@@ -1 +1 @@
1
- {"version":3,"file":"frontend-biome.d.ts","sourceRoot":"","sources":["../../../src/lib/biome-host/frontend-biome.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AACtD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAChD,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,yBAAyB,CAAC;AAYpE,MAAM,WAAW,mBAAmB;IAElC,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IAEpB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IAEvB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IAQvB,QAAQ,CAAC,IAAI,CAAC,EAAE,aAAa,CAAC;QAAE,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;KAAE,CAAC,CAAC;IAElE,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAE1B,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;CAC1B;AAQD,MAAM,MAAM,WAAW,GAAG,QAAQ,GAAG,WAAW,GAAG,gBAAgB,CAAC;AAEpE,MAAM,WAAW,iBAAiB;IAEhC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAEtB,QAAQ,CAAC,OAAO,EAAE,MAAM,SAAS,CAAC;IASlC,QAAQ,CAAC,aAAa,EAAE,OAAO,CAAC;IAKhC,QAAQ,CAAC,MAAM,CAAC,EAAE,WAAW,CAAC;CAC/B;AAQD,MAAM,WAAW,iBAAiB;IAEhC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAEtB,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IAEpB,QAAQ,CAAC,MAAM,EAAE,MAAM,SAAS,CAAC;IAEjC,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;CAC1B;AAUD,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,MAAM,EAAE,UAAU,CAAC;IAE5B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,aAAa;IAE5B,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IAEpB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAQ7B,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,EAAE,gBAAgB,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAOhE,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC9C,QAAQ,CAAC,QAAQ,CAAC,EAAE,SAAS,mBAAmB,EAAE,CAAC;IACnD,QAAQ,CAAC,MAAM,CAAC,EAAE,SAAS,iBAAiB,EAAE,CAAC;IAC/C,QAAQ,CAAC,MAAM,CAAC,EAAE,SAAS,iBAAiB,EAAE,CAAC;IAO/C,QAAQ,CAAC,OAAO,CAAC,EAAE,oBAAoB,CAAC;IAexC,QAAQ,CAAC,eAAe,CAAC,EAAE,SAAS,0BAA0B,EAAE,CAAC;CAClE;AAYD,MAAM,WAAW,0BAA0B;IAOzC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAQ5B,QAAQ,CAAC,MAAM,EAAE,MAAM,aAAa,CAAC;QAAE,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAA;KAAE,CAAC,CAAC;CACpE;AAaD,MAAM,MAAM,oBAAoB,GAAG,CAAC,MAAM,EAAE,UAAU,KAAK,aAAa,CAAC"}
1
+ {"version":3,"file":"frontend-biome.d.ts","sourceRoot":"","sources":["../../../src/lib/biome-host/frontend-biome.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AACtD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAChD,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,yBAAyB,CAAC;AAYpE,MAAM,WAAW,mBAAmB;IAElC,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IAEpB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IAEvB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IAQvB,QAAQ,CAAC,IAAI,CAAC,EAAE,aAAa,CAAC;QAAE,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;KAAE,CAAC,CAAC;IAWlE,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAM3B,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAK1B,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;CAC1B;AAQD,MAAM,MAAM,WAAW,GAAG,QAAQ,GAAG,WAAW,GAAG,gBAAgB,CAAC;AAEpE,MAAM,WAAW,iBAAiB;IAEhC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAEtB,QAAQ,CAAC,OAAO,EAAE,MAAM,SAAS,CAAC;IASlC,QAAQ,CAAC,aAAa,EAAE,OAAO,CAAC;IAKhC,QAAQ,CAAC,MAAM,CAAC,EAAE,WAAW,CAAC;CAC/B;AAQD,MAAM,WAAW,iBAAiB;IAEhC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAEtB,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IAEpB,QAAQ,CAAC,MAAM,EAAE,MAAM,SAAS,CAAC;IAEjC,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;CAC1B;AAUD,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,MAAM,EAAE,UAAU,CAAC;IAE5B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,aAAa;IAE5B,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IAEpB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAQ7B,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,EAAE,gBAAgB,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAOhE,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC9C,QAAQ,CAAC,QAAQ,CAAC,EAAE,SAAS,mBAAmB,EAAE,CAAC;IACnD,QAAQ,CAAC,MAAM,CAAC,EAAE,SAAS,iBAAiB,EAAE,CAAC;IAC/C,QAAQ,CAAC,MAAM,CAAC,EAAE,SAAS,iBAAiB,EAAE,CAAC;IAO/C,QAAQ,CAAC,OAAO,CAAC,EAAE,oBAAoB,CAAC;IAexC,QAAQ,CAAC,eAAe,CAAC,EAAE,SAAS,0BAA0B,EAAE,CAAC;CAClE;AAYD,MAAM,WAAW,0BAA0B;IAOzC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAQ5B,QAAQ,CAAC,MAAM,EAAE,MAAM,aAAa,CAAC;QAAE,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAA;KAAE,CAAC,CAAC;CACpE;AAaD,MAAM,MAAM,oBAAoB,GAAG,CAAC,MAAM,EAAE,UAAU,KAAK,aAAa,CAAC"}
@@ -4,6 +4,7 @@ export * from './biome-navigation';
4
4
  export * from './biome-scope';
5
5
  export * from './biome-scoped-query';
6
6
  export * from './biome-builders';
7
+ export * from './define-web-biome';
7
8
  export * from './create-biome-orval-config';
8
9
  export * from './biome-registry';
9
10
  export * from './session-contributions';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/lib/biome-host/index.ts"],"names":[],"mappings":"AAcA,cAAc,kBAAkB,CAAC;AACjC,cAAc,eAAe,CAAC;AAC9B,cAAc,oBAAoB,CAAC;AACnC,cAAc,eAAe,CAAC;AAC9B,cAAc,sBAAsB,CAAC;AACrC,cAAc,kBAAkB,CAAC;AACjC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,kBAAkB,CAAC;AACjC,cAAc,yBAAyB,CAAC;AACxC,cAAc,oBAAoB,CAAC;AACnC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,OAAO,CAAC;AACtB,cAAc,cAAc,CAAC;AAC7B,cAAc,oBAAoB,CAAC;AACnC,cAAc,iBAAiB,CAAC;AAChC,cAAc,kBAAkB,CAAC;AACjC,cAAc,UAAU,CAAC;AACzB,cAAc,qBAAqB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/lib/biome-host/index.ts"],"names":[],"mappings":"AAcA,cAAc,kBAAkB,CAAC;AACjC,cAAc,eAAe,CAAC;AAC9B,cAAc,oBAAoB,CAAC;AACnC,cAAc,eAAe,CAAC;AAC9B,cAAc,sBAAsB,CAAC;AACrC,cAAc,kBAAkB,CAAC;AACjC,cAAc,oBAAoB,CAAC;AACnC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,kBAAkB,CAAC;AACjC,cAAc,yBAAyB,CAAC;AACxC,cAAc,oBAAoB,CAAC;AACnC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,OAAO,CAAC;AACtB,cAAc,cAAc,CAAC;AAC7B,cAAc,oBAAoB,CAAC;AACnC,cAAc,iBAAiB,CAAC;AAChC,cAAc,kBAAkB,CAAC;AACjC,cAAc,UAAU,CAAC;AACzB,cAAc,qBAAqB,CAAC"}
@@ -20,6 +20,7 @@ __exportStar(require("./biome-navigation"), exports);
20
20
  __exportStar(require("./biome-scope"), exports);
21
21
  __exportStar(require("./biome-scoped-query"), exports);
22
22
  __exportStar(require("./biome-builders"), exports);
23
+ __exportStar(require("./define-web-biome"), exports);
23
24
  __exportStar(require("./create-biome-orval-config"), exports);
24
25
  __exportStar(require("./biome-registry"), exports);
25
26
  __exportStar(require("./session-contributions"), exports);
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/lib/biome-host/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAcA,mDAAiC;AACjC,gDAA8B;AAC9B,qDAAmC;AACnC,gDAA8B;AAC9B,uDAAqC;AACrC,mDAAiC;AACjC,8DAA4C;AAC5C,mDAAiC;AACjC,0DAAwC;AACxC,qDAAmC;AACnC,iDAA+B;AAC/B,wCAAsB;AACtB,+CAA6B;AAC7B,qDAAmC;AACnC,kDAAgC;AAChC,mDAAiC;AACjC,2CAAyB;AACzB,sDAAoC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/lib/biome-host/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAcA,mDAAiC;AACjC,gDAA8B;AAC9B,qDAAmC;AACnC,gDAA8B;AAC9B,uDAAqC;AACrC,mDAAiC;AACjC,qDAAmC;AACnC,8DAA4C;AAC5C,mDAAiC;AACjC,0DAAwC;AACxC,qDAAmC;AACnC,iDAA+B;AAC/B,wCAAsB;AACtB,+CAA6B;AAC7B,qDAAmC;AACnC,kDAAgC;AAChC,mDAAiC;AACjC,2CAAyB;AACzB,sDAAoC"}
@@ -0,0 +1,3 @@
1
+ import { type CompositionDiagnostic, type FrontendBiome } from '../../index';
2
+ export declare function validateHostBiomeComposition(biomes: readonly FrontendBiome[]): readonly CompositionDiagnostic[];
3
+ //# sourceMappingURL=composition-validation-host.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"composition-validation-host.d.ts","sourceRoot":"","sources":["../../../src/registry/lib/composition-validation-host.ts"],"names":[],"mappings":"AAUA,OAAO,EACL,KAAK,qBAAqB,EAC1B,KAAK,aAAa,EAEnB,MAAM,aAAa,CAAC;AAkBrB,wBAAgB,4BAA4B,CAC1C,MAAM,EAAE,SAAS,aAAa,EAAE,GAC/B,SAAS,qBAAqB,EAAE,CAElC"}
@@ -0,0 +1,10 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.validateHostBiomeComposition = validateHostBiomeComposition;
4
+ const index_1 = require("../../index");
5
+ const extension_points_1 = require("./extension-points");
6
+ const HOST_SLOT_IDS = new Set(Object.values(extension_points_1.HostExtensionSlots));
7
+ function validateHostBiomeComposition(biomes) {
8
+ return (0, index_1.validateBiomeComposition)(biomes, { knownSlots: HOST_SLOT_IDS });
9
+ }
10
+ //# sourceMappingURL=composition-validation-host.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"composition-validation-host.js","sourceRoot":"","sources":["../../../src/registry/lib/composition-validation-host.ts"],"names":[],"mappings":";;AAgCA,oEAIC;AA1BD,uCAIqB;AAErB,yDAAwD;AAOxD,MAAM,aAAa,GAAwB,IAAI,GAAG,CAChD,MAAM,CAAC,MAAM,CAAC,qCAAkB,CAAC,CAClC,CAAC;AAOF,SAAgB,4BAA4B,CAC1C,MAAgC;IAEhC,OAAO,IAAA,gCAAwB,EAAC,MAAM,EAAE,EAAE,UAAU,EAAE,aAAa,EAAE,CAAC,CAAC;AACzE,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"SessionWorkspaceShell.d.ts","sourceRoot":"","sources":["../../../src/session/shell/SessionWorkspaceShell.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAI9D,UAAU,0BAA0B;IAKlC,QAAQ,CAAC,iBAAiB,EAAE,SAAS,CAAC,cAAc,CAAC,CAAC;IAEtD,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAC;IAEjC,QAAQ,CAAC,UAAU,EAAE,OAAO,CAAC;IAE7B,QAAQ,CAAC,WAAW,EAAE,CAAC,KAAK,EAAE,UAAU,CAAC,WAAW,CAAC,KAAK,IAAI,CAAC;IAG/D,QAAQ,CAAC,QAAQ,EAAE,SAAS,CAAC;IAQ7B,QAAQ,CAAC,WAAW,EAAE,SAAS,CAAC;IAMhC,QAAQ,CAAC,eAAe,CAAC,EAAE,SAAS,CAAC;IAMrC,QAAQ,CAAC,cAAc,CAAC,EAAE,SAAS,CAAC;IAMpC,QAAQ,CAAC,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAGrC,QAAQ,CAAC,gBAAgB,CAAC,EAAE,MAAM,CAAC;CACpC;AAiBD,wBAAgB,qBAAqB,CAAC,EACpC,iBAAiB,EACjB,eAAe,EACf,UAAU,EACV,WAAW,EACX,QAAQ,EACR,WAAW,EACX,eAAe,EACf,cAAc,EACd,iBAAyB,EACzB,gBAAsB,GACvB,EAAE,0BAA0B,+BAgE5B"}
1
+ {"version":3,"file":"SessionWorkspaceShell.d.ts","sourceRoot":"","sources":["../../../src/session/shell/SessionWorkspaceShell.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAiB,SAAS,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAI7E,UAAU,0BAA0B;IAKlC,QAAQ,CAAC,iBAAiB,EAAE,SAAS,CAAC,cAAc,CAAC,CAAC;IAEtD,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAC;IAEjC,QAAQ,CAAC,UAAU,EAAE,OAAO,CAAC;IAE7B,QAAQ,CAAC,WAAW,EAAE,CAAC,KAAK,EAAE,UAAU,CAAC,WAAW,CAAC,KAAK,IAAI,CAAC;IAG/D,QAAQ,CAAC,QAAQ,EAAE,SAAS,CAAC;IAQ7B,QAAQ,CAAC,WAAW,EAAE,SAAS,CAAC;IAMhC,QAAQ,CAAC,eAAe,CAAC,EAAE,SAAS,CAAC;IAMrC,QAAQ,CAAC,cAAc,CAAC,EAAE,SAAS,CAAC;IAMpC,QAAQ,CAAC,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAGrC,QAAQ,CAAC,gBAAgB,CAAC,EAAE,MAAM,CAAC;CACpC;AAiBD,wBAAgB,qBAAqB,CAAC,EACpC,iBAAiB,EACjB,eAAe,EACf,UAAU,EACV,WAAW,EACX,QAAQ,EACR,WAAW,EACX,eAAe,EACf,cAAc,EACd,iBAAyB,EACzB,gBAAsB,GACvB,EAAE,0BAA0B,+BAsE5B"}
@@ -5,11 +5,14 @@ const jsx_runtime_1 = require("react/jsx-runtime");
5
5
  const cn_1 = require("../lib/cn");
6
6
  function SessionWorkspaceShell({ splitContainerRef, chatPanePercent, isResizing, startResize, chatSlot, previewSlot, rightHeaderSlot, chatFooterSlot, previewFullscreen = false, minLeftPaneWidth = 320, }) {
7
7
  const hasPreviewSlot = previewSlot !== null;
8
- return ((0, jsx_runtime_1.jsxs)("div", { ref: splitContainerRef, className: (0, cn_1.cn)('relative flex h-full w-full overflow-hidden', isResizing && 'cursor-col-resize'), children: [!previewFullscreen && ((0, jsx_runtime_1.jsx)("div", { className: (0, cn_1.cn)('flex h-full w-full flex-col overflow-hidden bg-paper', hasPreviewSlot ? 'lg:flex-none' : ''), style: hasPreviewSlot
9
- ? {
10
- minWidth: `${minLeftPaneWidth}px`,
11
- width: `${chatPanePercent}%`,
12
- }
13
- : undefined, children: (0, jsx_runtime_1.jsxs)("div", { className: "flex min-h-0 min-w-0 flex-1 flex-col overflow-hidden", children: [(0, jsx_runtime_1.jsx)("div", { className: "relative min-h-0 min-w-0 flex-1", children: chatSlot }), chatFooterSlot] }) })), !previewFullscreen && hasPreviewSlot && ((0, jsx_runtime_1.jsx)("div", { className: "relative hidden w-px shrink-0 bg-rule/30 lg:block", children: (0, jsx_runtime_1.jsx)("button", { type: "button", onMouseDown: startResize, "aria-label": "Resize chat and preview panels", title: "Drag to resize", className: "group absolute inset-y-0 left-1/2 w-2 -translate-x-1/2 cursor-col-resize", children: (0, jsx_runtime_1.jsx)("span", { "aria-hidden": true, className: "absolute inset-y-0 left-1/2 w-px -translate-x-1/2 bg-transparent transition-colors group-hover:bg-primary/40" }) }) })), hasPreviewSlot && ((0, jsx_runtime_1.jsxs)("div", { className: "flex min-w-0 flex-1 flex-col overflow-hidden bg-paper", children: [rightHeaderSlot, (0, jsx_runtime_1.jsx)("div", { className: "min-h-0 flex-1 overflow-hidden", children: previewSlot })] }))] }));
8
+ const leftPaneStyle = hasPreviewSlot
9
+ ? {
10
+ '--sws-min-left': `${minLeftPaneWidth}px`,
11
+ '--sws-chat-pct': `${chatPanePercent}%`,
12
+ }
13
+ : undefined;
14
+ return ((0, jsx_runtime_1.jsxs)("div", { ref: splitContainerRef, className: (0, cn_1.cn)('relative flex h-full w-full flex-col overflow-hidden lg:flex-row', isResizing && 'cursor-col-resize'), children: [!previewFullscreen && ((0, jsx_runtime_1.jsx)("div", { className: (0, cn_1.cn)('flex w-full min-h-0 flex-col overflow-hidden bg-paper', hasPreviewSlot
15
+ ? 'flex-1 lg:h-full lg:w-[var(--sws-chat-pct)] lg:min-w-[var(--sws-min-left)] lg:flex-none'
16
+ : 'h-full'), style: leftPaneStyle, children: (0, jsx_runtime_1.jsxs)("div", { className: "flex min-h-0 min-w-0 flex-1 flex-col overflow-hidden", children: [(0, jsx_runtime_1.jsx)("div", { className: "relative min-h-0 min-w-0 flex-1", children: chatSlot }), chatFooterSlot] }) })), !previewFullscreen && hasPreviewSlot && ((0, jsx_runtime_1.jsx)("div", { className: "relative hidden w-px shrink-0 bg-rule/30 lg:block", children: (0, jsx_runtime_1.jsx)("button", { type: "button", onMouseDown: startResize, "aria-label": "Resize chat and preview panels", title: "Drag to resize", className: "group absolute inset-y-0 left-1/2 w-2 -translate-x-1/2 cursor-col-resize", children: (0, jsx_runtime_1.jsx)("span", { "aria-hidden": true, className: "absolute inset-y-0 left-1/2 w-px -translate-x-1/2 bg-transparent transition-colors group-hover:bg-primary/40" }) }) })), hasPreviewSlot && ((0, jsx_runtime_1.jsxs)("div", { className: "flex min-h-0 min-w-0 flex-1 flex-col overflow-hidden bg-paper", children: [rightHeaderSlot, (0, jsx_runtime_1.jsx)("div", { className: "min-h-0 flex-1 overflow-hidden", children: previewSlot })] }))] }));
14
17
  }
15
18
  //# sourceMappingURL=SessionWorkspaceShell.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"SessionWorkspaceShell.js","sourceRoot":"","sources":["../../../src/session/shell/SessionWorkspaceShell.tsx"],"names":[],"mappings":";;AAiEA,sDA2EC;;AA1ID,kCAA+B;AA+D/B,SAAgB,qBAAqB,CAAC,EACpC,iBAAiB,EACjB,eAAe,EACf,UAAU,EACV,WAAW,EACX,QAAQ,EACR,WAAW,EACX,eAAe,EACf,cAAc,EACd,iBAAiB,GAAG,KAAK,EACzB,gBAAgB,GAAG,GAAG,GACK;IAI3B,MAAM,cAAc,GAAG,WAAW,KAAK,IAAI,CAAC;IAC5C,OAAO,CACL,iCACE,GAAG,EAAE,iBAAiB,EACtB,SAAS,EAAE,IAAA,OAAE,EACX,6CAA6C,EAC7C,UAAU,IAAI,mBAAmB,CAClC,aAEA,CAAC,iBAAiB,IAAI,CACrB,gCACE,SAAS,EAAE,IAAA,OAAE,EACX,sDAAsD,EACtD,cAAc,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,EAAE,CACrC,EACD,KAAK,EACH,cAAc;oBACZ,CAAC,CAAC;wBACE,QAAQ,EAAE,GAAG,gBAAgB,IAAI;wBACjC,KAAK,EAAE,GAAG,eAAe,GAAG;qBAC7B;oBACH,CAAC,CAAC,SAAS,YAGf,iCAAK,SAAS,EAAC,sDAAsD,aACnE,gCAAK,SAAS,EAAC,iCAAiC,YAAE,QAAQ,GAAO,EAChE,cAAc,IACX,GACF,CACP,EAEA,CAAC,iBAAiB,IAAI,cAAc,IAAI,CACvC,gCAAK,SAAS,EAAC,mDAAmD,YAKhE,mCACE,IAAI,EAAC,QAAQ,EACb,WAAW,EAAE,WAAW,gBACb,gCAAgC,EAC3C,KAAK,EAAC,gBAAgB,EACtB,SAAS,EAAC,0EAA0E,YAEpF,sDAEE,SAAS,EAAC,8GAA8G,GACxH,GACK,GACL,CACP,EAEA,cAAc,IAAI,CACjB,iCAAK,SAAS,EAAC,uDAAuD,aACnE,eAAe,EAChB,gCAAK,SAAS,EAAC,gCAAgC,YAAE,WAAW,GAAO,IAC/D,CACP,IACG,CACP,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"SessionWorkspaceShell.js","sourceRoot":"","sources":["../../../src/session/shell/SessionWorkspaceShell.tsx"],"names":[],"mappings":";;AAiEA,sDAiFC;;AAhJD,kCAA+B;AA+D/B,SAAgB,qBAAqB,CAAC,EACpC,iBAAiB,EACjB,eAAe,EACf,UAAU,EACV,WAAW,EACX,QAAQ,EACR,WAAW,EACX,eAAe,EACf,cAAc,EACd,iBAAiB,GAAG,KAAK,EACzB,gBAAgB,GAAG,GAAG,GACK;IAI3B,MAAM,cAAc,GAAG,WAAW,KAAK,IAAI,CAAC;IAM5C,MAAM,aAAa,GAA8B,cAAc;QAC7D,CAAC,CAAE;YACC,gBAAgB,EAAE,GAAG,gBAAgB,IAAI;YACzC,gBAAgB,EAAE,GAAG,eAAe,GAAG;SACtB;QACrB,CAAC,CAAC,SAAS,CAAC;IACd,OAAO,CACL,iCACE,GAAG,EAAE,iBAAiB,EACtB,SAAS,EAAE,IAAA,OAAE,EACX,kEAAkE,EAClE,UAAU,IAAI,mBAAmB,CAClC,aAEA,CAAC,iBAAiB,IAAI,CACrB,gCACE,SAAS,EAAE,IAAA,OAAE,EACX,uDAAuD,EACvD,cAAc;oBACZ,CAAC,CAAC,yFAAyF;oBAC3F,CAAC,CAAC,QAAQ,CACb,EACD,KAAK,EAAE,aAAa,YAEpB,iCAAK,SAAS,EAAC,sDAAsD,aACnE,gCAAK,SAAS,EAAC,iCAAiC,YAAE,QAAQ,GAAO,EAChE,cAAc,IACX,GACF,CACP,EAEA,CAAC,iBAAiB,IAAI,cAAc,IAAI,CACvC,gCAAK,SAAS,EAAC,mDAAmD,YAKhE,mCACE,IAAI,EAAC,QAAQ,EACb,WAAW,EAAE,WAAW,gBACb,gCAAgC,EAC3C,KAAK,EAAC,gBAAgB,EACtB,SAAS,EAAC,0EAA0E,YAEpF,sDAEE,SAAS,EAAC,8GAA8G,GACxH,GACK,GACL,CACP,EAEA,cAAc,IAAI,CACjB,iCAAK,SAAS,EAAC,+DAA+D,aAC3E,eAAe,EAChB,gCAAK,SAAS,EAAC,gCAAgC,YAAE,WAAW,GAAO,IAC/D,CACP,IACG,CACP,CAAC;AACJ,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xemahq/ui-kernel",
3
- "version": "0.3.0",
3
+ "version": "0.4.0",
4
4
  "description": "Host-framework-agnostic UI kernel for the Xema OS. Defines the SystemBus orchestration contract (capability.invoke, cross-biome intents, command palette, xema:// deeplinks, window manager) AND the biome-host contract surface (FrontendBiome/FrontendBiomeFactory, HostBridge, the singleton biomeRegistry, session contributions) that every frontend biome composes against. No Vite, Next.js, or React-Router — React itself IS allowed as the shared component model (the contracts traffic in ReactNode/ComponentType and a React context). Concrete host adapters (router/auth/toast wiring) live in separate packages that consume this kernel. The SystemBus is pure orchestration: it never authorizes, the backend capability-router enforces all policy.",
5
5
  "keywords": [
6
6
  "xema",
@@ -0,0 +1,161 @@
1
+ /**
2
+ * `defineWebBiome` — the authoring helper for `target: 'web'` biomes.
3
+ *
4
+ * Every web biome used to hand-repeat the same ~30 lines: one
5
+ * `lazy(() => import('./pages/X'))` per page, a `navItems` array, and a
6
+ * parallel `routes` array — writing the slug TWICE (once as `navItem.route`,
7
+ * once as `route.path`), the classic source of "nav points at a path no route
8
+ * serves" bugs.
9
+ *
10
+ * `defineWebBiome` collapses that to one declarative page list. Each
11
+ * {@link WebBiomePage} single-sources its `slug` for BOTH the nav route and the
12
+ * route path, so they can never drift. The helper emits one nav item (unless
13
+ * `navHidden`) and one route per page, wrapping the lazily-loaded page in a
14
+ * `<Suspense fallback={null}>` boundary via {@link lazyRoute}.
15
+ *
16
+ * Authors declare WHAT each surface is (`category`) and let the HOST own WHERE
17
+ * it renders in the global menu — preferring `category` over the legacy
18
+ * `section`/`weight`. `init`/`dispose`/`panels`/`session`/`outputRenderers`
19
+ * pass through to the `FrontendBiome` untouched, so bespoke biomes (one-shot
20
+ * registrations, slot fillers, session contributions) still use this helper.
21
+ *
22
+ * Host-framework-agnostic: pure React (`lazy`/`Suspense`/`createElement` via
23
+ * `lazyRoute`), no router and no Next.js.
24
+ *
25
+ * @example
26
+ * export default defineWebBiome({
27
+ * id: 'spaces-web',
28
+ * displayName: 'Spaces',
29
+ * pages: [
30
+ * {
31
+ * slug: 'system/spaces',
32
+ * label: 'Spaces',
33
+ * icon: Layers,
34
+ * category: 'knowledge',
35
+ * load: () => import('./pages/SpacesPage'),
36
+ * },
37
+ * ],
38
+ * });
39
+ */
40
+
41
+ import { lazyRoute } from './biome-builders';
42
+
43
+ import type {
44
+ FrontendBiome,
45
+ FrontendBiomeFactory,
46
+ NavItemContribution,
47
+ RouteAccess,
48
+ RouteContribution,
49
+ } from './frontend-biome';
50
+ import type { ComponentType } from 'react';
51
+
52
+ export interface WebBiomePage {
53
+ /**
54
+ * Single source of truth for BOTH the nav route AND the route path — the
55
+ * helper sets `navItem.route === route.path === slug`, so they can never
56
+ * diverge. May include `:param` segments (e.g. `system/concepts/:slug`).
57
+ */
58
+ readonly slug: string;
59
+ /**
60
+ * Stable nav-item id used for active-state matching + analytics. Defaults to
61
+ * {@link slug} when omitted — pass it explicitly only to preserve a
62
+ * pre-existing short id (e.g. `grants`) that differs from the route slug
63
+ * (`system/grants`). Must be unique across the biome's pages.
64
+ */
65
+ readonly id?: string;
66
+ /** Displayed nav label. */
67
+ readonly label: string;
68
+ /** Optional nav icon. Typed to match {@link NavItemContribution.icon}. */
69
+ readonly icon?: ComponentType<{ className?: string | undefined }>;
70
+ /**
71
+ * Host menu category — the biome's INTENT (`primary` | `build` | `operate` |
72
+ * `knowledge` | `admin` | `account`). The host maps it to a concrete rail
73
+ * group + order. Prefer this over `weight`.
74
+ */
75
+ readonly category?: string;
76
+ /**
77
+ * Route scope. `'org'` (default) mounts at the org root; `'project'` mounts
78
+ * under `/projects/:projectId`. Maps to {@link RouteContribution.projectScoped}.
79
+ */
80
+ readonly scope?: 'org' | 'project';
81
+ /** Access tier required to render the route. Defaults to `'member'`. */
82
+ readonly access?: RouteAccess;
83
+ /** Dynamic import of the page module (`() => import('./pages/X')`). */
84
+ readonly load: () => Promise<{ default: ComponentType<unknown> }>;
85
+ /**
86
+ * Optional legacy intra-category sort weight. Prefer host-owned `category`
87
+ * ordering; retained only as a tiebreak for un-migrated taxonomies.
88
+ */
89
+ readonly weight?: number;
90
+ /**
91
+ * When true the route is registered but NO nav item is emitted — for hidden
92
+ * surfaces such as a `:param` detail route reached only by deeplink.
93
+ */
94
+ readonly navHidden?: boolean;
95
+ }
96
+
97
+ export interface DefineWebBiomeOptions {
98
+ /** Stable biome id; matches `xema-biome.json` `xema.id`. */
99
+ readonly id: string;
100
+ /** Displayed name. */
101
+ readonly displayName: string;
102
+ /** One-shot initializer; passed through to {@link FrontendBiome.init}. */
103
+ readonly init?: FrontendBiome['init'];
104
+ /** Teardown counterpart; passed through to {@link FrontendBiome.dispose}. */
105
+ readonly dispose?: FrontendBiome['dispose'];
106
+ /** The biome's pages — one nav item (unless `navHidden`) + one route each. */
107
+ readonly pages: readonly WebBiomePage[];
108
+ /** Slot fillers; passed through to {@link FrontendBiome.panels}. */
109
+ readonly panels?: FrontendBiome['panels'];
110
+ /** Session-shell contributions; passed through to {@link FrontendBiome.session}. */
111
+ readonly session?: FrontendBiome['session'];
112
+ /** Output renderers; passed through to {@link FrontendBiome.outputRenderers}. */
113
+ readonly outputRenderers?: FrontendBiome['outputRenderers'];
114
+ }
115
+
116
+ /**
117
+ * Build the `FrontendBiomeFactory` a web biome default-exports. See the
118
+ * module doc-comment for the rationale and an example.
119
+ */
120
+ export function defineWebBiome(
121
+ options: DefineWebBiomeOptions,
122
+ ): FrontendBiomeFactory {
123
+ return () => {
124
+ const navItems: NavItemContribution[] = [];
125
+ const routes: RouteContribution[] = [];
126
+
127
+ for (const page of options.pages) {
128
+ routes.push({
129
+ path: page.slug,
130
+ projectScoped: page.scope === 'project',
131
+ element: lazyRoute(page.load),
132
+ ...(page.access ? { access: page.access } : {}),
133
+ });
134
+
135
+ if (!page.navHidden) {
136
+ navItems.push({
137
+ id: page.id ?? page.slug,
138
+ label: page.label,
139
+ route: page.slug,
140
+ ...(page.icon ? { icon: page.icon } : {}),
141
+ ...(page.category !== undefined ? { category: page.category } : {}),
142
+ ...(page.weight !== undefined ? { weight: page.weight } : {}),
143
+ });
144
+ }
145
+ }
146
+
147
+ return {
148
+ id: options.id,
149
+ displayName: options.displayName,
150
+ navItems,
151
+ routes,
152
+ ...(options.init ? { init: options.init } : {}),
153
+ ...(options.dispose ? { dispose: options.dispose } : {}),
154
+ ...(options.panels ? { panels: options.panels } : {}),
155
+ ...(options.session ? { session: options.session } : {}),
156
+ ...(options.outputRenderers
157
+ ? { outputRenderers: options.outputRenderers }
158
+ : {}),
159
+ };
160
+ };
161
+ }
@@ -27,9 +27,27 @@ export interface NavItemContribution {
27
27
  * className it computes from its own theme.
28
28
  */
29
29
  readonly icon?: ComponentType<{ className?: string | undefined }>;
30
- /** Section grouping key (matches host nav-registry sections). */
30
+ /**
31
+ * Semantic menu category the biome declares its INTENT to live in (e.g.
32
+ * `build`, `operate`, `knowledge`, `account`). The HOST owns the menu
33
+ * information-architecture: it maps a category to a concrete rail group,
34
+ * heading, and order. Authors declare WHAT a surface is, not WHERE in the
35
+ * global menu it renders — so the platform can re-organise the menu without
36
+ * editing every biome. Prefer this over `section`/`weight`. When omitted,
37
+ * the host falls back to its own taxonomy (keyed on the nav-item id) and,
38
+ * last, to the legacy `section`.
39
+ */
40
+ readonly category?: string;
41
+ /**
42
+ * @deprecated Legacy direct section-heading placement. The host now owns
43
+ * grouping via `category` + its taxonomy; retained only until every biome
44
+ * declares a `category`. Do NOT use in new biomes.
45
+ */
31
46
  readonly section?: string;
32
- /** Sort weight within the section (lower first). Defaults to 100. */
47
+ /**
48
+ * @deprecated Legacy intra-section sort weight. Ordering is host-owned per
49
+ * category now. Retained only for un-migrated biomes.
50
+ */
33
51
  readonly weight?: number;
34
52
  }
35
53
 
@@ -18,6 +18,7 @@ export * from './biome-navigation';
18
18
  export * from './biome-scope';
19
19
  export * from './biome-scoped-query';
20
20
  export * from './biome-builders';
21
+ export * from './define-web-biome';
21
22
  export * from './create-biome-orval-config';
22
23
  export * from './biome-registry';
23
24
  export * from './session-contributions';
@@ -1,4 +1,4 @@
1
- import type { ReactNode, MouseEvent, RefObject } from 'react';
1
+ import type { CSSProperties, ReactNode, MouseEvent, RefObject } from 'react';
2
2
 
3
3
  import { cn } from '../lib/cn';
4
4
 
@@ -79,28 +79,34 @@ export function SessionWorkspaceShell({
79
79
  // surface (Document Buddy). Hide the right pane + resize handle and
80
80
  // let the chat pane occupy the full width.
81
81
  const hasPreviewSlot = previewSlot !== null;
82
+ // Below `lg` the two panes stack vertically (flex-col) and each takes the
83
+ // full width; the chat pane's fixed width / minWidth split only applies at
84
+ // `lg`+ where the resize handle is available. The width values ride on CSS
85
+ // variables so the inline style never forces a side-by-side split on a
86
+ // phone (Tailwind applies them only at the `lg` breakpoint).
87
+ const leftPaneStyle: CSSProperties | undefined = hasPreviewSlot
88
+ ? ({
89
+ '--sws-min-left': `${minLeftPaneWidth}px`,
90
+ '--sws-chat-pct': `${chatPanePercent}%`,
91
+ } as CSSProperties)
92
+ : undefined;
82
93
  return (
83
94
  <div
84
95
  ref={splitContainerRef}
85
96
  className={cn(
86
- 'relative flex h-full w-full overflow-hidden',
97
+ 'relative flex h-full w-full flex-col overflow-hidden lg:flex-row',
87
98
  isResizing && 'cursor-col-resize',
88
99
  )}
89
100
  >
90
101
  {!previewFullscreen && (
91
102
  <div
92
103
  className={cn(
93
- 'flex h-full w-full flex-col overflow-hidden bg-paper',
94
- hasPreviewSlot ? 'lg:flex-none' : '',
95
- )}
96
- style={
104
+ 'flex w-full min-h-0 flex-col overflow-hidden bg-paper',
97
105
  hasPreviewSlot
98
- ? {
99
- minWidth: `${minLeftPaneWidth}px`,
100
- width: `${chatPanePercent}%`,
101
- }
102
- : undefined
103
- }
106
+ ? 'flex-1 lg:h-full lg:w-[var(--sws-chat-pct)] lg:min-w-[var(--sws-min-left)] lg:flex-none'
107
+ : 'h-full',
108
+ )}
109
+ style={leftPaneStyle}
104
110
  >
105
111
  <div className="flex min-h-0 min-w-0 flex-1 flex-col overflow-hidden">
106
112
  <div className="relative min-h-0 min-w-0 flex-1">{chatSlot}</div>
@@ -131,7 +137,7 @@ export function SessionWorkspaceShell({
131
137
  )}
132
138
 
133
139
  {hasPreviewSlot && (
134
- <div className="flex min-w-0 flex-1 flex-col overflow-hidden bg-paper">
140
+ <div className="flex min-h-0 min-w-0 flex-1 flex-col overflow-hidden bg-paper">
135
141
  {rightHeaderSlot}
136
142
  <div className="min-h-0 flex-1 overflow-hidden">{previewSlot}</div>
137
143
  </div>