@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,46 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
/**
|
|
4
|
+
* ChiefPanel — the AI Region's RAIL placement: an always-open inflow
|
|
5
|
+
* assistant rail mounted through @consciousclouds/assistant-surface's
|
|
6
|
+
* headless hook (open, non-modal, non-dismissible). The turn flow lives in
|
|
7
|
+
* useChiefTurn and the body in ChiefSession — shared verbatim with the
|
|
8
|
+
* drawer placement (ChiefDrawer); this file is only the right-rail chrome.
|
|
9
|
+
*
|
|
10
|
+
* Two shapes off one turn:
|
|
11
|
+
* - a deterministic command moves the surface via a `routed` event — ZERO
|
|
12
|
+
* model tokens (only honored when the destination is part of this
|
|
13
|
+
* console, DERIVED from the Flavor's nav; off-console targets are
|
|
14
|
+
* reported, not navigated to);
|
|
15
|
+
* - any other question is a router miss → the model reasons over the
|
|
16
|
+
* granted knowledge envelope and streams the answer here.
|
|
17
|
+
*
|
|
18
|
+
* The chat is just the access point; the operator intelligence is the
|
|
19
|
+
* knowledge underneath. Transport is the injected TurnAdapter's — the shell
|
|
20
|
+
* never owns the wire (P1-1).
|
|
21
|
+
*/
|
|
22
|
+
import * as React from "react";
|
|
23
|
+
import { Sparkles } from "lucide-react";
|
|
24
|
+
import { useAssistantSurface } from "@consciousclouds/assistant-surface";
|
|
25
|
+
import { cn } from "@consciousclouds/ui";
|
|
26
|
+
import { ChiefSession } from "./ChiefSession.js";
|
|
27
|
+
import { useChiefShortcut } from "./use-chief-shortcut.js";
|
|
28
|
+
import { useChiefTurn } from "./use-chief-turn.js";
|
|
29
|
+
export function ChiefPanel({ flavor, adapter, className }) {
|
|
30
|
+
const session = useChiefTurn({ flavor, adapter });
|
|
31
|
+
// Headless assistant-surface mount (inflow: always open, non-modal,
|
|
32
|
+
// non-dismissible). The drawer placement is the same content behind the
|
|
33
|
+
// sheet primitive — see ChiefRegion for the placement switch.
|
|
34
|
+
const surface = useAssistantSurface({
|
|
35
|
+
open: true,
|
|
36
|
+
onOpenChange: () => { },
|
|
37
|
+
surfaceId: "operator-shell-chief",
|
|
38
|
+
"aria-label": session.title,
|
|
39
|
+
});
|
|
40
|
+
// The shell-owned Chief keybinding (⌘J / Ctrl+J — use-chief-shortcut.ts).
|
|
41
|
+
// The rail is always open, so invocation here means: focus the composer.
|
|
42
|
+
const composerRef = React.useRef(null);
|
|
43
|
+
useChiefShortcut(() => composerRef.current?.focus());
|
|
44
|
+
return (_jsxs("aside", { ref: surface.surfaceRef, ...surface.surfaceProps, className: cn("hidden w-[340px] shrink-0 flex-col border-l border-border bg-background xl:flex", className), children: [_jsxs("div", { className: "flex h-12 shrink-0 items-center gap-2 border-b border-border px-4", children: [_jsx("div", { className: "flex size-6 items-center justify-center rounded-md bg-primary/10 text-primary", children: _jsx(Sparkles, { className: "size-3.5" }) }), _jsx("div", { className: "text-sm font-medium", children: session.title })] }), _jsx(ChiefSession, { session: session, composerRef: composerRef })] }));
|
|
45
|
+
}
|
|
46
|
+
//# sourceMappingURL=ChiefPanel.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ChiefPanel.js","sourceRoot":"","sources":["../../src/chief/ChiefPanel.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAC;;AAEb;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AAExC,OAAO,EAAE,mBAAmB,EAAE,MAAM,oCAAoC,CAAC;AACzE,OAAO,EAAE,EAAE,EAAE,MAAM,qBAAqB,CAAC;AAGzC,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAEjD,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAC3D,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AASnD,MAAM,UAAU,UAAU,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,SAAS,EAAmB;IACxE,MAAM,OAAO,GAAG,YAAY,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,CAAC;IAElD,oEAAoE;IACpE,wEAAwE;IACxE,8DAA8D;IAC9D,MAAM,OAAO,GAAG,mBAAmB,CAAC;QAClC,IAAI,EAAE,IAAI;QACV,YAAY,EAAE,GAAG,EAAE,GAAE,CAAC;QACtB,SAAS,EAAE,sBAAsB;QACjC,YAAY,EAAE,OAAO,CAAC,KAAK;KAC5B,CAAC,CAAC;IAEH,0EAA0E;IAC1E,yEAAyE;IACzE,MAAM,WAAW,GAAG,KAAK,CAAC,MAAM,CAAmB,IAAI,CAAC,CAAC;IACzD,gBAAgB,CAAC,GAAG,EAAE,CAAC,WAAW,CAAC,OAAO,EAAE,KAAK,EAAE,CAAC,CAAC;IAErD,OAAO,CACL,iBACE,GAAG,EAAE,OAAO,CAAC,UAAU,KACnB,OAAO,CAAC,YAAY,EACxB,SAAS,EAAE,EAAE,CACX,iFAAiF,EACjF,SAAS,CACV,aAED,eAAK,SAAS,EAAC,mEAAmE,aAChF,cAAK,SAAS,EAAC,+EAA+E,YAC5F,KAAC,QAAQ,IAAC,SAAS,EAAC,UAAU,GAAG,GAC7B,EACN,cAAK,SAAS,EAAC,qBAAqB,YAAE,OAAO,CAAC,KAAK,GAAO,IACtD,EAEN,KAAC,YAAY,IAAC,OAAO,EAAE,OAAO,EAAE,WAAW,EAAE,WAAW,GAAI,IACtD,CACT,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { OperatorFlavor } from "../flavor/types.js";
|
|
2
|
+
import type { TurnAdapter } from "./turn-adapter.js";
|
|
3
|
+
export interface ChiefRegionProps {
|
|
4
|
+
flavor: OperatorFlavor;
|
|
5
|
+
/** The product's transport (P1-1). The shell owns the region, never the wire. */
|
|
6
|
+
adapter: TurnAdapter;
|
|
7
|
+
}
|
|
8
|
+
export declare function ChiefRegion({ flavor, adapter }: ChiefRegionProps): import("react/jsx-runtime").JSX.Element;
|
|
9
|
+
//# sourceMappingURL=ChiefRegion.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ChiefRegion.d.ts","sourceRoot":"","sources":["../../src/chief/ChiefRegion.tsx"],"names":[],"mappings":"AA2BA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAGzD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAkBrD,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,cAAc,CAAC;IACvB,iFAAiF;IACjF,OAAO,EAAE,WAAW,CAAC;CACtB;AAED,wBAAgB,WAAW,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,EAAE,gBAAgB,2CAYhE"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
3
|
+
/**
|
|
4
|
+
* ChiefRegion — the shell's AI REGION: the one place Chief mounts, resolving
|
|
5
|
+
* `flavor.chief.placement` to a presentation. Placement is Flavor decoration
|
|
6
|
+
* (P1-1): it moves the panel, never the behavior — every placement runs the
|
|
7
|
+
* same useChiefTurn flow over the same injected TurnAdapter, the same
|
|
8
|
+
* conductor event vocabulary, and the same routed-directive guard.
|
|
9
|
+
*
|
|
10
|
+
* - `rail` (default): the always-open inflow right rail (ChiefPanel).
|
|
11
|
+
* Below the xl breakpoint — where the rail's `hidden xl:flex` chrome
|
|
12
|
+
* disappears — the region falls back to the DRAWER so Chief stays
|
|
13
|
+
* reachable on narrow viewports instead of silently vanishing (the rail
|
|
14
|
+
* was CSS-hidden there before; now the same seam that makes placement
|
|
15
|
+
* configurable also closes that gap).
|
|
16
|
+
* - `drawer`: the same content behind the sheet primitive + a floating
|
|
17
|
+
* trigger, with assistant-surface's open/close lifecycle (ChiefDrawer).
|
|
18
|
+
*
|
|
19
|
+
* Exactly ONE presentation mounts at a time (they share the
|
|
20
|
+
* `operator-shell-chief` surface id — the single-surface rule holds). The
|
|
21
|
+
* breakpoint check is undefined until the client knows the viewport; the
|
|
22
|
+
* region then renders the rail, whose CSS already hides it below xl, so
|
|
23
|
+
* SSR/hydration stay consistent and nothing flashes.
|
|
24
|
+
*/
|
|
25
|
+
import * as React from "react";
|
|
26
|
+
import { ChiefDrawer } from "./ChiefDrawer.js";
|
|
27
|
+
import { ChiefPanel } from "./ChiefPanel.js";
|
|
28
|
+
/** Tailwind's `xl` — MUST match the rail's `hidden xl:flex` visibility. */
|
|
29
|
+
const XL_QUERY = "(min-width: 1280px)";
|
|
30
|
+
/** undefined until the client can answer (SSR/first render). */
|
|
31
|
+
function useIsXl() {
|
|
32
|
+
const [isXl, setIsXl] = React.useState(undefined);
|
|
33
|
+
React.useEffect(() => {
|
|
34
|
+
const mql = window.matchMedia(XL_QUERY);
|
|
35
|
+
const onChange = () => setIsXl(mql.matches);
|
|
36
|
+
onChange();
|
|
37
|
+
mql.addEventListener("change", onChange);
|
|
38
|
+
return () => mql.removeEventListener("change", onChange);
|
|
39
|
+
}, []);
|
|
40
|
+
return isXl;
|
|
41
|
+
}
|
|
42
|
+
export function ChiefRegion({ flavor, adapter }) {
|
|
43
|
+
const placement = flavor.chief?.placement ?? "rail";
|
|
44
|
+
const isXl = useIsXl();
|
|
45
|
+
if (placement === "drawer")
|
|
46
|
+
return _jsx(ChiefDrawer, { flavor: flavor, adapter: adapter });
|
|
47
|
+
// Rail placement: the inflow rail at xl and up; the drawer below it
|
|
48
|
+
// (where the rail is CSS-hidden). While the viewport is unknown
|
|
49
|
+
// (SSR/first client render) the rail mounts — its own CSS keeps it
|
|
50
|
+
// invisible below xl, so there is no flash either way.
|
|
51
|
+
if (isXl === false)
|
|
52
|
+
return _jsx(ChiefDrawer, { flavor: flavor, adapter: adapter });
|
|
53
|
+
return _jsx(ChiefPanel, { flavor: flavor, adapter: adapter });
|
|
54
|
+
}
|
|
55
|
+
//# sourceMappingURL=ChiefRegion.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ChiefRegion.js","sourceRoot":"","sources":["../../src/chief/ChiefRegion.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAC;;AAEb;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAG/B,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC/C,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAG7C,2EAA2E;AAC3E,MAAM,QAAQ,GAAG,qBAAqB,CAAC;AAEvC,gEAAgE;AAChE,SAAS,OAAO;IACd,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC,GAAG,KAAK,CAAC,QAAQ,CAAsB,SAAS,CAAC,CAAC;IACvE,KAAK,CAAC,SAAS,CAAC,GAAG,EAAE;QACnB,MAAM,GAAG,GAAG,MAAM,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC;QACxC,MAAM,QAAQ,GAAG,GAAG,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;QAC5C,QAAQ,EAAE,CAAC;QACX,GAAG,CAAC,gBAAgB,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;QACzC,OAAO,GAAG,EAAE,CAAC,GAAG,CAAC,mBAAmB,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;IAC3D,CAAC,EAAE,EAAE,CAAC,CAAC;IACP,OAAO,IAAI,CAAC;AACd,CAAC;AAQD,MAAM,UAAU,WAAW,CAAC,EAAE,MAAM,EAAE,OAAO,EAAoB;IAC/D,MAAM,SAAS,GAAG,MAAM,CAAC,KAAK,EAAE,SAAS,IAAI,MAAM,CAAC;IACpD,MAAM,IAAI,GAAG,OAAO,EAAE,CAAC;IAEvB,IAAI,SAAS,KAAK,QAAQ;QAAE,OAAO,KAAC,WAAW,IAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,GAAI,CAAC;IAErF,oEAAoE;IACpE,gEAAgE;IAChE,mEAAmE;IACnE,uDAAuD;IACvD,IAAI,IAAI,KAAK,KAAK;QAAE,OAAO,KAAC,WAAW,IAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,GAAI,CAAC;IAC7E,OAAO,KAAC,UAAU,IAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,GAAI,CAAC;AAC1D,CAAC"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ChiefSession — the AI Region's shared BODY: idle hint, thread (question ·
|
|
3
|
+
* streamed answer · status line), and the composer form, rendered from a
|
|
4
|
+
* ChiefTurnSession. Pure presentation of the one turn flow — every placement
|
|
5
|
+
* (rail, drawer) mounts this same column inside its own chrome, so moving
|
|
6
|
+
* Chief never forks its behavior or its look.
|
|
7
|
+
*
|
|
8
|
+
* `composerRef` exposes the composer input to the mounting placement — the
|
|
9
|
+
* rail points the shell's ⌘J invocation at it (focus); presentation only,
|
|
10
|
+
* no behavior lives here.
|
|
11
|
+
*/
|
|
12
|
+
import type * as React from "react";
|
|
13
|
+
import type { ChiefTurnSession } from "./use-chief-turn.js";
|
|
14
|
+
export interface ChiefSessionProps {
|
|
15
|
+
session: ChiefTurnSession;
|
|
16
|
+
/** The composer input element — the placement's focus target (⌘J on the rail). */
|
|
17
|
+
composerRef?: React.Ref<HTMLInputElement>;
|
|
18
|
+
className?: string;
|
|
19
|
+
}
|
|
20
|
+
export declare function ChiefSession({ session, composerRef, className }: ChiefSessionProps): import("react/jsx-runtime").JSX.Element;
|
|
21
|
+
//# sourceMappingURL=ChiefSession.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ChiefSession.d.ts","sourceRoot":"","sources":["../../src/chief/ChiefSession.tsx"],"names":[],"mappings":"AAEA;;;;;;;;;;GAUG;AAEH,OAAO,KAAK,KAAK,KAAK,MAAM,OAAO,CAAC;AAKpC,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAE5D,MAAM,WAAW,iBAAiB;IAChC,OAAO,EAAE,gBAAgB,CAAC;IAC1B,kFAAkF;IAClF,WAAW,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,gBAAgB,CAAC,CAAC;IAC1C,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,wBAAgB,YAAY,CAAC,EAAE,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,EAAE,iBAAiB,2CAyFlF"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { ArrowRight, Loader2 } from "lucide-react";
|
|
4
|
+
import { Button, cn } from "@consciousclouds/ui";
|
|
5
|
+
export function ChiefSession({ session, composerRef, className }) {
|
|
6
|
+
const { title, placeholder, hint, hintExample, cmd, setCmd, busy, question, answer, meta, showThread, submit, } = session;
|
|
7
|
+
return (_jsxs("div", { className: cn("flex min-h-0 flex-1 flex-col", className), children: [_jsxs("div", { className: "flex min-h-0 flex-1 flex-col gap-3 overflow-y-auto p-4", children: [!showThread && (_jsxs("p", { className: "text-xs text-muted-foreground/70", children: [hint, hintExample ? (_jsxs(_Fragment, { children: [" ", "(", _jsx("span", { className: "font-medium text-foreground/80", children: hintExample }), ")"] })) : null, ". Some commands move the surface directly, with zero model tokens."] })), showThread && (_jsxs("div", { className: "space-y-3", children: [_jsx("div", { className: "text-xs font-medium text-muted-foreground", children: question }), answer && (_jsxs("div", { className: "whitespace-pre-wrap rounded-lg border border-border bg-card px-3 py-2 text-sm leading-relaxed text-foreground", children: [answer, busy && _jsx("span", { className: "ml-0.5 inline-block animate-pulse", children: "\u258D" })] })), busy && !answer && (_jsxs("div", { className: "flex items-center gap-2 text-xs text-muted-foreground", children: [_jsx(Loader2, { className: "size-3.5 animate-spin" }), " ", title, " is thinking\u2026"] })), meta && (_jsx("div", { className: cn("rounded-md border px-3 py-2 text-xs", meta.kind === "routed" && "border-primary/30 bg-primary/5 text-foreground", meta.kind === "unavailable" && "border-border bg-muted/40 text-muted-foreground", meta.kind === "error" && "border-destructive/30 bg-destructive/5 text-destructive"), children: meta.text }))] }))] }), _jsx("form", { onSubmit: submit, className: "shrink-0 border-t border-border p-3", children: _jsxs("div", { className: "flex items-center gap-2 rounded-lg border border-border bg-card px-3 py-2 focus-within:ring-1 focus-within:ring-ring", children: [_jsx("input", { ref: composerRef, value: cmd, onChange: (e) => setCmd(e.target.value), placeholder: placeholder, className: "min-w-0 flex-1 bg-transparent text-sm outline-none placeholder:text-muted-foreground/60", "aria-label": `Command ${title}` }), _jsx(Button, { type: "submit", variant: "ghost", size: "icon-xs", disabled: busy || !cmd.trim(), className: "text-primary hover:text-primary", "aria-label": "Send", children: busy ? _jsx(Loader2, { className: "size-4 animate-spin" }) : _jsx(ArrowRight, { className: "size-4" }) })] }) })] }));
|
|
8
|
+
}
|
|
9
|
+
//# sourceMappingURL=ChiefSession.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ChiefSession.js","sourceRoot":"","sources":["../../src/chief/ChiefSession.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAC;;AAeb,OAAO,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAEnD,OAAO,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,qBAAqB,CAAC;AAWjD,MAAM,UAAU,YAAY,CAAC,EAAE,OAAO,EAAE,WAAW,EAAE,SAAS,EAAqB;IACjF,MAAM,EACJ,KAAK,EACL,WAAW,EACX,IAAI,EACJ,WAAW,EACX,GAAG,EACH,MAAM,EACN,IAAI,EACJ,QAAQ,EACR,MAAM,EACN,IAAI,EACJ,UAAU,EACV,MAAM,GACP,GAAG,OAAO,CAAC;IAEZ,OAAO,CACL,eAAK,SAAS,EAAE,EAAE,CAAC,8BAA8B,EAAE,SAAS,CAAC,aAC3D,eAAK,SAAS,EAAC,wDAAwD,aACpE,CAAC,UAAU,IAAI,CACd,aAAG,SAAS,EAAC,kCAAkC,aAC5C,IAAI,EACJ,WAAW,CAAC,CAAC,CAAC,CACb,8BACG,GAAG,OACH,eAAM,SAAS,EAAC,gCAAgC,YAAE,WAAW,GAAQ,SACrE,CACJ,CAAC,CAAC,CAAC,IAAI,0EAEN,CACL,EAEA,UAAU,IAAI,CACb,eAAK,SAAS,EAAC,WAAW,aACxB,cAAK,SAAS,EAAC,2CAA2C,YAAE,QAAQ,GAAO,EAE1E,MAAM,IAAI,CACT,eAAK,SAAS,EAAC,+GAA+G,aAC3H,MAAM,EACN,IAAI,IAAI,eAAM,SAAS,EAAC,mCAAmC,uBAAS,IACjE,CACP,EAEA,IAAI,IAAI,CAAC,MAAM,IAAI,CAClB,eAAK,SAAS,EAAC,uDAAuD,aACpE,KAAC,OAAO,IAAC,SAAS,EAAC,uBAAuB,GAAG,OAAE,KAAK,0BAChD,CACP,EAEA,IAAI,IAAI,CACP,cACE,SAAS,EAAE,EAAE,CACX,qCAAqC,EACrC,IAAI,CAAC,IAAI,KAAK,QAAQ,IAAI,gDAAgD,EAC1E,IAAI,CAAC,IAAI,KAAK,aAAa,IAAI,iDAAiD,EAChF,IAAI,CAAC,IAAI,KAAK,OAAO,IAAI,yDAAyD,CACnF,YAEA,IAAI,CAAC,IAAI,GACN,CACP,IACG,CACP,IACG,EAEN,eAAM,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAC,qCAAqC,YACrE,eAAK,SAAS,EAAC,sHAAsH,aACnI,gBACE,GAAG,EAAE,WAAW,EAChB,KAAK,EAAE,GAAG,EACV,QAAQ,EAAE,CAAC,CAAsC,EAAE,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAC5E,WAAW,EAAE,WAAW,EACxB,SAAS,EAAC,yFAAyF,gBACvF,WAAW,KAAK,EAAE,GAC9B,EACF,KAAC,MAAM,IACL,IAAI,EAAC,QAAQ,EACb,OAAO,EAAC,OAAO,EACf,IAAI,EAAC,SAAS,EACd,QAAQ,EAAE,IAAI,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,EAC7B,SAAS,EAAC,iCAAiC,gBAChC,MAAM,YAEhB,IAAI,CAAC,CAAC,CAAC,KAAC,OAAO,IAAC,SAAS,EAAC,qBAAqB,GAAG,CAAC,CAAC,CAAC,KAAC,UAAU,IAAC,SAAS,EAAC,QAAQ,GAAG,GAChF,IACL,GACD,IACH,CACP,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Routed-directive handling — the shell's half of the deterministic
|
|
3
|
+
* navigation path. The conductor's `routed` event carries a
|
|
4
|
+
* `NavigationDirective` (the canonical wire shape from
|
|
5
|
+
* `@consciousclouds/conductor-react`); the shell turns it into an app href.
|
|
6
|
+
* Whether that href is honored is decided against routes DERIVED from the
|
|
7
|
+
* Flavor's nav (see ../nav/routes.ts) — never a hardcoded list.
|
|
8
|
+
*/
|
|
9
|
+
import type { NavigationDirective } from "@consciousclouds/conductor-react";
|
|
10
|
+
/**
|
|
11
|
+
* directiveToHref turns a navigation directive into an app href
|
|
12
|
+
* (params → query string). Carried over from the reference shell.
|
|
13
|
+
*/
|
|
14
|
+
export declare function directiveToHref(directive: NavigationDirective): string;
|
|
15
|
+
//# sourceMappingURL=directive.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"directive.d.ts","sourceRoot":"","sources":["../../src/chief/directive.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,kCAAkC,CAAC;AAE5E;;;GAGG;AACH,wBAAgB,eAAe,CAAC,SAAS,EAAE,mBAAmB,GAAG,MAAM,CAOtE"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Routed-directive handling — the shell's half of the deterministic
|
|
3
|
+
* navigation path. The conductor's `routed` event carries a
|
|
4
|
+
* `NavigationDirective` (the canonical wire shape from
|
|
5
|
+
* `@consciousclouds/conductor-react`); the shell turns it into an app href.
|
|
6
|
+
* Whether that href is honored is decided against routes DERIVED from the
|
|
7
|
+
* Flavor's nav (see ../nav/routes.ts) — never a hardcoded list.
|
|
8
|
+
*/
|
|
9
|
+
/**
|
|
10
|
+
* directiveToHref turns a navigation directive into an app href
|
|
11
|
+
* (params → query string). Carried over from the reference shell.
|
|
12
|
+
*/
|
|
13
|
+
export function directiveToHref(directive) {
|
|
14
|
+
if (!directive.target)
|
|
15
|
+
return "/";
|
|
16
|
+
const entries = Object.entries(directive.params ?? {}).map(([key, value]) => [key, String(value)]);
|
|
17
|
+
const qs = entries.length > 0 ? new URLSearchParams(entries).toString() : "";
|
|
18
|
+
return qs ? `${directive.target}?${qs}` : directive.target;
|
|
19
|
+
}
|
|
20
|
+
//# sourceMappingURL=directive.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"directive.js","sourceRoot":"","sources":["../../src/chief/directive.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAIH;;;GAGG;AACH,MAAM,UAAU,eAAe,CAAC,SAA8B;IAC5D,IAAI,CAAC,SAAS,CAAC,MAAM;QAAE,OAAO,GAAG,CAAC;IAClC,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC,GAAG,CACxD,CAAC,CAAC,GAAG,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,EAAE,MAAM,CAAC,KAAK,CAAC,CAAqB,CAC3D,CAAC;IACF,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,eAAe,CAAC,OAAO,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;IAC7E,OAAO,EAAE,CAAC,CAAC,CAAC,GAAG,SAAS,CAAC,MAAM,IAAI,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,MAAM,CAAC;AAC7D,CAAC"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TurnAdapter — the Chief transport seam (P1-1), per
|
|
3
|
+
* docs/design/operator-platform-contracts.md §4.
|
|
4
|
+
*
|
|
5
|
+
* THE SHELL OWNS THE PANEL; THE PRODUCT OWNS THE WIRE. The shell ships panel
|
|
6
|
+
* chrome/lifecycle, routed-directive handling, and stream-state rendering —
|
|
7
|
+
* it does NOT ship transport. The product implements and injects this
|
|
8
|
+
* adapter; its endpoint, credentials posture, and default personality stay in
|
|
9
|
+
* the product, on its own BFF/enrollment rail.
|
|
10
|
+
*
|
|
11
|
+
* VOCABULARY RULE (no parallel dialect): the adapter's event types are the
|
|
12
|
+
* existing published turn vocabulary — `ConductorEventName` /
|
|
13
|
+
* `ConductorEventDataMap` (with `DeltaEventData`, `CompletedEventData`,
|
|
14
|
+
* `ErrorEventData`, approval/tool events) from
|
|
15
|
+
* `@consciousclouds/conductor-sdk`; the navigation shape is
|
|
16
|
+
* `NavigationDirective` from `@consciousclouds/conductor-react`. The shell
|
|
17
|
+
* consumes the canonical types; an adapter maps whatever transport it wraps
|
|
18
|
+
* INTO them (`parseSseFrames` from conductor-sdk is available to adapter
|
|
19
|
+
* authors). A same-origin BFF wrapper and an `@consciousclouds/ai-client`
|
|
20
|
+
* wrapper are both valid adapters.
|
|
21
|
+
*/
|
|
22
|
+
import type { ConductorEventHandler } from "@consciousclouds/conductor-sdk";
|
|
23
|
+
/** What the panel hands the adapter — a prompt plus the Flavor's inert refs. */
|
|
24
|
+
export interface TurnAdapterRequest {
|
|
25
|
+
/** The operator's prompt. */
|
|
26
|
+
prompt: string;
|
|
27
|
+
/**
|
|
28
|
+
* The Flavor's inert personality REFERENCE (`flavor.chief.personalityRef`),
|
|
29
|
+
* passed through untouched. The adapter may read it, map it, or ignore it —
|
|
30
|
+
* the product owns what it means. Never an endpoint, never authority.
|
|
31
|
+
*/
|
|
32
|
+
personalityRef?: string;
|
|
33
|
+
}
|
|
34
|
+
/** The in-flight turn: awaitable to its end, abortable before it. */
|
|
35
|
+
export interface TurnAdapterHandle {
|
|
36
|
+
/**
|
|
37
|
+
* Resolves when the stream ends, however it ends. Turn-shaped failures
|
|
38
|
+
* arrive as `error` EVENTS, not rejections; a rejection means the adapter
|
|
39
|
+
* itself failed to reach its transport.
|
|
40
|
+
*/
|
|
41
|
+
done: Promise<void>;
|
|
42
|
+
/** Abort the in-flight turn. */
|
|
43
|
+
abort: () => void;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* The injected transport seam. In words: start a turn for a prompt → an
|
|
47
|
+
* abortable stream of turn events (conductor vocabulary) → done.
|
|
48
|
+
*/
|
|
49
|
+
export interface TurnAdapter {
|
|
50
|
+
startTurn(request: TurnAdapterRequest, onEvent: ConductorEventHandler): TurnAdapterHandle;
|
|
51
|
+
}
|
|
52
|
+
//# sourceMappingURL=turn-adapter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"turn-adapter.d.ts","sourceRoot":"","sources":["../../src/chief/turn-adapter.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,gCAAgC,CAAC;AAE5E,gFAAgF;AAChF,MAAM,WAAW,kBAAkB;IACjC,6BAA6B;IAC7B,MAAM,EAAE,MAAM,CAAC;IACf;;;;OAIG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,qEAAqE;AACrE,MAAM,WAAW,iBAAiB;IAChC;;;;OAIG;IACH,IAAI,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC;IACpB,gCAAgC;IAChC,KAAK,EAAE,MAAM,IAAI,CAAC;CACnB;AAED;;;GAGG;AACH,MAAM,WAAW,WAAW;IAC1B,SAAS,CAAC,OAAO,EAAE,kBAAkB,EAAE,OAAO,EAAE,qBAAqB,GAAG,iBAAiB,CAAC;CAC3F"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TurnAdapter — the Chief transport seam (P1-1), per
|
|
3
|
+
* docs/design/operator-platform-contracts.md §4.
|
|
4
|
+
*
|
|
5
|
+
* THE SHELL OWNS THE PANEL; THE PRODUCT OWNS THE WIRE. The shell ships panel
|
|
6
|
+
* chrome/lifecycle, routed-directive handling, and stream-state rendering —
|
|
7
|
+
* it does NOT ship transport. The product implements and injects this
|
|
8
|
+
* adapter; its endpoint, credentials posture, and default personality stay in
|
|
9
|
+
* the product, on its own BFF/enrollment rail.
|
|
10
|
+
*
|
|
11
|
+
* VOCABULARY RULE (no parallel dialect): the adapter's event types are the
|
|
12
|
+
* existing published turn vocabulary — `ConductorEventName` /
|
|
13
|
+
* `ConductorEventDataMap` (with `DeltaEventData`, `CompletedEventData`,
|
|
14
|
+
* `ErrorEventData`, approval/tool events) from
|
|
15
|
+
* `@consciousclouds/conductor-sdk`; the navigation shape is
|
|
16
|
+
* `NavigationDirective` from `@consciousclouds/conductor-react`. The shell
|
|
17
|
+
* consumes the canonical types; an adapter maps whatever transport it wraps
|
|
18
|
+
* INTO them (`parseSseFrames` from conductor-sdk is available to adapter
|
|
19
|
+
* authors). A same-origin BFF wrapper and an `@consciousclouds/ai-client`
|
|
20
|
+
* wrapper are both valid adapters.
|
|
21
|
+
*/
|
|
22
|
+
export {};
|
|
23
|
+
//# sourceMappingURL=turn-adapter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"turn-adapter.js","sourceRoot":"","sources":["../../src/chief/turn-adapter.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/** The Chief invocation key (with meta/ctrl; shift/alt refuse the match). */
|
|
2
|
+
export declare const CHIEF_SHORTCUT_KEY = "j";
|
|
3
|
+
/** Display copy for docs/UI hints — the shortcut next to the palette's ⌘K. */
|
|
4
|
+
export declare const CHIEF_SHORTCUT_LABEL = "\u2318J / Ctrl+J";
|
|
5
|
+
/**
|
|
6
|
+
* The one match rule: meta/ctrl + `j`, WITHOUT shift or alt (⌘⇧J is the
|
|
7
|
+
* browser's downloads chord — never captured). Pure and exported so the
|
|
8
|
+
* binding is provable without a DOM.
|
|
9
|
+
*/
|
|
10
|
+
export declare function isChiefShortcut(event: Pick<KeyboardEvent, "key" | "metaKey" | "ctrlKey" | "shiftKey" | "altKey">): boolean;
|
|
11
|
+
/**
|
|
12
|
+
* Attach the document-level Chief keybinding for the lifetime of the calling
|
|
13
|
+
* presentation. `onInvoke` is kept in a ref so the listener attaches once
|
|
14
|
+
* (no re-subscribe churn when the handler closes over fresh state).
|
|
15
|
+
*/
|
|
16
|
+
export declare function useChiefShortcut(onInvoke: () => void): void;
|
|
17
|
+
//# sourceMappingURL=use-chief-shortcut.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"use-chief-shortcut.d.ts","sourceRoot":"","sources":["../../src/chief/use-chief-shortcut.ts"],"names":[],"mappings":"AA2BA,6EAA6E;AAC7E,eAAO,MAAM,kBAAkB,MAAM,CAAC;AAEtC,8EAA8E;AAC9E,eAAO,MAAM,oBAAoB,qBAAgB,CAAC;AAElD;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,IAAI,CACzC,aAAa,EACb,KAAK,GAAG,SAAS,GAAG,SAAS,GAAG,UAAU,GAAG,QAAQ,CACtD,GAAG,OAAO,CAOV;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,IAAI,GAAG,IAAI,CAe3D"}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
/**
|
|
3
|
+
* useChiefShortcut — the shell-owned Chief keybinding: ⌘J / Ctrl+J invokes
|
|
4
|
+
* the AI Region, the invocation twin of the palette's ⌘K (same registry
|
|
5
|
+
* pattern: a document-level keydown listener owned by the shell, wired where
|
|
6
|
+
* the surface mounts — CommandPalette.tsx holds ⌘K; the mounted Chief
|
|
7
|
+
* presentation holds ⌘J).
|
|
8
|
+
*
|
|
9
|
+
* The key is chosen NOT to collide: ⌘K is the palette, ⌘B is the sidebar
|
|
10
|
+
* (registry sidebar keybinding), and the browser's downloads chord is
|
|
11
|
+
* ⌘⇧J / Ctrl+J-with-shift-variants — so the match REQUIRES meta/ctrl and
|
|
12
|
+
* REFUSES shift/alt (⌘⇧J stays the browser's; the palette's own ⌘K match
|
|
13
|
+
* stays untouched).
|
|
14
|
+
*
|
|
15
|
+
* What "invoke" means is the PLACEMENT's one degree of freedom — and the only
|
|
16
|
+
* one (the AI Region rule: placement moves the panel, never the behavior):
|
|
17
|
+
* - rail (ChiefPanel, always open): focus the composer input;
|
|
18
|
+
* - drawer (ChiefDrawer — declared, or the rail's below-xl fallback):
|
|
19
|
+
* toggle open/closed through assistant-surface's open/close lifecycle.
|
|
20
|
+
* Exactly ONE presentation mounts at a time (ChiefRegion — the
|
|
21
|
+
* single-surface rule), so exactly one listener is ever attached and the
|
|
22
|
+
* binding cannot double-fire across placements.
|
|
23
|
+
*/
|
|
24
|
+
import * as React from "react";
|
|
25
|
+
/** The Chief invocation key (with meta/ctrl; shift/alt refuse the match). */
|
|
26
|
+
export const CHIEF_SHORTCUT_KEY = "j";
|
|
27
|
+
/** Display copy for docs/UI hints — the shortcut next to the palette's ⌘K. */
|
|
28
|
+
export const CHIEF_SHORTCUT_LABEL = "⌘J / Ctrl+J";
|
|
29
|
+
/**
|
|
30
|
+
* The one match rule: meta/ctrl + `j`, WITHOUT shift or alt (⌘⇧J is the
|
|
31
|
+
* browser's downloads chord — never captured). Pure and exported so the
|
|
32
|
+
* binding is provable without a DOM.
|
|
33
|
+
*/
|
|
34
|
+
export function isChiefShortcut(event) {
|
|
35
|
+
return ((event.metaKey || event.ctrlKey) &&
|
|
36
|
+
!event.shiftKey &&
|
|
37
|
+
!event.altKey &&
|
|
38
|
+
event.key.toLowerCase() === CHIEF_SHORTCUT_KEY);
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Attach the document-level Chief keybinding for the lifetime of the calling
|
|
42
|
+
* presentation. `onInvoke` is kept in a ref so the listener attaches once
|
|
43
|
+
* (no re-subscribe churn when the handler closes over fresh state).
|
|
44
|
+
*/
|
|
45
|
+
export function useChiefShortcut(onInvoke) {
|
|
46
|
+
const handler = React.useRef(onInvoke);
|
|
47
|
+
React.useEffect(() => {
|
|
48
|
+
handler.current = onInvoke;
|
|
49
|
+
});
|
|
50
|
+
React.useEffect(() => {
|
|
51
|
+
const down = (event) => {
|
|
52
|
+
if (!isChiefShortcut(event))
|
|
53
|
+
return;
|
|
54
|
+
event.preventDefault();
|
|
55
|
+
handler.current();
|
|
56
|
+
};
|
|
57
|
+
document.addEventListener("keydown", down);
|
|
58
|
+
return () => document.removeEventListener("keydown", down);
|
|
59
|
+
}, []);
|
|
60
|
+
}
|
|
61
|
+
//# sourceMappingURL=use-chief-shortcut.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"use-chief-shortcut.js","sourceRoot":"","sources":["../../src/chief/use-chief-shortcut.ts"],"names":[],"mappings":"AAAA,YAAY,CAAC;AAEb;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B,6EAA6E;AAC7E,MAAM,CAAC,MAAM,kBAAkB,GAAG,GAAG,CAAC;AAEtC,8EAA8E;AAC9E,MAAM,CAAC,MAAM,oBAAoB,GAAG,aAAa,CAAC;AAElD;;;;GAIG;AACH,MAAM,UAAU,eAAe,CAAC,KAG/B;IACC,OAAO,CACL,CAAC,KAAK,CAAC,OAAO,IAAI,KAAK,CAAC,OAAO,CAAC;QAChC,CAAC,KAAK,CAAC,QAAQ;QACf,CAAC,KAAK,CAAC,MAAM;QACb,KAAK,CAAC,GAAG,CAAC,WAAW,EAAE,KAAK,kBAAkB,CAC/C,CAAC;AACJ,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,gBAAgB,CAAC,QAAoB;IACnD,MAAM,OAAO,GAAG,KAAK,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;IACvC,KAAK,CAAC,SAAS,CAAC,GAAG,EAAE;QACnB,OAAO,CAAC,OAAO,GAAG,QAAQ,CAAC;IAC7B,CAAC,CAAC,CAAC;IAEH,KAAK,CAAC,SAAS,CAAC,GAAG,EAAE;QACnB,MAAM,IAAI,GAAG,CAAC,KAAoB,EAAE,EAAE;YACpC,IAAI,CAAC,eAAe,CAAC,KAAK,CAAC;gBAAE,OAAO;YACpC,KAAK,CAAC,cAAc,EAAE,CAAC;YACvB,OAAO,CAAC,OAAO,EAAE,CAAC;QACpB,CAAC,CAAC;QACF,QAAQ,CAAC,gBAAgB,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;QAC3C,OAAO,GAAG,EAAE,CAAC,QAAQ,CAAC,mBAAmB,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;IAC7D,CAAC,EAAE,EAAE,CAAC,CAAC;AACT,CAAC"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* useChiefTurn — the Chief turn flow, extracted from the rail panel so every
|
|
3
|
+
* PLACEMENT of the AI Region (rail, drawer) runs the IDENTICAL behavior:
|
|
4
|
+
* turn lifecycle over the injected TurnAdapter (P1-1 — the product owns the
|
|
5
|
+
* wire), the conductor-sdk event vocabulary (`delta` / `routed` / `error`),
|
|
6
|
+
* the reference outcome precedence (routed > error > streamed text), and the
|
|
7
|
+
* in-console routed-directive guard DERIVED from the Flavor's nav. Placement
|
|
8
|
+
* moves the panel; it never touches this hook.
|
|
9
|
+
*/
|
|
10
|
+
import * as React from "react";
|
|
11
|
+
import type { OperatorFlavor } from "../flavor/types.js";
|
|
12
|
+
import type { TurnAdapter } from "./turn-adapter.js";
|
|
13
|
+
/** Post-turn status line: routed (0 tokens) · off-console · transport error. */
|
|
14
|
+
export interface ChiefTurnMeta {
|
|
15
|
+
kind: "routed" | "unavailable" | "error";
|
|
16
|
+
text: string;
|
|
17
|
+
}
|
|
18
|
+
/** Everything a Chief presentation (rail aside, drawer sheet) renders from. */
|
|
19
|
+
export interface ChiefTurnSession {
|
|
20
|
+
/** Panel display title (Flavor-decorated; defaults to `Chief`). */
|
|
21
|
+
title: string;
|
|
22
|
+
/** Input placeholder (defaults to `Ask {title}…`). */
|
|
23
|
+
placeholder: string;
|
|
24
|
+
/** Idle hint shown before the first turn. */
|
|
25
|
+
hint: string;
|
|
26
|
+
/** Optional emphasized example question rendered after the hint. */
|
|
27
|
+
hintExample?: string;
|
|
28
|
+
/** The composer's current input value. */
|
|
29
|
+
cmd: string;
|
|
30
|
+
setCmd: (value: string) => void;
|
|
31
|
+
/** A turn is in flight. */
|
|
32
|
+
busy: boolean;
|
|
33
|
+
/** The last submitted question (null before the first turn). */
|
|
34
|
+
question: string | null;
|
|
35
|
+
/** The streamed answer so far. */
|
|
36
|
+
answer: string;
|
|
37
|
+
/** Post-turn status (routed / off-console / error), if any. */
|
|
38
|
+
meta: ChiefTurnMeta | null;
|
|
39
|
+
/** A turn has been asked — render the thread instead of the idle hint. */
|
|
40
|
+
showThread: boolean;
|
|
41
|
+
/** Composer submit handler (form onSubmit). */
|
|
42
|
+
submit: (e: React.FormEvent) => Promise<void>;
|
|
43
|
+
}
|
|
44
|
+
export interface UseChiefTurnOptions {
|
|
45
|
+
flavor: OperatorFlavor;
|
|
46
|
+
/** The product's transport (P1-1). The shell owns the panel, never the wire. */
|
|
47
|
+
adapter: TurnAdapter;
|
|
48
|
+
}
|
|
49
|
+
export declare function useChiefTurn({ flavor, adapter }: UseChiefTurnOptions): ChiefTurnSession;
|
|
50
|
+
//# sourceMappingURL=use-chief-turn.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"use-chief-turn.d.ts","sourceRoot":"","sources":["../../src/chief/use-chief-turn.ts"],"names":[],"mappings":"AAEA;;;;;;;;GAQG;AAEH,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAM/B,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAGzD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAErD,gFAAgF;AAChF,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,QAAQ,GAAG,aAAa,GAAG,OAAO,CAAC;IACzC,IAAI,EAAE,MAAM,CAAC;CACd;AAED,+EAA+E;AAC/E,MAAM,WAAW,gBAAgB;IAC/B,mEAAmE;IACnE,KAAK,EAAE,MAAM,CAAC;IACd,sDAAsD;IACtD,WAAW,EAAE,MAAM,CAAC;IACpB,6CAA6C;IAC7C,IAAI,EAAE,MAAM,CAAC;IACb,oEAAoE;IACpE,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,0CAA0C;IAC1C,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAChC,2BAA2B;IAC3B,IAAI,EAAE,OAAO,CAAC;IACd,gEAAgE;IAChE,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,kCAAkC;IAClC,MAAM,EAAE,MAAM,CAAC;IACf,+DAA+D;IAC/D,IAAI,EAAE,aAAa,GAAG,IAAI,CAAC;IAC3B,0EAA0E;IAC1E,UAAU,EAAE,OAAO,CAAC;IACpB,+CAA+C;IAC/C,MAAM,EAAE,CAAC,CAAC,EAAE,KAAK,CAAC,SAAS,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CAC/C;AAED,MAAM,WAAW,mBAAmB;IAClC,MAAM,EAAE,cAAc,CAAC;IACvB,gFAAgF;IAChF,OAAO,EAAE,WAAW,CAAC;CACtB;AAED,wBAAgB,YAAY,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,EAAE,mBAAmB,GAAG,gBAAgB,CAwFvF"}
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
/**
|
|
3
|
+
* useChiefTurn — the Chief turn flow, extracted from the rail panel so every
|
|
4
|
+
* PLACEMENT of the AI Region (rail, drawer) runs the IDENTICAL behavior:
|
|
5
|
+
* turn lifecycle over the injected TurnAdapter (P1-1 — the product owns the
|
|
6
|
+
* wire), the conductor-sdk event vocabulary (`delta` / `routed` / `error`),
|
|
7
|
+
* the reference outcome precedence (routed > error > streamed text), and the
|
|
8
|
+
* in-console routed-directive guard DERIVED from the Flavor's nav. Placement
|
|
9
|
+
* moves the panel; it never touches this hook.
|
|
10
|
+
*/
|
|
11
|
+
import * as React from "react";
|
|
12
|
+
import { useRouter } from "next/navigation";
|
|
13
|
+
import { flavorRoutes, isRouteInConsole } from "../nav/routes.js";
|
|
14
|
+
import { directiveToHref } from "./directive.js";
|
|
15
|
+
export function useChiefTurn({ flavor, adapter }) {
|
|
16
|
+
const router = useRouter();
|
|
17
|
+
const [cmd, setCmd] = React.useState("");
|
|
18
|
+
const [busy, setBusy] = React.useState(false);
|
|
19
|
+
const [question, setQuestion] = React.useState(null);
|
|
20
|
+
const [answer, setAnswer] = React.useState("");
|
|
21
|
+
const [meta, setMeta] = React.useState(null);
|
|
22
|
+
const title = flavor.chief?.title ?? "Chief";
|
|
23
|
+
const placeholder = flavor.chief?.placeholder ?? `Ask ${title}…`;
|
|
24
|
+
const hint = flavor.chief?.hint ??
|
|
25
|
+
`Ask ${title} about this console — it reasons over the granted knowledge envelope`;
|
|
26
|
+
const hintExample = flavor.chief?.hintExample;
|
|
27
|
+
/**
|
|
28
|
+
* The set of routes this console actually serves — DERIVED from the
|
|
29
|
+
* Flavor's nav. Chief's deterministic router can emit a navigation to
|
|
30
|
+
* anything the conductor's routing table knows — including destinations
|
|
31
|
+
* this console doesn't carry. We refuse to navigate off-console rather
|
|
32
|
+
* than land the operator on a 404.
|
|
33
|
+
*/
|
|
34
|
+
const routes = React.useMemo(() => flavorRoutes(flavor.nav), [flavor.nav]);
|
|
35
|
+
async function submit(e) {
|
|
36
|
+
e.preventDefault();
|
|
37
|
+
const prompt = cmd.trim();
|
|
38
|
+
if (!prompt || busy)
|
|
39
|
+
return;
|
|
40
|
+
setBusy(true);
|
|
41
|
+
setCmd("");
|
|
42
|
+
setQuestion(prompt);
|
|
43
|
+
setAnswer("");
|
|
44
|
+
setMeta(null);
|
|
45
|
+
// Collected while streaming; resolved after the stream ends with the
|
|
46
|
+
// reference panel's outcome precedence: routed > error > streamed text.
|
|
47
|
+
const outcome = {
|
|
48
|
+
routed: null,
|
|
49
|
+
error: null,
|
|
50
|
+
};
|
|
51
|
+
try {
|
|
52
|
+
const handle = adapter.startTurn({ prompt, personalityRef: flavor.chief?.personalityRef }, (name, data) => {
|
|
53
|
+
if (name === "delta") {
|
|
54
|
+
const { text } = data;
|
|
55
|
+
setAnswer((a) => a + text);
|
|
56
|
+
}
|
|
57
|
+
else if (name === "routed") {
|
|
58
|
+
outcome.routed = data;
|
|
59
|
+
}
|
|
60
|
+
else if (name === "error") {
|
|
61
|
+
outcome.error = data.message;
|
|
62
|
+
}
|
|
63
|
+
});
|
|
64
|
+
await handle.done;
|
|
65
|
+
}
|
|
66
|
+
catch (err) {
|
|
67
|
+
outcome.error = err instanceof Error ? err.message : String(err);
|
|
68
|
+
}
|
|
69
|
+
if (outcome.routed) {
|
|
70
|
+
const href = directiveToHref(outcome.routed);
|
|
71
|
+
if (isRouteInConsole(routes, href)) {
|
|
72
|
+
setMeta({ kind: "routed", text: `routed → ${href} · 0 tokens` });
|
|
73
|
+
router.push(href);
|
|
74
|
+
}
|
|
75
|
+
else {
|
|
76
|
+
setMeta({ kind: "unavailable", text: `${href} isn't part of this console yet` });
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
else if (outcome.error) {
|
|
80
|
+
setMeta({ kind: "error", text: outcome.error });
|
|
81
|
+
}
|
|
82
|
+
setBusy(false);
|
|
83
|
+
}
|
|
84
|
+
return {
|
|
85
|
+
title,
|
|
86
|
+
placeholder,
|
|
87
|
+
hint,
|
|
88
|
+
hintExample,
|
|
89
|
+
cmd,
|
|
90
|
+
setCmd,
|
|
91
|
+
busy,
|
|
92
|
+
question,
|
|
93
|
+
answer,
|
|
94
|
+
meta,
|
|
95
|
+
showThread: question !== null,
|
|
96
|
+
submit,
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
//# sourceMappingURL=use-chief-turn.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"use-chief-turn.js","sourceRoot":"","sources":["../../src/chief/use-chief-turn.ts"],"names":[],"mappings":"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"}
|