@open-tomato/rafa 0.11.0 → 0.14.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.
@@ -4,7 +4,7 @@ import {
4
4
  openNdjsonStore,
5
5
  openSqliteStore,
6
6
  selectEffortStore
7
- } from "../../index-srdtw7w1.js";
7
+ } from "../../index-g9kvby04.js";
8
8
  import {
9
9
  STORE_BACKENDS
10
10
  } from "../../index-96pz9023.js";
@@ -867,6 +867,14 @@ function runningCommand() {
867
867
  return running;
868
868
  }
869
869
 
870
+ // src/utils/session-env.ts
871
+ function sessionSpawnEnv(base) {
872
+ return {
873
+ ...base,
874
+ CLAUDE_CODE_ENTRYPOINT: "cli"
875
+ };
876
+ }
877
+
870
878
  // src/utils/claude.ts
871
879
  async function getClaudeUsagePercent() {
872
880
  const envPct = process.env["CLAUDE_USAGE_PERCENT"];
@@ -912,12 +920,6 @@ function interruptClaudeSessions() {
912
920
  session.kill("SIGINT");
913
921
  return liveSessions.size;
914
922
  }
915
- function claudeSessionEnv() {
916
- return {
917
- ...process.env,
918
- CLAUDE_CODE_ENTRYPOINT: "cli"
919
- };
920
- }
921
923
 
922
924
  class UndeclaredSpendError extends Error {
923
925
  name = "UndeclaredSpendError";
@@ -962,7 +964,7 @@ async function spawnClaude(args, prompt) {
962
964
  stdin: new TextEncoder().encode(prompt),
963
965
  stdout: "inherit",
964
966
  stderr: "inherit",
965
- env: claudeSessionEnv()
967
+ env: sessionSpawnEnv(process.env)
966
968
  });
967
969
  liveSessions.add(proc);
968
970
  try {
@@ -1006,16 +1008,17 @@ async function teeToOperator(stream) {
1006
1008
  }
1007
1009
  return text + tail;
1008
1010
  }
1009
- async function spawnClaudeCaptured(args, prompt) {
1011
+ async function spawnClaudeCaptured(args, prompt, options = {}) {
1010
1012
  guardSpend();
1011
- return spawnCaptured(args, prompt);
1013
+ return spawnCaptured(args, prompt, options);
1012
1014
  }
1013
- async function spawnCaptured(args, prompt) {
1015
+ async function spawnCaptured(args, prompt, options = {}) {
1014
1016
  const proc = Bun.spawn([CLAUDE_BIN, ...args], {
1015
1017
  stdin: new TextEncoder().encode(prompt),
1016
1018
  stdout: "pipe",
1017
1019
  stderr: "inherit",
1018
- env: claudeSessionEnv()
1020
+ env: sessionSpawnEnv(process.env),
1021
+ ...options.cwd === undefined ? {} : { cwd: options.cwd }
1019
1022
  });
1020
1023
  liveSessions.add(proc);
1021
1024
  let stdout;
@@ -1130,11 +1133,16 @@ var REST_STATES = {
1130
1133
  cancelled: "closed"
1131
1134
  };
1132
1135
  function createGhRunner(options) {
1133
- const { cwd, command = "gh" } = options;
1136
+ const { cwd, command = "gh", env } = options;
1134
1137
  return async (args) => {
1138
+ const executable = env === undefined ? command : Bun.which(command, { PATH: env.PATH ?? "", cwd });
1139
+ if (executable === null) {
1140
+ return { ok: false, stdout: "", stderr: notOnPath(command, cwd, env?.PATH) };
1141
+ }
1135
1142
  try {
1136
- const proc = Bun.spawn([command, ...args], {
1143
+ const proc = Bun.spawn([executable, ...args], {
1137
1144
  cwd,
1145
+ ...env === undefined ? {} : { env: { ...env } },
1138
1146
  stdin: "ignore",
1139
1147
  stdout: "pipe",
1140
1148
  stderr: "pipe"
@@ -1150,6 +1158,10 @@ function createGhRunner(options) {
1150
1158
  }
1151
1159
  };
1152
1160
  }
1161
+ function notOnPath(command, cwd, path) {
1162
+ const searched = path === undefined ? "an environment with no PATH" : `PATH ${JSON.stringify(path)}`;
1163
+ return `could not run ${command} in ${cwd}: not found on ${searched} (ENOENT)`;
1164
+ }
1153
1165
  function isOneOf(members, value) {
1154
1166
  return typeof value === "string" && members.includes(value);
1155
1167
  }
@@ -1283,20 +1295,26 @@ function listedIssues(stdout) {
1283
1295
  function labelValue(labels, prefix) {
1284
1296
  return labels.find((label) => label.startsWith(prefix))?.slice(prefix.length);
1285
1297
  }
1298
+ function typeOfLabels(labels) {
1299
+ const type = labelValue(labels, GITHUB_LABELS.typePrefix);
1300
+ return isOneOf(ISSUE_TYPES, type) ? type : "code";
1301
+ }
1302
+ function moduleOfLabels(labels) {
1303
+ return labelValue(labels, GITHUB_LABELS.modulePrefix) ?? "unassigned";
1304
+ }
1286
1305
  function stateOf(viewed) {
1287
1306
  if (viewed.state === "OPEN")
1288
1307
  return "todo";
1289
1308
  return viewed.stateReason === NOT_PLANNED ? "cancelled" : "done";
1290
1309
  }
1291
1310
  function issueOf(ref, viewed) {
1292
- const type = labelValue(viewed.labels, GITHUB_LABELS.typePrefix);
1293
1311
  const priority = labelValue(viewed.labels, GITHUB_LABELS.priorityPrefix);
1294
1312
  return {
1295
1313
  opt: ref.opt,
1296
1314
  title: viewed.title,
1297
1315
  body: viewed.body,
1298
- type: isOneOf(ISSUE_TYPES, type) ? type : "code",
1299
- module: labelValue(viewed.labels, GITHUB_LABELS.modulePrefix) ?? "unassigned",
1316
+ type: typeOfLabels(viewed.labels),
1317
+ module: moduleOfLabels(viewed.labels),
1300
1318
  priority: isOneOf(ISSUE_PRIORITIES, priority) ? priority : null,
1301
1319
  project: null,
1302
1320
  blockedBy: viewed.labels.map((label) => label.startsWith(GITHUB_LABELS.blockedByPrefix) ? label.slice(GITHUB_LABELS.blockedByPrefix.length) : "").filter(isIssueNumber).map(Number),
package/dist/index.js CHANGED
@@ -50,7 +50,7 @@ import {
50
50
  sqliteStorePath,
51
51
  withSqliteStore,
52
52
  writeSqliteStore
53
- } from "./index-srdtw7w1.js";
53
+ } from "./index-g9kvby04.js";
54
54
  import {
55
55
  BUDGET_FLAG,
56
56
  CLAUDE_SETTING_SOURCES,
@@ -337,6 +337,13 @@ var PROMPT_SHAPES = [
337
337
  prefix: "The pull request for branch ",
338
338
  firstLineInfix: " is not mergeable: ",
339
339
  source: "src/start/pr-lifecycle.ts"
340
+ },
341
+ {
342
+ kind: "search",
343
+ label: "search",
344
+ prefix: "# Inventory search instructions",
345
+ firstLineInfix: null,
346
+ source: "src/inventory/search/prompt.ts"
340
347
  }
341
348
  ];
342
349
  var ENQUEUE_SCAN_WINDOW = 10;
@@ -1895,7 +1902,7 @@ async function report(args, repoRoot) {
1895
1902
  }
1896
1903
  }
1897
1904
  // package.json
1898
- var version = "0.11.0";
1905
+ var version = "0.14.0";
1899
1906
 
1900
1907
  // src/modules/manifest.ts
1901
1908
  var MANIFEST_VERSION = 1;
@@ -2378,8 +2385,7 @@ function definitionName(text) {
2378
2385
  const name = frontmatter["name"];
2379
2386
  return typeof name === "string" && name.length > 0 ? name : null;
2380
2387
  }
2381
- function readAgentDefinitions(root) {
2382
- const dir = join3(root, AGENT_DEFINITION_DIR);
2388
+ function readAgentDirectory(dir) {
2383
2389
  const found = [];
2384
2390
  for (const file of markdownFiles(dir)) {
2385
2391
  const path = join3(dir, file);
@@ -2393,6 +2399,9 @@ function readAgentDefinitions(root) {
2393
2399
  }
2394
2400
  return found.sort((a, b) => a.name.localeCompare(b.name));
2395
2401
  }
2402
+ function readAgentDefinitions(root) {
2403
+ return readAgentDirectory(join3(root, AGENT_DEFINITION_DIR));
2404
+ }
2396
2405
  function firstByName(files) {
2397
2406
  const byName = new Map;
2398
2407
  for (const file of files) {
@@ -4182,6 +4191,7 @@ var BLOCKED_BY_FIELD = "Blocked by";
4182
4191
  var FENCE_LINE2 = /^ {0,3}(?:```|~~~)/u;
4183
4192
  var FIELD_LINE = /^ {0,3}(?:[-*+]\s+)?[*_]{0,2}blocked\s+by[*_]{0,2}\s*:(.*)$/iu;
4184
4193
  var ISSUE_ID = /#(\d+)/gu;
4194
+ var FOREIGN_ID = /[A-Za-z0-9][A-Za-z0-9-]*\/[A-Za-z0-9._-]+#\d+/gu;
4185
4195
  var REMEDY4 = `name them as "${BLOCKED_BY_FIELD}: #24 #26", or take the ${SPEC_BLOCKED_LABEL} label off`;
4186
4196
  function hasSpecBlockedLabel(labels) {
4187
4197
  return labels.some((label) => label.trim().toLowerCase() === SPEC_BLOCKED_LABEL);
@@ -4214,29 +4224,41 @@ function idsIn(text) {
4214
4224
  }
4215
4225
  return found;
4216
4226
  }
4217
- function reading(kind, issue, found, blockers, unknown) {
4227
+ function foreignIn(text) {
4228
+ const found = [];
4229
+ for (const [token] of text.matchAll(FOREIGN_ID)) {
4230
+ if (!found.includes(token))
4231
+ found.push(token);
4232
+ }
4233
+ return found;
4234
+ }
4235
+ var NAMED_NOTHING = { ids: [], foreign: [] };
4236
+ function reading(kind, issue, found, named, unknown) {
4218
4237
  return {
4219
4238
  kind,
4220
4239
  issue,
4221
4240
  line: found?.number ?? null,
4222
4241
  text: found?.text ?? null,
4223
- blockers,
4242
+ blockers: named.ids,
4243
+ foreign: named.foreign,
4224
4244
  unknown
4225
4245
  };
4226
4246
  }
4227
4247
  function readBlockedBy(issue, body, known) {
4228
4248
  const found = findFieldLine(body);
4229
4249
  if (found === null)
4230
- return reading("no-line", issue, null, [], []);
4231
- const ids = idsIn(found.text);
4250
+ return reading("no-line", issue, null, NAMED_NOTHING, []);
4251
+ const foreign = foreignIn(found.text);
4252
+ const ids = idsIn(found.text.replace(FOREIGN_ID, " "));
4253
+ const named = { ids, foreign };
4232
4254
  if (ids.length === 0)
4233
- return reading("no-ids", issue, found, [], []);
4255
+ return reading("no-ids", issue, found, named, []);
4234
4256
  const unknown = known === undefined ? [] : ids.filter((id) => id !== issue && !known.has(id));
4235
4257
  if (ids.includes(issue))
4236
- return reading("self-reference", issue, found, ids, unknown);
4258
+ return reading("self-reference", issue, found, named, unknown);
4237
4259
  if (unknown.length > 0)
4238
- return reading("unknown-issue", issue, found, ids, unknown);
4239
- return reading("blocked", issue, found, ids, unknown);
4260
+ return reading("unknown-issue", issue, found, named, unknown);
4261
+ return reading("blocked", issue, found, named, unknown);
4240
4262
  }
4241
4263
  function nameIds(ids) {
4242
4264
  return ids.map((id) => `#${String(id)}`).join(" ");
@@ -4246,6 +4268,9 @@ function faultClause(read) {
4246
4268
  if (read.kind === "no-line") {
4247
4269
  return `is labelled ${SPEC_BLOCKED_LABEL} and its body carries no "${BLOCKED_BY_FIELD}:" line`;
4248
4270
  }
4271
+ if (read.kind === "no-ids" && read.foreign.length > 0) {
4272
+ return `has a "${BLOCKED_BY_FIELD}:" line ${at} naming only issues on other repositories: ${read.foreign.join(" ")}`;
4273
+ }
4249
4274
  if (read.kind === "no-ids") {
4250
4275
  return `has a "${BLOCKED_BY_FIELD}:" line ${at} naming no issue: "${read.text ?? ""}"`;
4251
4276
  }
@@ -4726,112 +4751,8 @@ async function resolvePlanSpec(options) {
4726
4751
  });
4727
4752
  }
4728
4753
 
4729
- // src/project/root-choice.ts
4754
+ // src/cli/prompt/confirm.ts
4730
4755
  import { createInterface as createInterface2 } from "readline";
4731
-
4732
- // src/project/roots.ts
4733
- import { accessSync, constants, readFileSync as readFileSync8, statSync as statSync7 } from "fs";
4734
-
4735
- // src/project/scope.ts
4736
- import { existsSync as existsSync9, realpathSync as realpathSync2 } from "fs";
4737
- import { dirname as dirname3, isAbsolute as isAbsolute2, join as join6 } from "path";
4738
- var SCOPE_DIR = dirname3(CONFIG_FILE);
4739
- var INIT_COMMAND = "rafa init";
4740
- var DISK_FILE_SYSTEM = Object.freeze({
4741
- exists: (path3) => existsSync9(path3),
4742
- realpath: (path3) => realpathSync2(path3)
4743
- });
4744
-
4745
- class ScopeError extends Error {
4746
- constructor(message, options) {
4747
- super(`rafa scope: ${message}`, options);
4748
- this.name = "ScopeError";
4749
- }
4750
- }
4751
- function scopeAt(base) {
4752
- return { dir: join6(base, SCOPE_DIR), configFile: configFilePath(base) };
4753
- }
4754
- function initHint(start, passedUserConfig = null) {
4755
- const passed2 = passedUserConfig === null ? [] : [`${passedUserConfig} is the user scope's config and marks no project`];
4756
- return [
4757
- `not inside a rafa project: no ${CONFIG_FILE} in ${start} or any directory above it`,
4758
- ...passed2,
4759
- `run \`${INIT_COMMAND}\` to set one up`
4760
- ].join(`
4761
- `);
4762
- }
4763
- function requireAbsolute(label, path3) {
4764
- if (!isAbsolute2(path3)) {
4765
- throw new ScopeError(`${label} is ${describeValue(path3)}, expected an absolute path`);
4766
- }
4767
- }
4768
- function realStartOf(start, fs2) {
4769
- try {
4770
- return fs2.realpath(start);
4771
- } catch (error) {
4772
- const message = `start directory ${start} does not resolve (${messageOf(error)})`;
4773
- throw new ScopeError(message, { cause: error });
4774
- }
4775
- }
4776
- function realHomeOf(home, fs2) {
4777
- try {
4778
- return fs2.realpath(home);
4779
- } catch {
4780
- return null;
4781
- }
4782
- }
4783
- function selfAndAncestors(path3) {
4784
- const parent = dirname3(path3);
4785
- return parent === path3 ? [path3] : [path3, ...selfAndAncestors(parent)];
4786
- }
4787
- function walkUp(realStart, realHome, fs2) {
4788
- let passedUserConfig = false;
4789
- for (const dir of selfAndAncestors(realStart)) {
4790
- if (!fs2.exists(configFilePath(dir)))
4791
- continue;
4792
- if (dir !== realHome)
4793
- return { root: dir, passedUserConfig };
4794
- passedUserConfig = true;
4795
- }
4796
- return { root: null, passedUserConfig };
4797
- }
4798
- function resolveScope(start, seams) {
4799
- const { home, fs: fs2 = DISK_FILE_SYSTEM } = seams;
4800
- requireAbsolute("start directory", start);
4801
- requireAbsolute("home directory", home);
4802
- const user = scopeAt(home);
4803
- const walk = walkUp(realStartOf(start, fs2), realHomeOf(home, fs2), fs2);
4804
- if (walk.root === null) {
4805
- const passed2 = walk.passedUserConfig ? user.configFile : null;
4806
- return { found: false, start, home, user, hint: initHint(start, passed2) };
4807
- }
4808
- return { found: true, root: walk.root, home, project: scopeAt(walk.root), user };
4809
- }
4810
-
4811
- // src/project/roots.ts
4812
- var REFUSED_ROOTS = Object.freeze([
4813
- { path: "/", why: "is the filesystem root" },
4814
- { path: "/var", why: "holds system state" },
4815
- { path: "/etc", why: "holds system configuration" },
4816
- { path: "/usr", why: "holds system programs" },
4817
- { path: "/home", why: "holds the home directories of every user" },
4818
- { path: "/Users", why: "holds the home directories of every user" }
4819
- ]);
4820
- var HOME_WHY = `is the home directory, whose ${SCOPE_DIR}/ is the user scope`;
4821
- var MONOREPO_MARKER_FILES = Object.freeze([
4822
- "turbo.json",
4823
- "pnpm-workspace.yaml",
4824
- "nx.json",
4825
- "lerna.json"
4826
- ]);
4827
- var DISK_ROOTS_FILE_SYSTEM = Object.freeze({
4828
- ...DISK_FILE_SYSTEM,
4829
- readFile: (path3) => readFileSync8(path3, "utf8"),
4830
- isDirectory: (path3) => statSync7(path3).isDirectory(),
4831
- assertWritable: (path3) => accessSync(path3, constants.W_OK)
4832
- });
4833
-
4834
- // src/project/root-choice.ts
4835
4756
  function createLinePrompter(input, output) {
4836
4757
  const buffered = [];
4837
4758
  const waiting = [];
@@ -5639,12 +5560,90 @@ import {
5639
5560
  linkSync as linkSync2,
5640
5561
  mkdirSync as mkdirSync4,
5641
5562
  readdirSync as readdirSync4,
5642
- readFileSync as readFileSync9,
5563
+ readFileSync as readFileSync8,
5643
5564
  renameSync as renameSync2,
5644
5565
  rmSync,
5645
5566
  writeFileSync as writeFileSync3
5646
5567
  } from "fs";
5647
5568
  import { basename as basename4, dirname as dirname4, join as join7 } from "path";
5569
+
5570
+ // src/project/scope.ts
5571
+ import { existsSync as existsSync9, realpathSync as realpathSync2 } from "fs";
5572
+ import { dirname as dirname3, isAbsolute as isAbsolute2, join as join6 } from "path";
5573
+ var SCOPE_DIR = dirname3(CONFIG_FILE);
5574
+ var INIT_COMMAND = "rafa init";
5575
+ var DISK_FILE_SYSTEM = Object.freeze({
5576
+ exists: (path3) => existsSync9(path3),
5577
+ realpath: (path3) => realpathSync2(path3)
5578
+ });
5579
+
5580
+ class ScopeError extends Error {
5581
+ constructor(message, options) {
5582
+ super(`rafa scope: ${message}`, options);
5583
+ this.name = "ScopeError";
5584
+ }
5585
+ }
5586
+ function scopeAt(base) {
5587
+ return { dir: join6(base, SCOPE_DIR), configFile: configFilePath(base) };
5588
+ }
5589
+ function initHint(start, passedUserConfig = null) {
5590
+ const passed2 = passedUserConfig === null ? [] : [`${passedUserConfig} is the user scope's config and marks no project`];
5591
+ return [
5592
+ `not inside a rafa project: no ${CONFIG_FILE} in ${start} or any directory above it`,
5593
+ ...passed2,
5594
+ `run \`${INIT_COMMAND}\` to set one up`
5595
+ ].join(`
5596
+ `);
5597
+ }
5598
+ function requireAbsolute(label, path3) {
5599
+ if (!isAbsolute2(path3)) {
5600
+ throw new ScopeError(`${label} is ${describeValue(path3)}, expected an absolute path`);
5601
+ }
5602
+ }
5603
+ function realStartOf(start, fs2) {
5604
+ try {
5605
+ return fs2.realpath(start);
5606
+ } catch (error) {
5607
+ const message = `start directory ${start} does not resolve (${messageOf(error)})`;
5608
+ throw new ScopeError(message, { cause: error });
5609
+ }
5610
+ }
5611
+ function realHomeOf(home, fs2) {
5612
+ try {
5613
+ return fs2.realpath(home);
5614
+ } catch {
5615
+ return null;
5616
+ }
5617
+ }
5618
+ function selfAndAncestors(path3) {
5619
+ const parent = dirname3(path3);
5620
+ return parent === path3 ? [path3] : [path3, ...selfAndAncestors(parent)];
5621
+ }
5622
+ function walkUp(realStart, realHome, fs2) {
5623
+ let passedUserConfig = false;
5624
+ for (const dir of selfAndAncestors(realStart)) {
5625
+ if (!fs2.exists(configFilePath(dir)))
5626
+ continue;
5627
+ if (dir !== realHome)
5628
+ return { root: dir, passedUserConfig };
5629
+ passedUserConfig = true;
5630
+ }
5631
+ return { root: null, passedUserConfig };
5632
+ }
5633
+ function resolveScope(start, seams) {
5634
+ const { home, fs: fs2 = DISK_FILE_SYSTEM } = seams;
5635
+ requireAbsolute("start directory", start);
5636
+ requireAbsolute("home directory", home);
5637
+ const user = scopeAt(home);
5638
+ const walk = walkUp(realStartOf(start, fs2), realHomeOf(home, fs2), fs2);
5639
+ if (walk.root === null) {
5640
+ const passed2 = walk.passedUserConfig ? user.configFile : null;
5641
+ return { found: false, start, home, user, hint: initHint(start, passed2) };
5642
+ }
5643
+ return { found: true, root: walk.root, home, project: scopeAt(walk.root), user };
5644
+ }
5645
+
5646
+ // src/loop/sessions.ts
5648
5647
  var SESSION_STATES = Object.freeze(["running", "paused", "stopped", "done"]);
5649
5648
  var RUNS_DIR = "runs";
5650
5649
  var RECORD_EXTENSION = ".json";
@@ -5792,7 +5791,7 @@ function readState2(record, isAlive = isPidAlive) {
5792
5791
  function readRecordFile(file) {
5793
5792
  let text;
5794
5793
  try {
5795
- text = readFileSync9(file, "utf8");
5794
+ text = readFileSync8(file, "utf8");
5796
5795
  } catch (error) {
5797
5796
  throw new SessionRecordError(file, `cannot be read: ${messageOf(error)}`);
5798
5797
  }
@@ -6005,15 +6004,15 @@ function openNextSources(context, seams = DEFAULT_NEXT_SOURCE_SEAMS) {
6005
6004
  }
6006
6005
 
6007
6006
  // src/commands/plan/list.ts
6008
- import { existsSync as existsSync10, readdirSync as readdirSync5, readFileSync as readFileSync10 } from "fs";
6007
+ import { existsSync as existsSync10, readdirSync as readdirSync5, readFileSync as readFileSync9 } from "fs";
6009
6008
  import { join as join9 } from "path";
6010
6009
  var USAGE2 = "rafa plan list";
6011
6010
  function listing(dir, stub) {
6012
6011
  const plan = join9(dir, planFileName(stub, false));
6013
6012
  const trackerPath = join9(dir, planFileName(stub, true));
6014
6013
  const tracker = isFile(trackerPath) ? trackerPath : null;
6015
- const planModel = parsePlan(readFileSync10(plan, "utf8"));
6016
- const counted2 = tracker === null ? planModel : parsePlan(readFileSync10(tracker, "utf8"));
6014
+ const planModel = parsePlan(readFileSync9(plan, "utf8"));
6015
+ const counted2 = tracker === null ? planModel : parsePlan(readFileSync9(tracker, "utf8"));
6017
6016
  return { stub, plan, tracker, tasks: countTasks(counted2.tasks), issues: planModel.issues.length };
6018
6017
  }
6019
6018
  function listPlans(plans) {
@@ -7029,7 +7028,7 @@ import { homedir as homedir3 } from "os";
7029
7028
  var RAFA_VERSION = version;
7030
7029
 
7031
7030
  // src/notices/notices.ts
7032
- import { mkdirSync as mkdirSync5, readFileSync as readFileSync11, writeFileSync as writeFileSync4 } from "fs";
7031
+ import { mkdirSync as mkdirSync5, readFileSync as readFileSync10, writeFileSync as writeFileSync4 } from "fs";
7033
7032
  import { dirname as dirname5, join as join10 } from "path";
7034
7033
  var NOTICE_IDS = Object.freeze(["alpha", "danger"]);
7035
7034
  var FEEDBACK_URL = "https://github.com/open-tomato/rafa/issues/new/choose";
@@ -7043,7 +7042,7 @@ function isNoticeId(value) {
7043
7042
  function readDismissed(home) {
7044
7043
  let raw;
7045
7044
  try {
7046
- raw = readFileSync11(noticesPath(home), "utf8");
7045
+ raw = readFileSync10(noticesPath(home), "utf8");
7047
7046
  } catch {
7048
7047
  return [];
7049
7048
  }
@@ -8260,16 +8259,16 @@ function writeProgress(repoRoot, planStub2) {
8260
8259
 
8261
8260
  // src/start/preflight.ts
8262
8261
  import { randomUUID as randomUUID6 } from "crypto";
8263
- import { existsSync as existsSync14, readFileSync as readFileSync13 } from "fs";
8262
+ import { existsSync as existsSync14, readFileSync as readFileSync12 } from "fs";
8264
8263
  import { homedir as homedir5 } from "os";
8265
8264
  import { basename as basename5 } from "path";
8266
8265
 
8267
8266
  // src/preflight/first-dispatch.ts
8268
- import { readFileSync as readFileSync12 } from "fs";
8267
+ import { readFileSync as readFileSync11 } from "fs";
8269
8268
  var TICKED_TASK = /^- \[[xX]\] (.+)/;
8270
8269
  function readIfReadable(path5) {
8271
8270
  try {
8272
- return readFileSync12(path5, "utf8");
8271
+ return readFileSync11(path5, "utf8");
8273
8272
  } catch {
8274
8273
  return null;
8275
8274
  }
@@ -8306,7 +8305,7 @@ function agentSourcePath(planPath) {
8306
8305
  }
8307
8306
  function readIfReadable2(path5) {
8308
8307
  try {
8309
- return readFileSync13(path5, "utf8");
8308
+ return readFileSync12(path5, "utf8");
8310
8309
  } catch {
8311
8310
  return null;
8312
8311
  }
@@ -8800,7 +8799,7 @@ async function handleRedChecks(io, branch, prNumber, rows) {
8800
8799
  }
8801
8800
 
8802
8801
  // src/release/prepare.ts
8803
- import { readFileSync as readFileSync15, writeFileSync as writeFileSync7 } from "fs";
8802
+ import { readFileSync as readFileSync14, writeFileSync as writeFileSync7 } from "fs";
8804
8803
 
8805
8804
  // src/release/changelog.ts
8806
8805
  var RELEASE_HEADING_FIELDS = ["version", "date", "title"];
@@ -8985,11 +8984,11 @@ function changelogDate(now) {
8985
8984
  }
8986
8985
 
8987
8986
  // src/release/enabled.ts
8988
- import { statSync as statSync8 } from "fs";
8987
+ import { statSync as statSync7 } from "fs";
8989
8988
  import { resolve as resolve9 } from "path";
8990
8989
  function isRegularFile(full) {
8991
8990
  try {
8992
- return statSync8(full).isFile();
8991
+ return statSync7(full).isFile();
8993
8992
  } catch {
8994
8993
  return false;
8995
8994
  }
@@ -9032,7 +9031,7 @@ function resolveReleaseLevel(declared, notes) {
9032
9031
  }
9033
9032
 
9034
9033
  // src/release/version.ts
9035
- import { readFileSync as readFileSync14, writeFileSync as writeFileSync6 } from "fs";
9034
+ import { readFileSync as readFileSync13, writeFileSync as writeFileSync6 } from "fs";
9036
9035
  var RELEASE_REMOTE = "origin";
9037
9036
  var RELEASE_BASE_BRANCH = "main";
9038
9037
  var VERSION_SHAPE = /^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-([0-9A-Za-z.-]+))?(?:\+([0-9A-Za-z.-]+))?$/;
@@ -9124,7 +9123,7 @@ function writeManifestVersion(path5, next) {
9124
9123
  const unwritten = { path: path5, written: false, previous: null, version: next };
9125
9124
  let text;
9126
9125
  try {
9127
- text = readFileSync14(path5, "utf8");
9126
+ text = readFileSync13(path5, "utf8");
9128
9127
  } catch (error) {
9129
9128
  return { ...unwritten, problem: `${path5} could not be read: ${messageOf(error)}` };
9130
9129
  }
@@ -9227,7 +9226,7 @@ function planVersion(input, versionFile, level) {
9227
9226
  }
9228
9227
  function textOf(path5) {
9229
9228
  try {
9230
- return readFileSync15(path5, "utf8");
9229
+ return readFileSync14(path5, "utf8");
9231
9230
  } catch {
9232
9231
  return null;
9233
9232
  }
@@ -9340,7 +9339,7 @@ function changelogFailure(failed3, versionEdit, restored) {
9340
9339
  }
9341
9340
 
9342
9341
  // src/release/verify.ts
9343
- import { readFileSync as readFileSync16, writeFileSync as writeFileSync8 } from "fs";
9342
+ import { readFileSync as readFileSync15, writeFileSync as writeFileSync8 } from "fs";
9344
9343
  function changelogInsertionSpan(before, after) {
9345
9344
  const beforeLines = before.split(`
9346
9345
  `);
@@ -9357,7 +9356,7 @@ function changelogInsertionSpan(before, after) {
9357
9356
  }
9358
9357
  function textOf2(path5) {
9359
9358
  try {
9360
- return readFileSync16(path5, "utf8");
9359
+ return readFileSync15(path5, "utf8");
9361
9360
  } catch {
9362
9361
  return null;
9363
9362
  }
@@ -9692,10 +9691,10 @@ async function finishRelease(input, seams = {}) {
9692
9691
  }
9693
9692
 
9694
9693
  // src/start/risk-total.ts
9695
- import { readFileSync as readFileSync18 } from "fs";
9694
+ import { readFileSync as readFileSync17 } from "fs";
9696
9695
 
9697
9696
  // src/plan/risk.ts
9698
- import { readFileSync as readFileSync17 } from "fs";
9697
+ import { readFileSync as readFileSync16 } from "fs";
9699
9698
  import { isAbsolute as isAbsolute3, join as join13, relative as relative2 } from "path";
9700
9699
 
9701
9700
  // src/schema/tiers.ts
@@ -10349,7 +10348,7 @@ function located(finding2, file, task) {
10349
10348
  }
10350
10349
  function readText4(path5) {
10351
10350
  try {
10352
- return readFileSync17(path5, "utf8");
10351
+ return readFileSync16(path5, "utf8");
10353
10352
  } catch {
10354
10353
  return null;
10355
10354
  }
@@ -10423,7 +10422,7 @@ function spawningRunners(root) {
10423
10422
  }
10424
10423
  async function readRiskTotalLine(input, seams = {}) {
10425
10424
  const makeRunners = seams.runners ?? spawningRunners;
10426
- const report2 = await assessPlanRisk({ path: input.planPath, text: readFileSync18(input.planPath, "utf8") }, {
10425
+ const report2 = await assessPlanRisk({ path: input.planPath, text: readFileSync17(input.planPath, "utf8") }, {
10427
10426
  repoRoot: input.repoRoot,
10428
10427
  home: input.home,
10429
10428
  settingSources: input.config.settingSources,
@@ -10595,7 +10594,7 @@ function announcePlanIssues(planContent) {
10595
10594
  }
10596
10595
 
10597
10596
  // src/start/runtime.ts
10598
- import { existsSync as existsSync17, readdirSync as readdirSync6, realpathSync as realpathSync4, statSync as statSync9 } from "fs";
10597
+ import { existsSync as existsSync17, readdirSync as readdirSync6, realpathSync as realpathSync4, statSync as statSync8 } from "fs";
10599
10598
  import { homedir as homedir6 } from "os";
10600
10599
  import { isAbsolute as isAbsolute4, join as join14, relative as relative4, resolve as resolve10, sep } from "path";
10601
10600
  var RUNTIME_FLAG = "--runtime";
@@ -10671,14 +10670,14 @@ function installedVersions(root) {
10671
10670
  }
10672
10671
  function isFile2(path5) {
10673
10672
  try {
10674
- return statSync9(path5).isFile();
10673
+ return statSync8(path5).isFile();
10675
10674
  } catch {
10676
10675
  return false;
10677
10676
  }
10678
10677
  }
10679
10678
  function isDirectory(path5) {
10680
10679
  try {
10681
- return statSync9(path5).isDirectory();
10680
+ return statSync8(path5).isDirectory();
10682
10681
  } catch {
10683
10682
  return false;
10684
10683
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@open-tomato/rafa",
3
- "version": "0.11.0",
3
+ "version": "0.14.0",
4
4
  "description": "Alpha. Runs a plan through the ralph loop: one Claude Code session per task, one commit per task, then a pull request and a CI wait.",
5
5
  "private": false,
6
6
  "publishConfig": {