mirror of
https://github.com/hanzoai/chat.git
synced 2026-09-30 20:51:17 +00:00
Say how to build on the package
This commit is contained in:
@@ -1,8 +1,8 @@
|
||||
# Hanzo Chat
|
||||
|
||||
A chat client for the estate. Vite and React draw it, `@hanzo/ui` supplies the
|
||||
components on the `@hanzo/gui` runtime, and `@hanzo/ai` is the only thing that
|
||||
speaks to a server.
|
||||
A chat client, and the package the desktop is built from. Vite and React draw
|
||||
it, `@hanzo/ui` supplies the components on the `@hanzo/gui` runtime, and
|
||||
`@hanzo/ai` is the only thing that speaks to a server.
|
||||
|
||||
One bundle serves three products. `src/brand.ts` states a record per brand — its
|
||||
organization, issuer, name, mark, and the hosts it answers on — and `wear()`
|
||||
@@ -13,9 +13,13 @@ no name for the product comes from the server.
|
||||
|
||||
## The wire
|
||||
|
||||
There is no HTTP client here. `src/data/ai.ts` builds one `createAiClient` and
|
||||
that client owns the base URL, the bearer, the stale-token retry and the SSE
|
||||
decode, so no path to the API appears in this repository at all.
|
||||
There is no HTTP client here. `src/data/origin.ts` builds one `createAiClient`
|
||||
per origin and that client owns the base URL, the bearer, the stale-token retry
|
||||
and the SSE decode, so no path to the API appears in this repository at all. A
|
||||
model's address is `origin/model`, so choosing a model chooses where it runs —
|
||||
the estate under the visitor's IAM token, or an engine on this machine under the
|
||||
key the shell started it with. Nothing downstream of the picker knows there is
|
||||
more than one place.
|
||||
|
||||
| what | call | route |
|
||||
| --- | --- | --- |
|
||||
@@ -61,13 +65,49 @@ component props resolved by the gui config that `<Hanzo>` mounts, which is why
|
||||
one tree renders on web, native and desktop and why the type scale moves for the
|
||||
whole product from one place.
|
||||
|
||||
## Building on it
|
||||
|
||||
The package publishes its modules as built JavaScript beside their declarations,
|
||||
so anything under `src` is reachable by its own path and a consumer compiles
|
||||
nothing:
|
||||
|
||||
```tsx
|
||||
import { Thread } from '@hanzo/chat/thread/Thread'
|
||||
import { Compose } from '@hanzo/chat/compose/Compose'
|
||||
import { client, ESTATE } from '@hanzo/chat/data/origin'
|
||||
```
|
||||
|
||||
`@hanzo/vite` states the resolution the runtime needs — react-native-web, the
|
||||
web-first extension order, one copy of gui — so a consumer's config is that call
|
||||
and its own plugins:
|
||||
|
||||
```ts
|
||||
import { hanzo } from '@hanzo/vite'
|
||||
import react from '@vitejs/plugin-react'
|
||||
|
||||
const config = hanzo(
|
||||
{ plugins: [react()], define: { 'process.env': '{}' } },
|
||||
{ root: import.meta.dirname },
|
||||
)
|
||||
|
||||
export default {
|
||||
...config,
|
||||
optimizeDeps: {
|
||||
rollupOptions: { resolve: { extensions: (config.resolve as { extensions: string[] }).extensions } },
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
`@hanzo/desktop` is this package plus what only a machine has, so a desktop is a
|
||||
fork of that rather than a second copy of this.
|
||||
|
||||
## Verifying
|
||||
|
||||
```sh
|
||||
CI=true pnpm install --no-frozen-lockfile
|
||||
pnpm dev # localhost:3090, /v1 proxied so calls stay same-origin
|
||||
pnpm typecheck
|
||||
pnpm test # 22 assertions, node --test, no framework
|
||||
pnpm test # 31 assertions, node --test, no framework
|
||||
pnpm build
|
||||
```
|
||||
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@hanzo/chat",
|
||||
"version": "0.1.0",
|
||||
"version": "1.0.6",
|
||||
"type": "module",
|
||||
"license": "MIT",
|
||||
"description": "Hanzo Chat \u2014 the client, on @hanzo/gui + @hanzo/ui.",
|
||||
|
||||
@@ -14,9 +14,9 @@ import { Bot, Save, X } from '@hanzogui/lucide-icons-2'
|
||||
import { SizableText, XStack, YStack } from '@hanzo/ui'
|
||||
import { useState, type FormEvent } from 'react'
|
||||
|
||||
import { useModels } from '../data/config'
|
||||
import { ESTATE } from '../data/origin'
|
||||
import { create, useTools } from './store'
|
||||
import { useModels } from '../data/config.ts'
|
||||
import { ESTATE } from '../data/origin.ts'
|
||||
import { create, useTools } from './store.ts'
|
||||
|
||||
export interface AgentBuilderProps {
|
||||
isOpen: boolean
|
||||
|
||||
@@ -15,7 +15,7 @@ import { Loader, Play, Plus, Trash2, X } from '@hanzogui/lucide-icons-2'
|
||||
import { useState } from 'react'
|
||||
import type { Agent } from '@hanzo/ai'
|
||||
|
||||
import { none, remove, run, swarmStore, unread, useAgent, useAgents, useSwarm } from './store'
|
||||
import { none, remove, run, swarmStore, unread, useAgent, useAgents, useSwarm } from './store.ts'
|
||||
|
||||
export interface AgentsAndAppsModalProps {
|
||||
onOpenAgentBuilder?: () => void
|
||||
|
||||
@@ -11,8 +11,8 @@ import { SizableText, XStack, YStack } from '@hanzo/ui'
|
||||
import { useEffect, useRef, useState } from 'react'
|
||||
import type { Agent } from '@hanzo/ai'
|
||||
|
||||
import { useMultiplayer } from '../presence/store'
|
||||
import { none, swarmStore, unread, useAgents, useSwarm } from './store'
|
||||
import { useMultiplayer } from '../presence/store.ts'
|
||||
import { none, swarmStore, unread, useAgents, useSwarm } from './store.ts'
|
||||
|
||||
/** An agent's face: the glyph somebody picked, or its initial. */
|
||||
const face = (agent: Agent) => agent.emoji || agent.name.charAt(0).toUpperCase()
|
||||
|
||||
+4
-4
@@ -14,10 +14,10 @@
|
||||
import { APIError, type Agent, type AgentCreateParams, type AgentDetail, type AgentRun } from '@hanzo/ai'
|
||||
import { useEffect, useState } from 'react'
|
||||
|
||||
import { client, ESTATE } from '../data/origin'
|
||||
import type { Key } from '../data/keys'
|
||||
import { invalidate, useRead } from '../data/query'
|
||||
import { useSession } from '../data/session'
|
||||
import { client, ESTATE } from '../data/origin.ts'
|
||||
import type { Key } from '../data/keys.ts'
|
||||
import { invalidate, useRead } from '../data/query.ts'
|
||||
import { useSession } from '../data/session.tsx'
|
||||
|
||||
/**
|
||||
* What a reader is told when the server answers nothing, or does not answer.
|
||||
|
||||
+5
-5
@@ -1,11 +1,11 @@
|
||||
import { Toaster, TooltipProvider } from '@hanzo/ui'
|
||||
import { RouterProvider } from 'react-router/dom'
|
||||
|
||||
import { Session } from './data/session'
|
||||
import { shell } from './data/shell'
|
||||
import { router } from './routes'
|
||||
import { consent, usePref } from './settings/prefs'
|
||||
import { Welcome } from './shell/Welcome'
|
||||
import { Session } from './data/session.tsx'
|
||||
import { shell } from './data/shell.ts'
|
||||
import { router } from './routes.tsx'
|
||||
import { consent, usePref } from './settings/prefs.ts'
|
||||
import { Welcome } from './shell/Welcome.tsx'
|
||||
|
||||
/** How long a hint waits before it appears, everywhere. ONE provider, so the
|
||||
* product cannot have two hover speeds depending on which subtree the pointer
|
||||
|
||||
@@ -24,8 +24,8 @@ import {
|
||||
import { SizableText, XStack, YStack } from '@hanzo/ui'
|
||||
import { useEffect, useRef, useState, type CSSProperties } from 'react'
|
||||
|
||||
import { useLease, type Line } from '../terminal/sandbox'
|
||||
import { artifactStore, previewable, runner, useArtifact, type ArtifactTab } from './store'
|
||||
import { useLease, type Line } from '../terminal/sandbox.ts'
|
||||
import { artifactStore, previewable, runner, useArtifact, type ArtifactTab } from './store.ts'
|
||||
|
||||
const TAB = (active: boolean): CSSProperties => ({
|
||||
display: 'inline-flex',
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
* An artifact opens EMPTY. There is no code here until a fenced block or the
|
||||
* palette puts some here.
|
||||
*/
|
||||
import { sandbox } from '../terminal/sandbox'
|
||||
import { sandbox } from '../terminal/sandbox.ts'
|
||||
|
||||
import { useEffect, useState } from 'react'
|
||||
|
||||
|
||||
@@ -9,10 +9,10 @@
|
||||
import { Clock, Play, Plus, X, Zap } from '@hanzogui/lucide-icons-2'
|
||||
import { useState, type FormEvent } from 'react'
|
||||
|
||||
import { useSession } from '../data/session'
|
||||
import { useSession } from '../data/session.tsx'
|
||||
|
||||
import { add, arm, start, useFlows, useRuns } from './auto'
|
||||
import { automationsStore, useAutomations } from './store'
|
||||
import { add, arm, start, useFlows, useRuns } from './auto.ts'
|
||||
import { automationsStore, useAutomations } from './store.ts'
|
||||
|
||||
const clock = (at?: number) => (at ? new Date(at).toLocaleString() : '')
|
||||
|
||||
|
||||
@@ -16,8 +16,8 @@
|
||||
* Nothing publishes a next firing time or a lifetime run total, so neither is
|
||||
* read. The last run is the head of `/v1/auto/runs`, which is newest first.
|
||||
*/
|
||||
import { client, ESTATE } from '../data/origin'
|
||||
import { invalidate, useRead } from '../data/query'
|
||||
import { client, ESTATE } from '../data/origin.ts'
|
||||
import { invalidate, useRead } from '../data/query.ts'
|
||||
|
||||
/** A flow row joined to its own record. Unix milliseconds on both clocks. */
|
||||
export type Flow = {
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
* The flows and their runs are the server's — `auto.ts` reads them — so the
|
||||
* panel holds only whether it is open and which row is expanded.
|
||||
*/
|
||||
import { atom, useAtom } from '../data/store'
|
||||
import { atom, useAtom } from '../data/store.ts'
|
||||
|
||||
export type Panel = {
|
||||
isOpen: boolean
|
||||
|
||||
@@ -10,9 +10,9 @@
|
||||
import { ArrowLeft, ArrowRight, Hand, Kanban, Plus, Search, X } from '@hanzogui/lucide-icons-2'
|
||||
import { useState, type FormEvent } from 'react'
|
||||
|
||||
import { useSession } from '../data/session'
|
||||
import { useSession } from '../data/session.tsx'
|
||||
|
||||
import { boardStore, useBoard } from './store'
|
||||
import { boardStore, useBoard } from './store.ts'
|
||||
import {
|
||||
COLUMNS,
|
||||
PRIORITIES,
|
||||
@@ -25,7 +25,7 @@ import {
|
||||
type Column,
|
||||
type Issue,
|
||||
type Priority,
|
||||
} from './todo'
|
||||
} from './todo.ts'
|
||||
|
||||
const columnLook: Record<Column, { title: string; color: string }> = {
|
||||
backlog: { title: 'Backlog', color: 'rgba(255, 255, 255, 0.4)' },
|
||||
|
||||
+1
-1
@@ -5,7 +5,7 @@
|
||||
* board, what was typed into the search box, and which card is open. None of
|
||||
* that outlives the tab, which is why none of it is persisted.
|
||||
*/
|
||||
import { atom, useAtom } from '../data/store'
|
||||
import { atom, useAtom } from '../data/store.ts'
|
||||
|
||||
export type View = {
|
||||
isOpen: boolean
|
||||
|
||||
+2
-2
@@ -19,8 +19,8 @@
|
||||
* purpose: a board IS a repository on the forge, and creating one is a forge
|
||||
* act with forge permissions.
|
||||
*/
|
||||
import { client, ESTATE } from '../data/origin'
|
||||
import { invalidate, useRead } from '../data/query'
|
||||
import { client, ESTATE } from '../data/origin.ts'
|
||||
import { invalidate, useRead } from '../data/query.ts'
|
||||
|
||||
/** The five columns the server recognises. An unknown value is refused with 400. */
|
||||
export const COLUMNS = ['backlog', 'todo', 'in_progress', 'done', 'canceled'] as const
|
||||
|
||||
+1
-1
@@ -20,7 +20,7 @@
|
||||
* Everything a brand can differ by is HERE, because split across two homes it
|
||||
* gets half-applied and every brand ends up wearing the first one's name.
|
||||
*/
|
||||
import { shell } from './data/shell'
|
||||
import { shell } from './data/shell.ts'
|
||||
|
||||
export type Brand = {
|
||||
/** IAM organization, lowercase. The OAuth client is `<org>-<app>`. */
|
||||
|
||||
@@ -13,8 +13,8 @@ import { SizableText, XStack, YStack } from '@hanzo/ui'
|
||||
import { X } from '@hanzogui/lucide-icons-2'
|
||||
import { useEffect } from 'react'
|
||||
|
||||
import { why } from '../data/missing'
|
||||
import { channelsStore, refusal, speaker, useChannels, useTransports, when } from './store'
|
||||
import { why } from '../data/missing.ts'
|
||||
import { channelsStore, refusal, speaker, useChannels, useTransports, when } from './store.ts'
|
||||
|
||||
const Note = ({ children }: { children: string }) => (
|
||||
<SizableText size="$1" style={{ fontSize: 12, color: 'rgba(255, 255, 255, 0.45)' }}>
|
||||
|
||||
@@ -14,8 +14,8 @@
|
||||
import { SizableText, XStack, YStack } from '@hanzo/ui'
|
||||
import { Compass, Hash, MessageSquare } from '@hanzogui/lucide-icons-2'
|
||||
|
||||
import { why } from '../data/missing'
|
||||
import { channelsStore, refusal, useChannels, when } from './store'
|
||||
import { why } from '../data/missing.ts'
|
||||
import { channelsStore, refusal, useChannels, when } from './store.ts'
|
||||
|
||||
const Note = ({ children }: { children: string }) => (
|
||||
<SizableText
|
||||
|
||||
@@ -21,12 +21,12 @@
|
||||
*/
|
||||
import { APIError, rooms as group, type Channel, type Room } from '@hanzo/ai'
|
||||
|
||||
import { client, ESTATE } from '../data/origin'
|
||||
import type { Key } from '../data/keys'
|
||||
import { peek, useRead, type Read } from '../data/query'
|
||||
import { useSession } from '../data/session'
|
||||
import { atom, useAtom } from '../data/store'
|
||||
import { explain } from '../data/types'
|
||||
import { client, ESTATE } from '../data/origin.ts'
|
||||
import type { Key } from '../data/keys.ts'
|
||||
import { peek, useRead, type Read } from '../data/query.ts'
|
||||
import { useSession } from '../data/session.tsx'
|
||||
import { atom, useAtom } from '../data/store.ts'
|
||||
import { explain } from '../data/types.ts'
|
||||
|
||||
/** Two cache keys under one prefix, so both drop together. */
|
||||
const TRANSPORTS: Key = ['channels', 'transports']
|
||||
|
||||
@@ -6,11 +6,11 @@ import { ArrowUp, Mic, MicOff, Paperclip, Square, X } from '@hanzogui/lucide-ico
|
||||
import { SizableText, XStack, YStack } from '@hanzo/ui'
|
||||
import { useCallback, useEffect, useRef, useState, type ReactNode } from 'react'
|
||||
|
||||
import { Starters, type Starter } from './Starters'
|
||||
import { useDraft } from './draft'
|
||||
import type { Handoff } from './link'
|
||||
import { payload, type Conversation, type Draft, type Payload } from './submit'
|
||||
import type { Attachment } from '../data/types'
|
||||
import { Starters, type Starter } from './Starters.tsx'
|
||||
import { useDraft } from './draft.ts'
|
||||
import type { Handoff } from './link.ts'
|
||||
import { payload, type Conversation, type Draft, type Payload } from './submit.ts'
|
||||
import type { Attachment } from '../data/types.ts'
|
||||
|
||||
const COLUMN = 768
|
||||
const MAX_TEXTAREA_HEIGHT = 220
|
||||
|
||||
@@ -3,8 +3,8 @@
|
||||
*/
|
||||
import { useCallback, useEffect, useRef, useState } from 'react'
|
||||
|
||||
import { blank, type Draft } from './submit'
|
||||
import type { Attachment } from '../data/types'
|
||||
import { blank, type Draft } from './submit.ts'
|
||||
import type { Attachment } from '../data/types.ts'
|
||||
|
||||
export const NEW = 'new'
|
||||
|
||||
|
||||
@@ -4,8 +4,8 @@
|
||||
* One verb, streaming decoded `chat.completion.chunk` values from @hanzo/ai.
|
||||
*/
|
||||
import type { ChatCompletionChunk, ChatCompletionMessage } from '@hanzo/ai'
|
||||
import { client, ESTATE } from '../data/origin'
|
||||
import { explain } from '../data/types'
|
||||
import { client, ESTATE } from '../data/origin.ts'
|
||||
import { explain } from '../data/types.ts'
|
||||
|
||||
/** How a turn ended. The shell answers each differently, so it is told which. */
|
||||
export type Ended =
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
*/
|
||||
import type { ChatCompletionContentPart, ChatCompletionMessage } from '@hanzo/ai'
|
||||
|
||||
import type { Attachment, Message } from '../data/types'
|
||||
import type { Attachment, Message } from '../data/types.ts'
|
||||
|
||||
/**
|
||||
* What the composer holds.
|
||||
|
||||
@@ -16,7 +16,7 @@ import { test } from 'node:test'
|
||||
|
||||
import { createAiClient, type ChatCompletionChunk } from '@hanzo/ai'
|
||||
|
||||
import type { Message } from '../data/types'
|
||||
import type { Message } from '../data/types.ts'
|
||||
|
||||
import { fold, opening, parts, spoken } from './frames.ts'
|
||||
import { history } from './submit.ts'
|
||||
|
||||
+1
-1
@@ -11,7 +11,7 @@
|
||||
* go, and where this app's own doorway is. Both are navigations rather than
|
||||
* requests — the browser leaves — so neither can be a method call.
|
||||
*/
|
||||
import { brand, clientId } from '../brand'
|
||||
import { brand, clientId } from '../brand.ts'
|
||||
|
||||
export const api = {
|
||||
/**
|
||||
|
||||
+4
-4
@@ -16,10 +16,10 @@
|
||||
* always was; what a guest may do is decided server-side from the absence of a
|
||||
* bearer, which is where it belongs and where it was already decided.
|
||||
*/
|
||||
import { keys } from './keys'
|
||||
import { client, origins } from './origin'
|
||||
import { useRead } from './query'
|
||||
import type { Served } from './types'
|
||||
import { keys } from './keys.ts'
|
||||
import { client, origins } from './origin.ts'
|
||||
import { useRead } from './query.ts'
|
||||
import type { Served } from './types.ts'
|
||||
|
||||
/** Who publishes a model, when it says. The menu's fallback group. */
|
||||
const OTHER = 'other'
|
||||
|
||||
+4
-4
@@ -12,10 +12,10 @@
|
||||
* There is no route to write to and no SDK method to call, so nothing here
|
||||
* pretends otherwise — `~/data/missing` is what the rail's controls report.
|
||||
*/
|
||||
import { client, ESTATE } from './origin'
|
||||
import { keys } from './keys'
|
||||
import { useRead } from './query'
|
||||
import type { Convo } from './types'
|
||||
import { client, ESTATE } from './origin.ts'
|
||||
import { keys } from './keys.ts'
|
||||
import { useRead } from './query.ts'
|
||||
import type { Convo } from './types.ts'
|
||||
|
||||
/**
|
||||
* Every conversation, newest first.
|
||||
|
||||
+1
-1
@@ -7,7 +7,7 @@
|
||||
* What a guest may do is decided there, from the absence of a bearer — which is
|
||||
* also why becoming one cannot fail and asks nobody's permission.
|
||||
*/
|
||||
import type { User } from './types'
|
||||
import type { User } from './types.ts'
|
||||
|
||||
export const GUEST = 'guest'
|
||||
|
||||
|
||||
+2
-2
@@ -11,8 +11,8 @@
|
||||
*/
|
||||
import { IAM } from '@hanzo/iam'
|
||||
|
||||
import { brand, clientId } from '../brand'
|
||||
import { callbackPath, loginPath } from './api'
|
||||
import { brand, clientId } from '../brand.ts'
|
||||
import { callbackPath, loginPath } from './api.ts'
|
||||
|
||||
/**
|
||||
* What a session asks for.
|
||||
|
||||
@@ -16,10 +16,10 @@
|
||||
* 200 with an empty transcript for another tenant's id, so the SDK reads empty
|
||||
* as absent. An empty list is passed straight through as an empty conversation.
|
||||
*/
|
||||
import { client } from './origin'
|
||||
import { keys } from './keys'
|
||||
import { useRead } from './query'
|
||||
import type { Message } from './types'
|
||||
import { client } from './origin.ts'
|
||||
import { keys } from './keys.ts'
|
||||
import { useRead } from './query.ts'
|
||||
import type { Message } from './types.ts'
|
||||
|
||||
/**
|
||||
* Every turn of one conversation, oldest first.
|
||||
|
||||
+4
-4
@@ -16,10 +16,10 @@
|
||||
*/
|
||||
import { createAiClient, type AiClient } from '@hanzo/ai'
|
||||
|
||||
import { brand } from '../brand'
|
||||
import { iam } from './iam'
|
||||
import { shell } from './shell'
|
||||
import { key } from '../settings/prefs'
|
||||
import { brand } from '../brand.ts'
|
||||
import { iam } from './iam.ts'
|
||||
import { shell } from './shell.ts'
|
||||
import { key } from '../settings/prefs.ts'
|
||||
|
||||
/** The estate. Its base URL is the SDK's default and is not restated. */
|
||||
export const ESTATE = 'hanzo'
|
||||
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
/**
|
||||
* Ask the issuer, once per visit, whether this browser is already signed in.
|
||||
*/
|
||||
import { keepHere } from './back'
|
||||
import { keepHere } from './back.ts'
|
||||
|
||||
const SLOT = 'chat.probed'
|
||||
|
||||
|
||||
+1
-1
@@ -25,7 +25,7 @@
|
||||
*/
|
||||
import { useCallback, useEffect, useRef, useState, useSyncExternalStore } from 'react'
|
||||
|
||||
import type { Key } from './keys'
|
||||
import type { Key } from './keys.ts'
|
||||
|
||||
/** A separator no key part contains, so a prefix match is a real prefix. */
|
||||
const SEP = ''
|
||||
|
||||
+10
-10
@@ -33,17 +33,17 @@ import {
|
||||
type ReactNode,
|
||||
} from 'react'
|
||||
|
||||
import { client } from './origin'
|
||||
import { api } from './api'
|
||||
import { keepHere, take } from './back'
|
||||
import { guest } from './guest'
|
||||
import { iam } from './iam'
|
||||
import { client } from './origin.ts'
|
||||
import { api } from './api.ts'
|
||||
import { keepHere, take } from './back.ts'
|
||||
import { guest } from './guest.ts'
|
||||
import { iam } from './iam.ts'
|
||||
import { HeldError } from '@hanzo/ai'
|
||||
import { keys } from './keys'
|
||||
import { exchanging, noSession, probe } from './probe'
|
||||
import { invalidate, useRead } from './query'
|
||||
import { shell, visit } from './shell'
|
||||
import type { Standing, User } from './types'
|
||||
import { keys } from './keys.ts'
|
||||
import { exchanging, noSession, probe } from './probe.ts'
|
||||
import { invalidate, useRead } from './query.ts'
|
||||
import { shell, visit } from './shell.ts'
|
||||
import type { Standing, User } from './types.ts'
|
||||
|
||||
|
||||
export type Session = {
|
||||
|
||||
+1
-1
@@ -19,7 +19,7 @@
|
||||
*/
|
||||
import { useSyncExternalStore } from 'react'
|
||||
|
||||
import type { Convo, Failure, Message } from './types'
|
||||
import type { Convo, Failure, Message } from './types.ts'
|
||||
|
||||
export type Atom<T> = {
|
||||
/** The value, right now. */
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
import { brand } from '../brand'
|
||||
import { brand } from '../brand.ts'
|
||||
|
||||
/**
|
||||
* What the wire carries, and what a refusal means to a reader.
|
||||
|
||||
+1
-1
@@ -22,7 +22,7 @@
|
||||
* NOT fall back to is a store that answers every call and forgets on exit,
|
||||
* which reads as a working keychain until the restart that loses the session.
|
||||
*/
|
||||
import { call, shell } from './shell'
|
||||
import { call, shell } from './shell.ts'
|
||||
|
||||
/** One entry, holding the whole session: the tokens travel together. */
|
||||
const NAME = 'session'
|
||||
|
||||
@@ -10,8 +10,8 @@ import {
|
||||
} from '@hanzogui/lucide-icons-2'
|
||||
import { SizableText, XStack, YStack } from '@hanzo/ui'
|
||||
import { useState, type FormEvent } from 'react'
|
||||
import { useShown } from '../show'
|
||||
import { intelligenceStore, useForget, useIntelligence, useRemember } from './store'
|
||||
import { useShown } from '../show.ts'
|
||||
import { intelligenceStore, useForget, useIntelligence, useRemember } from './store.ts'
|
||||
|
||||
export const IntelligenceModal = () => {
|
||||
const { isOpen, memories, symbols, query, activeTab, pending, fault, degraded } =
|
||||
|
||||
@@ -14,10 +14,10 @@
|
||||
* every keystroke sent a request and minted a cache entry per character, and
|
||||
* every one but the last was a question already finished being asked.
|
||||
*/
|
||||
import { atom, useAtom } from '../data/store'
|
||||
import { keys } from '../data/keys'
|
||||
import { client, ESTATE } from '../data/origin'
|
||||
import { reason, useRead, useSend, useSettled } from '../data/query'
|
||||
import { atom, useAtom } from '../data/store.ts'
|
||||
import { keys } from '../data/keys.ts'
|
||||
import { client, ESTATE } from '../data/origin.ts'
|
||||
import { reason, useRead, useSend, useSettled } from '../data/query.ts'
|
||||
|
||||
export interface MemoryItem {
|
||||
/** The memory's name in the store — how it is addressed. */
|
||||
|
||||
+3
-3
@@ -7,9 +7,9 @@ import '@hanzo/font/css'
|
||||
import { StrictMode } from 'react'
|
||||
import { createRoot } from 'react-dom/client'
|
||||
|
||||
import { App } from './app'
|
||||
import { brand, wear } from './brand'
|
||||
import { unlock } from './data/vault'
|
||||
import { App } from './app.tsx'
|
||||
import { brand, wear } from './brand.ts'
|
||||
import { unlock } from './data/vault.ts'
|
||||
|
||||
/**
|
||||
* The mount. Three lines, and the second one is the whole design system.
|
||||
|
||||
@@ -19,10 +19,10 @@ import { Blocks, Check, Plus, Power, Search, Trash2, Wrench, X } from '@hanzogui
|
||||
import { SizableText, XStack, YStack } from '@hanzo/ui'
|
||||
import { useEffect, useState } from 'react'
|
||||
|
||||
import { requireLogin } from '../data/gate'
|
||||
import { useSession } from '../data/session'
|
||||
import { mcpStore, useCatalog, useMcp } from './store'
|
||||
import type { McpServer } from './types'
|
||||
import { requireLogin } from '../data/gate.ts'
|
||||
import { useSession } from '../data/session.tsx'
|
||||
import { mcpStore, useCatalog, useMcp } from './store.ts'
|
||||
import type { McpServer } from './types.ts'
|
||||
|
||||
const dim = 'rgba(255, 255, 255, 0.5)'
|
||||
const faint = 'rgba(255, 255, 255, 0.4)'
|
||||
|
||||
+5
-5
@@ -22,11 +22,11 @@
|
||||
*/
|
||||
import { useSyncExternalStore } from 'react'
|
||||
|
||||
import { client, ESTATE } from '../data/origin'
|
||||
import { keys, sign, type Key } from '../data/keys'
|
||||
import { invalidate, peek, useRead } from '../data/query'
|
||||
import { useSession } from '../data/session'
|
||||
import type { McpServer } from './types'
|
||||
import { client, ESTATE } from '../data/origin.ts'
|
||||
import { keys, sign, type Key } from '../data/keys.ts'
|
||||
import { invalidate, peek, useRead } from '../data/query.ts'
|
||||
import { useSession } from '../data/session.tsx'
|
||||
import type { McpServer } from './types.ts'
|
||||
|
||||
const ACTIVATION = '/v1/tools/activation'
|
||||
const SERVERS = '/v1/tools/mcp/servers'
|
||||
|
||||
@@ -10,9 +10,9 @@
|
||||
import { Blocks, Search, X } from '@hanzogui/lucide-icons-2'
|
||||
import { useState } from 'react'
|
||||
|
||||
import { requireLogin } from '../data/gate'
|
||||
import { useSession } from '../data/session'
|
||||
import { pluginsStore, usePlugins } from './store'
|
||||
import { requireLogin } from '../data/gate.ts'
|
||||
import { useSession } from '../data/session.tsx'
|
||||
import { pluginsStore, usePlugins } from './store.ts'
|
||||
|
||||
const dim = 'rgba(255, 255, 255, 0.5)'
|
||||
const faint = 'rgba(255, 255, 255, 0.4)'
|
||||
|
||||
@@ -15,10 +15,10 @@
|
||||
import { useSyncExternalStore } from 'react'
|
||||
import type { PluginMount } from '@hanzo/ai'
|
||||
|
||||
import { client, ESTATE } from '../data/origin'
|
||||
import type { Key } from '../data/keys'
|
||||
import { useRead } from '../data/query'
|
||||
import { useSession } from '../data/session'
|
||||
import { client, ESTATE } from '../data/origin.ts'
|
||||
import type { Key } from '../data/keys.ts'
|
||||
import { useRead } from '../data/query.ts'
|
||||
import { useSession } from '../data/session.tsx'
|
||||
|
||||
const key: Key = ['plugins']
|
||||
|
||||
|
||||
@@ -16,8 +16,8 @@ import { APIError } from '@hanzo/ai'
|
||||
import { Users, X } from '@hanzogui/lucide-icons-2'
|
||||
import { SizableText, XStack, YStack } from '@hanzo/ui'
|
||||
|
||||
import { initial, label, tint } from './person'
|
||||
import { multiplayerStore, useMultiplayer } from './store'
|
||||
import { initial, label, tint } from './person.ts'
|
||||
import { multiplayerStore, useMultiplayer } from './store.ts'
|
||||
|
||||
/** What an empty roster means. The refusal is the contract's own sentence. */
|
||||
const nothing = (error: unknown, pending: boolean): string => {
|
||||
|
||||
@@ -12,9 +12,9 @@
|
||||
import { Terminal, Users } from '@hanzogui/lucide-icons-2'
|
||||
import { XStack } from '@hanzo/ui'
|
||||
|
||||
import { initial, label, tint } from './person'
|
||||
import { multiplayerStore, useMultiplayer } from './store'
|
||||
import { terminalStore, useTerminal } from '../terminal/store'
|
||||
import { initial, label, tint } from './person.ts'
|
||||
import { multiplayerStore, useMultiplayer } from './store.ts'
|
||||
import { terminalStore, useTerminal } from '../terminal/store.ts'
|
||||
|
||||
export const PresenceStack = () => {
|
||||
const { participants } = useMultiplayer()
|
||||
|
||||
@@ -25,9 +25,9 @@
|
||||
import { useCallback, useSyncExternalStore } from 'react'
|
||||
import type { Person } from '@hanzo/ai'
|
||||
|
||||
import { client, ESTATE } from '../data/origin'
|
||||
import { useRead } from '../data/query'
|
||||
import { useSession } from '../data/session'
|
||||
import { client, ESTATE } from '../data/origin.ts'
|
||||
import { useRead } from '../data/query.ts'
|
||||
import { useSession } from '../data/session.tsx'
|
||||
|
||||
export type MultiplayerState = {
|
||||
/** Whether the roster panel is open. */
|
||||
|
||||
@@ -8,10 +8,10 @@
|
||||
import { Building2, FolderGit2, Plus, Star, UserCheck, X } from '@hanzogui/lucide-icons-2'
|
||||
import { useState, type FormEvent } from 'react'
|
||||
|
||||
import { useSession } from '../data/session'
|
||||
import { useSession } from '../data/session.tsx'
|
||||
|
||||
import { create, star, useProjects, usePeople } from './projects'
|
||||
import { projectsStore, useProjectPanel } from './store'
|
||||
import { create, star, useProjects, usePeople } from './projects.ts'
|
||||
import { projectsStore, useProjectPanel } from './store.ts'
|
||||
|
||||
const field = {
|
||||
padding: '8px 12px',
|
||||
|
||||
@@ -13,8 +13,8 @@
|
||||
*/
|
||||
import type { Person } from '@hanzo/ai'
|
||||
|
||||
import { client, ESTATE } from '../data/origin'
|
||||
import { invalidate, useRead } from '../data/query'
|
||||
import { client, ESTATE } from '../data/origin.ts'
|
||||
import { invalidate, useRead } from '../data/query.ts'
|
||||
|
||||
/** A project row, as `/v1/projects` answers it. `slug` is what addresses it. */
|
||||
export type Project = {
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
* and the org is the principal's, so the only thing left to hold is whether
|
||||
* this panel is open and which of its two lists is in front.
|
||||
*/
|
||||
import { atom, useAtom } from '../data/store'
|
||||
import { atom, useAtom } from '../data/store.ts'
|
||||
|
||||
export type Pane = 'projects' | 'people'
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* The bottom user menu popover in the rail with Linear.app style liquid-glass aesthetics,
|
||||
* org switcher, account controls, and appearance options.
|
||||
*/
|
||||
import { api } from '../data/api'
|
||||
import { api } from '../data/api.ts'
|
||||
import {
|
||||
ChevronsUpDown,
|
||||
ExternalLink,
|
||||
|
||||
+3
-3
@@ -2,10 +2,10 @@ import { SizableText, YStack } from '@hanzo/ui'
|
||||
import { SidebarScroll, SidebarSection } from '@hanzo/ui/chat'
|
||||
import { useMemo } from 'react'
|
||||
|
||||
import type { Convo } from '../data/types'
|
||||
import type { Convo } from '../data/types.ts'
|
||||
|
||||
import { hits, id } from './group'
|
||||
import { Item } from './Item'
|
||||
import { hits, id } from './group.ts'
|
||||
import { Item } from './Item.tsx'
|
||||
|
||||
/**
|
||||
* What finding one found.
|
||||
|
||||
+2
-2
@@ -1,9 +1,9 @@
|
||||
import { Spinner } from '@hanzo/ui'
|
||||
import { SidebarItem } from '@hanzo/ui/chat'
|
||||
|
||||
import type { Convo } from '../data/types'
|
||||
import type { Convo } from '../data/types.ts'
|
||||
|
||||
import { named } from './group'
|
||||
import { named } from './group.ts'
|
||||
|
||||
/**
|
||||
* ONE conversation, as a row.
|
||||
|
||||
+3
-3
@@ -2,10 +2,10 @@ import { Paragraph, SizableText, Spinner, XStack } from '@hanzo/ui'
|
||||
import { SidebarScroll, SidebarSection } from '@hanzo/ui/chat'
|
||||
import { useEffect, useMemo, useRef } from 'react'
|
||||
|
||||
import type { Convo } from '../data/types'
|
||||
import type { Convo } from '../data/types.ts'
|
||||
|
||||
import { group, id } from './group'
|
||||
import { Item } from './Item'
|
||||
import { group, id } from './group.ts'
|
||||
import { Item } from './Item.tsx'
|
||||
|
||||
/**
|
||||
* The set, as the rail draws it: banded by when, newest first, pinned above.
|
||||
|
||||
+9
-9
@@ -5,15 +5,15 @@ import { HanzoMark } from '@hanzo/ui/product'
|
||||
import { Blocks, Kanban, LayoutGrid, ListTodo } from '@hanzogui/lucide-icons-2'
|
||||
import { useRef, useState, type ReactNode } from 'react'
|
||||
|
||||
import { boardStore } from '../boards/store'
|
||||
import { ChannelSection } from '../channels/ChannelSection'
|
||||
import { mcpStore } from '../mcp/store'
|
||||
import { swarmStore } from '../agents/store'
|
||||
import { taskQueueStore } from '../tasks/store'
|
||||
import type { Convo } from '../data/types'
|
||||
import { Find } from './Find'
|
||||
import { Hits } from './Hits'
|
||||
import { List } from './List'
|
||||
import { boardStore } from '../boards/store.ts'
|
||||
import { ChannelSection } from '../channels/ChannelSection.tsx'
|
||||
import { mcpStore } from '../mcp/store.ts'
|
||||
import { swarmStore } from '../agents/store.ts'
|
||||
import { taskQueueStore } from '../tasks/store.ts'
|
||||
import type { Convo } from '../data/types.ts'
|
||||
import { Find } from './Find.tsx'
|
||||
import { Hits } from './Hits.tsx'
|
||||
import { List } from './List.tsx'
|
||||
|
||||
export const OPEN = 270
|
||||
export const RAIL = 56
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
import type { Convo } from '../data/types'
|
||||
import type { Convo } from '../data/types.ts'
|
||||
|
||||
/**
|
||||
* The SET, ordered and named — the only rules about a list of conversations
|
||||
|
||||
+5
-5
@@ -1,10 +1,10 @@
|
||||
import { createBrowserRouter, Navigate } from 'react-router'
|
||||
|
||||
import { Boundary } from './shell/Boundary'
|
||||
import { Callback } from './shell/Callback'
|
||||
import { Chat } from './shell/Chat'
|
||||
import { Login } from './shell/Login'
|
||||
import { Root } from './shell/Root'
|
||||
import { Boundary } from './shell/Boundary.tsx'
|
||||
import { Callback } from './shell/Callback.tsx'
|
||||
import { Chat } from './shell/Chat.tsx'
|
||||
import { Login } from './shell/Login.tsx'
|
||||
import { Root } from './shell/Root.tsx'
|
||||
|
||||
/**
|
||||
* Where the app is mounted, from the document that served it.
|
||||
|
||||
@@ -14,8 +14,8 @@ import { row, rows } from '@hanzo/ui/glass'
|
||||
import { ConfirmDelete, DialogTemplate } from '@hanzo/ui/product'
|
||||
import { useState } from 'react'
|
||||
|
||||
import { api } from '../data/api'
|
||||
import type { User } from '../data/types'
|
||||
import { api } from '../data/api.ts'
|
||||
import type { User } from '../data/types.ts'
|
||||
|
||||
|
||||
export interface AccountProps {
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import { Paragraph, SizableText, Switch, XStack, YStack } from '@hanzo/ui'
|
||||
import { row, rows } from '@hanzo/ui/glass'
|
||||
|
||||
import { Model } from './Model'
|
||||
import type { Served } from '../data/types'
|
||||
import { model, steps, temporary, usePref, type Pref } from './prefs'
|
||||
import { Model } from './Model.tsx'
|
||||
import type { Served } from '../data/types.ts'
|
||||
import { model, steps, temporary, usePref, type Pref } from './prefs.ts'
|
||||
|
||||
/**
|
||||
* One preference, as a line: the name, what it does under it, the switch hard
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import { Paragraph, YStack } from '@hanzo/ui'
|
||||
import { rows } from '@hanzo/ui/glass'
|
||||
|
||||
import { Toggle } from './General'
|
||||
import { compact, full } from './prefs'
|
||||
import { Toggle } from './General.tsx'
|
||||
import { compact, full } from './prefs.ts'
|
||||
|
||||
/**
|
||||
* How the conversation reads.
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
import { Blocks, ExternalLink, Power } from '@hanzogui/lucide-icons-2'
|
||||
import { Paragraph, SizableText, XStack, YStack } from '@hanzo/ui'
|
||||
import { row, rows } from '@hanzo/ui/glass'
|
||||
import { mcpStore, useMcp } from '../mcp/store'
|
||||
import { mcpStore, useMcp } from '../mcp/store.ts'
|
||||
|
||||
export function McpSettings() {
|
||||
const { servers } = useMcp()
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import { ModelSelector } from '@hanzo/ui/models'
|
||||
import { useMemo } from 'react'
|
||||
|
||||
import { origins } from '../data/origin'
|
||||
import type { Served } from '../data/types'
|
||||
import { catalog } from './models'
|
||||
import { origins } from '../data/origin.ts'
|
||||
import type { Served } from '../data/types.ts'
|
||||
import { catalog } from './models.ts'
|
||||
|
||||
/**
|
||||
* Which model answers — one control, every surface that asks.
|
||||
|
||||
@@ -16,12 +16,12 @@ import {
|
||||
import { selected } from '@hanzo/ui/glass'
|
||||
import { useState, type ReactNode } from 'react'
|
||||
|
||||
import { Account, type AccountProps } from './Account'
|
||||
import { AiSettings } from './AiSettings'
|
||||
import { General } from './General'
|
||||
import { Look } from './Look'
|
||||
import { McpSettings } from './McpSettings'
|
||||
import type { Served } from '../data/types'
|
||||
import { Account, type AccountProps } from './Account.tsx'
|
||||
import { AiSettings } from './AiSettings.tsx'
|
||||
import { General } from './General.tsx'
|
||||
import { Look } from './Look.tsx'
|
||||
import { McpSettings } from './McpSettings.tsx'
|
||||
import type { Served } from '../data/types.ts'
|
||||
|
||||
export interface SettingsProps {
|
||||
open: boolean
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import type { ModelCatalogEntry } from '@hanzo/ui/models'
|
||||
|
||||
import type { Origin } from '../data/origin'
|
||||
import type { Served } from '../data/types'
|
||||
import type { Origin } from '../data/origin.ts'
|
||||
import type { Served } from '../data/types.ts'
|
||||
|
||||
/**
|
||||
* What can be asked, as ONE list a picker can read.
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { atom, useAtom, type Atom } from '../data/store'
|
||||
import { atom, useAtom, type Atom } from '../data/store.ts'
|
||||
|
||||
/**
|
||||
* Every preference that outlives the tab, and the only code in this app that
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import { useEffect, useRef } from 'react'
|
||||
import { useNavigate } from 'react-router'
|
||||
|
||||
import { loginPath } from '../data/api'
|
||||
import { useSession } from '../data/session'
|
||||
import { Waiting } from './Boundary'
|
||||
import { loginPath } from '../data/api.ts'
|
||||
import { useSession } from '../data/session.tsx'
|
||||
import { Waiting } from './Boundary.tsx'
|
||||
|
||||
/**
|
||||
* Where a sign-in lands on the way back from the issuer.
|
||||
|
||||
+32
-32
@@ -2,38 +2,38 @@ import { Fill, H2, Paragraph, XStack, YStack } from '@hanzo/ui'
|
||||
import { useCallback, useEffect, useMemo, useRef } from 'react'
|
||||
import { useLocation, useNavigate, useParams } from 'react-router'
|
||||
|
||||
import { SwarmBar } from '../agents/SwarmBar'
|
||||
import { ArtifactPanel } from '../artifact/ArtifactPanel'
|
||||
import { artifactStore } from '../artifact/store'
|
||||
import { brand } from '../brand'
|
||||
import { Compose } from '../compose/Compose'
|
||||
import { faulted, fold, opening, parts, spoken, stopped, type Part as Piece, type Reply } from '../compose/frames'
|
||||
import { useHandoff } from '../compose/link'
|
||||
import { run } from '../compose/stream'
|
||||
import { history, type Conversation, type Payload } from '../compose/submit'
|
||||
import { useChannels } from '../channels/store'
|
||||
import { client, ESTATE } from '../data/origin'
|
||||
import { useModels } from '../data/config'
|
||||
import { useConvo } from '../data/convos'
|
||||
import { requireLogin } from '../data/gate'
|
||||
import { keys } from '../data/keys'
|
||||
import { useTurns } from '../data/messages'
|
||||
import { invalidate } from '../data/query'
|
||||
import * as store from '../data/store'
|
||||
import type { Message, Part } from '../data/types'
|
||||
import { InviteModal } from '../presence/InviteModal'
|
||||
import { Model } from '../settings/Model'
|
||||
import { pick } from '../settings/models'
|
||||
import { model as preferred, usePref } from '../settings/prefs'
|
||||
import { Header } from './Header'
|
||||
import { useFrame } from './Root'
|
||||
import { useTitle } from './title'
|
||||
import { TerminalPanel } from '../terminal/TerminalPanel'
|
||||
import { BrowseChannelsModal } from '../channels/BrowseChannelsModal'
|
||||
import { ShortcutsModal } from '../shortcuts/ShortcutsModal'
|
||||
import { ThemeModal } from '../theme/ThemeModal'
|
||||
import { ExportModal } from '../thread/ExportModal'
|
||||
import { Thread } from '../thread/Thread'
|
||||
import { SwarmBar } from '../agents/SwarmBar.tsx'
|
||||
import { ArtifactPanel } from '../artifact/ArtifactPanel.tsx'
|
||||
import { artifactStore } from '../artifact/store.ts'
|
||||
import { brand } from '../brand.ts'
|
||||
import { Compose } from '../compose/Compose.tsx'
|
||||
import { faulted, fold, opening, parts, spoken, stopped, type Part as Piece, type Reply } from '../compose/frames.ts'
|
||||
import { useHandoff } from '../compose/link.ts'
|
||||
import { run } from '../compose/stream.ts'
|
||||
import { history, type Conversation, type Payload } from '../compose/submit.ts'
|
||||
import { useChannels } from '../channels/store.ts'
|
||||
import { client, ESTATE } from '../data/origin.ts'
|
||||
import { useModels } from '../data/config.ts'
|
||||
import { useConvo } from '../data/convos.ts'
|
||||
import { requireLogin } from '../data/gate.ts'
|
||||
import { keys } from '../data/keys.ts'
|
||||
import { useTurns } from '../data/messages.ts'
|
||||
import { invalidate } from '../data/query.ts'
|
||||
import * as store from '../data/store.ts'
|
||||
import type { Message, Part } from '../data/types.ts'
|
||||
import { InviteModal } from '../presence/InviteModal.tsx'
|
||||
import { Model } from '../settings/Model.tsx'
|
||||
import { pick } from '../settings/models.ts'
|
||||
import { model as preferred, usePref } from '../settings/prefs.ts'
|
||||
import { Header } from './Header.tsx'
|
||||
import { useFrame } from './Root.tsx'
|
||||
import { useTitle } from './title.ts'
|
||||
import { TerminalPanel } from '../terminal/TerminalPanel.tsx'
|
||||
import { BrowseChannelsModal } from '../channels/BrowseChannelsModal.tsx'
|
||||
import { ShortcutsModal } from '../shortcuts/ShortcutsModal.tsx'
|
||||
import { ThemeModal } from '../theme/ThemeModal.tsx'
|
||||
import { ExportModal } from '../thread/ExportModal.tsx'
|
||||
import { Thread } from '../thread/Thread.tsx'
|
||||
|
||||
/**
|
||||
* One piece of a reply, in the wire's vocabulary.
|
||||
|
||||
+4
-4
@@ -12,10 +12,10 @@ import {
|
||||
} from '@hanzo/ui'
|
||||
import { useEffect, useState } from 'react'
|
||||
|
||||
import { api } from '../data/api'
|
||||
import { takePending, watchLogin, type Reason } from '../data/gate'
|
||||
import { MACHINE, origins } from '../data/origin'
|
||||
import { useSession } from '../data/session'
|
||||
import { api } from '../data/api.ts'
|
||||
import { takePending, watchLogin, type Reason } from '../data/gate.ts'
|
||||
import { MACHINE, origins } from '../data/origin.ts'
|
||||
import { useSession } from '../data/session.tsx'
|
||||
|
||||
/**
|
||||
* Where somebody ready to pay goes. No price is repeated here: the plans page
|
||||
|
||||
@@ -14,12 +14,12 @@ import {
|
||||
import { XStack } from '@hanzo/ui'
|
||||
import { useEffect, useState } from 'react'
|
||||
|
||||
import { PresenceStack } from '../presence/PresenceStack'
|
||||
import { artifactStore, useArtifact } from '../artifact/store'
|
||||
import { useChannels } from '../channels/store'
|
||||
import { exportStore } from '../thread/exportStore'
|
||||
import { shortcutsStore } from '../shortcuts/store'
|
||||
import { themeCustomizerStore } from '../theme/store'
|
||||
import { PresenceStack } from '../presence/PresenceStack.tsx'
|
||||
import { artifactStore, useArtifact } from '../artifact/store.ts'
|
||||
import { useChannels } from '../channels/store.ts'
|
||||
import { exportStore } from '../thread/exportStore.ts'
|
||||
import { shortcutsStore } from '../shortcuts/store.ts'
|
||||
import { themeCustomizerStore } from '../theme/store.ts'
|
||||
|
||||
export interface HeaderProps {
|
||||
title: string
|
||||
|
||||
+3
-3
@@ -2,9 +2,9 @@ import { Button, H2, Paragraph, YStack } from '@hanzo/ui'
|
||||
import { useEffect, useRef } from 'react'
|
||||
import { Navigate, useSearchParams } from 'react-router'
|
||||
|
||||
import { brand } from '../brand'
|
||||
import { useSession } from '../data/session'
|
||||
import { Waiting } from './Boundary'
|
||||
import { brand } from '../brand.ts'
|
||||
import { useSession } from '../data/session.tsx'
|
||||
import { Waiting } from './Boundary.tsx'
|
||||
|
||||
/**
|
||||
* Where a refusal sends somebody, and it is a DOOR rather than a page.
|
||||
|
||||
+14
-14
@@ -22,20 +22,20 @@ import {
|
||||
import { useCallback, useEffect, useMemo, useState } from 'react'
|
||||
import { useNavigate } from 'react-router'
|
||||
|
||||
import { swarmStore } from '../agents/store'
|
||||
import { artifactStore } from '../artifact/store'
|
||||
import { automationsStore } from '../automations/store'
|
||||
import { boardStore } from '../boards/store'
|
||||
import { channelsStore } from '../channels/store'
|
||||
import { api } from '../data/api'
|
||||
import { useSession } from '../data/session'
|
||||
import { intelligenceStore } from '../intelligence/store'
|
||||
import { mcpStore } from '../mcp/store'
|
||||
import { pluginsStore } from '../plugins/store'
|
||||
import { multiplayerStore } from '../presence/store'
|
||||
import { projectsStore } from '../projects/store'
|
||||
import { taskQueueStore } from '../tasks/store'
|
||||
import { terminalStore } from '../terminal/store'
|
||||
import { swarmStore } from '../agents/store.ts'
|
||||
import { artifactStore } from '../artifact/store.ts'
|
||||
import { automationsStore } from '../automations/store.ts'
|
||||
import { boardStore } from '../boards/store.ts'
|
||||
import { channelsStore } from '../channels/store.ts'
|
||||
import { api } from '../data/api.ts'
|
||||
import { useSession } from '../data/session.tsx'
|
||||
import { intelligenceStore } from '../intelligence/store.ts'
|
||||
import { mcpStore } from '../mcp/store.ts'
|
||||
import { pluginsStore } from '../plugins/store.ts'
|
||||
import { multiplayerStore } from '../presence/store.ts'
|
||||
import { projectsStore } from '../projects/store.ts'
|
||||
import { taskQueueStore } from '../tasks/store.ts'
|
||||
import { terminalStore } from '../terminal/store.ts'
|
||||
|
||||
export interface PaletteProps {
|
||||
onSettings: () => void
|
||||
|
||||
+25
-25
@@ -2,31 +2,31 @@ import { Screen, XStack, YStack } from '@hanzo/ui'
|
||||
import { useCallback, useMemo, useState } from 'react'
|
||||
import { Outlet, useMatch, useNavigate, useOutletContext } from 'react-router'
|
||||
|
||||
import { AgentBuilderModal } from '../agents/AgentBuilderModal'
|
||||
import { AgentsAndAppsModal } from '../agents/AgentsAndAppsModal'
|
||||
import { AutomationsModal } from '../automations/AutomationsModal'
|
||||
import { BoardModal } from '../boards/BoardModal'
|
||||
import { brand } from '../brand'
|
||||
import { api } from '../data/api'
|
||||
import { useModels } from '../data/config'
|
||||
import { useConvos } from '../data/convos'
|
||||
import { useSession } from '../data/session'
|
||||
import type { Convo } from '../data/types'
|
||||
import { useNarrow } from '../gui'
|
||||
import { McpModal } from '../mcp/McpModal'
|
||||
import { IntelligenceModal } from '../intelligence/IntelligenceModal'
|
||||
import { PluginsModal } from '../plugins/PluginsModal'
|
||||
import { ProjectModal } from '../projects/ProjectModal'
|
||||
import { Account } from '../rail/Account'
|
||||
import { id } from '../rail/group'
|
||||
import { Rail } from '../rail/Rail'
|
||||
import { Visitor } from '../rail/Visitor'
|
||||
import { Settings } from '../settings/Settings'
|
||||
import { Announce } from './Announce'
|
||||
import { Gate } from './Gate'
|
||||
import { Palette } from './Palette'
|
||||
import { Scene } from './Scene'
|
||||
import { TaskQueueModal } from '../tasks/TaskQueueModal'
|
||||
import { AgentBuilderModal } from '../agents/AgentBuilderModal.tsx'
|
||||
import { AgentsAndAppsModal } from '../agents/AgentsAndAppsModal.tsx'
|
||||
import { AutomationsModal } from '../automations/AutomationsModal.tsx'
|
||||
import { BoardModal } from '../boards/BoardModal.tsx'
|
||||
import { brand } from '../brand.ts'
|
||||
import { api } from '../data/api.ts'
|
||||
import { useModels } from '../data/config.ts'
|
||||
import { useConvos } from '../data/convos.ts'
|
||||
import { useSession } from '../data/session.tsx'
|
||||
import type { Convo } from '../data/types.ts'
|
||||
import { useNarrow } from '../gui.ts'
|
||||
import { McpModal } from '../mcp/McpModal.tsx'
|
||||
import { IntelligenceModal } from '../intelligence/IntelligenceModal.tsx'
|
||||
import { PluginsModal } from '../plugins/PluginsModal.tsx'
|
||||
import { ProjectModal } from '../projects/ProjectModal.tsx'
|
||||
import { Account } from '../rail/Account.tsx'
|
||||
import { id } from '../rail/group.ts'
|
||||
import { Rail } from '../rail/Rail.tsx'
|
||||
import { Visitor } from '../rail/Visitor.tsx'
|
||||
import { Settings } from '../settings/Settings.tsx'
|
||||
import { Announce } from './Announce.tsx'
|
||||
import { Gate } from './Gate.tsx'
|
||||
import { Palette } from './Palette.tsx'
|
||||
import { Scene } from './Scene.tsx'
|
||||
import { TaskQueueModal } from '../tasks/TaskQueueModal.tsx'
|
||||
|
||||
/**
|
||||
* What a screen inside the shell can reach.
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
import { View } from '@hanzo/ui'
|
||||
|
||||
import { brand } from '../brand'
|
||||
import { brand } from '../brand.ts'
|
||||
|
||||
/**
|
||||
* The immersive ground the whole product floats on.
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import { Anchor, Button, Checkbox, H2, Image, Label, Paragraph, XStack, YStack } from '@hanzo/ui'
|
||||
import { useState } from 'react'
|
||||
|
||||
import { brand } from '../brand'
|
||||
import { useSession } from '../data/session'
|
||||
import { consent, usePref } from '../settings/prefs'
|
||||
import { brand } from '../brand.ts'
|
||||
import { useSession } from '../data/session.tsx'
|
||||
import { consent, usePref } from '../settings/prefs.ts'
|
||||
|
||||
/**
|
||||
* What an installed app asks before it opens, and it asks once.
|
||||
|
||||
+1
-1
@@ -12,7 +12,7 @@
|
||||
*/
|
||||
import { useEffect } from 'react'
|
||||
|
||||
import { brand } from '../brand'
|
||||
import { brand } from '../brand.ts'
|
||||
|
||||
export const useTitle = (subject?: string | null) => {
|
||||
useEffect(() => {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { useEffect } from 'react'
|
||||
import { Keyboard, X } from '@hanzogui/lucide-icons-2'
|
||||
import { shortcutsStore, useShortcuts } from './store'
|
||||
import { shortcutsStore, useShortcuts } from './store.ts'
|
||||
|
||||
interface ShortcutItem {
|
||||
keys: string[]
|
||||
|
||||
@@ -11,10 +11,10 @@
|
||||
import { ListTodo, Pause, Play, Square, X } from '@hanzogui/lucide-icons-2'
|
||||
import { useState } from 'react'
|
||||
|
||||
import { useSession } from '../data/session'
|
||||
import { useSession } from '../data/session.tsx'
|
||||
|
||||
import { steer, useRun, useRuns } from './runs'
|
||||
import { taskQueueStore, useTaskQueue } from './store'
|
||||
import { steer, useRun, useRuns } from './runs.ts'
|
||||
import { taskQueueStore, useTaskQueue } from './store.ts'
|
||||
import type { Session, SessionEvent, SessionStatus } from '@hanzo/ai'
|
||||
|
||||
const badge = (status: SessionStatus | undefined) => {
|
||||
|
||||
+2
-2
@@ -18,8 +18,8 @@
|
||||
*/
|
||||
import type { Session, SessionCommand, SessionDetail } from '@hanzo/ai'
|
||||
|
||||
import { client, ESTATE } from '../data/origin'
|
||||
import { invalidate, useRead } from '../data/query'
|
||||
import { client, ESTATE } from '../data/origin.ts'
|
||||
import { invalidate, useRead } from '../data/query.ts'
|
||||
|
||||
const runs = ['runs'] as const
|
||||
const one = (id: string) => ['runs', 'one', id] as const
|
||||
|
||||
+1
-1
@@ -6,7 +6,7 @@
|
||||
* row is selected. Those are this browser's and nobody else's, so they are an
|
||||
* atom rather than a cache entry.
|
||||
*/
|
||||
import { atom, useAtom } from '../data/store'
|
||||
import { atom, useAtom } from '../data/store.ts'
|
||||
|
||||
export type Queue = {
|
||||
isOpen: boolean
|
||||
|
||||
@@ -11,8 +11,8 @@ import { SizableText, XStack, YStack } from '@hanzo/ui'
|
||||
import type { SandboxRuntime } from '@hanzo/ai'
|
||||
import { useEffect, useRef, useState, type CSSProperties, type FormEvent } from 'react'
|
||||
|
||||
import { sandbox, useLease, type Line } from './sandbox'
|
||||
import { terminalStore, useTerminal } from './store'
|
||||
import { sandbox, useLease, type Line } from './sandbox.ts'
|
||||
import { terminalStore, useTerminal } from './store.ts'
|
||||
|
||||
const ACTION: CSSProperties = {
|
||||
display: 'inline-flex',
|
||||
|
||||
@@ -19,8 +19,8 @@
|
||||
import { APIError, AuthError, type Leased, type Ran, type SandboxRuntime, type Wrote } from '@hanzo/ai'
|
||||
import { useEffect, useState } from 'react'
|
||||
|
||||
import { client, ESTATE } from '../data/origin'
|
||||
import { requireLogin } from '../data/gate'
|
||||
import { client, ESTATE } from '../data/origin.ts'
|
||||
import { requireLogin } from '../data/gate.ts'
|
||||
|
||||
/** `said` is what was typed; the rest is what the server answered. */
|
||||
export type Line = { kind: 'said' | 'out' | 'err' | 'note'; text: string }
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { useEffect } from 'react'
|
||||
import { Check, Palette, X } from '@hanzogui/lucide-icons-2'
|
||||
import { ACCENT_PALETTE, themeCustomizerStore, useThemeCustomizer } from './store'
|
||||
import { ACCENT_PALETTE, themeCustomizerStore, useThemeCustomizer } from './store.ts'
|
||||
|
||||
export const ThemeModal = () => {
|
||||
const { isOpen, accent, blurPx, glassOpacity } = useThemeCustomizer()
|
||||
|
||||
@@ -13,7 +13,7 @@ import { Pencil, RefreshCw, ThumbsDown, ThumbsUp } from '@hanzogui/lucide-icons-
|
||||
import { Button, XStack } from '@hanzo/ui'
|
||||
import { CopyButton, TooltipAnchor } from '@hanzo/ui/product'
|
||||
|
||||
import type { Vote } from './tree'
|
||||
import type { Vote } from './tree.ts'
|
||||
|
||||
export interface ActionsProps {
|
||||
/** The turn as text — what copy puts on the clipboard. */
|
||||
|
||||
@@ -11,10 +11,10 @@ import {
|
||||
import { useEffect, useState } from 'react'
|
||||
import { useNavigate } from 'react-router'
|
||||
|
||||
import { client, ESTATE } from '../data/origin'
|
||||
import * as store from '../data/store'
|
||||
import { useChannels } from '../channels/store'
|
||||
import { exportStore, useExport } from './exportStore'
|
||||
import { client, ESTATE } from '../data/origin.ts'
|
||||
import * as store from '../data/store.ts'
|
||||
import { useChannels } from '../channels/store.ts'
|
||||
import { exportStore, useExport } from './exportStore.ts'
|
||||
|
||||
export const ExportModal = () => {
|
||||
const navigate = useNavigate()
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
*/
|
||||
import { Sparkles } from '@hanzogui/lucide-icons-2'
|
||||
import { Code } from '@hanzo/ui/chat'
|
||||
import { artifactStore } from '../artifact/store'
|
||||
import { artifactStore } from '../artifact/store.ts'
|
||||
|
||||
export interface FenceProps {
|
||||
/** The word after the backticks. Shown in the label bar. */
|
||||
|
||||
@@ -8,8 +8,8 @@
|
||||
import { Paperclip } from '@hanzogui/lucide-icons-2'
|
||||
import { SizableText, XStack } from '@hanzo/ui'
|
||||
|
||||
import type { Attachment } from '../data/types'
|
||||
import { Picture } from './Picture'
|
||||
import type { Attachment } from '../data/types.ts'
|
||||
import { Picture } from './Picture.tsx'
|
||||
|
||||
const UNITS = ['B', 'KB', 'MB', 'GB']
|
||||
|
||||
|
||||
@@ -12,13 +12,13 @@
|
||||
*/
|
||||
import { Failure } from '@hanzo/ui/chat'
|
||||
|
||||
import type { Message, Part } from '../data/types'
|
||||
import { Files } from './Files'
|
||||
import { Picture } from './Picture'
|
||||
import { Prose } from './Prose'
|
||||
import { Think } from './Think'
|
||||
import { Tool } from './Tool'
|
||||
import { value } from './tree'
|
||||
import type { Message, Part } from '../data/types.ts'
|
||||
import { Files } from './Files.tsx'
|
||||
import { Picture } from './Picture.tsx'
|
||||
import { Prose } from './Prose.tsx'
|
||||
import { Think } from './Think.tsx'
|
||||
import { Tool } from './Tool.tsx'
|
||||
import { value } from './tree.ts'
|
||||
|
||||
const OOPS = 'Something went wrong.'
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
*/
|
||||
import { Paragraph, YStack } from '@hanzo/ui'
|
||||
|
||||
import { Markdown } from './markdown'
|
||||
import { Markdown } from './markdown.tsx'
|
||||
|
||||
export interface ProseProps {
|
||||
source: string
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
import { Step } from '@hanzo/ui/chat'
|
||||
import { useState } from 'react'
|
||||
|
||||
import { Prose } from './Prose'
|
||||
import { Prose } from './Prose.tsx'
|
||||
|
||||
export interface ThinkProps {
|
||||
text: string
|
||||
|
||||
@@ -22,9 +22,9 @@ import { Fill } from '@hanzo/ui'
|
||||
import { Thread as Scroll, type Source } from '@hanzo/ui/chat'
|
||||
import { useCallback, useMemo, useState, type ReactNode } from 'react'
|
||||
|
||||
import type { Message } from '../data/types'
|
||||
import { build, path, type Choice, type Chosen, type Entry, type Vote } from './tree'
|
||||
import { Turn } from './Turn'
|
||||
import type { Message } from '../data/types.ts'
|
||||
import { build, path, type Choice, type Chosen, type Entry, type Vote } from './tree.ts'
|
||||
import { Turn } from './Turn.tsx'
|
||||
|
||||
/**
|
||||
* The answer that has been asked for and has not started.
|
||||
|
||||
+2
-2
@@ -12,8 +12,8 @@
|
||||
import { Step, type Ran } from '@hanzo/ui/chat'
|
||||
import type { ReactNode } from 'react'
|
||||
|
||||
import type { ToolCall } from '../data/types'
|
||||
import { Fence } from './Fence'
|
||||
import type { ToolCall } from '../data/types.ts'
|
||||
import { Fence } from './Fence.tsx'
|
||||
|
||||
/** Tools whose name is machinery. Everything else reads fine as it arrives. */
|
||||
const NAMES: Record<string, string> = {
|
||||
|
||||
+6
-6
@@ -12,12 +12,12 @@
|
||||
*/
|
||||
import { Failure, Message, Sources, type Source } from '@hanzo/ui/chat'
|
||||
|
||||
import { Actions, acts, type ActionsProps } from './Actions'
|
||||
import { Cited } from './Cite'
|
||||
import { Edit } from './Edit'
|
||||
import { Parts } from './Parts'
|
||||
import { Siblings } from './Siblings'
|
||||
import { plain, type Choice, type Vote } from './tree'
|
||||
import { Actions, acts, type ActionsProps } from './Actions.tsx'
|
||||
import { Cited } from './Cite.tsx'
|
||||
import { Edit } from './Edit.tsx'
|
||||
import { Parts } from './Parts.tsx'
|
||||
import { Siblings } from './Siblings.tsx'
|
||||
import { plain, type Choice, type Vote } from './tree.ts'
|
||||
|
||||
const OOPS = 'Something went wrong.'
|
||||
|
||||
|
||||
@@ -45,8 +45,8 @@ import ReactMarkdown from 'react-markdown'
|
||||
import type { Components } from 'react-markdown'
|
||||
import remarkGfm from 'remark-gfm'
|
||||
|
||||
import { Cite } from './Cite'
|
||||
import { Fence } from './Fence'
|
||||
import { Cite } from './Cite.tsx'
|
||||
import { Fence } from './Fence.tsx'
|
||||
|
||||
/**
|
||||
* The anchor a model writes beside a claim — U+E202 then `turn0search1`, in the
|
||||
|
||||
+1
-1
@@ -22,7 +22,7 @@
|
||||
*/
|
||||
import type { Source } from '@hanzo/ui/chat'
|
||||
|
||||
import type { Feedback, Message } from '../data/types'
|
||||
import type { Feedback, Message } from '../data/types.ts'
|
||||
|
||||
/** A thumbs-up or thumbs-down on an answer. */
|
||||
export type Vote = Feedback['rating']
|
||||
|
||||
+4
-1
@@ -8,7 +8,10 @@
|
||||
"noEmit": false,
|
||||
"declaration": true,
|
||||
"declarationMap": true,
|
||||
"allowImportingTsExtensions": false,
|
||||
// Source names the file it means, so `node --test` can run it straight; on
|
||||
// emit the same specifier becomes the `.js` beside it, which is the only
|
||||
// spelling Node resolves in a package.
|
||||
"rewriteRelativeImportExtensions": true,
|
||||
"outDir": "dist",
|
||||
"rootDir": "src"
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user