sigit-code 1.5.12__tar.gz → 1.6.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 (99) hide show
  1. {sigit_code-1.5.12 → sigit_code-1.6.0}/.agents/AGENTS.md +27 -8
  2. {sigit_code-1.5.12/.claude → sigit_code-1.6.0/.agents}/skills/agent-client-protocol/SKILL.md +17 -12
  3. {sigit_code-1.5.12 → sigit_code-1.6.0}/.agents/skills/sigit-code-release/SKILL.md +2 -0
  4. {sigit_code-1.5.12/.agents → sigit_code-1.6.0/.claude}/skills/agent-client-protocol/SKILL.md +17 -12
  5. {sigit_code-1.5.12 → sigit_code-1.6.0}/.claude/skills/sigit-code-release/SKILL.md +2 -0
  6. {sigit_code-1.5.12 → sigit_code-1.6.0}/AGENTS.md +27 -8
  7. {sigit_code-1.5.12 → sigit_code-1.6.0}/CHANGELOG.md +71 -0
  8. {sigit_code-1.5.12 → sigit_code-1.6.0}/CLAUDE.md +27 -8
  9. {sigit_code-1.5.12 → sigit_code-1.6.0}/Cargo.lock +8 -8
  10. {sigit_code-1.5.12 → sigit_code-1.6.0}/Cargo.toml +2 -2
  11. {sigit_code-1.5.12 → sigit_code-1.6.0}/PKG-INFO +1 -1
  12. {sigit_code-1.5.12 → sigit_code-1.6.0}/src/backend.rs +689 -72
  13. {sigit_code-1.5.12 → sigit_code-1.6.0}/src/main.rs +255 -66
  14. {sigit_code-1.5.12 → sigit_code-1.6.0}/src/mcp.rs +239 -69
  15. {sigit_code-1.5.12 → sigit_code-1.6.0}/src/provider.rs +16 -1
  16. {sigit_code-1.5.12 → sigit_code-1.6.0}/src/tools.rs +176 -7
  17. {sigit_code-1.5.12 → sigit_code-1.6.0}/tests/acp_endpoint_errors.rs +14 -11
  18. {sigit_code-1.5.12 → sigit_code-1.6.0}/tests/acp_session_load.rs +83 -0
  19. {sigit_code-1.5.12 → sigit_code-1.6.0}/.agents/skills/ai-assisted-coding/SKILL.md +0 -0
  20. {sigit_code-1.5.12 → sigit_code-1.6.0}/.agents/skills/branding/SKILL.md +0 -0
  21. {sigit_code-1.5.12 → sigit_code-1.6.0}/.agents/skills/run-sigit/SKILL.md +0 -0
  22. {sigit_code-1.5.12 → sigit_code-1.6.0}/.agents/skills/run-sigit/driver.mjs +0 -0
  23. {sigit_code-1.5.12 → sigit_code-1.6.0}/.agents/skills/run-sigit/tui-smoke.sh +0 -0
  24. {sigit_code-1.5.12 → sigit_code-1.6.0}/.agents/skills/tool-calling/SKILL.md +0 -0
  25. {sigit_code-1.5.12 → sigit_code-1.6.0}/.cargo/config.toml +0 -0
  26. {sigit_code-1.5.12 → sigit_code-1.6.0}/.claude/skills/ai-assisted-coding/SKILL.md +0 -0
  27. {sigit_code-1.5.12 → sigit_code-1.6.0}/.claude/skills/branding/SKILL.md +0 -0
  28. {sigit_code-1.5.12 → sigit_code-1.6.0}/.claude/skills/run-sigit/SKILL.md +0 -0
  29. {sigit_code-1.5.12 → sigit_code-1.6.0}/.claude/skills/run-sigit/driver.mjs +0 -0
  30. {sigit_code-1.5.12 → sigit_code-1.6.0}/.claude/skills/run-sigit/tui-smoke.sh +0 -0
  31. {sigit_code-1.5.12 → sigit_code-1.6.0}/.claude/skills/tool-calling/SKILL.md +0 -0
  32. {sigit_code-1.5.12 → sigit_code-1.6.0}/.github/workflows/ci.yml +0 -0
  33. {sigit_code-1.5.12 → sigit_code-1.6.0}/.github/workflows/release-aur.yml +0 -0
  34. {sigit_code-1.5.12 → sigit_code-1.6.0}/.github/workflows/release-crates.yml +0 -0
  35. {sigit_code-1.5.12 → sigit_code-1.6.0}/.github/workflows/release-github.yml +0 -0
  36. {sigit_code-1.5.12 → sigit_code-1.6.0}/.github/workflows/release-homebrew.yml +0 -0
  37. {sigit_code-1.5.12 → sigit_code-1.6.0}/.github/workflows/release-npm.yml +0 -0
  38. {sigit_code-1.5.12 → sigit_code-1.6.0}/.github/workflows/release-nuget.yml +0 -0
  39. {sigit_code-1.5.12 → sigit_code-1.6.0}/.github/workflows/release-pypi.yml +0 -0
  40. {sigit_code-1.5.12 → sigit_code-1.6.0}/.github/workflows/release-scoop.yml +0 -0
  41. {sigit_code-1.5.12 → sigit_code-1.6.0}/.github/workflows/release-winget.yml +0 -0
  42. {sigit_code-1.5.12 → sigit_code-1.6.0}/.gitignore +0 -0
  43. {sigit_code-1.5.12 → sigit_code-1.6.0}/.nvmrc +0 -0
  44. {sigit_code-1.5.12 → sigit_code-1.6.0}/LICENSE +0 -0
  45. {sigit_code-1.5.12 → sigit_code-1.6.0}/README.md +0 -0
  46. {sigit_code-1.5.12 → sigit_code-1.6.0}/docs/headless.md +0 -0
  47. {sigit_code-1.5.12 → sigit_code-1.6.0}/docs/hooks.md +0 -0
  48. {sigit_code-1.5.12 → sigit_code-1.6.0}/docs/mcp.md +0 -0
  49. {sigit_code-1.5.12 → sigit_code-1.6.0}/examples/settings-with-hooks.toml +0 -0
  50. {sigit_code-1.5.12 → sigit_code-1.6.0}/examples/skills/README.md +0 -0
  51. {sigit_code-1.5.12 → sigit_code-1.6.0}/examples/skills/commit-message/SKILL.md +0 -0
  52. {sigit_code-1.5.12 → sigit_code-1.6.0}/npm/README.md.tmpl +0 -0
  53. {sigit_code-1.5.12 → sigit_code-1.6.0}/npm/package-compat.json.tmpl +0 -0
  54. {sigit_code-1.5.12 → sigit_code-1.6.0}/npm/package-main.json.tmpl +0 -0
  55. {sigit_code-1.5.12 → sigit_code-1.6.0}/npm/package.json.tmpl +0 -0
  56. {sigit_code-1.5.12 → sigit_code-1.6.0}/npm/scripts/render-main-package.cjs +0 -0
  57. {sigit_code-1.5.12 → sigit_code-1.6.0}/npm/scripts/render-platform-package.cjs +0 -0
  58. {sigit_code-1.5.12 → sigit_code-1.6.0}/npm/sigit/.gitignore +0 -0
  59. {sigit_code-1.5.12 → sigit_code-1.6.0}/npm/sigit/README.md +0 -0
  60. {sigit_code-1.5.12 → sigit_code-1.6.0}/npm/sigit/package.json +0 -0
  61. {sigit_code-1.5.12 → sigit_code-1.6.0}/npm/sigit/src/index.ts +0 -0
  62. {sigit_code-1.5.12 → sigit_code-1.6.0}/npm/sigit/tsconfig.json +0 -0
  63. {sigit_code-1.5.12 → sigit_code-1.6.0}/nuget/.gitignore +0 -0
  64. {sigit_code-1.5.12 → sigit_code-1.6.0}/nuget/sigit/Program.cs +0 -0
  65. {sigit_code-1.5.12 → sigit_code-1.6.0}/nuget/sigit/README.md +0 -0
  66. {sigit_code-1.5.12 → sigit_code-1.6.0}/nuget/sigit/SiGit.Code.csproj +0 -0
  67. {sigit_code-1.5.12 → sigit_code-1.6.0}/packaging/aur/PKGBUILD.in +0 -0
  68. {sigit_code-1.5.12 → sigit_code-1.6.0}/packaging/nfpm.yaml +0 -0
  69. {sigit_code-1.5.12 → sigit_code-1.6.0}/packaging/windows/check-static-crt.ps1 +0 -0
  70. {sigit_code-1.5.12 → sigit_code-1.6.0}/packaging/winget/getSigit.siGitCode.installer.yaml.in +0 -0
  71. {sigit_code-1.5.12 → sigit_code-1.6.0}/packaging/winget/getSigit.siGitCode.locale.en-US.yaml.in +0 -0
  72. {sigit_code-1.5.12 → sigit_code-1.6.0}/packaging/winget/getSigit.siGitCode.yaml.in +0 -0
  73. {sigit_code-1.5.12 → sigit_code-1.6.0}/pypi/README.md +0 -0
  74. {sigit_code-1.5.12 → sigit_code-1.6.0}/pypi/pyproject.toml +0 -0
  75. {sigit_code-1.5.12 → sigit_code-1.6.0}/pyproject.toml +0 -0
  76. {sigit_code-1.5.12 → sigit_code-1.6.0}/rust-toolchain.toml +0 -0
  77. {sigit_code-1.5.12 → sigit_code-1.6.0}/src/account.rs +0 -0
  78. {sigit_code-1.5.12 → sigit_code-1.6.0}/src/browser_auth.rs +0 -0
  79. {sigit_code-1.5.12 → sigit_code-1.6.0}/src/chat.rs +0 -0
  80. {sigit_code-1.5.12 → sigit_code-1.6.0}/src/commands.rs +0 -0
  81. {sigit_code-1.5.12 → sigit_code-1.6.0}/src/credentials.rs +0 -0
  82. {sigit_code-1.5.12 → sigit_code-1.6.0}/src/frontmatter.rs +0 -0
  83. {sigit_code-1.5.12 → sigit_code-1.6.0}/src/headless.rs +0 -0
  84. {sigit_code-1.5.12 → sigit_code-1.6.0}/src/hooks.rs +0 -0
  85. {sigit_code-1.5.12 → sigit_code-1.6.0}/src/inline_tool_calls.rs +0 -0
  86. {sigit_code-1.5.12 → sigit_code-1.6.0}/src/instructions.rs +0 -0
  87. {sigit_code-1.5.12 → sigit_code-1.6.0}/src/models.rs +0 -0
  88. {sigit_code-1.5.12 → sigit_code-1.6.0}/src/permissions.rs +0 -0
  89. {sigit_code-1.5.12 → sigit_code-1.6.0}/src/session_store.rs +0 -0
  90. {sigit_code-1.5.12 → sigit_code-1.6.0}/src/settings.rs +0 -0
  91. {sigit_code-1.5.12 → sigit_code-1.6.0}/src/setup.rs +0 -0
  92. {sigit_code-1.5.12 → sigit_code-1.6.0}/src/skills.rs +0 -0
  93. {sigit_code-1.5.12 → sigit_code-1.6.0}/src/subagents.rs +0 -0
  94. {sigit_code-1.5.12 → sigit_code-1.6.0}/src/workspace.rs +0 -0
  95. {sigit_code-1.5.12 → sigit_code-1.6.0}/tests/acp_multi_root.rs +0 -0
  96. {sigit_code-1.5.12 → sigit_code-1.6.0}/tests/acp_permissions.rs +0 -0
  97. {sigit_code-1.5.12 → sigit_code-1.6.0}/tests/acp_session_list.rs +0 -0
  98. {sigit_code-1.5.12 → sigit_code-1.6.0}/tests/acp_tool_stdin.rs +0 -0
  99. {sigit_code-1.5.12 → sigit_code-1.6.0}/tests/headless_mode.rs +0 -0
@@ -225,6 +225,17 @@ feeds results back. Neither the loop nor ACP/TUI surfaces depend on a concrete b
225
225
  it's a remote server, the registry's URL-match rule forces a domain namespace (`si.sigit` ↔
226
226
  `sigit.si`) verified by a DNS TXT record, not the GitHub-OIDC scheme `smbcloud-cli` uses for its
227
227
  package listing.
228
+ Separate from all of the above are the servers an ACP client passes in `mcpServers` on
229
+ `session/new`, `session/load` and `session/fork`. ACP requires agents to connect to the stdio
230
+ ones, and they belong to the session that named them, so they cannot live in the startup
231
+ global: `connect_session_servers` returns a `SessionServers` that `main.rs` keeps on
232
+ `SessionState` and installs with `set_session_servers` whenever a session becomes live, the
233
+ same way it swaps the roots. `tool_specs`, `call_tool` and `/mcp` read the startup servers and
234
+ then the live session's. A client-supplied server whose name is already taken by a startup
235
+ server is not connected, since both would claim the same `mcp__<server>__` prefix. Streamable
236
+ HTTP entries are connected too, with the URL and headers the client sent, because
237
+ `handle_initialize` advertises `mcpCapabilities.http`. SSE is not advertised (the MCP spec
238
+ deprecated it), so a conforming client never sends one and a stray entry is skipped.
228
239
  - **`src/permissions.rs`** — tool permission policy. Every tool call passes through
229
240
  `decision_for` before executing: read-only tools always run; mutating tools (and all
230
241
  `mcp__*`/unknown tools) are governed by, in order: per-session plan mode (`/plan` — deny all
@@ -261,7 +272,8 @@ feeds results back. Neither the loop nor ACP/TUI surfaces depend on a concrete b
261
272
  read another session's roots from the global. Project-local
262
273
  discovery reads it: skills, slash commands, subagent types, and instruction files all scan
263
274
  every root. MCP is deliberately not on that list — `mcp::init` runs once at startup, before
264
- any session exists, so a second root's `.sigit/mcp.toml` has nobody to tell.
275
+ any session exists, so a second root's `.sigit/mcp.toml` has nobody to tell. (The servers a
276
+ client names in `mcpServers` are a different thing and are per session; see `src/mcp.rs`.)
265
277
  - **`src/chat.rs`** — the Unix-only ratatui TUI. Loading-spinner phase then chat; uses
266
278
  `tokio::select!` to multiplex terminal events with streaming tokens.
267
279
  - **`src/headless.rs`** — non-interactive `sigit run` execution for scripts, CI, and Factory
@@ -376,13 +388,20 @@ Three of these need credentials or a one-time manual step before they work:
376
388
 
377
389
  - Scoop needs a `getsigit/scoop-bucket` repo and a `SCOOP_BUCKET_TOKEN` secret, mirroring the
378
390
  Homebrew tap setup.
379
- - winget needs a `WINGET_TOKEN` (PAT with `public_repo`) so `wingetcreate` can fork
380
- `microsoft/winget-pkgs`. It is passed as `WINGET_CREATE_GITHUB_TOKEN` rather than `--token`,
381
- which wingetcreate warns can leak the token into logs. `wingetcreate update` only works on a
382
- package that already exists in `microsoft/winget-pkgs`, so the workflow checks the
383
- `manifests/g/getSigit/siGitCode` path first and falls back to rendering
384
- `packaging/winget/*.yaml.in` and running `wingetcreate submit` for a first submission. That
385
- fallback runs once, then every later release takes the `update` path.
391
+ - winget needs a `WINGET_TOKEN` (PAT with `public_repo` scope) so `wingetcreate` can fork
392
+ `microsoft/winget-pkgs` and open the manifest PR. It is passed as
393
+ `WINGET_CREATE_GITHUB_TOKEN` rather than `--token`, which wingetcreate warns can leak the
394
+ token into logs. `wingetcreate update` only works on a package that already exists in
395
+ `microsoft/winget-pkgs`, so the workflow checks the `manifests/g/getSigit/siGitCode` path
396
+ first and falls back to rendering `packaging/winget/*.yaml.in` and running
397
+ `wingetcreate submit` for a first submission. That fallback runs once, then every later
398
+ release takes the `update` path. Two non-obvious things in the update path: the `--urls`
399
+ arguments carry a trailing `|x64` / `|arm64` suffix that tells wingetcreate which installer
400
+ entry each URL replaces — without it, wingetcreate guesses from the file name, and
401
+ "sigit-win-amd64.exe" is not a spelling it recognises; and the first-submission render
402
+ uppercases the SHA256 (`tr '[:lower:]' '[:upper:]'`) to match the community validation
403
+ pipeline, which writes 64-hex checksums uppercase. The update path also passes
404
+ `--release-date`, `--release-notes-url`, `--submit`, and `--no-open` explicitly.
386
405
  - The AUR needs `AUR_USERNAME`, `AUR_EMAIL`, and `AUR_SSH_PRIVATE_KEY`. It publishes `sigit-bin`
387
406
  (a prebuilt binary) so Arch users are not compiling the on-device inference stack to install a
388
407
  CLI.
@@ -11,7 +11,7 @@ ACP is a JSON-RPC 2.0 protocol over **stdio** for integrating AI coding agents
11
11
  with editors (Zed, JetBrains, Neovim, etc.). The agent runs as a subprocess;
12
12
  the editor is the client. Communication is newline-delimited JSON on stdin/stdout.
13
13
 
14
- Crate: `agent-client-protocol = "0.13"` (siGit pins 0.13.0 in `Cargo.lock`)
14
+ Crate: `agent-client-protocol = "2.2"` (siGit pins 2.2.0 in `Cargo.lock`)
15
15
  Docs: https://docs.rs/agent-client-protocol
16
16
  Spec: https://agentclientprotocol.com
17
17
 
@@ -21,6 +21,11 @@ Spec: https://agentclientprotocol.com
21
21
  > handler receives a `ConnectionTo<Client>` (`cx`) you use to send notifications
22
22
  > and spawn tasks — so the old mpsc "circular dependency" pattern is gone.
23
23
 
24
+ > **SDK 2.x is not protocol v2.** The 2.x crate still speaks ACP protocol v1 by
25
+ > default, which is what siGit and Zed use (`ProtocolVersion::V1`). The draft v2
26
+ > protocol (`Agent.v2()`, `V2ConnectionTo`) sits behind the `unstable_protocol_v2`
27
+ > feature and siGit does not enable it.
28
+
24
29
  siGit's entire ACP server lives in `src/main.rs` (`run_acp_server`, the
25
30
  `SiGitAgent` struct, and its `handle_*` methods). Read it alongside this skill.
26
31
 
@@ -30,10 +35,8 @@ siGit's entire ACP server lives in `src/main.rs` (`run_acp_server`, the
30
35
 
31
36
  ```toml
32
37
  [dependencies]
33
- agent-client-protocol = { version = "0.13", features = [
34
- "unstable_session_fork", # session/fork support
35
- "unstable_session_additional_directories", # additional_directories on session requests
36
- "unstable_auth_methods", # AuthMethod::Agent etc.
38
+ agent-client-protocol = { version = "2.2", features = [
39
+ "unstable_session_fork", # session/fork support
37
40
  ] }
38
41
  async-trait = "0.1"
39
42
  tokio = { version = "1", features = ["rt", "rt-multi-thread", "macros", "io-std", "io-util", "sync", "time"] }
@@ -42,9 +45,12 @@ futures = "0.3"
42
45
  uuid = { version = "1", features = ["v4"] }
43
46
  ```
44
47
 
45
- The `unstable_*` features gate real types/methods (`ForkSessionRequest`,
46
- `additional_directories`, `AuthMethod::Agent`). Without them the corresponding
47
- APIs don't exist and you'll get "no variant/method" errors.
48
+ The `unstable_*` features gate real types/methods (`ForkSessionRequest`).
49
+ Without them the corresponding APIs don't exist and you'll get "no
50
+ variant/method" errors. `additional_directories` and `AuthMethod::Agent` used
51
+ to need `unstable_session_additional_directories` and `unstable_auth_methods`;
52
+ both are stable in 2.x and those feature names no longer exist, so listing them
53
+ is a Cargo resolution error.
48
54
 
49
55
  ---
50
56
 
@@ -556,10 +562,9 @@ Editor Agent
556
562
  8. **Never write to stdout except JSON-RPC** — log to stderr; in TTY mode siGit
557
563
  redirects fds to `$TMPDIR/sigit.log`. Any stray `println!` or native library
558
564
  stdout write corrupts the wire.
559
- 9. **Unstable features gate real types** — `unstable_session_fork`,
560
- `unstable_session_additional_directories`, `unstable_auth_methods` must be on
561
- in `Cargo.toml` or `ForkSessionRequest`, `additional_directories`, and
562
- `AuthMethod::Agent` won't exist.
565
+ 9. **Unstable features gate real types** — `unstable_session_fork` must be on
566
+ in `Cargo.toml` or `ForkSessionRequest` won't exist. `additional_directories`
567
+ and `AuthMethod::Agent` are stable in 2.x and need no feature.
563
568
  10. **Zed re-fires the last config selection on connect** — make
564
569
  `setConfigOption` a no-op when the requested model is already active, and
565
570
  never start a model switch while a startup load is still in flight (GPU OOM).
@@ -38,6 +38,7 @@ Use this skill when preparing a release for this repository.
38
38
  - The GitHub release body is generated, not hand-written: `release-github.yml`'s release job checks out the tag, awk-extracts the `## <version>` section from `CHANGELOG.md` (a missing section is a hard failure), appends a full-changelog link and a `sigit.si/code` footnote, and publishes it via `body_path: release_notes.md`. The only file a release-prep change needs to touch is `CHANGELOG.md` — never edit release notes in the GitHub UI, because the next tag push would overwrite them.
39
39
  - npm and NuGet publish via OIDC trusted publishing — neither has a stored token in the repo. On npm this is configured per package (each `@getsigit/*` name has a trusted publisher pointing at `release-npm.yml`), so a new package needs the same setup before its first publish will work. OIDC requires npm >= 11.5.1 and Node >= 22.14.0.
40
40
  - The NuGet package (`SiGit.Code`, `dotnet tool install --global SiGit.Code`) bundles all six platform binaries under `native/<os>-<arch>/` behind a managed shim, rather than shipping one package per platform like npm/PyPI. Watch the nuget.org 250 MB package-size limit if it ever grows.
41
+ - The winget channel (`release-winget.yml`) needs a `WINGET_TOKEN` secret that is a **classic PAT** with `public_repo` scope — not a fine-grained PAT. wingetcreate forks `microsoft/winget-pkgs` on first use and submits a PR from that fork; a fine-grained PAT scoped to `getsigit/sigit` cannot fork a repo outside its scope and every release fails with a 403/404 on the fork step. The token is passed as `WINGET_CREATE_GITHUB_TOKEN` (not `--token`) so it doesn't leak into logs. `wingetcreate update` only works on a package that already exists in `microsoft/winget-pkgs`, so the workflow checks `manifests/g/getSigit/siGitCode` first and falls back to `wingetcreate submit` with `packaging/winget/*.yaml.in` for the first release; every later release takes the `update` path. If a winget release fails with a fork/permission error, check the `WINGET_TOKEN` secret type before re-dispatching.
41
42
  - The baked-in official MCP server is separately listed in the public MCP Registry as `si.sigit/sigit` (`release-mcp-registry.yml`, driven by `server.json` at the repo root). It's a remote Streamable-HTTP listing, so it's verified by a DNS TXT record on the `sigit.si` domain rather than the GitHub-OIDC scheme used for package listings.
42
43
 
43
44
  ## Git release flow
@@ -84,3 +85,4 @@ Pushing the `v*.*.*` tag is what fires every release workflow, so create and pus
84
85
  - Package names, install commands, and branding stay consistent across npm, PyPI, crates.io, Homebrew, NuGet, Scoop, winget, AUR, and the `.deb`/`.rpm` packages.
85
86
  - Every release asset (including the new `.deb`/`.rpm`/raw binaries consumed by Scoop, winget, and AUR) has a matching `.sha256` sidecar.
86
87
  - Any known release limitations are called out explicitly, including a dispatch failure in `release-scoop`/`release-winget`/`release-aur` (non-fatal — logged as a warning by `release-github.yml`) versus a hard failure in a directly tag-triggered workflow like `release-nuget` or `release-mcp-registry`.
88
+ - The `WINGET_TOKEN` secret is a classic PAT with `public_repo` scope (not fine-grained), so wingetcreate can fork `microsoft/winget-pkgs`. If a winget release fails on the fork step, verify the token type before re-dispatching.
@@ -11,7 +11,7 @@ ACP is a JSON-RPC 2.0 protocol over **stdio** for integrating AI coding agents
11
11
  with editors (Zed, JetBrains, Neovim, etc.). The agent runs as a subprocess;
12
12
  the editor is the client. Communication is newline-delimited JSON on stdin/stdout.
13
13
 
14
- Crate: `agent-client-protocol = "0.13"` (siGit pins 0.13.0 in `Cargo.lock`)
14
+ Crate: `agent-client-protocol = "2.2"` (siGit pins 2.2.0 in `Cargo.lock`)
15
15
  Docs: https://docs.rs/agent-client-protocol
16
16
  Spec: https://agentclientprotocol.com
17
17
 
@@ -21,6 +21,11 @@ Spec: https://agentclientprotocol.com
21
21
  > handler receives a `ConnectionTo<Client>` (`cx`) you use to send notifications
22
22
  > and spawn tasks — so the old mpsc "circular dependency" pattern is gone.
23
23
 
24
+ > **SDK 2.x is not protocol v2.** The 2.x crate still speaks ACP protocol v1 by
25
+ > default, which is what siGit and Zed use (`ProtocolVersion::V1`). The draft v2
26
+ > protocol (`Agent.v2()`, `V2ConnectionTo`) sits behind the `unstable_protocol_v2`
27
+ > feature and siGit does not enable it.
28
+
24
29
  siGit's entire ACP server lives in `src/main.rs` (`run_acp_server`, the
25
30
  `SiGitAgent` struct, and its `handle_*` methods). Read it alongside this skill.
26
31
 
@@ -30,10 +35,8 @@ siGit's entire ACP server lives in `src/main.rs` (`run_acp_server`, the
30
35
 
31
36
  ```toml
32
37
  [dependencies]
33
- agent-client-protocol = { version = "0.13", features = [
34
- "unstable_session_fork", # session/fork support
35
- "unstable_session_additional_directories", # additional_directories on session requests
36
- "unstable_auth_methods", # AuthMethod::Agent etc.
38
+ agent-client-protocol = { version = "2.2", features = [
39
+ "unstable_session_fork", # session/fork support
37
40
  ] }
38
41
  async-trait = "0.1"
39
42
  tokio = { version = "1", features = ["rt", "rt-multi-thread", "macros", "io-std", "io-util", "sync", "time"] }
@@ -42,9 +45,12 @@ futures = "0.3"
42
45
  uuid = { version = "1", features = ["v4"] }
43
46
  ```
44
47
 
45
- The `unstable_*` features gate real types/methods (`ForkSessionRequest`,
46
- `additional_directories`, `AuthMethod::Agent`). Without them the corresponding
47
- APIs don't exist and you'll get "no variant/method" errors.
48
+ The `unstable_*` features gate real types/methods (`ForkSessionRequest`).
49
+ Without them the corresponding APIs don't exist and you'll get "no
50
+ variant/method" errors. `additional_directories` and `AuthMethod::Agent` used
51
+ to need `unstable_session_additional_directories` and `unstable_auth_methods`;
52
+ both are stable in 2.x and those feature names no longer exist, so listing them
53
+ is a Cargo resolution error.
48
54
 
49
55
  ---
50
56
 
@@ -556,10 +562,9 @@ Editor Agent
556
562
  8. **Never write to stdout except JSON-RPC** — log to stderr; in TTY mode siGit
557
563
  redirects fds to `$TMPDIR/sigit.log`. Any stray `println!` or native library
558
564
  stdout write corrupts the wire.
559
- 9. **Unstable features gate real types** — `unstable_session_fork`,
560
- `unstable_session_additional_directories`, `unstable_auth_methods` must be on
561
- in `Cargo.toml` or `ForkSessionRequest`, `additional_directories`, and
562
- `AuthMethod::Agent` won't exist.
565
+ 9. **Unstable features gate real types** — `unstable_session_fork` must be on
566
+ in `Cargo.toml` or `ForkSessionRequest` won't exist. `additional_directories`
567
+ and `AuthMethod::Agent` are stable in 2.x and need no feature.
563
568
  10. **Zed re-fires the last config selection on connect** — make
564
569
  `setConfigOption` a no-op when the requested model is already active, and
565
570
  never start a model switch while a startup load is still in flight (GPU OOM).
@@ -38,6 +38,7 @@ Use this skill when preparing a release for this repository.
38
38
  - The GitHub release body is generated, not hand-written: `release-github.yml`'s release job checks out the tag, awk-extracts the `## <version>` section from `CHANGELOG.md` (a missing section is a hard failure), appends a full-changelog link and a `sigit.si/code` footnote, and publishes it via `body_path: release_notes.md`. The only file a release-prep change needs to touch is `CHANGELOG.md` — never edit release notes in the GitHub UI, because the next tag push would overwrite them.
39
39
  - npm and NuGet publish via OIDC trusted publishing — neither has a stored token in the repo. On npm this is configured per package (each `@getsigit/*` name has a trusted publisher pointing at `release-npm.yml`), so a new package needs the same setup before its first publish will work. OIDC requires npm >= 11.5.1 and Node >= 22.14.0.
40
40
  - The NuGet package (`SiGit.Code`, `dotnet tool install --global SiGit.Code`) bundles all six platform binaries under `native/<os>-<arch>/` behind a managed shim, rather than shipping one package per platform like npm/PyPI. Watch the nuget.org 250 MB package-size limit if it ever grows.
41
+ - The winget channel (`release-winget.yml`) needs a `WINGET_TOKEN` secret that is a **classic PAT** with `public_repo` scope — not a fine-grained PAT. wingetcreate forks `microsoft/winget-pkgs` on first use and submits a PR from that fork; a fine-grained PAT scoped to `getsigit/sigit` cannot fork a repo outside its scope and every release fails with a 403/404 on the fork step. The token is passed as `WINGET_CREATE_GITHUB_TOKEN` (not `--token`) so it doesn't leak into logs. `wingetcreate update` only works on a package that already exists in `microsoft/winget-pkgs`, so the workflow checks `manifests/g/getSigit/siGitCode` first and falls back to `wingetcreate submit` with `packaging/winget/*.yaml.in` for the first release; every later release takes the `update` path. If a winget release fails with a fork/permission error, check the `WINGET_TOKEN` secret type before re-dispatching.
41
42
  - The baked-in official MCP server is separately listed in the public MCP Registry as `si.sigit/sigit` (`release-mcp-registry.yml`, driven by `server.json` at the repo root). It's a remote Streamable-HTTP listing, so it's verified by a DNS TXT record on the `sigit.si` domain rather than the GitHub-OIDC scheme used for package listings.
42
43
 
43
44
  ## Git release flow
@@ -84,3 +85,4 @@ Pushing the `v*.*.*` tag is what fires every release workflow, so create and pus
84
85
  - Package names, install commands, and branding stay consistent across npm, PyPI, crates.io, Homebrew, NuGet, Scoop, winget, AUR, and the `.deb`/`.rpm` packages.
85
86
  - Every release asset (including the new `.deb`/`.rpm`/raw binaries consumed by Scoop, winget, and AUR) has a matching `.sha256` sidecar.
86
87
  - Any known release limitations are called out explicitly, including a dispatch failure in `release-scoop`/`release-winget`/`release-aur` (non-fatal — logged as a warning by `release-github.yml`) versus a hard failure in a directly tag-triggered workflow like `release-nuget` or `release-mcp-registry`.
88
+ - The `WINGET_TOKEN` secret is a classic PAT with `public_repo` scope (not fine-grained), so wingetcreate can fork `microsoft/winget-pkgs`. If a winget release fails on the fork step, verify the token type before re-dispatching.
@@ -225,6 +225,17 @@ feeds results back. Neither the loop nor ACP/TUI surfaces depend on a concrete b
225
225
  it's a remote server, the registry's URL-match rule forces a domain namespace (`si.sigit` ↔
226
226
  `sigit.si`) verified by a DNS TXT record, not the GitHub-OIDC scheme `smbcloud-cli` uses for its
227
227
  package listing.
228
+ Separate from all of the above are the servers an ACP client passes in `mcpServers` on
229
+ `session/new`, `session/load` and `session/fork`. ACP requires agents to connect to the stdio
230
+ ones, and they belong to the session that named them, so they cannot live in the startup
231
+ global: `connect_session_servers` returns a `SessionServers` that `main.rs` keeps on
232
+ `SessionState` and installs with `set_session_servers` whenever a session becomes live, the
233
+ same way it swaps the roots. `tool_specs`, `call_tool` and `/mcp` read the startup servers and
234
+ then the live session's. A client-supplied server whose name is already taken by a startup
235
+ server is not connected, since both would claim the same `mcp__<server>__` prefix. Streamable
236
+ HTTP entries are connected too, with the URL and headers the client sent, because
237
+ `handle_initialize` advertises `mcpCapabilities.http`. SSE is not advertised (the MCP spec
238
+ deprecated it), so a conforming client never sends one and a stray entry is skipped.
228
239
  - **`src/permissions.rs`** — tool permission policy. Every tool call passes through
229
240
  `decision_for` before executing: read-only tools always run; mutating tools (and all
230
241
  `mcp__*`/unknown tools) are governed by, in order: per-session plan mode (`/plan` — deny all
@@ -261,7 +272,8 @@ feeds results back. Neither the loop nor ACP/TUI surfaces depend on a concrete b
261
272
  read another session's roots from the global. Project-local
262
273
  discovery reads it: skills, slash commands, subagent types, and instruction files all scan
263
274
  every root. MCP is deliberately not on that list — `mcp::init` runs once at startup, before
264
- any session exists, so a second root's `.sigit/mcp.toml` has nobody to tell.
275
+ any session exists, so a second root's `.sigit/mcp.toml` has nobody to tell. (The servers a
276
+ client names in `mcpServers` are a different thing and are per session; see `src/mcp.rs`.)
265
277
  - **`src/chat.rs`** — the Unix-only ratatui TUI. Loading-spinner phase then chat; uses
266
278
  `tokio::select!` to multiplex terminal events with streaming tokens.
267
279
  - **`src/headless.rs`** — non-interactive `sigit run` execution for scripts, CI, and Factory
@@ -376,13 +388,20 @@ Three of these need credentials or a one-time manual step before they work:
376
388
 
377
389
  - Scoop needs a `getsigit/scoop-bucket` repo and a `SCOOP_BUCKET_TOKEN` secret, mirroring the
378
390
  Homebrew tap setup.
379
- - winget needs a `WINGET_TOKEN` (PAT with `public_repo`) so `wingetcreate` can fork
380
- `microsoft/winget-pkgs`. It is passed as `WINGET_CREATE_GITHUB_TOKEN` rather than `--token`,
381
- which wingetcreate warns can leak the token into logs. `wingetcreate update` only works on a
382
- package that already exists in `microsoft/winget-pkgs`, so the workflow checks the
383
- `manifests/g/getSigit/siGitCode` path first and falls back to rendering
384
- `packaging/winget/*.yaml.in` and running `wingetcreate submit` for a first submission. That
385
- fallback runs once, then every later release takes the `update` path.
391
+ - winget needs a `WINGET_TOKEN` (PAT with `public_repo` scope) so `wingetcreate` can fork
392
+ `microsoft/winget-pkgs` and open the manifest PR. It is passed as
393
+ `WINGET_CREATE_GITHUB_TOKEN` rather than `--token`, which wingetcreate warns can leak the
394
+ token into logs. `wingetcreate update` only works on a package that already exists in
395
+ `microsoft/winget-pkgs`, so the workflow checks the `manifests/g/getSigit/siGitCode` path
396
+ first and falls back to rendering `packaging/winget/*.yaml.in` and running
397
+ `wingetcreate submit` for a first submission. That fallback runs once, then every later
398
+ release takes the `update` path. Two non-obvious things in the update path: the `--urls`
399
+ arguments carry a trailing `|x64` / `|arm64` suffix that tells wingetcreate which installer
400
+ entry each URL replaces — without it, wingetcreate guesses from the file name, and
401
+ "sigit-win-amd64.exe" is not a spelling it recognises; and the first-submission render
402
+ uppercases the SHA256 (`tr '[:lower:]' '[:upper:]'`) to match the community validation
403
+ pipeline, which writes 64-hex checksums uppercase. The update path also passes
404
+ `--release-date`, `--release-notes-url`, `--submit`, and `--no-open` explicitly.
386
405
  - The AUR needs `AUR_USERNAME`, `AUR_EMAIL`, and `AUR_SSH_PRIVATE_KEY`. It publishes `sigit-bin`
387
406
  (a prebuilt binary) so Arch users are not compiling the on-device inference stack to install a
388
407
  CLI.
@@ -1,5 +1,76 @@
1
1
  # Changelog
2
2
 
3
+ ## 1.6.0
4
+
5
+ ### Added
6
+
7
+ - **Editors can pass HTTP MCP servers to a session.** siGit Code now
8
+ advertises `mcpCapabilities.http`, so an ACP client may list Streamable HTTP
9
+ servers in `mcpServers` next to stdio ones. They are connected with the URL
10
+ and headers the client sent and are scoped to that session, like the stdio
11
+ ones. SSE is still not advertised, since the MCP spec deprecated it (#151).
12
+
13
+ - **The plan panel survives a failed turn.** The last `write_todos` list is
14
+ now kept by siGit Code itself. When a turn ends in an endpoint error before
15
+ the model gets to call `write_todos` again, the saved list is sent to the
16
+ editor again, so the plan stays on screen where it used to go blank (#132).
17
+
18
+ ### Changed
19
+
20
+ - **The ACP Rust SDK is now 2.2** (`agent-client-protocol`, up from 1.3).
21
+ siGit Code still speaks ACP protocol v1 to the editor, so nothing changes on
22
+ the wire. The `unstable_auth_methods` feature is gone because agent auth
23
+ methods are stable in 2.x.
24
+
25
+ ### Fixed
26
+
27
+ - **MCP servers the editor passes to a session are connected.** ACP clients
28
+ can name MCP servers in `mcpServers` when they open a session, and agents
29
+ are required to connect to the stdio ones. siGit Code accepted the field and
30
+ ignored it. The servers are now spawned when the session opens, their tools
31
+ are offered to that session only, and `/mcp` lists them as coming from the
32
+ editor. `SIGIT_MCP=off` still turns all of it off (#135).
33
+
34
+ - **A relative `cwd` is rejected when a session starts.** ACP requires the
35
+ working directory and every `additionalDirectories` entry to be absolute.
36
+ `session/new`, `session/load` and `session/fork` used to accept a relative
37
+ one and resolve it against wherever the editor spawned the process. They now
38
+ answer with an invalid-params error (#136).
39
+
40
+ - **Loading a session that does not exist is an error.** `session/load` with
41
+ an id that was never saved used to succeed and open an empty session under
42
+ that id, so the editor showed a blank thread that looked restored. It now
43
+ answers "not found" (`-32002`). A thread opened in the running process but
44
+ not spoken in yet still loads (#137).
45
+
46
+ - **Compaction no longer dead-ends a long session.** The summarization request
47
+ used to carry the whole conversation, which by then was already over the
48
+ model's window, so siGit Code Cloud timed out with a 504 and the session
49
+ stopped with "start a new thread". The transcript sent for summarizing is
50
+ now capped, cut from the middle so the opening request and the latest state
51
+ are kept. If summarizing still fails, the oldest messages are dropped until
52
+ the history fits, with whole tool rounds removed together. A failed attempt
53
+ leaves the conversation as it was (#125).
54
+
55
+ - **Gateway error pages stay out of the chat.** When an endpoint answers with
56
+ an HTML error page, the error shown is the status line, not the page's
57
+ markup (#125).
58
+
59
+ - **Issue and pull request work no longer assumes GitHub.** The system prompt
60
+ treated forge features as if every repository lived on GitHub, while the
61
+ built-in `mcp__sigit__*` tools only work for repositories hosted on
62
+ sigit.si. The agent now checks the remote first, uses those tools only for
63
+ sigit.si repositories, and reaches for the forge's own CLI (`gh`, `glab`,
64
+ `tea`) elsewhere (#127).
65
+
66
+ ## 1.5.13
67
+
68
+ ### Added
69
+
70
+ - **Three more siGit Code Cloud tiers: `flare`, `zenith` and `prism`.** They
71
+ show up in `/models` and in the editor's model picker alongside the existing
72
+ tiers. Selecting one needs a signed-in account, as before.
73
+
3
74
  ## 1.5.12
4
75
 
5
76
  ### Fixed
@@ -225,6 +225,17 @@ feeds results back. Neither the loop nor ACP/TUI surfaces depend on a concrete b
225
225
  it's a remote server, the registry's URL-match rule forces a domain namespace (`si.sigit` ↔
226
226
  `sigit.si`) verified by a DNS TXT record, not the GitHub-OIDC scheme `smbcloud-cli` uses for its
227
227
  package listing.
228
+ Separate from all of the above are the servers an ACP client passes in `mcpServers` on
229
+ `session/new`, `session/load` and `session/fork`. ACP requires agents to connect to the stdio
230
+ ones, and they belong to the session that named them, so they cannot live in the startup
231
+ global: `connect_session_servers` returns a `SessionServers` that `main.rs` keeps on
232
+ `SessionState` and installs with `set_session_servers` whenever a session becomes live, the
233
+ same way it swaps the roots. `tool_specs`, `call_tool` and `/mcp` read the startup servers and
234
+ then the live session's. A client-supplied server whose name is already taken by a startup
235
+ server is not connected, since both would claim the same `mcp__<server>__` prefix. Streamable
236
+ HTTP entries are connected too, with the URL and headers the client sent, because
237
+ `handle_initialize` advertises `mcpCapabilities.http`. SSE is not advertised (the MCP spec
238
+ deprecated it), so a conforming client never sends one and a stray entry is skipped.
228
239
  - **`src/permissions.rs`** — tool permission policy. Every tool call passes through
229
240
  `decision_for` before executing: read-only tools always run; mutating tools (and all
230
241
  `mcp__*`/unknown tools) are governed by, in order: per-session plan mode (`/plan` — deny all
@@ -261,7 +272,8 @@ feeds results back. Neither the loop nor ACP/TUI surfaces depend on a concrete b
261
272
  read another session's roots from the global. Project-local
262
273
  discovery reads it: skills, slash commands, subagent types, and instruction files all scan
263
274
  every root. MCP is deliberately not on that list — `mcp::init` runs once at startup, before
264
- any session exists, so a second root's `.sigit/mcp.toml` has nobody to tell.
275
+ any session exists, so a second root's `.sigit/mcp.toml` has nobody to tell. (The servers a
276
+ client names in `mcpServers` are a different thing and are per session; see `src/mcp.rs`.)
265
277
  - **`src/chat.rs`** — the Unix-only ratatui TUI. Loading-spinner phase then chat; uses
266
278
  `tokio::select!` to multiplex terminal events with streaming tokens.
267
279
  - **`src/headless.rs`** — non-interactive `sigit run` execution for scripts, CI, and Factory
@@ -376,13 +388,20 @@ Three of these need credentials or a one-time manual step before they work:
376
388
 
377
389
  - Scoop needs a `getsigit/scoop-bucket` repo and a `SCOOP_BUCKET_TOKEN` secret, mirroring the
378
390
  Homebrew tap setup.
379
- - winget needs a `WINGET_TOKEN` (PAT with `public_repo`) so `wingetcreate` can fork
380
- `microsoft/winget-pkgs`. It is passed as `WINGET_CREATE_GITHUB_TOKEN` rather than `--token`,
381
- which wingetcreate warns can leak the token into logs. `wingetcreate update` only works on a
382
- package that already exists in `microsoft/winget-pkgs`, so the workflow checks the
383
- `manifests/g/getSigit/siGitCode` path first and falls back to rendering
384
- `packaging/winget/*.yaml.in` and running `wingetcreate submit` for a first submission. That
385
- fallback runs once, then every later release takes the `update` path.
391
+ - winget needs a `WINGET_TOKEN` (PAT with `public_repo` scope) so `wingetcreate` can fork
392
+ `microsoft/winget-pkgs` and open the manifest PR. It is passed as
393
+ `WINGET_CREATE_GITHUB_TOKEN` rather than `--token`, which wingetcreate warns can leak the
394
+ token into logs. `wingetcreate update` only works on a package that already exists in
395
+ `microsoft/winget-pkgs`, so the workflow checks the `manifests/g/getSigit/siGitCode` path
396
+ first and falls back to rendering `packaging/winget/*.yaml.in` and running
397
+ `wingetcreate submit` for a first submission. That fallback runs once, then every later
398
+ release takes the `update` path. Two non-obvious things in the update path: the `--urls`
399
+ arguments carry a trailing `|x64` / `|arm64` suffix that tells wingetcreate which installer
400
+ entry each URL replaces — without it, wingetcreate guesses from the file name, and
401
+ "sigit-win-amd64.exe" is not a spelling it recognises; and the first-submission render
402
+ uppercases the SHA256 (`tr '[:lower:]' '[:upper:]'`) to match the community validation
403
+ pipeline, which writes 64-hex checksums uppercase. The update path also passes
404
+ `--release-date`, `--release-notes-url`, `--submit`, and `--no-open` explicitly.
386
405
  - The AUR needs `AUR_USERNAME`, `AUR_EMAIL`, and `AUR_SSH_PRIVATE_KEY`. It publishes `sigit-bin`
387
406
  (a prebuilt binary) so Arch users are not compiling the on-device inference stack to install a
388
407
  CLI.
@@ -20,9 +20,9 @@ checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa"
20
20
 
21
21
  [[package]]
22
22
  name = "agent-client-protocol"
23
- version = "1.3.0"
23
+ version = "2.2.0"
24
24
  source = "registry+https://github.com/rust-lang/crates.io-index"
25
- checksum = "1d386d6a58f4dbe0ebfa98e915caa54005dabdefd419de3d4678b28cd5752444"
25
+ checksum = "13f780597b2c88ab83d02509bcc3e86366751f86fa12114005e35c55ed691763"
26
26
  dependencies = [
27
27
  "agent-client-protocol-derive",
28
28
  "agent-client-protocol-schema",
@@ -44,19 +44,19 @@ dependencies = [
44
44
 
45
45
  [[package]]
46
46
  name = "agent-client-protocol-derive"
47
- version = "1.3.0"
47
+ version = "2.2.0"
48
48
  source = "registry+https://github.com/rust-lang/crates.io-index"
49
- checksum = "97b94934d118a69e921d14e94d4af5b3076563318c52662c89a0ecb3f139e1da"
49
+ checksum = "f4893bfb11e0e193aa5a64611a126ee87567acb1879556519c902722899229de"
50
50
  dependencies = [
51
51
  "quote",
52
- "syn 2.0.119",
52
+ "syn 3.0.4",
53
53
  ]
54
54
 
55
55
  [[package]]
56
56
  name = "agent-client-protocol-schema"
57
- version = "1.4.0"
57
+ version = "1.9.1"
58
58
  source = "registry+https://github.com/rust-lang/crates.io-index"
59
- checksum = "06679e1542356341f4550ccfb16338b64f37f6af70de2105446ef6fbb078234c"
59
+ checksum = "1d595a79e1665d02c91c7dd1bedd118501e75cc0a3d5b1651b5150ec4c5c1e0d"
60
60
  dependencies = [
61
61
  "anyhow",
62
62
  "derive_more",
@@ -5778,7 +5778,7 @@ checksum = "f8fadd59c855ef2080decdef8ff161eb6661b86933c9d82e5ba29dc602a55aba"
5778
5778
 
5779
5779
  [[package]]
5780
5780
  name = "sigit"
5781
- version = "1.5.12"
5781
+ version = "1.6.0"
5782
5782
  dependencies = [
5783
5783
  "agent-client-protocol",
5784
5784
  "anyhow",
@@ -1,6 +1,6 @@
1
1
  [package]
2
2
  name = "sigit"
3
- version = "1.5.12"
3
+ version = "1.6.0"
4
4
  edition = "2024"
5
5
  description = "siGit Code — ACP-compatible AI coding agent. Sí, git."
6
6
  documentation = "https://github.com/getsigit/sigit"
@@ -23,7 +23,7 @@ path = "src/main.rs"
23
23
 
24
24
  [dependencies]
25
25
  # ACP protocol SDK
26
- agent-client-protocol = { version = "1.3", features = ["unstable_session_fork", "unstable_auth_methods"] }
26
+ agent-client-protocol = { version = "2.2", features = ["unstable_session_fork"] }
27
27
 
28
28
  # Onde Inference engine (local LLM)
29
29
  # onde = { path = "../onde" }
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: sigit-code
3
- Version: 1.5.12
3
+ Version: 1.6.0
4
4
  Classifier: Development Status :: 4 - Beta
5
5
  Classifier: Environment :: Console
6
6
  Classifier: Intended Audience :: Developers