superacli 1.1.7 → 1.1.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.
package/cli/supercli.js CHANGED
@@ -58,6 +58,7 @@ const RESERVED_FLAGS = [
58
58
  "compact",
59
59
  "schema",
60
60
  "help-json",
61
+ "help",
61
62
  "no-color",
62
63
  "show-dag",
63
64
  "format",
@@ -103,15 +104,15 @@ function output(data) {
103
104
  }
104
105
 
105
106
  function makeStreamEmitter(commandName) {
106
- if (humanMode) return null
107
+ if (humanMode) return null;
107
108
  return (event) => {
108
109
  output({
109
110
  version: "1.0",
110
111
  command: commandName,
111
112
  stream: true,
112
113
  data: event,
113
- })
114
- }
114
+ });
115
+ };
115
116
  }
116
117
 
117
118
  function outputHumanTable(rows, columns) {
@@ -193,11 +194,16 @@ function renderTopLevelHelp(config) {
193
194
  const namespaces = [...new Set(config.commands.map((c) => c.namespace))];
194
195
  if (humanMode) {
195
196
  console.log("\n ⚡ SuperCLI\n");
197
+ console.log(
198
+ " Deterministic capability router for namespace.resource.action commands, plugin capabilities, MCP tool bindings, and SKILL.md skill documents.\n",
199
+ );
196
200
  console.log(" Namespaces:\n");
197
201
  namespaces.forEach((ns) => {
198
202
  const resources = [
199
203
  ...new Set(
200
- config.commands.filter((c) => c.namespace === ns).map((c) => c.resource),
204
+ config.commands
205
+ .filter((c) => c.namespace === ns)
206
+ .map((c) => c.resource),
201
207
  ),
202
208
  ];
203
209
  console.log(` ${ns}`);
@@ -227,7 +233,7 @@ function renderTopLevelHelp(config) {
227
233
  }
228
234
  console.log(" Server: supercli --server");
229
235
  console.log(
230
- " Flags: --json | --human | --compact | --schema | --help-json | --server\n",
236
+ " Flags: --help | --json | --human | --compact | --schema | --help-json | --server\n",
231
237
  );
232
238
  return;
233
239
  }
@@ -236,11 +242,18 @@ function renderTopLevelHelp(config) {
236
242
  version: "1.0",
237
243
  namespaces: namespaces.map((ns) => ({
238
244
  name: ns,
239
- resources: [...new Set(config.commands.filter((c) => c.namespace === ns).map((c) => c.resource))]
240
- .map((r) => ({
241
- name: r,
242
- actions: config.commands.filter((c) => c.namespace === ns && c.resource === r).map((c) => c.action),
243
- })),
245
+ resources: [
246
+ ...new Set(
247
+ config.commands
248
+ .filter((c) => c.namespace === ns)
249
+ .map((c) => c.resource),
250
+ ),
251
+ ].map((r) => ({
252
+ name: r,
253
+ actions: config.commands
254
+ .filter((c) => c.namespace === ns && c.resource === r)
255
+ .map((c) => c.action),
256
+ })),
244
257
  })),
245
258
  });
246
259
  }
@@ -297,6 +310,64 @@ async function main() {
297
310
  }
298
311
  }
299
312
 
313
+ // Check for namespace passthrough before handling --help
314
+ // This allows commands like "cline --help --json" to pass through
315
+ {
316
+ const config = await loadConfig(SERVER);
317
+ const passthrough = findNamespacePassthrough(config, positional, rawArgs);
318
+ if (passthrough) {
319
+ const start = Date.now();
320
+ const result = await execute(
321
+ passthrough.command,
322
+ {
323
+ __rawArgs: passthrough.passthroughArgs,
324
+ __passthroughInteractive: humanMode && isTTY,
325
+ },
326
+ {
327
+ server: SERVER || "",
328
+ config,
329
+ onStreamEvent:
330
+ passthrough.command.adapterConfig &&
331
+ passthrough.command.adapterConfig.stream === "jsonl"
332
+ ? makeStreamEmitter(`${passthrough.namespace}.passthrough`)
333
+ : null,
334
+ },
335
+ );
336
+ const duration = Date.now() - start;
337
+ const envelope = {
338
+ version: "1.0",
339
+ command: `${passthrough.namespace}.passthrough`,
340
+ duration_ms: duration,
341
+ data: result,
342
+ };
343
+
344
+ if (
345
+ humanMode &&
346
+ result &&
347
+ typeof result === "object" &&
348
+ result.passthrough === true
349
+ ) {
350
+ return;
351
+ }
352
+ if (
353
+ humanMode &&
354
+ result &&
355
+ typeof result === "object" &&
356
+ typeof result.raw === "string"
357
+ ) {
358
+ console.log(result.raw);
359
+ } else {
360
+ output(envelope);
361
+ }
362
+ return;
363
+ }
364
+ }
365
+
366
+ if (flags.help) {
367
+ displayComprehensiveHelp();
368
+ return;
369
+ }
370
+
300
371
  if (flags["help-json"]) {
301
372
  const config = await loadConfig(SERVER);
302
373
  output(buildCapabilities(config, hasServer));
@@ -314,11 +385,11 @@ async function main() {
314
385
  core_capabilities: ["commands", "plugins", "mcp", "skill_docs"],
315
386
  first_steps: [
316
387
  "supercli --help-json",
317
- "supercli discover --intent \"<task>\" --json",
388
+ 'supercli discover --intent "<task>" --json',
318
389
  "supercli plugins learn <name> --json",
319
390
  "supercli plugins install <name>",
320
391
  "supercli commands --query <keyword> --limit 50 --json",
321
- "supercli inspect <namespace> <resource> <action> --json"
392
+ "supercli inspect <namespace> <resource> <action> --json",
322
393
  ],
323
394
  intent_workflow:
324
395
  "If task command is unknown, use discover -> plugins learn -> plugins install -> commands/inspect -> execute.",
@@ -327,11 +398,11 @@ async function main() {
327
398
  'supercli discover --intent "send email" --json',
328
399
  "supercli plugins learn resend --json",
329
400
  "supercli plugins install resend",
330
- "supercli commands --namespace resend --json"
331
- ]
401
+ "supercli commands --namespace resend --json",
402
+ ],
332
403
  },
333
404
  no_llm_discovery: true,
334
- note: "Intent discovery is deterministic and does not call an LLM."
405
+ note: "Intent discovery is deterministic and does not call an LLM.",
335
406
  });
336
407
  return;
337
408
  }
@@ -377,7 +448,11 @@ async function main() {
377
448
 
378
449
  if (hasServer && positional[0] === "sync") {
379
450
  const result = await syncConfig(SERVER);
380
- output({ ok: true, message: "Config synced", server_plugins: result.server_plugins || null });
451
+ output({
452
+ ok: true,
453
+ message: "Config synced",
454
+ server_plugins: result.server_plugins || null,
455
+ });
381
456
  return;
382
457
  }
383
458
 
@@ -413,9 +488,9 @@ async function main() {
413
488
  }
414
489
 
415
490
  if (positional[0] === "discover") {
416
- const intent = flags.intent ? String(flags.intent) : ""
417
- const result = discoverPluginsByIntent(intent, { limit: flags.limit })
418
- output(result)
491
+ const intent = flags.intent ? String(flags.intent) : "";
492
+ const result = discoverPluginsByIntent(intent, { limit: flags.limit });
493
+ output(result);
419
494
  return;
420
495
  }
421
496
 
@@ -435,12 +510,23 @@ async function main() {
435
510
 
436
511
  if (positional[0] === "commands") {
437
512
  const config = await loadConfig(SERVER);
438
- const namespaceFilter = flags.namespace ? String(flags.namespace).toLowerCase().trim() : ""
439
- const resourceFilter = flags.resource ? String(flags.resource).toLowerCase().trim() : ""
440
- const actionFilter = flags.action ? String(flags.action).toLowerCase().trim() : ""
441
- const queryFilter = flags.query ? String(flags.query).toLowerCase().trim() : ""
442
- const limit = flags.limit === undefined ? null : Number(flags.limit)
443
- if (flags.limit !== undefined && (!Number.isFinite(limit) || limit <= 0 || !Number.isInteger(limit))) {
513
+ const namespaceFilter = flags.namespace
514
+ ? String(flags.namespace).toLowerCase().trim()
515
+ : "";
516
+ const resourceFilter = flags.resource
517
+ ? String(flags.resource).toLowerCase().trim()
518
+ : "";
519
+ const actionFilter = flags.action
520
+ ? String(flags.action).toLowerCase().trim()
521
+ : "";
522
+ const queryFilter = flags.query
523
+ ? String(flags.query).toLowerCase().trim()
524
+ : "";
525
+ const limit = flags.limit === undefined ? null : Number(flags.limit);
526
+ if (
527
+ flags.limit !== undefined &&
528
+ (!Number.isFinite(limit) || limit <= 0 || !Number.isInteger(limit))
529
+ ) {
444
530
  outputError({
445
531
  code: 85,
446
532
  type: "invalid_argument",
@@ -463,18 +549,22 @@ async function main() {
463
549
  }));
464
550
 
465
551
  rows = rows.filter((row) => {
466
- if (namespaceFilter && row.namespace.toLowerCase() !== namespaceFilter) return false
467
- if (resourceFilter && row.resource.toLowerCase() !== resourceFilter) return false
468
- if (actionFilter && row.action.toLowerCase() !== actionFilter) return false
552
+ if (namespaceFilter && row.namespace.toLowerCase() !== namespaceFilter)
553
+ return false;
554
+ if (resourceFilter && row.resource.toLowerCase() !== resourceFilter)
555
+ return false;
556
+ if (actionFilter && row.action.toLowerCase() !== actionFilter)
557
+ return false;
469
558
  if (queryFilter) {
470
- const haystack = `${row.command} ${row.description} ${row.adapter} ${row.args}`.toLowerCase()
471
- if (!haystack.includes(queryFilter)) return false
559
+ const haystack =
560
+ `${row.command} ${row.description} ${row.adapter} ${row.args}`.toLowerCase();
561
+ if (!haystack.includes(queryFilter)) return false;
472
562
  }
473
- return true
474
- })
563
+ return true;
564
+ });
475
565
 
476
- const total = rows.length
477
- if (limit !== null) rows = rows.slice(0, limit)
566
+ const total = rows.length;
567
+ if (limit !== null) rows = rows.slice(0, limit);
478
568
 
479
569
  if (humanMode) {
480
570
  console.log("\n ⚡ Commands\n");
@@ -484,7 +574,7 @@ async function main() {
484
574
  { key: "args", label: "Args" },
485
575
  { key: "description", label: "Description" },
486
576
  ]);
487
- console.log(` Returned: ${rows.length}/${total}`)
577
+ console.log(` Returned: ${rows.length}/${total}`);
488
578
  console.log("");
489
579
  } else {
490
580
  output({
@@ -654,45 +744,6 @@ async function main() {
654
744
  return;
655
745
  }
656
746
 
657
- {
658
- const config = await loadConfig(SERVER);
659
- const passthrough = findNamespacePassthrough(config, positional, rawArgs);
660
- if (passthrough) {
661
- const start = Date.now();
662
- const result = await execute(
663
- passthrough.command,
664
- {
665
- __rawArgs: passthrough.passthroughArgs,
666
- __passthroughInteractive: humanMode && isTTY,
667
- },
668
- {
669
- server: SERVER || "",
670
- config,
671
- onStreamEvent: passthrough.command.adapterConfig && passthrough.command.adapterConfig.stream === "jsonl"
672
- ? makeStreamEmitter(`${passthrough.namespace}.passthrough`)
673
- : null,
674
- },
675
- );
676
- const duration = Date.now() - start;
677
- const envelope = {
678
- version: "1.0",
679
- command: `${passthrough.namespace}.passthrough`,
680
- duration_ms: duration,
681
- data: result,
682
- };
683
-
684
- if (humanMode && result && typeof result === "object" && result.passthrough === true) {
685
- return;
686
- }
687
- if (humanMode && result && typeof result === "object" && typeof result.raw === "string") {
688
- console.log(result.raw);
689
- } else {
690
- output(envelope);
691
- }
692
- return;
693
- }
694
- }
695
-
696
747
  if (positional.length === 1) {
697
748
  const config = await loadConfig(SERVER);
698
749
  const cmds = config.commands.filter((c) => c.namespace === positional[0]);
@@ -812,9 +863,10 @@ async function main() {
812
863
  const result = await execute(cmd, uFlags, {
813
864
  server: SERVER || "",
814
865
  config,
815
- onStreamEvent: cmd.adapterConfig && cmd.adapterConfig.stream === "jsonl"
816
- ? makeStreamEmitter(`${namespace}.${resource}.${action}`)
817
- : null,
866
+ onStreamEvent:
867
+ cmd.adapterConfig && cmd.adapterConfig.stream === "jsonl"
868
+ ? makeStreamEmitter(`${namespace}.${resource}.${action}`)
869
+ : null,
818
870
  });
819
871
  const duration = Date.now() - start;
820
872
 
@@ -874,4 +926,68 @@ async function main() {
874
926
  }
875
927
  }
876
928
 
929
+ function displayComprehensiveHelp() {
930
+ console.log("\n ⚡ SuperCLI - Universal Capability Router for AI Agents\n");
931
+ console.log(" Repository: https://github.com/javimosch/supercli\n");
932
+ console.log(
933
+ " Discover and execute capabilities across CLIs, APIs, MCP servers, workflows, and custom automations through a single agent-friendly interface.\n",
934
+ );
935
+
936
+ console.log(" 📋 QUICK OVERVIEW:");
937
+ console.log(" • Capabilities: namespace.resource.action commands");
938
+ console.log(" • Plugin System: Install external CLIs as harnesses");
939
+ console.log(" • MCP Support: Model Context Protocol server integration");
940
+ console.log(" • Skill Docs: Agent-facing guidance in SKILL.md format");
941
+ console.log(" • AI Integration: Natural language query execution\n");
942
+
943
+ console.log(" 🚀 GETTING STARTED:");
944
+ console.log(" supercli help # List available harnesses");
945
+ console.log(
946
+ " supercli skills teach # Learn about skill documents",
947
+ );
948
+ console.log(" supercli plugins explore # Browse available plugins");
949
+ console.log(
950
+ ' supercli discover --intent "<task>" # Find capabilities for a task\n',
951
+ );
952
+
953
+ console.log(" 🔧 CORE COMMANDS:");
954
+ console.log(
955
+ " supercli <namespace> <resource> <action> # Execute capability",
956
+ );
957
+ console.log(
958
+ " supercli inspect <ns> <res> <act> # View command details",
959
+ );
960
+ console.log(
961
+ " supercli plan <ns> <res> <act> # Create execution plan",
962
+ );
963
+ console.log(" supercli execute <plan_id> # Run stored plan");
964
+ console.log(
965
+ ' supercli ask "<query>" # Natural language execution\n',
966
+ );
967
+
968
+ console.log(" 🧩 PLUGIN MANAGEMENT:");
969
+ console.log(" supercli plugins list # Show installed plugins");
970
+ console.log(" supercli plugins install <name> # Install a plugin");
971
+ console.log(" supercli plugins explore # Browse plugin registry\n");
972
+
973
+ console.log(" 📖 DOCUMENTATION & RESOURCES:");
974
+ console.log(" Full README: https://github.com/javimosch/supercli#readme");
975
+ console.log(" Supported Harnesses: docs/supported-harnesses.md");
976
+ console.log(" Plugin Creation Guide: docs/plugin-harness-guide.md\n");
977
+
978
+ console.log(" 🏷️ OUTPUT MODES:");
979
+ console.log(" (default) JSON if piped, human-readable if TTY");
980
+ console.log(" --json Structured JSON envelope");
981
+ console.log(" --human Formatted tables and key-value output");
982
+ console.log(" --compact Compressed JSON (shortened keys)\n");
983
+
984
+ console.log(" 🐛 EXIT CODES:");
985
+ console.log(" 0 success");
986
+ console.log(" 82 validation_error");
987
+ console.log(" 85 invalid_argument");
988
+ console.log(" 92 resource_not_found");
989
+ console.log(" 105 integration_error");
990
+ console.log(" 110 internal_error\n");
991
+ }
992
+
877
993
  main();