@skillport/cli 0.1.3 → 0.1.4

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 (2) hide show
  1. package/dist/index.js +20 -9
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -2504,10 +2504,11 @@ import { createServer } from "node:http";
2504
2504
  import { randomBytes } from "node:crypto";
2505
2505
  import chalk9 from "chalk";
2506
2506
  import inquirer4 from "inquirer";
2507
- function listenOnPort(server, port) {
2507
+ var DEFAULT_HOST = "127.0.0.1";
2508
+ function listenOnPort(server, port, host) {
2508
2509
  return new Promise((resolve, reject) => {
2509
2510
  server.once("error", reject);
2510
- server.listen(port, () => {
2511
+ server.listen(port, host, () => {
2511
2512
  server.removeListener("error", reject);
2512
2513
  const addr = server.address();
2513
2514
  resolve(addr.port);
@@ -2553,28 +2554,32 @@ async function loginCommand(options) {
2553
2554
  const state = randomBytes(16).toString("hex");
2554
2555
  const requestedPort = options.port !== void 0 ? parseInt(options.port, 10) : 9876;
2555
2556
  const userExplicitPort = options.port !== void 0;
2557
+ const bindHost = options.host || DEFAULT_HOST;
2556
2558
  const server = createServer();
2557
2559
  let actualPort;
2558
2560
  try {
2559
- actualPort = await listenOnPort(server, requestedPort);
2561
+ actualPort = await listenOnPort(server, requestedPort, bindHost);
2560
2562
  } catch (err) {
2561
2563
  const code = err.code;
2562
2564
  if (code === "EADDRINUSE" && !userExplicitPort) {
2563
2565
  console.log(chalk9.yellow(`Port ${requestedPort} in use, selecting a free port...`));
2564
- actualPort = await listenOnPort(server, 0);
2566
+ actualPort = await listenOnPort(server, 0, bindHost);
2565
2567
  } else {
2566
2568
  throw err;
2567
2569
  }
2568
2570
  }
2569
- const authUrl = `${config.marketplace_web_url}/auth/cli?state=${state}&port=${actualPort}`;
2571
+ const callbackHost = bindHost === "::1" ? "[::1]" : bindHost;
2572
+ const authUrl = `${config.marketplace_web_url}/auth/cli?state=${state}&port=${actualPort}&host=${encodeURIComponent(callbackHost)}`;
2570
2573
  if (options.browser === false) {
2571
2574
  console.log(chalk9.bold("Open this URL in your browser to authenticate:"));
2572
2575
  console.log();
2573
2576
  console.log(` ${authUrl}`);
2574
2577
  console.log();
2578
+ console.log(chalk9.dim(`Listening on ${callbackHost}:${actualPort}`));
2575
2579
  console.log(chalk9.dim("Waiting for authentication callback..."));
2576
2580
  } else {
2577
2581
  console.log(chalk9.dim(`Opening browser to: ${authUrl}`));
2582
+ console.log(chalk9.dim(`Listening on ${callbackHost}:${actualPort}`));
2578
2583
  console.log(chalk9.dim("Waiting for authentication..."));
2579
2584
  const { exec } = await import("node:child_process");
2580
2585
  const openCmd = process.platform === "darwin" ? "open" : process.platform === "win32" ? "start" : "xdg-open";
@@ -2583,10 +2588,16 @@ async function loginCommand(options) {
2583
2588
  const token = await new Promise((resolve, reject) => {
2584
2589
  const timeout = setTimeout(() => {
2585
2590
  server.close();
2586
- reject(new Error("Authentication timed out (60s). Try again or use: skillport login --method token --token <your-token>"));
2591
+ reject(new Error(
2592
+ `Authentication timed out (60s).
2593
+ Listened on: ${callbackHost}:${actualPort}
2594
+ Self-test: curl http://${callbackHost}:${actualPort}/callback?state=test\\&token=test
2595
+ Retry: skillport login --yes --no-browser --port 0 --host 127.0.0.1
2596
+ Or use: skillport login --method token --token <your-token>`
2597
+ ));
2587
2598
  }, 6e4);
2588
2599
  server.on("request", (req, res) => {
2589
- const url = new URL(req.url || "", `http://localhost:${actualPort}`);
2600
+ const url = new URL(req.url || "", `http://${callbackHost}:${actualPort}`);
2590
2601
  if (url.pathname === "/callback") {
2591
2602
  const callbackState = url.searchParams.get("state");
2592
2603
  const accessToken = url.searchParams.get("token");
@@ -2728,7 +2739,7 @@ async function publishCommand(sspPath) {
2728
2739
 
2729
2740
  // src/index.ts
2730
2741
  var program = new Command();
2731
- program.name("skillport").description("SkillPort \u2014 secure skill distribution for OpenClaw").version("0.1.3");
2742
+ program.name("skillport").description("SkillPort \u2014 secure skill distribution for OpenClaw").version("0.1.4");
2732
2743
  program.command("init").description("Generate Ed25519 key pair for signing").action(initCommand);
2733
2744
  program.command("scan <path>").description("Run security scan on a skill directory or .ssp file").action(scanCommand);
2734
2745
  program.command("export <path>").description("Export a skill directory as a SkillPort package (.ssp)").option("-o, --output <file>", "Output file path").option("-y, --yes", "Non-interactive mode (include all, skip prompts)").option("--id <id>", "Skill ID (author-slug/skill-slug)").option("--name <name>", "Skill name").option("--description <desc>", "Skill description").option("--skill-version <ver>", "Skill version (semver)").option("--author <name>", "Author name").option("--openclaw-compat <range>", "OpenClaw compatibility range").option("--os <os...>", "Compatible OS (macos, linux, windows)").action(exportCommand);
@@ -2737,6 +2748,6 @@ program.command("verify <ssp>").description("Verify SkillPort package signatures
2737
2748
  program.command("install <target>").description("Install a SkillPort package").option("--accept-risk", "Accept high-risk permissions (shell, critical flags)").option("-y, --yes", "Non-interactive mode (auto-approve, use defaults)").action(installCommand);
2738
2749
  program.command("dry-run <ssp>").description("Run installation diagnostics without installing").action(dryRunCommand);
2739
2750
  program.command("uninstall <id>").description("Uninstall an installed skill").action(uninstallCommand);
2740
- program.command("login").description("Authenticate with SkillPort Market").option("--method <method>", "Login method: browser or token", "browser").option("--token <token>", "API token (for --method token)").option("-y, --yes", "Non-interactive mode (skip prompts)").option("--no-browser", "Print auth URL instead of opening browser").option("--port <port>", "Callback port (default: 9876, use 0 for auto)").action(loginCommand);
2751
+ program.command("login").description("Authenticate with SkillPort Market").option("--method <method>", "Login method: browser or token", "browser").option("--token <token>", "API token (for --method token)").option("-y, --yes", "Non-interactive mode (skip prompts)").option("--no-browser", "Print auth URL instead of opening browser").option("--port <port>", "Callback port (default: 9876, use 0 for auto)").option("--host <host>", "Callback host (default: 127.0.0.1)").action(loginCommand);
2741
2752
  program.command("publish <ssp>").description("Publish a SkillPort package to the marketplace").action(publishCommand);
2742
2753
  program.parse();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@skillport/cli",
3
- "version": "0.1.3",
3
+ "version": "0.1.4",
4
4
  "description": "SkillPort CLI — secure skill distribution for OpenClaw. Export, scan, sign, and install AI skill packages.",
5
5
  "type": "module",
6
6
  "license": "MIT",