sigit-code 1.5.10__tar.gz → 1.5.12__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.
- {sigit_code-1.5.10 → sigit_code-1.5.12}/.agents/AGENTS.md +42 -5
- {sigit_code-1.5.10/.claude → sigit_code-1.5.12/.agents}/skills/agent-client-protocol/SKILL.md +11 -1
- sigit_code-1.5.12/.cargo/config.toml +7 -0
- {sigit_code-1.5.10/.agents → sigit_code-1.5.12/.claude}/skills/agent-client-protocol/SKILL.md +11 -1
- {sigit_code-1.5.10 → sigit_code-1.5.12}/.github/workflows/ci.yml +5 -0
- {sigit_code-1.5.10 → sigit_code-1.5.12}/.github/workflows/release-github.yml +5 -0
- {sigit_code-1.5.10 → sigit_code-1.5.12}/.gitignore +1 -0
- {sigit_code-1.5.10 → sigit_code-1.5.12}/AGENTS.md +42 -5
- {sigit_code-1.5.10 → sigit_code-1.5.12}/CHANGELOG.md +128 -0
- {sigit_code-1.5.10 → sigit_code-1.5.12}/CLAUDE.md +42 -5
- {sigit_code-1.5.10 → sigit_code-1.5.12}/Cargo.lock +1 -1
- {sigit_code-1.5.10 → sigit_code-1.5.12}/Cargo.toml +1 -1
- {sigit_code-1.5.10 → sigit_code-1.5.12}/PKG-INFO +5 -3
- {sigit_code-1.5.10 → sigit_code-1.5.12}/README.md +41 -7
- sigit_code-1.5.12/docs/headless.md +64 -0
- {sigit_code-1.5.10 → sigit_code-1.5.12}/npm/sigit/README.md +5 -3
- {sigit_code-1.5.10 → sigit_code-1.5.12}/nuget/sigit/README.md +10 -4
- sigit_code-1.5.12/packaging/windows/check-static-crt.ps1 +35 -0
- {sigit_code-1.5.10 → sigit_code-1.5.12}/packaging/winget/getSigit.siGitCode.installer.yaml.in +2 -0
- {sigit_code-1.5.10 → sigit_code-1.5.12}/pypi/README.md +4 -2
- {sigit_code-1.5.10 → sigit_code-1.5.12}/src/backend.rs +411 -48
- {sigit_code-1.5.10 → sigit_code-1.5.12}/src/chat.rs +8 -15
- {sigit_code-1.5.10 → sigit_code-1.5.12}/src/headless.rs +275 -34
- {sigit_code-1.5.10 → sigit_code-1.5.12}/src/inline_tool_calls.rs +338 -80
- {sigit_code-1.5.10 → sigit_code-1.5.12}/src/instructions.rs +3 -1
- {sigit_code-1.5.10 → sigit_code-1.5.12}/src/main.rs +995 -168
- {sigit_code-1.5.10 → sigit_code-1.5.12}/src/permissions.rs +0 -12
- sigit_code-1.5.12/src/session_store.rs +526 -0
- {sigit_code-1.5.10 → sigit_code-1.5.12}/src/tools.rs +625 -72
- {sigit_code-1.5.10 → sigit_code-1.5.12}/src/workspace.rs +14 -3
- {sigit_code-1.5.10 → sigit_code-1.5.12}/tests/acp_endpoint_errors.rs +3 -1
- {sigit_code-1.5.10 → sigit_code-1.5.12}/tests/acp_permissions.rs +258 -4
- sigit_code-1.5.12/tests/acp_session_list.rs +246 -0
- {sigit_code-1.5.10 → sigit_code-1.5.12}/tests/headless_mode.rs +166 -4
- sigit_code-1.5.10/src/session_store.rs +0 -261
- {sigit_code-1.5.10 → sigit_code-1.5.12}/.agents/skills/ai-assisted-coding/SKILL.md +0 -0
- {sigit_code-1.5.10 → sigit_code-1.5.12}/.agents/skills/branding/SKILL.md +0 -0
- {sigit_code-1.5.10 → sigit_code-1.5.12}/.agents/skills/run-sigit/SKILL.md +0 -0
- {sigit_code-1.5.10 → sigit_code-1.5.12}/.agents/skills/run-sigit/driver.mjs +0 -0
- {sigit_code-1.5.10 → sigit_code-1.5.12}/.agents/skills/run-sigit/tui-smoke.sh +0 -0
- {sigit_code-1.5.10 → sigit_code-1.5.12}/.agents/skills/sigit-code-release/SKILL.md +0 -0
- {sigit_code-1.5.10 → sigit_code-1.5.12}/.agents/skills/tool-calling/SKILL.md +0 -0
- {sigit_code-1.5.10 → sigit_code-1.5.12}/.claude/skills/ai-assisted-coding/SKILL.md +0 -0
- {sigit_code-1.5.10 → sigit_code-1.5.12}/.claude/skills/branding/SKILL.md +0 -0
- {sigit_code-1.5.10 → sigit_code-1.5.12}/.claude/skills/run-sigit/SKILL.md +0 -0
- {sigit_code-1.5.10 → sigit_code-1.5.12}/.claude/skills/run-sigit/driver.mjs +0 -0
- {sigit_code-1.5.10 → sigit_code-1.5.12}/.claude/skills/run-sigit/tui-smoke.sh +0 -0
- {sigit_code-1.5.10 → sigit_code-1.5.12}/.claude/skills/sigit-code-release/SKILL.md +0 -0
- {sigit_code-1.5.10 → sigit_code-1.5.12}/.claude/skills/tool-calling/SKILL.md +0 -0
- {sigit_code-1.5.10 → sigit_code-1.5.12}/.github/workflows/release-aur.yml +0 -0
- {sigit_code-1.5.10 → sigit_code-1.5.12}/.github/workflows/release-crates.yml +0 -0
- {sigit_code-1.5.10 → sigit_code-1.5.12}/.github/workflows/release-homebrew.yml +0 -0
- {sigit_code-1.5.10 → sigit_code-1.5.12}/.github/workflows/release-npm.yml +0 -0
- {sigit_code-1.5.10 → sigit_code-1.5.12}/.github/workflows/release-nuget.yml +0 -0
- {sigit_code-1.5.10 → sigit_code-1.5.12}/.github/workflows/release-pypi.yml +0 -0
- {sigit_code-1.5.10 → sigit_code-1.5.12}/.github/workflows/release-scoop.yml +0 -0
- {sigit_code-1.5.10 → sigit_code-1.5.12}/.github/workflows/release-winget.yml +0 -0
- {sigit_code-1.5.10 → sigit_code-1.5.12}/.nvmrc +0 -0
- {sigit_code-1.5.10 → sigit_code-1.5.12}/LICENSE +0 -0
- {sigit_code-1.5.10 → sigit_code-1.5.12}/docs/hooks.md +0 -0
- {sigit_code-1.5.10 → sigit_code-1.5.12}/docs/mcp.md +0 -0
- {sigit_code-1.5.10 → sigit_code-1.5.12}/examples/settings-with-hooks.toml +0 -0
- {sigit_code-1.5.10 → sigit_code-1.5.12}/examples/skills/README.md +0 -0
- {sigit_code-1.5.10 → sigit_code-1.5.12}/examples/skills/commit-message/SKILL.md +0 -0
- {sigit_code-1.5.10 → sigit_code-1.5.12}/npm/README.md.tmpl +0 -0
- {sigit_code-1.5.10 → sigit_code-1.5.12}/npm/package-compat.json.tmpl +0 -0
- {sigit_code-1.5.10 → sigit_code-1.5.12}/npm/package-main.json.tmpl +0 -0
- {sigit_code-1.5.10 → sigit_code-1.5.12}/npm/package.json.tmpl +0 -0
- {sigit_code-1.5.10 → sigit_code-1.5.12}/npm/scripts/render-main-package.cjs +0 -0
- {sigit_code-1.5.10 → sigit_code-1.5.12}/npm/scripts/render-platform-package.cjs +0 -0
- {sigit_code-1.5.10 → sigit_code-1.5.12}/npm/sigit/.gitignore +0 -0
- {sigit_code-1.5.10 → sigit_code-1.5.12}/npm/sigit/package.json +0 -0
- {sigit_code-1.5.10 → sigit_code-1.5.12}/npm/sigit/src/index.ts +0 -0
- {sigit_code-1.5.10 → sigit_code-1.5.12}/npm/sigit/tsconfig.json +0 -0
- {sigit_code-1.5.10 → sigit_code-1.5.12}/nuget/.gitignore +0 -0
- {sigit_code-1.5.10 → sigit_code-1.5.12}/nuget/sigit/Program.cs +0 -0
- {sigit_code-1.5.10 → sigit_code-1.5.12}/nuget/sigit/SiGit.Code.csproj +0 -0
- {sigit_code-1.5.10 → sigit_code-1.5.12}/packaging/aur/PKGBUILD.in +0 -0
- {sigit_code-1.5.10 → sigit_code-1.5.12}/packaging/nfpm.yaml +0 -0
- {sigit_code-1.5.10 → sigit_code-1.5.12}/packaging/winget/getSigit.siGitCode.locale.en-US.yaml.in +0 -0
- {sigit_code-1.5.10 → sigit_code-1.5.12}/packaging/winget/getSigit.siGitCode.yaml.in +0 -0
- {sigit_code-1.5.10 → sigit_code-1.5.12}/pypi/pyproject.toml +0 -0
- {sigit_code-1.5.10 → sigit_code-1.5.12}/pyproject.toml +0 -0
- {sigit_code-1.5.10 → sigit_code-1.5.12}/rust-toolchain.toml +0 -0
- {sigit_code-1.5.10 → sigit_code-1.5.12}/src/account.rs +0 -0
- {sigit_code-1.5.10 → sigit_code-1.5.12}/src/browser_auth.rs +0 -0
- {sigit_code-1.5.10 → sigit_code-1.5.12}/src/commands.rs +0 -0
- {sigit_code-1.5.10 → sigit_code-1.5.12}/src/credentials.rs +0 -0
- {sigit_code-1.5.10 → sigit_code-1.5.12}/src/frontmatter.rs +0 -0
- {sigit_code-1.5.10 → sigit_code-1.5.12}/src/hooks.rs +0 -0
- {sigit_code-1.5.10 → sigit_code-1.5.12}/src/mcp.rs +0 -0
- {sigit_code-1.5.10 → sigit_code-1.5.12}/src/models.rs +0 -0
- {sigit_code-1.5.10 → sigit_code-1.5.12}/src/provider.rs +0 -0
- {sigit_code-1.5.10 → sigit_code-1.5.12}/src/settings.rs +0 -0
- {sigit_code-1.5.10 → sigit_code-1.5.12}/src/setup.rs +0 -0
- {sigit_code-1.5.10 → sigit_code-1.5.12}/src/skills.rs +0 -0
- {sigit_code-1.5.10 → sigit_code-1.5.12}/src/subagents.rs +0 -0
- {sigit_code-1.5.10 → sigit_code-1.5.12}/tests/acp_multi_root.rs +0 -0
- {sigit_code-1.5.10 → sigit_code-1.5.12}/tests/acp_session_load.rs +0 -0
- {sigit_code-1.5.10 → sigit_code-1.5.12}/tests/acp_tool_stdin.rs +0 -0
|
@@ -111,9 +111,13 @@ The agent loop is backend-agnostic. The flow: a turn (messages + tool specs) goe
|
|
|
111
111
|
feeds results back. Neither the loop nor ACP/TUI surfaces depend on a concrete backend.
|
|
112
112
|
|
|
113
113
|
- **`src/main.rs`** — entry point, mode dispatch, the full ACP `Agent` impl (session lifecycle:
|
|
114
|
-
new/load/fork/prompt/cancel, config options, slash-command advertisement), and the `SYSTEM_PROMPT
|
|
115
|
-
|
|
116
|
-
|
|
114
|
+
new/load/fork/prompt/cancel, config options, slash-command advertisement), and the `SYSTEM_PROMPT`.
|
|
115
|
+
ACP session state owns its roots, conversation, and selected model even though the process has
|
|
116
|
+
one live backend; activating a thread parks and restores all three. Unknown session ids are
|
|
117
|
+
rejected instead of silently borrowing the active thread's cwd. Prompt cancellation is routed
|
|
118
|
+
outside `turn_lock`, which lets a client cancel the turn currently holding that lock. The
|
|
119
|
+
`SYSTEM_PROMPT` bakes in smbCloud-specific context the agent should use when the repo is clearly
|
|
120
|
+
smbCloud, and stay general otherwise.
|
|
117
121
|
- **`src/backend.rs`** — the `InferenceBackend` trait and neutral types (`ToolSpec`, `ToolCall`,
|
|
118
122
|
`ToolResult`, `TurnResult`). Two impls: `LocalBackend` (on-device via `onde::ChatEngine`) and
|
|
119
123
|
`OpenAiBackend` (any OpenAI-compatible HTTP endpoint). A `BackendError` is user-facing: the
|
|
@@ -123,6 +127,10 @@ feeds results back. Neither the loop nor ACP/TUI surfaces depend on a concrete b
|
|
|
123
127
|
endpoint can also fail *after* the response is open, reporting it as a `data:` frame holding
|
|
124
128
|
the same envelope; that frame has no `choices`, so `consume_stream` has to check for it
|
|
125
129
|
explicitly or it parses as an empty chunk and the turn ends looking like an empty answer.
|
|
130
|
+
Some models write tool calls into content as text; `src/inline_tool_calls.rs` recovers the
|
|
131
|
+
well-formed ones. A block that doesn't parse (or never closes) is dropped from both the reply
|
|
132
|
+
and history, and `OpenAiBackend::complete` retries once with a note telling the model the call
|
|
133
|
+
didn't run. Leaving the raw block in history makes the model invent `<function_results>` later.
|
|
126
134
|
- **`src/provider.rs`** — decides *which* backend serves inference. Resolution order, first match
|
|
127
135
|
wins: (1) override via `OPENAI_BASE_URL`+`OPENAI_API_KEY` or active profile in
|
|
128
136
|
`~/.config/sigit/providers.toml`; (2) siGit Code Cloud when logged in; (3) on-device.
|
|
@@ -131,7 +139,8 @@ feeds results back. Neither the loop nor ACP/TUI surfaces depend on a concrete b
|
|
|
131
139
|
`multi_edit`, `delete_file`, `run_command`, `write_todos`, `remember`. Add a tool in both the
|
|
132
140
|
spec list (`all_tools`) and the execute `match` (`execute_tool`). `run_command` also enforces
|
|
133
141
|
commit attribution: when a command creates a new commit that lacks the
|
|
134
|
-
`Co-Authored-By: siGit Code` trailer (`
|
|
142
|
+
`Co-Authored-By: siGit Code` trailer (`commit_co_author_trailer()`, which reads
|
|
143
|
+
`siGit Code v<version>-<acp|tui|headless>` from the surface `main` sets via `set_surface`), it amends the trailer in —
|
|
135
144
|
unless the commit already exists on a remote, which is never rewritten. Every child process it
|
|
136
145
|
spawns (`spawn_shell`, the `git` helpers, and `hooks.rs`) sets `stdin` to null and never
|
|
137
146
|
inherits it: in ACP mode sigit's stdin is the JSON-RPC pipe from the editor, so a command that
|
|
@@ -243,12 +252,32 @@ feeds results back. Neither the loop nor ACP/TUI surfaces depend on a concrete b
|
|
|
243
252
|
`handle_initialize` is what makes the rest of this reachable — without it Zed keeps the first
|
|
244
253
|
root, drops the others, and shows "This agent doesn't currently support multi-root workspaces".
|
|
245
254
|
The process still has one working directory, so the extra roots live in a
|
|
246
|
-
process-global here and `project_dirs()` returns cwd-first, extras after.
|
|
255
|
+
process-global here and `project_dirs()` returns cwd-first, extras after.
|
|
256
|
+
One process also serves every thread the editor has open, so that global
|
|
257
|
+
(with the cwd, the backend conversation, and the background-task owner in
|
|
258
|
+
`tools.rs`) always belongs to the *live* session: `main.rs` keeps a
|
|
259
|
+
`SessionState` per session id and `activate_session` parks the live one and
|
|
260
|
+
installs the requested one before any prompt or config change runs. Don't
|
|
261
|
+
read another session's roots from the global. Project-local
|
|
247
262
|
discovery reads it: skills, slash commands, subagent types, and instruction files all scan
|
|
248
263
|
every root. MCP is deliberately not on that list — `mcp::init` runs once at startup, before
|
|
249
264
|
any session exists, so a second root's `.sigit/mcp.toml` has nobody to tell.
|
|
250
265
|
- **`src/chat.rs`** — the Unix-only ratatui TUI. Loading-spinner phase then chat; uses
|
|
251
266
|
`tokio::select!` to multiplex terminal events with streaming tokens.
|
|
267
|
+
- **`src/headless.rs`** — non-interactive `sigit run` execution for scripts, CI, and Factory
|
|
268
|
+
clients. The legacy `-p` form reaches the same parser. Every new run gets a UUID session id;
|
|
269
|
+
`--resume <id>` restores that session through `session_store`, and `--output jsonl` emits a
|
|
270
|
+
structured session/delta/tool/result stream while logs stay on stderr. Headless permission
|
|
271
|
+
prompts collapse to denial unless the tool was pre-approved with `--allow-tool`.
|
|
272
|
+
- **`src/session_store.rs`** — durable conversations: one JSON-lines history file per session at
|
|
273
|
+
`$SIGIT_CONFIG_DIR/sessions/<id>.jsonl`, written atomically, restorable into either backend.
|
|
274
|
+
Each save also writes a `<id>.meta.json` sidecar naming the session's `cwd` and the extra roots
|
|
275
|
+
of a multi-root project. That sidecar is what makes a thread *listable*: ACP's `session/list`
|
|
276
|
+
(advertised as `sessionCapabilities.list`, handled by `handle_list_sessions` in `main.rs` — the
|
|
277
|
+
editor's "Import Threads" picker) must report an absolute `cwd` per session and may filter on
|
|
278
|
+
it, so a session without one is skipped there while still reopening by id through
|
|
279
|
+
`session/load`. Sidecars are written at save time, not at session start, so a thread nobody
|
|
280
|
+
spoke in leaves nothing behind.
|
|
252
281
|
- **`src/setup.rs`** — model cache location, local model discovery, selected-model persistence.
|
|
253
282
|
Must run (`setup_shared_model_cache`) *before* anything touches `ChatEngine`/`hf-hub`, since
|
|
254
283
|
those read env vars once at init.
|
|
@@ -322,6 +351,14 @@ GitHub release, so `release-github` builds the binaries, attaches the assets, an
|
|
|
322
351
|
is logged as a warning rather than failing the others, so an unconfigured channel does not block a
|
|
323
352
|
release. Their inputs live in `packaging/`.
|
|
324
353
|
|
|
354
|
+
The Windows binaries link the MSVC C runtime statically (`+crt-static` in `.cargo/config.toml`).
|
|
355
|
+
winget, Scoop, npm, PyPI and NuGet all ship the bare exe with no installer, so a dynamic build
|
|
356
|
+
that imports `VCRUNTIME140.dll` fails to load on a machine without the VC++ Redistributable
|
|
357
|
+
(`0xC0000135`, which is what failed winget's first validation).
|
|
358
|
+
`packaging/windows/check-static-crt.ps1` runs in CI and in `release-github` and fails the build if
|
|
359
|
+
a Windows exe imports the runtime again. Don't set a `RUSTFLAGS` env var in those workflows: it
|
|
360
|
+
replaces the config rustflags instead of adding to them.
|
|
361
|
+
|
|
325
362
|
Every release asset now carries a `.sha256` sidecar, not just the macOS Homebrew tarball. Scoop,
|
|
326
363
|
winget, and the AUR PKGBUILD each need one, and they consume the raw binaries rather than the
|
|
327
364
|
tarball. `release-github` also builds a `.deb` and `.rpm` per Linux target with nfpm
|
{sigit_code-1.5.10/.claude → sigit_code-1.5.12/.agents}/skills/agent-client-protocol/SKILL.md
RENAMED
|
@@ -196,6 +196,7 @@ the connection and the agent anymore. Don't reintroduce the mpsc forwarder patte
|
|
|
196
196
|
| `NewSessionRequest` | `handle_new_session` | sets cwd, resets history, advertises commands + config options |
|
|
197
197
|
| `LoadSessionRequest` | `handle_load_session` | like new_session; gated by `load_session(true)` capability |
|
|
198
198
|
| `ForkSessionRequest` | `handle_fork_session` | gated by `unstable_session_fork` + `SessionForkCapabilities` |
|
|
199
|
+
| `ListSessionsRequest` | `handle_list_sessions` | the editor's "Import Threads" picker; gated by `SessionListCapabilities` |
|
|
199
200
|
| `PromptRequest` | `handle_prompt` | the turn: parse blocks → slash commands or tool-calling loop |
|
|
200
201
|
| `SetSessionConfigOptionRequest` | `handle_set_session_config_option` | the Zed model picker — switches/downloads models |
|
|
201
202
|
| `CancelNotification` | `handle_cancel` | notification, no response |
|
|
@@ -226,7 +227,8 @@ Ok(InitializeResponse::new(ProtocolVersion::V1) // use V1, not args.proto
|
|
|
226
227
|
.load_session(true) // enables LoadSessionRequest
|
|
227
228
|
.session_capabilities(
|
|
228
229
|
SessionCapabilities::new()
|
|
229
|
-
.fork(SessionForkCapabilities::new())
|
|
230
|
+
.fork(SessionForkCapabilities::new()) // enables ForkSessionRequest
|
|
231
|
+
.list(SessionListCapabilities::new()), // enables ListSessionsRequest
|
|
230
232
|
),
|
|
231
233
|
)
|
|
232
234
|
.meta(initialize_meta())) // free-form Meta (see below)
|
|
@@ -573,6 +575,14 @@ Editor Agent
|
|
|
573
575
|
12. **Store `SessionId` as `SessionId`**, not `String`, so `==` is clean.
|
|
574
576
|
13. **`SetSessionConfigOptionResponse::new(config_options)`** — the response
|
|
575
577
|
carries the *rebuilt* options so the picker reflects the new current value.
|
|
578
|
+
14. **`session/list` needs a `cwd` per session, which history alone can't
|
|
579
|
+
supply.** `SessionInfo` requires an absolute `cwd` and the request may
|
|
580
|
+
filter on it, so `session_store` writes a `<id>.meta.json` sidecar next to
|
|
581
|
+
each saved thread; sessions without one are skipped by
|
|
582
|
+
`handle_list_sessions` rather than guessed at. Advertising
|
|
583
|
+
`SessionCapabilities::new().list(SessionListCapabilities::new())` is what
|
|
584
|
+
turns the editor's "Import Threads" picker from an error banner into a
|
|
585
|
+
list.
|
|
576
586
|
|
|
577
587
|
---
|
|
578
588
|
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
# Link the MSVC C runtime statically on Windows. Without this the binary
|
|
2
|
+
# imports VCRUNTIME140.dll and the UCRT api-ms-win-crt-*.dll set, and on a
|
|
3
|
+
# machine without the Visual C++ Redistributable it dies at load time with
|
|
4
|
+
# STATUS_DLL_NOT_FOUND (0xC0000135) before main runs. winget ships sigit as a
|
|
5
|
+
# portable exe, so there is no installer to bring the runtime along.
|
|
6
|
+
[target.'cfg(all(windows, target_env = "msvc"))']
|
|
7
|
+
rustflags = ["-C", "target-feature=+crt-static"]
|
{sigit_code-1.5.10/.agents → sigit_code-1.5.12/.claude}/skills/agent-client-protocol/SKILL.md
RENAMED
|
@@ -196,6 +196,7 @@ the connection and the agent anymore. Don't reintroduce the mpsc forwarder patte
|
|
|
196
196
|
| `NewSessionRequest` | `handle_new_session` | sets cwd, resets history, advertises commands + config options |
|
|
197
197
|
| `LoadSessionRequest` | `handle_load_session` | like new_session; gated by `load_session(true)` capability |
|
|
198
198
|
| `ForkSessionRequest` | `handle_fork_session` | gated by `unstable_session_fork` + `SessionForkCapabilities` |
|
|
199
|
+
| `ListSessionsRequest` | `handle_list_sessions` | the editor's "Import Threads" picker; gated by `SessionListCapabilities` |
|
|
199
200
|
| `PromptRequest` | `handle_prompt` | the turn: parse blocks → slash commands or tool-calling loop |
|
|
200
201
|
| `SetSessionConfigOptionRequest` | `handle_set_session_config_option` | the Zed model picker — switches/downloads models |
|
|
201
202
|
| `CancelNotification` | `handle_cancel` | notification, no response |
|
|
@@ -226,7 +227,8 @@ Ok(InitializeResponse::new(ProtocolVersion::V1) // use V1, not args.proto
|
|
|
226
227
|
.load_session(true) // enables LoadSessionRequest
|
|
227
228
|
.session_capabilities(
|
|
228
229
|
SessionCapabilities::new()
|
|
229
|
-
.fork(SessionForkCapabilities::new())
|
|
230
|
+
.fork(SessionForkCapabilities::new()) // enables ForkSessionRequest
|
|
231
|
+
.list(SessionListCapabilities::new()), // enables ListSessionsRequest
|
|
230
232
|
),
|
|
231
233
|
)
|
|
232
234
|
.meta(initialize_meta())) // free-form Meta (see below)
|
|
@@ -573,6 +575,14 @@ Editor Agent
|
|
|
573
575
|
12. **Store `SessionId` as `SessionId`**, not `String`, so `==` is clean.
|
|
574
576
|
13. **`SetSessionConfigOptionResponse::new(config_options)`** — the response
|
|
575
577
|
carries the *rebuilt* options so the picker reflects the new current value.
|
|
578
|
+
14. **`session/list` needs a `cwd` per session, which history alone can't
|
|
579
|
+
supply.** `SessionInfo` requires an absolute `cwd` and the request may
|
|
580
|
+
filter on it, so `session_store` writes a `<id>.meta.json` sidecar next to
|
|
581
|
+
each saved thread; sessions without one are skipped by
|
|
582
|
+
`handle_list_sessions` rather than guessed at. Advertising
|
|
583
|
+
`SessionCapabilities::new().list(SessionListCapabilities::new())` is what
|
|
584
|
+
turns the editor's "Import Threads" picker from an error banner into a
|
|
585
|
+
list.
|
|
576
586
|
|
|
577
587
|
---
|
|
578
588
|
|
|
@@ -119,3 +119,8 @@ jobs:
|
|
|
119
119
|
|
|
120
120
|
- name: Test
|
|
121
121
|
run: cargo test --locked --target ${{ matrix.target }}
|
|
122
|
+
|
|
123
|
+
- name: Check Windows binary has no VC++ runtime dependency
|
|
124
|
+
if: runner.os == 'Windows'
|
|
125
|
+
shell: pwsh
|
|
126
|
+
run: ./packaging/windows/check-static-crt.ps1 -Path target/${{ matrix.target }}/debug/sigit.exe
|
|
@@ -96,6 +96,11 @@ jobs:
|
|
|
96
96
|
shell: bash
|
|
97
97
|
run: cargo build --locked --release --target ${{ matrix.target }}
|
|
98
98
|
|
|
99
|
+
- name: Check Windows binary has no VC++ runtime dependency
|
|
100
|
+
if: contains(matrix.target, 'windows')
|
|
101
|
+
shell: pwsh
|
|
102
|
+
run: ./packaging/windows/check-static-crt.ps1 -Path target/${{ matrix.target }}/release/${{ env.PROJECT_NAME }}.exe
|
|
103
|
+
|
|
99
104
|
- name: Package binary
|
|
100
105
|
shell: bash
|
|
101
106
|
run: |
|
|
@@ -111,9 +111,13 @@ The agent loop is backend-agnostic. The flow: a turn (messages + tool specs) goe
|
|
|
111
111
|
feeds results back. Neither the loop nor ACP/TUI surfaces depend on a concrete backend.
|
|
112
112
|
|
|
113
113
|
- **`src/main.rs`** — entry point, mode dispatch, the full ACP `Agent` impl (session lifecycle:
|
|
114
|
-
new/load/fork/prompt/cancel, config options, slash-command advertisement), and the `SYSTEM_PROMPT
|
|
115
|
-
|
|
116
|
-
|
|
114
|
+
new/load/fork/prompt/cancel, config options, slash-command advertisement), and the `SYSTEM_PROMPT`.
|
|
115
|
+
ACP session state owns its roots, conversation, and selected model even though the process has
|
|
116
|
+
one live backend; activating a thread parks and restores all three. Unknown session ids are
|
|
117
|
+
rejected instead of silently borrowing the active thread's cwd. Prompt cancellation is routed
|
|
118
|
+
outside `turn_lock`, which lets a client cancel the turn currently holding that lock. The
|
|
119
|
+
`SYSTEM_PROMPT` bakes in smbCloud-specific context the agent should use when the repo is clearly
|
|
120
|
+
smbCloud, and stay general otherwise.
|
|
117
121
|
- **`src/backend.rs`** — the `InferenceBackend` trait and neutral types (`ToolSpec`, `ToolCall`,
|
|
118
122
|
`ToolResult`, `TurnResult`). Two impls: `LocalBackend` (on-device via `onde::ChatEngine`) and
|
|
119
123
|
`OpenAiBackend` (any OpenAI-compatible HTTP endpoint). A `BackendError` is user-facing: the
|
|
@@ -123,6 +127,10 @@ feeds results back. Neither the loop nor ACP/TUI surfaces depend on a concrete b
|
|
|
123
127
|
endpoint can also fail *after* the response is open, reporting it as a `data:` frame holding
|
|
124
128
|
the same envelope; that frame has no `choices`, so `consume_stream` has to check for it
|
|
125
129
|
explicitly or it parses as an empty chunk and the turn ends looking like an empty answer.
|
|
130
|
+
Some models write tool calls into content as text; `src/inline_tool_calls.rs` recovers the
|
|
131
|
+
well-formed ones. A block that doesn't parse (or never closes) is dropped from both the reply
|
|
132
|
+
and history, and `OpenAiBackend::complete` retries once with a note telling the model the call
|
|
133
|
+
didn't run. Leaving the raw block in history makes the model invent `<function_results>` later.
|
|
126
134
|
- **`src/provider.rs`** — decides *which* backend serves inference. Resolution order, first match
|
|
127
135
|
wins: (1) override via `OPENAI_BASE_URL`+`OPENAI_API_KEY` or active profile in
|
|
128
136
|
`~/.config/sigit/providers.toml`; (2) siGit Code Cloud when logged in; (3) on-device.
|
|
@@ -131,7 +139,8 @@ feeds results back. Neither the loop nor ACP/TUI surfaces depend on a concrete b
|
|
|
131
139
|
`multi_edit`, `delete_file`, `run_command`, `write_todos`, `remember`. Add a tool in both the
|
|
132
140
|
spec list (`all_tools`) and the execute `match` (`execute_tool`). `run_command` also enforces
|
|
133
141
|
commit attribution: when a command creates a new commit that lacks the
|
|
134
|
-
`Co-Authored-By: siGit Code` trailer (`
|
|
142
|
+
`Co-Authored-By: siGit Code` trailer (`commit_co_author_trailer()`, which reads
|
|
143
|
+
`siGit Code v<version>-<acp|tui|headless>` from the surface `main` sets via `set_surface`), it amends the trailer in —
|
|
135
144
|
unless the commit already exists on a remote, which is never rewritten. Every child process it
|
|
136
145
|
spawns (`spawn_shell`, the `git` helpers, and `hooks.rs`) sets `stdin` to null and never
|
|
137
146
|
inherits it: in ACP mode sigit's stdin is the JSON-RPC pipe from the editor, so a command that
|
|
@@ -243,12 +252,32 @@ feeds results back. Neither the loop nor ACP/TUI surfaces depend on a concrete b
|
|
|
243
252
|
`handle_initialize` is what makes the rest of this reachable — without it Zed keeps the first
|
|
244
253
|
root, drops the others, and shows "This agent doesn't currently support multi-root workspaces".
|
|
245
254
|
The process still has one working directory, so the extra roots live in a
|
|
246
|
-
process-global here and `project_dirs()` returns cwd-first, extras after.
|
|
255
|
+
process-global here and `project_dirs()` returns cwd-first, extras after.
|
|
256
|
+
One process also serves every thread the editor has open, so that global
|
|
257
|
+
(with the cwd, the backend conversation, and the background-task owner in
|
|
258
|
+
`tools.rs`) always belongs to the *live* session: `main.rs` keeps a
|
|
259
|
+
`SessionState` per session id and `activate_session` parks the live one and
|
|
260
|
+
installs the requested one before any prompt or config change runs. Don't
|
|
261
|
+
read another session's roots from the global. Project-local
|
|
247
262
|
discovery reads it: skills, slash commands, subagent types, and instruction files all scan
|
|
248
263
|
every root. MCP is deliberately not on that list — `mcp::init` runs once at startup, before
|
|
249
264
|
any session exists, so a second root's `.sigit/mcp.toml` has nobody to tell.
|
|
250
265
|
- **`src/chat.rs`** — the Unix-only ratatui TUI. Loading-spinner phase then chat; uses
|
|
251
266
|
`tokio::select!` to multiplex terminal events with streaming tokens.
|
|
267
|
+
- **`src/headless.rs`** — non-interactive `sigit run` execution for scripts, CI, and Factory
|
|
268
|
+
clients. The legacy `-p` form reaches the same parser. Every new run gets a UUID session id;
|
|
269
|
+
`--resume <id>` restores that session through `session_store`, and `--output jsonl` emits a
|
|
270
|
+
structured session/delta/tool/result stream while logs stay on stderr. Headless permission
|
|
271
|
+
prompts collapse to denial unless the tool was pre-approved with `--allow-tool`.
|
|
272
|
+
- **`src/session_store.rs`** — durable conversations: one JSON-lines history file per session at
|
|
273
|
+
`$SIGIT_CONFIG_DIR/sessions/<id>.jsonl`, written atomically, restorable into either backend.
|
|
274
|
+
Each save also writes a `<id>.meta.json` sidecar naming the session's `cwd` and the extra roots
|
|
275
|
+
of a multi-root project. That sidecar is what makes a thread *listable*: ACP's `session/list`
|
|
276
|
+
(advertised as `sessionCapabilities.list`, handled by `handle_list_sessions` in `main.rs` — the
|
|
277
|
+
editor's "Import Threads" picker) must report an absolute `cwd` per session and may filter on
|
|
278
|
+
it, so a session without one is skipped there while still reopening by id through
|
|
279
|
+
`session/load`. Sidecars are written at save time, not at session start, so a thread nobody
|
|
280
|
+
spoke in leaves nothing behind.
|
|
252
281
|
- **`src/setup.rs`** — model cache location, local model discovery, selected-model persistence.
|
|
253
282
|
Must run (`setup_shared_model_cache`) *before* anything touches `ChatEngine`/`hf-hub`, since
|
|
254
283
|
those read env vars once at init.
|
|
@@ -322,6 +351,14 @@ GitHub release, so `release-github` builds the binaries, attaches the assets, an
|
|
|
322
351
|
is logged as a warning rather than failing the others, so an unconfigured channel does not block a
|
|
323
352
|
release. Their inputs live in `packaging/`.
|
|
324
353
|
|
|
354
|
+
The Windows binaries link the MSVC C runtime statically (`+crt-static` in `.cargo/config.toml`).
|
|
355
|
+
winget, Scoop, npm, PyPI and NuGet all ship the bare exe with no installer, so a dynamic build
|
|
356
|
+
that imports `VCRUNTIME140.dll` fails to load on a machine without the VC++ Redistributable
|
|
357
|
+
(`0xC0000135`, which is what failed winget's first validation).
|
|
358
|
+
`packaging/windows/check-static-crt.ps1` runs in CI and in `release-github` and fails the build if
|
|
359
|
+
a Windows exe imports the runtime again. Don't set a `RUSTFLAGS` env var in those workflows: it
|
|
360
|
+
replaces the config rustflags instead of adding to them.
|
|
361
|
+
|
|
325
362
|
Every release asset now carries a `.sha256` sidecar, not just the macOS Homebrew tarball. Scoop,
|
|
326
363
|
winget, and the AUR PKGBUILD each need one, and they consume the raw binaries rather than the
|
|
327
364
|
tarball. `release-github` also builds a `.deb` and `.rpm` per Linux target with nfpm
|
|
@@ -1,5 +1,133 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 1.5.12
|
|
4
|
+
|
|
5
|
+
### Fixed
|
|
6
|
+
|
|
7
|
+
- **The Windows binaries start on machines without the Visual C++
|
|
8
|
+
Redistributable.** They used to import `VCRUNTIME140.dll` and the UCRT
|
|
9
|
+
`api-ms-win-crt-*` DLLs, so a clean Windows install refused to load them
|
|
10
|
+
with `STATUS_DLL_NOT_FOUND` (0xC0000135). That is what failed winget's
|
|
11
|
+
post-install check. The C runtime is now linked statically, and CI and the
|
|
12
|
+
release build fail if a Windows exe picks up that dependency again.
|
|
13
|
+
|
|
14
|
+
- **Watching a slow background command no longer ends the turn early.**
|
|
15
|
+
Polling `command_output` on the same task id three times tripped the
|
|
16
|
+
repeated-tool-call guard, which refused the call and dropped tools for the
|
|
17
|
+
rest of the turn. `command_output` now long-polls — it waits up to
|
|
18
|
+
`wait_seconds` (default 10, max 30) for the task to exit, then returns
|
|
19
|
+
everything printed in the meantime — and the repeat guard exempts it, since
|
|
20
|
+
polling the same task is the whole point of the tool.
|
|
21
|
+
|
|
22
|
+
- **A turn that ends with no visible text says why.** When the
|
|
23
|
+
repeated-tool-call guard blocked a call and the forced no-tools round came
|
|
24
|
+
back empty, sigit sent nothing more — the turn just stopped with no answer
|
|
25
|
+
and no question. When the last round of a tool-using turn produces no
|
|
26
|
+
visible text, sigit now sends a short closing message naming the repeated
|
|
27
|
+
tool and asking you to reply "continue" or redirect.
|
|
28
|
+
|
|
29
|
+
## 1.5.11
|
|
30
|
+
|
|
31
|
+
### Added
|
|
32
|
+
|
|
33
|
+
- **`sigit run` drives the agent headlessly with resumable sessions.** A new
|
|
34
|
+
non-interactive subcommand runs a prompt through the same agent loop as the
|
|
35
|
+
editor and terminal surfaces, for scripts, CI, and Factory clients. Every run
|
|
36
|
+
gets a UUID session id, writes a JSON-lines history file under
|
|
37
|
+
`~/.config/sigit/sessions/`, and can be restored with `--resume <id>`.
|
|
38
|
+
`--output jsonl` emits a structured session/delta/tool/result stream on
|
|
39
|
+
stdout while logs stay on stderr, and `--allow-tool` pre-approves a tool so
|
|
40
|
+
permission prompts collapse to denial in a non-interactive context. The
|
|
41
|
+
legacy `-p` form still works. Each run also rewrites the session metadata
|
|
42
|
+
with its own cwd and extra roots, so resuming keeps multi-root projects
|
|
43
|
+
|
|
44
|
+
- **Saved threads can be imported into the editor.** siGit Code now advertises
|
|
45
|
+
ACP's `sessionCapabilities.list` and answers `session/list`, so Zed's "Import
|
|
46
|
+
Threads" picker offers the conversations stored under
|
|
47
|
+
`~/.config/sigit/sessions/` instead of reporting that the agent doesn't
|
|
48
|
+
support the capability. A saved session gets a sidecar recording the project
|
|
49
|
+
directory it ran in — listing reports that `cwd`, the extra roots of a
|
|
50
|
+
multi-root project, an ISO 8601 last-activity timestamp, and a title taken
|
|
51
|
+
from the first user message — and a request may filter on `cwd` so one
|
|
52
|
+
project is never offered another's threads. Threads saved before this have no
|
|
53
|
+
sidecar and are not listed; they still reopen by id through `session/load`
|
|
54
|
+
|
|
55
|
+
### Changed
|
|
56
|
+
|
|
57
|
+
- **The commit trailer names the siGit Code version and surface.** Commits
|
|
58
|
+
siGit Code makes now end with
|
|
59
|
+
`Co-Authored-By: siGit Code v<version>-<surface> <noreply@sigit.si>` instead
|
|
60
|
+
of the bare name, where the surface is `acp` (an editor), `tui` (the
|
|
61
|
+
terminal UI), or `headless` (`sigit run`). The model changes from session to
|
|
62
|
+
session; the version and surface tell you which build of the agent wrote the
|
|
63
|
+
commit and how it was driven. GitHub still credits the co-author, since it
|
|
64
|
+
matches on the address. A commit that already carries a siGit Code trailer
|
|
65
|
+
from an older version is left alone
|
|
66
|
+
|
|
67
|
+
- **The terminal UI's model knows which directory the project is in.** The
|
|
68
|
+
editor (ACP) and headless paths put the working directory in the system
|
|
69
|
+
prompt, but the terminal UI only added the project's instruction files, so
|
|
70
|
+
on `/init` a small on-device model invented a `AGENTS.md` path and failed.
|
|
71
|
+
All three places the terminal UI builds a prompt now go through the same
|
|
72
|
+
session context path the ACP sessions get. The cloud tier switch had also
|
|
73
|
+
been dropping the instruction files; that's fixed too
|
|
74
|
+
|
|
75
|
+
- **An empty `write_todos` list clears the plan.** `write_todos` rejected an
|
|
76
|
+
empty list, so the model had no way to clear a finished checklist and the
|
|
77
|
+
last plan stayed in the editor until the session ended. An empty list now
|
|
78
|
+
returns "Task list cleared." and goes to the client as an ACP plan with no
|
|
79
|
+
entries. The tool description tells the model it can do this
|
|
80
|
+
|
|
81
|
+
- **`sigit run` gives clearer usage errors.** A second positional prompt says
|
|
82
|
+
"unexpected extra argument", a bare `sigit run` says "missing prompt", and a
|
|
83
|
+
mistyped flag like `--quite` is rejected instead of becoming the prompt
|
|
84
|
+
|
|
85
|
+
### Fixed
|
|
86
|
+
|
|
87
|
+
- **Each ACP session keeps its own roots, conversation, and tasks.** Zed runs
|
|
88
|
+
one siGit process for every open thread, but the process had a single cwd,
|
|
89
|
+
workspace root list, backend conversation, and background task table. The
|
|
90
|
+
most recent session owned all of them, so a prompt from an older thread ran
|
|
91
|
+
against another repo with another thread's history. A `SessionState` is now
|
|
92
|
+
kept per session id; before a prompt or config change runs, the live
|
|
93
|
+
conversation is parked and the requested session's cwd, extra roots, and
|
|
94
|
+
conversation are installed, rebuilding the system prompt from its roots.
|
|
95
|
+
`new`/`load`/`fork` share a single session-opening path, and fork carries the
|
|
96
|
+
source thread's conversation. Background tasks are scoped to the session that
|
|
97
|
+
started them, opening a session no longer wipes every other session's
|
|
98
|
+
permission grants, and model selection is routed per session
|
|
99
|
+
|
|
100
|
+
- **New sessions no longer carry the previous thread's history.** Opening a
|
|
101
|
+
new thread in Zed showed a `[Conversation summary]` from an earlier session.
|
|
102
|
+
The session handlers cleared the on-device engine but not the history a cloud
|
|
103
|
+
backend keeps for itself, and the startup routing to the cloud tier then
|
|
104
|
+
carried that history into the installed backend. A provider override had the
|
|
105
|
+
same leak. All session entry points now share a path that strips stale
|
|
106
|
+
history too, and unknown session ids are rejected instead of borrowing the
|
|
107
|
+
live thread's state
|
|
108
|
+
|
|
109
|
+
- **Unparseable tool-call markup is hidden and retried, not shown as text.**
|
|
110
|
+
Some models write tool calls into the reply as text. Well-formed blocks were
|
|
111
|
+
already recovered and run, but a block that failed to parse or never closed
|
|
112
|
+
was printed to the editor as-is and stayed in history, so the model later
|
|
113
|
+
read back a call it had "made" with no result and began writing invented
|
|
114
|
+
`<function_results>`. The scanner now reports those blocks as malformed; the
|
|
115
|
+
backend drops them from the reply and history, and when the only tool call
|
|
116
|
+
was malformed the model gets one retry telling it the call didn't run. A
|
|
117
|
+
block that merely *mentions* a tool-call marker (a backticked `<tool_call>` or an
|
|
118
|
+
unclosed XTML `<|open|>tools`) is now kept as prose, so a reply explaining
|
|
119
|
+
the scanner no longer loses everything after the first marker. The
|
|
120
|
+
non-streamed path now strips broken blocks beside structured calls and runs
|
|
121
|
+
any inline calls that did parse, matching the streaming path
|
|
122
|
+
|
|
123
|
+
- **The co-author trailer ends a conflicted merge commit.** Finishing a
|
|
124
|
+
conflicted merge with `git commit --no-edit` keeps git's `# Conflicts:` list
|
|
125
|
+
in the message, since no editor runs to strip it. When siGit Code then added
|
|
126
|
+
its trailer, the trailer went in above that list, so it was no longer the last
|
|
127
|
+
paragraph and GitHub didn't credit the co-author. The amend now drops the
|
|
128
|
+
leftover comment block and puts the trailer last. It also fixes a commit
|
|
129
|
+
that already has the trailer but still ends in that block
|
|
130
|
+
|
|
3
131
|
## 1.5.10
|
|
4
132
|
|
|
5
133
|
### What changed
|
|
@@ -111,9 +111,13 @@ The agent loop is backend-agnostic. The flow: a turn (messages + tool specs) goe
|
|
|
111
111
|
feeds results back. Neither the loop nor ACP/TUI surfaces depend on a concrete backend.
|
|
112
112
|
|
|
113
113
|
- **`src/main.rs`** — entry point, mode dispatch, the full ACP `Agent` impl (session lifecycle:
|
|
114
|
-
new/load/fork/prompt/cancel, config options, slash-command advertisement), and the `SYSTEM_PROMPT
|
|
115
|
-
|
|
116
|
-
|
|
114
|
+
new/load/fork/prompt/cancel, config options, slash-command advertisement), and the `SYSTEM_PROMPT`.
|
|
115
|
+
ACP session state owns its roots, conversation, and selected model even though the process has
|
|
116
|
+
one live backend; activating a thread parks and restores all three. Unknown session ids are
|
|
117
|
+
rejected instead of silently borrowing the active thread's cwd. Prompt cancellation is routed
|
|
118
|
+
outside `turn_lock`, which lets a client cancel the turn currently holding that lock. The
|
|
119
|
+
`SYSTEM_PROMPT` bakes in smbCloud-specific context the agent should use when the repo is clearly
|
|
120
|
+
smbCloud, and stay general otherwise.
|
|
117
121
|
- **`src/backend.rs`** — the `InferenceBackend` trait and neutral types (`ToolSpec`, `ToolCall`,
|
|
118
122
|
`ToolResult`, `TurnResult`). Two impls: `LocalBackend` (on-device via `onde::ChatEngine`) and
|
|
119
123
|
`OpenAiBackend` (any OpenAI-compatible HTTP endpoint). A `BackendError` is user-facing: the
|
|
@@ -123,6 +127,10 @@ feeds results back. Neither the loop nor ACP/TUI surfaces depend on a concrete b
|
|
|
123
127
|
endpoint can also fail *after* the response is open, reporting it as a `data:` frame holding
|
|
124
128
|
the same envelope; that frame has no `choices`, so `consume_stream` has to check for it
|
|
125
129
|
explicitly or it parses as an empty chunk and the turn ends looking like an empty answer.
|
|
130
|
+
Some models write tool calls into content as text; `src/inline_tool_calls.rs` recovers the
|
|
131
|
+
well-formed ones. A block that doesn't parse (or never closes) is dropped from both the reply
|
|
132
|
+
and history, and `OpenAiBackend::complete` retries once with a note telling the model the call
|
|
133
|
+
didn't run. Leaving the raw block in history makes the model invent `<function_results>` later.
|
|
126
134
|
- **`src/provider.rs`** — decides *which* backend serves inference. Resolution order, first match
|
|
127
135
|
wins: (1) override via `OPENAI_BASE_URL`+`OPENAI_API_KEY` or active profile in
|
|
128
136
|
`~/.config/sigit/providers.toml`; (2) siGit Code Cloud when logged in; (3) on-device.
|
|
@@ -131,7 +139,8 @@ feeds results back. Neither the loop nor ACP/TUI surfaces depend on a concrete b
|
|
|
131
139
|
`multi_edit`, `delete_file`, `run_command`, `write_todos`, `remember`. Add a tool in both the
|
|
132
140
|
spec list (`all_tools`) and the execute `match` (`execute_tool`). `run_command` also enforces
|
|
133
141
|
commit attribution: when a command creates a new commit that lacks the
|
|
134
|
-
`Co-Authored-By: siGit Code` trailer (`
|
|
142
|
+
`Co-Authored-By: siGit Code` trailer (`commit_co_author_trailer()`, which reads
|
|
143
|
+
`siGit Code v<version>-<acp|tui|headless>` from the surface `main` sets via `set_surface`), it amends the trailer in —
|
|
135
144
|
unless the commit already exists on a remote, which is never rewritten. Every child process it
|
|
136
145
|
spawns (`spawn_shell`, the `git` helpers, and `hooks.rs`) sets `stdin` to null and never
|
|
137
146
|
inherits it: in ACP mode sigit's stdin is the JSON-RPC pipe from the editor, so a command that
|
|
@@ -243,12 +252,32 @@ feeds results back. Neither the loop nor ACP/TUI surfaces depend on a concrete b
|
|
|
243
252
|
`handle_initialize` is what makes the rest of this reachable — without it Zed keeps the first
|
|
244
253
|
root, drops the others, and shows "This agent doesn't currently support multi-root workspaces".
|
|
245
254
|
The process still has one working directory, so the extra roots live in a
|
|
246
|
-
process-global here and `project_dirs()` returns cwd-first, extras after.
|
|
255
|
+
process-global here and `project_dirs()` returns cwd-first, extras after.
|
|
256
|
+
One process also serves every thread the editor has open, so that global
|
|
257
|
+
(with the cwd, the backend conversation, and the background-task owner in
|
|
258
|
+
`tools.rs`) always belongs to the *live* session: `main.rs` keeps a
|
|
259
|
+
`SessionState` per session id and `activate_session` parks the live one and
|
|
260
|
+
installs the requested one before any prompt or config change runs. Don't
|
|
261
|
+
read another session's roots from the global. Project-local
|
|
247
262
|
discovery reads it: skills, slash commands, subagent types, and instruction files all scan
|
|
248
263
|
every root. MCP is deliberately not on that list — `mcp::init` runs once at startup, before
|
|
249
264
|
any session exists, so a second root's `.sigit/mcp.toml` has nobody to tell.
|
|
250
265
|
- **`src/chat.rs`** — the Unix-only ratatui TUI. Loading-spinner phase then chat; uses
|
|
251
266
|
`tokio::select!` to multiplex terminal events with streaming tokens.
|
|
267
|
+
- **`src/headless.rs`** — non-interactive `sigit run` execution for scripts, CI, and Factory
|
|
268
|
+
clients. The legacy `-p` form reaches the same parser. Every new run gets a UUID session id;
|
|
269
|
+
`--resume <id>` restores that session through `session_store`, and `--output jsonl` emits a
|
|
270
|
+
structured session/delta/tool/result stream while logs stay on stderr. Headless permission
|
|
271
|
+
prompts collapse to denial unless the tool was pre-approved with `--allow-tool`.
|
|
272
|
+
- **`src/session_store.rs`** — durable conversations: one JSON-lines history file per session at
|
|
273
|
+
`$SIGIT_CONFIG_DIR/sessions/<id>.jsonl`, written atomically, restorable into either backend.
|
|
274
|
+
Each save also writes a `<id>.meta.json` sidecar naming the session's `cwd` and the extra roots
|
|
275
|
+
of a multi-root project. That sidecar is what makes a thread *listable*: ACP's `session/list`
|
|
276
|
+
(advertised as `sessionCapabilities.list`, handled by `handle_list_sessions` in `main.rs` — the
|
|
277
|
+
editor's "Import Threads" picker) must report an absolute `cwd` per session and may filter on
|
|
278
|
+
it, so a session without one is skipped there while still reopening by id through
|
|
279
|
+
`session/load`. Sidecars are written at save time, not at session start, so a thread nobody
|
|
280
|
+
spoke in leaves nothing behind.
|
|
252
281
|
- **`src/setup.rs`** — model cache location, local model discovery, selected-model persistence.
|
|
253
282
|
Must run (`setup_shared_model_cache`) *before* anything touches `ChatEngine`/`hf-hub`, since
|
|
254
283
|
those read env vars once at init.
|
|
@@ -322,6 +351,14 @@ GitHub release, so `release-github` builds the binaries, attaches the assets, an
|
|
|
322
351
|
is logged as a warning rather than failing the others, so an unconfigured channel does not block a
|
|
323
352
|
release. Their inputs live in `packaging/`.
|
|
324
353
|
|
|
354
|
+
The Windows binaries link the MSVC C runtime statically (`+crt-static` in `.cargo/config.toml`).
|
|
355
|
+
winget, Scoop, npm, PyPI and NuGet all ship the bare exe with no installer, so a dynamic build
|
|
356
|
+
that imports `VCRUNTIME140.dll` fails to load on a machine without the VC++ Redistributable
|
|
357
|
+
(`0xC0000135`, which is what failed winget's first validation).
|
|
358
|
+
`packaging/windows/check-static-crt.ps1` runs in CI and in `release-github` and fails the build if
|
|
359
|
+
a Windows exe imports the runtime again. Don't set a `RUSTFLAGS` env var in those workflows: it
|
|
360
|
+
replaces the config rustflags instead of adding to them.
|
|
361
|
+
|
|
325
362
|
Every release asset now carries a `.sha256` sidecar, not just the macOS Homebrew tarball. Scoop,
|
|
326
363
|
winget, and the AUR PKGBUILD each need one, and they consume the raw binaries rather than the
|
|
327
364
|
tarball. `release-github` also builds a `.deb` and `.rpm` per Linux target with nfpm
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: sigit-code
|
|
3
|
-
Version: 1.5.
|
|
3
|
+
Version: 1.5.12
|
|
4
4
|
Classifier: Development Status :: 4 - Beta
|
|
5
5
|
Classifier: Environment :: Console
|
|
6
6
|
Classifier: Intended Audience :: Developers
|
|
@@ -57,7 +57,8 @@ This installs a native `sigit` binary for your platform. You do not need a compi
|
|
|
57
57
|
sigit
|
|
58
58
|
```
|
|
59
59
|
|
|
60
|
-
That opens the local chat UI.
|
|
60
|
+
That opens the local chat UI. Editors drive the same binary in ACP mode, which
|
|
61
|
+
needs the `--acp` argument.
|
|
61
62
|
|
|
62
63
|
### Zed
|
|
63
64
|
|
|
@@ -68,7 +69,8 @@ siGit Code works as an [ACP-compatible](https://github.com/nicobailon/agent-clie
|
|
|
68
69
|
"agent_servers": {
|
|
69
70
|
"siGit Code": {
|
|
70
71
|
"type": "custom",
|
|
71
|
-
"command": "/absolute/path/to/sigit"
|
|
72
|
+
"command": "/absolute/path/to/sigit",
|
|
73
|
+
"args": ["--acp"]
|
|
72
74
|
}
|
|
73
75
|
}
|
|
74
76
|
}
|