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