@jingyi0605/codingns 0.1.1 → 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-CVG1cGAJ.js → TerminalPage-Dr7knYq2.js} +19 -19
- 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 +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 +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 +4 -2
- package/dist/server/modules/sessions/session-history-service.js +151 -29
- 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 +330 -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 +79 -43
- 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 +2 -1
- 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 +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 +82 -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 +23 -0
- package/node_modules/@codingns/session-sync-core/dist/runtime/codex-runtime.js +688 -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 +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/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,59 @@ 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
|
+
await transport.startTurn(request, providerSessionId);
|
|
33
59
|
return {
|
|
34
60
|
providerSessionId,
|
|
35
61
|
rawStoreRef,
|
|
36
62
|
interrupt: async () => {
|
|
37
63
|
abortController.abort();
|
|
64
|
+
await transport.interruptTurn().catch(() => {
|
|
65
|
+
return;
|
|
66
|
+
});
|
|
67
|
+
transport.close();
|
|
38
68
|
},
|
|
39
|
-
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
|
+
})
|
|
40
72
|
};
|
|
41
73
|
}
|
|
42
74
|
async continueSession(request, sink) {
|
|
@@ -44,31 +76,66 @@ export class CodexRuntimeAdapter {
|
|
|
44
76
|
if (!providerSessionId) {
|
|
45
77
|
throw new Error("PROVIDER_SESSION_ID_REQUIRED");
|
|
46
78
|
}
|
|
47
|
-
const
|
|
48
|
-
|
|
79
|
+
const transport = this.options.transportFactory
|
|
80
|
+
? this.options.transportFactory()
|
|
81
|
+
: createCodexAppServerTransport(this.options);
|
|
82
|
+
await transport.initialize();
|
|
49
83
|
const fallbackRawStoreRef = request.rawStoreRef ?? buildRuntimeRawStoreRef(providerSessionId);
|
|
50
84
|
const resolvedBinding = await this.resolveExistingSessionBinding(providerSessionId, fallbackRawStoreRef, request.workspacePath);
|
|
51
85
|
const resolvedSessionId = resolvedBinding?.providerSessionId ?? providerSessionId;
|
|
52
|
-
const
|
|
86
|
+
const resumed = await transport.resumeThread(request, resolvedSessionId);
|
|
87
|
+
const rawStoreRef = resolvedBinding?.rawStoreRef ?? resumed.rawStoreRef ?? fallbackRawStoreRef;
|
|
53
88
|
const abortController = new AbortController();
|
|
89
|
+
const eventQueue = createAsyncEventQueue();
|
|
54
90
|
sink.updateSessionBinding({
|
|
55
91
|
providerSessionId: resolvedSessionId,
|
|
56
92
|
rawStoreRef
|
|
57
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);
|
|
58
117
|
return {
|
|
59
118
|
providerSessionId: resolvedSessionId,
|
|
60
119
|
rawStoreRef,
|
|
61
120
|
interrupt: async () => {
|
|
62
121
|
abortController.abort();
|
|
122
|
+
await transport.interruptTurn().catch(() => {
|
|
123
|
+
return;
|
|
124
|
+
});
|
|
125
|
+
transport.close();
|
|
63
126
|
},
|
|
64
|
-
completed: this.runTurn(
|
|
127
|
+
completed: this.runTurn(null, request, sink, resolvedSessionId, rawStoreRef, abortController, eventQueue.iterator, [], Date.now()).finally(() => {
|
|
128
|
+
transport.close();
|
|
129
|
+
})
|
|
65
130
|
};
|
|
66
131
|
}
|
|
67
132
|
async runTurn(thread, request, sink, providerSessionId, rawStoreRef, abortController, preparedEvents, bufferedEvents = [], launchedAtMs = Date.now()) {
|
|
68
133
|
const context = {
|
|
69
134
|
providerSessionId,
|
|
70
135
|
rawStoreRef,
|
|
71
|
-
|
|
136
|
+
// 运行时消息必须接在历史消息后面,不能每轮都从 1 重新编号,
|
|
137
|
+
// 否则前端会把新 assistant/tool 消息排到旧消息前面,表现成用户消息一直挂在底部。
|
|
138
|
+
sequence: Math.max(0, request.sequenceBase ?? 0),
|
|
72
139
|
toolNameByCallId: new Map(),
|
|
73
140
|
sink,
|
|
74
141
|
workspacePath: request.workspacePath,
|
|
@@ -148,12 +215,23 @@ export class CodexRuntimeAdapter {
|
|
|
148
215
|
status: "failed",
|
|
149
216
|
providerSessionId: context.providerSessionId,
|
|
150
217
|
rawStoreRef: context.rawStoreRef,
|
|
151
|
-
errorCode: "CODEX_CLI_TURN_FAILED",
|
|
218
|
+
errorCode: classifyCodexDetailErrorCode(detail, "CODEX_CLI_TURN_FAILED"),
|
|
152
219
|
detail,
|
|
153
220
|
timestamp: pickTimestamp(event)
|
|
154
221
|
});
|
|
155
222
|
return;
|
|
156
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
|
+
}
|
|
157
235
|
if (interrupted) {
|
|
158
236
|
return;
|
|
159
237
|
}
|
|
@@ -451,6 +529,392 @@ export class CodexRuntimeAdapter {
|
|
|
451
529
|
}
|
|
452
530
|
}
|
|
453
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
|
+
}
|
|
454
918
|
export function createThreadOptions(request) {
|
|
455
919
|
const options = {
|
|
456
920
|
workingDirectory: request.workspacePath,
|
|
@@ -470,6 +934,61 @@ export function createThreadOptions(request) {
|
|
|
470
934
|
}
|
|
471
935
|
return options;
|
|
472
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
|
+
}
|
|
473
992
|
function normalizeCodexReasoningEffort(value) {
|
|
474
993
|
const normalized = value?.trim().toLowerCase() ?? null;
|
|
475
994
|
if (!normalized) {
|
|
@@ -507,6 +1026,23 @@ function createCodexInput(request) {
|
|
|
507
1026
|
});
|
|
508
1027
|
return input;
|
|
509
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
|
+
}
|
|
510
1046
|
async function loadCodexClient() {
|
|
511
1047
|
const moduleName = "@openai/codex-sdk";
|
|
512
1048
|
const runtimeImport = new Function("name", "return import(name);");
|
|
@@ -553,6 +1089,80 @@ function buildRuntimeRawStoreRef(providerSessionId) {
|
|
|
553
1089
|
function resolveRuntimeStoreKey(providerSessionId, sessionId) {
|
|
554
1090
|
return providerSessionId.trim() || sessionId;
|
|
555
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
|
+
}
|
|
556
1166
|
function resolveResumeThreadId(providerSessionId, rawStoreRef) {
|
|
557
1167
|
const normalizedProviderSessionId = ensureText(providerSessionId).trim();
|
|
558
1168
|
const fromRawStore = readThreadIdFromRawStore(rawStoreRef);
|
|
@@ -570,6 +1180,12 @@ function readProp(value, key) {
|
|
|
570
1180
|
}
|
|
571
1181
|
return value[key];
|
|
572
1182
|
}
|
|
1183
|
+
function toRecord(value) {
|
|
1184
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
1185
|
+
return null;
|
|
1186
|
+
}
|
|
1187
|
+
return value;
|
|
1188
|
+
}
|
|
573
1189
|
function ensureText(value) {
|
|
574
1190
|
if (typeof value === "string") {
|
|
575
1191
|
return value;
|
|
@@ -584,6 +1200,10 @@ function ensureText(value) {
|
|
|
584
1200
|
return String(value);
|
|
585
1201
|
}
|
|
586
1202
|
}
|
|
1203
|
+
function normalizeText(value) {
|
|
1204
|
+
const normalized = ensureText(value).trim();
|
|
1205
|
+
return normalized.length > 0 ? normalized : null;
|
|
1206
|
+
}
|
|
587
1207
|
function readThreadIdFromRawStore(rawStoreRef) {
|
|
588
1208
|
const filePath = ensureText(rawStoreRef).trim();
|
|
589
1209
|
if (!filePath || !existsSync(filePath)) {
|
|
@@ -715,9 +1335,14 @@ function pickFirstNonEmpty(...values) {
|
|
|
715
1335
|
}
|
|
716
1336
|
function isToolItem(itemType) {
|
|
717
1337
|
return (itemType === "command_execution" ||
|
|
1338
|
+
itemType === "file_change" ||
|
|
718
1339
|
itemType === "mcp_tool_call" ||
|
|
719
1340
|
itemType === "function_call" ||
|
|
720
|
-
itemType === "custom_tool_call"
|
|
1341
|
+
itemType === "custom_tool_call" ||
|
|
1342
|
+
itemType === "commandExecution" ||
|
|
1343
|
+
itemType === "fileChange" ||
|
|
1344
|
+
itemType === "mcpToolCall" ||
|
|
1345
|
+
itemType === "dynamicToolCall");
|
|
721
1346
|
}
|
|
722
1347
|
function inferToolSuccess(item, output) {
|
|
723
1348
|
const status = ensureText(readProp(item, "status")).trim().toLowerCase();
|
|
@@ -758,10 +1383,23 @@ function classifyCodexRuntimeFailure(error) {
|
|
|
758
1383
|
};
|
|
759
1384
|
}
|
|
760
1385
|
return {
|
|
761
|
-
errorCode: "CODEX_RUNTIME_ERROR",
|
|
1386
|
+
errorCode: classifyCodexDetailErrorCode(detail, "CODEX_RUNTIME_ERROR"),
|
|
762
1387
|
detail
|
|
763
1388
|
};
|
|
764
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
|
+
}
|
|
765
1403
|
function persistSyntheticUserMessageIfNeeded(rawStoreRef, providerSessionId, input) {
|
|
766
1404
|
if (!isSyntheticRawStoreRef(rawStoreRef) || input.content.trim().length === 0) {
|
|
767
1405
|
return;
|
|
@@ -921,4 +1559,37 @@ function mapToolStartItemType(itemType) {
|
|
|
921
1559
|
function mapToolResultItemType(itemType) {
|
|
922
1560
|
return itemType === "custom_tool_call" ? "custom_tool_call_output" : "function_call_output";
|
|
923
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
|
+
}
|
|
924
1595
|
//# sourceMappingURL=codex-runtime.js.map
|