@jingyi0605/codingns 0.1.1 → 0.1.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/README.md +14 -0
- package/dist/public/assets/{TerminalPage-CVG1cGAJ.js → TerminalPage-Nq5sPc5c.js} +19 -19
- package/dist/public/assets/index-9hnprhO7.css +1 -0
- package/dist/public/assets/index-BTpmuKhG.js +108 -0
- package/dist/public/index.html +2 -2
- package/dist/server/config/env.js +24 -3
- 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 +17 -0
- package/dist/server/modules/sessions/codex-app-server-helper-client.js +260 -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 +4 -2
- package/dist/server/modules/sessions/session-history-service.js +167 -44
- package/dist/server/modules/sessions/session-history-service.js.map +1 -1
- package/dist/server/modules/sessions/session-live-runtime-service.d.ts +42 -4
- package/dist/server/modules/sessions/session-live-runtime-service.js +343 -51
- 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 +6 -2
- package/dist/server/modules/terminal/command-template-service.js +91 -5
- 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/template-reverse-proxy-service.d.ts +10 -0
- package/dist/server/modules/terminal/template-reverse-proxy-service.js +320 -0
- package/dist/server/modules/terminal/template-reverse-proxy-service.js.map +1 -0
- package/dist/server/modules/terminal/terminal-controller.d.ts +1 -0
- package/dist/server/modules/terminal/terminal-controller.js +23 -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 +48 -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/proxy.d.ts +3 -0
- package/dist/server/routes/proxy.js +24 -0
- package/dist/server/routes/proxy.js.map +1 -0
- 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 +29 -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/terminal-command-template-repository.d.ts +1 -0
- package/dist/server/storage/repositories/terminal-command-template-repository.js +34 -3
- package/dist/server/storage/repositories/terminal-command-template-repository.js.map +1 -1
- 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/client.js +27 -0
- package/dist/server/storage/sqlite/client.js.map +1 -1
- package/dist/server/storage/sqlite/schema.sql +15 -0
- package/dist/server/types/domain.d.ts +30 -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 +82 -44
- package/dist/server/ws/ws-server.js.map +1 -1
- package/node_modules/@codingns/session-sync-core/dist/claude-message-utils.js +42 -0
- 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 +167 -7
- 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 +31 -0
- 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 +15 -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 +85 -1
- 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 +25 -0
- package/node_modules/@codingns/session-sync-core/dist/runtime/codex-runtime.js +718 -17
- 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 +3 -0
- package/node_modules/@codingns/session-sync-core/dist/runtime/provider-runtime-service.js +19 -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 +3 -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 +3 -2
- package/scripts/postinstall.mjs +15 -8
- package/dist/public/assets/index-BUPByQPG.css +0 -1
- package/dist/public/assets/index-D1CwTkI2.js +0 -106
|
@@ -1,7 +1,9 @@
|
|
|
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";
|
|
6
8
|
import { fileURLToPath, pathToFileURL } from "node:url";
|
|
7
9
|
import { appendJsonLine, createRawRef, ensureDirectory, extractTextBlocks, messageIdFromRawRef, nextTimestamp, normalizeWorkspacePath } from "../providers/utils.js";
|
|
@@ -14,29 +16,70 @@ export class CodexRuntimeAdapter {
|
|
|
14
16
|
}
|
|
15
17
|
async startSession(request, sink) {
|
|
16
18
|
const launchedAtMs = Date.now();
|
|
17
|
-
const
|
|
18
|
-
|
|
19
|
+
const transport = this.options.transportFactory
|
|
20
|
+
? this.options.transportFactory()
|
|
21
|
+
: createCodexAppServerTransport(this.options);
|
|
22
|
+
await transport.initialize();
|
|
19
23
|
const abortController = new AbortController();
|
|
20
|
-
const
|
|
21
|
-
|
|
22
|
-
});
|
|
23
|
-
const events = streamed.events[Symbol.asyncIterator]();
|
|
24
|
-
const startedSession = await this.awaitThreadStarted(thread, events, request.workspacePath, request.options.content, launchedAtMs);
|
|
24
|
+
const eventQueue = createAsyncEventQueue();
|
|
25
|
+
const startedSession = await transport.startThread(request);
|
|
25
26
|
const providerSessionId = startedSession.providerSessionId;
|
|
26
|
-
const fallbackRawStoreRef =
|
|
27
|
+
const fallbackRawStoreRef = startedSession.rawStoreRef ??
|
|
28
|
+
request.rawStoreRef ??
|
|
29
|
+
buildRuntimeRawStoreRef(resolveRuntimeStoreKey(providerSessionId, request.sessionId));
|
|
27
30
|
const resolvedBinding = await this.resolveExistingSessionBinding(providerSessionId, fallbackRawStoreRef, request.workspacePath);
|
|
28
31
|
const rawStoreRef = resolvedBinding?.rawStoreRef ?? fallbackRawStoreRef;
|
|
29
32
|
sink.updateSessionBinding({
|
|
30
33
|
providerSessionId,
|
|
31
34
|
rawStoreRef
|
|
32
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
|
+
transport.setOnClose((error) => {
|
|
59
|
+
if (error) {
|
|
60
|
+
eventQueue.push({
|
|
61
|
+
type: "turn.failed",
|
|
62
|
+
timestamp: nextTimestamp(),
|
|
63
|
+
error: error.message
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
eventQueue.close();
|
|
67
|
+
});
|
|
68
|
+
await transport.startTurn(request, providerSessionId);
|
|
33
69
|
return {
|
|
34
70
|
providerSessionId,
|
|
35
71
|
rawStoreRef,
|
|
36
72
|
interrupt: async () => {
|
|
37
73
|
abortController.abort();
|
|
74
|
+
await transport.interruptTurn().catch(() => {
|
|
75
|
+
return;
|
|
76
|
+
});
|
|
77
|
+
transport.close();
|
|
38
78
|
},
|
|
39
|
-
|
|
79
|
+
isAlive: () => transport.isClosed() === false,
|
|
80
|
+
completed: this.runTurn(null, request, sink, providerSessionId, rawStoreRef, abortController, eventQueue.iterator, [], launchedAtMs).finally(() => {
|
|
81
|
+
transport.close();
|
|
82
|
+
})
|
|
40
83
|
};
|
|
41
84
|
}
|
|
42
85
|
async continueSession(request, sink) {
|
|
@@ -44,31 +87,77 @@ export class CodexRuntimeAdapter {
|
|
|
44
87
|
if (!providerSessionId) {
|
|
45
88
|
throw new Error("PROVIDER_SESSION_ID_REQUIRED");
|
|
46
89
|
}
|
|
47
|
-
const
|
|
48
|
-
|
|
90
|
+
const transport = this.options.transportFactory
|
|
91
|
+
? this.options.transportFactory()
|
|
92
|
+
: createCodexAppServerTransport(this.options);
|
|
93
|
+
await transport.initialize();
|
|
49
94
|
const fallbackRawStoreRef = request.rawStoreRef ?? buildRuntimeRawStoreRef(providerSessionId);
|
|
50
95
|
const resolvedBinding = await this.resolveExistingSessionBinding(providerSessionId, fallbackRawStoreRef, request.workspacePath);
|
|
51
96
|
const resolvedSessionId = resolvedBinding?.providerSessionId ?? providerSessionId;
|
|
52
|
-
const
|
|
97
|
+
const resumed = await transport.resumeThread(request, resolvedSessionId);
|
|
98
|
+
const rawStoreRef = resolvedBinding?.rawStoreRef ?? resumed.rawStoreRef ?? fallbackRawStoreRef;
|
|
53
99
|
const abortController = new AbortController();
|
|
100
|
+
const eventQueue = createAsyncEventQueue();
|
|
54
101
|
sink.updateSessionBinding({
|
|
55
102
|
providerSessionId: resolvedSessionId,
|
|
56
103
|
rawStoreRef
|
|
57
104
|
});
|
|
105
|
+
transport.setNotificationHandler(async (notification) => {
|
|
106
|
+
const translated = translateCodexAppServerNotification(notification);
|
|
107
|
+
if (translated.turnId) {
|
|
108
|
+
eventQueue.setTurnId(translated.turnId);
|
|
109
|
+
}
|
|
110
|
+
if (translated.event) {
|
|
111
|
+
eventQueue.push(translated.event);
|
|
112
|
+
}
|
|
113
|
+
if (translated.terminal) {
|
|
114
|
+
eventQueue.close();
|
|
115
|
+
}
|
|
116
|
+
});
|
|
117
|
+
transport.setServerRequestHandler(async (serverRequest) => {
|
|
118
|
+
if (!this.options.handleServerRequest) {
|
|
119
|
+
throw new Error("CODEX_APP_SERVER_REQUEST_NOT_SUPPORTED");
|
|
120
|
+
}
|
|
121
|
+
return this.options.handleServerRequest({
|
|
122
|
+
sessionId: request.sessionId,
|
|
123
|
+
providerSessionId: resolvedSessionId,
|
|
124
|
+
request: serverRequest
|
|
125
|
+
});
|
|
126
|
+
});
|
|
127
|
+
transport.setOnClose((error) => {
|
|
128
|
+
if (error) {
|
|
129
|
+
eventQueue.push({
|
|
130
|
+
type: "turn.failed",
|
|
131
|
+
timestamp: nextTimestamp(),
|
|
132
|
+
error: error.message
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
eventQueue.close();
|
|
136
|
+
});
|
|
137
|
+
await transport.startTurn(request, resolvedSessionId);
|
|
58
138
|
return {
|
|
59
139
|
providerSessionId: resolvedSessionId,
|
|
60
140
|
rawStoreRef,
|
|
61
141
|
interrupt: async () => {
|
|
62
142
|
abortController.abort();
|
|
143
|
+
await transport.interruptTurn().catch(() => {
|
|
144
|
+
return;
|
|
145
|
+
});
|
|
146
|
+
transport.close();
|
|
63
147
|
},
|
|
64
|
-
|
|
148
|
+
isAlive: () => transport.isClosed() === false,
|
|
149
|
+
completed: this.runTurn(null, request, sink, resolvedSessionId, rawStoreRef, abortController, eventQueue.iterator, [], Date.now()).finally(() => {
|
|
150
|
+
transport.close();
|
|
151
|
+
})
|
|
65
152
|
};
|
|
66
153
|
}
|
|
67
154
|
async runTurn(thread, request, sink, providerSessionId, rawStoreRef, abortController, preparedEvents, bufferedEvents = [], launchedAtMs = Date.now()) {
|
|
68
155
|
const context = {
|
|
69
156
|
providerSessionId,
|
|
70
157
|
rawStoreRef,
|
|
71
|
-
|
|
158
|
+
// 运行时消息必须接在历史消息后面,不能每轮都从 1 重新编号,
|
|
159
|
+
// 否则前端会把新 assistant/tool 消息排到旧消息前面,表现成用户消息一直挂在底部。
|
|
160
|
+
sequence: Math.max(0, request.sequenceBase ?? 0),
|
|
72
161
|
toolNameByCallId: new Map(),
|
|
73
162
|
sink,
|
|
74
163
|
workspacePath: request.workspacePath,
|
|
@@ -148,12 +237,23 @@ export class CodexRuntimeAdapter {
|
|
|
148
237
|
status: "failed",
|
|
149
238
|
providerSessionId: context.providerSessionId,
|
|
150
239
|
rawStoreRef: context.rawStoreRef,
|
|
151
|
-
errorCode: "CODEX_CLI_TURN_FAILED",
|
|
240
|
+
errorCode: classifyCodexDetailErrorCode(detail, "CODEX_CLI_TURN_FAILED"),
|
|
152
241
|
detail,
|
|
153
242
|
timestamp: pickTimestamp(event)
|
|
154
243
|
});
|
|
155
244
|
return;
|
|
156
245
|
}
|
|
246
|
+
if (eventType === "turn.interrupted") {
|
|
247
|
+
await context.sink.emit({
|
|
248
|
+
type: "interrupted",
|
|
249
|
+
status: "interrupted",
|
|
250
|
+
providerSessionId: context.providerSessionId,
|
|
251
|
+
rawStoreRef: context.rawStoreRef,
|
|
252
|
+
detail: "codex turn interrupted",
|
|
253
|
+
timestamp: pickTimestamp(event)
|
|
254
|
+
});
|
|
255
|
+
return;
|
|
256
|
+
}
|
|
157
257
|
if (interrupted) {
|
|
158
258
|
return;
|
|
159
259
|
}
|
|
@@ -451,6 +551,400 @@ export class CodexRuntimeAdapter {
|
|
|
451
551
|
}
|
|
452
552
|
}
|
|
453
553
|
}
|
|
554
|
+
function createCodexAppServerTransport(options) {
|
|
555
|
+
const commandPath = resolveCodexCommand(options.commandPath);
|
|
556
|
+
const launch = resolveCodexCommandLaunch(commandPath, ["app-server"]);
|
|
557
|
+
const child = spawn(launch.command, launch.args, {
|
|
558
|
+
env: process.env,
|
|
559
|
+
stdio: ["pipe", "pipe", "pipe"],
|
|
560
|
+
shell: launch.shell,
|
|
561
|
+
windowsHide: true
|
|
562
|
+
});
|
|
563
|
+
const stdout = createInterface({ input: child.stdout });
|
|
564
|
+
let notificationHandler = () => undefined;
|
|
565
|
+
let serverRequestHandler = async () => {
|
|
566
|
+
throw new Error("CODEX_APP_SERVER_REQUEST_NOT_SUPPORTED");
|
|
567
|
+
};
|
|
568
|
+
let requestSequence = 0;
|
|
569
|
+
let closed = false;
|
|
570
|
+
let activeTurnId = null;
|
|
571
|
+
let activeThreadId = null;
|
|
572
|
+
let closeHandler = null;
|
|
573
|
+
const pendingResponses = new Map();
|
|
574
|
+
const finalize = (error) => {
|
|
575
|
+
if (closed) {
|
|
576
|
+
return;
|
|
577
|
+
}
|
|
578
|
+
closed = true;
|
|
579
|
+
stdout.close();
|
|
580
|
+
for (const pending of pendingResponses.values()) {
|
|
581
|
+
pending.reject(error ?? new Error("CODEX_APP_SERVER_CLOSED"));
|
|
582
|
+
}
|
|
583
|
+
pendingResponses.clear();
|
|
584
|
+
closeHandler?.(error);
|
|
585
|
+
};
|
|
586
|
+
child.on("error", (error) => {
|
|
587
|
+
finalize(error);
|
|
588
|
+
});
|
|
589
|
+
child.on("exit", (code, signal) => {
|
|
590
|
+
if (closed) {
|
|
591
|
+
return;
|
|
592
|
+
}
|
|
593
|
+
const detail = signal
|
|
594
|
+
? `codex app-server exited with signal ${signal}`
|
|
595
|
+
: `codex app-server exited with code ${String(code ?? "unknown")}`;
|
|
596
|
+
finalize(new Error(detail));
|
|
597
|
+
});
|
|
598
|
+
stdout.on("line", (line) => {
|
|
599
|
+
const trimmed = line.trim();
|
|
600
|
+
if (!trimmed) {
|
|
601
|
+
return;
|
|
602
|
+
}
|
|
603
|
+
let parsed;
|
|
604
|
+
try {
|
|
605
|
+
parsed = JSON.parse(trimmed);
|
|
606
|
+
}
|
|
607
|
+
catch {
|
|
608
|
+
return;
|
|
609
|
+
}
|
|
610
|
+
if (typeof parsed.method === "string" && parsed.id !== undefined) {
|
|
611
|
+
void Promise.resolve(serverRequestHandler(parsed))
|
|
612
|
+
.then((result) => {
|
|
613
|
+
writeJsonRpcMessage(child, {
|
|
614
|
+
jsonrpc: "2.0",
|
|
615
|
+
id: parsed.id,
|
|
616
|
+
result
|
|
617
|
+
});
|
|
618
|
+
})
|
|
619
|
+
.catch((error) => {
|
|
620
|
+
writeJsonRpcMessage(child, {
|
|
621
|
+
jsonrpc: "2.0",
|
|
622
|
+
id: parsed.id,
|
|
623
|
+
error: {
|
|
624
|
+
code: -32000,
|
|
625
|
+
message: error instanceof Error ? error.message : "CODEX_APP_SERVER_REQUEST_FAILED"
|
|
626
|
+
}
|
|
627
|
+
});
|
|
628
|
+
});
|
|
629
|
+
return;
|
|
630
|
+
}
|
|
631
|
+
if (typeof parsed.method === "string") {
|
|
632
|
+
const method = parsed.method.trim();
|
|
633
|
+
const params = readJsonRpcParams(parsed);
|
|
634
|
+
if (method === "turn/started") {
|
|
635
|
+
activeTurnId = ensureText(readProp(readProp(params, "turn"), "id")).trim() || activeTurnId;
|
|
636
|
+
}
|
|
637
|
+
if (method === "thread/started") {
|
|
638
|
+
activeThreadId = ensureText(readProp(readProp(params, "thread"), "id")).trim() || activeThreadId;
|
|
639
|
+
}
|
|
640
|
+
void notificationHandler({
|
|
641
|
+
method,
|
|
642
|
+
params
|
|
643
|
+
});
|
|
644
|
+
return;
|
|
645
|
+
}
|
|
646
|
+
const responseId = String(parsed.id ?? "");
|
|
647
|
+
const pending = pendingResponses.get(responseId);
|
|
648
|
+
if (!pending) {
|
|
649
|
+
return;
|
|
650
|
+
}
|
|
651
|
+
pendingResponses.delete(responseId);
|
|
652
|
+
if (parsed.error && typeof parsed.error === "object") {
|
|
653
|
+
const message = ensureText(readProp(parsed.error, "message")).trim() || "CODEX_APP_SERVER_ERROR";
|
|
654
|
+
pending.reject(new Error(message));
|
|
655
|
+
return;
|
|
656
|
+
}
|
|
657
|
+
pending.resolve(readJsonRpcResult(parsed));
|
|
658
|
+
});
|
|
659
|
+
return {
|
|
660
|
+
async initialize() {
|
|
661
|
+
await sendJsonRpcRequest(child, pendingResponses, () => nextJsonRpcId("initialize", () => ++requestSequence), {
|
|
662
|
+
method: "initialize",
|
|
663
|
+
params: {
|
|
664
|
+
clientInfo: {
|
|
665
|
+
name: "codingns-runtime",
|
|
666
|
+
version: "0.0.0"
|
|
667
|
+
},
|
|
668
|
+
capabilities: null
|
|
669
|
+
}
|
|
670
|
+
});
|
|
671
|
+
writeJsonRpcMessage(child, {
|
|
672
|
+
jsonrpc: "2.0",
|
|
673
|
+
method: "initialized",
|
|
674
|
+
params: {}
|
|
675
|
+
});
|
|
676
|
+
},
|
|
677
|
+
async startThread(request) {
|
|
678
|
+
const result = await sendJsonRpcRequest(child, pendingResponses, () => nextJsonRpcId("thread-start", () => ++requestSequence), {
|
|
679
|
+
method: "thread/start",
|
|
680
|
+
params: createThreadStartParams(request)
|
|
681
|
+
});
|
|
682
|
+
const thread = toRecord(result.thread);
|
|
683
|
+
const providerSessionId = ensureText(thread?.id).trim();
|
|
684
|
+
if (!providerSessionId) {
|
|
685
|
+
throw new Error("CODEX_APP_SERVER_THREAD_ID_MISSING");
|
|
686
|
+
}
|
|
687
|
+
activeThreadId = providerSessionId;
|
|
688
|
+
return {
|
|
689
|
+
providerSessionId,
|
|
690
|
+
rawStoreRef: normalizeText(thread?.path) || null
|
|
691
|
+
};
|
|
692
|
+
},
|
|
693
|
+
async resumeThread(request, providerSessionId) {
|
|
694
|
+
const result = await sendJsonRpcRequest(child, pendingResponses, () => nextJsonRpcId("thread-resume", () => ++requestSequence), {
|
|
695
|
+
method: "thread/resume",
|
|
696
|
+
params: createThreadResumeParams(request, providerSessionId)
|
|
697
|
+
});
|
|
698
|
+
const thread = toRecord(result.thread);
|
|
699
|
+
activeThreadId = ensureText(thread?.id).trim() || providerSessionId;
|
|
700
|
+
return {
|
|
701
|
+
providerSessionId: activeThreadId,
|
|
702
|
+
rawStoreRef: normalizeText(thread?.path) || null
|
|
703
|
+
};
|
|
704
|
+
},
|
|
705
|
+
async startTurn(request, providerSessionId) {
|
|
706
|
+
const result = await sendJsonRpcRequest(child, pendingResponses, () => nextJsonRpcId("turn-start", () => ++requestSequence), {
|
|
707
|
+
method: "turn/start",
|
|
708
|
+
params: createTurnStartParams(request, providerSessionId)
|
|
709
|
+
});
|
|
710
|
+
activeTurnId = ensureText(readProp(readProp(result, "turn"), "id")).trim() || activeTurnId;
|
|
711
|
+
},
|
|
712
|
+
async interruptTurn() {
|
|
713
|
+
if (!activeThreadId || !activeTurnId) {
|
|
714
|
+
return;
|
|
715
|
+
}
|
|
716
|
+
await sendJsonRpcRequest(child, pendingResponses, () => nextJsonRpcId("turn-interrupt", () => ++requestSequence), {
|
|
717
|
+
method: "turn/interrupt",
|
|
718
|
+
params: {
|
|
719
|
+
threadId: activeThreadId,
|
|
720
|
+
turnId: activeTurnId
|
|
721
|
+
}
|
|
722
|
+
});
|
|
723
|
+
},
|
|
724
|
+
setNotificationHandler(handler) {
|
|
725
|
+
notificationHandler = handler;
|
|
726
|
+
},
|
|
727
|
+
setServerRequestHandler(handler) {
|
|
728
|
+
serverRequestHandler = handler;
|
|
729
|
+
},
|
|
730
|
+
setOnClose(handler) {
|
|
731
|
+
closeHandler = handler;
|
|
732
|
+
},
|
|
733
|
+
isClosed() {
|
|
734
|
+
return closed;
|
|
735
|
+
},
|
|
736
|
+
close() {
|
|
737
|
+
if (closed) {
|
|
738
|
+
return;
|
|
739
|
+
}
|
|
740
|
+
finalize(null);
|
|
741
|
+
if (!child.stdin.destroyed) {
|
|
742
|
+
child.stdin.end();
|
|
743
|
+
}
|
|
744
|
+
if (!child.killed) {
|
|
745
|
+
child.kill("SIGTERM");
|
|
746
|
+
}
|
|
747
|
+
}
|
|
748
|
+
};
|
|
749
|
+
}
|
|
750
|
+
function createAsyncEventQueue() {
|
|
751
|
+
const values = [];
|
|
752
|
+
const waiters = [];
|
|
753
|
+
let closed = false;
|
|
754
|
+
let turnId = null;
|
|
755
|
+
return {
|
|
756
|
+
iterator: {
|
|
757
|
+
next() {
|
|
758
|
+
if (values.length > 0) {
|
|
759
|
+
return Promise.resolve({
|
|
760
|
+
done: false,
|
|
761
|
+
value: values.shift()
|
|
762
|
+
});
|
|
763
|
+
}
|
|
764
|
+
if (closed) {
|
|
765
|
+
return Promise.resolve({
|
|
766
|
+
done: true,
|
|
767
|
+
value: undefined
|
|
768
|
+
});
|
|
769
|
+
}
|
|
770
|
+
return new Promise((resolve) => {
|
|
771
|
+
waiters.push(resolve);
|
|
772
|
+
});
|
|
773
|
+
}
|
|
774
|
+
},
|
|
775
|
+
push(value) {
|
|
776
|
+
if (closed) {
|
|
777
|
+
return;
|
|
778
|
+
}
|
|
779
|
+
const waiter = waiters.shift();
|
|
780
|
+
if (waiter) {
|
|
781
|
+
waiter({
|
|
782
|
+
done: false,
|
|
783
|
+
value
|
|
784
|
+
});
|
|
785
|
+
return;
|
|
786
|
+
}
|
|
787
|
+
values.push(value);
|
|
788
|
+
},
|
|
789
|
+
close() {
|
|
790
|
+
if (closed) {
|
|
791
|
+
return;
|
|
792
|
+
}
|
|
793
|
+
closed = true;
|
|
794
|
+
while (waiters.length > 0) {
|
|
795
|
+
waiters.shift()?.({
|
|
796
|
+
done: true,
|
|
797
|
+
value: undefined
|
|
798
|
+
});
|
|
799
|
+
}
|
|
800
|
+
},
|
|
801
|
+
setTurnId(nextTurnId) {
|
|
802
|
+
turnId = nextTurnId;
|
|
803
|
+
},
|
|
804
|
+
getTurnId() {
|
|
805
|
+
return turnId;
|
|
806
|
+
}
|
|
807
|
+
};
|
|
808
|
+
}
|
|
809
|
+
function translateCodexAppServerNotification(notification) {
|
|
810
|
+
const method = ensureText(notification.method).trim();
|
|
811
|
+
const params = toRecord(notification.params) ?? {};
|
|
812
|
+
if (method === "turn/started") {
|
|
813
|
+
return {
|
|
814
|
+
event: null,
|
|
815
|
+
terminal: false,
|
|
816
|
+
turnId: ensureText(readProp(readProp(params, "turn"), "id")).trim() || null
|
|
817
|
+
};
|
|
818
|
+
}
|
|
819
|
+
if (method === "turn/completed") {
|
|
820
|
+
const turn = toRecord(params.turn);
|
|
821
|
+
const status = ensureText(turn?.status).trim();
|
|
822
|
+
if (status === "failed") {
|
|
823
|
+
return {
|
|
824
|
+
event: {
|
|
825
|
+
type: "turn.failed",
|
|
826
|
+
timestamp: nextTimestamp(),
|
|
827
|
+
error: ensureText(readProp(turn?.error, "message")).trim() || "codex turn failed"
|
|
828
|
+
},
|
|
829
|
+
terminal: true,
|
|
830
|
+
turnId: ensureText(turn?.id).trim() || null
|
|
831
|
+
};
|
|
832
|
+
}
|
|
833
|
+
if (status === "interrupted") {
|
|
834
|
+
return {
|
|
835
|
+
event: {
|
|
836
|
+
type: "turn.interrupted",
|
|
837
|
+
timestamp: nextTimestamp()
|
|
838
|
+
},
|
|
839
|
+
terminal: true,
|
|
840
|
+
turnId: ensureText(turn?.id).trim() || null
|
|
841
|
+
};
|
|
842
|
+
}
|
|
843
|
+
return {
|
|
844
|
+
event: {
|
|
845
|
+
type: "turn.completed",
|
|
846
|
+
timestamp: nextTimestamp()
|
|
847
|
+
},
|
|
848
|
+
terminal: true,
|
|
849
|
+
turnId: ensureText(turn?.id).trim() || null
|
|
850
|
+
};
|
|
851
|
+
}
|
|
852
|
+
if (method === "item/started" || method === "item/completed") {
|
|
853
|
+
const item = translateCodexAppServerItem(toRecord(params.item));
|
|
854
|
+
if (!item) {
|
|
855
|
+
return {
|
|
856
|
+
event: null,
|
|
857
|
+
terminal: false,
|
|
858
|
+
turnId: null
|
|
859
|
+
};
|
|
860
|
+
}
|
|
861
|
+
return {
|
|
862
|
+
event: {
|
|
863
|
+
type: method === "item/started" ? "item.started" : "item.completed",
|
|
864
|
+
item,
|
|
865
|
+
timestamp: nextTimestamp()
|
|
866
|
+
},
|
|
867
|
+
terminal: false,
|
|
868
|
+
turnId: null
|
|
869
|
+
};
|
|
870
|
+
}
|
|
871
|
+
return {
|
|
872
|
+
event: null,
|
|
873
|
+
terminal: false,
|
|
874
|
+
turnId: null
|
|
875
|
+
};
|
|
876
|
+
}
|
|
877
|
+
function translateCodexAppServerItem(item) {
|
|
878
|
+
if (!item) {
|
|
879
|
+
return null;
|
|
880
|
+
}
|
|
881
|
+
const itemType = ensureText(item.type).trim();
|
|
882
|
+
if (!itemType) {
|
|
883
|
+
return null;
|
|
884
|
+
}
|
|
885
|
+
if (itemType === "agentMessage") {
|
|
886
|
+
return {
|
|
887
|
+
type: "agent_message",
|
|
888
|
+
id: item.id,
|
|
889
|
+
text: item.text
|
|
890
|
+
};
|
|
891
|
+
}
|
|
892
|
+
if (itemType === "reasoning") {
|
|
893
|
+
return {
|
|
894
|
+
type: "reasoning",
|
|
895
|
+
id: item.id,
|
|
896
|
+
text: Array.isArray(item.content) ? item.content.join("\n") : "",
|
|
897
|
+
summary: Array.isArray(item.summary) ? item.summary.join("\n") : ""
|
|
898
|
+
};
|
|
899
|
+
}
|
|
900
|
+
if (itemType === "commandExecution") {
|
|
901
|
+
return {
|
|
902
|
+
type: "command_execution",
|
|
903
|
+
id: item.id,
|
|
904
|
+
command: item.command,
|
|
905
|
+
cwd: item.cwd,
|
|
906
|
+
status: normalizeCodexItemStatus(item.status),
|
|
907
|
+
commandActions: item.commandActions,
|
|
908
|
+
aggregated_output: item.aggregatedOutput,
|
|
909
|
+
exit_code: item.exitCode
|
|
910
|
+
};
|
|
911
|
+
}
|
|
912
|
+
if (itemType === "fileChange") {
|
|
913
|
+
const diffText = buildCodexFileChangeOutput(item.changes);
|
|
914
|
+
return {
|
|
915
|
+
type: "custom_tool_call",
|
|
916
|
+
id: item.id,
|
|
917
|
+
tool: "apply_patch",
|
|
918
|
+
input: diffText,
|
|
919
|
+
output: diffText,
|
|
920
|
+
status: normalizeCodexItemStatus(item.status)
|
|
921
|
+
};
|
|
922
|
+
}
|
|
923
|
+
if (itemType === "mcpToolCall") {
|
|
924
|
+
return {
|
|
925
|
+
type: "mcp_tool_call",
|
|
926
|
+
id: item.id,
|
|
927
|
+
tool: item.tool,
|
|
928
|
+
server: item.server,
|
|
929
|
+
arguments: item.arguments,
|
|
930
|
+
result: item.result,
|
|
931
|
+
error: item.error,
|
|
932
|
+
status: normalizeCodexItemStatus(item.status)
|
|
933
|
+
};
|
|
934
|
+
}
|
|
935
|
+
if (itemType === "dynamicToolCall") {
|
|
936
|
+
return {
|
|
937
|
+
type: "custom_tool_call",
|
|
938
|
+
id: item.id,
|
|
939
|
+
tool: item.tool,
|
|
940
|
+
input: item.arguments,
|
|
941
|
+
output: item.contentItems,
|
|
942
|
+
success: item.success,
|
|
943
|
+
status: normalizeCodexItemStatus(item.status)
|
|
944
|
+
};
|
|
945
|
+
}
|
|
946
|
+
return null;
|
|
947
|
+
}
|
|
454
948
|
export function createThreadOptions(request) {
|
|
455
949
|
const options = {
|
|
456
950
|
workingDirectory: request.workspacePath,
|
|
@@ -470,6 +964,61 @@ export function createThreadOptions(request) {
|
|
|
470
964
|
}
|
|
471
965
|
return options;
|
|
472
966
|
}
|
|
967
|
+
function createThreadStartParams(request) {
|
|
968
|
+
const permissionOptions = createCodexThreadPermissionOptions(request.options.permissionMode ?? "default");
|
|
969
|
+
const params = {
|
|
970
|
+
cwd: request.workspacePath,
|
|
971
|
+
approvalsReviewer: "user"
|
|
972
|
+
};
|
|
973
|
+
if (permissionOptions.approvalPolicy) {
|
|
974
|
+
params.approvalPolicy = permissionOptions.approvalPolicy;
|
|
975
|
+
}
|
|
976
|
+
if (permissionOptions.sandboxMode) {
|
|
977
|
+
params.sandbox = permissionOptions.sandboxMode;
|
|
978
|
+
}
|
|
979
|
+
if (request.options.model) {
|
|
980
|
+
params.model = request.options.model;
|
|
981
|
+
}
|
|
982
|
+
return params;
|
|
983
|
+
}
|
|
984
|
+
function createThreadResumeParams(request, providerSessionId) {
|
|
985
|
+
const permissionOptions = createCodexThreadPermissionOptions(request.options.permissionMode ?? "default");
|
|
986
|
+
const params = {
|
|
987
|
+
threadId: providerSessionId,
|
|
988
|
+
cwd: request.workspacePath,
|
|
989
|
+
approvalsReviewer: "user"
|
|
990
|
+
};
|
|
991
|
+
if (permissionOptions.approvalPolicy) {
|
|
992
|
+
params.approvalPolicy = permissionOptions.approvalPolicy;
|
|
993
|
+
}
|
|
994
|
+
if (permissionOptions.sandboxMode) {
|
|
995
|
+
params.sandbox = permissionOptions.sandboxMode;
|
|
996
|
+
}
|
|
997
|
+
if (request.options.model) {
|
|
998
|
+
params.model = request.options.model;
|
|
999
|
+
}
|
|
1000
|
+
return params;
|
|
1001
|
+
}
|
|
1002
|
+
function createTurnStartParams(request, providerSessionId) {
|
|
1003
|
+
const permissionOptions = createCodexThreadPermissionOptions(request.options.permissionMode ?? "default");
|
|
1004
|
+
const params = {
|
|
1005
|
+
threadId: providerSessionId,
|
|
1006
|
+
input: createCodexAppServerInput(request),
|
|
1007
|
+
cwd: request.workspacePath,
|
|
1008
|
+
approvalsReviewer: "user"
|
|
1009
|
+
};
|
|
1010
|
+
if (permissionOptions.approvalPolicy) {
|
|
1011
|
+
params.approvalPolicy = permissionOptions.approvalPolicy;
|
|
1012
|
+
}
|
|
1013
|
+
if (request.options.model) {
|
|
1014
|
+
params.model = request.options.model;
|
|
1015
|
+
}
|
|
1016
|
+
const reasoningEffort = normalizeCodexReasoningEffort(request.options.reasoningLevel);
|
|
1017
|
+
if (reasoningEffort) {
|
|
1018
|
+
params.effort = reasoningEffort;
|
|
1019
|
+
}
|
|
1020
|
+
return params;
|
|
1021
|
+
}
|
|
473
1022
|
function normalizeCodexReasoningEffort(value) {
|
|
474
1023
|
const normalized = value?.trim().toLowerCase() ?? null;
|
|
475
1024
|
if (!normalized) {
|
|
@@ -507,6 +1056,23 @@ function createCodexInput(request) {
|
|
|
507
1056
|
});
|
|
508
1057
|
return input;
|
|
509
1058
|
}
|
|
1059
|
+
function createCodexAppServerInput(request) {
|
|
1060
|
+
const input = [];
|
|
1061
|
+
const promptText = (request.options.providerPrompt ?? request.options.content).trim();
|
|
1062
|
+
if (promptText.length > 0) {
|
|
1063
|
+
input.push({
|
|
1064
|
+
type: "text",
|
|
1065
|
+
text: promptText
|
|
1066
|
+
});
|
|
1067
|
+
}
|
|
1068
|
+
for (const attachment of request.options.attachments) {
|
|
1069
|
+
input.push({
|
|
1070
|
+
type: "localImage",
|
|
1071
|
+
path: attachment.filePath
|
|
1072
|
+
});
|
|
1073
|
+
}
|
|
1074
|
+
return input;
|
|
1075
|
+
}
|
|
510
1076
|
async function loadCodexClient() {
|
|
511
1077
|
const moduleName = "@openai/codex-sdk";
|
|
512
1078
|
const runtimeImport = new Function("name", "return import(name);");
|
|
@@ -553,6 +1119,80 @@ function buildRuntimeRawStoreRef(providerSessionId) {
|
|
|
553
1119
|
function resolveRuntimeStoreKey(providerSessionId, sessionId) {
|
|
554
1120
|
return providerSessionId.trim() || sessionId;
|
|
555
1121
|
}
|
|
1122
|
+
function resolveCodexCommand(explicitPath) {
|
|
1123
|
+
const explicitCandidate = explicitPath?.trim() ||
|
|
1124
|
+
process.env.CODINGNS_CODEX_COMMAND?.trim() ||
|
|
1125
|
+
"codex";
|
|
1126
|
+
return explicitCandidate;
|
|
1127
|
+
}
|
|
1128
|
+
function resolveCodexCommandLaunch(commandPath, args) {
|
|
1129
|
+
const normalizedCommandPath = commandPath.trim();
|
|
1130
|
+
if (isNodeScriptPath(normalizedCommandPath)) {
|
|
1131
|
+
return {
|
|
1132
|
+
command: process.execPath,
|
|
1133
|
+
args: [normalizedCommandPath, ...args],
|
|
1134
|
+
shell: false
|
|
1135
|
+
};
|
|
1136
|
+
}
|
|
1137
|
+
return {
|
|
1138
|
+
command: normalizedCommandPath,
|
|
1139
|
+
args: [...args],
|
|
1140
|
+
shell: shouldSpawnViaShellOnWindows(normalizedCommandPath)
|
|
1141
|
+
};
|
|
1142
|
+
}
|
|
1143
|
+
function isNodeScriptPath(commandPath) {
|
|
1144
|
+
return /\.(?:c|m)?js$/i.test(commandPath);
|
|
1145
|
+
}
|
|
1146
|
+
function shouldSpawnViaShellOnWindows(commandPath) {
|
|
1147
|
+
if (process.platform !== "win32") {
|
|
1148
|
+
return false;
|
|
1149
|
+
}
|
|
1150
|
+
if (/\.(cmd|bat)$/i.test(commandPath)) {
|
|
1151
|
+
return true;
|
|
1152
|
+
}
|
|
1153
|
+
// Windows 上裸名命令(无扩展名、无路径分隔符)需要 shell 才能从 PATH 解析 .cmd 文件
|
|
1154
|
+
const extension = commandPath.split(".").pop()?.toLowerCase();
|
|
1155
|
+
const hasPathSep = commandPath.includes("\\") || commandPath.includes("/");
|
|
1156
|
+
if (!extension || extension === commandPath.toLowerCase()) {
|
|
1157
|
+
if (!hasPathSep) {
|
|
1158
|
+
return true;
|
|
1159
|
+
}
|
|
1160
|
+
}
|
|
1161
|
+
return false;
|
|
1162
|
+
}
|
|
1163
|
+
function nextJsonRpcId(prefix, allocate) {
|
|
1164
|
+
return `${prefix}:${allocate()}`;
|
|
1165
|
+
}
|
|
1166
|
+
function writeJsonRpcMessage(child, payload) {
|
|
1167
|
+
if (!child.stdin || child.stdin.destroyed || !child.stdin.writable) {
|
|
1168
|
+
throw new Error("CODEX_APP_SERVER_STDIN_UNAVAILABLE");
|
|
1169
|
+
}
|
|
1170
|
+
child.stdin.write(`${JSON.stringify(payload)}\n`, "utf8");
|
|
1171
|
+
}
|
|
1172
|
+
function sendJsonRpcRequest(child, pendingResponses, createRequestId, input) {
|
|
1173
|
+
const id = createRequestId();
|
|
1174
|
+
return new Promise((resolve, reject) => {
|
|
1175
|
+
pendingResponses.set(id, { resolve, reject });
|
|
1176
|
+
try {
|
|
1177
|
+
writeJsonRpcMessage(child, {
|
|
1178
|
+
jsonrpc: "2.0",
|
|
1179
|
+
id,
|
|
1180
|
+
method: input.method,
|
|
1181
|
+
params: input.params
|
|
1182
|
+
});
|
|
1183
|
+
}
|
|
1184
|
+
catch (error) {
|
|
1185
|
+
pendingResponses.delete(id);
|
|
1186
|
+
reject(error instanceof Error ? error : new Error("CODEX_APP_SERVER_REQUEST_WRITE_FAILED"));
|
|
1187
|
+
}
|
|
1188
|
+
});
|
|
1189
|
+
}
|
|
1190
|
+
function readJsonRpcParams(parsed) {
|
|
1191
|
+
return toRecord(parsed.params) ?? {};
|
|
1192
|
+
}
|
|
1193
|
+
function readJsonRpcResult(parsed) {
|
|
1194
|
+
return toRecord(parsed.result) ?? {};
|
|
1195
|
+
}
|
|
556
1196
|
function resolveResumeThreadId(providerSessionId, rawStoreRef) {
|
|
557
1197
|
const normalizedProviderSessionId = ensureText(providerSessionId).trim();
|
|
558
1198
|
const fromRawStore = readThreadIdFromRawStore(rawStoreRef);
|
|
@@ -570,6 +1210,12 @@ function readProp(value, key) {
|
|
|
570
1210
|
}
|
|
571
1211
|
return value[key];
|
|
572
1212
|
}
|
|
1213
|
+
function toRecord(value) {
|
|
1214
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
1215
|
+
return null;
|
|
1216
|
+
}
|
|
1217
|
+
return value;
|
|
1218
|
+
}
|
|
573
1219
|
function ensureText(value) {
|
|
574
1220
|
if (typeof value === "string") {
|
|
575
1221
|
return value;
|
|
@@ -584,6 +1230,10 @@ function ensureText(value) {
|
|
|
584
1230
|
return String(value);
|
|
585
1231
|
}
|
|
586
1232
|
}
|
|
1233
|
+
function normalizeText(value) {
|
|
1234
|
+
const normalized = ensureText(value).trim();
|
|
1235
|
+
return normalized.length > 0 ? normalized : null;
|
|
1236
|
+
}
|
|
587
1237
|
function readThreadIdFromRawStore(rawStoreRef) {
|
|
588
1238
|
const filePath = ensureText(rawStoreRef).trim();
|
|
589
1239
|
if (!filePath || !existsSync(filePath)) {
|
|
@@ -715,9 +1365,14 @@ function pickFirstNonEmpty(...values) {
|
|
|
715
1365
|
}
|
|
716
1366
|
function isToolItem(itemType) {
|
|
717
1367
|
return (itemType === "command_execution" ||
|
|
1368
|
+
itemType === "file_change" ||
|
|
718
1369
|
itemType === "mcp_tool_call" ||
|
|
719
1370
|
itemType === "function_call" ||
|
|
720
|
-
itemType === "custom_tool_call"
|
|
1371
|
+
itemType === "custom_tool_call" ||
|
|
1372
|
+
itemType === "commandExecution" ||
|
|
1373
|
+
itemType === "fileChange" ||
|
|
1374
|
+
itemType === "mcpToolCall" ||
|
|
1375
|
+
itemType === "dynamicToolCall");
|
|
721
1376
|
}
|
|
722
1377
|
function inferToolSuccess(item, output) {
|
|
723
1378
|
const status = ensureText(readProp(item, "status")).trim().toLowerCase();
|
|
@@ -758,10 +1413,23 @@ function classifyCodexRuntimeFailure(error) {
|
|
|
758
1413
|
};
|
|
759
1414
|
}
|
|
760
1415
|
return {
|
|
761
|
-
errorCode: "CODEX_RUNTIME_ERROR",
|
|
1416
|
+
errorCode: classifyCodexDetailErrorCode(detail, "CODEX_RUNTIME_ERROR"),
|
|
762
1417
|
detail
|
|
763
1418
|
};
|
|
764
1419
|
}
|
|
1420
|
+
function classifyCodexDetailErrorCode(detail, fallback) {
|
|
1421
|
+
const normalized = detail.trim();
|
|
1422
|
+
if (!normalized) {
|
|
1423
|
+
return fallback;
|
|
1424
|
+
}
|
|
1425
|
+
const statusMatch = normalized.match(/\bstatus\s+(\d{3})\b/i)
|
|
1426
|
+
?? normalized.match(/\bHTTP\s+(\d{3})\b/i)
|
|
1427
|
+
?? normalized.match(/\b(\d{3})\s+(?:Bad Gateway|Too Many Requests|Gateway Timeout|Service Unavailable)\b/i);
|
|
1428
|
+
if (!statusMatch) {
|
|
1429
|
+
return fallback;
|
|
1430
|
+
}
|
|
1431
|
+
return `CODEX_HTTP_${statusMatch[1]}`;
|
|
1432
|
+
}
|
|
765
1433
|
function persistSyntheticUserMessageIfNeeded(rawStoreRef, providerSessionId, input) {
|
|
766
1434
|
if (!isSyntheticRawStoreRef(rawStoreRef) || input.content.trim().length === 0) {
|
|
767
1435
|
return;
|
|
@@ -921,4 +1589,37 @@ function mapToolStartItemType(itemType) {
|
|
|
921
1589
|
function mapToolResultItemType(itemType) {
|
|
922
1590
|
return itemType === "custom_tool_call" ? "custom_tool_call_output" : "function_call_output";
|
|
923
1591
|
}
|
|
1592
|
+
function normalizeCodexItemStatus(value) {
|
|
1593
|
+
const normalized = ensureText(value).trim();
|
|
1594
|
+
if (!normalized) {
|
|
1595
|
+
return "in_progress";
|
|
1596
|
+
}
|
|
1597
|
+
if (normalized === "inProgress") {
|
|
1598
|
+
return "running";
|
|
1599
|
+
}
|
|
1600
|
+
if (normalized === "declined") {
|
|
1601
|
+
return "failed";
|
|
1602
|
+
}
|
|
1603
|
+
return normalized;
|
|
1604
|
+
}
|
|
1605
|
+
function buildCodexFileChangeOutput(value) {
|
|
1606
|
+
if (!Array.isArray(value)) {
|
|
1607
|
+
return "";
|
|
1608
|
+
}
|
|
1609
|
+
return value
|
|
1610
|
+
.map((change) => {
|
|
1611
|
+
const record = toRecord(change);
|
|
1612
|
+
if (!record) {
|
|
1613
|
+
return "";
|
|
1614
|
+
}
|
|
1615
|
+
const diff = ensureText(record.diff).trim();
|
|
1616
|
+
if (diff.length > 0) {
|
|
1617
|
+
return diff;
|
|
1618
|
+
}
|
|
1619
|
+
const path = ensureText(record.path).trim();
|
|
1620
|
+
return path.length > 0 ? `Updated ${path}` : "";
|
|
1621
|
+
})
|
|
1622
|
+
.filter((entry) => entry.length > 0)
|
|
1623
|
+
.join("\n\n");
|
|
1624
|
+
}
|
|
924
1625
|
//# sourceMappingURL=codex-runtime.js.map
|