@skillport/cli 0.1.2 → 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.
- package/dist/index.js +33 -14
- 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 {
|
|
81
|
+
return {
|
|
82
|
+
marketplace_url: DEFAULT_MARKETPLACE_URL,
|
|
83
|
+
marketplace_web_url: DEFAULT_MARKETPLACE_WEB_URL
|
|
84
|
+
};
|
|
81
85
|
}
|
|
82
|
-
|
|
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,11 @@ import { createServer } from "node:http";
|
|
|
2496
2504
|
import { randomBytes } from "node:crypto";
|
|
2497
2505
|
import chalk9 from "chalk";
|
|
2498
2506
|
import inquirer4 from "inquirer";
|
|
2499
|
-
|
|
2507
|
+
var DEFAULT_HOST = "127.0.0.1";
|
|
2508
|
+
function listenOnPort(server, port, host) {
|
|
2500
2509
|
return new Promise((resolve, reject) => {
|
|
2501
2510
|
server.once("error", reject);
|
|
2502
|
-
server.listen(port, () => {
|
|
2511
|
+
server.listen(port, host, () => {
|
|
2503
2512
|
server.removeListener("error", reject);
|
|
2504
2513
|
const addr = server.address();
|
|
2505
2514
|
resolve(addr.port);
|
|
@@ -2509,7 +2518,7 @@ function listenOnPort(server, port) {
|
|
|
2509
2518
|
async function loginCommand(options) {
|
|
2510
2519
|
const config = loadConfig();
|
|
2511
2520
|
console.log(chalk9.bold("SkillPort Market Login"));
|
|
2512
|
-
console.log(chalk9.dim(`Marketplace: ${config.
|
|
2521
|
+
console.log(chalk9.dim(`Marketplace: ${config.marketplace_web_url}`));
|
|
2513
2522
|
console.log();
|
|
2514
2523
|
let method = options.method;
|
|
2515
2524
|
if (options.token) {
|
|
@@ -2545,28 +2554,32 @@ async function loginCommand(options) {
|
|
|
2545
2554
|
const state = randomBytes(16).toString("hex");
|
|
2546
2555
|
const requestedPort = options.port !== void 0 ? parseInt(options.port, 10) : 9876;
|
|
2547
2556
|
const userExplicitPort = options.port !== void 0;
|
|
2557
|
+
const bindHost = options.host || DEFAULT_HOST;
|
|
2548
2558
|
const server = createServer();
|
|
2549
2559
|
let actualPort;
|
|
2550
2560
|
try {
|
|
2551
|
-
actualPort = await listenOnPort(server, requestedPort);
|
|
2561
|
+
actualPort = await listenOnPort(server, requestedPort, bindHost);
|
|
2552
2562
|
} catch (err) {
|
|
2553
2563
|
const code = err.code;
|
|
2554
2564
|
if (code === "EADDRINUSE" && !userExplicitPort) {
|
|
2555
2565
|
console.log(chalk9.yellow(`Port ${requestedPort} in use, selecting a free port...`));
|
|
2556
|
-
actualPort = await listenOnPort(server, 0);
|
|
2566
|
+
actualPort = await listenOnPort(server, 0, bindHost);
|
|
2557
2567
|
} else {
|
|
2558
2568
|
throw err;
|
|
2559
2569
|
}
|
|
2560
2570
|
}
|
|
2561
|
-
const
|
|
2571
|
+
const callbackHost = bindHost === "::1" ? "[::1]" : bindHost;
|
|
2572
|
+
const authUrl = `${config.marketplace_web_url}/auth/cli?state=${state}&port=${actualPort}&host=${encodeURIComponent(callbackHost)}`;
|
|
2562
2573
|
if (options.browser === false) {
|
|
2563
2574
|
console.log(chalk9.bold("Open this URL in your browser to authenticate:"));
|
|
2564
2575
|
console.log();
|
|
2565
2576
|
console.log(` ${authUrl}`);
|
|
2566
2577
|
console.log();
|
|
2578
|
+
console.log(chalk9.dim(`Listening on ${callbackHost}:${actualPort}`));
|
|
2567
2579
|
console.log(chalk9.dim("Waiting for authentication callback..."));
|
|
2568
2580
|
} else {
|
|
2569
2581
|
console.log(chalk9.dim(`Opening browser to: ${authUrl}`));
|
|
2582
|
+
console.log(chalk9.dim(`Listening on ${callbackHost}:${actualPort}`));
|
|
2570
2583
|
console.log(chalk9.dim("Waiting for authentication..."));
|
|
2571
2584
|
const { exec } = await import("node:child_process");
|
|
2572
2585
|
const openCmd = process.platform === "darwin" ? "open" : process.platform === "win32" ? "start" : "xdg-open";
|
|
@@ -2575,10 +2588,16 @@ async function loginCommand(options) {
|
|
|
2575
2588
|
const token = await new Promise((resolve, reject) => {
|
|
2576
2589
|
const timeout = setTimeout(() => {
|
|
2577
2590
|
server.close();
|
|
2578
|
-
reject(new Error(
|
|
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
|
+
));
|
|
2579
2598
|
}, 6e4);
|
|
2580
2599
|
server.on("request", (req, res) => {
|
|
2581
|
-
const url = new URL(req.url || "", `http
|
|
2600
|
+
const url = new URL(req.url || "", `http://${callbackHost}:${actualPort}`);
|
|
2582
2601
|
if (url.pathname === "/callback") {
|
|
2583
2602
|
const callbackState = url.searchParams.get("state");
|
|
2584
2603
|
const accessToken = url.searchParams.get("token");
|
|
@@ -2710,7 +2729,7 @@ async function publishCommand(sspPath) {
|
|
|
2710
2729
|
console.log(` ${chalk10.bold("Scan:")} ${result.scan_passed ? chalk10.green("PASSED") : chalk10.red("FAILED")}`);
|
|
2711
2730
|
console.log(` ${chalk10.bold("Risk Score:")} ${result.risk_score}/100`);
|
|
2712
2731
|
console.log();
|
|
2713
|
-
console.log(chalk10.dim(` URL: ${config.
|
|
2732
|
+
console.log(chalk10.dim(` URL: ${config.marketplace_web_url}/skills/${result.id}`));
|
|
2714
2733
|
console.log(chalk10.dim(` Install: skillport install ${result.ssp_id}@${result.version}`));
|
|
2715
2734
|
} catch (error) {
|
|
2716
2735
|
console.log(chalk10.red(`Upload failed: ${error.message}`));
|
|
@@ -2720,7 +2739,7 @@ async function publishCommand(sspPath) {
|
|
|
2720
2739
|
|
|
2721
2740
|
// src/index.ts
|
|
2722
2741
|
var program = new Command();
|
|
2723
|
-
program.name("skillport").description("SkillPort \u2014 secure skill distribution for OpenClaw").version("0.1.
|
|
2742
|
+
program.name("skillport").description("SkillPort \u2014 secure skill distribution for OpenClaw").version("0.1.4");
|
|
2724
2743
|
program.command("init").description("Generate Ed25519 key pair for signing").action(initCommand);
|
|
2725
2744
|
program.command("scan <path>").description("Run security scan on a skill directory or .ssp file").action(scanCommand);
|
|
2726
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);
|
|
@@ -2729,6 +2748,6 @@ program.command("verify <ssp>").description("Verify SkillPort package signatures
|
|
|
2729
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);
|
|
2730
2749
|
program.command("dry-run <ssp>").description("Run installation diagnostics without installing").action(dryRunCommand);
|
|
2731
2750
|
program.command("uninstall <id>").description("Uninstall an installed skill").action(uninstallCommand);
|
|
2732
|
-
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);
|
|
2733
2752
|
program.command("publish <ssp>").description("Publish a SkillPort package to the marketplace").action(publishCommand);
|
|
2734
2753
|
program.parse();
|
package/package.json
CHANGED