ralph-mcp 1.0.1 → 1.0.3

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
@@ -3,21 +3,46 @@
3
3
  [![npm version](https://badge.fury.io/js/ralph-mcp.svg)](https://www.npmjs.com/package/ralph-mcp)
4
4
  [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
5
5
 
6
- MCP server for autonomous PRD execution with Claude Code. Git worktree isolation, progress tracking, auto-merge.
6
+ **Parallel Ralph loop**: PRD `ralph_start` merged. Run multiple PRDs simultaneously in isolated worktrees with auto quality gates and merge.
7
7
 
8
8
  Based on [Geoffrey Huntley's Ralph pattern](https://ghuntley.com/ralph/).
9
9
 
10
10
  [中文文档](./README.zh-CN.md)
11
11
 
12
+ ## The Ralph Loop (2 Steps)
13
+
14
+ ```
15
+ Step 1: Generate PRD
16
+ User: "Create a PRD for user authentication"
17
+ Claude: [Generates tasks/prd-auth.md]
18
+
19
+ Step 2: Execute
20
+ User: "Start" or "Execute this PRD"
21
+ Claude: ralph_start → Task Agent handles everything automatically
22
+ ```
23
+
24
+ **That's it.** Ralph MCP automatically handles: branch creation, worktree isolation, code implementation, quality checks, commits, merge, and doc sync.
25
+
26
+ ## Why Ralph MCP?
27
+
28
+ | Without Ralph | With Ralph |
29
+ |---------------|------------|
30
+ | One feature at a time | Multiple features in parallel |
31
+ | Manual PRD writing | Claude generates PRD for you |
32
+ | Manual git branch management | Automatic worktree isolation |
33
+ | Lost progress on restart | Persistent state (JSON) |
34
+ | Manual merge coordination | Auto merge with conflict resolution |
35
+ | No visibility into progress | Real-time status tracking |
36
+
12
37
  ## Features
13
38
 
14
- - **PRD Parsing** - Extracts User Stories from markdown PRD files
15
- - **Git Worktree Isolation** - Each PRD runs in isolated worktree
16
- - **Background Execution** - Works with Claude Code's Task tool for parallel PRD execution
17
- - **Progress Tracking** - Real-time status via `ralph_status()`
18
- - **Auto Merge** - One-click merge with conflict resolution
39
+ - **2-Step Workflow** - Just create PRD and run `ralph_start`, everything else is automatic
40
+ - **Parallel Execution** - Run 5+ PRDs simultaneously with Claude Code Task tool
41
+ - **Git Worktree Isolation** - Each PRD runs in its own worktree, zero conflicts
42
+ - **Auto Quality Gates** - Type check, lint, build before every commit
43
+ - **Auto Merge** - Merges to main when all User Stories pass
44
+ - **Doc Sync** - Automatically updates TODO.md with completed items
19
45
  - **Notifications** - Windows Toast when PRD completes
20
- - **State Persistence** - Survives Claude Code restarts (JSON storage)
21
46
 
22
47
  ## Installation
23
48
 
@@ -66,6 +91,36 @@ Or if installed from source:
66
91
 
67
92
  Restart Claude Code to load.
68
93
 
94
+ ## Claude Code Skill Setup (Recommended)
95
+
96
+ For the best experience, create a skill file that teaches Claude how to use Ralph.
97
+
98
+ See **[SKILL-EXAMPLE.md](./SKILL-EXAMPLE.md)** for a complete, copy-paste ready skill configuration.
99
+
100
+ ### Quick Setup
101
+
102
+ ```bash
103
+ # 1. Create skill directory
104
+ mkdir -p .claude/skills/ralph
105
+
106
+ # 2. Copy the example (adjust path as needed)
107
+ cp /path/to/ralph-mcp/SKILL-EXAMPLE.md .claude/skills/ralph/SKILL.md
108
+
109
+ # 3. Customize quality check commands for your project
110
+ ```
111
+
112
+ ### Add to CLAUDE.md (optional)
113
+
114
+ ```markdown
115
+ ## Skills
116
+
117
+ | Skill | Trigger |
118
+ |-------|---------|
119
+ | `ralph` | PRD execution (generate PRD → start → auto merge) |
120
+ ```
121
+
122
+ This enables Claude to automatically use Ralph when you mention PRD execution.
123
+
69
124
  ## Tools
70
125
 
71
126
  | Tool | Description |
@@ -81,65 +136,53 @@ Restart Claude Code to load.
81
136
 
82
137
  ## Usage
83
138
 
84
- ### Basic Workflow
85
-
86
- ```javascript
87
- // 1. Start PRD execution
88
- ralph_start({ prdPath: "tasks/prd-feature.md" })
139
+ ### Typical Session
89
140
 
90
- // 2. Check status anytime
91
- ralph_status()
92
-
93
- // 3. Merge when complete
94
- ralph_merge({ branch: "ralph/prd-feature" })
95
141
  ```
142
+ User: Help me finish the Speaking module from TODO.md
96
143
 
97
- ### Parallel Execution with Claude Code Task Tool
144
+ Claude: Let me check TODO.md... Found 3 incomplete items:
145
+ - Speaking dialogue practice
146
+ - Speaking scoring optimization
147
+ - Speaking question bank
98
148
 
99
- Ralph MCP is designed to work with Claude Code's Task tool for parallel PRD execution:
149
+ I'll create 3 PRDs...
150
+ [Generates prd-speaking-dialogue.md]
151
+ [Generates prd-speaking-scoring.md]
152
+ [Generates prd-speaking-qb.md]
100
153
 
101
- ```
102
- 1. Analyze PRDs to identify independent tasks that can run in parallel
103
- 2. Start multiple PRDs via ralph_start()
104
- 3. Launch background Task agents for each PRD
105
- 4. Continue chatting - plan next features, review code, etc.
106
- 5. Get Windows Toast notification when PRDs complete
107
- 6. Merge completed PRDs to main via ralph_merge()
108
- ```
154
+ User: Start
109
155
 
110
- **Example session:**
156
+ Claude:
157
+ [ralph_start × 3]
158
+ [Task Agent × 3 running in parallel]
111
159
 
112
- ```
113
- User: Execute these 3 PRDs in parallel
114
-
115
- Claude: Let me analyze the PRDs...
116
- - prd-auth.md (independent)
117
- - prd-dashboard.md (independent)
118
- - prd-api.md (independent)
119
-
120
- All 3 can run in parallel. Starting...
160
+ 3 PRDs started. They'll auto-merge when complete.
161
+ Use ralph_status to check progress.
121
162
 
122
- [Calls ralph_start() for each PRD]
123
- [Launches 3 background Task agents]
163
+ --- Some time later ---
124
164
 
125
- PRDs are running in background. You can continue working.
126
- I'll notify you when they complete.
165
+ User: Progress?
127
166
 
128
- User: Great, let's plan the next feature while waiting...
167
+ Claude: [ralph_status]
168
+ ✅ prd-speaking-dialogue - Merged
169
+ ✅ prd-speaking-scoring - Merged
170
+ 🔄 prd-speaking-qb - US-003/005 in progress
129
171
 
130
- [Later - Windows Toast notification appears]
172
+ User: 👍
173
+ ```
131
174
 
132
- Claude: All 3 PRDs completed successfully!
133
- - ralph/prd-auth: 4/4 US ✓
134
- - ralph/prd-dashboard: 3/3 US ✓
135
- - ralph/prd-api: 5/5 US ✓
175
+ ### Manual Workflow
136
176
 
137
- Ready to merge?
177
+ ```javascript
178
+ // 1. Start PRD execution
179
+ ralph_start({ prdPath: "tasks/prd-feature.md" })
138
180
 
139
- User: Yes, merge all
181
+ // 2. Check status anytime
182
+ ralph_status()
140
183
 
141
- Claude: [Calls ralph_merge() for each branch]
142
- All PRDs merged to main successfully.
184
+ // 3. Manual merge if needed (usually automatic)
185
+ ralph_merge({ branch: "ralph/prd-feature" })
143
186
  ```
144
187
 
145
188
  ### API Reference
package/README.zh-CN.md CHANGED
@@ -3,21 +3,31 @@
3
3
  [![npm version](https://badge.fury.io/js/ralph-mcp.svg)](https://www.npmjs.com/package/ralph-mcp)
4
4
  [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
5
5
 
6
- 用于 Claude Code 自主执行 PRD 的 MCP 服务器。支持 Git worktree 隔离、进度追踪、自动合并。
6
+ 自主并行执行 PRD 的 Claude Code MCP 服务器。自动解析 PRD、创建隔离 worktree、追踪进度、合并完成的功能。
7
7
 
8
8
  基于 [Geoffrey Huntley 的 Ralph 模式](https://ghuntley.com/ralph/)。
9
9
 
10
10
  [English](./README.md)
11
11
 
12
+ ## 为什么选择 Ralph MCP?
13
+
14
+ | 没有 Ralph | 有 Ralph |
15
+ |------------|----------|
16
+ | 一次只能做一个功能 | 多个功能并行执行 |
17
+ | 手动管理 git 分支 | 自动 worktree 隔离 |
18
+ | 重启后进度丢失 | 状态持久化(JSON) |
19
+ | 手动协调合并 | 串行合并队列 |
20
+ | 看不到执行进度 | 实时状态追踪 |
21
+
12
22
  ## 特性
13
23
 
14
- - **PRD 解析** - markdown PRD 文件中提取 User Stories
15
- - **Git Worktree 隔离** - 每个 PRD 在独立的 worktree 中运行
16
- - **后台执行** - 配合 Claude Code 的 Task 工具并行执行多个 PRD
24
+ - **并行执行** - 配合 Claude Code Task 工具同时执行多个 PRD
25
+ - **Git Worktree 隔离** - 每个 PRD 在独立 worktree 中运行,零冲突
26
+ - **智能合并队列** - 串行合并避免并行合并冲突
17
27
  - **进度追踪** - 通过 `ralph_status()` 实时查看状态
18
- - **自动合并** - 一键合并,支持冲突解决策略
19
- - **完成通知** - PRD 完成时弹出 Windows Toast 通知
20
28
  - **状态持久化** - 重启 Claude Code 不丢失状态(JSON 存储)
29
+ - **自动合并** - 一键合并,支持多种冲突解决策略
30
+ - **完成通知** - PRD 完成时弹出 Windows Toast 通知
21
31
 
22
32
  ## 安装
23
33
 
package/dist/index.js CHANGED
@@ -47,8 +47,8 @@ server.setRequestHandler(ListToolsRequestSchema, async () => {
47
47
  },
48
48
  autoMerge: {
49
49
  type: "boolean",
50
- description: "Auto add to merge queue when all stories pass (default: false)",
51
- default: false,
50
+ description: "Auto add to merge queue when all stories pass (default: true)",
51
+ default: true,
52
52
  },
53
53
  notifyOnComplete: {
54
54
  type: "boolean",
@@ -92,7 +92,7 @@ export async function merge(input) {
92
92
  const commitMessage = generateCommitMessage(exec.branch, exec.description, completedStories);
93
93
  // Step 4: Attempt merge to main
94
94
  console.log(">>> Merging to main...");
95
- const mergeResult = await mergeBranchWithMessage(exec.projectRoot, exec.branch, commitMessage, onConflict);
95
+ const mergeResult = await mergeBranchWithMessage(exec.projectRoot, exec.worktreePath || undefined, exec.branch, commitMessage, onConflict);
96
96
  if (mergeResult.success) {
97
97
  // Step 5: Update docs
98
98
  const docsUpdated = [];
@@ -138,7 +138,9 @@ export async function merge(input) {
138
138
  : { typeCheck: true, build: true },
139
139
  docsUpdated: docsUpdated.length > 0 ? docsUpdated : undefined,
140
140
  mergedStories: completedStories.map((s) => s.id),
141
- message: `Successfully merged ${input.branch} to main`,
141
+ message: mergeResult.alreadyMerged
142
+ ? `Branch ${input.branch} was already merged to main`
143
+ : `Successfully merged ${input.branch} to main`,
142
144
  };
143
145
  }
144
146
  // Handle conflicts
@@ -250,13 +252,56 @@ export async function merge(input) {
250
252
  }
251
253
  /**
252
254
  * Merge branch with custom commit message
255
+ * Always merges in projectRoot (main repo) since it's already on main branch.
256
+ * Worktree is only used for development, not for merging.
253
257
  */
254
- async function mergeBranchWithMessage(projectRoot, branch, commitMessage, onConflict) {
258
+ async function mergeBranchWithMessage(projectRoot, _worktreePath, // Unused, kept for API compatibility
259
+ branch, commitMessage, onConflict) {
255
260
  const { exec: execAsync } = await import("child_process");
256
261
  const { promisify } = await import("util");
257
262
  const execPromise = promisify(execAsync);
258
- // Checkout main and pull
259
- await execPromise("git checkout main && git pull", { cwd: projectRoot });
263
+ // Always merge in projectRoot (main repo is already on main branch)
264
+ const cwd = projectRoot;
265
+ // Check if origin remote exists
266
+ let hasOrigin = false;
267
+ try {
268
+ const { stdout } = await execPromise("git remote", { cwd });
269
+ hasOrigin = stdout.includes("origin");
270
+ }
271
+ catch {
272
+ hasOrigin = false;
273
+ }
274
+ // Fetch latest main and pull
275
+ if (hasOrigin) {
276
+ try {
277
+ await execPromise("git fetch origin main", { cwd });
278
+ await execPromise("git pull origin main", { cwd });
279
+ }
280
+ catch {
281
+ // Ignore fetch/pull errors
282
+ }
283
+ }
284
+ // Check if branch is already merged into main
285
+ try {
286
+ const mergeBase = hasOrigin ? "origin/main" : "main";
287
+ const { stdout: mergedBranches } = await execPromise(`git branch --merged ${mergeBase}`, { cwd });
288
+ const isMerged = mergedBranches
289
+ .split("\n")
290
+ .map((b) => b.trim().replace(/^\* /, ""))
291
+ .includes(branch);
292
+ if (isMerged) {
293
+ const { stdout: hash } = await execPromise(`git rev-parse ${mergeBase}`, { cwd });
294
+ return {
295
+ success: true,
296
+ commitHash: hash.trim(),
297
+ hasConflicts: false,
298
+ alreadyMerged: true,
299
+ };
300
+ }
301
+ }
302
+ catch {
303
+ // Continue with merge attempt if check fails
304
+ }
260
305
  // Build merge strategy
261
306
  let mergeStrategy = "";
262
307
  if (onConflict === "auto_theirs") {
@@ -266,23 +311,27 @@ async function mergeBranchWithMessage(projectRoot, branch, commitMessage, onConf
266
311
  mergeStrategy = "-X ours";
267
312
  }
268
313
  try {
269
- // Use heredoc-style commit message to handle special characters
314
+ // Perform merge (main repo is already on main branch, no checkout needed)
270
315
  const escapedMessage = commitMessage.replace(/'/g, "'\\''");
271
- await execPromise(`git merge --no-ff ${mergeStrategy} "${branch}" -m '${escapedMessage}'`, { cwd: projectRoot });
272
- const { stdout: hash } = await execPromise("git rev-parse HEAD", {
273
- cwd: projectRoot,
274
- });
316
+ const { stdout: mergeOutput } = await execPromise(`git merge --no-ff ${mergeStrategy} "${branch}" -m '${escapedMessage}'`, { cwd });
317
+ const { stdout: hash } = await execPromise("git rev-parse HEAD", { cwd });
318
+ const commitHash = hash.trim();
319
+ // Check if "Already up to date" (no new commit created)
320
+ const alreadyUpToDate = mergeOutput.includes("Already up to date");
321
+ // Push to origin if available
322
+ if (hasOrigin) {
323
+ await execPromise("git push origin main", { cwd });
324
+ }
275
325
  return {
276
326
  success: true,
277
- commitHash: hash.trim(),
327
+ commitHash,
278
328
  hasConflicts: false,
329
+ alreadyMerged: alreadyUpToDate,
279
330
  };
280
331
  }
281
332
  catch {
282
333
  // Check for conflicts
283
- const { stdout: status } = await execPromise("git status --porcelain", {
284
- cwd: projectRoot,
285
- });
334
+ const { stdout: status } = await execPromise("git status --porcelain", { cwd });
286
335
  const conflictFiles = status
287
336
  .split("\n")
288
337
  .filter((line) => line.startsWith("UU ") || line.startsWith("AA "))
@@ -1,6 +1,7 @@
1
1
  import { z } from "zod";
2
2
  import notifier from "node-notifier";
3
3
  import { findExecutionByBranch, findMergeQueueItemByExecutionId, findUserStoryById, insertMergeQueueItem, listMergeQueue, listUserStoriesByExecutionId, updateExecution, updateUserStory, } from "../store/state.js";
4
+ import { mergeQueueAction } from "./merge.js";
4
5
  export const updateInputSchema = z.object({
5
6
  branch: z.string().describe("Branch name (e.g., ralph/task1-agent)"),
6
7
  storyId: z.string().describe("Story ID (e.g., US-001)"),
@@ -49,6 +50,15 @@ export async function update(input) {
49
50
  createdAt: new Date(),
50
51
  });
51
52
  addedToMergeQueue = true;
53
+ // Auto-process merge queue (fire and forget)
54
+ setImmediate(async () => {
55
+ try {
56
+ await mergeQueueAction({ action: "process" });
57
+ }
58
+ catch (e) {
59
+ console.error("Auto-merge failed:", e);
60
+ }
61
+ });
52
62
  }
53
63
  }
54
64
  // Send Windows toast notification when all complete (if enabled)
@@ -35,7 +35,8 @@ export declare function generateCommitMessage(branch: string, description: strin
35
35
  */
36
36
  export declare function getBranchCommits(projectRoot: string, branch: string): Promise<string[]>;
37
37
  /**
38
- * Update TODO.md to mark PRD as completed
38
+ * Update TODO.md to mark PRD-related items as completed
39
+ * Uses fuzzy matching based on keywords from the PRD description
39
40
  */
40
41
  export declare function updateTodoDoc(projectRoot: string, branch: string, description: string): boolean;
41
42
  /**
@@ -8,11 +8,23 @@ const execAsync = promisify(exec);
8
8
  */
9
9
  export async function syncMainToBranch(worktreePath, branch) {
10
10
  try {
11
- // Fetch latest main
12
- await execAsync("git fetch origin main", { cwd: worktreePath });
11
+ // Check if origin remote exists
12
+ let hasOrigin = false;
13
+ try {
14
+ const { stdout } = await execAsync("git remote", { cwd: worktreePath });
15
+ hasOrigin = stdout.includes("origin");
16
+ }
17
+ catch {
18
+ hasOrigin = false;
19
+ }
20
+ // Fetch latest main only if origin exists
21
+ if (hasOrigin) {
22
+ await execAsync("git fetch origin main", { cwd: worktreePath });
23
+ }
13
24
  // Try to merge main into feature branch
25
+ const mergeTarget = hasOrigin ? "origin/main" : "main";
14
26
  try {
15
- await execAsync("git merge origin/main --no-edit", { cwd: worktreePath });
27
+ await execAsync(`git merge ${mergeTarget} --no-edit`, { cwd: worktreePath });
16
28
  return {
17
29
  success: true,
18
30
  hasConflicts: false,
@@ -118,7 +130,8 @@ export async function getBranchCommits(projectRoot, branch) {
118
130
  }
119
131
  }
120
132
  /**
121
- * Update TODO.md to mark PRD as completed
133
+ * Update TODO.md to mark PRD-related items as completed
134
+ * Uses fuzzy matching based on keywords from the PRD description
122
135
  */
123
136
  export function updateTodoDoc(projectRoot, branch, description) {
124
137
  const todoPath = join(projectRoot, "docs", "TODO.md");
@@ -127,12 +140,28 @@ export function updateTodoDoc(projectRoot, branch, description) {
127
140
  }
128
141
  try {
129
142
  let content = readFileSync(todoPath, "utf-8");
130
- // Find and update the PRD entry (mark as completed)
131
- // Pattern: - [ ] PRD description -> - [x] PRD description
132
- const prdPattern = new RegExp(`- \\[ \\] (.*${description.slice(0, 30)}.*|.*${branch}.*)`);
133
- if (prdPattern.test(content)) {
134
- content = content.replace(prdPattern, "- [x] $1");
135
- writeFileSync(todoPath, content, "utf-8");
143
+ let updated = false;
144
+ // Extract keywords from description and branch for matching
145
+ const keywords = extractKeywords(description, branch);
146
+ // Find unchecked items that match keywords
147
+ const lines = content.split("\n");
148
+ const updatedLines = lines.map((line) => {
149
+ // Only process unchecked items
150
+ if (!line.match(/^(\s*)- \[ \]/)) {
151
+ return line;
152
+ }
153
+ // Check if line matches any keywords
154
+ const lineLower = line.toLowerCase();
155
+ const matchCount = keywords.filter((kw) => lineLower.includes(kw)).length;
156
+ // Require at least 2 keyword matches for confidence
157
+ if (matchCount >= 2) {
158
+ updated = true;
159
+ return line.replace("- [ ]", "- [x]");
160
+ }
161
+ return line;
162
+ });
163
+ if (updated) {
164
+ writeFileSync(todoPath, updatedLines.join("\n"), "utf-8");
136
165
  return true;
137
166
  }
138
167
  return false;
@@ -141,6 +170,36 @@ export function updateTodoDoc(projectRoot, branch, description) {
141
170
  return false;
142
171
  }
143
172
  }
173
+ /**
174
+ * Extract keywords from PRD description and branch name
175
+ */
176
+ function extractKeywords(description, branch) {
177
+ const keywords = [];
178
+ // Common words to ignore
179
+ const stopWords = new Set([
180
+ "the", "a", "an", "and", "or", "but", "in", "on", "at", "to", "for",
181
+ "of", "with", "by", "from", "as", "is", "was", "are", "were", "been",
182
+ "be", "have", "has", "had", "do", "does", "did", "will", "would",
183
+ "could", "should", "may", "might", "must", "shall", "can", "need",
184
+ "prd", "ralph", "user", "want", "that", "this", "which", "who",
185
+ ]);
186
+ // Extract from description
187
+ const descWords = description
188
+ .toLowerCase()
189
+ .replace(/[^a-z0-9\s]/g, " ")
190
+ .split(/\s+/)
191
+ .filter((w) => w.length > 2 && !stopWords.has(w));
192
+ keywords.push(...descWords);
193
+ // Extract from branch name (e.g., ralph/prd-speaking-dialogue-coach)
194
+ const branchWords = branch
195
+ .toLowerCase()
196
+ .replace(/[^a-z0-9]/g, " ")
197
+ .split(/\s+/)
198
+ .filter((w) => w.length > 2 && !stopWords.has(w));
199
+ keywords.push(...branchWords);
200
+ // Dedupe and return
201
+ return [...new Set(keywords)];
202
+ }
144
203
  /**
145
204
  * Update PROJECT-STATUS.md with merge info
146
205
  */
@@ -35,8 +35,7 @@ function parsePrdMarkdown(content) {
35
35
  const titleMatch = body.match(/^#\s+(.+)$/m);
36
36
  const title = frontmatter.title || titleMatch?.[1] || "Untitled PRD";
37
37
  // Extract branch name from frontmatter or generate from title
38
- const branchName = frontmatter.branch ||
39
- `ralph/${title.toLowerCase().replace(/[^a-z0-9]+/g, "-")}`;
38
+ const branchName = frontmatter.branch || generateBranchName(title);
40
39
  // Extract description
41
40
  const descMatch = body.match(/##\s*(?:Description|描述|Overview|概述)\s*\n([\s\S]*?)(?=\n##|\n$)/i);
42
41
  const description = descMatch?.[1]?.trim() || title;
package/package.json CHANGED
@@ -1,18 +1,12 @@
1
1
  {
2
2
  "name": "ralph-mcp",
3
- "version": "1.0.1",
3
+ "version": "1.0.3",
4
4
  "description": "MCP server for autonomous PRD execution with Claude Code. Git worktree isolation, progress tracking, auto-merge.",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
7
7
  "bin": {
8
8
  "ralph-mcp": "dist/index.js"
9
9
  },
10
- "scripts": {
11
- "build": "tsc",
12
- "dev": "tsx watch src/index.ts",
13
- "start": "node dist/index.js",
14
- "prepublishOnly": "npm run build"
15
- },
16
10
  "keywords": [
17
11
  "mcp",
18
12
  "claude",
@@ -20,7 +14,11 @@
20
14
  "prd",
21
15
  "ai-agent",
22
16
  "autonomous",
23
- "git-worktree"
17
+ "git-worktree",
18
+ "project-management",
19
+ "task-management",
20
+ "user-story",
21
+ "merge-queue"
24
22
  ],
25
23
  "author": "G0d2i11a",
26
24
  "license": "MIT",
@@ -40,15 +38,20 @@
40
38
  "node": ">=18"
41
39
  },
42
40
  "dependencies": {
43
- "@modelcontextprotocol/sdk": "^1.25.2",
41
+ "@modelcontextprotocol/sdk": "^1.25.3",
44
42
  "gray-matter": "^4.0.3",
45
43
  "node-notifier": "^10.0.1",
46
- "zod": "^3.24.1"
44
+ "zod": "^3.25.76"
47
45
  },
48
46
  "devDependencies": {
49
- "@types/node": "^22.10.5",
47
+ "@types/node": "^22.19.7",
50
48
  "@types/node-notifier": "^8.0.5",
51
- "tsx": "^4.19.2",
52
- "typescript": "^5.7.2"
49
+ "tsx": "^4.21.0",
50
+ "typescript": "^5.9.3"
51
+ },
52
+ "scripts": {
53
+ "build": "tsc",
54
+ "dev": "tsx watch src/index.ts",
55
+ "start": "node dist/index.js"
53
56
  }
54
- }
57
+ }