agent-relay-server 0.94.5 → 0.95.0
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/docs/openapi.json +1 -1
- package/package.json +2 -2
- package/public/assets/MessageBubble-CkPnAwxJ.js +3 -0
- package/public/assets/{MessageBubble-g4NKZBDI.js.map → MessageBubble-CkPnAwxJ.js.map} +1 -1
- package/public/assets/{PlanGraphPanel-Chydc7yG.js → PlanGraphPanel-DPgW_Ohe.js} +2 -2
- package/public/assets/{PlanGraphPanel-Chydc7yG.js.map → PlanGraphPanel-DPgW_Ohe.js.map} +1 -1
- package/public/assets/{activity-BXLw6f9y.js → activity-CRebaL8O.js} +2 -2
- package/public/assets/{activity-BXLw6f9y.js.map → activity-CRebaL8O.js.map} +1 -1
- package/public/assets/{agent-profiles-B6PsZZmM.js → agent-profiles-BFpEQHKo.js} +2 -2
- package/public/assets/{agent-profiles-B6PsZZmM.js.map → agent-profiles-BFpEQHKo.js.map} +1 -1
- package/public/assets/{agents-B0POygaD.js → agents-7WtV1Pf3.js} +2 -2
- package/public/assets/{agents-B0POygaD.js.map → agents-7WtV1Pf3.js.map} +1 -1
- package/public/assets/{analytics-B50LtRMU.js → analytics-DpnJh9UQ.js} +3 -3
- package/public/assets/{analytics-B50LtRMU.js.map → analytics-DpnJh9UQ.js.map} +1 -1
- package/public/assets/{automation-CeYilS-s.js → automation-CjQNCXlO.js} +2 -2
- package/public/assets/{automation-CeYilS-s.js.map → automation-CjQNCXlO.js.map} +1 -1
- package/public/assets/{badge-CcTIPkUa.js → badge-BbfOskRI.js} +2 -2
- package/public/assets/{badge-CcTIPkUa.js.map → badge-BbfOskRI.js.map} +1 -1
- package/public/assets/branch-state-badge-BcObk0ca.js +2 -0
- package/public/assets/{branch-state-badge-T6t16OU5.js.map → branch-state-badge-BcObk0ca.js.map} +1 -1
- package/public/assets/{button-Dvz6HZ1j.js → button-DWiw--lT.js} +2 -2
- package/public/assets/{button-Dvz6HZ1j.js.map → button-DWiw--lT.js.map} +1 -1
- package/public/assets/{card-xVEUTFuh.js → card-BeqvuYTT.js} +2 -2
- package/public/assets/{card-xVEUTFuh.js.map → card-BeqvuYTT.js.map} +1 -1
- package/public/assets/channels-B2bftzgH.js +2 -0
- package/public/assets/{channels-C0J-VHEa.js.map → channels-B2bftzgH.js.map} +1 -1
- package/public/assets/chat-Dcwua_5V.js +2 -0
- package/public/assets/chat-Dcwua_5V.js.map +1 -0
- package/public/assets/{connectors-P5V_DlvA.js → connectors-CJOJirYT.js} +2 -2
- package/public/assets/{connectors-P5V_DlvA.js.map → connectors-CJOJirYT.js.map} +1 -1
- package/public/assets/copy-button-CIXy8ks6.js +2 -0
- package/public/assets/{copy-button-gB8Wc3dh.js.map → copy-button-CIXy8ks6.js.map} +1 -1
- package/public/assets/display-DRiGi1zj.js.map +1 -1
- package/public/assets/{dist-DbJ0cYxd.js → dist-BQXmO19g.js} +2 -2
- package/public/assets/{dist-DbJ0cYxd.js.map → dist-BQXmO19g.js.map} +1 -1
- package/public/assets/{dist-CE9yg7LH.js → dist-BufB2Xy_.js} +2 -2
- package/public/assets/{dist-CE9yg7LH.js.map → dist-BufB2Xy_.js.map} +1 -1
- package/public/assets/dist-CXkmW1Od.js +2 -0
- package/public/assets/{dist-4Joy6mhT.js.map → dist-CXkmW1Od.js.map} +1 -1
- package/public/assets/{dist-DoHTwsqW.js → dist-CbxR2pzD.js} +2 -2
- package/public/assets/{dist-DoHTwsqW.js.map → dist-CbxR2pzD.js.map} +1 -1
- package/public/assets/{dist-Cu5eOAWz.js → dist-CtuS_3Jl.js} +2 -2
- package/public/assets/{dist-Cu5eOAWz.js.map → dist-CtuS_3Jl.js.map} +1 -1
- package/public/assets/{dist-CVWxY_y8.js → dist-Du_bcq-z.js} +2 -2
- package/public/assets/{dist-CVWxY_y8.js.map → dist-Du_bcq-z.js.map} +1 -1
- package/public/assets/{dist-BkHh9GoG.js → dist-KxiSP9h9.js} +2 -2
- package/public/assets/{dist-BkHh9GoG.js.map → dist-KxiSP9h9.js.map} +1 -1
- package/public/assets/dist-LFuRypZd.js +2 -0
- package/public/assets/{dist-4O7O9HEE.js.map → dist-LFuRypZd.js.map} +1 -1
- package/public/assets/dist-Q6OOS84U.js +2 -0
- package/public/assets/{dist-B2WymQRX.js.map → dist-Q6OOS84U.js.map} +1 -1
- package/public/assets/{dist-B5OjWLDL.js → dist-eG_93I3z.js} +2 -2
- package/public/assets/{dist-B5OjWLDL.js.map → dist-eG_93I3z.js.map} +1 -1
- package/public/assets/{dist-XUy-xPl6.js → dist-zTw85jD8.js} +2 -2
- package/public/assets/{dist-XUy-xPl6.js.map → dist-zTw85jD8.js.map} +1 -1
- package/public/assets/{es2015-Dv7v8EgR.js → es2015-ibwCE_JR.js} +2 -2
- package/public/assets/{es2015-Dv7v8EgR.js.map → es2015-ibwCE_JR.js.map} +1 -1
- package/public/assets/{formatted-body-impl-B8xoPLk0.js → formatted-body-impl-CGACmUqI.js} +2 -2
- package/public/assets/{formatted-body-impl-B8xoPLk0.js.map → formatted-body-impl-CGACmUqI.js.map} +1 -1
- package/public/assets/index-CKPsJqiW.css +2 -0
- package/public/assets/index-CwhhpGgX.js +23 -0
- package/public/assets/index-CwhhpGgX.js.map +1 -0
- package/public/assets/{input-CWYjJ4Bn.js → input-DUdtS3nG.js} +2 -2
- package/public/assets/{input-CWYjJ4Bn.js.map → input-DUdtS3nG.js.map} +1 -1
- package/public/assets/{insights-O02aG6Fa.js → insights-DqXjTYai.js} +2 -2
- package/public/assets/{insights-O02aG6Fa.js.map → insights-DqXjTYai.js.map} +1 -1
- package/public/assets/{integrations-COYT1FSR.js → integrations-DEgLatDv.js} +2 -2
- package/public/assets/{integrations-COYT1FSR.js.map → integrations-DEgLatDv.js.map} +1 -1
- package/public/assets/{lib-C6ShgLFg.js → lib-Gp69YB9e.js} +3 -3
- package/public/assets/{lib-C6ShgLFg.js.map → lib-Gp69YB9e.js.map} +1 -1
- package/public/assets/lucide-react-uFIMC7W7.js +9 -0
- package/public/assets/{lucide-react-BMjjWU36.js.map → lucide-react-uFIMC7W7.js.map} +1 -1
- package/public/assets/{maintenance-CsaxFb2K.js → maintenance-CcFJlNxt.js} +2 -2
- package/public/assets/{maintenance-CsaxFb2K.js.map → maintenance-CcFJlNxt.js.map} +1 -1
- package/public/assets/{managed-agents-BkMSa35M.js → managed-agents-CHR4Hx1O.js} +4 -4
- package/public/assets/{managed-agents-BkMSa35M.js.map → managed-agents-CHR4Hx1O.js.map} +1 -1
- package/public/assets/{markdown-preview-impl-CPUObdGL.js → markdown-preview-impl-BHaUcnfn.js} +2 -2
- package/public/assets/{markdown-preview-impl-CPUObdGL.js.map → markdown-preview-impl-BHaUcnfn.js.map} +1 -1
- package/public/assets/{memory-Bc9b5aFW.js → memory-Uk0VfqnC.js} +2 -2
- package/public/assets/{memory-Bc9b5aFW.js.map → memory-Uk0VfqnC.js.map} +1 -1
- package/public/assets/{messages-DDUpkDDo.js → messages-D_juCBfr.js} +2 -2
- package/public/assets/{messages-DDUpkDDo.js.map → messages-D_juCBfr.js.map} +1 -1
- package/public/assets/{orchestrators-CTiypI_B.js → orchestrators-8IrmgeHV.js} +2 -2
- package/public/assets/{orchestrators-CTiypI_B.js.map → orchestrators-8IrmgeHV.js.map} +1 -1
- package/public/assets/{overview-DT05JmLC.js → overview-D_DM0QHJ.js} +2 -2
- package/public/assets/{overview-DT05JmLC.js.map → overview-D_DM0QHJ.js.map} +1 -1
- package/public/assets/{pairs-VlxzegP3.js → pairs-jciDuPLn.js} +2 -2
- package/public/assets/{pairs-VlxzegP3.js.map → pairs-jciDuPLn.js.map} +1 -1
- package/public/assets/{projects-5xutbu4r.js → projects-C-QHyuMD.js} +2 -2
- package/public/assets/{projects-5xutbu4r.js.map → projects-C-QHyuMD.js.map} +1 -1
- package/public/assets/{react-dom-D1K8FBqJ.js → react-dom-DF2cuNaf.js} +2 -2
- package/public/assets/{react-dom-D1K8FBqJ.js.map → react-dom-DF2cuNaf.js.map} +1 -1
- package/public/assets/{registry-dClAc8d-.js → registry-D1EIvc8U.js} +2 -2
- package/public/assets/{registry-dClAc8d-.js.map → registry-D1EIvc8U.js.map} +1 -1
- package/public/assets/{security-sGs_RWhJ.js → security-C0_Df9yI.js} +2 -2
- package/public/assets/{security-sGs_RWhJ.js.map → security-C0_Df9yI.js.map} +1 -1
- package/public/assets/{select-AzzgLRfk.js → select-CXFXPZ7Z.js} +2 -2
- package/public/assets/{select-AzzgLRfk.js.map → select-CXFXPZ7Z.js.map} +1 -1
- package/public/assets/settings-DGPpdFoq.js +6 -0
- package/public/assets/{settings-A0LUC7z3.js.map → settings-DGPpdFoq.js.map} +1 -1
- package/public/assets/store-d-IbqTaD.js +9 -0
- package/public/assets/store-d-IbqTaD.js.map +1 -0
- package/public/assets/{tasks-QfihaEd7.js → tasks-B_epVa5b.js} +2 -2
- package/public/assets/{tasks-QfihaEd7.js.map → tasks-B_epVa5b.js.map} +1 -1
- package/public/assets/teams-D2hATpCD.js +2 -0
- package/public/assets/{teams-yi_-_mib.js.map → teams-D2hATpCD.js.map} +1 -1
- package/public/assets/{terminal-viewer-impl-BuXn1PG3.js → terminal-viewer-impl-CefeetWa.js} +3 -3
- package/public/assets/{terminal-viewer-impl-BuXn1PG3.js.map → terminal-viewer-impl-CefeetWa.js.map} +1 -1
- package/public/assets/types-Tv67voFu.js.map +1 -1
- package/public/assets/{use-keyboard-viewport-BAtKHKT6.js → use-keyboard-viewport-CeLM-PeW.js} +2 -2
- package/public/assets/{use-keyboard-viewport-BAtKHKT6.js.map → use-keyboard-viewport-CeLM-PeW.js.map} +1 -1
- package/public/assets/{user-avatar-D5hoY3pJ.js → user-avatar-BOGZ21O8.js} +2 -2
- package/public/assets/{user-avatar-D5hoY3pJ.js.map → user-avatar-BOGZ21O8.js.map} +1 -1
- package/public/assets/{work-queue-pZe5uRpJ.js → work-queue-C9wBOivX.js} +2 -2
- package/public/assets/{work-queue-pZe5uRpJ.js.map → work-queue-C9wBOivX.js.map} +1 -1
- package/public/assets/{workspaces-DVh1TmHX.js → workspaces-DKFmnOF8.js} +3 -3
- package/public/assets/{workspaces-DVh1TmHX.js.map → workspaces-DKFmnOF8.js.map} +1 -1
- package/public/index.html +21 -21
- package/runner/plugins/claude/.claude-plugin/plugin.json +1 -1
- package/src/agent-busy-health.ts +12 -1
- package/src/codex-wham-quota.ts +4 -1
- package/src/config-store.ts +16 -5
- package/src/db/provider-quotas.ts +45 -15
- package/src/maintenance/jobs.ts +0 -1
- package/src/mcp/index.ts +22 -0
- package/src/notification-router.ts +4 -0
- package/src/notification-rules.ts +87 -6
- package/src/notification-types.ts +12 -0
- package/src/runtime-tokens.ts +3 -1
- package/public/assets/MessageBubble-g4NKZBDI.js +0 -3
- package/public/assets/branch-state-badge-T6t16OU5.js +0 -2
- package/public/assets/channels-C0J-VHEa.js +0 -2
- package/public/assets/chat-KKQrWEE_.js +0 -2
- package/public/assets/chat-KKQrWEE_.js.map +0 -1
- package/public/assets/copy-button-gB8Wc3dh.js +0 -2
- package/public/assets/dist-4Joy6mhT.js +0 -2
- package/public/assets/dist-4O7O9HEE.js +0 -2
- package/public/assets/dist-B2WymQRX.js +0 -2
- package/public/assets/index-D9oZL47o.js +0 -23
- package/public/assets/index-D9oZL47o.js.map +0 -1
- package/public/assets/index-DcyinRQU.css +0 -2
- package/public/assets/lucide-react-BMjjWU36.js +0 -9
- package/public/assets/settings-A0LUC7z3.js +0 -6
- package/public/assets/store-Bfl3XVmS.js +0 -9
- package/public/assets/store-Bfl3XVmS.js.map +0 -1
- package/public/assets/teams-yi_-_mib.js +0 -2
package/src/mcp/index.ts
CHANGED
|
@@ -39,6 +39,23 @@ const TOOLS: ToolDefinition[] = [
|
|
|
39
39
|
...NTFY_TOOLS,
|
|
40
40
|
];
|
|
41
41
|
|
|
42
|
+
// Tool group membership (#551). Each tool belongs to exactly one group; toolGroups in the token
|
|
43
|
+
// constraints lists which groups are enabled (absent = all). This is the surface/eager layer on
|
|
44
|
+
// top of scope-gating — scope enforcement at tools/call stays authoritative.
|
|
45
|
+
export const RELAY_TOOL_GROUPS: Record<string, readonly string[]> = {
|
|
46
|
+
core: ["relay_whoami", "relay_send_message", "relay_reply", "relay_get_message", "relay_get_thread", "relay_find_agents"],
|
|
47
|
+
memory: ["relay_recall", "relay_compact_and_resume"],
|
|
48
|
+
artifacts: ["relay_upload_artifact", "relay_attach_artifact"],
|
|
49
|
+
workspace: ["relay_workspace_status", "relay_workspace_ready", "relay_workspace_deps", "relay_workspace_list", "relay_workspace_claim", "relay_workspace_release", "relay_workspace_land", "relay_merge_pause", "relay_merge_pauses", "relay_merge_renew", "relay_merge_resume"],
|
|
50
|
+
"spawn-lifecycle": ["relay_spawn_agent", "relay_spawn_targets", "relay_my_agents", "relay_shutdown_agent", "relay_agent_action", "relay_agent_status", "relay_agent_crash_report", "relay_schedule_timer", "relay_list_timers", "relay_cancel_timer"],
|
|
51
|
+
plans: ["relay_plan_create", "relay_plan_add_node", "relay_plan_update_node", "relay_plan_add_edge", "relay_plan_remove_node", "relay_plan_remove_edge", "relay_plan_delete", "relay_plan_get"],
|
|
52
|
+
teams: ["relay_team_get", "relay_team_set_brief", "relay_team_claim", "relay_team_dissolve"],
|
|
53
|
+
blackboard: ["relay_blackboard_write", "relay_blackboard_get", "relay_blackboard_read", "relay_blackboard_search", "relay_blackboard_retract"],
|
|
54
|
+
project: ["relay_project_list", "relay_project_get", "relay_project_add_root", "relay_project_write_entry", "relay_project_read", "relay_project_search", "relay_project_retract", "relay_project_add_edge", "relay_project_remove_edge", "relay_project_promote_entry", "relay_project_ingest_claudemd"],
|
|
55
|
+
issues: ["relay_issue_ref_upsert", "relay_issue_ref_resolve", "relay_issue_ref_get", "relay_issue_ref_list", "relay_issue_ref_update", "relay_issue_ref_delete", "relay_issue_association_associate", "relay_issue_association_list_issues_for_entity", "relay_issue_association_list_entities_for_issue", "relay_issue_association_remove", "relay_issue_activity_record", "relay_issue_activity_by_issue", "relay_issue_activity_by_agent", "relay_issue_lifecycle_reopen"],
|
|
56
|
+
subscriptions: ["relay_subscribe", "relay_unsubscribe", "relay_list_subscriptions", "relay_why_notified", "relay_notification_preview", "relay_notify_ntfy"],
|
|
57
|
+
};
|
|
58
|
+
|
|
42
59
|
export async function postMcp(req: Request): Promise<Response> {
|
|
43
60
|
const parsed = await parseJsonRpcRequest(req);
|
|
44
61
|
if (!parsed.ok) return Response.json(jsonRpcError(null, -32700, parsed.error), { status: parsed.status });
|
|
@@ -164,8 +181,13 @@ async function callTool(auth: McpAuthContext, params: unknown): Promise<Record<s
|
|
|
164
181
|
}
|
|
165
182
|
|
|
166
183
|
function visibleTools(auth: McpAuthContext): Array<Record<string, unknown>> {
|
|
184
|
+
const enabledGroups = auth.component?.constraints?.toolGroups;
|
|
185
|
+
const allowedNames = enabledGroups
|
|
186
|
+
? new Set(enabledGroups.flatMap((g) => RELAY_TOOL_GROUPS[g] ?? []))
|
|
187
|
+
: null;
|
|
167
188
|
return TOOLS
|
|
168
189
|
.filter((tool) => hasAnyScope(auth, tool.requiredScopes))
|
|
190
|
+
.filter((tool) => !allowedNames || allowedNames.has(tool.name))
|
|
169
191
|
.map(({ name, description, alwaysLoad, ...tool }) => ({
|
|
170
192
|
name,
|
|
171
193
|
description,
|
|
@@ -203,6 +203,10 @@ function routingReason(
|
|
|
203
203
|
): string {
|
|
204
204
|
if (!settingsEnabled) return "notifications are disabled for this recipient by settings";
|
|
205
205
|
if (matchedRule === "author") return "you are the author";
|
|
206
|
+
if (matchedRule === "targeted-at-user") return "you are directly targeted";
|
|
207
|
+
if (matchedRule === "spawned-by-user") return "you directly spawned this agent";
|
|
208
|
+
if (matchedRule === "spawn-parent-of") return "you are the subject agent's spawn parent";
|
|
209
|
+
if (matchedRule === "thread-participant") return "you are a participant in this thread";
|
|
206
210
|
if (matchedRule === "spawn-parent") return "you are the spawn parent";
|
|
207
211
|
if (matchedRule === "subject-agent") return "you are the notification subject";
|
|
208
212
|
if (matchedRule === "same-team") return scope.teamId ? `same team ${scope.teamId}` : "same team";
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { AgentCard } from "./types";
|
|
2
|
-
import {
|
|
2
|
+
import { canonicalHumanAgentId, isHumanAgentId } from "agent-relay-sdk";
|
|
3
|
+
import { getAgent, getThread, listAgents } from "./db";
|
|
3
4
|
import { isAgentOnline } from "./agent-ref";
|
|
4
5
|
import { notificationEnabledFor } from "./notification-settings-store";
|
|
5
6
|
import type { NotificationType, NotificationScope } from "./notification-types";
|
|
@@ -40,6 +41,31 @@ interface AudienceMember {
|
|
|
40
41
|
matchedRule: string;
|
|
41
42
|
}
|
|
42
43
|
|
|
44
|
+
function sameAddress(a: string | undefined, b: string | undefined): boolean {
|
|
45
|
+
if (!a || !b) return false;
|
|
46
|
+
if (isHumanAgentId(a) || isHumanAgentId(b)) return canonicalHumanAgentId(a) === canonicalHumanAgentId(b);
|
|
47
|
+
return a === b;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
function subjectParent(scope: NotificationScope): string | undefined {
|
|
51
|
+
if (scope.parent) return scope.parent;
|
|
52
|
+
return scope.agentId ? getAgent(scope.agentId)?.spawnedBy : undefined;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
function threadParticipantIds(scope: NotificationScope): Set<string> {
|
|
56
|
+
const ids = new Set<string>();
|
|
57
|
+
for (const id of scope.participants ?? []) {
|
|
58
|
+
if (id.trim()) ids.add(id);
|
|
59
|
+
}
|
|
60
|
+
if (typeof scope.threadId === "number" && Number.isSafeInteger(scope.threadId) && scope.threadId > 0) {
|
|
61
|
+
for (const message of getThread(scope.threadId)) {
|
|
62
|
+
ids.add(message.from);
|
|
63
|
+
ids.add(message.to);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
return ids;
|
|
67
|
+
}
|
|
68
|
+
|
|
43
69
|
/**
|
|
44
70
|
* Predicate library — the reusable building blocks each type composes its default audience from.
|
|
45
71
|
* Each factory returns a single-concern rule. `deliver` includes the agent; `abstain` leaves the
|
|
@@ -47,6 +73,38 @@ interface AudienceMember {
|
|
|
47
73
|
* shape #443 builds on). Compose them ordered: later rules override earlier (see {@link evaluateAudience}).
|
|
48
74
|
*/
|
|
49
75
|
export const audiencePredicates = {
|
|
76
|
+
/** A human directly targeted by the message/chat event. */
|
|
77
|
+
targetedAtUser: (): NotificationRule => ({
|
|
78
|
+
name: "targeted-at-user",
|
|
79
|
+
evaluate: (a, { scope }) => {
|
|
80
|
+
if (!isHumanAgentId(a.id)) return "abstain";
|
|
81
|
+
const target = scope.to ?? scope.target;
|
|
82
|
+
return sameAddress(a.id, target) ? "deliver" : "abstain";
|
|
83
|
+
},
|
|
84
|
+
}),
|
|
85
|
+
/** A human directly spawned the subject agent. Depth-1 only; grandchildren abstain. */
|
|
86
|
+
spawnedByUser: (): NotificationRule => ({
|
|
87
|
+
name: "spawned-by-user",
|
|
88
|
+
evaluate: (a, { scope }) => {
|
|
89
|
+
if (!isHumanAgentId(a.id)) return "abstain";
|
|
90
|
+
return sameAddress(a.id, subjectParent(scope)) ? "deliver" : "abstain";
|
|
91
|
+
},
|
|
92
|
+
}),
|
|
93
|
+
/** The subject agent's spawn-parent, deriving it from `scope.agentId` when needed. */
|
|
94
|
+
spawnParentOf: (): NotificationRule => ({
|
|
95
|
+
name: "spawn-parent-of",
|
|
96
|
+
evaluate: (a, { scope }) => (sameAddress(a.id, subjectParent(scope)) ? "deliver" : "abstain"),
|
|
97
|
+
}),
|
|
98
|
+
/** Any participant in the message/chat thread. */
|
|
99
|
+
threadParticipant: (): NotificationRule => ({
|
|
100
|
+
name: "thread-participant",
|
|
101
|
+
evaluate: (a, { scope }) => {
|
|
102
|
+
for (const participant of threadParticipantIds(scope)) {
|
|
103
|
+
if (sameAddress(a.id, participant)) return "deliver";
|
|
104
|
+
}
|
|
105
|
+
return "abstain";
|
|
106
|
+
},
|
|
107
|
+
}),
|
|
50
108
|
/** The agent whose work the notification is about — delivered even when offline (store-ahead #234). */
|
|
51
109
|
author: (): NotificationRule => ({
|
|
52
110
|
name: "author",
|
|
@@ -96,14 +154,15 @@ export const audiencePredicates = {
|
|
|
96
154
|
} as const;
|
|
97
155
|
|
|
98
156
|
/**
|
|
99
|
-
* The candidate pool for rule evaluation: every registered agent EXCEPT
|
|
100
|
-
*
|
|
101
|
-
*
|
|
102
|
-
* offline target; per-rule `onlineOnly` gates
|
|
157
|
+
* The candidate pool for rule evaluation: every registered agent EXCEPT `system` and channel agents,
|
|
158
|
+
* which are never wake-notification recipients. Human sinks stay in the pool so human-surface rules
|
|
159
|
+
* can decide when `user` belongs in an audience. Offline agents stay IN deliberately — a store-ahead
|
|
160
|
+
* rule (author/spawn-parent) must be able to select an offline target; per-rule `onlineOnly` gates
|
|
161
|
+
* the cases that need liveness (e.g. on-repo-root fan-out).
|
|
103
162
|
*/
|
|
104
163
|
export function audienceCandidates(): AgentCard[] {
|
|
105
164
|
return listAgents().filter(
|
|
106
|
-
(a) => a.id !== "system" && a.
|
|
165
|
+
(a) => a.id !== "system" && a.kind !== "system" && a.kind !== "channel" && a.meta?.kind !== "channel",
|
|
107
166
|
);
|
|
108
167
|
}
|
|
109
168
|
|
|
@@ -190,3 +249,25 @@ export function __resetAudienceRules(): void {
|
|
|
190
249
|
for (const [type, rules] of defaultAudienceRegistry) audienceRegistry.set(type, rules);
|
|
191
250
|
subscriptionRules = [];
|
|
192
251
|
}
|
|
252
|
+
|
|
253
|
+
const SPAWN_LIFECYCLE_AUDIENCE_TYPES = [
|
|
254
|
+
"agent.ready",
|
|
255
|
+
"agent.exited",
|
|
256
|
+
"agent.spawn_failed",
|
|
257
|
+
"agent.spawn_recovered",
|
|
258
|
+
] as const satisfies readonly NotificationType[];
|
|
259
|
+
|
|
260
|
+
for (const type of SPAWN_LIFECYCLE_AUDIENCE_TYPES) {
|
|
261
|
+
registerDefaultAudienceRules(type, [audiencePredicates.spawnParentOf(), audiencePredicates.spawnedByUser()]);
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
registerDefaultAudienceRules("agent.stuck_busy", [
|
|
265
|
+
audiencePredicates.spawnParentOf(),
|
|
266
|
+
audiencePredicates.spawnedByUser(),
|
|
267
|
+
]);
|
|
268
|
+
|
|
269
|
+
registerDefaultAudienceRules("message.new", [
|
|
270
|
+
audiencePredicates.targetedAtUser(),
|
|
271
|
+
audiencePredicates.spawnedByUser(),
|
|
272
|
+
audiencePredicates.threadParticipant(),
|
|
273
|
+
]);
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
export type NotificationType =
|
|
2
|
+
| "message.new"
|
|
2
3
|
| "landed-failure"
|
|
3
4
|
| "branch.landed"
|
|
4
5
|
| "agent.ready"
|
|
@@ -31,6 +32,16 @@ export type NotificationType =
|
|
|
31
32
|
* All optional because each emitter fills the fields it has in scope at the call site.
|
|
32
33
|
*/
|
|
33
34
|
export interface NotificationScope {
|
|
35
|
+
/** Message sender for message/chat audience evaluation. */
|
|
36
|
+
from?: string;
|
|
37
|
+
/** Message target for message/chat audience evaluation. */
|
|
38
|
+
to?: string;
|
|
39
|
+
/** Alias for `to` used by audience preview clients that describe the primary target. */
|
|
40
|
+
target?: string;
|
|
41
|
+
/** Message thread id for thread participant audience evaluation. */
|
|
42
|
+
threadId?: number;
|
|
43
|
+
/** Pre-resolved thread participants when the caller already has the thread membership. */
|
|
44
|
+
participants?: string[];
|
|
34
45
|
/** The agent whose work the notification concerns (branch author, workspace owner). */
|
|
35
46
|
author?: string;
|
|
36
47
|
/** The agent the notification is primarily about (lifecycle subject, advisory target). */
|
|
@@ -56,6 +67,7 @@ const MINUTES = 60 * 1000;
|
|
|
56
67
|
* obligation is `null` (never auto-expires). Only genuinely now-or-never pings get a short default.
|
|
57
68
|
*/
|
|
58
69
|
export const DEFAULT_TTL_MS: Record<NotificationType, number | null> = {
|
|
70
|
+
"message.new": null,
|
|
59
71
|
"landed-failure": null,
|
|
60
72
|
"branch.landed": null,
|
|
61
73
|
"agent.ready": null,
|
package/src/runtime-tokens.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { createToken, getTokenProfile, hardenStaleRevocation, revokeToken } from "./token-db";
|
|
2
2
|
import { verifyComponentTokenAllowExpired } from "./security";
|
|
3
|
-
import { spawnGrantForProfile } from "./config-store";
|
|
3
|
+
import { spawnGrantForProfile, toolGroupsForProfile } from "./config-store";
|
|
4
4
|
import type { TokenRecord } from "./types";
|
|
5
5
|
|
|
6
6
|
// Scopes that turn an agent's runtime token into a spawn-capable one (#221). Appended to the
|
|
@@ -112,6 +112,7 @@ export function issueRunnerRuntimeToken(input: {
|
|
|
112
112
|
projectId?: string;
|
|
113
113
|
}): RuntimeTokenResult {
|
|
114
114
|
const grant = spawnGrantForProfile(input.profile, input.agentInitiated);
|
|
115
|
+
const toolGroups = toolGroupsForProfile(input.profile);
|
|
115
116
|
const subject = input.policyName
|
|
116
117
|
? `runner:policy:${input.policyName}`
|
|
117
118
|
: input.spawnRequestId
|
|
@@ -131,6 +132,7 @@ export function issueRunnerRuntimeToken(input: {
|
|
|
131
132
|
...(input.spawnedBy ? { spawnedBy: input.spawnedBy } : {}),
|
|
132
133
|
...(input.teamId ? { teamId: input.teamId } : {}),
|
|
133
134
|
...(input.projectId ? { projectId: input.projectId } : {}),
|
|
135
|
+
...(toolGroups ? { toolGroups } : {}),
|
|
134
136
|
},
|
|
135
137
|
createdBy: input.createdBy ?? "runtime",
|
|
136
138
|
});
|
|
@@ -1,3 +0,0 @@
|
|
|
1
|
-
import{r as e}from"./chunk-CilyBKbf.js";import{B as t,En as n,Et as r,Gn as i,I as a,Jt as o,Ln as s,Rn as c,Rt as l,Tt as u,Yn as d,Yt as f,_n as p,a as m,an as h,b as g,c as _,ct as v,dt as y,g as b,hn as x,i as S,jn as C,m as w,mn as ee,nn as T,on as te,or as E,pn as D,qn as O,r as k,vn as A,y as j,yn as M,z as ne}from"./lucide-react-BMjjWU36.js";import{g as N,r as re,t as P}from"./store-Bfl3XVmS.js";import{E as F,H as ie,N as I,P as L,R,S as ae,V as oe,_ as se,d as ce,f as le,k as z,q as B,rt as V,v as ue}from"./display-DRiGi1zj.js";import{t as H}from"./types-Tv67voFu.js";import{a as de,i as fe,o as pe,t as U,w as W}from"./index-D9oZL47o.js";import{t as me}from"./user-avatar-D5hoY3pJ.js";var G=e(E(),1),he={online:`came online`,offline:`went offline`,shutdown:`shut down`,restarted:`restarted`,"compaction-requested":`compaction requested`,compacting:`compaction started`,compacted:`context compacted`,"compaction-stalled":`compaction stalled — may need manual intervention`,"clear-requested":`clear requested`,"clearing-context":`clear started`,"context-cleared":`context cleared`,"clear-stalled":`context clear stalled — may need manual intervention`,"shutting-down":`shutting down`},ge=new Set(Object.keys(he)),_e=3e3;function K(e){return new Date(e.occurredAt??e.createdAt).getTime()}function ve(e){if(e.kind!==`session`)return null;let t=e.payload?.session;return!t||t.type!==`narration`&&t.type!==`reasoning`&&t.type!==`tool`?null:{id:e.id,kind:t.type,label:typeof t.label==`string`?t.label:void 0,text:e.body,ts:K(e),turnId:typeof t.turnId==`string`?t.turnId:void 0}}function ye(e){if(e.kind!==`session`)return null;let t=e.payload?.session;if(t?.type!==`notice`)return null;let n=typeof t.label==`string`&&t.label?t.label:`compacted`;return{id:`notice-${e.id}`,status:n,timestamp:K(e)}}function be(e){if(e.kind!==`session`)return null;let t=e.payload?.session;if(t?.type!==`relay-injection`)return null;let n=t.relayInjection&&typeof t.relayInjection==`object`&&!Array.isArray(t.relayInjection)?t.relayInjection:{},r=typeof n.category==`string`&&[`memory`,`instructions`,`tools`,`comms`,`knowledge`,`context`].includes(n.category)?n.category:`context`,i=typeof n.timestamp==`number`&&Number.isFinite(n.timestamp)?n.timestamp:K(e),a=n.detail&&typeof n.detail==`object`&&!Array.isArray(n.detail)?n.detail:{};return{id:e.id,category:r,summary:typeof n.summary==`string`&&n.summary.trim()?n.summary:e.body,detail:a,agentId:typeof n.agentId==`string`&&n.agentId?n.agentId:e.from,timestamp:i}}function xe(e,t){let n=e.trim();for(let e of t){let t=e.trim();if(t){if(n===t)break;n.startsWith(`${t}\n\n`)&&(n=n.slice(t.length+2).trimStart())}}return n.trim()||e.trim()}function Se(e){return e.kind===`system`&&e.from===`system`}var Ce=new Set([`agent.ready`,`agent.exited`,`agent.spawn_failed`]);function q(e){let t=new Date(e);return`${t.getFullYear()}-${String(t.getMonth()+1).padStart(2,`0`)}-${String(t.getDate()).padStart(2,`0`)}`}function we(e){let t=e.filter(e=>ge.has(e.status)).slice().sort((e,t)=>e.timestamp-t.timestamp),n=[];for(let e of t)n.some(t=>t.id===e.id)||n.some(t=>t.status===e.status&&Math.abs(t.timestamp-e.timestamp)<=_e)||n.push(e);return n}function Te(e,t,n,r=[],i){let a=[];for(let e of r){let t=e.entries.reduce((e,t)=>Math.min(e,B(t.originalCreatedAt)),1/0),n=Number.isFinite(t)?t-1:e.importedAt;a.push({ts:n,entry:{type:`import-boundary`,history:e,timestamp:n}});for(let t of e.entries)a.push({ts:B(t.originalCreatedAt),entry:{type:`imported-message`,history:e,entry:t}})}if(n){let e=new Date(n).getTime();Number.isFinite(e)&&a.push({ts:e,entry:{type:`created`,timestamp:e}})}if(i?.spawnedBy){let e=n?new Date(n).getTime():0,t=Number.isFinite(e)?e:0;a.push({ts:t,entry:{type:`agent-action`,direction:`spawned-by`,agentId:i.spawnedBy.agentId,provider:i.spawnedBy.provider,status:`ready`,timestamp:t}})}let o=i?.spawnedBy?.agentId,s=null,c=1/0;for(let t of e){if(t.kind===`session`||Se(t)||F(t)||!(t.from===`user`||o!==void 0&&t.from===o)||!z(t).trim())continue;let e=K(t);e<c&&(c=e,s=t.id)}let l=new Map,u=new Map,d=new Map;for(let t of e){if(t.kind!==`session`)continue;let e=t.payload?.session;if(e?.type===`narration`&&typeof e.turnId==`string`){let n=u.get(e.turnId)??[];n.push({id:t.id,body:t.body.trim()}),u.set(e.turnId,n)}else if(e?.type===`response`&&typeof e.turnId==`string`){let n=l.get(e.turnId)??[];n.push(t.body.trim()),l.set(e.turnId,n)}}let f=new Map;for(let[e,t]of l){let n=(u.get(e)??[]).map(e=>e.body);f.set(e,t.map(e=>xe(e,n)))}for(let t of e){if(t.kind!==`session`)continue;let e=t.payload?.session;if(e?.type!==`response`||typeof e.turnId!=`string`)continue;let n=xe(t.body,(u.get(e.turnId)??[]).map(e=>e.body));n&&n!==t.body&&d.set(t.id,n)}let p=new Set;for(let[e,t]of f){let n=u.get(e)??[];for(let e of t)for(let t=n.length-1;t>=0;t--){let r=n[t];if(!p.has(r.id)&&ie(e,r.body)){p.add(r.id);break}}}let m=new Map,h=[];for(let t of e){if(Se(t)){let e=typeof t.payload?.kind==`string`?t.payload.kind:``;if(Ce.has(e)){let n=t.payload,r=typeof n.agentId==`string`?n.agentId:``,i=K(t);if(!r){a.push({ts:i,entry:{type:`notice`,msg:t}});continue}let o=e===`agent.ready`?`ready`:e===`agent.exited`?`exited`:`failed`,s=m.get(r);if(s)s.entry.status=o,typeof n.reason==`string`&&(s.entry.reason=n.reason),s.entry.timestamp=i,s.ts=i;else{let e={ts:i,entry:{type:`agent-action`,direction:`spawned-child`,agentId:r,provider:typeof n.provider==`string`?n.provider:void 0,status:o,reason:typeof n.reason==`string`?n.reason:void 0,timestamp:i}};m.set(r,e),a.push(e)}continue}a.push({ts:K(t),entry:{type:`notice`,msg:t}});continue}let e=ye(t);if(e){h.push(e);continue}let n=ve(t);if(n){if(n.kind===`narration`&&p.has(n.id))continue;a.push({ts:n.ts,entry:{type:`activity`,steps:[n],timestamp:n.ts}});continue}let r=be(t);if(r){a.push({ts:r.timestamp,entry:{type:`relay-injection`,event:r}});continue}if(t.kind===`session`){let e=t.payload?.session;if(e?.type===`response`&&typeof e.turnId==`string`){let e=d.get(t.id);if(e&&e!==t.body){a.push({ts:K(t),entry:{type:`message`,msg:{...t,body:e}}});continue}}}let i=t.id===s?`initial-prompt`:`message`;a.push({ts:K(t),entry:{type:i,msg:t}})}for(let e of we([...t,...h]))a.push({ts:e.timestamp,entry:{type:`status`,event:e}});let g={created:0,date:1,"import-boundary":2,"imported-message":3,"initial-prompt":4,message:4,activity:4,notice:4,"agent-action":4,"relay-injection":4,status:5};a.sort((e,t)=>{let n=e.ts-t.ts;return Math.abs(n)<3e3&&g[e.entry.type]-g[t.entry.type]||n});let _=[],v=``;for(let{ts:e,entry:t}of a){if(t.type===`created`){_.push(t);continue}let n=q(e);if(n!==v&&(_.push({type:`date`,date:n,timestamp:e}),v=n),t.type===`activity`){let e=_[_.length-1];if(e&&e.type===`activity`&&Oe(e,t)){e.steps.push(...t.steps);continue}}_.push(t)}return _}function Ee(e){return e.type===`message`?`msg-${e.msg.id}`:e.type===`initial-prompt`?`initprompt-${e.msg.id}`:e.type===`notice`?`notice-${e.msg.id}`:e.type===`relay-injection`?`relay-injection-${e.event.id}`:e.type===`agent-action`?`agent-action-${e.direction}-${e.agentId}`:e.type===`activity`?`act-${e.steps[0]?.id??e.timestamp}`:e.type===`import-boundary`?`import-${e.history.id}`:e.type===`imported-message`?`import-msg-${e.history.id}-${e.entry.originalMessageId}-${e.entry.position}`:e.type===`status`?`status-${e.event.id}`:e.type===`date`?`date-${e.date}`:`created-${e.timestamp}`}function De(e){return e.type===`message`||e.type===`initial-prompt`||e.type===`notice`?(e.msg.subject?`${e.msg.subject} `:``)+z(e.msg):e.type===`imported-message`?z(e.entry.message):e.type===`activity`?e.steps.map(e=>[e.label,e.text].filter(Boolean).join(` `)).join(`
|
|
2
|
-
`):e.type===`relay-injection`?`${e.event.category} ${e.event.summary}\n${JSON.stringify(e.event.detail)}`:``}function Oe(e,t){let n=e.steps[e.steps.length-1]?.turnId,r=t.steps[0]?.turnId;return n&&r?n===r:!n&&!r}function ke(e){return e<1024?`${e} B`:e<1024*1024?`${(e/1024).toFixed(1)} KB`:`${(e/1024/1024).toFixed(1)} MB`}function Ae(e,t){if(t.startsWith(`/`))return t;let n=`${e.replace(/\/+$/,``)}/${t}`.split(`/`),r=[];for(let e of n)!e||e===`.`||(e===`..`?r.pop():r.push(e));return`/`+r.join(`/`)}function je(e){let t=e.replace(/\/+$/,``),n=t.lastIndexOf(`/`);return n>0?t.slice(0,n):`/`}function Me(e,t){return e.filter(e=>e.status===`online`&&R(t,e.baseDir)).sort((e,t)=>I(t.baseDir).length-I(e.baseDir).length)[0]||e.find(e=>e.status===`online`)}function Ne(){return typeof window<`u`&&window.matchMedia(`(min-width: 1280px)`).matches}function Pe(){return typeof window<`u`&&!!window.getSelection()?.toString()}function Fe(e){let t=e.payload?.attachments;return Array.isArray(t)?t.filter(e=>!!(e&&typeof e==`object`&&typeof e.artifactId==`string`)):[]}var Ie=[`👍`,`❤️`,`✅`,`👀`];function Le(e){let t=new Map;for(let n of e.reactions||[]){let e=L(n.emoji),r=t.get(e)??{emoji:e,count:0,mine:!1,actors:[]};r.count+=1,r.mine=r.mine||n.actorId===`user`,r.actors.push(n.actorId),t.set(e,r)}return[...t.values()].sort((e,t)=>t.count-e.count||e.emoji.localeCompare(t.emoji))}function J(e){return F(e)}function Re(e,t){let n=e.readBy||[],r=e.resolvedToAgent||t||e.to,i=r?n.includes(r):!1,a=n.some(e=>e!==V);if(i||a){let e=i?r:n.find(e=>e!==V);return{label:`read`,title:e?`Read by ${e}`:`Read by agent`,tone:`ok`,icon:M}}if(e.deliveryStatus===`delivered`)return{label:`delivered`,title:`Delivered to agent inbox`,tone:`ok`,icon:M};if(e.deliveryStatus===`queued`)return{label:`queued`,title:`Queued until the target agent is available`,tone:`warn`,icon:T};if(e.deliveryStatus===`failed`||e.deliveryStatus===`dead`){let t=e.deliveryPoisonReason||e.deliveryLastError||e.deliveryStatus;return{label:e.deliveryStatus,title:t,tone:`danger`,icon:D}}return{label:`sent`,title:`Accepted by Relay`,tone:`muted`,icon:A}}function ze(e){let t=B(e.createdAt);return(e.reactions||[]).reduce((e,t)=>Math.max(e,B(t.updatedAt||t.createdAt)),t)}function Be(e){return e?e.messages.reduce((e,t)=>Math.max(e,ze(t)),0):0}function Ve(e,t,n){return(e-t)*n}function He(e){if(!e)return 0;let t=0;for(let n of e.messages)ae(n)&&(t=Math.max(t,B(n.createdAt)));return t}function Y(e){return new Date(e).toLocaleTimeString([],{hour:`2-digit`,minute:`2-digit`})}function Ue(e){for(let t of e)t.previewUrl&&URL.revokeObjectURL(t.previewUrl)}function We(e,t,n,r){if(e?.teamId)return{teamId:e.teamId};let i=[...t];n&&!i.some(e=>e.id===n.id)&&i.push(n);let a=i.filter(e=>e.threadId).reverse(),o=a.find(e=>!!r[re(e.threadId,e.channel)])??a[0];return o?.threadId?{threadId:o.threadId,...o.channel?{channel:o.channel}:{}}:null}var X=O(),Ge={online:`text-emerald-400`,offline:`text-zinc-400`,shutdown:`text-zinc-400`,restarted:`text-blue-400`,"compaction-requested":`text-zinc-400`,compacting:`text-amber-400`,compacted:`text-amber-400`,"compaction-stalled":`text-red-400`,"clear-requested":`text-zinc-400`,"clearing-context":`text-amber-400`,"context-cleared":`text-amber-400`,"clear-stalled":`text-red-400`,"shutting-down":`text-zinc-400`};function Ke(e){let t=new Date,[n,r,i]=e.split(`-`).map(Number),a=new Date(n,r-1,i);if(e===q(t.getTime()))return`Today`;let o=new Date(t);return o.setDate(o.getDate()-1),e===q(o.getTime())?`Yesterday`:a.toLocaleDateString(void 0,{weekday:`short`,month:`short`,day:`numeric`,year:a.getFullYear()===t.getFullYear()?void 0:`numeric`})}function qe({event:e}){return(0,X.jsxs)(`div`,{className:`flex items-center justify-center gap-2 py-2 my-1`,children:[(0,X.jsx)(`div`,{className:`h-px flex-1 bg-border`}),(0,X.jsxs)(`div`,{className:`flex items-center gap-1.5 text-xs text-muted-foreground`,children:[(0,X.jsx)(h,{className:i(`w-2 h-2 fill-current`,Ge[e.status]||`text-zinc-400`)}),(0,X.jsx)(`span`,{children:he[e.status]||e.status}),(0,X.jsx)(`span`,{className:`text-muted-foreground/60`,children:Y(e.timestamp)})]}),(0,X.jsx)(`div`,{className:`h-px flex-1 bg-border`})]})}var Je={"branch.landed":u,"context.warning":w,"agent.context_threshold":w,"agent.resume_budget_exhausted":w,"agent.rate_limit_resume":t},Ye={"branch.landed":`branch landed`,"context.warning":`context warning`,"agent.context_threshold":`context threshold reached`};function Xe(e){return e&&(e.includes(`.`)?e.slice(e.indexOf(`.`)+1):e).replace(/[._-]+/g,` `).trim()||`system signal`}function Z({agentId:e,fallbackLabel:t,className:n,noIcon:r}){let a=P(t=>t.agentsById[e])||null,o=P(e=>e.openInboxThread),s=P(e=>e.switchView),c=a?ce(a):t||e;return(0,X.jsxs)(`button`,{type:`button`,className:i(`inline-flex max-w-full items-center gap-1 rounded px-1 text-muted-foreground transition-colors hover:bg-muted/50 hover:text-foreground`,n),onClick:t=>{t.stopPropagation(),o(e),s(`chat`)},title:`Open chat for ${c}`,children:[!r&&(0,X.jsx)(W,{agent:a,className:`w-4 h-4 text-[10px]`}),(0,X.jsx)(`span`,{className:`max-w-[160px] truncate`,children:c})]})}function Ze({msg:e}){let t=e.payload??{},n=$e(e),r=typeof t.sha==`string`?t.sha:``,i=r?r.slice(0,7):``,a=typeof t.author==`string`?t.author:``,o=typeof t.branch==`string`?t.branch:``,s=typeof t.base==`string`?t.base:``,c=t.pushed;return(0,X.jsxs)(`div`,{className:`flex items-center justify-center gap-2 py-2 my-1`,children:[(0,X.jsx)(`div`,{className:`h-px flex-1 bg-border`}),(0,X.jsxs)(`div`,{className:`flex max-w-full flex-wrap items-center justify-center gap-x-1.5 gap-y-0.5 rounded-full border border-emerald-600/35 bg-emerald-500/10 px-2.5 py-1 text-xs text-emerald-700 dark:border-emerald-500/25 dark:text-emerald-300/90`,children:[(0,X.jsx)(u,{className:`h-3 w-3 shrink-0 text-emerald-600 dark:text-emerald-400`}),(0,X.jsx)(`span`,{className:`text-emerald-700 dark:text-emerald-300`,children:`branch landed`}),o&&s&&(0,X.jsxs)(`span`,{className:`font-mono text-emerald-700/80 dark:text-emerald-200/70`,title:`${o} → ${s}`,children:[o,(0,X.jsx)(`span`,{className:`opacity-50`,children:` → `}),s]}),i&&(0,X.jsx)(`span`,{className:`rounded bg-emerald-500/15 px-1 font-mono text-emerald-800 dark:text-emerald-200`,title:r,children:i}),a&&(0,X.jsxs)(`span`,{className:`inline-flex items-center gap-1 text-emerald-700/80 dark:text-emerald-300/80`,children:[(0,X.jsx)(`span`,{className:`opacity-70`,children:`by`}),(0,X.jsx)(Z,{agentId:a,className:`text-emerald-700 hover:text-emerald-900 dark:text-emerald-300/90 dark:hover:text-emerald-100`})]}),c===!1&&(0,X.jsx)(`span`,{className:`text-amber-600 dark:text-amber-300/80`,title:`Local-only land — not pushed to origin`,children:`· local only`}),n&&(0,X.jsxs)(`span`,{className:`max-w-[220px] truncate text-emerald-700/70 dark:text-emerald-300/70`,title:n,children:[`· because `,n]}),(0,X.jsx)(`span`,{className:`text-emerald-700/60 dark:text-emerald-300/50`,children:Y(e.occurredAt??e.createdAt)})]}),(0,X.jsx)(`div`,{className:`h-px flex-1 bg-border`})]})}function Qe({msg:e}){let t=typeof e.payload?.kind==`string`?e.payload.kind:``;if(t===`branch.landed`)return(0,X.jsx)(Ze,{msg:e});let n=Je[t]??a,r=Ye[t]??Xe(t),i=$e(e);return(0,X.jsxs)(`div`,{className:`flex items-center justify-center gap-2 py-2 my-1`,children:[(0,X.jsx)(`div`,{className:`h-px flex-1 bg-border`}),(0,X.jsxs)(`div`,{className:`flex items-center gap-1.5 rounded-full border border-border bg-muted/30 px-2.5 py-1 text-xs text-muted-foreground`,children:[(0,X.jsx)(n,{className:`h-3 w-3`}),(0,X.jsx)(`span`,{children:r}),i&&(0,X.jsxs)(`span`,{className:`max-w-[220px] truncate text-muted-foreground/80`,title:i,children:[`· because `,i]}),(0,X.jsx)(`span`,{className:`text-muted-foreground/60`,children:Y(e.occurredAt??e.createdAt)})]}),(0,X.jsx)(`div`,{className:`h-px flex-1 bg-border`})]})}function $e(e){let t=e.payload?.routing;if(!t||typeof t!=`object`||Array.isArray(t))return``;let n=t.reason;return typeof n==`string`?n:``}var et={"spawned-child":{ready:`spawned`,exited:`spawned · exited`,failed:`spawn failed`},"spawned-by":{ready:`spawned by`,exited:`spawned by`,failed:`spawned by`}},tt={"spawned-child-ready":ne,"spawned-child-exited":v,"spawned-child-failed":D,"spawned-by-ready":c,"spawned-by-exited":c,"spawned-by-failed":c},nt={"spawned-child-ready":`text-emerald-400`,"spawned-child-exited":`text-zinc-400`,"spawned-child-failed":`text-red-400`,"spawned-by-ready":`text-blue-400`,"spawned-by-exited":`text-blue-400`,"spawned-by-failed":`text-blue-400`};function rt({entry:e}){let t=`${e.direction}-${e.status}`,n=et[e.direction]?.[e.status]??e.direction,r=tt[t]??a,o=nt[t]??`text-muted-foreground`,s=e.status===`failed`;return(0,X.jsxs)(`div`,{className:`flex items-center justify-center gap-2 py-2 my-1`,children:[(0,X.jsx)(`div`,{className:`h-px flex-1 bg-border`}),(0,X.jsxs)(`div`,{className:i(`flex items-center gap-1.5 rounded-full border bg-muted/30 px-2.5 py-1 text-xs`,s?`border-red-500/30`:`border-border`),children:[(0,X.jsx)(r,{className:i(`h-3 w-3 shrink-0`,o)}),(0,X.jsx)(`span`,{className:`text-muted-foreground`,children:n}),(0,X.jsx)(Z,{agentId:e.agentId}),e.reason&&s&&(0,X.jsxs)(`span`,{className:`text-red-400/80 max-w-[120px] truncate`,title:e.reason,children:[`— `,e.reason]}),(0,X.jsx)(`span`,{className:`text-muted-foreground/60 shrink-0`,children:Y(e.timestamp)})]}),(0,X.jsx)(`div`,{className:`h-px flex-1 bg-border`})]})}var it={memory:n,instructions:l,tools:m,comms:a,knowledge:C,context:f},at={memory:`border-emerald-500/25 bg-emerald-500/10 text-emerald-300`,instructions:`border-sky-500/25 bg-sky-500/10 text-sky-300`,tools:`border-amber-500/25 bg-amber-500/10 text-amber-300`,comms:`border-violet-500/25 bg-violet-500/10 text-violet-300`,knowledge:`border-cyan-500/25 bg-cyan-500/10 text-cyan-300`,context:`border-zinc-500/25 bg-zinc-500/10 text-zinc-300`};function ot(e){try{return JSON.stringify(e,null,2)}catch{return String(e)}}function st({entry:e}){let[t,n]=(0,G.useState)(!1),r=e.event,a=it[r.category]??j;return(0,X.jsx)(`div`,{className:`flex justify-center py-2 my-1`,children:(0,X.jsxs)(`div`,{className:i(`w-full max-w-[85%] md:max-w-[75%] rounded-lg border px-2.5 py-1.5 text-xs shadow-sm`,at[r.category]??at.context),children:[(0,X.jsxs)(`button`,{type:`button`,className:`flex w-full min-w-0 items-center gap-1.5 text-left`,onClick:()=>n(e=>!e),children:[(0,X.jsx)(a,{className:`h-3.5 w-3.5 shrink-0`}),(0,X.jsx)(`span`,{className:`shrink-0 font-medium`,children:r.category}),(0,X.jsx)(`span`,{className:`min-w-0 flex-1 truncate text-foreground/80`,children:r.summary}),(0,X.jsx)(`span`,{className:`shrink-0 text-muted-foreground/60`,children:Y(r.timestamp)}),(0,X.jsx)(x,{className:i(`h-3.5 w-3.5 shrink-0 transition-transform`,t&&`rotate-90`)})]}),t&&(0,X.jsx)(`pre`,{className:`mt-2 max-h-72 overflow-auto rounded-md border border-border/60 bg-background/75 p-2 font-mono text-[11px] leading-relaxed text-muted-foreground whitespace-pre-wrap break-words`,children:ot(r.detail)})]})})}function ct({blockedLabel:e,onInterrupt:t}){return e?(0,X.jsx)(`div`,{className:`flex justify-start mb-3 animate-in fade-in slide-in-from-bottom-1 duration-150`,children:(0,X.jsxs)(`div`,{className:`flex h-9 items-center gap-2 rounded-2xl rounded-bl-sm bg-card ring-1 ring-red-500/30 px-4`,children:[(0,X.jsx)(D,{className:`w-3.5 h-3.5 text-red-400`}),(0,X.jsxs)(`span`,{className:`text-xs text-red-300`,children:[`blocked: `,e]})]})}):(0,X.jsx)(`div`,{className:`flex justify-start mb-3 animate-in fade-in slide-in-from-bottom-1 duration-150`,children:(0,X.jsxs)(`div`,{className:`flex h-9 items-center gap-2 rounded-2xl rounded-bl-sm bg-card ring-1 ring-foreground/10 px-4`,children:[(0,X.jsxs)(`div`,{className:`flex items-center gap-1`,children:[(0,X.jsx)(`span`,{className:`w-1.5 h-1.5 rounded-full bg-yellow-400 animate-[pulse_1.4s_ease-in-out_infinite]`}),(0,X.jsx)(`span`,{className:`w-1.5 h-1.5 rounded-full bg-yellow-400 animate-[pulse_1.4s_ease-in-out_0.2s_infinite]`}),(0,X.jsx)(`span`,{className:`w-1.5 h-1.5 rounded-full bg-yellow-400 animate-[pulse_1.4s_ease-in-out_0.4s_infinite]`})]}),(0,X.jsx)(`span`,{className:`text-xs text-muted-foreground`,children:`working`}),t&&(0,X.jsxs)(`button`,{onClick:t,title:`Interrupt`,className:`ml-1 flex items-center gap-1 rounded-full px-1.5 py-0.5 text-xs text-muted-foreground hover:text-red-300 hover:bg-red-500/10 transition-colors`,children:[(0,X.jsx)(te,{className:`w-3.5 h-3.5`}),`Stop`]})]})})}var Q=`agent-relay:chat-hide-tools`,$=(()=>{let e=new Set,t=(()=>{try{return window.localStorage.getItem(Q)===`on`}catch{return!1}})(),n=()=>e.forEach(e=>e());return typeof window<`u`&&window.addEventListener(`storage`,e=>{e.key===Q&&(t=e.newValue===`on`,n())}),{subscribe(t){return e.add(t),()=>e.delete(t)},get:()=>t,toggle(){t=!t;try{window.localStorage.setItem(Q,t?`on`:`off`)}catch{}n()}}})();function lt(){return[(0,G.useSyncExternalStore)($.subscribe,$.get,()=>!1),$.toggle]}function ut({steps:e,showReasoning:t,issueRepo:r}){let[a,o]=lt(),s=t?e:e.filter(e=>e.kind!==`reasoning`);if(!s.length)return null;let c=s.filter(e=>e.kind===`tool`).length;return(0,X.jsx)(`div`,{className:`flex justify-start mb-2`,children:(0,X.jsxs)(`div`,{className:`max-w-[85%] md:max-w-[75%] min-w-0 space-y-1.5`,children:[s.map(e=>e.kind===`narration`?(0,X.jsx)(U,{text:e.text,issueRepo:r,className:`text-sm leading-relaxed break-words text-foreground/90 min-w-0`},e.id):e.kind===`reasoning`?(0,X.jsxs)(`div`,{className:`flex items-start gap-1.5 text-xs leading-relaxed text-muted-foreground/80`,children:[(0,X.jsx)(n,{className:`w-3.5 h-3.5 mt-0.5 shrink-0 opacity-70`}),(0,X.jsx)(U,{text:e.text,issueRepo:r,className:`italic break-words min-w-0`})]},e.id):a?null:(0,X.jsxs)(`div`,{className:`flex items-start gap-1.5 text-xs leading-relaxed text-muted-foreground`,children:[(0,X.jsx)(b,{className:`w-3 h-3 mt-0.5 shrink-0 opacity-70`}),(0,X.jsxs)(`span`,{className:`min-w-0 break-words`,children:[(0,X.jsx)(`span`,{className:`font-medium`,children:e.label||`tool`}),e.text&&e.text.trim()&&e.text.trim()!==(e.label??``).trim()?(0,X.jsxs)(`span`,{className:`opacity-70`,children:[` — `,e.text]}):null]})]},e.id)),c>0&&(0,X.jsxs)(`button`,{onClick:o,className:`flex items-center gap-1 text-[11px] text-muted-foreground/50 hover:text-muted-foreground transition-colors text-left`,children:[(0,X.jsx)(x,{className:i(`w-3 h-3 shrink-0 transition-transform`,!a&&`rotate-90`)}),(0,X.jsx)(`span`,{children:a?`show ${c} tool step${c===1?``:`s`}`:`hide tool steps`})]})]})})}function dt({date:e}){return(0,X.jsxs)(`div`,{className:`flex items-center justify-center gap-3 py-3 my-1`,children:[(0,X.jsx)(`div`,{className:`h-px flex-1 bg-border`}),(0,X.jsx)(`span`,{className:`text-xs font-medium text-muted-foreground`,children:Ke(e)}),(0,X.jsx)(`div`,{className:`h-px flex-1 bg-border`})]})}function ft({timestamp:e}){let t=new Date(e).toLocaleString(void 0,{month:`short`,day:`numeric`,year:`numeric`,hour:`2-digit`,minute:`2-digit`});return(0,X.jsxs)(`div`,{className:`flex items-center justify-center gap-2 py-2 my-1`,children:[(0,X.jsx)(`div`,{className:`h-px flex-1 bg-border`}),(0,X.jsxs)(`span`,{className:`text-xs text-muted-foreground/60`,children:[`created `,t]}),(0,X.jsx)(`div`,{className:`h-px flex-1 bg-border`})]})}function pt({history:e}){let t=e.sourceAgentLabel||e.sourcePeerId,n=e.entries.length;return(0,X.jsxs)(`div`,{className:`flex items-center justify-center gap-2 py-2 my-1`,children:[(0,X.jsx)(`div`,{className:`h-px flex-1 bg-border`}),(0,X.jsxs)(`div`,{className:`flex items-center gap-1.5 rounded-full border border-dashed border-border bg-muted/30 px-2 py-1 text-[11px] text-muted-foreground`,children:[(0,X.jsx)(r,{className:`h-3 w-3`}),(0,X.jsxs)(`span`,{children:[`forked history from `,t]}),(0,X.jsxs)(`span`,{className:`text-muted-foreground/60`,children:[n,` `,n===1?`entry`:`entries`]})]}),(0,X.jsx)(`div`,{className:`h-px flex-1 bg-border`})]})}function mt({entry:e,sourceLabel:t,issueRepo:n}){let r=e.message,a=z(r),o=e.originalFrom===V;return(0,X.jsx)(`div`,{className:i(`flex mb-3 opacity-80`,o?`justify-end`:`justify-start`),children:(0,X.jsx)(`div`,{className:`max-w-[85%] md:max-w-[75%]`,children:(0,X.jsxs)(`div`,{className:i(`rounded-2xl border border-dashed px-3.5 py-2 text-sm select-text`,o?`border-primary/25 bg-primary/10 text-foreground rounded-br-sm`:`border-border bg-card/70 rounded-bl-sm`),children:[(0,X.jsxs)(`div`,{className:i(`mb-1 text-[10px] uppercase tracking-normal`,o?`text-primary/70`:`text-muted-foreground`),children:[`forked history · `,o?`you`:t||e.originalFrom]}),(0,X.jsx)(U,{text:a,rawBody:r.body,issueRepo:n,className:`leading-relaxed`}),(0,X.jsxs)(`p`,{className:i(`mt-1 flex items-center justify-end gap-1.5 text-xs`,o?`text-primary/60`:`text-muted-foreground`),children:[(0,X.jsxs)(`span`,{className:`opacity-40`,children:[`#`,e.originalMessageId]}),(0,X.jsx)(`span`,{children:Y(e.originalCreatedAt)})]})]})})})}function ht({msg:e,issueRepo:t}){let n=z(e),r=Y(e.occurredAt??e.createdAt);return(0,X.jsx)(`div`,{"data-msg-id":e.id,className:`mb-3`,children:(0,X.jsxs)(`div`,{className:`rounded-xl border border-primary/30 bg-primary/[0.06] px-3.5 py-2.5 shadow-sm`,children:[(0,X.jsxs)(`div`,{className:`mb-1.5 flex items-center gap-1.5 text-[11px] font-semibold uppercase tracking-wide text-primary/80`,children:[(0,X.jsx)(j,{className:`h-3.5 w-3.5`}),(0,X.jsx)(`span`,{children:`Initial prompt`}),(0,X.jsx)(`span`,{className:`ml-auto text-[10px] font-normal normal-case text-muted-foreground/60`,children:r})]}),(0,X.jsx)(U,{text:n,rawBody:e.body,issueRepo:t,className:`text-sm leading-relaxed text-foreground`})]})})}function gt({scrollEl:e,timeline:t}){let[n,r]=(0,G.useState)(!0),[a,o]=(0,G.useState)(null),[s,c]=(0,G.useState)(null),[l,u]=(0,G.useState)(!1),d=(0,G.useMemo)(()=>{for(let e=t.length-1;e>=0;e--){let n=t[e];if(!(!n||n.type!==`message`&&n.type!==`initial-prompt`)&&n.msg.from===`user`)return{id:n.msg.id,body:z(n.msg)}}return null},[t]);if((0,G.useEffect)(()=>{if(!d||!e){r(!0);return}let t=null,n=null,i=()=>{let i=e.querySelector(`[data-msg-id="${d.id}"]`);if(!i){t?.disconnect(),t=null,n=null,r(!1);return}let a=i.getBoundingClientRect(),o=e.getBoundingClientRect();u(a.top<o.top),i!==n&&(t?.disconnect(),n=i,t=new IntersectionObserver(([e])=>{e&&r(e.isIntersecting)},{root:e,threshold:0}),t.observe(i))};return i(),e.addEventListener(`scroll`,i,{passive:!0}),()=>{t?.disconnect(),e.removeEventListener(`scroll`,i)}},[d?.id,e]),n||!d||!d.body.trim())return null;let f=a?.id===d.id?a.value:!1,m=s?.id===d.id?s.value:!1;function h(){!e||!d||e.querySelector(`[data-msg-id="${d.id}"]`)?.scrollIntoView({behavior:`smooth`,block:`center`})}let g=l?`↑`:`↓`;return m?(0,X.jsx)(`div`,{className:`flex shrink-0 bg-card/45 border-b border-border`,children:(0,X.jsxs)(`button`,{type:`button`,className:`w-full flex items-center justify-center gap-1.5 py-1 text-[11px] text-primary/60 hover:text-primary transition-colors`,onClick:()=>c({id:d.id,value:!1}),children:[(0,X.jsx)(`span`,{children:`Your prompt`}),(0,X.jsx)(p,{className:`w-3 h-3`})]})}):(0,X.jsxs)(`section`,{className:`flex shrink-0 flex-col border-b border-border bg-card/45 px-3 py-2`,children:[(0,X.jsxs)(`div`,{className:`flex items-center gap-2 text-[11px] text-muted-foreground mb-0.5`,children:[(0,X.jsx)(`span`,{className:`font-medium text-primary/70`,children:`Your prompt`}),(0,X.jsxs)(`button`,{type:`button`,className:`ml-auto hover:text-foreground transition-colors`,onClick:h,children:[g,` scroll to original`]}),(0,X.jsx)(`button`,{type:`button`,className:`hover:text-foreground transition-colors`,onClick:()=>c({id:d.id,value:!0}),title:`Minimize`,children:(0,X.jsx)(ee,{className:`w-3 h-3`})})]}),(0,X.jsx)(`p`,{className:i(`text-sm text-foreground leading-snug cursor-pointer`,!f&&`line-clamp-2`),onClick:()=>o({id:d.id,value:!f}),children:d.body})]})}function _t(){return(0,G.useSyncExternalStore)(e=>N.subscribe(e),()=>N.getPlayingKey(),()=>null)}function vt({msg:e,peer:t}){return(0,X.jsx)(ht,{msg:e,issueRepo:P(e=>e.agentsById[t]?.issueRepo)})}function yt({agent:e,onClick:t}){let n=!!(t&&e);return(0,X.jsx)(`button`,{type:`button`,title:e?e.label||e.name||e.id:void 0,onClick:t,disabled:!n,className:i(`shrink-0 self-end transition-opacity`,n?`cursor-pointer hover:opacity-80`:`cursor-default opacity-60`),children:(0,X.jsx)(W,{agent:e})})}function bt({agentId:e,onOpen:t}){let n=P(t=>t.agentsById[e]??null);return(0,X.jsx)(yt,{agent:n,onClick:n?()=>t(n):void 0})}function xt({attachment:e,outbound:t}){let n=e.kind===`image`,r=e.title||e.artifactId,[a,s]=(0,G.useState)(null),[c,u]=(0,G.useState)(null),[f,p]=(0,G.useState)(!1),[m,h]=(0,G.useState)(!1);(0,G.useEffect)(()=>{let t=!1,n=null;async function r(){p(!0),u(null),s(null);try{let r=await d(`/artifacts/${encodeURIComponent(e.artifactId)}/content`);if(t)return;n=URL.createObjectURL(r),s(n)}catch(e){t||u(e.message)}finally{t||p(!1)}}return r(),()=>{t=!0,n&&URL.revokeObjectURL(n)}},[e.artifactId]);function g(){if(!a)return;let e=document.createElement(`a`);e.href=a,e.download=r,document.body.appendChild(e),e.click(),e.remove()}return n?(0,X.jsxs)(X.Fragment,{children:[(0,X.jsx)(`button`,{type:`button`,onClick:()=>a&&h(!0),disabled:!a,className:`group/img mt-2 block overflow-hidden rounded-md border border-foreground/10 bg-black/10 text-left disabled:cursor-default relative`,children:a?(0,X.jsxs)(X.Fragment,{children:[(0,X.jsx)(`img`,{src:a,alt:r,loading:`lazy`,className:`block max-h-72 max-w-full object-contain`}),(0,X.jsx)(`span`,{className:`absolute inset-0 flex items-center justify-center bg-black/0 group-hover/img:bg-black/30 transition-colors`,children:(0,X.jsx)(k,{className:`w-6 h-6 text-white opacity-0 group-hover/img:opacity-100 transition-opacity drop-shadow-md`})})]}):(0,X.jsxs)(`span`,{className:i(`flex min-h-20 items-center gap-2 px-3 py-2 text-xs`,c?`text-red-400`:`text-muted-foreground`),children:[f?(0,X.jsx)(y,{className:`h-4 w-4 animate-spin`}):(0,X.jsx)(D,{className:`h-4 w-4`}),c||`Loading image`]})}),a&&(0,X.jsx)(fe,{open:m,onOpenChange:h,children:(0,X.jsxs)(de,{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,X.jsx)(pe,{className:`sr-only`,children:r}),(0,X.jsxs)(`div`,{className:`relative flex items-center justify-center min-h-[200px]`,children:[(0,X.jsx)(`img`,{src:a,alt:r,className:`max-w-[93vw] max-h-[90vh] object-contain`}),(0,X.jsxs)(`div`,{className:`absolute top-2 right-2 flex gap-1`,children:[(0,X.jsx)(`button`,{type:`button`,onClick:g,className:`rounded-md bg-black/60 hover:bg-black/80 p-2 text-white transition-colors`,title:`Download`,children:(0,X.jsx)(o,{className:`w-4 h-4`})}),(0,X.jsx)(`button`,{type:`button`,onClick:()=>h(!1),className:`rounded-md bg-black/60 hover:bg-black/80 p-2 text-white transition-colors`,title:`Close`,children:(0,X.jsx)(S,{className:`w-4 h-4`})})]})]})]})})]}):(0,X.jsxs)(`button`,{type:`button`,onClick:g,disabled:!a,className:i(`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:[f?(0,X.jsx)(y,{className:`h-4 w-4 shrink-0 animate-spin`}):c?(0,X.jsx)(D,{className:`h-4 w-4 shrink-0 text-red-400`}):(0,X.jsx)(l,{className:`h-4 w-4 shrink-0`}),(0,X.jsx)(`span`,{className:i(`min-w-0 flex-1 truncate`,c&&`text-red-400`),children:c||r}),(0,X.jsx)(o,{className:`h-3.5 w-3.5 shrink-0`})]})}function St({open:e,onToggle:t,onReact:n}){return(0,X.jsxs)(`div`,{className:`relative shrink-0`,children:[(0,X.jsx)(`button`,{type:`button`,title:`Add reaction`,onClick:t,className:i(`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,X.jsx)(g,{className:`h-3 w-3`})}),e&&(0,X.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:Ie.map(e=>(0,X.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 Ct({msg:e,peer:t}){let[n,r]=(0,G.useState)(!1),a=P(e=>e.agentsById),o=P(e=>e.openAgentDetail),l=e.from===t,u=(l?e.to:e.from)||``,d=a[l?t:u]?.issueRepo??a[t]?.issueRepo,f=!u||u===`broadcast`||u.includes(`:`),p=z(e),m=Y(e.occurredAt??e.createdAt),h=l?s:c,g=a[e.from??``]??null;function _(e){e.stopPropagation(),g&&o(g)}return(0,X.jsx)(`div`,{"data-msg-id":e.id,className:`flex justify-center mb-1.5`,children:(0,X.jsxs)(`div`,{className:`w-full max-w-[94%] rounded-md border border-border/50 bg-muted/15 px-2.5 py-1`,children:[(0,X.jsxs)(`div`,{className:`flex items-center gap-1.5 text-xs cursor-pointer select-none`,onClick:()=>r(e=>!e),children:[(0,X.jsx)(x,{className:i(`h-3 w-3 shrink-0 text-muted-foreground/60 transition-transform`,n&&`rotate-90`)}),(0,X.jsx)(`button`,{type:`button`,title:g?g.label||g.name||g.id:void 0,disabled:!g,onClick:_,className:i(`shrink-0 transition-opacity`,g?`cursor-pointer hover:opacity-80`:`cursor-default opacity-60`),children:(0,X.jsx)(W,{agent:g,className:`!w-4 !h-4 !rounded-sm opacity-70`})}),(0,X.jsx)(h,{className:`h-3 w-3 shrink-0 text-muted-foreground/70`}),(0,X.jsxs)(`span`,{className:`shrink-0 text-muted-foreground`,children:[`Message `,l?`to`:`from`]}),f?(0,X.jsx)(`span`,{className:`shrink-0 font-medium text-muted-foreground`,children:le(u,a)}):(0,X.jsx)(Z,{agentId:u,className:`shrink-0 px-0.5 text-foreground/80`,noIcon:!0}),!n&&(0,X.jsx)(`span`,{className:`min-w-0 flex-1 truncate text-muted-foreground/50`,children:p}),(0,X.jsx)(`span`,{className:`ml-auto shrink-0 text-muted-foreground/40`,children:m})]}),n&&(0,X.jsx)(`div`,{className:`mt-1.5 pl-5`,children:(0,X.jsx)(U,{text:p,rawBody:e.body,issueRepo:d,className:`text-sm leading-relaxed text-foreground/90`})})]})})}var wt=(0,G.memo)(function({msg:e,peer:t,showAvatar:n=!1,onOpenReferencedPath:r,onPreviewReferencedPath:a,onPreviewReferencedPathEnd:o}){if(!H(e.from)&&!H(e.to))return(0,X.jsx)(Ct,{msg:e,peer:t});let s=e.kind===`session`?e.payload?.session:void 0;if(s?.type===`prompt`&&s?.origin===`provider`)return(0,X.jsx)(vt,{msg:e,peer:t});let c=H(e.from),l=P(e=>e.reactToMessage),u=P(e=>e.voiceTtsEnabled),d=_t(),f=P(e=>{let n=e.agentsById[t]?.meta?.cwd;return typeof n==`string`?n:``}),p=P(e=>e.agentsById[t]?.issueRepo),m=P(e=>e.usersById),h=P(e=>e.users.length>1),g=c?oe(e.from,m):void 0,v=P(e=>e.openAgentDetail),[y,b]=(0,G.useState)(!1),x=(0,G.useRef)(null),S=(0,G.useRef)(null),C=(0,G.useRef)(!1),w=z(e),ee=Y(e.occurredAt??e.createdAt),T=Fe(e),E=Le(e),D=c?Re(e,t):null,O=D?.icon,k=d===String(e.id),A=u&&!c&&!J(e)&&w.trim().length>0;function j(t){t.stopPropagation(),k?N.bargeIn():N.speak(e.body,String(e.id))}(0,G.useEffect)(()=>{if(!y)return;function e(e){Pe()||x.current&&!x.current.contains(e.target)&&b(!1)}return document.addEventListener(`mousedown`,e),document.addEventListener(`touchstart`,e),()=>{document.removeEventListener(`mousedown`,e),document.removeEventListener(`touchstart`,e)}},[y]);function M(e){return Ae(f||`/`,e)}function ne(e,t){let n=M(e);r?.(n,t)}function re(e,t,n){let r=M(e);a?.(r,t,n)}function F(t){l(e,t),b(!1)}function ie(e){e.button===0&&(S.current={x:e.clientX,y:e.clientY},C.current=!1)}function I(e){let t=S.current;t&&(Math.abs(e.clientX-t.x)>3||Math.abs(e.clientY-t.y)>3)&&(C.current=!0)}function L(t){if(!(J(e)||c)&&!t.target.closest(`a,button,input,textarea,select,[role="button"]`)){if(C.current||Pe()){C.current=!1;return}b(e=>!e)}}let R=n&&!J(e);return(0,X.jsxs)(`div`,{"data-msg-id":e.id,className:i(`group/msg flex mb-3 items-end`,c?`justify-end`:`justify-start`,R&&`gap-1.5`),children:[!c&&R&&(0,X.jsx)(bt,{agentId:t,onOpen:v}),(0,X.jsxs)(`div`,{ref:x,className:i(`relative`,R?`max-w-[calc(85%-2rem)] md:max-w-[calc(75%-2rem)]`:`max-w-[85%] md:max-w-[75%]`),children:[A&&(0,X.jsx)(`button`,{type:`button`,title:k?`Stop playback`:`Play aloud`,onClick:j,className:i(`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`,k?`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:k?(0,X.jsx)(te,{className:`h-3.5 w-3.5 animate-pulse`}):(0,X.jsx)(_,{className:`h-3.5 w-3.5`})}),(0,X.jsxs)(`div`,{className:i(`rounded-2xl px-3.5 py-2 text-sm select-text`,!c&&!J(e)&&`cursor-pointer`,c?`bg-primary text-primary-foreground rounded-br-sm`:`bg-card ring-1 ring-foreground/10 rounded-bl-sm`),onPointerDown:ie,onPointerMove:I,onClick:L,children:[c&&h&&(0,X.jsx)(`p`,{className:i(`text-[11px] font-semibold mb-0.5 text-right`,se(e.from)),children:ue(e.from,m)}),e.subject&&(0,X.jsx)(`p`,{className:i(`text-xs font-semibold mb-1`,c?`text-primary-foreground/70`:`text-muted-foreground`),children:e.subject}),(0,X.jsx)(U,{text:w,rawBody:e.body,issueRepo:p,className:`leading-relaxed`,onPrimary:c,onOpenPath:ne,onPreviewPath:re,onPreviewPathEnd:o,resolvePathTitle:(e,t)=>`${M(e)}${t?`:${t}`:``}`}),T.map(t=>(0,X.jsx)(xt,{attachment:t,outbound:c},`${e.id}-${t.artifactId}-${t.role||``}`)),(0,X.jsxs)(`p`,{className:i(`text-xs mt-1 flex items-center gap-1.5`,c?`justify-end text-primary-foreground/60`:`justify-end text-muted-foreground`),children:[(0,X.jsxs)(`span`,{className:`opacity-40`,children:[`#`,e.id]}),(0,X.jsx)(`span`,{children:ee}),D&&O&&(0,X.jsxs)(`span`,{className:i(`inline-flex items-center gap-1`,D.tone===`ok`&&`text-emerald-300`,D.tone===`warn`&&`text-amber-200`,D.tone===`danger`&&`text-red-200`),title:D.title,children:[(0,X.jsx)(O,{className:`h-3 w-3`}),D.label]})]})]}),!J(e)&&E.length>0&&(0,X.jsxs)(`div`,{className:i(`flex flex-wrap items-center gap-0.5 -mt-1 relative z-10`,c?`justify-end pr-2`:`justify-start pl-2`),children:[!c&&(0,X.jsx)(St,{open:y,onToggle:()=>b(e=>!e),onReact:F}),E.map(e=>(0,X.jsxs)(`button`,{type:`button`,title:e.actors.join(`, `),onClick:()=>F(e.emoji),className:i(`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,X.jsx)(`span`,{children:e.emoji}),e.count>1&&(0,X.jsx)(`span`,{children:e.count})]},e.emoji))]}),!J(e)&&!c&&E.length===0&&(0,X.jsx)(`div`,{className:`absolute -bottom-2.5 left-1 z-20`,children:(0,X.jsx)(St,{open:y,onToggle:()=>b(e=>!e),onReact:F})})]}),c&&R&&(0,X.jsx)(`span`,{className:`shrink-0 self-end opacity-60`,children:(0,X.jsx)(me,{user:g,address:e.from,distinct:h})})]})});export{Te as C,Be as S,De as T,Me as _,ft as a,Ue as b,mt as c,st as d,qe as f,He as g,ke as h,ct as i,ht as l,Ve as m,ut as n,dt as o,gt as p,rt as r,pt as s,wt as t,Qe as u,je as v,Ee as w,Ne as x,We as y};
|
|
3
|
-
//# sourceMappingURL=MessageBubble-g4NKZBDI.js.map
|
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
import{r as e}from"./chunk-CilyBKbf.js";import{Dt as t,Gn as n,Jn as r,a as i,an as a,fn as o,m as s,or as c,qn as l}from"./lucide-react-BMjjWU36.js";import{t as u}from"./store-Bfl3XVmS.js";var d=e(c(),1);function f(e){let t=u(e=>e.showError),[n,i]=(0,d.useState)(!1),[a,o]=(0,d.useState)(null),[s,c]=(0,d.useState)(!1);async function l(){if(!(!e||s)){c(!0);try{o(await r(`POST`,`/agents/`+encodeURIComponent(e)+`/terminal-session`)),i(!0)}catch(e){t(`Terminal Failed`,e.message)}finally{c(!1)}}}function f(t){if(t){i(!0);return}i(!1);let n=a;o(null),e&&n?.mode===`guest`&&r(`DELETE`,`/agents/`+encodeURIComponent(e)+`/terminal-session/`+encodeURIComponent(n.session)).catch(()=>{})}return{terminalOpen:n,terminalTarget:a,terminalOpening:s,openTerminal:l,closeTerminal:f}}var p=l(),m={idle:{label:`idle`,tip:`Branch worktree — nothing to land yet.`,className:`bg-zinc-500/10 text-zinc-400 border-zinc-500/20`,Icon:a},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:t},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:o},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:i},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:s}};function h({state:e,onClick:t,iconOnly:r=!1,className:i}){let a=m[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 n,h as t};
|
|
2
|
-
//# sourceMappingURL=branch-state-badge-T6t16OU5.js.map
|
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
import{$ as e,Ln as t,Rn as n,Wt as r,qn as i,zn as a}from"./lucide-react-BMjjWU36.js";import{l as o,t as s}from"./store-Bfl3XVmS.js";import{J as c,K as l,Y as u,c as d,s as f}from"./display-DRiGi1zj.js";import{t as p}from"./badge-CcTIPkUa.js";import{t as m}from"./button-Dvz6HZ1j.js";import{a as h,o as g,r as _,t as v}from"./card-xVEUTFuh.js";var y=i();function b({direction:e}){return e===`inbound`?(0,y.jsx)(n,{className:`w-3 h-3`}):e===`outbound`?(0,y.jsx)(t,{className:`w-3 h-3`}):(0,y.jsx)(a,{className:`w-3 h-3`})}function x({channel:t}){let n=o(),i=s(e=>e.openChannelDetail),a=d(t),f=t.status!==`offline`;return(0,y.jsxs)(v,{className:`${f?``:`opacity-60`} hover:border-zinc-600 transition-colors`,children:[(0,y.jsx)(h,{className:`pb-2 pt-4 px-4`,children:(0,y.jsxs)(`div`,{className:`flex items-start gap-2`,children:[(0,y.jsx)(`div`,{className:`p-1.5 rounded-md ${f?`bg-blue-500/10`:`bg-zinc-800`}`,children:(0,y.jsx)(e,{className:`w-4 h-4 ${f?`text-blue-400`:`text-zinc-500`}`})}),(0,y.jsxs)(`div`,{className:`flex-1 min-w-0`,children:[(0,y.jsx)(g,{className:`text-sm font-medium truncate`,children:t.name||t.id}),(0,y.jsxs)(`div`,{className:`text-xs text-muted-foreground mt-0.5`,children:[t.type,` · `,t.transport]})]}),(0,y.jsx)(p,{className:`text-[10px] shrink-0 ${c(a.tone)}`,children:a.label})]})}),(0,y.jsxs)(_,{className:`px-4 pb-4 space-y-2.5`,children:[(0,y.jsxs)(`div`,{className:`flex items-center gap-1.5 text-xs text-muted-foreground`,children:[(0,y.jsx)(b,{direction:t.direction}),(0,y.jsx)(`span`,{className:`capitalize`,children:t.direction}),t.target&&(0,y.jsxs)(y.Fragment,{children:[(0,y.jsx)(`span`,{children:`·`}),(0,y.jsx)(`span`,{className:`truncate text-foreground`,children:t.target})]})]}),t.targetHealth&&t.targetHealth.status!==`ok`&&(0,y.jsx)(`div`,{className:`text-xs px-2 py-1 rounded ${t.targetHealth.status===`error`?`bg-red-500/10 text-red-400`:`bg-yellow-500/10 text-yellow-400`}`,children:t.targetHealth.detail}),u(t.capabilities).length>0&&(0,y.jsx)(`div`,{className:`flex flex-wrap gap-1`,children:u(t.capabilities).map(e=>(0,y.jsx)(p,{variant:`secondary`,className:`text-[9px] px-1 py-0 h-4`,children:e},e))}),t.tags.length>0&&(0,y.jsx)(`div`,{className:`flex flex-wrap gap-1`,children:t.tags.map(e=>(0,y.jsx)(p,{variant:`outline`,className:`text-[9px] px-1 py-0 h-4`,children:e},e))}),(0,y.jsxs)(`div`,{className:`flex items-center justify-between pt-0.5`,children:[(0,y.jsx)(`span`,{className:`text-xs text-muted-foreground`,children:l(n,t.lastSeen)}),(0,y.jsxs)(m,{size:`sm`,variant:`outline`,className:`h-7 text-xs gap-1`,onClick:()=>i(t),children:[(0,y.jsx)(r,{className:`w-3 h-3`}),`Details`]})]})]})]})}function S(){let e=s(e=>e.channels),t=e.filter(f).length,n=e.filter(e=>e.targetHealth?.status===`error`).length,r=e.filter(e=>e.targetHealth?.status===`warning`).length;return(0,y.jsxs)(`div`,{className:`space-y-4`,children:[(0,y.jsxs)(`div`,{className:`flex items-center gap-3`,children:[(0,y.jsxs)(`div`,{children:[(0,y.jsx)(`h2`,{className:`text-base font-semibold`,children:`Channels`}),(0,y.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:`Inbound / outbound message integrations`})]}),(0,y.jsxs)(`div`,{className:`flex items-center gap-2 ml-auto`,children:[t>0&&(0,y.jsxs)(p,{className:`text-xs bg-emerald-500/15 text-emerald-400 border-emerald-500/30`,children:[t,` ready`]}),r>0&&(0,y.jsxs)(p,{className:`text-xs bg-yellow-500/15 text-yellow-400 border-yellow-500/30`,children:[r,` warning`]}),n>0&&(0,y.jsxs)(p,{className:`text-xs bg-red-500/15 text-red-400 border-red-500/30`,children:[n,` error`]})]})]}),e.length===0?(0,y.jsx)(`div`,{className:`text-center py-16 text-muted-foreground text-sm`,children:`No channels registered.`}):(0,y.jsx)(`div`,{className:`grid grid-cols-1 md:grid-cols-2 xl:grid-cols-3 gap-4`,children:e.map(e=>(0,y.jsx)(x,{channel:e},e.id))})]})}export{S as ChannelsView};
|
|
2
|
-
//# sourceMappingURL=channels-C0J-VHEa.js.map
|