howone 0.1.53 → 0.2.0
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/bin/index.mjs +362 -5
- package/package.json +1 -1
package/bin/index.mjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env bun
|
|
2
2
|
import { createRequire } from "node:module";
|
|
3
3
|
import { execFile } from "node:child_process";
|
|
4
|
-
import { readdir, rename, stat, writeFile } from "node:fs/promises";
|
|
4
|
+
import { readFile, readdir, rename, stat, writeFile } from "node:fs/promises";
|
|
5
5
|
import path from "node:path";
|
|
6
6
|
import { fileURLToPath } from "node:url";
|
|
7
7
|
import { promisify } from "node:util";
|
|
@@ -62,6 +62,18 @@ async function main() {
|
|
|
62
62
|
await runDeploy(command.options);
|
|
63
63
|
return;
|
|
64
64
|
}
|
|
65
|
+
if (scope === "capabilities" || scope === "capability" || scope === "caps") {
|
|
66
|
+
await runCapabilitiesCommand(subcommand, rest, command.options);
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
69
|
+
if (scope === "skills" || scope === "skill") {
|
|
70
|
+
await runSkillsCommand(subcommand, rest, command.options);
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
if (scope === "run") {
|
|
74
|
+
await runCapabilityRun(compact([subcommand, ...rest]), command.options);
|
|
75
|
+
return;
|
|
76
|
+
}
|
|
65
77
|
if (scope === "ai" && subcommand === "run") {
|
|
66
78
|
await runAiRun(rest, command.options);
|
|
67
79
|
return;
|
|
@@ -87,9 +99,22 @@ function parseCommand(args) {
|
|
|
87
99
|
"next",
|
|
88
100
|
"force",
|
|
89
101
|
"yes",
|
|
90
|
-
"json"
|
|
102
|
+
"json",
|
|
103
|
+
"stream"
|
|
91
104
|
],
|
|
92
|
-
string: [
|
|
105
|
+
string: [
|
|
106
|
+
"template",
|
|
107
|
+
"cwd",
|
|
108
|
+
"scope",
|
|
109
|
+
"input",
|
|
110
|
+
"output",
|
|
111
|
+
"prompt",
|
|
112
|
+
"api-url",
|
|
113
|
+
"token",
|
|
114
|
+
"status",
|
|
115
|
+
"reason"
|
|
116
|
+
],
|
|
117
|
+
number: ["limit"],
|
|
93
118
|
configuration: { "camel-case-expansion": false }
|
|
94
119
|
});
|
|
95
120
|
return {
|
|
@@ -103,6 +128,16 @@ function parseCommand(args) {
|
|
|
103
128
|
yes: Boolean(parsed.yes),
|
|
104
129
|
json: Boolean(parsed.json),
|
|
105
130
|
cwd: typeof parsed.cwd === "string" ? parsed.cwd : void 0,
|
|
131
|
+
scope: typeof parsed.scope === "string" ? parsed.scope : void 0,
|
|
132
|
+
input: typeof parsed.input === "string" ? parsed.input : void 0,
|
|
133
|
+
output: typeof parsed.output === "string" ? parsed.output : void 0,
|
|
134
|
+
prompt: typeof parsed.prompt === "string" ? parsed.prompt : void 0,
|
|
135
|
+
apiUrl: typeof parsed["api-url"] === "string" ? parsed["api-url"] : void 0,
|
|
136
|
+
token: typeof parsed.token === "string" ? parsed.token : void 0,
|
|
137
|
+
stream: Boolean(parsed.stream),
|
|
138
|
+
status: typeof parsed.status === "string" ? parsed.status : void 0,
|
|
139
|
+
limit: typeof parsed.limit === "number" && Number.isFinite(parsed.limit) ? parsed.limit : void 0,
|
|
140
|
+
reason: typeof parsed.reason === "string" ? parsed.reason : void 0,
|
|
106
141
|
help: Boolean(parsed.help) || hasHelp,
|
|
107
142
|
version: Boolean(parsed.version) || hasVersion
|
|
108
143
|
}
|
|
@@ -182,6 +217,244 @@ async function runAiRun(pathArgs, options) {
|
|
|
182
217
|
}
|
|
183
218
|
printPending("howone ai run", result.message ?? "AI run is not implemented yet.");
|
|
184
219
|
}
|
|
220
|
+
async function runCapabilitiesCommand(subcommand, pathArgs, options) {
|
|
221
|
+
if (!subcommand || subcommand === "search") {
|
|
222
|
+
const query = pathArgs.join(" ").trim();
|
|
223
|
+
if (!query) throw new CliError("E_QUERY_REQUIRED", "Search query is required.");
|
|
224
|
+
await runCapabilitySearch(query, options);
|
|
225
|
+
return;
|
|
226
|
+
}
|
|
227
|
+
if (subcommand === "list") {
|
|
228
|
+
await runCapabilityList(options);
|
|
229
|
+
return;
|
|
230
|
+
}
|
|
231
|
+
if (subcommand === "inspect" || subcommand === "show") {
|
|
232
|
+
const ref = pathArgs[0];
|
|
233
|
+
if (!ref) throw new CliError("E_CAPABILITY_REF_REQUIRED", "Capability reference is required.");
|
|
234
|
+
await runCapabilityInspect(ref, options);
|
|
235
|
+
return;
|
|
236
|
+
}
|
|
237
|
+
if (subcommand === "proposals") {
|
|
238
|
+
await runCapabilityProposals(options);
|
|
239
|
+
return;
|
|
240
|
+
}
|
|
241
|
+
if (subcommand === "apply") {
|
|
242
|
+
const proposalId = pathArgs[0];
|
|
243
|
+
if (!proposalId) throw new CliError("E_PROPOSAL_ID_REQUIRED", "Capability proposal id is required.");
|
|
244
|
+
await runCapabilityProposalAction("apply", proposalId, options);
|
|
245
|
+
return;
|
|
246
|
+
}
|
|
247
|
+
if (subcommand === "reject") {
|
|
248
|
+
const proposalId = pathArgs[0];
|
|
249
|
+
if (!proposalId) throw new CliError("E_PROPOSAL_ID_REQUIRED", "Capability proposal id is required.");
|
|
250
|
+
await runCapabilityProposalAction("reject", proposalId, options);
|
|
251
|
+
return;
|
|
252
|
+
}
|
|
253
|
+
throw new CliError("E_COMMAND_UNKNOWN", `Unknown capabilities command: ${["capabilities", subcommand].join(" ")}`);
|
|
254
|
+
}
|
|
255
|
+
async function runSkillsCommand(subcommand, pathArgs, options) {
|
|
256
|
+
const ref = pathArgs[0];
|
|
257
|
+
if (subcommand === "export") {
|
|
258
|
+
if (!ref) throw new CliError("E_SKILL_REF_REQUIRED", "Skill reference is required.");
|
|
259
|
+
await runSkillProjection("export", ref, options);
|
|
260
|
+
return;
|
|
261
|
+
}
|
|
262
|
+
if (subcommand === "install") {
|
|
263
|
+
if (!ref) throw new CliError("E_SKILL_REF_REQUIRED", "Skill reference is required.");
|
|
264
|
+
await runSkillProjection("install", ref, options);
|
|
265
|
+
return;
|
|
266
|
+
}
|
|
267
|
+
if (subcommand === "publish") {
|
|
268
|
+
if (!ref) throw new CliError("E_SKILL_REF_REQUIRED", "Skill reference is required.");
|
|
269
|
+
await runSkillProjection("publish", ref, options);
|
|
270
|
+
return;
|
|
271
|
+
}
|
|
272
|
+
throw new CliError("E_COMMAND_UNKNOWN", `Unknown skills command: ${["skills", subcommand].filter(Boolean).join(" ")}`);
|
|
273
|
+
}
|
|
274
|
+
async function runCapabilitySearch(query, options) {
|
|
275
|
+
const params = new URLSearchParams({ q: query });
|
|
276
|
+
if (options.scope) params.set("scope", options.scope);
|
|
277
|
+
await printRegistryResult("capabilities search", await callHowoneRegistryApi(`/api/capabilities/search?${params}`, {
|
|
278
|
+
options,
|
|
279
|
+
requireAuth: options.scope !== "public"
|
|
280
|
+
}), options);
|
|
281
|
+
}
|
|
282
|
+
async function runCapabilityList(options) {
|
|
283
|
+
const params = new URLSearchParams();
|
|
284
|
+
if (options.scope) params.set("scope", options.scope);
|
|
285
|
+
await printRegistryResult("capabilities list", await callHowoneRegistryApi(`/api/capabilities${params.size ? `?${params}` : ""}`, {
|
|
286
|
+
options,
|
|
287
|
+
requireAuth: options.scope !== "public"
|
|
288
|
+
}), options);
|
|
289
|
+
}
|
|
290
|
+
async function runCapabilityInspect(ref, options) {
|
|
291
|
+
const result = await callHowoneRegistryApi(`/api/capabilities/${encodeURIComponent(ref)}`, {
|
|
292
|
+
options,
|
|
293
|
+
requireAuth: options.scope !== "public"
|
|
294
|
+
});
|
|
295
|
+
await printRegistryResult(`capabilities inspect ${ref}`, result, options);
|
|
296
|
+
}
|
|
297
|
+
async function runCapabilityProposals(options) {
|
|
298
|
+
const params = new URLSearchParams();
|
|
299
|
+
if (options.status) params.set("status", options.status);
|
|
300
|
+
if (options.limit) params.set("limit", String(options.limit));
|
|
301
|
+
await printRegistryResult("capabilities proposals", await callHowoneRegistryApi(`/api/capabilities/proposals${params.size ? `?${params}` : ""}`, {
|
|
302
|
+
options,
|
|
303
|
+
requireAuth: true
|
|
304
|
+
}), options);
|
|
305
|
+
}
|
|
306
|
+
async function runCapabilityProposalAction(action, proposalId, options) {
|
|
307
|
+
const result = await callHowoneRegistryApi(`/api/capabilities/proposals/${encodeURIComponent(proposalId)}/${action}`, {
|
|
308
|
+
options,
|
|
309
|
+
requireAuth: true,
|
|
310
|
+
init: {
|
|
311
|
+
method: "POST",
|
|
312
|
+
headers: { "Content-Type": "application/json" },
|
|
313
|
+
body: JSON.stringify(action === "reject" ? { reason: options.reason } : {})
|
|
314
|
+
}
|
|
315
|
+
});
|
|
316
|
+
await printRegistryResult(`capabilities ${action} ${proposalId}`, result, options);
|
|
317
|
+
}
|
|
318
|
+
async function runCapabilityRun(pathArgs, options) {
|
|
319
|
+
const actionRef = pathArgs[0];
|
|
320
|
+
if (!actionRef && !options.prompt) throw new CliError("E_ACTION_REF_REQUIRED", "Capability action reference is required, or use --prompt for query-based routing.");
|
|
321
|
+
const input = await readCapabilityRunInput(options);
|
|
322
|
+
const body = {
|
|
323
|
+
...actionRef ? { actionRef } : {},
|
|
324
|
+
...options.prompt ? { prompt: options.prompt } : {},
|
|
325
|
+
input,
|
|
326
|
+
stream: Boolean(options.stream)
|
|
327
|
+
};
|
|
328
|
+
const result = await callHowoneRegistryApi("/api/capabilities/run", {
|
|
329
|
+
options,
|
|
330
|
+
requireAuth: true,
|
|
331
|
+
init: {
|
|
332
|
+
method: "POST",
|
|
333
|
+
headers: { "Content-Type": "application/json" },
|
|
334
|
+
body: JSON.stringify(body)
|
|
335
|
+
}
|
|
336
|
+
});
|
|
337
|
+
await printRegistryResult(actionRef ? `run ${actionRef}` : "run query", result, options);
|
|
338
|
+
}
|
|
339
|
+
async function runSkillProjection(action, ref, options) {
|
|
340
|
+
const method = action === "export" ? "GET" : "POST";
|
|
341
|
+
const result = await callHowoneRegistryApi(`/api/capabilities/skills/${encodeURIComponent(ref)}/${action}`, {
|
|
342
|
+
options,
|
|
343
|
+
requireAuth: action !== "export",
|
|
344
|
+
init: { method }
|
|
345
|
+
});
|
|
346
|
+
await printRegistryResult(`skills ${action} ${ref}`, result, options);
|
|
347
|
+
}
|
|
348
|
+
async function readCapabilityRunInput(options) {
|
|
349
|
+
if (!options.input) return {};
|
|
350
|
+
const raw = options.input.trim();
|
|
351
|
+
const content = raw.startsWith("{") || raw.startsWith("[") ? raw : await readFile(path.resolve(options.cwd ?? process.cwd(), raw), "utf-8");
|
|
352
|
+
try {
|
|
353
|
+
const parsed = JSON.parse(content);
|
|
354
|
+
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) throw new CliError("E_INPUT_INVALID", "Capability input must be a JSON object.");
|
|
355
|
+
return parsed;
|
|
356
|
+
} catch (error) {
|
|
357
|
+
if (error instanceof CliError) throw error;
|
|
358
|
+
throw new CliError("E_INPUT_INVALID", error instanceof Error ? error.message : "Invalid JSON input.");
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
function resolveHowoneApiUrl(options) {
|
|
362
|
+
return (options.apiUrl ?? process.env.HOWONE_API_URL ?? process.env.NEXT_PUBLIC_SERVER_URL ?? "https://howone.dev").replace(/\/+$/, "");
|
|
363
|
+
}
|
|
364
|
+
function resolveHowoneApiToken(options) {
|
|
365
|
+
return options.token ?? process.env.HOWONE_API_TOKEN ?? process.env.HOWONE_AGENT_TOKEN;
|
|
366
|
+
}
|
|
367
|
+
async function callHowoneRegistryApi(apiPath, args) {
|
|
368
|
+
const token = resolveHowoneApiToken(args.options);
|
|
369
|
+
if (args.requireAuth && !token) throw new CliError("E_AUTH_REQUIRED", "Set HOWONE_API_TOKEN or pass --token to access private/workspace capabilities.");
|
|
370
|
+
const url = `${resolveHowoneApiUrl(args.options)}${apiPath.startsWith("/") ? apiPath : `/${apiPath}`}`;
|
|
371
|
+
const headers = new Headers(args.init?.headers);
|
|
372
|
+
if (token) headers.set("Authorization", `Bearer ${token}`);
|
|
373
|
+
headers.set("Accept", args.options.stream ? "text/event-stream, application/json" : "application/json");
|
|
374
|
+
const response = await fetch(url, {
|
|
375
|
+
...args.init,
|
|
376
|
+
headers
|
|
377
|
+
});
|
|
378
|
+
const contentType = response.headers.get("content-type") ?? "";
|
|
379
|
+
if (args.options.stream && contentType.includes("text/event-stream")) return readSseResponse(response);
|
|
380
|
+
const text = await response.text();
|
|
381
|
+
const body = text ? parseJsonOrText(text) : null;
|
|
382
|
+
if (!response.ok) throw new CliError("E_API_REQUEST_FAILED", `HowOne API request failed: HTTP ${response.status}`, {
|
|
383
|
+
status: response.status,
|
|
384
|
+
body
|
|
385
|
+
});
|
|
386
|
+
return body;
|
|
387
|
+
}
|
|
388
|
+
async function readSseResponse(response) {
|
|
389
|
+
if (!response.ok) throw new CliError("E_API_REQUEST_FAILED", `HowOne API request failed: HTTP ${response.status}`);
|
|
390
|
+
if (!response.body) return {
|
|
391
|
+
ok: true,
|
|
392
|
+
events: []
|
|
393
|
+
};
|
|
394
|
+
const reader = response.body.getReader();
|
|
395
|
+
const decoder = new TextDecoder();
|
|
396
|
+
const events = [];
|
|
397
|
+
let buffer = "";
|
|
398
|
+
while (true) {
|
|
399
|
+
const { value, done } = await reader.read();
|
|
400
|
+
if (done) break;
|
|
401
|
+
buffer += decoder.decode(value, { stream: true });
|
|
402
|
+
let boundary = buffer.indexOf("\n\n");
|
|
403
|
+
while (boundary >= 0) {
|
|
404
|
+
const chunk = buffer.slice(0, boundary).trim();
|
|
405
|
+
buffer = buffer.slice(boundary + 2);
|
|
406
|
+
if (chunk) {
|
|
407
|
+
events.push(chunk);
|
|
408
|
+
console.log(chunk);
|
|
409
|
+
}
|
|
410
|
+
boundary = buffer.indexOf("\n\n");
|
|
411
|
+
}
|
|
412
|
+
}
|
|
413
|
+
const tail = buffer.trim();
|
|
414
|
+
if (tail) {
|
|
415
|
+
events.push(tail);
|
|
416
|
+
console.log(tail);
|
|
417
|
+
}
|
|
418
|
+
return {
|
|
419
|
+
ok: true,
|
|
420
|
+
events
|
|
421
|
+
};
|
|
422
|
+
}
|
|
423
|
+
function parseJsonOrText(text) {
|
|
424
|
+
try {
|
|
425
|
+
return JSON.parse(text);
|
|
426
|
+
} catch {
|
|
427
|
+
return text;
|
|
428
|
+
}
|
|
429
|
+
}
|
|
430
|
+
async function printRegistryResult(command, result, options) {
|
|
431
|
+
if (options.output) await writeFile(path.resolve(options.cwd ?? process.cwd(), options.output), `${JSON.stringify(result, null, 2)}\n`, "utf-8");
|
|
432
|
+
if (options.json || options.output) {
|
|
433
|
+
if (!options.output) console.log(JSON.stringify(result, null, 2));
|
|
434
|
+
return;
|
|
435
|
+
}
|
|
436
|
+
console.log(formatPanel(pc.bold(command), [formatRegistrySummary(result)]));
|
|
437
|
+
}
|
|
438
|
+
function formatRegistrySummary(result) {
|
|
439
|
+
if (typeof result === "string") return result;
|
|
440
|
+
if (!result || typeof result !== "object") return String(result);
|
|
441
|
+
const record = result;
|
|
442
|
+
const data = record.data ?? record.results ?? record.capabilities ?? record.actions;
|
|
443
|
+
if (Array.isArray(data)) {
|
|
444
|
+
if (!data.length) return "No capabilities found.";
|
|
445
|
+
return data.slice(0, 12).map((item) => {
|
|
446
|
+
if (!item || typeof item !== "object") return `- ${String(item)}`;
|
|
447
|
+
const row = item;
|
|
448
|
+
const name = row.name ?? row.title ?? row.slug ?? row.actionRef ?? row.proposalSlug ?? row.id ?? "capability";
|
|
449
|
+
const description = row.description ?? row.summary ?? row.reason ?? row.status;
|
|
450
|
+
return `- ${String(name)}${description ? `: ${String(description)}` : ""}`;
|
|
451
|
+
}).join("\n");
|
|
452
|
+
}
|
|
453
|
+
const name = record.name ?? record.title ?? record.slug ?? record.actionRef ?? record.proposalSlug ?? record.id;
|
|
454
|
+
const description = record.description ?? record.summary ?? record.reason ?? record.status;
|
|
455
|
+
if (name || description) return [name ? String(name) : void 0, description ? String(description) : void 0].filter(Boolean).join("\n");
|
|
456
|
+
return JSON.stringify(result, null, 2);
|
|
457
|
+
}
|
|
185
458
|
async function resolveCreatePlan(pathArgs, options, cwd, isInteractive) {
|
|
186
459
|
const template = resolveTemplateOption(options);
|
|
187
460
|
const projectName = pathArgs[0] === "template" ? pathArgs[1] : pathArgs[0];
|
|
@@ -417,6 +690,18 @@ function printHelp(pathArgs) {
|
|
|
417
690
|
printReservedHelp("howone deploy", "Deploy support is reserved and not implemented yet.");
|
|
418
691
|
return;
|
|
419
692
|
}
|
|
693
|
+
if (topic === "capabilities" || topic === "capabilities search") {
|
|
694
|
+
printCapabilitiesHelp();
|
|
695
|
+
return;
|
|
696
|
+
}
|
|
697
|
+
if (topic === "skills") {
|
|
698
|
+
printSkillsHelp();
|
|
699
|
+
return;
|
|
700
|
+
}
|
|
701
|
+
if (topic === "run") {
|
|
702
|
+
printRunHelp();
|
|
703
|
+
return;
|
|
704
|
+
}
|
|
420
705
|
if (topic === "ai" || topic === "ai run") {
|
|
421
706
|
printReservedHelp("howone ai run [aiId]", "AI run support is reserved and not implemented yet.");
|
|
422
707
|
return;
|
|
@@ -429,6 +714,11 @@ function printRootHelp() {
|
|
|
429
714
|
"",
|
|
430
715
|
pc.bold("Commands"),
|
|
431
716
|
formatCommand("init app [name]", "Create an app from a template"),
|
|
717
|
+
formatCommand("capabilities search <query>", "Search callable HowOne capabilities"),
|
|
718
|
+
formatCommand("capabilities inspect <ref>", "Inspect a capability package or action"),
|
|
719
|
+
formatCommand("capabilities proposals", "List generated capability proposals"),
|
|
720
|
+
formatCommand("run <package.action>", "Run a callable capability action"),
|
|
721
|
+
formatCommand("skills export <ref>", "Export a skill projection for a capability"),
|
|
432
722
|
formatCommand("create", "Reserved placeholder"),
|
|
433
723
|
formatCommand("deploy", "Reserved placeholder"),
|
|
434
724
|
formatCommand("ai run [aiId]", "Reserved placeholder"),
|
|
@@ -439,8 +729,10 @@ function printRootHelp() {
|
|
|
439
729
|
"",
|
|
440
730
|
pc.bold("Examples"),
|
|
441
731
|
` ${pc.cyan("howone init app my-app --template vite")}`,
|
|
442
|
-
` ${pc.cyan("howone
|
|
443
|
-
` ${pc.cyan("howone
|
|
732
|
+
` ${pc.cyan("howone capabilities search \"海报生成\" --scope public")}`,
|
|
733
|
+
` ${pc.cyan("howone capabilities proposals --status pending_review")}`,
|
|
734
|
+
` ${pc.cyan("howone run poster-generator.createPoster --input input.json --output result.json")}`,
|
|
735
|
+
` ${pc.cyan("howone run --prompt \"帮我生成一张 AI 发布会海报\" --stream")}`
|
|
444
736
|
]));
|
|
445
737
|
}
|
|
446
738
|
function printInitHelp() {
|
|
@@ -469,6 +761,71 @@ function printReservedHelp(command, description) {
|
|
|
469
761
|
`${pc.yellow("Pending")} This command is available as a stable placeholder.`
|
|
470
762
|
]));
|
|
471
763
|
}
|
|
764
|
+
function printCapabilitiesHelp() {
|
|
765
|
+
console.log(formatPanel(`${pc.bold("HowOne capabilities")}`, [
|
|
766
|
+
`${pc.dim("Usage")} howone capabilities <command> [options]`,
|
|
767
|
+
"",
|
|
768
|
+
pc.bold("Commands"),
|
|
769
|
+
formatCommand("search <query>", "Search private, workspace, installed, or public capabilities"),
|
|
770
|
+
formatCommand("list", "List capabilities in a scope"),
|
|
771
|
+
formatCommand("inspect <ref>", "Inspect package/action schemas and runtime bindings"),
|
|
772
|
+
formatCommand("proposals", "List generated proposals for the current user"),
|
|
773
|
+
formatCommand("apply <proposalId>", "Apply a generated proposal to the registry"),
|
|
774
|
+
formatCommand("reject <proposalId>", "Reject a generated proposal"),
|
|
775
|
+
"",
|
|
776
|
+
pc.bold("Options"),
|
|
777
|
+
formatCommand("--scope <scope>", "private, workspace, installed, public, or global"),
|
|
778
|
+
formatCommand("--status <status>", "Filter proposal list by status"),
|
|
779
|
+
formatCommand("--limit <number>", "Limit result count"),
|
|
780
|
+
formatCommand("--reason <text>", "Reason for rejecting a proposal"),
|
|
781
|
+
formatCommand("--api-url <url>", "HowOne registry API origin"),
|
|
782
|
+
formatCommand("--token <token>", "Agent API token; defaults to HOWONE_API_TOKEN"),
|
|
783
|
+
formatCommand("--json", "Print machine-readable JSON output"),
|
|
784
|
+
"",
|
|
785
|
+
pc.bold("Examples"),
|
|
786
|
+
` ${pc.cyan("howone capabilities search \"海报生成\" --scope public")}`,
|
|
787
|
+
` ${pc.cyan("howone capabilities inspect poster-generator.createPoster")}`,
|
|
788
|
+
` ${pc.cyan("howone capabilities proposals --status pending_review")}`,
|
|
789
|
+
` ${pc.cyan("howone capabilities apply 00000000-0000-0000-0000-000000000000")}`
|
|
790
|
+
]));
|
|
791
|
+
}
|
|
792
|
+
function printRunHelp() {
|
|
793
|
+
console.log(formatPanel(`${pc.bold("Run a capability")}`, [
|
|
794
|
+
`${pc.dim("Usage")} howone run <package.action> [options]`,
|
|
795
|
+
"",
|
|
796
|
+
pc.bold("Options"),
|
|
797
|
+
formatCommand("--input <json|file>", "JSON object or path to JSON input file"),
|
|
798
|
+
formatCommand("--prompt <text>", "Natural-language query routed through the registry"),
|
|
799
|
+
formatCommand("--output <file>", "Write JSON result to a file"),
|
|
800
|
+
formatCommand("--stream", "Request SSE and print events as they arrive"),
|
|
801
|
+
formatCommand("--api-url <url>", "HowOne registry API origin"),
|
|
802
|
+
formatCommand("--token <token>", "Agent API token; defaults to HOWONE_API_TOKEN"),
|
|
803
|
+
formatCommand("--json", "Print machine-readable JSON output"),
|
|
804
|
+
"",
|
|
805
|
+
pc.bold("Examples"),
|
|
806
|
+
` ${pc.cyan("howone run poster-generator.createPoster --input input.json")}`,
|
|
807
|
+
` ${pc.cyan("howone run --prompt \"帮我生成一张 AI 发布会海报\" --stream")}`
|
|
808
|
+
]));
|
|
809
|
+
}
|
|
810
|
+
function printSkillsHelp() {
|
|
811
|
+
console.log(formatPanel(`${pc.bold("HowOne skill projections")}`, [
|
|
812
|
+
`${pc.dim("Usage")} howone skills <command> <ref> [options]`,
|
|
813
|
+
"",
|
|
814
|
+
pc.bold("Commands"),
|
|
815
|
+
formatCommand("export <ref>", "Export an agent-facing skill artifact"),
|
|
816
|
+
formatCommand("install <ref>", "Install a public or workspace skill projection"),
|
|
817
|
+
formatCommand("publish <ref>", "Request publication of a capability skill projection"),
|
|
818
|
+
"",
|
|
819
|
+
pc.bold("Options"),
|
|
820
|
+
formatCommand("--api-url <url>", "HowOne registry API origin"),
|
|
821
|
+
formatCommand("--token <token>", "Agent API token; defaults to HOWONE_API_TOKEN"),
|
|
822
|
+
formatCommand("--json", "Print machine-readable JSON output"),
|
|
823
|
+
"",
|
|
824
|
+
pc.bold("Examples"),
|
|
825
|
+
` ${pc.cyan("howone skills export poster-generator")}`,
|
|
826
|
+
` ${pc.cyan("howone skills install poster-generator")}`
|
|
827
|
+
]));
|
|
828
|
+
}
|
|
472
829
|
function printPending(command, message) {
|
|
473
830
|
console.log(formatPanel(pc.bold(command), [`${pc.yellow("Pending")} ${message}`]));
|
|
474
831
|
}
|