01fb5a2703
There is no CI: the instance has no act_runner and none is planned, so releases are cut by hand. That makes `make check` the only thing standing between a mistake and the tracker, and it is one command: gofmt, vet, the suite with the cache defeated, `go mod verify`, a vendored build, and `kettle gen skills --check`. The last one is the invariant worth having — the plugin's SKILL.md command reference is generated from the binary's registry, so a flag that changed cannot ship with documentation that recommends the old one. `cli/cmd/release` publishes to Gitea using the same SDK the binary already vendors, which is a pleasing thing to be able to say: nothing third-party handles the artifacts. It is a second binary rather than a `kettle` subcommand on purpose — `kettle`'s command tree is what generates the plugin's skills, so a verb there ships to every operator, and publishing a release is build infrastructure. It is idempotent end to end: an existing release for the tag is reused, an asset of the same name is replaced rather than doubled, and a retried run converges instead of duplicating. `make release` refuses three things, each with its own message: a dirty working tree, a TAG that is not what `git describe` reports, and a tag the remote does not have. A release built from uncommitted code is unreproducible and nobody finds out until they need to reproduce it. `kettle version` reports the stamp, the toolchain and the VCS revision. The default is `dev`, and a hand build says so and means it — a binary out of somebody's working tree is not a release and must not claim to be one. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
187 lines
8.8 KiB
Markdown
187 lines
8.8 KiB
Markdown
---
|
|
name: project
|
|
description: Generated flag reference for the project-level `kettle` commands — `kettle init`, `kettle auth`, `kettle config`, `kettle gen`. Load it to look up the exact flags and defaults of one of those four, or when a command answers "no project" / "no login" and you need `kettle config` to say what this directory resolved to. The rules around initializing are /kettle:init and the credential workflow is /kettle:auth; this file is the flag table both of them point at.
|
|
---
|
|
|
|
# kettle project — the project itself
|
|
|
|
`kettle` resolves everything from one marker. `<project>/.kettle/` is created by
|
|
`kettle init` and never inferred: `.git` is in every clone, so a tool that
|
|
guessed a root from one would write issues into whatever tree it happened to be
|
|
standing in. With no marker anywhere the command stops and names the directories
|
|
it searched — that is an answer, not a fallback.
|
|
|
|
Two configuration files, and the split is the point. `<project>/.kettle/config.yaml`
|
|
holds the tracker repository and the **name** of a login; the name is worth
|
|
nothing on its own, which is what makes it safe inside a working tree.
|
|
`~/.config/kettle/logins.yaml` (0600, one per machine, `$KETTLE_CONFIG_HOME` or
|
|
`$XDG_CONFIG_HOME` move it) holds the tokens. `KETTLE_LOGIN`, `KETTLE_REPO`,
|
|
`KETTLE_URL` and `KETTLE_TOKEN` each override the file they shadow.
|
|
|
|
**No `kettle` on PATH?** `command not found: kettle` is the whole story — no
|
|
script and no `tea` invocation substitutes for it. Stop and tell the operator to
|
|
install it: `cd cli && go build -o ~/.local/bin/kettle ./cmd/kettle` in the
|
|
marketplace repository (go.mod requires **go 1.26**), or
|
|
`go install git.noodles.cam/claude-skills/marketplace/cli/cmd/kettle@latest`.
|
|
|
|
`kettle gen` is a maintainer command: it rewrites the generated region of these
|
|
SKILL.md files from the command registry the binary was built from. Run it after
|
|
changing the CLI, never to "fix" documentation by hand.
|
|
|
|
<!-- kettle:gen -->
|
|
**Generated from the kettle command registry by `kettle gen skills`.** Everything between the two markers is replaced on the next run — hand-written prose belongs outside them.
|
|
|
|
## `kettle auth list | add | remove <name>`
|
|
|
|
manage the tokens this machine holds
|
|
|
|
Credentials live in one file per machine, outside every working tree, mode
|
|
0600. A project pins a login by NAME; the name is worth nothing on its own,
|
|
which is what makes it safe to keep in a file inside the repository.
|
|
|
|
The token is read from standard input unless --token is given, because an
|
|
argument is in the shell history the moment it is typed:
|
|
|
|
kettle auth add --name noodles --url https://git.example.com < token.txt
|
|
pass show gitea/token | kettle auth add --name noodles --url https://git.example.com
|
|
|
|
`list` never prints a token. There is no flag to make it.
|
|
|
|
| flag | default | what it does |
|
|
| --- | --- | --- |
|
|
| `--name` | — | login name (add) |
|
|
| `--token` | — | token, if you would rather not use stdin (add) |
|
|
| `--url` | — | instance URL, e.g. https://git.example.com (add) |
|
|
| `--user` | — | account this token belongs to; documentation only (add) |
|
|
|
|
```bash
|
|
kettle auth list # what this machine holds
|
|
pass show gitea | kettle auth add --name noodles --url https://git.example.com # add one, token on stdin
|
|
kettle auth remove noodles # forget it
|
|
```
|
|
|
|
## `kettle config`
|
|
|
|
show what this project resolved to
|
|
|
|
Every path and every setting, with the overrides already applied, so a run that
|
|
went somewhere unexpected can be explained without guessing.
|
|
|
|
The token is never printed — only whether one was found.
|
|
|
|
This is the command to reach for when the store looks empty, when a push says
|
|
401, or when two directories disagree about which project they are in.
|
|
|
|
```bash
|
|
kettle config # resolved paths and settings
|
|
```
|
|
|
|
## `kettle gen skills`
|
|
|
|
write the plugin's SKILL.md files from the command registry
|
|
|
|
A SKILL.md tells an agent how to invoke this binary. Hand-written, it drifts: a
|
|
flag is renamed here and the documentation goes on recommending the old one,
|
|
and the agent that reads it fails in a way nobody traces back to a stale
|
|
sentence. Everything those files say about a command — its usage line, its
|
|
flags with their defaults, its worked examples — is already in the registry
|
|
this binary is built from, so it is written from there and cannot disagree.
|
|
|
|
THE GENERATOR OWNS A REGION, NOT A FILE. Each SKILL.md carries a pair of HTML
|
|
comment markers — `kettle:gen` to open and `/kettle:gen` to close, both written in
|
|
the `<!-- … -->` form and visible at the top and bottom of the block below.
|
|
Everything between them is replaced on every run; every byte outside them comes
|
|
back exactly as it was, which matters most for `description:`, the prose that
|
|
decides whether an agent loads the skill at all, and the one thing here that no
|
|
generator can write.
|
|
|
|
A file with no markers is REPORTED AND LEFT ALONE, never overwritten: clobbering
|
|
somebody's prose because they forgot a marker is the failure this design exists
|
|
to prevent. A file that does not exist yet is created with a frontmatter stub
|
|
around a generated block, for a human to fill in.
|
|
|
|
The output is deterministic to the byte — no timestamps, no map iteration — so
|
|
regenerating something that has not changed produces no diff. --check is that
|
|
property made useful: it writes nothing and exits 1 when any file on disk
|
|
differs from what would be generated, which is what a pre-commit hook or a CI
|
|
step calls. It wins over --dry-run when both are given.
|
|
|
|
| flag | default | what it does |
|
|
| --- | --- | --- |
|
|
| `--check` | `false` | write nothing, exit 1 if anything is out of date |
|
|
| `--dry-run` | `false` | print what would change; write nothing |
|
|
| `--out` | — | directory the skills live in; one <group>/SKILL.md under it |
|
|
|
|
```bash
|
|
kettle gen skills --out ../plugins/kettle/skills # write the region in every group's SKILL.md
|
|
kettle gen skills --out ../plugins/kettle/skills --dry-run # print what would change; write nothing
|
|
kettle gen skills --out ../plugins/kettle/skills --check # exit 1 if the docs are out of date
|
|
```
|
|
|
|
## `kettle init`
|
|
|
|
make this directory a project that tracks issues
|
|
|
|
Creates `.kettle/` — the marker every other command resolves the store from,
|
|
and `.kettle/config.yaml`, which says which tracker repository these issues
|
|
belong to and which login to reach it under.
|
|
|
|
The marker is deliberately something an operator makes, not something inferred
|
|
from the tree: `.git` is in every clone, so anything that inferred a root from
|
|
one would write issues into whatever it happened to be installed in.
|
|
|
|
--login pins a name, never a credential. The tokens live in one file per
|
|
machine, outside every working tree, managed with `kettle auth`.
|
|
|
|
All of it is idempotent: it creates .kettle/issues and .kettle/payload, migrates
|
|
an older store in if it finds one (either layout the tea plugin used, oldest
|
|
first), writes the config without disturbing settings it was not given, and adds
|
|
.kettle/ to .gitignore. Each migration is a move, not a copy — two stores is the
|
|
state the marker exists to prevent — and it refuses to pick a winner when both
|
|
sides hold a file of the same name.
|
|
|
|
Do NOT run this inside a linked worktree. A worktree is the same project on
|
|
another branch and reaches the store by a hop out to the main checkout; a marker
|
|
here would give one project two stores, and the directory holding the second one
|
|
disappears with the branch.
|
|
|
|
| flag | default | what it does |
|
|
| --- | --- | --- |
|
|
| `--at` | — | directory to initialize (default: the working directory) |
|
|
| `--dry-run` | `false` | report what would happen; change nothing |
|
|
| `--login` | — | name of a login in the machine-wide file (see `kettle auth`) |
|
|
| `--repo` | — | tracker repository, as owner/name |
|
|
|
|
```bash
|
|
kettle init # initialize the current directory
|
|
kettle init --login noodles --repo claude-skills/marketplace # and point it at a tracker
|
|
kettle init --at ~/code/x # initialize somewhere else
|
|
kettle init --dry-run # say what it would do, touch nothing
|
|
```
|
|
|
|
## `kettle version`
|
|
|
|
print the version this binary was built as
|
|
|
|
A binary that cannot say what it is, is a support problem: an operator with an
|
|
old copy on PATH and a skill written against a newer one has no way to see the
|
|
mismatch, and neither does anybody reading their transcript.
|
|
|
|
The version is stamped at link time. A build from source says "dev" and means
|
|
it — that is not a placeholder to be edited, it is the answer for a binary that
|
|
came out of somebody's working tree rather than off a tag.
|
|
|
|
The commit is reported when the build recorded one, which `go build` does from
|
|
git and a build from an unpacked tarball cannot. A tree with uncommitted
|
|
changes in it says so beside the commit.
|
|
|
|
| flag | default | what it does |
|
|
| --- | --- | --- |
|
|
| `--short` | `false` | print the version alone, with nothing around it |
|
|
|
|
```bash
|
|
kettle version # the version, the toolchain and the commit
|
|
kettle version --short # just the version, for a script
|
|
```
|
|
<!-- /kettle:gen -->
|