sigit-code 1.5.5__tar.gz → 1.5.7__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.5 → sigit_code-1.5.7}/.agents/AGENTS.md +64 -13
- {sigit_code-1.5.5/.claude → sigit_code-1.5.7/.agents}/skills/agent-client-protocol/SKILL.md +19 -4
- {sigit_code-1.5.5 → sigit_code-1.5.7}/.agents/skills/sigit-code-release/SKILL.md +18 -4
- {sigit_code-1.5.5/.agents → sigit_code-1.5.7/.claude}/skills/agent-client-protocol/SKILL.md +19 -4
- {sigit_code-1.5.5 → sigit_code-1.5.7}/.claude/skills/sigit-code-release/SKILL.md +18 -4
- {sigit_code-1.5.5 → sigit_code-1.5.7}/.github/workflows/release-aur.yml +8 -0
- {sigit_code-1.5.5 → sigit_code-1.5.7}/.github/workflows/release-crates.yml +34 -6
- {sigit_code-1.5.5 → sigit_code-1.5.7}/.github/workflows/release-github.yml +8 -0
- {sigit_code-1.5.5 → sigit_code-1.5.7}/.github/workflows/release-homebrew.yml +8 -0
- {sigit_code-1.5.5 → sigit_code-1.5.7}/.github/workflows/release-npm.yml +75 -32
- {sigit_code-1.5.5 → sigit_code-1.5.7}/.github/workflows/release-nuget.yml +37 -6
- {sigit_code-1.5.5 → sigit_code-1.5.7}/.github/workflows/release-pypi.yml +29 -6
- {sigit_code-1.5.5 → sigit_code-1.5.7}/.github/workflows/release-scoop.yml +8 -0
- {sigit_code-1.5.5 → sigit_code-1.5.7}/.github/workflows/release-winget.yml +8 -0
- {sigit_code-1.5.5 → sigit_code-1.5.7}/.gitignore +1 -0
- {sigit_code-1.5.5 → sigit_code-1.5.7}/AGENTS.md +64 -13
- {sigit_code-1.5.5 → sigit_code-1.5.7}/CHANGELOG.md +87 -0
- {sigit_code-1.5.5 → sigit_code-1.5.7}/CLAUDE.md +64 -13
- {sigit_code-1.5.5 → sigit_code-1.5.7}/Cargo.lock +1 -1
- {sigit_code-1.5.5 → sigit_code-1.5.7}/Cargo.toml +1 -1
- {sigit_code-1.5.5 → sigit_code-1.5.7}/PKG-INFO +1 -1
- {sigit_code-1.5.5 → sigit_code-1.5.7}/docs/mcp.md +5 -3
- {sigit_code-1.5.5 → sigit_code-1.5.7}/npm/README.md.tmpl +1 -1
- sigit_code-1.5.7/npm/package-compat.json.tmpl +41 -0
- {sigit_code-1.5.5 → sigit_code-1.5.7}/npm/package.json.tmpl +1 -1
- {sigit_code-1.5.5 → sigit_code-1.5.7}/npm/scripts/render-main-package.cjs +8 -7
- {sigit_code-1.5.5 → sigit_code-1.5.7}/npm/scripts/render-platform-package.cjs +11 -3
- {sigit_code-1.5.5 → sigit_code-1.5.7}/npm/sigit/README.md +8 -0
- sigit_code-1.5.7/npm/sigit/src/index.ts +74 -0
- {sigit_code-1.5.5 → sigit_code-1.5.7}/src/backend.rs +328 -2
- {sigit_code-1.5.5 → sigit_code-1.5.7}/src/commands.rs +5 -4
- {sigit_code-1.5.5 → sigit_code-1.5.7}/src/headless.rs +59 -42
- {sigit_code-1.5.5 → sigit_code-1.5.7}/src/hooks.rs +3 -0
- {sigit_code-1.5.5 → sigit_code-1.5.7}/src/instructions.rs +51 -5
- {sigit_code-1.5.5 → sigit_code-1.5.7}/src/main.rs +333 -104
- {sigit_code-1.5.5 → sigit_code-1.5.7}/src/provider.rs +18 -5
- {sigit_code-1.5.5 → sigit_code-1.5.7}/src/skills.rs +5 -4
- {sigit_code-1.5.5 → sigit_code-1.5.7}/src/subagents.rs +5 -4
- {sigit_code-1.5.5 → sigit_code-1.5.7}/src/tools.rs +182 -27
- sigit_code-1.5.7/src/workspace.rs +160 -0
- sigit_code-1.5.7/tests/acp_endpoint_errors.rs +262 -0
- sigit_code-1.5.7/tests/acp_multi_root.rs +254 -0
- {sigit_code-1.5.5 → sigit_code-1.5.7}/tests/acp_permissions.rs +231 -7
- sigit_code-1.5.7/tests/acp_tool_stdin.rs +235 -0
- {sigit_code-1.5.5 → sigit_code-1.5.7}/tests/headless_mode.rs +59 -0
- sigit_code-1.5.5/.github/workflows/release-mcp-registry.yml +0 -79
- sigit_code-1.5.5/npm/sigit/src/index.ts +0 -43
- sigit_code-1.5.5/server.json +0 -39
- {sigit_code-1.5.5 → sigit_code-1.5.7}/.agents/skills/ai-assisted-coding/SKILL.md +0 -0
- {sigit_code-1.5.5 → sigit_code-1.5.7}/.agents/skills/branding/SKILL.md +0 -0
- {sigit_code-1.5.5 → sigit_code-1.5.7}/.agents/skills/run-sigit/SKILL.md +0 -0
- {sigit_code-1.5.5 → sigit_code-1.5.7}/.agents/skills/run-sigit/driver.mjs +0 -0
- {sigit_code-1.5.5 → sigit_code-1.5.7}/.agents/skills/run-sigit/tui-smoke.sh +0 -0
- {sigit_code-1.5.5 → sigit_code-1.5.7}/.agents/skills/tool-calling/SKILL.md +0 -0
- {sigit_code-1.5.5 → sigit_code-1.5.7}/.claude/skills/ai-assisted-coding/SKILL.md +0 -0
- {sigit_code-1.5.5 → sigit_code-1.5.7}/.claude/skills/branding/SKILL.md +0 -0
- {sigit_code-1.5.5 → sigit_code-1.5.7}/.claude/skills/run-sigit/SKILL.md +0 -0
- {sigit_code-1.5.5 → sigit_code-1.5.7}/.claude/skills/run-sigit/driver.mjs +0 -0
- {sigit_code-1.5.5 → sigit_code-1.5.7}/.claude/skills/run-sigit/tui-smoke.sh +0 -0
- {sigit_code-1.5.5 → sigit_code-1.5.7}/.claude/skills/tool-calling/SKILL.md +0 -0
- {sigit_code-1.5.5 → sigit_code-1.5.7}/.github/workflows/ci.yml +0 -0
- {sigit_code-1.5.5 → sigit_code-1.5.7}/.nvmrc +0 -0
- {sigit_code-1.5.5 → sigit_code-1.5.7}/LICENSE +0 -0
- {sigit_code-1.5.5 → sigit_code-1.5.7}/README.md +0 -0
- {sigit_code-1.5.5 → sigit_code-1.5.7}/docs/hooks.md +0 -0
- {sigit_code-1.5.5 → sigit_code-1.5.7}/examples/settings-with-hooks.toml +0 -0
- {sigit_code-1.5.5 → sigit_code-1.5.7}/examples/skills/README.md +0 -0
- {sigit_code-1.5.5 → sigit_code-1.5.7}/examples/skills/commit-message/SKILL.md +0 -0
- {sigit_code-1.5.5 → sigit_code-1.5.7}/npm/package-main.json.tmpl +0 -0
- {sigit_code-1.5.5 → sigit_code-1.5.7}/npm/sigit/.gitignore +0 -0
- {sigit_code-1.5.5 → sigit_code-1.5.7}/npm/sigit/package.json +0 -0
- {sigit_code-1.5.5 → sigit_code-1.5.7}/npm/sigit/tsconfig.json +0 -0
- {sigit_code-1.5.5 → sigit_code-1.5.7}/nuget/.gitignore +0 -0
- {sigit_code-1.5.5 → sigit_code-1.5.7}/nuget/sigit/Program.cs +0 -0
- {sigit_code-1.5.5 → sigit_code-1.5.7}/nuget/sigit/README.md +0 -0
- {sigit_code-1.5.5 → sigit_code-1.5.7}/nuget/sigit/SiGit.Code.csproj +0 -0
- {sigit_code-1.5.5 → sigit_code-1.5.7}/packaging/aur/PKGBUILD.in +0 -0
- {sigit_code-1.5.5 → sigit_code-1.5.7}/packaging/nfpm.yaml +0 -0
- {sigit_code-1.5.5 → sigit_code-1.5.7}/packaging/winget/getSigit.siGitCode.installer.yaml.in +0 -0
- {sigit_code-1.5.5 → sigit_code-1.5.7}/packaging/winget/getSigit.siGitCode.locale.en-US.yaml.in +0 -0
- {sigit_code-1.5.5 → sigit_code-1.5.7}/packaging/winget/getSigit.siGitCode.yaml.in +0 -0
- {sigit_code-1.5.5 → sigit_code-1.5.7}/pypi/README.md +0 -0
- {sigit_code-1.5.5 → sigit_code-1.5.7}/pypi/pyproject.toml +0 -0
- {sigit_code-1.5.5 → sigit_code-1.5.7}/pyproject.toml +0 -0
- {sigit_code-1.5.5 → sigit_code-1.5.7}/rust-toolchain.toml +0 -0
- {sigit_code-1.5.5 → sigit_code-1.5.7}/src/account.rs +0 -0
- {sigit_code-1.5.5 → sigit_code-1.5.7}/src/browser_auth.rs +0 -0
- {sigit_code-1.5.5 → sigit_code-1.5.7}/src/chat.rs +0 -0
- {sigit_code-1.5.5 → sigit_code-1.5.7}/src/credentials.rs +0 -0
- {sigit_code-1.5.5 → sigit_code-1.5.7}/src/frontmatter.rs +0 -0
- {sigit_code-1.5.5 → sigit_code-1.5.7}/src/mcp.rs +0 -0
- {sigit_code-1.5.5 → sigit_code-1.5.7}/src/models.rs +0 -0
- {sigit_code-1.5.5 → sigit_code-1.5.7}/src/permissions.rs +0 -0
- {sigit_code-1.5.5 → sigit_code-1.5.7}/src/session_store.rs +0 -0
- {sigit_code-1.5.5 → sigit_code-1.5.7}/src/settings.rs +0 -0
- {sigit_code-1.5.5 → sigit_code-1.5.7}/src/setup.rs +0 -0
|
@@ -26,7 +26,23 @@ from the name alone (e.g. `feature/tool-permission-system`, `fix/glob-mtime-sort
|
|
|
26
26
|
a task, ticket, or session id (not `feature/task-q003hm`).
|
|
27
27
|
|
|
28
28
|
**IMPORTANT — pull request target:** Always open pull requests against the `development` branch,
|
|
29
|
-
never `main`. `main` is release-only; `development` is where day-to-day work integrates
|
|
29
|
+
never `main`. `main` is release-only; `development` is where day-to-day work integrates, and the
|
|
30
|
+
release merge (see the `sigit-code-release` skill) is the one thing that ever puts commits on
|
|
31
|
+
`main`.
|
|
32
|
+
|
|
33
|
+
This rule needs help to hold, because the repository's default branch is `main`: both
|
|
34
|
+
`gh pr create` and the GitHub web form pre-select it, so a PR lands on the wrong base unless the
|
|
35
|
+
base is passed explicitly. Pass it every time, and check that it took:
|
|
36
|
+
|
|
37
|
+
```sh
|
|
38
|
+
gh pr create --base development --head <branch>
|
|
39
|
+
gh pr view <number> --json baseRefName
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
Retargeting a PR that was opened against `main` costs nothing before it merges:
|
|
43
|
+
`gh pr edit <number> --base development`. After it merges it costs real work — the change sits on
|
|
44
|
+
`main` while `development`, which the next release is cut from, does not have it, and someone has
|
|
45
|
+
to carry it back by hand. PR #65 went in that way.
|
|
30
46
|
|
|
31
47
|
**IMPORTANT — branch off `development`:** Start every working branch from the latest
|
|
32
48
|
`origin/development`. Exception: when new work *depends on* a feature branch that has not merged
|
|
@@ -100,7 +116,13 @@ feeds results back. Neither the loop nor ACP/TUI surfaces depend on a concrete b
|
|
|
100
116
|
smbCloud, and stay general otherwise).
|
|
101
117
|
- **`src/backend.rs`** — the `InferenceBackend` trait and neutral types (`ToolSpec`, `ToolCall`,
|
|
102
118
|
`ToolResult`, `TurnResult`). Two impls: `LocalBackend` (on-device via `onde::ChatEngine`) and
|
|
103
|
-
`OpenAiBackend` (any OpenAI-compatible HTTP endpoint).
|
|
119
|
+
`OpenAiBackend` (any OpenAI-compatible HTTP endpoint). A `BackendError` is user-facing: the
|
|
120
|
+
ACP prompt handler passes it to the client verbatim and the editor puts it in an error banner,
|
|
121
|
+
so `describe_api_error` unwraps the OpenAI `{"error":{"message":…}}` envelope and shows that
|
|
122
|
+
message on its own, falling back to the status only when there is nothing to unwrap. An
|
|
123
|
+
endpoint can also fail *after* the response is open, reporting it as a `data:` frame holding
|
|
124
|
+
the same envelope; that frame has no `choices`, so `consume_stream` has to check for it
|
|
125
|
+
explicitly or it parses as an empty chunk and the turn ends looking like an empty answer.
|
|
104
126
|
- **`src/provider.rs`** — decides *which* backend serves inference. Resolution order, first match
|
|
105
127
|
wins: (1) override via `OPENAI_BASE_URL`+`OPENAI_API_KEY` or active profile in
|
|
106
128
|
`~/.config/sigit/providers.toml`; (2) siGit Code Cloud when logged in; (3) on-device.
|
|
@@ -110,7 +132,13 @@ feeds results back. Neither the loop nor ACP/TUI surfaces depend on a concrete b
|
|
|
110
132
|
spec list (`all_tools`) and the execute `match` (`execute_tool`). `run_command` also enforces
|
|
111
133
|
commit attribution: when a command creates a new commit that lacks the
|
|
112
134
|
`Co-Authored-By: siGit Code` trailer (`COMMIT_CO_AUTHOR_TRAILER`), it amends the trailer in —
|
|
113
|
-
unless the commit already exists on a remote, which is never rewritten.
|
|
135
|
+
unless the commit already exists on a remote, which is never rewritten. Every child process it
|
|
136
|
+
spawns (`spawn_shell`, the `git` helpers, and `hooks.rs`) sets `stdin` to null and never
|
|
137
|
+
inherits it: in ACP mode sigit's stdin is the JSON-RPC pipe from the editor, so a command that
|
|
138
|
+
reads stdin both blocks forever and eats the client's next request, wedging the session past
|
|
139
|
+
any timeout. On Unix the shell also leads its own process group so the timeout kills the whole
|
|
140
|
+
tree, and stdout/stderr are drained on threads while the command runs — waiting first and
|
|
141
|
+
reading after deadlocks as soon as the output outgrows the pipe buffer. Also owns the `task`
|
|
114
142
|
tool: a nested agent loop in a fresh conversation, offered only when `subagent_available()`
|
|
115
143
|
(a subagent factory is registered — see `register_subagent_factory_for` in `main.rs`; on-device
|
|
116
144
|
registers a `None`-returning factory since onde has a single shared history). A subagent's
|
|
@@ -129,7 +157,8 @@ feeds results back. Neither the loop nor ACP/TUI surfaces depend on a concrete b
|
|
|
129
157
|
HTTP/JSON-RPC implementation.
|
|
130
158
|
- **`src/skills.rs`** — [Agent Skills](https://agentskills.io) support. Discovers skill
|
|
131
159
|
folders (each with a `SKILL.md`: YAML frontmatter `name` + `description`, then Markdown
|
|
132
|
-
instructions) from `.sigit/skills/` and `.claude/skills/` in
|
|
160
|
+
instructions) from `.sigit/skills/` and `.claude/skills/` in every project root (see `src/workspace.rs`),
|
|
161
|
+
`$SIGIT_CONFIG_DIR/skills/`,
|
|
133
162
|
and `~/.claude/skills/`. Progressive disclosure: the discovery list (name + description) is
|
|
134
163
|
baked into the dynamically-built `skill` tool's description, and activating a skill (the model
|
|
135
164
|
calls `skill` with a name) loads the full `SKILL.md` body. The `skill` tool is appended in the
|
|
@@ -137,7 +166,7 @@ feeds results back. Neither the loop nor ACP/TUI surfaces depend on a concrete b
|
|
|
137
166
|
and only when at least one skill exists.
|
|
138
167
|
- **`src/commands.rs`** — user-defined slash commands. Discovers Markdown files (each an
|
|
139
168
|
optional YAML frontmatter block — `description`, `argument-hint` — followed by a prompt-template
|
|
140
|
-
body) from `.sigit/commands/` and `.claude/commands/` in
|
|
169
|
+
body) from `.sigit/commands/` and `.claude/commands/` in every project root, `$SIGIT_CONFIG_DIR/commands/`,
|
|
141
170
|
and `~/.claude/commands/`. A subdirectory namespaces the command with `:`
|
|
142
171
|
(`.sigit/commands/git/commit.md` → `/git:commit`). Unlike skills there's no tool-call
|
|
143
172
|
indirection: invoking one works exactly like the built-in `/init` — `commands::render`
|
|
@@ -151,7 +180,7 @@ feeds results back. Neither the loop nor ACP/TUI surfaces depend on a concrete b
|
|
|
151
180
|
- **`src/subagents.rs`** — configurable subagent types for the `task` tool. Discovers Markdown
|
|
152
181
|
files (YAML frontmatter `name` + `description`, optional comma-separated `tools:` allow-list,
|
|
153
182
|
then a Markdown body that becomes the subagent's system prompt) from `.sigit/agents/` and
|
|
154
|
-
`.claude/agents/` in
|
|
183
|
+
`.claude/agents/` in every project root, `$SIGIT_CONFIG_DIR/agents/`, and `~/.claude/agents/`. Passing a
|
|
155
184
|
type's `name` as `task`'s `subagent_type` argument swaps in that system prompt and, if `tools:`
|
|
156
185
|
is set, narrows the offered toolset to its *intersection* with `SUBAGENT_TOOL_NAMES` — the
|
|
157
186
|
security-relevant narrowing logic lives in `tools.rs` next to that constant, not here; this
|
|
@@ -182,10 +211,11 @@ feeds results back. Neither the loop nor ACP/TUI surfaces depend on a concrete b
|
|
|
182
211
|
`tests/mcp_stdio.rs`, driven by the test-only `src/bin/mcp_stdio_stub.rs` helper binary
|
|
183
212
|
(excluded from the published crate via `exclude` in `Cargo.toml`). The baked-in official
|
|
184
213
|
server is *also* listed in the public MCP Registry as `si.sigit/sigit` — a **remote**
|
|
185
|
-
Streamable-HTTP listing
|
|
186
|
-
`release-mcp-registry.yml`)
|
|
187
|
-
forces a domain namespace (`si.sigit` ↔
|
|
188
|
-
GitHub-OIDC scheme `smbcloud-cli` uses for its
|
|
214
|
+
Streamable-HTTP listing owned by the [`getsigit/si`](https://github.com/getsigit/si) repo
|
|
215
|
+
(`server.json` at its root, published by its `release-mcp-registry.yml`), not this one. Because
|
|
216
|
+
it's a remote server, the registry's URL-match rule forces a domain namespace (`si.sigit` ↔
|
|
217
|
+
`sigit.si`) verified by a DNS TXT record, not the GitHub-OIDC scheme `smbcloud-cli` uses for its
|
|
218
|
+
package listing.
|
|
189
219
|
- **`src/permissions.rs`** — tool permission policy. Every tool call passes through
|
|
190
220
|
`decision_for` before executing: read-only tools always run; mutating tools (and all
|
|
191
221
|
`mcp__*`/unknown tools) are governed by, in order: per-session plan mode (`/plan` — deny all
|
|
@@ -201,9 +231,22 @@ feeds results back. Neither the loop nor ACP/TUI surfaces depend on a concrete b
|
|
|
201
231
|
Reads `AGENTS.md` (the cross-tool [agents.md](https://agents.md) standard) and `CLAUDE.md`,
|
|
202
232
|
walking from the session cwd up to the repo root (nearest ancestor with `.git`, never above it),
|
|
203
233
|
plus a global file under `$SIGIT_CONFIG_DIR`. Files are ordered outermost-first so the deepest
|
|
204
|
-
(most specific) wins.
|
|
205
|
-
|
|
206
|
-
|
|
234
|
+
(most specific) wins. In a multi-root project that walk is repeated for every root
|
|
235
|
+
(`load_workspace_instructions`). The combined block is injected via `session_context_message`
|
|
236
|
+
in `main.rs` — pushed as a system message at every ACP session entry point (new/load/fork +
|
|
237
|
+
model switch) and appended to the system prompt on the cloud and TUI-startup paths.
|
|
238
|
+
- **`src/workspace.rs`** — the directories the session treats as project roots. An editor can
|
|
239
|
+
open several at once (Zed calls it a multi-root project) and ACP carries the extras as
|
|
240
|
+
`additional_directories` on every session request; the headless CLI takes them as repeatable
|
|
241
|
+
`--add-dir` flags. A client only sends those extras to an agent that advertises
|
|
242
|
+
`sessionCapabilities.additionalDirectories` in its `initialize` reply, so that capability in
|
|
243
|
+
`handle_initialize` is what makes the rest of this reachable — without it Zed keeps the first
|
|
244
|
+
root, drops the others, and shows "This agent doesn't currently support multi-root workspaces".
|
|
245
|
+
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. Project-local
|
|
247
|
+
discovery reads it: skills, slash commands, subagent types, and instruction files all scan
|
|
248
|
+
every root. MCP is deliberately not on that list — `mcp::init` runs once at startup, before
|
|
249
|
+
any session exists, so a second root's `.sigit/mcp.toml` has nobody to tell.
|
|
207
250
|
- **`src/chat.rs`** — the Unix-only ratatui TUI. Loading-spinner phase then chat; uses
|
|
208
251
|
`tokio::select!` to multiplex terminal events with streaming tokens.
|
|
209
252
|
- **`src/setup.rs`** — model cache location, local model discovery, selected-model persistence.
|
|
@@ -284,6 +327,14 @@ winget, and the AUR PKGBUILD each need one, and they consume the raw binaries ra
|
|
|
284
327
|
tarball. `release-github` also builds a `.deb` and `.rpm` per Linux target with nfpm
|
|
285
328
|
(`packaging/nfpm.yaml`), packaging the already-built binary rather than re-invoking cargo.
|
|
286
329
|
|
|
330
|
+
Re-pushing a tag fires every release workflow a second time, so each one is grouped by tag in a
|
|
331
|
+
`concurrency` block with `cancel-in-progress: false` — the duplicate queues behind the original
|
|
332
|
+
rather than interrupting a publish that is halfway through uploading. What keeps the queued run
|
|
333
|
+
from going red is the "is this version already published?" check each publishing workflow does
|
|
334
|
+
before it uploads. Those checks are load-bearing, not belt-and-braces: v1.5.6 published twice
|
|
335
|
+
because the crates.io one asked the API with curl's default User-Agent, which crates.io answers
|
|
336
|
+
with a 403, which read as "not published yet".
|
|
337
|
+
|
|
287
338
|
Three of these need credentials or a one-time manual step before they work:
|
|
288
339
|
|
|
289
340
|
- Scoop needs a `getsigit/scoop-bucket` repo and a `SCOOP_BUCKET_TOKEN` secret, mirroring the
|
|
@@ -271,8 +271,14 @@ Ok(ForkSessionResponse::new(new_id).config_options(config_options))
|
|
|
271
271
|
per-session picker (see Config options below).
|
|
272
272
|
|
|
273
273
|
The session requests carry `cwd: PathBuf` and (with the feature)
|
|
274
|
-
`additional_directories: Vec<PathBuf
|
|
275
|
-
|
|
274
|
+
`additional_directories: Vec<PathBuf>` — the other directories of a multi-root
|
|
275
|
+
project, sent only to an agent whose `initialize` reply carries
|
|
276
|
+
`SessionCapabilities::new().additional_directories(SessionAdditionalDirectoriesCapabilities::new())`. `SiGitAgent::enter_session_roots` stashes `cwd`, `set_current_dir`s to
|
|
277
|
+
it, hands the extras to `workspace::set_additional_roots`, and returns the ones
|
|
278
|
+
that survived (a root that isn't a directory, repeats, or just names `cwd` again
|
|
279
|
+
is dropped). `session_context_message` then names every root in the system
|
|
280
|
+
message, and project-local discovery — skills, slash commands, subagent types,
|
|
281
|
+
instruction files — scans all of them, primary root first.
|
|
276
282
|
|
|
277
283
|
### `PromptRequest` / blocks
|
|
278
284
|
|
|
@@ -555,8 +561,17 @@ Editor Agent
|
|
|
555
561
|
10. **Zed re-fires the last config selection on connect** — make
|
|
556
562
|
`setConfigOption` a no-op when the requested model is already active, and
|
|
557
563
|
never start a model switch while a startup load is still in flight (GPU OOM).
|
|
558
|
-
11.
|
|
559
|
-
|
|
564
|
+
11. **`additional_directories` is not decoration** — dropping it means a
|
|
565
|
+
multi-root project silently behaves as if only the first root existed, with
|
|
566
|
+
the other repositories' `AGENTS.md` and skills missing. Route it through
|
|
567
|
+
`workspace.rs`, not just the log line. Handling it is also only half the
|
|
568
|
+
job: Zed gates the field on
|
|
569
|
+
`agentCapabilities.sessionCapabilities.additionalDirectories` being present
|
|
570
|
+
in the `initialize` reply, so an agent that reads the field but never
|
|
571
|
+
advertises the capability is never sent one, and the user gets a banner
|
|
572
|
+
saying the agent has no multi-root support.
|
|
573
|
+
12. **Store `SessionId` as `SessionId`**, not `String`, so `==` is clean.
|
|
574
|
+
13. **`SetSessionConfigOptionResponse::new(config_options)`** — the response
|
|
560
575
|
carries the *rebuilt* options so the picker reflects the new current value.
|
|
561
576
|
|
|
562
577
|
---
|
|
@@ -28,9 +28,16 @@ Use this skill when preparing a release for this repository.
|
|
|
28
28
|
- Update the root `sigit` package entry in `Cargo.lock` when the crate version changes.
|
|
29
29
|
- Add or update the top changelog entry in `CHANGELOG.md` for the release being cut.
|
|
30
30
|
- Do not treat `npm/sigit/package.json` `0.0.0-dev` as a bug by default. The npm release workflow rewrites it at publish time using `npm/scripts/render-main-package.cjs` and the release tag.
|
|
31
|
+
- Every npm package publishes twice, under `@getsigit` and under `@smbcloud`. `@smbcloud` is the pre-1.5.5 name, mirrored so an install predating the rename keeps updating; `@getsigit` is canonical and is what the README, the Homebrew tap, and the ACP registry entry point at. All fourteen names (two base packages, twelve platform packages) publish over OIDC and each needs its own Trusted Publisher on npm pointing at `release-npm.yml`.
|
|
32
|
+
- The scope is a render-time argument, not a second copy of the packaging: `render-platform-package.cjs` takes it as a fifth argument, and the base package picks it up from `package-main.json.tmpl` versus `package-compat.json.tmpl`. `npm/sigit/src/index.ts` is built once and shipped under both names — it reads its own `package.json` at runtime to decide which scope to resolve the platform binary from, and prints the migration notice only when it finds itself running as `@smbcloud/sigit`.
|
|
31
33
|
- Do not add a hardcoded version to `pypi/pyproject.toml` for normal releases. PyPI uses `maturin` with `dynamic = ["version"]` and derives the published package version from `Cargo.toml`.
|
|
32
|
-
- Release workflows are tag-driven. `release-github.yml`, `release-npm.yml`, `release-pypi.yml`, `release-crates.yml`, and `release-
|
|
34
|
+
- Release workflows are tag-driven. `release-github.yml`, `release-npm.yml`, `release-pypi.yml`, `release-crates.yml`, `release-homebrew.yml`, `release-nuget.yml`, and `release-mcp-registry.yml` all derive `RELEASE_VERSION` from a `v*.*.*` tag or a manually supplied tag input.
|
|
33
35
|
- The crate is published to crates.io (`release-crates.yml`) and the Homebrew tap is updated (`release-homebrew.yml`) as part of the tag-driven flow. Per the siGit release flow, Homebrew is auto-triggered — do not dispatch it manually.
|
|
36
|
+
- `release-github.yml` builds the binaries, attaches them (plus a `.deb`/`.rpm` per Linux target built with nfpm from `packaging/nfpm.yaml`) to the GitHub release, then dispatches `release-homebrew`, `release-scoop`, `release-winget`, and `release-aur`. A dispatch failure in any one of those four is logged as a warning, not a hard failure — an unconfigured channel doesn't block the rest of the release. `release-nuget.yml` and `release-mcp-registry.yml`, by contrast, are tag-triggered directly like the other language-registry workflows, not dispatched from `release-github.yml`.
|
|
37
|
+
- Every release asset carries a `.sha256` sidecar (not just the macOS Homebrew tarball). Scoop, winget, and the AUR PKGBUILD each consume the raw binaries plus their sidecar checksum, rather than the tarball.
|
|
38
|
+
- 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.
|
|
39
|
+
- 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.
|
|
40
|
+
- 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.
|
|
34
41
|
|
|
35
42
|
## Git release flow
|
|
36
43
|
|
|
@@ -42,6 +49,8 @@ Releases are cut from `development` and shipped on `main`. The published tags (`
|
|
|
42
49
|
4. Merge `development` into `main` (commit message: `Merge development into main for v<version> release`).
|
|
43
50
|
5. Tag `v<version>` on that `main` merge commit, then push `main` and the tag.
|
|
44
51
|
|
|
52
|
+
Step 4 is the only way commits are meant to reach `main`. A feature or fix PR targeting `main` breaks that: it puts work on the release branch that `development` does not have, so the next release is cut without it. Such PRs belong on `development` (see the pull request target rule in `AGENTS.md`).
|
|
53
|
+
|
|
45
54
|
Pushing the `v*.*.*` tag is what fires every release workflow, so create and push it only after the merge into `main` has landed. Do not commit, tag, or push until the user explicitly asks — confirm the version and that they want the release to go out first.
|
|
46
55
|
|
|
47
56
|
## Typical files to inspect
|
|
@@ -51,10 +60,14 @@ Pushing the `v*.*.*` tag is what fires every release workflow, so create and pus
|
|
|
51
60
|
- `CHANGELOG.md`
|
|
52
61
|
- `README.md`
|
|
53
62
|
- `npm/sigit/package.json`
|
|
63
|
+
- `npm/package-main.json.tmpl`, `npm/package-compat.json.tmpl`, `npm/package.json.tmpl` (publish-time package metadata for both scopes)
|
|
54
64
|
- `npm/scripts/render-main-package.cjs`
|
|
55
65
|
- `npm/`
|
|
56
66
|
- `pypi/`
|
|
57
|
-
-
|
|
67
|
+
- `nuget/sigit/` (bundled-binary `.NET` tool packaging)
|
|
68
|
+
- `packaging/` (`nfpm.yaml` for `.deb`/`.rpm`, plus `aur/` and `winget/` templates)
|
|
69
|
+
- `server.json` (MCP Registry listing)
|
|
70
|
+
- `.github/workflows/` (`release-github.yml`, `release-npm.yml`, `release-pypi.yml`, `release-crates.yml`, `release-homebrew.yml`, `release-scoop.yml`, `release-winget.yml`, `release-aur.yml`, `release-nuget.yml`, `release-mcp-registry.yml`)
|
|
58
71
|
|
|
59
72
|
## Release checklist
|
|
60
73
|
|
|
@@ -67,5 +80,6 @@ Pushing the `v*.*.*` tag is what fires every release workflow, so create and pus
|
|
|
67
80
|
- Git flow followed: bump committed on `release/v<version>`, merged back to `development`, then `development` merged into `main`, with `v<version>` tagged on the `main` merge commit.
|
|
68
81
|
- Release notes or changelog entries match the actual changes.
|
|
69
82
|
- CI-equivalent local checks pass for the relevant platform or target.
|
|
70
|
-
- Package names, install commands, and branding stay consistent.
|
|
71
|
-
-
|
|
83
|
+
- Package names, install commands, and branding stay consistent across npm, PyPI, crates.io, Homebrew, NuGet, Scoop, winget, AUR, and the `.deb`/`.rpm` packages.
|
|
84
|
+
- Every release asset (including the new `.deb`/`.rpm`/raw binaries consumed by Scoop, winget, and AUR) has a matching `.sha256` sidecar.
|
|
85
|
+
- 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`.
|
|
@@ -271,8 +271,14 @@ Ok(ForkSessionResponse::new(new_id).config_options(config_options))
|
|
|
271
271
|
per-session picker (see Config options below).
|
|
272
272
|
|
|
273
273
|
The session requests carry `cwd: PathBuf` and (with the feature)
|
|
274
|
-
`additional_directories: Vec<PathBuf
|
|
275
|
-
|
|
274
|
+
`additional_directories: Vec<PathBuf>` — the other directories of a multi-root
|
|
275
|
+
project, sent only to an agent whose `initialize` reply carries
|
|
276
|
+
`SessionCapabilities::new().additional_directories(SessionAdditionalDirectoriesCapabilities::new())`. `SiGitAgent::enter_session_roots` stashes `cwd`, `set_current_dir`s to
|
|
277
|
+
it, hands the extras to `workspace::set_additional_roots`, and returns the ones
|
|
278
|
+
that survived (a root that isn't a directory, repeats, or just names `cwd` again
|
|
279
|
+
is dropped). `session_context_message` then names every root in the system
|
|
280
|
+
message, and project-local discovery — skills, slash commands, subagent types,
|
|
281
|
+
instruction files — scans all of them, primary root first.
|
|
276
282
|
|
|
277
283
|
### `PromptRequest` / blocks
|
|
278
284
|
|
|
@@ -555,8 +561,17 @@ Editor Agent
|
|
|
555
561
|
10. **Zed re-fires the last config selection on connect** — make
|
|
556
562
|
`setConfigOption` a no-op when the requested model is already active, and
|
|
557
563
|
never start a model switch while a startup load is still in flight (GPU OOM).
|
|
558
|
-
11.
|
|
559
|
-
|
|
564
|
+
11. **`additional_directories` is not decoration** — dropping it means a
|
|
565
|
+
multi-root project silently behaves as if only the first root existed, with
|
|
566
|
+
the other repositories' `AGENTS.md` and skills missing. Route it through
|
|
567
|
+
`workspace.rs`, not just the log line. Handling it is also only half the
|
|
568
|
+
job: Zed gates the field on
|
|
569
|
+
`agentCapabilities.sessionCapabilities.additionalDirectories` being present
|
|
570
|
+
in the `initialize` reply, so an agent that reads the field but never
|
|
571
|
+
advertises the capability is never sent one, and the user gets a banner
|
|
572
|
+
saying the agent has no multi-root support.
|
|
573
|
+
12. **Store `SessionId` as `SessionId`**, not `String`, so `==` is clean.
|
|
574
|
+
13. **`SetSessionConfigOptionResponse::new(config_options)`** — the response
|
|
560
575
|
carries the *rebuilt* options so the picker reflects the new current value.
|
|
561
576
|
|
|
562
577
|
---
|
|
@@ -28,9 +28,16 @@ Use this skill when preparing a release for this repository.
|
|
|
28
28
|
- Update the root `sigit` package entry in `Cargo.lock` when the crate version changes.
|
|
29
29
|
- Add or update the top changelog entry in `CHANGELOG.md` for the release being cut.
|
|
30
30
|
- Do not treat `npm/sigit/package.json` `0.0.0-dev` as a bug by default. The npm release workflow rewrites it at publish time using `npm/scripts/render-main-package.cjs` and the release tag.
|
|
31
|
+
- Every npm package publishes twice, under `@getsigit` and under `@smbcloud`. `@smbcloud` is the pre-1.5.5 name, mirrored so an install predating the rename keeps updating; `@getsigit` is canonical and is what the README, the Homebrew tap, and the ACP registry entry point at. All fourteen names (two base packages, twelve platform packages) publish over OIDC and each needs its own Trusted Publisher on npm pointing at `release-npm.yml`.
|
|
32
|
+
- The scope is a render-time argument, not a second copy of the packaging: `render-platform-package.cjs` takes it as a fifth argument, and the base package picks it up from `package-main.json.tmpl` versus `package-compat.json.tmpl`. `npm/sigit/src/index.ts` is built once and shipped under both names — it reads its own `package.json` at runtime to decide which scope to resolve the platform binary from, and prints the migration notice only when it finds itself running as `@smbcloud/sigit`.
|
|
31
33
|
- Do not add a hardcoded version to `pypi/pyproject.toml` for normal releases. PyPI uses `maturin` with `dynamic = ["version"]` and derives the published package version from `Cargo.toml`.
|
|
32
|
-
- Release workflows are tag-driven. `release-github.yml`, `release-npm.yml`, `release-pypi.yml`, `release-crates.yml`, and `release-
|
|
34
|
+
- Release workflows are tag-driven. `release-github.yml`, `release-npm.yml`, `release-pypi.yml`, `release-crates.yml`, `release-homebrew.yml`, `release-nuget.yml`, and `release-mcp-registry.yml` all derive `RELEASE_VERSION` from a `v*.*.*` tag or a manually supplied tag input.
|
|
33
35
|
- The crate is published to crates.io (`release-crates.yml`) and the Homebrew tap is updated (`release-homebrew.yml`) as part of the tag-driven flow. Per the siGit release flow, Homebrew is auto-triggered — do not dispatch it manually.
|
|
36
|
+
- `release-github.yml` builds the binaries, attaches them (plus a `.deb`/`.rpm` per Linux target built with nfpm from `packaging/nfpm.yaml`) to the GitHub release, then dispatches `release-homebrew`, `release-scoop`, `release-winget`, and `release-aur`. A dispatch failure in any one of those four is logged as a warning, not a hard failure — an unconfigured channel doesn't block the rest of the release. `release-nuget.yml` and `release-mcp-registry.yml`, by contrast, are tag-triggered directly like the other language-registry workflows, not dispatched from `release-github.yml`.
|
|
37
|
+
- Every release asset carries a `.sha256` sidecar (not just the macOS Homebrew tarball). Scoop, winget, and the AUR PKGBUILD each consume the raw binaries plus their sidecar checksum, rather than the tarball.
|
|
38
|
+
- 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.
|
|
39
|
+
- 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.
|
|
40
|
+
- 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.
|
|
34
41
|
|
|
35
42
|
## Git release flow
|
|
36
43
|
|
|
@@ -42,6 +49,8 @@ Releases are cut from `development` and shipped on `main`. The published tags (`
|
|
|
42
49
|
4. Merge `development` into `main` (commit message: `Merge development into main for v<version> release`).
|
|
43
50
|
5. Tag `v<version>` on that `main` merge commit, then push `main` and the tag.
|
|
44
51
|
|
|
52
|
+
Step 4 is the only way commits are meant to reach `main`. A feature or fix PR targeting `main` breaks that: it puts work on the release branch that `development` does not have, so the next release is cut without it. Such PRs belong on `development` (see the pull request target rule in `AGENTS.md`).
|
|
53
|
+
|
|
45
54
|
Pushing the `v*.*.*` tag is what fires every release workflow, so create and push it only after the merge into `main` has landed. Do not commit, tag, or push until the user explicitly asks — confirm the version and that they want the release to go out first.
|
|
46
55
|
|
|
47
56
|
## Typical files to inspect
|
|
@@ -51,10 +60,14 @@ Pushing the `v*.*.*` tag is what fires every release workflow, so create and pus
|
|
|
51
60
|
- `CHANGELOG.md`
|
|
52
61
|
- `README.md`
|
|
53
62
|
- `npm/sigit/package.json`
|
|
63
|
+
- `npm/package-main.json.tmpl`, `npm/package-compat.json.tmpl`, `npm/package.json.tmpl` (publish-time package metadata for both scopes)
|
|
54
64
|
- `npm/scripts/render-main-package.cjs`
|
|
55
65
|
- `npm/`
|
|
56
66
|
- `pypi/`
|
|
57
|
-
-
|
|
67
|
+
- `nuget/sigit/` (bundled-binary `.NET` tool packaging)
|
|
68
|
+
- `packaging/` (`nfpm.yaml` for `.deb`/`.rpm`, plus `aur/` and `winget/` templates)
|
|
69
|
+
- `server.json` (MCP Registry listing)
|
|
70
|
+
- `.github/workflows/` (`release-github.yml`, `release-npm.yml`, `release-pypi.yml`, `release-crates.yml`, `release-homebrew.yml`, `release-scoop.yml`, `release-winget.yml`, `release-aur.yml`, `release-nuget.yml`, `release-mcp-registry.yml`)
|
|
58
71
|
|
|
59
72
|
## Release checklist
|
|
60
73
|
|
|
@@ -67,5 +80,6 @@ Pushing the `v*.*.*` tag is what fires every release workflow, so create and pus
|
|
|
67
80
|
- Git flow followed: bump committed on `release/v<version>`, merged back to `development`, then `development` merged into `main`, with `v<version>` tagged on the `main` merge commit.
|
|
68
81
|
- Release notes or changelog entries match the actual changes.
|
|
69
82
|
- CI-equivalent local checks pass for the relevant platform or target.
|
|
70
|
-
- Package names, install commands, and branding stay consistent.
|
|
71
|
-
-
|
|
83
|
+
- Package names, install commands, and branding stay consistent across npm, PyPI, crates.io, Homebrew, NuGet, Scoop, winget, AUR, and the `.deb`/`.rpm` packages.
|
|
84
|
+
- Every release asset (including the new `.deb`/`.rpm`/raw binaries consumed by Scoop, winget, and AUR) has a matching `.sha256` sidecar.
|
|
85
|
+
- 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`.
|
|
@@ -12,6 +12,14 @@ on:
|
|
|
12
12
|
description: "Release tag (e.g. v1.5.2)"
|
|
13
13
|
required: true
|
|
14
14
|
|
|
15
|
+
concurrency:
|
|
16
|
+
# A re-pushed or re-dispatched tag fires this a second time. Queue the
|
|
17
|
+
# duplicate behind the original instead of cancelling it: cancelling a run
|
|
18
|
+
# mid-publish can leave a channel half-uploaded, whereas a queued duplicate
|
|
19
|
+
# just hits the "already published" check and exits clean.
|
|
20
|
+
group: ${{ github.workflow }}-${{ github.event.inputs.tag || github.ref_name }}
|
|
21
|
+
cancel-in-progress: false
|
|
22
|
+
|
|
15
23
|
permissions:
|
|
16
24
|
contents: read
|
|
17
25
|
|
|
@@ -10,6 +10,14 @@ on:
|
|
|
10
10
|
description: "Release tag (e.g. v1.0.2)"
|
|
11
11
|
required: true
|
|
12
12
|
|
|
13
|
+
concurrency:
|
|
14
|
+
# A re-pushed or re-dispatched tag fires this a second time. Queue the
|
|
15
|
+
# duplicate behind the original instead of cancelling it: cancelling a run
|
|
16
|
+
# mid-publish can leave a channel half-uploaded, whereas a queued duplicate
|
|
17
|
+
# just hits the "already published" check and exits clean.
|
|
18
|
+
group: ${{ github.workflow }}-${{ github.event.inputs.tag || github.ref_name }}
|
|
19
|
+
cancel-in-progress: false
|
|
20
|
+
|
|
13
21
|
permissions:
|
|
14
22
|
contents: read
|
|
15
23
|
|
|
@@ -56,12 +64,32 @@ jobs:
|
|
|
56
64
|
print(next(p['version'] for p in pkgs if p['name']=='sigit'))")
|
|
57
65
|
echo "version=${VERSION}" >> "$GITHUB_OUTPUT"
|
|
58
66
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
67
|
+
# crates.io answers 403 to requests without a descriptive
|
|
68
|
+
# User-Agent, so curl's default one makes this look like a 404 and
|
|
69
|
+
# the publish below runs into "crate already exists on the index".
|
|
70
|
+
# Branch on the status code rather than on curl's exit status, so an
|
|
71
|
+
# answer we do not understand stops the job instead of quietly
|
|
72
|
+
# degrading into that same failure.
|
|
73
|
+
# Retry first, so a timeout or a 5xx costs a few seconds instead of
|
|
74
|
+
# the whole release.
|
|
75
|
+
STATUS=$(curl -sS -o /dev/null -w '%{http_code}' \
|
|
76
|
+
--retry 3 --retry-delay 2 --retry-all-errors \
|
|
77
|
+
-H "User-Agent: ${GITHUB_REPOSITORY} release workflow (https://github.com/${GITHUB_REPOSITORY})" \
|
|
78
|
+
"https://crates.io/api/v1/crates/sigit/${VERSION}")
|
|
79
|
+
|
|
80
|
+
case "$STATUS" in
|
|
81
|
+
200)
|
|
82
|
+
echo "sigit ${VERSION} already exists on crates.io, skipping publish"
|
|
83
|
+
echo "exists=true" >> "$GITHUB_OUTPUT"
|
|
84
|
+
;;
|
|
85
|
+
404)
|
|
86
|
+
echo "exists=false" >> "$GITHUB_OUTPUT"
|
|
87
|
+
;;
|
|
88
|
+
*)
|
|
89
|
+
echo "Unexpected ${STATUS} from crates.io while checking whether sigit ${VERSION} is published" >&2
|
|
90
|
+
exit 1
|
|
91
|
+
;;
|
|
92
|
+
esac
|
|
65
93
|
|
|
66
94
|
- name: Publish to crates.io
|
|
67
95
|
if: steps.crates-check.outputs.exists != 'true'
|
|
@@ -10,6 +10,14 @@ on:
|
|
|
10
10
|
description: "Release tag (e.g. v0.1.1)"
|
|
11
11
|
required: true
|
|
12
12
|
|
|
13
|
+
concurrency:
|
|
14
|
+
# A re-pushed or re-dispatched tag fires this a second time. Queue the
|
|
15
|
+
# duplicate behind the original instead of cancelling it: cancelling a run
|
|
16
|
+
# mid-publish can leave a channel half-uploaded, whereas a queued duplicate
|
|
17
|
+
# just hits the "already published" check and exits clean.
|
|
18
|
+
group: ${{ github.workflow }}-${{ github.event.inputs.tag || github.ref_name }}
|
|
19
|
+
cancel-in-progress: false
|
|
20
|
+
|
|
13
21
|
permissions:
|
|
14
22
|
contents: write
|
|
15
23
|
actions: write
|
|
@@ -7,6 +7,14 @@ on:
|
|
|
7
7
|
description: "Release tag (e.g. v0.1.1)"
|
|
8
8
|
required: true
|
|
9
9
|
|
|
10
|
+
concurrency:
|
|
11
|
+
# A re-pushed or re-dispatched tag fires this a second time. Queue the
|
|
12
|
+
# duplicate behind the original instead of cancelling it: cancelling a run
|
|
13
|
+
# mid-publish can leave a channel half-uploaded, whereas a queued duplicate
|
|
14
|
+
# just hits the "already published" check and exits clean.
|
|
15
|
+
group: ${{ github.workflow }}-${{ github.event.inputs.tag || github.ref_name }}
|
|
16
|
+
cancel-in-progress: false
|
|
17
|
+
|
|
10
18
|
permissions:
|
|
11
19
|
contents: read
|
|
12
20
|
|
|
@@ -10,6 +10,14 @@ on:
|
|
|
10
10
|
description: "Release tag (e.g. v0.1.1)"
|
|
11
11
|
required: true
|
|
12
12
|
|
|
13
|
+
concurrency:
|
|
14
|
+
# A re-pushed or re-dispatched tag fires this a second time. Queue the
|
|
15
|
+
# duplicate behind the original instead of cancelling it: cancelling a run
|
|
16
|
+
# mid-publish can leave a channel half-uploaded, whereas a queued duplicate
|
|
17
|
+
# just hits the "already published" check and exits clean.
|
|
18
|
+
group: ${{ github.workflow }}-${{ github.event.inputs.tag || github.ref_name }}
|
|
19
|
+
cancel-in-progress: false
|
|
20
|
+
|
|
13
21
|
permissions:
|
|
14
22
|
id-token: write
|
|
15
23
|
contents: read
|
|
@@ -108,8 +116,10 @@ jobs:
|
|
|
108
116
|
shell: bash
|
|
109
117
|
run: npm install -g npm@latest
|
|
110
118
|
|
|
111
|
-
# Authentication is OIDC: each @getsigit/* package has a
|
|
112
|
-
# Publisher pointing at this workflow, so there is no token to
|
|
119
|
+
# Authentication is OIDC: each @getsigit/* and @smbcloud/* package has a
|
|
120
|
+
# Trusted Publisher pointing at this workflow, so there is no token to
|
|
121
|
+
# leak. @smbcloud is the pre-1.5.5 scope, published alongside @getsigit
|
|
122
|
+
# so that an install made before the rename keeps updating.
|
|
113
123
|
- name: Publish platform package to NPM
|
|
114
124
|
shell: bash
|
|
115
125
|
run: |
|
|
@@ -141,13 +151,6 @@ jobs:
|
|
|
141
151
|
# Create the package directory
|
|
142
152
|
mkdir -p "${node_pkg}/bin"
|
|
143
153
|
|
|
144
|
-
# Generate package.json + README for this platform slice
|
|
145
|
-
node ./scripts/render-platform-package.cjs \
|
|
146
|
-
"${node_pkg}" \
|
|
147
|
-
"${node_version}" \
|
|
148
|
-
"${node_os}" \
|
|
149
|
-
"${node_arch}"
|
|
150
|
-
|
|
151
154
|
# Windows binaries carry a .exe extension
|
|
152
155
|
if [ "${{ matrix.build.OS }}" = "windows-2022" ]; then
|
|
153
156
|
cargo_bin="${cargo_bin}.exe"
|
|
@@ -155,18 +158,36 @@ jobs:
|
|
|
155
158
|
|
|
156
159
|
cp "../target/${{ matrix.build.TARGET }}/release/${cargo_bin}" "${node_pkg}/bin"
|
|
157
160
|
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
161
|
+
# One binary, published under both scopes: re-render package.json and
|
|
162
|
+
# README for each, from the same directory.
|
|
163
|
+
for scope in "@getsigit" "@smbcloud"; do
|
|
164
|
+
node ./scripts/render-platform-package.cjs \
|
|
165
|
+
"${node_pkg}" \
|
|
166
|
+
"${node_version}" \
|
|
167
|
+
"${node_os}" \
|
|
168
|
+
"${node_arch}" \
|
|
169
|
+
"${scope}"
|
|
170
|
+
|
|
171
|
+
npm_package_name="${scope}/${node_pkg}"
|
|
172
|
+
|
|
173
|
+
# `npm view` exits non-zero both when the version is genuinely
|
|
174
|
+
# unpublished and when the registry could not be reached, so treat
|
|
175
|
+
# only an E404 as "not published yet". Anything else stops the job
|
|
176
|
+
# instead of publishing over a version that is already there.
|
|
177
|
+
if view_output=$(npm view "${npm_package_name}@${node_version}" version 2>&1); then
|
|
178
|
+
echo "${npm_package_name}@${node_version} already exists on npm, skipping publish"
|
|
179
|
+
continue
|
|
180
|
+
elif ! grep -q "E404" <<<"${view_output}"; then
|
|
181
|
+
echo "npm view failed while checking ${npm_package_name}@${node_version}:" >&2
|
|
182
|
+
echo "${view_output}" >&2
|
|
183
|
+
exit 1
|
|
184
|
+
fi
|
|
185
|
+
|
|
186
|
+
(cd "${node_pkg}" && npm publish --access public)
|
|
187
|
+
done
|
|
167
188
|
|
|
168
189
|
publish-npm-base:
|
|
169
|
-
name: Publish base NPM
|
|
190
|
+
name: Publish base NPM packages (@getsigit/sigit, @smbcloud/sigit)
|
|
170
191
|
needs: publish-npm-binaries
|
|
171
192
|
runs-on: ubuntu-latest
|
|
172
193
|
|
|
@@ -200,25 +221,47 @@ jobs:
|
|
|
200
221
|
shell: bash
|
|
201
222
|
run: npm install -g npm@latest
|
|
202
223
|
|
|
203
|
-
- name: Publish base
|
|
224
|
+
- name: Publish base packages to NPM
|
|
204
225
|
shell: bash
|
|
205
226
|
run: |
|
|
206
227
|
cd npm/sigit
|
|
207
228
|
|
|
208
|
-
# Rewrite package.json with the correct release version and
|
|
209
|
-
# matching optionalDependency versions
|
|
210
|
-
node ../scripts/render-main-package.cjs \
|
|
211
|
-
"./package.json" \
|
|
212
|
-
"${{ env.RELEASE_VERSION }}"
|
|
213
|
-
|
|
214
|
-
npm_package_name="@getsigit/sigit"
|
|
215
229
|
npm_package_version="${{ env.RELEASE_VERSION }}"
|
|
216
230
|
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
231
|
+
# Rewrite package.json with the correct release version and matching
|
|
232
|
+
# optionalDependency versions, then build. The compiled launcher is
|
|
233
|
+
# scope-agnostic — it reads its own package.json at runtime to decide
|
|
234
|
+
# which scope to resolve the platform binary from — so both packages
|
|
235
|
+
# ship the same lib/ and it only needs building once.
|
|
236
|
+
node ../scripts/render-main-package.cjs \
|
|
237
|
+
"./package.json" \
|
|
238
|
+
"${npm_package_version}"
|
|
221
239
|
|
|
222
240
|
npm install
|
|
223
241
|
npm run build
|
|
224
|
-
|
|
242
|
+
|
|
243
|
+
# @getsigit/sigit is the canonical package; @smbcloud/sigit is the
|
|
244
|
+
# pre-1.5.5 name, kept publishing so installs predating the rename
|
|
245
|
+
# keep updating. Its template points optionalDependencies at the
|
|
246
|
+
# @smbcloud platform packages.
|
|
247
|
+
for template in "package-main.json.tmpl" "package-compat.json.tmpl"; do
|
|
248
|
+
node ../scripts/render-main-package.cjs \
|
|
249
|
+
"./package.json" \
|
|
250
|
+
"${npm_package_version}" \
|
|
251
|
+
"${template}"
|
|
252
|
+
|
|
253
|
+
npm_package_name=$(node -p "require('./package.json').name")
|
|
254
|
+
|
|
255
|
+
# Same E404-only reading as the platform packages above: a registry
|
|
256
|
+
# failure must not look like an unpublished version.
|
|
257
|
+
if view_output=$(npm view "${npm_package_name}@${npm_package_version}" version 2>&1); then
|
|
258
|
+
echo "${npm_package_name}@${npm_package_version} already exists on npm, skipping publish"
|
|
259
|
+
continue
|
|
260
|
+
elif ! grep -q "E404" <<<"${view_output}"; then
|
|
261
|
+
echo "npm view failed while checking ${npm_package_name}@${npm_package_version}:" >&2
|
|
262
|
+
echo "${view_output}" >&2
|
|
263
|
+
exit 1
|
|
264
|
+
fi
|
|
265
|
+
|
|
266
|
+
npm publish --access public
|
|
267
|
+
done
|