ralphctl 0.8.4 → 0.8.5

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.mjs CHANGED
@@ -782,13 +782,13 @@ var createJsonSettingsRepository = (deps) => {
782
782
  import { spawn as nodeSpawn } from "child_process";
783
783
  var DEFAULT_GIT_TIMEOUT_MS = 3e4;
784
784
  var createGitRunner = (deps = {}) => {
785
- const spawn3 = deps.spawn ?? defaultSpawn;
785
+ const spawn2 = deps.spawn ?? defaultSpawn;
786
786
  const defaultTimeoutMs = deps.defaultTimeoutMs ?? DEFAULT_GIT_TIMEOUT_MS;
787
787
  const run = (cwd, args, opts = {}) => new Promise((resolve) => {
788
788
  const timeoutMs = opts.timeoutMs ?? defaultTimeoutMs;
789
789
  let child;
790
790
  try {
791
- child = spawn3("git", args, {
791
+ child = spawn2("git", args, {
792
792
  stdio: ["pipe", "pipe", "pipe"],
793
793
  cwd: String(cwd)
794
794
  });
@@ -865,7 +865,7 @@ import { spawn as nodeSpawn2 } from "child_process";
865
865
  var DEFAULT_SHELL_TIMEOUT_MS = 5 * 6e4;
866
866
  var MAX_OUTPUT_BYTES = 50 * 1024 * 1024;
867
867
  var createShellScriptRunner = (deps = {}) => {
868
- const spawn3 = deps.spawn ?? defaultSpawn2;
868
+ const spawn2 = deps.spawn ?? defaultSpawn2;
869
869
  const defaultTimeoutMs = deps.defaultTimeoutMs ?? DEFAULT_SHELL_TIMEOUT_MS;
870
870
  const now = deps.now ?? Date.now;
871
871
  const run = (cwd, script, opts = {}) => new Promise((resolve) => {
@@ -873,7 +873,7 @@ var createShellScriptRunner = (deps = {}) => {
873
873
  const timeoutMs = opts.timeoutMs ?? defaultTimeoutMs;
874
874
  let child;
875
875
  try {
876
- child = spawn3(script, [], {
876
+ child = spawn2(script, [], {
877
877
  stdio: ["pipe", "pipe", "pipe"],
878
878
  cwd: String(cwd),
879
879
  shell: true,
@@ -4005,10 +4005,10 @@ var createInteractiveAiProvider = (deps) => {
4005
4005
  };
4006
4006
 
4007
4007
  // src/integration/io/run-cli.ts
4008
- var runCli = (spawn3, command, args, opts) => new Promise((resolve) => {
4008
+ var runCli = (spawn2, command, args, opts) => new Promise((resolve) => {
4009
4009
  let child;
4010
4010
  try {
4011
- child = spawn3(command, args, {
4011
+ child = spawn2(command, args, {
4012
4012
  stdio: ["pipe", "pipe", "pipe"],
4013
4013
  ...opts.cwd !== void 0 ? { cwd: opts.cwd } : {}
4014
4014
  });
@@ -4146,9 +4146,9 @@ var looksLikeNotFound = (stderr) => {
4146
4146
  const s = stderr.toLowerCase();
4147
4147
  return s.includes("not found") || s.includes("404") || s.includes("could not resolve") || s.includes("does not exist");
4148
4148
  };
4149
- var fetchGitHub = async (spawn3, parsed, url) => {
4149
+ var fetchGitHub = async (spawn2, parsed, url) => {
4150
4150
  const result = await runCli(
4151
- spawn3,
4151
+ spawn2,
4152
4152
  "gh",
4153
4153
  [
4154
4154
  "issue",
@@ -4195,9 +4195,9 @@ var fetchGitHub = async (spawn3, parsed, url) => {
4195
4195
  comments
4196
4196
  });
4197
4197
  };
4198
- var fetchGitLabNotes = async (spawn3, parsed) => {
4198
+ var fetchGitLabNotes = async (spawn2, parsed) => {
4199
4199
  const result = await runCli(
4200
- spawn3,
4200
+ spawn2,
4201
4201
  "glab",
4202
4202
  ["issue", "note", "list", String(parsed.number), "--repo", `${parsed.owner}/${parsed.repo}`, "--output", "json"],
4203
4203
  { timeoutMs: CLI_TIMEOUT_MS }
@@ -4226,9 +4226,9 @@ var fetchGitLabNotes = async (spawn3, parsed) => {
4226
4226
  }));
4227
4227
  return { comments };
4228
4228
  };
4229
- var fetchGitLab = async (spawn3, parsed, url, logger) => {
4229
+ var fetchGitLab = async (spawn2, parsed, url, logger) => {
4230
4230
  const result = await runCli(
4231
- spawn3,
4231
+ spawn2,
4232
4232
  "glab",
4233
4233
  ["issue", "view", String(parsed.number), "--repo", `${parsed.owner}/${parsed.repo}`, "--output", "json"],
4234
4234
  { timeoutMs: CLI_TIMEOUT_MS }
@@ -4255,7 +4255,7 @@ var fetchGitLab = async (spawn3, parsed, url, logger) => {
4255
4255
  })
4256
4256
  );
4257
4257
  }
4258
- const notes = await fetchGitLabNotes(spawn3, parsed);
4258
+ const notes = await fetchGitLabNotes(spawn2, parsed);
4259
4259
  if (notes.failure !== void 0) {
4260
4260
  logger?.warn(`glab issue note list failed for ${url}: ${notes.failure} \u2014 proceeding without comments`);
4261
4261
  }
@@ -4276,9 +4276,9 @@ var createIssueFetcher = (deps) => async (url) => {
4276
4276
 
4277
4277
  // src/integration/scm/issue-pusher.ts
4278
4278
  var CLI_TIMEOUT_MS2 = 3e4;
4279
- var updateGitHub = async (spawn3, url, body, parsed) => {
4279
+ var updateGitHub = async (spawn2, url, body, parsed) => {
4280
4280
  const r = await runCli(
4281
- spawn3,
4281
+ spawn2,
4282
4282
  "gh",
4283
4283
  ["issue", "edit", String(parsed.number), "--repo", `${parsed.owner}/${parsed.repo}`, "--body-file", "-"],
4284
4284
  { stdin: body, timeoutMs: CLI_TIMEOUT_MS2 }
@@ -4294,9 +4294,9 @@ var updateGitHub = async (spawn3, url, body, parsed) => {
4294
4294
  }
4295
4295
  return Result.ok(void 0);
4296
4296
  };
4297
- var updateGitLab = async (spawn3, url, body, parsed) => {
4297
+ var updateGitLab = async (spawn2, url, body, parsed) => {
4298
4298
  const r = await runCli(
4299
- spawn3,
4299
+ spawn2,
4300
4300
  "glab",
4301
4301
  ["issue", "update", String(parsed.number), "--repo", `${parsed.owner}/${parsed.repo}`, "--description", body],
4302
4302
  { timeoutMs: CLI_TIMEOUT_MS2 }
@@ -4312,9 +4312,9 @@ var updateGitLab = async (spawn3, url, body, parsed) => {
4312
4312
  }
4313
4313
  return Result.ok(void 0);
4314
4314
  };
4315
- var createGitHub = async (spawn3, origin, title, body) => {
4315
+ var createGitHub = async (spawn2, origin, title, body) => {
4316
4316
  const r = await runCli(
4317
- spawn3,
4317
+ spawn2,
4318
4318
  "gh",
4319
4319
  ["issue", "create", "--repo", `${origin.owner}/${origin.repo}`, "--title", title, "--body-file", "-"],
4320
4320
  { stdin: body, timeoutMs: CLI_TIMEOUT_MS2 }
@@ -4339,9 +4339,9 @@ var createGitHub = async (spawn3, origin, title, body) => {
4339
4339
  }
4340
4340
  return Result.ok({ url });
4341
4341
  };
4342
- var createGitLab = async (spawn3, origin, title, body) => {
4342
+ var createGitLab = async (spawn2, origin, title, body) => {
4343
4343
  const r = await runCli(
4344
- spawn3,
4344
+ spawn2,
4345
4345
  "glab",
4346
4346
  ["issue", "create", "--repo", `${origin.owner}/${origin.repo}`, "--title", title, "--description", body],
4347
4347
  { timeoutMs: CLI_TIMEOUT_MS2 }
@@ -4475,11 +4475,11 @@ var buildGlabArgs = (input) => {
4475
4475
  if (input.draft) args.push("--draft");
4476
4476
  return args;
4477
4477
  };
4478
- var runPlatformCli = async (spawn3, platform, input) => {
4478
+ var runPlatformCli = async (spawn2, platform, input) => {
4479
4479
  const command = platform === "github" ? "gh" : "glab";
4480
4480
  const args = platform === "github" ? buildGhArgs(input) : buildGlabArgs(input);
4481
4481
  const noun = platform === "github" ? "gh pr create" : "glab mr create";
4482
- const result = await runCli(spawn3, command, args, { cwd: String(input.cwd), timeoutMs: CLI_TIMEOUT_MS3 });
4482
+ const result = await runCli(spawn2, command, args, { cwd: String(input.cwd), timeoutMs: CLI_TIMEOUT_MS3 });
4483
4483
  if (!result.ok) return Result.error(result.error);
4484
4484
  if (result.value.exitCode !== 0) {
4485
4485
  const stderr = result.value.stderr.trim();
@@ -4958,7 +4958,7 @@ var createNpmVersionChecker = (deps) => {
4958
4958
  // package.json
4959
4959
  var package_default = {
4960
4960
  name: "ralphctl",
4961
- version: "0.8.4",
4961
+ version: "0.8.5",
4962
4962
  description: "Agent harness for long-running AI coding tasks \u2014 orchestrates Claude Code, GitHub Copilot, and OpenAI Codex across repositories",
4963
4963
  homepage: "https://github.com/lukas-grigis/ralphctl",
4964
4964
  type: "module",
@@ -5596,7 +5596,7 @@ var noopNotificationDispatcher = {
5596
5596
  }
5597
5597
  };
5598
5598
  var wire = (opts) => {
5599
- const spawn3 = opts.spawn ?? defaultPipeSpawn;
5599
+ const spawn2 = opts.spawn ?? defaultPipeSpawn;
5600
5600
  const env = opts.env ?? process.env;
5601
5601
  const debugTrace = isTruthyEnvFlag(env[RALPHCTL_DEBUG_TRACE_ENV]);
5602
5602
  const appendFile = createAppendFile();
@@ -5646,9 +5646,9 @@ var wire = (opts) => {
5646
5646
  probes: PROBES,
5647
5647
  eventBus,
5648
5648
  logger,
5649
- pullRequestCreator: createPullRequestCreator({ gitRunner: createGitRunner(), spawn: spawn3 }),
5650
- issueFetcher: createIssueFetcher({ spawn: spawn3, logger }),
5651
- issuePusher: createIssuePusher({ spawn: spawn3 }),
5649
+ pullRequestCreator: createPullRequestCreator({ gitRunner: createGitRunner(), spawn: spawn2 }),
5650
+ issueFetcher: createIssueFetcher({ spawn: spawn2, logger }),
5651
+ issuePusher: createIssuePusher({ spawn: spawn2 }),
5652
5652
  versionChecker: createNpmVersionChecker({
5653
5653
  stateRoot: opts.storage.stateRoot,
5654
5654
  currentVersion: CLI_METADATA.currentVersion,
@@ -7069,7 +7069,7 @@ var probeSprintExecutionPairing = async (sprints, sprintExecutionRepo) => {
7069
7069
  // src/integration/io/command-exists.ts
7070
7070
  import { spawn } from "child_process";
7071
7071
  var commandExists = (name) => new Promise((resolve) => {
7072
- const child = spawn(name, ["--version"], { stdio: "ignore" });
7072
+ const child = process.platform === "win32" ? spawn("where", [name], { stdio: "ignore" }) : spawn("command", ["-v", name], { stdio: "ignore", shell: true });
7073
7073
  let settled = false;
7074
7074
  const settle = (value) => {
7075
7075
  if (settled) return;
@@ -7077,7 +7077,7 @@ var commandExists = (name) => new Promise((resolve) => {
7077
7077
  resolve(value);
7078
7078
  };
7079
7079
  child.on("error", () => settle(false));
7080
- child.on("exit", () => settle(true));
7080
+ child.on("exit", (code) => settle(code === 0));
7081
7081
  });
7082
7082
 
7083
7083
  // src/integration/io/run-command.ts
@@ -12139,7 +12139,6 @@ var createRefineFlow = (deps, opts) => {
12139
12139
  };
12140
12140
 
12141
12141
  // src/integration/system/detect-cli.ts
12142
- import { spawn as spawn2 } from "child_process";
12143
12142
  var PROVIDER_BINARY2 = {
12144
12143
  "claude-code": "claude",
12145
12144
  "github-copilot": "gh",
@@ -12216,17 +12215,7 @@ Install options (${os}):
12216
12215
  ${bullets}
12217
12216
  Docs: ${guidance.docsUrl}`;
12218
12217
  };
12219
- var defaultWhich = (binary) => new Promise((resolve) => {
12220
- const child = spawn2("command", ["-v", binary], { stdio: "pipe", shell: true });
12221
- let settled = false;
12222
- const settle = (value) => {
12223
- if (settled) return;
12224
- settled = true;
12225
- resolve(value);
12226
- };
12227
- child.on("error", () => settle(false));
12228
- child.on("exit", (code) => settle(code === 0));
12229
- });
12218
+ var defaultWhich = commandExists;
12230
12219
  var detectInstalledProviders = async (options = {}) => {
12231
12220
  const which = options.which ?? defaultWhich;
12232
12221
  const providers = Object.keys(PROVIDER_BINARY2);
@@ -15237,7 +15226,7 @@ var evaluatorLeaf = (deps, taskId) => leaf(`evaluator-${String(taskId)}`, {
15237
15226
  });
15238
15227
  if (!prompt.ok) return Result.error(prompt.error);
15239
15228
  await writeRoundPrompt(input.workspaceRoot, input.roundNum, "evaluator", String(prompt.value), deps.logger);
15240
- const spawn3 = await deps.provider.generate(
15229
+ const spawn2 = await deps.provider.generate(
15241
15230
  implementSession(
15242
15231
  input.workspaceRoot,
15243
15232
  deps.cwd,
@@ -15250,7 +15239,7 @@ var evaluatorLeaf = (deps, taskId) => leaf(`evaluator-${String(taskId)}`, {
15250
15239
  deps.effort
15251
15240
  )
15252
15241
  );
15253
- if (!spawn3.ok) return Result.error(spawn3.error);
15242
+ if (!spawn2.ok) return Result.error(spawn2.error);
15254
15243
  const validated = await validateSignalsFile(outputDir, evaluatorOutputContract);
15255
15244
  if (!validated.ok) return Result.error(validated.error);
15256
15245
  const signals = validated.value;
@@ -15456,7 +15445,7 @@ var generatorLeaf = (deps, taskId) => leaf(`generator-${String(taskId)}`, {
15456
15445
  if (!prompt.ok) return Result.error(prompt.error);
15457
15446
  await writeRoundPrompt(input.workspaceRoot, roundNum, "generator", String(prompt.value), deps.logger);
15458
15447
  const effectiveModel = task.escalatedToModel ?? deps.model;
15459
- const spawn3 = await deps.provider.generate(
15448
+ const spawn2 = await deps.provider.generate(
15460
15449
  implementSession(
15461
15450
  input.workspaceRoot,
15462
15451
  deps.cwd,
@@ -15469,7 +15458,7 @@ var generatorLeaf = (deps, taskId) => leaf(`generator-${String(taskId)}`, {
15469
15458
  deps.effort
15470
15459
  )
15471
15460
  );
15472
- if (!spawn3.ok) return Result.error(spawn3.error);
15461
+ if (!spawn2.ok) return Result.error(spawn2.error);
15473
15462
  const validated = await validateSignalsFile(outputDir, generatorOutputContract);
15474
15463
  if (!validated.ok) return Result.error(validated.error);
15475
15464
  const signals = validated.value;
@@ -18424,7 +18413,7 @@ var reviewRoundLeaf = (deps, opts) => leaf("review-round", {
18424
18413
  }
18425
18414
  const promptWrote = await writeTextAtomic(String(paths.value.promptFile), String(prompt));
18426
18415
  if (!promptWrote.ok) return Result.error(promptWrote.error);
18427
- const spawn3 = await deps.provider.generate({
18416
+ const spawn2 = await deps.provider.generate({
18428
18417
  prompt,
18429
18418
  cwd: paths.value.outputDir,
18430
18419
  additionalRoots: opts.additionalRoots,
@@ -18433,7 +18422,7 @@ var reviewRoundLeaf = (deps, opts) => leaf("review-round", {
18433
18422
  signalsFile: paths.value.signalsFile,
18434
18423
  outputDir: paths.value.outputDir
18435
18424
  });
18436
- if (!spawn3.ok) return Result.error(spawn3.error);
18425
+ if (!spawn2.ok) return Result.error(spawn2.error);
18437
18426
  const validated = await validateSignalsFile(paths.value.outputDir, reviewRoundOutputContract);
18438
18427
  if (!validated.ok) return Result.error(validated.error);
18439
18428
  for (const sig of validated.value) {
@@ -19747,7 +19736,7 @@ var proposeUseCase = async (deps, input) => {
19747
19736
  if (!prompt.ok) return Result.error(prompt.error);
19748
19737
  const promptWrote = await writeTextAtomic(String(paths.value.promptFile), String(prompt.value));
19749
19738
  if (!promptWrote.ok) return Result.error(promptWrote.error);
19750
- const spawn3 = await deps.provider.generate(
19739
+ const spawn2 = await deps.provider.generate(
19751
19740
  detectSkillsSession(
19752
19741
  input.repository,
19753
19742
  prompt.value,
@@ -19758,13 +19747,13 @@ var proposeUseCase = async (deps, input) => {
19758
19747
  deps.effort
19759
19748
  )
19760
19749
  );
19761
- if (!spawn3.ok) {
19750
+ if (!spawn2.ok) {
19762
19751
  log.error(`provider failed for repo ${input.repository.name}`, {
19763
19752
  repositoryId: String(input.repository.id),
19764
- error: spawn3.error.message,
19753
+ error: spawn2.error.message,
19765
19754
  runDir: String(paths.value.runDir)
19766
19755
  });
19767
- return Result.error(spawn3.error);
19756
+ return Result.error(spawn2.error);
19768
19757
  }
19769
19758
  const validated = await validateSignalsFile(paths.value.runDir, detectSkillsOutputContract);
19770
19759
  if (!validated.ok) {
@@ -20505,7 +20494,7 @@ var proposeUseCase2 = async (deps, input) => {
20505
20494
  if (!prompt.ok) return Result.error(prompt.error);
20506
20495
  const promptWrote = await writeTextAtomic(String(paths.value.promptFile), String(prompt.value));
20507
20496
  if (!promptWrote.ok) return Result.error(promptWrote.error);
20508
- const spawn3 = await deps.provider.generate(
20497
+ const spawn2 = await deps.provider.generate(
20509
20498
  detectScriptsSession(
20510
20499
  input.repository,
20511
20500
  prompt.value,
@@ -20516,13 +20505,13 @@ var proposeUseCase2 = async (deps, input) => {
20516
20505
  deps.effort
20517
20506
  )
20518
20507
  );
20519
- if (!spawn3.ok) {
20508
+ if (!spawn2.ok) {
20520
20509
  log.error(`provider failed for repo ${input.repository.name}`, {
20521
20510
  repositoryId: String(input.repository.id),
20522
- error: spawn3.error.message,
20511
+ error: spawn2.error.message,
20523
20512
  runDir: String(paths.value.runDir)
20524
20513
  });
20525
- return Result.error(spawn3.error);
20514
+ return Result.error(spawn2.error);
20526
20515
  }
20527
20516
  const validated = await validateSignalsFile(paths.value.runDir, detectScriptsOutputContract);
20528
20517
  if (!validated.ok) {
@@ -28429,9 +28418,9 @@ var generatePrContentLeaf = (deps) => leaf("generate-pr-content", {
28429
28418
  outputDir: input.unitRoot
28430
28419
  };
28431
28420
  try {
28432
- const spawn3 = await deps.provider.generate(session);
28433
- if (!spawn3.ok) {
28434
- deps.logger.named("create-pr.ai").warn(`create-pr: AI authoring failed, falling back to template (${spawn3.error.message})`);
28421
+ const spawn2 = await deps.provider.generate(session);
28422
+ if (!spawn2.ok) {
28423
+ deps.logger.named("create-pr.ai").warn(`create-pr: AI authoring failed, falling back to template (${spawn2.error.message})`);
28435
28424
  return Result.ok({});
28436
28425
  }
28437
28426
  const validated = await validateSignalsFile(input.unitRoot, generatePrContentOutputContract);
@@ -30243,10 +30232,10 @@ var resolveHelpers = ({ platform, env }) => {
30243
30232
  }
30244
30233
  return [];
30245
30234
  };
30246
- var runHelper = (spawn3, helper, text) => new Promise((resolve) => {
30235
+ var runHelper = (spawn2, helper, text) => new Promise((resolve) => {
30247
30236
  let child;
30248
30237
  try {
30249
- child = spawn3(helper.cmd, helper.args, { stdio: ["pipe", "pipe", "pipe"] });
30238
+ child = spawn2(helper.cmd, helper.args, { stdio: ["pipe", "pipe", "pipe"] });
30250
30239
  } catch (cause) {
30251
30240
  resolve(
30252
30241
  Result.error({
@@ -30290,7 +30279,7 @@ var runHelper = (spawn3, helper, text) => new Promise((resolve) => {
30290
30279
  }
30291
30280
  });
30292
30281
  var createCopyToClipboard = (opts = {}) => {
30293
- const spawn3 = opts.spawn ?? nodeSpawn10;
30282
+ const spawn2 = opts.spawn ?? nodeSpawn10;
30294
30283
  const platform = opts.platform ?? process.platform;
30295
30284
  const env = opts.env ?? process.env;
30296
30285
  const helpers = resolveHelpers({ platform, env });
@@ -30303,7 +30292,7 @@ var createCopyToClipboard = (opts = {}) => {
30303
30292
  }
30304
30293
  let lastError;
30305
30294
  for (const helper of helpers) {
30306
- const result = await runHelper(spawn3, helper, text);
30295
+ const result = await runHelper(spawn2, helper, text);
30307
30296
  if (result.ok) return result;
30308
30297
  lastError = result.error;
30309
30298
  if (result.error.code !== "no-helper") return result;
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "version": 1,
3
- "generatedAt": "2026-05-28T21:15:32.467Z",
3
+ "generatedAt": "2026-05-29T08:41:52.856Z",
4
4
  "assets": [
5
5
  "prompts/_partials/conventions-agents-md.md",
6
6
  "prompts/_partials/conventions-claude-md.md",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ralphctl",
3
- "version": "0.8.4",
3
+ "version": "0.8.5",
4
4
  "description": "Agent harness for long-running AI coding tasks — orchestrates Claude Code, GitHub Copilot, and OpenAI Codex across repositories",
5
5
  "homepage": "https://github.com/lukas-grigis/ralphctl",
6
6
  "type": "module",