@bensandee/tooling 0.40.2 → 0.40.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bin.mjs +59 -91
- package/package.json +3 -10
package/dist/bin.mjs
CHANGED
|
@@ -1332,8 +1332,8 @@ const PER_PACKAGE_DEV_DEPS = {
|
|
|
1332
1332
|
"release-it": "19.2.4",
|
|
1333
1333
|
"tsdown": "0.21.4",
|
|
1334
1334
|
"typescript": "5.9.3",
|
|
1335
|
-
"vitest": "4.1.
|
|
1336
|
-
"pnpm": "10.
|
|
1335
|
+
"vitest": "^4.1.1",
|
|
1336
|
+
"pnpm": "10.33.0"
|
|
1337
1337
|
}["@types/node"],
|
|
1338
1338
|
tsdown: {
|
|
1339
1339
|
"@changesets/cli": "2.30.0",
|
|
@@ -1348,8 +1348,8 @@ const PER_PACKAGE_DEV_DEPS = {
|
|
|
1348
1348
|
"release-it": "19.2.4",
|
|
1349
1349
|
"tsdown": "0.21.4",
|
|
1350
1350
|
"typescript": "5.9.3",
|
|
1351
|
-
"vitest": "4.1.
|
|
1352
|
-
"pnpm": "10.
|
|
1351
|
+
"vitest": "^4.1.1",
|
|
1352
|
+
"pnpm": "10.33.0"
|
|
1353
1353
|
}["tsdown"],
|
|
1354
1354
|
typescript: {
|
|
1355
1355
|
"@changesets/cli": "2.30.0",
|
|
@@ -1364,8 +1364,8 @@ const PER_PACKAGE_DEV_DEPS = {
|
|
|
1364
1364
|
"release-it": "19.2.4",
|
|
1365
1365
|
"tsdown": "0.21.4",
|
|
1366
1366
|
"typescript": "5.9.3",
|
|
1367
|
-
"vitest": "4.1.
|
|
1368
|
-
"pnpm": "10.
|
|
1367
|
+
"vitest": "^4.1.1",
|
|
1368
|
+
"pnpm": "10.33.0"
|
|
1369
1369
|
}["typescript"],
|
|
1370
1370
|
vitest: {
|
|
1371
1371
|
"@changesets/cli": "2.30.0",
|
|
@@ -1380,8 +1380,8 @@ const PER_PACKAGE_DEV_DEPS = {
|
|
|
1380
1380
|
"release-it": "19.2.4",
|
|
1381
1381
|
"tsdown": "0.21.4",
|
|
1382
1382
|
"typescript": "5.9.3",
|
|
1383
|
-
"vitest": "4.1.
|
|
1384
|
-
"pnpm": "10.
|
|
1383
|
+
"vitest": "^4.1.1",
|
|
1384
|
+
"pnpm": "10.33.0"
|
|
1385
1385
|
}["vitest"]
|
|
1386
1386
|
};
|
|
1387
1387
|
/** DevDeps that belong at the root regardless of structure. */
|
|
@@ -1399,8 +1399,8 @@ const ROOT_DEV_DEPS = {
|
|
|
1399
1399
|
"release-it": "19.2.4",
|
|
1400
1400
|
"tsdown": "0.21.4",
|
|
1401
1401
|
"typescript": "5.9.3",
|
|
1402
|
-
"vitest": "4.1.
|
|
1403
|
-
"pnpm": "10.
|
|
1402
|
+
"vitest": "^4.1.1",
|
|
1403
|
+
"pnpm": "10.33.0"
|
|
1404
1404
|
}["knip"],
|
|
1405
1405
|
lefthook: {
|
|
1406
1406
|
"@changesets/cli": "2.30.0",
|
|
@@ -1415,8 +1415,8 @@ const ROOT_DEV_DEPS = {
|
|
|
1415
1415
|
"release-it": "19.2.4",
|
|
1416
1416
|
"tsdown": "0.21.4",
|
|
1417
1417
|
"typescript": "5.9.3",
|
|
1418
|
-
"vitest": "4.1.
|
|
1419
|
-
"pnpm": "10.
|
|
1418
|
+
"vitest": "^4.1.1",
|
|
1419
|
+
"pnpm": "10.33.0"
|
|
1420
1420
|
}["lefthook"],
|
|
1421
1421
|
oxlint: {
|
|
1422
1422
|
"@changesets/cli": "2.30.0",
|
|
@@ -1431,8 +1431,8 @@ const ROOT_DEV_DEPS = {
|
|
|
1431
1431
|
"release-it": "19.2.4",
|
|
1432
1432
|
"tsdown": "0.21.4",
|
|
1433
1433
|
"typescript": "5.9.3",
|
|
1434
|
-
"vitest": "4.1.
|
|
1435
|
-
"pnpm": "10.
|
|
1434
|
+
"vitest": "^4.1.1",
|
|
1435
|
+
"pnpm": "10.33.0"
|
|
1436
1436
|
}["oxlint"]
|
|
1437
1437
|
};
|
|
1438
1438
|
/**
|
|
@@ -1472,8 +1472,8 @@ function addReleaseDeps(deps, config) {
|
|
|
1472
1472
|
"release-it": "19.2.4",
|
|
1473
1473
|
"tsdown": "0.21.4",
|
|
1474
1474
|
"typescript": "5.9.3",
|
|
1475
|
-
"vitest": "4.1.
|
|
1476
|
-
"pnpm": "10.
|
|
1475
|
+
"vitest": "^4.1.1",
|
|
1476
|
+
"pnpm": "10.33.0"
|
|
1477
1477
|
}["release-it"];
|
|
1478
1478
|
if (config.structure === "monorepo") deps["@release-it/bumper"] = {
|
|
1479
1479
|
"@changesets/cli": "2.30.0",
|
|
@@ -1488,8 +1488,8 @@ function addReleaseDeps(deps, config) {
|
|
|
1488
1488
|
"release-it": "19.2.4",
|
|
1489
1489
|
"tsdown": "0.21.4",
|
|
1490
1490
|
"typescript": "5.9.3",
|
|
1491
|
-
"vitest": "4.1.
|
|
1492
|
-
"pnpm": "10.
|
|
1491
|
+
"vitest": "^4.1.1",
|
|
1492
|
+
"pnpm": "10.33.0"
|
|
1493
1493
|
}["@release-it/bumper"];
|
|
1494
1494
|
break;
|
|
1495
1495
|
case "simple":
|
|
@@ -1506,8 +1506,8 @@ function addReleaseDeps(deps, config) {
|
|
|
1506
1506
|
"release-it": "19.2.4",
|
|
1507
1507
|
"tsdown": "0.21.4",
|
|
1508
1508
|
"typescript": "5.9.3",
|
|
1509
|
-
"vitest": "4.1.
|
|
1510
|
-
"pnpm": "10.
|
|
1509
|
+
"vitest": "^4.1.1",
|
|
1510
|
+
"pnpm": "10.33.0"
|
|
1511
1511
|
}["commit-and-tag-version"];
|
|
1512
1512
|
break;
|
|
1513
1513
|
case "changesets":
|
|
@@ -1524,8 +1524,8 @@ function addReleaseDeps(deps, config) {
|
|
|
1524
1524
|
"release-it": "19.2.4",
|
|
1525
1525
|
"tsdown": "0.21.4",
|
|
1526
1526
|
"typescript": "5.9.3",
|
|
1527
|
-
"vitest": "4.1.
|
|
1528
|
-
"pnpm": "10.
|
|
1527
|
+
"vitest": "^4.1.1",
|
|
1528
|
+
"pnpm": "10.33.0"
|
|
1529
1529
|
}["@changesets/cli"];
|
|
1530
1530
|
break;
|
|
1531
1531
|
}
|
|
@@ -1549,7 +1549,7 @@ async function generatePackageJson(ctx) {
|
|
|
1549
1549
|
const devDeps = { ...ROOT_DEV_DEPS };
|
|
1550
1550
|
if (!isMonorepo) Object.assign(devDeps, PER_PACKAGE_DEV_DEPS);
|
|
1551
1551
|
devDeps["@bensandee/config"] = isWorkspacePackage(ctx, "@bensandee/config") ? "workspace:*" : "0.10.0";
|
|
1552
|
-
devDeps["@bensandee/tooling"] = isWorkspacePackage(ctx, "@bensandee/tooling") ? "workspace:*" : "0.40.
|
|
1552
|
+
devDeps["@bensandee/tooling"] = isWorkspacePackage(ctx, "@bensandee/tooling") ? "workspace:*" : "0.40.3";
|
|
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",
|
|
@@ -1564,8 +1564,8 @@ async function generatePackageJson(ctx) {
|
|
|
1564
1564
|
"release-it": "19.2.4",
|
|
1565
1565
|
"tsdown": "0.21.4",
|
|
1566
1566
|
"typescript": "5.9.3",
|
|
1567
|
-
"vitest": "4.1.
|
|
1568
|
-
"pnpm": "10.
|
|
1567
|
+
"vitest": "^4.1.1",
|
|
1568
|
+
"pnpm": "10.33.0"
|
|
1569
1569
|
}["oxfmt"];
|
|
1570
1570
|
if (ctx.config.formatter === "prettier") devDeps["prettier"] = {
|
|
1571
1571
|
"@changesets/cli": "2.30.0",
|
|
@@ -1580,8 +1580,8 @@ async function generatePackageJson(ctx) {
|
|
|
1580
1580
|
"release-it": "19.2.4",
|
|
1581
1581
|
"tsdown": "0.21.4",
|
|
1582
1582
|
"typescript": "5.9.3",
|
|
1583
|
-
"vitest": "4.1.
|
|
1584
|
-
"pnpm": "10.
|
|
1583
|
+
"vitest": "^4.1.1",
|
|
1584
|
+
"pnpm": "10.33.0"
|
|
1585
1585
|
}["prettier"];
|
|
1586
1586
|
addReleaseDeps(devDeps, ctx.config);
|
|
1587
1587
|
if (existing) {
|
|
@@ -1664,8 +1664,8 @@ async function generatePackageJson(ctx) {
|
|
|
1664
1664
|
"release-it": "19.2.4",
|
|
1665
1665
|
"tsdown": "0.21.4",
|
|
1666
1666
|
"typescript": "5.9.3",
|
|
1667
|
-
"vitest": "4.1.
|
|
1668
|
-
"pnpm": "10.
|
|
1667
|
+
"vitest": "^4.1.1",
|
|
1668
|
+
"pnpm": "10.33.0"
|
|
1669
1669
|
}["pnpm"]}`
|
|
1670
1670
|
};
|
|
1671
1671
|
ctx.write(filePath, JSON.stringify(pkg, null, 2) + "\n");
|
|
@@ -2391,7 +2391,7 @@ async function generatePnpmWorkspace(ctx) {
|
|
|
2391
2391
|
//#region src/generators/claude-hooks.ts
|
|
2392
2392
|
const HOOK_PATH = ".claude/hooks/bst-hook.mjs";
|
|
2393
2393
|
async function generateClaudeHooks(ctx) {
|
|
2394
|
-
const content = "/**\n * bst-hook — Claude Code PreToolUse hook\n * @bensandee/claude-hooks v0.3.0\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`,`branch`,`remote`,`fetch`,`rev-parse`]),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=a.basename(i[0]);if(c===`command`&&i.length>1)return q(i.slice(1).join(` `),{...t,depth:t.depth+1});if(c===`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(c===`pnpm`)return Et(i,t);if(c===`npm`)return Ot(i);if(c===`bash`||c===`sh`||c===`zsh`)return jt(i,t);if(c===`node`&&(i.includes(`-e`)||i.includes(`-p`)||i.includes(`--eval`)||i.includes(`--print`)))return{action:`passthrough`,rule:null,reason:`node eval`};if(c===`mv`)return{action:`passthrough`,rule:null,reason:`mv`};for(let e of ft)if(e.match.test(c)&&(!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(c)&&(!e.when||e.when(i,t)))return{action:`allow`,rule:e.name,reason:null};return{action:`passthrough`,rule:null,reason:`no rule matched: ${c}`}}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{};";
|
|
2394
|
+
const content = "/* bst-hook not built — run pnpm build from packages/claude-hooks first */";
|
|
2395
2395
|
const existing = ctx.read(HOOK_PATH);
|
|
2396
2396
|
if (existing === content) return {
|
|
2397
2397
|
filePath: HOOK_PATH,
|
|
@@ -2449,61 +2449,18 @@ function buildSettings(ctx) {
|
|
|
2449
2449
|
if (ctx.config.structure !== "monorepo") {
|
|
2450
2450
|
if (ctx.packageJson ? packageHasWebUIDeps(ctx.packageJson) : false) enabledPlugins["frontend-design@claude-plugins-official"] = true;
|
|
2451
2451
|
}
|
|
2452
|
-
const hookCommand = `node "$CLAUDE_PROJECT_DIR/.claude/hooks/bst-hook.mjs"`;
|
|
2453
2452
|
return {
|
|
2454
2453
|
permissions: {
|
|
2455
2454
|
allow,
|
|
2456
|
-
deny: [
|
|
2457
|
-
"Read(.env)",
|
|
2458
|
-
"Read(.env.*)",
|
|
2459
|
-
"Read(*.env)",
|
|
2460
|
-
"Read(*.env.*)"
|
|
2461
|
-
]
|
|
2455
|
+
deny: []
|
|
2462
2456
|
},
|
|
2463
|
-
hooks: { PreToolUse: [
|
|
2464
|
-
|
|
2465
|
-
|
|
2466
|
-
|
|
2467
|
-
|
|
2468
|
-
|
|
2469
|
-
|
|
2470
|
-
},
|
|
2471
|
-
{
|
|
2472
|
-
matcher: "Read",
|
|
2473
|
-
hooks: [{
|
|
2474
|
-
type: "command",
|
|
2475
|
-
command: hookCommand
|
|
2476
|
-
}]
|
|
2477
|
-
},
|
|
2478
|
-
{
|
|
2479
|
-
matcher: "Write",
|
|
2480
|
-
hooks: [{
|
|
2481
|
-
type: "command",
|
|
2482
|
-
command: hookCommand
|
|
2483
|
-
}]
|
|
2484
|
-
},
|
|
2485
|
-
{
|
|
2486
|
-
matcher: "Edit",
|
|
2487
|
-
hooks: [{
|
|
2488
|
-
type: "command",
|
|
2489
|
-
command: hookCommand
|
|
2490
|
-
}]
|
|
2491
|
-
},
|
|
2492
|
-
{
|
|
2493
|
-
matcher: "Glob",
|
|
2494
|
-
hooks: [{
|
|
2495
|
-
type: "command",
|
|
2496
|
-
command: hookCommand
|
|
2497
|
-
}]
|
|
2498
|
-
},
|
|
2499
|
-
{
|
|
2500
|
-
matcher: "Grep",
|
|
2501
|
-
hooks: [{
|
|
2502
|
-
type: "command",
|
|
2503
|
-
command: hookCommand
|
|
2504
|
-
}]
|
|
2505
|
-
}
|
|
2506
|
-
] },
|
|
2457
|
+
hooks: { PreToolUse: [{
|
|
2458
|
+
matcher: "Bash|Read|Write|Edit|Glob|Grep",
|
|
2459
|
+
hooks: [{
|
|
2460
|
+
type: "command",
|
|
2461
|
+
command: `node "$CLAUDE_PROJECT_DIR/.claude/hooks/bst-hook.mjs"`
|
|
2462
|
+
}]
|
|
2463
|
+
}] },
|
|
2507
2464
|
instructions: [
|
|
2508
2465
|
"Use pnpm, not npm/yarn/npx. Run binaries with `pnpm exec`.",
|
|
2509
2466
|
"No typecasts (as/any). Use zod schemas, type guards, or narrowing instead.",
|
|
@@ -2515,9 +2472,14 @@ function buildSettings(ctx) {
|
|
|
2515
2472
|
};
|
|
2516
2473
|
}
|
|
2517
2474
|
const BST_HOOK_MARKER = "bst-hook.mjs";
|
|
2518
|
-
/**
|
|
2519
|
-
function
|
|
2520
|
-
|
|
2475
|
+
/** Remove old per-tool bst-hook entries that are now covered by a consolidated matcher. */
|
|
2476
|
+
function removeObsoleteBstHookEntries(matchers, consolidatedMatcher) {
|
|
2477
|
+
const consolidatedTools = new Set(consolidatedMatcher.split("|"));
|
|
2478
|
+
return matchers.filter((m) => {
|
|
2479
|
+
if (!consolidatedTools.has(m.matcher)) return true;
|
|
2480
|
+
if (!m.hooks.some((h) => h.command.includes(BST_HOOK_MARKER))) return true;
|
|
2481
|
+
return false;
|
|
2482
|
+
});
|
|
2521
2483
|
}
|
|
2522
2484
|
/** Remove enabledPlugins/extraKnownMarketplaces/hooks when empty to keep the file clean. */
|
|
2523
2485
|
function serializeSettings$1(settings) {
|
|
@@ -2553,10 +2515,16 @@ function writeOrMergeSettings(ctx, filePath, generated) {
|
|
|
2553
2515
|
const mergedHooks = { ...settings.hooks };
|
|
2554
2516
|
for (const [event, generatedMatchers] of Object.entries(generated.hooks)) {
|
|
2555
2517
|
const existingMatchers = mergedHooks[event] ?? [];
|
|
2556
|
-
const
|
|
2557
|
-
|
|
2558
|
-
|
|
2559
|
-
|
|
2518
|
+
for (const gm of generatedMatchers) {
|
|
2519
|
+
if (existingMatchers.some((m) => m.matcher === gm.matcher && m.hooks.some((h) => h.command.includes(BST_HOOK_MARKER)))) continue;
|
|
2520
|
+
if (gm.matcher.includes("|")) {
|
|
2521
|
+
const before = (mergedHooks[event] ?? []).length;
|
|
2522
|
+
mergedHooks[event] = removeObsoleteBstHookEntries(mergedHooks[event] ?? [], gm.matcher);
|
|
2523
|
+
const removed = before - (mergedHooks[event] ?? []).length;
|
|
2524
|
+
if (removed > 0) hookChanges += removed;
|
|
2525
|
+
}
|
|
2526
|
+
mergedHooks[event] = [...mergedHooks[event] ?? [], gm];
|
|
2527
|
+
hookChanges++;
|
|
2560
2528
|
}
|
|
2561
2529
|
}
|
|
2562
2530
|
const missingPlugins = Object.entries(generated.enabledPlugins).filter(([key]) => !(key in settings.enabledPlugins));
|
|
@@ -3229,7 +3197,7 @@ async function runGenerators(ctx) {
|
|
|
3229
3197
|
function generateMigratePrompt(results, config, detected) {
|
|
3230
3198
|
const sections = [];
|
|
3231
3199
|
const timestamp = (/* @__PURE__ */ new Date()).toISOString();
|
|
3232
|
-
sections.push(`# Migration Prompt\n\n_Generated by \`@bensandee/tooling@0.40.
|
|
3200
|
+
sections.push(`# Migration Prompt\n\n_Generated by \`@bensandee/tooling@0.40.3 repo:sync\` on ${timestamp}_\n`);
|
|
3233
3201
|
const changed = results.filter((r) => r.action === "created" || r.action === "updated" || r.action === "archived");
|
|
3234
3202
|
if (changed.length > 0) {
|
|
3235
3203
|
const items = changed.map((r) => {
|
|
@@ -5365,7 +5333,7 @@ const hooksAuditCommand = defineCommand({
|
|
|
5365
5333
|
const main = defineCommand({
|
|
5366
5334
|
meta: {
|
|
5367
5335
|
name: "bst",
|
|
5368
|
-
version: "0.40.
|
|
5336
|
+
version: "0.40.3",
|
|
5369
5337
|
description: "Bootstrap and maintain standardized TypeScript project tooling"
|
|
5370
5338
|
},
|
|
5371
5339
|
subCommands: {
|
|
@@ -5382,7 +5350,7 @@ const main = defineCommand({
|
|
|
5382
5350
|
"hooks:audit": hooksAuditCommand
|
|
5383
5351
|
}
|
|
5384
5352
|
});
|
|
5385
|
-
console.log(`@bensandee/tooling v0.40.
|
|
5353
|
+
console.log(`@bensandee/tooling v0.40.3`);
|
|
5386
5354
|
async function run() {
|
|
5387
5355
|
await runMain(main);
|
|
5388
5356
|
process.exit(process.exitCode ?? 0);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bensandee/tooling",
|
|
3
|
-
"version": "0.40.
|
|
3
|
+
"version": "0.40.3",
|
|
4
4
|
"description": "CLI tool to bootstrap and maintain standardized TypeScript project tooling",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -51,22 +51,15 @@
|
|
|
51
51
|
"@types/node": "24.12.0",
|
|
52
52
|
"@types/picomatch": "4.0.2",
|
|
53
53
|
"commit-and-tag-version": "12.7.1",
|
|
54
|
-
"knip": "6.0.3",
|
|
55
|
-
"lefthook": "2.1.4",
|
|
56
|
-
"oxfmt": "0.41.0",
|
|
57
|
-
"oxlint": "1.56.0",
|
|
58
54
|
"prettier": "3.8.1",
|
|
59
55
|
"release-it": "19.2.4",
|
|
60
56
|
"tsdown": "0.21.4",
|
|
61
|
-
"
|
|
62
|
-
"
|
|
63
|
-
"@bensandee/config": "0.10.0",
|
|
64
|
-
"@bensandee/claude-hooks": "0.3.0"
|
|
57
|
+
"@bensandee/claude-hooks": "0.3.0",
|
|
58
|
+
"@bensandee/config": "0.10.0"
|
|
65
59
|
},
|
|
66
60
|
"scripts": {
|
|
67
61
|
"build": "tsdown",
|
|
68
62
|
"dev": "tsdown --watch",
|
|
69
|
-
"typecheck": "tsc --noEmit",
|
|
70
63
|
"test": "vitest run",
|
|
71
64
|
"generate:schema": "node scripts/generate-schema.ts"
|
|
72
65
|
}
|