harness-wingman 0.6.1 → 0.8.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.
@@ -13243,9 +13243,9 @@ var init_dist5 = __esm({
13243
13243
  // apps/cli/dist/main.js
13244
13244
  init_dist2();
13245
13245
  init_dist();
13246
- import { readFileSync as readFileSync17 } from "node:fs";
13246
+ import { readFileSync as readFileSync18 } from "node:fs";
13247
13247
  import { homedir as homedir13 } from "node:os";
13248
- import { dirname as dirname18, resolve as resolve11 } from "node:path";
13248
+ import { dirname as dirname19, resolve as resolve12 } from "node:path";
13249
13249
  import { fileURLToPath as fileURLToPath2 } from "node:url";
13250
13250
 
13251
13251
  // packages/fixtures/dist/index.js
@@ -13373,7 +13373,7 @@ function isHookPayload(value) {
13373
13373
  }
13374
13374
  var HOOK_BODY_LIMIT = 1024 * 1024;
13375
13375
  function readBody(req) {
13376
- return new Promise((resolve12, reject) => {
13376
+ return new Promise((resolve13, reject) => {
13377
13377
  const chunks = [];
13378
13378
  let size = 0;
13379
13379
  req.on("data", (chunk) => {
@@ -13385,7 +13385,7 @@ function readBody(req) {
13385
13385
  }
13386
13386
  chunks.push(chunk);
13387
13387
  });
13388
- req.on("end", () => resolve12(Buffer.concat(chunks).toString("utf8")));
13388
+ req.on("end", () => resolve13(Buffer.concat(chunks).toString("utf8")));
13389
13389
  req.on("error", reject);
13390
13390
  });
13391
13391
  }
@@ -13980,7 +13980,7 @@ function isRecord2(value) {
13980
13980
 
13981
13981
  // packages/narrative/dist/parse.js
13982
13982
  function isHarnessSystemNotice(text) {
13983
- return /^\s*<(task-notification|system-reminder)\b/u.test(text);
13983
+ return /^\s*<(task-notification|system-reminder|in-app-browser-context)\b/u.test(text);
13984
13984
  }
13985
13985
  function parseTranscriptLine(line) {
13986
13986
  const trimmed = line.trim();
@@ -15606,7 +15606,7 @@ function resolveWingmanVersion({ defined, moduleUrl = import.meta.url, readPacka
15606
15606
  return void 0;
15607
15607
  }
15608
15608
  function wingmanVersion() {
15609
- const defined = false ? void 0 : "0.6.1";
15609
+ const defined = false ? void 0 : "0.8.0";
15610
15610
  return resolveWingmanVersion({
15611
15611
  defined,
15612
15612
  readPackage: (url) => JSON.parse(readFileSync15(url, "utf8"))
@@ -16014,10 +16014,23 @@ function createNarrativeService(options = {}) {
16014
16014
  session.follows.set(path, followTranscript(path, (line) => {
16015
16015
  if (closed || generation !== session.generation)
16016
16016
  return;
16017
- if (harness === "codex")
16018
- session.codexLines.push(parseCodexRolloutLine(line));
16019
- else
16020
- session.lines.push(parseTranscriptLine(line));
16017
+ let timestamp;
16018
+ if (harness === "codex") {
16019
+ const parsed = parseCodexRolloutLine(line);
16020
+ session.codexLines.push(parsed);
16021
+ if (parsed.kind !== "unknown")
16022
+ timestamp = parsed.timestamp;
16023
+ } else {
16024
+ const parsed = parseTranscriptLine(line);
16025
+ session.lines.push(parsed);
16026
+ if (parsed.kind !== "unknown")
16027
+ timestamp = parsed.timestamp;
16028
+ }
16029
+ const endedAt = session.endedAt ?? session.stopAt;
16030
+ if (timestamp !== void 0 && endedAt !== void 0 && Date.parse(timestamp) > Date.parse(endedAt)) {
16031
+ session.endedAt = void 0;
16032
+ session.stopAt = void 0;
16033
+ }
16021
16034
  recordToolObservations(harness, session, extractRawToolObservations(harness, line));
16022
16035
  session.dirty = true;
16023
16036
  notify(harness);
@@ -16138,13 +16151,8 @@ function createNarrativeService(options = {}) {
16138
16151
  };
16139
16152
  }
16140
16153
  }
16141
- if (name === "SessionEnd") {
16142
- session.endedAt = event.received_at;
16143
- } else if (name === "Stop") {
16144
- session.stopAt = event.received_at;
16145
- } else {
16146
- session.stopAt = void 0;
16147
- }
16154
+ session.endedAt = name === "SessionEnd" ? event.received_at : void 0;
16155
+ session.stopAt = name === "Stop" ? event.received_at : void 0;
16148
16156
  session.lastEvent = { name, at: event.received_at };
16149
16157
  session.dirty = true;
16150
16158
  notify(event.harness);
@@ -16457,6 +16465,7 @@ function createNarrativeService(options = {}) {
16457
16465
  };
16458
16466
  }
16459
16467
  projects.push({
16468
+ firstScreen: deriveProjectFirstScreen(plan, parsed?.availability === "available" ? parsed.goal : void 0, summary.currentPoints, sessionViews),
16460
16469
  root,
16461
16470
  presence: members.length === 0 ? "remembered" : "active",
16462
16471
  seenSinceStart: seenProjectRoots.has(rootIdentity),
@@ -16479,7 +16488,11 @@ function createNarrativeService(options = {}) {
16479
16488
  sessions: sessionViews
16480
16489
  });
16481
16490
  }
16482
- projects.sort((left, right) => left.root.localeCompare(right.root));
16491
+ projects.sort((left, right) => {
16492
+ const decisionOrder = Number(right.firstScreen.action.kind === "decision") - Number(left.firstScreen.action.kind === "decision");
16493
+ const activityOrder = (right.firstScreen.lastActivity === void 0 ? 0 : Date.parse(right.firstScreen.lastActivity.at)) - (left.firstScreen.lastActivity === void 0 ? 0 : Date.parse(left.firstScreen.lastActivity.at));
16494
+ return decisionOrder || activityOrder || left.root.localeCompare(right.root);
16495
+ });
16483
16496
  return {
16484
16497
  projects,
16485
16498
  ...projectMemoryUnavailable === void 0 ? {} : { memory: { unavailable: projectMemoryUnavailable } }
@@ -16507,6 +16520,107 @@ function createNarrativeService(options = {}) {
16507
16520
  loadRememberedProjectRoots();
16508
16521
  return { handleEvent, getState, getOverview, getProjects, seedFixture, subscribe, close };
16509
16522
  }
16523
+ function deriveProjectFirstScreen(plan, goal, points, sessions) {
16524
+ const source = ".wingman/plan.md nodes(status, children)";
16525
+ const currentPoints = points.map((point) => ({ ...point, source }));
16526
+ const branch = [];
16527
+ const checkpoints = [];
16528
+ function visit(node, ancestors) {
16529
+ const path = [...ancestors, node];
16530
+ const childCurrent = node.children.map((child) => visit(child, path)).some(Boolean);
16531
+ const onCurrentPath = node.status === "in_progress" || childCurrent;
16532
+ if (onCurrentPath && (node.status === "checkpoint" || node.verification !== void 0)) {
16533
+ checkpoints.push({
16534
+ key: node.key,
16535
+ path: path.map((ancestor) => ancestor.text),
16536
+ text: node.text,
16537
+ source: `.wingman/plan.md:${node.line} status / verification`,
16538
+ ...node.verification === void 0 ? {} : { verification: node.verification }
16539
+ });
16540
+ }
16541
+ return onCurrentPath;
16542
+ }
16543
+ if (plan.availability === "available") {
16544
+ for (const node of plan.nodes) {
16545
+ if (visit(node, []))
16546
+ branch.push({
16547
+ key: node.key,
16548
+ path: [node.text],
16549
+ text: node.text,
16550
+ source: `.wingman/plan.md:${node.line} \u5F53\u524D\u70B9\u9876\u5C42\u7956\u5148`
16551
+ });
16552
+ }
16553
+ }
16554
+ const requests = [];
16555
+ for (const session of sessions) {
16556
+ if (session.feedback?.state !== "needs_user")
16557
+ continue;
16558
+ requests.push({
16559
+ harness: session.harness,
16560
+ sessionId: session.id,
16561
+ label: session.label,
16562
+ since: session.feedback.since,
16563
+ source: session.feedback.source,
16564
+ ...session.feedback.message === void 0 ? {} : { text: session.feedback.message }
16565
+ });
16566
+ }
16567
+ let action;
16568
+ if (requests.length > 0)
16569
+ action = { kind: "decision", items: requests, source: "sessions.feedback(state=needs_user)" };
16570
+ else if (checkpoints.length > 0)
16571
+ action = {
16572
+ kind: "checkpoint",
16573
+ items: checkpoints,
16574
+ source: ".wingman/plan.md \u5F53\u524D\u70B9\u7956\u5148\u8DEF\u5F84 status / verification"
16575
+ };
16576
+ else if (plan.availability === "missing")
16577
+ action = {
16578
+ kind: "insufficient",
16579
+ reason: "no_plan",
16580
+ source: "plan.availability=missing; plan.lookedUp"
16581
+ };
16582
+ else if (plan.availability === "unavailable")
16583
+ action = {
16584
+ kind: "insufficient",
16585
+ reason: "plan_unavailable",
16586
+ source: `plan.availability=unavailable; plan.reason: ${plan.reason}`
16587
+ };
16588
+ else if (sessions.length > 0 && sessions.every((session) => session.feedback === void 0 || session.feedback.state === "unavailable"))
16589
+ action = {
16590
+ kind: "insufficient",
16591
+ reason: "feedback_unavailable",
16592
+ source: "sessions.feedback.state=unavailable / feedback \u672A\u63D0\u4F9B"
16593
+ };
16594
+ else if (currentPoints.length > 0 && sessions.some((session) => !session.ended))
16595
+ action = {
16596
+ kind: "in_progress",
16597
+ source: ".wingman/plan.md currentPoints; sessions.ended=false"
16598
+ };
16599
+ else
16600
+ action = {
16601
+ kind: "insufficient",
16602
+ reason: "no_session",
16603
+ source: `currentPoints.length=${currentPoints.length}; sessions(ended=false).length=${sessions.filter((session) => !session.ended).length}`
16604
+ };
16605
+ const latest = sessions.filter((session) => session.lastActivity !== void 0 && Number.isFinite(Date.parse(session.lastActivity))).sort((left, right) => Date.parse(right.lastActivity) - Date.parse(left.lastActivity))[0];
16606
+ return {
16607
+ source,
16608
+ branch,
16609
+ currentPoints,
16610
+ action,
16611
+ ...goal === void 0 ? {} : { goal: { text: goal, source: ".wingman/plan.md \u76EE\u6807: / Goal:" } },
16612
+ ...latest === void 0 ? {} : {
16613
+ lastActivity: {
16614
+ at: latest.lastActivity,
16615
+ harness: latest.harness,
16616
+ sessionId: latest.id,
16617
+ label: latest.user.title ?? (latest.title.source === "plan.md \u6B65\u9AA4" ? latest.title.text : latest.label),
16618
+ source: "sessions.lastActivity\uFF08\u6700\u8FD1 hook received_at / transcript timestamp\uFF09\u6700\u5927\u503C",
16619
+ labelSource: latest.user.title !== void 0 ? "sessions.user.title" : latest.title.source === "plan.md \u6B65\u9AA4" ? "sessions.title\uFF08plan.md \u6B65\u9AA4\uFF09" : "sessions.label\uFF08\u4F1A\u8BDD\u5DE5\u4F5C\u76EE\u5F55\u540D / sessionId\uFF09"
16620
+ }
16621
+ }
16622
+ };
16623
+ }
16510
16624
  function lastActivityOf(session) {
16511
16625
  if (session.lastActivity !== void 0)
16512
16626
  return session.lastActivity;
@@ -17510,10 +17624,108 @@ async function scanValidated(adapter, options) {
17510
17624
 
17511
17625
  // apps/cli/dist/server.js
17512
17626
  init_dist();
17627
+ import { execFile as execFile2 } from "node:child_process";
17513
17628
  import { createHmac, timingSafeEqual } from "node:crypto";
17514
17629
  import { readFile as readFile4 } from "node:fs/promises";
17515
17630
  import { createServer } from "node:http";
17516
- import { extname, resolve as resolve10, sep as sep2 } from "node:path";
17631
+ import { extname, resolve as resolve11, sep as sep2 } from "node:path";
17632
+
17633
+ // apps/cli/dist/return-target.js
17634
+ import { randomBytes as randomBytes5 } from "node:crypto";
17635
+ import { closeSync as closeSync4, copyFileSync as copyFileSync2, mkdirSync as mkdirSync12, openSync as openSync4, readFileSync as readFileSync17, renameSync as renameSync6, rmSync as rmSync10, statSync as statSync6, writeFileSync as writeFileSync13 } from "node:fs";
17636
+ import { dirname as dirname18, join as join24, resolve as resolve10 } from "node:path";
17637
+ var BUNDLES = [
17638
+ ["Terminal", "Terminal.app"],
17639
+ ["iTerm", "iTerm.app"],
17640
+ ["Ghostty", "Ghostty.app"],
17641
+ ["WezTerm", "WezTerm.app"],
17642
+ ["Warp", "Warp.app"],
17643
+ ["Alacritty", "Alacritty.app"],
17644
+ ["kitty", "kitty.app"],
17645
+ ["VS Code", "Visual Studio Code.app"]
17646
+ ];
17647
+ function detectReturnTargets(homeDir, roots = ["/Applications", join24(homeDir, "Applications")]) {
17648
+ const available = [];
17649
+ for (const [name, bundle] of BUNDLES) {
17650
+ for (const root of new Set(roots.map((root2) => resolve10(root2)))) {
17651
+ const bundlePath = join24(root, bundle);
17652
+ try {
17653
+ if (statSync6(bundlePath).isDirectory())
17654
+ available.push({ name, bundlePath });
17655
+ } catch {
17656
+ }
17657
+ }
17658
+ }
17659
+ return available;
17660
+ }
17661
+ function settingsPath(homeDir) {
17662
+ return join24(homeDir, ".wingman", "state", "settings.json");
17663
+ }
17664
+ function readReturnTargetSettings(homeDir) {
17665
+ let raw;
17666
+ try {
17667
+ raw = readFileSync17(settingsPath(homeDir), "utf8");
17668
+ } catch (error) {
17669
+ if (isRecord8(error) && error.code === "ENOENT")
17670
+ return { version: 1 };
17671
+ return { unavailable: "\u56DE\u8DF3\u8BBE\u7F6E\u65E0\u6CD5\u8BFB\u53D6;\u8BF7\u4EBA\u5DE5\u68C0\u67E5 settings.json" };
17672
+ }
17673
+ try {
17674
+ const value = JSON.parse(raw);
17675
+ if (!isSettings(value))
17676
+ throw new Error("\u4E0D\u662F\u5408\u6CD5 v1 \u7ED3\u6784");
17677
+ return value;
17678
+ } catch {
17679
+ return { unavailable: "\u56DE\u8DF3\u8BBE\u7F6E\u65E0\u6CD5\u89E3\u6790\u6216\u7248\u672C\u672A\u77E5,\u62D2\u7EDD\u8986\u76D6;\u8BF7\u4EBA\u5DE5\u68C0\u67E5 settings.json" };
17680
+ }
17681
+ }
17682
+ function saveReturnTarget(homeDir, bundlePath) {
17683
+ const current = readReturnTargetSettings(homeDir);
17684
+ if ("unavailable" in current)
17685
+ return current;
17686
+ const settings = { version: 1, returnTarget: { bundlePath } };
17687
+ const path = settingsPath(homeDir);
17688
+ const tempPath = join24(dirname18(path), `.settings-${randomBytes5(8).toString("hex")}.tmp`);
17689
+ let fd;
17690
+ try {
17691
+ mkdirSync12(dirname18(path), { recursive: true, mode: 448 });
17692
+ try {
17693
+ copyFileSync2(path, `${path}.bak`);
17694
+ } catch (error) {
17695
+ if (!isRecord8(error) || error.code !== "ENOENT")
17696
+ throw error;
17697
+ }
17698
+ fd = openSync4(tempPath, "wx", 384);
17699
+ writeFileSync13(fd, `${JSON.stringify(settings)}
17700
+ `, "utf8");
17701
+ closeSync4(fd);
17702
+ fd = void 0;
17703
+ renameSync6(tempPath, path);
17704
+ return settings;
17705
+ } catch {
17706
+ return { unavailable: "\u56DE\u8DF3\u8BBE\u7F6E\u5907\u4EFD\u6216\u5199\u5165\u5931\u8D25,\u672A\u8986\u76D6\u8BBE\u7F6E;\u8BF7\u4EBA\u5DE5\u68C0\u67E5 settings.json" };
17707
+ } finally {
17708
+ if (fd !== void 0) {
17709
+ try {
17710
+ closeSync4(fd);
17711
+ } catch {
17712
+ }
17713
+ }
17714
+ try {
17715
+ rmSync10(tempPath, { force: true });
17716
+ } catch {
17717
+ }
17718
+ }
17719
+ }
17720
+ function isSettings(value) {
17721
+ if (!isRecord8(value) || value.version !== 1 || !Object.keys(value).every((key) => key === "version" || key === "returnTarget")) {
17722
+ return false;
17723
+ }
17724
+ return value.returnTarget === void 0 || isRecord8(value.returnTarget) && Object.keys(value.returnTarget).every((key) => key === "bundlePath") && typeof value.returnTarget.bundlePath === "string" && value.returnTarget.bundlePath.startsWith("/");
17725
+ }
17726
+ function isRecord8(value) {
17727
+ return typeof value === "object" && value !== null && !Array.isArray(value);
17728
+ }
17517
17729
 
17518
17730
  // apps/cli/dist/suggest.js
17519
17731
  init_dist();
@@ -17761,6 +17973,10 @@ async function handle(req, res, options, warn, runtime) {
17761
17973
  await handleTaskOverlay(req, res, options);
17762
17974
  return;
17763
17975
  }
17976
+ if (url.pathname === "/api/return-target" || url.pathname === "/api/return") {
17977
+ await handleReturn(req, res, options, url.pathname === "/api/return");
17978
+ return;
17979
+ }
17764
17980
  if (url.pathname === "/api/license/install" && req.method === "POST") {
17765
17981
  await handleLicenseInstall(req, res, options);
17766
17982
  return;
@@ -17992,6 +18208,64 @@ async function handleActionApply(req, res, options, runtime) {
17992
18208
  sendJson2(res, 400, { error: errorMessage3(error) });
17993
18209
  }
17994
18210
  }
18211
+ async function handleReturn(req, res, options, activate) {
18212
+ if (req.method !== "POST" && (activate || req.method !== "GET")) {
18213
+ sendText2(res, 405, "method not allowed");
18214
+ return;
18215
+ }
18216
+ if (req.method === "POST" && options.readonlyActions) {
18217
+ sendJson2(res, 403, { error: "fixtures \u6A21\u5F0F\u53EA\u8BFB:\u4E0D\u4FDD\u5B58\u56DE\u8DF3\u8BBE\u7F6E\u6216\u6FC0\u6D3B\u5E94\u7528" });
18218
+ return;
18219
+ }
18220
+ if (options.homeDir === void 0) {
18221
+ sendJson2(res, 500, { error: "\u56DE\u8DF3\u8BBE\u7F6E\u7F3A\u5C11 homeDir" });
18222
+ return;
18223
+ }
18224
+ const available = detectReturnTargets(options.homeDir, options.returnTargetRoots);
18225
+ if (req.method === "GET") {
18226
+ const settings = readReturnTargetSettings(options.homeDir);
18227
+ sendJson2(res, 200, {
18228
+ available,
18229
+ ..."unavailable" in settings ? { settings } : settings.returnTarget === void 0 ? {} : { selected: settings.returnTarget }
18230
+ });
18231
+ return;
18232
+ }
18233
+ const body = await readJsonBody(req);
18234
+ if (!isRecord9(body) || Object.keys(body).some((key) => key !== "bundlePath") || typeof body.bundlePath !== "string") {
18235
+ sendJson2(res, 400, { error: "\u8BF7\u6C42\u53EA\u63A5\u53D7 bundlePath \u5B57\u7B26\u4E32" });
18236
+ return;
18237
+ }
18238
+ const target = available.find((target2) => target2.bundlePath === body.bundlePath);
18239
+ if (!target) {
18240
+ sendJson2(res, 400, { error: "\u672A\u68C0\u6D4B\u5230\u8BE5\u56DE\u8DF3\u5E94\u7528" });
18241
+ return;
18242
+ }
18243
+ if (!activate) {
18244
+ const settings = saveReturnTarget(options.homeDir, target.bundlePath);
18245
+ if ("unavailable" in settings)
18246
+ sendJson2(res, 409, { error: settings.unavailable });
18247
+ else
18248
+ sendJson2(res, 200, { selected: settings.returnTarget });
18249
+ return;
18250
+ }
18251
+ try {
18252
+ await (options.opener ?? openReturnTarget)(target.bundlePath);
18253
+ sendJson2(res, 200, { activated: true, name: target.name });
18254
+ } catch (error) {
18255
+ const timedOut = isRecord9(error) && (error.killed === true || error.code === "ETIMEDOUT");
18256
+ sendJson2(res, 200, { activated: false, reason: timedOut ? "\u5E94\u7528\u6FC0\u6D3B\u8D85\u65F6" : "\u5E94\u7528\u6FC0\u6D3B\u5931\u8D25" });
18257
+ }
18258
+ }
18259
+ function openReturnTarget(bundlePath) {
18260
+ return new Promise((resolveOpen, reject) => {
18261
+ execFile2("open", ["-a", bundlePath], { timeout: 5e3 }, (error) => {
18262
+ if (error)
18263
+ reject(error);
18264
+ else
18265
+ resolveOpen();
18266
+ });
18267
+ });
18268
+ }
17995
18269
  async function handleTaskOverlay(req, res, options) {
17996
18270
  if (options.readonlyActions) {
17997
18271
  sendJson2(res, 403, { error: "fixtures \u6A21\u5F0F\u53EA\u8BFB:\u4E0D\u5199\u4EFB\u52A1\u5361 overlay" });
@@ -18097,11 +18371,11 @@ function isToggleRequest(value) {
18097
18371
  return o.kind === "toggle" && typeof o.itemId === "string" && typeof o.enable === "boolean";
18098
18372
  }
18099
18373
  function isTaskOverlayRequest(value) {
18100
- if (!isRecord8(value) || !isHarnessId3(value.harness))
18374
+ if (!isRecord9(value) || !isHarnessId3(value.harness))
18101
18375
  return false;
18102
18376
  if (typeof value.sessionId !== "string" || value.sessionId.trim() === "")
18103
18377
  return false;
18104
- if (!isRecord8(value.patch))
18378
+ if (!isRecord9(value.patch))
18105
18379
  return false;
18106
18380
  const keys = Object.keys(value.patch);
18107
18381
  if (keys.length === 0 || keys.some((key) => !["title", "pinned", "hidden", "accepted"].includes(key))) {
@@ -18112,7 +18386,7 @@ function isTaskOverlayRequest(value) {
18112
18386
  function isHarnessId3(value) {
18113
18387
  return typeof value === "string" && HARNESS_IDS.includes(value);
18114
18388
  }
18115
- function isRecord8(value) {
18389
+ function isRecord9(value) {
18116
18390
  return typeof value === "object" && value !== null && !Array.isArray(value);
18117
18391
  }
18118
18392
  function readJsonBody(req) {
@@ -18151,8 +18425,8 @@ async function serveStatic(pathname, res, panelDistDir) {
18151
18425
  return;
18152
18426
  }
18153
18427
  const rel = decoded === "/" ? "/index.html" : decoded;
18154
- const distDir = resolve10(panelDistDir);
18155
- const filePath = resolve10(distDir, `.${rel}`);
18428
+ const distDir = resolve11(panelDistDir);
18429
+ const filePath = resolve11(distDir, `.${rel}`);
18156
18430
  if (filePath !== distDir && !filePath.startsWith(distDir + sep2)) {
18157
18431
  sendText2(res, 403, "forbidden");
18158
18432
  return;
@@ -18305,7 +18579,7 @@ async function runServe(args) {
18305
18579
  `);
18306
18580
  }
18307
18581
  }
18308
- const panelDistDir = panelDist === void 0 ? resolve11(dirname18(fileURLToPath2(import.meta.url)), "../../panel/dist") : resolve11(panelDist);
18582
+ const panelDistDir = panelDist === void 0 ? resolve12(dirname19(fileURLToPath2(import.meta.url)), "../../panel/dist") : resolve12(panelDist);
18309
18583
  const narrative = createNarrativeService({
18310
18584
  followTranscripts: !fixtures,
18311
18585
  homeDir,
@@ -18318,7 +18592,7 @@ async function runServe(args) {
18318
18592
  });
18319
18593
  if (fixtures) {
18320
18594
  try {
18321
- const raw = readFileSync17(fixturePath("cc", "sessions", "session-todos.jsonl"), "utf8");
18595
+ const raw = readFileSync18(fixturePath("cc", "sessions", "session-todos.jsonl"), "utf8");
18322
18596
  narrative.seedFixture("cc", raw.split("\n"), "MOCK \u2014 fixtures \u6F14\u793A:\u53D9\u4E8B\u6570\u636E\u6765\u81EA packages/fixtures \u7684 session-todos.jsonl \u6837\u4F8B\u4F1A\u8BDD,\u975E\u672C\u673A\u771F\u5B9E transcript\u3002");
18323
18597
  } catch (error) {
18324
18598
  const message = error instanceof Error ? error.message : String(error);