coding-tool-x 3.8.1 → 3.8.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.
Files changed (36) hide show
  1. package/CHANGELOG.md +2 -0
  2. package/dist/web/assets/{Analytics-8dRv1aYW.js → Analytics-COEUXmd4.js} +1 -1
  3. package/dist/web/assets/{ConfigTemplates-BQRXSICO.js → ConfigTemplates-DLLkS53H.js} +1 -1
  4. package/dist/web/assets/{Home-BtzWhKIa.js → Home-DCEyLzwX.js} +1 -1
  5. package/dist/web/assets/{PluginManager-BTa-Ygf6.js → PluginManager-Oe1ZHoMO.js} +1 -1
  6. package/dist/web/assets/{ProjectList-F_cB8ldA.js → ProjectList-CWjuAFof.js} +1 -1
  7. package/dist/web/assets/{SessionList-LOrbPQvu.js → SessionList-v3ehGg9U.js} +1 -1
  8. package/dist/web/assets/{SkillManager-BzI_t-yV.js → SkillManager-DUF_qP5S.js} +1 -1
  9. package/dist/web/assets/{WorkspaceManager-Db9RGiz7.js → WorkspaceManager-CjAWBosO.js} +1 -1
  10. package/dist/web/assets/index-D5hyHPj7.js +2 -0
  11. package/dist/web/index.html +1 -1
  12. package/docs/superpowers/plans/2026-08-10-codex-conversion-compatibility.md +251 -0
  13. package/docs/superpowers/plans/2026-08-11-windows-command-window-hiding.md +90 -0
  14. package/docs/superpowers/plans/2026-08-13-omp-restart-recovery.md +48 -0
  15. package/docs/superpowers/specs/2026-08-10-codex-conversion-compatibility-design.md +61 -0
  16. package/docs/superpowers/specs/2026-08-11-windows-command-window-hiding-design.md +44 -0
  17. package/docs/superpowers/specs/2026-08-13-omp-restart-recovery-design.md +22 -0
  18. package/package.json +1 -1
  19. package/src/commands/daemon.js +3 -12
  20. package/src/commands/update.js +1 -1
  21. package/src/index.js +8 -1
  22. package/src/server/omp-proxy-server.js +9 -6
  23. package/src/server/opencode-proxy-server.js +55 -1037
  24. package/src/server/services/claude-wire.js +694 -0
  25. package/src/server/services/codex-wire.js +219 -0
  26. package/src/server/services/gemini-wire.js +759 -0
  27. package/src/server/services/model-detector.js +49 -131
  28. package/src/server/services/omp-channels.js +23 -4
  29. package/src/server/services/omp-gateway.js +29 -1
  30. package/src/server/services/omp-settings-manager.js +27 -3
  31. package/src/server/services/opencode-gateway-adapters.js +22 -1147
  32. package/src/server/services/opencode-normalization.js +546 -0
  33. package/src/server/services/session-history-index.js +1 -1
  34. package/src/server/services/session-history-worker.js +2 -1
  35. package/src/server/services/speed-test.js +85 -303
  36. package/dist/web/assets/index-DIWJmyL6.js +0 -2
@@ -0,0 +1,219 @@
1
+ 'use strict';
2
+
3
+ const crypto = require('crypto');
4
+ const os = require('os');
5
+
6
+ const CODEX_CLIENT_VERSION = '0.144.1';
7
+ const CODEX_ORIGINATOR = 'codex_exec';
8
+ const CODEX_RESERVED_METADATA_KEYS = new Set([
9
+ 'x-codex-installation-id',
10
+ 'x-codex-window-id',
11
+ 'x-codex-turn-metadata',
12
+ 'session_id',
13
+ 'thread_id',
14
+ 'turn_id'
15
+ ]);
16
+ const CODEX_UNSUPPORTED_BODY_FIELDS = [
17
+ 'max_output_tokens',
18
+ 'max_completion_tokens',
19
+ 'temperature',
20
+ 'top_p',
21
+ 'top_k',
22
+ 'min_p',
23
+ 'presence_penalty',
24
+ 'frequency_penalty',
25
+ 'repetition_penalty',
26
+ 'stop',
27
+ 'service_tier',
28
+ 'user',
29
+ 'previous_response_id',
30
+ 'prompt_cache_retention',
31
+ 'safety_identifier'
32
+ ];
33
+
34
+ let installationId = '';
35
+
36
+ function cloneJsonCompatible(value) {
37
+ try {
38
+ return JSON.parse(JSON.stringify(value));
39
+ } catch {
40
+ return value;
41
+ }
42
+ }
43
+
44
+ function createId() {
45
+ return typeof crypto.randomUUID === 'function'
46
+ ? crypto.randomUUID()
47
+ : `${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 14)}`;
48
+ }
49
+
50
+ function getInstallationId() {
51
+ if (!installationId) installationId = createId();
52
+ return installationId;
53
+ }
54
+
55
+ function normalizeId(value, fallbackFactory = createId) {
56
+ const normalized = typeof value === 'string' ? value.trim() : '';
57
+ return normalized || fallbackFactory();
58
+ }
59
+
60
+ function normalizeCodexResponsesInput(inputValue) {
61
+ if (typeof inputValue === 'string') {
62
+ return [
63
+ {
64
+ type: 'message',
65
+ role: 'user',
66
+ content: [{ type: 'input_text', text: inputValue }]
67
+ }
68
+ ];
69
+ }
70
+
71
+ if (!Array.isArray(inputValue)) return undefined;
72
+ return inputValue.map(item => {
73
+ if (!item || typeof item !== 'object') return item;
74
+ const clonedItem = cloneJsonCompatible(item);
75
+ if (String(clonedItem?.role || '').trim().toLowerCase() === 'system') {
76
+ clonedItem.role = 'developer';
77
+ }
78
+ return clonedItem;
79
+ });
80
+ }
81
+
82
+ function normalizeInclude(value) {
83
+ const include = Array.isArray(value)
84
+ ? value.filter(item => typeof item === 'string' && item.trim())
85
+ : [];
86
+ if (!include.includes('reasoning.encrypted_content')) {
87
+ include.push('reasoning.encrypted_content');
88
+ }
89
+ return [...new Set(include)];
90
+ }
91
+
92
+ function normalizeClientMetadata(value) {
93
+ if (!value || typeof value !== 'object' || Array.isArray(value)) return {};
94
+ return Object.fromEntries(
95
+ Object.entries(value)
96
+ .filter(([key, item]) => !CODEX_RESERVED_METADATA_KEYS.has(key) && typeof item === 'string')
97
+ .map(([key, item]) => [key, item])
98
+ );
99
+ }
100
+
101
+ function resolveUserAgent(value) {
102
+ if (typeof value === 'string' && value.trim()) return value.trim();
103
+ const terminal = String(process.env.TERM_PROGRAM || process.env.TERM || 'Terminal').trim() || 'Terminal';
104
+ const platformName = process.platform === 'darwin' ? 'Mac OS' : process.platform;
105
+ return `${CODEX_ORIGINATOR}/${CODEX_CLIENT_VERSION} (${platformName} ${os.release()}; ${process.arch}) ${terminal} (${CODEX_ORIGINATOR}; ${CODEX_CLIENT_VERSION})`;
106
+ }
107
+
108
+ function buildTurnMetadata({ installationId: currentInstallationId, sessionId, threadId, turnId, windowId }) {
109
+ return JSON.stringify({
110
+ installation_id: currentInstallationId,
111
+ session_id: sessionId,
112
+ thread_id: threadId,
113
+ turn_id: turnId,
114
+ window_id: windowId,
115
+ request_kind: 'turn'
116
+ });
117
+ }
118
+
119
+ function createCodexRequest(payload = {}, options = {}) {
120
+ const source = payload && typeof payload === 'object' && !Array.isArray(payload)
121
+ ? payload
122
+ : {};
123
+ const body = cloneJsonCompatible(source);
124
+ const fallbackModel = typeof options.fallbackModel === 'string' ? options.fallbackModel.trim() : '';
125
+ const requestedSessionId = options.sessionId || body.prompt_cache_key;
126
+ if (body.model === undefined && fallbackModel) body.model = fallbackModel;
127
+
128
+ const sessionId = normalizeId(requestedSessionId, createId);
129
+ const threadId = normalizeId(options.threadId, () => sessionId);
130
+ const windowId = normalizeId(options.windowId, () => `${sessionId}:0`);
131
+ const turnId = normalizeId(options.turnId, createId);
132
+ const currentInstallationId = normalizeId(options.installationId, getInstallationId);
133
+ const normalizedInput = normalizeCodexResponsesInput(body.input);
134
+ if (normalizedInput !== undefined) body.input = normalizedInput;
135
+ body.stream = true;
136
+ if (body.parallel_tool_calls === undefined) body.parallel_tool_calls = true;
137
+ if (typeof body.instructions !== 'string') body.instructions = '';
138
+ body.store = false;
139
+ body.include = normalizeInclude(body.include);
140
+ const reasoningEffort = typeof body.reasoning_effort === 'string'
141
+ ? body.reasoning_effort.trim().toLowerCase()
142
+ : '';
143
+ if (reasoningEffort && body.reasoning === undefined && ['minimal', 'low', 'medium', 'high', 'xhigh', 'max', 'none'].includes(reasoningEffort)) {
144
+ body.reasoning = { effort: reasoningEffort };
145
+ }
146
+ delete body.reasoning_effort;
147
+ body.prompt_cache_key = normalizeId(body.prompt_cache_key, () => sessionId);
148
+
149
+ const callerMetadata = normalizeClientMetadata(body.client_metadata);
150
+ const turnMetadata = buildTurnMetadata({
151
+ installationId: currentInstallationId,
152
+ sessionId,
153
+ threadId,
154
+ turnId,
155
+ windowId
156
+ });
157
+ body.client_metadata = {
158
+ ...callerMetadata,
159
+ 'x-codex-installation-id': currentInstallationId,
160
+ session_id: sessionId,
161
+ thread_id: threadId,
162
+ 'x-codex-window-id': windowId,
163
+ turn_id: turnId,
164
+ 'x-codex-turn-metadata': turnMetadata
165
+ };
166
+
167
+ CODEX_UNSUPPORTED_BODY_FIELDS.forEach(field => delete body[field]);
168
+
169
+ const headers = {
170
+ authorization: `Bearer ${String(options.apiKey || '')}`,
171
+ accept: 'text/event-stream',
172
+ 'content-type': 'application/json',
173
+ originator: typeof options.originator === 'string' && options.originator.trim()
174
+ ? options.originator.trim()
175
+ : CODEX_ORIGINATOR,
176
+ 'user-agent': resolveUserAgent(options.userAgent),
177
+ 'session-id': sessionId,
178
+ 'thread-id': threadId,
179
+ 'x-client-request-id': sessionId,
180
+ 'x-codex-window-id': windowId,
181
+ 'x-codex-turn-metadata': turnMetadata,
182
+ 'x-codex-beta-features': 'remote_compaction_v2'
183
+ };
184
+
185
+ return {
186
+ body,
187
+ headers,
188
+ model: String(body.model || fallbackModel || '').trim()
189
+ };
190
+ }
191
+
192
+ function buildCodexTargetUrl(baseUrl = '') {
193
+ let targetUrl;
194
+ try {
195
+ targetUrl = new URL(String(baseUrl || '').trim());
196
+ } catch {
197
+ return '';
198
+ }
199
+
200
+ let pathname = targetUrl.pathname.replace(/\/+$/, '');
201
+ if (!pathname || pathname === '/') {
202
+ pathname = '/responses';
203
+ } else if (pathname.endsWith('/responses') || pathname.endsWith('/v1/responses')) {
204
+ // Already an endpoint.
205
+ } else {
206
+ pathname = `${pathname}/responses`;
207
+ }
208
+
209
+ targetUrl.pathname = pathname;
210
+ return targetUrl.toString();
211
+ }
212
+
213
+ module.exports = {
214
+ CODEX_CLIENT_VERSION,
215
+ CODEX_ORIGINATOR,
216
+ buildCodexTargetUrl,
217
+ createCodexRequest,
218
+ normalizeCodexResponsesInput
219
+ };