@bensandee/tooling 0.40.7 → 0.41.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 (2) hide show
  1. package/dist/bin.mjs +450 -92
  2. package/package.json +6 -6
package/dist/bin.mjs CHANGED
@@ -305,7 +305,7 @@ function getMonorepoPackages(targetDir) {
305
305
  }
306
306
  //#endregion
307
307
  //#region src/prompts/init-prompts.ts
308
- function isCancelled(value) {
308
+ function isCancelled$1(value) {
309
309
  return p.isCancel(value);
310
310
  }
311
311
  function detectProjectInfo(targetDir) {
@@ -342,7 +342,7 @@ async function runInitPrompts(targetDir, saved) {
342
342
  hint: "fast, Rust-based"
343
343
  }]
344
344
  });
345
- if (isCancelled(formatterAnswer)) {
345
+ if (isCancelled$1(formatterAnswer)) {
346
346
  p.cancel("Cancelled.");
347
347
  process.exit(0);
348
348
  }
@@ -368,7 +368,7 @@ async function runInitPrompts(targetDir, saved) {
368
368
  }
369
369
  ]
370
370
  });
371
- if (isCancelled(ciAnswer)) {
371
+ if (isCancelled$1(ciAnswer)) {
372
372
  p.cancel("Cancelled.");
373
373
  process.exit(0);
374
374
  }
@@ -401,7 +401,7 @@ async function runInitPrompts(targetDir, saved) {
401
401
  }
402
402
  ]
403
403
  });
404
- if (isCancelled(releaseAnswer)) {
404
+ if (isCancelled$1(releaseAnswer)) {
405
405
  p.cancel("Cancelled.");
406
406
  process.exit(0);
407
407
  }
@@ -414,7 +414,7 @@ async function runInitPrompts(targetDir, saved) {
414
414
  message: "Publish packages to npm?",
415
415
  initialValue: false
416
416
  });
417
- if (isCancelled(answer)) {
417
+ if (isCancelled$1(answer)) {
418
418
  p.cancel("Cancelled.");
419
419
  process.exit(0);
420
420
  }
@@ -428,7 +428,7 @@ async function runInitPrompts(targetDir, saved) {
428
428
  message: "Publish Docker images to a registry?",
429
429
  initialValue: false
430
430
  });
431
- if (isCancelled(answer)) {
431
+ if (isCancelled$1(answer)) {
432
432
  p.cancel("Cancelled.");
433
433
  process.exit(0);
434
434
  }
@@ -1324,14 +1324,14 @@ const PER_PACKAGE_DEV_DEPS = {
1324
1324
  "@release-it/bumper": "7.0.5",
1325
1325
  "@types/node": "24.12.0",
1326
1326
  "commit-and-tag-version": "12.7.1",
1327
- "knip": "6.0.3",
1327
+ "knip": "6.0.6",
1328
1328
  "lefthook": "2.1.4",
1329
- "oxfmt": "0.41.0",
1330
- "oxlint": "1.56.0",
1329
+ "oxfmt": "0.42.0",
1330
+ "oxlint": "1.57.0",
1331
1331
  "prettier": "3.8.1",
1332
1332
  "release-it": "19.2.4",
1333
- "tsdown": "0.21.4",
1334
- "typescript": "5.9.3",
1333
+ "tsdown": "0.21.6",
1334
+ "typescript": "6.0.2",
1335
1335
  "vitest": "^4.1.1",
1336
1336
  "pnpm": "10.33.0"
1337
1337
  }["@types/node"],
@@ -1340,14 +1340,14 @@ const PER_PACKAGE_DEV_DEPS = {
1340
1340
  "@release-it/bumper": "7.0.5",
1341
1341
  "@types/node": "24.12.0",
1342
1342
  "commit-and-tag-version": "12.7.1",
1343
- "knip": "6.0.3",
1343
+ "knip": "6.0.6",
1344
1344
  "lefthook": "2.1.4",
1345
- "oxfmt": "0.41.0",
1346
- "oxlint": "1.56.0",
1345
+ "oxfmt": "0.42.0",
1346
+ "oxlint": "1.57.0",
1347
1347
  "prettier": "3.8.1",
1348
1348
  "release-it": "19.2.4",
1349
- "tsdown": "0.21.4",
1350
- "typescript": "5.9.3",
1349
+ "tsdown": "0.21.6",
1350
+ "typescript": "6.0.2",
1351
1351
  "vitest": "^4.1.1",
1352
1352
  "pnpm": "10.33.0"
1353
1353
  }["tsdown"],
@@ -1356,14 +1356,14 @@ const PER_PACKAGE_DEV_DEPS = {
1356
1356
  "@release-it/bumper": "7.0.5",
1357
1357
  "@types/node": "24.12.0",
1358
1358
  "commit-and-tag-version": "12.7.1",
1359
- "knip": "6.0.3",
1359
+ "knip": "6.0.6",
1360
1360
  "lefthook": "2.1.4",
1361
- "oxfmt": "0.41.0",
1362
- "oxlint": "1.56.0",
1361
+ "oxfmt": "0.42.0",
1362
+ "oxlint": "1.57.0",
1363
1363
  "prettier": "3.8.1",
1364
1364
  "release-it": "19.2.4",
1365
- "tsdown": "0.21.4",
1366
- "typescript": "5.9.3",
1365
+ "tsdown": "0.21.6",
1366
+ "typescript": "6.0.2",
1367
1367
  "vitest": "^4.1.1",
1368
1368
  "pnpm": "10.33.0"
1369
1369
  }["typescript"],
@@ -1372,14 +1372,14 @@ const PER_PACKAGE_DEV_DEPS = {
1372
1372
  "@release-it/bumper": "7.0.5",
1373
1373
  "@types/node": "24.12.0",
1374
1374
  "commit-and-tag-version": "12.7.1",
1375
- "knip": "6.0.3",
1375
+ "knip": "6.0.6",
1376
1376
  "lefthook": "2.1.4",
1377
- "oxfmt": "0.41.0",
1378
- "oxlint": "1.56.0",
1377
+ "oxfmt": "0.42.0",
1378
+ "oxlint": "1.57.0",
1379
1379
  "prettier": "3.8.1",
1380
1380
  "release-it": "19.2.4",
1381
- "tsdown": "0.21.4",
1382
- "typescript": "5.9.3",
1381
+ "tsdown": "0.21.6",
1382
+ "typescript": "6.0.2",
1383
1383
  "vitest": "^4.1.1",
1384
1384
  "pnpm": "10.33.0"
1385
1385
  }["vitest"]
@@ -1391,14 +1391,14 @@ const ROOT_DEV_DEPS = {
1391
1391
  "@release-it/bumper": "7.0.5",
1392
1392
  "@types/node": "24.12.0",
1393
1393
  "commit-and-tag-version": "12.7.1",
1394
- "knip": "6.0.3",
1394
+ "knip": "6.0.6",
1395
1395
  "lefthook": "2.1.4",
1396
- "oxfmt": "0.41.0",
1397
- "oxlint": "1.56.0",
1396
+ "oxfmt": "0.42.0",
1397
+ "oxlint": "1.57.0",
1398
1398
  "prettier": "3.8.1",
1399
1399
  "release-it": "19.2.4",
1400
- "tsdown": "0.21.4",
1401
- "typescript": "5.9.3",
1400
+ "tsdown": "0.21.6",
1401
+ "typescript": "6.0.2",
1402
1402
  "vitest": "^4.1.1",
1403
1403
  "pnpm": "10.33.0"
1404
1404
  }["knip"],
@@ -1407,14 +1407,14 @@ const ROOT_DEV_DEPS = {
1407
1407
  "@release-it/bumper": "7.0.5",
1408
1408
  "@types/node": "24.12.0",
1409
1409
  "commit-and-tag-version": "12.7.1",
1410
- "knip": "6.0.3",
1410
+ "knip": "6.0.6",
1411
1411
  "lefthook": "2.1.4",
1412
- "oxfmt": "0.41.0",
1413
- "oxlint": "1.56.0",
1412
+ "oxfmt": "0.42.0",
1413
+ "oxlint": "1.57.0",
1414
1414
  "prettier": "3.8.1",
1415
1415
  "release-it": "19.2.4",
1416
- "tsdown": "0.21.4",
1417
- "typescript": "5.9.3",
1416
+ "tsdown": "0.21.6",
1417
+ "typescript": "6.0.2",
1418
1418
  "vitest": "^4.1.1",
1419
1419
  "pnpm": "10.33.0"
1420
1420
  }["lefthook"],
@@ -1423,14 +1423,14 @@ const ROOT_DEV_DEPS = {
1423
1423
  "@release-it/bumper": "7.0.5",
1424
1424
  "@types/node": "24.12.0",
1425
1425
  "commit-and-tag-version": "12.7.1",
1426
- "knip": "6.0.3",
1426
+ "knip": "6.0.6",
1427
1427
  "lefthook": "2.1.4",
1428
- "oxfmt": "0.41.0",
1429
- "oxlint": "1.56.0",
1428
+ "oxfmt": "0.42.0",
1429
+ "oxlint": "1.57.0",
1430
1430
  "prettier": "3.8.1",
1431
1431
  "release-it": "19.2.4",
1432
- "tsdown": "0.21.4",
1433
- "typescript": "5.9.3",
1432
+ "tsdown": "0.21.6",
1433
+ "typescript": "6.0.2",
1434
1434
  "vitest": "^4.1.1",
1435
1435
  "pnpm": "10.33.0"
1436
1436
  }["oxlint"]
@@ -1464,14 +1464,14 @@ function addReleaseDeps(deps, config) {
1464
1464
  "@release-it/bumper": "7.0.5",
1465
1465
  "@types/node": "24.12.0",
1466
1466
  "commit-and-tag-version": "12.7.1",
1467
- "knip": "6.0.3",
1467
+ "knip": "6.0.6",
1468
1468
  "lefthook": "2.1.4",
1469
- "oxfmt": "0.41.0",
1470
- "oxlint": "1.56.0",
1469
+ "oxfmt": "0.42.0",
1470
+ "oxlint": "1.57.0",
1471
1471
  "prettier": "3.8.1",
1472
1472
  "release-it": "19.2.4",
1473
- "tsdown": "0.21.4",
1474
- "typescript": "5.9.3",
1473
+ "tsdown": "0.21.6",
1474
+ "typescript": "6.0.2",
1475
1475
  "vitest": "^4.1.1",
1476
1476
  "pnpm": "10.33.0"
1477
1477
  }["release-it"];
@@ -1480,14 +1480,14 @@ function addReleaseDeps(deps, config) {
1480
1480
  "@release-it/bumper": "7.0.5",
1481
1481
  "@types/node": "24.12.0",
1482
1482
  "commit-and-tag-version": "12.7.1",
1483
- "knip": "6.0.3",
1483
+ "knip": "6.0.6",
1484
1484
  "lefthook": "2.1.4",
1485
- "oxfmt": "0.41.0",
1486
- "oxlint": "1.56.0",
1485
+ "oxfmt": "0.42.0",
1486
+ "oxlint": "1.57.0",
1487
1487
  "prettier": "3.8.1",
1488
1488
  "release-it": "19.2.4",
1489
- "tsdown": "0.21.4",
1490
- "typescript": "5.9.3",
1489
+ "tsdown": "0.21.6",
1490
+ "typescript": "6.0.2",
1491
1491
  "vitest": "^4.1.1",
1492
1492
  "pnpm": "10.33.0"
1493
1493
  }["@release-it/bumper"];
@@ -1498,14 +1498,14 @@ function addReleaseDeps(deps, config) {
1498
1498
  "@release-it/bumper": "7.0.5",
1499
1499
  "@types/node": "24.12.0",
1500
1500
  "commit-and-tag-version": "12.7.1",
1501
- "knip": "6.0.3",
1501
+ "knip": "6.0.6",
1502
1502
  "lefthook": "2.1.4",
1503
- "oxfmt": "0.41.0",
1504
- "oxlint": "1.56.0",
1503
+ "oxfmt": "0.42.0",
1504
+ "oxlint": "1.57.0",
1505
1505
  "prettier": "3.8.1",
1506
1506
  "release-it": "19.2.4",
1507
- "tsdown": "0.21.4",
1508
- "typescript": "5.9.3",
1507
+ "tsdown": "0.21.6",
1508
+ "typescript": "6.0.2",
1509
1509
  "vitest": "^4.1.1",
1510
1510
  "pnpm": "10.33.0"
1511
1511
  }["commit-and-tag-version"];
@@ -1516,14 +1516,14 @@ function addReleaseDeps(deps, config) {
1516
1516
  "@release-it/bumper": "7.0.5",
1517
1517
  "@types/node": "24.12.0",
1518
1518
  "commit-and-tag-version": "12.7.1",
1519
- "knip": "6.0.3",
1519
+ "knip": "6.0.6",
1520
1520
  "lefthook": "2.1.4",
1521
- "oxfmt": "0.41.0",
1522
- "oxlint": "1.56.0",
1521
+ "oxfmt": "0.42.0",
1522
+ "oxlint": "1.57.0",
1523
1523
  "prettier": "3.8.1",
1524
1524
  "release-it": "19.2.4",
1525
- "tsdown": "0.21.4",
1526
- "typescript": "5.9.3",
1525
+ "tsdown": "0.21.6",
1526
+ "typescript": "6.0.2",
1527
1527
  "vitest": "^4.1.1",
1528
1528
  "pnpm": "10.33.0"
1529
1529
  }["@changesets/cli"];
@@ -1548,22 +1548,22 @@ async function generatePackageJson(ctx) {
1548
1548
  }
1549
1549
  const devDeps = { ...ROOT_DEV_DEPS };
1550
1550
  if (!isMonorepo) Object.assign(devDeps, PER_PACKAGE_DEV_DEPS);
1551
- devDeps["@bensandee/config"] = isWorkspacePackage(ctx, "@bensandee/config") ? "workspace:*" : "0.10.0";
1552
- devDeps["@bensandee/tooling"] = isWorkspacePackage(ctx, "@bensandee/tooling") ? "workspace:*" : "0.40.7";
1551
+ devDeps["@bensandee/config"] = isWorkspacePackage(ctx, "@bensandee/config") ? "workspace:*" : "0.10.1";
1552
+ devDeps["@bensandee/tooling"] = isWorkspacePackage(ctx, "@bensandee/tooling") ? "workspace:*" : "0.41.1";
1553
1553
  if (ctx.config.useEslintPlugin) devDeps["@bensandee/eslint-plugin"] = isWorkspacePackage(ctx, "@bensandee/eslint-plugin") ? "workspace:*" : "0.12.0";
1554
1554
  if (ctx.config.formatter === "oxfmt") devDeps["oxfmt"] = {
1555
1555
  "@changesets/cli": "2.30.0",
1556
1556
  "@release-it/bumper": "7.0.5",
1557
1557
  "@types/node": "24.12.0",
1558
1558
  "commit-and-tag-version": "12.7.1",
1559
- "knip": "6.0.3",
1559
+ "knip": "6.0.6",
1560
1560
  "lefthook": "2.1.4",
1561
- "oxfmt": "0.41.0",
1562
- "oxlint": "1.56.0",
1561
+ "oxfmt": "0.42.0",
1562
+ "oxlint": "1.57.0",
1563
1563
  "prettier": "3.8.1",
1564
1564
  "release-it": "19.2.4",
1565
- "tsdown": "0.21.4",
1566
- "typescript": "5.9.3",
1565
+ "tsdown": "0.21.6",
1566
+ "typescript": "6.0.2",
1567
1567
  "vitest": "^4.1.1",
1568
1568
  "pnpm": "10.33.0"
1569
1569
  }["oxfmt"];
@@ -1572,14 +1572,14 @@ async function generatePackageJson(ctx) {
1572
1572
  "@release-it/bumper": "7.0.5",
1573
1573
  "@types/node": "24.12.0",
1574
1574
  "commit-and-tag-version": "12.7.1",
1575
- "knip": "6.0.3",
1575
+ "knip": "6.0.6",
1576
1576
  "lefthook": "2.1.4",
1577
- "oxfmt": "0.41.0",
1578
- "oxlint": "1.56.0",
1577
+ "oxfmt": "0.42.0",
1578
+ "oxlint": "1.57.0",
1579
1579
  "prettier": "3.8.1",
1580
1580
  "release-it": "19.2.4",
1581
- "tsdown": "0.21.4",
1582
- "typescript": "5.9.3",
1581
+ "tsdown": "0.21.6",
1582
+ "typescript": "6.0.2",
1583
1583
  "vitest": "^4.1.1",
1584
1584
  "pnpm": "10.33.0"
1585
1585
  }["prettier"];
@@ -1656,14 +1656,14 @@ async function generatePackageJson(ctx) {
1656
1656
  "@release-it/bumper": "7.0.5",
1657
1657
  "@types/node": "24.12.0",
1658
1658
  "commit-and-tag-version": "12.7.1",
1659
- "knip": "6.0.3",
1659
+ "knip": "6.0.6",
1660
1660
  "lefthook": "2.1.4",
1661
- "oxfmt": "0.41.0",
1662
- "oxlint": "1.56.0",
1661
+ "oxfmt": "0.42.0",
1662
+ "oxlint": "1.57.0",
1663
1663
  "prettier": "3.8.1",
1664
1664
  "release-it": "19.2.4",
1665
- "tsdown": "0.21.4",
1666
- "typescript": "5.9.3",
1665
+ "tsdown": "0.21.6",
1666
+ "typescript": "6.0.2",
1667
1667
  "vitest": "^4.1.1",
1668
1668
  "pnpm": "10.33.0"
1669
1669
  }["pnpm"]}`
@@ -2457,21 +2457,24 @@ async function generatePnpmWorkspace(ctx) {
2457
2457
  //#endregion
2458
2458
  //#region src/generators/claude-hooks.ts
2459
2459
  const HOOK_PATH = ".claude/hooks/bst-hook.mjs";
2460
- async function generateClaudeHooks(ctx) {
2461
- const content = "/**\n * bst-hook — Claude Code PreToolUse hook\n * @bensandee/claude-hooks v0.4.1\n * https://github.com/bensandee/tooling\n *\n * Auto-generated by @bensandee/tooling repo:sync — do not edit manually.\n */\nimport*as e from\"node:fs\";import{existsSync as t,readFileSync as n,readdirSync as r,statSync as i}from\"node:fs\";import*as a from\"node:path\";import{dirname as o,join as s,resolve as c}from\"node:path\";import{fileURLToPath as l}from\"node:url\";Object.freeze({status:`aborted`});function u(e,t,n){function r(n,r){if(n._zod||Object.defineProperty(n,`_zod`,{value:{def:r,constr:o,traits:new Set},enumerable:!1}),n._zod.traits.has(e))return;n._zod.traits.add(e),t(n,r);let i=o.prototype,a=Object.keys(i);for(let e=0;e<a.length;e++){let t=a[e];t in n||(n[t]=i[t].bind(n))}}let i=n?.Parent??Object;class a extends i{}Object.defineProperty(a,`name`,{value:e});function o(e){var t;let i=n?.Parent?new a:this;r(i,e),(t=i._zod).deferred??(t.deferred=[]);for(let e of i._zod.deferred)e();return i}return Object.defineProperty(o,`init`,{value:r}),Object.defineProperty(o,Symbol.hasInstance,{value:t=>n?.Parent&&t instanceof n.Parent?!0:t?._zod?.traits?.has(e)}),Object.defineProperty(o,`name`,{value:e}),o}var d=class extends Error{constructor(){super(`Encountered Promise during synchronous parse. Use .parseAsync() instead.`)}};const f={};function p(e){return e&&Object.assign(f,e),f}function ee(e,t){return typeof t==`bigint`?t.toString():t}function te(e){return{get value(){{let t=e();return Object.defineProperty(this,`value`,{value:t}),t}throw Error(`cached value already set`)}}}function ne(e){let t=e.startsWith(`^`)?1:0,n=e.endsWith(`$`)?e.length-1:e.length;return e.slice(t,n)}const re=Symbol(`evaluating`);function m(e,t,n){let r;Object.defineProperty(e,t,{get(){if(r!==re)return r===void 0&&(r=re,r=n()),r},set(n){Object.defineProperty(e,t,{value:n})},configurable:!0})}const h=`captureStackTrace`in Error?Error.captureStackTrace:(...e)=>{};function g(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function ie(e){if(g(e)===!1)return!1;let t=e.constructor;if(t===void 0||typeof t!=`function`)return!0;let n=t.prototype;return!(g(n)===!1||Object.prototype.hasOwnProperty.call(n,`isPrototypeOf`)===!1)}function ae(e,t,n){let r=new e._zod.constr(t??e._zod.def);return(!t||n?.parent)&&(r._zod.parent=e),r}function _(e){let t=e;if(!t)return{};if(typeof t==`string`)return{error:()=>t};if(t?.message!==void 0){if(t?.error!==void 0)throw Error(\"Cannot specify both `message` and `error` params\");t.error=t.message}return delete t.message,typeof t.error==`string`?{...t,error:()=>t.error}:t}function oe(e){return Object.keys(e).filter(t=>e[t]._zod.optin===`optional`&&e[t]._zod.optout===`optional`)}-Number.MAX_VALUE,Number.MAX_VALUE;function v(e,t=0){if(e.aborted===!0)return!0;for(let n=t;n<e.issues.length;n++)if(e.issues[n]?.continue!==!0)return!0;return!1}function y(e,t){return t.map(t=>{var n;return(n=t).path??(n.path=[]),t.path.unshift(e),t})}function b(e){return typeof e==`string`?e:e?.message}function x(e,t,n){let r={...e,path:e.path??[]};return e.message||(r.message=b(e.inst?._zod.def?.error?.(e))??b(t?.error?.(e))??b(n.customError?.(e))??b(n.localeError?.(e))??`Invalid input`),delete r.inst,delete r.continue,t?.reportInput||delete r.input,r}const se=(e,t)=>{e.name=`$ZodError`,Object.defineProperty(e,`_zod`,{value:e._zod,enumerable:!1}),Object.defineProperty(e,`issues`,{value:t,enumerable:!1}),e.message=JSON.stringify(t,ee,2),Object.defineProperty(e,`toString`,{value:()=>e.message,enumerable:!1})},ce=u(`$ZodError`,se),S=u(`$ZodError`,se,{Parent:Error}),le=(e=>(t,n,r,i)=>{let a=r?Object.assign(r,{async:!1}):{async:!1},o=t._zod.run({value:n,issues:[]},a);if(o instanceof Promise)throw new d;if(o.issues.length){let t=new(i?.Err??e)(o.issues.map(e=>x(e,a,p())));throw h(t,i?.callee),t}return o.value})(S),ue=(e=>async(t,n,r,i)=>{let a=r?Object.assign(r,{async:!0}):{async:!0},o=t._zod.run({value:n,issues:[]},a);if(o instanceof Promise&&(o=await o),o.issues.length){let t=new(i?.Err??e)(o.issues.map(e=>x(e,a,p())));throw h(t,i?.callee),t}return o.value})(S),C=(e=>(t,n,r)=>{let i=r?{...r,async:!1}:{async:!1},a=t._zod.run({value:n,issues:[]},i);if(a instanceof Promise)throw new d;return a.issues.length?{success:!1,error:new(e??ce)(a.issues.map(e=>x(e,i,p())))}:{success:!0,data:a.value}})(S),w=(e=>async(t,n,r)=>{let i=r?Object.assign(r,{async:!0}):{async:!0},a=t._zod.run({value:n,issues:[]},i);return a instanceof Promise&&(a=await a),a.issues.length?{success:!1,error:new e(a.issues.map(e=>x(e,i,p())))}:{success:!0,data:a.value}})(S),de=e=>{let t=e?`[\\\\s\\\\S]{${e?.minimum??0},${e?.maximum??``}}`:`[\\\\s\\\\S]*`;return RegExp(`^${t}$`)},fe=/^-?\\d+(?:\\.\\d+)?$/,pe={major:4,minor:3,patch:6},T=u(`$ZodType`,(e,t)=>{var n;e??={},e._zod.def=t,e._zod.bag=e._zod.bag||{},e._zod.version=pe;let r=[...e._zod.def.checks??[]];e._zod.traits.has(`$ZodCheck`)&&r.unshift(e);for(let t of r)for(let n of t._zod.onattach)n(e);if(r.length===0)(n=e._zod).deferred??(n.deferred=[]),e._zod.deferred?.push(()=>{e._zod.run=e._zod.parse});else{let t=(e,t,n)=>{let r=v(e),i;for(let a of t){if(a._zod.def.when){if(!a._zod.def.when(e))continue}else if(r)continue;let t=e.issues.length,o=a._zod.check(e);if(o instanceof Promise&&n?.async===!1)throw new d;if(i||o instanceof Promise)i=(i??Promise.resolve()).then(async()=>{await o,e.issues.length!==t&&(r||=v(e,t))});else{if(e.issues.length===t)continue;r||=v(e,t)}}return i?i.then(()=>e):e},n=(n,i,a)=>{if(v(n))return n.aborted=!0,n;let o=t(i,r,a);if(o instanceof Promise){if(a.async===!1)throw new d;return o.then(t=>e._zod.parse(t,a))}return e._zod.parse(o,a)};e._zod.run=(i,a)=>{if(a.skipChecks)return e._zod.parse(i,a);if(a.direction===`backward`){let t=e._zod.parse({value:i.value,issues:[]},{...a,skipChecks:!0});return t instanceof Promise?t.then(e=>n(e,i,a)):n(t,i,a)}let o=e._zod.parse(i,a);if(o instanceof Promise){if(a.async===!1)throw new d;return o.then(e=>t(e,r,a))}return t(o,r,a)}}m(e,`~standard`,()=>({validate:t=>{try{let n=C(e,t);return n.success?{value:n.data}:{issues:n.error?.issues}}catch{return w(e,t).then(e=>e.success?{value:e.data}:{issues:e.error?.issues})}},vendor:`zod`,version:1}))}),me=u(`$ZodString`,(e,t)=>{T.init(e,t),e._zod.pattern=[...e?._zod.bag?.patterns??[]].pop()??de(e._zod.bag),e._zod.parse=(n,r)=>{if(t.coerce)try{n.value=String(n.value)}catch{}return typeof n.value==`string`||n.issues.push({expected:`string`,code:`invalid_type`,input:n.value,inst:e}),n}}),he=u(`$ZodUnknown`,(e,t)=>{T.init(e,t),e._zod.parse=e=>e});function E(e,t,n,r,i){if(e.issues.length){if(i&&!(n in r))return;t.issues.push(...y(n,e.issues))}e.value===void 0?n in r&&(t.value[n]=void 0):t.value[n]=e.value}function ge(e){let t=Object.keys(e.shape);for(let n of t)if(!e.shape?.[n]?._zod?.traits?.has(`$ZodType`))throw Error(`Invalid element at key \"${n}\": expected a Zod schema`);let n=oe(e.shape);return{...e,keys:t,keySet:new Set(t),numKeys:t.length,optionalKeys:new Set(n)}}function _e(e,t,n,r,i,a){let o=[],s=i.keySet,c=i.catchall._zod,l=c.def.type,u=c.optout===`optional`;for(let i in t){if(s.has(i))continue;if(l===`never`){o.push(i);continue}let a=c.run({value:t[i],issues:[]},r);a instanceof Promise?e.push(a.then(e=>E(e,n,i,t,u))):E(a,n,i,t,u)}return o.length&&n.issues.push({code:`unrecognized_keys`,keys:o,input:t,inst:a}),e.length?Promise.all(e).then(()=>n):n}const ve=u(`$ZodObject`,(e,t)=>{if(T.init(e,t),!Object.getOwnPropertyDescriptor(t,`shape`)?.get){let e=t.shape;Object.defineProperty(t,`shape`,{get:()=>{let n={...e};return Object.defineProperty(t,`shape`,{value:n}),n}})}let n=te(()=>ge(t));m(e._zod,`propValues`,()=>{let e=t.shape,n={};for(let t in e){let r=e[t]._zod;if(r.values){n[t]??(n[t]=new Set);for(let e of r.values)n[t].add(e)}}return n});let r=g,i=t.catchall,a;e._zod.parse=(t,o)=>{a??=n.value;let s=t.value;if(!r(s))return t.issues.push({expected:`object`,code:`invalid_type`,input:s,inst:e}),t;t.value={};let c=[],l=a.shape;for(let e of a.keys){let n=l[e],r=n._zod.optout===`optional`,i=n._zod.run({value:s[e],issues:[]},o);i instanceof Promise?c.push(i.then(n=>E(n,t,e,s,r))):E(i,t,e,s,r)}return i?_e(c,s,t,o,n.value,e):c.length?Promise.all(c).then(()=>t):t}}),ye=u(`$ZodRecord`,(e,t)=>{T.init(e,t),e._zod.parse=(n,r)=>{let i=n.value;if(!ie(i))return n.issues.push({expected:`record`,code:`invalid_type`,input:i,inst:e}),n;let a=[],o=t.keyType._zod.values;if(o){n.value={};let s=new Set;for(let e of o)if(typeof e==`string`||typeof e==`number`||typeof e==`symbol`){s.add(typeof e==`number`?e.toString():e);let o=t.valueType._zod.run({value:i[e],issues:[]},r);o instanceof Promise?a.push(o.then(t=>{t.issues.length&&n.issues.push(...y(e,t.issues)),n.value[e]=t.value})):(o.issues.length&&n.issues.push(...y(e,o.issues)),n.value[e]=o.value)}let c;for(let e in i)s.has(e)||(c??=[],c.push(e));c&&c.length>0&&n.issues.push({code:`unrecognized_keys`,input:i,inst:e,keys:c})}else{n.value={};for(let o of Reflect.ownKeys(i)){if(o===`__proto__`)continue;let s=t.keyType._zod.run({value:o,issues:[]},r);if(s instanceof Promise)throw Error(`Async schemas not supported in object keys currently`);if(typeof o==`string`&&fe.test(o)&&s.issues.length){let e=t.keyType._zod.run({value:Number(o),issues:[]},r);if(e instanceof Promise)throw Error(`Async schemas not supported in object keys currently`);e.issues.length===0&&(s=e)}if(s.issues.length){t.mode===`loose`?n.value[o]=i[o]:n.issues.push({code:`invalid_key`,origin:`record`,issues:s.issues.map(e=>x(e,r,p())),input:o,path:[o],inst:e});continue}let c=t.valueType._zod.run({value:i[o],issues:[]},r);c instanceof Promise?a.push(c.then(e=>{e.issues.length&&n.issues.push(...y(o,e.issues)),n.value[s.value]=e.value})):(c.issues.length&&n.issues.push(...y(o,c.issues)),n.value[s.value]=c.value)}}return a.length?Promise.all(a).then(()=>n):n}});function D(e,t){return e.issues.length&&t===void 0?{issues:[],value:void 0}:e}const be=u(`$ZodOptional`,(e,t)=>{T.init(e,t),e._zod.optin=`optional`,e._zod.optout=`optional`,m(e._zod,`values`,()=>t.innerType._zod.values?new Set([...t.innerType._zod.values,void 0]):void 0),m(e._zod,`pattern`,()=>{let e=t.innerType._zod.pattern;return e?RegExp(`^(${ne(e.source)})?$`):void 0}),e._zod.parse=(e,n)=>{if(t.innerType._zod.optin===`optional`){let r=t.innerType._zod.run(e,n);return r instanceof Promise?r.then(t=>D(t,e.value)):D(r,e.value)}return e.value===void 0?e:t.innerType._zod.run(e,n)}});var O,xe=class{constructor(){this._map=new WeakMap,this._idmap=new Map}add(e,...t){let n=t[0];return this._map.set(e,n),n&&typeof n==`object`&&`id`in n&&this._idmap.set(n.id,e),this}clear(){return this._map=new WeakMap,this._idmap=new Map,this}remove(e){let t=this._map.get(e);return t&&typeof t==`object`&&`id`in t&&this._idmap.delete(t.id),this._map.delete(e),this}get(e){let t=e._zod.parent;if(t){let n={...this.get(t)??{}};delete n.id;let r={...n,...this._map.get(e)};return Object.keys(r).length?r:void 0}return this._map.get(e)}has(e){return this._map.has(e)}};function Se(){return new xe}(O=globalThis).__zod_globalRegistry??(O.__zod_globalRegistry=Se()),globalThis.__zod_globalRegistry;function Ce(e,t){return new e({type:`string`,..._(t)})}function we(e){return new e({type:`unknown`})}const k=u(`ZodMiniType`,(e,t)=>{if(!e._zod)throw Error(`Uninitialized schema in ZodMiniType.`);T.init(e,t),e.def=t,e.type=t.type,e.parse=(t,n)=>le(e,t,n,{callee:e.parse}),e.safeParse=(t,n)=>C(e,t,n),e.parseAsync=async(t,n)=>ue(e,t,n,{callee:e.parseAsync}),e.safeParseAsync=async(t,n)=>w(e,t,n),e.check=(...n)=>e.clone({...t,checks:[...t.checks??[],...n.map(e=>typeof e==`function`?{_zod:{check:e,def:{check:`custom`},onattach:[]}}:e)]},{parent:!0}),e.with=e.check,e.clone=(t,n)=>ae(e,t,n),e.brand=()=>e,e.register=((t,n)=>(t.add(e,n),e)),e.apply=t=>t(e)}),Te=u(`ZodMiniString`,(e,t)=>{me.init(e,t),k.init(e,t)});function A(e){return Ce(Te,e)}const Ee=u(`ZodMiniUnknown`,(e,t)=>{he.init(e,t),k.init(e,t)});function j(){return we(Ee)}const De=u(`ZodMiniObject`,(e,t)=>{ve.init(e,t),k.init(e,t),m(e,`shape`,()=>t.shape)});function M(e,t){return new De({type:`object`,shape:e??{},..._(t)})}const Oe=u(`ZodMiniRecord`,(e,t)=>{ye.init(e,t),k.init(e,t)});function N(e,t,n){return new Oe({type:`record`,keyType:e,valueType:t,..._(n)})}const ke=u(`ZodMiniOptional`,(e,t)=>{be.init(e,t),k.init(e,t)});function P(e){return new ke({type:`optional`,innerType:e})}const Ae=M({session_id:A(),transcript_path:A(),cwd:A(),permission_mode:A(),hook_event_name:A(),tool_name:A(),tool_input:N(A(),j())});async function je(){let e=[];for await(let t of process.stdin)e.push(typeof t==`string`?t:String(t));let t=JSON.parse(e.join(``)),n=Ae.safeParse(t);return n.success||(process.stderr.write(`[bst-hook] invalid hook input: ${n.error.message}\\n`),process.exit(0)),n.data}const Me=M({command:A(),description:P(A())}),Ne=M({file_path:A()}),Pe=M({pattern:A(),path:P(A())});function Fe(e){let t=Me.safeParse(e);return t.success?t.data:null}function Ie(e){let t=Ne.safeParse(e);return t.success?t.data:null}function Le(e){let t=Pe.safeParse(e);return t.success?t.data:null}function F(e,t){let n={hookSpecificOutput:{hookEventName:`PreToolUse`,permissionDecision:e,...e===`deny`&&t?{permissionDecisionReason:t}:{}}};process.stdout.write(JSON.stringify(n))}function Re(){let e=a.dirname(l(import.meta.url));return a.join(e,`bst-hook.audit.local.jsonl`)}function ze(t){try{if(e.statSync(t).size>1048576){let n=`${t}.1`;e.renameSync(t,n)}}catch{}}let Be=!1;function Ve(t){try{let n=Re();Be||=(ze(n),!0);let r={timestamp:new Date().toISOString(),...t};e.appendFileSync(n,JSON.stringify(r)+`\n`)}catch(e){process.stderr.write(`[bst-hook] audit write failed: ${e instanceof Error?e.message:String(e)}\\n`)}}function I(e){let t=[],n=``,r=0,i=!1;for(;r<e.length;){let a=e[r];if(a===`'`){for(i=!0,r++;r<e.length&&e[r]!==`'`;)n+=e[r],r++;if(r>=e.length)return{ok:!1,error:`unterminated single quote`};r++}else if(a===`\"`){for(i=!0,r++;r<e.length&&e[r]!==`\"`;){if(e[r]===`\\\\`&&r+1<e.length){let t=e[r+1];if(t===`\"`||t===`\\\\`||t===`$`||t===\"`\"){n+=t,r+=2;continue}}n+=e[r],r++}if(r>=e.length)return{ok:!1,error:`unterminated double quote`};r++}else a===`\\\\`&&r+1<e.length?(i=!0,n+=e[r+1],r+=2):a===` `||a===` `?(i&&=(t.push(n),n=``,!1),r++):(i=!0,n+=a,r++)}return i&&t.push(n),{ok:!0,tokens:t}}function He(e){if(!e||!e.trim())return[];let t=[],n=``,r=0,i=!1,a=!1;for(;r<e.length;){let o=e[r];if(o===`'`&&!a){i=!i,n+=o,r++;continue}if(o===`\"`&&!i){a=!a,n+=o,r++;continue}if(o===`\\\\`&&!i&&r+1<e.length){n+=o+e[r+1],r+=2;continue}if(!i&&!a){if(o===`&`&&r+1<e.length&&e[r+1]===`&`){L(t,n,`&&`),n=``,r+=2;continue}if(o===`&`&&!(r+1<e.length&&e[r+1]===`>`)&&!(r>0&&(e[r-1]===`>`||e[r-1]===`<`))){L(t,n,`&`),n=``,r++;continue}if(o===`|`&&r+1<e.length&&e[r+1]===`|`){L(t,n,`||`),n=``,r+=2;continue}if(o===`|`){L(t,n,`|`),n=``,r++;continue}if(o===`;`){L(t,n,`;`),n=``,r++;continue}}n+=o,r++}let o=n.trim();return o&&t.push({command:o,operator:null}),t}function L(e,t,n){let r=t.trim();r&&e.push({command:r,operator:n})}const R=new Set([`2>&1`,`2>/dev/null`,`>/dev/null`,`1>/dev/null`]);function Ue(e,t){if(/[\\n\\r]/.test(t))return{safe:!1,reason:`unquoted newline in command`};for(let t of e){if(t===\"`\")return{safe:!1,reason:`backtick command substitution`};if(t.includes(`$(`))return{safe:!1,reason:`dollar command substitution`};if(t.includes(\"`\"))return{safe:!1,reason:`backtick command substitution`};if(t.includes(`<(`)||t.includes(`>(`)&&!R.has(t))return{safe:!1,reason:`process substitution`}}for(let t=0;t<e.length;t++){let n=e[t];if(!R.has(n)){if(n.includes(`<`)&&!n.includes(`<(`))return{safe:!1,reason:`input redirect`};if(n.includes(`>`)){if(n.endsWith(`>/dev/null`)||n.match(/^(&>>|&>|>>|>|1>|2>)$/)&&e[t+1]===`/dev/null`)continue;return{safe:!1,reason:`output redirect to file`}}}}return{safe:!0}}const We=[`.sample`,`.example`,`.template`],Ge=/(^|[/\\\\])(\\.env(\\..*)?|.*\\.env(\\..*)?|\\.env)$/;function Ke(e){return We.some(t=>e.endsWith(t))}function z(e){return Ke(a.basename(e))?!1:Ge.test(e)}function qe(e){return e.slice(1).some(e=>!e.startsWith(`-`)&&z(e))}const Je=new Set([`status`,`log`,`diff`,`show`,`blame`,`grep`,`shortlog`,`range-diff`,`describe`,`branch`,`remote`,`fetch`,`ls-files`,`ls-tree`,`ls-remote`,`show-ref`,`for-each-ref`,`rev-parse`,`rev-list`,`cat-file`,`diff-tree`,`name-rev`,`merge-base`,`check-ignore`]),Ye=new Set([`push`,`add`,`commit`,`reset`,`merge`,`rebase`,`cherry-pick`,`checkout`,`switch`,`stash`,`tag`,`revert`,`clean`,`rm`,`mv`]),Xe=new Set([`-c`,`--exec-path`,`--pager`,`--upload-pack`,`--receive-pack`]),Ze=new Set([`-C`,`-c`,`--git-dir`,`--work-tree`]);function B(e){let t=e.slice(1);for(let e=0;e<t.length;e++){let n=t[e];if(Ze.has(n)){e++;continue}if(!n.startsWith(`-`))return n}}function Qe(e){for(let t of e.slice(1))if(Xe.has(t)||t===`-o`||t.startsWith(`--output`)||t.startsWith(`--exec-path=`)||t.startsWith(`--pager=`)||t.startsWith(`--upload-pack=`)||t.startsWith(`--receive-pack=`)||t.startsWith(`-o=`)||t.startsWith(`--output=`))return!1;let t=B(e);if(!t)return!1;if(t===`stash`){let t=e[e.indexOf(`stash`)+1];return t===`list`||t===void 0}return Je.has(t)}function $e(e){let t=B(e);if(!t)return!1;if(t===`stash`){let t=e[e.indexOf(`stash`)+1];if(t===`list`||t===void 0)return!1}return Ye.has(t)}const V=new Set(`install.i.add.remove.rm.uninstall.un.update.up.upgrade.list.ls.ll.la.why.view.info.show.outdated.audit.licenses.init.create.link.unlink.pack.publish.config.set.get.store.cache.rebuild.rb.prune.dedupe.dlx.exec.run.patch.patch-commit.recursive.-r`.split(`.`)),et=new Set([`list`,`ls`,`ll`,`la`,`why`,`view`,`info`,`show`,`outdated`]);function tt(e){let t=e.slice(1),n;for(let e of t)if(!(e.startsWith(`-`)&&!V.has(e))){n=e;break}return n?et.has(n)?!0:n===`install`||n===`i`?t.slice(t.indexOf(n)+1).every(e=>e.startsWith(`-`)):!1:!1}const nt=new Set([`view`,`info`,`show`]);function rt(e){let t=e[1];return t!==void 0&&nt.has(t)}function it(e){let t=e[1],n=`This project uses pnpm.`;return t?t===`install`||t===`i`||t===`ci`?e.slice(2).some(e=>!e.startsWith(`-`))?`${n} Use \\`pnpm add <pkg>\\` instead of \\`npm install <pkg>\\`.`:`${n} Use \\`pnpm install\\` instead of npm.`:t===`add`?`${n} Use \\`pnpm add <pkg>\\` instead of npm.`:t===`uninstall`||t===`remove`||t===`rm`||t===`un`||t===`r`?`${n} Use \\`pnpm remove <pkg>\\` instead of npm.`:t===`run`||t===`run-script`?`${n} Use \\`pnpm run <script>\\` or \\`pnpm <script>\\` instead of npm.`:t===`test`||t===`t`||t===`tst`?`${n} Use \\`pnpm test\\` instead of npm.`:t===`start`?`${n} Use \\`pnpm start\\` instead of npm.`:t===`stop`?`${n} Use \\`pnpm stop\\` instead of npm.`:t===`restart`?`${n} Use \\`pnpm restart\\` instead of npm.`:t===`exec`?`${n} Use \\`pnpm exec <cmd>\\` instead of npm.`:t===`list`||t===`ls`||t===`ll`||t===`la`?`${n} Use \\`pnpm list\\` instead of npm.`:t===`why`?`${n} Use \\`pnpm why\\` instead of npm.`:t===`outdated`?`${n} Use \\`pnpm outdated\\` instead of npm.`:t===`audit`?`${n} Use \\`pnpm audit\\` instead of npm.`:t===`update`||t===`up`||t===`upgrade`?`${n} Use \\`pnpm update\\` instead of npm.`:t===`init`?`${n} Use \\`pnpm init\\` instead of npm.`:t===`publish`?`${n} Use \\`pnpm publish\\` instead of npm.`:t===`link`?`${n} Use \\`pnpm link\\` instead of npm.`:t===`unlink`?`${n} Use \\`pnpm unlink\\` instead of npm.`:t===`pack`?`${n} Use \\`pnpm pack\\` instead of npm.`:t===`cache`?`${n} Use \\`pnpm store\\` instead of \\`npm cache\\`.`:t===`config`||t===`set`||t===`get`?`${n} Use \\`pnpm config\\` instead of npm.`:`${n} Use the equivalent pnpm command instead of npm.`:`${n} Use \\`pnpm\\` instead of npm.`}function H(e,t){for(let n of e.slice(1)){if(n.startsWith(`-`)){if(n===`-t`||n.startsWith(`--target-directory`))return!1;continue}if(a.basename(n).startsWith(`.`)||n.startsWith(`~/`)||n===`~`)return!1;let e=a.resolve(t.cwd,n);if(e!==t.cwd&&!e.startsWith(t.cwd+a.sep))return!1}return!0}const at=new Set([`-exec`,`-execdir`,`-ok`,`-okdir`,`-delete`,`-fprint`,`-fprint0`,`-fprintf`,`-fls`]);function ot(e){return!e.some(e=>at.has(e))}function st(e){return!e.includes(`-o`)&&!e.some(e=>e.startsWith(`--output`))}function ct(e){let t=e.findIndex(e=>a.basename(e)===`rm`);if(t===-1)return!1;let n=e.slice(t+1),r=n.filter(e=>e.startsWith(`-`)&&!e.startsWith(`--`)),i=n.filter(e=>e.startsWith(`--`)),o=r.some(e=>/[rR]/.test(e)),s=i.includes(`--recursive`);return o||s}function lt(e){return e.some(e=>e===`777`||e===`0777`)}function ut(e){let t=e.indexOf(`push`);if(t===-1)return!1;let n=e.slice(t+1);return n.some(e=>e===`--force`||e===`-f`&&!n.includes(`--force-with-lease`))}function dt(e){if(!(e.includes(`reset`)&&e.includes(`--hard`)))return!1;if(e.some(e=>e===`main`||e===`master`))return!0;let t=e.filter(e=>e!==`git`&&e!==`reset`&&!e.startsWith(`-`));return t.length===0||t.includes(`HEAD`)}const ft=[{name:`rm-recursive`,match:/^rm$/,action:`deny`,when:e=>ct(e),reason:\"Don't use recursive `rm`. Use more targeted deletes, or remove specific files/directories.\"},{name:`sudo`,match:/^sudo$/,action:`deny`,reason:`Don't use sudo. If you need elevated permissions, ask me to do it manually.`},{name:`git-force-push`,match:/^git$/,action:`deny`,when:e=>ut(e),reason:\"Use `git push --force-with-lease` instead of `--force`.\"},{name:`git-reset-hard`,match:/^git$/,action:`deny`,when:e=>dt(e),reason:\"Don't `reset --hard` on main. Create a branch first.\"},{name:`git-write`,match:/^git$/,action:`deny`,when:e=>$e(e),reason:`Git write operations (push, add, commit, reset, merge, etc.) are not allowed. Ask the user to run these manually.`},{name:`chmod-777`,match:/^chmod$/,action:`deny`,when:e=>lt(e),reason:`Don't use 777 permissions. Use more restrictive permissions.`},{name:`env-file-read`,match:/^(cat|head|tail|less|more|grep)$/,action:`deny`,when:e=>qe(e),reason:`Don't read .env files. These contain secrets that should not appear in the conversation.`},{name:`npx-redirect`,match:/^npx$/,action:`deny`,reason:\"This project uses pnpm. Use `pnpm dlx <pkg>` or `pnpm exec <cmd>` instead of npx.\"}],U=[{name:`vitest`,match:/^vitest$/,action:`allow`},{name:`jest`,match:/^jest$/,action:`allow`},{name:`tsc`,match:/^tsc$/,action:`allow`},{name:`tsdown`,match:/^tsdown$/,action:`allow`},{name:`oxlint`,match:/^oxlint$/,action:`allow`},{name:`oxfmt`,match:/^oxfmt$/,action:`allow`},{name:`eslint`,match:/^eslint$/,action:`allow`},{name:`prettier`,match:/^prettier$/,action:`allow`},{name:`biome`,match:/^biome$/,action:`allow`},{name:`knip`,match:/^knip$/,action:`allow`},{name:`cat`,match:/^cat$/,action:`allow`},{name:`head`,match:/^head$/,action:`allow`},{name:`tail`,match:/^tail$/,action:`allow`},{name:`grep`,match:/^grep$/,action:`allow`},{name:`ls`,match:/^ls$/,action:`allow`},{name:`wc`,match:/^wc$/,action:`allow`},{name:`uniq`,match:/^uniq$/,action:`allow`},{name:`diff`,match:/^diff$/,action:`allow`},{name:`echo`,match:/^echo$/,action:`allow`},{name:`pwd`,match:/^pwd$/,action:`allow`},{name:`which`,match:/^which$/,action:`allow`},{name:`dirname`,match:/^dirname$/,action:`allow`},{name:`basename`,match:/^basename$/,action:`allow`},{name:`realpath`,match:/^realpath$/,action:`allow`},{name:`npm`,match:/^npm$/,action:`allow`,when:e=>rt(e)},{name:`test`,match:/^test$/,action:`allow`},{name:`bracket-test`,match:/^\\[$/,action:`allow`},{name:`cd`,match:/^cd$/,action:`allow`},{name:`true`,match:/^true$/,action:`allow`},{name:`colon`,match:/^:$/,action:`allow`},{name:`find`,match:/^find$/,action:`allow`,when:e=>ot(e)},{name:`sort`,match:/^sort$/,action:`allow`,when:e=>st(e)},{name:`git`,match:/^git$/,action:`allow`,when:e=>Qe(e)},{name:`pnpm`,match:/^pnpm$/,action:`allow`,when:e=>tt(e)},{name:`cp`,match:/^cp$/,action:`allow`,when:(e,t)=>H(e,t)},{name:`mkdir`,match:/^mkdir$/,action:`allow`,when:(e,t)=>H(e,t)},{name:`touch`,match:/^touch$/,action:`allow`,when:(e,t)=>H(e,t)}],pt=M({scripts:N(A(),j())});function W(e,t){let n=xt(t);if(!n)return null;let r=n[e];if(typeof r!=`string`)return null;let i=n[`pre${e}`],a=n[`post${e}`];return{pre:typeof i==`string`?i:null,main:r,post:typeof a==`string`?a:null}}function mt(e,t,n){let r=_t(t,n);if(!r)return null;let i=W(e,r);return i?{...i,pkgDir:r}:null}function ht(e,t){let n=G(t);if(!n)return null;let r=[];for(let t of n){let n=W(e,t);n&&r.push({...n,pkgDir:t})}return r}function gt(e){let n=c(e);for(;;){if(t(s(n,`pnpm-workspace.yaml`)))return n;let e=o(n);if(e===n)return null;n=e}}function G(e){let t=vt(e);if(!t)return null;let n=[];for(let a of t){if(!a.endsWith(`/*`))continue;let t=c(e,a.slice(0,-2)),o;try{o=r(t)}catch{continue}for(let e of o){let r=s(t,e);try{if(!i(r).isDirectory())continue}catch{continue}n.push(r)}}return n.length>0?n:null}function _t(e,t){let n=G(t);if(!n)return null;for(let t of n){let n=bt(t);if(n===e||n===`@${e}`||t.split(`/`).pop()===e||n&&(n.startsWith(`@`)?n.split(`/`)[1]:n)===e)return t}return null}function vt(e){try{let t=n(s(e,`pnpm-workspace.yaml`),`utf-8`).split(`\n`),r=t.findIndex(e=>/^packages\\s*:/.test(e));if(r===-1)return null;let i=[];for(let e=r+1;e<t.length;e++){let n=t[e],r=/^\\s+-\\s+(.+)$/.exec(n);if(!r)break;i.push(r[1].trim().replace(/['\"`]/g,``))}return i.length>0?i:null}catch{return null}}const yt=M({name:A()});function bt(e){try{let t=n(s(e,`package.json`),`utf-8`),r=yt.safeParse(JSON.parse(t));return r.success?r.data.name:null}catch{return null}}function xt(e){try{let t=n(s(e,`package.json`),`utf-8`),r=pt.safeParse(JSON.parse(t));return r.success?r.data.scripts:null}catch{return null}}const St=new Set([`LD_PRELOAD`,`LD_LIBRARY_PATH`,`DYLD_INSERT_LIBRARIES`,`NODE_OPTIONS`,`PYTHONPATH`,`PYTHONSTARTUP`,`PERL5OPT`,`PERL5LIB`,`RUBYOPT`,`RUBYLIB`,`BASH_ENV`,`ENV`,`npm_config_prefix`,`npm_config_registry`,`EDITOR`,`VISUAL`]),Ct=[`GIT_CONFIG_`,`GIT_PAGER`,`GIT_SSH_COMMAND`,`GIT_EDITOR`,`GIT_EXEC_PATH`];function K(e){return St.has(e)?!0:Ct.some(t=>e.startsWith(t))}function wt(e,t){let n=I(e);if(!n.ok||n.tokens.length!==2)return null;let r=n.tokens;if(r[0]!==`cd`)return null;let i=r[1];return a.isAbsolute(i)?i:a.resolve(t.cwd,i)}function q(e,t){if(t.depth>=5)return{action:`passthrough`,rule:null,reason:`max evaluation depth exceeded`};let n=e.trim();if(!n)return{action:`passthrough`,rule:null,reason:null};if(n.startsWith(`(`)&&n.endsWith(`)`))return{action:`passthrough`,rule:null,reason:`subshell`};let r=He(n);if(r.length===0)return{action:`passthrough`,rule:null,reason:null};let i=null,a=null,o=t;for(let e of r){if(e.operator===`&&`){let t=wt(e.command,o);t&&(o={...o,cwd:t})}let t=Tt(e.command,o);if(t.action===`deny`)return t;t.action===`passthrough`&&(i||=t),t.action===`allow`&&(a=t)}return i||(r.length===1&&a?a:{action:`allow`,rule:`all-segments`,reason:null})}function J(e,t){if(e.pre){let n=q(e.pre,t);if(n.action!==`allow`)return n}let n=q(e.main,t);if(n.action!==`allow`)return n;if(e.post){let n=q(e.post,t);if(n.action!==`allow`)return n}return`allow`}function Tt(e,t){let n=e.trim();if(n.startsWith(`(`)&&n.endsWith(`)`))return{action:`passthrough`,rule:null,reason:`subshell`};let r=I(e);if(!r.ok)return{action:`passthrough`,rule:null,reason:r.error};let i=r.tokens;if(i.length===0)return{action:`passthrough`,rule:null,reason:null};let o=0;for(;o<i.length&&/^\\w+=/.test(i[o]);){let e=i[o].split(`=`)[0];if(K(e))return{action:`passthrough`,rule:null,reason:`dangerous env var: ${e}`};o++}if(o>=i.length)return{action:`allow`,rule:`env-only`,reason:null};i=i.slice(o);let s=Ue(i,e);if(!s.safe)return{action:`passthrough`,rule:null,reason:s.reason};for(let e=0;e<i.length;e++){let t=i[e];if(!(t===`2>&1`||t===`2>/dev/null`||t===`>/dev/null`||t===`1>/dev/null`)){if(t===`>`||t===`>>`){if(i[e+1]===`/dev/null`)continue;return{action:`passthrough`,rule:null,reason:`output redirect to file`}}if(t===`<`)return{action:`passthrough`,rule:null,reason:`input redirect`}}}let c=new Set([`2>&1`,`2>/dev/null`,`>/dev/null`,`1>/dev/null`]);i=i.filter((e,t)=>!(c.has(e)||(e===`>`||e===`>>`)&&i[t+1]===`/dev/null`||e===`/dev/null`&&t>0&&(i[t-1]===`>`||i[t-1]===`>>`)));let l=a.basename(i[0]);if(l===`command`&&i.length>1)return q(i.slice(1).join(` `),{...t,depth:t.depth+1});if(l===`env`){let e=1;for(;e<i.length&&/^\\w+=/.test(i[e]);){let t=i[e].split(`=`)[0];if(K(t))return{action:`passthrough`,rule:null,reason:`dangerous env var: ${t}`};e++}return e>=i.length?{action:`allow`,rule:`env-only`,reason:null}:q(i.slice(e).join(` `),{...t,depth:t.depth+1})}if(l===`pnpm`)return Et(i,t);if(l===`npm`)return Ot(i);if(l===`bash`||l===`sh`||l===`zsh`)return jt(i,t);if(l===`node`&&(i.includes(`-e`)||i.includes(`-p`)||i.includes(`--eval`)||i.includes(`--print`)))return{action:`passthrough`,rule:null,reason:`node eval`};if(l===`mv`)return{action:`passthrough`,rule:null,reason:`mv`};for(let e of ft)if(e.match.test(l)&&(!e.when||e.when(i,t)))return{action:`deny`,rule:e.name,reason:e.reason??null};for(let e of U)if(e.match.test(l)&&(!e.when||e.when(i,t)))return{action:`allow`,rule:e.name,reason:null};return{action:`passthrough`,rule:null,reason:`no rule matched: ${l}`}}function Et(e,t){let n=e.slice(1),r,i=-1,o=!1,s=!1,c;for(let a=0;a<n.length;a++){let l=n[a];if(l===`--filter`||l.startsWith(`--filter=`))return kt(e,n,a,t);if(l===`-r`||l===`--recursive`){o=!0;continue}if(l===`-w`||l===`--workspace-root`){s=!0;continue}if(l===`-C`||l===`--dir`){c=n[++a];continue}if(l.startsWith(`-C=`)||l.startsWith(`--dir=`)){c=l.split(`=`,2)[1];continue}if(!(l.startsWith(`-`)&&!V.has(l))){r=l,i=a;break}}if(!r)return{action:`passthrough`,rule:null,reason:null};if(r===`dlx`)return{action:`passthrough`,rule:null,reason:`pnpm dlx`};if(r===`add`)return{action:`passthrough`,rule:null,reason:`pnpm add`};if(r===`exec`){let e=n.slice(i+1);return e.length===0?{action:`passthrough`,rule:null,reason:`bare pnpm exec`}:q(e.join(` `),{...t,depth:t.depth+1})}let l;if(r===`run`){let e=n[i+1];if(!e||e.startsWith(`-`))return{action:`passthrough`,rule:null,reason:`pnpm run without script name`};l=e}else if(!V.has(r))l=r;else{for(let n of U)if(n.match.test(`pnpm`)&&(!n.when||n.when(e,t)))return{action:`allow`,rule:n.name,reason:null};return{action:`passthrough`,rule:null,reason:null}}if(o)return Dt(l,t);if(s){let e=gt(t.cwd);return e?Y(l,{...t,cwd:e}):{action:`passthrough`,rule:null,reason:`workspace root not found`}}if(c){let e=a.resolve(t.cwd,c);return Y(l,{...t,cwd:e})}return Y(l,t)}function Y(e,t){let n=W(e,t.cwd);if(!n)return{action:`passthrough`,rule:null,reason:`script resolution failed`};let r=J(n,{...t,depth:t.depth+1});return r===`allow`?{action:`allow`,rule:`pnpm-script:${e}`,reason:null}:r}function Dt(e,t){let n=ht(e,t.cwd);if(!n||n.length===0)return{action:`passthrough`,rule:null,reason:`pnpm recursive`};for(let e of n){let n=J(e,{...t,depth:t.depth+1,cwd:e.pkgDir??t.cwd});if(n!==`allow`)return n}return{action:`allow`,rule:`pnpm-recursive:${e}`,reason:null}}function Ot(e){for(let t of U)if(t.match.test(`npm`)&&(!t.when||t.when(e,{cwd:``,depth:0})))return{action:`allow`,rule:t.name,reason:null};return{action:`deny`,rule:`npm-redirect`,reason:it(e)}}function kt(e,t,n,r){let i=t[n],a,o;if(i.startsWith(`--filter=`))a=i.slice(9),o=n+1;else{if(a=t[n+1],!a||a.startsWith(`-`))return{action:`passthrough`,rule:null,reason:`pnpm --filter without package`};o=n+2}if(!a)return{action:`passthrough`,rule:null,reason:`pnpm --filter without package`};let s;for(let e=o;e<t.length;e++){let n=t[e];if(!(n.startsWith(`-`)&&!V.has(n))){s=n;break}}if(!s)return{action:`passthrough`,rule:null,reason:`pnpm --filter without subcommand`};if(s===`install`||s===`i`)return t.slice(t.indexOf(s)+1).every(e=>e.startsWith(`-`))?{action:`allow`,rule:`pnpm`,reason:null}:{action:`passthrough`,rule:null,reason:`pnpm --filter install with package arg`};if(s===`dlx`)return{action:`passthrough`,rule:null,reason:`pnpm dlx`};if(s===`add`)return{action:`passthrough`,rule:null,reason:`pnpm add`};if(new Set([`list`,`ls`,`ll`,`la`,`why`,`view`,`info`,`show`,`outdated`,`licenses`,`audit`]).has(s))return{action:`allow`,rule:`pnpm`,reason:null};if(s===`exec`){let e=t.indexOf(`exec`,o),n=t.slice(e+1);return n.length===0?{action:`passthrough`,rule:null,reason:`bare pnpm exec`}:q(n.join(` `),{...r,depth:r.depth+1})}let c=s===`run`?t[t.indexOf(`run`,o)+1]:s;if(!c||c.startsWith(`-`))return{action:`passthrough`,rule:null,reason:`pnpm --filter run without script name`};if(V.has(c)&&c!==`run`)return{action:`passthrough`,rule:null,reason:null};let l=mt(c,a,r.cwd);if(!l)return{action:`passthrough`,rule:null,reason:`filtered script resolution failed`};let u=J(l,{...r,depth:r.depth+1,cwd:l.pkgDir??r.cwd});return u===`allow`?{action:`allow`,rule:`pnpm-filter:${a}:${c}`,reason:null}:u}const At=new Set([`-i`,`--interactive`,`-l`,`--login`,`--init-file`,`--rcfile`,`--norc`,`--noprofile`,`-s`,`--stdin`]);function jt(e,t){let n=e.indexOf(`-c`);if(n===-1)return{action:`passthrough`,rule:null,reason:`shell without -c`};for(let t=1;t<e.length;t++){if(t===n||t===n+1)continue;let r=e[t];if(r.startsWith(`-`)||At.has(r))return{action:`passthrough`,rule:null,reason:`shell -c with extra flags`}}let r=e[n+1];return r?e.length>n+2?{action:`passthrough`,rule:null,reason:`shell -c with positional args`}:n===1?q(r,{...t,depth:t.depth+1}):{action:`passthrough`,rule:null,reason:`shell -c with extra flags`}:{action:`passthrough`,rule:null,reason:`shell -c without command`}}const Mt=new Set([`Read`,`Glob`,`Grep`]),X=new Set([`Write`,`Edit`]),Nt=[{name:`env-file-read`,tools:Mt,action:`deny`,when:e=>z(e),reason:`Don't read .env files. These contain secrets that should not appear in the conversation.`},{name:`env-file-write`,tools:X,action:`deny`,when:e=>z(e),reason:`Don't write to .env files. These contain secrets.`},{name:`outside-cwd-write`,tools:X,action:`deny`,when:(e,t)=>{let n=a.resolve(t.cwd,e);return n!==t.cwd&&!n.startsWith(t.cwd+a.sep)},reason:`Don't write files outside the project directory.`}],Pt=[{name:`cwd-read`,tools:Mt,action:`allow`,when:(e,t)=>{let n=a.resolve(t.cwd,e);return n===t.cwd||n.startsWith(t.cwd+a.sep)}},{name:`cwd-write`,tools:X,action:`allow`,when:(e,t)=>{let n=a.resolve(t.cwd,e);return n===t.cwd||n.startsWith(t.cwd+a.sep)}}],Ft=new Set([`Read`,`Write`,`Edit`]),It=new Set([`Glob`,`Grep`]);function Lt(e,t,n){return Ft.has(e)?Ie(t)?.file_path??null:It.has(e)?Le(t)?.path??n:null}function Rt(e,t,n){let r=Lt(e,t,n.cwd);if(r===null)return{action:`passthrough`,rule:null,reason:`unknown tool input shape`};for(let t of Nt)if(t.tools.has(e)&&t.when(r,n))return{action:`deny`,rule:t.name,reason:t.reason??null};for(let t of Pt)if(t.tools.has(e)&&t.when(r,n))return{action:`allow`,rule:t.name,reason:null};return{action:`passthrough`,rule:null,reason:`no file rule matched`}}const Z=await je();Z.hook_event_name!==`PreToolUse`&&process.exit(0),new Set([`Bash`,`Read`,`Write`,`Edit`,`Glob`,`Grep`]).has(Z.tool_name)||process.exit(0);let Q,$;if(Z.tool_name===`Bash`){let e=Fe(Z.tool_input);e||process.exit(0),Q=q(e.command,{cwd:Z.cwd,depth:0}),$=e.command}else{let e=process.env.CLAUDE_PROJECT_DIR??Z.cwd;Q=Rt(Z.tool_name,Z.tool_input,{cwd:e});let t=String(Z.tool_input.file_path??Z.tool_input.path??``);$=`${Z.tool_name} ${t}`}Ve({sessionId:Z.session_id,cwd:Z.cwd,toolName:Z.tool_name,command:$,decision:Q.action,rule:Q.rule,reason:Q.reason}),Q.action===`allow`?F(`allow`):Q.action===`deny`&&F(`deny`,Q.reason);export{};";
2462
- const existing = ctx.read(HOOK_PATH);
2460
+ const GUIDE_PATH = ".claude/hooks/bst-hook-guide.md";
2461
+ function writeIfChanged(ctx, filePath, content, label) {
2462
+ const existing = ctx.read(filePath);
2463
2463
  if (existing === content) return {
2464
- filePath: HOOK_PATH,
2464
+ filePath,
2465
2465
  action: "skipped",
2466
- description: "Hook is up to date"
2466
+ description: `${label} is up to date`
2467
2467
  };
2468
- ctx.write(HOOK_PATH, content);
2468
+ ctx.write(filePath, content);
2469
2469
  return {
2470
- filePath: HOOK_PATH,
2470
+ filePath,
2471
2471
  action: existing ? "updated" : "created",
2472
- description: existing ? "Updated bst-hook.mjs" : "Generated bst-hook.mjs"
2472
+ description: existing ? `Updated ${label}` : `Generated ${label}`
2473
2473
  };
2474
2474
  }
2475
+ async function generateClaudeHooks(ctx) {
2476
+ return [writeIfChanged(ctx, HOOK_PATH, "/**\n * bst-hook — Claude Code PreToolUse hook\n * @bensandee/claude-hooks v0.5.0\n * https://github.com/bensandee/tooling\n *\n * Auto-generated by @bensandee/tooling repo:sync — do not edit manually.\n */\nimport{a as e,i as t,n,o as r,r as i,t as a}from\"./file-rules-cP7-5vh6.mjs\";import*as o from\"node:fs\";import{existsSync as s,readFileSync as c,readdirSync as l,statSync as u}from\"node:fs\";import*as d from\"node:path\";import{dirname as ee,join as f,resolve as p}from\"node:path\";import{fileURLToPath as te}from\"node:url\";Object.freeze({status:`aborted`});function m(e,t,n){function r(n,r){if(n._zod||Object.defineProperty(n,`_zod`,{value:{def:r,constr:o,traits:new Set},enumerable:!1}),n._zod.traits.has(e))return;n._zod.traits.add(e),t(n,r);let i=o.prototype,a=Object.keys(i);for(let e=0;e<a.length;e++){let t=a[e];t in n||(n[t]=i[t].bind(n))}}let i=n?.Parent??Object;class a extends i{}Object.defineProperty(a,`name`,{value:e});function o(e){var t;let i=n?.Parent?new a:this;r(i,e),(t=i._zod).deferred??(t.deferred=[]);for(let e of i._zod.deferred)e();return i}return Object.defineProperty(o,`init`,{value:r}),Object.defineProperty(o,Symbol.hasInstance,{value:t=>n?.Parent&&t instanceof n.Parent?!0:t?._zod?.traits?.has(e)}),Object.defineProperty(o,`name`,{value:e}),o}var h=class extends Error{constructor(){super(`Encountered Promise during synchronous parse. Use .parseAsync() instead.`)}};const g={};function _(e){return e&&Object.assign(g,e),g}function ne(e,t){return typeof t==`bigint`?t.toString():t}function re(e){return{get value(){{let t=e();return Object.defineProperty(this,`value`,{value:t}),t}throw Error(`cached value already set`)}}}function ie(e){let t=e.startsWith(`^`)?1:0,n=e.endsWith(`$`)?e.length-1:e.length;return e.slice(t,n)}const v=Symbol(`evaluating`);function y(e,t,n){let r;Object.defineProperty(e,t,{get(){if(r!==v)return r===void 0&&(r=v,r=n()),r},set(n){Object.defineProperty(e,t,{value:n})},configurable:!0})}const b=`captureStackTrace`in Error?Error.captureStackTrace:(...e)=>{};function x(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function ae(e){if(x(e)===!1)return!1;let t=e.constructor;if(t===void 0||typeof t!=`function`)return!0;let n=t.prototype;return!(x(n)===!1||Object.prototype.hasOwnProperty.call(n,`isPrototypeOf`)===!1)}function oe(e,t,n){let r=new e._zod.constr(t??e._zod.def);return(!t||n?.parent)&&(r._zod.parent=e),r}function S(e){let t=e;if(!t)return{};if(typeof t==`string`)return{error:()=>t};if(t?.message!==void 0){if(t?.error!==void 0)throw Error(\"Cannot specify both `message` and `error` params\");t.error=t.message}return delete t.message,typeof t.error==`string`?{...t,error:()=>t.error}:t}function se(e){return Object.keys(e).filter(t=>e[t]._zod.optin===`optional`&&e[t]._zod.optout===`optional`)}-Number.MAX_VALUE,Number.MAX_VALUE;function C(e,t=0){if(e.aborted===!0)return!0;for(let n=t;n<e.issues.length;n++)if(e.issues[n]?.continue!==!0)return!0;return!1}function w(e,t){return t.map(t=>{var n;return(n=t).path??(n.path=[]),t.path.unshift(e),t})}function T(e){return typeof e==`string`?e:e?.message}function E(e,t,n){let r={...e,path:e.path??[]};return e.message||(r.message=T(e.inst?._zod.def?.error?.(e))??T(t?.error?.(e))??T(n.customError?.(e))??T(n.localeError?.(e))??`Invalid input`),delete r.inst,delete r.continue,t?.reportInput||delete r.input,r}const D=(e,t)=>{e.name=`$ZodError`,Object.defineProperty(e,`_zod`,{value:e._zod,enumerable:!1}),Object.defineProperty(e,`issues`,{value:t,enumerable:!1}),e.message=JSON.stringify(t,ne,2),Object.defineProperty(e,`toString`,{value:()=>e.message,enumerable:!1})},ce=m(`$ZodError`,D),O=m(`$ZodError`,D,{Parent:Error}),le=(e=>(t,n,r,i)=>{let a=r?Object.assign(r,{async:!1}):{async:!1},o=t._zod.run({value:n,issues:[]},a);if(o instanceof Promise)throw new h;if(o.issues.length){let t=new(i?.Err??e)(o.issues.map(e=>E(e,a,_())));throw b(t,i?.callee),t}return o.value})(O),ue=(e=>async(t,n,r,i)=>{let a=r?Object.assign(r,{async:!0}):{async:!0},o=t._zod.run({value:n,issues:[]},a);if(o instanceof Promise&&(o=await o),o.issues.length){let t=new(i?.Err??e)(o.issues.map(e=>E(e,a,_())));throw b(t,i?.callee),t}return o.value})(O),k=(e=>(t,n,r)=>{let i=r?{...r,async:!1}:{async:!1},a=t._zod.run({value:n,issues:[]},i);if(a instanceof Promise)throw new h;return a.issues.length?{success:!1,error:new(e??ce)(a.issues.map(e=>E(e,i,_())))}:{success:!0,data:a.value}})(O),A=(e=>async(t,n,r)=>{let i=r?Object.assign(r,{async:!0}):{async:!0},a=t._zod.run({value:n,issues:[]},i);return a instanceof Promise&&(a=await a),a.issues.length?{success:!1,error:new e(a.issues.map(e=>E(e,i,_())))}:{success:!0,data:a.value}})(O),de=e=>{let t=e?`[\\\\s\\\\S]{${e?.minimum??0},${e?.maximum??``}}`:`[\\\\s\\\\S]*`;return RegExp(`^${t}$`)},fe=/^-?\\d+(?:\\.\\d+)?$/,pe={major:4,minor:3,patch:6},j=m(`$ZodType`,(e,t)=>{var n;e??={},e._zod.def=t,e._zod.bag=e._zod.bag||{},e._zod.version=pe;let r=[...e._zod.def.checks??[]];e._zod.traits.has(`$ZodCheck`)&&r.unshift(e);for(let t of r)for(let n of t._zod.onattach)n(e);if(r.length===0)(n=e._zod).deferred??(n.deferred=[]),e._zod.deferred?.push(()=>{e._zod.run=e._zod.parse});else{let t=(e,t,n)=>{let r=C(e),i;for(let a of t){if(a._zod.def.when){if(!a._zod.def.when(e))continue}else if(r)continue;let t=e.issues.length,o=a._zod.check(e);if(o instanceof Promise&&n?.async===!1)throw new h;if(i||o instanceof Promise)i=(i??Promise.resolve()).then(async()=>{await o,e.issues.length!==t&&(r||=C(e,t))});else{if(e.issues.length===t)continue;r||=C(e,t)}}return i?i.then(()=>e):e},n=(n,i,a)=>{if(C(n))return n.aborted=!0,n;let o=t(i,r,a);if(o instanceof Promise){if(a.async===!1)throw new h;return o.then(t=>e._zod.parse(t,a))}return e._zod.parse(o,a)};e._zod.run=(i,a)=>{if(a.skipChecks)return e._zod.parse(i,a);if(a.direction===`backward`){let t=e._zod.parse({value:i.value,issues:[]},{...a,skipChecks:!0});return t instanceof Promise?t.then(e=>n(e,i,a)):n(t,i,a)}let o=e._zod.parse(i,a);if(o instanceof Promise){if(a.async===!1)throw new h;return o.then(e=>t(e,r,a))}return t(o,r,a)}}y(e,`~standard`,()=>({validate:t=>{try{let n=k(e,t);return n.success?{value:n.data}:{issues:n.error?.issues}}catch{return A(e,t).then(e=>e.success?{value:e.data}:{issues:e.error?.issues})}},vendor:`zod`,version:1}))}),me=m(`$ZodString`,(e,t)=>{j.init(e,t),e._zod.pattern=[...e?._zod.bag?.patterns??[]].pop()??de(e._zod.bag),e._zod.parse=(n,r)=>{if(t.coerce)try{n.value=String(n.value)}catch{}return typeof n.value==`string`||n.issues.push({expected:`string`,code:`invalid_type`,input:n.value,inst:e}),n}}),he=m(`$ZodUnknown`,(e,t)=>{j.init(e,t),e._zod.parse=e=>e});function M(e,t,n,r,i){if(e.issues.length){if(i&&!(n in r))return;t.issues.push(...w(n,e.issues))}e.value===void 0?n in r&&(t.value[n]=void 0):t.value[n]=e.value}function ge(e){let t=Object.keys(e.shape);for(let n of t)if(!e.shape?.[n]?._zod?.traits?.has(`$ZodType`))throw Error(`Invalid element at key \"${n}\": expected a Zod schema`);let n=se(e.shape);return{...e,keys:t,keySet:new Set(t),numKeys:t.length,optionalKeys:new Set(n)}}function _e(e,t,n,r,i,a){let o=[],s=i.keySet,c=i.catchall._zod,l=c.def.type,u=c.optout===`optional`;for(let i in t){if(s.has(i))continue;if(l===`never`){o.push(i);continue}let a=c.run({value:t[i],issues:[]},r);a instanceof Promise?e.push(a.then(e=>M(e,n,i,t,u))):M(a,n,i,t,u)}return o.length&&n.issues.push({code:`unrecognized_keys`,keys:o,input:t,inst:a}),e.length?Promise.all(e).then(()=>n):n}const ve=m(`$ZodObject`,(e,t)=>{if(j.init(e,t),!Object.getOwnPropertyDescriptor(t,`shape`)?.get){let e=t.shape;Object.defineProperty(t,`shape`,{get:()=>{let n={...e};return Object.defineProperty(t,`shape`,{value:n}),n}})}let n=re(()=>ge(t));y(e._zod,`propValues`,()=>{let e=t.shape,n={};for(let t in e){let r=e[t]._zod;if(r.values){n[t]??(n[t]=new Set);for(let e of r.values)n[t].add(e)}}return n});let r=x,i=t.catchall,a;e._zod.parse=(t,o)=>{a??=n.value;let s=t.value;if(!r(s))return t.issues.push({expected:`object`,code:`invalid_type`,input:s,inst:e}),t;t.value={};let c=[],l=a.shape;for(let e of a.keys){let n=l[e],r=n._zod.optout===`optional`,i=n._zod.run({value:s[e],issues:[]},o);i instanceof Promise?c.push(i.then(n=>M(n,t,e,s,r))):M(i,t,e,s,r)}return i?_e(c,s,t,o,n.value,e):c.length?Promise.all(c).then(()=>t):t}}),ye=m(`$ZodRecord`,(e,t)=>{j.init(e,t),e._zod.parse=(n,r)=>{let i=n.value;if(!ae(i))return n.issues.push({expected:`record`,code:`invalid_type`,input:i,inst:e}),n;let a=[],o=t.keyType._zod.values;if(o){n.value={};let s=new Set;for(let e of o)if(typeof e==`string`||typeof e==`number`||typeof e==`symbol`){s.add(typeof e==`number`?e.toString():e);let o=t.valueType._zod.run({value:i[e],issues:[]},r);o instanceof Promise?a.push(o.then(t=>{t.issues.length&&n.issues.push(...w(e,t.issues)),n.value[e]=t.value})):(o.issues.length&&n.issues.push(...w(e,o.issues)),n.value[e]=o.value)}let c;for(let e in i)s.has(e)||(c??=[],c.push(e));c&&c.length>0&&n.issues.push({code:`unrecognized_keys`,input:i,inst:e,keys:c})}else{n.value={};for(let o of Reflect.ownKeys(i)){if(o===`__proto__`)continue;let s=t.keyType._zod.run({value:o,issues:[]},r);if(s instanceof Promise)throw Error(`Async schemas not supported in object keys currently`);if(typeof o==`string`&&fe.test(o)&&s.issues.length){let e=t.keyType._zod.run({value:Number(o),issues:[]},r);if(e instanceof Promise)throw Error(`Async schemas not supported in object keys currently`);e.issues.length===0&&(s=e)}if(s.issues.length){t.mode===`loose`?n.value[o]=i[o]:n.issues.push({code:`invalid_key`,origin:`record`,issues:s.issues.map(e=>E(e,r,_())),input:o,path:[o],inst:e});continue}let c=t.valueType._zod.run({value:i[o],issues:[]},r);c instanceof Promise?a.push(c.then(e=>{e.issues.length&&n.issues.push(...w(o,e.issues)),n.value[s.value]=e.value})):(c.issues.length&&n.issues.push(...w(o,c.issues)),n.value[s.value]=c.value)}}return a.length?Promise.all(a).then(()=>n):n}});function N(e,t){return e.issues.length&&t===void 0?{issues:[],value:void 0}:e}const be=m(`$ZodOptional`,(e,t)=>{j.init(e,t),e._zod.optin=`optional`,e._zod.optout=`optional`,y(e._zod,`values`,()=>t.innerType._zod.values?new Set([...t.innerType._zod.values,void 0]):void 0),y(e._zod,`pattern`,()=>{let e=t.innerType._zod.pattern;return e?RegExp(`^(${ie(e.source)})?$`):void 0}),e._zod.parse=(e,n)=>{if(t.innerType._zod.optin===`optional`){let r=t.innerType._zod.run(e,n);return r instanceof Promise?r.then(t=>N(t,e.value)):N(r,e.value)}return e.value===void 0?e:t.innerType._zod.run(e,n)}});var P,xe=class{constructor(){this._map=new WeakMap,this._idmap=new Map}add(e,...t){let n=t[0];return this._map.set(e,n),n&&typeof n==`object`&&`id`in n&&this._idmap.set(n.id,e),this}clear(){return this._map=new WeakMap,this._idmap=new Map,this}remove(e){let t=this._map.get(e);return t&&typeof t==`object`&&`id`in t&&this._idmap.delete(t.id),this._map.delete(e),this}get(e){let t=e._zod.parent;if(t){let n={...this.get(t)??{}};delete n.id;let r={...n,...this._map.get(e)};return Object.keys(r).length?r:void 0}return this._map.get(e)}has(e){return this._map.has(e)}};function Se(){return new xe}(P=globalThis).__zod_globalRegistry??(P.__zod_globalRegistry=Se()),globalThis.__zod_globalRegistry;function Ce(e,t){return new e({type:`string`,...S(t)})}function we(e){return new e({type:`unknown`})}const F=m(`ZodMiniType`,(e,t)=>{if(!e._zod)throw Error(`Uninitialized schema in ZodMiniType.`);j.init(e,t),e.def=t,e.type=t.type,e.parse=(t,n)=>le(e,t,n,{callee:e.parse}),e.safeParse=(t,n)=>k(e,t,n),e.parseAsync=async(t,n)=>ue(e,t,n,{callee:e.parseAsync}),e.safeParseAsync=async(t,n)=>A(e,t,n),e.check=(...n)=>e.clone({...t,checks:[...t.checks??[],...n.map(e=>typeof e==`function`?{_zod:{check:e,def:{check:`custom`},onattach:[]}}:e)]},{parent:!0}),e.with=e.check,e.clone=(t,n)=>oe(e,t,n),e.brand=()=>e,e.register=((t,n)=>(t.add(e,n),e)),e.apply=t=>t(e)}),Te=m(`ZodMiniString`,(e,t)=>{me.init(e,t),F.init(e,t)});function I(e){return Ce(Te,e)}const Ee=m(`ZodMiniUnknown`,(e,t)=>{he.init(e,t),F.init(e,t)});function L(){return we(Ee)}const De=m(`ZodMiniObject`,(e,t)=>{ve.init(e,t),F.init(e,t),y(e,`shape`,()=>t.shape)});function R(e,t){return new De({type:`object`,shape:e??{},...S(t)})}const Oe=m(`ZodMiniRecord`,(e,t)=>{ye.init(e,t),F.init(e,t)});function z(e,t,n){return new Oe({type:`record`,keyType:e,valueType:t,...S(n)})}const ke=m(`ZodMiniOptional`,(e,t)=>{be.init(e,t),F.init(e,t)});function B(e){return new ke({type:`optional`,innerType:e})}const Ae=R({session_id:I(),transcript_path:I(),cwd:I(),permission_mode:I(),hook_event_name:I(),tool_name:I(),tool_input:z(I(),L())});async function je(){let e=[];for await(let t of process.stdin)e.push(typeof t==`string`?t:String(t));let t=JSON.parse(e.join(``)),n=Ae.safeParse(t);return n.success||(process.stderr.write(`[bst-hook] invalid hook input: ${n.error.message}\\n`),process.exit(0)),n.data}const Me=R({command:I(),description:B(I())}),Ne=R({file_path:I()}),Pe=R({pattern:I(),path:B(I())});function Fe(e){let t=Me.safeParse(e);return t.success?t.data:null}function Ie(e){let t=Ne.safeParse(e);return t.success?t.data:null}function Le(e){let t=Pe.safeParse(e);return t.success?t.data:null}function V(e,t){let n={hookSpecificOutput:{hookEventName:`PreToolUse`,permissionDecision:e,...e===`deny`&&t?{permissionDecisionReason:t}:{}}};process.stdout.write(JSON.stringify(n))}function Re(){let e=d.dirname(te(import.meta.url));return d.join(e,`bst-hook.audit.local.jsonl`)}function ze(e){try{if(o.statSync(e).size>1048576){let t=`${e}.1`;o.renameSync(e,t)}}catch{}}let Be=!1;function Ve(e){try{let t=Re();Be||=(ze(t),!0);let n={timestamp:new Date().toISOString(),...e};o.appendFileSync(t,JSON.stringify(n)+`\n`)}catch(e){process.stderr.write(`[bst-hook] audit write failed: ${e instanceof Error?e.message:String(e)}\\n`)}}function H(e){let t=[],n=``,r=0,i=!1;for(;r<e.length;){let a=e[r];if(a===`'`){for(i=!0,r++;r<e.length&&e[r]!==`'`;)n+=e[r],r++;if(r>=e.length)return{ok:!1,error:`unterminated single quote`};r++}else if(a===`\"`){for(i=!0,r++;r<e.length&&e[r]!==`\"`;){if(e[r]===`\\\\`&&r+1<e.length){let t=e[r+1];if(t===`\"`||t===`\\\\`||t===`$`||t===\"`\"){n+=t,r+=2;continue}}n+=e[r],r++}if(r>=e.length)return{ok:!1,error:`unterminated double quote`};r++}else a===`\\\\`&&r+1<e.length?(i=!0,n+=e[r+1],r+=2):a===` `||a===` `?(i&&=(t.push(n),n=``,!1),r++):(i=!0,n+=a,r++)}return i&&t.push(n),{ok:!0,tokens:t}}function He(e){if(!e||!e.trim())return[];let t=[],n=``,r=0,i=!1,a=!1;for(;r<e.length;){let o=e[r];if(o===`'`&&!a){i=!i,n+=o,r++;continue}if(o===`\"`&&!i){a=!a,n+=o,r++;continue}if(o===`\\\\`&&!i&&r+1<e.length){n+=o+e[r+1],r+=2;continue}if(!i&&!a){if(o===`&`&&r+1<e.length&&e[r+1]===`&`){U(t,n,`&&`),n=``,r+=2;continue}if(o===`&`&&!(r+1<e.length&&e[r+1]===`>`)&&!(r>0&&(e[r-1]===`>`||e[r-1]===`<`))){U(t,n,`&`),n=``,r++;continue}if(o===`|`&&r+1<e.length&&e[r+1]===`|`){U(t,n,`||`),n=``,r+=2;continue}if(o===`|`){U(t,n,`|`),n=``,r++;continue}if(o===`;`){U(t,n,`;`),n=``,r++;continue}}n+=o,r++}let o=n.trim();return o&&t.push({command:o,operator:null}),t}function U(e,t,n){let r=t.trim();r&&e.push({command:r,operator:n})}const W=new Set([`2>&1`,`2>/dev/null`,`>/dev/null`,`1>/dev/null`]);function Ue(e,t){if(/[\\n\\r]/.test(t))return{safe:!1,reason:`unquoted newline in command`};for(let t of e){if(t===\"`\")return{safe:!1,reason:`backtick command substitution`};if(t.includes(`$(`))return{safe:!1,reason:`dollar command substitution`};if(t.includes(\"`\"))return{safe:!1,reason:`backtick command substitution`};if(t.includes(`<(`)||t.includes(`>(`)&&!W.has(t))return{safe:!1,reason:`process substitution`}}for(let t=0;t<e.length;t++){let n=e[t];if(!W.has(n)){if(n.includes(`<`)&&!n.includes(`<(`))return{safe:!1,reason:`input redirect`};if(n.includes(`>`)){if(n.endsWith(`>/dev/null`)||n.match(/^(&>>|&>|>>|>|1>|2>)$/)&&e[t+1]===`/dev/null`)continue;return{safe:!1,reason:`output redirect to file`}}}}return{safe:!0}}const We=R({scripts:z(I(),L())});function G(e,t){let n=Qe(t);if(!n)return null;let r=n[e];if(typeof r!=`string`)return null;let i=n[`pre${e}`],a=n[`post${e}`];return{pre:typeof i==`string`?i:null,main:r,post:typeof a==`string`?a:null}}function Ge(e,t,n){let r=Je(t,n);if(!r)return null;let i=G(e,r);return i?{...i,pkgDir:r}:null}function Ke(e,t){let n=K(t);if(!n)return null;let r=[];for(let t of n){let n=G(e,t);n&&r.push({...n,pkgDir:t})}return r}function qe(e){let t=p(e);for(;;){if(s(f(t,`pnpm-workspace.yaml`)))return t;let e=ee(t);if(e===t)return null;t=e}}function K(e){let t=Ye(e);if(!t)return null;let n=[];for(let r of t){if(!r.endsWith(`/*`))continue;let t=p(e,r.slice(0,-2)),i;try{i=l(t)}catch{continue}for(let e of i){let r=f(t,e);try{if(!u(r).isDirectory())continue}catch{continue}n.push(r)}}return n.length>0?n:null}function Je(e,t){let n=K(t);if(!n)return null;for(let t of n){let n=Ze(t);if(n===e||n===`@${e}`||t.split(`/`).pop()===e||n&&(n.startsWith(`@`)?n.split(`/`)[1]:n)===e)return t}return null}function Ye(e){try{let t=c(f(e,`pnpm-workspace.yaml`),`utf-8`).split(`\n`),n=t.findIndex(e=>/^packages\\s*:/.test(e));if(n===-1)return null;let r=[];for(let e=n+1;e<t.length;e++){let n=t[e],i=/^\\s+-\\s+(.+)$/.exec(n);if(!i)break;r.push(i[1].trim().replace(/['\"`]/g,``))}return r.length>0?r:null}catch{return null}}const Xe=R({name:I()});function Ze(e){try{let t=c(f(e,`package.json`),`utf-8`),n=Xe.safeParse(JSON.parse(t));return n.success?n.data.name:null}catch{return null}}function Qe(e){try{let t=c(f(e,`package.json`),`utf-8`),n=We.safeParse(JSON.parse(t));return n.success?n.data.scripts:null}catch{return null}}const $e=new Set([`LD_PRELOAD`,`LD_LIBRARY_PATH`,`DYLD_INSERT_LIBRARIES`,`NODE_OPTIONS`,`PYTHONPATH`,`PYTHONSTARTUP`,`PERL5OPT`,`PERL5LIB`,`RUBYOPT`,`RUBYLIB`,`BASH_ENV`,`ENV`,`npm_config_prefix`,`npm_config_registry`,`EDITOR`,`VISUAL`]),et=[`GIT_CONFIG_`,`GIT_PAGER`,`GIT_SSH_COMMAND`,`GIT_EDITOR`,`GIT_EXEC_PATH`];function q(e){return $e.has(e)?!0:et.some(t=>e.startsWith(t))}function tt(e,t){let n=H(e);if(!n.ok||n.tokens.length!==2)return null;let r=n.tokens;if(r[0]!==`cd`)return null;let i=r[1];return d.isAbsolute(i)?i:d.resolve(t.cwd,i)}function J(e,t){if(t.depth>=5)return{action:`passthrough`,rule:null,reason:`max evaluation depth exceeded`};let n=e.trim();if(!n)return{action:`passthrough`,rule:null,reason:null};if(n.startsWith(`(`)&&n.endsWith(`)`))return{action:`passthrough`,rule:null,reason:`subshell`};let r=He(n);if(r.length===0)return{action:`passthrough`,rule:null,reason:null};let i=null,a=null,o=t;for(let e of r){if(e.operator===`&&`){let t=tt(e.command,o);t&&(o={...o,cwd:t})}let t=nt(e.command,o);if(t.action===`deny`)return t;t.action===`passthrough`&&(i||=t),t.action===`allow`&&(a=t)}return i||(r.length===1&&a?a:{action:`allow`,rule:`all-segments`,reason:null})}function Y(e,t){if(e.pre){let n=J(e.pre,t);if(n.action!==`allow`)return n}let n=J(e.main,t);if(n.action!==`allow`)return n;if(e.post){let n=J(e.post,t);if(n.action!==`allow`)return n}return`allow`}function nt(n,r){let i=n.trim();if(i.startsWith(`(`)&&i.endsWith(`)`))return{action:`passthrough`,rule:null,reason:`subshell`};let a=H(n);if(!a.ok)return{action:`passthrough`,rule:null,reason:a.error};let o=a.tokens;if(o.length===0)return{action:`passthrough`,rule:null,reason:null};let s=0;for(;s<o.length&&/^\\w+=/.test(o[s]);){let e=o[s].split(`=`)[0];if(q(e))return{action:`passthrough`,rule:null,reason:`dangerous env var: ${e}`};s++}if(s>=o.length)return{action:`allow`,rule:`env-only`,reason:null};o=o.slice(s);let c=Ue(o,n);if(!c.safe)return{action:`passthrough`,rule:null,reason:c.reason};for(let e=0;e<o.length;e++){let t=o[e];if(!(t===`2>&1`||t===`2>/dev/null`||t===`>/dev/null`||t===`1>/dev/null`)){if(t===`>`||t===`>>`){if(o[e+1]===`/dev/null`)continue;return{action:`passthrough`,rule:null,reason:`output redirect to file`}}if(t===`<`)return{action:`passthrough`,rule:null,reason:`input redirect`}}}let l=new Set([`2>&1`,`2>/dev/null`,`>/dev/null`,`1>/dev/null`]);o=o.filter((e,t)=>!(l.has(e)||(e===`>`||e===`>>`)&&o[t+1]===`/dev/null`||e===`/dev/null`&&t>0&&(o[t-1]===`>`||o[t-1]===`>>`)));let u=d.basename(o[0]);if(u===`command`&&o.length>1)return J(o.slice(1).join(` `),{...r,depth:r.depth+1});if(u===`env`){let e=1;for(;e<o.length&&/^\\w+=/.test(o[e]);){let t=o[e].split(`=`)[0];if(q(t))return{action:`passthrough`,rule:null,reason:`dangerous env var: ${t}`};e++}return e>=o.length?{action:`allow`,rule:`env-only`,reason:null}:J(o.slice(e).join(` `),{...r,depth:r.depth+1})}if(u===`pnpm`)return rt(o,r);if(u===`npm`)return at(o);if(u===`bash`||u===`sh`||u===`zsh`)return ct(o,r);if(u===`node`&&(o.includes(`-e`)||o.includes(`-p`)||o.includes(`--eval`)||o.includes(`--print`)))return{action:`passthrough`,rule:null,reason:`node eval`};if(u===`mv`)return{action:`passthrough`,rule:null,reason:`mv`};for(let t of e)if(t.match.test(u)&&(!t.when||t.when(o,r)))return{action:`deny`,rule:t.name,reason:t.reason??null};for(let e of t)if(e.match.test(u)&&(!e.when||e.when(o,r)))return{action:`allow`,rule:e.name,reason:null};return{action:`passthrough`,rule:null,reason:`no rule matched: ${u}`}}function rt(e,n){let r=e.slice(1),a,o=-1,s=!1,c=!1,l;for(let t=0;t<r.length;t++){let u=r[t];if(u===`--filter`||u.startsWith(`--filter=`))return ot(e,r,t,n);if(u===`-r`||u===`--recursive`){s=!0;continue}if(u===`-w`||u===`--workspace-root`){c=!0;continue}if(u===`-C`||u===`--dir`){l=r[++t];continue}if(u.startsWith(`-C=`)||u.startsWith(`--dir=`)){l=u.split(`=`,2)[1];continue}if(!(u.startsWith(`-`)&&!i.has(u))){a=u,o=t;break}}if(!a)return{action:`passthrough`,rule:null,reason:null};if(a===`dlx`)return{action:`passthrough`,rule:null,reason:`pnpm dlx`};if(a===`add`)return{action:`passthrough`,rule:null,reason:`pnpm add`};if(a===`exec`){let e=r.slice(o+1);return e.length===0?{action:`passthrough`,rule:null,reason:`bare pnpm exec`}:J(e.join(` `),{...n,depth:n.depth+1})}let u;if(a===`run`){let e=r[o+1];if(!e||e.startsWith(`-`))return{action:`passthrough`,rule:null,reason:`pnpm run without script name`};u=e}else if(!i.has(a))u=a;else{for(let r of t)if(r.match.test(`pnpm`)&&(!r.when||r.when(e,n)))return{action:`allow`,rule:r.name,reason:null};return{action:`passthrough`,rule:null,reason:null}}if(s)return it(u,n);if(c){let e=qe(n.cwd);return e?X(u,{...n,cwd:e}):{action:`passthrough`,rule:null,reason:`workspace root not found`}}if(l){let e=d.resolve(n.cwd,l);return X(u,{...n,cwd:e})}return X(u,n)}function X(e,t){let n=G(e,t.cwd);if(!n)return{action:`passthrough`,rule:null,reason:`script resolution failed`};let r=Y(n,{...t,depth:t.depth+1});return r===`allow`?{action:`allow`,rule:`pnpm-script:${e}`,reason:null}:r}function it(e,t){let n=Ke(e,t.cwd);if(!n||n.length===0)return{action:`passthrough`,rule:null,reason:`pnpm recursive`};for(let e of n){let n=Y(e,{...t,depth:t.depth+1,cwd:e.pkgDir??t.cwd});if(n!==`allow`)return n}return{action:`allow`,rule:`pnpm-recursive:${e}`,reason:null}}function at(e){for(let n of t)if(n.match.test(`npm`)&&(!n.when||n.when(e,{cwd:``,depth:0})))return{action:`allow`,rule:n.name,reason:null};return{action:`deny`,rule:`npm-redirect`,reason:r(e)}}function ot(e,t,n,r){let a=t[n],o,s;if(a.startsWith(`--filter=`))o=a.slice(9),s=n+1;else{if(o=t[n+1],!o||o.startsWith(`-`))return{action:`passthrough`,rule:null,reason:`pnpm --filter without package`};s=n+2}if(!o)return{action:`passthrough`,rule:null,reason:`pnpm --filter without package`};let c;for(let e=s;e<t.length;e++){let n=t[e];if(!(n.startsWith(`-`)&&!i.has(n))){c=n;break}}if(!c)return{action:`passthrough`,rule:null,reason:`pnpm --filter without subcommand`};if(c===`install`||c===`i`)return t.slice(t.indexOf(c)+1).every(e=>e.startsWith(`-`))?{action:`allow`,rule:`pnpm`,reason:null}:{action:`passthrough`,rule:null,reason:`pnpm --filter install with package arg`};if(c===`dlx`)return{action:`passthrough`,rule:null,reason:`pnpm dlx`};if(c===`add`)return{action:`passthrough`,rule:null,reason:`pnpm add`};if(new Set([`list`,`ls`,`ll`,`la`,`why`,`view`,`info`,`show`,`outdated`,`licenses`,`audit`]).has(c))return{action:`allow`,rule:`pnpm`,reason:null};if(c===`exec`){let e=t.indexOf(`exec`,s),n=t.slice(e+1);return n.length===0?{action:`passthrough`,rule:null,reason:`bare pnpm exec`}:J(n.join(` `),{...r,depth:r.depth+1})}let l=c===`run`?t[t.indexOf(`run`,s)+1]:c;if(!l||l.startsWith(`-`))return{action:`passthrough`,rule:null,reason:`pnpm --filter run without script name`};if(i.has(l)&&l!==`run`)return{action:`passthrough`,rule:null,reason:null};let u=Ge(l,o,r.cwd);if(!u)return{action:`passthrough`,rule:null,reason:`filtered script resolution failed`};let d=Y(u,{...r,depth:r.depth+1,cwd:u.pkgDir??r.cwd});return d===`allow`?{action:`allow`,rule:`pnpm-filter:${o}:${l}`,reason:null}:d}const st=new Set([`-i`,`--interactive`,`-l`,`--login`,`--init-file`,`--rcfile`,`--norc`,`--noprofile`,`-s`,`--stdin`]);function ct(e,t){let n=e.indexOf(`-c`);if(n===-1)return{action:`passthrough`,rule:null,reason:`shell without -c`};for(let t=1;t<e.length;t++){if(t===n||t===n+1)continue;let r=e[t];if(r.startsWith(`-`)||st.has(r))return{action:`passthrough`,rule:null,reason:`shell -c with extra flags`}}let r=e[n+1];return r?e.length>n+2?{action:`passthrough`,rule:null,reason:`shell -c with positional args`}:n===1?J(r,{...t,depth:t.depth+1}):{action:`passthrough`,rule:null,reason:`shell -c with extra flags`}:{action:`passthrough`,rule:null,reason:`shell -c without command`}}const lt=new Set([`Read`,`Write`,`Edit`]),ut=new Set([`Glob`,`Grep`]);function dt(e,t,n){return lt.has(e)?Ie(t)?.file_path??null:ut.has(e)?Le(t)?.path??n:null}function ft(e,t,r){let i=dt(e,t,r.cwd);if(i===null)return{action:`passthrough`,rule:null,reason:`unknown tool input shape`};for(let t of n)if(t.tools.has(e)&&t.when(i,r))return{action:`deny`,rule:t.name,reason:t.reason??null};for(let t of a)if(t.tools.has(e)&&t.when(i,r))return{action:`allow`,rule:t.name,reason:null};return{action:`passthrough`,rule:null,reason:`no file rule matched`}}const Z=await je();Z.hook_event_name!==`PreToolUse`&&process.exit(0),new Set([`Bash`,`Read`,`Write`,`Edit`,`Glob`,`Grep`]).has(Z.tool_name)||process.exit(0);let Q,$;if(Z.tool_name===`Bash`){let e=Fe(Z.tool_input);e||process.exit(0),Q=J(e.command,{cwd:Z.cwd,depth:0}),$=e.command}else{let e=process.env.CLAUDE_PROJECT_DIR??Z.cwd;Q=ft(Z.tool_name,Z.tool_input,{cwd:e});let t=String(Z.tool_input.file_path??Z.tool_input.path??``);$=`${Z.tool_name} ${t}`}Ve({sessionId:Z.session_id,cwd:Z.cwd,toolName:Z.tool_name,command:$,decision:Q.action,rule:Q.rule,reason:Q.reason}),Q.action===`allow`?V(`allow`):Q.action===`deny`&&V(`deny`,Q.reason);export{};", "bst-hook.mjs"), writeIfChanged(ctx, GUIDE_PATH, "# bst-hook Permission Guide\n\nThis project uses a PreToolUse hook (`bst-hook`) that evaluates Bash commands\nand file tool operations before execution. Commands fall into three tiers:\n\n- **Denied** — blocked with a redirect message\n- **Allowed** — auto-approved, no prompt\n- **Passthrough** — falls through to Claude Code's normal permission prompt\n\n## Denied commands\n\nThese are blocked. The hook tells you what to do instead.\n\n### Bash\n\n- **rm-recursive**: Don't use recursive `rm`. Use more targeted deletes, or remove specific files/directories.\n- **sudo**: Don't use sudo. If you need elevated permissions, ask me to do it manually.\n- **git-force-push**: Use `git push --force-with-lease` instead of `--force`.\n- **git-reset-hard**: Don't `reset --hard` on main. Create a branch first.\n- **git-write**: Git write operations (push, commit, reset, merge, etc.) are not allowed. Ask the user to run these manually.\n- **chmod-777**: Don't use 777 permissions. Use more restrictive permissions.\n- **env-file-read**: Don't read .env files. These contain secrets that should not appear in the conversation.\n- **npx-redirect**: This project uses pnpm. Use `pnpm dlx <pkg>` or `pnpm exec <cmd>` instead of npx.\n\n### File tools (Read, Write, Edit, Glob, Grep)\n\n- **env-file-read**: Don't read .env files. These contain secrets that should not appear in the conversation.\n- **env-file-write**: Don't write to .env files. These contain secrets.\n- **outside-cwd-write**: Don't write files outside the project directory.\n\n## Auto-approved commands\n\nThese run without prompting.\n\n### Bash\n\n- **Test runners**: vitest, jest\n- **Type checking**: tsc\n- **Build tools**: tsdown\n- **Linters & formatters**: oxlint, oxfmt, eslint, prettier, biome, knip\n- **Read-only commands**: cat, head, tail, grep, ls, wc, uniq, diff, echo, pwd, which, dirname, basename, realpath\n- **Package managers (read-only)**: npm (view, info, show only)\n- **Shell builtins**: test, bracket-test\n- **Navigation**: cd, true, colon\n- **Conditional commands**: find (without -exec, -delete), sort (without -o / --output)\n- **Git read operations**: git (status, log, diff, show, blame, branch, remote, fetch, rev-parse, etc.)\n- **Git safe writes**: git-safe-write (add, switch -c, checkout -b, stash push/pop/apply/show)\n- **pnpm (safe built-ins)**: pnpm (list, why, view, info, show, outdated, install (bare only))\n- **File operations (within project)**: cp (paths must be within project directory), mkdir (paths must be within project directory), touch (paths must be within project directory)\n\n### File tools\n\n- **Read/Glob/Grep**: Allowed within project directory\n- **Write/Edit**: Allowed within project directory\n\n## Passthrough\n\nEverything not listed above triggers Claude Code's normal permission prompt.\nCommon examples:\n\n- `pnpm add <pkg>`, `pnpm dlx <pkg>` (dependency changes)\n- `mv` (file moves)\n- `node`, `npx` scripts\n- Commands with output redirection (`> file`)\n- Any unrecognized command\n\n## How commands are evaluated\n\n- **Pipelines and chains**: every segment must be allowed; any deny blocks the whole command.\n- **pnpm scripts**: `pnpm <script>` resolves against `package.json` (including pre/post hooks and `--filter` workspaces) and evaluates the resolved command recursively.\n- **cd propagation**: `cd dir && cmd` evaluates `cmd` relative to the new directory.\n- **Audit log**: all decisions are logged to `.claude/hooks/bst-hook.audit.local.jsonl`.\n", "bst-hook-guide.md")];
2477
+ }
2475
2478
  //#endregion
2476
2479
  //#region src/generators/claude-settings.ts
2477
2480
  const HookEntrySchema = z.object({
@@ -2532,7 +2535,8 @@ function buildSettings(ctx) {
2532
2535
  "Use pnpm, not npm/yarn/npx. Run binaries with `pnpm exec`.",
2533
2536
  "No typecasts (as/any). Use zod schemas, type guards, or narrowing instead.",
2534
2537
  "Fix lint violations instead of suppressing them. Only add disable comments when suppression is genuinely the best option. For no-empty-function: add a `{ /* no-op */ }` comment body instead of a disable comment.",
2535
- "Prefer extensionless imports; if an extension is required, use .ts over .js."
2538
+ "Prefer extensionless imports; if an extension is required, use .ts over .js.",
2539
+ "The bst-hook manages Bash/file permissions. See .claude/hooks/bst-hook-guide.md for auto-approved, denied, and passthrough commands."
2536
2540
  ],
2537
2541
  enabledPlugins,
2538
2542
  extraKnownMarketplaces
@@ -3243,7 +3247,7 @@ async function runGenerators(ctx) {
3243
3247
  results.push(await generateKnip(ctx));
3244
3248
  results.push(await generateRenovate(ctx));
3245
3249
  results.push(await generateCi(ctx));
3246
- results.push(await generateClaudeHooks(ctx));
3250
+ results.push(...await generateClaudeHooks(ctx));
3247
3251
  results.push(...await generateClaudeSettings(ctx));
3248
3252
  results.push(await generateReleaseIt(ctx));
3249
3253
  results.push(await generateVersionrc(ctx));
@@ -3264,7 +3268,7 @@ async function runGenerators(ctx) {
3264
3268
  function generateMigratePrompt(results, config, detected) {
3265
3269
  const sections = [];
3266
3270
  const timestamp = (/* @__PURE__ */ new Date()).toISOString();
3267
- sections.push(`# Migration Prompt\n\n_Generated by \`@bensandee/tooling@0.40.7 repo:sync\` on ${timestamp}_\n`);
3271
+ sections.push(`# Migration Prompt\n\n_Generated by \`@bensandee/tooling@0.41.1 repo:sync\` on ${timestamp}_\n`);
3268
3272
  const changed = results.filter((r) => r.action === "created" || r.action === "updated" || r.action === "archived");
3269
3273
  if (changed.length > 0) {
3270
3274
  const items = changed.map((r) => {
@@ -3887,6 +3891,103 @@ async function ensureRelease(executor, conn, tag) {
3887
3891
  }
3888
3892
  throw new TransientError(`Failed to create release for ${tag} after ${String(RETRY_ATTEMPTS)} attempts`);
3889
3893
  }
3894
+ const ActionSecretListSchema = z.object({
3895
+ secrets: z.array(z.object({ name: z.string() })),
3896
+ total_count: z.number()
3897
+ });
3898
+ const AccessTokenResponseSchema = z.object({ sha1: z.string() });
3899
+ /**
3900
+ * Create a Forgejo access token via Basic auth.
3901
+ *
3902
+ * Returns the token value on success. Throws a `TransientError` with status 422
3903
+ * if a token with the same name already exists (caller should handle this).
3904
+ */
3905
+ async function createAccessToken(executor, serverUrl, username, password, tokenName, scopes) {
3906
+ const url = `${serverUrl}/api/v1/users/${encodeURIComponent(username)}/tokens`;
3907
+ const credentials = btoa(`${username}:${password}`);
3908
+ const res = await executor.fetch(url, {
3909
+ method: "POST",
3910
+ headers: {
3911
+ Authorization: `Basic ${credentials}`,
3912
+ "Content-Type": "application/json"
3913
+ },
3914
+ body: JSON.stringify({
3915
+ name: tokenName,
3916
+ scopes
3917
+ })
3918
+ });
3919
+ if (!res.ok) {
3920
+ const body = await responseBodyText(res);
3921
+ throw new TransientError(`Failed to create access token: ${String(res.status)} ${res.statusText}\n${body}`);
3922
+ }
3923
+ const parsed = AccessTokenResponseSchema.safeParse(await res.json());
3924
+ if (!parsed.success) throw new UnexpectedError(`Unexpected token response: ${parsed.error.message}`);
3925
+ return parsed.data.sha1;
3926
+ }
3927
+ /**
3928
+ * Set (or overwrite) a Forgejo Actions secret on a repository.
3929
+ *
3930
+ * Uses PUT which is idempotent — creates or overwrites.
3931
+ */
3932
+ async function setActionSecret(executor, conn, secretName, secretValue) {
3933
+ const [owner, repo] = conn.repository.split("/");
3934
+ const url = `${conn.serverUrl}/api/v1/repos/${owner}/${repo}/actions/secrets/${encodeURIComponent(secretName)}`;
3935
+ const res = await executor.fetch(url, {
3936
+ method: "PUT",
3937
+ headers: {
3938
+ Authorization: `token ${conn.token}`,
3939
+ "Content-Type": "application/json"
3940
+ },
3941
+ body: JSON.stringify({ data: secretValue })
3942
+ });
3943
+ if (!res.ok) {
3944
+ const body = await responseBodyText(res);
3945
+ throw new TransientError(`Failed to set secret ${secretName}: ${String(res.status)} ${res.statusText}\n${body}`);
3946
+ }
3947
+ }
3948
+ /**
3949
+ * List Forgejo Actions secret names for a repository.
3950
+ *
3951
+ * Returns only names — Forgejo never exposes secret values.
3952
+ * Paginates automatically to collect all secrets.
3953
+ */
3954
+ async function listActionSecrets(executor, conn) {
3955
+ const [owner, repo] = conn.repository.split("/");
3956
+ const names = [];
3957
+ let page = 1;
3958
+ const limit = 50;
3959
+ for (;;) {
3960
+ const url = `${conn.serverUrl}/api/v1/repos/${owner}/${repo}/actions/secrets?page=${String(page)}&limit=${String(limit)}`;
3961
+ const res = await executor.fetch(url, { headers: { Authorization: `token ${conn.token}` } });
3962
+ if (!res.ok) {
3963
+ const body = await responseBodyText(res);
3964
+ throw new TransientError(`Failed to list secrets: ${String(res.status)} ${res.statusText}\n${body}`);
3965
+ }
3966
+ const parsed = ActionSecretListSchema.safeParse(await res.json());
3967
+ if (!parsed.success) throw new UnexpectedError(`Unexpected secrets list response: ${parsed.error.message}`);
3968
+ for (const secret of parsed.data.secrets) names.push(secret.name);
3969
+ if (names.length >= parsed.data.total_count) break;
3970
+ page++;
3971
+ }
3972
+ return names;
3973
+ }
3974
+ /**
3975
+ * Delete a Forgejo Actions secret from a repository.
3976
+ *
3977
+ * Returns silently on success. Throws on failure (including 404 if the secret doesn't exist).
3978
+ */
3979
+ async function deleteActionSecret(executor, conn, secretName) {
3980
+ const [owner, repo] = conn.repository.split("/");
3981
+ const url = `${conn.serverUrl}/api/v1/repos/${owner}/${repo}/actions/secrets/${encodeURIComponent(secretName)}`;
3982
+ const res = await executor.fetch(url, {
3983
+ method: "DELETE",
3984
+ headers: { Authorization: `token ${conn.token}` }
3985
+ });
3986
+ if (!res.ok) {
3987
+ const body = await responseBodyText(res);
3988
+ throw new TransientError(`Failed to delete secret ${secretName}: ${String(res.status)} ${res.statusText}\n${body}`);
3989
+ }
3990
+ }
3890
3991
  //#endregion
3891
3992
  //#region src/release/version.ts
3892
3993
  const BRANCH = "changeset-release/main";
@@ -5396,11 +5497,266 @@ const hooksAuditCommand = defineCommand({
5396
5497
  }
5397
5498
  });
5398
5499
  //#endregion
5500
+ //#region src/commands/setup-secrets.ts
5501
+ function isCancelled(value) {
5502
+ return p.isCancel(value);
5503
+ }
5504
+ const TOKEN_SCOPES = [
5505
+ "write:organization",
5506
+ "write:package",
5507
+ "write:repository"
5508
+ ];
5509
+ /**
5510
+ * Core logic for setup:secrets, separated from the command handler for testability.
5511
+ */
5512
+ async function runSetupSecrets(executor, config) {
5513
+ const repoName = config.repository.split("/")[1] ?? config.repository;
5514
+ const tokenName = `bst-release-${repoName}`;
5515
+ const secretsSet = [];
5516
+ let token;
5517
+ if (config.dryRun) {
5518
+ log.info(`[dry-run] Would create access token "${tokenName}" for ${config.username}`);
5519
+ log.info(`[dry-run] Scopes: ${TOKEN_SCOPES.join(", ")}`);
5520
+ token = "dry-run-token";
5521
+ } else {
5522
+ log.info(`Creating access token "${tokenName}"...`);
5523
+ try {
5524
+ token = await createAccessToken(executor, config.serverUrl, config.username, config.password, tokenName, TOKEN_SCOPES);
5525
+ log.success(`Created access token "${tokenName}"`);
5526
+ } catch (error) {
5527
+ if (error instanceof Error && error.message.includes("422")) throw new FatalError(`Access token "${tokenName}" already exists. Delete it in Forgejo settings and re-run, or set secrets manually.`);
5528
+ throw error;
5529
+ }
5530
+ }
5531
+ const conn = {
5532
+ serverUrl: config.serverUrl,
5533
+ repository: config.repository,
5534
+ token
5535
+ };
5536
+ if (config.dryRun) log.info(`[dry-run] Would set secret RELEASE_TOKEN on ${config.repository}`);
5537
+ else {
5538
+ log.info("Setting RELEASE_TOKEN secret...");
5539
+ await setActionSecret(executor, conn, "RELEASE_TOKEN", token);
5540
+ log.success("Set RELEASE_TOKEN");
5541
+ }
5542
+ secretsSet.push("RELEASE_TOKEN");
5543
+ if (!config.noDocker) {
5544
+ const rootPkgRaw = executor.readFile(`${config.cwd}/package.json`);
5545
+ const rootName = (rootPkgRaw ? parsePackageJson(rootPkgRaw) : void 0)?.name ?? repoName;
5546
+ const dockerPackages = detectDockerPackages(executor, config.cwd, rootName);
5547
+ if (dockerPackages.length > 0) {
5548
+ log.info(`Detected ${String(dockerPackages.length)} Docker package(s) — setting Docker secrets`);
5549
+ if (config.dryRun) {
5550
+ log.info(`[dry-run] Would set secret DOCKER_USERNAME on ${config.repository}`);
5551
+ log.info(`[dry-run] Would set secret DOCKER_PASSWORD on ${config.repository}`);
5552
+ } else {
5553
+ await setActionSecret(executor, conn, "DOCKER_USERNAME", config.username);
5554
+ log.success("Set DOCKER_USERNAME");
5555
+ await setActionSecret(executor, conn, "DOCKER_PASSWORD", token);
5556
+ log.success("Set DOCKER_PASSWORD");
5557
+ }
5558
+ secretsSet.push("DOCKER_USERNAME", "DOCKER_PASSWORD");
5559
+ }
5560
+ }
5561
+ return {
5562
+ tokenCreated: !config.dryRun,
5563
+ secretsSet
5564
+ };
5565
+ }
5566
+ const setupSecretsCommand = defineCommand({
5567
+ meta: {
5568
+ name: "setup:secrets",
5569
+ description: "Create a Forgejo access token and configure CI secrets for this repository"
5570
+ },
5571
+ args: {
5572
+ "dry-run": {
5573
+ type: "boolean",
5574
+ description: "Show what would be created without making API calls"
5575
+ },
5576
+ "no-docker": {
5577
+ type: "boolean",
5578
+ description: "Skip Docker secrets setup even if Docker packages are detected"
5579
+ },
5580
+ verbose: {
5581
+ type: "boolean",
5582
+ description: "Enable verbose output"
5583
+ }
5584
+ },
5585
+ async run({ args }) {
5586
+ const cwd = process.cwd();
5587
+ const verbose = args.verbose === true || isEnvVerbose();
5588
+ const dryRun = args["dry-run"] === true;
5589
+ const noDocker = args["no-docker"] === true;
5590
+ p.intro("setup:secrets");
5591
+ const parsed = parseRepositoryUrl(cwd);
5592
+ if (!parsed) throw new FatalError("No repository URL found in package.json. Add a `repository` field pointing to your Forgejo instance.");
5593
+ if (parsed.hostname === "github.com") throw new FatalError("setup:secrets is for Forgejo repositories. GitHub uses different auth.");
5594
+ const serverUrl = `${parsed.protocol}//${parsed.hostname}`;
5595
+ const repository = parsed.repository;
5596
+ log.info(`Forgejo: ${serverUrl} / ${repository}`);
5597
+ const username = await p.text({
5598
+ message: "Forgejo username",
5599
+ validate: (v) => !v || v.length === 0 ? "Username is required" : void 0
5600
+ });
5601
+ if (isCancelled(username)) {
5602
+ p.cancel("Cancelled.");
5603
+ process.exit(0);
5604
+ }
5605
+ const password = await p.password({
5606
+ message: "Forgejo password",
5607
+ validate: (v) => !v || v.length === 0 ? "Password is required" : void 0
5608
+ });
5609
+ if (isCancelled(password)) {
5610
+ p.cancel("Cancelled.");
5611
+ process.exit(0);
5612
+ }
5613
+ const summary = (await runSetupSecrets(createRealExecutor(), {
5614
+ serverUrl,
5615
+ repository,
5616
+ username,
5617
+ password,
5618
+ cwd,
5619
+ dryRun,
5620
+ noDocker,
5621
+ verbose
5622
+ })).secretsSet.map((s) => ` - ${s}`).join("\n");
5623
+ p.outro(`Done! Secrets ${dryRun ? "that would be" : ""} configured:\n${summary}`);
5624
+ }
5625
+ });
5626
+ //#endregion
5627
+ //#region src/commands/forgejo-secrets.ts
5628
+ function requireForgejo(cwd) {
5629
+ const resolved = resolveConnection(cwd);
5630
+ if (resolved.type !== "forgejo") throw new FatalError("forgejo:secrets requires a Forgejo repository");
5631
+ return resolved.conn;
5632
+ }
5633
+ /** Read secret value from --body flag or stdin. */
5634
+ function readSecretValue(body) {
5635
+ if (body) return body;
5636
+ try {
5637
+ const value = readFileSync("/dev/stdin", "utf-8").trim();
5638
+ if (value.length === 0) throw new FatalError("No secret value provided. Use --body or pipe a value via stdin.");
5639
+ return value;
5640
+ } catch (error) {
5641
+ if (error instanceof FatalError) throw error;
5642
+ throw new FatalError("No secret value provided. Use --body or pipe a value via stdin.");
5643
+ }
5644
+ }
5645
+ async function runSecretsSet(executor, config) {
5646
+ if (config.dryRun) {
5647
+ log.info(`[dry-run] Would set secret ${config.secretName} on ${config.conn.repository}`);
5648
+ return;
5649
+ }
5650
+ await setActionSecret(executor, config.conn, config.secretName, config.secretValue);
5651
+ log.success(`Set secret ${config.secretName}`);
5652
+ }
5653
+ async function runSecretsList(executor, config) {
5654
+ const names = await listActionSecrets(executor, config.conn);
5655
+ if (names.length === 0) log.info("No secrets found");
5656
+ else for (const name of names) log.info(name);
5657
+ return names;
5658
+ }
5659
+ async function runSecretsDelete(executor, config) {
5660
+ if (config.dryRun) {
5661
+ log.info(`[dry-run] Would delete secret ${config.secretName} from ${config.conn.repository}`);
5662
+ return;
5663
+ }
5664
+ await deleteActionSecret(executor, config.conn, config.secretName);
5665
+ log.success(`Deleted secret ${config.secretName}`);
5666
+ }
5667
+ const forgejoSecretsCommand = defineCommand({
5668
+ meta: {
5669
+ name: "forgejo:secrets",
5670
+ description: "Manage Forgejo Actions secrets for the current repository"
5671
+ },
5672
+ subCommands: {
5673
+ set: defineCommand({
5674
+ meta: {
5675
+ name: "set",
5676
+ description: "Set a repository secret (reads value from --body or stdin)"
5677
+ },
5678
+ args: {
5679
+ name: {
5680
+ type: "positional",
5681
+ description: "Secret name",
5682
+ required: true
5683
+ },
5684
+ body: {
5685
+ type: "string",
5686
+ description: "Secret value (reads from stdin if omitted)"
5687
+ },
5688
+ "dry-run": {
5689
+ type: "boolean",
5690
+ description: "Show what would be done without making API calls"
5691
+ },
5692
+ verbose: {
5693
+ type: "boolean",
5694
+ description: "Enable verbose output"
5695
+ }
5696
+ },
5697
+ async run({ args }) {
5698
+ const conn = requireForgejo(process.cwd());
5699
+ const executor = createRealExecutor();
5700
+ const secretValue = readSecretValue(args.body);
5701
+ await runSecretsSet(executor, {
5702
+ conn,
5703
+ secretName: args.name,
5704
+ secretValue,
5705
+ dryRun: args["dry-run"] === true
5706
+ });
5707
+ }
5708
+ }),
5709
+ list: defineCommand({
5710
+ meta: {
5711
+ name: "list",
5712
+ description: "List repository secret names"
5713
+ },
5714
+ args: { verbose: {
5715
+ type: "boolean",
5716
+ description: "Enable verbose output"
5717
+ } },
5718
+ async run() {
5719
+ const conn = requireForgejo(process.cwd());
5720
+ await runSecretsList(createRealExecutor(), { conn });
5721
+ }
5722
+ }),
5723
+ delete: defineCommand({
5724
+ meta: {
5725
+ name: "delete",
5726
+ description: "Delete a repository secret"
5727
+ },
5728
+ args: {
5729
+ name: {
5730
+ type: "positional",
5731
+ description: "Secret name to delete",
5732
+ required: true
5733
+ },
5734
+ "dry-run": {
5735
+ type: "boolean",
5736
+ description: "Show what would be done without making API calls"
5737
+ },
5738
+ verbose: {
5739
+ type: "boolean",
5740
+ description: "Enable verbose output"
5741
+ }
5742
+ },
5743
+ async run({ args }) {
5744
+ const conn = requireForgejo(process.cwd());
5745
+ await runSecretsDelete(createRealExecutor(), {
5746
+ conn,
5747
+ secretName: args.name,
5748
+ dryRun: args["dry-run"] === true
5749
+ });
5750
+ }
5751
+ })
5752
+ }
5753
+ });
5754
+ //#endregion
5399
5755
  //#region src/bin.ts
5400
5756
  const main = defineCommand({
5401
5757
  meta: {
5402
5758
  name: "bst",
5403
- version: "0.40.7",
5759
+ version: "0.41.1",
5404
5760
  description: "Bootstrap and maintain standardized TypeScript project tooling"
5405
5761
  },
5406
5762
  subCommands: {
@@ -5414,10 +5770,12 @@ const main = defineCommand({
5414
5770
  "docker:publish": publishDockerCommand,
5415
5771
  "docker:build": dockerBuildCommand,
5416
5772
  "docker:check": dockerCheckCommand,
5417
- "hooks:audit": hooksAuditCommand
5773
+ "hooks:audit": hooksAuditCommand,
5774
+ "setup:secrets": setupSecretsCommand,
5775
+ "forgejo:secrets": forgejoSecretsCommand
5418
5776
  }
5419
5777
  });
5420
- console.log(`@bensandee/tooling v0.40.7`);
5778
+ console.log(`@bensandee/tooling v0.41.1`);
5421
5779
  async function run() {
5422
5780
  await runMain(main);
5423
5781
  process.exit(process.exitCode ?? 0);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bensandee/tooling",
3
- "version": "0.40.7",
3
+ "version": "0.41.1",
4
4
  "description": "CLI tool to bootstrap and maintain standardized TypeScript project tooling",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -40,8 +40,8 @@
40
40
  "citty": "^0.2.1",
41
41
  "json5": "^2.2.3",
42
42
  "jsonc-parser": "^3.3.1",
43
- "picomatch": "^4.0.3",
44
- "yaml": "^2.8.2",
43
+ "picomatch": "^4.0.4",
44
+ "yaml": "^2.8.3",
45
45
  "zod": "^4.3.6",
46
46
  "@bensandee/common": "0.1.2"
47
47
  },
@@ -53,9 +53,9 @@
53
53
  "commit-and-tag-version": "12.7.1",
54
54
  "prettier": "3.8.1",
55
55
  "release-it": "19.2.4",
56
- "tsdown": "0.21.4",
57
- "@bensandee/config": "0.10.0",
58
- "@bensandee/claude-hooks": "0.4.1"
56
+ "tsdown": "0.21.6",
57
+ "@bensandee/claude-hooks": "0.5.0",
58
+ "@bensandee/config": "0.10.1"
59
59
  },
60
60
  "scripts": {
61
61
  "build": "tsdown",