@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 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
- assertSafeSkillId(id);
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
- documents = await resolveLocalSkillDocuments(path2.resolve(args.from), id);
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
- documents = await Promise.all(
4414
- order.map((skill) => fetchSkillDocument(client3.http, skill, endpoint, base))
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, id, layout.baseDir, Boolean(args.force), {
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
- process.stdout.write(`\u2705 ${id} \u2192 ${result.target}
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 > 1) {
4430
- process.stdout.write(` \u5DF2\u5B89\u88C5 ${result.installed.join(" \u2192 ")}
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\u5B58\u5728\u4E14\u7248\u672C\u4E00\u81F4 ${result.unchanged.join(", ")}
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 ${result.source}
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, requestedId, baseDir, force, meta2) {
4591
- assertSafeSkillId(requestedId);
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
- const requested = candidates.find((candidate) => candidate.id === requestedId);
4605
- if (!requested) throw invalid(`\u5B89\u88C5\u95ED\u5305\u4E0D\u5305\u542B\u76EE\u6807\u6280\u80FD: ${requestedId}`);
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
- let existing;
4609
- try {
4610
- existing = await fsp.readFile(candidate.target, "utf8");
4611
- } catch (cause) {
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
- const kind = candidate.id === requestedId ? "\u76EE\u6807\u6280\u80FD\u5DF2\u5B58\u5728" : "\u524D\u7F6E\u6280\u80FD\u4E0E\u76EE\u6807\u73AF\u5883\u7248\u672C\u4E0D\u4E00\u81F4";
4620
- throw invalid(`${kind}\uFF1A${candidate.target}\u3002\u7528 --force \u8986\u76D6\u6574\u4E2A\u4F9D\u8D56\u95ED\u5305\uFF0C\u6216 --dir <path> \u88C5\u5230\u522B\u5904`);
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: /* @__PURE__ */ new Set([requestedId]),
4751
+ directIds: new Set(requestedIds),
4627
4752
  keepInstalledAt: unchanged
4628
4753
  });
4629
4754
  return {
4630
- id: requestedId,
4631
- target: requested.target,
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 directIds.sort()) {
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
- if (!args.check && plan.documents.length > 0) {
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
- directIds: /* @__PURE__ */ new Set()
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 <id>").description("\u8FDE\u540C requires \u524D\u7F6E\u6280\u80FD\u4E0E\u53C2\u8003\u6587\u4EF6\u88C5\u5230 agent \u6280\u80FD\u76EE\u5F55").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));
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");