remote-codex 0.1.10 → 0.11.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.
Files changed (40) hide show
  1. package/apps/supervisor-api/dist/index.js +11159 -27875
  2. package/apps/supervisor-web/dist/assets/{highlighted-body-OFNGDK62-CyMcatlD.js → highlighted-body-OFNGDK62-ChrwAL9u.js} +1 -1
  3. package/apps/supervisor-web/dist/assets/index-DHf2HOXx.js +381 -0
  4. package/apps/supervisor-web/dist/assets/index-DpWxXCgt.css +32 -0
  5. package/apps/supervisor-web/dist/assets/{xterm-DbYWMNQ0.js → xterm-D4sevve4.js} +1 -1
  6. package/apps/supervisor-web/dist/index.html +2 -2
  7. package/package.json +2 -3
  8. package/packages/agent-runtime/src/index.ts +4 -0
  9. package/packages/agent-runtime/src/management-errors.ts +11 -0
  10. package/packages/agent-runtime/src/model-pricing.ts +312 -0
  11. package/packages/agent-runtime/src/registry.ts +19 -4
  12. package/packages/agent-runtime/src/runtime-errors.ts +97 -0
  13. package/packages/agent-runtime/src/types.ts +36 -3
  14. package/packages/agent-runtime/src/unavailable-runtime.ts +169 -0
  15. package/packages/claude/src/runtimeAdapter.test.ts +95 -6
  16. package/packages/claude/src/runtimeAdapter.ts +421 -65
  17. package/packages/codex/src/historyItems.test.ts +110 -0
  18. package/packages/codex/src/historyItems.ts +96 -15
  19. package/packages/codex/src/hookHistory.test.ts +59 -0
  20. package/packages/codex/src/index.ts +7 -0
  21. package/packages/codex/src/local-session-store.ts +390 -0
  22. package/packages/codex/src/management/codex-management-service.ts +454 -0
  23. package/packages/codex/src/management/codexHostConfig.test.ts +88 -0
  24. package/packages/codex/src/management/codexHostConfig.ts +188 -0
  25. package/packages/codex/src/management/errors.ts +20 -0
  26. package/packages/codex/src/modelPricing.test.ts +184 -0
  27. package/packages/codex/src/modelPricing.ts +9 -0
  28. package/packages/codex/src/runtime-errors.test.ts +72 -0
  29. package/packages/codex/src/runtime-errors.ts +37 -0
  30. package/packages/codex/src/runtimeAdapter.ts +15 -0
  31. package/packages/codex/src/thread-title.ts +1 -0
  32. package/packages/opencode/src/historyItems.test.ts +504 -0
  33. package/packages/opencode/src/historyItems.ts +896 -0
  34. package/packages/opencode/src/index.ts +2 -0
  35. package/packages/opencode/src/runtimeAdapter.test.ts +1355 -0
  36. package/packages/opencode/src/runtimeAdapter.ts +1469 -0
  37. package/packages/shared/src/agent-providers.ts +56 -0
  38. package/packages/shared/src/index.ts +170 -35
  39. package/apps/supervisor-web/dist/assets/index-BlAhoIuq.js +0 -379
  40. package/apps/supervisor-web/dist/assets/index-DI0NRNgr.css +0 -32
@@ -2,17 +2,21 @@ import { describe, expect, it } from 'vitest';
2
2
  import fs from 'node:fs/promises';
3
3
  import os from 'node:os';
4
4
  import path from 'node:path';
5
- import type {
6
- Query,
7
- SDKMessage,
8
- SDKSessionInfo,
9
- SessionMessage,
10
- } from '@anthropic-ai/claude-agent-sdk';
11
5
 
12
6
  import { ClaudeRuntimeAdapter } from './runtimeAdapter';
13
7
  import { hiddenInitPrompt } from './historyItems';
14
8
  import type { AgentRuntimeEvent } from '../../agent-runtime/src/index';
15
9
 
10
+ type SDKMessage = Record<string, any>;
11
+ type SDKSessionInfo = Record<string, any>;
12
+ type SessionMessage = Record<string, any>;
13
+ interface Query extends AsyncIterable<SDKMessage> {
14
+ close(): void;
15
+ interrupt(): Promise<void>;
16
+ supportedModels(): Promise<any[]>;
17
+ mcpServerStatus(): Promise<any[]>;
18
+ }
19
+
16
20
  function wait(ms = 0) {
17
21
  return new Promise((resolve) => setTimeout(resolve, ms));
18
22
  }
@@ -229,6 +233,23 @@ describe('ClaudeRuntimeAdapter', () => {
229
233
  expect(sdkOptions[0]?.pathToClaudeCodeExecutable).toBe('claude');
230
234
  });
231
235
 
236
+ it('does not pass an empty tool list to Claude session initialization', async () => {
237
+ const sdkOptions: Record<string, unknown>[] = [];
238
+ const adapter = makeAdapter((_prompt, options) => {
239
+ sdkOptions.push(options);
240
+ return [systemInit(), result()];
241
+ });
242
+
243
+ await adapter.startSession({
244
+ cwd: '/tmp/workspace',
245
+ model: 'sonnet',
246
+ approvalMode: 'guarded',
247
+ sandboxMode: 'workspace-write',
248
+ });
249
+
250
+ expect(sdkOptions[0]).not.toHaveProperty('tools');
251
+ });
252
+
232
253
  it('maps thread sandbox modes to Claude permission and sandbox settings', async () => {
233
254
  const turnOptions: Record<string, unknown>[] = [];
234
255
  const adapter = makeAdapter((_prompt, options) => {
@@ -436,6 +457,74 @@ describe('ClaudeRuntimeAdapter', () => {
436
457
  });
437
458
  });
438
459
 
460
+ it('keeps image blocks visible when reading Claude session history', async () => {
461
+ const workspace = await fs.mkdtemp(path.join(os.tmpdir(), 'claude-history-image-'));
462
+ const adapter = new ClaudeRuntimeAdapter({
463
+ home: '/tmp/claude-home',
464
+ command: 'claude',
465
+ query: (() => new FakeQuery([systemInit(), result()])) as any,
466
+ listSessions: (async () => [] satisfies SDKSessionInfo[]) as any,
467
+ getSessionInfo: (async () => ({
468
+ sessionId: 'claude-session-1',
469
+ summary: 'Existing session',
470
+ lastModified: 1_772_000_000_000,
471
+ createdAt: 1_771_000_000_000,
472
+ cwd: workspace,
473
+ })) as any,
474
+ getSessionMessages: (async () => [
475
+ {
476
+ type: 'user',
477
+ uuid: '019e4657-bd3c-72d1-b59d-324ed8a4b1ec',
478
+ session_id: 'claude-session-1',
479
+ message: {
480
+ role: 'user',
481
+ content: [
482
+ { type: 'text', text: 'What number is in the screenshot? ' },
483
+ {
484
+ type: 'image',
485
+ source: {
486
+ type: 'base64',
487
+ media_type: 'image/png',
488
+ data: 'ZmFrZS1wbmc=',
489
+ },
490
+ },
491
+ ],
492
+ },
493
+ parent_tool_use_id: null,
494
+ },
495
+ {
496
+ type: 'assistant',
497
+ uuid: '019e4657-bd3c-72d1-b59d-324ed8a4b1ed',
498
+ session_id: 'claude-session-1',
499
+ message: {
500
+ role: 'assistant',
501
+ content: [{ type: 'text', text: 'The number is 9.' }],
502
+ },
503
+ parent_tool_use_id: null,
504
+ },
505
+ ] satisfies SessionMessage[]) as any,
506
+ });
507
+
508
+ const session = await adapter.readSession('claude-session-1', {
509
+ localThreadId: 'thread-1',
510
+ workspacePath: workspace,
511
+ });
512
+
513
+ expect(session.turns[0]?.items[0]).toMatchObject({
514
+ kind: 'userMessage',
515
+ text: 'What number is in the screenshot? \n[PHOTO ./.temp/threads/thread-1/claude-history-019e4657-bd3c-72d1-b59d-324ed8a4b1ec-1.png]',
516
+ });
517
+ await expect(
518
+ fs.readFile(
519
+ path.join(
520
+ workspace,
521
+ '.temp/threads/thread-1/claude-history-019e4657-bd3c-72d1-b59d-324ed8a4b1ec-1.png',
522
+ ),
523
+ 'utf8',
524
+ ),
525
+ ).resolves.toBe('fake-png');
526
+ });
527
+
439
528
  it('starts a session from the Claude init message and hides the synthetic prompt', async () => {
440
529
  const adapter = makeAdapter((prompt) => {
441
530
  expect(prompt).toBe(hiddenInitPrompt());