xcode-copilot-server 2.2.0 → 3.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.
Files changed (150) hide show
  1. package/README.md +83 -26
  2. package/config.json5 +13 -8
  3. package/dist/cli-validators.js +2 -2
  4. package/dist/cli-validators.js.map +1 -1
  5. package/dist/config.d.ts +1 -1
  6. package/dist/config.js +1 -1
  7. package/dist/config.js.map +1 -1
  8. package/dist/conversation-manager.d.ts +2 -1
  9. package/dist/conversation-manager.js +20 -1
  10. package/dist/conversation-manager.js.map +1 -1
  11. package/dist/handlers/responses/streaming.d.ts +6 -0
  12. package/dist/handlers/responses/streaming.js +265 -0
  13. package/dist/handlers/responses/streaming.js.map +1 -0
  14. package/dist/handlers/responses/tool-result-handler.d.ts +4 -0
  15. package/dist/handlers/responses/tool-result-handler.js +9 -0
  16. package/dist/handlers/responses/tool-result-handler.js.map +1 -0
  17. package/dist/handlers/responses.d.ts +4 -0
  18. package/dist/handlers/responses.js +164 -0
  19. package/dist/handlers/responses.js.map +1 -0
  20. package/dist/handlers/streaming-utils.d.ts +1 -0
  21. package/dist/handlers/streaming-utils.js +3 -0
  22. package/dist/handlers/streaming-utils.js.map +1 -1
  23. package/dist/index.js +23 -108
  24. package/dist/index.js.map +1 -1
  25. package/dist/providers/claude/count-tokens.d.ts +3 -0
  26. package/dist/providers/claude/count-tokens.js +72 -0
  27. package/dist/providers/claude/count-tokens.js.map +1 -0
  28. package/dist/providers/claude/handler.d.ts +4 -0
  29. package/dist/providers/claude/handler.js +150 -0
  30. package/dist/providers/claude/handler.js.map +1 -0
  31. package/dist/providers/claude/prompt.d.ts +2 -0
  32. package/dist/providers/claude/prompt.js +52 -0
  33. package/dist/providers/claude/prompt.js.map +1 -0
  34. package/dist/providers/claude/provider.d.ts +5 -0
  35. package/dist/providers/claude/provider.js +28 -0
  36. package/dist/providers/claude/provider.js.map +1 -0
  37. package/dist/providers/claude/schemas.d.ts +140 -0
  38. package/dist/providers/claude/schemas.js +58 -0
  39. package/dist/providers/claude/schemas.js.map +1 -0
  40. package/dist/providers/claude/streaming.d.ts +6 -0
  41. package/dist/providers/claude/streaming.js +116 -0
  42. package/dist/providers/claude/streaming.js.map +1 -0
  43. package/dist/providers/claude/tool-results.d.ts +4 -0
  44. package/dist/providers/claude/tool-results.js +19 -0
  45. package/dist/providers/claude/tool-results.js.map +1 -0
  46. package/dist/providers/codex/handler.d.ts +4 -0
  47. package/dist/providers/codex/handler.js +164 -0
  48. package/dist/providers/codex/handler.js.map +1 -0
  49. package/dist/providers/codex/prompt.d.ts +4 -0
  50. package/dist/providers/codex/prompt.js +58 -0
  51. package/dist/providers/codex/prompt.js.map +1 -0
  52. package/dist/providers/codex/provider.d.ts +5 -0
  53. package/dist/providers/codex/provider.js +24 -0
  54. package/dist/providers/codex/provider.js.map +1 -0
  55. package/dist/providers/codex/schemas.d.ts +122 -0
  56. package/dist/providers/codex/schemas.js +55 -0
  57. package/dist/providers/codex/schemas.js.map +1 -0
  58. package/dist/providers/codex/streaming.d.ts +9 -0
  59. package/dist/providers/codex/streaming.js +172 -0
  60. package/dist/providers/codex/streaming.js.map +1 -0
  61. package/dist/providers/codex/tool-results.d.ts +4 -0
  62. package/dist/providers/codex/tool-results.js +9 -0
  63. package/dist/providers/codex/tool-results.js.map +1 -0
  64. package/dist/providers/codex.d.ts +5 -0
  65. package/dist/providers/codex.js +24 -0
  66. package/dist/providers/codex.js.map +1 -0
  67. package/dist/providers/index.d.ts +6 -1
  68. package/dist/providers/index.js +5 -3
  69. package/dist/providers/index.js.map +1 -1
  70. package/dist/providers/openai/handler.d.ts +4 -0
  71. package/dist/providers/openai/handler.js +120 -0
  72. package/dist/providers/openai/handler.js.map +1 -0
  73. package/dist/providers/openai/models.d.ts +3 -0
  74. package/dist/providers/openai/models.js +28 -0
  75. package/dist/providers/openai/models.js.map +1 -0
  76. package/dist/providers/openai/prompt.d.ts +3 -0
  77. package/dist/providers/openai/prompt.js +38 -0
  78. package/dist/providers/openai/prompt.js.map +1 -0
  79. package/dist/providers/openai/provider.d.ts +5 -0
  80. package/dist/providers/openai/provider.js +25 -0
  81. package/dist/providers/openai/provider.js.map +1 -0
  82. package/dist/providers/openai/schemas.d.ts +98 -0
  83. package/dist/providers/openai/schemas.js +76 -0
  84. package/dist/providers/openai/schemas.js.map +1 -0
  85. package/dist/providers/openai/streaming.d.ts +4 -0
  86. package/dist/providers/openai/streaming.js +121 -0
  87. package/dist/providers/openai/streaming.js.map +1 -0
  88. package/dist/providers/shared/errors.d.ts +5 -0
  89. package/dist/providers/shared/errors.js +10 -0
  90. package/dist/providers/shared/errors.js.map +1 -0
  91. package/dist/providers/shared/model-resolver.d.ts +3 -0
  92. package/dist/providers/shared/model-resolver.js +45 -0
  93. package/dist/providers/shared/model-resolver.js.map +1 -0
  94. package/dist/providers/shared/prompt-utils.d.ts +1 -0
  95. package/dist/providers/shared/prompt-utils.js +15 -0
  96. package/dist/providers/shared/prompt-utils.js.map +1 -0
  97. package/dist/providers/shared/session-config.d.ts +15 -0
  98. package/dist/providers/shared/session-config.js +98 -0
  99. package/dist/providers/shared/session-config.js.map +1 -0
  100. package/dist/providers/shared/streaming-core.d.ts +19 -0
  101. package/dist/providers/shared/streaming-core.js +176 -0
  102. package/dist/providers/shared/streaming-core.js.map +1 -0
  103. package/dist/providers/shared/streaming-utils.d.ts +10 -0
  104. package/dist/providers/shared/streaming-utils.js +28 -0
  105. package/dist/providers/shared/streaming-utils.js.map +1 -0
  106. package/dist/schemas/config.d.ts +19 -1
  107. package/dist/schemas/config.js +2 -1
  108. package/dist/schemas/config.js.map +1 -1
  109. package/dist/schemas/responses.d.ts +122 -0
  110. package/dist/schemas/responses.js +54 -0
  111. package/dist/schemas/responses.js.map +1 -0
  112. package/dist/server.js +1 -2
  113. package/dist/server.js.map +1 -1
  114. package/dist/settings-patcher/anthropic.d.ts +5 -0
  115. package/dist/{settings-patcher.js → settings-patcher/anthropic.js} +3 -7
  116. package/dist/settings-patcher/anthropic.js.map +1 -0
  117. package/dist/settings-patcher/claude.d.ts +5 -0
  118. package/dist/settings-patcher/claude.js +75 -0
  119. package/dist/settings-patcher/claude.js.map +1 -0
  120. package/dist/settings-patcher/codex.d.ts +23 -0
  121. package/dist/settings-patcher/codex.js +114 -0
  122. package/dist/settings-patcher/codex.js.map +1 -0
  123. package/dist/settings-patcher/index.d.ts +15 -0
  124. package/dist/settings-patcher/index.js +9 -0
  125. package/dist/settings-patcher/index.js.map +1 -0
  126. package/dist/{settings-patcher.d.ts → settings-patcher/types.d.ts} +1 -5
  127. package/dist/settings-patcher/types.js +2 -0
  128. package/dist/settings-patcher/types.js.map +1 -0
  129. package/dist/startup.d.ts +11 -0
  130. package/dist/startup.js +154 -0
  131. package/dist/startup.js.map +1 -0
  132. package/dist/tool-bridge/constants.d.ts +2 -0
  133. package/dist/tool-bridge/constants.js +3 -0
  134. package/dist/tool-bridge/constants.js.map +1 -0
  135. package/dist/tool-bridge/index.d.ts +1 -0
  136. package/dist/tool-bridge/index.js +1 -0
  137. package/dist/tool-bridge/index.js.map +1 -1
  138. package/dist/tool-bridge/routes.js +2 -1
  139. package/dist/tool-bridge/routes.js.map +1 -1
  140. package/dist/tool-bridge/session-lifecycle.js +1 -1
  141. package/dist/tool-bridge/state.d.ts +1 -1
  142. package/dist/tool-bridge/tool-cache.d.ts +1 -1
  143. package/dist/ui.d.ts +7 -0
  144. package/dist/ui.js +8 -0
  145. package/dist/ui.js.map +1 -1
  146. package/dist/utils/responses-prompt.d.ts +4 -0
  147. package/dist/utils/responses-prompt.js +58 -0
  148. package/dist/utils/responses-prompt.js.map +1 -0
  149. package/package.json +1 -1
  150. package/dist/settings-patcher.js.map +0 -1
package/README.md CHANGED
@@ -1,17 +1,18 @@
1
1
  # xcode-copilot-server [![npm version](https://img.shields.io/npm/v/xcode-copilot-server)](https://www.npmjs.com/package/xcode-copilot-server)
2
2
 
3
- A proxy API server that lets you use GitHub Copilot in Xcode, either as a custom model provider (OpenAI mode) or as the backend for Claude Agent (Anthropic mode).
3
+ A proxy API server that lets you use GitHub Copilot in Xcode, either as a custom model provider or as the backend for Claude Agent and Codex Agent.
4
4
 
5
5
  ## Why
6
6
 
7
7
  Xcode 26 added support for third-party LLM providers, but it only supports ChatGPT and Claude out of the box. If you have a GitHub Copilot subscription, there's no built-in way to use it.
8
8
 
9
- This server bridges the gap by wrapping the [GitHub Copilot SDK](https://github.com/github/copilot-sdk) and exposing it as an API that Xcode can talk to. It supports two modes:
9
+ This server bridges the gap by wrapping the [GitHub Copilot SDK](https://github.com/github/copilot-sdk) and exposing it as an API that Xcode can talk to. It supports three providers:
10
10
 
11
- - **OpenAI mode** (default): This exposes an OpenAI-compatible API so Xcode can use Copilot as a custom model provider. Xcode handles tool execution directly.
12
- - **Anthropic mode**: This exposes an Anthropic-compatible API so Xcode can use Copilot as the proxy for Claude Agent. A built-in tool bridge intercepts tool calls from the Copilot session and routes them back to Xcode for execution.
11
+ - **OpenAI** (default): Exposes an OpenAI-compatible completions API so Xcode can use Copilot as a custom model provider. Xcode handles tool execution directly.
12
+ - **Claude**: Exposes an Anthropic-compatible API so Xcode can use Copilot as the backend for Claude Agent. A built-in tool bridge intercepts tool calls and routes them back to Xcode for execution.
13
+ - **Codex**: Exposes an OpenAI Responses-compatible API so Xcode can use Copilot as the backend for Codex Agent. Same tool bridge as Claude.
13
14
 
14
- Both modes connect to Xcode's built-in MCP tools (via `xcrun mcpbridge`), giving Copilot access to your project's build logs, indexes and other context. This requires Xcode 26.3 or later.
15
+ In OpenAI mode, the server also connects to Xcode's built-in MCP tools (via `xcrun mcpbridge`), giving Copilot access to your project's build logs, indexes and other context. This requires Xcode 26.3 or later. Claude and Codex handle MCP internally through their own agents.
15
16
 
16
17
  ## Installation
17
18
 
@@ -40,29 +41,30 @@ xcode-copilot-server [options]
40
41
 
41
42
  Options:
42
43
  -p, --port <number> Port to listen on (default: 8080)
43
- --proxy <provider> API format: openai, anthropic (default: openai)
44
+ --proxy <provider> API format: openai, claude, codex (default: openai)
44
45
  -l, --log-level <level> Log verbosity (default: info)
45
46
  -c, --config <path> Path to config file
46
47
  --cwd <path> Working directory for Copilot sessions
47
- --auto-patch Auto-patch settings.json on start, restore on exit
48
+ --auto-patch Auto-patch settings on start, restore on exit
48
49
  -v, --version Output the version number
49
50
  -h, --help Show help
50
51
 
51
52
  Commands:
52
- patch-settings Patch Claude Agent's settings.json and exit (Anthropic mode)
53
- restore-settings Restore Claude Agent's settings.json from backup and exit
53
+ patch-settings Patch provider settings and exit (--proxy claude or codex)
54
+ restore-settings Restore provider settings from backup and exit
54
55
  ```
55
56
 
56
57
  The `--proxy` flag determines which API the server exposes:
57
58
 
58
- | Mode | Flag | Routes |
59
- |-----------|----------------------------|-------------------------------------------------------|
60
- | OpenAI | `--proxy openai` (default) | `GET /v1/models`, `POST /v1/chat/completions` |
61
- | Anthropic | `--proxy anthropic` | `POST /v1/messages`, `POST /v1/messages/count_tokens` |
59
+ | Provider | Flag | Routes |
60
+ |----------|----------------------------|-------------------------------------------------------|
61
+ | OpenAI | `--proxy openai` (default) | `GET /v1/models`, `POST /v1/chat/completions` |
62
+ | Claude | `--proxy claude` | `POST /v1/messages`, `POST /v1/messages/count_tokens` |
63
+ | Codex | `--proxy codex` | `POST /v1/responses` |
62
64
 
63
65
  ## Xcode integration
64
66
 
65
- ### OpenAI mode (custom model provider)
67
+ ### OpenAI (custom model provider)
66
68
 
67
69
  1. Start the server: `xcode-copilot-server`
68
70
  2. Open Xcode and go to Settings > Intelligence > Add a provider
@@ -72,14 +74,14 @@ The `--proxy` flag determines which API the server exposes:
72
74
 
73
75
  To enable tool calling, select the provider and enable "Allow tools" under "Advanced". To connect Xcode's MCP tools (Xcode 26.3+), enable "Xcode Tools" under "Model Context Protocol".
74
76
 
75
- ### Anthropic mode (Claude Agent)
77
+ ### Claude (Claude Agent)
76
78
 
77
79
  1. Open Xcode and go to Settings > Intelligence > Anthropic > Claude Agent
78
80
  2. Enable Claude Agent and sign in with an API key (the key can be any random text, since the calls are proxied through the server)
79
81
  3. Start the server with `--auto-patch` to automatically configure `settings.json`:
80
82
 
81
83
  ```bash
82
- xcode-copilot-server --proxy anthropic --auto-patch
84
+ xcode-copilot-server --proxy claude --auto-patch
83
85
  ```
84
86
 
85
87
  This creates (or updates) `settings.json` at `~/Library/Developer/Xcode/CodingAssistant/ClaudeAgentConfig/` to point to the server, and restores the original file when the server shuts down. If `settings.json` already exists, a backup is saved as `settings.json.backup` and restored on exit.
@@ -98,21 +100,68 @@ To enable tool calling, select the provider and enable "Allow tools" under "Adva
98
100
  Set the port to match your `--port` flag (default 8080). The auth token can be any non-empty string. Then start the server without `--auto-patch`:
99
101
 
100
102
  ```bash
101
- xcode-copilot-server --proxy anthropic
103
+ xcode-copilot-server --proxy claude
102
104
  ```
103
105
 
104
- You can also use the `patch-settings` and `restore-settings` subcommands to patch or restore `settings.json` without starting the server:
106
+ You can also use the `patch-settings` and `restore-settings` subcommands to patch or restore settings without starting the server:
105
107
 
106
108
  ```bash
107
- xcode-copilot-server patch-settings --port 8080
108
- xcode-copilot-server restore-settings
109
+ xcode-copilot-server patch-settings --proxy claude --port 8080
110
+ xcode-copilot-server restore-settings --proxy claude
109
111
  ```
110
112
 
111
- The tool bridge is enabled by default in Anthropic mode (`toolBridge: true` in the config). It intercepts tool calls from the Copilot session and forwards them to Xcode, so Claude Agent can read files, search code, and make edits through the IDE.
113
+ The tool bridge is enabled by default for Claude (`toolBridge: true` in the config). It intercepts tool calls from the Copilot session and forwards them to Xcode, so Claude Agent can read files, search code, and make edits through the IDE.
114
+
115
+ ### Codex (Codex Agent)
116
+
117
+ 1. Open Xcode and go to Settings > Intelligence > OpenAI > Codex Agent
118
+ 2. Enable Codex Agent and sign in with an API key (the key can be any random text, since the calls are proxied through the server)
119
+ 3. Start the server with `--auto-patch` to automatically configure the environment:
120
+
121
+ ```bash
122
+ xcode-copilot-server --proxy codex --auto-patch
123
+ ```
124
+
125
+ This sets `OPENAI_BASE_URL` and `OPENAI_API_KEY` via `launchctl setenv` so Xcode (and any Codex process it spawns) can reach the server. The original values are backed up and restored when the server shuts down. If Xcode was already running, you might need to restart it so it picks up the new environment variables.
126
+
127
+ Alternatively, you can set the environment variables yourself via `launchctl`:
128
+
129
+ ```bash
130
+ launchctl setenv OPENAI_BASE_URL http://localhost:8080/v1
131
+ launchctl setenv OPENAI_API_KEY 12345
132
+ ```
133
+
134
+ Set the port to match your `--port` flag (default 8080). The API key can be any non-empty string. Then start the server without `--auto-patch`:
135
+
136
+ ```bash
137
+ xcode-copilot-server --proxy codex
138
+ ```
139
+
140
+ To restore the original values when you're done:
141
+
142
+ ```bash
143
+ launchctl unsetenv OPENAI_BASE_URL
144
+ launchctl unsetenv OPENAI_API_KEY
145
+ ```
146
+
147
+ You can also use the `patch-settings` and `restore-settings` subcommands to do this without starting the server:
148
+
149
+ ```bash
150
+ xcode-copilot-server patch-settings --proxy codex --port 8080
151
+ xcode-copilot-server restore-settings --proxy codex
152
+ ```
153
+
154
+ The tool bridge works the same way as Claude, as it intercepts tool calls and routes them back to Xcode for execution.
112
155
 
113
156
  ### Agent skills
114
157
 
115
- The underlying Copilot CLI session can access and invoke [Agent skills](https://docs.github.com/en/copilot/customizing-copilot/extending-copilot-coding-agent-with-agent-skills), which are folders of instructions, scripts, and resources that improve Copilot's performance on specialised tasks. Skills stored in your repository (`.github/skills/` or `.claude/skills/`) and personal skills in your home directory (`~/.copilot/skills/` or `~/.claude/skills/`) are automatically available.
158
+ [Agent skills](https://docs.github.com/en/copilot/concepts/agents/about-agent-skills) are an open standard for extending AI coding agents with specialised instructions and resources. All three providers support them through the underlying Copilot SDK session, and each agent also has its own skill paths:
159
+
160
+ | Agent | Project skills | Personal skills |
161
+ |---------|--------------------------------------------|------------------------|
162
+ | Copilot | `.github/skills/`, `.claude/skills/` | `~/.copilot/skills/` |
163
+ | Claude | `.claude/skills/` | `~/.claude/skills/` |
164
+ | Codex | `.codex/skills/` | `~/.codex/skills/` |
116
165
 
117
166
  ## Configuration
118
167
 
@@ -122,7 +171,7 @@ The server reads its configuration from a `config.json5` file. By default, it us
122
171
  xcode-copilot-server --config ./my-config.json5
123
172
  ```
124
173
 
125
- The config file uses [JSON5](https://json5.org/) format, which supports comments and trailing commas. The `--proxy` flag determines which provider section (`openai` or `anthropic`) is used at runtime:
174
+ The config file uses [JSON5](https://json5.org/) format, which supports comments and trailing commas. The `--proxy` flag determines which provider section (`openai`, `claude`, or `codex`) is used at runtime:
126
175
 
127
176
  ```json5
128
177
  {
@@ -141,15 +190,23 @@ The config file uses [JSON5](https://json5.org/) format, which supports comments
141
190
  },
142
191
  },
143
192
 
144
- anthropic: {
193
+ claude: {
145
194
  // Intercepts tool calls and forwards them to Xcode so Claude Agent
146
- // can drive tool execution through the IDE.
195
+ // drives tool execution through the IDE instead of the Copilot CLI.
147
196
  toolBridge: true,
148
197
 
149
198
  // No MCP servers needed, as Claude Agent handles tools natively.
150
199
  mcpServers: {},
151
200
  },
152
201
 
202
+ codex: {
203
+ // Same as Claude: intercepts tool calls and forwards them to Xcode
204
+ // so Codex drives tool execution through the IDE.
205
+ toolBridge: true,
206
+
207
+ mcpServers: {},
208
+ },
209
+
153
210
  // Built-in CLI tools allowlist.
154
211
  // ["*"] to allow all, [] to deny all, or a list of specific tool names.
155
212
  //
@@ -181,7 +238,7 @@ The config file uses [JSON5](https://json5.org/) format, which supports comments
181
238
 
182
239
  This server acts as a local proxy between Xcode and GitHub Copilot. It's designed to run on your machine and isn't intended to be exposed to the internet or shared networks. So, here's what you should know:
183
240
 
184
- - The server binds to `127.0.0.1`, so it's only reachable from your machine. Incoming requests are checked for expected user-agent headers (`Xcode/` in OpenAI mode, `claude-cli/` in Anthropic mode), which means casual or accidental connections from other tools will be rejected. This isn't a strong security boundary since user-agent headers can be trivially spoofed, but it helps ensure only the expected client is talking to the server.
241
+ - The server binds to `127.0.0.1`, so it's only reachable from your machine. Incoming requests are checked for expected user-agent headers (`Xcode/` for OpenAI and Codex, `claude-cli/` for Claude), which means casual or accidental connections from other tools will be rejected. This isn't a strong security boundary since user-agent headers can be trivially spoofed, but it helps ensure only the expected client is talking to the server.
185
242
 
186
243
  - The bundled config sets `autoApprovePermissions` to `["read", "mcp"]`, which lets the Copilot session read files and call MCP tools without prompting. Writes, shell commands, and URL fetches are denied by default. You can set it to `true` to approve everything, `false` to deny everything, or pick specific kinds from `"read"`, `"write"`, `"shell"`, `"mcp"`, and `"url"`.
187
244
 
package/config.json5 CHANGED
@@ -5,12 +5,11 @@
5
5
  // exists in both CLI and MCP tools then they can't have different permissions.
6
6
 
7
7
  {
8
- // Provider-specific settings. The active --proxy flag determines which
9
- // section is used at runtime.
8
+ // Which section gets used depends on the --proxy flag.
10
9
 
11
10
  openai: {
12
11
  // No tool bridge needed for OpenAI because Xcode drives tool execution
13
- // directly. TODO: will need this for Codex Agent support.
12
+ // directly.
14
13
  toolBridge: false,
15
14
 
16
15
  mcpServers: {
@@ -25,17 +24,23 @@
25
24
  },
26
25
  },
27
26
 
28
- anthropic: {
29
- // Normally the Copilot CLI executes tool calls (file reads, edits, etc.)
30
- // on its own. This shim intercepts those calls and forwards them to Xcode
31
- // so Claude Agent can drive tool execution through the IDE instead.
32
- // Set to false or remove to disable the tool bridge.
27
+ claude: {
28
+ // Intercepts tool calls and forwards them to Xcode so Claude Agent
29
+ // drives tool execution through the IDE instead of the Copilot CLI.
33
30
  toolBridge: true,
34
31
 
35
32
  // No MCP servers needed, because Claude Agent handles tools natively.
36
33
  mcpServers: {},
37
34
  },
38
35
 
36
+ codex: {
37
+ // Same as Claude: intercepts tool calls and forwards them to Xcode
38
+ // so Codex drives tool execution through the IDE.
39
+ toolBridge: true,
40
+
41
+ mcpServers: {},
42
+ },
43
+
39
44
  // Built-in Copilot CLI tools allowlist (glob, grep, bash, etc). Use ["*"] to allow
40
45
  // all, [] to deny all, or list specific tools like ["glob", "grep"].
41
46
  //
@@ -28,8 +28,8 @@ export function parseProxy(value) {
28
28
  return value;
29
29
  }
30
30
  export function validateAutoPatch(proxy, autoPatch) {
31
- if (autoPatch && proxy !== "anthropic") {
32
- throw new Error("--auto-patch can only be used with --proxy anthropic");
31
+ if (autoPatch && proxy !== "claude" && proxy !== "codex") {
32
+ throw new Error("--auto-patch can only be used with --proxy claude or --proxy codex");
33
33
  }
34
34
  }
35
35
  //# sourceMappingURL=cli-validators.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"cli-validators.js","sourceRoot":"","sources":["../src/cli-validators.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAiB,MAAM,aAAa,CAAC;AAC5D,OAAO,EAAE,SAAS,EAAkB,MAAM,sBAAsB,CAAC;AAEjE,MAAM,gBAAgB,GAAG,MAAM,CAAC,IAAI,CAAC,cAAc,CAAe,CAAC;AACnE,MAAM,aAAa,GAAG,MAAM,CAAC,IAAI,CAAC,SAAS,CAAgB,CAAC;AAE5D,SAAS,UAAU,CAAC,KAAa;IAC/B,OAAO,KAAK,IAAI,cAAc,CAAC;AACjC,CAAC;AAED,SAAS,WAAW,CAAC,KAAa;IAChC,OAAO,KAAK,IAAI,SAAS,CAAC;AAC5B,CAAC;AAED,MAAM,UAAU,SAAS,CAAC,KAAa;IACrC,MAAM,IAAI,GAAG,QAAQ,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;IACjC,IAAI,KAAK,CAAC,IAAI,CAAC,IAAI,IAAI,GAAG,CAAC,IAAI,IAAI,GAAG,KAAK,EAAE,CAAC;QAC5C,MAAM,IAAI,KAAK,CAAC,iBAAiB,KAAK,qBAAqB,CAAC,CAAC;IAC/D,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,KAAa;IACzC,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,EAAE,CAAC;QACvB,MAAM,IAAI,KAAK,CACb,sBAAsB,KAAK,aAAa,gBAAgB,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CACtE,CAAC;IACJ,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,KAAa;IACtC,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,EAAE,CAAC;QACxB,MAAM,IAAI,KAAK,CACb,kBAAkB,KAAK,aAAa,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAC/D,CAAC;IACJ,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAC,KAAgB,EAAE,SAAkB;IACpE,IAAI,SAAS,IAAI,KAAK,KAAK,WAAW,EAAE,CAAC;QACvC,MAAM,IAAI,KAAK,CAAC,sDAAsD,CAAC,CAAC;IAC1E,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"cli-validators.js","sourceRoot":"","sources":["../src/cli-validators.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAiB,MAAM,aAAa,CAAC;AAC5D,OAAO,EAAE,SAAS,EAAkB,MAAM,sBAAsB,CAAC;AAEjE,MAAM,gBAAgB,GAAG,MAAM,CAAC,IAAI,CAAC,cAAc,CAAe,CAAC;AACnE,MAAM,aAAa,GAAG,MAAM,CAAC,IAAI,CAAC,SAAS,CAAgB,CAAC;AAE5D,SAAS,UAAU,CAAC,KAAa;IAC/B,OAAO,KAAK,IAAI,cAAc,CAAC;AACjC,CAAC;AAED,SAAS,WAAW,CAAC,KAAa;IAChC,OAAO,KAAK,IAAI,SAAS,CAAC;AAC5B,CAAC;AAED,MAAM,UAAU,SAAS,CAAC,KAAa;IACrC,MAAM,IAAI,GAAG,QAAQ,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;IACjC,IAAI,KAAK,CAAC,IAAI,CAAC,IAAI,IAAI,GAAG,CAAC,IAAI,IAAI,GAAG,KAAK,EAAE,CAAC;QAC5C,MAAM,IAAI,KAAK,CAAC,iBAAiB,KAAK,qBAAqB,CAAC,CAAC;IAC/D,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,KAAa;IACzC,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,EAAE,CAAC;QACvB,MAAM,IAAI,KAAK,CACb,sBAAsB,KAAK,aAAa,gBAAgB,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CACtE,CAAC;IACJ,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,KAAa;IACtC,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,EAAE,CAAC;QACxB,MAAM,IAAI,KAAK,CACb,kBAAkB,KAAK,aAAa,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAC/D,CAAC;IACJ,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAC,KAAgB,EAAE,SAAkB;IACpE,IAAI,SAAS,IAAI,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,OAAO,EAAE,CAAC;QACzD,MAAM,IAAI,KAAK,CAAC,oEAAoE,CAAC,CAAC;IACxF,CAAC;AACH,CAAC"}
package/dist/config.d.ts CHANGED
@@ -3,7 +3,7 @@ import type { ProxyName } from "./providers/index.js";
3
3
  import { type MCPServer, type RawServerConfig } from "./schemas/config.js";
4
4
  export type { MCPLocalServer, MCPRemoteServer, MCPServer, ApprovalRule, ReasoningEffort, } from "./schemas/config.js";
5
5
  export type { ProxyName };
6
- export type ServerConfig = Omit<RawServerConfig, "bodyLimitMiB" | "openai" | "anthropic"> & {
6
+ export type ServerConfig = Omit<RawServerConfig, "bodyLimitMiB" | "openai" | "claude" | "codex"> & {
7
7
  toolBridge: boolean;
8
8
  mcpServers: Record<string, MCPServer>;
9
9
  bodyLimit: number;
package/dist/config.js CHANGED
@@ -8,7 +8,7 @@ const DEFAULT_CONFIG = {
8
8
  mcpServers: {},
9
9
  allowedCliTools: [],
10
10
  excludedFilePatterns: [],
11
- bodyLimit: 10 * 1024 * 1024, // 10 MiB
11
+ bodyLimit: 10 * 1024 * 1024,
12
12
  autoApprovePermissions: ["read", "mcp"],
13
13
  };
14
14
  function resolveServerPaths(servers, configDir) {
@@ -1 +1 @@
1
- {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
@@ -1,6 +1,6 @@
1
1
  import type { CopilotSession } from "@github/copilot-sdk";
2
2
  import { ToolBridgeState } from "./tool-bridge/state.js";
3
- import type { AnthropicMessage } from "./schemas/anthropic.js";
3
+ import type { AnthropicMessage } from "./providers/claude/schemas.js";
4
4
  import type { Logger } from "./logger.js";
5
5
  export interface Conversation {
6
6
  id: string;
@@ -25,6 +25,7 @@ export declare class ConversationManager {
25
25
  isReuse: boolean;
26
26
  };
27
27
  findByContinuation(messages: AnthropicMessage[]): Conversation | undefined;
28
+ findByContinuationIds(callIds: string[]): Conversation | undefined;
28
29
  findByExpectedTool(name: string): ToolBridgeState | undefined;
29
30
  getState(convId: string): ToolBridgeState | undefined;
30
31
  remove(convId: string): void;
@@ -81,7 +81,7 @@ export class ConversationManager {
81
81
  }
82
82
  }
83
83
  }
84
- // the model sometimes retries a tool after an internal failure so the
84
+ // The model sometimes retries a tool after an internal failure so the
85
85
  // tool_use_id won't match anything, but we can still route by session
86
86
  for (const [, conv] of this.conversations) {
87
87
  if (conv.state.sessionActive) {
@@ -91,6 +91,25 @@ export class ConversationManager {
91
91
  }
92
92
  return undefined;
93
93
  }
94
+ findByContinuationIds(callIds) {
95
+ if (callIds.length === 0)
96
+ return undefined;
97
+ for (const [, conv] of this.conversations) {
98
+ for (const callId of callIds) {
99
+ if (conv.state.hasPendingToolCall(callId)) {
100
+ this.logger.debug(`Continuation matched conversation ${conv.id} via call_id ${callId}`);
101
+ return conv;
102
+ }
103
+ }
104
+ }
105
+ for (const [, conv] of this.conversations) {
106
+ if (conv.state.sessionActive) {
107
+ this.logger.debug(`Continuation matched conversation ${conv.id} via sessionActive fallback`);
108
+ return conv;
109
+ }
110
+ }
111
+ return undefined;
112
+ }
94
113
  findByExpectedTool(name) {
95
114
  for (const [, conv] of this.conversations) {
96
115
  if (conv.state.hasExpectedTool(name)) {
@@ -1 +1 @@
1
- {"version":3,"file":"conversation-manager.js","sourceRoot":"","sources":["../src/conversation-manager.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAEzC,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAazD,MAAM,OAAO,mBAAmB;IACb,aAAa,GAAG,IAAI,GAAG,EAAwB,CAAC;IAChD,MAAM,CAAS;IACxB,SAAS,GAAkB,IAAI,CAAC;IAExC,YAAY,MAAc;QACxB,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;IACvB,CAAC;IAED,MAAM,CAAC,OAAiC;QACtC,MAAM,EAAE,GAAG,UAAU,EAAE,CAAC;QACxB,MAAM,SAAS,GAAG,OAAO,EAAE,SAAS,IAAI,KAAK,CAAC;QAC9C,MAAM,KAAK,GAAG,IAAI,eAAe,EAAE,CAAC;QACpC,MAAM,YAAY,GAAiB;YACjC,EAAE;YACF,KAAK;YACL,OAAO,EAAE,IAAI;YACb,gBAAgB,EAAE,CAAC;YACnB,SAAS;YACT,KAAK,EAAE,IAAI;SACZ,CAAC;QACF,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,EAAE,EAAE,YAAY,CAAC,CAAC;QAEzC,IAAI,CAAC,SAAS,EAAE,CAAC;YACf,KAAK,CAAC,YAAY,CAAC,GAAG,EAAE;gBACtB,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,gBAAgB,EAAE,0BAA0B,CAAC,CAAC;gBAChE,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;YAChC,CAAC,CAAC,CAAC;QACL,CAAC;QAED,IAAI,SAAS,EAAE,CAAC;YACd,IAAI,CAAC,SAAS,GAAG,EAAE,CAAC;QACtB,CAAC;QAED,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,wBAAwB,EAAE,aAAa,MAAM,CAAC,SAAS,CAAC,aAAa,MAAM,CAAC,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAC3H,OAAO,YAAY,CAAC;IACtB,CAAC;IAED,UAAU;QACR,IAAI,CAAC,IAAI,CAAC,SAAS;YAAE,OAAO,IAAI,CAAC;QACjC,OAAO,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,IAAI,CAAC;IACxD,CAAC;IAED,YAAY;QACV,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;YACnB,MAAM,IAAI,GAAG,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;YACpD,IAAI,IAAI,EAAE,CAAC;gBACT,IAAI,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC;gBACrB,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;gBAC1C,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,gCAAgC,IAAI,CAAC,SAAS,aAAa,MAAM,CAAC,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YACnH,CAAC;YACD,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC;QACxB,CAAC;IACH,CAAC;IAED,iBAAiB;QACf,MAAM,OAAO,GAAG,IAAI,CAAC,UAAU,EAAE,CAAC;QAClC,IAAI,OAAO,EAAE,CAAC;YACZ,IAAI,OAAO,CAAC,KAAK,CAAC,aAAa,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC;gBACpD,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,WAAW,OAAO,CAAC,EAAE,iDAAiD,CAAC,CAAC;gBAC1F,OAAO,EAAE,YAAY,EAAE,IAAI,CAAC,MAAM,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC;YACzD,CAAC;YACD,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,gCAAgC,OAAO,CAAC,EAAE,EAAE,CAAC,CAAC;YAChE,OAAO,EAAE,YAAY,EAAE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;QAClD,CAAC;QACD,OAAO,EAAE,YAAY,EAAE,IAAI,CAAC,MAAM,CAAC,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC;IAC5E,CAAC;IAED,kBAAkB,CAAC,QAA4B;QAC7C,MAAM,OAAO,GAAG,QAAQ,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;QAC9C,IAAI,CAAC,OAAO,IAAI,OAAO,CAAC,IAAI,KAAK,MAAM,IAAI,OAAO,OAAO,CAAC,OAAO,KAAK,QAAQ,EAAE,CAAC;YAC/E,OAAO,SAAS,CAAC;QACnB,CAAC;QAED,MAAM,UAAU,GAAa,EAAE,CAAC;QAChC,KAAK,MAAM,KAAK,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;YACpC,IAAI,KAAK,CAAC,IAAI,KAAK,aAAa,EAAE,CAAC;gBACjC,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;YACrC,CAAC;QACH,CAAC;QAED,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,SAAS,CAAC;QAE9C,KAAK,MAAM,CAAC,EAAE,IAAI,CAAC,IAAI,IAAI,CAAC,aAAa,EAAE,CAAC;YAC1C,KAAK,MAAM,SAAS,IAAI,UAAU,EAAE,CAAC;gBACnC,IAAI,IAAI,CAAC,KAAK,CAAC,kBAAkB,CAAC,SAAS,CAAC,EAAE,CAAC;oBAC7C,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,qCAAqC,IAAI,CAAC,EAAE,oBAAoB,SAAS,EAAE,CAAC,CAAC;oBAC/F,OAAO,IAAI,CAAC;gBACd,CAAC;YACH,CAAC;QACH,CAAC;QAED,sEAAsE;QACtE,sEAAsE;QACtE,KAAK,MAAM,CAAC,EAAE,IAAI,CAAC,IAAI,IAAI,CAAC,aAAa,EAAE,CAAC;YAC1C,IAAI,IAAI,CAAC,KAAK,CAAC,aAAa,EAAE,CAAC;gBAC7B,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,qCAAqC,IAAI,CAAC,EAAE,6BAA6B,CAAC,CAAC;gBAC7F,OAAO,IAAI,CAAC;YACd,CAAC;QACH,CAAC;QAED,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,kBAAkB,CAAC,IAAY;QAC7B,KAAK,MAAM,CAAC,EAAE,IAAI,CAAC,IAAI,IAAI,CAAC,aAAa,EAAE,CAAC;YAC1C,IAAI,IAAI,CAAC,KAAK,CAAC,eAAe,CAAC,IAAI,CAAC,EAAE,CAAC;gBACrC,OAAO,IAAI,CAAC,KAAK,CAAC;YACpB,CAAC;QACH,CAAC;QACD,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,QAAQ,CAAC,MAAc;QACrB,OAAO,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,KAAK,CAAC;IAC/C,CAAC;IAED,MAAM,CAAC,MAAc;QACnB,MAAM,IAAI,GAAG,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QAC5C,IAAI,IAAI,EAAE,CAAC;YACT,IAAI,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC;YACrB,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;YAClC,IAAI,MAAM,KAAK,IAAI,CAAC,SAAS,EAAE,CAAC;gBAC9B,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC;YACxB,CAAC;YACD,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,wBAAwB,MAAM,aAAa,MAAM,CAAC,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACnG,CAAC;IACH,CAAC;IAED,IAAI,IAAI;QACN,OAAO,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC;IACjC,CAAC;CACF"}
1
+ {"version":3,"file":"conversation-manager.js","sourceRoot":"","sources":["../src/conversation-manager.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ import type { FastifyReply } from "fastify";
2
+ import type { CopilotSession } from "@github/copilot-sdk";
3
+ import type { Logger } from "../../logger.js";
4
+ import type { ToolBridgeState } from "../../tool-bridge/state.js";
5
+ export declare function startResponseStream(reply: FastifyReply, responseId: string, model: string): void;
6
+ export declare function handleResponsesStreaming(state: ToolBridgeState, session: CopilotSession, prompt: string, model: string, logger: Logger, hasBridge: boolean, responseId: string): Promise<void>;
@@ -0,0 +1,265 @@
1
+ import { currentTimestamp, genId } from "../../schemas/responses.js";
2
+ import { formatCompaction, SSE_HEADERS, sendSSEEvent as sendEvent, sendSSEComment } from "../streaming-utils.js";
3
+ const MCP_PREFIX = "xcode-bridge-";
4
+ export function startResponseStream(reply, responseId, model) {
5
+ reply.raw.writeHead(200, SSE_HEADERS);
6
+ const response = {
7
+ id: responseId,
8
+ object: "response",
9
+ created_at: currentTimestamp(),
10
+ model,
11
+ status: "in_progress",
12
+ output: [],
13
+ };
14
+ sendEvent(reply, "response.created", { response });
15
+ sendEvent(reply, "response.in_progress", { response });
16
+ }
17
+ export async function handleResponsesStreaming(state, session, prompt, model, logger, hasBridge, responseId) {
18
+ const reply = state.currentReply;
19
+ if (!reply)
20
+ throw new Error("No reply set on bridge state");
21
+ startResponseStream(reply, responseId, model);
22
+ state.markSessionActive();
23
+ let pendingDeltas = [];
24
+ let sessionDone = false;
25
+ // Send keepalive comments every 15s to prevent client timeouts
26
+ // during long internal tool execution periods.
27
+ const keepaliveInterval = setInterval(() => {
28
+ const r = state.currentReply;
29
+ if (r)
30
+ sendSSEComment(r);
31
+ }, 15_000);
32
+ // lazily created on first text delta
33
+ let messageItem = null;
34
+ let messageStarted = false;
35
+ let outputIndex = 0;
36
+ const outputItems = [];
37
+ const accumulatedText = [];
38
+ const toolNames = new Map();
39
+ function getReply() {
40
+ return state.currentReply;
41
+ }
42
+ function ensureMessageItem(r) {
43
+ if (!messageStarted) {
44
+ messageItem = {
45
+ type: "message",
46
+ id: genId("msg"),
47
+ status: "in_progress",
48
+ role: "assistant",
49
+ content: [],
50
+ };
51
+ sendEvent(r, "response.output_item.added", {
52
+ output_index: outputIndex,
53
+ item: messageItem,
54
+ });
55
+ sendEvent(r, "response.content_part.added", {
56
+ item_id: messageItem.id,
57
+ output_index: outputIndex,
58
+ content_index: 0,
59
+ part: { type: "output_text", text: "", annotations: [] },
60
+ });
61
+ messageStarted = true;
62
+ }
63
+ }
64
+ function flushPending() {
65
+ const r = getReply();
66
+ if (!r || pendingDeltas.length === 0)
67
+ return;
68
+ ensureMessageItem(r);
69
+ for (const text of pendingDeltas) {
70
+ sendEvent(r, "response.output_text.delta", {
71
+ item_id: messageItem.id,
72
+ output_index: outputIndex,
73
+ content_index: 0,
74
+ delta: text,
75
+ });
76
+ accumulatedText.push(text);
77
+ }
78
+ pendingDeltas = [];
79
+ }
80
+ function closeMessageItem(r) {
81
+ if (!messageStarted || !messageItem)
82
+ return;
83
+ const fullText = accumulatedText.join("");
84
+ sendEvent(r, "response.output_text.done", {
85
+ item_id: messageItem.id,
86
+ output_index: outputIndex,
87
+ content_index: 0,
88
+ text: fullText,
89
+ });
90
+ sendEvent(r, "response.content_part.done", {
91
+ item_id: messageItem.id,
92
+ output_index: outputIndex,
93
+ content_index: 0,
94
+ part: { type: "output_text", text: fullText, annotations: [] },
95
+ });
96
+ messageItem.status = "completed";
97
+ messageItem.content = [{ type: "output_text", text: fullText, annotations: [] }];
98
+ outputItems.push(messageItem);
99
+ sendEvent(r, "response.output_item.done", {
100
+ output_index: outputIndex,
101
+ item: messageItem,
102
+ });
103
+ outputIndex++;
104
+ messageStarted = false;
105
+ messageItem = null;
106
+ }
107
+ function finishReply(r, status) {
108
+ clearInterval(keepaliveInterval);
109
+ const response = {
110
+ id: responseId,
111
+ object: "response",
112
+ created_at: currentTimestamp(),
113
+ model,
114
+ status,
115
+ output: outputItems,
116
+ };
117
+ sendEvent(r, `response.${status}`, { response });
118
+ r.raw.end();
119
+ state.clearReply();
120
+ state.notifyStreamingDone();
121
+ // reset for potential continuation
122
+ messageStarted = false;
123
+ messageItem = null;
124
+ outputIndex = 0;
125
+ outputItems.length = 0;
126
+ accumulatedText.length = 0;
127
+ }
128
+ const unsubscribe = session.on((event) => {
129
+ logger.debug(`Session event: ${event.type}`);
130
+ if (event.type === "tool.execution_start") {
131
+ const d = event.data;
132
+ toolNames.set(d.toolCallId, d.toolName);
133
+ logger.debug(`Running ${d.toolName} (id=${d.toolCallId}, args=${JSON.stringify(d.arguments)})`);
134
+ return;
135
+ }
136
+ if (event.type === "tool.execution_complete") {
137
+ const d = event.data;
138
+ const name = toolNames.get(d.toolCallId) ?? d.toolCallId;
139
+ toolNames.delete(d.toolCallId);
140
+ const detail = d.success
141
+ ? JSON.stringify(d.result?.content)
142
+ : d.error?.message ?? "failed";
143
+ logger.debug(`${name} done (success=${String(d.success)}, ${detail})`);
144
+ return;
145
+ }
146
+ switch (event.type) {
147
+ case "assistant.message_delta":
148
+ if (event.data.deltaContent) {
149
+ logger.debug(`Delta: ${event.data.deltaContent}`);
150
+ pendingDeltas.push(event.data.deltaContent);
151
+ }
152
+ break;
153
+ case "assistant.message": {
154
+ logger.debug(`assistant.message: toolRequests=${String(event.data.toolRequests?.length ?? 0)}`);
155
+ if (event.data.toolRequests && event.data.toolRequests.length > 0) {
156
+ const bridgeRequests = hasBridge
157
+ ? event.data.toolRequests.filter((tr) => tr.name.startsWith(MCP_PREFIX))
158
+ : event.data.toolRequests;
159
+ if (hasBridge && bridgeRequests.length < event.data.toolRequests.length) {
160
+ const skipped = event.data.toolRequests.length - bridgeRequests.length;
161
+ logger.debug(`Skipped ${String(skipped)} non-bridge tool request(s)`);
162
+ }
163
+ if (bridgeRequests.length > 0) {
164
+ // Xcode's Codex client does not process function_call items
165
+ // (it won't send function_call_output back), so emitting them
166
+ // breaks the conversation protocol. Instead we let the SDK
167
+ // handle bridge tools via MCP internally. The MCP tools/call
168
+ // will fail fast (no expected entry registered), prompting the
169
+ // model to fall back to its built-in tools.
170
+ const names = bridgeRequests.map((tr) => tr.name).join(", ");
171
+ logger.debug(`Bridge tool(s) requested (${names}), handled via MCP internally`);
172
+ }
173
+ else {
174
+ logger.debug("All tool requests were non-bridge, none emitted");
175
+ }
176
+ }
177
+ else {
178
+ const r = getReply();
179
+ if (r) {
180
+ logger.debug(`Flushing ${String(pendingDeltas.length)} pending deltas`);
181
+ flushPending();
182
+ }
183
+ }
184
+ break;
185
+ }
186
+ case "session.idle": {
187
+ logger.info(`Done, wrapping up stream (pendingDeltas=${String(pendingDeltas.length)})`);
188
+ sessionDone = true;
189
+ state.markSessionInactive();
190
+ flushPending();
191
+ const r = getReply();
192
+ if (r) {
193
+ if (!messageStarted) {
194
+ ensureMessageItem(r);
195
+ }
196
+ closeMessageItem(r);
197
+ finishReply(r, "completed");
198
+ }
199
+ unsubscribe();
200
+ break;
201
+ }
202
+ case "session.compaction_start":
203
+ logger.info("Compacting context...");
204
+ break;
205
+ case "session.compaction_complete":
206
+ logger.info(`Context compacted: ${formatCompaction(event.data)}`);
207
+ break;
208
+ case "session.error": {
209
+ logger.error(`Session error: ${event.data.message}`);
210
+ sessionDone = true;
211
+ state.markSessionErrored();
212
+ state.markSessionInactive();
213
+ const r = getReply();
214
+ if (r) {
215
+ if (messageStarted) {
216
+ closeMessageItem(r);
217
+ }
218
+ finishReply(r, "failed");
219
+ }
220
+ else {
221
+ // finishReply not called, so notify manually
222
+ clearInterval(keepaliveInterval);
223
+ state.notifyStreamingDone();
224
+ }
225
+ unsubscribe();
226
+ break;
227
+ }
228
+ default:
229
+ logger.debug(`Unhandled event: ${event.type}, data=${JSON.stringify(event.data)}`);
230
+ break;
231
+ }
232
+ });
233
+ reply.raw.on("close", () => {
234
+ if (!sessionDone && state.currentReply === reply) {
235
+ logger.info("Client disconnected, aborting session");
236
+ clearInterval(keepaliveInterval);
237
+ messageStarted = false;
238
+ messageItem = null;
239
+ state.markSessionErrored();
240
+ state.cleanup();
241
+ unsubscribe();
242
+ session.abort().catch((err) => {
243
+ logger.error("Failed to abort session:", err);
244
+ });
245
+ state.notifyStreamingDone();
246
+ }
247
+ });
248
+ const done = state.waitForStreamingDone();
249
+ session.send({ prompt }).catch((err) => {
250
+ logger.error("Failed to send prompt:", err);
251
+ clearInterval(keepaliveInterval);
252
+ sessionDone = true;
253
+ messageStarted = false;
254
+ messageItem = null;
255
+ const r = getReply();
256
+ if (r) {
257
+ r.raw.end();
258
+ state.clearReply();
259
+ }
260
+ unsubscribe();
261
+ state.notifyStreamingDone();
262
+ });
263
+ return done;
264
+ }
265
+ //# sourceMappingURL=streaming.js.map