@walkhi/code-relax 0.1.0-beta.2 → 0.1.0-beta.20
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/README.md +55 -71
- package/dist/bin/codex-remote.mjs +150 -126
- package/dist/bin/manage-relay-admin.mjs +20 -0
- package/dist/bin/migrate-relay-db.mjs +107 -0
- package/dist/bin/self-relay-admin.mjs +8 -0
- package/dist/bin/self-relay-demo.mjs +2 -2
- package/dist/bin/self-relay-server.mjs +18 -10
- package/dist/shared/app-server-events.cjs +42 -15
- package/dist/shared/file-mentions.cjs +35 -0
- package/dist/shared/server-requests.cjs +86 -58
- package/dist/skills/code-relax/SKILL.md +7 -6
- package/dist/src/desktop-launcher.mjs +16 -21
- package/dist/src/file-upload-session.mjs +124 -0
- package/dist/src/lan-socket-server.mjs +52 -9
- package/dist/src/managed-app-server.mjs +44 -13
- package/dist/src/message-images.mjs +0 -18
- package/dist/src/onboarding.mjs +9 -11
- package/dist/src/platform/README.md +1 -1
- package/dist/src/platform/windows/background-process.mjs +1 -1
- package/dist/src/platform/windows/codex-runtime.mjs +251 -0
- package/dist/src/platform/windows/desktop-host.mjs +17 -3
- package/dist/src/platform/windows/desktop-info.ps1 +2 -4
- package/dist/src/platform/windows/desktop-runtime.ps1 +10 -0
- package/dist/src/platform/windows/desktop-shortcuts.ps1 +7 -14
- package/dist/src/platform/windows/launch-worker.mjs +42 -0
- package/dist/src/platform/windows/resident-start.js +20 -0
- package/dist/src/platform/windows/resident-startup.ps1 +76 -20
- package/dist/src/platform/windows/service-host.mjs +4 -16
- package/dist/src/platform/windows/start-hidden-console.ps1 +10 -5
- package/dist/src/platform/windows/stop-desktop.ps1 +7 -4
- package/dist/src/platform/windows/user-environment.mjs +1 -1
- package/dist/src/runtime-discovery.mjs +43 -0
- package/dist/src/self-relay/admin-cloud.mjs +101 -0
- package/dist/src/self-relay/admin-page.mjs +79 -0
- package/dist/src/self-relay/admin-server.mjs +66 -0
- package/dist/src/self-relay/admin-state.mjs +82 -19
- package/dist/src/self-relay/admin-style.mjs +9 -0
- package/dist/src/self-relay/admin-usage-page.mjs +28 -0
- package/dist/src/self-relay/connector.mjs +243 -30
- package/dist/src/self-relay/demo.mjs +3 -4
- package/dist/src/self-relay/email-accounts.mjs +141 -0
- package/dist/src/self-relay/lifecycle.mjs +99 -142
- package/dist/src/self-relay/mysql-state.mjs +104 -0
- package/dist/src/self-relay/p2p-probe.mjs +1 -1
- package/dist/src/self-relay/server.mjs +335 -59
- package/dist/src/self-relay/usage-diagnostics.mjs +46 -0
- package/dist/src/self-relay/usage-meter.mjs +125 -0
- package/dist/src/server.mjs +731 -1439
- package/dist/src/service-control.mjs +4 -4
- package/dist/src/service-doctor.mjs +27 -29
- package/dist/src/service-health.mjs +2 -2
- package/dist/src/service-install.mjs +1 -4
- package/dist/src/service-lifecycle.mjs +19 -19
- package/dist/src/shared-app-server.mjs +277 -270
- package/dist/src/shared-catalog.mjs +1 -11
- package/dist/src/shared-recovery.mjs +11 -9
- package/dist/src/shared-thread-stream.mjs +1 -1
- package/dist/src/skill-install.mjs +0 -13
- package/package.json +17 -18
- package/tools/postinstall.mjs +69 -15
- package/dist/src/app-server-client.mjs +0 -468
- package/dist/src/app-server-tasks.mjs +0 -358
- package/dist/src/debug-ui.mjs +0 -131
- package/dist/src/platform/windows/desktop-monitor.mjs +0 -34
- package/dist/src/platform/windows/desktop-shortcut-run.ps1 +0 -5
- package/dist/src/platform/windows/desktop-tools.mjs +0 -48
- package/dist/src/platform/windows/launch-worker.ps1 +0 -20
- package/dist/src/thread-catalog.mjs +0 -47
- package/dist/tools/find-desktop-pipe.mjs +0 -10
- package/dist/web/activity-view.js +0 -283
- package/dist/web/approval-ui.js +0 -188
- package/dist/web/capabilities.js +0 -57
- package/dist/web/chat-transport.js +0 -202
- package/dist/web/chat.css +0 -782
- package/dist/web/chat.js +0 -3830
- package/dist/web/client-platform.js +0 -11
- package/dist/web/community-view.js +0 -20
- package/dist/web/community.css +0 -77
- package/dist/web/community.html +0 -37
- package/dist/web/composer-controller.js +0 -101
- package/dist/web/conversation-controller.js +0 -99
- package/dist/web/disclosure-state-controller.js +0 -95
- package/dist/web/draft-controller.js +0 -103
- package/dist/web/harmony-platform.js +0 -52
- package/dist/web/highlight-powershell.min.js +0 -39
- package/dist/web/highlight.min.js +0 -1262
- package/dist/web/history-cache.js +0 -240
- package/dist/web/history-controller.js +0 -167
- package/dist/web/index.html +0 -325
- package/dist/web/lan-session.js +0 -122
- package/dist/web/link-action-controller.js +0 -212
- package/dist/web/message-send-controller.js +0 -177
- package/dist/web/message-view.js +0 -98
- package/dist/web/p2p-data-channel.js +0 -50
- package/dist/web/p2p-diagnostics.js +0 -28
- package/dist/web/p2p-probe.js +0 -123
- package/dist/web/page-resume.js +0 -28
- package/dist/web/pending-message-store.js +0 -108
- package/dist/web/queue-controller.js +0 -82
- package/dist/web/resources.json +0 -1
- package/dist/web/self-relay-session.js +0 -129
- package/dist/web/server-requests.js +0 -67
- package/dist/web/station-connection-controller.js +0 -75
- package/dist/web/task-list-view.js +0 -296
- package/dist/web/thread-attention-controller.js +0 -124
- package/dist/web/thread-context-controller.js +0 -30
- package/dist/web/thread-list-controller.js +0 -61
- package/dist/web/thread-list-sync.js +0 -86
- package/dist/web/thread-title-controller.js +0 -57
- package/dist/web/timeline-formatters.js +0 -249
- package/dist/web/timeline-reducer.js +0 -81
- package/dist/web/timeline-renderer.js +0 -161
- package/dist/web/timeline-scroll-controller.js +0 -50
- package/dist/web/timeline-sync.js +0 -67
- package/dist/web/usage-controller.js +0 -258
- package/dist/web/vendor/README.md +0 -14
- package/dist/web/vendor/highlight-powershell.min.js +0 -39
- package/dist/web/vendor/highlight.LICENSE.txt +0 -29
- package/dist/web/vendor/highlight.min.js +0 -1262
- package/dist/web/vendor/lucide.LICENSE.txt +0 -17
|
@@ -1,202 +0,0 @@
|
|
|
1
|
-
(function (root) {
|
|
2
|
-
const capabilities = root.CodexCapabilities;
|
|
3
|
-
const selfRelay = root.codexSelfRelayConfig;
|
|
4
|
-
const lanOrigin = selfRelay ? new URL(selfRelay.url).origin.replace(/^wss:/, 'https:').replace(/^ws:/, 'http:') : root.codexLanConfig?.address || root.location?.origin;
|
|
5
|
-
const stationScope = selfRelay
|
|
6
|
-
? JSON.stringify([selfRelay.url, selfRelay.room, selfRelay.clientId])
|
|
7
|
-
// workstationScope is the released native/Web wire field; stationScope is the domain name used here.
|
|
8
|
-
: root.codexLanConfig?.workstationScope || '';
|
|
9
|
-
|
|
10
|
-
class LanTransport extends (selfRelay ? root.CodexSelfRelaySession : root.CodexLanSession) {
|
|
11
|
-
constructor(token) { super(token); this.mode = root.codexLanConfig?.transportMode || 'lan-legacy'; }
|
|
12
|
-
connectionState() { return this.ready ? 'connected' : 'disconnected'; }
|
|
13
|
-
async api(path, options = {}) {
|
|
14
|
-
const body = await this.request(path, options);
|
|
15
|
-
if (path.startsWith('/api/health')) {
|
|
16
|
-
this.mode = body.transportMode || 'lan-legacy';
|
|
17
|
-
this.recoveryAvailable = body.sharedRecoveryAvailable === true;
|
|
18
|
-
this.execution = body.execution;
|
|
19
|
-
this.managedAppServer = body.managedAppServer;
|
|
20
|
-
this.desktop = body.desktop;
|
|
21
|
-
this.desktopRestartRecommended = body.desktopRestartRecommended === true;
|
|
22
|
-
}
|
|
23
|
-
return body;
|
|
24
|
-
}
|
|
25
|
-
events(thread, sync, known) {
|
|
26
|
-
const query = new URLSearchParams();
|
|
27
|
-
if (thread.hostId) query.set('hostId', thread.hostId);
|
|
28
|
-
if (sync?.id && sync.epoch && Number.isSafeInteger(sync.seq)) {
|
|
29
|
-
query.set('syncId', sync.id); query.set('syncEpoch', sync.epoch); query.set('afterSeq', String(sync.seq));
|
|
30
|
-
}
|
|
31
|
-
const knownUpdatedAt = Number(known?.thread?.updatedAt) || 0;
|
|
32
|
-
const knownTurn = known?.turns?.at(-1);
|
|
33
|
-
if (knownUpdatedAt > 0 && knownTurn?.id) {
|
|
34
|
-
query.set('knownUpdatedAt', knownUpdatedAt.toString());
|
|
35
|
-
query.set('knownTurnId', knownTurn.id);
|
|
36
|
-
if (knownTurn.status) query.set('knownTurnStatus', knownTurn.status);
|
|
37
|
-
}
|
|
38
|
-
return this.subscribe(`/api/threads/${encodeURIComponent(thread.id)}/events?${query}`);
|
|
39
|
-
}
|
|
40
|
-
async cacheScope() {
|
|
41
|
-
if (stationScope) return `workstation-v1:${stationScope}`;
|
|
42
|
-
if (!selfRelay) return root.codexLanConfig?.cacheScope ? `${root.codexLanConfig.cacheScope}:${this.mode}` : null;
|
|
43
|
-
const identity = [selfRelay.url, selfRelay.room, selfRelay.clientId, selfRelay.revision, selfRelay.credential].join('\0');
|
|
44
|
-
const bytes = await crypto.subtle.digest('SHA-256', new TextEncoder().encode(identity));
|
|
45
|
-
return `self-relay-v1:${[...new Uint8Array(bytes)].map(byte => byte.toString(16).padStart(2, '0')).join('')}`;
|
|
46
|
-
}
|
|
47
|
-
async cacheHash(value) {
|
|
48
|
-
if (!selfRelay) return [...crypto.getRandomValues(new Uint8Array(24))].map(byte => byte.toString(16).padStart(2, '0')).join('');
|
|
49
|
-
const bytes = await crypto.subtle.digest('SHA-256', new TextEncoder().encode(value));
|
|
50
|
-
return [...new Uint8Array(bytes)].map(byte => byte.toString(16).padStart(2, '0')).join('');
|
|
51
|
-
}
|
|
52
|
-
async readCached(id, thread) {
|
|
53
|
-
const scope = await this.cacheScope();
|
|
54
|
-
return scope ? root.codexHistoryCache?.get(scope, (stationScope || selfRelay) ? id : JSON.stringify([thread?.hostId || 'local', id])) : null;
|
|
55
|
-
}
|
|
56
|
-
async readLastCached() {
|
|
57
|
-
const scope = await this.cacheScope();
|
|
58
|
-
return scope ? root.codexHistoryCache?.latest(scope) : null;
|
|
59
|
-
}
|
|
60
|
-
async saveCached(data) {
|
|
61
|
-
const scope = await this.cacheScope();
|
|
62
|
-
if (scope) return root.codexHistoryCache?.save(scope, data, value => this.cacheHash(value), (stationScope || selfRelay) ? data.thread.id : JSON.stringify([data.thread.hostId || 'local', data.thread.id]));
|
|
63
|
-
}
|
|
64
|
-
async addImage(blob) {
|
|
65
|
-
if (!['image/jpeg', 'image/png', 'image/webp'].includes(blob.type) || !blob.size || blob.size > 8 * 1024 * 1024) throw new Error('请选择不超过 8 MiB 的 JPEG、PNG 或 WebP 图片');
|
|
66
|
-
const bytes = new Uint8Array(await blob.arrayBuffer()); let binary = '';
|
|
67
|
-
for (let i = 0; i < bytes.length; i += 16384) binary += String.fromCharCode(...bytes.subarray(i, i + 16384));
|
|
68
|
-
const url = `data:${blob.type};base64,${btoa(binary)}`;
|
|
69
|
-
return { id: url, url, thumbnailUrl: url };
|
|
70
|
-
}
|
|
71
|
-
assetUrl(value) {
|
|
72
|
-
if (!value) return '';
|
|
73
|
-
if (/^data:image\/(?:png|jpeg|webp|gif|bmp);base64,/i.test(value)) return value;
|
|
74
|
-
if (selfRelay) return '';
|
|
75
|
-
const url = new URL(value, lanOrigin);
|
|
76
|
-
if (url.origin !== new URL(lanOrigin).origin) return '';
|
|
77
|
-
if (this.token) url.searchParams.set('token', this.token);
|
|
78
|
-
return url.href;
|
|
79
|
-
}
|
|
80
|
-
async readImage(threadId, id, variant = 'original', recoveryToken = '', recoveryTurnId = '') {
|
|
81
|
-
if (!/^[a-f0-9]{64}$/.test(id)) throw new Error('无效的图片标识');
|
|
82
|
-
const query = new URLSearchParams();
|
|
83
|
-
if (variant === 'thumbnail') query.set('variant', 'thumbnail');
|
|
84
|
-
if (recoveryToken) query.set('recovery', recoveryToken);
|
|
85
|
-
if (threadId) query.set('threadId', threadId);
|
|
86
|
-
if (recoveryTurnId) query.set('turnId', recoveryTurnId);
|
|
87
|
-
return (await this.api(`/api/images/${id}${query.size ? `?${query}` : ''}`)).url;
|
|
88
|
-
}
|
|
89
|
-
async readFile(_threadId, id) {
|
|
90
|
-
if (!/^[a-f0-9]{64}$/.test(id)) throw new Error('无效的文件标识');
|
|
91
|
-
return this.api(`/api/files/${id}`);
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
// Relay owns login, device pairing, reconnection and phone cache.
|
|
96
|
-
// The LAN adapter owns the authenticated WebSocket; both expose the same UI operations.
|
|
97
|
-
root.createChatTransport = function ({ token, currentThread, relay = root.codexTransport }) {
|
|
98
|
-
const adapter = relay || new LanTransport(token);
|
|
99
|
-
const modeFor = thread => {
|
|
100
|
-
if (relay) return 'relay';
|
|
101
|
-
if (thread?.transport === 'app-server') return 'app-server';
|
|
102
|
-
if (thread?.hostId && thread.hostId !== 'local') return 'lan-legacy';
|
|
103
|
-
return adapter.mode;
|
|
104
|
-
};
|
|
105
|
-
const mode = () => modeFor(currentThread());
|
|
106
|
-
const serviceAdvisory = () => {
|
|
107
|
-
if (relay) return null;
|
|
108
|
-
const managed = adapter.managedAppServer;
|
|
109
|
-
if (managed?.state === 'restarting' || managed?.restart?.status === 'running') return {
|
|
110
|
-
kind: 'restarting', title: 'Codex 内核正在重启',
|
|
111
|
-
detail: '工作站连接保持在线;任务操作暂不可用,恢复后不会自动重发。'
|
|
112
|
-
};
|
|
113
|
-
if (managed?.ready && managed.updatePending) return {
|
|
114
|
-
kind: 'update-pending', title: 'Codex 内核有更新',
|
|
115
|
-
detail: '当前任务不受影响;点击查看状态,并选择何时重启更新。'
|
|
116
|
-
};
|
|
117
|
-
if (adapter.execution && (!adapter.execution.ready || adapter.execution.state === 'recovering')) return {
|
|
118
|
-
kind: 'execution-unavailable',
|
|
119
|
-
title: adapter.execution.state === 'recovering' ? 'Codex 内核正在恢复' : 'Codex 内核暂不可用',
|
|
120
|
-
detail: '工作站连接正常;点击查看当前状况、影响和可执行操作。'
|
|
121
|
-
};
|
|
122
|
-
if (adapter.mode === 'lan-legacy') return {
|
|
123
|
-
kind: 'basic', title: '当前为基础控制',
|
|
124
|
-
detail: '部分实时控制不可用;点击查看影响和恢复完整控制。'
|
|
125
|
-
};
|
|
126
|
-
return null;
|
|
127
|
-
};
|
|
128
|
-
return {
|
|
129
|
-
mode,
|
|
130
|
-
transportMode: () => relay ? 'relay' : adapter.mode,
|
|
131
|
-
recoverySupported: () => !relay && adapter.recoveryAvailable,
|
|
132
|
-
recoveryEvents: () => {
|
|
133
|
-
if (relay) throw new Error('请通过工作站管理连接查看切换进度');
|
|
134
|
-
return adapter.subscribe('/api/shared-recovery/events');
|
|
135
|
-
},
|
|
136
|
-
recoveryStatus: () => {
|
|
137
|
-
if (relay) throw new Error('OpenAI 官方中继不支持从手机启用完整控制');
|
|
138
|
-
return adapter.api('/api/shared-recovery');
|
|
139
|
-
},
|
|
140
|
-
recoverShared: operationId => {
|
|
141
|
-
if (relay) throw new Error('请通过局域网或Code Relax 中继切换工作站执行模式');
|
|
142
|
-
if (!adapter.recoveryAvailable) throw new Error('工作站端尚未支持恢复功能,请更新 Bridge');
|
|
143
|
-
return adapter.api('/api/shared-recovery', { method: 'POST', body: { confirmed: true, operationId } });
|
|
144
|
-
},
|
|
145
|
-
sharedServiceNotice: serviceAdvisory,
|
|
146
|
-
connectionLabel: (compact = false) => {
|
|
147
|
-
if (relay) return compact ? 'OpenAI中继' : 'OpenAI 中继';
|
|
148
|
-
const network = selfRelay ? compact ? 'CodeRelax中继' : 'Code Relax 中继' : '局域网';
|
|
149
|
-
return serviceAdvisory() ? network : `${network} · ${adapter.mode === 'lan-shared' ? '完整控制' : '基础控制'}`;
|
|
150
|
-
},
|
|
151
|
-
draftScope: () => relay ? adapter.draftScope() : stationScope || (selfRelay ? `${lanOrigin}/${selfRelay.room}` : lanOrigin),
|
|
152
|
-
capabilities: () => capabilities.describe(mode()),
|
|
153
|
-
has: name => (name === 'historyCache' && Boolean(selfRelay || root.codexLanConfig?.cacheScope)) || capabilities.has(mode(), name),
|
|
154
|
-
supports: (name, thread) => capabilities.has(modeFor(thread), name),
|
|
155
|
-
actionState: (action, context) => capabilities.actionState(mode(), action, {
|
|
156
|
-
...context, writable: context?.writable !== false && (relay || adapter.execution?.canWrite !== false)
|
|
157
|
-
}),
|
|
158
|
-
api(path, options) {
|
|
159
|
-
if (!relay && /^\/api\/(threads\/|models)/.test(path)) {
|
|
160
|
-
const hostId = currentThread()?.hostId;
|
|
161
|
-
if (hostId) {
|
|
162
|
-
const url = new URL(path, lanOrigin);
|
|
163
|
-
if (!url.searchParams.has('hostId')) url.searchParams.set('hostId', hostId);
|
|
164
|
-
path = url.pathname + url.search;
|
|
165
|
-
}
|
|
166
|
-
}
|
|
167
|
-
return adapter.api(path, options);
|
|
168
|
-
},
|
|
169
|
-
events: (thread, sync, known) => relay ? adapter.events(thread.id) : adapter.events(thread, sync, known),
|
|
170
|
-
respondApproval: (thread, request, result) => {
|
|
171
|
-
const body = { id: request.id, epoch: request.epoch, result };
|
|
172
|
-
if (relay) return adapter.respondApproval(thread.id, body);
|
|
173
|
-
const query = new URLSearchParams({ hostId: thread.hostId || 'local' });
|
|
174
|
-
return adapter.api(`/api/threads/${encodeURIComponent(thread.id)}/approvals?${query}`, { method: 'POST', body });
|
|
175
|
-
},
|
|
176
|
-
addImage: blob => adapter.addImage(blob),
|
|
177
|
-
removeImage: id => adapter.removeImage?.(id),
|
|
178
|
-
clearImages: () => adapter.clearImages?.(),
|
|
179
|
-
readImage: (id, path, variant, recoveryToken, recoveryTurnId) => adapter.readImage(id, path, variant, recoveryToken, recoveryTurnId),
|
|
180
|
-
readFile: (id, path) => adapter.readFile(id, path),
|
|
181
|
-
readCached: async (id, thread) => adapter.readCached?.(id, thread),
|
|
182
|
-
readLastCached: async () => adapter.readLastCached?.(),
|
|
183
|
-
saveCached: async timeline => adapter.saveCached?.(timeline),
|
|
184
|
-
diagnostics: () => adapter.diagnostics?.(),
|
|
185
|
-
pause: async () => adapter.pause?.(),
|
|
186
|
-
resume: async () => adapter.resume?.(),
|
|
187
|
-
checkConnection: () => relay ? adapter.checkConnection() : adapter.api('/api/health', { timeoutMs: 5000 }),
|
|
188
|
-
connectionState: () => adapter.connectionState?.(),
|
|
189
|
-
onConnectionChange: callback => { if (!relay) adapter.onConnectionChange = callback; },
|
|
190
|
-
usageEvents: () => {
|
|
191
|
-
if (relay) return adapter.usageEvents();
|
|
192
|
-
if (adapter.mode !== 'lan-shared') return null;
|
|
193
|
-
return adapter.subscribe('/api/usage-events');
|
|
194
|
-
},
|
|
195
|
-
assetUrl(value) {
|
|
196
|
-
if (!relay) return adapter.assetUrl(value);
|
|
197
|
-
if (/^data:image\/(?:png|jpeg|webp|gif);base64,/i.test(value) || /^blob:/i.test(value)) return value;
|
|
198
|
-
const url = new URL(value, location.origin); return url.protocol === 'https:' ? url.href : '';
|
|
199
|
-
},
|
|
200
|
-
};
|
|
201
|
-
};
|
|
202
|
-
})(globalThis);
|