@sideboard-ai/core 0.1.279 → 0.1.280

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/index.d.cts CHANGED
@@ -5738,7 +5738,7 @@ declare class Orchestrator {
5738
5738
  initializeGit(threadRef: string): Promise<void>;
5739
5739
  listFiles(threadRef: string): Promise<string[]>;
5740
5740
  statPath(threadRef: string, relativePath: string): Promise<'file' | 'dir' | 'missing'>;
5741
- readFile(threadRef: string, relativePath: string): Promise<{
5741
+ readFile(threadRef: string, relativePath: string, tail?: boolean): Promise<{
5742
5742
  path: string;
5743
5743
  content: string;
5744
5744
  truncated: boolean;
@@ -7024,7 +7024,7 @@ interface IpcApi {
7024
7024
  listFiles(threadRef: string): Promise<string[]>;
7025
7025
  /** Classify a worktree path so chat links can preview files or reveal folders. */
7026
7026
  statPath(threadRef: string, relativePath: string): Promise<'file' | 'dir' | 'missing'>;
7027
- readFile(threadRef: string, relativePath: string): Promise<{
7027
+ readFile(threadRef: string, relativePath: string, tail?: boolean): Promise<{
7028
7028
  path: string;
7029
7029
  content: string;
7030
7030
  truncated: boolean;
package/dist/index.d.ts CHANGED
@@ -5738,7 +5738,7 @@ declare class Orchestrator {
5738
5738
  initializeGit(threadRef: string): Promise<void>;
5739
5739
  listFiles(threadRef: string): Promise<string[]>;
5740
5740
  statPath(threadRef: string, relativePath: string): Promise<'file' | 'dir' | 'missing'>;
5741
- readFile(threadRef: string, relativePath: string): Promise<{
5741
+ readFile(threadRef: string, relativePath: string, tail?: boolean): Promise<{
5742
5742
  path: string;
5743
5743
  content: string;
5744
5744
  truncated: boolean;
@@ -7024,7 +7024,7 @@ interface IpcApi {
7024
7024
  listFiles(threadRef: string): Promise<string[]>;
7025
7025
  /** Classify a worktree path so chat links can preview files or reveal folders. */
7026
7026
  statPath(threadRef: string, relativePath: string): Promise<'file' | 'dir' | 'missing'>;
7027
- readFile(threadRef: string, relativePath: string): Promise<{
7027
+ readFile(threadRef: string, relativePath: string, tail?: boolean): Promise<{
7028
7028
  path: string;
7029
7029
  content: string;
7030
7030
  truncated: boolean;
package/dist/index.js CHANGED
@@ -185,7 +185,7 @@ import {
185
185
  worktreeBoardStatus,
186
186
  worktreeCleanupSettings,
187
187
  writeWorktreeFile
188
- } from "./chunk-V5DMHB6Y.js";
188
+ } from "./chunk-DK4DKQ2H.js";
189
189
  import {
190
190
  BASE_ALLOWED_TOOLS,
191
191
  BRIGHTSY_MCP_ALLOWED_TOOLS,
@@ -4949,7 +4949,7 @@ async function handleJobStop(params, _ctx) {
4949
4949
  return stopDetachedJob(jobCwd(rec), id, reason ? { reason } : void 0);
4950
4950
  }
4951
4951
  async function defaultTurnWait(ref, timeoutMs) {
4952
- const { getOrchestrator: getOrchestrator2 } = await import("./orchestrator-KY2KBBE2.js");
4952
+ const { getOrchestrator: getOrchestrator2 } = await import("./orchestrator-XEKODYDQ.js");
4953
4953
  const orch = getOrchestrator2();
4954
4954
  const thread = await orch.waitForTurn(ref, timeoutMs, {
4955
4955
  resolveIfStillRunning: true
@@ -12408,7 +12408,7 @@ async function continueSourceThread(threadId, prompt) {
12408
12408
  await continueOnReply(threadId, prompt);
12409
12409
  return;
12410
12410
  }
12411
- const { getOrchestrator: getOrchestrator2 } = await import("./orchestrator-KY2KBBE2.js");
12411
+ const { getOrchestrator: getOrchestrator2 } = await import("./orchestrator-XEKODYDQ.js");
12412
12412
  await getOrchestrator2().send(threadId, prompt);
12413
12413
  } catch {
12414
12414
  }
@@ -22893,6 +22893,51 @@ var init_land = __esm({
22893
22893
  }
22894
22894
  });
22895
22895
 
22896
+ // src/diff/read-worktree-tail.ts
22897
+ function readWorktreeFileTail(worktreePath, relativePath, maxBytes = WORKTREE_TAIL_BYTES) {
22898
+ if (!relativePath || relativePath.includes("..") || relativePath.startsWith("/")) {
22899
+ throw new Error("Invalid path");
22900
+ }
22901
+ const abs = (0, import_node_path55.join)(worktreePath, relativePath);
22902
+ const fd = (0, import_node_fs58.openSync)(abs, "r");
22903
+ try {
22904
+ const st = (0, import_node_fs58.fstatSync)(fd);
22905
+ if (!st.isFile()) throw new Error(`Not a file: ${relativePath}`);
22906
+ const size = st.size;
22907
+ const start = Math.max(0, size - maxBytes);
22908
+ const length = size - start;
22909
+ const buf = Buffer.alloc(length);
22910
+ if (length > 0) (0, import_node_fs58.readSync)(fd, buf, 0, length, start);
22911
+ if (buf.subarray(0, Math.min(buf.length, 8e3)).includes(0)) {
22912
+ return {
22913
+ path: relativePath,
22914
+ content: `(binary file, ${size} bytes)`,
22915
+ truncated: false,
22916
+ binary: true,
22917
+ encoding: "utf8"
22918
+ };
22919
+ }
22920
+ let content = buf.toString("utf8");
22921
+ const truncated = start > 0;
22922
+ if (truncated) {
22923
+ const nl = content.indexOf("\n");
22924
+ if (nl >= 0) content = content.slice(nl + 1);
22925
+ }
22926
+ return { path: relativePath, content, truncated, binary: false, encoding: "utf8" };
22927
+ } finally {
22928
+ (0, import_node_fs58.closeSync)(fd);
22929
+ }
22930
+ }
22931
+ var import_node_fs58, import_node_path55, WORKTREE_TAIL_BYTES;
22932
+ var init_read_worktree_tail = __esm({
22933
+ "src/diff/read-worktree-tail.ts"() {
22934
+ "use strict";
22935
+ import_node_fs58 = require("fs");
22936
+ import_node_path55 = require("path");
22937
+ WORKTREE_TAIL_BYTES = 2e5;
22938
+ }
22939
+ });
22940
+
22896
22941
  // src/skills/bundled/long-running.ts
22897
22942
  var LONG_RUNNING_SKILL_COMMAND, LONG_RUNNING_SKILL_NAME, BUNDLED_LONG_RUNNING_PATH, LONG_RUNNING_SKILL_DESCRIPTION, LONG_RUNNING_SKILL_BODY;
22898
22943
  var init_long_running = __esm({
@@ -23037,7 +23082,7 @@ function parseFrontmatter(content) {
23037
23082
  }
23038
23083
  function readSkill(skillMd, source) {
23039
23084
  try {
23040
- const content = (0, import_node_fs58.readFileSync)(skillMd, "utf8");
23085
+ const content = (0, import_node_fs59.readFileSync)(skillMd, "utf8");
23041
23086
  const { name: fmName, description } = parseFrontmatter(content);
23042
23087
  const dirName = skillMd.split("/").slice(-2, -1)[0] || "skill";
23043
23088
  const name = fmName || dirName;
@@ -23056,19 +23101,19 @@ function readSkill(skillMd, source) {
23056
23101
  }
23057
23102
  }
23058
23103
  function scanSkillsDir(dir, source, out) {
23059
- if (!(0, import_node_fs58.existsSync)(dir)) return;
23104
+ if (!(0, import_node_fs59.existsSync)(dir)) return;
23060
23105
  let entries;
23061
23106
  try {
23062
- entries = (0, import_node_fs58.readdirSync)(dir);
23107
+ entries = (0, import_node_fs59.readdirSync)(dir);
23063
23108
  } catch {
23064
23109
  return;
23065
23110
  }
23066
23111
  for (const entry of entries) {
23067
23112
  if (entry.startsWith(".")) continue;
23068
- const skillMd = (0, import_node_path55.join)(dir, entry, "SKILL.md");
23069
- if (!(0, import_node_fs58.existsSync)(skillMd)) continue;
23113
+ const skillMd = (0, import_node_path56.join)(dir, entry, "SKILL.md");
23114
+ if (!(0, import_node_fs59.existsSync)(skillMd)) continue;
23070
23115
  try {
23071
- if (!(0, import_node_fs58.statSync)(skillMd).isFile()) continue;
23116
+ if (!(0, import_node_fs59.statSync)(skillMd).isFile()) continue;
23072
23117
  } catch {
23073
23118
  continue;
23074
23119
  }
@@ -23077,24 +23122,24 @@ function scanSkillsDir(dir, source, out) {
23077
23122
  }
23078
23123
  }
23079
23124
  function scanClaudePluginSkills(pluginsRoot, out) {
23080
- if (!(0, import_node_fs58.existsSync)(pluginsRoot)) return;
23125
+ if (!(0, import_node_fs59.existsSync)(pluginsRoot)) return;
23081
23126
  const walk = (dir, depth, lookingForSkillsDir) => {
23082
23127
  if (depth > 7) return;
23083
23128
  let entries;
23084
23129
  try {
23085
- entries = (0, import_node_fs58.readdirSync)(dir);
23130
+ entries = (0, import_node_fs59.readdirSync)(dir);
23086
23131
  } catch {
23087
23132
  return;
23088
23133
  }
23089
23134
  if (lookingForSkillsDir && entries.includes("SKILL.md")) {
23090
- const skill = readSkill((0, import_node_path55.join)(dir, "SKILL.md"), "cli");
23135
+ const skill = readSkill((0, import_node_path56.join)(dir, "SKILL.md"), "cli");
23091
23136
  if (skill) out.push(skill);
23092
23137
  }
23093
23138
  for (const entry of entries) {
23094
23139
  if (entry === "node_modules" || entry === ".git") continue;
23095
- const full = (0, import_node_path55.join)(dir, entry);
23140
+ const full = (0, import_node_path56.join)(dir, entry);
23096
23141
  try {
23097
- if (!(0, import_node_fs58.statSync)(full).isDirectory()) continue;
23142
+ if (!(0, import_node_fs59.statSync)(full).isDirectory()) continue;
23098
23143
  } catch {
23099
23144
  continue;
23100
23145
  }
@@ -23112,17 +23157,17 @@ function discoverSkills(worktreePath) {
23112
23157
  const home = (0, import_node_os16.homedir)();
23113
23158
  const collected = [];
23114
23159
  for (const rel of [".claude/skills", ".cursor/skills", ".sideboard/skills", ".brightsy/skills", "skills"]) {
23115
- scanSkillsDir((0, import_node_path55.join)(worktreePath, rel), "workspace", collected);
23160
+ scanSkillsDir((0, import_node_path56.join)(worktreePath, rel), "workspace", collected);
23116
23161
  }
23117
23162
  for (const abs of [
23118
- (0, import_node_path55.join)(home, ".claude/skills"),
23119
- (0, import_node_path55.join)(home, ".cursor/skills"),
23120
- (0, import_node_path55.join)(home, ".sideboard/skills"),
23121
- (0, import_node_path55.join)(home, ".brightsy/skills")
23163
+ (0, import_node_path56.join)(home, ".claude/skills"),
23164
+ (0, import_node_path56.join)(home, ".cursor/skills"),
23165
+ (0, import_node_path56.join)(home, ".sideboard/skills"),
23166
+ (0, import_node_path56.join)(home, ".brightsy/skills")
23122
23167
  ]) {
23123
23168
  scanSkillsDir(abs, "user", collected);
23124
23169
  }
23125
- scanClaudePluginSkills((0, import_node_path55.join)(home, ".claude/plugins"), collected);
23170
+ scanClaudePluginSkills((0, import_node_path56.join)(home, ".claude/plugins"), collected);
23126
23171
  collected.push(...bundledSkills());
23127
23172
  const rank = {
23128
23173
  workspace: 0,
@@ -23148,7 +23193,7 @@ function readSkillBody(skillPath, maxChars = 12e3) {
23148
23193
  \u2026(truncated)` : body;
23149
23194
  }
23150
23195
  }
23151
- const raw = (0, import_node_fs58.readFileSync)(skillPath, "utf8");
23196
+ const raw = (0, import_node_fs59.readFileSync)(skillPath, "utf8");
23152
23197
  if (raw.startsWith("---")) {
23153
23198
  const end = raw.indexOf("\n---", 3);
23154
23199
  if (end >= 0) {
@@ -23162,13 +23207,13 @@ function readSkillBody(skillPath, maxChars = 12e3) {
23162
23207
 
23163
23208
  \u2026(truncated)` : raw;
23164
23209
  }
23165
- var import_node_fs58, import_node_os16, import_node_path55, BUNDLED_SKILL_PREFIX;
23210
+ var import_node_fs59, import_node_os16, import_node_path56, BUNDLED_SKILL_PREFIX;
23166
23211
  var init_discover = __esm({
23167
23212
  "src/skills/discover.ts"() {
23168
23213
  "use strict";
23169
- import_node_fs58 = require("fs");
23214
+ import_node_fs59 = require("fs");
23170
23215
  import_node_os16 = require("os");
23171
- import_node_path55 = require("path");
23216
+ import_node_path56 = require("path");
23172
23217
  init_long_running();
23173
23218
  BUNDLED_SKILL_PREFIX = "bundled:";
23174
23219
  }
@@ -23323,7 +23368,7 @@ function compiledModuleDir() {
23323
23368
  try {
23324
23369
  const url = import_meta5.url;
23325
23370
  if (typeof url === "string" && url.length > 0) {
23326
- return (0, import_node_path56.dirname)((0, import_node_url5.fileURLToPath)(url));
23371
+ return (0, import_node_path57.dirname)((0, import_node_url5.fileURLToPath)(url));
23327
23372
  }
23328
23373
  } catch {
23329
23374
  }
@@ -23331,8 +23376,8 @@ function compiledModuleDir() {
23331
23376
  }
23332
23377
  function detachedJobScriptIn(dir) {
23333
23378
  for (const name of DETACHED_JOB_FILENAMES) {
23334
- const script = (0, import_node_path56.join)(dir, "scripts", name);
23335
- if ((0, import_node_fs59.existsSync)(script)) return script;
23379
+ const script = (0, import_node_path57.join)(dir, "scripts", name);
23380
+ if ((0, import_node_fs60.existsSync)(script)) return script;
23336
23381
  }
23337
23382
  return null;
23338
23383
  }
@@ -23349,7 +23394,7 @@ function resolveDetachedJobScript() {
23349
23394
  for (let i = 0; i < 8; i++) {
23350
23395
  const candidate = detachedJobScriptIn(dir);
23351
23396
  if (candidate) return candidate;
23352
- const parent = (0, import_node_path56.dirname)(dir);
23397
+ const parent = (0, import_node_path57.dirname)(dir);
23353
23398
  if (parent === dir) break;
23354
23399
  dir = parent;
23355
23400
  }
@@ -23360,12 +23405,12 @@ function formatDetachedJobInvoke(scriptPath) {
23360
23405
  if (resolved) return `node ${JSON.stringify(resolved)}`;
23361
23406
  return "node scripts/detached-job.cjs";
23362
23407
  }
23363
- var import_node_fs59, import_node_path56, import_node_url5, import_meta5, DETACHED_JOB_FILENAMES;
23408
+ var import_node_fs60, import_node_path57, import_node_url5, import_meta5, DETACHED_JOB_FILENAMES;
23364
23409
  var init_detached_job_path = __esm({
23365
23410
  "src/skills/detached-job-path.ts"() {
23366
23411
  "use strict";
23367
- import_node_fs59 = require("fs");
23368
- import_node_path56 = require("path");
23412
+ import_node_fs60 = require("fs");
23413
+ import_node_path57 = require("path");
23369
23414
  import_node_url5 = require("url");
23370
23415
  init_packaged_runtime();
23371
23416
  import_meta5 = {};
@@ -23559,9 +23604,9 @@ function formatPrGateDirective() {
23559
23604
  }
23560
23605
  function formatProcessGuideDirective(opts) {
23561
23606
  const worktree = opts?.worktreePath?.trim();
23562
- const hasGraphSkill = !!worktree && (0, import_node_fs60.existsSync)((0, import_node_path57.join)(worktree, ".claude/skills/graph-engineering/SKILL.md"));
23563
- const hasReviewSkill = !!worktree && (0, import_node_fs60.existsSync)((0, import_node_path57.join)(worktree, ".claude/skills/review/SKILL.md"));
23564
- const hasInstallSkill = !!worktree && (0, import_node_fs60.existsSync)((0, import_node_path57.join)(worktree, ".claude/skills/worktree-install/SKILL.md"));
23607
+ const hasGraphSkill = !!worktree && (0, import_node_fs61.existsSync)((0, import_node_path58.join)(worktree, ".claude/skills/graph-engineering/SKILL.md"));
23608
+ const hasReviewSkill = !!worktree && (0, import_node_fs61.existsSync)((0, import_node_path58.join)(worktree, ".claude/skills/review/SKILL.md"));
23609
+ const hasInstallSkill = !!worktree && (0, import_node_fs61.existsSync)((0, import_node_path58.join)(worktree, ".claude/skills/worktree-install/SKILL.md"));
23565
23610
  return [
23566
23611
  "Process guides (recurring work only):",
23567
23612
  hasGraphSkill ? "- Migrations, ports, batch fixes, and other fan-out: follow `.claude/skills/graph-engineering/SKILL.md` (`/graph-engineering`). Judge first; state on disk; grow the rulebook; do not patch around it." : null,
@@ -23600,12 +23645,12 @@ function formatArtifactDirective() {
23600
23645
  function formatUiReminder() {
23601
23646
  return "Sideboard UI: markdown table is enough to read data; present_schema if they ask to edit/filter (even after markdown); present_files for the file manager. html fence or present_artifact, not both for the same document. type=log appends (same artifact_id, new lines only). ask_user only for a real multiple-choice (not hellos, \u201Cwhat next?\u201D, or after a review) \u2014 reply in chat. ask_user wakes the parent orchestrator; notify_orchestrator if blocked without a picker. Do not say artifacts/CMS UI are unavailable. Dev / preview: run_dev_script (same as the Dev button; pass name \u2014 several scripts can run at once) returns {url, port, preview} (SIDEBOARD_PORT \u2014 never guess :3000). preview=url \u2192 open url; preview=window \u2192 Electron window is the app, url is renderer/HMR only. list_run_scripts active[].url if already running; get_run_log for that script\u2019s Run-tab terminal; stop_dev_script to stop one.";
23602
23647
  }
23603
- var import_node_fs60, import_node_path57, PR_GOAL_RE, GITHUB_TICKET_REF, KEYED_TICKET_REF;
23648
+ var import_node_fs61, import_node_path58, PR_GOAL_RE, GITHUB_TICKET_REF, KEYED_TICKET_REF;
23604
23649
  var init_instructions = __esm({
23605
23650
  "src/agents/instructions.ts"() {
23606
23651
  "use strict";
23607
- import_node_fs60 = require("fs");
23608
- import_node_path57 = require("path");
23652
+ import_node_fs61 = require("fs");
23653
+ import_node_path58 = require("path");
23609
23654
  init_git_auth_mode();
23610
23655
  init_branch_prefix();
23611
23656
  init_worktree_labels();
@@ -23745,40 +23790,40 @@ __export(plan_file_exports, {
23745
23790
  writePlanFile: () => writePlanFile
23746
23791
  });
23747
23792
  function ensureAttachmentsGitignore(worktreePath) {
23748
- const gitignoreAbs = (0, import_node_path58.join)(worktreePath, ATTACHMENTS_DIR, ".gitignore");
23749
- if ((0, import_node_fs61.existsSync)(gitignoreAbs)) return;
23750
- (0, import_node_fs61.mkdirSync)((0, import_node_path58.dirname)(gitignoreAbs), { recursive: true });
23751
- (0, import_node_fs61.writeFileSync)(gitignoreAbs, attachmentsGitignoreBody(), "utf8");
23793
+ const gitignoreAbs = (0, import_node_path59.join)(worktreePath, ATTACHMENTS_DIR, ".gitignore");
23794
+ if ((0, import_node_fs62.existsSync)(gitignoreAbs)) return;
23795
+ (0, import_node_fs62.mkdirSync)((0, import_node_path59.dirname)(gitignoreAbs), { recursive: true });
23796
+ (0, import_node_fs62.writeFileSync)(gitignoreAbs, attachmentsGitignoreBody(), "utf8");
23752
23797
  }
23753
23798
  function planFileAbs(worktreePath) {
23754
- return (0, import_node_path58.join)(worktreePath, PLAN_FILE_REL);
23799
+ return (0, import_node_path59.join)(worktreePath, PLAN_FILE_REL);
23755
23800
  }
23756
23801
  function readTextIfPresent2(abs) {
23757
- if (!(0, import_node_fs61.existsSync)(abs)) return null;
23802
+ if (!(0, import_node_fs62.existsSync)(abs)) return null;
23758
23803
  try {
23759
- const content = (0, import_node_fs61.readFileSync)(abs, "utf8");
23804
+ const content = (0, import_node_fs62.readFileSync)(abs, "utf8");
23760
23805
  return content.trim() ? content : null;
23761
23806
  } catch {
23762
23807
  return null;
23763
23808
  }
23764
23809
  }
23765
23810
  function readPlanFile(worktreePath) {
23766
- return readTextIfPresent2(planFileAbs(worktreePath)) ?? readTextIfPresent2((0, import_node_path58.join)(worktreePath, `${LEGACY_ATTACHMENTS_DIR}/plan.md`)) ?? readTextIfPresent2((0, import_node_path58.join)(worktreePath, LEGACY_PLAN_FILE_REL));
23811
+ return readTextIfPresent2(planFileAbs(worktreePath)) ?? readTextIfPresent2((0, import_node_path59.join)(worktreePath, `${LEGACY_ATTACHMENTS_DIR}/plan.md`)) ?? readTextIfPresent2((0, import_node_path59.join)(worktreePath, LEGACY_PLAN_FILE_REL));
23767
23812
  }
23768
23813
  function writePlanFile(worktreePath, content) {
23769
23814
  ensureAttachmentsGitignore(worktreePath);
23770
23815
  const abs = planFileAbs(worktreePath);
23771
- (0, import_node_fs61.mkdirSync)((0, import_node_path58.dirname)(abs), { recursive: true });
23816
+ (0, import_node_fs62.mkdirSync)((0, import_node_path59.dirname)(abs), { recursive: true });
23772
23817
  const body = content.trimEnd() + (content.endsWith("\n") ? "" : "\n");
23773
- (0, import_node_fs61.writeFileSync)(abs, body, "utf8");
23818
+ (0, import_node_fs62.writeFileSync)(abs, body, "utf8");
23774
23819
  return PLAN_FILE_REL;
23775
23820
  }
23776
- var import_node_fs61, import_node_path58;
23821
+ var import_node_fs62, import_node_path59;
23777
23822
  var init_plan_file = __esm({
23778
23823
  "src/plan/plan-file.ts"() {
23779
23824
  "use strict";
23780
- import_node_fs61 = require("fs");
23781
- import_node_path58 = require("path");
23825
+ import_node_fs62 = require("fs");
23826
+ import_node_path59 = require("path");
23782
23827
  init_workspace_scratch();
23783
23828
  init_plan_present();
23784
23829
  init_plan_present();
@@ -23827,7 +23872,7 @@ function setCaffeinateHoldHooks(next) {
23827
23872
  hooks = next;
23828
23873
  }
23829
23874
  function caffeinateHoldPath() {
23830
- return (0, import_node_path59.join)(appDataDir(), "caffeinate-hold.json");
23875
+ return (0, import_node_path60.join)(appDataDir(), "caffeinate-hold.json");
23831
23876
  }
23832
23877
  function processAlive(pid) {
23833
23878
  if (hooks.processAlive) return hooks.processAlive(pid);
@@ -23861,9 +23906,9 @@ function uniqueIds(ids) {
23861
23906
  }
23862
23907
  function readHold() {
23863
23908
  const path = caffeinateHoldPath();
23864
- if (!(0, import_node_fs62.existsSync)(path)) return null;
23909
+ if (!(0, import_node_fs63.existsSync)(path)) return null;
23865
23910
  try {
23866
- const parsed = JSON.parse((0, import_node_fs62.readFileSync)(path, "utf8"));
23911
+ const parsed = JSON.parse((0, import_node_fs63.readFileSync)(path, "utf8"));
23867
23912
  if (typeof parsed?.pid === "number" && parsed.pid > 0) {
23868
23913
  return {
23869
23914
  pid: parsed.pid,
@@ -23885,7 +23930,7 @@ function writeHold(pid, threadIds) {
23885
23930
  }
23886
23931
  function clearHold() {
23887
23932
  try {
23888
- (0, import_node_fs62.unlinkSync)(caffeinateHoldPath());
23933
+ (0, import_node_fs63.unlinkSync)(caffeinateHoldPath());
23889
23934
  } catch {
23890
23935
  }
23891
23936
  }
@@ -23970,13 +24015,13 @@ function releaseCaffeinateHoldForThread(threadId) {
23970
24015
  }
23971
24016
  return setCaffeinateHold(false, { threadId: id });
23972
24017
  }
23973
- var import_node_child_process6, import_node_fs62, import_node_path59, hooks;
24018
+ var import_node_child_process6, import_node_fs63, import_node_path60, hooks;
23974
24019
  var init_caffeinate_hold = __esm({
23975
24020
  "src/store/caffeinate-hold.ts"() {
23976
24021
  "use strict";
23977
24022
  import_node_child_process6 = require("child_process");
23978
- import_node_fs62 = require("fs");
23979
- import_node_path59 = require("path");
24023
+ import_node_fs63 = require("fs");
24024
+ import_node_path60 = require("path");
23980
24025
  init_paths();
23981
24026
  init_private_file();
23982
24027
  hooks = {};
@@ -23985,7 +24030,7 @@ var init_caffeinate_hold = __esm({
23985
24030
 
23986
24031
  // src/store/schedules.ts
23987
24032
  function schedulesPath() {
23988
- return (0, import_node_path60.join)(appDataDir(), "schedules.json");
24033
+ return (0, import_node_path61.join)(appDataDir(), "schedules.json");
23989
24034
  }
23990
24035
  function parseDurationMs(every) {
23991
24036
  const m = every.trim().match(DURATION_RE);
@@ -24085,9 +24130,9 @@ function normalizeTask(raw) {
24085
24130
  }
24086
24131
  function readAll2() {
24087
24132
  const path = schedulesPath();
24088
- if (!(0, import_node_fs63.existsSync)(path)) return [];
24133
+ if (!(0, import_node_fs64.existsSync)(path)) return [];
24089
24134
  try {
24090
- const parsed = JSON.parse((0, import_node_fs63.readFileSync)(path, "utf8"));
24135
+ const parsed = JSON.parse((0, import_node_fs64.readFileSync)(path, "utf8"));
24091
24136
  if (!Array.isArray(parsed)) return [];
24092
24137
  return parsed.map((row) => {
24093
24138
  try {
@@ -24212,13 +24257,13 @@ function recordScheduleRun(id, result) {
24212
24257
  writeAll2(rows);
24213
24258
  return next;
24214
24259
  }
24215
- var import_node_crypto13, import_node_fs63, import_node_path60, import_croner, DURATION_RE, UNIT_MS;
24260
+ var import_node_crypto13, import_node_fs64, import_node_path61, import_croner, DURATION_RE, UNIT_MS;
24216
24261
  var init_schedules = __esm({
24217
24262
  "src/store/schedules.ts"() {
24218
24263
  "use strict";
24219
24264
  import_node_crypto13 = require("crypto");
24220
- import_node_fs63 = require("fs");
24221
- import_node_path60 = require("path");
24265
+ import_node_fs64 = require("fs");
24266
+ import_node_path61 = require("path");
24222
24267
  import_croner = require("croner");
24223
24268
  init_orchestrator_capable();
24224
24269
  init_paths();
@@ -24367,9 +24412,9 @@ function recoverFinishedCursorRun(opts) {
24367
24412
  return best;
24368
24413
  }
24369
24414
  function scanFinishedCursorRuns(runsPath, agentId, startedAfterMs) {
24370
- if (!(0, import_node_fs64.existsSync)(runsPath)) return null;
24415
+ if (!(0, import_node_fs65.existsSync)(runsPath)) return null;
24371
24416
  try {
24372
- const lines = (0, import_node_fs64.readFileSync)(runsPath, "utf8").split("\n");
24417
+ const lines = (0, import_node_fs65.readFileSync)(runsPath, "utf8").split("\n");
24373
24418
  let best = null;
24374
24419
  for (const line of lines) {
24375
24420
  const trimmed = line.trim();
@@ -24395,11 +24440,11 @@ function scanFinishedCursorRuns(runsPath, agentId, startedAfterMs) {
24395
24440
  return null;
24396
24441
  }
24397
24442
  }
24398
- var import_node_fs64;
24443
+ var import_node_fs65;
24399
24444
  var init_cursor_recover = __esm({
24400
24445
  "src/agents/cursor-recover.ts"() {
24401
24446
  "use strict";
24402
- import_node_fs64 = require("fs");
24447
+ import_node_fs65 = require("fs");
24403
24448
  init_cursor_store();
24404
24449
  }
24405
24450
  });
@@ -24522,7 +24567,7 @@ async function startOrchestration(opts) {
24522
24567
  }
24523
24568
  return updated;
24524
24569
  }
24525
- var import_node_events, import_node_crypto14, import_node_fs65, LIVE_TURN_SPAWN_GRACE_MS, RUN_SCRIPT_DESKTOP_ADOPT_MS, STALE_AGENT_PID_WAIT_MS, LIGHT_RECONCILE_THROTTLE_MS, Orchestrator, singleton;
24570
+ var import_node_events, import_node_crypto14, import_node_fs66, LIVE_TURN_SPAWN_GRACE_MS, RUN_SCRIPT_DESKTOP_ADOPT_MS, STALE_AGENT_PID_WAIT_MS, LIGHT_RECONCILE_THROTTLE_MS, Orchestrator, singleton;
24526
24571
  var init_orchestrator = __esm({
24527
24572
  "src/orchestrator/orchestrator.ts"() {
24528
24573
  "use strict";
@@ -24531,7 +24576,7 @@ var init_orchestrator = __esm({
24531
24576
  init_task_state();
24532
24577
  init_wait_for_turn();
24533
24578
  import_node_crypto14 = require("crypto");
24534
- import_node_fs65 = require("fs");
24579
+ import_node_fs66 = require("fs");
24535
24580
  init_error_detail();
24536
24581
  init_run();
24537
24582
  init_stale_lock();
@@ -24580,6 +24625,7 @@ var init_orchestrator = __esm({
24580
24625
  init_stack_layers();
24581
24626
  init_land();
24582
24627
  init_diff();
24628
+ init_read_worktree_tail();
24583
24629
  init_discover();
24584
24630
  init_expand();
24585
24631
  init_consume_attachments();
@@ -24713,7 +24759,7 @@ var init_orchestrator = __esm({
24713
24759
  this.lightReconcileAt.set(repoPath, Date.now());
24714
24760
  for (const thread of listThreads()) {
24715
24761
  if (isGlobalThread(thread) || thread.repoPath !== repoPath) continue;
24716
- if (!(0, import_node_fs65.existsSync)(thread.worktreePath)) {
24762
+ if (!(0, import_node_fs66.existsSync)(thread.worktreePath)) {
24717
24763
  setStatus(thread.id, "broken", "Worktree missing on disk");
24718
24764
  this.emit({ type: "status_changed", threadId: thread.id, status: "broken" });
24719
24765
  }
@@ -24742,7 +24788,7 @@ var init_orchestrator = __esm({
24742
24788
  }
24743
24789
  continue;
24744
24790
  }
24745
- if (!(0, import_node_fs65.existsSync)(thread.worktreePath)) {
24791
+ if (!(0, import_node_fs66.existsSync)(thread.worktreePath)) {
24746
24792
  setStatus(thread.id, "broken", "Worktree missing on disk");
24747
24793
  this.emit({ type: "status_changed", threadId: thread.id, status: "broken" });
24748
24794
  continue;
@@ -26689,12 +26735,12 @@ var init_orchestrator = __esm({
26689
26735
  return "missing";
26690
26736
  }
26691
26737
  }
26692
- async readFile(threadRef, relativePath) {
26738
+ async readFile(threadRef, relativePath, tail) {
26693
26739
  const thread = this.requireThread(threadRef);
26694
26740
  if (relativePath.includes("..") || relativePath.startsWith("/")) {
26695
26741
  throw new Error("Invalid path");
26696
26742
  }
26697
- return readWorktreeFile(thread.worktreePath, relativePath);
26743
+ return (tail ? readWorktreeFileTail : readWorktreeFile)(thread.worktreePath, relativePath);
26698
26744
  }
26699
26745
  async readFileForUpload(threadRef, relativePath) {
26700
26746
  const thread = this.requireThread(threadRef);
@@ -27203,7 +27249,7 @@ var init_orchestrator = __esm({
27203
27249
  this.emit({ type: "status_changed", threadId: restored2.id, status: restored2.status });
27204
27250
  return restored2;
27205
27251
  }
27206
- if (!(0, import_node_fs65.existsSync)(thread.worktreePath)) {
27252
+ if (!(0, import_node_fs66.existsSync)(thread.worktreePath)) {
27207
27253
  if (isCowboyThread(thread) || isPrimaryCheckoutThread(thread)) {
27208
27254
  throw new Error(
27209
27255
  `Cowboy checkout missing: ${thread.worktreePath}. Re-add the project folder, then restore.`
@@ -27372,7 +27418,7 @@ function createClippedMcpServer() {
27372
27418
  // src/mcp/server.ts
27373
27419
  var import_zod8 = require("zod");
27374
27420
  var import_node_crypto18 = require("crypto");
27375
- var import_node_path64 = require("path");
27421
+ var import_node_path65 = require("path");
27376
27422
  init_orchestrator();
27377
27423
  init_task_state();
27378
27424
  init_worktree();
@@ -30529,7 +30575,7 @@ function registerScheduleTools(server) {
30529
30575
 
30530
30576
  // src/agent-rpc/handlers.ts
30531
30577
  var import_node_crypto16 = require("crypto");
30532
- var import_node_path61 = require("path");
30578
+ var import_node_path62 = require("path");
30533
30579
  init_wait_for_job();
30534
30580
  init_wait_for_turn();
30535
30581
  init_protocol();
@@ -30553,27 +30599,27 @@ init_gh_errors();
30553
30599
  init_git_auth_mode();
30554
30600
 
30555
30601
  // src/board/load-home-board.ts
30556
- var import_node_fs67 = require("fs");
30557
- var import_node_path63 = require("path");
30602
+ var import_node_fs68 = require("fs");
30603
+ var import_node_path64 = require("path");
30558
30604
  init_worktree();
30559
30605
  init_paths();
30560
30606
 
30561
30607
  // src/board/board-pins.ts
30562
30608
  var import_node_crypto17 = require("crypto");
30563
- var import_node_fs66 = require("fs");
30564
- var import_node_path62 = require("path");
30609
+ var import_node_fs67 = require("fs");
30610
+ var import_node_path63 = require("path");
30565
30611
  init_paths();
30566
30612
  init_home_board();
30567
30613
  var FILE = "home-board-pins.json";
30568
30614
  var VERSION = 1;
30569
30615
  function pinsFile() {
30570
- return (0, import_node_path62.join)(appDataDir(), FILE);
30616
+ return (0, import_node_path63.join)(appDataDir(), FILE);
30571
30617
  }
30572
30618
  function readDisk() {
30573
30619
  const path = pinsFile();
30574
- if (!(0, import_node_fs66.existsSync)(path)) return [];
30620
+ if (!(0, import_node_fs67.existsSync)(path)) return [];
30575
30621
  try {
30576
- const raw = JSON.parse((0, import_node_fs66.readFileSync)(path, "utf8"));
30622
+ const raw = JSON.parse((0, import_node_fs67.readFileSync)(path, "utf8"));
30577
30623
  if (raw?.version !== VERSION || !Array.isArray(raw.items)) return [];
30578
30624
  return raw.items.filter((item) => item?.id && item.kind && item.ref);
30579
30625
  } catch {
@@ -30581,8 +30627,8 @@ function readDisk() {
30581
30627
  }
30582
30628
  }
30583
30629
  function writeDisk(items) {
30584
- (0, import_node_fs66.mkdirSync)(appDataDir(), { recursive: true });
30585
- (0, import_node_fs66.writeFileSync)(pinsFile(), JSON.stringify({ version: VERSION, items }, null, 2), "utf8");
30630
+ (0, import_node_fs67.mkdirSync)(appDataDir(), { recursive: true });
30631
+ (0, import_node_fs67.writeFileSync)(pinsFile(), JSON.stringify({ version: VERSION, items }, null, 2), "utf8");
30586
30632
  }
30587
30633
  function listBoardPins() {
30588
30634
  return readDisk();
@@ -30603,7 +30649,7 @@ function homeBoardWorkspaceKey(workspaces) {
30603
30649
  return workspaces.map((w) => w.path).filter(Boolean).sort().join("\n");
30604
30650
  }
30605
30651
  function cacheFile() {
30606
- return (0, import_node_path63.join)(appDataDir(), "home-board-cache.json");
30652
+ return (0, import_node_path64.join)(appDataDir(), "home-board-cache.json");
30607
30653
  }
30608
30654
  function emptyInputs() {
30609
30655
  return {
@@ -30629,9 +30675,9 @@ function shouldCacheHomeBoardInputs(inputs) {
30629
30675
  }
30630
30676
  function readDiskCache() {
30631
30677
  const path = cacheFile();
30632
- if (!(0, import_node_fs67.existsSync)(path)) return null;
30678
+ if (!(0, import_node_fs68.existsSync)(path)) return null;
30633
30679
  try {
30634
- const raw = JSON.parse((0, import_node_fs67.readFileSync)(path, "utf8"));
30680
+ const raw = JSON.parse((0, import_node_fs68.readFileSync)(path, "utf8"));
30635
30681
  if (raw?.version !== CACHE_VERSION || typeof raw.fetchedAt !== "number") {
30636
30682
  return null;
30637
30683
  }
@@ -30645,8 +30691,8 @@ function readDiskCache() {
30645
30691
  }
30646
30692
  function writeDiskCache(entry) {
30647
30693
  try {
30648
- (0, import_node_fs67.mkdirSync)(appDataDir(), { recursive: true });
30649
- (0, import_node_fs67.writeFileSync)(cacheFile(), JSON.stringify(entry), "utf8");
30694
+ (0, import_node_fs68.mkdirSync)(appDataDir(), { recursive: true });
30695
+ (0, import_node_fs68.writeFileSync)(cacheFile(), JSON.stringify(entry), "utf8");
30650
30696
  } catch {
30651
30697
  }
30652
30698
  }
@@ -31048,7 +31094,7 @@ async function startMcpServer() {
31048
31094
  async () => {
31049
31095
  const threads = orch.getThreads(true);
31050
31096
  const lines = threads.map((t) => {
31051
- const repo = t.repoPath === GLOBAL_WORKSPACE_ID ? "Orchestration" : (0, import_node_path64.basename)(t.repoPath) || t.repoPath;
31097
+ const repo = t.repoPath === GLOBAL_WORKSPACE_ID ? "Orchestration" : (0, import_node_path65.basename)(t.repoPath) || t.repoPath;
31052
31098
  const live = orch.threadLooksLive(t) ? readTurnLive(t.id) : null;
31053
31099
  const parent = t.parentThreadId ? ` parent:${t.parentThreadId.slice(0, 8)}` : "";
31054
31100
  const preview = lastMessagePreview(t.messages, 80);
@@ -59,7 +59,7 @@ import {
59
59
  stampPlanBlock,
60
60
  syncBoardPins,
61
61
  updateSchedule
62
- } from "../chunk-CPGJ5ICZ.js";
62
+ } from "../chunk-2P75E243.js";
63
63
  import "../chunk-LX5R5JOR.js";
64
64
  import {
65
65
  PRESENT_PLAN_REQUIRES_PLAN_MODE,
@@ -11,7 +11,7 @@ import {
11
11
  resolveSendFollowUp,
12
12
  startOrchestration,
13
13
  waitForPidExit
14
- } from "./chunk-CPGJ5ICZ.js";
14
+ } from "./chunk-2P75E243.js";
15
15
  import "./chunk-LX5R5JOR.js";
16
16
  import "./chunk-4GK32AYX.js";
17
17
  import "./chunk-5DZUWGKV.js";
@@ -9,7 +9,7 @@ import {
9
9
  resolveSendFollowUp,
10
10
  startOrchestration,
11
11
  waitForPidExit
12
- } from "./chunk-V5DMHB6Y.js";
12
+ } from "./chunk-DK4DKQ2H.js";
13
13
  import "./chunk-HNNS25SG.js";
14
14
  import "./chunk-GWFVCCJZ.js";
15
15
  import "./chunk-HQXBBUQX.js";