svamp-cli 0.2.8 → 0.2.9
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/{agentCommands-BBTwxjv1.mjs → agentCommands-CrfvZzCn.mjs} +2 -2
- package/dist/cli.mjs +28 -28
- package/dist/{commands-CAGeQm5f.mjs → commands-C1xgznG4.mjs} +2 -2
- package/dist/{commands-DXaH6BQg.mjs → commands-h1lFrJKK.mjs} +1 -1
- package/dist/index.mjs +1 -1
- package/dist/{package-BMEGmZWU.mjs → package-Bx_FLMjC.mjs} +1 -1
- package/dist/{run-CAcScbEG.mjs → run-IDo93bqK.mjs} +200 -5
- package/dist/{run-B3G5eZmn.mjs → run-wHgMyNHQ.mjs} +1 -1
- package/dist/{serveCommands-Dr9CAgHo.mjs → serveCommands-BguUrQAM.mjs} +4 -4
- package/package.json +1 -1
|
@@ -148,7 +148,7 @@ async function sessionBroadcast(action, args) {
|
|
|
148
148
|
console.log(`Broadcast sent: ${action}`);
|
|
149
149
|
}
|
|
150
150
|
async function connectToMachineService() {
|
|
151
|
-
const { connectAndGetMachine } = await import('./commands-
|
|
151
|
+
const { connectAndGetMachine } = await import('./commands-h1lFrJKK.mjs');
|
|
152
152
|
return connectAndGetMachine();
|
|
153
153
|
}
|
|
154
154
|
async function inboxSend(targetSessionId, opts) {
|
|
@@ -165,7 +165,7 @@ async function inboxSend(targetSessionId, opts) {
|
|
|
165
165
|
}
|
|
166
166
|
const { server, machine } = await connectToMachineService();
|
|
167
167
|
try {
|
|
168
|
-
const { resolveSessionId } = await import('./commands-
|
|
168
|
+
const { resolveSessionId } = await import('./commands-h1lFrJKK.mjs');
|
|
169
169
|
const sessions = await machine.listSessions();
|
|
170
170
|
const match = resolveSessionId(sessions, targetSessionId);
|
|
171
171
|
const fullTargetId = match.sessionId;
|
package/dist/cli.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { b as stopDaemon, s as startDaemon, d as daemonStatus } from './run-
|
|
1
|
+
import { b as stopDaemon, s as startDaemon, d as daemonStatus } from './run-IDo93bqK.mjs';
|
|
2
2
|
import 'os';
|
|
3
3
|
import 'fs/promises';
|
|
4
4
|
import 'fs';
|
|
@@ -231,7 +231,7 @@ async function main() {
|
|
|
231
231
|
console.error("svamp serve: Serve commands are not available in sandboxed sessions.");
|
|
232
232
|
process.exit(1);
|
|
233
233
|
}
|
|
234
|
-
const { handleServeCommand } = await import('./serveCommands-
|
|
234
|
+
const { handleServeCommand } = await import('./serveCommands-BguUrQAM.mjs');
|
|
235
235
|
await handleServeCommand();
|
|
236
236
|
process.exit(0);
|
|
237
237
|
} else if (subcommand === "process" || subcommand === "proc") {
|
|
@@ -240,7 +240,7 @@ async function main() {
|
|
|
240
240
|
console.error("svamp process: Process commands are not available in sandboxed sessions.");
|
|
241
241
|
process.exit(1);
|
|
242
242
|
}
|
|
243
|
-
const { processCommand } = await import('./commands-
|
|
243
|
+
const { processCommand } = await import('./commands-C1xgznG4.mjs');
|
|
244
244
|
let machineId;
|
|
245
245
|
const processArgs = args.slice(1);
|
|
246
246
|
const mIdx = processArgs.findIndex((a) => a === "--machine" || a === "-m");
|
|
@@ -258,7 +258,7 @@ async function main() {
|
|
|
258
258
|
} else if (!subcommand || subcommand === "start") {
|
|
259
259
|
await handleInteractiveCommand();
|
|
260
260
|
} else if (subcommand === "--version" || subcommand === "-v") {
|
|
261
|
-
const pkg = await import('./package-
|
|
261
|
+
const pkg = await import('./package-Bx_FLMjC.mjs').catch(() => ({ default: { version: "unknown" } }));
|
|
262
262
|
console.log(`svamp version: ${pkg.default.version}`);
|
|
263
263
|
} else {
|
|
264
264
|
console.error(`Unknown command: ${subcommand}`);
|
|
@@ -267,7 +267,7 @@ async function main() {
|
|
|
267
267
|
}
|
|
268
268
|
}
|
|
269
269
|
async function handleInteractiveCommand() {
|
|
270
|
-
const { runInteractive } = await import('./run-
|
|
270
|
+
const { runInteractive } = await import('./run-wHgMyNHQ.mjs');
|
|
271
271
|
const interactiveArgs = subcommand === "start" ? args.slice(1) : args;
|
|
272
272
|
let directory = process.cwd();
|
|
273
273
|
let resumeSessionId;
|
|
@@ -312,7 +312,7 @@ async function handleAgentCommand() {
|
|
|
312
312
|
return;
|
|
313
313
|
}
|
|
314
314
|
if (agentArgs[0] === "list") {
|
|
315
|
-
const { KNOWN_ACP_AGENTS, KNOWN_MCP_AGENTS: KNOWN_MCP_AGENTS2 } = await import('./run-
|
|
315
|
+
const { KNOWN_ACP_AGENTS, KNOWN_MCP_AGENTS: KNOWN_MCP_AGENTS2 } = await import('./run-IDo93bqK.mjs').then(function (n) { return n.i; });
|
|
316
316
|
console.log("Known agents:");
|
|
317
317
|
for (const [name, config2] of Object.entries(KNOWN_ACP_AGENTS)) {
|
|
318
318
|
console.log(` ${name.padEnd(12)} ${config2.command} ${config2.args.join(" ")} (ACP)`);
|
|
@@ -324,7 +324,7 @@ async function handleAgentCommand() {
|
|
|
324
324
|
console.log('Use "svamp agent -- <command> [args]" for a custom ACP agent.');
|
|
325
325
|
return;
|
|
326
326
|
}
|
|
327
|
-
const { resolveAcpAgentConfig, KNOWN_MCP_AGENTS } = await import('./run-
|
|
327
|
+
const { resolveAcpAgentConfig, KNOWN_MCP_AGENTS } = await import('./run-IDo93bqK.mjs').then(function (n) { return n.i; });
|
|
328
328
|
let cwd = process.cwd();
|
|
329
329
|
const filteredArgs = [];
|
|
330
330
|
for (let i = 0; i < agentArgs.length; i++) {
|
|
@@ -348,12 +348,12 @@ async function handleAgentCommand() {
|
|
|
348
348
|
console.log(`Starting ${config.agentName} agent in ${cwd}...`);
|
|
349
349
|
let backend;
|
|
350
350
|
if (KNOWN_MCP_AGENTS[config.agentName]) {
|
|
351
|
-
const { CodexMcpBackend } = await import('./run-
|
|
351
|
+
const { CodexMcpBackend } = await import('./run-IDo93bqK.mjs').then(function (n) { return n.j; });
|
|
352
352
|
backend = new CodexMcpBackend({ cwd, log: logFn });
|
|
353
353
|
} else {
|
|
354
|
-
const { AcpBackend } = await import('./run-
|
|
355
|
-
const { GeminiTransport } = await import('./run-
|
|
356
|
-
const { DefaultTransport } = await import('./run-
|
|
354
|
+
const { AcpBackend } = await import('./run-IDo93bqK.mjs').then(function (n) { return n.h; });
|
|
355
|
+
const { GeminiTransport } = await import('./run-IDo93bqK.mjs').then(function (n) { return n.G; });
|
|
356
|
+
const { DefaultTransport } = await import('./run-IDo93bqK.mjs').then(function (n) { return n.D; });
|
|
357
357
|
const transportHandler = config.agentName === "gemini" ? new GeminiTransport() : new DefaultTransport(config.agentName);
|
|
358
358
|
backend = new AcpBackend({
|
|
359
359
|
agentName: config.agentName,
|
|
@@ -480,7 +480,7 @@ async function handleSessionCommand() {
|
|
|
480
480
|
process.exit(1);
|
|
481
481
|
}
|
|
482
482
|
}
|
|
483
|
-
const { sessionList, sessionSpawn, sessionStop, sessionInfo, sessionMessages, sessionAttach, sessionMachines, sessionSend, sessionWait, sessionShare, sessionRalphStart, sessionRalphCancel, sessionRalphStatus, sessionInboxSend, sessionInboxList, sessionInboxRead, sessionInboxReply, sessionInboxClear } = await import('./commands-
|
|
483
|
+
const { sessionList, sessionSpawn, sessionStop, sessionInfo, sessionMessages, sessionAttach, sessionMachines, sessionSend, sessionWait, sessionShare, sessionRalphStart, sessionRalphCancel, sessionRalphStatus, sessionInboxSend, sessionInboxList, sessionInboxRead, sessionInboxReply, sessionInboxClear } = await import('./commands-h1lFrJKK.mjs');
|
|
484
484
|
const parseFlagStr = (flag, shortFlag) => {
|
|
485
485
|
for (let i = 1; i < sessionArgs.length; i++) {
|
|
486
486
|
if ((sessionArgs[i] === flag || shortFlag) && i + 1 < sessionArgs.length) {
|
|
@@ -540,7 +540,7 @@ async function handleSessionCommand() {
|
|
|
540
540
|
allowDomain.push(sessionArgs[++i]);
|
|
541
541
|
}
|
|
542
542
|
}
|
|
543
|
-
const { parseShareArg } = await import('./commands-
|
|
543
|
+
const { parseShareArg } = await import('./commands-h1lFrJKK.mjs');
|
|
544
544
|
const shareEntries = share.map((s) => parseShareArg(s));
|
|
545
545
|
await sessionSpawn(agent, dir, targetMachineId, {
|
|
546
546
|
message,
|
|
@@ -626,7 +626,7 @@ async function handleSessionCommand() {
|
|
|
626
626
|
console.error("Usage: svamp session approve <session-id> [request-id] [--json]");
|
|
627
627
|
process.exit(1);
|
|
628
628
|
}
|
|
629
|
-
const { sessionApprove } = await import('./commands-
|
|
629
|
+
const { sessionApprove } = await import('./commands-h1lFrJKK.mjs');
|
|
630
630
|
const approveReqId = sessionArgs[2] && !sessionArgs[2].startsWith("--") ? sessionArgs[2] : void 0;
|
|
631
631
|
await sessionApprove(sessionArgs[1], approveReqId, targetMachineId, {
|
|
632
632
|
json: hasFlag("--json")
|
|
@@ -636,7 +636,7 @@ async function handleSessionCommand() {
|
|
|
636
636
|
console.error("Usage: svamp session deny <session-id> [request-id] [--json]");
|
|
637
637
|
process.exit(1);
|
|
638
638
|
}
|
|
639
|
-
const { sessionDeny } = await import('./commands-
|
|
639
|
+
const { sessionDeny } = await import('./commands-h1lFrJKK.mjs');
|
|
640
640
|
const denyReqId = sessionArgs[2] && !sessionArgs[2].startsWith("--") ? sessionArgs[2] : void 0;
|
|
641
641
|
await sessionDeny(sessionArgs[1], denyReqId, targetMachineId, {
|
|
642
642
|
json: hasFlag("--json")
|
|
@@ -672,7 +672,7 @@ async function handleSessionCommand() {
|
|
|
672
672
|
console.error("Usage: svamp session set-title <title>");
|
|
673
673
|
process.exit(1);
|
|
674
674
|
}
|
|
675
|
-
const { sessionSetTitle } = await import('./agentCommands-
|
|
675
|
+
const { sessionSetTitle } = await import('./agentCommands-CrfvZzCn.mjs');
|
|
676
676
|
await sessionSetTitle(title);
|
|
677
677
|
} else if (sessionSubcommand === "set-link") {
|
|
678
678
|
const url = sessionArgs[1];
|
|
@@ -681,7 +681,7 @@ async function handleSessionCommand() {
|
|
|
681
681
|
process.exit(1);
|
|
682
682
|
}
|
|
683
683
|
const label = sessionArgs[2] && !sessionArgs[2].startsWith("--") ? sessionArgs[2] : void 0;
|
|
684
|
-
const { sessionSetLink } = await import('./agentCommands-
|
|
684
|
+
const { sessionSetLink } = await import('./agentCommands-CrfvZzCn.mjs');
|
|
685
685
|
await sessionSetLink(url, label);
|
|
686
686
|
} else if (sessionSubcommand === "notify") {
|
|
687
687
|
const message = sessionArgs[1];
|
|
@@ -690,7 +690,7 @@ async function handleSessionCommand() {
|
|
|
690
690
|
process.exit(1);
|
|
691
691
|
}
|
|
692
692
|
const level = parseFlagStr("--level") || "info";
|
|
693
|
-
const { sessionNotify } = await import('./agentCommands-
|
|
693
|
+
const { sessionNotify } = await import('./agentCommands-CrfvZzCn.mjs');
|
|
694
694
|
await sessionNotify(message, level);
|
|
695
695
|
} else if (sessionSubcommand === "broadcast") {
|
|
696
696
|
const action = sessionArgs[1];
|
|
@@ -698,7 +698,7 @@ async function handleSessionCommand() {
|
|
|
698
698
|
console.error("Usage: svamp session broadcast <action> [args...]\nActions: open-canvas <url> [label], close-canvas, toast <message>");
|
|
699
699
|
process.exit(1);
|
|
700
700
|
}
|
|
701
|
-
const { sessionBroadcast } = await import('./agentCommands-
|
|
701
|
+
const { sessionBroadcast } = await import('./agentCommands-CrfvZzCn.mjs');
|
|
702
702
|
await sessionBroadcast(action, sessionArgs.slice(2).filter((a) => !a.startsWith("--")));
|
|
703
703
|
} else if (sessionSubcommand === "inbox") {
|
|
704
704
|
const inboxSubcmd = sessionArgs[1];
|
|
@@ -709,7 +709,7 @@ async function handleSessionCommand() {
|
|
|
709
709
|
process.exit(1);
|
|
710
710
|
}
|
|
711
711
|
if (agentSessionId) {
|
|
712
|
-
const { inboxSend } = await import('./agentCommands-
|
|
712
|
+
const { inboxSend } = await import('./agentCommands-CrfvZzCn.mjs');
|
|
713
713
|
await inboxSend(sessionArgs[2], {
|
|
714
714
|
body: sessionArgs[3],
|
|
715
715
|
subject: parseFlagStr("--subject"),
|
|
@@ -724,7 +724,7 @@ async function handleSessionCommand() {
|
|
|
724
724
|
}
|
|
725
725
|
} else if (inboxSubcmd === "list" || inboxSubcmd === "ls") {
|
|
726
726
|
if (agentSessionId && !sessionArgs[2]) {
|
|
727
|
-
const { inboxList } = await import('./agentCommands-
|
|
727
|
+
const { inboxList } = await import('./agentCommands-CrfvZzCn.mjs');
|
|
728
728
|
await inboxList({
|
|
729
729
|
unread: hasFlag("--unread"),
|
|
730
730
|
limit: parseFlagInt("--limit"),
|
|
@@ -746,7 +746,7 @@ async function handleSessionCommand() {
|
|
|
746
746
|
process.exit(1);
|
|
747
747
|
}
|
|
748
748
|
if (agentSessionId && !sessionArgs[3]) {
|
|
749
|
-
const { inboxList } = await import('./agentCommands-
|
|
749
|
+
const { inboxList } = await import('./agentCommands-CrfvZzCn.mjs');
|
|
750
750
|
await sessionInboxRead(agentSessionId, sessionArgs[2], targetMachineId);
|
|
751
751
|
} else if (sessionArgs[3]) {
|
|
752
752
|
await sessionInboxRead(sessionArgs[2], sessionArgs[3], targetMachineId);
|
|
@@ -756,7 +756,7 @@ async function handleSessionCommand() {
|
|
|
756
756
|
}
|
|
757
757
|
} else if (inboxSubcmd === "reply") {
|
|
758
758
|
if (agentSessionId && sessionArgs[2] && sessionArgs[3] && !sessionArgs[4]) {
|
|
759
|
-
const { inboxReply } = await import('./agentCommands-
|
|
759
|
+
const { inboxReply } = await import('./agentCommands-CrfvZzCn.mjs');
|
|
760
760
|
await inboxReply(sessionArgs[2], sessionArgs[3]);
|
|
761
761
|
} else if (sessionArgs[2] && sessionArgs[3] && sessionArgs[4]) {
|
|
762
762
|
await sessionInboxReply(sessionArgs[2], sessionArgs[3], sessionArgs[4], targetMachineId);
|
|
@@ -792,7 +792,7 @@ async function handleMachineCommand() {
|
|
|
792
792
|
return;
|
|
793
793
|
}
|
|
794
794
|
if (machineSubcommand === "share") {
|
|
795
|
-
const { machineShare } = await import('./commands-
|
|
795
|
+
const { machineShare } = await import('./commands-h1lFrJKK.mjs');
|
|
796
796
|
let machineId;
|
|
797
797
|
const shareArgs = [];
|
|
798
798
|
for (let i = 1; i < machineArgs.length; i++) {
|
|
@@ -822,7 +822,7 @@ async function handleMachineCommand() {
|
|
|
822
822
|
}
|
|
823
823
|
await machineShare(machineId, { add, remove, list, configPath, showConfig });
|
|
824
824
|
} else if (machineSubcommand === "exec") {
|
|
825
|
-
const { machineExec } = await import('./commands-
|
|
825
|
+
const { machineExec } = await import('./commands-h1lFrJKK.mjs');
|
|
826
826
|
let machineId;
|
|
827
827
|
let cwd;
|
|
828
828
|
const cmdParts = [];
|
|
@@ -842,7 +842,7 @@ async function handleMachineCommand() {
|
|
|
842
842
|
}
|
|
843
843
|
await machineExec(machineId, command, cwd);
|
|
844
844
|
} else if (machineSubcommand === "info") {
|
|
845
|
-
const { machineInfo } = await import('./commands-
|
|
845
|
+
const { machineInfo } = await import('./commands-h1lFrJKK.mjs');
|
|
846
846
|
let machineId;
|
|
847
847
|
for (let i = 1; i < machineArgs.length; i++) {
|
|
848
848
|
if ((machineArgs[i] === "--machine" || machineArgs[i] === "-m") && i + 1 < machineArgs.length) {
|
|
@@ -862,10 +862,10 @@ async function handleMachineCommand() {
|
|
|
862
862
|
level = machineArgs[++i];
|
|
863
863
|
}
|
|
864
864
|
}
|
|
865
|
-
const { machineNotify } = await import('./agentCommands-
|
|
865
|
+
const { machineNotify } = await import('./agentCommands-CrfvZzCn.mjs');
|
|
866
866
|
await machineNotify(message, level);
|
|
867
867
|
} else if (machineSubcommand === "ls") {
|
|
868
|
-
const { machineLs } = await import('./commands-
|
|
868
|
+
const { machineLs } = await import('./commands-h1lFrJKK.mjs');
|
|
869
869
|
let machineId;
|
|
870
870
|
let showHidden = false;
|
|
871
871
|
let path;
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { writeFileSync, readFileSync } from 'fs';
|
|
2
2
|
import { resolve } from 'path';
|
|
3
|
-
import { connectAndGetMachine } from './commands-
|
|
3
|
+
import { connectAndGetMachine } from './commands-h1lFrJKK.mjs';
|
|
4
4
|
import 'node:fs';
|
|
5
5
|
import 'node:child_process';
|
|
6
6
|
import 'node:path';
|
|
7
7
|
import 'node:os';
|
|
8
|
-
import './run-
|
|
8
|
+
import './run-IDo93bqK.mjs';
|
|
9
9
|
import 'os';
|
|
10
10
|
import 'fs/promises';
|
|
11
11
|
import 'url';
|
|
@@ -2,7 +2,7 @@ import { existsSync, readFileSync } from 'node:fs';
|
|
|
2
2
|
import { execSync } from 'node:child_process';
|
|
3
3
|
import { resolve, join } from 'node:path';
|
|
4
4
|
import os from 'node:os';
|
|
5
|
-
import { l as loadSecurityContextConfig, e as resolveSecurityContext, f as buildSecurityContextFromFlags, m as mergeSecurityContexts, c as connectToHypha } from './run-
|
|
5
|
+
import { l as loadSecurityContextConfig, e as resolveSecurityContext, f as buildSecurityContextFromFlags, m as mergeSecurityContexts, c as connectToHypha } from './run-IDo93bqK.mjs';
|
|
6
6
|
import 'os';
|
|
7
7
|
import 'fs/promises';
|
|
8
8
|
import 'fs';
|
package/dist/index.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { c as connectToHypha, d as daemonStatus, g as getHyphaServerUrl, r as registerMachineService, a as registerSessionService, s as startDaemon, b as stopDaemon } from './run-
|
|
1
|
+
export { c as connectToHypha, d as daemonStatus, g as getHyphaServerUrl, r as registerMachineService, a as registerSessionService, s as startDaemon, b as stopDaemon } from './run-IDo93bqK.mjs';
|
|
2
2
|
import 'os';
|
|
3
3
|
import 'fs/promises';
|
|
4
4
|
import 'fs';
|
|
@@ -6,7 +6,7 @@ import { fileURLToPath } from 'url';
|
|
|
6
6
|
import { spawn as spawn$1 } from 'child_process';
|
|
7
7
|
import { randomUUID as randomUUID$1 } from 'crypto';
|
|
8
8
|
import { existsSync, readFileSync, writeFileSync as writeFileSync$1, mkdirSync as mkdirSync$1, appendFileSync } from 'node:fs';
|
|
9
|
-
import { randomUUID } from 'node:crypto';
|
|
9
|
+
import { randomUUID, createHash } from 'node:crypto';
|
|
10
10
|
import { join as join$1 } from 'node:path';
|
|
11
11
|
import { spawn, execSync, execFile } from 'node:child_process';
|
|
12
12
|
import { ndJsonStream, ClientSideConnection } from '@agentclientprotocol/sdk';
|
|
@@ -718,6 +718,7 @@ async function registerMachineService(server, machineId, metadata, daemonState,
|
|
|
718
718
|
if (newSharing.enabled && !newSharing.owner && context?.user?.email) {
|
|
719
719
|
newSharing = { ...newSharing, owner: context.user.email };
|
|
720
720
|
}
|
|
721
|
+
const oldSharing = currentMetadata.sharing;
|
|
721
722
|
currentMetadata = { ...currentMetadata, sharing: newSharing };
|
|
722
723
|
metadataVersion++;
|
|
723
724
|
savePersistedMachineMetadata(metadata.svampHomeDir, {
|
|
@@ -730,6 +731,20 @@ async function registerMachineService(server, machineId, metadata, daemonState,
|
|
|
730
731
|
machineId,
|
|
731
732
|
metadata: { value: currentMetadata, version: metadataVersion }
|
|
732
733
|
});
|
|
734
|
+
handlers.sharingNotificationSync?.syncSharing(
|
|
735
|
+
`machine-${machineId}`,
|
|
736
|
+
oldSharing,
|
|
737
|
+
newSharing,
|
|
738
|
+
{
|
|
739
|
+
machineId,
|
|
740
|
+
machineServiceId: `${server.config.workspace}/${server.config.client_id}:default`,
|
|
741
|
+
ownerWorkspace: server.config.workspace,
|
|
742
|
+
ownerEmail: newSharing.owner || "",
|
|
743
|
+
label: currentMetadata.displayName || machineId,
|
|
744
|
+
shareType: "machine"
|
|
745
|
+
}
|
|
746
|
+
).catch(() => {
|
|
747
|
+
});
|
|
733
748
|
return { success: true, sharing: newSharing };
|
|
734
749
|
},
|
|
735
750
|
// Get security context config
|
|
@@ -2013,7 +2028,7 @@ async function registerDebugService(server, machineId, deps) {
|
|
|
2013
2028
|
};
|
|
2014
2029
|
}
|
|
2015
2030
|
|
|
2016
|
-
const COLLECTION_ALIAS = "svamp-agent-sessions";
|
|
2031
|
+
const COLLECTION_ALIAS$1 = "svamp-agent-sessions";
|
|
2017
2032
|
class SessionArtifactSync {
|
|
2018
2033
|
server;
|
|
2019
2034
|
artifactManager = null;
|
|
@@ -2048,14 +2063,14 @@ class SessionArtifactSync {
|
|
|
2048
2063
|
async ensureCollection() {
|
|
2049
2064
|
try {
|
|
2050
2065
|
const existing = await this.artifactManager.read({
|
|
2051
|
-
artifact_id: COLLECTION_ALIAS,
|
|
2066
|
+
artifact_id: COLLECTION_ALIAS$1,
|
|
2052
2067
|
_rkwargs: true
|
|
2053
2068
|
});
|
|
2054
2069
|
this.collectionId = existing.id;
|
|
2055
2070
|
this.log(`[ARTIFACT SYNC] Found existing collection: ${this.collectionId}`);
|
|
2056
2071
|
} catch {
|
|
2057
2072
|
const collection = await this.artifactManager.create({
|
|
2058
|
-
alias: COLLECTION_ALIAS,
|
|
2073
|
+
alias: COLLECTION_ALIAS$1,
|
|
2059
2074
|
type: "collection",
|
|
2060
2075
|
manifest: {
|
|
2061
2076
|
name: "Svamp Agent Sessions",
|
|
@@ -2334,6 +2349,170 @@ class SessionArtifactSync {
|
|
|
2334
2349
|
}
|
|
2335
2350
|
}
|
|
2336
2351
|
|
|
2352
|
+
const COLLECTION_ALIAS = "svamp-shared-sessions";
|
|
2353
|
+
function emailHash(email) {
|
|
2354
|
+
return createHash("sha256").update(email.toLowerCase()).digest("hex").slice(0, 12);
|
|
2355
|
+
}
|
|
2356
|
+
function notificationAlias(sessionId, recipientEmail) {
|
|
2357
|
+
return `share-${sessionId.slice(0, 8)}-${emailHash(recipientEmail)}`;
|
|
2358
|
+
}
|
|
2359
|
+
class SharingNotificationSync {
|
|
2360
|
+
server;
|
|
2361
|
+
artifactManager = null;
|
|
2362
|
+
collectionId = null;
|
|
2363
|
+
initialized = false;
|
|
2364
|
+
log;
|
|
2365
|
+
constructor(server, log) {
|
|
2366
|
+
this.server = server;
|
|
2367
|
+
this.log = log;
|
|
2368
|
+
}
|
|
2369
|
+
async init() {
|
|
2370
|
+
try {
|
|
2371
|
+
this.artifactManager = await this.server.getService("public/artifact-manager");
|
|
2372
|
+
if (!this.artifactManager) {
|
|
2373
|
+
this.log("[SHARING NOTIFY] Artifact manager not available");
|
|
2374
|
+
return;
|
|
2375
|
+
}
|
|
2376
|
+
await this.ensureCollection();
|
|
2377
|
+
this.initialized = true;
|
|
2378
|
+
this.log("[SHARING NOTIFY] Initialized");
|
|
2379
|
+
} catch (err) {
|
|
2380
|
+
this.log(`[SHARING NOTIFY] Init failed: ${err.message}`);
|
|
2381
|
+
}
|
|
2382
|
+
}
|
|
2383
|
+
async ensureCollection() {
|
|
2384
|
+
try {
|
|
2385
|
+
const existing = await this.artifactManager.read({
|
|
2386
|
+
artifact_id: COLLECTION_ALIAS,
|
|
2387
|
+
_rkwargs: true
|
|
2388
|
+
});
|
|
2389
|
+
this.collectionId = existing.id;
|
|
2390
|
+
} catch {
|
|
2391
|
+
const collection = await this.artifactManager.create({
|
|
2392
|
+
alias: COLLECTION_ALIAS,
|
|
2393
|
+
type: "collection",
|
|
2394
|
+
manifest: {
|
|
2395
|
+
name: "Svamp Shared Sessions",
|
|
2396
|
+
description: "Cross-workspace share notifications for session/machine bookmarks"
|
|
2397
|
+
},
|
|
2398
|
+
config: {
|
|
2399
|
+
permissions: { "*": "r", "@": "rw+" }
|
|
2400
|
+
},
|
|
2401
|
+
_rkwargs: true
|
|
2402
|
+
});
|
|
2403
|
+
this.collectionId = collection.id;
|
|
2404
|
+
await this.artifactManager.commit({
|
|
2405
|
+
artifact_id: this.collectionId,
|
|
2406
|
+
_rkwargs: true
|
|
2407
|
+
});
|
|
2408
|
+
this.log(`[SHARING NOTIFY] Created collection: ${this.collectionId}`);
|
|
2409
|
+
}
|
|
2410
|
+
}
|
|
2411
|
+
/**
|
|
2412
|
+
* Publish a share notification for a recipient.
|
|
2413
|
+
* Idempotent — uses deterministic alias, so re-sharing updates the existing artifact.
|
|
2414
|
+
*/
|
|
2415
|
+
async notifyShare(params) {
|
|
2416
|
+
if (!this.initialized || !this.collectionId) return;
|
|
2417
|
+
const alias = notificationAlias(params.sessionId, params.recipientEmail);
|
|
2418
|
+
const manifest = {
|
|
2419
|
+
recipientEmail: params.recipientEmail.toLowerCase(),
|
|
2420
|
+
sessionId: params.sessionId,
|
|
2421
|
+
machineId: params.machineId,
|
|
2422
|
+
machineServiceId: params.machineServiceId,
|
|
2423
|
+
ownerWorkspace: params.ownerWorkspace,
|
|
2424
|
+
ownerEmail: params.ownerEmail,
|
|
2425
|
+
label: params.label || "",
|
|
2426
|
+
role: params.role,
|
|
2427
|
+
sharedAt: Date.now(),
|
|
2428
|
+
shareType: params.shareType || "session"
|
|
2429
|
+
};
|
|
2430
|
+
try {
|
|
2431
|
+
const existing = await this.artifactManager.read({
|
|
2432
|
+
artifact_id: alias,
|
|
2433
|
+
parent_id: this.collectionId,
|
|
2434
|
+
_rkwargs: true
|
|
2435
|
+
});
|
|
2436
|
+
await this.artifactManager.edit({
|
|
2437
|
+
artifact_id: existing.id,
|
|
2438
|
+
manifest,
|
|
2439
|
+
_rkwargs: true
|
|
2440
|
+
});
|
|
2441
|
+
await this.artifactManager.commit({
|
|
2442
|
+
artifact_id: existing.id,
|
|
2443
|
+
_rkwargs: true
|
|
2444
|
+
});
|
|
2445
|
+
} catch {
|
|
2446
|
+
try {
|
|
2447
|
+
const artifact = await this.artifactManager.create({
|
|
2448
|
+
alias,
|
|
2449
|
+
parent_id: this.collectionId,
|
|
2450
|
+
type: "share-notification",
|
|
2451
|
+
manifest,
|
|
2452
|
+
_rkwargs: true
|
|
2453
|
+
});
|
|
2454
|
+
await this.artifactManager.commit({
|
|
2455
|
+
artifact_id: artifact.id,
|
|
2456
|
+
_rkwargs: true
|
|
2457
|
+
});
|
|
2458
|
+
} catch (createErr) {
|
|
2459
|
+
this.log(`[SHARING NOTIFY] Failed to create notification for ${params.recipientEmail}: ${createErr.message}`);
|
|
2460
|
+
return;
|
|
2461
|
+
}
|
|
2462
|
+
}
|
|
2463
|
+
this.log(`[SHARING NOTIFY] Notified ${params.recipientEmail} about ${params.shareType || "session"} ${params.sessionId.slice(0, 8)}`);
|
|
2464
|
+
}
|
|
2465
|
+
/**
|
|
2466
|
+
* Remove a share notification when a user is unshared.
|
|
2467
|
+
*/
|
|
2468
|
+
async removeNotification(sessionId, recipientEmail) {
|
|
2469
|
+
if (!this.initialized || !this.collectionId) return;
|
|
2470
|
+
const alias = notificationAlias(sessionId, recipientEmail);
|
|
2471
|
+
try {
|
|
2472
|
+
const existing = await this.artifactManager.read({
|
|
2473
|
+
artifact_id: alias,
|
|
2474
|
+
parent_id: this.collectionId,
|
|
2475
|
+
_rkwargs: true
|
|
2476
|
+
});
|
|
2477
|
+
await this.artifactManager.delete({
|
|
2478
|
+
artifact_id: existing.id,
|
|
2479
|
+
_rkwargs: true
|
|
2480
|
+
});
|
|
2481
|
+
this.log(`[SHARING NOTIFY] Removed notification for ${recipientEmail} on ${sessionId.slice(0, 8)}`);
|
|
2482
|
+
} catch {
|
|
2483
|
+
}
|
|
2484
|
+
}
|
|
2485
|
+
/**
|
|
2486
|
+
* Sync all sharing notifications for a session based on its current sharing config.
|
|
2487
|
+
* Adds notifications for new users, removes for removed users.
|
|
2488
|
+
*/
|
|
2489
|
+
async syncSharing(sessionId, oldSharing, newSharing, context) {
|
|
2490
|
+
if (!this.initialized) return;
|
|
2491
|
+
const oldEmails = new Set(
|
|
2492
|
+
(oldSharing?.allowedUsers || []).map((u) => u.email.toLowerCase())
|
|
2493
|
+
);
|
|
2494
|
+
const newUsers = newSharing.allowedUsers || [];
|
|
2495
|
+
const newEmails = new Set(newUsers.map((u) => u.email.toLowerCase()));
|
|
2496
|
+
for (const user of newUsers) {
|
|
2497
|
+
if (!oldEmails.has(user.email.toLowerCase())) {
|
|
2498
|
+
this.notifyShare({
|
|
2499
|
+
recipientEmail: user.email,
|
|
2500
|
+
sessionId,
|
|
2501
|
+
role: user.role,
|
|
2502
|
+
...context
|
|
2503
|
+
}).catch(() => {
|
|
2504
|
+
});
|
|
2505
|
+
}
|
|
2506
|
+
}
|
|
2507
|
+
for (const email of oldEmails) {
|
|
2508
|
+
if (!newEmails.has(email)) {
|
|
2509
|
+
this.removeNotification(sessionId, email).catch(() => {
|
|
2510
|
+
});
|
|
2511
|
+
}
|
|
2512
|
+
}
|
|
2513
|
+
}
|
|
2514
|
+
}
|
|
2515
|
+
|
|
2337
2516
|
const DEFAULT_TIMEOUTS = {
|
|
2338
2517
|
init: 6e4,
|
|
2339
2518
|
toolCall: 12e4,
|
|
@@ -7128,6 +7307,7 @@ The automated loop has finished. Review the progress above and let me know if yo
|
|
|
7128
7307
|
},
|
|
7129
7308
|
onSharingUpdate: (newSharing) => {
|
|
7130
7309
|
logger.log(`[Session ${sessionId}] Sharing config updated \u2014 persisting to disk`);
|
|
7310
|
+
const oldSharing = sessionMetadata.sharing;
|
|
7131
7311
|
sessionMetadata = { ...sessionMetadata, sharing: newSharing };
|
|
7132
7312
|
if (!trackedSession.stopped) {
|
|
7133
7313
|
saveSession({
|
|
@@ -7142,6 +7322,17 @@ The automated loop has finished. Review the progress above and let me know if yo
|
|
|
7142
7322
|
wasProcessing: sessionWasProcessing
|
|
7143
7323
|
});
|
|
7144
7324
|
}
|
|
7325
|
+
const ownerWorkspace = server.config.workspace;
|
|
7326
|
+
const machineServiceId = `${ownerWorkspace}/${server.config.client_id}:default`;
|
|
7327
|
+
sharingNotificationSync.syncSharing(sessionId, oldSharing, newSharing, {
|
|
7328
|
+
machineId,
|
|
7329
|
+
machineServiceId,
|
|
7330
|
+
ownerWorkspace,
|
|
7331
|
+
ownerEmail: newSharing.owner || "",
|
|
7332
|
+
label: sessionMetadata.summary?.text || "",
|
|
7333
|
+
shareType: "session"
|
|
7334
|
+
}).catch(() => {
|
|
7335
|
+
});
|
|
7145
7336
|
},
|
|
7146
7337
|
onApplySystemPrompt: async (prompt) => {
|
|
7147
7338
|
logger.log(`[Session ${sessionId}] System prompt update requested \u2014 restarting agent`);
|
|
@@ -8065,6 +8256,9 @@ The automated loop has finished. Review the progress above and let me know if yo
|
|
|
8065
8256
|
pid: process.pid,
|
|
8066
8257
|
startedAt: Date.now()
|
|
8067
8258
|
};
|
|
8259
|
+
const sharingNotificationSync = new SharingNotificationSync(server, logger.log);
|
|
8260
|
+
sharingNotificationSync.init().catch(() => {
|
|
8261
|
+
});
|
|
8068
8262
|
const machineService = await registerMachineService(
|
|
8069
8263
|
server,
|
|
8070
8264
|
machineId,
|
|
@@ -8097,7 +8291,8 @@ The automated loop has finished. Review the progress above and let me know if yo
|
|
|
8097
8291
|
},
|
|
8098
8292
|
supervisor,
|
|
8099
8293
|
tunnels,
|
|
8100
|
-
serveManager
|
|
8294
|
+
serveManager,
|
|
8295
|
+
sharingNotificationSync
|
|
8101
8296
|
}
|
|
8102
8297
|
);
|
|
8103
8298
|
logger.log(`Machine service registered: svamp-machine-${machineId}`);
|
|
@@ -2,7 +2,7 @@ import{createRequire as _pkgrollCR}from"node:module";const require=_pkgrollCR(im
|
|
|
2
2
|
import os from 'node:os';
|
|
3
3
|
import { join, resolve } from 'node:path';
|
|
4
4
|
import { mkdirSync, writeFileSync, existsSync, unlinkSync, readFileSync, watch } from 'node:fs';
|
|
5
|
-
import { c as connectToHypha, a as registerSessionService } from './run-
|
|
5
|
+
import { c as connectToHypha, a as registerSessionService } from './run-IDo93bqK.mjs';
|
|
6
6
|
import { createServer } from 'node:http';
|
|
7
7
|
import { spawn } from 'node:child_process';
|
|
8
8
|
import { createInterface } from 'node:readline';
|
|
@@ -52,7 +52,7 @@ async function handleServeCommand() {
|
|
|
52
52
|
}
|
|
53
53
|
}
|
|
54
54
|
async function serveAdd(args, machineId) {
|
|
55
|
-
const { connectAndGetMachine } = await import('./commands-
|
|
55
|
+
const { connectAndGetMachine } = await import('./commands-h1lFrJKK.mjs');
|
|
56
56
|
const pos = positionalArgs(args);
|
|
57
57
|
const name = pos[0];
|
|
58
58
|
if (!name) {
|
|
@@ -84,7 +84,7 @@ async function serveAdd(args, machineId) {
|
|
|
84
84
|
}
|
|
85
85
|
}
|
|
86
86
|
async function serveRemove(args, machineId) {
|
|
87
|
-
const { connectAndGetMachine } = await import('./commands-
|
|
87
|
+
const { connectAndGetMachine } = await import('./commands-h1lFrJKK.mjs');
|
|
88
88
|
const pos = positionalArgs(args);
|
|
89
89
|
const name = pos[0];
|
|
90
90
|
if (!name) {
|
|
@@ -104,7 +104,7 @@ async function serveRemove(args, machineId) {
|
|
|
104
104
|
}
|
|
105
105
|
}
|
|
106
106
|
async function serveList(args, machineId) {
|
|
107
|
-
const { connectAndGetMachine } = await import('./commands-
|
|
107
|
+
const { connectAndGetMachine } = await import('./commands-h1lFrJKK.mjs');
|
|
108
108
|
const all = hasFlag(args, "--all", "-a");
|
|
109
109
|
const json = hasFlag(args, "--json");
|
|
110
110
|
const sessionId = getFlag(args, "--session");
|
|
@@ -137,7 +137,7 @@ async function serveList(args, machineId) {
|
|
|
137
137
|
}
|
|
138
138
|
}
|
|
139
139
|
async function serveInfo(machineId) {
|
|
140
|
-
const { connectAndGetMachine } = await import('./commands-
|
|
140
|
+
const { connectAndGetMachine } = await import('./commands-h1lFrJKK.mjs');
|
|
141
141
|
const { machine, server } = await connectAndGetMachine(machineId);
|
|
142
142
|
try {
|
|
143
143
|
const info = await machine.serveInfo({ _rkwargs: true });
|