@consciousclouds/operator-shell 0.1.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/CHANGELOG.md +36 -0
- package/LICENSE +194 -0
- package/README.md +319 -0
- package/dist/chief/ChiefDrawer.d.ts +11 -0
- package/dist/chief/ChiefDrawer.d.ts.map +1 -0
- package/dist/chief/ChiefDrawer.js +49 -0
- package/dist/chief/ChiefDrawer.js.map +1 -0
- package/dist/chief/ChiefPanel.d.ts +10 -0
- package/dist/chief/ChiefPanel.d.ts.map +1 -0
- package/dist/chief/ChiefPanel.js +46 -0
- package/dist/chief/ChiefPanel.js.map +1 -0
- package/dist/chief/ChiefRegion.d.ts +9 -0
- package/dist/chief/ChiefRegion.d.ts.map +1 -0
- package/dist/chief/ChiefRegion.js +55 -0
- package/dist/chief/ChiefRegion.js.map +1 -0
- package/dist/chief/ChiefSession.d.ts +21 -0
- package/dist/chief/ChiefSession.d.ts.map +1 -0
- package/dist/chief/ChiefSession.js +9 -0
- package/dist/chief/ChiefSession.js.map +1 -0
- package/dist/chief/directive.d.ts +15 -0
- package/dist/chief/directive.d.ts.map +1 -0
- package/dist/chief/directive.js +20 -0
- package/dist/chief/directive.js.map +1 -0
- package/dist/chief/turn-adapter.d.ts +52 -0
- package/dist/chief/turn-adapter.d.ts.map +1 -0
- package/dist/chief/turn-adapter.js +23 -0
- package/dist/chief/turn-adapter.js.map +1 -0
- package/dist/chief/use-chief-shortcut.d.ts +17 -0
- package/dist/chief/use-chief-shortcut.d.ts.map +1 -0
- package/dist/chief/use-chief-shortcut.js +61 -0
- package/dist/chief/use-chief-shortcut.js.map +1 -0
- package/dist/chief/use-chief-turn.d.ts +50 -0
- package/dist/chief/use-chief-turn.d.ts.map +1 -0
- package/dist/chief/use-chief-turn.js +99 -0
- package/dist/chief/use-chief-turn.js.map +1 -0
- package/dist/flavor/types.d.ts +189 -0
- package/dist/flavor/types.d.ts.map +1 -0
- package/dist/flavor/types.js +13 -0
- package/dist/flavor/types.js.map +1 -0
- package/dist/frame/OperatorShell.d.ts +91 -0
- package/dist/frame/OperatorShell.d.ts.map +1 -0
- package/dist/frame/OperatorShell.js +54 -0
- package/dist/frame/OperatorShell.js.map +1 -0
- package/dist/guard/PermissionProvider.d.ts +49 -0
- package/dist/guard/PermissionProvider.d.ts.map +1 -0
- package/dist/guard/PermissionProvider.js +103 -0
- package/dist/guard/PermissionProvider.js.map +1 -0
- package/dist/guard/RouteGuard.d.ts +45 -0
- package/dist/guard/RouteGuard.d.ts.map +1 -0
- package/dist/guard/RouteGuard.js +59 -0
- package/dist/guard/RouteGuard.js.map +1 -0
- package/dist/guard/permissions.d.ts +88 -0
- package/dist/guard/permissions.d.ts.map +1 -0
- package/dist/guard/permissions.js +105 -0
- package/dist/guard/permissions.js.map +1 -0
- package/dist/header/EnvironmentSwitcher.d.ts +5 -0
- package/dist/header/EnvironmentSwitcher.d.ts.map +1 -0
- package/dist/header/EnvironmentSwitcher.js +51 -0
- package/dist/header/EnvironmentSwitcher.js.map +1 -0
- package/dist/header/OperatorHeader.d.ts +25 -0
- package/dist/header/OperatorHeader.d.ts.map +1 -0
- package/dist/header/OperatorHeader.js +13 -0
- package/dist/header/OperatorHeader.js.map +1 -0
- package/dist/header/OperatorProfileMenu.d.ts +2 -0
- package/dist/header/OperatorProfileMenu.d.ts.map +1 -0
- package/dist/header/OperatorProfileMenu.js +14 -0
- package/dist/header/OperatorProfileMenu.js.map +1 -0
- package/dist/header/ThemeToggle.d.ts +2 -0
- package/dist/header/ThemeToggle.d.ts.map +1 -0
- package/dist/header/ThemeToggle.js +17 -0
- package/dist/header/ThemeToggle.js.map +1 -0
- package/dist/icons/registry.d.ts +57 -0
- package/dist/icons/registry.d.ts.map +1 -0
- package/dist/icons/registry.js +83 -0
- package/dist/icons/registry.js.map +1 -0
- package/dist/index.d.ts +77 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +129 -0
- package/dist/index.js.map +1 -0
- package/dist/inspector/InspectorProvider.d.ts +41 -0
- package/dist/inspector/InspectorProvider.d.ts.map +1 -0
- package/dist/inspector/InspectorProvider.js +63 -0
- package/dist/inspector/InspectorProvider.js.map +1 -0
- package/dist/inspector/types.d.ts +91 -0
- package/dist/inspector/types.d.ts.map +1 -0
- package/dist/inspector/types.js +40 -0
- package/dist/inspector/types.js.map +1 -0
- package/dist/nav/routes.d.ts +39 -0
- package/dist/nav/routes.d.ts.map +1 -0
- package/dist/nav/routes.js +46 -0
- package/dist/nav/routes.js.map +1 -0
- package/dist/palette/CommandPalette.d.ts +40 -0
- package/dist/palette/CommandPalette.d.ts.map +1 -0
- package/dist/palette/CommandPalette.js +108 -0
- package/dist/palette/CommandPalette.js.map +1 -0
- package/dist/palette/commands.d.ts +58 -0
- package/dist/palette/commands.d.ts.map +1 -0
- package/dist/palette/commands.js +81 -0
- package/dist/palette/commands.js.map +1 -0
- package/dist/palette/search-sources.d.ts +126 -0
- package/dist/palette/search-sources.d.ts.map +1 -0
- package/dist/palette/search-sources.js +101 -0
- package/dist/palette/search-sources.js.map +1 -0
- package/dist/palette/use-search-results.d.ts +4 -0
- package/dist/palette/use-search-results.d.ts.map +1 -0
- package/dist/palette/use-search-results.js +51 -0
- package/dist/palette/use-search-results.js.map +1 -0
- package/dist/sidebar/OperatorSidebar.d.ts +44 -0
- package/dist/sidebar/OperatorSidebar.d.ts.map +1 -0
- package/dist/sidebar/OperatorSidebar.js +30 -0
- package/dist/sidebar/OperatorSidebar.js.map +1 -0
- package/dist/workspace/CanvasWorkspace.d.ts +78 -0
- package/dist/workspace/CanvasWorkspace.d.ts.map +1 -0
- package/dist/workspace/CanvasWorkspace.js +44 -0
- package/dist/workspace/CanvasWorkspace.js.map +1 -0
- package/dist/workspace/DashboardWorkspace.d.ts +91 -0
- package/dist/workspace/DashboardWorkspace.d.ts.map +1 -0
- package/dist/workspace/DashboardWorkspace.js +39 -0
- package/dist/workspace/DashboardWorkspace.js.map +1 -0
- package/dist/workspace/FormWorkspace.d.ts +107 -0
- package/dist/workspace/FormWorkspace.d.ts.map +1 -0
- package/dist/workspace/FormWorkspace.js +38 -0
- package/dist/workspace/FormWorkspace.js.map +1 -0
- package/dist/workspace/GraphWorkspace.d.ts +112 -0
- package/dist/workspace/GraphWorkspace.d.ts.map +1 -0
- package/dist/workspace/GraphWorkspace.js +147 -0
- package/dist/workspace/GraphWorkspace.js.map +1 -0
- package/dist/workspace/TableWorkspace.d.ts +74 -0
- package/dist/workspace/TableWorkspace.d.ts.map +1 -0
- package/dist/workspace/TableWorkspace.js +25 -0
- package/dist/workspace/TableWorkspace.js.map +1 -0
- package/dist/workspace/WorkspaceHost.d.ts +26 -0
- package/dist/workspace/WorkspaceHost.d.ts.map +1 -0
- package/dist/workspace/WorkspaceHost.js +21 -0
- package/dist/workspace/WorkspaceHost.js.map +1 -0
- package/dist/workspace/registry.d.ts +30 -0
- package/dist/workspace/registry.d.ts.map +1 -0
- package/dist/workspace/registry.js +33 -0
- package/dist/workspace/registry.js.map +1 -0
- package/dist/workspace/types.d.ts +79 -0
- package/dist/workspace/types.d.ts.map +1 -0
- package/dist/workspace/types.js +48 -0
- package/dist/workspace/types.js.map +1 -0
- package/package.json +64 -0
- package/styles/source.css +16 -0
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
/**
|
|
4
|
+
* Graph workspace type — the built-in entity-relationship exploration
|
|
5
|
+
* workspace: a typed nodes/edges contract rendered as ADJACENCY-STYLE
|
|
6
|
+
* exploration (select an entity → see its connections → traverse), composed
|
|
7
|
+
* entirely from registry primitives. No visualization dependency: the
|
|
8
|
+
* license allowlist is the open shadcn registry + Radix/CVA/lucide + the CC
|
|
9
|
+
* SDKs, so force-directed canvases (react-flow/d3) are deliberately outside
|
|
10
|
+
* this workspace's vocabulary — a master-detail adjacency browser is
|
|
11
|
+
* legitimate graph exploration without them.
|
|
12
|
+
*
|
|
13
|
+
* MECHANISM ONLY. The framework owns the hosting state machine
|
|
14
|
+
* (error → loading → empty → ready), the index/detail composition, selection,
|
|
15
|
+
* and traversal; the PRODUCT owns every node, edge, kind, and label — what an
|
|
16
|
+
* entity IS and what a relationship MEANS arrive fully resolved via the
|
|
17
|
+
* mount input. No routes, no fetching, no brand.
|
|
18
|
+
*
|
|
19
|
+
* FAIL-CLOSED details:
|
|
20
|
+
* - `error` renders the error state and NO graph (a failed read never shows
|
|
21
|
+
* a misleading empty graph).
|
|
22
|
+
* - An edge endpoint that names an id not present in `nodes` renders as an
|
|
23
|
+
* explicit UNRESOLVED connection — visible but not traversable. The
|
|
24
|
+
* workspace never fabricates a node for a dangling reference.
|
|
25
|
+
*
|
|
26
|
+
* Frame-free by design (Separation Law): imports only React and the UI
|
|
27
|
+
* primitives — never the shell frame.
|
|
28
|
+
*/
|
|
29
|
+
import * as React from "react";
|
|
30
|
+
import { Badge, Card, EmptyState, FailClosed, SectionHeading, Skeleton, cn, } from "@consciousclouds/ui";
|
|
31
|
+
/** Neutral default while the product's reads are in flight. */
|
|
32
|
+
function DefaultLoading() {
|
|
33
|
+
return (_jsxs("div", { className: "grid gap-4 lg:grid-cols-[280px_1fr]", children: [_jsx(Skeleton, { className: "h-72" }), _jsx(Skeleton, { className: "h-72" })] }));
|
|
34
|
+
}
|
|
35
|
+
function resolveGraph(nodes, edges, kinds) {
|
|
36
|
+
const byId = new Map();
|
|
37
|
+
for (const n of nodes)
|
|
38
|
+
if (!byId.has(n.id))
|
|
39
|
+
byId.set(n.id, n);
|
|
40
|
+
const outgoing = new Map();
|
|
41
|
+
const incoming = new Map();
|
|
42
|
+
const push = (map, key, e) => {
|
|
43
|
+
const list = map.get(key);
|
|
44
|
+
if (list)
|
|
45
|
+
list.push(e);
|
|
46
|
+
else
|
|
47
|
+
map.set(key, [e]);
|
|
48
|
+
};
|
|
49
|
+
for (const e of edges) {
|
|
50
|
+
push(outgoing, e.source, e);
|
|
51
|
+
push(incoming, e.target, e);
|
|
52
|
+
}
|
|
53
|
+
const kindLabel = new Map();
|
|
54
|
+
const order = [];
|
|
55
|
+
for (const k of kinds) {
|
|
56
|
+
if (!kindLabel.has(k.id)) {
|
|
57
|
+
kindLabel.set(k.id, k.label);
|
|
58
|
+
order.push(k.id);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
for (const n of byId.values()) {
|
|
62
|
+
if (!kindLabel.has(n.kind)) {
|
|
63
|
+
kindLabel.set(n.kind, n.kind);
|
|
64
|
+
order.push(n.kind);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
const groups = order
|
|
68
|
+
.map((id) => ({
|
|
69
|
+
id,
|
|
70
|
+
label: kindLabel.get(id),
|
|
71
|
+
nodes: [...byId.values()].filter((n) => n.kind === id),
|
|
72
|
+
}))
|
|
73
|
+
.filter((g) => g.nodes.length > 0);
|
|
74
|
+
return { byId, outgoing, incoming, groups, kindLabel };
|
|
75
|
+
}
|
|
76
|
+
/** One connection row: the relationship + the far endpoint (traversable when
|
|
77
|
+
* resolved; an explicit unresolved marker when the endpoint id is unknown). */
|
|
78
|
+
function ConnectionRow({ edge, direction, resolved, onTraverse, }) {
|
|
79
|
+
const farId = direction === "outgoing" ? edge.target : edge.source;
|
|
80
|
+
const far = resolved.byId.get(farId);
|
|
81
|
+
const relation = edge.label ?? "related to";
|
|
82
|
+
if (!far) {
|
|
83
|
+
// FAIL-CLOSED: a dangling endpoint is shown, never fabricated or hidden.
|
|
84
|
+
return (_jsxs("li", { "data-graph-connection": edge.id, "data-graph-unresolved": farId, className: "flex items-center gap-2 rounded-md border border-dashed border-border px-3 py-2 text-sm text-muted-foreground", children: [_jsx("span", { className: "text-xs uppercase tracking-wide", children: relation }), _jsx("code", { className: "font-mono text-xs", children: farId }), _jsx(Badge, { variant: "warn", children: "not in this graph" })] }));
|
|
85
|
+
}
|
|
86
|
+
return (_jsx("li", { "data-graph-connection": edge.id, children: _jsxs("button", { type: "button", onClick: () => onTraverse(far.id), className: "flex w-full items-center gap-2 rounded-md border border-border px-3 py-2 text-left text-sm transition-colors hover:border-primary/40 hover:bg-accent", children: [_jsx("span", { className: "shrink-0 text-[11px] uppercase tracking-wide text-muted-foreground", children: direction === "outgoing" ? relation : `${relation} from` }), _jsx("span", { className: "min-w-0 flex-1 truncate font-medium", children: far.label }), _jsx(Badge, { variant: "muted", children: resolved.kindLabel.get(far.kind) ?? far.kind })] }) }));
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* The graph workspace component. Selection, traversal, and grouping are the
|
|
90
|
+
* framework's; every entity, relationship, and label is the product's.
|
|
91
|
+
*/
|
|
92
|
+
export function GraphWorkspace({ input, }) {
|
|
93
|
+
const { error, loading, nodes, edges, kinds, initialNodeId, emptyMessage, slots } = input;
|
|
94
|
+
// Hooks run unconditionally (state may flip between renders of one mount).
|
|
95
|
+
const resolved = React.useMemo(() => resolveGraph(nodes ?? [], edges ?? [], kinds ?? []), [nodes, edges, kinds]);
|
|
96
|
+
const [selectedId, setSelectedId] = React.useState(null);
|
|
97
|
+
// The traversal trail — where the operator came from (ids, oldest first).
|
|
98
|
+
const [trail, setTrail] = React.useState([]);
|
|
99
|
+
const firstId = resolved.groups[0]?.nodes[0]?.id ?? null;
|
|
100
|
+
const effectiveId = selectedId != null && resolved.byId.has(selectedId)
|
|
101
|
+
? selectedId
|
|
102
|
+
: initialNodeId != null && resolved.byId.has(initialNodeId)
|
|
103
|
+
? initialNodeId
|
|
104
|
+
: firstId;
|
|
105
|
+
const selected = effectiveId != null ? resolved.byId.get(effectiveId) : undefined;
|
|
106
|
+
if (error != null) {
|
|
107
|
+
return (_jsx("div", { "data-graph-workspace-state": "error", children: slots?.error ? slots.error(error) : _jsx(FailClosed, { what: "this graph", detail: error }) }));
|
|
108
|
+
}
|
|
109
|
+
if (loading) {
|
|
110
|
+
return (_jsx("div", { "data-graph-workspace-state": "loading", children: slots?.loading ?? _jsx(DefaultLoading, {}) }));
|
|
111
|
+
}
|
|
112
|
+
if (!selected) {
|
|
113
|
+
return (_jsx("div", { "data-graph-workspace-state": "empty", children: slots?.empty ?? (_jsx(EmptyState, { children: emptyMessage ?? "This graph has no entities yet." })) }));
|
|
114
|
+
}
|
|
115
|
+
const select = (id) => {
|
|
116
|
+
setTrail([]);
|
|
117
|
+
setSelectedId(id);
|
|
118
|
+
};
|
|
119
|
+
const traverse = (id) => {
|
|
120
|
+
if (effectiveId != null)
|
|
121
|
+
setTrail((t) => [...t, effectiveId]);
|
|
122
|
+
setSelectedId(id);
|
|
123
|
+
};
|
|
124
|
+
const jumpBack = (index) => {
|
|
125
|
+
const id = trail[index];
|
|
126
|
+
if (id == null)
|
|
127
|
+
return;
|
|
128
|
+
setTrail((t) => t.slice(0, index));
|
|
129
|
+
setSelectedId(id);
|
|
130
|
+
};
|
|
131
|
+
const out = resolved.outgoing.get(selected.id) ?? [];
|
|
132
|
+
const inc = resolved.incoming.get(selected.id) ?? [];
|
|
133
|
+
return (_jsxs("div", { "data-graph-workspace-state": "ready", className: "grid items-start gap-4 lg:grid-cols-[280px_1fr]", children: [_jsx(Card, { "data-graph-node-index": "", className: "gap-0 p-2", children: resolved.groups.map((group) => (_jsxs("div", { className: "px-1 pb-2", children: [_jsx(SectionHeading, { className: "px-2 pb-1", children: group.label }), _jsx("ul", { className: "space-y-0.5", children: group.nodes.map((node) => (_jsx("li", { children: _jsx("button", { type: "button", "data-graph-index-node": node.id, "aria-current": node.id === selected.id ? "true" : undefined, onClick: () => select(node.id), className: cn("w-full truncate rounded-md px-2 py-1.5 text-left text-sm transition-colors hover:bg-accent", node.id === selected.id
|
|
134
|
+
? "bg-accent font-medium"
|
|
135
|
+
: "text-muted-foreground"), children: node.label }) }, node.id))) })] }, group.id))) }), _jsxs(Card, { "data-graph-node-detail": selected.id, className: "gap-0 p-4", children: [trail.length > 0 ? (_jsxs("nav", { "data-graph-trail": "", "aria-label": "Traversal trail", className: "mb-3 flex flex-wrap items-center gap-1 text-xs text-muted-foreground", children: [trail.map((id, i) => (_jsxs(React.Fragment, { children: [_jsx("button", { type: "button", onClick: () => jumpBack(i), className: "rounded px-1 py-0.5 underline-offset-2 transition-colors hover:bg-accent hover:underline", children: resolved.byId.get(id)?.label ?? id }), _jsx("span", { "aria-hidden": "true", children: "/" })] }, `${id}-${i}`))), _jsx("span", { className: "px-1 font-medium text-foreground", children: selected.label })] })) : null, _jsxs("div", { className: "flex items-start justify-between gap-2", children: [_jsxs("div", { className: "min-w-0", children: [_jsx("h2", { className: "truncate text-lg font-semibold tracking-tight", children: selected.label }), _jsx("code", { className: "font-mono text-xs text-muted-foreground", children: selected.id })] }), _jsx(Badge, { variant: "active", children: resolved.kindLabel.get(selected.kind) ?? selected.kind })] }), selected.attributes && selected.attributes.length > 0 ? (_jsx("dl", { className: "mt-4 grid gap-x-6 gap-y-1.5 text-sm sm:grid-cols-2", children: selected.attributes.map((attr) => (_jsxs("div", { className: "flex items-baseline justify-between gap-3 sm:justify-start", children: [_jsx("dt", { className: "shrink-0 text-xs uppercase tracking-wide text-muted-foreground", children: attr.label }), _jsx("dd", { className: "min-w-0 truncate", children: attr.value })] }, attr.id))) })) : null, _jsx("div", { className: "mt-5 space-y-4", children: _jsxs("section", { children: [_jsx(SectionHeading, { className: "pb-2", children: "Connections" }), out.length === 0 && inc.length === 0 ? (_jsx("p", { "data-graph-no-connections": "", className: "text-sm text-muted-foreground", children: "This entity has no recorded connections." })) : (_jsxs("div", { className: "space-y-3", children: [out.length > 0 ? (_jsx("ul", { "data-graph-outgoing": "", className: "space-y-1.5", children: out.map((edge) => (_jsx(ConnectionRow, { edge: edge, direction: "outgoing", resolved: resolved, onTraverse: traverse }, edge.id))) })) : null, inc.length > 0 ? (_jsx("ul", { "data-graph-incoming": "", className: "space-y-1.5", children: inc.map((edge) => (_jsx(ConnectionRow, { edge: edge, direction: "incoming", resolved: resolved, onTraverse: traverse }, edge.id))) })) : null] }))] }) })] })] }));
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* The registered `graph` workspace type — compose it into the app's registry
|
|
139
|
+
* via `createWorkspaceRegistry([..., graphWorkspaceType])`.
|
|
140
|
+
*/
|
|
141
|
+
export const graphWorkspaceType = {
|
|
142
|
+
id: "graph",
|
|
143
|
+
displayName: "Graph",
|
|
144
|
+
description: "Entity-relationship exploration over a typed nodes/edges contract — select an entity, see its connections, traverse; dangling references fail closed.",
|
|
145
|
+
Component: GraphWorkspace,
|
|
146
|
+
};
|
|
147
|
+
//# sourceMappingURL=GraphWorkspace.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"GraphWorkspace.js","sourceRoot":"","sources":["../../src/workspace/GraphWorkspace.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Table workspace type — the built-in tabular-exploration workspace: hosts
|
|
3
|
+
* the graduated InteractiveDataTable composite (@consciousclouds/ui's
|
|
4
|
+
* interactive tier — registry `table` primitive + @tanstack/react-table)
|
|
5
|
+
* with client-side sorting, pagination, and explicit loading/empty states.
|
|
6
|
+
*
|
|
7
|
+
* MECHANISM ONLY. The framework owns the hosting state machine — a
|
|
8
|
+
* fail-closed `error` state layered ABOVE the composite's own loading/empty
|
|
9
|
+
* handling — and delegates everything tabular to InteractiveDataTable
|
|
10
|
+
* (consumed, never rebuilt). The PRODUCT owns the columns (typed
|
|
11
|
+
* `ColumnDef`s, sortable headers via DataTableColumnHeader), the rows, and
|
|
12
|
+
* the empty-state wording. No routes, no fetching, no brand: data arrives
|
|
13
|
+
* fully resolved via the mount input.
|
|
14
|
+
*
|
|
15
|
+
* Frame-free by design (Separation Law): imports only React and the UI
|
|
16
|
+
* primitives — never the shell frame.
|
|
17
|
+
*/
|
|
18
|
+
import type * as React from "react";
|
|
19
|
+
import { type ColumnDef, type SortingState } from "@consciousclouds/ui";
|
|
20
|
+
import type { WorkspaceComponentProps, WorkspaceType } from "./types.js";
|
|
21
|
+
/** Product-supplied state content; a neutral fail-closed default otherwise. */
|
|
22
|
+
export interface TableWorkspaceSlots {
|
|
23
|
+
/** Rendered when `error` is set; receives the error message. */
|
|
24
|
+
error?: (message: string) => React.ReactNode;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* The table workspace mount input. Precedence (fail-closed first): `error` →
|
|
28
|
+
* the composite's own states (`loading` skeleton rows → empty message →
|
|
29
|
+
* rows). Column/row typing is erased at the registry boundary (see
|
|
30
|
+
* AnyWorkspaceType); each mount re-establishes `TData` at the call site.
|
|
31
|
+
*/
|
|
32
|
+
export interface TableWorkspaceInput<TData = unknown> {
|
|
33
|
+
/**
|
|
34
|
+
* A load-failure message. When set, the workspace renders the error state
|
|
35
|
+
* and NO table — a failed read fails closed rather than show a misleading
|
|
36
|
+
* empty result set.
|
|
37
|
+
*/
|
|
38
|
+
error?: string | null;
|
|
39
|
+
/** The read is still in flight — the composite draws skeleton rows. */
|
|
40
|
+
loading?: boolean;
|
|
41
|
+
/** Typed column definitions (sortable headers via DataTableColumnHeader). */
|
|
42
|
+
columns: ColumnDef<TData, any>[];
|
|
43
|
+
/** The resolved rows. */
|
|
44
|
+
data: TData[];
|
|
45
|
+
/** Optional title bar above the table. */
|
|
46
|
+
title?: React.ReactNode;
|
|
47
|
+
/** The honest zero state when a completed read has no rows. */
|
|
48
|
+
emptyMessage?: React.ReactNode;
|
|
49
|
+
/** Client-side page size (controls appear only past one page). */
|
|
50
|
+
pageSize?: number;
|
|
51
|
+
/** Initial sort, e.g. `[{ id: "name", desc: false }]`. */
|
|
52
|
+
initialSorting?: SortingState;
|
|
53
|
+
/** Stable row identity (defaults to the row index). */
|
|
54
|
+
getRowId?: (row: TData, index: number) => string;
|
|
55
|
+
/**
|
|
56
|
+
* Row activation — click/Enter/Space on a data row (e.g. the page opens
|
|
57
|
+
* the shell's inspector on the row's entity). Forwarded to the composite;
|
|
58
|
+
* the framework never interprets the row.
|
|
59
|
+
*/
|
|
60
|
+
onRowClick?: (row: TData) => void;
|
|
61
|
+
/** Product-supplied state content; a neutral default otherwise. */
|
|
62
|
+
slots?: TableWorkspaceSlots;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* The table workspace component. The framework selects the state; the
|
|
66
|
+
* composite renders the table; the product means the columns and rows.
|
|
67
|
+
*/
|
|
68
|
+
export declare function TableWorkspace<TData = unknown>({ input, }: WorkspaceComponentProps<TableWorkspaceInput<TData>>): import("react/jsx-runtime").JSX.Element;
|
|
69
|
+
/**
|
|
70
|
+
* The registered `table` workspace type — compose it into the app's registry
|
|
71
|
+
* via `createWorkspaceRegistry([..., tableWorkspaceType])`.
|
|
72
|
+
*/
|
|
73
|
+
export declare const tableWorkspaceType: WorkspaceType<TableWorkspaceInput>;
|
|
74
|
+
//# sourceMappingURL=TableWorkspace.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TableWorkspace.d.ts","sourceRoot":"","sources":["../../src/workspace/TableWorkspace.tsx"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,KAAK,KAAK,KAAK,MAAM,OAAO,CAAC;AAEpC,OAAO,EAGL,KAAK,SAAS,EACd,KAAK,YAAY,EAClB,MAAM,qBAAqB,CAAC;AAE7B,OAAO,KAAK,EAAE,uBAAuB,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAEzE,+EAA+E;AAC/E,MAAM,WAAW,mBAAmB;IAClC,gEAAgE;IAChE,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,KAAK,CAAC,SAAS,CAAC;CAC9C;AAED;;;;;GAKG;AACH,MAAM,WAAW,mBAAmB,CAAC,KAAK,GAAG,OAAO;IAClD;;;;OAIG;IACH,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,uEAAuE;IACvE,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,6EAA6E;IAE7E,OAAO,EAAE,SAAS,CAAC,KAAK,EAAE,GAAG,CAAC,EAAE,CAAC;IACjC,yBAAyB;IACzB,IAAI,EAAE,KAAK,EAAE,CAAC;IACd,0CAA0C;IAC1C,KAAK,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACxB,+DAA+D;IAC/D,YAAY,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC/B,kEAAkE;IAClE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,0DAA0D;IAC1D,cAAc,CAAC,EAAE,YAAY,CAAC;IAC9B,uDAAuD;IACvD,QAAQ,CAAC,EAAE,CAAC,GAAG,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,KAAK,MAAM,CAAC;IACjD;;;;OAIG;IACH,UAAU,CAAC,EAAE,CAAC,GAAG,EAAE,KAAK,KAAK,IAAI,CAAC;IAClC,mEAAmE;IACnE,KAAK,CAAC,EAAE,mBAAmB,CAAC;CAC7B;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,KAAK,GAAG,OAAO,EAAE,EAC9C,KAAK,GACN,EAAE,uBAAuB,CAAC,mBAAmB,CAAC,KAAK,CAAC,CAAC,2CA0CrD;AAED;;;GAGG;AACH,eAAO,MAAM,kBAAkB,EAAE,aAAa,CAAC,mBAAmB,CAMjE,CAAC"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
3
|
+
import { FailClosed, InteractiveDataTable, } from "@consciousclouds/ui";
|
|
4
|
+
/**
|
|
5
|
+
* The table workspace component. The framework selects the state; the
|
|
6
|
+
* composite renders the table; the product means the columns and rows.
|
|
7
|
+
*/
|
|
8
|
+
export function TableWorkspace({ input, }) {
|
|
9
|
+
const { error, loading, columns, data, title, emptyMessage, pageSize, initialSorting, getRowId, onRowClick, slots, } = input;
|
|
10
|
+
if (error != null) {
|
|
11
|
+
return (_jsx("div", { "data-table-workspace-state": "error", children: slots?.error ? (slots.error(error)) : (_jsx(FailClosed, { what: "this table", detail: error })) }));
|
|
12
|
+
}
|
|
13
|
+
return (_jsx("div", { "data-table-workspace-state": loading ? "loading" : "ready", children: _jsx(InteractiveDataTable, { columns: columns, data: data, title: title, loading: loading, emptyMessage: emptyMessage, pageSize: pageSize, initialSorting: initialSorting, getRowId: getRowId, onRowClick: onRowClick }) }));
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* The registered `table` workspace type — compose it into the app's registry
|
|
17
|
+
* via `createWorkspaceRegistry([..., tableWorkspaceType])`.
|
|
18
|
+
*/
|
|
19
|
+
export const tableWorkspaceType = {
|
|
20
|
+
id: "table",
|
|
21
|
+
displayName: "Data Table",
|
|
22
|
+
description: "Tabular data exploration over the interactive data-table composite — client-side sorting, pagination, explicit loading/empty states.",
|
|
23
|
+
Component: TableWorkspace,
|
|
24
|
+
};
|
|
25
|
+
//# sourceMappingURL=TableWorkspace.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TableWorkspace.js","sourceRoot":"","sources":["../../src/workspace/TableWorkspace.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAC;;AAsBb,OAAO,EACL,UAAU,EACV,oBAAoB,GAGrB,MAAM,qBAAqB,CAAC;AAkD7B;;;GAGG;AACH,MAAM,UAAU,cAAc,CAAkB,EAC9C,KAAK,GAC+C;IACpD,MAAM,EACJ,KAAK,EACL,OAAO,EACP,OAAO,EACP,IAAI,EACJ,KAAK,EACL,YAAY,EACZ,QAAQ,EACR,cAAc,EACd,QAAQ,EACR,UAAU,EACV,KAAK,GACN,GAAG,KAAK,CAAC;IAEV,IAAI,KAAK,IAAI,IAAI,EAAE,CAAC;QAClB,OAAO,CACL,4CAAgC,OAAO,YACpC,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,CACd,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,CACnB,CAAC,CAAC,CAAC,CACF,KAAC,UAAU,IAAC,IAAI,EAAC,YAAY,EAAC,MAAM,EAAE,KAAK,GAAI,CAChD,GACG,CACP,CAAC;IACJ,CAAC;IAED,OAAO,CACL,4CAAiC,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,YAC5D,KAAC,oBAAoB,IACnB,OAAO,EAAE,OAAO,EAChB,IAAI,EAAE,IAAI,EACV,KAAK,EAAE,KAAK,EACZ,OAAO,EAAE,OAAO,EAChB,YAAY,EAAE,YAAY,EAC1B,QAAQ,EAAE,QAAQ,EAClB,cAAc,EAAE,cAAc,EAC9B,QAAQ,EAAE,QAAQ,EAClB,UAAU,EAAE,UAAU,GACtB,GACE,CACP,CAAC;AACJ,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAuC;IACpE,EAAE,EAAE,OAAO;IACX,WAAW,EAAE,YAAY;IACzB,WAAW,EACT,sIAAsI;IACxI,SAAS,EAAE,cAAc;CAC1B,CAAC"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { WorkspaceRegistry } from "./registry.js";
|
|
2
|
+
export interface WorkspaceHostProps<TInput = unknown> {
|
|
3
|
+
/** The composed registry (shell built-ins + product additions). */
|
|
4
|
+
registry: WorkspaceRegistry;
|
|
5
|
+
/**
|
|
6
|
+
* The workspace type to mount — runtime data (a route/flavor says what the
|
|
7
|
+
* main region is), so any string is accepted and unknowns fail closed.
|
|
8
|
+
*/
|
|
9
|
+
typeId: string;
|
|
10
|
+
/** Optional instance title, passed through to the mounted component. */
|
|
11
|
+
title?: string;
|
|
12
|
+
/** The mount's input data — opaque to the host, typed by the workspace type. */
|
|
13
|
+
input: TInput;
|
|
14
|
+
/** Extra classes for the host wrapper. */
|
|
15
|
+
className?: string;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* The neutral unavailable state an unknown/unregistered type id renders.
|
|
19
|
+
* Exported so products can present the same state for their own gated
|
|
20
|
+
* workspace affordances (one vocabulary of "not available here").
|
|
21
|
+
*/
|
|
22
|
+
export declare function WorkspaceUnavailable({ typeId }: {
|
|
23
|
+
typeId: string;
|
|
24
|
+
}): import("react/jsx-runtime").JSX.Element;
|
|
25
|
+
export declare function WorkspaceHost<TInput = unknown>({ registry, typeId, title, input, className, }: WorkspaceHostProps<TInput>): import("react/jsx-runtime").JSX.Element;
|
|
26
|
+
//# sourceMappingURL=WorkspaceHost.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"WorkspaceHost.d.ts","sourceRoot":"","sources":["../../src/workspace/WorkspaceHost.tsx"],"names":[],"mappings":"AAsBA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAEvD,MAAM,WAAW,kBAAkB,CAAC,MAAM,GAAG,OAAO;IAClD,mEAAmE;IACnE,QAAQ,EAAE,iBAAiB,CAAC;IAC5B;;;OAGG;IACH,MAAM,EAAE,MAAM,CAAC;IACf,wEAAwE;IACxE,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,gFAAgF;IAChF,KAAK,EAAE,MAAM,CAAC;IACd,0CAA0C;IAC1C,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,EAAE,MAAM,EAAE,EAAE;IAAE,MAAM,EAAE,MAAM,CAAA;CAAE,2CAkBlE;AAED,wBAAgB,aAAa,CAAC,MAAM,GAAG,OAAO,EAAE,EAC9C,QAAQ,EACR,MAAM,EACN,KAAK,EACL,KAAK,EACL,SAAS,GACV,EAAE,kBAAkB,CAAC,MAAM,CAAC,2CAe5B"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@consciousclouds/ui";
|
|
4
|
+
import { CircleAlert } from "lucide-react";
|
|
5
|
+
/**
|
|
6
|
+
* The neutral unavailable state an unknown/unregistered type id renders.
|
|
7
|
+
* Exported so products can present the same state for their own gated
|
|
8
|
+
* workspace affordances (one vocabulary of "not available here").
|
|
9
|
+
*/
|
|
10
|
+
export function WorkspaceUnavailable({ typeId }) {
|
|
11
|
+
return (_jsxs(Card, { "data-workspace-unavailable": typeId, className: "border-dashed", children: [_jsxs(CardHeader, { children: [_jsxs(CardTitle, { className: "flex items-center gap-2 text-muted-foreground", children: [_jsx(CircleAlert, { className: "size-4", "aria-hidden": "true" }), "Workspace unavailable"] }), _jsxs(CardDescription, { children: ["No workspace type is registered for ", _jsx("code", { className: "font-mono", children: typeId }), "."] })] }), _jsx(CardContent, { className: "text-sm text-muted-foreground", children: "This surface declared a workspace the console has not registered. Nothing was rendered \u2014 unregistered workspace types fail closed." })] }));
|
|
12
|
+
}
|
|
13
|
+
export function WorkspaceHost({ registry, typeId, title, input, className, }) {
|
|
14
|
+
const type = registry.get(typeId);
|
|
15
|
+
if (!type) {
|
|
16
|
+
return _jsx(WorkspaceUnavailable, { typeId: typeId });
|
|
17
|
+
}
|
|
18
|
+
const Component = type.Component;
|
|
19
|
+
return (_jsx("div", { "data-workspace-type": typeId, className: className, children: _jsx(Component, { typeId: typeId, title: title, input: input }) }));
|
|
20
|
+
}
|
|
21
|
+
//# sourceMappingURL=WorkspaceHost.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"WorkspaceHost.js","sourceRoot":"","sources":["../../src/workspace/WorkspaceHost.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAC;;AAmBb,OAAO,EAAE,IAAI,EAAE,WAAW,EAAE,eAAe,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAChG,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAoB3C;;;;GAIG;AACH,MAAM,UAAU,oBAAoB,CAAC,EAAE,MAAM,EAAsB;IACjE,OAAO,CACL,MAAC,IAAI,kCAA6B,MAAM,EAAE,SAAS,EAAC,eAAe,aACjE,MAAC,UAAU,eACT,MAAC,SAAS,IAAC,SAAS,EAAC,+CAA+C,aAClE,KAAC,WAAW,IAAC,SAAS,EAAC,QAAQ,iBAAa,MAAM,GAAG,6BAE3C,EACZ,MAAC,eAAe,uDACsB,eAAM,SAAS,EAAC,WAAW,YAAE,MAAM,GAAQ,SAC/D,IACP,EACb,KAAC,WAAW,IAAC,SAAS,EAAC,+BAA+B,wJAGxC,IACT,CACR,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,aAAa,CAAmB,EAC9C,QAAQ,EACR,MAAM,EACN,KAAK,EACL,KAAK,EACL,SAAS,GACkB;IAC3B,MAAM,IAAI,GAAG,QAAQ,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;IAClC,IAAI,CAAC,IAAI,EAAE,CAAC;QACV,OAAO,KAAC,oBAAoB,IAAC,MAAM,EAAE,MAAM,GAAI,CAAC;IAClD,CAAC;IACD,MAAM,SAAS,GAAG,IAAI,CAAC,SAIrB,CAAC;IACH,OAAO,CACL,qCAA0B,MAAM,EAAE,SAAS,EAAE,SAAS,YACpD,KAAC,SAAS,IAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,GAAI,GACrD,CACP,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Workspace Framework — the type registry.
|
|
3
|
+
*
|
|
4
|
+
* A value-based, immutable registry (no module-global mutable state): the
|
|
5
|
+
* app composes shell built-ins + product-registered types ONCE and hands
|
|
6
|
+
* the result to the WorkspaceHost. Registration is compile-time honest
|
|
7
|
+
* (ids come from the declared vocabulary); resolution accepts any string —
|
|
8
|
+
* runtime data — and FAILS CLOSED on an unknown/unregistered id.
|
|
9
|
+
*
|
|
10
|
+
* Frame-free by design (Separation Law): nothing here imports the shell.
|
|
11
|
+
*/
|
|
12
|
+
import type { AnyWorkspaceType } from "./types.js";
|
|
13
|
+
/** An immutable, resolved set of workspace types. */
|
|
14
|
+
export interface WorkspaceRegistry {
|
|
15
|
+
/** Resolve a type by id; `undefined` for anything not registered. */
|
|
16
|
+
get(id: string): AnyWorkspaceType | undefined;
|
|
17
|
+
/** Is this id registered? */
|
|
18
|
+
has(id: string): boolean;
|
|
19
|
+
/** The registered ids, in registration order. */
|
|
20
|
+
ids(): readonly string[];
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Build a registry from workspace types (shell built-ins first, then product
|
|
24
|
+
* additions, combined by the caller). A DUPLICATE id throws — registration
|
|
25
|
+
* is composition-time, so a collision is a programming error, never a
|
|
26
|
+
* runtime negotiation (last-write-wins would let a product silently replace
|
|
27
|
+
* a shell built-in).
|
|
28
|
+
*/
|
|
29
|
+
export declare function createWorkspaceRegistry(types: readonly AnyWorkspaceType[]): WorkspaceRegistry;
|
|
30
|
+
//# sourceMappingURL=registry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../src/workspace/registry.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAEnD,qDAAqD;AACrD,MAAM,WAAW,iBAAiB;IAChC,qEAAqE;IACrE,GAAG,CAAC,EAAE,EAAE,MAAM,GAAG,gBAAgB,GAAG,SAAS,CAAC;IAC9C,6BAA6B;IAC7B,GAAG,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC;IACzB,iDAAiD;IACjD,GAAG,IAAI,SAAS,MAAM,EAAE,CAAC;CAC1B;AAED;;;;;;GAMG;AACH,wBAAgB,uBAAuB,CACrC,KAAK,EAAE,SAAS,gBAAgB,EAAE,GACjC,iBAAiB,CAenB"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Workspace Framework — the type registry.
|
|
3
|
+
*
|
|
4
|
+
* A value-based, immutable registry (no module-global mutable state): the
|
|
5
|
+
* app composes shell built-ins + product-registered types ONCE and hands
|
|
6
|
+
* the result to the WorkspaceHost. Registration is compile-time honest
|
|
7
|
+
* (ids come from the declared vocabulary); resolution accepts any string —
|
|
8
|
+
* runtime data — and FAILS CLOSED on an unknown/unregistered id.
|
|
9
|
+
*
|
|
10
|
+
* Frame-free by design (Separation Law): nothing here imports the shell.
|
|
11
|
+
*/
|
|
12
|
+
/**
|
|
13
|
+
* Build a registry from workspace types (shell built-ins first, then product
|
|
14
|
+
* additions, combined by the caller). A DUPLICATE id throws — registration
|
|
15
|
+
* is composition-time, so a collision is a programming error, never a
|
|
16
|
+
* runtime negotiation (last-write-wins would let a product silently replace
|
|
17
|
+
* a shell built-in).
|
|
18
|
+
*/
|
|
19
|
+
export function createWorkspaceRegistry(types) {
|
|
20
|
+
const byId = new Map();
|
|
21
|
+
for (const type of types) {
|
|
22
|
+
if (byId.has(type.id)) {
|
|
23
|
+
throw new Error(`createWorkspaceRegistry: duplicate workspace type id "${type.id}"`);
|
|
24
|
+
}
|
|
25
|
+
byId.set(type.id, type);
|
|
26
|
+
}
|
|
27
|
+
return {
|
|
28
|
+
get: (id) => byId.get(id),
|
|
29
|
+
has: (id) => byId.has(id),
|
|
30
|
+
ids: () => [...byId.keys()],
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
//# sourceMappingURL=registry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"registry.js","sourceRoot":"","sources":["../../src/workspace/registry.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAcH;;;;;;GAMG;AACH,MAAM,UAAU,uBAAuB,CACrC,KAAkC;IAElC,MAAM,IAAI,GAAG,IAAI,GAAG,EAA4B,CAAC;IACjD,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,IAAI,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC;YACtB,MAAM,IAAI,KAAK,CACb,yDAAyD,IAAI,CAAC,EAAE,GAAG,CACpE,CAAC;QACJ,CAAC;QACD,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,EAAE,IAAI,CAAC,CAAC;IAC1B,CAAC;IACD,OAAO;QACL,GAAG,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;QACzB,GAAG,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;QACzB,GAAG,EAAE,GAAG,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;KAC5B,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Workspace Framework — the type contract (the shell's main-region seam).
|
|
3
|
+
*
|
|
4
|
+
* The shell's main region is a WORKSPACE, not a page body: an operator
|
|
5
|
+
* surface is an AI-native operating environment, and what fills its main
|
|
6
|
+
* region is a typed, registered workspace — a canvas, a graph exploration,
|
|
7
|
+
* a data table, a form, a dashboard — mounted through one host
|
|
8
|
+
* (docs/design/frontend-platform-v1-mission.md, the Workspace Framework
|
|
9
|
+
* correction).
|
|
10
|
+
*
|
|
11
|
+
* This subtree is deliberately SELF-CONTAINED: it imports nothing from the
|
|
12
|
+
* shell frame (frame/header/sidebar/nav/flavor/guard/icons), so a future
|
|
13
|
+
* extraction into its own package is a photograph, not a negotiation
|
|
14
|
+
* (Separation Law, docs/design/separation-law.md).
|
|
15
|
+
*/
|
|
16
|
+
import type * as React from "react";
|
|
17
|
+
/**
|
|
18
|
+
* The full V1 workspace-type vocabulary, declared NOW so later types are
|
|
19
|
+
* additions, never surgery:
|
|
20
|
+
*
|
|
21
|
+
* - `canvas` — a Canvas workspace over @consciousclouds/canvas-sdk +
|
|
22
|
+
* canvas-runtime (first-class; consumed, never rebuilt).
|
|
23
|
+
* - `dashboard` — stat/overview composition (built-in, this mission).
|
|
24
|
+
* - `table` — tabular data exploration (built-in, this mission).
|
|
25
|
+
* - `form` — structured input/editing (built-in, this mission).
|
|
26
|
+
* - `graph` — entity-relationship exploration over existing reads.
|
|
27
|
+
* - `map` — geographic workspace (typed seam; no honest data source
|
|
28
|
+
* yet — deferred implementation).
|
|
29
|
+
* - `timeline` — temporal/event workspace (typed seam; deferred).
|
|
30
|
+
* - `workflow` — durable-process workspace (typed seam; deferred — see
|
|
31
|
+
* docs/design/workflow-contract.md for the backend dual).
|
|
32
|
+
* - `ai-session`— a reasoning/AI-session workspace (typed seam; deferred).
|
|
33
|
+
*/
|
|
34
|
+
export declare const WORKSPACE_TYPE_IDS: readonly ["canvas", "dashboard", "table", "form", "graph", "map", "timeline", "workflow", "ai-session"];
|
|
35
|
+
/** One of the nine declared workspace-type ids. */
|
|
36
|
+
export type WorkspaceTypeId = (typeof WORKSPACE_TYPE_IDS)[number];
|
|
37
|
+
/** Type guard: is this string one of the declared V1 workspace-type ids? */
|
|
38
|
+
export declare function isWorkspaceTypeId(id: string): id is WorkspaceTypeId;
|
|
39
|
+
/**
|
|
40
|
+
* The mount contract — what every workspace component receives from the
|
|
41
|
+
* host. `input` is the page/route-supplied data for THIS mount (typed per
|
|
42
|
+
* workspace type); the framework carries it opaquely and never interprets it.
|
|
43
|
+
*/
|
|
44
|
+
export interface WorkspaceComponentProps<TInput = unknown> {
|
|
45
|
+
/** The type id this component was registered under. */
|
|
46
|
+
typeId: string;
|
|
47
|
+
/** Optional instance title (display only; the host renders no chrome for it). */
|
|
48
|
+
title?: string;
|
|
49
|
+
/** The mount's input data — meaning belongs to the workspace type. */
|
|
50
|
+
input: TInput;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* A registered workspace type: id + display metadata + the component the
|
|
54
|
+
* host mounts. Registration is composition-time (shell built-ins + product
|
|
55
|
+
* additions); resolution at render time is fail-closed.
|
|
56
|
+
*/
|
|
57
|
+
export interface WorkspaceType<TInput = unknown> {
|
|
58
|
+
/** One of the declared vocabulary ids (compile-time checked). */
|
|
59
|
+
id: WorkspaceTypeId;
|
|
60
|
+
/** Human display name (e.g. `Canvas`, `Data Table`). */
|
|
61
|
+
displayName: string;
|
|
62
|
+
/** One-line description of what this workspace type presents. */
|
|
63
|
+
description?: string;
|
|
64
|
+
/**
|
|
65
|
+
* Icon by NAME, resolved through the shell's icon registry by whoever
|
|
66
|
+
* renders workspace chrome — never an imported component here (the
|
|
67
|
+
* subtree stays frame-free).
|
|
68
|
+
*/
|
|
69
|
+
icon?: string;
|
|
70
|
+
/** The component the WorkspaceHost mounts for this type. */
|
|
71
|
+
Component: React.ComponentType<WorkspaceComponentProps<TInput>>;
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* A workspace type as stored/resolved — input typing is erased at the
|
|
75
|
+
* registry boundary (heterogeneous types share one registry; each mount
|
|
76
|
+
* re-establishes its own `TInput`).
|
|
77
|
+
*/
|
|
78
|
+
export type AnyWorkspaceType = WorkspaceType<any>;
|
|
79
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/workspace/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,KAAK,KAAK,KAAK,MAAM,OAAO,CAAC;AAEpC;;;;;;;;;;;;;;;;GAgBG;AACH,eAAO,MAAM,kBAAkB,yGAUrB,CAAC;AAEX,mDAAmD;AACnD,MAAM,MAAM,eAAe,GAAG,CAAC,OAAO,kBAAkB,CAAC,CAAC,MAAM,CAAC,CAAC;AAElE,4EAA4E;AAC5E,wBAAgB,iBAAiB,CAAC,EAAE,EAAE,MAAM,GAAG,EAAE,IAAI,eAAe,CAEnE;AAED;;;;GAIG;AACH,MAAM,WAAW,uBAAuB,CAAC,MAAM,GAAG,OAAO;IACvD,uDAAuD;IACvD,MAAM,EAAE,MAAM,CAAC;IACf,iFAAiF;IACjF,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,sEAAsE;IACtE,KAAK,EAAE,MAAM,CAAC;CACf;AAED;;;;GAIG;AACH,MAAM,WAAW,aAAa,CAAC,MAAM,GAAG,OAAO;IAC7C,iEAAiE;IACjE,EAAE,EAAE,eAAe,CAAC;IACpB,wDAAwD;IACxD,WAAW,EAAE,MAAM,CAAC;IACpB,iEAAiE;IACjE,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;;OAIG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,4DAA4D;IAC5D,SAAS,EAAE,KAAK,CAAC,aAAa,CAAC,uBAAuB,CAAC,MAAM,CAAC,CAAC,CAAC;CACjE;AAED;;;;GAIG;AAEH,MAAM,MAAM,gBAAgB,GAAG,aAAa,CAAC,GAAG,CAAC,CAAC"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Workspace Framework — the type contract (the shell's main-region seam).
|
|
3
|
+
*
|
|
4
|
+
* The shell's main region is a WORKSPACE, not a page body: an operator
|
|
5
|
+
* surface is an AI-native operating environment, and what fills its main
|
|
6
|
+
* region is a typed, registered workspace — a canvas, a graph exploration,
|
|
7
|
+
* a data table, a form, a dashboard — mounted through one host
|
|
8
|
+
* (docs/design/frontend-platform-v1-mission.md, the Workspace Framework
|
|
9
|
+
* correction).
|
|
10
|
+
*
|
|
11
|
+
* This subtree is deliberately SELF-CONTAINED: it imports nothing from the
|
|
12
|
+
* shell frame (frame/header/sidebar/nav/flavor/guard/icons), so a future
|
|
13
|
+
* extraction into its own package is a photograph, not a negotiation
|
|
14
|
+
* (Separation Law, docs/design/separation-law.md).
|
|
15
|
+
*/
|
|
16
|
+
/**
|
|
17
|
+
* The full V1 workspace-type vocabulary, declared NOW so later types are
|
|
18
|
+
* additions, never surgery:
|
|
19
|
+
*
|
|
20
|
+
* - `canvas` — a Canvas workspace over @consciousclouds/canvas-sdk +
|
|
21
|
+
* canvas-runtime (first-class; consumed, never rebuilt).
|
|
22
|
+
* - `dashboard` — stat/overview composition (built-in, this mission).
|
|
23
|
+
* - `table` — tabular data exploration (built-in, this mission).
|
|
24
|
+
* - `form` — structured input/editing (built-in, this mission).
|
|
25
|
+
* - `graph` — entity-relationship exploration over existing reads.
|
|
26
|
+
* - `map` — geographic workspace (typed seam; no honest data source
|
|
27
|
+
* yet — deferred implementation).
|
|
28
|
+
* - `timeline` — temporal/event workspace (typed seam; deferred).
|
|
29
|
+
* - `workflow` — durable-process workspace (typed seam; deferred — see
|
|
30
|
+
* docs/design/workflow-contract.md for the backend dual).
|
|
31
|
+
* - `ai-session`— a reasoning/AI-session workspace (typed seam; deferred).
|
|
32
|
+
*/
|
|
33
|
+
export const WORKSPACE_TYPE_IDS = [
|
|
34
|
+
"canvas",
|
|
35
|
+
"dashboard",
|
|
36
|
+
"table",
|
|
37
|
+
"form",
|
|
38
|
+
"graph",
|
|
39
|
+
"map",
|
|
40
|
+
"timeline",
|
|
41
|
+
"workflow",
|
|
42
|
+
"ai-session",
|
|
43
|
+
];
|
|
44
|
+
/** Type guard: is this string one of the declared V1 workspace-type ids? */
|
|
45
|
+
export function isWorkspaceTypeId(id) {
|
|
46
|
+
return WORKSPACE_TYPE_IDS.includes(id);
|
|
47
|
+
}
|
|
48
|
+
//# sourceMappingURL=types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/workspace/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAIH;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG;IAChC,QAAQ;IACR,WAAW;IACX,OAAO;IACP,MAAM;IACN,OAAO;IACP,KAAK;IACL,UAAU;IACV,UAAU;IACV,YAAY;CACJ,CAAC;AAKX,4EAA4E;AAC5E,MAAM,UAAU,iBAAiB,CAAC,EAAU;IAC1C,OAAQ,kBAAwC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AAChE,CAAC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@consciousclouds/operator-shell",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "ConsciousClouds Operator Shell — the operator-console shell archetype: frame, header, sidebar, nav engine, icon registry, OperatorFlavor types, permission-guard slot, and the Chief region (panel chrome over assistant-surface; transport injected via TurnAdapter — the product owns the wire). Layer 4 of the Frontend Platform.",
|
|
5
|
+
"license": "Apache-2.0",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"main": "./dist/index.js",
|
|
8
|
+
"types": "./dist/index.d.ts",
|
|
9
|
+
"exports": {
|
|
10
|
+
".": {
|
|
11
|
+
"types": "./dist/index.d.ts",
|
|
12
|
+
"import": "./dist/index.js"
|
|
13
|
+
},
|
|
14
|
+
"./styles/source.css": "./styles/source.css"
|
|
15
|
+
},
|
|
16
|
+
"files": [
|
|
17
|
+
"dist",
|
|
18
|
+
"styles",
|
|
19
|
+
"README.md",
|
|
20
|
+
"CHANGELOG.md",
|
|
21
|
+
"LICENSE"
|
|
22
|
+
],
|
|
23
|
+
"scripts": {
|
|
24
|
+
"build": "tsc -p tsconfig.build.json",
|
|
25
|
+
"clean": "rm -rf dist",
|
|
26
|
+
"test": "bun test",
|
|
27
|
+
"type-check": "tsc --noEmit",
|
|
28
|
+
"prepublishOnly": "bun run clean && bun run build && bun run type-check"
|
|
29
|
+
},
|
|
30
|
+
"dependencies": {
|
|
31
|
+
"@consciousclouds/assistant-surface": "0.2.0",
|
|
32
|
+
"@consciousclouds/brand": "0.1.0",
|
|
33
|
+
"@consciousclouds/canvas-runtime": "0.2.0",
|
|
34
|
+
"@consciousclouds/canvas-sdk": "0.2.0",
|
|
35
|
+
"@consciousclouds/conductor-react": "0.1.0",
|
|
36
|
+
"@consciousclouds/conductor-sdk": "0.1.0",
|
|
37
|
+
"@consciousclouds/frontend-runtime": "0.2.0",
|
|
38
|
+
"@consciousclouds/ui": "0.1.0",
|
|
39
|
+
"lucide-react": "^1.7.0"
|
|
40
|
+
},
|
|
41
|
+
"peerDependencies": {
|
|
42
|
+
"@consciousclouds/tokens": "0.1.0",
|
|
43
|
+
"next": ">=15.0.0 <17.0.0",
|
|
44
|
+
"react": ">=18.0.0"
|
|
45
|
+
},
|
|
46
|
+
"devDependencies": {
|
|
47
|
+
"@consciousclouds/tokens": "0.1.0",
|
|
48
|
+
"@happy-dom/global-registrator": "^20.10.3",
|
|
49
|
+
"@types/react": "^19.2.7",
|
|
50
|
+
"@types/react-dom": "^19.2.1",
|
|
51
|
+
"happy-dom": "^20.10.3",
|
|
52
|
+
"next": "^16.1.6",
|
|
53
|
+
"react": "19.2.4",
|
|
54
|
+
"react-dom": "19.2.4",
|
|
55
|
+
"typescript": "^5.7.2"
|
|
56
|
+
},
|
|
57
|
+
"publishConfig": {
|
|
58
|
+
"access": "public"
|
|
59
|
+
},
|
|
60
|
+
"engines": {
|
|
61
|
+
"bun": ">=1.0.0",
|
|
62
|
+
"node": ">=18.0.0"
|
|
63
|
+
}
|
|
64
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* @consciousclouds/operator-shell — Tailwind v4 source registration.
|
|
3
|
+
*
|
|
4
|
+
* Tailwind v4 does not scan node_modules: without this, utility classes that
|
|
5
|
+
* exist ONLY inside this package's components would be missing from an app's
|
|
6
|
+
* generated CSS. Import from the app's Tailwind entry stylesheet, after
|
|
7
|
+
* Tailwind itself:
|
|
8
|
+
*
|
|
9
|
+
* @import "tailwindcss";
|
|
10
|
+
* @import "@consciousclouds/operator-shell/styles/source.css";
|
|
11
|
+
*
|
|
12
|
+
* The path is relative to THIS file, so it resolves inside the installed
|
|
13
|
+
* package regardless of where the consuming app lives.
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
@source "../dist";
|