hypha-cli 0.1.7 → 0.1.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.
@@ -0,0 +1,283 @@
1
+ import { e as hasFlag, l as loginToHypha, c as connectToHypha, g as getFlagInt, i as getFlag, f as formatJson, a as formatTable, r as resolveServerUrl } from './helpers-DWQC3Lr8.mjs';
2
+ import 'fs';
3
+ import 'path';
4
+ import 'os';
5
+
6
+ async function getWorkspaceManager(server) {
7
+ return server.getService("public/*:workspace-manager");
8
+ }
9
+ async function loginCommand(args) {
10
+ if (hasFlag(args, "--help", "-h")) {
11
+ console.log(`Usage: hypha login [server-url]
12
+
13
+ Login to a Hypha server via browser-based OAuth.
14
+ Credentials are saved to ~/.hypha/.env.
15
+
16
+ Default server: https://hypha.aicell.io`);
17
+ return;
18
+ }
19
+ const serverUrl = args[0] && !args[0].startsWith("-") ? args[0] : void 0;
20
+ await loginToHypha(serverUrl);
21
+ }
22
+ async function tokenCommand(args) {
23
+ if (hasFlag(args, "--help", "-h")) {
24
+ console.log(`Usage: hypha token [options]
25
+
26
+ Generate a workspace token.
27
+
28
+ Options:
29
+ --expires-in <seconds> Token expiration (default: 3600)
30
+ --permission <perm> Permission level: read, read_write, admin (default: read_write)
31
+ --workspace <ws> Target workspace (default: current)
32
+ --json Output as JSON`);
33
+ return;
34
+ }
35
+ const server = await connectToHypha();
36
+ try {
37
+ const expiresIn = getFlagInt(args, "--expires-in") || 3600;
38
+ const permission = getFlag(args, "--permission") || "read_write";
39
+ const workspace = getFlag(args, "--workspace") || server.config.workspace;
40
+ const json = hasFlag(args, "--json");
41
+ const token = await server.generateToken({
42
+ expires_in: expiresIn,
43
+ permission,
44
+ workspace
45
+ });
46
+ if (json) {
47
+ console.log(formatJson({
48
+ token,
49
+ workspace,
50
+ permission,
51
+ expires_in: expiresIn
52
+ }));
53
+ } else {
54
+ console.log(token);
55
+ }
56
+ } finally {
57
+ await server.disconnect();
58
+ }
59
+ }
60
+ async function servicesCommand(args) {
61
+ if (hasFlag(args, "--help", "-h")) {
62
+ console.log(`Usage: hypha services [options]
63
+
64
+ List services in the current workspace.
65
+
66
+ Options:
67
+ --type <type> Filter by service type
68
+ --include-unlisted Include unlisted services
69
+ --json Output as JSON`);
70
+ return;
71
+ }
72
+ const server = await connectToHypha();
73
+ try {
74
+ const type = getFlag(args, "--type");
75
+ const includeUnlisted = hasFlag(args, "--include-unlisted");
76
+ const json = hasFlag(args, "--json");
77
+ const query = { _rkwargs: true };
78
+ if (type) query.type = type;
79
+ if (includeUnlisted) query.include_unlisted = true;
80
+ const services = await server.listServices(query);
81
+ if (json) {
82
+ console.log(formatJson(services));
83
+ return;
84
+ }
85
+ if (!services || services.length === 0) {
86
+ console.log("No services found.");
87
+ return;
88
+ }
89
+ const rows = [["ID", "NAME", "TYPE", "DESCRIPTION"]];
90
+ for (const svc of services) {
91
+ rows.push([
92
+ svc.id || "",
93
+ svc.name || "",
94
+ svc.type || "",
95
+ (svc.description || "").slice(0, 60)
96
+ ]);
97
+ }
98
+ console.log(formatTable(rows));
99
+ } finally {
100
+ await server.disconnect();
101
+ }
102
+ }
103
+ async function clientsCommand(args) {
104
+ if (hasFlag(args, "--help", "-h")) {
105
+ console.log(`Usage: hypha clients [workspace] [options]
106
+
107
+ List connected clients in a workspace. Defaults to the connected workspace.
108
+ Use a positional argument to target a different workspace (requires admin).
109
+
110
+ Options:
111
+ --json Output as JSON`);
112
+ return;
113
+ }
114
+ const server = await connectToHypha();
115
+ try {
116
+ const json = hasFlag(args, "--json");
117
+ const targetWs = args[0] && !args[0].startsWith("-") ? args[0] : server.config.workspace;
118
+ const wm = await getWorkspaceManager(server);
119
+ const clients = await wm.listClients({ workspace: targetWs, _rkwargs: true });
120
+ if (json) {
121
+ console.log(formatJson(clients));
122
+ return;
123
+ }
124
+ console.log(`${clients.length} client(s) in workspace ${targetWs}`);
125
+ if (clients.length === 0) return;
126
+ for (const c of clients.slice(0, 50)) {
127
+ console.log(` ${c}`);
128
+ }
129
+ if (clients.length > 50) {
130
+ console.log(` ... and ${clients.length - 50} more`);
131
+ }
132
+ } finally {
133
+ await server.disconnect();
134
+ }
135
+ }
136
+ async function pingCommand(args) {
137
+ if (hasFlag(args, "--help", "-h")) {
138
+ console.log(`Usage: hypha ping <client-id> [options]
139
+
140
+ Ping a specific client to check if it's alive.
141
+
142
+ Options:
143
+ --timeout <seconds> Ping timeout (default: 5)`);
144
+ return;
145
+ }
146
+ const clientId = args[0] && !args[0].startsWith("-") ? args[0] : void 0;
147
+ if (!clientId) {
148
+ console.error("Usage: hypha ping <client-id>");
149
+ process.exit(1);
150
+ }
151
+ const server = await connectToHypha();
152
+ try {
153
+ const timeout = getFlagInt(args, "--timeout") || 5;
154
+ const wm = await getWorkspaceManager(server);
155
+ try {
156
+ const result = await wm.pingClient({ client_id: clientId, timeout, _rkwargs: true });
157
+ console.log(`${clientId}: ${result}`);
158
+ } catch (e) {
159
+ console.log(`${clientId}: dead (${e.message || e})`);
160
+ }
161
+ } finally {
162
+ await server.disconnect();
163
+ }
164
+ }
165
+ async function kickCommand(args) {
166
+ if (hasFlag(args, "--help", "-h")) {
167
+ console.log(`Usage: hypha kick <client-id> [workspace]
168
+
169
+ Disconnect a client and remove all its services. Requires admin.
170
+ If workspace is not specified, uses the connected workspace.`);
171
+ return;
172
+ }
173
+ const clientId = args[0] && !args[0].startsWith("-") ? args[0] : void 0;
174
+ if (!clientId) {
175
+ console.error("Usage: hypha kick <client-id> [workspace]");
176
+ process.exit(1);
177
+ }
178
+ const server = await connectToHypha();
179
+ try {
180
+ const targetWs = args[1] && !args[1].startsWith("-") ? args[1] : server.config.workspace;
181
+ const wm = await getWorkspaceManager(server);
182
+ await wm.deleteClient({ client_id: clientId, workspace: targetWs, _rkwargs: true });
183
+ console.log(`Kicked client ${clientId} from ${targetWs}`);
184
+ } finally {
185
+ await server.disconnect();
186
+ }
187
+ }
188
+ async function cleanupCommand(args) {
189
+ if (hasFlag(args, "--help", "-h")) {
190
+ console.log(`Usage: hypha cleanup [workspace] [options]
191
+
192
+ Ping all clients in a workspace and remove dead/stale ones.
193
+ Requires admin permission.
194
+ Defaults to the connected workspace. Pass workspace name as positional arg.
195
+
196
+ Options:
197
+ --timeout <seconds> Ping timeout per client (default: 2)
198
+ --json Output as JSON`);
199
+ return;
200
+ }
201
+ const server = await connectToHypha();
202
+ try {
203
+ const timeout = getFlagInt(args, "--timeout") || 2;
204
+ const json = hasFlag(args, "--json");
205
+ const targetWs = args[0] && !args[0].startsWith("-") ? args[0] : server.config.workspace;
206
+ const wm = await getWorkspaceManager(server);
207
+ const clients = await wm.listClients({ workspace: targetWs, _rkwargs: true });
208
+ console.log(`Workspace ${targetWs}: ${clients.length} client(s)`);
209
+ console.log(`Pinging all clients (timeout=${timeout}s)... this may take a while.`);
210
+ const result = await wm.cleanup({ workspace: targetWs, timeout, _rkwargs: true });
211
+ const removed = result?.removed_clients || result?.removedClients || [];
212
+ if (json) {
213
+ console.log(formatJson(result));
214
+ } else {
215
+ console.log(`Removed ${removed.length} dead client(s).`);
216
+ if (removed.length > 0 && removed.length <= 30) {
217
+ for (const c of removed) {
218
+ console.log(` - ${c}`);
219
+ }
220
+ }
221
+ if (result?.removed_workspace || result?.removedWorkspace) {
222
+ console.log(`Workspace ${targetWs} was removed (no live clients remaining).`);
223
+ }
224
+ }
225
+ } finally {
226
+ await server.disconnect();
227
+ }
228
+ }
229
+ async function workspaceInfoCommand(args) {
230
+ if (hasFlag(args, "--help", "-h")) {
231
+ console.log(`Usage: hypha workspace-info [workspace] [--json]
232
+
233
+ Show detailed workspace information (admin).`);
234
+ return;
235
+ }
236
+ const server = await connectToHypha();
237
+ try {
238
+ const json = hasFlag(args, "--json");
239
+ const targetWs = args[0] && !args[0].startsWith("-") ? args[0] : server.config.workspace;
240
+ const wm = await getWorkspaceManager(server);
241
+ const wsInfo = await wm.getWorkspaceInfo({ workspace: targetWs, _rkwargs: true });
242
+ if (json) {
243
+ console.log(formatJson(wsInfo));
244
+ } else {
245
+ console.log(`Workspace: ${wsInfo.id || wsInfo.name || targetWs}`);
246
+ for (const [k, v] of Object.entries(wsInfo)) {
247
+ if (k === "id" || k === "name") continue;
248
+ const val = typeof v === "object" ? JSON.stringify(v) : String(v);
249
+ console.log(` ${k}: ${val.slice(0, 120)}`);
250
+ }
251
+ }
252
+ } finally {
253
+ await server.disconnect();
254
+ }
255
+ }
256
+ async function infoCommand(args) {
257
+ if (hasFlag(args, "--help", "-h")) {
258
+ console.log(`Usage: hypha info [--json]
259
+
260
+ Show connection information.`);
261
+ return;
262
+ }
263
+ const server = await connectToHypha();
264
+ try {
265
+ const json = hasFlag(args, "--json");
266
+ const info = {
267
+ server_url: server.config.public_base_url || resolveServerUrl(),
268
+ workspace: server.config.workspace,
269
+ client_id: server.config.client_id
270
+ };
271
+ if (json) {
272
+ console.log(formatJson(info));
273
+ } else {
274
+ console.log(`Server: ${info.server_url}`);
275
+ console.log(`Workspace: ${info.workspace}`);
276
+ console.log(`Client ID: ${info.client_id}`);
277
+ }
278
+ } finally {
279
+ await server.disconnect();
280
+ }
281
+ }
282
+
283
+ export { cleanupCommand, clientsCommand, infoCommand, kickCommand, loginCommand, pingCommand, servicesCommand, tokenCommand, workspaceInfoCommand };
@@ -1,4 +1,4 @@
1
- import { e as hasFlag, l as loginToHypha, c as connectToHypha, g as getFlagInt, i as getFlag, f as formatJson, a as formatTable } from './helpers-DWQC3Lr8.mjs';
1
+ import { e as hasFlag, l as loginToHypha, c as connectToHypha, g as getFlagInt, i as getFlag, f as formatJson, a as formatTable } from './helpers-BvfSCkvr.mjs';
2
2
  import 'fs';
3
3
  import 'path';
4
4
  import 'os';
@@ -38,7 +38,8 @@ Options:
38
38
  const token = await server.generateToken({
39
39
  expires_in: expiresIn,
40
40
  permission,
41
- workspace
41
+ workspace,
42
+ _rkwargs: true
42
43
  });
43
44
  if (json) {
44
45
  console.log(formatJson({
@@ -0,0 +1,284 @@
1
+ import { e as hasFlag, l as loginToHypha, c as connectToHypha, g as getFlagInt, i as getFlag, f as formatJson, a as formatTable, r as resolveServerUrl } from './helpers-DWQC3Lr8.mjs';
2
+ import 'fs';
3
+ import 'path';
4
+ import 'os';
5
+
6
+ async function loginCommand(args) {
7
+ if (hasFlag(args, "--help", "-h")) {
8
+ console.log(`Usage: hypha login [server-url]
9
+
10
+ Login to a Hypha server via browser-based OAuth.
11
+ Credentials are saved to ~/.hypha/.env.
12
+
13
+ Default server: https://hypha.aicell.io`);
14
+ return;
15
+ }
16
+ const serverUrl = args[0] && !args[0].startsWith("-") ? args[0] : void 0;
17
+ await loginToHypha(serverUrl);
18
+ }
19
+ async function tokenCommand(args) {
20
+ if (hasFlag(args, "--help", "-h")) {
21
+ console.log(`Usage: hypha token [options]
22
+
23
+ Generate a workspace token.
24
+
25
+ Options:
26
+ --expires-in <seconds> Token expiration (default: 3600)
27
+ --permission <perm> Permission level: read, read_write, admin (default: read_write)
28
+ --workspace <ws> Target workspace (default: current)
29
+ --json Output as JSON`);
30
+ return;
31
+ }
32
+ const server = await connectToHypha();
33
+ try {
34
+ const expiresIn = getFlagInt(args, "--expires-in") || 3600;
35
+ const permission = getFlag(args, "--permission") || "read_write";
36
+ const workspace = getFlag(args, "--workspace") || server.config.workspace;
37
+ const json = hasFlag(args, "--json");
38
+ const token = await server.generateToken({
39
+ expires_in: expiresIn,
40
+ permission,
41
+ workspace
42
+ });
43
+ if (json) {
44
+ console.log(formatJson({
45
+ token,
46
+ workspace,
47
+ permission,
48
+ expires_in: expiresIn
49
+ }));
50
+ } else {
51
+ console.log(token);
52
+ }
53
+ } finally {
54
+ await server.disconnect();
55
+ }
56
+ }
57
+ async function servicesCommand(args) {
58
+ if (hasFlag(args, "--help", "-h")) {
59
+ console.log(`Usage: hypha services [options]
60
+
61
+ List services in the current workspace.
62
+
63
+ Options:
64
+ --type <type> Filter by service type
65
+ --include-unlisted Include unlisted services
66
+ --json Output as JSON`);
67
+ return;
68
+ }
69
+ const server = await connectToHypha();
70
+ try {
71
+ const type = getFlag(args, "--type");
72
+ const includeUnlisted = hasFlag(args, "--include-unlisted");
73
+ const json = hasFlag(args, "--json");
74
+ const query = { _rkwargs: true };
75
+ if (type) query.type = type;
76
+ if (includeUnlisted) query.include_unlisted = true;
77
+ const services = await server.listServices(query);
78
+ if (json) {
79
+ console.log(formatJson(services));
80
+ return;
81
+ }
82
+ if (!services || services.length === 0) {
83
+ console.log("No services found.");
84
+ return;
85
+ }
86
+ const rows = [["ID", "NAME", "TYPE", "DESCRIPTION"]];
87
+ for (const svc of services) {
88
+ rows.push([
89
+ svc.id || "",
90
+ svc.name || "",
91
+ svc.type || "",
92
+ (svc.description || "").slice(0, 60)
93
+ ]);
94
+ }
95
+ console.log(formatTable(rows));
96
+ } finally {
97
+ await server.disconnect();
98
+ }
99
+ }
100
+ async function clientsCommand(args) {
101
+ if (hasFlag(args, "--help", "-h")) {
102
+ console.log(`Usage: hypha clients [workspace] [options]
103
+
104
+ List connected clients in a workspace. Defaults to the connected workspace.
105
+ Pass a workspace name as positional arg to target a different workspace (requires admin).
106
+
107
+ Options:
108
+ --json Output as JSON`);
109
+ return;
110
+ }
111
+ const server = await connectToHypha();
112
+ try {
113
+ const json = hasFlag(args, "--json");
114
+ const targetWs = args[0] && !args[0].startsWith("-") ? args[0] : server.config.workspace;
115
+ const clients = await server.listClients({ workspace: targetWs, _rkwargs: true });
116
+ if (json) {
117
+ console.log(formatJson(clients));
118
+ return;
119
+ }
120
+ console.log(`${clients.length} client(s) in workspace ${targetWs}`);
121
+ if (clients.length === 0) return;
122
+ for (const c of clients.slice(0, 50)) {
123
+ console.log(` ${c}`);
124
+ }
125
+ if (clients.length > 50) {
126
+ console.log(` ... and ${clients.length - 50} more`);
127
+ }
128
+ } finally {
129
+ await server.disconnect();
130
+ }
131
+ }
132
+ async function pingCommand(args) {
133
+ if (hasFlag(args, "--help", "-h")) {
134
+ console.log(`Usage: hypha ping <client-id> [options]
135
+
136
+ Ping a specific client to check if it's alive.
137
+
138
+ Options:
139
+ --timeout <seconds> Ping timeout (default: 5)`);
140
+ return;
141
+ }
142
+ const clientId = args[0] && !args[0].startsWith("-") ? args[0] : void 0;
143
+ if (!clientId) {
144
+ console.error("Usage: hypha ping <client-id>");
145
+ process.exit(1);
146
+ }
147
+ const server = await connectToHypha();
148
+ try {
149
+ const timeout = getFlagInt(args, "--timeout") || 5;
150
+ try {
151
+ const result = await server.ping({ client_id: clientId, timeout, _rkwargs: true });
152
+ console.log(`${clientId}: ${result}`);
153
+ } catch (e) {
154
+ console.log(`${clientId}: dead (${e.message || e})`);
155
+ }
156
+ } finally {
157
+ await server.disconnect();
158
+ }
159
+ }
160
+ async function kickCommand(args) {
161
+ if (hasFlag(args, "--help", "-h")) {
162
+ console.log(`Usage: hypha kick <client-id> [workspace]
163
+
164
+ Disconnect a client and remove all its services. Requires admin.
165
+ If workspace is not specified, uses the connected workspace.
166
+
167
+ Note: delete_client is not in the default workspace interface.
168
+ This command uses the workspace-manager service directly.`);
169
+ return;
170
+ }
171
+ const clientId = args[0] && !args[0].startsWith("-") ? args[0] : void 0;
172
+ if (!clientId) {
173
+ console.error("Usage: hypha kick <client-id> [workspace]");
174
+ process.exit(1);
175
+ }
176
+ const server = await connectToHypha();
177
+ try {
178
+ const targetWs = args[1] && !args[1].startsWith("-") ? args[1] : server.config.workspace;
179
+ const svc = await server.getService(`${server.config.workspace}/*:default`);
180
+ if (svc.deleteClient) {
181
+ await svc.deleteClient({ client_id: clientId, workspace: targetWs, _rkwargs: true });
182
+ } else {
183
+ console.error("delete_client is not available. Use `hypha cleanup` instead.");
184
+ process.exit(1);
185
+ }
186
+ console.log(`Kicked client ${clientId} from ${targetWs}`);
187
+ } finally {
188
+ await server.disconnect();
189
+ }
190
+ }
191
+ async function cleanupCommand(args) {
192
+ if (hasFlag(args, "--help", "-h")) {
193
+ console.log(`Usage: hypha cleanup [workspace] [options]
194
+
195
+ Ping all clients in a workspace and remove dead/stale ones.
196
+ Requires admin permission.
197
+ Defaults to the connected workspace. Pass workspace name as positional arg.
198
+
199
+ Options:
200
+ --timeout <seconds> Ping timeout per client (default: 2)
201
+ --json Output as JSON`);
202
+ return;
203
+ }
204
+ const server = await connectToHypha();
205
+ try {
206
+ const timeout = getFlagInt(args, "--timeout") || 2;
207
+ const json = hasFlag(args, "--json");
208
+ const targetWs = args[0] && !args[0].startsWith("-") ? args[0] : server.config.workspace;
209
+ const clients = await server.listClients({ workspace: targetWs, _rkwargs: true });
210
+ console.log(`Workspace ${targetWs}: ${clients.length} client(s)`);
211
+ console.log(`Pinging all clients (timeout=${timeout}s)... this may take a while.`);
212
+ const result = await server.cleanup({ workspace: targetWs, timeout, _rkwargs: true });
213
+ const removed = result?.removed_clients || result?.removedClients || [];
214
+ if (json) {
215
+ console.log(formatJson(result));
216
+ } else {
217
+ console.log(`Removed ${removed.length} dead client(s).`);
218
+ if (removed.length > 0 && removed.length <= 30) {
219
+ for (const c of removed) {
220
+ console.log(` - ${c}`);
221
+ }
222
+ }
223
+ if (result?.removed_workspace || result?.removedWorkspace) {
224
+ console.log(`Workspace ${targetWs} was removed (no live clients remaining).`);
225
+ }
226
+ }
227
+ } finally {
228
+ await server.disconnect();
229
+ }
230
+ }
231
+ async function workspaceInfoCommand(args) {
232
+ if (hasFlag(args, "--help", "-h")) {
233
+ console.log(`Usage: hypha workspace-info [workspace] [--json]
234
+
235
+ Show detailed workspace information (admin).`);
236
+ return;
237
+ }
238
+ const server = await connectToHypha();
239
+ try {
240
+ const json = hasFlag(args, "--json");
241
+ const targetWs = args[0] && !args[0].startsWith("-") ? args[0] : server.config.workspace;
242
+ const wsInfo = await server.getWorkspaceInfo({ workspace: targetWs, _rkwargs: true });
243
+ if (json) {
244
+ console.log(formatJson(wsInfo));
245
+ } else {
246
+ console.log(`Workspace: ${wsInfo.id || wsInfo.name || targetWs}`);
247
+ for (const [k, v] of Object.entries(wsInfo)) {
248
+ if (k === "id" || k === "name") continue;
249
+ const val = typeof v === "object" ? JSON.stringify(v) : String(v);
250
+ console.log(` ${k}: ${val.slice(0, 120)}`);
251
+ }
252
+ }
253
+ } finally {
254
+ await server.disconnect();
255
+ }
256
+ }
257
+ async function infoCommand(args) {
258
+ if (hasFlag(args, "--help", "-h")) {
259
+ console.log(`Usage: hypha info [--json]
260
+
261
+ Show connection information.`);
262
+ return;
263
+ }
264
+ const server = await connectToHypha();
265
+ try {
266
+ const json = hasFlag(args, "--json");
267
+ const info = {
268
+ server_url: server.config.public_base_url || resolveServerUrl(),
269
+ workspace: server.config.workspace,
270
+ client_id: server.config.client_id
271
+ };
272
+ if (json) {
273
+ console.log(formatJson(info));
274
+ } else {
275
+ console.log(`Server: ${info.server_url}`);
276
+ console.log(`Workspace: ${info.workspace}`);
277
+ console.log(`Client ID: ${info.client_id}`);
278
+ }
279
+ } finally {
280
+ await server.disconnect();
281
+ }
282
+ }
283
+
284
+ export { cleanupCommand, clientsCommand, infoCommand, kickCommand, loginCommand, pingCommand, servicesCommand, tokenCommand, workspaceInfoCommand };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "hypha-cli",
3
- "version": "0.1.7",
3
+ "version": "0.1.9",
4
4
  "description": "Hypha Cloud CLI — manage workspaces, apps, and artifacts",
5
5
  "author": "Amun AI AB",
6
6
  "license": "SEE LICENSE IN LICENSE",