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/CONTRIBUTING.md +270 -0
- package/README.md +64 -1
- package/__tests__/adapter-schema.test.js +251 -86
- package/__tests__/resend-plugin.test.js +109 -82
- package/cli/adapters/process.js +1 -5
- package/cli/plugins-manager.js +3 -3
- package/cli/supercli.js +193 -77
- package/docs/index.html +183 -123
- package/index.html +384 -0
- package/package.json +2 -2
- package/plugins/plugins.json +11 -0
- package/docs/docs.html +0 -224
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
|
|
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: [
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
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
|
-
|
|
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({
|
|
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
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
const
|
|
442
|
-
|
|
443
|
-
|
|
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)
|
|
467
|
-
|
|
468
|
-
if (
|
|
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 =
|
|
471
|
-
|
|
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:
|
|
816
|
-
|
|
817
|
-
|
|
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();
|