@neriros/ralphy 3.10.5 → 3.10.7

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 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 join5 } from "path";
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 join2 } from "path";
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 = join(changeDir, STATE_FILE);
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
- return StateSchema.parse(JSON.parse(raw));
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 = join(changeDir, STATE_FILE);
24178
- getStorage().write(filePath, JSON.stringify(state, null, 2) + `
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 = join2(changesDir, name);
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(join2(changeDir, ".ralph-state.json"));
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 = join2(changesDir, name);
24307
+ const changeDir = join3(changesDir, name);
24272
24308
  const state = readState(changeDir);
24273
- const taskDir = join2(taskFilesDir, name);
24274
- const tasksContent = storage.read(join2(taskDir, "tasks.md"));
24275
- const proposalContent = storage.read(join2(taskDir, "proposal.md"));
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 = join2(changesDir, name);
24320
- const stateExists = getStorage().read(join2(changeDir, ".ralph-state.json")) !== null;
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 = join2(taskFilesDir, name);
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 = join2(changesDir, name);
24395
- if (getStorage().read(join2(changeDir, ".ralph-state.json")) === null) {
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 = join2(taskFilesDir, name);
24436
- getStorage().write(join2(taskDir, "STOP"), reason ?? "Stopped via MCP");
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 dirname3, join as join4 } from "path";
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 dirname2, join as join3 } from "path";
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(join3(dir, "package.json")).size >= 0) {
25048
+ if (Bun.file(join4(dir, "package.json")).size >= 0) {
25013
25049
  try {
25014
- if (Bun.file(join3(dir, "package.json")).size > 0)
25050
+ if (Bun.file(join4(dir, "package.json")).size > 0)
25015
25051
  return dir;
25016
25052
  } catch {}
25017
25053
  }
25018
- const parent = dirname2(dir);
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 join3(dirname2(pkgJsonPath), "bin", "openspec.js");
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 join3(dirname2(pkgJsonPath), "bin", "openspec.js");
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 join4("openspec", "changes", name);
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 = join4("openspec", "changes");
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(join4("openspec", "changes", name, "tasks.md"));
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 = join4("openspec", "changes", name, "tasks.md");
25157
- await mkdir(dirname3(path), { recursive: true });
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 = join4("openspec", "changes", name, "steering.md");
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(dirname3(path), { recursive: true });
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 = join4("openspec", "changes", name, "tasks.md");
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(dirname3(tasksPath), { recursive: true });
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(join5(dir, "openspec")))
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 = join5(projectRoot, ".ralph", "tasks");
25288
- const taskFilesDir = join5(projectRoot, "openspec", "changes");
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",