From 4a35c27bd46189fff87e74f7d73bb58a57756409 Mon Sep 17 00:00:00 2001 From: SuperCLI Dev Date: Sun, 12 Jul 2026 13:07:05 +0000 Subject: [PATCH 1/3] docs: align package.json description with 10,000+ plugins README and branding advertise 10,000+ CLI tools (10,160 plugins in plugins/), but the npm package description still said 5,000+. Update it so the npm listing matches the actual catalog size and README. --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 76a2ad726..2e448743b 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "superacli", "version": "1.31.5", - "description": "5,000+ tools. One CLI. Zero configuration.", + "description": "10,000+ tools. One CLI. Zero configuration.", "license": "MIT", "main": "server/app.js", "bin": { From 7f685b1ae1283943e402a6e4f63d5f8847e7333f Mon Sep 17 00:00:00 2001 From: SuperCLI Dev Date: Sun, 12 Jul 2026 13:08:03 +0000 Subject: [PATCH 2/3] test: add unit tests for cli/help.js help.js had no test coverage. Cover displayJsonHelp (identity fields, output modes, exit-code shape) and renderTopLevelHelp's JSON path (namespace/resource/action grouping and dedup) plus its human-mode no-throw contract. --- __tests__/help.test.js | 96 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 96 insertions(+) create mode 100644 __tests__/help.test.js diff --git a/__tests__/help.test.js b/__tests__/help.test.js new file mode 100644 index 000000000..ee1771155 --- /dev/null +++ b/__tests__/help.test.js @@ -0,0 +1,96 @@ +"use strict" + +const { + displayJsonHelp, + renderTopLevelHelp, +} = require("../cli/help") + +// ────────────────────────────────────────────────────────────────────────────── +// displayJsonHelp +// ────────────────────────────────────────────────────────────────────────────── + +describe("displayJsonHelp", () => { + const help = displayJsonHelp() + + test("returns core identity fields", () => { + expect(help.name).toBe("SuperCLI") + expect(help.repository).toBe("https://github.com/javimosch/supercli") + expect(typeof help.description).toBe("string") + }) + + test("advertises the documented output modes", () => { + const modes = help.output_modes.join(" ") + expect(modes).toContain("--json") + expect(modes).toContain("--human") + expect(modes).toContain("--compact") + }) + + test("exposes exit codes as {code, description} pairs", () => { + expect(Array.isArray(help.exit_codes)).toBe(true) + for (const entry of help.exit_codes) { + expect(typeof entry.code).toBe("number") + expect(typeof entry.description).toBe("string") + } + }) + + test("includes the success exit code (0)", () => { + const success = help.exit_codes.find((e) => e.code === 0) + expect(success).toBeDefined() + expect(success.description).toBe("success") + }) +}) + +// ────────────────────────────────────────────────────────────────────────────── +// renderTopLevelHelp (JSON / non-human path) +// ────────────────────────────────────────────────────────────────────────────── + +describe("renderTopLevelHelp", () => { + const config = { + commands: [ + { namespace: "aws", resource: "cfn", action: "deploy" }, + { namespace: "aws", resource: "cfn", action: "delete" }, + { namespace: "aws", resource: "s3", action: "sync" }, + { namespace: "git", resource: "repo", action: "clone" }, + ], + } + + function render() { + let captured + renderTopLevelHelp(config, { + humanMode: false, + output: (payload) => { + captured = payload + }, + hasServer: false, + }) + return captured + } + + test("groups commands by namespace without duplicates", () => { + const out = render() + expect(out.namespaces.map((n) => n.name)).toEqual(["aws", "git"]) + }) + + test("nests resources and their actions under each namespace", () => { + const out = render() + const aws = out.namespaces.find((n) => n.name === "aws") + const cfn = aws.resources.find((r) => r.name === "cfn") + expect(cfn.actions).toEqual(["deploy", "delete"]) + expect(aws.resources.map((r) => r.name)).toEqual(["cfn", "s3"]) + }) + + test("does not throw and returns nothing in human mode", () => { + const logSpy = jest.spyOn(console, "log").mockImplementation(() => {}) + try { + const result = renderTopLevelHelp(config, { + humanMode: true, + output: () => {}, + hasServer: true, + }) + expect(result).toBeUndefined() + expect(logSpy).toHaveBeenCalled() + } finally { + logSpy.mockRestore() + } + }) +}) From 76880651e1d1e4bd51999b35521727ad09293535 Mon Sep 17 00:00:00 2001 From: SuperCLI Dev Date: Sun, 12 Jul 2026 13:09:28 +0000 Subject: [PATCH 3/3] test: add unit tests for cli/mcp-diagnostics helpers mcp-diagnostics.js had no test coverage. Cover commandBinary (token extraction, whitespace, empty/null coercion) and checkCommandAvailable (the missing-command short-circuit plus present/absent PATH probes). --- __tests__/mcp-diagnostics.test.js | 62 +++++++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) create mode 100644 __tests__/mcp-diagnostics.test.js diff --git a/__tests__/mcp-diagnostics.test.js b/__tests__/mcp-diagnostics.test.js new file mode 100644 index 000000000..74d2ae616 --- /dev/null +++ b/__tests__/mcp-diagnostics.test.js @@ -0,0 +1,62 @@ +"use strict" + +const { + commandBinary, + checkCommandAvailable, +} = require("../cli/mcp-diagnostics") + +// ────────────────────────────────────────────────────────────────────────────── +// commandBinary — extracts the executable name from a command string +// ────────────────────────────────────────────────────────────────────────────── + +describe("commandBinary", () => { + test("returns the first token of a command", () => { + expect(commandBinary("npx some-mcp-server --flag")).toBe("npx") + }) + + test("collapses leading/inner whitespace", () => { + expect(commandBinary(" node server.js ")).toBe("node") + }) + + test("handles a bare binary with no args", () => { + expect(commandBinary("docker")).toBe("docker") + }) + + test("returns empty string for empty / whitespace input", () => { + expect(commandBinary("")).toBe("") + expect(commandBinary(" ")).toBe("") + }) + + test("returns empty string for null/undefined", () => { + expect(commandBinary(null)).toBe("") + expect(commandBinary(undefined)).toBe("") + }) + + test("coerces non-string input via String()", () => { + expect(commandBinary(123)).toBe("123") + }) +}) + +// ────────────────────────────────────────────────────────────────────────────── +// checkCommandAvailable — the no-binary short-circuit (no process spawned) +// ────────────────────────────────────────────────────────────────────────────── + +describe("checkCommandAvailable", () => { + test("reports failure for an empty command without probing PATH", () => { + const result = checkCommandAvailable("") + expect(result.ok).toBe(false) + expect(result.message).toBe("Missing command") + }) + + test("finds a binary that exists in PATH (sh)", () => { + const result = checkCommandAvailable("sh -c 'echo hi'") + expect(result.ok).toBe(true) + expect(result.message).toContain("sh") + }) + + test("reports a clear message for a binary that does not exist", () => { + const result = checkCommandAvailable("definitely-not-a-real-binary-xyz") + expect(result.ok).toBe(false) + expect(result.message).toContain("not found in PATH") + }) +})