@codemieai/code 0.13.1 → 0.14.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.
Files changed (137) hide show
  1. package/README.md +44 -6
  2. package/dist/agents/core/AgentCLI.d.ts.map +1 -1
  3. package/dist/agents/core/AgentCLI.js +53 -4
  4. package/dist/agents/core/AgentCLI.js.map +1 -1
  5. package/dist/agents/plugins/claude/claude.models.d.ts +12 -0
  6. package/dist/agents/plugins/claude/claude.models.d.ts.map +1 -0
  7. package/dist/agents/plugins/claude/claude.models.js +191 -0
  8. package/dist/agents/plugins/claude/claude.models.js.map +1 -0
  9. package/dist/agents/plugins/claude/claude.plugin.d.ts.map +1 -1
  10. package/dist/agents/plugins/claude/claude.plugin.js +45 -1
  11. package/dist/agents/plugins/claude/claude.plugin.js.map +1 -1
  12. package/dist/agents/plugins/codex/codex-models.d.ts +11 -0
  13. package/dist/agents/plugins/codex/codex-models.d.ts.map +1 -1
  14. package/dist/agents/plugins/codex/codex-models.js +71 -0
  15. package/dist/agents/plugins/codex/codex-models.js.map +1 -1
  16. package/dist/agents/plugins/gemini/gemini.paths.d.ts +11 -0
  17. package/dist/agents/plugins/gemini/gemini.paths.d.ts.map +1 -0
  18. package/dist/agents/plugins/gemini/gemini.paths.js +21 -0
  19. package/dist/agents/plugins/gemini/gemini.paths.js.map +1 -0
  20. package/dist/agents/plugins/gemini/gemini.session-adapter.d.ts +20 -0
  21. package/dist/agents/plugins/gemini/gemini.session-adapter.d.ts.map +1 -1
  22. package/dist/agents/plugins/gemini/gemini.session-adapter.js +119 -3
  23. package/dist/agents/plugins/gemini/gemini.session-adapter.js.map +1 -1
  24. package/dist/agents/plugins/pi/pi.models.d.ts +14 -0
  25. package/dist/agents/plugins/pi/pi.models.d.ts.map +1 -1
  26. package/dist/agents/plugins/pi/pi.models.js +89 -0
  27. package/dist/agents/plugins/pi/pi.models.js.map +1 -1
  28. package/dist/cli/commands/analytics/agent-labels.d.ts.map +1 -1
  29. package/dist/cli/commands/analytics/agent-labels.js +1 -0
  30. package/dist/cli/commands/analytics/agent-labels.js.map +1 -1
  31. package/dist/cli/commands/analytics/aggregator.js +1 -1
  32. package/dist/cli/commands/analytics/aggregator.js.map +1 -1
  33. package/dist/cli/commands/analytics/cost/cost-calculator.d.ts +1 -1
  34. package/dist/cli/commands/analytics/cost/cost-calculator.d.ts.map +1 -1
  35. package/dist/cli/commands/analytics/cost/cost-enricher.js +2 -2
  36. package/dist/cli/commands/analytics/cost/cost-enricher.js.map +1 -1
  37. package/dist/cli/commands/analytics/data-loader.d.ts.map +1 -1
  38. package/dist/cli/commands/analytics/data-loader.js +9 -0
  39. package/dist/cli/commands/analytics/data-loader.js.map +1 -1
  40. package/dist/cli/commands/analytics/native-loader.js +1 -1
  41. package/dist/cli/commands/analytics/native-loader.js.map +1 -1
  42. package/dist/cli/commands/analytics/otel-loader.js +1 -1
  43. package/dist/cli/commands/analytics/otel-loader.js.map +1 -1
  44. package/dist/cli/commands/analytics/report/client/app.js +1 -1
  45. package/dist/cli/commands/hook.d.ts.map +1 -1
  46. package/dist/cli/commands/hook.js +70 -1
  47. package/dist/cli/commands/hook.js.map +1 -1
  48. package/dist/cli/commands/proxy/connect-orchestrator.d.ts +95 -0
  49. package/dist/cli/commands/proxy/connect-orchestrator.d.ts.map +1 -0
  50. package/dist/cli/commands/proxy/connect-orchestrator.js +501 -0
  51. package/dist/cli/commands/proxy/connect-orchestrator.js.map +1 -0
  52. package/dist/cli/commands/proxy/connectors/codex-config-toml.d.ts +81 -0
  53. package/dist/cli/commands/proxy/connectors/codex-config-toml.d.ts.map +1 -0
  54. package/dist/cli/commands/proxy/connectors/codex-config-toml.js +218 -0
  55. package/dist/cli/commands/proxy/connectors/codex-config-toml.js.map +1 -0
  56. package/dist/cli/commands/proxy/connectors/codex-desktop.d.ts +85 -0
  57. package/dist/cli/commands/proxy/connectors/codex-desktop.d.ts.map +1 -0
  58. package/dist/cli/commands/proxy/connectors/codex-desktop.js +299 -0
  59. package/dist/cli/commands/proxy/connectors/codex-desktop.js.map +1 -0
  60. package/dist/cli/commands/proxy/connectors/vscode-claude-code.d.ts +26 -0
  61. package/dist/cli/commands/proxy/connectors/vscode-claude-code.d.ts.map +1 -0
  62. package/dist/cli/commands/proxy/connectors/vscode-claude-code.js +132 -0
  63. package/dist/cli/commands/proxy/connectors/vscode-claude-code.js.map +1 -0
  64. package/dist/cli/commands/proxy/connectors/vscode.d.ts +2 -0
  65. package/dist/cli/commands/proxy/connectors/vscode.d.ts.map +1 -1
  66. package/dist/cli/commands/proxy/connectors/vscode.js +2 -2
  67. package/dist/cli/commands/proxy/connectors/vscode.js.map +1 -1
  68. package/dist/cli/commands/proxy/disconnect-orchestrator.d.ts +8 -0
  69. package/dist/cli/commands/proxy/disconnect-orchestrator.d.ts.map +1 -0
  70. package/dist/cli/commands/proxy/disconnect-orchestrator.js +43 -0
  71. package/dist/cli/commands/proxy/disconnect-orchestrator.js.map +1 -0
  72. package/dist/cli/commands/proxy/index.d.ts.map +1 -1
  73. package/dist/cli/commands/proxy/index.js +91 -370
  74. package/dist/cli/commands/proxy/index.js.map +1 -1
  75. package/dist/cli/index.js +7 -7
  76. package/dist/providers/integration/setup-ui.d.ts +14 -2
  77. package/dist/providers/integration/setup-ui.d.ts.map +1 -1
  78. package/dist/providers/integration/setup-ui.js +70 -33
  79. package/dist/providers/integration/setup-ui.js.map +1 -1
  80. package/dist/providers/plugins/anthropic-subscription/anthropic-subscription.setup-steps.d.ts.map +1 -1
  81. package/dist/providers/plugins/anthropic-subscription/anthropic-subscription.setup-steps.js +9 -2
  82. package/dist/providers/plugins/anthropic-subscription/anthropic-subscription.setup-steps.js.map +1 -1
  83. package/dist/providers/plugins/anthropic-subscription/anthropic-subscription.template.d.ts.map +1 -1
  84. package/dist/providers/plugins/anthropic-subscription/anthropic-subscription.template.js +18 -28
  85. package/dist/providers/plugins/anthropic-subscription/anthropic-subscription.template.js.map +1 -1
  86. package/dist/providers/plugins/bedrock/bedrock.setup-steps.d.ts.map +1 -1
  87. package/dist/providers/plugins/bedrock/bedrock.setup-steps.js +4 -4
  88. package/dist/providers/plugins/bedrock/bedrock.setup-steps.js.map +1 -1
  89. package/dist/providers/plugins/litellm/litellm.setup-steps.d.ts.map +1 -1
  90. package/dist/providers/plugins/litellm/litellm.setup-steps.js +3 -1
  91. package/dist/providers/plugins/litellm/litellm.setup-steps.js.map +1 -1
  92. package/dist/providers/plugins/moonshot-subscription/moonshot-subscription.setup-steps.d.ts.map +1 -1
  93. package/dist/providers/plugins/moonshot-subscription/moonshot-subscription.setup-steps.js +5 -1
  94. package/dist/providers/plugins/moonshot-subscription/moonshot-subscription.setup-steps.js.map +1 -1
  95. package/dist/providers/plugins/ollama/ollama.setup-steps.d.ts.map +1 -1
  96. package/dist/providers/plugins/ollama/ollama.setup-steps.js +3 -2
  97. package/dist/providers/plugins/ollama/ollama.setup-steps.js.map +1 -1
  98. package/dist/providers/plugins/sso/proxy/plugins/codex-encrypted-content-sanitizer.plugin.d.ts.map +1 -1
  99. package/dist/providers/plugins/sso/proxy/plugins/codex-encrypted-content-sanitizer.plugin.js +4 -0
  100. package/dist/providers/plugins/sso/proxy/plugins/codex-encrypted-content-sanitizer.plugin.js.map +1 -1
  101. package/dist/providers/plugins/sso/proxy/plugins/codex-model-resolver.d.ts +45 -0
  102. package/dist/providers/plugins/sso/proxy/plugins/codex-model-resolver.d.ts.map +1 -0
  103. package/dist/providers/plugins/sso/proxy/plugins/codex-model-resolver.js +129 -0
  104. package/dist/providers/plugins/sso/proxy/plugins/codex-model-resolver.js.map +1 -0
  105. package/dist/providers/plugins/sso/proxy/plugins/codex-request-normalizer.plugin.d.ts +27 -0
  106. package/dist/providers/plugins/sso/proxy/plugins/codex-request-normalizer.plugin.d.ts.map +1 -0
  107. package/dist/providers/plugins/sso/proxy/plugins/codex-request-normalizer.plugin.js +242 -0
  108. package/dist/providers/plugins/sso/proxy/plugins/codex-request-normalizer.plugin.js.map +1 -0
  109. package/dist/providers/plugins/sso/proxy/plugins/index.d.ts +2 -1
  110. package/dist/providers/plugins/sso/proxy/plugins/index.d.ts.map +1 -1
  111. package/dist/providers/plugins/sso/proxy/plugins/index.js +3 -1
  112. package/dist/providers/plugins/sso/proxy/plugins/index.js.map +1 -1
  113. package/dist/providers/plugins/sso/session/processors/metrics/metrics-api-client.d.ts.map +1 -1
  114. package/dist/providers/plugins/sso/session/processors/metrics/metrics-api-client.js +15 -1
  115. package/dist/providers/plugins/sso/session/processors/metrics/metrics-api-client.js.map +1 -1
  116. package/dist/providers/plugins/sso/sso.auth.d.ts.map +1 -1
  117. package/dist/providers/plugins/sso/sso.auth.js +3 -0
  118. package/dist/providers/plugins/sso/sso.auth.js.map +1 -1
  119. package/dist/utils/analytics-auth-status.d.ts +48 -0
  120. package/dist/utils/analytics-auth-status.d.ts.map +1 -0
  121. package/dist/utils/analytics-auth-status.js +89 -0
  122. package/dist/utils/analytics-auth-status.js.map +1 -0
  123. package/dist/utils/model-normalizer.d.ts.map +1 -0
  124. package/dist/utils/model-normalizer.js.map +1 -0
  125. package/dist/utils/pricing.d.ts.map +1 -0
  126. package/dist/{cli/commands/analytics/cost → utils}/pricing.js +3 -3
  127. package/dist/utils/pricing.js.map +1 -0
  128. package/package.json +1 -1
  129. package/scripts/copy-plugins.js +3 -3
  130. package/dist/cli/commands/analytics/cost/pricing.d.ts.map +0 -1
  131. package/dist/cli/commands/analytics/cost/pricing.js.map +0 -1
  132. package/dist/cli/commands/analytics/model-normalizer.d.ts.map +0 -1
  133. package/dist/cli/commands/analytics/model-normalizer.js.map +0 -1
  134. /package/dist/{cli/commands/analytics → utils}/model-normalizer.d.ts +0 -0
  135. /package/dist/{cli/commands/analytics → utils}/model-normalizer.js +0 -0
  136. /package/dist/{cli/commands/analytics/cost → utils}/pricing.d.ts +0 -0
  137. /package/dist/{cli/commands/analytics/cost → utils}/pricing.json +0 -0
@@ -0,0 +1,218 @@
1
+ /**
2
+ * Pure string surgery for the CodeMie-managed regions of `~/.codex/config.toml`.
3
+ *
4
+ * Nothing here touches the filesystem, the network, or the logger. The Codex
5
+ * config file is user-owned, so the managed content is spliced in as delimited
6
+ * text rather than round-tripped through a TOML serializer: `@iarna/toml`'s
7
+ * `stringify` discards comments and key order, which would silently rewrite the
8
+ * user's file on every connect.
9
+ *
10
+ * TOML permits bare top-level keys only *before* the first table header, so the
11
+ * managed content cannot be one contiguous block. It is two regions: a header
12
+ * region prepended to the file (holding `model_provider` and `model`) and a
13
+ * table region appended to it (holding `[model_providers.codemie]`).
14
+ */
15
+ export const HEADER_OPEN = '# >>> codemie proxy connect (codex-desktop) header - managed block, do not edit';
16
+ export const HEADER_CLOSE = '# <<< codemie proxy connect (codex-desktop) header';
17
+ export const TABLE_OPEN = '# >>> codemie proxy connect (codex-desktop) provider - managed block, do not edit';
18
+ export const TABLE_CLOSE = '# <<< codemie proxy connect (codex-desktop) provider';
19
+ /**
20
+ * A line is a sentinel when it equals one after trimming.
21
+ *
22
+ * Trailing whitespace and a stray `\r` are tolerated because this file is
23
+ * rewritten by the Codex desktop app and by editors on Windows, a supported
24
+ * platform. Matching strictly would make a sentinel unrecognizable to the
25
+ * cutter while still looking managed to the reader — which duplicates the
26
+ * managed block into the user's file.
27
+ */
28
+ function isSentinel(line, sentinel) {
29
+ return line.trim() === sentinel;
30
+ }
31
+ function locate(text, open, close) {
32
+ const lines = text.split('\n');
33
+ const openLine = lines.findIndex((line) => isSentinel(line, open));
34
+ if (openLine === -1)
35
+ return null;
36
+ const closeLine = lines.findIndex((line, index) => index > openLine && isSentinel(line, close));
37
+ if (closeLine === -1)
38
+ return null;
39
+ // Character offsets of the whole-line span, so callers can slice text.
40
+ const start = lines.slice(0, openLine).reduce((n, line) => n + line.length + 1, 0);
41
+ const end = lines.slice(0, closeLine + 1).reduce((n, line) => n + line.length + 1, 0) - 1;
42
+ return { start, end };
43
+ }
44
+ /**
45
+ * Locate both managed regions. A region whose close sentinel is missing is
46
+ * reported as absent rather than guessed at — a truncated block is treated as
47
+ * unmanaged text so the writer never deletes content it cannot delimit.
48
+ */
49
+ export function findManagedRegions(text) {
50
+ return {
51
+ header: locate(text, HEADER_OPEN, HEADER_CLOSE),
52
+ table: locate(text, TABLE_OPEN, TABLE_CLOSE),
53
+ };
54
+ }
55
+ /** Marks a user key the connector commented out so it can be restored verbatim. */
56
+ export const DISPLACED_PREFIX = '#codemie-displaced# ';
57
+ /** Top-level keys the managed header region owns and therefore must displace. */
58
+ const DISPLACED_KEYS = ['model', 'model_provider'];
59
+ const DISPLACED_KEY_PATTERN = new RegExp(`^\\s*(?:${DISPLACED_KEYS.join('|')})\\s*=`);
60
+ /** A line opening a TOML table, after which bare keys belong to that table. */
61
+ function isTableHeader(line) {
62
+ return /^\s*\[/.test(line);
63
+ }
64
+ /**
65
+ * Comment out unmanaged root-level `model` / `model_provider` assignments.
66
+ *
67
+ * Only the document root matters: once the scan passes the first table header,
68
+ * any same-named key belongs to that table and is none of our business.
69
+ * Idempotent — a line already carrying `DISPLACED_PREFIX` is left alone.
70
+ */
71
+ export function commentDisplacedKeys(text) {
72
+ let inRootScope = true;
73
+ return text
74
+ .split('\n')
75
+ .map((line) => {
76
+ if (isTableHeader(line)) {
77
+ inRootScope = false;
78
+ return line;
79
+ }
80
+ if (!inRootScope)
81
+ return line;
82
+ if (line.startsWith(DISPLACED_PREFIX))
83
+ return line;
84
+ if (!DISPLACED_KEY_PATTERN.test(line))
85
+ return line;
86
+ return `${DISPLACED_PREFIX}${line}`;
87
+ })
88
+ .join('\n');
89
+ }
90
+ /** Exact inverse of `commentDisplacedKeys`. */
91
+ export function restoreDisplacedKeys(text) {
92
+ return text
93
+ .split('\n')
94
+ .map((line) => (line.startsWith(DISPLACED_PREFIX) ? line.slice(DISPLACED_PREFIX.length) : line))
95
+ .join('\n');
96
+ }
97
+ /**
98
+ * Remove both managed regions, line by line.
99
+ *
100
+ * Line-based rather than offset-based on purpose: `spliceManagedBlocks` inserts
101
+ * each region as whole lines plus exactly one blank separator line, so removing
102
+ * whole lines plus exactly one separator is its precise inverse. Slicing by
103
+ * character offset cannot express "and the blank line that came with it", which
104
+ * is what makes `strip(splice(x)) === x` hold here.
105
+ */
106
+ /** Index of the matching close sentinel after `from`, or -1 when unterminated. */
107
+ function findClose(lines, from, close) {
108
+ for (let i = from + 1; i < lines.length; i++) {
109
+ if (isSentinel(lines[i], close))
110
+ return i;
111
+ }
112
+ return -1;
113
+ }
114
+ function cutRegionLines(text) {
115
+ const lines = text.split('\n');
116
+ const keep = [];
117
+ let i = 0;
118
+ while (i < lines.length) {
119
+ if (isSentinel(lines[i], HEADER_OPEN)) {
120
+ const closeAt = findClose(lines, i, HEADER_CLOSE);
121
+ if (closeAt === -1) {
122
+ // Unterminated region: keep the line verbatim rather than consuming the
123
+ // rest of the file. Deleting to EOF here would destroy a user config
124
+ // whose close marker was removed, and would contradict
125
+ // findManagedRegions, which reports such a region as absent.
126
+ keep.push(lines[i]);
127
+ i++;
128
+ continue;
129
+ }
130
+ i = closeAt + 1;
131
+ // The header chunk owns exactly one blank line after it.
132
+ if (i < lines.length && lines[i].trim() === '')
133
+ i++;
134
+ continue;
135
+ }
136
+ if (isSentinel(lines[i], TABLE_OPEN)) {
137
+ const closeAt = findClose(lines, i, TABLE_CLOSE);
138
+ if (closeAt === -1) {
139
+ keep.push(lines[i]);
140
+ i++;
141
+ continue;
142
+ }
143
+ // The table chunk owns exactly one blank line before it.
144
+ if (keep.length > 0 && keep[keep.length - 1].trim() === '')
145
+ keep.pop();
146
+ i = closeAt + 1;
147
+ continue;
148
+ }
149
+ keep.push(lines[i]);
150
+ i++;
151
+ }
152
+ return keep.join('\n');
153
+ }
154
+ /** Normalize to `''` or text terminated by exactly one newline. */
155
+ function normalizeBase(text) {
156
+ if (text.trim() === '')
157
+ return '';
158
+ return text.endsWith('\n') ? text : `${text}\n`;
159
+ }
160
+ /**
161
+ * Insert both managed regions, replacing any that already exist. The header is
162
+ * prepended (TOML bare keys must precede the first table header) and the table
163
+ * is appended. Every line outside the two regions is preserved verbatim.
164
+ */
165
+ export function spliceManagedBlocks(text, blocks) {
166
+ const base = normalizeBase(commentDisplacedKeys(cutRegionLines(text)));
167
+ const header = [HEADER_OPEN, blocks.header, HEADER_CLOSE].join('\n');
168
+ const table = [TABLE_OPEN, blocks.table, TABLE_CLOSE].join('\n');
169
+ if (base === '')
170
+ return `${header}\n\n${table}\n`;
171
+ return `${header}\n\n${base}\n${table}\n`;
172
+ }
173
+ /**
174
+ * Remove both managed regions and restore any keys the splice displaced,
175
+ * yielding the text the file held before `spliceManagedBlocks` ran.
176
+ */
177
+ export function stripManagedRegions(text) {
178
+ const restored = restoreDisplacedKeys(cutRegionLines(text));
179
+ if (restored.trim() === '')
180
+ return '';
181
+ return restored.endsWith('\n') ? restored : `${restored}\n`;
182
+ }
183
+ /** The provider id CodeMie owns in the user's Codex config. */
184
+ export const CODEMIE_PROVIDER_ID = 'codemie';
185
+ /** Escape a value for a TOML basic string. */
186
+ function toTomlString(value) {
187
+ const escaped = value
188
+ .replace(/\\/g, '\\\\')
189
+ .replace(/"/g, '\\"')
190
+ .replace(/\n/g, '\\n');
191
+ return `"${escaped}"`;
192
+ }
193
+ /**
194
+ * Render the two managed region bodies.
195
+ *
196
+ * `wire_api` is always `responses`: Codex removed the `chat` wire API in
197
+ * February 2026, so a custom provider declaring anything else fails at startup.
198
+ * The gateway key travels as a static `http_headers` entry rather than an
199
+ * `env_key`, because a desktop app does not inherit the shell environment — and
200
+ * never via `~/.codex/auth.json`, because writing there flips the app into
201
+ * API-key auth mode and disables its ChatGPT-account features.
202
+ */
203
+ export function buildManagedBlocks(input) {
204
+ const header = [
205
+ `model_provider = ${toTomlString(CODEMIE_PROVIDER_ID)}`,
206
+ `model = ${toTomlString(input.model)}`,
207
+ ].join('\n');
208
+ const table = [
209
+ `[model_providers.${CODEMIE_PROVIDER_ID}]`,
210
+ `name = ${toTomlString('CodeMie')}`,
211
+ `base_url = ${toTomlString(input.baseUrl)}`,
212
+ 'wire_api = "responses"',
213
+ `[model_providers.${CODEMIE_PROVIDER_ID}.http_headers]`,
214
+ `Authorization = ${toTomlString(`Bearer ${input.gatewayKey}`)}`,
215
+ ].join('\n');
216
+ return { header, table };
217
+ }
218
+ //# sourceMappingURL=codex-config-toml.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"codex-config-toml.js","sourceRoot":"","sources":["../../../../../src/cli/commands/proxy/connectors/codex-config-toml.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,85 @@
1
+ /**
2
+ * Resolve the config file the desktop app reads.
3
+ *
4
+ * Deliberately NOT `getCodexHomePath()` from the codex agent plugin. That helper
5
+ * is used by code paths which redirect `CODEX_HOME` to a CodeMie-isolated home
6
+ * for the CLI they spawn, and the desktop app never reads that home. A
7
+ * `CODEX_HOME` visible here belongs to the user, and upstream documents the app
8
+ * respecting it, so it is honoured.
9
+ */
10
+ export declare function getCodexDesktopConfigPath(): string;
11
+ /** Where the connector records what it owns, mirroring the Claude Desktop precedent. */
12
+ export declare function getCodexDesktopStatePath(): string;
13
+ /** Install locations for the ChatGPT desktop app, which is what ships Codex. */
14
+ export declare function getCodexDesktopAppCandidates(): string[];
15
+ /** First candidate path that exists, or null. */
16
+ export declare function findCodexDesktopApp(candidates?: string[]): string | null;
17
+ /** Suffix for the pre-connect snapshot of the user's Codex config. */
18
+ export declare const BACKUP_SUFFIX = ".codemie-backup";
19
+ /**
20
+ * Snapshot the config only when CodeMie does not already own part of it.
21
+ *
22
+ * Keyed on marker presence rather than backup presence on purpose. Once our
23
+ * block is in the file, the existing backup is the true pre-CodeMie original and
24
+ * must not be replaced by a copy that already contains our block — which is the
25
+ * bug the Kimi hook injector's create-once backup has.
26
+ */
27
+ export declare function backupIfUnmanaged(configPath: string, currentText: string): Promise<string | null>;
28
+ /**
29
+ * Discover Codex-compatible model ids through the local proxy.
30
+ *
31
+ * Discovery goes through the proxy rather than the backend so the connector
32
+ * exercises exactly the path the app will use — a broken proxy fails here,
33
+ * before the config is written, rather than after.
34
+ */
35
+ export declare function discoverCodexModels(proxyUrl: string, gatewayKey: string): Promise<string[]>;
36
+ /**
37
+ * Choose the model to pin.
38
+ *
39
+ * An explicit request is resolved with the same rule the proxy applies to
40
+ * in-flight requests, so `--model gpt-5.6-luna` — the undated name the app's
41
+ * model picker displays — pins the dated deployment behind it rather than being
42
+ * rejected. Anything with no CodeMie equivalent is an error here: at connect
43
+ * time the user is present and can be told, so silently substituting would mean
44
+ * they run something other than what they asked for.
45
+ */
46
+ export declare function selectCodexModel(discovered: string[], requested?: string): string;
47
+ export interface CodexDesktopState {
48
+ configPath: string;
49
+ backupPath: string | null;
50
+ model: string;
51
+ writtenAt: string;
52
+ }
53
+ export interface WriteCodexDesktopConfigOptions {
54
+ configPath: string;
55
+ statePath: string;
56
+ proxyUrl: string;
57
+ baseUrl: string;
58
+ gatewayKey: string;
59
+ model: string;
60
+ force?: boolean;
61
+ }
62
+ /**
63
+ * Splice the managed block into the user's Codex config and record ownership.
64
+ *
65
+ * The marker state is written BEFORE the config on purpose. If the config write
66
+ * then fails, the marker over-claims — and removal is idempotent, so that is
67
+ * harmless. The reverse order is genuinely unsafe: a written config with no
68
+ * marker is one CodeMie can no longer recognize as its own.
69
+ */
70
+ export declare function writeCodexDesktopConfig(options: WriteCodexDesktopConfigOptions): Promise<CodexDesktopState>;
71
+ export interface RemoveCodexDesktopResult {
72
+ removed: boolean;
73
+ usedBackup: boolean;
74
+ configPath: string | null;
75
+ }
76
+ /**
77
+ * Remove the managed block, restoring the file to its pre-connect content.
78
+ *
79
+ * The surgical strip is the primary path rather than a wholesale backup restore:
80
+ * a blind restore would also throw away any edits the user made to their Codex
81
+ * config while connected. The backup is the fallback for when stripping cannot
82
+ * produce a parseable file.
83
+ */
84
+ export declare function removeCodexDesktopConfig(statePath?: string): Promise<RemoveCodexDesktopResult>;
85
+ //# sourceMappingURL=codex-desktop.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"codex-desktop.d.ts","sourceRoot":"","sources":["../../../../../src/cli/commands/proxy/connectors/codex-desktop.ts"],"names":[],"mappings":"AAiCA;;;;;;;;GAQG;AACH,wBAAgB,yBAAyB,IAAI,MAAM,CAGlD;AAED,wFAAwF;AACxF,wBAAgB,wBAAwB,IAAI,MAAM,CAEjD;AAED,gFAAgF;AAChF,wBAAgB,4BAA4B,IAAI,MAAM,EAAE,CAiBvD;AAED,iDAAiD;AACjD,wBAAgB,mBAAmB,CACjC,UAAU,GAAE,MAAM,EAAmC,GACpD,MAAM,GAAG,IAAI,CAEf;AAKD,sEAAsE;AACtE,eAAO,MAAM,aAAa,oBAAoB,CAAC;AAE/C;;;;;;;GAOG;AACH,wBAAsB,iBAAiB,CACrC,UAAU,EAAE,MAAM,EAClB,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAwBxB;AAED;;;;;;GAMG;AACH,wBAAsB,mBAAmB,CACvC,QAAQ,EAAE,MAAM,EAChB,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,MAAM,EAAE,CAAC,CAqCnB;AAED;;;;;;;;;GASG;AACH,wBAAgB,gBAAgB,CAAC,UAAU,EAAE,MAAM,EAAE,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,MAAM,CAYjF;AAED,MAAM,WAAW,iBAAiB;IAChC,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,8BAA8B;IAC7C,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAoBD;;;;;;;GAOG;AACH,wBAAsB,uBAAuB,CAC3C,OAAO,EAAE,8BAA8B,GACtC,OAAO,CAAC,iBAAiB,CAAC,CA6D5B;AAoBD,MAAM,WAAW,wBAAwB;IACvC,OAAO,EAAE,OAAO,CAAC;IACjB,UAAU,EAAE,OAAO,CAAC;IACpB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;CAC3B;AAED;;;;;;;GAOG;AACH,wBAAsB,wBAAwB,CAC5C,SAAS,GAAE,MAAmC,GAC7C,OAAO,CAAC,wBAAwB,CAAC,CA2DnC"}
@@ -0,0 +1,299 @@
1
+ /**
2
+ * Connector that points the Codex desktop app (Codex inside the ChatGPT desktop
3
+ * app) at the local CodeMie proxy by splicing a managed provider block into the
4
+ * user's `~/.codex/config.toml`.
5
+ *
6
+ * CodeMie never installs, launches or patches the app — the shared config file
7
+ * that the app and the Codex CLI both read is the whole integration seam.
8
+ */
9
+ import { existsSync } from 'node:fs';
10
+ import { copyFile, readFile } from 'node:fs/promises';
11
+ import { homedir } from 'node:os';
12
+ import { join } from 'node:path';
13
+ import TOML from '@iarna/toml';
14
+ import { rankCodexModelIdsByRecency } from '../../../../agents/plugins/codex/codex-models.js';
15
+ import { ConfigurationError } from '../../../../utils/errors.js';
16
+ import { logger } from '../../../../utils/logger.js';
17
+ import { getCodemiePath } from '../../../../utils/paths.js';
18
+ import { sanitizeLogArgs } from '../../../../utils/security.js';
19
+ import { CODEMIE_PROVIDER_ID, buildManagedBlocks, findManagedRegions, spliceManagedBlocks, stripManagedRegions, } from './codex-config-toml.js';
20
+ import { resolveCodexDeployment } from '../../../../providers/plugins/sso/proxy/plugins/codex-model-resolver.js';
21
+ import { writeAtomically } from './vscode.js';
22
+ /**
23
+ * Resolve the config file the desktop app reads.
24
+ *
25
+ * Deliberately NOT `getCodexHomePath()` from the codex agent plugin. That helper
26
+ * is used by code paths which redirect `CODEX_HOME` to a CodeMie-isolated home
27
+ * for the CLI they spawn, and the desktop app never reads that home. A
28
+ * `CODEX_HOME` visible here belongs to the user, and upstream documents the app
29
+ * respecting it, so it is honoured.
30
+ */
31
+ export function getCodexDesktopConfigPath() {
32
+ const codexHome = process.env.CODEX_HOME || join(homedir(), '.codex');
33
+ return join(codexHome, 'config.toml');
34
+ }
35
+ /** Where the connector records what it owns, mirroring the Claude Desktop precedent. */
36
+ export function getCodexDesktopStatePath() {
37
+ return getCodemiePath('proxy', 'codex-desktop-state.json');
38
+ }
39
+ /** Install locations for the ChatGPT desktop app, which is what ships Codex. */
40
+ export function getCodexDesktopAppCandidates() {
41
+ const home = homedir();
42
+ if (process.platform === 'darwin') {
43
+ return [
44
+ '/Applications/ChatGPT.app',
45
+ join(home, 'Applications', 'ChatGPT.app'),
46
+ ];
47
+ }
48
+ if (process.platform === 'win32') {
49
+ const localAppData = process.env.LOCALAPPDATA ?? join(home, 'AppData', 'Local');
50
+ const programFiles = process.env.ProgramFiles ?? 'C:\\Program Files';
51
+ return [
52
+ join(localAppData, 'Programs', 'ChatGPT'),
53
+ join(programFiles, 'ChatGPT'),
54
+ ];
55
+ }
56
+ return [];
57
+ }
58
+ /** First candidate path that exists, or null. */
59
+ export function findCodexDesktopApp(candidates = getCodexDesktopAppCandidates()) {
60
+ return candidates.find((candidate) => existsSync(candidate)) ?? null;
61
+ }
62
+ /** Bound on the connect-time model listing. */
63
+ const MODEL_LIST_TIMEOUT_MS = 15000;
64
+ /** Suffix for the pre-connect snapshot of the user's Codex config. */
65
+ export const BACKUP_SUFFIX = '.codemie-backup';
66
+ /**
67
+ * Snapshot the config only when CodeMie does not already own part of it.
68
+ *
69
+ * Keyed on marker presence rather than backup presence on purpose. Once our
70
+ * block is in the file, the existing backup is the true pre-CodeMie original and
71
+ * must not be replaced by a copy that already contains our block — which is the
72
+ * bug the Kimi hook injector's create-once backup has.
73
+ */
74
+ export async function backupIfUnmanaged(configPath, currentText) {
75
+ if (!existsSync(configPath))
76
+ return null;
77
+ const backupPath = `${configPath}${BACKUP_SUFFIX}`;
78
+ const regions = findManagedRegions(currentText);
79
+ const alreadyManaged = regions.header !== null || regions.table !== null;
80
+ if (alreadyManaged) {
81
+ if (existsSync(backupPath)) {
82
+ logger.debug('[proxy] Codex config already managed; keeping existing backup', { backupPath });
83
+ return backupPath;
84
+ }
85
+ // Managed but the backup is gone. Copying the file as-is would enshrine our
86
+ // own block — bearer token included — as the "pre-connect original", and a
87
+ // later disconnect fallback would restore the credential. Reconstruct the
88
+ // original by stripping the managed regions instead.
89
+ await writeAtomically(backupPath, stripManagedRegions(currentText));
90
+ logger.debug('[proxy] Rebuilt missing Codex config backup without managed content', { backupPath });
91
+ return backupPath;
92
+ }
93
+ await copyFile(configPath, backupPath);
94
+ logger.debug('[proxy] Backed up Codex config', { configPath, backupPath });
95
+ return backupPath;
96
+ }
97
+ /**
98
+ * Discover Codex-compatible model ids through the local proxy.
99
+ *
100
+ * Discovery goes through the proxy rather than the backend so the connector
101
+ * exercises exactly the path the app will use — a broken proxy fails here,
102
+ * before the config is written, rather than after.
103
+ */
104
+ export async function discoverCodexModels(proxyUrl, gatewayKey) {
105
+ const url = new URL('/v1/llm_models?include_all=true', proxyUrl).toString();
106
+ let response;
107
+ try {
108
+ response = await fetch(url, {
109
+ headers: { Authorization: `Bearer ${gatewayKey}` },
110
+ // A proxy that accepts the socket but never answers would otherwise hang
111
+ // `proxy connect` indefinitely, after the daemon has already started.
112
+ signal: AbortSignal.timeout(MODEL_LIST_TIMEOUT_MS),
113
+ });
114
+ }
115
+ catch (error) {
116
+ throw new ConfigurationError(`Could not reach the local proxy at ${proxyUrl} to list models: ` +
117
+ `${error instanceof Error ? error.message : String(error)}`);
118
+ }
119
+ if (!response.ok) {
120
+ throw new ConfigurationError(`Local proxy returned ${response.status} for ${url}.`);
121
+ }
122
+ const payload = (await response.json());
123
+ const entries = Array.isArray(payload) ? payload : (payload.data ?? []);
124
+ // Ranked newest-first. The gateway's own order is arbitrary and in practice
125
+ // lists the oldest GPT-5 first, so taking entries[0] would pin a stale model.
126
+ const ids = rankCodexModelIdsByRecency(entries);
127
+ if (ids.length === 0) {
128
+ throw new ConfigurationError('The local proxy exposes no GPT/Codex-compatible model. ' +
129
+ 'Enable a GPT-5/Codex deployment in CodeMie, then re-run this command.');
130
+ }
131
+ return ids;
132
+ }
133
+ /**
134
+ * Choose the model to pin.
135
+ *
136
+ * An explicit request is resolved with the same rule the proxy applies to
137
+ * in-flight requests, so `--model gpt-5.6-luna` — the undated name the app's
138
+ * model picker displays — pins the dated deployment behind it rather than being
139
+ * rejected. Anything with no CodeMie equivalent is an error here: at connect
140
+ * time the user is present and can be told, so silently substituting would mean
141
+ * they run something other than what they asked for.
142
+ */
143
+ export function selectCodexModel(discovered, requested) {
144
+ if (requested === undefined)
145
+ return discovered[0];
146
+ if (requested.trim() === '') {
147
+ throw new ConfigurationError('--model was given an empty value.');
148
+ }
149
+ const resolution = resolveCodexDeployment(requested.trim(), discovered, undefined);
150
+ if (resolution.kind === 'exact' || resolution.kind === 'resolved')
151
+ return resolution.model;
152
+ throw new ConfigurationError(`Model "${requested}" is not available through the proxy. Available: ${discovered.join(', ')}`);
153
+ }
154
+ /** Read the config, or empty text when the file does not exist yet. */
155
+ async function readConfigText(configPath) {
156
+ if (!existsSync(configPath))
157
+ return '';
158
+ return readFile(configPath, 'utf-8');
159
+ }
160
+ /** Parse for validation only — the file itself is never re-serialized. */
161
+ function parseOrThrow(text, configPath) {
162
+ try {
163
+ return TOML.parse(text);
164
+ }
165
+ catch (error) {
166
+ throw new ConfigurationError(`Codex config at ${configPath} is not valid TOML and was not changed: ` +
167
+ `${error instanceof Error ? error.message : String(error)}`);
168
+ }
169
+ }
170
+ /**
171
+ * Splice the managed block into the user's Codex config and record ownership.
172
+ *
173
+ * The marker state is written BEFORE the config on purpose. If the config write
174
+ * then fails, the marker over-claims — and removal is idempotent, so that is
175
+ * harmless. The reverse order is genuinely unsafe: a written config with no
176
+ * marker is one CodeMie can no longer recognize as its own.
177
+ */
178
+ export async function writeCodexDesktopConfig(options) {
179
+ const currentText = await readConfigText(options.configPath);
180
+ // Validate and check for conflicts before touching anything on disk.
181
+ if (currentText.trim() !== '') {
182
+ const parsed = parseOrThrow(currentText, options.configPath);
183
+ const active = parsed.model_provider;
184
+ if (!options.force && typeof active === 'string' && active !== CODEMIE_PROVIDER_ID) {
185
+ throw new ConfigurationError(`Codex config already selects model_provider "${active}". ` +
186
+ 'Re-run with --force to replace it with the CodeMie provider.');
187
+ }
188
+ }
189
+ const backupPath = await backupIfUnmanaged(options.configPath, currentText);
190
+ const state = {
191
+ configPath: options.configPath,
192
+ backupPath,
193
+ model: options.model,
194
+ writtenAt: new Date().toISOString(),
195
+ };
196
+ await writeAtomically(options.statePath, `${JSON.stringify(state, null, 2)}\n`);
197
+ const blocks = buildManagedBlocks({
198
+ baseUrl: options.baseUrl,
199
+ gatewayKey: options.gatewayKey,
200
+ model: options.model,
201
+ });
202
+ const next = spliceManagedBlocks(currentText, blocks);
203
+ // Validate what we are about to write, not just what we read. Every splice
204
+ // edge case — a duplicated region, an unrecognized quoted key, a value that
205
+ // escaping did not cover — surfaces here instead of landing a broken
206
+ // config.toml on the user's disk.
207
+ try {
208
+ TOML.parse(next);
209
+ }
210
+ catch (error) {
211
+ throw new ConfigurationError(`Refusing to write ${options.configPath}: the result would not be valid TOML ` +
212
+ `(${error instanceof Error ? error.message : String(error)}). The file is unchanged.`);
213
+ }
214
+ await writeAtomically(options.configPath, next);
215
+ // The gateway key is deliberately absent: sanitizeLogArgs redacts by key name,
216
+ // and `gatewayKey` matches none of its patterns, so passing it would write the
217
+ // credential to the log in cleartext. Nothing here needs it.
218
+ logger.info('[proxy] Codex desktop configuration written', ...sanitizeLogArgs({
219
+ configPath: options.configPath,
220
+ backupPath,
221
+ model: options.model,
222
+ baseUrl: options.baseUrl,
223
+ }));
224
+ return state;
225
+ }
226
+ /**
227
+ * Throw when a stripped config still carries CodeMie-owned keys.
228
+ *
229
+ * The post-strip check for disconnect: a parseable result that still selects the
230
+ * CodeMie provider means removal did not actually happen, which is what occurs
231
+ * when the managed sentinels have been lost.
232
+ */
233
+ function assertNoCodeMieKeys(parsed) {
234
+ if (parsed.model_provider === CODEMIE_PROVIDER_ID) {
235
+ throw new Error(`model_provider is still "${CODEMIE_PROVIDER_ID}"`);
236
+ }
237
+ const providers = parsed.model_providers;
238
+ if (providers !== null && typeof providers === 'object'
239
+ && CODEMIE_PROVIDER_ID in providers) {
240
+ throw new Error(`model_providers.${CODEMIE_PROVIDER_ID} is still present`);
241
+ }
242
+ }
243
+ /**
244
+ * Remove the managed block, restoring the file to its pre-connect content.
245
+ *
246
+ * The surgical strip is the primary path rather than a wholesale backup restore:
247
+ * a blind restore would also throw away any edits the user made to their Codex
248
+ * config while connected. The backup is the fallback for when stripping cannot
249
+ * produce a parseable file.
250
+ */
251
+ export async function removeCodexDesktopConfig(statePath = getCodexDesktopStatePath()) {
252
+ if (!existsSync(statePath)) {
253
+ return { removed: false, usedBackup: false, configPath: null };
254
+ }
255
+ const raw = await readFile(statePath, 'utf-8');
256
+ if (raw.trim() === '') {
257
+ return { removed: false, usedBackup: false, configPath: null };
258
+ }
259
+ let state;
260
+ try {
261
+ state = JSON.parse(raw);
262
+ }
263
+ catch (error) {
264
+ throw new ConfigurationError(`CodeMie Codex desktop state at ${statePath} is unreadable: ` +
265
+ `${error instanceof Error ? error.message : String(error)}`);
266
+ }
267
+ if (!existsSync(state.configPath)) {
268
+ await writeAtomically(statePath, '');
269
+ return { removed: false, usedBackup: false, configPath: state.configPath };
270
+ }
271
+ const currentText = await readFile(state.configPath, 'utf-8');
272
+ const stripped = stripManagedRegions(currentText);
273
+ let nextText = stripped;
274
+ let usedBackup = false;
275
+ try {
276
+ if (stripped.trim() !== '') {
277
+ const parsed = TOML.parse(stripped);
278
+ // Parsing is not enough: if the sentinels were lost the strip is a silent
279
+ // no-op, and reporting success would leave the CodeMie provider — and its
280
+ // bearer header — in the user's config.
281
+ assertNoCodeMieKeys(parsed);
282
+ }
283
+ }
284
+ catch {
285
+ if (!state.backupPath || !existsSync(state.backupPath)) {
286
+ throw new ConfigurationError(`Could not cleanly remove the CodeMie block from ${state.configPath} ` +
287
+ '(the managed markers appear to be damaged or missing) and no backup is ' +
288
+ `available to restore. Remove the model_provider and [model_providers.${CODEMIE_PROVIDER_ID}] ` +
289
+ 'entries by hand.');
290
+ }
291
+ nextText = await readFile(state.backupPath, 'utf-8');
292
+ usedBackup = true;
293
+ logger.warn('[proxy] Surgical removal of the CodeMie Codex block failed; restored the backup', ...sanitizeLogArgs({ configPath: state.configPath, backupPath: state.backupPath }));
294
+ }
295
+ await writeAtomically(state.configPath, nextText);
296
+ await writeAtomically(statePath, '');
297
+ return { removed: true, usedBackup, configPath: state.configPath };
298
+ }
299
+ //# sourceMappingURL=codex-desktop.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"codex-desktop.js","sourceRoot":"","sources":["../../../../../src/cli/commands/proxy/connectors/codex-desktop.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,26 @@
1
+ export interface WriteVsCodeClaudeCodeConfigResult {
2
+ written: boolean;
3
+ path: string;
4
+ }
5
+ /**
6
+ * Resolve the VS Code Claude Code extension's `settings.json` path for the given
7
+ * VS Code edition, mirroring `vscode.ts`'s `getVsCodeLanguageModelsPath` — including its
8
+ * throw when the product's user-data directory doesn't exist, so a missing edition fails
9
+ * loudly instead of silently writing into a directory tree nothing will ever read.
10
+ */
11
+ export declare function getVsCodeClaudeCodeSettingsPath(insiders?: boolean): string;
12
+ /**
13
+ * Write CodeMie's managed `claudeCode.*` keys into the VS Code Claude Code extension's
14
+ * `settings.json` at an explicit path. Preserves every unrelated top-level key and every
15
+ * unrelated `claudeCode.environmentVariables` entry (e.g. keys the user set manually) —
16
+ * only `ANTHROPIC_BASE_URL`/`ANTHROPIC_AUTH_TOKEN` entries and `disableLoginPrompt` are
17
+ * CodeMie-managed and get overwritten.
18
+ */
19
+ export declare function writeVsCodeClaudeCodeConfigAtPath(configPath: string, gatewayUrl: string, gatewayKey: string): Promise<WriteVsCodeClaudeCodeConfigResult>;
20
+ /**
21
+ * Write CodeMie's managed `claudeCode.*` keys into the current user's VS Code (or VS Code
22
+ * Insiders) `settings.json`, so the bundled Claude Code extension routes through the local
23
+ * gateway daemon without a Claude.ai OAuth login prompt.
24
+ */
25
+ export declare function writeVsCodeClaudeCodeConfig(gatewayUrl: string, gatewayKey: string, insiders?: boolean): Promise<WriteVsCodeClaudeCodeConfigResult>;
26
+ //# sourceMappingURL=vscode-claude-code.d.ts.map