@hanzo/rooms 0.1.88 → 0.1.90
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/App.js +7 -4
- package/dist/Chat.js +4 -0
- package/dist/Column.js +14 -3
- package/dist/Rail.d.ts +2 -1
- package/dist/Rail.js +5 -6
- package/dist/Terminals.d.ts +1 -0
- package/dist/Terminals.js +15 -0
- package/dist/Top.js +1 -1
- package/dist/lib/host.d.ts +8 -1
- package/dist/lib/host.js +13 -2
- package/dist/where.d.ts +1 -1
- package/dist/where.js +1 -1
- package/package.json +5 -3
package/dist/App.js
CHANGED
|
@@ -76,11 +76,13 @@ import { Palette } from './Palette.js';
|
|
|
76
76
|
import { summons } from './seek.js';
|
|
77
77
|
import { floor, pane } from './ground.js';
|
|
78
78
|
import { pick } from './lib/session.js';
|
|
79
|
-
import { app, go, place, studio, talk } from './lib/host.js';
|
|
79
|
+
import { app, go, place, studio, talk, TERMINALS } from './lib/host.js';
|
|
80
80
|
import { Top } from './Top.js';
|
|
81
81
|
import { FOOT, HEIGHT, TOP, useView } from './view.js';
|
|
82
82
|
/** Studio, fetched the first time the reader stands in it. */
|
|
83
83
|
const Studio = lazy(() => import('@hanzo/studio').then((m) => ({ default: m.Studio })));
|
|
84
|
+
/** Tabs, the same way: the terminals on the reader's machines (Terminals.tsx). */
|
|
85
|
+
const Terminals = lazy(() => import('./Terminals.js'));
|
|
84
86
|
/** `/` is Chat on a new conversation. */
|
|
85
87
|
const HOME = { mode: 'chat', thread: null };
|
|
86
88
|
/** The bar's height, px: the reference window's title bar. */
|
|
@@ -98,7 +100,7 @@ const INSET = {
|
|
|
98
100
|
left: 'max(var(--pane-gap), var(--safe-left))',
|
|
99
101
|
};
|
|
100
102
|
/** Where each mode was last, so the rail goes back to it. */
|
|
101
|
-
const last = { chat: '', dev: '', studio: '' };
|
|
103
|
+
const last = { chat: '', dev: '', studio: '', tabs: '' };
|
|
102
104
|
/** Whether a key press is the reader typing, where the app's keys are the field's. */
|
|
103
105
|
const typing = (e) => {
|
|
104
106
|
const el = e.target;
|
|
@@ -239,10 +241,11 @@ function Window({ bar }) {
|
|
|
239
241
|
const toChat = () => move(last.chat || talk());
|
|
240
242
|
const toDev = () => move(last.dev || app(''));
|
|
241
243
|
const toStudio = () => move(last.studio || studio(''));
|
|
244
|
+
const toTabs = () => move(TERMINALS);
|
|
242
245
|
// Another organization: picked, and the app opened in it at the mode's New.
|
|
243
246
|
const org = (o) => {
|
|
244
247
|
pick(o);
|
|
245
|
-
window.location.assign(mode === 'dev' ? app('') : mode === 'studio' ? studio('') : talk());
|
|
248
|
+
window.location.assign(mode === 'dev' ? app('') : mode === 'studio' ? studio('') : mode === 'tabs' ? TERMINALS : talk());
|
|
246
249
|
};
|
|
247
250
|
const sidebar = mode === 'studio' ? places(maker, (p) => maker.go(p)) : undefined;
|
|
248
251
|
const flip = () => setClosed(!closed);
|
|
@@ -250,5 +253,5 @@ function Window({ bar }) {
|
|
|
250
253
|
shut();
|
|
251
254
|
setFinding(true);
|
|
252
255
|
};
|
|
253
|
-
return (_jsx(AiProvider, { client: client ?? undefined, children: _jsx(HostProvider, { host: host, children: _jsx(PrefsProvider, { children: _jsxs(YStack, { ref: view, "data-slot": "window", ...(bar ? floor : null), flex: 1, minW: 0, height: "100dvh", overflow: "hidden", "$max-md": { position: 'fixed', t: TOP, l: 0, r: 0, height: HEIGHT }, children: [bar ? (_jsxs(XStack, { "data-slot": "title-bar", height: BAR, shrink: 0, items: "center", gap: 2, pl: (bar.inset ?? 0) + 6, pr: "$2", ...bar.drag, children: [_jsx(XStack, { "$max-md": { display: 'none' }, children: _jsx(Toggle, { open: !closed, onPress: flip }) }), _jsx(XStack, { $md: { display: 'none' }, children: _jsx(Toggle, { open: drawer, onPress: () => setDrawer(true), label: "Open sidebar" }) }), _jsx(Mark, { label: "Back", "data-slot": "back", onPress: () => router.back(), children: _jsx(ArrowLeft, { size: 18, "aria-hidden": true }) }), _jsx(Mark, { label: "Forward", "data-slot": "forward", onPress: () => router.forward(), children: _jsx(ArrowRight, { size: 18, "aria-hidden": true }) }), _jsx(XStack, { flex: 1, self: "stretch", ...bar.drag })] })) : null, _jsxs(XStack, { "data-room": "", "data-app": mode, "data-slot": "frame", ...(bar ? null : floor), flex: 1, minW: 0, minH: 0, pr: "var(--pane-gap)", pb: "var(--pane-gap)", pt: bar ? 0 : 'var(--pane-gap)', "$max-md": { p: 0 }, children: [_jsx(YStack, { height: "100%", "$max-md": { display: 'none' }, children: _jsx(Rail, { host: host, mode: mode, at: where, open: !closed, toggle: bar ? undefined : flip, onChat: toChat, onDev: toDev, onStudio: toStudio, go: move, onOrg: org }) }), closed ? null : (_jsx(YStack, { "$max-md": { display: 'none' }, children: _jsx(Column, { host: host, mode: mode, thread: thread, go: move, onShut: () => setClosed(true), onSeek: seek, onBack: back, places: sidebar }) })), _jsxs(YStack, { "data-slot": "stage", flex: 1, minW: 0, minH: 0, ml: "var(--pane-gap)", "$max-md": { ml: 0, pb: FOOT }, children: [bar ? null : _jsx(Top, { host: host, mode: mode, places: sidebar, go: move, onMenu: () => setDrawer(true), onChat: toChat, onDev: toDev }), _jsx(XStack, { "data-slot": "panes", flex: 1, minW: 0, minH: 0, children: mode === 'chat' ? (_jsx(Paned, { framed: true, children: _jsx(Chat, {}) })) : mode === 'studio' ? (_jsx(YStack, { render: "main", "data-slot": "pane", ...pane(), overflow: "hidden", flex: 1, minW: 0, minH: 0, children: _jsx(YStack, { flex: 1, minH: 0, height: "100%", children: _jsx(Suspense, { fallback: null, children: _jsx(Studio, { host: maker, rail: false }) }) }) })) : (_jsx(YStack, { render: "main", "data-slot": "pane", ...(run ? null : { ...pane(), overflow: 'hidden' }), flex: 1, minW: 0, minH: 0, children: plans ? null : _jsx(Builder, { host: host, rail: false }) })) })] })] }), drawer ? (_jsxs(_Fragment, { children: [_jsx(YStack, { render: "button", "aria-label": "Close sidebar", onPress: () => setDrawer(false), bg: DIM, position: "absolute", t: 0, r: 0, b: 0, l: 0, z: "var(--z-overlay)", $md: { display: 'none' } }), _jsx(YStack, { "data-slot": "drawer", position: "absolute", t: INSET.top, b: INSET.bottom, l: INSET.left, width: "min(320px, calc(100% - 2 * var(--pane-gap) - 48px))", z: "var(--z-modal)", $md: { display: 'none' }, children: _jsx(Column, { host: host, mode: mode, thread: thread, go: move, onShut: shut, onSeek: seek, onBack: back, drawer: true, places: sidebar, foot: _jsx(Rail, { host: host, mode: mode, at: where, open: true, flat: true, onChat: toChat, onDev: toDev, onStudio: toStudio, go: move, onOrg: org }) }) })] })) : null, finding ? _jsx(Palette, { go: move, onClose: found, mode: mode, host: host }) : null] }) }) }) }));
|
|
256
|
+
return (_jsx(AiProvider, { client: client ?? undefined, children: _jsx(HostProvider, { host: host, children: _jsx(PrefsProvider, { children: _jsxs(YStack, { ref: view, "data-slot": "window", ...(bar ? floor : null), flex: 1, minW: 0, height: "100dvh", overflow: "hidden", "$max-md": { position: 'fixed', t: TOP, l: 0, r: 0, height: HEIGHT }, children: [bar ? (_jsxs(XStack, { "data-slot": "title-bar", height: BAR, shrink: 0, items: "center", gap: 2, pl: (bar.inset ?? 0) + 6, pr: "$2", ...bar.drag, children: [_jsx(XStack, { "$max-md": { display: 'none' }, children: _jsx(Toggle, { open: !closed, onPress: flip }) }), _jsx(XStack, { $md: { display: 'none' }, children: _jsx(Toggle, { open: drawer, onPress: () => setDrawer(true), label: "Open sidebar" }) }), _jsx(Mark, { label: "Back", "data-slot": "back", onPress: () => router.back(), children: _jsx(ArrowLeft, { size: 18, "aria-hidden": true }) }), _jsx(Mark, { label: "Forward", "data-slot": "forward", onPress: () => router.forward(), children: _jsx(ArrowRight, { size: 18, "aria-hidden": true }) }), _jsx(XStack, { flex: 1, self: "stretch", ...bar.drag })] })) : null, _jsxs(XStack, { "data-room": "", "data-app": mode, "data-slot": "frame", ...(bar ? null : floor), flex: 1, minW: 0, minH: 0, pr: "var(--pane-gap)", pb: "var(--pane-gap)", pt: bar ? 0 : 'var(--pane-gap)', "$max-md": { p: 0 }, children: [_jsx(YStack, { height: "100%", "$max-md": { display: 'none' }, children: _jsx(Rail, { host: host, mode: mode, at: where, open: !closed, toggle: bar ? undefined : flip, onChat: toChat, onDev: toDev, onStudio: toStudio, onTabs: toTabs, go: move, onOrg: org }) }), closed || mode === 'tabs' ? null : (_jsx(YStack, { "$max-md": { display: 'none' }, children: _jsx(Column, { host: host, mode: mode, thread: thread, go: move, onShut: () => setClosed(true), onSeek: seek, onBack: back, places: sidebar }) })), _jsxs(YStack, { "data-slot": "stage", flex: 1, minW: 0, minH: 0, ml: "var(--pane-gap)", "$max-md": { ml: 0, pb: FOOT }, children: [bar ? null : _jsx(Top, { host: host, mode: mode, places: sidebar, go: move, onMenu: () => setDrawer(true), onChat: toChat, onDev: toDev }), _jsx(XStack, { "data-slot": "panes", flex: 1, minW: 0, minH: 0, children: mode === 'chat' ? (_jsx(Paned, { framed: true, children: _jsx(Chat, {}) })) : mode === 'tabs' ? (_jsx(YStack, { render: "main", "data-slot": "pane", ...pane(), overflow: "hidden", flex: 1, minW: 0, minH: 0, children: _jsx(Suspense, { fallback: null, children: _jsx(Terminals, {}) }) })) : mode === 'studio' ? (_jsx(YStack, { render: "main", "data-slot": "pane", ...pane(), overflow: "hidden", flex: 1, minW: 0, minH: 0, children: _jsx(YStack, { flex: 1, minH: 0, height: "100%", children: _jsx(Suspense, { fallback: null, children: _jsx(Studio, { host: maker, rail: false }) }) }) })) : (_jsx(YStack, { render: "main", "data-slot": "pane", ...(run ? null : { ...pane(), overflow: 'hidden' }), flex: 1, minW: 0, minH: 0, children: plans ? null : _jsx(Builder, { host: host, rail: false }) })) })] })] }), drawer ? (_jsxs(_Fragment, { children: [_jsx(YStack, { render: "button", "aria-label": "Close sidebar", onPress: () => setDrawer(false), bg: DIM, position: "absolute", t: 0, r: 0, b: 0, l: 0, z: "var(--z-overlay)", $md: { display: 'none' } }), _jsx(YStack, { "data-slot": "drawer", position: "absolute", t: INSET.top, b: INSET.bottom, l: INSET.left, width: "min(320px, calc(100% - 2 * var(--pane-gap) - 48px))", z: "var(--z-modal)", $md: { display: 'none' }, children: _jsx(Column, { host: host, mode: mode, thread: thread, go: move, onShut: shut, onSeek: seek, onBack: back, drawer: true, places: sidebar, foot: _jsx(Rail, { host: host, mode: mode, at: where, open: true, flat: true, onChat: toChat, onDev: toDev, onStudio: toStudio, onTabs: toTabs, go: move, onOrg: org }) }) })] })) : null, finding ? _jsx(Palette, { go: move, onClose: found, mode: mode, host: host }) : null] }) }) }) }));
|
|
254
257
|
}
|
package/dist/Chat.js
CHANGED
|
@@ -1169,6 +1169,10 @@ function Thread({ placeholder = message(), initial, anonymous = false, heading,
|
|
|
1169
1169
|
{ id: `u-${Date.now()}`, role: "user", content: text },
|
|
1170
1170
|
{ id: `a-${Date.now()}`, role: "assistant", content: reply },
|
|
1171
1171
|
]);
|
|
1172
|
+
// A page a plugin's answer carries (a design system's preview) opens beside it at once.
|
|
1173
|
+
const made = artifacts(reply).filter(renders);
|
|
1174
|
+
if (made.length)
|
|
1175
|
+
see(made[made.length - 1]);
|
|
1172
1176
|
if (!anonymous)
|
|
1173
1177
|
void ai.threads
|
|
1174
1178
|
.record([{ role: "user", content: text }, { role: "assistant", content: reply }], open ?? undefined)
|
package/dist/Column.js
CHANGED
|
@@ -22,7 +22,7 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
22
22
|
// its floor it shuts (`onShut`), as the sidebar's toggle shuts it.
|
|
23
23
|
import { Text, XStack, YStack } from '@hanzo/gui';
|
|
24
24
|
import { ArrowLeft, Bell, Search, Settings2, SquarePen } from 'lucide-react';
|
|
25
|
-
import { DOTS, Gutter, NEW, own, path as written, sections, tabs, useSessions } from '@hanzo/build';
|
|
25
|
+
import { DOTS, Gutter, library, NEW, own, path as written, sections, tabs, useScheduled, useSessions } from '@hanzo/build';
|
|
26
26
|
import { tidy } from './lib/title.js';
|
|
27
27
|
import { DropdownMenu } from '@hanzo/ui';
|
|
28
28
|
import { Sidebar, SidebarIconButton, SidebarItem, StatusDot } from '@hanzo/ui/chat';
|
|
@@ -98,7 +98,18 @@ export function Column({ host, mode, thread, go, onShut, onSeek, onBack, drawer
|
|
|
98
98
|
const span = useSpan(SPAN, WIDTH, FLOOR, CEIL);
|
|
99
99
|
const dev = (p) => host.go(p);
|
|
100
100
|
const at = mode === 'dev' ? spot(host.path) : null;
|
|
101
|
-
|
|
101
|
+
// Each place the rail holds lists its own rows: Library its kinds and Upload, Scheduled tasks its tasks and New task.
|
|
102
|
+
const scheduled = useScheduled(host, dev, at === 'scheduled');
|
|
103
|
+
const groups = places ??
|
|
104
|
+
(at === 'settings'
|
|
105
|
+
? sections(host, dev)
|
|
106
|
+
: at === 'customize'
|
|
107
|
+
? tabs(host, dev)
|
|
108
|
+
: at === 'library'
|
|
109
|
+
? library(host, dev)
|
|
110
|
+
: at === 'scheduled'
|
|
111
|
+
? scheduled
|
|
112
|
+
: own(host, dev));
|
|
102
113
|
const open = (row) => (row.kind === 'chat' ? go(talk(row.id)) : dev(row.id));
|
|
103
114
|
// Chat's New; Dev's is the first of its places.
|
|
104
115
|
const create = () => {
|
|
@@ -107,5 +118,5 @@ export function Column({ host, mode, thread, go, onShut, onSeek, onBack, drawer
|
|
|
107
118
|
};
|
|
108
119
|
return (_jsxs(YStack, { "data-slot": "app-column", ref: drawer ? undefined : span.ref,
|
|
109
120
|
// inline-style: `--span`, the width a drag rewrites on the element itself (span.ts); no prop sets a variable.
|
|
110
|
-
style: drawer ? undefined : span.style, position: "relative", flex: drawer ? 1 : undefined, shrink: drawer ? 1 : 0, minW: 0, height: "100%", width: drawer ? undefined : 'var(--span)', children: [_jsxs(Sidebar, { "data-slot": "app-rail", role: "navigation", "aria-label": brand(), ...(drawer ? { ...pane(), ...FLOAT } : { bg: 'transparent', borderWidth: 0 }), ...FILL, px: "$2", pt: drawer ? '$2' : 0, pb: "$2", gap: "$0", children: [at ? (_jsxs(XStack, { "data-slot": "app-head", items: "center", gap: "$1", pl: 2, pr: 2, height: 52, shrink: 0, minW: 0, children: [_jsx(SidebarIconButton, { label: "Back", "data-slot": "place-back", onPress: onBack, ...HEAD, children: _jsx(ArrowLeft, { size: 16, "aria-hidden": true }) }), _jsx(Text, { flex: 1, minW: 0, fontSize: 18, lineHeight: 24, fontWeight: "600", color: "$ink", numberOfLines: 1, "data-slot": "place-name", children: TITLE[at] })] })) : (_jsxs(XStack, { "data-slot": "app-head", items: "center", gap: "$1", pl: "$2", pr: 2, height: 52, shrink: 0, minW: 0, children: [_jsx(Text, { flex: 1, minW: 0, fontSize: 18, lineHeight: 24, fontWeight: "600", color: "$ink", numberOfLines: 1, children: wordmark(mode) }), _jsx(Activity, { host: host }), _jsx(SidebarIconButton, { label: "Search", onPress: onSeek, "aria-haspopup": "dialog", ...HEAD, children: _jsx(Search, { size: 16, "aria-hidden": true }) })] })), mode === 'chat' ? (_jsx(YStack, { role: "list", gap: 2, shrink: 0, children: _jsx(YStack, { role: "listitem", children: _jsx(SidebarItem, { "data-slot": "app-new", ...ROW, active: !thread, bg: "transparent", hoverStyle: { bg: '$hover' }, icon: _jsx(SquarePen, { size: 16, "aria-hidden": true }), onPress: create, ...keys(create), children: _jsx(Text, { fontSize: "$3", color: "$ink", children: "New chat" }) }) }) })) : (_jsx(YStack, { "data-slot": "app-places", shrink: 0, children: groups.map((g, i) => (_jsxs(YStack, { pt: i ? '$2' : 0, children: [i && g.label ? (_jsx(Text, { id: `${uid}-${g.id}`, pl: "$2", pb: 2, fontSize: "$3", color: "$soft", children: g.label })) : null, _jsx(YStack, { role: "list", "aria-labelledby": i && g.label ? `${uid}-${g.id}` : undefined, "aria-label": i && g.label ? undefined : g.label || (at ? TITLE[at] : g.id), gap: 1, children: g.links.map((link) => (_jsx(YStack, { role: "listitem", children: _jsx(SidebarItem, { ...ROW, ...(link.id === NEW ? { 'data-slot': 'app-new' } : {}), active: link.active, icon: link.id === NEW ? _jsx(SquarePen, { size: 16, "aria-hidden": true }) : link.icon, onPress: link.onPress, ...keys(() => link.onPress?.()), children: _jsx(Text, { fontSize: "$3", color: link.active ? '$ink' : '$quiet', children: link.label }) }) }, link.id))) })] }, g.id))) })), mode === 'studio' || at ? null : _jsx(Recents, { host: host, mode: mode, thread: thread, onOpen: open, onNew: create }), at ? null : (_jsxs(YStack, { gap: "$2", pt: "$2", shrink: 0, children: [_jsx(Made, {}), _jsx(Setup, {})] })), foot] }), drawer ? null : (_jsx(Gutter, { side: "left", span: span.span, floor: FLOOR, ceil: CEIL, reset: WIDTH, onSpan: span.move, onKeep: span.keep, onShut: onShut, label: "Resize sidebar" }))] }));
|
|
121
|
+
style: drawer ? undefined : span.style, position: "relative", flex: drawer ? 1 : undefined, shrink: drawer ? 1 : 0, minW: 0, height: "100%", width: drawer ? undefined : 'var(--span)', children: [_jsxs(Sidebar, { "data-slot": "app-rail", role: "navigation", "aria-label": brand(), ...(drawer ? { ...pane(), ...FLOAT } : { bg: 'transparent', borderWidth: 0 }), ...FILL, px: "$2", pt: drawer ? '$2' : 0, pb: "$2", gap: "$0", children: [at ? (_jsxs(XStack, { "data-slot": "app-head", items: "center", gap: "$1", pl: 2, pr: 2, height: 52, shrink: 0, minW: 0, children: [_jsx(SidebarIconButton, { label: "Back", "data-slot": "place-back", onPress: onBack, ...HEAD, children: _jsx(ArrowLeft, { size: 16, "aria-hidden": true }) }), _jsx(Text, { flex: 1, minW: 0, fontSize: 18, lineHeight: 24, fontWeight: "600", color: "$ink", numberOfLines: 1, "data-slot": "place-name", children: TITLE[at] })] })) : (_jsxs(XStack, { "data-slot": "app-head", items: "center", gap: "$1", pl: "$2", pr: 2, height: 52, shrink: 0, minW: 0, children: [_jsx(Text, { flex: 1, minW: 0, fontSize: 18, lineHeight: 24, fontWeight: "600", color: "$ink", numberOfLines: 1, children: wordmark(mode) }), _jsx(Activity, { host: host }), _jsx(SidebarIconButton, { label: "Search", onPress: onSeek, "aria-haspopup": "dialog", ...HEAD, children: _jsx(Search, { size: 16, "aria-hidden": true }) })] })), mode === 'chat' ? (_jsx(YStack, { role: "list", gap: 2, shrink: 0, children: _jsx(YStack, { role: "listitem", children: _jsx(SidebarItem, { "data-slot": "app-new", ...ROW, active: !thread, bg: "transparent", hoverStyle: { bg: '$hover' }, icon: _jsx(SquarePen, { size: 16, "aria-hidden": true }), onPress: create, ...keys(create), children: _jsx(Text, { fontSize: "$3", color: "$ink", children: "New chat" }) }) }) })) : (_jsx(YStack, { "data-slot": "app-places", shrink: 0, children: groups.map((g, i) => (_jsxs(YStack, { pt: i ? '$2' : 0, children: [i && g.label ? (_jsx(Text, { id: `${uid}-${g.id}`, pl: "$2", pb: 2, fontSize: "$3", color: "$soft", children: g.label })) : null, _jsx(YStack, { role: "list", "aria-labelledby": i && g.label ? `${uid}-${g.id}` : undefined, "aria-label": i && g.label ? undefined : g.label || (at ? TITLE[at] : g.id), gap: 1, children: g.links.map((link) => (_jsx(YStack, { role: "listitem", children: _jsx(SidebarItem, { ...ROW, ...(link.id === NEW ? { 'data-slot': 'app-new' } : {}), active: link.active, icon: link.id === NEW ? _jsx(SquarePen, { size: 16, "aria-hidden": true }) : link.icon, onPress: link.onPress, ...keys(() => link.onPress?.()), children: _jsx(Text, { fontSize: "$3", color: link.active ? '$ink' : '$quiet', children: link.label }) }) }, link.id))) })] }, g.id))) })), mode === 'studio' || mode === 'tabs' || at ? null : _jsx(Recents, { host: host, mode: mode, thread: thread, onOpen: open, onNew: create }), at ? null : (_jsxs(YStack, { gap: "$2", pt: "$2", shrink: 0, children: [_jsx(Made, {}), _jsx(Setup, {})] })), foot] }), drawer ? null : (_jsx(Gutter, { side: "left", span: span.span, floor: FLOOR, ceil: CEIL, reset: WIDTH, onSpan: span.move, onKeep: span.keep, onShut: onShut, label: "Resize sidebar" }))] }));
|
|
111
122
|
}
|
package/dist/Rail.d.ts
CHANGED
|
@@ -31,7 +31,7 @@ export declare function Toggle({ open, onPress, label }: {
|
|
|
31
31
|
onPress: () => void;
|
|
32
32
|
label?: string;
|
|
33
33
|
}): import("react").JSX.Element;
|
|
34
|
-
export declare function Rail({ host, mode, at, open, toggle, flat, onChat, onDev, onStudio, go, onOrg, }: {
|
|
34
|
+
export declare function Rail({ host, mode, at, open, toggle, flat, onChat, onDev, onStudio, onTabs, go, onOrg, }: {
|
|
35
35
|
host: Host;
|
|
36
36
|
mode: Place['mode'];
|
|
37
37
|
/** Dev's builder address, or null outside Dev. */
|
|
@@ -46,6 +46,7 @@ export declare function Rail({ host, mode, at, open, toggle, flat, onChat, onDev
|
|
|
46
46
|
onChat: () => void;
|
|
47
47
|
onDev: () => void;
|
|
48
48
|
onStudio: () => void;
|
|
49
|
+
onTabs: () => void;
|
|
49
50
|
/** Moves the app to an address of this page. */
|
|
50
51
|
go: (address: string) => void;
|
|
51
52
|
/** Work in another organization. */
|
package/dist/Rail.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
3
|
// The app's rail: its products as marks down the window's left edge, in one
|
|
4
|
-
// order — Chat, Dev, Studio, Library, Scheduled tasks, Customize — then
|
|
5
|
-
//
|
|
4
|
+
// order — Chat, Dev, Studio, Tabs, Library, Scheduled tasks, Customize — then
|
|
5
|
+
// More (Team, on a host of its own), and the account at the foot. It
|
|
6
6
|
// is how the app moves between its products; a phone, which has no rail,
|
|
7
7
|
// switches Chat and Dev in its bar (Top.tsx).
|
|
8
8
|
//
|
|
@@ -32,7 +32,7 @@ import { route } from '@hanzo/build';
|
|
|
32
32
|
import { DropdownMenu } from '@hanzo/ui';
|
|
33
33
|
import { out } from './help.js';
|
|
34
34
|
import { Me } from './Me.js';
|
|
35
|
-
import { app,
|
|
35
|
+
import { app, WORKSPACE } from './lib/host.js';
|
|
36
36
|
/** The rail's width, px. */
|
|
37
37
|
export const RAIL = 48;
|
|
38
38
|
/** A mark, px: a 36px square on a 44px pitch. */
|
|
@@ -64,7 +64,7 @@ export function Mark({ label, on = false, onPress, children, ...rest }) {
|
|
|
64
64
|
export function Toggle({ open, onPress, label }) {
|
|
65
65
|
return (_jsx(Mark, { label: label ?? (open ? 'Close sidebar' : 'Open sidebar'), "data-slot": "sidebar-toggle", "aria-expanded": open, onPress: onPress, children: _jsx(PanelLeft, { size: 18, "aria-hidden": true }) }));
|
|
66
66
|
}
|
|
67
|
-
export function Rail({ host, mode, at, open, toggle, flat = false, onChat, onDev, onStudio, go, onOrg, }) {
|
|
67
|
+
export function Rail({ host, mode, at, open, toggle, flat = false, onChat, onDev, onStudio, onTabs, go, onOrg, }) {
|
|
68
68
|
const here = mode === 'dev' ? spot(at) : null;
|
|
69
69
|
const to = (p) => () => go(app(p));
|
|
70
70
|
// The products on hosts of their own, behind More; on a phone the raised places lead it.
|
|
@@ -77,9 +77,8 @@ export function Rail({ host, mode, at, open, toggle, flat = false, onChat, onDev
|
|
|
77
77
|
{ type: 'separator', key: 'raised' },
|
|
78
78
|
]
|
|
79
79
|
: []),
|
|
80
|
-
{ key: 'tabs', label: 'Tabs', icon: _jsx(SquareTerminal, { size: 16, "aria-hidden": true }), onSelect: () => out(TABS) },
|
|
81
80
|
{ key: 'team', label: 'Team', icon: _jsx(Users, { size: 16, "aria-hidden": true }), onSelect: () => out(WORKSPACE) },
|
|
82
81
|
];
|
|
83
82
|
const Stack = flat ? XStack : YStack;
|
|
84
|
-
return (_jsxs(Stack, { "data-slot": "rail", render: "nav", "aria-label": "Products", ...(flat ? { pt: '$2', mt: '$2', borderTopWidth: 1, borderColor: '$borderColor', gap: '$1' } : { width: RAIL, flex: 1, pt: '$2', pb: '$2', gap: 8 }), shrink: 0, items: "center", children: [toggle ? (_jsx(YStack, { pb: 8, children: _jsx(Toggle, { open: open, onPress: toggle }) })) : null, _jsx(Mark, { label: "Chat", on: mode === 'chat', onPress: onChat, "data-slot": "rail-chat", children: _jsx(MessageSquare, { size: 18, "aria-hidden": true }) }), _jsx(Mark, { label: "Dev", on: mode === 'dev' && !here, onPress: onDev, "data-slot": "rail-dev", children: _jsx(Code2, { size: 18, "aria-hidden": true }) }), _jsx(Mark, { label: "Studio", on: mode === 'studio', onPress: onStudio, "data-slot": "rail-studio", children: _jsx(WandSparkles, { size: 18, "aria-hidden": true }) }), flat ? null : (_jsxs(_Fragment, { children: [_jsx(Mark, { label: "Library", on: here === 'library', onPress: to(RAISED.library), "data-slot": "rail-library", children: _jsx(Library, { size: 18, "aria-hidden": true }) }), _jsx(Mark, { label: "Scheduled tasks", on: here === 'scheduled', onPress: to(RAISED.scheduled), "data-slot": "rail-scheduled", children: _jsx(Clock, { size: 18, "aria-hidden": true }) }), _jsx(Mark, { label: "Customize", on: here === 'customize', onPress: to(RAISED.customize), "data-slot": "rail-customize", children: _jsx(Puzzle, { size: 18, "aria-hidden": true }) })] })), _jsx(DropdownMenu, { placement: flat ? 'top-start' : 'right-start', minWidth: 220, trigger: _jsx(XStack, { render: "button", "aria-label": "More", ...{ title: 'More' }, "data-slot": "rail-more", width: MARK, height: MARK, rounded: "$4", items: "center", justify: "center", cursor: "pointer", opacity: 0.62, hoverStyle: { bg: '$hover', opacity: 1 }, pressStyle: { bg: '$raised' }, focusVisibleStyle: { outlineWidth: 2, outlineStyle: 'solid', outlineColor: '$outlineColor' }, $touchable: { width: 44, height: 44 }, children: _jsx(Ellipsis, { size: 18, "aria-hidden": true }) }), items: rest }), _jsx(YStack, { flex: 1 }), _jsx(Me, { host: host, narrow: true, above: flat, onOrg: onOrg })] }));
|
|
83
|
+
return (_jsxs(Stack, { "data-slot": "rail", render: "nav", "aria-label": "Products", ...(flat ? { pt: '$2', mt: '$2', borderTopWidth: 1, borderColor: '$borderColor', gap: '$1' } : { width: RAIL, flex: 1, pt: '$2', pb: '$2', gap: 8 }), shrink: 0, items: "center", children: [toggle ? (_jsx(YStack, { pb: 8, children: _jsx(Toggle, { open: open, onPress: toggle }) })) : null, _jsx(Mark, { label: "Chat", on: mode === 'chat', onPress: onChat, "data-slot": "rail-chat", children: _jsx(MessageSquare, { size: 18, "aria-hidden": true }) }), _jsx(Mark, { label: "Dev", on: mode === 'dev' && !here, onPress: onDev, "data-slot": "rail-dev", children: _jsx(Code2, { size: 18, "aria-hidden": true }) }), _jsx(Mark, { label: "Studio", on: mode === 'studio', onPress: onStudio, "data-slot": "rail-studio", children: _jsx(WandSparkles, { size: 18, "aria-hidden": true }) }), _jsx(Mark, { label: "Tabs", on: mode === 'tabs', onPress: onTabs, "data-slot": "rail-tabs", children: _jsx(SquareTerminal, { size: 18, "aria-hidden": true }) }), flat ? null : (_jsxs(_Fragment, { children: [_jsx(Mark, { label: "Library", on: here === 'library', onPress: to(RAISED.library), "data-slot": "rail-library", children: _jsx(Library, { size: 18, "aria-hidden": true }) }), _jsx(Mark, { label: "Scheduled tasks", on: here === 'scheduled', onPress: to(RAISED.scheduled), "data-slot": "rail-scheduled", children: _jsx(Clock, { size: 18, "aria-hidden": true }) }), _jsx(Mark, { label: "Customize", on: here === 'customize', onPress: to(RAISED.customize), "data-slot": "rail-customize", children: _jsx(Puzzle, { size: 18, "aria-hidden": true }) })] })), _jsx(DropdownMenu, { placement: flat ? 'top-start' : 'right-start', minWidth: 220, trigger: _jsx(XStack, { render: "button", "aria-label": "More", ...{ title: 'More' }, "data-slot": "rail-more", width: MARK, height: MARK, rounded: "$4", items: "center", justify: "center", cursor: "pointer", opacity: 0.62, hoverStyle: { bg: '$hover', opacity: 1 }, pressStyle: { bg: '$raised' }, focusVisibleStyle: { outlineWidth: 2, outlineStyle: 'solid', outlineColor: '$outlineColor' }, $touchable: { width: 44, height: 44 }, children: _jsx(Ellipsis, { size: 18, "aria-hidden": true }) }), items: rest }), _jsx(YStack, { flex: 1 }), _jsx(Me, { host: host, narrow: true, above: flat, onOrg: onOrg })] }));
|
|
85
84
|
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export default function Terminals(): import("react").JSX.Element;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
// Tabs in the app: the terminals on the reader's linked machines and sandboxes,
|
|
4
|
+
// tiled (@hanzo/tabs `Workspace`), wired by `useFleet` with the reader's own
|
|
5
|
+
// bearer against this host's cloud. The workspace holds no token; the fleet
|
|
6
|
+
// mints each pane's address. hanzo.ai/tabs draws it for a signed-in reader, the
|
|
7
|
+
// way /studio draws Studio.
|
|
8
|
+
import { Text, YStack } from '@hanzo/gui';
|
|
9
|
+
import { useFleet, Workspace } from '@hanzo/tabs';
|
|
10
|
+
import { api } from './lib/api.js';
|
|
11
|
+
import { bearer } from './lib/session.js';
|
|
12
|
+
export default function Terminals() {
|
|
13
|
+
const fleet = useFleet(bearer(), api());
|
|
14
|
+
return (_jsxs(YStack, { "data-slot": "terminals", flex: 1, minH: 0, minW: 0, children: [fleet.error ? (_jsx(Text, { role: "alert", px: "$4", py: "$2", fontSize: "$2", color: "$soft", children: `The machines could not be read: ${fleet.error}` })) : null, _jsx(Workspace, { hosts: fleet.hosts, mint: fleet.mint, onLaunch: fleet.launch })] }));
|
|
15
|
+
}
|
package/dist/Top.js
CHANGED
|
@@ -54,5 +54,5 @@ export function Top({ host, mode, places, go, onMenu, onChat, onDev, }) {
|
|
|
54
54
|
},
|
|
55
55
|
}
|
|
56
56
|
: { label: made?.label ?? 'New', onPress: made?.onPress };
|
|
57
|
-
return (_jsxs(XStack, { "data-slot": "app-bar", height: `calc(${LINE}px + var(--safe-top))`, pt: "var(--safe-top)", px: "$4.5", items: "center", justify: "space-between", shrink: 0, $md: { display: 'none' }, children: [_jsx(Round, { label: "Open sidebar", "data-slot": "bar-menu", onPress: onMenu, children: _jsx(Lines, {}) }), _jsx(XStack, { "data-slot": "bar-mode", ...GLASS, height: LINE, p: "$1", items: "center", children: _jsxs(ToggleGroup, { type: "single", "aria-label": "App", value: mode === '
|
|
57
|
+
return (_jsxs(XStack, { "data-slot": "app-bar", height: `calc(${LINE}px + var(--safe-top))`, pt: "var(--safe-top)", px: "$4.5", items: "center", justify: "space-between", shrink: 0, $md: { display: 'none' }, children: [_jsx(Round, { label: "Open sidebar", "data-slot": "bar-menu", onPress: onMenu, children: _jsx(Lines, {}) }), _jsx(XStack, { "data-slot": "bar-mode", ...GLASS, height: LINE, p: "$1", items: "center", children: _jsxs(ToggleGroup, { type: "single", "aria-label": "App", value: mode === 'chat' || mode === 'dev' ? mode : '', disableDeactivation: true, onValueChange: (v) => (v === 'chat' ? onChat() : v === 'dev' ? onDev() : undefined), children: [_jsx(Side, { value: "chat", children: "Chat" }), _jsx(Side, { value: "dev", children: "Dev" })] }) }), _jsx(Round, { label: fresh.label, "data-slot": "bar-new", onPress: fresh.onPress, children: _jsx(SquarePen, { size: 20, "aria-hidden": true }) })] }));
|
|
58
58
|
}
|
package/dist/lib/host.d.ts
CHANGED
|
@@ -30,7 +30,7 @@ export declare const ENTRY = "https://hanzo.team/?signin";
|
|
|
30
30
|
* team's session has to live.
|
|
31
31
|
*/
|
|
32
32
|
export declare const START = "https://hanzo.team/start";
|
|
33
|
-
/** Hanzo Tabs
|
|
33
|
+
/** Hanzo Tabs on its own origin, which hanzo.team's shell opens; the app draws it in place at `TERMINALS`. */
|
|
34
34
|
export declare const TABS = "https://tabs.hanzo.ai";
|
|
35
35
|
/**
|
|
36
36
|
* THE APP'S ADDRESSES ARE PATHS, in two modes at two roots. Chat is /chat, a
|
|
@@ -51,6 +51,11 @@ export declare const DEV = "/dev";
|
|
|
51
51
|
* hanzo.ai/studio, whose page draws the app for a signed-in reader.
|
|
52
52
|
*/
|
|
53
53
|
export declare const STUDIO = "/studio";
|
|
54
|
+
/**
|
|
55
|
+
* Tabs: the terminals on the reader's linked machines and sandboxes, tiled
|
|
56
|
+
* (@hanzo/tabs `Workspace`), drawn in the app at hanzo.ai/tabs.
|
|
57
|
+
*/
|
|
58
|
+
export declare const TERMINALS = "/tabs";
|
|
54
59
|
/** Studio at an address of its own (@hanzo/studio `route`): '' is New, /studio. */
|
|
55
60
|
export declare const studio: (at: string) => string;
|
|
56
61
|
/** Chat on a conversation, or /chat itself for a new one. */
|
|
@@ -67,6 +72,8 @@ export type Place = {
|
|
|
67
72
|
} | {
|
|
68
73
|
mode: 'studio';
|
|
69
74
|
at: string;
|
|
75
|
+
} | {
|
|
76
|
+
mode: 'tabs';
|
|
70
77
|
};
|
|
71
78
|
/** The place a path names, or null when it names none of the app's. */
|
|
72
79
|
export declare function place(pathname: string): Place | null;
|
package/dist/lib/host.js
CHANGED
|
@@ -33,7 +33,7 @@ export const ENTRY = `${WORKSPACE}/?signin`;
|
|
|
33
33
|
* team's session has to live.
|
|
34
34
|
*/
|
|
35
35
|
export const START = `${WORKSPACE}/start`;
|
|
36
|
-
/** Hanzo Tabs
|
|
36
|
+
/** Hanzo Tabs on its own origin, which hanzo.team's shell opens; the app draws it in place at `TERMINALS`. */
|
|
37
37
|
export const TABS = 'https://tabs.hanzo.ai';
|
|
38
38
|
/**
|
|
39
39
|
* THE APP'S ADDRESSES ARE PATHS, in two modes at two roots. Chat is /chat, a
|
|
@@ -54,6 +54,11 @@ export const DEV = '/dev';
|
|
|
54
54
|
* hanzo.ai/studio, whose page draws the app for a signed-in reader.
|
|
55
55
|
*/
|
|
56
56
|
export const STUDIO = '/studio';
|
|
57
|
+
/**
|
|
58
|
+
* Tabs: the terminals on the reader's linked machines and sandboxes, tiled
|
|
59
|
+
* (@hanzo/tabs `Workspace`), drawn in the app at hanzo.ai/tabs.
|
|
60
|
+
*/
|
|
61
|
+
export const TERMINALS = '/tabs';
|
|
57
62
|
/** Studio at an address of its own (@hanzo/studio `route`): '' is New, /studio. */
|
|
58
63
|
export const studio = (at) => (at ? `${STUDIO}/${at.replace(/^\/+/, '')}` : STUDIO);
|
|
59
64
|
/** Chat on a conversation, or /chat itself for a new one. */
|
|
@@ -71,6 +76,8 @@ export function place(pathname) {
|
|
|
71
76
|
return { mode: 'dev', at: path(parse(p.slice(DEV.length))) };
|
|
72
77
|
if (p === STUDIO || p.startsWith(`${STUDIO}/`))
|
|
73
78
|
return { mode: 'studio', at: p.slice(STUDIO.length + 1) };
|
|
79
|
+
if (p === TERMINALS)
|
|
80
|
+
return { mode: 'tabs' };
|
|
74
81
|
if (!p.startsWith(`${CHAT}/`))
|
|
75
82
|
return null;
|
|
76
83
|
const id = p.slice(CHAT.length + 1);
|
|
@@ -90,6 +97,10 @@ export function page(pathname) {
|
|
|
90
97
|
return pathname;
|
|
91
98
|
if (at.mode === 'chat')
|
|
92
99
|
return at.thread ? `${CHAT}/:id` : CHAT;
|
|
100
|
+
if (at.mode === 'tabs')
|
|
101
|
+
return TERMINALS;
|
|
102
|
+
if (at.mode === 'studio')
|
|
103
|
+
return STUDIO;
|
|
93
104
|
const r = route(at.at);
|
|
94
105
|
if (r.kind === 'run')
|
|
95
106
|
return `${DEV}/run/:id`;
|
|
@@ -141,7 +152,7 @@ export function remember(mode) {
|
|
|
141
152
|
export function resume() {
|
|
142
153
|
try {
|
|
143
154
|
const kept = window.localStorage.getItem(MODE);
|
|
144
|
-
return kept === 'dev' ? DEV : kept === 'studio' ? STUDIO : CHAT;
|
|
155
|
+
return kept === 'dev' ? DEV : kept === 'studio' ? STUDIO : kept === 'tabs' ? TERMINALS : CHAT;
|
|
145
156
|
}
|
|
146
157
|
catch {
|
|
147
158
|
return CHAT;
|
package/dist/where.d.ts
CHANGED
|
@@ -74,6 +74,6 @@ export declare const where: () => Addresses;
|
|
|
74
74
|
/** The product's name, as the host states it. Read at call time, like every address. */
|
|
75
75
|
export declare const brand: () => string;
|
|
76
76
|
/** The product's name in each mode of the app: the host's brand in Chat (Hanzo AI, Hanzo Team), Hanzo Dev in Dev. */
|
|
77
|
-
export declare const wordmark: (mode: 'chat' | 'dev' | 'studio') => string;
|
|
77
|
+
export declare const wordmark: (mode: 'chat' | 'dev' | 'studio' | 'tabs') => string;
|
|
78
78
|
/** A page of the app's own, from wherever the rooms are mounted. */
|
|
79
79
|
export declare const site: (path: string) => string;
|
package/dist/where.js
CHANGED
|
@@ -12,6 +12,6 @@ export const where = () => addresses;
|
|
|
12
12
|
/** The product's name, as the host states it. Read at call time, like every address. */
|
|
13
13
|
export const brand = () => addresses.brand ?? 'Hanzo AI';
|
|
14
14
|
/** The product's name in each mode of the app: the host's brand in Chat (Hanzo AI, Hanzo Team), Hanzo Dev in Dev. */
|
|
15
|
-
export const wordmark = (mode) => (mode === 'dev' ? 'Hanzo Dev' : mode === 'studio' ? 'Hanzo Studio' : brand());
|
|
15
|
+
export const wordmark = (mode) => (mode === 'dev' ? 'Hanzo Dev' : mode === 'studio' ? 'Hanzo Studio' : mode === 'tabs' ? 'Hanzo Tabs' : brand());
|
|
16
16
|
/** A page of the app's own, from wherever the rooms are mounted. */
|
|
17
17
|
export const site = (path) => `${addresses.site}${path}`;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hanzo/rooms",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.90",
|
|
4
4
|
"description": "The workspace rooms — Home, Chat, Inbox, Contacts, Meet, Cal, Drive, Board, Work, Bots — and the frame that holds them, once, for every Hanzo surface.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -49,13 +49,14 @@
|
|
|
49
49
|
"peerDependencies": {
|
|
50
50
|
"@hanzo/ai": ">=0.6.23",
|
|
51
51
|
"@hanzo/appearance": ">=0.2.6",
|
|
52
|
-
"@hanzo/build": ">=0.2.
|
|
52
|
+
"@hanzo/build": ">=0.2.77",
|
|
53
53
|
"@hanzo/composer": ">=0.2.0",
|
|
54
54
|
"@hanzo/event": ">=0.3.56",
|
|
55
55
|
"@hanzo/gui": "^8.3.5",
|
|
56
56
|
"@hanzo/iam": ">=0.21.33",
|
|
57
57
|
"@hanzo/logo": ">=1.0.26",
|
|
58
58
|
"@hanzo/studio": ">=0.1.0",
|
|
59
|
+
"@hanzo/tabs": ">=0.1.8",
|
|
59
60
|
"@hanzo/ui": ">=8.29.0",
|
|
60
61
|
"@hanzo/usage": ">=0.1.18",
|
|
61
62
|
"@hanzo/voice": ">=0.1.16",
|
|
@@ -67,7 +68,7 @@
|
|
|
67
68
|
"devDependencies": {
|
|
68
69
|
"@hanzo/ai": "0.6.23",
|
|
69
70
|
"@hanzo/appearance": "0.2.8",
|
|
70
|
-
"@hanzo/build": "0.2.
|
|
71
|
+
"@hanzo/build": "0.2.77",
|
|
71
72
|
"@hanzo/composer": "0.2.0",
|
|
72
73
|
"@hanzo/design": "0.5.34",
|
|
73
74
|
"@hanzo/event": "0.3.56",
|
|
@@ -75,6 +76,7 @@
|
|
|
75
76
|
"@hanzo/iam": "0.21.33",
|
|
76
77
|
"@hanzo/logo": "1.0.26",
|
|
77
78
|
"@hanzo/studio": "0.1.0",
|
|
79
|
+
"@hanzo/tabs": "github:hanzo-apps/tabs#af6f1e4c02a3ef7faa192a8310e193219fa5c1c5",
|
|
78
80
|
"@hanzo/ui": "8.29.0",
|
|
79
81
|
"@hanzo/usage": "0.1.18",
|
|
80
82
|
"@hanzo/voice": "0.1.19",
|