release/v1.6.1
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.1 |
| 4 | |
| 5 | ### Added |
| 6 | |
| 7 | - **Images can be attached to a prompt in the editor.** siGit Code now |
| 8 | advertises `promptCapabilities.image`, so an ACP client offers image |
| 9 | attachments. The image goes to the model when the active model reads images. |
| 10 | The model picker marks those models with "reads images". The on-device |
| 11 | models and four cloud tiers (`nova`, `orbit`, `apex`, `flux`) are text-only: |
| 12 | with one of them active the image is left out, a note in the thread says so, |
| 13 | and the model is told an image was withheld. Switching a thread that already |
| 14 | holds images to a text-only model flags that once as well. Cloud tiers need |
| 15 | siGit Code Cloud to accept image parts, which is rolling out separately |
| 16 | (#134). |
| 17 | |
| 18 | - **The tool-round cap of a headless run can be set.** `--max-tool-rounds <n>` |
| 19 | or `SIGIT_MAX_TOOL_ROUNDS` (1 to 500) replaces the built-in 24 for |
| 20 | `sigit run` and `sigit -p`. The flag wins over the variable. |
| 21 | |
| 22 | ### Fixed |
| 23 | |
| 24 | - **A prompt turn now reports why it stopped.** ACP defines five stop reasons |
| 25 | and siGit Code only ever sent `end_turn` and `cancelled`. A turn that runs |
| 26 | into the tool-round cap now ends with `max_turn_requests`, a reply cut off |
| 27 | at the token limit with `max_tokens`, and a reply the endpoint withheld |
| 28 | (`content_filter`) with `refusal`. A refused turn is also taken out of the |
| 29 | conversation, which is what the protocol tells the client to expect (#140). |
| 30 | |
| 31 | - **A tool call that needs approval is one card, not two.** The permission |
| 32 | request carried an id of its own, so an ACP client showed an approval card |
| 33 | beside a call that already claimed to be running. The call is now announced |
| 34 | as `pending`, the permission request names that same call, and it moves to |
| 35 | `in_progress` once approved. Calls allowed by policy still start out |
| 36 | `in_progress` (#138). |
| 37 | |
| 38 | - **A turn that runs out of tool rounds says so.** In an editor, a long task |
| 39 | could stop on a line like "Now commit:" with nothing after it. The turn had |
| 40 | used all 24 tool rounds, the model spent its last reply announcing the next |
| 41 | step, and the call behind it was dropped. siGit Code now tells the model |
| 42 | that its rounds are used up before that last reply, and ends the turn with a |
| 43 | message saying why it stopped and that "continue" picks it back up. |
| 44 | `SIGIT_MAX_TOOL_ROUNDS` now sets the cap for editor sessions too (#120). |
| 45 | |
| 46 | - **A headless run no longer ends silently with no final message.** When the |
| 47 | last round came back empty, which is what happens when a run is cut off at |
| 48 | the tool-round cap mid-task, stdout was empty and the exit status was 0, so |
| 49 | a caller could not tell it from a run with nothing to report. siGit Code now |
| 50 | asks the model once for its final message before finishing. |
| 51 | |
| 52 | ## 1.6.0 |
| 53 | |
| 54 | ### Added |
| 55 | |
| 56 | - **Editors can pass HTTP MCP servers to a session.** siGit Code now |
| 57 | advertises `mcpCapabilities.http`, so an ACP client may list Streamable HTTP |
| 58 | servers in `mcpServers` next to stdio ones. They are connected with the URL |
| 59 | and headers the client sent and are scoped to that session, like the stdio |
| 60 | ones. SSE is still not advertised, since the MCP spec deprecated it (#151). |
| 61 | |
| 62 | - **The plan panel survives a failed turn.** The last `write_todos` list is |
| 63 | now kept by siGit Code itself. When a turn ends in an endpoint error before |
| 64 | the model gets to call `write_todos` again, the saved list is sent to the |
| 65 | editor again, so the plan stays on screen where it used to go blank (#132). |
| 66 | |
| 67 | ### Changed |
| 68 | |
| 69 | - **The ACP Rust SDK is now 2.2** (`agent-client-protocol`, up from 1.3). |
| 70 | siGit Code still speaks ACP protocol v1 to the editor, so nothing changes on |
| 71 | the wire. The `unstable_auth_methods` feature is gone because agent auth |
| 72 | methods are stable in 2.x. |
| 73 | |
| 74 | ### Fixed |
| 75 | |
| 76 | - **MCP servers the editor passes to a session are connected.** ACP clients |
| 77 | can name MCP servers in `mcpServers` when they open a session, and agents |
| 78 | are required to connect to the stdio ones. siGit Code accepted the field and |
| 79 | ignored it. The servers are now spawned when the session opens, their tools |
| 80 | are offered to that session only, and `/mcp` lists them as coming from the |
| 81 | editor. `SIGIT_MCP=off` still turns all of it off (#135). |
| 82 | |
| 83 | - **A relative `cwd` is rejected when a session starts.** ACP requires the |
| 84 | working directory and every `additionalDirectories` entry to be absolute. |
| 85 | `session/new`, `session/load` and `session/fork` used to accept a relative |
| 86 | one and resolve it against wherever the editor spawned the process. They now |
| 87 | answer with an invalid-params error (#136). |
| 88 | |
| 89 | - **Loading a session that does not exist is an error.** `session/load` with |
| 90 | an id that was never saved used to succeed and open an empty session under |
| 91 | that id, so the editor showed a blank thread that looked restored. It now |
| 92 | answers "not found" (`-32002`). A thread opened in the running process but |
| 93 | not spoken in yet still loads (#137). |
| 94 | |
| 95 | - **Compaction no longer dead-ends a long session.** The summarization request |
| 96 | used to carry the whole conversation, which by then was already over the |
| 97 | model's window, so siGit Code Cloud timed out with a 504 and the session |
| 98 | stopped with "start a new thread". The transcript sent for summarizing is |
| 99 | now capped, cut from the middle so the opening request and the latest state |
| 100 | are kept. If summarizing still fails, the oldest messages are dropped until |
| 101 | the history fits, with whole tool rounds removed together. A failed attempt |
| 102 | leaves the conversation as it was (#125). |
| 103 | |
| 104 | - **Gateway error pages stay out of the chat.** When an endpoint answers with |
| 105 | an HTML error page, the error shown is the status line, not the page's |
| 106 | markup (#125). |
| 107 | |
| 108 | - **Issue and pull request work no longer assumes GitHub.** The system prompt |
| 109 | treated forge features as if every repository lived on GitHub, while the |
| 110 | built-in `mcp__sigit__*` tools only work for repositories hosted on |
| 111 | sigit.si. The agent now checks the remote first, uses those tools only for |
| 112 | sigit.si repositories, and reaches for the forge's own CLI (`gh`, `glab`, |
| 113 | `tea`) elsewhere (#127). |
| 114 | |
| 115 | ## 1.5.13 |
| 116 | |
| 117 | ### Added |
| 118 | |
| 119 | - **Three more siGit Code Cloud tiers: `flare`, `zenith` and `prism`.** They |
| 120 | show up in `/models` and in the editor's model picker alongside the existing |
| 121 | tiers. Selecting one needs a signed-in account, as before. |
| 122 | |
| 123 | ## 1.5.12 |
| 124 | |
| 125 | ### Fixed |
| 126 | |
| 127 | - **The Windows binaries start on machines without the Visual C++ |
| 128 | Redistributable.** They used to import `VCRUNTIME140.dll` and the UCRT |
| 129 | `api-ms-win-crt-*` DLLs, so a clean Windows install refused to load them |
| 130 | with `STATUS_DLL_NOT_FOUND` (0xC0000135). That is what failed winget's |
| 131 | post-install check. The C runtime is now linked statically, and CI and the |
| 132 | release build fail if a Windows exe picks up that dependency again. |
| 133 | |
| 134 | - **Watching a slow background command no longer ends the turn early.** |
| 135 | Polling `command_output` on the same task id three times tripped the |
| 136 | repeated-tool-call guard, which refused the call and dropped tools for the |
| 137 | rest of the turn. `command_output` now long-polls — it waits up to |
| 138 | `wait_seconds` (default 10, max 30) for the task to exit, then returns |
| 139 | everything printed in the meantime — and the repeat guard exempts it, since |
| 140 | polling the same task is the whole point of the tool. |
| 141 | |
| 142 | - **A turn that ends with no visible text says why.** When the |
| 143 | repeated-tool-call guard blocked a call and the forced no-tools round came |
| 144 | back empty, sigit sent nothing more — the turn just stopped with no answer |
| 145 | and no question. When the last round of a tool-using turn produces no |
| 146 | visible text, sigit now sends a short closing message naming the repeated |
| 147 | tool and asking you to reply "continue" or redirect. |
| 148 | |
| 149 | ## 1.5.11 |
| 150 | |
| 151 | ### Added |
| 152 | |
| 153 | - **`sigit run` drives the agent headlessly with resumable sessions.** A new |
| 154 | non-interactive subcommand runs a prompt through the same agent loop as the |
| 155 | editor and terminal surfaces, for scripts, CI, and Factory clients. Every run |
| 156 | gets a UUID session id, writes a JSON-lines history file under |
| 157 | `~/.config/sigit/sessions/`, and can be restored with `--resume <id>`. |
| 158 | `--output jsonl` emits a structured session/delta/tool/result stream on |
| 159 | stdout while logs stay on stderr, and `--allow-tool` pre-approves a tool so |
| 160 | permission prompts collapse to denial in a non-interactive context. The |
| 161 | legacy `-p` form still works. Each run also rewrites the session metadata |
| 162 | with its own cwd and extra roots, so resuming keeps multi-root projects |
| 163 | |
| 164 | - **Saved threads can be imported into the editor.** siGit Code now advertises |
| 165 | ACP's `sessionCapabilities.list` and answers `session/list`, so Zed's "Import |
| 166 | Threads" picker offers the conversations stored under |
| 167 | `~/.config/sigit/sessions/` instead of reporting that the agent doesn't |
| 168 | support the capability. A saved session gets a sidecar recording the project |
| 169 | directory it ran in — listing reports that `cwd`, the extra roots of a |
| 170 | multi-root project, an ISO 8601 last-activity timestamp, and a title taken |
| 171 | from the first user message — and a request may filter on `cwd` so one |
| 172 | project is never offered another's threads. Threads saved before this have no |
| 173 | sidecar and are not listed; they still reopen by id through `session/load` |
| 174 | |
| 175 | ### Changed |
| 176 | |
| 177 | - **The commit trailer names the siGit Code version and surface.** Commits |
| 178 | siGit Code makes now end with |
| 179 | `Co-Authored-By: siGit Code v<version>-<surface> <noreply@sigit.si>` instead |
| 180 | of the bare name, where the surface is `acp` (an editor), `tui` (the |
| 181 | terminal UI), or `headless` (`sigit run`). The model changes from session to |
| 182 | session; the version and surface tell you which build of the agent wrote the |
| 183 | commit and how it was driven. GitHub still credits the co-author, since it |
| 184 | matches on the address. A commit that already carries a siGit Code trailer |
| 185 | from an older version is left alone |
| 186 | |
| 187 | - **The terminal UI's model knows which directory the project is in.** The |
| 188 | editor (ACP) and headless paths put the working directory in the system |
| 189 | prompt, but the terminal UI only added the project's instruction files, so |
| 190 | on `/init` a small on-device model invented a `AGENTS.md` path and failed. |
| 191 | All three places the terminal UI builds a prompt now go through the same |
| 192 | session context path the ACP sessions get. The cloud tier switch had also |
| 193 | been dropping the instruction files; that's fixed too |
| 194 | |
| 195 | - **An empty `write_todos` list clears the plan.** `write_todos` rejected an |
| 196 | empty list, so the model had no way to clear a finished checklist and the |
| 197 | last plan stayed in the editor until the session ended. An empty list now |
| 198 | returns "Task list cleared." and goes to the client as an ACP plan with no |
| 199 | entries. The tool description tells the model it can do this |
| 200 | |
| 201 | - **`sigit run` gives clearer usage errors.** A second positional prompt says |
| 202 | "unexpected extra argument", a bare `sigit run` says "missing prompt", and a |
| 203 | mistyped flag like `--quite` is rejected instead of becoming the prompt |
| 204 | |
| 205 | ### Fixed |
| 206 | |
| 207 | - **Each ACP session keeps its own roots, conversation, and tasks.** Zed runs |
| 208 | one siGit process for every open thread, but the process had a single cwd, |
| 209 | workspace root list, backend conversation, and background task table. The |
| 210 | most recent session owned all of them, so a prompt from an older thread ran |
| 211 | against another repo with another thread's history. A `SessionState` is now |
| 212 | kept per session id; before a prompt or config change runs, the live |
| 213 | conversation is parked and the requested session's cwd, extra roots, and |
| 214 | conversation are installed, rebuilding the system prompt from its roots. |
| 215 | `new`/`load`/`fork` share a single session-opening path, and fork carries the |
| 216 | source thread's conversation. Background tasks are scoped to the session that |
| 217 | started them, opening a session no longer wipes every other session's |
| 218 | permission grants, and model selection is routed per session |
| 219 | |
| 220 | - **New sessions no longer carry the previous thread's history.** Opening a |
| 221 | new thread in Zed showed a `[Conversation summary]` from an earlier session. |
| 222 | The session handlers cleared the on-device engine but not the history a cloud |
| 223 | backend keeps for itself, and the startup routing to the cloud tier then |
| 224 | carried that history into the installed backend. A provider override had the |
| 225 | same leak. All session entry points now share a path that strips stale |
| 226 | history too, and unknown session ids are rejected instead of borrowing the |
| 227 | live thread's state |
| 228 | |
| 229 | - **Unparseable tool-call markup is hidden and retried, not shown as text.** |
| 230 | Some models write tool calls into the reply as text. Well-formed blocks were |
| 231 | already recovered and run, but a block that failed to parse or never closed |
| 232 | was printed to the editor as-is and stayed in history, so the model later |
| 233 | read back a call it had "made" with no result and began writing invented |
| 234 | `<function_results>`. The scanner now reports those blocks as malformed; the |
| 235 | backend drops them from the reply and history, and when the only tool call |
| 236 | was malformed the model gets one retry telling it the call didn't run. A |
| 237 | block that merely *mentions* a tool-call marker (a backticked `<tool_call>` or an |
| 238 | unclosed XTML `<|open|>tools`) is now kept as prose, so a reply explaining |
| 239 | the scanner no longer loses everything after the first marker. The |
| 240 | non-streamed path now strips broken blocks beside structured calls and runs |
| 241 | any inline calls that did parse, matching the streaming path |
| 242 | |
| 243 | - **The co-author trailer ends a conflicted merge commit.** Finishing a |
| 244 | conflicted merge with `git commit --no-edit` keeps git's `# Conflicts:` list |
| 245 | in the message, since no editor runs to strip it. When siGit Code then added |
| 246 | its trailer, the trailer went in above that list, so it was no longer the last |
| 247 | paragraph and GitHub didn't credit the co-author. The amend now drops the |
| 248 | leftover comment block and puts the trailer last. It also fixes a commit |
| 249 | that already has the trailer but still ends in that block |
| 250 | |
| 251 | ## 1.5.10 |
| 252 | |
| 253 | ### What changed |
| 254 | |
| 255 | - **Xcode's context no longer buries slash commands.** Xcode sends the user's |
| 256 | prompt as the last of several text blocks, with project context in the |
| 257 | blocks before it, so `/models` and friends sat in the middle of joined text |
| 258 | and were handed to the model instead of dispatching locally. Slash-command |
| 259 | parsing now searches the prompt's text blocks from the end, so a standalone |
| 260 | command in the final user block dispatches no matter what context the client |
| 261 | prepends |
| 262 | - **The nova tier is the default cloud engine.** When local inference is off |
| 263 | and no explicit provider override is set, the cloud tier now defaults to |
| 264 | `nova` (the `onde-nova` model) instead of the balanced tier, in both the |
| 265 | interactive and headless paths |
| 266 | |
| 267 | ### Fixed |
| 268 | |
| 269 | - **Malformed Chinese-model tool calls are handled end-to-end in ACP.** The |
| 270 | inline-call recovery that 1.5.9 added for Kimi K3's XTML protocol and GLM's |
| 271 | mis-tagged blocks only applied to the interactive and headless surfaces; |
| 272 | the ACP path never ran it, so an editor session still surfaced raw protocol |
| 273 | text and dropped the calls. Recovery now runs in the ACP prompt loop too, |
| 274 | covered by integration tests, and the tool names are checked against the |
| 275 | turn's offered tools before anything executes |
| 276 | - **Suppressed tool-call log spam is gone.** The guard that logs when a |
| 277 | structured call is dropped for arriving as forced text fired once per |
| 278 | streamed argument fragment — one malformed call could log a warning per |
| 279 | chunk. The check now fires once per turn with the count and names of what |
| 280 | was dropped, and the non-streaming path reports the same |
| 281 | - **A history-replay test no longer races on the process cwd.** One ACP test |
| 282 | built its expected path from `std::env::current_dir()` while other tests |
| 283 | briefly swap that process-global cwd, so on CI it could read a temp |
| 284 | directory mid-swap and compare a truncated title against an untruncated |
| 285 | expectation. It now uses a fixed path it never needed to derive |
| 286 | |
| 287 | ## 1.5.9 |
| 288 | |
| 289 | ### Fixed |
| 290 | |
| 291 | - **Kimi K3 tool calls no longer arrive as raw protocol text.** Kimi K3 renders |
| 292 | a call in Moonshot's XTML protocol — pipe-delimited open/sep/close tokens |
| 293 | wrapping named blocks — and when the serving stack doesn't parse that back |
| 294 | into structured tool calls, the whole block surfaced in the editor as literal |
| 295 | text and the turn ended as though the model had answered in prose. The |
| 296 | inline-call recovery now speaks that protocol alongside the legacy XML tags: |
| 297 | tools blocks are parsed into real calls (several per block, argument values |
| 298 | decoded and typed from the block's own type attribute or, when it is |
| 299 | missing, the turn's tool schemas), response blocks are unwrapped so their |
| 300 | text still renders, and think blocks are dropped as private reasoning rather |
| 301 | than shown. The streaming scanner watches all the opening markers, so a |
| 302 | block split across chunk boundaries still recovers |
| 303 | - **GLM's mis-tagged calls recover too.** GLM sometimes precedes the legacy |
| 304 | block's first argument key with another tool-call opening tag instead of the |
| 305 | arg-key opening tag the format calls for, and the recovery rejected the |
| 306 | whole block when it did — the call surfaced as text and whatever it was |
| 307 | trying to do was dropped. The parser now accepts that alias for the first |
| 308 | argument only — later arguments stay strict, so text that merely resembles a |
| 309 | call cannot be recovered as one — in both the whole-blob and streaming |
| 310 | paths, and the scanner tolerates the malformed marker split across chunk |
| 311 | boundaries. Recovery in both protocols also checks the call's name against |
| 312 | the tools actually offered in the turn: a tag naming a tool that was never |
| 313 | in the turn's spec stays on screen instead of being executed |
| 314 | |
| 315 | ## 1.5.8 |
| 316 | |
| 317 | ### What changed |
| 318 | |
| 319 | - **Editor panels can switch permission mode without a slash command.** ACP |
| 320 | clients now get a Permissions selector next to the model controls with |
| 321 | Manual, Auto, and Plan choices for the current session. Manual keeps the |
| 322 | existing approval prompts, Auto lets mutating tools run unattended while |
| 323 | still respecting explicit deny rules in `settings.toml`, and Plan keeps the |
| 324 | agent in research-only mode. The selector follows `/plan` and `/clear`, and |
| 325 | it is deliberately session-scoped so a risky Auto choice does not persist |
| 326 | into the next task |
| 327 | - **Tool calls in the editor are worth opening now.** Zed only drew the |
| 328 | disclosure arrow on the handful of cards siGit set `content` on — the model |
| 329 | download and switch spinners — because everything else carried nothing but |
| 330 | `rawInput` and `rawOutput`, fields ACP gives clients no display guidance for. |
| 331 | Every tool call now gets a fenced content block: the pretty-printed arguments |
| 332 | while it runs, then the tool's output once it finishes, with a `(no output)` |
| 333 | placeholder for a silent command like `git add`. Cards are titled |
| 334 | `<tool> · <arg>` rather than the bare tool name, path-bearing tools set |
| 335 | `locations` so the editor can follow along, and a replayed session gets the |
| 336 | same treatment as a live one |
| 337 | - **The context window is visible before compaction fires.** Both model pickers |
| 338 | show each model's window, and the TUI title bar has a gauge for how much of |
| 339 | it the conversation is using. Cloud tiers report their own window instead of |
| 340 | the compaction budget — the budget is when siGit Code summarizes history, not |
| 341 | how much the model can hold, and labelling one with the other understated the |
| 342 | window by an order of magnitude |
| 343 | - **`write_todos` renders as a plan, not a tool card.** Zed and other clients |
| 344 | have real progress UI for `session/update` plans, so the model's todo list |
| 345 | goes there |
| 346 | - **Picker changes read as status rather than chat.** Switching model or |
| 347 | inference backend is UI state, so it renders as a completed think-kind tool |
| 348 | call. The sign-in prompt stays an assistant message, since it needs the user |
| 349 | to act on it |
| 350 | |
| 351 | ### Fixed |
| 352 | |
| 353 | - **A reopened thread comes back with its history.** Clicking a saved thread in |
| 354 | Zed sends `session/load`, and the client draws the thread purely from the |
| 355 | `session/update` notifications the agent streams while that request is in |
| 356 | flight. siGit restored the saved history into the backend, which is what |
| 357 | makes the model remember, but sent the client nothing — so the thread opened |
| 358 | empty and looked like a brand new conversation. The snapshot is now turned |
| 359 | into updates before it is restored: user and assistant text as message chunks |
| 360 | with reasoning stripped, each tool call completed with its result folded in, |
| 361 | and `write_todos` as a plan the way it renders live. System messages stay |
| 362 | out, since they seeded the model and were never on screen |
| 363 | - **Compaction no longer fails in every session that ran a tool.** |
| 364 | `compact_history` asked for the summary through `complete(None, None)`, which |
| 365 | sends no tools array but left the live history in place. That history is |
| 366 | thick with assistant `tool_calls` and `role: "tool"` messages, and an |
| 367 | endpoint handed tool shapes with no schema to check them against rejects the |
| 368 | request — Anthropic answers 400. So compaction failed on every attempt in any |
| 369 | session that had run a single tool, however small the history was, and then |
| 370 | retried on every prompt and tool round while that history kept growing. The |
| 371 | conversation now goes as a flattened transcript in one user message, which |
| 372 | keeps what the summary needs and drops the shapes that only mean anything |
| 373 | next to a tool schema |
| 374 | - **A tool call emitted as text is no longer dropped.** Qwen 3, GLM and |
| 375 | DeepSeek write a call as `<tool_call>NAME<arg_key>…` in their chat template |
| 376 | and rely on the serving stack to parse it back into `tool_calls`. When that |
| 377 | doesn't happen the tag arrives as ordinary content, so it was rendered |
| 378 | verbatim in the editor and the turn ended as though the model had chosen to |
| 379 | answer in prose. Both the streaming and non-streaming paths now scan content |
| 380 | for those blocks and turn well-formed ones back into real calls, typing |
| 381 | argument values from the turn's own tool schemas. The streaming scanner holds |
| 382 | back only enough text to catch a tag straddling a chunk boundary, so ordinary |
| 383 | answers still stream token by token. A block that doesn't match the expected |
| 384 | shape is left in the text untouched: reissuing a `run_command` is cheap, but |
| 385 | guessing wrong at a half-parsed `edit_file` would write the wrong change to a |
| 386 | file |
| 387 | - **Tool-call content survives awkward output.** Whitespace-only output is |
| 388 | preserved rather than collapsed, malformed arguments no longer get a |
| 389 | misleading JSON fence, and fence language identifiers are sanitized |
| 390 | |
| 391 | ## 1.5.7 |
| 392 | |
| 393 | ### What changed |
| 394 | |
| 395 | - **`@smbcloud/sigit` gets releases again.** The npm scope moved to |
| 396 | `@getsigit` in 1.5.5 and the old package was left sitting on the registry at |
| 397 | 1.5.2, so an install made before the rename went quiet — `npm update` had |
| 398 | nothing to give it and nothing said why. All seven packages now publish under |
| 399 | both scopes from the same build, so `@smbcloud/sigit` is a full install again |
| 400 | rather than a stub, with its own platform binaries and no dependency on the |
| 401 | new scope. It prints a line on stderr saying where the package moved to; |
| 402 | `SIGIT_SUPPRESS_SCOPE_NOTICE=1` turns that off. This is a migration path, not |
| 403 | a second home: `@getsigit/sigit` is what the docs, the Homebrew tap, and the |
| 404 | ACP registry entry point at, and it is the name to move to |
| 405 | - **Multi-root projects now work in the editor.** When a client opens several |
| 406 | directories in one project, ACP sends the extra ones as |
| 407 | `additionalDirectories` — but only to an agent that says it wants them, which |
| 408 | siGit never did, so Zed kept the first root and showed a banner saying |
| 409 | multi-root workspaces were unsupported. The capability is now advertised at |
| 410 | `initialize`, and the directories that arrive are no longer logged and thrown |
| 411 | away. All the roots are now part of the session: the model is told about each |
| 412 | one, every root's `AGENTS.md` / `CLAUDE.md` is loaded, and skills, slash |
| 413 | commands, and subagent types are discovered from all of them (primary root |
| 414 | first, so it still wins name collisions). `/status` lists the roots when |
| 415 | there is more than one, and headless runs take the same thing as repeatable |
| 416 | `--add-dir <dir>` flags. MCP servers are the exception: discovery happens |
| 417 | once at startup, before a session exists, so a second root's `.sigit/mcp.toml` |
| 418 | is not picked up |
| 419 | |
| 420 | ### Fixed |
| 421 | |
| 422 | - **A shell command can no longer wedge the editor session.** Tool commands |
| 423 | inherited siGit's own stdin, which in ACP mode is the JSON-RPC pipe from the |
| 424 | editor. A command that read stdin — a signing passphrase prompt, a pager, a |
| 425 | `git` credential ask — blocked on it and consumed the client's next request |
| 426 | out of the pipe, so nothing typed afterwards ever reached the agent and the |
| 427 | session stayed dead past the command timeout. Commands, hooks, and the |
| 428 | co-author `git` helpers now run with stdin closed, so a command that wants |
| 429 | input gets EOF and reports an error instead |
| 430 | - **A command that prints a lot no longer stalls for two minutes.** |
| 431 | `run_command` waited for the command to exit before reading its output, so |
| 432 | anything past the pipe buffer (a build, a verbose test run) blocked writing |
| 433 | while siGit blocked waiting, until the 120-second timeout killed it. Output |
| 434 | is now drained while the command runs |
| 435 | - **The command timeout now stops the whole command.** It killed only the |
| 436 | shell, leaving anything that shell had started running and unreaped; it now |
| 437 | kills the process group |
| 438 | - **A refused turn now shows the endpoint's own message.** siGit pasted the |
| 439 | status line and the raw JSON body into the editor's error banner, so a |
| 440 | billing or allowance message arrived wrapped in |
| 441 | `endpoint returned 429 Too Many Requests: {"error":{"message":…`. The message |
| 442 | the endpoint wrote is what the banner shows now; the status is only used when |
| 443 | there is no message to show |
| 444 | - **An error that arrives mid-stream is no longer silent.** An endpoint that |
| 445 | fails after the response is already open reports it as a frame in the stream. |
| 446 | That frame carries no `choices`, so siGit parsed it as an empty chunk and |
| 447 | skipped it, and the turn ended as though the model had answered with nothing |
| 448 | |
| 449 | ## 1.5.6 |
| 450 | |
| 451 | ### What changed |
| 452 | |
| 453 | - **Switching models mid-conversation no longer restarts it.** Both switching |
| 454 | to a local GGUF model and picking a different cloud tier now carry the live |
| 455 | conversation history across, repairing any half-finished tool call so |
| 456 | strict OpenAI-compatible endpoints don't reject the session |
| 457 | - **Long-running tools now show progress in ACP clients.** Synchronous tools |
| 458 | (shell commands, file operations, `read_website`, ...) run on a blocking |
| 459 | thread pool instead of the ACP connection's own task, so a slow command's |
| 460 | `in_progress` update reaches the client — and Zed's spinner — while the |
| 461 | command is still running instead of arriving with the result |
| 462 | - **Text from consecutive tool rounds no longer runs together.** ACP and |
| 463 | headless clients concatenate consecutive message chunks, so a reply that |
| 464 | continued after a tool call used to glue onto the previous round's last |
| 465 | sentence with no space. A blank line now opens the next round's text |
| 466 | - **New onde-cloud model tiers.** The model picker (`/models` in the TUI, the |
| 467 | config panel in editors) now offers five additional siGit Code Cloud tiers — |
| 468 | `flux`, `apex`, `aura`, `orbit`, and `nova` — alongside the existing Fast, |
| 469 | Balanced, Large, Mini, Air, Pro, and KKK options. The tier list mirrors |
| 470 | onde-cloud's router catalogue, so all three sides (the picker, the router, |
| 471 | and the cloud catalogue) have to be updated together when a tier is added |
| 472 | - **MCP Registry listing moved to `getsigit/si`.** The `server.json` manifest |
| 473 | and its `release-mcp-registry.yml` publish workflow now live in the |
| 474 | [`getsigit/si`](https://github.com/getsigit/si) repo alongside the si CLI's |
| 475 | other code, since the registry entry describes the si platform rather than |
| 476 | the coding agent |
| 477 | |
| 478 | ## 1.5.5 |
| 479 | |
| 480 | A distribution release. siGit Code itself is unchanged. What moved is how it |
| 481 | reaches you on npm and on Windows. |
| 482 | |
| 483 | ### What changed |
| 484 | |
| 485 | - **The npm package is now `@getsigit/sigit`.** The six platform packages moved |
| 486 | with it. `@smbcloud/sigit` stays on the registry but stops receiving updates, |
| 487 | so upgrading means switching names: |
| 488 | `npm uninstall -g @smbcloud/sigit && npm install -g @getsigit/sigit`. The old |
| 489 | package had been stuck at 1.5.2, so this picks up 1.5.3 and 1.5.4 as well. |
| 490 | - **npm publishes over OIDC.** Every `@getsigit/*` package has a trusted |
| 491 | publisher pointing at the release workflow, so no npm token is stored in the |
| 492 | repository. The release workflow moves to Node 22, which trusted publishing |
| 493 | requires. |
| 494 | - **winget releases actually go out.** The workflow could only update a package |
| 495 | already present in `microsoft/winget-pkgs`, and siGit Code had never been |
| 496 | submitted there, so every dispatch failed. It now submits the package the |
| 497 | first time and updates it on later releases. The identifier is |
| 498 | `getSigit.siGitCode`. |
| 499 | |
| 500 | ## 1.5.4 |
| 501 | |
| 502 | - **CI**: nfpm config expanded to include package version and binary path |
| 503 | |
| 504 | ## 1.5.3 |
| 505 | |
| 506 | Adds browser-based sign-in, expands distribution channels to Windows (winget, |
| 507 | Scoop), Linux (AUR, deb, rpm), and .NET (NuGet), gives ACP clients live |
| 508 | visibility into tool activity, adds the KKK and Moonshot AI cloud tiers, and |
| 509 | fixes the co-authored-by trailer email. |
| 510 | |
| 511 | ### What changed |
| 512 | |
| 513 | - **Browser sign-in:** `sigit login` now opens a browser OAuth flow (PKCE S256 |
| 514 | against the siGit Code Cloud authorization server) so you can sign in without |
| 515 | a password. A loopback listener catches the redirect automatically; a |
| 516 | paste-back fallback handles environments where a loopback isn't reachable. |
| 517 | `--paste` forces the paste path, `--password` keeps the old email/password |
| 518 | prompt. Zed's "Sign in to siGit Code" button uses the loopback path via ACP |
| 519 | `authenticate` |
| 520 | - **New release channels:** siGit Code is now published to winget |
| 521 | (`getsigit.siGitCode`), Scoop (`getsigit/scoop-bucket`), the AUR |
| 522 | (`sigit-bin`), and as `.deb`/`.rpm` packages alongside the existing |
| 523 | Homebrew, npm, PyPI, crates.io, and NuGet channels |
| 524 | - **NuGet .NET tool:** `dotnet tool install --global SiGit.Code` now works on |
| 525 | Windows, macOS, and Linux — the package bundles all six platform binaries and |
| 526 | a managed shim that execs the right one, leaving stdin/stdout/stderr |
| 527 | unredirected so TUI vs ACP mode detection still works |
| 528 | - **New cloud tiers:** the model picker (`/models` in the TUI, the config |
| 529 | panel in Zed) now offers the `onde-kkk` (KKK) and Moonshot AI (`oke`) tiers |
| 530 | alongside the existing Fast, Balanced, Large, Mini, Air, and Pro options |
| 531 | - **ACP tool visibility:** the agent loop now emits `ToolCall(InProgress)` |
| 532 | before each tool runs and `ToolCallUpdate(Completed/Failed)` after it |
| 533 | returns, so clients like Zed gain live visibility into tool activity between |
| 534 | inference rounds. `tool_choice: "auto"` is also sent explicitly whenever |
| 535 | tools are present, fixing models that describe actions in prose rather than |
| 536 | issuing a tool call when the field is absent |
| 537 | - **Malformed tool argument logging:** invalid tool argument JSON is now logged |
| 538 | at three sites (TUI pretty-printer, ACP tool-call event, permission request) |
| 539 | instead of silently falling back to a string value, making malformed payloads |
| 540 | visible in logs while preserving backward-compatible behaviour |
| 541 | - **Co-authored-by trailer fix:** the `Co-Authored-By` trailer email was |
| 542 | updated to `noreply@sigit.si` (platform-neutral); the commit attribution |
| 543 | check was tightened to use idiomatic ownership |
| 544 | - **NuGet trusted publishing:** the NuGet release workflow now exchanges a |
| 545 | GitHub OIDC token for a short-lived NuGet API key (via `NuGet/login`) instead |
| 546 | of relying on a long-lived `NUGET_API_KEY` secret, so there is no stored |
| 547 | credential to rotate or leak |
| 548 | - **AUR dispatch temporarily disabled:** the AUR release workflow is no longer |
| 549 | dispatched from `release-github` while new AUR account registration is |
| 550 | closed; the `sigit-bin` channel returns once registration reopens |
| 551 | - Legal and branding copy updated |
| 552 | |
| 553 | ## 1.5.2 |
| 554 | |
| 555 | Brings the latest siGit Code Cloud tiers to the picker and aligns the MCP |
| 556 | registry metadata with the server release. |
| 557 | |
| 558 | ### What changed |
| 559 | |
| 560 | - `/models` now lists the Pro, Air, and Mini siGit Code Cloud tiers alongside |
| 561 | Fast, Balanced, and Large |
| 562 | - Updated the MCP registry manifest to version 1.2.5, matching the siGit Code |
| 563 | Cloud server release |
| 564 | - Updated the Agent Client Protocol SDK to the latest v1 release |
| 565 | |
| 566 | ## 1.5.1 |
| 567 | |
| 568 | Makes siGit Code work as an Xcode custom agent, and updates the Onde SDK. |
| 569 | |
| 570 | ### What changed |
| 571 | |
| 572 | - Xcode can now run siGit Code as a custom agent. Point it at the binary with |
| 573 | `--acp` as the argument, and that explicit mode loads the selected on-device |
| 574 | model on the first prompt, since Xcode's chat has no equivalent of `/load`. |
| 575 | The README covers the setup, including wiring up `xcrun mcpbridge` in |
| 576 | `mcp.toml` so the agent can use Xcode's build, test, and project tools |
| 577 | - MCP calls to the `xcode` server time out after 30 seconds instead of 120, so |
| 578 | a request Xcode cannot service no longer leaves the prompt looking busy for |
| 579 | two minutes. String JSON-RPC ids from the bridge are handled too |
| 580 | - The agent stops repeating itself: a tool call made three times with identical |
| 581 | arguments now forces a text reply instead of looping |
| 582 | - Onde SDK bumped to 1.2.2 |
| 583 | - The registry listing in `server.json` matches what sigit.si publishes |
| 584 | |
| 585 | ## 1.5.0 |
| 586 | |
| 587 | Opens the agent up to user extension: lifecycle hooks, custom slash commands, |
| 588 | and configurable subagent types. Also adds web search, a Repo tab in the TUI, |
| 589 | and a baked-in smbCloud MCP server. |
| 590 | |
| 591 | ### What changed |
| 592 | |
| 593 | - Hooks let you run shell commands at three points in the agent's lifecycle: |
| 594 | `session_start`, `pre_tool_use`, and `post_tool_use`, configured under |
| 595 | `[hooks]` in `settings.toml`. Commands get context through variable |
| 596 | substitution (`{cwd}`, `{tool_name}`, `{tool_result_len}`) and run in the |
| 597 | session working directory. A hook that fails is logged and the session |
| 598 | continues; a hook that hangs is killed on a timeout, along with its whole |
| 599 | process group |
| 600 | - User-defined slash commands: drop a Markdown file in `.sigit/commands/` or |
| 601 | `.claude/commands/` (or the personal `$SIGIT_CONFIG_DIR/commands/` and |
| 602 | `~/.claude/commands/`) with optional `description` and `argument-hint` |
| 603 | frontmatter, and the body becomes a prompt template. `$ARGUMENTS` takes the |
| 604 | whole argument string and `$1`..`$9` the positional words. A subdirectory |
| 605 | namespaces the command with `:`, so `.sigit/commands/git/commit.md` becomes |
| 606 | `/git:commit`. They run as ordinary agent turns through the usual tools and |
| 607 | permission checks, and are advertised to ACP clients like Zed. `/commands` |
| 608 | lists what was discovered |
| 609 | - Configurable subagent types for the `task` tool: a Markdown file in |
| 610 | `.sigit/agents/` or `.claude/agents/` with `name`, `description`, and an |
| 611 | optional `tools:` allow-list, whose body becomes that subagent's system |
| 612 | prompt. Pass its name as `subagent_type` to swap the prompt in. The |
| 613 | `tools:` list can only narrow the subagent's read-only ceiling, never widen |
| 614 | it, so a config file cannot grant itself `edit_file` or `run_command` and |
| 615 | route around the permission system. `/agents` lists the discovered types |
| 616 | - New `web_search` tool, backed by the Brave-Search-backed search on siGit |
| 617 | Code Cloud's MCP server. It is offered only when you are signed in, and it |
| 618 | is classified read-only, so searching never triggers a permission prompt |
| 619 | - The TUI gains a Repo tab, shown when the session's `origin` remote points at |
| 620 | the sigit.si host. It lists issues and pull requests fetched through the |
| 621 | official MCP server: Up and Down select, Enter opens a scrollable detail, |
| 622 | `i`, `p`, Left and Right switch sections, `r` refreshes. The tab is hidden |
| 623 | and skipped in the cycle for any other remote |
| 624 | - The smbCloud CLI's stdio MCP server (`smb --mcp`) is now baked in, so |
| 625 | smbCloud project and deployment tools work with no `mcp.toml` setup. It is |
| 626 | added only when the `smb` binary is on `PATH`, its read-only tools (`me`, |
| 627 | `deployments`, `project_list`, `project_show`) skip permission prompts, and |
| 628 | you can opt out with `smbcloud = false` in `mcp.toml` or |
| 629 | `SIGIT_MCP_SMBCLOUD=off` |
| 630 | - siGit Code Cloud's MCP server is now listed in the public MCP Registry as |
| 631 | `si.sigit/sigit`, published from `server.json` at the repository root |
| 632 | |
| 633 | ### Fixes |
| 634 | |
| 635 | - An explicit `deny` rule now applies to read-only first-party tools instead |
| 636 | of being skipped |
| 637 | - A subagent type whose `tools:` list resolves to an empty set is rejected |
| 638 | rather than producing a subagent with no tools |
| 639 | - Command templates render in a single substitution pass, so an argument that |
| 640 | contains something like `$1` is no longer re-substituted |
| 641 | - Frontmatter is stripped with the same leniency it is parsed with |
| 642 | - The Repo tab's detail view no longer shows stale data after a refresh |
| 643 | |
| 644 | ## 1.4.1 |
| 645 | |
| 646 | Two small fixes: correct co-author attribution and a Homebrew tap fix. |
| 647 | |
| 648 | ### What changed |
| 649 | |
| 650 | - The `Co-Authored-By` trailer siGit Code adds to commits now uses the GitHub |
| 651 | noreply address for the [sigitc](https://github.com/sigitc) account instead |
| 652 | of `sigit@sigit.si`, so GitHub reliably attributes co-authored commits to |
| 653 | the siGit Code profile |
| 654 | - Fixed the Homebrew tap install docs to trust the tap with `brew trust` |
| 655 | instead of a `brew tap --force` flag |
| 656 | |
| 657 | ## 1.4.0 |
| 658 | |
| 659 | Adds a headless one-shot mode, fine-grained permission rules, stdio transport |
| 660 | for MCP servers, an `/init` command, and a set of TUI upgrades: tabs, a live |
| 661 | thinking display, and collapsible tool calls. |
| 662 | |
| 663 | ### What changed |
| 664 | |
| 665 | - 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` |
| 666 | - 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 |
| 667 | - 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 |
| 668 | - 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 |
| 669 | - 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 |
| 670 | - 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 |
| 671 | - 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 |
| 672 | - When `AGENTS.md` and `CLAUDE.md` sit in the same directory, the instructions loader now prefers `AGENTS.md`, so shared content is injected once |
| 673 | |
| 674 | ## 1.3.2 |
| 675 | |
| 676 | Adds a tool permission system with plan mode, durable sessions with context |
| 677 | compaction, background command execution, a subagent research tool, and commit |
| 678 | co-author attribution. |
| 679 | |
| 680 | ### What changed |
| 681 | |
| 682 | - 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 |
| 683 | - 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 |
| 684 | - 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 |
| 685 | - 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 |
| 686 | - `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` |
| 687 | - 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 |
| 688 | - 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 |
| 689 | - ACP mode now honors the `OPENAI_BASE_URL`/`OPENAI_API_KEY` provider override at startup, matching the interactive client |
| 690 | |
| 691 | ## 1.3.1 |
| 692 | |
| 693 | Adds [Model Context Protocol](https://modelcontextprotocol.io) (MCP) client |
| 694 | support with the official siGit Code MCP server baked in, a set of agent tools |
| 695 | that close parity gaps in the tool layer, and refreshed branding and licensing. |
| 696 | |
| 697 | ### What changed |
| 698 | |
| 699 | - 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 |
| 700 | - 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 |
| 701 | - 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 |
| 702 | - 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 |
| 703 | - 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 |
| 704 | - Added a `/mcp` slash command (TUI and ACP) that lists configured servers, their connection status, and the tools each exposes |
| 705 | - Disable MCP entirely with `SIGIT_MCP=off`, or just the official server with `SIGIT_MCP_OFFICIAL=off` |
| 706 | - 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`) |
| 707 | - `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 |
| 708 | - `search_files` gained a `file_glob` filter and a `max_results` cap (default 50, hard-capped at 1000) that also bounds the directory walk |
| 709 | - Refreshed branding and legal: updated `LICENSE`, `README`, and the npm/PyPI package descriptions |
| 710 | |
| 711 | ## 1.3.0 |
| 712 | |
| 713 | Adds a Local Inference on/off toggle, the open [Agent Skills](https://agentskills.io) |
| 714 | format, and support for project instruction files (`AGENTS.md` and the like). |
| 715 | |
| 716 | ### What changed |
| 717 | |
| 718 | - 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` |
| 719 | - 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 |
| 720 | - `/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 |
| 721 | - Discovers Agent Skills (folders with a `SKILL.md`) from `.sigit/skills/` and `.claude/skills/` in the project, `~/.config/sigit/skills/`, and `~/.claude/skills/` |
| 722 | - 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 |
| 723 | - Added a `/skills` slash command (TUI and ACP) that lists the discovered skills |
| 724 | - 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 |
| 725 | - Nested instruction files are ordered outermost-first so the closest, most specific file takes precedence; the scan never reads above the repository root |
| 726 | - 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. |
| 727 | |
| 728 | ## 1.2.2 |
| 729 | |
| 730 | Streams assistant tokens as they arrive, on-device and over the cloud. |
| 731 | |
| 732 | ### What changed |
| 733 | |
| 734 | - Streamed assistant tokens live in the TUI and ACP sessions, both on-device and through siGit Code Cloud |
| 735 | - 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 |
| 736 | - Fixed the TUI so the latest message stays visible in long chats |
| 737 | - Put the cloud model-switch confirmation on its own line in ACP |
| 738 | |
| 739 | ## 1.2.1 |
| 740 | |
| 741 | Stabilizes the Zed/ACP integration and finishes the cloud-tier wiring on top of 1.2.0. |
| 742 | |
| 743 | ### What changed |
| 744 | |
| 745 | - Fixed a Zed crash by keeping model-picker labels ASCII in the ACP model selector |
| 746 | - Wired ACP auth, cloud tiers, and slash commands into the Zed panel, including a `/reload` command to re-sync session state in place |
| 747 | - Fixed the TUI so the loaded-model checkmark appears once a download completes |
| 748 | - Synced bundled agent skills with the current code and added `CLAUDE.md` |
| 749 | |
| 750 | ## 1.2.0 |
| 751 | |
| 752 | Adds siGit Code Cloud — a hosted inference tier alongside on-device models. |
| 753 | |
| 754 | ### What changed |
| 755 | |
| 756 | - Added siGit Code Cloud with cloud-tier routing, pointed at `sigit.si` |
| 757 | - Added account management slash commands and surfaced cloud tiers in `/models` |
| 758 | - Carried forward from 1.1.0: ACP SDK v0.13, refreshed dependencies and branding |
| 759 | |
| 760 | ## 1.1.0 |
| 761 | |
| 762 | Bumps the ACP SDK to v0.13 and pulls in updated dependencies. |
| 763 | |
| 764 | ### What changed |
| 765 | |
| 766 | - Updated `agent-client-protocol` from v0.11 to v0.13 |
| 767 | - Updated `onde` to 1.1.2 |
| 768 | - Refreshed branding and skill metadata |
| 769 | |
| 770 | ## 1.0.4 |
| 771 | |
| 772 | This release tightens up the terminal experience and finishes a few release-facing cleanup items. |
| 773 | |
| 774 | ### What changed |
| 775 | |
| 776 | - Added bold rich-text rendering in the TUI for assistant replies, so `**text**` now displays with terminal styling instead of raw markdown markers |
| 777 | - Refreshed the bundled skill metadata to follow the current Agent Skills `SKILL.md` format |
| 778 | - Synced the crate release metadata for the `1.0.4` cut |
| 779 | |
| 780 | ## 1.0.3 |
| 781 | |
| 782 | This is the cleanup release for the editor-side startup problems. |
| 783 | |
| 784 | ### What changed |
| 785 | |
| 786 | - Fixed ACP sessions failing on the first real prompt because the server claimed the model was ready before anything had actually been loaded |
| 787 | - Changed ACP startup so the default model loads lazily on the first non-slash prompt instead of pretending it is already in memory |
| 788 | - Kept `initialize` and `session/new` lightweight while still sending proper progress updates once model loading begins |
| 789 | - Updated the Onde integration to `1.0.0` |
| 790 | - Removed a few dependencies we were no longer using |
| 791 | |
| 792 | ## 1.0.2 |
| 793 | |
| 794 | 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. |
| 795 | |
| 796 | ### What changed |
| 797 | |
| 798 | - Delayed model loading in ACP mode so startup diagnostics would not leak into protocol stdout during the auth handshake |
| 799 | - Tightened up the ACP startup path for editor integrations |
| 800 | - Refreshed some README wording while cutting `1.0.2` |
| 801 | |
| 802 | ## 1.0.1 |
| 803 | |
| 804 | The first patch after `1.0.0` was mostly about making model loading and model switching feel less opaque. |
| 805 | |
| 806 | ### What changed |
| 807 | |
| 808 | - Added ToolCall-based progress UI for startup model loading and downloading |
| 809 | - Improved model-switch progress reporting in ACP clients |
| 810 | - Fixed model-load error handling so failed switches did not leave the UI in a weird state |
| 811 | - Cleaned up a few status messages and docs while the release was going out |
| 812 | |
| 813 | ## 1.0.0 (2026) |
| 814 | |
| 815 | 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. |
| 816 | |
| 817 | ### What this release is |
| 818 | |
| 819 | 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. |
| 820 | |
| 821 | You can install it with Cargo, pip, npm, or Homebrew and use it like any other tool on your machine. |
| 822 | |
| 823 | ### What shipped in 1.0 |
| 824 | |
| 825 | #### Editor integration |
| 826 | |
| 827 | This is the core of the project. |
| 828 | |
| 829 | 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. |
| 830 | |
| 831 | #### Terminal UI |
| 832 | |
| 833 | 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. |
| 834 | |
| 835 | It runs on macOS and Linux. Windows gets ACP and editor mode for now. The Windows terminal UI is still unfinished. |
| 836 | |
| 837 | #### Tool calling |
| 838 | |
| 839 | 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. |
| 840 | |
| 841 | Available tools: |
| 842 | |
| 843 | - `read_file` / `write_file` / `delete_file` |
| 844 | - `list_directory` / `search_files` |
| 845 | - `run_command`, with an optional working directory |
| 846 | - `read_website`, which fetches a URL and strips it down to readable text |
| 847 | |
| 848 | The model can call a tool, inspect the result, and keep going until it has a real answer. |
| 849 | |
| 850 | #### Model support |
| 851 | |
| 852 | The model list ended up wider than we expected for 1.0: |
| 853 | |
| 854 | - Qwen 3 1.7B, 4B, 8B, and 14B |
| 855 | - Qwen 2.5 1.5B and 3B |
| 856 | - Qwen 2.5 Coder 1.5B, 3B, and 7B |
| 857 | - DeepSeek Coder 6.7B |
| 858 | |
| 859 | They are all GGUF models and they all come from Hugging Face on first run. |
| 860 | |
| 861 | 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. |
| 862 | |
| 863 | 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. |
| 864 | |
| 865 | #### Model picker |
| 866 | |
| 867 | The model picker shows: |
| 868 | |
| 869 | - what is already cached locally |
| 870 | - what can be downloaded |
| 871 | - which models support tool calling |
| 872 | - whether the local cache looks healthy |
| 873 | |
| 874 | 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. |
| 875 | |
| 876 | #### smbCloud context |
| 877 | |
| 878 | 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. |
| 879 | |
| 880 | Outside smbCloud, it backs off and behaves like a normal coding agent. |
| 881 | |
| 882 | #### Distribution |
| 883 | |
| 884 | Distribution took an unreasonable amount of time, honestly. |
| 885 | |
| 886 | 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: |
| 887 | |
| 888 | - `cargo install sigit` |
| 889 | - `pip install sigit-code` |
| 890 | - `npm install -g @smbcloud/sigit` |
| 891 | - `brew install sigit` |
| 892 | |
| 893 | Getting that whole pipeline to behave across CI, crates.io, PyPI, npm, and Homebrew was basically its own project. |
| 894 | |
| 895 | ### What still does not work |
| 896 | |
| 897 | The Windows terminal UI is still missing. |
| 898 | |
| 899 | 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. |
| 900 | |
| 901 | ### Changes since 0.1.2 |
| 902 | |
| 903 | - Added Qwen 3 14B support |
| 904 | - Added Qwen 3 `<think>` block parsing and separate rendering in the TUI |
| 905 | - Moved all TUI code into `#[cfg(unix)]`, which fixed a pile of dead-code errors on Windows CI |
| 906 | - Added live download progress during model switches, including cancellation with Ctrl+C |
| 907 | - Added model download and loading progress in the Zed agent config panel |
| 908 | - Added an animated spinner during model switching |
| 909 | - Added Qwen 2.5 Coder 7B |
| 910 | - Added downloadable models to the picker, not just locally cached ones |
| 911 | - Made model selection persist across restarts |
| 912 | - Added session working-directory support |
| 913 | - Moved model picker logic into a platform-independent module so Windows can compile without the TUI |
| 914 | - Added the `/models N` shortcut for picking a model by number |
| 915 | - Added the `read_website` tool |
| 916 | - Improved `read_file` handling and empty-reply detection |
| 917 | - Added async tool execution |
| 918 | - Fixed CI cross-compilation for macOS, iOS, Linux, and Windows |
| 919 | - Added npm, PyPI, and Homebrew distribution |
| 920 | |
| 921 | --- |
| 922 | |
| 923 | *© 2026 PT Sigit Mitra Bangun ([siGit Code & Deploy](https://sigit.si)), distributed by [Splitfire AB](https://5mb.app).* |