remote-codex 0.11.2 → 0.11.3
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/apps/relay-server/dist/index.d.ts +2 -0
- package/apps/relay-server/dist/index.js +1221 -0
- package/apps/supervisor-api/dist/index.js +610 -66
- package/apps/supervisor-web/dist/assets/index-CBIze1VS.css +1 -0
- package/apps/supervisor-web/dist/assets/index-YpGAPjED.js +4 -0
- package/apps/supervisor-web/dist/assets/{thread-ui-CDk3ExRH.js → thread-ui-CF80LEEN.js} +126 -29
- package/apps/supervisor-web/dist/assets/{ui-vendor-CgOZX1B8.js → ui-vendor-CW6egZBG.js} +83 -78
- package/apps/supervisor-web/dist/index.html +4 -4
- package/bin/remote-codex.mjs +73 -16
- package/package.json +2 -1
- package/packages/shared/src/index.ts +154 -0
- package/apps/supervisor-web/dist/assets/index-CbDzXN9T.css +0 -1
- package/apps/supervisor-web/dist/assets/index-DQpHiQXN.js +0 -4
|
@@ -4,17 +4,17 @@
|
|
|
4
4
|
<meta charset="UTF-8" />
|
|
5
5
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
6
6
|
<title>Remote Codex Supervisor</title>
|
|
7
|
-
<script type="module" crossorigin src="/assets/index-
|
|
7
|
+
<script type="module" crossorigin src="/assets/index-YpGAPjED.js"></script>
|
|
8
8
|
<link rel="modulepreload" crossorigin href="/assets/react-vendor-o1Xrx7m4.js">
|
|
9
|
-
<link rel="modulepreload" crossorigin href="/assets/ui-vendor-
|
|
9
|
+
<link rel="modulepreload" crossorigin href="/assets/ui-vendor-CW6egZBG.js">
|
|
10
10
|
<link rel="modulepreload" crossorigin href="/assets/terminal-vendor-CLGgN91S.js">
|
|
11
11
|
<link rel="modulepreload" crossorigin href="/assets/graph-vendor-CGzY-MFv.js">
|
|
12
12
|
<link rel="modulepreload" crossorigin href="/assets/markdown-vendor-hBDTCSB-.js">
|
|
13
|
-
<link rel="modulepreload" crossorigin href="/assets/thread-ui-
|
|
13
|
+
<link rel="modulepreload" crossorigin href="/assets/thread-ui-CF80LEEN.js">
|
|
14
14
|
<link rel="stylesheet" crossorigin href="/assets/terminal-vendor-Beg8tuEN.css">
|
|
15
15
|
<link rel="stylesheet" crossorigin href="/assets/graph-vendor-C5ap-Sga.css">
|
|
16
16
|
<link rel="stylesheet" crossorigin href="/assets/thread-ui-BEieA99i.css">
|
|
17
|
-
<link rel="stylesheet" crossorigin href="/assets/index-
|
|
17
|
+
<link rel="stylesheet" crossorigin href="/assets/index-CBIze1VS.css">
|
|
18
18
|
</head>
|
|
19
19
|
<body class="bg-stone-950">
|
|
20
20
|
<div id="root"></div>
|
package/bin/remote-codex.mjs
CHANGED
|
@@ -9,6 +9,8 @@ const binDir = path.dirname(fileURLToPath(import.meta.url));
|
|
|
9
9
|
const packageRoot = path.resolve(binDir, '..');
|
|
10
10
|
const packageJsonPath = path.join(packageRoot, 'package.json');
|
|
11
11
|
const serviceManagerPath = path.join(packageRoot, 'scripts', 'service-manager.mjs');
|
|
12
|
+
const relayDistEntry = path.join(packageRoot, 'apps', 'relay-server', 'dist', 'index.js');
|
|
13
|
+
const relaySourceEntry = path.join(packageRoot, 'apps', 'relay-server', 'src', 'index.ts');
|
|
12
14
|
const sourceCheckout =
|
|
13
15
|
fs.existsSync(path.join(packageRoot, 'pnpm-workspace.yaml')) &&
|
|
14
16
|
fs.existsSync(path.join(packageRoot, 'scripts', 'service-restart.mjs'));
|
|
@@ -33,30 +35,74 @@ if (command === 'version') {
|
|
|
33
35
|
process.exit(0);
|
|
34
36
|
}
|
|
35
37
|
|
|
36
|
-
if (
|
|
38
|
+
if (command === 'relay') {
|
|
39
|
+
runRelayServer();
|
|
40
|
+
} else if (!['start', 'stop', 'status'].includes(command)) {
|
|
37
41
|
printHelp();
|
|
38
42
|
process.exit(command ? 1 : 0);
|
|
43
|
+
} else {
|
|
44
|
+
const child = spawn(process.execPath, [serviceManagerPath, command], {
|
|
45
|
+
cwd: packageRoot,
|
|
46
|
+
env: process.env,
|
|
47
|
+
stdio: 'inherit',
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
child.on('exit', (code, signal) => {
|
|
51
|
+
if (signal) {
|
|
52
|
+
process.kill(process.pid, signal);
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
process.exit(code ?? 1);
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
child.on('error', (error) => {
|
|
60
|
+
console.error(`Failed to run remote-codex ${command}: ${error.message}`);
|
|
61
|
+
process.exit(1);
|
|
62
|
+
});
|
|
39
63
|
}
|
|
40
64
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
});
|
|
65
|
+
function runRelayServer() {
|
|
66
|
+
const relayEntry = fs.existsSync(relayDistEntry) ? relayDistEntry : relaySourceEntry;
|
|
67
|
+
let commandToRun = process.execPath;
|
|
68
|
+
let args = [relayEntry];
|
|
46
69
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
70
|
+
if (!fs.existsSync(relayEntry)) {
|
|
71
|
+
console.error('Relay server build artifacts are missing. Run `pnpm build` before using `remote-codex relay`.');
|
|
72
|
+
console.error(`Missing: ${path.relative(packageRoot, relayDistEntry)}`);
|
|
73
|
+
process.exit(1);
|
|
51
74
|
}
|
|
52
75
|
|
|
53
|
-
|
|
54
|
-
|
|
76
|
+
if (relayEntry === relaySourceEntry) {
|
|
77
|
+
const tsxEntry = path.join(packageRoot, 'node_modules', 'tsx', 'dist', 'cli.mjs');
|
|
78
|
+
if (!fs.existsSync(tsxEntry)) {
|
|
79
|
+
console.error('Relay server build artifacts are missing and tsx is not installed for source execution.');
|
|
80
|
+
console.error('Run `pnpm build` or install dependencies with `pnpm install`.');
|
|
81
|
+
process.exit(1);
|
|
82
|
+
}
|
|
83
|
+
args = [tsxEntry, relaySourceEntry];
|
|
84
|
+
}
|
|
55
85
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
86
|
+
const relay = spawn(commandToRun, args, {
|
|
87
|
+
cwd: packageRoot,
|
|
88
|
+
env: process.env,
|
|
89
|
+
stdio: 'inherit',
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
relay.on('exit', (code, signal) => {
|
|
93
|
+
if (signal) {
|
|
94
|
+
process.kill(process.pid, signal);
|
|
95
|
+
return;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
process.exit(code ?? 1);
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
relay.on('error', (error) => {
|
|
102
|
+
console.error(`Failed to run remote-codex relay: ${error.message}`);
|
|
103
|
+
process.exit(1);
|
|
104
|
+
});
|
|
105
|
+
}
|
|
60
106
|
|
|
61
107
|
function normalizeCommand(value) {
|
|
62
108
|
if (!value || value === '-h' || value === '--help') {
|
|
@@ -86,6 +132,7 @@ Usage:
|
|
|
86
132
|
remote-codex start
|
|
87
133
|
remote-codex status
|
|
88
134
|
remote-codex stop
|
|
135
|
+
remote-codex relay
|
|
89
136
|
|
|
90
137
|
Environment:
|
|
91
138
|
SERVICE_HOST Web listen host, default 127.0.0.1
|
|
@@ -93,5 +140,15 @@ Environment:
|
|
|
93
140
|
SERVICE_API_HOST API listen host, default 127.0.0.1
|
|
94
141
|
SERVICE_API_PORT API listen port, default ${defaultApiPort}
|
|
95
142
|
REMOTE_CODEX_SERVICE_DIR Service state and log directory, default ~/.remote-codex/service
|
|
143
|
+
|
|
144
|
+
Relay:
|
|
145
|
+
REMOTE_CODEX_RELAY_SUPERVISOR_TOKEN Legacy bootstrap token for supervisor tunnels
|
|
146
|
+
REMOTE_CODEX_ADMIN_USERNAME Relay admin username
|
|
147
|
+
REMOTE_CODEX_ADMIN_PASSWORD Relay admin password
|
|
148
|
+
REMOTE_CODEX_RELAY_DATA_DIR Relay user/device store, default .local/relay-server
|
|
149
|
+
REMOTE_CODEX_RELAY_WEB_DIST_DIR Web dist override, defaults to packaged supervisor-web/dist
|
|
150
|
+
REMOTE_CODEX_RELAY_REGISTRATION_ENABLED true/false, default true
|
|
151
|
+
HOST Relay listen host, default 0.0.0.0
|
|
152
|
+
PORT Relay listen port, default 8788
|
|
96
153
|
`);
|
|
97
154
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "remote-codex",
|
|
3
|
-
"version": "0.11.
|
|
3
|
+
"version": "0.11.3",
|
|
4
4
|
"description": "Local web supervisor for Codex workspaces and threads.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -12,6 +12,7 @@
|
|
|
12
12
|
"scripts/service-manager.mjs",
|
|
13
13
|
"scripts/run-web-service.mjs",
|
|
14
14
|
"apps/supervisor-api/dist/",
|
|
15
|
+
"apps/relay-server/dist/",
|
|
15
16
|
"apps/supervisor-web/dist/",
|
|
16
17
|
"config/codex-model-pricing.json",
|
|
17
18
|
"packages/agent-runtime/src/",
|
|
@@ -16,6 +16,7 @@ export type {
|
|
|
16
16
|
|
|
17
17
|
export type ApiErrorCode =
|
|
18
18
|
| 'bad_request'
|
|
19
|
+
| 'unauthorized'
|
|
19
20
|
| 'not_found'
|
|
20
21
|
| 'conflict'
|
|
21
22
|
| 'provider_goal_error'
|
|
@@ -53,12 +54,165 @@ export function truncateAutoThreadTitle(value: string) {
|
|
|
53
54
|
export interface RuntimeConfigDto {
|
|
54
55
|
appName: string;
|
|
55
56
|
appVersion: string;
|
|
57
|
+
mode: 'local' | 'server' | 'relay';
|
|
56
58
|
host: string;
|
|
57
59
|
port: number;
|
|
58
60
|
workspaceRoot: string;
|
|
59
61
|
environment: string;
|
|
60
62
|
}
|
|
61
63
|
|
|
64
|
+
export interface AuthSessionDto {
|
|
65
|
+
authenticated: boolean;
|
|
66
|
+
username: string | null;
|
|
67
|
+
expiresAt: string | null;
|
|
68
|
+
mode: 'local' | 'server' | 'relay';
|
|
69
|
+
authRequired: boolean;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
export interface AuthLoginResultDto {
|
|
73
|
+
token: string | null;
|
|
74
|
+
session: AuthSessionDto;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
export interface RelayHealthDto {
|
|
78
|
+
status: 'ok';
|
|
79
|
+
supervisorConnected: boolean;
|
|
80
|
+
supervisorConnectedAt: string | null;
|
|
81
|
+
lastSupervisorHeartbeatAt: string | null;
|
|
82
|
+
supervisorCount?: number;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
export type RelayUserRoleDto = 'admin' | 'user';
|
|
86
|
+
|
|
87
|
+
export interface RelayUserDto {
|
|
88
|
+
id: string;
|
|
89
|
+
email: string;
|
|
90
|
+
username: string;
|
|
91
|
+
role: RelayUserRoleDto;
|
|
92
|
+
enabled: boolean;
|
|
93
|
+
createdAt: string;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
export interface RelayDeviceDto {
|
|
97
|
+
id: string;
|
|
98
|
+
ownerUserId: string;
|
|
99
|
+
name: string;
|
|
100
|
+
tokenPreview: string;
|
|
101
|
+
connected: boolean;
|
|
102
|
+
connectedAt: string | null;
|
|
103
|
+
lastHeartbeatAt: string | null;
|
|
104
|
+
createdAt: string;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
export interface RelaySessionShareDto {
|
|
108
|
+
id: string;
|
|
109
|
+
ownerUserId: string;
|
|
110
|
+
ownerUsername: string;
|
|
111
|
+
targetUsername: string;
|
|
112
|
+
targetUserId: string;
|
|
113
|
+
deviceId: string;
|
|
114
|
+
deviceName: string;
|
|
115
|
+
threadId: string;
|
|
116
|
+
label: string | null;
|
|
117
|
+
createdAt: string;
|
|
118
|
+
revokedAt: string | null;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
export interface RelaySessionDto {
|
|
122
|
+
authenticated: boolean;
|
|
123
|
+
user: RelayUserDto | null;
|
|
124
|
+
registrationEnabled: boolean;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
export interface RelayLoginResultDto {
|
|
128
|
+
token: string;
|
|
129
|
+
session: RelaySessionDto;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
export interface RelayRegisterResultDto {
|
|
133
|
+
token: string;
|
|
134
|
+
session: RelaySessionDto;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
export interface RelayCreateDeviceResultDto {
|
|
138
|
+
device: RelayDeviceDto;
|
|
139
|
+
token: string;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
export interface RelayPortalSummaryDto {
|
|
143
|
+
user: RelayUserDto;
|
|
144
|
+
devices: RelayDeviceDto[];
|
|
145
|
+
sharedWithMe: RelaySessionShareDto[];
|
|
146
|
+
sharedByMe: RelaySessionShareDto[];
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
export interface RelayAdminSummaryDto {
|
|
150
|
+
users: RelayUserDto[];
|
|
151
|
+
devices: RelayDeviceDto[];
|
|
152
|
+
registrationEnabled: boolean;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
export type RelaySupervisorEnvelope =
|
|
156
|
+
| {
|
|
157
|
+
type: 'relay.connected';
|
|
158
|
+
timestamp: string;
|
|
159
|
+
deviceId?: string;
|
|
160
|
+
}
|
|
161
|
+
| {
|
|
162
|
+
type: 'relay.heartbeat';
|
|
163
|
+
timestamp: string;
|
|
164
|
+
deviceId?: string;
|
|
165
|
+
}
|
|
166
|
+
| {
|
|
167
|
+
type: 'relay.request';
|
|
168
|
+
timestamp: string;
|
|
169
|
+
requestId: string;
|
|
170
|
+
deviceId?: string;
|
|
171
|
+
payload: RelayHttpRequestPayload;
|
|
172
|
+
}
|
|
173
|
+
| {
|
|
174
|
+
type: 'relay.response';
|
|
175
|
+
timestamp: string;
|
|
176
|
+
requestId: string;
|
|
177
|
+
deviceId?: string;
|
|
178
|
+
payload: RelayHttpResponsePayload;
|
|
179
|
+
}
|
|
180
|
+
| {
|
|
181
|
+
type: 'relay.client.connected';
|
|
182
|
+
timestamp: string;
|
|
183
|
+
clientId: string;
|
|
184
|
+
}
|
|
185
|
+
| {
|
|
186
|
+
type: 'relay.client.disconnected';
|
|
187
|
+
timestamp: string;
|
|
188
|
+
clientId: string;
|
|
189
|
+
}
|
|
190
|
+
| {
|
|
191
|
+
type: 'relay.client.message';
|
|
192
|
+
timestamp: string;
|
|
193
|
+
clientId: string;
|
|
194
|
+
payload: SupervisorSocketClientEnvelope;
|
|
195
|
+
}
|
|
196
|
+
| {
|
|
197
|
+
type: 'relay.server.message';
|
|
198
|
+
timestamp: string;
|
|
199
|
+
clientId: string;
|
|
200
|
+
payload: SupervisorSocketServerEnvelope;
|
|
201
|
+
};
|
|
202
|
+
|
|
203
|
+
export interface RelayHttpRequestPayload {
|
|
204
|
+
method: string;
|
|
205
|
+
path: string;
|
|
206
|
+
headers: Record<string, string>;
|
|
207
|
+
body: string | null;
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
export interface RelayHttpResponsePayload {
|
|
211
|
+
statusCode: number;
|
|
212
|
+
headers: Record<string, string>;
|
|
213
|
+
body: string;
|
|
214
|
+
}
|
|
215
|
+
|
|
62
216
|
export interface AgentRuntimeStatusDto {
|
|
63
217
|
state: 'starting' | 'ready' | 'degraded' | 'stopped' | 'failed';
|
|
64
218
|
transport: 'stdio' | 'sdk' | 'none';
|