sigit-code 0.1.1__tar.gz → 1.0.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (43) hide show
  1. sigit_code-1.0.0/.agents/skills/tool-calling/SKILL.md +290 -0
  2. {sigit_code-0.1.1 → sigit_code-1.0.0}/.github/workflows/ci.yml +4 -1
  3. {sigit_code-0.1.1 → sigit_code-1.0.0}/.github/workflows/release-homebrew.yml +1 -1
  4. sigit_code-1.0.0/CHANGELOG.md +70 -0
  5. {sigit_code-0.1.1 → sigit_code-1.0.0}/Cargo.lock +17 -16
  6. {sigit_code-0.1.1 → sigit_code-1.0.0}/Cargo.toml +5 -4
  7. {sigit_code-0.1.1 → sigit_code-1.0.0}/PKG-INFO +13 -19
  8. sigit_code-1.0.0/README.md +111 -0
  9. sigit_code-1.0.0/npm/README.md.tmpl +62 -0
  10. sigit_code-1.0.0/npm/sigit/README.md +106 -0
  11. {sigit_code-0.1.1 → sigit_code-1.0.0}/pypi/README.md +12 -18
  12. sigit_code-1.0.0/src/chat.rs +1713 -0
  13. sigit_code-1.0.0/src/main.rs +1691 -0
  14. sigit_code-1.0.0/src/models.rs +196 -0
  15. sigit_code-1.0.0/src/setup.rs +750 -0
  16. {sigit_code-0.1.1 → sigit_code-1.0.0}/src/tools.rs +472 -76
  17. sigit_code-0.1.1/.agents/skills/tool-calling/SKILL.md +0 -283
  18. sigit_code-0.1.1/README.md +0 -55
  19. sigit_code-0.1.1/npm/README.md.tmpl +0 -22
  20. sigit_code-0.1.1/npm/sigit/README.md +0 -85
  21. sigit_code-0.1.1/src/chat.rs +0 -1162
  22. sigit_code-0.1.1/src/main.rs +0 -527
  23. sigit_code-0.1.1/src/setup.rs +0 -89
  24. {sigit_code-0.1.1 → sigit_code-1.0.0}/.agents/AGENTS.md +0 -0
  25. {sigit_code-0.1.1 → sigit_code-1.0.0}/.agents/skills/agent-client-protocol/SKILL.md +0 -0
  26. {sigit_code-0.1.1 → sigit_code-1.0.0}/.agents/skills/ai-assisted-coding/SKILL.md +0 -0
  27. {sigit_code-0.1.1 → sigit_code-1.0.0}/.github/workflows/release-github.yml +0 -0
  28. {sigit_code-0.1.1 → sigit_code-1.0.0}/.github/workflows/release-npm.yml +0 -0
  29. {sigit_code-0.1.1 → sigit_code-1.0.0}/.github/workflows/release-pypi.yml +0 -0
  30. {sigit_code-0.1.1 → sigit_code-1.0.0}/.gitignore +0 -0
  31. {sigit_code-0.1.1 → sigit_code-1.0.0}/.nvmrc +0 -0
  32. {sigit_code-0.1.1 → sigit_code-1.0.0}/LICENSE +0 -0
  33. {sigit_code-0.1.1 → sigit_code-1.0.0}/npm/package-main.json.tmpl +0 -0
  34. {sigit_code-0.1.1 → sigit_code-1.0.0}/npm/package.json.tmpl +0 -0
  35. {sigit_code-0.1.1 → sigit_code-1.0.0}/npm/scripts/render-main-package.cjs +0 -0
  36. {sigit_code-0.1.1 → sigit_code-1.0.0}/npm/scripts/render-platform-package.cjs +0 -0
  37. {sigit_code-0.1.1 → sigit_code-1.0.0}/npm/sigit/.gitignore +0 -0
  38. {sigit_code-0.1.1 → sigit_code-1.0.0}/npm/sigit/package.json +0 -0
  39. {sigit_code-0.1.1 → sigit_code-1.0.0}/npm/sigit/src/index.ts +0 -0
  40. {sigit_code-0.1.1 → sigit_code-1.0.0}/npm/sigit/tsconfig.json +0 -0
  41. {sigit_code-0.1.1 → sigit_code-1.0.0}/pypi/pyproject.toml +0 -0
  42. {sigit_code-0.1.1 → sigit_code-1.0.0}/pyproject.toml +0 -0
  43. {sigit_code-0.1.1 → sigit_code-1.0.0}/rust-toolchain.toml +0 -0
@@ -0,0 +1,290 @@
1
+ # Skill: Tool Calling in siGit Code
2
+
3
+ ## Overview
4
+
5
+ siGit Code supports **agentic tool calling** — the LLM invokes tools (read/write files, run commands, read websites) to operate on the user's codebase. This works in both **interactive TUI mode** and **ACP server mode** (Zed editor).
6
+
7
+ Tool calling spans three layers:
8
+
9
+ ```
10
+ siGit (agent loop + tool execution)
11
+ → onde (ChatEngine with tool-aware API)
12
+ → mistral.rs (model inference + tool call parsing)
13
+ ```
14
+
15
+ ---
16
+
17
+ ## Model Requirement
18
+
19
+ **Only Qwen 3 supports tool calling.** Qwen 2.5 does NOT — mistral.rs only has a parser for Qwen 3's `<tool_call>...</tool_call>` XML format.
20
+
21
+ | Model | Constructor | Size | Tool calling | Default |
22
+ |-------|-----------|------|:---:|:---:|
23
+ | Qwen 3 8B (Q4_K_M) | `GgufModelConfig::qwen3_8b()` | ~5 GB | ✅ | ✅ **default** |
24
+ | Qwen 3 4B (Q4_K_M) | `GgufModelConfig::qwen3_4b()` | ~2.7 GB | ✅ | |
25
+ | Qwen 3 1.7B (Q4_K_M) | `GgufModelConfig::qwen3_1_7b()` | ~1.3 GB | ✅ | |
26
+ | Qwen 2.5 Coder 3B | `GgufModelConfig::qwen25_coder_3b()` | ~1.93 GB | ❌ | |
27
+ | Qwen 2.5 Coder 1.5B | `GgufModelConfig::qwen25_coder_1_5b()` | ~941 MB | ❌ | |
28
+
29
+ siGit uses **Qwen 3 8B** by default with `max_tokens: 8192` (set in `main.rs` for both TUI and ACP modes).
30
+
31
+ ### Why 8B over 4B
32
+
33
+ 4B can't do `edit_file` reliably. It reads a file, then fails to reproduce the exact `old_text` it just saw. This spirals into 7+ retry rounds that burn through `max_tokens` on `<think>` blocks and return nothing. 8B is the smallest model that actually lands edits.
34
+
35
+ ### bartowski GGUF naming convention
36
+
37
+ bartowski's repos use the publisher name as a prefix with an underscore:
38
+
39
+ | Constant | Value |
40
+ |----------|-------|
41
+ | `BARTOWSKI_QWEN3_8B_GGUF` | `"bartowski/Qwen_Qwen3-8B-GGUF"` |
42
+ | `QWEN3_8B_GGUF_FILE` | `"Qwen_Qwen3-8B-Q4_K_M.gguf"` |
43
+ | `BARTOWSKI_QWEN3_4B_GGUF` | `"bartowski/Qwen_Qwen3-4B-GGUF"` |
44
+ | `QWEN3_4B_GGUF_FILE` | `"Qwen_Qwen3-4B-Q4_K_M.gguf"` |
45
+
46
+ These constants live in `onde/src/inference/models.rs`.
47
+
48
+ ---
49
+
50
+ ## Tools (9 total)
51
+
52
+ Defined in `sigit/src/tools.rs` via `all_tools()`:
53
+
54
+ | # | Tool | Parameters | Behavior |
55
+ |---|------|-----------|----------|
56
+ | 1 | `read_file` | `path` | Reads file contents, truncates at 10,000 chars |
57
+ | 2 | `create_directory` | `path` | Creates directory and all parents |
58
+ | 3 | `list_directory` | `path` | Lists entries with `[DIR]`/`[FILE]` prefix, dirs first |
59
+ | 4 | `search_files` | `pattern`, `path` (optional) | Recursive regex search, max 50 matches |
60
+ | 5 | `read_website` | `url` | Fetches HTTP/HTTPS, strips HTML, returns text |
61
+ | 6 | `create_file` | `path`, `content` | Creates new file (fails if exists) |
62
+ | 7 | `edit_file` | `path`, `old_text`, `new_text` | Find-and-replace (must match exactly once) |
63
+ | 8 | `delete_file` | `path` | Deletes file or empty directory |
64
+ | 9 | `run_command` | `command`, `cwd` (optional) | Shell command with 120s timeout |
65
+
66
+ ### Async handling
67
+
68
+ `execute_tool()` is `async`. Most tools run synchronously, except:
69
+
70
+ - **`read_website`** — uses `tokio::task::spawn_blocking` because `reqwest::blocking::Client` panics inside a tokio runtime ("Cannot start a runtime from within a runtime")
71
+
72
+ ### Tool gating by model
73
+
74
+ In TUI mode, `run_inference_task()` takes a `tools_enabled: bool` parameter. When the model's `ModelOption.tool_calling` is `false` (Qwen 2.5), an empty tool list is passed so the model doesn't receive tool schemas it can't use.
75
+
76
+ ---
77
+
78
+ ## Architecture
79
+
80
+ ### Layer 1: mistral.rs (model-level)
81
+
82
+ - `RequestBuilder::set_tools(Vec<Tool>)` — attach tool definitions
83
+ - `RequestBuilder::set_tool_choice(ToolChoice::Auto)` — let model decide
84
+ - `QwenParser` detects `<tool_call>...</tool_call>` tags in output
85
+ - Grammar-constrained decoding forces valid JSON inside tool calls
86
+ - `<think>...</think>` reasoning is separated from tool calls by the reasoning parser
87
+ - Works identically for GGUF and full-precision models
88
+
89
+ ### Layer 2: onde (engine-level)
90
+
91
+ #### Key types (`onde/src/inference/types.rs`)
92
+
93
+ | Type | Purpose |
94
+ |------|---------|
95
+ | `ToolDefinition` | `{ name, description, parameters_schema: String }` |
96
+ | `ToolCallRequest` | `{ id, function_name, arguments: String }` |
97
+ | `ToolResult` | `{ tool_call_id, content: String }` |
98
+ | `ToolAwareResult` | `{ text, tool_calls: Vec<ToolCallRequest>, duration_secs, ... }` |
99
+
100
+ #### Key methods (`onde/src/inference/engine.rs`)
101
+
102
+ | Method | Purpose |
103
+ |--------|---------|
104
+ | `send_message_with_tools(msg, &[ToolDefinition])` | Returns `ToolAwareResult` with possible tool calls |
105
+ | `send_tool_results(Vec<ToolResult>, Option<&[ToolDefinition]>)` | Feed results back; `None` forces text response |
106
+
107
+ #### Internal details
108
+
109
+ - `attach_tools()` converts `ToolDefinition` → mistral.rs `Tool`, sets `ToolChoice::Auto` and `strict: Some(true)`
110
+ - `parse_tool_calls()` extracts tool calls from `choice.message.tool_calls`, generates fallback IDs if empty
111
+ - `replay_history_with_tools()` uses `.enumerate()` for correct sequential `index` values
112
+ - Malformed `parameters_schema` JSON logs a warning instead of silently producing empty params
113
+ - Malformed tool call `arguments` JSON logs a warning for debugging
114
+
115
+ ### Layer 3: siGit (agent-level)
116
+
117
+ #### ACP session handling (`src/main.rs`)
118
+
119
+ All session handlers (`load_session`, `fork_session`, `new_session`) do:
120
+
121
+ 1. **Store `args.cwd`** in `session_cwd: Mutex<Option<PathBuf>>`
122
+ 2. **`std::env::set_current_dir(&args.cwd)`** — so relative paths in tool calls resolve correctly
123
+ 3. **`engine.clear_history()`** — siGit doesn't persist sessions
124
+ 4. **`engine.push_history(ChatMessage::system(...))`** — injects: *"The user's project working directory is {cwd}. Always use absolute paths..."*
125
+
126
+ Without step 4, the model uses the process `cwd` (often `$HOME`) and creates files in the wrong directory.
127
+
128
+ #### ACP content block handling (`prompt()`)
129
+
130
+ The `prompt()` handler processes all ACP content block types:
131
+
132
+ - **`ContentBlock::Text`** — passed through as-is
133
+ - **`ContentBlock::Resource` (EmbeddedResource)** — `TextResourceContents` inlined as `--- {uri} ---\n{text}\n--- end ---`
134
+ - **`ContentBlock::ResourceLink`** — `file://` URIs are read from disk. **Line range fragments** like `#L207:219` are parsed: the `#` fragment is stripped from the path, and only lines 207–219 are extracted and sent to the model
135
+
136
+ Example: Zed sends `@ index.html (207:219)` as:
137
+ ```
138
+ ResourceLink(name="index.html (207:219)", uri="file:///path/to/index.html#L207:219")
139
+ ```
140
+ siGit parses this into path `/path/to/index.html` + lines 207–219.
141
+
142
+ ---
143
+
144
+ ## The Agentic Loop
145
+
146
+ Both ACP mode (`SiGitAgent::prompt()`) and TUI mode (`run_inference_task()`) implement:
147
+
148
+ ```
149
+ 1. engine.send_message_with_tools(user_text, &tools) → ToolAwareResult
150
+ 2. while result.tool_calls is non-empty AND round < MAX_TOOL_ROUNDS (10):
151
+ a. For each tool_call:
152
+ - Log: → tool_name(arguments)
153
+ - Execute: tools::execute_tool(name, arguments).await
154
+ - Log: ← N chars
155
+ - Collect ToolResult { tool_call_id, content }
156
+ b. Decide next_tools:
157
+ - round < MAX_TOOL_ROUNDS → Some(&tools) (allow more calls)
158
+ - else → None (force text response)
159
+ c. engine.send_tool_results(results, next_tools) → ToolAwareResult
160
+ 3. Send final result.text to user
161
+ - Empty reply after tool rounds → log warning (ACP) or show error (TUI)
162
+ ```
163
+
164
+ ---
165
+
166
+ ## System Prompt
167
+
168
+ The `SYSTEM_PROMPT` in `main.rs` (~122 lines) includes critical instructions:
169
+
170
+ - **Never tell the user to run commands** — use `run_command` tool instead
171
+ - **Can access websites** — use `read_website` tool (overrides RLHF refusal training)
172
+ - **Prefer absolute paths** in all tool arguments
173
+ - **Git operations** — always use `run_command` with absolute cwd
174
+ - **smbCloud domain knowledge** — auth boundaries, deploy flows, project structure
175
+
176
+ The session `cwd` is injected as a separate system message at session creation time (not part of the static prompt).
177
+
178
+ ---
179
+
180
+ ## Model Cache
181
+
182
+ Models are stored in the shared Onde App Group container on macOS:
183
+
184
+ ```
185
+ ~/Library/Group Containers/group.com.ondeinference.apps/models/hub/
186
+ ```
187
+
188
+ `setup.rs` sets `HF_HOME` and `HF_HUB_CACHE` to point there at startup, so siGit reuses models downloaded by the Onde desktop app (and vice versa).
189
+
190
+ ---
191
+
192
+ ## Adding a New Tool
193
+
194
+ 1. Add an `AgentTool` entry to `all_tools()` in `src/tools.rs`
195
+ 2. Add a match arm to `execute_tool()` — use `spawn_blocking` if the implementation blocks
196
+ 3. Write `exec_your_tool(arguments: &str) -> String`
197
+ 4. Update `test_all_tools_count` test (currently expects 9)
198
+
199
+ No changes needed in onde or mistral.rs — tool definitions are passed dynamically.
200
+
201
+ ---
202
+
203
+ ## Adding a New Model
204
+
205
+ 1. **`onde/src/inference/models.rs`** — add `pub const` for repo ID and GGUF filename, add to `SUPPORTED_MODELS` array and `SUPPORTED_MODEL_INFO`
206
+ 2. **`onde/src/inference/engine.rs`** — add `pub fn model_name() -> Self` constructor to `impl GgufModelConfig`
207
+ 3. **`sigit/src/chat.rs`** — add `ModelOption` entry to `SIGIT_MODELS` with `tool_calling: true/false`
208
+ 4. **`sigit/src/main.rs`** — update `run_interactive()` and `run_acp_server()` if changing the default
209
+
210
+ ---
211
+
212
+ ## Debugging
213
+
214
+ ### Log locations
215
+
216
+ - **TUI mode:** `$TMPDIR/sigit.log` (e.g. `/var/folders/.../sigit.log`)
217
+ - **ACP mode (Zed):** `~/Library/Logs/Zed/Zed.log` — grep for `agent stderr:.*sigit`
218
+
219
+ ### Key log patterns
220
+
221
+ ```
222
+ # Model loaded successfully
223
+ ChatEngine: model Qwen 3 8B loaded in 6.9s
224
+
225
+ # Session cwd captured
226
+ load_session: id=..., cwd=/path/to/project, additional_directories=[...]
227
+
228
+ # Tool call parsed by mistral.rs
229
+ ChatEngine: tool inference END — 12.3s — tool_calls: 1
230
+
231
+ # Tool executed
232
+ → read_file({"path":"/absolute/path/to/file.rs"})
233
+ ← 6506 chars
234
+
235
+ # Tool result sent back
236
+ ChatEngine: tool results inference START — 1 results
237
+
238
+ # Model returned empty (exhausted max_tokens on thinking)
239
+ model returned empty reply after 7 tool round(s)
240
+
241
+ # ResourceLink received from Zed
242
+ block[1]: ResourceLink(name=index.html (207:219), uri=file:///path/to/index.html#L207:219)
243
+
244
+ # ResourceLink read failed (fragment not stripped — old bug, now fixed)
245
+ could not read ResourceLink file:///path/to/index.html#L207:219: No such file or directory
246
+ ```
247
+
248
+ ### Common issues
249
+
250
+ | Symptom | Cause | Fix |
251
+ |---------|-------|-----|
252
+ | Model says "I cannot access websites" | RLHF refusal override not in system prompt | System prompt now has CRITICAL block about `read_website` |
253
+ | `0 tool call(s)` for every prompt | Wrong model loaded (Qwen 2.5) | Check log for `loading GGUF model` — must be Qwen 3 |
254
+ | `edit_file` returns `← 161 chars` repeatedly | `old_text not found` — model can't match exact text | Use Qwen 3 8B (not 4B); consider line-based edit tool |
255
+ | Files created in wrong directory | `cwd` not captured from ACP session | Session handlers must call `set_current_dir` + `push_history` with cwd |
256
+ | `@ file.html (207:219)` context missing | `#L207:219` fragment not stripped from file path | `prompt()` now parses URI fragments and extracts line ranges |
257
+ | `read_website` panics/hangs | `reqwest::blocking` inside tokio runtime | `exec_read_website` wrapped in `spawn_blocking` |
258
+ | Empty reply after many tool rounds | Model exhausted `max_tokens` on `<think>` blocks | Set `max_tokens: 8192`; 8B model wastes fewer tokens on thinking |
259
+
260
+ ---
261
+
262
+ ## Cargo Dependency Note
263
+
264
+ For local development, `sigit/Cargo.toml` must use the path dependency:
265
+
266
+ ```toml
267
+ onde = { path = "../onde" }
268
+ ```
269
+
270
+ For CI/release, switch to the git dependency (after pushing Onde changes):
271
+
272
+ ```toml
273
+ onde = { git = "https://github.com/ondeinference/onde", branch = "development" }
274
+ ```
275
+
276
+ The `qwen3_8b()` constructor only exists in the local Onde SDK until it's pushed to the `development` branch.
277
+
278
+ ---
279
+
280
+ ## File Map
281
+
282
+ | File | What it does |
283
+ |------|-------------|
284
+ | `sigit/src/tools.rs` | 9 tool schemas (`all_tools()`), `execute_tool()` dispatch, all `exec_*` implementations |
285
+ | `sigit/src/main.rs` | `SYSTEM_PROMPT`, `SiGitAgent` struct with `session_cwd`, ACP session handlers (cwd + push_history), `prompt()` with content block parsing, model selection (`qwen3_8b`), `MAX_TOOL_ROUNDS` |
286
+ | `sigit/src/chat.rs` | `SIGIT_MODELS` array (4 models), `run_inference_task()` with `tools_enabled` gate, TUI tool loop |
287
+ | `sigit/src/setup.rs` | HF cache setup pointing to shared App Group container |
288
+ | `onde/src/inference/types.rs` | `ToolDefinition`, `ToolCallRequest`, `ToolResult`, `ToolAwareResult` |
289
+ | `onde/src/inference/engine.rs` | `send_message_with_tools()`, `send_tool_results()`, `attach_tools()`, `parse_tool_calls()`, `replay_history_with_tools()`, `GgufModelConfig::qwen3_8b()` |
290
+ | `onde/src/inference/models.rs` | Model constants and `SUPPORTED_MODELS` array |
@@ -4,7 +4,10 @@ name: CI
4
4
  # Splits formatting, clippy, and tests into separate jobs for clearer reporting
5
5
  # across supported desktop targets.
6
6
 
7
- on: push
7
+ on:
8
+ push:
9
+ pull_request:
10
+ workflow_dispatch:
8
11
 
9
12
  env:
10
13
  CARGO_TERM_COLOR: always
@@ -54,7 +54,7 @@ jobs:
54
54
  - name: Checkout Homebrew tap
55
55
  uses: actions/checkout@v6
56
56
  with:
57
- repository: getsigit/sigit-homebrew-tap
57
+ repository: getsigit/homebrew-tap
58
58
  token: ${{ secrets.HOMEBREW_TAP_TOKEN }}
59
59
  path: homebrew-tap
60
60
 
@@ -0,0 +1,70 @@
1
+ # Changelog
2
+
3
+ ## 1.0.0 — 2026
4
+
5
+ We've been running siGit in production across smbCloud codebases for a while now. It works. Time to call it 1.0.
6
+
7
+ ---
8
+
9
+ ### The short version
10
+
11
+ siGit is a local coding agent. It runs a quantized LLM on your machine, talks to editors over ACP, and can read files, run commands, search the web, and write code — all without sending anything to a cloud API. You install it with cargo, pip, npm, or Homebrew. It just works.
12
+
13
+ ---
14
+
15
+ ### What's actually in here
16
+
17
+ **The editor integration** is the main thing. Zed and VSCode both pick it up as an ACP agent. Multi-turn sessions, tool calling, session forking, working directory context — all there. This was the original goal and it's solid.
18
+
19
+ **The terminal UI** is a bonus that turned out to be genuinely useful. Full-screen ratatui chat, streaming tokens with a blinking cursor, a thinking spinner while the model reasons, a model picker you can pull up mid-session. It runs on macOS and Linux. Windows gets the editor integration for now — TUI support there is on the list.
20
+
21
+ **Tool calling** is what makes it an agent instead of a chat window. The loop runs up to 10 rounds per message:
22
+
23
+ - `read_file` / `write_file` / `delete_file`
24
+ - `list_directory` / `search_files`
25
+ - `run_command` — shell commands with optional working directory
26
+ - `read_website` — fetches a URL and strips it to readable text
27
+
28
+ The model decides which tools to call, sees the results, and keeps going until it has something worth saying.
29
+
30
+ **Model support** is broader than we expected to ship at 1.0. Qwen 3 1.7B, 4B, 8B, and 14B. Qwen 2.5 1.5B and 3B. Qwen 2.5 Coder 1.5B, 3B, and 7B. DeepSeek Coder 6.7B. All GGUF, all pulled from HuggingFace on first run.
31
+
32
+ Qwen 3 is the interesting one. It uses extended thinking mode — the model reasons inside `<think>…</think>` blocks before answering. The TUI strips those out and renders them dimmed above the reply, so you can see what it was doing without it cluttering the conversation. The 8B is the default on desktop. Mobile defaults to 1.7B because iOS gives apps ~2–3 GB and we found out the hard way that 3B causes OOM on an iPhone 16e.
33
+
34
+ **The model picker** (`/models` in the TUI, or an agent config option in editors) shows what's cached locally, what's available to download, whether a model supports tool calling, and whether its local cache looks healthy. Switching models downloads and loads in the background — the UI stays alive the whole time with a progress bar.
35
+
36
+ **smbCloud context** is baked into the system prompt. siGit knows the difference between platform user flows and tenant app auth flows, how `Project` / `FrontendApp` / `AuthApp` / GresIQ fit together, that Next.js SSR deploys are not the generic git-push path, and what workspace patterns smbCloud repos tend to follow. Outside smbCloud it's a normal coding agent and doesn't push platform-specific advice where it doesn't belong.
37
+
38
+ **Distribution** ended up being more work than the software itself, honestly. Pre-built binaries for macOS (arm64 + x64), Linux (arm64 + x64), and Windows (arm64 + x64). Four install methods: `cargo install sigit`, `pip install sigit-code`, `npm install -g @smbcloud/sigit`, `brew install sigit`. Getting all of that working across CI, crates.io, PyPI, npm, and Homebrew is its own project.
39
+
40
+ ---
41
+
42
+ ### What doesn't work yet
43
+
44
+ The Windows TUI. ACP/editor mode works fine on Windows — it's just the interactive terminal UI that's missing. The underlying issue is Unix-specific terminal handling we haven't abstracted yet.
45
+
46
+ ---
47
+
48
+ ### Changes since 0.1.2
49
+
50
+ - Qwen 3 14B support
51
+ - Qwen 3 `<think>` block parsing — strips and renders thinking content separately in the TUI
52
+ - Moved all TUI code into `#[cfg(unix)]` — this fixed a pile of dead-code errors on Windows CI that were blocking releases
53
+ - Live download progress bar during model switch, with cancellation (Ctrl+C mid-download works)
54
+ - Model download and loading progress shown in the Zed agent config panel
55
+ - Animated spinner during model switching
56
+ - Qwen 2.5 Coder 7B
57
+ - Available-for-download models shown in the picker, not just locally cached ones
58
+ - Model selection persists across restarts
59
+ - Session working directory support
60
+ - Model picker logic moved to a platform-independent module so it compiles on Windows even without the TUI
61
+ - `/models N` shortcut for picking a model by number directly
62
+ - `read_website` tool
63
+ - Better `read_file` handling and empty reply detection
64
+ - Async tool execution
65
+ - Fixed CI cross-compilation for macOS, iOS, Linux, and Windows
66
+ - npm, PyPI, and Homebrew distribution added
67
+
68
+ ---
69
+
70
+ *© 2026 [smbCloud](https://smbcloud.xyz/) (Splitfire AB).*
@@ -741,9 +741,9 @@ dependencies = [
741
741
 
742
742
  [[package]]
743
743
  name = "cc"
744
- version = "1.2.60"
744
+ version = "1.2.61"
745
745
  source = "registry+https://github.com/rust-lang/crates.io-index"
746
- checksum = "43c5703da9466b66a946814e1adf53ea2c90f10063b86290cc9eb67ce3478a20"
746
+ checksum = "d16d90359e986641506914ba71350897565610e87ce0ad9e6f28569db3dd5c6d"
747
747
  dependencies = [
748
748
  "find-msvc-tools",
749
749
  "jobserver",
@@ -1264,9 +1264,9 @@ dependencies = [
1264
1264
 
1265
1265
  [[package]]
1266
1266
  name = "data-encoding"
1267
- version = "2.10.0"
1267
+ version = "2.11.0"
1268
1268
  source = "registry+https://github.com/rust-lang/crates.io-index"
1269
- checksum = "d7a1e2f27636f116493b8b860f5546edb47c8d8f8ea73e1d2a20be88e28d1fea"
1269
+ checksum = "a4ae5f15dda3c708c0ade84bfee31ccab44a3da4f88015ed22f63732abe300c8"
1270
1270
 
1271
1271
  [[package]]
1272
1272
  name = "defmac"
@@ -3264,7 +3264,7 @@ dependencies = [
3264
3264
  [[package]]
3265
3265
  name = "mistralrs"
3266
3266
  version = "0.8.1"
3267
- source = "git+https://github.com/setoelkahfi/mistral.rs?branch=fix%2Fall-platform-fixes#020dcbf8e2c4147c16bb015e89435811501baa28"
3267
+ source = "git+https://github.com/setoelkahfi/mistral.rs?branch=fix%2Fall-platform-fixes#e53956bcd1b40c8221f79b919d78c1e496aba634"
3268
3268
  dependencies = [
3269
3269
  "anyhow",
3270
3270
  "candle-core",
@@ -3291,7 +3291,7 @@ dependencies = [
3291
3291
  [[package]]
3292
3292
  name = "mistralrs-audio"
3293
3293
  version = "0.8.1"
3294
- source = "git+https://github.com/setoelkahfi/mistral.rs?branch=fix%2Fall-platform-fixes#020dcbf8e2c4147c16bb015e89435811501baa28"
3294
+ source = "git+https://github.com/setoelkahfi/mistral.rs?branch=fix%2Fall-platform-fixes#e53956bcd1b40c8221f79b919d78c1e496aba634"
3295
3295
  dependencies = [
3296
3296
  "anyhow",
3297
3297
  "apodize",
@@ -3302,7 +3302,7 @@ dependencies = [
3302
3302
  [[package]]
3303
3303
  name = "mistralrs-core"
3304
3304
  version = "0.8.1"
3305
- source = "git+https://github.com/setoelkahfi/mistral.rs?branch=fix%2Fall-platform-fixes#020dcbf8e2c4147c16bb015e89435811501baa28"
3305
+ source = "git+https://github.com/setoelkahfi/mistral.rs?branch=fix%2Fall-platform-fixes#e53956bcd1b40c8221f79b919d78c1e496aba634"
3306
3306
  dependencies = [
3307
3307
  "ahash",
3308
3308
  "akin",
@@ -3399,7 +3399,7 @@ dependencies = [
3399
3399
  [[package]]
3400
3400
  name = "mistralrs-macros"
3401
3401
  version = "0.8.1"
3402
- source = "git+https://github.com/setoelkahfi/mistral.rs?branch=fix%2Fall-platform-fixes#020dcbf8e2c4147c16bb015e89435811501baa28"
3402
+ source = "git+https://github.com/setoelkahfi/mistral.rs?branch=fix%2Fall-platform-fixes#e53956bcd1b40c8221f79b919d78c1e496aba634"
3403
3403
  dependencies = [
3404
3404
  "darling 0.23.0",
3405
3405
  "proc-macro2",
@@ -3410,7 +3410,7 @@ dependencies = [
3410
3410
  [[package]]
3411
3411
  name = "mistralrs-mcp"
3412
3412
  version = "0.8.1"
3413
- source = "git+https://github.com/setoelkahfi/mistral.rs?branch=fix%2Fall-platform-fixes#020dcbf8e2c4147c16bb015e89435811501baa28"
3413
+ source = "git+https://github.com/setoelkahfi/mistral.rs?branch=fix%2Fall-platform-fixes#e53956bcd1b40c8221f79b919d78c1e496aba634"
3414
3414
  dependencies = [
3415
3415
  "anyhow",
3416
3416
  "async-trait",
@@ -3430,7 +3430,7 @@ dependencies = [
3430
3430
  [[package]]
3431
3431
  name = "mistralrs-paged-attn"
3432
3432
  version = "0.8.1"
3433
- source = "git+https://github.com/setoelkahfi/mistral.rs?branch=fix%2Fall-platform-fixes#020dcbf8e2c4147c16bb015e89435811501baa28"
3433
+ source = "git+https://github.com/setoelkahfi/mistral.rs?branch=fix%2Fall-platform-fixes#e53956bcd1b40c8221f79b919d78c1e496aba634"
3434
3434
  dependencies = [
3435
3435
  "anyhow",
3436
3436
  "candle-core",
@@ -3446,7 +3446,7 @@ dependencies = [
3446
3446
  [[package]]
3447
3447
  name = "mistralrs-quant"
3448
3448
  version = "0.8.1"
3449
- source = "git+https://github.com/setoelkahfi/mistral.rs?branch=fix%2Fall-platform-fixes#020dcbf8e2c4147c16bb015e89435811501baa28"
3449
+ source = "git+https://github.com/setoelkahfi/mistral.rs?branch=fix%2Fall-platform-fixes#e53956bcd1b40c8221f79b919d78c1e496aba634"
3450
3450
  dependencies = [
3451
3451
  "byteorder",
3452
3452
  "candle-core",
@@ -3475,7 +3475,7 @@ dependencies = [
3475
3475
  [[package]]
3476
3476
  name = "mistralrs-vision"
3477
3477
  version = "0.8.1"
3478
- source = "git+https://github.com/setoelkahfi/mistral.rs?branch=fix%2Fall-platform-fixes#020dcbf8e2c4147c16bb015e89435811501baa28"
3478
+ source = "git+https://github.com/setoelkahfi/mistral.rs?branch=fix%2Fall-platform-fixes#e53956bcd1b40c8221f79b919d78c1e496aba634"
3479
3479
  dependencies = [
3480
3480
  "candle-core",
3481
3481
  "image",
@@ -3799,7 +3799,7 @@ checksum = "384b8ab6d37215f3c5301a95a4accb5d64aa607f1fcb26a11b5303878451b4fe"
3799
3799
  [[package]]
3800
3800
  name = "onde"
3801
3801
  version = "0.1.8"
3802
- source = "git+https://github.com/ondeinference/onde?branch=development#f0bb0daad7fb07af951002f1bcae16fbd0bc876d"
3802
+ source = "git+https://github.com/ondeinference/onde?branch=development#dfcc6ecfa74ac965af6c33ba0bd06d9cf241fc12"
3803
3803
  dependencies = [
3804
3804
  "anyhow",
3805
3805
  "cc",
@@ -4807,9 +4807,9 @@ dependencies = [
4807
4807
 
4808
4808
  [[package]]
4809
4809
  name = "rustls-pki-types"
4810
- version = "1.14.0"
4810
+ version = "1.14.1"
4811
4811
  source = "registry+https://github.com/rust-lang/crates.io-index"
4812
- checksum = "be040f8b0a225e40375822a563fa9524378b9d63112f53e19ffff34df5d33fdd"
4812
+ checksum = "30a7197ae7eb376e574fe940d068c30fe0462554a3ddbe4eca7838e049c937a9"
4813
4813
  dependencies = [
4814
4814
  "web-time",
4815
4815
  "zeroize",
@@ -5271,7 +5271,7 @@ checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64"
5271
5271
 
5272
5272
  [[package]]
5273
5273
  name = "sigit"
5274
- version = "0.1.1"
5274
+ version = "1.0.0"
5275
5275
  dependencies = [
5276
5276
  "agent-client-protocol",
5277
5277
  "anyhow",
@@ -5283,6 +5283,7 @@ dependencies = [
5283
5283
  "onde",
5284
5284
  "ratatui",
5285
5285
  "regex",
5286
+ "reqwest 0.12.28",
5286
5287
  "serde_json",
5287
5288
  "tokio",
5288
5289
  "tokio-util",
@@ -1,6 +1,6 @@
1
1
  [package]
2
2
  name = "sigit"
3
- version = "0.1.1"
3
+ version = "1.0.0"
4
4
  edition = "2024"
5
5
  description = "siGit Code — ACP-compatible AI coding agent for smbCloud platform."
6
6
  documentation = "https://github.com/getsigit/sigit"
@@ -18,11 +18,11 @@ path = "src/main.rs"
18
18
 
19
19
  [dependencies]
20
20
  # ACP protocol SDK
21
- agent-client-protocol = { version = "0.10.4", features = ["unstable_session_fork"] }
21
+ agent-client-protocol = { version = "0.10.4", features = ["unstable_session_fork", "unstable_session_additional_directories"] }
22
22
 
23
23
  # Onde Inference engine (local LLM)
24
- # For local development: onde = { path = "../onde" }
25
- onde = { git = "https://github.com/ondeinference/onde", branch = "development" }
24
+ # onde = { path = "../onde" }
25
+ onde = { version = "0.1.8", git = "https://github.com/ondeinference/onde", branch = "development" }
26
26
 
27
27
  # Async runtime
28
28
  async-trait = "0.1"
@@ -41,4 +41,5 @@ log = "0.4"
41
41
  tracing-subscriber = { version = "0.3", features = ["fmt", "env-filter"] }
42
42
  serde_json = "1"
43
43
  regex = "1"
44
+ reqwest = { version = "0.12", default-features = false, features = ["blocking", "rustls-tls"] }
44
45
  uuid = { version = "1", features = ["v4"] }
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: sigit-code
3
- Version: 0.1.1
3
+ Version: 1.0.0
4
4
  Classifier: Development Status :: 4 - Beta
5
5
  Classifier: Environment :: Console
6
6
  Classifier: Intended Audience :: Developers
@@ -25,11 +25,7 @@ Project-URL: Homepage, https://smbcloud.xyz
25
25
  Project-URL: Issues, https://github.com/getsigit/sigit/issues
26
26
  Project-URL: Repository, https://github.com/getsigit/sigit
27
27
 
28
- <p align="center">
29
- <strong>siGit Code</strong>
30
- </p>
31
-
32
- <h1 align="center">sigit</h1>
28
+ <h1 align="center">siGit Code</h1>
33
29
 
34
30
  <p align="center">
35
31
  <strong>AI coding agent powered by local LLM via <a href="https://ondeinference.com">Onde Inference</a>.</strong><br>
@@ -37,10 +33,10 @@ Project-URL: Repository, https://github.com/getsigit/sigit
37
33
  </p>
38
34
 
39
35
  <p align="center">
40
- <a href="https://smbcloud.xyz"><img src="https://img.shields.io/badge/smbcloud.xyz-235843?style=flat-square&labelColor=17211D" alt="Website"></a>
41
36
  <a href="https://pypi.org/project/sigit-code/"><img src="https://img.shields.io/pypi/v/sigit-code?style=flat-square&labelColor=17211D&color=235843" alt="PyPI"></a>
42
- <a href="https://www.npmjs.com/package/@smbcloud/sigit"><img src="https://img.shields.io/npm/v/@smbcloud/sigit?style=flat-square&labelColor=17211D&color=235843" alt="npm"></a>
43
37
  <a href="https://crates.io/crates/sigit"><img src="https://img.shields.io/crates/v/sigit?style=flat-square&labelColor=17211D&color=235843" alt="Crates.io"></a>
38
+ <a href="https://www.npmjs.com/package/@smbcloud/sigit"><img src="https://img.shields.io/npm/v/@smbcloud/sigit?style=flat-square&labelColor=17211D&color=235843" alt="npm"></a>
39
+ <a href="https://smbcloud.xyz"><img src="https://img.shields.io/badge/smbcloud.xyz-235843?style=flat-square&labelColor=17211D" alt="Website"></a>
44
40
  <a href="https://github.com/getsigit/sigit/blob/main/LICENSE"><img src="https://img.shields.io/badge/license-Apache--2.0-235843?style=flat-square&labelColor=17211D" alt="License"></a>
45
41
  </p>
46
42
 
@@ -50,8 +46,11 @@ Project-URL: Repository, https://github.com/getsigit/sigit
50
46
 
51
47
  ## Install
52
48
 
49
+ Use `pip` or `uv`:
50
+
53
51
  ```sh
54
52
  pip install sigit-code
53
+ uvx --from sigit-code sigit
55
54
  ```
56
55
 
57
56
  Installs the native `sigit` binary for your platform — no compiler, no Node.js, no runtime dependencies.
@@ -72,15 +71,10 @@ siGit works as an [ACP-compatible](https://github.com/nicobailon/agent-client-pr
72
71
 
73
72
  ```json
74
73
  {
75
- "agent": {
76
- "profiles": {
77
- "sigit": {
78
- "provider": "acp",
79
- "binary": {
80
- "path": "sigit",
81
- "args": ["--acp"]
82
- }
83
- }
74
+ "agent_servers": {
75
+ "siGit Code": {
76
+ "type": "custom",
77
+ "command": "/absolute/path/to/sigit"
84
78
  }
85
79
  }
86
80
  }
@@ -93,7 +87,7 @@ Then select **sigit** as your agent profile in the Zed assistant panel.
93
87
  | Method | Command |
94
88
  |--------|---------|
95
89
  | npm | `npm install -g @smbcloud/sigit` |
96
- | Homebrew | `brew install getsigit/sigit/sigit` |
90
+ | Homebrew | `brew tap getsigit/tap && brew install sigit` |
97
91
  | Cargo | `cargo install sigit` |
98
92
 
99
93
  ### From source
@@ -131,4 +125,4 @@ Licensed under **Apache 2.0**.
131
125
 
132
126
  ## Copyright
133
127
 
134
- 2026 smbCloud (Splitfire AB).
128
+ © 2026 [smbCloud](https://smbcloud.xyz/) (Splitfire AB).