feature/sigit-agent-profile
claude/github-issue-40-0au5ua
claude/linked-issue-acp-tui-u4vvpa
claude/minor-release-cut-vkugow
claude/sigit-acp-local-chat-cx6380
claude/sigit-cloud-agent-expansion-reox0a
claude/tool-permission-system
claude/zen-feynman-0u78dk
development
feature/acp-cancel-request
feature/acp-session-list-cursor
feature/acp-v1-conformance
feature/agent-tools-multiedit-glob-todos-remember
feature/cargo-workspace
feature/hooks
feature/load-local-model-explicitly
feature/sigit-agent-profile
feature/sigit-code-cloud
feature/xcode-mcp-server
fix/acp-replay-loaded-session-history
fix/acp-replay-reasoning-and-attachments
fix/dsml-doubled-bar-markers
main
release/v1.5.10
release/v1.5.6
release/v1.6.1
| 1 | # Changelog |
| 2 | |
| 3 | ## 1.6.7 |
| 4 | |
| 5 | ### Fixed |
| 6 | |
| 7 | - **A cancel that arrives before the turn starts is no longer lost.** A prompt |
| 8 | now registers for `session/cancel` as soon as it begins, not once it reaches |
| 9 | inference. A cancel that lands while the turn is queued on the workspace, |
| 10 | switching threads, loading a model, or running a slash command ends it with |
| 11 | `cancelled` instead of `end_turn`. |
| 12 | - **Cancelling a turn stops the command it is running.** A foreground |
| 13 | `run_command` used to run to its own end (up to two minutes) before the turn |
| 14 | noticed the cancel. A cancel or `session/close` now kills the process tree, or |
| 15 | sends `terminal/kill` when the command runs in the editor's terminal, and the |
| 16 | turn ends `cancelled` within a moment. |
| 17 | - **Switching permission mode works while a turn is running.** `session/set_mode` |
| 18 | and the Permissions config option queued behind the turn's session lock, so |
| 19 | choosing Auto while a permission prompt was open did nothing until the turn |
| 20 | ended. They now take no lock, are answered at once, and the pending call's |
| 21 | successors follow the new mode. Model and Inference changes still wait for |
| 22 | the turn. |
| 23 | - **`authenticate` checks the method id.** An id that `initialize` never offered |
| 24 | is now rejected with `invalid_params` (`-32602`) instead of starting a |
| 25 | browser sign-in. A sign-in that fails reports `-32603`, since `-32000` means |
| 26 | authentication is required before a call. |
| 27 | - **A session the agent does not know is `-32002`.** `session/prompt`, |
| 28 | `session/set_mode` and `session/set_config_option` answered `-32602` for an |
| 29 | unknown id; they now say resource not found, as `session/load` and |
| 30 | `session/resume` already did. |
| 31 | - **A finished terminal command no longer names a released terminal.** The |
| 32 | closing `tool_call_update` of a command that ran in the editor's terminal |
| 33 | re-sent the terminal id after `terminal/release`. It now leaves the content |
| 34 | alone, so the embedded terminal stays as it was, and the result still goes out |
| 35 | as `rawOutput`. |
| 36 | - **`session/list` rejects a relative `cwd` filter** with `-32602`, as |
| 37 | `session/new` does. |
| 38 | - **An embedded binary resource is read when the model can read it.** An image |
| 39 | blob becomes an image input and an audio blob an audio input. Any other blob |
| 40 | keeps its placeholder, now with its MIME type. |
| 41 | - **A prompt that is only audio is answered.** A clip with no text or image used |
| 42 | to end the turn at once with nothing sent to the model, even though the agent |
| 43 | advertises audio. |
| 44 | |
| 45 | ## 1.6.6 |
| 46 | |
| 47 | ### Added |
| 48 | |
| 49 | - **A tool call carries its programmatic tool name.** The `tool_call` an editor |
| 50 | gets for a running tool now includes `name` (`read_file`, `run_command`, |
| 51 | `mcp__…`) next to the human title, sent on the first report of the call only |
| 52 | as the protocol asks. A client can tell a command from a file edit without |
| 53 | parsing the title, and a replayed thread from `session/load` carries the same |
| 54 | name (#196). |
| 55 | |
| 56 | ### Changed |
| 57 | |
| 58 | - **MCP runs on `rmcp`, the official Rust SDK, through `ed-mcp`.** siGit Code's |
| 59 | own JSON-RPC client for stdio and Streamable HTTP servers (about 600 lines) |
| 60 | is gone; `ed-mcp` is the layer every Onde agent shares. `mcp.toml`, the |
| 61 | baked-in `sigit` and `smbcloud` servers, tool names and `/mcp` are unchanged. |
| 62 | An HTTP server that stops answering is now reconnected and the call retried |
| 63 | once for any failure but a timeout, not only on a 404. |
| 64 | |
| 65 | ### Fixed |
| 66 | |
| 67 | - **A reply that degenerates into a repetition loop is cut off.** After a tool |
| 68 | call, a model could fall into thousands of words from a tiny vocabulary |
| 69 | (`find: list: check: get: …`) with no tool call and no end, and the junk went |
| 70 | into history for the next turn. siGit Code now watches a streamed reply for a |
| 71 | window of 200 words with very few distinct ones (code blocks excepted), stops |
| 72 | reading, keeps only the text before the loop, tells you it stopped, and asks |
| 73 | the model once to make its call or answer briefly (#123). |
| 74 | - **A linked selection written as `L10-L20` or `L10` reads just those lines.** |
| 75 | siGit Code read the line range of a `resource_link` only as `L10:20` or |
| 76 | `L10-20`, so `L10-L20` (the GitHub style) and a single line `L10` sent the |
| 77 | whole file instead of the selection. It now reads the same forms Zed's own |
| 78 | mention parser does, and a range that starts at line 0 or runs backwards |
| 79 | counts as no range. |
| 80 | |
| 81 | ## 1.6.5 |
| 82 | |
| 83 | ### Added |
| 84 | |
| 85 | - **An `@file` mention can carry unsaved edits.** siGit Code now advertises |
| 86 | `promptCapabilities.embeddedContext`, so a client can put a resource's |
| 87 | contents in the prompt instead of sending a link to it. Before, a client |
| 88 | that follows the spec only sent `resource_link`, and siGit Code read the |
| 89 | file from disk, missing whatever the user had not saved yet (#141). |
| 90 | - **A prompt can carry audio.** siGit Code now advertises |
| 91 | `promptCapabilities.audio` and sends an attached clip to the model as an |
| 92 | OpenAI `input_audio` part. It works the way image attachments do: a model on |
| 93 | an endpoint you configure yourself gets the clip and decides for itself, |
| 94 | while siGit Code Cloud tiers and on-device models, none of which take audio |
| 95 | today, get a note in its place and the editor says the clip was left out |
| 96 | (#143). |
| 97 | - **The README says what telemetry is sent.** A new Telemetry section covers |
| 98 | the model-timing events Onde Inference can report for on-device models, |
| 99 | what they leave out, and how to turn them off with `ONDE_DISABLE_PULSE=1`. |
| 100 | |
| 101 | ### Changed |
| 102 | |
| 103 | - **A turn that cannot get its session back stops.** A turn on an HTTP backend |
| 104 | gives up the process-wide working directory while it waits and reinstalls |
| 105 | its session before a tool runs. If the reinstall failed, the turn logged a |
| 106 | warning and carried on in whichever directory was current. Nothing makes it |
| 107 | fail today, since a close waits for the turn, but the turn now ends as |
| 108 | cancelled instead of depending on that. |
| 109 | - **Dependencies match the rest of the Onde stack.** Onde 1.2.2 to 1.3.1, |
| 110 | reqwest 0.12 to 0.13 and ratatui 0.29 to 0.30, the versions Ed, OndeCode and |
| 111 | SplitFire Agent use. ratatui is built with only its crossterm backend, which |
| 112 | drops the second copy of crossterm (0.28) from the build. |
| 113 | |
| 114 | ### Fixed |
| 115 | |
| 116 | - **Tags a model makes up no longer show in the reply.** After a long run of |
| 117 | tool rounds, a model could start writing markup that looked like it came |
| 118 | from siGit Code: a `<system_warning>` block telling the user the previous |
| 119 | turn was injected and should be ignored, or a question wrapped in |
| 120 | `<Option_Picker>`. Neither tag means anything to siGit Code or the editor, |
| 121 | so both rendered as raw text. A `system_*` block is now dropped from the |
| 122 | reply and from the history, and other made-up tags are removed while the |
| 123 | text inside them stays. Code blocks are left alone. The system prompt also |
| 124 | tells the model to write plain Markdown and to list choices as plain text |
| 125 | (#122). |
| 126 | - **Closing a thread that is waiting at a permission prompt no longer hangs.** |
| 127 | `session/close` cancels the session's running turn and waits for it to end, |
| 128 | but a turn stopped at a permission prompt only went on when the client |
| 129 | answered the request. A client that closed the thread without answering |
| 130 | left the close, and every later request for that thread, waiting for good. |
| 131 | The same held for `session/cancel` with a client that did not send the |
| 132 | cancelled outcome the protocol asks for. The permission wait now ends on |
| 133 | the cancellation as well, and an approval that arrives after the turn was |
| 134 | cancelled runs nothing. |
| 135 | |
| 136 | - **A closed thread no longer leaves its request lock behind.** The process |
| 137 | kept one lock per session id for as long as it ran, for closed threads and |
| 138 | for ids no session ever had. The entry now goes with the last request that |
| 139 | used it. |
| 140 | |
| 141 | - **A tool call that did not run no longer shows as completed.** When policy |
| 142 | or plan mode denied a call, when the user picked Deny at the permission |
| 143 | prompt, or when the repeat guard skipped a call the model made three times, |
| 144 | the editor's card still ended `completed`. Those cards now end `failed`, the |
| 145 | same way a call cancelled at the prompt already did. A call denied at the |
| 146 | prompt also gets its own title back instead of keeping the permission |
| 147 | request's (#139). |
| 148 | |
| 149 | - **On-device inference no longer panics on some non-English text.** siGit Code |
| 150 | now builds on Onde 1.3.1, which fixes a panic when a message longer than 100 |
| 151 | bytes had a multi-byte character (an accented letter, CJK, or an emoji) at |
| 152 | byte 100. Onde 1.3 also reports Pulse events for streaming inference, which |
| 153 | is the path on-device turns take, so those turns are now reported alongside |
| 154 | model loads. `ONDE_DISABLE_PULSE=1` turns Pulse off. |
| 155 | |
| 156 | ## 1.6.4 |
| 157 | |
| 158 | ### Added |
| 159 | |
| 160 | - **DeepSeek DSML tool calls written into the reply text are recovered.** A |
| 161 | DeepSeek-family endpoint can render a tool call as literal |
| 162 | `<|DSML|tool_calls>` text instead of the structured `tool_calls` field, |
| 163 | which streamed the tag into the editor and ended the turn with nothing run. |
| 164 | The inline tool-call scanner that already recovered the GLM XML and Kimi K3 |
| 165 | shapes now recovers the DSML shape too, including a marker split across |
| 166 | stream chunks. A block that fails to parse is still kept out of the reply |
| 167 | and the history, and the model is told the call did not run (#181). |
| 168 | |
| 169 | ### Fixed |
| 170 | |
| 171 | - **The round-cap stop message no longer carries a stray run of spaces.** |
| 172 | When the tool-round cap ended a turn, the closing message could collapse a |
| 173 | space run into the wrong spot, which the editor then rendered verbatim |
| 174 | (#177). |
| 175 | |
| 176 | ## 1.6.3 |
| 177 | |
| 178 | ### Added |
| 179 | |
| 180 | - **A client can resume a session and close one.** siGit Code now advertises |
| 181 | `sessionCapabilities.resume` and `sessionCapabilities.close`. |
| 182 | `session/resume` restores a saved thread the way `session/load` does, but |
| 183 | sends none of it back: it is for a client that still has the thread on |
| 184 | screen, after an agent restart for example. `session/close` cancels the |
| 185 | session's running turn and drops what the process held for it, which is its |
| 186 | state, its permission grants and plan mode, the MCP servers the client named |
| 187 | for it, and the background commands it started. The saved history is left |
| 188 | alone, so a closed thread still lists and reopens (#149). |
| 189 | |
| 190 | - **The permission modes are also offered as ACP session modes.** Manual, Auto |
| 191 | and Plan were only reachable as a config option, which is what the protocol |
| 192 | now recommends and what Zed reads. A client that draws the older mode |
| 193 | selector saw nothing. `session/new`, `session/load` and `session/fork` now |
| 194 | return the same three in `modes`, `session/set_mode` switches between them, |
| 195 | and a change made any other way (the config option, `/plan`, `/clear`, |
| 196 | `/reload`) is announced with `current_mode_update`. A client that reads |
| 197 | config options ignores `modes`, so nothing changes there (#148). |
| 198 | |
| 199 | - **An editor can sign out of siGit Code.** The `initialize` reply carried an |
| 200 | empty `auth` object, so a client drew no sign out button, and typing |
| 201 | `/logout` was the only way out of an account. The reply now advertises |
| 202 | `agentCapabilities.auth.logout`, and a `logout` request ends the account |
| 203 | session through the method `/logout` calls. The request names no session, |
| 204 | so it moves every open thread that used the account, not only the live one: |
| 205 | a thread parked on a cloud tier goes on-device with the live thread instead |
| 206 | of failing to restore its tier on its next prompt, and every thread that |
| 207 | moved gets a fresh model picker. Local inference is switched back on if it |
| 208 | was off, so a thread opened after signing out asks for no cloud tier |
| 209 | (#150). |
| 210 | |
| 211 | ### Changed |
| 212 | |
| 213 | - **Two threads can run a turn at the same time.** An editor runs one siGit |
| 214 | Code process for every thread it has open, and a single lock ordered every |
| 215 | turn-affecting request in it, so a second prompt waited for the first |
| 216 | thread's whole turn and two prompts never overlapped. The lock held what a |
| 217 | session installs process-wide — the working directory, the workspace roots, |
| 218 | the MCP servers the client named for it, the live backend — none of which a |
| 219 | turn touches while it waits on an HTTP endpoint, which is most of its time. |
| 220 | A session on an HTTP backend now keeps a backend of its own, so its |
| 221 | conversation is no longer swapped in and out of a shared one, and a turn |
| 222 | releases the process-wide lock while it waits on the endpoint or on a |
| 223 | permission answer and takes it back, reinstalling its session, before any |
| 224 | tool runs. On-device turns are unchanged, since the engine keeps one |
| 225 | conversation, and tool execution still runs one session at a time (#176). |
| 226 | |
| 227 | ### Fixed |
| 228 | |
| 229 | - **A prompt whose inference failed is kept through a model switch.** A turn |
| 230 | that ended in an endpoint error stayed in the client's thread, but the |
| 231 | carryover into a new model dropped its trailing user message, and the error |
| 232 | path never saved the session. Only a cancelled prompt should be taken back |
| 233 | out, so cancellation now removes it from the live history, and the error |
| 234 | path persists the session (#124). |
| 235 | |
| 236 | ## 1.6.2 |
| 237 | |
| 238 | ### Added |
| 239 | |
| 240 | - **`sigit --version` prints the release.** `sigit --version` and `sigit -V` |
| 241 | print `sigit <version>` on stdout and exit 0. Before, the flag was not |
| 242 | recognized and siGit Code started a session, which left a script that asked |
| 243 | for the version waiting. |
| 244 | |
| 245 | - **File tools read and write through the editor when it offers to.** An ACP |
| 246 | client that advertises `fs.readTextFile` or `fs.writeTextFile` serves those |
| 247 | requests from its open buffers. siGit Code always used the disk, so |
| 248 | `read_file` missed unsaved changes and `edit_file` wrote underneath a buffer |
| 249 | the user might have modified. `read_file`, `create_file`, `edit_file` and |
| 250 | `multi_edit` now go through the client for paths inside the session's roots. |
| 251 | The two capabilities are independent, and the disk is still the fallback: |
| 252 | for a path outside the roots, and for a request the client fails or leaves |
| 253 | unanswered for 30 seconds. `SIGIT_CLIENT_FS=off` keeps the file tools on |
| 254 | disk (#147). |
| 255 | |
| 256 | ### Fixed |
| 257 | |
| 258 | - **A file attached from the editor is found when its path needs escaping.** |
| 259 | A `resource_link` was read by stripping `file://` and using the rest as the |
| 260 | path, so a space arrived as `%20`, a non-ASCII name failed, and a Windows |
| 261 | URI kept its leading slash. A `#` in a file name was also taken for the |
| 262 | line-range fragment. The URI is now parsed properly (#170). |
| 263 | |
| 264 | ## 1.6.1 |
| 265 | |
| 266 | ### Added |
| 267 | |
| 268 | - **Images can be attached to a prompt in the editor.** siGit Code now |
| 269 | advertises `promptCapabilities.image`, so an ACP client offers image |
| 270 | attachments. The image goes to the model when the active model reads images. |
| 271 | The model picker marks those models with "reads images". The on-device |
| 272 | models and four cloud tiers (`nova`, `orbit`, `apex`, `flux`) are text-only: |
| 273 | with one of them active the image is left out, a note in the thread says so, |
| 274 | and the model is told an image was withheld. Switching a thread that already |
| 275 | holds images to a text-only model flags that once as well. Cloud tiers need |
| 276 | siGit Code Cloud to accept image parts, which is rolling out separately |
| 277 | (#134). |
| 278 | |
| 279 | - **The tool-round cap of a headless run can be set.** `--max-tool-rounds <n>` |
| 280 | or `SIGIT_MAX_TOOL_ROUNDS` (1 to 500) replaces the built-in 24 for |
| 281 | `sigit run` and `sigit -p`. The flag wins over the variable. |
| 282 | |
| 283 | ### Fixed |
| 284 | |
| 285 | - **A prompt turn now reports why it stopped.** ACP defines five stop reasons |
| 286 | and siGit Code only ever sent `end_turn` and `cancelled`. A turn that runs |
| 287 | into the tool-round cap now ends with `max_turn_requests`, a reply cut off |
| 288 | at the token limit with `max_tokens`, and a reply the endpoint withheld |
| 289 | (`content_filter`) with `refusal`. A refused turn is also taken out of the |
| 290 | conversation, which is what the protocol tells the client to expect (#140). |
| 291 | |
| 292 | - **A tool call that needs approval is one card, not two.** The permission |
| 293 | request carried an id of its own, so an ACP client showed an approval card |
| 294 | beside a call that already claimed to be running. The call is now announced |
| 295 | as `pending`, the permission request names that same call, and it moves to |
| 296 | `in_progress` once approved. Calls allowed by policy still start out |
| 297 | `in_progress` (#138). |
| 298 | |
| 299 | - **A turn that runs out of tool rounds says so.** In an editor, a long task |
| 300 | could stop on a line like "Now commit:" with nothing after it. The turn had |
| 301 | used all 24 tool rounds, the model spent its last reply announcing the next |
| 302 | step, and the call behind it was dropped. siGit Code now tells the model |
| 303 | that its rounds are used up before that last reply, and ends the turn with a |
| 304 | message saying why it stopped and that "continue" picks it back up. |
| 305 | `SIGIT_MAX_TOOL_ROUNDS` now sets the cap for editor sessions too (#120). |
| 306 | |
| 307 | - **A headless run no longer ends silently with no final message.** When the |
| 308 | last round came back empty, which is what happens when a run is cut off at |
| 309 | the tool-round cap mid-task, stdout was empty and the exit status was 0, so |
| 310 | a caller could not tell it from a run with nothing to report. siGit Code now |
| 311 | asks the model once for its final message before finishing. |
| 312 | |
| 313 | ## 1.6.0 |
| 314 | |
| 315 | ### Added |
| 316 | |
| 317 | - **Editors can pass HTTP MCP servers to a session.** siGit Code now |
| 318 | advertises `mcpCapabilities.http`, so an ACP client may list Streamable HTTP |
| 319 | servers in `mcpServers` next to stdio ones. They are connected with the URL |
| 320 | and headers the client sent and are scoped to that session, like the stdio |
| 321 | ones. SSE is still not advertised, since the MCP spec deprecated it (#151). |
| 322 | |
| 323 | - **The plan panel survives a failed turn.** The last `write_todos` list is |
| 324 | now kept by siGit Code itself. When a turn ends in an endpoint error before |
| 325 | the model gets to call `write_todos` again, the saved list is sent to the |
| 326 | editor again, so the plan stays on screen where it used to go blank (#132). |
| 327 | |
| 328 | ### Changed |
| 329 | |
| 330 | - **The ACP Rust SDK is now 2.2** (`agent-client-protocol`, up from 1.3). |
| 331 | siGit Code still speaks ACP protocol v1 to the editor, so nothing changes on |
| 332 | the wire. The `unstable_auth_methods` feature is gone because agent auth |
| 333 | methods are stable in 2.x. |
| 334 | |
| 335 | ### Fixed |
| 336 | |
| 337 | - **MCP servers the editor passes to a session are connected.** ACP clients |
| 338 | can name MCP servers in `mcpServers` when they open a session, and agents |
| 339 | are required to connect to the stdio ones. siGit Code accepted the field and |
| 340 | ignored it. The servers are now spawned when the session opens, their tools |
| 341 | are offered to that session only, and `/mcp` lists them as coming from the |
| 342 | editor. `SIGIT_MCP=off` still turns all of it off (#135). |
| 343 | |
| 344 | - **A relative `cwd` is rejected when a session starts.** ACP requires the |
| 345 | working directory and every `additionalDirectories` entry to be absolute. |
| 346 | `session/new`, `session/load` and `session/fork` used to accept a relative |
| 347 | one and resolve it against wherever the editor spawned the process. They now |
| 348 | answer with an invalid-params error (#136). |
| 349 | |
| 350 | - **Loading a session that does not exist is an error.** `session/load` with |
| 351 | an id that was never saved used to succeed and open an empty session under |
| 352 | that id, so the editor showed a blank thread that looked restored. It now |
| 353 | answers "not found" (`-32002`). A thread opened in the running process but |
| 354 | not spoken in yet still loads (#137). |
| 355 | |
| 356 | - **Compaction no longer dead-ends a long session.** The summarization request |
| 357 | used to carry the whole conversation, which by then was already over the |
| 358 | model's window, so siGit Code Cloud timed out with a 504 and the session |
| 359 | stopped with "start a new thread". The transcript sent for summarizing is |
| 360 | now capped, cut from the middle so the opening request and the latest state |
| 361 | are kept. If summarizing still fails, the oldest messages are dropped until |
| 362 | the history fits, with whole tool rounds removed together. A failed attempt |
| 363 | leaves the conversation as it was (#125). |
| 364 | |
| 365 | - **Gateway error pages stay out of the chat.** When an endpoint answers with |
| 366 | an HTML error page, the error shown is the status line, not the page's |
| 367 | markup (#125). |
| 368 | |
| 369 | - **Issue and pull request work no longer assumes GitHub.** The system prompt |
| 370 | treated forge features as if every repository lived on GitHub, while the |
| 371 | built-in `mcp__sigit__*` tools only work for repositories hosted on |
| 372 | sigit.si. The agent now checks the remote first, uses those tools only for |
| 373 | sigit.si repositories, and reaches for the forge's own CLI (`gh`, `glab`, |
| 374 | `tea`) elsewhere (#127). |
| 375 | |
| 376 | ## 1.5.13 |
| 377 | |
| 378 | ### Added |
| 379 | |
| 380 | - **Three more siGit Code Cloud tiers: `flare`, `zenith` and `prism`.** They |
| 381 | show up in `/models` and in the editor's model picker alongside the existing |
| 382 | tiers. Selecting one needs a signed-in account, as before. |
| 383 | |
| 384 | ## 1.5.12 |
| 385 | |
| 386 | ### Fixed |
| 387 | |
| 388 | - **The Windows binaries start on machines without the Visual C++ |
| 389 | Redistributable.** They used to import `VCRUNTIME140.dll` and the UCRT |
| 390 | `api-ms-win-crt-*` DLLs, so a clean Windows install refused to load them |
| 391 | with `STATUS_DLL_NOT_FOUND` (0xC0000135). That is what failed winget's |
| 392 | post-install check. The C runtime is now linked statically, and CI and the |
| 393 | release build fail if a Windows exe picks up that dependency again. |
| 394 | |
| 395 | - **Watching a slow background command no longer ends the turn early.** |
| 396 | Polling `command_output` on the same task id three times tripped the |
| 397 | repeated-tool-call guard, which refused the call and dropped tools for the |
| 398 | rest of the turn. `command_output` now long-polls — it waits up to |
| 399 | `wait_seconds` (default 10, max 30) for the task to exit, then returns |
| 400 | everything printed in the meantime — and the repeat guard exempts it, since |
| 401 | polling the same task is the whole point of the tool. |
| 402 | |
| 403 | - **A turn that ends with no visible text says why.** When the |
| 404 | repeated-tool-call guard blocked a call and the forced no-tools round came |
| 405 | back empty, sigit sent nothing more — the turn just stopped with no answer |
| 406 | and no question. When the last round of a tool-using turn produces no |
| 407 | visible text, sigit now sends a short closing message naming the repeated |
| 408 | tool and asking you to reply "continue" or redirect. |
| 409 | |
| 410 | ## 1.5.11 |
| 411 | |
| 412 | ### Added |
| 413 | |
| 414 | - **`sigit run` drives the agent headlessly with resumable sessions.** A new |
| 415 | non-interactive subcommand runs a prompt through the same agent loop as the |
| 416 | editor and terminal surfaces, for scripts, CI, and Factory clients. Every run |
| 417 | gets a UUID session id, writes a JSON-lines history file under |
| 418 | `~/.config/sigit/sessions/`, and can be restored with `--resume <id>`. |
| 419 | `--output jsonl` emits a structured session/delta/tool/result stream on |
| 420 | stdout while logs stay on stderr, and `--allow-tool` pre-approves a tool so |
| 421 | permission prompts collapse to denial in a non-interactive context. The |
| 422 | legacy `-p` form still works. Each run also rewrites the session metadata |
| 423 | with its own cwd and extra roots, so resuming keeps multi-root projects |
| 424 | |
| 425 | - **Saved threads can be imported into the editor.** siGit Code now advertises |
| 426 | ACP's `sessionCapabilities.list` and answers `session/list`, so Zed's "Import |
| 427 | Threads" picker offers the conversations stored under |
| 428 | `~/.config/sigit/sessions/` instead of reporting that the agent doesn't |
| 429 | support the capability. A saved session gets a sidecar recording the project |
| 430 | directory it ran in — listing reports that `cwd`, the extra roots of a |
| 431 | multi-root project, an ISO 8601 last-activity timestamp, and a title taken |
| 432 | from the first user message — and a request may filter on `cwd` so one |
| 433 | project is never offered another's threads. Threads saved before this have no |
| 434 | sidecar and are not listed; they still reopen by id through `session/load` |
| 435 | |
| 436 | ### Changed |
| 437 | |
| 438 | - **The commit trailer names the siGit Code version and surface.** Commits |
| 439 | siGit Code makes now end with |
| 440 | `Co-Authored-By: siGit Code v<version>-<surface> <noreply@sigit.si>` instead |
| 441 | of the bare name, where the surface is `acp` (an editor), `tui` (the |
| 442 | terminal UI), or `headless` (`sigit run`). The model changes from session to |
| 443 | session; the version and surface tell you which build of the agent wrote the |
| 444 | commit and how it was driven. GitHub still credits the co-author, since it |
| 445 | matches on the address. A commit that already carries a siGit Code trailer |
| 446 | from an older version is left alone |
| 447 | |
| 448 | - **The terminal UI's model knows which directory the project is in.** The |
| 449 | editor (ACP) and headless paths put the working directory in the system |
| 450 | prompt, but the terminal UI only added the project's instruction files, so |
| 451 | on `/init` a small on-device model invented a `AGENTS.md` path and failed. |
| 452 | All three places the terminal UI builds a prompt now go through the same |
| 453 | session context path the ACP sessions get. The cloud tier switch had also |
| 454 | been dropping the instruction files; that's fixed too |
| 455 | |
| 456 | - **An empty `write_todos` list clears the plan.** `write_todos` rejected an |
| 457 | empty list, so the model had no way to clear a finished checklist and the |
| 458 | last plan stayed in the editor until the session ended. An empty list now |
| 459 | returns "Task list cleared." and goes to the client as an ACP plan with no |
| 460 | entries. The tool description tells the model it can do this |
| 461 | |
| 462 | - **`sigit run` gives clearer usage errors.** A second positional prompt says |
| 463 | "unexpected extra argument", a bare `sigit run` says "missing prompt", and a |
| 464 | mistyped flag like `--quite` is rejected instead of becoming the prompt |
| 465 | |
| 466 | ### Fixed |
| 467 | |
| 468 | - **Each ACP session keeps its own roots, conversation, and tasks.** Zed runs |
| 469 | one siGit process for every open thread, but the process had a single cwd, |
| 470 | workspace root list, backend conversation, and background task table. The |
| 471 | most recent session owned all of them, so a prompt from an older thread ran |
| 472 | against another repo with another thread's history. A `SessionState` is now |
| 473 | kept per session id; before a prompt or config change runs, the live |
| 474 | conversation is parked and the requested session's cwd, extra roots, and |
| 475 | conversation are installed, rebuilding the system prompt from its roots. |
| 476 | `new`/`load`/`fork` share a single session-opening path, and fork carries the |
| 477 | source thread's conversation. Background tasks are scoped to the session that |
| 478 | started them, opening a session no longer wipes every other session's |
| 479 | permission grants, and model selection is routed per session |
| 480 | |
| 481 | - **New sessions no longer carry the previous thread's history.** Opening a |
| 482 | new thread in Zed showed a `[Conversation summary]` from an earlier session. |
| 483 | The session handlers cleared the on-device engine but not the history a cloud |
| 484 | backend keeps for itself, and the startup routing to the cloud tier then |
| 485 | carried that history into the installed backend. A provider override had the |
| 486 | same leak. All session entry points now share a path that strips stale |
| 487 | history too, and unknown session ids are rejected instead of borrowing the |
| 488 | live thread's state |
| 489 | |
| 490 | - **Unparseable tool-call markup is hidden and retried, not shown as text.** |
| 491 | Some models write tool calls into the reply as text. Well-formed blocks were |
| 492 | already recovered and run, but a block that failed to parse or never closed |
| 493 | was printed to the editor as-is and stayed in history, so the model later |
| 494 | read back a call it had "made" with no result and began writing invented |
| 495 | `<function_results>`. The scanner now reports those blocks as malformed; the |
| 496 | backend drops them from the reply and history, and when the only tool call |
| 497 | was malformed the model gets one retry telling it the call didn't run. A |
| 498 | block that merely *mentions* a tool-call marker (a backticked `<tool_call>` or an |
| 499 | unclosed XTML `<|open|>tools`) is now kept as prose, so a reply explaining |
| 500 | the scanner no longer loses everything after the first marker. The |
| 501 | non-streamed path now strips broken blocks beside structured calls and runs |
| 502 | any inline calls that did parse, matching the streaming path |
| 503 | |
| 504 | - **The co-author trailer ends a conflicted merge commit.** Finishing a |
| 505 | conflicted merge with `git commit --no-edit` keeps git's `# Conflicts:` list |
| 506 | in the message, since no editor runs to strip it. When siGit Code then added |
| 507 | its trailer, the trailer went in above that list, so it was no longer the last |
| 508 | paragraph and GitHub didn't credit the co-author. The amend now drops the |
| 509 | leftover comment block and puts the trailer last. It also fixes a commit |
| 510 | that already has the trailer but still ends in that block |
| 511 | |
| 512 | ## 1.5.10 |
| 513 | |
| 514 | ### What changed |
| 515 | |
| 516 | - **Xcode's context no longer buries slash commands.** Xcode sends the user's |
| 517 | prompt as the last of several text blocks, with project context in the |
| 518 | blocks before it, so `/models` and friends sat in the middle of joined text |
| 519 | and were handed to the model instead of dispatching locally. Slash-command |
| 520 | parsing now searches the prompt's text blocks from the end, so a standalone |
| 521 | command in the final user block dispatches no matter what context the client |
| 522 | prepends |
| 523 | - **The nova tier is the default cloud engine.** When local inference is off |
| 524 | and no explicit provider override is set, the cloud tier now defaults to |
| 525 | `nova` (the `onde-nova` model) instead of the balanced tier, in both the |
| 526 | interactive and headless paths |
| 527 | |
| 528 | ### Fixed |
| 529 | |
| 530 | - **Malformed Chinese-model tool calls are handled end-to-end in ACP.** The |
| 531 | inline-call recovery that 1.5.9 added for Kimi K3's XTML protocol and GLM's |
| 532 | mis-tagged blocks only applied to the interactive and headless surfaces; |
| 533 | the ACP path never ran it, so an editor session still surfaced raw protocol |
| 534 | text and dropped the calls. Recovery now runs in the ACP prompt loop too, |
| 535 | covered by integration tests, and the tool names are checked against the |
| 536 | turn's offered tools before anything executes |
| 537 | - **Suppressed tool-call log spam is gone.** The guard that logs when a |
| 538 | structured call is dropped for arriving as forced text fired once per |
| 539 | streamed argument fragment — one malformed call could log a warning per |
| 540 | chunk. The check now fires once per turn with the count and names of what |
| 541 | was dropped, and the non-streaming path reports the same |
| 542 | - **A history-replay test no longer races on the process cwd.** One ACP test |
| 543 | built its expected path from `std::env::current_dir()` while other tests |
| 544 | briefly swap that process-global cwd, so on CI it could read a temp |
| 545 | directory mid-swap and compare a truncated title against an untruncated |
| 546 | expectation. It now uses a fixed path it never needed to derive |
| 547 | |
| 548 | ## 1.5.9 |
| 549 | |
| 550 | ### Fixed |
| 551 | |
| 552 | - **Kimi K3 tool calls no longer arrive as raw protocol text.** Kimi K3 renders |
| 553 | a call in Moonshot's XTML protocol — pipe-delimited open/sep/close tokens |
| 554 | wrapping named blocks — and when the serving stack doesn't parse that back |
| 555 | into structured tool calls, the whole block surfaced in the editor as literal |
| 556 | text and the turn ended as though the model had answered in prose. The |
| 557 | inline-call recovery now speaks that protocol alongside the legacy XML tags: |
| 558 | tools blocks are parsed into real calls (several per block, argument values |
| 559 | decoded and typed from the block's own type attribute or, when it is |
| 560 | missing, the turn's tool schemas), response blocks are unwrapped so their |
| 561 | text still renders, and think blocks are dropped as private reasoning rather |
| 562 | than shown. The streaming scanner watches all the opening markers, so a |
| 563 | block split across chunk boundaries still recovers |
| 564 | - **GLM's mis-tagged calls recover too.** GLM sometimes precedes the legacy |
| 565 | block's first argument key with another tool-call opening tag instead of the |
| 566 | arg-key opening tag the format calls for, and the recovery rejected the |
| 567 | whole block when it did — the call surfaced as text and whatever it was |
| 568 | trying to do was dropped. The parser now accepts that alias for the first |
| 569 | argument only — later arguments stay strict, so text that merely resembles a |
| 570 | call cannot be recovered as one — in both the whole-blob and streaming |
| 571 | paths, and the scanner tolerates the malformed marker split across chunk |
| 572 | boundaries. Recovery in both protocols also checks the call's name against |
| 573 | the tools actually offered in the turn: a tag naming a tool that was never |
| 574 | in the turn's spec stays on screen instead of being executed |
| 575 | |
| 576 | ## 1.5.8 |
| 577 | |
| 578 | ### What changed |
| 579 | |
| 580 | - **Editor panels can switch permission mode without a slash command.** ACP |
| 581 | clients now get a Permissions selector next to the model controls with |
| 582 | Manual, Auto, and Plan choices for the current session. Manual keeps the |
| 583 | existing approval prompts, Auto lets mutating tools run unattended while |
| 584 | still respecting explicit deny rules in `settings.toml`, and Plan keeps the |
| 585 | agent in research-only mode. The selector follows `/plan` and `/clear`, and |
| 586 | it is deliberately session-scoped so a risky Auto choice does not persist |
| 587 | into the next task |
| 588 | - **Tool calls in the editor are worth opening now.** Zed only drew the |
| 589 | disclosure arrow on the handful of cards siGit set `content` on — the model |
| 590 | download and switch spinners — because everything else carried nothing but |
| 591 | `rawInput` and `rawOutput`, fields ACP gives clients no display guidance for. |
| 592 | Every tool call now gets a fenced content block: the pretty-printed arguments |
| 593 | while it runs, then the tool's output once it finishes, with a `(no output)` |
| 594 | placeholder for a silent command like `git add`. Cards are titled |
| 595 | `<tool> · <arg>` rather than the bare tool name, path-bearing tools set |
| 596 | `locations` so the editor can follow along, and a replayed session gets the |
| 597 | same treatment as a live one |
| 598 | - **The context window is visible before compaction fires.** Both model pickers |
| 599 | show each model's window, and the TUI title bar has a gauge for how much of |
| 600 | it the conversation is using. Cloud tiers report their own window instead of |
| 601 | the compaction budget — the budget is when siGit Code summarizes history, not |
| 602 | how much the model can hold, and labelling one with the other understated the |
| 603 | window by an order of magnitude |
| 604 | - **`write_todos` renders as a plan, not a tool card.** Zed and other clients |
| 605 | have real progress UI for `session/update` plans, so the model's todo list |
| 606 | goes there |
| 607 | - **Picker changes read as status rather than chat.** Switching model or |
| 608 | inference backend is UI state, so it renders as a completed think-kind tool |
| 609 | call. The sign-in prompt stays an assistant message, since it needs the user |
| 610 | to act on it |
| 611 | |
| 612 | ### Fixed |
| 613 | |
| 614 | - **A reopened thread comes back with its history.** Clicking a saved thread in |
| 615 | Zed sends `session/load`, and the client draws the thread purely from the |
| 616 | `session/update` notifications the agent streams while that request is in |
| 617 | flight. siGit restored the saved history into the backend, which is what |
| 618 | makes the model remember, but sent the client nothing — so the thread opened |
| 619 | empty and looked like a brand new conversation. The snapshot is now turned |
| 620 | into updates before it is restored: user and assistant text as message chunks |
| 621 | with reasoning stripped, each tool call completed with its result folded in, |
| 622 | and `write_todos` as a plan the way it renders live. System messages stay |
| 623 | out, since they seeded the model and were never on screen |
| 624 | - **Compaction no longer fails in every session that ran a tool.** |
| 625 | `compact_history` asked for the summary through `complete(None, None)`, which |
| 626 | sends no tools array but left the live history in place. That history is |
| 627 | thick with assistant `tool_calls` and `role: "tool"` messages, and an |
| 628 | endpoint handed tool shapes with no schema to check them against rejects the |
| 629 | request — Anthropic answers 400. So compaction failed on every attempt in any |
| 630 | session that had run a single tool, however small the history was, and then |
| 631 | retried on every prompt and tool round while that history kept growing. The |
| 632 | conversation now goes as a flattened transcript in one user message, which |
| 633 | keeps what the summary needs and drops the shapes that only mean anything |
| 634 | next to a tool schema |
| 635 | - **A tool call emitted as text is no longer dropped.** Qwen 3, GLM and |
| 636 | DeepSeek write a call as `<tool_call>NAME<arg_key>…` in their chat template |
| 637 | and rely on the serving stack to parse it back into `tool_calls`. When that |
| 638 | doesn't happen the tag arrives as ordinary content, so it was rendered |
| 639 | verbatim in the editor and the turn ended as though the model had chosen to |
| 640 | answer in prose. Both the streaming and non-streaming paths now scan content |
| 641 | for those blocks and turn well-formed ones back into real calls, typing |
| 642 | argument values from the turn's own tool schemas. The streaming scanner holds |
| 643 | back only enough text to catch a tag straddling a chunk boundary, so ordinary |
| 644 | answers still stream token by token. A block that doesn't match the expected |
| 645 | shape is left in the text untouched: reissuing a `run_command` is cheap, but |
| 646 | guessing wrong at a half-parsed `edit_file` would write the wrong change to a |
| 647 | file |
| 648 | - **Tool-call content survives awkward output.** Whitespace-only output is |
| 649 | preserved rather than collapsed, malformed arguments no longer get a |
| 650 | misleading JSON fence, and fence language identifiers are sanitized |
| 651 | |
| 652 | ## 1.5.7 |
| 653 | |
| 654 | ### What changed |
| 655 | |
| 656 | - **`@smbcloud/sigit` gets releases again.** The npm scope moved to |
| 657 | `@getsigit` in 1.5.5 and the old package was left sitting on the registry at |
| 658 | 1.5.2, so an install made before the rename went quiet — `npm update` had |
| 659 | nothing to give it and nothing said why. All seven packages now publish under |
| 660 | both scopes from the same build, so `@smbcloud/sigit` is a full install again |
| 661 | rather than a stub, with its own platform binaries and no dependency on the |
| 662 | new scope. It prints a line on stderr saying where the package moved to; |
| 663 | `SIGIT_SUPPRESS_SCOPE_NOTICE=1` turns that off. This is a migration path, not |
| 664 | a second home: `@getsigit/sigit` is what the docs, the Homebrew tap, and the |
| 665 | ACP registry entry point at, and it is the name to move to |
| 666 | - **Multi-root projects now work in the editor.** When a client opens several |
| 667 | directories in one project, ACP sends the extra ones as |
| 668 | `additionalDirectories` — but only to an agent that says it wants them, which |
| 669 | siGit never did, so Zed kept the first root and showed a banner saying |
| 670 | multi-root workspaces were unsupported. The capability is now advertised at |
| 671 | `initialize`, and the directories that arrive are no longer logged and thrown |
| 672 | away. All the roots are now part of the session: the model is told about each |
| 673 | one, every root's `AGENTS.md` / `CLAUDE.md` is loaded, and skills, slash |
| 674 | commands, and subagent types are discovered from all of them (primary root |
| 675 | first, so it still wins name collisions). `/status` lists the roots when |
| 676 | there is more than one, and headless runs take the same thing as repeatable |
| 677 | `--add-dir <dir>` flags. MCP servers are the exception: discovery happens |
| 678 | once at startup, before a session exists, so a second root's `.sigit/mcp.toml` |
| 679 | is not picked up |
| 680 | |
| 681 | ### Fixed |
| 682 | |
| 683 | - **A shell command can no longer wedge the editor session.** Tool commands |
| 684 | inherited siGit's own stdin, which in ACP mode is the JSON-RPC pipe from the |
| 685 | editor. A command that read stdin — a signing passphrase prompt, a pager, a |
| 686 | `git` credential ask — blocked on it and consumed the client's next request |
| 687 | out of the pipe, so nothing typed afterwards ever reached the agent and the |
| 688 | session stayed dead past the command timeout. Commands, hooks, and the |
| 689 | co-author `git` helpers now run with stdin closed, so a command that wants |
| 690 | input gets EOF and reports an error instead |
| 691 | - **A command that prints a lot no longer stalls for two minutes.** |
| 692 | `run_command` waited for the command to exit before reading its output, so |
| 693 | anything past the pipe buffer (a build, a verbose test run) blocked writing |
| 694 | while siGit blocked waiting, until the 120-second timeout killed it. Output |
| 695 | is now drained while the command runs |
| 696 | - **The command timeout now stops the whole command.** It killed only the |
| 697 | shell, leaving anything that shell had started running and unreaped; it now |
| 698 | kills the process group |
| 699 | - **A refused turn now shows the endpoint's own message.** siGit pasted the |
| 700 | status line and the raw JSON body into the editor's error banner, so a |
| 701 | billing or allowance message arrived wrapped in |
| 702 | `endpoint returned 429 Too Many Requests: {"error":{"message":…`. The message |
| 703 | the endpoint wrote is what the banner shows now; the status is only used when |
| 704 | there is no message to show |
| 705 | - **An error that arrives mid-stream is no longer silent.** An endpoint that |
| 706 | fails after the response is already open reports it as a frame in the stream. |
| 707 | That frame carries no `choices`, so siGit parsed it as an empty chunk and |
| 708 | skipped it, and the turn ended as though the model had answered with nothing |
| 709 | |
| 710 | ## 1.5.6 |
| 711 | |
| 712 | ### What changed |
| 713 | |
| 714 | - **Switching models mid-conversation no longer restarts it.** Both switching |
| 715 | to a local GGUF model and picking a different cloud tier now carry the live |
| 716 | conversation history across, repairing any half-finished tool call so |
| 717 | strict OpenAI-compatible endpoints don't reject the session |
| 718 | - **Long-running tools now show progress in ACP clients.** Synchronous tools |
| 719 | (shell commands, file operations, `read_website`, ...) run on a blocking |
| 720 | thread pool instead of the ACP connection's own task, so a slow command's |
| 721 | `in_progress` update reaches the client — and Zed's spinner — while the |
| 722 | command is still running instead of arriving with the result |
| 723 | - **Text from consecutive tool rounds no longer runs together.** ACP and |
| 724 | headless clients concatenate consecutive message chunks, so a reply that |
| 725 | continued after a tool call used to glue onto the previous round's last |
| 726 | sentence with no space. A blank line now opens the next round's text |
| 727 | - **New onde-cloud model tiers.** The model picker (`/models` in the TUI, the |
| 728 | config panel in editors) now offers five additional siGit Code Cloud tiers — |
| 729 | `flux`, `apex`, `aura`, `orbit`, and `nova` — alongside the existing Fast, |
| 730 | Balanced, Large, Mini, Air, Pro, and KKK options. The tier list mirrors |
| 731 | onde-cloud's router catalogue, so all three sides (the picker, the router, |
| 732 | and the cloud catalogue) have to be updated together when a tier is added |
| 733 | - **MCP Registry listing moved to `getsigit/si`.** The `server.json` manifest |
| 734 | and its `release-mcp-registry.yml` publish workflow now live in the |
| 735 | [`getsigit/si`](https://github.com/getsigit/si) repo alongside the si CLI's |
| 736 | other code, since the registry entry describes the si platform rather than |
| 737 | the coding agent |
| 738 | |
| 739 | ## 1.5.5 |
| 740 | |
| 741 | A distribution release. siGit Code itself is unchanged. What moved is how it |
| 742 | reaches you on npm and on Windows. |
| 743 | |
| 744 | ### What changed |
| 745 | |
| 746 | - **The npm package is now `@getsigit/sigit`.** The six platform packages moved |
| 747 | with it. `@smbcloud/sigit` stays on the registry but stops receiving updates, |
| 748 | so upgrading means switching names: |
| 749 | `npm uninstall -g @smbcloud/sigit && npm install -g @getsigit/sigit`. The old |
| 750 | package had been stuck at 1.5.2, so this picks up 1.5.3 and 1.5.4 as well. |
| 751 | - **npm publishes over OIDC.** Every `@getsigit/*` package has a trusted |
| 752 | publisher pointing at the release workflow, so no npm token is stored in the |
| 753 | repository. The release workflow moves to Node 22, which trusted publishing |
| 754 | requires. |
| 755 | - **winget releases actually go out.** The workflow could only update a package |
| 756 | already present in `microsoft/winget-pkgs`, and siGit Code had never been |
| 757 | submitted there, so every dispatch failed. It now submits the package the |
| 758 | first time and updates it on later releases. The identifier is |
| 759 | `getSigit.siGitCode`. |
| 760 | |
| 761 | ## 1.5.4 |
| 762 | |
| 763 | - **CI**: nfpm config expanded to include package version and binary path |
| 764 | |
| 765 | ## 1.5.3 |
| 766 | |
| 767 | Adds browser-based sign-in, expands distribution channels to Windows (winget, |
| 768 | Scoop), Linux (AUR, deb, rpm), and .NET (NuGet), gives ACP clients live |
| 769 | visibility into tool activity, adds the KKK and Moonshot AI cloud tiers, and |
| 770 | fixes the co-authored-by trailer email. |
| 771 | |
| 772 | ### What changed |
| 773 | |
| 774 | - **Browser sign-in:** `sigit login` now opens a browser OAuth flow (PKCE S256 |
| 775 | against the siGit Code Cloud authorization server) so you can sign in without |
| 776 | a password. A loopback listener catches the redirect automatically; a |
| 777 | paste-back fallback handles environments where a loopback isn't reachable. |
| 778 | `--paste` forces the paste path, `--password` keeps the old email/password |
| 779 | prompt. Zed's "Sign in to siGit Code" button uses the loopback path via ACP |
| 780 | `authenticate` |
| 781 | - **New release channels:** siGit Code is now published to winget |
| 782 | (`getsigit.siGitCode`), Scoop (`getsigit/scoop-bucket`), the AUR |
| 783 | (`sigit-bin`), and as `.deb`/`.rpm` packages alongside the existing |
| 784 | Homebrew, npm, PyPI, crates.io, and NuGet channels |
| 785 | - **NuGet .NET tool:** `dotnet tool install --global SiGit.Code` now works on |
| 786 | Windows, macOS, and Linux — the package bundles all six platform binaries and |
| 787 | a managed shim that execs the right one, leaving stdin/stdout/stderr |
| 788 | unredirected so TUI vs ACP mode detection still works |
| 789 | - **New cloud tiers:** the model picker (`/models` in the TUI, the config |
| 790 | panel in Zed) now offers the `onde-kkk` (KKK) and Moonshot AI (`oke`) tiers |
| 791 | alongside the existing Fast, Balanced, Large, Mini, Air, and Pro options |
| 792 | - **ACP tool visibility:** the agent loop now emits `ToolCall(InProgress)` |
| 793 | before each tool runs and `ToolCallUpdate(Completed/Failed)` after it |
| 794 | returns, so clients like Zed gain live visibility into tool activity between |
| 795 | inference rounds. `tool_choice: "auto"` is also sent explicitly whenever |
| 796 | tools are present, fixing models that describe actions in prose rather than |
| 797 | issuing a tool call when the field is absent |
| 798 | - **Malformed tool argument logging:** invalid tool argument JSON is now logged |
| 799 | at three sites (TUI pretty-printer, ACP tool-call event, permission request) |
| 800 | instead of silently falling back to a string value, making malformed payloads |
| 801 | visible in logs while preserving backward-compatible behaviour |
| 802 | - **Co-authored-by trailer fix:** the `Co-Authored-By` trailer email was |
| 803 | updated to `noreply@sigit.si` (platform-neutral); the commit attribution |
| 804 | check was tightened to use idiomatic ownership |
| 805 | - **NuGet trusted publishing:** the NuGet release workflow now exchanges a |
| 806 | GitHub OIDC token for a short-lived NuGet API key (via `NuGet/login`) instead |
| 807 | of relying on a long-lived `NUGET_API_KEY` secret, so there is no stored |
| 808 | credential to rotate or leak |
| 809 | - **AUR dispatch temporarily disabled:** the AUR release workflow is no longer |
| 810 | dispatched from `release-github` while new AUR account registration is |
| 811 | closed; the `sigit-bin` channel returns once registration reopens |
| 812 | - Legal and branding copy updated |
| 813 | |
| 814 | ## 1.5.2 |
| 815 | |
| 816 | Brings the latest siGit Code Cloud tiers to the picker and aligns the MCP |
| 817 | registry metadata with the server release. |
| 818 | |
| 819 | ### What changed |
| 820 | |
| 821 | - `/models` now lists the Pro, Air, and Mini siGit Code Cloud tiers alongside |
| 822 | Fast, Balanced, and Large |
| 823 | - Updated the MCP registry manifest to version 1.2.5, matching the siGit Code |
| 824 | Cloud server release |
| 825 | - Updated the Agent Client Protocol SDK to the latest v1 release |
| 826 | |
| 827 | ## 1.5.1 |
| 828 | |
| 829 | Makes siGit Code work as an Xcode custom agent, and updates the Onde SDK. |
| 830 | |
| 831 | ### What changed |
| 832 | |
| 833 | - Xcode can now run siGit Code as a custom agent. Point it at the binary with |
| 834 | `--acp` as the argument, and that explicit mode loads the selected on-device |
| 835 | model on the first prompt, since Xcode's chat has no equivalent of `/load`. |
| 836 | The README covers the setup, including wiring up `xcrun mcpbridge` in |
| 837 | `mcp.toml` so the agent can use Xcode's build, test, and project tools |
| 838 | - MCP calls to the `xcode` server time out after 30 seconds instead of 120, so |
| 839 | a request Xcode cannot service no longer leaves the prompt looking busy for |
| 840 | two minutes. String JSON-RPC ids from the bridge are handled too |
| 841 | - The agent stops repeating itself: a tool call made three times with identical |
| 842 | arguments now forces a text reply instead of looping |
| 843 | - Onde SDK bumped to 1.2.2 |
| 844 | - The registry listing in `server.json` matches what sigit.si publishes |
| 845 | |
| 846 | ## 1.5.0 |
| 847 | |
| 848 | Opens the agent up to user extension: lifecycle hooks, custom slash commands, |
| 849 | and configurable subagent types. Also adds web search, a Repo tab in the TUI, |
| 850 | and a baked-in smbCloud MCP server. |
| 851 | |
| 852 | ### What changed |
| 853 | |
| 854 | - Hooks let you run shell commands at three points in the agent's lifecycle: |
| 855 | `session_start`, `pre_tool_use`, and `post_tool_use`, configured under |
| 856 | `[hooks]` in `settings.toml`. Commands get context through variable |
| 857 | substitution (`{cwd}`, `{tool_name}`, `{tool_result_len}`) and run in the |
| 858 | session working directory. A hook that fails is logged and the session |
| 859 | continues; a hook that hangs is killed on a timeout, along with its whole |
| 860 | process group |
| 861 | - User-defined slash commands: drop a Markdown file in `.sigit/commands/` or |
| 862 | `.claude/commands/` (or the personal `$SIGIT_CONFIG_DIR/commands/` and |
| 863 | `~/.claude/commands/`) with optional `description` and `argument-hint` |
| 864 | frontmatter, and the body becomes a prompt template. `$ARGUMENTS` takes the |
| 865 | whole argument string and `$1`..`$9` the positional words. A subdirectory |
| 866 | namespaces the command with `:`, so `.sigit/commands/git/commit.md` becomes |
| 867 | `/git:commit`. They run as ordinary agent turns through the usual tools and |
| 868 | permission checks, and are advertised to ACP clients like Zed. `/commands` |
| 869 | lists what was discovered |
| 870 | - Configurable subagent types for the `task` tool: a Markdown file in |
| 871 | `.sigit/agents/` or `.claude/agents/` with `name`, `description`, and an |
| 872 | optional `tools:` allow-list, whose body becomes that subagent's system |
| 873 | prompt. Pass its name as `subagent_type` to swap the prompt in. The |
| 874 | `tools:` list can only narrow the subagent's read-only ceiling, never widen |
| 875 | it, so a config file cannot grant itself `edit_file` or `run_command` and |
| 876 | route around the permission system. `/agents` lists the discovered types |
| 877 | - New `web_search` tool, backed by the Brave-Search-backed search on siGit |
| 878 | Code Cloud's MCP server. It is offered only when you are signed in, and it |
| 879 | is classified read-only, so searching never triggers a permission prompt |
| 880 | - The TUI gains a Repo tab, shown when the session's `origin` remote points at |
| 881 | the sigit.si host. It lists issues and pull requests fetched through the |
| 882 | official MCP server: Up and Down select, Enter opens a scrollable detail, |
| 883 | `i`, `p`, Left and Right switch sections, `r` refreshes. The tab is hidden |
| 884 | and skipped in the cycle for any other remote |
| 885 | - The smbCloud CLI's stdio MCP server (`smb --mcp`) is now baked in, so |
| 886 | smbCloud project and deployment tools work with no `mcp.toml` setup. It is |
| 887 | added only when the `smb` binary is on `PATH`, its read-only tools (`me`, |
| 888 | `deployments`, `project_list`, `project_show`) skip permission prompts, and |
| 889 | you can opt out with `smbcloud = false` in `mcp.toml` or |
| 890 | `SIGIT_MCP_SMBCLOUD=off` |
| 891 | - siGit Code Cloud's MCP server is now listed in the public MCP Registry as |
| 892 | `si.sigit/sigit`, published from `server.json` at the repository root |
| 893 | |
| 894 | ### Fixes |
| 895 | |
| 896 | - An explicit `deny` rule now applies to read-only first-party tools instead |
| 897 | of being skipped |
| 898 | - A subagent type whose `tools:` list resolves to an empty set is rejected |
| 899 | rather than producing a subagent with no tools |
| 900 | - Command templates render in a single substitution pass, so an argument that |
| 901 | contains something like `$1` is no longer re-substituted |
| 902 | - Frontmatter is stripped with the same leniency it is parsed with |
| 903 | - The Repo tab's detail view no longer shows stale data after a refresh |
| 904 | |
| 905 | ## 1.4.1 |
| 906 | |
| 907 | Two small fixes: correct co-author attribution and a Homebrew tap fix. |
| 908 | |
| 909 | ### What changed |
| 910 | |
| 911 | - The `Co-Authored-By` trailer siGit Code adds to commits now uses the GitHub |
| 912 | noreply address for the [sigitc](https://github.com/sigitc) account instead |
| 913 | of `sigit@sigit.si`, so GitHub reliably attributes co-authored commits to |
| 914 | the siGit Code profile |
| 915 | - Fixed the Homebrew tap install docs to trust the tap with `brew trust` |
| 916 | instead of a `brew tap --force` flag |
| 917 | |
| 918 | ## 1.4.0 |
| 919 | |
| 920 | Adds a headless one-shot mode, fine-grained permission rules, stdio transport |
| 921 | for MCP servers, an `/init` command, and a set of TUI upgrades: tabs, a live |
| 922 | thinking display, and collapsible tool calls. |
| 923 | |
| 924 | ### What changed |
| 925 | |
| 926 | - New headless mode: `sigit -p "prompt"` runs one agent turn with tools and exits — 0 on a completed turn, 1 on inference errors, 2 on bad invocations. Assistant text streams to stdout while logs and tool progress stay on stderr; `--cwd` sets the working directory and `--quiet` prints only the final message. Nobody can answer a permission prompt in a headless run, so `ask` collapses to a denial: grant tools for the run with `--allow-tool`, block them with `--deny-tool`, or use `SIGIT_PERMISSIONS=allow` |
| 927 | - Permission rules make autonomy granular: `[permissions.rules]` in `settings.toml` holds ordered `allow` and `deny` lists of `tool_name(pattern)` entries, e.g. `run_command(git *)` or `edit_file(src/*)`. Patterns match the command string for `run_command` and the path for file tools; deny always beats allow, and unparseable patterns fail closed, so a bad rule can only narrow access. Always-allow on a `run_command` prompt now grants that command family (its first two tokens), not the whole shell |
| 928 | - The MCP client speaks stdio: `mcp.toml` server entries can give a `command`, `args`, and an `env` map instead of a `url`, so the stdio-first majority of published MCP servers plugs in. Same handshake, timeouts, tool namespacing, and output caps as HTTP; `/mcp` shows the command line for stdio servers |
| 929 | - New `/init` command (TUI and ACP): runs a normal agent turn that explores the repository and writes an `AGENTS.md` — or improves an existing `AGENTS.md`/`CLAUDE.md` in place — going through the ordinary tools and permission checks |
| 930 | - The TUI gains tabs, cycled with the Tab key: Session is the chat, History lists saved sessions (restore with Enter, delete with a confirmed double-`d`, refresh with `r`), and Cloud shows the signed-in account, inference mode, current model and engine state, permission policy, and config dir, with a live Local Inference toggle |
| 931 | - The TUI shows model thinking: while a reply streams, the last three lines of the reasoning appear live under the spinner, dim and italic; finished replies collapse to a one-line indicator with the line count, and `/thinking` expands the full reasoning block above each reply. Display only — nothing changes in what is sent to the model, saved to sessions, or streamed over ACP |
| 932 | - Tool calls in the TUI transcript collapse to single dim title lines (the command for `run_command`, the path for file tools, the pattern for search and glob); `/tools` expands every entry to show the pretty-printed arguments and a capped tail of the result. Permission prompts keep showing the full command, and the model still receives full outputs |
| 933 | - When `AGENTS.md` and `CLAUDE.md` sit in the same directory, the instructions loader now prefers `AGENTS.md`, so shared content is injected once |
| 934 | |
| 935 | ## 1.3.2 |
| 936 | |
| 937 | Adds a tool permission system with plan mode, durable sessions with context |
| 938 | compaction, background command execution, a subagent research tool, and commit |
| 939 | co-author attribution. |
| 940 | |
| 941 | ### What changed |
| 942 | |
| 943 | - Every tool call now passes a permission policy before executing. Read-only tools always run; mutating tools (and all MCP or unknown tools) are governed by, in order: plan mode, session grants, per-tool overrides, and a default mode from `[permissions]` in `settings.toml` (`allow`/`ask`/`deny`, default `ask`). On `ask`, editors get a native ACP permission dialog (allow once / allow for this session / deny) and the TUI pauses on a y/a/n prompt showing the tool and its arguments. `SIGIT_PERMISSIONS` overrides the default mode for headless runs and clients without permission support |
| 944 | - New `/plan [on|off]` command: plan mode blocks mutating tools and asks the model to present a plan while research tools keep working. `/permissions` prints the effective policy |
| 945 | - Sessions are durable: conversation history is saved per session under `~/.config/sigit/sessions/` after every turn. ACP `session/load` actually restores it, the TUI gets `/resume`, and `/clear` deletes the saved file |
| 946 | - Context compaction: `/compact` compresses the conversation on demand, and the agent compacts automatically once the history approaches a 24k-token budget, summarizing older turns and keeping the recent ones. The tool-round cap rises from 10 to 24 now that long sessions have a defense other than the cap |
| 947 | - `run_command` can run work in the background: pass `run_in_background` and the tool returns a task id immediately, so builds, test suites, and dev servers are no longer killed by the 120 second foreground timeout. Poll with the new `command_output` tool (read-only, never prompts) and stop with `kill_command` |
| 948 | - New `task` tool: delegate research to a fresh subagent conversation that only gets the read-only tools and returns its final answer, keeping the main context small. Available on OpenAI-compatible backends; on-device returns a clear fallback until onde supports a second context |
| 949 | - Commits created by the agent are co-authored: commit messages end with `Co-Authored-By: siGit Code <sigit@sigit.si>` (the [sigitc](https://github.com/sigitc) account), which GitHub renders next to the human author. If the model forgets the trailer, siGit amends it in, never rewriting commits that already exist on a remote |
| 950 | - ACP mode now honors the `OPENAI_BASE_URL`/`OPENAI_API_KEY` provider override at startup, matching the interactive client |
| 951 | |
| 952 | ## 1.3.1 |
| 953 | |
| 954 | Adds [Model Context Protocol](https://modelcontextprotocol.io) (MCP) client |
| 955 | support with the official siGit Code MCP server baked in, a set of agent tools |
| 956 | that close parity gaps in the tool layer, and refreshed branding and licensing. |
| 957 | |
| 958 | ### What changed |
| 959 | |
| 960 | - siGit Code is now an MCP client: it connects to MCP servers over the Streamable HTTP transport (a single JSON-RPC endpoint), discovers the tools they expose, and offers them to the model alongside the built-in tools. When the model calls one, the call is forwarded to the owning server and the result fed back into the agent loop |
| 961 | - Bakes in the official siGit Code MCP server at `https://sigit.si/api/v1/mcp` (follows `SIGIT_CLOUD_URL`). When you are signed in (`sigit login`), the cloud session token is sent as the bearer credential |
| 962 | - Configure additional servers in `mcp.toml` — global (`~/.config/sigit/mcp.toml`) or project-local (`.sigit/mcp.toml`). Each `[[server]]` has a `name`, `url`, optional `enabled`, and optional `[server.headers]`; set `official = false` to opt out of the baked-in server |
| 963 | - MCP tools are namespaced `mcp__<server>__<tool>` so they never collide with built-in tools or across servers; tool output is capped to protect the model's context |
| 964 | - Discovery is best-effort at startup and bounded by a per-server timeout, so an unreachable server never blocks startup — it just contributes no tools |
| 965 | - Added a `/mcp` slash command (TUI and ACP) that lists configured servers, their connection status, and the tools each exposes |
| 966 | - Disable MCP entirely with `SIGIT_MCP=off`, or just the official server with `SIGIT_MCP_OFFICIAL=off` |
| 967 | - New agent tools that close parity gaps in the tool layer: `multi_edit` (apply a batch of exact-substring edits to one file atomically — written only if every edit matches), `glob` (locate files by name pattern with `**`/`*`/`?`/`{a,b}`, most-recently-modified first), `write_todos` (render a live task checklist through the tool result for multi-step work), and `remember` (append durable notes to the nearest `AGENTS.md`/`CLAUDE.md`) |
| 968 | - `edit_file` now supports `replace_all` and returns actionable failure context — naming the line whose trimmed text matches when only whitespace differs — so the model self-corrects in one round |
| 969 | - `search_files` gained a `file_glob` filter and a `max_results` cap (default 50, hard-capped at 1000) that also bounds the directory walk |
| 970 | - Refreshed branding and legal: updated `LICENSE`, `README`, and the npm/PyPI package descriptions |
| 971 | |
| 972 | ## 1.3.0 |
| 973 | |
| 974 | Adds a Local Inference on/off toggle, the open [Agent Skills](https://agentskills.io) |
| 975 | format, and support for project instruction files (`AGENTS.md` and the like). |
| 976 | |
| 977 | ### What changed |
| 978 | |
| 979 | - Added a Local Inference on/off setting that is the explicit local-vs-cloud mode switch. It is persisted in `~/.config/sigit/settings.toml` (default on, local-first) and can be overridden with `SIGIT_LOCAL_INFERENCE` |
| 980 | - Toggle it with the `/local [on|off]` command (TUI and ACP); ACP clients without slash-command support get an equivalent "Local Inference" On/Off control in the session config panel |
| 981 | - `/models` now groups models by nature — Local vs siGit Code Cloud — and highlights the active mode's group while still showing the other, so the cloud tiers stay discoverable |
| 982 | - Discovers Agent Skills (folders with a `SKILL.md`) from `.sigit/skills/` and `.claude/skills/` in the project, `~/.config/sigit/skills/`, and `~/.claude/skills/` |
| 983 | - Follows the spec's progressive disclosure: each skill's name and description are advertised up front via a new `skill` tool, and the full instructions load only when the agent activates one |
| 984 | - Added a `/skills` slash command (TUI and ACP) that lists the discovered skills |
| 985 | - Reads project instruction files at session start: `AGENTS.md` (the cross-tool standard) and `CLAUDE.md`, walking from the working directory up to the repository root, plus a global file under `~/.config/sigit/`, and injects them into the session's system context so their guidance is always in force |
| 986 | - Nested instruction files are ordered outermost-first so the closest, most specific file takes precedence; the scan never reads above the repository root |
| 987 | - On-device models are no longer loaded implicitly. The chat UI and ACP sessions come up immediately, and the local model is brought into memory only when you run the `/load` command (or pick one in `/models`). Prompts sent before a model is loaded now return a hint instead of blocking on a multi-minute download. |
| 988 | |
| 989 | ## 1.2.2 |
| 990 | |
| 991 | Streams assistant tokens as they arrive, on-device and over the cloud. |
| 992 | |
| 993 | ### What changed |
| 994 | |
| 995 | - Streamed assistant tokens live in the TUI and ACP sessions, both on-device and through siGit Code Cloud |
| 996 | - On-device inference streams only when a turn offers no tools, since `onde` can't stream and detect tool calls in the same pass; tool-capable turns still resolve in one shot |
| 997 | - Fixed the TUI so the latest message stays visible in long chats |
| 998 | - Put the cloud model-switch confirmation on its own line in ACP |
| 999 | |
| 1000 | ## 1.2.1 |
| 1001 | |
| 1002 | Stabilizes the Zed/ACP integration and finishes the cloud-tier wiring on top of 1.2.0. |
| 1003 | |
| 1004 | ### What changed |
| 1005 | |
| 1006 | - Fixed a Zed crash by keeping model-picker labels ASCII in the ACP model selector |
| 1007 | - Wired ACP auth, cloud tiers, and slash commands into the Zed panel, including a `/reload` command to re-sync session state in place |
| 1008 | - Fixed the TUI so the loaded-model checkmark appears once a download completes |
| 1009 | - Synced bundled agent skills with the current code and added `CLAUDE.md` |
| 1010 | |
| 1011 | ## 1.2.0 |
| 1012 | |
| 1013 | Adds siGit Code Cloud — a hosted inference tier alongside on-device models. |
| 1014 | |
| 1015 | ### What changed |
| 1016 | |
| 1017 | - Added siGit Code Cloud with cloud-tier routing, pointed at `sigit.si` |
| 1018 | - Added account management slash commands and surfaced cloud tiers in `/models` |
| 1019 | - Carried forward from 1.1.0: ACP SDK v0.13, refreshed dependencies and branding |
| 1020 | |
| 1021 | ## 1.1.0 |
| 1022 | |
| 1023 | Bumps the ACP SDK to v0.13 and pulls in updated dependencies. |
| 1024 | |
| 1025 | ### What changed |
| 1026 | |
| 1027 | - Updated `agent-client-protocol` from v0.11 to v0.13 |
| 1028 | - Updated `onde` to 1.1.2 |
| 1029 | - Refreshed branding and skill metadata |
| 1030 | |
| 1031 | ## 1.0.4 |
| 1032 | |
| 1033 | This release tightens up the terminal experience and finishes a few release-facing cleanup items. |
| 1034 | |
| 1035 | ### What changed |
| 1036 | |
| 1037 | - Added bold rich-text rendering in the TUI for assistant replies, so `**text**` now displays with terminal styling instead of raw markdown markers |
| 1038 | - Refreshed the bundled skill metadata to follow the current Agent Skills `SKILL.md` format |
| 1039 | - Synced the crate release metadata for the `1.0.4` cut |
| 1040 | |
| 1041 | ## 1.0.3 |
| 1042 | |
| 1043 | This is the cleanup release for the editor-side startup problems. |
| 1044 | |
| 1045 | ### What changed |
| 1046 | |
| 1047 | - Fixed ACP sessions failing on the first real prompt because the server claimed the model was ready before anything had actually been loaded |
| 1048 | - Changed ACP startup so the default model loads lazily on the first non-slash prompt instead of pretending it is already in memory |
| 1049 | - Kept `initialize` and `session/new` lightweight while still sending proper progress updates once model loading begins |
| 1050 | - Updated the Onde integration to `1.0.0` |
| 1051 | - Removed a few dependencies we were no longer using |
| 1052 | |
| 1053 | ## 1.0.2 |
| 1054 | |
| 1055 | This release was supposed to fix the ACP auth breakage. It did fix the stdout pollution problem, but it turned out not to be the whole story. |
| 1056 | |
| 1057 | ### What changed |
| 1058 | |
| 1059 | - Delayed model loading in ACP mode so startup diagnostics would not leak into protocol stdout during the auth handshake |
| 1060 | - Tightened up the ACP startup path for editor integrations |
| 1061 | - Refreshed some README wording while cutting `1.0.2` |
| 1062 | |
| 1063 | ## 1.0.1 |
| 1064 | |
| 1065 | The first patch after `1.0.0` was mostly about making model loading and model switching feel less opaque. |
| 1066 | |
| 1067 | ### What changed |
| 1068 | |
| 1069 | - Added ToolCall-based progress UI for startup model loading and downloading |
| 1070 | - Improved model-switch progress reporting in ACP clients |
| 1071 | - Fixed model-load error handling so failed switches did not leave the UI in a weird state |
| 1072 | - Cleaned up a few status messages and docs while the release was going out |
| 1073 | |
| 1074 | ## 1.0.0 (2026) |
| 1075 | |
| 1076 | siGit Code has been living in real smbCloud repos for a while now. At some point it stopped feeling like an experiment, so we called it 1.0. |
| 1077 | |
| 1078 | ### What this release is |
| 1079 | |
| 1080 | siGit Code is a local coding agent. It runs a quantized model on your machine, talks to editors over ACP, and can read files, run commands, fetch web pages, and write code without sending your project to a hosted API. |
| 1081 | |
| 1082 | You can install it with Cargo, pip, npm, or Homebrew and use it like any other tool on your machine. |
| 1083 | |
| 1084 | ### What shipped in 1.0 |
| 1085 | |
| 1086 | #### Editor integration |
| 1087 | |
| 1088 | This is the core of the project. |
| 1089 | |
| 1090 | Zed and VS Code can talk to siGit Code over ACP. Multi-turn sessions work. Tool calling works. Session forking works. Working-directory context works. That was the original goal, and it feels solid now. |
| 1091 | |
| 1092 | #### Terminal UI |
| 1093 | |
| 1094 | The terminal UI started as a side quest and turned out to be useful. You get a full-screen ratatui chat, streaming tokens, a spinner while the model is busy, and a model picker you can open in the middle of a session. |
| 1095 | |
| 1096 | It runs on macOS and Linux. Windows gets ACP and editor mode for now. The Windows terminal UI is still unfinished. |
| 1097 | |
| 1098 | #### Tool calling |
| 1099 | |
| 1100 | This is the part that makes siGit Code feel like an agent instead of a chat box. The loop can run up to 10 rounds per message. |
| 1101 | |
| 1102 | Available tools: |
| 1103 | |
| 1104 | - `read_file` / `write_file` / `delete_file` |
| 1105 | - `list_directory` / `search_files` |
| 1106 | - `run_command`, with an optional working directory |
| 1107 | - `read_website`, which fetches a URL and strips it down to readable text |
| 1108 | |
| 1109 | The model can call a tool, inspect the result, and keep going until it has a real answer. |
| 1110 | |
| 1111 | #### Model support |
| 1112 | |
| 1113 | The model list ended up wider than we expected for 1.0: |
| 1114 | |
| 1115 | - Qwen 3 1.7B, 4B, 8B, and 14B |
| 1116 | - Qwen 2.5 1.5B and 3B |
| 1117 | - Qwen 2.5 Coder 1.5B, 3B, and 7B |
| 1118 | - DeepSeek Coder 6.7B |
| 1119 | |
| 1120 | They are all GGUF models and they all come from Hugging Face on first run. |
| 1121 | |
| 1122 | Qwen 3 is the interesting one. It uses extended thinking mode. The model reasons inside `<think>...</think>` blocks before answering. The TUI strips those blocks out and renders them dimmed above the reply, so you can see what happened without turning the whole conversation into noise. |
| 1123 | |
| 1124 | The 8B model is the desktop default. Mobile stays on 1.7B because iOS gives apps roughly 2 to 3 GB of memory, and we learned the hard way that 3B can blow up on an iPhone 16e. |
| 1125 | |
| 1126 | #### Model picker |
| 1127 | |
| 1128 | The model picker shows: |
| 1129 | |
| 1130 | - what is already cached locally |
| 1131 | - what can be downloaded |
| 1132 | - which models support tool calling |
| 1133 | - whether the local cache looks healthy |
| 1134 | |
| 1135 | You can open it with `/models` in the TUI or through the editor config option. Switching models happens in the background and the UI stays alive while the download or load is in progress. |
| 1136 | |
| 1137 | #### smbCloud context |
| 1138 | |
| 1139 | siGit Code knows smbCloud repos better than a generic coding assistant does. It understands the difference between platform-user flows and tenant-app auth flows, how `Project`, `FrontendApp`, `AuthApp`, and GresIQ fit together, and why Next.js SSR deploys are not the same thing as the generic git-push path. |
| 1140 | |
| 1141 | Outside smbCloud, it backs off and behaves like a normal coding agent. |
| 1142 | |
| 1143 | #### Distribution |
| 1144 | |
| 1145 | Distribution took an unreasonable amount of time, honestly. |
| 1146 | |
| 1147 | There are prebuilt binaries for macOS, Linux, and Windows on both arm64 and x64 where relevant, plus install paths through Cargo, PyPI, npm, and Homebrew: |
| 1148 | |
| 1149 | - `cargo install sigit` |
| 1150 | - `pip install sigit-code` |
| 1151 | - `npm install -g @smbcloud/sigit` |
| 1152 | - `brew install sigit` |
| 1153 | |
| 1154 | Getting that whole pipeline to behave across CI, crates.io, PyPI, npm, and Homebrew was basically its own project. |
| 1155 | |
| 1156 | ### What still does not work |
| 1157 | |
| 1158 | The Windows terminal UI is still missing. |
| 1159 | |
| 1160 | ACP and editor mode work on Windows. The part that is still missing is the interactive full-screen terminal UI. The blocker is Unix-specific terminal handling that has not been abstracted cleanly yet. |
| 1161 | |
| 1162 | ### Changes since 0.1.2 |
| 1163 | |
| 1164 | - Added Qwen 3 14B support |
| 1165 | - Added Qwen 3 `<think>` block parsing and separate rendering in the TUI |
| 1166 | - Moved all TUI code into `#[cfg(unix)]`, which fixed a pile of dead-code errors on Windows CI |
| 1167 | - Added live download progress during model switches, including cancellation with Ctrl+C |
| 1168 | - Added model download and loading progress in the Zed agent config panel |
| 1169 | - Added an animated spinner during model switching |
| 1170 | - Added Qwen 2.5 Coder 7B |
| 1171 | - Added downloadable models to the picker, not just locally cached ones |
| 1172 | - Made model selection persist across restarts |
| 1173 | - Added session working-directory support |
| 1174 | - Moved model picker logic into a platform-independent module so Windows can compile without the TUI |
| 1175 | - Added the `/models N` shortcut for picking a model by number |
| 1176 | - Added the `read_website` tool |
| 1177 | - Improved `read_file` handling and empty-reply detection |
| 1178 | - Added async tool execution |
| 1179 | - Fixed CI cross-compilation for macOS, iOS, Linux, and Windows |
| 1180 | - Added npm, PyPI, and Homebrew distribution |
| 1181 | |
| 1182 | --- |
| 1183 | |
| 1184 | *© 2026 PT Sigit Mitra Bangun ([siGit Code & Deploy](https://sigit.si)), distributed by [Splitfire AB](https://5mb.app).* |