@shrkcrft/boundaries 0.1.0-alpha.22 → 0.1.0-alpha.23

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/index.d.ts CHANGED
@@ -7,6 +7,7 @@ export * from './evaluate/evaluate-boundaries.js';
7
7
  export * from './scan/tsconfig-aliases.js';
8
8
  export * from './wiring/evaluate-wiring.js';
9
9
  export * from './wiring/scan-wiring-files.js';
10
+ export * from './wiring/registry-query.js';
10
11
  export * from './policy/extract-templates.js';
11
12
  export * from './policy/evaluate-policy.js';
12
13
  export * from './policy/run-policy.js';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,0BAA0B,CAAC;AACzC,cAAc,iCAAiC,CAAC;AAChD,cAAc,mCAAmC,CAAC;AAClD,cAAc,gBAAgB,CAAC;AAC/B,cAAc,wBAAwB,CAAC;AACvC,cAAc,mCAAmC,CAAC;AAClD,cAAc,4BAA4B,CAAC;AAC3C,cAAc,6BAA6B,CAAC;AAC5C,cAAc,+BAA+B,CAAC;AAC9C,cAAc,+BAA+B,CAAC;AAC9C,cAAc,6BAA6B,CAAC;AAC5C,cAAc,wBAAwB,CAAC;AACvC,cAAc,sBAAsB,CAAC;AACrC,cAAc,sBAAsB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,0BAA0B,CAAC;AACzC,cAAc,iCAAiC,CAAC;AAChD,cAAc,mCAAmC,CAAC;AAClD,cAAc,gBAAgB,CAAC;AAC/B,cAAc,wBAAwB,CAAC;AACvC,cAAc,mCAAmC,CAAC;AAClD,cAAc,4BAA4B,CAAC;AAC3C,cAAc,6BAA6B,CAAC;AAC5C,cAAc,+BAA+B,CAAC;AAC9C,cAAc,4BAA4B,CAAC;AAC3C,cAAc,+BAA+B,CAAC;AAC9C,cAAc,6BAA6B,CAAC;AAC5C,cAAc,wBAAwB,CAAC;AACvC,cAAc,sBAAsB,CAAC;AACrC,cAAc,sBAAsB,CAAC"}
package/dist/index.js CHANGED
@@ -7,6 +7,7 @@ export * from "./evaluate/evaluate-boundaries.js";
7
7
  export * from "./scan/tsconfig-aliases.js";
8
8
  export * from "./wiring/evaluate-wiring.js";
9
9
  export * from "./wiring/scan-wiring-files.js";
10
+ export * from "./wiring/registry-query.js";
10
11
  export * from "./policy/extract-templates.js";
11
12
  export * from "./policy/evaluate-policy.js";
12
13
  export * from "./policy/run-policy.js";
@@ -36,6 +36,14 @@ export interface IPolicyReport {
36
36
  readonly rules: readonly IPolicyRuleResult[];
37
37
  readonly findings: readonly IPolicyFinding[];
38
38
  readonly diagnostics: readonly string[];
39
+ /**
40
+ * Count of rules that actually scanned ≥1 unit. A rule whose globs matched 0
41
+ * files (e.g. a `style` rule in a project with no stylesheets) is NOT
42
+ * evaluated — a silent no-op the gate surfaces as `skipped` rather than a
43
+ * green pass. Misconfigured rules count as evaluated so their error is not
44
+ * swallowed by the gate's `evaluated === 0` skip path.
45
+ */
46
+ readonly evaluated: number;
39
47
  readonly verdict: 'pass' | 'errors' | 'warnings';
40
48
  }
41
49
  /** Resolves the content units to scan for a given rule (injected for purity/testability). */
@@ -1 +1 @@
1
- {"version":3,"file":"evaluate-policy.d.ts","sourceRoot":"","sources":["../../src/policy/evaluate-policy.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAGjE,eAAO,MAAM,kBAAkB,EAAG,2BAAoC,CAAC;AAEvE;;;;GAIG;AACH,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,6DAA6D;IAC7D,QAAQ,CAAC,cAAc,CAAC,EAAE,OAAO,CAAC;CACnC;AAED,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,OAAO,EAAE,aAAa,CAAC;IAChC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,uFAAuF;IACvF,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,QAAQ,EAAE,OAAO,GAAG,SAAS,CAAC;IACvC,QAAQ,CAAC,cAAc,CAAC,EAAE,OAAO,CAAC;CACnC;AAED,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,OAAO,EAAE,aAAa,CAAC;IAChC,QAAQ,CAAC,QAAQ,EAAE,OAAO,GAAG,SAAS,CAAC;IACvC,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,MAAM,EAAE,OAAO,kBAAkB,CAAC;IAC3C,QAAQ,CAAC,KAAK,EAAE,SAAS,iBAAiB,EAAE,CAAC;IAC7C,QAAQ,CAAC,QAAQ,EAAE,SAAS,cAAc,EAAE,CAAC;IAC7C,QAAQ,CAAC,WAAW,EAAE,SAAS,MAAM,EAAE,CAAC;IACxC,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,QAAQ,GAAG,UAAU,CAAC;CAClD;AAED,6FAA6F;AAC7F,MAAM,MAAM,kBAAkB,GAAG,CAAC,IAAI,EAAE,WAAW,KAAK,SAAS,WAAW,EAAE,CAAC;AAgB/E;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,SAAS,WAAW,EAAE,EAAE,OAAO,EAAE,kBAAkB,GAAG,aAAa,CAoExG"}
1
+ {"version":3,"file":"evaluate-policy.d.ts","sourceRoot":"","sources":["../../src/policy/evaluate-policy.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAGjE,eAAO,MAAM,kBAAkB,EAAG,2BAAoC,CAAC;AAEvE;;;;GAIG;AACH,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,6DAA6D;IAC7D,QAAQ,CAAC,cAAc,CAAC,EAAE,OAAO,CAAC;CACnC;AAED,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,OAAO,EAAE,aAAa,CAAC;IAChC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,uFAAuF;IACvF,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,QAAQ,EAAE,OAAO,GAAG,SAAS,CAAC;IACvC,QAAQ,CAAC,cAAc,CAAC,EAAE,OAAO,CAAC;CACnC;AAED,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,OAAO,EAAE,aAAa,CAAC;IAChC,QAAQ,CAAC,QAAQ,EAAE,OAAO,GAAG,SAAS,CAAC;IACvC,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,MAAM,EAAE,OAAO,kBAAkB,CAAC;IAC3C,QAAQ,CAAC,KAAK,EAAE,SAAS,iBAAiB,EAAE,CAAC;IAC7C,QAAQ,CAAC,QAAQ,EAAE,SAAS,cAAc,EAAE,CAAC;IAC7C,QAAQ,CAAC,WAAW,EAAE,SAAS,MAAM,EAAE,CAAC;IACxC;;;;;;OAMG;IACH,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,QAAQ,GAAG,UAAU,CAAC;CAClD;AAED,6FAA6F;AAC7F,MAAM,MAAM,kBAAkB,GAAG,CAAC,IAAI,EAAE,WAAW,KAAK,SAAS,WAAW,EAAE,CAAC;AAgB/E;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,SAAS,WAAW,EAAE,EAAE,OAAO,EAAE,kBAAkB,GAAG,aAAa,CA2ExG"}
@@ -23,6 +23,7 @@ export function evaluatePolicy(rules, resolve) {
23
23
  const ruleResults = [];
24
24
  const findings = [];
25
25
  const diagnostics = [];
26
+ let evaluated = 0;
26
27
  let misconfigError = false;
27
28
  let misconfigWarn = false;
28
29
  for (const rule of rules) {
@@ -36,11 +37,17 @@ export function evaluatePolicy(rules, resolve) {
36
37
  else
37
38
  misconfigWarn = true;
38
39
  ruleResults.push({ ruleId: rule.id, surface: rule.surface, severity, findingCount: 0, error: msg });
40
+ // A misconfigured rule attempted to run — count it as evaluated so its
41
+ // error isn't swallowed by the gate's `evaluated === 0` skip path.
42
+ evaluated += 1;
39
43
  continue;
40
44
  }
45
+ const units = resolve(rule);
46
+ if (units.length > 0)
47
+ evaluated += 1;
41
48
  let count = 0;
42
49
  let zeroWidth = false;
43
- for (const unit of resolve(rule)) {
50
+ for (const unit of units) {
44
51
  re.lastIndex = 0;
45
52
  let m;
46
53
  while ((m = re.exec(unit.content)) !== null) {
@@ -87,6 +94,7 @@ export function evaluatePolicy(rules, resolve) {
87
94
  rules: ruleResults,
88
95
  findings,
89
96
  diagnostics,
97
+ evaluated,
90
98
  verdict: hasError ? 'errors' : hasWarn ? 'warnings' : 'pass',
91
99
  };
92
100
  }
@@ -1 +1 @@
1
- {"version":3,"file":"run-policy.d.ts","sourceRoot":"","sources":["../../src/policy/run-policy.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAIjE,OAAO,EAAkB,KAAK,aAAa,EAAoB,MAAM,sBAAsB,CAAC;AAY5F,MAAM,WAAW,iBAAiB;IAChC,2CAA2C;IAC3C,QAAQ,CAAC,QAAQ,CAAC,EAAE,SAAS,aAAa,EAAE,CAAC;IAC7C,+BAA+B;IAC/B,QAAQ,CAAC,IAAI,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAClC,kEAAkE;IAClE,QAAQ,CAAC,WAAW,CAAC,EAAE,OAAO,CAAC;IAC/B,QAAQ,CAAC,YAAY,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC1C,2FAA2F;IAC3F,QAAQ,CAAC,WAAW,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CAC1C;AAMD;;;;;GAKG;AACH,wBAAgB,aAAa,CAC3B,WAAW,EAAE,MAAM,EACnB,KAAK,EAAE,SAAS,WAAW,EAAE,EAC7B,OAAO,GAAE,iBAAsB,GAC9B,aAAa,CAsCf"}
1
+ {"version":3,"file":"run-policy.d.ts","sourceRoot":"","sources":["../../src/policy/run-policy.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAIjE,OAAO,EAAkB,KAAK,aAAa,EAAoB,MAAM,sBAAsB,CAAC;AAY5F,MAAM,WAAW,iBAAiB;IAChC,2CAA2C;IAC3C,QAAQ,CAAC,QAAQ,CAAC,EAAE,SAAS,aAAa,EAAE,CAAC;IAC7C,+BAA+B;IAC/B,QAAQ,CAAC,IAAI,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAClC,kEAAkE;IAClE,QAAQ,CAAC,WAAW,CAAC,EAAE,OAAO,CAAC;IAC/B,QAAQ,CAAC,YAAY,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC1C,2FAA2F;IAC3F,QAAQ,CAAC,WAAW,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CAC1C;AAMD;;;;;GAKG;AACH,wBAAgB,aAAa,CAC3B,WAAW,EAAE,MAAM,EACnB,KAAK,EAAE,SAAS,WAAW,EAAE,EAC7B,OAAO,GAAE,iBAAsB,GAC9B,aAAa,CA6Cf"}
@@ -35,14 +35,22 @@ export function runPolicyLint(projectRoot, rules, options = {}) {
35
35
  selected = selected.filter((r) => changed.some((c) => matchesAny(c, globsFor(r))));
36
36
  }
37
37
  if (selected.length === 0) {
38
- return { schema: 'sharkcraft.policy-lint/v1', rules: [], findings: [], diagnostics: [], verdict: 'pass' };
38
+ return { schema: 'sharkcraft.policy-lint/v1', rules: [], findings: [], diagnostics: [], evaluated: 0, verdict: 'pass' };
39
39
  }
40
+ // Under --changed-only, restrict the SCANNED files to the changed set too (not
41
+ // just rule selection). Per-file regex findings have no cross-file dependency,
42
+ // so a pre-existing violation in a file the diff never touched is out of scope
43
+ // — this mirrors how `check boundaries`/wiring restrict to the changeset and
44
+ // stops the gate failing RED on untouched legacy debt.
45
+ const changedSet = options.changedOnly ? new Set(options.changedFiles ?? []) : undefined;
40
46
  const allGlobs = [...new Set(selected.flatMap((r) => [...globsFor(r)]))];
41
47
  const cache = readMatchingFiles(projectRoot, allGlobs, new Set(options.excludeDirs ?? []));
42
48
  return evaluatePolicy(selected, (rule) => {
43
49
  const globs = globsFor(rule);
44
50
  const units = [];
45
51
  for (const [path, content] of cache) {
52
+ if (changedSet && !changedSet.has(path))
53
+ continue;
46
54
  if (!matchesAny(path, globs))
47
55
  continue;
48
56
  const ext = nodePath.extname(path).toLowerCase();
@@ -1 +1 @@
1
- {"version":3,"file":"scan-imports.d.ts","sourceRoot":"","sources":["../../src/scan/scan-imports.ts"],"names":[],"mappings":"AAkBA,MAAM,WAAW,mBAAmB;IAClC,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAChC,iEAAiE;IACjE,OAAO,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CAC7B;AAED,MAAM,WAAW,WAAW;IAC1B,6CAA6C;IAC7C,IAAI,EAAE,MAAM,CAAC;IACb,gCAAgC;IAChC,eAAe,EAAE,MAAM,CAAC;IACxB,0DAA0D;IAC1D,IAAI,EAAE,MAAM,CAAC;IACb;;;;;OAKG;IACH,IAAI,EAAE,UAAU,GAAG,UAAU,CAAC;CAC/B;AAED,MAAM,WAAW,iBAAiB;IAChC,YAAY,EAAE,MAAM,CAAC;IACrB,KAAK,EAAE,WAAW,EAAE,CAAC;IACrB,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAoFD;;GAEG;AACH,wBAAgB,WAAW,CAAC,OAAO,EAAE,mBAAmB,GAAG,iBAAiB,CAyB3E;AAED;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC,YAAY,EAAE,MAAM,CAAC;IACrB,YAAY,EAAE,MAAM,CAAC;IACrB,eAAe,EAAE,MAAM,CAAC;IACxB,eAAe,EAAE,MAAM,CAAC;IACxB,qBAAqB,EAAE,SAAS;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IACvE,QAAQ,EAAE,SAAS,MAAM,EAAE,CAAC;CAC7B;AAED,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,iBAAiB,GAAG,mBAAmB,CAmB7E"}
1
+ {"version":3,"file":"scan-imports.d.ts","sourceRoot":"","sources":["../../src/scan/scan-imports.ts"],"names":[],"mappings":"AAkBA,MAAM,WAAW,mBAAmB;IAClC,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAChC,iEAAiE;IACjE,OAAO,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CAC7B;AAED,MAAM,WAAW,WAAW;IAC1B,6CAA6C;IAC7C,IAAI,EAAE,MAAM,CAAC;IACb,gCAAgC;IAChC,eAAe,EAAE,MAAM,CAAC;IACxB,0DAA0D;IAC1D,IAAI,EAAE,MAAM,CAAC;IACb;;;;;OAKG;IACH,IAAI,EAAE,UAAU,GAAG,UAAU,CAAC;CAC/B;AAED,MAAM,WAAW,iBAAiB;IAChC,YAAY,EAAE,MAAM,CAAC;IACrB,KAAK,EAAE,WAAW,EAAE,CAAC;IACrB,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAkFD;;GAEG;AACH,wBAAgB,WAAW,CAAC,OAAO,EAAE,mBAAmB,GAAG,iBAAiB,CAyB3E;AAED;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC,YAAY,EAAE,MAAM,CAAC;IACrB,YAAY,EAAE,MAAM,CAAC;IACrB,eAAe,EAAE,MAAM,CAAC;IACxB,eAAe,EAAE,MAAM,CAAC;IACxB,qBAAqB,EAAE,SAAS;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IACvE,QAAQ,EAAE,SAAS,MAAM,EAAE,CAAC;CAC7B;AAED,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,iBAAiB,GAAG,mBAAmB,CAmB7E"}
@@ -1,4 +1,4 @@
1
- import { existsSync, readFileSync, readdirSync, statSync } from 'node:fs';
1
+ import { existsSync, readFileSync, readdirSync } from 'node:fs';
2
2
  import * as nodePath from 'node:path';
3
3
  const SUPPORTED_EXTS = new Set(['.ts', '.tsx', '.js', '.jsx', '.mjs', '.cjs']);
4
4
  const DEFAULT_IGNORE = new Set([
@@ -46,18 +46,16 @@ function* walk(root, current, extraIgnore) {
46
46
  const name = String(entry.name);
47
47
  if (isIgnored(name, extraIgnore))
48
48
  continue;
49
+ // Do NOT descend into (or yield through) symlinks. Following a symlinked
50
+ // directory can inject phantom files into the graph — a self-referential
51
+ // loop (`src/loop -> src` => `src/loop/loop/loop/...`) only self-terminates
52
+ // by accident at PATH_MAX, and a link to a large external tree gets fully
53
+ // scanned. Mirror detect-workspace.ts's isTraversableDir pruning.
54
+ if (entry.isSymbolicLink())
55
+ continue;
49
56
  const full = nodePath.join(current, name);
50
- try {
51
- const isDir = entry.isDirectory() || entry.isSymbolicLink();
52
- if (isDir) {
53
- const stat = statSync(full);
54
- if (stat.isDirectory()) {
55
- yield* walk(root, full, extraIgnore);
56
- }
57
- continue;
58
- }
59
- }
60
- catch {
57
+ if (entry.isDirectory()) {
58
+ yield* walk(root, full, extraIgnore);
61
59
  continue;
62
60
  }
63
61
  if (entry.isFile()) {
@@ -6,7 +6,7 @@ export interface IWiringFileEntry {
6
6
  readonly path: string;
7
7
  readonly content: string;
8
8
  }
9
- /** A captured token + where it was captured (for declared tokens). */
9
+ /** A captured token + where it was captured. */
10
10
  export interface IWiringTokenSite {
11
11
  readonly token: string;
12
12
  readonly file: string;
@@ -14,12 +14,18 @@ export interface IWiringTokenSite {
14
14
  }
15
15
  export interface IWiringViolation {
16
16
  readonly ruleId: string;
17
- /** The declared token that is not present in the registered set. */
17
+ /** The token that is missing from the other side. */
18
18
  readonly token: string;
19
- /** Declaring file (project-relative) + 1-based line. */
19
+ /** Declaring (or registering) file (project-relative) + 1-based line. */
20
20
  readonly file: string;
21
21
  readonly line: number;
22
22
  readonly severity: 'error' | 'warning';
23
+ /**
24
+ * Which side the token is missing from. `declared-missing` (the subset case):
25
+ * declared but not registered. `registered-missing` (parity only): registered
26
+ * but never declared.
27
+ */
28
+ readonly direction?: 'declared-missing' | 'registered-missing';
23
29
  readonly hint?: string;
24
30
  }
25
31
  export interface IWiringRuleResult {
@@ -29,7 +35,7 @@ export interface IWiringRuleResult {
29
35
  readonly declaredCount: number;
30
36
  readonly registeredCount: number;
31
37
  readonly violations: readonly IWiringViolation[];
32
- /** Set when the rule is misconfigured (bad regex / no capture group). */
38
+ /** Set when the rule is misconfigured (bad regex / no capture group / bad source). */
33
39
  readonly error?: string;
34
40
  }
35
41
  export interface IWiringReport {
@@ -38,15 +44,36 @@ export interface IWiringReport {
38
44
  readonly violations: readonly IWiringViolation[];
39
45
  /** Rule-level misconfiguration messages (never throws — degrades gracefully). */
40
46
  readonly diagnostics: readonly string[];
47
+ /**
48
+ * Count of rules that actually ran a comparison. A rule whose declared+
49
+ * registered globs matched 0 files is NOT evaluated (a silent no-op the gate
50
+ * surfaces as `skipped`). Misconfigured rules count as evaluated so their
51
+ * error is not swallowed.
52
+ */
53
+ readonly evaluated: number;
41
54
  readonly verdict: 'pass' | 'errors' | 'warnings';
42
55
  }
43
56
  /** Resolves a rule-side's globs to the concrete files (path + content) to scan. */
44
57
  export type WiringFileResolver = (source: IWiringSource) => readonly IWiringFileEntry[];
45
58
  /**
46
- * Pure wiring evaluation. For each rule: every DECLARED token that is not in the
47
- * REGISTERED set is a violation, reported at its first declaring site. The
48
- * `resolve` callback supplies the files for a given rule-side (injected so the
49
- * engine stays pure / testable see `runWiring` for the fs-backed wiring).
59
+ * Public: extract every token site from ONE wiring source (regex capture group
60
+ * 1 or `arrayProperty` elements) over the given files. Shared by the wiring
61
+ * evaluator and the registry-inventory engine so both honour the exact same
62
+ * extraction semantics. A misconfigured source returns an `error` and no sites
63
+ * (never throws).
64
+ */
65
+ export declare function collectSourceSites(source: IWiringSource, files: readonly IWiringFileEntry[]): {
66
+ sites: readonly IWiringTokenSite[];
67
+ error?: string;
68
+ };
69
+ /**
70
+ * Pure wiring evaluation. For each rule: the DECLARED token set is checked
71
+ * against the UNION of the REGISTERED sources. Every declared token absent from
72
+ * the registered set is a `declared-missing` violation; in `parity` mode every
73
+ * registered token absent from the declared set is also a `registered-missing`
74
+ * violation. With `groupBy`, membership is checked within the same dir/package.
75
+ * The `resolve` callback supplies the files for a given rule-side (injected so
76
+ * the engine stays pure / testable — see `runWiring` for the fs-backed wiring).
50
77
  */
51
78
  export declare function evaluateWiring(rules: readonly IWiringRule[], resolve: WiringFileResolver): IWiringReport;
52
79
  //# sourceMappingURL=evaluate-wiring.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"evaluate-wiring.d.ts","sourceRoot":"","sources":["../../src/wiring/evaluate-wiring.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAGjE,eAAO,MAAM,aAAa,EAAG,sBAA+B,CAAC;AAE7D,2CAA2C;AAC3C,MAAM,WAAW,gBAAgB;IAC/B,mCAAmC;IACnC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CAC1B;AAED,sEAAsE;AACtE,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,oEAAoE;IACpE,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,wDAAwD;IACxD,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,QAAQ,EAAE,OAAO,GAAG,SAAS,CAAC;IACvC,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,QAAQ,EAAE,OAAO,GAAG,SAAS,CAAC;IACvC,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAC;IACjC,QAAQ,CAAC,UAAU,EAAE,SAAS,gBAAgB,EAAE,CAAC;IACjD,yEAAyE;IACzE,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,MAAM,EAAE,OAAO,aAAa,CAAC;IACtC,QAAQ,CAAC,KAAK,EAAE,SAAS,iBAAiB,EAAE,CAAC;IAC7C,QAAQ,CAAC,UAAU,EAAE,SAAS,gBAAgB,EAAE,CAAC;IACjD,iFAAiF;IACjF,QAAQ,CAAC,WAAW,EAAE,SAAS,MAAM,EAAE,CAAC;IACxC,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,QAAQ,GAAG,UAAU,CAAC;CAClD;AAED,mFAAmF;AACnF,MAAM,MAAM,kBAAkB,GAAG,CAAC,MAAM,EAAE,aAAa,KAAK,SAAS,gBAAgB,EAAE,CAAC;AAiDxF;;;;;GAKG;AACH,wBAAgB,cAAc,CAC5B,KAAK,EAAE,SAAS,WAAW,EAAE,EAC7B,OAAO,EAAE,kBAAkB,GAC1B,aAAa,CAkFf"}
1
+ {"version":3,"file":"evaluate-wiring.d.ts","sourceRoot":"","sources":["../../src/wiring/evaluate-wiring.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAGjE,eAAO,MAAM,aAAa,EAAG,sBAA+B,CAAC;AAE7D,2CAA2C;AAC3C,MAAM,WAAW,gBAAgB;IAC/B,mCAAmC;IACnC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CAC1B;AAED,gDAAgD;AAChD,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,qDAAqD;IACrD,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,yEAAyE;IACzE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,QAAQ,EAAE,OAAO,GAAG,SAAS,CAAC;IACvC;;;;OAIG;IACH,QAAQ,CAAC,SAAS,CAAC,EAAE,kBAAkB,GAAG,oBAAoB,CAAC;IAC/D,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,QAAQ,EAAE,OAAO,GAAG,SAAS,CAAC;IACvC,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAC;IACjC,QAAQ,CAAC,UAAU,EAAE,SAAS,gBAAgB,EAAE,CAAC;IACjD,sFAAsF;IACtF,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,MAAM,EAAE,OAAO,aAAa,CAAC;IACtC,QAAQ,CAAC,KAAK,EAAE,SAAS,iBAAiB,EAAE,CAAC;IAC7C,QAAQ,CAAC,UAAU,EAAE,SAAS,gBAAgB,EAAE,CAAC;IACjD,iFAAiF;IACjF,QAAQ,CAAC,WAAW,EAAE,SAAS,MAAM,EAAE,CAAC;IACxC;;;;;OAKG;IACH,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,QAAQ,GAAG,UAAU,CAAC;CAClD;AAED,mFAAmF;AACnF,MAAM,MAAM,kBAAkB,GAAG,CAAC,MAAM,EAAE,aAAa,KAAK,SAAS,gBAAgB,EAAE,CAAC;AAsCxF;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAChC,MAAM,EAAE,aAAa,EACrB,KAAK,EAAE,SAAS,gBAAgB,EAAE,GACjC;IAAE,KAAK,EAAE,SAAS,gBAAgB,EAAE,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,CAOxD;AAuJD;;;;;;;;GAQG;AACH,wBAAgB,cAAc,CAC5B,KAAK,EAAE,SAAS,WAAW,EAAE,EAC7B,OAAO,EAAE,kBAAkB,GAC1B,aAAa,CAsHf"}
Binary file
@@ -0,0 +1,40 @@
1
+ import type { IRegistryDeclaration } from '@shrkcrft/core';
2
+ export declare const REGISTRY_SCHEMA: "sharkcraft.registry-inventory/v1";
3
+ /** Where an id was found (project-relative path + 1-based line). */
4
+ export interface IRegistrySite {
5
+ readonly file: string;
6
+ readonly line: number;
7
+ }
8
+ /** One id in a registry: its declaration sites + (optional) consumer/binding sites. */
9
+ export interface IRegistryEntry {
10
+ readonly id: string;
11
+ /** Declaration sites (from `source`), sorted by file then line. */
12
+ readonly sites: readonly IRegistrySite[];
13
+ /** Consumer/binding sites (from `consumer`), when the declaration sets one. */
14
+ readonly consumerSites?: readonly IRegistrySite[];
15
+ }
16
+ /** A scanned registry inventory: every distinct id and where it lives. */
17
+ export interface IRegistryInventory {
18
+ readonly schema: typeof REGISTRY_SCHEMA;
19
+ readonly name: string;
20
+ readonly description?: string;
21
+ /** Distinct ids, sorted, each with its sites. */
22
+ readonly entries: readonly IRegistryEntry[];
23
+ /** Misconfiguration messages (bad regex / no capture group / bad source). */
24
+ readonly diagnostics: readonly string[];
25
+ }
26
+ export interface IScanRegistryOptions {
27
+ /** Project-relative directories to prune from the walk. */
28
+ readonly excludeDirs?: readonly string[];
29
+ }
30
+ /**
31
+ * Scan a declared registry, returning every distinct id and its declaration
32
+ * (and optional consumer) sites. Pure-engine output; the only IO is a single
33
+ * read-only tree walk over the union of the source/consumer globs.
34
+ */
35
+ export declare function scanRegistry(projectRoot: string, decl: IRegistryDeclaration, options?: IScanRegistryOptions): IRegistryInventory;
36
+ /** True if `id` is declared in the registry (alias-blind exact membership). */
37
+ export declare function registryExists(inventory: IRegistryInventory, id: string): boolean;
38
+ /** The entry for `id`, or undefined if not declared. */
39
+ export declare function registryWhere(inventory: IRegistryInventory, id: string): IRegistryEntry | undefined;
40
+ //# sourceMappingURL=registry-query.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registry-query.d.ts","sourceRoot":"","sources":["../../src/wiring/registry-query.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,gBAAgB,CAAC;AAK3D,eAAO,MAAM,eAAe,EAAG,kCAA2C,CAAC;AAE3E,oEAAoE;AACpE,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACvB;AAED,uFAAuF;AACvF,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,mEAAmE;IACnE,QAAQ,CAAC,KAAK,EAAE,SAAS,aAAa,EAAE,CAAC;IACzC,+EAA+E;IAC/E,QAAQ,CAAC,aAAa,CAAC,EAAE,SAAS,aAAa,EAAE,CAAC;CACnD;AAED,0EAA0E;AAC1E,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,MAAM,EAAE,OAAO,eAAe,CAAC;IACxC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B,iDAAiD;IACjD,QAAQ,CAAC,OAAO,EAAE,SAAS,cAAc,EAAE,CAAC;IAC5C,6EAA6E;IAC7E,QAAQ,CAAC,WAAW,EAAE,SAAS,MAAM,EAAE,CAAC;CACzC;AAED,MAAM,WAAW,oBAAoB;IACnC,2DAA2D;IAC3D,QAAQ,CAAC,WAAW,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CAC1C;AAMD;;;;GAIG;AACH,wBAAgB,YAAY,CAC1B,WAAW,EAAE,MAAM,EACnB,IAAI,EAAE,oBAAoB,EAC1B,OAAO,GAAE,oBAAyB,GACjC,kBAAkB,CA+CpB;AAED,+EAA+E;AAC/E,wBAAgB,cAAc,CAAC,SAAS,EAAE,kBAAkB,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAEjF;AAED,wDAAwD;AACxD,wBAAgB,aAAa,CAAC,SAAS,EAAE,kBAAkB,EAAE,EAAE,EAAE,MAAM,GAAG,cAAc,GAAG,SAAS,CAEnG"}
@@ -0,0 +1,65 @@
1
+ import { matchesAny } from "../scan/glob.js";
2
+ import { readMatchingFiles } from "../util/walk-files.js";
3
+ import { collectSourceSites } from "./evaluate-wiring.js";
4
+ export const REGISTRY_SCHEMA = 'sharkcraft.registry-inventory/v1';
5
+ function sortSites(sites) {
6
+ return [...sites].sort((a, b) => a.file.localeCompare(b.file) || a.line - b.line);
7
+ }
8
+ /**
9
+ * Scan a declared registry, returning every distinct id and its declaration
10
+ * (and optional consumer) sites. Pure-engine output; the only IO is a single
11
+ * read-only tree walk over the union of the source/consumer globs.
12
+ */
13
+ export function scanRegistry(projectRoot, decl, options = {}) {
14
+ const globs = [
15
+ ...new Set([...decl.source.files, ...(decl.consumer ? decl.consumer.files : [])]),
16
+ ];
17
+ const cache = readMatchingFiles(projectRoot, globs, new Set(options.excludeDirs ?? []));
18
+ const entries = [...cache.entries()].map(([path, content]) => ({ path, content }));
19
+ const diagnostics = [];
20
+ const sourceFiles = entries.filter((f) => matchesAny(f.path, decl.source.files));
21
+ const declared = collectSourceSites(decl.source, sourceFiles);
22
+ if (declared.error)
23
+ diagnostics.push(`registry "${decl.name}" source: ${declared.error}`);
24
+ const consumerByToken = new Map();
25
+ if (decl.consumer) {
26
+ const consumerFiles = entries.filter((f) => matchesAny(f.path, decl.consumer.files));
27
+ const consumed = collectSourceSites(decl.consumer, consumerFiles);
28
+ if (consumed.error)
29
+ diagnostics.push(`registry "${decl.name}" consumer: ${consumed.error}`);
30
+ for (const s of consumed.sites) {
31
+ const list = consumerByToken.get(s.token) ?? [];
32
+ list.push({ file: s.file, line: s.line });
33
+ consumerByToken.set(s.token, list);
34
+ }
35
+ }
36
+ const declaredByToken = new Map();
37
+ for (const s of declared.sites) {
38
+ const list = declaredByToken.get(s.token) ?? [];
39
+ list.push({ file: s.file, line: s.line });
40
+ declaredByToken.set(s.token, list);
41
+ }
42
+ const entriesOut = [...declaredByToken.keys()].sort().map((id) => {
43
+ const consumerSites = consumerByToken.get(id);
44
+ return {
45
+ id,
46
+ sites: sortSites(declaredByToken.get(id) ?? []),
47
+ ...(consumerSites && consumerSites.length > 0 ? { consumerSites: sortSites(consumerSites) } : {}),
48
+ };
49
+ });
50
+ return {
51
+ schema: REGISTRY_SCHEMA,
52
+ name: decl.name,
53
+ ...(decl.description ? { description: decl.description } : {}),
54
+ entries: entriesOut,
55
+ diagnostics,
56
+ };
57
+ }
58
+ /** True if `id` is declared in the registry (alias-blind exact membership). */
59
+ export function registryExists(inventory, id) {
60
+ return inventory.entries.some((e) => e.id === id);
61
+ }
62
+ /** The entry for `id`, or undefined if not declared. */
63
+ export function registryWhere(inventory, id) {
64
+ return inventory.entries.find((e) => e.id === id);
65
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"scan-wiring-files.d.ts","sourceRoot":"","sources":["../../src/wiring/scan-wiring-files.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAGlD,OAAO,EAGL,KAAK,aAAa,EACnB,MAAM,sBAAsB,CAAC;AAE9B,MAAM,WAAW,iBAAiB;IAChC,wEAAwE;IACxE,QAAQ,CAAC,YAAY,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC1C,iGAAiG;IACjG,QAAQ,CAAC,WAAW,CAAC,EAAE,OAAO,CAAC;IAC/B,+BAA+B;IAC/B,QAAQ,CAAC,IAAI,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAClC,2FAA2F;IAC3F,QAAQ,CAAC,WAAW,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CAC1C;AAED;;;;GAIG;AACH,wBAAgB,SAAS,CACvB,WAAW,EAAE,MAAM,EACnB,KAAK,EAAE,SAAS,WAAW,EAAE,EAC7B,OAAO,GAAE,iBAAsB,GAC9B,aAAa,CAyBf"}
1
+ {"version":3,"file":"scan-wiring-files.d.ts","sourceRoot":"","sources":["../../src/wiring/scan-wiring-files.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAiB,MAAM,gBAAgB,CAAC;AAGjE,OAAO,EAGL,KAAK,aAAa,EACnB,MAAM,sBAAsB,CAAC;AAW9B,MAAM,WAAW,iBAAiB;IAChC,wEAAwE;IACxE,QAAQ,CAAC,YAAY,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC1C,iGAAiG;IACjG,QAAQ,CAAC,WAAW,CAAC,EAAE,OAAO,CAAC;IAC/B,+BAA+B;IAC/B,QAAQ,CAAC,IAAI,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAClC,2FAA2F;IAC3F,QAAQ,CAAC,WAAW,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CAC1C;AAED;;;;GAIG;AACH,wBAAgB,SAAS,CACvB,WAAW,EAAE,MAAM,EACnB,KAAK,EAAE,SAAS,WAAW,EAAE,EAC7B,OAAO,GAAE,iBAAsB,GAC9B,aAAa,CA8Bf"}
@@ -1,6 +1,14 @@
1
1
  import { matchesAny } from "../scan/glob.js";
2
2
  import { readMatchingFiles } from "../util/walk-files.js";
3
3
  import { evaluateWiring, } from "./evaluate-wiring.js";
4
+ /** All file globs a rule references: its declared side + every registered source (union). */
5
+ function ruleGlobs(rule) {
6
+ const reg = rule.registered;
7
+ const sources = Array.isArray(reg)
8
+ ? reg
9
+ : [reg];
10
+ return [...rule.declared.files, ...sources.flatMap((s) => [...s.files])];
11
+ }
4
12
  /**
5
13
  * Filesystem-backed wiring run: walks the project once, reads only the files a
6
14
  * rule references (skipping oversized files), and evaluates every (selected)
@@ -15,17 +23,22 @@ export function runWiring(projectRoot, rules, options = {}) {
15
23
  if (options.changedOnly) {
16
24
  const changed = options.changedFiles ?? [];
17
25
  selected = selected.filter((r) => {
18
- const globs = [...r.declared.files, ...r.registered.files];
26
+ const globs = ruleGlobs(r);
19
27
  return changed.some((c) => matchesAny(c, globs));
20
28
  });
21
29
  }
22
30
  if (selected.length === 0) {
23
- return { schema: 'sharkcraft.wiring/v1', rules: [], violations: [], diagnostics: [], verdict: 'pass' };
31
+ return {
32
+ schema: 'sharkcraft.wiring/v1',
33
+ rules: [],
34
+ violations: [],
35
+ diagnostics: [],
36
+ evaluated: 0,
37
+ verdict: 'pass',
38
+ };
24
39
  }
25
40
  // Union of all globs across selected rules → one tree walk, cached reads.
26
- const allGlobs = [
27
- ...new Set(selected.flatMap((r) => [...r.declared.files, ...r.registered.files])),
28
- ];
41
+ const allGlobs = [...new Set(selected.flatMap(ruleGlobs))];
29
42
  const cache = readMatchingFiles(projectRoot, allGlobs, new Set(options.excludeDirs ?? []));
30
43
  const entries = [...cache.entries()].map(([path, content]) => ({ path, content }));
31
44
  return evaluateWiring(selected, (source) => entries.filter((f) => matchesAny(f.path, source.files)));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@shrkcrft/boundaries",
3
- "version": "0.1.0-alpha.22",
3
+ "version": "0.1.0-alpha.23",
4
4
  "description": "SharkCraft boundary rules: detect when a repository violates its own architecture (forbidden imports across folder/package/layer boundaries).",
5
5
  "license": "MIT",
6
6
  "author": "SharkCraft contributors",
@@ -43,7 +43,7 @@
43
43
  "typecheck": "tsc --noEmit -p tsconfig.json"
44
44
  },
45
45
  "dependencies": {
46
- "@shrkcrft/core": "^0.1.0-alpha.22"
46
+ "@shrkcrft/core": "^0.1.0-alpha.23"
47
47
  },
48
48
  "publishConfig": {
49
49
  "access": "public"