@drisp/cli 0.5.8 → 0.5.11

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.
@@ -373,6 +373,21 @@ var RULES = {
373
373
  defaultTimeoutMs: DEFAULT_TIMEOUT_MS,
374
374
  canBlock: false
375
375
  },
376
+ "instructions.loaded": {
377
+ expectsDecision: false,
378
+ defaultTimeoutMs: DEFAULT_TIMEOUT_MS,
379
+ canBlock: false
380
+ },
381
+ "worktree.create": {
382
+ expectsDecision: false,
383
+ defaultTimeoutMs: DEFAULT_TIMEOUT_MS,
384
+ canBlock: false
385
+ },
386
+ "worktree.remove": {
387
+ expectsDecision: false,
388
+ defaultTimeoutMs: DEFAULT_TIMEOUT_MS,
389
+ canBlock: false
390
+ },
376
391
  "elicitation.request": {
377
392
  expectsDecision: true,
378
393
  defaultTimeoutMs: PERMISSION_TIMEOUT_MS,
@@ -629,6 +644,32 @@ function translateClaudeEnvelope(envelope) {
629
644
  file_path: payload["file_path"]
630
645
  }
631
646
  };
647
+ case "InstructionsLoaded":
648
+ return {
649
+ kind: "instructions.loaded",
650
+ data: {
651
+ file_path: payload["file_path"],
652
+ memory_type: payload["memory_type"],
653
+ load_reason: payload["load_reason"],
654
+ globs: Array.isArray(payload["globs"]) ? payload["globs"] : void 0,
655
+ trigger_file_path: payload["trigger_file_path"],
656
+ parent_file_path: payload["parent_file_path"]
657
+ }
658
+ };
659
+ case "WorktreeCreate":
660
+ return {
661
+ kind: "worktree.create",
662
+ data: {
663
+ worktree_path: payload["worktree_path"]
664
+ }
665
+ };
666
+ case "WorktreeRemove":
667
+ return {
668
+ kind: "worktree.remove",
669
+ data: {
670
+ worktree_path: payload["worktree_path"]
671
+ }
672
+ };
632
673
  case "Elicitation":
633
674
  return {
634
675
  kind: "elicitation.request",
@@ -6158,15 +6199,34 @@ function createCodexServer(opts) {
6158
6199
  },
6159
6200
  stop() {
6160
6201
  clearPendingApprovals();
6161
- if (loadedAgentConfig) {
6162
- cleanupAgentConfig(loadedAgentConfig.tempDir);
6163
- loadedAgentConfig = null;
6164
- }
6165
- if (manager) {
6166
- manager.removeAllListeners();
6167
- manager.stop().catch(() => {
6168
- });
6169
- manager = null;
6202
+ const managerToStop = manager;
6203
+ const agentConfigToCleanup = loadedAgentConfig;
6204
+ manager = null;
6205
+ loadedAgentConfig = null;
6206
+ if (managerToStop) {
6207
+ managerToStop.removeAllListeners();
6208
+ void (async () => {
6209
+ if (agentConfigToCleanup) {
6210
+ const removalEdits = buildAgentRemovalEdits(
6211
+ agentConfigToCleanup.agentNames
6212
+ );
6213
+ if (removalEdits.length > 0) {
6214
+ try {
6215
+ await managerToStop.sendRequest(CONFIG_BATCH_WRITE, {
6216
+ filePath: `${projectDir}/.codex/config.toml`,
6217
+ edits: removalEdits
6218
+ });
6219
+ } catch (error) {
6220
+ console.error(
6221
+ `[athena:codex] failed to remove agents on stop: ${error instanceof Error ? error.message : String(error)}`
6222
+ );
6223
+ }
6224
+ }
6225
+ cleanupAgentConfig(agentConfigToCleanup.tempDir);
6226
+ }
6227
+ await managerToStop.stop().catch(() => {
6228
+ });
6229
+ })();
6170
6230
  }
6171
6231
  status = "stopped";
6172
6232
  lastError = null;
@@ -7107,15 +7167,10 @@ function loadPlugin(pluginDir) {
7107
7167
  }
7108
7168
  const mcpConfigPath = path12.join(pluginDir, ".mcp.json");
7109
7169
  const hasMcpConfig = fs14.existsSync(mcpConfigPath);
7110
- const entries = fs14.readdirSync(skillsDir, { withFileTypes: true });
7111
7170
  const commands2 = [];
7112
- for (const entry of entries) {
7113
- if (!entry.isDirectory()) continue;
7114
- const skillPath = path12.join(skillsDir, entry.name, "SKILL.md");
7115
- if (!fs14.existsSync(skillPath)) continue;
7116
- const content = fs14.readFileSync(skillPath, "utf-8");
7117
- const parsed = parseFrontmatter(content);
7118
- if (!parsed.frontmatter["user-invocable"]) continue;
7171
+ const loadSkillFile = (skillPath) => {
7172
+ const parsed = parseFrontmatter(fs14.readFileSync(skillPath, "utf-8"));
7173
+ if (!parsed.frontmatter["user-invocable"]) return;
7119
7174
  commands2.push(
7120
7175
  skillToCommand(
7121
7176
  parsed.frontmatter,
@@ -7123,6 +7178,20 @@ function loadPlugin(pluginDir) {
7123
7178
  hasMcpConfig ? mcpConfigPath : void 0
7124
7179
  )
7125
7180
  );
7181
+ };
7182
+ for (const entry of fs14.readdirSync(skillsDir, { withFileTypes: true })) {
7183
+ if (!entry.isDirectory()) continue;
7184
+ const entryDir = path12.join(skillsDir, entry.name);
7185
+ const directSkill = path12.join(entryDir, "SKILL.md");
7186
+ if (fs14.existsSync(directSkill)) {
7187
+ loadSkillFile(directSkill);
7188
+ continue;
7189
+ }
7190
+ for (const nested of fs14.readdirSync(entryDir, { withFileTypes: true })) {
7191
+ if (!nested.isDirectory()) continue;
7192
+ const nestedSkill = path12.join(entryDir, nested.name, "SKILL.md");
7193
+ if (fs14.existsSync(nestedSkill)) loadSkillFile(nestedSkill);
7194
+ }
7126
7195
  }
7127
7196
  return commands2;
7128
7197
  }
@@ -7659,6 +7728,12 @@ function generateNeutralTitle(event, g) {
7659
7728
  return truncate(`${g["config.icon"]} cwd \u2192 ${event.data.cwd}`);
7660
7729
  case "file.changed":
7661
7730
  return truncate(`File changed: ${event.data.file_path}`);
7731
+ case "instructions.loaded":
7732
+ return truncate(`Instructions loaded: ${event.data.file_path}`);
7733
+ case "worktree.create":
7734
+ return truncate(`Worktree created: ${event.data.worktree_path}`);
7735
+ case "worktree.remove":
7736
+ return truncate(`Worktree removed: ${event.data.worktree_path}`);
7662
7737
  case "stop.failure":
7663
7738
  return truncate(
7664
7739
  `${g["status.blocked"]} Stop failure: ${event.data.error_type}`
@@ -8109,6 +8184,64 @@ function createRootPlanTracker() {
8109
8184
  };
8110
8185
  }
8111
8186
 
8187
+ // src/core/feed/internals/taskLifecycleTracker.ts
8188
+ function coerceTaskStatus(status) {
8189
+ switch (status) {
8190
+ case "pending":
8191
+ case "in_progress":
8192
+ case "completed":
8193
+ case "failed":
8194
+ return status;
8195
+ default:
8196
+ return null;
8197
+ }
8198
+ }
8199
+ function createTaskLifecycleTracker() {
8200
+ let items = [];
8201
+ return {
8202
+ current() {
8203
+ return items;
8204
+ },
8205
+ upsertCreated({ taskId, subject, description, activeForm }) {
8206
+ const task = {
8207
+ taskId,
8208
+ content: subject,
8209
+ status: "pending",
8210
+ activeForm: activeForm ?? description
8211
+ };
8212
+ const existingIndex = items.findIndex((item) => item.taskId === taskId);
8213
+ if (existingIndex === -1) {
8214
+ items = [...items, task];
8215
+ return;
8216
+ }
8217
+ items = items.map(
8218
+ (item, index) => index === existingIndex ? {
8219
+ ...item,
8220
+ taskId,
8221
+ content: subject,
8222
+ activeForm: task.activeForm ?? item.activeForm
8223
+ } : item
8224
+ );
8225
+ },
8226
+ markCompleted({ taskId, subject }) {
8227
+ const existingIndex = items.findIndex((item) => item.taskId === taskId);
8228
+ if (existingIndex === -1) {
8229
+ if (!subject) return;
8230
+ items = [...items, { taskId, content: subject, status: "completed" }];
8231
+ return;
8232
+ }
8233
+ items = items.map(
8234
+ (item, index) => index === existingIndex ? { ...item, status: "completed" } : item
8235
+ );
8236
+ },
8237
+ updateStatus({ taskId, status }) {
8238
+ items = items.map(
8239
+ (item) => item.taskId === taskId ? { ...item, status } : item
8240
+ );
8241
+ }
8242
+ };
8243
+ }
8244
+
8112
8245
  // src/core/feed/internals/subagentTracker.ts
8113
8246
  function createSubagentTracker() {
8114
8247
  const stack = [];
@@ -8205,6 +8338,7 @@ function createToolProjection(args) {
8205
8338
  runLifecycle,
8206
8339
  toolCorrelation,
8207
8340
  rootPlan,
8341
+ taskLifecycle,
8208
8342
  subagents,
8209
8343
  resolveToolActor
8210
8344
  } = args;
@@ -8304,6 +8438,13 @@ function createToolProjection(args) {
8304
8438
  if (toolName === "TodoWrite" && preEvent.actor_id === "agent:root") {
8305
8439
  rootPlan.set(extractTodoItems(toolInput));
8306
8440
  }
8441
+ if (toolName === "TaskUpdate") {
8442
+ const taskId = readString(toolInput["taskId"], toolInput["task_id"]);
8443
+ const status = coerceTaskStatus(toolInput["status"]);
8444
+ if (taskId && status) {
8445
+ taskLifecycle.updateStatus({ taskId, status });
8446
+ }
8447
+ }
8307
8448
  if (isSubagentTool(toolName)) {
8308
8449
  if (typeof toolInput["description"] === "string") {
8309
8450
  subagents.recordPendingDescription(toolInput["description"]);
@@ -8330,6 +8471,35 @@ function createToolProjection(args) {
8330
8471
  toolUseCause(toolUseId, parentId)
8331
8472
  );
8332
8473
  results.push(postEvent);
8474
+ if (toolName === "TaskCreate") {
8475
+ const response = readObject(data["tool_response"]);
8476
+ const task = readObject(response["task"]);
8477
+ const taskId = readString(task["id"], task["task_id"]);
8478
+ const subject = readString(task["subject"], toolInput["subject"]);
8479
+ if (taskId && subject) {
8480
+ taskLifecycle.upsertCreated({
8481
+ taskId,
8482
+ subject,
8483
+ description: readString(toolInput["description"]),
8484
+ activeForm: readString(toolInput["activeForm"])
8485
+ });
8486
+ }
8487
+ }
8488
+ if (toolName === "TaskUpdate") {
8489
+ const response = readObject(data["tool_response"]);
8490
+ const taskId = readString(
8491
+ response["taskId"],
8492
+ response["task_id"],
8493
+ toolInput["taskId"],
8494
+ toolInput["task_id"]
8495
+ );
8496
+ const status = coerceTaskStatus(
8497
+ readObject(response["statusChange"])["to"] ?? toolInput["status"]
8498
+ );
8499
+ if (taskId && status) {
8500
+ taskLifecycle.updateStatus({ taskId, status });
8501
+ }
8502
+ }
8333
8503
  if (toolName === "WebSearch") {
8334
8504
  results.push(
8335
8505
  webSearchCompleted(event, data, toolUseId, postEvent.event_id)
@@ -8940,6 +9110,59 @@ function createFileConfigProjection(args) {
8940
9110
  );
8941
9111
  return results;
8942
9112
  }
9113
+ if (event.kind === "instructions.loaded") {
9114
+ results.push(
9115
+ collapsed(
9116
+ makeEvent(
9117
+ "instructions.loaded",
9118
+ "info",
9119
+ "system",
9120
+ {
9121
+ file_path: readString(data["file_path"]) ?? "",
9122
+ memory_type: readString(data["memory_type"]),
9123
+ load_reason: readString(data["load_reason"]),
9124
+ globs: Array.isArray(data["globs"]) ? data["globs"] : void 0,
9125
+ trigger_file_path: readString(data["trigger_file_path"]),
9126
+ parent_file_path: readString(data["parent_file_path"])
9127
+ },
9128
+ event
9129
+ )
9130
+ )
9131
+ );
9132
+ return results;
9133
+ }
9134
+ if (event.kind === "worktree.create") {
9135
+ results.push(
9136
+ collapsed(
9137
+ makeEvent(
9138
+ "worktree.create",
9139
+ "info",
9140
+ "system",
9141
+ {
9142
+ worktree_path: readString(data["worktree_path"]) ?? ""
9143
+ },
9144
+ event
9145
+ )
9146
+ )
9147
+ );
9148
+ return results;
9149
+ }
9150
+ if (event.kind === "worktree.remove") {
9151
+ results.push(
9152
+ collapsed(
9153
+ makeEvent(
9154
+ "worktree.remove",
9155
+ "info",
9156
+ "system",
9157
+ {
9158
+ worktree_path: readString(data["worktree_path"]) ?? ""
9159
+ },
9160
+ event
9161
+ )
9162
+ )
9163
+ );
9164
+ return results;
9165
+ }
8943
9166
  return results;
8944
9167
  }
8945
9168
  };
@@ -9208,7 +9431,7 @@ function createRunSessionProjection(args) {
9208
9431
 
9209
9432
  // src/core/feed/internals/statusProjection.ts
9210
9433
  function createStatusProjection(args) {
9211
- const { ensureRunArray, makeEvent } = args;
9434
+ const { ensureRunArray, makeEvent, taskLifecycle } = args;
9212
9435
  return {
9213
9436
  mapStatusEvent(event, data) {
9214
9437
  const results = ensureRunArray(event);
@@ -9228,15 +9451,25 @@ function createStatusProjection(args) {
9228
9451
  return results;
9229
9452
  }
9230
9453
  if (event.kind === "task.created") {
9454
+ const taskId = readString(data["task_id"]) ?? "";
9455
+ const subject = readString(data["task_subject"]) ?? "";
9456
+ const description = readString(data["task_description"]);
9457
+ if (taskId && subject) {
9458
+ taskLifecycle.upsertCreated({
9459
+ taskId,
9460
+ subject,
9461
+ description
9462
+ });
9463
+ }
9231
9464
  results.push(
9232
9465
  makeEvent(
9233
9466
  "task.created",
9234
9467
  "info",
9235
9468
  "system",
9236
9469
  {
9237
- task_id: readString(data["task_id"]) ?? "",
9238
- task_subject: readString(data["task_subject"]) ?? "",
9239
- task_description: readString(data["task_description"]),
9470
+ task_id: taskId,
9471
+ task_subject: subject,
9472
+ task_description: description,
9240
9473
  teammate_name: readString(data["teammate_name"]),
9241
9474
  team_name: readString(data["team_name"])
9242
9475
  },
@@ -9246,14 +9479,17 @@ function createStatusProjection(args) {
9246
9479
  return results;
9247
9480
  }
9248
9481
  if (event.kind === "task.completed") {
9482
+ const taskId = readString(data["task_id"]) ?? "";
9483
+ const subject = readString(data["task_subject"]);
9484
+ if (taskId) taskLifecycle.markCompleted({ taskId, subject });
9249
9485
  results.push(
9250
9486
  makeEvent(
9251
9487
  "task.completed",
9252
9488
  "info",
9253
9489
  "system",
9254
9490
  {
9255
- task_id: readString(data["task_id"]) ?? "",
9256
- task_subject: readString(data["task_subject"]) ?? "",
9491
+ task_id: taskId,
9492
+ task_subject: subject ?? "",
9257
9493
  task_description: readString(data["task_description"]),
9258
9494
  teammate_name: readString(data["teammate_name"]),
9259
9495
  team_name: readString(data["team_name"])
@@ -9304,7 +9540,10 @@ var FILE_CONFIG_EVENT_KINDS = /* @__PURE__ */ new Set([
9304
9540
  "config.change",
9305
9541
  "compact.post",
9306
9542
  "cwd.changed",
9307
- "file.changed"
9543
+ "file.changed",
9544
+ "instructions.loaded",
9545
+ "worktree.create",
9546
+ "worktree.remove"
9308
9547
  ]);
9309
9548
  var STATUS_EVENT_KINDS = /* @__PURE__ */ new Set([
9310
9549
  "teammate.idle",
@@ -9318,6 +9557,7 @@ function createFeedMapper(bootstrap) {
9318
9557
  const transcriptReader = createTranscriptReader();
9319
9558
  const actors = new ActorRegistry();
9320
9559
  const rootPlan = createRootPlanTracker();
9560
+ const taskLifecycle = createTaskLifecycleTracker();
9321
9561
  const subagents = createSubagentTracker();
9322
9562
  function makeEvent(kind, level, actorId, data, runtimeEvent, cause) {
9323
9563
  const s = runLifecycle.allocateSeq();
@@ -9353,6 +9593,40 @@ function createFeedMapper(bootstrap) {
9353
9593
  makeEvent,
9354
9594
  transcriptReader
9355
9595
  );
9596
+ function replayTaskLifecycleToolEvent(e) {
9597
+ if (e.kind !== "tool.pre" && e.kind !== "tool.post") return;
9598
+ const data = e.data;
9599
+ const toolInput = readObject(data.tool_input);
9600
+ if (data.tool_name === "TaskCreate" && e.kind === "tool.post") {
9601
+ const response = readObject(data.tool_response);
9602
+ const task = readObject(response["task"]);
9603
+ const taskId = readString(task["id"], task["task_id"]);
9604
+ const subject = readString(task["subject"], toolInput["subject"]);
9605
+ if (taskId && subject) {
9606
+ taskLifecycle.upsertCreated({
9607
+ taskId,
9608
+ subject,
9609
+ description: readString(toolInput["description"]),
9610
+ activeForm: readString(toolInput["activeForm"])
9611
+ });
9612
+ }
9613
+ }
9614
+ if (data.tool_name === "TaskUpdate") {
9615
+ const response = readObject(data.tool_response);
9616
+ const status = coerceTaskStatus(
9617
+ readObject(response["statusChange"])["to"] ?? toolInput["status"]
9618
+ );
9619
+ const taskId = readString(
9620
+ response["taskId"],
9621
+ response["task_id"],
9622
+ toolInput["taskId"],
9623
+ toolInput["task_id"]
9624
+ );
9625
+ if (taskId && status) {
9626
+ taskLifecycle.updateStatus({ taskId, status });
9627
+ }
9628
+ }
9629
+ }
9356
9630
  if (bootstrap) {
9357
9631
  runLifecycle.restoreFrom(bootstrap);
9358
9632
  for (const e of bootstrap.feedEvents) {
@@ -9361,6 +9635,26 @@ function createFeedMapper(bootstrap) {
9361
9635
  extractTodoItems(e.data.tool_input)
9362
9636
  );
9363
9637
  }
9638
+ replayTaskLifecycleToolEvent(e);
9639
+ if (e.kind === "task.created") {
9640
+ const data = e.data;
9641
+ if (data.task_id && data.task_subject) {
9642
+ taskLifecycle.upsertCreated({
9643
+ taskId: data.task_id,
9644
+ subject: data.task_subject,
9645
+ description: data.task_description
9646
+ });
9647
+ }
9648
+ }
9649
+ if (e.kind === "task.completed") {
9650
+ const data = e.data;
9651
+ if (data.task_id) {
9652
+ taskLifecycle.markCompleted({
9653
+ taskId: data.task_id,
9654
+ subject: data.task_subject
9655
+ });
9656
+ }
9657
+ }
9364
9658
  }
9365
9659
  }
9366
9660
  function closeRunIntoEvent(runtimeEvent, status) {
@@ -9409,6 +9703,7 @@ function createFeedMapper(bootstrap) {
9409
9703
  runLifecycle,
9410
9704
  toolCorrelation,
9411
9705
  rootPlan,
9706
+ taskLifecycle,
9412
9707
  subagents,
9413
9708
  resolveToolActor
9414
9709
  });
@@ -9436,7 +9731,8 @@ function createFeedMapper(bootstrap) {
9436
9731
  });
9437
9732
  const statusProjection = createStatusProjection({
9438
9733
  ensureRunArray,
9439
- makeEvent
9734
+ makeEvent,
9735
+ taskLifecycle
9440
9736
  });
9441
9737
  const currentScope = () => subagents.currentScope();
9442
9738
  const runSessionProjection = createRunSessionProjection({
@@ -9533,7 +9829,7 @@ function createFeedMapper(bootstrap) {
9533
9829
  getSession: () => runLifecycle.getSession(),
9534
9830
  getCurrentRun: () => runLifecycle.getCurrentRun(),
9535
9831
  getActors: () => actors.all(),
9536
- getTasks: () => rootPlan.current(),
9832
+ getTasks: () => [...rootPlan.current(), ...taskLifecycle.current()],
9537
9833
  allocateSeq: () => runLifecycle.allocateSeq()
9538
9834
  };
9539
9835
  }
@@ -10247,122 +10543,3209 @@ function createSessionStore(opts) {
10247
10543
  };
10248
10544
  }
10249
10545
 
10250
- // src/infra/sessions/registry.ts
10251
- import fs18 from "fs";
10252
- import os10 from "os";
10253
- import path15 from "path";
10546
+ // src/infra/sessions/hookAudit.ts
10254
10547
  import Database2 from "better-sqlite3";
10255
- function sessionsDir() {
10256
- return path15.join(os10.homedir(), ".config", "athena", "sessions");
10548
+
10549
+ // src/core/feed/filter.ts
10550
+ var TASK_TOOL_NAMES = /* @__PURE__ */ new Set([
10551
+ "TodoWrite",
10552
+ "TaskCreate",
10553
+ "TaskUpdate",
10554
+ "TaskList",
10555
+ "TaskGet"
10556
+ ]);
10557
+ function isTaskToolEvent(event) {
10558
+ if (event.kind !== "tool.pre" && event.kind !== "tool.post") return false;
10559
+ return TASK_TOOL_NAMES.has(event.data.tool_name);
10257
10560
  }
10258
- function sessionDbPath(sessionId) {
10259
- return path15.join(sessionsDir(), sessionId, "session.db");
10561
+ function shouldExcludeFromFeed(event) {
10562
+ if (isTaskToolEvent(event)) return true;
10563
+ if (event.kind === "todo.update") return true;
10564
+ return false;
10260
10565
  }
10261
- function readSessionFromDb(dbPath) {
10262
- if (!fs18.existsSync(dbPath)) return null;
10263
- let db;
10264
- try {
10265
- db = new Database2(dbPath, { readonly: true });
10266
- const versionRow = db.prepare("SELECT version FROM schema_version").get();
10267
- if (versionRow && versionRow.version > SCHEMA_VERSION) {
10268
- return null;
10269
- }
10270
- const row = db.prepare("SELECT * FROM session LIMIT 1").get();
10271
- if (!row) return null;
10272
- const adapters = db.prepare("SELECT session_id FROM adapter_sessions ORDER BY started_at").all();
10273
- let firstPrompt;
10274
- if (!row.label && (row.event_count ?? 0) > 0) {
10275
- const promptRow = db.prepare(
10276
- `SELECT json_extract(payload, '$.data.prompt') as prompt FROM runtime_events WHERE hook_name = 'UserPromptSubmit' ORDER BY seq ASC LIMIT 1`
10277
- ).get();
10278
- if (promptRow?.prompt) {
10279
- firstPrompt = promptRow.prompt;
10280
- }
10566
+
10567
+ // src/core/feed/items.ts
10568
+ function mergeFeedItems(messages, feedEvents) {
10569
+ const messageItems = messages.map((message) => ({
10570
+ type: "message",
10571
+ data: message
10572
+ }));
10573
+ const feedItems = feedEvents.filter((event) => !shouldExcludeFromFeed(event)).map((event) => ({ type: "feed", data: event }));
10574
+ return [...messageItems, ...feedItems].sort((left, right) => {
10575
+ if (left.data.seq !== right.data.seq) return left.data.seq - right.data.seq;
10576
+ if (left.type === "message" && right.type !== "message") return -1;
10577
+ if (left.type !== "message" && right.type === "message") return 1;
10578
+ return 0;
10579
+ });
10580
+ }
10581
+ function buildPostByToolUseId(events) {
10582
+ const map = /* @__PURE__ */ new Map();
10583
+ for (const event of events) {
10584
+ if (event.kind !== "tool.delta" && event.kind !== "tool.post" && event.kind !== "tool.failure") {
10585
+ continue;
10281
10586
  }
10282
- return rowToAthenaSession(
10283
- row,
10284
- adapters.map((a) => a.session_id),
10285
- firstPrompt
10286
- );
10287
- } catch {
10288
- return null;
10289
- } finally {
10290
- db?.close();
10587
+ const toolUseId = event.data.tool_use_id;
10588
+ if (toolUseId) map.set(toolUseId, event);
10291
10589
  }
10590
+ return map;
10292
10591
  }
10293
- function listSessions(projectDir) {
10294
- const dir = sessionsDir();
10295
- if (!fs18.existsSync(dir)) return [];
10296
- const entries = fs18.readdirSync(dir, { withFileTypes: true });
10297
- const sessions = [];
10298
- for (const entry of entries) {
10299
- if (!entry.isDirectory()) continue;
10300
- const dbPath = path15.join(dir, entry.name, "session.db");
10301
- const session = readSessionFromDb(dbPath);
10302
- if (session && (session.eventCount ?? 0) > 0) {
10303
- if (!projectDir || session.projectDir === projectDir) {
10304
- sessions.push(session);
10305
- }
10306
- }
10592
+
10593
+ // node_modules/ansi-regex/index.js
10594
+ function ansiRegex({ onlyFirst = false } = {}) {
10595
+ const ST = "(?:\\u0007|\\u001B\\u005C|\\u009C)";
10596
+ const osc = `(?:\\u001B\\][\\s\\S]*?${ST})`;
10597
+ const csi = "[\\u001B\\u009B][[\\]()#;?]*(?:\\d{1,4}(?:[;:]\\d{0,4})*)?[\\dA-PR-TZcf-nq-uy=><~]";
10598
+ const pattern = `${osc}|${csi}`;
10599
+ return new RegExp(pattern, onlyFirst ? void 0 : "g");
10600
+ }
10601
+
10602
+ // node_modules/strip-ansi/index.js
10603
+ var regex = ansiRegex();
10604
+ function stripAnsi(string) {
10605
+ if (typeof string !== "string") {
10606
+ throw new TypeError(`Expected a \`string\`, got \`${typeof string}\``);
10307
10607
  }
10308
- return sessions.sort((a, b) => b.updatedAt - a.updatedAt);
10608
+ return string.replace(regex, "");
10309
10609
  }
10310
- function getSessionMeta(sessionId) {
10311
- return readSessionFromDb(sessionDbPath(sessionId));
10610
+
10611
+ // node_modules/get-east-asian-width/lookup.js
10612
+ function isAmbiguous(x) {
10613
+ return x === 161 || x === 164 || x === 167 || x === 168 || x === 170 || x === 173 || x === 174 || x >= 176 && x <= 180 || x >= 182 && x <= 186 || x >= 188 && x <= 191 || x === 198 || x === 208 || x === 215 || x === 216 || x >= 222 && x <= 225 || x === 230 || x >= 232 && x <= 234 || x === 236 || x === 237 || x === 240 || x === 242 || x === 243 || x >= 247 && x <= 250 || x === 252 || x === 254 || x === 257 || x === 273 || x === 275 || x === 283 || x === 294 || x === 295 || x === 299 || x >= 305 && x <= 307 || x === 312 || x >= 319 && x <= 322 || x === 324 || x >= 328 && x <= 331 || x === 333 || x === 338 || x === 339 || x === 358 || x === 359 || x === 363 || x === 462 || x === 464 || x === 466 || x === 468 || x === 470 || x === 472 || x === 474 || x === 476 || x === 593 || x === 609 || x === 708 || x === 711 || x >= 713 && x <= 715 || x === 717 || x === 720 || x >= 728 && x <= 731 || x === 733 || x === 735 || x >= 768 && x <= 879 || x >= 913 && x <= 929 || x >= 931 && x <= 937 || x >= 945 && x <= 961 || x >= 963 && x <= 969 || x === 1025 || x >= 1040 && x <= 1103 || x === 1105 || x === 8208 || x >= 8211 && x <= 8214 || x === 8216 || x === 8217 || x === 8220 || x === 8221 || x >= 8224 && x <= 8226 || x >= 8228 && x <= 8231 || x === 8240 || x === 8242 || x === 8243 || x === 8245 || x === 8251 || x === 8254 || x === 8308 || x === 8319 || x >= 8321 && x <= 8324 || x === 8364 || x === 8451 || x === 8453 || x === 8457 || x === 8467 || x === 8470 || x === 8481 || x === 8482 || x === 8486 || x === 8491 || x === 8531 || x === 8532 || x >= 8539 && x <= 8542 || x >= 8544 && x <= 8555 || x >= 8560 && x <= 8569 || x === 8585 || x >= 8592 && x <= 8601 || x === 8632 || x === 8633 || x === 8658 || x === 8660 || x === 8679 || x === 8704 || x === 8706 || x === 8707 || x === 8711 || x === 8712 || x === 8715 || x === 8719 || x === 8721 || x === 8725 || x === 8730 || x >= 8733 && x <= 8736 || x === 8739 || x === 8741 || x >= 8743 && x <= 8748 || x === 8750 || x >= 8756 && x <= 8759 || x === 8764 || x === 8765 || x === 8776 || x === 8780 || x === 8786 || x === 8800 || x === 8801 || x >= 8804 && x <= 8807 || x === 8810 || x === 8811 || x === 8814 || x === 8815 || x === 8834 || x === 8835 || x === 8838 || x === 8839 || x === 8853 || x === 8857 || x === 8869 || x === 8895 || x === 8978 || x >= 9312 && x <= 9449 || x >= 9451 && x <= 9547 || x >= 9552 && x <= 9587 || x >= 9600 && x <= 9615 || x >= 9618 && x <= 9621 || x === 9632 || x === 9633 || x >= 9635 && x <= 9641 || x === 9650 || x === 9651 || x === 9654 || x === 9655 || x === 9660 || x === 9661 || x === 9664 || x === 9665 || x >= 9670 && x <= 9672 || x === 9675 || x >= 9678 && x <= 9681 || x >= 9698 && x <= 9701 || x === 9711 || x === 9733 || x === 9734 || x === 9737 || x === 9742 || x === 9743 || x === 9756 || x === 9758 || x === 9792 || x === 9794 || x === 9824 || x === 9825 || x >= 9827 && x <= 9829 || x >= 9831 && x <= 9834 || x === 9836 || x === 9837 || x === 9839 || x === 9886 || x === 9887 || x === 9919 || x >= 9926 && x <= 9933 || x >= 9935 && x <= 9939 || x >= 9941 && x <= 9953 || x === 9955 || x === 9960 || x === 9961 || x >= 9963 && x <= 9969 || x === 9972 || x >= 9974 && x <= 9977 || x === 9979 || x === 9980 || x === 9982 || x === 9983 || x === 10045 || x >= 10102 && x <= 10111 || x >= 11094 && x <= 11097 || x >= 12872 && x <= 12879 || x >= 57344 && x <= 63743 || x >= 65024 && x <= 65039 || x === 65533 || x >= 127232 && x <= 127242 || x >= 127248 && x <= 127277 || x >= 127280 && x <= 127337 || x >= 127344 && x <= 127373 || x === 127375 || x === 127376 || x >= 127387 && x <= 127404 || x >= 917760 && x <= 917999 || x >= 983040 && x <= 1048573 || x >= 1048576 && x <= 1114109;
10312
10614
  }
10313
- function getMostRecentAthenaSession(projectDir) {
10314
- const sessions = listSessions(projectDir);
10315
- return sessions[0] ?? null;
10615
+ function isFullWidth(x) {
10616
+ return x === 12288 || x >= 65281 && x <= 65376 || x >= 65504 && x <= 65510;
10617
+ }
10618
+ function isWide(x) {
10619
+ return x >= 4352 && x <= 4447 || x === 8986 || x === 8987 || x === 9001 || x === 9002 || x >= 9193 && x <= 9196 || x === 9200 || x === 9203 || x === 9725 || x === 9726 || x === 9748 || x === 9749 || x >= 9776 && x <= 9783 || x >= 9800 && x <= 9811 || x === 9855 || x >= 9866 && x <= 9871 || x === 9875 || x === 9889 || x === 9898 || x === 9899 || x === 9917 || x === 9918 || x === 9924 || x === 9925 || x === 9934 || x === 9940 || x === 9962 || x === 9970 || x === 9971 || x === 9973 || x === 9978 || x === 9981 || x === 9989 || x === 9994 || x === 9995 || x === 10024 || x === 10060 || x === 10062 || x >= 10067 && x <= 10069 || x === 10071 || x >= 10133 && x <= 10135 || x === 10160 || x === 10175 || x === 11035 || x === 11036 || x === 11088 || x === 11093 || x >= 11904 && x <= 11929 || x >= 11931 && x <= 12019 || x >= 12032 && x <= 12245 || x >= 12272 && x <= 12287 || x >= 12289 && x <= 12350 || x >= 12353 && x <= 12438 || x >= 12441 && x <= 12543 || x >= 12549 && x <= 12591 || x >= 12593 && x <= 12686 || x >= 12688 && x <= 12773 || x >= 12783 && x <= 12830 || x >= 12832 && x <= 12871 || x >= 12880 && x <= 42124 || x >= 42128 && x <= 42182 || x >= 43360 && x <= 43388 || x >= 44032 && x <= 55203 || x >= 63744 && x <= 64255 || x >= 65040 && x <= 65049 || x >= 65072 && x <= 65106 || x >= 65108 && x <= 65126 || x >= 65128 && x <= 65131 || x >= 94176 && x <= 94180 || x >= 94192 && x <= 94198 || x >= 94208 && x <= 101589 || x >= 101631 && x <= 101662 || x >= 101760 && x <= 101874 || x >= 110576 && x <= 110579 || x >= 110581 && x <= 110587 || x === 110589 || x === 110590 || x >= 110592 && x <= 110882 || x === 110898 || x >= 110928 && x <= 110930 || x === 110933 || x >= 110948 && x <= 110951 || x >= 110960 && x <= 111355 || x >= 119552 && x <= 119638 || x >= 119648 && x <= 119670 || x === 126980 || x === 127183 || x === 127374 || x >= 127377 && x <= 127386 || x >= 127488 && x <= 127490 || x >= 127504 && x <= 127547 || x >= 127552 && x <= 127560 || x === 127568 || x === 127569 || x >= 127584 && x <= 127589 || x >= 127744 && x <= 127776 || x >= 127789 && x <= 127797 || x >= 127799 && x <= 127868 || x >= 127870 && x <= 127891 || x >= 127904 && x <= 127946 || x >= 127951 && x <= 127955 || x >= 127968 && x <= 127984 || x === 127988 || x >= 127992 && x <= 128062 || x === 128064 || x >= 128066 && x <= 128252 || x >= 128255 && x <= 128317 || x >= 128331 && x <= 128334 || x >= 128336 && x <= 128359 || x === 128378 || x === 128405 || x === 128406 || x === 128420 || x >= 128507 && x <= 128591 || x >= 128640 && x <= 128709 || x === 128716 || x >= 128720 && x <= 128722 || x >= 128725 && x <= 128728 || x >= 128732 && x <= 128735 || x === 128747 || x === 128748 || x >= 128756 && x <= 128764 || x >= 128992 && x <= 129003 || x === 129008 || x >= 129292 && x <= 129338 || x >= 129340 && x <= 129349 || x >= 129351 && x <= 129535 || x >= 129648 && x <= 129660 || x >= 129664 && x <= 129674 || x >= 129678 && x <= 129734 || x === 129736 || x >= 129741 && x <= 129756 || x >= 129759 && x <= 129770 || x >= 129775 && x <= 129784 || x >= 131072 && x <= 196605 || x >= 196608 && x <= 262141;
10316
10620
  }
10317
10621
 
10318
- // src/app/channels/relayAdapter.ts
10319
- function createRelayPermissionCallback(bridge, runtime) {
10320
- return (event) => {
10321
- const toolName = resolveToolName2(event);
10322
- writeGatewayTrace(
10323
- `relayAdapter relayPermission event=${event.id} tool=${toolName}`
10324
- );
10325
- void bridge.relayPermission({
10326
- toolName,
10327
- description: event.display?.title ?? `${toolName} request`,
10328
- inputPreview: previewToolInput(event),
10329
- ...event.interaction.defaultTimeoutMs !== void 0 ? { ttlMs: event.interaction.defaultTimeoutMs } : {}
10330
- }).then((res) => {
10331
- const decision = permissionRelayDecision(res.result);
10332
- if (!decision) return;
10333
- runtime.sendDecision(event.id, decision);
10334
- }).catch((err) => {
10335
- if (process.env["ATHENA_GATEWAY_TRACE"] === "1") {
10336
- console.error(
10337
- `[athena] gateway relayPermission failed: ${err instanceof Error ? err.message : String(err)}`
10338
- );
10339
- }
10340
- });
10341
- };
10622
+ // node_modules/get-east-asian-width/index.js
10623
+ function validate(codePoint) {
10624
+ if (!Number.isSafeInteger(codePoint)) {
10625
+ throw new TypeError(`Expected a code point, got \`${typeof codePoint}\`.`);
10626
+ }
10342
10627
  }
10343
- function createRelayQuestionCallback(bridge, runtime) {
10344
- return (event) => {
10345
- const questions = extractRelayQuestions(event);
10346
- const title = event.display?.title ?? "Question";
10347
- writeGatewayTrace(
10348
- `relayAdapter relayQuestion event=${event.id} count=${questions.length}`
10349
- );
10350
- void bridge.relayQuestion({
10351
- title,
10352
- questions,
10353
- ...event.interaction.defaultTimeoutMs !== void 0 ? { ttlMs: event.interaction.defaultTimeoutMs } : {}
10354
- }).then((res) => {
10355
- const decision = questionRelayDecision(res.result);
10356
- if (!decision) return;
10357
- runtime.sendDecision(event.id, decision);
10358
- }).catch((err) => {
10359
- if (process.env["ATHENA_GATEWAY_TRACE"] === "1") {
10360
- console.error(
10361
- `[athena] gateway relayQuestion failed: ${err instanceof Error ? err.message : String(err)}`
10362
- );
10628
+ function eastAsianWidth(codePoint, { ambiguousAsWide = false } = {}) {
10629
+ validate(codePoint);
10630
+ if (isFullWidth(codePoint) || isWide(codePoint) || ambiguousAsWide && isAmbiguous(codePoint)) {
10631
+ return 2;
10632
+ }
10633
+ return 1;
10634
+ }
10635
+
10636
+ // node_modules/string-width/index.js
10637
+ var segmenter = new Intl.Segmenter();
10638
+ var zeroWidthClusterRegex = new RegExp("^(?:\\p{Default_Ignorable_Code_Point}|\\p{Control}|\\p{Format}|\\p{Mark}|\\p{Surrogate})+$", "v");
10639
+ var leadingNonPrintingRegex = new RegExp("^[\\p{Default_Ignorable_Code_Point}\\p{Control}\\p{Format}\\p{Mark}\\p{Surrogate}]+", "v");
10640
+ var rgiEmojiRegex = new RegExp("^\\p{RGI_Emoji}$", "v");
10641
+ function baseVisible(segment) {
10642
+ return segment.replace(leadingNonPrintingRegex, "");
10643
+ }
10644
+ function isZeroWidthCluster(segment) {
10645
+ return zeroWidthClusterRegex.test(segment);
10646
+ }
10647
+ function trailingHalfwidthWidth(segment, eastAsianWidthOptions) {
10648
+ let extra = 0;
10649
+ if (segment.length > 1) {
10650
+ for (const char of segment.slice(1)) {
10651
+ if (char >= "\uFF00" && char <= "\uFFEF") {
10652
+ extra += eastAsianWidth(char.codePointAt(0), eastAsianWidthOptions);
10363
10653
  }
10364
- });
10365
- };
10654
+ }
10655
+ }
10656
+ return extra;
10657
+ }
10658
+ function stringWidth(input, options = {}) {
10659
+ if (typeof input !== "string" || input.length === 0) {
10660
+ return 0;
10661
+ }
10662
+ const {
10663
+ ambiguousIsNarrow = true,
10664
+ countAnsiEscapeCodes = false
10665
+ } = options;
10666
+ let string = input;
10667
+ if (!countAnsiEscapeCodes) {
10668
+ string = stripAnsi(string);
10669
+ }
10670
+ if (string.length === 0) {
10671
+ return 0;
10672
+ }
10673
+ let width = 0;
10674
+ const eastAsianWidthOptions = { ambiguousAsWide: !ambiguousIsNarrow };
10675
+ for (const { segment } of segmenter.segment(string)) {
10676
+ if (isZeroWidthCluster(segment)) {
10677
+ continue;
10678
+ }
10679
+ if (rgiEmojiRegex.test(segment)) {
10680
+ width += 2;
10681
+ continue;
10682
+ }
10683
+ const codePoint = baseVisible(segment).codePointAt(0);
10684
+ width += eastAsianWidth(codePoint, eastAsianWidthOptions);
10685
+ width += trailingHalfwidthWidth(segment, eastAsianWidthOptions);
10686
+ }
10687
+ return width;
10688
+ }
10689
+
10690
+ // node_modules/ansi-styles/index.js
10691
+ var ANSI_BACKGROUND_OFFSET = 10;
10692
+ var wrapAnsi16 = (offset = 0) => (code) => `\x1B[${code + offset}m`;
10693
+ var wrapAnsi256 = (offset = 0) => (code) => `\x1B[${38 + offset};5;${code}m`;
10694
+ var wrapAnsi16m = (offset = 0) => (red, green, blue) => `\x1B[${38 + offset};2;${red};${green};${blue}m`;
10695
+ var styles = {
10696
+ modifier: {
10697
+ reset: [0, 0],
10698
+ // 21 isn't widely supported and 22 does the same thing
10699
+ bold: [1, 22],
10700
+ dim: [2, 22],
10701
+ italic: [3, 23],
10702
+ underline: [4, 24],
10703
+ overline: [53, 55],
10704
+ inverse: [7, 27],
10705
+ hidden: [8, 28],
10706
+ strikethrough: [9, 29]
10707
+ },
10708
+ color: {
10709
+ black: [30, 39],
10710
+ red: [31, 39],
10711
+ green: [32, 39],
10712
+ yellow: [33, 39],
10713
+ blue: [34, 39],
10714
+ magenta: [35, 39],
10715
+ cyan: [36, 39],
10716
+ white: [37, 39],
10717
+ // Bright color
10718
+ blackBright: [90, 39],
10719
+ gray: [90, 39],
10720
+ // Alias of `blackBright`
10721
+ grey: [90, 39],
10722
+ // Alias of `blackBright`
10723
+ redBright: [91, 39],
10724
+ greenBright: [92, 39],
10725
+ yellowBright: [93, 39],
10726
+ blueBright: [94, 39],
10727
+ magentaBright: [95, 39],
10728
+ cyanBright: [96, 39],
10729
+ whiteBright: [97, 39]
10730
+ },
10731
+ bgColor: {
10732
+ bgBlack: [40, 49],
10733
+ bgRed: [41, 49],
10734
+ bgGreen: [42, 49],
10735
+ bgYellow: [43, 49],
10736
+ bgBlue: [44, 49],
10737
+ bgMagenta: [45, 49],
10738
+ bgCyan: [46, 49],
10739
+ bgWhite: [47, 49],
10740
+ // Bright color
10741
+ bgBlackBright: [100, 49],
10742
+ bgGray: [100, 49],
10743
+ // Alias of `bgBlackBright`
10744
+ bgGrey: [100, 49],
10745
+ // Alias of `bgBlackBright`
10746
+ bgRedBright: [101, 49],
10747
+ bgGreenBright: [102, 49],
10748
+ bgYellowBright: [103, 49],
10749
+ bgBlueBright: [104, 49],
10750
+ bgMagentaBright: [105, 49],
10751
+ bgCyanBright: [106, 49],
10752
+ bgWhiteBright: [107, 49]
10753
+ }
10754
+ };
10755
+ var modifierNames = Object.keys(styles.modifier);
10756
+ var foregroundColorNames = Object.keys(styles.color);
10757
+ var backgroundColorNames = Object.keys(styles.bgColor);
10758
+ var colorNames = [...foregroundColorNames, ...backgroundColorNames];
10759
+ function assembleStyles() {
10760
+ const codes = /* @__PURE__ */ new Map();
10761
+ for (const [groupName, group] of Object.entries(styles)) {
10762
+ for (const [styleName, style] of Object.entries(group)) {
10763
+ styles[styleName] = {
10764
+ open: `\x1B[${style[0]}m`,
10765
+ close: `\x1B[${style[1]}m`
10766
+ };
10767
+ group[styleName] = styles[styleName];
10768
+ codes.set(style[0], style[1]);
10769
+ }
10770
+ Object.defineProperty(styles, groupName, {
10771
+ value: group,
10772
+ enumerable: false
10773
+ });
10774
+ }
10775
+ Object.defineProperty(styles, "codes", {
10776
+ value: codes,
10777
+ enumerable: false
10778
+ });
10779
+ styles.color.close = "\x1B[39m";
10780
+ styles.bgColor.close = "\x1B[49m";
10781
+ styles.color.ansi = wrapAnsi16();
10782
+ styles.color.ansi256 = wrapAnsi256();
10783
+ styles.color.ansi16m = wrapAnsi16m();
10784
+ styles.bgColor.ansi = wrapAnsi16(ANSI_BACKGROUND_OFFSET);
10785
+ styles.bgColor.ansi256 = wrapAnsi256(ANSI_BACKGROUND_OFFSET);
10786
+ styles.bgColor.ansi16m = wrapAnsi16m(ANSI_BACKGROUND_OFFSET);
10787
+ Object.defineProperties(styles, {
10788
+ rgbToAnsi256: {
10789
+ value(red, green, blue) {
10790
+ if (red === green && green === blue) {
10791
+ if (red < 8) {
10792
+ return 16;
10793
+ }
10794
+ if (red > 248) {
10795
+ return 231;
10796
+ }
10797
+ return Math.round((red - 8) / 247 * 24) + 232;
10798
+ }
10799
+ return 16 + 36 * Math.round(red / 255 * 5) + 6 * Math.round(green / 255 * 5) + Math.round(blue / 255 * 5);
10800
+ },
10801
+ enumerable: false
10802
+ },
10803
+ hexToRgb: {
10804
+ value(hex) {
10805
+ const matches = /[a-f\d]{6}|[a-f\d]{3}/i.exec(hex.toString(16));
10806
+ if (!matches) {
10807
+ return [0, 0, 0];
10808
+ }
10809
+ let [colorString] = matches;
10810
+ if (colorString.length === 3) {
10811
+ colorString = [...colorString].map((character) => character + character).join("");
10812
+ }
10813
+ const integer = Number.parseInt(colorString, 16);
10814
+ return [
10815
+ /* eslint-disable no-bitwise */
10816
+ integer >> 16 & 255,
10817
+ integer >> 8 & 255,
10818
+ integer & 255
10819
+ /* eslint-enable no-bitwise */
10820
+ ];
10821
+ },
10822
+ enumerable: false
10823
+ },
10824
+ hexToAnsi256: {
10825
+ value: (hex) => styles.rgbToAnsi256(...styles.hexToRgb(hex)),
10826
+ enumerable: false
10827
+ },
10828
+ ansi256ToAnsi: {
10829
+ value(code) {
10830
+ if (code < 8) {
10831
+ return 30 + code;
10832
+ }
10833
+ if (code < 16) {
10834
+ return 90 + (code - 8);
10835
+ }
10836
+ let red;
10837
+ let green;
10838
+ let blue;
10839
+ if (code >= 232) {
10840
+ red = ((code - 232) * 10 + 8) / 255;
10841
+ green = red;
10842
+ blue = red;
10843
+ } else {
10844
+ code -= 16;
10845
+ const remainder = code % 36;
10846
+ red = Math.floor(code / 36) / 5;
10847
+ green = Math.floor(remainder / 6) / 5;
10848
+ blue = remainder % 6 / 5;
10849
+ }
10850
+ const value = Math.max(red, green, blue) * 2;
10851
+ if (value === 0) {
10852
+ return 30;
10853
+ }
10854
+ let result = 30 + (Math.round(blue) << 2 | Math.round(green) << 1 | Math.round(red));
10855
+ if (value === 2) {
10856
+ result += 60;
10857
+ }
10858
+ return result;
10859
+ },
10860
+ enumerable: false
10861
+ },
10862
+ rgbToAnsi: {
10863
+ value: (red, green, blue) => styles.ansi256ToAnsi(styles.rgbToAnsi256(red, green, blue)),
10864
+ enumerable: false
10865
+ },
10866
+ hexToAnsi: {
10867
+ value: (hex) => styles.ansi256ToAnsi(styles.hexToAnsi256(hex)),
10868
+ enumerable: false
10869
+ }
10870
+ });
10871
+ return styles;
10872
+ }
10873
+ var ansiStyles = assembleStyles();
10874
+ var ansi_styles_default = ansiStyles;
10875
+
10876
+ // node_modules/is-fullwidth-code-point/index.js
10877
+ function isFullwidthCodePoint(codePoint) {
10878
+ if (!Number.isInteger(codePoint)) {
10879
+ return false;
10880
+ }
10881
+ return isFullWidth(codePoint) || isWide(codePoint);
10882
+ }
10883
+
10884
+ // node_modules/slice-ansi/index.js
10885
+ var ESCAPES = /* @__PURE__ */ new Set([27, 155]);
10886
+ var CODE_POINT_0 = "0".codePointAt(0);
10887
+ var CODE_POINT_9 = "9".codePointAt(0);
10888
+ var MAX_ANSI_SEQUENCE_LENGTH = 19;
10889
+ var endCodesSet = /* @__PURE__ */ new Set();
10890
+ var endCodesMap = /* @__PURE__ */ new Map();
10891
+ for (const [start, end] of ansi_styles_default.codes) {
10892
+ endCodesSet.add(ansi_styles_default.color.ansi(end));
10893
+ endCodesMap.set(ansi_styles_default.color.ansi(start), ansi_styles_default.color.ansi(end));
10894
+ }
10895
+ function getEndCode(code) {
10896
+ if (endCodesSet.has(code)) {
10897
+ return code;
10898
+ }
10899
+ if (endCodesMap.has(code)) {
10900
+ return endCodesMap.get(code);
10901
+ }
10902
+ code = code.slice(2);
10903
+ if (code.includes(";")) {
10904
+ code = code[0] + "0";
10905
+ }
10906
+ const returnValue = ansi_styles_default.codes.get(Number.parseInt(code, 10));
10907
+ if (returnValue) {
10908
+ return ansi_styles_default.color.ansi(returnValue);
10909
+ }
10910
+ return ansi_styles_default.reset.open;
10911
+ }
10912
+ function findNumberIndex(string) {
10913
+ for (let index = 0; index < string.length; index++) {
10914
+ const codePoint = string.codePointAt(index);
10915
+ if (codePoint >= CODE_POINT_0 && codePoint <= CODE_POINT_9) {
10916
+ return index;
10917
+ }
10918
+ }
10919
+ return -1;
10920
+ }
10921
+ function parseAnsiCode(string, offset) {
10922
+ string = string.slice(offset, offset + MAX_ANSI_SEQUENCE_LENGTH);
10923
+ const startIndex = findNumberIndex(string);
10924
+ if (startIndex !== -1) {
10925
+ let endIndex = string.indexOf("m", startIndex);
10926
+ if (endIndex === -1) {
10927
+ endIndex = string.length;
10928
+ }
10929
+ return string.slice(0, endIndex + 1);
10930
+ }
10931
+ }
10932
+ function tokenize(string, endCharacter = Number.POSITIVE_INFINITY) {
10933
+ const returnValue = [];
10934
+ let index = 0;
10935
+ let visibleCount = 0;
10936
+ while (index < string.length) {
10937
+ const codePoint = string.codePointAt(index);
10938
+ if (ESCAPES.has(codePoint)) {
10939
+ const code = parseAnsiCode(string, index);
10940
+ if (code) {
10941
+ returnValue.push({
10942
+ type: "ansi",
10943
+ code,
10944
+ endCode: getEndCode(code)
10945
+ });
10946
+ index += code.length;
10947
+ continue;
10948
+ }
10949
+ }
10950
+ const isFullWidth2 = isFullwidthCodePoint(codePoint);
10951
+ const character = String.fromCodePoint(codePoint);
10952
+ returnValue.push({
10953
+ type: "character",
10954
+ value: character,
10955
+ isFullWidth: isFullWidth2
10956
+ });
10957
+ index += character.length;
10958
+ visibleCount += isFullWidth2 ? 2 : character.length;
10959
+ if (visibleCount >= endCharacter) {
10960
+ break;
10961
+ }
10962
+ }
10963
+ return returnValue;
10964
+ }
10965
+ function reduceAnsiCodes(codes) {
10966
+ let returnValue = [];
10967
+ for (const code of codes) {
10968
+ if (code.code === ansi_styles_default.reset.open) {
10969
+ returnValue = [];
10970
+ } else if (endCodesSet.has(code.code)) {
10971
+ returnValue = returnValue.filter((returnValueCode) => returnValueCode.endCode !== code.code);
10972
+ } else {
10973
+ returnValue = returnValue.filter((returnValueCode) => returnValueCode.endCode !== code.endCode);
10974
+ returnValue.push(code);
10975
+ }
10976
+ }
10977
+ return returnValue;
10978
+ }
10979
+ function undoAnsiCodes(codes) {
10980
+ const reduced = reduceAnsiCodes(codes);
10981
+ const endCodes = reduced.map(({ endCode }) => endCode);
10982
+ return endCodes.reverse().join("");
10983
+ }
10984
+ function sliceAnsi(string, start, end) {
10985
+ const tokens = tokenize(string, end);
10986
+ let activeCodes = [];
10987
+ let position = 0;
10988
+ let returnValue = "";
10989
+ let include = false;
10990
+ for (const token of tokens) {
10991
+ if (end !== void 0 && position >= end) {
10992
+ break;
10993
+ }
10994
+ if (token.type === "ansi") {
10995
+ activeCodes.push(token);
10996
+ if (include) {
10997
+ returnValue += token.code;
10998
+ }
10999
+ } else {
11000
+ if (!include && position >= start) {
11001
+ include = true;
11002
+ activeCodes = reduceAnsiCodes(activeCodes);
11003
+ returnValue = activeCodes.map(({ code }) => code).join("");
11004
+ }
11005
+ if (include) {
11006
+ returnValue += token.value;
11007
+ }
11008
+ position += token.isFullWidth ? 2 : token.value.length;
11009
+ }
11010
+ }
11011
+ returnValue += undoAnsiCodes(activeCodes);
11012
+ return returnValue;
11013
+ }
11014
+
11015
+ // src/shared/utils/toolNameParser.ts
11016
+ function extractFriendlyServerName(mcpServer) {
11017
+ const pluginMatch = /^plugin_[^_]+_(.+)$/.exec(mcpServer);
11018
+ if (pluginMatch) {
11019
+ return pluginMatch[1];
11020
+ }
11021
+ return mcpServer;
11022
+ }
11023
+ function parseToolName(toolName) {
11024
+ const match = /^mcp__([^_]+(?:_[^_]+)*)__(.+)$/.exec(toolName);
11025
+ if (match) {
11026
+ const mcpServer = match[1];
11027
+ const mcpAction = match[2];
11028
+ const friendlyServer = extractFriendlyServerName(mcpServer);
11029
+ return {
11030
+ displayName: mcpAction,
11031
+ isMcp: true,
11032
+ mcpServer,
11033
+ mcpAction,
11034
+ serverLabel: `${friendlyServer} (MCP)`
11035
+ };
11036
+ }
11037
+ return {
11038
+ displayName: toolName,
11039
+ isMcp: false
11040
+ };
11041
+ }
11042
+
11043
+ // src/shared/utils/format.ts
11044
+ var SIMPLE_ASCII_RE = /^[\x20-\x7E]*$/;
11045
+ var WIDTH_CACHE_MAX = 2e3;
11046
+ var WIDTH_CACHE_MAX_TEXT_LENGTH = 512;
11047
+ var SPACE_CACHE_MAX = 128;
11048
+ var widthCache = /* @__PURE__ */ new Map();
11049
+ var spaceCache = [""];
11050
+ function cachedStringWidth(text) {
11051
+ if (text.length > WIDTH_CACHE_MAX_TEXT_LENGTH) {
11052
+ return stringWidth(text);
11053
+ }
11054
+ const cached = widthCache.get(text);
11055
+ if (cached !== void 0) {
11056
+ widthCache.delete(text);
11057
+ widthCache.set(text, cached);
11058
+ return cached;
11059
+ }
11060
+ const measured = stringWidth(text);
11061
+ widthCache.set(text, measured);
11062
+ if (widthCache.size > WIDTH_CACHE_MAX) {
11063
+ const oldest = widthCache.keys().next().value;
11064
+ if (oldest !== void 0) {
11065
+ widthCache.delete(oldest);
11066
+ }
11067
+ }
11068
+ return measured;
11069
+ }
11070
+ function spaces(count) {
11071
+ if (count <= 0) return "";
11072
+ if (count < SPACE_CACHE_MAX) {
11073
+ if (count in spaceCache) {
11074
+ return spaceCache[count];
11075
+ }
11076
+ const generated = " ".repeat(count);
11077
+ spaceCache[count] = generated;
11078
+ return generated;
11079
+ }
11080
+ return " ".repeat(count);
11081
+ }
11082
+ function isSimpleAscii(text) {
11083
+ return SIMPLE_ASCII_RE.test(text);
11084
+ }
11085
+ function fitAscii(text, width) {
11086
+ if (width <= 0) return "";
11087
+ const len = text.length;
11088
+ if (len <= width) {
11089
+ const pad = width - len;
11090
+ return pad > 0 ? text + spaces(pad) : text;
11091
+ }
11092
+ if (width <= 3) return text.slice(0, width);
11093
+ return text.slice(0, width - 3) + "...";
11094
+ }
11095
+ function compactText(value, max) {
11096
+ const clean = value.replace(/\s+/g, " ").trim();
11097
+ if (max <= 0) return "";
11098
+ if (isSimpleAscii(clean)) {
11099
+ if (clean.length <= max) return clean;
11100
+ if (max <= 3) return clean.slice(0, max);
11101
+ return clean.slice(0, max - 3) + "...";
11102
+ }
11103
+ const w = cachedStringWidth(clean);
11104
+ if (w <= max) return clean;
11105
+ if (max <= 3) return sliceAnsi(clean, 0, max);
11106
+ return sliceAnsi(clean, 0, max - 3) + "...";
11107
+ }
11108
+ function fit(text, width) {
11109
+ if (isSimpleAscii(text)) {
11110
+ return fitAscii(text, width);
11111
+ }
11112
+ if (width <= 0) return "";
11113
+ const w = cachedStringWidth(text);
11114
+ if (w <= width) {
11115
+ const pad = width - w;
11116
+ return pad > 0 ? text + spaces(pad) : text;
11117
+ }
11118
+ if (width <= 3) return sliceAnsi(text, 0, width);
11119
+ return sliceAnsi(text, 0, width - 3) + "...";
11120
+ }
11121
+ function fitAnsi(text, width) {
11122
+ if (isSimpleAscii(text)) {
11123
+ return fitAscii(text, width);
11124
+ }
11125
+ if (width <= 0) return "";
11126
+ const visualWidth = cachedStringWidth(text);
11127
+ if (visualWidth <= width) {
11128
+ const pad = width - visualWidth;
11129
+ return pad > 0 ? text + spaces(pad) : text;
11130
+ }
11131
+ if (width <= 3) return sliceAnsi(text, 0, width);
11132
+ return sliceAnsi(text, 0, width - 3) + "...";
11133
+ }
11134
+ function centerAnsi(text, width) {
11135
+ if (width <= 0) return "";
11136
+ const visualWidth = cachedStringWidth(text);
11137
+ if (visualWidth >= width) return sliceAnsi(text, 0, width);
11138
+ const left = Math.floor((width - visualWidth) / 2);
11139
+ const right = width - left - visualWidth;
11140
+ return spaces(left) + text + spaces(right);
11141
+ }
11142
+ function formatClock(timestamp) {
11143
+ const d = new Date(timestamp);
11144
+ const hh = String(d.getHours()).padStart(2, "0");
11145
+ const mm = String(d.getMinutes()).padStart(2, "0");
11146
+ return `${hh}:${mm}`;
11147
+ }
11148
+ function formatRunLabel(runId) {
11149
+ if (!runId) return "R-";
11150
+ const direct = runId.match(/^(R\d+)$/i);
11151
+ if (direct) return direct[1].toUpperCase();
11152
+ const tail2 = runId.replace(/[^a-zA-Z0-9]/g, "").slice(-4);
11153
+ return `R${tail2 || "-"}`;
11154
+ }
11155
+ function actorLabel(actorId) {
11156
+ if (actorId === "user") return "USER";
11157
+ if (actorId === "agent:root") return "AGENT";
11158
+ if (actorId === "system") return "SYSTEM";
11159
+ if (actorId.startsWith("subagent:")) {
11160
+ return "SUB-AGENT";
11161
+ }
11162
+ return compactText(actorId.toUpperCase(), 12);
11163
+ }
11164
+ function summarizeValue(value) {
11165
+ if (typeof value === "string") return compactText(JSON.stringify(value), 28);
11166
+ if (typeof value === "number" || typeof value === "boolean") {
11167
+ return String(value);
11168
+ }
11169
+ if (value === null || value === void 0) return String(value);
11170
+ if (Array.isArray(value)) return `[${value.length}]`;
11171
+ if (typeof value === "object") return "{...}";
11172
+ return compactText(String(value), 20);
11173
+ }
11174
+ function summarizeToolInput(input) {
11175
+ const entries = Object.entries(input);
11176
+ const pairs = entries.slice(0, 2).map(([key, value]) => `${key}=${summarizeValue(value)}`);
11177
+ const overflow = entries.length - 2;
11178
+ if (overflow > 0) {
11179
+ pairs.push(`+${overflow}`);
11180
+ }
11181
+ return pairs.join(" ");
11182
+ }
11183
+ function shortenPath(filePath) {
11184
+ const segments = filePath.split("/").filter(Boolean);
11185
+ if (segments.length <= 2) return segments.join("/");
11186
+ return "\u2026/" + segments.slice(-2).join("/");
11187
+ }
11188
+ function compactCommandPaths(cmd) {
11189
+ return cmd.replace(
11190
+ /\/(?:[\w.@-]+\/){2,}[\w.@-]+/g,
11191
+ (match) => shortenPath(match)
11192
+ );
11193
+ }
11194
+ function shortenPathStructured(filePath) {
11195
+ const segments = filePath.split("/").filter(Boolean);
11196
+ if (segments.length === 0) return { prefix: "", filename: filePath };
11197
+ const filename = segments[segments.length - 1];
11198
+ if (segments.length === 1) return { prefix: "", filename };
11199
+ if (segments.length === 2) return { prefix: segments[0] + "/", filename };
11200
+ return { prefix: "\u2026/" + segments[segments.length - 2] + "/", filename };
11201
+ }
11202
+ var filePathExtractor = (input) => shortenPath(String(input.file_path ?? ""));
11203
+ var PRIMARY_INPUT_EXTRACTORS = {
11204
+ Read: filePathExtractor,
11205
+ Write: filePathExtractor,
11206
+ Edit: filePathExtractor,
11207
+ Bash: (input) => compactText(compactCommandPaths(String(input.command ?? "")), 96),
11208
+ Glob: (input) => String(input.pattern ?? ""),
11209
+ Grep: (input) => {
11210
+ const p = `"${String(input.pattern ?? "")}"`;
11211
+ const g = input.glob ? ` ${String(input.glob)}` : "";
11212
+ return p + g;
11213
+ },
11214
+ Task: (input) => compactText(String(input.description ?? ""), 96),
11215
+ Agent: (input) => compactText(String(input.description ?? ""), 96),
11216
+ WebSearch: (input) => `"${String(input.query ?? "")}"`,
11217
+ WebFetch: (input) => compactText(String(input.url ?? ""), 96),
11218
+ Skill: (input) => {
11219
+ const name = String(input.skill ?? "");
11220
+ const colonIdx = name.indexOf(":");
11221
+ return compactText(colonIdx >= 0 ? name.slice(colonIdx + 1) : name, 80);
11222
+ },
11223
+ NotebookEdit: (input) => {
11224
+ const path22 = String(input.notebook_path ?? "");
11225
+ return path22 ? shortenPath(path22) : "";
11226
+ },
11227
+ AskUserQuestion: (input) => {
11228
+ const questions = input.questions;
11229
+ const n = Array.isArray(questions) ? questions.length : 0;
11230
+ return `${n} question${n !== 1 ? "s" : ""}`;
11231
+ }
11232
+ };
11233
+ var eidExtractor = (input) => {
11234
+ const eid = String(input.eid ?? "");
11235
+ return eid ? `eid:${eid.slice(0, 6)}\u2026` : "";
11236
+ };
11237
+ var MCP_INPUT_EXTRACTORS = {
11238
+ navigate: (input) => {
11239
+ const url = String(input.url ?? "");
11240
+ try {
11241
+ const u = new URL(url);
11242
+ return u.hostname.replace(/^www\./, "");
11243
+ } catch {
11244
+ return compactText(url, 96);
11245
+ }
11246
+ },
11247
+ find_elements: (input) => {
11248
+ const parts = [];
11249
+ if (input.kind) parts.push(String(input.kind));
11250
+ if (input.label) parts.push(`"${String(input.label)}"`);
11251
+ if (parts.length === 0 && input.region) parts.push(String(input.region));
11252
+ return parts.join(" ") || "elements";
11253
+ },
11254
+ get_element_details: eidExtractor,
11255
+ click: eidExtractor,
11256
+ type: (input) => {
11257
+ const text = String(input.text ?? "");
11258
+ const eid = input.eid ? String(input.eid).slice(0, 5) + "\u2026" : "";
11259
+ const quoted = `"${compactText(text, 72)}"`;
11260
+ return eid ? `${quoted} \u2192 ${eid}` : quoted;
11261
+ },
11262
+ hover: eidExtractor,
11263
+ select: (input) => {
11264
+ const value = String(input.value ?? "");
11265
+ return value ? `"${compactText(value, 72)}"` : "";
11266
+ },
11267
+ press: (input) => String(input.key ?? ""),
11268
+ scroll_page: (input) => String(input.direction ?? ""),
11269
+ take_screenshot: () => "",
11270
+ close_session: () => "session",
11271
+ close_page: () => ""
11272
+ };
11273
+ function summarizeToolPrimaryInput(toolName, toolInput) {
11274
+ if (toolName in PRIMARY_INPUT_EXTRACTORS) {
11275
+ if (Object.keys(toolInput).length === 0) return "";
11276
+ return PRIMARY_INPUT_EXTRACTORS[toolName](toolInput);
11277
+ }
11278
+ const parsed = parseToolName(toolName);
11279
+ if (parsed.isMcp && parsed.mcpAction) {
11280
+ if (parsed.mcpAction in MCP_INPUT_EXTRACTORS) {
11281
+ return MCP_INPUT_EXTRACTORS[parsed.mcpAction](toolInput);
11282
+ }
11283
+ }
11284
+ if (Object.keys(toolInput).length === 0) return "";
11285
+ return summarizeToolInput(toolInput);
11286
+ }
11287
+ var MAX_INPUT_ROWS = 6;
11288
+ var CURSOR_ON = "\x1B[7m";
11289
+ var CURSOR_OFF = "\x1B[27m";
11290
+ function cursorToVisualPosition(value, cursorOffset, width) {
11291
+ if (width <= 0) return { line: 0, col: cursorOffset, totalLines: 1 };
11292
+ const segments = value.split("\n");
11293
+ let visualLine = 0;
11294
+ let globalOffset = 0;
11295
+ for (let s = 0; s < segments.length; s++) {
11296
+ const seg = segments[s];
11297
+ const segEnd = globalOffset + seg.length;
11298
+ if (cursorOffset <= segEnd) {
11299
+ const posInSeg = cursorOffset - globalOffset;
11300
+ const totalLines2 = visualLine + countSegmentVisualLines(segments, s, width);
11301
+ if (seg.length === 0) {
11302
+ return { line: visualLine, col: 0, totalLines: totalLines2 };
11303
+ }
11304
+ const lineInSeg = Math.min(
11305
+ Math.floor(posInSeg / width),
11306
+ segmentVisualLines(seg.length, width) - 1
11307
+ );
11308
+ const colInLine = posInSeg - lineInSeg * width;
11309
+ return { line: visualLine + lineInSeg, col: colInLine, totalLines: totalLines2 };
11310
+ }
11311
+ visualLine += segmentVisualLines(seg.length, width);
11312
+ globalOffset = segEnd + 1;
11313
+ }
11314
+ const totalLines = wrapText(value, width).length;
11315
+ return { line: Math.max(0, totalLines - 1), col: 0, totalLines };
11316
+ }
11317
+ function segmentVisualLines(segLen, width) {
11318
+ return segLen === 0 ? 1 : Math.ceil(segLen / width);
11319
+ }
11320
+ function countSegmentVisualLines(segments, fromIdx, width) {
11321
+ let count = 0;
11322
+ for (let i = fromIdx; i < segments.length; i++) {
11323
+ count += segmentVisualLines(segments[i].length, width);
11324
+ }
11325
+ return count;
11326
+ }
11327
+ function visualPositionToOffset(value, targetLine, targetCol, width) {
11328
+ if (width <= 0) return targetCol;
11329
+ const segments = value.split("\n");
11330
+ let visualLine = 0;
11331
+ let globalOffset = 0;
11332
+ for (let s = 0; s < segments.length; s++) {
11333
+ const seg = segments[s];
11334
+ const numWrappedLines = segmentVisualLines(seg.length, width);
11335
+ if (targetLine < visualLine + numWrappedLines) {
11336
+ const lineInSeg = targetLine - visualLine;
11337
+ const lineStart = lineInSeg * width;
11338
+ const lineLen = Math.min(width, seg.length - lineStart);
11339
+ return globalOffset + lineStart + Math.min(targetCol, lineLen);
11340
+ }
11341
+ visualLine += numWrappedLines;
11342
+ globalOffset += seg.length + 1;
11343
+ }
11344
+ return value.length;
11345
+ }
11346
+ function renderInputLines(value, cursorOffset, width, showCursor, placeholder) {
11347
+ if (width <= 0) return [""];
11348
+ if (value.length === 0) {
11349
+ if (!showCursor) return [fit(placeholder, width)];
11350
+ const cursor = `${CURSOR_ON} ${CURSOR_OFF}`;
11351
+ return [cursor + fit(placeholder, width - 1)];
11352
+ }
11353
+ if (!showCursor) {
11354
+ const rawLines2 = wrapText(value, width);
11355
+ const visible = rawLines2.slice(0, MAX_INPUT_ROWS);
11356
+ return visible.map((line) => fit(line, width));
11357
+ }
11358
+ const rawLines = wrapText(value, width);
11359
+ const { line: cursorLine, col: cursorCol } = cursorToVisualPosition(
11360
+ value,
11361
+ cursorOffset,
11362
+ width
11363
+ );
11364
+ let viewStart = 0;
11365
+ if (rawLines.length > MAX_INPUT_ROWS) {
11366
+ viewStart = Math.max(
11367
+ 0,
11368
+ Math.min(
11369
+ cursorLine - Math.floor(MAX_INPUT_ROWS / 2),
11370
+ rawLines.length - MAX_INPUT_ROWS
11371
+ )
11372
+ );
11373
+ }
11374
+ const visibleLines = rawLines.slice(viewStart, viewStart + MAX_INPUT_ROWS);
11375
+ return visibleLines.map((line, i) => {
11376
+ const globalIdx = viewStart + i;
11377
+ if (globalIdx === cursorLine) {
11378
+ const before = line.slice(0, cursorCol);
11379
+ const charAtCursor = cursorCol < line.length ? line[cursorCol] : " ";
11380
+ const after = cursorCol < line.length ? line.slice(cursorCol + 1) : "";
11381
+ const rendered = `${before}${CURSOR_ON}${charAtCursor}${CURSOR_OFF}${after}`;
11382
+ return fitAnsi(rendered, width);
11383
+ }
11384
+ return fit(line, width);
11385
+ });
11386
+ }
11387
+ function wrapText(text, width) {
11388
+ if (width <= 0) return [text];
11389
+ const lines = [];
11390
+ for (const segment of text.split("\n")) {
11391
+ if (segment.length === 0) {
11392
+ lines.push("");
11393
+ continue;
11394
+ }
11395
+ for (let i = 0; i < segment.length; i += width) {
11396
+ lines.push(segment.slice(i, i + width));
11397
+ }
11398
+ }
11399
+ return lines;
11400
+ }
11401
+ function computeInputRows(value, width) {
11402
+ if (!value || width <= 0) return 1;
11403
+ return Math.max(1, Math.min(wrapText(value, width).length, MAX_INPUT_ROWS));
11404
+ }
11405
+ function isCommandPrefix(value) {
11406
+ return value.startsWith("/") && !value.includes(" ");
11407
+ }
11408
+
11409
+ // src/shared/utils/toolResponse.ts
11410
+ function isRecord(value) {
11411
+ return typeof value === "object" && value !== null;
11412
+ }
11413
+ function formatToolResponse(response) {
11414
+ if (response == null) return "";
11415
+ if (typeof response === "string") return response.trim();
11416
+ if (Array.isArray(response)) {
11417
+ const parts = [];
11418
+ for (const block of response) {
11419
+ if (!isRecord(block)) continue;
11420
+ if (block["type"] === "image") {
11421
+ parts.push("[image]");
11422
+ } else if (typeof block["text"] === "string") {
11423
+ parts.push(block["text"]);
11424
+ }
11425
+ }
11426
+ if (parts.length > 0) return parts.join("\n").trim();
11427
+ return JSON.stringify(response, null, 2);
11428
+ }
11429
+ if (isRecord(response)) {
11430
+ if (typeof response["text"] === "string" && response["type"] === "text") {
11431
+ return response["text"].trim();
11432
+ }
11433
+ if ("content" in response && response["content"] != null) {
11434
+ return formatToolResponse(response["content"]);
11435
+ }
11436
+ return Object.entries(response).map(([key, val]) => {
11437
+ const valStr = typeof val === "string" ? val : JSON.stringify(val);
11438
+ return ` ${key}: ${valStr}`;
11439
+ }).join("\n");
11440
+ }
11441
+ return String(response);
11442
+ }
11443
+ function isBashToolResponse(response) {
11444
+ return isRecord(response) && typeof response["stdout"] === "string";
11445
+ }
11446
+
11447
+ // src/core/feed/toolSummary.ts
11448
+ function prop(obj, key) {
11449
+ if (typeof obj === "object" && obj !== null) {
11450
+ return obj[key];
11451
+ }
11452
+ return void 0;
11453
+ }
11454
+ function extractFileContent(response) {
11455
+ if (Array.isArray(response)) {
11456
+ for (const block of response) {
11457
+ const fc = prop(prop(block, "file"), "content");
11458
+ if (typeof fc === "string") return fc;
11459
+ const text = prop(block, "text");
11460
+ if (typeof text === "string") return text;
11461
+ }
11462
+ }
11463
+ return void 0;
11464
+ }
11465
+ function summarizeBash(_input, response) {
11466
+ if (isBashToolResponse(response)) {
11467
+ const exitCode = prop(response, "exitCode") ?? 0;
11468
+ const stderr = response.stderr.trim();
11469
+ const firstLine = stderr.split("\n")[0] ?? "";
11470
+ if (stderr && Number(exitCode) !== 0) {
11471
+ return `exit ${exitCode} \u2014 ${firstLine}`;
11472
+ }
11473
+ return `exit ${exitCode}`;
11474
+ }
11475
+ return "";
11476
+ }
11477
+ function summarizeRead(_input, response) {
11478
+ const content = extractFileContent(response);
11479
+ if (content) {
11480
+ const lines = content.split("\n").length;
11481
+ return `${lines} lines`;
11482
+ }
11483
+ return "";
11484
+ }
11485
+ function summarizeEdit(input, _response) {
11486
+ const oldStr = typeof input["old_string"] === "string" ? input["old_string"] : "";
11487
+ const newStr = typeof input["new_string"] === "string" ? input["new_string"] : "";
11488
+ const oldLines = oldStr.split("\n").length;
11489
+ const newLines = newStr.split("\n").length;
11490
+ return `replaced ${oldLines} \u2192 ${newLines} lines`;
11491
+ }
11492
+ function summarizeWrite(_input, _response) {
11493
+ return "";
11494
+ }
11495
+ function summarizeGlob(_input, response) {
11496
+ const filenames = prop(response, "filenames");
11497
+ if (Array.isArray(filenames))
11498
+ return `${filenames.length} ${filenames.length === 1 ? "file" : "files"}`;
11499
+ const numFiles = prop(response, "numFiles");
11500
+ if (typeof numFiles === "number")
11501
+ return `${numFiles} ${numFiles === 1 ? "file" : "files"}`;
11502
+ return "";
11503
+ }
11504
+ function summarizeGrep(_input, response) {
11505
+ if (typeof response === "string") {
11506
+ const matches = response.split("\n").filter(Boolean).length;
11507
+ return `${matches} matches`;
11508
+ }
11509
+ if (typeof response === "object" && response !== null) {
11510
+ const numMatches = prop(response, "numMatches");
11511
+ if (typeof numMatches === "number") return `${numMatches} matches`;
11512
+ const count = prop(response, "count");
11513
+ if (typeof count === "number") return `${count} matches`;
11514
+ }
11515
+ return "";
11516
+ }
11517
+ function summarizeWebSearch(_input, response) {
11518
+ const results = prop(response, "results");
11519
+ if (Array.isArray(results)) {
11520
+ let count = 0;
11521
+ for (const entry of results) {
11522
+ const content = prop(entry, "content");
11523
+ count += Array.isArray(content) ? content.length : 1;
11524
+ }
11525
+ return `${count} results`;
11526
+ }
11527
+ const actionType = prop(response, "type");
11528
+ if (typeof actionType === "string") {
11529
+ return actionType.replace(/_/g, " ");
11530
+ }
11531
+ return "";
11532
+ }
11533
+ function summarizeTask(input, _response) {
11534
+ const agentType = input["subagent_type"] ?? "agent";
11535
+ return String(agentType);
11536
+ }
11537
+ var SUMMARIZERS = {
11538
+ Bash: summarizeBash,
11539
+ Read: summarizeRead,
11540
+ Edit: summarizeEdit,
11541
+ Write: summarizeWrite,
11542
+ Glob: summarizeGlob,
11543
+ Grep: summarizeGrep,
11544
+ WebSearch: summarizeWebSearch,
11545
+ Task: summarizeTask,
11546
+ Agent: summarizeTask
11547
+ };
11548
+ function summarizeFindElements(_input, response) {
11549
+ if (typeof response === "object" && response !== null) {
11550
+ const elements = prop(response, "elements") ?? prop(response, "items");
11551
+ if (Array.isArray(elements)) return `${elements.length} found`;
11552
+ if (Array.isArray(response)) return `${response.length} found`;
11553
+ }
11554
+ return "";
11555
+ }
11556
+ var MCP_SUMMARIZERS = {
11557
+ find_elements: summarizeFindElements
11558
+ };
11559
+ function summarizeToolResult(toolName, toolInput, toolResponse, error) {
11560
+ if (error) {
11561
+ const firstLine = error.split("\n")[0] ?? error;
11562
+ return compactText(firstLine, 160);
11563
+ }
11564
+ if (toolName in SUMMARIZERS) {
11565
+ try {
11566
+ return SUMMARIZERS[toolName](toolInput, toolResponse);
11567
+ } catch {
11568
+ return "";
11569
+ }
11570
+ }
11571
+ const parsed = parseToolName(toolName);
11572
+ if (parsed.isMcp && parsed.mcpAction) {
11573
+ if (parsed.mcpAction in MCP_SUMMARIZERS) {
11574
+ try {
11575
+ return MCP_SUMMARIZERS[parsed.mcpAction](toolInput, toolResponse);
11576
+ } catch {
11577
+ return "";
11578
+ }
11579
+ }
11580
+ }
11581
+ return "";
11582
+ }
11583
+
11584
+ // src/core/feed/verbMap.ts
11585
+ var MCP_VERB_MAP = {
11586
+ navigate: "Navigate",
11587
+ find_elements: "Find",
11588
+ click: "Click",
11589
+ close_session: "Close",
11590
+ close_page: "Close",
11591
+ type: "Type",
11592
+ take_screenshot: "Screenshot",
11593
+ capture_snapshot: "Snapshot",
11594
+ scroll_page: "Scroll",
11595
+ scroll_element_into_view: "Scroll",
11596
+ hover: "Hover",
11597
+ press: "Press",
11598
+ select: "Select",
11599
+ go_back: "Back",
11600
+ go_forward: "Forward",
11601
+ reload: "Reload",
11602
+ list_pages: "Pages",
11603
+ get_element_details: "Inspect",
11604
+ get_form_understanding: "FormScan",
11605
+ get_field_context: "FieldInfo",
11606
+ ping: "Ping",
11607
+ // context7
11608
+ "resolve-library-id": "Resolve",
11609
+ "query-docs": "QueryDocs"
11610
+ };
11611
+ function resolveVerb(toolName, parsed) {
11612
+ if (!parsed.isMcp || !parsed.mcpAction) return toolName;
11613
+ const mapped = MCP_VERB_MAP[parsed.mcpAction];
11614
+ if (mapped) return mapped;
11615
+ const action = parsed.mcpAction;
11616
+ return action.charAt(0).toUpperCase() + action.slice(1).replace(/_/g, " ");
11617
+ }
11618
+
11619
+ // src/core/feed/timeline.ts
11620
+ function opCategory(op) {
11621
+ const dot = op.indexOf(".");
11622
+ return dot >= 0 ? op.slice(0, dot) : op;
11623
+ }
11624
+ function computeDuplicateActors(entries) {
11625
+ for (let i = 0; i < entries.length; i++) {
11626
+ const prev = i > 0 ? entries[i - 1] : void 0;
11627
+ const sameActor = prev !== void 0 && entries[i].actorId === prev.actorId;
11628
+ const isBreak = prev !== void 0 && opCategory(entries[i].opTag) !== opCategory(prev.opTag);
11629
+ entries[i].duplicateActor = sameActor && !isBreak;
11630
+ }
11631
+ }
11632
+ function stripMarkdownInline(text) {
11633
+ return text.replace(/#{1,6}\s+/g, "").replace(/\*\*(.+?)\*\*/g, "$1").replace(/__(.+?)__/g, "$1").replace(/\*(.+?)\*/g, "$1").replace(/`(.+?)`/g, "$1").replace(/~~(.+?)~~/g, "$1");
11634
+ }
11635
+ function firstSentence(text) {
11636
+ const nlIdx = text.indexOf("\n");
11637
+ const sentIdx = text.indexOf(". ");
11638
+ const nlEnd = nlIdx === -1 ? Infinity : nlIdx;
11639
+ const sentEnd = sentIdx === -1 ? Infinity : sentIdx + 1;
11640
+ const end = Math.min(nlEnd, sentEnd, text.length);
11641
+ return text.slice(0, end).trim();
11642
+ }
11643
+ function resolveDisplayName(toolName) {
11644
+ const parsed = parseToolName(toolName);
11645
+ if (parsed.isMcp && parsed.mcpServer && parsed.mcpAction) {
11646
+ const friendlyServer = extractFriendlyServerName(parsed.mcpServer);
11647
+ return `[${friendlyServer}] ${parsed.mcpAction}`;
11648
+ }
11649
+ return toolName;
11650
+ }
11651
+ var PATH_TOOLS = /* @__PURE__ */ new Set(["Read", "Write", "Edit", "Glob", "Grep"]);
11652
+ function withMcpServerContext(parsed, primaryInput) {
11653
+ if (!parsed.isMcp || !parsed.mcpServer) return primaryInput;
11654
+ const server = extractFriendlyServerName(parsed.mcpServer);
11655
+ if (!server) return primaryInput;
11656
+ return primaryInput ? `[${server}] ${primaryInput}` : `[${server}]`;
11657
+ }
11658
+ function formatToolSummary(toolName, toolInput, errorSuffix) {
11659
+ const parsed = parseToolName(toolName);
11660
+ const verb = resolveVerb(toolName, parsed);
11661
+ const primaryInput = withMcpServerContext(
11662
+ parsed,
11663
+ summarizeToolPrimaryInput(toolName, toolInput)
11664
+ );
11665
+ const secondary = [primaryInput, errorSuffix].filter(Boolean).join(" ");
11666
+ if (!secondary) {
11667
+ const text2 = compactText(verb, 200);
11668
+ return { text: text2, segments: [{ text: text2, role: "verb" }] };
11669
+ }
11670
+ const full = `${verb} ${secondary}`;
11671
+ const text = compactText(full, 200);
11672
+ const rest = text.slice(verb.length);
11673
+ const baseName = toolName;
11674
+ const filePath = toolInput.file_path ?? toolInput.pattern ?? toolInput.path;
11675
+ if (PATH_TOOLS.has(baseName) && typeof filePath === "string") {
11676
+ const { prefix, filename } = shortenPathStructured(filePath);
11677
+ if (prefix && filename) {
11678
+ const idx = rest.indexOf(prefix);
11679
+ if (idx >= 0) {
11680
+ const beforeFilename = rest.slice(0, idx + prefix.length);
11681
+ const afterFilename = rest.slice(idx + prefix.length + filename.length);
11682
+ return {
11683
+ text,
11684
+ segments: [
11685
+ { text: verb, role: "verb" },
11686
+ { text: beforeFilename, role: "target" },
11687
+ { text: filename, role: "filename" },
11688
+ ...afterFilename ? [{ text: afterFilename, role: "target" }] : []
11689
+ ]
11690
+ };
11691
+ }
11692
+ }
11693
+ }
11694
+ return {
11695
+ text,
11696
+ segments: [
11697
+ { text: verb, role: "verb" },
11698
+ { text: rest, role: "target" }
11699
+ ]
11700
+ };
11701
+ }
11702
+ function formatPermissionSummary(event) {
11703
+ const base = formatToolSummary(event.data.tool_name, event.data.tool_input);
11704
+ const host = event.data.network_context?.host;
11705
+ if (!host) {
11706
+ return base;
11707
+ }
11708
+ const protocol = event.data.network_context?.protocol;
11709
+ const suffix = ` \u2192 ${protocol ? `${protocol} ` : ""}${host}`;
11710
+ const text = compactText(`${base.text}${suffix}`, 200);
11711
+ return {
11712
+ text,
11713
+ segments: [...base.segments, { text: suffix, role: "target" }]
11714
+ };
11715
+ }
11716
+ function formatRunEndSummary(event) {
11717
+ const toolText = `${event.data.counters.tool_uses} tool${event.data.counters.tool_uses === 1 ? "" : "s"}`;
11718
+ const failureCount = event.data.counters.tool_failures;
11719
+ if (failureCount > 0) {
11720
+ return `${event.data.status} \xB7 ${toolText}, ${failureCount} failure${failureCount === 1 ? "" : "s"}`;
11721
+ }
11722
+ return `${event.data.status} \xB7 ${toolText}`;
11723
+ }
11724
+ function harnessSummary(event) {
11725
+ const title = event.display?.title?.trim();
11726
+ if (!title) return void 0;
11727
+ const text = compactText(title, 200);
11728
+ return { text, segments: [{ text, role: "target" }] };
11729
+ }
11730
+ function postOutcome(postEvent) {
11731
+ if (postEvent.kind === "tool.failure") {
11732
+ return summarizeToolResult(
11733
+ postEvent.data.tool_name,
11734
+ postEvent.data.tool_input,
11735
+ void 0,
11736
+ postEvent.data.error
11737
+ );
11738
+ }
11739
+ if (postEvent.kind === "tool.post") {
11740
+ return summarizeToolResult(
11741
+ postEvent.data.tool_name,
11742
+ postEvent.data.tool_input,
11743
+ postEvent.data.tool_response
11744
+ );
11745
+ }
11746
+ return void 0;
11747
+ }
11748
+ function plainSummary(text) {
11749
+ const compact = compactText(text, 200);
11750
+ return { text: compact, segments: [{ text: compact, role: "target" }] };
11751
+ }
11752
+ function dataExpansion(event) {
11753
+ return JSON.stringify(event.data, null, 2);
11754
+ }
11755
+ function rawOrDataExpansion(event) {
11756
+ return JSON.stringify(event.raw ?? event.data, null, 2);
11757
+ }
11758
+ function defaultRenderer(summarize) {
11759
+ return {
11760
+ operation: () => "event",
11761
+ label: () => "Event",
11762
+ detail: () => "\u2500",
11763
+ summary: (event) => plainSummary(summarize(event)),
11764
+ expansion: rawOrDataExpansion
11765
+ };
11766
+ }
11767
+ var sessionStart = {
11768
+ operation: () => "sess.start",
11769
+ label: () => "Sess Start",
11770
+ detail: (event) => event.data.source,
11771
+ summary: (event) => plainSummary(event.data.source),
11772
+ expansion: rawOrDataExpansion
11773
+ };
11774
+ var sessionEnd = {
11775
+ operation: () => "sess.end",
11776
+ label: () => "Sess End",
11777
+ detail: () => "\u2500",
11778
+ summary: (event) => plainSummary(event.data.reason),
11779
+ expansion: rawOrDataExpansion
11780
+ };
11781
+ var runStart = {
11782
+ operation: () => "run.start",
11783
+ label: () => "Run Start",
11784
+ detail: () => "\u2500",
11785
+ summary: (event) => plainSummary(event.data.trigger.prompt_preview || "interactive"),
11786
+ expansion: rawOrDataExpansion
11787
+ };
11788
+ var runEnd = {
11789
+ operation: (event) => {
11790
+ if (event.data.status === "completed") return "run.ok";
11791
+ if (event.data.status === "failed") return "run.fail";
11792
+ return "run.abort";
11793
+ },
11794
+ label: (event) => {
11795
+ if (event.data.status === "completed") return "Run OK";
11796
+ if (event.data.status === "failed") return "Run Fail";
11797
+ return "Run Abort";
11798
+ },
11799
+ detail: () => "\u2500",
11800
+ summary: (event) => plainSummary(formatRunEndSummary(event)),
11801
+ expansion: dataExpansion,
11802
+ isError: (event) => event.data.status !== "completed"
11803
+ };
11804
+ var userPrompt = {
11805
+ operation: () => "prompt",
11806
+ label: () => "User Prompt",
11807
+ detail: () => "\u2500",
11808
+ summary: (event) => plainSummary(event.data.prompt),
11809
+ expansion: rawOrDataExpansion
11810
+ };
11811
+ var planUpdate = {
11812
+ operation: () => "plan.upd",
11813
+ label: () => "Plan Update",
11814
+ detail: () => "plan",
11815
+ summary: (event) => {
11816
+ if (event.data.explanation) return plainSummary(event.data.explanation);
11817
+ if (event.data.plan && event.data.plan.length > 0) {
11818
+ const completed = event.data.plan.filter(
11819
+ (step) => step.status === "completed"
11820
+ ).length;
11821
+ return plainSummary(`${completed}/${event.data.plan.length} steps`);
11822
+ }
11823
+ return plainSummary(event.data.delta || "plan updated");
11824
+ },
11825
+ expansion: dataExpansion
11826
+ };
11827
+ var reasoningSummary = {
11828
+ operation: () => "reason",
11829
+ label: () => "Reasoning",
11830
+ detail: () => "summary",
11831
+ summary: (event) => plainSummary(firstSentence(stripMarkdownInline(event.data.message))),
11832
+ expansion: dataExpansion
11833
+ };
11834
+ var usageUpdate = {
11835
+ operation: () => "usage.upd",
11836
+ label: () => "Usage Update",
11837
+ detail: () => "tokens",
11838
+ summary: (event) => {
11839
+ const total = event.data.usage?.total;
11840
+ const delta = event.data.delta?.total;
11841
+ if (typeof total === "number" && typeof delta === "number") {
11842
+ return plainSummary(
11843
+ `${total.toLocaleString()} total (+${delta.toLocaleString()})`
11844
+ );
11845
+ }
11846
+ if (typeof total === "number") {
11847
+ return plainSummary(`${total.toLocaleString()} total`);
11848
+ }
11849
+ return plainSummary("usage updated");
11850
+ },
11851
+ expansion: dataExpansion
11852
+ };
11853
+ var toolDelta = {
11854
+ operation: () => "tool.call",
11855
+ label: () => "Tool Call",
11856
+ detail: (event) => resolveDisplayName(event.data.tool_name),
11857
+ summary: (event) => formatToolSummary(event.data.tool_name, event.data.tool_input),
11858
+ expansion: (event) => JSON.stringify(
11859
+ { tool: event.data.tool_name, args: event.data.tool_input },
11860
+ null,
11861
+ 2
11862
+ )
11863
+ };
11864
+ var toolPre = {
11865
+ operation: () => "tool.call",
11866
+ label: () => "Tool Call",
11867
+ detail: (event) => resolveDisplayName(event.data.tool_name),
11868
+ summary: (event) => formatToolSummary(event.data.tool_name, event.data.tool_input),
11869
+ expansion: (event) => JSON.stringify(
11870
+ { tool: event.data.tool_name, args: event.data.tool_input },
11871
+ null,
11872
+ 2
11873
+ )
11874
+ };
11875
+ var toolPost = {
11876
+ operation: () => "tool.ok",
11877
+ label: () => "Tool OK",
11878
+ detail: (event) => resolveDisplayName(event.data.tool_name),
11879
+ summary: (event) => formatToolSummary(event.data.tool_name, event.data.tool_input),
11880
+ expansion: (event) => JSON.stringify(
11881
+ {
11882
+ tool: event.data.tool_name,
11883
+ args: event.data.tool_input,
11884
+ result: event.data.tool_response
11885
+ },
11886
+ null,
11887
+ 2
11888
+ )
11889
+ };
11890
+ var toolFailure = {
11891
+ operation: () => "tool.fail",
11892
+ label: () => "Tool Fail",
11893
+ detail: (event) => resolveDisplayName(event.data.tool_name),
11894
+ summary: (event) => formatToolSummary(
11895
+ event.data.tool_name,
11896
+ event.data.tool_input,
11897
+ event.data.error
11898
+ ),
11899
+ expansion: (event) => JSON.stringify(
11900
+ {
11901
+ tool: event.data.tool_name,
11902
+ args: event.data.tool_input,
11903
+ error: event.data.error,
11904
+ interrupt: event.data.is_interrupt
11905
+ },
11906
+ null,
11907
+ 2
11908
+ ),
11909
+ isError: () => true
11910
+ };
11911
+ var permissionRequest = {
11912
+ operation: () => "perm.req",
11913
+ label: () => "Perm Request",
11914
+ detail: (event) => resolveDisplayName(event.data.tool_name),
11915
+ summary: (event) => formatPermissionSummary(event),
11916
+ expansion: (event) => JSON.stringify(
11917
+ {
11918
+ tool: event.data.tool_name,
11919
+ args: event.data.tool_input,
11920
+ suggestions: event.data.permission_suggestions
11921
+ },
11922
+ null,
11923
+ 2
11924
+ )
11925
+ };
11926
+ var permissionDecision = {
11927
+ operation: (event) => `perm.${event.data.decision_type}`,
11928
+ label: (event) => {
11929
+ switch (event.data.decision_type) {
11930
+ case "allow":
11931
+ return "Perm Allow";
11932
+ case "deny":
11933
+ return "Perm Deny";
11934
+ case "ask":
11935
+ return "Perm Ask";
11936
+ case "no_opinion":
11937
+ return "Perm Skip";
11938
+ default:
11939
+ return "Perm Decision";
11940
+ }
11941
+ },
11942
+ detail: () => "\u2500",
11943
+ summary: (event) => {
11944
+ const detail = event.data.decision_type === "deny" ? event.data.message || event.data.reason : event.data.reason;
11945
+ return plainSummary(detail || event.data.decision_type);
11946
+ },
11947
+ expansion: rawOrDataExpansion,
11948
+ isError: (event) => event.data.decision_type === "deny"
11949
+ };
11950
+ var stopRequest = {
11951
+ operation: () => "stop.req",
11952
+ label: () => "Stop Request",
11953
+ detail: () => "\u2500",
11954
+ summary: (event) => plainSummary(
11955
+ event.data.stop_hook_active ? "Stop hook active" : "Stop hook inactive"
11956
+ ),
11957
+ expansion: rawOrDataExpansion
11958
+ };
11959
+ var stopDecision = {
11960
+ operation: (event) => `stop.${event.data.decision_type}`,
11961
+ label: (event) => {
11962
+ switch (event.data.decision_type) {
11963
+ case "block":
11964
+ return "Stop Block";
11965
+ case "allow":
11966
+ return "Stop Allow";
11967
+ case "no_opinion":
11968
+ return "Stop Skip";
11969
+ default:
11970
+ return "Stop Decision";
11971
+ }
11972
+ },
11973
+ detail: () => "\u2500",
11974
+ summary: (event) => plainSummary(event.data.reason || event.data.decision_type),
11975
+ expansion: rawOrDataExpansion,
11976
+ isError: (event) => event.data.decision_type === "block"
11977
+ };
11978
+ var subagentStart = {
11979
+ operation: () => "sub.start",
11980
+ label: () => "Sub Start",
11981
+ detail: (event) => event.data.agent_type,
11982
+ summary: (event) => {
11983
+ const text = compactText(
11984
+ event.data.description?.trim() || `id:${event.data.agent_id}`,
11985
+ 200
11986
+ );
11987
+ return { text, segments: [{ text, role: "target" }] };
11988
+ },
11989
+ expansion: rawOrDataExpansion
11990
+ };
11991
+ var subagentStop = {
11992
+ operation: () => "sub.stop",
11993
+ label: () => "Sub Stop",
11994
+ detail: (event) => event.data.agent_type,
11995
+ summary: (event) => {
11996
+ const text = compactText(
11997
+ event.data.description?.trim() || `id:${event.data.agent_id}`,
11998
+ 200
11999
+ );
12000
+ return { text, segments: [{ text, role: "target" }] };
12001
+ },
12002
+ expansion: dataExpansion
12003
+ };
12004
+ var notification = {
12005
+ operation: () => "notify",
12006
+ label: () => "Notify",
12007
+ detail: () => "\u2500",
12008
+ summary: (event) => plainSummary(stripMarkdownInline(event.data.message)),
12009
+ expansion: rawOrDataExpansion
12010
+ };
12011
+ var runtimeError = {
12012
+ operation: () => "error",
12013
+ label: () => "Error",
12014
+ detail: () => "\u2500",
12015
+ summary: (event) => plainSummary(stripMarkdownInline(event.data.message)),
12016
+ expansion: dataExpansion,
12017
+ isError: () => true
12018
+ };
12019
+ var threadStatus = {
12020
+ operation: () => "thread",
12021
+ label: () => "Thread",
12022
+ detail: (event) => event.data.status_type ?? "status",
12023
+ summary: (event) => plainSummary(event.data.message),
12024
+ expansion: dataExpansion
12025
+ };
12026
+ var turnDiff = {
12027
+ operation: () => "diff",
12028
+ label: () => "Diff",
12029
+ detail: () => "\u2500",
12030
+ summary: (event) => plainSummary(event.data.message),
12031
+ expansion: dataExpansion
12032
+ };
12033
+ var serverRequestResolved = {
12034
+ operation: () => "req.done",
12035
+ label: () => "Request",
12036
+ detail: (event) => event.data.request_id ?? "request",
12037
+ summary: (event) => plainSummary(event.data.message),
12038
+ expansion: dataExpansion
12039
+ };
12040
+ var webSearch = {
12041
+ operation: () => "web.search",
12042
+ label: () => "Web Search",
12043
+ detail: (event) => event.data.action_type ?? event.data.phase,
12044
+ summary: (event) => plainSummary(event.data.message),
12045
+ expansion: dataExpansion
12046
+ };
12047
+ var reviewStatus = {
12048
+ operation: () => "review",
12049
+ label: () => "Review",
12050
+ detail: (event) => event.data.phase,
12051
+ summary: (event) => plainSummary(event.data.message),
12052
+ expansion: dataExpansion
12053
+ };
12054
+ var imageView = {
12055
+ operation: () => "image",
12056
+ label: () => "Image",
12057
+ detail: (event) => event.data.path ?? "image",
12058
+ summary: (event) => plainSummary(event.data.message),
12059
+ expansion: dataExpansion
12060
+ };
12061
+ var contextCompaction = {
12062
+ operation: () => "compact",
12063
+ label: () => "Compaction",
12064
+ detail: (event) => event.data.phase,
12065
+ summary: (event) => plainSummary(event.data.message),
12066
+ expansion: dataExpansion
12067
+ };
12068
+ var mcpProgress = {
12069
+ operation: () => "mcp.prog",
12070
+ label: () => "MCP Progress",
12071
+ detail: () => "\u2500",
12072
+ summary: (event) => plainSummary(event.data.message),
12073
+ expansion: dataExpansion
12074
+ };
12075
+ var terminalInput = {
12076
+ operation: () => "term.in",
12077
+ label: () => "Terminal In",
12078
+ detail: () => "\u2500",
12079
+ summary: (event) => plainSummary(event.data.message),
12080
+ expansion: dataExpansion
12081
+ };
12082
+ var skillsChanged = {
12083
+ operation: () => "skills",
12084
+ label: () => "Skills",
12085
+ detail: () => "\u2500",
12086
+ summary: (event) => plainSummary(event.data.message),
12087
+ expansion: dataExpansion
12088
+ };
12089
+ var skillsLoaded = {
12090
+ operation: () => "skills",
12091
+ label: () => "Skills",
12092
+ detail: () => "\u2500",
12093
+ summary: (event) => plainSummary(event.data.message),
12094
+ expansion: dataExpansion
12095
+ };
12096
+ var compactPre = {
12097
+ operation: () => "compact",
12098
+ label: () => "Compact",
12099
+ detail: () => "\u2500",
12100
+ summary: (event) => plainSummary(event.data.trigger),
12101
+ expansion: dataExpansion
12102
+ };
12103
+ var setup = {
12104
+ operation: () => "setup",
12105
+ label: () => "Setup",
12106
+ detail: () => "\u2500",
12107
+ summary: (event) => plainSummary(event.data.trigger),
12108
+ expansion: rawOrDataExpansion
12109
+ };
12110
+ var unknownHook = {
12111
+ operation: () => "unknown",
12112
+ label: () => "Unknown",
12113
+ detail: () => "\u2500",
12114
+ summary: (event) => plainSummary(event.data.hook_event_name),
12115
+ expansion: rawOrDataExpansion
12116
+ };
12117
+ var todoAdd = {
12118
+ operation: () => "todo.add",
12119
+ label: () => "Todo Add",
12120
+ detail: (event) => (event.data.priority ?? "p1").toUpperCase(),
12121
+ summary: (event) => plainSummary(
12122
+ `${event.data.priority?.toUpperCase() ?? "P1"} ${event.data.text}`
12123
+ ),
12124
+ expansion: rawOrDataExpansion
12125
+ };
12126
+ var todoUpdate = {
12127
+ operation: () => "todo.upd",
12128
+ label: () => "Todo Update",
12129
+ detail: (event) => event.data.todo_id,
12130
+ summary: (event) => {
12131
+ const patchFields = Object.keys(event.data.patch);
12132
+ return plainSummary(
12133
+ `${event.data.todo_id} ${patchFields.length > 0 ? patchFields.join(",") : "update"}`
12134
+ );
12135
+ },
12136
+ expansion: rawOrDataExpansion
12137
+ };
12138
+ var todoDone = {
12139
+ operation: () => "todo.done",
12140
+ label: () => "Todo Done",
12141
+ detail: (event) => event.data.todo_id,
12142
+ summary: (event) => plainSummary(`${event.data.todo_id} ${event.data.reason || "done"}`),
12143
+ expansion: rawOrDataExpansion
12144
+ };
12145
+ var agentMessage = {
12146
+ operation: () => "agent.msg",
12147
+ label: () => "Agent Msg",
12148
+ detail: () => "\u2500",
12149
+ summary: (event) => {
12150
+ const text = compactText(
12151
+ firstSentence(stripMarkdownInline(event.data.message)),
12152
+ 200
12153
+ );
12154
+ return { text, segments: [{ text, role: "plain" }] };
12155
+ },
12156
+ expansion: rawOrDataExpansion
12157
+ };
12158
+ var teammateIdle = {
12159
+ operation: () => "tm.idle",
12160
+ label: () => "Team Idle",
12161
+ detail: () => "\u2500",
12162
+ summary: (event) => plainSummary(`${event.data.teammate_name} idle in ${event.data.team_name}`),
12163
+ expansion: rawOrDataExpansion
12164
+ };
12165
+ var taskCompleted = {
12166
+ operation: () => "task.ok",
12167
+ label: () => "Task OK",
12168
+ detail: () => "\u2500",
12169
+ summary: (event) => plainSummary(event.data.task_subject),
12170
+ expansion: rawOrDataExpansion
12171
+ };
12172
+ var configChange = {
12173
+ operation: () => "cfg.chg",
12174
+ label: () => "Config Chg",
12175
+ detail: (event) => event.data.source,
12176
+ summary: (event) => plainSummary(
12177
+ `${event.data.source}${event.data.file_path ? ` ${event.data.file_path}` : ""}`
12178
+ ),
12179
+ expansion: rawOrDataExpansion
12180
+ };
12181
+ var compactPost = defaultRenderer(
12182
+ (event) => `compacted (${event.data.trigger})`
12183
+ );
12184
+ var taskCreated = defaultRenderer(
12185
+ (event) => event.data.task_subject
12186
+ );
12187
+ var cwdChanged = defaultRenderer(
12188
+ (event) => `cwd \u2192 ${event.data.cwd}`
12189
+ );
12190
+ var fileChanged = defaultRenderer(
12191
+ (event) => `changed ${event.data.file_path}`
12192
+ );
12193
+ var instructionsLoaded = defaultRenderer(
12194
+ (event) => `${event.data.memory_type ?? "instructions"} ${event.data.file_path}`
12195
+ );
12196
+ var worktreeCreate = defaultRenderer(
12197
+ (event) => `created ${event.data.worktree_path}`
12198
+ );
12199
+ var worktreeRemove = defaultRenderer(
12200
+ (event) => `removed ${event.data.worktree_path}`
12201
+ );
12202
+ var stopFailure = defaultRenderer(
12203
+ (event) => `${event.data.error_type}${event.data.error_message ? `: ${event.data.error_message}` : ""}`
12204
+ );
12205
+ var permissionDenied = defaultRenderer(
12206
+ (event) => `${event.data.tool_name}${event.data.reason ? `: ${event.data.reason}` : ""}`
12207
+ );
12208
+ var elicitationRequest = defaultRenderer((event) => `elicitation from ${event.data.mcp_server}`);
12209
+ var elicitationResult = defaultRenderer(
12210
+ (event) => `${event.data.mcp_server} \u2192 ${event.data.action}`
12211
+ );
12212
+ var channelPermissionRelayed = defaultRenderer(
12213
+ (event) => `${event.data.channel_name}: ${event.data.tool_name} (${event.data.channel_request_id})`
12214
+ );
12215
+ var channelPermissionResolved = defaultRenderer(
12216
+ (event) => `${event.data.channel_name} ${event.data.source} ${event.data.tool_name}`
12217
+ );
12218
+ var channelQuestionRelayed = defaultRenderer(
12219
+ (event) => `${event.data.channel_name}: ${event.data.title} (${event.data.channel_request_id})`
12220
+ );
12221
+ var channelQuestionResolved = defaultRenderer(
12222
+ (event) => `${event.data.channel_name || event.data.source} ${event.data.source} ${event.data.title}`
12223
+ );
12224
+ var channelChatInbound = defaultRenderer((event) => `${event.data.channel_name}: ${event.data.content}`);
12225
+ var channelChatOutbound = defaultRenderer(
12226
+ (event) => `${event.data.channel_name} \u2192 ${event.data.target_peer_id}: ${event.data.content}`
12227
+ );
12228
+ var gatewayFunctionInvoked = defaultRenderer(
12229
+ (event) => `fn invoked: ${event.data.function_name} (${event.data.caller_kind})`
12230
+ );
12231
+ var gatewayFunctionCompleted = defaultRenderer(
12232
+ (event) => `fn ok: ${event.data.function_name} ${event.data.duration_ms}ms`
12233
+ );
12234
+ var gatewayFunctionFailed = defaultRenderer(
12235
+ (event) => `fn ${event.data.reason}: ${event.data.function_name} \u2014 ${event.data.error_message}`
12236
+ );
12237
+ var artifactsManifest = defaultRenderer(
12238
+ (event) => {
12239
+ const manifest = event.data.manifest;
12240
+ const count = Array.isArray(manifest.entries) ? manifest.entries.length : 0;
12241
+ return `artifacts manifest (${count} item${count === 1 ? "" : "s"})`;
12242
+ }
12243
+ );
12244
+ var RENDERERS = {
12245
+ "session.start": sessionStart,
12246
+ "session.end": sessionEnd,
12247
+ "run.start": runStart,
12248
+ "run.end": runEnd,
12249
+ "user.prompt": userPrompt,
12250
+ "plan.update": planUpdate,
12251
+ "reasoning.summary": reasoningSummary,
12252
+ "usage.update": usageUpdate,
12253
+ "tool.delta": toolDelta,
12254
+ "tool.pre": toolPre,
12255
+ "tool.post": toolPost,
12256
+ "tool.failure": toolFailure,
12257
+ "permission.request": permissionRequest,
12258
+ "permission.decision": permissionDecision,
12259
+ "stop.request": stopRequest,
12260
+ "stop.decision": stopDecision,
12261
+ "subagent.start": subagentStart,
12262
+ "subagent.stop": subagentStop,
12263
+ notification,
12264
+ "runtime.error": runtimeError,
12265
+ "thread.status": threadStatus,
12266
+ "turn.diff": turnDiff,
12267
+ "server.request.resolved": serverRequestResolved,
12268
+ "web.search": webSearch,
12269
+ "review.status": reviewStatus,
12270
+ "image.view": imageView,
12271
+ "context.compaction": contextCompaction,
12272
+ "mcp.progress": mcpProgress,
12273
+ "terminal.input": terminalInput,
12274
+ "skills.changed": skillsChanged,
12275
+ "skills.loaded": skillsLoaded,
12276
+ "compact.pre": compactPre,
12277
+ "compact.post": compactPost,
12278
+ setup,
12279
+ "unknown.hook": unknownHook,
12280
+ "todo.add": todoAdd,
12281
+ "todo.update": todoUpdate,
12282
+ "todo.done": todoDone,
12283
+ "agent.message": agentMessage,
12284
+ "teammate.idle": teammateIdle,
12285
+ "task.created": taskCreated,
12286
+ "task.completed": taskCompleted,
12287
+ "config.change": configChange,
12288
+ "cwd.changed": cwdChanged,
12289
+ "file.changed": fileChanged,
12290
+ "instructions.loaded": instructionsLoaded,
12291
+ "worktree.create": worktreeCreate,
12292
+ "worktree.remove": worktreeRemove,
12293
+ "stop.failure": stopFailure,
12294
+ "permission.denied": permissionDenied,
12295
+ "elicitation.request": elicitationRequest,
12296
+ "elicitation.result": elicitationResult,
12297
+ "channel.permission.relayed": channelPermissionRelayed,
12298
+ "channel.permission.resolved": channelPermissionResolved,
12299
+ "channel.question.relayed": channelQuestionRelayed,
12300
+ "channel.question.resolved": channelQuestionResolved,
12301
+ "channel.chat.inbound": channelChatInbound,
12302
+ "channel.chat.outbound": channelChatOutbound,
12303
+ "gateway.function.invoked": gatewayFunctionInvoked,
12304
+ "gateway.function.completed": gatewayFunctionCompleted,
12305
+ "gateway.function.failed": gatewayFunctionFailed,
12306
+ "artifacts.manifest": artifactsManifest
12307
+ };
12308
+ function rendererFor(event) {
12309
+ return RENDERERS[event.kind];
12310
+ }
12311
+ function eventOperation(event) {
12312
+ return rendererFor(event).operation(event);
12313
+ }
12314
+ function eventLabel(event) {
12315
+ return rendererFor(event).label(event);
12316
+ }
12317
+ function eventSummary(event) {
12318
+ const harness = harnessSummary(event);
12319
+ if (harness) return harness;
12320
+ return rendererFor(event).summary(event);
12321
+ }
12322
+ function expansionForEvent(event) {
12323
+ return rendererFor(event).expansion(event);
12324
+ }
12325
+ function isEventError(event) {
12326
+ if (event.level === "error") return true;
12327
+ const renderer = rendererFor(event);
12328
+ return renderer.isError?.(event) ?? false;
12329
+ }
12330
+ function isEventExpandable(event) {
12331
+ void event;
12332
+ return true;
12333
+ }
12334
+ var toolPairOk = {
12335
+ operation: () => "tool.ok",
12336
+ label: () => "Tool OK",
12337
+ summary: (pre, post) => buildMergedToolSummary(pre, post)
12338
+ };
12339
+ var toolPairFail = {
12340
+ operation: () => "tool.fail",
12341
+ label: () => "Tool Fail",
12342
+ summary: (pre, post) => buildMergedToolSummary(pre, post)
12343
+ };
12344
+ var TOOL_PAIRS = {
12345
+ "tool.post": toolPairOk,
12346
+ "tool.failure": toolPairFail
12347
+ };
12348
+ function buildMergedToolSummary(event, postEvent) {
12349
+ const harness = harnessSummary(event) ?? harnessSummary(postEvent);
12350
+ if (harness) {
12351
+ return {
12352
+ ...harness,
12353
+ outcome: postOutcome(postEvent),
12354
+ outcomeZero: false
12355
+ };
12356
+ }
12357
+ const toolName = event.data.tool_name;
12358
+ const preInput = event.data.tool_input;
12359
+ const postInput = postEvent.kind === "tool.post" || postEvent.kind === "tool.failure" ? postEvent.data.tool_input : void 0;
12360
+ const toolInput = postInput && Object.keys(preInput).every((k) => preInput[k] == null) ? postInput : preInput;
12361
+ const parsed = parseToolName(toolName);
12362
+ const name = resolveVerb(toolName, parsed);
12363
+ const primaryInput = withMcpServerContext(
12364
+ parsed,
12365
+ summarizeToolPrimaryInput(toolName, toolInput)
12366
+ );
12367
+ let resultText;
12368
+ if (postEvent.kind === "tool.failure") {
12369
+ resultText = summarizeToolResult(
12370
+ toolName,
12371
+ toolInput,
12372
+ void 0,
12373
+ postEvent.data.error
12374
+ );
12375
+ } else if (postEvent.kind === "tool.post") {
12376
+ resultText = summarizeToolResult(
12377
+ toolName,
12378
+ toolInput,
12379
+ postEvent.data.tool_response
12380
+ );
12381
+ } else {
12382
+ return eventSummary(event);
12383
+ }
12384
+ const prefix = primaryInput ? `${name} ${primaryInput}` : name;
12385
+ const prefixText = compactText(prefix, 200);
12386
+ const segments = primaryInput ? [
12387
+ { text: name, role: "verb" },
12388
+ { text: prefixText.slice(name.length), role: "target" }
12389
+ ] : [{ text: prefixText, role: "verb" }];
12390
+ if (!resultText) {
12391
+ return { text: prefixText, segments };
12392
+ }
12393
+ return {
12394
+ text: prefixText,
12395
+ segments,
12396
+ outcome: resultText,
12397
+ outcomeZero: /^0\s/.test(resultText)
12398
+ };
12399
+ }
12400
+ function mergedEventOperation(event, postEvent) {
12401
+ if (!postEvent) return eventOperation(event);
12402
+ const pair = TOOL_PAIRS[postEvent.kind];
12403
+ if (!pair) return eventOperation(event);
12404
+ return pair.operation(event, postEvent);
12405
+ }
12406
+ function mergedEventLabel(event, postEvent) {
12407
+ if (!postEvent) return eventLabel(event);
12408
+ const pair = TOOL_PAIRS[postEvent.kind];
12409
+ if (!pair) return eventLabel(event);
12410
+ return pair.label(event, postEvent);
12411
+ }
12412
+ function mergedEventSummary(event, postEvent) {
12413
+ if (!postEvent) return eventSummary(event);
12414
+ if (event.kind !== "tool.pre" && event.kind !== "permission.request") {
12415
+ return eventSummary(event);
12416
+ }
12417
+ const pair = TOOL_PAIRS[postEvent.kind];
12418
+ if (!pair) return eventSummary(event);
12419
+ return pair.summary(event, postEvent);
12420
+ }
12421
+ var VERBOSE_ONLY_KINDS = /* @__PURE__ */ new Set([
12422
+ "session.start",
12423
+ "session.end",
12424
+ "run.start",
12425
+ "run.end",
12426
+ "unknown.hook",
12427
+ "compact.pre",
12428
+ "config.change",
12429
+ "instructions.loaded",
12430
+ "worktree.create",
12431
+ "worktree.remove",
12432
+ "turn.diff",
12433
+ "usage.update",
12434
+ "reasoning.summary"
12435
+ ]);
12436
+ function toRunStatus(event) {
12437
+ switch (event.data.status) {
12438
+ case "completed":
12439
+ return "SUCCEEDED";
12440
+ case "failed":
12441
+ return "FAILED";
12442
+ case "aborted":
12443
+ return "CANCELLED";
12444
+ }
12445
+ }
12446
+
12447
+ // src/core/feed/toolDisplay.ts
12448
+ function prop2(obj, key) {
12449
+ if (typeof obj === "object" && obj !== null) {
12450
+ return obj[key];
12451
+ }
12452
+ return void 0;
12453
+ }
12454
+ function truncate2(text, max) {
12455
+ if (text.length <= max) return text;
12456
+ if (max <= 3) return text.slice(0, max);
12457
+ return text.slice(0, max - 1) + "\u2026";
12458
+ }
12459
+ function extractDomain(url) {
12460
+ if (typeof url !== "string") return "";
12461
+ try {
12462
+ const u = new URL(url);
12463
+ return u.hostname.replace(/^www\./, "");
12464
+ } catch {
12465
+ return compactText(String(url), 40);
12466
+ }
12467
+ }
12468
+ function filePathSegments(input) {
12469
+ const path22 = prop2(input, "file_path") ?? prop2(input, "notebook_path") ?? "";
12470
+ if (typeof path22 !== "string" || !path22) return [];
12471
+ const { prefix, filename } = shortenPathStructured(path22);
12472
+ if (prefix && filename) {
12473
+ return [
12474
+ { text: prefix, role: "target" },
12475
+ { text: filename, role: "filename" }
12476
+ ];
12477
+ }
12478
+ return [{ text: filename || path22, role: "filename" }];
12479
+ }
12480
+ function grepSegments(input) {
12481
+ const pattern = String(prop2(input, "pattern") ?? "");
12482
+ const glob = prop2(input, "glob");
12483
+ const parts = `"${pattern}"${glob ? ` ${String(glob)}` : ""}`;
12484
+ return [{ text: parts, role: "target" }];
12485
+ }
12486
+ function commandSegments(input) {
12487
+ const cmd = String(prop2(input, "command") ?? "");
12488
+ return [{ text: compactText(compactCommandPaths(cmd), 50), role: "target" }];
12489
+ }
12490
+ function countOutcome(output, label) {
12491
+ if (Array.isArray(output)) {
12492
+ return { text: `${output.length} ${label}`, zero: output.length === 0 };
12493
+ }
12494
+ if (typeof output === "object" && output !== null) {
12495
+ const filenames = prop2(output, "filenames");
12496
+ if (Array.isArray(filenames)) {
12497
+ return {
12498
+ text: `${filenames.length} ${label}`,
12499
+ zero: filenames.length === 0
12500
+ };
12501
+ }
12502
+ const numFiles = prop2(output, "numFiles");
12503
+ if (typeof numFiles === "number") {
12504
+ return { text: `${numFiles} ${label}`, zero: numFiles === 0 };
12505
+ }
12506
+ const numMatches = prop2(output, "numMatches");
12507
+ if (typeof numMatches === "number") {
12508
+ return { text: `${numMatches} ${label}`, zero: numMatches === 0 };
12509
+ }
12510
+ const count = prop2(output, "count");
12511
+ if (typeof count === "number") {
12512
+ return { text: `${count} ${label}`, zero: count === 0 };
12513
+ }
12514
+ }
12515
+ if (typeof output === "string") {
12516
+ const lines = output.split("\n").filter(Boolean).length;
12517
+ return { text: `${lines} ${label}`, zero: lines === 0 };
12518
+ }
12519
+ return void 0;
12520
+ }
12521
+ function exitCodeOutcome(output) {
12522
+ if (isBashToolResponse(output)) {
12523
+ const code = prop2(output, "exitCode") ?? 0;
12524
+ const stderr = output.stderr.trim();
12525
+ const firstLine = stderr.split("\n")[0] ?? "";
12526
+ if (stderr && Number(code) !== 0) {
12527
+ return { text: `exit ${code} \u2014 ${truncate2(firstLine, 30)}`, zero: false };
12528
+ }
12529
+ return { text: `exit ${code}`, zero: false };
12530
+ }
12531
+ return void 0;
12532
+ }
12533
+ function webSearchOutcome(output) {
12534
+ const results = prop2(output, "results");
12535
+ if (Array.isArray(results)) {
12536
+ let count = 0;
12537
+ for (const entry of results) {
12538
+ const content = prop2(entry, "content");
12539
+ count += Array.isArray(content) ? content.length : 1;
12540
+ }
12541
+ return { text: `${count} results`, zero: count === 0 };
12542
+ }
12543
+ const actionType = prop2(output, "type");
12544
+ if (typeof actionType === "string") {
12545
+ return { text: actionType.replace(/_/g, " "), zero: false };
12546
+ }
12547
+ return void 0;
12548
+ }
12549
+ function taskOutputOutcome(output) {
12550
+ if (typeof output === "string" && output.trim()) {
12551
+ return { text: truncate2(output.trim(), 30), zero: false };
12552
+ }
12553
+ return void 0;
12554
+ }
12555
+ function eidExtractor2(input) {
12556
+ const eid = String(prop2(input, "eid") ?? "");
12557
+ return eid ? [{ text: `eid:${eid.slice(0, 6)}\u2026`, role: "target" }] : [];
12558
+ }
12559
+ function eidOrLabelExtractor(input) {
12560
+ const label = prop2(input, "label");
12561
+ if (typeof label === "string" && label) {
12562
+ return [{ text: `"${truncate2(label, 20)}"`, role: "target" }];
12563
+ }
12564
+ return eidExtractor2(input);
12565
+ }
12566
+ function findDetailsExtractor(input) {
12567
+ const parts = [];
12568
+ const kind = prop2(input, "kind");
12569
+ if (kind) parts.push(String(kind));
12570
+ const label = prop2(input, "label");
12571
+ if (label) parts.push(`"${String(label)}"`);
12572
+ if (parts.length === 0) {
12573
+ const region = prop2(input, "region");
12574
+ if (region) parts.push(String(region));
12575
+ }
12576
+ return parts.length > 0 ? [{ text: parts.join(" "), role: "target" }] : [{ text: "elements", role: "target" }];
12577
+ }
12578
+ function typeDetailsExtractor(input) {
12579
+ const text = String(prop2(input, "text") ?? "");
12580
+ const eid = prop2(input, "eid");
12581
+ const quoted = `"${truncate2(text, 30)}"`;
12582
+ if (eid) {
12583
+ return [{ text: `${quoted} \u2192 ${String(eid).slice(0, 5)}\u2026`, role: "target" }];
12584
+ }
12585
+ return [{ text: quoted, role: "target" }];
12586
+ }
12587
+ function scrollDetailsExtractor(input) {
12588
+ const dir = String(prop2(input, "direction") ?? "");
12589
+ const amount = prop2(input, "amount");
12590
+ const text = amount ? `${dir} ${amount}px` : dir;
12591
+ return text ? [{ text, role: "target" }] : [];
12592
+ }
12593
+ function tabRefExtractor(input) {
12594
+ const pageId = prop2(input, "page_id");
12595
+ return pageId ? [{ text: `page:${String(pageId).slice(0, 6)}`, role: "target" }] : [];
12596
+ }
12597
+ function foundCountOutcome(output) {
12598
+ if (Array.isArray(output)) {
12599
+ return { text: `${output.length} found`, zero: output.length === 0 };
12600
+ }
12601
+ if (typeof output === "object" && output !== null) {
12602
+ const elements = prop2(output, "elements") ?? prop2(output, "items");
12603
+ if (Array.isArray(elements)) {
12604
+ return { text: `${elements.length} found`, zero: elements.length === 0 };
12605
+ }
12606
+ }
12607
+ return void 0;
12608
+ }
12609
+ function tabCountOutcome(output) {
12610
+ if (Array.isArray(output)) {
12611
+ return { text: `${output.length} tabs`, zero: output.length === 0 };
12612
+ }
12613
+ const pages = prop2(output, "pages");
12614
+ if (Array.isArray(pages)) {
12615
+ return { text: `${pages.length} tabs`, zero: pages.length === 0 };
12616
+ }
12617
+ return void 0;
12618
+ }
12619
+ function formCountOutcome(output) {
12620
+ const fields = prop2(output, "fields");
12621
+ if (Array.isArray(fields)) {
12622
+ return { text: `${fields.length} fields`, zero: fields.length === 0 };
12623
+ }
12624
+ return void 0;
12625
+ }
12626
+ function pingOutcome(output) {
12627
+ if (output) return { text: "ok", zero: false };
12628
+ return void 0;
12629
+ }
12630
+ var KNOWN_TOOL_DISPLAY = new Map([
12631
+ // ── Core file tools ──
12632
+ [
12633
+ "Read",
12634
+ {
12635
+ display: "Read",
12636
+ extractDetails: filePathSegments,
12637
+ extractOutcome: () => void 0
12638
+ }
12639
+ ],
12640
+ [
12641
+ "Write",
12642
+ {
12643
+ display: "Write",
12644
+ extractDetails: filePathSegments,
12645
+ extractOutcome: () => void 0
12646
+ }
12647
+ ],
12648
+ [
12649
+ "Edit",
12650
+ {
12651
+ display: "Edit",
12652
+ extractDetails: filePathSegments,
12653
+ extractOutcome: () => void 0
12654
+ }
12655
+ ],
12656
+ [
12657
+ "Glob",
12658
+ {
12659
+ display: "Glob",
12660
+ extractDetails: (input) => [
12661
+ { text: String(prop2(input, "pattern") ?? ""), role: "target" }
12662
+ ],
12663
+ extractOutcome: (output) => countOutcome(output, "files")
12664
+ }
12665
+ ],
12666
+ [
12667
+ "Grep",
12668
+ {
12669
+ display: "Grep",
12670
+ extractDetails: grepSegments,
12671
+ extractOutcome: (output) => countOutcome(output, "matches")
12672
+ }
12673
+ ],
12674
+ [
12675
+ "Bash",
12676
+ {
12677
+ display: "Bash",
12678
+ extractDetails: commandSegments,
12679
+ extractOutcome: exitCodeOutcome
12680
+ }
12681
+ ],
12682
+ // ── Web tools ──
12683
+ [
12684
+ "WebFetch",
12685
+ {
12686
+ display: "WebFetch",
12687
+ extractDetails: (input) => [
12688
+ { text: extractDomain(prop2(input, "url")), role: "target" }
12689
+ ],
12690
+ extractOutcome: () => void 0
12691
+ }
12692
+ ],
12693
+ [
12694
+ "WebSearch",
12695
+ {
12696
+ display: "WebSearch",
12697
+ extractDetails: (input) => [
12698
+ {
12699
+ text: truncate2(String(prop2(input, "query") ?? ""), 40),
12700
+ role: "target"
12701
+ }
12702
+ ],
12703
+ extractOutcome: webSearchOutcome
12704
+ }
12705
+ ],
12706
+ [
12707
+ "NotebookEdit",
12708
+ {
12709
+ display: "Notebook",
12710
+ extractDetails: filePathSegments,
12711
+ extractOutcome: () => void 0
12712
+ }
12713
+ ],
12714
+ // ── Agent & task tools ──
12715
+ ...["Task", "Agent"].map(
12716
+ (name) => [
12717
+ name,
12718
+ {
12719
+ display: "Task",
12720
+ extractDetails: (input) => [
12721
+ {
12722
+ text: truncate2(String(prop2(input, "description") ?? ""), 50),
12723
+ role: "plain"
12724
+ }
12725
+ ],
12726
+ extractOutcome: (output) => {
12727
+ const agentType = prop2(output, "subagent_type");
12728
+ return agentType ? { text: String(agentType), zero: false } : void 0;
12729
+ }
12730
+ }
12731
+ ]
12732
+ ),
12733
+ [
12734
+ "TaskOutput",
12735
+ {
12736
+ display: "TaskOut",
12737
+ extractDetails: (input) => [
12738
+ { text: String(prop2(input, "task_id") ?? ""), role: "target" }
12739
+ ],
12740
+ extractOutcome: taskOutputOutcome
12741
+ }
12742
+ ],
12743
+ [
12744
+ "TaskStop",
12745
+ {
12746
+ display: "TaskStop",
12747
+ extractDetails: (input) => [
12748
+ { text: String(prop2(input, "task_id") ?? ""), role: "target" }
12749
+ ],
12750
+ extractOutcome: () => ({ text: "stopped", zero: false })
12751
+ }
12752
+ ],
12753
+ [
12754
+ "TodoWrite",
12755
+ {
12756
+ display: "TodoWrite",
12757
+ extractDetails: (input) => {
12758
+ const todos = prop2(input, "todos");
12759
+ const n = Array.isArray(todos) ? todos.length : 0;
12760
+ return [{ text: `${n} items`, role: "target" }];
12761
+ },
12762
+ extractOutcome: () => void 0
12763
+ }
12764
+ ],
12765
+ // ── Planning & interaction ──
12766
+ [
12767
+ "AskUserQuestion",
12768
+ {
12769
+ display: "AskUser",
12770
+ extractDetails: (input) => {
12771
+ const questions = prop2(input, "questions");
12772
+ const n = Array.isArray(questions) ? questions.length : 0;
12773
+ return [{ text: `${n} question${n !== 1 ? "s" : ""}`, role: "target" }];
12774
+ },
12775
+ extractOutcome: () => void 0
12776
+ }
12777
+ ],
12778
+ [
12779
+ "EnterPlanMode",
12780
+ {
12781
+ display: "PlanMode",
12782
+ extractDetails: () => [],
12783
+ extractOutcome: () => ({ text: "entered", zero: false })
12784
+ }
12785
+ ],
12786
+ [
12787
+ "ExitPlanMode",
12788
+ {
12789
+ display: "PlanMode",
12790
+ extractDetails: () => [],
12791
+ extractOutcome: () => ({ text: "submitted", zero: false })
12792
+ }
12793
+ ],
12794
+ [
12795
+ "EnterWorktree",
12796
+ {
12797
+ display: "Worktree",
12798
+ extractDetails: (input) => [
12799
+ { text: String(prop2(input, "branch") ?? ""), role: "target" }
12800
+ ],
12801
+ extractOutcome: () => ({ text: "created", zero: false })
12802
+ }
12803
+ ],
12804
+ [
12805
+ "ExitWorktree",
12806
+ {
12807
+ display: "Worktree",
12808
+ extractDetails: (input) => [
12809
+ { text: String(prop2(input, "action") ?? ""), role: "target" }
12810
+ ],
12811
+ extractOutcome: () => ({ text: "exited", zero: false })
12812
+ }
12813
+ ],
12814
+ // ── Cron / scheduling ──
12815
+ [
12816
+ "CronCreate",
12817
+ {
12818
+ display: "Cron",
12819
+ extractDetails: (input) => [
12820
+ { text: truncate2(String(prop2(input, "cron") ?? ""), 30), role: "target" }
12821
+ ],
12822
+ extractOutcome: () => ({ text: "created", zero: false })
12823
+ }
12824
+ ],
12825
+ [
12826
+ "CronDelete",
12827
+ {
12828
+ display: "Cron",
12829
+ extractDetails: (input) => [
12830
+ { text: String(prop2(input, "id") ?? ""), role: "target" }
12831
+ ],
12832
+ extractOutcome: () => ({ text: "deleted", zero: false })
12833
+ }
12834
+ ],
12835
+ [
12836
+ "CronList",
12837
+ {
12838
+ display: "Cron",
12839
+ extractDetails: () => [{ text: "list", role: "target" }],
12840
+ extractOutcome: (output) => countOutcome(output, "triggers")
12841
+ }
12842
+ ],
12843
+ // ── Remote triggers ──
12844
+ [
12845
+ "RemoteTrigger",
12846
+ {
12847
+ display: "Trigger",
12848
+ extractDetails: (input) => {
12849
+ const action = String(prop2(input, "action") ?? "");
12850
+ const triggerId = prop2(input, "trigger_id");
12851
+ const text = triggerId ? `${action} ${String(triggerId)}` : action;
12852
+ return [{ text, role: "target" }];
12853
+ },
12854
+ extractOutcome: () => void 0
12855
+ }
12856
+ ],
12857
+ [
12858
+ "Skill",
12859
+ {
12860
+ display: "Skill",
12861
+ extractDetails: (input) => {
12862
+ const name = String(prop2(input, "skill") ?? "");
12863
+ const colonIdx = name.indexOf(":");
12864
+ const display = colonIdx >= 0 ? name.slice(colonIdx + 1) : name;
12865
+ return [{ text: display.replace(/^\//, ""), role: "target" }];
12866
+ },
12867
+ extractOutcome: () => void 0
12868
+ }
12869
+ ]
12870
+ ]);
12871
+ var MCP_VERB_DISPLAY = /* @__PURE__ */ new Map([
12872
+ // ── Navigation ──
12873
+ [
12874
+ "navigate",
12875
+ {
12876
+ display: "Navigate",
12877
+ extractDetails: (i) => [
12878
+ { text: extractDomain(prop2(i, "url")), role: "target" }
12879
+ ],
12880
+ extractOutcome: () => void 0
12881
+ }
12882
+ ],
12883
+ [
12884
+ "reload",
12885
+ {
12886
+ display: "Reload",
12887
+ extractDetails: () => [],
12888
+ extractOutcome: () => void 0
12889
+ }
12890
+ ],
12891
+ [
12892
+ "go_back",
12893
+ {
12894
+ display: "Back",
12895
+ extractDetails: () => [],
12896
+ extractOutcome: () => void 0
12897
+ }
12898
+ ],
12899
+ [
12900
+ "go_forward",
12901
+ {
12902
+ display: "Forward",
12903
+ extractDetails: () => [],
12904
+ extractOutcome: () => void 0
12905
+ }
12906
+ ],
12907
+ // ── Element interaction ──
12908
+ [
12909
+ "find_elements",
12910
+ {
12911
+ display: "Find",
12912
+ extractDetails: findDetailsExtractor,
12913
+ extractOutcome: foundCountOutcome
12914
+ }
12915
+ ],
12916
+ [
12917
+ "click",
12918
+ {
12919
+ display: "Click",
12920
+ extractDetails: eidOrLabelExtractor,
12921
+ extractOutcome: () => void 0
12922
+ }
12923
+ ],
12924
+ [
12925
+ "type",
12926
+ {
12927
+ display: "Type",
12928
+ extractDetails: typeDetailsExtractor,
12929
+ extractOutcome: () => void 0
12930
+ }
12931
+ ],
12932
+ [
12933
+ "press",
12934
+ {
12935
+ display: "Press",
12936
+ extractDetails: (i) => [
12937
+ { text: String(prop2(i, "key") ?? ""), role: "target" }
12938
+ ],
12939
+ extractOutcome: () => void 0
12940
+ }
12941
+ ],
12942
+ [
12943
+ "select",
12944
+ {
12945
+ display: "Select",
12946
+ extractDetails: (i) => [
12947
+ { text: String(prop2(i, "value") ?? ""), role: "target" }
12948
+ ],
12949
+ extractOutcome: () => void 0
12950
+ }
12951
+ ],
12952
+ [
12953
+ "hover",
12954
+ {
12955
+ display: "Hover",
12956
+ extractDetails: eidOrLabelExtractor,
12957
+ extractOutcome: () => void 0
12958
+ }
12959
+ ],
12960
+ // ── Inspection ──
12961
+ [
12962
+ "get_element_details",
12963
+ {
12964
+ display: "Inspect",
12965
+ extractDetails: eidExtractor2,
12966
+ extractOutcome: () => void 0
12967
+ }
12968
+ ],
12969
+ [
12970
+ "take_screenshot",
12971
+ {
12972
+ display: "Screenshot",
12973
+ extractDetails: () => [],
12974
+ extractOutcome: () => ({ text: "captured", zero: false })
12975
+ }
12976
+ ],
12977
+ [
12978
+ "capture_snapshot",
12979
+ {
12980
+ display: "Snapshot",
12981
+ extractDetails: () => [],
12982
+ extractOutcome: () => void 0
12983
+ }
12984
+ ],
12985
+ [
12986
+ "get_form_understanding",
12987
+ {
12988
+ display: "FormScan",
12989
+ extractDetails: () => [],
12990
+ extractOutcome: formCountOutcome
12991
+ }
12992
+ ],
12993
+ [
12994
+ "get_field_context",
12995
+ {
12996
+ display: "FieldCtx",
12997
+ extractDetails: eidExtractor2,
12998
+ extractOutcome: () => void 0
12999
+ }
13000
+ ],
13001
+ // ── Scroll ──
13002
+ [
13003
+ "scroll_page",
13004
+ {
13005
+ display: "Scroll",
13006
+ extractDetails: scrollDetailsExtractor,
13007
+ extractOutcome: () => void 0
13008
+ }
13009
+ ],
13010
+ [
13011
+ "scroll_element_into_view",
13012
+ {
13013
+ display: "ScrollTo",
13014
+ extractDetails: eidExtractor2,
13015
+ extractOutcome: () => void 0
13016
+ }
13017
+ ],
13018
+ // ── Session ──
13019
+ [
13020
+ "close_session",
13021
+ {
13022
+ display: "Close",
13023
+ extractDetails: () => [{ text: "session", role: "target" }],
13024
+ extractOutcome: () => void 0
13025
+ }
13026
+ ],
13027
+ [
13028
+ "close_page",
13029
+ {
13030
+ display: "ClosePage",
13031
+ extractDetails: tabRefExtractor,
13032
+ extractOutcome: () => void 0
13033
+ }
13034
+ ],
13035
+ [
13036
+ "list_pages",
13037
+ {
13038
+ display: "ListPages",
13039
+ extractDetails: () => [],
13040
+ extractOutcome: tabCountOutcome
13041
+ }
13042
+ ],
13043
+ [
13044
+ "ping",
13045
+ {
13046
+ display: "Ping",
13047
+ extractDetails: () => [],
13048
+ extractOutcome: pingOutcome
13049
+ }
13050
+ ],
13051
+ // ── Context7 ──
13052
+ [
13053
+ "resolve-library-id",
13054
+ {
13055
+ display: "Resolve",
13056
+ extractDetails: (i) => [
13057
+ {
13058
+ text: truncate2(String(prop2(i, "libraryName") ?? ""), 30),
13059
+ role: "target"
13060
+ }
13061
+ ],
13062
+ extractOutcome: () => void 0
13063
+ }
13064
+ ],
13065
+ [
13066
+ "query-docs",
13067
+ {
13068
+ display: "QueryDocs",
13069
+ extractDetails: (i) => [
13070
+ {
13071
+ text: truncate2(String(prop2(i, "query") ?? ""), 40),
13072
+ role: "target"
13073
+ }
13074
+ ],
13075
+ extractOutcome: () => void 0
13076
+ }
13077
+ ]
13078
+ ]);
13079
+ function humanizeToolName(raw) {
13080
+ const display = raw.split(/[_-]/).map((s) => s.charAt(0).toUpperCase() + s.slice(1)).join("");
13081
+ return display.length > 14 ? display.slice(0, 13) + "\u2026" : display;
13082
+ }
13083
+ function resolveToolColumn(toolName) {
13084
+ const parsed = parseToolName(toolName);
13085
+ const known = KNOWN_TOOL_DISPLAY.get(parsed.displayName);
13086
+ if (known) return known.display;
13087
+ if (parsed.isMcp && parsed.mcpAction) {
13088
+ const mcp = MCP_VERB_DISPLAY.get(parsed.mcpAction);
13089
+ if (mcp) return mcp.display;
13090
+ }
13091
+ return parsed.isMcp && parsed.mcpAction ? humanizeToolName(parsed.mcpAction) : humanizeToolName(parsed.displayName);
13092
+ }
13093
+ function resolveEventToolColumn(event) {
13094
+ switch (event.kind) {
13095
+ case "subagent.start":
13096
+ case "subagent.stop":
13097
+ return event.data.agent_type;
13098
+ case "permission.request":
13099
+ return resolveToolColumn(event.data.tool_name);
13100
+ case "setup":
13101
+ case "session.start":
13102
+ case "session.end":
13103
+ case "run.start":
13104
+ case "run.end":
13105
+ case "user.prompt":
13106
+ case "plan.update":
13107
+ case "reasoning.summary":
13108
+ case "usage.update":
13109
+ case "tool.delta":
13110
+ case "tool.pre":
13111
+ case "tool.post":
13112
+ case "tool.failure":
13113
+ case "permission.decision":
13114
+ case "permission.denied":
13115
+ case "stop.request":
13116
+ case "stop.decision":
13117
+ case "stop.failure":
13118
+ case "notification":
13119
+ case "runtime.error":
13120
+ case "thread.status":
13121
+ case "turn.diff":
13122
+ case "server.request.resolved":
13123
+ case "web.search":
13124
+ case "review.status":
13125
+ case "image.view":
13126
+ case "context.compaction":
13127
+ case "mcp.progress":
13128
+ case "terminal.input":
13129
+ case "skills.changed":
13130
+ case "skills.loaded":
13131
+ case "compact.pre":
13132
+ case "compact.post":
13133
+ case "unknown.hook":
13134
+ case "todo.add":
13135
+ case "todo.update":
13136
+ case "todo.done":
13137
+ case "agent.message":
13138
+ case "teammate.idle":
13139
+ case "task.created":
13140
+ case "task.completed":
13141
+ case "config.change":
13142
+ case "cwd.changed":
13143
+ case "file.changed":
13144
+ case "instructions.loaded":
13145
+ case "worktree.create":
13146
+ case "worktree.remove":
13147
+ case "elicitation.request":
13148
+ case "elicitation.result":
13149
+ case "channel.permission.relayed":
13150
+ case "channel.permission.resolved":
13151
+ case "channel.question.relayed":
13152
+ case "channel.question.resolved":
13153
+ case "channel.chat.inbound":
13154
+ case "channel.chat.outbound":
13155
+ case "gateway.function.invoked":
13156
+ case "gateway.function.completed":
13157
+ case "gateway.function.failed":
13158
+ case "artifacts.manifest":
13159
+ return "";
13160
+ }
13161
+ }
13162
+
13163
+ // src/core/feed/indexedTimeline.ts
13164
+ var MAX_SEARCH_CACHE_SIZE = 8;
13165
+ function subagentActorLabel(_agentType, _agentId) {
13166
+ return "SUB AGENT";
13167
+ }
13168
+ function buildSubagentTypeMap(feedEvents) {
13169
+ const map = /* @__PURE__ */ new Map();
13170
+ updateSubagentTypeMap(map, feedEvents);
13171
+ return map;
13172
+ }
13173
+ function updateSubagentTypeMap(map, feedEvents) {
13174
+ for (const event of feedEvents) {
13175
+ if (event.kind !== "subagent.start" && event.kind !== "subagent.stop") {
13176
+ continue;
13177
+ }
13178
+ const agentId = event.data.agent_id;
13179
+ const agentType = event.data.agent_type;
13180
+ if (!agentId || !agentType || map.has(agentId)) continue;
13181
+ map.set(agentId, agentType);
13182
+ }
13183
+ }
13184
+ function resolveActorLabel(event, subagentTypes) {
13185
+ if (!event.actor_id.startsWith("subagent:")) {
13186
+ return actorLabel(event.actor_id);
13187
+ }
13188
+ const agentId = event.actor_id.slice("subagent:".length);
13189
+ const eventAgentType = event.kind === "subagent.start" || event.kind === "subagent.stop" ? event.data.agent_type : void 0;
13190
+ return subagentActorLabel(
13191
+ eventAgentType || subagentTypes.get(agentId),
13192
+ agentId
13193
+ );
13194
+ }
13195
+ function buildMessageEntry(item, activeRunId, messageCounter) {
13196
+ const summary = compactText(item.content, 200);
13197
+ const details = item.content;
13198
+ return {
13199
+ id: `M${String(messageCounter).padStart(3, "0")}`,
13200
+ ts: item.timestamp.getTime(),
13201
+ runId: activeRunId,
13202
+ op: item.role === "user" ? "User Msg" : "Agent Msg",
13203
+ opTag: item.role === "user" ? "msg.user" : "msg.agent",
13204
+ actor: item.role === "user" ? "USER" : "AGENT",
13205
+ actorId: item.role === "user" ? "user" : "agent:root",
13206
+ toolColumn: "",
13207
+ summary,
13208
+ summarySegments: [{ text: summary, role: "plain" }],
13209
+ searchText: `${summary}
13210
+ ${details}`,
13211
+ error: false,
13212
+ expandable: details.length > 120,
13213
+ details,
13214
+ duplicateActor: false
13215
+ };
13216
+ }
13217
+ function shouldSkipEvent(event, verbose) {
13218
+ if (!verbose && VERBOSE_ONLY_KINDS.has(event.kind)) {
13219
+ return true;
13220
+ }
13221
+ if (!verbose && event.kind === "stop.request" && !event.data.stop_hook_active) {
13222
+ return true;
13223
+ }
13224
+ return false;
13225
+ }
13226
+ function mergedToolUseId(event, postByToolUseId) {
13227
+ if (event.kind !== "tool.post" && event.kind !== "tool.failure" || isSubagentTool(event.data.tool_name) || !postByToolUseId) {
13228
+ return void 0;
13229
+ }
13230
+ const toolUseId = event.data.tool_use_id;
13231
+ if (!toolUseId) return void 0;
13232
+ return postByToolUseId.get(toolUseId) === event ? toolUseId : void 0;
13233
+ }
13234
+ function pairedPostForEvent(event, postByToolUseId) {
13235
+ if (event.kind !== "tool.pre" && event.kind !== "permission.request" || isSubagentTool(event.data.tool_name) || !event.data.tool_use_id) {
13236
+ return void 0;
13237
+ }
13238
+ return postByToolUseId?.get(event.data.tool_use_id);
13239
+ }
13240
+ function pendingToolUpdateUseId(event) {
13241
+ if (event.kind !== "tool.delta" && event.kind !== "tool.post" && event.kind !== "tool.failure") {
13242
+ return void 0;
13243
+ }
13244
+ if (isSubagentTool(event.data.tool_name)) {
13245
+ return void 0;
13246
+ }
13247
+ return event.data.tool_use_id;
13248
+ }
13249
+ function buildEventEntry(event, subagentTypes, pairedPost) {
13250
+ const opTag = pairedPost ? mergedEventOperation(event, pairedPost) : eventOperation(event);
13251
+ const op = pairedPost ? mergedEventLabel(event, pairedPost) : eventLabel(event);
13252
+ const summaryResult = pairedPost ? mergedEventSummary(event, pairedPost) : eventSummary(event);
13253
+ const { text: summary, segments: summarySegments } = summaryResult;
13254
+ const toolColumn = event.kind === "tool.pre" || event.kind === "tool.post" || event.kind === "tool.failure" ? resolveToolColumn(event.data.tool_name) : resolveEventToolColumn(event);
13255
+ return {
13256
+ id: event.event_id,
13257
+ ts: event.ts,
13258
+ runId: event.run_id,
13259
+ op,
13260
+ opTag,
13261
+ actor: resolveActorLabel(event, subagentTypes),
13262
+ actorId: event.actor_id,
13263
+ toolColumn,
13264
+ summary,
13265
+ summarySegments,
13266
+ summaryOutcome: summaryResult.outcome,
13267
+ summaryOutcomeZero: summaryResult.outcomeZero,
13268
+ searchText: summary,
13269
+ error: isEventError(event) || pairedPost?.kind === "tool.failure",
13270
+ expandable: isEventExpandable(event),
13271
+ details: "",
13272
+ feedEvent: event,
13273
+ pairedPostEvent: pairedPost,
13274
+ duplicateActor: false
13275
+ };
13276
+ }
13277
+ function maybeBuildEventEntry(event, subagentTypes, postByToolUseId, verbose) {
13278
+ if (shouldSkipEvent(event, verbose)) return null;
13279
+ if (event.kind === "tool.delta") return null;
13280
+ if (mergedToolUseId(event, postByToolUseId)) {
13281
+ return null;
13282
+ }
13283
+ return buildEventEntry(
13284
+ event,
13285
+ subagentTypes,
13286
+ pairedPostForEvent(event, postByToolUseId)
13287
+ );
13288
+ }
13289
+ function rememberPendingEntry(pendingEntryIndexByToolUseId, entry, index) {
13290
+ const event = entry.feedEvent;
13291
+ if (!event) return;
13292
+ if (event.kind !== "tool.pre" && event.kind !== "permission.request" || isSubagentTool(event.data.tool_name) || !event.data.tool_use_id || entry.pairedPostEvent) {
13293
+ return;
13294
+ }
13295
+ pendingEntryIndexByToolUseId.set(event.data.tool_use_id, index);
13296
+ }
13297
+ function recomputeDuplicateActorAt(entries, index) {
13298
+ const entry = entries[index];
13299
+ if (index === 0) {
13300
+ entry.duplicateActor = false;
13301
+ return;
13302
+ }
13303
+ const prev = entries[index - 1];
13304
+ const sameActor = entry.actorId === prev.actorId;
13305
+ const isBreak = opCategory(entry.opTag) !== opCategory(prev.opTag);
13306
+ entry.duplicateActor = sameActor && !isBreak;
13307
+ }
13308
+ function recomputeDuplicateActorsAround(entries, index) {
13309
+ recomputeDuplicateActorAt(entries, index);
13310
+ if (index + 1 < entries.length) {
13311
+ recomputeDuplicateActorAt(entries, index + 1);
13312
+ }
13313
+ }
13314
+ function sameFeedItemPrefix(previous, next) {
13315
+ if (next.length < previous.length) return false;
13316
+ for (let i = 0; i < previous.length; i++) {
13317
+ const prev = previous[i];
13318
+ const curr = next[i];
13319
+ if (prev.type !== curr.type || prev.data !== curr.data) {
13320
+ return false;
13321
+ }
13322
+ }
13323
+ return true;
13324
+ }
13325
+ function sameFeedEventPrefix(previous, next) {
13326
+ if (next.length < previous.length) return false;
13327
+ for (let i = 0; i < previous.length; i++) {
13328
+ if (previous[i] !== next[i]) {
13329
+ return false;
13330
+ }
13331
+ }
13332
+ return true;
13333
+ }
13334
+ function canAppendIncrementally(previous, feedItems, feedEvents, verbose) {
13335
+ if (!previous) return false;
13336
+ if (previous.verbose !== verbose) return false;
13337
+ return sameFeedItemPrefix(previous.feedItems, feedItems) && sameFeedEventPrefix(previous.feedEvents, feedEvents);
13338
+ }
13339
+ function buildTimelineCache(feedItems, feedEvents, postByToolUseId, verbose) {
13340
+ const entries = [];
13341
+ let activeRunId;
13342
+ let messageCounter = 1;
13343
+ const subagentTypes = buildSubagentTypeMap(feedEvents);
13344
+ const pendingEntryIndexByToolUseId = /* @__PURE__ */ new Map();
13345
+ for (const item of feedItems) {
13346
+ if (item.type === "message") {
13347
+ entries.push(buildMessageEntry(item.data, activeRunId, messageCounter++));
13348
+ continue;
13349
+ }
13350
+ const event = item.data;
13351
+ if (event.kind === "run.start") {
13352
+ activeRunId = event.run_id;
13353
+ }
13354
+ const entry = maybeBuildEventEntry(
13355
+ event,
13356
+ subagentTypes,
13357
+ postByToolUseId,
13358
+ verbose
13359
+ );
13360
+ if (entry) {
13361
+ const index = entries.push(entry) - 1;
13362
+ rememberPendingEntry(pendingEntryIndexByToolUseId, entry, index);
13363
+ }
13364
+ if (event.kind === "run.end") {
13365
+ activeRunId = void 0;
13366
+ }
13367
+ }
13368
+ computeDuplicateActors(entries);
13369
+ return {
13370
+ feedItems,
13371
+ feedEvents,
13372
+ entries,
13373
+ activeRunId,
13374
+ messageCounter,
13375
+ subagentTypes,
13376
+ pendingEntryIndexByToolUseId,
13377
+ verbose
13378
+ };
13379
+ }
13380
+ function appendTimelineCache(previous, feedItems, feedEvents, postByToolUseId) {
13381
+ const entries = previous.entries.slice();
13382
+ const subagentTypes = new Map(previous.subagentTypes);
13383
+ updateSubagentTypeMap(
13384
+ subagentTypes,
13385
+ feedEvents.slice(previous.feedEvents.length)
13386
+ );
13387
+ const pendingEntryIndexByToolUseId = new Map(
13388
+ previous.pendingEntryIndexByToolUseId
13389
+ );
13390
+ let activeRunId = previous.activeRunId;
13391
+ let messageCounter = previous.messageCounter;
13392
+ for (const item of feedItems.slice(previous.feedItems.length)) {
13393
+ if (item.type === "message") {
13394
+ const index = entries.push(
13395
+ buildMessageEntry(item.data, activeRunId, messageCounter++)
13396
+ ) - 1;
13397
+ recomputeDuplicateActorsAround(entries, index);
13398
+ continue;
13399
+ }
13400
+ const event = item.data;
13401
+ if (event.kind === "run.start") {
13402
+ activeRunId = event.run_id;
13403
+ }
13404
+ const resolvedToolUseId = pendingToolUpdateUseId(event);
13405
+ if (resolvedToolUseId) {
13406
+ const pendingIndex = pendingEntryIndexByToolUseId.get(resolvedToolUseId);
13407
+ if (pendingIndex !== void 0) {
13408
+ const pendingEntry = entries[pendingIndex];
13409
+ if (pendingEntry.feedEvent) {
13410
+ entries[pendingIndex] = buildEventEntry(
13411
+ pendingEntry.feedEvent,
13412
+ subagentTypes,
13413
+ event
13414
+ );
13415
+ if (event.kind === "tool.post" || event.kind === "tool.failure") {
13416
+ pendingEntryIndexByToolUseId.delete(resolvedToolUseId);
13417
+ }
13418
+ recomputeDuplicateActorsAround(entries, pendingIndex);
13419
+ }
13420
+ }
13421
+ continue;
13422
+ }
13423
+ const entry = maybeBuildEventEntry(
13424
+ event,
13425
+ subagentTypes,
13426
+ postByToolUseId,
13427
+ previous.verbose
13428
+ );
13429
+ if (entry) {
13430
+ const index = entries.push(entry) - 1;
13431
+ recomputeDuplicateActorsAround(entries, index);
13432
+ rememberPendingEntry(pendingEntryIndexByToolUseId, entry, index);
13433
+ }
13434
+ if (event.kind === "run.end") {
13435
+ activeRunId = void 0;
13436
+ }
13437
+ }
13438
+ return {
13439
+ feedItems,
13440
+ feedEvents,
13441
+ entries,
13442
+ activeRunId,
13443
+ messageCounter,
13444
+ subagentTypes,
13445
+ pendingEntryIndexByToolUseId,
13446
+ verbose: previous.verbose
13447
+ };
13448
+ }
13449
+ var IndexedTimeline = class {
13450
+ cache = null;
13451
+ runIndex = /* @__PURE__ */ new Map();
13452
+ errorPositions = /* @__PURE__ */ new Set();
13453
+ _runSummaryMap = /* @__PURE__ */ new Map();
13454
+ _runSummariesDirty = true;
13455
+ _runSummariesCache = [];
13456
+ _lastFeedEventsLength = 0;
13457
+ searchCache = /* @__PURE__ */ new Map();
13458
+ lastFilteredRef = null;
13459
+ detailCache = /* @__PURE__ */ new WeakMap();
13460
+ searchTextCache = /* @__PURE__ */ new WeakMap();
13461
+ verbose = false;
13462
+ update(feedItems, feedEvents, postByToolUseId, verbose) {
13463
+ this.verbose = verbose;
13464
+ const incremental = canAppendIncrementally(
13465
+ this.cache,
13466
+ feedItems,
13467
+ feedEvents,
13468
+ this.verbose
13469
+ );
13470
+ if (incremental) {
13471
+ this.updateRunSummaries(feedEvents);
13472
+ this.cache = appendTimelineCache(
13473
+ this.cache,
13474
+ feedItems,
13475
+ feedEvents,
13476
+ postByToolUseId
13477
+ );
13478
+ } else {
13479
+ this.rebuildRunSummaries(feedEvents);
13480
+ this.cache = buildTimelineCache(
13481
+ feedItems,
13482
+ feedEvents,
13483
+ postByToolUseId,
13484
+ this.verbose
13485
+ );
13486
+ }
13487
+ this.rebuildIndexes();
13488
+ }
13489
+ getEntries() {
13490
+ return this.cache?.entries ?? [];
13491
+ }
13492
+ getFilteredView(runFilter, errorsOnly) {
13493
+ const entries = this.getEntries();
13494
+ if ((!runFilter || runFilter === "all") && !errorsOnly) {
13495
+ return entries;
13496
+ }
13497
+ let candidateIndices;
13498
+ if (runFilter && runFilter !== "all") {
13499
+ candidateIndices = this.runIndex.get(runFilter) ?? [];
13500
+ } else {
13501
+ candidateIndices = Array.from({ length: entries.length }, (_, i) => i);
13502
+ }
13503
+ if (errorsOnly) {
13504
+ candidateIndices = candidateIndices.filter(
13505
+ (i) => this.errorPositions.has(i)
13506
+ );
13507
+ }
13508
+ return candidateIndices.map((i) => entries[i]);
13509
+ }
13510
+ getSearchMatches(filteredEntries, query) {
13511
+ const q = query.trim().toLowerCase();
13512
+ if (!q) return [];
13513
+ if (filteredEntries !== this.lastFilteredRef) {
13514
+ this.searchCache.clear();
13515
+ this.lastFilteredRef = filteredEntries;
13516
+ }
13517
+ const cached = this.searchCache.get(q);
13518
+ if (cached && cached.lastScanned === filteredEntries.length) {
13519
+ return cached.matches;
13520
+ }
13521
+ const startFrom = cached ? cached.lastScanned : 0;
13522
+ const matches = cached ? [...cached.matches] : [];
13523
+ for (let i = startFrom; i < filteredEntries.length; i++) {
13524
+ const searchText = this.getEntrySearchText(filteredEntries[i]);
13525
+ if (searchText.toLowerCase().includes(q)) {
13526
+ matches.push(i);
13527
+ }
13528
+ }
13529
+ this.searchCache.set(q, { matches, lastScanned: filteredEntries.length });
13530
+ if (this.searchCache.size > MAX_SEARCH_CACHE_SIZE) {
13531
+ const oldest = this.searchCache.keys().next().value;
13532
+ if (oldest !== void 0) {
13533
+ this.searchCache.delete(oldest);
13534
+ }
13535
+ }
13536
+ return matches;
13537
+ }
13538
+ getEntrySearchText(entry) {
13539
+ const cached = this.searchTextCache.get(entry);
13540
+ if (cached !== void 0) return cached;
13541
+ if (!entry.feedEvent) {
13542
+ this.searchTextCache.set(entry, entry.searchText);
13543
+ return entry.searchText;
13544
+ }
13545
+ const details = this.getEntryDetails(entry);
13546
+ const searchText = details ? `${entry.summary}
13547
+ ${details}` : entry.summary;
13548
+ this.searchTextCache.set(entry, searchText);
13549
+ return searchText;
13550
+ }
13551
+ getEntryDetails(entry) {
13552
+ if (entry.details) return entry.details;
13553
+ if (!entry.feedEvent) return entry.summary;
13554
+ const cached = this.detailCache.get(entry);
13555
+ if (cached !== void 0) return cached;
13556
+ const details = isEventExpandable(entry.feedEvent) ? expansionForEvent(entry.feedEvent) : "";
13557
+ this.detailCache.set(entry, details);
13558
+ return details;
13559
+ }
13560
+ getRunSummaries() {
13561
+ if (this._runSummariesDirty) {
13562
+ this._runSummariesCache = Array.from(this._runSummaryMap.values()).sort(
13563
+ (a, b) => a.startedAt - b.startedAt
13564
+ );
13565
+ this._runSummariesDirty = false;
13566
+ }
13567
+ return this._runSummariesCache;
13568
+ }
13569
+ processRunEvent(event) {
13570
+ if (event.kind === "run.start") {
13571
+ this._runSummaryMap.set(event.run_id, {
13572
+ runId: event.run_id,
13573
+ title: compactText(
13574
+ event.data.trigger.prompt_preview || "Untitled run",
13575
+ 46
13576
+ ),
13577
+ status: "RUNNING",
13578
+ startedAt: event.ts
13579
+ });
13580
+ this._runSummariesDirty = true;
13581
+ } else if (event.kind === "run.end") {
13582
+ const existing = this._runSummaryMap.get(event.run_id);
13583
+ if (existing) {
13584
+ existing.status = toRunStatus(event);
13585
+ existing.endedAt = event.ts;
13586
+ } else {
13587
+ this._runSummaryMap.set(event.run_id, {
13588
+ runId: event.run_id,
13589
+ title: "Untitled run",
13590
+ status: toRunStatus(event),
13591
+ startedAt: event.ts,
13592
+ endedAt: event.ts
13593
+ });
13594
+ }
13595
+ this._runSummariesDirty = true;
13596
+ }
13597
+ }
13598
+ rebuildRunSummaries(feedEvents) {
13599
+ this._runSummaryMap.clear();
13600
+ this._runSummariesDirty = true;
13601
+ this._lastFeedEventsLength = 0;
13602
+ this.updateRunSummaries(feedEvents);
13603
+ }
13604
+ updateRunSummaries(feedEvents) {
13605
+ for (let i = this._lastFeedEventsLength; i < feedEvents.length; i++) {
13606
+ this.processRunEvent(feedEvents[i]);
13607
+ }
13608
+ this._lastFeedEventsLength = feedEvents.length;
13609
+ }
13610
+ addToIndex(entry, index) {
13611
+ const runId = entry.runId ?? "__none__";
13612
+ let indices = this.runIndex.get(runId);
13613
+ if (!indices) {
13614
+ indices = [];
13615
+ this.runIndex.set(runId, indices);
13616
+ }
13617
+ indices.push(index);
13618
+ if (entry.error) {
13619
+ this.errorPositions.add(index);
13620
+ }
13621
+ }
13622
+ rebuildIndexes() {
13623
+ this.runIndex.clear();
13624
+ this.errorPositions.clear();
13625
+ this.searchCache.clear();
13626
+ const entries = this.getEntries();
13627
+ for (let i = 0; i < entries.length; i++) {
13628
+ this.addToIndex(entries[i], i);
13629
+ }
13630
+ }
13631
+ };
13632
+
13633
+ // src/infra/sessions/registry.ts
13634
+ import fs18 from "fs";
13635
+ import os10 from "os";
13636
+ import path15 from "path";
13637
+ import Database3 from "better-sqlite3";
13638
+ function sessionsDir() {
13639
+ return path15.join(os10.homedir(), ".config", "athena", "sessions");
13640
+ }
13641
+ function sessionDbPath(sessionId) {
13642
+ return path15.join(sessionsDir(), sessionId, "session.db");
13643
+ }
13644
+ function readSessionFromDb(dbPath) {
13645
+ if (!fs18.existsSync(dbPath)) return null;
13646
+ let db;
13647
+ try {
13648
+ db = new Database3(dbPath, { readonly: true });
13649
+ const versionRow = db.prepare("SELECT version FROM schema_version").get();
13650
+ if (versionRow && versionRow.version > SCHEMA_VERSION) {
13651
+ return null;
13652
+ }
13653
+ const row = db.prepare("SELECT * FROM session LIMIT 1").get();
13654
+ if (!row) return null;
13655
+ const adapters = db.prepare("SELECT session_id FROM adapter_sessions ORDER BY started_at").all();
13656
+ let firstPrompt;
13657
+ if (!row.label && (row.event_count ?? 0) > 0) {
13658
+ const promptRow = db.prepare(
13659
+ `SELECT json_extract(payload, '$.data.prompt') as prompt FROM runtime_events WHERE hook_name = 'UserPromptSubmit' ORDER BY seq ASC LIMIT 1`
13660
+ ).get();
13661
+ if (promptRow?.prompt) {
13662
+ firstPrompt = promptRow.prompt;
13663
+ }
13664
+ }
13665
+ return rowToAthenaSession(
13666
+ row,
13667
+ adapters.map((a) => a.session_id),
13668
+ firstPrompt
13669
+ );
13670
+ } catch {
13671
+ return null;
13672
+ } finally {
13673
+ db?.close();
13674
+ }
13675
+ }
13676
+ function listSessions(projectDir) {
13677
+ const dir = sessionsDir();
13678
+ if (!fs18.existsSync(dir)) return [];
13679
+ const entries = fs18.readdirSync(dir, { withFileTypes: true });
13680
+ const sessions = [];
13681
+ for (const entry of entries) {
13682
+ if (!entry.isDirectory()) continue;
13683
+ const dbPath = path15.join(dir, entry.name, "session.db");
13684
+ const session = readSessionFromDb(dbPath);
13685
+ if (session && (session.eventCount ?? 0) > 0) {
13686
+ if (!projectDir || session.projectDir === projectDir) {
13687
+ sessions.push(session);
13688
+ }
13689
+ }
13690
+ }
13691
+ return sessions.sort((a, b) => b.updatedAt - a.updatedAt);
13692
+ }
13693
+ function getSessionMeta(sessionId) {
13694
+ return readSessionFromDb(sessionDbPath(sessionId));
13695
+ }
13696
+ function getMostRecentAthenaSession(projectDir) {
13697
+ const sessions = listSessions(projectDir);
13698
+ return sessions[0] ?? null;
13699
+ }
13700
+
13701
+ // src/app/channels/relayAdapter.ts
13702
+ function createRelayPermissionCallback(bridge, runtime) {
13703
+ return (event) => {
13704
+ const toolName = resolveToolName2(event);
13705
+ writeGatewayTrace(
13706
+ `relayAdapter relayPermission event=${event.id} tool=${toolName}`
13707
+ );
13708
+ void bridge.relayPermission({
13709
+ toolName,
13710
+ description: event.display?.title ?? `${toolName} request`,
13711
+ inputPreview: previewToolInput(event),
13712
+ ...event.interaction.defaultTimeoutMs !== void 0 ? { ttlMs: event.interaction.defaultTimeoutMs } : {}
13713
+ }).then((res) => {
13714
+ const decision = permissionRelayDecision(res.result);
13715
+ if (!decision) return;
13716
+ runtime.sendDecision(event.id, decision);
13717
+ }).catch((err) => {
13718
+ if (process.env["ATHENA_GATEWAY_TRACE"] === "1") {
13719
+ console.error(
13720
+ `[athena] gateway relayPermission failed: ${err instanceof Error ? err.message : String(err)}`
13721
+ );
13722
+ }
13723
+ });
13724
+ };
13725
+ }
13726
+ function createRelayQuestionCallback(bridge, runtime) {
13727
+ return (event) => {
13728
+ const questions = extractRelayQuestions(event);
13729
+ const title = event.display?.title ?? "Question";
13730
+ writeGatewayTrace(
13731
+ `relayAdapter relayQuestion event=${event.id} count=${questions.length}`
13732
+ );
13733
+ void bridge.relayQuestion({
13734
+ title,
13735
+ questions,
13736
+ ...event.interaction.defaultTimeoutMs !== void 0 ? { ttlMs: event.interaction.defaultTimeoutMs } : {}
13737
+ }).then((res) => {
13738
+ const decision = questionRelayDecision(res.result);
13739
+ if (!decision) return;
13740
+ runtime.sendDecision(event.id, decision);
13741
+ }).catch((err) => {
13742
+ if (process.env["ATHENA_GATEWAY_TRACE"] === "1") {
13743
+ console.error(
13744
+ `[athena] gateway relayQuestion failed: ${err instanceof Error ? err.message : String(err)}`
13745
+ );
13746
+ }
13747
+ });
13748
+ };
10366
13749
  }
10367
13750
  function resolveToolName2(event) {
10368
13751
  const data = event.data;
@@ -10750,7 +14133,7 @@ import path16 from "path";
10750
14133
 
10751
14134
  // src/shared/gateway-protocol/endpoint.ts
10752
14135
  function parseRuntimeEndpoint(value) {
10753
- if (!isRecord(value)) {
14136
+ if (!isRecord2(value)) {
10754
14137
  throw new Error("gateway client config must be an object");
10755
14138
  }
10756
14139
  if (value["mode"] === "local") {
@@ -10795,7 +14178,7 @@ function isSupportedGatewayUrl(url) {
10795
14178
  return false;
10796
14179
  }
10797
14180
  }
10798
- function isRecord(value) {
14181
+ function isRecord2(value) {
10799
14182
  return typeof value === "object" && value !== null && !Array.isArray(value);
10800
14183
  }
10801
14184
 
@@ -11267,7 +14650,7 @@ function sleepOrAbort(ms, signal) {
11267
14650
  }
11268
14651
 
11269
14652
  // src/app/dashboard/dashboardFeedPublisher.ts
11270
- import Database3 from "better-sqlite3";
14653
+ import Database4 from "better-sqlite3";
11271
14654
  function dashboardFeedOutboxPath() {
11272
14655
  return `${ensureDaemonStateDir().dir}/dashboard-feed-outbox.db`;
11273
14656
  }
@@ -11308,7 +14691,7 @@ function makeEnvelope(input) {
11308
14691
  };
11309
14692
  }
11310
14693
  function createDashboardFeedOutbox(options = {}) {
11311
- const db = new Database3(options.dbPath ?? dashboardFeedOutboxPath());
14694
+ const db = new Database4(options.dbPath ?? dashboardFeedOutboxPath());
11312
14695
  initOutboxSchema(db);
11313
14696
  const insert = db.prepare(`
11314
14697
  INSERT OR IGNORE INTO dashboard_feed_outbox (
@@ -11656,6 +15039,7 @@ async function runExec(options) {
11656
15039
  const runtimeFactory = options.runtimeFactory ?? createRuntime;
11657
15040
  const sessionStoreFactory = options.sessionStoreFactory ?? createSessionStore;
11658
15041
  const athenaSessionId = options.athenaSessionId ?? crypto2.randomUUID();
15042
+ const ownsFeedPublisher = !options.dashboardFeedPublisher;
11659
15043
  const dashboardFeedPublisher = options.dashboardFeedPublisher ?? createPairedFeedPublisher();
11660
15044
  const dashboardOrigin = options.dashboardOrigin ?? "local";
11661
15045
  const output = createExecOutputWriter({
@@ -12025,6 +15409,9 @@ async function runExec(options) {
12025
15409
  }
12026
15410
  await bridge?.stop();
12027
15411
  store.close();
15412
+ if (ownsFeedPublisher) {
15413
+ dashboardFeedPublisher.close();
15414
+ }
12028
15415
  }
12029
15416
  const resolvedFinalMessage = resolveFinalMessage({
12030
15417
  streamMessage: streamFinalMessage,
@@ -13508,7 +16895,7 @@ function createAttachmentReconciler(options) {
13508
16895
  }
13509
16896
 
13510
16897
  // src/app/dashboard/dashboardDecisionInbox.ts
13511
- import Database4 from "better-sqlite3";
16898
+ import Database5 from "better-sqlite3";
13512
16899
  function dashboardDecisionInboxPath() {
13513
16900
  return `${ensureDaemonStateDir().dir}/dashboard-decision-inbox.db`;
13514
16901
  }
@@ -13576,7 +16963,7 @@ function initInboxSchema(db) {
13576
16963
  `);
13577
16964
  }
13578
16965
  function createDashboardDecisionInbox(options = {}) {
13579
- const db = new Database4(options.dbPath ?? dashboardDecisionInboxPath());
16966
+ const db = new Database5(options.dbPath ?? dashboardDecisionInboxPath());
13580
16967
  initInboxSchema(db);
13581
16968
  const upsertUnconsumed = db.prepare(`
13582
16969
  INSERT INTO dashboard_decision_inbox (
@@ -13747,6 +17134,10 @@ function createDashboardPairedExecution(options) {
13747
17134
  return { kind: "accepted" };
13748
17135
  }
13749
17136
  return {
17137
+ // `job_assignment` is intentionally not handled here: the runtime daemon
17138
+ // routes assignments through `DashboardAssignmentIntake`, which gates
17139
+ // admission on attachment readiness and then calls `admitAssignment`
17140
+ // directly. `handleFrame` owns only the frames that flow straight through.
13750
17141
  handleFrame(frame) {
13751
17142
  if (frame.type === "dashboard_decision") {
13752
17143
  handleDecision(frame);
@@ -13756,10 +17147,6 @@ function createDashboardPairedExecution(options) {
13756
17147
  handleCancel(frame);
13757
17148
  return true;
13758
17149
  }
13759
- if (frame.type === "job_assignment") {
13760
- handleAssignment(frame);
13761
- return true;
13762
- }
13763
17150
  return false;
13764
17151
  },
13765
17152
  admitAssignment(frame, input) {
@@ -14220,15 +17607,16 @@ async function runDashboardRuntimeDaemon(options = {}) {
14220
17607
  accessToken: token.accessToken
14221
17608
  });
14222
17609
  } catch (err) {
14223
- client = null;
14224
- assignmentIntake.markNotReady();
14225
17610
  attachmentReconciler.markStale(token.instanceId);
14226
- next.close("attachment reconciliation failed");
14227
- throw err;
17611
+ log(
17612
+ "warn",
17613
+ `runtime daemon: attachment reconciliation failed; continuing with push-only mirror: ${err instanceof Error ? err.message : String(err)}`
17614
+ );
14228
17615
  }
17616
+ if (stopped || client !== next) return;
17617
+ assignmentIntake.markReady();
14229
17618
  currentInstanceId = token.instanceId;
14230
17619
  currentDashboardUrl = config.dashboardUrl;
14231
- assignmentIntake.markReady();
14232
17620
  reconnectAttempt = 0;
14233
17621
  scheduleRefresh(token.expiresInSec);
14234
17622
  pairedFeedPublisher.attachTransport(next);
@@ -14600,7 +17988,10 @@ export {
14600
17988
  isScopedPermissionsRequest,
14601
17989
  supportsSessionApproval,
14602
17990
  extractPermissionSnapshot,
14603
- isSubagentTool,
17991
+ extractFriendlyServerName,
17992
+ parseToolName,
17993
+ mergeFeedItems,
17994
+ buildPostByToolUseId,
14604
17995
  createFeedMapper,
14605
17996
  ingestRuntimeEvent,
14606
17997
  ingestRuntimeDecision,
@@ -14653,6 +18044,26 @@ export {
14653
18044
  register,
14654
18045
  get,
14655
18046
  getAll,
18047
+ stripAnsi,
18048
+ stringWidth,
18049
+ sliceAnsi,
18050
+ spaces,
18051
+ compactText,
18052
+ fit,
18053
+ fitAnsi,
18054
+ centerAnsi,
18055
+ formatClock,
18056
+ formatRunLabel,
18057
+ cursorToVisualPosition,
18058
+ visualPositionToOffset,
18059
+ renderInputLines,
18060
+ wrapText,
18061
+ computeInputRows,
18062
+ isCommandPrefix,
18063
+ formatToolResponse,
18064
+ isBashToolResponse,
18065
+ resolveToolColumn,
18066
+ IndexedTimeline,
14656
18067
  bootstrapRuntimeConfig,
14657
18068
  EXEC_EXIT_CODE,
14658
18069
  runExec,
@@ -14665,4 +18076,4 @@ export {
14665
18076
  startUdsServer,
14666
18077
  sendUdsRequest
14667
18078
  };
14668
- //# sourceMappingURL=chunk-XIWMD4GT.js.map
18079
+ //# sourceMappingURL=chunk-2QMUBFZZ.js.map