git-worktree-organize 1.0.8 → 1.0.10

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.
package/dist/cli.js ADDED
@@ -0,0 +1,382 @@
1
+ #!/usr/bin/env bun
2
+ // @bun
3
+
4
+ // src/cli.ts
5
+ import { resolve as resolve3, join as join3, dirname as dirname2, basename as basename2 } from "path";
6
+
7
+ // src/run.ts
8
+ import { spawnSync } from "node:child_process";
9
+ function run(cmd, args, options) {
10
+ const result = spawnSync(cmd, args, {
11
+ encoding: "utf8",
12
+ cwd: options?.cwd,
13
+ env: options?.env ?? process.env
14
+ });
15
+ if (result.status !== 0) {
16
+ const err = new Error(`${cmd} ${args.join(" ")} failed: ${result.stderr?.trim() || result.error?.message}`);
17
+ err.exitCode = result.status;
18
+ err.stderr = result.stderr;
19
+ throw err;
20
+ }
21
+ return { stdout: result.stdout ?? "", stderr: result.stderr ?? "" };
22
+ }
23
+
24
+ // src/detect.ts
25
+ import { existsSync, statSync, readFileSync } from "node:fs";
26
+ import { join, resolve, isAbsolute } from "node:path";
27
+
28
+ // src/run.ts
29
+ import { spawnSync as spawnSync2 } from "node:child_process";
30
+ function run2(cmd, args, options) {
31
+ const result = spawnSync2(cmd, args, {
32
+ encoding: "utf8",
33
+ cwd: options?.cwd,
34
+ env: options?.env ?? process.env
35
+ });
36
+ if (result.status !== 0) {
37
+ const err = new Error(`${cmd} ${args.join(" ")} failed: ${result.stderr?.trim() || result.error?.message}`);
38
+ err.exitCode = result.status;
39
+ err.stderr = result.stderr;
40
+ throw err;
41
+ }
42
+ return { stdout: result.stdout ?? "", stderr: result.stderr ?? "" };
43
+ }
44
+
45
+ // src/detect.ts
46
+ function readCoreBare(gitdir) {
47
+ try {
48
+ const result = run2("git", ["--git-dir", gitdir, "config", "--get", "core.bare"]);
49
+ return result.stdout.trim() === "true";
50
+ } catch {
51
+ return false;
52
+ }
53
+ }
54
+ async function detect(repoPath) {
55
+ const gitEntryPath = join(repoPath, ".git");
56
+ const gitEntryExists = existsSync(gitEntryPath);
57
+ if (gitEntryExists) {
58
+ const stat = statSync(gitEntryPath);
59
+ if (stat.isDirectory()) {
60
+ const isbare = readCoreBare(gitEntryPath);
61
+ if (isbare) {
62
+ return { type: "bare-dotgit", gitdir: gitEntryPath };
63
+ } else {
64
+ return { type: "standard", gitdir: gitEntryPath, mainWorktree: repoPath };
65
+ }
66
+ } else if (stat.isFile()) {
67
+ const contents = readFileSync(gitEntryPath, "utf8");
68
+ const firstLine = contents.split(`
69
+ `)[0].trim();
70
+ const match = firstLine.match(/^gitdir:\s*(.+)$/);
71
+ if (!match) {
72
+ throw new Error(`not a git repository: ${repoPath}`);
73
+ }
74
+ const rawGitdir = match[1].trim();
75
+ const absGitdir = isAbsolute(rawGitdir) ? rawGitdir : resolve(repoPath, rawGitdir);
76
+ if (absGitdir.includes("/worktrees/")) {
77
+ throw new Error("is a linked worktree, not a repo root");
78
+ }
79
+ if (!existsSync(join(absGitdir, "HEAD")) || !existsSync(join(absGitdir, "objects")) || !existsSync(join(absGitdir, "refs"))) {
80
+ throw new Error(`gitdir does not appear to be a git repository: ${absGitdir}`);
81
+ }
82
+ if (absGitdir.endsWith(".bare")) {
83
+ return { type: "bare-hub", gitdir: absGitdir };
84
+ }
85
+ return { type: "bare-external", gitdir: absGitdir };
86
+ }
87
+ }
88
+ const headExists = existsSync(join(repoPath, "HEAD"));
89
+ const refsExists = existsSync(join(repoPath, "refs"));
90
+ const objectsExists = existsSync(join(repoPath, "objects"));
91
+ if (headExists && refsExists && objectsExists) {
92
+ return { type: "bare-root", gitdir: repoPath };
93
+ }
94
+ throw new Error(`not a git repository: ${repoPath}`);
95
+ }
96
+
97
+ // src/worktrees.ts
98
+ function parsePorcelain(output) {
99
+ const worktrees = [];
100
+ const blocks = output.trim().split(/\n\n+/);
101
+ for (const block of blocks) {
102
+ if (!block.trim())
103
+ continue;
104
+ const lines = block.trim().split(`
105
+ `);
106
+ let path = "";
107
+ let head = "";
108
+ let branch = null;
109
+ let isBare = false;
110
+ for (const line of lines) {
111
+ if (line.startsWith("worktree ")) {
112
+ path = line.slice("worktree ".length);
113
+ } else if (line.startsWith("HEAD ")) {
114
+ head = line.slice("HEAD ".length);
115
+ } else if (line.startsWith("branch ")) {
116
+ const ref = line.slice("branch ".length);
117
+ branch = ref.startsWith("refs/heads/") ? ref.slice("refs/heads/".length) : ref;
118
+ } else if (line === "detached") {
119
+ branch = null;
120
+ } else if (line === "bare") {
121
+ isBare = true;
122
+ branch = null;
123
+ }
124
+ }
125
+ worktrees.push({ path, head, branch, isBare });
126
+ }
127
+ return worktrees;
128
+ }
129
+ async function listWorktrees(repoPath) {
130
+ const result = run2("git", ["-C", repoPath, "worktree", "list", "--porcelain"]);
131
+ return parsePorcelain(result.stdout);
132
+ }
133
+
134
+ // src/migrate.ts
135
+ import { mkdirSync, writeFileSync, readFileSync as readFileSync2, existsSync as existsSync2, renameSync, statSync as statSync2 } from "node:fs";
136
+ import { join as join2, dirname, basename, resolve as resolve2 } from "node:path";
137
+
138
+ // src/worktrees.ts
139
+ function parsePorcelain2(output) {
140
+ const worktrees = [];
141
+ const blocks = output.trim().split(/\n\n+/);
142
+ for (const block of blocks) {
143
+ if (!block.trim())
144
+ continue;
145
+ const lines = block.trim().split(`
146
+ `);
147
+ let path = "";
148
+ let head = "";
149
+ let branch = null;
150
+ let isBare = false;
151
+ for (const line of lines) {
152
+ if (line.startsWith("worktree ")) {
153
+ path = line.slice("worktree ".length);
154
+ } else if (line.startsWith("HEAD ")) {
155
+ head = line.slice("HEAD ".length);
156
+ } else if (line.startsWith("branch ")) {
157
+ const ref = line.slice("branch ".length);
158
+ branch = ref.startsWith("refs/heads/") ? ref.slice("refs/heads/".length) : ref;
159
+ } else if (line === "detached") {
160
+ branch = null;
161
+ } else if (line === "bare") {
162
+ isBare = true;
163
+ branch = null;
164
+ }
165
+ }
166
+ worktrees.push({ path, head, branch, isBare });
167
+ }
168
+ return worktrees;
169
+ }
170
+ async function listWorktrees2(repoPath) {
171
+ const result = run2("git", ["-C", repoPath, "worktree", "list", "--porcelain"]);
172
+ return parsePorcelain2(result.stdout);
173
+ }
174
+
175
+ // src/git.ts
176
+ async function git(args, options) {
177
+ const result = run2("git", args, {
178
+ cwd: options?.cwd,
179
+ env: options?.env ? { ...process.env, ...options.env } : undefined
180
+ });
181
+ return result.stdout;
182
+ }
183
+ async function setGitConfig(key, value, options) {
184
+ const env = {};
185
+ if (options?.gitdir)
186
+ env["GIT_DIR"] = options.gitdir;
187
+ await git(["config", key, value], { cwd: options?.cwd, env });
188
+ }
189
+
190
+ // src/migrate.ts
191
+ async function moveDir(src, dest) {
192
+ const destForStat = existsSync2(dest) ? dest : dirname(dest);
193
+ if (statSync2(src).dev === statSync2(destForStat).dev) {
194
+ renameSync(src, dest);
195
+ } else {
196
+ run2("cp", ["-a", src, dest]);
197
+ run2("rm", ["-rf", src]);
198
+ }
199
+ }
200
+ function sanitizeBranch(branch) {
201
+ return branch.replace(/\//g, "-");
202
+ }
203
+ async function migrate(config, options) {
204
+ const source = resolve2(options.source);
205
+ const dest = options.dest ? resolve2(options.dest) : join2(dirname(source), basename(source) + "-bare");
206
+ const destBare = join2(dest, ".bare");
207
+ if (existsSync2(destBare)) {
208
+ throw new Error(`'${destBare}' already exists`);
209
+ }
210
+ const allWorktrees = await listWorktrees2(source);
211
+ const worktrees = allWorktrees.filter((wt) => !wt.isBare);
212
+ const seen = new Map;
213
+ for (const wt of worktrees) {
214
+ const branch = wt.branch ?? `detached-${wt.head.slice(0, 8)}`;
215
+ const safe = sanitizeBranch(branch);
216
+ if (seen.has(safe)) {
217
+ throw new Error(`branch name collision: '${seen.get(safe)}' and '${branch}' both map to '${safe}'`);
218
+ }
219
+ seen.set(safe, branch);
220
+ }
221
+ mkdirSync(destBare, { recursive: true });
222
+ run2("cp", ["-a", config.gitdir + "/.", destBare + "/"]);
223
+ await setGitConfig("core.bare", "true", { gitdir: destBare });
224
+ await setGitConfig("remote.origin.fetch", "+refs/heads/*:refs/remotes/origin/*", { gitdir: destBare });
225
+ writeFileSync(join2(dest, ".git"), `gitdir: ./.bare
226
+ `);
227
+ if (config.type === "standard") {
228
+ const mainBranch = worktrees[0].branch;
229
+ const mainSafe = sanitizeBranch(mainBranch);
230
+ const mainDest = join2(dest, mainSafe);
231
+ const mainHeadContent = readFileSync2(join2(destBare, "HEAD"), "utf8");
232
+ run2("rm", ["-rf", join2(source, ".git")]);
233
+ await moveDir(source, mainDest);
234
+ const mainAdminDir = join2(destBare, "worktrees", mainSafe);
235
+ mkdirSync(mainAdminDir, { recursive: true });
236
+ writeFileSync(join2(mainAdminDir, "gitdir"), mainDest + `/.git
237
+ `);
238
+ writeFileSync(join2(mainAdminDir, "commondir"), `../../
239
+ `);
240
+ const headToWrite = mainHeadContent.endsWith(`
241
+ `) ? mainHeadContent : mainHeadContent + `
242
+ `;
243
+ writeFileSync(join2(mainAdminDir, "HEAD"), headToWrite);
244
+ const bareIndex = join2(destBare, "index");
245
+ if (existsSync2(bareIndex)) {
246
+ renameSync(bareIndex, join2(mainAdminDir, "index"));
247
+ }
248
+ writeFileSync(join2(mainDest, ".git"), `gitdir: ${mainAdminDir}
249
+ `);
250
+ for (let i = 1;i < worktrees.length; i++) {
251
+ await processLinkedWorktree(worktrees[i], dest, destBare);
252
+ }
253
+ } else {
254
+ for (const wt of worktrees) {
255
+ await processLinkedWorktree(wt, dest, destBare);
256
+ }
257
+ }
258
+ return dest;
259
+ }
260
+ async function processLinkedWorktree(wt, dest, destBare) {
261
+ const wtSrc = wt.path;
262
+ const wtBranch = wt.branch ?? `detached-${wt.head.slice(0, 8)}`;
263
+ const wtSafe = sanitizeBranch(wtBranch);
264
+ const wtDest = join2(dest, wtSafe);
265
+ await moveDir(wtSrc, wtDest);
266
+ const gitFileContent = readFileSync2(join2(wtDest, ".git"), "utf8");
267
+ const match = gitFileContent.match(/^gitdir:\s*(.+)/m);
268
+ if (!match) {
269
+ console.warn(`Could not parse .git file in ${wtDest}`);
270
+ return;
271
+ }
272
+ const oldPath = match[1].trim();
273
+ const adminName = basename(oldPath);
274
+ const newAdmin = join2(destBare, "worktrees", adminName);
275
+ writeFileSync(join2(wtDest, ".git"), `gitdir: ${newAdmin}
276
+ `);
277
+ if (existsSync2(newAdmin)) {
278
+ writeFileSync(join2(newAdmin, "gitdir"), wtDest + `/.git
279
+ `);
280
+ } else {
281
+ console.warn(`Admin dir ${newAdmin} does not exist for worktree ${wtDest}`);
282
+ }
283
+ }
284
+
285
+ // src/cli.ts
286
+ var GREEN = "\x1B[32m";
287
+ var YELLOW = "\x1B[33m";
288
+ var BOLD = "\x1B[1m";
289
+ var RESET = "\x1B[0m";
290
+ function green(s) {
291
+ return `${GREEN}${s}${RESET}`;
292
+ }
293
+ function yellow(s) {
294
+ return `${YELLOW}${s}${RESET}`;
295
+ }
296
+ function bold(s) {
297
+ return `${BOLD}${s}${RESET}`;
298
+ }
299
+ function usage() {
300
+ console.log(`Usage: git-worktree-organize <source> [destination]
301
+
302
+ Convert a git repository into the canonical bare-hub worktree layout:
303
+
304
+ <dest>/.bare/ \u2190 bare git repo
305
+ <dest>/.git \u2190 plain file: "gitdir: ./.bare"
306
+ <dest>/<branch>/ \u2190 one directory per worktree
307
+
308
+ Arguments:
309
+ source Path to existing git repository
310
+ destination Target hub directory (default: <parent>/<name>-bare)
311
+
312
+ Options:
313
+ -h, --help Show help`);
314
+ }
315
+ async function main() {
316
+ const args = process.argv.slice(2);
317
+ if (args.length === 0 || args[0] === "-h" || args[0] === "--help") {
318
+ usage();
319
+ process.exit(0);
320
+ }
321
+ const sourcePath = args[0];
322
+ const destArg = args[1];
323
+ const source = resolve3(sourcePath);
324
+ const dest = destArg ? resolve3(destArg) : join3(dirname2(source), basename2(source) + "-bare");
325
+ console.log(`
326
+ ${green("==>")} Reading worktrees from ${source}
327
+ `);
328
+ const config = await detect(source);
329
+ const allWorktrees = await listWorktrees(source);
330
+ const worktrees = allWorktrees.filter((wt) => !wt.isBare);
331
+ let mainBranch = null;
332
+ if (config.type === "standard" && worktrees.length > 0) {
333
+ mainBranch = worktrees[0].branch;
334
+ }
335
+ console.log("Worktrees to migrate:");
336
+ const entries = worktrees.map((wt) => {
337
+ const branch = wt.branch ?? `detached-${wt.head.slice(0, 8)}`;
338
+ const safe = sanitizeBranch(branch);
339
+ const isMain = branch === mainBranch;
340
+ const destDir = join3(dest, safe);
341
+ return { branch, isMain, destDir };
342
+ });
343
+ const maxNameLen = entries.reduce((m, e) => Math.max(m, e.branch.length), 0);
344
+ for (const { branch, isMain, destDir } of entries) {
345
+ const tag = isMain ? yellow("[main]") : "";
346
+ const tagPad = isMain ? ` (labeled ${yellow("[main]")})` : "";
347
+ const nameCol = bold(`[${branch}]`).padEnd(maxNameLen + 2 + BOLD.length + RESET.length);
348
+ const annotation = isMain ? ` (labeled ${yellow("[main]")})`.padEnd(18 + YELLOW.length + RESET.length) : "".padEnd(18);
349
+ console.log(` ${nameCol}${annotation} \u2192 ${destDir}`);
350
+ }
351
+ console.log();
352
+ console.log(`Hub destination: ${bold(dest)} (bare repo at ${dest}/.bare)`);
353
+ console.log();
354
+ process.stdout.write("Proceed? [y/N] ");
355
+ const ans = await new Promise((resolve4) => {
356
+ process.stdin.setEncoding("utf8");
357
+ process.stdin.once("data", (chunk) => resolve4(chunk.toString().trim()));
358
+ });
359
+ process.stdin.destroy();
360
+ if (!/^[Yy]$/.test(ans)) {
361
+ console.log("Aborted.");
362
+ process.exit(0);
363
+ }
364
+ console.log();
365
+ const hubPath = await migrate(config, { source: sourcePath, dest: destArg ?? "" });
366
+ console.log(`${green("==>")} Verifying with git worktree list...`);
367
+ const verifyOutput = run("git", ["-C", hubPath, "worktree", "list"]).stdout;
368
+ console.log(verifyOutput);
369
+ console.log(`Done! Hub: ${hubPath}`);
370
+ console.log();
371
+ const mainSafe = mainBranch ? sanitizeBranch(mainBranch) : entries[0]?.branch ? sanitizeBranch(entries[0].branch) : "";
372
+ console.log("Useful commands:");
373
+ console.log(` git -C ${hubPath} worktree list`);
374
+ if (mainSafe) {
375
+ console.log(` git -C ${hubPath}/${mainSafe} log --oneline -5`);
376
+ }
377
+ }
378
+ main().catch((err) => {
379
+ process.stderr.write(`error: ${err.message}
380
+ `);
381
+ process.exit(1);
382
+ });
package/package.json CHANGED
@@ -1,16 +1,20 @@
1
1
  {
2
2
  "name": "git-worktree-organize",
3
- "version": "1.0.8",
3
+ "version": "1.0.10",
4
4
  "description": "Convert any git repo into the canonical bare-hub worktree layout",
5
5
  "type": "module",
6
6
  "bin": {
7
- "git-worktree-organize": "./src/cli.ts"
7
+ "git-worktree-organize": "./dist/cli.js"
8
8
  },
9
+ "files": [
10
+ "dist/"
11
+ ],
9
12
  "scripts": {
10
13
  "build": "bun build src/cli.ts --outfile dist/cli.js --target node",
14
+ "prepublishOnly": "bun run build",
11
15
  "test": "bun test",
12
16
  "test:watch": "vitest",
13
- "publish": "op run -- npm publish"
17
+ "release": "op run -- npm publish"
14
18
  },
15
19
  "devDependencies": {
16
20
  "@types/bun": "latest",
package/.beads/README.md DELETED
@@ -1,81 +0,0 @@
1
- # Beads - AI-Native Issue Tracking
2
-
3
- Welcome to Beads! This repository uses **Beads** for issue tracking - a modern, AI-native tool designed to live directly in your codebase alongside your code.
4
-
5
- ## What is Beads?
6
-
7
- Beads is issue tracking that lives in your repo, making it perfect for AI coding agents and developers who want their issues close to their code. No web UI required - everything works through the CLI and integrates seamlessly with git.
8
-
9
- **Learn more:** [github.com/steveyegge/beads](https://github.com/steveyegge/beads)
10
-
11
- ## Quick Start
12
-
13
- ### Essential Commands
14
-
15
- ```bash
16
- # Create new issues
17
- bd create "Add user authentication"
18
-
19
- # View all issues
20
- bd list
21
-
22
- # View issue details
23
- bd show <issue-id>
24
-
25
- # Update issue status
26
- bd update <issue-id> --claim
27
- bd update <issue-id> --status done
28
-
29
- # Sync with Dolt remote
30
- bd dolt push
31
- ```
32
-
33
- ### Working with Issues
34
-
35
- Issues in Beads are:
36
- - **Git-native**: Stored in `.beads/issues.jsonl` and synced like code
37
- - **AI-friendly**: CLI-first design works perfectly with AI coding agents
38
- - **Branch-aware**: Issues can follow your branch workflow
39
- - **Always in sync**: Auto-syncs with your commits
40
-
41
- ## Why Beads?
42
-
43
- ✨ **AI-Native Design**
44
- - Built specifically for AI-assisted development workflows
45
- - CLI-first interface works seamlessly with AI coding agents
46
- - No context switching to web UIs
47
-
48
- 🚀 **Developer Focused**
49
- - Issues live in your repo, right next to your code
50
- - Works offline, syncs when you push
51
- - Fast, lightweight, and stays out of your way
52
-
53
- 🔧 **Git Integration**
54
- - Automatic sync with git commits
55
- - Branch-aware issue tracking
56
- - Intelligent JSONL merge resolution
57
-
58
- ## Get Started with Beads
59
-
60
- Try Beads in your own projects:
61
-
62
- ```bash
63
- # Install Beads
64
- curl -sSL https://raw.githubusercontent.com/steveyegge/beads/main/scripts/install.sh | bash
65
-
66
- # Initialize in your repo
67
- bd init
68
-
69
- # Create your first issue
70
- bd create "Try out Beads"
71
- ```
72
-
73
- ## Learn More
74
-
75
- - **Documentation**: [github.com/steveyegge/beads/docs](https://github.com/steveyegge/beads/tree/main/docs)
76
- - **Quick Start Guide**: Run `bd quickstart`
77
- - **Examples**: [github.com/steveyegge/beads/examples](https://github.com/steveyegge/beads/tree/main/examples)
78
-
79
- ---
80
-
81
- *Beads: Issue tracking that moves at the speed of thought* ⚡
@@ -1,13 +0,0 @@
1
- {
2
- "last_dolt_commit": "l1dnbhthsfgi9v89teho6b2efhklvlv0",
3
- "last_event_id": 0,
4
- "timestamp": "2026-03-06T13:05:38.518606871Z",
5
- "counts": {
6
- "issues": 9,
7
- "events": 31,
8
- "comments": 0,
9
- "dependencies": 10,
10
- "labels": 0,
11
- "config": 11
12
- }
13
- }
File without changes
@@ -1,11 +0,0 @@
1
- {"key":"auto_compact_enabled","value":"false"}
2
- {"key":"compact_batch_size","value":"50"}
3
- {"key":"compact_parallel_workers","value":"5"}
4
- {"key":"compact_tier1_days","value":"30"}
5
- {"key":"compact_tier1_dep_levels","value":"2"}
6
- {"key":"compact_tier2_commits","value":"100"}
7
- {"key":"compact_tier2_days","value":"90"}
8
- {"key":"compact_tier2_dep_levels","value":"5"}
9
- {"key":"compaction_enabled","value":"false"}
10
- {"key":"issue_prefix","value":"git-worktree-organize"}
11
- {"key":"schema_version","value":"6"}
@@ -1,10 +0,0 @@
1
- {"created_at":"2026-03-05T23:28:12Z","created_by":"Mike Crowe","depends_on_id":"git-worktree-organize-pa7","issue_id":"git-worktree-organize-3h1","type":"blocks"}
2
- {"created_at":"2026-03-05T23:28:12Z","created_by":"Mike Crowe","depends_on_id":"git-worktree-organize-3h1","issue_id":"git-worktree-organize-53n","type":"blocks"}
3
- {"created_at":"2026-03-05T23:28:12Z","created_by":"Mike Crowe","depends_on_id":"git-worktree-organize-jnu","issue_id":"git-worktree-organize-5ea","type":"blocks"}
4
- {"created_at":"2026-03-05T23:28:12Z","created_by":"Mike Crowe","depends_on_id":"git-worktree-organize-q2e","issue_id":"git-worktree-organize-5ea","type":"blocks"}
5
- {"created_at":"2026-03-05T23:28:12Z","created_by":"Mike Crowe","depends_on_id":"git-worktree-organize-t83","issue_id":"git-worktree-organize-5ea","type":"blocks"}
6
- {"created_at":"2026-03-05T23:28:12Z","created_by":"Mike Crowe","depends_on_id":"git-worktree-organize-3yq","issue_id":"git-worktree-organize-7sk","type":"blocks"}
7
- {"created_at":"2026-03-05T23:28:12Z","created_by":"Mike Crowe","depends_on_id":"git-worktree-organize-7sk","issue_id":"git-worktree-organize-jnu","type":"blocks"}
8
- {"created_at":"2026-03-05T23:28:12Z","created_by":"Mike Crowe","depends_on_id":"git-worktree-organize-5ea","issue_id":"git-worktree-organize-pa7","type":"blocks"}
9
- {"created_at":"2026-03-05T23:28:12Z","created_by":"Mike Crowe","depends_on_id":"git-worktree-organize-7sk","issue_id":"git-worktree-organize-q2e","type":"blocks"}
10
- {"created_at":"2026-03-05T23:28:12Z","created_by":"Mike Crowe","depends_on_id":"git-worktree-organize-7sk","issue_id":"git-worktree-organize-t83","type":"blocks"}
@@ -1,31 +0,0 @@
1
- {"actor":"Mike Crowe","comment":null,"created_at":"2026-03-05T23:27:46Z","event_type":"created","id":1,"issue_id":"git-worktree-organize-3yq","new_value":"","old_value":""}
2
- {"actor":"Mike Crowe","comment":null,"created_at":"2026-03-05T23:27:46Z","event_type":"created","id":2,"issue_id":"git-worktree-organize-7sk","new_value":"","old_value":""}
3
- {"actor":"Mike Crowe","comment":null,"created_at":"2026-03-05T23:27:54Z","event_type":"created","id":3,"issue_id":"git-worktree-organize-t83","new_value":"","old_value":""}
4
- {"actor":"Mike Crowe","comment":null,"created_at":"2026-03-05T23:27:54Z","event_type":"created","id":4,"issue_id":"git-worktree-organize-q2e","new_value":"","old_value":""}
5
- {"actor":"Mike Crowe","comment":null,"created_at":"2026-03-05T23:27:54Z","event_type":"created","id":5,"issue_id":"git-worktree-organize-jnu","new_value":"","old_value":""}
6
- {"actor":"Mike Crowe","comment":null,"created_at":"2026-03-05T23:28:02Z","event_type":"created","id":6,"issue_id":"git-worktree-organize-3h1","new_value":"","old_value":""}
7
- {"actor":"Mike Crowe","comment":null,"created_at":"2026-03-05T23:28:02Z","event_type":"created","id":7,"issue_id":"git-worktree-organize-5ea","new_value":"","old_value":""}
8
- {"actor":"Mike Crowe","comment":null,"created_at":"2026-03-05T23:28:02Z","event_type":"created","id":8,"issue_id":"git-worktree-organize-pa7","new_value":"","old_value":""}
9
- {"actor":"Mike Crowe","comment":null,"created_at":"2026-03-05T23:28:02Z","event_type":"created","id":9,"issue_id":"git-worktree-organize-53n","new_value":"","old_value":""}
10
- {"actor":"Mike Crowe","comment":null,"created_at":"2026-03-06T06:17:41Z","event_type":"closed","id":10,"issue_id":"git-worktree-organize-53n","new_value":"Removed — not tracking npm publish as a task","old_value":""}
11
- {"actor":"Mike Crowe","comment":null,"created_at":"2026-03-06T06:24:30Z","event_type":"status_changed","id":11,"issue_id":"git-worktree-organize-3yq","new_value":"{\"status\":\"in_progress\"}","old_value":"{\"id\":\"git-worktree-organize-3yq\",\"title\":\"Set up package.json for Bun + TypeScript + Vitest\",\"description\":\"Configure package.json with correct bin entry, scripts (build, test), deps (typescript, vitest, @types/bun), tsconfig.json. Stack: Bun runtime, TypeScript, Vitest.\",\"status\":\"open\",\"priority\":0,\"issue_type\":\"task\",\"owner\":\"drmikecrowe@gmail.com\",\"created_at\":\"2026-03-06T04:27:47Z\",\"created_by\":\"Mike Crowe\",\"updated_at\":\"2026-03-06T04:27:47Z\"}"}
12
- {"actor":"Mike Crowe","comment":null,"created_at":"2026-03-06T06:25:33Z","event_type":"closed","id":12,"issue_id":"git-worktree-organize-3yq","new_value":"Closed","old_value":""}
13
- {"actor":"Mike Crowe","comment":null,"created_at":"2026-03-06T06:25:33Z","event_type":"status_changed","id":13,"issue_id":"git-worktree-organize-7sk","new_value":"{\"status\":\"in_progress\"}","old_value":"{\"id\":\"git-worktree-organize-7sk\",\"title\":\"Scaffold source files with types and stubs\",\"description\":\"Create src/cli.ts, src/detect.ts, src/worktrees.ts, src/migrate.ts, src/git.ts, src/fs.ts with the types from AGENT_HANDOVER.md (RepoConfig, Worktree) and stub implementations.\",\"status\":\"open\",\"priority\":0,\"issue_type\":\"task\",\"owner\":\"drmikecrowe@gmail.com\",\"created_at\":\"2026-03-06T04:27:47Z\",\"created_by\":\"Mike Crowe\",\"updated_at\":\"2026-03-06T04:27:47Z\"}"}
14
- {"actor":"Mike Crowe","comment":null,"created_at":"2026-03-06T06:26:35Z","event_type":"closed","id":14,"issue_id":"git-worktree-organize-7sk","new_value":"Closed","old_value":""}
15
- {"actor":"Mike Crowe","comment":null,"created_at":"2026-03-06T06:26:38Z","event_type":"status_changed","id":15,"issue_id":"git-worktree-organize-jnu","new_value":"{\"status\":\"in_progress\"}","old_value":"{\"id\":\"git-worktree-organize-jnu\",\"title\":\"Implement git.ts and fs.ts thin wrappers\",\"description\":\"git.ts: run git commands, read git config. fs.ts: move/copy with cross-filesystem detection via statSync().dev. These are the only modules that touch the real system.\",\"status\":\"open\",\"priority\":1,\"issue_type\":\"feature\",\"owner\":\"drmikecrowe@gmail.com\",\"created_at\":\"2026-03-06T04:27:55Z\",\"created_by\":\"Mike Crowe\",\"updated_at\":\"2026-03-06T04:27:55Z\"}"}
16
- {"actor":"Mike Crowe","comment":null,"created_at":"2026-03-06T06:26:39Z","event_type":"status_changed","id":16,"issue_id":"git-worktree-organize-q2e","new_value":"{\"status\":\"in_progress\"}","old_value":"{\"id\":\"git-worktree-organize-q2e\",\"title\":\"Implement worktrees.ts + tests\",\"description\":\"Parse git worktree list --porcelain output into typed Worktree[]. Handle bare, linked, detached HEAD cases. Tests in test/worktrees.test.ts.\",\"status\":\"open\",\"priority\":1,\"issue_type\":\"feature\",\"owner\":\"drmikecrowe@gmail.com\",\"created_at\":\"2026-03-06T04:27:55Z\",\"created_by\":\"Mike Crowe\",\"updated_at\":\"2026-03-06T04:27:55Z\"}"}
17
- {"actor":"Mike Crowe","comment":null,"created_at":"2026-03-06T06:26:39Z","event_type":"status_changed","id":17,"issue_id":"git-worktree-organize-t83","new_value":"{\"status\":\"in_progress\"}","old_value":"{\"id\":\"git-worktree-organize-t83\",\"title\":\"Implement detect.ts + full test suite\",\"description\":\"Implement all 7 detection cases from the detection matrix: standard, bare-hub, bare-root, bare-dotgit, bare-external, reject-linked-worktree, reject-not-a-repo. Tests in test/detect.test.ts using real git repos in tmpdir.\",\"status\":\"open\",\"priority\":1,\"issue_type\":\"feature\",\"owner\":\"drmikecrowe@gmail.com\",\"created_at\":\"2026-03-06T04:27:55Z\",\"created_by\":\"Mike Crowe\",\"updated_at\":\"2026-03-06T04:27:55Z\"}"}
18
- {"actor":"Mike Crowe","comment":null,"created_at":"2026-03-06T06:27:31Z","event_type":"closed","id":18,"issue_id":"git-worktree-organize-jnu","new_value":"Closed","old_value":""}
19
- {"actor":"Mike Crowe","comment":null,"created_at":"2026-03-06T06:29:41Z","event_type":"closed","id":19,"issue_id":"git-worktree-organize-q2e","new_value":"Closed","old_value":""}
20
- {"actor":"Mike Crowe","comment":null,"created_at":"2026-03-06T06:30:04Z","event_type":"closed","id":20,"issue_id":"git-worktree-organize-t83","new_value":"Closed","old_value":""}
21
- {"actor":"Mike Crowe","comment":null,"created_at":"2026-03-06T06:30:25Z","event_type":"closed","id":21,"issue_id":"git-worktree-organize-jnu","new_value":"Closed","old_value":""}
22
- {"actor":"Mike Crowe","comment":null,"created_at":"2026-03-06T06:30:26Z","event_type":"closed","id":22,"issue_id":"git-worktree-organize-q2e","new_value":"Closed","old_value":""}
23
- {"actor":"Mike Crowe","comment":null,"created_at":"2026-03-06T06:30:26Z","event_type":"closed","id":23,"issue_id":"git-worktree-organize-t83","new_value":"Closed","old_value":""}
24
- {"actor":"Mike Crowe","comment":null,"created_at":"2026-03-06T06:32:04Z","event_type":"status_changed","id":24,"issue_id":"git-worktree-organize-5ea","new_value":"{\"status\":\"in_progress\"}","old_value":"{\"id\":\"git-worktree-organize-5ea\",\"title\":\"Implement migrate.ts + full test suite\",\"description\":\"Orchestrate the full migration for all repo config types. Tests: standard→hub, bare-root→hub, bare-hub→new location, no worktrees→hub, cross-filesystem, branch with / sanitized to -, collision detection.\",\"status\":\"open\",\"priority\":2,\"issue_type\":\"feature\",\"owner\":\"drmikecrowe@gmail.com\",\"created_at\":\"2026-03-06T04:28:03Z\",\"created_by\":\"Mike Crowe\",\"updated_at\":\"2026-03-06T04:28:03Z\"}"}
25
- {"actor":"Mike Crowe","comment":null,"created_at":"2026-03-06T06:35:54Z","event_type":"closed","id":25,"issue_id":"git-worktree-organize-5ea","new_value":"Closed","old_value":""}
26
- {"actor":"Mike Crowe","comment":null,"created_at":"2026-03-06T06:36:16Z","event_type":"closed","id":26,"issue_id":"git-worktree-organize-5ea","new_value":"Closed","old_value":""}
27
- {"actor":"Mike Crowe","comment":null,"created_at":"2026-03-06T06:36:25Z","event_type":"status_changed","id":27,"issue_id":"git-worktree-organize-pa7","new_value":"{\"status\":\"in_progress\"}","old_value":"{\"id\":\"git-worktree-organize-pa7\",\"title\":\"Implement cli.ts entry point\",\"description\":\"Arg parsing (citty or yargs), interactive confirmation prompt, formatted output matching bash prototype (colors, worktree preview table, done message). Wire up npx binary entry.\",\"status\":\"open\",\"priority\":2,\"issue_type\":\"feature\",\"owner\":\"drmikecrowe@gmail.com\",\"created_at\":\"2026-03-06T04:28:03Z\",\"created_by\":\"Mike Crowe\",\"updated_at\":\"2026-03-06T04:28:03Z\"}"}
28
- {"actor":"Mike Crowe","comment":null,"created_at":"2026-03-06T06:37:52Z","event_type":"closed","id":28,"issue_id":"git-worktree-organize-pa7","new_value":"Closed","old_value":""}
29
- {"actor":"Mike Crowe","comment":null,"created_at":"2026-03-06T06:38:11Z","event_type":"closed","id":29,"issue_id":"git-worktree-organize-pa7","new_value":"Closed","old_value":""}
30
- {"actor":"Mike Crowe","comment":null,"created_at":"2026-03-06T06:38:11Z","event_type":"status_changed","id":30,"issue_id":"git-worktree-organize-3h1","new_value":"{\"status\":\"in_progress\"}","old_value":"{\"id\":\"git-worktree-organize-3h1\",\"title\":\"Write README\",\"description\":\"Document usage, installation methods (npx, direct install), what the tool does, before/after directory structure examples.\",\"status\":\"open\",\"priority\":3,\"issue_type\":\"task\",\"owner\":\"drmikecrowe@gmail.com\",\"created_at\":\"2026-03-06T04:28:03Z\",\"created_by\":\"Mike Crowe\",\"updated_at\":\"2026-03-06T04:28:03Z\"}"}
31
- {"actor":"Mike Crowe","comment":null,"created_at":"2026-03-06T06:39:00Z","event_type":"closed","id":31,"issue_id":"git-worktree-organize-3h1","new_value":"Closed","old_value":""}
@@ -1,9 +0,0 @@
1
- {"acceptance_criteria":"","actor":"","agent_state":"","assignee":null,"await_id":"","await_type":"","close_reason":"Closed","closed_at":"2026-03-06T11:39:01Z","closed_by_session":"","compacted_at":null,"compacted_at_commit":null,"compaction_level":0,"content_hash":"561f6b5866ebbb03db36aa8f14a46eb580c05a0691c30814cefe8d90133a6dfc","created_at":"2026-03-06T04:28:03Z","created_by":"Mike Crowe","crystallizes":0,"defer_until":null,"description":"Document usage, installation methods (npx, direct install), what the tool does, before/after directory structure examples.","design":"","due_at":null,"ephemeral":0,"estimated_minutes":null,"event_kind":"","external_ref":null,"hook_bead":"","id":"git-worktree-organize-3h1","is_template":0,"issue_type":"task","last_activity":null,"metadata":"{}","mol_type":"","notes":"","original_size":null,"owner":"drmikecrowe@gmail.com","payload":"","pinned":0,"priority":3,"quality_score":null,"rig":"","role_bead":"","role_type":"","sender":"","source_repo":"","source_system":"","spec_id":"","status":"closed","target":"","timeout_ns":0,"title":"Write README","updated_at":"2026-03-06T11:39:01Z","waiters":"","wisp_type":"","work_type":""}
2
- {"acceptance_criteria":"","actor":"","agent_state":"","assignee":null,"await_id":"","await_type":"","close_reason":"Closed","closed_at":"2026-03-06T11:25:33Z","closed_by_session":"","compacted_at":null,"compacted_at_commit":null,"compaction_level":0,"content_hash":"fb0acfcdb0465d4f5b9dc129ddeb6d91efd79069adc8d86ad1acb4e207809b4a","created_at":"2026-03-06T04:27:47Z","created_by":"Mike Crowe","crystallizes":0,"defer_until":null,"description":"Configure package.json with correct bin entry, scripts (build, test), deps (typescript, vitest, @types/bun), tsconfig.json. Stack: Bun runtime, TypeScript, Vitest.","design":"","due_at":null,"ephemeral":0,"estimated_minutes":null,"event_kind":"","external_ref":null,"hook_bead":"","id":"git-worktree-organize-3yq","is_template":0,"issue_type":"task","last_activity":null,"metadata":"{}","mol_type":"","notes":"","original_size":null,"owner":"drmikecrowe@gmail.com","payload":"","pinned":0,"priority":0,"quality_score":null,"rig":"","role_bead":"","role_type":"","sender":"","source_repo":"","source_system":"","spec_id":"","status":"closed","target":"","timeout_ns":0,"title":"Set up package.json for Bun + TypeScript + Vitest","updated_at":"2026-03-06T11:25:33Z","waiters":"","wisp_type":"","work_type":""}
3
- {"acceptance_criteria":"","actor":"","agent_state":"","assignee":null,"await_id":"","await_type":"","close_reason":"Removed — not tracking npm publish as a task","closed_at":"2026-03-06T11:17:42Z","closed_by_session":"","compacted_at":null,"compacted_at_commit":null,"compaction_level":0,"content_hash":"dd2362b7ac9b221851317c89933365a9244782bf7e243b487f0f58cbfcc3731e","created_at":"2026-03-06T04:28:03Z","created_by":"Mike Crowe","crystallizes":0,"defer_until":null,"description":"Verify npx git-worktree-organize works locally, then publish package to npm registry.","design":"","due_at":null,"ephemeral":0,"estimated_minutes":null,"event_kind":"","external_ref":null,"hook_bead":"","id":"git-worktree-organize-53n","is_template":0,"issue_type":"task","last_activity":null,"metadata":"{}","mol_type":"","notes":"","original_size":null,"owner":"drmikecrowe@gmail.com","payload":"","pinned":0,"priority":4,"quality_score":null,"rig":"","role_bead":"","role_type":"","sender":"","source_repo":"","source_system":"","spec_id":"","status":"closed","target":"","timeout_ns":0,"title":"Publish to npm","updated_at":"2026-03-06T11:17:42Z","waiters":"","wisp_type":"","work_type":""}
4
- {"acceptance_criteria":"","actor":"","agent_state":"","assignee":null,"await_id":"","await_type":"","close_reason":"Closed","closed_at":"2026-03-06T11:36:16Z","closed_by_session":"","compacted_at":null,"compacted_at_commit":null,"compaction_level":0,"content_hash":"ee988a5cd9bba616c11f15991543ca2991525f0ccf7a42570e78f6d58305eb1d","created_at":"2026-03-06T04:28:03Z","created_by":"Mike Crowe","crystallizes":0,"defer_until":null,"description":"Orchestrate the full migration for all repo config types. Tests: standard→hub, bare-root→hub, bare-hub→new location, no worktrees→hub, cross-filesystem, branch with / sanitized to -, collision detection.","design":"","due_at":null,"ephemeral":0,"estimated_minutes":null,"event_kind":"","external_ref":null,"hook_bead":"","id":"git-worktree-organize-5ea","is_template":0,"issue_type":"feature","last_activity":null,"metadata":"{}","mol_type":"","notes":"","original_size":null,"owner":"drmikecrowe@gmail.com","payload":"","pinned":0,"priority":2,"quality_score":null,"rig":"","role_bead":"","role_type":"","sender":"","source_repo":"","source_system":"","spec_id":"","status":"closed","target":"","timeout_ns":0,"title":"Implement migrate.ts + full test suite","updated_at":"2026-03-06T11:36:16Z","waiters":"","wisp_type":"","work_type":""}
5
- {"acceptance_criteria":"","actor":"","agent_state":"","assignee":null,"await_id":"","await_type":"","close_reason":"Closed","closed_at":"2026-03-06T11:26:36Z","closed_by_session":"","compacted_at":null,"compacted_at_commit":null,"compaction_level":0,"content_hash":"7aabd95b4fd55f537a1de1d736dcf6dfbc2bdb4606022497d617bd4327f0d176","created_at":"2026-03-06T04:27:47Z","created_by":"Mike Crowe","crystallizes":0,"defer_until":null,"description":"Create src/cli.ts, src/detect.ts, src/worktrees.ts, src/migrate.ts, src/git.ts, src/fs.ts with the types from AGENT_HANDOVER.md (RepoConfig, Worktree) and stub implementations.","design":"","due_at":null,"ephemeral":0,"estimated_minutes":null,"event_kind":"","external_ref":null,"hook_bead":"","id":"git-worktree-organize-7sk","is_template":0,"issue_type":"task","last_activity":null,"metadata":"{}","mol_type":"","notes":"","original_size":null,"owner":"drmikecrowe@gmail.com","payload":"","pinned":0,"priority":0,"quality_score":null,"rig":"","role_bead":"","role_type":"","sender":"","source_repo":"","source_system":"","spec_id":"","status":"closed","target":"","timeout_ns":0,"title":"Scaffold source files with types and stubs","updated_at":"2026-03-06T11:26:36Z","waiters":"","wisp_type":"","work_type":""}
6
- {"acceptance_criteria":"","actor":"","agent_state":"","assignee":null,"await_id":"","await_type":"","close_reason":"Closed","closed_at":"2026-03-06T11:30:26Z","closed_by_session":"","compacted_at":null,"compacted_at_commit":null,"compaction_level":0,"content_hash":"0a01642f655d9349862290f82014254401d6614d5160b5763253fd6738775dea","created_at":"2026-03-06T04:27:55Z","created_by":"Mike Crowe","crystallizes":0,"defer_until":null,"description":"git.ts: run git commands, read git config. fs.ts: move/copy with cross-filesystem detection via statSync().dev. These are the only modules that touch the real system.","design":"","due_at":null,"ephemeral":0,"estimated_minutes":null,"event_kind":"","external_ref":null,"hook_bead":"","id":"git-worktree-organize-jnu","is_template":0,"issue_type":"feature","last_activity":null,"metadata":"{}","mol_type":"","notes":"","original_size":null,"owner":"drmikecrowe@gmail.com","payload":"","pinned":0,"priority":1,"quality_score":null,"rig":"","role_bead":"","role_type":"","sender":"","source_repo":"","source_system":"","spec_id":"","status":"closed","target":"","timeout_ns":0,"title":"Implement git.ts and fs.ts thin wrappers","updated_at":"2026-03-06T11:30:26Z","waiters":"","wisp_type":"","work_type":""}
7
- {"acceptance_criteria":"","actor":"","agent_state":"","assignee":null,"await_id":"","await_type":"","close_reason":"Closed","closed_at":"2026-03-06T11:38:11Z","closed_by_session":"","compacted_at":null,"compacted_at_commit":null,"compaction_level":0,"content_hash":"aac42923f4098c6b3b314b1c10374e205085707e0dd4df714a3e0fc2868ce2ba","created_at":"2026-03-06T04:28:03Z","created_by":"Mike Crowe","crystallizes":0,"defer_until":null,"description":"Arg parsing (citty or yargs), interactive confirmation prompt, formatted output matching bash prototype (colors, worktree preview table, done message). Wire up npx binary entry.","design":"","due_at":null,"ephemeral":0,"estimated_minutes":null,"event_kind":"","external_ref":null,"hook_bead":"","id":"git-worktree-organize-pa7","is_template":0,"issue_type":"feature","last_activity":null,"metadata":"{}","mol_type":"","notes":"","original_size":null,"owner":"drmikecrowe@gmail.com","payload":"","pinned":0,"priority":2,"quality_score":null,"rig":"","role_bead":"","role_type":"","sender":"","source_repo":"","source_system":"","spec_id":"","status":"closed","target":"","timeout_ns":0,"title":"Implement cli.ts entry point","updated_at":"2026-03-06T11:38:11Z","waiters":"","wisp_type":"","work_type":""}
8
- {"acceptance_criteria":"","actor":"","agent_state":"","assignee":null,"await_id":"","await_type":"","close_reason":"Closed","closed_at":"2026-03-06T11:30:26Z","closed_by_session":"","compacted_at":null,"compacted_at_commit":null,"compaction_level":0,"content_hash":"74d94c1a48786197343e664f31b426b3105f9142e00f2bc70a923ca4d12adadb","created_at":"2026-03-06T04:27:55Z","created_by":"Mike Crowe","crystallizes":0,"defer_until":null,"description":"Parse git worktree list --porcelain output into typed Worktree[]. Handle bare, linked, detached HEAD cases. Tests in test/worktrees.test.ts.","design":"","due_at":null,"ephemeral":0,"estimated_minutes":null,"event_kind":"","external_ref":null,"hook_bead":"","id":"git-worktree-organize-q2e","is_template":0,"issue_type":"feature","last_activity":null,"metadata":"{}","mol_type":"","notes":"","original_size":null,"owner":"drmikecrowe@gmail.com","payload":"","pinned":0,"priority":1,"quality_score":null,"rig":"","role_bead":"","role_type":"","sender":"","source_repo":"","source_system":"","spec_id":"","status":"closed","target":"","timeout_ns":0,"title":"Implement worktrees.ts + tests","updated_at":"2026-03-06T11:30:26Z","waiters":"","wisp_type":"","work_type":""}
9
- {"acceptance_criteria":"","actor":"","agent_state":"","assignee":null,"await_id":"","await_type":"","close_reason":"Closed","closed_at":"2026-03-06T11:30:26Z","closed_by_session":"","compacted_at":null,"compacted_at_commit":null,"compaction_level":0,"content_hash":"e1c9d043c99e2fbecc16f2c9e7ceae6d43600a5ab07c7dea9a53e8dc082552f6","created_at":"2026-03-06T04:27:55Z","created_by":"Mike Crowe","crystallizes":0,"defer_until":null,"description":"Implement all 7 detection cases from the detection matrix: standard, bare-hub, bare-root, bare-dotgit, bare-external, reject-linked-worktree, reject-not-a-repo. Tests in test/detect.test.ts using real git repos in tmpdir.","design":"","due_at":null,"ephemeral":0,"estimated_minutes":null,"event_kind":"","external_ref":null,"hook_bead":"","id":"git-worktree-organize-t83","is_template":0,"issue_type":"feature","last_activity":null,"metadata":"{}","mol_type":"","notes":"","original_size":null,"owner":"drmikecrowe@gmail.com","payload":"","pinned":0,"priority":1,"quality_score":null,"rig":"","role_bead":"","role_type":"","sender":"","source_repo":"","source_system":"","spec_id":"","status":"closed","target":"","timeout_ns":0,"title":"Implement detect.ts + full test suite","updated_at":"2026-03-06T11:30:26Z","waiters":"","wisp_type":"","work_type":""}
File without changes