@byfriends/vis-server 0.3.5 → 0.4.0
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.d.mts +1 -1
- package/dist/index.mjs +21 -20
- package/dist/index.mjs.map +10 -0
- package/dist/public/assets/{index-CE9cqWg9.js → index-BicyXOcO.js} +1 -1
- package/dist/public/index.html +1 -1
- package/dist/server-enpsx6np.mjs +1010 -0
- package/dist/server-enpsx6np.mjs.map +25 -0
- package/dist/server.d.mts +5 -8
- package/dist/server.mjs +13 -2
- package/dist/server.mjs.map +9 -0
- package/package.json +10 -10
- package/dist/server-CqbNDUBH.mjs +0 -1044
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../src/app.ts", "../src/routes/context.ts", "../src/config.ts", "../src/lib/context-projector.ts", "../src/lib/session-store.ts", "../src/lib/wire-reader.ts", "../../../../packages/agent-core/src/agent/records/migration/v1.1.ts", "../../../../packages/agent-core/src/agent/records/migration/index.ts", "../src/routes/session-detail.ts", "../src/routes/sessions.ts", "../src/lib/reveal.ts", "../src/routes/subagents.ts", "../src/lib/agent-tree.ts", "../src/routes/wire.ts", "../src/startup-banner.ts", "../src/server.ts"],
|
|
4
|
+
"sourcesContent": [
|
|
5
|
+
"import { timingSafeEqual } from 'node:crypto';\nimport { readFile, stat } from 'node:fs/promises';\nimport { join, resolve } from 'node:path';\n\nimport { Hono } from 'hono';\n\nimport { contextRoute } from './routes/context';\nimport { sessionDetailRoute } from './routes/session-detail';\nimport { sessionsRoute } from './routes/sessions';\nimport { subagentsRoute } from './routes/subagents';\nimport { wireRoute } from './routes/wire';\n\n/** Resolve the SPA bundle directory next to the compiled server.mjs, if it\n * exists. Returns `null` in dev mode where the web bundle lives elsewhere. */\nasync function resolvePublicDir(): Promise<string | null> {\n try {\n const here = import.meta.dirname;\n const candidate = resolve(here, 'public');\n const s = await stat(candidate);\n if (s.isDirectory()) return candidate;\n } catch {\n // not present\n }\n return null;\n}\n\nconst STATIC_EXT_MIME: Record<string, string> = {\n '.html': 'text/html; charset=utf-8',\n '.js': 'application/javascript; charset=utf-8',\n '.mjs': 'application/javascript; charset=utf-8',\n '.css': 'text/css; charset=utf-8',\n '.json': 'application/json; charset=utf-8',\n '.svg': 'image/svg+xml',\n '.png': 'image/png',\n '.jpg': 'image/jpeg',\n '.jpeg': 'image/jpeg',\n '.gif': 'image/gif',\n '.ico': 'image/x-icon',\n '.woff': 'font/woff',\n '.woff2': 'font/woff2',\n '.ttf': 'font/ttf',\n '.map': 'application/json; charset=utf-8',\n};\n\nfunction mimeFor(path: string): string {\n const i = path.lastIndexOf('.');\n if (i < 0) return 'application/octet-stream';\n const ext = path.slice(i).toLowerCase();\n return STATIC_EXT_MIME[ext] ?? 'application/octet-stream';\n}\n\nexport interface CreateAppOptions {\n readonly authToken?: string;\n /**\n * Directory holding the built SPA assets. When provided, this directory is\n * used directly; otherwise the `public/` directory next to the compiled\n * server bundle is auto-detected (returns `null` in dev mode where the web\n * bundle lives elsewhere, e.g. behind the Vite dev server).\n */\n readonly publicDir?: string;\n}\n\nfunction bearerToken(value: string | undefined): string | null {\n if (value === undefined) return null;\n const match = /^Bearer\\s+(.+)$/i.exec(value);\n return match?.[1]?.trim() ?? null;\n}\n\nfunction tokenMatches(actual: string, expected: string): boolean {\n const actualBytes = Buffer.from(actual);\n const expectedBytes = Buffer.from(expected);\n return actualBytes.length === expectedBytes.length && timingSafeEqual(actualBytes, expectedBytes);\n}\n\n/** Build a Hono app mounting /api/* routes, plus SPA static fallback. */\nexport async function createApp(options: CreateAppOptions = {}): Promise<Hono> {\n const app = new Hono();\n\n // /api/* handlers.\n const api = new Hono();\n const authToken = options.authToken;\n if (authToken !== undefined && authToken.length > 0) {\n api.use('*', async (c, next) => {\n const token = bearerToken(c.req.header('authorization'));\n if (token !== null && tokenMatches(token, authToken)) {\n await next();\n return;\n }\n c.header('www-authenticate', 'Bearer realm=\"byf-vis\"');\n return c.json({ error: 'unauthorized', code: 'UNAUTHORIZED' }, 401);\n });\n }\n api.route('/sessions', sessionsRoute());\n api.route('/sessions', sessionDetailRoute());\n api.route('/sessions', wireRoute());\n api.route('/sessions', subagentsRoute());\n // Mount contextRoute last because it currently uses a catch-all stub\n // (Phase C scope) that would otherwise shadow more specific routes\n // registered below it.\n api.route('/sessions', contextRoute());\n\n app.route('/api', api);\n\n // Static + SPA fallback (production only).\n const publicDir = options.publicDir ?? (await resolvePublicDir());\n if (publicDir !== null) {\n app.get('*', async (c) => {\n const url = new URL(c.req.url);\n let pathname = decodeURIComponent(url.pathname);\n if (pathname.startsWith('/api')) {\n // Should have been routed above; 404 here.\n return c.json({ error: `api route not found: ${pathname}`, code: 'NOT_FOUND' }, 404);\n }\n if (pathname === '/' || pathname === '') pathname = '/index.html';\n const resolved = resolve(publicDir, `.${pathname}`);\n if (!resolved.startsWith(publicDir)) {\n return c.text('forbidden', 403);\n }\n try {\n const s = await stat(resolved);\n if (s.isFile()) {\n const buf = await readFile(resolved);\n const body = new Uint8Array(buf.buffer, buf.byteOffset, buf.byteLength);\n return new Response(body, {\n headers: { 'content-type': mimeFor(resolved) },\n });\n }\n } catch {\n // fall through to SPA fallback\n }\n // SPA fallback — index.html for any unknown GET so client-side\n // React Router can resolve the route.\n try {\n const indexHtml = await readFile(join(publicDir, 'index.html'));\n const body = new Uint8Array(indexHtml.buffer, indexHtml.byteOffset, indexHtml.byteLength);\n return new Response(body, {\n headers: { 'content-type': 'text/html; charset=utf-8' },\n });\n } catch {\n return c.text('not found', 404);\n }\n });\n }\n\n return app;\n}\n",
|
|
6
|
+
"import { join } from 'node:path';\n\nimport { Hono } from 'hono';\n\nimport { resolveByfHome } from '../config';\nimport { projectContext } from '../lib/context-projector';\nimport { isSafeAgentId, readSessionDetail } from '../lib/session-store';\nimport { readAgentWire } from '../lib/wire-reader';\n\nexport function contextRoute(): Hono {\n const r = new Hono();\n r.get('/:id/context', async (c) => {\n const id = c.req.param('id');\n const agentId = c.req.query('agent') ?? 'main';\n if (!isSafeAgentId(agentId)) {\n return c.json({ error: 'invalid agent id', code: 'BAD_REQUEST' }, 400);\n }\n const detail = await readSessionDetail(resolveByfHome(), id);\n if (!detail) {\n return c.json({ error: 'session not found', code: 'NOT_FOUND' }, 404);\n }\n const agent = detail.agents.find((a) => a.agentId === agentId);\n if (!agent || !agent.wireExists) {\n return c.json({ error: 'agent wire not found', code: 'NOT_FOUND' }, 404);\n }\n try {\n const wire = await readAgentWire(join(detail.sessionDir, 'agents', agentId, 'wire.jsonl'));\n const proj = projectContext(wire.records);\n return c.json({\n sessionId: id,\n agentId,\n messages: proj.messages,\n usage: proj.usage,\n config: proj.config,\n permission: proj.permission,\n });\n } catch (error) {\n const msg = (error as Error).message;\n if (msg.toLowerCase().includes('unsupported protocol')) {\n return c.json({ error: msg, code: 'UNSUPPORTED_PROTOCOL' }, 400);\n }\n return c.json({ error: msg, code: 'READ_ERROR' }, 500);\n }\n });\n return r;\n}\n",
|
|
7
|
+
"import { homedir } from 'node:os';\nimport { join } from 'node:path';\n\n/** Resolve BYF_HOME (env > ~/.byf). */\nexport function resolveByfHome(): string {\n const envHome = process.env['BYF_HOME'];\n if (envHome !== undefined && envHome.length > 0) {\n return envHome;\n }\n return join(homedir(), '.byf');\n}\n\n/** HTTP port for the vis API server. */\nexport function resolvePort(): number {\n const raw = process.env['PORT'];\n if (raw !== undefined && raw.length > 0) {\n const n = Number.parseInt(raw, 10);\n if (Number.isFinite(n) && n > 0 && n < 65536) {\n return n;\n }\n }\n return 3001;\n}\n\n/** HTTP host for the vis API server. Defaults to loopback. */\nexport function resolveHost(): string {\n const raw = process.env['VIS_HOST'] ?? process.env['HOST'];\n const host = raw?.trim();\n return host !== undefined && host.length > 0 ? host : '127.0.0.1';\n}\n\nexport function isLoopbackHost(host: string): boolean {\n const normalized = host.trim().toLowerCase().replaceAll('[', '').replaceAll(']', '');\n return (\n normalized === 'localhost' ||\n normalized === '::1' ||\n normalized === '0:0:0:0:0:0:0:1' ||\n normalized.startsWith('127.')\n );\n}\n\nexport function resolveVisAuthToken(host: string = resolveHost()): string | undefined {\n const raw = process.env['VIS_AUTH_TOKEN'];\n const token = raw?.trim();\n if (token !== undefined && token.length > 0) return token;\n if (!isLoopbackHost(host)) {\n throw new Error(\n `VIS_AUTH_TOKEN is required when binding vis-server outside loopback (host=${host})`,\n );\n }\n return undefined;\n}\n",
|
|
8
|
+
"// Context-projection DTOs — canonical definitions live in shared/types.ts\nimport type {\n ProjectedMessage,\n UsageTotals,\n ConfigSnapshot,\n ContextProjection,\n} from '../../../shared/types';\nimport type {\n ContentPart,\n ContextMessage,\n TokenUsage,\n ToolCall,\n WireEntry,\n} from './agent-record-types';\n\nexport type { ProjectedMessage, UsageTotals, ConfigSnapshot, ContextProjection };\n\nconst ZERO: TokenUsage = { inputOther: 0, output: 0, inputCacheRead: 0, inputCacheCreation: 0 };\n\n/** Build a conversation timeline + derived state from a sequence of\n * wire entries. The reconstruction mirrors agent-core's own\n * `appendLoopEvent` logic, so:\n *\n * - `context.append_message` records become messages as-is (the\n * user / tool messages and any explicit assistant injections).\n * - `step.begin` pushes a fresh assistant message; later\n * `content.part` and `tool.call` events on the same step **mutate\n * that same message** to grow its content / toolCalls. `step.end`\n * just closes the step.\n * - `tool.result` events emit an independent `role: 'tool'` message,\n * matching how agent-core surfaces tool exchanges to the model.\n *\n * Without this loop-event reconstruction the timeline would only\n * show user prompts — agent-core does not emit a synthetic\n * `context.append_message` for assistant turns. */\nexport function projectContext(entries: ReadonlyArray<WireEntry>): ContextProjection {\n let messages: ProjectedMessage[] = [];\n const usage: UsageTotals = {\n byScope: { session: { ...ZERO }, turn: { ...ZERO } },\n byModel: {},\n };\n const config: ConfigSnapshot = {};\n let permissionMode: 'manual' | 'yolo' | 'auto' | null = null;\n // Maps step.uuid → the assistant ProjectedMessage that step is filling in.\n // Cleared on context.clear / context.apply_compaction.\n let openSteps = new Map<string, ProjectedMessage>();\n\n for (const entry of entries) {\n const rec = entry.data;\n switch (rec.type) {\n case 'context.append_message':\n messages.push({\n lineNo: entry.lineNo,\n time: rec.time,\n source: 'append_message',\n message: rec.message,\n toolStepUuids: [],\n });\n break;\n case 'context.append_loop_event': {\n const ev = rec.event;\n if (ev.type === 'step.begin') {\n const message: ContextMessage = {\n role: 'assistant',\n content: [],\n toolCalls: [],\n };\n const projected: ProjectedMessage = {\n lineNo: entry.lineNo,\n time: rec.time,\n source: 'append_message',\n message,\n toolStepUuids: [ev.uuid],\n };\n messages.push(projected);\n openSteps.set(ev.uuid, projected);\n } else if (ev.type === 'content.part') {\n const projected = openSteps.get(ev.stepUuid);\n if (projected !== undefined) {\n (projected.message.content as ContentPart[]).push(ev.part);\n }\n } else if (ev.type === 'tool.call') {\n const projected = openSteps.get(ev.stepUuid);\n if (projected !== undefined) {\n const args =\n typeof ev.args === 'string'\n ? ev.args\n : ev.args === undefined\n ? null\n : JSON.stringify(ev.args);\n (projected.message.toolCalls as ToolCall[]).push({\n type: 'function',\n id: ev.toolCallId,\n name: ev.name,\n arguments: args,\n });\n }\n } else if (ev.type === 'step.end') {\n openSteps.delete(ev.uuid);\n } else if (ev.type === 'tool.result') {\n const output = ev.result.output;\n const content: ContentPart[] =\n typeof output === 'string'\n ? [{ type: 'text', text: output }]\n : (output as ContentPart[]);\n const toolMsg: ContextMessage = {\n role: 'tool',\n content,\n toolCalls: [],\n toolCallId: ev.toolCallId,\n ...(ev.result.isError === true ? { isError: true } : {}),\n };\n messages.push({\n lineNo: entry.lineNo,\n time: rec.time,\n source: 'append_message',\n message: toolMsg,\n toolStepUuids: [],\n });\n }\n break;\n }\n case 'context.clear':\n messages = [];\n openSteps = new Map();\n break;\n case 'context.apply_compaction':\n openSteps = new Map();\n // Mirror agent-core's actual `applyCompaction` behaviour: the\n // summary is inserted as an *assistant* message tagged with\n // `origin.kind = 'compaction_summary'` (see\n // `packages/agent-core/src/agent/context/index.ts`). Using\n // 'system' here would skew role counts and any downstream tool\n // that diffs the projected timeline against agent-core history.\n messages = [\n {\n lineNo: entry.lineNo,\n time: rec.time,\n source: 'compaction_summary',\n message: {\n role: 'assistant',\n content: [{ type: 'text', text: rec.summary }],\n toolCalls: [],\n origin: { kind: 'compaction_summary' },\n } as ContextMessage,\n toolStepUuids: [],\n },\n ];\n break;\n case 'usage.record': {\n const scope: keyof UsageTotals['byScope'] = rec.usageScope === 'turn' ? 'turn' : 'session';\n addUsage(usage.byScope[scope], rec.usage);\n usage.byModel[rec.model] ??= { ...ZERO };\n addUsage(usage.byModel[rec.model]!, rec.usage);\n break;\n }\n case 'config.update': {\n const typeChecked = rec as {\n type: 'config.update';\n cwd?: string;\n modelAlias?: string;\n profileName?: string;\n thinkingLevel?: string;\n systemPrompt?: string;\n };\n if (typeChecked.cwd !== undefined) config.cwd = typeChecked.cwd;\n if (typeChecked.modelAlias !== undefined) config.modelAlias = typeChecked.modelAlias;\n if (typeChecked.profileName !== undefined) config.profileName = typeChecked.profileName;\n if (typeChecked.thinkingLevel !== undefined)\n config.thinkingLevel = typeChecked.thinkingLevel;\n if (typeChecked.systemPrompt !== undefined) config.systemPrompt = typeChecked.systemPrompt;\n break;\n }\n case 'permission.set_mode':\n permissionMode = rec.mode;\n break;\n default:\n break;\n }\n }\n\n return {\n messages,\n usage,\n config,\n permission: { mode: permissionMode },\n };\n}\n\nfunction addUsage(into: TokenUsage, src: TokenUsage): void {\n (into as any).inputOther += src.inputOther;\n (into as any).output += src.output;\n (into as any).inputCacheRead += src.inputCacheRead;\n (into as any).inputCacheCreation += src.inputCacheCreation;\n}\n",
|
|
9
|
+
"import { createReadStream } from 'node:fs';\nimport { readdir, readFile, stat } from 'node:fs/promises';\nimport { join, resolve, sep } from 'node:path';\nimport { createInterface } from 'node:readline';\n\nimport type { SessionSummary, SessionDetail, AgentInfo, SessionHealth } from './agent-record-types';\n\nconst SESSION_ID_RE = /^session_[A-Za-z0-9._-]+$/;\nconst AGENT_ID_RE = /^[A-Za-z0-9._-]+$/;\n\n/** Reject agent ids that could escape the session directory via path\n * joins. Defence-in-depth: the on-disk source of these ids is\n * agent-core (which only generates main / agent-N), but a corrupted\n * or hand-edited `state.json.agents` key could otherwise turn vis\n * into a local-file-read primitive when exposed beyond loopback. */\nexport function isSafeAgentId(id: string): boolean {\n return AGENT_ID_RE.test(id) && id !== '.' && id !== '..';\n}\n\ninterface StateJson {\n createdAt?: string;\n updatedAt?: string;\n title?: string;\n isCustomTitle?: boolean;\n lastPrompt?: string;\n agents?: Record<\n string,\n { homedir: string; type: 'main' | 'sub' | 'independent'; parentAgentId: string | null }\n >;\n custom?: Record<string, unknown>;\n}\n\nexport async function listSessions(home: string): Promise<SessionSummary[]> {\n const sessionsDir = join(home, 'sessions');\n const buckets = await readdir(sessionsDir, { withFileTypes: true }).catch(() => []);\n const index = await readSessionIndex(home);\n const out: SessionSummary[] = [];\n for (const bucket of buckets) {\n if (!bucket.isDirectory()) continue;\n const bucketDir = join(sessionsDir, bucket.name);\n const sessionDirs = await readdir(bucketDir, { withFileTypes: true }).catch(() => []);\n for (const entry of sessionDirs) {\n if (!entry.isDirectory() || !SESSION_ID_RE.test(entry.name)) continue;\n const sessionDir = join(bucketDir, entry.name);\n const workDir = index.get(entry.name)?.workDir ?? '';\n const summary = await tryReadSummary(sessionDir, entry.name, workDir);\n if (summary !== null) out.push(summary);\n }\n }\n out.sort((a, b) => b.updatedAt - a.updatedAt);\n return out;\n}\n\nexport async function readSessionDetail(\n home: string,\n sessionId: string,\n): Promise<SessionDetail | null> {\n const sessionDir = await findSessionDir(home, sessionId);\n if (sessionDir === null) return null;\n const index = await readSessionIndex(home);\n const workDir = index.get(sessionId)?.workDir ?? '';\n const state = await readState(sessionDir);\n // When state.json is unreadable we still return a SessionDetail so the\n // UI can render the broken-state diagnostic. Agent inventory cannot be\n // derived from state, but the on-disk `agents/<id>/wire.jsonl` files\n // are independent of state — probe for them directly so users can\n // still inspect the wire/context of a session whose state is corrupt.\n if (state === null) {\n const agents = await discoverAgentsFromDisk(sessionDir);\n return { sessionId, sessionDir, workDir, state: null, agents };\n }\n if (state.custom?.['imported_from_byf_cli'] === true) return null;\n const agents = await inventoryAgents(sessionDir, state);\n return { sessionId, sessionDir, workDir, state, agents };\n}\n\n/** Fallback inventory used when `state.json` is unreadable: walk\n * `<sessionDir>/agents/*` directly and synthesize minimal AgentInfo\n * records for the directories that contain a `wire.jsonl`. Parent\n * links and `type` are unknown without state, so we mark every agent\n * as `independent` with a null parent — the routes only need\n * `agentId` + `wireExists` to serve wire/context. */\nasync function discoverAgentsFromDisk(sessionDir: string): Promise<AgentInfo[]> {\n const agentsDir = join(sessionDir, 'agents');\n let entries: import('node:fs').Dirent[];\n try {\n entries = await readdir(agentsDir, { withFileTypes: true });\n } catch {\n return [];\n }\n const out: AgentInfo[] = [];\n for (const entry of entries) {\n if (!entry.isDirectory()) continue;\n const id = entry.name;\n if (!isSafeAgentId(id)) continue;\n const wirePath = join(agentsDir, id, 'wire.jsonl');\n const exists = await pathExists(wirePath);\n let readable = exists;\n let info: { count: number; protocolVersion: string | null } = {\n count: 0,\n protocolVersion: null,\n };\n if (exists) {\n try {\n info = await scanWire(wirePath);\n } catch {\n readable = false;\n }\n }\n out.push({\n agentId: id,\n type: id === 'main' ? 'main' : 'independent',\n parentAgentId: null,\n homedir: join(agentsDir, id),\n wireExists: readable,\n wireRecordCount: info.count,\n wireProtocolVersion: info.protocolVersion,\n });\n }\n return out.toSorted((a, b) => {\n if (a.agentId === 'main') return -1;\n if (b.agentId === 'main') return 1;\n return a.agentId.localeCompare(b.agentId);\n });\n}\n\nasync function tryReadSummary(\n sessionDir: string,\n sessionId: string,\n workDir: string,\n): Promise<SessionSummary | null> {\n const state = await readState(sessionDir);\n if (state === null) {\n return brokenStateSummary(sessionDir, sessionId, workDir);\n }\n if (state.custom?.['imported_from_byf_cli'] === true) return null;\n\n const mainWirePath = join(sessionDir, 'agents', 'main', 'wire.jsonl');\n const mainExists = await pathExists(mainWirePath);\n let mainCount = 0;\n let protocolVersion: string | null = null;\n let health: SessionHealth = 'ok';\n if (!mainExists) {\n health = 'missing_main_wire';\n } else {\n try {\n const info = await scanWire(mainWirePath);\n mainCount = info.count;\n protocolVersion = info.protocolVersion;\n // Note: the protocol version is not used to gate health any more —\n // the wire-reader best-efforts unknown versions with a warning.\n } catch {\n // A single unreadable wire file must not fail the whole list.\n health = 'broken_main_wire';\n }\n }\n\n return {\n sessionId,\n sessionDir,\n workDir,\n title: state.title ?? null,\n lastPrompt: state.lastPrompt ?? null,\n isCustomTitle: state.isCustomTitle ?? false,\n createdAt: parseTs(state.createdAt),\n updatedAt: parseTs(state.updatedAt),\n agentCount: Object.keys(state.agents ?? {}).length,\n mainAgentExists: mainExists,\n mainWireRecordCount: mainCount,\n wireProtocolVersion: protocolVersion,\n health,\n };\n}\n\nfunction brokenStateSummary(\n sessionDir: string,\n sessionId: string,\n workDir: string,\n): SessionSummary {\n return {\n sessionId,\n sessionDir,\n workDir,\n title: null,\n lastPrompt: null,\n isCustomTitle: false,\n createdAt: 0,\n updatedAt: 0,\n agentCount: 0,\n mainAgentExists: false,\n mainWireRecordCount: 0,\n wireProtocolVersion: null,\n health: 'broken_state',\n };\n}\n\ninterface SessionIndexEntry {\n sessionDir: string;\n workDir: string;\n}\n\nasync function readSessionIndex(home: string): Promise<Map<string, SessionIndexEntry>> {\n const out = new Map<string, SessionIndexEntry>();\n let raw: string;\n try {\n raw = await readFile(join(home, 'session_index.jsonl'), 'utf8');\n } catch {\n return out;\n }\n for (const line of raw.split(/\\r?\\n/)) {\n if (!line.trim()) continue;\n try {\n const entry = JSON.parse(line) as {\n sessionId?: string;\n sessionDir?: string;\n workDir?: string;\n };\n if (typeof entry.sessionId === 'string' && typeof entry.sessionDir === 'string') {\n out.set(entry.sessionId, {\n sessionDir: entry.sessionDir,\n workDir: typeof entry.workDir === 'string' ? entry.workDir : '',\n });\n }\n } catch {\n /* skip malformed */\n }\n }\n return out;\n}\n\nasync function inventoryAgents(sessionDir: string, state: StateJson): Promise<AgentInfo[]> {\n const result: AgentInfo[] = [];\n for (const [id, meta] of Object.entries(state.agents ?? {})) {\n if (!isSafeAgentId(id)) continue;\n const wirePath = join(sessionDir, 'agents', id, 'wire.jsonl');\n const exists = await pathExists(wirePath);\n let readable = exists;\n let info: { count: number; protocolVersion: string | null } = {\n count: 0,\n protocolVersion: null,\n };\n if (exists) {\n try {\n info = await scanWire(wirePath);\n } catch {\n // The file exists but is unreadable / malformed. Report it as\n // unavailable so wire/context routes return 404 (\"wire missing\")\n // instead of 500 (\"READ_ERROR\") and the UI shows the \"no wire\"\n // badge consistently with the missing-file path.\n readable = false;\n }\n }\n result.push({\n agentId: id,\n type: meta.type,\n parentAgentId: meta.parentAgentId,\n homedir: meta.homedir,\n wireExists: readable,\n wireRecordCount: info.count,\n wireProtocolVersion: info.protocolVersion,\n });\n }\n return result.toSorted((a, b) => {\n if (a.agentId === 'main') return -1;\n if (b.agentId === 'main') return 1;\n return a.agentId.localeCompare(b.agentId);\n });\n}\n\nasync function readState(sessionDir: string): Promise<StateJson | null> {\n try {\n return JSON.parse(await readFile(join(sessionDir, 'state.json'), 'utf8')) as StateJson;\n } catch {\n return null;\n }\n}\n\nasync function findSessionDir(home: string, sessionId: string): Promise<string | null> {\n if (!SESSION_ID_RE.test(sessionId)) return null;\n const sessionsRoot = resolve(join(home, 'sessions'));\n const sessionsRootPrefix = sessionsRoot + sep;\n // Try index first — but only trust entries that point *under*\n // `<home>/sessions/` AND whose basename matches the requested id.\n // This blocks stale/poisoned index lines from redirecting reads to\n // unrelated directories.\n try {\n const indexLines = (await readFile(join(home, 'session_index.jsonl'), 'utf8')).split(/\\r?\\n/);\n for (const line of indexLines) {\n if (!line.trim()) continue;\n const entry = JSON.parse(line) as { sessionId?: string; sessionDir?: string };\n if (entry.sessionId !== sessionId || typeof entry.sessionDir !== 'string') continue;\n const candidate = resolve(entry.sessionDir);\n if (!candidate.startsWith(sessionsRootPrefix)) continue;\n if (candidate.split(sep).pop() !== sessionId) continue;\n if (await pathExists(candidate)) return candidate;\n }\n } catch {\n /* no index */\n }\n // Fall back to scanning buckets\n const buckets = await readdir(sessionsRoot, { withFileTypes: true }).catch(() => []);\n for (const bucket of buckets) {\n if (!bucket.isDirectory()) continue;\n const candidate = join(sessionsRoot, bucket.name, sessionId);\n if (await pathExists(candidate)) return candidate;\n }\n return null;\n}\n\nasync function scanWire(path: string): Promise<{ count: number; protocolVersion: string }> {\n const stream = createReadStream(path, { encoding: 'utf8' });\n const rl = createInterface({ input: stream, crlfDelay: Infinity });\n let count = 0;\n let protocolVersion: string | null = null;\n for await (const line of rl) {\n if (line.length === 0) continue;\n if (protocolVersion === null) {\n // Strict: the first non-empty line MUST be a well-formed\n // `metadata` record. Otherwise the list-view health would say\n // \"ok\" while the wire-reader rejects the file on open.\n let parsed: { type?: unknown; protocol_version?: unknown };\n try {\n parsed = JSON.parse(line) as typeof parsed;\n } catch {\n throw new Error(`wire metadata is not valid JSON at line 1`);\n }\n if (parsed.type !== 'metadata' || typeof parsed.protocol_version !== 'string') {\n throw new Error(`wire is missing a metadata header on line 1`);\n }\n protocolVersion = parsed.protocol_version;\n }\n count += 1;\n }\n if (protocolVersion === null) {\n throw new Error('wire file is empty');\n }\n return { count, protocolVersion };\n}\n\nfunction parseTs(input: string | undefined): number {\n if (!input) return 0;\n const n = Date.parse(input);\n return Number.isFinite(n) ? n : 0;\n}\n\nasync function pathExists(p: string): Promise<boolean> {\n try {\n await stat(p);\n return true;\n } catch {\n return false;\n }\n}\n",
|
|
10
|
+
"import { createReadStream } from 'node:fs';\nimport { createInterface } from 'node:readline';\n\nimport {\n isNewerWireVersion,\n migrateWireRecord,\n resolveWireMigrations,\n type WireMigration,\n} from '@byfriends/agent-core/agent/records/migration';\n\nimport type { AgentRecord, WireEntry } from './agent-record-types';\n\nexport interface WireReadResult {\n metadata: { protocolVersion: string; createdAt: number };\n records: ReadonlyArray<WireEntry>;\n warnings: string[];\n}\n\n/** Best-effort fallback when a wire file declares a protocol_version that\n * `agent-core` does not know about (e.g. the historic \"2.2\" alias that\n * pre-dates the 1.x renumber). We try to apply the chain *starting* from\n * the oldest known version (1.0) and warn the caller. If even that fails\n * we just pass records through unchanged. */\nfunction bestEffortMigrations(): readonly WireMigration[] {\n try {\n return resolveWireMigrations('1.0');\n } catch {\n return [];\n }\n}\n\n/** Read a single agent's `wire.jsonl`.\n *\n * Each record is returned as a `WireEntry` containing both the\n * on-disk parsed form (`raw`) and the migrated current-protocol form\n * (`data`). For wires that declare a protocol version `agent-core`\n * does not recognise (historic 2.x labels, or truly future versions),\n * the reader falls back to a best-effort path: records are run\n * through the 1.0-onwards migration chain and a warning is added to\n * `warnings[]` so the UI can surface the caveat. */\nexport async function readAgentWire(path: string): Promise<WireReadResult> {\n const stream = createReadStream(path, { encoding: 'utf8' });\n const rl = createInterface({ input: stream, crlfDelay: Infinity });\n let lineNo = 0;\n let metadata: WireReadResult['metadata'] | null = null;\n let migrations: readonly WireMigration[] = [];\n const records: WireEntry[] = [];\n const warnings: string[] = [];\n\n for await (const line of rl) {\n lineNo += 1;\n if (line.length === 0) continue;\n let parsed: unknown;\n try {\n parsed = JSON.parse(line);\n } catch (error) {\n warnings.push(`line ${lineNo}: invalid JSON (${(error as Error).message})`);\n continue;\n }\n if (!isObject(parsed) || typeof parsed['type'] !== 'string') {\n warnings.push(`line ${lineNo}: missing 'type' field`);\n continue;\n }\n if (metadata === null) {\n if (parsed['type'] !== 'metadata') {\n throw new Error(`Wire file missing metadata header at line ${lineNo}`);\n }\n const pv = parsed['protocol_version'];\n const ca = parsed['created_at'];\n if (typeof pv !== 'string' || typeof ca !== 'number') {\n throw new TypeError(`Wire metadata malformed at line ${lineNo}`);\n }\n // Newer-than-supported versions return [] from resolveWireMigrations\n // without throwing (agent-core replays them unmigrated). Vis still wants\n // a best-effort 1.0→current chain + warning so historic labels like \"2.2\"\n // surface in the UI.\n if (isNewerWireVersion(pv)) {\n warnings.push(\n `unrecognised protocol_version \"${pv}\" — parsing as best-effort (newer than supported)`,\n );\n migrations = bestEffortMigrations();\n } else {\n try {\n migrations = resolveWireMigrations(pv);\n } catch (error) {\n warnings.push(\n `unrecognised protocol_version \"${pv}\" — parsing as best-effort (${(error as Error).message})`,\n );\n migrations = bestEffortMigrations();\n }\n }\n metadata = { protocolVersion: pv, createdAt: ca };\n continue;\n }\n const raw = parsed;\n let migrated: Record<string, unknown>;\n try {\n migrated =\n migrations.length === 0\n ? raw\n : (migrateWireRecord(\n raw as Record<string, unknown> & { type: string },\n migrations,\n ) as Record<string, unknown>);\n } catch (error) {\n // A single record that won't migrate is not fatal — keep the raw\n // payload so the UI can still render whatever fields it understands.\n warnings.push(\n `line ${lineNo}: migration failed (${(error as Error).message}); using raw record`,\n );\n migrated = raw;\n }\n records.push({ lineNo, data: migrated as AgentRecord, raw });\n }\n if (metadata === null) {\n throw new Error('Wire file is empty (no metadata)');\n }\n return { metadata, records, warnings };\n}\n\nfunction isObject(v: unknown): v is Record<string, unknown> {\n return typeof v === 'object' && v !== null && !Array.isArray(v);\n}\n",
|
|
11
|
+
"import type { WireMigration, WireMigrationRecord } from './index';\n\n/**\n * Wire records before v1.1 used a nested `function` wrapper for each tool call:\n * { function: { name: 'xxx', arguments: 'yyy' } }\n * v1.1 flattens it to:\n * { name: 'xxx', arguments: 'yyy' }\n */\ninterface LegacyToolCall {\n type: 'function';\n id: string;\n function: {\n name?: string;\n arguments?: string | null;\n };\n}\n\nfunction isLegacyToolCall(v: unknown): v is LegacyToolCall {\n if (!isRecord(v)) return false;\n return v['type'] === 'function' && typeof v['id'] === 'string' && isRecord(v['function']);\n}\n\nfunction migrateToolCall(v: LegacyToolCall): unknown {\n const { function: fn, ...rest } = v;\n return {\n ...rest,\n name: fn.name,\n arguments: fn.arguments,\n };\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nexport const migrateV1_0ToV1_1: WireMigration = {\n sourceVersion: '1.0',\n targetVersion: '1.1',\n migrateRecord(record: WireMigrationRecord): WireMigrationRecord {\n if (record.type !== 'context.append_message') return record;\n\n const message = record['message'] as {\n readonly toolCalls: readonly unknown[];\n };\n\n let changed = false;\n const toolCalls = message.toolCalls.map((toolCall) => {\n if (!isLegacyToolCall(toolCall)) return toolCall;\n changed = true;\n return migrateToolCall(toolCall);\n });\n\n if (!changed) return record;\n\n return {\n ...record,\n message: {\n ...message,\n toolCalls,\n },\n };\n },\n};\n",
|
|
12
|
+
"import { migrateV1_0ToV1_1 } from './v1.1';\n\n// Wire protocol versions currently support only the `number.number` format.\nexport const AGENT_WIRE_PROTOCOL_VERSION = '1.1';\n\nexport interface WireMigrationRecord {\n readonly type: string;\n [key: string]: unknown;\n}\n\nexport interface WireMigration {\n readonly sourceVersion: string;\n readonly targetVersion: string;\n migrateRecord(record: WireMigrationRecord): WireMigrationRecord;\n}\n\nconst MIGRATIONS: readonly WireMigration[] = [migrateV1_0ToV1_1];\n\nexport function isNewerWireVersion(readVersion: string): boolean {\n return compareWireVersions(readVersion, AGENT_WIRE_PROTOCOL_VERSION) > 0;\n}\n\nexport function resolveWireMigrations(readVersion: string): readonly WireMigration[] {\n if (compareWireVersions(readVersion, AGENT_WIRE_PROTOCOL_VERSION) >= 0) {\n return [];\n }\n\n const migrations: WireMigration[] = [];\n let version = readVersion;\n while (compareWireVersions(version, AGENT_WIRE_PROTOCOL_VERSION) < 0) {\n const migration = findMigration(version);\n if (migration === undefined) {\n throw new Error(`Missing wire migration for version ${version}`);\n }\n migrations.push(migration);\n version = migration.targetVersion;\n }\n\n return migrations;\n}\n\nexport function migrateWireRecord(\n record: WireMigrationRecord,\n migrations: readonly WireMigration[],\n): WireMigrationRecord {\n return migrations.reduce((current, migration) => migration.migrateRecord(current), record);\n}\n\nexport function migrateWireRecords(\n records: readonly WireMigrationRecord[],\n readVersion: string | undefined,\n): WireMigrationRecord[] {\n const migrations = readVersion === undefined ? MIGRATIONS : resolveWireMigrations(readVersion);\n return records.map((record) => migrateWireRecord(record, migrations));\n}\n\nfunction findMigration(sourceVersion: string): WireMigration | undefined {\n for (const migration of MIGRATIONS) {\n if (migration.sourceVersion === sourceVersion) return migration;\n }\n}\n\nfunction compareWireVersions(a: string, b: string): number {\n const partsA = a.split('.');\n const partsB = b.split('.');\n const maxLength = Math.max(partsA.length, partsB.length);\n\n for (let i = 0; i < maxLength; i++) {\n const diff = Number(partsA[i] ?? '0') - Number(partsB[i] ?? '0');\n if (diff !== 0) return diff;\n }\n\n return 0;\n}\n",
|
|
13
|
+
"import { Hono } from 'hono';\n\nimport { resolveByfHome } from '../config';\nimport { readSessionDetail } from '../lib/session-store';\n\nexport function sessionDetailRoute(): Hono {\n const r = new Hono();\n r.get('/:id', async (c) => {\n const id = c.req.param('id');\n const detail = await readSessionDetail(resolveByfHome(), id);\n if (!detail) return c.json({ error: 'session not found', code: 'NOT_FOUND' }, 404);\n return c.json(detail);\n });\n return r;\n}\n",
|
|
14
|
+
"import { rm } from 'node:fs/promises';\n\nimport { Hono } from 'hono';\n\nimport { resolveByfHome } from '../config';\nimport { revealInOs } from '../lib/reveal';\nimport { listSessions, readSessionDetail } from '../lib/session-store';\n\nexport function sessionsRoute(): Hono {\n const r = new Hono();\n r.get('/', async (c) => {\n const sessions = await listSessions(resolveByfHome());\n return c.json({ sessions });\n });\n r.delete('/:id', async (c) => {\n const id = c.req.param('id');\n const all = await listSessions(resolveByfHome());\n const target = all.find((s) => s.sessionId === id);\n if (!target) return c.json({ error: 'session not found', code: 'NOT_FOUND' }, 404);\n await rm(target.sessionDir, { recursive: true, force: true });\n return c.json({ sessionId: id, deleted: true });\n });\n // Open the session directory in the OS file manager. The folder is\n // opened on the SERVER host — only meaningful when vis runs locally.\n r.post('/:id/reveal', async (c) => {\n const id = c.req.param('id');\n const detail = await readSessionDetail(resolveByfHome(), id);\n if (!detail) return c.json({ error: 'session not found', code: 'NOT_FOUND' }, 404);\n try {\n await revealInOs(detail.sessionDir);\n return c.json({ sessionId: id, opened: detail.sessionDir });\n } catch (error) {\n return c.json(\n { error: `failed to open: ${(error as Error).message}`, code: 'READ_ERROR' },\n 500,\n );\n }\n });\n return r;\n}\n",
|
|
15
|
+
"import { spawn } from 'node:child_process';\n\nexport interface RevealCommand {\n readonly command: string;\n readonly args: readonly string[];\n}\n\n/** Resolve the platform-specific \"reveal in file manager\" command for\n * the given absolute path. Kept pure (no IO) so it can be unit-tested. */\nexport function revealCommandFor(\n path: string,\n platform: NodeJS.Platform = process.platform,\n): RevealCommand {\n // oxlint-disable-next-line typescript(switch-exhaustiveness-check) -- only darwin/win32 differ; all other platforms fall back to xdg-open\n switch (platform) {\n case 'darwin':\n return { command: 'open', args: [path] };\n case 'win32':\n // `start` is a cmd built-in; the empty title `\"\"` prevents the path\n // from being mistaken for a window title.\n return { command: 'cmd', args: ['/c', 'start', '\"\"', path] };\n default:\n return { command: 'xdg-open', args: [path] };\n }\n}\n\n/** Spawn the OS file manager to reveal `path`. Resolves once the launcher\n * process has started; rejects only if the launcher itself fails to\n * spawn (missing binary etc.) — not if it later fails to find the path,\n * since the launcher exits asynchronously after we've detached. */\nexport async function revealInOs(path: string): Promise<void> {\n const { command, args } = revealCommandFor(path);\n return new Promise<void>((resolve, reject) => {\n let settled = false;\n const child = spawn(command, args, { detached: true, stdio: 'ignore' });\n child.once('error', (err) => {\n if (settled) return;\n settled = true;\n reject(err);\n });\n child.once('spawn', () => {\n if (settled) return;\n settled = true;\n child.unref();\n resolve();\n });\n });\n}\n",
|
|
16
|
+
"import { Hono } from 'hono';\n\nimport { resolveByfHome } from '../config';\nimport { buildAgentTree } from '../lib/agent-tree';\nimport { readSessionDetail } from '../lib/session-store';\n\nexport function subagentsRoute(): Hono {\n const r = new Hono();\n r.get('/:id/agents', async (c) => {\n const id = c.req.param('id');\n const detail = await readSessionDetail(resolveByfHome(), id);\n if (!detail) {\n return c.json({ error: 'session not found', code: 'NOT_FOUND' }, 404);\n }\n return c.json({ sessionId: id, tree: buildAgentTree(detail.agents) });\n });\n return r;\n}\n",
|
|
17
|
+
"import type { AgentInfo } from './agent-record-types';\n\nexport interface AgentNode extends AgentInfo {\n children: AgentNode[];\n}\n\n/**\n * Build a parent/child tree from the flat agent inventory found on\n * `state.json.agents`. Roots are agents with no `parentAgentId`, plus any\n * agent whose `parentAgentId` does not resolve in the inventory (orphans).\n * The returned roots are sorted so that the `main` agent always appears\n * first; remaining roots fall back to a stable lexicographic order.\n */\nexport function buildAgentTree(agents: ReadonlyArray<AgentInfo>): AgentNode[] {\n const byId = new Map<string, AgentNode>();\n for (const a of agents) byId.set(a.agentId, { ...a, children: [] });\n\n const roots: AgentNode[] = [];\n for (const node of byId.values()) {\n if (node.parentAgentId !== null && byId.has(node.parentAgentId)) {\n byId.get(node.parentAgentId)!.children.push(node);\n } else {\n roots.push(node);\n }\n }\n return roots.toSorted(sortAgents);\n}\n\nfunction sortAgents(a: AgentNode, b: AgentNode): number {\n if (a.agentId === 'main') return -1;\n if (b.agentId === 'main') return 1;\n return a.agentId.localeCompare(b.agentId);\n}\n",
|
|
18
|
+
"import { join } from 'node:path';\n\nimport { Hono } from 'hono';\n\nimport { resolveByfHome } from '../config';\nimport { isSafeAgentId, readSessionDetail } from '../lib/session-store';\nimport { readAgentWire } from '../lib/wire-reader';\n\nexport function wireRoute(): Hono {\n const r = new Hono();\n r.get('/:id/wire', async (c) => {\n const id = c.req.param('id');\n const agentId = c.req.query('agent') ?? 'main';\n if (!isSafeAgentId(agentId)) {\n return c.json({ error: 'invalid agent id', code: 'BAD_REQUEST' }, 400);\n }\n const detail = await readSessionDetail(resolveByfHome(), id);\n if (!detail) {\n return c.json({ error: 'session not found', code: 'NOT_FOUND' }, 404);\n }\n const agent = detail.agents.find((a) => a.agentId === agentId);\n if (!agent) {\n return c.json({ error: `agent \"${agentId}\" not found`, code: 'NOT_FOUND' }, 404);\n }\n if (!agent.wireExists) {\n return c.json({ error: 'wire missing', code: 'NOT_FOUND' }, 404);\n }\n try {\n const result = await readAgentWire(join(detail.sessionDir, 'agents', agentId, 'wire.jsonl'));\n return c.json({\n sessionId: id,\n agentId,\n protocolVersion: result.metadata.protocolVersion,\n metadata: result.metadata,\n records: result.records,\n warnings: result.warnings,\n });\n } catch (error) {\n const msg = (error as Error).message;\n if (msg.toLowerCase().includes('unsupported protocol')) {\n return c.json({ error: msg, code: 'UNSUPPORTED_PROTOCOL' }, 400);\n }\n return c.json({ error: msg, code: 'READ_ERROR' }, 500);\n }\n });\n return r;\n}\n",
|
|
19
|
+
"export interface StartupBannerOptions {\n readonly authToken?: string;\n readonly host: string;\n readonly byfCodeHome: string;\n readonly port: number;\n}\n\nexport function formatStartupBanner(options: StartupBannerOptions): string {\n const authStatus = options.authToken === undefined ? 'auth=disabled' : 'auth=required';\n return (\n `[vis-server] listening on http://${hostForUrl(options.host)}:${String(options.port)} ` +\n `(${authStatus}, BYF_HOME=${options.byfCodeHome})\\n`\n );\n}\n\nfunction hostForUrl(host: string): string {\n if (host.includes(':') && !host.startsWith('[')) return `[${host}]`;\n return host;\n}\n",
|
|
20
|
+
"import { createApp } from './app';\nimport { resolveByfHome, resolveHost, resolvePort, resolveVisAuthToken } from './config';\nimport { formatStartupBanner } from './startup-banner';\n\n/** Options for starting a vis HTTP server programmatically. */\nexport interface StartVisServerOptions {\n /** Bind host. Defaults to `resolveHost()` (loopback). */\n readonly host?: string;\n /** Bind port. Defaults to `resolvePort()` (3001). */\n readonly port?: number;\n /** Auth token. Defaults to `resolveVisAuthToken(host)` (required outside loopback). */\n readonly authToken?: string;\n /**\n * Directory holding the built SPA assets to serve. When omitted, the\n * `public/` directory next to the compiled server bundle is used (if any);\n * in dev mode this resolves to `null` and only the API is served.\n */\n readonly publicDir?: string;\n}\n\n/** A handle to a running vis server. */\nexport interface VisServerHandle {\n /** The host the server is bound to. */\n readonly host: string;\n /** The port the server is bound to. */\n readonly port: number;\n /** Base URL (`http://<host>:<port>`), with IPv6 hosts bracketed. */\n readonly url: string;\n /** Stop the server. Subsequent connections are refused. */\n close(): void;\n}\n\nfunction hostForUrl(host: string): string {\n if (host.includes(':') && !host.startsWith('[')) return `[${host}]`;\n return host;\n}\n\n/**\n * Start the vis HTTP server programmatically. Resolves once the server is\n * listening. Used by the CLI `byf vis` subcommand (in-process) and by the\n * standalone `index.ts` entry.\n *\n * Binds via `Bun.serve` (library runtime contract is Bun-only). Bind failures\n * such as `EADDRINUSE` throw synchronously so callers can catch them.\n */\nexport async function startVisServer(\n options: StartVisServerOptions = {},\n): Promise<VisServerHandle> {\n const host = options.host ?? resolveHost();\n const port = options.port ?? resolvePort();\n const authToken = options.authToken ?? resolveVisAuthToken(host);\n const app = await createApp({ authToken, publicDir: options.publicDir });\n\n // Bun.serve binds before returning. Port-in-use and other listen failures\n // throw (with `code: 'EADDRINUSE'` when applicable) rather than emitting an\n // async 'error' event as Node's http.Server did via @hono/node-server.\n const server = Bun.serve({\n hostname: host,\n port,\n fetch: app.fetch,\n });\n\n // Bun.serve().port is typed optional; after a successful bind it is always set.\n const actualPort = server.port ?? port;\n return {\n host,\n port: actualPort,\n url: `http://${hostForUrl(host)}:${actualPort}`,\n close: () => {\n // stop(true) drops keep-alive / in-flight sockets so the event loop can\n // empty and the process can exit promptly after close().\n void server.stop(true);\n },\n };\n}\n\n/**\n * Resolve the BYF_HOME the server reads session records from. Exposed for the\n * standalone entry's startup banner. CLI consumers rely on the same env var.\n */\nexport function resolveVisByfHome(): string {\n return resolveByfHome();\n}\n\n/**\n * Format the startup banner text. Exposed so the CLI can reuse the exact same\n * wording without depending on startup-banner internals.\n */\nexport function formatVisStartupBanner(input: {\n readonly authToken?: string;\n readonly host: string;\n readonly port: number;\n}): string {\n return formatStartupBanner({\n authToken: input.authToken,\n host: input.host,\n byfCodeHome: resolveByfHome(),\n port: input.port,\n });\n}\n"
|
|
21
|
+
],
|
|
22
|
+
"mappings": "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",
|
|
23
|
+
"debugId": "8EBCC0393347A59C64756E2164756E21",
|
|
24
|
+
"names": []
|
|
25
|
+
}
|
package/dist/server.d.mts
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
//#region src/server.d.ts
|
|
2
1
|
/** Options for starting a vis HTTP server programmatically. */
|
|
3
|
-
interface StartVisServerOptions {
|
|
2
|
+
export interface StartVisServerOptions {
|
|
4
3
|
/** Bind host. Defaults to `resolveHost()` (loopback). */
|
|
5
4
|
readonly host?: string;
|
|
6
5
|
/** Bind port. Defaults to `resolvePort()` (3001). */
|
|
@@ -15,7 +14,7 @@ interface StartVisServerOptions {
|
|
|
15
14
|
readonly publicDir?: string;
|
|
16
15
|
}
|
|
17
16
|
/** A handle to a running vis server. */
|
|
18
|
-
interface VisServerHandle {
|
|
17
|
+
export interface VisServerHandle {
|
|
19
18
|
/** The host the server is bound to. */
|
|
20
19
|
readonly host: string;
|
|
21
20
|
/** The port the server is bound to. */
|
|
@@ -30,20 +29,18 @@ interface VisServerHandle {
|
|
|
30
29
|
* listening. Used by the CLI `byf vis` subcommand (in-process) and by the
|
|
31
30
|
* standalone `index.ts` entry.
|
|
32
31
|
*/
|
|
33
|
-
declare function startVisServer(options?: StartVisServerOptions): Promise<VisServerHandle>;
|
|
32
|
+
export declare function startVisServer(options?: StartVisServerOptions): Promise<VisServerHandle>;
|
|
34
33
|
/**
|
|
35
34
|
* Resolve the BYF_HOME the server reads session records from. Exposed for the
|
|
36
35
|
* standalone entry's startup banner. CLI consumers rely on the same env var.
|
|
37
36
|
*/
|
|
38
|
-
declare function resolveVisByfHome(): string;
|
|
37
|
+
export declare function resolveVisByfHome(): string;
|
|
39
38
|
/**
|
|
40
39
|
* Format the startup banner text. Exposed so the CLI can reuse the exact same
|
|
41
40
|
* wording without depending on startup-banner internals.
|
|
42
41
|
*/
|
|
43
|
-
declare function formatVisStartupBanner(input: {
|
|
42
|
+
export declare function formatVisStartupBanner(input: {
|
|
44
43
|
readonly authToken?: string;
|
|
45
44
|
readonly host: string;
|
|
46
45
|
readonly port: number;
|
|
47
46
|
}): string;
|
|
48
|
-
//#endregion
|
|
49
|
-
export { StartVisServerOptions, VisServerHandle, formatVisStartupBanner, resolveVisByfHome, startVisServer };
|
package/dist/server.mjs
CHANGED
|
@@ -1,2 +1,13 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
1
|
+
import {
|
|
2
|
+
formatVisStartupBanner,
|
|
3
|
+
resolveVisByfHome,
|
|
4
|
+
startVisServer
|
|
5
|
+
} from "./server-enpsx6np.mjs";
|
|
6
|
+
export {
|
|
7
|
+
startVisServer,
|
|
8
|
+
resolveVisByfHome,
|
|
9
|
+
formatVisStartupBanner
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
//# debugId=44AA6CEDB8F1FBF964756E2164756E21
|
|
13
|
+
//# sourceMappingURL=server.mjs.map
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@byfriends/vis-server",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0",
|
|
4
4
|
"description": "HTTP server for BYF session visualization, serving the API and built SPA assets",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"byf",
|
|
@@ -42,19 +42,19 @@
|
|
|
42
42
|
"provenance": false
|
|
43
43
|
},
|
|
44
44
|
"scripts": {
|
|
45
|
-
"dev": "
|
|
46
|
-
"build": "
|
|
47
|
-
"test": "
|
|
45
|
+
"dev": "bun --watch src/index.ts",
|
|
46
|
+
"build": "bun ../../../build/bun-lib-build.mjs ./src/server.ts ./src/index.ts --bundle-workspace && bun scripts/build-dts.mjs && bun ../scripts/copy-web-dist.mjs",
|
|
47
|
+
"test": "bun test"
|
|
48
48
|
},
|
|
49
49
|
"dependencies": {
|
|
50
|
-
"@byfriends/agent-core": "
|
|
51
|
-
"@hono/node-server": "^1.13.7",
|
|
50
|
+
"@byfriends/agent-core": "^0.4.0",
|
|
52
51
|
"hono": "^4.7.7"
|
|
53
52
|
},
|
|
54
53
|
"devDependencies": {
|
|
55
|
-
"@byfriends/kosong": "
|
|
56
|
-
"@byfriends/vis-web": "
|
|
57
|
-
|
|
58
|
-
|
|
54
|
+
"@byfriends/kosong": "0.4.0",
|
|
55
|
+
"@byfriends/vis-web": "0.3.2"
|
|
56
|
+
},
|
|
57
|
+
"engines": {
|
|
58
|
+
"bun": ">=1.3.14"
|
|
59
59
|
}
|
|
60
60
|
}
|