@xemahq/ui-kernel 0.1.6 → 0.1.7
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/dist/lib/biome-host/create-biome-orval-config.d.ts +14 -0
- package/dist/lib/biome-host/create-biome-orval-config.d.ts.map +1 -0
- package/dist/lib/biome-host/create-biome-orval-config.js +22 -0
- package/dist/lib/biome-host/create-biome-orval-config.js.map +1 -0
- package/dist/lib/biome-host/host-bridge.d.ts +2 -0
- package/dist/lib/biome-host/host-bridge.d.ts.map +1 -1
- package/dist/lib/biome-host/host-bridge.js.map +1 -1
- package/dist/lib/biome-host/host-sources.d.ts +2 -0
- package/dist/lib/biome-host/host-sources.d.ts.map +1 -1
- package/dist/lib/biome-host/index.d.ts +1 -0
- package/dist/lib/biome-host/index.d.ts.map +1 -1
- package/dist/lib/biome-host/index.js +1 -0
- package/dist/lib/biome-host/index.js.map +1 -1
- package/dist/session-kit/approvals/ApprovalButton.d.ts +14 -0
- package/dist/session-kit/approvals/ApprovalButton.d.ts.map +1 -0
- package/dist/session-kit/approvals/ApprovalButton.js +45 -0
- package/dist/session-kit/approvals/ApprovalButton.js.map +1 -0
- package/dist/session-kit/approvals/ApprovalCard.d.ts +12 -0
- package/dist/session-kit/approvals/ApprovalCard.d.ts.map +1 -0
- package/dist/session-kit/approvals/ApprovalCard.js +117 -0
- package/dist/session-kit/approvals/ApprovalCard.js.map +1 -0
- package/dist/session-kit/approvals/ApprovalsCenter.d.ts +11 -0
- package/dist/session-kit/approvals/ApprovalsCenter.d.ts.map +1 -0
- package/dist/session-kit/approvals/ApprovalsCenter.js +127 -0
- package/dist/session-kit/approvals/ApprovalsCenter.js.map +1 -0
- package/dist/session-kit/approvals/CapabilityApprovalStickyBar.d.ts +12 -0
- package/dist/session-kit/approvals/CapabilityApprovalStickyBar.d.ts.map +1 -0
- package/dist/session-kit/approvals/CapabilityApprovalStickyBar.js +36 -0
- package/dist/session-kit/approvals/CapabilityApprovalStickyBar.js.map +1 -0
- package/dist/session-kit/approvals/Obligation.d.ts +15 -0
- package/dist/session-kit/approvals/Obligation.d.ts.map +1 -0
- package/dist/session-kit/approvals/Obligation.js +42 -0
- package/dist/session-kit/approvals/Obligation.js.map +1 -0
- package/dist/session-kit/approvals/ScopedBody.d.ts +9 -0
- package/dist/session-kit/approvals/ScopedBody.d.ts.map +1 -0
- package/dist/session-kit/approvals/ScopedBody.js +145 -0
- package/dist/session-kit/approvals/ScopedBody.js.map +1 -0
- package/dist/session-kit/approvals/approval-icons.d.ts +15 -0
- package/dist/session-kit/approvals/approval-icons.d.ts.map +1 -0
- package/dist/session-kit/approvals/approval-icons.js +3 -0
- package/dist/session-kit/approvals/approval-icons.js.map +1 -0
- package/dist/session-kit/approvals/approval-model.d.ts +83 -0
- package/dist/session-kit/approvals/approval-model.d.ts.map +1 -0
- package/dist/session-kit/approvals/approval-model.js +25 -0
- package/dist/session-kit/approvals/approval-model.js.map +1 -0
- package/dist/session-kit/approvals/index.d.ts +12 -0
- package/dist/session-kit/approvals/index.d.ts.map +1 -0
- package/dist/session-kit/approvals/index.js +28 -0
- package/dist/session-kit/approvals/index.js.map +1 -0
- package/dist/session-kit/approvals/obligation-display.d.ts +17 -0
- package/dist/session-kit/approvals/obligation-display.d.ts.map +1 -0
- package/dist/session-kit/approvals/obligation-display.js +58 -0
- package/dist/session-kit/approvals/obligation-display.js.map +1 -0
- package/dist/session-kit/approvals/risk-accent.d.ts +8 -0
- package/dist/session-kit/approvals/risk-accent.d.ts.map +1 -0
- package/dist/session-kit/approvals/risk-accent.js +28 -0
- package/dist/session-kit/approvals/risk-accent.js.map +1 -0
- package/dist/session-kit/approvals/scope-icons.d.ts +12 -0
- package/dist/session-kit/approvals/scope-icons.d.ts.map +1 -0
- package/dist/session-kit/approvals/scope-icons.js +14 -0
- package/dist/session-kit/approvals/scope-icons.js.map +1 -0
- package/dist/session-kit/combobox/Combobox.d.ts +46 -0
- package/dist/session-kit/combobox/Combobox.d.ts.map +1 -0
- package/dist/session-kit/combobox/Combobox.js +113 -0
- package/dist/session-kit/combobox/Combobox.js.map +1 -0
- package/dist/session-kit/combobox/use-click-outside.d.ts +3 -0
- package/dist/session-kit/combobox/use-click-outside.d.ts.map +1 -0
- package/dist/session-kit/combobox/use-click-outside.js +18 -0
- package/dist/session-kit/combobox/use-click-outside.js.map +1 -0
- package/dist/session-kit/display/ContextHeader.d.ts +27 -0
- package/dist/session-kit/display/ContextHeader.d.ts.map +1 -0
- package/dist/session-kit/display/ContextHeader.js +47 -0
- package/dist/session-kit/display/ContextHeader.js.map +1 -0
- package/dist/session-kit/display/FileDiffCard.d.ts +18 -0
- package/dist/session-kit/display/FileDiffCard.d.ts.map +1 -0
- package/dist/session-kit/display/FileDiffCard.js +58 -0
- package/dist/session-kit/display/FileDiffCard.js.map +1 -0
- package/dist/session-kit/display/MD.d.ts +7 -0
- package/dist/session-kit/display/MD.d.ts.map +1 -0
- package/dist/session-kit/display/MD.js +89 -0
- package/dist/session-kit/display/MD.js.map +1 -0
- package/dist/session-kit/display/MessageTurn.d.ts +21 -0
- package/dist/session-kit/display/MessageTurn.d.ts.map +1 -0
- package/dist/session-kit/display/MessageTurn.js +62 -0
- package/dist/session-kit/display/MessageTurn.js.map +1 -0
- package/dist/session-kit/display/ThinkingPanel.d.ts +12 -0
- package/dist/session-kit/display/ThinkingPanel.d.ts.map +1 -0
- package/dist/session-kit/display/ThinkingPanel.js +30 -0
- package/dist/session-kit/display/ThinkingPanel.js.map +1 -0
- package/dist/session-kit/display/TodoChecklist.d.ts +17 -0
- package/dist/session-kit/display/TodoChecklist.d.ts.map +1 -0
- package/dist/session-kit/display/TodoChecklist.js +50 -0
- package/dist/session-kit/display/TodoChecklist.js.map +1 -0
- package/dist/session-kit/display/TokenMeter.d.ts +15 -0
- package/dist/session-kit/display/TokenMeter.d.ts.map +1 -0
- package/dist/session-kit/display/TokenMeter.js +35 -0
- package/dist/session-kit/display/TokenMeter.js.map +1 -0
- package/dist/session-kit/display/ToolStrip.d.ts +31 -0
- package/dist/session-kit/display/ToolStrip.d.ts.map +1 -0
- package/dist/session-kit/display/ToolStrip.js +99 -0
- package/dist/session-kit/display/ToolStrip.js.map +1 -0
- package/dist/session-kit/display/TypingDots.d.ts +3 -0
- package/dist/session-kit/display/TypingDots.d.ts.map +1 -0
- package/dist/session-kit/display/TypingDots.js +14 -0
- package/dist/session-kit/display/TypingDots.js.map +1 -0
- package/dist/session-kit/index.d.ts +21 -0
- package/dist/session-kit/index.d.ts.map +1 -0
- package/dist/session-kit/index.js +37 -0
- package/dist/session-kit/index.js.map +1 -0
- package/dist/session-kit/lib/enums.d.ts +34 -0
- package/dist/session-kit/lib/enums.d.ts.map +1 -0
- package/dist/session-kit/lib/enums.js +44 -0
- package/dist/session-kit/lib/enums.js.map +1 -0
- package/dist/session-kit/lib/portal-accent.d.ts +3 -0
- package/dist/session-kit/lib/portal-accent.d.ts.map +1 -0
- package/dist/session-kit/lib/portal-accent.js +9 -0
- package/dist/session-kit/lib/portal-accent.js.map +1 -0
- package/dist/session-kit/lib/status-dot.d.ts +10 -0
- package/dist/session-kit/lib/status-dot.d.ts.map +1 -0
- package/dist/session-kit/lib/status-dot.js +43 -0
- package/dist/session-kit/lib/status-dot.js.map +1 -0
- package/dist/session-kit/primitives/Avatar.d.ts +10 -0
- package/dist/session-kit/primitives/Avatar.d.ts.map +1 -0
- package/dist/session-kit/primitives/Avatar.js +21 -0
- package/dist/session-kit/primitives/Avatar.js.map +1 -0
- package/dist/session-kit/primitives/PortalGlyph.d.ts +12 -0
- package/dist/session-kit/primitives/PortalGlyph.d.ts.map +1 -0
- package/dist/session-kit/primitives/PortalGlyph.js +21 -0
- package/dist/session-kit/primitives/PortalGlyph.js.map +1 -0
- package/dist/session-kit/primitives/RiskPill.d.ts +12 -0
- package/dist/session-kit/primitives/RiskPill.d.ts.map +1 -0
- package/dist/session-kit/primitives/RiskPill.js +53 -0
- package/dist/session-kit/primitives/RiskPill.js.map +1 -0
- package/dist/session-kit/primitives/ScopeDot.d.ts +9 -0
- package/dist/session-kit/primitives/ScopeDot.d.ts.map +1 -0
- package/dist/session-kit/primitives/ScopeDot.js +23 -0
- package/dist/session-kit/primitives/ScopeDot.js.map +1 -0
- package/dist/session-kit/primitives/Segmented.d.ts +16 -0
- package/dist/session-kit/primitives/Segmented.d.ts.map +1 -0
- package/dist/session-kit/primitives/Segmented.js +31 -0
- package/dist/session-kit/primitives/Segmented.js.map +1 -0
- package/package.json +2 -2
- package/src/lib/biome-host/create-biome-orval-config.ts +76 -0
- package/src/lib/biome-host/host-bridge.ts +22 -0
- package/src/lib/biome-host/host-sources.ts +13 -0
- package/src/lib/biome-host/index.ts +1 -0
- package/src/session-kit/approvals/ApprovalButton.tsx +89 -0
- package/src/session-kit/approvals/ApprovalCard.tsx +336 -0
- package/src/session-kit/approvals/ApprovalsCenter.tsx +327 -0
- package/src/session-kit/approvals/CapabilityApprovalStickyBar.tsx +118 -0
- package/src/session-kit/approvals/Obligation.tsx +111 -0
- package/src/session-kit/approvals/ScopedBody.tsx +392 -0
- package/src/session-kit/approvals/approval-icons.ts +31 -0
- package/src/session-kit/approvals/approval-model.ts +205 -0
- package/src/session-kit/approvals/index.ts +22 -0
- package/src/session-kit/approvals/obligation-display.ts +100 -0
- package/src/session-kit/approvals/risk-accent.ts +47 -0
- package/src/session-kit/approvals/scope-icons.ts +19 -0
- package/src/session-kit/combobox/Combobox.tsx +327 -0
- package/src/session-kit/combobox/use-click-outside.ts +21 -0
- package/src/session-kit/display/ContextHeader.tsx +148 -0
- package/src/session-kit/display/FileDiffCard.tsx +140 -0
- package/src/session-kit/display/MD.tsx +153 -0
- package/src/session-kit/display/MessageTurn.tsx +157 -0
- package/src/session-kit/display/ThinkingPanel.tsx +78 -0
- package/src/session-kit/display/TodoChecklist.tsx +120 -0
- package/src/session-kit/display/TokenMeter.tsx +89 -0
- package/src/session-kit/display/ToolStrip.tsx +278 -0
- package/src/session-kit/display/TypingDots.tsx +24 -0
- package/src/session-kit/index.ts +44 -0
- package/src/session-kit/lib/enums.ts +66 -0
- package/src/session-kit/lib/portal-accent.ts +30 -0
- package/src/session-kit/lib/status-dot.ts +68 -0
- package/src/session-kit/primitives/Avatar.tsx +44 -0
- package/src/session-kit/primitives/PortalGlyph.tsx +51 -0
- package/src/session-kit/primitives/RiskPill.tsx +95 -0
- package/src/session-kit/primitives/ScopeDot.tsx +47 -0
- package/src/session-kit/primitives/Segmented.tsx +71 -0
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { CSSProperties, ReactElement } from 'react';
|
|
2
|
+
export interface AvatarProps {
|
|
3
|
+
readonly initials: string;
|
|
4
|
+
readonly size?: number;
|
|
5
|
+
readonly color?: string;
|
|
6
|
+
readonly ink?: string;
|
|
7
|
+
readonly style?: CSSProperties;
|
|
8
|
+
}
|
|
9
|
+
export declare function Avatar({ initials, size, color, ink, style, }: AvatarProps): ReactElement;
|
|
10
|
+
//# sourceMappingURL=Avatar.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Avatar.d.ts","sourceRoot":"","sources":["../../../src/session-kit/primitives/Avatar.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,OAAO,CAAC;AAEzD,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IAEvB,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IAExB,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,KAAK,CAAC,EAAE,aAAa,CAAC;CAChC;AAED,wBAAgB,MAAM,CAAC,EACrB,QAAQ,EACR,IAAS,EACT,KAAkD,EAClD,GAAkD,EAClD,KAAK,GACN,EAAE,WAAW,GAAG,YAAY,CAsB5B"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Avatar = Avatar;
|
|
4
|
+
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
5
|
+
function Avatar({ initials, size = 26, color = 'hsl(var(--accent-2, var(--accent-tint)))', ink = 'hsl(var(--primary-ink, var(--accent-ink)))', style, }) {
|
|
6
|
+
return ((0, jsx_runtime_1.jsx)("span", { className: "mono", style: {
|
|
7
|
+
width: size,
|
|
8
|
+
height: size,
|
|
9
|
+
borderRadius: '50%',
|
|
10
|
+
flexShrink: 0,
|
|
11
|
+
display: 'grid',
|
|
12
|
+
placeItems: 'center',
|
|
13
|
+
background: color,
|
|
14
|
+
color: ink,
|
|
15
|
+
fontSize: size * 0.4,
|
|
16
|
+
fontWeight: 600,
|
|
17
|
+
letterSpacing: '-0.02em',
|
|
18
|
+
...style,
|
|
19
|
+
}, children: initials }));
|
|
20
|
+
}
|
|
21
|
+
//# sourceMappingURL=Avatar.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Avatar.js","sourceRoot":"","sources":["../../../src/session-kit/primitives/Avatar.tsx"],"names":[],"mappings":";;AAeA,wBA4BC;;AA5BD,SAAgB,MAAM,CAAC,EACrB,QAAQ,EACR,IAAI,GAAG,EAAE,EACT,KAAK,GAAG,0CAA0C,EAClD,GAAG,GAAG,4CAA4C,EAClD,KAAK,GACO;IACZ,OAAO,CACL,iCACE,SAAS,EAAC,MAAM,EAChB,KAAK,EAAE;YACL,KAAK,EAAE,IAAI;YACX,MAAM,EAAE,IAAI;YACZ,YAAY,EAAE,KAAK;YACnB,UAAU,EAAE,CAAC;YACb,OAAO,EAAE,MAAM;YACf,UAAU,EAAE,QAAQ;YACpB,UAAU,EAAE,KAAK;YACjB,KAAK,EAAE,GAAG;YACV,QAAQ,EAAE,IAAI,GAAG,GAAG;YACpB,UAAU,EAAE,GAAG;YACf,aAAa,EAAE,SAAS;YACxB,GAAG,KAAK;SACT,YAEA,QAAQ,GACJ,CACR,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { type PortalAccentVar } from '../lib/portal-accent';
|
|
2
|
+
import type { CSSProperties, ReactElement, ReactNode } from 'react';
|
|
3
|
+
export interface PortalGlyphProps {
|
|
4
|
+
readonly accentVar?: PortalAccentVar;
|
|
5
|
+
readonly icon: ReactNode;
|
|
6
|
+
readonly size?: number;
|
|
7
|
+
readonly radius?: number;
|
|
8
|
+
readonly active?: boolean;
|
|
9
|
+
readonly style?: CSSProperties;
|
|
10
|
+
}
|
|
11
|
+
export declare function PortalGlyph({ accentVar, icon, size, radius, active, style, }: PortalGlyphProps): ReactElement;
|
|
12
|
+
//# sourceMappingURL=PortalGlyph.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PortalGlyph.d.ts","sourceRoot":"","sources":["../../../src/session-kit/primitives/PortalGlyph.tsx"],"names":[],"mappings":"AAMA,OAAO,EAAgB,KAAK,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAE1E,OAAO,KAAK,EAAE,aAAa,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAGpE,MAAM,WAAW,gBAAgB;IAE/B,QAAQ,CAAC,SAAS,CAAC,EAAE,eAAe,CAAC;IAErC,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC;IACzB,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IAEzB,QAAQ,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC;IAC1B,QAAQ,CAAC,KAAK,CAAC,EAAE,aAAa,CAAC;CAChC;AAED,wBAAgB,WAAW,CAAC,EAC1B,SAAS,EACT,IAAI,EACJ,IAAS,EACT,MAAU,EACV,MAAc,EACd,KAAK,GACN,EAAE,gBAAgB,GAAG,YAAY,CAoBjC"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.PortalGlyph = PortalGlyph;
|
|
4
|
+
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
5
|
+
const portal_accent_1 = require("../lib/portal-accent");
|
|
6
|
+
function PortalGlyph({ accentVar, icon, size = 34, radius = 9, active = false, style, }) {
|
|
7
|
+
return ((0, jsx_runtime_1.jsx)("span", { style: {
|
|
8
|
+
width: size,
|
|
9
|
+
height: size,
|
|
10
|
+
borderRadius: radius,
|
|
11
|
+
flexShrink: 0,
|
|
12
|
+
display: 'grid',
|
|
13
|
+
placeItems: 'center',
|
|
14
|
+
background: (0, portal_accent_1.portalAccent)(accentVar, 0.13),
|
|
15
|
+
color: (0, portal_accent_1.portalAccent)(accentVar),
|
|
16
|
+
border: `1px solid ${(0, portal_accent_1.portalAccent)(accentVar, active ? 0.5 : 0.22)}`,
|
|
17
|
+
boxShadow: active ? `0 0 0 1px ${(0, portal_accent_1.portalAccent)(accentVar, 0.25)}` : 'none',
|
|
18
|
+
...style,
|
|
19
|
+
}, children: icon }));
|
|
20
|
+
}
|
|
21
|
+
//# sourceMappingURL=PortalGlyph.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PortalGlyph.js","sourceRoot":"","sources":["../../../src/session-kit/primitives/PortalGlyph.tsx"],"names":[],"mappings":";;AAuBA,kCA2BC;;AA5CD,wDAA0E;AAiB1E,SAAgB,WAAW,CAAC,EAC1B,SAAS,EACT,IAAI,EACJ,IAAI,GAAG,EAAE,EACT,MAAM,GAAG,CAAC,EACV,MAAM,GAAG,KAAK,EACd,KAAK,GACY;IACjB,OAAO,CACL,iCACE,KAAK,EAAE;YACL,KAAK,EAAE,IAAI;YACX,MAAM,EAAE,IAAI;YACZ,YAAY,EAAE,MAAM;YACpB,UAAU,EAAE,CAAC;YACb,OAAO,EAAE,MAAM;YACf,UAAU,EAAE,QAAQ;YACpB,UAAU,EAAE,IAAA,4BAAY,EAAC,SAAS,EAAE,IAAI,CAAC;YACzC,KAAK,EAAE,IAAA,4BAAY,EAAC,SAAS,CAAC;YAC9B,MAAM,EAAE,aAAa,IAAA,4BAAY,EAAC,SAAS,EAAE,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE;YACnE,SAAS,EAAE,MAAM,CAAC,CAAC,CAAC,aAAa,IAAA,4BAAY,EAAC,SAAS,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM;YACzE,GAAG,KAAK;SACT,YAEA,IAAI,GACA,CACR,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { CapabilityRiskTier } from '@xemahq/kernel-contracts/capability';
|
|
2
|
+
import type { CSSProperties, ReactElement, ReactNode } from 'react';
|
|
3
|
+
export { CapabilityRiskTier };
|
|
4
|
+
export type RiskPillSize = 'xs' | 'sm';
|
|
5
|
+
export interface RiskPillProps {
|
|
6
|
+
readonly tier: CapabilityRiskTier;
|
|
7
|
+
readonly size?: RiskPillSize;
|
|
8
|
+
readonly criticalIcon?: ReactNode;
|
|
9
|
+
readonly style?: CSSProperties;
|
|
10
|
+
}
|
|
11
|
+
export declare function RiskPill({ tier, size, criticalIcon, style, }: RiskPillProps): ReactElement;
|
|
12
|
+
//# sourceMappingURL=RiskPill.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"RiskPill.d.ts","sourceRoot":"","sources":["../../../src/session-kit/primitives/RiskPill.tsx"],"names":[],"mappings":"AAYA,OAAO,EAAE,kBAAkB,EAAE,MAAM,qCAAqC,CAAC;AAEzE,OAAO,KAAK,EAAE,aAAa,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAEpE,OAAO,EAAE,kBAAkB,EAAE,CAAC;AAsC9B,MAAM,MAAM,YAAY,GAAG,IAAI,GAAG,IAAI,CAAC;AAEvC,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,IAAI,EAAE,kBAAkB,CAAC;IAClC,QAAQ,CAAC,IAAI,CAAC,EAAE,YAAY,CAAC;IAE7B,QAAQ,CAAC,YAAY,CAAC,EAAE,SAAS,CAAC;IAClC,QAAQ,CAAC,KAAK,CAAC,EAAE,aAAa,CAAC;CAChC;AAED,wBAAgB,QAAQ,CAAC,EACvB,IAAI,EACJ,IAAW,EACX,YAAY,EACZ,KAAK,GACN,EAAE,aAAa,GAAG,YAAY,CAyB9B"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.CapabilityRiskTier = void 0;
|
|
4
|
+
exports.RiskPill = RiskPill;
|
|
5
|
+
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
6
|
+
const capability_1 = require("@xemahq/kernel-contracts/capability");
|
|
7
|
+
Object.defineProperty(exports, "CapabilityRiskTier", { enumerable: true, get: function () { return capability_1.CapabilityRiskTier; } });
|
|
8
|
+
const DANGER = 'var(--destructive, var(--danger))';
|
|
9
|
+
const RISK = {
|
|
10
|
+
[capability_1.CapabilityRiskTier.Low]: {
|
|
11
|
+
label: 'Low',
|
|
12
|
+
fg: 'hsl(var(--ink-3))',
|
|
13
|
+
bg: 'hsl(var(--muted))',
|
|
14
|
+
bd: 'hsl(var(--rule))',
|
|
15
|
+
},
|
|
16
|
+
[capability_1.CapabilityRiskTier.Medium]: {
|
|
17
|
+
label: 'Medium',
|
|
18
|
+
fg: 'hsl(var(--info))',
|
|
19
|
+
bg: 'hsl(var(--info) / 0.09)',
|
|
20
|
+
bd: 'hsl(var(--info) / 0.28)',
|
|
21
|
+
},
|
|
22
|
+
[capability_1.CapabilityRiskTier.High]: {
|
|
23
|
+
label: 'High',
|
|
24
|
+
fg: 'hsl(var(--warning))',
|
|
25
|
+
bg: 'hsl(var(--warning) / 0.1)',
|
|
26
|
+
bd: 'hsl(var(--warning) / 0.3)',
|
|
27
|
+
},
|
|
28
|
+
[capability_1.CapabilityRiskTier.Critical]: {
|
|
29
|
+
label: 'Critical',
|
|
30
|
+
fg: `hsl(${DANGER})`,
|
|
31
|
+
bg: `hsl(${DANGER} / 0.09)`,
|
|
32
|
+
bd: `hsl(${DANGER} / 0.32)`,
|
|
33
|
+
},
|
|
34
|
+
};
|
|
35
|
+
function RiskPill({ tier, size = 'sm', criticalIcon, style, }) {
|
|
36
|
+
const r = RISK[tier];
|
|
37
|
+
return ((0, jsx_runtime_1.jsxs)("span", { className: "mono", style: {
|
|
38
|
+
display: 'inline-flex',
|
|
39
|
+
alignItems: 'center',
|
|
40
|
+
gap: 4,
|
|
41
|
+
padding: size === 'xs' ? '1px 6px' : '2px 8px',
|
|
42
|
+
fontSize: size === 'xs' ? 9.5 : 10,
|
|
43
|
+
fontWeight: 600,
|
|
44
|
+
textTransform: 'uppercase',
|
|
45
|
+
letterSpacing: '0.06em',
|
|
46
|
+
color: r.fg,
|
|
47
|
+
background: r.bg,
|
|
48
|
+
border: `1px solid ${r.bd}`,
|
|
49
|
+
borderRadius: 5,
|
|
50
|
+
...style,
|
|
51
|
+
}, children: [tier === capability_1.CapabilityRiskTier.Critical && criticalIcon, r.label] }));
|
|
52
|
+
}
|
|
53
|
+
//# sourceMappingURL=RiskPill.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"RiskPill.js","sourceRoot":"","sources":["../../../src/session-kit/primitives/RiskPill.tsx"],"names":[],"mappings":";;;AAgEA,4BA8BC;;AAlFD,oEAAyE;AAIhE,mGAJA,+BAAkB,OAIA;AAS3B,MAAM,MAAM,GAAG,mCAAmC,CAAC;AAEnD,MAAM,IAAI,GAA0C;IAClD,CAAC,+BAAkB,CAAC,GAAG,CAAC,EAAE;QACxB,KAAK,EAAE,KAAK;QACZ,EAAE,EAAE,mBAAmB;QACvB,EAAE,EAAE,mBAAmB;QACvB,EAAE,EAAE,kBAAkB;KACvB;IACD,CAAC,+BAAkB,CAAC,MAAM,CAAC,EAAE;QAC3B,KAAK,EAAE,QAAQ;QACf,EAAE,EAAE,kBAAkB;QACtB,EAAE,EAAE,yBAAyB;QAC7B,EAAE,EAAE,yBAAyB;KAC9B;IACD,CAAC,+BAAkB,CAAC,IAAI,CAAC,EAAE;QACzB,KAAK,EAAE,MAAM;QACb,EAAE,EAAE,qBAAqB;QACzB,EAAE,EAAE,2BAA2B;QAC/B,EAAE,EAAE,2BAA2B;KAChC;IACD,CAAC,+BAAkB,CAAC,QAAQ,CAAC,EAAE;QAC7B,KAAK,EAAE,UAAU;QACjB,EAAE,EAAE,OAAO,MAAM,GAAG;QACpB,EAAE,EAAE,OAAO,MAAM,UAAU;QAC3B,EAAE,EAAE,OAAO,MAAM,UAAU;KAC5B;CACF,CAAC;AAYF,SAAgB,QAAQ,CAAC,EACvB,IAAI,EACJ,IAAI,GAAG,IAAI,EACX,YAAY,EACZ,KAAK,GACS;IACd,MAAM,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC;IACrB,OAAO,CACL,kCACE,SAAS,EAAC,MAAM,EAChB,KAAK,EAAE;YACL,OAAO,EAAE,aAAa;YACtB,UAAU,EAAE,QAAQ;YACpB,GAAG,EAAE,CAAC;YACN,OAAO,EAAE,IAAI,KAAK,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS;YAC9C,QAAQ,EAAE,IAAI,KAAK,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE;YAClC,UAAU,EAAE,GAAG;YACf,aAAa,EAAE,WAAW;YAC1B,aAAa,EAAE,QAAQ;YACvB,KAAK,EAAE,CAAC,CAAC,EAAE;YACX,UAAU,EAAE,CAAC,CAAC,EAAE;YAChB,MAAM,EAAE,aAAa,CAAC,CAAC,EAAE,EAAE;YAC3B,YAAY,EAAE,CAAC;YACf,GAAG,KAAK;SACT,aAEA,IAAI,KAAK,+BAAkB,CAAC,QAAQ,IAAI,YAAY,EACpD,CAAC,CAAC,KAAK,IACH,CACR,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { BiomeScope } from '../lib/enums';
|
|
2
|
+
import type { CSSProperties, ReactElement } from 'react';
|
|
3
|
+
export interface ScopeDotProps {
|
|
4
|
+
readonly scope: BiomeScope;
|
|
5
|
+
readonly size?: number;
|
|
6
|
+
readonly style?: CSSProperties;
|
|
7
|
+
}
|
|
8
|
+
export declare function ScopeDot({ scope, size, style, }: ScopeDotProps): ReactElement;
|
|
9
|
+
//# sourceMappingURL=ScopeDot.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ScopeDot.d.ts","sourceRoot":"","sources":["../../../src/session-kit/primitives/ScopeDot.tsx"],"names":[],"mappings":"AAIA,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAE1C,OAAO,KAAK,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,OAAO,CAAC;AAczD,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,KAAK,EAAE,UAAU,CAAC;IAC3B,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,KAAK,CAAC,EAAE,aAAa,CAAC;CAChC;AAED,wBAAgB,QAAQ,CAAC,EACvB,KAAK,EACL,IAAQ,EACR,KAAK,GACN,EAAE,aAAa,GAAG,YAAY,CAgB9B"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ScopeDot = ScopeDot;
|
|
4
|
+
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
5
|
+
const enums_1 = require("../lib/enums");
|
|
6
|
+
const SCOPE = {
|
|
7
|
+
[enums_1.BiomeScope.System]: { color: 'hsl(var(--ink-4))', label: 'System' },
|
|
8
|
+
[enums_1.BiomeScope.Platform]: { color: 'hsl(var(--primary))', label: 'Platform' },
|
|
9
|
+
[enums_1.BiomeScope.Community]: { color: 'hsl(var(--p-people))', label: 'Community' },
|
|
10
|
+
};
|
|
11
|
+
function ScopeDot({ scope, size = 7, style, }) {
|
|
12
|
+
const s = SCOPE[scope];
|
|
13
|
+
return ((0, jsx_runtime_1.jsx)("span", { title: s.label, style: {
|
|
14
|
+
width: size,
|
|
15
|
+
height: size,
|
|
16
|
+
borderRadius: '50%',
|
|
17
|
+
background: s.color,
|
|
18
|
+
flexShrink: 0,
|
|
19
|
+
display: 'inline-block',
|
|
20
|
+
...style,
|
|
21
|
+
} }));
|
|
22
|
+
}
|
|
23
|
+
//# sourceMappingURL=ScopeDot.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ScopeDot.js","sourceRoot":"","sources":["../../../src/session-kit/primitives/ScopeDot.tsx"],"names":[],"mappings":";;AA0BA,4BAoBC;;AA1CD,wCAA0C;AAU1C,MAAM,KAAK,GAAmC;IAC5C,CAAC,kBAAU,CAAC,MAAM,CAAC,EAAE,EAAE,KAAK,EAAE,mBAAmB,EAAE,KAAK,EAAE,QAAQ,EAAE;IACpE,CAAC,kBAAU,CAAC,QAAQ,CAAC,EAAE,EAAE,KAAK,EAAE,qBAAqB,EAAE,KAAK,EAAE,UAAU,EAAE;IAC1E,CAAC,kBAAU,CAAC,SAAS,CAAC,EAAE,EAAE,KAAK,EAAE,sBAAsB,EAAE,KAAK,EAAE,WAAW,EAAE;CAC9E,CAAC;AAQF,SAAgB,QAAQ,CAAC,EACvB,KAAK,EACL,IAAI,GAAG,CAAC,EACR,KAAK,GACS;IACd,MAAM,CAAC,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC;IACvB,OAAO,CACL,iCACE,KAAK,EAAE,CAAC,CAAC,KAAK,EACd,KAAK,EAAE;YACL,KAAK,EAAE,IAAI;YACX,MAAM,EAAE,IAAI;YACZ,YAAY,EAAE,KAAK;YACnB,UAAU,EAAE,CAAC,CAAC,KAAK;YACnB,UAAU,EAAE,CAAC;YACb,OAAO,EAAE,cAAc;YACvB,GAAG,KAAK;SACT,GACD,CACH,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { CSSProperties, ReactElement, ReactNode } from 'react';
|
|
2
|
+
export interface SegmentedOption<V extends string> {
|
|
3
|
+
readonly value: V;
|
|
4
|
+
readonly label: ReactNode;
|
|
5
|
+
readonly icon?: ReactNode;
|
|
6
|
+
}
|
|
7
|
+
export type SegmentedSize = 'sm' | 'md';
|
|
8
|
+
export interface SegmentedProps<V extends string> {
|
|
9
|
+
readonly options: ReadonlyArray<SegmentedOption<V>>;
|
|
10
|
+
readonly value: V;
|
|
11
|
+
readonly onChange: (value: V) => void;
|
|
12
|
+
readonly size?: SegmentedSize;
|
|
13
|
+
readonly style?: CSSProperties;
|
|
14
|
+
}
|
|
15
|
+
export declare function Segmented<V extends string>({ options, value, onChange, size, style, }: SegmentedProps<V>): ReactElement;
|
|
16
|
+
//# sourceMappingURL=Segmented.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Segmented.d.ts","sourceRoot":"","sources":["../../../src/session-kit/primitives/Segmented.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,aAAa,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAEpE,MAAM,WAAW,eAAe,CAAC,CAAC,SAAS,MAAM;IAC/C,QAAQ,CAAC,KAAK,EAAE,CAAC,CAAC;IAClB,QAAQ,CAAC,KAAK,EAAE,SAAS,CAAC;IAE1B,QAAQ,CAAC,IAAI,CAAC,EAAE,SAAS,CAAC;CAC3B;AAED,MAAM,MAAM,aAAa,GAAG,IAAI,GAAG,IAAI,CAAC;AAExC,MAAM,WAAW,cAAc,CAAC,CAAC,SAAS,MAAM;IAC9C,QAAQ,CAAC,OAAO,EAAE,aAAa,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,CAAC;IACpD,QAAQ,CAAC,KAAK,EAAE,CAAC,CAAC;IAClB,QAAQ,CAAC,QAAQ,EAAE,CAAC,KAAK,EAAE,CAAC,KAAK,IAAI,CAAC;IACtC,QAAQ,CAAC,IAAI,CAAC,EAAE,aAAa,CAAC;IAC9B,QAAQ,CAAC,KAAK,CAAC,EAAE,aAAa,CAAC;CAChC;AAED,wBAAgB,SAAS,CAAC,CAAC,SAAS,MAAM,EAAE,EAC1C,OAAO,EACP,KAAK,EACL,QAAQ,EACR,IAAW,EACX,KAAK,GACN,EAAE,cAAc,CAAC,CAAC,CAAC,GAAG,YAAY,CAyClC"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Segmented = Segmented;
|
|
4
|
+
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
5
|
+
function Segmented({ options, value, onChange, size = 'sm', style, }) {
|
|
6
|
+
return ((0, jsx_runtime_1.jsx)("div", { style: {
|
|
7
|
+
display: 'inline-flex',
|
|
8
|
+
padding: 2,
|
|
9
|
+
gap: 2,
|
|
10
|
+
background: 'hsl(var(--paper-sunk))',
|
|
11
|
+
border: '1px solid hsl(var(--rule))',
|
|
12
|
+
borderRadius: 8,
|
|
13
|
+
...style,
|
|
14
|
+
}, children: options.map((option) => {
|
|
15
|
+
const on = option.value === value;
|
|
16
|
+
return ((0, jsx_runtime_1.jsxs)("button", { type: "button", onClick: () => onChange(option.value), style: {
|
|
17
|
+
display: 'inline-flex',
|
|
18
|
+
alignItems: 'center',
|
|
19
|
+
gap: 5,
|
|
20
|
+
padding: size === 'sm' ? '4px 10px' : '6px 12px',
|
|
21
|
+
fontSize: size === 'sm' ? 12 : 13,
|
|
22
|
+
fontWeight: on ? 600 : 450,
|
|
23
|
+
borderRadius: 6,
|
|
24
|
+
color: on ? 'hsl(var(--ink))' : 'hsl(var(--ink-3))',
|
|
25
|
+
background: on ? 'hsl(var(--paper-elev))' : 'transparent',
|
|
26
|
+
boxShadow: on ? 'var(--shadow-2, var(--shadow-1))' : 'none',
|
|
27
|
+
transition: 'background 140ms ease, color 140ms ease, box-shadow 140ms ease',
|
|
28
|
+
}, children: [option.icon, option.label] }, option.value));
|
|
29
|
+
}) }));
|
|
30
|
+
}
|
|
31
|
+
//# sourceMappingURL=Segmented.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Segmented.js","sourceRoot":"","sources":["../../../src/session-kit/primitives/Segmented.tsx"],"names":[],"mappings":";;AAuBA,8BA+CC;;AA/CD,SAAgB,SAAS,CAAmB,EAC1C,OAAO,EACP,KAAK,EACL,QAAQ,EACR,IAAI,GAAG,IAAI,EACX,KAAK,GACa;IAClB,OAAO,CACL,gCACE,KAAK,EAAE;YACL,OAAO,EAAE,aAAa;YACtB,OAAO,EAAE,CAAC;YACV,GAAG,EAAE,CAAC;YACN,UAAU,EAAE,wBAAwB;YACpC,MAAM,EAAE,4BAA4B;YACpC,YAAY,EAAE,CAAC;YACf,GAAG,KAAK;SACT,YAEA,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE;YACtB,MAAM,EAAE,GAAG,MAAM,CAAC,KAAK,KAAK,KAAK,CAAC;YAClC,OAAO,CACL,oCAEE,IAAI,EAAC,QAAQ,EACb,OAAO,EAAE,GAAG,EAAE,CAAC,QAAQ,CAAC,MAAM,CAAC,KAAK,CAAC,EACrC,KAAK,EAAE;oBACL,OAAO,EAAE,aAAa;oBACtB,UAAU,EAAE,QAAQ;oBACpB,GAAG,EAAE,CAAC;oBACN,OAAO,EAAE,IAAI,KAAK,IAAI,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,UAAU;oBAChD,QAAQ,EAAE,IAAI,KAAK,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE;oBACjC,UAAU,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG;oBAC1B,YAAY,EAAE,CAAC;oBACf,KAAK,EAAE,EAAE,CAAC,CAAC,CAAC,iBAAiB,CAAC,CAAC,CAAC,mBAAmB;oBACnD,UAAU,EAAE,EAAE,CAAC,CAAC,CAAC,wBAAwB,CAAC,CAAC,CAAC,aAAa;oBACzD,SAAS,EAAE,EAAE,CAAC,CAAC,CAAC,kCAAkC,CAAC,CAAC,CAAC,MAAM;oBAC3D,UAAU,EAAE,gEAAgE;iBAC7E,aAEA,MAAM,CAAC,IAAI,EACX,MAAM,CAAC,KAAK,KAlBR,MAAM,CAAC,KAAK,CAmBV,CACV,CAAC;QACJ,CAAC,CAAC,GACE,CACP,CAAC;AACJ,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@xemahq/ui-kernel",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.7",
|
|
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",
|
|
@@ -35,7 +35,7 @@
|
|
|
35
35
|
"LICENSE"
|
|
36
36
|
],
|
|
37
37
|
"dependencies": {
|
|
38
|
-
"@xemahq/kernel-contracts": "^0.
|
|
38
|
+
"@xemahq/kernel-contracts": "^0.3.0",
|
|
39
39
|
"clsx": "^2.1.1",
|
|
40
40
|
"tailwind-merge": "^2.5.4",
|
|
41
41
|
"@xemahq/registry": "0.1.3"
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared Orval-client wiring for frontend biomes.
|
|
3
|
+
*
|
|
4
|
+
* Every biome that calls a platform API through an Orval-generated client must
|
|
5
|
+
* configure that client with the SAME auth/header/401 behavior the host shell
|
|
6
|
+
* uses for its own clients. Hand-copying a `configureOrgDbClient`-style helper
|
|
7
|
+
* into each biome (as `org-databases` did across three hook files) duplicates
|
|
8
|
+
* the correlation-id + org-header + token logic and lets it drift from the
|
|
9
|
+
* host. This factory centralizes it: a biome builds one config from its
|
|
10
|
+
* `HostBridge` and feeds it straight into the client's `configureClient(...)`.
|
|
11
|
+
*
|
|
12
|
+
* Auth/refresh/redirect stay HOST-owned — this only READS the bridge's
|
|
13
|
+
* host-implemented methods (`getActorToken`, `ensureFreshToken`,
|
|
14
|
+
* `onUnauthorized`, `getOrgId`). It owns no auth state of its own.
|
|
15
|
+
*/
|
|
16
|
+
import type { HostBridge } from './host-bridge';
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* The Orval client config shape every generated `configureClient(...)` accepts.
|
|
20
|
+
* Kept structural (not imported from a client package) so the kernel stays free
|
|
21
|
+
* of any concrete service-client dependency — biomes pass the result straight
|
|
22
|
+
* into their own client's `configureClient`, which validates the shape.
|
|
23
|
+
*/
|
|
24
|
+
export interface BiomeOrvalConfig {
|
|
25
|
+
readonly baseUrl: string;
|
|
26
|
+
readonly maxRetries: number;
|
|
27
|
+
getAuthToken(): Promise<string>;
|
|
28
|
+
getHeaders(): Promise<Record<string, string>>;
|
|
29
|
+
onUnauthorized(): Promise<void>;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export interface CreateBiomeOrvalConfigOptions {
|
|
33
|
+
/** Absolute base URL of the target service. */
|
|
34
|
+
readonly baseUrl: string;
|
|
35
|
+
/**
|
|
36
|
+
* Retry budget for the underlying fetch wrapper. Defaults to 1 — a single
|
|
37
|
+
* retry covers the `onUnauthorized` refresh-then-retry path without turning
|
|
38
|
+
* a hard failure into a retry storm.
|
|
39
|
+
*/
|
|
40
|
+
readonly maxRetries?: number;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Build an Orval client config from a `HostBridge`. Wires:
|
|
45
|
+
* - `getAuthToken` → `bridge.auth.ensureFreshToken()` (proactive refresh;
|
|
46
|
+
* the host owns the refresh + login-redirect single-flight).
|
|
47
|
+
* - `getHeaders` → a fresh `X-Correlation-Id` per call, plus `X-Org-Id` when
|
|
48
|
+
* an org is selected. Per-call headers set by the caller still win in the
|
|
49
|
+
* client's own header merge.
|
|
50
|
+
* - `onUnauthorized` → `bridge.auth.onUnauthorized()` (host force-refresh +
|
|
51
|
+
* redirect-on-failure).
|
|
52
|
+
*
|
|
53
|
+
* @example
|
|
54
|
+
* configureClient(createBiomeOrvalConfig(bridge, { baseUrl: API_BASE_URL }));
|
|
55
|
+
*/
|
|
56
|
+
export function createBiomeOrvalConfig(
|
|
57
|
+
bridge: HostBridge,
|
|
58
|
+
opts: CreateBiomeOrvalConfigOptions,
|
|
59
|
+
): BiomeOrvalConfig {
|
|
60
|
+
return {
|
|
61
|
+
baseUrl: opts.baseUrl,
|
|
62
|
+
maxRetries: opts.maxRetries ?? 1,
|
|
63
|
+
getAuthToken: () => bridge.auth.ensureFreshToken(),
|
|
64
|
+
getHeaders: async () => {
|
|
65
|
+
const headers: Record<string, string> = {
|
|
66
|
+
'X-Correlation-Id': crypto.randomUUID(),
|
|
67
|
+
};
|
|
68
|
+
const orgId = bridge.auth.getOrgId();
|
|
69
|
+
if (orgId) {
|
|
70
|
+
headers['X-Org-Id'] = orgId;
|
|
71
|
+
}
|
|
72
|
+
return headers;
|
|
73
|
+
},
|
|
74
|
+
onUnauthorized: () => bridge.auth.onUnauthorized(),
|
|
75
|
+
};
|
|
76
|
+
}
|
|
@@ -58,6 +58,28 @@ export interface HostBridgeAuth {
|
|
|
58
58
|
getProjectId(): string | null;
|
|
59
59
|
/** Returns the current actor's user id (subject), or null. */
|
|
60
60
|
getUserId(): string | null;
|
|
61
|
+
/**
|
|
62
|
+
* Proactively refresh the actor token if it is within `minValiditySeconds`
|
|
63
|
+
* of expiry, then return a guaranteed-valid bearer. The refresh + any
|
|
64
|
+
* redirect-on-failure stays HOST-owned (the host owns the auth client and
|
|
65
|
+
* the single-flight login guard) — biomes only reach it through this method
|
|
66
|
+
* so an Orval client's `getAuthToken` can be wired against the SAME refresh
|
|
67
|
+
* path the host uses, instead of each biome re-implementing token freshness.
|
|
68
|
+
*
|
|
69
|
+
* @param minValiditySeconds Refresh when fewer than this many seconds of
|
|
70
|
+
* validity remain. Defaults to a host-chosen safe window.
|
|
71
|
+
* @returns A valid bearer token string. Implementations that cannot produce
|
|
72
|
+
* one (session expired) trigger the host login redirect and reject.
|
|
73
|
+
*/
|
|
74
|
+
ensureFreshToken(minValiditySeconds?: number): Promise<string>;
|
|
75
|
+
/**
|
|
76
|
+
* Handle a 401 from a downstream API call: force-refresh the token and, if
|
|
77
|
+
* that fails, redirect to login. HOST-owned for the same reason as
|
|
78
|
+
* {@link HostBridgeAuth.ensureFreshToken} — there is ONE login-redirect
|
|
79
|
+
* single-flight guard and one refresh-dedup path in the host; biomes funnel
|
|
80
|
+
* 401 recovery through here rather than forking that logic.
|
|
81
|
+
*/
|
|
82
|
+
onUnauthorized(): Promise<void>;
|
|
61
83
|
}
|
|
62
84
|
|
|
63
85
|
export interface HostBridgeToast {
|
|
@@ -25,6 +25,19 @@ export interface AuthSource {
|
|
|
25
25
|
getProjectId(): string | null;
|
|
26
26
|
/** Subject (user) id of the actor, or null when unauthenticated. */
|
|
27
27
|
getUserId(): string | null;
|
|
28
|
+
/**
|
|
29
|
+
* Proactively refresh the token if it is within `minValiditySeconds` of
|
|
30
|
+
* expiry and return a valid bearer. Backed by the host's auth client
|
|
31
|
+
* (keycloak-js `updateToken`, …) and its single-flight login redirect.
|
|
32
|
+
* Mirrors {@link HostBridgeAuth.ensureFreshToken} — the bridge delegates
|
|
33
|
+
* straight through to this source.
|
|
34
|
+
*/
|
|
35
|
+
ensureFreshToken(minValiditySeconds?: number): Promise<string>;
|
|
36
|
+
/**
|
|
37
|
+
* Force-refresh on a 401 and redirect to login on failure. Backed by the
|
|
38
|
+
* host's auth-guard. Mirrors {@link HostBridgeAuth.onUnauthorized}.
|
|
39
|
+
*/
|
|
40
|
+
onUnauthorized(): Promise<void>;
|
|
28
41
|
}
|
|
29
42
|
|
|
30
43
|
/**
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Minimal action button used by the approval surfaces (card / sticky bar /
|
|
3
|
+
* Center). The kit carries no button primitive, so this is a small,
|
|
4
|
+
* inline-styled control matching the design's `Btn` (ghost / soft /
|
|
5
|
+
* primary, with an optional accent override for critical-tier approve).
|
|
6
|
+
*
|
|
7
|
+
* Kept inside the approvals folder because it is only the approval
|
|
8
|
+
* actions — it is NOT a general-purpose kit button.
|
|
9
|
+
*/
|
|
10
|
+
import type { CSSProperties, ReactElement, ReactNode } from 'react';
|
|
11
|
+
|
|
12
|
+
export type ApprovalButtonVariant = 'ghost' | 'soft' | 'primary';
|
|
13
|
+
export type ApprovalButtonSize = 'xs' | 'sm';
|
|
14
|
+
|
|
15
|
+
export interface ApprovalButtonProps {
|
|
16
|
+
readonly variant?: ApprovalButtonVariant;
|
|
17
|
+
readonly size?: ApprovalButtonSize;
|
|
18
|
+
/** Accent for the `primary` variant background (e.g. portal/risk accent). */
|
|
19
|
+
readonly accent?: string;
|
|
20
|
+
readonly icon?: ReactNode;
|
|
21
|
+
readonly disabled?: boolean;
|
|
22
|
+
readonly onClick?: () => void;
|
|
23
|
+
readonly children: ReactNode;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
const PAD: Record<ApprovalButtonSize, string> = {
|
|
27
|
+
xs: '3px 9px',
|
|
28
|
+
sm: '5px 11px',
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
const FONT: Record<ApprovalButtonSize, number> = { xs: 12, sm: 12.5 };
|
|
32
|
+
|
|
33
|
+
export function ApprovalButton({
|
|
34
|
+
variant = 'ghost',
|
|
35
|
+
size = 'sm',
|
|
36
|
+
accent = 'hsl(var(--primary))',
|
|
37
|
+
icon,
|
|
38
|
+
disabled = false,
|
|
39
|
+
onClick,
|
|
40
|
+
children,
|
|
41
|
+
}: ApprovalButtonProps): ReactElement {
|
|
42
|
+
const base: CSSProperties = {
|
|
43
|
+
display: 'inline-flex',
|
|
44
|
+
alignItems: 'center',
|
|
45
|
+
gap: 5,
|
|
46
|
+
padding: PAD[size],
|
|
47
|
+
fontSize: FONT[size],
|
|
48
|
+
fontWeight: 550,
|
|
49
|
+
borderRadius: 7,
|
|
50
|
+
cursor: disabled ? 'not-allowed' : 'pointer',
|
|
51
|
+
opacity: disabled ? 0.5 : 1,
|
|
52
|
+
whiteSpace: 'nowrap',
|
|
53
|
+
lineHeight: 1.2,
|
|
54
|
+
};
|
|
55
|
+
const variantStyle = resolveVariantStyle(variant, accent);
|
|
56
|
+
return (
|
|
57
|
+
<button
|
|
58
|
+
type="button"
|
|
59
|
+
disabled={disabled}
|
|
60
|
+
onClick={onClick}
|
|
61
|
+
style={{ ...base, ...variantStyle }}
|
|
62
|
+
>
|
|
63
|
+
{icon}
|
|
64
|
+
{children}
|
|
65
|
+
</button>
|
|
66
|
+
);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
function resolveVariantStyle(
|
|
70
|
+
variant: ApprovalButtonVariant,
|
|
71
|
+
accent: string,
|
|
72
|
+
): CSSProperties {
|
|
73
|
+
switch (variant) {
|
|
74
|
+
case 'primary':
|
|
75
|
+
return { background: accent, color: '#fff', border: '1px solid transparent' };
|
|
76
|
+
case 'soft':
|
|
77
|
+
return {
|
|
78
|
+
background: 'hsl(var(--muted))',
|
|
79
|
+
color: 'hsl(var(--ink))',
|
|
80
|
+
border: '1px solid hsl(var(--rule))',
|
|
81
|
+
};
|
|
82
|
+
case 'ghost':
|
|
83
|
+
return {
|
|
84
|
+
background: 'transparent',
|
|
85
|
+
color: 'hsl(var(--ink-2))',
|
|
86
|
+
border: '1px solid transparent',
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
}
|