-
-
Notifications
You must be signed in to change notification settings - Fork 3
Commands
Run Tailor from your project directory. Use baste to preview changes before alter.
Tailor selects a GitHub fetch remote in this order: origin, github, upstream, then another remote. A default set through gh repo set-default overrides this order.
This selection applies to fit, alter, baste, and docket. fit checks its target directory. The other commands check the current directory.
In a fork clone, origin usually selects your fork. Check the repository with tailor docket before tailor baste and tailor alter.
Creates a project directory and writes .tailor.yml with the full default swatch set. It does not copy files or apply settings. fit . also works in an existing directory.
The default licence is BlueOak-1.0.0.
tailor fit ./my-project
tailor fit ./my-project --license=Apache-2.0
tailor fit ./my-project --license=none
tailor fit ./my-project --description="Short description"fit uses the embedded swatches/.tailor.yml defaults for all managed settings, including for existing projects. It copies only repository description and homepage from GitHub, exactly, including empty strings. An explicit --description takes precedence. Without a GitHub remote, the description defaults to the project directory name and the homepage stays omitted.
Review .tailor.yml and run tailor baste before tailor alter. The defaults can disable an existing wiki, Code Quality and immutable releases, and replace the Tailor ruleset. Topics stay unmanaged because the embedded defaults omit them.
fit exits with an error if .tailor.yml already exists. Existing configs retain their declared values, including values copied from GitHub by an earlier fit. Default merging stays append-only, including with --recut.
Reads .tailor.yml in the current directory. It applies repository settings, immutable releases, Actions policy, code scanning, Code Quality, the ruleset, labels, variables, Pages, wiki files, and the licence. The swatch stage then publishes Dependabot, managed development files, and ordinary swatches. Pages files follow.
Wiki setup has one earlier write: after local safety checks, Tailor enables a declared wiki before its readiness check. If readiness fails, no other changes follow. See GitHub wiki for setup steps.
tailor alter # Apply changes
tailor alter --recut # Overwrite eligible always and first-fit swatches--recut overrides first-fit for ordinary swatches, but it still skips never. Existing justfile, flake.nix, and .gitignore roots, wiki starter pages, static Pages starter files, and regular LICENSE files are exempt. Ordinary .gitignore processing preserves an existing regular file or final symlink byte-for-byte under every mode. It does not read or hash the file, or follow the symlink.
For an active mode other than never, Tailor creates a missing .gitignore atomically without clobbering a destination that appears during the write. It rejects a directory or special file before repository checks, authentication, or writes. never skips that inspection and write. Enabled Hugo or Jekyll Pages is a later additive exception that can replace a final symlink and append its output rule. Review the rule order when an existing matching rule precedes a later negation. For .tailor.yml, see default merging.
Dependabot uses whole-file ownership. The exact first-line marker is # Managed by Tailor: .github/dependabot.yml. Back up a custom file before adding it because the next reconciliation can remove every custom field.
first-fit and always reconcile owned content, with or without --recut. They preserve an unmarked regular file byte-for-byte. An omitted entry or never skips both .yml and .yaml names without inspection.
Active Dependabot preflight runs before repository context, authentication, wiki enablement, or other writes. It rejects alternate .yaml entries, unsafe paths, unreadable input, and input or output above 1 MiB. Publication waits until the swatch stage after the licence stage.
Before publication, Tailor rechecks both names, the parent identity, the destination identity and type, the marker, and exact bytes. Creation never replaces a destination that appears after preflight. Replacement uses file sync, close, atomic rename, and directory sync.
When Pages or wiki creates a missing .github parent in the same run, Dependabot accepts only the captured private directory identity. Linux and macOS support protected no-replace parent publication. On other platforms, a missing parent returns errors.ErrUnsupported; runtime acceptance is not claimed there.
The final check-to-rename race remains, and the complete alter run is not a transaction. If publication succeeds before a later sync, cleanup, close, or stage error, Tailor reports the confirmed change and returns the error.
The following workflow is for a future release. Tailor will first build one rooted .gitignore snapshot and plan before local or remote mutation. One writer will handle ordinary, Go, and Pages rules. baste will show marker snippets for an unadopted existing root, without changing it.
Before publication, Tailor will recheck the file identity, type, and bytes. If they changed, Tailor will report a conflict instead of making a new plan. Run tailor baste again, review the new plan, then retry tailor alter.
Publication will use an exclusive sibling temporary file, file sync, close, rename, and directory sync. Missing-root publication will not replace a destination that appears. These checks are not an atomic filesystem compare-and-swap because another writer can change the destination between the final check and rename. If that race occurs, recover the project-owned file from Git or backup before retrying with one writer.
Future .gitignore atomicity will cover one file only. It will not cover remote operations or the complete alter run. Final symlinks, linked parents, directories, special files, unreadable files, and files above 1 MiB will stop future reconciliation. See the future contract.
If a later step fails, completed local and repository changes remain. Tailor does not roll them back. Fix the reported error, then run tailor baste before you retry tailor alter.
alter and alter --recut report a completed label after each successful change. Labels are set, created, updated, removed, copied, and overwritten.
A default merge, retired-entry cleanup, or security prerequisite normalisation in .tailor.yml reports updated. Security normalisation also shows a warning. A retired workflow file cleanup reports removed.
baste previews the changes that alter will make. It makes no changes.
For Dependabot, baste distinguishes creation, complete-file replacement, unchanged owned content, preserved unmarked content, skipped management, and conflicts. It creates no file, directory, temporary file, or ownership record.
tailor bastebaste uses planned labels. The write commands use the corresponding completed labels:
baste |
alter and alter --recut
|
|---|---|
would set |
set |
would create |
created |
would update |
updated |
would remove |
removed |
would copy |
copied |
would overwrite |
overwritten |
skipped and no change use the same labels in all three commands. A skipped file shows its reason after the path.
A default merge, retired-entry cleanup, or security prerequisite normalisation in .tailor.yml reports would update in baste. Security normalisation also shows a warning. After a successful write, alter reports updated.
Each present retired workflow file reports would remove in baste and removed after deletion.
would set: repository.has_wiki = false
would update: .tailor.yml
would remove: .github/workflows/tailor-automerge.yml
would remove: .github/workflows/tailor.yml
would copy: LICENSE
would overwrite: SECURITY.md
no change: CODE_OF_CONDUCT.md
skipped: .envrc (first-fit, exists)
skipped: .github/pull_request_template.md (mode never)
Displays the current GitHub authentication state and repository context.
When authenticated, docket verifies the token with GET /user. Pages adds no requests to this command.
tailor docketChecks community health files and configuration alignment. No network access, no authentication, no .tailor.yml required.
The Pages workflow is not a community health file. Its registered path remains part of the configuration comparison, even when Pages is disabled.
tailor measure missing: .github/FUNDING.yml
warning: LICENSE (contains unresolved placeholders)
warning: README.md (not managed by tailor)
present: CODE_OF_CONDUCT.md
not-configured: .github/dependabot.yml
mode-differs: SECURITY.md (config: first-fit, default: always)
| Status | Meaning |
|---|---|
missing |
Health file does not exist on disk |
warning |
Missing README.md, known unresolved licence placeholders, or an uninspected licence |
present |
Health file exists on disk |
not-configured |
Default swatch not in .tailor.yml
|
config-only |
Swatch in .tailor.yml not in the built-in default set |
mode-differs |
Alteration mode differs from the default |
The not-configured, config-only, and mode-differs statuses appear only when .tailor.yml is present.
measure checks which community health files are present, missing, or need attention. It warns when README.md is absent or when LICENSE contains a known unresolved placeholder. The licence check recognises year, yyyy, fullname, name of copyright owner, name of copyright holder, software name, project, projecturl, and email inside square or curly braces. Matching ignores case, allows ASCII whitespace beside the delimiters, and treats each internal sequence of ASCII whitespace as one space.
Other bracketed licence text and complete Markdown inline links do not cause a warning.
| Licence warning | Action |
|---|---|
(contains unresolved placeholders) |
Fill in the licence placeholders manually. |
(not inspected: exceeds 1 MiB) |
Inspect the licence manually. Tailor does not scan files above this limit. |
(not inspected: read failed) |
Check that LICENSE is a readable regular file, fix read access, then rerun tailor measure. |
The generated files require Just 1.23.0 or later. The protected root imports managed fragments and owns the sole default recipe.
| Command | Runs | Requirements |
|---|---|---|
just |
Lists recipes | Just 1.23.0 or later |
just alter |
tailor alter |
Tailor, GitHub authentication, valid .tailor.yml
|
just lint-actions |
actionlint |
actionlint |
just lint |
lint-actions, then each registered linter whose capability is explicitly true |
Every selected linter tool |
just measure |
tailor baste, then tailor measure
|
Tailor, GitHub authentication, valid .tailor.yml
|
just release x.y.z |
Validates a clean tree, then creates the local vX.Y.Z tag |
Git |
Tailor records the just lint dependencies during the last successful file reconciliation. It always selects lint-actions, then each registered linter whose capability is explicitly true, in lexical capability order. The current registry adds only lint-go for Go; Pages and Playwright register no linter. False and absent capabilities are excluded. A retained fragment for an absent capability remains callable as a standalone recipe. Missing tools fail, and Just stops at the first failed dependency.
With Go support enabled, Tailor adds these recipes:
| Command | Runs | Requirements |
|---|---|---|
just build |
go build ./... |
Go |
just test |
go test ./... |
Go |
just lint-go |
golangci-lint run |
golangci-lint |
With Pages enabled, just pages previews the effective site at http://127.0.0.1:18473.
Tailor's repository adds these user-owned recipes in just/project.just:
| Command | Runs | Purpose |
|---|---|---|
just build-tailor |
go build -ldflags "-s -w" -o tailor ./cmd/tailor |
Builds the stripped Tailor binary. |
just lint-all |
just lint |
Compatibility alias for the aggregate linter recipe. |
just alter-source |
go run ./cmd/tailor alter |
Runs an alteration from the current source. |
just measure-source |
go run ./cmd/tailor baste, then go run ./cmd/tailor measure
|
Runs preview and local checks from the current source. |
just snapshot |
goreleaser release --snapshot --clean --skip=sign |
Builds local release packages. |
just check |
goreleaser check, then nix flake check
|
Checks release and flake configuration. |
After you set mcp.playwright: true, preview and apply the five managed files:
tailor baste
tailor alter
git status --shortReview each new Nix and client file, then stage the approved paths with git add. Nix flakes ignore untracked files. Tailor does not stage files.
When Tailor preserves flake.nix, add the Nix loader expression to its package list. Do the same for the Just loader only when you need other managed recipes. Playwright has no Just fragment or recipe.
Enter the project shell with nix develop, or reload direnv after direnv allow. Start a new client instance from that environment, or use the client's configuration reload command. Then approve Playwright MCP tool calls through the client's normal approval prompt.
The configured MCP server starts its own headless, isolated browser. Do not start a manual stdio server or CDP endpoint. Start just pages only when you also want the separate Pages preview server.
A validated future contract defines the proposed --adopt-mcp and --release-mcp flags. Tailor does not implement these flags and does not infer consent. Future adoption will use a local ownership ledger bound to the project. Entry edits will preserve non-target client bytes, and release will preserve all client file bytes. Release is blocked while a transaction is pending. Reviewed recovery comes first. Client-version acceptance and adoption implementation remain separate follow-on work.
Unlike tailor measure, just measure needs authentication because its first command is tailor baste. If that preview fails, the recipe stops before the local health check.
Tailor preserves an existing root and gives loader adoption guidance, including for never, --recut, or an omitted swatch entry. Before you add the exact Just loader import from managed development files, remove or rename each user recipe that duplicates a managed recipe. Keep custom checks under distinct wrapper names. Tailor does not rewrite user recipes or change production recipe names.
A partial tailor alter can leave the imported Just files temporarily invalid. Fix the reported error, then retry tailor alter before you run a recipe. The generated dispatch is consistent, but installed tool versions and configuration can produce different diagnostics. This lint aggregation change adds no tool pin or CI policy change.
Run tailor baste to preview the upgrade.
Run tailor alter to apply it. Tailor cleans up both retired workflows automatically:
.github/workflows/tailor-automerge.yml.github/workflows/tailor.yml
baste changes no files. It reports would update when .tailor.yml contains retired entries and would remove for each retired workflow file on disk.
alter and alter --recut write .tailor.yml once as updated when the config contains retired entries. They then delete each present workflow file as removed.
Tailor accepts the historical triggered mode only for retired entries during this migration. Any other unrecognised swatch path stops validation before Tailor changes any files.
Edit this documentation in the source repository's wiki/ directory, not in the published wiki.