@theholocron/cli 2.0.0-alpha.71 → 2.0.0-alpha.73

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.
Files changed (2) hide show
  1. package/dist/cli.mjs +91 -17
  2. package/package.json +1 -1
package/dist/cli.mjs CHANGED
@@ -1430,7 +1430,7 @@ async function runNpmPublishInitial(input = {}) {
1430
1430
  const dryRun = input.dryRun ?? false;
1431
1431
  const otp = input.otp;
1432
1432
  const env = input.env ?? process.env;
1433
- const exec = input.exec ?? defaultExec$1;
1433
+ const exec = input.exec ?? defaultExec$2;
1434
1434
  const publishArgs = [
1435
1435
  "-r",
1436
1436
  "--filter=./packages/*",
@@ -1506,7 +1506,7 @@ function printNextSteps$1(print, env) {
1506
1506
  print(" https://www.npmjs.com/settings/~/tokens");
1507
1507
  }
1508
1508
  }
1509
- const defaultExec$1 = async (cmd, args, opts) => {
1509
+ const defaultExec$2 = async (cmd, args, opts) => {
1510
1510
  const result = spawnSync(cmd, args, {
1511
1511
  cwd: opts.cwd,
1512
1512
  encoding: "utf8",
@@ -2485,7 +2485,7 @@ function runPluginCreate(input) {
2485
2485
  filesWritten.push(resolvedPath);
2486
2486
  }
2487
2487
  if (!input.dryRun && !input.noVerify) {
2488
- const execFn = input.exec ?? defaultExec;
2488
+ const execFn = input.exec ?? defaultExec$1;
2489
2489
  const pkg = `@theholocron/holocron-plugin-${inputs.slug}`;
2490
2490
  print("");
2491
2491
  print(" Verifying scaffold…");
@@ -2572,7 +2572,7 @@ function defaultWrite(filepath, content) {
2572
2572
  mkdirSync(path.dirname(filepath), { recursive: true });
2573
2573
  writeFileSync(filepath, content, "utf8");
2574
2574
  }
2575
- function defaultExec(cmd, args, opts) {
2575
+ function defaultExec$1(cmd, args, opts) {
2576
2576
  execFileSync(cmd, args, {
2577
2577
  cwd: opts.cwd,
2578
2578
  stdio: opts.stdio
@@ -3261,14 +3261,22 @@ async function runSetup(input) {
3261
3261
  await source.writeRepoFile(".editorconfig-checker.json", EDITORCONFIG_CHECKER_CONFIG);
3262
3262
  }));
3263
3263
  print(formatStep(steps[steps.length - 1]));
3264
- steps.push(await runStep("source", "write codecov.yml", dryRun, async () => {
3264
+ {
3265
3265
  const packages = await readWorkspacePackages(input.context.repoRoot);
3266
3266
  const existing = await readFile(join(input.context.repoRoot, "codecov.yml"), "utf8").catch(() => null);
3267
- const content = existing != null ? mergeCodecovComponents(existing, packages) : codecovContent(packages);
3268
- await source.writeRepoFile("codecov.yml", content);
3269
- return packages.length > 0 ? `${packages.length} components` : "no components";
3270
- }));
3271
- print(formatStep(steps[steps.length - 1]));
3267
+ if (packages.length === 0 && existing == null) steps.push({
3268
+ capability: "source",
3269
+ step: "write codecov.yml",
3270
+ status: "skip",
3271
+ message: "no packages and no existing codecov.yml"
3272
+ });
3273
+ else steps.push(await runStep("source", "write codecov.yml", dryRun, async () => {
3274
+ const content = existing != null ? mergeCodecovComponents(existing, packages) : codecovContent(packages);
3275
+ await source.writeRepoFile("codecov.yml", content);
3276
+ return packages.length > 0 ? `${packages.length} components` : "no components";
3277
+ }));
3278
+ print(formatStep(steps[steps.length - 1]));
3279
+ }
3272
3280
  if (source.syncLabels) {
3273
3281
  steps.push(await runStep("source", "sync labels", dryRun, async () => {
3274
3282
  return source.syncLabels(CANONICAL_LABELS, STALE_LABELS);
@@ -3600,6 +3608,23 @@ function formatStep(step) {
3600
3608
  }
3601
3609
  //#endregion
3602
3610
  //#region src/commands/skills.ts
3611
+ /**
3612
+ * `holocron skills` — install, remove, and update agent skills from @theholocron/skills.
3613
+ *
3614
+ * Unlike `holocron setup`, this command is purely local (no GitHub token
3615
+ * required). It reads `agent` and `skills` from the config and installs
3616
+ * the listed skills into `.agents/skills/<name>/` with a symlink at the
3617
+ * agent-specific path (e.g. `.claude/skills/<name>` for Claude Code).
3618
+ *
3619
+ * `holocron skills remove [name]` and `holocron skills update [name]` delegate
3620
+ * to the corresponding `npx skills` subcommands from the upstream skills CLI.
3621
+ */
3622
+ const defaultExec = (cmd, args, opts) => {
3623
+ return { exitCode: spawnSync(cmd, args, {
3624
+ cwd: opts.cwd,
3625
+ stdio: "inherit"
3626
+ }).status ?? -1 };
3627
+ };
3603
3628
  async function runSkillsInstall(input) {
3604
3629
  const print = input.print ?? ((line) => console.log(line));
3605
3630
  const config = input.loaded.resolved;
@@ -3623,6 +3648,36 @@ async function runSkillsInstall(input) {
3623
3648
  print(` ✗ ${err instanceof Error ? err.message : String(err)}`);
3624
3649
  }
3625
3650
  }
3651
+ function runSkillsRemove(input) {
3652
+ const { dryRun, repoRoot } = input.context;
3653
+ const exec = input.exec ?? defaultExec;
3654
+ const args = [
3655
+ "skills",
3656
+ "remove",
3657
+ ...input.names ?? []
3658
+ ];
3659
+ if (dryRun) {
3660
+ console.log(`Would run: npx ${args.join(" ")}`);
3661
+ return { status: "dry-run" };
3662
+ }
3663
+ const { exitCode } = exec("npx", args, { cwd: repoRoot });
3664
+ return { status: exitCode === 0 ? "ok" : "fail" };
3665
+ }
3666
+ function runSkillsUpdate(input) {
3667
+ const { dryRun, repoRoot } = input.context;
3668
+ const exec = input.exec ?? defaultExec;
3669
+ const args = [
3670
+ "skills",
3671
+ "update",
3672
+ ...input.name ? [input.name] : []
3673
+ ];
3674
+ if (dryRun) {
3675
+ console.log(`Would run: npx ${args.join(" ")}`);
3676
+ return { status: "dry-run" };
3677
+ }
3678
+ const { exitCode } = exec("npx", args, { cwd: repoRoot });
3679
+ return { status: exitCode === 0 ? "ok" : "fail" };
3680
+ }
3626
3681
  //#endregion
3627
3682
  //#region src/commands/sync.ts
3628
3683
  const SYNC_STEPS = [
@@ -4058,19 +4113,38 @@ await yargs(hideBin(process.argv)).scriptName("holocron").usage("$0 <command> [o
4058
4113
  ...argv.token ? { cliToken: argv.token } : {}
4059
4114
  }
4060
4115
  })).summary.fail > 0) process.exitCode = 1;
4061
- }).command("skills <action>", "Manage agent skills from the @theholocron/skills registry", (y) => y.positional("action", {
4062
- type: "string",
4063
- choices: ["install"],
4064
- describe: "install — copy skills from @theholocron/skills into .agents/ with agent symlinks"
4065
- }), async (argv) => {
4066
- if (argv.action === "install") await runSkillsInstall({
4116
+ }).command("skills", "Manage agent skills from the @theholocron/skills registry", (y) => y.command("install", "Copy skills from @theholocron/skills into .agents/ with agent symlinks", () => {}, async (argv) => {
4117
+ await runSkillsInstall({
4067
4118
  loaded: await loadConfig(argv.cwd),
4068
4119
  context: {
4069
4120
  repoRoot: argv.cwd,
4070
4121
  dryRun: argv.dryRun
4071
4122
  }
4072
4123
  });
4073
- }).command("secret set <name> [value]", "Set a single secret via the configured `secrets` capability", (y) => y.positional("name", {
4124
+ }).command("remove [names..]", "Remove installed skills via npx skills remove", (yy) => yy.positional("names", {
4125
+ type: "string",
4126
+ array: true,
4127
+ describe: "Skill name(s) to remove (omit to remove all installed skills)"
4128
+ }), (argv) => {
4129
+ if (runSkillsRemove({
4130
+ context: {
4131
+ repoRoot: argv.cwd,
4132
+ dryRun: argv.dryRun
4133
+ },
4134
+ ...argv.names?.length ? { names: argv.names } : {}
4135
+ }).status === "fail") process.exitCode = 1;
4136
+ }).command("update [name]", "Update installed skills to their latest upstream versions via npx skills update", (yy) => yy.positional("name", {
4137
+ type: "string",
4138
+ describe: "Skill name to update (omit to update all installed skills)"
4139
+ }), (argv) => {
4140
+ if (runSkillsUpdate({
4141
+ context: {
4142
+ repoRoot: argv.cwd,
4143
+ dryRun: argv.dryRun
4144
+ },
4145
+ ...argv.name ? { name: argv.name } : {}
4146
+ }).status === "fail") process.exitCode = 1;
4147
+ }).demandCommand(1, "Run `holocron skills --help` to see available skills subcommands."), () => {}).command("secret set <name> [value]", "Set a single secret via the configured `secrets` capability", (y) => y.positional("name", {
4074
4148
  type: "string",
4075
4149
  demandOption: true,
4076
4150
  describe: "Secret name (e.g., NPM_TOKEN)"
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@theholocron/cli",
3
- "version": "2.0.0-alpha.71",
3
+ "version": "2.0.0-alpha.73",
4
4
  "description": "The Holocron CLI — a pluggable, capability-based orchestrator for spinning up and operating software projects.",
5
5
  "homepage": "https://github.com/theholocron/holocron/tree/main/packages/cli#readme",
6
6
  "bugs": "https://github.com/theholocron/holocron/issues",