@skillport/cli 0.1.1 → 0.1.3

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 +43 -12
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -10,7 +10,7 @@ var __export = (target, all) => {
10
10
  };
11
11
 
12
12
  // ../../packages/shared/dist/constants.js
13
- var SP_VERSION, SP_CONFIG_DIR, SP_KEYS_DIR, SP_AUDIT_DIR, SP_CONFIG_FILE, SP_REGISTRY_FILE, OPENCLAW_SKILLS_DIR, DEFAULT_MARKETPLACE_URL;
13
+ var SP_VERSION, SP_CONFIG_DIR, SP_KEYS_DIR, SP_AUDIT_DIR, SP_CONFIG_FILE, SP_REGISTRY_FILE, OPENCLAW_SKILLS_DIR, DEFAULT_MARKETPLACE_URL, DEFAULT_MARKETPLACE_WEB_URL;
14
14
  var init_constants = __esm({
15
15
  "../../packages/shared/dist/constants.js"() {
16
16
  "use strict";
@@ -22,6 +22,7 @@ var init_constants = __esm({
22
22
  SP_REGISTRY_FILE = "installed/registry.json";
23
23
  OPENCLAW_SKILLS_DIR = ".openclaw/skills";
24
24
  DEFAULT_MARKETPLACE_URL = "https://api.skillport.market";
25
+ DEFAULT_MARKETPLACE_WEB_URL = "https://skillport.market";
25
26
  }
26
27
  });
27
28
 
@@ -77,9 +78,16 @@ function registryPath() {
77
78
  function loadConfig() {
78
79
  const path = configPath();
79
80
  if (!existsSync(path)) {
80
- return { marketplace_url: DEFAULT_MARKETPLACE_URL };
81
+ return {
82
+ marketplace_url: DEFAULT_MARKETPLACE_URL,
83
+ marketplace_web_url: DEFAULT_MARKETPLACE_WEB_URL
84
+ };
81
85
  }
82
- return JSON.parse(readFileSync(path, "utf-8"));
86
+ const raw = JSON.parse(readFileSync(path, "utf-8"));
87
+ if (!raw.marketplace_web_url) {
88
+ raw.marketplace_web_url = DEFAULT_MARKETPLACE_WEB_URL;
89
+ }
90
+ return raw;
83
91
  }
84
92
  function saveConfig(config) {
85
93
  ensureConfigDirs();
@@ -2496,10 +2504,20 @@ import { createServer } from "node:http";
2496
2504
  import { randomBytes } from "node:crypto";
2497
2505
  import chalk9 from "chalk";
2498
2506
  import inquirer4 from "inquirer";
2507
+ function listenOnPort(server, port) {
2508
+ return new Promise((resolve, reject) => {
2509
+ server.once("error", reject);
2510
+ server.listen(port, () => {
2511
+ server.removeListener("error", reject);
2512
+ const addr = server.address();
2513
+ resolve(addr.port);
2514
+ });
2515
+ });
2516
+ }
2499
2517
  async function loginCommand(options) {
2500
2518
  const config = loadConfig();
2501
2519
  console.log(chalk9.bold("SkillPort Market Login"));
2502
- console.log(chalk9.dim(`Marketplace: ${config.marketplace_url}`));
2520
+ console.log(chalk9.dim(`Marketplace: ${config.marketplace_web_url}`));
2503
2521
  console.log();
2504
2522
  let method = options.method;
2505
2523
  if (options.token) {
@@ -2533,8 +2551,22 @@ async function loginCommand(options) {
2533
2551
  return;
2534
2552
  }
2535
2553
  const state = randomBytes(16).toString("hex");
2536
- const port = 9876;
2537
- const authUrl = `${config.marketplace_url}/auth/cli?state=${state}&port=${port}`;
2554
+ const requestedPort = options.port !== void 0 ? parseInt(options.port, 10) : 9876;
2555
+ const userExplicitPort = options.port !== void 0;
2556
+ const server = createServer();
2557
+ let actualPort;
2558
+ try {
2559
+ actualPort = await listenOnPort(server, requestedPort);
2560
+ } catch (err) {
2561
+ const code = err.code;
2562
+ if (code === "EADDRINUSE" && !userExplicitPort) {
2563
+ console.log(chalk9.yellow(`Port ${requestedPort} in use, selecting a free port...`));
2564
+ actualPort = await listenOnPort(server, 0);
2565
+ } else {
2566
+ throw err;
2567
+ }
2568
+ }
2569
+ const authUrl = `${config.marketplace_web_url}/auth/cli?state=${state}&port=${actualPort}`;
2538
2570
  if (options.browser === false) {
2539
2571
  console.log(chalk9.bold("Open this URL in your browser to authenticate:"));
2540
2572
  console.log();
@@ -2553,8 +2585,8 @@ async function loginCommand(options) {
2553
2585
  server.close();
2554
2586
  reject(new Error("Authentication timed out (60s). Try again or use: skillport login --method token --token <your-token>"));
2555
2587
  }, 6e4);
2556
- const server = createServer(async (req, res) => {
2557
- const url = new URL(req.url || "", `http://localhost:${port}`);
2588
+ server.on("request", (req, res) => {
2589
+ const url = new URL(req.url || "", `http://localhost:${actualPort}`);
2558
2590
  if (url.pathname === "/callback") {
2559
2591
  const callbackState = url.searchParams.get("state");
2560
2592
  const accessToken = url.searchParams.get("token");
@@ -2575,7 +2607,6 @@ async function loginCommand(options) {
2575
2607
  resolve(accessToken);
2576
2608
  }
2577
2609
  });
2578
- server.listen(port);
2579
2610
  });
2580
2611
  try {
2581
2612
  const response = await fetch(`${config.marketplace_url}/v1/auth/cli-token`, {
@@ -2687,7 +2718,7 @@ async function publishCommand(sspPath) {
2687
2718
  console.log(` ${chalk10.bold("Scan:")} ${result.scan_passed ? chalk10.green("PASSED") : chalk10.red("FAILED")}`);
2688
2719
  console.log(` ${chalk10.bold("Risk Score:")} ${result.risk_score}/100`);
2689
2720
  console.log();
2690
- console.log(chalk10.dim(` URL: ${config.marketplace_url}/skills/${result.id}`));
2721
+ console.log(chalk10.dim(` URL: ${config.marketplace_web_url}/skills/${result.id}`));
2691
2722
  console.log(chalk10.dim(` Install: skillport install ${result.ssp_id}@${result.version}`));
2692
2723
  } catch (error) {
2693
2724
  console.log(chalk10.red(`Upload failed: ${error.message}`));
@@ -2697,7 +2728,7 @@ async function publishCommand(sspPath) {
2697
2728
 
2698
2729
  // src/index.ts
2699
2730
  var program = new Command();
2700
- program.name("skillport").description("SkillPort \u2014 secure skill distribution for OpenClaw").version("0.1.1");
2731
+ program.name("skillport").description("SkillPort \u2014 secure skill distribution for OpenClaw").version("0.1.3");
2701
2732
  program.command("init").description("Generate Ed25519 key pair for signing").action(initCommand);
2702
2733
  program.command("scan <path>").description("Run security scan on a skill directory or .ssp file").action(scanCommand);
2703
2734
  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);
@@ -2706,6 +2737,6 @@ program.command("verify <ssp>").description("Verify SkillPort package signatures
2706
2737
  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);
2707
2738
  program.command("dry-run <ssp>").description("Run installation diagnostics without installing").action(dryRunCommand);
2708
2739
  program.command("uninstall <id>").description("Uninstall an installed skill").action(uninstallCommand);
2709
- 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").action(loginCommand);
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);
2710
2741
  program.command("publish <ssp>").description("Publish a SkillPort package to the marketplace").action(publishCommand);
2711
2742
  program.parse();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@skillport/cli",
3
- "version": "0.1.1",
3
+ "version": "0.1.3",
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",