Skip to content

Commit ef6f6e3

Browse files
heyfirstclaude
andcommitted
Add README, MIT license and CI
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
1 parent 7df5c82 commit ef6f6e3

4 files changed

Lines changed: 139 additions & 1 deletion

File tree

‎.github/workflows/check.yml‎

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
name: check
2+
3+
on:
4+
push:
5+
branches: [main]
6+
pull_request:
7+
8+
jobs:
9+
check:
10+
runs-on: ubuntu-latest
11+
steps:
12+
- uses: actions/checkout@v4
13+
- uses: oven-sh/setup-bun@v2
14+
- run: bun install --frozen-lockfile
15+
- run: bun run check

‎LICENSE‎

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2026 Kanisorn Sutham
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

‎README.md‎

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
# herdr-worktree-include
2+
3+
A [herdr](https://herdr.dev) plugin that copies your gitignored local files --
4+
`.env`, local config, secrets -- into every new herdr worktree, using the same
5+
`.worktreeinclude` file [Claude Code](https://code.claude.com/docs/en/worktrees)
6+
reads.
7+
8+
Git worktrees check out tracked files only, so a new worktree starts without
9+
the files that make the project run. One `.worktreeinclude` now covers both
10+
herdr and Claude Code worktrees.
11+
12+
## Install
13+
14+
Requires herdr 0.9.0 or later and [Bun](https://bun.sh) on `PATH`.
15+
16+
```bash
17+
herdr plugin install heyfirst/herdr-worktree-include
18+
```
19+
20+
No build step and no runtime dependencies: herdr runs `bun src/main.ts`
21+
directly.
22+
23+
## Use
24+
25+
Add a `.worktreeinclude` to the root of the repo, in `.gitignore` syntax:
26+
27+
```gitignore
28+
.env
29+
.env.*
30+
!.env.example
31+
config/local/
32+
```
33+
34+
A file is copied into a new worktree only if it:
35+
36+
- matches `.worktreeinclude`, **and**
37+
- is ignored by git in the main checkout.
38+
39+
Tracked files are never copied -- the worktree already has them. This is the
40+
same rule Claude Code applies, and git decides both halves, so negation,
41+
directory patterns and nested `.gitignore` files behave exactly as git says.
42+
43+
It runs on herdr's `worktree.created` event. To run it by hand on the focused
44+
workspace, use the **Apply worktree include** action, or:
45+
46+
```bash
47+
bun src/main.ts apply /path/to/worktree
48+
```
49+
50+
## Safety
51+
52+
- Never overwrites a file that already exists in the worktree.
53+
- Never copies tracked files.
54+
- Rejects absolute paths and paths containing `..`.
55+
- Skips files inside other linked worktrees nested in the main checkout.
56+
- Symlinks are recreated as symlinks, never followed.
57+
- Always exits 0, so it can never break worktree creation.
58+
- No `.worktreeinclude` means it does nothing.
59+
60+
## Logs
61+
62+
Every run prints one JSON outcome, readable with:
63+
64+
```bash
65+
herdr plugin log list --plugin heyfirst.worktree-include --limit 5
66+
```
67+
68+
| `tag` | Means |
69+
|---|---|
70+
| `applied` | Ran. `files` lists each path as `copied`, `skipped` (with a reason) or `failed` |
71+
| `no-manifest` | The main checkout has no `.worktreeinclude` |
72+
| `is-main` | The target is the main checkout itself |
73+
| `no-source` | Could not find the main checkout |
74+
| `no-target` | Could not find the new worktree in the event |
75+
76+
## Develop
77+
78+
```bash
79+
bun install
80+
bun run check # tsc, oxlint (type-aware), bun test
81+
herdr plugin link . # run your checkout instead of the installed copy
82+
```
83+
84+
Tests build real git repositories in a temp directory. Lint bans `any`,
85+
`unknown` and unsafe access.
86+
87+
## Prior art
88+
89+
- [eightHundreds/herdr-worktreeinclude](https://github.com/eightHundreds/herdr-worktreeinclude)
90+
-- the same idea in Rust, shipped as a prebuilt binary. Its safety rules
91+
shaped the list above.
92+
- [crexi/herdr-worktree-copy](https://github.com/crexi/herdr-worktree-copy)
93+
-- a shell plugin with its own manifest format.
94+
95+
## License
96+
97+
[MIT](LICENSE)

‎package.json‎

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
{
2-
"name": "worktree-include",
2+
"name": "herdr-worktree-include",
33
"private": true,
44
"type": "module",
55
"scripts": {
@@ -13,5 +13,10 @@
1313
"oxlint": "^1.85.0",
1414
"oxlint-tsgolint": "^7.0.2002",
1515
"typescript": "^7.0.2"
16+
},
17+
"license": "MIT",
18+
"repository": {
19+
"type": "git",
20+
"url": "git+https://github.com/heyfirst/herdr-worktree-include.git"
1621
}
1722
}

0 commit comments

Comments
 (0)