@hcmai/cli 0.1.0 → 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/dist/index.js +541 -46
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -4186,11 +4186,16 @@ import {
|
|
|
4186
4186
|
fromAxiosError as fromAxiosError12,
|
|
4187
4187
|
uploadDocument as uploadDocument2
|
|
4188
4188
|
} from "@hcmai/sdk";
|
|
4189
|
+
var DEFAULT_UPLOAD_CATEGORY = "attachment";
|
|
4189
4190
|
async function uploadCommand(filePath, args) {
|
|
4190
4191
|
try {
|
|
4191
4192
|
const ctx = await getActiveAuthContextFromCli(args);
|
|
4192
4193
|
const client3 = HcmClient14.fromAuthContext(ctx);
|
|
4193
|
-
const meta2 = await uploadDocument2(
|
|
4194
|
+
const meta2 = await uploadDocument2(
|
|
4195
|
+
client3.raw(),
|
|
4196
|
+
filePath,
|
|
4197
|
+
args.category ?? DEFAULT_UPLOAD_CATEGORY
|
|
4198
|
+
);
|
|
4194
4199
|
const fmt = args.output ?? "json";
|
|
4195
4200
|
if (fmt !== "json") {
|
|
4196
4201
|
process.stdout.write(
|
|
@@ -4220,10 +4225,18 @@ init_exit();
|
|
|
4220
4225
|
import { promises as fsp } from "fs";
|
|
4221
4226
|
import os2 from "os";
|
|
4222
4227
|
import path2 from "path";
|
|
4228
|
+
import { createHash } from "crypto";
|
|
4223
4229
|
import {
|
|
4224
4230
|
createHttpClient as createHttpClient2,
|
|
4225
4231
|
fetchSkillCatalog,
|
|
4226
4232
|
fetchSkillMarkdown,
|
|
4233
|
+
fetchSkillReference,
|
|
4234
|
+
resolveChironBase,
|
|
4235
|
+
assertSafeSkillId,
|
|
4236
|
+
assertSafeReferencePath,
|
|
4237
|
+
normalizeReferences,
|
|
4238
|
+
parseSkillRequirements,
|
|
4239
|
+
resolveSkillInstallOrder,
|
|
4227
4240
|
matchSkills,
|
|
4228
4241
|
filterByStage,
|
|
4229
4242
|
formatObject as formatObject13,
|
|
@@ -4234,6 +4247,10 @@ import {
|
|
|
4234
4247
|
CliError as CliError14,
|
|
4235
4248
|
CliErrorCode as CliErrorCode13
|
|
4236
4249
|
} from "@hcmai/sdk";
|
|
4250
|
+
var SKILLS_STATE_FILE = ".hcm-skills.json";
|
|
4251
|
+
function sha256(text) {
|
|
4252
|
+
return createHash("sha256").update(text, "utf8").digest("hex");
|
|
4253
|
+
}
|
|
4237
4254
|
async function resolveEndpoint(args) {
|
|
4238
4255
|
if (args.endpoint) return args.endpoint.replace(/\/+$/, "");
|
|
4239
4256
|
const g = await loadGlobalConfig6();
|
|
@@ -4247,13 +4264,45 @@ async function resolveEndpoint(args) {
|
|
|
4247
4264
|
}
|
|
4248
4265
|
return env2.endpoint.replace(/\/+$/, "");
|
|
4249
4266
|
}
|
|
4250
|
-
function
|
|
4251
|
-
|
|
4267
|
+
async function exists(target) {
|
|
4268
|
+
try {
|
|
4269
|
+
await fsp.stat(target);
|
|
4270
|
+
return true;
|
|
4271
|
+
} catch {
|
|
4272
|
+
return false;
|
|
4273
|
+
}
|
|
4274
|
+
}
|
|
4275
|
+
async function detectTarget(cwd) {
|
|
4276
|
+
if (await exists(path2.join(cwd, ".claude"))) return "claude";
|
|
4277
|
+
if (await exists(path2.join(cwd, "AGENTS.md"))) return "codex";
|
|
4278
|
+
if (await exists(path2.join(cwd, ".codex"))) return "codex";
|
|
4279
|
+
return void 0;
|
|
4280
|
+
}
|
|
4281
|
+
async function resolveInstallLayout(args, cwd = process.cwd()) {
|
|
4282
|
+
const requested = args.target && args.target !== "auto" ? args.target : void 0;
|
|
4283
|
+
const target = requested ?? await detectTarget(cwd) ?? "claude";
|
|
4284
|
+
if (target === "codex") {
|
|
4285
|
+
const root = args.global ? path2.join(os2.homedir(), ".codex") : cwd;
|
|
4286
|
+
return {
|
|
4287
|
+
target,
|
|
4288
|
+
baseDir: args.dir ? path2.resolve(args.dir) : path2.join(root, "hcm-skills"),
|
|
4289
|
+
agentsFile: path2.join(root, "AGENTS.md")
|
|
4290
|
+
};
|
|
4291
|
+
}
|
|
4292
|
+
return {
|
|
4293
|
+
target,
|
|
4294
|
+
baseDir: args.dir ? path2.resolve(args.dir) : args.global ? path2.join(os2.homedir(), ".claude", "skills") : path2.join(cwd, ".claude", "skills")
|
|
4295
|
+
};
|
|
4296
|
+
}
|
|
4297
|
+
async function chironClient(args) {
|
|
4298
|
+
const endpoint = await resolveEndpoint(args);
|
|
4299
|
+
const http = createHttpClient2({
|
|
4252
4300
|
endpoint,
|
|
4253
4301
|
getAccessToken: async () => null,
|
|
4254
4302
|
onRefresh: async () => {
|
|
4255
4303
|
}
|
|
4256
4304
|
});
|
|
4305
|
+
return { http, endpoint, base: await resolveChironBase(http) };
|
|
4257
4306
|
}
|
|
4258
4307
|
function fail3(e, args) {
|
|
4259
4308
|
const err = e;
|
|
@@ -4266,8 +4315,8 @@ function fail3(e, args) {
|
|
|
4266
4315
|
}
|
|
4267
4316
|
async function skillsListCommand(keyword, args) {
|
|
4268
4317
|
try {
|
|
4269
|
-
const endpoint = await
|
|
4270
|
-
const manifest2 = await fetchSkillCatalog(
|
|
4318
|
+
const { http, endpoint, base } = await chironClient(args);
|
|
4319
|
+
const manifest2 = await fetchSkillCatalog(http, base);
|
|
4271
4320
|
const fmt = args.output ?? "table";
|
|
4272
4321
|
let cats = manifest2.categories ?? [];
|
|
4273
4322
|
if (args.category) cats = cats.filter((c) => c.key === args.category);
|
|
@@ -4337,8 +4386,8 @@ async function skillsListCommand(keyword, args) {
|
|
|
4337
4386
|
}
|
|
4338
4387
|
async function skillsShowCommand(id, args) {
|
|
4339
4388
|
try {
|
|
4340
|
-
const
|
|
4341
|
-
const md = await fetchSkillMarkdown(
|
|
4389
|
+
const { http, base } = await chironClient(args);
|
|
4390
|
+
const md = await fetchSkillMarkdown(http, id, base);
|
|
4342
4391
|
process.stdout.write(md.endsWith("\n") ? md : md + "\n");
|
|
4343
4392
|
process.exit(0);
|
|
4344
4393
|
} catch (e) {
|
|
@@ -4347,52 +4396,493 @@ async function skillsShowCommand(id, args) {
|
|
|
4347
4396
|
}
|
|
4348
4397
|
async function skillsInstallCommand(id, args) {
|
|
4349
4398
|
try {
|
|
4350
|
-
|
|
4399
|
+
assertSafeSkillId(id);
|
|
4400
|
+
const layout = await resolveInstallLayout(args);
|
|
4401
|
+
let documents;
|
|
4402
|
+
let endpoint;
|
|
4403
|
+
let base;
|
|
4404
|
+
let manifest2;
|
|
4405
|
+
if (args.from) {
|
|
4406
|
+
documents = await resolveLocalSkillDocuments(path2.resolve(args.from), id);
|
|
4407
|
+
} else {
|
|
4408
|
+
const client3 = await chironClient(args);
|
|
4409
|
+
endpoint = client3.endpoint;
|
|
4410
|
+
base = client3.base;
|
|
4411
|
+
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))
|
|
4415
|
+
);
|
|
4416
|
+
}
|
|
4417
|
+
const result = await installSkillDocuments(documents, id, layout.baseDir, Boolean(args.force), {
|
|
4418
|
+
endpoint,
|
|
4419
|
+
base,
|
|
4420
|
+
target: layout.target
|
|
4421
|
+
});
|
|
4422
|
+
const agents = layout.agentsFile ? await syncAgentsIndex(layout, manifest2) : void 0;
|
|
4423
|
+
const fmt = args.output ?? "table";
|
|
4424
|
+
if (fmt === "json" || fmt === "yaml") {
|
|
4425
|
+
process.stdout.write(formatObject13({ ...result, target_agent: layout.target, agentsFile: layout.agentsFile, agents }, { format: fmt }) + "\n");
|
|
4426
|
+
} else {
|
|
4427
|
+
process.stdout.write(`\u2705 ${id} \u2192 ${result.target}
|
|
4428
|
+
`);
|
|
4429
|
+
if (result.installed.length > 1) {
|
|
4430
|
+
process.stdout.write(` \u5DF2\u5B89\u88C5 ${result.installed.join(" \u2192 ")}
|
|
4431
|
+
`);
|
|
4432
|
+
}
|
|
4433
|
+
if (result.unchanged.length > 0) {
|
|
4434
|
+
process.stdout.write(` \u5DF2\u5B58\u5728\u4E14\u7248\u672C\u4E00\u81F4 ${result.unchanged.join(", ")}
|
|
4435
|
+
`);
|
|
4436
|
+
}
|
|
4437
|
+
const referenceCount = documents.reduce((n, d) => n + (d.references?.length ?? 0), 0);
|
|
4438
|
+
if (referenceCount > 0) {
|
|
4439
|
+
process.stdout.write(` \u53C2\u8003\u6587\u4EF6 ${referenceCount} \u4E2A\uFF08references/ \u4E0B\uFF09
|
|
4440
|
+
`);
|
|
4441
|
+
}
|
|
4442
|
+
if (layout.agentsFile) {
|
|
4443
|
+
process.stdout.write(` \u5DF2${agents === "created" ? "\u521B\u5EFA" : "\u66F4\u65B0"} ${layout.agentsFile} \u91CC\u7684\u6280\u80FD\u7D22\u5F15\uFF08Codex \u8BFB\u8FD9\u91CC\uFF09
|
|
4444
|
+
`);
|
|
4445
|
+
}
|
|
4446
|
+
process.stdout.write(` \u6765\u6E90 ${result.source}
|
|
4447
|
+
`);
|
|
4448
|
+
process.stdout.write(` \u4EA7\u54C1\u66F4\u65B0\u540E\u8DD1 hcm skills update \u5347\u7EA7
|
|
4449
|
+
`);
|
|
4450
|
+
}
|
|
4451
|
+
process.exit(0);
|
|
4452
|
+
} catch (e) {
|
|
4453
|
+
fail3(e, args);
|
|
4454
|
+
}
|
|
4455
|
+
}
|
|
4456
|
+
async function fetchSkillDocument(http, skill, endpoint, base) {
|
|
4457
|
+
const relatives = normalizeReferences(skill.references, skill.id);
|
|
4458
|
+
const references = await Promise.all(relatives.map(async (relative2) => ({
|
|
4459
|
+
path: relative2,
|
|
4460
|
+
content: await fetchSkillReference(http, skill.id, relative2, base)
|
|
4461
|
+
})));
|
|
4462
|
+
return {
|
|
4463
|
+
id: skill.id,
|
|
4464
|
+
markdown: await fetchSkillMarkdown(http, skill.id, base),
|
|
4465
|
+
source: `${endpoint}${base}/skills/${skill.id}.md`,
|
|
4466
|
+
references
|
|
4467
|
+
};
|
|
4468
|
+
}
|
|
4469
|
+
async function syncAgentsIndex(layout, manifest2) {
|
|
4470
|
+
if (!layout.agentsFile) return void 0;
|
|
4471
|
+
const state = await readSkillsState(layout.baseDir);
|
|
4472
|
+
if (!state) return void 0;
|
|
4473
|
+
const catalog = /* @__PURE__ */ new Map();
|
|
4474
|
+
for (const category of manifest2?.categories ?? []) {
|
|
4475
|
+
for (const skill of category.skills ?? []) catalog.set(skill.id, skill);
|
|
4476
|
+
}
|
|
4477
|
+
const agentsDir = path2.dirname(layout.agentsFile);
|
|
4478
|
+
const entries = Object.keys(state.skills).sort().map((id) => {
|
|
4479
|
+
const known = catalog.get(id);
|
|
4480
|
+
const absolute = path2.join(layout.baseDir, id, "SKILL.md");
|
|
4481
|
+
let relative2 = path2.relative(agentsDir, absolute);
|
|
4482
|
+
if (!relative2.startsWith(".")) relative2 = `./${relative2}`;
|
|
4483
|
+
return {
|
|
4484
|
+
id,
|
|
4485
|
+
title: known?.title ?? id,
|
|
4486
|
+
description: known?.description ?? "",
|
|
4487
|
+
relativePath: relative2.split(path2.sep).join("/")
|
|
4488
|
+
};
|
|
4489
|
+
});
|
|
4490
|
+
return upsertAgentsBlock(layout.agentsFile, renderAgentsBlock(entries));
|
|
4491
|
+
}
|
|
4492
|
+
async function resolveLocalSkillDocuments(sourceRoot, targetId) {
|
|
4493
|
+
assertSafeSkillId(targetId);
|
|
4494
|
+
const state = /* @__PURE__ */ new Map();
|
|
4495
|
+
const pathStack = [];
|
|
4496
|
+
const order = [];
|
|
4497
|
+
const visit = async (id, requiredBy) => {
|
|
4498
|
+
const current = state.get(id);
|
|
4499
|
+
if (current === "done") return;
|
|
4500
|
+
if (current === "visiting") {
|
|
4501
|
+
const start = pathStack.indexOf(id);
|
|
4502
|
+
throw invalid(`\u6280\u80FD\u4F9D\u8D56\u5B58\u5728\u73AF: ${[...pathStack.slice(Math.max(0, start)), id].join(" -> ")}`);
|
|
4503
|
+
}
|
|
4504
|
+
assertSafeSkillId(id);
|
|
4505
|
+
const local = path2.join(sourceRoot, id, "SKILL.md");
|
|
4506
|
+
let markdown;
|
|
4507
|
+
try {
|
|
4508
|
+
markdown = await fsp.readFile(local, "utf8");
|
|
4509
|
+
} catch (cause) {
|
|
4510
|
+
if (cause?.code === "ENOENT") {
|
|
4511
|
+
throw invalid(requiredBy ? `\u672C\u5730\u6280\u80FD ${requiredBy} \u4F9D\u8D56\u4E0D\u5B58\u5728: ${id}\uFF08${local}\uFF09` : `\u672C\u5730\u76EE\u5F55\u91CC\u6CA1\u6709 ${id}/SKILL.md\uFF1A${path2.join(sourceRoot, id)}`);
|
|
4512
|
+
}
|
|
4513
|
+
throw cause;
|
|
4514
|
+
}
|
|
4515
|
+
if (!markdown.trim()) throw invalid(`\u6280\u80FD ${id} \u5185\u5BB9\u4E3A\u7A7A`);
|
|
4516
|
+
state.set(id, "visiting");
|
|
4517
|
+
pathStack.push(id);
|
|
4518
|
+
const document = {
|
|
4519
|
+
id,
|
|
4520
|
+
markdown,
|
|
4521
|
+
source: local,
|
|
4522
|
+
references: await readLocalReferences(path2.join(sourceRoot, id))
|
|
4523
|
+
};
|
|
4524
|
+
for (const required of parseSkillRequirements(markdown, id)) {
|
|
4525
|
+
await visit(required, id);
|
|
4526
|
+
}
|
|
4527
|
+
pathStack.pop();
|
|
4528
|
+
state.set(id, "done");
|
|
4529
|
+
order.push(document);
|
|
4530
|
+
};
|
|
4531
|
+
await visit(targetId);
|
|
4532
|
+
return order;
|
|
4533
|
+
}
|
|
4534
|
+
async function readSkillsState(baseDir) {
|
|
4535
|
+
try {
|
|
4536
|
+
const raw = await fsp.readFile(path2.join(baseDir, SKILLS_STATE_FILE), "utf8");
|
|
4537
|
+
const parsed = JSON.parse(raw);
|
|
4538
|
+
if (!parsed || typeof parsed !== "object" || !parsed.skills) return void 0;
|
|
4539
|
+
return parsed;
|
|
4540
|
+
} catch {
|
|
4541
|
+
return void 0;
|
|
4542
|
+
}
|
|
4543
|
+
}
|
|
4544
|
+
async function writeSkillsState(baseDir, state) {
|
|
4545
|
+
await fsp.mkdir(baseDir, { recursive: true });
|
|
4546
|
+
const file = path2.join(baseDir, SKILLS_STATE_FILE);
|
|
4547
|
+
const temp = `${file}.${process.pid}.tmp`;
|
|
4548
|
+
await fsp.writeFile(temp, JSON.stringify(state, null, 2) + "\n", "utf8");
|
|
4549
|
+
await fsp.rename(temp, file);
|
|
4550
|
+
}
|
|
4551
|
+
var AGENTS_BLOCK_BEGIN = "<!-- hcm-skills:begin -->";
|
|
4552
|
+
var AGENTS_BLOCK_END = "<!-- hcm-skills:end -->";
|
|
4553
|
+
function renderAgentsBlock(entries) {
|
|
4554
|
+
const lines = [
|
|
4555
|
+
AGENTS_BLOCK_BEGIN,
|
|
4556
|
+
"## HCMnext \u4EA4\u4ED8\u6280\u80FD\uFF08\u7531 `hcm skills install` \u7EF4\u62A4\uFF0C\u52FF\u624B\u5DE5\u7F16\u8F91\u672C\u5757\uFF09",
|
|
4557
|
+
"",
|
|
4558
|
+
"\u9047\u5230\u4E0B\u9762\u8FD9\u4E9B\u6D3B\u513F\uFF0C**\u5148\u8BFB\u5BF9\u5E94\u6587\u4EF6\u518D\u52A8\u624B**\u2014\u2014\u91CC\u9762\u662F\u8FD9\u5957\u4EA7\u54C1\u7684\u6B63\u786E\u505A\u6CD5\uFF0C",
|
|
4559
|
+
"\u7167\u7740\u505A\u4E0D\u7528\u7FFB\u6E90\u7801\uFF0C\u4E5F\u4E0D\u7528\u731C API\u3002",
|
|
4560
|
+
""
|
|
4561
|
+
];
|
|
4562
|
+
for (const e of entries) {
|
|
4563
|
+
lines.push(`- \`${e.relativePath}\` \u2014 **${e.title}**`);
|
|
4564
|
+
if (e.description) lines.push(` ${e.description}`);
|
|
4565
|
+
}
|
|
4566
|
+
lines.push("", AGENTS_BLOCK_END);
|
|
4567
|
+
return lines.join("\n");
|
|
4568
|
+
}
|
|
4569
|
+
async function upsertAgentsBlock(agentsFile, block) {
|
|
4570
|
+
let existing = "";
|
|
4571
|
+
try {
|
|
4572
|
+
existing = await fsp.readFile(agentsFile, "utf8");
|
|
4573
|
+
} catch (cause) {
|
|
4574
|
+
if (cause?.code !== "ENOENT") throw cause;
|
|
4575
|
+
await fsp.mkdir(path2.dirname(agentsFile), { recursive: true });
|
|
4576
|
+
await fsp.writeFile(agentsFile, block + "\n", "utf8");
|
|
4577
|
+
return "created";
|
|
4578
|
+
}
|
|
4579
|
+
const begin = existing.indexOf(AGENTS_BLOCK_BEGIN);
|
|
4580
|
+
const end = existing.indexOf(AGENTS_BLOCK_END);
|
|
4581
|
+
if (begin >= 0 && end > begin) {
|
|
4582
|
+
const next = existing.slice(0, begin) + block + existing.slice(end + AGENTS_BLOCK_END.length);
|
|
4583
|
+
await fsp.writeFile(agentsFile, next, "utf8");
|
|
4584
|
+
return "replaced";
|
|
4585
|
+
}
|
|
4586
|
+
const separator = existing.endsWith("\n") ? "\n" : "\n\n";
|
|
4587
|
+
await fsp.writeFile(agentsFile, existing + separator + block + "\n", "utf8");
|
|
4588
|
+
return "appended";
|
|
4589
|
+
}
|
|
4590
|
+
async function installSkillDocuments(documents, requestedId, baseDir, force, meta2) {
|
|
4591
|
+
assertSafeSkillId(requestedId);
|
|
4592
|
+
const seen = /* @__PURE__ */ new Set();
|
|
4593
|
+
const candidates = documents.map((document) => {
|
|
4594
|
+
assertSafeSkillId(document.id);
|
|
4595
|
+
if (seen.has(document.id)) throw invalid(`\u5B89\u88C5\u95ED\u5305\u5305\u542B\u91CD\u590D\u6280\u80FD: ${document.id}`);
|
|
4596
|
+
seen.add(document.id);
|
|
4597
|
+
if (!document.markdown.trim()) throw invalid(`\u6280\u80FD ${document.id} \u5185\u5BB9\u4E3A\u7A7A`);
|
|
4598
|
+
return {
|
|
4599
|
+
...document,
|
|
4600
|
+
target: path2.join(baseDir, document.id, "SKILL.md"),
|
|
4601
|
+
bytes: Buffer.byteLength(document.markdown)
|
|
4602
|
+
};
|
|
4603
|
+
});
|
|
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}`);
|
|
4606
|
+
const unchanged = /* @__PURE__ */ new Set();
|
|
4607
|
+
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) {
|
|
4616
|
+
unchanged.add(candidate.id);
|
|
4617
|
+
continue;
|
|
4618
|
+
}
|
|
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`);
|
|
4621
|
+
}
|
|
4622
|
+
const pending = candidates.filter((candidate) => !unchanged.has(candidate.id));
|
|
4623
|
+
await writeSkillDocuments(pending, baseDir);
|
|
4624
|
+
await recordInstalled(baseDir, candidates, {
|
|
4625
|
+
...meta2,
|
|
4626
|
+
directIds: /* @__PURE__ */ new Set([requestedId]),
|
|
4627
|
+
keepInstalledAt: unchanged
|
|
4628
|
+
});
|
|
4629
|
+
return {
|
|
4630
|
+
id: requestedId,
|
|
4631
|
+
target: requested.target,
|
|
4632
|
+
source: requested.source,
|
|
4633
|
+
bytes: requested.bytes,
|
|
4634
|
+
installed: pending.map((candidate) => candidate.id),
|
|
4635
|
+
unchanged: candidates.filter((candidate) => unchanged.has(candidate.id)).map((candidate) => candidate.id),
|
|
4636
|
+
files: candidates.map((candidate) => ({
|
|
4637
|
+
id: candidate.id,
|
|
4638
|
+
target: candidate.target,
|
|
4639
|
+
source: candidate.source,
|
|
4640
|
+
bytes: candidate.bytes,
|
|
4641
|
+
status: unchanged.has(candidate.id) ? "unchanged" : "installed"
|
|
4642
|
+
}))
|
|
4643
|
+
};
|
|
4644
|
+
}
|
|
4645
|
+
async function readLocalReferences(skillDir) {
|
|
4646
|
+
const root = path2.join(skillDir, "references");
|
|
4647
|
+
const out = [];
|
|
4648
|
+
const walk = async (dir, prefix) => {
|
|
4649
|
+
let items;
|
|
4650
|
+
try {
|
|
4651
|
+
items = await fsp.readdir(dir, { withFileTypes: true });
|
|
4652
|
+
} catch (cause) {
|
|
4653
|
+
if (cause?.code === "ENOENT") return;
|
|
4654
|
+
throw cause;
|
|
4655
|
+
}
|
|
4656
|
+
for (const item of items.sort((a, b) => a.name.localeCompare(b.name))) {
|
|
4657
|
+
const relative2 = prefix ? `${prefix}/${item.name}` : item.name;
|
|
4658
|
+
if (item.isDirectory()) {
|
|
4659
|
+
await walk(path2.join(dir, item.name), relative2);
|
|
4660
|
+
continue;
|
|
4661
|
+
}
|
|
4662
|
+
if (!item.isFile()) continue;
|
|
4663
|
+
assertSafeReferencePath(relative2);
|
|
4664
|
+
out.push({ path: relative2, content: await fsp.readFile(path2.join(dir, item.name), "utf8") });
|
|
4665
|
+
}
|
|
4666
|
+
};
|
|
4667
|
+
await walk(root, "");
|
|
4668
|
+
return out;
|
|
4669
|
+
}
|
|
4670
|
+
async function writeSkillDocuments(documents, baseDir) {
|
|
4671
|
+
const staged = [];
|
|
4672
|
+
try {
|
|
4673
|
+
for (const document of documents) {
|
|
4674
|
+
const target = path2.join(baseDir, document.id, "SKILL.md");
|
|
4675
|
+
await fsp.mkdir(path2.dirname(target), { recursive: true });
|
|
4676
|
+
const temp = path2.join(path2.dirname(target), `.SKILL.md.${process.pid}.${Date.now()}.tmp`);
|
|
4677
|
+
await fsp.writeFile(temp, document.markdown, "utf8");
|
|
4678
|
+
staged.push({ temp, target });
|
|
4679
|
+
for (const reference of document.references ?? []) {
|
|
4680
|
+
assertSafeReferencePath(reference.path);
|
|
4681
|
+
const referenceTarget = path2.join(baseDir, document.id, "references", reference.path);
|
|
4682
|
+
await fsp.mkdir(path2.dirname(referenceTarget), { recursive: true });
|
|
4683
|
+
const referenceTemp = `${referenceTarget}.${process.pid}.${Date.now()}.tmp`;
|
|
4684
|
+
await fsp.writeFile(referenceTemp, reference.content, "utf8");
|
|
4685
|
+
staged.push({ temp: referenceTemp, target: referenceTarget });
|
|
4686
|
+
}
|
|
4687
|
+
}
|
|
4688
|
+
for (const file of staged) await fsp.rename(file.temp, file.target);
|
|
4689
|
+
} catch (cause) {
|
|
4690
|
+
await Promise.all(staged.map((file) => fsp.unlink(file.temp).catch(() => void 0)));
|
|
4691
|
+
throw cause;
|
|
4692
|
+
}
|
|
4693
|
+
}
|
|
4694
|
+
async function recordInstalled(baseDir, documents, meta2) {
|
|
4695
|
+
const state = await readSkillsState(baseDir) ?? {
|
|
4696
|
+
version: 1,
|
|
4697
|
+
target: meta2.target ?? "claude",
|
|
4698
|
+
updatedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
4699
|
+
skills: {}
|
|
4700
|
+
};
|
|
4701
|
+
state.version = 1;
|
|
4702
|
+
if (meta2.target) state.target = meta2.target;
|
|
4703
|
+
if (meta2.endpoint) state.endpoint = meta2.endpoint;
|
|
4704
|
+
if (meta2.base !== void 0) state.base = meta2.base;
|
|
4705
|
+
state.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
4706
|
+
for (const document of documents) {
|
|
4707
|
+
const previous = state.skills[document.id];
|
|
4708
|
+
state.skills[document.id] = {
|
|
4709
|
+
source: document.source,
|
|
4710
|
+
sha256: sha256(document.markdown),
|
|
4711
|
+
installedAt: meta2.keepInstalledAt?.has(document.id) && previous ? previous.installedAt : state.updatedAt,
|
|
4712
|
+
// 已经是直接安装的,不因为这次作为依赖被带进来就降级
|
|
4713
|
+
direct: meta2.directIds.has(document.id) || Boolean(previous?.direct),
|
|
4714
|
+
references: Object.fromEntries(
|
|
4715
|
+
(document.references ?? []).map((reference) => [reference.path, sha256(reference.content)])
|
|
4716
|
+
)
|
|
4717
|
+
};
|
|
4718
|
+
}
|
|
4719
|
+
await writeSkillsState(baseDir, state);
|
|
4720
|
+
return state;
|
|
4721
|
+
}
|
|
4722
|
+
function invalid(message) {
|
|
4723
|
+
return new CliError14({ code: CliErrorCode13.INVALID_ARGUMENT, message });
|
|
4724
|
+
}
|
|
4725
|
+
async function readInstalled(baseDir, id) {
|
|
4726
|
+
try {
|
|
4727
|
+
return await fsp.readFile(path2.join(baseDir, id, "SKILL.md"), "utf8");
|
|
4728
|
+
} catch (cause) {
|
|
4729
|
+
if (cause?.code === "ENOENT") return void 0;
|
|
4730
|
+
throw cause;
|
|
4731
|
+
}
|
|
4732
|
+
}
|
|
4733
|
+
async function readInstalledReference(baseDir, id, relative2) {
|
|
4734
|
+
try {
|
|
4735
|
+
return await fsp.readFile(path2.join(baseDir, id, "references", relative2), "utf8");
|
|
4736
|
+
} catch (cause) {
|
|
4737
|
+
if (cause?.code === "ENOENT") return void 0;
|
|
4738
|
+
throw cause;
|
|
4739
|
+
}
|
|
4740
|
+
}
|
|
4741
|
+
async function planSkillUpdate(options) {
|
|
4742
|
+
const { state, manifest: manifest2, baseDir, force, fetchDocument } = options;
|
|
4743
|
+
const recorded = Object.entries(state.skills);
|
|
4744
|
+
const directIds = recorded.some(([, r]) => r.direct) ? recorded.filter(([, r]) => r.direct).map(([id]) => id) : recorded.map(([id]) => id);
|
|
4745
|
+
const entries = [];
|
|
4746
|
+
const closure = /* @__PURE__ */ new Map();
|
|
4747
|
+
for (const id of directIds.sort()) {
|
|
4748
|
+
try {
|
|
4749
|
+
for (const skill of resolveSkillInstallOrder(manifest2, id)) {
|
|
4750
|
+
if (!closure.has(skill.id)) closure.set(skill.id, skill);
|
|
4751
|
+
}
|
|
4752
|
+
} catch {
|
|
4753
|
+
entries.push({
|
|
4754
|
+
id,
|
|
4755
|
+
status: "removed-upstream",
|
|
4756
|
+
note: "\u4EA7\u54C1\u8FD9\u4E00\u7248\u7684\u6280\u80FD\u76EE\u5F55\u91CC\u5DF2\u7ECF\u6CA1\u6709\u5B83\u4E86\uFF1B\u672C\u5730\u6587\u4EF6\u4FDD\u7559\u4E0D\u52A8"
|
|
4757
|
+
});
|
|
4758
|
+
}
|
|
4759
|
+
}
|
|
4760
|
+
const documents = [];
|
|
4761
|
+
for (const skill of closure.values()) {
|
|
4762
|
+
const record = state.skills[skill.id];
|
|
4763
|
+
const onDisk = await readInstalled(baseDir, skill.id);
|
|
4764
|
+
if (onDisk === void 0) {
|
|
4765
|
+
documents.push(await fetchDocument(skill));
|
|
4766
|
+
entries.push({
|
|
4767
|
+
id: skill.id,
|
|
4768
|
+
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"
|
|
4770
|
+
});
|
|
4771
|
+
continue;
|
|
4772
|
+
}
|
|
4773
|
+
const remote = await fetchDocument(skill);
|
|
4774
|
+
const remoteReferences = remote.references ?? [];
|
|
4775
|
+
let differsFromRemote = remote.markdown !== onDisk;
|
|
4776
|
+
let editedLocally = record !== void 0 && sha256(onDisk) !== record.sha256;
|
|
4777
|
+
for (const reference of remoteReferences) {
|
|
4778
|
+
const installed = await readInstalledReference(baseDir, skill.id, reference.path);
|
|
4779
|
+
if (installed !== reference.content) differsFromRemote = true;
|
|
4780
|
+
const recordedSha = record?.references?.[reference.path];
|
|
4781
|
+
if (installed !== void 0 && recordedSha && sha256(installed) !== recordedSha) editedLocally = true;
|
|
4782
|
+
}
|
|
4783
|
+
if (!differsFromRemote) {
|
|
4784
|
+
entries.push({ id: skill.id, status: "unchanged" });
|
|
4785
|
+
continue;
|
|
4786
|
+
}
|
|
4787
|
+
if (editedLocally && !force) {
|
|
4788
|
+
entries.push({
|
|
4789
|
+
id: skill.id,
|
|
4790
|
+
status: "locally-modified",
|
|
4791
|
+
note: "\u672C\u5730\u6539\u8FC7\uFF0C\u6CA1\u6709\u8986\u76D6\uFF1B\u786E\u5B9A\u8981\u7528\u4EA7\u54C1\u8FD9\u4E00\u7248\u5C31\u52A0 --force"
|
|
4792
|
+
});
|
|
4793
|
+
continue;
|
|
4794
|
+
}
|
|
4795
|
+
documents.push(remote);
|
|
4796
|
+
entries.push({
|
|
4797
|
+
id: skill.id,
|
|
4798
|
+
status: "updated",
|
|
4799
|
+
note: editedLocally ? "\u672C\u5730\u6539\u8FC7\uFF0C--force \u5DF2\u8986\u76D6" : void 0
|
|
4800
|
+
});
|
|
4801
|
+
}
|
|
4802
|
+
entries.sort((a, b) => a.id.localeCompare(b.id));
|
|
4803
|
+
return { entries, documents };
|
|
4804
|
+
}
|
|
4805
|
+
var UPDATE_STATUS_LABEL = {
|
|
4806
|
+
updated: "\u5DF2\u66F4\u65B0",
|
|
4807
|
+
added: "\u5DF2\u8865\u88C5",
|
|
4808
|
+
unchanged: "\u5DF2\u662F\u6700\u65B0",
|
|
4809
|
+
"locally-modified": "\u672C\u5730\u6539\u8FC7\xB7\u8DF3\u8FC7",
|
|
4810
|
+
"removed-upstream": "\u4EA7\u54C1\u5DF2\u79FB\u9664"
|
|
4811
|
+
};
|
|
4812
|
+
async function skillsUpdateCommand(args) {
|
|
4813
|
+
try {
|
|
4814
|
+
const layout = await resolveInstallLayout(args);
|
|
4815
|
+
const state = await readSkillsState(layout.baseDir);
|
|
4816
|
+
if (!state || Object.keys(state.skills).length === 0) {
|
|
4351
4817
|
throw new CliError14({
|
|
4352
4818
|
code: CliErrorCode13.INVALID_ARGUMENT,
|
|
4353
|
-
message:
|
|
4819
|
+
message: `${path2.join(layout.baseDir, SKILLS_STATE_FILE)} \u4E0D\u5B58\u5728\u6216\u4E3A\u7A7A \u2014\u2014 \u8FD9\u4E2A\u76EE\u5F55\u4E0B\u8FD8\u6CA1\u6709\u7528\u672C CLI \u88C5\u8FC7\u6280\u80FD\u3002\u5148 \`hcm skills install <id>\`\uFF1B\u5982\u679C\u6280\u80FD\u662F\u624B\u5DE5\u62F7\u8FDB\u6765\u7684\uFF0C\u91CD\u88C5\u4E00\u6B21\u5373\u53EF\u63A5\u7BA1\u5347\u7EA7\u3002`
|
|
4354
4820
|
});
|
|
4355
4821
|
}
|
|
4356
|
-
|
|
4357
|
-
|
|
4358
|
-
|
|
4359
|
-
|
|
4360
|
-
|
|
4361
|
-
|
|
4362
|
-
|
|
4363
|
-
|
|
4364
|
-
|
|
4365
|
-
|
|
4366
|
-
|
|
4367
|
-
|
|
4368
|
-
|
|
4369
|
-
|
|
4370
|
-
|
|
4371
|
-
|
|
4372
|
-
|
|
4373
|
-
|
|
4374
|
-
|
|
4375
|
-
|
|
4376
|
-
|
|
4377
|
-
|
|
4822
|
+
const endpoint = args.endpoint ? args.endpoint.replace(/\/+$/, "") : await resolveEndpoint(args).catch((e) => {
|
|
4823
|
+
if (state.endpoint) return state.endpoint;
|
|
4824
|
+
throw e;
|
|
4825
|
+
});
|
|
4826
|
+
const { http, base } = await chironClient({ ...args, endpoint });
|
|
4827
|
+
const manifest2 = await fetchSkillCatalog(http, base);
|
|
4828
|
+
const plan = await planSkillUpdate({
|
|
4829
|
+
state,
|
|
4830
|
+
manifest: manifest2,
|
|
4831
|
+
baseDir: layout.baseDir,
|
|
4832
|
+
force: Boolean(args.force),
|
|
4833
|
+
fetchDocument: (skill) => fetchSkillDocument(http, skill, endpoint, base)
|
|
4834
|
+
});
|
|
4835
|
+
if (!args.check && plan.documents.length > 0) {
|
|
4836
|
+
await writeSkillDocuments(plan.documents, layout.baseDir);
|
|
4837
|
+
await recordInstalled(layout.baseDir, plan.documents, {
|
|
4838
|
+
endpoint,
|
|
4839
|
+
base,
|
|
4840
|
+
target: layout.target,
|
|
4841
|
+
directIds: /* @__PURE__ */ new Set()
|
|
4842
|
+
});
|
|
4843
|
+
if (layout.agentsFile) await syncAgentsIndex(layout, manifest2);
|
|
4378
4844
|
}
|
|
4379
|
-
|
|
4380
|
-
await fsp.writeFile(target, md, "utf8");
|
|
4845
|
+
const changed = plan.entries.filter((e) => e.status === "updated" || e.status === "added");
|
|
4381
4846
|
const fmt = args.output ?? "table";
|
|
4382
4847
|
if (fmt === "json" || fmt === "yaml") {
|
|
4383
|
-
process.stdout.write(
|
|
4384
|
-
|
|
4385
|
-
|
|
4848
|
+
process.stdout.write(formatObject13({
|
|
4849
|
+
endpoint,
|
|
4850
|
+
baseDir: layout.baseDir,
|
|
4851
|
+
target: layout.target,
|
|
4852
|
+
dryRun: Boolean(args.check),
|
|
4853
|
+
changed: changed.length,
|
|
4854
|
+
entries: plan.entries
|
|
4855
|
+
}, { format: fmt }) + "\n");
|
|
4856
|
+
process.exit(0);
|
|
4857
|
+
}
|
|
4858
|
+
process.stdout.write(`\u777F\u620E\u6280\u80FD\u5347\u7EA7 \u2014 ${endpoint}
|
|
4859
|
+
`);
|
|
4860
|
+
process.stdout.write(`\u843D\u70B9 ${layout.baseDir}\uFF08${layout.target}\uFF09
|
|
4861
|
+
|
|
4862
|
+
`);
|
|
4863
|
+
for (const entry of plan.entries) {
|
|
4864
|
+
const mark = entry.status === "unchanged" ? " " : entry.status === "locally-modified" ? "!" : "\xB7";
|
|
4865
|
+
process.stdout.write(` ${mark} ${entry.id.padEnd(30)} ${UPDATE_STATUS_LABEL[entry.status]}
|
|
4866
|
+
`);
|
|
4867
|
+
if (entry.note) process.stdout.write(` ${entry.note}
|
|
4868
|
+
`);
|
|
4869
|
+
}
|
|
4870
|
+
process.stdout.write("\n");
|
|
4871
|
+
const skipped = plan.entries.filter((e) => e.status === "locally-modified").length;
|
|
4872
|
+
const removed = plan.entries.filter((e) => e.status === "removed-upstream").length;
|
|
4873
|
+
const tail = [
|
|
4874
|
+
skipped > 0 ? `${skipped} \u4E2A\u672C\u5730\u6539\u8FC7\u88AB\u8DF3\u8FC7\uFF08--force \u8986\u76D6\uFF09` : "",
|
|
4875
|
+
removed > 0 ? `${removed} \u4E2A\u4EA7\u54C1\u5DF2\u79FB\u9664\uFF08\u672C\u5730\u6587\u4EF6\u4FDD\u7559\uFF09` : ""
|
|
4876
|
+
].filter(Boolean).join("\uFF0C");
|
|
4877
|
+
if (changed.length === 0 && skipped === 0 && removed === 0) {
|
|
4878
|
+
process.stdout.write(args.check ? " \u5168\u90E8\u5DF2\u662F\u6700\u65B0\uFF08--check \u53EA\u770B\u4E0D\u52A8\uFF09\n" : " \u5168\u90E8\u5DF2\u662F\u6700\u65B0\uFF0C\u6CA1\u6709\u6539\u52A8\n");
|
|
4386
4879
|
} else {
|
|
4387
|
-
|
|
4388
|
-
|
|
4880
|
+
const head = args.check ? changed.length > 0 ? `\u6709 ${changed.length} \u4E2A\u53EF\u4EE5\u66F4\u65B0\uFF0C\u53BB\u6389 --check \u5C31\u4F1A\u5199\u5165` : "\u6CA1\u6709\u53EF\u5199\u5165\u7684\u66F4\u65B0" : changed.length > 0 ? `\u5DF2\u66F4\u65B0 ${changed.length} \u4E2A` : "\u6CA1\u6709\u5199\u5165\u4EFB\u4F55\u6539\u52A8";
|
|
4881
|
+
process.stdout.write(` ${[head, tail].filter(Boolean).join("\uFF1B")}
|
|
4389
4882
|
`);
|
|
4390
4883
|
}
|
|
4391
4884
|
process.exit(0);
|
|
4392
4885
|
} catch (e) {
|
|
4393
|
-
if (e?.code === "ENOENT" && args.from) {
|
|
4394
|
-
exitWithError(new Error(`\u672C\u5730\u76EE\u5F55\u91CC\u6CA1\u6709 ${id}/SKILL.md\uFF1A${path2.resolve(args.from, id)}`));
|
|
4395
|
-
}
|
|
4396
4886
|
fail3(e, args);
|
|
4397
4887
|
}
|
|
4398
4888
|
}
|
|
@@ -5289,7 +5779,7 @@ async function walkWorkspaceRawFiles(rootDir, relativeDir, files) {
|
|
|
5289
5779
|
localPath,
|
|
5290
5780
|
absolutePath,
|
|
5291
5781
|
content,
|
|
5292
|
-
sha256:
|
|
5782
|
+
sha256: sha2562(content),
|
|
5293
5783
|
size: Buffer.byteLength(content, "utf-8")
|
|
5294
5784
|
});
|
|
5295
5785
|
}
|
|
@@ -5356,7 +5846,7 @@ function buildWorkspaceRawPushPlan(manifest2, localFiles, remoteFiles) {
|
|
|
5356
5846
|
for (const entry of status) {
|
|
5357
5847
|
const remote = remoteByLocal.get(entry.localPath);
|
|
5358
5848
|
const base = baseByLocal.get(entry.localPath);
|
|
5359
|
-
const remoteSha = remote ?
|
|
5849
|
+
const remoteSha = remote ? sha2562(remote.content) : void 0;
|
|
5360
5850
|
if (entry.status === "added") {
|
|
5361
5851
|
if (remote) {
|
|
5362
5852
|
conflicts.push(workspaceRawConflict(entry, "remote file already exists but was not in local snapshot"));
|
|
@@ -5621,7 +6111,7 @@ function normalizeRelativePath(value) {
|
|
|
5621
6111
|
function toPosix(value) {
|
|
5622
6112
|
return value.split(path3.sep).join("/");
|
|
5623
6113
|
}
|
|
5624
|
-
function
|
|
6114
|
+
function sha2562(content) {
|
|
5625
6115
|
return crypto.createHash("sha256").update(content, "utf-8").digest("hex");
|
|
5626
6116
|
}
|
|
5627
6117
|
function stringRequired(value, field) {
|
|
@@ -6059,7 +6549,11 @@ var cache = program.command("cache").description("\u6A21\u578B\u7F13\u5B58\u8FD0
|
|
|
6059
6549
|
cache.command("stats <Model>").description("\u67E5\u770B\u6A21\u578B\u7F13\u5B58\u7EDF\u8BA1").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((model, opts) => cacheStatsCommand(model, opts));
|
|
6060
6550
|
cache.command("clear <Model>").description("\u6E05\u6A21\u578B\u5B9E\u4F53\u7F13\u5B58\uFF08\u5E42\u7B49\uFF0C\u4E0D\u7834\u574F\u6570\u636E\uFF09").option("--id <id>", "\u53EA\u6E05\u5355\u6761\uFF08\u9ED8\u8BA4\u6E05\u5168\u90E8\uFF09").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((model, opts) => cacheClearCommand(model, opts));
|
|
6061
6551
|
cache.command("clear-meta <Model>").description("\u6E05\u5143\u6570\u636E\u7F13\u5B58\uFF08Code \u7EA7 YAML + Action \u5B9A\u4E49\uFF09\u2014\u2014\u6539 meta YAML \u540E\u5FC5\u8DD1").option("--type <type>", "\u5143\u6570\u636E\u7C7B\u578B\uFF1Alist | info | view | filter | page\u2026\uFF08\u9ED8\u8BA4\u5168\u6E05\uFF09").option("--state <state>", "\u72B6\u6001\u53D8\u4F53\uFF08\u5982 self\uFF09\uFF0C\u914D\u5408 --type").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((model, opts) => cacheClearMetaCommand(model, opts));
|
|
6062
|
-
program.command("upload <file>").description("\u4E0A\u4F20\u672C\u5730\u6587\u4EF6\u5230 HCM \u6587\u6863\u670D\u52A1\uFF0C\u8FD4\u56DE documentId").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").
|
|
6552
|
+
program.command("upload <file>").description("\u4E0A\u4F20\u672C\u5730\u6587\u4EF6\u5230 HCM \u6587\u6863\u670D\u52A1\uFF0C\u8FD4\u56DE documentId").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").option(
|
|
6553
|
+
"--category <name>",
|
|
6554
|
+
"\u5B58\u50A8\u5206\u7C7B\uFF08\u987B\u662F\u76EE\u6807\u73AF\u5883\u91CC\u771F\u5B9E\u5B58\u5728\u7684\u5206\u7C7B\uFF0C\u5982 flex-report / template / attachment\uFF09",
|
|
6555
|
+
"attachment"
|
|
6556
|
+
).action((file, opts) => uploadCommand(file, opts));
|
|
6063
6557
|
var tenant = program.command("tenant").description("\u79DF\u6237\u5F00\u901A\u4E0E\u751F\u547D\u5468\u671F");
|
|
6064
6558
|
tenant.command("bootstrap").description("\u5F00\u901A\u65B0\u79DF\u6237\uFF08\u5EFA\u79DF\u6237 + admin \u7528\u6237 + \u7ED3\u6784 reconcile\uFF09\u2014\u2014\u4E0D\u53EF\u9006\uFF0C\u9ED8\u8BA4\u8FC7\u786E\u8BA4\u95F8").requiredOption("--tenant-id <id>", "\u79DF\u6237 ID").requiredOption("--admin-username <user>", "\u7BA1\u7406\u5458\u7528\u6237\u540D").option("--admin-password <pwd>", "\u7BA1\u7406\u5458\u5BC6\u7801\uFF08\u4F1A\u6CC4\u6F0F\u5230 history/ps\uFF0C\u5EFA\u8BAE --admin-password-stdin\uFF09").option("--admin-password-stdin", "\u4ECE\u6807\u51C6\u8F93\u5165\u8BFB\u7BA1\u7406\u5458\u5BC6\u7801\uFF08\u63A8\u8350\uFF09").option("--tenant-name <name>", "\u79DF\u6237\u540D\u79F0\uFF08\u9ED8\u8BA4\u53D6 tenantId\uFF09").option("--bootstrap-key <key>", "bootstrap \u5BC6\u94A5\uFF08\u5EFA\u8BAE\u7528 HCM_BOOTSTRAP_KEY \u73AF\u5883\u53D8\u91CF\uFF09").option("--bootstrap-key-stdin", "\u4ECE\u6807\u51C6\u8F93\u5165\u8BFB bootstrap \u5BC6\u94A5").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("-y, --yes", "\u8DF3\u8FC7\u786E\u8BA4\uFF08CI \u7528\uFF09").option("--output <fmt>", "\u8F93\u51FA\u683C\u5F0F\uFF1Atable | json | yaml", "json").action((opts) => tenantBootstrapCommand(opts));
|
|
6065
6559
|
var meta = program.command("meta").description("\u79DF\u6237\u5143\u6570\u636E\u8BFB\u5199\uFF08\u9875\u9762/\u5B57\u6BB5/\u5217\u8868\u914D\u7F6E\uFF09");
|
|
@@ -6070,7 +6564,8 @@ meta.command("delete <path>").description("\u5220\u9664 meta\uFF08\u4E0D\u53EF\u
|
|
|
6070
6564
|
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");
|
|
6071
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));
|
|
6072
6566
|
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));
|
|
6073
|
-
skills.command("install <id>").description("\u88C5\u5230 agent \u6280\u80FD\u76EE\u5F55\
|
|
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));
|
|
6074
6569
|
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));
|
|
6075
6570
|
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));
|
|
6076
6571
|
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");
|