@neriros/ralphy 3.10.6 → 3.10.8
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/mcp/index.js +75 -39
- package/dist/shell/index.js +493 -281
- package/package.json +1 -1
package/dist/mcp/index.js
CHANGED
|
@@ -6605,7 +6605,7 @@ var require_dist = __commonJS((exports, module) => {
|
|
|
6605
6605
|
});
|
|
6606
6606
|
|
|
6607
6607
|
// apps/mcp/src/index.ts
|
|
6608
|
-
import { resolve, join as
|
|
6608
|
+
import { resolve, join as join6 } from "path";
|
|
6609
6609
|
import { exists } from "fs/promises";
|
|
6610
6610
|
|
|
6611
6611
|
// packages/context/src/context.ts
|
|
@@ -20045,7 +20045,7 @@ class StdioServerTransport {
|
|
|
20045
20045
|
}
|
|
20046
20046
|
|
|
20047
20047
|
// apps/mcp/src/tools.ts
|
|
20048
|
-
import { join as
|
|
20048
|
+
import { join as join3 } from "path";
|
|
20049
20049
|
|
|
20050
20050
|
// node_modules/.bun/zod@3.25.76/node_modules/zod/v3/external.js
|
|
20051
20051
|
var exports_external = {};
|
|
@@ -24032,8 +24032,35 @@ var OWNERSHIP = {
|
|
|
24032
24032
|
};
|
|
24033
24033
|
var ALL_OWNED_SLOTS = new Set(Object.values(OWNERSHIP).flatMap((slots) => [...slots]));
|
|
24034
24034
|
|
|
24035
|
+
// packages/core/src/state/sidecar.ts
|
|
24036
|
+
import { dirname as dirname2, join } from "path";
|
|
24037
|
+
var CORE_STATE_FILE = ".ralph-state.json";
|
|
24038
|
+
function slotSidecarPath(changeDir, slot) {
|
|
24039
|
+
return join(changeDir, `${CORE_STATE_FILE.replace(/\.json$/, "")}.${slot}.json`);
|
|
24040
|
+
}
|
|
24041
|
+
function parseObject(text) {
|
|
24042
|
+
if (text === null)
|
|
24043
|
+
return null;
|
|
24044
|
+
try {
|
|
24045
|
+
const parsed = JSON.parse(text);
|
|
24046
|
+
if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
|
|
24047
|
+
return parsed;
|
|
24048
|
+
}
|
|
24049
|
+
return null;
|
|
24050
|
+
} catch {
|
|
24051
|
+
return null;
|
|
24052
|
+
}
|
|
24053
|
+
}
|
|
24054
|
+
function overlaySidecarsSync(changeDir, target, read) {
|
|
24055
|
+
for (const slot of ALL_OWNED_SLOTS) {
|
|
24056
|
+
const obj = parseObject(read(slotSidecarPath(changeDir, slot)));
|
|
24057
|
+
if (obj !== undefined && obj !== null)
|
|
24058
|
+
target[slot] = obj;
|
|
24059
|
+
}
|
|
24060
|
+
return target;
|
|
24061
|
+
}
|
|
24035
24062
|
// packages/core/src/state.ts
|
|
24036
|
-
import { join } from "path";
|
|
24063
|
+
import { join as join2 } from "path";
|
|
24037
24064
|
|
|
24038
24065
|
// packages/types/src/types.ts
|
|
24039
24066
|
var IterationUsageSchema = exports_external.object({
|
|
@@ -24166,16 +24193,25 @@ function formatTaskName(name) {
|
|
|
24166
24193
|
|
|
24167
24194
|
// packages/core/src/state.ts
|
|
24168
24195
|
var STATE_FILE = ".ralph-state.json";
|
|
24196
|
+
function stripOwnedSlots(state) {
|
|
24197
|
+
const out = { ...state };
|
|
24198
|
+
for (const slot of ALL_OWNED_SLOTS)
|
|
24199
|
+
delete out[slot];
|
|
24200
|
+
return out;
|
|
24201
|
+
}
|
|
24169
24202
|
function readState(changeDir) {
|
|
24170
|
-
const filePath =
|
|
24203
|
+
const filePath = join2(changeDir, STATE_FILE);
|
|
24171
24204
|
const raw = getStorage().read(filePath);
|
|
24172
24205
|
if (raw === null)
|
|
24173
24206
|
throw new Error(".ralph-state.json not found");
|
|
24174
|
-
|
|
24207
|
+
const base = JSON.parse(raw);
|
|
24208
|
+
overlaySidecarsSync(changeDir, base, (p) => getStorage().read(p));
|
|
24209
|
+
return StateSchema.parse(base);
|
|
24175
24210
|
}
|
|
24176
24211
|
function writeState(changeDir, state) {
|
|
24177
|
-
const filePath =
|
|
24178
|
-
|
|
24212
|
+
const filePath = join2(changeDir, STATE_FILE);
|
|
24213
|
+
const core2 = stripOwnedSlots(state);
|
|
24214
|
+
getStorage().write(filePath, JSON.stringify(core2, null, 2) + `
|
|
24179
24215
|
`);
|
|
24180
24216
|
}
|
|
24181
24217
|
function buildInitialState(options) {
|
|
@@ -24224,7 +24260,7 @@ function registerTools(server, changesDir, changeStore, taskFilesDir = changesDi
|
|
|
24224
24260
|
const names = await changeStore.listChanges();
|
|
24225
24261
|
const changes = [];
|
|
24226
24262
|
for (const name of names) {
|
|
24227
|
-
const changeDir =
|
|
24263
|
+
const changeDir = join3(changesDir, name);
|
|
24228
24264
|
try {
|
|
24229
24265
|
const state = readState(changeDir);
|
|
24230
24266
|
if (!includeCompleted && state.status === "completed")
|
|
@@ -24239,7 +24275,7 @@ function registerTools(server, changesDir, changeStore, taskFilesDir = changesDi
|
|
|
24239
24275
|
lastModified: state.lastModified
|
|
24240
24276
|
});
|
|
24241
24277
|
} catch {
|
|
24242
|
-
const stateRaw = storage.read(
|
|
24278
|
+
const stateRaw = storage.read(join3(changeDir, ".ralph-state.json"));
|
|
24243
24279
|
if (stateRaw !== null) {
|
|
24244
24280
|
changes.push({ name, status: "unknown" });
|
|
24245
24281
|
}
|
|
@@ -24268,11 +24304,11 @@ function registerTools(server, changesDir, changeStore, taskFilesDir = changesDi
|
|
|
24268
24304
|
return runWithContext(createDefaultContext(), () => {
|
|
24269
24305
|
try {
|
|
24270
24306
|
const storage = getStorage();
|
|
24271
|
-
const changeDir =
|
|
24307
|
+
const changeDir = join3(changesDir, name);
|
|
24272
24308
|
const state = readState(changeDir);
|
|
24273
|
-
const taskDir =
|
|
24274
|
-
const tasksContent = storage.read(
|
|
24275
|
-
const proposalContent = storage.read(
|
|
24309
|
+
const taskDir = join3(taskFilesDir, name);
|
|
24310
|
+
const tasksContent = storage.read(join3(taskDir, "tasks.md"));
|
|
24311
|
+
const proposalContent = storage.read(join3(taskDir, "proposal.md"));
|
|
24276
24312
|
const result = {
|
|
24277
24313
|
name: state.name,
|
|
24278
24314
|
prompt: state.prompt,
|
|
@@ -24316,8 +24352,8 @@ function registerTools(server, changesDir, changeStore, taskFilesDir = changesDi
|
|
|
24316
24352
|
}, async ({ name, prompt, engine, model, run, maxIterations, maxCostUsd, maxRuntimeMinutes }) => {
|
|
24317
24353
|
return runWithContext(createDefaultContext(), () => {
|
|
24318
24354
|
try {
|
|
24319
|
-
const changeDir =
|
|
24320
|
-
const stateExists = getStorage().read(
|
|
24355
|
+
const changeDir = join3(changesDir, name);
|
|
24356
|
+
const stateExists = getStorage().read(join3(changeDir, ".ralph-state.json")) !== null;
|
|
24321
24357
|
if (!stateExists) {
|
|
24322
24358
|
const state = buildInitialState({
|
|
24323
24359
|
name,
|
|
@@ -24328,7 +24364,7 @@ function registerTools(server, changesDir, changeStore, taskFilesDir = changesDi
|
|
|
24328
24364
|
writeState(changeDir, state);
|
|
24329
24365
|
}
|
|
24330
24366
|
if (!run) {
|
|
24331
|
-
const taskFilesPath =
|
|
24367
|
+
const taskFilesPath = join3(taskFilesDir, name);
|
|
24332
24368
|
return {
|
|
24333
24369
|
content: [
|
|
24334
24370
|
{
|
|
@@ -24391,8 +24427,8 @@ function registerTools(server, changesDir, changeStore, taskFilesDir = changesDi
|
|
|
24391
24427
|
}, async ({ name, message }) => {
|
|
24392
24428
|
return runWithContext(createDefaultContext(), async () => {
|
|
24393
24429
|
try {
|
|
24394
|
-
const changeDir =
|
|
24395
|
-
if (getStorage().read(
|
|
24430
|
+
const changeDir = join3(changesDir, name);
|
|
24431
|
+
if (getStorage().read(join3(changeDir, ".ralph-state.json")) === null) {
|
|
24396
24432
|
return {
|
|
24397
24433
|
content: [{ type: "text", text: `Change '${name}' does not exist` }],
|
|
24398
24434
|
isError: true
|
|
@@ -24432,8 +24468,8 @@ function registerTools(server, changesDir, changeStore, taskFilesDir = changesDi
|
|
|
24432
24468
|
}, async ({ name, reason }) => {
|
|
24433
24469
|
return runWithContext(createDefaultContext(), () => {
|
|
24434
24470
|
try {
|
|
24435
|
-
const taskDir =
|
|
24436
|
-
getStorage().write(
|
|
24471
|
+
const taskDir = join3(taskFilesDir, name);
|
|
24472
|
+
getStorage().write(join3(taskDir, "STOP"), reason ?? "Stopped via MCP");
|
|
24437
24473
|
return {
|
|
24438
24474
|
content: [{ type: "text", text: `Stop signal written for change '${name}'` }]
|
|
24439
24475
|
};
|
|
@@ -24987,11 +25023,11 @@ function error2(msg) {
|
|
|
24987
25023
|
}
|
|
24988
25024
|
|
|
24989
25025
|
// packages/openspec/src/openspec-change-store.ts
|
|
24990
|
-
import { dirname as
|
|
25026
|
+
import { dirname as dirname4, join as join5 } from "path";
|
|
24991
25027
|
import { readdir, mkdir } from "fs/promises";
|
|
24992
25028
|
|
|
24993
25029
|
// packages/openspec/src/openspec-bin.ts
|
|
24994
|
-
import { dirname as
|
|
25030
|
+
import { dirname as dirname3, join as join4 } from "path";
|
|
24995
25031
|
var bunInstallRunner = {
|
|
24996
25032
|
spawnSync: (cmd, cwd) => {
|
|
24997
25033
|
const proc = Bun.spawnSync({
|
|
@@ -25009,13 +25045,13 @@ var bunInstallRunner = {
|
|
|
25009
25045
|
function findPackageRoot(startDir) {
|
|
25010
25046
|
let dir = startDir;
|
|
25011
25047
|
for (let i = 0;i < 8; i++) {
|
|
25012
|
-
if (Bun.file(
|
|
25048
|
+
if (Bun.file(join4(dir, "package.json")).size >= 0) {
|
|
25013
25049
|
try {
|
|
25014
|
-
if (Bun.file(
|
|
25050
|
+
if (Bun.file(join4(dir, "package.json")).size > 0)
|
|
25015
25051
|
return dir;
|
|
25016
25052
|
} catch {}
|
|
25017
25053
|
}
|
|
25018
|
-
const parent =
|
|
25054
|
+
const parent = dirname3(dir);
|
|
25019
25055
|
if (parent === dir)
|
|
25020
25056
|
break;
|
|
25021
25057
|
dir = parent;
|
|
@@ -25047,11 +25083,11 @@ function ensureOpenspecInstalled(fromDir, runner) {
|
|
|
25047
25083
|
function resolveOpenspecBin(fromDir, runner = bunInstallRunner) {
|
|
25048
25084
|
try {
|
|
25049
25085
|
const pkgJsonPath = runner.resolveSync("@fission-ai/openspec/package.json", fromDir);
|
|
25050
|
-
return
|
|
25086
|
+
return join4(dirname3(pkgJsonPath), "bin", "openspec.js");
|
|
25051
25087
|
} catch {
|
|
25052
25088
|
ensureOpenspecInstalled(fromDir, runner);
|
|
25053
25089
|
const pkgJsonPath = runner.resolveSync("@fission-ai/openspec/package.json", fromDir);
|
|
25054
|
-
return
|
|
25090
|
+
return join4(dirname3(pkgJsonPath), "bin", "openspec.js");
|
|
25055
25091
|
}
|
|
25056
25092
|
}
|
|
25057
25093
|
|
|
@@ -25124,7 +25160,7 @@ class OpenSpecChangeStore {
|
|
|
25124
25160
|
}
|
|
25125
25161
|
}
|
|
25126
25162
|
getChangeDirectory(name) {
|
|
25127
|
-
return
|
|
25163
|
+
return join5("openspec", "changes", name);
|
|
25128
25164
|
}
|
|
25129
25165
|
async listChanges() {
|
|
25130
25166
|
const result = runOpenspec(["list", "--json"]);
|
|
@@ -25138,7 +25174,7 @@ class OpenSpecChangeStore {
|
|
|
25138
25174
|
}
|
|
25139
25175
|
} catch {}
|
|
25140
25176
|
}
|
|
25141
|
-
const changesDir =
|
|
25177
|
+
const changesDir = join5("openspec", "changes");
|
|
25142
25178
|
try {
|
|
25143
25179
|
const entries = await readdir(changesDir, { withFileTypes: true });
|
|
25144
25180
|
return entries.filter((entry) => entry.isDirectory() && entry.name !== "archive").map((entry) => entry.name);
|
|
@@ -25147,35 +25183,35 @@ class OpenSpecChangeStore {
|
|
|
25147
25183
|
}
|
|
25148
25184
|
}
|
|
25149
25185
|
async readTaskList(name) {
|
|
25150
|
-
const file = Bun.file(
|
|
25186
|
+
const file = Bun.file(join5("openspec", "changes", name, "tasks.md"));
|
|
25151
25187
|
if (!await file.exists())
|
|
25152
25188
|
return "";
|
|
25153
25189
|
return await file.text();
|
|
25154
25190
|
}
|
|
25155
25191
|
async writeTaskList(name, content) {
|
|
25156
|
-
const path =
|
|
25157
|
-
await mkdir(
|
|
25192
|
+
const path = join5("openspec", "changes", name, "tasks.md");
|
|
25193
|
+
await mkdir(dirname4(path), { recursive: true });
|
|
25158
25194
|
await Bun.write(path, content);
|
|
25159
25195
|
}
|
|
25160
25196
|
async appendSteering(name, message) {
|
|
25161
|
-
const path =
|
|
25197
|
+
const path = join5("openspec", "changes", name, "steering.md");
|
|
25162
25198
|
const file = Bun.file(path);
|
|
25163
25199
|
const existing = await file.exists() ? await file.text() : null;
|
|
25164
25200
|
const updated = existing ? `${message}
|
|
25165
25201
|
|
|
25166
25202
|
${existing.trimStart()}` : `${message}
|
|
25167
25203
|
`;
|
|
25168
|
-
await mkdir(
|
|
25204
|
+
await mkdir(dirname4(path), { recursive: true });
|
|
25169
25205
|
await Bun.write(path, updated);
|
|
25170
25206
|
const firstLine = message.split(/\r?\n/).map((l) => l.trim()).find((l) => l.length > 0) ?? message.trim();
|
|
25171
25207
|
if (firstLine.length === 0)
|
|
25172
25208
|
return;
|
|
25173
|
-
const tasksPath =
|
|
25209
|
+
const tasksPath = join5("openspec", "changes", name, "tasks.md");
|
|
25174
25210
|
const tasksFile = Bun.file(tasksPath);
|
|
25175
25211
|
const existingTasks = await tasksFile.exists() ? await tasksFile.text() : "";
|
|
25176
25212
|
const taskLine = `- [ ] Address steering: ${firstLine}`;
|
|
25177
25213
|
const next = appendSteeringTaskToTasksMd(existingTasks, taskLine);
|
|
25178
|
-
await mkdir(
|
|
25214
|
+
await mkdir(dirname4(tasksPath), { recursive: true });
|
|
25179
25215
|
await Bun.write(tasksPath, next);
|
|
25180
25216
|
}
|
|
25181
25217
|
async validateChange(name) {
|
|
@@ -25270,7 +25306,7 @@ ${existing.trimStart()}` : `${message}
|
|
|
25270
25306
|
async function findProjectRoot(startDir) {
|
|
25271
25307
|
let dir = startDir;
|
|
25272
25308
|
while (dir !== "/") {
|
|
25273
|
-
if (await exists(
|
|
25309
|
+
if (await exists(join6(dir, "openspec")))
|
|
25274
25310
|
return dir;
|
|
25275
25311
|
dir = resolve(dir, "..");
|
|
25276
25312
|
}
|
|
@@ -25284,8 +25320,8 @@ async function main() {
|
|
|
25284
25320
|
startDir = resolve(args[dirIdx + 1]);
|
|
25285
25321
|
}
|
|
25286
25322
|
const projectRoot = await findProjectRoot(startDir);
|
|
25287
|
-
const changesDir =
|
|
25288
|
-
const taskFilesDir =
|
|
25323
|
+
const changesDir = join6(projectRoot, ".ralph", "tasks");
|
|
25324
|
+
const taskFilesDir = join6(projectRoot, "openspec", "changes");
|
|
25289
25325
|
const changeStore = new OpenSpecChangeStore;
|
|
25290
25326
|
const server = new McpServer({
|
|
25291
25327
|
name: "ralph",
|