@theholocron/cli 4.18.1 → 4.18.3

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/README.md CHANGED
@@ -157,10 +157,13 @@ export default defineConfig({
157
157
  ```
158
158
 
159
159
  `holocron setup` writes `.husky/pre-push` (runs `holocron ci` before every
160
- push) and sets `package.json#scripts.prepare` to `husky`. On by default for
160
+ push) and `.husky/pre-commit` (runs `gitleaks protect --staged` + `lint-staged`
161
+ before every commit — scoped to staged changes, not the whole history, so a
162
+ past false positive can't permanently block future commits) and sets
163
+ `package.json#scripts.prepare` to `husky`. Both on by default for
161
164
  `protection: "strict"`; `false` / `{ prePush: false }` opts out. `holocron
162
165
  setup --hooks` / `--no-hooks` override per run. Bypass one push with `git push
163
- --no-verify`.
166
+ --no-verify`; bypass one commit with `git commit --no-verify`.
164
167
 
165
168
  ### Task scripts
166
169
 
package/dist/cli.mjs CHANGED
@@ -3563,19 +3563,19 @@ var alexrc_default = { allow: [
3563
3563
  ] };
3564
3564
  //#endregion
3565
3565
  //#region src/templates/configs/alexjs/create-config.ts
3566
- const { workflowHeader: workflowHeader$6 } = createHeader({ source: "packages/cli/src/templates/configs/alexjs/create-config.ts" });
3566
+ const { workflowHeader: workflowHeader$7 } = createHeader({ source: "packages/cli/src/templates/configs/alexjs/create-config.ts" });
3567
3567
  function createRcConfig() {
3568
3568
  return JSON.stringify(alexrc_default, null, 2) + "\n";
3569
3569
  }
3570
3570
  function createIgnoreConfig() {
3571
- return `${workflowHeader$6()}${alexignore_default}`;
3571
+ return `${workflowHeader$7()}${alexignore_default}`;
3572
3572
  }
3573
3573
  //#endregion
3574
3574
  //#region src/templates/configs/devmoji/create-config.ts
3575
- const { workflowHeader: workflowHeader$5 } = createHeader({ source: "packages/cli/src/templates/configs/devmoji/create-config.ts" });
3576
- function createConfig$4() {
3575
+ const { workflowHeader: workflowHeader$6 } = createHeader({ source: "packages/cli/src/templates/configs/devmoji/create-config.ts" });
3576
+ function createConfig$5() {
3577
3577
  return [
3578
- workflowHeader$5("cjs"),
3578
+ workflowHeader$6("cjs"),
3579
3579
  `/* eslint-disable */`,
3580
3580
  `const { defineConfig } = require("@theholocron/devmoji-config");`,
3581
3581
  `module.exports = defineConfig();`,
@@ -3587,9 +3587,9 @@ function createConfig$4() {
3587
3587
  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";
3588
3588
  //#endregion
3589
3589
  //#region src/templates/configs/editorconfig/create-config.ts
3590
- const { workflowHeader: workflowHeader$4 } = createHeader({ source: "packages/cli/src/templates/configs/editorconfig/create-config.ts" });
3591
- function createConfig$3() {
3592
- return `${workflowHeader$4()}${editorconfig_default}`;
3590
+ const { workflowHeader: workflowHeader$5 } = createHeader({ source: "packages/cli/src/templates/configs/editorconfig/create-config.ts" });
3591
+ function createConfig$4() {
3592
+ return `${workflowHeader$5()}${editorconfig_default}`;
3593
3593
  }
3594
3594
  //#endregion
3595
3595
  //#region src/templates/configs/editorconfig-checker/editorconfig-checker.json
@@ -3630,10 +3630,31 @@ var editorconfig_checker_default = {
3630
3630
  * options here (`Exclude`, `Disable`) are stable across releases, so pinning
3631
3631
  * buys nothing.
3632
3632
  */
3633
- function createConfig$2() {
3633
+ function createConfig$3() {
3634
3634
  return JSON.stringify(editorconfig_checker_default, null, 2) + "\n";
3635
3635
  }
3636
3636
  //#endregion
3637
+ //#region src/templates/configs/pre-commit/pre-commit
3638
+ var pre_commit_default = "# Run GitLeaks against staged changes only — a full `gitleaks git` history\n# scan re-flags every pre-existing (already-merged) finding on every commit,\n# permanently blocking the repo once any false positive lands in history.\n# CI's super-linter GITLEAKS validator is likewise scoped to changed files.\ngitleaks protect --staged --no-banner\n\n# Exit with non-zero if secrets are detected by GitLeaks\nif [ $? -ne 0 ]; then\n echo \"Secrets detected by GitLeaks, aborting commit!\"\n exit 1\nfi\n\n# Run lint-staged with a custom config\nnpx lint-staged --config @theholocron/lint-staged-config\n";
3639
+ //#endregion
3640
+ //#region src/templates/configs/pre-commit/create-config.ts
3641
+ const { workflowHeader: workflowHeader$4 } = createHeader({ source: "packages/cli/src/templates/configs/pre-commit/create-config.ts" });
3642
+ /**
3643
+ * `.husky/pre-commit` — runs GitLeaks (scoped to staged changes) and
3644
+ * lint-staged before every commit. Installed by `holocron setup` when hooks
3645
+ * are enabled (default for `protection: "strict"`). `git commit --no-verify`
3646
+ * bypasses it.
3647
+ *
3648
+ * `gitleaks protect --staged` (not `gitleaks git`) is deliberate: the latter
3649
+ * scans the entire commit history on every invocation, so once any false
3650
+ * positive lands in a past commit — a fake test token, an example key in a
3651
+ * doc — every future commit is permanently blocked, regardless of what's
3652
+ * actually staged.
3653
+ */
3654
+ function createConfig$2() {
3655
+ return `${workflowHeader$4("shebang")}${pre_commit_default}`;
3656
+ }
3657
+ //#endregion
3637
3658
  //#region src/templates/configs/pre-push/pre-push
3638
3659
  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";
3639
3660
  //#endregion
@@ -4606,15 +4627,15 @@ async function runSetup(input) {
4606
4627
  }));
4607
4628
  print(formatStep(steps[steps.length - 1]));
4608
4629
  steps.push(await runStep("source", "write .editorconfig", dryRun, async () => {
4609
- await source.writeRepoFile(".editorconfig", createConfig$3());
4630
+ await source.writeRepoFile(".editorconfig", createConfig$4());
4610
4631
  }));
4611
4632
  print(formatStep(steps[steps.length - 1]));
4612
4633
  steps.push(await runStep("source", "write .editorconfig-checker.json", dryRun, async () => {
4613
- await source.writeRepoFile(".editorconfig-checker.json", createConfig$2());
4634
+ await source.writeRepoFile(".editorconfig-checker.json", createConfig$3());
4614
4635
  }));
4615
4636
  print(formatStep(steps[steps.length - 1]));
4616
4637
  steps.push(await runStep("source", "write devmoji.config.cjs", dryRun, async () => {
4617
- await source.writeRepoFile("devmoji.config.cjs", createConfig$4());
4638
+ await source.writeRepoFile("devmoji.config.cjs", createConfig$5());
4618
4639
  }));
4619
4640
  print(formatStep(steps[steps.length - 1]));
4620
4641
  steps.push(await runStep("source", "write .husky/prepare-commit-msg", dryRun, async () => {
@@ -4627,6 +4648,11 @@ async function runSetup(input) {
4627
4648
  return "runs `holocron ci` before push — bypass with `git push --no-verify`";
4628
4649
  }));
4629
4650
  print(formatStep(steps[steps.length - 1]));
4651
+ steps.push(await runStep("source", "write .husky/pre-commit", dryRun, async () => {
4652
+ await source.writeRepoFile(".husky/pre-commit", createConfig$2());
4653
+ return "runs GitLeaks (staged-only) + lint-staged before commit";
4654
+ }));
4655
+ print(formatStep(steps[steps.length - 1]));
4630
4656
  if (config.syncScripts !== false) {
4631
4657
  steps.push(await runStep("source", "set package.json prepare script", dryRun, async () => {
4632
4658
  return await ensurePrepareScript(input.context.repoRoot) ? "prepare now runs husky" : "already runs husky";
@@ -4641,6 +4667,13 @@ async function runSetup(input) {
4641
4667
  message: "git hooks disabled"
4642
4668
  });
4643
4669
  print(formatStep(steps[steps.length - 1]));
4670
+ steps.push({
4671
+ capability: "source",
4672
+ step: "write .husky/pre-commit",
4673
+ status: "skip",
4674
+ message: "git hooks disabled"
4675
+ });
4676
+ print(formatStep(steps[steps.length - 1]));
4644
4677
  }
4645
4678
  {
4646
4679
  const hasTestWorkflow = (config.tasks ?? []).map((e) => typeof e === "string" ? e : e.name).includes("test");