remote-codex 0.1.10 → 0.11.1

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 (46) hide show
  1. package/apps/supervisor-api/dist/chunk-6M32PPHZ.js +24507 -0
  2. package/apps/supervisor-api/dist/chunk-7AA2MFXK.js +24499 -0
  3. package/apps/supervisor-api/dist/chunk-HKBFCPHH.js +24511 -0
  4. package/apps/supervisor-api/dist/index.js +12525 -28436
  5. package/apps/supervisor-api/dist/worker-index.d.ts +2 -0
  6. package/apps/supervisor-api/dist/worker-index.js +33 -0
  7. package/apps/supervisor-web/dist/assets/{highlighted-body-OFNGDK62-CyMcatlD.js → highlighted-body-OFNGDK62-p31aS0f0.js} +1 -1
  8. package/apps/supervisor-web/dist/assets/index-BiuFei_K.css +32 -0
  9. package/apps/supervisor-web/dist/assets/index-D1R9CUnx.js +2161 -0
  10. package/apps/supervisor-web/dist/assets/{xterm-DbYWMNQ0.js → xterm-D92BViLH.js} +1 -1
  11. package/apps/supervisor-web/dist/index.html +2 -2
  12. package/package.json +2 -3
  13. package/packages/agent-runtime/src/index.ts +4 -0
  14. package/packages/agent-runtime/src/management-errors.ts +11 -0
  15. package/packages/agent-runtime/src/model-pricing.ts +325 -0
  16. package/packages/agent-runtime/src/registry.ts +19 -4
  17. package/packages/agent-runtime/src/runtime-errors.ts +97 -0
  18. package/packages/agent-runtime/src/types.ts +36 -3
  19. package/packages/agent-runtime/src/unavailable-runtime.ts +169 -0
  20. package/packages/claude/src/historyItems.ts +41 -5
  21. package/packages/claude/src/runtimeAdapter.test.ts +117 -6
  22. package/packages/claude/src/runtimeAdapter.ts +421 -65
  23. package/packages/codex/src/historyItems.test.ts +137 -0
  24. package/packages/codex/src/historyItems.ts +135 -17
  25. package/packages/codex/src/hookHistory.test.ts +59 -0
  26. package/packages/codex/src/index.ts +7 -0
  27. package/packages/codex/src/local-session-store.ts +390 -0
  28. package/packages/codex/src/management/codex-management-service.ts +454 -0
  29. package/packages/codex/src/management/codexHostConfig.test.ts +88 -0
  30. package/packages/codex/src/management/codexHostConfig.ts +188 -0
  31. package/packages/codex/src/management/errors.ts +20 -0
  32. package/packages/codex/src/modelPricing.test.ts +235 -0
  33. package/packages/codex/src/modelPricing.ts +9 -0
  34. package/packages/codex/src/runtime-errors.test.ts +72 -0
  35. package/packages/codex/src/runtime-errors.ts +37 -0
  36. package/packages/codex/src/runtimeAdapter.ts +15 -0
  37. package/packages/codex/src/thread-title.ts +1 -0
  38. package/packages/opencode/src/historyItems.test.ts +504 -0
  39. package/packages/opencode/src/historyItems.ts +896 -0
  40. package/packages/opencode/src/index.ts +2 -0
  41. package/packages/opencode/src/runtimeAdapter.test.ts +1444 -0
  42. package/packages/opencode/src/runtimeAdapter.ts +1473 -0
  43. package/packages/shared/src/agent-providers.ts +56 -0
  44. package/packages/shared/src/index.ts +240 -35
  45. package/apps/supervisor-web/dist/assets/index-BlAhoIuq.js +0 -379
  46. package/apps/supervisor-web/dist/assets/index-DI0NRNgr.css +0 -32
@@ -0,0 +1,169 @@
1
+ import { EventEmitter } from 'node:events';
2
+
3
+ import {
4
+ agentBackendMetadata,
5
+ } from '../../shared/src/index';
6
+ import type {
7
+ AgentBackendInstallationDto,
8
+ } from '../../shared/src/index';
9
+ import type {
10
+ AgentSessionDetail,
11
+ AgentTurn,
12
+ AgentProviderId,
13
+ AgentProviderCapabilities,
14
+ AgentRuntime,
15
+ AgentRuntimeManagementSchema,
16
+ AgentRuntimeStatus,
17
+ InterruptAgentTurnInput,
18
+ ReadAgentSessionOptions,
19
+ ResumeAgentSessionInput,
20
+ StartAgentSessionInput,
21
+ StartAgentSessionResult,
22
+ StartAgentTurnInput,
23
+ } from './types';
24
+ import { AgentRuntimeError } from './types';
25
+
26
+ const unavailableCapabilities: AgentProviderCapabilities = {
27
+ sessions: {
28
+ list: false,
29
+ read: false,
30
+ resume: false,
31
+ importLocal: false,
32
+ },
33
+ turns: {
34
+ start: false,
35
+ streamInput: false,
36
+ steer: false,
37
+ interrupt: false,
38
+ compact: false,
39
+ },
40
+ branching: {
41
+ fork: false,
42
+ hardRollback: false,
43
+ resumeAt: false,
44
+ rewindFiles: false,
45
+ },
46
+ controls: {
47
+ planMode: false,
48
+ permissionRequests: false,
49
+ sandboxMode: false,
50
+ performanceMode: false,
51
+ goals: false,
52
+ },
53
+ management: {
54
+ models: false,
55
+ mcpStatus: false,
56
+ skills: false,
57
+ hooks: false,
58
+ hookTrust: false,
59
+ hostConfigFiles: false,
60
+ providerSettings: false,
61
+ },
62
+ usage: {
63
+ contextWindow: false,
64
+ tokenUsage: false,
65
+ costUsd: false,
66
+ },
67
+ };
68
+
69
+ const unavailableManagementSchema: AgentRuntimeManagementSchema = {
70
+ hostConfigFiles: [],
71
+ toolboxItems: [],
72
+ hookCommandTemplates: [],
73
+ providerConfigFormat: 'none',
74
+ mcpConfigFormat: 'none',
75
+ configArchives: false,
76
+ buildRestart: false,
77
+ };
78
+
79
+ export interface UnavailableRuntimeOptions {
80
+ provider: AgentProviderId;
81
+ reason: string;
82
+ }
83
+
84
+ export class UnavailableRuntimeAdapter extends EventEmitter implements AgentRuntime {
85
+ readonly provider: AgentProviderId;
86
+ readonly displayName: string;
87
+ readonly description: string;
88
+ readonly capabilities = unavailableCapabilities;
89
+ readonly managementSchema = unavailableManagementSchema;
90
+ readonly installation: AgentBackendInstallationDto;
91
+
92
+ private readonly status: AgentRuntimeStatus;
93
+
94
+ constructor(options: UnavailableRuntimeOptions) {
95
+ super();
96
+ const metadata = agentBackendMetadata[options.provider];
97
+ this.provider = options.provider;
98
+ this.displayName = metadata.displayName;
99
+ this.description = metadata.description;
100
+ this.installation = {
101
+ packageName: null,
102
+ installed: false,
103
+ installedVersion: null,
104
+ latestVersion: null,
105
+ installCommand: null,
106
+ updateCommand: null,
107
+ busy: false,
108
+ lastError: options.reason,
109
+ };
110
+ this.status = {
111
+ state: 'stopped',
112
+ transport: metadata.defaultTransport,
113
+ lastStartedAt: null,
114
+ lastError: options.reason,
115
+ restartCount: 0,
116
+ };
117
+ }
118
+
119
+ getStatus(): AgentRuntimeStatus {
120
+ return { ...this.status };
121
+ }
122
+
123
+ async start() {}
124
+
125
+ async stop() {}
126
+
127
+ async listModels() {
128
+ return [];
129
+ }
130
+
131
+ async listSessions() {
132
+ return [];
133
+ }
134
+
135
+ async listLoadedSessions() {
136
+ return [];
137
+ }
138
+
139
+ async readSession(
140
+ _providerSessionId: string,
141
+ _options?: ReadAgentSessionOptions,
142
+ ): Promise<AgentSessionDetail> {
143
+ throw this.unavailableError();
144
+ }
145
+
146
+ async startSession(_input: StartAgentSessionInput): Promise<StartAgentSessionResult> {
147
+ throw this.unavailableError();
148
+ }
149
+
150
+ async resumeSession(_input: ResumeAgentSessionInput): Promise<StartAgentSessionResult> {
151
+ throw this.unavailableError();
152
+ }
153
+
154
+ async startTurn(_input: StartAgentTurnInput): Promise<AgentTurn> {
155
+ throw this.unavailableError();
156
+ }
157
+
158
+ async interruptTurn(_input: InterruptAgentTurnInput): Promise<AgentTurn | null> {
159
+ throw this.unavailableError();
160
+ }
161
+
162
+ private unavailableError() {
163
+ return new AgentRuntimeError(
164
+ this.status.lastError ?? `${this.displayName} is not available.`,
165
+ this.provider,
166
+ 'provider_unavailable',
167
+ );
168
+ }
169
+ }
@@ -104,6 +104,40 @@ function readableToolName(toolName: string) {
104
104
  return toolName;
105
105
  }
106
106
 
107
+ function projectRelativePathLabel(value: string | null | undefined) {
108
+ const normalized = value?.trim();
109
+ if (!normalized) {
110
+ return null;
111
+ }
112
+
113
+ const slashNormalized = normalized.replace(/\\/g, '/');
114
+ if (!slashNormalized.startsWith('/')) {
115
+ return slashNormalized.replace(/^\.\//, '');
116
+ }
117
+
118
+ const markers = [
119
+ '/apps/',
120
+ '/packages/',
121
+ '/src/',
122
+ '/test/',
123
+ '/tests/',
124
+ '/docs/',
125
+ '/config/',
126
+ '/scripts/',
127
+ '/e2e/',
128
+ '/.agents/',
129
+ '/.codex/',
130
+ ];
131
+ for (const marker of markers) {
132
+ const markerIndex = slashNormalized.indexOf(marker);
133
+ if (markerIndex >= 0) {
134
+ return slashNormalized.slice(markerIndex + 1);
135
+ }
136
+ }
137
+
138
+ return slashNormalized;
139
+ }
140
+
107
141
  function commandFromInput(input: unknown) {
108
142
  if (!isRecord(input)) {
109
143
  return null;
@@ -115,11 +149,13 @@ function pathFromInput(input: unknown) {
115
149
  if (!isRecord(input)) {
116
150
  return null;
117
151
  }
118
- return (
119
- stringValue(input.file_path) ??
120
- stringValue(input.filePath) ??
121
- stringValue(input.path) ??
122
- stringValue(input.notebook_path)
152
+ return projectRelativePathLabel(
153
+ stringValue(input.relative_path) ??
154
+ stringValue(input.relativePath) ??
155
+ stringValue(input.file_path) ??
156
+ stringValue(input.filePath) ??
157
+ stringValue(input.path) ??
158
+ stringValue(input.notebook_path),
123
159
  );
124
160
  }
125
161
 
@@ -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());
@@ -1933,6 +2022,16 @@ describe('ClaudeRuntimeAdapter', () => {
1933
2022
  file_path: 'packages/claude/src/runtimeAdapter.ts',
1934
2023
  },
1935
2024
  },
2025
+ {
2026
+ type: 'tool_use',
2027
+ id: 'toolu_edit',
2028
+ name: 'Edit',
2029
+ input: {
2030
+ file_path: '/home/u/dev/remoteCodex/apps/supervisor-api/src/thread-service.ts',
2031
+ old_string: 'before',
2032
+ new_string: 'after',
2033
+ },
2034
+ },
1936
2035
  {
1937
2036
  type: 'tool_use',
1938
2037
  id: 'toolu_skill',
@@ -1980,6 +2079,11 @@ describe('ClaudeRuntimeAdapter', () => {
1980
2079
  tool_use_id: 'toolu_read',
1981
2080
  content: 'export class ClaudeRuntimeAdapter {}',
1982
2081
  },
2082
+ {
2083
+ type: 'tool_result',
2084
+ tool_use_id: 'toolu_edit',
2085
+ content: 'File updated.',
2086
+ },
1983
2087
  {
1984
2088
  type: 'tool_result',
1985
2089
  tool_use_id: 'toolu_skill',
@@ -2025,6 +2129,13 @@ describe('ClaudeRuntimeAdapter', () => {
2025
2129
  text: 'Read file: packages/claude/src/runtimeAdapter.ts',
2026
2130
  status: 'completed',
2027
2131
  }),
2132
+ expect.objectContaining({
2133
+ id: 'toolu_edit',
2134
+ kind: 'fileChange',
2135
+ text: 'apps/supervisor-api/src/thread-service.ts',
2136
+ previewText: 'Edit file: apps/supervisor-api/src/thread-service.ts',
2137
+ status: 'completed',
2138
+ }),
2028
2139
  expect.objectContaining({
2029
2140
  id: 'toolu_skill',
2030
2141
  kind: 'skillToolCall',