@neriros/ralphy 2.10.2 → 2.11.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/dist/cli/index.js +64 -28
- package/package.json +1 -1
package/dist/cli/index.js
CHANGED
|
@@ -50837,8 +50837,8 @@ var require_axios = __commonJS((exports, module) => {
|
|
|
50837
50837
|
});
|
|
50838
50838
|
|
|
50839
50839
|
// apps/cli/src/index.ts
|
|
50840
|
-
import { resolve, join as join17, dirname as
|
|
50841
|
-
import { exists as exists2, mkdir as
|
|
50840
|
+
import { resolve, join as join17, dirname as dirname5 } from "path";
|
|
50841
|
+
import { exists as exists2, mkdir as mkdir4, rm } from "fs/promises";
|
|
50842
50842
|
|
|
50843
50843
|
// node_modules/.bun/ink@5.2.1+1f88f629f0141b18/node_modules/ink/build/render.js
|
|
50844
50844
|
import { Stream } from "stream";
|
|
@@ -56407,7 +56407,7 @@ function log(msg) {
|
|
|
56407
56407
|
// package.json
|
|
56408
56408
|
var package_default = {
|
|
56409
56409
|
name: "@neriros/ralphy",
|
|
56410
|
-
version: "2.
|
|
56410
|
+
version: "2.11.0",
|
|
56411
56411
|
description: "An iterative AI task execution framework. Orchestrates multi-phase autonomous work using Claude or Codex engines.",
|
|
56412
56412
|
keywords: [
|
|
56413
56413
|
"agent",
|
|
@@ -64894,7 +64894,9 @@ var {spawn: bunSpawn } = globalThis.Bun;
|
|
|
64894
64894
|
var spawn = bunSpawn;
|
|
64895
64895
|
|
|
64896
64896
|
// packages/engine/src/engine.ts
|
|
64897
|
-
import {
|
|
64897
|
+
import { createWriteStream } from "fs";
|
|
64898
|
+
import { mkdtemp, unlink, mkdir } from "fs/promises";
|
|
64899
|
+
import { dirname as dirname2 } from "path";
|
|
64898
64900
|
import { join as join5 } from "path";
|
|
64899
64901
|
import { tmpdir } from "os";
|
|
64900
64902
|
|
|
@@ -65711,6 +65713,21 @@ async function runEngine(opts) {
|
|
|
65711
65713
|
stdin.write(new TextEncoder().encode(prompt));
|
|
65712
65714
|
await stdin.flush();
|
|
65713
65715
|
stdin.end();
|
|
65716
|
+
let rawWriter = null;
|
|
65717
|
+
if (opts.logFlag && opts.logFile) {
|
|
65718
|
+
await mkdir(dirname2(opts.logFile), { recursive: true });
|
|
65719
|
+
rawWriter = createWriteStream(opts.logFile, { flags: "a" });
|
|
65720
|
+
}
|
|
65721
|
+
const writeRaw = (line) => {
|
|
65722
|
+
if (rawWriter)
|
|
65723
|
+
rawWriter.write(line + `
|
|
65724
|
+
`);
|
|
65725
|
+
};
|
|
65726
|
+
const closeRaw = () => new Promise((resolve) => {
|
|
65727
|
+
if (!rawWriter)
|
|
65728
|
+
return resolve();
|
|
65729
|
+
rawWriter.end(resolve);
|
|
65730
|
+
});
|
|
65714
65731
|
const emit = opts.onFeedEvent;
|
|
65715
65732
|
function emitEvent(event) {
|
|
65716
65733
|
if (emit) {
|
|
@@ -65745,6 +65762,7 @@ async function runEngine(opts) {
|
|
|
65745
65762
|
usage: null
|
|
65746
65763
|
};
|
|
65747
65764
|
for await (const line of streamLines(stdout)) {
|
|
65765
|
+
writeRaw(line);
|
|
65748
65766
|
if (sessionId === null) {
|
|
65749
65767
|
try {
|
|
65750
65768
|
const parsed = JSON.parse(line);
|
|
@@ -65772,6 +65790,7 @@ async function runEngine(opts) {
|
|
|
65772
65790
|
pendingTools: 0
|
|
65773
65791
|
};
|
|
65774
65792
|
for await (const line of streamLines(stdout)) {
|
|
65793
|
+
writeRaw(line);
|
|
65775
65794
|
for (const event of parseCodexLine(line, codexState)) {
|
|
65776
65795
|
emitEvent(event);
|
|
65777
65796
|
}
|
|
@@ -65779,12 +65798,14 @@ async function runEngine(opts) {
|
|
|
65779
65798
|
if (proc.stderr) {
|
|
65780
65799
|
const stderr = proc.stderr;
|
|
65781
65800
|
for await (const line of streamLines(stderr)) {
|
|
65801
|
+
writeRaw(line);
|
|
65782
65802
|
for (const event of parseCodexLine(line, codexState)) {
|
|
65783
65803
|
emitEvent(event);
|
|
65784
65804
|
}
|
|
65785
65805
|
}
|
|
65786
65806
|
}
|
|
65787
65807
|
}
|
|
65808
|
+
await closeRaw();
|
|
65788
65809
|
const exitCode = await proc.exited;
|
|
65789
65810
|
const wasIntentionalKill = (exitCode === 143 || exitCode === 137) && (usage !== null || aborted);
|
|
65790
65811
|
const normalizedExitCode = wasIntentionalKill ? 0 : exitCode;
|
|
@@ -65843,7 +65864,7 @@ function commitTaskDir(taskDir, message) {
|
|
|
65843
65864
|
}
|
|
65844
65865
|
|
|
65845
65866
|
// node_modules/.bun/posthog-node@4.18.0/node_modules/posthog-node/lib/node/index.mjs
|
|
65846
|
-
import { posix, dirname as
|
|
65867
|
+
import { posix, dirname as dirname3, sep } from "path";
|
|
65847
65868
|
import { createReadStream } from "fs";
|
|
65848
65869
|
import { createInterface } from "readline";
|
|
65849
65870
|
var NAME = "posthog-node";
|
|
@@ -66423,7 +66444,7 @@ class ErrorTracking {
|
|
|
66423
66444
|
return !this.client.isDisabled && this._exceptionAutocaptureEnabled;
|
|
66424
66445
|
}
|
|
66425
66446
|
}
|
|
66426
|
-
function createGetModuleFromFilename(basePath = process.argv[1] ?
|
|
66447
|
+
function createGetModuleFromFilename(basePath = process.argv[1] ? dirname3(process.argv[1]) : process.cwd(), isWindows3 = sep === "\\") {
|
|
66427
66448
|
const normalizedBase = isWindows3 ? normalizeWindowsPath(basePath) : basePath;
|
|
66428
66449
|
return (filename) => {
|
|
66429
66450
|
if (!filename) {
|
|
@@ -69460,11 +69481,16 @@ var STEERING_MAX_LINES = 20;
|
|
|
69460
69481
|
function extractFirstUncheckedSection(tasksContent) {
|
|
69461
69482
|
const sections = tasksContent.split(/(?=^## )/m);
|
|
69462
69483
|
for (const section of sections) {
|
|
69463
|
-
if (/^- \[ \]/m.test(section))
|
|
69484
|
+
if (/^## /m.test(section) && /^- \[ \]/m.test(section))
|
|
69464
69485
|
return section.trim();
|
|
69465
69486
|
}
|
|
69487
|
+
if (/^- \[ \]/m.test(tasksContent))
|
|
69488
|
+
return tasksContent.trim();
|
|
69466
69489
|
return null;
|
|
69467
69490
|
}
|
|
69491
|
+
function countUncheckedTasks(tasksContent) {
|
|
69492
|
+
return (tasksContent.match(/^- \[ \]/gm) ?? []).length;
|
|
69493
|
+
}
|
|
69468
69494
|
function allTasksCompleted(tasksContent) {
|
|
69469
69495
|
return !/^- \[ \]/m.test(tasksContent);
|
|
69470
69496
|
}
|
|
@@ -69504,6 +69530,9 @@ function buildTaskPrompt(state, taskDir) {
|
|
|
69504
69530
|
`;
|
|
69505
69531
|
prompt += `---
|
|
69506
69532
|
|
|
69533
|
+
`;
|
|
69534
|
+
prompt += `**Tracking progress**: as you finish each item above, edit ` + `\`${join7(taskDir, "tasks.md")}\` and change its \`- [ ]\` to ` + `\`- [x]\` in the same commit. The loop reads this file between ` + `iterations and stops when no \`- [ ]\` items remain \u2014 if you do ` + `not tick the box, the next iteration will repeat this task.
|
|
69535
|
+
|
|
69507
69536
|
`;
|
|
69508
69537
|
}
|
|
69509
69538
|
} else if (state.prompt) {
|
|
@@ -69723,6 +69752,10 @@ function useLoop(opts) {
|
|
|
69723
69752
|
break;
|
|
69724
69753
|
}
|
|
69725
69754
|
const tasksContent = storage.read(join8(tasksDir, "tasks.md"));
|
|
69755
|
+
if (tasksContent !== null) {
|
|
69756
|
+
const remaining = countUncheckedTasks(tasksContent);
|
|
69757
|
+
addInfo(`tasks.md: ${remaining} unchecked item${remaining === 1 ? "" : "s"} remaining`);
|
|
69758
|
+
}
|
|
69726
69759
|
if (tasksContent !== null && allTasksCompleted(tasksContent)) {
|
|
69727
69760
|
addInfo("All tasks completed \u2014 archiving change.");
|
|
69728
69761
|
currentState = {
|
|
@@ -69758,6 +69791,7 @@ function useLoop(opts) {
|
|
|
69758
69791
|
model: opts.model,
|
|
69759
69792
|
prompt,
|
|
69760
69793
|
logFlag: opts.log,
|
|
69794
|
+
logFile: join8(stateDir, "log.json"),
|
|
69761
69795
|
taskDir: tasksDir,
|
|
69762
69796
|
interactive: false,
|
|
69763
69797
|
onFeedEvent: addFeedEvent,
|
|
@@ -69780,6 +69814,7 @@ function useLoop(opts) {
|
|
|
69780
69814
|
model: opts.model,
|
|
69781
69815
|
prompt: buildSteeringPrompt(steerMessage),
|
|
69782
69816
|
logFlag: opts.log,
|
|
69817
|
+
logFile: join8(stateDir, "log.json"),
|
|
69783
69818
|
taskDir: tasksDir,
|
|
69784
69819
|
onFeedEvent: addResumeFeedEvent,
|
|
69785
69820
|
signal: resumeController.signal,
|
|
@@ -70262,7 +70297,7 @@ async function writeAgentState(projectRoot, state) {
|
|
|
70262
70297
|
|
|
70263
70298
|
// apps/cli/src/agent/scaffold.ts
|
|
70264
70299
|
import { join as join11 } from "path";
|
|
70265
|
-
import { mkdir } from "fs/promises";
|
|
70300
|
+
import { mkdir as mkdir2 } from "fs/promises";
|
|
70266
70301
|
function changeNameForIssue(issue) {
|
|
70267
70302
|
const slug = issue.title.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "").slice(0, 40);
|
|
70268
70303
|
return slug ? `${issue.identifier.toLowerCase()}-${slug}` : issue.identifier.toLowerCase();
|
|
@@ -70271,9 +70306,9 @@ async function scaffoldChangeForIssue(tasksDir, statesDir, issue, comments = [],
|
|
|
70271
70306
|
const name = changeNameForIssue(issue);
|
|
70272
70307
|
const changeDir = join11(tasksDir, name);
|
|
70273
70308
|
const stateDir = join11(statesDir, name);
|
|
70274
|
-
await
|
|
70275
|
-
await
|
|
70276
|
-
await
|
|
70309
|
+
await mkdir2(changeDir, { recursive: true });
|
|
70310
|
+
await mkdir2(join11(changeDir, "specs"), { recursive: true });
|
|
70311
|
+
await mkdir2(stateDir, { recursive: true });
|
|
70277
70312
|
const commentsBlock = comments.length > 0 ? [
|
|
70278
70313
|
"",
|
|
70279
70314
|
"## Linear comments",
|
|
@@ -70308,6 +70343,8 @@ async function scaffoldChangeForIssue(tasksDir, statesDir, issue, comments = [],
|
|
|
70308
70343
|
const tasks = [
|
|
70309
70344
|
`# Tasks for ${issue.identifier}`,
|
|
70310
70345
|
"",
|
|
70346
|
+
"## Subtasks",
|
|
70347
|
+
"",
|
|
70311
70348
|
`- [ ] Read the Linear issue at ${issue.url} and break it into concrete subtasks`,
|
|
70312
70349
|
`- [ ] Implement the changes described in proposal.md`,
|
|
70313
70350
|
`- [ ] Add or update tests covering the new behavior`,
|
|
@@ -70851,15 +70888,14 @@ var jsx_dev_runtime9 = __toESM(require_jsx_dev_runtime(), 1);
|
|
|
70851
70888
|
import { join as join14 } from "path";
|
|
70852
70889
|
import { exists } from "fs/promises";
|
|
70853
70890
|
async function seedWorktreeMcpConfig(projectRoot, worktreeCwd) {
|
|
70854
|
-
const src = join14(projectRoot, ".mcp.json");
|
|
70855
|
-
if (!await exists(src))
|
|
70856
|
-
return;
|
|
70857
70891
|
const dst = join14(worktreeCwd, ".mcp.json");
|
|
70858
|
-
|
|
70892
|
+
const src = join14(projectRoot, ".mcp.json");
|
|
70893
|
+
const source = await exists(dst) ? dst : await exists(src) ? src : null;
|
|
70894
|
+
if (!source)
|
|
70859
70895
|
return;
|
|
70860
70896
|
let parsed;
|
|
70861
70897
|
try {
|
|
70862
|
-
parsed = await Bun.file(
|
|
70898
|
+
parsed = await Bun.file(source).json();
|
|
70863
70899
|
} catch {
|
|
70864
70900
|
return;
|
|
70865
70901
|
}
|
|
@@ -71480,11 +71516,11 @@ ${check.unpushedCommits}`, "yellow");
|
|
|
71480
71516
|
}
|
|
71481
71517
|
|
|
71482
71518
|
// packages/openspec/src/openspec-change-store.ts
|
|
71483
|
-
import { join as join15, dirname as
|
|
71484
|
-
import { readdir, mkdir as
|
|
71519
|
+
import { join as join15, dirname as dirname4 } from "path";
|
|
71520
|
+
import { readdir, mkdir as mkdir3 } from "fs/promises";
|
|
71485
71521
|
function resolveOpenspecBin() {
|
|
71486
71522
|
const pkgJsonPath = Bun.resolveSync("@fission-ai/openspec/package.json", import.meta.dir);
|
|
71487
|
-
return join15(
|
|
71523
|
+
return join15(dirname4(pkgJsonPath), "bin", "openspec.js");
|
|
71488
71524
|
}
|
|
71489
71525
|
function runOpenspec(args, options = {}) {
|
|
71490
71526
|
const stdio = options.inherit ? ["inherit", "inherit", "inherit"] : ["ignore", "pipe", "pipe"];
|
|
@@ -71542,7 +71578,7 @@ class OpenSpecChangeStore {
|
|
|
71542
71578
|
}
|
|
71543
71579
|
async writeTaskList(name, content) {
|
|
71544
71580
|
const path = join15("openspec", "changes", name, "tasks.md");
|
|
71545
|
-
await
|
|
71581
|
+
await mkdir3(dirname4(path), { recursive: true });
|
|
71546
71582
|
await Bun.write(path, content);
|
|
71547
71583
|
}
|
|
71548
71584
|
async appendSteering(name, message) {
|
|
@@ -71553,7 +71589,7 @@ class OpenSpecChangeStore {
|
|
|
71553
71589
|
|
|
71554
71590
|
${existing.trimStart()}` : `${message}
|
|
71555
71591
|
`;
|
|
71556
|
-
await
|
|
71592
|
+
await mkdir3(dirname4(path), { recursive: true });
|
|
71557
71593
|
await Bun.write(path, updated);
|
|
71558
71594
|
}
|
|
71559
71595
|
async readSection(name, artifact, heading) {
|
|
@@ -71739,8 +71775,8 @@ try {
|
|
|
71739
71775
|
const statesDir = join17(projectRoot, ".ralph", "tasks");
|
|
71740
71776
|
const tasksDir = join17(projectRoot, "openspec", "changes");
|
|
71741
71777
|
if (args.mode === "init") {
|
|
71742
|
-
await
|
|
71743
|
-
const openspecBin = join17(
|
|
71778
|
+
await mkdir4(statesDir, { recursive: true });
|
|
71779
|
+
const openspecBin = join17(dirname5(Bun.resolveSync("@fission-ai/openspec/package.json", import.meta.dir)), "bin", "openspec.js");
|
|
71744
71780
|
Bun.spawnSync({
|
|
71745
71781
|
cmd: [process.execPath, openspecBin, "init", "--tools", "none", "--force"],
|
|
71746
71782
|
stdio: ["inherit", "inherit", "inherit"],
|
|
@@ -71816,13 +71852,13 @@ try {
|
|
|
71816
71852
|
process.exit(0);
|
|
71817
71853
|
}
|
|
71818
71854
|
if (args.mode === "task" && args.name) {
|
|
71819
|
-
await
|
|
71820
|
-
await
|
|
71855
|
+
await mkdir4(join17(statesDir, args.name), { recursive: true });
|
|
71856
|
+
await mkdir4(join17(tasksDir, args.name), { recursive: true });
|
|
71821
71857
|
}
|
|
71822
71858
|
if (args.mode === "agent") {
|
|
71823
|
-
await
|
|
71824
|
-
await
|
|
71825
|
-
await
|
|
71859
|
+
await mkdir4(statesDir, { recursive: true });
|
|
71860
|
+
await mkdir4(tasksDir, { recursive: true });
|
|
71861
|
+
await mkdir4(join17(projectRoot, ".ralph"), { recursive: true });
|
|
71826
71862
|
}
|
|
71827
71863
|
await runWithContext(createDefaultContext(), async () => {
|
|
71828
71864
|
const { waitUntilExit } = render_default(import_react59.createElement(App2, { args, statesDir, tasksDir, projectRoot }));
|