@edcalderon/versioning 1.2.0 → 1.3.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.
Files changed (31) hide show
  1. package/README.md +121 -14
  2. package/dist/cli.js +76 -4
  3. package/dist/extensions/{cleanup-repo-extension.d.ts → cleanup-repo/index.d.ts} +2 -2
  4. package/dist/extensions/{cleanup-repo-extension.js → cleanup-repo/index.js} +40 -32
  5. package/dist/extensions/lifecycle-hooks/index.d.ts +4 -0
  6. package/dist/extensions/{lifecycle-hooks.js → lifecycle-hooks/index.js} +1 -1
  7. package/dist/extensions/npm-publish/index.d.ts +4 -0
  8. package/dist/extensions/{npm-publish.js → npm-publish/index.js} +1 -1
  9. package/dist/extensions/reentry-status/config-manager.js +3 -1
  10. package/dist/extensions/reentry-status/constants.d.ts +1 -1
  11. package/dist/extensions/reentry-status/constants.js +1 -1
  12. package/dist/extensions/reentry-status/extension.d.ts +4 -0
  13. package/dist/extensions/{reentry-status-extension.js → reentry-status/extension.js} +14 -14
  14. package/dist/extensions/reentry-status/index.d.ts +2 -0
  15. package/dist/extensions/reentry-status/index.js +5 -0
  16. package/dist/extensions/sample-extension/index.d.ts +4 -0
  17. package/dist/extensions/{sample-extension.js → sample-extension/index.js} +1 -1
  18. package/dist/extensions/secrets-check/index.d.ts +16 -0
  19. package/dist/extensions/secrets-check/index.js +264 -0
  20. package/dist/extensions.js +27 -15
  21. package/dist/release.d.ts +16 -12
  22. package/dist/release.js +35 -1
  23. package/dist/versioning.d.ts +49 -0
  24. package/dist/versioning.js +313 -2
  25. package/examples/versioning.config.branch-aware.json +51 -0
  26. package/package.json +2 -2
  27. package/versioning.config.json +44 -1
  28. package/dist/extensions/lifecycle-hooks.d.ts +0 -4
  29. package/dist/extensions/npm-publish.d.ts +0 -4
  30. package/dist/extensions/reentry-status-extension.d.ts +0 -4
  31. package/dist/extensions/sample-extension.d.ts +0 -4
package/README.md CHANGED
@@ -5,13 +5,16 @@ A comprehensive versioning and changelog management tool designed for monorepos
5
5
  ## Features
6
6
 
7
7
  - 🚀 Automated version bumping (patch, minor, major, prerelease)
8
+ - 🌿 Optional branch-aware versioning (`main`, `develop`, `feature/*`, `hotfix/*`)
8
9
  - 📝 Conventional commit-based changelog generation
9
10
  - 🔄 Version synchronization across monorepo packages
10
11
  - 🎯 Works with both monorepos and single repositories
11
12
  - 📦 NPM publishable
12
13
  - 🏷️ Git tagging and committing
13
14
  - ✅ Validation of version sync
14
- - 🔌 **Extensible plugin system** for custom business logic
15
+ - 🔌 **Extensible plugin system** for subdirectory-based extensions
16
+ - 🔒 **Security Checks** with automatic Husky integration
17
+ - 🧹 **Repository Cleanup** to keep root directory organized
15
18
 
16
19
  ## Installation
17
20
 
@@ -33,7 +36,7 @@ The versioning tool supports a **composable extension system** that allows you t
33
36
  - Implement custom versioning strategies
34
37
 
35
38
  Extensions are loaded automatically from:
36
- - Built-in extensions in the `src/extensions/` directory
39
+ - Built-in extensions in subdirectories of `src/extensions/` (e.g. `src/extensions/reentry-status/index.ts`)
37
40
  - External packages listed in `versioning.config.json`
38
41
 
39
42
  ### Creating Extensions
@@ -172,20 +175,56 @@ versioning cleanup scan # Dry-run scan of root
172
175
  versioning cleanup move # Move files to configured destinations
173
176
  versioning cleanup restore # Restore a moved file
174
177
  versioning cleanup config # View/manage configuration
175
- versioning cleanup husky # Setup git hook
178
+ versioning cleanup husky # Setup git hook (scan-only by default)
176
179
  ```
177
180
 
178
181
  Configuration (`versioning.config.json`):
179
182
 
180
183
  ```json
181
184
  {
182
- "cleanup": {
183
- "enabled": true,
184
- "defaultDestination": "docs",
185
- "allowlist": ["CHANGELOG.md"],
186
- "routes": {
187
- ".sh": "scripts",
188
- ".json": "config"
185
+ "extensionConfig": {
186
+ "cleanup-repo": {
187
+ "enabled": true,
188
+ "defaultDestination": "docs",
189
+ "allowlist": ["CHANGELOG.md"],
190
+ "routes": {
191
+ ".sh": "scripts",
192
+ ".json": "config"
193
+ }
194
+ }
195
+ }
196
+ }
197
+ ```
198
+
199
+ #### Secrets Check Extension
200
+
201
+ Prevents sensitive data (private keys, tokens, mnemonics) from being committed to the repository.
202
+
203
+ Features:
204
+ - **Pre-defined Patterns:** Detects AWS, GitHub, NPM tokens, private keys, and EVM mnemonics.
205
+ - **Allowlist:** Ignore false positives or specific test keys.
206
+ - **Husky Integration:** Easy CLI setup to block commits containing secrets.
207
+
208
+ Commands:
209
+
210
+ ```bash
211
+ versioning check-secrets # Scan staged files for secrets
212
+ versioning check-secrets husky # Add blocking secrets check to pre-commit hook
213
+ ```
214
+
215
+ Configuration (`versioning.config.json`):
216
+
217
+ ```json
218
+ {
219
+ "extensionConfig": {
220
+ "secrets-check": {
221
+ "enabled": true,
222
+ "patterns": [
223
+ "CUSTOM_API_KEY=[0-9a-f]{32}"
224
+ ],
225
+ "allowlist": [
226
+ "ETHERSCAN_API_KEY=YOUR_KEY"
227
+ ]
189
228
  }
190
229
  }
191
230
  }
@@ -369,7 +408,41 @@ For single repositories:
369
408
  "changelogFile": "CHANGELOG.md",
370
409
  "conventionalCommits": true,
371
410
  "syncDependencies": false,
372
- "ignorePackages": []
411
+ "ignorePackages": [],
412
+ "branchAwareness": {
413
+ "enabled": false,
414
+ "defaultBranch": "main",
415
+ "branches": {
416
+ "main": {
417
+ "versionFormat": "semantic",
418
+ "tagFormat": "v{version}",
419
+ "syncFiles": ["package.json", "version.production.json"],
420
+ "environment": "production",
421
+ "bumpStrategy": "semantic"
422
+ },
423
+ "develop": {
424
+ "versionFormat": "dev",
425
+ "tagFormat": "v{version}",
426
+ "syncFiles": ["version.development.json"],
427
+ "environment": "development",
428
+ "bumpStrategy": "dev-build"
429
+ },
430
+ "feature/*": {
431
+ "versionFormat": "feature",
432
+ "tagFormat": "v{version}",
433
+ "syncFiles": ["version.development.json"],
434
+ "environment": "development",
435
+ "bumpStrategy": "feature-branch"
436
+ },
437
+ "hotfix/*": {
438
+ "versionFormat": "hotfix",
439
+ "tagFormat": "v{version}",
440
+ "syncFiles": ["version.development.json"],
441
+ "environment": "development",
442
+ "bumpStrategy": "hotfix"
443
+ }
444
+ }
445
+ }
373
446
  }
374
447
  ```
375
448
 
@@ -393,6 +466,28 @@ For monorepos:
393
466
  - `conventionalCommits`: Whether to use conventional commits for changelog
394
467
  - `syncDependencies`: Whether to sync internal dependencies
395
468
  - `ignorePackages`: Array of package names to ignore during sync
469
+ - `branchAwareness`: Optional branch-aware release rules and file sync targets
470
+ - `branchAwareness.branches.<pattern>.versionFormat`: `semantic`, `dev`, `feature`, `hotfix`, or custom
471
+ - `branchAwareness.branches.<pattern>.syncFiles`: Only these files are updated when branch-aware mode is enabled
472
+
473
+ ### Branch-Aware Releases
474
+
475
+ Enable branch-aware mode per command:
476
+
477
+ ```bash
478
+ versioning patch --branch-aware
479
+ versioning patch --branch-aware --target-branch develop
480
+ versioning patch --branch-aware --format dev --build 396
481
+ versioning minor --branch-aware
482
+ versioning major --branch-aware
483
+ ```
484
+
485
+ Behavior summary:
486
+ - Exact branch names are checked first (e.g. `main`, `develop`)
487
+ - Wildcard patterns are checked next (e.g. `feature/*`, `hotfix/*`)
488
+ - If no match is found, the `defaultBranch` rule is used
489
+ - `--force-branch-aware` enables branch-aware behavior even when `branchAwareness.enabled` is `false`
490
+ - Full config template: `packages/versioning/examples/versioning.config.branch-aware.json`
396
491
 
397
492
  ## Commands
398
493
 
@@ -433,13 +528,25 @@ versioning release 1.2.3 --message "Custom release"
433
528
  versioning release 2.0.0-beta.1 --skip-sync
434
529
  ```
435
530
 
436
- **Options for release commands:**
531
+ **Options for `patch`, `minor`, and `major`:**
532
+ - `-p, --packages <packages>`: Comma-separated list of packages to sync
533
+ - `-m, --message <message>`: Release commit message
534
+ - `-c, --config <file>`: Config file path (default: versioning.config.json)
535
+ - `--branch-aware`: Enable branch-aware release behavior
536
+ - `--force-branch-aware`: Force branch-aware mode even if disabled in config
537
+ - `--target-branch <branch>`: Explicit branch to resolve branch rules
538
+ - `--format <format>`: Override the configured branch version format
539
+ - `--build <number>`: Override build number for non-semantic branch formats
540
+ - `--no-tag`: Do not create git tag
541
+ - `--no-commit`: Do not commit changes
542
+
543
+ **Options for `release <version>`:**
437
544
  - `-p, --packages <packages>`: Comma-separated list of packages to sync
438
545
  - `-m, --message <message>`: Release commit message
439
546
  - `-c, --config <file>`: Config file path (default: versioning.config.json)
440
547
  - `--no-tag`: Do not create git tag
441
548
  - `--no-commit`: Do not commit changes
442
- - `--skip-sync`: Skip version synchronization (for `release` command)
549
+ - `--skip-sync`: Skip version synchronization
443
550
 
444
551
  ### Other Commands
445
552
 
@@ -586,4 +693,4 @@ Tags should follow the format `v{major}.{minor}.{patch}` (e.g., `v1.0.0`, `v1.1.
586
693
  The `create-tag` script will:
587
694
  - Read the version from `package.json`
588
695
  - Create an annotated git tag
589
- - Push the tag to trigger the publish workflow
696
+ - Push the tag to trigger the publish workflow
package/dist/cli.js CHANGED
@@ -161,6 +161,11 @@ program
161
161
  .option('-p, --packages <packages>', 'Comma-separated list of packages to sync')
162
162
  .option('-m, --message <message>', 'Release commit message')
163
163
  .option('-c, --config <file>', 'Config file path', 'versioning.config.json')
164
+ .option('--branch-aware', 'Enable branch-aware versioning')
165
+ .option('--force-branch-aware', 'Force branch-aware mode even if disabled in config')
166
+ .option('--target-branch <branch>', 'Explicit branch to apply branch-aware rules')
167
+ .option('--format <format>', 'Override version format (semantic, dev, feature, hotfix)')
168
+ .option('--build <number>', 'Override build number for non-semantic formats', parseBuildOption)
164
169
  .option('--no-tag', 'Do not create git tag')
165
170
  .option('--no-commit', 'Do not commit changes')
166
171
  .action(async (options) => {
@@ -179,7 +184,12 @@ program
179
184
  const packages = options.packages ? options.packages.split(',').map((p) => p.trim()) : undefined;
180
185
  const newVersion = await releaseManager.patchRelease({
181
186
  packages,
182
- message: options.message
187
+ message: options.message,
188
+ branchAware: options.branchAware,
189
+ forceBranchAware: options.forceBranchAware,
190
+ targetBranch: options.targetBranch,
191
+ format: options.format,
192
+ build: options.build
183
193
  });
184
194
  console.log(`✅ Patch release v${newVersion} completed`);
185
195
  }
@@ -194,6 +204,11 @@ program
194
204
  .option('-p, --packages <packages>', 'Comma-separated list of packages to sync')
195
205
  .option('-m, --message <message>', 'Release commit message')
196
206
  .option('-c, --config <file>', 'Config file path', 'versioning.config.json')
207
+ .option('--branch-aware', 'Enable branch-aware versioning')
208
+ .option('--force-branch-aware', 'Force branch-aware mode even if disabled in config')
209
+ .option('--target-branch <branch>', 'Explicit branch to apply branch-aware rules')
210
+ .option('--format <format>', 'Override version format (semantic, dev, feature, hotfix)')
211
+ .option('--build <number>', 'Override build number for non-semantic formats', parseBuildOption)
197
212
  .option('--no-tag', 'Do not create git tag')
198
213
  .option('--no-commit', 'Do not commit changes')
199
214
  .action(async (options) => {
@@ -212,7 +227,12 @@ program
212
227
  const packages = options.packages ? options.packages.split(',').map((p) => p.trim()) : undefined;
213
228
  const newVersion = await releaseManager.minorRelease({
214
229
  packages,
215
- message: options.message
230
+ message: options.message,
231
+ branchAware: options.branchAware,
232
+ forceBranchAware: options.forceBranchAware,
233
+ targetBranch: options.targetBranch,
234
+ format: options.format,
235
+ build: options.build
216
236
  });
217
237
  console.log(`✅ Minor release v${newVersion} completed`);
218
238
  }
@@ -225,7 +245,13 @@ program
225
245
  .command('major')
226
246
  .description('Create a major release')
227
247
  .option('-p, --packages <packages>', 'Comma-separated list of packages to sync')
248
+ .option('-m, --message <message>', 'Release commit message')
228
249
  .option('-c, --config <file>', 'Config file path', 'versioning.config.json')
250
+ .option('--branch-aware', 'Enable branch-aware versioning')
251
+ .option('--force-branch-aware', 'Force branch-aware mode even if disabled in config')
252
+ .option('--target-branch <branch>', 'Explicit branch to apply branch-aware rules')
253
+ .option('--format <format>', 'Override version format (semantic, dev, feature, hotfix)')
254
+ .option('--build <number>', 'Override build number for non-semantic formats', parseBuildOption)
229
255
  .option('--no-tag', 'Do not create git tag')
230
256
  .option('--no-commit', 'Do not commit changes')
231
257
  .action(async (options) => {
@@ -244,7 +270,12 @@ program
244
270
  const packages = options.packages ? options.packages.split(',').map((p) => p.trim()) : undefined;
245
271
  const newVersion = await releaseManager.majorRelease({
246
272
  packages,
247
- message: options.message
273
+ message: options.message,
274
+ branchAware: options.branchAware,
275
+ forceBranchAware: options.forceBranchAware,
276
+ targetBranch: options.targetBranch,
277
+ format: options.format,
278
+ build: options.build
248
279
  });
249
280
  console.log(`✅ Major release v${newVersion} completed`);
250
281
  }
@@ -306,7 +337,41 @@ program
306
337
  conventionalCommits: true,
307
338
  syncDependencies: false,
308
339
  ignorePackages: [],
309
- extensions: [] // Add extensions array to config
340
+ extensions: [], // Add extensions array to config
341
+ branchAwareness: {
342
+ enabled: false,
343
+ defaultBranch: 'main',
344
+ branches: {
345
+ main: {
346
+ versionFormat: 'semantic',
347
+ tagFormat: 'v{version}',
348
+ syncFiles: ['package.json'],
349
+ environment: 'production',
350
+ bumpStrategy: 'semantic'
351
+ },
352
+ develop: {
353
+ versionFormat: 'dev',
354
+ tagFormat: 'v{version}',
355
+ syncFiles: ['version.development.json'],
356
+ environment: 'development',
357
+ bumpStrategy: 'dev-build'
358
+ },
359
+ 'feature/*': {
360
+ versionFormat: 'feature',
361
+ tagFormat: 'v{version}',
362
+ syncFiles: ['version.development.json'],
363
+ environment: 'development',
364
+ bumpStrategy: 'feature-branch'
365
+ },
366
+ 'hotfix/*': {
367
+ versionFormat: 'hotfix',
368
+ tagFormat: 'v{version}',
369
+ syncFiles: ['version.development.json'],
370
+ environment: 'development',
371
+ bumpStrategy: 'hotfix'
372
+ }
373
+ }
374
+ }
310
375
  };
311
376
  await fs.writeJson(configPath, defaultConfig, { spaces: 2 });
312
377
  console.log('✅ Initialized versioning config at versioning.config.json');
@@ -322,6 +387,13 @@ async function loadConfig(configPath) {
322
387
  }
323
388
  return await fs.readJson(configPath);
324
389
  }
390
+ function parseBuildOption(value) {
391
+ const parsed = Number.parseInt(value, 10);
392
+ if (!Number.isInteger(parsed) || parsed < 0) {
393
+ throw new Error(`Invalid build number "${value}". Use a non-negative integer.`);
394
+ }
395
+ return parsed;
396
+ }
325
397
  async function main() {
326
398
  try {
327
399
  // Load and register extensions
@@ -1,4 +1,4 @@
1
- import { VersioningExtension } from '../extensions';
1
+ import { VersioningExtension } from '../../extensions';
2
2
  /**
3
3
  * The canonical cleanup configuration schema.
4
4
  * Everything the plugin needs lives here.
@@ -46,4 +46,4 @@ declare function loadCleanupConfig(rootConfig: any): CleanupRepoConfig;
46
46
  declare const extension: VersioningExtension;
47
47
  export { loadCleanupConfig, BUILTIN_ALLOWLIST, DEFAULT_EXTENSIONS, DEFAULT_ROUTES };
48
48
  export default extension;
49
- //# sourceMappingURL=cleanup-repo-extension.d.ts.map
49
+ //# sourceMappingURL=index.d.ts.map
@@ -124,7 +124,7 @@ exports.DEFAULT_ROUTES = DEFAULT_ROUTES;
124
124
  // CONFIG LOADER
125
125
  // ─────────────────────────────────────────────────────────────────
126
126
  function loadCleanupConfig(rootConfig) {
127
- const raw = rootConfig?.cleanup ?? {};
127
+ const raw = rootConfig?.extensionConfig?.['cleanup-repo'] ?? rootConfig?.cleanup ?? {};
128
128
  return {
129
129
  enabled: raw.enabled !== false,
130
130
  defaultDestination: typeof raw.defaultDestination === 'string' ? raw.defaultDestination : 'docs',
@@ -262,7 +262,7 @@ const extension = {
262
262
  return;
263
263
  }
264
264
  console.log('\n🔍 Repository Root Cleanup Scan\n');
265
- console.log(` Config: versioning.config.json → cleanup`);
265
+ console.log(` Config: versioning.config.json → extensionConfig['cleanup-repo']`);
266
266
  console.log(` Default destination: ${cfg.defaultDestination}/`);
267
267
  console.log(` Extensions monitored: ${cfg.extensions.join(', ')}`);
268
268
  console.log(` Allowlist (custom): ${cfg.allowlist.length > 0 ? cfg.allowlist.join(', ') : '—'}`);
@@ -390,23 +390,27 @@ const extension = {
390
390
  if (await fs.pathExists(configPath)) {
391
391
  rawCfg = await fs.readJson(configPath);
392
392
  }
393
- // Ensure cleanup section exists
394
- if (!rawCfg.cleanup)
395
- rawCfg.cleanup = {};
396
- if (!Array.isArray(rawCfg.cleanup.allowlist))
397
- rawCfg.cleanup.allowlist = [];
398
- if (!Array.isArray(rawCfg.cleanup.denylist))
399
- rawCfg.cleanup.denylist = [];
400
- if (!rawCfg.cleanup.routes)
401
- rawCfg.cleanup.routes = { ...DEFAULT_ROUTES };
402
- if (!rawCfg.cleanup.extensions)
403
- rawCfg.cleanup.extensions = [...DEFAULT_EXTENSIONS];
393
+ // Ensure extensionConfig section exists
394
+ if (!rawCfg.extensionConfig)
395
+ rawCfg.extensionConfig = {};
396
+ if (!rawCfg.extensionConfig['cleanup-repo']) {
397
+ rawCfg.extensionConfig['cleanup-repo'] = rawCfg.cleanup || {};
398
+ }
399
+ const extensionCfg = rawCfg.extensionConfig['cleanup-repo'];
400
+ if (!Array.isArray(extensionCfg.allowlist))
401
+ extensionCfg.allowlist = [];
402
+ if (!Array.isArray(extensionCfg.denylist))
403
+ extensionCfg.denylist = [];
404
+ if (!extensionCfg.routes)
405
+ extensionCfg.routes = { ...DEFAULT_ROUTES };
406
+ if (!extensionCfg.extensions)
407
+ extensionCfg.extensions = [...DEFAULT_EXTENSIONS];
404
408
  let modified = false;
405
409
  // ── --allow
406
410
  if (options.allow) {
407
411
  const file = String(options.allow).trim();
408
- if (!rawCfg.cleanup.allowlist.includes(file)) {
409
- rawCfg.cleanup.allowlist.push(file);
412
+ if (!extensionCfg.allowlist.includes(file)) {
413
+ extensionCfg.allowlist.push(file);
410
414
  modified = true;
411
415
  console.log(`✅ Added "${file}" to cleanup.allowlist`);
412
416
  }
@@ -417,8 +421,8 @@ const extension = {
417
421
  // ── --deny
418
422
  if (options.deny) {
419
423
  const file = String(options.deny).trim();
420
- if (!rawCfg.cleanup.denylist.includes(file)) {
421
- rawCfg.cleanup.denylist.push(file);
424
+ if (!extensionCfg.denylist.includes(file)) {
425
+ extensionCfg.denylist.push(file);
422
426
  modified = true;
423
427
  console.log(`✅ Added "${file}" to cleanup.denylist`);
424
428
  }
@@ -429,9 +433,9 @@ const extension = {
429
433
  // ── --unallow
430
434
  if (options.unallow) {
431
435
  const file = String(options.unallow).trim();
432
- const idx = rawCfg.cleanup.allowlist.indexOf(file);
436
+ const idx = extensionCfg.allowlist.indexOf(file);
433
437
  if (idx !== -1) {
434
- rawCfg.cleanup.allowlist.splice(idx, 1);
438
+ extensionCfg.allowlist.splice(idx, 1);
435
439
  modified = true;
436
440
  console.log(`✅ Removed "${file}" from cleanup.allowlist`);
437
441
  }
@@ -442,9 +446,9 @@ const extension = {
442
446
  // ── --undeny
443
447
  if (options.undeny) {
444
448
  const file = String(options.undeny).trim();
445
- const idx = rawCfg.cleanup.denylist.indexOf(file);
449
+ const idx = extensionCfg.denylist.indexOf(file);
446
450
  if (idx !== -1) {
447
- rawCfg.cleanup.denylist.splice(idx, 1);
451
+ extensionCfg.denylist.splice(idx, 1);
448
452
  modified = true;
449
453
  console.log(`✅ Removed "${file}" from cleanup.denylist`);
450
454
  }
@@ -464,15 +468,15 @@ const extension = {
464
468
  const dest = mapping.slice(eqIdx + 1).trim();
465
469
  if (!ext.startsWith('.'))
466
470
  ext = `.${ext}`;
467
- rawCfg.cleanup.routes[ext] = dest;
471
+ extensionCfg.routes[ext] = dest;
468
472
  modified = true;
469
473
  console.log(`✅ Added route: ${ext} → ${dest}/`);
470
474
  }
471
475
  // ── --set-dest
472
476
  if (options.setDest) {
473
- rawCfg.cleanup.defaultDestination = String(options.setDest).trim();
477
+ extensionCfg.defaultDestination = String(options.setDest).trim();
474
478
  modified = true;
475
- console.log(`✅ Default destination set to "${rawCfg.cleanup.defaultDestination}"`);
479
+ console.log(`✅ Default destination set to "${extensionCfg.defaultDestination}"`);
476
480
  }
477
481
  // Write config if modified
478
482
  if (modified) {
@@ -626,16 +630,20 @@ async function updateHuskyConfig(configPath, enabled, hook, mode) {
626
630
  if (await fs.pathExists(fullPath)) {
627
631
  rawCfg = await fs.readJson(fullPath);
628
632
  }
629
- if (!rawCfg.cleanup)
630
- rawCfg.cleanup = {};
631
- if (!rawCfg.cleanup.husky)
632
- rawCfg.cleanup.husky = {};
633
- rawCfg.cleanup.husky.enabled = enabled;
633
+ if (!rawCfg.extensionConfig)
634
+ rawCfg.extensionConfig = {};
635
+ if (!rawCfg.extensionConfig['cleanup-repo']) {
636
+ rawCfg.extensionConfig['cleanup-repo'] = rawCfg.cleanup || {};
637
+ }
638
+ const extensionCfg = rawCfg.extensionConfig['cleanup-repo'];
639
+ if (!extensionCfg.husky)
640
+ extensionCfg.husky = {};
641
+ extensionCfg.husky.enabled = enabled;
634
642
  if (hook)
635
- rawCfg.cleanup.husky.hook = hook;
643
+ extensionCfg.husky.hook = hook;
636
644
  if (mode)
637
- rawCfg.cleanup.husky.mode = mode;
645
+ extensionCfg.husky.mode = mode;
638
646
  await fs.writeJson(fullPath, rawCfg, { spaces: 2 });
639
647
  }
640
648
  exports.default = extension;
641
- //# sourceMappingURL=cleanup-repo-extension.js.map
649
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1,4 @@
1
+ import { VersioningExtension } from '../../extensions';
2
+ declare const extension: VersioningExtension;
3
+ export default extension;
4
+ //# sourceMappingURL=index.d.ts.map
@@ -65,4 +65,4 @@ const extension = {
65
65
  }
66
66
  };
67
67
  exports.default = extension;
68
- //# sourceMappingURL=lifecycle-hooks.js.map
68
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1,4 @@
1
+ import { VersioningExtension } from '../../extensions';
2
+ declare const extension: VersioningExtension;
3
+ export default extension;
4
+ //# sourceMappingURL=index.d.ts.map
@@ -178,4 +178,4 @@ async function publishToLocalRegistry(options) {
178
178
  console.log(`✅ Published to local registry: ${registry}`);
179
179
  }
180
180
  exports.default = extension;
181
- //# sourceMappingURL=npm-publish.js.map
181
+ //# sourceMappingURL=index.js.map
@@ -84,7 +84,9 @@ function defaultFilesConfigForProject(project) {
84
84
  class ConfigManager {
85
85
  static loadConfig(rootConfig, project) {
86
86
  const canonicalProject = canonicalProjectKey(project);
87
- const raw = (rootConfig && typeof rootConfig === 'object' ? rootConfig.reentryStatus : undefined);
87
+ // Try new extensionConfig location first, then fallback to root-level property
88
+ const extensionConfig = rootConfig?.extensionConfig?.['reentry-status'];
89
+ const raw = (extensionConfig ?? (rootConfig && typeof rootConfig === 'object' ? rootConfig.reentryStatus : undefined));
88
90
  const basePartial = { ...(raw ?? {}) };
89
91
  delete basePartial.projects;
90
92
  const projectPartial = canonicalProject && raw && typeof raw === 'object' && raw.projects && typeof raw.projects === 'object'
@@ -1,4 +1,4 @@
1
- export declare const REENTRY_EXTENSION_NAME = "reentry-status-extension";
1
+ export declare const REENTRY_EXTENSION_NAME = "reentry-status";
2
2
  export declare const REENTRY_STATUS_DIRNAME = ".versioning";
3
3
  export declare const REENTRY_STATUS_JSON_FILENAME = "reentry.status.json";
4
4
  export declare const REENTRY_STATUS_MD_FILENAME = "REENTRY.md";
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.ROADMAP_MD_FILENAME = exports.REENTRY_STATUS_MD_FILENAME = exports.REENTRY_STATUS_JSON_FILENAME = exports.REENTRY_STATUS_DIRNAME = exports.REENTRY_EXTENSION_NAME = void 0;
4
- exports.REENTRY_EXTENSION_NAME = 'reentry-status-extension';
4
+ exports.REENTRY_EXTENSION_NAME = 'reentry-status';
5
5
  exports.REENTRY_STATUS_DIRNAME = '.versioning';
6
6
  exports.REENTRY_STATUS_JSON_FILENAME = 'reentry.status.json';
7
7
  exports.REENTRY_STATUS_MD_FILENAME = 'REENTRY.md';
@@ -0,0 +1,4 @@
1
+ import { VersioningExtension } from '../../extensions';
2
+ declare const extension: VersioningExtension;
3
+ export default extension;
4
+ //# sourceMappingURL=extension.d.ts.map
@@ -36,19 +36,19 @@ Object.defineProperty(exports, "__esModule", { value: true });
36
36
  const commander_1 = require("commander");
37
37
  const fs = __importStar(require("fs-extra"));
38
38
  const path = __importStar(require("path"));
39
- const config_manager_1 = require("./reentry-status/config-manager");
40
- const constants_1 = require("./reentry-status/constants");
41
- const file_manager_1 = require("./reentry-status/file-manager");
42
- const dirty_detection_1 = require("./reentry-status/dirty-detection");
43
- const github_rest_client_1 = require("./reentry-status/github-rest-client");
44
- const github_sync_adapter_1 = require("./reentry-status/github-sync-adapter");
45
- const obsidian_cli_client_1 = require("./reentry-status/obsidian-cli-client");
46
- const obsidian_sync_adapter_1 = require("./reentry-status/obsidian-sync-adapter");
47
- const roadmap_parser_1 = require("./reentry-status/roadmap-parser");
48
- const roadmap_renderer_1 = require("./reentry-status/roadmap-renderer");
49
- const status_renderer_1 = require("./reentry-status/status-renderer");
50
- const reentry_status_manager_1 = require("./reentry-status/reentry-status-manager");
51
- const git_context_1 = require("./reentry-status/git-context");
39
+ const config_manager_1 = require("./config-manager");
40
+ const constants_1 = require("./constants");
41
+ const file_manager_1 = require("./file-manager");
42
+ const dirty_detection_1 = require("./dirty-detection");
43
+ const github_rest_client_1 = require("./github-rest-client");
44
+ const github_sync_adapter_1 = require("./github-sync-adapter");
45
+ const obsidian_cli_client_1 = require("./obsidian-cli-client");
46
+ const obsidian_sync_adapter_1 = require("./obsidian-sync-adapter");
47
+ const roadmap_parser_1 = require("./roadmap-parser");
48
+ const roadmap_renderer_1 = require("./roadmap-renderer");
49
+ const status_renderer_1 = require("./status-renderer");
50
+ const reentry_status_manager_1 = require("./reentry-status-manager");
51
+ const git_context_1 = require("./git-context");
52
52
  const extension = {
53
53
  name: constants_1.REENTRY_EXTENSION_NAME,
54
54
  description: 'Maintains canonical re-entry status and synchronizes to files, GitHub Issues, and Obsidian notes',
@@ -672,4 +672,4 @@ const extension = {
672
672
  }
673
673
  };
674
674
  exports.default = extension;
675
- //# sourceMappingURL=reentry-status-extension.js.map
675
+ //# sourceMappingURL=extension.js.map
@@ -12,4 +12,6 @@ export * from './roadmap-renderer';
12
12
  export * from './git-context';
13
13
  export * from './reentry-status-manager';
14
14
  export * from './status-renderer';
15
+ import extension from './extension';
16
+ export default extension;
15
17
  //# sourceMappingURL=index.d.ts.map
@@ -13,6 +13,9 @@ var __createBinding = (this && this.__createBinding) || (Object.create ? (functi
13
13
  var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
14
  for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
15
  };
16
+ var __importDefault = (this && this.__importDefault) || function (mod) {
17
+ return (mod && mod.__esModule) ? mod : { "default": mod };
18
+ };
16
19
  Object.defineProperty(exports, "__esModule", { value: true });
17
20
  __exportStar(require("./constants"), exports);
18
21
  __exportStar(require("./config-manager"), exports);
@@ -28,4 +31,6 @@ __exportStar(require("./roadmap-renderer"), exports);
28
31
  __exportStar(require("./git-context"), exports);
29
32
  __exportStar(require("./reentry-status-manager"), exports);
30
33
  __exportStar(require("./status-renderer"), exports);
34
+ const extension_1 = __importDefault(require("./extension"));
35
+ exports.default = extension_1.default;
31
36
  //# sourceMappingURL=index.js.map
@@ -0,0 +1,4 @@
1
+ import { VersioningExtension } from '../../extensions';
2
+ declare const extension: VersioningExtension;
3
+ export default extension;
4
+ //# sourceMappingURL=index.d.ts.map
@@ -51,4 +51,4 @@ const extension = {
51
51
  }
52
52
  };
53
53
  exports.default = extension;
54
- //# sourceMappingURL=sample-extension.js.map
54
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1,16 @@
1
+ import { VersioningExtension } from '../../extensions';
2
+ export interface SecretCheckResult {
3
+ file: string;
4
+ line: number;
5
+ content: string;
6
+ pattern: string;
7
+ }
8
+ export interface SecretsConfig {
9
+ enabled?: boolean;
10
+ patterns?: string[];
11
+ allowlist?: string[];
12
+ }
13
+ export declare function checkContentForSecrets(content: string, patterns: RegExp[], allowlist: string[], filename: string): SecretCheckResult[];
14
+ declare const extension: VersioningExtension;
15
+ export default extension;
16
+ //# sourceMappingURL=index.d.ts.map