worktree-bay 1.1.0 → 1.2.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.
package/README.md CHANGED
@@ -114,6 +114,22 @@ worktree-bay completion install
114
114
 
115
115
  执行 `source ~/.bashrc`(或重开终端)即可 tab 补全子命令、功能名、服务名。也可手动:`worktree-bay completion bash`(打印脚本,自行接入)。
116
116
 
117
+ ## MCP(让 AI 直接用)
118
+
119
+ 内置一个 MCP 服务,让 AI(Claude Code 等)通过 MCP 调用 worktree-bay 完成并行开发,并内置工作流指导(告诉 AI 何时用 up/ls/run/down/gc)。
120
+
121
+ 启动:`worktree-bay mcp`(stdio)。在 Claude Code 里注册:
122
+
123
+ ```json
124
+ {
125
+ "mcpServers": {
126
+ "worktree-bay": { "command": "worktree-bay", "args": ["mcp"] }
127
+ }
128
+ }
129
+ ```
130
+
131
+ > 服务在哪个工作区目录启动,就用哪个目录的 `worktree-bay.config.json`(或设 `WORKTREE_BAY_CONFIG`)。暴露的工具:`worktree_bay_up / ls / add / run / down / gc`。
132
+
117
133
  ## 许可证
118
134
 
119
135
  [MIT](./LICENSE)
package/dist/cli.js CHANGED
@@ -9,6 +9,7 @@ import { runCommand, shCommand } from './commands/passthrough.js';
9
9
  import { rmCommand } from './commands/rm.js';
10
10
  import { gcCommand } from './commands/gc.js';
11
11
  import { complete, completionCommand, installCompletion } from './commands/completion.js';
12
+ import { startMcp } from './mcp.js';
12
13
  import { die } from './util/log.js';
13
14
  const pkg = JSON.parse(readFileSync(new URL('../package.json', import.meta.url), 'utf8'));
14
15
  const program = new Command();
@@ -77,6 +78,13 @@ program.command('completion <target> [shell]').description('install 一键装进
77
78
  catch (e) {
78
79
  die(e.message);
79
80
  } });
81
+ program.command('mcp').description('启动 MCP 服务(stdio),供 AI 通过 MCP 调用 worktree-bay 完成并行开发')
82
+ .action(async () => { try {
83
+ await startMcp();
84
+ }
85
+ catch (e) {
86
+ die(e.message);
87
+ } });
80
88
  program.command('__complete', { hidden: true }).allowUnknownOption().action(() => {
81
89
  const words = process.argv.slice(process.argv.indexOf('--') + 1);
82
90
  try {
@@ -3,7 +3,7 @@ import os from 'node:os';
3
3
  import path from 'node:path';
4
4
  import { readLabels } from '../slots.js';
5
5
  import { log } from '../util/log.js';
6
- const SUBCMDS = ['claim', 'up', 'add', 'ls', 'gc', 'down', 'rm', 'run', 'sh', 'completion'];
6
+ const SUBCMDS = ['claim', 'up', 'add', 'ls', 'gc', 'down', 'rm', 'run', 'sh', 'completion', 'mcp'];
7
7
  // words = 命令名 + 光标前已输入完的词(不含当前正在补的词)
8
8
  export function complete(cfg, words) {
9
9
  const prev = words.slice(1);
package/dist/mcp.js ADDED
@@ -0,0 +1,56 @@
1
+ import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
+ import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
3
+ import { z } from 'zod';
4
+ import { spawnSync } from 'node:child_process';
5
+ import { fileURLToPath } from 'node:url';
6
+ import { readFileSync } from 'node:fs';
7
+ import path from 'node:path';
8
+ const CLI = path.join(path.dirname(fileURLToPath(import.meta.url)), 'cli.js');
9
+ const VERSION = JSON.parse(readFileSync(new URL('../package.json', import.meta.url), 'utf8')).version;
10
+ // 工具实现:直接调底层 worktree-bay CLI 并捕获输出返回,复用全部逻辑
11
+ function runCli(args) {
12
+ const r = spawnSync(process.execPath, [CLI, ...args], { encoding: 'utf8' });
13
+ const text = [r.stdout, r.stderr].filter(Boolean).join('\n').trim() || '(无输出)';
14
+ return { content: [{ type: 'text', text }] };
15
+ }
16
+ export const INSTRUCTIONS = `worktree-bay 是「功能 = 槽位」的并行开发编排器。当你需要在一个多服务工作区里并行开发多个功能、又不想让它们的端口/依赖/数据互相干扰时,用本服务的工具来完成开发工作。
17
+
18
+ 核心模型:一个功能占一个「槽位」→ 得到一个端口块;该功能用到哪些服务,就在哪些服务上各开一个 git worktree 挂进这个槽,端口自动错开,前端自动连到同槽的后端。
19
+
20
+ 推荐工作流:
21
+ 1. 起新功能:调用 worktree_bay_up,传功能名 + 要改的服务列表(如 ["api","lms"])。它会自动占槽、为每个服务开 worktree、拷依赖、注入端口并起服务。
22
+ 2. 查看在跑的功能:worktree_bay_ls。
23
+ 3. 在某功能的某服务里跑测试/命令:worktree_bay_run(name 用配置里定义的,如 "test")。
24
+ 4. 收尾:分支合并后,先 worktree_bay_gc 看可回收项,再 worktree_bay_down 拆掉该功能。
25
+
26
+ 要点:
27
+ - 同一个功能从头到尾用同一个功能名(它同时是默认分支名)贯穿 up/run/down。
28
+ - 只起这个功能「实际要改」的服务,不要全起。
29
+ - 拿不准当前状态时先调 worktree_bay_ls。
30
+ - worktree_bay_gc 默认只读(dry-run 列出建议),apply=true 才真删,且只删「已合并到主分支且工作区干净」的,安全保守、不会误删未完成的工作。`;
31
+ export function createServer() {
32
+ const server = new McpServer({ name: 'worktree-bay', version: VERSION }, { instructions: INSTRUCTIONS });
33
+ server.tool('worktree_bay_ls', '列出所有功能槽位与占用(每槽:功能名、端口块、已起服务及端口、是否已并入主分支)', {}, async () => runCli(['ls']));
34
+ server.tool('worktree_bay_up', '为一个功能一次性起多个服务(自动占槽 + 各服务开 worktree,分支默认 = 功能名,前端自动接同槽后端)。并行开发新功能首选。', {
35
+ feature: z.string().describe('功能名(同时作为默认分支名)'),
36
+ services: z.array(z.string()).describe('要起的服务名列表,如 ["api","lms"]'),
37
+ }, async ({ feature, services }) => runCli(['up', feature, ...services]));
38
+ server.tool('worktree_bay_add', '为功能在单个服务上开 worktree(branch 省略则用功能名)', {
39
+ feature: z.string(), service: z.string(), branch: z.string().optional(),
40
+ }, async ({ feature, service, branch }) => runCli(['add', feature, service, ...(branch ? [branch] : [])]));
41
+ server.tool('worktree_bay_run', '在某功能某服务的运行体里跑预设命令(如 test),可透传额外参数', {
42
+ feature: z.string(), service: z.string(),
43
+ name: z.string().describe('配置里 run.<name> 的名字,如 test'),
44
+ args: z.array(z.string()).optional(),
45
+ }, async ({ feature, service, name, args }) => runCli(['run', feature, service, name, ...(args ?? [])]));
46
+ server.tool('worktree_bay_down', '拆除整个功能的所有服务 worktree(默认查脏/未推保护,force=true 强删)', {
47
+ feature: z.string(), force: z.boolean().optional(),
48
+ }, async ({ feature, force }) => runCli(['down', feature, ...(force ? ['-f'] : [])]));
49
+ server.tool('worktree_bay_gc', '合并感知回收:默认 dry-run 只列建议,apply=true 才实际删除「已合并且干净」的功能', {
50
+ apply: z.boolean().optional(),
51
+ }, async ({ apply }) => runCli(['gc', ...(apply ? ['--apply'] : [])]));
52
+ return server;
53
+ }
54
+ export async function startMcp() {
55
+ await createServer().connect(new StdioServerTransport());
56
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "worktree-bay",
3
- "version": "1.1.0",
3
+ "version": "1.2.0",
4
4
  "description": "Config-driven git worktree slot + port orchestrator for parallel multi-service development",
5
5
  "keywords": [
6
6
  "git",
@@ -43,7 +43,9 @@
43
43
  "registry": "https://registry.npmjs.org"
44
44
  },
45
45
  "dependencies": {
46
- "commander": "^12.1.0"
46
+ "@modelcontextprotocol/sdk": "^1.12.0",
47
+ "commander": "^12.1.0",
48
+ "zod": "^3.23.8"
47
49
  },
48
50
  "devDependencies": {
49
51
  "@types/node": "^22.0.0",