@fulldivevr/workcord-cli 1.6.0 → 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,8 +1,8 @@
1
- import { Option } from "commander";
1
+ import { Help, Option } from "commander";
2
2
  import { randomUUID } from "node:crypto";
3
3
  import { readFile, stat, writeFile } from "node:fs/promises";
4
4
  import { Writable } from "node:stream";
5
- import { actingUserId, resolveHermesKey } from "../auth.js";
5
+ import { actingUserId, isManagedHubMode, resolveHermesKey } from "../auth.js";
6
6
  import { hermesBinary, hermesCall, hermesStream, hermesUpload } from "../hermes-client.js";
7
7
  import { assertArchiveSize, flavorSetWarnings, guardOwnership, rolloutBody, } from "../hermes-guards.js";
8
8
  import { getOrCreateGroup } from "./_group.js";
@@ -23,7 +23,8 @@ function agentFlags(cmd) {
23
23
  .option("--room-agent <id>", "room agent id (resolved as workcord-room-agent:<id>)")
24
24
  .option("--marketplace-install <id>", "marketplace flavor install id or its room agent id")
25
25
  .option("--refresh", "re-reveal the tenant key instead of using the cached one")
26
- .option("--no-cache", "do not read or write the local tenant-key cache");
26
+ .option("--no-cache", "do not read or write the local tenant-key cache")
27
+ .option("--managed", "managed mode: always reveal, no cache, no --as (also WORKCORD_HUB_MANAGED=1)");
27
28
  }
28
29
  function jsonOption(cmd, name, description) {
29
30
  return cmd.option(`--${name} <json>`, description);
@@ -44,16 +45,18 @@ function out(data) {
44
45
  export function hermesChatTextBody(text) {
45
46
  return { parts: [{ type: "text", text }] };
46
47
  }
47
- async function credentials(program, opts) {
48
+ async function credentials(program, opts, deps) {
48
49
  return resolveHermesKey(agentRef(opts), {
49
50
  refresh: opts.refresh,
50
51
  cache: opts.cache,
52
+ managed: opts.managed || undefined,
51
53
  asUserId: actingUserId(program),
54
+ ...deps,
52
55
  });
53
56
  }
54
57
  function tenantPath(creds, suffix) {
55
58
  if (!creds.tenantId) {
56
- throw new Error("No tenantId available for this agent. Re-run with --refresh, or set WORKCORD_HERMES_TENANT_ID alongside WORKCORD_HERMES_KEY.");
59
+ throw new Error("No tenantId available for this agent. Re-run with --refresh, or set WORKCORD_HUB_TENANT_ID alongside WORKCORD_HUB_KEY.");
57
60
  }
58
61
  return `/v1/tenants/${encodeURIComponent(creds.tenantId)}${suffix}`;
59
62
  }
@@ -102,54 +105,69 @@ async function readArchive(archivePath) {
102
105
  const buffer = await readFile(archivePath);
103
106
  return buffer.buffer.slice(buffer.byteOffset, buffer.byteOffset + buffer.byteLength);
104
107
  }
105
- export function registerHermes(program) {
106
- const group = getOrCreateGroup(program, "hermes", "Advanced Hermes Hub diagnostics and recovery for an agent tenant");
107
- agentFlags(group.command("key").description("Reveal (and cache) the Hermes Hub tenant key for an agent.")).action(async (opts) => {
108
- const creds = await credentials(program, opts);
108
+ export function registerHub(program, deps = {}) {
109
+ // `hermes` is a hidden alias of `hub`, kept for one release. The help formatter
110
+ // below replaces only the exact `name|alias` token so the alias stays out of help output.
111
+ const help = new Help();
112
+ const withoutAlias = (cmd, term) => {
113
+ const alias = cmd.aliases()[0];
114
+ return alias ? term.replace(`${cmd.name()}|${alias}`, cmd.name()) : term;
115
+ };
116
+ program.configureHelp({
117
+ subcommandTerm: (cmd) => withoutAlias(cmd, help.subcommandTerm(cmd)),
118
+ commandUsage: (cmd) => withoutAlias(cmd, help.commandUsage(cmd)),
119
+ });
120
+ const group = getOrCreateGroup(program, "hub", "Advanced Autoworker Hub diagnostics and recovery for an agent tenant").alias("hermes");
121
+ agentFlags(group.command("key").description("Reveal (and cache) the Autoworker Hub tenant key for an agent. In managed mode the key is not printed.")).action(async (opts) => {
122
+ const creds = await credentials(program, opts, deps);
123
+ if (opts.managed || isManagedHubMode()) {
124
+ out({ tenantId: creds.tenantId, hubBaseUrl: creds.hubBaseUrl, managed: true });
125
+ return;
126
+ }
109
127
  out({ key: creds.key, tenantId: creds.tenantId, hubBaseUrl: creds.hubBaseUrl });
110
128
  });
111
- agentFlags(group.command("whoami").description("Show the Hermes Hub tenant this agent's key belongs to.")).action(async (opts) => {
112
- const creds = await credentials(program, opts);
129
+ agentFlags(group.command("whoami").description("Show the Autoworker Hub tenant this agent's key belongs to.")).action(async (opts) => {
130
+ const creds = await credentials(program, opts, deps);
113
131
  out(await hermesCall({ ...creds, path: "/v1/tenant-api/tenant" }));
114
132
  });
115
133
  agentFlags(group.command("runtime").description("Show the tenant runtime.")).action(async (opts) => {
116
- const creds = await credentials(program, opts);
134
+ const creds = await credentials(program, opts, deps);
117
135
  out(await hermesCall({ ...creds, path: "/v1/tenant-api/tenant/runtime" }));
118
136
  });
119
137
  const agent = group.command("agent").description("Tenant agent lifecycle");
120
138
  agentFlags(agent.command("status").description("Show the tenant agent.")).action(async (opts) => {
121
- const creds = await credentials(program, opts);
139
+ const creds = await credentials(program, opts, deps);
122
140
  out(await hermesCall({ ...creds, path: "/v1/tenant-api/tenant/agent" }));
123
141
  });
124
142
  for (const verb of ["start", "stop", "restart"]) {
125
143
  agentFlags(agent.command(verb).description(`${verb[0].toUpperCase()}${verb.slice(1)} the tenant agent.`)).action(async (opts) => {
126
- const creds = await credentials(program, opts);
144
+ const creds = await credentials(program, opts, deps);
127
145
  out(await hermesCall({ ...creds, method: "POST", path: `/v1/tenant-api/tenant/agent/${verb}` }));
128
146
  });
129
147
  }
130
148
  agentFlags(agent.command("card").description("Show the tenant agent card.")).action(async (opts) => {
131
- const creds = await credentials(program, opts);
149
+ const creds = await credentials(program, opts, deps);
132
150
  out(await hermesCall({ ...creds, path: "/v1/tenant-api/tenant/agent-card" }));
133
151
  });
134
152
  const chat = group.command("chat").description("Tenant chats and chat messages");
135
153
  jsonOption(agentFlags(chat.command("list").description("List chats.")), "query", "query parameters as JSON").action(async (opts) => {
136
- const creds = await credentials(program, opts);
154
+ const creds = await credentials(program, opts, deps);
137
155
  out(await hermesCall({ ...creds, path: tenantPath(creds, "/chats"), query: parseJson(opts.query, "--query") }));
138
156
  });
139
157
  jsonOption(agentFlags(chat.command("create").description("Create a chat.")), "body", "request body as JSON").action(async (opts) => {
140
- const creds = await credentials(program, opts);
158
+ const creds = await credentials(program, opts, deps);
141
159
  out(await hermesCall({ ...creds, method: "POST", path: tenantPath(creds, "/chats"), body: parseJson(opts.body, "--body") ?? {} }));
142
160
  });
143
161
  agentFlags(chat.command("get").description("Get one chat."))
144
162
  .requiredOption("--chat <chatId>", "chat id")
145
163
  .action(async (opts) => {
146
- const creds = await credentials(program, opts);
164
+ const creds = await credentials(program, opts, deps);
147
165
  out(await hermesCall({ ...creds, path: tenantPath(creds, `/chats/${encodeURIComponent(opts.chat)}`) }));
148
166
  });
149
167
  jsonOption(agentFlags(chat.command("messages").description("List messages in a chat.")), "query", "query parameters as JSON")
150
168
  .requiredOption("--chat <chatId>", "chat id")
151
169
  .action(async (opts) => {
152
- const creds = await credentials(program, opts);
170
+ const creds = await credentials(program, opts, deps);
153
171
  out(await hermesCall({
154
172
  ...creds,
155
173
  path: tenantPath(creds, `/chats/${encodeURIComponent(opts.chat)}/messages`),
@@ -161,7 +179,7 @@ export function registerHermes(program) {
161
179
  .option("--text <text>", "message text")
162
180
  .option("--idempotency-key <key>", "Idempotency-Key header (generated when omitted)")
163
181
  .action(async (opts) => {
164
- const creds = await credentials(program, opts);
182
+ const creds = await credentials(program, opts, deps);
165
183
  const body = parseJson(opts.body, "--body") ?? (opts.text !== undefined ? hermesChatTextBody(opts.text) : undefined);
166
184
  if (body === undefined) {
167
185
  throw new Error("One of --text or --body is required.");
@@ -179,7 +197,7 @@ export function registerHermes(program) {
179
197
  .option("--after-revision <n>", "only return when the revision is newer than this")
180
198
  .option("--wait-seconds <n>", "long-poll for up to this many seconds")
181
199
  .action(async (opts) => {
182
- const creds = await credentials(program, opts);
200
+ const creds = await credentials(program, opts, deps);
183
201
  out(await hermesCall({
184
202
  ...creds,
185
203
  path: tenantPath(creds, `/chat-messages/${encodeURIComponent(opts.message)}`),
@@ -190,7 +208,7 @@ export function registerHermes(program) {
190
208
  .requiredOption("--message <messageId>", "chat message id")
191
209
  .option("--last-event-id <id>", "resume from this event id")
192
210
  .action(async (opts) => {
193
- const creds = await credentials(program, opts);
211
+ const creds = await credentials(program, opts, deps);
194
212
  await hermesStream({
195
213
  ...creds,
196
214
  path: tenantPath(creds, `/chat-messages/${encodeURIComponent(opts.message)}/events`),
@@ -200,13 +218,13 @@ export function registerHermes(program) {
200
218
  agentFlags(chat.command("stop").description("Stop a chat message."))
201
219
  .requiredOption("--message <messageId>", "chat message id")
202
220
  .action(async (opts) => {
203
- const creds = await credentials(program, opts);
221
+ const creds = await credentials(program, opts, deps);
204
222
  out(await hermesCall({ ...creds, method: "POST", path: tenantPath(creds, `/chat-messages/${encodeURIComponent(opts.message)}/stop`) }));
205
223
  });
206
224
  jsonOption(agentFlags(chat.command("approve").description("Answer a chat message's approval request.")), "body", "request body as JSON")
207
225
  .requiredOption("--message <messageId>", "chat message id")
208
226
  .action(async (opts) => {
209
- const creds = await credentials(program, opts);
227
+ const creds = await credentials(program, opts, deps);
210
228
  out(await hermesCall({
211
229
  ...creds,
212
230
  method: "POST",
@@ -216,32 +234,32 @@ export function registerHermes(program) {
216
234
  });
217
235
  const run = group.command("run").description("Tenant runs");
218
236
  jsonOption(agentFlags(run.command("create").description("Create a run.")), "body", "request body as JSON").action(async (opts) => {
219
- const creds = await credentials(program, opts);
237
+ const creds = await credentials(program, opts, deps);
220
238
  out(await hermesCall({ ...creds, method: "POST", path: tenantPath(creds, "/runs"), body: parseJson(opts.body, "--body") ?? {} }));
221
239
  });
222
240
  agentFlags(run.command("get").description("Get one run."))
223
241
  .requiredOption("--run <runId>", "run id")
224
242
  .action(async (opts) => {
225
- const creds = await credentials(program, opts);
243
+ const creds = await credentials(program, opts, deps);
226
244
  out(await hermesCall({ ...creds, path: tenantPath(creds, `/runs/${encodeURIComponent(opts.run)}`) }));
227
245
  });
228
246
  agentFlags(run.command("stream").description("Stream a run's events (SSE)."))
229
247
  .requiredOption("--run <runId>", "run id")
230
248
  .option("--last-event-id <id>", "resume from this event id")
231
249
  .action(async (opts) => {
232
- const creds = await credentials(program, opts);
250
+ const creds = await credentials(program, opts, deps);
233
251
  await hermesStream({ ...creds, path: tenantPath(creds, `/runs/${encodeURIComponent(opts.run)}/events`), lastEventId: opts.lastEventId });
234
252
  });
235
253
  agentFlags(run.command("stop").description("Stop a run."))
236
254
  .requiredOption("--run <runId>", "run id")
237
255
  .action(async (opts) => {
238
- const creds = await credentials(program, opts);
256
+ const creds = await credentials(program, opts, deps);
239
257
  out(await hermesCall({ ...creds, method: "POST", path: tenantPath(creds, `/runs/${encodeURIComponent(opts.run)}/stop`) }));
240
258
  });
241
259
  jsonOption(agentFlags(run.command("approve").description("Answer a run's approval request.")), "body", "request body as JSON")
242
260
  .requiredOption("--run <runId>", "run id")
243
261
  .action(async (opts) => {
244
- const creds = await credentials(program, opts);
262
+ const creds = await credentials(program, opts, deps);
245
263
  out(await hermesCall({
246
264
  ...creds,
247
265
  method: "POST",
@@ -253,20 +271,20 @@ export function registerHermes(program) {
253
271
  agentFlags(files.command("ls").description("List files under the tenant's virtual roots."))
254
272
  .option("--path <path>", "directory path (empty means root)")
255
273
  .action(async (opts) => {
256
- const creds = await credentials(program, opts);
274
+ const creds = await credentials(program, opts, deps);
257
275
  out(await hermesCall({ ...creds, path: "/v1/tenant-api/tenant/files", query: { path: opts.path } }));
258
276
  });
259
277
  agentFlags(files.command("cat").description("Read one tenant-visible file."))
260
278
  .requiredOption("--path <path>", "file path")
261
279
  .action(async (opts) => {
262
- const creds = await credentials(program, opts);
280
+ const creds = await credentials(program, opts, deps);
263
281
  out(await hermesCall({ ...creds, path: "/v1/tenant-api/tenant/files/content", query: { path: opts.path } }));
264
282
  });
265
283
  agentFlags(files.command("download").description("Download one tenant-visible file (raw bytes)."))
266
284
  .requiredOption("--path <path>", "file path")
267
285
  .option("--out <file>", "write to this file instead of stdout")
268
286
  .action(async (opts) => {
269
- const creds = await credentials(program, opts);
287
+ const creds = await credentials(program, opts, deps);
270
288
  const path = "/v1/tenant-api/tenant/files/download";
271
289
  const query = { path: opts.path };
272
290
  if (opts.out) {
@@ -277,7 +295,7 @@ export function registerHermes(program) {
277
295
  });
278
296
  const share = group.command("share").description("Share-group filesystem");
279
297
  agentFlags(share.command("groups").description("List share groups visible to this tenant.")).action(async (opts) => {
280
- const creds = await credentials(program, opts);
298
+ const creds = await credentials(program, opts, deps);
281
299
  out(await hermesCall({ ...creds, path: "/v1/tenant-api/tenant/shares" }));
282
300
  });
283
301
  const shareGroupFlags = (cmd) => agentFlags(cmd).requiredOption("--group <groupId>", "share group id");
@@ -285,7 +303,7 @@ export function registerHermes(program) {
285
303
  shareGroupFlags(share.command("ls").description("List one share-group directory."))
286
304
  .option("--path <path>", "path relative to the share root")
287
305
  .action(async (opts) => {
288
- const creds = await credentials(program, opts);
306
+ const creds = await credentials(program, opts, deps);
289
307
  out(await hermesCall({ ...creds, path: sharePath(opts.group, "list"), query: { path: opts.path } }));
290
308
  });
291
309
  shareGroupFlags(share.command("read").description("Read one file from a share group."))
@@ -293,7 +311,7 @@ export function registerHermes(program) {
293
311
  .option("--offset <n>", "leading lines to skip")
294
312
  .option("--limit <n>", "maximum lines to return")
295
313
  .action(async (opts) => {
296
- const creds = await credentials(program, opts);
314
+ const creds = await credentials(program, opts, deps);
297
315
  out(await hermesCall({
298
316
  ...creds,
299
317
  path: sharePath(opts.group, "read"),
@@ -303,7 +321,7 @@ export function registerHermes(program) {
303
321
  shareGroupFlags(share.command("stat").description("Stat one share-group path."))
304
322
  .requiredOption("--path <path>", "path relative to the share root")
305
323
  .action(async (opts) => {
306
- const creds = await credentials(program, opts);
324
+ const creds = await credentials(program, opts, deps);
307
325
  out(await hermesCall({ ...creds, path: sharePath(opts.group, "stat"), query: { path: opts.path } }));
308
326
  });
309
327
  shareGroupFlags(share.command("grep").description("Search share-group file contents."))
@@ -312,7 +330,7 @@ export function registerHermes(program) {
312
330
  .option("--ignore-case", "case-insensitive match")
313
331
  .option("--max <n>", "maximum results")
314
332
  .action(async (opts) => {
315
- const creds = await credentials(program, opts);
333
+ const creds = await credentials(program, opts, deps);
316
334
  out(await hermesCall({
317
335
  ...creds,
318
336
  path: sharePath(opts.group, "grep"),
@@ -324,7 +342,7 @@ export function registerHermes(program) {
324
342
  .option("--path <path>", "path relative to the share root")
325
343
  .option("--max <n>", "maximum results")
326
344
  .action(async (opts) => {
327
- const creds = await credentials(program, opts);
345
+ const creds = await credentials(program, opts, deps);
328
346
  out(await hermesCall({
329
347
  ...creds,
330
348
  path: sharePath(opts.group, "find"),
@@ -336,7 +354,7 @@ export function registerHermes(program) {
336
354
  .option("--content <text>", "file contents", "")
337
355
  .addOption(new Option("--mode <mode>", "write mode").choices(["overwrite", "append"]))
338
356
  .action(async (opts) => {
339
- const creds = await credentials(program, opts);
357
+ const creds = await credentials(program, opts, deps);
340
358
  out(await hermesCall({
341
359
  ...creds,
342
360
  method: "POST",
@@ -347,21 +365,21 @@ export function registerHermes(program) {
347
365
  shareGroupFlags(share.command("mkdir").description("Create a share-group directory."))
348
366
  .requiredOption("--path <path>", "directory path relative to the share root")
349
367
  .action(async (opts) => {
350
- const creds = await credentials(program, opts);
368
+ const creds = await credentials(program, opts, deps);
351
369
  out(await hermesCall({ ...creds, method: "POST", path: sharePath(opts.group, "mkdir"), body: { path: opts.path } }));
352
370
  });
353
371
  shareGroupFlags(share.command("move").description("Move a share-group path."))
354
372
  .requiredOption("--from <path>", "source path relative to the share root")
355
373
  .requiredOption("--to <path>", "destination path relative to the share root")
356
374
  .action(async (opts) => {
357
- const creds = await credentials(program, opts);
375
+ const creds = await credentials(program, opts, deps);
358
376
  out(await hermesCall({ ...creds, method: "POST", path: sharePath(opts.group, "move"), body: { from: opts.from, to: opts.to } }));
359
377
  });
360
378
  shareGroupFlags(share.command("rm").description("Remove a share-group path."))
361
379
  .requiredOption("--path <path>", "path relative to the share root")
362
380
  .option("--recursive", "required to remove a non-empty directory")
363
381
  .action(async (opts) => {
364
- const creds = await credentials(program, opts);
382
+ const creds = await credentials(program, opts, deps);
365
383
  out(await hermesCall({
366
384
  ...creds,
367
385
  method: "POST",
@@ -371,14 +389,14 @@ export function registerHermes(program) {
371
389
  });
372
390
  const skills = group.command("skills").description("Skills installed on this tenant");
373
391
  agentFlags(skills.command("list").description("List this tenant's skills.")).action(async (opts) => {
374
- const creds = await credentials(program, opts);
392
+ const creds = await credentials(program, opts, deps);
375
393
  out(await hermesCall({ ...creds, path: "/v1/tenant-api/tenant/skills" }));
376
394
  });
377
395
  for (const [verb, enabled] of [["enable", true], ["disable", false]]) {
378
396
  agentFlags(skills.command(verb).description(`${verb[0].toUpperCase()}${verb.slice(1)} one skill on this tenant.`))
379
397
  .requiredOption("--skill <name>", "skill name")
380
398
  .action(async (opts) => {
381
- const creds = await credentials(program, opts);
399
+ const creds = await credentials(program, opts, deps);
382
400
  out(await hermesCall({
383
401
  ...creds,
384
402
  method: "PUT",
@@ -391,28 +409,28 @@ export function registerHermes(program) {
391
409
  .requiredOption("--category <category>", "skill category")
392
410
  .requiredOption("--skill <skill>", "skill name")
393
411
  .action(async (opts) => {
394
- const creds = await credentials(program, opts);
412
+ const creds = await credentials(program, opts, deps);
395
413
  out(await hermesCall({ ...creds, path: `/v1/tenant-api/tenant/skills/${seg(opts.category)}/${seg(opts.skill)}/files` }));
396
414
  });
397
415
  agentFlags(skills.command("cat").description("Read one skill file."))
398
416
  .requiredOption("--path <skillPath>", "slash-delimited path relative to $HERMES_HOME/skills")
399
417
  .action(async (opts) => {
400
- const creds = await credentials(program, opts);
418
+ const creds = await credentials(program, opts, deps);
401
419
  out(await hermesCall({ ...creds, path: `/v1/tenant-api/tenant/skill-files/${segments(opts.path)}` }));
402
420
  });
403
421
  const flavor = group.command("flavor").description("Flavor marketplace and this tenant's flavor pin");
404
422
  agentFlags(flavor.command("current").description("Show this tenant's current flavor pin.")).action(async (opts) => {
405
- const creds = await credentials(program, opts);
423
+ const creds = await credentials(program, opts, deps);
406
424
  out(await hermesCall({ ...creds, path: "/v1/tenant-api/flavors/current" }));
407
425
  });
408
426
  agentFlags(flavor.command("catalog").description("List the flavor catalog.")).action(async (opts) => {
409
- const creds = await credentials(program, opts);
427
+ const creds = await credentials(program, opts, deps);
410
428
  out(await hermesCall({ ...creds, path: "/v1/tenant-api/flavors" }));
411
429
  });
412
430
  agentFlags(flavor.command("get").description("Get one catalog flavor."))
413
431
  .requiredOption("--flavor <flavorId>", "flavor id")
414
432
  .action(async (opts) => {
415
- const creds = await credentials(program, opts);
433
+ const creds = await credentials(program, opts, deps);
416
434
  out(await hermesCall({ ...creds, path: `/v1/tenant-api/flavors/${seg(opts.flavor)}` }));
417
435
  });
418
436
  agentFlags(flavor.command("set").description("Re-pin this tenant to another version of its flavor."))
@@ -420,7 +438,7 @@ export function registerHermes(program) {
420
438
  .option("--flavor <flavorId>", "flavor id (defaults to the current pin)")
421
439
  .option("--force", "proceed despite a downgrade or deprecated target")
422
440
  .action(async (opts) => {
423
- const creds = await credentials(program, opts);
441
+ const creds = await credentials(program, opts, deps);
424
442
  const current = await currentFlavor(creds);
425
443
  const flavorId = opts.flavor ?? current?.id;
426
444
  if (!flavorId) {
@@ -446,7 +464,7 @@ export function registerHermes(program) {
446
464
  agentFlags(flavor.command("subscribe").description("Set this tenant's flavor update policy."))
447
465
  .addOption(new Option("--policy <policy>", "update policy").choices(["pinned", "stable", "canary", "auto_patch"]).makeOptionMandatory())
448
466
  .action(async (opts) => {
449
- const creds = await credentials(program, opts);
467
+ const creds = await credentials(program, opts, deps);
450
468
  out(await hermesCall({
451
469
  ...creds,
452
470
  method: "PUT",
@@ -459,7 +477,7 @@ export function registerHermes(program) {
459
477
  .requiredOption("--out <file>", "write the gzipped tarball here")
460
478
  .option("--flavor <flavorId>", "flavor id (defaults to the current pin)")
461
479
  .action(async (opts) => {
462
- const creds = await credentials(program, opts);
480
+ const creds = await credentials(program, opts, deps);
463
481
  const flavorId = await resolveFlavorId(creds, opts.flavor);
464
482
  const bytes = await downloadToFile(creds, `/v1/tenant-api/flavors/${seg(flavorId)}/versions/${seg(opts.flavorVersion)}/source`, opts.out);
465
483
  out({ path: opts.out, bytes });
@@ -468,7 +486,7 @@ export function registerHermes(program) {
468
486
  .requiredOption("--archive <file>", "gzipped flavor package built beforehand")
469
487
  .option("--flavor <flavorId>", "flavor id (defaults to the current pin)")
470
488
  .action(async (opts) => {
471
- const creds = await credentials(program, opts);
489
+ const creds = await credentials(program, opts, deps);
472
490
  const flavorId = await resolveFlavorId(creds, opts.flavor);
473
491
  const data = await readArchive(opts.archive);
474
492
  out(await guardOwnership("flavor", flavorId, creds.tenantId, () => hermesUpload({
@@ -487,7 +505,7 @@ export function registerHermes(program) {
487
505
  .option("--force", "accept the blast radius of --all-matching")
488
506
  .action(async (opts) => {
489
507
  const body = rolloutBody(opts);
490
- const creds = await credentials(program, opts);
508
+ const creds = await credentials(program, opts, deps);
491
509
  const flavorId = await resolveFlavorId(creds, opts.flavor);
492
510
  const result = (await guardOwnership("flavor", flavorId, creds.tenantId, () => hermesCall({
493
511
  ...creds,
@@ -500,13 +518,13 @@ export function registerHermes(program) {
500
518
  });
501
519
  const skill = group.command("skill").description("Skill marketplace (owner-gated for publish)");
502
520
  agentFlags(skill.command("catalog").description("List the skill catalog.")).action(async (opts) => {
503
- const creds = await credentials(program, opts);
521
+ const creds = await credentials(program, opts, deps);
504
522
  out(await hermesCall({ ...creds, path: "/v1/tenant-api/skills" }));
505
523
  });
506
524
  agentFlags(skill.command("get").description("Get one catalog skill."))
507
525
  .requiredOption("--skill <skillId>", "skill id")
508
526
  .action(async (opts) => {
509
- const creds = await credentials(program, opts);
527
+ const creds = await credentials(program, opts, deps);
510
528
  out(await hermesCall({ ...creds, path: `/v1/tenant-api/skills/${seg(opts.skill)}` }));
511
529
  });
512
530
  agentFlags(skill.command("checkout").description("Download one skill version's source tarball."))
@@ -514,7 +532,7 @@ export function registerHermes(program) {
514
532
  .requiredOption("--skill-version <version>", "skill version")
515
533
  .requiredOption("--out <file>", "write the gzipped tarball here")
516
534
  .action(async (opts) => {
517
- const creds = await credentials(program, opts);
535
+ const creds = await credentials(program, opts, deps);
518
536
  const bytes = await downloadToFile(creds, `/v1/tenant-api/skills/${seg(opts.skill)}/versions/${seg(opts.skillVersion)}/source`, opts.out);
519
537
  out({ path: opts.out, bytes });
520
538
  });
@@ -522,7 +540,7 @@ export function registerHermes(program) {
522
540
  .requiredOption("--skill <skillId>", "skill id")
523
541
  .requiredOption("--archive <file>", "gzipped skill package built beforehand")
524
542
  .action(async (opts) => {
525
- const creds = await credentials(program, opts);
543
+ const creds = await credentials(program, opts, deps);
526
544
  const data = await readArchive(opts.archive);
527
545
  out(await guardOwnership("skill", opts.skill, creds.tenantId, () => hermesUpload({
528
546
  ...creds,
@@ -533,13 +551,13 @@ export function registerHermes(program) {
533
551
  });
534
552
  const evals = group.command("eval").description("Flavor eval suites and runs");
535
553
  agentFlags(evals.command("suites").description("List eval suites for this tenant's flavor.")).action(async (opts) => {
536
- const creds = await credentials(program, opts);
554
+ const creds = await credentials(program, opts, deps);
537
555
  out(await hermesCall({ ...creds, path: "/v1/tenant-api/tenant/flavor/eval-suites" }));
538
556
  });
539
557
  agentFlags(evals.command("run").description("Start an eval run."))
540
558
  .requiredOption("--suite <suiteId>", "eval suite id")
541
559
  .action(async (opts) => {
542
- const creds = await credentials(program, opts);
560
+ const creds = await credentials(program, opts, deps);
543
561
  out(await hermesCall({ ...creds, method: "POST", path: "/v1/tenant-api/tenant/flavor/eval-runs", body: { suiteId: opts.suite } }));
544
562
  });
545
563
  agentFlags(evals.command("list").description("List this tenant's eval runs."))
@@ -547,7 +565,7 @@ export function registerHermes(program) {
547
565
  .option("--status <status>", "filter by status")
548
566
  .option("--limit <n>", "maximum runs to return")
549
567
  .action(async (opts) => {
550
- const creds = await credentials(program, opts);
568
+ const creds = await credentials(program, opts, deps);
551
569
  out(await hermesCall({
552
570
  ...creds,
553
571
  path: "/v1/tenant-api/tenant/eval-runs",
@@ -557,24 +575,24 @@ export function registerHermes(program) {
557
575
  agentFlags(evals.command("get").description("Get one eval run."))
558
576
  .requiredOption("--run <evalRunId>", "eval run id")
559
577
  .action(async (opts) => {
560
- const creds = await credentials(program, opts);
578
+ const creds = await credentials(program, opts, deps);
561
579
  out(await hermesCall({ ...creds, path: `/v1/tenant-api/tenant/eval-runs/${seg(opts.run)}` }));
562
580
  });
563
581
  agentFlags(evals.command("cancel").description("Cancel one eval run."))
564
582
  .requiredOption("--run <evalRunId>", "eval run id")
565
583
  .action(async (opts) => {
566
- const creds = await credentials(program, opts);
584
+ const creds = await credentials(program, opts, deps);
567
585
  out(await hermesCall({ ...creds, method: "POST", path: `/v1/tenant-api/tenant/eval-runs/${seg(opts.run)}:cancel` }));
568
586
  });
569
587
  const peers = group.command("peers").description("A2A peers");
570
588
  agentFlags(peers.command("list").description("List this tenant's A2A peers.")).action(async (opts) => {
571
- const creds = await credentials(program, opts);
589
+ const creds = await credentials(program, opts, deps);
572
590
  out(await hermesCall({ ...creds, path: "/v1/tenant-api/peers" }));
573
591
  });
574
592
  agentFlags(peers.command("get").description("Get one peer."))
575
593
  .requiredOption("--peer <peerId>", "peer id")
576
594
  .action(async (opts) => {
577
- const creds = await credentials(program, opts);
595
+ const creds = await credentials(program, opts, deps);
578
596
  out(await hermesCall({ ...creds, path: `/v1/tenant-api/peers/${seg(opts.peer)}` }));
579
597
  });
580
598
  jsonOption(agentFlags(peers.command("call").description("Send a message to a peer.")), "body", "request body as JSON (overrides the other flags)")
@@ -585,7 +603,7 @@ export function registerHermes(program) {
585
603
  .option("--wait-seconds <n>", "seconds to wait for a reply")
586
604
  .option("--idempotency-key <key>", "idempotency key (generated when omitted)")
587
605
  .action(async (opts) => {
588
- const creds = await credentials(program, opts);
606
+ const creds = await credentials(program, opts, deps);
589
607
  const body = parseJson(opts.body, "--body") ??
590
608
  (opts.message !== undefined
591
609
  ? {
@@ -607,7 +625,7 @@ export function registerHermes(program) {
607
625
  .option("--exclude-capability <name>", "capability the peer must not have (repeatable)", collect)
608
626
  .option("--limit <n>", "maximum peers to return")
609
627
  .action(async (opts) => {
610
- const creds = await credentials(program, opts);
628
+ const creds = await credentials(program, opts, deps);
611
629
  const body = parseJson(opts.body, "--body") ?? {
612
630
  ...(opts.query ? { query: opts.query } : {}),
613
631
  ...(opts.requiredCapability?.length ? { requiredCapabilities: opts.requiredCapability } : {}),
@@ -618,19 +636,19 @@ export function registerHermes(program) {
618
636
  });
619
637
  const conversations = group.command("conversations").description("A2A conversations");
620
638
  agentFlags(conversations.command("list").description("List conversations.")).action(async (opts) => {
621
- const creds = await credentials(program, opts);
639
+ const creds = await credentials(program, opts, deps);
622
640
  out(await hermesCall({ ...creds, path: "/v1/tenant-api/conversations" }));
623
641
  });
624
642
  agentFlags(conversations.command("get").description("Get one conversation."))
625
643
  .requiredOption("--context <contextId>", "conversation context id")
626
644
  .action(async (opts) => {
627
- const creds = await credentials(program, opts);
645
+ const creds = await credentials(program, opts, deps);
628
646
  out(await hermesCall({ ...creds, path: `/v1/tenant-api/conversations/${seg(opts.context)}` }));
629
647
  });
630
648
  agentFlags(conversations.command("messages").description("List one conversation's messages."))
631
649
  .requiredOption("--context <contextId>", "conversation context id")
632
650
  .action(async (opts) => {
633
- const creds = await credentials(program, opts);
651
+ const creds = await credentials(program, opts, deps);
634
652
  out(await hermesCall({ ...creds, path: `/v1/tenant-api/conversations/${seg(opts.context)}/messages` }));
635
653
  });
636
654
  const sessions = group.command("sessions").description("Tenant agent sessions");
@@ -638,12 +656,12 @@ export function registerHermes(program) {
638
656
  .option("--limit <n>", "maximum sessions to return")
639
657
  .option("--source <source>", "filter by source")
640
658
  .action(async (opts) => {
641
- const creds = await credentials(program, opts);
659
+ const creds = await credentials(program, opts, deps);
642
660
  out(await hermesCall({ ...creds, path: "/v1/tenant-api/tenant/sessions", query: { limit: opts.limit, source: opts.source } }));
643
661
  });
644
662
  agentFlags(group.command("artifacts").description("List this tenant's artifacts.")).action(async (opts) => {
645
- const creds = await credentials(program, opts);
663
+ const creds = await credentials(program, opts, deps);
646
664
  out(await hermesCall({ ...creds, path: "/v1/tenant-api/tenant/artifacts" }));
647
665
  });
648
666
  }
649
- //# sourceMappingURL=hermes.js.map
667
+ //# sourceMappingURL=hub.js.map