@jingyi0605/codingns 0.1.0 → 0.1.2
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 +14 -0
- package/dist/public/assets/TerminalPage-Dr7knYq2.js +55 -0
- package/dist/public/assets/index-BpUi6zoT.js +108 -0
- package/dist/public/assets/index-NMtdQNda.css +1 -0
- package/dist/public/index.html +2 -2
- package/dist/server/config/env.js +72 -7
- package/dist/server/config/env.js.map +1 -1
- package/dist/server/config/opencode-base-url-resolver.d.ts +13 -8
- package/dist/server/config/opencode-base-url-resolver.js +117 -147
- package/dist/server/config/opencode-base-url-resolver.js.map +1 -1
- package/dist/server/config/opencode-system-probe-helper-client.d.ts +18 -0
- package/dist/server/config/opencode-system-probe-helper-client.js +127 -0
- package/dist/server/config/opencode-system-probe-helper-client.js.map +1 -0
- package/dist/server/config/opencode-system-probe-helper-process.d.ts +1 -0
- package/dist/server/config/opencode-system-probe-helper-process.js +208 -0
- package/dist/server/config/opencode-system-probe-helper-process.js.map +1 -0
- package/dist/server/modules/git/git-command-helper-client.d.ts +25 -0
- package/dist/server/modules/git/git-command-helper-client.js +143 -0
- package/dist/server/modules/git/git-command-helper-client.js.map +1 -0
- package/dist/server/modules/git/git-command-helper-process.d.ts +1 -0
- package/dist/server/modules/git/git-command-helper-process.js +237 -0
- package/dist/server/modules/git/git-command-helper-process.js.map +1 -0
- package/dist/server/modules/git/git-command-runner.d.ts +8 -0
- package/dist/server/modules/git/git-command-runner.js +77 -6
- package/dist/server/modules/git/git-command-runner.js.map +1 -1
- package/dist/server/modules/git/git-controller.d.ts +4 -0
- package/dist/server/modules/git/git-controller.js +4 -1
- package/dist/server/modules/git/git-controller.js.map +1 -1
- package/dist/server/modules/git/git-read-service.d.ts +2 -1
- package/dist/server/modules/git/git-read-service.js +30 -0
- package/dist/server/modules/git/git-read-service.js.map +1 -1
- package/dist/server/modules/git/git-write-service.d.ts +1 -1
- package/dist/server/modules/git/git-write-service.js +8 -7
- package/dist/server/modules/git/git-write-service.js.map +1 -1
- package/dist/server/modules/git/types.d.ts +5 -0
- package/dist/server/modules/preferences/common.d.ts +2 -0
- package/dist/server/modules/preferences/common.js +13 -0
- package/dist/server/modules/preferences/common.js.map +1 -0
- package/dist/server/modules/preferences/profile-controller.d.ts +11 -0
- package/dist/server/modules/preferences/profile-controller.js +14 -0
- package/dist/server/modules/preferences/profile-controller.js.map +1 -0
- package/dist/server/modules/preferences/profile-service.d.ts +17 -0
- package/dist/server/modules/preferences/profile-service.js +213 -0
- package/dist/server/modules/preferences/profile-service.js.map +1 -0
- package/dist/server/modules/preferences/quick-phrase-controller.js +2 -12
- package/dist/server/modules/preferences/quick-phrase-controller.js.map +1 -1
- package/dist/server/modules/provider/codex-model-options.js +26 -165
- package/dist/server/modules/provider/codex-model-options.js.map +1 -1
- package/dist/server/modules/provider/opencode-model-options.js +6 -71
- package/dist/server/modules/provider/opencode-model-options.js.map +1 -1
- package/dist/server/modules/provider/provider-controller.d.ts +2 -0
- package/dist/server/modules/provider/provider-controller.js +21 -1
- package/dist/server/modules/provider/provider-controller.js.map +1 -1
- package/dist/server/modules/provider/provider-discovery-helper-client.d.ts +25 -0
- package/dist/server/modules/provider/provider-discovery-helper-client.js +114 -0
- package/dist/server/modules/provider/provider-discovery-helper-client.js.map +1 -0
- package/dist/server/modules/provider/provider-discovery-helper-process.d.ts +1 -0
- package/dist/server/modules/provider/provider-discovery-helper-process.js +296 -0
- package/dist/server/modules/provider/provider-discovery-helper-process.js.map +1 -0
- package/dist/server/modules/sessions/claude-runtime-helper-client.d.ts +28 -0
- package/dist/server/modules/sessions/claude-runtime-helper-client.js +221 -0
- package/dist/server/modules/sessions/claude-runtime-helper-client.js.map +1 -0
- package/dist/server/modules/sessions/claude-runtime-helper-process.d.ts +1 -0
- package/dist/server/modules/sessions/claude-runtime-helper-process.js +146 -0
- package/dist/server/modules/sessions/claude-runtime-helper-process.js.map +1 -0
- package/dist/server/modules/sessions/codex-app-server-helper-client.d.ts +16 -0
- package/dist/server/modules/sessions/codex-app-server-helper-client.js +237 -0
- package/dist/server/modules/sessions/codex-app-server-helper-client.js.map +1 -0
- package/dist/server/modules/sessions/codex-app-server-helper-process.d.ts +1 -0
- package/dist/server/modules/sessions/codex-app-server-helper-process.js +484 -0
- package/dist/server/modules/sessions/codex-app-server-helper-process.js.map +1 -0
- package/dist/server/modules/sessions/session-activity-authority-service.d.ts +52 -0
- package/dist/server/modules/sessions/session-activity-authority-service.js +377 -0
- package/dist/server/modules/sessions/session-activity-authority-service.js.map +1 -0
- package/dist/server/modules/sessions/session-activity-inspector.js +80 -40
- package/dist/server/modules/sessions/session-activity-inspector.js.map +1 -1
- package/dist/server/modules/sessions/session-controller.d.ts +15 -1
- package/dist/server/modules/sessions/session-controller.js +14 -1
- package/dist/server/modules/sessions/session-controller.js.map +1 -1
- package/dist/server/modules/sessions/session-history-service.d.ts +8 -3
- package/dist/server/modules/sessions/session-history-service.js +303 -64
- package/dist/server/modules/sessions/session-history-service.js.map +1 -1
- package/dist/server/modules/sessions/session-live-runtime-service.d.ts +40 -4
- package/dist/server/modules/sessions/session-live-runtime-service.js +334 -44
- package/dist/server/modules/sessions/session-live-runtime-service.js.map +1 -1
- package/dist/server/modules/sessions/session-permission-request-service.d.ts +175 -0
- package/dist/server/modules/sessions/session-permission-request-service.js +1615 -0
- package/dist/server/modules/sessions/session-permission-request-service.js.map +1 -0
- package/dist/server/modules/sessions/session-provider-error-mapper.js +14 -0
- package/dist/server/modules/sessions/session-provider-error-mapper.js.map +1 -1
- package/dist/server/modules/terminal/command-template-service.d.ts +2 -2
- package/dist/server/modules/terminal/command-template-service.js +3 -3
- package/dist/server/modules/terminal/command-template-service.js.map +1 -1
- package/dist/server/modules/terminal/runtime/adapters/conpty-control-helper-client.d.ts +24 -0
- package/dist/server/modules/terminal/runtime/adapters/conpty-control-helper-client.js +104 -0
- package/dist/server/modules/terminal/runtime/adapters/conpty-control-helper-client.js.map +1 -0
- package/dist/server/modules/terminal/runtime/adapters/conpty-control-helper-process.d.ts +1 -0
- package/dist/server/modules/terminal/runtime/adapters/conpty-control-helper-process.js +96 -0
- package/dist/server/modules/terminal/runtime/adapters/conpty-control-helper-process.js.map +1 -0
- package/dist/server/modules/terminal/runtime/adapters/conpty-runtime-adapter.d.ts +37 -0
- package/dist/server/modules/terminal/runtime/adapters/conpty-runtime-adapter.js +123 -0
- package/dist/server/modules/terminal/runtime/adapters/conpty-runtime-adapter.js.map +1 -0
- package/dist/server/modules/terminal/runtime/adapters/embedded-pty-runtime-adapter.d.ts +12 -5
- package/dist/server/modules/terminal/runtime/adapters/embedded-pty-runtime-adapter.js +44 -4
- package/dist/server/modules/terminal/runtime/adapters/embedded-pty-runtime-adapter.js.map +1 -1
- package/dist/server/modules/terminal/runtime/adapters/tmux-helper-client.d.ts +14 -0
- package/dist/server/modules/terminal/runtime/adapters/tmux-helper-client.js +105 -0
- package/dist/server/modules/terminal/runtime/adapters/tmux-helper-client.js.map +1 -0
- package/dist/server/modules/terminal/runtime/adapters/tmux-helper-process.d.ts +1 -0
- package/dist/server/modules/terminal/runtime/adapters/tmux-helper-process.js +67 -0
- package/dist/server/modules/terminal/runtime/adapters/tmux-helper-process.js.map +1 -0
- package/dist/server/modules/terminal/runtime/adapters/tmux-runtime-adapter.d.ts +8 -12
- package/dist/server/modules/terminal/runtime/adapters/tmux-runtime-adapter.js +112 -21
- package/dist/server/modules/terminal/runtime/adapters/tmux-runtime-adapter.js.map +1 -1
- package/dist/server/modules/terminal/runtime/conpty-runtime-shared.d.ts +25 -0
- package/dist/server/modules/terminal/runtime/conpty-runtime-shared.js +124 -0
- package/dist/server/modules/terminal/runtime/conpty-runtime-shared.js.map +1 -0
- package/dist/server/modules/terminal/runtime/conpty-session-agent-process.d.ts +1 -0
- package/dist/server/modules/terminal/runtime/conpty-session-agent-process.js +205 -0
- package/dist/server/modules/terminal/runtime/conpty-session-agent-process.js.map +1 -0
- package/dist/server/modules/terminal/runtime/conpty-session-attach-client.d.ts +1 -0
- package/dist/server/modules/terminal/runtime/conpty-session-attach-client.js +108 -0
- package/dist/server/modules/terminal/runtime/conpty-session-attach-client.js.map +1 -0
- package/dist/server/modules/terminal/runtime/conpty-session-control-client.d.ts +1 -0
- package/dist/server/modules/terminal/runtime/conpty-session-control-client.js +90 -0
- package/dist/server/modules/terminal/runtime/conpty-session-control-client.js.map +1 -0
- package/dist/server/modules/terminal/runtime/pty-broker-agent-process.d.ts +1 -0
- package/dist/server/modules/terminal/runtime/pty-broker-agent-process.js +179 -0
- package/dist/server/modules/terminal/runtime/pty-broker-agent-process.js.map +1 -0
- package/dist/server/modules/terminal/runtime/pty-broker-client.d.ts +29 -0
- package/dist/server/modules/terminal/runtime/pty-broker-client.js +169 -0
- package/dist/server/modules/terminal/runtime/pty-broker-client.js.map +1 -0
- package/dist/server/modules/terminal/runtime/pty-broker-shared.d.ts +22 -0
- package/dist/server/modules/terminal/runtime/pty-broker-shared.js +123 -0
- package/dist/server/modules/terminal/runtime/pty-broker-shared.js.map +1 -0
- package/dist/server/modules/terminal/runtime/pty-host-attachment-manager.d.ts +1 -0
- package/dist/server/modules/terminal/runtime/pty-host-attachment-manager.js +11 -1
- package/dist/server/modules/terminal/runtime/pty-host-attachment-manager.js.map +1 -1
- package/dist/server/modules/terminal/runtime/terminal-log-file-store.d.ts +1 -0
- package/dist/server/modules/terminal/runtime/terminal-log-file-store.js +7 -1
- package/dist/server/modules/terminal/runtime/terminal-log-file-store.js.map +1 -1
- package/dist/server/modules/terminal/runtime/terminal-log-spooler.js +3 -2
- package/dist/server/modules/terminal/runtime/terminal-log-spooler.js.map +1 -1
- package/dist/server/modules/terminal/runtime/terminal-runtime-adapter.d.ts +5 -3
- package/dist/server/modules/terminal/runtime/terminal-runtime-manager.d.ts +11 -5
- package/dist/server/modules/terminal/runtime/terminal-runtime-manager.js +110 -13
- package/dist/server/modules/terminal/runtime/terminal-runtime-manager.js.map +1 -1
- package/dist/server/modules/terminal/terminal-controller.js +7 -7
- package/dist/server/modules/terminal/terminal-controller.js.map +1 -1
- package/dist/server/modules/terminal/terminal-service.d.ts +30 -14
- package/dist/server/modules/terminal/terminal-service.js +260 -51
- package/dist/server/modules/terminal/terminal-service.js.map +1 -1
- package/dist/server/modules/terminal/terminal-shell.d.ts +4 -0
- package/dist/server/modules/terminal/terminal-shell.js +165 -18
- package/dist/server/modules/terminal/terminal-shell.js.map +1 -1
- package/dist/server/modules/workbench/workspace-file-watcher.d.ts +30 -0
- package/dist/server/modules/workbench/workspace-file-watcher.js +137 -0
- package/dist/server/modules/workbench/workspace-file-watcher.js.map +1 -0
- package/dist/server/modules/workbench/workspace-panel-snapshot-service.js +43 -7
- package/dist/server/modules/workbench/workspace-panel-snapshot-service.js.map +1 -1
- package/dist/server/routes/git.js +1 -0
- package/dist/server/routes/git.js.map +1 -1
- package/dist/server/routes/preferences.d.ts +2 -1
- package/dist/server/routes/preferences.js +3 -1
- package/dist/server/routes/preferences.js.map +1 -1
- package/dist/server/routes/sessions.js +2 -0
- package/dist/server/routes/sessions.js.map +1 -1
- package/dist/server/server/create-server.d.ts +4 -0
- package/dist/server/server/create-server.js +22 -5
- package/dist/server/server/create-server.js.map +1 -1
- package/dist/server/shared/utils/command-launch.d.ts +6 -0
- package/dist/server/shared/utils/command-launch.js +39 -0
- package/dist/server/shared/utils/command-launch.js.map +1 -0
- package/dist/server/shared/utils/perf-log.d.ts +1 -0
- package/dist/server/shared/utils/perf-log.js +8 -2
- package/dist/server/shared/utils/perf-log.js.map +1 -1
- package/dist/server/shared/utils/permission-debug-log.d.ts +2 -0
- package/dist/server/shared/utils/permission-debug-log.js +40 -0
- package/dist/server/shared/utils/permission-debug-log.js.map +1 -0
- package/dist/server/shared/utils/terminal-debug-log.d.ts +4 -0
- package/dist/server/shared/utils/terminal-debug-log.js +71 -0
- package/dist/server/shared/utils/terminal-debug-log.js.map +1 -0
- package/dist/server/storage/repositories/user-preference-profile-repository.d.ts +8 -0
- package/dist/server/storage/repositories/user-preference-profile-repository.js +46 -0
- package/dist/server/storage/repositories/user-preference-profile-repository.js.map +1 -0
- package/dist/server/storage/sqlite/schema.sql +13 -0
- package/dist/server/types/domain.d.ts +28 -1
- package/dist/server/ws/terminal-ws-hub.d.ts +2 -0
- package/dist/server/ws/terminal-ws-hub.js +42 -5
- package/dist/server/ws/terminal-ws-hub.js.map +1 -1
- package/dist/server/ws/workbench-ws-hub.d.ts +9 -1
- package/dist/server/ws/workbench-ws-hub.js +132 -21
- package/dist/server/ws/workbench-ws-hub.js.map +1 -1
- package/dist/server/ws/ws-server.d.ts +22 -1
- package/dist/server/ws/ws-server.js +134 -46
- package/dist/server/ws/ws-server.js.map +1 -1
- package/node_modules/@codingns/session-sync-core/dist/claude-message-utils.d.ts +4 -1
- package/node_modules/@codingns/session-sync-core/dist/claude-message-utils.js +107 -6
- package/node_modules/@codingns/session-sync-core/dist/claude-message-utils.js.map +1 -1
- package/node_modules/@codingns/session-sync-core/dist/patch-builder.d.ts +30 -0
- package/node_modules/@codingns/session-sync-core/dist/patch-builder.js +103 -0
- package/node_modules/@codingns/session-sync-core/dist/patch-builder.js.map +1 -0
- package/node_modules/@codingns/session-sync-core/dist/providers/claude-code.d.ts +1 -1
- package/node_modules/@codingns/session-sync-core/dist/providers/claude-code.js +38 -6
- package/node_modules/@codingns/session-sync-core/dist/providers/claude-code.js.map +1 -1
- package/node_modules/@codingns/session-sync-core/dist/providers/codex.d.ts +1 -1
- package/node_modules/@codingns/session-sync-core/dist/providers/codex.js +1 -1
- package/node_modules/@codingns/session-sync-core/dist/providers/codex.js.map +1 -1
- package/node_modules/@codingns/session-sync-core/dist/providers/opencode-permissions.d.ts +1 -0
- package/node_modules/@codingns/session-sync-core/dist/providers/opencode-permissions.js +8 -0
- package/node_modules/@codingns/session-sync-core/dist/providers/opencode-permissions.js.map +1 -0
- package/node_modules/@codingns/session-sync-core/dist/providers/opencode-shared.js +87 -7
- package/node_modules/@codingns/session-sync-core/dist/providers/opencode-shared.js.map +1 -1
- package/node_modules/@codingns/session-sync-core/dist/providers/opencode.d.ts +1 -1
- package/node_modules/@codingns/session-sync-core/dist/providers/opencode.js +8 -4
- package/node_modules/@codingns/session-sync-core/dist/providers/opencode.js.map +1 -1
- package/node_modules/@codingns/session-sync-core/dist/runtime/active-run-registry.d.ts +1 -0
- package/node_modules/@codingns/session-sync-core/dist/runtime/active-run-registry.js +5 -0
- package/node_modules/@codingns/session-sync-core/dist/runtime/active-run-registry.js.map +1 -1
- package/node_modules/@codingns/session-sync-core/dist/runtime/claude-runtime.d.ts +5 -0
- package/node_modules/@codingns/session-sync-core/dist/runtime/claude-runtime.js +114 -6
- package/node_modules/@codingns/session-sync-core/dist/runtime/claude-runtime.js.map +1 -1
- package/node_modules/@codingns/session-sync-core/dist/runtime/codex-runtime.d.ts +23 -0
- package/node_modules/@codingns/session-sync-core/dist/runtime/codex-runtime.js +721 -18
- package/node_modules/@codingns/session-sync-core/dist/runtime/codex-runtime.js.map +1 -1
- package/node_modules/@codingns/session-sync-core/dist/runtime/opencode-runtime.d.ts +3 -0
- package/node_modules/@codingns/session-sync-core/dist/runtime/opencode-runtime.js +106 -23
- package/node_modules/@codingns/session-sync-core/dist/runtime/opencode-runtime.js.map +1 -1
- package/node_modules/@codingns/session-sync-core/dist/runtime/provider-runtime-service.d.ts +1 -0
- package/node_modules/@codingns/session-sync-core/dist/runtime/provider-runtime-service.js +3 -0
- package/node_modules/@codingns/session-sync-core/dist/runtime/provider-runtime-service.js.map +1 -1
- package/node_modules/@codingns/session-sync-core/dist/runtime/types.d.ts +1 -0
- package/node_modules/@codingns/session-sync-core/dist/services.d.ts +1 -1
- package/node_modules/@codingns/session-sync-core/dist/services.js +2 -2
- package/node_modules/@codingns/session-sync-core/dist/services.js.map +1 -1
- package/node_modules/@codingns/session-sync-core/dist/types.d.ts +1 -1
- package/package.json +6 -2
- package/scripts/postinstall.mjs +218 -0
- package/dist/public/assets/TerminalPage-Dj_VDew3.js +0 -54
- package/dist/public/assets/index-C1GZV2wq.js +0 -106
- package/dist/public/assets/index-DU7f8NaZ.css +0 -1
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
import { randomUUID } from "node:crypto";
|
|
2
|
+
import { spawn } from "node:child_process";
|
|
2
3
|
import { existsSync, readdirSync, readFileSync, statSync } from "node:fs";
|
|
3
4
|
import { homedir } from "node:os";
|
|
4
5
|
import { basename, dirname, join, resolve } from "node:path";
|
|
6
|
+
import { createInterface } from "node:readline";
|
|
5
7
|
import { DatabaseSync } from "node:sqlite";
|
|
8
|
+
import { fileURLToPath, pathToFileURL } from "node:url";
|
|
6
9
|
import { appendJsonLine, createRawRef, ensureDirectory, extractTextBlocks, messageIdFromRawRef, nextTimestamp, normalizeWorkspacePath } from "../providers/utils.js";
|
|
7
10
|
import { createCodexThreadPermissionOptions } from "./codex-permissions.js";
|
|
8
11
|
export class CodexRuntimeAdapter {
|
|
@@ -13,29 +16,59 @@ export class CodexRuntimeAdapter {
|
|
|
13
16
|
}
|
|
14
17
|
async startSession(request, sink) {
|
|
15
18
|
const launchedAtMs = Date.now();
|
|
16
|
-
const
|
|
17
|
-
|
|
19
|
+
const transport = this.options.transportFactory
|
|
20
|
+
? this.options.transportFactory()
|
|
21
|
+
: createCodexAppServerTransport(this.options);
|
|
22
|
+
await transport.initialize();
|
|
18
23
|
const abortController = new AbortController();
|
|
19
|
-
const
|
|
20
|
-
|
|
21
|
-
});
|
|
22
|
-
const events = streamed.events[Symbol.asyncIterator]();
|
|
23
|
-
const startedSession = await this.awaitThreadStarted(thread, events, request.workspacePath, request.options.content, launchedAtMs);
|
|
24
|
+
const eventQueue = createAsyncEventQueue();
|
|
25
|
+
const startedSession = await transport.startThread(request);
|
|
24
26
|
const providerSessionId = startedSession.providerSessionId;
|
|
25
|
-
const fallbackRawStoreRef =
|
|
27
|
+
const fallbackRawStoreRef = startedSession.rawStoreRef ??
|
|
28
|
+
request.rawStoreRef ??
|
|
29
|
+
buildRuntimeRawStoreRef(resolveRuntimeStoreKey(providerSessionId, request.sessionId));
|
|
26
30
|
const resolvedBinding = await this.resolveExistingSessionBinding(providerSessionId, fallbackRawStoreRef, request.workspacePath);
|
|
27
31
|
const rawStoreRef = resolvedBinding?.rawStoreRef ?? fallbackRawStoreRef;
|
|
28
32
|
sink.updateSessionBinding({
|
|
29
33
|
providerSessionId,
|
|
30
34
|
rawStoreRef
|
|
31
35
|
});
|
|
36
|
+
transport.setNotificationHandler(async (notification) => {
|
|
37
|
+
const translated = translateCodexAppServerNotification(notification);
|
|
38
|
+
if (translated.turnId) {
|
|
39
|
+
eventQueue.setTurnId(translated.turnId);
|
|
40
|
+
}
|
|
41
|
+
if (translated.event) {
|
|
42
|
+
eventQueue.push(translated.event);
|
|
43
|
+
}
|
|
44
|
+
if (translated.terminal) {
|
|
45
|
+
eventQueue.close();
|
|
46
|
+
}
|
|
47
|
+
});
|
|
48
|
+
transport.setServerRequestHandler(async (serverRequest) => {
|
|
49
|
+
if (!this.options.handleServerRequest) {
|
|
50
|
+
throw new Error("CODEX_APP_SERVER_REQUEST_NOT_SUPPORTED");
|
|
51
|
+
}
|
|
52
|
+
return this.options.handleServerRequest({
|
|
53
|
+
sessionId: request.sessionId,
|
|
54
|
+
providerSessionId,
|
|
55
|
+
request: serverRequest
|
|
56
|
+
});
|
|
57
|
+
});
|
|
58
|
+
await transport.startTurn(request, providerSessionId);
|
|
32
59
|
return {
|
|
33
60
|
providerSessionId,
|
|
34
61
|
rawStoreRef,
|
|
35
62
|
interrupt: async () => {
|
|
36
63
|
abortController.abort();
|
|
64
|
+
await transport.interruptTurn().catch(() => {
|
|
65
|
+
return;
|
|
66
|
+
});
|
|
67
|
+
transport.close();
|
|
37
68
|
},
|
|
38
|
-
completed: this.runTurn(null, request, sink, providerSessionId, rawStoreRef, abortController,
|
|
69
|
+
completed: this.runTurn(null, request, sink, providerSessionId, rawStoreRef, abortController, eventQueue.iterator, [], launchedAtMs).finally(() => {
|
|
70
|
+
transport.close();
|
|
71
|
+
})
|
|
39
72
|
};
|
|
40
73
|
}
|
|
41
74
|
async continueSession(request, sink) {
|
|
@@ -43,31 +76,66 @@ export class CodexRuntimeAdapter {
|
|
|
43
76
|
if (!providerSessionId) {
|
|
44
77
|
throw new Error("PROVIDER_SESSION_ID_REQUIRED");
|
|
45
78
|
}
|
|
46
|
-
const
|
|
47
|
-
|
|
79
|
+
const transport = this.options.transportFactory
|
|
80
|
+
? this.options.transportFactory()
|
|
81
|
+
: createCodexAppServerTransport(this.options);
|
|
82
|
+
await transport.initialize();
|
|
48
83
|
const fallbackRawStoreRef = request.rawStoreRef ?? buildRuntimeRawStoreRef(providerSessionId);
|
|
49
84
|
const resolvedBinding = await this.resolveExistingSessionBinding(providerSessionId, fallbackRawStoreRef, request.workspacePath);
|
|
50
85
|
const resolvedSessionId = resolvedBinding?.providerSessionId ?? providerSessionId;
|
|
51
|
-
const
|
|
86
|
+
const resumed = await transport.resumeThread(request, resolvedSessionId);
|
|
87
|
+
const rawStoreRef = resolvedBinding?.rawStoreRef ?? resumed.rawStoreRef ?? fallbackRawStoreRef;
|
|
52
88
|
const abortController = new AbortController();
|
|
89
|
+
const eventQueue = createAsyncEventQueue();
|
|
53
90
|
sink.updateSessionBinding({
|
|
54
91
|
providerSessionId: resolvedSessionId,
|
|
55
92
|
rawStoreRef
|
|
56
93
|
});
|
|
94
|
+
transport.setNotificationHandler(async (notification) => {
|
|
95
|
+
const translated = translateCodexAppServerNotification(notification);
|
|
96
|
+
if (translated.turnId) {
|
|
97
|
+
eventQueue.setTurnId(translated.turnId);
|
|
98
|
+
}
|
|
99
|
+
if (translated.event) {
|
|
100
|
+
eventQueue.push(translated.event);
|
|
101
|
+
}
|
|
102
|
+
if (translated.terminal) {
|
|
103
|
+
eventQueue.close();
|
|
104
|
+
}
|
|
105
|
+
});
|
|
106
|
+
transport.setServerRequestHandler(async (serverRequest) => {
|
|
107
|
+
if (!this.options.handleServerRequest) {
|
|
108
|
+
throw new Error("CODEX_APP_SERVER_REQUEST_NOT_SUPPORTED");
|
|
109
|
+
}
|
|
110
|
+
return this.options.handleServerRequest({
|
|
111
|
+
sessionId: request.sessionId,
|
|
112
|
+
providerSessionId: resolvedSessionId,
|
|
113
|
+
request: serverRequest
|
|
114
|
+
});
|
|
115
|
+
});
|
|
116
|
+
await transport.startTurn(request, resolvedSessionId);
|
|
57
117
|
return {
|
|
58
118
|
providerSessionId: resolvedSessionId,
|
|
59
119
|
rawStoreRef,
|
|
60
120
|
interrupt: async () => {
|
|
61
121
|
abortController.abort();
|
|
122
|
+
await transport.interruptTurn().catch(() => {
|
|
123
|
+
return;
|
|
124
|
+
});
|
|
125
|
+
transport.close();
|
|
62
126
|
},
|
|
63
|
-
completed: this.runTurn(
|
|
127
|
+
completed: this.runTurn(null, request, sink, resolvedSessionId, rawStoreRef, abortController, eventQueue.iterator, [], Date.now()).finally(() => {
|
|
128
|
+
transport.close();
|
|
129
|
+
})
|
|
64
130
|
};
|
|
65
131
|
}
|
|
66
132
|
async runTurn(thread, request, sink, providerSessionId, rawStoreRef, abortController, preparedEvents, bufferedEvents = [], launchedAtMs = Date.now()) {
|
|
67
133
|
const context = {
|
|
68
134
|
providerSessionId,
|
|
69
135
|
rawStoreRef,
|
|
70
|
-
|
|
136
|
+
// 运行时消息必须接在历史消息后面,不能每轮都从 1 重新编号,
|
|
137
|
+
// 否则前端会把新 assistant/tool 消息排到旧消息前面,表现成用户消息一直挂在底部。
|
|
138
|
+
sequence: Math.max(0, request.sequenceBase ?? 0),
|
|
71
139
|
toolNameByCallId: new Map(),
|
|
72
140
|
sink,
|
|
73
141
|
workspacePath: request.workspacePath,
|
|
@@ -147,12 +215,23 @@ export class CodexRuntimeAdapter {
|
|
|
147
215
|
status: "failed",
|
|
148
216
|
providerSessionId: context.providerSessionId,
|
|
149
217
|
rawStoreRef: context.rawStoreRef,
|
|
150
|
-
errorCode: "CODEX_CLI_TURN_FAILED",
|
|
218
|
+
errorCode: classifyCodexDetailErrorCode(detail, "CODEX_CLI_TURN_FAILED"),
|
|
151
219
|
detail,
|
|
152
220
|
timestamp: pickTimestamp(event)
|
|
153
221
|
});
|
|
154
222
|
return;
|
|
155
223
|
}
|
|
224
|
+
if (eventType === "turn.interrupted") {
|
|
225
|
+
await context.sink.emit({
|
|
226
|
+
type: "interrupted",
|
|
227
|
+
status: "interrupted",
|
|
228
|
+
providerSessionId: context.providerSessionId,
|
|
229
|
+
rawStoreRef: context.rawStoreRef,
|
|
230
|
+
detail: "codex turn interrupted",
|
|
231
|
+
timestamp: pickTimestamp(event)
|
|
232
|
+
});
|
|
233
|
+
return;
|
|
234
|
+
}
|
|
156
235
|
if (interrupted) {
|
|
157
236
|
return;
|
|
158
237
|
}
|
|
@@ -450,6 +529,392 @@ export class CodexRuntimeAdapter {
|
|
|
450
529
|
}
|
|
451
530
|
}
|
|
452
531
|
}
|
|
532
|
+
function createCodexAppServerTransport(options) {
|
|
533
|
+
const commandPath = resolveCodexCommand(options.commandPath);
|
|
534
|
+
const launch = resolveCodexCommandLaunch(commandPath, ["app-server"]);
|
|
535
|
+
const child = spawn(launch.command, launch.args, {
|
|
536
|
+
env: process.env,
|
|
537
|
+
stdio: ["pipe", "pipe", "pipe"],
|
|
538
|
+
shell: launch.shell,
|
|
539
|
+
windowsHide: true
|
|
540
|
+
});
|
|
541
|
+
const stdout = createInterface({ input: child.stdout });
|
|
542
|
+
let notificationHandler = () => undefined;
|
|
543
|
+
let serverRequestHandler = async () => {
|
|
544
|
+
throw new Error("CODEX_APP_SERVER_REQUEST_NOT_SUPPORTED");
|
|
545
|
+
};
|
|
546
|
+
let requestSequence = 0;
|
|
547
|
+
let closed = false;
|
|
548
|
+
let activeTurnId = null;
|
|
549
|
+
let activeThreadId = null;
|
|
550
|
+
const pendingResponses = new Map();
|
|
551
|
+
const finalize = (error) => {
|
|
552
|
+
if (closed) {
|
|
553
|
+
return;
|
|
554
|
+
}
|
|
555
|
+
closed = true;
|
|
556
|
+
stdout.close();
|
|
557
|
+
for (const pending of pendingResponses.values()) {
|
|
558
|
+
pending.reject(error ?? new Error("CODEX_APP_SERVER_CLOSED"));
|
|
559
|
+
}
|
|
560
|
+
pendingResponses.clear();
|
|
561
|
+
};
|
|
562
|
+
child.on("error", (error) => {
|
|
563
|
+
finalize(error);
|
|
564
|
+
});
|
|
565
|
+
child.on("exit", (code, signal) => {
|
|
566
|
+
if (closed) {
|
|
567
|
+
return;
|
|
568
|
+
}
|
|
569
|
+
const detail = signal
|
|
570
|
+
? `codex app-server exited with signal ${signal}`
|
|
571
|
+
: `codex app-server exited with code ${String(code ?? "unknown")}`;
|
|
572
|
+
finalize(new Error(detail));
|
|
573
|
+
});
|
|
574
|
+
stdout.on("line", (line) => {
|
|
575
|
+
const trimmed = line.trim();
|
|
576
|
+
if (!trimmed) {
|
|
577
|
+
return;
|
|
578
|
+
}
|
|
579
|
+
let parsed;
|
|
580
|
+
try {
|
|
581
|
+
parsed = JSON.parse(trimmed);
|
|
582
|
+
}
|
|
583
|
+
catch {
|
|
584
|
+
return;
|
|
585
|
+
}
|
|
586
|
+
if (typeof parsed.method === "string" && parsed.id !== undefined) {
|
|
587
|
+
void Promise.resolve(serverRequestHandler(parsed))
|
|
588
|
+
.then((result) => {
|
|
589
|
+
writeJsonRpcMessage(child, {
|
|
590
|
+
jsonrpc: "2.0",
|
|
591
|
+
id: parsed.id,
|
|
592
|
+
result
|
|
593
|
+
});
|
|
594
|
+
})
|
|
595
|
+
.catch((error) => {
|
|
596
|
+
writeJsonRpcMessage(child, {
|
|
597
|
+
jsonrpc: "2.0",
|
|
598
|
+
id: parsed.id,
|
|
599
|
+
error: {
|
|
600
|
+
code: -32000,
|
|
601
|
+
message: error instanceof Error ? error.message : "CODEX_APP_SERVER_REQUEST_FAILED"
|
|
602
|
+
}
|
|
603
|
+
});
|
|
604
|
+
});
|
|
605
|
+
return;
|
|
606
|
+
}
|
|
607
|
+
if (typeof parsed.method === "string") {
|
|
608
|
+
const method = parsed.method.trim();
|
|
609
|
+
const params = readJsonRpcParams(parsed);
|
|
610
|
+
if (method === "turn/started") {
|
|
611
|
+
activeTurnId = ensureText(readProp(readProp(params, "turn"), "id")).trim() || activeTurnId;
|
|
612
|
+
}
|
|
613
|
+
if (method === "thread/started") {
|
|
614
|
+
activeThreadId = ensureText(readProp(readProp(params, "thread"), "id")).trim() || activeThreadId;
|
|
615
|
+
}
|
|
616
|
+
void notificationHandler({
|
|
617
|
+
method,
|
|
618
|
+
params
|
|
619
|
+
});
|
|
620
|
+
return;
|
|
621
|
+
}
|
|
622
|
+
const responseId = String(parsed.id ?? "");
|
|
623
|
+
const pending = pendingResponses.get(responseId);
|
|
624
|
+
if (!pending) {
|
|
625
|
+
return;
|
|
626
|
+
}
|
|
627
|
+
pendingResponses.delete(responseId);
|
|
628
|
+
if (parsed.error && typeof parsed.error === "object") {
|
|
629
|
+
const message = ensureText(readProp(parsed.error, "message")).trim() || "CODEX_APP_SERVER_ERROR";
|
|
630
|
+
pending.reject(new Error(message));
|
|
631
|
+
return;
|
|
632
|
+
}
|
|
633
|
+
pending.resolve(readJsonRpcResult(parsed));
|
|
634
|
+
});
|
|
635
|
+
return {
|
|
636
|
+
async initialize() {
|
|
637
|
+
await sendJsonRpcRequest(child, pendingResponses, () => nextJsonRpcId("initialize", () => ++requestSequence), {
|
|
638
|
+
method: "initialize",
|
|
639
|
+
params: {
|
|
640
|
+
clientInfo: {
|
|
641
|
+
name: "codingns-runtime",
|
|
642
|
+
version: "0.0.0"
|
|
643
|
+
},
|
|
644
|
+
capabilities: null
|
|
645
|
+
}
|
|
646
|
+
});
|
|
647
|
+
writeJsonRpcMessage(child, {
|
|
648
|
+
jsonrpc: "2.0",
|
|
649
|
+
method: "initialized",
|
|
650
|
+
params: {}
|
|
651
|
+
});
|
|
652
|
+
},
|
|
653
|
+
async startThread(request) {
|
|
654
|
+
const result = await sendJsonRpcRequest(child, pendingResponses, () => nextJsonRpcId("thread-start", () => ++requestSequence), {
|
|
655
|
+
method: "thread/start",
|
|
656
|
+
params: createThreadStartParams(request)
|
|
657
|
+
});
|
|
658
|
+
const thread = toRecord(result.thread);
|
|
659
|
+
const providerSessionId = ensureText(thread?.id).trim();
|
|
660
|
+
if (!providerSessionId) {
|
|
661
|
+
throw new Error("CODEX_APP_SERVER_THREAD_ID_MISSING");
|
|
662
|
+
}
|
|
663
|
+
activeThreadId = providerSessionId;
|
|
664
|
+
return {
|
|
665
|
+
providerSessionId,
|
|
666
|
+
rawStoreRef: normalizeText(thread?.path) || null
|
|
667
|
+
};
|
|
668
|
+
},
|
|
669
|
+
async resumeThread(request, providerSessionId) {
|
|
670
|
+
const result = await sendJsonRpcRequest(child, pendingResponses, () => nextJsonRpcId("thread-resume", () => ++requestSequence), {
|
|
671
|
+
method: "thread/resume",
|
|
672
|
+
params: createThreadResumeParams(request, providerSessionId)
|
|
673
|
+
});
|
|
674
|
+
const thread = toRecord(result.thread);
|
|
675
|
+
activeThreadId = ensureText(thread?.id).trim() || providerSessionId;
|
|
676
|
+
return {
|
|
677
|
+
providerSessionId: activeThreadId,
|
|
678
|
+
rawStoreRef: normalizeText(thread?.path) || null
|
|
679
|
+
};
|
|
680
|
+
},
|
|
681
|
+
async startTurn(request, providerSessionId) {
|
|
682
|
+
const result = await sendJsonRpcRequest(child, pendingResponses, () => nextJsonRpcId("turn-start", () => ++requestSequence), {
|
|
683
|
+
method: "turn/start",
|
|
684
|
+
params: createTurnStartParams(request, providerSessionId)
|
|
685
|
+
});
|
|
686
|
+
activeTurnId = ensureText(readProp(readProp(result, "turn"), "id")).trim() || activeTurnId;
|
|
687
|
+
},
|
|
688
|
+
async interruptTurn() {
|
|
689
|
+
if (!activeThreadId || !activeTurnId) {
|
|
690
|
+
return;
|
|
691
|
+
}
|
|
692
|
+
await sendJsonRpcRequest(child, pendingResponses, () => nextJsonRpcId("turn-interrupt", () => ++requestSequence), {
|
|
693
|
+
method: "turn/interrupt",
|
|
694
|
+
params: {
|
|
695
|
+
threadId: activeThreadId,
|
|
696
|
+
turnId: activeTurnId
|
|
697
|
+
}
|
|
698
|
+
});
|
|
699
|
+
},
|
|
700
|
+
setNotificationHandler(handler) {
|
|
701
|
+
notificationHandler = handler;
|
|
702
|
+
},
|
|
703
|
+
setServerRequestHandler(handler) {
|
|
704
|
+
serverRequestHandler = handler;
|
|
705
|
+
},
|
|
706
|
+
close() {
|
|
707
|
+
if (closed) {
|
|
708
|
+
return;
|
|
709
|
+
}
|
|
710
|
+
finalize(null);
|
|
711
|
+
if (!child.stdin.destroyed) {
|
|
712
|
+
child.stdin.end();
|
|
713
|
+
}
|
|
714
|
+
if (!child.killed) {
|
|
715
|
+
child.kill("SIGTERM");
|
|
716
|
+
}
|
|
717
|
+
}
|
|
718
|
+
};
|
|
719
|
+
}
|
|
720
|
+
function createAsyncEventQueue() {
|
|
721
|
+
const values = [];
|
|
722
|
+
const waiters = [];
|
|
723
|
+
let closed = false;
|
|
724
|
+
let turnId = null;
|
|
725
|
+
return {
|
|
726
|
+
iterator: {
|
|
727
|
+
next() {
|
|
728
|
+
if (values.length > 0) {
|
|
729
|
+
return Promise.resolve({
|
|
730
|
+
done: false,
|
|
731
|
+
value: values.shift()
|
|
732
|
+
});
|
|
733
|
+
}
|
|
734
|
+
if (closed) {
|
|
735
|
+
return Promise.resolve({
|
|
736
|
+
done: true,
|
|
737
|
+
value: undefined
|
|
738
|
+
});
|
|
739
|
+
}
|
|
740
|
+
return new Promise((resolve) => {
|
|
741
|
+
waiters.push(resolve);
|
|
742
|
+
});
|
|
743
|
+
}
|
|
744
|
+
},
|
|
745
|
+
push(value) {
|
|
746
|
+
if (closed) {
|
|
747
|
+
return;
|
|
748
|
+
}
|
|
749
|
+
const waiter = waiters.shift();
|
|
750
|
+
if (waiter) {
|
|
751
|
+
waiter({
|
|
752
|
+
done: false,
|
|
753
|
+
value
|
|
754
|
+
});
|
|
755
|
+
return;
|
|
756
|
+
}
|
|
757
|
+
values.push(value);
|
|
758
|
+
},
|
|
759
|
+
close() {
|
|
760
|
+
if (closed) {
|
|
761
|
+
return;
|
|
762
|
+
}
|
|
763
|
+
closed = true;
|
|
764
|
+
while (waiters.length > 0) {
|
|
765
|
+
waiters.shift()?.({
|
|
766
|
+
done: true,
|
|
767
|
+
value: undefined
|
|
768
|
+
});
|
|
769
|
+
}
|
|
770
|
+
},
|
|
771
|
+
setTurnId(nextTurnId) {
|
|
772
|
+
turnId = nextTurnId;
|
|
773
|
+
},
|
|
774
|
+
getTurnId() {
|
|
775
|
+
return turnId;
|
|
776
|
+
}
|
|
777
|
+
};
|
|
778
|
+
}
|
|
779
|
+
function translateCodexAppServerNotification(notification) {
|
|
780
|
+
const method = ensureText(notification.method).trim();
|
|
781
|
+
const params = toRecord(notification.params) ?? {};
|
|
782
|
+
if (method === "turn/started") {
|
|
783
|
+
return {
|
|
784
|
+
event: null,
|
|
785
|
+
terminal: false,
|
|
786
|
+
turnId: ensureText(readProp(readProp(params, "turn"), "id")).trim() || null
|
|
787
|
+
};
|
|
788
|
+
}
|
|
789
|
+
if (method === "turn/completed") {
|
|
790
|
+
const turn = toRecord(params.turn);
|
|
791
|
+
const status = ensureText(turn?.status).trim();
|
|
792
|
+
if (status === "failed") {
|
|
793
|
+
return {
|
|
794
|
+
event: {
|
|
795
|
+
type: "turn.failed",
|
|
796
|
+
timestamp: nextTimestamp(),
|
|
797
|
+
error: ensureText(readProp(turn?.error, "message")).trim() || "codex turn failed"
|
|
798
|
+
},
|
|
799
|
+
terminal: true,
|
|
800
|
+
turnId: ensureText(turn?.id).trim() || null
|
|
801
|
+
};
|
|
802
|
+
}
|
|
803
|
+
if (status === "interrupted") {
|
|
804
|
+
return {
|
|
805
|
+
event: {
|
|
806
|
+
type: "turn.interrupted",
|
|
807
|
+
timestamp: nextTimestamp()
|
|
808
|
+
},
|
|
809
|
+
terminal: true,
|
|
810
|
+
turnId: ensureText(turn?.id).trim() || null
|
|
811
|
+
};
|
|
812
|
+
}
|
|
813
|
+
return {
|
|
814
|
+
event: {
|
|
815
|
+
type: "turn.completed",
|
|
816
|
+
timestamp: nextTimestamp()
|
|
817
|
+
},
|
|
818
|
+
terminal: true,
|
|
819
|
+
turnId: ensureText(turn?.id).trim() || null
|
|
820
|
+
};
|
|
821
|
+
}
|
|
822
|
+
if (method === "item/started" || method === "item/completed") {
|
|
823
|
+
const item = translateCodexAppServerItem(toRecord(params.item));
|
|
824
|
+
if (!item) {
|
|
825
|
+
return {
|
|
826
|
+
event: null,
|
|
827
|
+
terminal: false,
|
|
828
|
+
turnId: null
|
|
829
|
+
};
|
|
830
|
+
}
|
|
831
|
+
return {
|
|
832
|
+
event: {
|
|
833
|
+
type: method === "item/started" ? "item.started" : "item.completed",
|
|
834
|
+
item,
|
|
835
|
+
timestamp: nextTimestamp()
|
|
836
|
+
},
|
|
837
|
+
terminal: false,
|
|
838
|
+
turnId: null
|
|
839
|
+
};
|
|
840
|
+
}
|
|
841
|
+
return {
|
|
842
|
+
event: null,
|
|
843
|
+
terminal: false,
|
|
844
|
+
turnId: null
|
|
845
|
+
};
|
|
846
|
+
}
|
|
847
|
+
function translateCodexAppServerItem(item) {
|
|
848
|
+
if (!item) {
|
|
849
|
+
return null;
|
|
850
|
+
}
|
|
851
|
+
const itemType = ensureText(item.type).trim();
|
|
852
|
+
if (!itemType) {
|
|
853
|
+
return null;
|
|
854
|
+
}
|
|
855
|
+
if (itemType === "agentMessage") {
|
|
856
|
+
return {
|
|
857
|
+
type: "agent_message",
|
|
858
|
+
id: item.id,
|
|
859
|
+
text: item.text
|
|
860
|
+
};
|
|
861
|
+
}
|
|
862
|
+
if (itemType === "reasoning") {
|
|
863
|
+
return {
|
|
864
|
+
type: "reasoning",
|
|
865
|
+
id: item.id,
|
|
866
|
+
text: Array.isArray(item.content) ? item.content.join("\n") : "",
|
|
867
|
+
summary: Array.isArray(item.summary) ? item.summary.join("\n") : ""
|
|
868
|
+
};
|
|
869
|
+
}
|
|
870
|
+
if (itemType === "commandExecution") {
|
|
871
|
+
return {
|
|
872
|
+
type: "command_execution",
|
|
873
|
+
id: item.id,
|
|
874
|
+
command: item.command,
|
|
875
|
+
cwd: item.cwd,
|
|
876
|
+
status: normalizeCodexItemStatus(item.status),
|
|
877
|
+
commandActions: item.commandActions,
|
|
878
|
+
aggregated_output: item.aggregatedOutput,
|
|
879
|
+
exit_code: item.exitCode
|
|
880
|
+
};
|
|
881
|
+
}
|
|
882
|
+
if (itemType === "fileChange") {
|
|
883
|
+
const diffText = buildCodexFileChangeOutput(item.changes);
|
|
884
|
+
return {
|
|
885
|
+
type: "custom_tool_call",
|
|
886
|
+
id: item.id,
|
|
887
|
+
tool: "apply_patch",
|
|
888
|
+
input: diffText,
|
|
889
|
+
output: diffText,
|
|
890
|
+
status: normalizeCodexItemStatus(item.status)
|
|
891
|
+
};
|
|
892
|
+
}
|
|
893
|
+
if (itemType === "mcpToolCall") {
|
|
894
|
+
return {
|
|
895
|
+
type: "mcp_tool_call",
|
|
896
|
+
id: item.id,
|
|
897
|
+
tool: item.tool,
|
|
898
|
+
server: item.server,
|
|
899
|
+
arguments: item.arguments,
|
|
900
|
+
result: item.result,
|
|
901
|
+
error: item.error,
|
|
902
|
+
status: normalizeCodexItemStatus(item.status)
|
|
903
|
+
};
|
|
904
|
+
}
|
|
905
|
+
if (itemType === "dynamicToolCall") {
|
|
906
|
+
return {
|
|
907
|
+
type: "custom_tool_call",
|
|
908
|
+
id: item.id,
|
|
909
|
+
tool: item.tool,
|
|
910
|
+
input: item.arguments,
|
|
911
|
+
output: item.contentItems,
|
|
912
|
+
success: item.success,
|
|
913
|
+
status: normalizeCodexItemStatus(item.status)
|
|
914
|
+
};
|
|
915
|
+
}
|
|
916
|
+
return null;
|
|
917
|
+
}
|
|
453
918
|
export function createThreadOptions(request) {
|
|
454
919
|
const options = {
|
|
455
920
|
workingDirectory: request.workspacePath,
|
|
@@ -469,6 +934,61 @@ export function createThreadOptions(request) {
|
|
|
469
934
|
}
|
|
470
935
|
return options;
|
|
471
936
|
}
|
|
937
|
+
function createThreadStartParams(request) {
|
|
938
|
+
const permissionOptions = createCodexThreadPermissionOptions(request.options.permissionMode ?? "default");
|
|
939
|
+
const params = {
|
|
940
|
+
cwd: request.workspacePath,
|
|
941
|
+
approvalsReviewer: "user"
|
|
942
|
+
};
|
|
943
|
+
if (permissionOptions.approvalPolicy) {
|
|
944
|
+
params.approvalPolicy = permissionOptions.approvalPolicy;
|
|
945
|
+
}
|
|
946
|
+
if (permissionOptions.sandboxMode) {
|
|
947
|
+
params.sandbox = permissionOptions.sandboxMode;
|
|
948
|
+
}
|
|
949
|
+
if (request.options.model) {
|
|
950
|
+
params.model = request.options.model;
|
|
951
|
+
}
|
|
952
|
+
return params;
|
|
953
|
+
}
|
|
954
|
+
function createThreadResumeParams(request, providerSessionId) {
|
|
955
|
+
const permissionOptions = createCodexThreadPermissionOptions(request.options.permissionMode ?? "default");
|
|
956
|
+
const params = {
|
|
957
|
+
threadId: providerSessionId,
|
|
958
|
+
cwd: request.workspacePath,
|
|
959
|
+
approvalsReviewer: "user"
|
|
960
|
+
};
|
|
961
|
+
if (permissionOptions.approvalPolicy) {
|
|
962
|
+
params.approvalPolicy = permissionOptions.approvalPolicy;
|
|
963
|
+
}
|
|
964
|
+
if (permissionOptions.sandboxMode) {
|
|
965
|
+
params.sandbox = permissionOptions.sandboxMode;
|
|
966
|
+
}
|
|
967
|
+
if (request.options.model) {
|
|
968
|
+
params.model = request.options.model;
|
|
969
|
+
}
|
|
970
|
+
return params;
|
|
971
|
+
}
|
|
972
|
+
function createTurnStartParams(request, providerSessionId) {
|
|
973
|
+
const permissionOptions = createCodexThreadPermissionOptions(request.options.permissionMode ?? "default");
|
|
974
|
+
const params = {
|
|
975
|
+
threadId: providerSessionId,
|
|
976
|
+
input: createCodexAppServerInput(request),
|
|
977
|
+
cwd: request.workspacePath,
|
|
978
|
+
approvalsReviewer: "user"
|
|
979
|
+
};
|
|
980
|
+
if (permissionOptions.approvalPolicy) {
|
|
981
|
+
params.approvalPolicy = permissionOptions.approvalPolicy;
|
|
982
|
+
}
|
|
983
|
+
if (request.options.model) {
|
|
984
|
+
params.model = request.options.model;
|
|
985
|
+
}
|
|
986
|
+
const reasoningEffort = normalizeCodexReasoningEffort(request.options.reasoningLevel);
|
|
987
|
+
if (reasoningEffort) {
|
|
988
|
+
params.effort = reasoningEffort;
|
|
989
|
+
}
|
|
990
|
+
return params;
|
|
991
|
+
}
|
|
472
992
|
function normalizeCodexReasoningEffort(value) {
|
|
473
993
|
const normalized = value?.trim().toLowerCase() ?? null;
|
|
474
994
|
if (!normalized) {
|
|
@@ -506,21 +1026,143 @@ function createCodexInput(request) {
|
|
|
506
1026
|
});
|
|
507
1027
|
return input;
|
|
508
1028
|
}
|
|
1029
|
+
function createCodexAppServerInput(request) {
|
|
1030
|
+
const input = [];
|
|
1031
|
+
const promptText = (request.options.providerPrompt ?? request.options.content).trim();
|
|
1032
|
+
if (promptText.length > 0) {
|
|
1033
|
+
input.push({
|
|
1034
|
+
type: "text",
|
|
1035
|
+
text: promptText
|
|
1036
|
+
});
|
|
1037
|
+
}
|
|
1038
|
+
for (const attachment of request.options.attachments) {
|
|
1039
|
+
input.push({
|
|
1040
|
+
type: "localImage",
|
|
1041
|
+
path: attachment.filePath
|
|
1042
|
+
});
|
|
1043
|
+
}
|
|
1044
|
+
return input;
|
|
1045
|
+
}
|
|
509
1046
|
async function loadCodexClient() {
|
|
510
1047
|
const moduleName = "@openai/codex-sdk";
|
|
511
1048
|
const runtimeImport = new Function("name", "return import(name);");
|
|
512
|
-
const
|
|
1049
|
+
const resolvedModuleName = resolveCodexSdkModuleSpecifier(moduleName);
|
|
1050
|
+
const module = (await runtimeImport(resolvedModuleName));
|
|
513
1051
|
if (!module.Codex) {
|
|
514
1052
|
throw new Error("CODEX_SDK_UNAVAILABLE");
|
|
515
1053
|
}
|
|
516
1054
|
return new module.Codex();
|
|
517
1055
|
}
|
|
1056
|
+
function resolveCodexSdkModuleSpecifier(moduleName) {
|
|
1057
|
+
const localSdkEntry = findNodeModulesFile(dirname(fileURLToPath(import.meta.url)), ["@openai", "codex-sdk", "dist", "index.js"]);
|
|
1058
|
+
if (localSdkEntry) {
|
|
1059
|
+
return pathToFileURL(localSdkEntry).href;
|
|
1060
|
+
}
|
|
1061
|
+
if (typeof import.meta.resolve === "function") {
|
|
1062
|
+
return import.meta.resolve(moduleName);
|
|
1063
|
+
}
|
|
1064
|
+
return moduleName;
|
|
1065
|
+
}
|
|
1066
|
+
function findNodeModulesFile(startDirectory, relativeSegments) {
|
|
1067
|
+
let currentDirectory = startDirectory;
|
|
1068
|
+
while (true) {
|
|
1069
|
+
const candidate = resolveNodeModulesCandidate(currentDirectory, relativeSegments);
|
|
1070
|
+
if (existsSync(candidate)) {
|
|
1071
|
+
return candidate;
|
|
1072
|
+
}
|
|
1073
|
+
const parentDirectory = dirname(currentDirectory);
|
|
1074
|
+
if (parentDirectory === currentDirectory) {
|
|
1075
|
+
return null;
|
|
1076
|
+
}
|
|
1077
|
+
currentDirectory = parentDirectory;
|
|
1078
|
+
}
|
|
1079
|
+
}
|
|
1080
|
+
function resolveNodeModulesCandidate(currentDirectory, relativeSegments) {
|
|
1081
|
+
if (basename(currentDirectory) === "node_modules") {
|
|
1082
|
+
return resolve(currentDirectory, ...relativeSegments);
|
|
1083
|
+
}
|
|
1084
|
+
return resolve(currentDirectory, "node_modules", ...relativeSegments);
|
|
1085
|
+
}
|
|
518
1086
|
function buildRuntimeRawStoreRef(providerSessionId) {
|
|
519
1087
|
return resolve(process.cwd(), "runtime", "codex", `${providerSessionId}.stream`);
|
|
520
1088
|
}
|
|
521
1089
|
function resolveRuntimeStoreKey(providerSessionId, sessionId) {
|
|
522
1090
|
return providerSessionId.trim() || sessionId;
|
|
523
1091
|
}
|
|
1092
|
+
function resolveCodexCommand(explicitPath) {
|
|
1093
|
+
const explicitCandidate = explicitPath?.trim() ||
|
|
1094
|
+
process.env.CODINGNS_CODEX_COMMAND?.trim() ||
|
|
1095
|
+
"codex";
|
|
1096
|
+
return explicitCandidate;
|
|
1097
|
+
}
|
|
1098
|
+
function resolveCodexCommandLaunch(commandPath, args) {
|
|
1099
|
+
const normalizedCommandPath = commandPath.trim();
|
|
1100
|
+
if (isNodeScriptPath(normalizedCommandPath)) {
|
|
1101
|
+
return {
|
|
1102
|
+
command: process.execPath,
|
|
1103
|
+
args: [normalizedCommandPath, ...args],
|
|
1104
|
+
shell: false
|
|
1105
|
+
};
|
|
1106
|
+
}
|
|
1107
|
+
return {
|
|
1108
|
+
command: normalizedCommandPath,
|
|
1109
|
+
args: [...args],
|
|
1110
|
+
shell: shouldSpawnViaShellOnWindows(normalizedCommandPath)
|
|
1111
|
+
};
|
|
1112
|
+
}
|
|
1113
|
+
function isNodeScriptPath(commandPath) {
|
|
1114
|
+
return /\.(?:c|m)?js$/i.test(commandPath);
|
|
1115
|
+
}
|
|
1116
|
+
function shouldSpawnViaShellOnWindows(commandPath) {
|
|
1117
|
+
if (process.platform !== "win32") {
|
|
1118
|
+
return false;
|
|
1119
|
+
}
|
|
1120
|
+
if (/\.(cmd|bat)$/i.test(commandPath)) {
|
|
1121
|
+
return true;
|
|
1122
|
+
}
|
|
1123
|
+
// Windows 上裸名命令(无扩展名、无路径分隔符)需要 shell 才能从 PATH 解析 .cmd 文件
|
|
1124
|
+
const extension = commandPath.split(".").pop()?.toLowerCase();
|
|
1125
|
+
const hasPathSep = commandPath.includes("\\") || commandPath.includes("/");
|
|
1126
|
+
if (!extension || extension === commandPath.toLowerCase()) {
|
|
1127
|
+
if (!hasPathSep) {
|
|
1128
|
+
return true;
|
|
1129
|
+
}
|
|
1130
|
+
}
|
|
1131
|
+
return false;
|
|
1132
|
+
}
|
|
1133
|
+
function nextJsonRpcId(prefix, allocate) {
|
|
1134
|
+
return `${prefix}:${allocate()}`;
|
|
1135
|
+
}
|
|
1136
|
+
function writeJsonRpcMessage(child, payload) {
|
|
1137
|
+
if (!child.stdin || child.stdin.destroyed || !child.stdin.writable) {
|
|
1138
|
+
throw new Error("CODEX_APP_SERVER_STDIN_UNAVAILABLE");
|
|
1139
|
+
}
|
|
1140
|
+
child.stdin.write(`${JSON.stringify(payload)}\n`, "utf8");
|
|
1141
|
+
}
|
|
1142
|
+
function sendJsonRpcRequest(child, pendingResponses, createRequestId, input) {
|
|
1143
|
+
const id = createRequestId();
|
|
1144
|
+
return new Promise((resolve, reject) => {
|
|
1145
|
+
pendingResponses.set(id, { resolve, reject });
|
|
1146
|
+
try {
|
|
1147
|
+
writeJsonRpcMessage(child, {
|
|
1148
|
+
jsonrpc: "2.0",
|
|
1149
|
+
id,
|
|
1150
|
+
method: input.method,
|
|
1151
|
+
params: input.params
|
|
1152
|
+
});
|
|
1153
|
+
}
|
|
1154
|
+
catch (error) {
|
|
1155
|
+
pendingResponses.delete(id);
|
|
1156
|
+
reject(error instanceof Error ? error : new Error("CODEX_APP_SERVER_REQUEST_WRITE_FAILED"));
|
|
1157
|
+
}
|
|
1158
|
+
});
|
|
1159
|
+
}
|
|
1160
|
+
function readJsonRpcParams(parsed) {
|
|
1161
|
+
return toRecord(parsed.params) ?? {};
|
|
1162
|
+
}
|
|
1163
|
+
function readJsonRpcResult(parsed) {
|
|
1164
|
+
return toRecord(parsed.result) ?? {};
|
|
1165
|
+
}
|
|
524
1166
|
function resolveResumeThreadId(providerSessionId, rawStoreRef) {
|
|
525
1167
|
const normalizedProviderSessionId = ensureText(providerSessionId).trim();
|
|
526
1168
|
const fromRawStore = readThreadIdFromRawStore(rawStoreRef);
|
|
@@ -538,6 +1180,12 @@ function readProp(value, key) {
|
|
|
538
1180
|
}
|
|
539
1181
|
return value[key];
|
|
540
1182
|
}
|
|
1183
|
+
function toRecord(value) {
|
|
1184
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
1185
|
+
return null;
|
|
1186
|
+
}
|
|
1187
|
+
return value;
|
|
1188
|
+
}
|
|
541
1189
|
function ensureText(value) {
|
|
542
1190
|
if (typeof value === "string") {
|
|
543
1191
|
return value;
|
|
@@ -552,6 +1200,10 @@ function ensureText(value) {
|
|
|
552
1200
|
return String(value);
|
|
553
1201
|
}
|
|
554
1202
|
}
|
|
1203
|
+
function normalizeText(value) {
|
|
1204
|
+
const normalized = ensureText(value).trim();
|
|
1205
|
+
return normalized.length > 0 ? normalized : null;
|
|
1206
|
+
}
|
|
555
1207
|
function readThreadIdFromRawStore(rawStoreRef) {
|
|
556
1208
|
const filePath = ensureText(rawStoreRef).trim();
|
|
557
1209
|
if (!filePath || !existsSync(filePath)) {
|
|
@@ -683,9 +1335,14 @@ function pickFirstNonEmpty(...values) {
|
|
|
683
1335
|
}
|
|
684
1336
|
function isToolItem(itemType) {
|
|
685
1337
|
return (itemType === "command_execution" ||
|
|
1338
|
+
itemType === "file_change" ||
|
|
686
1339
|
itemType === "mcp_tool_call" ||
|
|
687
1340
|
itemType === "function_call" ||
|
|
688
|
-
itemType === "custom_tool_call"
|
|
1341
|
+
itemType === "custom_tool_call" ||
|
|
1342
|
+
itemType === "commandExecution" ||
|
|
1343
|
+
itemType === "fileChange" ||
|
|
1344
|
+
itemType === "mcpToolCall" ||
|
|
1345
|
+
itemType === "dynamicToolCall");
|
|
689
1346
|
}
|
|
690
1347
|
function inferToolSuccess(item, output) {
|
|
691
1348
|
const status = ensureText(readProp(item, "status")).trim().toLowerCase();
|
|
@@ -726,10 +1383,23 @@ function classifyCodexRuntimeFailure(error) {
|
|
|
726
1383
|
};
|
|
727
1384
|
}
|
|
728
1385
|
return {
|
|
729
|
-
errorCode: "CODEX_RUNTIME_ERROR",
|
|
1386
|
+
errorCode: classifyCodexDetailErrorCode(detail, "CODEX_RUNTIME_ERROR"),
|
|
730
1387
|
detail
|
|
731
1388
|
};
|
|
732
1389
|
}
|
|
1390
|
+
function classifyCodexDetailErrorCode(detail, fallback) {
|
|
1391
|
+
const normalized = detail.trim();
|
|
1392
|
+
if (!normalized) {
|
|
1393
|
+
return fallback;
|
|
1394
|
+
}
|
|
1395
|
+
const statusMatch = normalized.match(/\bstatus\s+(\d{3})\b/i)
|
|
1396
|
+
?? normalized.match(/\bHTTP\s+(\d{3})\b/i)
|
|
1397
|
+
?? normalized.match(/\b(\d{3})\s+(?:Bad Gateway|Too Many Requests|Gateway Timeout|Service Unavailable)\b/i);
|
|
1398
|
+
if (!statusMatch) {
|
|
1399
|
+
return fallback;
|
|
1400
|
+
}
|
|
1401
|
+
return `CODEX_HTTP_${statusMatch[1]}`;
|
|
1402
|
+
}
|
|
733
1403
|
function persistSyntheticUserMessageIfNeeded(rawStoreRef, providerSessionId, input) {
|
|
734
1404
|
if (!isSyntheticRawStoreRef(rawStoreRef) || input.content.trim().length === 0) {
|
|
735
1405
|
return;
|
|
@@ -889,4 +1559,37 @@ function mapToolStartItemType(itemType) {
|
|
|
889
1559
|
function mapToolResultItemType(itemType) {
|
|
890
1560
|
return itemType === "custom_tool_call" ? "custom_tool_call_output" : "function_call_output";
|
|
891
1561
|
}
|
|
1562
|
+
function normalizeCodexItemStatus(value) {
|
|
1563
|
+
const normalized = ensureText(value).trim();
|
|
1564
|
+
if (!normalized) {
|
|
1565
|
+
return "in_progress";
|
|
1566
|
+
}
|
|
1567
|
+
if (normalized === "inProgress") {
|
|
1568
|
+
return "running";
|
|
1569
|
+
}
|
|
1570
|
+
if (normalized === "declined") {
|
|
1571
|
+
return "failed";
|
|
1572
|
+
}
|
|
1573
|
+
return normalized;
|
|
1574
|
+
}
|
|
1575
|
+
function buildCodexFileChangeOutput(value) {
|
|
1576
|
+
if (!Array.isArray(value)) {
|
|
1577
|
+
return "";
|
|
1578
|
+
}
|
|
1579
|
+
return value
|
|
1580
|
+
.map((change) => {
|
|
1581
|
+
const record = toRecord(change);
|
|
1582
|
+
if (!record) {
|
|
1583
|
+
return "";
|
|
1584
|
+
}
|
|
1585
|
+
const diff = ensureText(record.diff).trim();
|
|
1586
|
+
if (diff.length > 0) {
|
|
1587
|
+
return diff;
|
|
1588
|
+
}
|
|
1589
|
+
const path = ensureText(record.path).trim();
|
|
1590
|
+
return path.length > 0 ? `Updated ${path}` : "";
|
|
1591
|
+
})
|
|
1592
|
+
.filter((entry) => entry.length > 0)
|
|
1593
|
+
.join("\n\n");
|
|
1594
|
+
}
|
|
892
1595
|
//# sourceMappingURL=codex-runtime.js.map
|