scoop-distribution
Maintain the Windows Scoop release channel: the per-repo manifest template and config, the publish-scoop-manifest job, and the shared xberg-io/scoop-bucket.
Skill by xberg-io
Install
Works with Claude Code, Claude apps, Codex, Cursor, Gemini CLI, GitHub Copilot, VS Code, OpenCode, Goose, Windsurf. Read the repository before you give any tool access to your data.
npx agentmarket install skill/xberg-io-scoop-distribution
Asks which of your tools to add it to (Claude Code, Codex, Cursor, VS Code, Windsurf, Gemini CLI, Claude Desktop) and shows the change first. See https://agentmart.dev/cli.
Get the weekly diff
The weekly diff: one email a week with new agent tools, notable updates and grade changes, plus security alerts for tools you follow. Double opt-in, one-click unsubscribe.
About
Use cases: writing
Reviews
Write a reviewNo reviews yet. Installed it? Reviews come from verified installers only. How reviews work
Permissions
What this skill can do and what it asks for, from its SKILL.md. Checked Oct 25, 2026.
- Tools
- No tools found
- Secrets
- None asked for
- Install scripts
- None found
Network hosts it talks to 1
codeload.github.com· found in install command
Files it touches
~/.claude/skills/scoop-distribution
What's inside
- Skill name
scoop-distribution- Description
- Maintain the Windows Scoop release channel: the per-repo manifest template and config, the publish-scoop-manifest job, and the shared xberg-io/scoop-bucket. Use this skill when editing anything under scripts/publish/*.json.tmpl or scripts/publish/scoop.json, when adding a CLI to the bucket, or when a Scoop install fails after a release.
- License
- MIT
- Instructions
- 121 lines in SKILL.md · view on GitHub
Agent Skills spec issues
- name: missing
- files: referenced but missing: scripts/publish/scoop.json
Files (2)
- SKILL.md
- index.md
SKILL.md (first lines)
# Scoop Distribution
Scoop is the Windows counterpart of the Homebrew tap. Each publishing repo owns one manifest
template; the release pipeline renders it and pushes the result into `xberg-io/scoop-bucket`.
The bucket is generated output — never hand-edit `bucket/*.json` there, because the next
release of the owning repo overwrites it wholesale.
Per repo:
<!-- ~keep The example manifest is supplied by the consuming product repository. -->
<!-- ai-rulez-lint-ignore: AR402 ~keep -->
- `scripts/publish/scoop.json` — which manifests to render, and which release asset each SHA
placeholder binds to
- `scripts/publish/<app>.json.tmpl` — the manifest template
- a `publish-scoop-manifest` job, mirroring `publish-homebrew-formula` in the same workflow
<!-- ai-rulez-lint-ignore: AR402 ~keep -->
alef differs: `scripts/publish/scoop-manifests.json` with its own `commit-scoop-manifest.sh` and
`compute-scoop-gate.sh`, and `scoop` is an opt-in release target. Read its `publish.yaml`.
## The two escaping traps
Templates are rendered with Python `string.Template.substitute`, so **every literal `$` in the
manifest must be doubled**. Two of them appear in every template:
- `"$$schema"` — a bare `"$schema"` is read as the placeholder `$schema` and raises `KeyError`,
failing the render. Loud, so you find it immediately.
- `$$version` inside `autoupdate` — this is Scoop's own placeholder, expanded by Scoop when it
detects a new release. A bare `$version` there is **not** an error: it renders to the current
release's version and silently freezes `autoupdate` on it forever.
The second is the one that bites, because a frozen `autoupdate` looks correct in review and in
the rendered manifest. Assert on it: the published `autoupdate` block must still contain a
literal `$version`, while the top-level `architecture` URLs must contain a concrete number.
## `extract_dir` cannot be derived
The repos do not package their Windows zips identically, and there is no rule that maps an asset
name to its inner layout. Get this wrong and `bin` resolves to nothing — the manifest hashes and
validates perfectly and installs a broken shim.
Each repo records its own app's layout next to its template. The shapes seen so far: nested in a
directory named after the asset (`<app>-cli-x86_64-pc-windows-msvc`), nested with the **version in
the directory name** (`<app>-${version}-x86_64-pc-windows-msvc`), and **flat**, with the `.exe` at
the zip root, where `extract_dir` is omitted entirely.
Confirm with `unzip -l <asset>` against the actual release before trusting any of these; a repo
can change its packaging without anyone noticing the manifest went stale.
## Render locally instead of waiting for CI
A template change is cheap to verify end to end. This downloads the real asset, hashes it, and
writes the manifest exactly as the release job would:
```bash
git -C ../actions show origin/main:publish-scoop-manifests/scripts/render.py > /tmp/render.py
mkdir -p /tmp/bkt/bucket
GITHUB_WORKSPACE="$PWD" \
INPUT_BUCKET_DIR=/tmp/bkt \
INPUT_CONFIG_FILE="$PWD/scripts/publish/scoop.json" \
INPUT_TAG=v1.2.3 INPUT_VERSION=1.2.3 \
INPUT_GITHUB_REPO=xberg-io/<repo> INPUT_DRY_RUN=false \
python3 /tmp/render.py
```
Diff the result against the manifest currently in the bucket: for a released version it should
come out byte-identical, and for a new one the only change should be the version and hashes.
Set `INPUT_DRY_RUN=true` to render against a tag that does not exist yet — assets are replaced
with a zero-SHA placeholder and the run still succeeds, which is what the dry-run pipeline does.
## Adding a release target (`scoop` or any other)
A repo's release targets (for example `release_scoop`) come from `alef release-metadata`, not from
the workflow YAML. alef's `ALL_RELEASE_TARGETS` must already contain the target, **and an alef
release carrying it must be published**, before any repo can name it: `parse_targets` hard-fails on
an unknown name, so adding it to an explicit `available-targets:` list too early breaks that repo's
release. Repos that pass no `available-targets` default to all targets and need no edit. Until then
the wiring is inert: the target resolves to an empty string and its job's gate is false.
## Job shape
Copy the repo's own `publish-homebrew-formula` rather than inventing one — in particular its
five-attempt rebase/push loop. Six release pipelines push to the single shared bucket, so a
concurrent release can land between checkout and push and reject it as non-fast-forward. Each
repo touches only its own manifest, so rebasing onto the new tip and retrying is safe.
Two deliberate differences from the Homebrew job:
- **No `check-scoop` idempotency gate.** The render rewrites the manifest in place and the commit
is guarded by `git diff --quiet bucket/`, so re-running a release is already a no-op. Pass no
fourth argument to `require_publish` — there is no "already published" probe to consult.
- **The job runs on dry runs; only the commit step is skipped.** Dry-run renders are the only
pre-release exercise the template gets. Gating the whole job on `dry_run != 'true'` removes
that safety net.
## Native dependencies
Every CLI is a native MSVC build importing `VCRUNTIME140.dll`, so every manifest carries
`"suggest": {"vcredist": "extras/vcredist2022"}`.
Check the import table before adding an app — `llvm-objdump -p <exe> | grep 'DLL Name'`. A
third-party hard import that is not bundled in the zip produces a binary that cannot start at
all, and no amount of manifest correctness fixes it. A hard-imported third-party DLL must be vendored
into the archive by the publish job; Scoop's shim resolves DLLs from the app directory, so
bundling is sufficient and no `depends` entry is needed. A runtime lookup on `PATH` (an external
tool the CLI shells out to) belongs in `notes`, not in `depends`.
## What actually proves an install works
Nothing on macOS or Linux does. Schema validation, a correct hash, and a byte-identical render
all pass on a manifest that installs a binary which cannot launch. The only real proof is the
`windows-latest` job in the bucket's `validate-manifests.yml`, which adds the checkout as a
bucket, installs each changed app, and runs `<app> --version`. Treat a green local check as
"nothing is obviously wrong", not as "this installs".From xberg-io/agent-conventions, MIT.
More from xberg-io/agent-conventions
- 0.564score
release-workflow
xberg-io
Release/publish a Rust core crate or CLI in an xberg-io polyglot repo (crawlberg, html-to-markdown, xberg, tree-sitter-language-pack, liter-llm).
SkillAFreshness: A★ 8Claude Code +9 - 0.564score
tracing-conventions
xberg-io
The canonical contract for tracing as a first-class product observability surface across xberg-io Rust libraries and services — level semantics, span/field…
SkillAFreshness: A★ 8Claude Code +9 - 0.564score
xberg-brand-and-docs
xberg-io
Canonical xberg.io brand, product catalog, docs-site (Astro Starlight + @xberg-io/docs-theme), alef badge, docs task commands, prose style, Google Analytics…
SkillAFreshness: A★ 8Claude Code +9 - 0.564score
agent-coordination
xberg-io
How to dispatch, monitor, recover, and trust subagents and worktree-isolated peers safely in a repo other agents may also be touching.
SkillAFreshness: A★ 8Claude Code +9 - 0.564score
consumer-release-gates
xberg-io
Reproduce an alef-generated consumer repo's release gate locally before cutting a release, and verify published package names against the real manifest rather…
SkillAFreshness: A★ 8Claude Code +9 - 0.564score
binding-architecture
xberg-io
Architecture rules for the polyglot binding layer and the C FFI boundary — crate naming, distribution paths, ownership and null-safety invariants…
SkillAFreshness: A★ 8Claude Code +9 - 0.564score
feature-flag-conventions
xberg-io
The shared Cargo feature-flag naming and semantics contract across xberg-io Rust libraries — the same flag names mean the same thing everywhere (otel…
SkillAFreshness: A★ 8Claude Code +9 - 0.561score
quick-start
xberg-io
Developer quick-start for xberg-io repos — prerequisites, initial setup, and the core build/test/lint workflow.
SkillAFreshness: A★ 8Claude Code +9 - 0.561score
basemind-tools
xberg-io
How to use basemind's MCP tools and CLI for structural and historical code questions instead of grep, file reads, and naked git.
SkillAFreshness: A★ 8Claude Code +9 - 0.561score
taskfile-structure
xberg-io
Standard Taskfile conventions across xberg-io repos — task discovery, common and language-scoped tasks, build profiles, the alef and e2e task families…
SkillAFreshness: A★ 8Claude Code +9 - 0.561score
create-e2e-fixture
xberg-io
How to author a new e2e test fixture for cross-language test generation — fixture fields, assertion types, and id conventions.
SkillAFreshness: A★ 8Claude Code +9 - 0.561score
poly-lint-format
xberg-io
Reference for poly, the single-binary multi-language linter and formatter — per-language engines, the lint/fmt commands, poly.toml configuration, severity…
SkillAFreshness: A★ 8Claude Code +9
Signals
- Stars
- 8
- Forks
- 2
- Open issues
- 0
- Last commit (this folder)
- Oct 14, 2026 (15 days ago)
From GitHub (fetched Oct 24, 2026).
Details
- License
- MIT
- Repository
- github.com/xberg-io/agent-conventions
- First seen
- Oct 24, 2026
- Last checked
- Oct 24, 2026
- Source
- GitHubgithub-graphql
More from xberg-io
- 0.769score
feature-flag-policy
xberg-io
Cargo feature flags for crates/xberg — ORT-incompatible targets (WASM, Android x86_64 emulator), type-only and tract inference companion features…
SkillAFreshness: A★ 9.4KClaude Code +9 - 0.769score
crate-structure
xberg-io
The Xberg workspace layout — the version source of truth (root Cargo.toml [workspace.package] version), the 19 workspace members and 3 excluded crates, the…
SkillAFreshness: A★ 9.4KClaude Code +9 - 0.769score
config-loading-precedence
xberg-io
How Xberg resolves configuration — CLI-mode and server/MCP-mode precedence orders, project config walk-up, user config fallback, field-level inline JSON merge…
SkillAFreshness: A★ 9.4KClaude Code +9 - 0.769score
alef-generated-bindings
xberg-io
Alef-managed generated bindings in packages/* and binding crates — the regeneration workflow (task alef:generate / alef:verify), the alef.toml section layout…
SkillAFreshness: A★ 9.4KClaude Code +9 - 0.769score
wasm-constraints
xberg-io
WASM build constraints for the crates/xberg-wasm crate — the wasm-target feature set, no-tokio sync-only internal APIs, the crate-private SyncExtractor trait…
SkillAFreshness: A★ 9.4KClaude Code +9 - 0.769score
mime-detection-routing
xberg-io
MIME type detection and extractor routing in core/mime.rs — the FORMATS registry that EXT_TO_MIME and SUPPORTED_MIME_TYPES are derived from, the path-based…
SkillAFreshness: A★ 9.4KClaude Code +9
Cite this page
scoop-distribution skill. Agent Mart. https://agentmart.dev/skills/xberg-io-scoop-distribution (last updated 2026-10-24)