• v0.1.0 8b1b11001a

    claude released this 2026-08-12 11:17:59 +00:00 | 0 commits to main since this release

    kettle is no longer a plugin. It installs itself into a project.

    go install git.noodles.cam/claude-skills/marketplace/cli/cmd/kettle@latest
    kettle init --interactive
    

    The plugin and the binary shipped on two release cadences, and nothing on an
    operator's machine ever checked that the one they installed described the other.
    The generated flag block existed precisely so a renamed flag could not ship with
    documentation recommending the old one — and then shipped one version behind the
    registry it came from, which is the same bug one hop downstream.

    The prose lives inside the binary now. kettle init and kettle gen scaffold
    write it into a project's own .claude/, and the two cannot disagree because
    there is one artefact. kettle config says when the tree on disk was written by
    an older build.

    Breaking

    • kettle gen skills is now kettle gen scaffold. It writes commands,
      skills and the runner subagent, into <project>/.claude by default.
    • Files are written whole. The old generator owned a region between
      <!-- kettle:gen --> markers and left the prose around it alone, because that
      prose was somebody's hand-written file. It is embedded now, so there is none to
      protect — and preserving local edits would freeze a project's documentation at
      whatever version first initialized it. --check warns before an upgrade
      discards one.
    • Uninstall the plugin. /plugin uninstall kettle@claude-skills, then
      kettle init in each project you tracked issues in. The marketplace still
      carries tdl, which has no binary and never needed one.

    Your .kettle/ store, your logins and your config are untouched.

    The slash commands survive

    A project's skills are flat, so the prefix is spelled into the directory name —
    kettle-issue, not issue. A project's commands take their namespace from a
    subdirectory, so /kettle:init, /kettle:auth, /kettle:issue, /kettle:sync,
    /kettle:api and /kettle:project are all still what you type.

    init and auth stopped being skills carrying disable-model-invocation: true
    and became commands, because a command is operator-invoked. auth now
    restricts allowed-tools so a model cannot reach kettle auth add at all.

    kettle init --interactive

    Walks you through the login, the token, the tracker repository, the .claude/
    tree and the mirror hook. The token is read with the terminal's echo off, so it
    lands in no shell history, no temp file and no scrollback — which is the one
    thing this can do that no flag can.

    It refuses a stdin that is not a terminal and names the flags instead. Every
    question it asks has one, and it performs nothing itself, so an interactive run
    and a flag run are the same code path:

    kettle init --login noodles --repo owner/name --mirror-hook
    kettle init --no-scaffold          # marker and config only
    

    kettle mirror

    Keeps CLAUDE.md a symlink to AGENTS.md in every directory below where it is
    run — two harnesses reading two filenames for one document otherwise keep two
    documents, and they drift.

    This was 141 lines of Python behind a filename that said .sh, shipped as a
    plugin hook. Same seven branches, same refusal to merge two real files whose
    contents differ, now with a table test per branch and a check that a repair
    converges in one pass.

    kettle mirror              # repair, and say what changed
    kettle mirror --check      # exit 1 if anything is out of place; write nothing
    kettle mirror --hook       # the PreToolUse form; exits 0 on every path
    

    --hook is opt-in per projectkettle init --mirror-hook, or one question
    in --interactive. That is strictly narrower than the plugin hook it replaces,
    which was on for everybody who installed the plugin in every repository they
    touched.

    Two rules that stopped being prose

    • init refuses a linked worktree and names the main checkout. A worktree
      reaches the main store on its own; a marker there gives one project two stores,
      and the second disappears with the branch.
    • An existing .claude/settings.json is never reformatted. Go cannot preserve
      JSON key order, so a merge would rewrite a file you commit and share.
      --mirror-hook prints the snippet to paste instead, and --force-settings is
      the way past it.

    Also

    • .kettle/scaffold.yaml records which build wrote a project's tree. Nothing
      resolves from it; deleting it costs the warning in kettle config and nothing
      else. It is a separate file because an unknown key in config.yaml is a hard
      error, and that file may be committed and read by whatever build each machine
      happens to have.
    • Two new packages, internal/mirror and internal/scaffold, both importing
      nothing but the standard library — mirror bans os/exec and scaffold bans
      os, each held by a layering test.
    • golang.org/x/term becomes a direct dependency. It was already in the tree
      indirectly, so no module was added.
    Downloads