KQ-1341 · AI/WORKSPACE

AI Workspace

A whole assistant screen built from thread-view, prompt-dock and pin-press: a dated, searchable conversation sidebar, a thread whose replies stream in word by word while Send folds into Stop, and an artifact the reply writes line by line in a pane that slides in beside the thread on glide, its column and the thread's edge one motion value, each new line rising 4px on glide; split, overlay and canvas set how the pane arrives, a split divider follows the pointer 1:1 and settles on glide, and pinned conversations glide to the top. Below 640px it becomes a stack of conversations, thread and artifact pushed on glide with the screen beneath shifting and dimming. The sidebar is a roving list (arrows, Home, End), the divider a separator the arrow keys move, Preview and Source a tablist, and Escape closes the pane or goes back.

KQ-1341 · AI/WORKSPACE
Fieldline
Rae OkaforFieldline · Team plan

Payout cut-off policy

Fernworks Model 3
  1. Rae Okafor, 52 min ago:

    Draft a cut-off policy for Waylight Pay payouts. Batches approved after 16:00 should roll to the next working day.

  2. Fernworks Model 3, 51 min ago:

    Here is a first version beside this thread. It sets the 16:00 cut-off, says what happens on weekends and bank holidays, and who can push a late batch through.

  3. Rae Okafor, 21 min ago:

    Add how payees hear about a rolled batch.

  4. Fernworks Model 3, 20 min ago:

    Added a section on telling payees:

    • an email the moment their batch rolls, with the new date
    • the rolled date and the reason on the batch page

4520 of 8000 tokens.

payout cut-off policy · 7 conversations

Install

One command — the source lands in your repo. Or copy it from the Code tab.

$ pnpm dlx shadcn@latest add @kinetiq/ai-workspace

Props

density
"compact" | "cozy" | "roomy"
default "cozy"
How tightly the thread and the sidebar are set: passed to the thread, and the sidebar's rows follow.
pane
"split" | "overlay" | "canvas"
default "split"
How the artifact arrives: a column sharing the stage with the thread (with a draggable divider, the sidebar folding when the three cannot fit), a sheet sliding over the thread's edge, or a canvas that gives the artifact the stage.
theme
"page" | "light" | "dark"
default "page"
Wear the page's theme, or force light or dark inside the workspace.
conversations / defaultConversations
AiConversation[]
default defaultAiConversations
Every conversation: a title, its thread-view messages, whether it is pinned, and the latest artifact it produced. Controlled or uncontrolled.
onConversationsChange
(conversations: AiConversation[]) => void
default —
Fires from the send, stream, pin, edit or reaction that changed them, with all of them. A streamed reply is reported whole when it starts and again when it finishes.
conversation / defaultConversation
string
default the first conversation
The open conversation's id. Controlled or uncontrolled.
onConversationChange
(id: string) => void
default —
Fires from the row, New chat or key that opened another conversation.
artifactOpen / defaultArtifactOpen
boolean
default false
Whether the artifact pane is open. Controlled or uncontrolled.
onArtifactOpenChange
(open: boolean) => void
default —
Fires from the strip, the Artifact button, Close, Escape, or a reply that started writing an artifact.
respond
(prompt: string, conversation: AiConversation) => AiReply | Promise<AiReply>
default defaultAiRespond
Answers a prompt with text and, optionally, an artifact. A promise shows the reply thinking until it settles; a rejection shows it failed, with Retry.
onSend
(text: string, conversationId: string) => void
default —
A prompt was sent, from the dock or by editing a sent turn.
onStop
(conversationId: string) => void
default —
Stop, or Escape in the dock, cut a reply short where it stood.
onCopy
(text: string, artifact: AiArtifact) => void
default —
The artifact was copied.
models
DockModel[]
default defaultModels
The models the dock's pill switches between.
model
string
default the first model
The selected model's id; its name signs replies and heads the thread.
onModelChange
(id: string) => void
default —
The visitor switched models in the dock.
user
{ name: string; plan?: string }
default { name: "Rae Okafor", plan: "Team plan" }
Who is signed in, at the foot of the sidebar; prompts are sent under this name.
workspace
string
default "Fieldline"
The workspace's name, at the head of the sidebar.
now
Date | number
default defaultAiNow
The moment the sidebar's groups (Today, Yesterday, Previous 7 days) and times count from, so server and browser agree.
stream
number
default 240
How fast a reply streams in, in characters a second.
status
"ready" | "loading" | "error"
default "ready"
Whether the conversations have arrived: loading draws placeholders, error offers Try again.
onRetry
() => void
default —
Try again was pressed after the conversations failed to load.
label
string
default "Assistant"
The screen's accessible name.
sound
boolean
default false
Play the ticks and the pane's swish, only for the visitor's own actions. The composed pieces play theirs too.
disabled
boolean
default false
Read only: nothing can be sent, pinned or opened.
className
string
default —
Classes for the root. It is 560px tall by default; pass a height class to change it.