structkit 3.3.0: .structkit.yaml, Config Layering, and Safer Hooks
structkit 3.3.0 is out. The default project file is now .structkit.yaml, with .struct.yaml still read as a fallback. You can set your CLI defaults once in a user config file. Hooks now ask before they run, can be restricted with an allowlist, and are off by default for MCP calls. The latest_release filter can strip the v or return the commit SHA. And Linux users get native .deb and .rpm packages. Upgrade with pip install -U structkit.
.structkit.yaml is the new default project file
structkit started life as STRUCT, so a lot of repositories commit a .struct.yaml. Starting with 3.3.0 the canonical name is .structkit.yaml:
structkit initcreates.structkit.yamlstructkit generatedefaults to.structkit.yamland falls back to.struct.yamlwhen that's the only file present- If both exist,
.structkit.yamlwins and structkit logs a note asking you to remove the legacy file
Why it matters: the file name now matches the tool, so it's easier to spot in a repo and easier for editors and CI tools to match on. Nothing breaks: existing .struct.yaml files keep working.
To rename yours:
git mv .struct.yaml .structkit.yamlConfig layering: set your defaults once
Tired of passing --file-strategy backup every time? CLI defaults are now merged from four layers, lowest to highest priority:
- Built-in defaults
- User config at
~/.config/struct/config.yaml, loaded automatically when it exists - Project config, but only the file you pass with
--config-file - CLI flags, which always win
# ~/.config/struct/config.yaml
structures_path: ~/my-custom-structures
input_store: ~/.cache/structkit/input.json
file_strategy: backup
log: WARNINGTo see what structkit will actually use, and where each value came from:
structkit config print
structkit config print --format json
structkit config print -c project-config.yamlWhy it matters: personal preferences stay on your machine, team defaults can live in a checked-in file you pass with --config-file, and one-off overrides still go on the command line.
Note:
.structkit.yamlis your structure definition. It is not auto-loaded as CLI config. Project-level CLI defaults only apply when you pass--config-file. See Configuration for the full list of supported keys.
Hook safety controls
pre_hooks and post_hooks run shell commands, which is powerful and also risky when you're generating from a structure you didn't write. 3.3.0 adds four guardrails:
- Interactive confirmation: structkit lists the hooks and asks before running them
- Skip hooks entirely:
--no-hooksorSTRUCTKIT_NO_HOOKS=true - Allowlist: a
.struct-hooks-allowlistfile (or--hooks-allowlist/STRUCTKIT_HOOKS_ALLOWLIST) limits which commands may run. Anything not listed fails generation. - MCP calls skip hooks by default (
no_hooks: true)
# .struct-hooks-allowlist
echo
git
python# CI: never run hooks
structkit generate .structkit.yaml --no-hooks
# Custom allowlist location
structkit generate .structkit.yaml --hooks-allowlist /path/to/allowlist.txtWarning:
--non-interactive(orSTRUCTKIT_NON_INTERACTIVE=true) without--no-hooksruns hooks without asking. In automation, pair it with an allowlist or turn hooks off.
Why it matters: you can now safely point structkit, or an AI assistant driving it, at a template from somewhere else. Details in Hooks.
latest_release: strip the v or get the commit SHA
The latest_release filter takes two new optional arguments, strip_v and return_sha:
files:
- release.txt:
content: |
{{@ "httpdss/structkit" | latest_release @}} # v3.3.0
{{@ "httpdss/structkit" | latest_release(strip_v=true) @}} # 3.3.0
{{@ "httpdss/structkit" | latest_release(return_sha=true) @}} # full commit SHAstrip_vremoves exactly one leading lowercasevreturn_shareturns the commit the release tag points to, following annotated tags. If you set both,return_shawins.- Calls without the new arguments behave exactly as before
Why it matters: version pins like version = "3.3.0" and SHA-pinned GitHub Actions can now be generated straight from a template. This also works for Terraform providers, for example {{@ "hashicorp/terraform-provider-aws" | latest_release(strip_v=true) @}}. Set GITHUB_TOKEN for private repos and higher rate limits. See Template Variables.
Native Linux packages (.deb / .rpm)
This is phase 1 of Linux packaging. Each published release now builds .deb (Debian/Ubuntu) and .rpm (Fedora/RHEL) packages for amd64 and arm64. The packages ship structkit in its own Python environment under /usr/lib/structkit/venv/, with a /usr/bin/structkit wrapper, so they don't touch your system Python.
For now, the packages are workflow artifacts (kept for 90 days) on the build-linux-packages runs. They are not attached to the GitHub Release yet.
# Debian/Ubuntu
sudo dpkg -i structkit_VERSION_amd64.deb
# Fedora/RHEL
sudo dnf install ./structkit-VERSION-1.x86_64.rpmSee Installation for artifact names, or packaging/README.md to build the packages yourself.
structkit as the scaffolding layer for AI assistants
We rewrote the MCP docs around one idea: the assistant picks an approved template, and structkit generates the files the same way every time. The new end-to-end walkthrough goes discover → inspect → preview → generate:
list_structuresandget_structure_infoto find a templateget_structure_varsto ask for required variables instead of guessing themgenerate_structurewithoutput: "console"anddry_run: trueto preview- The same call with
output: "files"once you approve
structkit mcp --server --transport stdioHooks are skipped by default throughout, so an assistant can't run shell commands without you opting in. Walkthrough: MCP / AI Agent Workflow.
Upgrading
# pip
pip install -U structkit
# Homebrew (tap)
brew update && brew upgrade structkit
# first install:
brew install httpdss/structkit/structkitThen check that it runs with structkit --help.
Known issue in 3.3.0: structkit imports cachetools but 3.3.0 doesn't list it as a dependency. Most pip installs get it anyway through fastmcp's dependencies. If you see ModuleNotFoundError: No module named 'cachetools', run:
pip install cachetoolsThe fix (declaring cachetools as a dependency) is merged and ships in 3.3.1, which hasn't been released yet.
Ecosystem
The companion projects now support .structkit.yaml on their main branches:
- structkit-action:
struct_fileauto-detects.structkit.yaml - structkit-pre-commit: hook file patterns match
.structkit.yaml - vscode-structkit: schema and autocomplete recognize
.structkit.yaml - structkit-skills: skill and validator updated for 3.3.0
- homebrew-structkit: formula bumped to 3.3.0
- backstage-plugin-structkit: scaffolder actions for platform teams
GitHub Actions: setup, then action
GitHub Actions support is now split into two actions. structkit-setup (v0.0.1) only installs structkit and caches it, keyed on OS, Python version and structkit version. structkit-action runs validate/generate and the drift check. Call setup first:
steps:
- uses: actions/checkout@v4
- uses: httpdss/structkit-setup@v0
- uses: httpdss/structkit-action@v0After structkit-setup, you can also run any structkit command in your own steps. As of structkit-action v0.0.2 (@v0), structkit-action no longer installs structkit itself and fails with a clear message if it isn't on the PATH. Full guide: GitHub Actions.
Smaller fixes
- Fish shell completions fixed (#187):
structkit --print-completion fish > ~/.config/fish/completions/structkit.fish - Docs fixes for the block end delimiter, the
slugifysignature, and old repo references (#189) - New Ecosystem section in the README (#194)
What's next
3.3.1 is a small packaging release: the cachetools dependency fix and package metadata updated to Apache-2.0. On the integrations side, the next steps are v1 releases of the GitHub Actions and the pre-commit hook, and publishing the StructKit extension on the VS Code Marketplace.
Links
- Release notes: v3.3.0 on GitHub
- PyPI: structkit
- Docs: structkit.app/docs
- Questions: GitHub Discussions
Read more: StructKit in CI | Pin smarter with the latest_release filter
structkit is open source (Apache-2.0). Contributions and template shares welcome.