agent-relay-server 0.123.0 → 0.123.2
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/README.md +3 -1
- package/docs/openapi.json +1 -1
- package/package.json +3 -2
- package/public/assets/MessageBubble-NCggGKTA.js +2 -0
- package/public/assets/{MessageBubble-BTeFExjj.js.map → MessageBubble-NCggGKTA.js.map} +1 -1
- package/public/assets/{PlanGraphPanel-jU1DXg7w.js → PlanGraphPanel-CSdszmGk.js} +2 -2
- package/public/assets/{PlanGraphPanel-jU1DXg7w.js.map → PlanGraphPanel-CSdszmGk.js.map} +1 -1
- package/public/assets/{activity-DUig2iYW.js → activity-Cyp2nolX.js} +2 -2
- package/public/assets/{activity-DUig2iYW.js.map → activity-Cyp2nolX.js.map} +1 -1
- package/public/assets/{agent-profiles-D-oFmb6S.js → agent-profiles-D5Izg0Vn.js} +2 -2
- package/public/assets/{agent-profiles-D-oFmb6S.js.map → agent-profiles-D5Izg0Vn.js.map} +1 -1
- package/public/assets/{agent-type-icon-Dan2l3Tm.js → agent-type-icon-BxUopALO.js} +2 -2
- package/public/assets/{agent-type-icon-Dan2l3Tm.js.map → agent-type-icon-BxUopALO.js.map} +1 -1
- package/public/assets/agents-DIOxuJ6M.js +2 -0
- package/public/assets/{agents-BkC6mcTh.js.map → agents-DIOxuJ6M.js.map} +1 -1
- package/public/assets/{analytics-C3Dlmqe9.js → analytics-DqAuUAwX.js} +3 -3
- package/public/assets/{analytics-C3Dlmqe9.js.map → analytics-DqAuUAwX.js.map} +1 -1
- package/public/assets/{automation-AeMZ70WQ.js → automation-Bn6mOLAR.js} +2 -2
- package/public/assets/{automation-AeMZ70WQ.js.map → automation-Bn6mOLAR.js.map} +1 -1
- package/public/assets/{badge-DCIT3Irj.js → badge-XEru6wto.js} +2 -2
- package/public/assets/{badge-DCIT3Irj.js.map → badge-XEru6wto.js.map} +1 -1
- package/public/assets/branch-state-badge-Mf0Ow77K.js +2 -0
- package/public/assets/{branch-state-badge-CNW10MTC.js.map → branch-state-badge-Mf0Ow77K.js.map} +1 -1
- package/public/assets/{button-CzdTkRIf.js → button-C3CQSr4p.js} +2 -2
- package/public/assets/{button-CzdTkRIf.js.map → button-C3CQSr4p.js.map} +1 -1
- package/public/assets/card-C5XTIPvq.js +2 -0
- package/public/assets/{card-C3BGuVC6.js.map → card-C5XTIPvq.js.map} +1 -1
- package/public/assets/{channels-Bc_mEd56.js → channels-DVRkVeky.js} +2 -2
- package/public/assets/{channels-Bc_mEd56.js.map → channels-DVRkVeky.js.map} +1 -1
- package/public/assets/chat-eUaPz399.js +2 -0
- package/public/assets/{chat-BCNCuTgw.js.map → chat-eUaPz399.js.map} +1 -1
- package/public/assets/{connectors-h0d5Mc6e.js → connectors-Cqubkw9C.js} +2 -2
- package/public/assets/{connectors-h0d5Mc6e.js.map → connectors-Cqubkw9C.js.map} +1 -1
- package/public/assets/copy-button-Bil2CjzT.js +2 -0
- package/public/assets/{copy-button-B3o1jpLu.js.map → copy-button-Bil2CjzT.js.map} +1 -1
- package/public/assets/{dist-OUPTEP6q.js → dist-4VwhnLtj.js} +2 -2
- package/public/assets/{dist-OUPTEP6q.js.map → dist-4VwhnLtj.js.map} +1 -1
- package/public/assets/{dist-BIjlN-xB.js → dist-B8tD9ZcR.js} +2 -2
- package/public/assets/{dist-BIjlN-xB.js.map → dist-B8tD9ZcR.js.map} +1 -1
- package/public/assets/{dist-BInckSJC.js → dist-BJaV2BD4.js} +2 -2
- package/public/assets/{dist-BInckSJC.js.map → dist-BJaV2BD4.js.map} +1 -1
- package/public/assets/{dist-B-T7lg0a.js → dist-C5z05Vkz.js} +2 -2
- package/public/assets/{dist-B-T7lg0a.js.map → dist-C5z05Vkz.js.map} +1 -1
- package/public/assets/dist-CFtFIhu3.js +2 -0
- package/public/assets/{dist-DT-OV6sQ.js.map → dist-CFtFIhu3.js.map} +1 -1
- package/public/assets/{dist-C7aTlosb.js → dist-CGaHpxnN.js} +2 -2
- package/public/assets/{dist-C7aTlosb.js.map → dist-CGaHpxnN.js.map} +1 -1
- package/public/assets/dist-CjyfQThq.js +2 -0
- package/public/assets/{dist-DGfp5dLz.js.map → dist-CjyfQThq.js.map} +1 -1
- package/public/assets/dist-CrUl2aQp.js +2 -0
- package/public/assets/{dist-B6woQ9Tb.js.map → dist-CrUl2aQp.js.map} +1 -1
- package/public/assets/{dist-B3e4B9pg.js → dist-DKmTXfpP.js} +2 -2
- package/public/assets/{dist-B3e4B9pg.js.map → dist-DKmTXfpP.js.map} +1 -1
- package/public/assets/{dist-B9G83DXv.js → dist-V3wu3BHw.js} +2 -2
- package/public/assets/{dist-B9G83DXv.js.map → dist-V3wu3BHw.js.map} +1 -1
- package/public/assets/{dist-BlzVGRhh.js → dist-r8wyUTkK.js} +2 -2
- package/public/assets/{dist-BlzVGRhh.js.map → dist-r8wyUTkK.js.map} +1 -1
- package/public/assets/{es2015-CnKXYKpf.js → es2015-5DTJe35n.js} +2 -2
- package/public/assets/{es2015-CnKXYKpf.js.map → es2015-5DTJe35n.js.map} +1 -1
- package/public/assets/formatted-body-CvrQ2D1J.js +3 -0
- package/public/assets/{formatted-body-CVr3Iev9.js.map → formatted-body-CvrQ2D1J.js.map} +1 -1
- package/public/assets/{formatted-body-impl-Cq5SRGpm.js → formatted-body-impl-BJ7jdbpR.js} +2 -2
- package/public/assets/{formatted-body-impl-Cq5SRGpm.js.map → formatted-body-impl-BJ7jdbpR.js.map} +1 -1
- package/public/assets/index-DnUo0Zqg.js +25 -0
- package/public/assets/index-DnUo0Zqg.js.map +1 -0
- package/public/assets/{input-B6Q0NWCS.js → input-CXMbJ848.js} +2 -2
- package/public/assets/{input-B6Q0NWCS.js.map → input-CXMbJ848.js.map} +1 -1
- package/public/assets/{insights-C8lIBXg3.js → insights-CQGH5LhD.js} +2 -2
- package/public/assets/{insights-C8lIBXg3.js.map → insights-CQGH5LhD.js.map} +1 -1
- package/public/assets/{integrations-7OFsJtY7.js → integrations-9G5TJnnU.js} +2 -2
- package/public/assets/{integrations-7OFsJtY7.js.map → integrations-9G5TJnnU.js.map} +1 -1
- package/public/assets/{lib-BHsWPMKB.js → lib-BcUW1l-W.js} +2 -2
- package/public/assets/{lib-BHsWPMKB.js.map → lib-BcUW1l-W.js.map} +1 -1
- package/public/assets/lucide-react-CoU_Xts2.js +10 -0
- package/public/assets/{lucide-react-DuhlF2Sj.js.map → lucide-react-CoU_Xts2.js.map} +1 -1
- package/public/assets/maintenance-7c7UvpAt.js +2 -0
- package/public/assets/{maintenance-HDpg20OY.js.map → maintenance-7c7UvpAt.js.map} +1 -1
- package/public/assets/{managed-agents-muCIMxng.js → managed-agents-yh4HPO5a.js} +4 -4
- package/public/assets/{managed-agents-muCIMxng.js.map → managed-agents-yh4HPO5a.js.map} +1 -1
- package/public/assets/{markdown-preview-impl-Cx7pCfA6.js → markdown-preview-impl-BuOn5-Uc.js} +2 -2
- package/public/assets/{markdown-preview-impl-Cx7pCfA6.js.map → markdown-preview-impl-BuOn5-Uc.js.map} +1 -1
- package/public/assets/memory-Qv0JN8CE.js +2 -0
- package/public/assets/{memory-CTO1FfJ-.js.map → memory-Qv0JN8CE.js.map} +1 -1
- package/public/assets/messages-CgjHJmc2.js +2 -0
- package/public/assets/{messages-RWSXG2UM.js.map → messages-CgjHJmc2.js.map} +1 -1
- package/public/assets/{orchestrators-5aiYw3yx.js → orchestrators-CgL4CFzb.js} +2 -2
- package/public/assets/{orchestrators-5aiYw3yx.js.map → orchestrators-CgL4CFzb.js.map} +1 -1
- package/public/assets/{overview-Du6XLt5l.js → overview-Bri04eYE.js} +2 -2
- package/public/assets/{overview-Du6XLt5l.js.map → overview-Bri04eYE.js.map} +1 -1
- package/public/assets/{pairs-BDRnlEta.js → pairs-C78LwUH2.js} +2 -2
- package/public/assets/{pairs-BDRnlEta.js.map → pairs-C78LwUH2.js.map} +1 -1
- package/public/assets/{projects-DwsWE9es.js → projects-CquHTMo1.js} +2 -2
- package/public/assets/{projects-DwsWE9es.js.map → projects-CquHTMo1.js.map} +1 -1
- package/public/assets/prompt-settings-DDEkMqPZ.js +2 -0
- package/public/assets/{prompt-settings-CaJX_LbA.js.map → prompt-settings-DDEkMqPZ.js.map} +1 -1
- package/public/assets/{react-dom-DWBmcawP.js → react-dom-BQICbUuF.js} +2 -2
- package/public/assets/{react-dom-DWBmcawP.js.map → react-dom-BQICbUuF.js.map} +1 -1
- package/public/assets/registry-5KhP5FE5.js +2 -0
- package/public/assets/registry-5KhP5FE5.js.map +1 -0
- package/public/assets/{security-BpVrdYhJ.js → security-wvnRKFvm.js} +2 -2
- package/public/assets/{security-BpVrdYhJ.js.map → security-wvnRKFvm.js.map} +1 -1
- package/public/assets/{select-DallbU93.js → select-BIfbVmLf.js} +2 -2
- package/public/assets/{select-DallbU93.js.map → select-BIfbVmLf.js.map} +1 -1
- package/public/assets/settings-B6Ntahx7.js +6 -0
- package/public/assets/{settings-BUQirdyI.js.map → settings-B6Ntahx7.js.map} +1 -1
- package/public/assets/{store-DMZSTozC.js → store-zFLzd0Jd.js} +5 -5
- package/public/assets/{store-DMZSTozC.js.map → store-zFLzd0Jd.js.map} +1 -1
- package/public/assets/{task-chip-DXfvXBDx.js → task-chip-BHM-e3I8.js} +2 -2
- package/public/assets/{task-chip-DXfvXBDx.js.map → task-chip-BHM-e3I8.js.map} +1 -1
- package/public/assets/{tasks-k8mQDfKy.js → tasks-CUglafo5.js} +2 -2
- package/public/assets/{tasks-k8mQDfKy.js.map → tasks-CUglafo5.js.map} +1 -1
- package/public/assets/{teams-DI-Lhhbl.js → teams-EE8RHhHM.js} +2 -2
- package/public/assets/{teams-DI-Lhhbl.js.map → teams-EE8RHhHM.js.map} +1 -1
- package/public/assets/{terminal-viewer-impl-BL853Fpi.js → terminal-viewer-impl-DBRkdyag.js} +3 -3
- package/public/assets/{terminal-viewer-impl-BL853Fpi.js.map → terminal-viewer-impl-DBRkdyag.js.map} +1 -1
- package/public/assets/{use-keyboard-viewport-CP109w9y.js → use-keyboard-viewport-CAa7IQTm.js} +2 -2
- package/public/assets/{use-keyboard-viewport-CP109w9y.js.map → use-keyboard-viewport-CAa7IQTm.js.map} +1 -1
- package/public/assets/user-avatar-kYPfLgXp.js +2 -0
- package/public/assets/{user-avatar-D9xyGi3u.js.map → user-avatar-kYPfLgXp.js.map} +1 -1
- package/public/assets/{work-queue-DrLIdvxB.js → work-queue-BFQVVL4T.js} +2 -2
- package/public/assets/{work-queue-DrLIdvxB.js.map → work-queue-BFQVVL4T.js.map} +1 -1
- package/public/assets/workspaces-CR6f7G0R.js +3 -0
- package/public/assets/{workspaces-CnNL6T8Q.js.map → workspaces-CR6f7G0R.js.map} +1 -1
- package/public/index.html +23 -23
- package/runner/hooks/rg-r-guard/hooks.json +18 -0
- package/runner/hooks/rg-r-guard/rg-r-guard.cjs +144 -0
- package/runner/plugins/claude/.claude-plugin/plugin.json +1 -1
- package/runner/src/launch-assembly.ts +34 -1
- package/runner/src/provisioning.ts +15 -0
- package/src/services/spawn-chain-inspector.ts +134 -0
- package/public/assets/MessageBubble-BTeFExjj.js +0 -2
- package/public/assets/agents-BkC6mcTh.js +0 -2
- package/public/assets/branch-state-badge-CNW10MTC.js +0 -2
- package/public/assets/card-C3BGuVC6.js +0 -2
- package/public/assets/chat-BCNCuTgw.js +0 -2
- package/public/assets/copy-button-B3o1jpLu.js +0 -2
- package/public/assets/dist-B6woQ9Tb.js +0 -2
- package/public/assets/dist-DGfp5dLz.js +0 -2
- package/public/assets/dist-DT-OV6sQ.js +0 -2
- package/public/assets/formatted-body-CVr3Iev9.js +0 -3
- package/public/assets/index--9UMzCFf.js +0 -25
- package/public/assets/index--9UMzCFf.js.map +0 -1
- package/public/assets/lucide-react-DuhlF2Sj.js +0 -10
- package/public/assets/maintenance-HDpg20OY.js +0 -2
- package/public/assets/memory-CTO1FfJ-.js +0 -2
- package/public/assets/messages-RWSXG2UM.js +0 -2
- package/public/assets/prompt-settings-CaJX_LbA.js +0 -2
- package/public/assets/registry-C-uIL0Nl.js +0 -2
- package/public/assets/registry-C-uIL0Nl.js.map +0 -1
- package/public/assets/settings-BUQirdyI.js +0 -6
- package/public/assets/user-avatar-D9xyGi3u.js +0 -2
- package/public/assets/workspaces-CnNL6T8Q.js +0 -3
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
{
|
|
2
|
+
"hooks": {
|
|
3
|
+
"PreToolUse": [
|
|
4
|
+
{
|
|
5
|
+
"matcher": "Bash",
|
|
6
|
+
"hooks": [
|
|
7
|
+
{
|
|
8
|
+
"type": "command",
|
|
9
|
+
"command": "node \"${HOOK_DIR}/rg-r-guard.cjs\"",
|
|
10
|
+
"timeout": 5,
|
|
11
|
+
"statusMessage": "Checking ripgrep replace guard",
|
|
12
|
+
"suppressOutput": true
|
|
13
|
+
}
|
|
14
|
+
]
|
|
15
|
+
}
|
|
16
|
+
]
|
|
17
|
+
}
|
|
18
|
+
}
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
|
|
4
|
+
let input = "";
|
|
5
|
+
process.stdin.setEncoding("utf8");
|
|
6
|
+
process.stdin.on("data", (chunk) => {
|
|
7
|
+
input += chunk;
|
|
8
|
+
});
|
|
9
|
+
process.stdin.on("end", () => {
|
|
10
|
+
let payload;
|
|
11
|
+
try {
|
|
12
|
+
payload = JSON.parse(input || "{}");
|
|
13
|
+
} catch {
|
|
14
|
+
return;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
const toolName = String(payload.tool_name || payload.toolName || "").toLowerCase();
|
|
18
|
+
const command = String(payload.tool_input?.command || payload.toolInput?.command || "");
|
|
19
|
+
if (toolName !== "bash" || !command || !containsRipgrepReplaceFootgun(command)) return;
|
|
20
|
+
|
|
21
|
+
const reason = "Blocked: `rg -r` is ripgrep replace, not recursive search. Use `rg PATTERN PATH` for search, or `rg --replace REPLACEMENT PATTERN` only when replacement output is intentional.";
|
|
22
|
+
process.stdout.write(JSON.stringify({
|
|
23
|
+
hookSpecificOutput: {
|
|
24
|
+
hookEventName: "PreToolUse",
|
|
25
|
+
permissionDecision: "deny",
|
|
26
|
+
permissionDecisionReason: reason,
|
|
27
|
+
},
|
|
28
|
+
}));
|
|
29
|
+
process.stdout.write("\n");
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
function containsRipgrepReplaceFootgun(command) {
|
|
33
|
+
for (const segment of splitShellSegments(command)) {
|
|
34
|
+
const words = shellWords(segment);
|
|
35
|
+
for (let i = 0; i < words.length; i += 1) {
|
|
36
|
+
const word = basename(words[i] || "");
|
|
37
|
+
if (word !== "rg" && word !== "ripgrep") continue;
|
|
38
|
+
if (ripgrepArgsUseReplace(words.slice(i + 1))) return true;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
return false;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
function ripgrepArgsUseReplace(args) {
|
|
45
|
+
for (let i = 0; i < args.length; i += 1) {
|
|
46
|
+
const arg = args[i] || "";
|
|
47
|
+
if (arg === "--") return false;
|
|
48
|
+
if (arg === "--replace" || arg.startsWith("--replace=")) return true;
|
|
49
|
+
if (arg === "-r") return true;
|
|
50
|
+
if (/^-([A-Za-z]*r[A-Za-z]*|[A-Za-z]*r=.+)$/.test(arg)) return true;
|
|
51
|
+
}
|
|
52
|
+
return false;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
function splitShellSegments(text) {
|
|
56
|
+
const segments = [];
|
|
57
|
+
let current = "";
|
|
58
|
+
let quote = "";
|
|
59
|
+
let escaped = false;
|
|
60
|
+
for (let i = 0; i < text.length; i += 1) {
|
|
61
|
+
const ch = text[i];
|
|
62
|
+
if (escaped) {
|
|
63
|
+
current += ch;
|
|
64
|
+
escaped = false;
|
|
65
|
+
continue;
|
|
66
|
+
}
|
|
67
|
+
if (ch === "\\") {
|
|
68
|
+
current += ch;
|
|
69
|
+
escaped = true;
|
|
70
|
+
continue;
|
|
71
|
+
}
|
|
72
|
+
if (quote) {
|
|
73
|
+
current += ch;
|
|
74
|
+
if (ch === quote) quote = "";
|
|
75
|
+
continue;
|
|
76
|
+
}
|
|
77
|
+
if (ch === "'" || ch === "\"") {
|
|
78
|
+
quote = ch;
|
|
79
|
+
current += ch;
|
|
80
|
+
continue;
|
|
81
|
+
}
|
|
82
|
+
// Command-substitution + grouping boundaries (`$(rg -r …)`, backtick `` `rg -r …` ``,
|
|
83
|
+
// subshells) split into their own segments so the inner command is scanned on its own
|
|
84
|
+
// (basename of `$(rg` ≠ rg otherwise) and its args never bleed into the outer command's
|
|
85
|
+
// scan. Only fires OUTSIDE quotes — a single/double-quoted literal is left intact, matching
|
|
86
|
+
// the tokenizer's existing quote handling. Known gap: substitution inside double quotes
|
|
87
|
+
// ("$(rg -r x)") is still treated as an opaque quoted word.
|
|
88
|
+
if (ch === "(" || ch === ")" || ch === "`") {
|
|
89
|
+
if (current.trim()) segments.push(current);
|
|
90
|
+
current = "";
|
|
91
|
+
continue;
|
|
92
|
+
}
|
|
93
|
+
if (ch === ";" || ch === "|" || ch === "&" || ch === "\n") {
|
|
94
|
+
if (current.trim()) segments.push(current);
|
|
95
|
+
current = "";
|
|
96
|
+
continue;
|
|
97
|
+
}
|
|
98
|
+
current += ch;
|
|
99
|
+
}
|
|
100
|
+
if (current.trim()) segments.push(current);
|
|
101
|
+
return segments;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
function shellWords(text) {
|
|
105
|
+
const words = [];
|
|
106
|
+
let current = "";
|
|
107
|
+
let quote = "";
|
|
108
|
+
let escaped = false;
|
|
109
|
+
for (let i = 0; i < text.length; i += 1) {
|
|
110
|
+
const ch = text[i];
|
|
111
|
+
if (escaped) {
|
|
112
|
+
current += ch;
|
|
113
|
+
escaped = false;
|
|
114
|
+
continue;
|
|
115
|
+
}
|
|
116
|
+
if (ch === "\\") {
|
|
117
|
+
escaped = true;
|
|
118
|
+
continue;
|
|
119
|
+
}
|
|
120
|
+
if (quote) {
|
|
121
|
+
if (ch === quote) quote = "";
|
|
122
|
+
else current += ch;
|
|
123
|
+
continue;
|
|
124
|
+
}
|
|
125
|
+
if (ch === "'" || ch === "\"") {
|
|
126
|
+
quote = ch;
|
|
127
|
+
continue;
|
|
128
|
+
}
|
|
129
|
+
if (/\s/.test(ch)) {
|
|
130
|
+
if (current) {
|
|
131
|
+
words.push(current);
|
|
132
|
+
current = "";
|
|
133
|
+
}
|
|
134
|
+
continue;
|
|
135
|
+
}
|
|
136
|
+
current += ch;
|
|
137
|
+
}
|
|
138
|
+
if (current) words.push(current);
|
|
139
|
+
return words;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
function basename(value) {
|
|
143
|
+
return value.split("/").pop() || value;
|
|
144
|
+
}
|
|
@@ -32,6 +32,7 @@ import {
|
|
|
32
32
|
resolveProjectMcpServers,
|
|
33
33
|
profileProvisioning,
|
|
34
34
|
writeCodexHooksJson,
|
|
35
|
+
writeClaudeSettingsJson,
|
|
35
36
|
} from "./provisioning";
|
|
36
37
|
import {
|
|
37
38
|
claudeMcpLaunchArgs,
|
|
@@ -325,6 +326,28 @@ export function stripSettingsArgs(args: string[]): string[] {
|
|
|
325
326
|
return result;
|
|
326
327
|
}
|
|
327
328
|
|
|
329
|
+
// #1096 — the settings.json relay WRITES into an isolated managed Claude home so the provisioned
|
|
330
|
+
// hooks (baseline guard included) land in the DOCUMENTED hook source Claude honors
|
|
331
|
+
// ($CLAUDE_CONFIG_DIR/settings.json — loaded under `--setting-sources "user"` and the default),
|
|
332
|
+
// rather than riding ONLY the inline `--settings` CLI flag. Claude does not document `--settings`
|
|
333
|
+
// as a hook source, and — unlike a file written straight to disk — that flag's JSON must survive
|
|
334
|
+
// shell/tmux launcher transit and passes Claude's "silently ignore settings that fail validation"
|
|
335
|
+
// gate; a written settings.json bypasses both, so the baseline guard can't be silently absent
|
|
336
|
+
// (the #1096 inert-at-runtime symptom). Returns null when:
|
|
337
|
+
// • there is NO isolated managed home (host base reuses the real ~/.claude — relay must not
|
|
338
|
+
// clobber it; that path keeps the inline --settings delivery), or
|
|
339
|
+
// • a caller --settings is present (the merge/suppression path owns hook delivery inline; see
|
|
340
|
+
// claudeSettingsArgs) — so the file and inline channels never DOUBLE-register the same hook.
|
|
341
|
+
// Both assembleClaude (to keep these hooks OUT of the inline --settings) and materializeClaudeAssets
|
|
342
|
+
// (to write the file) call this, so the launch and the disk agree.
|
|
343
|
+
export function claudeManagedHookSettings(config: RunnerSpawnConfig, configHome: string | undefined): { hooks: ProvisioningHookSet } | null {
|
|
344
|
+
if (!configHome) return null;
|
|
345
|
+
const hostDefaultArgs = profileUsesProviderHostGlobals(config) ? config.providerConfig.defaultArgs : [];
|
|
346
|
+
if (hasSettingsArg(hostDefaultArgs) || hasSettingsArg(config.providerArgs)) return null;
|
|
347
|
+
const hookSet = renderProvisionedHookSet(resolveProvisionedHooks(configHome, config));
|
|
348
|
+
return Object.keys(hookSet).length ? { hooks: hookSet } : null;
|
|
349
|
+
}
|
|
350
|
+
|
|
328
351
|
// ── Instruction disposition (the vanilla floor's effect on the host instruction cascade) ──
|
|
329
352
|
|
|
330
353
|
function repoInstructionDisposition(profile: AgentProfile): AssembledInstructionDisposition {
|
|
@@ -374,9 +397,15 @@ function assembleClaude(config: RunnerSpawnConfig, providerConfig: ProviderConfi
|
|
|
374
397
|
const hookHome = configHome ?? assetHome;
|
|
375
398
|
const provisionedHooks = hookHome ? resolveProvisionedHooks(hookHome, config) : [];
|
|
376
399
|
const provisionedHookSet = renderProvisionedHookSet(provisionedHooks);
|
|
400
|
+
// #1096 — for an isolated managed home with no caller --settings, the provisioned hooks are
|
|
401
|
+
// delivered through the managed settings.json (the documented, transit-safe hook source), so
|
|
402
|
+
// keep them OUT of the inline --settings to avoid double-registering the same guard. Host-base
|
|
403
|
+
// and caller-`--settings` launches keep inline delivery (see claudeManagedHookSettings).
|
|
404
|
+
const managedHookSettings = claudeManagedHookSettings(config, configHome);
|
|
405
|
+
const inlineHookSet = managedHookSettings ? {} : provisionedHookSet;
|
|
377
406
|
const settings = claudeSettingsArgs(
|
|
378
407
|
projectSettings.settings,
|
|
379
|
-
|
|
408
|
+
inlineHookSet,
|
|
380
409
|
provisionedHooks.map((h) => h.name),
|
|
381
410
|
statusLine,
|
|
382
411
|
hostDefaultArgs,
|
|
@@ -629,6 +658,10 @@ function materializeClaudeAssets(config: RunnerSpawnConfig): void {
|
|
|
629
658
|
materializeResolvedAssets(hostSkills);
|
|
630
659
|
materializeResolvedAssets(resolveClaudeProjectSkills(configHome, config, new Set([...skills, ...hostSkills].map((s) => s.name))));
|
|
631
660
|
materializeResolvedAssets(resolveProvisionedHooks(configHome, config));
|
|
661
|
+
// #1096 — land the provisioned hooks in the managed home's settings.json (the documented
|
|
662
|
+
// hook source), matching the assembler's decision to keep them out of the inline --settings.
|
|
663
|
+
const managedHookSettings = claudeManagedHookSettings(config, configHome);
|
|
664
|
+
if (managedHookSettings) writeClaudeSettingsJson(configHome, managedHookSettings);
|
|
632
665
|
}
|
|
633
666
|
if (assetHome) materializeResolvedAssets(resolveClaudeProvisionedPlugins(assetHome, config));
|
|
634
667
|
if (!configHome && assetHome) materializeResolvedAssets(resolveProvisionedHooks(assetHome, config));
|
|
@@ -357,6 +357,21 @@ export function writeCodexHooksJson(codexHome: string, hooks: ProvisioningHookSe
|
|
|
357
357
|
writeFileSync(join(codexHome, "hooks.json"), JSON.stringify({ hooks }, null, 2), { mode: 0o600 });
|
|
358
358
|
}
|
|
359
359
|
|
|
360
|
+
// #1096 — write relay-owned settings into an ISOLATED Claude managed home's `settings.json`
|
|
361
|
+
// (the DOCUMENTED hook source Claude honors under `--setting-sources "user"` or the default,
|
|
362
|
+
// unlike the inline `--settings` CLI flag). The managed home is relay-owned and freshly keyed
|
|
363
|
+
// per spawn, so an unconditional write is safe (profile-home seeds only `.claude.json`/`CLAUDE.md`,
|
|
364
|
+
// never `settings.json`). Removes the file when there is nothing relay-owned to deliver so disk
|
|
365
|
+
// stays == report. Never called for a host-base launch (which reuses the real `~/.claude`).
|
|
366
|
+
export function writeClaudeSettingsJson(claudeHome: string, settings: Record<string, unknown>): void {
|
|
367
|
+
mkdirSync(claudeHome, { recursive: true });
|
|
368
|
+
if (!Object.keys(settings).length) {
|
|
369
|
+
rmSync(join(claudeHome, "settings.json"), { force: true });
|
|
370
|
+
return;
|
|
371
|
+
}
|
|
372
|
+
writeFileSync(join(claudeHome, "settings.json"), JSON.stringify(settings, null, 2), { mode: 0o600 });
|
|
373
|
+
}
|
|
374
|
+
|
|
360
375
|
// Write the resolved assets to disk; returns the dirs that materialized successfully,
|
|
361
376
|
// in resolution order. Idempotent — safe to re-run against an existing home.
|
|
362
377
|
export function materializeResolvedAssets(assets: ResolvedAsset[]): string[] {
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
// Real-chain spawn inspector (#1103 L1 seed) — the regression harness whose absence let two
|
|
2
|
+
// dead #1096 fixes ship. It drives the ACTUAL spawn chain for a named profile, end to end, with
|
|
3
|
+
// NO hand-fed config objects:
|
|
4
|
+
//
|
|
5
|
+
// getAgentProfile(name) — the real built-in/stored profile
|
|
6
|
+
// → withResolvedProvisioning — relay-side registry resolution (needs a seeded DB)
|
|
7
|
+
// → buildSpawnCommand — the command params the orchestrator dispatches
|
|
8
|
+
// → JSON round-trip — the command-bus / AGENT_RELAY_AGENT_PROFILE_JSON env seam
|
|
9
|
+
// → spawnOptionsFromControl — orchestrator re-parse of the command
|
|
10
|
+
// → ClaudeAdapter.buildSpawnArgs — runner assembly + hook/skill/plugin MATERIALIZATION to disk
|
|
11
|
+
//
|
|
12
|
+
// then reads back the EFFECTIVE on-disk artifacts: the written managed `settings.json`, the
|
|
13
|
+
// materialized `relay-provisioned-hooks/` tree, and the assembled argv. Two prior fixes each
|
|
14
|
+
// tested one half in isolation (relay resolution OR runner materialization) with a hand-fed
|
|
15
|
+
// `provisioning.hooks`, so neither caught that the bundled hook asset is never SHIPPED (the
|
|
16
|
+
// `runner/hooks/**` packaging gap) and so never seeds → resolves empty on a real deployed spawn.
|
|
17
|
+
// This helper runs the whole chain against the real DB + real package layout, so that class of
|
|
18
|
+
// break surfaces as a red on-disk artifact instead of a green half-test.
|
|
19
|
+
|
|
20
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
21
|
+
import { join } from "node:path";
|
|
22
|
+
import type { SpawnProvider } from "agent-relay-sdk";
|
|
23
|
+
import { withResolvedProvisioning } from "../db";
|
|
24
|
+
import { getAgentProfile } from "../config-store";
|
|
25
|
+
import { buildSpawnCommand } from "../spawn-command";
|
|
26
|
+
import { spawnOptionsFromControl } from "../../orchestrator/src/control";
|
|
27
|
+
import { ClaudeAdapter } from "../../runner/src/adapters/claude";
|
|
28
|
+
import { defaultProviderConfig } from "../../runner/src/config";
|
|
29
|
+
import type { RunnerSpawnConfig } from "../../runner/src/adapter";
|
|
30
|
+
|
|
31
|
+
/** The bundled baseline safety hook whose silent absence is the #1096 bug. */
|
|
32
|
+
export const BASELINE_HOOK_REF = "agent-relay-rg-r-guard";
|
|
33
|
+
export const BASELINE_HOOK_SCRIPT = "rg-r-guard.cjs";
|
|
34
|
+
|
|
35
|
+
export interface SpawnChainInspection {
|
|
36
|
+
profile: string;
|
|
37
|
+
provider: SpawnProvider;
|
|
38
|
+
/** The isolated managed CLAUDE_CONFIG_DIR the runner assembled + materialized into. */
|
|
39
|
+
configHome: string | undefined;
|
|
40
|
+
/** Absolute path of the managed settings.json (whether or not it exists). */
|
|
41
|
+
settingsPath: string | undefined;
|
|
42
|
+
/** Parsed on-disk settings.json (null when relay wrote none). */
|
|
43
|
+
settings: Record<string, unknown> | null;
|
|
44
|
+
/** The effective launch argv the adapter would exec. */
|
|
45
|
+
argv: string[];
|
|
46
|
+
/** The launch command (claude / claude-rig). */
|
|
47
|
+
command: string;
|
|
48
|
+
/** relay-provisioned-hooks/<ref> dir for the baseline guard. */
|
|
49
|
+
baselineHookAssetDir: string | undefined;
|
|
50
|
+
baselineHookAssetExists: boolean;
|
|
51
|
+
baselineHookScriptExists: boolean;
|
|
52
|
+
/** True iff the WRITTEN settings.json (the documented, transit-safe hook source) carries the
|
|
53
|
+
* baseline PreToolUse guard — the #1096 proof-of-life bar. */
|
|
54
|
+
settingsHasBaselineHook: boolean;
|
|
55
|
+
/** True iff SOME launch channel (written settings.json OR inline --settings) carries it. */
|
|
56
|
+
launchHasBaselineHook: boolean;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
function settingsCarriesBaselineHook(settings: Record<string, unknown> | null): boolean {
|
|
60
|
+
const pre = (settings?.hooks as { PreToolUse?: unknown } | undefined)?.PreToolUse;
|
|
61
|
+
if (!Array.isArray(pre)) return false;
|
|
62
|
+
return JSON.stringify(pre).includes(BASELINE_HOOK_SCRIPT);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
function argvCarriesBaselineHook(argv: string[]): boolean {
|
|
66
|
+
const idx = argv.findIndex((a) => a === "--settings");
|
|
67
|
+
if (idx < 0 || idx + 1 >= argv.length) return false;
|
|
68
|
+
return argv[idx + 1]!.includes(BASELINE_HOOK_SCRIPT);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Run the real spawn chain for a profile and read back the on-disk artifacts. Two preconditions,
|
|
73
|
+
* both owned by the caller so this stays a pure harness (no global/env mutation of its own):
|
|
74
|
+
* • the DB is seeded (initDb) so registry resolution can find the bundled hook, and
|
|
75
|
+
* • AGENT_RELAY_PROVIDER_HOME_ROOT points at a scratch dir (the runner's config module reads it
|
|
76
|
+
* to place isolated provider homes) — set it like launch-assembly.test.ts does.
|
|
77
|
+
*/
|
|
78
|
+
export function inspectSpawnChain(opts: {
|
|
79
|
+
profile: string;
|
|
80
|
+
provider: SpawnProvider;
|
|
81
|
+
cwd: string;
|
|
82
|
+
approvalMode?: string;
|
|
83
|
+
}): SpawnChainInspection {
|
|
84
|
+
const { profile, provider, cwd } = opts;
|
|
85
|
+
|
|
86
|
+
// 1. RELAY: resolve the named profile's provisioning against the registry.
|
|
87
|
+
const resolved = withResolvedProvisioning(getAgentProfile(profile)?.value, provider);
|
|
88
|
+
if (!resolved) throw new Error(`profile not found: ${profile}`);
|
|
89
|
+
|
|
90
|
+
// 2. RELAY: build the spawn command params the orchestrator dispatches.
|
|
91
|
+
const cmdParams = buildSpawnCommand({
|
|
92
|
+
provider, cwd, agentProfile: resolved, env: {}, requestedBy: "spawn-chain-inspector",
|
|
93
|
+
} as Parameters<typeof buildSpawnCommand>[0]);
|
|
94
|
+
|
|
95
|
+
// 3. SEAM: JSON round-trip through the command bus / AGENT_RELAY_AGENT_PROFILE_JSON env var.
|
|
96
|
+
const roundTripped = JSON.parse(JSON.stringify(cmdParams)) as Record<string, unknown>;
|
|
97
|
+
|
|
98
|
+
// 4. ORCHESTRATOR: re-parse the command into spawn options.
|
|
99
|
+
const spawnOpts = spawnOptionsFromControl(roundTripped, { providers: [provider], baseDir: cwd } as never);
|
|
100
|
+
|
|
101
|
+
// 5. RUNNER: assemble the RunnerSpawnConfig the adapter consumes.
|
|
102
|
+
const providerConfig = defaultProviderConfig(provider);
|
|
103
|
+
const config = {
|
|
104
|
+
provider, runnerId: "inspector", instanceId: `insp-${profile}`, agentId: "insp",
|
|
105
|
+
relayUrl: "http://localhost:4850", cwd, headless: true,
|
|
106
|
+
approvalMode: opts.approvalMode ?? "open", providerArgs: [], providerConfig,
|
|
107
|
+
env: {}, controlPort: 4900,
|
|
108
|
+
agentProfile: spawnOpts.agentProfile,
|
|
109
|
+
} as unknown as RunnerSpawnConfig;
|
|
110
|
+
|
|
111
|
+
// 6. RUNNER: the REAL adapter path — prepares the home, materializes provisioned assets to
|
|
112
|
+
// disk, and returns the launch argv (exactly what the runner execs).
|
|
113
|
+
const spawnArgs = new ClaudeAdapter().buildSpawnArgs(config, providerConfig);
|
|
114
|
+
|
|
115
|
+
// 7. Read back the effective on-disk artifacts.
|
|
116
|
+
const configHome = spawnArgs.env.CLAUDE_CONFIG_DIR;
|
|
117
|
+
const settingsPath = configHome ? join(configHome, "settings.json") : undefined;
|
|
118
|
+
const settings = settingsPath && existsSync(settingsPath)
|
|
119
|
+
? (JSON.parse(readFileSync(settingsPath, "utf8")) as Record<string, unknown>)
|
|
120
|
+
: null;
|
|
121
|
+
const baselineHookAssetDir = configHome
|
|
122
|
+
? join(configHome, "relay-provisioned-hooks", BASELINE_HOOK_REF)
|
|
123
|
+
: undefined;
|
|
124
|
+
|
|
125
|
+
return {
|
|
126
|
+
profile, provider, configHome, settingsPath, settings,
|
|
127
|
+
argv: spawnArgs.args, command: spawnArgs.command,
|
|
128
|
+
baselineHookAssetDir,
|
|
129
|
+
baselineHookAssetExists: Boolean(baselineHookAssetDir && existsSync(baselineHookAssetDir)),
|
|
130
|
+
baselineHookScriptExists: Boolean(baselineHookAssetDir && existsSync(join(baselineHookAssetDir, BASELINE_HOOK_SCRIPT))),
|
|
131
|
+
settingsHasBaselineHook: settingsCarriesBaselineHook(settings),
|
|
132
|
+
launchHasBaselineHook: settingsCarriesBaselineHook(settings) || argvCarriesBaselineHook(spawnArgs.args),
|
|
133
|
+
};
|
|
134
|
+
}
|
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
import{r as e}from"./chunk-CilyBKbf.js";import{Gn as t,Kn as n,S as r,Sn as i,Ut as a,a as o,bn as s,en as c,er as l,hr as u,ir as d,l as f,nr as p,pn as m,pt as h,r as g}from"./lucide-react-DuhlF2Sj.js";import{b as _,t as v}from"./store-DMZSTozC.js";import{s as y}from"./types-CRptbSYh.js";import{V as b,_ as x,f as S,k as C,v as ee}from"./display-GFbGUG0O.js";import{t as w}from"./agent-type-icon-Dan2l3Tm.js";import{t as T}from"./formatted-body-CVr3Iev9.js";import{A as te,D as E,E as D,I as ne,M as O,P as k,h as A,j,l as M,n as N,o as P,t as F,z as I}from"./index--9UMzCFf.js";import{t as L}from"./user-avatar-D9xyGi3u.js";var R=e(u(),1);function re(){return(0,R.useSyncExternalStore)(e=>_.subscribe(e),()=>_.getPlayingKey(),()=>null)}var z=p();function ie({msg:e,peer:t}){return(0,z.jsx)(A,{msg:e,issueRepo:v(e=>e.agentsById[t]?.issueRepo)})}function B({agent:e,onClick:t}){let n=!!(t&&e);return(0,z.jsx)(`button`,{type:`button`,title:e?e.label||e.name||e.id:void 0,onClick:t,disabled:!n,className:l(`shrink-0 self-end transition-opacity`,n?`cursor-pointer hover:opacity-80`:`cursor-default opacity-60`),children:(0,z.jsx)(w,{agent:e})})}function ae({agentId:e,onOpen:t}){let n=v(t=>t.agentsById[e]??null);return(0,z.jsx)(B,{agent:n,onClick:n?()=>t(n):void 0})}function V({attachment:e,outbound:t}){let n=e.kind===`image`,r=e.title||e.artifactId,[i,u]=(0,R.useState)(null),[f,p]=(0,R.useState)(null),[m,_]=(0,R.useState)(!1),[v,y]=(0,R.useState)(!1);(0,R.useEffect)(()=>{let t=!1,n=null;async function r(){_(!0),p(null),u(null);try{let r=await d(`/artifacts/${encodeURIComponent(e.artifactId)}/content`);if(t)return;n=URL.createObjectURL(r),u(n)}catch(e){t||p(e.message)}finally{t||_(!1)}}return r(),()=>{t=!0,n&&URL.revokeObjectURL(n)}},[e.artifactId]);function b(){if(!i)return;let e=document.createElement(`a`);e.href=i,e.download=r,document.body.appendChild(e),e.click(),e.remove()}return n?(0,z.jsxs)(z.Fragment,{children:[(0,z.jsx)(`button`,{type:`button`,onClick:()=>i&&y(!0),disabled:!i,className:`group/img mt-2 block overflow-hidden rounded-md border border-foreground/10 bg-black/10 text-left disabled:cursor-default relative`,children:i?(0,z.jsxs)(z.Fragment,{children:[(0,z.jsx)(`img`,{src:i,alt:r,loading:`lazy`,className:`block max-h-72 max-w-full object-contain`}),(0,z.jsx)(`span`,{className:`absolute inset-0 flex items-center justify-center bg-black/0 group-hover/img:bg-black/30 transition-colors`,children:(0,z.jsx)(g,{className:`w-6 h-6 text-white opacity-0 group-hover/img:opacity-100 transition-opacity drop-shadow-md`})})]}):(0,z.jsxs)(`span`,{className:l(`flex min-h-20 items-center gap-2 px-3 py-2 text-xs`,f?`text-red-400`:`text-muted-foreground`),children:[m?(0,z.jsx)(h,{className:`h-4 w-4 animate-spin`}):(0,z.jsx)(s,{className:`h-4 w-4`}),f||`Loading image`]})}),i&&(0,z.jsx)(F,{open:v,onOpenChange:y,children:(0,z.jsxs)(N,{className:`max-w-[95vw] max-h-[95vh] w-auto p-0 bg-black/95 border-zinc-800 gap-0 overflow-hidden`,showCloseButton:!1,children:[(0,z.jsx)(P,{className:`sr-only`,children:r}),(0,z.jsxs)(`div`,{className:`relative flex items-center justify-center min-h-[200px]`,children:[(0,z.jsx)(`img`,{src:i,alt:r,className:`max-w-[93vw] max-h-[90vh] object-contain`}),(0,z.jsxs)(`div`,{className:`absolute top-2 right-2 flex gap-1`,children:[(0,z.jsx)(`button`,{type:`button`,onClick:b,className:`rounded-md bg-black/60 hover:bg-black/80 p-2 text-white transition-colors`,title:`Download`,children:(0,z.jsx)(c,{className:`w-4 h-4`})}),(0,z.jsx)(`button`,{type:`button`,onClick:()=>y(!1),className:`rounded-md bg-black/60 hover:bg-black/80 p-2 text-white transition-colors`,title:`Close`,children:(0,z.jsx)(o,{className:`w-4 h-4`})})]})]})]})})]}):(0,z.jsxs)(`button`,{type:`button`,onClick:b,disabled:!i,className:l(`mt-2 flex w-full items-center gap-2 rounded-md border px-2.5 py-2 text-left text-xs transition-colors disabled:cursor-default disabled:opacity-70`,t?`border-primary-foreground/20 bg-primary-foreground/10 hover:bg-primary-foreground/15`:`border-border bg-background hover:bg-muted`),children:[m?(0,z.jsx)(h,{className:`h-4 w-4 shrink-0 animate-spin`}):f?(0,z.jsx)(s,{className:`h-4 w-4 shrink-0 text-red-400`}):(0,z.jsx)(a,{className:`h-4 w-4 shrink-0`}),(0,z.jsx)(`span`,{className:l(`min-w-0 flex-1 truncate`,f&&`text-red-400`),children:f||r}),(0,z.jsx)(c,{className:`h-3.5 w-3.5 shrink-0`})]})}function H({open:e,onToggle:t,onReact:n}){return(0,z.jsxs)(`div`,{className:`relative shrink-0`,children:[(0,z.jsx)(`button`,{type:`button`,title:`Add reaction`,onClick:t,className:l(`inline-flex h-5 w-6 items-center justify-center rounded-full border border-border bg-popover text-muted-foreground shadow-sm transition hover:bg-muted hover:text-foreground`,e?`opacity-100`:`opacity-0 pointer-events-none md:group-hover/msg:opacity-100 md:group-hover/msg:pointer-events-auto`),children:(0,z.jsx)(r,{className:`h-3 w-3`})}),e&&(0,z.jsx)(`div`,{className:`absolute bottom-full left-0 z-30 mb-1 flex gap-0.5 rounded-full border border-border bg-popover p-0.5 shadow-md`,children:D.map(e=>(0,z.jsx)(`button`,{type:`button`,title:`React ${e}`,onClick:()=>n(e),className:`inline-flex h-6 w-7 items-center justify-center rounded-full text-xs transition-colors hover:bg-muted`,children:e},e))})]})}function U({msg:e,peer:r}){let[a,o]=(0,R.useState)(!1),s=v(e=>e.agentsById),c=v(e=>e.openAgentDetail),u=e.from===r,d=(u?e.to:e.from)||``,f=s[u?r:d]?.issueRepo??s[r]?.issueRepo,p=!d||d===`broadcast`||d.includes(`:`),m=C(e),h=E(e.occurredAt??e.createdAt),g=u?t:n,_=s[e.from??``]??null;function y(e){e.stopPropagation(),_&&c(_)}return(0,z.jsx)(`div`,{"data-msg-id":e.id,className:`flex justify-center mb-1.5`,children:(0,z.jsxs)(`div`,{className:`w-full max-w-[94%] rounded-md border border-border/50 bg-muted/15 px-2.5 py-1`,children:[(0,z.jsxs)(`div`,{className:`flex items-center gap-1.5 text-xs cursor-pointer select-none`,onClick:()=>o(e=>!e),children:[(0,z.jsx)(i,{className:l(`h-3 w-3 shrink-0 text-muted-foreground/60 transition-transform`,a&&`rotate-90`)}),(0,z.jsx)(`button`,{type:`button`,title:_?_.label||_.name||_.id:void 0,disabled:!_,onClick:y,className:l(`shrink-0 transition-opacity`,_?`cursor-pointer hover:opacity-80`:`cursor-default opacity-60`),children:(0,z.jsx)(w,{agent:_,className:`!w-4 !h-4 !rounded-sm opacity-70`})}),(0,z.jsx)(g,{className:`h-3 w-3 shrink-0 text-muted-foreground/70`}),(0,z.jsxs)(`span`,{className:`shrink-0 text-muted-foreground`,children:[`Message `,u?`to`:`from`]}),p?(0,z.jsx)(`span`,{className:`shrink-0 font-medium text-muted-foreground`,children:S(d,s)}):(0,z.jsx)(M,{agentId:d,className:`shrink-0 px-0.5 text-foreground/80`,noIcon:!0}),!a&&(0,z.jsx)(`span`,{className:`min-w-0 flex-1 truncate text-muted-foreground/50`,children:m}),(0,z.jsx)(`span`,{className:`ml-auto shrink-0 text-muted-foreground/40`,children:h})]}),a&&(0,z.jsx)(`div`,{className:`mt-1.5 pl-5`,children:(0,z.jsx)(T,{text:m,rawBody:e.body,issueRepo:f,className:`text-sm leading-relaxed text-foreground/90`})})]})})}var W=(0,R.memo)(function({msg:e,peer:t,showAvatar:n=!1,onOpenReferencedPath:r,onPreviewReferencedPath:i,onPreviewReferencedPathEnd:a}){if(!y(e.from)&&!y(e.to))return(0,z.jsx)(U,{msg:e,peer:t});let o=e.kind===`session`?e.payload?.session:void 0;if(o?.type===`prompt`&&o?.origin===`provider`)return(0,z.jsx)(ie,{msg:e,peer:t});let s=y(e.from),c=v(e=>e.reactToMessage),u=v(e=>e.voiceTtsEnabled),d=re(),p=v(e=>{let n=e.agentsById[t]?.meta?.cwd;return typeof n==`string`?n:``}),h=v(e=>e.agentsById[t]?.issueRepo),g=v(e=>e.usersById),S=v(e=>e.users.length>1),w=s?b(e.from,g):void 0,D=v(e=>e.openAgentDetail);v(e=>e.openTaskDetailById);let[A,M]=(0,R.useState)(!1),N=(0,R.useRef)(null),P=(0,R.useRef)(null),F=(0,R.useRef)(!1),B=C(e),W=E(e.occurredAt??e.createdAt),G=k(e),K=te(e),q=s?ne(e,t):null,J=q?.icon,Y=d===String(e.id),oe=u&&!s&&!O(e)&&B.trim().length>0;function se(t){t.stopPropagation(),Y?_.bargeIn():_.speak(e.body,String(e.id))}(0,R.useEffect)(()=>{if(!A)return;function e(e){j()||N.current&&!N.current.contains(e.target)&&M(!1)}return document.addEventListener(`mousedown`,e),document.addEventListener(`touchstart`,e),()=>{document.removeEventListener(`mousedown`,e),document.removeEventListener(`touchstart`,e)}},[A]);function X(e){return I(p||`/`,e)}function ce(e,t){let n=X(e);r?.(n,t)}function Z(e,t,n){let r=X(e);i?.(r,t,n)}function Q(t){c(e,t),M(!1)}function le(e){e.button===0&&(P.current={x:e.clientX,y:e.clientY},F.current=!1)}function ue(e){let t=P.current;t&&(Math.abs(e.clientX-t.x)>3||Math.abs(e.clientY-t.y)>3)&&(F.current=!0)}function de(t){if(!(O(e)||s)&&!t.target.closest(`a,button,input,textarea,select,[role="button"]`)){if(F.current||j()){F.current=!1;return}M(e=>!e)}}let $=n&&!O(e);return(0,z.jsxs)(`div`,{"data-msg-id":e.id,className:l(`group/msg flex mb-3 items-end`,s?`justify-end`:`justify-start`,$&&`gap-1.5`),children:[!s&&$&&(0,z.jsx)(ae,{agentId:t,onOpen:D}),(0,z.jsxs)(`div`,{ref:N,className:l(`relative`,$?`max-w-[calc(85%-2rem)] md:max-w-[calc(75%-2rem)]`:`max-w-[85%] md:max-w-[75%]`),children:[oe&&(0,z.jsx)(`button`,{type:`button`,title:Y?`Stop playback`:`Play aloud`,onClick:se,className:l(`absolute -top-2 -right-2 z-20 inline-flex h-6 w-6 items-center justify-center rounded-full border bg-popover shadow-sm transition`,Y?`border-primary/50 text-primary opacity-100`:`border-border text-muted-foreground opacity-70 hover:bg-muted hover:text-foreground hover:opacity-100 [@media(hover:hover)]:md:opacity-0 [@media(hover:hover)]:md:group-hover/msg:opacity-100`),children:Y?(0,z.jsx)(m,{className:`h-3.5 w-3.5 animate-pulse`}):(0,z.jsx)(f,{className:`h-3.5 w-3.5`})}),(0,z.jsxs)(`div`,{className:l(`rounded-2xl px-3.5 py-2 text-sm select-text`,!s&&!O(e)&&`cursor-pointer`,s?`bg-primary text-primary-foreground rounded-br-sm`:`bg-card ring-1 ring-foreground/10 rounded-bl-sm`),onPointerDown:le,onPointerMove:ue,onClick:de,children:[s&&S&&(0,z.jsx)(`p`,{className:l(`text-[11px] font-semibold mb-0.5 text-right`,x(e.from)),children:ee(e.from,g)}),e.subject&&(0,z.jsx)(`p`,{className:l(`text-xs font-semibold mb-1`,s?`text-primary-foreground/70`:`text-muted-foreground`),children:e.subject}),(0,z.jsx)(T,{text:B,rawBody:e.body,issueRepo:h,className:`leading-relaxed`,onPrimary:s,onOpenPath:ce,onPreviewPath:Z,onPreviewPathEnd:a,resolvePathTitle:(e,t)=>`${X(e)}${t?`:${t}`:``}`}),G.map(t=>(0,z.jsx)(V,{attachment:t,outbound:s},`${e.id}-${t.artifactId}-${t.role||``}`)),(0,z.jsxs)(`p`,{className:l(`text-xs mt-1 flex items-center gap-1.5`,s?`justify-end text-primary-foreground/60`:`justify-end text-muted-foreground`),children:[(0,z.jsxs)(`span`,{className:`opacity-40`,children:[`#`,e.id]}),(0,z.jsx)(`span`,{children:W}),q&&J&&(0,z.jsxs)(`span`,{className:l(`inline-flex items-center gap-1`,q.tone===`ok`&&`text-emerald-300`,q.tone===`warn`&&`text-amber-200`,q.tone===`danger`&&`text-red-200`),title:q.title,children:[(0,z.jsx)(J,{className:`h-3 w-3`}),q.label]})]})]}),!O(e)&&K.length>0&&(0,z.jsxs)(`div`,{className:l(`flex flex-wrap items-center gap-0.5 -mt-1 relative z-10`,s?`justify-end pr-2`:`justify-start pl-2`),children:[!s&&(0,z.jsx)(H,{open:A,onToggle:()=>M(e=>!e),onReact:Q}),K.map(e=>(0,z.jsxs)(`button`,{type:`button`,title:e.actors.join(`, `),onClick:()=>Q(e.emoji),className:l(`inline-flex h-5 items-center gap-0.5 rounded-full border px-1.5 text-[11px] shadow-sm transition-colors`,e.mine?`border-primary/40 bg-primary/10 text-primary`:`border-border bg-background hover:bg-muted text-foreground`),children:[(0,z.jsx)(`span`,{children:e.emoji}),e.count>1&&(0,z.jsx)(`span`,{children:e.count})]},e.emoji))]}),!O(e)&&!s&&K.length===0&&(0,z.jsx)(`div`,{className:`absolute -bottom-2.5 left-1 z-20`,children:(0,z.jsx)(H,{open:A,onToggle:()=>M(e=>!e),onReact:Q})})]}),s&&$&&(0,z.jsx)(`span`,{className:`shrink-0 self-end opacity-60`,children:(0,z.jsx)(L,{user:w,address:e.from,distinct:S})})]})});export{W as t};
|
|
2
|
-
//# sourceMappingURL=MessageBubble-BTeFExjj.js.map
|
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
import{r as e}from"./chunk-CilyBKbf.js";import{$ as t,K as n,V as r,Vt as i,Wn as a,Yn as o,Zt as s,_ as c,a as l,er as u,g as d,gt as f,hr as p,nr as m,nt as h,u as g,z as _}from"./lucide-react-DuhlF2Sj.js";import{p as ee,t as v}from"./store-DMZSTozC.js";import{g as y,m as b}from"./types-CRptbSYh.js";import{J as x,K as S,W as te,Y as C,a as w,d as T,i as ne,n as re}from"./display-GFbGUG0O.js";import{o as E,r as D}from"./dist-BIjlN-xB.js";import{t as O}from"./dist-B9G83DXv.js";import{i as ie,n as k}from"./dist-B-T7lg0a.js";import{t as A}from"./dist-OUPTEP6q.js";import{t as j}from"./dist-BlzVGRhh.js";import{a as M,i as N,n as P,o as F,r as I,s as L,t as ae}from"./es2015-CnKXYKpf.js";import{a as R,i as oe,n as z,r as se,t as B}from"./dist-B3e4B9pg.js";import{t as V}from"./badge-DCIT3Irj.js";import{t as H}from"./button-CzdTkRIf.js";import{t as ce}from"./copy-button-B3o1jpLu.js";import{t as U}from"./agent-type-icon-Dan2l3Tm.js";import{Dt as W,Et as le,J as ue,Ot as de,Y as fe,Z as pe,bt as me,ct as G,et as he,kt as ge,nt as _e,q as ve,rt as ye,tt as be}from"./index--9UMzCFf.js";import{r as xe,t as Se}from"./card-C3BGuVC6.js";import{i as Ce,n as we,r as Te,t as Ee}from"./branch-state-badge-CNW10MTC.js";var K=e(p(),1),q=m(),J=`Popover`,[De,Oe]=ie(J,[R]),Y=R(),[ke,X]=De(J),Ae=e=>{let{__scopePopover:t,children:n,open:r,defaultOpen:i,onOpenChange:a,modal:o=!1}=e,s=Y(t),c=K.useRef(null),[l,u]=K.useState(!1),[d,f]=A({prop:r,defaultProp:i??!1,onChange:a,caller:J});return(0,q.jsx)(oe,{...s,children:(0,q.jsx)(ke,{scope:t,contentId:L(),triggerRef:c,open:d,onOpenChange:f,onOpenToggle:K.useCallback(()=>f(e=>!e),[f]),hasCustomAnchor:l,onCustomAnchorAdd:K.useCallback(()=>u(!0),[]),onCustomAnchorRemove:K.useCallback(()=>u(!1),[]),modal:o,children:n})})};Ae.displayName=J;var je=`PopoverAnchor`,Me=K.forwardRef((e,t)=>{let{__scopePopover:n,...r}=e,i=X(je,n),a=Y(n),{onCustomAnchorAdd:o,onCustomAnchorRemove:s}=i;return K.useEffect(()=>(o(),()=>s()),[o,s]),(0,q.jsx)(B,{...a,...r,ref:t})});Me.displayName=je;var Ne=`PopoverTrigger`,Z=K.forwardRef((e,t)=>{let{__scopePopover:n,...r}=e,i=X(Ne,n),a=Y(n),o=E(t,i.triggerRef),s=(0,q.jsx)(O.button,{type:`button`,"aria-haspopup":`dialog`,"aria-expanded":i.open,"aria-controls":i.contentId,"data-state":Ke(i.open),...r,ref:o,onClick:k(e.onClick,i.onOpenToggle)});return i.hasCustomAnchor?s:(0,q.jsx)(B,{asChild:!0,...a,children:s})});Z.displayName=Ne;var Q=`PopoverPortal`,[Pe,Fe]=De(Q,{forceMount:void 0}),Ie=e=>{let{__scopePopover:t,forceMount:n,children:r,container:i}=e,a=X(Q,t);return(0,q.jsx)(Pe,{scope:t,forceMount:n,children:(0,q.jsx)(j,{present:n||a.open,children:(0,q.jsx)(N,{asChild:!0,container:i,children:r})})})};Ie.displayName=Q;var $=`PopoverContent`,Le=K.forwardRef((e,t)=>{let n=Fe($,e.__scopePopover),{forceMount:r=n.forceMount,...i}=e,a=X($,e.__scopePopover);return(0,q.jsx)(j,{present:r||a.open,children:a.modal?(0,q.jsx)(ze,{...i,ref:t}):(0,q.jsx)(Be,{...i,ref:t})})});Le.displayName=$;var Re=D(`PopoverContent.RemoveScroll`),ze=K.forwardRef((e,t)=>{let n=X($,e.__scopePopover),r=K.useRef(null),i=E(t,r),a=K.useRef(!1);return K.useEffect(()=>{let e=r.current;if(e)return ae(e)},[]),(0,q.jsx)(P,{as:Re,allowPinchZoom:!0,children:(0,q.jsx)(Ve,{...e,ref:i,trapFocus:n.open,disableOutsidePointerEvents:!0,onCloseAutoFocus:k(e.onCloseAutoFocus,e=>{e.preventDefault(),a.current||n.triggerRef.current?.focus()}),onPointerDownOutside:k(e.onPointerDownOutside,e=>{let t=e.detail.originalEvent,n=t.button===0&&t.ctrlKey===!0;a.current=t.button===2||n},{checkForDefaultPrevented:!1}),onFocusOutside:k(e.onFocusOutside,e=>e.preventDefault(),{checkForDefaultPrevented:!1})})})}),Be=K.forwardRef((e,t)=>{let n=X($,e.__scopePopover),r=K.useRef(!1),i=K.useRef(!1);return(0,q.jsx)(Ve,{...e,ref:t,trapFocus:!1,disableOutsidePointerEvents:!1,onCloseAutoFocus:t=>{e.onCloseAutoFocus?.(t),t.defaultPrevented||(r.current||n.triggerRef.current?.focus(),t.preventDefault()),r.current=!1,i.current=!1},onInteractOutside:t=>{e.onInteractOutside?.(t),t.defaultPrevented||(r.current=!0,t.detail.originalEvent.type===`pointerdown`&&(i.current=!0));let a=t.target;n.triggerRef.current?.contains(a)&&t.preventDefault(),t.detail.originalEvent.type===`focusin`&&i.current&&t.preventDefault()}})}),Ve=K.forwardRef((e,t)=>{let{__scopePopover:n,trapFocus:r,onOpenAutoFocus:i,onCloseAutoFocus:a,disableOutsidePointerEvents:o,onEscapeKeyDown:s,onPointerDownOutside:c,onFocusOutside:l,onInteractOutside:u,...d}=e,f=X($,n),p=Y(n);return I(),(0,q.jsx)(M,{asChild:!0,loop:!0,trapped:r,onMountAutoFocus:i,onUnmountAutoFocus:a,children:(0,q.jsx)(F,{asChild:!0,disableOutsidePointerEvents:o,onInteractOutside:u,onEscapeKeyDown:s,onPointerDownOutside:c,onFocusOutside:l,onDismiss:()=>f.onOpenChange(!1),children:(0,q.jsx)(se,{"data-state":Ke(f.open),role:`dialog`,id:f.contentId,...p,...d,ref:t,style:{...d.style,"--radix-popover-content-transform-origin":`var(--radix-popper-transform-origin)`,"--radix-popover-content-available-width":`var(--radix-popper-available-width)`,"--radix-popover-content-available-height":`var(--radix-popper-available-height)`,"--radix-popover-trigger-width":`var(--radix-popper-anchor-width)`,"--radix-popover-trigger-height":`var(--radix-popper-anchor-height)`}})})})}),He=`PopoverClose`,Ue=K.forwardRef((e,t)=>{let{__scopePopover:n,...r}=e,i=X(He,n);return(0,q.jsx)(O.button,{type:`button`,...r,ref:t,onClick:k(e.onClick,()=>i.onOpenChange(!1))})});Ue.displayName=He;var We=`PopoverArrow`,Ge=K.forwardRef((e,t)=>{let{__scopePopover:n,...r}=e,i=Y(n);return(0,q.jsx)(z,{...i,...r,ref:t})});Ge.displayName=We;function Ke(e){return e?`open`:`closed`}var qe=Ae,Je=Z,Ye=Ie,Xe=Le;function Ze({...e}){return(0,q.jsx)(qe,{"data-slot":`popover`,...e})}function Qe({...e}){return(0,q.jsx)(Je,{"data-slot":`popover-trigger`,...e})}function $e({className:e,align:t=`center`,sideOffset:n=4,...r}){return(0,q.jsx)(Ye,{children:(0,q.jsx)(Xe,{"data-slot":`popover-content`,align:t,sideOffset:n,className:u(`z-50 flex w-72 origin-(--radix-popover-content-transform-origin) flex-col gap-2.5 rounded-lg bg-popover p-2.5 text-sm text-popover-foreground shadow-md ring-1 ring-foreground/10 outline-hidden duration-100 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-95`,e),...r})})}function et({className:e,...t}){return(0,q.jsx)(`div`,{"data-slot":`popover-header`,className:u(`flex flex-col gap-0.5 text-sm`,e),...t})}function tt({className:e,...t}){return(0,q.jsx)(`div`,{"data-slot":`popover-title`,className:u(`font-medium`,e),...t})}function nt({agent:e,childAgents:r=[],parentAgent:a}){let o=ee();v(e=>e.set);let l=v(e=>e.switchView),u=v(e=>e.openInboxThread),p=v(e=>e.openAgentDetail),m=v(e=>e.openPairInvite),y=v(e=>e.openRename),b=v(e=>e.openConfirm),E=v(e=>e.doAgentAction),D=v(e=>e.doDeleteAgent),O=v(e=>e.openFilesForAgent),ie=v(e=>e.workspaceAction),k=v(e=>e.openWorkspaceFocus),{terminalOpen:A,terminalTarget:j,terminalOpening:M,openTerminal:N,closeTerminal:P}=Ce(e.id),F=le(),I=ne(o,e,me(e),F[e.id]||null),L=w(e,`shutdown`),ae=w(e,`compact`),R=w(e,`clearContext`),oe=!!(e.providerCapabilities?.terminal?.live?.read||e.providerCapabilities?.terminal?.attach?.create),z=!!e.providerCapabilities?.terminal?.live?.write,se=re(e),B=a?T(a):e.spawnedBy,W=r.length>0;return(0,q.jsxs)(q.Fragment,{children:[(0,q.jsx)(Se,{className:`group hover:border-zinc-600 transition-colors cursor-pointer`,onClick:()=>p(e),children:(0,q.jsxs)(xe,{className:`p-4`,children:[(0,q.jsxs)(`div`,{className:`flex items-start gap-2.5 mb-2.5`,children:[(0,q.jsx)(G,{agent:e,now:o,className:`mt-0.5`}),(0,q.jsx)(U,{agent:e}),(0,q.jsxs)(`div`,{className:`flex-1 min-w-0`,children:[(0,q.jsxs)(`div`,{className:`flex items-center gap-1 min-w-0`,children:[(0,q.jsx)(we,{profile:Te(e),className:`text-sm shrink-0`}),(0,q.jsx)(`span`,{className:`text-sm font-medium truncate`,children:T(e)})]}),(0,q.jsx)(`div`,{className:`text-xs mt-0.5 ${x(I.tone)}`,children:I.label}),typeof e.meta?.cwd==`string`&&e.meta.cwd&&(0,q.jsx)(`button`,{type:`button`,className:`mt-0.5 block max-w-full truncate font-mono text-[10px] text-muted-foreground hover:text-foreground`,title:`Open ${e.meta.cwd} in Files`,onClick:t=>{t.stopPropagation(),O(e)},children:te(e.meta.cwd)}),(0,q.jsx)(pe,{agent:e,className:`mt-1`})]}),e.branchState&&e.branchWorkspaceId&&(0,q.jsx)(Ee,{state:e.branchState,className:`mt-0.5 shrink-0`,onClick:t=>{t.stopPropagation(),k(e.branchWorkspaceId)}})]}),I.badges.length>0&&(0,q.jsx)(`div`,{className:`flex flex-wrap gap-1 mb-2`,children:I.badges.map(e=>(0,q.jsx)(`span`,{className:`text-[10px] px-1.5 py-0.5 rounded-full font-medium ${e.className}`,children:e.label},e.label))}),(W||e.spawnedBy&&B)&&(0,q.jsxs)(`div`,{className:`mb-2 flex flex-wrap gap-1.5`,onClick:e=>e.stopPropagation(),children:[W&&(0,q.jsxs)(Ze,{children:[(0,q.jsx)(Qe,{asChild:!0,children:(0,q.jsxs)(`button`,{type:`button`,className:`inline-flex h-6 max-w-full items-center gap-1.5 rounded-full border border-sky-500/30 bg-sky-500/10 px-2 text-[10px] font-medium text-sky-300 transition-colors hover:bg-sky-500/15`,title:`${r.length} live child ${r.length===1?`agent`:`agents`}`,children:[(0,q.jsx)(g,{className:`h-3 w-3`}),(0,q.jsx)(`span`,{children:r.length}),(0,q.jsx)(`span`,{className:`flex -space-x-1`,children:r.slice(0,4).map(e=>(0,q.jsx)(G,{agent:e,now:o,className:`h-2 w-2 ring-1 ring-background`},e.id))})]})}),(0,q.jsxs)($e,{align:`start`,className:`w-80`,onClick:e=>e.stopPropagation(),children:[(0,q.jsx)(et,{children:(0,q.jsx)(tt,{children:`Team`})}),(0,q.jsx)(`div`,{className:`space-y-1.5`,children:r.map(e=>(0,q.jsxs)(`div`,{className:`rounded-md border border-border bg-card/60 p-2`,children:[(0,q.jsxs)(`div`,{className:`flex items-start gap-2`,children:[(0,q.jsx)(G,{agent:e,now:o,className:`mt-1`}),(0,q.jsx)(U,{agent:e}),(0,q.jsxs)(`div`,{className:`min-w-0 flex-1`,children:[(0,q.jsx)(`div`,{className:`truncate text-xs font-medium`,children:T(e)}),(0,q.jsx)(`div`,{className:`truncate text-[10px] text-muted-foreground`,children:e.providerCapabilities?.model?.alias||e.providerCapabilities?.model?.id||e.providerCapabilities?.model?.provider||e.status})]}),(0,q.jsx)(V,{variant:`outline`,className:`h-4 px-1.5 text-[9px]`,children:e.status})]}),(0,q.jsxs)(`div`,{className:`mt-2 flex gap-1`,children:[(0,q.jsx)(H,{size:`xs`,variant:`outline`,onClick:()=>p(e),children:`Open`}),(0,q.jsxs)(H,{size:`xs`,variant:`ghost`,onClick:()=>{u(e.id),l(`chat`)},children:[(0,q.jsx)(h,{className:`h-3 w-3`}),`Chat`]})]})]},e.id))})]})]}),e.spawnedBy&&B&&(0,q.jsx)(V,{variant:`outline`,className:`max-w-full text-[10px] text-muted-foreground`,children:(0,q.jsxs)(`span`,{className:`truncate`,children:[`spawned by `,B]})})]}),(e.tags.length>0||C(e.capabilities).length>0)&&(0,q.jsxs)(`div`,{className:`flex flex-wrap gap-1 mb-2`,children:[e.tags.slice(0,3).map(e=>(0,q.jsx)(V,{variant:`outline`,className:`text-[9px] px-1 py-0 h-4`,children:e},e)),C(e.capabilities).slice(0,2).map(e=>(0,q.jsx)(V,{variant:`secondary`,className:`text-[9px] px-1 py-0 h-4`,children:e},e))]}),(0,q.jsxs)(`div`,{className:`space-y-2 mb-2`,children:[(0,q.jsx)(_e,{agent:e}),(0,q.jsx)(be,{agent:e,compact:!0}),(0,q.jsx)(ye,{agent:e})]}),(0,q.jsx)(`div`,{className:`text-xs text-muted-foreground`,children:e.id!==`user`&&e.id!==`system`&&S(o,e.lastSeen)}),(0,q.jsxs)(`div`,{className:`flex gap-1 mt-2.5 opacity-100 sm:opacity-0 sm:group-hover:opacity-100 transition-opacity`,onClick:e=>e.stopPropagation(),children:[(0,q.jsx)(ce,{value:e.id,label:`Copy agent ID`,size:`icon`,className:`h-7 w-7`,iconClassName:`w-3 h-3`}),(0,q.jsx)(H,{size:`icon`,variant:`ghost`,className:`h-7 w-7`,title:`Chat`,onClick:()=>{u(e.id),l(`chat`)},children:(0,q.jsx)(h,{className:`w-3 h-3`})}),(0,q.jsx)(H,{size:`icon`,variant:`ghost`,className:`h-7 w-7`,title:`Pair`,onClick:()=>m(e.id),children:(0,q.jsx)(f,{className:`w-3 h-3`})}),(0,q.jsx)(H,{size:`icon`,variant:`ghost`,className:`h-7 w-7`,title:`Rename`,onClick:()=>y(e),children:(0,q.jsx)(n,{className:`w-3 h-3`})}),oe&&(0,q.jsx)(H,{size:`icon`,variant:`ghost`,className:`h-7 w-7`,title:`Terminal`,disabled:M,onClick:()=>void N(),children:(0,q.jsx)(c,{className:`w-3 h-3`})}),(e.branchState===`changes`||e.branchState===`idle`)&&e.branchWorkspaceId&&(0,q.jsx)(H,{size:`icon`,variant:`ghost`,className:`h-7 w-7 text-amber-400 hover:text-amber-300`,title:`Mark workspace ready — hand off to the auto-merge`,onClick:()=>b(`Mark Workspace Ready`,`Mark ${T(e)}'s branch ready to land? The relay auto-merge will rebase and land it.`,()=>ie(e.branchWorkspaceId,`ready`)),children:(0,q.jsx)(i,{className:`w-3 h-3`})}),ae&&(0,q.jsx)(H,{size:`icon`,variant:`ghost`,className:`h-7 w-7`,title:`Compact`,onClick:()=>b(`Compact Agent`,`Compact context for ${T(e)}?`,()=>E(e,`compact`,`agents-grid`)),children:(0,q.jsx)(t,{className:`w-3 h-3`})}),R&&(0,q.jsx)(H,{size:`icon`,variant:`ghost`,className:`h-7 w-7`,title:`Clear Context`,onClick:()=>b(`Clear Context`,`Clear context for ${T(e)}?`,()=>E(e,`clearContext`,`agents-grid`)),children:(0,q.jsx)(s,{className:`w-3 h-3`})}),L&&(0,q.jsx)(H,{size:`icon`,variant:`ghost`,className:`h-7 w-7 text-red-400 hover:text-red-300`,title:`Shutdown`,onClick:()=>b(`Shutdown Agent`,`Shutdown ${T(e)}?`,()=>E(e,`shutdown`,`agents-grid`)),children:(0,q.jsx)(_,{className:`w-3 h-3`})}),se&&(0,q.jsx)(H,{size:`icon`,variant:`ghost`,className:`h-7 w-7 text-red-400 hover:text-red-300`,title:`Forget stale agent`,onClick:()=>b(`Forget Agent`,`Forget ${T(e)}?`,()=>D(e.id)),children:(0,q.jsx)(d,{className:`w-3 h-3`})})]})]})}),j&&(0,q.jsx)(he,{open:A,onOpenChange:P,orchestratorId:j.orchestratorId,session:j.session,interactive:j.interactive||z,canWrite:z})]})}function rt(){let e=v(e=>e.agentPresetFilter),t=v(e=>e.agentStatusFilter),n=v(e=>e.agentTagFilter),i=v(e=>e.agentHostFilter),s=v(e=>e.agentSort),c=v(e=>e.agentSortDir),u=v(e=>e.showOffline),d=v(e=>e.set),f=v(e=>e.openAgentSpawn),p=v(e=>e.agentsById),m=ee(),h=W(),g=ge(),_=de(),x=ve(h,m),S=fe(h,m),te=e||t||n||i;function C(){d({agentPresetFilter:``,agentStatusFilter:``,agentTagFilter:``,agentHostFilter:``})}function w(){d({agentSortDir:c===`asc`?`desc`:`asc`})}return(0,q.jsxs)(`div`,{className:`space-y-4`,children:[(0,q.jsxs)(`div`,{className:`flex flex-wrap items-center gap-2`,children:[(0,q.jsxs)(`select`,{value:e,onChange:e=>d({agentPresetFilter:e.target.value}),className:`h-8 rounded-md border border-border bg-card text-sm px-2 text-foreground`,children:[(0,q.jsx)(`option`,{value:``,children:`All agents`}),(0,q.jsx)(`option`,{value:`active`,children:`Active`}),b().map(e=>(0,q.jsx)(`option`,{value:e,children:y(e)},e)),(0,q.jsx)(`option`,{value:`paired`,children:`Paired`}),(0,q.jsx)(`option`,{value:`unpaired`,children:`Unpaired`}),(0,q.jsx)(`option`,{value:`offline_stale`,children:`Offline / Stale`})]}),(0,q.jsxs)(`select`,{value:t,onChange:e=>d({agentStatusFilter:e.target.value}),className:`h-8 rounded-md border border-border bg-card text-sm px-2 text-foreground`,children:[(0,q.jsx)(`option`,{value:``,children:`Any status`}),(0,q.jsx)(`option`,{value:`online`,children:`Online`}),(0,q.jsx)(`option`,{value:`idle`,children:`Idle`}),(0,q.jsx)(`option`,{value:`busy`,children:`Busy`}),(0,q.jsx)(`option`,{value:`offline`,children:`Offline`}),(0,q.jsx)(`option`,{value:`starting`,children:`Starting`})]}),g.length>0&&(0,q.jsxs)(`select`,{value:n,onChange:e=>d({agentTagFilter:e.target.value}),className:`h-8 rounded-md border border-border bg-card text-sm px-2 text-foreground`,children:[(0,q.jsx)(`option`,{value:``,children:`Any tag`}),g.map(e=>(0,q.jsx)(`option`,{value:e,children:e},e))]}),_.length>1&&(0,q.jsxs)(`select`,{value:i,onChange:e=>d({agentHostFilter:e.target.value}),className:`h-8 rounded-md border border-border bg-card text-sm px-2 text-foreground`,children:[(0,q.jsx)(`option`,{value:``,children:`Any host`}),_.map(e=>(0,q.jsx)(`option`,{value:e,children:e},e))]}),(0,q.jsxs)(`select`,{value:s,onChange:e=>d({agentSort:e.target.value}),className:`h-8 rounded-md border border-border bg-card text-sm px-2 text-foreground`,children:[(0,q.jsx)(`option`,{value:`status`,children:`Sort: Status`}),(0,q.jsx)(`option`,{value:`name`,children:`Sort: Name`}),(0,q.jsx)(`option`,{value:`lastSeen`,children:`Sort: Last seen`}),(0,q.jsx)(`option`,{value:`created`,children:`Sort: Created`})]}),(0,q.jsx)(H,{size:`icon`,variant:`outline`,className:`h-8 w-8`,title:`Toggle sort direction`,onClick:w,children:c===`asc`?(0,q.jsx)(a,{className:`w-3.5 h-3.5`}):(0,q.jsx)(o,{className:`w-3.5 h-3.5`})}),(0,q.jsxs)(`label`,{className:`flex items-center gap-1.5 text-sm text-muted-foreground cursor-pointer select-none`,children:[(0,q.jsx)(`input`,{type:`checkbox`,checked:u,onChange:e=>d({showOffline:e.target.checked}),className:`rounded`}),`Show offline`]}),te&&(0,q.jsxs)(H,{size:`sm`,variant:`ghost`,className:`h-8 text-muted-foreground hover:text-foreground gap-1`,onClick:C,children:[(0,q.jsx)(l,{className:`w-3 h-3`}),`Clear filters`]}),(0,q.jsx)(`div`,{className:`ml-auto`,children:(0,q.jsxs)(H,{size:`sm`,onClick:f,className:`gap-1`,children:[(0,q.jsx)(r,{className:`w-3.5 h-3.5`}),`Spawn`]})})]}),S.length===0?(0,q.jsx)(`div`,{className:`text-center py-16 text-muted-foreground text-sm`,children:`No agents match the current filters.`}):(0,q.jsx)(`div`,{className:`grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 xl:grid-cols-4 gap-3`,children:S.map(e=>(0,q.jsx)(nt,{agent:e,parentAgent:e.spawnedBy?p[e.spawnedBy]??null:null,childAgents:ue(x.get(e.id)??[])},e.id))})]})}export{rt as AgentsView};
|
|
2
|
-
//# sourceMappingURL=agents-BkC6mcTh.js.map
|
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
import{r as e}from"./chunk-CilyBKbf.js";import{dn as t,er as n,h as r,hr as i,jt as a,nr as o,o as s,rr as c,yn as l}from"./lucide-react-DuhlF2Sj.js";import{t as u}from"./store-DMZSTozC.js";var d=e(i(),1);function f(e){let t=u(e=>e.showError),[n,r]=(0,d.useState)(!1),[i,a]=(0,d.useState)(null),[o,s]=(0,d.useState)(!1);async function l(){if(!(!e||o)){s(!0);try{a(await c(`POST`,`/agents/`+encodeURIComponent(e)+`/terminal-session`)),r(!0)}catch(e){t(`Terminal Failed`,e.message)}finally{s(!1)}}}function f(t){if(t){r(!0);return}r(!1);let n=i;a(null),e&&n?.mode===`guest`&&c(`DELETE`,`/agents/`+encodeURIComponent(e)+`/terminal-session/`+encodeURIComponent(n.session)).catch(()=>{})}return{terminalOpen:n,terminalTarget:i,terminalOpening:o,openTerminal:l,closeTerminal:f}}var p=o(),m=`•`;function h(e){return u(t=>e&&t.agentProfiles.find(t=>t.name===e)?.icon?.trim()||null)}function g(e){return typeof e?.meta?.profile==`string`?e.meta.profile:void 0}function _({profile:e,className:t,title:r}){let i=h(e),a=r??(e?`Profile: ${e}`:`No profile`);return(0,p.jsx)(`span`,{role:`img`,"aria-label":a,title:a,className:n(`inline-flex items-center justify-center leading-none select-none`,!i&&`text-muted-foreground/70`,t),children:i??m})}var v={idle:{label:`idle`,tip:`Branch worktree — nothing to land yet.`,className:`bg-zinc-500/10 text-zinc-400 border-zinc-500/20`,Icon:t},changes:{label:`changes`,tip:`Unlanded work in this branch — use "Mark workspace ready" to land it.`,className:`bg-amber-500/10 text-amber-400 border-amber-500/20`,Icon:a},ready:{label:`ready`,tip:`Handed off — the relay auto-merge will land it (~2 min sweep).`,className:`bg-blue-500/10 text-blue-400 border-blue-500/20`,Icon:l},steward:{label:`steward`,tip:`Under reconciliation — a steward is landing it. No action needed.`,className:`bg-orange-500/10 text-orange-400 border-orange-500/20`,Icon:s},blocked:{label:`blocked`,tip:`Escalated — the auto-merge/steward path is stuck. Needs human attention.`,className:`bg-red-500/10 text-red-400 border-red-500/20`,Icon:r}};function y({state:e,onClick:t,iconOnly:r=!1,className:i}){let a=v[e],{Icon:o}=a,s=!!t,c=s?`${a.tip} Click to open this workspace.`:a.tip;return(0,p.jsxs)(`span`,{role:s?`button`:void 0,tabIndex:s?0:void 0,title:c,onClick:t,onKeyDown:s?e=>{(e.key===`Enter`||e.key===` `)&&(e.preventDefault(),t?.(e))}:void 0,className:n(`inline-flex items-center gap-1 rounded-full border px-1.5 py-0.5 text-[10px] font-medium leading-none`,a.className,s&&`cursor-pointer hover:brightness-125 focus:outline-none focus:ring-1 focus:ring-current`,i),children:[(0,p.jsx)(o,{className:`h-2.5 w-2.5 shrink-0`}),!r&&(0,p.jsx)(`span`,{children:a.label})]})}export{f as i,_ as n,g as r,y as t};
|
|
2
|
-
//# sourceMappingURL=branch-state-badge-CNW10MTC.js.map
|
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
import"./chunk-CilyBKbf.js";import{er as e,hr as t,nr as n}from"./lucide-react-DuhlF2Sj.js";t();var r=n();function i({className:t,size:n=`default`,...i}){return(0,r.jsx)(`div`,{"data-slot":`card`,"data-size":n,className:e(`group/card flex flex-col gap-4 overflow-hidden rounded-xl bg-card py-4 text-sm text-card-foreground ring-1 ring-foreground/10 has-data-[slot=card-footer]:pb-0 has-[>img:first-child]:pt-0 data-[size=sm]:gap-3 data-[size=sm]:py-3 data-[size=sm]:has-data-[slot=card-footer]:pb-0 *:[img:first-child]:rounded-t-xl *:[img:last-child]:rounded-b-xl`,t),...i})}function a({className:t,...n}){return(0,r.jsx)(`div`,{"data-slot":`card-header`,className:e(`group/card-header @container/card-header grid auto-rows-min items-start gap-1 rounded-t-xl px-4 group-data-[size=sm]/card:px-3 has-data-[slot=card-action]:grid-cols-[1fr_auto] has-data-[slot=card-description]:grid-rows-[auto_auto] [.border-b]:pb-4 group-data-[size=sm]/card:[.border-b]:pb-3`,t),...n})}function o({className:t,...n}){return(0,r.jsx)(`div`,{"data-slot":`card-title`,className:e(`font-heading text-base leading-snug font-medium group-data-[size=sm]/card:text-sm`,t),...n})}function s({className:t,...n}){return(0,r.jsx)(`div`,{"data-slot":`card-description`,className:e(`text-sm text-muted-foreground`,t),...n})}function c({className:t,...n}){return(0,r.jsx)(`div`,{"data-slot":`card-action`,className:e(`col-start-2 row-span-2 row-start-1 self-start justify-self-end`,t),...n})}function l({className:t,...n}){return(0,r.jsx)(`div`,{"data-slot":`card-content`,className:e(`px-4 group-data-[size=sm]/card:px-3`,t),...n})}function u({className:t,...n}){return(0,r.jsx)(`div`,{"data-slot":`card-footer`,className:e(`flex items-center rounded-b-xl border-t bg-muted/50 p-4 group-data-[size=sm]/card:p-3`,t),...n})}export{u as a,s as i,c as n,a as o,l as r,o as s,i as t};
|
|
2
|
-
//# sourceMappingURL=card-C3BGuVC6.js.map
|