@theholocron/cli 4.9.0 → 4.10.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/cli.mjs +80 -15
- package/dist/cli.mjs.map +1 -1
- package/dist/index.d.mts +12 -0
- package/dist/index.mjs +1 -0
- package/package.json +5 -5
package/dist/cli.mjs
CHANGED
|
@@ -284,6 +284,7 @@ function resolveConfig(raw) {
|
|
|
284
284
|
syncScripts: raw.syncScripts,
|
|
285
285
|
holocronScript: raw.holocronScript,
|
|
286
286
|
extraRequiredChecks: raw.extraRequiredChecks,
|
|
287
|
+
hooks: raw.hooks,
|
|
287
288
|
providers,
|
|
288
289
|
apps: raw.apps ?? [],
|
|
289
290
|
doctor: raw.doctor ?? {},
|
|
@@ -3374,12 +3375,12 @@ var alexrc_default = { allow: [
|
|
|
3374
3375
|
] };
|
|
3375
3376
|
//#endregion
|
|
3376
3377
|
//#region src/templates/configs/alexjs/create-config.ts
|
|
3377
|
-
const { workflowHeader: workflowHeader$
|
|
3378
|
+
const { workflowHeader: workflowHeader$7 } = createHeader({ source: "packages/cli/src/templates/configs/alexjs/create-config.ts" });
|
|
3378
3379
|
function createRcConfig() {
|
|
3379
3380
|
return JSON.stringify(alexrc_default, null, 2) + "\n";
|
|
3380
3381
|
}
|
|
3381
3382
|
function createIgnoreConfig() {
|
|
3382
|
-
return `${workflowHeader$
|
|
3383
|
+
return `${workflowHeader$7()}${alexignore_default}`;
|
|
3383
3384
|
}
|
|
3384
3385
|
//#endregion
|
|
3385
3386
|
//#region src/templates/configs/codecov/codecov.yml
|
|
@@ -3423,15 +3424,15 @@ async function readWorkspacePackages(repoRoot) {
|
|
|
3423
3424
|
//#endregion
|
|
3424
3425
|
//#region src/templates/configs/codecov/create-config.ts
|
|
3425
3426
|
const { scaffoldHeader } = createHeader({ source: "packages/cli/src/templates/configs/codecov/create-config.ts" });
|
|
3426
|
-
function createConfig$
|
|
3427
|
+
function createConfig$5(packages) {
|
|
3427
3428
|
return `${scaffoldHeader()}${codecov_default.trimEnd()}${codecovComponentBlock(packages)}`;
|
|
3428
3429
|
}
|
|
3429
3430
|
//#endregion
|
|
3430
3431
|
//#region src/templates/configs/devmoji/create-config.ts
|
|
3431
|
-
const { workflowHeader: workflowHeader$
|
|
3432
|
-
function createConfig$
|
|
3432
|
+
const { workflowHeader: workflowHeader$6 } = createHeader({ source: "packages/cli/src/templates/configs/devmoji/create-config.ts" });
|
|
3433
|
+
function createConfig$4() {
|
|
3433
3434
|
return [
|
|
3434
|
-
workflowHeader$
|
|
3435
|
+
workflowHeader$6("cjs"),
|
|
3435
3436
|
`/* eslint-disable */`,
|
|
3436
3437
|
`const { defineConfig } = require("@theholocron/devmoji-config");`,
|
|
3437
3438
|
`module.exports = defineConfig();`,
|
|
@@ -3443,9 +3444,9 @@ function createConfig$3() {
|
|
|
3443
3444
|
var editorconfig_default = "root = true\n\n[*]\nend_of_line = lf\ncharset = utf-8\ntrim_trailing_whitespace = true\ninsert_final_newline = true\nindent_style = tab\nindent_size = 4\n\n[.gitattributes]\nindent_style = space\nindent_size = 2\n\n[*.{json,yml,yaml}]\nindent_style = space\nindent_size = 2\n\n[*.{md,mdx}]\ntrim_trailing_whitespace = false\n\n[.*{rc,ignore}]\nindent_style = space\nindent_size = 2\n";
|
|
3444
3445
|
//#endregion
|
|
3445
3446
|
//#region src/templates/configs/editorconfig/create-config.ts
|
|
3446
|
-
const { workflowHeader: workflowHeader$
|
|
3447
|
-
function createConfig$
|
|
3448
|
-
return `${workflowHeader$
|
|
3447
|
+
const { workflowHeader: workflowHeader$5 } = createHeader({ source: "packages/cli/src/templates/configs/editorconfig/create-config.ts" });
|
|
3448
|
+
function createConfig$3() {
|
|
3449
|
+
return `${workflowHeader$5()}${editorconfig_default}`;
|
|
3449
3450
|
}
|
|
3450
3451
|
//#endregion
|
|
3451
3452
|
//#region src/templates/configs/editorconfig-checker/editorconfig-checker.json
|
|
@@ -3476,10 +3477,27 @@ var editorconfig_checker_default = {
|
|
|
3476
3477
|
};
|
|
3477
3478
|
//#endregion
|
|
3478
3479
|
//#region src/templates/configs/editorconfig-checker/create-config.ts
|
|
3479
|
-
function createConfig$
|
|
3480
|
+
function createConfig$2() {
|
|
3480
3481
|
return JSON.stringify(editorconfig_checker_default, null, 2) + "\n";
|
|
3481
3482
|
}
|
|
3482
3483
|
//#endregion
|
|
3484
|
+
//#region src/templates/configs/pre-push/pre-push
|
|
3485
|
+
var pre_push_default = "# Run the merge-gating checks locally before pushing — the same set CI runs.\n# Bypass once with: git push --no-verify\n\n# CI runners (semantic-release, super-linter auto-commit, bots) push without a\n# built dev environment — the hook has nothing to add there.\n[ -n \"$CI\" ] && exit 0\n\n__HOLOCRON_SCRIPT__ ci\n";
|
|
3486
|
+
//#endregion
|
|
3487
|
+
//#region src/templates/configs/pre-push/create-config.ts
|
|
3488
|
+
const { workflowHeader: workflowHeader$4 } = createHeader({ source: "packages/cli/src/templates/configs/pre-push/create-config.ts" });
|
|
3489
|
+
/**
|
|
3490
|
+
* `.husky/pre-push` — runs `holocron ci` (the merge-gating checks, in CI order)
|
|
3491
|
+
* before every push. Installed by `holocron setup` when hooks are enabled
|
|
3492
|
+
* (default for `protection: "strict"`). `git push --no-verify` bypasses it.
|
|
3493
|
+
*
|
|
3494
|
+
* @param holocronScript - the command that invokes the CLI. Defaults to
|
|
3495
|
+
* `pnpm exec holocron`; the source repo passes `node packages/cli/dist/cli.mjs`.
|
|
3496
|
+
*/
|
|
3497
|
+
function createConfig$1(holocronScript = "pnpm exec holocron") {
|
|
3498
|
+
return `${workflowHeader$4("shebang")}${pre_push_default.replace("__HOLOCRON_SCRIPT__", holocronScript)}`;
|
|
3499
|
+
}
|
|
3500
|
+
//#endregion
|
|
3483
3501
|
//#region src/templates/configs/prepare-commit-msg/prepare-commit-msg
|
|
3484
3502
|
var prepare_commit_msg_default = "NAME=$(git config user.name)\nEMAIL=$(git config user.email)\n\nif [ -z \"$NAME\" ]; then\n echo \"empty git config user.name\"\n exit 1\nfi\n\nif [ -z \"$EMAIL\" ]; then\n echo \"empty git config user.email\"\n exit 1\nfi\n\ngit interpret-trailers --if-exists doNothing --trailer \\\n \"Signed-off-by: $NAME <$EMAIL>\" \\\n --in-place \"$1\"\n\nnpx devmoji -e\n";
|
|
3485
3503
|
//#endregion
|
|
@@ -4319,6 +4337,7 @@ async function runSetup(input) {
|
|
|
4319
4337
|
const steps = [];
|
|
4320
4338
|
const repo = config.repo;
|
|
4321
4339
|
const effectivePreset = repo?.protection;
|
|
4340
|
+
const hooksEnabled = input.hooks ?? (typeof config.hooks === "boolean" ? config.hooks : typeof config.hooks === "object" ? config.hooks.prePush !== false : effectivePreset === "strict");
|
|
4322
4341
|
print(style.header(`Holocron setup — ${config.name}${dryRun ? " (dry-run)" : ""}`));
|
|
4323
4342
|
print(style.dim(` config: ${input.loaded.filepath}`));
|
|
4324
4343
|
print("");
|
|
@@ -4454,21 +4473,42 @@ async function runSetup(input) {
|
|
|
4454
4473
|
}));
|
|
4455
4474
|
print(formatStep(steps[steps.length - 1]));
|
|
4456
4475
|
steps.push(await runStep("source", "write .editorconfig", dryRun, async () => {
|
|
4457
|
-
await source.writeRepoFile(".editorconfig", createConfig$
|
|
4476
|
+
await source.writeRepoFile(".editorconfig", createConfig$3());
|
|
4458
4477
|
}));
|
|
4459
4478
|
print(formatStep(steps[steps.length - 1]));
|
|
4460
4479
|
steps.push(await runStep("source", "write .editorconfig-checker.json", dryRun, async () => {
|
|
4461
|
-
await source.writeRepoFile(".editorconfig-checker.json", createConfig$
|
|
4480
|
+
await source.writeRepoFile(".editorconfig-checker.json", createConfig$2());
|
|
4462
4481
|
}));
|
|
4463
4482
|
print(formatStep(steps[steps.length - 1]));
|
|
4464
4483
|
steps.push(await runStep("source", "write devmoji.config.cjs", dryRun, async () => {
|
|
4465
|
-
await source.writeRepoFile("devmoji.config.cjs", createConfig$
|
|
4484
|
+
await source.writeRepoFile("devmoji.config.cjs", createConfig$4());
|
|
4466
4485
|
}));
|
|
4467
4486
|
print(formatStep(steps[steps.length - 1]));
|
|
4468
4487
|
steps.push(await runStep("source", "write .husky/prepare-commit-msg", dryRun, async () => {
|
|
4469
4488
|
await source.writeRepoFile(".husky/prepare-commit-msg", createConfig());
|
|
4470
4489
|
}));
|
|
4471
4490
|
print(formatStep(steps[steps.length - 1]));
|
|
4491
|
+
if (hooksEnabled) {
|
|
4492
|
+
steps.push(await runStep("source", "write .husky/pre-push", dryRun, async () => {
|
|
4493
|
+
await source.writeRepoFile(".husky/pre-push", createConfig$1(config.holocronScript));
|
|
4494
|
+
return "runs `holocron ci` before push — bypass with `git push --no-verify`";
|
|
4495
|
+
}));
|
|
4496
|
+
print(formatStep(steps[steps.length - 1]));
|
|
4497
|
+
if (config.syncScripts !== false) {
|
|
4498
|
+
steps.push(await runStep("source", "set package.json prepare script", dryRun, async () => {
|
|
4499
|
+
return await ensurePrepareScript(input.context.repoRoot) ? "prepare = \"husky\"" : "already set";
|
|
4500
|
+
}));
|
|
4501
|
+
print(formatStep(steps[steps.length - 1]));
|
|
4502
|
+
}
|
|
4503
|
+
} else {
|
|
4504
|
+
steps.push({
|
|
4505
|
+
capability: "source",
|
|
4506
|
+
step: "write .husky/pre-push",
|
|
4507
|
+
status: "skip",
|
|
4508
|
+
message: "git hooks disabled"
|
|
4509
|
+
});
|
|
4510
|
+
print(formatStep(steps[steps.length - 1]));
|
|
4511
|
+
}
|
|
4472
4512
|
{
|
|
4473
4513
|
const hasTestWorkflow = (config.tasks ?? []).map((e) => typeof e === "string" ? e : e.name).includes("test");
|
|
4474
4514
|
const packages = await readWorkspacePackages(input.context.repoRoot);
|
|
@@ -4480,7 +4520,7 @@ async function runSetup(input) {
|
|
|
4480
4520
|
message: "no test workflow configured"
|
|
4481
4521
|
});
|
|
4482
4522
|
else steps.push(await runStep("source", "write codecov.yml", dryRun, async () => {
|
|
4483
|
-
const content = existing != null ? mergeCodecovComponents(existing, packages) : createConfig$
|
|
4523
|
+
const content = existing != null ? mergeCodecovComponents(existing, packages) : createConfig$5(packages);
|
|
4484
4524
|
await source.writeRepoFile("codecov.yml", content);
|
|
4485
4525
|
return packages.length > 0 ? `${packages.length} components` : "no components";
|
|
4486
4526
|
}));
|
|
@@ -4854,6 +4894,27 @@ async function runSetup(input) {
|
|
|
4854
4894
|
summary
|
|
4855
4895
|
};
|
|
4856
4896
|
}
|
|
4897
|
+
/**
|
|
4898
|
+
* Ensure `package.json#scripts.prepare` is `"husky"` so git hooks register on
|
|
4899
|
+
* install. Merge-only: leaves every other script untouched. Returns `true` when
|
|
4900
|
+
* it wrote a change, `false` when already set or there is no `package.json`.
|
|
4901
|
+
*/
|
|
4902
|
+
async function ensurePrepareScript(repoRoot) {
|
|
4903
|
+
const pkgPath = join(repoRoot, "package.json");
|
|
4904
|
+
let content;
|
|
4905
|
+
try {
|
|
4906
|
+
content = await readFile(pkgPath, "utf8");
|
|
4907
|
+
} catch {
|
|
4908
|
+
return false;
|
|
4909
|
+
}
|
|
4910
|
+
const pkg = JSON.parse(content);
|
|
4911
|
+
const scripts = pkg.scripts ?? {};
|
|
4912
|
+
if (scripts.prepare === "husky") return false;
|
|
4913
|
+
scripts.prepare = "husky";
|
|
4914
|
+
pkg.scripts = scripts;
|
|
4915
|
+
await writeFile(pkgPath, JSON.stringify(pkg, null, 2) + "\n", "utf8");
|
|
4916
|
+
return true;
|
|
4917
|
+
}
|
|
4857
4918
|
//#endregion
|
|
4858
4919
|
//#region src/commands/skills.ts
|
|
4859
4920
|
/**
|
|
@@ -6834,6 +6895,9 @@ try {
|
|
|
6834
6895
|
}).command("setup", "Apply infra setup actions across every configured capability", (y) => y.option("repo", {
|
|
6835
6896
|
type: "string",
|
|
6836
6897
|
describe: "Repo coords (\"owner/name\"). Defaults to plugin-specific resolution."
|
|
6898
|
+
}).option("hooks", {
|
|
6899
|
+
type: "boolean",
|
|
6900
|
+
describe: "Install git hooks (.husky/pre-push → holocron ci). Default: on for protection:'strict'. --no-hooks to skip."
|
|
6837
6901
|
}), async (argv) => {
|
|
6838
6902
|
const tokens = tokenContext(argv.token);
|
|
6839
6903
|
if (!tokens) return;
|
|
@@ -6847,7 +6911,8 @@ try {
|
|
|
6847
6911
|
...argv.repo ? { repo: argv.repo } : {},
|
|
6848
6912
|
...tokens,
|
|
6849
6913
|
org: resolveOrg(argv, loaded.resolved)
|
|
6850
|
-
}
|
|
6914
|
+
},
|
|
6915
|
+
...argv.hooks !== void 0 ? { hooks: argv.hooks } : {}
|
|
6851
6916
|
})).summary.fail > 0) process.exitCode = 1;
|
|
6852
6917
|
}).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) => {
|
|
6853
6918
|
await runSkillsInstall({
|