@wlv-zedd/dsh-chatgpt-web 1.0.0
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/LICENSE +21 -0
- package/README.md +140 -0
- package/assets/demo.gif +0 -0
- package/assets/hero-demo.png +0 -0
- package/assets/promo-dshmarket-official.png +0 -0
- package/cordis.patch.yml +4 -0
- package/lib/cli.js +239642 -0
- package/lib/plugin.js +195 -0
- package/package.json +88 -0
- package/screenshots.json +5 -0
- package/src/adapters/base.ts +16 -0
- package/src/adapters/chatgpt-web/adapter-error.ts +59 -0
- package/src/adapters/chatgpt-web/browser-helper-main.ts +513 -0
- package/src/adapters/chatgpt-web/browser-helper-prompt-selection.ts +27 -0
- package/src/adapters/chatgpt-web/browser-worker.ts +4944 -0
- package/src/adapters/chatgpt-web/codex-rollout-environment.ts +628 -0
- package/src/adapters/chatgpt-web/compaction-handoff.ts +533 -0
- package/src/adapters/chatgpt-web/compaction-transaction.ts +142 -0
- package/src/adapters/chatgpt-web/concurrency.ts +6 -0
- package/src/adapters/chatgpt-web/conversation-key.ts +58 -0
- package/src/adapters/chatgpt-web/environment.ts +669 -0
- package/src/adapters/chatgpt-web/index.ts +1544 -0
- package/src/adapters/chatgpt-web/input-tokens.ts +74 -0
- package/src/adapters/chatgpt-web/launcher-helper-client.ts +695 -0
- package/src/adapters/chatgpt-web/markdown.ts +418 -0
- package/src/adapters/chatgpt-web/mcp-main.ts +25 -0
- package/src/adapters/chatgpt-web/mcp-server.ts +933 -0
- package/src/adapters/chatgpt-web/model.ts +70 -0
- package/src/adapters/chatgpt-web/native-compaction-control.ts +74 -0
- package/src/adapters/chatgpt-web/output-validation.ts +62 -0
- package/src/adapters/chatgpt-web/process-line-writer.ts +46 -0
- package/src/adapters/chatgpt-web/prompt.ts +702 -0
- package/src/adapters/chatgpt-web/retry-policy.ts +73 -0
- package/src/adapters/chatgpt-web/rolling-checkpoint.ts +384 -0
- package/src/adapters/chatgpt-web/thread-environment.ts +238 -0
- package/src/adapters/chatgpt-web/tool-stream-parser.ts +601 -0
- package/src/adapters/chatgpt-web/turn-broker.ts +1481 -0
- package/src/adapters/chatgpt-web/turn-execution.ts +816 -0
- package/src/adapters/chatgpt-web/turn-progress.ts +292 -0
- package/src/adapters/chatgpt-web/usage.ts +121 -0
- package/src/adapters/image.ts +9 -0
- package/src/bridge.ts +1083 -0
- package/src/browser-login.ts +521 -0
- package/src/chatgpt-session.ts +240 -0
- package/src/chatgpt-web-models.ts +400 -0
- package/src/cli.ts +568 -0
- package/src/codex-integration-document.ts +824 -0
- package/src/codex-integration-journal.ts +212 -0
- package/src/codex-integration-route.ts +515 -0
- package/src/codex-integration-shared.ts +332 -0
- package/src/codex-integration.ts +529 -0
- package/src/codex-interrupt-hook.ts +158 -0
- package/src/config.ts +616 -0
- package/src/dev-chat/cli.ts +432 -0
- package/src/dev-chat/constants.ts +3 -0
- package/src/dev-chat/driver.ts +655 -0
- package/src/dev-chat/profile.ts +223 -0
- package/src/dev-chat/session.ts +287 -0
- package/src/dev-chat/transport.ts +54 -0
- package/src/doctor.ts +237 -0
- package/src/event-queue.ts +45 -0
- package/src/http-body.ts +30 -0
- package/src/launcher-browser-host.ts +695 -0
- package/src/lib/errors.ts +281 -0
- package/src/lib/token-estimate.ts +42 -0
- package/src/login-helper.cjs +140 -0
- package/src/model-catalog.ts +197 -0
- package/src/native-passthrough.ts +261 -0
- package/src/plugin.ts +191 -0
- package/src/process.ts +45 -0
- package/src/responses/compaction.ts +199 -0
- package/src/responses/parser.ts +633 -0
- package/src/responses/reasoning-envelope.ts +49 -0
- package/src/responses/schema.ts +172 -0
- package/src/responses/state.ts +230 -0
- package/src/server.ts +1111 -0
- package/src/service.ts +315 -0
- package/src/setup.ts +671 -0
- package/src/stall-timeout.ts +23 -0
- package/src/tunnel-service.ts +160 -0
- package/src/tunnel.ts +417 -0
- package/src/turndown-plugin-gfm.d.ts +5 -0
- package/src/types.ts +307 -0
- package/src/usage/totals.ts +12 -0
- package/src/version.ts +1 -0
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
2
|
+
import { resolve } from "node:path";
|
|
3
|
+
import { atomicWriteFile, stripUtf8Bom } from "./config";
|
|
4
|
+
import {
|
|
5
|
+
CODEX_REALTIME_WEBRTC_CALL_BASE_URL,
|
|
6
|
+
getCodexConfigPath,
|
|
7
|
+
getCodexJournalPath,
|
|
8
|
+
getCodexJournalRecoveryPath,
|
|
9
|
+
serializeJournal,
|
|
10
|
+
writeFilesWithCompensation,
|
|
11
|
+
} from "./codex-integration-shared";
|
|
12
|
+
import type {
|
|
13
|
+
AnyCodexIntegrationJournal,
|
|
14
|
+
CodexIntegrationJournal,
|
|
15
|
+
LegacyCodexIntegrationJournal,
|
|
16
|
+
LegacyCodexIntegrationJournalV9,
|
|
17
|
+
LegacyCodexIntegrationJournalV3,
|
|
18
|
+
LegacyCodexIntegrationJournalV4,
|
|
19
|
+
LegacyCodexIntegrationJournalV5,
|
|
20
|
+
LegacyCodexIntegrationJournalV6,
|
|
21
|
+
LegacyCodexIntegrationJournalV7,
|
|
22
|
+
LegacyCodexIntegrationJournalV8,
|
|
23
|
+
} from "./codex-integration-shared";
|
|
24
|
+
import { verifyManagedJournalState } from "./codex-integration-route";
|
|
25
|
+
|
|
26
|
+
function isPreviousAssignment(value: unknown): boolean {
|
|
27
|
+
if (!value || typeof value !== "object") return false;
|
|
28
|
+
const assignment = value as Record<string, unknown>;
|
|
29
|
+
if (typeof assignment.present !== "boolean") return false;
|
|
30
|
+
return !assignment.present
|
|
31
|
+
|| (typeof assignment.rawLine === "string" && typeof assignment.value === "string");
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
function isInstalledInterruptHook(value: unknown): boolean {
|
|
35
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) return false;
|
|
36
|
+
const hook = value as Record<string, unknown>;
|
|
37
|
+
return typeof hook.command === "string" && hook.command.length > 0
|
|
38
|
+
&& Number.isSafeInteger(hook.groupIndex) && (hook.groupIndex as number) >= 0
|
|
39
|
+
&& typeof hook.stateKey === "string" && hook.stateKey.length > 0
|
|
40
|
+
&& typeof hook.trustedHash === "string" && /^sha256:[a-f0-9]{64}$/.test(hook.trustedHash)
|
|
41
|
+
&& typeof hook.fragment === "string" && hook.fragment.length > 0;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
function parseJournal(path: string): AnyCodexIntegrationJournal {
|
|
45
|
+
const value = JSON.parse(stripUtf8Bom(readFileSync(path, "utf8"))) as Record<string, unknown>;
|
|
46
|
+
const installed = value.installed as Record<string, unknown> | undefined;
|
|
47
|
+
if (value.version === 10
|
|
48
|
+
&& typeof value.active === "boolean"
|
|
49
|
+
&& installed
|
|
50
|
+
&& typeof installed.openai_base_url === "string"
|
|
51
|
+
&& installed.experimental_realtime_webrtc_call_base_url === CODEX_REALTIME_WEBRTC_CALL_BASE_URL
|
|
52
|
+
&& (installed.subagent_protocol === "compatibility-v1" || installed.subagent_protocol === "native")
|
|
53
|
+
&& (installed.subagent_protocol !== "compatibility-v1"
|
|
54
|
+
|| (value.previousMultiAgent && value.previousMultiAgentV2
|
|
55
|
+
&& value.previousAgentMaxDepth
|
|
56
|
+
&& typeof installed.agent_max_depth === "number"
|
|
57
|
+
&& Number.isSafeInteger(installed.agent_max_depth)
|
|
58
|
+
&& installed.agent_max_depth >= 2))
|
|
59
|
+
&& value.previous
|
|
60
|
+
&& isPreviousAssignment(value.previousRealtimeWebrtcCallBaseUrl)
|
|
61
|
+
&& isInstalledInterruptHook(value.interruptHook)
|
|
62
|
+
&& typeof value.configPath === "string") {
|
|
63
|
+
return value as unknown as CodexIntegrationJournal;
|
|
64
|
+
}
|
|
65
|
+
if (value.version === 9
|
|
66
|
+
&& typeof value.active === "boolean"
|
|
67
|
+
&& installed
|
|
68
|
+
&& typeof installed.openai_base_url === "string"
|
|
69
|
+
&& installed.experimental_realtime_webrtc_call_base_url === CODEX_REALTIME_WEBRTC_CALL_BASE_URL
|
|
70
|
+
&& (installed.subagent_protocol === "compatibility-v1" || installed.subagent_protocol === "native")
|
|
71
|
+
&& (installed.subagent_protocol !== "compatibility-v1"
|
|
72
|
+
|| (value.previousMultiAgent && value.previousMultiAgentV2
|
|
73
|
+
&& value.previousAgentMaxDepth
|
|
74
|
+
&& typeof installed.agent_max_depth === "number"
|
|
75
|
+
&& Number.isSafeInteger(installed.agent_max_depth)
|
|
76
|
+
&& installed.agent_max_depth >= 2))
|
|
77
|
+
&& value.previous
|
|
78
|
+
&& isPreviousAssignment(value.previousRealtimeWebrtcCallBaseUrl)
|
|
79
|
+
&& typeof value.configPath === "string") {
|
|
80
|
+
return value as unknown as LegacyCodexIntegrationJournalV9;
|
|
81
|
+
}
|
|
82
|
+
if (value.version === 8
|
|
83
|
+
&& typeof value.active === "boolean"
|
|
84
|
+
&& installed
|
|
85
|
+
&& (installed.subagent_protocol === "compatibility-v1" || installed.subagent_protocol === "native")
|
|
86
|
+
&& (installed.subagent_protocol !== "compatibility-v1"
|
|
87
|
+
|| (value.previousMultiAgent && value.previousMultiAgentV2
|
|
88
|
+
&& value.previousAgentMaxDepth
|
|
89
|
+
&& typeof installed.agent_max_depth === "number"
|
|
90
|
+
&& Number.isSafeInteger(installed.agent_max_depth)
|
|
91
|
+
&& installed.agent_max_depth >= 2))
|
|
92
|
+
&& value.previous
|
|
93
|
+
&& typeof value.configPath === "string") {
|
|
94
|
+
return value as unknown as LegacyCodexIntegrationJournalV8;
|
|
95
|
+
}
|
|
96
|
+
if (value.version === 7
|
|
97
|
+
&& typeof value.active === "boolean"
|
|
98
|
+
&& value.installed
|
|
99
|
+
&& value.previous
|
|
100
|
+
&& typeof value.configPath === "string") {
|
|
101
|
+
return value as unknown as LegacyCodexIntegrationJournalV7;
|
|
102
|
+
}
|
|
103
|
+
if (value.version === 6
|
|
104
|
+
&& typeof value.active === "boolean"
|
|
105
|
+
&& value.installed
|
|
106
|
+
&& value.previous
|
|
107
|
+
&& value.previousRemoteCompactionV2
|
|
108
|
+
&& value.previousMultiAgent
|
|
109
|
+
&& value.previousMultiAgentV2
|
|
110
|
+
&& typeof value.configPath === "string") {
|
|
111
|
+
return value as unknown as LegacyCodexIntegrationJournalV6;
|
|
112
|
+
}
|
|
113
|
+
if (value.version === 5
|
|
114
|
+
&& typeof value.active === "boolean"
|
|
115
|
+
&& value.installed
|
|
116
|
+
&& value.previous
|
|
117
|
+
&& value.previousRemoteCompactionV2
|
|
118
|
+
&& value.previousMultiAgent
|
|
119
|
+
&& typeof value.configPath === "string") {
|
|
120
|
+
return value as unknown as LegacyCodexIntegrationJournalV5;
|
|
121
|
+
}
|
|
122
|
+
if (value.version === 4
|
|
123
|
+
&& typeof value.active === "boolean"
|
|
124
|
+
&& value.installed
|
|
125
|
+
&& value.previous
|
|
126
|
+
&& typeof value.configPath === "string") {
|
|
127
|
+
return value as unknown as LegacyCodexIntegrationJournalV4;
|
|
128
|
+
}
|
|
129
|
+
if (value.version === 3 && value.installed && value.previous && typeof value.configPath === "string") {
|
|
130
|
+
return value as unknown as LegacyCodexIntegrationJournalV3;
|
|
131
|
+
}
|
|
132
|
+
if (value.version === 2 && value.installed && value.previous && typeof value.providerBlock === "string") {
|
|
133
|
+
return value as unknown as LegacyCodexIntegrationJournal;
|
|
134
|
+
}
|
|
135
|
+
throw new Error(`Invalid Codex integration journal: ${path}`);
|
|
136
|
+
}
|
|
137
|
+
function journalMatchesConfig(journal: AnyCodexIntegrationJournal): boolean {
|
|
138
|
+
try {
|
|
139
|
+
assertJournalTargetsConfig(journal, getCodexConfigPath());
|
|
140
|
+
if (!existsSync(journal.configPath)) return false;
|
|
141
|
+
const text = readFileSync(journal.configPath, "utf8");
|
|
142
|
+
if (journal.version === 2) return text.includes(journal.providerBlock);
|
|
143
|
+
verifyManagedJournalState(text, journal);
|
|
144
|
+
return true;
|
|
145
|
+
} catch {
|
|
146
|
+
return false;
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
export function readJournal(): AnyCodexIntegrationJournal | undefined {
|
|
151
|
+
const primaryPath = getCodexJournalPath();
|
|
152
|
+
const recoveryPath = getCodexJournalRecoveryPath();
|
|
153
|
+
let primary: AnyCodexIntegrationJournal | undefined;
|
|
154
|
+
let recovery: AnyCodexIntegrationJournal | undefined;
|
|
155
|
+
let primaryError: unknown;
|
|
156
|
+
let recoveryError: unknown;
|
|
157
|
+
if (existsSync(primaryPath)) {
|
|
158
|
+
try { primary = parseJournal(primaryPath); } catch (error) { primaryError = error; }
|
|
159
|
+
}
|
|
160
|
+
if (existsSync(recoveryPath)) {
|
|
161
|
+
try { recovery = parseJournal(recoveryPath); } catch (error) { recoveryError = error; }
|
|
162
|
+
}
|
|
163
|
+
if (!primary && !recovery) {
|
|
164
|
+
if (primaryError) throw primaryError;
|
|
165
|
+
if (recoveryError) throw recoveryError;
|
|
166
|
+
return undefined;
|
|
167
|
+
}
|
|
168
|
+
if (primary && recovery && serializeJournal(primary) === serializeJournal(recovery)) return primary;
|
|
169
|
+
if (primary && !recovery && !recoveryError) {
|
|
170
|
+
atomicWriteFile(recoveryPath, serializeJournal(primary));
|
|
171
|
+
return primary;
|
|
172
|
+
}
|
|
173
|
+
if (recovery && !primary && !primaryError) {
|
|
174
|
+
if (!journalMatchesConfig(recovery)) {
|
|
175
|
+
throw new Error("Codex integration recovery journal does not match the active config");
|
|
176
|
+
}
|
|
177
|
+
atomicWriteFile(primaryPath, serializeJournal(recovery));
|
|
178
|
+
return recovery;
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
const primaryMatches = primary ? journalMatchesConfig(primary) : false;
|
|
182
|
+
const recoveryMatches = recovery ? journalMatchesConfig(recovery) : false;
|
|
183
|
+
if (primaryMatches === recoveryMatches) {
|
|
184
|
+
throw new Error(
|
|
185
|
+
primaryMatches
|
|
186
|
+
? "Codex integration journal copies contain different baselines for the same config"
|
|
187
|
+
: "Codex integration journal copies do not match the active config",
|
|
188
|
+
);
|
|
189
|
+
}
|
|
190
|
+
const selected = primaryMatches ? primary! : recovery!;
|
|
191
|
+
const data = serializeJournal(selected);
|
|
192
|
+
writeFilesWithCompensation([
|
|
193
|
+
{ path: recoveryPath, data },
|
|
194
|
+
{ path: primaryPath, data },
|
|
195
|
+
]);
|
|
196
|
+
return selected;
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
export function assertJournalTargetsConfig(
|
|
200
|
+
journal: AnyCodexIntegrationJournal,
|
|
201
|
+
configPath: string,
|
|
202
|
+
): void {
|
|
203
|
+
const pathIdentity = (value: string): string => {
|
|
204
|
+
const normalized = resolve(value);
|
|
205
|
+
return process.platform === "win32" ? normalized.toLowerCase() : normalized;
|
|
206
|
+
};
|
|
207
|
+
if (pathIdentity(journal.configPath) !== pathIdentity(configPath)) {
|
|
208
|
+
throw new Error(
|
|
209
|
+
`Codex integration journal belongs to ${journal.configPath}, not the active config ${configPath}`,
|
|
210
|
+
);
|
|
211
|
+
}
|
|
212
|
+
}
|