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