@drisp/cli 0.5.24 → 0.5.26
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/{WorkflowInstallWizard-IMU47QWB.js → WorkflowInstallWizard-5FENJHBW.js} +2 -2
- package/dist/athena-gateway.js +61 -242
- package/dist/{chunk-YU2WMPRC.js → chunk-3U37HT4T.js} +381 -114
- package/dist/{chunk-7GEQJQMR.js → chunk-4NX4WFPB.js} +2 -2
- package/dist/{chunk-7UUPLAP4.js → chunk-73V7GXV6.js} +10 -13
- package/dist/{chunk-BTKQ67RE.js → chunk-QYB6N2OT.js} +1 -1
- package/dist/{chunk-QBMYQJFX.js → chunk-YZ7RCBKO.js} +580 -153
- package/dist/cli.js +752 -355
- package/dist/dashboard-daemon.js +4 -4
- package/dist/hook-forwarder.js +1 -1
- package/package.json +1 -1
|
@@ -12,30 +12,33 @@ import {
|
|
|
12
12
|
isToolEvent,
|
|
13
13
|
isValidHookEventEnvelope,
|
|
14
14
|
resolveHookSocketPath
|
|
15
|
-
} from "./chunk-
|
|
15
|
+
} from "./chunk-QYB6N2OT.js";
|
|
16
16
|
import {
|
|
17
17
|
TransportUnreachableError,
|
|
18
18
|
createUdsClientTransport,
|
|
19
|
+
createWsClientTransport,
|
|
19
20
|
generateChannelRequestId,
|
|
20
21
|
openVersionedDb,
|
|
21
22
|
readDashboardClientConfig,
|
|
22
23
|
refreshDashboardAccessToken,
|
|
23
24
|
resolveGatewayPaths,
|
|
24
|
-
traceGatewayFrame,
|
|
25
25
|
trackGatewayTransportReconnect,
|
|
26
|
-
writeGatewayTrace
|
|
27
|
-
|
|
26
|
+
writeGatewayTrace,
|
|
27
|
+
wsClientOptionsForEndpoint
|
|
28
|
+
} from "./chunk-3U37HT4T.js";
|
|
28
29
|
import {
|
|
29
30
|
compileWorkflowPlan,
|
|
30
31
|
createWorkflowRunner,
|
|
31
32
|
installWorkflowFromSource,
|
|
33
|
+
isMarketplaceRef,
|
|
32
34
|
readConfig,
|
|
33
35
|
readGlobalConfig,
|
|
34
36
|
resolveActiveWorkflow,
|
|
37
|
+
resolveMarketplacePlugin,
|
|
35
38
|
resolveWorkflow,
|
|
36
39
|
resolveWorkflowInstall,
|
|
37
40
|
resolveWorkflowPlugins
|
|
38
|
-
} from "./chunk-
|
|
41
|
+
} from "./chunk-73V7GXV6.js";
|
|
39
42
|
|
|
40
43
|
// src/infra/daemon/stateDir.ts
|
|
41
44
|
import fs from "fs";
|
|
@@ -238,6 +241,16 @@ var RULES = {
|
|
|
238
241
|
defaultTimeoutMs: DEFAULT_TIMEOUT_MS,
|
|
239
242
|
canBlock: false
|
|
240
243
|
},
|
|
244
|
+
// Observation-only: the batch fires after every call in it has already
|
|
245
|
+
// resolved, so nothing downstream produces a decision or block for it. The
|
|
246
|
+
// claim is not cosmetic — hook dispatch keeps every decision-capable event
|
|
247
|
+
// on Claude's critical path, so a false `canBlock` would make every
|
|
248
|
+
// parallel tool batch wait on the forwarder for a reply never sent.
|
|
249
|
+
"tool.batch": {
|
|
250
|
+
expectsDecision: false,
|
|
251
|
+
defaultTimeoutMs: DEFAULT_TIMEOUT_MS,
|
|
252
|
+
canBlock: false
|
|
253
|
+
},
|
|
241
254
|
"tool.delta": {
|
|
242
255
|
expectsDecision: false,
|
|
243
256
|
defaultTimeoutMs: DEFAULT_TIMEOUT_MS,
|
|
@@ -288,6 +301,16 @@ var RULES = {
|
|
|
288
301
|
defaultTimeoutMs: DEFAULT_TIMEOUT_MS,
|
|
289
302
|
canBlock: true
|
|
290
303
|
},
|
|
304
|
+
// Observation-only: nothing in the pipeline produces a decision or a block
|
|
305
|
+
// for an expansion, so it must not claim `canBlock`. The claim is not
|
|
306
|
+
// cosmetic — hook dispatch keeps every decision-capable event on Claude's
|
|
307
|
+
// critical path, so a false `canBlock` would make every slash command wait
|
|
308
|
+
// on the forwarder for a reply that is never sent.
|
|
309
|
+
"prompt.expansion": {
|
|
310
|
+
expectsDecision: false,
|
|
311
|
+
defaultTimeoutMs: DEFAULT_TIMEOUT_MS,
|
|
312
|
+
canBlock: false
|
|
313
|
+
},
|
|
291
314
|
"turn.start": {
|
|
292
315
|
expectsDecision: false,
|
|
293
316
|
defaultTimeoutMs: DEFAULT_TIMEOUT_MS,
|
|
@@ -420,6 +443,15 @@ function asRecord(value) {
|
|
|
420
443
|
}
|
|
421
444
|
return {};
|
|
422
445
|
}
|
|
446
|
+
function readToolBatchCalls(value) {
|
|
447
|
+
if (!Array.isArray(value)) return [];
|
|
448
|
+
return value.filter((entry) => typeof entry === "object" && entry !== null).map((entry) => asRecord(entry)).map((call) => ({
|
|
449
|
+
tool_name: call["tool_name"],
|
|
450
|
+
tool_input: call["tool_input"],
|
|
451
|
+
tool_use_id: call["tool_use_id"],
|
|
452
|
+
tool_response: call["tool_response"]
|
|
453
|
+
}));
|
|
454
|
+
}
|
|
423
455
|
function translateClaudeEnvelope(envelope) {
|
|
424
456
|
const payload = asRecord(envelope.payload);
|
|
425
457
|
let toolName;
|
|
@@ -444,7 +476,9 @@ function translateClaudeEnvelope(envelope) {
|
|
|
444
476
|
kind: "session.start",
|
|
445
477
|
data: {
|
|
446
478
|
source: payload["source"],
|
|
447
|
-
|
|
479
|
+
model: payload["model"],
|
|
480
|
+
agent_type: payload["agent_type"],
|
|
481
|
+
session_title: payload["session_title"]
|
|
448
482
|
}
|
|
449
483
|
};
|
|
450
484
|
case "SessionEnd":
|
|
@@ -458,6 +492,22 @@ function translateClaudeEnvelope(envelope) {
|
|
|
458
492
|
return {
|
|
459
493
|
kind: "user.prompt",
|
|
460
494
|
data: {
|
|
495
|
+
prompt: payload["prompt"],
|
|
496
|
+
cwd: payload["cwd"],
|
|
497
|
+
permission_mode: payload["permission_mode"]
|
|
498
|
+
}
|
|
499
|
+
};
|
|
500
|
+
// Fires immediately before UserPromptSubmit, sharing its prompt_id,
|
|
501
|
+
// when a typed command expands into a prompt. Field names are pinned
|
|
502
|
+
// to the payload captured in the #116 spike.
|
|
503
|
+
case "UserPromptExpansion":
|
|
504
|
+
return {
|
|
505
|
+
kind: "prompt.expansion",
|
|
506
|
+
data: {
|
|
507
|
+
expansion_type: payload["expansion_type"],
|
|
508
|
+
command_name: payload["command_name"],
|
|
509
|
+
command_args: payload["command_args"],
|
|
510
|
+
command_source: payload["command_source"],
|
|
461
511
|
prompt: payload["prompt"],
|
|
462
512
|
permission_mode: payload["permission_mode"]
|
|
463
513
|
}
|
|
@@ -485,6 +535,18 @@ function translateClaudeEnvelope(envelope) {
|
|
|
485
535
|
tool_response: payload["tool_response"]
|
|
486
536
|
}
|
|
487
537
|
};
|
|
538
|
+
// Fires once per assistant tool batch, after every PostToolUse in it.
|
|
539
|
+
// Field names are pinned to the payload captured in the #116 spike;
|
|
540
|
+
// note that `tool_calls[].tool_response` is a STRING there, unlike
|
|
541
|
+
// PostToolUse's structured `tool_response`.
|
|
542
|
+
case "PostToolBatch":
|
|
543
|
+
return {
|
|
544
|
+
kind: "tool.batch",
|
|
545
|
+
data: {
|
|
546
|
+
tool_calls: readToolBatchCalls(payload["tool_calls"]),
|
|
547
|
+
permission_mode: payload["permission_mode"]
|
|
548
|
+
}
|
|
549
|
+
};
|
|
488
550
|
case "PostToolUseFailure":
|
|
489
551
|
return {
|
|
490
552
|
kind: "tool.failure",
|
|
@@ -495,7 +557,10 @@ function translateClaudeEnvelope(envelope) {
|
|
|
495
557
|
tool_input: payload["tool_input"] ?? {},
|
|
496
558
|
tool_use_id: toolUseId,
|
|
497
559
|
error: payload["error"],
|
|
498
|
-
is_interrupt: payload["is_interrupt"]
|
|
560
|
+
is_interrupt: payload["is_interrupt"],
|
|
561
|
+
exit_code: payload["exit_code"],
|
|
562
|
+
output: payload["output"],
|
|
563
|
+
error_code: payload["error_code"]
|
|
499
564
|
}
|
|
500
565
|
};
|
|
501
566
|
case "PermissionRequest":
|
|
@@ -721,6 +786,12 @@ function buildClaudeDisplay(kind, data) {
|
|
|
721
786
|
}
|
|
722
787
|
|
|
723
788
|
// src/harnesses/claude/runtime/mapper.ts
|
|
789
|
+
function readEffortLevel(payload) {
|
|
790
|
+
const effort = payload["effort"];
|
|
791
|
+
if (typeof effort !== "object" || effort === null) return void 0;
|
|
792
|
+
const level = effort["level"];
|
|
793
|
+
return typeof level === "string" ? level : void 0;
|
|
794
|
+
}
|
|
724
795
|
function mapEnvelopeToRuntimeEvent(envelope) {
|
|
725
796
|
const payload = envelope.payload;
|
|
726
797
|
const safePayload = typeof payload === "object" && payload !== null ? payload : { value: payload };
|
|
@@ -738,6 +809,13 @@ function mapEnvelopeToRuntimeEvent(envelope) {
|
|
|
738
809
|
data: translated.data,
|
|
739
810
|
hookName: envelope.hook_event_name,
|
|
740
811
|
sessionId: envelope.session_id,
|
|
812
|
+
// prompt_id is a Claude common input field (v2.1.196+) on every hook
|
|
813
|
+
// payload; carried harness-neutrally as the Prompt identity (ADR 0009).
|
|
814
|
+
promptId: safePayloadRecord["prompt_id"],
|
|
815
|
+
// `effort` is likewise a common input field ({level}), observed on
|
|
816
|
+
// PostToolUse-class payloads and never on SessionStart, so it is read here
|
|
817
|
+
// rather than in any one hook's translation.
|
|
818
|
+
effortLevel: readEffortLevel(safePayloadRecord),
|
|
741
819
|
toolName: translated.toolName,
|
|
742
820
|
toolUseId: translated.toolUseId,
|
|
743
821
|
agentId: translated.agentId,
|
|
@@ -855,9 +933,23 @@ function extractResultText(content) {
|
|
|
855
933
|
}
|
|
856
934
|
return parts.join("\n");
|
|
857
935
|
}
|
|
858
|
-
function
|
|
936
|
+
function extractAssistantText(content) {
|
|
937
|
+
if (!Array.isArray(content)) return "";
|
|
938
|
+
const parts = [];
|
|
939
|
+
for (const block of content) {
|
|
940
|
+
if (typeof block === "object" && block !== null) {
|
|
941
|
+
const rec = block;
|
|
942
|
+
if (rec["type"] === "text" && typeof rec["text"] === "string") {
|
|
943
|
+
parts.push(rec["text"]);
|
|
944
|
+
}
|
|
945
|
+
}
|
|
946
|
+
}
|
|
947
|
+
return parts.join("");
|
|
948
|
+
}
|
|
949
|
+
function createStreamJsonToolParser(onToolResult, onToolUse, onMessageDelta, onMessageComplete) {
|
|
859
950
|
let buffer = "";
|
|
860
951
|
const toolNameById = /* @__PURE__ */ new Map();
|
|
952
|
+
let currentMessageId;
|
|
861
953
|
function processLine(line) {
|
|
862
954
|
const trimmed = line.trim();
|
|
863
955
|
if (!trimmed) return;
|
|
@@ -868,6 +960,19 @@ function createStreamJsonToolParser(onToolResult, onToolUse) {
|
|
|
868
960
|
return;
|
|
869
961
|
}
|
|
870
962
|
const record = parsed.type === "stream_event" && parsed.event ? parsed.event : parsed;
|
|
963
|
+
if (record.type === "message_start") {
|
|
964
|
+
const id = record.message?.["id"];
|
|
965
|
+
if (typeof id === "string") currentMessageId = id;
|
|
966
|
+
}
|
|
967
|
+
if (record.type === "content_block_delta") {
|
|
968
|
+
const delta = record["delta"];
|
|
969
|
+
if (typeof delta === "object" && delta !== null) {
|
|
970
|
+
const d = delta;
|
|
971
|
+
if (d["type"] === "text_delta" && typeof d["text"] === "string") {
|
|
972
|
+
onMessageDelta?.({ item_id: currentMessageId, delta: d["text"] });
|
|
973
|
+
}
|
|
974
|
+
}
|
|
975
|
+
}
|
|
871
976
|
const contentBlocks = (record.type === "assistant" ? record.message?.content : record.type === "message" && record.role === "assistant" ? record.content : void 0) ?? [];
|
|
872
977
|
for (const block of contentBlocks) {
|
|
873
978
|
if (typeof block !== "object" || block === null) continue;
|
|
@@ -877,6 +982,14 @@ function createStreamJsonToolParser(onToolResult, onToolUse) {
|
|
|
877
982
|
onToolUse?.({ tool_use_id: rec["id"], tool_name: rec["name"] });
|
|
878
983
|
}
|
|
879
984
|
}
|
|
985
|
+
if (record.type === "assistant" || record.type === "message" && record.role === "assistant") {
|
|
986
|
+
const messageText = extractAssistantText(contentBlocks);
|
|
987
|
+
if (messageText) {
|
|
988
|
+
const idValue = record.type === "assistant" ? record.message?.["id"] : record["id"];
|
|
989
|
+
const itemId = typeof idValue === "string" ? idValue : currentMessageId;
|
|
990
|
+
onMessageComplete?.({ item_id: itemId, message: messageText });
|
|
991
|
+
}
|
|
992
|
+
}
|
|
880
993
|
if (record.type === "tool_result") {
|
|
881
994
|
const toolUseId = typeof record.tool_use_id === "string" ? record.tool_use_id : void 0;
|
|
882
995
|
const text = extractResultText(record.content);
|
|
@@ -975,6 +1088,38 @@ function createServer2(opts) {
|
|
|
975
1088
|
},
|
|
976
1089
|
() => {
|
|
977
1090
|
transportStats.streamToolUses++;
|
|
1091
|
+
},
|
|
1092
|
+
(messageDelta) => {
|
|
1093
|
+
emit({
|
|
1094
|
+
id: `stream-msg-delta-${messageDelta.item_id ?? "unknown"}-${Date.now()}`,
|
|
1095
|
+
timestamp: Date.now(),
|
|
1096
|
+
kind: "message.delta",
|
|
1097
|
+
data: {
|
|
1098
|
+
item_id: messageDelta.item_id,
|
|
1099
|
+
delta: messageDelta.delta
|
|
1100
|
+
},
|
|
1101
|
+
hookName: "stream-json",
|
|
1102
|
+
sessionId,
|
|
1103
|
+
context: { cwd: projectDir, transcriptPath: "" },
|
|
1104
|
+
interaction: getInteractionHints("message.delta"),
|
|
1105
|
+
payload: null
|
|
1106
|
+
});
|
|
1107
|
+
},
|
|
1108
|
+
(messageComplete) => {
|
|
1109
|
+
emit({
|
|
1110
|
+
id: `stream-msg-complete-${messageComplete.item_id ?? "unknown"}-${Date.now()}`,
|
|
1111
|
+
timestamp: Date.now(),
|
|
1112
|
+
kind: "message.complete",
|
|
1113
|
+
data: {
|
|
1114
|
+
item_id: messageComplete.item_id,
|
|
1115
|
+
message: messageComplete.message
|
|
1116
|
+
},
|
|
1117
|
+
hookName: "stream-json",
|
|
1118
|
+
sessionId,
|
|
1119
|
+
context: { cwd: projectDir, transcriptPath: "" },
|
|
1120
|
+
interaction: getInteractionHints("message.complete"),
|
|
1121
|
+
payload: null
|
|
1122
|
+
});
|
|
978
1123
|
}
|
|
979
1124
|
);
|
|
980
1125
|
function emit(event) {
|
|
@@ -1375,6 +1520,10 @@ var TOOL_HOOK_EVENTS = [
|
|
|
1375
1520
|
"PreToolUse",
|
|
1376
1521
|
"PostToolUse",
|
|
1377
1522
|
"PostToolUseFailure",
|
|
1523
|
+
// Batch-level, not per-tool, but Claude accepts (and requires) a matcher
|
|
1524
|
+
// here: the #116 capture registered it with `matcher: '*'` and it fired in
|
|
1525
|
+
// every run. Matcher-less registration is unverified.
|
|
1526
|
+
"PostToolBatch",
|
|
1378
1527
|
"PermissionRequest",
|
|
1379
1528
|
"PermissionDenied",
|
|
1380
1529
|
"Elicitation",
|
|
@@ -1389,6 +1538,7 @@ var NON_TOOL_HOOK_EVENTS = [
|
|
|
1389
1538
|
"SubagentStart",
|
|
1390
1539
|
"SubagentStop",
|
|
1391
1540
|
"UserPromptSubmit",
|
|
1541
|
+
"UserPromptExpansion",
|
|
1392
1542
|
"PreCompact",
|
|
1393
1543
|
"PostCompact",
|
|
1394
1544
|
"Setup",
|
|
@@ -1401,6 +1551,27 @@ var NON_TOOL_HOOK_EVENTS = [
|
|
|
1401
1551
|
"WorktreeCreate",
|
|
1402
1552
|
"WorktreeRemove"
|
|
1403
1553
|
];
|
|
1554
|
+
var SYNC_HOOK_EVENTS = [
|
|
1555
|
+
// Decision/blocking — kept in step with `runtime/interactionRules.ts`.
|
|
1556
|
+
"PreToolUse",
|
|
1557
|
+
"PermissionRequest",
|
|
1558
|
+
"UserPromptSubmit",
|
|
1559
|
+
"Stop",
|
|
1560
|
+
"StopFailure",
|
|
1561
|
+
"SubagentStop",
|
|
1562
|
+
"Elicitation",
|
|
1563
|
+
"ElicitationResult",
|
|
1564
|
+
"TeammateIdle",
|
|
1565
|
+
"TaskCreated",
|
|
1566
|
+
"TaskCompleted",
|
|
1567
|
+
"ConfigChange",
|
|
1568
|
+
// Teardown — see (2) above.
|
|
1569
|
+
"SessionEnd"
|
|
1570
|
+
];
|
|
1571
|
+
var SYNC_HOOK_EVENT_SET = new Set(SYNC_HOOK_EVENTS);
|
|
1572
|
+
function isAsyncHookEvent(event) {
|
|
1573
|
+
return !SYNC_HOOK_EVENT_SET.has(event);
|
|
1574
|
+
}
|
|
1404
1575
|
function quoteShellArg(value) {
|
|
1405
1576
|
return `'${value.replace(/'/g, `'"'"'`)}'`;
|
|
1406
1577
|
}
|
|
@@ -1448,23 +1619,20 @@ function generateHookSettings(tempDir, authOverlay) {
|
|
|
1448
1619
|
if (process.env["ATHENA_DEBUG"]) {
|
|
1449
1620
|
console.error("[athena-debug] Hook forwarder path:", hookForwarder.command);
|
|
1450
1621
|
}
|
|
1451
|
-
const
|
|
1452
|
-
type: "command",
|
|
1453
|
-
command: hookForwarder.command
|
|
1454
|
-
};
|
|
1622
|
+
const hookCommandFor = (event) => isAsyncHookEvent(event) ? { type: "command", command: hookForwarder.command, async: true } : { type: "command", command: hookForwarder.command };
|
|
1455
1623
|
const hooks = {};
|
|
1456
1624
|
for (const event of TOOL_HOOK_EVENTS) {
|
|
1457
1625
|
hooks[event] = [
|
|
1458
1626
|
{
|
|
1459
1627
|
matcher: "*",
|
|
1460
|
-
hooks: [
|
|
1628
|
+
hooks: [hookCommandFor(event)]
|
|
1461
1629
|
}
|
|
1462
1630
|
];
|
|
1463
1631
|
}
|
|
1464
1632
|
for (const event of NON_TOOL_HOOK_EVENTS) {
|
|
1465
1633
|
hooks[event] = [
|
|
1466
1634
|
{
|
|
1467
|
-
hooks: [
|
|
1635
|
+
hooks: [hookCommandFor(event)]
|
|
1468
1636
|
}
|
|
1469
1637
|
];
|
|
1470
1638
|
}
|
|
@@ -2824,6 +2992,17 @@ import os8 from "os";
|
|
|
2824
2992
|
import path10 from "path";
|
|
2825
2993
|
|
|
2826
2994
|
// src/harnesses/claude/config/isolation.ts
|
|
2995
|
+
var CLAUDE_EFFORT_LEVELS = [
|
|
2996
|
+
"low",
|
|
2997
|
+
"medium",
|
|
2998
|
+
"high",
|
|
2999
|
+
"xhigh",
|
|
3000
|
+
"max"
|
|
3001
|
+
];
|
|
3002
|
+
function normalizeEffort(value) {
|
|
3003
|
+
if (value === void 0) return void 0;
|
|
3004
|
+
return CLAUDE_EFFORT_LEVELS.includes(value) ? value : void 0;
|
|
3005
|
+
}
|
|
2827
3006
|
var DISALLOWED_FIRST_PARTY_MCPS = [
|
|
2828
3007
|
"mcp__claude_ai_Gmail__*",
|
|
2829
3008
|
"mcp__claude_ai_Google_Calendar__*",
|
|
@@ -2934,6 +3113,7 @@ var FLAG_REGISTRY = [
|
|
|
2934
3113
|
{ field: "additionalDirectories", flag: "--add-dir", kind: "array" },
|
|
2935
3114
|
// === Model & Agent ===
|
|
2936
3115
|
{ field: "model", flag: "--model", kind: "value" },
|
|
3116
|
+
{ field: "effort", flag: "--effort", kind: "value" },
|
|
2937
3117
|
{ field: "fallbackModel", flag: "--fallback-model", kind: "value" },
|
|
2938
3118
|
{ field: "agent", flag: "--agent", kind: "value" },
|
|
2939
3119
|
{ field: "agents", flag: "--agents", kind: "json" },
|
|
@@ -3831,20 +4011,49 @@ function buildClaudeCompatibleIsolationConfig({
|
|
|
3831
4011
|
additionalDirectories,
|
|
3832
4012
|
pluginDirs,
|
|
3833
4013
|
verbose,
|
|
3834
|
-
configuredModel
|
|
4014
|
+
configuredModel,
|
|
4015
|
+
configuredEffort
|
|
3835
4016
|
}) {
|
|
3836
4017
|
return {
|
|
3837
4018
|
preset: isolationPreset,
|
|
3838
4019
|
additionalDirectories,
|
|
3839
4020
|
pluginDirs: pluginDirs.length > 0 ? pluginDirs : void 0,
|
|
3840
4021
|
debug: verbose,
|
|
3841
|
-
model: configuredModel
|
|
4022
|
+
model: configuredModel,
|
|
4023
|
+
effort: normalizeEffort(configuredEffort)
|
|
3842
4024
|
};
|
|
3843
4025
|
}
|
|
4026
|
+
var CLAUDE_MODEL_OPTIONS = [
|
|
4027
|
+
{
|
|
4028
|
+
value: "sonnet",
|
|
4029
|
+
label: "Sonnet",
|
|
4030
|
+
description: "Balanced default for day-to-day coding work."
|
|
4031
|
+
},
|
|
4032
|
+
{
|
|
4033
|
+
value: "opus",
|
|
4034
|
+
label: "Opus",
|
|
4035
|
+
description: "Stronger reasoning for complex architecture and debugging."
|
|
4036
|
+
},
|
|
4037
|
+
{
|
|
4038
|
+
value: "haiku",
|
|
4039
|
+
label: "Haiku",
|
|
4040
|
+
description: "Fastest option for lighter tasks."
|
|
4041
|
+
},
|
|
4042
|
+
{
|
|
4043
|
+
value: "opusplan",
|
|
4044
|
+
label: "OpusPlan",
|
|
4045
|
+
description: "Uses Opus for planning and Sonnet for execution."
|
|
4046
|
+
}
|
|
4047
|
+
];
|
|
3844
4048
|
var CLAUDE_CONFIG_PROFILE = {
|
|
3845
4049
|
harness: "claude-code",
|
|
3846
4050
|
buildIsolationConfig: buildClaudeCompatibleIsolationConfig,
|
|
3847
|
-
resolveModelName: ({ projectDir, configuredModel }) => resolveClaudeModel({ projectDir, configuredModel })
|
|
4051
|
+
resolveModelName: ({ projectDir, configuredModel }) => resolveClaudeModel({ projectDir, configuredModel }),
|
|
4052
|
+
pluginDelivery: {
|
|
4053
|
+
mergeWorkflowPluginDirs: true,
|
|
4054
|
+
registrationBuildsMcpConfig: true,
|
|
4055
|
+
workflowPluginsVia: "registration"
|
|
4056
|
+
}
|
|
3848
4057
|
};
|
|
3849
4058
|
var claudeHarnessAdapter = {
|
|
3850
4059
|
id: "claude-code",
|
|
@@ -3854,7 +4063,9 @@ var claudeHarnessAdapter = {
|
|
|
3854
4063
|
conversationModel: "fresh_per_turn",
|
|
3855
4064
|
killWaitsForTurnSettlement: true,
|
|
3856
4065
|
supportsEphemeralSessions: false,
|
|
3857
|
-
supportsConfigurableIsolation: true
|
|
4066
|
+
supportsConfigurableIsolation: true,
|
|
4067
|
+
emitsStartupDiagnostics: true,
|
|
4068
|
+
extraAllowedTools: []
|
|
3858
4069
|
},
|
|
3859
4070
|
verify: () => verifyClaudeHarness(),
|
|
3860
4071
|
createRuntime: (input) => createClaudeHookRuntime({
|
|
@@ -3890,7 +4101,8 @@ var claudeHarnessAdapter = {
|
|
|
3890
4101
|
};
|
|
3891
4102
|
return controller;
|
|
3892
4103
|
},
|
|
3893
|
-
resolveConfigProfile: () => CLAUDE_CONFIG_PROFILE
|
|
4104
|
+
resolveConfigProfile: () => CLAUDE_CONFIG_PROFILE,
|
|
4105
|
+
listModels: async () => CLAUDE_MODEL_OPTIONS
|
|
3894
4106
|
};
|
|
3895
4107
|
|
|
3896
4108
|
// src/harnesses/codex/runtime/appServerManager.ts
|
|
@@ -7029,7 +7241,12 @@ var CODEX_CONFIG_PROFILE = {
|
|
|
7029
7241
|
preset: isolationPreset,
|
|
7030
7242
|
model: configuredModel
|
|
7031
7243
|
}),
|
|
7032
|
-
resolveModelName: ({ configuredModel }) => configuredModel ?? null
|
|
7244
|
+
resolveModelName: ({ configuredModel }) => configuredModel ?? null,
|
|
7245
|
+
pluginDelivery: {
|
|
7246
|
+
mergeWorkflowPluginDirs: false,
|
|
7247
|
+
registrationBuildsMcpConfig: false,
|
|
7248
|
+
workflowPluginsVia: "generated-mcp"
|
|
7249
|
+
}
|
|
7033
7250
|
};
|
|
7034
7251
|
var codexHarnessAdapter = {
|
|
7035
7252
|
id: "openai-codex",
|
|
@@ -7039,7 +7256,12 @@ var codexHarnessAdapter = {
|
|
|
7039
7256
|
conversationModel: "persistent_thread",
|
|
7040
7257
|
killWaitsForTurnSettlement: true,
|
|
7041
7258
|
supportsEphemeralSessions: true,
|
|
7042
|
-
supportsConfigurableIsolation: true
|
|
7259
|
+
supportsConfigurableIsolation: true,
|
|
7260
|
+
emitsStartupDiagnostics: false,
|
|
7261
|
+
// Codex auto-approves Bash/Edit (outside-sandbox commandExecution /
|
|
7262
|
+
// fileChange) and the scoped 'Permissions' capability, on top of the
|
|
7263
|
+
// shared 'mcp__*' baseline seeded via allowedTools (see buildInitialRules).
|
|
7264
|
+
extraAllowedTools: ["Permissions", "Bash", "Edit"]
|
|
7043
7265
|
},
|
|
7044
7266
|
verify: () => verifyCodexHarness(),
|
|
7045
7267
|
createRuntime: (input) => createCodexRuntime({
|
|
@@ -7066,8 +7288,23 @@ var codexHarnessAdapter = {
|
|
|
7066
7288
|
};
|
|
7067
7289
|
return controller;
|
|
7068
7290
|
},
|
|
7069
|
-
resolveConfigProfile: () => CODEX_CONFIG_PROFILE
|
|
7291
|
+
resolveConfigProfile: () => CODEX_CONFIG_PROFILE,
|
|
7292
|
+
listModels: async (runtime) => {
|
|
7293
|
+
if (!isCodexRuntimeWithModels(runtime)) {
|
|
7294
|
+
throw new Error("Codex runtime is not available");
|
|
7295
|
+
}
|
|
7296
|
+
const models = await runtime.listModels();
|
|
7297
|
+
return models.map((model) => ({
|
|
7298
|
+
value: model.model,
|
|
7299
|
+
label: model.displayName,
|
|
7300
|
+
description: model.description,
|
|
7301
|
+
isDefault: model.isDefault
|
|
7302
|
+
}));
|
|
7303
|
+
}
|
|
7070
7304
|
};
|
|
7305
|
+
function isCodexRuntimeWithModels(runtime) {
|
|
7306
|
+
return Boolean(runtime && "listModels" in runtime);
|
|
7307
|
+
}
|
|
7071
7308
|
|
|
7072
7309
|
// src/harnesses/registry.ts
|
|
7073
7310
|
function buildClaudeCompatibleIsolationConfig2({
|
|
@@ -7093,7 +7330,9 @@ var opencodeHarnessAdapter = {
|
|
|
7093
7330
|
conversationModel: "fresh_per_turn",
|
|
7094
7331
|
killWaitsForTurnSettlement: true,
|
|
7095
7332
|
supportsEphemeralSessions: false,
|
|
7096
|
-
supportsConfigurableIsolation: false
|
|
7333
|
+
supportsConfigurableIsolation: false,
|
|
7334
|
+
emitsStartupDiagnostics: false,
|
|
7335
|
+
extraAllowedTools: []
|
|
7097
7336
|
},
|
|
7098
7337
|
createRuntime: (input) => claudeHarnessAdapter.createRuntime(input),
|
|
7099
7338
|
createSessionController: (input) => claudeHarnessAdapter.createSessionController(input),
|
|
@@ -7101,8 +7340,14 @@ var opencodeHarnessAdapter = {
|
|
|
7101
7340
|
resolveConfigProfile: () => ({
|
|
7102
7341
|
harness: "opencode",
|
|
7103
7342
|
buildIsolationConfig: (input) => buildClaudeCompatibleIsolationConfig2(input),
|
|
7104
|
-
resolveModelName: ({ configuredModel }) => configuredModel ?? null
|
|
7105
|
-
|
|
7343
|
+
resolveModelName: ({ configuredModel }) => configuredModel ?? null,
|
|
7344
|
+
pluginDelivery: {
|
|
7345
|
+
mergeWorkflowPluginDirs: true,
|
|
7346
|
+
registrationBuildsMcpConfig: true,
|
|
7347
|
+
workflowPluginsVia: "registration"
|
|
7348
|
+
}
|
|
7349
|
+
}),
|
|
7350
|
+
listModels: async () => []
|
|
7106
7351
|
};
|
|
7107
7352
|
var HARNESS_ADAPTERS = [
|
|
7108
7353
|
claudeHarnessAdapter,
|
|
@@ -7218,6 +7463,28 @@ function loadPlugin(pluginDir) {
|
|
|
7218
7463
|
}
|
|
7219
7464
|
return commands2;
|
|
7220
7465
|
}
|
|
7466
|
+
function loadPersonalSkills(skills) {
|
|
7467
|
+
const commands2 = [];
|
|
7468
|
+
for (const skill of skills) {
|
|
7469
|
+
const skillPath = path12.join(skill.path, "SKILL.md");
|
|
7470
|
+
if (!fs14.existsSync(skillPath)) {
|
|
7471
|
+
console.warn(
|
|
7472
|
+
`Skipping personal skill '${skill.name}' [${skill.sourceLayer}]: SKILL.md not found at ${skill.path}`
|
|
7473
|
+
);
|
|
7474
|
+
continue;
|
|
7475
|
+
}
|
|
7476
|
+
try {
|
|
7477
|
+
const parsed = parseFrontmatter(fs14.readFileSync(skillPath, "utf-8"));
|
|
7478
|
+
commands2.push(skillToCommand(parsed.frontmatter, parsed.body));
|
|
7479
|
+
} catch (error) {
|
|
7480
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
7481
|
+
console.warn(
|
|
7482
|
+
`Skipping personal skill '${skill.name}' [${skill.sourceLayer}]: ${message}`
|
|
7483
|
+
);
|
|
7484
|
+
}
|
|
7485
|
+
}
|
|
7486
|
+
return commands2;
|
|
7487
|
+
}
|
|
7221
7488
|
function skillToCommand(frontmatter, body, mcpConfigPath) {
|
|
7222
7489
|
const args = frontmatter["argument-hint"] ? [
|
|
7223
7490
|
{
|
|
@@ -7241,8 +7508,9 @@ function skillToCommand(frontmatter, body, mcpConfigPath) {
|
|
|
7241
7508
|
}
|
|
7242
7509
|
|
|
7243
7510
|
// src/infra/plugins/register.ts
|
|
7244
|
-
function buildPluginMcpConfig(pluginDirs, mcpServerOptions) {
|
|
7511
|
+
function buildPluginMcpConfig(pluginDirs, mcpServerOptions, personalMcpServers = []) {
|
|
7245
7512
|
const mergedServers = {};
|
|
7513
|
+
const conflicts = [];
|
|
7246
7514
|
for (const dir of pluginDirs) {
|
|
7247
7515
|
const mcpPath = path13.join(dir, ".mcp.json");
|
|
7248
7516
|
if (!fs15.existsSync(mcpPath)) {
|
|
@@ -7268,22 +7536,99 @@ function buildPluginMcpConfig(pluginDirs, mcpServerOptions) {
|
|
|
7268
7536
|
mergedServers[serverName] = rest;
|
|
7269
7537
|
}
|
|
7270
7538
|
}
|
|
7539
|
+
for (const personal of personalMcpServers) {
|
|
7540
|
+
const { name, sourceLayer: _sourceLayer, ...server } = personal;
|
|
7541
|
+
if (name in mergedServers) {
|
|
7542
|
+
conflicts.push(personal);
|
|
7543
|
+
continue;
|
|
7544
|
+
}
|
|
7545
|
+
mergedServers[name] = server;
|
|
7546
|
+
}
|
|
7271
7547
|
if (Object.keys(mergedServers).length === 0) {
|
|
7272
|
-
return void 0;
|
|
7548
|
+
return { mcpConfig: void 0, conflicts };
|
|
7273
7549
|
}
|
|
7274
7550
|
const mcpConfig = path13.join(os10.tmpdir(), `athena-mcp-${process.pid}.json`);
|
|
7275
7551
|
fs15.writeFileSync(mcpConfig, JSON.stringify({ mcpServers: mergedServers }));
|
|
7276
|
-
return mcpConfig;
|
|
7552
|
+
return { mcpConfig, conflicts };
|
|
7277
7553
|
}
|
|
7278
|
-
function registerPlugins(pluginDirs, mcpServerOptions, includeMcpConfig = true) {
|
|
7554
|
+
function registerPlugins(pluginDirs, mcpServerOptions, includeMcpConfig = true, personalMcpServers = [], personalSkills = []) {
|
|
7279
7555
|
for (const dir of pluginDirs) {
|
|
7280
7556
|
const commands2 = loadPlugin(dir);
|
|
7281
7557
|
for (const command of commands2) {
|
|
7282
7558
|
register(command);
|
|
7283
7559
|
}
|
|
7284
7560
|
}
|
|
7285
|
-
const
|
|
7286
|
-
|
|
7561
|
+
const skillByName = new Map(personalSkills.map((skill) => [skill.name, skill]));
|
|
7562
|
+
const skillConflicts = [];
|
|
7563
|
+
for (const command of loadPersonalSkills(personalSkills)) {
|
|
7564
|
+
if (get(command.name)) {
|
|
7565
|
+
const shadowed = skillByName.get(command.name);
|
|
7566
|
+
if (shadowed) {
|
|
7567
|
+
skillConflicts.push(shadowed);
|
|
7568
|
+
}
|
|
7569
|
+
continue;
|
|
7570
|
+
}
|
|
7571
|
+
register(command);
|
|
7572
|
+
}
|
|
7573
|
+
const mcpResult = includeMcpConfig ? buildPluginMcpConfig(pluginDirs, mcpServerOptions, personalMcpServers) : { mcpConfig: void 0, conflicts: [] };
|
|
7574
|
+
return {
|
|
7575
|
+
mcpConfig: mcpResult.mcpConfig,
|
|
7576
|
+
conflicts: { mcpServers: mcpResult.conflicts, skills: skillConflicts }
|
|
7577
|
+
};
|
|
7578
|
+
}
|
|
7579
|
+
|
|
7580
|
+
// src/infra/plugins/pluginRefResolution.ts
|
|
7581
|
+
function resolvePluginDirs(entries) {
|
|
7582
|
+
const dirs = [];
|
|
7583
|
+
const warnings = [];
|
|
7584
|
+
for (const entry of entries) {
|
|
7585
|
+
if (!isMarketplaceRef(entry)) {
|
|
7586
|
+
dirs.push(entry);
|
|
7587
|
+
continue;
|
|
7588
|
+
}
|
|
7589
|
+
try {
|
|
7590
|
+
dirs.push(resolveMarketplacePlugin(entry));
|
|
7591
|
+
} catch (error) {
|
|
7592
|
+
warnings.push(`Skipping plugin "${entry}": ${error.message}`);
|
|
7593
|
+
}
|
|
7594
|
+
}
|
|
7595
|
+
return { dirs, warnings };
|
|
7596
|
+
}
|
|
7597
|
+
|
|
7598
|
+
// src/infra/capabilities/effective.ts
|
|
7599
|
+
function resolveEffectiveCapabilities(input) {
|
|
7600
|
+
const { globalConfig, projectConfig } = input;
|
|
7601
|
+
return {
|
|
7602
|
+
mcpServers: mergeMcpServers(
|
|
7603
|
+
globalConfig.mcpServers,
|
|
7604
|
+
projectConfig.mcpServers
|
|
7605
|
+
),
|
|
7606
|
+
skills: mergeSkills(globalConfig.skills, projectConfig.skills)
|
|
7607
|
+
};
|
|
7608
|
+
}
|
|
7609
|
+
function mergeMcpServers(global, project) {
|
|
7610
|
+
const projectNames = new Set(Object.keys(project ?? {}));
|
|
7611
|
+
const result = [];
|
|
7612
|
+
for (const [name, server] of Object.entries(global ?? {})) {
|
|
7613
|
+
if (projectNames.has(name)) continue;
|
|
7614
|
+
result.push({ name, ...server, sourceLayer: "global" });
|
|
7615
|
+
}
|
|
7616
|
+
for (const [name, server] of Object.entries(project ?? {})) {
|
|
7617
|
+
result.push({ name, ...server, sourceLayer: "project" });
|
|
7618
|
+
}
|
|
7619
|
+
return result;
|
|
7620
|
+
}
|
|
7621
|
+
function mergeSkills(global, project) {
|
|
7622
|
+
const projectNames = new Set((project ?? []).map((s) => s.name));
|
|
7623
|
+
const result = [];
|
|
7624
|
+
for (const skill of global ?? []) {
|
|
7625
|
+
if (projectNames.has(skill.name)) continue;
|
|
7626
|
+
result.push({ ...skill, sourceLayer: "global" });
|
|
7627
|
+
}
|
|
7628
|
+
for (const skill of project ?? []) {
|
|
7629
|
+
result.push({ ...skill, sourceLayer: "project" });
|
|
7630
|
+
}
|
|
7631
|
+
return result;
|
|
7287
7632
|
}
|
|
7288
7633
|
|
|
7289
7634
|
// src/setup/shouldResolveWorkflow.ts
|
|
@@ -7339,6 +7684,9 @@ function bootstrapRuntimeConfig({
|
|
|
7339
7684
|
const projectConfig = providedProjectConfig ?? readConfig(projectDir);
|
|
7340
7685
|
const warnings = [];
|
|
7341
7686
|
const harness = harnessOverride ?? projectConfig.harness ?? globalConfig.harness ?? DEFAULT_HARNESS;
|
|
7687
|
+
const harnessConfigProfile = resolveHarnessConfigProfile(harness);
|
|
7688
|
+
const pluginDelivery = harnessConfigProfile.pluginDelivery;
|
|
7689
|
+
const workflowPluginsAsGeneratedMcp = pluginDelivery.workflowPluginsVia === "generated-mcp";
|
|
7342
7690
|
const activeWorkflowSelection = resolveActiveWorkflow({
|
|
7343
7691
|
globalConfig,
|
|
7344
7692
|
projectConfig,
|
|
@@ -7361,34 +7709,45 @@ function bootstrapRuntimeConfig({
|
|
|
7361
7709
|
(plugin) => plugin.claudeArtifactDir
|
|
7362
7710
|
);
|
|
7363
7711
|
}
|
|
7712
|
+
const globalPluginResolution = resolvePluginDirs(globalConfig.plugins);
|
|
7713
|
+
const projectPluginResolution = resolvePluginDirs(projectConfig.plugins);
|
|
7714
|
+
warnings.push(
|
|
7715
|
+
...globalPluginResolution.warnings,
|
|
7716
|
+
...projectPluginResolution.warnings
|
|
7717
|
+
);
|
|
7364
7718
|
const pluginDirs = mergePluginDirs({
|
|
7365
|
-
workflowPluginDirs:
|
|
7366
|
-
globalPlugins:
|
|
7367
|
-
projectPlugins:
|
|
7719
|
+
workflowPluginDirs: pluginDelivery.mergeWorkflowPluginDirs ? workflowPluginDirs : [],
|
|
7720
|
+
globalPlugins: globalPluginResolution.dirs,
|
|
7721
|
+
projectPlugins: projectPluginResolution.dirs,
|
|
7368
7722
|
pluginFlags
|
|
7369
7723
|
});
|
|
7370
|
-
const
|
|
7724
|
+
const effectiveCapabilities = harness === "openai-codex" ? { mcpServers: [], skills: [] } : resolveEffectiveCapabilities({ globalConfig, projectConfig });
|
|
7725
|
+
const personalMcpServers = effectiveCapabilities.mcpServers;
|
|
7726
|
+
const personalSkills = effectiveCapabilities.skills;
|
|
7727
|
+
const pluginResult = pluginDirs.length > 0 || personalMcpServers.length > 0 || personalSkills.length > 0 ? registerPlugins(
|
|
7371
7728
|
pluginDirs,
|
|
7372
7729
|
workflowToResolve ? activeWorkflowConfig.workflowSelections?.[workflowToResolve]?.mcpServerOptions : void 0,
|
|
7373
|
-
|
|
7374
|
-
|
|
7375
|
-
|
|
7730
|
+
pluginDelivery.registrationBuildsMcpConfig,
|
|
7731
|
+
personalMcpServers,
|
|
7732
|
+
personalSkills
|
|
7733
|
+
) : { mcpConfig: void 0, conflicts: { mcpServers: [], skills: [] } };
|
|
7734
|
+
const workflowPluginMcpConfig = workflowPluginsAsGeneratedMcp ? buildPluginMcpConfig(
|
|
7376
7735
|
workflowPluginDirs,
|
|
7377
7736
|
workflowToResolve ? activeWorkflowConfig.workflowSelections?.[workflowToResolve]?.mcpServerOptions : void 0
|
|
7378
|
-
) : void 0;
|
|
7379
|
-
const pluginMcpConfig =
|
|
7737
|
+
).mcpConfig : void 0;
|
|
7738
|
+
const pluginMcpConfig = workflowPluginsAsGeneratedMcp ? void 0 : pluginResult.mcpConfig;
|
|
7380
7739
|
const activeWorkflow = resolvedWorkflow;
|
|
7381
7740
|
const additionalDirectories = [
|
|
7382
7741
|
...globalConfig.additionalDirectories,
|
|
7383
7742
|
...projectConfig.additionalDirectories
|
|
7384
7743
|
];
|
|
7385
|
-
const harnessConfigProfile = resolveHarnessConfigProfile(harness);
|
|
7386
7744
|
const workflowPlan = compileWorkflowPlan({
|
|
7387
7745
|
workflow: activeWorkflow,
|
|
7388
7746
|
resolvedPlugins: activeWorkflow && resolvedWorkflow?.name === activeWorkflow.name ? workflowResolvedPlugins : void 0,
|
|
7389
|
-
pluginMcpConfig:
|
|
7747
|
+
pluginMcpConfig: workflowPluginsAsGeneratedMcp && activeWorkflow && resolvedWorkflow?.name === activeWorkflow.name ? workflowPluginMcpConfig : pluginResult.mcpConfig
|
|
7390
7748
|
});
|
|
7391
7749
|
const configModel = projectConfig.model || globalConfig.model || activeWorkflow?.model;
|
|
7750
|
+
const configEffort = activeWorkflow?.effort;
|
|
7392
7751
|
let isolationPreset = initialIsolationPreset;
|
|
7393
7752
|
if (activeWorkflow?.isolation) {
|
|
7394
7753
|
const presetOrder = ["strict", "minimal", "permissive"];
|
|
@@ -7407,7 +7766,8 @@ function bootstrapRuntimeConfig({
|
|
|
7407
7766
|
additionalDirectories,
|
|
7408
7767
|
pluginDirs,
|
|
7409
7768
|
verbose,
|
|
7410
|
-
configuredModel: configModel
|
|
7769
|
+
configuredModel: configModel,
|
|
7770
|
+
configuredEffort: configEffort
|
|
7411
7771
|
});
|
|
7412
7772
|
const modelName = harnessConfigProfile.resolveModelName({
|
|
7413
7773
|
projectDir,
|
|
@@ -7423,6 +7783,9 @@ function bootstrapRuntimeConfig({
|
|
|
7423
7783
|
workflow: activeWorkflow,
|
|
7424
7784
|
workflowPlan,
|
|
7425
7785
|
modelName,
|
|
7786
|
+
personalMcpServers,
|
|
7787
|
+
personalSkills,
|
|
7788
|
+
capabilityConflicts: pluginResult.conflicts,
|
|
7426
7789
|
warnings
|
|
7427
7790
|
};
|
|
7428
7791
|
}
|
|
@@ -7635,8 +7998,10 @@ function generateTitle(event, ascii = false) {
|
|
|
7635
7998
|
}
|
|
7636
7999
|
function generateNeutralTitle(event, g) {
|
|
7637
8000
|
switch (event.kind) {
|
|
7638
|
-
case "session.start":
|
|
7639
|
-
|
|
8001
|
+
case "session.start": {
|
|
8002
|
+
const sessionTitle = event.data.session_title?.trim();
|
|
8003
|
+
return sessionTitle ? truncate(sessionTitle) : `Session started (${event.data.source})`;
|
|
8004
|
+
}
|
|
7640
8005
|
case "session.end":
|
|
7641
8006
|
return `Session ended (${event.data.reason})`;
|
|
7642
8007
|
case "run.start":
|
|
@@ -7645,6 +8010,8 @@ function generateNeutralTitle(event, g) {
|
|
|
7645
8010
|
return `Run ${event.data.status}`;
|
|
7646
8011
|
case "user.prompt":
|
|
7647
8012
|
return truncate(event.data.prompt);
|
|
8013
|
+
case "prompt.expansion":
|
|
8014
|
+
return event.data.command_name ? truncate(`Expanded /${event.data.command_name}`) : "Prompt expanded";
|
|
7648
8015
|
case "plan.update":
|
|
7649
8016
|
return truncate(
|
|
7650
8017
|
event.data.explanation || event.data.delta || "Plan updated"
|
|
@@ -7659,6 +8026,10 @@ function generateNeutralTitle(event, g) {
|
|
|
7659
8026
|
return `${g["tool.bullet"]} ${event.data.tool_name}`;
|
|
7660
8027
|
case "tool.post":
|
|
7661
8028
|
return `${g["tool.gutter"]} ${event.data.tool_name} result`;
|
|
8029
|
+
case "tool.batch": {
|
|
8030
|
+
const n = event.data.tool_calls.length;
|
|
8031
|
+
return `Batch of ${n} tool call${n === 1 ? "" : "s"}`;
|
|
8032
|
+
}
|
|
7662
8033
|
case "tool.failure":
|
|
7663
8034
|
return truncate(
|
|
7664
8035
|
`${g["status.blocked"]} ${event.data.tool_name} failed: ${event.data.error}`
|
|
@@ -7889,6 +8260,7 @@ function createRunLifecycle(boundary) {
|
|
|
7889
8260
|
let currentRun = null;
|
|
7890
8261
|
let seq = 0;
|
|
7891
8262
|
let runSeq = 0;
|
|
8263
|
+
let currentPromptId;
|
|
7892
8264
|
function getRunId() {
|
|
7893
8265
|
const sessId = currentSession?.session_id ?? "unknown";
|
|
7894
8266
|
return `${sessId}:R${runSeq}`;
|
|
@@ -7937,7 +8309,13 @@ function createRunLifecycle(boundary) {
|
|
|
7937
8309
|
);
|
|
7938
8310
|
}
|
|
7939
8311
|
function beginRun(runtimeEvent, triggerType = "other", promptPreview) {
|
|
7940
|
-
|
|
8312
|
+
const promptId = runtimeEvent.promptId;
|
|
8313
|
+
const isExplicitContextTrigger = triggerType === "resume" || triggerType === "clear" || triggerType === "compact";
|
|
8314
|
+
if (promptId !== void 0 && !isExplicitContextTrigger) {
|
|
8315
|
+
if (currentRun && promptId === currentPromptId) return [];
|
|
8316
|
+
} else if (promptId === void 0 && currentRun && triggerType === "other") {
|
|
8317
|
+
return [];
|
|
8318
|
+
}
|
|
7941
8319
|
const results = [];
|
|
7942
8320
|
const closeEvt = closeRunIntoEvent(runtimeEvent, "completed");
|
|
7943
8321
|
if (closeEvt) results.push(closeEvt);
|
|
@@ -7948,6 +8326,7 @@ function createRunLifecycle(boundary) {
|
|
|
7948
8326
|
triggerType,
|
|
7949
8327
|
promptPreview
|
|
7950
8328
|
);
|
|
8329
|
+
currentPromptId = promptId;
|
|
7951
8330
|
results.push(
|
|
7952
8331
|
makeEvent(
|
|
7953
8332
|
"run.start",
|
|
@@ -8027,6 +8406,7 @@ function createRunLifecycle(boundary) {
|
|
|
8027
8406
|
if (e.kind === "tool.failure") currentRun.counters.tool_failures++;
|
|
8028
8407
|
if (e.kind === "permission.request")
|
|
8029
8408
|
currentRun.counters.permission_requests++;
|
|
8409
|
+
if (e.prompt_id !== void 0) currentPromptId = e.prompt_id;
|
|
8030
8410
|
}
|
|
8031
8411
|
}
|
|
8032
8412
|
}
|
|
@@ -8538,6 +8918,15 @@ function toolUseCause(toolUseId, parentId) {
|
|
|
8538
8918
|
...parentId ? { parent_event_id: parentId } : {}
|
|
8539
8919
|
};
|
|
8540
8920
|
}
|
|
8921
|
+
function readToolBatchCalls2(value) {
|
|
8922
|
+
if (!Array.isArray(value)) return [];
|
|
8923
|
+
return value.filter((entry) => typeof entry === "object" && entry !== null).map((entry) => readObject(entry)).map((call) => ({
|
|
8924
|
+
tool_name: readString(call["tool_name"]),
|
|
8925
|
+
tool_input: readObject(call["tool_input"]),
|
|
8926
|
+
tool_use_id: readString(call["tool_use_id"]),
|
|
8927
|
+
tool_response: readString(call["tool_response"])
|
|
8928
|
+
}));
|
|
8929
|
+
}
|
|
8541
8930
|
function createToolProjection(args) {
|
|
8542
8931
|
const {
|
|
8543
8932
|
ensureRunArray,
|
|
@@ -8594,6 +8983,21 @@ function createToolProjection(args) {
|
|
|
8594
8983
|
return {
|
|
8595
8984
|
mapToolEvent(event, data) {
|
|
8596
8985
|
const results = ensureRunArray(event);
|
|
8986
|
+
if (event.kind === "tool.batch") {
|
|
8987
|
+
results.push(
|
|
8988
|
+
makeEvent(
|
|
8989
|
+
"tool.batch",
|
|
8990
|
+
"info",
|
|
8991
|
+
resolveToolActor(),
|
|
8992
|
+
{
|
|
8993
|
+
tool_calls: readToolBatchCalls2(data["tool_calls"]),
|
|
8994
|
+
permission_mode: readString(data["permission_mode"])
|
|
8995
|
+
},
|
|
8996
|
+
event
|
|
8997
|
+
)
|
|
8998
|
+
);
|
|
8999
|
+
return results;
|
|
9000
|
+
}
|
|
8597
9001
|
const toolUseId = resolveToolUseId(event, data);
|
|
8598
9002
|
const toolName = event.toolName ?? readString(data["tool_name"]) ?? "Unknown";
|
|
8599
9003
|
const toolInput = readObject(data["tool_input"]);
|
|
@@ -9372,7 +9776,8 @@ function createRunSessionProjection(args) {
|
|
|
9372
9776
|
{
|
|
9373
9777
|
source,
|
|
9374
9778
|
agent_type: readString(data["agent_type"]),
|
|
9375
|
-
model: readString(data["model"])
|
|
9779
|
+
model: readString(data["model"]),
|
|
9780
|
+
session_title: readString(data["session_title"])
|
|
9376
9781
|
},
|
|
9377
9782
|
event
|
|
9378
9783
|
)
|
|
@@ -9417,6 +9822,34 @@ function createRunSessionProjection(args) {
|
|
|
9417
9822
|
);
|
|
9418
9823
|
return results;
|
|
9419
9824
|
}
|
|
9825
|
+
if (event.kind === "prompt.expansion") {
|
|
9826
|
+
if (event.promptId !== void 0) {
|
|
9827
|
+
results.push(
|
|
9828
|
+
...ensureRunArray(
|
|
9829
|
+
event,
|
|
9830
|
+
"user_prompt_submit",
|
|
9831
|
+
readString(data["prompt"])?.slice(0, 80)
|
|
9832
|
+
)
|
|
9833
|
+
);
|
|
9834
|
+
}
|
|
9835
|
+
results.push(
|
|
9836
|
+
makeEvent(
|
|
9837
|
+
"prompt.expansion",
|
|
9838
|
+
"info",
|
|
9839
|
+
"user",
|
|
9840
|
+
{
|
|
9841
|
+
expansion_type: readString(data["expansion_type"]),
|
|
9842
|
+
command_name: readString(data["command_name"]),
|
|
9843
|
+
command_args: readString(data["command_args"]),
|
|
9844
|
+
command_source: readString(data["command_source"]),
|
|
9845
|
+
prompt: readString(data["prompt"]),
|
|
9846
|
+
permission_mode: event.context.permissionMode ?? readString(data["permission_mode"])
|
|
9847
|
+
},
|
|
9848
|
+
event
|
|
9849
|
+
)
|
|
9850
|
+
);
|
|
9851
|
+
return results;
|
|
9852
|
+
}
|
|
9420
9853
|
if (event.kind === "turn.start") {
|
|
9421
9854
|
agentMessageStream.clearPending();
|
|
9422
9855
|
const prompt = readString(data["prompt"]);
|
|
@@ -9649,6 +10082,7 @@ var RUN_SESSION_EVENT_KINDS = /* @__PURE__ */ new Set([
|
|
|
9649
10082
|
"session.start",
|
|
9650
10083
|
"session.end",
|
|
9651
10084
|
"user.prompt",
|
|
10085
|
+
"prompt.expansion",
|
|
9652
10086
|
"turn.start",
|
|
9653
10087
|
"message.delta",
|
|
9654
10088
|
"message.complete",
|
|
@@ -9661,6 +10095,7 @@ var TOOL_EVENT_KINDS = /* @__PURE__ */ new Set([
|
|
|
9661
10095
|
"tool.delta",
|
|
9662
10096
|
"tool.pre",
|
|
9663
10097
|
"tool.post",
|
|
10098
|
+
"tool.batch",
|
|
9664
10099
|
"tool.failure"
|
|
9665
10100
|
]);
|
|
9666
10101
|
var DECISION_EVENT_KINDS = /* @__PURE__ */ new Set([
|
|
@@ -9722,6 +10157,8 @@ function createFeedMapper(bootstrap) {
|
|
|
9722
10157
|
ts: runtimeEvent.timestamp,
|
|
9723
10158
|
session_id: runtimeEvent.sessionId,
|
|
9724
10159
|
run_id: runId,
|
|
10160
|
+
prompt_id: runtimeEvent.promptId,
|
|
10161
|
+
effort_level: runtimeEvent.effortLevel,
|
|
9725
10162
|
kind,
|
|
9726
10163
|
level,
|
|
9727
10164
|
actor_id: actorId,
|
|
@@ -9877,7 +10314,7 @@ function createFeedMapper(bootstrap) {
|
|
|
9877
10314
|
}
|
|
9878
10315
|
|
|
9879
10316
|
// src/infra/sessions/schema.ts
|
|
9880
|
-
var SCHEMA_VERSION =
|
|
10317
|
+
var SCHEMA_VERSION = 7;
|
|
9881
10318
|
var applySessionSchema = (db, fromVersion) => {
|
|
9882
10319
|
db.exec(`
|
|
9883
10320
|
CREATE TABLE IF NOT EXISTS session (
|
|
@@ -9907,6 +10344,10 @@ var applySessionSchema = (db, fromVersion) => {
|
|
|
9907
10344
|
actor_id TEXT NOT NULL,
|
|
9908
10345
|
timestamp INTEGER NOT NULL,
|
|
9909
10346
|
data JSON NOT NULL,
|
|
10347
|
+
-- Harness-native Prompt identity (Claude prompt_id): a nullable
|
|
10348
|
+
-- correlation key, NOT the Run identity (that stays run_id). Unset for
|
|
10349
|
+
-- pre-prompt bootstrap + harnesses/versions without it (ADR 0009).
|
|
10350
|
+
prompt_id TEXT,
|
|
9910
10351
|
FOREIGN KEY (runtime_event_id) REFERENCES runtime_events(id)
|
|
9911
10352
|
);
|
|
9912
10353
|
|
|
@@ -9960,6 +10401,11 @@ var applySessionSchema = (db, fromVersion) => {
|
|
|
9960
10401
|
CREATE INDEX IF NOT EXISTS idx_workflow_runs_session ON workflow_runs(session_id);
|
|
9961
10402
|
CREATE INDEX IF NOT EXISTS idx_outbox_due ON channel_outbox(next_attempt_at);
|
|
9962
10403
|
`);
|
|
10404
|
+
if (fromVersion === void 0 || fromVersion >= 7) {
|
|
10405
|
+
db.exec(
|
|
10406
|
+
"CREATE INDEX IF NOT EXISTS idx_feed_prompt ON feed_events(prompt_id);"
|
|
10407
|
+
);
|
|
10408
|
+
}
|
|
9963
10409
|
if (fromVersion === void 0) return;
|
|
9964
10410
|
if (fromVersion >= SCHEMA_VERSION) return;
|
|
9965
10411
|
if (fromVersion < 2) {
|
|
@@ -10022,6 +10468,14 @@ var applySessionSchema = (db, fromVersion) => {
|
|
|
10022
10468
|
UPDATE schema_version SET version = 6;
|
|
10023
10469
|
`);
|
|
10024
10470
|
}
|
|
10471
|
+
const versionAfterV6 = db.prepare("SELECT version FROM schema_version").get().version;
|
|
10472
|
+
if (versionAfterV6 === 6) {
|
|
10473
|
+
db.exec(`
|
|
10474
|
+
ALTER TABLE feed_events ADD COLUMN prompt_id TEXT;
|
|
10475
|
+
CREATE INDEX IF NOT EXISTS idx_feed_prompt ON feed_events(prompt_id);
|
|
10476
|
+
UPDATE schema_version SET version = 7;
|
|
10477
|
+
`);
|
|
10478
|
+
}
|
|
10025
10479
|
};
|
|
10026
10480
|
var SESSION_SCHEMA = {
|
|
10027
10481
|
version: SCHEMA_VERSION,
|
|
@@ -10078,8 +10532,8 @@ function createSessionStore(opts) {
|
|
|
10078
10532
|
VALUES (?, ?, ?, ?, ?, ?)`
|
|
10079
10533
|
);
|
|
10080
10534
|
const insertFeedEvent = db.prepare(
|
|
10081
|
-
`INSERT OR IGNORE INTO feed_events (event_id, runtime_event_id, seq, kind, run_id, actor_id, timestamp, data)
|
|
10082
|
-
VALUES (?, ?, ?, ?, ?, ?, ?, ?)`
|
|
10535
|
+
`INSERT OR IGNORE INTO feed_events (event_id, runtime_event_id, seq, kind, run_id, actor_id, timestamp, data, prompt_id)
|
|
10536
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)`
|
|
10083
10537
|
);
|
|
10084
10538
|
const insertAdapterSession = db.prepare(
|
|
10085
10539
|
`INSERT OR IGNORE INTO adapter_sessions (session_id, started_at)
|
|
@@ -10134,7 +10588,8 @@ function createSessionStore(opts) {
|
|
|
10134
10588
|
fe.run_id,
|
|
10135
10589
|
fe.actor_id,
|
|
10136
10590
|
fe.ts,
|
|
10137
|
-
JSON.stringify(fe)
|
|
10591
|
+
JSON.stringify(fe),
|
|
10592
|
+
fe.prompt_id ?? null
|
|
10138
10593
|
);
|
|
10139
10594
|
}
|
|
10140
10595
|
updateEventCount.run(feedEvents.length, opts.sessionId);
|
|
@@ -10150,7 +10605,8 @@ function createSessionStore(opts) {
|
|
|
10150
10605
|
fe.run_id,
|
|
10151
10606
|
fe.actor_id,
|
|
10152
10607
|
fe.ts,
|
|
10153
|
-
JSON.stringify(fe)
|
|
10608
|
+
JSON.stringify(fe),
|
|
10609
|
+
fe.prompt_id ?? null
|
|
10154
10610
|
);
|
|
10155
10611
|
}
|
|
10156
10612
|
updateEventCount.run(feedEvents.length, opts.sessionId);
|
|
@@ -11984,6 +12440,13 @@ var stopFailure = defaultRenderer(
|
|
|
11984
12440
|
var permissionDenied = defaultRenderer(
|
|
11985
12441
|
(event) => `${event.data.tool_name}${event.data.reason ? `: ${event.data.reason}` : ""}`
|
|
11986
12442
|
);
|
|
12443
|
+
var promptExpansion = defaultRenderer(
|
|
12444
|
+
(event) => event.data.command_name ? `/${event.data.command_name}${event.data.command_args ? ` ${event.data.command_args}` : ""}` : event.data.expansion_type ?? ""
|
|
12445
|
+
);
|
|
12446
|
+
var toolBatch = defaultRenderer((event) => {
|
|
12447
|
+
const names = event.data.tool_calls.map((call) => call.tool_name).filter((name) => Boolean(name));
|
|
12448
|
+
return names.length > 0 ? names.join(", ") : "";
|
|
12449
|
+
});
|
|
11987
12450
|
var elicitationRequest = defaultRenderer((event) => `elicitation from ${event.data.mcp_server}`);
|
|
11988
12451
|
var elicitationResult = defaultRenderer(
|
|
11989
12452
|
(event) => `${event.data.mcp_server} \u2192 ${event.data.action}`
|
|
@@ -12032,6 +12495,7 @@ var RENDERERS = {
|
|
|
12032
12495
|
"tool.delta": toolDelta,
|
|
12033
12496
|
"tool.pre": toolPre,
|
|
12034
12497
|
"tool.post": toolPost,
|
|
12498
|
+
"tool.batch": toolBatch,
|
|
12035
12499
|
"tool.failure": toolFailure,
|
|
12036
12500
|
"permission.request": permissionRequest,
|
|
12037
12501
|
"permission.decision": permissionDecision,
|
|
@@ -12071,6 +12535,7 @@ var RENDERERS = {
|
|
|
12071
12535
|
"worktree.remove": worktreeRemove,
|
|
12072
12536
|
"stop.failure": stopFailure,
|
|
12073
12537
|
"permission.denied": permissionDenied,
|
|
12538
|
+
"prompt.expansion": promptExpansion,
|
|
12074
12539
|
"elicitation.request": elicitationRequest,
|
|
12075
12540
|
"elicitation.result": elicitationResult,
|
|
12076
12541
|
"channel.permission.relayed": channelPermissionRelayed,
|
|
@@ -12912,6 +13377,7 @@ function resolveEventToolColumn(event) {
|
|
|
12912
13377
|
case "tool.delta":
|
|
12913
13378
|
case "tool.pre":
|
|
12914
13379
|
case "tool.post":
|
|
13380
|
+
case "tool.batch":
|
|
12915
13381
|
case "tool.failure":
|
|
12916
13382
|
case "permission.decision":
|
|
12917
13383
|
case "permission.denied":
|
|
@@ -12939,6 +13405,7 @@ function resolveEventToolColumn(event) {
|
|
|
12939
13405
|
case "todo.done":
|
|
12940
13406
|
case "agent.message":
|
|
12941
13407
|
case "teammate.idle":
|
|
13408
|
+
case "prompt.expansion":
|
|
12942
13409
|
case "task.created":
|
|
12943
13410
|
case "task.completed":
|
|
12944
13411
|
case "config.change":
|
|
@@ -13642,7 +14109,7 @@ function extractRelayQuestions(event) {
|
|
|
13642
14109
|
}
|
|
13643
14110
|
|
|
13644
14111
|
// src/app/channels/gatewayControlClient.ts
|
|
13645
|
-
import { readFileSync as
|
|
14112
|
+
import { readFileSync as readFileSync2 } from "fs";
|
|
13646
14113
|
|
|
13647
14114
|
// src/gateway/control/client.ts
|
|
13648
14115
|
import crypto from "crypto";
|
|
@@ -13750,6 +14217,7 @@ async function connect(opts) {
|
|
|
13750
14217
|
preHelloResolve = (frame) => {
|
|
13751
14218
|
clearTimeout(timer);
|
|
13752
14219
|
preHelloAbort = null;
|
|
14220
|
+
helloAcked = true;
|
|
13753
14221
|
resolve(frame);
|
|
13754
14222
|
};
|
|
13755
14223
|
preHelloAbort = (err) => {
|
|
@@ -13772,7 +14240,6 @@ async function connect(opts) {
|
|
|
13772
14240
|
}
|
|
13773
14241
|
throw new GatewayProtocolError(String(msg));
|
|
13774
14242
|
}
|
|
13775
|
-
helloAcked = true;
|
|
13776
14243
|
const request = async (kind, payload, reqOpts) => {
|
|
13777
14244
|
const requestId = crypto.randomUUID();
|
|
13778
14245
|
const envelope = {
|
|
@@ -13793,9 +14260,6 @@ async function connect(opts) {
|
|
|
13793
14260
|
);
|
|
13794
14261
|
connection.send(envelope);
|
|
13795
14262
|
const res = await responsePromise;
|
|
13796
|
-
if (res.request_id !== requestId) {
|
|
13797
|
-
throw new GatewayProtocolError("response request_id mismatch");
|
|
13798
|
-
}
|
|
13799
14263
|
if (!res.ok) {
|
|
13800
14264
|
throw new GatewayProtocolError(
|
|
13801
14265
|
`${res.error.code}: ${res.error.message}`,
|
|
@@ -13832,93 +14296,6 @@ function isStringRecord(v) {
|
|
|
13832
14296
|
return typeof v === "object" && v !== null && !Array.isArray(v);
|
|
13833
14297
|
}
|
|
13834
14298
|
|
|
13835
|
-
// src/gateway/transport/wsClient.ts
|
|
13836
|
-
import { WebSocket } from "ws";
|
|
13837
|
-
import { readFileSync as readFileSync2 } from "fs";
|
|
13838
|
-
function createWsClientTransport(opts) {
|
|
13839
|
-
return {
|
|
13840
|
-
kind: "ws",
|
|
13841
|
-
connect: () => connectWs(opts)
|
|
13842
|
-
};
|
|
13843
|
-
}
|
|
13844
|
-
function wsClientOptionsForEndpoint(input) {
|
|
13845
|
-
return {
|
|
13846
|
-
url: input.url,
|
|
13847
|
-
...input.timeoutMs !== void 0 ? { timeoutMs: input.timeoutMs } : {},
|
|
13848
|
-
...input.tlsCaPath !== void 0 ? { tlsCaPath: input.tlsCaPath } : {}
|
|
13849
|
-
};
|
|
13850
|
-
}
|
|
13851
|
-
async function connectWs(opts) {
|
|
13852
|
-
const timeoutMs = opts.timeoutMs ?? 5e3;
|
|
13853
|
-
const wsOpts = opts.tlsCaPath ? { ca: readFileSync2(opts.tlsCaPath) } : {};
|
|
13854
|
-
const ws = new WebSocket(opts.url, wsOpts);
|
|
13855
|
-
await new Promise((resolve, reject) => {
|
|
13856
|
-
const timer = setTimeout(() => {
|
|
13857
|
-
ws.close();
|
|
13858
|
-
reject(
|
|
13859
|
-
new TransportUnreachableError(`connect timed out after ${timeoutMs}ms`)
|
|
13860
|
-
);
|
|
13861
|
-
}, timeoutMs);
|
|
13862
|
-
ws.once("open", () => {
|
|
13863
|
-
clearTimeout(timer);
|
|
13864
|
-
resolve();
|
|
13865
|
-
});
|
|
13866
|
-
ws.once("error", (err) => {
|
|
13867
|
-
clearTimeout(timer);
|
|
13868
|
-
reject(
|
|
13869
|
-
new TransportUnreachableError(
|
|
13870
|
-
`gateway not reachable at ${opts.url}: ${err.message}`
|
|
13871
|
-
)
|
|
13872
|
-
);
|
|
13873
|
-
});
|
|
13874
|
-
});
|
|
13875
|
-
return createWsConnection(ws, opts.url);
|
|
13876
|
-
}
|
|
13877
|
-
function createWsConnection(ws, peer) {
|
|
13878
|
-
const frameHandlers = /* @__PURE__ */ new Set();
|
|
13879
|
-
const closeHandlers = /* @__PURE__ */ new Set();
|
|
13880
|
-
const errorHandlers = /* @__PURE__ */ new Set();
|
|
13881
|
-
ws.on("message", (data) => {
|
|
13882
|
-
let parsed;
|
|
13883
|
-
try {
|
|
13884
|
-
parsed = JSON.parse(data.toString());
|
|
13885
|
-
} catch {
|
|
13886
|
-
ws.close();
|
|
13887
|
-
return;
|
|
13888
|
-
}
|
|
13889
|
-
traceGatewayFrame("ws-client", peer, "in", parsed);
|
|
13890
|
-
for (const handler of frameHandlers) handler(parsed);
|
|
13891
|
-
});
|
|
13892
|
-
ws.on("error", (err) => {
|
|
13893
|
-
for (const handler of errorHandlers) handler(err);
|
|
13894
|
-
});
|
|
13895
|
-
ws.on("close", () => {
|
|
13896
|
-
for (const handler of closeHandlers) handler();
|
|
13897
|
-
});
|
|
13898
|
-
return {
|
|
13899
|
-
kind: "ws",
|
|
13900
|
-
peer,
|
|
13901
|
-
send: (frame) => {
|
|
13902
|
-
if (ws.readyState !== ws.OPEN) return;
|
|
13903
|
-
traceGatewayFrame("ws-client", peer, "out", frame);
|
|
13904
|
-
ws.send(JSON.stringify(frame));
|
|
13905
|
-
},
|
|
13906
|
-
close: () => ws.close(),
|
|
13907
|
-
onFrame: (cb) => {
|
|
13908
|
-
frameHandlers.add(cb);
|
|
13909
|
-
return () => frameHandlers.delete(cb);
|
|
13910
|
-
},
|
|
13911
|
-
onClose: (cb) => {
|
|
13912
|
-
closeHandlers.add(cb);
|
|
13913
|
-
return () => closeHandlers.delete(cb);
|
|
13914
|
-
},
|
|
13915
|
-
onError: (cb) => {
|
|
13916
|
-
errorHandlers.add(cb);
|
|
13917
|
-
return () => errorHandlers.delete(cb);
|
|
13918
|
-
}
|
|
13919
|
-
};
|
|
13920
|
-
}
|
|
13921
|
-
|
|
13922
14299
|
// src/app/channels/gatewayControlClient.ts
|
|
13923
14300
|
async function connectGatewayControlClient(opts) {
|
|
13924
14301
|
const loadToken = opts.loadToken ?? defaultLoadToken;
|
|
@@ -13940,7 +14317,7 @@ async function connectGatewayControlClient(opts) {
|
|
|
13940
14317
|
});
|
|
13941
14318
|
}
|
|
13942
14319
|
function defaultLoadToken(tokenPath) {
|
|
13943
|
-
return
|
|
14320
|
+
return readFileSync2(tokenPath, "utf8").trim();
|
|
13944
14321
|
}
|
|
13945
14322
|
|
|
13946
14323
|
// src/infra/config/gatewayClient.ts
|
|
@@ -15034,6 +15411,10 @@ function createExecOutputWriter(options) {
|
|
|
15034
15411
|
if (!options.verbose) return;
|
|
15035
15412
|
writeLine(options.stderr, `[athena exec] ${message}`);
|
|
15036
15413
|
},
|
|
15414
|
+
notice(message) {
|
|
15415
|
+
if (options.json) return;
|
|
15416
|
+
writeLine(options.stderr, `[athena exec] ${message}`);
|
|
15417
|
+
},
|
|
15037
15418
|
warn(message) {
|
|
15038
15419
|
writeLine(options.stderr, `[athena exec] warning: ${message}`);
|
|
15039
15420
|
},
|
|
@@ -15062,6 +15443,34 @@ var NULL_TOKENS3 = {
|
|
|
15062
15443
|
contextSize: null,
|
|
15063
15444
|
contextWindowSize: null
|
|
15064
15445
|
};
|
|
15446
|
+
function formatPersonalCapabilityNotice(summary) {
|
|
15447
|
+
const parts = [];
|
|
15448
|
+
if (summary.mcpServers.length > 0) {
|
|
15449
|
+
const list = summary.mcpServers.map((server) => `${server.name} [${server.sourceLayer}]`).join(", ");
|
|
15450
|
+
parts.push(`mcp servers: ${list}`);
|
|
15451
|
+
}
|
|
15452
|
+
if (summary.skills.length > 0) {
|
|
15453
|
+
const list = summary.skills.map((skill) => `${skill.name} [${skill.sourceLayer}]`).join(", ");
|
|
15454
|
+
parts.push(`skills: ${list}`);
|
|
15455
|
+
}
|
|
15456
|
+
if (parts.length === 0) return null;
|
|
15457
|
+
return `personal capabilities active \u2014 ${parts.join("; ")}`;
|
|
15458
|
+
}
|
|
15459
|
+
function formatCapabilityConflictNotice(summary) {
|
|
15460
|
+
const parts = [];
|
|
15461
|
+
if (summary.mcpServers.length > 0) {
|
|
15462
|
+
const list = summary.mcpServers.map((server) => `${server.name} [${server.sourceLayer}]`).join(", ");
|
|
15463
|
+
parts.push(`mcp servers: ${list}`);
|
|
15464
|
+
}
|
|
15465
|
+
if (summary.skills.length > 0) {
|
|
15466
|
+
const list = summary.skills.map((skill) => `${skill.name} [${skill.sourceLayer}]`).join(", ");
|
|
15467
|
+
parts.push(`skills: ${list}`);
|
|
15468
|
+
}
|
|
15469
|
+
if (parts.length === 0) return null;
|
|
15470
|
+
return `personal capability conflicts \u2014 workflow plugin wins; shadowed: ${parts.join(
|
|
15471
|
+
"; "
|
|
15472
|
+
)}`;
|
|
15473
|
+
}
|
|
15065
15474
|
function workflowFailure(state, message) {
|
|
15066
15475
|
return {
|
|
15067
15476
|
kind: "workflow",
|
|
@@ -15336,11 +15745,29 @@ async function runExec(options) {
|
|
|
15336
15745
|
});
|
|
15337
15746
|
}, options.timeoutMs);
|
|
15338
15747
|
}
|
|
15748
|
+
const personalCapabilities = options.personalCapabilities ?? {
|
|
15749
|
+
mcpServers: [],
|
|
15750
|
+
skills: []
|
|
15751
|
+
};
|
|
15752
|
+
const capabilityConflicts = options.capabilityConflicts ?? {
|
|
15753
|
+
mcpServers: [],
|
|
15754
|
+
skills: []
|
|
15755
|
+
};
|
|
15339
15756
|
output.emitJsonEvent("exec.started", {
|
|
15340
15757
|
projectDir: options.projectDir,
|
|
15341
15758
|
harness: options.harness,
|
|
15342
|
-
athenaSessionId: options.ephemeral ? null : athenaSessionId
|
|
15759
|
+
athenaSessionId: options.ephemeral ? null : athenaSessionId,
|
|
15760
|
+
personalCapabilities,
|
|
15761
|
+
capabilityConflicts
|
|
15343
15762
|
});
|
|
15763
|
+
const personalCapabilityNotice = formatPersonalCapabilityNotice(personalCapabilities);
|
|
15764
|
+
if (personalCapabilityNotice) {
|
|
15765
|
+
output.notice(personalCapabilityNotice);
|
|
15766
|
+
}
|
|
15767
|
+
const capabilityConflictNotice = formatCapabilityConflictNotice(capabilityConflicts);
|
|
15768
|
+
if (capabilityConflictNotice) {
|
|
15769
|
+
output.notice(capabilityConflictNotice);
|
|
15770
|
+
}
|
|
15344
15771
|
try {
|
|
15345
15772
|
await runtime.start();
|
|
15346
15773
|
runtimeStarted = true;
|
|
@@ -15497,7 +15924,7 @@ async function runExec(options) {
|
|
|
15497
15924
|
}
|
|
15498
15925
|
|
|
15499
15926
|
// src/app/dashboard/instanceSocketClient.ts
|
|
15500
|
-
import { WebSocket
|
|
15927
|
+
import { WebSocket } from "ws";
|
|
15501
15928
|
var DEFAULT_HEARTBEAT_MS = 3e4;
|
|
15502
15929
|
var DEFAULT_CONNECT_TIMEOUT_MS = 1e4;
|
|
15503
15930
|
function instanceSocketUrl(dashboardUrl, instanceId) {
|
|
@@ -15514,7 +15941,7 @@ function createInstanceSocketClient(opts) {
|
|
|
15514
15941
|
const log = opts.log ?? (() => {
|
|
15515
15942
|
});
|
|
15516
15943
|
const now = opts.now ?? (() => Date.now());
|
|
15517
|
-
const makeWebSocket = opts.makeWebSocket ?? ((url, accessToken) => new
|
|
15944
|
+
const makeWebSocket = opts.makeWebSocket ?? ((url, accessToken) => new WebSocket(url, [accessToken]));
|
|
15518
15945
|
const frameHandlers = /* @__PURE__ */ new Set();
|
|
15519
15946
|
const closeHandlers = /* @__PURE__ */ new Set();
|
|
15520
15947
|
let ws = null;
|
|
@@ -15714,7 +16141,7 @@ function normalizeHarnessOverride(value) {
|
|
|
15714
16141
|
}
|
|
15715
16142
|
|
|
15716
16143
|
// src/app/dashboard/runStreamClient.ts
|
|
15717
|
-
import { WebSocket as
|
|
16144
|
+
import { WebSocket as WebSocket2 } from "ws";
|
|
15718
16145
|
var DEFAULT_RECONNECT_DELAYS_MS = [250, 1e3, 2e3, 5e3, 15e3];
|
|
15719
16146
|
var DEFAULT_HEARTBEAT_MS2 = 3e4;
|
|
15720
16147
|
var DEFAULT_WATCHDOG_MS = 9e4;
|
|
@@ -15727,7 +16154,7 @@ function createRunStreamClient(opts) {
|
|
|
15727
16154
|
const heartbeatMs = opts.heartbeatIntervalMs ?? DEFAULT_HEARTBEAT_MS2;
|
|
15728
16155
|
const watchdogMs = opts.watchdogTimeoutMs ?? DEFAULT_WATCHDOG_MS;
|
|
15729
16156
|
const maxQueueSize = opts.maxQueueSize ?? DEFAULT_MAX_QUEUE_SIZE;
|
|
15730
|
-
const makeWebSocket = opts.makeWebSocket ?? ((url) => new
|
|
16157
|
+
const makeWebSocket = opts.makeWebSocket ?? ((url) => new WebSocket2(url));
|
|
15731
16158
|
const setTimer = opts.setTimer ?? ((fn, ms) => setTimeout(fn, ms));
|
|
15732
16159
|
const clearTimer = opts.clearTimer ?? ((t) => clearTimeout(t));
|
|
15733
16160
|
let nextSeq = 1;
|
|
@@ -18092,8 +18519,6 @@ export {
|
|
|
18092
18519
|
GatewayUnreachableError,
|
|
18093
18520
|
GatewayUnauthorizedError,
|
|
18094
18521
|
connect,
|
|
18095
|
-
createWsClientTransport,
|
|
18096
|
-
wsClientOptionsForEndpoint,
|
|
18097
18522
|
isSupportedGatewayUrl,
|
|
18098
18523
|
readGatewayClientConfig,
|
|
18099
18524
|
writeGatewayClientConfig,
|
|
@@ -18121,6 +18546,8 @@ export {
|
|
|
18121
18546
|
isBashToolResponse,
|
|
18122
18547
|
resolveToolColumn,
|
|
18123
18548
|
IndexedTimeline,
|
|
18549
|
+
parseFrontmatter,
|
|
18550
|
+
resolveEffectiveCapabilities,
|
|
18124
18551
|
bootstrapRuntimeConfig,
|
|
18125
18552
|
EXEC_EXIT_CODE,
|
|
18126
18553
|
runExec,
|
|
@@ -18133,4 +18560,4 @@ export {
|
|
|
18133
18560
|
startUdsServer,
|
|
18134
18561
|
sendUdsRequest
|
|
18135
18562
|
};
|
|
18136
|
-
//# sourceMappingURL=chunk-
|
|
18563
|
+
//# sourceMappingURL=chunk-YZ7RCBKO.js.map
|