svamp-cli 0.2.7 → 0.2.8

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.
@@ -0,0 +1,191 @@
1
+ import * as path from 'path';
2
+
3
+ function getFlag(args, flag) {
4
+ const idx = args.indexOf(flag);
5
+ return idx !== -1 && idx + 1 < args.length ? args[idx + 1] : void 0;
6
+ }
7
+ function hasFlag(args, ...flags) {
8
+ return flags.some((f) => args.includes(f));
9
+ }
10
+ function positionalArgs(args) {
11
+ const result = [];
12
+ for (let i = 0; i < args.length; i++) {
13
+ if (args[i].startsWith("-")) {
14
+ if (!args[i].startsWith("--no-") && i + 1 < args.length && !args[i + 1].startsWith("-")) {
15
+ i++;
16
+ }
17
+ continue;
18
+ }
19
+ result.push(args[i]);
20
+ }
21
+ return result;
22
+ }
23
+ async function handleServeCommand() {
24
+ const args = process.argv.slice(3);
25
+ const sub = args[0];
26
+ let machineId;
27
+ const mIdx = args.findIndex((a) => a === "--machine" || a === "-m");
28
+ if (mIdx !== -1 && mIdx + 1 < args.length) {
29
+ machineId = args[mIdx + 1];
30
+ }
31
+ const filteredArgs = args.filter((_a, i) => {
32
+ if (args[i] === "--machine" || args[i] === "-m") return false;
33
+ if (i > 0 && (args[i - 1] === "--machine" || args[i - 1] === "-m")) return false;
34
+ return true;
35
+ });
36
+ if (sub === "--help" || sub === "-h") {
37
+ printServeHelp();
38
+ return;
39
+ }
40
+ if (sub === "remove" || sub === "rm") {
41
+ await serveRemove(filteredArgs.slice(1), machineId);
42
+ } else if (sub === "list" || sub === "ls") {
43
+ await serveList(filteredArgs.slice(1), machineId);
44
+ } else if (sub === "info") {
45
+ await serveInfo(machineId);
46
+ } else if (sub === "add") {
47
+ await serveAdd(filteredArgs.slice(1), machineId);
48
+ } else if (sub && !sub.startsWith("-")) {
49
+ await serveAdd(filteredArgs, machineId);
50
+ } else {
51
+ printServeHelp();
52
+ }
53
+ }
54
+ async function serveAdd(args, machineId) {
55
+ const { connectAndGetMachine } = await import('./commands-DXaH6BQg.mjs');
56
+ const pos = positionalArgs(args);
57
+ const name = pos[0];
58
+ if (!name) {
59
+ console.error("Usage: svamp serve [add] <name> [directory] [--public | --access email1,email2]");
60
+ process.exit(1);
61
+ }
62
+ const directory = path.resolve(pos[1] || ".");
63
+ let access = "owner";
64
+ if (hasFlag(args, "--public")) {
65
+ access = "public";
66
+ } else {
67
+ const accessFlag = getFlag(args, "--access");
68
+ if (accessFlag) {
69
+ access = accessFlag.split(",").map((e) => e.trim()).filter(Boolean);
70
+ }
71
+ }
72
+ const { machine, server } = await connectAndGetMachine(machineId);
73
+ try {
74
+ const result = await machine.serveAdd({ name, directory, access, _rkwargs: true });
75
+ console.log(`Mount added: ${name} \u2192 ${directory}`);
76
+ console.log(`Access: ${access === "public" ? "public" : access === "owner" ? "owner only" : access.join(", ")}`);
77
+ console.log(`URL: ${result.url}`);
78
+ } catch (err) {
79
+ console.error(`Error: ${err.message || err}`);
80
+ process.exit(1);
81
+ } finally {
82
+ await server.disconnect().catch(() => {
83
+ });
84
+ }
85
+ }
86
+ async function serveRemove(args, machineId) {
87
+ const { connectAndGetMachine } = await import('./commands-DXaH6BQg.mjs');
88
+ const pos = positionalArgs(args);
89
+ const name = pos[0];
90
+ if (!name) {
91
+ console.error("Usage: svamp serve remove <name>");
92
+ process.exit(1);
93
+ }
94
+ const { machine, server } = await connectAndGetMachine(machineId);
95
+ try {
96
+ await machine.serveRemove({ name, _rkwargs: true });
97
+ console.log(`Mount '${name}' removed.`);
98
+ } catch (err) {
99
+ console.error(`Error: ${err.message || err}`);
100
+ process.exit(1);
101
+ } finally {
102
+ await server.disconnect().catch(() => {
103
+ });
104
+ }
105
+ }
106
+ async function serveList(args, machineId) {
107
+ const { connectAndGetMachine } = await import('./commands-DXaH6BQg.mjs');
108
+ const all = hasFlag(args, "--all", "-a");
109
+ const json = hasFlag(args, "--json");
110
+ const sessionId = getFlag(args, "--session");
111
+ const { machine, server } = await connectAndGetMachine(machineId);
112
+ try {
113
+ const mounts = await machine.serveList({ sessionId, all, _rkwargs: true });
114
+ if (json) {
115
+ console.log(JSON.stringify(mounts, null, 2));
116
+ } else if (mounts.length === 0) {
117
+ console.log(all ? "No mounts registered." : "No mounts for this session. Use --all to see all mounts.");
118
+ } else {
119
+ const label = all ? "All mounts" : `Mounts${sessionId ? ` (session ${sessionId.slice(0, 8)})` : ""}`;
120
+ console.log(`${label}:
121
+ `);
122
+ for (const m of mounts) {
123
+ const session = m.sessionId ? m.sessionId.slice(0, 8) : "-";
124
+ console.log(` ${m.name}`);
125
+ console.log(` Directory: ${m.directory}`);
126
+ console.log(` Session: ${session}`);
127
+ console.log(` Added: ${new Date(m.addedAt).toISOString().slice(0, 16).replace("T", " ")}`);
128
+ console.log("");
129
+ }
130
+ }
131
+ } catch (err) {
132
+ console.error(`Error: ${err.message || err}`);
133
+ process.exit(1);
134
+ } finally {
135
+ await server.disconnect().catch(() => {
136
+ });
137
+ }
138
+ }
139
+ async function serveInfo(machineId) {
140
+ const { connectAndGetMachine } = await import('./commands-DXaH6BQg.mjs');
141
+ const { machine, server } = await connectAndGetMachine(machineId);
142
+ try {
143
+ const info = await machine.serveInfo({ _rkwargs: true });
144
+ console.log(`Static file server:`);
145
+ console.log(` Status: ${info.running ? "running" : "stopped"}`);
146
+ console.log(` Port: ${info.port || "-"}`);
147
+ console.log(` URL: ${info.url || "(not exposed)"}`);
148
+ console.log(` Mounts: ${info.mountCount}`);
149
+ } catch (err) {
150
+ console.error(`Error: ${err.message || err}`);
151
+ process.exit(1);
152
+ } finally {
153
+ await server.disconnect().catch(() => {
154
+ });
155
+ }
156
+ }
157
+ function printServeHelp() {
158
+ console.log(`
159
+ svamp serve \u2014 Shared static file server
160
+
161
+ Serve local directories via a single daemon-managed HTTP server with one public URL.
162
+ Multiple sessions can register different mount points without port conflicts.
163
+
164
+ Usage:
165
+ svamp serve <name> [directory] Add a mount and print its URL (dir defaults to .)
166
+ svamp serve add <name> [directory] Same as above
167
+ svamp serve remove <name> Remove a mount
168
+ svamp serve list [--all] [--json] List mounts (default: current session only)
169
+ svamp serve info Show server status and URL
170
+
171
+ Access control (default: owner only):
172
+ --public Allow anyone to access (no auth)
173
+ --access email1,email2 Allow specific users (comma-separated emails)
174
+ (no flag) Owner only \u2014 requires Hypha login
175
+
176
+ Options:
177
+ -m, --machine <id> Target a specific machine
178
+ --session <id> Filter by session ID
179
+ --all, -a Show mounts from all sessions
180
+ --json Output as JSON
181
+
182
+ Examples:
183
+ svamp serve my-report ./output # Owner-only (default)
184
+ svamp serve dashboard ./dist --public # Anyone can access
185
+ svamp serve data ./csv --access a@x.com,b@y.com # Specific users
186
+ svamp serve list --all # Show all mounts
187
+ svamp serve remove my-report # Stop serving
188
+ `);
189
+ }
190
+
191
+ export { handleServeCommand };