@skillport/cli 0.1.6 → 0.1.7
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 +345 -7
- package/package.json +4 -4
package/dist/index.js
CHANGED
|
@@ -2765,34 +2765,227 @@ async function publishCommand(sspPath) {
|
|
|
2765
2765
|
}
|
|
2766
2766
|
}
|
|
2767
2767
|
const result = await response.json();
|
|
2768
|
-
|
|
2768
|
+
if (result.status === "published") {
|
|
2769
|
+
console.log(chalk11.green("Version updated successfully!"));
|
|
2770
|
+
} else {
|
|
2771
|
+
console.log(chalk11.green("Uploaded as draft."));
|
|
2772
|
+
}
|
|
2769
2773
|
console.log();
|
|
2770
2774
|
console.log(` ${chalk11.bold("Skill ID:")} ${result.id}`);
|
|
2771
2775
|
console.log(` ${chalk11.bold("SSP ID:")} ${result.ssp_id}`);
|
|
2772
2776
|
console.log(` ${chalk11.bold("Version:")} ${result.version}`);
|
|
2777
|
+
console.log(` ${chalk11.bold("Status:")} ${result.status === "published" ? chalk11.green("published") : chalk11.yellow(result.status || "draft")}`);
|
|
2773
2778
|
console.log(` ${chalk11.bold("Scan:")} ${result.scan_passed ? chalk11.green("PASSED") : chalk11.red("FAILED")}`);
|
|
2774
2779
|
console.log(` ${chalk11.bold("Risk Score:")} ${result.risk_score}/100`);
|
|
2775
2780
|
console.log();
|
|
2776
|
-
|
|
2777
|
-
|
|
2781
|
+
if (result.status === "published") {
|
|
2782
|
+
console.log(chalk11.dim(` URL: ${config.marketplace_web_url}/skills/${result.id}`));
|
|
2783
|
+
console.log(chalk11.dim(` Install: skillport install ${result.ssp_id}@${result.version}`));
|
|
2784
|
+
} else {
|
|
2785
|
+
console.log(chalk11.dim(` Go to Dashboard to publish: ${config.marketplace_web_url}/dashboard`));
|
|
2786
|
+
}
|
|
2778
2787
|
} catch (error) {
|
|
2779
2788
|
console.log(chalk11.red(`Upload failed: ${error.message}`));
|
|
2780
2789
|
process.exitCode = 1;
|
|
2781
2790
|
}
|
|
2782
2791
|
}
|
|
2783
2792
|
|
|
2793
|
+
// src/commands/whoami.ts
|
|
2794
|
+
import { existsSync as existsSync6 } from "node:fs";
|
|
2795
|
+
import chalk12 from "chalk";
|
|
2796
|
+
init_config();
|
|
2797
|
+
function gather() {
|
|
2798
|
+
const cfgPath = configPath();
|
|
2799
|
+
const cfgExists = existsSync6(cfgPath);
|
|
2800
|
+
const config = loadConfig();
|
|
2801
|
+
const keysExist = hasKeys();
|
|
2802
|
+
let localKeyId = null;
|
|
2803
|
+
if (keysExist) {
|
|
2804
|
+
try {
|
|
2805
|
+
const pem = loadPublicKey2();
|
|
2806
|
+
localKeyId = computeKeyId(pem);
|
|
2807
|
+
} catch {
|
|
2808
|
+
}
|
|
2809
|
+
}
|
|
2810
|
+
return {
|
|
2811
|
+
config_path: cfgPath,
|
|
2812
|
+
config_exists: cfgExists,
|
|
2813
|
+
marketplace_url: config.marketplace_url,
|
|
2814
|
+
marketplace_web_url: config.marketplace_web_url,
|
|
2815
|
+
authenticated: !!config.auth_token,
|
|
2816
|
+
default_key_id: config.default_key_id ?? null,
|
|
2817
|
+
keys_exist: keysExist,
|
|
2818
|
+
local_key_id: localKeyId
|
|
2819
|
+
};
|
|
2820
|
+
}
|
|
2821
|
+
function whoamiCommand(opts) {
|
|
2822
|
+
const info = gather();
|
|
2823
|
+
if (opts.json) {
|
|
2824
|
+
console.log(JSON.stringify(info, null, 2));
|
|
2825
|
+
return;
|
|
2826
|
+
}
|
|
2827
|
+
console.log(chalk12.bold("SkillPort CLI"));
|
|
2828
|
+
console.log();
|
|
2829
|
+
console.log(` ${chalk12.bold("Config:")} ${info.config_exists ? chalk12.green(info.config_path) : chalk12.yellow("not created yet")}`);
|
|
2830
|
+
console.log(` ${chalk12.bold("API:")} ${info.marketplace_url}`);
|
|
2831
|
+
console.log(` ${chalk12.bold("Web:")} ${info.marketplace_web_url}`);
|
|
2832
|
+
console.log(` ${chalk12.bold("Authenticated:")} ${info.authenticated ? chalk12.green("yes") : chalk12.red("no")}`);
|
|
2833
|
+
console.log(` ${chalk12.bold("Signing keys:")} ${info.keys_exist ? chalk12.green("present") : chalk12.red("not found")}`);
|
|
2834
|
+
if (info.local_key_id) {
|
|
2835
|
+
console.log(` ${chalk12.bold("Key ID:")} ${info.local_key_id}`);
|
|
2836
|
+
}
|
|
2837
|
+
if (info.default_key_id) {
|
|
2838
|
+
console.log(` ${chalk12.bold("Default key:")} ${info.default_key_id}`);
|
|
2839
|
+
}
|
|
2840
|
+
}
|
|
2841
|
+
|
|
2842
|
+
// src/commands/doctor.ts
|
|
2843
|
+
import { existsSync as existsSync7 } from "node:fs";
|
|
2844
|
+
import chalk13 from "chalk";
|
|
2845
|
+
init_config();
|
|
2846
|
+
async function fetchHealth(url, timeoutMs = 5e3) {
|
|
2847
|
+
try {
|
|
2848
|
+
const controller = new AbortController();
|
|
2849
|
+
const timer = setTimeout(() => controller.abort(), timeoutMs);
|
|
2850
|
+
const res = await fetch(`${url}/health`, { signal: controller.signal });
|
|
2851
|
+
clearTimeout(timer);
|
|
2852
|
+
return res.ok;
|
|
2853
|
+
} catch {
|
|
2854
|
+
return false;
|
|
2855
|
+
}
|
|
2856
|
+
}
|
|
2857
|
+
async function fetchWebReachable(url, timeoutMs = 5e3) {
|
|
2858
|
+
try {
|
|
2859
|
+
const controller = new AbortController();
|
|
2860
|
+
const timer = setTimeout(() => controller.abort(), timeoutMs);
|
|
2861
|
+
const res = await fetch(url, {
|
|
2862
|
+
method: "HEAD",
|
|
2863
|
+
signal: controller.signal
|
|
2864
|
+
});
|
|
2865
|
+
clearTimeout(timer);
|
|
2866
|
+
return res.ok || res.status === 308 || res.status === 307;
|
|
2867
|
+
} catch {
|
|
2868
|
+
return false;
|
|
2869
|
+
}
|
|
2870
|
+
}
|
|
2871
|
+
async function runChecks() {
|
|
2872
|
+
const checks = [];
|
|
2873
|
+
const config = loadConfig();
|
|
2874
|
+
const cfgExists = existsSync7(configPath());
|
|
2875
|
+
checks.push({
|
|
2876
|
+
name: "config",
|
|
2877
|
+
status: cfgExists ? "ok" : "warn",
|
|
2878
|
+
message: cfgExists ? `Found: ${configPath()}` : "No config file (using defaults)"
|
|
2879
|
+
});
|
|
2880
|
+
checks.push({
|
|
2881
|
+
name: "auth",
|
|
2882
|
+
status: config.auth_token ? "ok" : "warn",
|
|
2883
|
+
message: config.auth_token ? "Authenticated" : "Not logged in \u2014 run 'skillport login'"
|
|
2884
|
+
});
|
|
2885
|
+
const keysExist = hasKeys();
|
|
2886
|
+
let keyMsg = "Not found \u2014 run 'skillport init'";
|
|
2887
|
+
if (keysExist) {
|
|
2888
|
+
try {
|
|
2889
|
+
const pem = loadPublicKey2();
|
|
2890
|
+
const kid = computeKeyId(pem);
|
|
2891
|
+
keyMsg = `Present (key ID: ${kid})`;
|
|
2892
|
+
} catch {
|
|
2893
|
+
keyMsg = "Files exist but unreadable";
|
|
2894
|
+
}
|
|
2895
|
+
}
|
|
2896
|
+
checks.push({
|
|
2897
|
+
name: "keys",
|
|
2898
|
+
status: keysExist ? "ok" : "warn",
|
|
2899
|
+
message: keyMsg
|
|
2900
|
+
});
|
|
2901
|
+
const apiOk = await fetchHealth(config.marketplace_url);
|
|
2902
|
+
checks.push({
|
|
2903
|
+
name: "api",
|
|
2904
|
+
status: apiOk ? "ok" : "fail",
|
|
2905
|
+
message: apiOk ? `Reachable: ${config.marketplace_url}` : `Unreachable: ${config.marketplace_url}`
|
|
2906
|
+
});
|
|
2907
|
+
const webOk = await fetchWebReachable(config.marketplace_web_url);
|
|
2908
|
+
checks.push({
|
|
2909
|
+
name: "web",
|
|
2910
|
+
status: webOk ? "ok" : "fail",
|
|
2911
|
+
message: webOk ? `Reachable: ${config.marketplace_web_url}` : `Unreachable: ${config.marketplace_web_url}`
|
|
2912
|
+
});
|
|
2913
|
+
if (config.auth_token && keysExist) {
|
|
2914
|
+
try {
|
|
2915
|
+
const pem = loadPublicKey2();
|
|
2916
|
+
const kid = computeKeyId(pem);
|
|
2917
|
+
const controller = new AbortController();
|
|
2918
|
+
const timer = setTimeout(() => controller.abort(), 5e3);
|
|
2919
|
+
const res = await fetch(`${config.marketplace_url}/v1/keys`, {
|
|
2920
|
+
method: "POST",
|
|
2921
|
+
headers: {
|
|
2922
|
+
"Content-Type": "application/json",
|
|
2923
|
+
Authorization: `Bearer ${config.auth_token}`
|
|
2924
|
+
},
|
|
2925
|
+
body: JSON.stringify({ public_key_pem: pem, label: "default" }),
|
|
2926
|
+
signal: controller.signal
|
|
2927
|
+
});
|
|
2928
|
+
clearTimeout(timer);
|
|
2929
|
+
if (res.ok || res.status === 409) {
|
|
2930
|
+
checks.push({
|
|
2931
|
+
name: "key_registered",
|
|
2932
|
+
status: "ok",
|
|
2933
|
+
message: `Key ${kid} is registered on marketplace`
|
|
2934
|
+
});
|
|
2935
|
+
} else {
|
|
2936
|
+
const body = await res.json().catch(() => ({}));
|
|
2937
|
+
checks.push({
|
|
2938
|
+
name: "key_registered",
|
|
2939
|
+
status: "warn",
|
|
2940
|
+
message: `Key registration check failed: ${body.error || res.statusText}`
|
|
2941
|
+
});
|
|
2942
|
+
}
|
|
2943
|
+
} catch {
|
|
2944
|
+
checks.push({
|
|
2945
|
+
name: "key_registered",
|
|
2946
|
+
status: "warn",
|
|
2947
|
+
message: "Could not verify key registration (API unreachable)"
|
|
2948
|
+
});
|
|
2949
|
+
}
|
|
2950
|
+
}
|
|
2951
|
+
const ok = checks.every((c) => c.status !== "fail");
|
|
2952
|
+
return { checks, ok };
|
|
2953
|
+
}
|
|
2954
|
+
async function doctorCommand(opts) {
|
|
2955
|
+
if (!opts.json) {
|
|
2956
|
+
console.log(chalk13.bold("SkillPort Doctor"));
|
|
2957
|
+
console.log();
|
|
2958
|
+
}
|
|
2959
|
+
const result = await runChecks();
|
|
2960
|
+
if (opts.json) {
|
|
2961
|
+
console.log(JSON.stringify(result, null, 2));
|
|
2962
|
+
} else {
|
|
2963
|
+
for (const check of result.checks) {
|
|
2964
|
+
const icon = check.status === "ok" ? chalk13.green("OK") : check.status === "warn" ? chalk13.yellow("WARN") : chalk13.red("FAIL");
|
|
2965
|
+
console.log(` [${icon}] ${chalk13.bold(check.name)}: ${check.message}`);
|
|
2966
|
+
}
|
|
2967
|
+
console.log();
|
|
2968
|
+
if (result.ok) {
|
|
2969
|
+
console.log(chalk13.green("All critical checks passed."));
|
|
2970
|
+
} else {
|
|
2971
|
+
console.log(chalk13.red("Some checks failed. See above for details."));
|
|
2972
|
+
process.exitCode = 1;
|
|
2973
|
+
}
|
|
2974
|
+
}
|
|
2975
|
+
}
|
|
2976
|
+
|
|
2784
2977
|
// src/commands/keys-register.ts
|
|
2785
2978
|
init_config();
|
|
2786
|
-
import
|
|
2979
|
+
import chalk14 from "chalk";
|
|
2787
2980
|
async function keysRegisterCommand() {
|
|
2788
2981
|
const config = loadConfig();
|
|
2789
2982
|
if (!config.auth_token) {
|
|
2790
|
-
console.log(
|
|
2983
|
+
console.log(chalk14.red("Not logged in. Run 'skillport login' first."));
|
|
2791
2984
|
process.exitCode = 1;
|
|
2792
2985
|
return;
|
|
2793
2986
|
}
|
|
2794
2987
|
if (!hasKeys()) {
|
|
2795
|
-
console.log(
|
|
2988
|
+
console.log(chalk14.red("No signing keys found. Run 'skillport init' first."));
|
|
2796
2989
|
process.exitCode = 1;
|
|
2797
2990
|
return;
|
|
2798
2991
|
}
|
|
@@ -2802,9 +2995,150 @@ async function keysRegisterCommand() {
|
|
|
2802
2995
|
}
|
|
2803
2996
|
}
|
|
2804
2997
|
|
|
2998
|
+
// src/commands/list.ts
|
|
2999
|
+
init_config();
|
|
3000
|
+
import chalk15 from "chalk";
|
|
3001
|
+
var STATUS_COLORS = {
|
|
3002
|
+
published: chalk15.green,
|
|
3003
|
+
draft: chalk15.yellow,
|
|
3004
|
+
archived: chalk15.gray,
|
|
3005
|
+
suspended: chalk15.red,
|
|
3006
|
+
pending_review: chalk15.cyan
|
|
3007
|
+
};
|
|
3008
|
+
var STATUS_LABELS = {
|
|
3009
|
+
published: "published",
|
|
3010
|
+
draft: "draft",
|
|
3011
|
+
archived: "deleted",
|
|
3012
|
+
suspended: "suspended",
|
|
3013
|
+
pending_review: "pending"
|
|
3014
|
+
};
|
|
3015
|
+
async function listCommand(opts) {
|
|
3016
|
+
const config = loadConfig();
|
|
3017
|
+
if (!config.auth_token) {
|
|
3018
|
+
console.log(chalk15.red("Not logged in. Run 'skillport login' first."));
|
|
3019
|
+
process.exitCode = 1;
|
|
3020
|
+
return;
|
|
3021
|
+
}
|
|
3022
|
+
try {
|
|
3023
|
+
const res = await fetch(`${config.marketplace_url}/v1/me/skills`, {
|
|
3024
|
+
headers: { Authorization: `Bearer ${config.auth_token}` }
|
|
3025
|
+
});
|
|
3026
|
+
if (!res.ok) {
|
|
3027
|
+
const body = await res.json().catch(() => ({}));
|
|
3028
|
+
console.log(chalk15.red(`Failed to fetch skills: ${body.error || res.statusText}`));
|
|
3029
|
+
process.exitCode = 1;
|
|
3030
|
+
return;
|
|
3031
|
+
}
|
|
3032
|
+
const skills = await res.json();
|
|
3033
|
+
if (opts.json) {
|
|
3034
|
+
console.log(JSON.stringify(skills, null, 2));
|
|
3035
|
+
return;
|
|
3036
|
+
}
|
|
3037
|
+
if (skills.length === 0) {
|
|
3038
|
+
console.log(chalk15.dim("No skills found. Publish your first skill with:"));
|
|
3039
|
+
console.log(chalk15.dim(" skillport export ./my-skill -o my-skill.ssp && skillport publish my-skill.ssp"));
|
|
3040
|
+
return;
|
|
3041
|
+
}
|
|
3042
|
+
console.log(chalk15.bold(`Your Skills (${skills.length})`));
|
|
3043
|
+
console.log();
|
|
3044
|
+
const idWidth = Math.max(4, ...skills.map((s) => s.ssp_id.length));
|
|
3045
|
+
const titleWidth = Math.max(5, ...skills.map((s) => s.title.length));
|
|
3046
|
+
const statusWidth = 10;
|
|
3047
|
+
const versionWidth = 8;
|
|
3048
|
+
const dlWidth = 5;
|
|
3049
|
+
console.log(
|
|
3050
|
+
chalk15.dim(
|
|
3051
|
+
" " + "SSP ID".padEnd(idWidth + 2) + "TITLE".padEnd(titleWidth + 2) + "STATUS".padEnd(statusWidth + 2) + "VERSION".padEnd(versionWidth + 2) + "DL".padEnd(dlWidth + 2) + "ID"
|
|
3052
|
+
)
|
|
3053
|
+
);
|
|
3054
|
+
for (const skill of skills) {
|
|
3055
|
+
const colorFn = STATUS_COLORS[skill.status] || chalk15.white;
|
|
3056
|
+
const label = STATUS_LABELS[skill.status] || skill.status;
|
|
3057
|
+
console.log(
|
|
3058
|
+
" " + skill.ssp_id.padEnd(idWidth + 2) + skill.title.padEnd(titleWidth + 2) + colorFn(label.padEnd(statusWidth + 2)) + (skill.latest_version || "\u2014").padEnd(versionWidth + 2) + String(skill.downloads || 0).padEnd(dlWidth + 2) + chalk15.dim(skill.id)
|
|
3059
|
+
);
|
|
3060
|
+
}
|
|
3061
|
+
console.log();
|
|
3062
|
+
console.log(chalk15.dim(" Manage: skillport manage <skill-id> publish|unpublish|delete"));
|
|
3063
|
+
} catch (error) {
|
|
3064
|
+
console.log(chalk15.red(`Failed to fetch skills: ${error.message}`));
|
|
3065
|
+
process.exitCode = 1;
|
|
3066
|
+
}
|
|
3067
|
+
}
|
|
3068
|
+
|
|
3069
|
+
// src/commands/manage.ts
|
|
3070
|
+
init_config();
|
|
3071
|
+
import chalk16 from "chalk";
|
|
3072
|
+
var ACTION_DESC = {
|
|
3073
|
+
publish: "Publishing skill (draft \u2192 published)...",
|
|
3074
|
+
unpublish: "Unpublishing skill (published \u2192 draft)...",
|
|
3075
|
+
delete: "Deleting skill..."
|
|
3076
|
+
};
|
|
3077
|
+
var ACTION_SUCCESS = {
|
|
3078
|
+
publish: "Skill published! It is now live on the marketplace.",
|
|
3079
|
+
unpublish: "Skill unpublished. It is now in draft.",
|
|
3080
|
+
delete: "Skill deleted. It is no longer visible on the marketplace."
|
|
3081
|
+
};
|
|
3082
|
+
async function manageCommand(skillId, action) {
|
|
3083
|
+
const validActions = ["publish", "unpublish", "delete"];
|
|
3084
|
+
if (!validActions.includes(action)) {
|
|
3085
|
+
console.log(chalk16.red(`Invalid action: ${action}`));
|
|
3086
|
+
console.log(`Valid actions: ${validActions.join(", ")}`);
|
|
3087
|
+
process.exitCode = 1;
|
|
3088
|
+
return;
|
|
3089
|
+
}
|
|
3090
|
+
const config = loadConfig();
|
|
3091
|
+
if (!config.auth_token) {
|
|
3092
|
+
console.log(chalk16.red("Not logged in. Run 'skillport login' first."));
|
|
3093
|
+
process.exitCode = 1;
|
|
3094
|
+
return;
|
|
3095
|
+
}
|
|
3096
|
+
const act = action;
|
|
3097
|
+
console.log(ACTION_DESC[act]);
|
|
3098
|
+
try {
|
|
3099
|
+
let res;
|
|
3100
|
+
if (act === "delete") {
|
|
3101
|
+
res = await fetch(`${config.marketplace_url}/v1/skills/${skillId}`, {
|
|
3102
|
+
method: "DELETE",
|
|
3103
|
+
headers: { Authorization: `Bearer ${config.auth_token}` }
|
|
3104
|
+
});
|
|
3105
|
+
} else {
|
|
3106
|
+
res = await fetch(`${config.marketplace_url}/v1/skills/${skillId}/${act}`, {
|
|
3107
|
+
method: "POST",
|
|
3108
|
+
headers: { Authorization: `Bearer ${config.auth_token}` }
|
|
3109
|
+
});
|
|
3110
|
+
}
|
|
3111
|
+
if (!res.ok) {
|
|
3112
|
+
const body = await res.json().catch(() => ({}));
|
|
3113
|
+
const msg = String(body.error || res.statusText);
|
|
3114
|
+
if (res.status === 403) {
|
|
3115
|
+
console.log(chalk16.red("Permission denied. You are not the author of this skill."));
|
|
3116
|
+
} else if (res.status === 404) {
|
|
3117
|
+
console.log(chalk16.red(`Skill not found: ${skillId}`));
|
|
3118
|
+
} else {
|
|
3119
|
+
console.log(chalk16.red(`Failed: ${msg}`));
|
|
3120
|
+
}
|
|
3121
|
+
process.exitCode = 1;
|
|
3122
|
+
return;
|
|
3123
|
+
}
|
|
3124
|
+
const result = await res.json();
|
|
3125
|
+
console.log(chalk16.green(ACTION_SUCCESS[act]));
|
|
3126
|
+
console.log();
|
|
3127
|
+
console.log(` ${chalk16.bold("Skill ID:")} ${result.id}`);
|
|
3128
|
+
console.log(` ${chalk16.bold("Status:")} ${result.status}`);
|
|
3129
|
+
if (act === "publish") {
|
|
3130
|
+
console.log();
|
|
3131
|
+
console.log(chalk16.dim(` URL: ${config.marketplace_web_url}/skills/${result.id}`));
|
|
3132
|
+
}
|
|
3133
|
+
} catch (error) {
|
|
3134
|
+
console.log(chalk16.red(`Failed: ${error.message}`));
|
|
3135
|
+
process.exitCode = 1;
|
|
3136
|
+
}
|
|
3137
|
+
}
|
|
3138
|
+
|
|
2805
3139
|
// src/index.ts
|
|
2806
3140
|
var program = new Command();
|
|
2807
|
-
program.name("skillport").description("SkillPort \u2014 secure skill distribution for OpenClaw").version("0.1.
|
|
3141
|
+
program.name("skillport").description("SkillPort \u2014 open-source secure skill distribution for OpenClaw").version("0.1.7");
|
|
2808
3142
|
program.command("init").description("Generate Ed25519 key pair for signing").action(initCommand);
|
|
2809
3143
|
program.command("scan <path>").description("Run security scan on a skill directory or .ssp file").action(scanCommand);
|
|
2810
3144
|
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);
|
|
@@ -2815,6 +3149,10 @@ program.command("dry-run <ssp>").description("Run installation diagnostics witho
|
|
|
2815
3149
|
program.command("uninstall <id>").description("Uninstall an installed skill").action(uninstallCommand);
|
|
2816
3150
|
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);
|
|
2817
3151
|
program.command("publish <ssp>").description("Publish a SkillPort package to the marketplace").action(publishCommand);
|
|
3152
|
+
program.command("list").description("List your marketplace skills and their status").option("--json", "Output as JSON").action(listCommand);
|
|
3153
|
+
program.command("manage <skill-id> <action>").description("Manage a skill: publish, unpublish, or delete").action(manageCommand);
|
|
3154
|
+
program.command("whoami").description("Show current configuration and identity").option("--json", "Output as JSON").action(whoamiCommand);
|
|
3155
|
+
program.command("doctor").description("Check connectivity and setup health").option("--json", "Output as JSON").action(doctorCommand);
|
|
2818
3156
|
var keys = program.command("keys").description("Manage signing keys");
|
|
2819
3157
|
keys.command("register").description("Register your public signing key with the marketplace").action(keysRegisterCommand);
|
|
2820
3158
|
program.parse();
|
package/package.json
CHANGED
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@skillport/cli",
|
|
3
|
-
"version": "0.1.
|
|
4
|
-
"description": "SkillPort CLI — secure skill distribution for OpenClaw. Export, scan, sign, and install AI skill packages.",
|
|
3
|
+
"version": "0.1.7",
|
|
4
|
+
"description": "SkillPort CLI — open-source secure skill distribution for OpenClaw. Export, scan, sign, and install AI skill packages.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"repository": {
|
|
8
8
|
"type": "git",
|
|
9
|
-
"url": "https://github.com/
|
|
9
|
+
"url": "https://github.com/skillport-dev/skillport.git",
|
|
10
10
|
"directory": "apps/cli"
|
|
11
11
|
},
|
|
12
12
|
"homepage": "https://skillport.market",
|
|
13
|
-
"bugs": "https://github.com/
|
|
13
|
+
"bugs": "https://github.com/skillport-dev/skillport/issues",
|
|
14
14
|
"keywords": [
|
|
15
15
|
"skillport",
|
|
16
16
|
"openclaw",
|