svamp-cli 0.1.43 → 0.1.47

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.
Files changed (121) hide show
  1. package/dist/cli.mjs +166 -15
  2. package/dist/commands-8Wmq0uak.mjs +1407 -0
  3. package/dist/commands-8Xn02pQg.mjs +1217 -0
  4. package/dist/commands-B-XaqFDB.mjs +1407 -0
  5. package/dist/commands-BD_NjWJL.mjs +1217 -0
  6. package/dist/commands-BEhSQqTp.mjs +507 -0
  7. package/dist/commands-BIFQZZGw.mjs +1375 -0
  8. package/dist/commands-BLmRIMdf.mjs +1217 -0
  9. package/dist/commands-BQ_347V_.mjs +1374 -0
  10. package/dist/commands-BTEmyf2m.mjs +1407 -0
  11. package/dist/commands-BVjcCbWS.mjs +1375 -0
  12. package/dist/commands-BY09VTpk.mjs +1375 -0
  13. package/dist/commands-Bi0zYJvj.mjs +1407 -0
  14. package/dist/commands-C6KDr9Yp.mjs +1407 -0
  15. package/dist/commands-CFv6lO0D.mjs +1217 -0
  16. package/dist/commands-CJ2n5jS2.mjs +1375 -0
  17. package/dist/commands-CKEKQ_5B.mjs +1217 -0
  18. package/dist/commands-CQz67Rm1.mjs +1395 -0
  19. package/dist/commands-CRZbJjqN.mjs +1375 -0
  20. package/dist/commands-CToIvBFX.mjs +1375 -0
  21. package/dist/commands-CWsfciHn.mjs +1217 -0
  22. package/dist/commands-CYMSyqYC.mjs +1395 -0
  23. package/dist/commands-Cc73uUnP.mjs +1375 -0
  24. package/dist/commands-CdyCWC3y.mjs +1395 -0
  25. package/dist/commands-CorUNLRF.mjs +1375 -0
  26. package/dist/commands-CrdvbXPI.mjs +1395 -0
  27. package/dist/commands-D7-NHH5q.mjs +1407 -0
  28. package/dist/commands-DLoe6FyK.mjs +1375 -0
  29. package/dist/commands-DVw-P6-0.mjs +1407 -0
  30. package/dist/commands-DVygnMsh.mjs +1217 -0
  31. package/dist/commands-DZfaDmsk.mjs +1374 -0
  32. package/dist/commands-DsIoygTL.mjs +1395 -0
  33. package/dist/commands-DypTF36z.mjs +506 -0
  34. package/dist/commands-EUMJqBCs.mjs +1407 -0
  35. package/dist/commands-Jk5no-DX.mjs +1407 -0
  36. package/dist/commands-O1Q9g00y.mjs +1395 -0
  37. package/dist/commands-OwMfbBrU.mjs +1395 -0
  38. package/dist/commands-S_MFQ9n1.mjs +354 -0
  39. package/dist/commands-T3q8VKCY.mjs +1407 -0
  40. package/dist/commands-g-1n3_Rp.mjs +1395 -0
  41. package/dist/commands-otgzprjb.mjs +1375 -0
  42. package/dist/index.mjs +1 -1
  43. package/dist/package-BMCjXPI9.mjs +58 -0
  44. package/dist/package-BufekbY1.mjs +57 -0
  45. package/dist/package-CmIBOZtY.mjs +57 -0
  46. package/dist/package-CmVt1kdw.mjs +58 -0
  47. package/dist/package-DG0AkZdm.mjs +58 -0
  48. package/dist/package-DRO1LpXW.mjs +58 -0
  49. package/dist/package-UwLIU765.mjs +58 -0
  50. package/dist/package-rasGC9_z.mjs +58 -0
  51. package/dist/run-4li60ojK.mjs +1051 -0
  52. package/dist/run-6dwQnoBL.mjs +1051 -0
  53. package/dist/run-B-PWtXF-.mjs +5894 -0
  54. package/dist/run-B1ivovUl.mjs +5964 -0
  55. package/dist/run-B2zRMxE0.mjs +5508 -0
  56. package/dist/run-B31biy0V.mjs +1050 -0
  57. package/dist/run-B7V-xXM7.mjs +5775 -0
  58. package/dist/run-BE_AIJ7z.mjs +1051 -0
  59. package/dist/run-BREPr7Yc.mjs +5508 -0
  60. package/dist/run-BTwshVk1.mjs +5728 -0
  61. package/dist/run-BVcPemGr.mjs +5947 -0
  62. package/dist/run-BWqEmIiz.mjs +5964 -0
  63. package/dist/run-BWsDPiNe.mjs +1050 -0
  64. package/dist/run-BXYfq8mK.mjs +5836 -0
  65. package/dist/run-BY12Ataq.mjs +5732 -0
  66. package/dist/run-BieEN0Pg.mjs +5761 -0
  67. package/dist/run-Bl8OkKyC.mjs +5969 -0
  68. package/dist/run-BlEFlhfn.mjs +5510 -0
  69. package/dist/run-Bmx5wEBF.mjs +1051 -0
  70. package/dist/run-BzRP6Q5t.mjs +1051 -0
  71. package/dist/run-C0dyMP62.mjs +1051 -0
  72. package/dist/run-C1lS3SwN.mjs +5733 -0
  73. package/dist/run-C9Hrqjy_.mjs +1050 -0
  74. package/dist/run-CC2C8P-U.mjs +6031 -0
  75. package/dist/run-CCcW4asS.mjs +1050 -0
  76. package/dist/run-CDBKhQ1Z.mjs +1051 -0
  77. package/dist/run-CEB6sYzn.mjs +5962 -0
  78. package/dist/run-CHyN5U0t.mjs +1050 -0
  79. package/dist/run-CIFezmkC.mjs +5949 -0
  80. package/dist/run-CLA9zw7J.mjs +5907 -0
  81. package/dist/run-COWb9ovq.mjs +1050 -0
  82. package/dist/run-CSUAy5T5.mjs +1051 -0
  83. package/dist/run-CSk7i0Hq.mjs +1050 -0
  84. package/dist/run-C_8iOjO1.mjs +5892 -0
  85. package/dist/run-CdihMx0V.mjs +1051 -0
  86. package/dist/run-CkbDK6jA.mjs +1051 -0
  87. package/dist/run-Ckyg9-fm.mjs +6079 -0
  88. package/dist/run-Ct--DWF1.mjs +1051 -0
  89. package/dist/run-CxGAa9MH.mjs +1050 -0
  90. package/dist/run-D0ow-xms.mjs +5905 -0
  91. package/dist/run-D2X3jEqg.mjs +1051 -0
  92. package/dist/run-D39C7Ta3.mjs +1050 -0
  93. package/dist/run-D3bhRCCb.mjs +1051 -0
  94. package/dist/run-D691XPXy.mjs +6031 -0
  95. package/dist/run-DA-YBjNw.mjs +6018 -0
  96. package/dist/run-DByI8mI0.mjs +1051 -0
  97. package/dist/run-DDF-tRbn.mjs +5954 -0
  98. package/dist/run-DGsXW19O.mjs +5541 -0
  99. package/dist/run-DHrF2xpW.mjs +5776 -0
  100. package/dist/run-DJ4k0WzZ.mjs +1051 -0
  101. package/dist/run-DNX3djCI.mjs +1050 -0
  102. package/dist/run-DOPaGRT2.mjs +6027 -0
  103. package/dist/run-DP7KSZqR.mjs +1051 -0
  104. package/dist/run-DTkldU6a.mjs +1050 -0
  105. package/dist/run-DU10B3gK.mjs +5728 -0
  106. package/dist/run-DVZGKdKO.mjs +1050 -0
  107. package/dist/run-DXJ2M19k.mjs +1050 -0
  108. package/dist/run-DZOeccNu.mjs +5484 -0
  109. package/dist/run-DaReJPf8.mjs +1051 -0
  110. package/dist/run-De-wkVl3.mjs +5487 -0
  111. package/dist/run-Dfl3Ze2L.mjs +5541 -0
  112. package/dist/run-DfuHUDIJ.mjs +1051 -0
  113. package/dist/run-DfwfyFqj.mjs +5975 -0
  114. package/dist/run-DgUDGHZy.mjs +1051 -0
  115. package/dist/run-Dge2K7h1.mjs +1050 -0
  116. package/dist/run-Dm3U4FB5.mjs +6018 -0
  117. package/dist/run-DzXohf8-.mjs +1051 -0
  118. package/dist/run-HU4XjZfs.mjs +6023 -0
  119. package/dist/run-ZDa17iLg.mjs +6060 -0
  120. package/dist/run-ZN0qMdS_.mjs +1051 -0
  121. package/package.json +3 -2
package/dist/cli.mjs CHANGED
@@ -1,4 +1,4 @@
1
- import { b as stopDaemon, s as startDaemon, d as daemonStatus } from './run-CF6aXLmA.mjs';
1
+ import { b as stopDaemon, s as startDaemon, d as daemonStatus } from './run-Ckyg9-fm.mjs';
2
2
  import 'os';
3
3
  import 'fs/promises';
4
4
  import 'fs';
@@ -19,6 +19,13 @@ import 'zod';
19
19
  import 'node:fs/promises';
20
20
  import 'node:util';
21
21
 
22
+ const nodeMajor = parseInt(process.versions.node.split(".")[0], 10);
23
+ if (nodeMajor < 22) {
24
+ console.error(`Error: svamp requires Node.js >= 22 (you have ${process.version}).`);
25
+ console.error(" Node 22+ includes native WebSocket support needed by hypha-rpc.");
26
+ console.error(" Upgrade with: nvm install 22 && nvm alias default 22");
27
+ process.exit(1);
28
+ }
22
29
  const args = process.argv.slice(2);
23
30
  const subcommand = args[0];
24
31
  let daemonSubcommand = args[1];
@@ -96,12 +103,14 @@ async function main() {
96
103
  await handleSessionCommand();
97
104
  } else if (subcommand === "machine") {
98
105
  await handleMachineCommand();
106
+ } else if (subcommand === "skills") {
107
+ await handleSkillsCommand();
99
108
  } else if (subcommand === "--help" || subcommand === "-h") {
100
109
  printHelp();
101
110
  } else if (!subcommand || subcommand === "start") {
102
111
  await handleInteractiveCommand();
103
112
  } else if (subcommand === "--version" || subcommand === "-v") {
104
- const pkg = await import('./package-C1hpYMj4.mjs').catch(() => ({ default: { version: "unknown" } }));
113
+ const pkg = await import('./package-DG0AkZdm.mjs').catch(() => ({ default: { version: "unknown" } }));
105
114
  console.log(`svamp version: ${pkg.default.version}`);
106
115
  } else {
107
116
  console.error(`Unknown command: ${subcommand}`);
@@ -110,7 +119,7 @@ async function main() {
110
119
  }
111
120
  }
112
121
  async function handleInteractiveCommand() {
113
- const { runInteractive } = await import('./run-4eArMb_9.mjs');
122
+ const { runInteractive } = await import('./run-6dwQnoBL.mjs');
114
123
  const interactiveArgs = subcommand === "start" ? args.slice(1) : args;
115
124
  let directory = process.cwd();
116
125
  let resumeSessionId;
@@ -155,7 +164,7 @@ async function handleAgentCommand() {
155
164
  return;
156
165
  }
157
166
  if (agentArgs[0] === "list") {
158
- const { KNOWN_ACP_AGENTS, KNOWN_MCP_AGENTS: KNOWN_MCP_AGENTS2 } = await import('./run-CF6aXLmA.mjs').then(function (n) { return n.i; });
167
+ const { KNOWN_ACP_AGENTS, KNOWN_MCP_AGENTS: KNOWN_MCP_AGENTS2 } = await import('./run-Ckyg9-fm.mjs').then(function (n) { return n.i; });
159
168
  console.log("Known agents:");
160
169
  for (const [name, config2] of Object.entries(KNOWN_ACP_AGENTS)) {
161
170
  console.log(` ${name.padEnd(12)} ${config2.command} ${config2.args.join(" ")} (ACP)`);
@@ -167,7 +176,7 @@ async function handleAgentCommand() {
167
176
  console.log('Use "svamp agent -- <command> [args]" for a custom ACP agent.');
168
177
  return;
169
178
  }
170
- const { resolveAcpAgentConfig, KNOWN_MCP_AGENTS } = await import('./run-CF6aXLmA.mjs').then(function (n) { return n.i; });
179
+ const { resolveAcpAgentConfig, KNOWN_MCP_AGENTS } = await import('./run-Ckyg9-fm.mjs').then(function (n) { return n.i; });
171
180
  let cwd = process.cwd();
172
181
  const filteredArgs = [];
173
182
  for (let i = 0; i < agentArgs.length; i++) {
@@ -191,12 +200,12 @@ async function handleAgentCommand() {
191
200
  console.log(`Starting ${config.agentName} agent in ${cwd}...`);
192
201
  let backend;
193
202
  if (KNOWN_MCP_AGENTS[config.agentName]) {
194
- const { CodexMcpBackend } = await import('./run-CF6aXLmA.mjs').then(function (n) { return n.j; });
203
+ const { CodexMcpBackend } = await import('./run-Ckyg9-fm.mjs').then(function (n) { return n.j; });
195
204
  backend = new CodexMcpBackend({ cwd, log: logFn });
196
205
  } else {
197
- const { AcpBackend } = await import('./run-CF6aXLmA.mjs').then(function (n) { return n.h; });
198
- const { GeminiTransport } = await import('./run-CF6aXLmA.mjs').then(function (n) { return n.G; });
199
- const { DefaultTransport } = await import('./run-CF6aXLmA.mjs').then(function (n) { return n.D; });
206
+ const { AcpBackend } = await import('./run-Ckyg9-fm.mjs').then(function (n) { return n.h; });
207
+ const { GeminiTransport } = await import('./run-Ckyg9-fm.mjs').then(function (n) { return n.G; });
208
+ const { DefaultTransport } = await import('./run-Ckyg9-fm.mjs').then(function (n) { return n.D; });
200
209
  const transportHandler = config.agentName === "gemini" ? new GeminiTransport() : new DefaultTransport(config.agentName);
201
210
  backend = new AcpBackend({
202
211
  agentName: config.agentName,
@@ -314,7 +323,7 @@ async function handleSessionCommand() {
314
323
  printSessionHelp();
315
324
  return;
316
325
  }
317
- const { sessionList, sessionSpawn, sessionStop, sessionInfo, sessionMessages, sessionAttach, sessionMachines, sessionSend, sessionWait, sessionShare } = await import('./commands-SQ0Wp_kD.mjs');
326
+ const { sessionList, sessionSpawn, sessionStop, sessionInfo, sessionMessages, sessionAttach, sessionMachines, sessionSend, sessionWait, sessionShare, sessionRalphStart, sessionRalphCancel, sessionRalphStatus, sessionQueueAdd, sessionQueueList, sessionQueueClear } = await import('./commands-DsIoygTL.mjs');
318
327
  const parseFlagStr = (flag, shortFlag) => {
319
328
  for (let i = 1; i < sessionArgs.length; i++) {
320
329
  if ((sessionArgs[i] === flag || shortFlag) && i + 1 < sessionArgs.length) {
@@ -366,7 +375,7 @@ async function handleSessionCommand() {
366
375
  allowDomain.push(sessionArgs[++i]);
367
376
  }
368
377
  }
369
- const { parseShareArg } = await import('./commands-SQ0Wp_kD.mjs');
378
+ const { parseShareArg } = await import('./commands-DsIoygTL.mjs');
370
379
  const shareEntries = share.map((s) => parseShareArg(s));
371
380
  await sessionSpawn(agent, dir, targetMachineId, {
372
381
  message,
@@ -430,14 +439,60 @@ async function handleSessionCommand() {
430
439
  });
431
440
  } else if (sessionSubcommand === "share") {
432
441
  if (!sessionArgs[1]) {
433
- console.error("Usage: svamp session share <session-id> --add <email>[:<role>] | --remove <email> | --list");
442
+ console.error("Usage: svamp session share <session-id> --add <email>[:<role>] | --remove <email> | --list | --public <view|interact|off>");
434
443
  process.exit(1);
435
444
  }
436
445
  await sessionShare(sessionArgs[1], targetMachineId, {
437
446
  add: parseFlagStr("--add"),
438
447
  remove: parseFlagStr("--remove"),
439
- list: hasFlag("--list")
448
+ list: hasFlag("--list"),
449
+ public: parseFlagStr("--public")
440
450
  });
451
+ } else if (sessionSubcommand === "ralph-start" || sessionSubcommand === "ralph") {
452
+ if (!sessionArgs[1] || !sessionArgs[2]) {
453
+ console.error('Usage: svamp session ralph-start <session-id> "<task>" [--completion-promise TEXT] [--max-iterations N]');
454
+ process.exit(1);
455
+ }
456
+ await sessionRalphStart(sessionArgs[1], sessionArgs[2], targetMachineId, {
457
+ completionPromise: parseFlagStr("--completion-promise"),
458
+ maxIterations: parseFlagInt("--max-iterations")
459
+ });
460
+ } else if (sessionSubcommand === "ralph-cancel") {
461
+ if (!sessionArgs[1]) {
462
+ console.error("Usage: svamp session ralph-cancel <session-id>");
463
+ process.exit(1);
464
+ }
465
+ await sessionRalphCancel(sessionArgs[1], targetMachineId);
466
+ } else if (sessionSubcommand === "ralph-status") {
467
+ if (!sessionArgs[1]) {
468
+ console.error("Usage: svamp session ralph-status <session-id>");
469
+ process.exit(1);
470
+ }
471
+ await sessionRalphStatus(sessionArgs[1], targetMachineId);
472
+ } else if (sessionSubcommand === "queue") {
473
+ const queueSubcmd = sessionArgs[1];
474
+ if (queueSubcmd === "add") {
475
+ if (!sessionArgs[2] || !sessionArgs[3]) {
476
+ console.error('Usage: svamp session queue add <session-id> "<message>"');
477
+ process.exit(1);
478
+ }
479
+ await sessionQueueAdd(sessionArgs[2], sessionArgs[3], targetMachineId);
480
+ } else if (queueSubcmd === "list" || queueSubcmd === "ls") {
481
+ if (!sessionArgs[2]) {
482
+ console.error("Usage: svamp session queue list <session-id>");
483
+ process.exit(1);
484
+ }
485
+ await sessionQueueList(sessionArgs[2], targetMachineId);
486
+ } else if (queueSubcmd === "clear") {
487
+ if (!sessionArgs[2]) {
488
+ console.error("Usage: svamp session queue clear <session-id>");
489
+ process.exit(1);
490
+ }
491
+ await sessionQueueClear(sessionArgs[2], targetMachineId);
492
+ } else {
493
+ console.error("Usage: svamp session queue <add|list|clear> <session-id> [args]");
494
+ process.exit(1);
495
+ }
441
496
  } else {
442
497
  console.error(`Unknown session command: ${sessionSubcommand}`);
443
498
  printSessionHelp();
@@ -453,7 +508,7 @@ async function handleMachineCommand() {
453
508
  return;
454
509
  }
455
510
  if (machineSubcommand === "share") {
456
- const { machineShare } = await import('./commands-SQ0Wp_kD.mjs');
511
+ const { machineShare } = await import('./commands-DsIoygTL.mjs');
457
512
  let machineId;
458
513
  const shareArgs = [];
459
514
  for (let i = 1; i < machineArgs.length; i++) {
@@ -489,6 +544,51 @@ async function handleMachineCommand() {
489
544
  }
490
545
  process.exit(0);
491
546
  }
547
+ async function handleSkillsCommand() {
548
+ const skillsArgs = args.slice(1);
549
+ const skillsSubcommand = skillsArgs[0];
550
+ if (!skillsSubcommand || skillsSubcommand === "--help" || skillsSubcommand === "-h") {
551
+ printSkillsHelp();
552
+ return;
553
+ }
554
+ const { skillsFind, skillsInstall, skillsList, skillsRemove, skillsPublish } = await import('./commands-BEhSQqTp.mjs');
555
+ if (skillsSubcommand === "find" || skillsSubcommand === "search") {
556
+ const query = skillsArgs.slice(1).filter((a) => !a.startsWith("--")).join(" ");
557
+ if (!query) {
558
+ console.error("Usage: svamp skills find <query> [--json]");
559
+ process.exit(1);
560
+ }
561
+ await skillsFind(query, { json: skillsArgs.includes("--json") });
562
+ } else if (skillsSubcommand === "install" || skillsSubcommand === "add") {
563
+ if (!skillsArgs[1]) {
564
+ console.error("Usage: svamp skills install <name> [--force]");
565
+ process.exit(1);
566
+ }
567
+ await skillsInstall(skillsArgs[1], { force: skillsArgs.includes("--force") });
568
+ } else if (skillsSubcommand === "list" || skillsSubcommand === "ls") {
569
+ await skillsList();
570
+ } else if (skillsSubcommand === "remove" || skillsSubcommand === "rm") {
571
+ if (!skillsArgs[1]) {
572
+ console.error("Usage: svamp skills remove <name>");
573
+ process.exit(1);
574
+ }
575
+ await skillsRemove(skillsArgs[1]);
576
+ } else if (skillsSubcommand === "publish") {
577
+ const publishArgs = skillsArgs.slice(1).filter((a) => !a.startsWith("--"));
578
+ if (!publishArgs[0]) {
579
+ console.error("Usage: svamp skills publish <path> [--version <tag>]");
580
+ process.exit(1);
581
+ }
582
+ const versionIdx = skillsArgs.indexOf("--version");
583
+ const versionTag = versionIdx !== -1 ? skillsArgs[versionIdx + 1] : void 0;
584
+ await skillsPublish(publishArgs[0], { version: versionTag });
585
+ } else {
586
+ console.error(`Unknown skills command: ${skillsSubcommand}`);
587
+ printSkillsHelp();
588
+ process.exit(1);
589
+ }
590
+ process.exit(0);
591
+ }
492
592
  async function loginToHypha() {
493
593
  const serverUrl = args[1] || process.env.HYPHA_SERVER_URL;
494
594
  if (!serverUrl) {
@@ -566,7 +666,14 @@ Login successful!`);
566
666
  console.log(`
567
667
  You can now start the daemon: svamp daemon start`);
568
668
  } catch (err) {
569
- console.error("Login failed:", err.message || err);
669
+ const msg = err.message || String(err);
670
+ if (msg.includes("WebSocket is not defined")) {
671
+ console.error(`Login failed: WebSocket is not available in this Node.js version (${process.version}).`);
672
+ console.error(` hypha-rpc requires Node.js >= 22 (which includes native WebSocket support).`);
673
+ console.error(` Please upgrade Node.js: nvm install 22 && nvm use 22`);
674
+ } else {
675
+ console.error("Login failed:", msg);
676
+ }
570
677
  process.exit(1);
571
678
  }
572
679
  }
@@ -806,6 +913,9 @@ Usage:
806
913
  svamp session --help Show all session commands
807
914
  svamp machine share Manage machine sharing & security contexts
808
915
  svamp machine --help Show all machine commands
916
+ svamp skills find <query> Search the skills marketplace
917
+ svamp skills install <n> Install a skill from the marketplace
918
+ svamp skills --help Show all skill commands
809
919
  svamp agent list List known agents
810
920
  svamp agent <name> Start local agent session (gemini, codex)
811
921
  svamp --version Show version
@@ -860,6 +970,7 @@ Usage:
860
970
  svamp session share <id> --list List shared users
861
971
  svamp session share <id> --add <email>[:<role>] Share with user
862
972
  svamp session share <id> --remove <email> Remove shared user
973
+ svamp session share <id> --public <view|interact|off> Set public link access
863
974
 
864
975
  Options:
865
976
  --machine <id>, -m <id> Target a specific machine (prefix match supported)
@@ -889,7 +1000,23 @@ Examples:
889
1000
  svamp session spawn claude -d /tmp/proj --share alice@example.com:admin --deny-read /etc
890
1001
  svamp session spawn claude --security-context ./security.json
891
1002
  svamp session share abc12345 --add bob@example.com:view
1003
+ svamp session share abc12345 --public view
892
1004
  svamp session share abc12345 --list
1005
+
1006
+ Ralph Loop (iterative task loop):
1007
+ svamp session ralph-start <id> "<task>" [--completion-promise TEXT] [--max-iterations N]
1008
+ Start a Ralph loop
1009
+ svamp session ralph-cancel <id> Cancel active Ralph loop
1010
+ svamp session ralph-status <id> Show Ralph loop status
1011
+
1012
+ Message Queue:
1013
+ svamp session queue add <id> "<message>" Add message to queue
1014
+ svamp session queue list <id> List queued messages
1015
+ svamp session queue clear <id> Clear the queue
1016
+
1017
+ Ralph Loop Examples:
1018
+ svamp session ralph-start abc12 "Fix all linting errors" --completion-promise "All linting errors fixed" --max-iterations 10
1019
+ svamp session ralph-cancel abc12
893
1020
  `);
894
1021
  }
895
1022
  function printMachineHelp() {
@@ -929,6 +1056,30 @@ Examples:
929
1056
  svamp machine share --list
930
1057
  `);
931
1058
  }
1059
+ function printSkillsHelp() {
1060
+ console.log(`
1061
+ svamp skills \u2014 Agent skills marketplace
1062
+
1063
+ Usage:
1064
+ svamp skills find <query> [--json] Search for skills in the marketplace
1065
+ svamp skills install <name> [--force] Install skill to ~/.claude/skills/<name>/
1066
+ svamp skills list List locally installed skills
1067
+ svamp skills remove <name> Remove an installed skill
1068
+ svamp skills publish <path> [--version <tag>] Publish a skill to the marketplace
1069
+
1070
+ Skills are stored in ~/.claude/skills/ and automatically detected by Claude Code.
1071
+ Each skill contains a SKILL.md file with instructions and metadata.
1072
+ Skills use git-backed storage \u2014 you can also clone and push via git.
1073
+
1074
+ Browse online: https://hypha.aicell.io/hypha-cloud/artifacts/marketplace
1075
+
1076
+ Examples:
1077
+ svamp skills find "code review"
1078
+ svamp skills install code-review
1079
+ svamp skills publish ./my-skill/
1080
+ svamp skills publish ./my-skill/ --version v1.0
1081
+ `);
1082
+ }
932
1083
  function printInteractiveHelp() {
933
1084
  console.log(`
934
1085
  svamp \u2014 Interactive Claude session with cloud sync