@hanzo/app 0.2.2 → 0.2.3
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 +1 -1
- package/dist/Chat.js +2 -2
- package/dist/Me.js +6 -2
- package/dist/Settings.js +1 -0
- package/dist/SettingsPane.js +37 -1
- package/dist/Shell.js +7 -2
- package/package.json +3 -2
package/dist/App.js
CHANGED
|
@@ -262,5 +262,5 @@ function Window({ bar }) {
|
|
|
262
262
|
};
|
|
263
263
|
return (_jsx(AiProvider, { client: client ?? undefined, children: _jsx(HostProvider, { host: host, children: _jsx(PrefsProvider, { children: _jsxs(YStack, { ref: windowRef, "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, ...{ overflow: 'clip' } }, 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.state === 'open', onPress: drawer.open, label: t('Open sidebar') }) }), _jsx(Mark, { label: t('Back'), "data-slot": "back", onPress: () => router.back(), children: _jsx(ArrowLeft, { size: 18, "aria-hidden": true, "data-i18n-mirror": true }) }), _jsx(Mark, { label: t('Forward'), "data-slot": "forward", onPress: () => router.forward(), children: _jsx(ArrowRight, { size: 18, "aria-hidden": true, "data-i18n-mirror": true }) }), _jsx(XStack, { flex: 1, self: "stretch", ...bar.drag })] })) : null, _jsxs(XStack, { ref: drawer.pane, "data-room": "", "data-app": mode, "data-slot": "frame", ...(bar ? null : floor), ...(drawer.slide ? RAISED : null),
|
|
264
264
|
// inline-style: the slide, a transform with no logical form whose sign and distance the drawer writes on the element itself, a drag every frame (Drawer.tsx).
|
|
265
|
-
style: drawer.slide ?? undefined, flex: 1, minW: 0, minH: 0, paddingInlineEnd: "var(--pane-gap)", pb: "var(--pane-gap)", pt: bar ? 0 : 'var(--pane-gap)', "$max-md": { p: 0 }, children: [drawer.slide ? _jsx(Lift, {}) : null, _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, marginInlineStart: "var(--pane-gap)", "$max-md": { marginInlineStart: 0, pb: FOOT }, children: [bar ? null : _jsx(Top, { host: host, mode: mode, places: sidebar, go: move, onMenu: drawer.open, 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.state === 'shut' ? null : (_jsx(Layer, { drawer: drawer, top: bar ? BAR : 0, children: _jsx(Column, { host: host, mode: mode, thread: thread, go: move, onShut: shut, onSeek: seek, onBack: back, drawer: true, places: sidebar, rail: _jsx(Rail, { host: host, mode: mode, at: where, open: true, rows: true, onChat: toChat, onDev: toDev, onStudio: toStudio, onTabs: toTabs, go: move, onOrg: org }), foot: _jsx(Foot, { host: host, onChat: fresh, onOrg: org }) }) })), finding ? _jsx(Palette, { go: move, onClose: found, mode: mode, host: host }) : null] }) }) }) }));
|
|
265
|
+
style: drawer.slide ?? undefined, flex: 1, minW: 0, minH: 0, paddingInlineStart: closed || mode === 'tabs' ? 'var(--pane-gap)' : 0, paddingInlineEnd: "var(--pane-gap)", pb: "var(--pane-gap)", pt: bar ? 0 : 'var(--pane-gap)', "$max-md": { p: 0 }, children: [drawer.slide ? _jsx(Lift, {}) : null, _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, marginInlineStart: "var(--pane-gap)", "$max-md": { marginInlineStart: 0, pb: FOOT }, children: [bar ? null : _jsx(Top, { host: host, mode: mode, places: sidebar, go: move, onMenu: drawer.open, 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.state === 'shut' ? null : (_jsx(Layer, { drawer: drawer, top: bar ? BAR : 0, children: _jsx(Column, { host: host, mode: mode, thread: thread, go: move, onShut: shut, onSeek: seek, onBack: back, drawer: true, places: sidebar, rail: _jsx(Rail, { host: host, mode: mode, at: where, open: true, rows: true, onChat: toChat, onDev: toDev, onStudio: toStudio, onTabs: toTabs, go: move, onOrg: org }), foot: _jsx(Foot, { host: host, onChat: fresh, onOrg: org }) }) })), finding ? _jsx(Palette, { go: move, onClose: found, mode: mode, host: host }) : null] }) }) }) }));
|
|
266
266
|
}
|
package/dist/Chat.js
CHANGED
|
@@ -57,7 +57,7 @@ import { useHydrated } from "./lib/hydrated.js";
|
|
|
57
57
|
import { base, served } from "./lib/ai.js";
|
|
58
58
|
import { onServed } from "./lib/served.js";
|
|
59
59
|
import { refused as worded, speech, useDictation, useTalk, useVoice } from "@hanzo/voice";
|
|
60
|
-
import { Check, Clock, FileText, Image as ImageMark, Library as LibraryMark, Paperclip, X } from "lucide-react";
|
|
60
|
+
import { Check, Clock, FileText, Image as ImageMark, Library as LibraryMark, Paperclip, Sparkles, X } from "lucide-react";
|
|
61
61
|
import { FREE } from "./lib/ai.js";
|
|
62
62
|
import { openThread, useOpen } from "./open.js";
|
|
63
63
|
import { Beside, Framed } from "./Shell.js";
|
|
@@ -1480,7 +1480,7 @@ function Thread({ placeholder = message(), initial, anonymous = false, heading,
|
|
|
1480
1480
|
}, children: [_jsx(Schedule, { open: plan !== null, onOpenChange: (open) => {
|
|
1481
1481
|
if (!open)
|
|
1482
1482
|
setPlan(null);
|
|
1483
|
-
}, prompt: plan ?? "", model: model, models: models.map((m) => ({ id: m.id, name: nameOf(m.id, listed) })) }), dragging ? (_jsx(YStack, { "aria-hidden": true, position: "absolute", t: 0, r: 0, b: 0, l: 0, z: 10, items: "center", justify: "center", bg: "var(--surface-scrim)", borderWidth: 2, borderStyle: "dashed", borderColor: "$borderColor", rounded: "var(--pane-round)", pointerEvents: "none", children: _jsxs(XStack, { items: "center", gap: "$2", px: "$4", py: "$2.5", rounded: "$10", bg: "$background", borderWidth: 1, borderColor: "$borderColor", children: [_jsx(Paperclip, { size: 15, "aria-hidden": true }), _jsx(Text, { fontSize: "$4", color: "$ink", children: t("Drop files to attach") })] }) })) : null, _jsxs(XStack, { "data-slot": "conversation-head", height: 52, items: "center", justify: "space-between", gap: "$3", paddingInlineStart: "$4", paddingInlineEnd: "$2", shrink: 0, children: [_jsxs(XStack, { items: "center", gap: "$2", minW: 0, flex: 1, children: [mine ? (_jsx(Text, { fontSize: 15, lineHeight: 20, color: "$ink", numberOfLines: 1, shrink: 1, minW: 0, children: tidy(mine.title) })) : null, room.length ? (_jsx(XStack, { role: "list", "aria-label": t("Agents in this chat"), items: "center", gap: "$1.5", minW: 0, overflowX: "auto", "$platform-web": { scrollbarWidth: "none" }, children: room.map((name) => (_jsxs(XStack, { role: "listitem", items: "center", gap: "$1.5", paddingInlineStart: "$1", paddingInlineEnd: "$0.5", py: "$0.5", rounded: 999, borderWidth: 1, borderColor: "$borderColor", shrink: 0, children: [_jsx(Face, { src: faces[name]?.avatar ?? (name === withWhom ? portrait : undefined), emoji: faces[name]?.emoji ?? (name === withWhom ? persona?.emoji : undefined), name: name, size: 22 }), _jsx(Text, { fontSize: "$2", fontWeight: "600", color: "$color", numberOfLines: 1, display: "none", $sm: { display: "flex" }, children: name }), _jsx(Box, { render: "button", onClick: () => openAgent(name), "aria-label": t("Remove {name} from this chat", { name }), title: t("Remove {name}", { name }), width: 24, height: 24, rounded: 999, items: "center", justify: "center", hoverStyle: { bg: "$hover" }, children: _jsx(X, { size: 13, "aria-hidden": true, color: "var(--soft, var(--muted-foreground))" }) })] }, name))) })) : null] }), _jsxs(XStack, { "data-slot": "conversation-controls", items: "center", gap:
|
|
1483
|
+
}, prompt: plan ?? "", model: model, models: models.map((m) => ({ id: m.id, name: nameOf(m.id, listed) })) }), dragging ? (_jsx(YStack, { "aria-hidden": true, position: "absolute", t: 0, r: 0, b: 0, l: 0, z: 10, items: "center", justify: "center", bg: "var(--surface-scrim)", borderWidth: 2, borderStyle: "dashed", borderColor: "$borderColor", rounded: "var(--pane-round)", pointerEvents: "none", children: _jsxs(XStack, { items: "center", gap: "$2", px: "$4", py: "$2.5", rounded: "$10", bg: "$background", borderWidth: 1, borderColor: "$borderColor", children: [_jsx(Paperclip, { size: 15, "aria-hidden": true }), _jsx(Text, { fontSize: "$4", color: "$ink", children: t("Drop files to attach") })] }) })) : null, _jsxs(XStack, { "data-slot": "conversation-head", height: 52, items: "center", justify: "space-between", gap: "$3", paddingInlineStart: "$4", paddingInlineEnd: "$2", shrink: 0, children: [_jsxs(XStack, { items: "center", gap: "$2", minW: 0, flex: 1, children: [mine ? (_jsx(Text, { fontSize: 15, lineHeight: 20, color: "$ink", numberOfLines: 1, shrink: 1, minW: 0, children: tidy(mine.title) })) : null, room.length ? (_jsx(XStack, { role: "list", "aria-label": t("Agents in this chat"), items: "center", gap: "$1.5", minW: 0, overflowX: "auto", "$platform-web": { scrollbarWidth: "none" }, children: room.map((name) => (_jsxs(XStack, { role: "listitem", items: "center", gap: "$1.5", paddingInlineStart: "$1", paddingInlineEnd: "$0.5", py: "$0.5", rounded: 999, borderWidth: 1, borderColor: "$borderColor", shrink: 0, children: [_jsx(Face, { src: faces[name]?.avatar ?? (name === withWhom ? portrait : undefined), emoji: faces[name]?.emoji ?? (name === withWhom ? persona?.emoji : undefined), name: name, size: 22 }), _jsx(Text, { fontSize: "$2", fontWeight: "600", color: "$color", numberOfLines: 1, display: "none", $sm: { display: "flex" }, children: name }), _jsx(Box, { render: "button", onClick: () => openAgent(name), "aria-label": t("Remove {name} from this chat", { name }), title: t("Remove {name}", { name }), width: 24, height: 24, rounded: 999, items: "center", justify: "center", hoverStyle: { bg: "$hover" }, children: _jsx(X, { size: 13, "aria-hidden": true, color: "var(--soft, var(--muted-foreground))" }) })] }, name))) })) : null] }), _jsxs(XStack, { "data-slot": "conversation-controls", items: "center", gap: 4, shrink: 0, children: [free ? (_jsxs(Button, { size: "xs", variant: "outline", "data-slot": "header-upgrade", gap: "$1.5", px: "$2.5", py: "$1", rounded: "$4", cursor: "pointer", hoverStyle: { bg: 'var(--white-10)' }, onPress: () => setAsk({}), "aria-label": t("Upgrade"), children: [_jsx(Sparkles, { size: 13, color: "var(--primary)", "aria-hidden": true }), _jsx(Text, { fontSize: "$1", fontWeight: "600", color: "$ink", children: t("Upgrade") })] })) : null, open ? _jsx(Share, { thread: open }) : null, mine ? (_jsx(ConversationMenu, { threads: alone, active: open, onSchedule: anonymous ? undefined : () => setPlan(lastAsked()), children: _jsx(XStack, { children: _jsx(ThreadMore, { t: mine }) }) })) : null, _jsx(Summary, { sections: sections, onOpen: () => setPanel(true), label: t("Summary") }), _jsx(PanelToggle, { open: panel, onToggle: () => setPanel(!panel) })] })] }), wide && aside !== null ? (_jsx(Beside, { children: _jsx(Panel, { side: deck, kinds: NONE, onHide: () => setPanel(false), label: t("Tabs"), ...browsing }) })) : null, !wide && panel ? _jsx(Panel, { side: deck, kinds: NONE, sheet: true, onHide: () => setPanel(false), label: t("Tabs"), ...browsing }) : null, _jsx(ChatSurface, { ...chat, messages: shown, send: guarded,
|
|
1484
1484
|
// AN EMPTY ROOM CENTRES ITS COMPOSER on a laptop. While nothing has been
|
|
1485
1485
|
// said the opening (the heading) and the composer sit as one group in the
|
|
1486
1486
|
// middle of the height; the moment a turn exists the transcript takes the
|
package/dist/Me.js
CHANGED
|
@@ -171,7 +171,8 @@ export function Me({ host, narrow = false, above = false, onOrg, }) {
|
|
|
171
171
|
// A personal plan is bought for the personal organization, beside any business one.
|
|
172
172
|
// The plans row's name (a phrase of `upgrade`'s).
|
|
173
173
|
const plans = upgrade(read.value?.label?.name);
|
|
174
|
-
const
|
|
174
|
+
const isFree = !read.value?.label?.name || read.value?.label?.name?.toLowerCase() === 'free';
|
|
175
|
+
const getPro = () => (personal ? window.location.assign(payUrl('/cart', { plan: 'pro', org: personal.name, returnUrl: window.location.href })) : window.location.assign(payUrl('/cart', { plan: 'pro', returnUrl: window.location.href })));
|
|
175
176
|
const apple = mac();
|
|
176
177
|
useEffect(() => {
|
|
177
178
|
if (above)
|
|
@@ -211,7 +212,10 @@ export function Me({ host, narrow = false, above = false, onOrg, }) {
|
|
|
211
212
|
row.current = el instanceof HTMLElement ? el : null;
|
|
212
213
|
}, render: "button", "data-slot": "me", "aria-label": t('Account: {name}', { name: [who, current].filter(Boolean).join(' · ') }), ...{ title: who }, width: narrow ? 36 : '100%', minH: narrow ? 36 : 48,
|
|
213
214
|
// A thumb's 44 on a touch screen.
|
|
214
|
-
$touchable: narrow ? { width: 44, minH: 44 } : undefined, px: narrow ? 0 : '$2', gap: "$2.5", rounded: narrow ? 999 : '$5', items: "center", justify: narrow ? 'center' : 'flex-start', hoverStyle: { bg: '$hover' }, focusVisibleStyle: { outlineWidth: 2, outlineStyle: 'solid', outlineColor: '$outlineColor' }, cursor: "pointer", children: [_jsx(Face, { host: host, size: narrow ? 26 : 32 }), narrow ? null : (_jsxs(_Fragment, { children: [_jsxs(YStack, { flex: 1, minW: 0, children: [_jsx(SizableText, { size: "$3", fontWeight: "600", color: "$ink", numberOfLines: 1, text: "start", children: who }), working ? (_jsx(SizableText, { size: "$1", color: "$soft", numberOfLines: 1, text: "start", children: working })) : null] }),
|
|
215
|
+
$touchable: narrow ? { width: 44, minH: 44 } : undefined, px: narrow ? 0 : '$2', gap: "$2.5", rounded: narrow ? 999 : '$5', items: "center", justify: narrow ? 'center' : 'flex-start', hoverStyle: { bg: '$hover' }, focusVisibleStyle: { outlineWidth: 2, outlineStyle: 'solid', outlineColor: '$outlineColor' }, cursor: "pointer", children: [_jsx(Face, { host: host, size: narrow ? 26 : 32 }), narrow ? null : (_jsxs(_Fragment, { children: [_jsxs(YStack, { flex: 1, minW: 0, children: [_jsx(SizableText, { size: "$3", fontWeight: "600", color: "$ink", numberOfLines: 1, text: "start", children: who }), working ? (_jsx(SizableText, { size: "$1", color: "$soft", numberOfLines: 1, text: "start", children: working })) : null] }), isFree ? (_jsx(Button, { size: "xs", variant: "outline", "data-slot": "me-upgrade", px: "$2", py: "$0.5", rounded: "$3", onPress: (e) => {
|
|
216
|
+
e?.stopPropagation?.();
|
|
217
|
+
getPro();
|
|
218
|
+
}, cursor: "pointer", children: t('Upgrade') })) : null, _jsx(ChevronsUpDown, { size: 14, "aria-hidden": true, opacity: 0.6 })] }))] }) }), _jsxs(DropdownMenuContent, { minW: 260, maxW: "calc(100vw - 16px)", "aria-labelledby": undefined, "aria-label": t('Account'), onCloseAutoFocus: back, children: [_jsxs(DropdownMenuSub, { open: account, onOpenChange: setAccount, children: [_jsxs(DropdownMenuSubTrigger, { minH: 48, gap: "$2.5", children: [_jsx(Face, { host: host, size: 28 }), _jsxs(YStack, { flex: 1, minW: 0, children: [_jsx(SizableText, { size: "$2", fontWeight: "600", color: "$ink", numberOfLines: 1, children: who }), _jsx(SizableText, { size: "$1", color: "$soft", numberOfLines: 1, children: host.person.email || working })] })] }), account ? (_jsxs(DropdownMenuSubContent, { minW: 260, maxW: "calc(100vw - 16px)", pointerEvents: "auto", children: [_jsx(Meter, { read: read, onPlans: () => leave('here'), onBilling: () => (setOpen(false), showSettings('billing')) }), _jsx(DropdownMenuSeparator, {}), _jsx(DropdownMenuLabel, { children: t('Organizations') }), all.map((o) => (_jsx(DropdownMenuItem, { onSelect: () => o.name !== current && onOrg(o.name), children: _jsx(Line, { icon: _jsx(Mark, { org: o }), sub: [o.personal ? t('Personal') : said(o.role, t), planFor(o)].filter(Boolean).join(' · '), trail: o.name === current ? _jsx(Check, { size: 16, "aria-label": t('Current') }) : null, children: o.display }) }, o.name))), _jsx(DropdownMenuItem, { onSelect: () => setCreating(true), children: _jsx(Line, { icon: _jsx(Plus, { size: 16, "aria-hidden": true }), children: t('Create organization') }) }), _jsx(DropdownMenuItem, { onSelect: () => out(site(settings('organization'))), children: _jsx(Line, { icon: _jsx(Settings, { size: 16, "aria-hidden": true }), children: t('Organization settings') }) }), where().team ? null : here && !here.personal ? (_jsx(DropdownMenuItem, { onSelect: () => out(`${ENTRY}&org=${encodeURIComponent(here.name)}`), children: _jsx(Line, { icon: _jsx(Users, { size: 16, "aria-hidden": true }), trail: _jsx(ArrowUpRight, { size: 14, "aria-hidden": true, opacity: 0.6 }), children: t('Open in Hanzo Team') }) })) : (_jsx(DropdownMenuItem, { onSelect: () => setCreating(true), children: _jsx(Line, { icon: _jsx(Users, { size: 16, "aria-hidden": true }), children: t('Create a team') }) })), superAdmin() ? (_jsx(DropdownMenuItem, { onSelect: choose, children: _jsx(Line, { icon: _jsx(Building2, { size: 16, "aria-hidden": true }), children: t('All organizations') }) })) : null] })) : null] }), team ? (_jsx(DropdownMenuItem, { "data-slot": "me-team", onSelect: () => team.name !== current && onOrg(team.name), children: _jsx(Line, { icon: _jsx(Mark, { org: team }), trail: team.name === current ? _jsx(Check, { size: 16, "aria-label": t('Current') }) : null, children: t('{org} · {plan}', { org: team.display, plan: teamPlan || t('No plan') }) }) })) : null, personal ? (_jsx(DropdownMenuItem, { "data-slot": "me-personal", onSelect: () => personal.name !== current && onOrg(personal.name), actionsVisibility: "always", actions: ownPlan ? undefined : (_jsx(Button, { size: "xs", variant: "outline", onPress: getPro, children: t('Get Pro') })), children: _jsx(Line, { icon: _jsx(CircleUserRound, { size: 16, "aria-hidden": true }), trail: personal.name === current ? _jsx(Check, { size: 16, "aria-label": t('Current') }) : null, children: t('Personal · {plan}', { plan: ownPlan || t('No plan') }) }) })) : null, _jsx(DropdownMenuSeparator, {}), _jsx(DropdownMenuItem, { onSelect: () => leave('here'), children: _jsx(Line, { icon: _jsx(Sparkles, { size: 16, "aria-hidden": true }), children: t(plans) }) }), _jsx(DropdownMenuItem, { onSelect: () => showSettings('general'), children: _jsx(Line, { icon: _jsx(Palette, { size: 16, "aria-hidden": true }), children: t('Personalization') }) }), _jsx(DropdownMenuItem, { onSelect: () => showSettings('account'), children: _jsx(Line, { icon: _jsx(CircleUserRound, { size: 16, "aria-hidden": true }), children: t('Profile') }) }), _jsx(DropdownMenuItem, { "aria-keyshortcuts": "Control+, Meta+,", onSelect: () => showSettings('general'), children: _jsx(Line, { icon: _jsx(Settings, { size: 16, "aria-hidden": true }), trail: _jsx(DropdownMenuShortcut, { "aria-hidden": true, children: _jsx("bdi", { dir: "ltr", children: apple ? '⌘,' : 'Ctrl+,' }) }), children: t('Settings') }) }), _jsx(DropdownMenuItem, { onSelect: () => window.location.assign(site('/beta/status')), children: _jsx(Line, { icon: _jsx(FlaskConical, { size: 16, "aria-hidden": true }), children: t('Beta') }) }), _jsx(DropdownMenuSeparator, {}), _jsxs(DropdownMenuSub, { open: help, onOpenChange: setHelp, children: [_jsx(DropdownMenuSubTrigger, { children: _jsx(Line, { icon: _jsx(LifeBuoy, { size: 16, "aria-hidden": true }), children: t('Help') }) }), help ? (_jsxs(DropdownMenuSubContent, { minW: 240, maxW: "calc(100vw - 16px)", pointerEvents: "auto", children: [pages().map((p) => (_jsx(DropdownMenuItem, { onSelect: () => out(p.href), children: _jsx(Line, { icon: ICONS[p.key], trail: p.key === 'help' ? _jsx(ArrowUpRight, { size: 14, "aria-hidden": true, opacity: 0.6 }) : null, children: t(p.label) }) }, p.key))), _jsx(DropdownMenuItem, { "aria-keyshortcuts": "Control+/ Meta+/", onSelect: () => setKeys(true), children: _jsx(Line, { icon: _jsx(Keyboard, { size: 16, "aria-hidden": true }), trail: _jsx(DropdownMenuShortcut, { "aria-hidden": true, children: _jsx("bdi", { dir: "ltr", children: apple ? '⌘/' : 'Ctrl+/' }) }), children: t('Keyboard shortcuts') }) }), _jsx(DropdownMenuSeparator, {}), legal().map((p) => (_jsx(DropdownMenuItem, { onSelect: () => out(p.href), children: _jsx(Line, { icon: ICONS[p.key], children: t(p.label) }) }, p.key)))] })) : null] }), host.signOut ? (_jsx(DropdownMenuItem, { onSelect: () => host.signOut?.(), children: _jsx(Line, { icon: _jsx(LogOut, { size: 16, "aria-hidden": true, "data-i18n-mirror": true }), children: t('Log out') }) })) : null] })] }), _jsx(Create, { open: creating, onOpenChange: setCreating }), _jsx(Shortcuts, { open: keys, onOpenChange: setKeys, apple: apple })] }));
|
|
215
219
|
}
|
|
216
220
|
/** The app's keys (help.ts `KEYS`), one row each, spelled for this platform. */
|
|
217
221
|
function Shortcuts({ open, onOpenChange, apple }) {
|
package/dist/Settings.js
CHANGED
|
@@ -39,6 +39,7 @@ const GROUPS = [
|
|
|
39
39
|
{ id: 'general', label: phrase('General') },
|
|
40
40
|
{ id: 'account', label: phrase('Account') },
|
|
41
41
|
{ id: 'billing', label: phrase('Billing') },
|
|
42
|
+
{ id: 'referrals', label: phrase('Referrals & Rewards') },
|
|
42
43
|
{ id: 'usage', label: phrase('Usage') },
|
|
43
44
|
{ id: 'capabilities', label: phrase('Capabilities'), note: phrase('What a model may reach for on your behalf.') },
|
|
44
45
|
{ id: 'privacy', label: phrase('Privacy'), href: site('/legal/privacy') },
|
package/dist/SettingsPane.js
CHANGED
|
@@ -6,7 +6,7 @@ import { useMemo, useState } from 'react';
|
|
|
6
6
|
import { phrase } from '@hanzo/i18n';
|
|
7
7
|
import { useI18n } from '@hanzo/i18n/react';
|
|
8
8
|
import { ArrowUpRight, ExternalLink } from 'lucide-react';
|
|
9
|
-
import { Box, Button, Separator, Text, XStack, YStack, } from '@hanzo/ui';
|
|
9
|
+
import { Box, Button, Input, Separator, Text, XStack, YStack, } from '@hanzo/ui';
|
|
10
10
|
import { tap } from './lib/tap.js';
|
|
11
11
|
import { useIam, useIamIdentity, useOrganizations } from '@hanzo/iam/react';
|
|
12
12
|
import { useSignOut } from './lib/signout.js';
|
|
@@ -52,6 +52,8 @@ function Pane({ id, note }) {
|
|
|
52
52
|
return _jsx(Account, {});
|
|
53
53
|
if (id === 'billing')
|
|
54
54
|
return _jsx(Billing, {});
|
|
55
|
+
if (id === 'referrals')
|
|
56
|
+
return _jsx(Referrals, {});
|
|
55
57
|
if (id === 'usage')
|
|
56
58
|
return _jsx(Usage, {});
|
|
57
59
|
if (id === 'model')
|
|
@@ -116,6 +118,40 @@ function Account() {
|
|
|
116
118
|
return (_jsx(Box, { render: _jsx("button", { type: "button" }), onClick: () => { pick(o.name); switchOrg(o.name); }, ...tap, children: _jsxs(XStack, { items: "center", justify: "space-between", py: "$2", width: "100%", gap: "$2", children: [_jsx(Text, { fontSize: "$3", color: here ? '$ink' : '$soft', children: o.displayName || o.name }), here && currentRole ? _jsx(Text, { fontSize: "$2", color: "$soft", children: currentRole }) : null] }) }, o.name));
|
|
117
119
|
}))] }), _jsx(Separator, {}), _jsx(XStack, { children: _jsx(Button, { size: "sm", onClick: () => logout(), children: t('Sign out') }) })] }));
|
|
118
120
|
}
|
|
121
|
+
/** Referrals & Rewards — customer referral program and affiliate partner portal. */
|
|
122
|
+
function Referrals() {
|
|
123
|
+
const { t } = useI18n();
|
|
124
|
+
const identity = useIamIdentity();
|
|
125
|
+
const { isAuthenticated } = useIam();
|
|
126
|
+
const [copied, setCopied] = useState(false);
|
|
127
|
+
const [vanity, setVanity] = useState('');
|
|
128
|
+
const [applied, setApplied] = useState(false);
|
|
129
|
+
if (!isAuthenticated || !identity) {
|
|
130
|
+
return _jsx(Text, { fontSize: "$3", color: "$soft", children: t('Sign in to view your referral program.') });
|
|
131
|
+
}
|
|
132
|
+
const handle = identity.name ? identity.name.toLowerCase().replace(/\s+/g, '-') : (identity.email ? identity.email.split('@')[0] : 'user');
|
|
133
|
+
const referralUrl = `https://hanzo.ai/?ref=${encodeURIComponent(handle)}`;
|
|
134
|
+
const copy = () => {
|
|
135
|
+
navigator.clipboard.writeText(referralUrl);
|
|
136
|
+
setCopied(true);
|
|
137
|
+
setTimeout(() => setCopied(false), 2000);
|
|
138
|
+
};
|
|
139
|
+
const tweet = () => {
|
|
140
|
+
const text = 'Deploy AI agents, sites, and apps on @HanzoAI. Get $20 in free cloud compute credits:';
|
|
141
|
+
window.open(`https://twitter.com/intent/tweet?text=${encodeURIComponent(text)}&url=${encodeURIComponent(referralUrl)}`, '_blank', 'noopener,noreferrer');
|
|
142
|
+
};
|
|
143
|
+
const linkedin = () => {
|
|
144
|
+
window.open(`https://www.linkedin.com/sharing/share-offsite/?url=${encodeURIComponent(referralUrl)}`, '_blank', 'noopener,noreferrer');
|
|
145
|
+
};
|
|
146
|
+
const telegram = () => {
|
|
147
|
+
window.open(`https://t.me/share/url?url=${encodeURIComponent(referralUrl)}&text=${encodeURIComponent('Get $20 free Hanzo cloud compute credits:')}`, '_blank', 'noopener,noreferrer');
|
|
148
|
+
};
|
|
149
|
+
const whatsapp = () => {
|
|
150
|
+
window.open(`https://api.whatsapp.com/send?text=${encodeURIComponent('Deploy with Hanzo — get $20 in free cloud credits: ' + referralUrl)}`, '_blank', 'noopener,noreferrer');
|
|
151
|
+
};
|
|
152
|
+
return (_jsxs(YStack, { gap: "$5", maxW: 640, children: [_jsxs(YStack, { gap: "$1.5", children: [_jsx(XStack, { items: "center", gap: "$2", children: _jsx(Text, { fontSize: "$4", fontWeight: "600", color: "$ink", children: t('Give $20, Get 20%') }) }), _jsx(Text, { fontSize: "$3", color: "$soft", children: t('Invite developers, creators, and colleagues to Hanzo. They get $20 in free cloud compute credits, and you earn 20% recurring revenue share on their compute spend for 12 months.') })] }), _jsxs(YStack, { gap: "$2", p: "$3", rounded: "$3", borderWidth: 1, borderColor: "$borderColor", children: [_jsx(Text, { fontSize: "$2", fontWeight: "600", color: "$ink", children: t('Your Personal Referral Link') }), _jsxs(XStack, { items: "center", gap: "$2", children: [_jsx(Box, { flex: 1, p: "$2", rounded: "$2", bg: "$hover", borderWidth: 1, borderColor: "$borderColor", children: _jsx(Text, { fontSize: "$2", color: "$ink", fontFamily: "$mono", numberOfLines: 1, children: referralUrl }) }), _jsx(Button, { size: "sm", onClick: copy, children: copied ? t('Copied!') : t('Copy Link') })] }), _jsxs(XStack, { items: "center", justify: "space-between", pt: "$2", flexWrap: "wrap", gap: "$2", children: [_jsx(Text, { fontSize: "$1", color: "$soft", children: t('1-Click Social Share:') }), _jsxs(XStack, { gap: "$2", flexWrap: "wrap", children: [_jsx(Button, { size: "sm", variant: "outline", onClick: tweet, children: "\uD835\uDD4F (Twitter)" }), _jsx(Button, { size: "sm", variant: "outline", onClick: linkedin, children: "LinkedIn" }), _jsx(Button, { size: "sm", variant: "outline", onClick: telegram, children: "Telegram" }), _jsx(Button, { size: "sm", variant: "outline", onClick: whatsapp, children: "WhatsApp" })] })] })] }), _jsx(Separator, {}), _jsxs(YStack, { gap: "$2", children: [_jsx(Text, { fontSize: "$3", fontWeight: "600", color: "$ink", children: t('Referral Rules & Offer Details') }), _jsxs(YStack, { gap: "$1", children: [_jsxs(Text, { fontSize: "$2", color: "$soft", children: ["\u2022 ", t('30-day attribution window: First click binds to user identity upon registration.')] }), _jsxs(Text, { fontSize: "$2", color: "$soft", children: ["\u2022 ", t('20% recurring margin share: Calculated against net platform margin (safe from wholesale token dilution).')] }), _jsxs(Text, { fontSize: "$2", color: "$soft", children: ["\u2022 ", t('Payout options: Platform credits, direct wire/ACH, or on-chain EVM wallet settlement.')] })] })] }), _jsx(Separator, {}), _jsxs(YStack, { gap: "$3", children: [_jsx(Text, { fontSize: "$3", fontWeight: "600", color: "$ink", children: t('Official Affiliate & Creator Program') }), _jsx(Text, { fontSize: "$2", color: "$soft", children: t('Building an open-source project, template, or dev community? Apply for official affiliate status for custom vanity links (hanzo.ai/?aff=code) and elevated commission tiers.') }), !applied ? (_jsxs(XStack, { gap: "$2", children: [_jsx(Input, { flex: 1, size: "sm", placeholder: t('Desired vanity code (e.g. your project)'), value: vanity, onChange: (e) => setVanity(e.target.value) }), _jsx(Button, { size: "sm", onClick: () => { if (vanity.trim())
|
|
153
|
+
setApplied(true); }, children: t('Apply for Partner') })] })) : (_jsx(Box, { p: "$3", rounded: "$2", bg: "$hover", children: _jsx(Text, { fontSize: "$2", color: "$ink", children: t('Application submitted for review. Manage payouts and advanced settings in platform.hanzo.ai/dashboard/settings/referrals') }) })), _jsx(XStack, { pt: "$1", children: _jsx(Box, { render: _jsx("a", { href: "https://platform.hanzo.ai/dashboard/settings/referrals", target: "_blank", rel: "noreferrer" }), ...tap, children: _jsxs(XStack, { items: "center", gap: "$1.5", children: [_jsx(Text, { fontSize: "$2", color: "$ink", children: t('Open Full Referrals & Affiliate Portal') }), _jsx(ArrowUpRight, { size: 13, "aria-hidden": true })] }) }) })] })] }));
|
|
154
|
+
}
|
|
119
155
|
/** Where the plan's and billing's reads go: this browser's bearer, in its organization. */
|
|
120
156
|
function useTarget() {
|
|
121
157
|
const scoped = org();
|
package/dist/Shell.js
CHANGED
|
@@ -17,7 +17,7 @@ import { createContext, lazy, Suspense, useCallback, useContext, useEffect, useM
|
|
|
17
17
|
import { createPortal } from "react-dom";
|
|
18
18
|
import { phrase } from "@hanzo/i18n";
|
|
19
19
|
import { useI18n } from "@hanzo/i18n/react";
|
|
20
|
-
import { MessageSquare, Code2, Inbox, Bot, ListChecks, HardDrive, Settings2, UserPlus, PanelLeftClose, Search, Hash, AtSign, Lock, Workflow, Plus, ArrowLeft, ArrowRight, Send, Minus, Blocks, Star, FolderOpen, Activity, BookOpen, SquareTerminal, Share2, PanelLeft, PanelRight, Users, Globe, Cpu, Boxes, Wallet, Video, Calendar, LayoutGrid, ArrowUpLeft, } from "lucide-react";
|
|
20
|
+
import { MessageSquare, Code2, Inbox, Bot, ListChecks, HardDrive, Settings2, UserPlus, PanelLeftClose, Search, Hash, AtSign, Lock, Workflow, Plus, ArrowLeft, ArrowRight, Send, Minus, Blocks, Star, FolderOpen, Activity, BookOpen, SquareTerminal, Share2, PanelLeft, PanelRight, Users, Globe, Cpu, Boxes, Wallet, Video, Calendar, LayoutGrid, ArrowUpLeft, Sparkles, } from "lucide-react";
|
|
21
21
|
import { AiProvider, useAgents, useInbox, useModels, usePeople, } from "@hanzo/ai/react";
|
|
22
22
|
import { PINNED } from "./recent.js";
|
|
23
23
|
import { ConversationMenu, ThreadRow, useThreadList } from "./thread.js";
|
|
@@ -48,6 +48,8 @@ import { mark } from "./lib/mark.js";
|
|
|
48
48
|
import { useOpen } from "./open.js";
|
|
49
49
|
import { useSpan } from "./span.js";
|
|
50
50
|
import { pane } from "./ground.js";
|
|
51
|
+
import { useFree } from "./Upgrade.js";
|
|
52
|
+
import { payUrl } from "./lib/pay.js";
|
|
51
53
|
/** The new-agent row's fields: an outlined box in the room's own ink. */
|
|
52
54
|
const FIELD = {
|
|
53
55
|
bg: "transparent",
|
|
@@ -385,6 +387,7 @@ function Chats({ filter = "", onPick, }) {
|
|
|
385
387
|
const { isAuthenticated, user } = useIam();
|
|
386
388
|
const { user: account } = useAccount();
|
|
387
389
|
const signedIn = isAuthenticated || Boolean(user) || Boolean(account) || hasSession();
|
|
390
|
+
const free = useFree(signedIn);
|
|
388
391
|
const mergedThreads = useMemo(() => {
|
|
389
392
|
const list = threads.map((t) => ({
|
|
390
393
|
id: t.id,
|
|
@@ -562,6 +565,7 @@ function Team({ filter = "", onPick, navigate, }) {
|
|
|
562
565
|
const { isAuthenticated, user } = useIam();
|
|
563
566
|
const { user: account } = useAccount();
|
|
564
567
|
const signedIn = isAuthenticated || Boolean(user) || Boolean(account) || hasSession();
|
|
568
|
+
const free = useFree(signedIn);
|
|
565
569
|
const [starred] = useStarred();
|
|
566
570
|
const shown = list(rooms).filter((r) => matches(r.name, filter));
|
|
567
571
|
const favourites = shown.filter((r) => starred.has(titleOf(r.name, r.direct)));
|
|
@@ -1216,6 +1220,7 @@ function Frame({ mode, children, navigate, back, forward, }) {
|
|
|
1216
1220
|
const settled = hydrated && !isLoading;
|
|
1217
1221
|
const { user: account } = useAccount();
|
|
1218
1222
|
const signedIn = isAuthenticated || Boolean(user) || Boolean(account) || hasSession();
|
|
1223
|
+
const free = useFree(signedIn);
|
|
1219
1224
|
const logout = useSignOut();
|
|
1220
1225
|
const face = account?.avatar ?? user?.avatar;
|
|
1221
1226
|
// The account menu's reading of this host: who, in which organization, and how they leave.
|
|
@@ -1260,7 +1265,7 @@ function Frame({ mode, children, navigate, back, forward, }) {
|
|
|
1260
1265
|
gridTemplateColumns: "minmax(0, 1fr)",
|
|
1261
1266
|
gridTemplateRows: `44px minmax(0, 1fr) ${TABS_HEIGHT}`,
|
|
1262
1267
|
gridTemplateAreas: '"bar" "pane" "rail"',
|
|
1263
|
-
}, position: "relative", width: "100%", height: "100dvh", overflow: "hidden", bg: "$background", backgroundImage: "var(--pane-ground)", children: [_jsx(Rail, { mode: mode, places: places, open: asked, team: onApex ? (signedIn ? ENTRY : WORKSPACE) : undefined, navigate: navigate, onSettings: () => showSettings(FIRST), onMore: () => setFinding(true) }), _jsxs(XStack, { render: "header", "data-slot": "bar", gridArea: "bar", ...sheet(0), height: 44, shrink: 0, items: "center", px: "$3", gap: "$3", borderBottomWidth: 1, borderColor: "var(--edge, var(--white-06))", children: [_jsxs(XStack, { items: "center", gap: "$1", shrink: 0, children: [_jsx(SidebarIconButton, { ...TAP, label: t(shown ? "Close sidebar" : "Open sidebar"), onPress: toggle, onMouseEnter: () => setPeeking(true), children: _jsx(PanelLeft, { size: 16, "aria-hidden": true, "data-i18n-mirror": "" }) }), back || forward ? (_jsxs(XStack, { display: "none", $md: { display: "flex" }, items: "center", gap: "$1", shrink: 0, children: [_jsx(SidebarIconButton, { ...TAP, label: t("Back"), onPress: () => back?.(), children: _jsx(ArrowLeft, { size: 16, "aria-hidden": true, "data-i18n-mirror": "" }) }), _jsx(SidebarIconButton, { ...TAP, label: t("Forward"), onPress: () => forward?.(), children: _jsx(ArrowRight, { size: 16, "aria-hidden": true, "data-i18n-mirror": "" }) })] })) : null] }), _jsx(XStack, { flex: 1, justify: "center", children: _jsx(YStack, { width: 440, maxW: "100%", position: "relative", children: _jsxs(Box, { render: "button", onClick: () => setFinding(true), display: "flex", flexDirection: "row", "data-slot": "find", items: "center", "$max-md": { justify: "center" }, gap: "$2", width: "100%", height: CONTROL, px: "$2.5", rounded: "$2", borderWidth: 1, borderColor: "$borderColor", hoverStyle: { bg: '$hover' }, children: [_jsx(Search, { size: 13, "aria-hidden": true, color: "var(--soft, var(--muted-foreground))" }), _jsx(Text, { fontSize: "$1", color: "$soft", "$max-md": { display: "none" }, children: t("Search {workspace}", { workspace }) }), _jsx(Shortcut, { keys: ["Mod", "K"], marginInlineStart: "auto", "data-i18n-ltr": "", "$max-md": { display: "none" } })] }) }) }), _jsxs(XStack, { shrink: 0, minW: 0, justify: "flex-end", items: "center", gap: "$2", children: [settled && !signedIn ? (_jsx(Box, { ...TAP, render: "button", onClick: () => enter(LOGIN), display: "flex", items: "center", justify: "center", cursor: "pointer", children: _jsx(XStack, { items: "center", justify: "center", height: CONTROL, px: "$2.5", rounded: "$2", borderWidth: 1, borderColor: "$borderColor", hoverStyle: { bg: '$hover' }, children: _jsx(Text, { fontSize: "$1", fontWeight: "600", color: "$ink", children: t("Sign in") }) }) })) : null, _jsxs(XStack, { display: "none", $lg: { display: "flex" }, items: "center", gap: "$1", children: [_jsx(SidebarIconButton, { ...TAP, label: t(aside === "roster" ? "Hide directory & roster" : "Show directory & roster"), onPress: () => showAside(aside === "roster" ? null : "roster"), children: _jsx(Users, { size: 16, "aria-hidden": true }) }), _jsx(SidebarIconButton, { ...TAP, label: t(aside === "tasks" ? "Close side panel" : "Open side panel"), onPress: () => showAside(aside === "tasks" ? null : "tasks"), children: _jsx(PanelRight, { size: 16, "aria-hidden": true, "data-i18n-mirror": "" }) })] })] })] }), shown ? (_jsx(Box, { render: "button", "aria-label": t("Close sidebar"), onClick: dismiss, ...scrim, "data-slot": "scrim", position: "absolute", t: 44, r: 0, b: TABS_HEIGHT, l: 0, z: "var(--z-scrim)", $md: { display: "none" } })) : null, shown ? (_jsx(XStack, { "data-slot": "list", gridArea: "list", position: asked ? "relative" : "absolute", ...(asked ? {} : { top: 44, bottom: 0, insetInlineStart: 64 }), "$max-md": { position: "fixed", t: 44, r: 0, b: TABS_HEIGHT, l: 0, width: "100%" }, z: "var(--z-drawer)", bg: "$background", onMouseEnter: () => setPeeking(true), onMouseLeave: () => {
|
|
1268
|
+
}, position: "relative", width: "100%", height: "100dvh", overflow: "hidden", bg: "$background", backgroundImage: "var(--pane-ground)", children: [_jsx(Rail, { mode: mode, places: places, open: asked, team: onApex ? (signedIn ? ENTRY : WORKSPACE) : undefined, navigate: navigate, onSettings: () => showSettings(FIRST), onMore: () => setFinding(true) }), _jsxs(XStack, { render: "header", "data-slot": "bar", gridArea: "bar", ...sheet(0), height: 44, shrink: 0, items: "center", px: "$3", gap: "$3", borderBottomWidth: 1, borderColor: "var(--edge, var(--white-06))", children: [_jsxs(XStack, { items: "center", gap: "$1", shrink: 0, children: [_jsx(SidebarIconButton, { ...TAP, label: t(shown ? "Close sidebar" : "Open sidebar"), onPress: toggle, onMouseEnter: () => setPeeking(true), children: _jsx(PanelLeft, { size: 16, "aria-hidden": true, "data-i18n-mirror": "" }) }), back || forward ? (_jsxs(XStack, { display: "none", $md: { display: "flex" }, items: "center", gap: "$1", shrink: 0, children: [_jsx(SidebarIconButton, { ...TAP, label: t("Back"), onPress: () => back?.(), children: _jsx(ArrowLeft, { size: 16, "aria-hidden": true, "data-i18n-mirror": "" }) }), _jsx(SidebarIconButton, { ...TAP, label: t("Forward"), onPress: () => forward?.(), children: _jsx(ArrowRight, { size: 16, "aria-hidden": true, "data-i18n-mirror": "" }) })] })) : null] }), _jsx(XStack, { flex: 1, justify: "center", children: _jsx(YStack, { width: 440, maxW: "100%", position: "relative", children: _jsxs(Box, { render: "button", onClick: () => setFinding(true), display: "flex", flexDirection: "row", "data-slot": "find", items: "center", "$max-md": { justify: "center" }, gap: "$2", width: "100%", height: CONTROL, px: "$2.5", rounded: "$2", borderWidth: 1, borderColor: "$borderColor", hoverStyle: { bg: '$hover' }, children: [_jsx(Search, { size: 13, "aria-hidden": true, color: "var(--soft, var(--muted-foreground))" }), _jsx(Text, { fontSize: "$1", color: "$soft", "$max-md": { display: "none" }, children: t("Search {workspace}", { workspace }) }), _jsx(Shortcut, { keys: ["Mod", "K"], marginInlineStart: "auto", "data-i18n-ltr": "", "$max-md": { display: "none" } })] }) }) }), _jsxs(XStack, { shrink: 0, minW: 0, justify: "flex-end", items: "center", gap: "$2", children: [settled && !signedIn ? (_jsx(Box, { ...TAP, render: "button", onClick: () => enter(LOGIN), display: "flex", items: "center", justify: "center", cursor: "pointer", children: _jsx(XStack, { items: "center", justify: "center", height: CONTROL, px: "$2.5", rounded: "$2", borderWidth: 1, borderColor: "$borderColor", hoverStyle: { bg: '$hover' }, children: _jsx(Text, { fontSize: "$1", fontWeight: "600", color: "$ink", children: t("Sign in") }) }) })) : null, settled && signedIn && free ? (_jsx(Box, { ...TAP, render: "button", onClick: () => window.location.assign(payUrl("/cart", { plan: "pro", returnUrl: window.location.href })), display: "flex", items: "center", justify: "center", cursor: "pointer", "aria-label": t("Upgrade"), "data-slot": "bar-upgrade", children: _jsxs(XStack, { items: "center", justify: "center", height: CONTROL, px: "$2.5", rounded: "$2", borderWidth: 1, borderColor: "$borderColor", gap: "$1.5", hoverStyle: { bg: "$hover" }, children: [_jsx(Sparkles, { size: 13, "aria-hidden": true, color: "var(--primary)" }), _jsx(Text, { fontSize: "$1", fontWeight: "600", color: "$ink", children: t("Upgrade") })] }) })) : null, _jsxs(XStack, { display: "none", $lg: { display: "flex" }, items: "center", gap: "$1", children: [_jsx(SidebarIconButton, { ...TAP, label: t(aside === "roster" ? "Hide directory & roster" : "Show directory & roster"), onPress: () => showAside(aside === "roster" ? null : "roster"), children: _jsx(Users, { size: 16, "aria-hidden": true }) }), _jsx(SidebarIconButton, { ...TAP, label: t(aside === "tasks" ? "Close side panel" : "Open side panel"), onPress: () => showAside(aside === "tasks" ? null : "tasks"), children: _jsx(PanelRight, { size: 16, "aria-hidden": true, "data-i18n-mirror": "" }) })] })] })] }), shown ? (_jsx(Box, { render: "button", "aria-label": t("Close sidebar"), onClick: dismiss, ...scrim, "data-slot": "scrim", position: "absolute", t: 44, r: 0, b: TABS_HEIGHT, l: 0, z: "var(--z-scrim)", $md: { display: "none" } })) : null, shown ? (_jsx(XStack, { "data-slot": "list", gridArea: "list", position: asked ? "relative" : "absolute", ...(asked ? {} : { top: 44, bottom: 0, insetInlineStart: 64 }), "$max-md": { position: "fixed", t: 44, r: 0, b: TABS_HEIGHT, l: 0, width: "100%" }, z: "var(--z-drawer)", bg: "$background", onMouseEnter: () => setPeeking(true), onMouseLeave: () => {
|
|
1264
1269
|
if (!asked)
|
|
1265
1270
|
setPeeking(false);
|
|
1266
1271
|
}, children: list })) : null, _jsx(Paned, { swap: settingsPane ? _jsx(Suspense, { fallback: null, children: _jsx(SettingsPane, { id: settingsPane }) }) : undefined, children: children }), finding ? (_jsx(Palette, { actions: doors, onClose: found,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hanzo/app",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.3",
|
|
4
4
|
"description": "Hanzo's app: the shell and its apps (Home, Chat, Inbox, Contacts, Meet, Calendar, Drive, Board, Work, Bots), once, for every Hanzo surface.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -100,7 +100,8 @@
|
|
|
100
100
|
},
|
|
101
101
|
"repository": {
|
|
102
102
|
"type": "git",
|
|
103
|
-
"url": "git+https://github.com/hanzoai/app.git"
|
|
103
|
+
"url": "git+https://github.com/hanzoai/app.git",
|
|
104
|
+
"directory": "pkg/app"
|
|
104
105
|
},
|
|
105
106
|
"engines": {
|
|
106
107
|
"node": ">=22.18"
|