worktree-bay 2.1.0 → 2.1.1

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 CHANGED
@@ -119,8 +119,13 @@ catch (e) {
119
119
  program.command('version').description('显示版本号').action(() => log(pkg.version));
120
120
  program.command('__complete', { hidden: true }).allowUnknownOption().action(() => {
121
121
  const words = process.argv.slice(process.argv.indexOf('--') + 1);
122
+ let cfg = null;
122
123
  try {
123
- console.log(complete(loadConfig(process.cwd()), words).join('\n'));
124
+ cfg = loadConfig(process.cwd());
125
+ }
126
+ catch { /* 无配置:仍补全子命令,只是补不了 feature/service */ }
127
+ try {
128
+ console.log(complete(cfg, words).join('\n'));
124
129
  }
125
130
  catch { /* 静默 */ }
126
131
  });
@@ -9,6 +9,8 @@ export function complete(cfg, words) {
9
9
  const prev = words.slice(1);
10
10
  if (prev.length === 0)
11
11
  return SUBCMDS;
12
+ if (!cfg)
13
+ return []; // 无配置(不在工作区内):子命令已补全,feature/service 无从读取
12
14
  const sub = prev[0];
13
15
  const pos = prev.length;
14
16
  const featureSubs = ['up', 'add', 'rm', 'down', 'run', 'sh', 'path'];
@@ -24,8 +26,9 @@ export function completionScript(shell) {
24
26
  // 脚本只传"光标前已完成的词",不含当前正在补的词,与 complete() 的模型一致
25
27
  if (shell === 'bash')
26
28
  return `_worktree_bay(){ COMPREPLY=( $(worktree-bay __complete -- "\${COMP_WORDS[@]:0:\$COMP_CWORD}") ); }\ncomplete -F _worktree_bay worktree-bay`;
29
+ // zsh 默认不对 $(...) 做单词分割,必须用 ${(f)...} 按行拆成多个候选,否则多行输出会变成单个候选
27
30
  if (shell === 'zsh')
28
- return `#compdef worktree-bay\n_worktree_bay(){ compadd -- $(worktree-bay __complete -- "\${(@)words[1,CURRENT-1]}") }\ncompdef _worktree_bay worktree-bay`;
31
+ return `#compdef worktree-bay\n_worktree_bay(){ compadd -- \${(f)"$(worktree-bay __complete -- "\${(@)words[1,CURRENT-1]}")"} }\ncompdef _worktree_bay worktree-bay`;
29
32
  if (shell === 'fish')
30
33
  return `complete -c worktree-bay -f -a '(worktree-bay __complete -- (commandline -opc))'`;
31
34
  throw new Error('unsupported shell: ' + shell);
package/dist/git.js CHANGED
@@ -1,11 +1,20 @@
1
1
  import { spawnSync } from 'node:child_process';
2
+ import fs from 'node:fs';
2
3
  function git(repo, ...a) { return spawnSync('git', ['-C', repo, ...a], { encoding: 'utf8' }); }
3
4
  function ok(repo, ...a) { const r = git(repo, ...a); if (r.status !== 0)
4
5
  throw new Error(`git ${a.join(' ')}: ${r.stderr || r.stdout}`); return r.stdout; }
5
6
  export function addWorktree(repo, dir, branch, base) { ok(repo, 'worktree', 'add', '-b', branch, dir, base); }
6
- export function removeWorktree(repo, dir, force) { const a = ['worktree', 'remove', dir]; if (force)
7
- a.push('--force'); const r = git(repo, ...a); if (r.status !== 0)
8
- throw new Error('worktree remove: ' + (r.stderr || r.stdout)); git(repo, 'worktree', 'prune'); }
7
+ export function removeWorktree(repo, dir, force) {
8
+ const a = ['worktree', 'remove', dir];
9
+ if (force)
10
+ a.push('--force');
11
+ git(repo, ...a); // 尽力移除;残留交给下面兜底(调用方已先过脏/未推保护,到这里删除是安全的)
12
+ // git worktree remove 不会删被忽略的文件(前端 node_modules 等)→ 目录残留报 "Directory not empty";
13
+ // 它还可能先摘了登记再删目录失败,留下「git 不认但磁盘还在」的孤儿。统一兜底:物理删目录 + prune 同步元数据。
14
+ if (fs.existsSync(dir))
15
+ fs.rmSync(dir, { recursive: true, force: true });
16
+ git(repo, 'worktree', 'prune');
17
+ }
9
18
  export function isDirty(dir) { return ok(dir, 'status', '--porcelain').trim().length > 0; }
10
19
  export function currentBranch(dir) { return ok(dir, 'rev-parse', '--abbrev-ref', 'HEAD').trim(); }
11
20
  export function mainBranch(repo) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "worktree-bay",
3
- "version": "2.1.0",
3
+ "version": "2.1.1",
4
4
  "description": "Per-feature git worktree + port slots for parallel multi-service development: auto deps, env wiring, frontend-to-backend, merge-aware reclaim, plus an MCP server for AI agents.",
5
5
  "keywords": [
6
6
  "git",
@@ -54,6 +54,6 @@
54
54
  "@types/node": "^22.0.0",
55
55
  "tsx": "^4.19.0",
56
56
  "typescript": "^5.6.0",
57
- "vitest": "^2.1.0"
57
+ "vitest": "^4.1.0"
58
58
  }
59
59
  }