@okrapdf/cli 0.3.2 → 0.3.4

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.
Files changed (48) hide show
  1. package/dist/cli.test.js +178 -11
  2. package/dist/cli.test.js.map +1 -1
  3. package/dist/commands/chat-schema-output.test.d.ts +2 -0
  4. package/dist/commands/chat-schema-output.test.d.ts.map +1 -0
  5. package/dist/commands/chat-schema-output.test.js +151 -0
  6. package/dist/commands/chat-schema-output.test.js.map +1 -0
  7. package/dist/commands/chat.d.ts.map +1 -1
  8. package/dist/commands/chat.js +268 -12
  9. package/dist/commands/chat.js.map +1 -1
  10. package/dist/commands/chat.test.js +178 -3
  11. package/dist/commands/chat.test.js.map +1 -1
  12. package/dist/commands/jobs.d.ts.map +1 -1
  13. package/dist/commands/jobs.js +4 -3
  14. package/dist/commands/jobs.js.map +1 -1
  15. package/dist/index.js +0 -0
  16. package/dist/lib/agent-renderer.d.ts +12 -0
  17. package/dist/lib/agent-renderer.d.ts.map +1 -1
  18. package/dist/lib/agent-renderer.js +28 -0
  19. package/dist/lib/agent-renderer.js.map +1 -1
  20. package/dist/lib/client.d.ts +1 -0
  21. package/dist/lib/client.d.ts.map +1 -1
  22. package/dist/lib/client.js +1 -0
  23. package/dist/lib/client.js.map +1 -1
  24. package/dist/lib/config.d.ts +8 -0
  25. package/dist/lib/config.d.ts.map +1 -1
  26. package/dist/lib/config.js +13 -0
  27. package/dist/lib/config.js.map +1 -1
  28. package/dist/lib/progress.d.ts +6 -2
  29. package/dist/lib/progress.d.ts.map +1 -1
  30. package/dist/lib/progress.js +5 -2
  31. package/dist/lib/progress.js.map +1 -1
  32. package/dist/lib/runtime.d.ts.map +1 -1
  33. package/dist/lib/runtime.js +5 -0
  34. package/dist/lib/runtime.js.map +1 -1
  35. package/dist/lib/structured-output.d.ts +32 -0
  36. package/dist/lib/structured-output.d.ts.map +1 -0
  37. package/dist/lib/structured-output.js +156 -0
  38. package/dist/lib/structured-output.js.map +1 -0
  39. package/dist/lib/structured-output.test.d.ts +2 -0
  40. package/dist/lib/structured-output.test.d.ts.map +1 -0
  41. package/dist/lib/structured-output.test.js +148 -0
  42. package/dist/lib/structured-output.test.js.map +1 -0
  43. package/dist/lib/system-prompt.d.ts +4 -0
  44. package/dist/lib/system-prompt.d.ts.map +1 -1
  45. package/dist/lib/system-prompt.js +8 -0
  46. package/dist/lib/system-prompt.js.map +1 -1
  47. package/dist/templates/replay-viewer.html +230 -0
  48. package/package.json +4 -3
@@ -22,29 +22,70 @@ import '../lib/ws-polyfill.js';
22
22
  import { Command } from 'commander';
23
23
  import { AgentSessionClient } from '@steventsao/agent-session';
24
24
  import { fetchBootstrap } from '../lib/bootstrap.js';
25
- import { AgentRenderer } from '../lib/agent-renderer.js';
26
- import { CLI_SYSTEM_PROMPT } from '../lib/system-prompt.js';
27
- import { getApiKey } from '../lib/config.js';
25
+ import { AgentRenderer, SilentCollectorRenderer } from '../lib/agent-renderer.js';
26
+ import { buildSystemPrompt } from '../lib/system-prompt.js';
27
+ import { getApiKey, getAgentSessionUrl, getAgentSessionHttpUrl } from '../lib/config.js';
28
28
  import { error, info } from '../lib/output.js';
29
29
  import { createSpinner } from '../lib/progress.js';
30
30
  import { OkraApiError, EXIT_CODES } from '../lib/client.js';
31
- const WSS_URL = 'wss://agent-session.steventsao.workers.dev';
31
+ import { resolveSchema, extractJson, listBuiltinNames, } from '../lib/structured-output.js';
32
+ const WSS_URL = getAgentSessionUrl();
32
33
  const SANDBOX_TEMPLATE = 'okra-claude-agent-sdk';
33
34
  const SANDBOX_TIMEOUT_MS = 120_000;
34
35
  export function createChatCommand() {
35
36
  const chat = new Command('chat')
36
- .description('Chat with a document via agent session')
37
+ .description('Chat with a document via agent session');
38
+ // Default subcommand: okra chat <jobId> -m "msg"
39
+ const send = new Command('send')
40
+ .description('Send a message to a document chat session')
37
41
  .argument('<jobId>', 'OCR job ID (e.g. ocr-Bvx9ire6wFEHbsjecW3FM)')
38
42
  .requiredOption('-m, --message <message>', 'Message to send')
39
43
  .option('-o, --output <format>', 'Output format (text, json)', 'text')
44
+ .option('-s, --schema <schema>', 'Structured output: built-in name, inline JSON, or file path')
40
45
  .action(async (jobId, options) => {
46
+ // Handle --schema help
47
+ if (options.schema === 'help') {
48
+ console.log('Built-in schemas:');
49
+ for (const name of listBuiltinNames()) {
50
+ console.log(` ${name}`);
51
+ }
52
+ console.log('\nYou can also pass inline JSON or a file path:');
53
+ console.log(' --schema \'{"type":"object","properties":{"name":{"type":"string"}}}\'');
54
+ console.log(' --schema ./my-schema.json');
55
+ process.exit(0);
56
+ }
57
+ // Resolve schema (built-in name, inline JSON, or file path)
58
+ let resolvedSchema;
59
+ if (options.schema) {
60
+ const result = resolveSchema(options.schema);
61
+ if ('error' in result) {
62
+ error(result.error);
63
+ process.exit(EXIT_CODES.INVALID_ARGS);
64
+ }
65
+ resolvedSchema = result.schema;
66
+ }
41
67
  const apiKey = getApiKey();
42
68
  if (!apiKey) {
43
69
  error('Not authenticated. Run `okra auth login` first.');
44
70
  process.exit(EXIT_CODES.AUTH_ERROR);
45
71
  }
72
+ // In schema mode, all human-friendly output goes to stderr (gh CLI pattern).
73
+ // stdout is reserved exclusively for the JSON result.
74
+ const spinnerStream = resolvedSchema ? process.stderr : undefined;
75
+ // Suppress library console.log that pollutes stdout
76
+ // (AgentSessionClient logs "[AgentSession] ..." to console.log)
77
+ // Must happen before client.connect() so connect/connected logs are caught.
78
+ const origConsoleLog = console.log;
79
+ if (resolvedSchema) {
80
+ console.log = (...args) => {
81
+ const first = typeof args[0] === 'string' ? args[0] : '';
82
+ if (first.startsWith('[AgentSession]'))
83
+ return;
84
+ origConsoleLog(...args);
85
+ };
86
+ }
46
87
  // 1. Fetch bootstrap (archive URL + metadata)
47
- const bootSpinner = createSpinner('Preparing document...');
88
+ const bootSpinner = createSpinner('Preparing document...', { stream: spinnerStream });
48
89
  bootSpinner.start();
49
90
  let archiveUrl;
50
91
  let totalPages;
@@ -68,7 +109,9 @@ export function createChatCommand() {
68
109
  process.exit(EXIT_CODES.GENERAL_ERROR);
69
110
  }
70
111
  // 2. Connect WebSocket
71
- const renderer = new AgentRenderer();
112
+ const renderer = resolvedSchema
113
+ ? new SilentCollectorRenderer()
114
+ : new AgentRenderer();
72
115
  const client = new AgentSessionClient({
73
116
  url: WSS_URL,
74
117
  sessionId: jobId,
@@ -116,7 +159,7 @@ export function createChatCommand() {
116
159
  rejectAgent = reject;
117
160
  });
118
161
  // 3. Register event handlers
119
- const sandboxSpinner = createSpinner('Booting sandbox...');
162
+ const sandboxSpinner = createSpinner('Booting sandbox...', { stream: spinnerStream });
120
163
  client.on('READY', (event) => {
121
164
  if (event.sandboxId) {
122
165
  // Sandbox already running — server sends SANDBOX_STATUS ready separately
@@ -141,6 +184,8 @@ export function createChatCommand() {
141
184
  return;
142
185
  renderer.onAgentStarted();
143
186
  });
187
+ // Capture structured_output from SDK result event
188
+ let structuredOutput = undefined;
144
189
  client.on('AGENT_MESSAGE', (event) => {
145
190
  if (!messageSent)
146
191
  return;
@@ -151,6 +196,10 @@ export function createChatCommand() {
151
196
  rejectAgent(new Error(String(errMsg)));
152
197
  return;
153
198
  }
199
+ // Capture SDK structured_output from result event
200
+ if (event.subtype === 'result' && event.structured_output != null) {
201
+ structuredOutput = event.structured_output;
202
+ }
154
203
  renderer.onAgentMessage(event.message?.content);
155
204
  });
156
205
  client.on('AGENT_DONE', (event) => {
@@ -188,17 +237,27 @@ export function createChatCommand() {
188
237
  await replayDone;
189
238
  // 7. Send message — flip gate so subsequent events are rendered
190
239
  messageSent = true;
191
- info(`Sending: ${options.message}`);
240
+ if (!resolvedSchema)
241
+ info(`Sending: ${options.message}`);
242
+ const systemPrompt = buildSystemPrompt({ schema: resolvedSchema });
192
243
  // Send raw AGENT_MESSAGE so author metadata is preserved across
193
244
  // older @steventsao/agent-session client versions used by the CLI.
194
- client.send({
245
+ const wsMessage = {
195
246
  type: 'AGENT_MESSAGE',
196
247
  content: options.message,
197
248
  model: { id: 'claude-sonnet-4-20250514', provider: 'anthropic' },
198
- systemPrompt: CLI_SYSTEM_PROMPT,
249
+ systemPrompt,
199
250
  agentType: 'claude-code',
200
251
  author: { name: 'okra-cli', clientType: 'cli' },
201
- });
252
+ };
253
+ // Send JSON Schema for SDK-native structured output
254
+ if (resolvedSchema) {
255
+ wsMessage.outputFormat = {
256
+ type: 'json_schema',
257
+ schema: resolvedSchema.jsonSchema,
258
+ };
259
+ }
260
+ client.send(wsMessage);
202
261
  // 8. Wait for agent completion
203
262
  try {
204
263
  await agentDone;
@@ -207,10 +266,207 @@ export function createChatCommand() {
207
266
  error(err instanceof Error ? err.message : String(err));
208
267
  process.exitCode = EXIT_CODES.GENERAL_ERROR;
209
268
  }
269
+ // Restore console.log before outputting results
270
+ if (resolvedSchema)
271
+ console.log = origConsoleLog;
272
+ // 8b. Structured output: prefer SDK structured_output, fall back to text extraction
273
+ // Write JSON to stdout via process.stdout.write (not console.log) to keep
274
+ // a clean machine-readable stream — gh CLI pattern.
275
+ if (resolvedSchema && !process.exitCode) {
276
+ let parsed = structuredOutput ?? null;
277
+ // Fallback: extract JSON from collected text if SDK didn't return structured_output
278
+ if (parsed === null) {
279
+ const raw = renderer.getCollectedText();
280
+ parsed = extractJson(raw);
281
+ if (parsed === null) {
282
+ process.stderr.write('Failed to extract JSON from agent response.\n');
283
+ process.stderr.write('Raw output:\n' + raw + '\n');
284
+ process.exitCode = EXIT_CODES.VALIDATION_ERROR;
285
+ }
286
+ }
287
+ if (parsed !== null && !process.exitCode) {
288
+ // For built-in schemas, validate with Zod; for custom schemas, output as-is
289
+ if (resolvedSchema.zodSchema) {
290
+ const result = resolvedSchema.zodSchema.safeParse(parsed);
291
+ if (result.success) {
292
+ process.stdout.write(JSON.stringify(result.data, null, 2) + '\n');
293
+ }
294
+ else {
295
+ process.stderr.write('Schema validation failed:\n');
296
+ for (const issue of result.error.issues) {
297
+ process.stderr.write(` - ${issue.path.join('.')}: ${issue.message}\n`);
298
+ }
299
+ process.stderr.write('\nRaw JSON:\n' + JSON.stringify(parsed, null, 2) + '\n');
300
+ process.exitCode = EXIT_CODES.VALIDATION_ERROR;
301
+ }
302
+ }
303
+ else {
304
+ // Custom schema — SDK already validated via constrained decoding
305
+ process.stdout.write(JSON.stringify(parsed, null, 2) + '\n');
306
+ }
307
+ }
308
+ }
210
309
  // 9. Disconnect and exit
211
310
  client.disconnect();
212
311
  process.exit(process.exitCode ?? 0);
213
312
  });
313
+ // ── view subcommand ──────────────────────────────────────────────────
314
+ const view = new Command('view')
315
+ .description('View a past chat session (read-only replay)')
316
+ .argument('[sessionId]', 'Session ID to view')
317
+ .option('--file <path>', 'Read events from local JSONL file instead of server')
318
+ .option('--web', 'Open as static HTML in browser')
319
+ .option('--jsonl', 'Output raw JSONL to stdout')
320
+ .action(async (sessionId, opts) => {
321
+ const { readFileSync, writeFileSync } = await import('fs');
322
+ const { tmpdir } = await import('os');
323
+ const { join, dirname } = await import('path');
324
+ const { fileURLToPath } = await import('url');
325
+ const chalk = (await import('chalk')).default;
326
+ const got = (await import('got')).default;
327
+ const { openInBrowser } = await import('../lib/browser.js');
328
+ // Resolve events source
329
+ let events;
330
+ if (opts.file) {
331
+ try {
332
+ const raw = readFileSync(opts.file, 'utf8');
333
+ events = parseJsonl(raw);
334
+ }
335
+ catch (err) {
336
+ error(`Failed to read file: ${err instanceof Error ? err.message : err}`);
337
+ process.exit(EXIT_CODES.GENERAL_ERROR);
338
+ }
339
+ }
340
+ else if (sessionId) {
341
+ const apiKey = getApiKey();
342
+ if (!apiKey) {
343
+ error('Not authenticated. Run `okra auth login` first.');
344
+ process.exit(EXIT_CODES.AUTH_ERROR);
345
+ }
346
+ const spinner = createSpinner('Fetching session events...');
347
+ spinner.start();
348
+ try {
349
+ const url = `${getAgentSessionHttpUrl()}/session/${sessionId}/events`;
350
+ const response = await got(url, {
351
+ headers: { Authorization: `Bearer ${apiKey}` },
352
+ timeout: { request: 15_000 },
353
+ });
354
+ events = parseJsonl(response.body);
355
+ spinner.succeed(`${events.length} events loaded`);
356
+ }
357
+ catch (err) {
358
+ spinner.fail('Failed to fetch events');
359
+ error(err instanceof Error ? err.message : String(err));
360
+ process.exit(EXIT_CODES.GENERAL_ERROR);
361
+ }
362
+ }
363
+ else {
364
+ error('Provide a session ID or --file path');
365
+ process.exit(EXIT_CODES.INVALID_ARGS);
366
+ return;
367
+ }
368
+ if (events.length === 0) {
369
+ info('No events found');
370
+ process.exit(0);
371
+ }
372
+ // Output modes
373
+ if (opts.jsonl) {
374
+ for (const evt of events) {
375
+ console.log(JSON.stringify(evt));
376
+ }
377
+ }
378
+ else if (opts.web) {
379
+ const label = sessionId || opts.file || 'local';
380
+ const currentDir = dirname(fileURLToPath(import.meta.url));
381
+ const templatePath = join(currentDir, '..', 'templates', 'replay-viewer.html');
382
+ let template = readFileSync(templatePath, 'utf8');
383
+ template = template.replace(/\{\{SESSION_ID\}\}/g, label);
384
+ template = template.replace('{{REPLAY_DATA}}', JSON.stringify(events));
385
+ const safeId = label.replace(/[^a-zA-Z0-9_-]/g, '_');
386
+ const outPath = join(tmpdir(), `okra-replay-${safeId}.html`);
387
+ writeFileSync(outPath, template, 'utf8');
388
+ info(`Opening ${outPath}`);
389
+ await openInBrowser(`file://${outPath}`);
390
+ }
391
+ else {
392
+ renderTerminalTranscript(events, chalk);
393
+ }
394
+ process.exit(0);
395
+ });
396
+ chat.addCommand(send, { isDefault: true });
397
+ chat.addCommand(view);
214
398
  return chat;
215
399
  }
400
+ function parseJsonl(raw) {
401
+ return raw
402
+ .split('\n')
403
+ .filter(line => line.trim())
404
+ .map(line => {
405
+ try {
406
+ return JSON.parse(line);
407
+ }
408
+ catch {
409
+ return null;
410
+ }
411
+ })
412
+ .filter((e) => e !== null);
413
+ }
414
+ /* eslint-disable @typescript-eslint/no-explicit-any */
415
+ function renderTerminalTranscript(events, chalk) {
416
+ for (const evt of events) {
417
+ const ts = evt.timestamp ? chalk.dim(new Date(evt.timestamp).toLocaleTimeString() + ' ') : '';
418
+ switch (evt.type) {
419
+ case 'user': {
420
+ const author = evt.author ? chalk.dim(` (${evt.author.name})`) : '';
421
+ console.log(`\n${ts}${chalk.blue.bold('User')}${author}`);
422
+ const content = typeof evt.message?.content === 'string'
423
+ ? evt.message.content
424
+ : '';
425
+ if (content)
426
+ console.log(content);
427
+ break;
428
+ }
429
+ case 'assistant': {
430
+ console.log(`\n${ts}${chalk.bold('Assistant')}`);
431
+ const blocks = evt.message?.content;
432
+ if (Array.isArray(blocks)) {
433
+ for (const b of blocks) {
434
+ if (b.type === 'text' && b.text) {
435
+ console.log(b.text);
436
+ }
437
+ else if (b.type === 'tool_use') {
438
+ console.log(chalk.dim(` ▸ ${b.name}(${JSON.stringify(b.input).slice(0, 120)})`));
439
+ }
440
+ else if (b.type === 'tool_result') {
441
+ const text = typeof b.content === 'string' ? b.content : JSON.stringify(b.content);
442
+ if (text) {
443
+ const truncated = text.length > 200 ? text.slice(0, 200) + '...' : text;
444
+ console.log(chalk.dim(` ← ${truncated}`));
445
+ }
446
+ }
447
+ }
448
+ }
449
+ break;
450
+ }
451
+ case 'result': {
452
+ const parts = [];
453
+ if (evt.duration_ms != null)
454
+ parts.push(`${(evt.duration_ms / 1000).toFixed(1)}s`);
455
+ if (evt.total_cost_usd != null)
456
+ parts.push(`$${evt.total_cost_usd.toFixed(4)}`);
457
+ if (evt.exit_code != null)
458
+ parts.push(`exit ${evt.exit_code}`);
459
+ if (parts.length)
460
+ console.log(chalk.dim(`\n${parts.join(' · ')}`));
461
+ break;
462
+ }
463
+ case 'error':
464
+ console.log(`\n${ts}${chalk.red('Error:')} ${evt.error || ''}`);
465
+ break;
466
+ case 'system':
467
+ console.log(chalk.dim(` [system] ${evt.message || ''}`));
468
+ break;
469
+ }
470
+ }
471
+ }
216
472
  //# sourceMappingURL=chat.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"chat.js","sourceRoot":"","sources":["../../src/commands/chat.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"chat.js","sourceRoot":"","sources":["../../src/commands/chat.ts"],"names":[],"mappings":"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"}
@@ -13,7 +13,10 @@
13
13
  * The CLI adds a 100ms drain after SANDBOX_STATUS resolves to let
14
14
  * EVENTS_BATCH arrive and process before flipping messageSent = true.
15
15
  */
16
- import { describe, it, expect, vi, beforeEach } from 'vitest';
16
+ import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
17
+ import { writeFileSync, unlinkSync, mkdtempSync } from 'fs';
18
+ import { join } from 'path';
19
+ import { tmpdir } from 'os';
17
20
  // --- Mocks ---
18
21
  class MockAgentSessionClient {
19
22
  handlers = new Map();
@@ -55,6 +58,8 @@ vi.mock('../lib/bootstrap.js', () => ({
55
58
  }));
56
59
  vi.mock('../lib/config.js', () => ({
57
60
  getApiKey: vi.fn().mockReturnValue('okra_testkey123'),
61
+ getAgentSessionUrl: vi.fn().mockReturnValue('wss://test.example.com'),
62
+ getAgentSessionHttpUrl: vi.fn().mockReturnValue('https://test.example.com'),
58
63
  }));
59
64
  vi.mock('../lib/output.js', () => ({
60
65
  error: vi.fn(),
@@ -81,9 +86,28 @@ vi.mock('../lib/agent-renderer.js', () => ({
81
86
  onAgentDone: vi.fn().mockImplementation(() => { agentDoneCount++; }),
82
87
  onAgentError: vi.fn().mockImplementation((msg) => { agentErrors.push(msg); }),
83
88
  })),
89
+ SilentCollectorRenderer: vi.fn().mockImplementation(() => {
90
+ const chunks = [];
91
+ return {
92
+ onAgentStarted: vi.fn().mockImplementation(() => { chunks.length = 0; }),
93
+ onAgentMessage: vi.fn().mockImplementation((content) => {
94
+ if (!content)
95
+ return;
96
+ for (const block of content) {
97
+ if (block.type === 'text' && block.text)
98
+ chunks.push(block.text);
99
+ }
100
+ }),
101
+ onAgentDone: vi.fn(),
102
+ onAgentError: vi.fn().mockImplementation((msg) => { agentErrors.push(msg); }),
103
+ getCollectedText: vi.fn().mockImplementation(() => chunks.join('')),
104
+ };
105
+ }),
84
106
  }));
85
107
  vi.mock('../lib/system-prompt.js', () => ({
86
- CLI_SYSTEM_PROMPT: 'test system prompt',
108
+ buildSystemPrompt: vi.fn().mockImplementation((opts) => {
109
+ return opts?.schema ? `test system prompt\n<structured-output>${opts.schema.source || 'custom'}</structured-output>` : 'test system prompt';
110
+ }),
87
111
  }));
88
112
  vi.mock('../lib/ws-polyfill.js', () => ({}));
89
113
  vi.spyOn(process, 'exit').mockImplementation((() => { }));
@@ -130,7 +154,7 @@ describe('chat command — replay handling', () => {
130
154
  // Wait for 100ms drain to complete + message to be sent
131
155
  await new Promise(r => setTimeout(r, 150));
132
156
  // Verify our message was sent
133
- expect(mockClient.sentMessages.some(m => m.type === 'SEND_AGENT_MESSAGE' && m.message === 'hi')).toBe(true);
157
+ expect(mockClient.sentMessages.some(m => m.type === 'AGENT_MESSAGE' && m.content === 'hi')).toBe(true);
134
158
  // --- Live events for our new message ---
135
159
  mockClient.emit('AGENT_STARTED', {});
136
160
  mockClient.emit('AGENT_MESSAGE', {
@@ -169,6 +193,46 @@ describe('chat command — replay handling', () => {
169
193
  expect(renderedMessages).toHaveLength(1);
170
194
  expect(agentDoneCount).toBe(1);
171
195
  });
196
+ it('sends structured output system prompt when --schema is used', async () => {
197
+ const cmd = createChatCommand();
198
+ cmd.parseAsync(['node', 'test', 'ocr-schema1', '-m', 'summarize', '--schema', 'summary']);
199
+ await vi.waitFor(() => expect(mockClient).toBeDefined());
200
+ await vi.waitFor(() => expect(mockClient.connectCalled).toBe(true));
201
+ mockClient.emit('CONNECTED', { clientId: 'cli-s1', sessionId: 'ocr-schema1' });
202
+ mockClient.emit('READY', { sandboxId: 'sbx-s1' });
203
+ mockClient.emit('SANDBOX_STATUS', { status: 'ready', sandboxId: 'sbx-s1' });
204
+ await new Promise(r => setTimeout(r, 150));
205
+ // System prompt should contain structured-output block
206
+ const agentMsg = mockClient.sentMessages.find(m => m.type === 'AGENT_MESSAGE');
207
+ expect(agentMsg).toBeDefined();
208
+ expect(agentMsg.systemPrompt).toContain('<structured-output>');
209
+ expect(agentMsg.systemPrompt).toContain('summary');
210
+ // Should send outputFormat with JSON Schema
211
+ expect(agentMsg.outputFormat).toBeDefined();
212
+ expect(agentMsg.outputFormat.type).toBe('json_schema');
213
+ expect(agentMsg.outputFormat.schema).toBeDefined();
214
+ });
215
+ it('collects text silently and outputs JSON in schema mode', async () => {
216
+ const consoleSpy = vi.spyOn(console, 'log').mockImplementation(() => { });
217
+ const cmd = createChatCommand();
218
+ cmd.parseAsync(['node', 'test', 'ocr-schema2', '-m', 'summarize', '--schema', 'summary']);
219
+ await vi.waitFor(() => expect(mockClient).toBeDefined());
220
+ await vi.waitFor(() => expect(mockClient.connectCalled).toBe(true));
221
+ mockClient.emit('CONNECTED', { clientId: 'cli-s2', sessionId: 'ocr-schema2' });
222
+ mockClient.emit('READY', { sandboxId: 'sbx-s2' });
223
+ mockClient.emit('SANDBOX_STATUS', { status: 'ready', sandboxId: 'sbx-s2' });
224
+ await new Promise(r => setTimeout(r, 150));
225
+ // Agent returns valid JSON
226
+ mockClient.emit('AGENT_STARTED', {});
227
+ mockClient.emit('AGENT_MESSAGE', {
228
+ message: { content: [{ type: 'text', text: '{"title":"Test Doc","description":"A test","key_points":["point1"],"page_count":5}' }] },
229
+ });
230
+ mockClient.emit('AGENT_DONE', { total_cost_usd: 0.01, duration_ms: 2000 });
231
+ await new Promise(r => setTimeout(r, 50));
232
+ // Should NOT use normal renderer (agentStartedCount stays 0 for this test's renderer)
233
+ // Schema mode uses SilentCollectorRenderer
234
+ consoleSpy.mockRestore();
235
+ });
172
236
  it('handles AGENT_MESSAGE with is_error:true as an error', async () => {
173
237
  const cmd = createChatCommand();
174
238
  cmd.parseAsync(['node', 'test', 'ocr-err', '-m', 'hello']);
@@ -196,4 +260,115 @@ describe('chat command — replay handling', () => {
196
260
  expect(agentDoneCount).toBe(0);
197
261
  });
198
262
  });
263
+ // =============================================================================
264
+ // chat view — JSONL parsing + terminal transcript + HTML generation
265
+ // =============================================================================
266
+ // Mock browser so --web doesn't actually open anything
267
+ vi.mock('../lib/browser.js', () => ({
268
+ openInBrowser: vi.fn().mockResolvedValue(undefined),
269
+ }));
270
+ describe('chat view — local file rendering', () => {
271
+ let tmpDir;
272
+ let jsonlPath;
273
+ const consoleLogs = [];
274
+ let logSpy;
275
+ const SAMPLE_EVENTS = [
276
+ { type: 'user', message: { content: 'hello' }, timestamp: 1700000000000, author: { name: 'okra-cli' } },
277
+ { type: 'assistant', message: { content: [{ type: 'text', text: 'Hi there!' }] }, timestamp: 1700000001000 },
278
+ { type: 'assistant', message: { content: [{ type: 'tool_use', name: 'read_file', id: 't1', input: { path: '/app/data.csv' } }] }, timestamp: 1700000002000 },
279
+ { type: 'assistant', message: { content: [{ type: 'tool_result', tool_use_id: 't1', content: 'col1,col2\na,b' }] }, timestamp: 1700000003000 },
280
+ { type: 'result', exit_code: 0, duration_ms: 5000, total_cost_usd: 0.027, timestamp: 1700000004000 },
281
+ ];
282
+ beforeEach(() => {
283
+ tmpDir = mkdtempSync(join(tmpdir(), 'okra-test-'));
284
+ jsonlPath = join(tmpDir, 'events.jsonl');
285
+ writeFileSync(jsonlPath, SAMPLE_EVENTS.map(e => JSON.stringify(e)).join('\n'), 'utf8');
286
+ consoleLogs.length = 0;
287
+ logSpy = vi.spyOn(console, 'log').mockImplementation((...args) => {
288
+ consoleLogs.push(args.map(String).join(' '));
289
+ });
290
+ });
291
+ afterEach(() => {
292
+ logSpy.mockRestore();
293
+ try {
294
+ unlinkSync(jsonlPath);
295
+ }
296
+ catch { }
297
+ });
298
+ it('renders terminal transcript from local JSONL file', async () => {
299
+ const cmd = createChatCommand();
300
+ await cmd.parseAsync(['node', 'test', 'view', '--file', jsonlPath]);
301
+ // User message rendered
302
+ expect(consoleLogs.some(l => l.includes('User'))).toBe(true);
303
+ // Assistant text rendered
304
+ expect(consoleLogs.some(l => l.includes('Hi there!'))).toBe(true);
305
+ // Tool use rendered with name
306
+ expect(consoleLogs.some(l => l.includes('read_file'))).toBe(true);
307
+ // Tool result rendered
308
+ expect(consoleLogs.some(l => l.includes('col1,col2'))).toBe(true);
309
+ // Result line with cost
310
+ expect(consoleLogs.some(l => l.includes('$0.0270'))).toBe(true);
311
+ // Result line with duration
312
+ expect(consoleLogs.some(l => l.includes('5.0s'))).toBe(true);
313
+ });
314
+ it('outputs raw JSONL to stdout with --jsonl flag', async () => {
315
+ const cmd = createChatCommand();
316
+ await cmd.parseAsync(['node', 'test', 'view', '--file', jsonlPath, '--jsonl']);
317
+ // Each line should be valid JSON
318
+ expect(consoleLogs).toHaveLength(SAMPLE_EVENTS.length);
319
+ for (const line of consoleLogs) {
320
+ const parsed = JSON.parse(line);
321
+ expect(parsed).toHaveProperty('type');
322
+ }
323
+ // First event is user
324
+ expect(JSON.parse(consoleLogs[0]).type).toBe('user');
325
+ // Last is result
326
+ expect(JSON.parse(consoleLogs[4]).type).toBe('result');
327
+ });
328
+ it('generates HTML file with --web flag', async () => {
329
+ const { openInBrowser } = await import('../lib/browser.js');
330
+ const cmd = createChatCommand();
331
+ await cmd.parseAsync(['node', 'test', 'view', '--file', jsonlPath, '--web']);
332
+ // openInBrowser should have been called with a file:// URL
333
+ expect(openInBrowser).toHaveBeenCalledTimes(1);
334
+ const url = openInBrowser.mock.calls[0][0];
335
+ expect(url).toMatch(/^file:\/\//);
336
+ expect(url).toContain('okra-replay-');
337
+ // Read the generated HTML and verify data embedding
338
+ const { readFileSync } = await import('fs');
339
+ const htmlPath = url.replace('file://', '');
340
+ const html = readFileSync(htmlPath, 'utf8');
341
+ expect(html).toContain('OkraPDF Chat Replay');
342
+ expect(html).toContain('Hi there!'); // embedded event data
343
+ expect(html).toContain('read_file'); // tool name in data
344
+ });
345
+ it('handles empty JSONL file gracefully', async () => {
346
+ const emptyPath = join(tmpDir, 'empty.jsonl');
347
+ writeFileSync(emptyPath, '', 'utf8');
348
+ const infoMock = (await import('../lib/output.js')).info;
349
+ const cmd = createChatCommand();
350
+ await cmd.parseAsync(['node', 'test', 'view', '--file', emptyPath]);
351
+ expect(infoMock).toHaveBeenCalledWith('No events found');
352
+ });
353
+ it('handles malformed JSONL lines — skips bad lines, parses good ones', async () => {
354
+ const mixedPath = join(tmpDir, 'mixed.jsonl');
355
+ writeFileSync(mixedPath, [
356
+ '{"type":"user","message":{"content":"good line"}}',
357
+ 'this is not json',
358
+ '{"type":"result","exit_code":0}',
359
+ ].join('\n'), 'utf8');
360
+ const cmd = createChatCommand();
361
+ await cmd.parseAsync(['node', 'test', 'view', '--file', mixedPath, '--jsonl']);
362
+ // Only 2 valid lines
363
+ expect(consoleLogs).toHaveLength(2);
364
+ expect(JSON.parse(consoleLogs[0]).type).toBe('user');
365
+ expect(JSON.parse(consoleLogs[1]).type).toBe('result');
366
+ });
367
+ it('errors when no sessionId or --file provided', async () => {
368
+ const errorMock = (await import('../lib/output.js')).error;
369
+ const cmd = createChatCommand();
370
+ await cmd.parseAsync(['node', 'test', 'view']);
371
+ expect(errorMock).toHaveBeenCalledWith('Provide a session ID or --file path');
372
+ });
373
+ });
199
374
  //# sourceMappingURL=chat.test.js.map