@hcmai/cli 0.2.0 → 0.2.1
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 +182 -44
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -4236,7 +4236,10 @@ import {
|
|
|
4236
4236
|
assertSafeReferencePath,
|
|
4237
4237
|
normalizeReferences,
|
|
4238
4238
|
parseSkillRequirements,
|
|
4239
|
+
parseSkillFrontmatter,
|
|
4239
4240
|
resolveSkillInstallOrder,
|
|
4241
|
+
resolveAllSkillsInstallOrder,
|
|
4242
|
+
flattenSkills,
|
|
4240
4243
|
matchSkills,
|
|
4241
4244
|
filterByStage,
|
|
4242
4245
|
formatObject as formatObject13,
|
|
@@ -4315,6 +4318,7 @@ function fail3(e, args) {
|
|
|
4315
4318
|
}
|
|
4316
4319
|
async function skillsListCommand(keyword, args) {
|
|
4317
4320
|
try {
|
|
4321
|
+
if (args.installed) return await listInstalledSkills(keyword, args);
|
|
4318
4322
|
const { http, endpoint, base } = await chironClient(args);
|
|
4319
4323
|
const manifest2 = await fetchSkillCatalog(http, base);
|
|
4320
4324
|
const fmt = args.output ?? "table";
|
|
@@ -4384,6 +4388,78 @@ async function skillsListCommand(keyword, args) {
|
|
|
4384
4388
|
fail3(e, args);
|
|
4385
4389
|
}
|
|
4386
4390
|
}
|
|
4391
|
+
async function listInstalledSkills(keyword, args) {
|
|
4392
|
+
const layout = await resolveInstallLayout(args);
|
|
4393
|
+
const state = await readSkillsState(layout.baseDir);
|
|
4394
|
+
const fmt = args.output ?? "table";
|
|
4395
|
+
if (!state || Object.keys(state.skills).length === 0) {
|
|
4396
|
+
if (fmt === "json" || fmt === "yaml") {
|
|
4397
|
+
process.stdout.write(formatObject13({ baseDir: layout.baseDir, target: layout.target, all: false, skills: [] }, { format: fmt }) + "\n");
|
|
4398
|
+
process.exit(0);
|
|
4399
|
+
}
|
|
4400
|
+
process.stdout.write(`${path2.join(layout.baseDir, SKILLS_STATE_FILE)} \u4E0D\u5B58\u5728\u6216\u4E3A\u7A7A \u2014\u2014 \u8FD9\u4E2A\u76EE\u5F55\u4E0B\u8FD8\u6CA1\u7528\u672C CLI \u88C5\u8FC7\u6280\u80FD\u3002
|
|
4401
|
+
`);
|
|
4402
|
+
process.stdout.write(" \u88C5\u5168\u90E8\uFF1Ahcm skills install --all\n");
|
|
4403
|
+
process.exit(0);
|
|
4404
|
+
}
|
|
4405
|
+
const rows = [];
|
|
4406
|
+
for (const [id, record] of Object.entries(state.skills).sort(([a], [b]) => a.localeCompare(b))) {
|
|
4407
|
+
const markdown = await readInstalled(layout.baseDir, id);
|
|
4408
|
+
let title = id;
|
|
4409
|
+
if (markdown !== void 0) {
|
|
4410
|
+
const raw = parseSkillFrontmatter(markdown, id).title;
|
|
4411
|
+
if (typeof raw === "string" && raw.trim()) title = raw.trim();
|
|
4412
|
+
}
|
|
4413
|
+
rows.push({
|
|
4414
|
+
id,
|
|
4415
|
+
title,
|
|
4416
|
+
direct: record.direct,
|
|
4417
|
+
installedAt: record.installedAt,
|
|
4418
|
+
// 三种状态互斥:文件没了 / 本地改过 / 和装的时候一致
|
|
4419
|
+
status: markdown === void 0 ? "missing" : sha256(markdown) !== record.sha256 ? "locally-modified" : "installed"
|
|
4420
|
+
});
|
|
4421
|
+
}
|
|
4422
|
+
const shown = keyword ? rows.filter((row) => row.id.includes(keyword) || row.title.includes(keyword)) : rows;
|
|
4423
|
+
if (fmt === "json" || fmt === "yaml") {
|
|
4424
|
+
process.stdout.write(formatObject13({
|
|
4425
|
+
baseDir: layout.baseDir,
|
|
4426
|
+
target: layout.target,
|
|
4427
|
+
endpoint: state.endpoint,
|
|
4428
|
+
all: Boolean(state.all),
|
|
4429
|
+
updatedAt: state.updatedAt,
|
|
4430
|
+
skills: shown
|
|
4431
|
+
}, { format: fmt }) + "\n");
|
|
4432
|
+
process.exit(0);
|
|
4433
|
+
}
|
|
4434
|
+
process.stdout.write(`\u5DF2\u5B89\u88C5\u7684\u777F\u620E\u6280\u80FD \u2014 ${layout.baseDir}\uFF08${layout.target}\uFF09
|
|
4435
|
+
`);
|
|
4436
|
+
process.stdout.write(`\u6765\u6E90 ${state.endpoint ?? "\uFF08\u672A\u8BB0\u5F55\uFF09"}` + (state.all ? " \u8DDF\u968F\u5168\u96C6\uFF1A\u662F\n\n" : "\n\n"));
|
|
4437
|
+
if (shown.length === 0) {
|
|
4438
|
+
process.stdout.write(` \u6CA1\u6709\u5339\u914D\u300C${keyword}\u300D\u7684\u6280\u80FD\uFF08\u5171\u88C5\u4E86 ${rows.length} \u4E2A\uFF09
|
|
4439
|
+
`);
|
|
4440
|
+
process.exit(0);
|
|
4441
|
+
}
|
|
4442
|
+
for (const row of shown) {
|
|
4443
|
+
const mark = row.status === "missing" ? "?" : row.status === "locally-modified" ? "!" : row.direct ? "\u25CF" : "\u25CB";
|
|
4444
|
+
const note = row.status === "missing" ? "\u6587\u4EF6\u4E0D\u89C1\u4E86\uFF08update \u4F1A\u88C5\u56DE\uFF09" : row.status === "locally-modified" ? "\u672C\u5730\u6539\u8FC7" : row.direct ? "" : "\u4F9D\u8D56\u5E26\u5165";
|
|
4445
|
+
process.stdout.write(` ${mark} ${row.id.padEnd(30)} ${row.title.padEnd(24)} ${note}
|
|
4446
|
+
`);
|
|
4447
|
+
}
|
|
4448
|
+
const modified = shown.filter((row) => row.status === "locally-modified").length;
|
|
4449
|
+
const missing = shown.filter((row) => row.status === "missing").length;
|
|
4450
|
+
const indirect = shown.filter((row) => row.direct === false).length;
|
|
4451
|
+
process.stdout.write("\n");
|
|
4452
|
+
process.stdout.write(` \u25CF \u76F4\u63A5\u5B89\u88C5 \u25CB \u4F9D\u8D56\u5E26\u5165 ! \u672C\u5730\u6539\u8FC7 ? \u6587\u4EF6\u7F3A\u5931
|
|
4453
|
+
`);
|
|
4454
|
+
process.stdout.write(` \u5171 ${shown.length} \u4E2A` + [
|
|
4455
|
+
indirect > 0 ? `${indirect} \u4E2A\u662F\u4F9D\u8D56\u5E26\u5165` : "",
|
|
4456
|
+
modified > 0 ? `${modified} \u4E2A\u672C\u5730\u6539\u8FC7` : "",
|
|
4457
|
+
missing > 0 ? `${missing} \u4E2A\u6587\u4EF6\u7F3A\u5931` : ""
|
|
4458
|
+
].filter(Boolean).map((t) => `\uFF0C${t}`).join("") + "\n");
|
|
4459
|
+
process.stdout.write(` \u5347\u7EA7\uFF1Ahcm skills update${state.all ? "" : "\uFF08\u60F3\u8DDF\u968F\u5168\u96C6\u52A0 --all\uFF09"}
|
|
4460
|
+
`);
|
|
4461
|
+
process.exit(0);
|
|
4462
|
+
}
|
|
4387
4463
|
async function skillsShowCommand(id, args) {
|
|
4388
4464
|
try {
|
|
4389
4465
|
const { http, base } = await chironClient(args);
|
|
@@ -4396,42 +4472,64 @@ async function skillsShowCommand(id, args) {
|
|
|
4396
4472
|
}
|
|
4397
4473
|
async function skillsInstallCommand(id, args) {
|
|
4398
4474
|
try {
|
|
4399
|
-
|
|
4475
|
+
const all = Boolean(args.all);
|
|
4476
|
+
if (all && id) throw invalid("`--all` \u662F\u88C5\u6574\u4E2A\u6280\u80FD\u5E93\uFF0C\u4E0D\u8981\u518D\u5E26\u6280\u80FD id\uFF1B\u53EA\u88C5\u4E00\u4E2A\u5C31\u53BB\u6389 --all");
|
|
4477
|
+
if (!all && !id) throw invalid("\u8981\u88C5\u54EA\u4E2A\u6280\u80FD\uFF1F\u7ED9\u4E2A id\uFF08`hcm skills list` \u770B\u76EE\u5F55\uFF09\uFF0C\u6216\u7528 `--all` \u88C5\u5168\u90E8");
|
|
4478
|
+
if (id) assertSafeSkillId(id);
|
|
4400
4479
|
const layout = await resolveInstallLayout(args);
|
|
4401
4480
|
let documents;
|
|
4481
|
+
let requestedIds;
|
|
4402
4482
|
let endpoint;
|
|
4403
4483
|
let base;
|
|
4404
4484
|
let manifest2;
|
|
4405
4485
|
if (args.from) {
|
|
4406
|
-
|
|
4486
|
+
const root = path2.resolve(args.from);
|
|
4487
|
+
requestedIds = all ? await listLocalSkillIds(root) : [id];
|
|
4488
|
+
const seen = /* @__PURE__ */ new Set();
|
|
4489
|
+
documents = [];
|
|
4490
|
+
for (const one of requestedIds) {
|
|
4491
|
+
for (const document of await resolveLocalSkillDocuments(root, one)) {
|
|
4492
|
+
if (seen.has(document.id)) continue;
|
|
4493
|
+
seen.add(document.id);
|
|
4494
|
+
documents.push(document);
|
|
4495
|
+
}
|
|
4496
|
+
}
|
|
4407
4497
|
} else {
|
|
4408
4498
|
const client3 = await chironClient(args);
|
|
4409
4499
|
endpoint = client3.endpoint;
|
|
4410
4500
|
base = client3.base;
|
|
4411
4501
|
manifest2 = await fetchSkillCatalog(client3.http, base);
|
|
4412
|
-
const order = resolveSkillInstallOrder(manifest2, id);
|
|
4413
|
-
|
|
4414
|
-
|
|
4502
|
+
const order = all ? resolveAllSkillsInstallOrder(manifest2) : resolveSkillInstallOrder(manifest2, id);
|
|
4503
|
+
if (all && order.length === 0) throw invalid(`${endpoint} \u7684\u6280\u80FD\u76EE\u5F55\u662F\u7A7A\u7684\uFF0C\u6CA1\u6709\u53EF\u88C5\u7684\u6280\u80FD`);
|
|
4504
|
+
requestedIds = all ? order.map((skill) => skill.id) : [id];
|
|
4505
|
+
documents = await mapWithConcurrency(
|
|
4506
|
+
order,
|
|
4507
|
+
FETCH_CONCURRENCY,
|
|
4508
|
+
(skill) => fetchSkillDocument(client3.http, skill, endpoint, base)
|
|
4415
4509
|
);
|
|
4416
4510
|
}
|
|
4417
|
-
const result = await installSkillDocuments(documents,
|
|
4511
|
+
const result = await installSkillDocuments(documents, requestedIds, layout.baseDir, Boolean(args.force), {
|
|
4418
4512
|
endpoint,
|
|
4419
4513
|
base,
|
|
4420
|
-
target: layout.target
|
|
4514
|
+
target: layout.target,
|
|
4515
|
+
all
|
|
4421
4516
|
});
|
|
4422
4517
|
const agents = layout.agentsFile ? await syncAgentsIndex(layout, manifest2) : void 0;
|
|
4423
4518
|
const fmt = args.output ?? "table";
|
|
4424
4519
|
if (fmt === "json" || fmt === "yaml") {
|
|
4425
|
-
process.stdout.write(formatObject13({ ...result, target_agent: layout.target, agentsFile: layout.agentsFile, agents }, { format: fmt }) + "\n");
|
|
4520
|
+
process.stdout.write(formatObject13({ ...result, all, target_agent: layout.target, agentsFile: layout.agentsFile, agents }, { format: fmt }) + "\n");
|
|
4426
4521
|
} else {
|
|
4427
|
-
|
|
4522
|
+
const headline = all ? `\u2705 \u5168\u90E8 ${requestedIds.length} \u4E2A\u6280\u80FD \u2192 ${result.baseDir}` : `\u2705 ${id} \u2192 ${path2.join(result.baseDir, id, "SKILL.md")}`;
|
|
4523
|
+
process.stdout.write(`${headline}
|
|
4428
4524
|
`);
|
|
4429
|
-
if (result.installed.length >
|
|
4430
|
-
process.stdout.write(` \
|
|
4525
|
+
if (result.installed.length > 0) {
|
|
4526
|
+
process.stdout.write(all ? ` \u65B0\u5199\u5165 ${result.installed.length} \u4E2A
|
|
4527
|
+
` : ` \u5DF2\u5B89\u88C5 ${result.installed.join(" \u2192 ")}
|
|
4431
4528
|
`);
|
|
4432
4529
|
}
|
|
4433
4530
|
if (result.unchanged.length > 0) {
|
|
4434
|
-
process.stdout.write(` \u5DF2\
|
|
4531
|
+
process.stdout.write(all ? ` \u5DF2\u662F\u8FD9\u4E00\u7248\u3001\u672A\u6539\u52A8 ${result.unchanged.length} \u4E2A
|
|
4532
|
+
` : ` \u5DF2\u5B58\u5728\u4E14\u7248\u672C\u4E00\u81F4 ${result.unchanged.join(", ")}
|
|
4435
4533
|
`);
|
|
4436
4534
|
}
|
|
4437
4535
|
const referenceCount = documents.reduce((n, d) => n + (d.references?.length ?? 0), 0);
|
|
@@ -4443,16 +4541,44 @@ async function skillsInstallCommand(id, args) {
|
|
|
4443
4541
|
process.stdout.write(` \u5DF2${agents === "created" ? "\u521B\u5EFA" : "\u66F4\u65B0"} ${layout.agentsFile} \u91CC\u7684\u6280\u80FD\u7D22\u5F15\uFF08Codex \u8BFB\u8FD9\u91CC\uFF09
|
|
4444
4542
|
`);
|
|
4445
4543
|
}
|
|
4446
|
-
process.stdout.write(` \u6765\u6E90 ${
|
|
4447
|
-
`);
|
|
4448
|
-
process.stdout.write(` \u4EA7\u54C1\u66F4\u65B0\u540E\u8DD1 hcm skills update \u5347\u7EA7
|
|
4544
|
+
process.stdout.write(` \u6765\u6E90 ${endpoint ?? path2.resolve(args.from)}
|
|
4449
4545
|
`);
|
|
4546
|
+
process.stdout.write(all ? " \u5DF2\u8BB0\u4E3A\u300C\u8DDF\u968F\u5168\u96C6\u300D\uFF1A\u4EE5\u540E\u8DD1 hcm skills update\uFF0C\u4EA7\u54C1\u65B0\u589E\u7684\u6280\u80FD\u4F1A\u81EA\u52A8\u8865\u4E0A\n" : " \u4EA7\u54C1\u66F4\u65B0\u540E\u8DD1 hcm skills update \u5347\u7EA7\n");
|
|
4450
4547
|
}
|
|
4451
4548
|
process.exit(0);
|
|
4452
4549
|
} catch (e) {
|
|
4453
4550
|
fail3(e, args);
|
|
4454
4551
|
}
|
|
4455
4552
|
}
|
|
4553
|
+
var FETCH_CONCURRENCY = 6;
|
|
4554
|
+
async function mapWithConcurrency(items, limit, fn) {
|
|
4555
|
+
const results = new Array(items.length);
|
|
4556
|
+
let cursor = 0;
|
|
4557
|
+
const worker = async () => {
|
|
4558
|
+
for (; ; ) {
|
|
4559
|
+
const index = cursor++;
|
|
4560
|
+
if (index >= items.length) return;
|
|
4561
|
+
results[index] = await fn(items[index]);
|
|
4562
|
+
}
|
|
4563
|
+
};
|
|
4564
|
+
await Promise.all(Array.from({ length: Math.min(limit, items.length) }, worker));
|
|
4565
|
+
return results;
|
|
4566
|
+
}
|
|
4567
|
+
async function listLocalSkillIds(root) {
|
|
4568
|
+
let entries;
|
|
4569
|
+
try {
|
|
4570
|
+
entries = await fsp.readdir(root, { withFileTypes: true });
|
|
4571
|
+
} catch {
|
|
4572
|
+
throw invalid(`\u8BFB\u4E0D\u5230\u672C\u5730\u6280\u80FD\u76EE\u5F55\uFF1A${root}`);
|
|
4573
|
+
}
|
|
4574
|
+
const ids = [];
|
|
4575
|
+
for (const entry of entries) {
|
|
4576
|
+
if (!entry.isDirectory()) continue;
|
|
4577
|
+
if (await exists(path2.join(root, entry.name, "SKILL.md"))) ids.push(entry.name);
|
|
4578
|
+
}
|
|
4579
|
+
if (ids.length === 0) throw invalid(`\u672C\u5730\u76EE\u5F55\u91CC\u6CA1\u6709\u4EFB\u4F55 <id>/SKILL.md\uFF1A${root}`);
|
|
4580
|
+
return ids.sort();
|
|
4581
|
+
}
|
|
4456
4582
|
async function fetchSkillDocument(http, skill, endpoint, base) {
|
|
4457
4583
|
const relatives = normalizeReferences(skill.references, skill.id);
|
|
4458
4584
|
const references = await Promise.all(relatives.map(async (relative2) => ({
|
|
@@ -4587,8 +4713,9 @@ async function upsertAgentsBlock(agentsFile, block) {
|
|
|
4587
4713
|
await fsp.writeFile(agentsFile, existing + separator + block + "\n", "utf8");
|
|
4588
4714
|
return "appended";
|
|
4589
4715
|
}
|
|
4590
|
-
async function installSkillDocuments(documents,
|
|
4591
|
-
|
|
4716
|
+
async function installSkillDocuments(documents, requestedIds, baseDir, force, meta2) {
|
|
4717
|
+
if (requestedIds.length === 0) throw invalid("\u6CA1\u6709\u6307\u5B9A\u8981\u88C5\u7684\u6280\u80FD");
|
|
4718
|
+
for (const id of requestedIds) assertSafeSkillId(id);
|
|
4592
4719
|
const seen = /* @__PURE__ */ new Set();
|
|
4593
4720
|
const candidates = documents.map((document) => {
|
|
4594
4721
|
assertSafeSkillId(document.id);
|
|
@@ -4601,36 +4728,32 @@ async function installSkillDocuments(documents, requestedId, baseDir, force, met
|
|
|
4601
4728
|
bytes: Buffer.byteLength(document.markdown)
|
|
4602
4729
|
};
|
|
4603
4730
|
});
|
|
4604
|
-
|
|
4605
|
-
|
|
4731
|
+
for (const id of requestedIds) {
|
|
4732
|
+
if (!seen.has(id)) throw invalid(`\u5B89\u88C5\u95ED\u5305\u4E0D\u5305\u542B\u76EE\u6807\u6280\u80FD: ${id}`);
|
|
4733
|
+
}
|
|
4606
4734
|
const unchanged = /* @__PURE__ */ new Set();
|
|
4607
4735
|
for (const candidate of candidates) {
|
|
4608
|
-
|
|
4609
|
-
|
|
4610
|
-
|
|
4611
|
-
|
|
4612
|
-
if (cause?.code !== "ENOENT") throw cause;
|
|
4613
|
-
}
|
|
4614
|
-
if (existing === void 0 || force) continue;
|
|
4615
|
-
if (candidate.id !== requestedId && existing === candidate.markdown) {
|
|
4736
|
+
if (force) continue;
|
|
4737
|
+
const same = await sameOnDisk(baseDir, candidate);
|
|
4738
|
+
if (same === void 0) continue;
|
|
4739
|
+
if (same) {
|
|
4616
4740
|
unchanged.add(candidate.id);
|
|
4617
4741
|
continue;
|
|
4618
4742
|
}
|
|
4619
|
-
|
|
4620
|
-
|
|
4743
|
+
throw invalid(
|
|
4744
|
+
`${candidate.target} \u5DF2\u5B58\u5728\uFF0C\u4E14\u548C\u76EE\u6807\u73AF\u5883\u8FD9\u4E00\u7248\u4E0D\u4E00\u81F4\u3002\u7528 --force \u8986\u76D6\uFF08\u4F1A\u4E22\u6389\u672C\u5730\u6539\u52A8\uFF09\uFF0C\u6216 --dir <path> \u88C5\u5230\u522B\u5904\uFF1B\u53EA\u60F3\u8DDF\u4E0A\u4EA7\u54C1\u7248\u672C\u7528 hcm skills update`
|
|
4745
|
+
);
|
|
4621
4746
|
}
|
|
4622
4747
|
const pending = candidates.filter((candidate) => !unchanged.has(candidate.id));
|
|
4623
4748
|
await writeSkillDocuments(pending, baseDir);
|
|
4624
4749
|
await recordInstalled(baseDir, candidates, {
|
|
4625
4750
|
...meta2,
|
|
4626
|
-
directIds:
|
|
4751
|
+
directIds: new Set(requestedIds),
|
|
4627
4752
|
keepInstalledAt: unchanged
|
|
4628
4753
|
});
|
|
4629
4754
|
return {
|
|
4630
|
-
|
|
4631
|
-
|
|
4632
|
-
source: requested.source,
|
|
4633
|
-
bytes: requested.bytes,
|
|
4755
|
+
ids: [...requestedIds],
|
|
4756
|
+
baseDir,
|
|
4634
4757
|
installed: pending.map((candidate) => candidate.id),
|
|
4635
4758
|
unchanged: candidates.filter((candidate) => unchanged.has(candidate.id)).map((candidate) => candidate.id),
|
|
4636
4759
|
files: candidates.map((candidate) => ({
|
|
@@ -4642,6 +4765,15 @@ async function installSkillDocuments(documents, requestedId, baseDir, force, met
|
|
|
4642
4765
|
}))
|
|
4643
4766
|
};
|
|
4644
4767
|
}
|
|
4768
|
+
async function sameOnDisk(baseDir, candidate) {
|
|
4769
|
+
const existing = await readInstalled(baseDir, candidate.id);
|
|
4770
|
+
if (existing === void 0) return void 0;
|
|
4771
|
+
if (existing !== candidate.markdown) return false;
|
|
4772
|
+
for (const reference of candidate.references ?? []) {
|
|
4773
|
+
if (await readInstalledReference(baseDir, candidate.id, reference.path) !== reference.content) return false;
|
|
4774
|
+
}
|
|
4775
|
+
return true;
|
|
4776
|
+
}
|
|
4645
4777
|
async function readLocalReferences(skillDir) {
|
|
4646
4778
|
const root = path2.join(skillDir, "references");
|
|
4647
4779
|
const out = [];
|
|
@@ -4702,6 +4834,7 @@ async function recordInstalled(baseDir, documents, meta2) {
|
|
|
4702
4834
|
if (meta2.target) state.target = meta2.target;
|
|
4703
4835
|
if (meta2.endpoint) state.endpoint = meta2.endpoint;
|
|
4704
4836
|
if (meta2.base !== void 0) state.base = meta2.base;
|
|
4837
|
+
if (meta2.all) state.all = true;
|
|
4705
4838
|
state.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
4706
4839
|
for (const document of documents) {
|
|
4707
4840
|
const previous = state.skills[document.id];
|
|
@@ -4740,11 +4873,13 @@ async function readInstalledReference(baseDir, id, relative2) {
|
|
|
4740
4873
|
}
|
|
4741
4874
|
async function planSkillUpdate(options) {
|
|
4742
4875
|
const { state, manifest: manifest2, baseDir, force, fetchDocument } = options;
|
|
4876
|
+
const all = options.all ?? Boolean(state.all);
|
|
4743
4877
|
const recorded = Object.entries(state.skills);
|
|
4744
4878
|
const directIds = recorded.some(([, r]) => r.direct) ? recorded.filter(([, r]) => r.direct).map(([id]) => id) : recorded.map(([id]) => id);
|
|
4879
|
+
const wanted = all ? [.../* @__PURE__ */ new Set([...directIds, ...flattenSkills(manifest2).map((skill) => skill.id)])] : directIds;
|
|
4745
4880
|
const entries = [];
|
|
4746
4881
|
const closure = /* @__PURE__ */ new Map();
|
|
4747
|
-
for (const id of
|
|
4882
|
+
for (const id of wanted.sort()) {
|
|
4748
4883
|
try {
|
|
4749
4884
|
for (const skill of resolveSkillInstallOrder(manifest2, id)) {
|
|
4750
4885
|
if (!closure.has(skill.id)) closure.set(skill.id, skill);
|
|
@@ -4766,7 +4901,7 @@ async function planSkillUpdate(options) {
|
|
|
4766
4901
|
entries.push({
|
|
4767
4902
|
id: skill.id,
|
|
4768
4903
|
status: "added",
|
|
4769
|
-
note: record ? "\u672C\u5730\u6587\u4EF6\u7F3A\u5931\uFF0C\u91CD\u65B0\u88C5\u56DE" : "\u4EA7\u54C1\u65B0\u589E\u7684\u524D\u7F6E\u6280\u80FD"
|
|
4904
|
+
note: record ? "\u672C\u5730\u6587\u4EF6\u7F3A\u5931\uFF0C\u91CD\u65B0\u88C5\u56DE" : all ? "\u4EA7\u54C1\u8FD9\u4E00\u7248\u65B0\u589E\u7684\u6280\u80FD" : "\u4EA7\u54C1\u65B0\u589E\u7684\u524D\u7F6E\u6280\u80FD"
|
|
4770
4905
|
});
|
|
4771
4906
|
continue;
|
|
4772
4907
|
}
|
|
@@ -4825,20 +4960,24 @@ async function skillsUpdateCommand(args) {
|
|
|
4825
4960
|
});
|
|
4826
4961
|
const { http, base } = await chironClient({ ...args, endpoint });
|
|
4827
4962
|
const manifest2 = await fetchSkillCatalog(http, base);
|
|
4963
|
+
const all = Boolean(args.all) || Boolean(state.all);
|
|
4828
4964
|
const plan = await planSkillUpdate({
|
|
4829
4965
|
state,
|
|
4830
4966
|
manifest: manifest2,
|
|
4831
4967
|
baseDir: layout.baseDir,
|
|
4832
4968
|
force: Boolean(args.force),
|
|
4969
|
+
all,
|
|
4833
4970
|
fetchDocument: (skill) => fetchSkillDocument(http, skill, endpoint, base)
|
|
4834
4971
|
});
|
|
4835
|
-
|
|
4972
|
+
const subscriptionChanged = all && !state.all;
|
|
4973
|
+
if (!args.check && (plan.documents.length > 0 || subscriptionChanged)) {
|
|
4836
4974
|
await writeSkillDocuments(plan.documents, layout.baseDir);
|
|
4837
4975
|
await recordInstalled(layout.baseDir, plan.documents, {
|
|
4838
4976
|
endpoint,
|
|
4839
4977
|
base,
|
|
4840
4978
|
target: layout.target,
|
|
4841
|
-
|
|
4979
|
+
all,
|
|
4980
|
+
directIds: all ? new Set(plan.documents.map((document) => document.id)) : /* @__PURE__ */ new Set()
|
|
4842
4981
|
});
|
|
4843
4982
|
if (layout.agentsFile) await syncAgentsIndex(layout, manifest2);
|
|
4844
4983
|
}
|
|
@@ -4850,6 +4989,7 @@ async function skillsUpdateCommand(args) {
|
|
|
4850
4989
|
baseDir: layout.baseDir,
|
|
4851
4990
|
target: layout.target,
|
|
4852
4991
|
dryRun: Boolean(args.check),
|
|
4992
|
+
all,
|
|
4853
4993
|
changed: changed.length,
|
|
4854
4994
|
entries: plan.entries
|
|
4855
4995
|
}, { format: fmt }) + "\n");
|
|
@@ -4857,9 +4997,7 @@ async function skillsUpdateCommand(args) {
|
|
|
4857
4997
|
}
|
|
4858
4998
|
process.stdout.write(`\u777F\u620E\u6280\u80FD\u5347\u7EA7 \u2014 ${endpoint}
|
|
4859
4999
|
`);
|
|
4860
|
-
process.stdout.write(`\u843D\u70B9 ${layout.baseDir}\uFF08${layout.target}\uFF09
|
|
4861
|
-
|
|
4862
|
-
`);
|
|
5000
|
+
process.stdout.write(`\u843D\u70B9 ${layout.baseDir}\uFF08${layout.target}\uFF09` + (all ? " \u8DDF\u968F\u5168\u96C6\uFF1A\u4EA7\u54C1\u65B0\u589E\u7684\u6280\u80FD\u4F1A\u81EA\u52A8\u8865\u4E0A\n\n" : "\n\n"));
|
|
4863
5001
|
for (const entry of plan.entries) {
|
|
4864
5002
|
const mark = entry.status === "unchanged" ? " " : entry.status === "locally-modified" ? "!" : "\xB7";
|
|
4865
5003
|
process.stdout.write(` ${mark} ${entry.id.padEnd(30)} ${UPDATE_STATUS_LABEL[entry.status]}
|
|
@@ -6562,10 +6700,10 @@ meta.command("get <path>").description("\u6253\u5370 meta \u539F\u6587\uFF08\u59
|
|
|
6562
6700
|
meta.command("set <path>").description("\u5199\u5165 meta \u539F\u6587\uFF1B\u5199\u5B8C\u987B hcm cache clear-meta <Model> \u624D\u751F\u6548").requiredOption("--file <file>", "\u4ECE\u6587\u4EF6\u8BFB\u53D6\u539F\u6587\uFF08- \u8868\u793A stdin\uFF09").option("--dry-run", "\u53EA\u663E\u793A\u5C06\u5199\u5165\u7684\u5185\u5BB9\uFF0C\u4E0D\u5B9E\u9645\u5199\u5165").option("--env <name>", "\u4E34\u65F6\u5207\u73AF\u5883\uFF08\u8986\u76D6 activeEnv\uFF0C\u672C\u6B21\u547D\u4EE4\uFF09").option("--as <identity>", "\u4E34\u65F6\u6362\u8EAB\u4EFD").option("--output <fmt>", "\u8F93\u51FA\u683C\u5F0F\uFF1Atable | json | yaml", "json").action((p, opts) => metaSetCommand(p, opts));
|
|
6563
6701
|
meta.command("delete <path>").description("\u5220\u9664 meta\uFF08\u4E0D\u53EF\u9006\uFF0C\u9ED8\u8BA4\u8FC7\u786E\u8BA4\u95F8\uFF09").option("-y, --yes", "\u8DF3\u8FC7\u786E\u8BA4").option("--env <name>", "\u4E34\u65F6\u5207\u73AF\u5883\uFF08\u8986\u76D6 activeEnv\uFF0C\u672C\u6B21\u547D\u4EE4\uFF09").option("--as <identity>", "\u4E34\u65F6\u6362\u8EAB\u4EFD").option("--output <fmt>", "\u8F93\u51FA\u683C\u5F0F\uFF1Atable | json | yaml", "json").action((p, opts) => metaDeleteCommand(p, opts));
|
|
6564
6702
|
var skills = program.command("skills").description("\u777F\u620E Chiron \u4EA4\u4ED8\u6280\u80FD\u5E93\uFF1A\u5217\u51FA / \u67E5\u770B / \u5B89\u88C5\u4EA4\u4ED8\u6280\u80FD\uFF08\u514D\u8BA4\u8BC1\uFF0C\u65E0\u9700\u5148 login\uFF09");
|
|
6565
|
-
skills.command("list [keyword]").description("\u5217\u51FA\u76EE\u6807\u73AF\u5883\u8FD9\u4E00\u7248\u7684\u4EA4\u4ED8\u6280\u80FD").option("--category <key>", "\u53EA\u770B\u67D0\u4E2A\u5206\u7C7B").option("--stage <key>", "\u53EA\u770B\u67D0\u4E2A\u4EA4\u4ED8\u9636\u6BB5\uFF1Ahandover | baseline | configure | migrate | integrate | golive | operate").option("--by-stage", "\u6309\u4EA4\u4ED8\u751F\u547D\u5468\u671F\u5206\u7EC4\u5C55\u793A\uFF08\u9ED8\u8BA4\u6309\u529F\u80FD\u5206\u7C7B\uFF09").option("--endpoint <url>", "\u6280\u80FD\u5E93\u5730\u5740\uFF08\u9ED8\u8BA4\u53D6 activeEnv \u7684 endpoint\uFF09").option("--env <name>", "\u4ECE\u8BE5 env \u89E3\u6790 endpoint").option("--output <fmt>", "\u8F93\u51FA\u683C\u5F0F\uFF1Atable | json | yaml", "table").action((kw, opts) => skillsListCommand(kw, opts));
|
|
6703
|
+
skills.command("list [keyword]").description("\u5217\u51FA\u76EE\u6807\u73AF\u5883\u8FD9\u4E00\u7248\u7684\u4EA4\u4ED8\u6280\u80FD\uFF1B--installed \u6539\u770B\u672C\u5730\u88C5\u4E86\u54EA\u4E9B\uFF08\u4E0D\u8FDE\u7F51\uFF09").option("--installed", "\u53EA\u770B\u672C\u5730\u5DF2\u88C5\u7684\u6280\u80FD\uFF08\u8BFB .hcm-skills.json\uFF0C\u4E0D\u8FDE\u7F51\uFF09").option("--target <agent>", "\u914D\u5408 --installed\uFF1Aclaude | codex | auto", "auto").option("--global", "\u914D\u5408 --installed\uFF1A\u770B\u7528\u6237\u7EA7\u76EE\u5F55").option("--dir <path>", "\u914D\u5408 --installed\uFF1A\u770B\u6307\u5B9A\u76EE\u5F55").option("--category <key>", "\u53EA\u770B\u67D0\u4E2A\u5206\u7C7B").option("--stage <key>", "\u53EA\u770B\u67D0\u4E2A\u4EA4\u4ED8\u9636\u6BB5\uFF1Ahandover | baseline | configure | migrate | integrate | golive | operate").option("--by-stage", "\u6309\u4EA4\u4ED8\u751F\u547D\u5468\u671F\u5206\u7EC4\u5C55\u793A\uFF08\u9ED8\u8BA4\u6309\u529F\u80FD\u5206\u7C7B\uFF09").option("--endpoint <url>", "\u6280\u80FD\u5E93\u5730\u5740\uFF08\u9ED8\u8BA4\u53D6 activeEnv \u7684 endpoint\uFF09").option("--env <name>", "\u4ECE\u8BE5 env \u89E3\u6790 endpoint").option("--output <fmt>", "\u8F93\u51FA\u683C\u5F0F\uFF1Atable | json | yaml", "table").action((kw, opts) => skillsListCommand(kw, opts));
|
|
6566
6704
|
skills.command("show <id>").description("\u6253\u5370\u6280\u80FD\u539F\u6587\uFF08\u7BA1\u9053\u53CB\u597D\uFF09").option("--endpoint <url>", "\u6280\u80FD\u5E93\u5730\u5740\uFF08\u9ED8\u8BA4\u53D6 activeEnv \u7684 endpoint\uFF09").option("--env <name>", "\u4ECE\u8BE5 env \u89E3\u6790 endpoint").action((id, opts) => skillsShowCommand(id, opts));
|
|
6567
|
-
skills.command("install
|
|
6568
|
-
skills.command("update").description("\u628A\u88C5\u8FC7\u7684\u6280\u80FD\u5347\u5230\u76EE\u6807\u73AF\u5883\u8FD9\u4E00\u7248\uFF08\u4EA7\u54C1\u5347\u7EA7\u540E\u8DD1\u5B83\uFF09").option("--check", "\u53EA\u770B\u4F1A\u53D8\u4EC0\u4E48\uFF0C\u4E0D\u5199\u76D8").option("--target <agent>", "claude | codex | auto\uFF08\u9ED8\u8BA4\u6309\u5DF2\u5B89\u88C5\u76EE\u5F55\u63A2\uFF09", "auto").option("--global", "\u5347\u7EA7\u7528\u6237\u7EA7\u76EE\u5F55\u91CC\u7684\u6280\u80FD").option("--dir <path>", "\u5347\u7EA7\u6307\u5B9A\u76EE\u5F55\u91CC\u7684\u6280\u80FD").option("--force", "\u8FDE\u672C\u5730\u6539\u8FC7\u7684\u6280\u80FD\u4E00\u8D77\u8986\u76D6\u6210\u4EA7\u54C1\u8FD9\u4E00\u7248").option("--endpoint <url>", "\u6280\u80FD\u5E93\u5730\u5740\uFF08\u9ED8\u8BA4\u53D6\u5B89\u88C5\u65F6\u8BB0\u5F55\u7684\u5730\u5740\uFF09").option("--env <name>", "\u4ECE\u8BE5 env \u89E3\u6790 endpoint").option("--output <fmt>", "\u8F93\u51FA\u683C\u5F0F\uFF1Atable | json | yaml", "table").action((opts) => skillsUpdateCommand(opts));
|
|
6705
|
+
skills.command("install [id]").description("\u8FDE\u540C requires \u524D\u7F6E\u6280\u80FD\u4E0E\u53C2\u8003\u6587\u4EF6\u88C5\u5230 agent \u6280\u80FD\u76EE\u5F55\uFF1B--all \u88C5\u6574\u4E2A\u6280\u80FD\u5E93").option("--all", "\u88C5\u6574\u4E2A\u6280\u80FD\u5E93\uFF0C\u5E76\u8BB0\u4E3A\u300C\u8DDF\u968F\u5168\u96C6\u300D\uFF08\u5F80\u540E update \u4F1A\u81EA\u52A8\u8865\u4E0A\u4EA7\u54C1\u65B0\u589E\u7684\u6280\u80FD\uFF09").option("--target <agent>", "\u88C5\u7ED9\u54EA\u4E2A agent\uFF1Aclaude\uFF08.claude/skills/\uFF09| codex\uFF08hcm-skills/ + AGENTS.md\uFF09| auto", "auto").option("--global", "\u88C5\u5230\u7528\u6237\u7EA7\u76EE\u5F55\u800C\u975E\u5F53\u524D\u9879\u76EE").option("--dir <path>", "\u88C5\u5230\u6307\u5B9A\u76EE\u5F55").option("--from <dir>", "\u4ECE\u672C\u5730\u76EE\u5F55\u88C5\uFF08\u73B0\u573A\u6539\u8FC7\u7684\u7248\u672C\uFF09\uFF0C\u4E0D\u8D70\u7F51\u7EDC").option("--force", "\u8986\u76D6\u5DF2\u5B58\u5728\u7684\u540C\u540D\u6280\u80FD").option("--endpoint <url>", "\u6280\u80FD\u5E93\u5730\u5740\uFF08\u9ED8\u8BA4\u53D6 activeEnv \u7684 endpoint\uFF09").option("--env <name>", "\u4ECE\u8BE5 env \u89E3\u6790 endpoint").option("--output <fmt>", "\u8F93\u51FA\u683C\u5F0F\uFF1Atable | json | yaml", "table").action((id, opts) => skillsInstallCommand(id, opts));
|
|
6706
|
+
skills.command("update").description("\u628A\u88C5\u8FC7\u7684\u6280\u80FD\u5347\u5230\u76EE\u6807\u73AF\u5883\u8FD9\u4E00\u7248\uFF08\u4EA7\u54C1\u5347\u7EA7\u540E\u8DD1\u5B83\uFF09").option("--all", "\u8FDE\u4EA7\u54C1\u65B0\u589E\u7684\u6280\u80FD\u4E00\u8D77\u88C5\u4E0A\uFF0C\u5E76\u8BB0\u4E3A\u300C\u8DDF\u968F\u5168\u96C6\u300D").option("--check", "\u53EA\u770B\u4F1A\u53D8\u4EC0\u4E48\uFF0C\u4E0D\u5199\u76D8").option("--target <agent>", "claude | codex | auto\uFF08\u9ED8\u8BA4\u6309\u5DF2\u5B89\u88C5\u76EE\u5F55\u63A2\uFF09", "auto").option("--global", "\u5347\u7EA7\u7528\u6237\u7EA7\u76EE\u5F55\u91CC\u7684\u6280\u80FD").option("--dir <path>", "\u5347\u7EA7\u6307\u5B9A\u76EE\u5F55\u91CC\u7684\u6280\u80FD").option("--force", "\u8FDE\u672C\u5730\u6539\u8FC7\u7684\u6280\u80FD\u4E00\u8D77\u8986\u76D6\u6210\u4EA7\u54C1\u8FD9\u4E00\u7248").option("--endpoint <url>", "\u6280\u80FD\u5E93\u5730\u5740\uFF08\u9ED8\u8BA4\u53D6\u5B89\u88C5\u65F6\u8BB0\u5F55\u7684\u5730\u5740\uFF09").option("--env <name>", "\u4ECE\u8BE5 env \u89E3\u6790 endpoint").option("--output <fmt>", "\u8F93\u51FA\u683C\u5F0F\uFF1Atable | json | yaml", "table").action((opts) => skillsUpdateCommand(opts));
|
|
6569
6707
|
program.command("update <Model>").description("\u66F4\u65B0\u4E00\u6761 Model \u8BB0\u5F55\uFF08\u8D70\u540E\u7AEF\u5B8C\u6574\u6821\u9A8C\uFF09").requiredOption("--id <id>", "\u8BB0\u5F55 ID").requiredOption("--data <JSON>", `\u8981\u66F4\u65B0\u7684\u5B57\u6BB5 JSON\uFF0C\u4F8B\u5982 '{"name":"\u65B0\u540D\u79F0"}'`).option("--env <name>", "\u4E34\u65F6\u5207\u73AF\u5883\uFF08\u8986\u76D6 activeEnv\uFF0C\u672C\u6B21\u547D\u4EE4\uFF09").option("--as <identity>", "\u4E34\u65F6\u6362\u8EAB\u4EFD\uFF08\u8986\u76D6 env defaultIdentity\uFF0C\u672C\u6B21\u547D\u4EE4\uFF09").option("--output <fmt>", "\u8F93\u51FA\u683C\u5F0F\uFF1Atable | json | yaml", "json").action((model, opts) => updateCommand(model, opts));
|
|
6570
6708
|
program.command("version").description("\u67E5\u540E\u7AEF\u7248\u672C\uFF08commit / tag / \u6784\u5EFA\u65F6\u95F4\uFF09\u2014\u2014\u514D\u8BA4\u8BC1\uFF0C\u65E0\u9700\u5148 login").option("--endpoint <url>", "\u540E\u7AEF\u5730\u5740\uFF08\u9ED8\u8BA4\u53D6 activeEnv \u7684 endpoint\uFF09").option("--env <name>", "\u4ECE\u8BE5 env \u89E3\u6790 endpoint").option("--output <fmt>", "\u8F93\u51FA\u683C\u5F0F\uFF1Atable | json | yaml", "json").action((opts) => versionCommand(opts));
|
|
6571
6709
|
var setting = program.command("setting").description("\u79DF\u6237\u7CFB\u7EDF\u53C2\u6570\uFF08\u767B\u5F55\u7B56\u7565 / \u5BC6\u7801\u7B56\u7565 / \u529F\u80FD\u5F00\u5173 / \u96C6\u6210\u53C2\u6570\uFF09");
|