Commit 3122294
GitHub release assets for q2: installers + minisign + bundled quarto-hub.com MCP defaults (bd-c6l13j79) (#278)
* feat(mcp-launcher): bundled quarto-hub.com defaults via option_env (bd-c6l13j79)
Release builds of q2 compile in defaults for the three env vars the TS
MCP server reads (QUARTO_HUB_MCP_CLIENT_ID/CLIENT_SECRET, QUARTO_HUB_SERVER)
from QUARTO_HUB_BUNDLED_{CLIENT_ID,CLIENT_SECRET,SERVER} build-time env
(set only by the release workflow, from GH secrets/vars). The launcher
injects them into the node child's environment for any variable the
user hasn't set to a non-blank value — readNonEmpty semantics mirrored
from oauth-config.ts, so blank counts as unset. Source builds compile
with no values and behave exactly as before (TS server's own error).
The Desktop-app OAuth client_secret is a public client credential
(RFC 8252) — embedding is the standard native-app distribution (gcloud,
gh, rclone); CI-time injection only keeps GOCSPX- scanners away from
the repo. Plan: claude-notes/plans/2026-06-12-q2-github-releases-bundled-mcp.md
- src/defaults.rs: bundled_defaults() + classify/injections/sources
pure logic, unit-tested (9 tests)
- delegate.rs: build_command seam (testable — the Unix path execs and
cannot be observed by a test); env injection ahead of the
exec/spawn split (2 tests)
- --launcher-info gains 'default <VAR>: env|bundled|absent' lines
(values uniformly elided; printed for placeholder builds too)
- .gitignore: /q2-release.{key,pub} — release signing keypair must
never be committed
Verified end-to-end with test values baked into a local build: child
process receives bundled values only for unset vars; user env wins;
absent-defaults build injects nothing. 35/35 launcher tests pass.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* feat: q2 release installers (install.sh/install.ps1) + offline test harness (bd-c6l13j79)
Ported from cscheid/braid's release tooling (study copy in
external-sources/braid): checksum + minisign Ed25519 verification both
mandatory and fail-closed, trusted comment = archive filename (replay
protection), atomic install, non-interactive under curl|bash. q2
deltas: flat archive (the MCP bundle is embedded in the binary), Q2_*
env vars, --from-source builds the MCP bundle when npm is present,
unsupported-platform advice points at --from-source. The pinned
signing key is 91F595A50BD20376 (public half; the secret lives in the
MINISIGN_SECRET_KEY repo secret).
- crates/quarto/tests/integration/bootstrap_sh.rs: 32 offline tests
(file:// + --checksum; no network), covering refusal paths, signature
replay, tampering, dest resolution, quiet mode, uninstall, shellcheck
- test-suite.yml: install minisign on both runners (the suite requires
it loudly — silent skip would leave the signature contract unguarded)
- README: Installing section with pinned pubkey + manual verification
Plan: claude-notes/plans/2026-06-12-q2-github-releases-bundled-mcp.md
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* feat(hub-mcp): target-aware keyring staging for the bundle (bd-c6l13j79)
The .node addon ships inside the bundle's mini node_modules and is
loaded by the *user's* node, so it must match the release target, not
the build host — braid-style release matrices cross-build darwin_amd64
on arm64 runners, where only keyring-darwin-arm64 is installed.
scripts/stage-keyring.mjs (split from bundle.mjs, injectable fetcher):
- KEYRING_PLATFORMS env (e.g. 'darwin-x64,darwin-arm64') pins exactly
which platform packages ship; missing ones are fetched via npm pack
at the loader's exact version
- unset → original dev behavior (stage every installed platform pkg)
- fail-closed: unfetchable platform or addon-less package aborts
10 offline unit tests (fake fetcher, fabricated @napi-rs trees) in
src/keyring-staging.test.ts. Real-fetch path verified by hand on this
arm64 mac: KEYRING_PLATFORMS=darwin-arm64,darwin-x64 staged a Mach-O
x86_64 keyring.darwin-x64.node via npm pack. Full package suite green
(194 passed; requires QUARTO_HUB_MCP_* unset — exported operator
credentials make spawned test servers register auth tools).
Plan: claude-notes/plans/2026-06-12-q2-github-releases-bundled-mcp.md
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* feat: release workflow + real CLI version (bd-c6l13j79)
.github/workflows/release.yml, ported from cscheid/braid with q2's
three-embedded-payloads reality:
- preflight: tag must match the workspace Cargo.toml version
- web-payloads job builds the target-independent embeds once (WASM →
preview SPA, trace viewer; toolchain mirrors hub-client-e2e.yml,
wasm-bindgen-cli pinned from Cargo.lock); the 5-target matrix
downloads them and builds the MCP bundle per target with
KEYRING_PLATFORMS (user-node addons: both libcs on linux, both mac
archs, both win archs)
- bundled hub defaults injected from secrets/vars into the cargo env,
release workflow only, with an empty-value fail-fast
- per-target verify step: --version equals the tag version; launcher
info shows no PLACEHOLDER, 'default …: bundled' ×3, and a keyring
addon per requested platform (the anti-stale-embed gate)
- archives + sha256 + minisign (trusted comment = filename),
self-verified against the install.sh pinned key; combined
checksums.sha256; gh release create (prerelease on -suffix tags)
CLI version contract change (Carlos, in-session): q2 --version now
reports the real workspace version ('quarto 0.1.0') instead of the
99.9.9-dev extension-compat placeholder — release artifacts must be
verifiable against their tag, and Lua-side quarto.version already
reported {0,1,0}. TDD'd (red first) in quarto-util. The since_version
99.9.9 markers in error_catalog.json are a separate concern, untouched.
Also: musl-scoped openssl-sys/vendored in crates/quarto (samod →
tokio-tungstenite(native-tls) needs openssl; static musl builds get it
from source), and a semver-compliant deprecated-since in
quarto-source-map (pre-existing deny-level clippy error, on-topic with
the version decision). Remaining pre-existing clippy deny in
quarto-core filed as bd-3up1mf8c.
Full workspace suite after the version change: 10038/10038 passed.
Plan: claude-notes/plans/2026-06-12-q2-github-releases-bundled-mcp.md
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>1 parent 6bd9d59 commit 3122294
19 files changed
Lines changed: 3295 additions & 60 deletions
File tree
- .github/workflows
- claude-notes/plans
- crates
- quarto-mcp-launcher/src
- quarto-source-map/src
- quarto-util/src
- quarto
- tests/integration
- ts-packages/quarto-hub-mcp
- scripts
- src
Large diffs are not rendered by default.
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
107 | 107 | | |
108 | 108 | | |
109 | 109 | | |
| 110 | + | |
| 111 | + | |
| 112 | + | |
| 113 | + | |
| 114 | + | |
| 115 | + | |
| 116 | + | |
| 117 | + | |
| 118 | + | |
| 119 | + | |
| 120 | + | |
| 121 | + | |
110 | 122 | | |
111 | 123 | | |
112 | 124 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
44 | 44 | | |
45 | 45 | | |
46 | 46 | | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
6 | 6 | | |
7 | 7 | | |
8 | 8 | | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
9 | 51 | | |
10 | 52 | | |
11 | 53 | | |
| |||
0 commit comments