@junctionpanel/server 0.1.34 → 0.1.36
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/server/client/daemon-client.d.ts +9 -6
- package/dist/server/client/daemon-client.d.ts.map +1 -1
- package/dist/server/client/daemon-client.js +15 -1
- package/dist/server/client/daemon-client.js.map +1 -1
- package/dist/server/server/agent/agent-manager.d.ts +24 -1
- package/dist/server/server/agent/agent-manager.d.ts.map +1 -1
- package/dist/server/server/agent/agent-manager.js +26 -3
- package/dist/server/server/agent/agent-manager.js.map +1 -1
- package/dist/server/server/agent/agent-projections.d.ts.map +1 -1
- package/dist/server/server/agent/agent-projections.js +11 -0
- package/dist/server/server/agent/agent-projections.js.map +1 -1
- package/dist/server/server/agent/agent-sdk-types.d.ts +21 -0
- package/dist/server/server/agent/agent-sdk-types.d.ts.map +1 -1
- package/dist/server/server/agent/agent-sdk-types.js.map +1 -1
- package/dist/server/server/agent/agent-storage.d.ts +4 -4
- package/dist/server/server/agent/pending-plan-review.d.ts +12 -0
- package/dist/server/server/agent/pending-plan-review.d.ts.map +1 -0
- package/dist/server/server/agent/pending-plan-review.js +85 -0
- package/dist/server/server/agent/pending-plan-review.js.map +1 -0
- package/dist/server/server/agent/providers/claude-agent.d.ts.map +1 -1
- package/dist/server/server/agent/providers/claude-agent.js +38 -90
- package/dist/server/server/agent/providers/claude-agent.js.map +1 -1
- package/dist/server/server/agent/providers/claude-cli-capabilities.d.ts +50 -0
- package/dist/server/server/agent/providers/claude-cli-capabilities.d.ts.map +1 -0
- package/dist/server/server/agent/providers/claude-cli-capabilities.js +247 -0
- package/dist/server/server/agent/providers/claude-cli-capabilities.js.map +1 -0
- package/dist/server/server/agent/providers/gemini-agent.d.ts +287 -1
- package/dist/server/server/agent/providers/gemini-agent.d.ts.map +1 -1
- package/dist/server/server/agent/providers/gemini-agent.js +255 -16
- package/dist/server/server/agent/providers/gemini-agent.js.map +1 -1
- package/dist/server/server/agent/providers/tool-call-detail-primitives.d.ts.map +1 -1
- package/dist/server/server/agent-attention-policy.d.ts +2 -3
- package/dist/server/server/agent-attention-policy.d.ts.map +1 -1
- package/dist/server/server/agent-attention-policy.js +2 -2
- package/dist/server/server/agent-attention-policy.js.map +1 -1
- package/dist/server/server/daemon-doctor.d.ts +5 -0
- package/dist/server/server/daemon-doctor.d.ts.map +1 -1
- package/dist/server/server/daemon-doctor.js +26 -0
- package/dist/server/server/daemon-doctor.js.map +1 -1
- package/dist/server/server/file-explorer/service.d.ts +1 -0
- package/dist/server/server/file-explorer/service.d.ts.map +1 -1
- package/dist/server/server/file-explorer/service.js +36 -0
- package/dist/server/server/file-explorer/service.js.map +1 -1
- package/dist/server/server/notifications/relay-client.d.ts +9 -0
- package/dist/server/server/notifications/relay-client.d.ts.map +1 -0
- package/dist/server/server/notifications/relay-client.js +55 -0
- package/dist/server/server/notifications/relay-client.js.map +1 -0
- package/dist/server/server/notifications/relay-ownership.d.ts +5 -0
- package/dist/server/server/notifications/relay-ownership.d.ts.map +1 -0
- package/dist/server/server/notifications/relay-ownership.js +25 -0
- package/dist/server/server/notifications/relay-ownership.js.map +1 -0
- package/dist/server/server/notifications/relay-store.d.ts +22 -0
- package/dist/server/server/notifications/relay-store.d.ts.map +1 -0
- package/dist/server/server/notifications/relay-store.js +72 -0
- package/dist/server/server/notifications/relay-store.js.map +1 -0
- package/dist/server/server/session.d.ts +3 -0
- package/dist/server/server/session.d.ts.map +1 -1
- package/dist/server/server/session.js +130 -76
- package/dist/server/server/session.js.map +1 -1
- package/dist/server/server/websocket-server.d.ts +1 -0
- package/dist/server/server/websocket-server.d.ts.map +1 -1
- package/dist/server/server/websocket-server.js +31 -5
- package/dist/server/server/websocket-server.js.map +1 -1
- package/dist/server/shared/agent-attention-notification.d.ts +2 -0
- package/dist/server/shared/agent-attention-notification.d.ts.map +1 -1
- package/dist/server/shared/agent-attention-notification.js +23 -5
- package/dist/server/shared/agent-attention-notification.js.map +1 -1
- package/dist/server/shared/messages.d.ts +1522 -1035
- package/dist/server/shared/messages.d.ts.map +1 -1
- package/dist/server/shared/messages.js +51 -12
- package/dist/server/shared/messages.js.map +1 -1
- package/package.json +2 -2
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
const NOTIFICATION_RELAY_REQUEST_TIMEOUT_MS = 10000;
|
|
2
|
+
export class NotificationRelayClient {
|
|
3
|
+
constructor(logger) {
|
|
4
|
+
this.logger = logger;
|
|
5
|
+
}
|
|
6
|
+
async relayAttention(config, notification) {
|
|
7
|
+
const expiresAt = new Date(config.expiresAt);
|
|
8
|
+
if (Number.isNaN(expiresAt.getTime()) || expiresAt.getTime() <= Date.now()) {
|
|
9
|
+
this.logger.warn({ expiresAt: config.expiresAt }, "Skipping expired notification relay config");
|
|
10
|
+
return;
|
|
11
|
+
}
|
|
12
|
+
const body = {
|
|
13
|
+
notification: {
|
|
14
|
+
title: notification.title,
|
|
15
|
+
body: notification.body,
|
|
16
|
+
tag: `${notification.data.serverId}:${notification.data.agentId}:${notification.data.category}`,
|
|
17
|
+
data: {
|
|
18
|
+
type: "agent_attention",
|
|
19
|
+
serverId: notification.data.serverId,
|
|
20
|
+
agentId: notification.data.agentId,
|
|
21
|
+
category: notification.data.category,
|
|
22
|
+
sentAt: new Date().toISOString(),
|
|
23
|
+
},
|
|
24
|
+
},
|
|
25
|
+
};
|
|
26
|
+
const controller = new AbortController();
|
|
27
|
+
const timeoutId = setTimeout(() => controller.abort(), NOTIFICATION_RELAY_REQUEST_TIMEOUT_MS);
|
|
28
|
+
let response;
|
|
29
|
+
try {
|
|
30
|
+
response = await fetch(config.relayUrl, {
|
|
31
|
+
method: "POST",
|
|
32
|
+
headers: {
|
|
33
|
+
authorization: `Bearer ${config.token}`,
|
|
34
|
+
"content-type": "application/json",
|
|
35
|
+
},
|
|
36
|
+
body: JSON.stringify(body),
|
|
37
|
+
signal: controller.signal,
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
catch (error) {
|
|
41
|
+
if (error instanceof Error && error.name === "AbortError") {
|
|
42
|
+
throw new Error(`Notification relay timed out after ${NOTIFICATION_RELAY_REQUEST_TIMEOUT_MS}ms`);
|
|
43
|
+
}
|
|
44
|
+
throw error;
|
|
45
|
+
}
|
|
46
|
+
finally {
|
|
47
|
+
clearTimeout(timeoutId);
|
|
48
|
+
}
|
|
49
|
+
if (!response.ok) {
|
|
50
|
+
const responseText = await response.text().catch(() => "");
|
|
51
|
+
throw new Error(`Notification relay failed with ${response.status}${responseText ? `: ${responseText}` : ""}`);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
//# sourceMappingURL=relay-client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"relay-client.js","sourceRoot":"","sources":["../../../../src/server/notifications/relay-client.ts"],"names":[],"mappings":"AAQA,MAAM,qCAAqC,GAAG,KAAK,CAAA;AAiBnD,MAAM,OAAO,uBAAuB;IAClC,YAA6B,MAAc;QAAd,WAAM,GAAN,MAAM,CAAQ;IAAG,CAAC;IAE/C,KAAK,CAAC,cAAc,CAClB,MAA+B,EAC/B,YAA+C;QAE/C,MAAM,SAAS,GAAG,IAAI,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,CAAA;QAC5C,IAAI,MAAM,CAAC,KAAK,CAAC,SAAS,CAAC,OAAO,EAAE,CAAC,IAAI,SAAS,CAAC,OAAO,EAAE,IAAI,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC;YAC3E,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,SAAS,EAAE,MAAM,CAAC,SAAS,EAAE,EAAE,4CAA4C,CAAC,CAAA;YAC/F,OAAM;QACR,CAAC;QAED,MAAM,IAAI,GAAiC;YACzC,YAAY,EAAE;gBACZ,KAAK,EAAE,YAAY,CAAC,KAAK;gBACzB,IAAI,EAAE,YAAY,CAAC,IAAI;gBACvB,GAAG,EAAE,GAAG,YAAY,CAAC,IAAI,CAAC,QAAQ,IAAI,YAAY,CAAC,IAAI,CAAC,OAAO,IAAI,YAAY,CAAC,IAAI,CAAC,QAAQ,EAAE;gBAC/F,IAAI,EAAE;oBACJ,IAAI,EAAE,iBAAiB;oBACvB,QAAQ,EAAE,YAAY,CAAC,IAAI,CAAC,QAAQ;oBACpC,OAAO,EAAE,YAAY,CAAC,IAAI,CAAC,OAAO;oBAClC,QAAQ,EAAE,YAAY,CAAC,IAAI,CAAC,QAAQ;oBACpC,MAAM,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;iBACjC;aACF;SACF,CAAA;QAED,MAAM,UAAU,GAAG,IAAI,eAAe,EAAE,CAAA;QACxC,MAAM,SAAS,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,UAAU,CAAC,KAAK,EAAE,EAAE,qCAAqC,CAAC,CAAA;QAC7F,IAAI,QAAkB,CAAA;QAEtB,IAAI,CAAC;YACH,QAAQ,GAAG,MAAM,KAAK,CAAC,MAAM,CAAC,QAAQ,EAAE;gBACtC,MAAM,EAAE,MAAM;gBACd,OAAO,EAAE;oBACP,aAAa,EAAE,UAAU,MAAM,CAAC,KAAK,EAAE;oBACvC,cAAc,EAAE,kBAAkB;iBACnC;gBACD,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC;gBAC1B,MAAM,EAAE,UAAU,CAAC,MAAM;aAC1B,CAAC,CAAA;QACJ,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,KAAK,YAAY,KAAK,IAAI,KAAK,CAAC,IAAI,KAAK,YAAY,EAAE,CAAC;gBAC1D,MAAM,IAAI,KAAK,CACb,sCAAsC,qCAAqC,IAAI,CAChF,CAAA;YACH,CAAC;YACD,MAAM,KAAK,CAAA;QACb,CAAC;gBAAS,CAAC;YACT,YAAY,CAAC,SAAS,CAAC,CAAA;QACzB,CAAC;QAED,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;YACjB,MAAM,YAAY,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,CAAA;YAC1D,MAAM,IAAI,KAAK,CACb,kCAAkC,QAAQ,CAAC,MAAM,GAAG,YAAY,CAAC,CAAC,CAAC,KAAK,YAAY,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAC9F,CAAA;QACH,CAAC;IACH,CAAC;CACF"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export declare const NOTIFICATION_RELAY_USER_LABEL = "junction:notification-user";
|
|
2
|
+
export declare function applyNotificationRelayOwnerLabel(labels: Record<string, string> | undefined, userId: string | undefined): Record<string, string> | undefined;
|
|
3
|
+
export declare function preserveNotificationRelayOwnerLabel(currentLabels: Record<string, string>, nextLabels: Record<string, string>): Record<string, string>;
|
|
4
|
+
export declare function getNotificationRelayOwnerUserId(labels: Record<string, string> | undefined): string | undefined;
|
|
5
|
+
//# sourceMappingURL=relay-ownership.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"relay-ownership.d.ts","sourceRoot":"","sources":["../../../../src/server/notifications/relay-ownership.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,6BAA6B,+BAA+B,CAAA;AAEzE,wBAAgB,gCAAgC,CAC9C,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,SAAS,EAC1C,MAAM,EAAE,MAAM,GAAG,SAAS,GACzB,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,SAAS,CASpC;AAED,wBAAgB,mCAAmC,CACjD,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EACrC,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GACjC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAUxB;AAED,wBAAgB,+BAA+B,CAC7C,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,SAAS,GACzC,MAAM,GAAG,SAAS,CAGpB"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
export const NOTIFICATION_RELAY_USER_LABEL = "junction:notification-user";
|
|
2
|
+
export function applyNotificationRelayOwnerLabel(labels, userId) {
|
|
3
|
+
if (!userId) {
|
|
4
|
+
return labels;
|
|
5
|
+
}
|
|
6
|
+
return {
|
|
7
|
+
...(labels ?? {}),
|
|
8
|
+
[NOTIFICATION_RELAY_USER_LABEL]: userId,
|
|
9
|
+
};
|
|
10
|
+
}
|
|
11
|
+
export function preserveNotificationRelayOwnerLabel(currentLabels, nextLabels) {
|
|
12
|
+
const relayOwnerUserId = currentLabels[NOTIFICATION_RELAY_USER_LABEL];
|
|
13
|
+
if (!relayOwnerUserId) {
|
|
14
|
+
return nextLabels;
|
|
15
|
+
}
|
|
16
|
+
return {
|
|
17
|
+
...nextLabels,
|
|
18
|
+
[NOTIFICATION_RELAY_USER_LABEL]: relayOwnerUserId,
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
export function getNotificationRelayOwnerUserId(labels) {
|
|
22
|
+
const relayOwnerUserId = labels?.[NOTIFICATION_RELAY_USER_LABEL]?.trim();
|
|
23
|
+
return relayOwnerUserId ? relayOwnerUserId : undefined;
|
|
24
|
+
}
|
|
25
|
+
//# sourceMappingURL=relay-ownership.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"relay-ownership.js","sourceRoot":"","sources":["../../../../src/server/notifications/relay-ownership.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,6BAA6B,GAAG,4BAA4B,CAAA;AAEzE,MAAM,UAAU,gCAAgC,CAC9C,MAA0C,EAC1C,MAA0B;IAE1B,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,OAAO,MAAM,CAAA;IACf,CAAC;IAED,OAAO;QACL,GAAG,CAAC,MAAM,IAAI,EAAE,CAAC;QACjB,CAAC,6BAA6B,CAAC,EAAE,MAAM;KACxC,CAAA;AACH,CAAC;AAED,MAAM,UAAU,mCAAmC,CACjD,aAAqC,EACrC,UAAkC;IAElC,MAAM,gBAAgB,GAAG,aAAa,CAAC,6BAA6B,CAAC,CAAA;IACrE,IAAI,CAAC,gBAAgB,EAAE,CAAC;QACtB,OAAO,UAAU,CAAA;IACnB,CAAC;IAED,OAAO;QACL,GAAG,UAAU;QACb,CAAC,6BAA6B,CAAC,EAAE,gBAAgB;KAClD,CAAA;AACH,CAAC;AAED,MAAM,UAAU,+BAA+B,CAC7C,MAA0C;IAE1C,MAAM,gBAAgB,GAAG,MAAM,EAAE,CAAC,6BAA6B,CAAC,EAAE,IAAI,EAAE,CAAA;IACxE,OAAO,gBAAgB,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC,CAAC,SAAS,CAAA;AACxD,CAAC"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
export declare const NotificationRelayConfigSchema: z.ZodObject<{
|
|
3
|
+
relayUrl: z.ZodString;
|
|
4
|
+
token: z.ZodString;
|
|
5
|
+
expiresAt: z.ZodString;
|
|
6
|
+
updatedAt: z.ZodString;
|
|
7
|
+
}, "strip", z.ZodTypeAny, {
|
|
8
|
+
updatedAt: string;
|
|
9
|
+
relayUrl: string;
|
|
10
|
+
token: string;
|
|
11
|
+
expiresAt: string;
|
|
12
|
+
}, {
|
|
13
|
+
updatedAt: string;
|
|
14
|
+
relayUrl: string;
|
|
15
|
+
token: string;
|
|
16
|
+
expiresAt: string;
|
|
17
|
+
}>;
|
|
18
|
+
export type NotificationRelayConfig = z.infer<typeof NotificationRelayConfigSchema>;
|
|
19
|
+
export declare function loadNotificationRelayConfig(junctionHome: string, userId?: string): NotificationRelayConfig | null;
|
|
20
|
+
export declare function loadNotificationRelayConfigs(junctionHome: string): NotificationRelayConfig[];
|
|
21
|
+
export declare function saveNotificationRelayConfig(junctionHome: string, userId: string | undefined, relay: Omit<NotificationRelayConfig, "updatedAt"> | null): NotificationRelayConfig | null;
|
|
22
|
+
//# sourceMappingURL=relay-store.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"relay-store.d.ts","sourceRoot":"","sources":["../../../../src/server/notifications/relay-store.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAEvB,eAAO,MAAM,6BAA6B;;;;;;;;;;;;;;;EAKxC,CAAA;AAEF,MAAM,MAAM,uBAAuB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,6BAA6B,CAAC,CAAA;AAsCnF,wBAAgB,2BAA2B,CACzC,YAAY,EAAE,MAAM,EACpB,MAAM,CAAC,EAAE,MAAM,GACd,uBAAuB,GAAG,IAAI,CAahC;AAED,wBAAgB,4BAA4B,CAAC,YAAY,EAAE,MAAM,GAAG,uBAAuB,EAAE,CAE5F;AAED,wBAAgB,2BAA2B,CACzC,YAAY,EAAE,MAAM,EACpB,MAAM,EAAE,MAAM,GAAG,SAAS,EAC1B,KAAK,EAAE,IAAI,CAAC,uBAAuB,EAAE,WAAW,CAAC,GAAG,IAAI,GACvD,uBAAuB,GAAG,IAAI,CA0BhC"}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { chmodSync, existsSync, mkdirSync, readFileSync, rmSync, writeFileSync } from "node:fs";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import { z } from "zod";
|
|
4
|
+
export const NotificationRelayConfigSchema = z.object({
|
|
5
|
+
relayUrl: z.string().trim().url(),
|
|
6
|
+
token: z.string().trim().min(1),
|
|
7
|
+
expiresAt: z.string(),
|
|
8
|
+
updatedAt: z.string(),
|
|
9
|
+
});
|
|
10
|
+
const NotificationRelayConfigFileSchema = z.object({
|
|
11
|
+
relaysByScope: z.record(z.string(), NotificationRelayConfigSchema),
|
|
12
|
+
});
|
|
13
|
+
function getNotificationRelayScope(userId) {
|
|
14
|
+
const trimmedUserId = userId?.trim();
|
|
15
|
+
return trimmedUserId ? `user:${trimmedUserId}` : "anonymous";
|
|
16
|
+
}
|
|
17
|
+
function getNotificationRelayConfigPath(junctionHome) {
|
|
18
|
+
return path.join(junctionHome, "notification-relay.json");
|
|
19
|
+
}
|
|
20
|
+
function loadNotificationRelayConfigFile(junctionHome) {
|
|
21
|
+
const configPath = getNotificationRelayConfigPath(junctionHome);
|
|
22
|
+
if (!existsSync(configPath)) {
|
|
23
|
+
return { relaysByScope: {} };
|
|
24
|
+
}
|
|
25
|
+
const raw = readFileSync(configPath, "utf8");
|
|
26
|
+
return NotificationRelayConfigFileSchema.parse(JSON.parse(raw));
|
|
27
|
+
}
|
|
28
|
+
function writeNotificationRelayConfigFile(configPath, relaysByScope) {
|
|
29
|
+
mkdirSync(path.dirname(configPath), { recursive: true });
|
|
30
|
+
writeFileSync(configPath, JSON.stringify(NotificationRelayConfigFileSchema.parse({ relaysByScope }), null, 2) + "\n", { mode: 0o600 });
|
|
31
|
+
chmodSync(configPath, 0o600);
|
|
32
|
+
}
|
|
33
|
+
export function loadNotificationRelayConfig(junctionHome, userId) {
|
|
34
|
+
const parsed = loadNotificationRelayConfigFile(junctionHome);
|
|
35
|
+
const directMatch = parsed.relaysByScope[getNotificationRelayScope(userId)] ?? null;
|
|
36
|
+
if (directMatch) {
|
|
37
|
+
return directMatch;
|
|
38
|
+
}
|
|
39
|
+
if (userId !== undefined) {
|
|
40
|
+
return null;
|
|
41
|
+
}
|
|
42
|
+
const scopedConfigs = Object.values(parsed.relaysByScope);
|
|
43
|
+
return scopedConfigs.length === 1 ? scopedConfigs[0] : null;
|
|
44
|
+
}
|
|
45
|
+
export function loadNotificationRelayConfigs(junctionHome) {
|
|
46
|
+
return Object.values(loadNotificationRelayConfigFile(junctionHome).relaysByScope);
|
|
47
|
+
}
|
|
48
|
+
export function saveNotificationRelayConfig(junctionHome, userId, relay) {
|
|
49
|
+
const configPath = getNotificationRelayConfigPath(junctionHome);
|
|
50
|
+
const scope = getNotificationRelayScope(userId);
|
|
51
|
+
const nextRelaysByScope = loadNotificationRelayConfigFile(junctionHome).relaysByScope;
|
|
52
|
+
if (relay === null) {
|
|
53
|
+
delete nextRelaysByScope[scope];
|
|
54
|
+
if (Object.keys(nextRelaysByScope).length === 0) {
|
|
55
|
+
rmSync(configPath, { force: true });
|
|
56
|
+
return null;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
else {
|
|
60
|
+
mkdirSync(path.dirname(configPath), { recursive: true });
|
|
61
|
+
const savedRelay = NotificationRelayConfigSchema.parse({
|
|
62
|
+
...relay,
|
|
63
|
+
updatedAt: new Date().toISOString(),
|
|
64
|
+
});
|
|
65
|
+
nextRelaysByScope[scope] = savedRelay;
|
|
66
|
+
writeNotificationRelayConfigFile(configPath, nextRelaysByScope);
|
|
67
|
+
return savedRelay;
|
|
68
|
+
}
|
|
69
|
+
writeNotificationRelayConfigFile(configPath, nextRelaysByScope);
|
|
70
|
+
return null;
|
|
71
|
+
}
|
|
72
|
+
//# sourceMappingURL=relay-store.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"relay-store.js","sourceRoot":"","sources":["../../../../src/server/notifications/relay-store.ts"],"names":[],"mappings":"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"}
|
|
@@ -99,6 +99,8 @@ export declare class Session {
|
|
|
99
99
|
*/
|
|
100
100
|
private startAgentStream;
|
|
101
101
|
private handleAgentRunError;
|
|
102
|
+
private enqueueAcceptedAgentMessageExecution;
|
|
103
|
+
private performAgentMessageSend;
|
|
102
104
|
/**
|
|
103
105
|
* Initialize Agent MCP client for this session using in-memory transport
|
|
104
106
|
*/
|
|
@@ -156,6 +158,7 @@ export declare class Session {
|
|
|
156
158
|
private handleGetDaemonProviderSettingsRequest;
|
|
157
159
|
private handleUpdateDaemonProviderSettingsRequest;
|
|
158
160
|
private handleAutoRouteProviderRequest;
|
|
161
|
+
private handleUpdateNotificationRelayConfigRequest;
|
|
159
162
|
private normalizeGitOptions;
|
|
160
163
|
private assertSafeGitRef;
|
|
161
164
|
private assertSafeRemoteName;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../../../src/server/session.ts"],"names":[],"mappings":"AAQA,OAAO,EAGL,KAAK,qBAAqB,EAC1B,KAAK,sBAAsB,
|
|
1
|
+
{"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../../../src/server/session.ts"],"names":[],"mappings":"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"}
|
|
@@ -18,7 +18,7 @@ import { appendTimelineItemIfAgentKnown, emitLiveTimelineItemIfAgentKnown, } fro
|
|
|
18
18
|
import { projectTimelineRows, selectTimelineWindowByProjectedLimit, } from './agent/timeline-projection.js';
|
|
19
19
|
import { DEFAULT_STRUCTURED_GENERATION_PROVIDERS, StructuredAgentFallbackError, StructuredAgentResponseError, generateStructuredAgentResponseWithFallback, } from './agent/agent-response-loop.js';
|
|
20
20
|
import { isValidAgentProvider, AGENT_PROVIDER_IDS } from './agent/provider-manifest.js';
|
|
21
|
-
import { listDirectoryEntries, readExplorerFile, getDownloadableFileInfo, } from './file-explorer/service.js';
|
|
21
|
+
import { listDirectoryEntries, readExplorerFile, getDownloadableFileInfo, isWorkspaceExplorerMissingPathError, } from './file-explorer/service.js';
|
|
22
22
|
import { slugify, validateBranchSlug, listJunctionWorktrees, deleteJunctionWorktree, isJunctionOwnedWorktreeCwd, resolveJunctionWorktreeRootForCwd, createInRepoWorktree, restoreInRepoWorktree, } from '../utils/worktree.js';
|
|
23
23
|
import { readJunctionWorktreeMetadata } from '../utils/worktree-metadata.js';
|
|
24
24
|
import { runAsyncWorktreeBootstrap } from './worktree-bootstrap.js';
|
|
@@ -33,6 +33,8 @@ import { deriveProjectGroupingKey, deriveProjectGroupingName } from '../shared/p
|
|
|
33
33
|
import { DEFAULT_DAEMON_PACKAGE_NAME, resolveDaemonPackageVersion, } from './daemon-package-context.js';
|
|
34
34
|
import { runDaemonDoctor } from './daemon-doctor.js';
|
|
35
35
|
import { MANAGED_DAEMON_PROVIDERS, autoRouteProviderExecutable, loadDaemonProviderSettings, saveDaemonProviderExecutablePath, } from './daemon-provider-settings.js';
|
|
36
|
+
import { applyNotificationRelayOwnerLabel, preserveNotificationRelayOwnerLabel, } from './notifications/relay-ownership.js';
|
|
37
|
+
import { saveNotificationRelayConfig } from './notifications/relay-store.js';
|
|
36
38
|
import { resolvePackageUpdateInfo } from './package-update.js';
|
|
37
39
|
import { loadPersistedConfig } from './persisted-config.js';
|
|
38
40
|
const execAsync = promisify(exec);
|
|
@@ -42,6 +44,7 @@ const READ_ONLY_GIT_ENV = {
|
|
|
42
44
|
};
|
|
43
45
|
const DEFAULT_STORED_TIMELINE_FETCH_LIMIT = 200;
|
|
44
46
|
const pendingAgentInitializations = new Map();
|
|
47
|
+
const pendingAgentMessageExecutions = new Map();
|
|
45
48
|
const DEFAULT_AGENT_PROVIDER = AGENT_PROVIDER_IDS[0];
|
|
46
49
|
const CHECKOUT_DIFF_WATCH_DEBOUNCE_MS = 150;
|
|
47
50
|
const CHECKOUT_DIFF_FALLBACK_REFRESH_MS = 5000;
|
|
@@ -247,6 +250,61 @@ export class Session {
|
|
|
247
250
|
},
|
|
248
251
|
});
|
|
249
252
|
}
|
|
253
|
+
enqueueAcceptedAgentMessageExecution(input) {
|
|
254
|
+
const previous = pendingAgentMessageExecutions.get(input.agentId) ?? Promise.resolve();
|
|
255
|
+
const execution = previous
|
|
256
|
+
.catch(() => undefined)
|
|
257
|
+
.then(async () => {
|
|
258
|
+
const startedAt = Date.now();
|
|
259
|
+
const phaseTimings = {
|
|
260
|
+
performSendMs: 0,
|
|
261
|
+
waitForRunStartMs: 0,
|
|
262
|
+
};
|
|
263
|
+
const performSendStartedAt = Date.now();
|
|
264
|
+
await this.performAgentMessageSend(input);
|
|
265
|
+
phaseTimings.performSendMs = Date.now() - performSendStartedAt;
|
|
266
|
+
const waitForRunStartStartedAt = Date.now();
|
|
267
|
+
await this.agentManager.waitForAgentRunStart(input.agentId);
|
|
268
|
+
phaseTimings.waitForRunStartMs = Date.now() - waitForRunStartStartedAt;
|
|
269
|
+
this.sessionLogger.debug({
|
|
270
|
+
agentId: input.agentId,
|
|
271
|
+
durationMs: Date.now() - startedAt,
|
|
272
|
+
...phaseTimings,
|
|
273
|
+
}, 'Accepted send_agent_message_request execution started');
|
|
274
|
+
});
|
|
275
|
+
const trackedExecution = execution.finally(() => {
|
|
276
|
+
if (pendingAgentMessageExecutions.get(input.agentId) === trackedExecution) {
|
|
277
|
+
pendingAgentMessageExecutions.delete(input.agentId);
|
|
278
|
+
}
|
|
279
|
+
});
|
|
280
|
+
pendingAgentMessageExecutions.set(input.agentId, trackedExecution);
|
|
281
|
+
return trackedExecution;
|
|
282
|
+
}
|
|
283
|
+
async performAgentMessageSend(input) {
|
|
284
|
+
await this.ensureAgentLoaded(input.agentId);
|
|
285
|
+
await this.interruptAgentIfRunning(input.agentId);
|
|
286
|
+
try {
|
|
287
|
+
this.agentManager.recordUserMessage(input.agentId, input.text, {
|
|
288
|
+
messageId: input.messageId,
|
|
289
|
+
emitState: false,
|
|
290
|
+
images: input.images?.map((image) => ({
|
|
291
|
+
data: image.preview?.data ?? image.data,
|
|
292
|
+
mimeType: image.preview?.mimeType ?? image.mimeType,
|
|
293
|
+
...(image.label ? { label: image.label } : {}),
|
|
294
|
+
...(image.preview?.width != null ? { width: image.preview.width } : {}),
|
|
295
|
+
...(image.preview?.height != null ? { height: image.preview.height } : {}),
|
|
296
|
+
})),
|
|
297
|
+
});
|
|
298
|
+
}
|
|
299
|
+
catch (error) {
|
|
300
|
+
this.sessionLogger.error({ err: error, agentId: input.agentId }, `Failed to record user message for agent ${input.agentId}`);
|
|
301
|
+
}
|
|
302
|
+
const prompt = this.buildAgentPrompt(input.text, input.images);
|
|
303
|
+
const started = this.startAgentStream(input.agentId, prompt, input.runOptions);
|
|
304
|
+
if (!started.ok) {
|
|
305
|
+
throw new Error(started.error);
|
|
306
|
+
}
|
|
307
|
+
}
|
|
250
308
|
/**
|
|
251
309
|
* Initialize Agent MCP client for this session using in-memory transport
|
|
252
310
|
*/
|
|
@@ -889,6 +947,9 @@ export class Session {
|
|
|
889
947
|
case 'auto_route_provider_request':
|
|
890
948
|
await this.handleAutoRouteProviderRequest(msg);
|
|
891
949
|
break;
|
|
950
|
+
case 'update_notification_relay_config_request':
|
|
951
|
+
await this.handleUpdateNotificationRelayConfigRequest(msg);
|
|
952
|
+
break;
|
|
892
953
|
case 'clear_agent_attention':
|
|
893
954
|
await this.handleClearAgentAttention(msg.agentId);
|
|
894
955
|
break;
|
|
@@ -1357,7 +1418,7 @@ export class Session {
|
|
|
1357
1418
|
await this.agentManager.setTitle(agentId, normalizedName);
|
|
1358
1419
|
}
|
|
1359
1420
|
if (normalizedLabels) {
|
|
1360
|
-
await this.agentManager.setLabels(agentId, normalizedLabels);
|
|
1421
|
+
await this.agentManager.setLabels(agentId, preserveNotificationRelayOwnerLabel(liveAgent.labels, normalizedLabels));
|
|
1361
1422
|
}
|
|
1362
1423
|
}
|
|
1363
1424
|
else {
|
|
@@ -1368,7 +1429,11 @@ export class Session {
|
|
|
1368
1429
|
await this.agentStorage.upsert({
|
|
1369
1430
|
...existing,
|
|
1370
1431
|
...(normalizedName ? { title: normalizedName } : {}),
|
|
1371
|
-
...(normalizedLabels
|
|
1432
|
+
...(normalizedLabels
|
|
1433
|
+
? {
|
|
1434
|
+
labels: preserveNotificationRelayOwnerLabel(existing.labels, normalizedLabels),
|
|
1435
|
+
}
|
|
1436
|
+
: {}),
|
|
1372
1437
|
});
|
|
1373
1438
|
}
|
|
1374
1439
|
this.emit({
|
|
@@ -1409,30 +1474,17 @@ export class Session {
|
|
|
1409
1474
|
return;
|
|
1410
1475
|
}
|
|
1411
1476
|
try {
|
|
1412
|
-
await this.
|
|
1413
|
-
|
|
1414
|
-
|
|
1415
|
-
this.handleAgentRunError(agentId, error, 'Failed to initialize agent before sending prompt');
|
|
1416
|
-
return;
|
|
1417
|
-
}
|
|
1418
|
-
try {
|
|
1419
|
-
await this.interruptAgentIfRunning(agentId);
|
|
1420
|
-
}
|
|
1421
|
-
catch (error) {
|
|
1422
|
-
this.handleAgentRunError(agentId, error, 'Failed to interrupt running agent before sending prompt');
|
|
1423
|
-
return;
|
|
1424
|
-
}
|
|
1425
|
-
const prompt = this.buildAgentPrompt(text, images);
|
|
1426
|
-
try {
|
|
1427
|
-
this.agentManager.recordUserMessage(agentId, text, {
|
|
1477
|
+
await this.performAgentMessageSend({
|
|
1478
|
+
agentId,
|
|
1479
|
+
text,
|
|
1428
1480
|
messageId,
|
|
1429
|
-
|
|
1481
|
+
images,
|
|
1482
|
+
runOptions,
|
|
1430
1483
|
});
|
|
1431
1484
|
}
|
|
1432
1485
|
catch (error) {
|
|
1433
|
-
this.
|
|
1486
|
+
this.handleAgentRunError(agentId, error, 'Failed to send prompt to agent');
|
|
1434
1487
|
}
|
|
1435
|
-
this.startAgentStream(agentId, prompt, runOptions);
|
|
1436
1488
|
}
|
|
1437
1489
|
/**
|
|
1438
1490
|
* Handle create agent request
|
|
@@ -1445,7 +1497,9 @@ export class Session {
|
|
|
1445
1497
|
const mergedLabels = autoWorkspaceName
|
|
1446
1498
|
? { ...labels, 'junction:workspace': autoWorkspaceName }
|
|
1447
1499
|
: labels;
|
|
1448
|
-
const snapshot = await this.agentManager.createAgent(sessionConfig, undefined, {
|
|
1500
|
+
const snapshot = await this.agentManager.createAgent(sessionConfig, undefined, {
|
|
1501
|
+
labels: applyNotificationRelayOwnerLabel(mergedLabels, this.userId),
|
|
1502
|
+
});
|
|
1449
1503
|
await this.forwardAgentUpdate(snapshot);
|
|
1450
1504
|
if (requestId) {
|
|
1451
1505
|
const agentPayload = await this.getAgentPayloadById(snapshot.id);
|
|
@@ -1941,6 +1995,46 @@ export class Session {
|
|
|
1941
1995
|
});
|
|
1942
1996
|
}
|
|
1943
1997
|
}
|
|
1998
|
+
async handleUpdateNotificationRelayConfigRequest(msg) {
|
|
1999
|
+
try {
|
|
2000
|
+
const relayUrl = msg.relayUrl?.trim();
|
|
2001
|
+
const token = msg.token?.trim();
|
|
2002
|
+
const expiresAt = msg.expiresAt?.trim();
|
|
2003
|
+
const providedCount = [msg.relayUrl, msg.token, msg.expiresAt].filter((value) => value !== undefined).length;
|
|
2004
|
+
if (providedCount === 0) {
|
|
2005
|
+
saveNotificationRelayConfig(this.junctionHome, this.userId, null);
|
|
2006
|
+
}
|
|
2007
|
+
else if (providedCount !== 3 || !relayUrl || !token || !expiresAt) {
|
|
2008
|
+
throw new SessionRequestError('invalid_notification_relay_config', 'relayUrl, token, and expiresAt must be provided together');
|
|
2009
|
+
}
|
|
2010
|
+
else {
|
|
2011
|
+
saveNotificationRelayConfig(this.junctionHome, this.userId, {
|
|
2012
|
+
relayUrl,
|
|
2013
|
+
token,
|
|
2014
|
+
expiresAt,
|
|
2015
|
+
});
|
|
2016
|
+
}
|
|
2017
|
+
this.emit({
|
|
2018
|
+
type: 'update_notification_relay_config_response',
|
|
2019
|
+
payload: {
|
|
2020
|
+
success: true,
|
|
2021
|
+
error: null,
|
|
2022
|
+
requestId: msg.requestId,
|
|
2023
|
+
},
|
|
2024
|
+
});
|
|
2025
|
+
}
|
|
2026
|
+
catch (error) {
|
|
2027
|
+
this.sessionLogger.error({ err: error }, 'Failed to update notification relay config');
|
|
2028
|
+
this.emit({
|
|
2029
|
+
type: 'update_notification_relay_config_response',
|
|
2030
|
+
payload: {
|
|
2031
|
+
success: false,
|
|
2032
|
+
error: error instanceof Error ? error.message : String(error),
|
|
2033
|
+
requestId: msg.requestId,
|
|
2034
|
+
},
|
|
2035
|
+
});
|
|
2036
|
+
}
|
|
2037
|
+
}
|
|
1944
2038
|
normalizeGitOptions(gitOptions, legacyWorktreeName) {
|
|
1945
2039
|
const fallbackOptions = legacyWorktreeName
|
|
1946
2040
|
? {
|
|
@@ -3743,7 +3837,10 @@ export class Session {
|
|
|
3743
3837
|
}
|
|
3744
3838
|
}
|
|
3745
3839
|
catch (error) {
|
|
3746
|
-
|
|
3840
|
+
const log = isWorkspaceExplorerMissingPathError(error)
|
|
3841
|
+
? this.sessionLogger.debug.bind(this.sessionLogger)
|
|
3842
|
+
: this.sessionLogger.error.bind(this.sessionLogger);
|
|
3843
|
+
log({ err: error, cwd, path: requestedPath }, `Failed to fulfill workspace file explorer request for cwd ${cwd}`);
|
|
3747
3844
|
this.emit({
|
|
3748
3845
|
type: 'workspace_file_explorer_response',
|
|
3749
3846
|
payload: {
|
|
@@ -4420,7 +4517,8 @@ export class Session {
|
|
|
4420
4517
|
}
|
|
4421
4518
|
try {
|
|
4422
4519
|
const agentId = resolved.agentId;
|
|
4423
|
-
const
|
|
4520
|
+
const storedRecord = await this.agentStorage.get(agentId);
|
|
4521
|
+
const archivedAt = storedRecord?.archivedAt ?? null;
|
|
4424
4522
|
if (archivedAt) {
|
|
4425
4523
|
this.emit({
|
|
4426
4524
|
type: 'send_agent_message_response',
|
|
@@ -4433,57 +4531,13 @@ export class Session {
|
|
|
4433
4531
|
});
|
|
4434
4532
|
return;
|
|
4435
4533
|
}
|
|
4436
|
-
await this.
|
|
4437
|
-
|
|
4438
|
-
|
|
4439
|
-
|
|
4440
|
-
|
|
4441
|
-
|
|
4442
|
-
|
|
4443
|
-
}
|
|
4444
|
-
catch (error) {
|
|
4445
|
-
this.sessionLogger.error({ err: error, agentId }, 'Failed to record user message for send_agent_message_request');
|
|
4446
|
-
}
|
|
4447
|
-
const prompt = this.buildAgentPrompt(msg.text, msg.images);
|
|
4448
|
-
const started = this.startAgentStream(agentId, prompt, normalizeAgentRunOptions(msg.runOptions));
|
|
4449
|
-
if (!started.ok) {
|
|
4450
|
-
this.emit({
|
|
4451
|
-
type: 'send_agent_message_response',
|
|
4452
|
-
payload: {
|
|
4453
|
-
requestId: msg.requestId,
|
|
4454
|
-
agentId,
|
|
4455
|
-
accepted: false,
|
|
4456
|
-
error: started.error,
|
|
4457
|
-
},
|
|
4458
|
-
});
|
|
4459
|
-
return;
|
|
4460
|
-
}
|
|
4461
|
-
const startAbort = new AbortController();
|
|
4462
|
-
const startTimeoutMs = 15000;
|
|
4463
|
-
const startTimeout = setTimeout(() => startAbort.abort('timeout'), startTimeoutMs);
|
|
4464
|
-
try {
|
|
4465
|
-
await this.agentManager.waitForAgentRunStart(agentId, { signal: startAbort.signal });
|
|
4466
|
-
}
|
|
4467
|
-
catch (error) {
|
|
4468
|
-
const message = error instanceof Error
|
|
4469
|
-
? error.message
|
|
4470
|
-
: typeof error === 'string'
|
|
4471
|
-
? error
|
|
4472
|
-
: 'Unknown error';
|
|
4473
|
-
this.emit({
|
|
4474
|
-
type: 'send_agent_message_response',
|
|
4475
|
-
payload: {
|
|
4476
|
-
requestId: msg.requestId,
|
|
4477
|
-
agentId,
|
|
4478
|
-
accepted: false,
|
|
4479
|
-
error: message,
|
|
4480
|
-
},
|
|
4481
|
-
});
|
|
4482
|
-
return;
|
|
4483
|
-
}
|
|
4484
|
-
finally {
|
|
4485
|
-
clearTimeout(startTimeout);
|
|
4486
|
-
}
|
|
4534
|
+
await this.enqueueAcceptedAgentMessageExecution({
|
|
4535
|
+
agentId,
|
|
4536
|
+
text: msg.text,
|
|
4537
|
+
...(msg.messageId ? { messageId: msg.messageId } : {}),
|
|
4538
|
+
...(msg.images ? { images: msg.images } : {}),
|
|
4539
|
+
runOptions: normalizeAgentRunOptions(msg.runOptions),
|
|
4540
|
+
});
|
|
4487
4541
|
this.emit({
|
|
4488
4542
|
type: 'send_agent_message_response',
|
|
4489
4543
|
payload: {
|