Skip to content

Commit 48ac13c

Browse files
committed
Update contributor and import docs
Document contributor setup and workflow in CONTRIBUTING. Clarify the atomic install marker flow in architecture docs and note that import rejects source trees with symlinks.
1 parent f6d4711 commit 48ac13c

4 files changed

Lines changed: 166 additions & 3 deletions

File tree

ARCHITECTURE.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -141,8 +141,8 @@ Install behavior:
141141
- verify target support
142142
- copy the skill directory into a temp dir on the target filesystem
143143
- transform `SKILL.md` by prepending generated YAML frontmatter
144+
- write the `.loadout` marker into the staging directory
144145
- atomically rename into place
145-
- write a `.loadout` marker file containing repo commit and install timestamp
146146

147147
Remove behavior deletes the installed directory if present.
148148

@@ -320,7 +320,7 @@ User equip:
320320
2. The service loads the requested skill from the registry.
321321
3. The service verifies the skill supports the requested target.
322322
4. The service resolves the configured target root.
323-
5. `install.Install` copies the repo content, transforms `SKILL.md`, and writes a `.loadout` marker.
323+
5. `install.Install` copies the repo content, transforms `SKILL.md`, writes the `.loadout` marker into staging, and atomically renames the completed directory into place.
324324

325325
User unequip:
326326

CONTRIBUTING.md

Lines changed: 155 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,155 @@
1+
# Contributing
2+
3+
Loadout is a Go CLI/TUI for managing machine-local Claude and Codex skills from a shared git-backed repo. This guide covers the local contributor workflow and the project constraints worth preserving when you change behavior.
4+
5+
## Prerequisites
6+
7+
- Go installed locally
8+
- `golangci-lint` available for `make lint`
9+
- Git configured for normal commit and push workflows
10+
11+
## Initial Setup
12+
13+
macOS and Linux are the primary supported contributor environments.
14+
15+
Windows compatibility is not currently guaranteed and may drift. If you are developing on Windows, plan on using configurable target paths instead of assuming the default `~/.claude/skills` and `~/.codex/skills` locations fit your environment.
16+
17+
Clone the repo, then enable the repo-local Git hooks:
18+
19+
```bash
20+
git config core.hooksPath .githooks
21+
```
22+
23+
The repo includes a `commit-msg` hook in `.githooks/commit-msg` that enforces the local commit message style:
24+
25+
- subject line required
26+
- subject line starts with a capital letter
27+
- subject line is 50 characters or fewer
28+
- subject line does not end with a period
29+
- body is separated from the subject by a blank line
30+
- body lines wrap at 72 characters
31+
32+
The hook runs with `sh`, so consistent hook enforcement assumes a POSIX shell environment. On Windows, use Git Bash, WSL, or a comparable shell if you want the repo-local hooks to run as documented.
33+
34+
## Build And Run
35+
36+
Use the standard Go commands during development:
37+
38+
```bash
39+
go build ./...
40+
go test ./...
41+
go vet ./...
42+
go run ./cmd/loadout
43+
```
44+
45+
Make targets are available for the common workflows:
46+
47+
```bash
48+
make build
49+
make test
50+
make test-race
51+
make vet
52+
make lint
53+
```
54+
55+
## Development Workflow
56+
57+
1. Make the smallest coherent change you can.
58+
2. Add or update tests with the code change.
59+
3. Run focused tests while iterating.
60+
4. Run the full quality gates before committing.
61+
62+
For most changes, run these before commit:
63+
64+
```bash
65+
make test-race
66+
make vet
67+
make lint
68+
```
69+
70+
If you changed behavior that affects user workflows, architecture, or contributor setup, update the relevant docs in the same change.
71+
72+
## Project Structure
73+
74+
Key directories:
75+
76+
```text
77+
cmd/loadout/ CLI entry point and Cobra commands
78+
internal/app/ Service-layer orchestration
79+
internal/config/ Local config persistence
80+
internal/domain/ Core types, validation, sentinel errors
81+
internal/gitrepo/ Git operations
82+
internal/importer/ Import and candidate discovery
83+
internal/install/ Install/remove logic for target roots
84+
internal/reconcile/ Inventory/status computation
85+
internal/scope/ User vs project scope resolution
86+
internal/skillmd/ SKILL.md parsing/frontmatter helpers
87+
internal/tui/ Bubble Tea presentation layer
88+
testdata/ Fixture trees for tests
89+
```
90+
91+
## Architectural Guardrails
92+
93+
These are the important invariants to preserve:
94+
95+
- The repo stores skill content only, not machine state.
96+
- Install means copy into target roots, not symlink.
97+
- Managed installs are identified by a `.loadout` marker.
98+
- Installed copies are disposable derived artifacts.
99+
- The TUI contains presentation logic only and delegates business actions to `internal/app`.
100+
- `internal/domain` stays dependency-free.
101+
102+
Dependency direction:
103+
104+
```text
105+
cmd -> app, tui
106+
tui -> app, domain
107+
app -> domain, config, registry, gitrepo, install, importer, reconcile, scope
108+
domain -> nothing
109+
```
110+
111+
## Code Style
112+
113+
- Prefer concrete types; introduce interfaces only at the point of use.
114+
- Export only what other packages need.
115+
- Keep package names short and non-stuttering.
116+
- Group imports as stdlib, third-party, then local imports.
117+
- Do not add logging infrastructure; return errors to the caller.
118+
119+
## Error Handling
120+
121+
- Use sentinel errors from `internal/domain/errors.go`.
122+
- Wrap errors with `%w`.
123+
- Check behavior with `errors.Is()`, not string matching.
124+
- Keep error strings lowercase with no trailing punctuation.
125+
126+
## Testing Expectations
127+
128+
- Prefer table-driven tests.
129+
- Name tests as `TestFunc_Scenario`.
130+
- Use `t.TempDir()` for filesystem behavior.
131+
- Use real filesystem state instead of mocks for install/import behavior.
132+
- Mark helpers with `t.Helper()`.
133+
- Use `t.Fatalf` when continuing would make the test meaningless.
134+
135+
Recent regressions have come from install and import edge cases, so changes in those areas should usually include direct regression coverage.
136+
137+
## Commit Messages
138+
139+
Keep commits small and descriptive. The local hook enforces the mechanical parts of the project style, but a good message should still explain the behavior change clearly when the subject alone is not enough.
140+
141+
## Pull Requests
142+
143+
When opening a PR:
144+
145+
- describe the user-visible or architectural change
146+
- call out any risks or edge cases
147+
- mention the tests you ran
148+
- note doc updates when behavior or contributor workflow changed
149+
150+
## Related Docs
151+
152+
- [README.md](README.md) for product usage and CLI/TUI behavior
153+
- [docs/guides.md](docs/guides.md) for workflow-oriented user guides
154+
- [ARCHITECTURE.md](ARCHITECTURE.md) for design details and runtime flows
155+
- [AGENTS.md](AGENTS.md) for codebase-specific implementation rules used by coding agents

README.md

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,12 @@ brew install sethdeckard/tap/loadout
2222
go install github.com/sethdeckard/loadout/cmd/loadout@latest
2323
```
2424

25+
## Platform Support
26+
27+
Loadout is primarily supported on macOS and Linux.
28+
29+
Windows compatibility is not currently guaranteed and may drift. If the default config path or default Claude/Codex target paths do not match your environment, configure custom paths during `loadout init` or by editing the config file directly.
30+
2531
## Quick Start
2632

2733
Looking for workflow-oriented docs instead of reference material? See [docs/guides.md](docs/guides.md) for practical guides on importing existing skills, using `loadout-smith`, and choosing the right creation path.
@@ -119,6 +125,7 @@ In project scope, ready project-local skills may already be visible in the main
119125
- If the source only has `SKILL.md`, Loadout generates `skill.json` from frontmatter, markdown headings, and the source target root when possible.
120126
- Imported skills are written to `skills/<name>/`, where `name` is the canonical identifier from `skill.json` or the inferred slug when `skill.json` is missing.
121127
- Import strips install-time frontmatter from `SKILL.md` and removes any `.loadout` marker from the copied repo version.
128+
- Import rejects source trees that contain symlinks.
122129
- `--commit` creates a commit for the imported skill only.
123130

124131
If the same skill appears in both Claude and Codex roots with conflicting metadata, Loadout blocks the import instead of guessing.
@@ -230,4 +237,4 @@ make vet # Static analysis
230237
make lint # Run golangci-lint
231238
```
232239

233-
See [ARCHITECTURE.md](ARCHITECTURE.md) for design details and [AGENTS.md](AGENTS.md) for coding conventions.
240+
See [CONTRIBUTING.md](CONTRIBUTING.md) for contributor setup, [ARCHITECTURE.md](ARCHITECTURE.md) for design details, and [AGENTS.md](AGENTS.md) for coding conventions.

docs/guides.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ Use this when you already have skills living outside your Loadout-managed repo a
1111
- Copies an existing local skill directory into your repo under `skills/<name>/`
1212
- Preserves declared metadata from `skill.json` when present
1313
- Infers metadata from `SKILL.md` and the source root when `skill.json` is missing
14+
- Rejects source trees that contain symlinks
1415
- Refuses imports when the same skill appears with conflicting metadata across Claude and Codex roots
1516

1617
After import, the repo copy becomes the source of truth. Edit the skill there, not in the installed copy.

0 commit comments

Comments
 (0)