openclawmp 1.0.0 → 1.0.2
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/README.md +8 -11
- package/lib/api.js +65 -1
- package/lib/commands/info.js +2 -1
- package/lib/commands/install.js +2 -1
- package/lib/commands/search.js +5 -1
- package/lib/publish-flow.js +4 -2
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
**OpenClaw Marketplace CLI** — 水产市场命令行工具
|
|
4
4
|
|
|
5
|
-
A command-line client for the [OpenClaw Marketplace](https://openclawmp.
|
|
5
|
+
A command-line client for the [OpenClaw Marketplace](https://openclawmp.stepfun.com), allowing you to search, install, publish, and manage agent assets (skills, plugins, triggers, channels, and more).
|
|
6
6
|
|
|
7
7
|
## 安装
|
|
8
8
|
|
|
@@ -27,9 +27,6 @@ openclawmp info 6c476a36955a4270a3fa303beeeed5ee
|
|
|
27
27
|
# 安装资产
|
|
28
28
|
openclawmp install skill/7c19dc4c3244418096f1dcb59c93f795
|
|
29
29
|
|
|
30
|
-
# 安装指定版本
|
|
31
|
-
openclawmp install skill/7c19dc4c3244418096f1dcb59c93f795@1.0.3
|
|
32
|
-
|
|
33
30
|
# 列出本地已安装资产
|
|
34
31
|
openclawmp list
|
|
35
32
|
|
|
@@ -106,12 +103,12 @@ cat .metadata.json
|
|
|
106
103
|
|
|
107
104
|
```json
|
|
108
105
|
{
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
106
|
+
"assetType": "skill",
|
|
107
|
+
"name": "my-skill",
|
|
108
|
+
"displayName": "My Skill",
|
|
109
|
+
"semver": "1.0.0",
|
|
110
|
+
"category": "productivity",
|
|
111
|
+
"tags": ["agent", "automation"]
|
|
115
112
|
}
|
|
116
113
|
```
|
|
117
114
|
|
|
@@ -201,7 +198,7 @@ openclawmp search 天气 --page-size 10
|
|
|
201
198
|
- 不再通过 CLI 参数补录 `assetType`、`name`、`displayName`、`semver`
|
|
202
199
|
- `assetId` 可写在 `.metadata.json`,也可以通过 `--asset-id` 或目录根部 `.assetid` 透传
|
|
203
200
|
- `objectId` 由上传完成后自动生成,登录态始终必需
|
|
204
|
-
-
|
|
201
|
+
- 默认不打印请求预览或请求头明细;加 `--verbose` 会额外输出接口 URL、入参与返回详情
|
|
205
202
|
|
|
206
203
|
## 默认配置来源
|
|
207
204
|
|
package/lib/api.js
CHANGED
|
@@ -79,14 +79,68 @@ function detectTokenPrefix(token) {
|
|
|
79
79
|
return text;
|
|
80
80
|
}
|
|
81
81
|
|
|
82
|
+
function stringifyVerboseValue(value) {
|
|
83
|
+
if (value === undefined) {
|
|
84
|
+
return "";
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
if (typeof value === "string") {
|
|
88
|
+
const text = value.trim();
|
|
89
|
+
if (!text) {
|
|
90
|
+
return "\"\"";
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
if (text.startsWith("{") || text.startsWith("[") || text === "null") {
|
|
94
|
+
try {
|
|
95
|
+
return JSON.stringify(JSON.parse(text), null, 2);
|
|
96
|
+
} catch {
|
|
97
|
+
return value;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
return value;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
try {
|
|
105
|
+
const serialized = JSON.stringify(value, jsonReplacer, 2);
|
|
106
|
+
if (serialized !== undefined) {
|
|
107
|
+
return serialized;
|
|
108
|
+
}
|
|
109
|
+
} catch {
|
|
110
|
+
return String(value);
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
return String(value);
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
function printVerboseValue(label, value, writer) {
|
|
117
|
+
const serialized = stringifyVerboseValue(value);
|
|
118
|
+
if (!serialized) {
|
|
119
|
+
return;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
const output = typeof writer === "function" ? writer : console.log;
|
|
123
|
+
const lines = serialized.split("\n");
|
|
124
|
+
if (lines.length === 1) {
|
|
125
|
+
output(" " + label + ": " + lines[0]);
|
|
126
|
+
return;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
output(" " + label + ":");
|
|
130
|
+
lines.forEach(function eachLine(line) {
|
|
131
|
+
output(" " + line);
|
|
132
|
+
});
|
|
133
|
+
}
|
|
82
134
|
|
|
83
135
|
function createCatalogClient(options) {
|
|
84
136
|
const defaultRequestId = normalizeRequestId(options.requestId) || generateRequestId();
|
|
137
|
+
const verbose = Boolean(options.verbose);
|
|
85
138
|
|
|
86
139
|
async function unary(methodName, body, extra) {
|
|
87
140
|
const requestId = normalizeRequestId((extra && extra.requestId) || defaultRequestId);
|
|
88
141
|
const operationName = humanizeApiMethodName(methodName) || methodName || "接口调用";
|
|
89
142
|
const requestUrl = String(buildServiceUrl(options.baseUrl, CATALOG_SERVICE, methodName));
|
|
143
|
+
const requestBody = JSON.stringify(body || {}, jsonReplacer);
|
|
90
144
|
const headers = {
|
|
91
145
|
"Connect-Protocol-Version": "1",
|
|
92
146
|
"Content-Type": "application/json",
|
|
@@ -107,13 +161,17 @@ function createCatalogClient(options) {
|
|
|
107
161
|
printTerminalOperationNotice(operationName, [
|
|
108
162
|
requestId ? "request-id: " + requestId : ""
|
|
109
163
|
]);
|
|
164
|
+
if (verbose) {
|
|
165
|
+
printVerboseValue("请求地址", requestUrl);
|
|
166
|
+
printVerboseValue("入参", requestBody);
|
|
167
|
+
}
|
|
110
168
|
|
|
111
169
|
let response;
|
|
112
170
|
try {
|
|
113
171
|
response = await fetch(requestUrl, {
|
|
114
172
|
method: "POST",
|
|
115
173
|
headers,
|
|
116
|
-
body:
|
|
174
|
+
body: requestBody
|
|
117
175
|
});
|
|
118
176
|
} catch (error) {
|
|
119
177
|
printTerminalOperationFailure(operationName, [
|
|
@@ -149,6 +207,9 @@ function createCatalogClient(options) {
|
|
|
149
207
|
responseRequestId ? "request-id: " + responseRequestId : "",
|
|
150
208
|
message
|
|
151
209
|
]);
|
|
210
|
+
if (verbose) {
|
|
211
|
+
printVerboseValue("接口返回", payload, console.error);
|
|
212
|
+
}
|
|
152
213
|
throw new ApiError(message, {
|
|
153
214
|
status: response.status,
|
|
154
215
|
code: payload && payload.code,
|
|
@@ -162,6 +223,9 @@ function createCatalogClient(options) {
|
|
|
162
223
|
"HTTP " + response.status,
|
|
163
224
|
responseRequestId ? "request-id: " + responseRequestId : ""
|
|
164
225
|
]);
|
|
226
|
+
if (verbose) {
|
|
227
|
+
printVerboseValue("接口返回", payload);
|
|
228
|
+
}
|
|
165
229
|
|
|
166
230
|
return {
|
|
167
231
|
data: payload || {},
|
package/lib/commands/info.js
CHANGED
|
@@ -196,7 +196,8 @@ async function run(context) {
|
|
|
196
196
|
const client = createCatalogClient({
|
|
197
197
|
baseUrl: resolveConnectBaseUrl(parsed.options["base-url"]),
|
|
198
198
|
cliVersion: context.cliVersion,
|
|
199
|
-
requestId
|
|
199
|
+
requestId,
|
|
200
|
+
verbose: Boolean(parsed.options.verbose)
|
|
200
201
|
});
|
|
201
202
|
|
|
202
203
|
const assetResponse = await client.getAsset({
|
package/lib/commands/install.js
CHANGED
|
@@ -246,7 +246,8 @@ async function run(context) {
|
|
|
246
246
|
baseUrl: resolveConnectBaseUrl(parsed.options["base-url"]),
|
|
247
247
|
token: loadedCredentials.credentials.token,
|
|
248
248
|
cliVersion: context.cliVersion,
|
|
249
|
-
requestId
|
|
249
|
+
requestId,
|
|
250
|
+
verbose: Boolean(parsed.options.verbose)
|
|
250
251
|
});
|
|
251
252
|
|
|
252
253
|
if (parsed.options.verbose) {
|
package/lib/commands/search.js
CHANGED
|
@@ -138,6 +138,9 @@ function printSearchResult(item, index) {
|
|
|
138
138
|
if (item.latestSemver) {
|
|
139
139
|
console.log(" 版本: " + item.latestSemver);
|
|
140
140
|
}
|
|
141
|
+
if (item.assetId) {
|
|
142
|
+
console.log(" 资产ID: " + item.assetId);
|
|
143
|
+
}
|
|
141
144
|
if (item.name && item.name !== title) {
|
|
142
145
|
console.log(" 标识: " + item.name);
|
|
143
146
|
}
|
|
@@ -167,7 +170,8 @@ async function run(context) {
|
|
|
167
170
|
const client = createCatalogClient({
|
|
168
171
|
baseUrl: resolveConnectBaseUrl(parsed.options["base-url"]),
|
|
169
172
|
cliVersion: context.cliVersion,
|
|
170
|
-
requestId
|
|
173
|
+
requestId,
|
|
174
|
+
verbose: Boolean(parsed.options.verbose)
|
|
171
175
|
});
|
|
172
176
|
|
|
173
177
|
const response = await client.searchAssets({
|
package/lib/publish-flow.js
CHANGED
|
@@ -211,7 +211,8 @@ async function publishAsset(options) {
|
|
|
211
211
|
baseUrl: connectBaseUrl,
|
|
212
212
|
token: loadedCredentials.credentials.token,
|
|
213
213
|
cliVersion: options.cliVersion,
|
|
214
|
-
requestId: options.requestId
|
|
214
|
+
requestId: options.requestId,
|
|
215
|
+
verbose: Boolean(options.verbose)
|
|
215
216
|
});
|
|
216
217
|
|
|
217
218
|
if (options.verbose) {
|
|
@@ -331,7 +332,8 @@ async function publishAsset(options) {
|
|
|
331
332
|
baseUrl: resolveConnectBaseUrl(options.baseUrl),
|
|
332
333
|
token: loadedCredentials.credentials.token,
|
|
333
334
|
cliVersion: options.cliVersion,
|
|
334
|
-
requestId: options.requestId
|
|
335
|
+
requestId: options.requestId,
|
|
336
|
+
verbose: Boolean(options.verbose)
|
|
335
337
|
});
|
|
336
338
|
const abortUploadRequest = { uploadId };
|
|
337
339
|
await client.abortUpload(abortUploadRequest);
|