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).*