ralph-mcp 1.0.9 → 1.0.11

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.
@@ -5,7 +5,8 @@ import { execSync } from "child_process";
5
5
  import { parsePrdFile } from "../utils/prd-parser.js";
6
6
  import { createWorktree } from "../utils/worktree.js";
7
7
  import { generateAgentPrompt } from "../utils/agent.js";
8
- import { areDependenciesSatisfied, findExecutionByBranch, insertExecution, insertUserStories, } from "../store/state.js";
8
+ import { detectPackageManager, getInstallCommand, } from "../utils/package-manager.js";
9
+ import { areDependenciesSatisfied, findExecutionByBranch, insertExecution, insertUserStories, updateExecution, } from "../store/state.js";
9
10
  export const batchStartInputSchema = z.object({
10
11
  prdPaths: z.array(z.string()).describe("Array of paths to PRD markdown files"),
11
12
  projectRoot: z.string().optional().describe("Project root directory (defaults to cwd)"),
@@ -20,7 +21,7 @@ export const batchStartInputSchema = z.object({
20
21
  .string()
21
22
  .optional()
22
23
  .describe("Path to a file (e.g., CLAUDE.md) to inject into the agent prompt"),
23
- preheat: z.boolean().default(true).describe("Run pnpm install serially before starting agents (avoids store lock)"),
24
+ preheat: z.boolean().default(true).describe("Run install command serially before starting agents (avoids store lock)"),
24
25
  });
25
26
  /**
26
27
  * Topological sort to determine execution order based on dependencies.
@@ -53,23 +54,30 @@ function topologicalSort(prds) {
53
54
  return result;
54
55
  }
55
56
  /**
56
- * Run pnpm install in a worktree directory.
57
+ * Run install command in a worktree directory.
57
58
  */
58
- function preheatWorktree(worktreePath) {
59
+ function preheatWorktree(worktreePath, installCmd) {
60
+ const cmd = `${installCmd.command} ${installCmd.args.join(" ")}`;
59
61
  try {
60
- execSync("pnpm install --frozen-lockfile", {
62
+ execSync(cmd, {
61
63
  cwd: worktreePath,
62
64
  stdio: "pipe",
63
65
  timeout: 300000, // 5 minutes
64
66
  });
65
67
  }
66
68
  catch (error) {
67
- // Try without frozen lockfile
68
- execSync("pnpm install", {
69
- cwd: worktreePath,
70
- stdio: "pipe",
71
- timeout: 300000,
72
- });
69
+ // Try fallback if available
70
+ if (installCmd.fallbackArgs.length > 0) {
71
+ const fallbackCmd = `${installCmd.command} ${installCmd.fallbackArgs.join(" ")}`;
72
+ execSync(fallbackCmd, {
73
+ cwd: worktreePath,
74
+ stdio: "pipe",
75
+ timeout: 300000,
76
+ });
77
+ }
78
+ else {
79
+ throw error;
80
+ }
73
81
  }
74
82
  }
75
83
  export async function batchStart(input) {
@@ -78,6 +86,9 @@ export async function batchStart(input) {
78
86
  const contextPath = input.contextInjectionPath
79
87
  ? resolve(projectRoot, input.contextInjectionPath)
80
88
  : undefined;
89
+ // Detect package manager
90
+ const pm = detectPackageManager(projectRoot);
91
+ const installCmd = getInstallCommand(pm);
81
92
  const skipped = [];
82
93
  const prdInfos = [];
83
94
  // Phase 1: Parse all PRDs and create execution records
@@ -159,13 +170,13 @@ export async function batchStart(input) {
159
170
  }
160
171
  // Phase 2: Topological sort for preheat order
161
172
  const sortedPrds = topologicalSort(prdInfos);
162
- // Phase 3: Preheat worktrees serially (avoids pnpm store lock contention)
173
+ // Phase 3: Preheat worktrees serially (avoids store lock contention)
163
174
  let preheatCompleted = false;
164
175
  if (input.preheat && input.worktree) {
165
176
  for (const prd of sortedPrds) {
166
177
  if (prd.worktreePath) {
167
178
  try {
168
- preheatWorktree(prd.worktreePath);
179
+ preheatWorktree(prd.worktreePath, installCmd);
169
180
  }
170
181
  catch (error) {
171
182
  console.error(`Preheat failed for ${prd.branch}:`, error);
@@ -184,6 +195,11 @@ export async function batchStart(input) {
184
195
  if (depStatus.satisfied) {
185
196
  const agentPrompt = generateAgentPrompt(prd.branch, "", // description not stored in prdInfo
186
197
  prd.worktreePath || projectRoot, prd.stories, contextPath);
198
+ // Mark as running immediately since we're returning the prompt
199
+ await updateExecution(prd.executionId, {
200
+ status: "running",
201
+ updatedAt: new Date(),
202
+ });
187
203
  readyToStart.push({
188
204
  branch: prd.branch,
189
205
  agentPrompt,
@@ -0,0 +1,8 @@
1
+ export type PackageManager = "pnpm" | "npm" | "yarn" | "bun";
2
+ export interface InstallCommand {
3
+ command: string;
4
+ args: string[];
5
+ fallbackArgs: string[];
6
+ }
7
+ export declare function detectPackageManager(projectRoot: string): PackageManager;
8
+ export declare function getInstallCommand(pm: PackageManager): InstallCommand;
@@ -0,0 +1,44 @@
1
+ import { existsSync } from "fs";
2
+ import { join } from "path";
3
+ export function detectPackageManager(projectRoot) {
4
+ if (existsSync(join(projectRoot, "pnpm-lock.yaml"))) {
5
+ return "pnpm";
6
+ }
7
+ if (existsSync(join(projectRoot, "yarn.lock"))) {
8
+ return "yarn";
9
+ }
10
+ if (existsSync(join(projectRoot, "bun.lockb"))) {
11
+ return "bun";
12
+ }
13
+ // Default to npm if package-lock.json exists or as fallback
14
+ return "npm";
15
+ }
16
+ export function getInstallCommand(pm) {
17
+ switch (pm) {
18
+ case "pnpm":
19
+ return {
20
+ command: "pnpm",
21
+ args: ["install", "--frozen-lockfile"],
22
+ fallbackArgs: ["install"],
23
+ };
24
+ case "yarn":
25
+ return {
26
+ command: "yarn",
27
+ args: ["install", "--frozen-lockfile"],
28
+ fallbackArgs: ["install"],
29
+ };
30
+ case "bun":
31
+ return {
32
+ command: "bun",
33
+ args: ["install", "--frozen-lockfile"],
34
+ fallbackArgs: ["install"],
35
+ };
36
+ case "npm":
37
+ default:
38
+ return {
39
+ command: "npm",
40
+ args: ["ci"],
41
+ fallbackArgs: ["install"],
42
+ };
43
+ }
44
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ralph-mcp",
3
- "version": "1.0.9",
3
+ "version": "1.0.11",
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",