justfile
Create, edit, refactor, lint, and maintain Justfiles and `.just` module files using the `just` command runner. ALWAYS use this skill when the user mentions justfile, Justfile, just recipes, just modules, `.just` files, or asks to set up task automation with just. Also trigger when migrating a Makefile to just, adding recipes or modules to an existing Justfile, or organizing and documenting project commands. Covers house conventions, templates, namespacing by domain, dotenv, cross-platform support, and a structural lint. NOT FOR file-based build dependency graphs that need timestamp tracking (use make).
What this skill does
# Justfile Skill
`just` is a command runner (not a build system) that saves and runs project-specific commands in a
file called `Justfile`. It uses make-inspired syntax but is simpler and more portable, with none of
make's idiosyncrasies (`.PHONY`, tab sensitivity, implicit rules, timestamp tracking).
This skill enforces a consistent **house style** so every Justfile looks the same across projects.
The rules below are the authoritative convention; `Tools/lint.ts` validates the deterministic ones.
## Workflow Routing
| Trigger | Workflow |
|---------|----------|
| "create a justfile", "set up just", "add a recipe/module" | `Workflows/CreateJustfile.md` |
| "migrate Makefile to just", "convert make to just" | `Workflows/MigrateFromMake.md` |
| "check/lint this justfile", "is this justfile correct" | `Workflows/CheckJustfile.md` |
## When to Use Just vs Make
| Scenario | Tool |
|----------|------|
| Project task automation (build, test, deploy, lint) | **just** |
| Cross-platform command runner | **just** |
| Actual file-based build dependencies (compile `.c` → `.o`) | **make** |
| Legacy projects already deep in make | **make** (or migrate) |
## Common Mistakes — do NOT do these
Patterns the model often generates incorrectly. Check output against this list.
| WRONG | RIGHT |
|-------|-------|
| `justfile` (lowercase) | `Justfile` (capital J) |
| `mod docker` (bare) | `mod docker '.justfiles/docker.just'` |
| Module at `docker.just` or `just/docker.just` | Module at `.justfiles/docker.just` |
| `default:` | `_default:` (underscore required) |
| `@just --list` | `@just --list --unsorted` (module) or `--unsorted --list-submodules` (root with modules) |
| `env("NAME", "val")` | `env_var_or_default("NAME", "val")` |
| Module file without the three-line header | Every file gets the full header |
| Module file without its own `_default` recipe | Every file gets its own `_default` |
| Module named after a tool (`psql.just`) | Module named after a concern (`db.just`) |
| Tests in `docker.just` because they run in a container | Tests in `test.just` — classify by purpose, not implementation |
| Root recipe duplicates module logic | Root shortcut delegates: `build: docker-build` |
| Ad-hoc names (`run-tests`, `do-lint`) | Standard names: `test`, `lint`, `build`, `dev`, `fmt`, `check` |
| Relative paths in module recipes (`bash tests/run.sh`) | Use `source_directory()` for absolute paths |
## Mandatory Rules — apply to EVERY file you create or edit
1. The root file MUST be named `Justfile` (capital J).
2. EVERY file (root and every `.just` module) MUST start with this three-line header:
```just
#!/usr/bin/env just --justfile
set shell := ["bash", "-euo", "pipefail", "-c"]
set dotenv-load := true
```
Use `set dotenv-load := false` where appropriate, but the line must always be present.
3. EVERY file MUST have `_default` as its first recipe:
```just
# List all available recipes
_default:
@just --list --unsorted
```
The **root** Justfile with modules uses `@just --list --unsorted --list-submodules`. Module
files use `@just --list --unsorted` (no `--list-submodules`).
4. Section order in every file: **variables → mod imports → recipes**.
5. Module files MUST live at `.justfiles/<name>.just` — never `just/`, never beside the root.
6. Import modules with explicit paths: `mod name '.justfiles/name.just'` — never bare `mod name`.
7. Use `env_var_or_default("NAME", "value")` for variable defaults — never `env()`.
8. Every recipe gets a `#` doc comment on the line directly above it.
9. Parameterized recipes document each param: `# param - description (default: value)`.
10. Private/helper recipes start with `_`.
11. Dependencies go on the definition line: `build: _lint test`.
12. Destructive recipes prompt for confirmation; the doc comment says "DESTRUCTIVE, prompts for confirmation".
13. Extract modules by **domain concern**, named after the concern (`db.just`) not the tool (`psql.just`). The root Justfile is a thin orchestrator: `_default`, shortcut recipes, and project-wide recipes like `check`/`clean`.
14. The root provides shortcut recipes for common workflows that delegate to modules, giving developers a flat namespace for everyday tasks.
15. Use the standard recipe vocabulary below as the public API. Never invent `run-tests`, `do-lint`, `compile`, `format`.
16. In modules, never use bare relative paths — module recipes run with the module's directory as CWD. Define `root := source_directory() / ".."` and reference files as `{{root}}/tests/run.sh`.
## Standard Recipe Vocabulary
A developer should be able to run `just test`, `just dev`, or `just check` in any project without guessing. Use these exact names; include only the ones that apply.
| Recipe | Purpose | Include when |
|--------|---------|--------------|
| `dev` | Start dev environment (server, watch, REPL) | Project has a dev loop |
| `test` | Run the test suite | Always |
| `build` | Build or compile | Project has a build step |
| `lint` | Run linters | Linters configured |
| `fmt` | Format code | Formatters configured |
| `check` | Run ALL quality gates (`check: lint test`) | Always |
| `clean` | Remove build artifacts, caches, generated files | Project produces output |
`check` is the meta-recipe — depend on the applicable gates and add format checks (`cargo fmt --check`, `ruff format --check`) as appropriate.
## Namespacing by Concern
Group by **domain**, not tool. Classify by purpose: a test that runs in Docker is a *testing* recipe (`test.just`), not a Docker recipe. A migration that uses kubectl is a *database* recipe (`db.just`).
| Concern | Module | Typical recipes |
|---------|--------|-----------------|
| Development | `dev.just` | build, test, lint, fmt, bench |
| Testing | `test.just` | run, list, watch, coverage |
| Containers | `docker.just` | build, push, run, compose-up |
| CI/CD | `ci.just` | lint, deploy, release |
| Database | `db.just` | migrate, seed, reset, dump, restore |
| Infrastructure | `infra.just` | plan, apply, destroy |
| Kubernetes | `k8s.just` | apply, diff, rollback, logs |
| Documentation | `docs.just` | build, serve, publish |
Single-concern projects (e.g. a Go/Rust project with only build/test/lint/fmt) use one `dev.just`; the root still stays thin. Modules are self-contained: own variables, own `_default`, no cross-module recipe dependencies.
## Templates & References
- **Templates** (root + module, copy-and-adapt): `Templates.md`
- **just language reference** (variables, args, deps, conditionals, attributes, functions, install): `References/Syntax.md`
- **Recipe fragments by project type** (Terraform, Go, Python, Docker, Azure, Ansible): `References/Patterns.md`
- **Makefile → just migration guide**: `References/MakeMigration.md`
## Linting
After creating or editing ANY Justfile or `.just` module, run the structural lint and fix every failure:
```bash
bun Tools/lint.ts <project-dir>
```
It checks file naming, the three-line header, `_default` as first recipe, the `--unsorted`/`--list-submodules` flags, `env_var_or_default()` usage, doc comments on all recipes, explicit module import paths, and section order. Any `FAIL` is a bug — fix and re-run until clean. The lint cannot judge concern-based naming, self-containment, or standard-vocabulary use — verify those by inspection (see `Workflows/CheckJustfile.md`).
## Gotchas
- **Each recipe line runs in a separate shell by default** — `cd foo` on one line and `ls` on the next runs `ls` in the original directory. Use a shebang recipe for multi-line scripts.
- **`set dotenv-load` loads `.env` from the justfile directory, not the invocation directory** — running `just` from a subdirectory loads the parent's `.env`. Use `set dotenv-path` to override.
- **Backtick variables evaluate at parse time, every invocation** — `git_hash := \`git rev-parse HEAD\`` runs git on every `just` call, even for unrelated recipes. Slow on large repos; move inside the recipe if not Related in Productivity
gitea-workflow
IncludedOrchestrate agile development workflows for Gitea repositories using the tea CLI. Use when working with Gitea-hosted repos and asking to 'run the workflow', 'continue working', 'what's next', 'complete the task cycle', 'start my day', 'end the sprint', 'implement the next task', or wanting guided step-by-step development assistance. Keywords: workflow, orchestrate, agile, task cycle, sprint, daily, implement, review, PR, standup, retrospective, gitea, tea.
microsoft-graph-gateway
IncludedRoute Microsoft Graph work in this workspace. Use when users want to read or write Outlook mail, calendar events, contacts, OneDrive or SharePoint files, Teams, Planner, To Do, users, groups, directory data, or arbitrary Microsoft Graph endpoints from VS Code. Prefer WorkIQ for common read scenarios. Use Microsoft Graph for write actions and gap-read scenarios that need exact Graph properties, filters, permissions, or endpoints.
copilotkit
IncludedUse when building with CopilotKit — setup, development, integrations, debugging, upgrading, or contributing. Routes to the appropriate specialized skill based on the task.
wordly-wisdom
IncludedProvides calibrated decision analysis using Charlie Munger-style multiple mental models, inversion, incentive mapping, circle-of-competence checks, misjudgment audits, second-order effects, and forecast updates. Use when the user asks for an oracle take, a hard call, a decision memo, a premortem, an outside view, a red-team, a sanity-check, what am I missing, think this through, or wants a strategy, hire, investment, plan, product, partnership, or major life choice analysed. Avoid for simple factual lookups or time-sensitive legal, medical, or market questions without fresh evidence.
swain-session
IncludedSession management and project status dashboard. Owns the full session lifecycle (start/work/close/resume), focus lane, bookmarks, worktree detection, and tab naming. Also serves as the project status dashboard — shows active epics, progress, actionable next steps, blocked items, tasks, GitHub issues, and recommendations. Worktree creation is deferred to swain-do task dispatch (SPEC-195). Triggers on: 'session', 'status', 'what's next', 'dashboard', 'overview', 'where are we', 'what should I work on', 'show me priorities', 'bookmark', 'focus on', 'session info'.
gandi
IncludedComprehensive Gandi domain registrar integration for domain and DNS management. Register and manage domains, create/update/delete DNS records (A, AAAA, CNAME, MX, TXT, SRV, and more), configure email forwarding and aliases, check SSL certificate status, create DNS snapshots for safe rollback, bulk update zone files, and monitor domain expiration. Supports multi-domain management, zone file import/export, and automated DNS backups. Includes both read-only and destructive operations with safety controls.