@arbidocs/tui 0.3.68 → 0.3.70
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/index.js +28 -2
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/tui-helpers.ts","../src/theme/theme.ts","../src/theme/syntax-theme.ts","../src/components/assistant-message.ts","../src/components/user-message.ts","../src/components/system-message.ts","../src/components/right-aligned-text.ts","../src/components/agent-step.ts","../src/components/chat-log.ts","../src/event-log.ts","../src/sources-index.ts","../src/components/arbi-editor.ts","../src/components/toast-container.ts","../src/command-registry.ts","../src/commands/general.ts","../src/prompts.ts","../src/auth.ts","../src/commands/auth.ts","../src/commands/workspace.ts","../src/commands/document.ts","../src/commands/conversation.ts","../src/commands/tag.ts","../src/commands/misc.ts","../src/components/citation-panel.ts","../src/commands/citation.ts","../src/commands/events.ts","../src/commands/view.ts","../src/commands/sources.ts","../src/commands/history.ts","../src/commands/skills.ts","../src/commands/index.ts","../src/event-handlers.ts","../src/dm-handler.ts","../src/ws-handler.ts","../src/tui.ts","../src/index.ts"],"names":["selectWorkspaceById","getErrorMessage","resolveWorkspace","chalk","Container","Text","Markdown","visibleWidth","Spacer","resolveCitations","Editor","matchesKey","Key","input","parseSlashCommand","select","password","confirm","performPasswordLogin","createArbiClient","workspaces","formatWorkspaceChoices","projects","generateNewWorkspaceKey","resolveAuth","ws","formatUserName","documents","documentsNode","conversations","tags","contacts","showMessage","health","settings","Box","countCitations","summarizeCitations","DEFAULT_LIMIT","assistant","mkdtempSync","join","tmpdir","path","writeFileSync","statSync","spawnSync","readFileSync","rmSync","formatAgentStepLabel","streamSSE","formatStreamSummary","base64ToBytes","deriveEncryptionKeypairFromSigning","dm","encryptMessage","decryptMessage","formatWsMessage","connectWithReconnect","TUI","ProcessTerminal","CombinedAutocompleteProvider","Command","FileConfigStore"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * Shared TUI helpers — eliminates repeated boilerplate across command handlers.\n *\n * - requireAuth(): guard that checks authentication\n * - showMessage(): addSystem + requestRender in one call\n * - switchWorkspace(): workspace selection + state update\n * - runInteractiveFlow(): pause TUI → run action → restart TUI\n */\n\nimport { getErrorMessage, selectWorkspaceById, resolveWorkspace } from '@arbidocs/sdk'\nimport type { ArbiTui } from './tui.js'\nimport type { SystemMessageLevel } from './components/system-message.js'\n\n/**\n * Guard: check that the user is authenticated.\n * Returns true if auth context is present, otherwise shows an error and returns false.\n */\nexport function requireAuth(\n tui: ArbiTui,\n message = 'Not authenticated. Use /login first.'\n): boolean {\n if (tui.authContext) return true\n showMessage(tui, message, 'error')\n return false\n}\n\n/**\n * Display a system message and request a render in one call.\n */\nexport function showMessage(tui: ArbiTui, message: string, level?: SystemMessageLevel): void {\n tui.chatLog.addSystem(message, level)\n tui.requestRender()\n}\n\n/**\n * Switch to a workspace by ID — selects it, updates TUI state, persists config.\n * Returns the workspace info on success, or null on failure.\n */\nexport async function switchWorkspace(\n tui: ArbiTui,\n workspaceId: string\n): Promise<{ external_id: string; name: string } | null> {\n if (!tui.authContext) return null\n\n try {\n const ws = await selectWorkspaceById(\n tui.authContext.arbi,\n workspaceId,\n tui.authContext.loginResult.serverSessionKey,\n tui.store.requireCredentials().signingPrivateKeyBase64\n )\n\n tui.state.workspaceId = ws.external_id\n tui.state.workspaceName = ws.name\n tui.state.conversationMessageId = null\n tui.store.clearChatSession()\n tui.store.updateConfig({ selectedWorkspaceId: ws.external_id })\n await tui.refreshWorkspaceContext()\n\n return ws\n } catch (err) {\n showMessage(tui, `Failed to switch workspace: ${getErrorMessage(err)}`, 'error')\n return null\n }\n}\n\n/**\n * Set up workspace context after login/register when a workspace was auto-selected.\n */\nexport async function applyWorkspaceSelection(\n tui: ArbiTui,\n workspaceId?: string,\n workspaceName?: string | null\n): Promise<void> {\n if (!workspaceId) return\n const wsCtx = await resolveWorkspace(tui.store, workspaceId)\n tui.setWorkspaceContext(wsCtx)\n tui.state.workspaceName = workspaceName ?? null\n}\n\n/**\n * Run an interactive flow that requires stdin (login, register).\n * Stops the TUI, runs the action, restarts the TUI, and handles errors.\n * Returns the action result on success, or null on failure.\n */\nexport async function runInteractiveFlow<T>(\n tui: ArbiTui,\n pauseMessage: string,\n action: () => Promise<T>,\n errorPrefix: string\n): Promise<T | null> {\n showMessage(tui, pauseMessage)\n tui.stopTui()\n\n try {\n const result = await action()\n tui.restartTui()\n return result\n } catch (err) {\n tui.restartTui()\n showMessage(tui, `${errorPrefix}: ${getErrorMessage(err)}`, 'error')\n return null\n }\n}\n","/**\n * ARBI TUI theme — color palette and component styling functions.\n *\n * Uses chalk for ANSI color output. All theme values are functions\n * that wrap text in the appropriate escape sequences.\n */\n\nimport chalk from 'chalk'\nimport type { MarkdownTheme, EditorTheme, SelectListTheme } from '@mariozechner/pi-tui'\n\n// ── Color palette ──────────────────────────────────────────────────────────\n\nexport const colors = {\n /** Primary accent — teal/cyan used for headings, prompts, highlights */\n accent: chalk.cyan,\n accentBold: chalk.bold.cyan,\n\n /** Secondary accent — blue for links and info */\n secondary: chalk.blue,\n\n /** Muted text — dim gray for borders, metadata */\n muted: chalk.gray,\n mutedDim: chalk.dim.gray,\n\n /** Success — green for completed states */\n success: chalk.green,\n\n /** Warning — yellow for pending states, code */\n warning: chalk.yellow,\n\n /** Error — red for error messages */\n error: chalk.red,\n errorBold: chalk.bold.red,\n\n /** Text — default and bold */\n text: chalk.white,\n textBold: chalk.bold.white,\n\n /** User message styling */\n userLabel: chalk.bold.green,\n userText: chalk.white,\n\n /** Assistant message styling */\n assistantLabel: chalk.bold.cyan,\n\n /** System message styling */\n systemText: chalk.dim,\n systemInfo: chalk.dim.cyan,\n systemError: chalk.dim.red,\n systemWarning: chalk.dim.yellow,\n\n /** Agent step styling */\n stepPending: chalk.dim.yellow,\n stepComplete: chalk.dim.green,\n} as const\n\n// ── Background functions ───────────────────────────────────────────────────\n\nexport const bgFn = {\n /** Subtle background for user messages */\n user: (text: string) => chalk.bgGray(text),\n\n /** Background for agent steps */\n agentStep: (text: string) => text,\n} as const\n\n// ── Component themes ───────────────────────────────────────────────────────\n\nexport const selectListTheme: SelectListTheme = {\n selectedPrefix: (s: string) => colors.accent(s),\n selectedText: (s: string) => colors.text(s),\n description: (s: string) => colors.muted(s),\n scrollInfo: (s: string) => colors.muted(s),\n noMatch: (s: string) => colors.muted(s),\n}\n\nexport const editorTheme: EditorTheme = {\n borderColor: (s: string) => colors.accent(s),\n selectList: selectListTheme,\n}\n\nexport const markdownTheme: MarkdownTheme = {\n heading: (s: string) => colors.accentBold(s),\n link: (s: string) => chalk.underline.blue(s),\n linkUrl: (s: string) => colors.muted(s),\n code: (s: string) => colors.warning(s),\n codeBlock: (s: string) => colors.text(s),\n codeBlockBorder: (s: string) => colors.muted(s),\n quote: (s: string) => chalk.italic.gray(s),\n quoteBorder: (s: string) => colors.muted(s),\n hr: (s: string) => colors.muted(s),\n listBullet: (s: string) => colors.accent(s),\n bold: (s: string) => chalk.bold(s),\n italic: (s: string) => chalk.italic(s),\n strikethrough: (s: string) => chalk.strikethrough(s),\n underline: (s: string) => chalk.underline(s),\n}\n\n// ── Header / Footer helpers ────────────────────────────────────────────────\n\nexport function formatHeader(workspaceName: string | null, status: string): string {\n const app = colors.accentBold('ARBI')\n const ws = workspaceName ? colors.muted(` | ${workspaceName}`) : ''\n const st = colors.muted(` | ${status}`)\n return `${app}${ws}${st}`\n}\n\nexport function formatPrompt(): string {\n return colors.accent('> ')\n}\n","/**\n * Syntax highlighting theme for code blocks in Markdown.\n *\n * Provides a highlightCode function compatible with pi-tui's\n * MarkdownTheme.highlightCode option.\n */\n\nimport chalk from 'chalk'\n\n/**\n * Simple keyword-based syntax highlighting for code blocks.\n * Returns an array of styled lines.\n *\n * For a first version, we apply basic keyword coloring. This can be\n * upgraded to use a proper highlighter (e.g., cli-highlight) later.\n */\n// eslint-disable-next-line @typescript-eslint/no-unused-vars\nexport function highlightCode(code: string, lang?: string): string[] {\n const lines = code.split('\\n')\n\n return lines.map((line) => {\n // Highlight common keywords\n let styled = line\n // String literals (double and single quoted)\n .replace(/([\"'])(?:(?=(\\\\?))\\2.)*?\\1/g, (m) => chalk.green(m))\n // Numbers\n .replace(/\\b(\\d+\\.?\\d*)\\b/g, (m) => chalk.yellow(m))\n // Comments (// and #)\n .replace(/(\\/\\/.*|#.*)$/g, (m) => chalk.gray(m))\n\n // Keywords (applied after strings/comments to avoid conflicts in simple cases)\n const keywords =\n /\\b(const|let|var|function|return|if|else|for|while|import|export|from|class|extends|new|async|await|try|catch|throw|type|interface|enum|def|self|None|True|False|print)\\b/g\n styled = styled.replace(keywords, (m) => chalk.cyan(m))\n\n return styled\n })\n}\n","/**\n * AssistantMessage — streaming markdown response from the RAG assistant.\n *\n * Wraps pi-tui's Markdown component. Call setText() as tokens arrive\n * to update the rendered content incrementally.\n */\n\nimport { Container, Markdown, Text } from '@mariozechner/pi-tui'\nimport { markdownTheme, colors } from '../theme/theme.js'\nimport { highlightCode } from '../theme/syntax-theme.js'\n\nconst assistantMarkdownTheme = {\n ...markdownTheme,\n highlightCode,\n}\n\nexport class AssistantMessage extends Container {\n private markdown: Markdown\n private label: Text\n\n constructor() {\n super()\n this.label = new Text(colors.assistantLabel('ARBI'), 1, 0)\n this.markdown = new Markdown('', 1, 0, assistantMarkdownTheme)\n this.addChild(this.label)\n this.addChild(this.markdown)\n }\n\n /** Update the response text (called as tokens stream in). */\n setText(text: string): void {\n this.markdown.setText(text)\n }\n}\n","/**\n * UserMessage — displays a user's submitted question.\n *\n * Wraps pi-tui's Markdown component with user-specific styling.\n */\n\nimport { Container, Markdown, Text } from '@mariozechner/pi-tui'\nimport { markdownTheme, colors } from '../theme/theme.js'\n\nexport class UserMessage extends Container {\n constructor(text: string) {\n super()\n const label = new Text(colors.userLabel('You'), 1, 0)\n const content = new Markdown(text, 1, 0, markdownTheme)\n this.addChild(label)\n this.addChild(content)\n }\n}\n","/**\n * SystemMessage — info, warning, and error messages.\n *\n * Wraps pi-tui's Text component with dim/accent styling.\n */\n\nimport { Text } from '@mariozechner/pi-tui'\nimport { colors } from '../theme/theme.js'\n\nexport type SystemMessageLevel = 'info' | 'warning' | 'error'\n\nexport class SystemMessage extends Text {\n constructor(message: string, level: SystemMessageLevel = 'info') {\n const styleFn =\n level === 'error'\n ? colors.systemError\n : level === 'warning'\n ? colors.systemWarning\n : colors.systemInfo\n super(styleFn(message), 1, 0)\n }\n}\n","/**\n * RightAlignedText — single-line text component that renders right-aligned.\n *\n * Used for stream summary lines (token counts, timing) that should\n * appear flush-right, matching the CLI's right-aligned summary style.\n */\n\nimport { visibleWidth } from '@mariozechner/pi-tui'\n\nexport class RightAlignedText {\n private text: string\n private styleFn: (s: string) => string\n\n constructor(text: string, styleFn: (s: string) => string) {\n this.text = text\n this.styleFn = styleFn\n }\n\n invalidate(): void {\n // No cache to invalidate\n }\n\n render(width: number): string[] {\n if (!this.text || this.text.trim() === '') return []\n\n const styled = this.styleFn(this.text)\n const textWidth = visibleWidth(styled)\n const padding = Math.max(0, width - textWidth)\n return [' '.repeat(padding) + styled]\n }\n}\n","/**\n * AgentStep — displays a single agent processing step.\n *\n * Two render modes:\n *\n * - **Flat**: ``> label`` — the original behaviour, used when the\n * step has no extra context (e.g. lifecycle \"Planning\", \"Generating\n * answer\").\n *\n * - **Structured**: ``▸ label`` followed by indented secondary\n * lines for ``tool``, ``args``, and ``result`` summaries. Matches\n * the claude-code rendering of tool-use blocks where the\n * invocation header sits flush-left and the arguments / output\n * hang underneath at a fixed indent.\n *\n * The class still extends ``Text`` from pi-tui, so it's still a\n * single block in the chat log — pi-tui handles wrapping. Future\n * work could swap to a ``Container`` for keyboard-focusable collapse\n * (claude-code's ``Tab`` / ``Enter`` cycling); the data model is\n * already shaped for that.\n */\n\nimport { Text } from '@mariozechner/pi-tui'\nimport { colors } from '../theme/theme.js'\n\n/** Optional structured context for an agent step. All fields are\n * short single-line summaries — the renderer doesn't try to pretty-\n * print JSON or wrap long results, that's the caller's job. */\nexport interface AgentStepDetails {\n /** Tool the step is invoking, when applicable. */\n tool?: string\n /** One-line summary of the inputs (e.g. ``query: \"what...?\"``). */\n args?: string\n /** One-line summary of the outputs (e.g. ``→ 5 chunks from 3 docs``). */\n result?: string\n}\n\n/** Pick a glyph for the step header. ASCII fallbacks live alongside\n * the UTF-8 versions in case a terminal doesn't render the latter\n * cleanly. Kept here, not in ``theme``, because the glyph IS the\n * semantic (\"tool\" vs \"lifecycle\" vs \"complete\"). */\nconst GLYPH_LIFECYCLE = '>'\nconst GLYPH_TOOL = '▸'\nconst GLYPH_RESULT = '→'\n\nexport class AgentStep extends Text {\n private completed = false\n\n constructor(label: string, details?: AgentStepDetails) {\n super(buildText(label, details), 2, 0)\n }\n\n /** Mark this step as completed. Renderer is unchanged for now —\n * see the file-header comment for the planned focusable-collapse\n * upgrade path. */\n complete(): void {\n if (this.completed) return\n this.completed = true\n }\n}\n\n/** Render the multi-line text body for the step. Pulled out so the\n * shape is testable without instantiating ``Text`` (which needs\n * pi-tui internals). */\nexport function buildText(label: string, details?: AgentStepDetails): string {\n const hasDetails = !!(details?.tool || details?.args || details?.result)\n const glyph = hasDetails ? GLYPH_TOOL : GLYPH_LIFECYCLE\n const header = `${colors.stepPending(glyph)} ${hasDetails ? colors.accent(label) : colors.muted(label)}`\n\n if (!hasDetails) return header\n\n const lines: string[] = [header]\n // Two-space indent so the sub-lines visually hang from the header.\n // Mirrors claude-code's tool-call expansion layout.\n if (details?.tool && details.tool !== label) {\n lines.push(` ${colors.muted('tool:')} ${details.tool}`)\n }\n if (details?.args) {\n lines.push(` ${colors.muted('args:')} ${details.args}`)\n }\n if (details?.result) {\n lines.push(` ${colors.muted(GLYPH_RESULT)} ${details.result}`)\n }\n return lines.join('\\n')\n}\n","/**\n * ChatLog — container managing the message list and streaming runs.\n *\n * Provides methods for adding user/system messages and managing\n * assistant streaming lifecycle (start → update → finalize).\n */\n\nimport { Container, Spacer, Text } from '@mariozechner/pi-tui'\nimport { AssistantMessage } from './assistant-message.js'\nimport { UserMessage } from './user-message.js'\nimport { SystemMessage, type SystemMessageLevel } from './system-message.js'\nimport { RightAlignedText } from './right-aligned-text.js'\nimport { AgentStep, type AgentStepDetails } from './agent-step.js'\nimport { colors } from '../theme/theme.js'\n\nexport class ChatLog extends Container {\n /** Currently streaming assistant message (null when idle). */\n private activeAssistant: AssistantMessage | null = null\n\n /** Agent steps associated with the current streaming run. */\n private activeSteps: AgentStep[] = []\n\n /** Add a user message to the log. */\n addUser(text: string): void {\n this.addChild(new UserMessage(text))\n this.addChild(new Spacer(1))\n }\n\n /** Add a complete assistant message (non-streaming, e.g. for history restoration). */\n addAssistant(text: string): void {\n const msg = new AssistantMessage()\n msg.setText(text)\n this.addChild(msg)\n this.addChild(new Spacer(1))\n }\n\n /** Add a system/info/error message. */\n addSystem(message: string, level: SystemMessageLevel = 'info'): void {\n this.addChild(new SystemMessage(message, level))\n this.addChild(new Spacer(1))\n }\n\n /** Add a right-aligned summary line (e.g. stream stats). */\n addSummary(text: string): void {\n this.addChild(new RightAlignedText(text, colors.systemInfo))\n this.addChild(new Spacer(1))\n }\n\n /** Add a received DM message (cyan label with sender email). */\n addDm(senderEmail: string, text: string): void {\n const container = new Container()\n const label = new Text(colors.accent(senderEmail), 1, 0)\n const content = new Text(colors.text(text), 1, 0)\n container.addChild(label)\n container.addChild(content)\n this.addChild(container)\n this.addChild(new Spacer(1))\n }\n\n /** Remove all messages from the chat log. */\n clearMessages(): void {\n this.activeAssistant = null\n this.activeSteps = []\n // Remove all children by iterating backwards\n while (this.children.length > 0) {\n this.removeChild(this.children[this.children.length - 1])\n }\n }\n\n /** Start a new assistant streaming response. */\n startAssistant(): void {\n this.activeAssistant = new AssistantMessage()\n this.activeSteps = []\n this.addChild(this.activeAssistant)\n }\n\n /** Update the active assistant message with accumulated text. */\n updateAssistant(text: string): void {\n this.activeAssistant?.setText(text)\n }\n\n /** Add an agent step to the current streaming run. Optional\n * ``details`` enriches the rendered block with ``tool`` / ``args``\n * / ``result`` lines beneath the header — claude-code-style\n * tool-use expansion. Callers that don't have structured detail\n * can omit the second arg and get the original flat behaviour. */\n addAgentStep(label: string, details?: AgentStepDetails): void {\n if (!this.activeAssistant) return\n const step = new AgentStep(label, details)\n this.activeSteps.push(step)\n // Insert step before the assistant message content\n this.addChild(step)\n }\n\n /** Remove all active agent steps from the chat log (e.g. when streaming starts). */\n clearActiveSteps(): void {\n for (const step of this.activeSteps) {\n this.removeChild(step)\n }\n this.activeSteps = []\n }\n\n /** Finalize the current assistant response. */\n finalizeAssistant(): void {\n this.clearActiveSteps()\n this.activeAssistant = null\n this.addChild(new Spacer(1))\n }\n}\n","/**\n * WsEventLog — persistent ring buffer of WebSocket events.\n *\n * Sits alongside the ephemeral ``ToastContainer``. Toasts are great\n * for \"did something just happen?\" — they disappear in 3–8s. But the\n * common gap with the previous setup was answering \"what happened\n * during this session?\": upload progress, doc parsing milestones,\n * presence updates, errors. The log captures every WS event for the\n * lifetime of the session so ``/events`` can replay them.\n *\n * Inspired by claude-code's persistent tool-call timeline and\n * openclaw's per-session event log. Bounded so a long session can't\n * leak memory — kept at the most-recent ``capacity`` entries.\n */\n\nexport type WsEventLevel = 'info' | 'success' | 'warning' | 'error'\n\nexport interface WsEventEntry {\n /** Wall-clock time the event was observed by the TUI. */\n at: Date\n /** Pre-formatted, user-facing one-liner (from ``formatWsMessage``\n * or, for transport status events, a fixed string). */\n text: string\n /** Severity — drives both colouring in ``/events`` and the\n * toast-suppression policy in ``ws-handler``. */\n level: WsEventLevel\n /** The raw message ``type`` (when known) so callers can filter\n * ``/events --type task_update`` without re-parsing the text. */\n msgType?: string\n}\n\nexport class WsEventLog {\n private readonly entries: WsEventEntry[] = []\n private readonly capacity: number\n\n /** ``capacity`` defaults to 200, the same order-of-magnitude as\n * a typical long chat session. Old entries roll off when the\n * buffer fills — same shape as openclaw's session log. */\n constructor(capacity = 200) {\n this.capacity = capacity\n }\n\n /** Append a new entry. Drops the oldest if at capacity. */\n add(entry: Omit<WsEventEntry, 'at'> & { at?: Date }): void {\n this.entries.push({\n at: entry.at ?? new Date(),\n text: entry.text,\n level: entry.level,\n msgType: entry.msgType,\n })\n while (this.entries.length > this.capacity) this.entries.shift()\n }\n\n /** Read the last ``limit`` entries (most recent last). Optionally\n * filter by level — useful for ``/events --errors``. */\n getAll(options?: { limit?: number; level?: WsEventLevel }): WsEventEntry[] {\n let view: WsEventEntry[] = this.entries\n if (options?.level) view = view.filter((e) => e.level === options.level)\n if (options?.limit != null) view = view.slice(-options.limit)\n return view\n }\n\n /** Number of entries currently retained (after eviction). */\n get size(): number {\n return this.entries.length\n }\n}\n\n/** Format an entry as a single line for the chat-log dump that\n * ``/events`` uses. Kept separate from ``WsEventLog`` itself so the\n * data layer stays free of presentation choices (colour, padding). */\nexport function formatEventLine(entry: WsEventEntry): string {\n const h = String(entry.at.getHours()).padStart(2, '0')\n const m = String(entry.at.getMinutes()).padStart(2, '0')\n const s = String(entry.at.getSeconds()).padStart(2, '0')\n const tag = entry.level.padEnd(7) // longest = \"warning\"\n return `[${h}:${m}:${s}] ${tag} ${entry.text}`\n}\n","/**\n * SourcesIndex — running tally of documents referenced by the\n * current conversation, accumulated across multiple turns.\n *\n * The TUI's chat log is linear and scrolls, so users lose track of\n * which documents have backed up the conversation so far. This\n * index is the \"what's in play?\" data that powers ``/sources`` —\n * and, eventually, a persistent right-side sidebar (the Codex /\n * VS-Code pattern). Building the data layer first lets us ship\n * ``/sources`` today and promote it to a layout component when the\n * pi-tui side-by-side primitives are wired up.\n *\n * Reset on ``/new`` so each conversation starts with a clean slate.\n */\n\nimport { resolveCitations, type MessageMetadataPayload, type ResolvedCitation } from '@arbidocs/sdk'\n\nexport interface SourceEntry {\n /** Document external ID (e.g. ``doc-abc123``). */\n docId: string\n /** Best-known display title (parsed metadata title or file name). */\n title: string\n /** Page numbers cited on this doc, sorted ascending. */\n pages: number[]\n /** Citation indices ([1], [2], …) that point at this doc, sorted. */\n citationNums: string[]\n}\n\nexport class SourcesIndex {\n // Keyed by docId so successive turns add to the same entry rather\n // than duplicating it.\n private readonly entries = new Map<string, SourceEntry>()\n\n /** Fold every citation in ``metadata`` into the index. Idempotent\n * on the same payload — adding the same metadata twice doesn't\n * inflate counts. */\n recordCitations(metadata: MessageMetadataPayload | null | undefined): void {\n if (!metadata) return\n this.recordResolved(resolveCitations(metadata))\n }\n\n /** The underlying fold step, separated so tests can drive it with\n * hand-rolled ``ResolvedCitation`` fixtures rather than mocking\n * the full ``MessageMetadataPayload.tools.*`` graph that\n * ``resolveCitations`` traverses. */\n recordResolved(resolved: ResolvedCitation[]): void {\n for (const c of resolved) {\n for (const chunk of c.chunks) {\n const docId = chunk.metadata?.doc_ext_id\n if (!docId) continue\n const title = (chunk.metadata?.doc_title as string | undefined) ?? docId\n const page = chunk.metadata?.page_number\n const existing = this.entries.get(docId)\n if (existing) {\n if (typeof page === 'number' && !existing.pages.includes(page)) {\n existing.pages.push(page)\n existing.pages.sort((a, b) => a - b)\n }\n if (!existing.citationNums.includes(c.citationNum)) {\n existing.citationNums.push(c.citationNum)\n existing.citationNums.sort()\n }\n // Title may be missing on early chunks; upgrade if a later\n // chunk has a better one.\n if (existing.title === docId && title !== docId) existing.title = title\n } else {\n this.entries.set(docId, {\n docId,\n title,\n pages: typeof page === 'number' ? [page] : [],\n citationNums: [c.citationNum],\n })\n }\n }\n }\n }\n\n /** All entries in registration order — first-cited first. The\n * iterator order of ``Map`` is insertion order, which is what\n * we want for ``/sources`` (oldest at top, newest at bottom). */\n list(): SourceEntry[] {\n return Array.from(this.entries.values())\n }\n\n /** Clear the index. Wired to ``/new`` so a fresh conversation\n * starts with no inherited sources. */\n clear(): void {\n this.entries.clear()\n }\n\n /** Number of unique documents tracked. */\n get size(): number {\n return this.entries.size\n }\n}\n","/**\n * ArbiEditor — custom Editor with ARBI-specific keybindings.\n *\n * Extends pi-tui's Editor to add:\n * - Escape → abort active stream\n * - Ctrl+C → clear input / double-tap to exit\n * - Ctrl+D → exit\n * - Ctrl+W → workspace selector\n * - Ctrl+N → new conversation\n * - Alt+1..9 → jump straight to citation N from the last response.\n * (Ctrl+digit doesn't have a reliable terminal encoding, but Alt+\n * digit sends ``ESC <n>`` which pi-tui can match cleanly. Picked\n * because none of the editor's text-entry paths use Alt — typing\n * ``1`` still inserts a literal ``1``.)\n */\n\nimport { Editor, matchesKey, Key, type TUI } from '@mariozechner/pi-tui'\nimport { editorTheme } from '../theme/theme.js'\n\nexport class ArbiEditor extends Editor {\n /** Callback when Escape is pressed (abort streaming). */\n onEscape?: () => void\n\n /** Callback when Ctrl+C is pressed (clear or exit). */\n onCtrlC?: () => void\n\n /** Callback when Ctrl+D is pressed (exit). */\n onCtrlD?: () => void\n\n /** Callback when Ctrl+W is pressed (workspace selector). */\n onCtrlW?: () => void\n\n /** Callback when Ctrl+N is pressed (new conversation). */\n onCtrlN?: () => void\n\n /** Callback when Alt+1..9 is pressed (jump to citation N from\n * the last response). The handler gets the integer ``1`` through\n * ``9``; it is responsible for checking whether that citation\n * exists and surfacing a useful message if not. */\n onCitationKey?: (n: number) => void\n\n /**\n * Callback fired after every keystroke that mutates the buffer.\n *\n * The TUI uses this to power the **pre-flight skill hint**: when\n * the user types ``/<slug>`` we surface the skill's description in\n * the chat log so they see what they're about to invoke before\n * pressing Enter. The handler is responsible for its own\n * deduplication (e.g. only show the hint when the parsed slug\n * changes), since this callback fires on *every* mutating key.\n *\n * Receives the buffer text *after* the base ``handleInput`` has\n * applied the change. Read-only — handlers must not mutate the\n * editor synchronously or it'll loop.\n */\n onBufferChange?: (text: string) => void\n\n /** Track Ctrl+C presses for double-tap exit. */\n private lastCtrlCTime = 0\n\n /** Snapshot of the last text we emitted, so we don't fire on\n * non-mutating keys (cursor moves, redraws). */\n private lastEmittedText = ''\n\n constructor(tui: TUI) {\n super(tui, editorTheme, { paddingX: 1 })\n }\n\n override handleInput(data: string): void {\n if (matchesKey(data, Key.escape)) {\n this.onEscape?.()\n return\n }\n\n if (matchesKey(data, Key.ctrl('c'))) {\n const now = Date.now()\n if (this.getText().trim()) {\n // First Ctrl+C with content: clear input\n this.setText('')\n this.lastCtrlCTime = now\n } else if (now - this.lastCtrlCTime < 1000) {\n // Double Ctrl+C within 1s: exit\n this.onCtrlC?.()\n } else {\n this.lastCtrlCTime = now\n this.onCtrlC?.()\n }\n return\n }\n\n if (matchesKey(data, Key.ctrl('d'))) {\n this.onCtrlD?.()\n return\n }\n\n if (matchesKey(data, Key.ctrl('w'))) {\n this.onCtrlW?.()\n return\n }\n\n if (matchesKey(data, Key.ctrl('n'))) {\n this.onCtrlN?.()\n return\n }\n\n // Alt+1..9 — citation hotkeys. Only fire when there's a handler;\n // otherwise fall through so unbound terminals don't swallow the\n // input. ``onCitationKey`` itself decides what to do if there are\n // no citations available right now.\n if (this.onCitationKey) {\n for (let n = 1; n <= 9; n++) {\n if (matchesKey(data, Key.alt(String(n) as '1'))) {\n this.onCitationKey(n)\n return\n }\n }\n }\n\n // Pass all other input to the base Editor\n super.handleInput(data)\n\n // Buffer-change notification. Fires only when text actually\n // changed — arrow keys, redraws, and the no-op Ctrl-keys handled\n // above don't pay the lookup cost. Wrapped in try/catch so a\n // throwing observer never wedges the editor.\n if (this.onBufferChange) {\n const current = this.getText()\n if (current !== this.lastEmittedText) {\n this.lastEmittedText = current\n try {\n this.onBufferChange(current)\n } catch {\n // Swallow — the observer is best-effort UX.\n }\n }\n }\n }\n}\n","/**\n * ToastContainer — auto-dismissing notification toasts.\n *\n * Manages a list of styled Text children that appear briefly then\n * auto-remove themselves. Used for WebSocket event notifications.\n */\n\nimport { Container, Text } from '@mariozechner/pi-tui'\nimport chalk from 'chalk'\n\nexport type ToastLevel = 'info' | 'success' | 'warning' | 'error'\n\nconst LEVEL_STYLE: Record<ToastLevel, (s: string) => string> = {\n info: chalk.dim.cyan,\n success: chalk.dim.green,\n warning: chalk.dim.yellow,\n error: chalk.dim.red,\n}\n\nfunction formatTimestamp(): string {\n const now = new Date()\n const hh = String(now.getHours()).padStart(2, '0')\n const mm = String(now.getMinutes()).padStart(2, '0')\n const ss = String(now.getSeconds()).padStart(2, '0')\n return `${hh}:${mm}:${ss}`\n}\n\ninterface ActiveToast {\n text: Text\n timer: ReturnType<typeof setTimeout>\n}\n\nexport class ToastContainer extends Container {\n private activeToasts: ActiveToast[] = []\n private renderCallback: (() => void) | null = null\n\n /** Set the callback used to trigger a TUI re-render after toast changes. */\n setRenderCallback(cb: () => void): void {\n this.renderCallback = cb\n }\n\n /** Show a toast notification that auto-dismisses after `durationMs`. */\n show(message: string, level: ToastLevel = 'info', durationMs = 5000): void {\n const styleFn = LEVEL_STYLE[level]\n const formatted = styleFn(`[${formatTimestamp()}] ${message}`)\n const text = new Text(formatted, 1, 0)\n\n const timer = setTimeout(() => {\n this.dismiss(text)\n }, durationMs)\n\n this.activeToasts.push({ text, timer })\n this.addChild(text)\n this.renderCallback?.()\n }\n\n /** Remove all active toasts immediately. */\n clear(): void {\n for (const toast of this.activeToasts) {\n clearTimeout(toast.timer)\n this.removeChild(toast.text)\n }\n this.activeToasts = []\n this.renderCallback?.()\n }\n\n private dismiss(text: Text): void {\n const idx = this.activeToasts.findIndex((t) => t.text === text)\n if (idx !== -1) {\n clearTimeout(this.activeToasts[idx].timer)\n this.activeToasts.splice(idx, 1)\n this.removeChild(text)\n this.renderCallback?.()\n }\n }\n}\n","/**\n * Declarative command registry — replaces the switch-statement dispatcher\n * and static command array with a data-driven registry.\n *\n * Adding a new command is a single object literal in the appropriate domain file.\n * Auth guards, arg validation, help text, autocomplete, and error handling are automatic.\n */\n\nimport type { SlashCommand } from '@mariozechner/pi-tui'\nimport type { ArbiClient } from '@arbidocs/client'\nimport type { AuthContext, WorkspaceContext } from '@arbidocs/sdk'\nimport { getErrorMessage, parseSlashCommand } from '@arbidocs/sdk'\nimport type { ArbiTui } from './tui.js'\nimport { showMessage } from './tui-helpers.js'\n\n// ── Types ──────────────────────────────────────────────────────────────────\n\nexport type CommandRequires = 'none' | 'auth' | 'workspace'\n\ninterface CommandContextBase {\n args: string[]\n rawInput: string\n tui: ArbiTui\n}\n\nexport interface NoneCommandContext extends CommandContextBase {\n requires: 'none'\n}\n\nexport interface AuthCommandContext extends CommandContextBase {\n requires: 'auth'\n arbi: ArbiClient\n authContext: AuthContext\n}\n\nexport interface WorkspaceCommandContext extends CommandContextBase {\n requires: 'workspace'\n arbi: ArbiClient\n authContext: AuthContext\n wsContext: WorkspaceContext\n authHeaders: { baseUrl: string; accessToken: string }\n}\n\nexport type CommandContext = NoneCommandContext | AuthCommandContext | WorkspaceCommandContext\n\nexport type CommandOutput = string | string[] | void\n\nexport interface CommandDef {\n name: string\n description: string\n requires: CommandRequires\n run: (ctx: CommandContext) => CommandOutput | Promise<CommandOutput>\n /** Shown in help: /cmd <argHint> */\n argHint?: string\n /** Auto usage-error if fewer args are provided */\n minArgs?: number\n /** Omitted from /help (e.g. /quit alias) */\n hidden?: boolean\n}\n\n// ── Registry ───────────────────────────────────────────────────────────────\n\nconst registry = new Map<string, CommandDef>()\n\n/**\n * Slash commands the backend intercepts directly (not via the skills\n * registry). Kept tiny and explicit — every entry mirrors a branch in\n * ``src/core/router_helpers/commands.py``. ``/skill`` is excluded\n * because it's already registered as a static client-side command.\n */\nconst KNOWN_SERVER_COMMANDS: ReadonlySet<string> = new Set(['pa', 'setup', 'cold-start'])\n\n/** Register a single command definition. */\nexport function registerCommand(def: CommandDef): void {\n registry.set(def.name, def)\n}\n\n/** Register an array of command definitions. */\nexport function registerCommands(defs: CommandDef[]): void {\n for (const def of defs) {\n registerCommand(def)\n }\n}\n\n// ── Autocomplete / Help ────────────────────────────────────────────────────\n\n/** Convert the registry to an array of SlashCommand for pi-tui autocomplete. */\nexport function toSlashCommands(): SlashCommand[] {\n const cmds: SlashCommand[] = []\n for (const def of registry.values()) {\n if (def.hidden) continue\n cmds.push({ name: def.name, description: def.description })\n }\n return cmds\n}\n\n/**\n * Merge static client commands with dynamic backend skills into one\n * autocomplete list. This is the **single source of truth** for what\n * the editor's tab-complete shows — static-client and backend-skill\n * entries appear in the same dropdown so the user doesn't have to\n * know the difference.\n *\n * If a skill's slug collides with a static command (e.g. someone\n * names a skill ``help``), the static command wins because it owns\n * the TS handler. We skip the colliding skill entry rather than\n * shadowing the static one in the dropdown.\n *\n * Decoupled from ``toSlashCommands`` so callers that only want\n * static commands (e.g. ``formatHelpText``) keep working.\n */\nexport function toSlashCommandsWithSkills(\n skills: ReadonlyArray<{ slug: string; description: string }>\n): SlashCommand[] {\n const out = toSlashCommands()\n const taken = new Set(out.map((c) => c.name))\n for (const s of skills) {\n if (taken.has(s.slug)) continue\n out.push({ name: s.slug, description: s.description })\n }\n return out\n}\n\n/** Format all visible commands as a help string for display. */\nexport function formatHelpText(): string {\n const lines: string[] = []\n for (const def of registry.values()) {\n if (def.hidden) continue\n const hint = def.argHint ? ` <${def.argHint}>` : ''\n lines.push(` /${def.name}${hint} — ${def.description}`)\n }\n return [\n 'Available commands:',\n '',\n ...lines,\n '',\n 'Direct messages:',\n ' @name — Switch to DM channel with a contact',\n ' @arbi — Switch back to AI chat',\n '',\n 'Keyboard shortcuts:',\n ' Ctrl+N — New conversation',\n ' Ctrl+W — Switch workspace',\n ' Ctrl+D — Exit',\n ' Escape — Abort streaming',\n ' Alt+1..9 — Jump to citation N from the last response',\n '',\n 'Skills: any workspace SKILL.md with `user-invocable: true` becomes a',\n ' ``/<slug>`` command — type it like a regular slash command and the',\n ' agent handles it. ``/skills`` lists what is available.',\n ].join('\\n')\n}\n\n// ── Dispatcher ─────────────────────────────────────────────────────────────\n\n/**\n * Resolution order for ``/<name>``:\n *\n * 1. **Static client command** in this registry (e.g. ``/help``,\n * ``/cite``, ``/view``) — TUI-only affordances that run TS handlers.\n * 2. **Backend skill** in ``tui.skillsCache`` — workspace skills the\n * user has uploaded with ``user-invocable: true``. The TUI does\n * **not** run skill logic; it forwards the raw ``/<slug>`` text\n * to the backend, which intercepts in ``handle_skill_command``\n * and injects the skill body into the agent's prompt. This is the\n * single source of truth — the TUI never has its own skill catalogue.\n * 3. **Unknown** — friendly error.\n *\n * This is the \"no two sources of truth\" rule: static-client commands\n * are TS-defined here, backend skills come from ``GET /v1/assistant/skills``,\n * and the dispatcher walks them in priority order. Previously a typed\n * ``/<skill-slug>`` would say \"Unknown command\" even though the backend\n * would have happily intercepted it; that mismatch is the bug this\n * closes.\n */\n\n/** Dispatch a slash command. Returns true if handled. */\nexport async function dispatchCommand(tui: ArbiTui, input: string): Promise<boolean> {\n // Canonical parse — same regex as the React menu and the pre-flight\n // hint, lives in ``packages/arbi-sdk/src/operations/assistant.ts``.\n // ``parseSlashCommand`` returns ``null`` for anything that isn't a\n // slash command (including the bare DM ``@name`` shortcut), so the\n // caller can confidently let other handlers see the input.\n const parsed = parseSlashCommand(input)\n if (!parsed) return false\n\n const cmdName = parsed.slug\n // ``args`` is the rest-of-buffer as a single string from the SDK's\n // parser; the dispatcher's older callers expect ``string[]`` (split\n // on whitespace) so we keep that contract here.\n const args = parsed.args.length > 0 ? parsed.args.split(/\\s+/) : []\n // ``trimmed`` is kept as the raw command text for handlers that want\n // to inspect the original (e.g. ``rawInput`` in context). It's the\n // input minus leading/trailing whitespace, matching the previous\n // behaviour.\n const trimmed = input.trim()\n\n const def = registry.get(cmdName)\n if (!def) {\n // Fall through to backend skills before declaring \"unknown\".\n // The cache is populated on workspace switch\n // (``tui.refreshSkillsCache``) and on every ``/skills`` call.\n // Match by slug or display name so frontmatter authors aren't\n // surprised either way.\n const skill = tui.skillsCache?.find(\n (s) => s.slug === cmdName || s.name.toLowerCase() === cmdName\n )\n if (skill) {\n // Surface the skill's metadata in the chat log so the user can\n // see what they're invoking before the agent responds.\n // Equivalent of claude-code's pre-flight slash-command palette\n // confirmation — same data, no separate overlay needed.\n const meta = skill.arg_hint\n ? `Skill: ${skill.name} ${skill.arg_hint} — ${skill.description}`\n : `Skill: ${skill.name} — ${skill.description}`\n showMessage(tui, meta, 'info')\n\n // Returning ``false`` tells ``handleSubmit`` to fall through to\n // the normal AI-send path. The backend intercepts ``/<slug>``\n // server-side in ``handle_skill_command``; we never run skill\n // logic locally. Even ``type=python`` skills execute in the\n // backend's workspace sandbox — the TUI is purely a transport.\n return false\n }\n\n // Built-in backend commands the TUI never executes locally. They're\n // intercepted in ``src/core/router_helpers/commands.py`` on the\n // server (``/pa`` for OpenClaw PA, ``/setup`` / ``/cold-start`` for\n // the skills cold-start interview) and aren't in the skills cache\n // because they're not user-data. Passing them through here matches\n // the backend's vocabulary; without this they'd be wrongly flagged\n // as \"Unknown command\" client-side.\n if (KNOWN_SERVER_COMMANDS.has(cmdName)) {\n return false\n }\n\n showMessage(tui, `Unknown command: /${cmdName}. Type /help for available commands.`, 'warning')\n return true\n }\n\n // Check minArgs\n if (def.minArgs && args.length < def.minArgs) {\n const hint = def.argHint ? ` <${def.argHint}>` : ''\n showMessage(tui, `Usage: /${def.name}${hint}`, 'warning')\n return true\n }\n\n // Build context based on `requires`\n let ctx: CommandContext\n\n if (def.requires === 'none') {\n ctx = { requires: 'none', args, rawInput: trimmed, tui }\n } else if (def.requires === 'auth') {\n if (!tui.authContext) {\n showMessage(tui, 'Not authenticated. Use /login first.', 'error')\n return true\n }\n ctx = {\n requires: 'auth',\n args,\n rawInput: trimmed,\n tui,\n arbi: tui.authContext.arbi,\n authContext: tui.authContext,\n }\n } else {\n // requires === 'workspace'\n if (!tui.authContext) {\n showMessage(tui, 'Not authenticated. Use /login first.', 'error')\n return true\n }\n if (!tui.wsContext) {\n showMessage(tui, 'No workspace selected. Use /workspace <id> first.', 'warning')\n return true\n }\n ctx = {\n requires: 'workspace',\n args,\n rawInput: trimmed,\n tui,\n arbi: tui.wsContext.arbi,\n authContext: tui.authContext,\n wsContext: tui.wsContext,\n authHeaders: {\n baseUrl: tui.wsContext.config.baseUrl,\n accessToken: tui.wsContext.accessToken,\n },\n }\n }\n\n try {\n const result = await def.run(ctx)\n if (typeof result === 'string') {\n showMessage(tui, result)\n } else if (Array.isArray(result)) {\n showMessage(tui, result.join('\\n'))\n }\n } catch (err) {\n showMessage(tui, `Command /${def.name} failed: ${getErrorMessage(err)}`, 'error')\n }\n\n return true\n}\n","/**\n * General commands — /help, /status, /exit, /quit, /new\n */\n\nimport type { CommandDef, NoneCommandContext } from '../command-registry.js'\nimport { formatHelpText } from '../command-registry.js'\nimport { colors } from '../theme/theme.js'\n\nexport const generalCommands: CommandDef[] = [\n {\n name: 'help',\n description: 'Show available commands',\n requires: 'none',\n run: () => formatHelpText(),\n },\n {\n name: 'status',\n description: 'Show auth/workspace/connection status',\n requires: 'none',\n run: (ctx) => {\n const { tui } = ctx as NoneCommandContext\n const { state } = tui\n return [\n `Authenticated: ${state.isAuthenticated ? colors.success('yes') : colors.error('no')}`,\n `Workspace: ${state.workspaceName ? colors.accent(state.workspaceName) : colors.muted('none')}`,\n `Workspace ID: ${state.workspaceId ?? colors.muted('none')}`,\n `Conversation: ${state.conversationMessageId ? colors.muted(state.conversationMessageId) : colors.muted('new')}`,\n `Status: ${state.activityStatus}`,\n `WebSocket: ${tui.wsConnected ? colors.success('connected') : colors.muted('disconnected')}`,\n ]\n },\n },\n {\n name: 'new',\n description: 'Start fresh conversation (clear threading)',\n requires: 'none',\n run: (ctx) => {\n const { tui } = ctx as NoneCommandContext\n tui.state.conversationMessageId = null\n tui.lastMetadata = null\n // Sources index is scoped to the conversation — wiping it\n // alongside the threading state keeps ``/sources`` aligned with\n // \"this conversation\", not \"everything since the TUI launched\".\n tui.sourcesIndex.clear()\n tui.store.clearChatSession()\n return 'Started new conversation.'\n },\n },\n {\n name: 'exit',\n description: 'Exit TUI',\n requires: 'none',\n run: (ctx) => {\n const { tui } = ctx as NoneCommandContext\n tui.shutdown()\n },\n },\n {\n name: 'quit',\n description: 'Exit TUI',\n requires: 'none',\n hidden: true,\n run: (ctx) => {\n const { tui } = ctx as NoneCommandContext\n tui.shutdown()\n },\n },\n]\n","/**\n * Interactive prompt helpers using @inquirer/prompts.\n *\n * These are only used in interactive (TTY) flows — before the TUI starts\n * or after temporarily stopping it. Mirrors the CLI's prompt wrappers\n * for consistent validation and UX.\n */\n\nimport { select, input, password, confirm, checkbox, search } from '@inquirer/prompts'\n\nexport { select, input, password, confirm, checkbox, search }\n\n/**\n * Prompt user to pick from a list of items.\n * Returns the value of the selected choice.\n */\nexport async function promptSelect<T>(\n message: string,\n choices: Array<{ name: string; value: T; description?: string }>\n): Promise<T> {\n return select({ message, choices })\n}\n\n/**\n * Prompt user to pick multiple items from a list.\n * Returns array of selected values.\n */\nexport async function promptCheckbox<T>(\n message: string,\n choices: Array<{ name: string; value: T; checked?: boolean }>\n): Promise<T[]> {\n return checkbox({ message, choices })\n}\n\n/**\n * Prompt user to search and pick from a large list.\n * Type-ahead fuzzy filtering — best for docs (could be hundreds).\n */\nexport async function promptSearch<T>(\n message: string,\n choices: Array<{ name: string; value: T; description?: string }>\n): Promise<T> {\n return search({\n message,\n source: async (term) => {\n if (!term) return choices\n const lower = term.toLowerCase()\n return choices.filter((c) => c.name.toLowerCase().includes(lower))\n },\n })\n}\n\n/**\n * Prompt for text input. Returns trimmed string.\n */\nexport async function promptInput(message: string, required = true): Promise<string> {\n return input({\n message,\n validate: required ? (v) => (v.trim() ? true : 'Required') : undefined,\n })\n}\n\n/**\n * Prompt for a password (masked input).\n */\nexport async function promptPassword(message: string): Promise<string> {\n return password({\n message,\n mask: '*',\n validate: (v) => (v ? true : 'Required'),\n })\n}\n\n/**\n * Prompt for yes/no confirmation.\n */\nexport async function promptConfirm(message: string, defaultValue = true): Promise<boolean> {\n return confirm({ message, default: defaultValue })\n}\n","/**\n * Authentication flows for the TUI.\n *\n * Handles login and registration using @inquirer/prompts for interactive input.\n * These flows run BEFORE the TUI takes over the terminal (pi-tui raw mode),\n * or after temporarily stopping the TUI.\n */\n\nimport 'fake-indexeddb/auto'\nimport { createArbiClient } from '@arbidocs/client'\nimport type { ConfigStore, AuthContext } from '@arbidocs/sdk'\nimport {\n getErrorMessage,\n performPasswordLogin,\n formatWorkspaceChoices,\n generateNewWorkspaceKey,\n resolveAuth,\n workspaces,\n projects,\n} from '@arbidocs/sdk'\nimport { promptInput, promptPassword, promptSelect, promptConfirm } from './prompts.js'\n\n// ── Login ──────────────────────────────────────────────────────────────────\n\nexport interface LoginResult {\n authContext: AuthContext\n selectedWorkspaceId?: string\n selectedWorkspaceName?: string\n}\n\n/**\n * Interactive login flow. Prompts for email/password, authenticates,\n * and offers workspace selection.\n *\n * Must be called before the TUI starts (or after stopping it).\n */\nexport async function interactiveLogin(store: ConfigStore): Promise<LoginResult> {\n const config = store.requireConfig()\n\n const email = await promptInput('Email')\n const pw = await promptPassword('Password')\n\n const authContext = await performPasswordLogin(config, email, pw, store)\n\n console.info(`Logged in as ${email}`)\n\n // Workspace selection\n const result = await selectOrCreateWorkspace(authContext, store)\n\n return { authContext, ...result }\n}\n\n// ── Registration ───────────────────────────────────────────────────────────\n\n/**\n * Interactive registration flow. Prompts for email, verification code,\n * password, and name. Optionally logs in afterward.\n *\n * Must be called before the TUI starts (or after stopping it).\n */\nexport async function interactiveRegister(store: ConfigStore): Promise<LoginResult> {\n const config = store.requireConfig()\n\n const email = await promptInput('Email')\n\n const arbi = createArbiClient({\n baseUrl: config.baseUrl,\n deploymentDomain: config.deploymentDomain,\n credentials: 'omit',\n })\n await arbi.crypto.initSodium()\n\n // Verification\n const codeMethod = await promptSelect('Verification method', [\n { name: 'I have an invitation code', value: 'code' as const },\n { name: 'Send me a verification email', value: 'email' as const },\n ])\n\n let verificationCode: string\n if (codeMethod === 'code') {\n verificationCode = await promptInput('Invitation code')\n } else {\n console.info('Sending verification email...')\n const verifyResponse = await arbi.fetch.POST('/v1/user/verify-email', {\n body: { email },\n })\n if (verifyResponse.error) {\n throw new Error(`Failed to send verification email: ${JSON.stringify(verifyResponse.error)}`)\n }\n console.info('Verification email sent. Check your inbox.')\n verificationCode = await promptInput('Verification code')\n }\n\n // Password\n const pw = await promptPassword('Password')\n const confirmPw = await promptPassword('Confirm password')\n if (pw !== confirmPw) {\n throw new Error('Passwords do not match.')\n }\n\n // Name\n const firstName = (await promptInput('First name (optional)', false)) || 'User'\n const lastName = (await promptInput('Last name (optional)', false)) || ''\n\n // Register\n await arbi.auth.register({\n email,\n password: pw,\n verificationCode,\n firstName,\n lastName,\n })\n\n console.info(`\\nRegistered successfully as ${email}`)\n\n // Auto-login with the credentials just provided\n console.info('Logging in...')\n const authContext = await performPasswordLogin(config, email, pw, store)\n\n console.info(`Logged in as ${email}`)\n const result = await selectOrCreateWorkspace(authContext, store)\n\n return { authContext, ...result }\n}\n\n// ── Workspace selection / creation ──────────────────────────────────────────\n\n/**\n * After login, select an existing workspace or prompt to create one.\n * Used by both login and register flows.\n */\nasync function selectOrCreateWorkspace(\n authContext: AuthContext,\n store: ConfigStore\n): Promise<{ selectedWorkspaceId?: string; selectedWorkspaceName?: string }> {\n const wsList = await workspaces.listWorkspaces(authContext.arbi)\n\n if (wsList.length === 1) {\n store.updateConfig({ selectedWorkspaceId: wsList[0].external_id })\n console.info(`Workspace: ${wsList[0].name}`)\n return { selectedWorkspaceId: wsList[0].external_id, selectedWorkspaceName: wsList[0].name }\n }\n\n if (wsList.length > 1) {\n const choices = formatWorkspaceChoices(wsList)\n\n const selectedWorkspaceId = await promptSelect('Select workspace', choices)\n const ws = wsList.find((w) => w.external_id === selectedWorkspaceId)\n store.updateConfig({ selectedWorkspaceId })\n console.info(`Workspace: ${ws?.name}`)\n return { selectedWorkspaceId, selectedWorkspaceName: ws?.name }\n }\n\n // No workspaces — offer to create one\n console.info('No workspaces found.')\n const shouldCreate = await promptConfirm('Create a new workspace?')\n\n if (shouldCreate) {\n const name = await promptInput('Workspace name')\n const userProjects = await projects.listProjects(authContext.arbi)\n const defaultProjectExtId = userProjects[0]?.external_id\n if (!defaultProjectExtId) throw new Error('No projects found for user')\n const encryptedKey = await generateNewWorkspaceKey(\n authContext.arbi,\n authContext.loginResult.serverSessionKey\n )\n const ws = await workspaces.createWorkspace(\n authContext.arbi,\n name.trim(),\n encryptedKey,\n defaultProjectExtId\n )\n store.updateConfig({ selectedWorkspaceId: ws.external_id })\n console.info(`Created workspace: ${ws.name}`)\n return { selectedWorkspaceId: ws.external_id, selectedWorkspaceName: ws.name }\n }\n\n return {}\n}\n\n// ── Pre-flight auth check ──────────────────────────────────────────────────\n\n/**\n * Check if the user is authenticated. If not, offer to login or register.\n * Returns the auth context if successful, or exits the process.\n *\n * Called at startup before the TUI launches.\n */\nexport async function ensureAuthenticated(store: ConfigStore): Promise<LoginResult> {\n // Try existing credentials first\n try {\n const authContext = await resolveAuth(store)\n const config = store.requireConfig()\n return {\n authContext,\n selectedWorkspaceId: config.selectedWorkspaceId,\n }\n } catch {\n // Not authenticated — offer login/register with retry on errors\n console.info('Not authenticated.\\n')\n }\n\n // Retry loop — keeps prompting until successful login/register or user exits\n while (true) {\n const action = await promptSelect('What would you like to do?', [\n { name: 'Log in', value: 'login' as const },\n { name: 'Register a new account', value: 'register' as const },\n { name: 'Exit', value: 'exit' as const },\n ])\n\n if (action === 'exit') {\n process.exit(0)\n }\n\n try {\n if (action === 'register') {\n return await interactiveRegister(store)\n }\n return await interactiveLogin(store)\n } catch (err) {\n console.error(`\\n${getErrorMessage(err)}\\n`)\n }\n }\n}\n","/**\n * Auth commands — /login, /register, /logout\n */\n\nimport type { CommandDef, NoneCommandContext } from '../command-registry.js'\nimport { interactiveLogin, interactiveRegister } from '../auth.js'\nimport { showMessage, applyWorkspaceSelection, runInteractiveFlow } from '../tui-helpers.js'\n\nexport const authCommands: CommandDef[] = [\n {\n name: 'login',\n description: 'Log in (re-authenticate)',\n requires: 'none',\n run: async (ctx) => {\n const { tui } = ctx as NoneCommandContext\n const result = await runInteractiveFlow(\n tui,\n 'Pausing TUI for login...',\n () => interactiveLogin(tui.store),\n 'Login failed'\n )\n\n if (result) {\n tui.setAuthContext(result.authContext)\n await applyWorkspaceSelection(tui, result.selectedWorkspaceId, result.selectedWorkspaceName)\n showMessage(tui, 'Logged in successfully.')\n }\n },\n },\n {\n name: 'register',\n description: 'Register a new account',\n requires: 'none',\n run: async (ctx) => {\n const { tui } = ctx as NoneCommandContext\n const result = await runInteractiveFlow(\n tui,\n 'Pausing TUI for registration...',\n () => interactiveRegister(tui.store),\n 'Registration failed'\n )\n\n if (result) {\n tui.setAuthContext(result.authContext)\n await applyWorkspaceSelection(tui, result.selectedWorkspaceId, result.selectedWorkspaceName)\n showMessage(tui, 'Registered and logged in.')\n }\n },\n },\n {\n name: 'logout',\n description: 'Log out and clear credentials',\n requires: 'none',\n run: (ctx) => {\n const { tui } = ctx as NoneCommandContext\n tui.store.deleteCredentials()\n tui.store.updateConfig({ selectedWorkspaceId: undefined })\n tui.store.clearChatSession()\n\n tui.authContext = null\n tui.state.isAuthenticated = false\n tui.state.workspaceId = null\n tui.state.workspaceName = null\n tui.state.conversationMessageId = null\n\n return 'Logged out. Use /login to authenticate again.'\n },\n },\n]\n","/**\n * Workspace commands — /workspaces, /workspace, /create,\n * plus new: /ws-delete, /ws-users, /ws-add-user, /ws-remove-user\n */\n\nimport { workspaces, projects, generateNewWorkspaceKey, formatUserName } from '@arbidocs/sdk'\nimport type {\n CommandDef,\n AuthCommandContext,\n WorkspaceCommandContext,\n} from '../command-registry.js'\nimport { colors } from '../theme/theme.js'\nimport { showMessage, switchWorkspace } from '../tui-helpers.js'\n\nexport const workspaceCommands: CommandDef[] = [\n {\n name: 'workspaces',\n description: 'List all workspaces',\n requires: 'auth',\n run: async (ctx) => {\n const { arbi, tui } = ctx as AuthCommandContext\n const wsList = await workspaces.listWorkspaces(arbi)\n const lines = wsList.map((ws) => {\n const current = ws.external_id === tui.state.workspaceId ? colors.accent(' (current)') : ''\n return ` ${ws.external_id} ${ws.name}${current}`\n })\n return ['Workspaces:', '', ...lines]\n },\n },\n {\n name: 'workspace',\n description: 'Switch workspace',\n argHint: 'id',\n requires: 'auth',\n run: async (ctx) => {\n const { args, arbi, tui } = ctx as AuthCommandContext\n\n if (!args[0]) {\n const wsList = await workspaces.listWorkspaces(arbi)\n const lines = wsList.map((ws) => {\n const current =\n ws.external_id === tui.state.workspaceId ? colors.accent(' (current)') : ''\n return ` ${ws.external_id} ${ws.name}${current}`\n })\n showMessage(tui, ['Workspaces:', '', ...lines].join('\\n'))\n return 'Use /workspace <id> to switch.'\n }\n\n showMessage(tui, `Switching to workspace ${args[0]}...`)\n const ws = await switchWorkspace(tui, args[0])\n if (ws) {\n return `Switched to workspace: ${colors.accentBold(ws.name)}`\n }\n },\n },\n {\n name: 'create',\n description: 'Create a new workspace',\n argHint: 'name',\n minArgs: 1,\n requires: 'auth',\n run: async (ctx) => {\n const { args, arbi, authContext, tui } = ctx as AuthCommandContext\n const name = args.join(' ').trim()\n\n showMessage(tui, `Creating workspace \"${name}\"...`)\n const userProjects = await projects.listProjects(arbi)\n const defaultProjectExtId = userProjects[0]?.external_id\n if (!defaultProjectExtId) throw new Error('No projects found')\n const encryptedKey = await generateNewWorkspaceKey(\n arbi,\n authContext.loginResult.serverSessionKey\n )\n const ws = await workspaces.createWorkspace(arbi, name, encryptedKey, defaultProjectExtId)\n const selected = await switchWorkspace(tui, ws.external_id)\n\n if (selected) {\n return `Created and switched to workspace: ${colors.accentBold(selected.name)}`\n }\n },\n },\n {\n name: 'ws-delete',\n description: 'Delete a workspace',\n argHint: 'id',\n minArgs: 1,\n requires: 'auth',\n run: async (ctx) => {\n const { args, arbi } = ctx as AuthCommandContext\n await workspaces.deleteWorkspaces(arbi, [args[0]!])\n return `${colors.success('Deleted')} workspace ${args[0]}`\n },\n },\n {\n name: 'ws-users',\n description: 'List users in current workspace',\n requires: 'workspace',\n run: async (ctx) => {\n const { arbi } = ctx as WorkspaceCommandContext\n const users = await workspaces.listWorkspaceUsers(arbi)\n if (users.length === 0) return 'No users in this workspace.'\n\n const lines = users.map((u) => {\n const name = formatUserName(u.user)\n const nameStr = name ? colors.muted(` (${name})`) : ''\n const role = u.role ? colors.muted(` [${u.role}]`) : ''\n return ` ${u.user.email}${nameStr}${role}`\n })\n return [`Workspace users (${users.length}):`, '', ...lines]\n },\n },\n {\n name: 'ws-add-user',\n description: 'Add a user to current workspace',\n argHint: 'email',\n minArgs: 1,\n requires: 'workspace',\n run: async (ctx) => {\n const { args, arbi } = ctx as WorkspaceCommandContext\n const email = args[0]!.trim()\n await workspaces.addWorkspaceUsers(arbi, [email])\n return `${colors.success('Added')} ${email} to workspace.`\n },\n },\n {\n name: 'ws-remove-user',\n description: 'Remove a user from current workspace',\n argHint: 'email',\n minArgs: 1,\n requires: 'workspace',\n run: async (ctx) => {\n const { args, arbi } = ctx as WorkspaceCommandContext\n const email = args[0]!.trim()\n\n // Resolve email to user ID\n const users = await workspaces.listWorkspaceUsers(arbi)\n const user = users.find((u) => u.user.email === email)\n if (!user) return `User ${email} not found in this workspace.`\n\n const userId = user.user.external_id as string | undefined\n if (!userId) return `Could not resolve user ID for ${email}.`\n\n await workspaces.removeWorkspaceUsers(arbi, [userId])\n return `${colors.success('Removed')} ${email} from workspace.`\n },\n },\n]\n","/**\n * Document commands — /docs, /delete, /upload,\n * plus new: /doc, /upload-url, /parsed\n */\n\nimport { documents, documentsNode } from '@arbidocs/sdk'\nimport type { CommandDef, WorkspaceCommandContext } from '../command-registry.js'\nimport { colors } from '../theme/theme.js'\nimport { showMessage } from '../tui-helpers.js'\n\nexport const documentCommands: CommandDef[] = [\n {\n name: 'docs',\n description: 'List documents in current workspace',\n requires: 'workspace',\n run: async (ctx) => {\n const { arbi } = ctx as WorkspaceCommandContext\n const docs = await documents.listDocuments(arbi)\n if (docs.length === 0) return 'No documents in this workspace.'\n\n const lines = docs.map((d) => ` ${d.external_id} ${d.file_name ?? '(unnamed)'}`)\n return [`Documents (${docs.length}):`, '', ...lines]\n },\n },\n {\n name: 'doc',\n description: 'Show document details',\n argHint: 'id',\n minArgs: 1,\n requires: 'workspace',\n run: async (ctx) => {\n const { args, arbi } = ctx as WorkspaceCommandContext\n const docs = await documents.getDocuments(arbi, [args[0]!])\n if (docs.length === 0) return `Document ${args[0]} not found.`\n\n const doc = docs[0]!\n const lines = [\n `Document: ${colors.accent(doc.file_name ?? '(unnamed)')}`,\n '',\n ` ID: ${doc.external_id}`,\n ` Status: ${doc.status ?? colors.muted('unknown')}`,\n ` Size: ${doc.file_size != null ? `${doc.file_size} bytes` : colors.muted('unknown')}`,\n ` Created: ${doc.created_at ?? colors.muted('unknown')}`,\n ]\n return lines\n },\n },\n {\n name: 'upload',\n description: 'Upload a file',\n argHint: 'path',\n minArgs: 1,\n requires: 'workspace',\n run: async (ctx) => {\n const { args, tui, wsContext } = ctx as WorkspaceCommandContext\n const filePath = args.join(' ').trim()\n\n showMessage(tui, `Uploading ${filePath}...`)\n\n const result = await documentsNode.uploadLocalFile(\n {\n baseUrl: wsContext.config.baseUrl,\n accessToken: wsContext.accessToken,\n },\n filePath\n )\n\n const ids = (result.doc_ext_ids ?? []).join(', ')\n showMessage(tui, `${colors.success('Uploaded')} ${result.fileName} — doc ID(s): ${ids}`)\n\n if (result.skipped && result.skipped.length > 0) {\n showMessage(\n tui,\n `Skipped: ${result.skipped.map((s) => `${s.file_name} (${s.reason})`).join(', ')}`,\n 'warning'\n )\n }\n },\n },\n {\n name: 'upload-url',\n description: 'Upload a document from URL',\n argHint: 'url',\n minArgs: 1,\n requires: 'workspace',\n run: async (ctx) => {\n const { args, arbi, wsContext, tui } = ctx as WorkspaceCommandContext\n const url = args[0]!.trim()\n\n showMessage(tui, `Uploading from ${url}...`)\n const result = await documents.uploadUrl(arbi, [url])\n\n const ids = (result.doc_ext_ids ?? []).join(', ')\n const lines = [`${colors.success('Uploaded')} from URL — doc ID(s): ${ids}`]\n if (result.skipped && result.skipped.length > 0) {\n lines.push(\n `Skipped: ${result.skipped.map((s) => `${s.file_name} (${s.reason})`).join(', ')}`\n )\n }\n return lines\n },\n },\n {\n name: 'delete',\n description: 'Delete a document',\n argHint: 'doc-id',\n minArgs: 1,\n requires: 'workspace',\n run: async (ctx) => {\n const { args, arbi, tui } = ctx as WorkspaceCommandContext\n const docId = args[0]!.trim()\n\n showMessage(tui, `Deleting document ${docId}...`)\n await documents.deleteDocuments(arbi, [docId])\n return `${colors.success('Deleted')} document ${docId}`\n },\n },\n {\n name: 'parsed',\n description: 'Show parsed content of a document',\n argHint: 'doc-id',\n minArgs: 1,\n requires: 'workspace',\n run: async (ctx) => {\n const { args, authHeaders } = ctx as WorkspaceCommandContext\n const docId = args[0]!.trim()\n\n const data = await documents.getParsedContent(authHeaders, docId, 'content')\n const content = (data as Record<string, unknown>).content as string | undefined\n\n if (!content) return `No parsed content available for document ${docId}.`\n\n // Truncate very long content for terminal display\n const maxLen = 3000\n const truncated =\n content.length > maxLen ? content.slice(0, maxLen) + '\\n... (truncated)' : content\n return [`Parsed content for ${docId}:`, '', truncated]\n },\n },\n]\n","/**\n * Conversation commands — /conversations,\n * plus new: /conv-delete, /conv-title, /conv-share\n */\n\nimport { conversations } from '@arbidocs/sdk'\nimport type { CommandDef, WorkspaceCommandContext } from '../command-registry.js'\nimport { colors } from '../theme/theme.js'\n\nexport const conversationCommands: CommandDef[] = [\n {\n name: 'conversations',\n description: 'List conversations',\n requires: 'workspace',\n run: async (ctx) => {\n const { arbi } = ctx as WorkspaceCommandContext\n const convs = await conversations.listConversations(arbi)\n if (convs.length === 0) return 'No conversations in this workspace.'\n\n const lines = convs.map((c) => ` ${c.external_id} ${c.title ?? '(untitled)'}`)\n return [`Conversations (${convs.length}):`, '', ...lines]\n },\n },\n {\n name: 'conv-delete',\n description: 'Delete a conversation',\n argHint: 'id',\n minArgs: 1,\n requires: 'workspace',\n run: async (ctx) => {\n const { args, arbi } = ctx as WorkspaceCommandContext\n await conversations.deleteConversation(arbi, args[0]!)\n return `${colors.success('Deleted')} conversation ${args[0]}`\n },\n },\n {\n name: 'conv-title',\n description: 'Rename a conversation',\n argHint: 'id title',\n minArgs: 2,\n requires: 'workspace',\n run: async (ctx) => {\n const { args, arbi } = ctx as WorkspaceCommandContext\n const [id, ...titleParts] = args\n const title = titleParts.join(' ')\n await conversations.updateConversationTitle(arbi, id!, title)\n return `Renamed conversation ${id} to: ${colors.accent(title)}`\n },\n },\n {\n name: 'conv-share',\n description: 'Share a conversation',\n argHint: 'id',\n minArgs: 1,\n requires: 'workspace',\n run: async (ctx) => {\n const { args, arbi } = ctx as WorkspaceCommandContext\n const result = await conversations.shareConversation(arbi, args[0]!)\n const shareId =\n (result as Record<string, unknown>).share_ext_id ??\n (result as Record<string, unknown>).external_id\n return `${colors.success('Shared')} conversation ${args[0]} — share ID: ${shareId}`\n },\n },\n]\n","/**\n * Tag commands — /tags, /tag-create, /tag-delete\n */\n\nimport { tags } from '@arbidocs/sdk'\nimport type { CommandDef, WorkspaceCommandContext } from '../command-registry.js'\nimport { colors } from '../theme/theme.js'\n\nexport const tagCommands: CommandDef[] = [\n {\n name: 'tags',\n description: 'List tags in workspace',\n requires: 'workspace',\n run: async (ctx) => {\n const { arbi } = ctx as WorkspaceCommandContext\n const data = await tags.listTags(arbi)\n if (data.length === 0) return 'No tags in this workspace.'\n\n const lines = data.map((t) => ` ${t.external_id} ${t.name}`)\n return [`Tags (${data.length}):`, '', ...lines]\n },\n },\n {\n name: 'tag-create',\n description: 'Create a tag',\n argHint: 'name',\n minArgs: 1,\n requires: 'workspace',\n run: async (ctx) => {\n const { args, arbi } = ctx as WorkspaceCommandContext\n const name = args.join(' ').trim()\n const tag = await tags.createTag(arbi, { name })\n return `${colors.success('Created')} tag \"${tag.name}\" — ID: ${tag.external_id}`\n },\n },\n {\n name: 'tag-delete',\n description: 'Delete a tag',\n argHint: 'id',\n minArgs: 1,\n requires: 'workspace',\n run: async (ctx) => {\n const { args, arbi } = ctx as WorkspaceCommandContext\n await tags.deleteTag(arbi, args[0]!)\n return `${colors.success('Deleted')} tag ${args[0]}`\n },\n },\n]\n","/**\n * Miscellaneous commands — /contacts, /invite, /models, /health,\n * plus new: /settings\n */\n\nimport { contacts, health, settings, formatUserName } from '@arbidocs/sdk'\nimport type { CommandDef, AuthCommandContext } from '../command-registry.js'\nimport { colors } from '../theme/theme.js'\n\nexport const miscCommands: CommandDef[] = [\n {\n name: 'contacts',\n description: 'List contacts (type @name to DM)',\n requires: 'auth',\n run: async (ctx) => {\n const { arbi } = ctx as AuthCommandContext\n const contactList = await contacts.listContacts(arbi)\n const { registered, pending } = contacts.groupContactsByStatus(contactList)\n\n if (registered.length === 0 && pending.length === 0) {\n return 'No contacts. Use the web app to add contacts.'\n }\n\n const lines: string[] = []\n\n if (registered.length > 0) {\n lines.push(`Contacts (${registered.length}):`, '')\n for (const c of registered) {\n const name = formatUserName(c.user)\n const nameStr = name ? colors.muted(` (${name})`) : ''\n lines.push(` ${c.email}${nameStr}`)\n }\n }\n\n if (pending.length > 0) {\n if (lines.length > 0) lines.push('')\n lines.push(`Pending invitations (${pending.length}):`)\n for (const c of pending) {\n lines.push(` ${c.email} — ${colors.muted(c.status)}`)\n }\n }\n\n lines.push('', colors.muted('Type @name to start a DM with a registered contact.'))\n return lines\n },\n },\n {\n name: 'invite',\n description: 'Invite a contact',\n argHint: 'email',\n minArgs: 1,\n requires: 'auth',\n run: async (ctx) => {\n const { args, arbi, tui } = ctx as AuthCommandContext\n const email = args[0]!.trim()\n\n const { showMessage } = await import('../tui-helpers.js')\n showMessage(tui, `Inviting ${email}...`)\n\n const result = await contacts.addContacts(arbi, [email])\n const contact = result[0]\n\n if (contact?.status === 'registered') {\n return `${colors.success('Added')} ${email} — already registered. You can DM them with @${email.split('@')[0]}`\n }\n return `${colors.success('Invited')} ${email} — invitation sent. They'll appear in /contacts once they register.`\n },\n },\n {\n name: 'models',\n description: 'List available AI models',\n requires: 'auth',\n run: async (ctx) => {\n const { arbi } = ctx as AuthCommandContext\n const data = await health.getHealthModels(arbi)\n const models = Array.isArray(data)\n ? data\n : (((data as Record<string, unknown>).data as unknown[]) ?? [])\n\n if (models.length === 0) return 'No models available.'\n\n const lines: string[] = [`Models (${models.length}):`, '']\n for (const m of models) {\n const model = m as Record<string, unknown>\n const name = (model.model_name ?? model.name ?? 'unknown') as string\n const provider = (model.provider ?? '') as string\n const apiType = (model.api_type ?? '') as string\n const parts = [colors.accent(name)]\n if (provider) parts.push(`provider: ${provider}`)\n if (apiType) parts.push(`api: ${apiType}`)\n lines.push(` ${parts.join(' ')}`)\n }\n return lines\n },\n },\n {\n name: 'health',\n description: 'Show system health status',\n requires: 'auth',\n run: async (ctx) => {\n const { arbi } = ctx as AuthCommandContext\n const data = await health.getHealth(arbi)\n const lines: string[] = ['System Health:', '']\n\n const status = (data as Record<string, unknown>).status as string | undefined\n if (status) {\n const statusColor = status === 'healthy' ? colors.success(status) : colors.warning(status)\n lines.push(` Status: ${statusColor}`)\n }\n\n const services = (data as Record<string, unknown>).services as\n | Record<string, unknown>\n | undefined\n if (services) {\n lines.push('', ' Services:')\n for (const [name, info] of Object.entries(services)) {\n const svc = info as Record<string, unknown>\n const svcStatus = svc.status as string | undefined\n const statusStr = svcStatus\n ? svcStatus === 'healthy'\n ? colors.success(svcStatus)\n : colors.error(svcStatus)\n : colors.muted('unknown')\n lines.push(` ${name}: ${statusStr}`)\n }\n }\n\n return lines\n },\n },\n {\n name: 'settings',\n description: 'Show user settings',\n requires: 'auth',\n run: async (ctx) => {\n const { arbi } = ctx as AuthCommandContext\n const data = await settings.getSettings(arbi)\n const entries = Object.entries(data as Record<string, unknown>)\n\n if (entries.length === 0) return 'No settings configured.'\n\n const lines: string[] = ['User Settings:', '']\n for (const [key, value] of entries) {\n const display = typeof value === 'object' ? JSON.stringify(value) : String(value)\n lines.push(` ${colors.accent(key)}: ${display}`)\n }\n return lines\n },\n },\n]\n","/**\n * CitationPanel — overlay component for displaying citation passage details.\n *\n * Shows citation number, document title, page number, statement text,\n * and passage content. Used by the /cite command when showing a specific\n * citation in the TUI.\n */\n\nimport { Box, Text, Markdown } from '@mariozechner/pi-tui'\nimport type { ResolvedCitation } from '@arbidocs/sdk'\nimport { colors, markdownTheme } from '../theme/theme.js'\n\nconst MAX_PASSAGE_CHARS = 2000\n\nexport class CitationPanel extends Box {\n constructor(citation: ResolvedCitation, passageIndex = 0) {\n super(1, 1)\n\n const chunk = citation.chunks[passageIndex]\n const docTitle = chunk?.metadata?.doc_title ?? 'Unknown document'\n const page = chunk?.metadata?.page_number\n\n // Header line: [Citation N] Document Title\n const headerParts = [\n `${colors.accentBold(`[Citation ${citation.citationNum}]`)} ${colors.textBold(docTitle)}`,\n ]\n if (page != null) {\n headerParts.push(colors.muted(` Page ${page}`))\n }\n if (citation.chunks.length > 1) {\n headerParts.push(colors.muted(` Passage ${passageIndex + 1}/${citation.chunks.length}`))\n }\n this.addChild(new Text(headerParts.join(''), 0, 0))\n\n // Statement\n this.addChild(new Text('', 0, 0))\n this.addChild(new Text(colors.textBold('Statement:'), 0, 0))\n this.addChild(new Text(` ${citation.citationData.statement}`, 0, 0))\n\n // Passage content\n this.addChild(new Text('', 0, 0))\n this.addChild(new Text(colors.textBold('Passage:'), 0, 0))\n\n if (chunk) {\n let content = chunk.content\n if (content.length > MAX_PASSAGE_CHARS) {\n content = content.slice(0, MAX_PASSAGE_CHARS) + '\\n...(truncated)'\n }\n this.addChild(new Markdown(content, 0, 0, markdownTheme))\n } else {\n this.addChild(new Text(colors.muted(' (no passage data available)'), 0, 0))\n }\n\n // Navigation hints\n this.addChild(new Text('', 0, 0))\n const hints: string[] = []\n if (citation.chunks.length > 1) {\n hints.push(\n `/cite ${citation.citationNum} <1-${citation.chunks.length}> to view other passages`\n )\n }\n hints.push('Press Escape to close')\n this.addChild(new Text(colors.muted(hints.join(' · ')), 0, 0))\n }\n}\n","/**\n * Citation commands — /cite and /refs (hidden alias)\n *\n * Browse citations from the last assistant response.\n * /cite List all citation summaries\n * /cite N Show overlay with passage for citation N\n * /cite N P Show passage P of citation N (multi-chunk)\n */\n\nimport { resolveCitations, summarizeCitations, countCitations } from '@arbidocs/sdk'\nimport type { CommandDef, NoneCommandContext } from '../command-registry.js'\nimport { CitationPanel } from '../components/citation-panel.js'\nimport { colors } from '../theme/theme.js'\n\nfunction handleCite(ctx: NoneCommandContext): string | string[] | void {\n const { tui, args } = ctx\n\n if (!tui.lastMetadata) {\n return 'No citation data available. Ask a question first.'\n }\n\n const count = countCitations(tui.lastMetadata)\n if (count === 0) {\n return 'The last response contained no citations.'\n }\n\n const resolved = resolveCitations(tui.lastMetadata)\n\n // /cite N [P] — show overlay for specific citation\n if (args.length >= 1) {\n const citationNum = args[0]\n const citation = resolved.find((r) => r.citationNum === citationNum)\n if (!citation) {\n return `Citation [${citationNum}] not found. Use /cite to list all citations.`\n }\n\n // Optional passage index (1-based input, 0-based internal)\n let passageIndex = 0\n if (args.length >= 2) {\n const p = parseInt(args[1], 10)\n if (isNaN(p) || p < 1 || p > citation.chunks.length) {\n return `Passage must be between 1 and ${citation.chunks.length}.`\n }\n passageIndex = p - 1\n }\n\n const panel = new CitationPanel(citation, passageIndex)\n tui.showCitationOverlay(panel)\n return\n }\n\n // /cite — list all citation summaries\n const summaries = summarizeCitations(resolved)\n const lines: string[] = [`Citations (${summaries.length}):\\n`]\n\n for (const s of summaries) {\n const page = s.pageNumber != null ? `, p${s.pageNumber}` : ''\n const chunks = s.chunkCount > 1 ? ` (${s.chunkCount} passages)` : ''\n const truncated =\n s.statement.length > 100\n ? s.statement.slice(0, 100).replace(/\\n/g, ' ').trim() + '...'\n : s.statement.replace(/\\n/g, ' ').trim()\n\n lines.push(\n ` ${colors.accent(`[${s.citationNum}]`)} ${colors.textBold(s.docTitle)}${page}${chunks}`\n )\n lines.push(` ${colors.muted(truncated)}`)\n }\n\n lines.push(colors.muted('\\nUse /cite <N> to view full passage.'))\n return lines\n}\n\nexport const citationCommands: CommandDef[] = [\n {\n name: 'cite',\n description: 'Browse citations from last response',\n requires: 'none',\n argHint: '[N] [passage]',\n run: (ctx) => handleCite(ctx as NoneCommandContext),\n },\n {\n name: 'refs',\n description: 'Browse citations from last response',\n requires: 'none',\n hidden: true,\n run: (ctx) => handleCite(ctx as NoneCommandContext),\n },\n]\n","/**\n * /events — replay the persistent WS event log.\n *\n * The complement to ephemeral toasts. While the toast container\n * shows roughly the last 5–10 seconds of activity, ``tui.eventLog``\n * captures every WS event for the lifetime of the session.\n * ``/events`` dumps a slice of that buffer into the chat log so a\n * user can scroll back and answer \"what happened during this session?\"\n *\n * Usage:\n * /events — last 20 entries\n * /events all — every retained entry (capacity is 200)\n * /events errors — last 20 entries with level=error\n * /events <n> — last <n> entries (cap at the buffer size)\n *\n * Modeled on claude-code's persistent tool-call timeline and\n * openclaw's per-session event view.\n */\n\nimport type { CommandDef, NoneCommandContext } from '../command-registry.js'\nimport { formatEventLine, type WsEventLevel } from '../event-log.js'\nimport { colors } from '../theme/theme.js'\n\nconst DEFAULT_LIMIT = 20\n\n/** Parse one user-supplied positional arg into a ``getAll`` query.\n * Exported for tests — verifying the parsing without booting the\n * pi-tui dispatcher is cleaner than driving the full command. */\nexport function parseEventsArg(arg: string | undefined): {\n limit?: number\n level?: WsEventLevel\n} {\n if (!arg) return { limit: DEFAULT_LIMIT }\n const lower = arg.trim().toLowerCase()\n if (lower === 'all') return {}\n if (lower === 'errors' || lower === 'error') {\n return { limit: DEFAULT_LIMIT, level: 'error' }\n }\n if (lower === 'warnings' || lower === 'warning') {\n return { limit: DEFAULT_LIMIT, level: 'warning' }\n }\n const n = Number.parseInt(lower, 10)\n if (Number.isFinite(n) && n > 0) return { limit: n }\n // Unknown filter — be forgiving, fall back to default.\n return { limit: DEFAULT_LIMIT }\n}\n\nexport const eventCommands: CommandDef[] = [\n {\n name: 'events',\n description: 'Show recent WebSocket events (replaces toasts that scroll off)',\n argHint: 'count|all|errors',\n requires: 'none',\n run: (ctx) => {\n const { tui, args } = ctx as NoneCommandContext\n const query = parseEventsArg(args[0])\n const entries = tui.eventLog.getAll(query)\n\n if (entries.length === 0) {\n if (query.level) {\n return `No ${query.level} events recorded yet.`\n }\n return 'No WebSocket events recorded yet.'\n }\n\n const lines = entries.map((e) => {\n const line = formatEventLine(e)\n switch (e.level) {\n case 'error':\n return colors.error(line)\n case 'warning':\n return colors.warning(line)\n case 'success':\n return colors.success(line)\n default:\n return colors.muted(line)\n }\n })\n\n const header =\n query.level != null\n ? `Events (${entries.length}, level=${query.level}):`\n : `Events (${entries.length} of ${tui.eventLog.size} retained):`\n return [header, '', ...lines]\n },\n },\n]\n","/**\n * /view <doc-id> — read a document inside the TUI.\n *\n * The complement to ``/parsed`` (which truncates at 3000 chars). For\n * a RAG-first product, reading the source IS the workflow — you ask\n * a question, jump to a citation, then want to see the surrounding\n * pages. ``/view`` fetches the full parsed content and lays it out\n * in the chat-log scrollback as a sequence of clearly-separated\n * pages, with citation hits flagged page-by-page so users can scan\n * for \"where does this doc back up the answer?\".\n *\n * Sized to use the existing chat-log as the pager (the terminal's\n * native scrollback). A future iteration could promote this to a\n * full modal pager overlay with arrow-key page navigation; the\n * formatter below is built so the same renderer feeds either UI.\n *\n * Mirrors what claude-code does with ``/diff`` or ``/files`` —\n * cleanly-separated content blocks in the timeline, not a separate\n * window the user has to manage.\n */\n\nimport { documents, resolveCitations, type ResolvedCitation } from '@arbidocs/sdk'\nimport type { CommandDef, WorkspaceCommandContext } from '../command-registry.js'\nimport { colors } from '../theme/theme.js'\n\n/** A single rendered page of a document. ``pageNumber`` is the\n * 1-based index; ``content`` is the page's body text (already\n * trimmed); ``citationNums`` lists the citation indices in the\n * current conversation that landed on this page. */\nexport interface RenderedPage {\n pageNumber: number\n content: string\n citationNums: string[]\n}\n\n/** Hard cap on how many characters of a page we render inline. Long\n * pages still get the citation markers and a continuation hint, just\n * not the entire body — same trade-off ``/parsed`` makes but applied\n * per-page rather than once across the whole doc. */\nconst MAX_CHARS_PER_PAGE = 2000\n\n/** Split a parsed-content blob into pages.\n *\n * The marker pipeline emits ``\\n---\\n`` between pages by convention.\n * If that's not present (e.g. ``content`` is plain text from a TXT\n * upload) we fall back to splitting on form-feed (``\\f``) and\n * finally just treat the whole blob as a single page.\n *\n * Pure so it can be unit-tested without touching pi-tui or the SDK.\n */\nexport function splitIntoPages(content: string): string[] {\n if (!content) return []\n const trimmed = content.trim()\n if (!trimmed) return []\n\n // Try the dominant marker convention first.\n if (trimmed.includes('\\n---\\n')) {\n return trimmed\n .split(/\\n---\\n/)\n .map((p) => p.trim())\n .filter((p) => p.length > 0)\n }\n // PDFs that came through a different pipeline sometimes use form\n // feeds between pages.\n if (trimmed.includes('\\f')) {\n return trimmed\n .split('\\f')\n .map((p) => p.trim())\n .filter((p) => p.length > 0)\n }\n // Single page.\n return [trimmed]\n}\n\n/** Build the per-page citation index. Walks the citation set once\n * and groups by ``pageNumber``. Citations without a page number are\n * attributed to page 1 — they still exist, we just can't pin them\n * more precisely, and dropping them silently would mislead the\n * user about coverage. */\nexport function indexCitationsByPage(\n docId: string,\n citations: ResolvedCitation[]\n): Map<number, string[]> {\n const byPage = new Map<number, string[]>()\n for (const c of citations) {\n for (const chunk of c.chunks) {\n if (chunk.metadata?.doc_ext_id !== docId) continue\n const page = chunk.metadata?.page_number ?? 1\n const list = byPage.get(page) ?? []\n if (!list.includes(c.citationNum)) list.push(c.citationNum)\n byPage.set(page, list)\n }\n }\n return byPage\n}\n\n/** Compose the final rendered lines for the chat-log dump. Pure;\n * the command itself just calls this and hands the result to\n * ``showMessage``/``return``. */\nexport function renderDocView(opts: {\n docId: string\n title: string\n fileName: string | null\n pages: string[]\n citationsByPage: Map<number, string[]>\n}): string[] {\n const { docId, title, fileName, pages, citationsByPage } = opts\n const totalCitations = Array.from(citationsByPage.values()).reduce((n, ids) => n + ids.length, 0)\n\n const lines: string[] = []\n // Header: title + identity + breadth-first stats.\n lines.push(colors.textBold(title))\n if (fileName && fileName !== title) lines.push(colors.muted(fileName))\n lines.push(colors.muted(`${docId} — ${pages.length} page${pages.length === 1 ? '' : 's'}`))\n if (totalCitations > 0) {\n lines.push(\n colors.muted(\n `${totalCitations} citation${totalCitations === 1 ? '' : 's'} from the current conversation`\n )\n )\n }\n lines.push('')\n\n // Pages.\n for (let i = 0; i < pages.length; i++) {\n const pageNum = i + 1\n const cites = citationsByPage.get(pageNum)\n const citeBadge =\n cites && cites.length > 0 ? colors.accent(` [${cites.map((n) => `[${n}]`).join(' ')}]`) : ''\n lines.push(colors.accentBold(`── page ${pageNum} ──`) + citeBadge)\n\n const body = pages[i]!\n if (body.length > MAX_CHARS_PER_PAGE) {\n lines.push(body.slice(0, MAX_CHARS_PER_PAGE))\n lines.push(\n colors.muted(\n `… (${body.length - MAX_CHARS_PER_PAGE} more chars — use /parsed ${docId} for the raw stream)`\n )\n )\n } else {\n lines.push(body)\n }\n lines.push('')\n }\n\n return lines\n}\n\nexport const viewCommands: CommandDef[] = [\n {\n name: 'view',\n description: 'Read a document in the chat log, with citation hints per page',\n argHint: 'doc-id',\n minArgs: 1,\n requires: 'workspace',\n run: async (ctx) => {\n const { args, arbi, authHeaders, tui } = ctx as WorkspaceCommandContext\n const docId = args[0]!.trim()\n\n // Metadata for the header — title falls back to file_name if\n // the doc didn't get a parsed title (e.g. plain-text uploads).\n const [docs, parsed] = await Promise.all([\n documents.getDocuments(arbi, [docId]),\n documents.getParsedContent(authHeaders, docId, 'content'),\n ])\n const doc = docs[0]\n if (!doc) return `Document ${docId} not found.`\n const meta = doc.doc_metadata as { title?: string | null } | null\n const title = meta?.title ?? doc.file_name ?? docId\n\n const content = (parsed as { content?: string }).content ?? ''\n if (!content) return `No parsed content available for ${docId}.`\n\n const pages = splitIntoPages(content)\n\n // Citations from the current conversation that hit this doc —\n // gives the user immediate \"where does my answer come from on\n // this page?\" feedback.\n const citationsByPage = tui.lastMetadata\n ? indexCitationsByPage(docId, resolveCitations(tui.lastMetadata))\n : new Map<number, string[]>()\n\n return renderDocView({\n docId,\n title,\n fileName: doc.file_name ?? null,\n pages,\n citationsByPage,\n })\n },\n },\n]\n","/**\n * /sources — list every document referenced in the current\n * conversation, with citation indices and the pages they hit.\n *\n * The TUI's chat log is linear, so once you've asked several\n * questions it's easy to lose track of which docs have actually\n * backed up the discussion. ``/sources`` is the running answer to\n * \"what's in play right now?\" — modelled after Codex's task-side\n * panel but as a command for now (a layout-level sidebar can come\n * later). Combined with ``/view <doc-id>`` and Alt+N citation\n * hotkeys, this gives ARBI users a complete source-navigation\n * surface that the reference TUIs don't have (none of them have\n * citations in the first place).\n */\n\nimport type { CommandDef, NoneCommandContext } from '../command-registry.js'\nimport type { SourceEntry } from '../sources-index.js'\nimport { colors } from '../theme/theme.js'\n\n/** Format the index as the lines we'll print in the chat log. Pure\n * so the test suite can lock the shape without spinning up the TUI. */\nexport function renderSourcesList(entries: SourceEntry[]): string | string[] {\n if (entries.length === 0) {\n return 'No sources cited yet in this conversation. Ask a question first.'\n }\n\n const lines: string[] = [`Sources in this conversation (${entries.length}):`, '']\n\n for (const e of entries) {\n const cites = e.citationNums.map((n) => `[${n}]`).join(' ')\n const pages = e.pages.length > 0 ? ` p.${e.pages.join(', p.')}` : ''\n lines.push(` ${colors.accent(cites)} ${colors.textBold(e.title)}${pages}`)\n lines.push(` ${colors.muted(e.docId)}`)\n }\n\n lines.push('')\n lines.push(\n colors.muted('Use /view <doc-id> to read a source, or /cite N for a specific passage.')\n )\n return lines\n}\n\nexport const sourcesCommands: CommandDef[] = [\n {\n name: 'sources',\n description: 'List documents cited in this conversation',\n requires: 'none',\n run: (ctx) => {\n const { tui } = ctx as NoneCommandContext\n return renderSourcesList(tui.sourcesIndex.list())\n },\n },\n]\n","/**\n * /history — list and resume past conversations in this workspace.\n *\n * The TUI already auto-resumes the last conversation on launch (via\n * ``index.ts``'s session-restore path) but offers no way to jump to\n * any earlier one without restarting with a different ``session.json``\n * on disk. ``/history`` closes that gap:\n *\n * /history — list the most-recent conversations\n * /history all — list every conversation in this workspace\n * /resume <conv-id> — switch the active chat thread to that conv\n *\n * Mirrors claude-code's session list + ``/resume`` flow. The data\n * comes from the existing ``conversations.listConversations`` SDK\n * call (newest-first server-side), so this is mostly a presentation\n * layer over already-shipped server functionality.\n */\n\nimport { conversations } from '@arbidocs/sdk'\nimport type { CommandDef, WorkspaceCommandContext } from '../command-registry.js'\nimport { colors } from '../theme/theme.js'\n\nconst DEFAULT_LIMIT = 10\n\n/** Minimal projection of the conversation list rows we render. */\nexport interface HistoryRow {\n external_id: string\n title: string | null\n updated_at?: string | null\n message_count?: number\n}\n\n/** Format a single history line — pure so the test can lock the\n * shape independently of the SDK shape drift. */\nexport function formatHistoryLine(row: HistoryRow): string {\n const title = row.title?.trim() || colors.muted('(untitled)')\n const count = typeof row.message_count === 'number' ? ` · ${row.message_count} msg` : ''\n const when = row.updated_at ? ` · ${formatRelativeTime(row.updated_at)}` : ''\n return ` ${colors.accent(row.external_id)} ${title}${colors.muted(count + when)}`\n}\n\n/** Render an ISO timestamp as a coarse relative label (\"3m ago\",\n * \"yesterday\", \"Mar 5\"). Falls back to the raw date string if\n * parsing fails so we never show garbage. */\nexport function formatRelativeTime(iso: string, now = new Date()): string {\n const t = new Date(iso)\n if (Number.isNaN(t.getTime())) return iso\n const seconds = Math.floor((now.getTime() - t.getTime()) / 1000)\n if (seconds < 60) return 'just now'\n if (seconds < 3600) return `${Math.floor(seconds / 60)}m ago`\n if (seconds < 86400) return `${Math.floor(seconds / 3600)}h ago`\n if (seconds < 86400 * 2) return 'yesterday'\n if (seconds < 86400 * 7) return `${Math.floor(seconds / 86400)}d ago`\n // Older than a week — show a calendar-ish anchor instead of \"23d\n // ago\" which becomes unhelpful once you scroll past a few weeks.\n return t.toLocaleDateString(undefined, { month: 'short', day: 'numeric' })\n}\n\nexport const historyCommands: CommandDef[] = [\n {\n name: 'history',\n description: 'Browse past conversations',\n argHint: 'count|all',\n requires: 'workspace',\n run: async (ctx) => {\n const { arbi, args } = ctx as WorkspaceCommandContext\n const arg = args[0]?.trim().toLowerCase()\n const convs = (await conversations.listConversations(arbi)) as HistoryRow[]\n\n if (convs.length === 0) {\n return 'No conversations yet in this workspace. Ask a question to start one.'\n }\n\n // Slice to the user-requested window. Default: most-recent 10.\n const slice = arg === 'all' ? convs : convs.slice(0, parseLimit(arg) ?? DEFAULT_LIMIT)\n\n const lines: string[] = [\n `Conversations (${slice.length}${slice.length < convs.length ? ` of ${convs.length}` : ''}):`,\n '',\n ]\n for (const row of slice) lines.push(formatHistoryLine(row))\n lines.push('')\n lines.push(colors.muted('Use /resume <conv-id> to switch to one of these.'))\n return lines\n },\n },\n {\n name: 'resume',\n description: 'Switch to a past conversation by ID',\n argHint: 'conv-id',\n minArgs: 1,\n requires: 'workspace',\n run: async (ctx) => {\n const { args, arbi, tui } = ctx as WorkspaceCommandContext\n const convId = args[0]!.trim()\n\n // Pull the full thread so we can set ``lastMessageExtId`` to the\n // leaf for proper continuity, AND replay the messages into the\n // chat log so the user sees the context they're resuming into.\n // Same data path that ``index.ts`` uses on startup, just driven\n // by the user here.\n const data = (await conversations.getConversationThreads(arbi, convId)) as {\n threads?: Array<{\n leaf_message_ext_id?: string\n history?: { role: string; content: string }[]\n }>\n }\n const threadList = data.threads ?? []\n const primary = threadList[0]\n if (!primary?.leaf_message_ext_id) {\n return `Conversation ${convId} not found or has no messages.`\n }\n\n // Wipe the current chat log and replay this conversation's\n // history into it. Same convention used on startup-restore so\n // the visual result is identical.\n tui.chatLog.clearMessages()\n for (const msg of primary.history ?? []) {\n if (msg.role === 'user') tui.chatLog.addUser(msg.content)\n else if (msg.role === 'assistant') tui.chatLog.addAssistant(msg.content)\n }\n tui.chatLog.addSystem(`--- resumed conversation ${convId} ---`, 'info')\n\n // Threading state: subsequent ``ask`` requests will chain off\n // this leaf and the right ``conversation_ext_id``.\n tui.state.conversationMessageId = primary.leaf_message_ext_id\n tui.store.updateChatSession({\n lastMessageExtId: primary.leaf_message_ext_id,\n conversationExtId: convId,\n })\n\n // Sources index is conversation-scoped. The resumed conversation\n // has its own history of citations; we don't have an easy way to\n // reconstruct it without re-streaming, so clear and let the next\n // turn re-populate from there.\n tui.sourcesIndex.clear()\n tui.lastMetadata = null\n\n tui.requestRender()\n return `Resumed conversation ${convId}.`\n },\n },\n]\n\n/** Parse a numeric limit arg. Returns ``undefined`` on anything that\n * isn't a positive integer so the caller falls back to default. */\nfunction parseLimit(arg: string | undefined): number | undefined {\n if (!arg) return undefined\n const n = Number.parseInt(arg, 10)\n return Number.isFinite(n) && n > 0 ? n : undefined\n}\n","/**\n * /skills — list user-invocable skills in the active workspace\n * /skill view <slug> — print a skill's SKILL.md body in the chat log\n * /skill source <slug> — print the source doc ID for editing externally\n * /skill edit <slug> — pull SKILL.md, open in $EDITOR, re-upload if changed\n *\n * Companion to the autocomplete provider (see ``tui.ts`` —\n * ``refreshSkillsCache`` populates ``tui.skillsCache``) and the\n * inline pre-flight hint that surfaces a skill's description when\n * the editor opens it.\n *\n * Skills live entirely server-side; these commands never run skill\n * logic locally. ``/skills`` / ``/skill view`` / ``/skill source``\n * are pure read-side surfaces. ``/skill edit`` is the one write\n * path: it round-trips SKILL.md through the user's ``$EDITOR`` and\n * re-uploads the result with ``wp_type=skill`` so the backend's\n * frontmatter loader picks up the newest version.\n */\n\nimport { spawnSync } from 'node:child_process'\nimport { mkdtempSync, readFileSync, writeFileSync, rmSync, statSync } from 'node:fs'\nimport { tmpdir } from 'node:os'\nimport { join } from 'node:path'\nimport { assistant, documents } from '@arbidocs/sdk'\nimport type { CommandDef, WorkspaceCommandContext } from '../command-registry.js'\nimport { colors } from '../theme/theme.js'\nimport { runInteractiveFlow } from '../tui-helpers.js'\n\nexport const skillCommands: CommandDef[] = [\n {\n name: 'skills',\n description: 'List user-invocable skills in the active workspace',\n requires: 'workspace',\n run: async (ctx) => {\n const { arbi, tui } = ctx as WorkspaceCommandContext\n const list = await assistant.listSkills(arbi)\n\n // Keep the cache fresh while we're at it — saves a refetch on\n // the next ``/skills`` invocation and primes the autocomplete\n // hint surface.\n tui.skillsCache = list\n\n if (list.length === 0) {\n return [\n 'No skills in this workspace yet.',\n colors.muted(\n 'Skills are documents with wp_type=skill. Upload a SKILL.md with frontmatter ' +\n '(name, description, user-invocable: true) to add one.'\n ),\n ]\n }\n\n const lines: string[] = [`Skills (${list.length}):`, '']\n for (const s of list) {\n const argHint = s.arg_hint ? colors.muted(` ${s.arg_hint}`) : ''\n const typeBadge =\n s.skill_type && s.skill_type !== 'markdown' ? colors.muted(` [${s.skill_type}]`) : ''\n lines.push(` ${colors.accent('/' + s.slug)}${argHint}${typeBadge}`)\n if (s.description) {\n lines.push(` ${colors.muted(s.description)}`)\n }\n }\n lines.push('')\n lines.push(\n colors.muted('Use /skill view <slug> to read a skill, /skill source <slug> for its doc-id.')\n )\n return lines\n },\n },\n {\n name: 'skill',\n description: 'Inspect or edit a skill (view | source | edit) <slug>',\n argHint: 'subcommand slug',\n minArgs: 2,\n requires: 'workspace',\n run: async (ctx) => {\n const { args, arbi, tui } = ctx as WorkspaceCommandContext\n const [sub, slug, ...rest] = args\n if (sub !== 'view' && sub !== 'source' && sub !== 'edit') {\n return (\n `Unknown /skill subcommand \"${sub}\". ` +\n 'Use /skill view <slug>, /skill source <slug>, or /skill edit <slug>.'\n )\n }\n void rest // future-proof for additional args\n\n // Lookup against the cache when available, else refetch. The\n // cache is populated by ``refreshSkillsCache`` on workspace\n // change and by ``/skills`` invocation.\n const list = tui.skillsCache?.length\n ? tui.skillsCache\n : await assistant.listSkills(arbi, { includeHidden: true })\n const skill = list.find((s) => s.slug === slug || s.name === slug)\n if (!skill) {\n return `No skill matching \"${slug}\" in this workspace. Use /skills to list available skills.`\n }\n\n if (sub === 'source') {\n return [\n colors.textBold(`${skill.name} (${skill.slug})`),\n colors.muted(`doc-id: ${skill.doc_ext_id}`),\n colors.muted(`workspace: ${skill.workspace_ext_id}`),\n colors.muted(\n 'Use `arbi upload --folder skills/<slug>` to replace the SKILL.md, or edit it via the web app.'\n ),\n ]\n }\n\n const { authHeaders } = ctx as WorkspaceCommandContext\n\n if (sub === 'edit') {\n // Round-trip the SKILL.md through ``$EDITOR``. We don't run a\n // diff in the TUI — the backend versions documents by upload\n // order, so a no-op re-upload would still bump the timestamp\n // and confuse cache observers. mtime check is good enough:\n // if the file's modification time hasn't moved, the user\n // never wrote, so skip the upload.\n return await editSkill(tui, authHeaders, skill)\n }\n\n // sub === 'view' — fetch the SKILL.md body via document\n // download. The marker parsing pipeline (``getParsedContent``)\n // runs only for source documents; skills bypass it because the\n // SKILL.md *is* the body — no chunking, no embedding needed.\n const dlRes = await documents.downloadDocument(authHeaders, skill.doc_ext_id)\n const body = dlRes.ok ? await dlRes.text() : ''\n\n const lines: string[] = [colors.textBold(`${skill.name} (${skill.slug})`)]\n if (skill.description) lines.push(colors.muted(skill.description))\n if (skill.arg_hint) lines.push(colors.muted(`args: ${skill.arg_hint}`))\n lines.push(colors.muted(`type: ${skill.skill_type} doc: ${skill.doc_ext_id}`))\n lines.push('')\n lines.push(body)\n return lines\n },\n },\n]\n\n// ── /skill edit ────────────────────────────────────────────────────────────\n\n/**\n * Pulls the skill's SKILL.md body, drops it in a temp file, spawns\n * ``$EDITOR`` against it (TUI paused so the editor owns the terminal),\n * then re-uploads if the user actually wrote.\n *\n * Why not use ``arbi upload --folder skills/<slug>``? Same end result,\n * but this command means the user never has to leave the TUI for the\n * common iteration loop \"tweak a skill, retry it.\" That's why\n * ``/skill source`` still exists for the rare case of editing in a\n * heavier IDE.\n */\nasync function editSkill(\n tui: import('../tui.js').ArbiTui,\n authHeaders: { baseUrl: string; accessToken: string },\n skill: { slug: string; name: string; doc_ext_id: string }\n): Promise<string | string[]> {\n // 1. Download current body. Same path as /skill view — no marker\n // pipeline, just the raw file bytes the user uploaded.\n const dlRes = await documents.downloadDocument(authHeaders, skill.doc_ext_id)\n if (!dlRes.ok) {\n return `Failed to fetch skill body (HTTP ${dlRes.status}). Edit aborted.`\n }\n const original = await dlRes.text()\n\n // 2. Drop into a per-call temp dir so we can clean up the whole\n // directory afterwards without worrying about ENOENT on a sibling.\n const dir = mkdtempSync(join(tmpdir(), `arbi-skill-${skill.slug}-`))\n const path = join(dir, 'SKILL.md')\n writeFileSync(path, original, 'utf8')\n const mtimeBefore = statSync(path).mtimeMs\n\n // 3. Spawn $EDITOR with the TUI paused. ``runInteractiveFlow``\n // releases stdin/stdout, runs the action, then reclaims them.\n // Fallback editor order: $VISUAL → $EDITOR → ``vi``. Same order\n // git uses, so users with a configured editor get it for free.\n const editor = process.env.VISUAL || process.env.EDITOR || 'vi'\n\n const result = await runInteractiveFlow(\n tui,\n colors.muted(`Opening ${skill.slug}/SKILL.md in ${editor}…`),\n async () => {\n const child = spawnSync(editor, [path], { stdio: 'inherit' })\n if (child.error) throw child.error\n if (child.status !== 0 && child.status !== null) {\n throw new Error(`${editor} exited with status ${child.status}`)\n }\n return readFileSync(path, 'utf8')\n },\n `Skill edit (${skill.slug}) failed`\n )\n\n // 4. Decide whether to re-upload. The mtime check catches \"user\n // quit without saving\" cleanly even if they wrote the same bytes\n // (e.g. closed via :q in vi without ever entering insert mode).\n const mtimeAfter = (() => {\n try {\n return statSync(path).mtimeMs\n } catch {\n return mtimeBefore\n }\n })()\n\n // Snapshot the body for upload before we tear down the temp dir.\n const updated = result ?? original\n rmSync(dir, { recursive: true, force: true })\n\n if (result === null) {\n // ``runInteractiveFlow`` already surfaced the error toast.\n return []\n }\n if (mtimeAfter === mtimeBefore || updated === original) {\n return colors.muted(`No changes to ${skill.slug}/SKILL.md — skill unchanged.`)\n }\n\n // 5. Re-upload. The backend treats ``wp_type='skill'`` + the same\n // folder path as a versioning hint — newest wins on\n // ``SkillManager.load_skill``. We don't need to delete the old\n // doc; it stays around as history and the loader ignores it.\n const blob = new Blob([updated], { type: 'text/markdown' })\n await documents.uploadFile(authHeaders, blob, 'SKILL.md', {\n folder: `skills/${skill.slug}`,\n wpType: 'skill',\n })\n\n // Refresh the cache so the autocomplete / dispatcher see any\n // frontmatter edits (e.g. ``description`` change) on the next\n // keystroke. Otherwise the user has to ``/skills`` manually.\n await tui.refreshSkillsCache()\n\n return [\n colors.textBold(`Updated ${skill.name} (${skill.slug})`),\n colors.muted('Skill cache refreshed — new description and args take effect immediately.'),\n ]\n}\n","/**\n * Command barrel — imports all domain command arrays and registers them.\n */\n\nimport { registerCommands } from '../command-registry.js'\nimport { generalCommands } from './general.js'\nimport { authCommands } from './auth.js'\nimport { workspaceCommands } from './workspace.js'\nimport { documentCommands } from './document.js'\nimport { conversationCommands } from './conversation.js'\nimport { tagCommands } from './tag.js'\nimport { miscCommands } from './misc.js'\nimport { citationCommands } from './citation.js'\nimport { eventCommands } from './events.js'\nimport { viewCommands } from './view.js'\nimport { sourcesCommands } from './sources.js'\nimport { historyCommands } from './history.js'\nimport { skillCommands } from './skills.js'\n\n/** Register all commands with the global registry. Call once at startup. */\nexport function registerAllCommands(): void {\n registerCommands(generalCommands)\n registerCommands(authCommands)\n registerCommands(workspaceCommands)\n registerCommands(documentCommands)\n registerCommands(conversationCommands)\n registerCommands(tagCommands)\n registerCommands(miscCommands)\n registerCommands(citationCommands)\n registerCommands(eventCommands)\n registerCommands(viewCommands)\n registerCommands(sourcesCommands)\n registerCommands(historyCommands)\n registerCommands(skillCommands)\n}\n","/**\n * SSE streaming event handler — wires @arbidocs/sdk streaming\n * into TUI component updates.\n */\n\nimport {\n getErrorMessage,\n streamSSE,\n formatAgentStepLabel,\n formatStreamSummary,\n countCitations,\n type SSEStreamCallbacks,\n type SSEStreamResult,\n type AgentStepEvent,\n} from '@arbidocs/sdk'\nimport type { ArbiTui } from './tui.js'\nimport type { AgentStepDetails } from './components/agent-step.js'\n\n/**\n * Pull out structured tool details from an ``AgentStepEvent`` so the\n * chat log can render claude-code-style tool blocks (header + indented\n * tool / args / result lines) instead of a flat label.\n *\n * The backend's ``tool_progress`` events typically carry a single\n * ``detail`` entry shaped ``{ tool, label, message }``:\n * - ``tool`` — the tool name (e.g. ``retrieval_chunk``)\n * - ``label`` — already used as the step's headline by\n * ``formatAgentStepLabel``, so we don't repeat it\n * - ``message`` — a one-line summary, which we surface as either\n * ``args`` (when the step is starting) or ``result`` (when it's\n * finishing). We can't always tell the two apart from the wire\n * format, so for now we attribute it to ``args`` — which renders\n * as \"args: <message>\" beneath the header. Cleaner than dropping\n * it on the floor; we can split start/finish when the schema\n * gains a status field.\n */\nexport function extractStepDetails(data: AgentStepEvent): AgentStepDetails | undefined {\n const detail = data.detail as\n | Array<{ tool?: string; label?: string; message?: string }>\n | undefined\n if (!detail || detail.length === 0) return undefined\n const d = detail[0]\n if (!d) return undefined\n const result: AgentStepDetails = {}\n if (d.tool) result.tool = d.tool\n if (d.message) result.args = d.message\n return result.tool || result.args || result.result ? result : undefined\n}\n\n/**\n * Stream an assistant response from the API into the TUI.\n *\n * 1. Creates an assistant message in the chat log\n * 2. Streams tokens into it via SSE callbacks\n * 3. Displays agent steps as they arrive\n * 4. Finalizes when complete\n *\n * Returns the full SSE result for caller to extract metadata.\n */\nexport async function streamResponse(tui: ArbiTui, response: Response): Promise<SSEStreamResult> {\n tui.chatLog.startAssistant()\n tui.state.activityStatus = 'streaming'\n tui.requestRender()\n\n let accumulated = ''\n let elapsedTime: number | null = null\n let firstToken = true\n\n const callbacks: SSEStreamCallbacks = {\n onStreamStart: (data) => {\n if (data.assistant_message_ext_id) {\n tui.state.conversationMessageId = data.assistant_message_ext_id\n }\n },\n\n onToken: (content) => {\n if (firstToken) {\n firstToken = false\n tui.chatLog.clearActiveSteps()\n }\n accumulated += content\n tui.chatLog.updateAssistant(accumulated)\n tui.requestRender()\n },\n\n onAgentStep: (data) => {\n const label = formatAgentStepLabel(data)\n if (label) {\n tui.chatLog.addAgentStep(label, extractStepDetails(data))\n tui.requestRender()\n }\n },\n\n onElapsedTime: (t) => {\n elapsedTime = t\n },\n\n onError: (message) => {\n tui.chatLog.addSystem(`Stream error: ${message}`, 'error')\n tui.requestRender()\n },\n }\n\n try {\n const result = await streamSSE(response, callbacks)\n tui.chatLog.finalizeAssistant()\n\n // Store metadata for /cite command\n tui.lastMetadata = result.metadata ?? null\n\n // Fold this turn's citations into the conversation-wide sources\n // index so ``/sources`` can show the running list of documents\n // backing the discussion. Idempotent on the same metadata blob.\n tui.sourcesIndex.recordCitations(result.metadata)\n\n // Build summary with citation count\n const summary = formatStreamSummary(result, elapsedTime)\n if (summary) {\n const refs = countCitations(result.metadata ?? null)\n const refSuffix = refs > 0 ? ` · ${refs} ref${refs === 1 ? '' : 's'}` : ''\n tui.chatLog.addSummary(`[${summary}${refSuffix}]`)\n }\n\n tui.state.activityStatus = 'idle'\n tui.requestRender()\n return result\n } catch (err) {\n tui.chatLog.finalizeAssistant()\n tui.state.activityStatus = 'error'\n tui.chatLog.addSystem(`Streaming failed: ${getErrorMessage(err)}`, 'error')\n tui.requestRender()\n throw err\n }\n}\n","/**\n * DM handler — encryption setup, send/receive, channel switching.\n *\n * Manages the DM channel state and E2E encrypted messaging.\n * Uses the same ECDH encryption pattern as the React frontend.\n */\n\nimport { getErrorMessage, dm, contacts } from '@arbidocs/sdk'\nimport {\n base64ToBytes,\n deriveEncryptionKeypairFromSigning,\n encryptMessage,\n decryptMessage,\n type KeyPair,\n type WsNotificationResponse,\n} from '@arbidocs/client'\nimport type { ArbiTui } from './tui.js'\nimport { colors } from './theme/theme.js'\nimport { showMessage } from './tui-helpers.js'\n\n// ── Types ────────────────────────────────────────────────────────────────────\n\nexport interface DmContact {\n external_id: string\n email: string\n encryption_public_key: string\n given_name: string\n family_name?: string | null\n}\n\nexport interface DmChannel {\n user: DmContact\n}\n\n// ── Encryption keypair derivation ────────────────────────────────────────────\n\n/**\n * Derive X25519 encryption keypair from the stored Ed25519 signing key.\n * Called once after login.\n */\nexport function deriveEncryptionKeypair(signingPrivateKeyBase64: string): KeyPair {\n const signingPrivateKey = base64ToBytes(signingPrivateKeyBase64)\n // Ed25519 public key is the last 32 bytes of the 64-byte private key\n const ed25519PublicKey = signingPrivateKey.slice(32, 64)\n return deriveEncryptionKeypairFromSigning({\n publicKey: ed25519PublicKey,\n secretKey: signingPrivateKey,\n })\n}\n\n// ── Recipient resolution ─────────────────────────────────────────────────────\n\n/**\n * Resolve a @query to a contact user.\n * Matches by email prefix or given_name (case-insensitive).\n * Returns the matched contact user, or null if not found/ambiguous.\n */\nexport async function resolveRecipient(tui: ArbiTui, query: string): Promise<DmContact | null> {\n if (!tui.authContext) {\n showMessage(tui, 'Not authenticated. Use /login first.', 'error')\n return null\n }\n\n const queryLower = query.toLowerCase()\n\n try {\n const contactList = await contacts.listContacts(tui.authContext.arbi)\n\n // Filter for registered contacts with encryption keys\n const registered = contactList.filter(\n (c) => c.status === 'registered' && c.user?.encryption_public_key\n )\n\n // Match by email prefix (before @) or given_name\n const matches = registered.filter((c) => {\n const emailPrefix = c.email.split('@')[0]?.toLowerCase()\n const givenName = c.user?.given_name?.toLowerCase()\n return emailPrefix === queryLower || givenName === queryLower\n })\n\n if (matches.length === 0) {\n showMessage(\n tui,\n `No registered contact matching \"${query}\". Use /contacts to see available contacts.`,\n 'warning'\n )\n return null\n }\n\n if (matches.length > 1) {\n const names = matches\n .map((c) => ` ${c.email} (${c.user?.given_name ?? ''} ${c.user?.family_name ?? ''})`)\n .join('\\n')\n showMessage(tui, `Ambiguous match for \"${query}\". Be more specific:\\n${names}`, 'warning')\n return null\n }\n\n const contact = matches[0]\n const user = contact.user!\n return {\n external_id: user.external_id,\n email: contact.email,\n encryption_public_key: user.encryption_public_key,\n given_name: user.given_name,\n family_name: user.family_name,\n }\n } catch (err) {\n showMessage(tui, `Failed to resolve contact: ${getErrorMessage(err)}`, 'error')\n return null\n }\n}\n\n// ── Channel switching ────────────────────────────────────────────────────────\n\n/**\n * Handle @input — switch to DM channel or back to arbi.\n */\nexport async function handleChannelSwitch(tui: ArbiTui, input: string): Promise<void> {\n const query = input.slice(1).trim() // Remove leading @\n\n if (!query) {\n showMessage(tui, 'Usage: @username to switch to DM, @arbi to switch back.', 'warning')\n return\n }\n\n // @arbi — switch back to AI chat\n if (query.toLowerCase() === 'arbi') {\n switchToArbi(tui)\n return\n }\n\n // Resolve recipient\n const user = await resolveRecipient(tui, query)\n if (!user) return\n\n await switchToDmChannel(tui, user)\n}\n\n/**\n * Switch to a DM channel with a specific user.\n * Updates header, clears chat, loads DM history.\n */\nexport async function switchToDmChannel(tui: ArbiTui, user: DmContact): Promise<void> {\n if (!tui.authContext || !tui.encryptionKeys) {\n showMessage(tui, 'Not authenticated or encryption not initialized.', 'error')\n return\n }\n\n // Set channel state\n tui.currentDmChannel = { user }\n tui.updateHeader()\n\n // Clear chat log for DM view\n tui.chatLog.clearMessages()\n\n showMessage(tui, `Switched to DM with ${colors.accent(user.email)}. Type @arbi to switch back.`)\n\n // Fetch and display DM history\n await loadDmHistory(tui, user)\n}\n\n/**\n * Switch back to AI chat mode.\n */\nexport function switchToArbi(tui: ArbiTui): void {\n if (!tui.currentDmChannel) {\n showMessage(tui, 'Already in AI chat mode.', 'info')\n return\n }\n\n tui.currentDmChannel = null\n tui.updateHeader()\n\n // Clear chat log for fresh AI view\n tui.chatLog.clearMessages()\n showMessage(tui, 'Switched back to AI chat.')\n}\n\n// ── DM history ───────────────────────────────────────────────────────────────\n\n/**\n * Fetch all DMs and display the conversation with a specific user.\n */\nasync function loadDmHistory(tui: ArbiTui, user: DmContact): Promise<void> {\n if (!tui.authContext || !tui.encryptionKeys) return\n\n const myExtId = tui.authContext.loginResult.userExtId\n\n try {\n const allDms = await dm.listDMs(tui.authContext.arbi)\n\n // Filter for DMs between us and this user (type === 'user_message')\n const conversation = allDms.filter(\n (msg) =>\n msg.type === 'user_message' &&\n ((msg.sender.external_id === user.external_id && msg.recipient.external_id === myExtId) ||\n (msg.sender.external_id === myExtId && msg.recipient.external_id === user.external_id))\n )\n\n // Sort by created_at ascending\n conversation.sort((a, b) => new Date(a.created_at).getTime() - new Date(b.created_at).getTime())\n\n // Mark unread messages as read\n const unreadIds = conversation\n .filter((msg) => !msg.read && msg.sender.external_id === user.external_id)\n .map((msg) => msg.external_id)\n\n if (unreadIds.length > 0) {\n dm.markRead(tui.authContext.arbi, unreadIds).catch(() => {\n // Non-fatal — just log\n })\n }\n\n // Decrypt and display messages\n for (const msg of conversation) {\n const isSent = msg.sender.external_id === myExtId\n const plaintext = await decryptNotification(msg, myExtId!, tui.encryptionKeys, user)\n if (plaintext) {\n displayDmMessage(tui, plaintext, isSent, user.email)\n }\n }\n\n tui.requestRender()\n } catch (err) {\n showMessage(tui, `Failed to load DM history: ${getErrorMessage(err)}`, 'error')\n }\n}\n\n// ── Send encrypted DM ────────────────────────────────────────────────────────\n\n/**\n * Encrypt and send a DM to the current channel's recipient.\n */\nexport async function sendEncryptedDm(tui: ArbiTui, plaintext: string): Promise<void> {\n if (!tui.authContext || !tui.encryptionKeys || !tui.currentDmChannel) {\n showMessage(tui, 'Cannot send DM — not in a DM channel.', 'error')\n return\n }\n\n const recipient = tui.currentDmChannel.user\n\n try {\n // Encrypt the message\n const encrypted = await encryptMessage(\n plaintext,\n recipient.encryption_public_key,\n tui.encryptionKeys.secretKey\n )\n\n // Send via API\n await dm.sendDM(tui.authContext.arbi, [\n { recipient_ext_id: recipient.external_id, content: encrypted },\n ])\n\n // Display sent message in chat log\n displayDmMessage(tui, plaintext, true, recipient.email)\n tui.requestRender()\n } catch (err) {\n showMessage(tui, `Failed to send DM: ${getErrorMessage(err)}`, 'error')\n }\n}\n\n// ── Incoming DM handling (from WebSocket) ────────────────────────────────────\n\n/**\n * Handle an incoming WebSocket DM notification.\n * If we're in a DM channel with the sender, show it inline and return true.\n * Otherwise return false (caller shows toast).\n */\nexport async function handleIncomingDm(\n tui: ArbiTui,\n msg: WsNotificationResponse\n): Promise<boolean> {\n if (!tui.currentDmChannel || !tui.encryptionKeys || !tui.authContext) {\n return false\n }\n\n const myExtId = tui.authContext.loginResult.userExtId\n const channelUserId = tui.currentDmChannel.user.external_id\n\n // Check if this message is from the user we're chatting with\n if (msg.sender.external_id !== channelUserId) {\n return false\n }\n\n // Decrypt and display inline\n const plaintext = await decryptNotification(\n msg,\n myExtId!,\n tui.encryptionKeys,\n tui.currentDmChannel.user\n )\n\n if (plaintext) {\n displayDmMessage(tui, plaintext, false, msg.sender.email)\n tui.requestRender()\n\n // Mark as read\n dm.markRead(tui.authContext.arbi, [msg.external_id]).catch(() => {\n // Non-fatal\n })\n }\n\n return true\n}\n\n// ── Decryption helper ────────────────────────────────────────────────────────\n\n/**\n * Decrypt a notification's content field.\n *\n * For received messages: decrypt with sender's public key + our private key.\n * For sent messages: decrypt with recipient's public key + our private key.\n */\nasync function decryptNotification(\n notification: WsNotificationResponse,\n _myExtId: string,\n encryptionKeyPair: KeyPair,\n otherUser: DmContact\n): Promise<string | null> {\n if (!notification.content) return null\n\n try {\n // ECDH decryption uses the other party's public key in both cases\n return await decryptMessage(\n notification.content,\n otherUser.encryption_public_key,\n encryptionKeyPair.secretKey\n )\n } catch {\n return '[decryption failed]'\n }\n}\n\n// ── Display helper ───────────────────────────────────────────────────────────\n\n/**\n * Display a DM message in the chat log.\n * Sent messages show \"You:\", received show the sender's email.\n */\nfunction displayDmMessage(tui: ArbiTui, text: string, isSent: boolean, senderEmail: string): void {\n if (isSent) {\n tui.chatLog.addUser(text)\n } else {\n tui.chatLog.addDm(senderEmail, text)\n }\n}\n","/**\n * WebSocket handler — routes incoming WS messages to two surfaces:\n *\n * 1. ``tui.eventLog`` — **always** recorded. The persistent\n * scrollback that ``/events`` replays. Nothing is dropped here so\n * a session can be reviewed end-to-end after the fact.\n *\n * 2. ``ToastContainer`` — **only the important ones**. Errors and\n * terminal task statuses (completed/failed) pop a toast for\n * immediate visibility. Routine traffic (presence pings,\n * in-progress updates) only goes into the log, mirroring the\n * claude-code policy of \"every event is captured, only\n * noteworthy ones interrupt\".\n *\n * Uses ``connectWithReconnect()`` and ``formatWsMessage()`` from\n * the SDK for connection/auth + shared formatting.\n */\n\nimport {\n connectWithReconnect,\n formatWsMessage,\n type ReconnectableWsConnection,\n} from '@arbidocs/sdk'\nimport { type WebSocketServerMessage, type WsNotificationResponse } from '@arbidocs/client'\nimport type { ArbiTui } from './tui.js'\nimport type { ToastContainer, ToastLevel } from './components/toast-container.js'\nimport { handleIncomingDm } from './dm-handler.js'\nimport type { WsEventLog, WsEventLevel } from './event-log.js'\n\n// ── Duration constants ────────────────────────────────────────────────────────\n\nconst DURATION_SHORT = 3000 // frequent in-progress updates\nconst DURATION_DEFAULT = 5000 // completed tasks, batch, notifications\nconst DURATION_LONG = 8000 // errors — longer so user notices\n\n// ── Duration mapping by level ────────────────────────────────────────────────\n\nconst DURATION_BY_LEVEL: Record<string, number> = {\n info: DURATION_SHORT,\n success: DURATION_DEFAULT,\n error: DURATION_LONG,\n warning: DURATION_DEFAULT,\n}\n\n// ── Helpers ──────────────────────────────────────────────────────────────────\n\n/** NotificationResponse uses NotificationType as its `type` field, not a single literal. */\nfunction isNotification(msg: WebSocketServerMessage): msg is WsNotificationResponse {\n return 'sender' in msg && 'recipient' in msg\n}\n\n// ── Message routing ───────────────────────────────────────────────────────────\n\n/** Decide whether a given message should ALSO pop a toast on top of\n * being logged. The rules are conservative: only pop on terminal\n * states (success/error/warning) and ``response_complete`` /\n * ``batch_complete`` which represent finished long-running work.\n * Routine ``info`` traffic (presence pings, in-progress updates)\n * stays in the log only — visible in ``/events`` but not flashing in\n * the user's face. */\nfunction shouldToast(level: WsEventLevel, msgType: string | undefined): boolean {\n if (level === 'error' || level === 'warning' || level === 'success') return true\n // Terminal completions on the info path (rare, but possible).\n if (msgType === 'response_complete' || msgType === 'batch_complete') return true\n return false\n}\n\nasync function handleMessage(\n msg: WebSocketServerMessage,\n toasts: ToastContainer,\n eventLog: WsEventLog,\n tui: ArbiTui | null\n): Promise<void> {\n // DM routing — TUI-specific: route user_message to the DM chat log.\n // DMs are first-class chat content and intentionally bypass both\n // the toast and the event log (the chat log itself is the persistent\n // surface for them).\n if (isNotification(msg) && msg.type === 'user_message' && tui) {\n const handled = await handleIncomingDm(tui, msg)\n if (handled) return\n }\n\n // Use shared formatter for text + level. Stable across CLI/TUI so\n // both surfaces agree on what a given event means.\n const { text, level } = formatWsMessage(msg)\n const msgType = (msg as { type?: string }).type\n eventLog.add({ text, level: level as WsEventLevel, msgType })\n\n if (shouldToast(level as WsEventLevel, msgType)) {\n const duration = DURATION_BY_LEVEL[level] ?? DURATION_DEFAULT\n toasts.show(text, level as ToastLevel, duration)\n }\n}\n\n// ── Public API ────────────────────────────────────────────────────────────────\n\nexport interface TuiWsOptions {\n baseUrl: string\n accessToken: string\n toasts: ToastContainer\n eventLog: WsEventLog\n tui?: ArbiTui\n}\n\n/**\n * Connect WebSocket with auto-reconnection and route messages to both\n * the persistent event log and (selectively) the toast container.\n * Returns the connection handle for cleanup, or null on failure.\n */\nexport async function connectTuiWebSocket(\n options: TuiWsOptions\n): Promise<ReconnectableWsConnection | null> {\n const { baseUrl, accessToken, toasts, eventLog, tui } = options\n\n // Transport-level events (connect/disconnect/reconnect) are always\n // worth surfacing because they affect the user's ability to do\n // anything else. So they get both log + toast, not the routine\n // filter.\n const recordTransport = (text: string, level: WsEventLevel): void => {\n eventLog.add({ text, level })\n const duration = DURATION_BY_LEVEL[level] ?? DURATION_DEFAULT\n toasts.show(text, level as ToastLevel, duration)\n }\n\n try {\n const connection = await connectWithReconnect({\n baseUrl,\n accessToken,\n onMessage: (msg) => handleMessage(msg, toasts, eventLog, tui ?? null),\n onClose: () => recordTransport('WebSocket disconnected', 'warning'),\n onReconnecting: (attempt, maxRetries) =>\n recordTransport(`Reconnecting... (${attempt}/${maxRetries})`, 'warning'),\n onReconnected: () => recordTransport('WebSocket reconnected', 'success'),\n onReconnectFailed: () => recordTransport('WebSocket reconnection failed', 'error'),\n })\n return connection\n } catch {\n // Auth failure or connection error — not fatal, just skip WS\n recordTransport('WebSocket connection failed', 'warning')\n return null\n }\n}\n","/**\n * ArbiTui — main orchestrator for the ARBI terminal UI.\n *\n * Manages state, component wiring, and lifecycle. Coordinates between\n * the editor input, chat log display, command dispatch, and SSE streaming.\n */\n\nimport {\n TUI,\n ProcessTerminal,\n Text,\n Spacer,\n CombinedAutocompleteProvider,\n matchesKey,\n Key,\n type Component,\n type OverlayHandle,\n} from '@mariozechner/pi-tui'\nimport {\n type AuthContext,\n type WorkspaceContext,\n type ReconnectableWsConnection,\n type ConfigStore,\n type MessageMetadataPayload,\n type SkillSummary,\n getErrorMessage,\n assistant,\n documents,\n countCitations,\n parseSlashCommand,\n} from '@arbidocs/sdk'\nimport type { KeyPair } from '@arbidocs/client'\nimport { ChatLog } from './components/chat-log.js'\nimport { WsEventLog } from './event-log.js'\nimport { SourcesIndex } from './sources-index.js'\nimport { ArbiEditor } from './components/arbi-editor.js'\nimport { ToastContainer } from './components/toast-container.js'\nimport { dispatchCommand, toSlashCommands, toSlashCommandsWithSkills } from './command-registry.js'\nimport { registerAllCommands } from './commands/index.js'\nimport { streamResponse } from './event-handlers.js'\nimport { connectTuiWebSocket } from './ws-handler.js'\nimport {\n type DmChannel,\n deriveEncryptionKeypair,\n handleChannelSwitch,\n sendEncryptedDm,\n} from './dm-handler.js'\nimport { colors, formatHeader } from './theme/theme.js'\nimport { showMessage } from './tui-helpers.js'\n\n// ── State ──────────────────────────────────────────────────────────────────\n\nexport interface TuiState {\n workspaceId: string | null\n workspaceName: string | null\n conversationMessageId: string | null\n activityStatus: 'idle' | 'sending' | 'streaming' | 'error'\n isAuthenticated: boolean\n}\n\n// ── Main TUI class ─────────────────────────────────────────────────────────\n\nexport class ArbiTui {\n private tui: TUI\n private header: Text\n\n /** The chat message log — public so command handlers can add messages. */\n readonly chatLog: ChatLog\n\n /** Toast notifications from WebSocket events. */\n readonly toastContainer: ToastContainer\n\n /** The input editor. */\n private editor: ArbiEditor\n\n /** Application state — public so handlers can read/write it. */\n state: TuiState\n\n /** Auth context from @arbidocs/sdk — set during init. */\n authContext: AuthContext | null = null\n\n /** Workspace context with tokens/headers — set when workspace is selected. */\n private workspaceContext: WorkspaceContext | null = null\n\n /** Config store for persistence. */\n readonly store: ConfigStore\n\n /** Active WebSocket connection (null when not connected). */\n private wsConnection: ReconnectableWsConnection | null = null\n\n /** X25519 encryption keypair derived from signing key (null until login). */\n private encryptionKeyPair: KeyPair | null = null\n\n /** Current DM channel (null = AI chat mode). */\n private dmChannel: DmChannel | null = null\n\n /** Last response metadata — used by /cite for citation browsing. */\n lastMetadata: MessageMetadataPayload | null = null\n\n /** Persistent log of WebSocket events for this session. Toasts are\n * ephemeral; this is the \"what happened?\" scrollback that\n * ``/events`` reads from. Public so ws-handler can append and the\n * events command can read. */\n readonly eventLog = new WsEventLog()\n\n /** Running tally of documents cited in the current conversation.\n * Cleared on ``/new``; appended to after every assistant response\n * that carries citation metadata. Drives ``/sources`` and (later)\n * the persistent right-side sources panel. */\n readonly sourcesIndex = new SourcesIndex()\n\n /** Cached list of user-invocable skills in the active workspace.\n * Refreshed on workspace switch (``setWorkspaceContext``) and\n * invalidated to ``[]`` when leaving a workspace. Drives the\n * autocomplete provider and the ``/skills`` / ``/skill view``\n * commands. ``null`` means \"haven't fetched yet\"; ``[]`` means\n * \"fetched, no skills exist\". */\n skillsCache: SkillSummary[] = []\n\n /** Active citation overlay handle (null when not showing). */\n private citationOverlay: OverlayHandle | null = null\n\n /** Input listener ID for overlay dismiss (null when no overlay). */\n private overlayInputListener: (() => void) | null = null\n\n constructor(store: ConfigStore) {\n this.store = store\n\n this.state = {\n workspaceId: null,\n workspaceName: null,\n conversationMessageId: null,\n activityStatus: 'idle',\n isAuthenticated: false,\n }\n\n // Register all slash commands with the declarative registry\n registerAllCommands()\n\n // Build TUI component tree\n this.tui = new TUI(new ProcessTerminal())\n\n // Header\n this.header = new Text(formatHeader(null, 'starting...'), 1, 0)\n\n // Chat log\n this.chatLog = new ChatLog()\n\n // Toast container for WebSocket notifications\n this.toastContainer = new ToastContainer()\n this.toastContainer.setRenderCallback(() => this.tui.requestRender())\n\n // Editor\n this.editor = this.createEditor()\n\n // Compose layout\n this.tui.addChild(this.header)\n this.tui.addChild(new Spacer(1))\n this.tui.addChild(this.toastContainer)\n this.tui.addChild(this.chatLog)\n this.tui.addChild(this.editor)\n\n this.tui.setFocus(this.editor)\n }\n\n // ── Lifecycle ──────────────────────────────────────────────────────────\n\n /** Start the TUI event loop (clears screen for fullscreen layout). */\n start(): void {\n this.tui.start()\n this.updateHeader()\n this.tui.requestRender(true)\n }\n\n /** Gracefully shut down the TUI and exit. */\n shutdown(): void {\n this.wsConnection?.close()\n this.wsConnection = null\n this.toastContainer.clear()\n this.tui.stop()\n process.exit(0)\n }\n\n /**\n * Temporarily stop the TUI (releases terminal raw mode).\n * Used before interactive prompts that need stdin (login, register).\n */\n stopTui(): void {\n this.tui.stop()\n }\n\n /**\n * Restart the TUI after a stopTui() call.\n * Rebuilds the component tree with a fresh TUI instance since\n * pi-tui doesn't support stop/start cycling on the same instance.\n */\n restartTui(): void {\n this.tui = new TUI(new ProcessTerminal())\n\n // Re-compose layout\n this.tui.addChild(this.header)\n this.tui.addChild(new Spacer(1))\n this.tui.addChild(this.toastContainer)\n this.tui.addChild(this.chatLog)\n\n // Create new editor (needs fresh TUI reference)\n this.editor = this.createEditor()\n this.tui.addChild(this.editor)\n this.tui.setFocus(this.editor)\n\n this.tui.start()\n this.updateHeader()\n this.tui.requestRender(true)\n }\n\n /** Create and wire a new editor instance. */\n private createEditor(): ArbiEditor {\n const editor = new ArbiEditor(this.tui)\n // pi-tui's ``CombinedAutocompleteProvider`` now requires\n // ``basePath`` (cwd for file-completion) alongside the command\n // list. The TUI doesn't lean on file completions, so the process\n // cwd is the right neutral default.\n editor.setAutocompleteProvider(\n new CombinedAutocompleteProvider(toSlashCommands(), process.cwd())\n )\n editor.onSubmit = (text: string) => this.handleSubmit(text)\n editor.onEscape = () => this.handleAbort()\n editor.onCtrlC = () => this.shutdown()\n editor.onCtrlD = () => this.shutdown()\n editor.onCtrlW = () => this.handleSubmit('/workspaces')\n editor.onCtrlN = () => this.handleSubmit('/new')\n // Alt+1..9 jumps straight to citation N. The ``/cite`` command\n // already handles \"no citations available\" / \"citation not found\"\n // messaging, so we just route the keypress through the same code\n // path the user would have typed.\n editor.onCitationKey = (n: number) => this.handleSubmit(`/cite ${n}`)\n // Pre-flight skill hint. Fires every time the buffer changes;\n // ``handleBufferChange`` self-dedupes so the chat log doesn't\n // get spammed when the user is still typing the same slug.\n editor.onBufferChange = (text: string) => this.handleBufferChange(text)\n return editor\n }\n\n /** The slug we last surfaced as a pre-flight hint. ``null`` once\n * the user has navigated away from the skill prefix (e.g. typed a\n * non-slash char first, or deleted past the slash). Tracking this\n * here — not in the editor — keeps the editor pure: it just emits\n * text, the TUI decides what's interesting. */\n private lastHintedSlug: string | null = null\n\n /**\n * Pre-flight skill hint dispatcher.\n *\n * Watches the editor buffer; when it starts with ``/<token>`` where\n * ``<token>`` is a slug in ``skillsCache`` *and* not also a static\n * command (those have their own ``--help`` style help), we drop a\n * one-line description into the chat log so the user sees what\n * they're about to invoke before pressing Enter. Equivalent of\n * claude-code's slash-command palette preview, minus the modal.\n *\n * Dedup rule: only emit when the matched slug *changes*. Typing\n * \"/foo\" → \"/foob\" → \"/foo\" emits once for ``foo``, never for the\n * intermediate ``foob`` (no match), and not again when the user\n * lands back on ``foo``. The state resets whenever the buffer no\n * longer matches anything, so a fresh ``/foo`` after a clear emits\n * the hint again.\n */\n private handleBufferChange(text: string): void {\n // Canonical parse — same helper the React menu and TUI dispatcher\n // use. ``parseSlashCommand`` returns ``null`` for non-slash\n // buffers, including empty input, so the early-return covers all\n // the \"user isn't typing a slash command\" cases in one branch.\n const parsed = parseSlashCommand(text)\n if (!parsed) {\n this.lastHintedSlug = null\n return\n }\n const slug = parsed.slug\n\n // Static commands win — they have their own help surface\n // (``/help``), so showing skill metadata for a same-named slug\n // would be the wrong thing. The autocomplete merge in\n // ``toSlashCommandsWithSkills`` applies the same rule.\n if (this.skillsCache.length === 0) return\n const skill = this.skillsCache.find((s) => s.slug === slug)\n if (!skill) {\n this.lastHintedSlug = null\n return\n }\n if (this.lastHintedSlug === slug) return\n this.lastHintedSlug = slug\n\n const argHint = skill.arg_hint ? ` ${skill.arg_hint}` : ''\n showMessage(this, `Skill: /${skill.slug}${argHint} — ${skill.description}`, 'info')\n }\n\n /** Request a render update. */\n requestRender(): void {\n this.tui.requestRender()\n }\n\n // ── Auth / Workspace ───────────────────────────────────────────────────\n\n /** Set authentication context after login. */\n setAuthContext(ctx: AuthContext): void {\n this.authContext = ctx\n this.state.isAuthenticated = true\n this.encryptionKeyPair = deriveEncryptionKeypair(\n this.store.requireCredentials().signingPrivateKeyBase64\n )\n this.updateHeader()\n }\n\n /** Set workspace context after workspace selection. */\n setWorkspaceContext(ctx: WorkspaceContext): void {\n this.workspaceContext = ctx\n this.state.workspaceId = ctx.workspaceId\n // Workspace name will be set separately since WorkspaceContext doesn't include it\n this.updateHeader()\n this.connectWebSocket()\n // Best-effort refresh of the skills cache so autocomplete picks\n // up workspace-specific skills. Failures are swallowed — skills\n // are an aid, not a critical path; absence falls back to the\n // static slash-command list.\n void this.refreshSkillsCache()\n }\n\n /** Refresh the cached skills list for the current workspace. Called\n * on workspace switch and from ``/skills`` itself so a freshly\n * uploaded skill becomes invocable without a TUI restart. */\n async refreshSkillsCache(): Promise<void> {\n if (!this.workspaceContext) {\n this.skillsCache = []\n this.rebuildAutocomplete()\n return\n }\n try {\n this.skillsCache = await assistant.listSkills(this.workspaceContext.arbi)\n } catch {\n // Older backends without the endpoint will 404 — autocomplete\n // simply won't surface skills until the backend ships\n // ``GET /v1/assistant/skills``. Not a failure.\n this.skillsCache = []\n }\n this.rebuildAutocomplete()\n }\n\n /** Re-feed the editor's autocomplete provider with the merged\n * static-commands + skills list. Called on workspace switch and\n * after every ``refreshSkillsCache`` so a newly uploaded skill\n * appears in tab-complete without a TUI restart. */\n private rebuildAutocomplete(): void {\n if (!this.editor) return\n const merged = toSlashCommandsWithSkills(\n this.skillsCache.map((s) => ({ slug: s.slug, description: s.description }))\n )\n this.editor.setAutocompleteProvider(new CombinedAutocompleteProvider(merged, process.cwd()))\n }\n\n /** Refresh workspace context (after switching workspaces). */\n async refreshWorkspaceContext(): Promise<void> {\n if (!this.state.workspaceId || !this.authContext) return\n\n const { resolveWorkspace } = await import('@arbidocs/sdk')\n const ctx = await resolveWorkspace(this.store, this.state.workspaceId)\n this.workspaceContext = ctx\n this.updateHeader()\n }\n\n /** Public accessor for workspace context (used by command handlers). */\n get wsContext(): WorkspaceContext | null {\n return this.workspaceContext\n }\n\n /** Whether the WebSocket is currently connected. */\n get wsConnected(): boolean {\n return this.wsConnection !== null\n }\n\n /** Connect (or reconnect) WebSocket for real-time notifications. */\n private connectWebSocket(): void {\n if (!this.workspaceContext) return\n\n // Close existing connection before reconnecting\n this.wsConnection?.close()\n this.wsConnection = null\n\n const { config, accessToken } = this.workspaceContext\n\n connectTuiWebSocket({\n baseUrl: config.baseUrl,\n accessToken,\n toasts: this.toastContainer,\n eventLog: this.eventLog,\n tui: this,\n }).then((conn) => {\n this.wsConnection = conn\n })\n }\n\n // ── Input handling ─────────────────────────────────────────────────────\n\n private async handleSubmit(text: string): Promise<void> {\n const trimmed = text.trim()\n if (!trimmed) return\n\n // Check for @channel switching\n if (trimmed.startsWith('@')) {\n await handleChannelSwitch(this, trimmed)\n return\n }\n\n // Check for slash commands\n if (trimmed.startsWith('/')) {\n const handled = await dispatchCommand(this, trimmed)\n if (handled) return\n }\n\n // Route to DM or AI based on channel\n if (this.dmChannel) {\n await sendEncryptedDm(this, trimmed)\n } else {\n await this.sendMessage(trimmed)\n }\n }\n\n private handleAbort(): void {\n if (this.state.activityStatus === 'streaming') {\n // TODO: implement AbortController for stream cancellation\n this.chatLog.addSystem('Abort requested (stream will complete current chunk).', 'warning')\n this.requestRender()\n }\n }\n\n // ── Messaging ──────────────────────────────────────────────────────────\n\n private async sendMessage(question: string): Promise<void> {\n if (!this.workspaceContext) {\n this.chatLog.addSystem(\n 'No workspace selected. Use /workspace <id> or /workspaces to choose one.',\n 'warning'\n )\n this.requestRender()\n return\n }\n\n // Display user message\n this.chatLog.addUser(question)\n this.state.activityStatus = 'sending'\n this.updateHeader()\n this.requestRender()\n\n try {\n // Get all docs in workspace for retrieval context\n const docs = await documents.listDocuments(this.workspaceContext.arbi)\n const docIds = docs.map((d) => d.external_id as string)\n\n // Load chat session for conversation threading\n const session = this.store.getChatSession()\n const previousResponseId = this.state.conversationMessageId ?? session.lastMessageExtId\n\n // Query the assistant\n const response = await assistant.queryAssistant({\n baseUrl: this.workspaceContext.config.baseUrl,\n accessToken: this.workspaceContext.accessToken,\n workspaceId: this.workspaceContext.workspaceId,\n question,\n docIds,\n previousResponseId,\n })\n\n // Stream the response into the chat log\n const result = await streamResponse(this, response)\n\n // Citation hotkey hint — after each response that has citations,\n // remind the user they can jump straight to a passage with\n // ``Alt+N`` instead of typing ``/cite N``. We compute the count\n // off ``tui.lastMetadata`` which ``streamResponse`` has already\n // populated. Capped at 9 because that's all Alt+1..9 covers; if\n // there are more, the user falls back to ``/cite N``.\n if (this.lastMetadata) {\n const n = countCitations(this.lastMetadata)\n if (n > 0) {\n const cap = Math.min(n, 9)\n const label =\n n <= 9\n ? `${n} citation${n === 1 ? '' : 's'} available`\n : `${n} citations — Alt+1..9 jumps to the first 9; /cite N for the rest`\n this.chatLog.addSystem(`${label} — press Alt+1..${cap} to view`, 'info')\n }\n }\n\n // Save conversation state for threading and history restoration\n if (result.assistantMessageExtId) {\n this.state.conversationMessageId = result.assistantMessageExtId\n const sessionUpdate: Record<string, string> = {\n lastMessageExtId: result.assistantMessageExtId,\n }\n // Extract conversation ID from user_message or metadata\n const conversationExtId =\n (result.userMessage?.conversation_ext_id as string) ??\n (result.metadata?.conversation_ext_id as string)\n if (conversationExtId) {\n sessionUpdate.conversationExtId = conversationExtId\n }\n this.store.updateChatSession(sessionUpdate)\n }\n } catch (err) {\n this.state.activityStatus = 'error'\n this.chatLog.addSystem(`Error: ${getErrorMessage(err)}`, 'error')\n }\n\n this.state.activityStatus = 'idle'\n this.updateHeader()\n this.requestRender()\n }\n\n // ── UI Updates ─────────────────────────────────────────────────────────\n\n /** Update the header bar — public so dm-handler can call it. */\n updateHeader(): void {\n const statusText =\n this.state.activityStatus === 'idle'\n ? colors.success('ready')\n : this.state.activityStatus === 'streaming'\n ? colors.warning('streaming...')\n : this.state.activityStatus === 'sending'\n ? colors.warning('sending...')\n : colors.error('error')\n\n if (this.dmChannel) {\n this.header.setText(formatHeader(`DM: ${this.dmChannel.user.email}`, statusText))\n } else {\n this.header.setText(formatHeader(this.state.workspaceName, statusText))\n }\n }\n\n // ── Citation overlay ───────────────────────────────────────────────────\n\n /** Show a component as a centered overlay (used by /cite). */\n showCitationOverlay(component: Component): void {\n this.dismissCitationOverlay()\n\n this.citationOverlay = this.tui.showOverlay(component, {\n anchor: 'center',\n width: '80%',\n maxHeight: '80%',\n margin: 2,\n })\n\n // Listen for Escape to dismiss (consume the keypress so editor doesn't see it)\n this.overlayInputListener = this.tui.addInputListener((data: string) => {\n if (matchesKey(data, Key.escape)) {\n this.dismissCitationOverlay()\n return { consume: true }\n }\n return undefined\n })\n\n this.tui.requestRender()\n }\n\n /** Dismiss the active citation overlay. */\n dismissCitationOverlay(): void {\n if (this.citationOverlay) {\n this.citationOverlay.hide()\n this.citationOverlay = null\n }\n if (this.overlayInputListener) {\n this.overlayInputListener()\n this.overlayInputListener = null\n }\n this.tui.requestRender()\n }\n\n // ── DM channel accessors (used by dm-handler) ────────────────────────────\n\n /** Current DM channel (null = AI chat mode). */\n get currentDmChannel(): DmChannel | null {\n return this.dmChannel\n }\n\n set currentDmChannel(ch: DmChannel | null) {\n this.dmChannel = ch\n }\n\n /** Encryption keypair for E2E DM encryption. */\n get encryptionKeys(): KeyPair | null {\n return this.encryptionKeyPair\n }\n}\n","/**\n * ARBI TUI — entry point\n *\n * Handles CLI argument parsing, authentication, and TUI launch.\n * Uses @arbidocs/sdk for auth and config, pi-tui for rendering.\n *\n * If not authenticated, offers interactive login/register before launching.\n *\n * Usage:\n * arbi-tui # Launch with default workspace\n * arbi-tui -w <workspace-id> # Launch with specific workspace\n */\n\n// Suppress SDK middleware logging\nconsole.debug = () => {}\nconst _origInfo = console.info\nconsole.info = (...args: unknown[]) => {\n if (typeof args[0] === 'string' && args[0].startsWith('[API]')) return\n _origInfo(...args)\n}\n\nimport { Command } from 'commander'\nimport {\n FileConfigStore,\n getErrorMessage,\n resolveWorkspace,\n workspaces,\n conversations,\n} from '@arbidocs/sdk'\nimport { ArbiTui } from './tui.js'\nimport { ensureAuthenticated } from './auth.js'\n\nconst program = new Command()\n\nprogram\n .name('arbi-tui')\n .description('Interactive terminal UI for ARBI — chat with the RAG assistant')\n .version('0.1.0')\n .option('-w, --workspace <id>', 'Workspace ID to use')\n .action(async (opts: { workspace?: string }) => {\n const store = new FileConfigStore()\n\n // Ensure config exists\n try {\n store.requireConfig()\n } catch {\n console.error('Not configured. Run `arbi config set-url <url>` first.')\n process.exit(1)\n }\n\n // Authenticate — offers login/register if not already authenticated\n const { authContext, selectedWorkspaceId, selectedWorkspaceName } =\n await ensureAuthenticated(store)\n\n // Resolve workspace\n const workspaceId = opts.workspace || selectedWorkspaceId\n\n // Create and start TUI\n const tui = new ArbiTui(store)\n tui.setAuthContext(authContext)\n\n if (workspaceId) {\n try {\n const wsCtx = await resolveWorkspace(store, workspaceId)\n tui.setWorkspaceContext(wsCtx)\n\n // Get workspace name\n if (selectedWorkspaceName && workspaceId === selectedWorkspaceId) {\n tui.state.workspaceName = selectedWorkspaceName\n } else {\n const wsList = await workspaces.listWorkspaces(authContext.arbi)\n const ws = wsList.find((w) => w.external_id === workspaceId)\n if (ws) {\n tui.state.workspaceName = ws.name\n }\n }\n } catch (err) {\n tui.chatLog.addSystem(`Failed to load workspace: ${getErrorMessage(err)}`, 'warning')\n tui.chatLog.addSystem('Use /workspaces to list and /workspace <id> to select.')\n }\n } else {\n tui.chatLog.addSystem(\n 'No workspace selected. Use /workspaces to list and /workspace <id> to select.'\n )\n }\n\n // Load chat session for conversation continuity\n const session = store.getChatSession()\n if (session.lastMessageExtId) {\n tui.state.conversationMessageId = session.lastMessageExtId\n }\n\n // Restore chat history from previous session\n if (session.conversationExtId && session.lastMessageExtId && tui.authContext) {\n try {\n const threads = await conversations.getConversationThreads(\n tui.authContext.arbi,\n session.conversationExtId\n )\n const threadList = (threads as { threads?: unknown[] }).threads ?? []\n const thread = threadList.find(\n (t) =>\n (t as { leaf_message_ext_id?: string }).leaf_message_ext_id === session.lastMessageExtId\n ) as { history?: { role: string; content: string }[] } | undefined\n\n if (thread?.history && thread.history.length > 0) {\n for (const msg of thread.history) {\n if (msg.role === 'user') {\n tui.chatLog.addUser(msg.content)\n } else if (msg.role === 'assistant') {\n tui.chatLog.addAssistant(msg.content)\n }\n }\n tui.chatLog.addSystem('--- restored from previous session ---')\n }\n } catch {\n // History restoration is best-effort — continue normally\n }\n }\n\n tui.chatLog.addSystem(\n 'Type a question to chat with the ARBI assistant. Use /help for commands.'\n )\n tui.start()\n })\n\nprogram.parse()\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/tui-helpers.ts","../src/theme/theme.ts","../src/theme/syntax-theme.ts","../src/components/assistant-message.ts","../src/components/user-message.ts","../src/components/system-message.ts","../src/components/right-aligned-text.ts","../src/components/agent-step.ts","../src/components/chat-log.ts","../src/event-log.ts","../src/sources-index.ts","../src/components/arbi-editor.ts","../src/components/toast-container.ts","../src/command-registry.ts","../src/commands/general.ts","../src/prompts.ts","../src/auth.ts","../src/commands/auth.ts","../src/commands/workspace.ts","../src/commands/document.ts","../src/commands/conversation.ts","../src/commands/tag.ts","../src/commands/misc.ts","../src/components/citation-panel.ts","../src/commands/citation.ts","../src/commands/events.ts","../src/commands/view.ts","../src/commands/sources.ts","../src/commands/history.ts","../src/commands/skills.ts","../src/commands/index.ts","../src/event-handlers.ts","../src/dm-handler.ts","../src/ws-handler.ts","../src/tui.ts","../src/index.ts"],"names":["selectWorkspaceById","getErrorMessage","resolveWorkspace","chalk","Container","Text","Markdown","visibleWidth","Spacer","resolveCitations","Editor","matchesKey","Key","input","parseSlashCommand","select","password","confirm","performPasswordLogin","createArbiClient","workspaces","formatWorkspaceChoices","projects","generateNewWorkspaceKey","resolveAuth","ws","formatUserName","documents","documentsNode","conversations","tags","contacts","showMessage","health","settings","Box","countCitations","summarizeCitations","DEFAULT_LIMIT","assistant","mkdtempSync","join","tmpdir","path","writeFileSync","statSync","spawnSync","readFileSync","rmSync","formatAgentStepLabel","streamSSE","formatStreamSummary","base64ToBytes","deriveEncryptionKeypairFromSigning","dm","encryptMessage","decryptMessage","formatWsMessage","connectWithReconnect","TUI","ProcessTerminal","CombinedAutocompleteProvider","Command","FileConfigStore"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * Shared TUI helpers — eliminates repeated boilerplate across command handlers.\n *\n * - requireAuth(): guard that checks authentication\n * - showMessage(): addSystem + requestRender in one call\n * - switchWorkspace(): workspace selection + state update\n * - runInteractiveFlow(): pause TUI → run action → restart TUI\n */\n\nimport { getErrorMessage, selectWorkspaceById, resolveWorkspace } from '@arbidocs/sdk'\nimport type { ArbiTui } from './tui.js'\nimport type { SystemMessageLevel } from './components/system-message.js'\n\n/**\n * Guard: check that the user is authenticated.\n * Returns true if auth context is present, otherwise shows an error and returns false.\n */\nexport function requireAuth(\n tui: ArbiTui,\n message = 'Not authenticated. Use /login first.'\n): boolean {\n if (tui.authContext) return true\n showMessage(tui, message, 'error')\n return false\n}\n\n/**\n * Display a system message and request a render in one call.\n */\nexport function showMessage(tui: ArbiTui, message: string, level?: SystemMessageLevel): void {\n tui.chatLog.addSystem(message, level)\n tui.requestRender()\n}\n\n/**\n * Switch to a workspace by ID — selects it, updates TUI state, persists config.\n * Returns the workspace info on success, or null on failure.\n */\nexport async function switchWorkspace(\n tui: ArbiTui,\n workspaceId: string\n): Promise<{ external_id: string; name: string } | null> {\n if (!tui.authContext) return null\n\n try {\n const ws = await selectWorkspaceById(\n tui.authContext.arbi,\n workspaceId,\n tui.authContext.loginResult.serverSessionKey,\n tui.store.requireCredentials().signingPrivateKeyBase64\n )\n\n tui.state.workspaceId = ws.external_id\n tui.state.workspaceName = ws.name\n tui.state.conversationMessageId = null\n tui.store.clearChatSession()\n tui.store.updateConfig({ selectedWorkspaceId: ws.external_id })\n await tui.refreshWorkspaceContext()\n\n return ws\n } catch (err) {\n showMessage(tui, `Failed to switch workspace: ${getErrorMessage(err)}`, 'error')\n return null\n }\n}\n\n/**\n * Set up workspace context after login/register when a workspace was auto-selected.\n */\nexport async function applyWorkspaceSelection(\n tui: ArbiTui,\n workspaceId?: string,\n workspaceName?: string | null\n): Promise<void> {\n if (!workspaceId) return\n const wsCtx = await resolveWorkspace(tui.store, workspaceId)\n tui.setWorkspaceContext(wsCtx)\n tui.state.workspaceName = workspaceName ?? null\n}\n\n/**\n * Run an interactive flow that requires stdin (login, register).\n * Stops the TUI, runs the action, restarts the TUI, and handles errors.\n * Returns the action result on success, or null on failure.\n */\nexport async function runInteractiveFlow<T>(\n tui: ArbiTui,\n pauseMessage: string,\n action: () => Promise<T>,\n errorPrefix: string\n): Promise<T | null> {\n showMessage(tui, pauseMessage)\n tui.stopTui()\n\n try {\n const result = await action()\n tui.restartTui()\n return result\n } catch (err) {\n tui.restartTui()\n showMessage(tui, `${errorPrefix}: ${getErrorMessage(err)}`, 'error')\n return null\n }\n}\n","/**\n * ARBI TUI theme — color palette and component styling functions.\n *\n * Uses chalk for ANSI color output. All theme values are functions\n * that wrap text in the appropriate escape sequences.\n */\n\nimport chalk from 'chalk'\nimport type { MarkdownTheme, EditorTheme, SelectListTheme } from '@mariozechner/pi-tui'\n\n// ── Color palette ──────────────────────────────────────────────────────────\n\nexport const colors = {\n /** Primary accent — teal/cyan used for headings, prompts, highlights */\n accent: chalk.cyan,\n accentBold: chalk.bold.cyan,\n\n /** Secondary accent — blue for links and info */\n secondary: chalk.blue,\n\n /** Muted text — dim gray for borders, metadata */\n muted: chalk.gray,\n mutedDim: chalk.dim.gray,\n\n /** Success — green for completed states */\n success: chalk.green,\n\n /** Warning — yellow for pending states, code */\n warning: chalk.yellow,\n\n /** Error — red for error messages */\n error: chalk.red,\n errorBold: chalk.bold.red,\n\n /** Text — default and bold */\n text: chalk.white,\n textBold: chalk.bold.white,\n\n /** User message styling */\n userLabel: chalk.bold.green,\n userText: chalk.white,\n\n /** Assistant message styling */\n assistantLabel: chalk.bold.cyan,\n\n /** System message styling */\n systemText: chalk.dim,\n systemInfo: chalk.dim.cyan,\n systemError: chalk.dim.red,\n systemWarning: chalk.dim.yellow,\n\n /** Agent step styling */\n stepPending: chalk.dim.yellow,\n stepComplete: chalk.dim.green,\n} as const\n\n// ── Background functions ───────────────────────────────────────────────────\n\nexport const bgFn = {\n /** Subtle background for user messages */\n user: (text: string) => chalk.bgGray(text),\n\n /** Background for agent steps */\n agentStep: (text: string) => text,\n} as const\n\n// ── Component themes ───────────────────────────────────────────────────────\n\nexport const selectListTheme: SelectListTheme = {\n selectedPrefix: (s: string) => colors.accent(s),\n selectedText: (s: string) => colors.text(s),\n description: (s: string) => colors.muted(s),\n scrollInfo: (s: string) => colors.muted(s),\n noMatch: (s: string) => colors.muted(s),\n}\n\nexport const editorTheme: EditorTheme = {\n borderColor: (s: string) => colors.accent(s),\n selectList: selectListTheme,\n}\n\nexport const markdownTheme: MarkdownTheme = {\n heading: (s: string) => colors.accentBold(s),\n link: (s: string) => chalk.underline.blue(s),\n linkUrl: (s: string) => colors.muted(s),\n code: (s: string) => colors.warning(s),\n codeBlock: (s: string) => colors.text(s),\n codeBlockBorder: (s: string) => colors.muted(s),\n quote: (s: string) => chalk.italic.gray(s),\n quoteBorder: (s: string) => colors.muted(s),\n hr: (s: string) => colors.muted(s),\n listBullet: (s: string) => colors.accent(s),\n bold: (s: string) => chalk.bold(s),\n italic: (s: string) => chalk.italic(s),\n strikethrough: (s: string) => chalk.strikethrough(s),\n underline: (s: string) => chalk.underline(s),\n}\n\n// ── Header / Footer helpers ────────────────────────────────────────────────\n\nexport function formatHeader(workspaceName: string | null, status: string): string {\n const app = colors.accentBold('ARBI')\n const ws = workspaceName ? colors.muted(` | ${workspaceName}`) : ''\n const st = colors.muted(` | ${status}`)\n return `${app}${ws}${st}`\n}\n\nexport function formatPrompt(): string {\n return colors.accent('> ')\n}\n","/**\n * Syntax highlighting theme for code blocks in Markdown.\n *\n * Provides a highlightCode function compatible with pi-tui's\n * MarkdownTheme.highlightCode option.\n */\n\nimport chalk from 'chalk'\n\n/**\n * Simple keyword-based syntax highlighting for code blocks.\n * Returns an array of styled lines.\n *\n * For a first version, we apply basic keyword coloring. This can be\n * upgraded to use a proper highlighter (e.g., cli-highlight) later.\n */\n// eslint-disable-next-line @typescript-eslint/no-unused-vars\nexport function highlightCode(code: string, lang?: string): string[] {\n const lines = code.split('\\n')\n\n return lines.map((line) => {\n // Highlight common keywords\n let styled = line\n // String literals (double and single quoted)\n .replace(/([\"'])(?:(?=(\\\\?))\\2.)*?\\1/g, (m) => chalk.green(m))\n // Numbers\n .replace(/\\b(\\d+\\.?\\d*)\\b/g, (m) => chalk.yellow(m))\n // Comments (// and #)\n .replace(/(\\/\\/.*|#.*)$/g, (m) => chalk.gray(m))\n\n // Keywords (applied after strings/comments to avoid conflicts in simple cases)\n const keywords =\n /\\b(const|let|var|function|return|if|else|for|while|import|export|from|class|extends|new|async|await|try|catch|throw|type|interface|enum|def|self|None|True|False|print)\\b/g\n styled = styled.replace(keywords, (m) => chalk.cyan(m))\n\n return styled\n })\n}\n","/**\n * AssistantMessage — streaming markdown response from the RAG assistant.\n *\n * Wraps pi-tui's Markdown component. Call setText() as tokens arrive\n * to update the rendered content incrementally.\n */\n\nimport { Container, Markdown, Text } from '@mariozechner/pi-tui'\nimport { markdownTheme, colors } from '../theme/theme.js'\nimport { highlightCode } from '../theme/syntax-theme.js'\n\nconst assistantMarkdownTheme = {\n ...markdownTheme,\n highlightCode,\n}\n\nexport class AssistantMessage extends Container {\n private markdown: Markdown\n private label: Text\n\n constructor() {\n super()\n this.label = new Text(colors.assistantLabel('ARBI'), 1, 0)\n this.markdown = new Markdown('', 1, 0, assistantMarkdownTheme)\n this.addChild(this.label)\n this.addChild(this.markdown)\n }\n\n /** Update the response text (called as tokens stream in). */\n setText(text: string): void {\n this.markdown.setText(text)\n }\n}\n","/**\n * UserMessage — displays a user's submitted question.\n *\n * Wraps pi-tui's Markdown component with user-specific styling.\n */\n\nimport { Container, Markdown, Text } from '@mariozechner/pi-tui'\nimport { markdownTheme, colors } from '../theme/theme.js'\n\nexport class UserMessage extends Container {\n constructor(text: string) {\n super()\n const label = new Text(colors.userLabel('You'), 1, 0)\n const content = new Markdown(text, 1, 0, markdownTheme)\n this.addChild(label)\n this.addChild(content)\n }\n}\n","/**\n * SystemMessage — info, warning, and error messages.\n *\n * Wraps pi-tui's Text component with dim/accent styling.\n */\n\nimport { Text } from '@mariozechner/pi-tui'\nimport { colors } from '../theme/theme.js'\n\nexport type SystemMessageLevel = 'info' | 'warning' | 'error'\n\nexport class SystemMessage extends Text {\n constructor(message: string, level: SystemMessageLevel = 'info') {\n const styleFn =\n level === 'error'\n ? colors.systemError\n : level === 'warning'\n ? colors.systemWarning\n : colors.systemInfo\n super(styleFn(message), 1, 0)\n }\n}\n","/**\n * RightAlignedText — single-line text component that renders right-aligned.\n *\n * Used for stream summary lines (token counts, timing) that should\n * appear flush-right, matching the CLI's right-aligned summary style.\n */\n\nimport { visibleWidth } from '@mariozechner/pi-tui'\n\nexport class RightAlignedText {\n private text: string\n private styleFn: (s: string) => string\n\n constructor(text: string, styleFn: (s: string) => string) {\n this.text = text\n this.styleFn = styleFn\n }\n\n invalidate(): void {\n // No cache to invalidate\n }\n\n render(width: number): string[] {\n if (!this.text || this.text.trim() === '') return []\n\n const styled = this.styleFn(this.text)\n const textWidth = visibleWidth(styled)\n const padding = Math.max(0, width - textWidth)\n return [' '.repeat(padding) + styled]\n }\n}\n","/**\n * AgentStep — displays a single agent processing step.\n *\n * Two render modes:\n *\n * - **Flat**: ``> label`` — the original behaviour, used when the\n * step has no extra context (e.g. lifecycle \"Planning\", \"Generating\n * answer\").\n *\n * - **Structured**: ``▸ label`` followed by indented secondary\n * lines for ``tool``, ``args``, and ``result`` summaries. Matches\n * the claude-code rendering of tool-use blocks where the\n * invocation header sits flush-left and the arguments / output\n * hang underneath at a fixed indent.\n *\n * The class still extends ``Text`` from pi-tui, so it's still a\n * single block in the chat log — pi-tui handles wrapping. Future\n * work could swap to a ``Container`` for keyboard-focusable collapse\n * (claude-code's ``Tab`` / ``Enter`` cycling); the data model is\n * already shaped for that.\n */\n\nimport { Text } from '@mariozechner/pi-tui'\nimport { colors } from '../theme/theme.js'\n\n/** Optional structured context for an agent step. All fields are\n * short single-line summaries — the renderer doesn't try to pretty-\n * print JSON or wrap long results, that's the caller's job. */\nexport interface AgentStepDetails {\n /** Tool the step is invoking, when applicable. */\n tool?: string\n /** One-line summary of the inputs (e.g. ``query: \"what...?\"``). */\n args?: string\n /** One-line summary of the outputs (e.g. ``→ 5 chunks from 3 docs``). */\n result?: string\n}\n\n/** Pick a glyph for the step header. ASCII fallbacks live alongside\n * the UTF-8 versions in case a terminal doesn't render the latter\n * cleanly. Kept here, not in ``theme``, because the glyph IS the\n * semantic (\"tool\" vs \"lifecycle\" vs \"complete\"). */\nconst GLYPH_LIFECYCLE = '>'\nconst GLYPH_TOOL = '▸'\nconst GLYPH_RESULT = '→'\n\nexport class AgentStep extends Text {\n private completed = false\n\n constructor(label: string, details?: AgentStepDetails) {\n super(buildText(label, details), 2, 0)\n }\n\n /** Mark this step as completed. Renderer is unchanged for now —\n * see the file-header comment for the planned focusable-collapse\n * upgrade path. */\n complete(): void {\n if (this.completed) return\n this.completed = true\n }\n}\n\n/** Render the multi-line text body for the step. Pulled out so the\n * shape is testable without instantiating ``Text`` (which needs\n * pi-tui internals). */\nexport function buildText(label: string, details?: AgentStepDetails): string {\n const hasDetails = !!(details?.tool || details?.args || details?.result)\n const glyph = hasDetails ? GLYPH_TOOL : GLYPH_LIFECYCLE\n const header = `${colors.stepPending(glyph)} ${hasDetails ? colors.accent(label) : colors.muted(label)}`\n\n if (!hasDetails) return header\n\n const lines: string[] = [header]\n // Two-space indent so the sub-lines visually hang from the header.\n // Mirrors claude-code's tool-call expansion layout.\n if (details?.tool && details.tool !== label) {\n lines.push(` ${colors.muted('tool:')} ${details.tool}`)\n }\n if (details?.args) {\n lines.push(` ${colors.muted('args:')} ${details.args}`)\n }\n if (details?.result) {\n lines.push(` ${colors.muted(GLYPH_RESULT)} ${details.result}`)\n }\n return lines.join('\\n')\n}\n","/**\n * ChatLog — container managing the message list and streaming runs.\n *\n * Provides methods for adding user/system messages and managing\n * assistant streaming lifecycle (start → update → finalize).\n */\n\nimport { Container, Spacer, Text } from '@mariozechner/pi-tui'\nimport { AssistantMessage } from './assistant-message.js'\nimport { UserMessage } from './user-message.js'\nimport { SystemMessage, type SystemMessageLevel } from './system-message.js'\nimport { RightAlignedText } from './right-aligned-text.js'\nimport { AgentStep, type AgentStepDetails } from './agent-step.js'\nimport { colors } from '../theme/theme.js'\n\nexport class ChatLog extends Container {\n /** Currently streaming assistant message (null when idle). */\n private activeAssistant: AssistantMessage | null = null\n\n /** Agent steps associated with the current streaming run. */\n private activeSteps: AgentStep[] = []\n\n /** Add a user message to the log. */\n addUser(text: string): void {\n this.addChild(new UserMessage(text))\n this.addChild(new Spacer(1))\n }\n\n /** Add a complete assistant message (non-streaming, e.g. for history restoration). */\n addAssistant(text: string): void {\n const msg = new AssistantMessage()\n msg.setText(text)\n this.addChild(msg)\n this.addChild(new Spacer(1))\n }\n\n /** Add a system/info/error message. */\n addSystem(message: string, level: SystemMessageLevel = 'info'): void {\n this.addChild(new SystemMessage(message, level))\n this.addChild(new Spacer(1))\n }\n\n /** Add a right-aligned summary line (e.g. stream stats). */\n addSummary(text: string): void {\n this.addChild(new RightAlignedText(text, colors.systemInfo))\n this.addChild(new Spacer(1))\n }\n\n /** Add a received DM message (cyan label with sender email). */\n addDm(senderEmail: string, text: string): void {\n const container = new Container()\n const label = new Text(colors.accent(senderEmail), 1, 0)\n const content = new Text(colors.text(text), 1, 0)\n container.addChild(label)\n container.addChild(content)\n this.addChild(container)\n this.addChild(new Spacer(1))\n }\n\n /** Remove all messages from the chat log. */\n clearMessages(): void {\n this.activeAssistant = null\n this.activeSteps = []\n // Remove all children by iterating backwards\n while (this.children.length > 0) {\n this.removeChild(this.children[this.children.length - 1])\n }\n }\n\n /** Start a new assistant streaming response. */\n startAssistant(): void {\n this.activeAssistant = new AssistantMessage()\n this.activeSteps = []\n this.addChild(this.activeAssistant)\n }\n\n /** Update the active assistant message with accumulated text. */\n updateAssistant(text: string): void {\n this.activeAssistant?.setText(text)\n }\n\n /** Add an agent step to the current streaming run. Optional\n * ``details`` enriches the rendered block with ``tool`` / ``args``\n * / ``result`` lines beneath the header — claude-code-style\n * tool-use expansion. Callers that don't have structured detail\n * can omit the second arg and get the original flat behaviour. */\n addAgentStep(label: string, details?: AgentStepDetails): void {\n if (!this.activeAssistant) return\n const step = new AgentStep(label, details)\n this.activeSteps.push(step)\n // Insert step before the assistant message content\n this.addChild(step)\n }\n\n /** Remove all active agent steps from the chat log (e.g. when streaming starts). */\n clearActiveSteps(): void {\n for (const step of this.activeSteps) {\n this.removeChild(step)\n }\n this.activeSteps = []\n }\n\n /** Finalize the current assistant response. */\n finalizeAssistant(): void {\n this.clearActiveSteps()\n this.activeAssistant = null\n this.addChild(new Spacer(1))\n }\n}\n","/**\n * WsEventLog — persistent ring buffer of WebSocket events.\n *\n * Sits alongside the ephemeral ``ToastContainer``. Toasts are great\n * for \"did something just happen?\" — they disappear in 3–8s. But the\n * common gap with the previous setup was answering \"what happened\n * during this session?\": upload progress, doc parsing milestones,\n * presence updates, errors. The log captures every WS event for the\n * lifetime of the session so ``/events`` can replay them.\n *\n * Inspired by claude-code's persistent tool-call timeline and\n * openclaw's per-session event log. Bounded so a long session can't\n * leak memory — kept at the most-recent ``capacity`` entries.\n */\n\nexport type WsEventLevel = 'info' | 'success' | 'warning' | 'error'\n\nexport interface WsEventEntry {\n /** Wall-clock time the event was observed by the TUI. */\n at: Date\n /** Pre-formatted, user-facing one-liner (from ``formatWsMessage``\n * or, for transport status events, a fixed string). */\n text: string\n /** Severity — drives both colouring in ``/events`` and the\n * toast-suppression policy in ``ws-handler``. */\n level: WsEventLevel\n /** The raw message ``type`` (when known) so callers can filter\n * ``/events --type task_update`` without re-parsing the text. */\n msgType?: string\n}\n\nexport class WsEventLog {\n private readonly entries: WsEventEntry[] = []\n private readonly capacity: number\n\n /** ``capacity`` defaults to 200, the same order-of-magnitude as\n * a typical long chat session. Old entries roll off when the\n * buffer fills — same shape as openclaw's session log. */\n constructor(capacity = 200) {\n this.capacity = capacity\n }\n\n /** Append a new entry. Drops the oldest if at capacity. */\n add(entry: Omit<WsEventEntry, 'at'> & { at?: Date }): void {\n this.entries.push({\n at: entry.at ?? new Date(),\n text: entry.text,\n level: entry.level,\n msgType: entry.msgType,\n })\n while (this.entries.length > this.capacity) this.entries.shift()\n }\n\n /** Read the last ``limit`` entries (most recent last). Optionally\n * filter by level — useful for ``/events --errors``. */\n getAll(options?: { limit?: number; level?: WsEventLevel }): WsEventEntry[] {\n let view: WsEventEntry[] = this.entries\n if (options?.level) view = view.filter((e) => e.level === options.level)\n if (options?.limit != null) view = view.slice(-options.limit)\n return view\n }\n\n /** Number of entries currently retained (after eviction). */\n get size(): number {\n return this.entries.length\n }\n}\n\n/** Format an entry as a single line for the chat-log dump that\n * ``/events`` uses. Kept separate from ``WsEventLog`` itself so the\n * data layer stays free of presentation choices (colour, padding). */\nexport function formatEventLine(entry: WsEventEntry): string {\n const h = String(entry.at.getHours()).padStart(2, '0')\n const m = String(entry.at.getMinutes()).padStart(2, '0')\n const s = String(entry.at.getSeconds()).padStart(2, '0')\n const tag = entry.level.padEnd(7) // longest = \"warning\"\n return `[${h}:${m}:${s}] ${tag} ${entry.text}`\n}\n","/**\n * SourcesIndex — running tally of documents referenced by the\n * current conversation, accumulated across multiple turns.\n *\n * The TUI's chat log is linear and scrolls, so users lose track of\n * which documents have backed up the conversation so far. This\n * index is the \"what's in play?\" data that powers ``/sources`` —\n * and, eventually, a persistent right-side sidebar (the Codex /\n * VS-Code pattern). Building the data layer first lets us ship\n * ``/sources`` today and promote it to a layout component when the\n * pi-tui side-by-side primitives are wired up.\n *\n * Reset on ``/new`` so each conversation starts with a clean slate.\n */\n\nimport { resolveCitations, type MessageMetadataPayload, type ResolvedCitation } from '@arbidocs/sdk'\n\nexport interface SourceEntry {\n /** Document external ID (e.g. ``doc-abc123``). */\n docId: string\n /** Best-known display title (parsed metadata title or file name). */\n title: string\n /** Page numbers cited on this doc, sorted ascending. */\n pages: number[]\n /** Citation indices ([1], [2], …) that point at this doc, sorted. */\n citationNums: string[]\n}\n\nexport class SourcesIndex {\n // Keyed by docId so successive turns add to the same entry rather\n // than duplicating it.\n private readonly entries = new Map<string, SourceEntry>()\n\n /** Fold every citation in ``metadata`` into the index. Idempotent\n * on the same payload — adding the same metadata twice doesn't\n * inflate counts. */\n recordCitations(metadata: MessageMetadataPayload | null | undefined): void {\n if (!metadata) return\n this.recordResolved(resolveCitations(metadata))\n }\n\n /** The underlying fold step, separated so tests can drive it with\n * hand-rolled ``ResolvedCitation`` fixtures rather than mocking\n * the full ``MessageMetadataPayload.tools.*`` graph that\n * ``resolveCitations`` traverses. */\n recordResolved(resolved: ResolvedCitation[]): void {\n for (const c of resolved) {\n for (const chunk of c.chunks) {\n const docId = chunk.metadata?.doc_ext_id\n if (!docId) continue\n const title = (chunk.metadata?.doc_title as string | undefined) ?? docId\n const page = chunk.metadata?.page_number\n const existing = this.entries.get(docId)\n if (existing) {\n if (typeof page === 'number' && !existing.pages.includes(page)) {\n existing.pages.push(page)\n existing.pages.sort((a, b) => a - b)\n }\n if (!existing.citationNums.includes(c.citationNum)) {\n existing.citationNums.push(c.citationNum)\n existing.citationNums.sort()\n }\n // Title may be missing on early chunks; upgrade if a later\n // chunk has a better one.\n if (existing.title === docId && title !== docId) existing.title = title\n } else {\n this.entries.set(docId, {\n docId,\n title,\n pages: typeof page === 'number' ? [page] : [],\n citationNums: [c.citationNum],\n })\n }\n }\n }\n }\n\n /** All entries in registration order — first-cited first. The\n * iterator order of ``Map`` is insertion order, which is what\n * we want for ``/sources`` (oldest at top, newest at bottom). */\n list(): SourceEntry[] {\n return Array.from(this.entries.values())\n }\n\n /** Clear the index. Wired to ``/new`` so a fresh conversation\n * starts with no inherited sources. */\n clear(): void {\n this.entries.clear()\n }\n\n /** Number of unique documents tracked. */\n get size(): number {\n return this.entries.size\n }\n}\n","/**\n * ArbiEditor — custom Editor with ARBI-specific keybindings.\n *\n * Extends pi-tui's Editor to add:\n * - Escape → abort active stream\n * - Ctrl+C → clear input / double-tap to exit\n * - Ctrl+D → exit\n * - Ctrl+W → workspace selector\n * - Ctrl+N → new conversation\n * - Alt+1..9 → jump straight to citation N from the last response.\n * (Ctrl+digit doesn't have a reliable terminal encoding, but Alt+\n * digit sends ``ESC <n>`` which pi-tui can match cleanly. Picked\n * because none of the editor's text-entry paths use Alt — typing\n * ``1`` still inserts a literal ``1``.)\n */\n\nimport { Editor, matchesKey, Key, type TUI } from '@mariozechner/pi-tui'\nimport { editorTheme } from '../theme/theme.js'\n\nexport class ArbiEditor extends Editor {\n /** Callback when Escape is pressed (abort streaming). */\n onEscape?: () => void\n\n /** Callback when Ctrl+C is pressed (clear or exit). */\n onCtrlC?: () => void\n\n /** Callback when Ctrl+D is pressed (exit). */\n onCtrlD?: () => void\n\n /** Callback when Ctrl+W is pressed (workspace selector). */\n onCtrlW?: () => void\n\n /** Callback when Ctrl+N is pressed (new conversation). */\n onCtrlN?: () => void\n\n /** Callback when Alt+1..9 is pressed (jump to citation N from\n * the last response). The handler gets the integer ``1`` through\n * ``9``; it is responsible for checking whether that citation\n * exists and surfacing a useful message if not. */\n onCitationKey?: (n: number) => void\n\n /**\n * Callback fired after every keystroke that mutates the buffer.\n *\n * The TUI uses this to power the **pre-flight skill hint**: when\n * the user types ``/<slug>`` we surface the skill's description in\n * the chat log so they see what they're about to invoke before\n * pressing Enter. The handler is responsible for its own\n * deduplication (e.g. only show the hint when the parsed slug\n * changes), since this callback fires on *every* mutating key.\n *\n * Receives the buffer text *after* the base ``handleInput`` has\n * applied the change. Read-only — handlers must not mutate the\n * editor synchronously or it'll loop.\n */\n onBufferChange?: (text: string) => void\n\n /** Track Ctrl+C presses for double-tap exit. */\n private lastCtrlCTime = 0\n\n /** Snapshot of the last text we emitted, so we don't fire on\n * non-mutating keys (cursor moves, redraws). */\n private lastEmittedText = ''\n\n constructor(tui: TUI) {\n super(tui, editorTheme, { paddingX: 1 })\n }\n\n override handleInput(data: string): void {\n if (matchesKey(data, Key.escape)) {\n this.onEscape?.()\n return\n }\n\n if (matchesKey(data, Key.ctrl('c'))) {\n const now = Date.now()\n if (this.getText().trim()) {\n // First Ctrl+C with content: clear input\n this.setText('')\n this.lastCtrlCTime = now\n } else if (now - this.lastCtrlCTime < 1000) {\n // Double Ctrl+C within 1s: exit\n this.onCtrlC?.()\n } else {\n this.lastCtrlCTime = now\n this.onCtrlC?.()\n }\n return\n }\n\n if (matchesKey(data, Key.ctrl('d'))) {\n this.onCtrlD?.()\n return\n }\n\n if (matchesKey(data, Key.ctrl('w'))) {\n this.onCtrlW?.()\n return\n }\n\n if (matchesKey(data, Key.ctrl('n'))) {\n this.onCtrlN?.()\n return\n }\n\n // Alt+1..9 — citation hotkeys. Only fire when there's a handler;\n // otherwise fall through so unbound terminals don't swallow the\n // input. ``onCitationKey`` itself decides what to do if there are\n // no citations available right now.\n if (this.onCitationKey) {\n for (let n = 1; n <= 9; n++) {\n if (matchesKey(data, Key.alt(String(n) as '1'))) {\n this.onCitationKey(n)\n return\n }\n }\n }\n\n // Pass all other input to the base Editor\n super.handleInput(data)\n\n // Buffer-change notification. Fires only when text actually\n // changed — arrow keys, redraws, and the no-op Ctrl-keys handled\n // above don't pay the lookup cost. Wrapped in try/catch so a\n // throwing observer never wedges the editor.\n if (this.onBufferChange) {\n const current = this.getText()\n if (current !== this.lastEmittedText) {\n this.lastEmittedText = current\n try {\n this.onBufferChange(current)\n } catch {\n // Swallow — the observer is best-effort UX.\n }\n }\n }\n }\n}\n","/**\n * ToastContainer — auto-dismissing notification toasts.\n *\n * Manages a list of styled Text children that appear briefly then\n * auto-remove themselves. Used for WebSocket event notifications.\n */\n\nimport { Container, Text } from '@mariozechner/pi-tui'\nimport chalk from 'chalk'\n\nexport type ToastLevel = 'info' | 'success' | 'warning' | 'error'\n\nconst LEVEL_STYLE: Record<ToastLevel, (s: string) => string> = {\n info: chalk.dim.cyan,\n success: chalk.dim.green,\n warning: chalk.dim.yellow,\n error: chalk.dim.red,\n}\n\nfunction formatTimestamp(): string {\n const now = new Date()\n const hh = String(now.getHours()).padStart(2, '0')\n const mm = String(now.getMinutes()).padStart(2, '0')\n const ss = String(now.getSeconds()).padStart(2, '0')\n return `${hh}:${mm}:${ss}`\n}\n\ninterface ActiveToast {\n text: Text\n timer: ReturnType<typeof setTimeout>\n}\n\nexport class ToastContainer extends Container {\n private activeToasts: ActiveToast[] = []\n private renderCallback: (() => void) | null = null\n\n /** Set the callback used to trigger a TUI re-render after toast changes. */\n setRenderCallback(cb: () => void): void {\n this.renderCallback = cb\n }\n\n /** Show a toast notification that auto-dismisses after `durationMs`. */\n show(message: string, level: ToastLevel = 'info', durationMs = 5000): void {\n const styleFn = LEVEL_STYLE[level]\n const formatted = styleFn(`[${formatTimestamp()}] ${message}`)\n const text = new Text(formatted, 1, 0)\n\n const timer = setTimeout(() => {\n this.dismiss(text)\n }, durationMs)\n\n this.activeToasts.push({ text, timer })\n this.addChild(text)\n this.renderCallback?.()\n }\n\n /** Remove all active toasts immediately. */\n clear(): void {\n for (const toast of this.activeToasts) {\n clearTimeout(toast.timer)\n this.removeChild(toast.text)\n }\n this.activeToasts = []\n this.renderCallback?.()\n }\n\n private dismiss(text: Text): void {\n const idx = this.activeToasts.findIndex((t) => t.text === text)\n if (idx !== -1) {\n clearTimeout(this.activeToasts[idx].timer)\n this.activeToasts.splice(idx, 1)\n this.removeChild(text)\n this.renderCallback?.()\n }\n }\n}\n","/**\n * Declarative command registry — replaces the switch-statement dispatcher\n * and static command array with a data-driven registry.\n *\n * Adding a new command is a single object literal in the appropriate domain file.\n * Auth guards, arg validation, help text, autocomplete, and error handling are automatic.\n */\n\nimport type { SlashCommand } from '@mariozechner/pi-tui'\nimport type { ArbiClient } from '@arbidocs/client'\nimport type { AuthContext, WorkspaceContext } from '@arbidocs/sdk'\nimport { getErrorMessage, parseSlashCommand } from '@arbidocs/sdk'\nimport type { ArbiTui } from './tui.js'\nimport { showMessage } from './tui-helpers.js'\n\n// ── Types ──────────────────────────────────────────────────────────────────\n\nexport type CommandRequires = 'none' | 'auth' | 'workspace'\n\ninterface CommandContextBase {\n args: string[]\n rawInput: string\n tui: ArbiTui\n}\n\nexport interface NoneCommandContext extends CommandContextBase {\n requires: 'none'\n}\n\nexport interface AuthCommandContext extends CommandContextBase {\n requires: 'auth'\n arbi: ArbiClient\n authContext: AuthContext\n}\n\nexport interface WorkspaceCommandContext extends CommandContextBase {\n requires: 'workspace'\n arbi: ArbiClient\n authContext: AuthContext\n wsContext: WorkspaceContext\n authHeaders: { baseUrl: string; accessToken: string }\n}\n\nexport type CommandContext = NoneCommandContext | AuthCommandContext | WorkspaceCommandContext\n\nexport type CommandOutput = string | string[] | void\n\nexport interface CommandDef {\n name: string\n description: string\n requires: CommandRequires\n run: (ctx: CommandContext) => CommandOutput | Promise<CommandOutput>\n /** Shown in help: /cmd <argHint> */\n argHint?: string\n /** Auto usage-error if fewer args are provided */\n minArgs?: number\n /** Omitted from /help (e.g. /quit alias) */\n hidden?: boolean\n}\n\n// ── Registry ───────────────────────────────────────────────────────────────\n\nconst registry = new Map<string, CommandDef>()\n\n/**\n * Slash commands the backend intercepts directly (not via the skills\n * registry). Kept tiny and explicit — every entry mirrors a branch in\n * ``src/core/router_helpers/commands.py``. ``/skill`` is excluded\n * because it's already registered as a static client-side command.\n */\nconst KNOWN_SERVER_COMMANDS: ReadonlySet<string> = new Set(['pa', 'setup', 'cold-start'])\n\n/** Register a single command definition. */\nexport function registerCommand(def: CommandDef): void {\n registry.set(def.name, def)\n}\n\n/** Register an array of command definitions. */\nexport function registerCommands(defs: CommandDef[]): void {\n for (const def of defs) {\n registerCommand(def)\n }\n}\n\n// ── Autocomplete / Help ────────────────────────────────────────────────────\n\n/** Convert the registry to an array of SlashCommand for pi-tui autocomplete. */\nexport function toSlashCommands(): SlashCommand[] {\n const cmds: SlashCommand[] = []\n for (const def of registry.values()) {\n if (def.hidden) continue\n cmds.push({ name: def.name, description: def.description })\n }\n return cmds\n}\n\n/**\n * Merge static client commands with dynamic backend skills into one\n * autocomplete list. This is the **single source of truth** for what\n * the editor's tab-complete shows — static-client and backend-skill\n * entries appear in the same dropdown so the user doesn't have to\n * know the difference.\n *\n * If a skill's slug collides with a static command (e.g. someone\n * names a skill ``help``), the static command wins because it owns\n * the TS handler. We skip the colliding skill entry rather than\n * shadowing the static one in the dropdown.\n *\n * Decoupled from ``toSlashCommands`` so callers that only want\n * static commands (e.g. ``formatHelpText``) keep working.\n */\nexport function toSlashCommandsWithSkills(\n skills: ReadonlyArray<{ slug: string; description: string }>\n): SlashCommand[] {\n const out = toSlashCommands()\n const taken = new Set(out.map((c) => c.name))\n for (const s of skills) {\n if (taken.has(s.slug)) continue\n out.push({ name: s.slug, description: s.description })\n }\n return out\n}\n\n/** Format all visible commands as a help string for display. */\nexport function formatHelpText(): string {\n const lines: string[] = []\n for (const def of registry.values()) {\n if (def.hidden) continue\n const hint = def.argHint ? ` <${def.argHint}>` : ''\n lines.push(` /${def.name}${hint} — ${def.description}`)\n }\n return [\n 'Available commands:',\n '',\n ...lines,\n '',\n 'Direct messages:',\n ' @name — Switch to DM channel with a contact',\n ' @arbi — Switch back to AI chat',\n '',\n 'Keyboard shortcuts:',\n ' Ctrl+N — New conversation',\n ' Ctrl+W — Switch workspace',\n ' Ctrl+D — Exit',\n ' Escape — Abort streaming',\n ' Alt+1..9 — Jump to citation N from the last response',\n '',\n 'Skills: any workspace SKILL.md with `user-invocable: true` becomes a',\n ' ``/<slug>`` command — type it like a regular slash command and the',\n ' agent handles it. ``/skills`` lists what is available.',\n ].join('\\n')\n}\n\n// ── Dispatcher ─────────────────────────────────────────────────────────────\n\n/**\n * Resolution order for ``/<name>``:\n *\n * 1. **Static client command** in this registry (e.g. ``/help``,\n * ``/cite``, ``/view``) — TUI-only affordances that run TS handlers.\n * 2. **Backend skill** in ``tui.skillsCache`` — workspace skills the\n * user has uploaded with ``user-invocable: true``. The TUI does\n * **not** run skill logic; it forwards the raw ``/<slug>`` text\n * to the backend, which intercepts in ``handle_skill_command``\n * and injects the skill body into the agent's prompt. This is the\n * single source of truth — the TUI never has its own skill catalogue.\n * 3. **Unknown** — friendly error.\n *\n * This is the \"no two sources of truth\" rule: static-client commands\n * are TS-defined here, backend skills come from ``GET /v1/assistant/skills``,\n * and the dispatcher walks them in priority order. Previously a typed\n * ``/<skill-slug>`` would say \"Unknown command\" even though the backend\n * would have happily intercepted it; that mismatch is the bug this\n * closes.\n */\n\n/** Dispatch a slash command. Returns true if handled. */\nexport async function dispatchCommand(tui: ArbiTui, input: string): Promise<boolean> {\n // Canonical parse — same regex as the React menu and the pre-flight\n // hint, lives in ``packages/arbi-sdk/src/operations/assistant.ts``.\n // ``parseSlashCommand`` returns ``null`` for anything that isn't a\n // slash command (including the bare DM ``@name`` shortcut), so the\n // caller can confidently let other handlers see the input.\n const parsed = parseSlashCommand(input)\n if (!parsed) return false\n\n const cmdName = parsed.slug\n // ``args`` is the rest-of-buffer as a single string from the SDK's\n // parser; the dispatcher's older callers expect ``string[]`` (split\n // on whitespace) so we keep that contract here.\n const args = parsed.args.length > 0 ? parsed.args.split(/\\s+/) : []\n // ``trimmed`` is kept as the raw command text for handlers that want\n // to inspect the original (e.g. ``rawInput`` in context). It's the\n // input minus leading/trailing whitespace, matching the previous\n // behaviour.\n const trimmed = input.trim()\n\n const def = registry.get(cmdName)\n if (!def) {\n // Fall through to backend skills before declaring \"unknown\".\n // The cache is populated on workspace switch\n // (``tui.refreshSkillsCache``) and on every ``/skills`` call.\n // Match by slug or display name so frontmatter authors aren't\n // surprised either way.\n const skill = tui.skillsCache?.find(\n (s) => s.slug === cmdName || s.name.toLowerCase() === cmdName\n )\n if (skill) {\n // Surface the skill's metadata in the chat log so the user can\n // see what they're invoking before the agent responds.\n // Equivalent of claude-code's pre-flight slash-command palette\n // confirmation — same data, no separate overlay needed.\n const meta = skill.arg_hint\n ? `Skill: ${skill.name} ${skill.arg_hint} — ${skill.description}`\n : `Skill: ${skill.name} — ${skill.description}`\n showMessage(tui, meta, 'info')\n\n // Returning ``false`` tells ``handleSubmit`` to fall through to\n // the normal AI-send path. The backend intercepts ``/<slug>``\n // server-side in ``handle_skill_command``; we never run skill\n // logic locally. Even ``type=python`` skills execute in the\n // backend's workspace sandbox — the TUI is purely a transport.\n return false\n }\n\n // Built-in backend commands the TUI never executes locally. They're\n // intercepted in ``src/core/router_helpers/commands.py`` on the\n // server (``/pa`` for OpenClaw PA, ``/setup`` / ``/cold-start`` for\n // the skills cold-start interview) and aren't in the skills cache\n // because they're not user-data. Passing them through here matches\n // the backend's vocabulary; without this they'd be wrongly flagged\n // as \"Unknown command\" client-side.\n if (KNOWN_SERVER_COMMANDS.has(cmdName)) {\n return false\n }\n\n showMessage(tui, `Unknown command: /${cmdName}. Type /help for available commands.`, 'warning')\n return true\n }\n\n // Check minArgs\n if (def.minArgs && args.length < def.minArgs) {\n const hint = def.argHint ? ` <${def.argHint}>` : ''\n showMessage(tui, `Usage: /${def.name}${hint}`, 'warning')\n return true\n }\n\n // Build context based on `requires`\n let ctx: CommandContext\n\n if (def.requires === 'none') {\n ctx = { requires: 'none', args, rawInput: trimmed, tui }\n } else if (def.requires === 'auth') {\n if (!tui.authContext) {\n showMessage(tui, 'Not authenticated. Use /login first.', 'error')\n return true\n }\n ctx = {\n requires: 'auth',\n args,\n rawInput: trimmed,\n tui,\n arbi: tui.authContext.arbi,\n authContext: tui.authContext,\n }\n } else {\n // requires === 'workspace'\n if (!tui.authContext) {\n showMessage(tui, 'Not authenticated. Use /login first.', 'error')\n return true\n }\n if (!tui.wsContext) {\n showMessage(tui, 'No workspace selected. Use /workspace <id> first.', 'warning')\n return true\n }\n ctx = {\n requires: 'workspace',\n args,\n rawInput: trimmed,\n tui,\n arbi: tui.wsContext.arbi,\n authContext: tui.authContext,\n wsContext: tui.wsContext,\n authHeaders: {\n baseUrl: tui.wsContext.config.baseUrl,\n accessToken: tui.wsContext.accessToken,\n },\n }\n }\n\n try {\n const result = await def.run(ctx)\n if (typeof result === 'string') {\n showMessage(tui, result)\n } else if (Array.isArray(result)) {\n showMessage(tui, result.join('\\n'))\n }\n } catch (err) {\n showMessage(tui, `Command /${def.name} failed: ${getErrorMessage(err)}`, 'error')\n }\n\n return true\n}\n","/**\n * General commands — /help, /status, /exit, /quit, /new\n */\n\nimport type { CommandDef, NoneCommandContext } from '../command-registry.js'\nimport { formatHelpText } from '../command-registry.js'\nimport { colors } from '../theme/theme.js'\n\nexport const generalCommands: CommandDef[] = [\n {\n name: 'help',\n description: 'Show available commands',\n requires: 'none',\n run: () => formatHelpText(),\n },\n {\n name: 'status',\n description: 'Show auth/workspace/connection status',\n requires: 'none',\n run: (ctx) => {\n const { tui } = ctx as NoneCommandContext\n const { state } = tui\n return [\n `Authenticated: ${state.isAuthenticated ? colors.success('yes') : colors.error('no')}`,\n `Workspace: ${state.workspaceName ? colors.accent(state.workspaceName) : colors.muted('none')}`,\n `Workspace ID: ${state.workspaceId ?? colors.muted('none')}`,\n `Conversation: ${state.conversationMessageId ? colors.muted(state.conversationMessageId) : colors.muted('new')}`,\n `Status: ${state.activityStatus}`,\n `WebSocket: ${tui.wsConnected ? colors.success('connected') : colors.muted('disconnected')}`,\n ]\n },\n },\n {\n name: 'new',\n description: 'Start fresh conversation (clear threading)',\n requires: 'none',\n run: (ctx) => {\n const { tui } = ctx as NoneCommandContext\n tui.state.conversationMessageId = null\n tui.lastMetadata = null\n // Sources index is scoped to the conversation — wiping it\n // alongside the threading state keeps ``/sources`` aligned with\n // \"this conversation\", not \"everything since the TUI launched\".\n tui.sourcesIndex.clear()\n tui.store.clearChatSession()\n return 'Started new conversation.'\n },\n },\n {\n name: 'exit',\n description: 'Exit TUI',\n requires: 'none',\n run: (ctx) => {\n const { tui } = ctx as NoneCommandContext\n tui.shutdown()\n },\n },\n {\n name: 'quit',\n description: 'Exit TUI',\n requires: 'none',\n hidden: true,\n run: (ctx) => {\n const { tui } = ctx as NoneCommandContext\n tui.shutdown()\n },\n },\n]\n","/**\n * Interactive prompt helpers using @inquirer/prompts.\n *\n * These are only used in interactive (TTY) flows — before the TUI starts\n * or after temporarily stopping it. Mirrors the CLI's prompt wrappers\n * for consistent validation and UX.\n */\n\nimport { select, input, password, confirm, checkbox, search } from '@inquirer/prompts'\n\nexport { select, input, password, confirm, checkbox, search }\n\n/**\n * Prompt user to pick from a list of items.\n * Returns the value of the selected choice.\n */\nexport async function promptSelect<T>(\n message: string,\n choices: Array<{ name: string; value: T; description?: string }>\n): Promise<T> {\n return select({ message, choices })\n}\n\n/**\n * Prompt user to pick multiple items from a list.\n * Returns array of selected values.\n */\nexport async function promptCheckbox<T>(\n message: string,\n choices: Array<{ name: string; value: T; checked?: boolean }>\n): Promise<T[]> {\n return checkbox({ message, choices })\n}\n\n/**\n * Prompt user to search and pick from a large list.\n * Type-ahead fuzzy filtering — best for docs (could be hundreds).\n */\nexport async function promptSearch<T>(\n message: string,\n choices: Array<{ name: string; value: T; description?: string }>\n): Promise<T> {\n return search({\n message,\n source: async (term) => {\n if (!term) return choices\n const lower = term.toLowerCase()\n return choices.filter((c) => c.name.toLowerCase().includes(lower))\n },\n })\n}\n\n/**\n * Prompt for text input. Returns trimmed string.\n */\nexport async function promptInput(message: string, required = true): Promise<string> {\n return input({\n message,\n validate: required ? (v) => (v.trim() ? true : 'Required') : undefined,\n })\n}\n\n/**\n * Prompt for a password (masked input).\n */\nexport async function promptPassword(message: string): Promise<string> {\n return password({\n message,\n mask: '*',\n validate: (v) => (v ? true : 'Required'),\n })\n}\n\n/**\n * Prompt for yes/no confirmation.\n */\nexport async function promptConfirm(message: string, defaultValue = true): Promise<boolean> {\n return confirm({ message, default: defaultValue })\n}\n","/**\n * Authentication flows for the TUI.\n *\n * Handles login and registration using @inquirer/prompts for interactive input.\n * These flows run BEFORE the TUI takes over the terminal (pi-tui raw mode),\n * or after temporarily stopping the TUI.\n */\n\nimport 'fake-indexeddb/auto'\nimport { createArbiClient } from '@arbidocs/client'\nimport type { ConfigStore, AuthContext } from '@arbidocs/sdk'\nimport {\n getErrorMessage,\n performPasswordLogin,\n formatWorkspaceChoices,\n generateNewWorkspaceKey,\n resolveAuth,\n workspaces,\n projects,\n} from '@arbidocs/sdk'\nimport { promptInput, promptPassword, promptSelect, promptConfirm } from './prompts.js'\n\n// ── Login ──────────────────────────────────────────────────────────────────\n\nexport interface LoginResult {\n authContext: AuthContext\n selectedWorkspaceId?: string\n selectedWorkspaceName?: string\n}\n\n/**\n * Interactive login flow. Prompts for email/password, authenticates,\n * and offers workspace selection.\n *\n * Must be called before the TUI starts (or after stopping it).\n */\nexport async function interactiveLogin(store: ConfigStore): Promise<LoginResult> {\n const config = store.requireConfig()\n\n const email = await promptInput('Email')\n const pw = await promptPassword('Password')\n\n const authContext = await performPasswordLogin(config, email, pw, store)\n\n console.info(`Logged in as ${email}`)\n\n // Workspace selection\n const result = await selectOrCreateWorkspace(authContext, store)\n\n return { authContext, ...result }\n}\n\n// ── Registration ───────────────────────────────────────────────────────────\n\n/**\n * Interactive registration flow. Prompts for email, verification code,\n * password, and name. Optionally logs in afterward.\n *\n * Must be called before the TUI starts (or after stopping it).\n */\nexport async function interactiveRegister(store: ConfigStore): Promise<LoginResult> {\n const config = store.requireConfig()\n\n const email = await promptInput('Email')\n\n const arbi = createArbiClient({\n baseUrl: config.baseUrl,\n deploymentDomain: config.deploymentDomain,\n credentials: 'omit',\n })\n await arbi.crypto.initSodium()\n\n // Verification\n const codeMethod = await promptSelect('Verification method', [\n { name: 'I have an invitation code', value: 'code' as const },\n { name: 'Send me a verification email', value: 'email' as const },\n ])\n\n let verificationCode: string\n if (codeMethod === 'code') {\n verificationCode = await promptInput('Invitation code')\n } else {\n console.info('Sending verification email...')\n const verifyResponse = await arbi.fetch.POST('/v1/user/verify-email', {\n body: { email },\n })\n if (verifyResponse.error) {\n throw new Error(`Failed to send verification email: ${JSON.stringify(verifyResponse.error)}`)\n }\n console.info('Verification email sent. Check your inbox.')\n verificationCode = await promptInput('Verification code')\n }\n\n // Password\n const pw = await promptPassword('Password')\n const confirmPw = await promptPassword('Confirm password')\n if (pw !== confirmPw) {\n throw new Error('Passwords do not match.')\n }\n\n // Name\n const firstName = (await promptInput('First name (optional)', false)) || 'User'\n const lastName = (await promptInput('Last name (optional)', false)) || ''\n\n // Register\n await arbi.auth.register({\n email,\n password: pw,\n verificationCode,\n firstName,\n lastName,\n })\n\n console.info(`\\nRegistered successfully as ${email}`)\n\n // Auto-login with the credentials just provided\n console.info('Logging in...')\n const authContext = await performPasswordLogin(config, email, pw, store)\n\n console.info(`Logged in as ${email}`)\n const result = await selectOrCreateWorkspace(authContext, store)\n\n return { authContext, ...result }\n}\n\n// ── Workspace selection / creation ──────────────────────────────────────────\n\n/**\n * After login, select an existing workspace or prompt to create one.\n * Used by both login and register flows.\n */\nasync function selectOrCreateWorkspace(\n authContext: AuthContext,\n store: ConfigStore\n): Promise<{ selectedWorkspaceId?: string; selectedWorkspaceName?: string }> {\n const wsList = await workspaces.listWorkspaces(authContext.arbi)\n\n if (wsList.length === 1) {\n store.updateConfig({ selectedWorkspaceId: wsList[0].external_id })\n console.info(`Workspace: ${wsList[0].name}`)\n return { selectedWorkspaceId: wsList[0].external_id, selectedWorkspaceName: wsList[0].name }\n }\n\n if (wsList.length > 1) {\n const choices = formatWorkspaceChoices(wsList)\n\n const selectedWorkspaceId = await promptSelect('Select workspace', choices)\n const ws = wsList.find((w) => w.external_id === selectedWorkspaceId)\n store.updateConfig({ selectedWorkspaceId })\n console.info(`Workspace: ${ws?.name}`)\n return { selectedWorkspaceId, selectedWorkspaceName: ws?.name }\n }\n\n // No workspaces — offer to create one\n console.info('No workspaces found.')\n const shouldCreate = await promptConfirm('Create a new workspace?')\n\n if (shouldCreate) {\n const name = await promptInput('Workspace name')\n const userProjects = await projects.listProjects(authContext.arbi)\n const defaultProjectExtId = userProjects[0]?.external_id\n if (!defaultProjectExtId) throw new Error('No projects found for user')\n const encryptedKey = await generateNewWorkspaceKey(\n authContext.arbi,\n authContext.loginResult.serverSessionKey\n )\n const ws = await workspaces.createWorkspace(\n authContext.arbi,\n name.trim(),\n encryptedKey,\n defaultProjectExtId\n )\n store.updateConfig({ selectedWorkspaceId: ws.external_id })\n console.info(`Created workspace: ${ws.name}`)\n return { selectedWorkspaceId: ws.external_id, selectedWorkspaceName: ws.name }\n }\n\n return {}\n}\n\n// ── Pre-flight auth check ──────────────────────────────────────────────────\n\n/**\n * Check if the user is authenticated. If not, offer to login or register.\n * Returns the auth context if successful, or exits the process.\n *\n * Called at startup before the TUI launches.\n */\nexport async function ensureAuthenticated(store: ConfigStore): Promise<LoginResult> {\n // Try existing credentials first\n try {\n const authContext = await resolveAuth(store)\n const config = store.requireConfig()\n return {\n authContext,\n selectedWorkspaceId: config.selectedWorkspaceId,\n }\n } catch {\n // Not authenticated — offer login/register with retry on errors\n console.info('Not authenticated.\\n')\n }\n\n // Retry loop — keeps prompting until successful login/register or user exits\n while (true) {\n const action = await promptSelect('What would you like to do?', [\n { name: 'Log in', value: 'login' as const },\n { name: 'Register a new account', value: 'register' as const },\n { name: 'Exit', value: 'exit' as const },\n ])\n\n if (action === 'exit') {\n process.exit(0)\n }\n\n try {\n if (action === 'register') {\n return await interactiveRegister(store)\n }\n return await interactiveLogin(store)\n } catch (err) {\n console.error(`\\n${getErrorMessage(err)}\\n`)\n }\n }\n}\n","/**\n * Auth commands — /login, /register, /logout\n */\n\nimport type { CommandDef, NoneCommandContext } from '../command-registry.js'\nimport { interactiveLogin, interactiveRegister } from '../auth.js'\nimport { showMessage, applyWorkspaceSelection, runInteractiveFlow } from '../tui-helpers.js'\n\nexport const authCommands: CommandDef[] = [\n {\n name: 'login',\n description: 'Log in (re-authenticate)',\n requires: 'none',\n run: async (ctx) => {\n const { tui } = ctx as NoneCommandContext\n const result = await runInteractiveFlow(\n tui,\n 'Pausing TUI for login...',\n () => interactiveLogin(tui.store),\n 'Login failed'\n )\n\n if (result) {\n tui.setAuthContext(result.authContext)\n await applyWorkspaceSelection(tui, result.selectedWorkspaceId, result.selectedWorkspaceName)\n showMessage(tui, 'Logged in successfully.')\n }\n },\n },\n {\n name: 'register',\n description: 'Register a new account',\n requires: 'none',\n run: async (ctx) => {\n const { tui } = ctx as NoneCommandContext\n const result = await runInteractiveFlow(\n tui,\n 'Pausing TUI for registration...',\n () => interactiveRegister(tui.store),\n 'Registration failed'\n )\n\n if (result) {\n tui.setAuthContext(result.authContext)\n await applyWorkspaceSelection(tui, result.selectedWorkspaceId, result.selectedWorkspaceName)\n showMessage(tui, 'Registered and logged in.')\n }\n },\n },\n {\n name: 'logout',\n description: 'Log out and clear credentials',\n requires: 'none',\n run: (ctx) => {\n const { tui } = ctx as NoneCommandContext\n tui.store.deleteCredentials()\n tui.store.updateConfig({ selectedWorkspaceId: undefined })\n tui.store.clearChatSession()\n\n tui.authContext = null\n tui.state.isAuthenticated = false\n tui.state.workspaceId = null\n tui.state.workspaceName = null\n tui.state.conversationMessageId = null\n\n return 'Logged out. Use /login to authenticate again.'\n },\n },\n]\n","/**\n * Workspace commands — /workspaces, /workspace, /create,\n * plus new: /ws-delete, /ws-users, /ws-add-user, /ws-remove-user\n */\n\nimport { workspaces, projects, generateNewWorkspaceKey, formatUserName } from '@arbidocs/sdk'\nimport type {\n CommandDef,\n AuthCommandContext,\n WorkspaceCommandContext,\n} from '../command-registry.js'\nimport { colors } from '../theme/theme.js'\nimport { showMessage, switchWorkspace } from '../tui-helpers.js'\n\nexport const workspaceCommands: CommandDef[] = [\n {\n name: 'workspaces',\n description: 'List all workspaces',\n requires: 'auth',\n run: async (ctx) => {\n const { arbi, tui } = ctx as AuthCommandContext\n const wsList = await workspaces.listWorkspaces(arbi)\n const lines = wsList.map((ws) => {\n const current = ws.external_id === tui.state.workspaceId ? colors.accent(' (current)') : ''\n return ` ${ws.external_id} ${ws.name}${current}`\n })\n return ['Workspaces:', '', ...lines]\n },\n },\n {\n name: 'workspace',\n description: 'Switch workspace',\n argHint: 'id',\n requires: 'auth',\n run: async (ctx) => {\n const { args, arbi, tui } = ctx as AuthCommandContext\n\n if (!args[0]) {\n const wsList = await workspaces.listWorkspaces(arbi)\n const lines = wsList.map((ws) => {\n const current =\n ws.external_id === tui.state.workspaceId ? colors.accent(' (current)') : ''\n return ` ${ws.external_id} ${ws.name}${current}`\n })\n showMessage(tui, ['Workspaces:', '', ...lines].join('\\n'))\n return 'Use /workspace <id> to switch.'\n }\n\n showMessage(tui, `Switching to workspace ${args[0]}...`)\n const ws = await switchWorkspace(tui, args[0])\n if (ws) {\n return `Switched to workspace: ${colors.accentBold(ws.name)}`\n }\n },\n },\n {\n name: 'create',\n description: 'Create a new workspace',\n argHint: 'name',\n minArgs: 1,\n requires: 'auth',\n run: async (ctx) => {\n const { args, arbi, authContext, tui } = ctx as AuthCommandContext\n const name = args.join(' ').trim()\n\n showMessage(tui, `Creating workspace \"${name}\"...`)\n const userProjects = await projects.listProjects(arbi)\n const defaultProjectExtId = userProjects[0]?.external_id\n if (!defaultProjectExtId) throw new Error('No projects found')\n const encryptedKey = await generateNewWorkspaceKey(\n arbi,\n authContext.loginResult.serverSessionKey\n )\n const ws = await workspaces.createWorkspace(arbi, name, encryptedKey, defaultProjectExtId)\n const selected = await switchWorkspace(tui, ws.external_id)\n\n if (selected) {\n return `Created and switched to workspace: ${colors.accentBold(selected.name)}`\n }\n },\n },\n {\n name: 'ws-delete',\n description: 'Delete a workspace',\n argHint: 'id',\n minArgs: 1,\n requires: 'auth',\n run: async (ctx) => {\n const { args, arbi } = ctx as AuthCommandContext\n await workspaces.deleteWorkspaces(arbi, [args[0]!])\n return `${colors.success('Deleted')} workspace ${args[0]}`\n },\n },\n {\n name: 'ws-users',\n description: 'List users in current workspace',\n requires: 'workspace',\n run: async (ctx) => {\n const { arbi } = ctx as WorkspaceCommandContext\n const users = await workspaces.listWorkspaceUsers(arbi)\n if (users.length === 0) return 'No users in this workspace.'\n\n const lines = users.map((u) => {\n const name = formatUserName(u.user)\n const nameStr = name ? colors.muted(` (${name})`) : ''\n const role = u.role ? colors.muted(` [${u.role}]`) : ''\n return ` ${u.user.email}${nameStr}${role}`\n })\n return [`Workspace users (${users.length}):`, '', ...lines]\n },\n },\n {\n name: 'ws-add-user',\n description: 'Add a user to current workspace',\n argHint: 'email',\n minArgs: 1,\n requires: 'workspace',\n run: async (ctx) => {\n const { args, arbi } = ctx as WorkspaceCommandContext\n const email = args[0]!.trim()\n await workspaces.addWorkspaceUsers(arbi, [email])\n return `${colors.success('Added')} ${email} to workspace.`\n },\n },\n {\n name: 'ws-remove-user',\n description: 'Remove a user from current workspace',\n argHint: 'email',\n minArgs: 1,\n requires: 'workspace',\n run: async (ctx) => {\n const { args, arbi } = ctx as WorkspaceCommandContext\n const email = args[0]!.trim()\n\n // Resolve email to user ID\n const users = await workspaces.listWorkspaceUsers(arbi)\n const user = users.find((u) => u.user.email === email)\n if (!user) return `User ${email} not found in this workspace.`\n\n const userId = user.user.external_id as string | undefined\n if (!userId) return `Could not resolve user ID for ${email}.`\n\n await workspaces.removeWorkspaceUsers(arbi, [userId])\n return `${colors.success('Removed')} ${email} from workspace.`\n },\n },\n]\n","/**\n * Document commands — /docs, /delete, /upload,\n * plus new: /doc, /upload-url, /parsed\n */\n\nimport { documents, documentsNode } from '@arbidocs/sdk'\nimport type { CommandDef, WorkspaceCommandContext } from '../command-registry.js'\nimport { colors } from '../theme/theme.js'\nimport { showMessage } from '../tui-helpers.js'\n\nexport const documentCommands: CommandDef[] = [\n {\n name: 'docs',\n description: 'List documents in current workspace',\n requires: 'workspace',\n run: async (ctx) => {\n const { arbi } = ctx as WorkspaceCommandContext\n const docs = await documents.listDocuments(arbi)\n if (docs.length === 0) return 'No documents in this workspace.'\n\n const lines = docs.map((d) => ` ${d.external_id} ${d.file_name ?? '(unnamed)'}`)\n return [`Documents (${docs.length}):`, '', ...lines]\n },\n },\n {\n name: 'doc',\n description: 'Show document details',\n argHint: 'id',\n minArgs: 1,\n requires: 'workspace',\n run: async (ctx) => {\n const { args, arbi } = ctx as WorkspaceCommandContext\n const docs = await documents.getDocuments(arbi, [args[0]!])\n if (docs.length === 0) return `Document ${args[0]} not found.`\n\n const doc = docs[0]!\n const lines = [\n `Document: ${colors.accent(doc.file_name ?? '(unnamed)')}`,\n '',\n ` ID: ${doc.external_id}`,\n ` Status: ${doc.status ?? colors.muted('unknown')}`,\n ` Size: ${doc.file_size != null ? `${doc.file_size} bytes` : colors.muted('unknown')}`,\n ` Created: ${doc.created_at ?? colors.muted('unknown')}`,\n ]\n return lines\n },\n },\n {\n name: 'upload',\n description: 'Upload a file',\n argHint: 'path',\n minArgs: 1,\n requires: 'workspace',\n run: async (ctx) => {\n const { args, tui, wsContext } = ctx as WorkspaceCommandContext\n const filePath = args.join(' ').trim()\n\n showMessage(tui, `Uploading ${filePath}...`)\n\n const result = await documentsNode.uploadLocalFile(\n {\n baseUrl: wsContext.config.baseUrl,\n accessToken: wsContext.accessToken,\n },\n filePath\n )\n\n const ids = (result.doc_ext_ids ?? []).join(', ')\n showMessage(tui, `${colors.success('Uploaded')} ${result.fileName} — doc ID(s): ${ids}`)\n\n if (result.skipped && result.skipped.length > 0) {\n showMessage(\n tui,\n `Skipped: ${result.skipped.map((s) => `${s.file_name} (${s.reason})`).join(', ')}`,\n 'warning'\n )\n }\n },\n },\n {\n name: 'upload-url',\n description: 'Upload a document from URL',\n argHint: 'url',\n minArgs: 1,\n requires: 'workspace',\n run: async (ctx) => {\n const { args, arbi, wsContext, tui } = ctx as WorkspaceCommandContext\n const url = args[0]!.trim()\n\n showMessage(tui, `Uploading from ${url}...`)\n const result = await documents.uploadUrl(arbi, [url])\n\n const ids = (result.doc_ext_ids ?? []).join(', ')\n const lines = [`${colors.success('Uploaded')} from URL — doc ID(s): ${ids}`]\n if (result.skipped && result.skipped.length > 0) {\n lines.push(\n `Skipped: ${result.skipped.map((s) => `${s.file_name} (${s.reason})`).join(', ')}`\n )\n }\n return lines\n },\n },\n {\n name: 'delete',\n description: 'Delete a document',\n argHint: 'doc-id',\n minArgs: 1,\n requires: 'workspace',\n run: async (ctx) => {\n const { args, arbi, tui } = ctx as WorkspaceCommandContext\n const docId = args[0]!.trim()\n\n showMessage(tui, `Deleting document ${docId}...`)\n await documents.deleteDocuments(arbi, [docId])\n return `${colors.success('Deleted')} document ${docId}`\n },\n },\n {\n name: 'parsed',\n description: 'Show parsed content of a document',\n argHint: 'doc-id',\n minArgs: 1,\n requires: 'workspace',\n run: async (ctx) => {\n const { args, authHeaders } = ctx as WorkspaceCommandContext\n const docId = args[0]!.trim()\n\n const data = await documents.getParsedContent(authHeaders, docId, 'content')\n const content = (data as Record<string, unknown>).content as string | undefined\n\n if (!content) return `No parsed content available for document ${docId}.`\n\n // Truncate very long content for terminal display\n const maxLen = 3000\n const truncated =\n content.length > maxLen ? content.slice(0, maxLen) + '\\n... (truncated)' : content\n return [`Parsed content for ${docId}:`, '', truncated]\n },\n },\n]\n","/**\n * Conversation commands — /conversations,\n * plus new: /conv-delete, /conv-title, /conv-share\n */\n\nimport { conversations } from '@arbidocs/sdk'\nimport type { CommandDef, WorkspaceCommandContext } from '../command-registry.js'\nimport { colors } from '../theme/theme.js'\n\nexport const conversationCommands: CommandDef[] = [\n {\n name: 'conversations',\n description: 'List conversations',\n requires: 'workspace',\n run: async (ctx) => {\n const { arbi } = ctx as WorkspaceCommandContext\n const convs = await conversations.listConversations(arbi)\n if (convs.length === 0) return 'No conversations in this workspace.'\n\n const lines = convs.map((c) => ` ${c.external_id} ${c.title ?? '(untitled)'}`)\n return [`Conversations (${convs.length}):`, '', ...lines]\n },\n },\n {\n name: 'conv-delete',\n description: 'Delete a conversation',\n argHint: 'id',\n minArgs: 1,\n requires: 'workspace',\n run: async (ctx) => {\n const { args, arbi } = ctx as WorkspaceCommandContext\n await conversations.deleteConversation(arbi, args[0]!)\n return `${colors.success('Deleted')} conversation ${args[0]}`\n },\n },\n {\n name: 'conv-title',\n description: 'Rename a conversation',\n argHint: 'id title',\n minArgs: 2,\n requires: 'workspace',\n run: async (ctx) => {\n const { args, arbi } = ctx as WorkspaceCommandContext\n const [id, ...titleParts] = args\n const title = titleParts.join(' ')\n await conversations.updateConversationTitle(arbi, id!, title)\n return `Renamed conversation ${id} to: ${colors.accent(title)}`\n },\n },\n {\n name: 'conv-share',\n description: 'Share a conversation',\n argHint: 'id',\n minArgs: 1,\n requires: 'workspace',\n run: async (ctx) => {\n const { args, arbi } = ctx as WorkspaceCommandContext\n const result = await conversations.shareConversation(arbi, args[0]!)\n const shareId =\n (result as Record<string, unknown>).share_ext_id ??\n (result as Record<string, unknown>).external_id\n return `${colors.success('Shared')} conversation ${args[0]} — share ID: ${shareId}`\n },\n },\n]\n","/**\n * Tag commands — /tags, /tag-create, /tag-delete\n */\n\nimport { tags } from '@arbidocs/sdk'\nimport type { CommandDef, WorkspaceCommandContext } from '../command-registry.js'\nimport { colors } from '../theme/theme.js'\n\nexport const tagCommands: CommandDef[] = [\n {\n name: 'tags',\n description: 'List tags in workspace',\n requires: 'workspace',\n run: async (ctx) => {\n const { arbi } = ctx as WorkspaceCommandContext\n const data = await tags.listTags(arbi)\n if (data.length === 0) return 'No tags in this workspace.'\n\n const lines = data.map((t) => ` ${t.external_id} ${t.name}`)\n return [`Tags (${data.length}):`, '', ...lines]\n },\n },\n {\n name: 'tag-create',\n description: 'Create a tag',\n argHint: 'name',\n minArgs: 1,\n requires: 'workspace',\n run: async (ctx) => {\n const { args, arbi } = ctx as WorkspaceCommandContext\n const name = args.join(' ').trim()\n const tag = await tags.createTag(arbi, { name })\n return `${colors.success('Created')} tag \"${tag.name}\" — ID: ${tag.external_id}`\n },\n },\n {\n name: 'tag-delete',\n description: 'Delete a tag',\n argHint: 'id',\n minArgs: 1,\n requires: 'workspace',\n run: async (ctx) => {\n const { args, arbi } = ctx as WorkspaceCommandContext\n await tags.deleteTag(arbi, args[0]!)\n return `${colors.success('Deleted')} tag ${args[0]}`\n },\n },\n]\n","/**\n * Miscellaneous commands — /contacts, /invite, /models, /health,\n * plus new: /settings\n */\n\nimport { contacts, health, settings, formatUserName } from '@arbidocs/sdk'\nimport type { CommandDef, AuthCommandContext } from '../command-registry.js'\nimport { colors } from '../theme/theme.js'\n\nexport const miscCommands: CommandDef[] = [\n {\n name: 'contacts',\n description: 'List contacts (type @name to DM)',\n requires: 'auth',\n run: async (ctx) => {\n const { arbi } = ctx as AuthCommandContext\n const contactList = await contacts.listContacts(arbi)\n const { registered, pending } = contacts.groupContactsByStatus(contactList)\n\n if (registered.length === 0 && pending.length === 0) {\n return 'No contacts. Use the web app to add contacts.'\n }\n\n const lines: string[] = []\n\n if (registered.length > 0) {\n lines.push(`Contacts (${registered.length}):`, '')\n for (const c of registered) {\n const name = formatUserName(c.user)\n const nameStr = name ? colors.muted(` (${name})`) : ''\n lines.push(` ${c.email}${nameStr}`)\n }\n }\n\n if (pending.length > 0) {\n if (lines.length > 0) lines.push('')\n lines.push(`Pending invitations (${pending.length}):`)\n for (const c of pending) {\n lines.push(` ${c.email} — ${colors.muted(c.status)}`)\n }\n }\n\n lines.push('', colors.muted('Type @name to start a DM with a registered contact.'))\n return lines\n },\n },\n {\n name: 'invite',\n description: 'Invite a contact',\n argHint: 'email',\n minArgs: 1,\n requires: 'auth',\n run: async (ctx) => {\n const { args, arbi, tui } = ctx as AuthCommandContext\n const email = args[0]!.trim()\n\n const { showMessage } = await import('../tui-helpers.js')\n showMessage(tui, `Inviting ${email}...`)\n\n const result = await contacts.addContacts(arbi, [email])\n const contact = result[0]\n\n if (contact?.status === 'registered') {\n return `${colors.success('Added')} ${email} — already registered. You can DM them with @${email.split('@')[0]}`\n }\n return `${colors.success('Invited')} ${email} — invitation sent. They'll appear in /contacts once they register.`\n },\n },\n {\n name: 'models',\n description: 'List available AI models',\n requires: 'auth',\n run: async (ctx) => {\n const { arbi } = ctx as AuthCommandContext\n const data = await health.getHealthModels(arbi)\n const models = Array.isArray(data)\n ? data\n : (((data as Record<string, unknown>).data as unknown[]) ?? [])\n\n if (models.length === 0) return 'No models available.'\n\n const lines: string[] = [`Models (${models.length}):`, '']\n for (const m of models) {\n const model = m as Record<string, unknown>\n const name = (model.model_name ?? model.name ?? 'unknown') as string\n const provider = (model.provider ?? '') as string\n const apiType = (model.api_type ?? '') as string\n const parts = [colors.accent(name)]\n if (provider) parts.push(`provider: ${provider}`)\n if (apiType) parts.push(`api: ${apiType}`)\n lines.push(` ${parts.join(' ')}`)\n }\n return lines\n },\n },\n {\n name: 'health',\n description: 'Show system health status',\n requires: 'auth',\n run: async (ctx) => {\n const { arbi } = ctx as AuthCommandContext\n const data = await health.getHealth(arbi)\n const lines: string[] = ['System Health:', '']\n\n const status = (data as Record<string, unknown>).status as string | undefined\n if (status) {\n const statusColor = status === 'healthy' ? colors.success(status) : colors.warning(status)\n lines.push(` Status: ${statusColor}`)\n }\n\n const services = (data as Record<string, unknown>).services as\n | Record<string, unknown>\n | undefined\n if (services) {\n lines.push('', ' Services:')\n for (const [name, info] of Object.entries(services)) {\n const svc = info as Record<string, unknown>\n const svcStatus = svc.status as string | undefined\n const statusStr = svcStatus\n ? svcStatus === 'healthy'\n ? colors.success(svcStatus)\n : colors.error(svcStatus)\n : colors.muted('unknown')\n lines.push(` ${name}: ${statusStr}`)\n }\n }\n\n return lines\n },\n },\n {\n name: 'settings',\n description: 'Show or update user settings',\n argHint: 'get | set <key> <value>',\n requires: 'auth',\n run: async (ctx) => {\n const { args, arbi } = ctx as AuthCommandContext\n const sub = args[0]?.toLowerCase()\n\n if (sub === 'set') {\n const key = args[1]\n const rawValue = args.slice(2).join(' ').trim()\n if (!key || rawValue.length === 0) {\n return `${colors.error('Usage:')} /settings set <key> <value> (e.g. /settings set show_pa_mode true)`\n }\n const value = coerceSettingValue(rawValue)\n await settings.updateSettings(arbi, {\n [key]: value,\n } as Parameters<typeof settings.updateSettings>[1])\n return `${colors.success('Updated')} ${colors.accent(key)} → ${String(value)}`\n }\n\n if (sub && sub !== 'get') {\n return `${colors.error('Unknown subcommand:')} /settings ${sub} — use /settings, /settings get, or /settings set <key> <value>`\n }\n\n const data = await settings.getSettings(arbi)\n const entries = Object.entries(data as Record<string, unknown>)\n\n if (entries.length === 0) return 'No settings configured.'\n\n const lines: string[] = ['User Settings:', '']\n for (const [key, value] of entries) {\n const display = typeof value === 'object' ? JSON.stringify(value) : String(value)\n lines.push(` ${colors.accent(key)}: ${display}`)\n }\n return lines\n },\n },\n]\n\n/**\n * Coerce a TUI-typed value string into the appropriate primitive for a\n * setting update. The CLI sees everything as a string, but the settings\n * schema is mostly booleans plus a handful of strings/numbers, so we\n * promote the obvious cases so users don't have to know JSON literals.\n *\n * - ``true`` / ``false`` / ``yes`` / ``no`` / ``on`` / ``off`` → boolean\n * - ``null`` → null\n * - integer or decimal literal → number\n * - anything else → raw string\n *\n * Case-insensitive on the boolean/null keywords. Whitespace is the\n * caller's responsibility (the dispatcher already splits on it).\n */\nexport function coerceSettingValue(raw: string): boolean | number | string | null {\n const lower = raw.toLowerCase()\n if (lower === 'true' || lower === 'yes' || lower === 'on') return true\n if (lower === 'false' || lower === 'no' || lower === 'off') return false\n if (lower === 'null') return null\n if (/^-?\\d+$/.test(raw)) return Number(raw)\n if (/^-?\\d+\\.\\d+$/.test(raw)) return Number(raw)\n return raw\n}\n","/**\n * CitationPanel — overlay component for displaying citation passage details.\n *\n * Shows citation number, document title, page number, statement text,\n * and passage content. Used by the /cite command when showing a specific\n * citation in the TUI.\n */\n\nimport { Box, Text, Markdown } from '@mariozechner/pi-tui'\nimport type { ResolvedCitation } from '@arbidocs/sdk'\nimport { colors, markdownTheme } from '../theme/theme.js'\n\nconst MAX_PASSAGE_CHARS = 2000\n\nexport class CitationPanel extends Box {\n constructor(citation: ResolvedCitation, passageIndex = 0) {\n super(1, 1)\n\n const chunk = citation.chunks[passageIndex]\n const docTitle = chunk?.metadata?.doc_title ?? 'Unknown document'\n const page = chunk?.metadata?.page_number\n\n // Header line: [Citation N] Document Title\n const headerParts = [\n `${colors.accentBold(`[Citation ${citation.citationNum}]`)} ${colors.textBold(docTitle)}`,\n ]\n if (page != null) {\n headerParts.push(colors.muted(` Page ${page}`))\n }\n if (citation.chunks.length > 1) {\n headerParts.push(colors.muted(` Passage ${passageIndex + 1}/${citation.chunks.length}`))\n }\n this.addChild(new Text(headerParts.join(''), 0, 0))\n\n // Statement\n this.addChild(new Text('', 0, 0))\n this.addChild(new Text(colors.textBold('Statement:'), 0, 0))\n this.addChild(new Text(` ${citation.citationData.statement}`, 0, 0))\n\n // Passage content\n this.addChild(new Text('', 0, 0))\n this.addChild(new Text(colors.textBold('Passage:'), 0, 0))\n\n if (chunk) {\n let content = chunk.content\n if (content.length > MAX_PASSAGE_CHARS) {\n content = content.slice(0, MAX_PASSAGE_CHARS) + '\\n...(truncated)'\n }\n this.addChild(new Markdown(content, 0, 0, markdownTheme))\n } else {\n this.addChild(new Text(colors.muted(' (no passage data available)'), 0, 0))\n }\n\n // Navigation hints\n this.addChild(new Text('', 0, 0))\n const hints: string[] = []\n if (citation.chunks.length > 1) {\n hints.push(\n `/cite ${citation.citationNum} <1-${citation.chunks.length}> to view other passages`\n )\n }\n hints.push('Press Escape to close')\n this.addChild(new Text(colors.muted(hints.join(' · ')), 0, 0))\n }\n}\n","/**\n * Citation commands — /cite and /refs (hidden alias)\n *\n * Browse citations from the last assistant response.\n * /cite List all citation summaries\n * /cite N Show overlay with passage for citation N\n * /cite N P Show passage P of citation N (multi-chunk)\n */\n\nimport { resolveCitations, summarizeCitations, countCitations } from '@arbidocs/sdk'\nimport type { CommandDef, NoneCommandContext } from '../command-registry.js'\nimport { CitationPanel } from '../components/citation-panel.js'\nimport { colors } from '../theme/theme.js'\n\nfunction handleCite(ctx: NoneCommandContext): string | string[] | void {\n const { tui, args } = ctx\n\n if (!tui.lastMetadata) {\n return 'No citation data available. Ask a question first.'\n }\n\n const count = countCitations(tui.lastMetadata)\n if (count === 0) {\n return 'The last response contained no citations.'\n }\n\n const resolved = resolveCitations(tui.lastMetadata)\n\n // /cite N [P] — show overlay for specific citation\n if (args.length >= 1) {\n const citationNum = args[0]\n const citation = resolved.find((r) => r.citationNum === citationNum)\n if (!citation) {\n return `Citation [${citationNum}] not found. Use /cite to list all citations.`\n }\n\n // Optional passage index (1-based input, 0-based internal)\n let passageIndex = 0\n if (args.length >= 2) {\n const p = parseInt(args[1], 10)\n if (isNaN(p) || p < 1 || p > citation.chunks.length) {\n return `Passage must be between 1 and ${citation.chunks.length}.`\n }\n passageIndex = p - 1\n }\n\n const panel = new CitationPanel(citation, passageIndex)\n tui.showCitationOverlay(panel)\n return\n }\n\n // /cite — list all citation summaries\n const summaries = summarizeCitations(resolved)\n const lines: string[] = [`Citations (${summaries.length}):\\n`]\n\n for (const s of summaries) {\n const page = s.pageNumber != null ? `, p${s.pageNumber}` : ''\n const chunks = s.chunkCount > 1 ? ` (${s.chunkCount} passages)` : ''\n const truncated =\n s.statement.length > 100\n ? s.statement.slice(0, 100).replace(/\\n/g, ' ').trim() + '...'\n : s.statement.replace(/\\n/g, ' ').trim()\n\n lines.push(\n ` ${colors.accent(`[${s.citationNum}]`)} ${colors.textBold(s.docTitle)}${page}${chunks}`\n )\n lines.push(` ${colors.muted(truncated)}`)\n }\n\n lines.push(colors.muted('\\nUse /cite <N> to view full passage.'))\n return lines\n}\n\nexport const citationCommands: CommandDef[] = [\n {\n name: 'cite',\n description: 'Browse citations from last response',\n requires: 'none',\n argHint: '[N] [passage]',\n run: (ctx) => handleCite(ctx as NoneCommandContext),\n },\n {\n name: 'refs',\n description: 'Browse citations from last response',\n requires: 'none',\n hidden: true,\n run: (ctx) => handleCite(ctx as NoneCommandContext),\n },\n]\n","/**\n * /events — replay the persistent WS event log.\n *\n * The complement to ephemeral toasts. While the toast container\n * shows roughly the last 5–10 seconds of activity, ``tui.eventLog``\n * captures every WS event for the lifetime of the session.\n * ``/events`` dumps a slice of that buffer into the chat log so a\n * user can scroll back and answer \"what happened during this session?\"\n *\n * Usage:\n * /events — last 20 entries\n * /events all — every retained entry (capacity is 200)\n * /events errors — last 20 entries with level=error\n * /events <n> — last <n> entries (cap at the buffer size)\n *\n * Modeled on claude-code's persistent tool-call timeline and\n * openclaw's per-session event view.\n */\n\nimport type { CommandDef, NoneCommandContext } from '../command-registry.js'\nimport { formatEventLine, type WsEventLevel } from '../event-log.js'\nimport { colors } from '../theme/theme.js'\n\nconst DEFAULT_LIMIT = 20\n\n/** Parse one user-supplied positional arg into a ``getAll`` query.\n * Exported for tests — verifying the parsing without booting the\n * pi-tui dispatcher is cleaner than driving the full command. */\nexport function parseEventsArg(arg: string | undefined): {\n limit?: number\n level?: WsEventLevel\n} {\n if (!arg) return { limit: DEFAULT_LIMIT }\n const lower = arg.trim().toLowerCase()\n if (lower === 'all') return {}\n if (lower === 'errors' || lower === 'error') {\n return { limit: DEFAULT_LIMIT, level: 'error' }\n }\n if (lower === 'warnings' || lower === 'warning') {\n return { limit: DEFAULT_LIMIT, level: 'warning' }\n }\n const n = Number.parseInt(lower, 10)\n if (Number.isFinite(n) && n > 0) return { limit: n }\n // Unknown filter — be forgiving, fall back to default.\n return { limit: DEFAULT_LIMIT }\n}\n\nexport const eventCommands: CommandDef[] = [\n {\n name: 'events',\n description: 'Show recent WebSocket events (replaces toasts that scroll off)',\n argHint: 'count|all|errors',\n requires: 'none',\n run: (ctx) => {\n const { tui, args } = ctx as NoneCommandContext\n const query = parseEventsArg(args[0])\n const entries = tui.eventLog.getAll(query)\n\n if (entries.length === 0) {\n if (query.level) {\n return `No ${query.level} events recorded yet.`\n }\n return 'No WebSocket events recorded yet.'\n }\n\n const lines = entries.map((e) => {\n const line = formatEventLine(e)\n switch (e.level) {\n case 'error':\n return colors.error(line)\n case 'warning':\n return colors.warning(line)\n case 'success':\n return colors.success(line)\n default:\n return colors.muted(line)\n }\n })\n\n const header =\n query.level != null\n ? `Events (${entries.length}, level=${query.level}):`\n : `Events (${entries.length} of ${tui.eventLog.size} retained):`\n return [header, '', ...lines]\n },\n },\n]\n","/**\n * /view <doc-id> — read a document inside the TUI.\n *\n * The complement to ``/parsed`` (which truncates at 3000 chars). For\n * a RAG-first product, reading the source IS the workflow — you ask\n * a question, jump to a citation, then want to see the surrounding\n * pages. ``/view`` fetches the full parsed content and lays it out\n * in the chat-log scrollback as a sequence of clearly-separated\n * pages, with citation hits flagged page-by-page so users can scan\n * for \"where does this doc back up the answer?\".\n *\n * Sized to use the existing chat-log as the pager (the terminal's\n * native scrollback). A future iteration could promote this to a\n * full modal pager overlay with arrow-key page navigation; the\n * formatter below is built so the same renderer feeds either UI.\n *\n * Mirrors what claude-code does with ``/diff`` or ``/files`` —\n * cleanly-separated content blocks in the timeline, not a separate\n * window the user has to manage.\n */\n\nimport { documents, resolveCitations, type ResolvedCitation } from '@arbidocs/sdk'\nimport type { CommandDef, WorkspaceCommandContext } from '../command-registry.js'\nimport { colors } from '../theme/theme.js'\n\n/** A single rendered page of a document. ``pageNumber`` is the\n * 1-based index; ``content`` is the page's body text (already\n * trimmed); ``citationNums`` lists the citation indices in the\n * current conversation that landed on this page. */\nexport interface RenderedPage {\n pageNumber: number\n content: string\n citationNums: string[]\n}\n\n/** Hard cap on how many characters of a page we render inline. Long\n * pages still get the citation markers and a continuation hint, just\n * not the entire body — same trade-off ``/parsed`` makes but applied\n * per-page rather than once across the whole doc. */\nconst MAX_CHARS_PER_PAGE = 2000\n\n/** Split a parsed-content blob into pages.\n *\n * The marker pipeline emits ``\\n---\\n`` between pages by convention.\n * If that's not present (e.g. ``content`` is plain text from a TXT\n * upload) we fall back to splitting on form-feed (``\\f``) and\n * finally just treat the whole blob as a single page.\n *\n * Pure so it can be unit-tested without touching pi-tui or the SDK.\n */\nexport function splitIntoPages(content: string): string[] {\n if (!content) return []\n const trimmed = content.trim()\n if (!trimmed) return []\n\n // Try the dominant marker convention first.\n if (trimmed.includes('\\n---\\n')) {\n return trimmed\n .split(/\\n---\\n/)\n .map((p) => p.trim())\n .filter((p) => p.length > 0)\n }\n // PDFs that came through a different pipeline sometimes use form\n // feeds between pages.\n if (trimmed.includes('\\f')) {\n return trimmed\n .split('\\f')\n .map((p) => p.trim())\n .filter((p) => p.length > 0)\n }\n // Single page.\n return [trimmed]\n}\n\n/** Build the per-page citation index. Walks the citation set once\n * and groups by ``pageNumber``. Citations without a page number are\n * attributed to page 1 — they still exist, we just can't pin them\n * more precisely, and dropping them silently would mislead the\n * user about coverage. */\nexport function indexCitationsByPage(\n docId: string,\n citations: ResolvedCitation[]\n): Map<number, string[]> {\n const byPage = new Map<number, string[]>()\n for (const c of citations) {\n for (const chunk of c.chunks) {\n if (chunk.metadata?.doc_ext_id !== docId) continue\n const page = chunk.metadata?.page_number ?? 1\n const list = byPage.get(page) ?? []\n if (!list.includes(c.citationNum)) list.push(c.citationNum)\n byPage.set(page, list)\n }\n }\n return byPage\n}\n\n/** Compose the final rendered lines for the chat-log dump. Pure;\n * the command itself just calls this and hands the result to\n * ``showMessage``/``return``. */\nexport function renderDocView(opts: {\n docId: string\n title: string\n fileName: string | null\n pages: string[]\n citationsByPage: Map<number, string[]>\n}): string[] {\n const { docId, title, fileName, pages, citationsByPage } = opts\n const totalCitations = Array.from(citationsByPage.values()).reduce((n, ids) => n + ids.length, 0)\n\n const lines: string[] = []\n // Header: title + identity + breadth-first stats.\n lines.push(colors.textBold(title))\n if (fileName && fileName !== title) lines.push(colors.muted(fileName))\n lines.push(colors.muted(`${docId} — ${pages.length} page${pages.length === 1 ? '' : 's'}`))\n if (totalCitations > 0) {\n lines.push(\n colors.muted(\n `${totalCitations} citation${totalCitations === 1 ? '' : 's'} from the current conversation`\n )\n )\n }\n lines.push('')\n\n // Pages.\n for (let i = 0; i < pages.length; i++) {\n const pageNum = i + 1\n const cites = citationsByPage.get(pageNum)\n const citeBadge =\n cites && cites.length > 0 ? colors.accent(` [${cites.map((n) => `[${n}]`).join(' ')}]`) : ''\n lines.push(colors.accentBold(`── page ${pageNum} ──`) + citeBadge)\n\n const body = pages[i]!\n if (body.length > MAX_CHARS_PER_PAGE) {\n lines.push(body.slice(0, MAX_CHARS_PER_PAGE))\n lines.push(\n colors.muted(\n `… (${body.length - MAX_CHARS_PER_PAGE} more chars — use /parsed ${docId} for the raw stream)`\n )\n )\n } else {\n lines.push(body)\n }\n lines.push('')\n }\n\n return lines\n}\n\nexport const viewCommands: CommandDef[] = [\n {\n name: 'view',\n description: 'Read a document in the chat log, with citation hints per page',\n argHint: 'doc-id',\n minArgs: 1,\n requires: 'workspace',\n run: async (ctx) => {\n const { args, arbi, authHeaders, tui } = ctx as WorkspaceCommandContext\n const docId = args[0]!.trim()\n\n // Metadata for the header — title falls back to file_name if\n // the doc didn't get a parsed title (e.g. plain-text uploads).\n const [docs, parsed] = await Promise.all([\n documents.getDocuments(arbi, [docId]),\n documents.getParsedContent(authHeaders, docId, 'content'),\n ])\n const doc = docs[0]\n if (!doc) return `Document ${docId} not found.`\n const meta = doc.doc_metadata as { title?: string | null } | null\n const title = meta?.title ?? doc.file_name ?? docId\n\n const content = (parsed as { content?: string }).content ?? ''\n if (!content) return `No parsed content available for ${docId}.`\n\n const pages = splitIntoPages(content)\n\n // Citations from the current conversation that hit this doc —\n // gives the user immediate \"where does my answer come from on\n // this page?\" feedback.\n const citationsByPage = tui.lastMetadata\n ? indexCitationsByPage(docId, resolveCitations(tui.lastMetadata))\n : new Map<number, string[]>()\n\n return renderDocView({\n docId,\n title,\n fileName: doc.file_name ?? null,\n pages,\n citationsByPage,\n })\n },\n },\n]\n","/**\n * /sources — list every document referenced in the current\n * conversation, with citation indices and the pages they hit.\n *\n * The TUI's chat log is linear, so once you've asked several\n * questions it's easy to lose track of which docs have actually\n * backed up the discussion. ``/sources`` is the running answer to\n * \"what's in play right now?\" — modelled after Codex's task-side\n * panel but as a command for now (a layout-level sidebar can come\n * later). Combined with ``/view <doc-id>`` and Alt+N citation\n * hotkeys, this gives ARBI users a complete source-navigation\n * surface that the reference TUIs don't have (none of them have\n * citations in the first place).\n */\n\nimport type { CommandDef, NoneCommandContext } from '../command-registry.js'\nimport type { SourceEntry } from '../sources-index.js'\nimport { colors } from '../theme/theme.js'\n\n/** Format the index as the lines we'll print in the chat log. Pure\n * so the test suite can lock the shape without spinning up the TUI. */\nexport function renderSourcesList(entries: SourceEntry[]): string | string[] {\n if (entries.length === 0) {\n return 'No sources cited yet in this conversation. Ask a question first.'\n }\n\n const lines: string[] = [`Sources in this conversation (${entries.length}):`, '']\n\n for (const e of entries) {\n const cites = e.citationNums.map((n) => `[${n}]`).join(' ')\n const pages = e.pages.length > 0 ? ` p.${e.pages.join(', p.')}` : ''\n lines.push(` ${colors.accent(cites)} ${colors.textBold(e.title)}${pages}`)\n lines.push(` ${colors.muted(e.docId)}`)\n }\n\n lines.push('')\n lines.push(\n colors.muted('Use /view <doc-id> to read a source, or /cite N for a specific passage.')\n )\n return lines\n}\n\nexport const sourcesCommands: CommandDef[] = [\n {\n name: 'sources',\n description: 'List documents cited in this conversation',\n requires: 'none',\n run: (ctx) => {\n const { tui } = ctx as NoneCommandContext\n return renderSourcesList(tui.sourcesIndex.list())\n },\n },\n]\n","/**\n * /history — list and resume past conversations in this workspace.\n *\n * The TUI already auto-resumes the last conversation on launch (via\n * ``index.ts``'s session-restore path) but offers no way to jump to\n * any earlier one without restarting with a different ``session.json``\n * on disk. ``/history`` closes that gap:\n *\n * /history — list the most-recent conversations\n * /history all — list every conversation in this workspace\n * /resume <conv-id> — switch the active chat thread to that conv\n *\n * Mirrors claude-code's session list + ``/resume`` flow. The data\n * comes from the existing ``conversations.listConversations`` SDK\n * call (newest-first server-side), so this is mostly a presentation\n * layer over already-shipped server functionality.\n */\n\nimport { conversations } from '@arbidocs/sdk'\nimport type { CommandDef, WorkspaceCommandContext } from '../command-registry.js'\nimport { colors } from '../theme/theme.js'\n\nconst DEFAULT_LIMIT = 10\n\n/** Minimal projection of the conversation list rows we render. */\nexport interface HistoryRow {\n external_id: string\n title: string | null\n updated_at?: string | null\n message_count?: number\n}\n\n/** Format a single history line — pure so the test can lock the\n * shape independently of the SDK shape drift. */\nexport function formatHistoryLine(row: HistoryRow): string {\n const title = row.title?.trim() || colors.muted('(untitled)')\n const count = typeof row.message_count === 'number' ? ` · ${row.message_count} msg` : ''\n const when = row.updated_at ? ` · ${formatRelativeTime(row.updated_at)}` : ''\n return ` ${colors.accent(row.external_id)} ${title}${colors.muted(count + when)}`\n}\n\n/** Render an ISO timestamp as a coarse relative label (\"3m ago\",\n * \"yesterday\", \"Mar 5\"). Falls back to the raw date string if\n * parsing fails so we never show garbage. */\nexport function formatRelativeTime(iso: string, now = new Date()): string {\n const t = new Date(iso)\n if (Number.isNaN(t.getTime())) return iso\n const seconds = Math.floor((now.getTime() - t.getTime()) / 1000)\n if (seconds < 60) return 'just now'\n if (seconds < 3600) return `${Math.floor(seconds / 60)}m ago`\n if (seconds < 86400) return `${Math.floor(seconds / 3600)}h ago`\n if (seconds < 86400 * 2) return 'yesterday'\n if (seconds < 86400 * 7) return `${Math.floor(seconds / 86400)}d ago`\n // Older than a week — show a calendar-ish anchor instead of \"23d\n // ago\" which becomes unhelpful once you scroll past a few weeks.\n return t.toLocaleDateString(undefined, { month: 'short', day: 'numeric' })\n}\n\nexport const historyCommands: CommandDef[] = [\n {\n name: 'history',\n description: 'Browse past conversations',\n argHint: 'count|all',\n requires: 'workspace',\n run: async (ctx) => {\n const { arbi, args } = ctx as WorkspaceCommandContext\n const arg = args[0]?.trim().toLowerCase()\n const convs = (await conversations.listConversations(arbi)) as HistoryRow[]\n\n if (convs.length === 0) {\n return 'No conversations yet in this workspace. Ask a question to start one.'\n }\n\n // Slice to the user-requested window. Default: most-recent 10.\n const slice = arg === 'all' ? convs : convs.slice(0, parseLimit(arg) ?? DEFAULT_LIMIT)\n\n const lines: string[] = [\n `Conversations (${slice.length}${slice.length < convs.length ? ` of ${convs.length}` : ''}):`,\n '',\n ]\n for (const row of slice) lines.push(formatHistoryLine(row))\n lines.push('')\n lines.push(colors.muted('Use /resume <conv-id> to switch to one of these.'))\n return lines\n },\n },\n {\n name: 'resume',\n description: 'Switch to a past conversation by ID',\n argHint: 'conv-id',\n minArgs: 1,\n requires: 'workspace',\n run: async (ctx) => {\n const { args, arbi, tui } = ctx as WorkspaceCommandContext\n const convId = args[0]!.trim()\n\n // Pull the full thread so we can set ``lastMessageExtId`` to the\n // leaf for proper continuity, AND replay the messages into the\n // chat log so the user sees the context they're resuming into.\n // Same data path that ``index.ts`` uses on startup, just driven\n // by the user here.\n const data = (await conversations.getConversationThreads(arbi, convId)) as {\n threads?: Array<{\n leaf_message_ext_id?: string\n history?: { role: string; content: string }[]\n }>\n }\n const threadList = data.threads ?? []\n const primary = threadList[0]\n if (!primary?.leaf_message_ext_id) {\n return `Conversation ${convId} not found or has no messages.`\n }\n\n // Wipe the current chat log and replay this conversation's\n // history into it. Same convention used on startup-restore so\n // the visual result is identical.\n tui.chatLog.clearMessages()\n for (const msg of primary.history ?? []) {\n if (msg.role === 'user') tui.chatLog.addUser(msg.content)\n else if (msg.role === 'assistant') tui.chatLog.addAssistant(msg.content)\n }\n tui.chatLog.addSystem(`--- resumed conversation ${convId} ---`, 'info')\n\n // Threading state: subsequent ``ask`` requests will chain off\n // this leaf and the right ``conversation_ext_id``.\n tui.state.conversationMessageId = primary.leaf_message_ext_id\n tui.store.updateChatSession({\n lastMessageExtId: primary.leaf_message_ext_id,\n conversationExtId: convId,\n })\n\n // Sources index is conversation-scoped. The resumed conversation\n // has its own history of citations; we don't have an easy way to\n // reconstruct it without re-streaming, so clear and let the next\n // turn re-populate from there.\n tui.sourcesIndex.clear()\n tui.lastMetadata = null\n\n tui.requestRender()\n return `Resumed conversation ${convId}.`\n },\n },\n]\n\n/** Parse a numeric limit arg. Returns ``undefined`` on anything that\n * isn't a positive integer so the caller falls back to default. */\nfunction parseLimit(arg: string | undefined): number | undefined {\n if (!arg) return undefined\n const n = Number.parseInt(arg, 10)\n return Number.isFinite(n) && n > 0 ? n : undefined\n}\n","/**\n * /skills — list user-invocable skills in the active workspace\n * /skill view <slug> — print a skill's SKILL.md body in the chat log\n * /skill source <slug> — print the source doc ID for editing externally\n * /skill edit <slug> — pull SKILL.md, open in $EDITOR, re-upload if changed\n *\n * Companion to the autocomplete provider (see ``tui.ts`` —\n * ``refreshSkillsCache`` populates ``tui.skillsCache``) and the\n * inline pre-flight hint that surfaces a skill's description when\n * the editor opens it.\n *\n * Skills live entirely server-side; these commands never run skill\n * logic locally. ``/skills`` / ``/skill view`` / ``/skill source``\n * are pure read-side surfaces. ``/skill edit`` is the one write\n * path: it round-trips SKILL.md through the user's ``$EDITOR`` and\n * re-uploads the result with ``wp_type=skill`` so the backend's\n * frontmatter loader picks up the newest version.\n */\n\nimport { spawnSync } from 'node:child_process'\nimport { mkdtempSync, readFileSync, writeFileSync, rmSync, statSync } from 'node:fs'\nimport { tmpdir } from 'node:os'\nimport { join } from 'node:path'\nimport { assistant, documents } from '@arbidocs/sdk'\nimport type { CommandDef, WorkspaceCommandContext } from '../command-registry.js'\nimport { colors } from '../theme/theme.js'\nimport { runInteractiveFlow } from '../tui-helpers.js'\n\nexport const skillCommands: CommandDef[] = [\n {\n name: 'skills',\n description: 'List user-invocable skills in the active workspace',\n requires: 'workspace',\n run: async (ctx) => {\n const { arbi, tui } = ctx as WorkspaceCommandContext\n const list = await assistant.listSkills(arbi)\n\n // Keep the cache fresh while we're at it — saves a refetch on\n // the next ``/skills`` invocation and primes the autocomplete\n // hint surface.\n tui.skillsCache = list\n\n if (list.length === 0) {\n return [\n 'No skills in this workspace yet.',\n colors.muted(\n 'Skills are documents with wp_type=skill. Upload a SKILL.md with frontmatter ' +\n '(name, description, user-invocable: true) to add one.'\n ),\n ]\n }\n\n const lines: string[] = [`Skills (${list.length}):`, '']\n for (const s of list) {\n const argHint = s.arg_hint ? colors.muted(` ${s.arg_hint}`) : ''\n const typeBadge =\n s.skill_type && s.skill_type !== 'markdown' ? colors.muted(` [${s.skill_type}]`) : ''\n lines.push(` ${colors.accent('/' + s.slug)}${argHint}${typeBadge}`)\n if (s.description) {\n lines.push(` ${colors.muted(s.description)}`)\n }\n }\n lines.push('')\n lines.push(\n colors.muted('Use /skill view <slug> to read a skill, /skill source <slug> for its doc-id.')\n )\n return lines\n },\n },\n {\n name: 'skill',\n description: 'Inspect or edit a skill (view | source | edit) <slug>',\n argHint: 'subcommand slug',\n minArgs: 2,\n requires: 'workspace',\n run: async (ctx) => {\n const { args, arbi, tui } = ctx as WorkspaceCommandContext\n const [sub, slug, ...rest] = args\n if (sub !== 'view' && sub !== 'source' && sub !== 'edit') {\n return (\n `Unknown /skill subcommand \"${sub}\". ` +\n 'Use /skill view <slug>, /skill source <slug>, or /skill edit <slug>.'\n )\n }\n void rest // future-proof for additional args\n\n // Lookup against the cache when available, else refetch. The\n // cache is populated by ``refreshSkillsCache`` on workspace\n // change and by ``/skills`` invocation.\n const list = tui.skillsCache?.length\n ? tui.skillsCache\n : await assistant.listSkills(arbi, { includeHidden: true })\n const skill = list.find((s) => s.slug === slug || s.name === slug)\n if (!skill) {\n return `No skill matching \"${slug}\" in this workspace. Use /skills to list available skills.`\n }\n\n if (sub === 'source') {\n return [\n colors.textBold(`${skill.name} (${skill.slug})`),\n colors.muted(`doc-id: ${skill.doc_ext_id}`),\n colors.muted(`workspace: ${skill.workspace_ext_id}`),\n colors.muted(\n 'Use `arbi upload --folder skills/<slug>` to replace the SKILL.md, or edit it via the web app.'\n ),\n ]\n }\n\n const { authHeaders } = ctx as WorkspaceCommandContext\n\n if (sub === 'edit') {\n // Round-trip the SKILL.md through ``$EDITOR``. We don't run a\n // diff in the TUI — the backend versions documents by upload\n // order, so a no-op re-upload would still bump the timestamp\n // and confuse cache observers. mtime check is good enough:\n // if the file's modification time hasn't moved, the user\n // never wrote, so skip the upload.\n return await editSkill(tui, authHeaders, skill)\n }\n\n // sub === 'view' — fetch the SKILL.md body via document\n // download. The marker parsing pipeline (``getParsedContent``)\n // runs only for source documents; skills bypass it because the\n // SKILL.md *is* the body — no chunking, no embedding needed.\n const dlRes = await documents.downloadDocument(authHeaders, skill.doc_ext_id)\n const body = dlRes.ok ? await dlRes.text() : ''\n\n const lines: string[] = [colors.textBold(`${skill.name} (${skill.slug})`)]\n if (skill.description) lines.push(colors.muted(skill.description))\n if (skill.arg_hint) lines.push(colors.muted(`args: ${skill.arg_hint}`))\n lines.push(colors.muted(`type: ${skill.skill_type} doc: ${skill.doc_ext_id}`))\n lines.push('')\n lines.push(body)\n return lines\n },\n },\n]\n\n// ── /skill edit ────────────────────────────────────────────────────────────\n\n/**\n * Pulls the skill's SKILL.md body, drops it in a temp file, spawns\n * ``$EDITOR`` against it (TUI paused so the editor owns the terminal),\n * then re-uploads if the user actually wrote.\n *\n * Why not use ``arbi upload --folder skills/<slug>``? Same end result,\n * but this command means the user never has to leave the TUI for the\n * common iteration loop \"tweak a skill, retry it.\" That's why\n * ``/skill source`` still exists for the rare case of editing in a\n * heavier IDE.\n */\nasync function editSkill(\n tui: import('../tui.js').ArbiTui,\n authHeaders: { baseUrl: string; accessToken: string },\n skill: { slug: string; name: string; doc_ext_id: string }\n): Promise<string | string[]> {\n // 1. Download current body. Same path as /skill view — no marker\n // pipeline, just the raw file bytes the user uploaded.\n const dlRes = await documents.downloadDocument(authHeaders, skill.doc_ext_id)\n if (!dlRes.ok) {\n return `Failed to fetch skill body (HTTP ${dlRes.status}). Edit aborted.`\n }\n const original = await dlRes.text()\n\n // 2. Drop into a per-call temp dir so we can clean up the whole\n // directory afterwards without worrying about ENOENT on a sibling.\n const dir = mkdtempSync(join(tmpdir(), `arbi-skill-${skill.slug}-`))\n const path = join(dir, 'SKILL.md')\n writeFileSync(path, original, 'utf8')\n const mtimeBefore = statSync(path).mtimeMs\n\n // 3. Spawn $EDITOR with the TUI paused. ``runInteractiveFlow``\n // releases stdin/stdout, runs the action, then reclaims them.\n // Fallback editor order: $VISUAL → $EDITOR → ``vi``. Same order\n // git uses, so users with a configured editor get it for free.\n const editor = process.env.VISUAL || process.env.EDITOR || 'vi'\n\n const result = await runInteractiveFlow(\n tui,\n colors.muted(`Opening ${skill.slug}/SKILL.md in ${editor}…`),\n async () => {\n const child = spawnSync(editor, [path], { stdio: 'inherit' })\n if (child.error) throw child.error\n if (child.status !== 0 && child.status !== null) {\n throw new Error(`${editor} exited with status ${child.status}`)\n }\n return readFileSync(path, 'utf8')\n },\n `Skill edit (${skill.slug}) failed`\n )\n\n // 4. Decide whether to re-upload. The mtime check catches \"user\n // quit without saving\" cleanly even if they wrote the same bytes\n // (e.g. closed via :q in vi without ever entering insert mode).\n const mtimeAfter = (() => {\n try {\n return statSync(path).mtimeMs\n } catch {\n return mtimeBefore\n }\n })()\n\n // Snapshot the body for upload before we tear down the temp dir.\n const updated = result ?? original\n rmSync(dir, { recursive: true, force: true })\n\n if (result === null) {\n // ``runInteractiveFlow`` already surfaced the error toast.\n return []\n }\n if (mtimeAfter === mtimeBefore || updated === original) {\n return colors.muted(`No changes to ${skill.slug}/SKILL.md — skill unchanged.`)\n }\n\n // 5. Re-upload. The backend treats ``wp_type='skill'`` + the same\n // folder path as a versioning hint — newest wins on\n // ``SkillManager.load_skill``. We don't need to delete the old\n // doc; it stays around as history and the loader ignores it.\n const blob = new Blob([updated], { type: 'text/markdown' })\n await documents.uploadFile(authHeaders, blob, 'SKILL.md', {\n folder: `skills/${skill.slug}`,\n wpType: 'skill',\n })\n\n // Refresh the cache so the autocomplete / dispatcher see any\n // frontmatter edits (e.g. ``description`` change) on the next\n // keystroke. Otherwise the user has to ``/skills`` manually.\n await tui.refreshSkillsCache()\n\n return [\n colors.textBold(`Updated ${skill.name} (${skill.slug})`),\n colors.muted('Skill cache refreshed — new description and args take effect immediately.'),\n ]\n}\n","/**\n * Command barrel — imports all domain command arrays and registers them.\n */\n\nimport { registerCommands } from '../command-registry.js'\nimport { generalCommands } from './general.js'\nimport { authCommands } from './auth.js'\nimport { workspaceCommands } from './workspace.js'\nimport { documentCommands } from './document.js'\nimport { conversationCommands } from './conversation.js'\nimport { tagCommands } from './tag.js'\nimport { miscCommands } from './misc.js'\nimport { citationCommands } from './citation.js'\nimport { eventCommands } from './events.js'\nimport { viewCommands } from './view.js'\nimport { sourcesCommands } from './sources.js'\nimport { historyCommands } from './history.js'\nimport { skillCommands } from './skills.js'\n\n/** Register all commands with the global registry. Call once at startup. */\nexport function registerAllCommands(): void {\n registerCommands(generalCommands)\n registerCommands(authCommands)\n registerCommands(workspaceCommands)\n registerCommands(documentCommands)\n registerCommands(conversationCommands)\n registerCommands(tagCommands)\n registerCommands(miscCommands)\n registerCommands(citationCommands)\n registerCommands(eventCommands)\n registerCommands(viewCommands)\n registerCommands(sourcesCommands)\n registerCommands(historyCommands)\n registerCommands(skillCommands)\n}\n","/**\n * SSE streaming event handler — wires @arbidocs/sdk streaming\n * into TUI component updates.\n */\n\nimport {\n getErrorMessage,\n streamSSE,\n formatAgentStepLabel,\n formatStreamSummary,\n countCitations,\n type SSEStreamCallbacks,\n type SSEStreamResult,\n type AgentStepEvent,\n} from '@arbidocs/sdk'\nimport type { ArbiTui } from './tui.js'\nimport type { AgentStepDetails } from './components/agent-step.js'\n\n/**\n * Pull out structured tool details from an ``AgentStepEvent`` so the\n * chat log can render claude-code-style tool blocks (header + indented\n * tool / args / result lines) instead of a flat label.\n *\n * The backend's ``tool_progress`` events typically carry a single\n * ``detail`` entry shaped ``{ tool, label, message }``:\n * - ``tool`` — the tool name (e.g. ``retrieval_chunk``)\n * - ``label`` — already used as the step's headline by\n * ``formatAgentStepLabel``, so we don't repeat it\n * - ``message`` — a one-line summary, which we surface as either\n * ``args`` (when the step is starting) or ``result`` (when it's\n * finishing). We can't always tell the two apart from the wire\n * format, so for now we attribute it to ``args`` — which renders\n * as \"args: <message>\" beneath the header. Cleaner than dropping\n * it on the floor; we can split start/finish when the schema\n * gains a status field.\n */\nexport function extractStepDetails(data: AgentStepEvent): AgentStepDetails | undefined {\n const detail = data.detail as\n | Array<{ tool?: string; label?: string; message?: string }>\n | undefined\n if (!detail || detail.length === 0) return undefined\n const d = detail[0]\n if (!d) return undefined\n const result: AgentStepDetails = {}\n if (d.tool) result.tool = d.tool\n if (d.message) result.args = d.message\n return result.tool || result.args || result.result ? result : undefined\n}\n\n/**\n * Stream an assistant response from the API into the TUI.\n *\n * 1. Creates an assistant message in the chat log\n * 2. Streams tokens into it via SSE callbacks\n * 3. Displays agent steps as they arrive\n * 4. Finalizes when complete\n *\n * Returns the full SSE result for caller to extract metadata.\n */\nexport async function streamResponse(tui: ArbiTui, response: Response): Promise<SSEStreamResult> {\n tui.chatLog.startAssistant()\n tui.state.activityStatus = 'streaming'\n tui.requestRender()\n\n let accumulated = ''\n let elapsedTime: number | null = null\n let firstToken = true\n\n const callbacks: SSEStreamCallbacks = {\n onStreamStart: (data) => {\n if (data.assistant_message_ext_id) {\n tui.state.conversationMessageId = data.assistant_message_ext_id\n }\n },\n\n onToken: (content) => {\n if (firstToken) {\n firstToken = false\n tui.chatLog.clearActiveSteps()\n }\n accumulated += content\n tui.chatLog.updateAssistant(accumulated)\n tui.requestRender()\n },\n\n onAgentStep: (data) => {\n const label = formatAgentStepLabel(data)\n if (label) {\n tui.chatLog.addAgentStep(label, extractStepDetails(data))\n tui.requestRender()\n }\n },\n\n onElapsedTime: (t) => {\n elapsedTime = t\n },\n\n onError: (message) => {\n tui.chatLog.addSystem(`Stream error: ${message}`, 'error')\n tui.requestRender()\n },\n }\n\n try {\n const result = await streamSSE(response, callbacks)\n tui.chatLog.finalizeAssistant()\n\n // Store metadata for /cite command\n tui.lastMetadata = result.metadata ?? null\n\n // Fold this turn's citations into the conversation-wide sources\n // index so ``/sources`` can show the running list of documents\n // backing the discussion. Idempotent on the same metadata blob.\n tui.sourcesIndex.recordCitations(result.metadata)\n\n // Build summary with citation count\n const summary = formatStreamSummary(result, elapsedTime)\n if (summary) {\n const refs = countCitations(result.metadata ?? null)\n const refSuffix = refs > 0 ? ` · ${refs} ref${refs === 1 ? '' : 's'}` : ''\n tui.chatLog.addSummary(`[${summary}${refSuffix}]`)\n }\n\n tui.state.activityStatus = 'idle'\n tui.requestRender()\n return result\n } catch (err) {\n tui.chatLog.finalizeAssistant()\n tui.state.activityStatus = 'error'\n tui.chatLog.addSystem(`Streaming failed: ${getErrorMessage(err)}`, 'error')\n tui.requestRender()\n throw err\n }\n}\n","/**\n * DM handler — encryption setup, send/receive, channel switching.\n *\n * Manages the DM channel state and E2E encrypted messaging.\n * Uses the same ECDH encryption pattern as the React frontend.\n */\n\nimport { getErrorMessage, dm, contacts } from '@arbidocs/sdk'\nimport {\n base64ToBytes,\n deriveEncryptionKeypairFromSigning,\n encryptMessage,\n decryptMessage,\n type KeyPair,\n type WsNotificationResponse,\n} from '@arbidocs/client'\nimport type { ArbiTui } from './tui.js'\nimport { colors } from './theme/theme.js'\nimport { showMessage } from './tui-helpers.js'\n\n// ── Types ────────────────────────────────────────────────────────────────────\n\nexport interface DmContact {\n external_id: string\n email: string\n encryption_public_key: string\n given_name: string\n family_name?: string | null\n}\n\nexport interface DmChannel {\n user: DmContact\n}\n\n// ── Encryption keypair derivation ────────────────────────────────────────────\n\n/**\n * Derive X25519 encryption keypair from the stored Ed25519 signing key.\n * Called once after login.\n */\nexport function deriveEncryptionKeypair(signingPrivateKeyBase64: string): KeyPair {\n const signingPrivateKey = base64ToBytes(signingPrivateKeyBase64)\n // Ed25519 public key is the last 32 bytes of the 64-byte private key\n const ed25519PublicKey = signingPrivateKey.slice(32, 64)\n return deriveEncryptionKeypairFromSigning({\n publicKey: ed25519PublicKey,\n secretKey: signingPrivateKey,\n })\n}\n\n// ── Recipient resolution ─────────────────────────────────────────────────────\n\n/**\n * Resolve a @query to a contact user.\n * Matches by email prefix or given_name (case-insensitive).\n * Returns the matched contact user, or null if not found/ambiguous.\n */\nexport async function resolveRecipient(tui: ArbiTui, query: string): Promise<DmContact | null> {\n if (!tui.authContext) {\n showMessage(tui, 'Not authenticated. Use /login first.', 'error')\n return null\n }\n\n const queryLower = query.toLowerCase()\n\n try {\n const contactList = await contacts.listContacts(tui.authContext.arbi)\n\n // Filter for registered contacts with encryption keys\n const registered = contactList.filter(\n (c) => c.status === 'registered' && c.user?.encryption_public_key\n )\n\n // Match by email prefix (before @) or given_name\n const matches = registered.filter((c) => {\n const emailPrefix = c.email.split('@')[0]?.toLowerCase()\n const givenName = c.user?.given_name?.toLowerCase()\n return emailPrefix === queryLower || givenName === queryLower\n })\n\n if (matches.length === 0) {\n showMessage(\n tui,\n `No registered contact matching \"${query}\". Use /contacts to see available contacts.`,\n 'warning'\n )\n return null\n }\n\n if (matches.length > 1) {\n const names = matches\n .map((c) => ` ${c.email} (${c.user?.given_name ?? ''} ${c.user?.family_name ?? ''})`)\n .join('\\n')\n showMessage(tui, `Ambiguous match for \"${query}\". Be more specific:\\n${names}`, 'warning')\n return null\n }\n\n const contact = matches[0]\n const user = contact.user!\n return {\n external_id: user.external_id,\n email: contact.email,\n encryption_public_key: user.encryption_public_key,\n given_name: user.given_name,\n family_name: user.family_name,\n }\n } catch (err) {\n showMessage(tui, `Failed to resolve contact: ${getErrorMessage(err)}`, 'error')\n return null\n }\n}\n\n// ── Channel switching ────────────────────────────────────────────────────────\n\n/**\n * Handle @input — switch to DM channel or back to arbi.\n */\nexport async function handleChannelSwitch(tui: ArbiTui, input: string): Promise<void> {\n const query = input.slice(1).trim() // Remove leading @\n\n if (!query) {\n showMessage(tui, 'Usage: @username to switch to DM, @arbi to switch back.', 'warning')\n return\n }\n\n // @arbi — switch back to AI chat\n if (query.toLowerCase() === 'arbi') {\n switchToArbi(tui)\n return\n }\n\n // Resolve recipient\n const user = await resolveRecipient(tui, query)\n if (!user) return\n\n await switchToDmChannel(tui, user)\n}\n\n/**\n * Switch to a DM channel with a specific user.\n * Updates header, clears chat, loads DM history.\n */\nexport async function switchToDmChannel(tui: ArbiTui, user: DmContact): Promise<void> {\n if (!tui.authContext || !tui.encryptionKeys) {\n showMessage(tui, 'Not authenticated or encryption not initialized.', 'error')\n return\n }\n\n // Set channel state\n tui.currentDmChannel = { user }\n tui.updateHeader()\n\n // Clear chat log for DM view\n tui.chatLog.clearMessages()\n\n showMessage(tui, `Switched to DM with ${colors.accent(user.email)}. Type @arbi to switch back.`)\n\n // Fetch and display DM history\n await loadDmHistory(tui, user)\n}\n\n/**\n * Switch back to AI chat mode.\n */\nexport function switchToArbi(tui: ArbiTui): void {\n if (!tui.currentDmChannel) {\n showMessage(tui, 'Already in AI chat mode.', 'info')\n return\n }\n\n tui.currentDmChannel = null\n tui.updateHeader()\n\n // Clear chat log for fresh AI view\n tui.chatLog.clearMessages()\n showMessage(tui, 'Switched back to AI chat.')\n}\n\n// ── DM history ───────────────────────────────────────────────────────────────\n\n/**\n * Fetch all DMs and display the conversation with a specific user.\n */\nasync function loadDmHistory(tui: ArbiTui, user: DmContact): Promise<void> {\n if (!tui.authContext || !tui.encryptionKeys) return\n\n const myExtId = tui.authContext.loginResult.userExtId\n\n try {\n const allDms = await dm.listDMs(tui.authContext.arbi)\n\n // Filter for DMs between us and this user (type === 'user_message')\n const conversation = allDms.filter(\n (msg) =>\n msg.type === 'user_message' &&\n ((msg.sender.external_id === user.external_id && msg.recipient.external_id === myExtId) ||\n (msg.sender.external_id === myExtId && msg.recipient.external_id === user.external_id))\n )\n\n // Sort by created_at ascending\n conversation.sort((a, b) => new Date(a.created_at).getTime() - new Date(b.created_at).getTime())\n\n // Mark unread messages as read\n const unreadIds = conversation\n .filter((msg) => !msg.read && msg.sender.external_id === user.external_id)\n .map((msg) => msg.external_id)\n\n if (unreadIds.length > 0) {\n dm.markRead(tui.authContext.arbi, unreadIds).catch(() => {\n // Non-fatal — just log\n })\n }\n\n // Decrypt and display messages\n for (const msg of conversation) {\n const isSent = msg.sender.external_id === myExtId\n const plaintext = await decryptNotification(msg, myExtId!, tui.encryptionKeys, user)\n if (plaintext) {\n displayDmMessage(tui, plaintext, isSent, user.email)\n }\n }\n\n tui.requestRender()\n } catch (err) {\n showMessage(tui, `Failed to load DM history: ${getErrorMessage(err)}`, 'error')\n }\n}\n\n// ── Send encrypted DM ────────────────────────────────────────────────────────\n\n/**\n * Encrypt and send a DM to the current channel's recipient.\n */\nexport async function sendEncryptedDm(tui: ArbiTui, plaintext: string): Promise<void> {\n if (!tui.authContext || !tui.encryptionKeys || !tui.currentDmChannel) {\n showMessage(tui, 'Cannot send DM — not in a DM channel.', 'error')\n return\n }\n\n const recipient = tui.currentDmChannel.user\n\n try {\n // Encrypt the message\n const encrypted = await encryptMessage(\n plaintext,\n recipient.encryption_public_key,\n tui.encryptionKeys.secretKey\n )\n\n // Send via API\n await dm.sendDM(tui.authContext.arbi, [\n { recipient_ext_id: recipient.external_id, content: encrypted },\n ])\n\n // Display sent message in chat log\n displayDmMessage(tui, plaintext, true, recipient.email)\n tui.requestRender()\n } catch (err) {\n showMessage(tui, `Failed to send DM: ${getErrorMessage(err)}`, 'error')\n }\n}\n\n// ── Incoming DM handling (from WebSocket) ────────────────────────────────────\n\n/**\n * Handle an incoming WebSocket DM notification.\n * If we're in a DM channel with the sender, show it inline and return true.\n * Otherwise return false (caller shows toast).\n */\nexport async function handleIncomingDm(\n tui: ArbiTui,\n msg: WsNotificationResponse\n): Promise<boolean> {\n if (!tui.currentDmChannel || !tui.encryptionKeys || !tui.authContext) {\n return false\n }\n\n const myExtId = tui.authContext.loginResult.userExtId\n const channelUserId = tui.currentDmChannel.user.external_id\n\n // Check if this message is from the user we're chatting with\n if (msg.sender.external_id !== channelUserId) {\n return false\n }\n\n // Decrypt and display inline\n const plaintext = await decryptNotification(\n msg,\n myExtId!,\n tui.encryptionKeys,\n tui.currentDmChannel.user\n )\n\n if (plaintext) {\n displayDmMessage(tui, plaintext, false, msg.sender.email)\n tui.requestRender()\n\n // Mark as read\n dm.markRead(tui.authContext.arbi, [msg.external_id]).catch(() => {\n // Non-fatal\n })\n }\n\n return true\n}\n\n// ── Decryption helper ────────────────────────────────────────────────────────\n\n/**\n * Decrypt a notification's content field.\n *\n * For received messages: decrypt with sender's public key + our private key.\n * For sent messages: decrypt with recipient's public key + our private key.\n */\nasync function decryptNotification(\n notification: WsNotificationResponse,\n _myExtId: string,\n encryptionKeyPair: KeyPair,\n otherUser: DmContact\n): Promise<string | null> {\n if (!notification.content) return null\n\n try {\n // ECDH decryption uses the other party's public key in both cases\n return await decryptMessage(\n notification.content,\n otherUser.encryption_public_key,\n encryptionKeyPair.secretKey\n )\n } catch {\n return '[decryption failed]'\n }\n}\n\n// ── Display helper ───────────────────────────────────────────────────────────\n\n/**\n * Display a DM message in the chat log.\n * Sent messages show \"You:\", received show the sender's email.\n */\nfunction displayDmMessage(tui: ArbiTui, text: string, isSent: boolean, senderEmail: string): void {\n if (isSent) {\n tui.chatLog.addUser(text)\n } else {\n tui.chatLog.addDm(senderEmail, text)\n }\n}\n","/**\n * WebSocket handler — routes incoming WS messages to two surfaces:\n *\n * 1. ``tui.eventLog`` — **always** recorded. The persistent\n * scrollback that ``/events`` replays. Nothing is dropped here so\n * a session can be reviewed end-to-end after the fact.\n *\n * 2. ``ToastContainer`` — **only the important ones**. Errors and\n * terminal task statuses (completed/failed) pop a toast for\n * immediate visibility. Routine traffic (presence pings,\n * in-progress updates) only goes into the log, mirroring the\n * claude-code policy of \"every event is captured, only\n * noteworthy ones interrupt\".\n *\n * Uses ``connectWithReconnect()`` and ``formatWsMessage()`` from\n * the SDK for connection/auth + shared formatting.\n */\n\nimport {\n connectWithReconnect,\n formatWsMessage,\n type ReconnectableWsConnection,\n} from '@arbidocs/sdk'\nimport { type WebSocketServerMessage, type WsNotificationResponse } from '@arbidocs/client'\nimport type { ArbiTui } from './tui.js'\nimport type { ToastContainer, ToastLevel } from './components/toast-container.js'\nimport { handleIncomingDm } from './dm-handler.js'\nimport type { WsEventLog, WsEventLevel } from './event-log.js'\n\n// ── Duration constants ────────────────────────────────────────────────────────\n\nconst DURATION_SHORT = 3000 // frequent in-progress updates\nconst DURATION_DEFAULT = 5000 // completed tasks, batch, notifications\nconst DURATION_LONG = 8000 // errors — longer so user notices\n\n// ── Duration mapping by level ────────────────────────────────────────────────\n\nconst DURATION_BY_LEVEL: Record<string, number> = {\n info: DURATION_SHORT,\n success: DURATION_DEFAULT,\n error: DURATION_LONG,\n warning: DURATION_DEFAULT,\n}\n\n// ── Helpers ──────────────────────────────────────────────────────────────────\n\n/** NotificationResponse uses NotificationType as its `type` field, not a single literal. */\nfunction isNotification(msg: WebSocketServerMessage): msg is WsNotificationResponse {\n return 'sender' in msg && 'recipient' in msg\n}\n\n// ── Message routing ───────────────────────────────────────────────────────────\n\n/** Decide whether a given message should ALSO pop a toast on top of\n * being logged. The rules are conservative: only pop on terminal\n * states (success/error/warning) and ``response_complete`` /\n * ``batch_complete`` which represent finished long-running work.\n * Routine ``info`` traffic (presence pings, in-progress updates)\n * stays in the log only — visible in ``/events`` but not flashing in\n * the user's face. */\nfunction shouldToast(level: WsEventLevel, msgType: string | undefined): boolean {\n if (level === 'error' || level === 'warning' || level === 'success') return true\n // Terminal completions on the info path (rare, but possible).\n if (msgType === 'response_complete' || msgType === 'batch_complete') return true\n return false\n}\n\nasync function handleMessage(\n msg: WebSocketServerMessage,\n toasts: ToastContainer,\n eventLog: WsEventLog,\n tui: ArbiTui | null\n): Promise<void> {\n // DM routing — TUI-specific: route user_message to the DM chat log.\n // DMs are first-class chat content and intentionally bypass both\n // the toast and the event log (the chat log itself is the persistent\n // surface for them).\n if (isNotification(msg) && msg.type === 'user_message' && tui) {\n const handled = await handleIncomingDm(tui, msg)\n if (handled) return\n }\n\n // Use shared formatter for text + level. Stable across CLI/TUI so\n // both surfaces agree on what a given event means.\n const { text, level } = formatWsMessage(msg)\n const msgType = (msg as { type?: string }).type\n eventLog.add({ text, level: level as WsEventLevel, msgType })\n\n if (shouldToast(level as WsEventLevel, msgType)) {\n const duration = DURATION_BY_LEVEL[level] ?? DURATION_DEFAULT\n toasts.show(text, level as ToastLevel, duration)\n }\n}\n\n// ── Public API ────────────────────────────────────────────────────────────────\n\nexport interface TuiWsOptions {\n baseUrl: string\n accessToken: string\n toasts: ToastContainer\n eventLog: WsEventLog\n tui?: ArbiTui\n}\n\n/**\n * Connect WebSocket with auto-reconnection and route messages to both\n * the persistent event log and (selectively) the toast container.\n * Returns the connection handle for cleanup, or null on failure.\n */\nexport async function connectTuiWebSocket(\n options: TuiWsOptions\n): Promise<ReconnectableWsConnection | null> {\n const { baseUrl, accessToken, toasts, eventLog, tui } = options\n\n // Transport-level events (connect/disconnect/reconnect) are always\n // worth surfacing because they affect the user's ability to do\n // anything else. So they get both log + toast, not the routine\n // filter.\n const recordTransport = (text: string, level: WsEventLevel): void => {\n eventLog.add({ text, level })\n const duration = DURATION_BY_LEVEL[level] ?? DURATION_DEFAULT\n toasts.show(text, level as ToastLevel, duration)\n }\n\n try {\n const connection = await connectWithReconnect({\n baseUrl,\n accessToken,\n onMessage: (msg) => handleMessage(msg, toasts, eventLog, tui ?? null),\n onClose: () => recordTransport('WebSocket disconnected', 'warning'),\n onReconnecting: (attempt, maxRetries) =>\n recordTransport(`Reconnecting... (${attempt}/${maxRetries})`, 'warning'),\n onReconnected: () => recordTransport('WebSocket reconnected', 'success'),\n onReconnectFailed: () => recordTransport('WebSocket reconnection failed', 'error'),\n })\n return connection\n } catch {\n // Auth failure or connection error — not fatal, just skip WS\n recordTransport('WebSocket connection failed', 'warning')\n return null\n }\n}\n","/**\n * ArbiTui — main orchestrator for the ARBI terminal UI.\n *\n * Manages state, component wiring, and lifecycle. Coordinates between\n * the editor input, chat log display, command dispatch, and SSE streaming.\n */\n\nimport {\n TUI,\n ProcessTerminal,\n Text,\n Spacer,\n CombinedAutocompleteProvider,\n matchesKey,\n Key,\n type Component,\n type OverlayHandle,\n} from '@mariozechner/pi-tui'\nimport {\n type AuthContext,\n type WorkspaceContext,\n type ReconnectableWsConnection,\n type ConfigStore,\n type MessageMetadataPayload,\n type SkillSummary,\n getErrorMessage,\n assistant,\n documents,\n countCitations,\n parseSlashCommand,\n} from '@arbidocs/sdk'\nimport type { KeyPair } from '@arbidocs/client'\nimport { ChatLog } from './components/chat-log.js'\nimport { WsEventLog } from './event-log.js'\nimport { SourcesIndex } from './sources-index.js'\nimport { ArbiEditor } from './components/arbi-editor.js'\nimport { ToastContainer } from './components/toast-container.js'\nimport { dispatchCommand, toSlashCommands, toSlashCommandsWithSkills } from './command-registry.js'\nimport { registerAllCommands } from './commands/index.js'\nimport { streamResponse } from './event-handlers.js'\nimport { connectTuiWebSocket } from './ws-handler.js'\nimport {\n type DmChannel,\n deriveEncryptionKeypair,\n handleChannelSwitch,\n sendEncryptedDm,\n} from './dm-handler.js'\nimport { colors, formatHeader } from './theme/theme.js'\nimport { showMessage } from './tui-helpers.js'\n\n// ── State ──────────────────────────────────────────────────────────────────\n\nexport interface TuiState {\n workspaceId: string | null\n workspaceName: string | null\n conversationMessageId: string | null\n activityStatus: 'idle' | 'sending' | 'streaming' | 'error'\n isAuthenticated: boolean\n}\n\n// ── Main TUI class ─────────────────────────────────────────────────────────\n\nexport class ArbiTui {\n private tui: TUI\n private header: Text\n\n /** The chat message log — public so command handlers can add messages. */\n readonly chatLog: ChatLog\n\n /** Toast notifications from WebSocket events. */\n readonly toastContainer: ToastContainer\n\n /** The input editor. */\n private editor: ArbiEditor\n\n /** Application state — public so handlers can read/write it. */\n state: TuiState\n\n /** Auth context from @arbidocs/sdk — set during init. */\n authContext: AuthContext | null = null\n\n /** Workspace context with tokens/headers — set when workspace is selected. */\n private workspaceContext: WorkspaceContext | null = null\n\n /** Config store for persistence. */\n readonly store: ConfigStore\n\n /** Active WebSocket connection (null when not connected). */\n private wsConnection: ReconnectableWsConnection | null = null\n\n /** X25519 encryption keypair derived from signing key (null until login). */\n private encryptionKeyPair: KeyPair | null = null\n\n /** Current DM channel (null = AI chat mode). */\n private dmChannel: DmChannel | null = null\n\n /** Last response metadata — used by /cite for citation browsing. */\n lastMetadata: MessageMetadataPayload | null = null\n\n /** Persistent log of WebSocket events for this session. Toasts are\n * ephemeral; this is the \"what happened?\" scrollback that\n * ``/events`` reads from. Public so ws-handler can append and the\n * events command can read. */\n readonly eventLog = new WsEventLog()\n\n /** Running tally of documents cited in the current conversation.\n * Cleared on ``/new``; appended to after every assistant response\n * that carries citation metadata. Drives ``/sources`` and (later)\n * the persistent right-side sources panel. */\n readonly sourcesIndex = new SourcesIndex()\n\n /** Cached list of user-invocable skills in the active workspace.\n * Refreshed on workspace switch (``setWorkspaceContext``) and\n * invalidated to ``[]`` when leaving a workspace. Drives the\n * autocomplete provider and the ``/skills`` / ``/skill view``\n * commands. ``null`` means \"haven't fetched yet\"; ``[]`` means\n * \"fetched, no skills exist\". */\n skillsCache: SkillSummary[] = []\n\n /** Active citation overlay handle (null when not showing). */\n private citationOverlay: OverlayHandle | null = null\n\n /** Input listener ID for overlay dismiss (null when no overlay). */\n private overlayInputListener: (() => void) | null = null\n\n constructor(store: ConfigStore) {\n this.store = store\n\n this.state = {\n workspaceId: null,\n workspaceName: null,\n conversationMessageId: null,\n activityStatus: 'idle',\n isAuthenticated: false,\n }\n\n // Register all slash commands with the declarative registry\n registerAllCommands()\n\n // Build TUI component tree\n this.tui = new TUI(new ProcessTerminal())\n\n // Header\n this.header = new Text(formatHeader(null, 'starting...'), 1, 0)\n\n // Chat log\n this.chatLog = new ChatLog()\n\n // Toast container for WebSocket notifications\n this.toastContainer = new ToastContainer()\n this.toastContainer.setRenderCallback(() => this.tui.requestRender())\n\n // Editor\n this.editor = this.createEditor()\n\n // Compose layout\n this.tui.addChild(this.header)\n this.tui.addChild(new Spacer(1))\n this.tui.addChild(this.toastContainer)\n this.tui.addChild(this.chatLog)\n this.tui.addChild(this.editor)\n\n this.tui.setFocus(this.editor)\n }\n\n // ── Lifecycle ──────────────────────────────────────────────────────────\n\n /** Start the TUI event loop (clears screen for fullscreen layout). */\n start(): void {\n this.tui.start()\n this.updateHeader()\n this.tui.requestRender(true)\n }\n\n /** Gracefully shut down the TUI and exit. */\n shutdown(): void {\n this.wsConnection?.close()\n this.wsConnection = null\n this.toastContainer.clear()\n this.tui.stop()\n process.exit(0)\n }\n\n /**\n * Temporarily stop the TUI (releases terminal raw mode).\n * Used before interactive prompts that need stdin (login, register).\n */\n stopTui(): void {\n this.tui.stop()\n }\n\n /**\n * Restart the TUI after a stopTui() call.\n * Rebuilds the component tree with a fresh TUI instance since\n * pi-tui doesn't support stop/start cycling on the same instance.\n */\n restartTui(): void {\n this.tui = new TUI(new ProcessTerminal())\n\n // Re-compose layout\n this.tui.addChild(this.header)\n this.tui.addChild(new Spacer(1))\n this.tui.addChild(this.toastContainer)\n this.tui.addChild(this.chatLog)\n\n // Create new editor (needs fresh TUI reference)\n this.editor = this.createEditor()\n this.tui.addChild(this.editor)\n this.tui.setFocus(this.editor)\n\n this.tui.start()\n this.updateHeader()\n this.tui.requestRender(true)\n }\n\n /** Create and wire a new editor instance. */\n private createEditor(): ArbiEditor {\n const editor = new ArbiEditor(this.tui)\n // pi-tui's ``CombinedAutocompleteProvider`` now requires\n // ``basePath`` (cwd for file-completion) alongside the command\n // list. The TUI doesn't lean on file completions, so the process\n // cwd is the right neutral default.\n editor.setAutocompleteProvider(\n new CombinedAutocompleteProvider(toSlashCommands(), process.cwd())\n )\n editor.onSubmit = (text: string) => this.handleSubmit(text)\n editor.onEscape = () => this.handleAbort()\n editor.onCtrlC = () => this.shutdown()\n editor.onCtrlD = () => this.shutdown()\n editor.onCtrlW = () => this.handleSubmit('/workspaces')\n editor.onCtrlN = () => this.handleSubmit('/new')\n // Alt+1..9 jumps straight to citation N. The ``/cite`` command\n // already handles \"no citations available\" / \"citation not found\"\n // messaging, so we just route the keypress through the same code\n // path the user would have typed.\n editor.onCitationKey = (n: number) => this.handleSubmit(`/cite ${n}`)\n // Pre-flight skill hint. Fires every time the buffer changes;\n // ``handleBufferChange`` self-dedupes so the chat log doesn't\n // get spammed when the user is still typing the same slug.\n editor.onBufferChange = (text: string) => this.handleBufferChange(text)\n return editor\n }\n\n /** The slug we last surfaced as a pre-flight hint. ``null`` once\n * the user has navigated away from the skill prefix (e.g. typed a\n * non-slash char first, or deleted past the slash). Tracking this\n * here — not in the editor — keeps the editor pure: it just emits\n * text, the TUI decides what's interesting. */\n private lastHintedSlug: string | null = null\n\n /**\n * Pre-flight skill hint dispatcher.\n *\n * Watches the editor buffer; when it starts with ``/<token>`` where\n * ``<token>`` is a slug in ``skillsCache`` *and* not also a static\n * command (those have their own ``--help`` style help), we drop a\n * one-line description into the chat log so the user sees what\n * they're about to invoke before pressing Enter. Equivalent of\n * claude-code's slash-command palette preview, minus the modal.\n *\n * Dedup rule: only emit when the matched slug *changes*. Typing\n * \"/foo\" → \"/foob\" → \"/foo\" emits once for ``foo``, never for the\n * intermediate ``foob`` (no match), and not again when the user\n * lands back on ``foo``. The state resets whenever the buffer no\n * longer matches anything, so a fresh ``/foo`` after a clear emits\n * the hint again.\n */\n private handleBufferChange(text: string): void {\n // Canonical parse — same helper the React menu and TUI dispatcher\n // use. ``parseSlashCommand`` returns ``null`` for non-slash\n // buffers, including empty input, so the early-return covers all\n // the \"user isn't typing a slash command\" cases in one branch.\n const parsed = parseSlashCommand(text)\n if (!parsed) {\n this.lastHintedSlug = null\n return\n }\n const slug = parsed.slug\n\n // Static commands win — they have their own help surface\n // (``/help``), so showing skill metadata for a same-named slug\n // would be the wrong thing. The autocomplete merge in\n // ``toSlashCommandsWithSkills`` applies the same rule.\n if (this.skillsCache.length === 0) return\n const skill = this.skillsCache.find((s) => s.slug === slug)\n if (!skill) {\n this.lastHintedSlug = null\n return\n }\n if (this.lastHintedSlug === slug) return\n this.lastHintedSlug = slug\n\n const argHint = skill.arg_hint ? ` ${skill.arg_hint}` : ''\n showMessage(this, `Skill: /${skill.slug}${argHint} — ${skill.description}`, 'info')\n }\n\n /** Request a render update. */\n requestRender(): void {\n this.tui.requestRender()\n }\n\n // ── Auth / Workspace ───────────────────────────────────────────────────\n\n /** Set authentication context after login. */\n setAuthContext(ctx: AuthContext): void {\n this.authContext = ctx\n this.state.isAuthenticated = true\n this.encryptionKeyPair = deriveEncryptionKeypair(\n this.store.requireCredentials().signingPrivateKeyBase64\n )\n this.updateHeader()\n }\n\n /** Set workspace context after workspace selection. */\n setWorkspaceContext(ctx: WorkspaceContext): void {\n this.workspaceContext = ctx\n this.state.workspaceId = ctx.workspaceId\n // Workspace name will be set separately since WorkspaceContext doesn't include it\n this.updateHeader()\n this.connectWebSocket()\n // Best-effort refresh of the skills cache so autocomplete picks\n // up workspace-specific skills. Failures are swallowed — skills\n // are an aid, not a critical path; absence falls back to the\n // static slash-command list.\n void this.refreshSkillsCache()\n }\n\n /** Refresh the cached skills list for the current workspace. Called\n * on workspace switch and from ``/skills`` itself so a freshly\n * uploaded skill becomes invocable without a TUI restart. */\n async refreshSkillsCache(): Promise<void> {\n if (!this.workspaceContext) {\n this.skillsCache = []\n this.rebuildAutocomplete()\n return\n }\n try {\n this.skillsCache = await assistant.listSkills(this.workspaceContext.arbi)\n } catch {\n // Older backends without the endpoint will 404 — autocomplete\n // simply won't surface skills until the backend ships\n // ``GET /v1/assistant/skills``. Not a failure.\n this.skillsCache = []\n }\n this.rebuildAutocomplete()\n }\n\n /** Re-feed the editor's autocomplete provider with the merged\n * static-commands + skills list. Called on workspace switch and\n * after every ``refreshSkillsCache`` so a newly uploaded skill\n * appears in tab-complete without a TUI restart. */\n private rebuildAutocomplete(): void {\n if (!this.editor) return\n const merged = toSlashCommandsWithSkills(\n this.skillsCache.map((s) => ({ slug: s.slug, description: s.description }))\n )\n this.editor.setAutocompleteProvider(new CombinedAutocompleteProvider(merged, process.cwd()))\n }\n\n /** Refresh workspace context (after switching workspaces). */\n async refreshWorkspaceContext(): Promise<void> {\n if (!this.state.workspaceId || !this.authContext) return\n\n const { resolveWorkspace } = await import('@arbidocs/sdk')\n const ctx = await resolveWorkspace(this.store, this.state.workspaceId)\n this.workspaceContext = ctx\n this.updateHeader()\n }\n\n /** Public accessor for workspace context (used by command handlers). */\n get wsContext(): WorkspaceContext | null {\n return this.workspaceContext\n }\n\n /** Whether the WebSocket is currently connected. */\n get wsConnected(): boolean {\n return this.wsConnection !== null\n }\n\n /** Connect (or reconnect) WebSocket for real-time notifications. */\n private connectWebSocket(): void {\n if (!this.workspaceContext) return\n\n // Close existing connection before reconnecting\n this.wsConnection?.close()\n this.wsConnection = null\n\n const { config, accessToken } = this.workspaceContext\n\n connectTuiWebSocket({\n baseUrl: config.baseUrl,\n accessToken,\n toasts: this.toastContainer,\n eventLog: this.eventLog,\n tui: this,\n }).then((conn) => {\n this.wsConnection = conn\n })\n }\n\n // ── Input handling ─────────────────────────────────────────────────────\n\n private async handleSubmit(text: string): Promise<void> {\n const trimmed = text.trim()\n if (!trimmed) return\n\n // Check for @channel switching\n if (trimmed.startsWith('@')) {\n await handleChannelSwitch(this, trimmed)\n return\n }\n\n // Check for slash commands\n if (trimmed.startsWith('/')) {\n const handled = await dispatchCommand(this, trimmed)\n if (handled) return\n }\n\n // Route to DM or AI based on channel\n if (this.dmChannel) {\n await sendEncryptedDm(this, trimmed)\n } else {\n await this.sendMessage(trimmed)\n }\n }\n\n private handleAbort(): void {\n if (this.state.activityStatus === 'streaming') {\n // TODO: implement AbortController for stream cancellation\n this.chatLog.addSystem('Abort requested (stream will complete current chunk).', 'warning')\n this.requestRender()\n }\n }\n\n // ── Messaging ──────────────────────────────────────────────────────────\n\n private async sendMessage(question: string): Promise<void> {\n if (!this.workspaceContext) {\n this.chatLog.addSystem(\n 'No workspace selected. Use /workspace <id> or /workspaces to choose one.',\n 'warning'\n )\n this.requestRender()\n return\n }\n\n // Display user message\n this.chatLog.addUser(question)\n this.state.activityStatus = 'sending'\n this.updateHeader()\n this.requestRender()\n\n try {\n // Get all docs in workspace for retrieval context\n const docs = await documents.listDocuments(this.workspaceContext.arbi)\n const docIds = docs.map((d) => d.external_id as string)\n\n // Load chat session for conversation threading\n const session = this.store.getChatSession()\n const previousResponseId = this.state.conversationMessageId ?? session.lastMessageExtId\n\n // Query the assistant\n const response = await assistant.queryAssistant({\n baseUrl: this.workspaceContext.config.baseUrl,\n accessToken: this.workspaceContext.accessToken,\n workspaceId: this.workspaceContext.workspaceId,\n question,\n docIds,\n previousResponseId,\n })\n\n // Stream the response into the chat log\n const result = await streamResponse(this, response)\n\n // Citation hotkey hint — after each response that has citations,\n // remind the user they can jump straight to a passage with\n // ``Alt+N`` instead of typing ``/cite N``. We compute the count\n // off ``tui.lastMetadata`` which ``streamResponse`` has already\n // populated. Capped at 9 because that's all Alt+1..9 covers; if\n // there are more, the user falls back to ``/cite N``.\n if (this.lastMetadata) {\n const n = countCitations(this.lastMetadata)\n if (n > 0) {\n const cap = Math.min(n, 9)\n const label =\n n <= 9\n ? `${n} citation${n === 1 ? '' : 's'} available`\n : `${n} citations — Alt+1..9 jumps to the first 9; /cite N for the rest`\n this.chatLog.addSystem(`${label} — press Alt+1..${cap} to view`, 'info')\n }\n }\n\n // Save conversation state for threading and history restoration\n if (result.assistantMessageExtId) {\n this.state.conversationMessageId = result.assistantMessageExtId\n const sessionUpdate: Record<string, string> = {\n lastMessageExtId: result.assistantMessageExtId,\n }\n // Extract conversation ID from user_message or metadata\n const conversationExtId =\n (result.userMessage?.conversation_ext_id as string) ??\n (result.metadata?.conversation_ext_id as string)\n if (conversationExtId) {\n sessionUpdate.conversationExtId = conversationExtId\n }\n this.store.updateChatSession(sessionUpdate)\n }\n } catch (err) {\n this.state.activityStatus = 'error'\n this.chatLog.addSystem(`Error: ${getErrorMessage(err)}`, 'error')\n }\n\n this.state.activityStatus = 'idle'\n this.updateHeader()\n this.requestRender()\n }\n\n // ── UI Updates ─────────────────────────────────────────────────────────\n\n /** Update the header bar — public so dm-handler can call it. */\n updateHeader(): void {\n const statusText =\n this.state.activityStatus === 'idle'\n ? colors.success('ready')\n : this.state.activityStatus === 'streaming'\n ? colors.warning('streaming...')\n : this.state.activityStatus === 'sending'\n ? colors.warning('sending...')\n : colors.error('error')\n\n if (this.dmChannel) {\n this.header.setText(formatHeader(`DM: ${this.dmChannel.user.email}`, statusText))\n } else {\n this.header.setText(formatHeader(this.state.workspaceName, statusText))\n }\n }\n\n // ── Citation overlay ───────────────────────────────────────────────────\n\n /** Show a component as a centered overlay (used by /cite). */\n showCitationOverlay(component: Component): void {\n this.dismissCitationOverlay()\n\n this.citationOverlay = this.tui.showOverlay(component, {\n anchor: 'center',\n width: '80%',\n maxHeight: '80%',\n margin: 2,\n })\n\n // Listen for Escape to dismiss (consume the keypress so editor doesn't see it)\n this.overlayInputListener = this.tui.addInputListener((data: string) => {\n if (matchesKey(data, Key.escape)) {\n this.dismissCitationOverlay()\n return { consume: true }\n }\n return undefined\n })\n\n this.tui.requestRender()\n }\n\n /** Dismiss the active citation overlay. */\n dismissCitationOverlay(): void {\n if (this.citationOverlay) {\n this.citationOverlay.hide()\n this.citationOverlay = null\n }\n if (this.overlayInputListener) {\n this.overlayInputListener()\n this.overlayInputListener = null\n }\n this.tui.requestRender()\n }\n\n // ── DM channel accessors (used by dm-handler) ────────────────────────────\n\n /** Current DM channel (null = AI chat mode). */\n get currentDmChannel(): DmChannel | null {\n return this.dmChannel\n }\n\n set currentDmChannel(ch: DmChannel | null) {\n this.dmChannel = ch\n }\n\n /** Encryption keypair for E2E DM encryption. */\n get encryptionKeys(): KeyPair | null {\n return this.encryptionKeyPair\n }\n}\n","/**\n * ARBI TUI — entry point\n *\n * Handles CLI argument parsing, authentication, and TUI launch.\n * Uses @arbidocs/sdk for auth and config, pi-tui for rendering.\n *\n * If not authenticated, offers interactive login/register before launching.\n *\n * Usage:\n * arbi-tui # Launch with default workspace\n * arbi-tui -w <workspace-id> # Launch with specific workspace\n */\n\n// Suppress SDK middleware logging\nconsole.debug = () => {}\nconst _origInfo = console.info\nconsole.info = (...args: unknown[]) => {\n if (typeof args[0] === 'string' && args[0].startsWith('[API]')) return\n _origInfo(...args)\n}\n\nimport { Command } from 'commander'\nimport {\n FileConfigStore,\n getErrorMessage,\n resolveWorkspace,\n workspaces,\n conversations,\n} from '@arbidocs/sdk'\nimport { ArbiTui } from './tui.js'\nimport { ensureAuthenticated } from './auth.js'\n\nconst program = new Command()\n\nprogram\n .name('arbi-tui')\n .description('Interactive terminal UI for ARBI — chat with the RAG assistant')\n .version('0.1.0')\n .option('-w, --workspace <id>', 'Workspace ID to use')\n .action(async (opts: { workspace?: string }) => {\n const store = new FileConfigStore()\n\n // Ensure config exists\n try {\n store.requireConfig()\n } catch {\n console.error('Not configured. Run `arbi config set-url <url>` first.')\n process.exit(1)\n }\n\n // Authenticate — offers login/register if not already authenticated\n const { authContext, selectedWorkspaceId, selectedWorkspaceName } =\n await ensureAuthenticated(store)\n\n // Resolve workspace\n const workspaceId = opts.workspace || selectedWorkspaceId\n\n // Create and start TUI\n const tui = new ArbiTui(store)\n tui.setAuthContext(authContext)\n\n if (workspaceId) {\n try {\n const wsCtx = await resolveWorkspace(store, workspaceId)\n tui.setWorkspaceContext(wsCtx)\n\n // Get workspace name\n if (selectedWorkspaceName && workspaceId === selectedWorkspaceId) {\n tui.state.workspaceName = selectedWorkspaceName\n } else {\n const wsList = await workspaces.listWorkspaces(authContext.arbi)\n const ws = wsList.find((w) => w.external_id === workspaceId)\n if (ws) {\n tui.state.workspaceName = ws.name\n }\n }\n } catch (err) {\n tui.chatLog.addSystem(`Failed to load workspace: ${getErrorMessage(err)}`, 'warning')\n tui.chatLog.addSystem('Use /workspaces to list and /workspace <id> to select.')\n }\n } else {\n tui.chatLog.addSystem(\n 'No workspace selected. Use /workspaces to list and /workspace <id> to select.'\n )\n }\n\n // Load chat session for conversation continuity\n const session = store.getChatSession()\n if (session.lastMessageExtId) {\n tui.state.conversationMessageId = session.lastMessageExtId\n }\n\n // Restore chat history from previous session\n if (session.conversationExtId && session.lastMessageExtId && tui.authContext) {\n try {\n const threads = await conversations.getConversationThreads(\n tui.authContext.arbi,\n session.conversationExtId\n )\n const threadList = (threads as { threads?: unknown[] }).threads ?? []\n const thread = threadList.find(\n (t) =>\n (t as { leaf_message_ext_id?: string }).leaf_message_ext_id === session.lastMessageExtId\n ) as { history?: { role: string; content: string }[] } | undefined\n\n if (thread?.history && thread.history.length > 0) {\n for (const msg of thread.history) {\n if (msg.role === 'user') {\n tui.chatLog.addUser(msg.content)\n } else if (msg.role === 'assistant') {\n tui.chatLog.addAssistant(msg.content)\n }\n }\n tui.chatLog.addSystem('--- restored from previous session ---')\n }\n } catch {\n // History restoration is best-effort — continue normally\n }\n }\n\n tui.chatLog.addSystem(\n 'Type a question to chat with the ARBI assistant. Use /help for commands.'\n )\n tui.start()\n })\n\nprogram.parse()\n"]}
|