@hanzo/build 0.2.75 → 0.2.76
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/lib/api/library.d.ts +7 -2
- package/lib/api/library.js +14 -2
- package/lib/index.d.ts +1 -1
- package/lib/index.js +1 -1
- package/lib/library.js +13 -15
- package/lib/nav.d.ts +6 -0
- package/lib/nav.js +75 -1
- package/lib/route.d.ts +5 -0
- package/lib/route.js +7 -1
- package/package.json +1 -1
package/lib/api/library.d.ts
CHANGED
|
@@ -13,8 +13,13 @@
|
|
|
13
13
|
* signed and stop working at `expires`: read the item again for fresh ones.
|
|
14
14
|
*/
|
|
15
15
|
import { type Target } from './call.ts';
|
|
16
|
-
export declare const
|
|
17
|
-
export type Kind = (typeof
|
|
16
|
+
export declare const KIND_IDS: readonly ['image', 'video', 'audio', 'document', 'slides', 'type', 'model', 'code', 'file'];
|
|
17
|
+
export type Kind = (typeof KIND_IDS)[number];
|
|
18
|
+
/** The kinds a reader narrows to, in the order the Library lists them, '' being all. */
|
|
19
|
+
export declare const KINDS: readonly {
|
|
20
|
+
id: Kind | '';
|
|
21
|
+
label: string;
|
|
22
|
+
}[];
|
|
18
23
|
export declare const SOURCES: readonly ['chat', 'dev', 'studio', 'workflow'];
|
|
19
24
|
export type Source = (typeof SOURCES)[number];
|
|
20
25
|
export type Scope = 'all' | 'mine' | 'shared';
|
package/lib/api/library.js
CHANGED
|
@@ -13,7 +13,19 @@
|
|
|
13
13
|
* signed and stop working at `expires`: read the item again for fresh ones.
|
|
14
14
|
*/
|
|
15
15
|
import { call, query, seg } from './call.js';
|
|
16
|
-
export const
|
|
16
|
+
export const KIND_IDS = ['image', 'video', 'audio', 'document', 'slides', 'type', 'model', 'code', 'file'];
|
|
17
|
+
/** The kinds a reader narrows to, in the order the Library lists them, '' being all. */
|
|
18
|
+
export const KINDS = [
|
|
19
|
+
{ id: '', label: 'All' },
|
|
20
|
+
{ id: 'image', label: 'Images' },
|
|
21
|
+
{ id: 'video', label: 'Videos' },
|
|
22
|
+
{ id: 'audio', label: 'Audio' },
|
|
23
|
+
{ id: 'document', label: 'Documents' },
|
|
24
|
+
{ id: 'slides', label: 'Slides' },
|
|
25
|
+
{ id: 'model', label: '3D' },
|
|
26
|
+
{ id: 'code', label: 'Code' },
|
|
27
|
+
{ id: 'file', label: 'Files' },
|
|
28
|
+
];
|
|
17
29
|
export const SOURCES = ['chat', 'dev', 'studio', 'workflow'];
|
|
18
30
|
/** A product, as a person names it. */
|
|
19
31
|
export const SOURCE = { chat: 'Chat', dev: 'Dev', studio: 'Studio', workflow: 'Workflow' };
|
|
@@ -33,7 +45,7 @@ export function item(raw) {
|
|
|
33
45
|
const id = str(o.id);
|
|
34
46
|
if (!id)
|
|
35
47
|
return null;
|
|
36
|
-
const kind =
|
|
48
|
+
const kind = KIND_IDS.includes(str(o.kind)) ? o.kind : 'file';
|
|
37
49
|
const source = SOURCES.includes(str(o.source)) ? o.source : 'dev';
|
|
38
50
|
return {
|
|
39
51
|
id,
|
package/lib/index.d.ts
CHANGED
|
@@ -25,7 +25,7 @@ export { Library, Outputs, Preview, Thumb, want } from './library.tsx';
|
|
|
25
25
|
export { SOURCE, type Item, type Kind as ItemKind, type Source } from './api/library.ts';
|
|
26
26
|
export { Scheduled, schedule } from './scheduled.tsx';
|
|
27
27
|
export { Editor } from './automations.tsx';
|
|
28
|
-
export { nav, NEW, own, sections, tabs, type Group } from './nav.tsx';
|
|
28
|
+
export { library, nav, NEW, own, sections, tabs, useScheduled, type Group } from './nav.tsx';
|
|
29
29
|
export { DevSection, DOTS, useSessions } from './section.tsx';
|
|
30
30
|
export { HostProvider } from './host.tsx';
|
|
31
31
|
export { Slack, useWho, Who } from './foot.tsx';
|
package/lib/index.js
CHANGED
|
@@ -25,7 +25,7 @@ export { Library, Outputs, Preview, Thumb, want } from './library.js';
|
|
|
25
25
|
export { SOURCE } from './api/library.js';
|
|
26
26
|
export { Scheduled, schedule } from './scheduled.js';
|
|
27
27
|
export { Editor } from './automations.js';
|
|
28
|
-
export { nav, NEW, own, sections, tabs } from './nav.js';
|
|
28
|
+
export { library, nav, NEW, own, sections, tabs, useScheduled } from './nav.js';
|
|
29
29
|
export { DevSection, DOTS, useSessions } from './section.js';
|
|
30
30
|
export { HostProvider } from './host.js';
|
|
31
31
|
export { Slack, useWho, Who } from './foot.js';
|
package/lib/library.js
CHANGED
|
@@ -18,26 +18,16 @@ import { Button, Dialog, DialogContent, DialogTitle, DropdownMenu, Input } from
|
|
|
18
18
|
import { ChipSelect } from '@hanzo/ui/product';
|
|
19
19
|
import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
|
20
20
|
import { ago } from './ago.js';
|
|
21
|
-
import { change, days, get, items as list, remove, size, SOURCE } from './api/library.js';
|
|
21
|
+
import { change, days, get, items as list, KINDS, remove, size, SOURCE } from './api/library.js';
|
|
22
22
|
import { Confirm, Rename } from './ask.js';
|
|
23
23
|
import { useKept, useProjects, useRead } from './data.js';
|
|
24
24
|
import { useHost, useTarget } from './host.js';
|
|
25
|
+
import { KEPT } from './nav.js';
|
|
26
|
+
import { path, route } from './route.js';
|
|
25
27
|
import { Panel } from './panel.js';
|
|
26
28
|
import { gap, pane } from './pane.js';
|
|
27
29
|
import { Sites } from './shelf.js';
|
|
28
30
|
import { useDeck } from './tabs.js';
|
|
29
|
-
/** The kinds a reader narrows to, in the order the chips draw them. */
|
|
30
|
-
const KINDS = [
|
|
31
|
-
{ id: '', label: 'All' },
|
|
32
|
-
{ id: 'image', label: 'Images' },
|
|
33
|
-
{ id: 'video', label: 'Videos' },
|
|
34
|
-
{ id: 'audio', label: 'Audio' },
|
|
35
|
-
{ id: 'document', label: 'Documents' },
|
|
36
|
-
{ id: 'slides', label: 'Slides' },
|
|
37
|
-
{ id: 'model', label: '3D' },
|
|
38
|
-
{ id: 'code', label: 'Code' },
|
|
39
|
-
{ id: 'file', label: 'Files' },
|
|
40
|
-
];
|
|
41
31
|
const FROM = [
|
|
42
32
|
{ id: '', label: 'Anywhere' },
|
|
43
33
|
{ id: 'chat', label: 'Chat' },
|
|
@@ -351,7 +341,10 @@ export function Library() {
|
|
|
351
341
|
const t = useTarget();
|
|
352
342
|
const signed = Boolean(host.person);
|
|
353
343
|
const wide = useMedia().md;
|
|
354
|
-
|
|
344
|
+
// The kind is the address's (-/artifacts/<kind>), so the sidebar, a link and Back all name it.
|
|
345
|
+
const at = route(host.path);
|
|
346
|
+
const kind = at.kind === 'screen' && at.of ? at.of : '';
|
|
347
|
+
const setKind = (k) => host.go(path({ kind: 'screen', screen: 'artifacts', ...(k ? { of: k } : {}) }));
|
|
355
348
|
const [source, setSource] = useState('');
|
|
356
349
|
const [scope, setScope] = useState('all');
|
|
357
350
|
const [typed, setTyped] = useState('');
|
|
@@ -368,6 +361,11 @@ export function Library() {
|
|
|
368
361
|
const load = useMemo(() => (signed ? (cursor, signal) => list(t, { kind, source, scope, q, limit: PAGE, cursor }, { signal }) : null), [signed, t, kind, source, scope, q]);
|
|
369
362
|
const pages = usePages(load, `${kind}|${source}|${scope}|${q}|${t.org}`);
|
|
370
363
|
const end = useEnd(pages.more);
|
|
364
|
+
const reload = pages.reload;
|
|
365
|
+
useEffect(() => {
|
|
366
|
+
window.addEventListener(KEPT, reload);
|
|
367
|
+
return () => window.removeEventListener(KEPT, reload);
|
|
368
|
+
}, [reload]);
|
|
371
369
|
const look = useCallback((x) => {
|
|
372
370
|
side.open({ id: `${TAB}${x.id}`, kind: `${TAB}${x.id}`, title: x.name });
|
|
373
371
|
setShown(true);
|
|
@@ -397,7 +395,7 @@ export function Library() {
|
|
|
397
395
|
const open = shown && side.tabs.length > 0;
|
|
398
396
|
const groups = days(pages.rows);
|
|
399
397
|
const narrowed = Boolean(kind || source || q || scope !== 'all');
|
|
400
|
-
return (_jsxs(XStack, { flex: 1, minH: 0, minW: 0, width: "100%", children: [_jsx(YStack, { flex: 1, minH: 0, minW: 0, overflow: "scroll", px: "$6", py: "$6", "$max-md": { px: '$4', py: '$4' }, children: _jsxs(YStack, { width: "100%", maxW: 1120, mx: "auto", gap: "$4", children: [_jsxs(XStack, { items: "center", gap: "$3", children: [_jsx(SizableText, { render: "h1", size: "$7", fontWeight: "600", color: "$ink", flex: 1, children:
|
|
398
|
+
return (_jsxs(XStack, { flex: 1, minH: 0, minW: 0, width: "100%", children: [_jsx(YStack, { flex: 1, minH: 0, minW: 0, overflow: "scroll", px: "$6", py: "$6", "$max-md": { px: '$4', py: '$4' }, children: _jsxs(YStack, { width: "100%", maxW: 1120, mx: "auto", gap: "$4", children: [_jsxs(XStack, { items: "center", gap: "$3", children: [_jsx(SizableText, { render: "h1", size: "$7", fontWeight: "600", color: "$ink", flex: 1, children: KINDS.find((k) => k.id === kind)?.id ? KINDS.find((k) => k.id === kind).label : 'Library' }), _jsxs(XStack, { role: "radiogroup", "aria-label": "View", gap: "$1", children: [_jsx(ViewMark, { label: "Grid", on: view === 'grid', onPress: () => setView('grid'), children: _jsx(LayoutGrid, { size: 16 }) }), _jsx(ViewMark, { label: "List", on: view === 'list', onPress: () => setView('list'), children: _jsx(List, { size: 16 }) })] })] }), _jsxs(XStack, { items: "center", gap: "$2", maxW: 480, children: [_jsx(Search, { size: 16, opacity: 0.6 }), _jsx(YStack, { flex: 1, minW: 0, children: _jsx(Input, { value: typed, onChangeText: setTyped, placeholder: "Search your library", "aria-label": "Search your library", disabled: !signed }) })] }), _jsxs(YStack, { gap: "$2", children: [host.sections ? null : (_jsx(XStack, { role: "radiogroup", "aria-label": "Kind", gap: "$2", overflowX: "auto", pb: "$1", "$platform-web": { scrollbarWidth: 'none' }, children: KINDS.map((k) => (_jsx(Chip, { label: k.label, on: kind === k.id, onPress: () => setKind(k.id) }, k.id || 'all'))) })), _jsxs(XStack, { gap: "$2", flexWrap: "wrap", rowGap: "$2", children: [_jsx(ChipSelect, { name: "From", label: FROM.find((f) => f.id === source).label, chosen: FROM.find((f) => f.id === source), items: FROM, onChange: (f) => setSource(f.id), placement: "bottom-start", width: 200 }), _jsx(ChipSelect, { name: "Whose", label: WHOSE.find((w) => w.id === scope).label, chosen: WHOSE.find((w) => w.id === scope), items: WHOSE, onChange: (w) => setScope(w.id), placement: "bottom-start", width: 220 })] })] }), acts.note ? (_jsx(SizableText, { size: "$2", color: "$soft", role: "status", children: acts.note })) : null, !signed ? (_jsx(Said, { says: "Sign in to see your library.", children: _jsx(Button, { size: "sm", onPress: () => host.signIn?.(), children: "Sign in" }) })) : pages.error && !pages.rows.length ? (_jsx(Said, { says: pages.error.message, children: _jsx(Button, { size: "sm", variant: "outline", onPress: pages.reload, children: "Try again" }) })) : pages.loading && !pages.rows.length ? (_jsx(Said, { says: "Reading\u2026" })) : !pages.rows.length ? (_jsx(Said, { says: narrowed ? 'Nothing matches.' : 'Nothing here yet. What you make in Chat, Dev and Studio lands here.' })) : (_jsxs(YStack, { gap: "$5", children: [groups.map((g) => (_jsxs(YStack, { gap: "$3", role: "group", "aria-label": g.label, children: [_jsx(SizableText, { size: "$2", color: "$soft", fontWeight: "500", children: g.label }), view === 'grid' ? (_jsx("div", { role: "list", "aria-label": `Made ${g.label.toLowerCase()}`, style: { display: 'grid', gridTemplateColumns: 'repeat(auto-fill, minmax(min(46%, 168px), 1fr))', gap: 16 }, children: g.rows.map((x) => (_jsx(Tile, { x: x, onOpen: () => look(x), rows: acts.rows(x) }, x.id))) })) : (_jsx(YStack, { role: "list", "aria-label": `Made ${g.label.toLowerCase()}`, gap: "$0.5", children: g.rows.map((x) => (_jsx(Row, { x: x, onOpen: () => look(x), rows: acts.rows(x) }, x.id))) }))] }, g.label))), _jsx(YStack, { ref: end, height: 1 }), pages.loading ? (_jsx(SizableText, { size: "$1", color: "$soft", children: "Reading more\u2026" })) : pages.error ? (_jsx(SizableText, { size: "$1", color: "$soft", role: "status", children: pages.error.message })) : null] })), signed && !q && !kind && (source === '' || source === 'dev') && scope !== 'shared' ? (_jsx(YStack, { pt: "$6", borderTopWidth: 1, borderColor: "$borderColor", children: _jsx(Sites, {}) })) : null] }) }), open && !wide ? panel(true) : null, open && wide ? (_jsx(YStack, { "data-slot": "library-side", ...pane, ml: gap, shrink: 0, minH: 0, width: 440, maxW: "45%", children: panel(false) })) : null, acts.dialogs] }));
|
|
401
399
|
}
|
|
402
400
|
function ViewMark({ label, on, onPress, children }) {
|
|
403
401
|
return (_jsx(XStack, { render: "button", role: "radio", "aria-checked": on, "aria-label": label, onPress: onPress, width: 32, height: 32, items: "center", justify: "center", rounded: "$3", bg: on ? '$hover' : 'transparent', hoverStyle: { bg: '$hover' }, cursor: "pointer", opacity: on ? 1 : 0.6, children: children }));
|
package/lib/nav.d.ts
CHANGED
|
@@ -19,3 +19,9 @@ export declare const own: (host: Host, go: (path: string) => void) => Group[];
|
|
|
19
19
|
export declare function sections(host: Host, go: (path: string) => void): Group[];
|
|
20
20
|
/** Customize's tabs as a host's sidebar lists them, Agents first; an agent's profile lights Agents. */
|
|
21
21
|
export declare function tabs(host: Host, go: (path: string) => void): Group[];
|
|
22
|
+
/** Fired on `window` once the sidebar's Upload has kept its files, for the Library to read again. */
|
|
23
|
+
export declare const KEPT = "hanzo:library:kept";
|
|
24
|
+
/** The Library's sidebar: Upload, then every kind it narrows to, the one in the address lit. */
|
|
25
|
+
export declare function library(host: Host, go: (path: string) => void): Group[];
|
|
26
|
+
/** Scheduled tasks' sidebar: New task, then each of the person's tasks, the one open lit. Read only while `on`. */
|
|
27
|
+
export declare function useScheduled(host: Host, go: (path: string) => void, on: boolean): Group[];
|
package/lib/nav.js
CHANGED
|
@@ -9,8 +9,12 @@ import { jsx as _jsx } from "react/jsx-runtime";
|
|
|
9
9
|
* Every row moves the builder through `go` with the address `path` writes, so
|
|
10
10
|
* where a place lives is said here and in route.ts and nowhere else.
|
|
11
11
|
*/
|
|
12
|
-
import { Bell, BookOpen, Bot, Brain, CircleDot, Clock, Code, Container, Cpu, CreditCard, FolderGit2, Gauge, Key, LayoutTemplate, Library, Plug, Puzzle, Settings, Shield, SlidersHorizontal, Sparkles, SquarePen, User, Users } from '@hanzogui/lucide-icons-2';
|
|
12
|
+
import { AudioLines, Bell, BookOpen, Bot, Box, Brain, CircleDot, Clock, Code, Container, Cpu, CreditCard, File, FileText, FolderGit2, Gauge, Image, Key, LayoutTemplate, Library, Plug, Plus, Presentation, Puzzle, Settings, Shield, SlidersHorizontal, Sparkles, SquarePen, Upload, User, Users, Video } from '@hanzogui/lucide-icons-2';
|
|
13
|
+
import { useMemo } from 'react';
|
|
14
|
+
import { automations } from './api/auto.js';
|
|
15
|
+
import { KINDS, upload } from './api/library.js';
|
|
13
16
|
import { pinBoard } from './choice.js';
|
|
17
|
+
import { useRead } from './data.js';
|
|
14
18
|
import { DOCS } from './foot.js';
|
|
15
19
|
import { path, route, TABS } from './route.js';
|
|
16
20
|
import { GROUPS, heading, LIST } from './settings/list.js';
|
|
@@ -117,3 +121,73 @@ const SECTION_ICON = {
|
|
|
117
121
|
integrations: _jsx(Plug, { size: 16 }),
|
|
118
122
|
notifications: _jsx(Bell, { size: 16 }),
|
|
119
123
|
};
|
|
124
|
+
const KIND_ICON = {
|
|
125
|
+
'': _jsx(Library, { size: 16 }),
|
|
126
|
+
image: _jsx(Image, { size: 16 }),
|
|
127
|
+
video: _jsx(Video, { size: 16 }),
|
|
128
|
+
audio: _jsx(AudioLines, { size: 16 }),
|
|
129
|
+
document: _jsx(FileText, { size: 16 }),
|
|
130
|
+
slides: _jsx(Presentation, { size: 16 }),
|
|
131
|
+
model: _jsx(Box, { size: 16 }),
|
|
132
|
+
code: _jsx(Code, { size: 16 }),
|
|
133
|
+
file: _jsx(File, { size: 16 }),
|
|
134
|
+
};
|
|
135
|
+
/** Fired on `window` once the sidebar's Upload has kept its files, for the Library to read again. */
|
|
136
|
+
export const KEPT = 'hanzo:library:kept';
|
|
137
|
+
/** Asks for files and keeps each in the Library; a refusal is said in the page's own words. */
|
|
138
|
+
function keep(host) {
|
|
139
|
+
const input = document.createElement('input');
|
|
140
|
+
input.type = 'file';
|
|
141
|
+
input.multiple = true;
|
|
142
|
+
input.onchange = async () => {
|
|
143
|
+
const t = { api: host.api, token: host.token, org: host.org };
|
|
144
|
+
for (const f of Array.from(input.files ?? [])) {
|
|
145
|
+
try {
|
|
146
|
+
await upload(t, { name: f.name, type: f.type, bytes: new Uint8Array(await f.arrayBuffer()) }, { source: 'chat' });
|
|
147
|
+
}
|
|
148
|
+
catch (e) {
|
|
149
|
+
window.alert(e instanceof Error ? e.message : `${f.name} was not kept`);
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
window.dispatchEvent(new Event(KEPT));
|
|
153
|
+
};
|
|
154
|
+
input.click();
|
|
155
|
+
}
|
|
156
|
+
/** The Library's sidebar: Upload, then every kind it narrows to, the one in the address lit. */
|
|
157
|
+
export function library(host, go) {
|
|
158
|
+
const r = route(host.path);
|
|
159
|
+
const at = r.kind === 'screen' && r.screen === 'artifacts' ? (r.of ?? '') : null;
|
|
160
|
+
return [
|
|
161
|
+
{ id: 'library-do', label: '', links: [{ id: 'upload', label: 'Upload', icon: _jsx(Upload, { size: 16 }), onPress: () => keep(host) }] },
|
|
162
|
+
{
|
|
163
|
+
id: 'library-kinds',
|
|
164
|
+
label: '',
|
|
165
|
+
links: KINDS.map((k) => ({
|
|
166
|
+
id: `kind-${k.id || 'all'}`,
|
|
167
|
+
label: k.label,
|
|
168
|
+
icon: KIND_ICON[k.id],
|
|
169
|
+
onPress: () => go(path({ kind: 'screen', screen: 'artifacts', ...(k.id ? { of: k.id } : {}) })),
|
|
170
|
+
active: at === k.id,
|
|
171
|
+
})),
|
|
172
|
+
},
|
|
173
|
+
];
|
|
174
|
+
}
|
|
175
|
+
/** Scheduled tasks' sidebar: New task, then each of the person's tasks, the one open lit. Read only while `on`. */
|
|
176
|
+
export function useScheduled(host, go, on) {
|
|
177
|
+
const t = useMemo(() => ({ api: host.api, token: host.token, org: host.org }), [host.api, host.token, host.org]);
|
|
178
|
+
const list = useRead(on && host.person ? () => automations(t) : null, [], [t, on, host.path]);
|
|
179
|
+
const r = route(host.path);
|
|
180
|
+
const at = r.kind === 'automation' ? r.id : '';
|
|
181
|
+
return [
|
|
182
|
+
{
|
|
183
|
+
id: 'scheduled-do',
|
|
184
|
+
label: '',
|
|
185
|
+
links: [{ id: 'new-task', label: 'New task', icon: _jsx(Plus, { size: 16 }), onPress: () => go(path({ kind: 'automation', id: 'new' })), active: at === 'new' }],
|
|
186
|
+
},
|
|
187
|
+
{
|
|
188
|
+
id: 'scheduled-tasks',
|
|
189
|
+
label: list.value.length ? 'Tasks' : '',
|
|
190
|
+
links: list.value.map((a) => ({ id: a.id, label: a.name || 'Untitled task', icon: _jsx(Clock, { size: 16 }), onPress: () => go(path({ kind: 'automation', id: a.id })), active: at === a.id })),
|
|
191
|
+
},
|
|
192
|
+
];
|
|
193
|
+
}
|
package/lib/route.d.ts
CHANGED
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
* '' the empty state: a new run
|
|
5
5
|
* sess_<32 hex> one run
|
|
6
6
|
* -/<screen> a builder screen
|
|
7
|
+
* -/artifacts/<kind> the Library narrowed to one kind (image, video, document, …)
|
|
7
8
|
* -/automations/<id> one automation's editor and runs; `new` writes one
|
|
8
9
|
* -/settings[/<section>] a section of Settings
|
|
9
10
|
* -/customize[/<tab>] agents, skills, connectors and plugins: what the agent brings to a run
|
|
@@ -42,6 +43,7 @@ export type Route = {
|
|
|
42
43
|
} | {
|
|
43
44
|
kind: 'screen';
|
|
44
45
|
screen: Screen;
|
|
46
|
+
of?: Of;
|
|
45
47
|
} | {
|
|
46
48
|
kind: 'settings';
|
|
47
49
|
section: Section;
|
|
@@ -62,6 +64,9 @@ export type Route = {
|
|
|
62
64
|
kind: 'automation';
|
|
63
65
|
id: string;
|
|
64
66
|
};
|
|
67
|
+
/** The kinds the Library narrows to by address (api/library.ts KIND_IDS). */
|
|
68
|
+
export declare const OF: readonly ['image', 'video', 'audio', 'document', 'slides', 'type', 'model', 'code', 'file'];
|
|
69
|
+
export type Of = (typeof OF)[number];
|
|
65
70
|
export declare const SESSION: RegExp;
|
|
66
71
|
export declare const SLUG: RegExp;
|
|
67
72
|
/** An organization or a repository name on the forge (api/codebases.ts `NAME`). */
|
package/lib/route.js
CHANGED
|
@@ -17,6 +17,8 @@ export const SECTIONS = [
|
|
|
17
17
|
];
|
|
18
18
|
/** Customize, one tab each: what the agent brings to a run, yours and to discover. Agents first. */
|
|
19
19
|
export const TABS = ['agents', 'skills', 'connectors', 'plugins'];
|
|
20
|
+
/** The kinds the Library narrows to by address (api/library.ts KIND_IDS). */
|
|
21
|
+
export const OF = ['image', 'video', 'audio', 'document', 'slides', 'type', 'model', 'code', 'file'];
|
|
20
22
|
export const SESSION = /^sess_[0-9a-f]{32}$/;
|
|
21
23
|
export const SLUG = /^[a-z0-9]([a-z0-9-]{0,38}[a-z0-9])?$/;
|
|
22
24
|
/** An organization or a repository name on the forge (api/codebases.ts `NAME`). */
|
|
@@ -44,6 +46,10 @@ export function route(path) {
|
|
|
44
46
|
const id = p.slice('-/automations/'.length);
|
|
45
47
|
return AUTOMATION.test(id) ? { kind: 'automation', id } : { kind: 'new' };
|
|
46
48
|
}
|
|
49
|
+
if (p.startsWith('-/artifacts/')) {
|
|
50
|
+
const of = p.slice('-/artifacts/'.length);
|
|
51
|
+
return OF.includes(of) ? { kind: 'screen', screen: 'artifacts', of } : { kind: 'new' };
|
|
52
|
+
}
|
|
47
53
|
if (p.startsWith('-/')) {
|
|
48
54
|
const s = p.slice(2);
|
|
49
55
|
return SCREENS.includes(s) ? { kind: 'screen', screen: s } : { kind: 'new' };
|
|
@@ -103,7 +109,7 @@ export function path(r) {
|
|
|
103
109
|
case 'run':
|
|
104
110
|
return r.id;
|
|
105
111
|
case 'screen':
|
|
106
|
-
return `-/${r.screen}`;
|
|
112
|
+
return r.of ? `-/${r.screen}/${r.of}` : `-/${r.screen}`;
|
|
107
113
|
case 'settings':
|
|
108
114
|
return r.section === 'general' ? '-/settings' : `-/settings/${r.section}`;
|
|
109
115
|
case 'customize':
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hanzo/build",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.76",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"license": "Apache-2.0 OR MIT",
|
|
6
6
|
"description": "Hanzo Build — say what you want, watch it built, deployed and running. The builder as a component, mounted by the Hanzo app at hanzo.ai.",
|