git-worktree-organize 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (57) hide show
  1. package/.bare/HEAD +1 -0
  2. package/.bare/config +6 -0
  3. package/.bare/description +1 -0
  4. package/.bare/hooks/applypatch-msg.sample +15 -0
  5. package/.bare/hooks/commit-msg.sample +24 -0
  6. package/.bare/hooks/fsmonitor-watchman.sample +174 -0
  7. package/.bare/hooks/post-update.sample +8 -0
  8. package/.bare/hooks/pre-applypatch.sample +14 -0
  9. package/.bare/hooks/pre-commit.sample +49 -0
  10. package/.bare/hooks/pre-merge-commit.sample +13 -0
  11. package/.bare/hooks/pre-push.sample +53 -0
  12. package/.bare/hooks/pre-rebase.sample +169 -0
  13. package/.bare/hooks/pre-receive.sample +24 -0
  14. package/.bare/hooks/prepare-commit-msg.sample +42 -0
  15. package/.bare/hooks/push-to-checkout.sample +78 -0
  16. package/.bare/hooks/sendemail-validate.sample +77 -0
  17. package/.bare/hooks/update.sample +128 -0
  18. package/.bare/info/exclude +6 -0
  19. package/.bare/objects/pack/pack-1a869640f0628b133e36287958cd040e132be773.idx +0 -0
  20. package/.bare/objects/pack/pack-1a869640f0628b133e36287958cd040e132be773.pack +0 -0
  21. package/.bare/objects/pack/pack-1a869640f0628b133e36287958cd040e132be773.rev +0 -0
  22. package/.bare/packed-refs +2 -0
  23. package/.beads/README.md +81 -0
  24. package/.beads/backup/backup_state.json +13 -0
  25. package/.beads/backup/comments.jsonl +0 -0
  26. package/.beads/backup/config.jsonl +11 -0
  27. package/.beads/backup/dependencies.jsonl +10 -0
  28. package/.beads/backup/events.jsonl +31 -0
  29. package/.beads/backup/issues.jsonl +9 -0
  30. package/.beads/backup/labels.jsonl +0 -0
  31. package/.beads/config.yaml +55 -0
  32. package/.beads/hooks/post-checkout +9 -0
  33. package/.beads/hooks/post-merge +9 -0
  34. package/.beads/hooks/pre-commit +9 -0
  35. package/.beads/hooks/pre-push +9 -0
  36. package/.beads/hooks/prepare-commit-msg +9 -0
  37. package/.beads/interactions.jsonl +0 -0
  38. package/.beads/metadata.json +9 -0
  39. package/.claude/settings.local.json +8 -0
  40. package/AGENTS.md +150 -0
  41. package/README.md +84 -0
  42. package/bun.lock +205 -0
  43. package/package.json +21 -0
  44. package/src/cli.ts +143 -0
  45. package/src/detect.ts +95 -0
  46. package/src/fs.ts +22 -0
  47. package/src/git.ts +40 -0
  48. package/src/migrate.ts +162 -0
  49. package/src/worktrees.ts +54 -0
  50. package/test/__bun-shim__.ts +78 -0
  51. package/test/detect.test.ts +99 -0
  52. package/test/helpers/repo.ts +75 -0
  53. package/test/migrate.test.ts +124 -0
  54. package/test/security.test.ts +25 -0
  55. package/test/worktrees.test.ts +164 -0
  56. package/tsconfig.json +13 -0
  57. package/vitest.config.ts +13 -0
package/AGENTS.md ADDED
@@ -0,0 +1,150 @@
1
+ # Agent Instructions
2
+
3
+ This project uses **bd** (beads) for issue tracking. Run `bd onboard` to get started.
4
+
5
+ ## Quick Reference
6
+
7
+ ```bash
8
+ bd ready # Find available work
9
+ bd show <id> # View issue details
10
+ bd update <id> --claim # Claim work atomically
11
+ bd close <id> # Complete work
12
+ bd sync # Sync with git
13
+ ```
14
+
15
+ ## Non-Interactive Shell Commands
16
+
17
+ **ALWAYS use non-interactive flags** with file operations to avoid hanging on confirmation prompts.
18
+
19
+ Shell commands like `cp`, `mv`, and `rm` may be aliased to include `-i` (interactive) mode on some systems, causing the agent to hang indefinitely waiting for y/n input.
20
+
21
+ **Use these forms instead:**
22
+ ```bash
23
+ # Force overwrite without prompting
24
+ cp -f source dest # NOT: cp source dest
25
+ mv -f source dest # NOT: mv source dest
26
+ rm -f file # NOT: rm file
27
+
28
+ # For recursive operations
29
+ rm -rf directory # NOT: rm -r directory
30
+ cp -rf source dest # NOT: cp -r source dest
31
+ ```
32
+
33
+ **Other commands that may prompt:**
34
+ - `scp` - use `-o BatchMode=yes` for non-interactive
35
+ - `ssh` - use `-o BatchMode=yes` to fail instead of prompting
36
+ - `apt-get` - use `-y` flag
37
+ - `brew` - use `HOMEBREW_NO_AUTO_UPDATE=1` env var
38
+
39
+ <!-- BEGIN BEADS INTEGRATION -->
40
+ ## Issue Tracking with bd (beads)
41
+
42
+ **IMPORTANT**: This project uses **bd (beads)** for ALL issue tracking. Do NOT use markdown TODOs, task lists, or other tracking methods.
43
+
44
+ ### Why bd?
45
+
46
+ - Dependency-aware: Track blockers and relationships between issues
47
+ - Git-friendly: Auto-syncs to JSONL for version control
48
+ - Agent-optimized: JSON output, ready work detection, discovered-from links
49
+ - Prevents duplicate tracking systems and confusion
50
+
51
+ ### Quick Start
52
+
53
+ **Check for ready work:**
54
+
55
+ ```bash
56
+ bd ready --json
57
+ ```
58
+
59
+ **Create new issues:**
60
+
61
+ ```bash
62
+ bd create "Issue title" --description="Detailed context" -t bug|feature|task -p 0-4 --json
63
+ bd create "Issue title" --description="What this issue is about" -p 1 --deps discovered-from:bd-123 --json
64
+ ```
65
+
66
+ **Claim and update:**
67
+
68
+ ```bash
69
+ bd update <id> --claim --json
70
+ bd update bd-42 --priority 1 --json
71
+ ```
72
+
73
+ **Complete work:**
74
+
75
+ ```bash
76
+ bd close bd-42 --reason "Completed" --json
77
+ ```
78
+
79
+ ### Issue Types
80
+
81
+ - `bug` - Something broken
82
+ - `feature` - New functionality
83
+ - `task` - Work item (tests, docs, refactoring)
84
+ - `epic` - Large feature with subtasks
85
+ - `chore` - Maintenance (dependencies, tooling)
86
+
87
+ ### Priorities
88
+
89
+ - `0` - Critical (security, data loss, broken builds)
90
+ - `1` - High (major features, important bugs)
91
+ - `2` - Medium (default, nice-to-have)
92
+ - `3` - Low (polish, optimization)
93
+ - `4` - Backlog (future ideas)
94
+
95
+ ### Workflow for AI Agents
96
+
97
+ 1. **Check ready work**: `bd ready` shows unblocked issues
98
+ 2. **Claim your task atomically**: `bd update <id> --claim`
99
+ 3. **Work on it**: Implement, test, document
100
+ 4. **Discover new work?** Create linked issue:
101
+ - `bd create "Found bug" --description="Details about what was found" -p 1 --deps discovered-from:<parent-id>`
102
+ 5. **Complete**: `bd close <id> --reason "Done"`
103
+
104
+ ### Auto-Sync
105
+
106
+ bd automatically syncs with git:
107
+
108
+ - Exports to `.beads/issues.jsonl` after changes (5s debounce)
109
+ - Imports from JSONL when newer (e.g., after `git pull`)
110
+ - No manual export/import needed!
111
+
112
+ ### Important Rules
113
+
114
+ - ✅ Use bd for ALL task tracking
115
+ - ✅ Always use `--json` flag for programmatic use
116
+ - ✅ Link discovered work with `discovered-from` dependencies
117
+ - ✅ Check `bd ready` before asking "what should I work on?"
118
+ - ❌ Do NOT create markdown TODO lists
119
+ - ❌ Do NOT use external issue trackers
120
+ - ❌ Do NOT duplicate tracking systems
121
+
122
+ For more details, see README.md and docs/QUICKSTART.md.
123
+
124
+ <!-- END BEADS INTEGRATION -->
125
+
126
+ ## Landing the Plane (Session Completion)
127
+
128
+ **When ending a work session**, you MUST complete ALL steps below. Work is NOT complete until `git push` succeeds.
129
+
130
+ **MANDATORY WORKFLOW:**
131
+
132
+ 1. **File issues for remaining work** - Create issues for anything that needs follow-up
133
+ 2. **Run quality gates** (if code changed) - Tests, linters, builds
134
+ 3. **Update issue status** - Close finished work, update in-progress items
135
+ 4. **PUSH TO REMOTE** - This is MANDATORY:
136
+ ```bash
137
+ git pull --rebase
138
+ bd sync
139
+ git push
140
+ git status # MUST show "up to date with origin"
141
+ ```
142
+ 5. **Clean up** - Clear stashes, prune remote branches
143
+ 6. **Verify** - All changes committed AND pushed
144
+ 7. **Hand off** - Provide context for next session
145
+
146
+ **CRITICAL RULES:**
147
+ - Work is NOT complete until `git push` succeeds
148
+ - NEVER stop before pushing - that leaves work stranded locally
149
+ - NEVER say "ready to push when you are" - YOU must push
150
+ - If push fails, resolve and retry until it succeeds
package/README.md ADDED
@@ -0,0 +1,84 @@
1
+ # git-worktree-organize
2
+
3
+ Convert any git repository into the canonical bare-hub worktree layout, so every branch lives in its own directory and you never need to stash or switch again.
4
+
5
+ ## What it does
6
+
7
+ Takes an existing git repo (any type) and migrates it into this structure:
8
+
9
+ ```
10
+ <dest>/
11
+ ├── .bare/ ← bare git repo (the actual git database)
12
+ ├── .git ← plain file: "gitdir: ./.bare"
13
+ ├── main/ ← worktree for the main branch
14
+ └── feature-x/ ← worktree for each other branch
15
+ ```
16
+
17
+ Each branch directory is a fully functional working tree. Open them in separate terminals or IDE windows simultaneously — no stashing, no switching.
18
+
19
+ The `.git` file at the hub root makes tools that walk up looking for `.git` (IDEs, linters, etc.) find the repo correctly.
20
+
21
+ ## Installation
22
+
23
+ **Zero-install (npx):**
24
+ ```sh
25
+ npx git-worktree-organize <source> [destination]
26
+ ```
27
+
28
+ **Global install:**
29
+ ```sh
30
+ npm install -g git-worktree-organize
31
+ git-worktree-organize <source> [destination]
32
+ ```
33
+
34
+ ## Usage
35
+
36
+ ```
37
+ git-worktree-organize <source> [destination]
38
+ ```
39
+
40
+ | Argument | Description |
41
+ |---------------|------------------------------------------------------------------|
42
+ | `source` | Path to the existing git repository to migrate |
43
+ | `destination` | Target hub directory (default: `<parent>/<repo-name>-bare`) |
44
+
45
+ The tool shows a preview of what will be created and asks for confirmation before making any changes.
46
+
47
+ ## Example
48
+
49
+ Given a repo at `/projects/myrepo` with branches `main`, `feature-x`, and `hotfix`:
50
+
51
+ ```sh
52
+ git-worktree-organize /projects/myrepo /projects/myrepo-bare
53
+ ```
54
+
55
+ Result:
56
+
57
+ ```
58
+ /projects/myrepo-bare/
59
+ ├── .bare/
60
+ ├── .git
61
+ ├── main/
62
+ ├── feature-x/
63
+ └── hotfix/
64
+ ```
65
+
66
+ The original `/projects/myrepo` is moved to `/projects/myrepo-bare/main/`. No data is lost.
67
+
68
+ ## Supported repo types
69
+
70
+ - **Standard repos** — ordinary repos with a `.git` directory
71
+ - **Bare-root** — bare repo with git internals at the root (`HEAD`, `refs/`, `objects/`)
72
+ - **Bare-dotgit** — repo where `.git` is a bare git directory (`core.bare = true`)
73
+ - **Bare-external** — repo where `.git` is a file pointing to a gitdir elsewhere
74
+ - **Bare-hub** — already in the bare-hub layout (re-organizes worktrees into the canonical structure)
75
+
76
+ Branch names with slashes (e.g. `feature/auth`) are mapped to hyphenated directory names (`feature-auth`).
77
+
78
+ ## Why this layout
79
+
80
+ Having every branch as a sibling directory means you can work on multiple branches simultaneously without stashing or switching. It is also easier to run branch-specific build artifacts side by side, and the `.git` file at the hub root ensures IDE and tooling compatibility without any special configuration.
81
+
82
+ ## License
83
+
84
+ MIT — see [github.com/drmikecrowe/git-worktree-organize](https://github.com/drmikecrowe/git-worktree-organize).
package/bun.lock ADDED
@@ -0,0 +1,205 @@
1
+ {
2
+ "lockfileVersion": 1,
3
+ "configVersion": 1,
4
+ "workspaces": {
5
+ "": {
6
+ "name": "git-worktree-organize",
7
+ "devDependencies": {
8
+ "@types/bun": "latest",
9
+ "typescript": "^5.0.0",
10
+ "vitest": "^2.0.0",
11
+ },
12
+ },
13
+ },
14
+ "packages": {
15
+ "@esbuild/aix-ppc64": ["@esbuild/aix-ppc64@0.21.5", "", { "os": "aix", "cpu": "ppc64" }, "sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ=="],
16
+
17
+ "@esbuild/android-arm": ["@esbuild/android-arm@0.21.5", "", { "os": "android", "cpu": "arm" }, "sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg=="],
18
+
19
+ "@esbuild/android-arm64": ["@esbuild/android-arm64@0.21.5", "", { "os": "android", "cpu": "arm64" }, "sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A=="],
20
+
21
+ "@esbuild/android-x64": ["@esbuild/android-x64@0.21.5", "", { "os": "android", "cpu": "x64" }, "sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA=="],
22
+
23
+ "@esbuild/darwin-arm64": ["@esbuild/darwin-arm64@0.21.5", "", { "os": "darwin", "cpu": "arm64" }, "sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ=="],
24
+
25
+ "@esbuild/darwin-x64": ["@esbuild/darwin-x64@0.21.5", "", { "os": "darwin", "cpu": "x64" }, "sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw=="],
26
+
27
+ "@esbuild/freebsd-arm64": ["@esbuild/freebsd-arm64@0.21.5", "", { "os": "freebsd", "cpu": "arm64" }, "sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g=="],
28
+
29
+ "@esbuild/freebsd-x64": ["@esbuild/freebsd-x64@0.21.5", "", { "os": "freebsd", "cpu": "x64" }, "sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ=="],
30
+
31
+ "@esbuild/linux-arm": ["@esbuild/linux-arm@0.21.5", "", { "os": "linux", "cpu": "arm" }, "sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA=="],
32
+
33
+ "@esbuild/linux-arm64": ["@esbuild/linux-arm64@0.21.5", "", { "os": "linux", "cpu": "arm64" }, "sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q=="],
34
+
35
+ "@esbuild/linux-ia32": ["@esbuild/linux-ia32@0.21.5", "", { "os": "linux", "cpu": "ia32" }, "sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg=="],
36
+
37
+ "@esbuild/linux-loong64": ["@esbuild/linux-loong64@0.21.5", "", { "os": "linux", "cpu": "none" }, "sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg=="],
38
+
39
+ "@esbuild/linux-mips64el": ["@esbuild/linux-mips64el@0.21.5", "", { "os": "linux", "cpu": "none" }, "sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg=="],
40
+
41
+ "@esbuild/linux-ppc64": ["@esbuild/linux-ppc64@0.21.5", "", { "os": "linux", "cpu": "ppc64" }, "sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w=="],
42
+
43
+ "@esbuild/linux-riscv64": ["@esbuild/linux-riscv64@0.21.5", "", { "os": "linux", "cpu": "none" }, "sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA=="],
44
+
45
+ "@esbuild/linux-s390x": ["@esbuild/linux-s390x@0.21.5", "", { "os": "linux", "cpu": "s390x" }, "sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A=="],
46
+
47
+ "@esbuild/linux-x64": ["@esbuild/linux-x64@0.21.5", "", { "os": "linux", "cpu": "x64" }, "sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ=="],
48
+
49
+ "@esbuild/netbsd-x64": ["@esbuild/netbsd-x64@0.21.5", "", { "os": "none", "cpu": "x64" }, "sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg=="],
50
+
51
+ "@esbuild/openbsd-x64": ["@esbuild/openbsd-x64@0.21.5", "", { "os": "openbsd", "cpu": "x64" }, "sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow=="],
52
+
53
+ "@esbuild/sunos-x64": ["@esbuild/sunos-x64@0.21.5", "", { "os": "sunos", "cpu": "x64" }, "sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg=="],
54
+
55
+ "@esbuild/win32-arm64": ["@esbuild/win32-arm64@0.21.5", "", { "os": "win32", "cpu": "arm64" }, "sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A=="],
56
+
57
+ "@esbuild/win32-ia32": ["@esbuild/win32-ia32@0.21.5", "", { "os": "win32", "cpu": "ia32" }, "sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA=="],
58
+
59
+ "@esbuild/win32-x64": ["@esbuild/win32-x64@0.21.5", "", { "os": "win32", "cpu": "x64" }, "sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw=="],
60
+
61
+ "@jridgewell/sourcemap-codec": ["@jridgewell/sourcemap-codec@1.5.5", "", {}, "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og=="],
62
+
63
+ "@rollup/rollup-android-arm-eabi": ["@rollup/rollup-android-arm-eabi@4.59.0", "", { "os": "android", "cpu": "arm" }, "sha512-upnNBkA6ZH2VKGcBj9Fyl9IGNPULcjXRlg0LLeaioQWueH30p6IXtJEbKAgvyv+mJaMxSm1l6xwDXYjpEMiLMg=="],
64
+
65
+ "@rollup/rollup-android-arm64": ["@rollup/rollup-android-arm64@4.59.0", "", { "os": "android", "cpu": "arm64" }, "sha512-hZ+Zxj3SySm4A/DylsDKZAeVg0mvi++0PYVceVyX7hemkw7OreKdCvW2oQ3T1FMZvCaQXqOTHb8qmBShoqk69Q=="],
66
+
67
+ "@rollup/rollup-darwin-arm64": ["@rollup/rollup-darwin-arm64@4.59.0", "", { "os": "darwin", "cpu": "arm64" }, "sha512-W2Psnbh1J8ZJw0xKAd8zdNgF9HRLkdWwwdWqubSVk0pUuQkoHnv7rx4GiF9rT4t5DIZGAsConRE3AxCdJ4m8rg=="],
68
+
69
+ "@rollup/rollup-darwin-x64": ["@rollup/rollup-darwin-x64@4.59.0", "", { "os": "darwin", "cpu": "x64" }, "sha512-ZW2KkwlS4lwTv7ZVsYDiARfFCnSGhzYPdiOU4IM2fDbL+QGlyAbjgSFuqNRbSthybLbIJ915UtZBtmuLrQAT/w=="],
70
+
71
+ "@rollup/rollup-freebsd-arm64": ["@rollup/rollup-freebsd-arm64@4.59.0", "", { "os": "freebsd", "cpu": "arm64" }, "sha512-EsKaJ5ytAu9jI3lonzn3BgG8iRBjV4LxZexygcQbpiU0wU0ATxhNVEpXKfUa0pS05gTcSDMKpn3Sx+QB9RlTTA=="],
72
+
73
+ "@rollup/rollup-freebsd-x64": ["@rollup/rollup-freebsd-x64@4.59.0", "", { "os": "freebsd", "cpu": "x64" }, "sha512-d3DuZi2KzTMjImrxoHIAODUZYoUUMsuUiY4SRRcJy6NJoZ6iIqWnJu9IScV9jXysyGMVuW+KNzZvBLOcpdl3Vg=="],
74
+
75
+ "@rollup/rollup-linux-arm-gnueabihf": ["@rollup/rollup-linux-arm-gnueabihf@4.59.0", "", { "os": "linux", "cpu": "arm" }, "sha512-t4ONHboXi/3E0rT6OZl1pKbl2Vgxf9vJfWgmUoCEVQVxhW6Cw/c8I6hbbu7DAvgp82RKiH7TpLwxnJeKv2pbsw=="],
76
+
77
+ "@rollup/rollup-linux-arm-musleabihf": ["@rollup/rollup-linux-arm-musleabihf@4.59.0", "", { "os": "linux", "cpu": "arm" }, "sha512-CikFT7aYPA2ufMD086cVORBYGHffBo4K8MQ4uPS/ZnY54GKj36i196u8U+aDVT2LX4eSMbyHtyOh7D7Zvk2VvA=="],
78
+
79
+ "@rollup/rollup-linux-arm64-gnu": ["@rollup/rollup-linux-arm64-gnu@4.59.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-jYgUGk5aLd1nUb1CtQ8E+t5JhLc9x5WdBKew9ZgAXg7DBk0ZHErLHdXM24rfX+bKrFe+Xp5YuJo54I5HFjGDAA=="],
80
+
81
+ "@rollup/rollup-linux-arm64-musl": ["@rollup/rollup-linux-arm64-musl@4.59.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-peZRVEdnFWZ5Bh2KeumKG9ty7aCXzzEsHShOZEFiCQlDEepP1dpUl/SrUNXNg13UmZl+gzVDPsiCwnV1uI0RUA=="],
82
+
83
+ "@rollup/rollup-linux-loong64-gnu": ["@rollup/rollup-linux-loong64-gnu@4.59.0", "", { "os": "linux", "cpu": "none" }, "sha512-gbUSW/97f7+r4gHy3Jlup8zDG190AuodsWnNiXErp9mT90iCy9NKKU0Xwx5k8VlRAIV2uU9CsMnEFg/xXaOfXg=="],
84
+
85
+ "@rollup/rollup-linux-loong64-musl": ["@rollup/rollup-linux-loong64-musl@4.59.0", "", { "os": "linux", "cpu": "none" }, "sha512-yTRONe79E+o0FWFijasoTjtzG9EBedFXJMl888NBEDCDV9I2wGbFFfJQQe63OijbFCUZqxpHz1GzpbtSFikJ4Q=="],
86
+
87
+ "@rollup/rollup-linux-ppc64-gnu": ["@rollup/rollup-linux-ppc64-gnu@4.59.0", "", { "os": "linux", "cpu": "ppc64" }, "sha512-sw1o3tfyk12k3OEpRddF68a1unZ5VCN7zoTNtSn2KndUE+ea3m3ROOKRCZxEpmT9nsGnogpFP9x6mnLTCaoLkA=="],
88
+
89
+ "@rollup/rollup-linux-ppc64-musl": ["@rollup/rollup-linux-ppc64-musl@4.59.0", "", { "os": "linux", "cpu": "ppc64" }, "sha512-+2kLtQ4xT3AiIxkzFVFXfsmlZiG5FXYW7ZyIIvGA7Bdeuh9Z0aN4hVyXS/G1E9bTP/vqszNIN/pUKCk/BTHsKA=="],
90
+
91
+ "@rollup/rollup-linux-riscv64-gnu": ["@rollup/rollup-linux-riscv64-gnu@4.59.0", "", { "os": "linux", "cpu": "none" }, "sha512-NDYMpsXYJJaj+I7UdwIuHHNxXZ/b/N2hR15NyH3m2qAtb/hHPA4g4SuuvrdxetTdndfj9b1WOmy73kcPRoERUg=="],
92
+
93
+ "@rollup/rollup-linux-riscv64-musl": ["@rollup/rollup-linux-riscv64-musl@4.59.0", "", { "os": "linux", "cpu": "none" }, "sha512-nLckB8WOqHIf1bhymk+oHxvM9D3tyPndZH8i8+35p/1YiVoVswPid2yLzgX7ZJP0KQvnkhM4H6QZ5m0LzbyIAg=="],
94
+
95
+ "@rollup/rollup-linux-s390x-gnu": ["@rollup/rollup-linux-s390x-gnu@4.59.0", "", { "os": "linux", "cpu": "s390x" }, "sha512-oF87Ie3uAIvORFBpwnCvUzdeYUqi2wY6jRFWJAy1qus/udHFYIkplYRW+wo+GRUP4sKzYdmE1Y3+rY5Gc4ZO+w=="],
96
+
97
+ "@rollup/rollup-linux-x64-gnu": ["@rollup/rollup-linux-x64-gnu@4.59.0", "", { "os": "linux", "cpu": "x64" }, "sha512-3AHmtQq/ppNuUspKAlvA8HtLybkDflkMuLK4DPo77DfthRb71V84/c4MlWJXixZz4uruIH4uaa07IqoAkG64fg=="],
98
+
99
+ "@rollup/rollup-linux-x64-musl": ["@rollup/rollup-linux-x64-musl@4.59.0", "", { "os": "linux", "cpu": "x64" }, "sha512-2UdiwS/9cTAx7qIUZB/fWtToJwvt0Vbo0zmnYt7ED35KPg13Q0ym1g442THLC7VyI6JfYTP4PiSOWyoMdV2/xg=="],
100
+
101
+ "@rollup/rollup-openbsd-x64": ["@rollup/rollup-openbsd-x64@4.59.0", "", { "os": "openbsd", "cpu": "x64" }, "sha512-M3bLRAVk6GOwFlPTIxVBSYKUaqfLrn8l0psKinkCFxl4lQvOSz8ZrKDz2gxcBwHFpci0B6rttydI4IpS4IS/jQ=="],
102
+
103
+ "@rollup/rollup-openharmony-arm64": ["@rollup/rollup-openharmony-arm64@4.59.0", "", { "os": "none", "cpu": "arm64" }, "sha512-tt9KBJqaqp5i5HUZzoafHZX8b5Q2Fe7UjYERADll83O4fGqJ49O1FsL6LpdzVFQcpwvnyd0i+K/VSwu/o/nWlA=="],
104
+
105
+ "@rollup/rollup-win32-arm64-msvc": ["@rollup/rollup-win32-arm64-msvc@4.59.0", "", { "os": "win32", "cpu": "arm64" }, "sha512-V5B6mG7OrGTwnxaNUzZTDTjDS7F75PO1ae6MJYdiMu60sq0CqN5CVeVsbhPxalupvTX8gXVSU9gq+Rx1/hvu6A=="],
106
+
107
+ "@rollup/rollup-win32-ia32-msvc": ["@rollup/rollup-win32-ia32-msvc@4.59.0", "", { "os": "win32", "cpu": "ia32" }, "sha512-UKFMHPuM9R0iBegwzKF4y0C4J9u8C6MEJgFuXTBerMk7EJ92GFVFYBfOZaSGLu6COf7FxpQNqhNS4c4icUPqxA=="],
108
+
109
+ "@rollup/rollup-win32-x64-gnu": ["@rollup/rollup-win32-x64-gnu@4.59.0", "", { "os": "win32", "cpu": "x64" }, "sha512-laBkYlSS1n2L8fSo1thDNGrCTQMmxjYY5G0WFWjFFYZkKPjsMBsgJfGf4TLxXrF6RyhI60L8TMOjBMvXiTcxeA=="],
110
+
111
+ "@rollup/rollup-win32-x64-msvc": ["@rollup/rollup-win32-x64-msvc@4.59.0", "", { "os": "win32", "cpu": "x64" }, "sha512-2HRCml6OztYXyJXAvdDXPKcawukWY2GpR5/nxKp4iBgiO3wcoEGkAaqctIbZcNB6KlUQBIqt8VYkNSj2397EfA=="],
112
+
113
+ "@types/bun": ["@types/bun@1.3.10", "", { "dependencies": { "bun-types": "1.3.10" } }, "sha512-0+rlrUrOrTSskibryHbvQkDOWRJwJZqZlxrUs1u4oOoTln8+WIXBPmAuCF35SWB2z4Zl3E84Nl/D0P7803nigQ=="],
114
+
115
+ "@types/estree": ["@types/estree@1.0.8", "", {}, "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w=="],
116
+
117
+ "@types/node": ["@types/node@25.3.5", "", { "dependencies": { "undici-types": "~7.18.0" } }, "sha512-oX8xrhvpiyRCQkG1MFchB09f+cXftgIXb3a7UUa4Y3wpmZPw5tyZGTLWhlESOLq1Rq6oDlc8npVU2/9xiCuXMA=="],
118
+
119
+ "@vitest/expect": ["@vitest/expect@2.1.9", "", { "dependencies": { "@vitest/spy": "2.1.9", "@vitest/utils": "2.1.9", "chai": "^5.1.2", "tinyrainbow": "^1.2.0" } }, "sha512-UJCIkTBenHeKT1TTlKMJWy1laZewsRIzYighyYiJKZreqtdxSos/S1t+ktRMQWu2CKqaarrkeszJx1cgC5tGZw=="],
120
+
121
+ "@vitest/mocker": ["@vitest/mocker@2.1.9", "", { "dependencies": { "@vitest/spy": "2.1.9", "estree-walker": "^3.0.3", "magic-string": "^0.30.12" }, "peerDependencies": { "msw": "^2.4.9", "vite": "^5.0.0" }, "optionalPeers": ["msw", "vite"] }, "sha512-tVL6uJgoUdi6icpxmdrn5YNo3g3Dxv+IHJBr0GXHaEdTcw3F+cPKnsXFhli6nO+f/6SDKPHEK1UN+k+TQv0Ehg=="],
122
+
123
+ "@vitest/pretty-format": ["@vitest/pretty-format@2.1.9", "", { "dependencies": { "tinyrainbow": "^1.2.0" } }, "sha512-KhRIdGV2U9HOUzxfiHmY8IFHTdqtOhIzCpd8WRdJiE7D/HUcZVD0EgQCVjm+Q9gkUXWgBvMmTtZgIG48wq7sOQ=="],
124
+
125
+ "@vitest/runner": ["@vitest/runner@2.1.9", "", { "dependencies": { "@vitest/utils": "2.1.9", "pathe": "^1.1.2" } }, "sha512-ZXSSqTFIrzduD63btIfEyOmNcBmQvgOVsPNPe0jYtESiXkhd8u2erDLnMxmGrDCwHCCHE7hxwRDCT3pt0esT4g=="],
126
+
127
+ "@vitest/snapshot": ["@vitest/snapshot@2.1.9", "", { "dependencies": { "@vitest/pretty-format": "2.1.9", "magic-string": "^0.30.12", "pathe": "^1.1.2" } }, "sha512-oBO82rEjsxLNJincVhLhaxxZdEtV0EFHMK5Kmx5sJ6H9L183dHECjiefOAdnqpIgT5eZwT04PoggUnW88vOBNQ=="],
128
+
129
+ "@vitest/spy": ["@vitest/spy@2.1.9", "", { "dependencies": { "tinyspy": "^3.0.2" } }, "sha512-E1B35FwzXXTs9FHNK6bDszs7mtydNi5MIfUWpceJ8Xbfb1gBMscAnwLbEu+B44ed6W3XjL9/ehLPHR1fkf1KLQ=="],
130
+
131
+ "@vitest/utils": ["@vitest/utils@2.1.9", "", { "dependencies": { "@vitest/pretty-format": "2.1.9", "loupe": "^3.1.2", "tinyrainbow": "^1.2.0" } }, "sha512-v0psaMSkNJ3A2NMrUEHFRzJtDPFn+/VWZ5WxImB21T9fjucJRmS7xCS3ppEnARb9y11OAzaD+P2Ps+b+BGX5iQ=="],
132
+
133
+ "assertion-error": ["assertion-error@2.0.1", "", {}, "sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA=="],
134
+
135
+ "bun-types": ["bun-types@1.3.10", "", { "dependencies": { "@types/node": "*" } }, "sha512-tcpfCCl6XWo6nCVnpcVrxQ+9AYN1iqMIzgrSKYMB/fjLtV2eyAVEg7AxQJuCq/26R6HpKWykQXuSOq/21RYcbg=="],
136
+
137
+ "cac": ["cac@6.7.14", "", {}, "sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ=="],
138
+
139
+ "chai": ["chai@5.3.3", "", { "dependencies": { "assertion-error": "^2.0.1", "check-error": "^2.1.1", "deep-eql": "^5.0.1", "loupe": "^3.1.0", "pathval": "^2.0.0" } }, "sha512-4zNhdJD/iOjSH0A05ea+Ke6MU5mmpQcbQsSOkgdaUMJ9zTlDTD/GYlwohmIE2u0gaxHYiVHEn1Fw9mZ/ktJWgw=="],
140
+
141
+ "check-error": ["check-error@2.1.3", "", {}, "sha512-PAJdDJusoxnwm1VwW07VWwUN1sl7smmC3OKggvndJFadxxDRyFJBX/ggnu/KE4kQAB7a3Dp8f/YXC1FlUprWmA=="],
142
+
143
+ "debug": ["debug@4.4.3", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA=="],
144
+
145
+ "deep-eql": ["deep-eql@5.0.2", "", {}, "sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q=="],
146
+
147
+ "es-module-lexer": ["es-module-lexer@1.7.0", "", {}, "sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA=="],
148
+
149
+ "esbuild": ["esbuild@0.21.5", "", { "optionalDependencies": { "@esbuild/aix-ppc64": "0.21.5", "@esbuild/android-arm": "0.21.5", "@esbuild/android-arm64": "0.21.5", "@esbuild/android-x64": "0.21.5", "@esbuild/darwin-arm64": "0.21.5", "@esbuild/darwin-x64": "0.21.5", "@esbuild/freebsd-arm64": "0.21.5", "@esbuild/freebsd-x64": "0.21.5", "@esbuild/linux-arm": "0.21.5", "@esbuild/linux-arm64": "0.21.5", "@esbuild/linux-ia32": "0.21.5", "@esbuild/linux-loong64": "0.21.5", "@esbuild/linux-mips64el": "0.21.5", "@esbuild/linux-ppc64": "0.21.5", "@esbuild/linux-riscv64": "0.21.5", "@esbuild/linux-s390x": "0.21.5", "@esbuild/linux-x64": "0.21.5", "@esbuild/netbsd-x64": "0.21.5", "@esbuild/openbsd-x64": "0.21.5", "@esbuild/sunos-x64": "0.21.5", "@esbuild/win32-arm64": "0.21.5", "@esbuild/win32-ia32": "0.21.5", "@esbuild/win32-x64": "0.21.5" }, "bin": { "esbuild": "bin/esbuild" } }, "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw=="],
150
+
151
+ "estree-walker": ["estree-walker@3.0.3", "", { "dependencies": { "@types/estree": "^1.0.0" } }, "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g=="],
152
+
153
+ "expect-type": ["expect-type@1.3.0", "", {}, "sha512-knvyeauYhqjOYvQ66MznSMs83wmHrCycNEN6Ao+2AeYEfxUIkuiVxdEa1qlGEPK+We3n0THiDciYSsCcgW/DoA=="],
154
+
155
+ "fsevents": ["fsevents@2.3.3", "", { "os": "darwin" }, "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw=="],
156
+
157
+ "loupe": ["loupe@3.2.1", "", {}, "sha512-CdzqowRJCeLU72bHvWqwRBBlLcMEtIvGrlvef74kMnV2AolS9Y8xUv1I0U/MNAWMhBlKIoyuEgoJ0t/bbwHbLQ=="],
158
+
159
+ "magic-string": ["magic-string@0.30.21", "", { "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.5" } }, "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ=="],
160
+
161
+ "ms": ["ms@2.1.3", "", {}, "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="],
162
+
163
+ "nanoid": ["nanoid@3.3.11", "", { "bin": { "nanoid": "bin/nanoid.cjs" } }, "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w=="],
164
+
165
+ "pathe": ["pathe@1.1.2", "", {}, "sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ=="],
166
+
167
+ "pathval": ["pathval@2.0.1", "", {}, "sha512-//nshmD55c46FuFw26xV/xFAaB5HF9Xdap7HJBBnrKdAd6/GxDBaNA1870O79+9ueg61cZLSVc+OaFlfmObYVQ=="],
168
+
169
+ "picocolors": ["picocolors@1.1.1", "", {}, "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA=="],
170
+
171
+ "postcss": ["postcss@8.5.8", "", { "dependencies": { "nanoid": "^3.3.11", "picocolors": "^1.1.1", "source-map-js": "^1.2.1" } }, "sha512-OW/rX8O/jXnm82Ey1k44pObPtdblfiuWnrd8X7GJ7emImCOstunGbXUpp7HdBrFQX6rJzn3sPT397Wp5aCwCHg=="],
172
+
173
+ "rollup": ["rollup@4.59.0", "", { "dependencies": { "@types/estree": "1.0.8" }, "optionalDependencies": { "@rollup/rollup-android-arm-eabi": "4.59.0", "@rollup/rollup-android-arm64": "4.59.0", "@rollup/rollup-darwin-arm64": "4.59.0", "@rollup/rollup-darwin-x64": "4.59.0", "@rollup/rollup-freebsd-arm64": "4.59.0", "@rollup/rollup-freebsd-x64": "4.59.0", "@rollup/rollup-linux-arm-gnueabihf": "4.59.0", "@rollup/rollup-linux-arm-musleabihf": "4.59.0", "@rollup/rollup-linux-arm64-gnu": "4.59.0", "@rollup/rollup-linux-arm64-musl": "4.59.0", "@rollup/rollup-linux-loong64-gnu": "4.59.0", "@rollup/rollup-linux-loong64-musl": "4.59.0", "@rollup/rollup-linux-ppc64-gnu": "4.59.0", "@rollup/rollup-linux-ppc64-musl": "4.59.0", "@rollup/rollup-linux-riscv64-gnu": "4.59.0", "@rollup/rollup-linux-riscv64-musl": "4.59.0", "@rollup/rollup-linux-s390x-gnu": "4.59.0", "@rollup/rollup-linux-x64-gnu": "4.59.0", "@rollup/rollup-linux-x64-musl": "4.59.0", "@rollup/rollup-openbsd-x64": "4.59.0", "@rollup/rollup-openharmony-arm64": "4.59.0", "@rollup/rollup-win32-arm64-msvc": "4.59.0", "@rollup/rollup-win32-ia32-msvc": "4.59.0", "@rollup/rollup-win32-x64-gnu": "4.59.0", "@rollup/rollup-win32-x64-msvc": "4.59.0", "fsevents": "~2.3.2" }, "bin": { "rollup": "dist/bin/rollup" } }, "sha512-2oMpl67a3zCH9H79LeMcbDhXW/UmWG/y2zuqnF2jQq5uq9TbM9TVyXvA4+t+ne2IIkBdrLpAaRQAvo7YI/Yyeg=="],
174
+
175
+ "siginfo": ["siginfo@2.0.0", "", {}, "sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g=="],
176
+
177
+ "source-map-js": ["source-map-js@1.2.1", "", {}, "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA=="],
178
+
179
+ "stackback": ["stackback@0.0.2", "", {}, "sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw=="],
180
+
181
+ "std-env": ["std-env@3.10.0", "", {}, "sha512-5GS12FdOZNliM5mAOxFRg7Ir0pWz8MdpYm6AY6VPkGpbA7ZzmbzNcBJQ0GPvvyWgcY7QAhCgf9Uy89I03faLkg=="],
182
+
183
+ "tinybench": ["tinybench@2.9.0", "", {}, "sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg=="],
184
+
185
+ "tinyexec": ["tinyexec@0.3.2", "", {}, "sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA=="],
186
+
187
+ "tinypool": ["tinypool@1.1.1", "", {}, "sha512-Zba82s87IFq9A9XmjiX5uZA/ARWDrB03OHlq+Vw1fSdt0I+4/Kutwy8BP4Y/y/aORMo61FQ0vIb5j44vSo5Pkg=="],
188
+
189
+ "tinyrainbow": ["tinyrainbow@1.2.0", "", {}, "sha512-weEDEq7Z5eTHPDh4xjX789+fHfF+P8boiFB+0vbWzpbnbsEr/GRaohi/uMKxg8RZMXnl1ItAi/IUHWMsjDV7kQ=="],
190
+
191
+ "tinyspy": ["tinyspy@3.0.2", "", {}, "sha512-n1cw8k1k0x4pgA2+9XrOkFydTerNcJ1zWCO5Nn9scWHTD+5tp8dghT2x1uduQePZTZgd3Tupf+x9BxJjeJi77Q=="],
192
+
193
+ "typescript": ["typescript@5.9.3", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw=="],
194
+
195
+ "undici-types": ["undici-types@7.18.2", "", {}, "sha512-AsuCzffGHJybSaRrmr5eHr81mwJU3kjw6M+uprWvCXiNeN9SOGwQ3Jn8jb8m3Z6izVgknn1R0FTCEAP2QrLY/w=="],
196
+
197
+ "vite": ["vite@5.4.21", "", { "dependencies": { "esbuild": "^0.21.3", "postcss": "^8.4.43", "rollup": "^4.20.0" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "peerDependencies": { "@types/node": "^18.0.0 || >=20.0.0", "less": "*", "lightningcss": "^1.21.0", "sass": "*", "sass-embedded": "*", "stylus": "*", "sugarss": "*", "terser": "^5.4.0" }, "optionalPeers": ["@types/node", "less", "lightningcss", "sass", "sass-embedded", "stylus", "sugarss", "terser"], "bin": { "vite": "bin/vite.js" } }, "sha512-o5a9xKjbtuhY6Bi5S3+HvbRERmouabWbyUcpXXUA1u+GNUKoROi9byOJ8M0nHbHYHkYICiMlqxkg1KkYmm25Sw=="],
198
+
199
+ "vite-node": ["vite-node@2.1.9", "", { "dependencies": { "cac": "^6.7.14", "debug": "^4.3.7", "es-module-lexer": "^1.5.4", "pathe": "^1.1.2", "vite": "^5.0.0" }, "bin": { "vite-node": "vite-node.mjs" } }, "sha512-AM9aQ/IPrW/6ENLQg3AGY4K1N2TGZdR5e4gu/MmmR2xR3Ll1+dib+nook92g4TV3PXVyeyxdWwtaCAiUL0hMxA=="],
200
+
201
+ "vitest": ["vitest@2.1.9", "", { "dependencies": { "@vitest/expect": "2.1.9", "@vitest/mocker": "2.1.9", "@vitest/pretty-format": "^2.1.9", "@vitest/runner": "2.1.9", "@vitest/snapshot": "2.1.9", "@vitest/spy": "2.1.9", "@vitest/utils": "2.1.9", "chai": "^5.1.2", "debug": "^4.3.7", "expect-type": "^1.1.0", "magic-string": "^0.30.12", "pathe": "^1.1.2", "std-env": "^3.8.0", "tinybench": "^2.9.0", "tinyexec": "^0.3.1", "tinypool": "^1.0.1", "tinyrainbow": "^1.2.0", "vite": "^5.0.0", "vite-node": "2.1.9", "why-is-node-running": "^2.3.0" }, "peerDependencies": { "@edge-runtime/vm": "*", "@types/node": "^18.0.0 || >=20.0.0", "@vitest/browser": "2.1.9", "@vitest/ui": "2.1.9", "happy-dom": "*", "jsdom": "*" }, "optionalPeers": ["@edge-runtime/vm", "@types/node", "@vitest/browser", "@vitest/ui", "happy-dom", "jsdom"], "bin": { "vitest": "vitest.mjs" } }, "sha512-MSmPM9REYqDGBI8439mA4mWhV5sKmDlBKWIYbA3lRb2PTHACE0mgKwA8yQ2xq9vxDTuk4iPrECBAEW2aoFXY0Q=="],
202
+
203
+ "why-is-node-running": ["why-is-node-running@2.3.0", "", { "dependencies": { "siginfo": "^2.0.0", "stackback": "0.0.2" }, "bin": { "why-is-node-running": "cli.js" } }, "sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w=="],
204
+ }
205
+ }
package/package.json ADDED
@@ -0,0 +1,21 @@
1
+ {
2
+ "name": "git-worktree-organize",
3
+ "version": "1.0.0",
4
+ "description": "Convert any git repo into the canonical bare-hub worktree layout",
5
+ "type": "module",
6
+ "bin": {
7
+ "git-worktree-organize": "./src/cli.ts"
8
+ },
9
+ "scripts": {
10
+ "build": "bun build src/cli.ts --outfile dist/cli.js --target node",
11
+ "test": "bun test",
12
+ "test:watch": "vitest",
13
+ "publish": "op run -- npm publish"
14
+ },
15
+ "devDependencies": {
16
+ "@types/bun": "latest",
17
+ "typescript": "^5.0.0",
18
+ "vitest": "^2.0.0"
19
+ },
20
+ "license": "MIT"
21
+ }
package/src/cli.ts ADDED
@@ -0,0 +1,143 @@
1
+ #!/usr/bin/env bun
2
+ /**
3
+ * git-worktree-organize <source> [destination]
4
+ *
5
+ * Convert any git repo into the canonical bare-hub worktree layout.
6
+ */
7
+
8
+ import { resolve, join, dirname, basename } from 'node:path'
9
+ import { $ } from 'bun'
10
+ import { detect } from './detect.ts'
11
+ import { listWorktrees } from './worktrees.ts'
12
+ import { migrate, sanitizeBranch } from './migrate.ts'
13
+
14
+ // ANSI color helpers
15
+ const GREEN = '\x1b[32m'
16
+ const YELLOW = '\x1b[33m'
17
+ const BOLD = '\x1b[1m'
18
+ const RESET = '\x1b[0m'
19
+
20
+ function green(s: string) { return `${GREEN}${s}${RESET}` }
21
+ function yellow(s: string) { return `${YELLOW}${s}${RESET}` }
22
+ function bold(s: string) { return `${BOLD}${s}${RESET}` }
23
+
24
+ function usage(): void {
25
+ console.log(`Usage: git-worktree-organize <source> [destination]
26
+
27
+ Convert a git repository into the canonical bare-hub worktree layout:
28
+
29
+ <dest>/.bare/ ← bare git repo
30
+ <dest>/.git ← plain file: "gitdir: ./.bare"
31
+ <dest>/<branch>/ ← one directory per worktree
32
+
33
+ Arguments:
34
+ source Path to existing git repository
35
+ destination Target hub directory (default: <parent>/<name>-bare)
36
+
37
+ Options:
38
+ -h, --help Show help`)
39
+ }
40
+
41
+ async function main(): Promise<void> {
42
+ const args = process.argv.slice(2)
43
+
44
+ if (args.length === 0 || args[0] === '-h' || args[0] === '--help') {
45
+ usage()
46
+ process.exit(0)
47
+ }
48
+
49
+ const sourcePath = args[0]
50
+ const destArg = args[1]
51
+
52
+ // Resolve source early so we can display it
53
+ const source = resolve(sourcePath)
54
+
55
+ // Compute the destination the same way migrate() does
56
+ const dest = destArg
57
+ ? resolve(destArg)
58
+ : join(dirname(source), basename(source) + '-bare')
59
+
60
+ console.log(`\n${green('==>')} Reading worktrees from ${source}\n`)
61
+
62
+ // Detect repo type and list worktrees for display
63
+ const config = await detect(source)
64
+ const allWorktrees = await listWorktrees(source)
65
+ const worktrees = allWorktrees.filter(wt => !wt.isBare)
66
+
67
+ // Determine which branch is "main" (first worktree for standard repos)
68
+ let mainBranch: string | null = null
69
+ if (config.type === 'standard' && worktrees.length > 0) {
70
+ mainBranch = worktrees[0].branch
71
+ }
72
+
73
+ // Print worktrees table
74
+ console.log('Worktrees to migrate:')
75
+
76
+ // Find the longest branch name for alignment
77
+ const entries = worktrees.map(wt => {
78
+ const branch = wt.branch ?? `detached-${wt.head.slice(0, 8)}`
79
+ const safe = sanitizeBranch(branch)
80
+ const isMain = branch === mainBranch
81
+ const destDir = join(dest, safe)
82
+ return { branch, isMain, destDir }
83
+ })
84
+
85
+ const maxNameLen = entries.reduce((m, e) => Math.max(m, e.branch.length), 0)
86
+
87
+ for (const { branch, isMain, destDir } of entries) {
88
+ const tag = isMain ? yellow('[main]') : ''
89
+ const tagPad = isMain ? ` (labeled ${yellow('[main]')})` : ''
90
+ // branch column width: bold branch name padded to maxNameLen + 2 brackets
91
+ const nameCol = bold(`[${branch}]`).padEnd(maxNameLen + 2 + BOLD.length + RESET.length)
92
+ // align the tag annotation
93
+ const annotation = isMain
94
+ ? ` (labeled ${yellow('[main]')})`.padEnd(18 + YELLOW.length + RESET.length)
95
+ : ''.padEnd(18)
96
+ void tag; void tagPad
97
+ console.log(` ${nameCol}${annotation} → ${destDir}`)
98
+ }
99
+
100
+ console.log()
101
+ console.log(`Hub destination: ${bold(dest)} (bare repo at ${dest}/.bare)`)
102
+ console.log()
103
+
104
+ // Interactive confirmation
105
+ process.stdout.write('Proceed? [y/N] ')
106
+ const ans = await new Promise<string>(resolve => {
107
+ process.stdin.setEncoding('utf8')
108
+ process.stdin.once('data', chunk => resolve(chunk.toString().trim()))
109
+ })
110
+ process.stdin.destroy()
111
+
112
+ if (!/^[Yy]$/.test(ans)) {
113
+ console.log('Aborted.')
114
+ process.exit(0)
115
+ }
116
+
117
+ console.log()
118
+
119
+ // Run migration
120
+ const hubPath = await migrate(config, { source: sourcePath, dest: destArg ?? '' })
121
+
122
+ // Verify
123
+ console.log(`${green('==>')} Verifying with git worktree list...`)
124
+ const verifyOutput = await $`git -C ${hubPath} worktree list`.text()
125
+ console.log(verifyOutput)
126
+
127
+ console.log(`Done! Hub: ${hubPath}`)
128
+ console.log()
129
+
130
+ // Determine main branch name for the useful commands hint
131
+ const mainSafe = mainBranch ? sanitizeBranch(mainBranch) : (entries[0]?.branch ? sanitizeBranch(entries[0].branch) : '')
132
+
133
+ console.log('Useful commands:')
134
+ console.log(` git -C ${hubPath} worktree list`)
135
+ if (mainSafe) {
136
+ console.log(` git -C ${hubPath}/${mainSafe} log --oneline -5`)
137
+ }
138
+ }
139
+
140
+ main().catch(err => {
141
+ process.stderr.write(`error: ${err.message}\n`)
142
+ process.exit(1)
143
+ })