Repository navigation
Releases: 0xble/toolkit
Release list
v0.1.16
Skip unchanged nightlies
- New
nightly-guardcomposite action (.github/actions/nightly-guard). A scheduled nightly skips its expensive lane only when the latest successful scheduled run already covers the current default-branch SHA and finished less than seven days ago. - Manual
workflow_dispatchruns always run, and the seven-day floor keeps drift coverage for dependencies and external services. - The guard fails open: any API error, parse failure or ambiguity runs the nightly. An intentional skip counts as healthy in qualification.
tool-nightly.ymlruns the guard onubuntu-slimand needsactions: read. Callers must grantpermissions: actions: read.
v0.1.15
Faster schema copies
op.cloneSchemanow uses a reflective deep copy instead of a JSON round trip. Copies stay fully independent: every slice, map, pointer andjson.RawMessageis copied.mcp.NewServerandapi.Handlerreuse each entry's cached schema copies instead of copying every schema for each server, handler or call. The cache is held weakly, so it never keeps a registry alive.GET /openapi.jsonbuilds the document per request from current entries, soop.Addand metadata edits still show up immediately.InputSchema(),OutputSchema()andOpenAPI()still return caller-owned copies. No public API changes and no expected golden changes.
Tools with many large operations get much faster tests: mercury's -race ops pass drops from about 265s to 73s.
Full change: #25
v0.1.14
Duplicate-send protection
- Add process-safe
sendguardoutbound-send claims with a flock-protected, pruned ledger and optional remote history checks. - Store only a SHA-256 digest rather than account, destination, or body text.
- Preserve uncertain attempts as unverified, with explicit duplicate overrides for intentional repeated sends.
- Map
duplicate_sendto CLI exit 4 and HTTP 409 across operation surfaces. - Bound claim-finalization locks, fsync the ledger parent directory, and recover safely from an unterminated trailing ledger record.
- Use golang.org/x/text v0.39.0 to address GO-2026-5970.
v0.1.13
The reusable gate can fold its qualification check into the caller's required qualification job, so an opted-in tool pays for one aggregation job per run instead of two.
tool-gate.ymltakes a newcaller-qualificationinput (defaultfalse) and exposes alane-resultoutput: the status of the exact-SHA gate lane. A skipped lane emits nothing.- With
caller-qualification: true, the reusablegate / qualificationjob is skipped. The caller's ownqualificationjob must then run withif: always()and require bothneeds.gate.resultandneeds.gate.outputs.lane-resultto equalsuccess. A reusable workflow whose jobs were all skipped can report success, so checking its result alone is unsafe. Toolkit's.github/workflows/gate.ymlis the reference. - Don't opt in where branch protection requires
gate / qualification, because that check is skipped once you opt in. Repositories that require the plainqualificationcheck, or have no protection at all, can opt in. - On an opted-in caller, a draft PR fails with
gate not qualifiedrather thandraft: gate not run. It still fails closed. - The default leaves existing callers unchanged. The Go module API, CLI parsing and output are unchanged from v0.1.12, so no caller goldens should change.
Opting in means editing the caller's gate workflow:
jobs:
gate:
uses: 0xble/toolkit/.github/workflows/tool-gate.yml@v0.1.13
with:
caller-qualification: true
qualification:
runs-on: ubuntu-slim
needs: [gate]
if: always()
steps:
- env:
GATE_RESULT: ${{ needs.gate.result }}
LANE_RESULT: ${{ needs.gate.outputs.lane-result }}
run: |
[ "$GATE_RESULT" = success ] && [ "$LANE_RESULT" = success ]v0.1.12
Runner-mode reusable gate and nightly workflows can now install Ubuntu APT packages before ./bin/ci runs, and the nightly falls back to the primary runner.
tool-gate.ymlandtool-nightly.ymltake an optionalapt-packagesinput, a space-separated list of Ubuntu packages. They runapt-get update, then install the list with--no-install-recommendsbefore./bin/ci gateor./bin/ci nightly. The input is ignored whenci-image-diris set, so image-mode CI is unchanged. Callers that leave it empty see no change.tool-nightly.ymlnow picks its runner fromrunner, thenvars.CI_NIGHTLY_RUNNER, thenvars.CI_RUNNER, thenubuntu-24.04. A repository that setsCI_RUNNERbut notCI_NIGHTLY_RUNNERnow runs its nightly on theCI_RUNNERlabel instead ofubuntu-24.04.
The Go module API, CLI parsing and output are unchanged from v0.1.11, so no caller goldens should change.
v0.1.11
Runner-mode reusable gate and nightly workflows now install the newest Go patch in each caller's declared minor, so a stdlib security fix reaches every tool without editing its go.mod.
tool-gate.ymlandtool-nightly.ymlresolve the minor fromgo-version-file(toolchainfirst, thengo, includinggo.work,.go-versionand.tool-versions) and askactions/setup-gofor the latest patch of that minor. A caller pinned atgo 1.26.8now builds and runs govulncheck with go1.26.9.toolchain defaultfalls back to thegoline. Prerelease toolchains such asgo1.27rc1keep the previous behaviour: setup-go reads the file directly, withoutcheck-latest.- Image mode (
ci-image-dir) is unchanged.
v0.1.10
The CLI accepts negative numbers and keeps explicit zero values, large integers stay exact on every surface, and nested default and json:",string" tags follow encoding/json.
- The CLI accepts a negative number as a flag value or positional argument:
--min -5,temp -40 --side right,--ratio -0.5,-1e3. Tools no longer need--or argument rewriting for it. A digit declared as a short flag stays a flag, and-j,-yand other flags are unchanged. A stray negative number now fails withunexpected argument -40rather thanunknown flag -4. - An explicit CLI value equal to the zero value now reaches the operation when its input field has a
defaulttag andomitempty:--level 0,--enabled=false,--label "", a root flag such as--limit 0, and a flag's env var set to0. Before, the default replaced it. HTTP and MCP already kept an explicit0,falseor"". - An
int64oruint64input above 2^53, such as a Telegram message, chat, document or custom emoji ID, now reaches the operation exactly on the CLI, HTTP and MCP.op.(*Entry).Decodeused to read every number asfloat64, so5312241539987020022arrived as5312241539987019776and18446744073709551615failed to decode into auint64.--fieldsoutput likewise keeps such integers exact, paged or not. Numbers written with a fraction or exponent still decode as before, so1.0and1e3still fill an integer field. - Input
defaulttags now apply in nested struct fields, not only in embedded ones, on the CLI, HTTP and MCP. A pointer-to-struct section gets its defaults only when the caller sends it. An omitted section stays nil, so a handler can still tell absent from present. A tool whose input nests a struct withdefaulttags will now see those defaults where it saw zero values. - A
json:",string"tag now follows encoding/json everywhere. The input schema types such a field as a string, and adefaulton it is written as a JSON string ("7", not7). The tag is ignored on slices, maps, structs and pointers to pointers, as encoding/json ignores it. An explicit zero CLI value (--count 0,--enabled=false, an empty<id>) is sent in its quoted form. Each operation under a shared<id>path placeholder uses its own field's tag.
v0.1.9
Pin the reusable nightly vulnerability scanner to golang.org/x/vuln v1.7.0, compatible with callers using Go 1.25.x. The image and runner paths share the pin, and CI now checks both pin consistency and Go-toolchain compatibility before installation.
v0.1.8
op.Op.CLIConfirmedmakes the command line the confirmation of a
destructiveCLIImmediateoperation: the CLI applies it without--yes
or a prompt, and--dry-runstill previews. HTTP and MCP still need
"apply": trueand"confirm": true.Addrejects it unless the effect
is destructive andCLIImmediateis set. It shows ascli_confirmedin
the metadata,x-cli-confirmedin OpenAPI andtoolkit/cli_confirmed
(mcp.MetaCLIConfirmed) in the MCP tool_meta, and the conformance kit
checks that the CLI applies without--yes.
v0.1.7
op.Request.Metacarries a copy of an MCP tool call's request_metaon
stdio and HTTP MCP, nil when absent and always nil on the CLI and the HTTP
API. It is never read from the arguments.serve --allow-apply=OP[,OP...]allows applied calls to the listed write
and destructive operations on the HTTP API from a Unix socket peer running
as the server's uid, without a Tailscale identity header. Confirmation is
still required for destructive operations, and an unknown or read
operation fails startup withinvalid_allow_apply. It adds to the tool's
own authorizer.