@open-tomato/rafa 0.16.0 → 0.17.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,8 +4,8 @@ import {
4
4
  openNdjsonStore,
5
5
  openSqliteStore,
6
6
  selectEffortStore
7
- } from "../../index-q491ekzm.js";
8
- import"../../index-6cw1n0qy.js";
7
+ } from "../../index-7t0qz29r.js";
8
+ import"../../index-ps5sac9p.js";
9
9
  import"../../index-p901zs2p.js";
10
10
  import {
11
11
  STORE_BACKENDS
@@ -8,6 +8,7 @@ import {
8
8
  findNextTask,
9
9
  isStampableStub,
10
10
  loadPlanPrerequisites,
11
+ malformedPrerequisiteLines,
11
12
  parsePlan,
12
13
  parseReport,
13
14
  planStubFromPath,
@@ -19,7 +20,7 @@ import {
19
20
  trackerPathFor,
20
21
  updateTrackerLine,
21
22
  writeTrackerBlocker
22
- } from "./index-krjzghpz.js";
23
+ } from "./index-64wec0k7.js";
23
24
  import {
24
25
  CORE_ADAPTER_REGISTRY,
25
26
  ClaudePlannerError,
@@ -37,7 +38,7 @@ import {
37
38
  sqliteStorePath,
38
39
  withSqliteStore,
39
40
  writeSqliteStore
40
- } from "./index-q491ekzm.js";
41
+ } from "./index-7t0qz29r.js";
41
42
  import {
42
43
  CONFIG_DEFAULTS,
43
44
  CONFIG_FILE,
@@ -49,7 +50,7 @@ import {
49
50
  parseConfigText,
50
51
  readRafaBlocks,
51
52
  resolveConfig
52
- } from "./index-6cw1n0qy.js";
53
+ } from "./index-ps5sac9p.js";
53
54
  import {
54
55
  DESCRIBE_BINARY,
55
56
  DESCRIBE_SCHEMA_VERSION,
@@ -1899,7 +1900,7 @@ async function report(args, repoRoot) {
1899
1900
 
1900
1901
  // package.json
1901
1902
  var name = "@open-tomato/rafa";
1902
- var version = "0.16.0";
1903
+ var version = "0.17.0";
1903
1904
 
1904
1905
  // src/modules/manifest.ts
1905
1906
  var MANIFEST_VERSION = 1;
@@ -2791,6 +2792,7 @@ var HEADING_LINE = /^ {0,3}(#{1,6})\s+(.*)$/u;
2791
2792
  var FENCE_LINE = /^ {0,3}(?:```|~~~)/u;
2792
2793
  var LIST_ITEM = /^ {0,3}(?:[-*+]|\d+[.)])\s+\S/u;
2793
2794
  var CODE_SPAN = /`[^`]*`/gu;
2795
+ var CODE_TICK = "`";
2794
2796
  var HEADING_DRESS = /[*_`]/gu;
2795
2797
  var HEADING_TAIL = /[:.]+$/u;
2796
2798
  var COMMENT_OPEN = "<!--";
@@ -2801,6 +2803,15 @@ var PLACEHOLDER_SHAPES = [
2801
2803
  { token: "???", pattern: /\?{3,}/u }
2802
2804
  ];
2803
2805
  var REMEDY = "fill each gap in the spec and rerun";
2806
+ function codeSpanEnd(text, limit) {
2807
+ const open = text.indexOf(CODE_TICK);
2808
+ if (open === -1 || open > limit)
2809
+ return -1;
2810
+ const close = text.indexOf(CODE_TICK, open + 1);
2811
+ if (close === -1)
2812
+ return -1;
2813
+ return close + 1;
2814
+ }
2804
2815
  function stripComments(line, carried) {
2805
2816
  const comments = [];
2806
2817
  let visible = "";
@@ -2820,6 +2831,12 @@ function stripComments(line, carried) {
2820
2831
  visible += rest;
2821
2832
  break;
2822
2833
  }
2834
+ const quoted = codeSpanEnd(rest, start);
2835
+ if (quoted !== -1) {
2836
+ visible += rest.slice(0, quoted);
2837
+ rest = rest.slice(quoted);
2838
+ continue;
2839
+ }
2823
2840
  visible += rest.slice(0, start);
2824
2841
  const body = rest.slice(start + COMMENT_OPEN.length);
2825
2842
  const end = body.indexOf(COMMENT_CLOSE);
@@ -2840,6 +2857,9 @@ function headingOf(visible) {
2840
2857
  const [, hashes = "", title = ""] = match;
2841
2858
  return { level: hashes.length, title: title.replace(/\s+#+\s*$/u, "").trim() };
2842
2859
  }
2860
+ function fencedLine(number, text) {
2861
+ return { number, fenced: true, visible: text, comments: [], heading: null };
2862
+ }
2843
2863
  function readLines2(body) {
2844
2864
  const raw = body.split(`
2845
2865
  `).map((line) => line.replace(/\r$/u, ""));
@@ -2847,18 +2867,21 @@ function readLines2(body) {
2847
2867
  let carried = false;
2848
2868
  let fenced = false;
2849
2869
  raw.forEach((text, index) => {
2870
+ const number = index + 1;
2871
+ const isFence = FENCE_LINE.test(text);
2872
+ if (fenced || !carried && isFence) {
2873
+ fenced = !fenced || !isFence;
2874
+ lines.push(fencedLine(number, text));
2875
+ return;
2876
+ }
2850
2877
  const stripped = stripComments(text, carried);
2851
2878
  carried = stripped.open;
2852
- const isFence = FENCE_LINE.test(stripped.visible);
2853
- const inFence = fenced || isFence;
2854
- if (isFence)
2855
- fenced = !fenced;
2856
2879
  lines.push({
2857
- number: index + 1,
2858
- fenced: inFence,
2880
+ number,
2881
+ fenced: false,
2859
2882
  visible: stripped.visible,
2860
2883
  comments: stripped.comments,
2861
- heading: inFence ? null : headingOf(stripped.visible)
2884
+ heading: headingOf(stripped.visible)
2862
2885
  });
2863
2886
  });
2864
2887
  return lines;
@@ -2898,13 +2921,13 @@ function gapAt(kind, heading, what, line) {
2898
2921
  return { kind, heading, what, line };
2899
2922
  }
2900
2923
  function placeholdersInLine(heading, line) {
2924
+ if (line.fenced)
2925
+ return [];
2901
2926
  const found = [];
2902
2927
  const unfilled = line.comments.some((comment) => !comment.trim().startsWith(MARKER_PREFIX));
2903
2928
  if (unfilled) {
2904
2929
  found.push(gapAt("placeholder", heading, `holds an unfilled template comment on line ${String(line.number)}`, line.number));
2905
2930
  }
2906
- if (line.fenced)
2907
- return found;
2908
2931
  const prose = line.visible.replace(CODE_SPAN, " ");
2909
2932
  for (const shape of PLACEHOLDER_SHAPES) {
2910
2933
  if (!shape.pattern.test(prose))
@@ -7910,7 +7933,7 @@ function backtickRunLength(text, start) {
7910
7933
  end += 1;
7911
7934
  return end - start;
7912
7935
  }
7913
- function codeSpanEnd(text, from, length) {
7936
+ function codeSpanEnd2(text, from, length) {
7914
7937
  let index = text.indexOf("`", from);
7915
7938
  while (index !== -1) {
7916
7939
  const run = backtickRunLength(text, index);
@@ -7926,7 +7949,7 @@ function firstClause(text) {
7926
7949
  const character = text.charAt(index);
7927
7950
  if (character === "`") {
7928
7951
  const run = backtickRunLength(text, index);
7929
- const end = codeSpanEnd(text, index + run, run);
7952
+ const end = codeSpanEnd2(text, index + run, run);
7930
7953
  index = end === -1 ? index + run : end;
7931
7954
  continue;
7932
7955
  }
@@ -8755,6 +8778,18 @@ async function loadItems(options) {
8755
8778
  `));
8756
8779
  }
8757
8780
  }
8781
+ function refuseMalformedItems(planPath, items) {
8782
+ if (items.malformed.length === 0)
8783
+ return;
8784
+ const file = basename5(prerequisitesPathForPlan(planPath) ?? planPath);
8785
+ const [head = "", ...rest] = malformedPrerequisiteLines(file, items.malformed);
8786
+ throw new CommandExit(1, [
8787
+ `\u274C Refusing to start: ${head}`,
8788
+ ...rest.map((line) => ` ${line}`),
8789
+ " Nothing was checked and nothing was dispatched."
8790
+ ].join(`
8791
+ `));
8792
+ }
8758
8793
  function skippedStartLine(item, tracker) {
8759
8794
  return `\u23ED start-only item ${item.kind} ${JSON.stringify(item.name)} was not checked:` + " it is probed on a first dispatch alone," + ` and ${tracker} already holds a ticked task`;
8760
8795
  }
@@ -8812,6 +8847,7 @@ async function runStartPreflight(options) {
8812
8847
  const runId = (options.newRunId ?? randomUUID6)();
8813
8848
  refuseUnresolvableAgents(options);
8814
8849
  const items = await loadItems(options);
8850
+ refuseMalformedItems(options.planPath, items);
8815
8851
  announceReminders(options.planPath, items.reminders);
8816
8852
  const tiers = {
8817
8853
  required: [...automaticItems(options), ...startTier(options.planPath, items), ...items.required],
@@ -12943,7 +12979,7 @@ async function enforceRefsGate(options) {
12943
12979
  // src/commands/plan/refs-check.ts
12944
12980
  async function coreRoster() {
12945
12981
  const [{ CORE_REGISTRY }, { describeRegistry }] = await Promise.all([
12946
- import("./index-kph6p7rp.js"),
12982
+ import("./index-r7cnr44m.js"),
12947
12983
  import("./describe-wbn759vf.js")
12948
12984
  ]);
12949
12985
  return describeRegistry(CORE_REGISTRY, version);
@@ -13293,4 +13329,4 @@ async function plan(args, repoRoot, registry = CORE_ADAPTER_REGISTRY) {
13293
13329
  }
13294
13330
  }
13295
13331
 
13296
- export { readConfigFile, loadConfig, planStubsFromFileNames, resolvePlanStub, sessionLogDir, collectSessionRow, collect, report, name, version, MANIFEST_VERSION, FEATURE_TYPES, OUTPUT_CHANNELS, RUNNING_MANIFEST_SEAMS, validateManifest, plansDirAt, requireProject, resolvePlansDir, resolveProjectConfig, countTasks, formatCounts, checkbox, planFileName, stubOfPlanFile, isFile, issueLine, plural, expectNoArgument, expectOneArgument, expectAtMostOneArgument, readSwitch, readFrontmatterDocument, readFrontmatter, renderFrontmatter, mergeFrontmatter, writeFrontmatter, AGENT_DEFINITION_DIR, VENDOR_COMMAND, readAgentDirectory, readAgentDefinitions, resolveAgentRoster, missingPlanAgents, validate_default, SPEC_READY_LABEL, TEMPLATE_HEADINGS, findReadinessGaps, hasSpecReadyLabel, createGhPermissions, readAuthorTrust, trustRefusalClause, requireTrustedAuthor, SPEC_NEEDS_WORK_LABEL, SPEC_BLOCKED_LABEL, hasSpecBlockedLabel, readBlockedBy, blockedFaultMessage, UNREADABLE, RefsBlockError, fingerprintText, readRefsText, readCopyRefs, restampCopyRefs, createGitRunner, gitSaid, RefVerifyError, ghIssueReader, tsSymbolsOutliner, createRefVerifier, PROJECT_ID_LENGTH, PROJECT_ID_PATTERN, normalizeRemote, gitRemoteUrl, createGhIssueBoard, ID_PREFIX, BRANCH_PREFIX, SPEC_EXTENSION, boardId, notesFileName, PREVIOUS_COPY_WARN_ABOVE, previousDir, countPreviousCopies, SPEC_LABEL, createGhSpecIssueReader, ROADMAP_TITLE, ROADMAP_SETTING, ROADMAP_REFUSAL_EXIT, parseRoadmapBody, createGhRoadmapSearch, severalRoadmapsMessage, resolveRoadmapIssue, createGhOpenPullRequests, closedIssuesIn, branchClaims, scanClaimBranches, memoiseVerifier, isShellFence, commandOf, toolOf, heredocTerminator, continuesLine, isForeignCodeLine, SKILL_TIERS, isSkillTier, realEntry, skillTierDirectory, resolveInstinctScopes, tierExists, SCOPE_DIR, INIT_COMMAND, DISK_FILE_SYSTEM, ScopeError, scopeAt, initHint, selfAndAncestors, resolveScope, readPlanChanges, shellQuote, ghMissingMessage, ghUnauthenticatedMessage, ghHostOf, ghPreflightItems, resolvePrProvider, requireGhProvider, isFirstDispatch, SESSION_ID_FLAG2 as SESSION_ID_FLAG, SessionRecordError, runsDir, errorCode, readSessions, readSession, resolveLoopSeams, sessionIdFlag, refusal2 as refusal, isLive, planLabel, sessionLine, projectRoot, readRecords, pickSession, writeSession, readSessionChecklist, checkboxAt, estimateEta, readSessionFinishes, etaLine, verdictOf, failingRows, formatRows, waitForChecks, parseWorkingTree, parseWorktrees, readMergeRefusal, cleanUpSteps, commandLine, remainingFrom, createGhPullRequests, ghPullRequestsIn, DEFAULT_BASE_BRANCH, openNextSources, createLinePrompter, REMOTE, parseBaseStanding, hasDiverged, list_default, readNextState, commandWords, nextQuestion, NEXT_COMMAND_ACTIONS, actionInvocation, runAction, HINT_FLAG_SPEC, actionOutput, endWithNextStep, endingWith, DEFAULT_ISSUE_SEAMS, lineRefusal2 as lineRefusal, expectTwoArguments, readTextFlag, readNonBlankFlag, readRequiredFlag, readChoice, readChoiceFlag, issueProject, issueSubjectConfig, resolveIssueTracker, issueRef, issueName, urlLines, onTracker, lazyPrompter, ready_default, versionLine, DEFAULT_PLAN_FILE, resolvePlanPath, assessPlanRisk, renderRiskText, announceRiskTotal, resolveCreateSpec, resolveReleaseEnabled, TRIAGE_MODULE, DEFAULT_CI_TIMEOUT_MIN, CI_POLL_INTERVAL_MS, DEFAULT_CI_ATTEMPTS, RUNTIME_SUBDIR, RUNTIME_ENTRY, VERSION_SHAPE2 as VERSION_SHAPE, refuseMisplacedRuntime, groupChangeNotes, renderNoteLines, highestChangeLevel, parseSemanticVersion, readManifestVersion, MECHANICAL_CONFLICT_SENTENCE, start, usage, coreRoster, createPlanRefsVerifier, plan };
13332
+ export { readConfigFile, loadConfig, planStubsFromFileNames, resolvePlanStub, sessionLogDir, collectSessionRow, collect, report, name, version, MANIFEST_VERSION, FEATURE_TYPES, OUTPUT_CHANNELS, RUNNING_MANIFEST_SEAMS, validateManifest, plansDirAt, requireProject, resolvePlansDir, resolveProjectConfig, countTasks, formatCounts, checkbox, planFileName, stubOfPlanFile, isFile, issueLine, plural, expectNoArgument, expectOneArgument, expectAtMostOneArgument, readSwitch, readFrontmatterDocument, readFrontmatter, renderFrontmatter, mergeFrontmatter, writeFrontmatter, AGENT_DEFINITION_DIR, VENDOR_COMMAND, readAgentDirectory, readAgentDefinitions, resolveAgentRoster, missingPlanAgents, validate_default, SPEC_READY_LABEL, TEMPLATE_HEADINGS, findReadinessGaps, hasSpecReadyLabel, createGhPermissions, readAuthorTrust, trustRefusalClause, requireTrustedAuthor, SPEC_NEEDS_WORK_LABEL, SPEC_BLOCKED_LABEL, hasSpecBlockedLabel, readBlockedBy, blockedFaultMessage, UNREADABLE, RefsBlockError, fingerprintText, readRefsText, readCopyRefs, restampCopyRefs, createGitRunner, gitSaid, RefVerifyError, ghIssueReader, tsSymbolsOutliner, createRefVerifier, PROJECT_ID_LENGTH, PROJECT_ID_PATTERN, normalizeRemote, gitRemoteUrl, createGhIssueBoard, ID_PREFIX, BRANCH_PREFIX, SPEC_EXTENSION, boardId, notesFileName, PREVIOUS_COPY_WARN_ABOVE, previousDir, countPreviousCopies, SPEC_LABEL, createGhSpecIssueReader, ROADMAP_TITLE, ROADMAP_SETTING, ROADMAP_REFUSAL_EXIT, parseRoadmapBody, createGhRoadmapSearch, severalRoadmapsMessage, resolveRoadmapIssue, createGhOpenPullRequests, closedIssuesIn, branchClaims, scanClaimBranches, blockedLineSentence, memoiseVerifier, isShellFence, commandOf, toolOf, heredocTerminator, continuesLine, isForeignCodeLine, SKILL_TIERS, isSkillTier, realEntry, skillTierDirectory, resolveInstinctScopes, tierExists, SCOPE_DIR, INIT_COMMAND, DISK_FILE_SYSTEM, ScopeError, scopeAt, initHint, selfAndAncestors, resolveScope, readPlanChanges, shellQuote, ghMissingMessage, ghUnauthenticatedMessage, ghHostOf, ghPreflightItems, resolvePrProvider, requireGhProvider, isFirstDispatch, SESSION_ID_FLAG2 as SESSION_ID_FLAG, SessionRecordError, runsDir, errorCode, readSessions, readSession, resolveLoopSeams, sessionIdFlag, refusal2 as refusal, isLive, planLabel, sessionLine, projectRoot, readRecords, pickSession, writeSession, readSessionChecklist, checkboxAt, estimateEta, readSessionFinishes, etaLine, verdictOf, failingRows, formatRows, waitForChecks, parseWorkingTree, parseWorktrees, readMergeRefusal, cleanUpSteps, commandLine, remainingFrom, createGhPullRequests, ghPullRequestsIn, DEFAULT_BASE_BRANCH, ghNextBoard, openNextSources, createLinePrompter, REMOTE, parseBaseStanding, hasDiverged, list_default, readBranch, readPlans, readOpenPull, readBranchPlan, readNextState, commandWords, nextQuestion, NEXT_COMMAND_ACTIONS, actionInvocation, runAction, HINT_FLAG_SPEC, actionOutput, endWithNextStep, endingWith, DEFAULT_ISSUE_SEAMS, lineRefusal2 as lineRefusal, expectTwoArguments, readTextFlag, readNonBlankFlag, readRequiredFlag, readChoice, readChoiceFlag, issueProject, issueSubjectConfig, resolveIssueTracker, issueRef, issueName, urlLines, onTracker, lazyPrompter, ready_default, versionLine, DEFAULT_PLAN_FILE, resolvePlanPath, assessPlanRisk, renderRiskText, announceRiskTotal, resolveCreateSpec, resolveReleaseEnabled, TRIAGE_MODULE, DEFAULT_CI_TIMEOUT_MIN, CI_POLL_INTERVAL_MS, DEFAULT_CI_ATTEMPTS, RUNTIME_SUBDIR, RUNTIME_ENTRY, VERSION_SHAPE2 as VERSION_SHAPE, refuseMisplacedRuntime, groupChangeNotes, renderNoteLines, highestChangeLevel, parseSemanticVersion, readManifestVersion, MECHANICAL_CONFLICT_SENTENCE, start, usage, coreRoster, createPlanRefsVerifier, plan };
@@ -2,7 +2,7 @@
2
2
  import {
3
3
  activeOutput,
4
4
  readRafaBlocks
5
- } from "./index-6cw1n0qy.js";
5
+ } from "./index-ps5sac9p.js";
6
6
  import {
7
7
  messageOf,
8
8
  parseTaskDeclaration
@@ -16,7 +16,7 @@ var ITEM_RE = /^-\s+\[\s*\]\s+/;
16
16
  var INLINE_AUTO_RE = /^-\s+\[\s*\]\s+\[auto\]\s+/i;
17
17
  var INLINE_HUMAN_RE = /^-\s+\[\s*\]\s+\[human\]\s+/i;
18
18
  var INLINE_START_RE = /^-\s+\[\s*\]\s+\[start\]\s+/i;
19
- var BACKTICK_RE = /`([^`]+)`/;
19
+ var PROBE_RE = /:\s+`([^`]+)`\s*$/;
20
20
  var HEADING_MARKS_RE = /^#+/;
21
21
  var FENCE_RE = /^ {0,3}(`{3,}|~{3,})/;
22
22
  var NESTED_LIST_ITEM_RE = /^\s+(?:[-*+]|\d+[.)])\s/;
@@ -78,7 +78,7 @@ function isProbedTag(tag) {
78
78
  return tag === "auto" || tag === "start";
79
79
  }
80
80
  function extractProbe(description) {
81
- const probe = BACKTICK_RE.exec(description)?.[1]?.trim();
81
+ const probe = PROBE_RE.exec(description)?.[1]?.trim();
82
82
  return probe || null;
83
83
  }
84
84
  function readItem(lines, lineIndex, inherited) {
@@ -125,24 +125,37 @@ function requiredItemsTagged(items, tag) {
125
125
  const probed = items.filter(isProbed).filter((item) => item.tag === tag);
126
126
  return Object.freeze(probed.map(requiredItem));
127
127
  }
128
- function reminderOf(item) {
128
+ function namedItemOf(item) {
129
129
  return Object.freeze({ description: item.description, tag: item.tag, line: item.lineIndex + 1 });
130
130
  }
131
+ function isMalformed(item) {
132
+ return isProbedTag(item.tag) && item.probe === null;
133
+ }
131
134
  function planPrerequisites(content) {
132
135
  const items = parsePrerequisites(content);
133
136
  return Object.freeze({
134
137
  required: requiredItemsTagged(items, "auto"),
135
138
  startRequired: requiredItemsTagged(items, "start"),
136
- reminders: Object.freeze(items.filter((item) => !isProbed(item)).map(reminderOf))
139
+ reminders: Object.freeze(items.filter((item) => !isProbedTag(item.tag)).map(namedItemOf)),
140
+ malformed: Object.freeze(items.filter(isMalformed).map(namedItemOf))
137
141
  });
138
142
  }
143
+ var PROBE_ITEM_EXAMPLE = "- [ ] uv installed: `uvx --version`";
144
+ function malformedPrerequisiteLines(file, malformed) {
145
+ return [
146
+ `${file} holds ${malformed.length} malformed [auto] or [start] item(s): no command ends the item after a final ": ".`,
147
+ ...malformed.map((item) => ` line ${item.line} [${item.tag}]: ${item.description}`),
148
+ `Write each as ${PROBE_ITEM_EXAMPLE}, its one backticked span a complete command run as written;` + " prove a tool is there with `<tool> --version`, `<tool> --help` or `which <tool>`."
149
+ ];
150
+ }
139
151
  function mergePlanPrerequisites(settings, content) {
140
152
  const plan = planPrerequisites(content ?? "");
141
153
  return Object.freeze({
142
154
  required: Object.freeze([...settings.prerequisitesRequired, ...plan.required]),
143
155
  startRequired: plan.startRequired,
144
156
  optional: Object.freeze([...settings.prerequisitesOptional]),
145
- reminders: plan.reminders
157
+ reminders: plan.reminders,
158
+ malformed: plan.malformed
146
159
  });
147
160
  }
148
161
  function prerequisitesPathForPlan(planPath) {
@@ -1100,4 +1113,4 @@ function renderInjection(request) {
1100
1113
  }
1101
1114
  return { requested: mode, mode, text: RENDERERS[mode](model, location.task), fallback: null };
1102
1115
  }
1103
- export { isStampableStub, planStubFromPrompt, stampPrompt, planStubFromPath, REPORT_STATUSES, FINDING_KINDS, FINDING_SIGNALS, CHANGE_LEVELS, parseReport, escapeBlockerText, splitBlockerComment, findNextTask, updateTrackerLine, writeTrackerBlocker, trackerPathFor, PLAN_BLOCK_KINDS, PLAN_HEADER_FIELDS, parsePlan, parsePrerequisites, planPrerequisites, mergePlanPrerequisites, prerequisitesPathForPlan, loadPlanPrerequisites, PROBE_TIMEOUT_MS, runShellProbe, runPreflight, renderInjection };
1116
+ export { isStampableStub, planStubFromPrompt, stampPrompt, planStubFromPath, REPORT_STATUSES, FINDING_KINDS, FINDING_SIGNALS, CHANGE_LEVELS, parseReport, escapeBlockerText, splitBlockerComment, findNextTask, updateTrackerLine, writeTrackerBlocker, trackerPathFor, PLAN_BLOCK_KINDS, PLAN_HEADER_FIELDS, parsePlan, parsePrerequisites, planPrerequisites, malformedPrerequisiteLines, mergePlanPrerequisites, prerequisitesPathForPlan, loadPlanPrerequisites, PROBE_TIMEOUT_MS, runShellProbe, runPreflight, renderInjection };
@@ -4,7 +4,7 @@ import {
4
4
  activeOutputMode,
5
5
  createTextOutput,
6
6
  readRafaBlocks
7
- } from "./index-6cw1n0qy.js";
7
+ } from "./index-ps5sac9p.js";
8
8
  import {
9
9
  commandSpelling
10
10
  } from "./index-p901zs2p.js";
@@ -1117,7 +1117,7 @@ var REST_STATES = {
1117
1117
  cancelled: "closed"
1118
1118
  };
1119
1119
  function createGhRunner(options) {
1120
- const { cwd, command = "gh", env } = options;
1120
+ const { cwd, command = "gh", env, timeoutMs } = options;
1121
1121
  return async (args) => {
1122
1122
  const executable = env === undefined ? command : Bun.which(command, { PATH: env.PATH ?? "", cwd });
1123
1123
  if (executable === null) {
@@ -1131,17 +1131,38 @@ function createGhRunner(options) {
1131
1131
  stdout: "pipe",
1132
1132
  stderr: "pipe"
1133
1133
  });
1134
- const [stdout, stderr, exitCode] = await Promise.all([
1134
+ const finished = Promise.all([
1135
1135
  new Response(proc.stdout).text(),
1136
1136
  new Response(proc.stderr).text(),
1137
1137
  proc.exited
1138
1138
  ]);
1139
+ const outcome = await withDeadline(finished, timeoutMs);
1140
+ if (outcome === TIMED_OUT) {
1141
+ proc.kill("SIGKILL");
1142
+ await proc.exited;
1143
+ return { ok: false, stdout: "", stderr: `${command} in ${cwd} timed out after ${timeoutMs}ms and was killed` };
1144
+ }
1145
+ const [stdout, stderr, exitCode] = outcome;
1139
1146
  return { ok: exitCode === 0, stdout, stderr };
1140
1147
  } catch (error) {
1141
1148
  return { ok: false, stdout: "", stderr: `could not run ${command} in ${cwd}: ${messageOf(error)}` };
1142
1149
  }
1143
1150
  };
1144
1151
  }
1152
+ var TIMED_OUT = Symbol("timed out");
1153
+ async function withDeadline(work, timeoutMs) {
1154
+ if (timeoutMs === undefined)
1155
+ return work;
1156
+ let timer;
1157
+ const deadline = new Promise((resolve2) => {
1158
+ timer = setTimeout(() => resolve2(TIMED_OUT), timeoutMs);
1159
+ });
1160
+ try {
1161
+ return await Promise.race([work, deadline]);
1162
+ } finally {
1163
+ clearTimeout(timer);
1164
+ }
1165
+ }
1145
1166
  function notOnPath(command, cwd, path) {
1146
1167
  const searched = path === undefined ? "an environment with no PATH" : `PATH ${JSON.stringify(path)}`;
1147
1168
  return `could not run ${command} in ${cwd}: not found on ${searched} (ENOENT)`;
@@ -63,7 +63,8 @@ var CONFIG_DEFAULTS = Object.freeze({
63
63
  cleanupStaleDays: 30,
64
64
  cleanupWorktreeIdleDays: 7,
65
65
  cleanupKeep: Object.freeze([]),
66
- dangerousAcceptStaleRefs: false
66
+ dangerousAcceptStaleRefs: false,
67
+ statusNotice: true
67
68
  });
68
69
  var directory = text("a directory path");
69
70
  var trackerKind = text("a tracker kind name");
@@ -154,7 +155,8 @@ var SETTINGS = {
154
155
  key: "dangerous.acceptStaleRefs",
155
156
  read: flag,
156
157
  cli: false
157
- }
158
+ },
159
+ statusNotice: { key: "status.notice", read: flag, cli: false }
158
160
  };
159
161
  var SETTING_NAMES = Object.keys(SETTINGS);
160
162
  var SETTING_BY_KEY = new Map(SETTING_NAMES.map((setting) => [
@@ -252,7 +254,8 @@ function readLayer(rawOf, atOf) {
252
254
  cleanupStaleDays: read("cleanupStaleDays"),
253
255
  cleanupWorktreeIdleDays: read("cleanupWorktreeIdleDays"),
254
256
  cleanupKeep: read("cleanupKeep"),
255
- dangerousAcceptStaleRefs: read("dangerousAcceptStaleRefs")
257
+ dangerousAcceptStaleRefs: read("dangerousAcceptStaleRefs"),
258
+ statusNotice: read("statusNotice")
256
259
  };
257
260
  return { layer, problems, extras };
258
261
  }