Skip to content

Releases: 0xble/toolkit

v0.1.16

Choose a tag to compare

@0xble 0xble released this 16 Oct 02:40
6e6b8e1

Skip unchanged nightlies

  • New nightly-guard composite 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_dispatch runs 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.yml runs the guard on ubuntu-slim and needs actions: read. Callers must grant permissions: actions: read.

v0.1.15

Choose a tag to compare

@0xble 0xble released this 13 Oct 01:13
cc22cae

Faster schema copies

  • op.cloneSchema now uses a reflective deep copy instead of a JSON round trip. Copies stay fully independent: every slice, map, pointer and json.RawMessage is copied.
  • mcp.NewServer and api.Handler reuse 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.json builds the document per request from current entries, so op.Add and metadata edits still show up immediately.
  • InputSchema(), OutputSchema() and OpenAPI() 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

Choose a tag to compare

@0xble 0xble released this 11 Oct 06:11
57cbf96

Duplicate-send protection

  • Add process-safe sendguard outbound-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_send to 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

Choose a tag to compare

@0xble 0xble released this 11 Oct 03:39
35e1c71

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.yml takes a new caller-qualification input (default false) and exposes a lane-result output: the status of the exact-SHA gate lane. A skipped lane emits nothing.
  • With caller-qualification: true, the reusable gate / qualification job is skipped. The caller's own qualification job must then run with if: always() and require both needs.gate.result and needs.gate.outputs.lane-result to equal success. A reusable workflow whose jobs were all skipped can report success, so checking its result alone is unsafe. Toolkit's .github/workflows/gate.yml is 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 plain qualification check, or have no protection at all, can opt in.
  • On an opted-in caller, a draft PR fails with gate not qualified rather than draft: 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

Choose a tag to compare

@0xble 0xble released this 11 Oct 01:06
3e7de60

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.yml and tool-nightly.yml take an optional apt-packages input, a space-separated list of Ubuntu packages. They run apt-get update, then install the list with --no-install-recommends before ./bin/ci gate or ./bin/ci nightly. The input is ignored when ci-image-dir is set, so image-mode CI is unchanged. Callers that leave it empty see no change.
  • tool-nightly.yml now picks its runner from runner, then vars.CI_NIGHTLY_RUNNER, then vars.CI_RUNNER, then ubuntu-24.04. A repository that sets CI_RUNNER but not CI_NIGHTLY_RUNNER now runs its nightly on the CI_RUNNER label instead of ubuntu-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

Choose a tag to compare

@0xble 0xble released this 09 Oct 22:17
d0db6a3

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.yml and tool-nightly.yml resolve the minor from go-version-file (toolchain first, then go, including go.work, .go-version and .tool-versions) and ask actions/setup-go for the latest patch of that minor. A caller pinned at go 1.26.8 now builds and runs govulncheck with go1.26.9.
  • toolchain default falls back to the go line. Prerelease toolchains such as go1.27rc1 keep the previous behaviour: setup-go reads the file directly, without check-latest.
  • Image mode (ci-image-dir) is unchanged.

v0.1.10

Choose a tag to compare

@0xble 0xble released this 08 Oct 06:00
ffae84c

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, -y and other flags are unchanged. A stray negative number now fails with unexpected argument -40 rather than unknown flag -4.
  • An explicit CLI value equal to the zero value now reaches the operation when its input field has a default tag and omitempty: --level 0, --enabled=false, --label "", a root flag such as --limit 0, and a flag's env var set to 0. Before, the default replaced it. HTTP and MCP already kept an explicit 0, false or "".
  • An int64 or uint64 input 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).Decode used to read every number as float64, so 5312241539987020022 arrived as 5312241539987019776 and 18446744073709551615 failed to decode into a uint64. --fields output likewise keeps such integers exact, paged or not. Numbers written with a fraction or exponent still decode as before, so 1.0 and 1e3 still fill an integer field.
  • Input default tags 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 with default tags 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 a default on it is written as a JSON string ("7", not 7). 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

Choose a tag to compare

@0xble 0xble released this 07 Oct 05:36
953081f

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

Choose a tag to compare

@0xble 0xble released this 06 Oct 23:06
165de03
  • op.Op.CLIConfirmed makes the command line the confirmation of a
    destructive CLIImmediate operation: the CLI applies it without --yes
    or a prompt, and --dry-run still previews. HTTP and MCP still need
    "apply": true and "confirm": true. Add rejects it unless the effect
    is destructive and CLIImmediate is set. It shows as cli_confirmed in
    the metadata, x-cli-confirmed in OpenAPI and toolkit/cli_confirmed
    (mcp.MetaCLIConfirmed) in the MCP tool _meta, and the conformance kit
    checks that the CLI applies without --yes.

v0.1.7

Choose a tag to compare

@0xble 0xble released this 05 Oct 18:53
94a71ef
  • op.Request.Meta carries a copy of an MCP tool call's request _meta on
    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 with invalid_allow_apply. It adds to the tool's
    own authorizer.