@pho9ubenaa/siro 0.4.3 → 0.5.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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,70 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.5.1]
4
+
5
+ ### Refactoring
6
+
7
+ - Reorganize runtime code around explicit domain and application ports, concrete adapters, and outer composition while preserving the public API, CLI, JSON schema, package-manager policy, and error behavior.
8
+ - Make the source dependency graph acyclic and enforce inward dependencies with TypeScript module resolution, including type imports, re-exports, host globals, and unresolved local modules.
9
+ - Move filesystem, path, glob, configuration loading, reporting, and clock behavior behind focused boundaries. Keep JavaScript date parsing in the adapter and inject the current time into release-age policy.
10
+ - Centralize workspace pattern classification and Deno release-age parsing, replacing incidental regular expressions and string rewrites where direct string operations are clearer.
11
+
12
+ ### Maintenance
13
+
14
+ - Consolidate tests around observable decisions, failures, public wiring, CLI behavior, and installed-package contracts. Remove duplicate, implementation-coupled, mock-self-verifying, and library-guarantee cases.
15
+ - Add architecture and maintainer documentation for dependency direction, composition, ports, adapters, and behavioral contracts.
16
+ - Invite real-world feedback through GitHub Issues and explain how GitHub Stars inform time spent on future features and maintenance.
17
+
18
+ ### Compatibility
19
+
20
+ - This release changes internal structure and test coverage only. Existing public exports, synchronous `lint`, asynchronous `lintCommand`, CLI flags and exit codes, JSON schema 2, supported package-manager behavior, and Node.js range remain unchanged.
21
+
22
+ ## [0.5.0]
23
+
24
+ ### Features
25
+
26
+ - Allow custom checks to return a nonempty `violations` group. Report unsupported settings separately per file and Aube lifecycle controls separately per missing file. JSON schema 2 is unchanged; exhaustive `CheckStatus` consumers must handle the new variant.
27
+ - Add optional `FileSystem.resolveDirectory` for Deno's native positive literal-prefix lookup, retaining minimatch and existing dependencies. Virtual filesystems without this port resolve exact child names. Negative patterns retain lexical applicability; conflicting overlapping bases fail explicitly.
28
+
29
+ - Add `unsupported-settings` to report configured settings introduced after a declared or explicit stable PM version. Cover 16 setting/file pairs across npm, pnpm, Yarn, Bun, and Deno, with a generated table of release sources.
30
+ - Resolve each manager's target from `package.json#packageManager`, `config.pmVersions`, or the higher-priority `--pm-version` / API `pmVersion` option (which requires `--pm` / `pm`). Expose the resolved target as `RuleContext.pmVersion` for custom rules.
31
+ - Preserve name detection when a declaration has no exact stable version. Reject ranges, tags, partial versions, and prereleases in explicit targets; accept build metadata such as Corepack hashes.
32
+ - Add opt-in `--workspaces` / API `workspaces: true` to inspect declared npm, pnpm, Yarn, Bun, Deno, and Aube members' publication metadata. Reuse existing rules, identify member file paths, and aggregate severity counts and CLI exit status.
33
+ - Add optional `FileSystem.readDirectories` for workspace discovery in virtual repositories, without falling back to host IO.
34
+
35
+ ### Behavior and scope
36
+
37
+ - The new rule defaults to `error`; projects with previously accepted unsupported settings may now exit 1. Existing security checks, severity overrides, and JSON schema 2 remain in effect.
38
+ - Availability checks cover recorded introductions in the listed files, not whole PM schemas, runtime discovery, removals, backports, version-specific value syntax, or effective defaults. Deno coverage is limited to `.npmrc#min-release-age`; Aube retains its existing checks without introduction coverage in this release.
39
+ - Distinguish pnpm's strict-build setting introduction (10.3.0) from general workspace YAML support (10.6.0), and correct Bun's scanner introduction note to 1.2.21.
40
+ - Keep shared installation and lockfile checks at the root. Members infer their own publication status and use the root's PM target; child executable configs are not loaded. Workspace discovery requires explicit declarations, excludes directory symlinks, and does not cover effective configuration inheritance. Deno/Aube use bounded, source-derived declaration semantics.
41
+
42
+ ### Fixes
43
+
44
+ - Update `smol-toml` to 1.8.0 and Vitest to 4.1.11 to include upstream security fixes.
45
+ - Honor Deno 2.8.1+'s project `.npmrc#min-release-age` fallback when `deno.json` does not provide an age, while retaining `deno.json` precedence and reporting an explicit zero opt-out.
46
+ - For pnpm targets before 10.9.0, recommend supported `strictDepBuilds` gating without claiming that the ignored future-version bypass requires pnpm 10.9.0.
47
+ - Keep nested workspace candidates visible when only their ancestor candidate is excluded. Prune traversal only when a trailing `/**` exclusion covers the subtree.
48
+ - Reject workspace patterns whose brace-expanded alternatives contain parent traversal or exceed 8,192 entries before compilation, and avoid backtracking in Aube exclusion matching.
49
+ - Match npm's odd/even interpretation of repeated leading `!` characters.
50
+ - Match Bun's workspace ordering and syntax classification: explicit members remain included, later positive globs can re-include earlier exclusions, and extglob punctuation stays literal.
51
+ - Exclude `CMakeFiles` from Bun glob traversal while retaining explicitly named members below it, matching Bun's walker and literal-member path.
52
+ - Honor npm's ordered cancellation of workspace exclusions, including its handling of adjacent repeated exclusions.
53
+ - Match npm's leading-`#` comment behavior while retaining `#` in nested path segments.
54
+ - Permit colons in ordinary relative workspace segments while continuing to reject absolute and drive-letter paths.
55
+ - Report rejected workspace glob patterns as configuration errors (exit 2) instead of internal crashes (exit 70).
56
+ - Reject non-file manifest inputs before reading, preventing root and workspace FIFO manifests from blocking the scan.
57
+ - Match literal workspace path segments and exclusions case-insensitively on macOS and Windows, so declaration casing does not silently omit members.
58
+ - Use minimatch consistently for workspace membership, exclusions, and traversal. Remove custom brace expansion and globstar matching.
59
+ - Limit workspace traversal using each applicable pattern's own depth, preserving errors from required directory reads.
60
+ - Wait for asynchronous reporters and propagate their failures through the command's error handling.
61
+ - Reject non-file entries at configuration and lockfile paths instead of accepting directories as existing files.
62
+
63
+ ### Verification
64
+
65
+ - Exercise version boundaries, selection precedence, multi-manager isolation, invalid targets, CLI exit codes, custom-rule context, and the installed package's API and strict types.
66
+ - Exercise workspace patterns, exclusions, duplicate matches, malformed child manifests, private roots with public children, injected IO, and installed CLI/API member inspection.
67
+
3
68
  ## [0.4.3]
4
69
 
5
70
  ### Maintenance
package/README.md CHANGED
@@ -38,7 +38,7 @@ The CLI reads `siro.config.*` as executable code. Review repository configuratio
38
38
 
39
39
  ## Features
40
40
 
41
- - **Rules across six managers.** 27 rules covering lifecycle scripts, version pinning, lockfiles
41
+ - **Rules across six managers.** 28 rules covering lifecycle scripts, version pinning, lockfiles
42
42
  (`commit`/`frozen`), release age, publish provenance, `files`/`publishConfig`, SSL enforcement,
43
43
  checksum verification, exotic subdependency blocking, audit suppression review, store integrity,
44
44
  Bun's security scanner API, and Yarn 4's hardened-mode — each mapped to the right setting per
@@ -50,6 +50,12 @@ The CLI reads `siro.config.*` as executable code. Review repository configuratio
50
50
  - **Machine-readable remediation.** A finding can carry automatic key operations or manual
51
51
  instructions. Review proposed changes and rerun the linter after editing.
52
52
  See [docs/json-output.md](docs/json-output.md).
53
+ - **Target PM versions.** Flag settings introduced after the declared or explicit stable PM
54
+ version. See [checked settings and sources](docs/rules.md#checked-introduction-versions)
55
+ for the npm, pnpm, Yarn, Bun, and Deno coverage.
56
+ - **Workspace members.** `--workspaces` adds publication-metadata checks for declared npm,
57
+ pnpm, Yarn, Bun, Deno, and Aube members, including public packages under a private root.
58
+ See [workspace inspection](docs/configuration.md#workspace-members) for scope and exclusions.
53
59
  - **Lint with severities.** `error` fails CI by default; `--severity warn` tightens the gate.
54
60
  - **Reporters.** `pretty` (default), `json` for CI, `github` for PR annotations; register your own.
55
61
  - **Configurable.** Drop a `siro.config.ts` to disable rules, override severities, restrict PMs,
@@ -61,8 +67,10 @@ See the [rule reference](docs/rules.md) for what each check does and why, and th
61
67
  ## Versioning policy
62
68
 
63
69
  siro evaluates the recorded policy snapshot in [docs/policy-sources.md](docs/policy-sources.md).
64
- It detects package-manager names, not effective runtime versions. Version annotations describe
65
- verified upstream facts. A version-dependent safe-default annotation prevents an unverified
70
+ It detects package-manager names and reads exact stable targets from `packageManager`,
71
+ `config.pmVersions`, or `--pm-version`. It does not inspect installed binaries. The
72
+ `unsupported-settings` rule checks recorded introduction versions; unlisted settings and
73
+ unknown targets are not evaluated for availability. A version-dependent safe-default annotation prevents an unverified
66
74
  severity downgrade; it does not prove that the current version satisfies the rule. See
67
75
  [configuration](docs/configuration.md) for defaults, applicability, and limits.
68
76
 
@@ -72,6 +80,8 @@ severity downgrade; it does not prove that the current version satisfies the rul
72
80
  siro <lint|check> [path] [options]
73
81
 
74
82
  --pm <npm|pnpm|yarn|bun|deno|aube> Target a specific package manager (auto-detected; required if detection finds nothing)
83
+ --pm-version <x.y.z> Exact stable target version (requires --pm)
84
+ --workspaces Also inspect workspace members' publication metadata
75
85
  --project-type <application|package> Select application or published-package policy (default auto)
76
86
  --reporter <pretty|json|github> Output format (default pretty)
77
87
  --severity <error|warn|info> Show and fail on findings at or above this level
@@ -99,6 +109,11 @@ Different layer of the supply-chain pipeline; you want both.
99
109
  Adding a rule or a package manager is a localized change — see
100
110
  [docs/contributing.md](docs/contributing.md).
101
111
 
112
+ If siro is useful to you, a [GitHub Star](https://github.com/pHo9UBenaA/siro) would be appreciated.
113
+ Stars help me decide how much time to devote to future features and maintenance.
114
+ Please share feedback from real-world use and feature requests in
115
+ [GitHub Issues](https://github.com/pHo9UBenaA/siro/issues).
116
+
102
117
  ## License
103
118
 
104
119
  MIT
package/dist/cli.mjs CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import { C as SUPPORTED_NODE_RANGE, D as isNodeError, M as UsageError, O as asAbsPath, S as isSeverity, T as assertDirectory, _ as PROJECT_TYPES, b as SEVERITIES, c as DEFAULT_REPORTER_NAME, f as version, j as SiroError, l as JSON_REPORTER_NAME, m as loadConfig, n as lintCommand, s as BUILTIN_REPORTER_NAMES, t as nodeIO, v as isProjectType, w as isSupportedNodeVersion, x as isPM, y as PMS } from "./node-io-B3Hbcwyn.mjs";
2
+ import { C as SUPPORTED_NODE_RANGE, D as isNodeError, M as UsageError, O as asAbsPath, S as isSupportedNodeVersion, T as assertDirectory, _ as isProjectType, a as DEFAULT_REPORTER_NAME, b as isPM, g as PROJECT_TYPES, i as BUILTIN_REPORTER_NAMES, j as SiroError, o as JSON_REPORTER_NAME, p as loadConfig, r as lintCommand, t as nodeIO, v as PMS, w as version, x as isSeverity, y as SEVERITIES } from "./node-io-BDHg4J2w.mjs";
3
3
  import path from "node:path";
4
4
  import { pathToFileURL } from "node:url";
5
5
  import { parseArgs } from "node:util";
@@ -33,6 +33,7 @@ const isCommandName = (value) => COMMANDS.some((cmd) => cmd === value);
33
33
  //#region src/cli/parse-args.ts
34
34
  const VALUE_FLAGS = new Set([
35
35
  "pm",
36
+ "pm-version",
36
37
  "project-type",
37
38
  "reporter",
38
39
  "severity"
@@ -40,7 +41,8 @@ const VALUE_FLAGS = new Set([
40
41
  const BOOLEAN_FLAGS = new Set([
41
42
  "help",
42
43
  "version",
43
- "json"
44
+ "json",
45
+ "workspaces"
44
46
  ]);
45
47
  const parseCommand = (argv) => {
46
48
  const { tokens } = parseArgs({
@@ -110,10 +112,13 @@ const parseCommand = (argv) => {
110
112
  if (extra.length > 0) throw new UsageError(`Unexpected extra argument: ${extra.join(" ")}`);
111
113
  if (flags.has("reporter") && flags.has("json")) throw new UsageError("Invalid reporter selection: use either --reporter or --json.");
112
114
  const reporter = flags.get("reporter");
115
+ const pmVersion = flags.get("pm-version");
113
116
  return {
114
117
  kind: "lint",
115
118
  cwd: asAbsPath(path.resolve(cwd ?? process.cwd())),
116
119
  pm: parsePmFlag(flags.get("pm")),
120
+ pmVersion: typeof pmVersion === "string" ? pmVersion : void 0,
121
+ workspaces: flags.has("workspaces") || void 0,
117
122
  projectType: parseProjectTypeFlag(flags.get("project-type")),
118
123
  severity: parseSeverityFlag(flags.get("severity")),
119
124
  reporter: typeof reporter === "string" ? reporter : flags.has("json") ? JSON_REPORTER_NAME : DEFAULT_REPORTER_NAME
@@ -128,6 +133,8 @@ const SEVERITIES_LIST = SEVERITIES.join("|");
128
133
  const FLAG_LINES = {
129
134
  json: " --json Shortcut for --reporter json",
130
135
  pm: ` --pm <name> Target a specific package manager (${PMS_LIST})`,
136
+ pmVersion: " --pm-version <x.y.z> Target an exact stable PM version (requires --pm)",
137
+ workspaces: " --workspaces Also check workspace members' publication metadata",
131
138
  projectType: ` --project-type <type> Project type (${PROJECT_TYPES_LIST}; default auto)`,
132
139
  reporter: ` --reporter <name> Reporter (${REPORTERS_LIST}; additional reporters can be registered via siro.config.ts)`,
133
140
  severity: ` --severity <level> Show + fail on findings at or above this level (${SEVERITIES_LIST})`
@@ -143,6 +150,8 @@ const HELP_ROOT = [
143
150
  "",
144
151
  "GLOBAL FLAGS",
145
152
  FLAG_LINES.pm,
153
+ FLAG_LINES.pmVersion,
154
+ FLAG_LINES.workspaces,
146
155
  FLAG_LINES.projectType,
147
156
  " --version Print the siro version",
148
157
  " --help Show help for siro or a command",
@@ -171,6 +180,8 @@ const HELP_LINT = [
171
180
  "",
172
181
  "FLAGS",
173
182
  FLAG_LINES.pm,
183
+ FLAG_LINES.pmVersion,
184
+ FLAG_LINES.workspaces,
174
185
  FLAG_LINES.projectType,
175
186
  FLAG_LINES.reporter,
176
187
  FLAG_LINES.json,
package/dist/index.d.mts CHANGED
@@ -1,5 +1,16 @@
1
1
  import * as vb from "valibot";
2
2
 
3
+ //#region src/shared/paths.d.ts
4
+ declare const AbsPathBrand: unique symbol;
5
+ declare const RelPathBrand: unique symbol;
6
+ type AbsPath = string & {
7
+ readonly [AbsPathBrand]: true;
8
+ };
9
+ type RelPath = string & {
10
+ readonly [RelPathBrand]: true;
11
+ };
12
+ declare const asRelPath: (value: string) => RelPath;
13
+ //#endregion
3
14
  //#region src/domain/entities/config-value.d.ts
4
15
  declare const CODEC_KINDS: readonly ["json", "npmrc", "toml", "yaml"];
5
16
  type CodecKind = (typeof CODEC_KINDS)[number];
@@ -16,23 +27,11 @@ type ConfigReadValue = unknown;
16
27
  /** Read an own key path; absent or non-mapping parents yield undefined. */
17
28
  declare const getByPath: (config: ParsedConfig, keyPath: KeyPath) => ConfigReadValue;
18
29
  //#endregion
19
- //#region src/shared/paths.d.ts
20
- declare const AbsPathBrand: unique symbol;
21
- declare const RelPathBrand: unique symbol;
22
- type AbsPath = string & {
23
- readonly [AbsPathBrand]: true;
24
- };
25
- type RelPath = string & {
26
- readonly [RelPathBrand]: true;
27
- };
28
- declare const asAbsPath: (value: string) => AbsPath;
29
- declare const asRelPath: (value: string) => RelPath;
30
- //#endregion
31
- //#region src/domain/ports/file-system.d.ts
32
- /** IO boundary: swap in memfs (or any other backend) for tests. */
33
- interface FileSystem {
34
- readText: (path: AbsPath) => string | undefined;
35
- exists: (path: AbsPath) => boolean;
30
+ //#region src/domain/entities/config-file-ref.d.ts
31
+ /** A repository-relative configuration location, independent of any rule. */
32
+ interface ConfigFileRef {
33
+ readonly kind: CodecKind;
34
+ readonly path: RelPath;
36
35
  }
37
36
  //#endregion
38
37
  //#region src/domain/entities/pms.d.ts
@@ -48,10 +47,6 @@ type Severity = (typeof SEVERITIES)[number];
48
47
  declare const isPM: (value: string) => value is PM;
49
48
  declare const isSeverity: (value: string) => value is Severity;
50
49
  //#endregion
51
- //#region src/domain/entities/project-type.d.ts
52
- declare const PROJECT_TYPES: readonly ["application", "package"];
53
- type ProjectType = (typeof PROJECT_TYPES)[number];
54
- //#endregion
55
50
  //#region src/domain/schemas/package-json.d.ts
56
51
  declare const PackageJsonSchema: vb.LooseObjectSchema<{
57
52
  readonly files: vb.OptionalSchema<vb.ArraySchema<vb.StringSchema<undefined>, undefined>, undefined>;
@@ -65,6 +60,10 @@ declare const PackageJsonSchema: vb.LooseObjectSchema<{
65
60
  }, undefined>;
66
61
  type PackageJson = vb.InferOutput<typeof PackageJsonSchema>;
67
62
  //#endregion
63
+ //#region src/domain/entities/project-type.d.ts
64
+ declare const PROJECT_TYPES: readonly ["application", "package"];
65
+ type ProjectType = (typeof PROJECT_TYPES)[number];
66
+ //#endregion
68
67
  //#region src/domain/ports/repo-context.d.ts
69
68
  /** Read-only view of a repository, passed to every rule's `check`. */
70
69
  interface RepoContext {
@@ -76,14 +75,12 @@ interface RepoContext {
76
75
  }
77
76
  /** Settings read during one evaluation share its parser and cache. */
78
77
  interface RuleContext extends RepoContext {
78
+ /** Declared or explicit stable version of this binding's manager, if known. */
79
+ readonly pmVersion?: string;
79
80
  readConfig: (file: ConfigFileRef) => ParsedConfig;
80
81
  }
81
82
  //#endregion
82
83
  //#region src/domain/entities/rule.d.ts
83
- interface ConfigFileRef {
84
- readonly kind: CodecKind;
85
- readonly path: RelPath;
86
- }
87
84
  interface SetKeyOperation {
88
85
  readonly op: 'setKey';
89
86
  readonly file: ConfigFileRef;
@@ -100,18 +97,24 @@ type Remediation = {
100
97
  readonly steps: readonly [string, ...string[]];
101
98
  readonly operations?: never;
102
99
  };
103
- type CheckStatus = {
104
- readonly state: 'ok';
105
- } | {
106
- readonly state: 'na';
107
- } | {
100
+ interface ViolationStatus {
108
101
  readonly state: 'violation';
109
- readonly message: string; /** Override the primary file when the violation concerns another input. */
102
+ readonly message: string;
103
+ /** File responsible for this individual violation. */
110
104
  readonly file?: RelPath;
111
105
  readonly expected?: ConfigValue;
112
- readonly actual?: ConfigReadValue; /** User configuration takes precedence over this per-result severity. */
106
+ readonly actual?: ConfigReadValue;
107
+ /** User configuration takes precedence over this per-result severity. */
113
108
  readonly severity?: Severity;
114
109
  readonly remediation?: Remediation;
110
+ }
111
+ type CheckStatus = {
112
+ readonly state: 'ok';
113
+ } | {
114
+ readonly state: 'na';
115
+ } | ViolationStatus | {
116
+ readonly state: 'violations'; /** Independent findings; a rule chooses its own grouping granularity. */
117
+ readonly violations: readonly [ViolationStatus, ...ViolationStatus[]];
115
118
  };
116
119
  /** Display-only package-manager version metadata. */
117
120
  interface VersionNote {
@@ -140,9 +143,29 @@ interface Rule<Id extends string = string> {
140
143
  }
141
144
  declare const defineRule: <const Id extends string>(rule: Rule<Id>) => Rule<Id>;
142
145
  //#endregion
146
+ //#region src/domain/ports/file-system.d.ts
147
+ /** IO boundary: swap in memfs (or any other backend) for tests. */
148
+ interface FileSystem {
149
+ /** Ordinary child directory names, excluding symlinks. Required only for workspace discovery. Errors must propagate. */
150
+ readDirectories?: (path: AbsPath) => readonly string[];
151
+ /** Resolve one ordinary child using this filesystem's native name semantics, returning its enumerated name. No symlinks. Undefined for absence; other errors propagate. Without this optional port, Deno literal prefixes use exact names from readDirectories. */
152
+ resolveDirectory?: (parent: AbsPath, name: string) => string | undefined;
153
+ /** Read a regular file (including a symlink to one); undefined only for ENOENT. Other errors and non-file entries must throw. */
154
+ readText: (path: AbsPath) => string | undefined;
155
+ /** True for a regular file (including a symlink to one); false only for ENOENT. Other errors and non-file entries must throw. */
156
+ exists: (path: AbsPath) => boolean;
157
+ }
158
+ //#endregion
159
+ //#region src/domain/ports/date-time.d.ts
160
+ /** Host time and native date parsing, including the host timezone for offsetless input. */
161
+ interface DateTime {
162
+ now: () => number;
163
+ parse: (value: string) => number;
164
+ }
165
+ //#endregion
143
166
  //#region src/domain/builtin-rules.d.ts
144
- declare const rules: readonly [Rule<"advisory-check">, Rule<"approved-git-repos">, Rule<"audit-suppression">, Rule<"block-auto-install">, Rule<"block-exotic-subdeps">, Rule<"bun-security-scanner">, Rule<"checksum-verification">, Rule<"commit-lockfile">, Rule<"dependency-overrides">, Rule<"disable-lifecycle-scripts">, Rule<"enforce-strict-ssl">, Rule<"files-field">, Rule<"frozen-lockfile">, Rule<"frozen-store">, Rule<"hardened-mode">, Rule<"minimum-release-age">, Rule<"named-registries">, Rule<"paranoid-mode">, Rule<"patched-dependencies">, Rule<"pin-exact-versions">, Rule<"provenance">, Rule<"publish-access">, Rule<"store-server">, Rule<"strict-allow-scripts">, Rule<"strict-release-age">, Rule<"strict-store-integrity">, Rule<"trust-policy">];
145
- type BuiltinRuleId = (typeof rules)[number]['id'];
167
+ declare const createBuiltinRules: (time: DateTime) => readonly [Rule<"advisory-check">, Rule<"approved-git-repos">, Rule<"audit-suppression">, Rule<"block-auto-install">, Rule<"block-exotic-subdeps">, Rule<"bun-security-scanner">, Rule<"checksum-verification">, Rule<"commit-lockfile">, Rule<"dependency-overrides">, Rule<"disable-lifecycle-scripts">, Rule<"enforce-strict-ssl">, Rule<"files-field">, Rule<"frozen-lockfile">, Rule<"frozen-store">, Rule<"hardened-mode">, Rule<"minimum-release-age">, Rule<"named-registries">, Rule<"paranoid-mode">, Rule<"patched-dependencies">, Rule<"pin-exact-versions">, Rule<"provenance">, Rule<"publish-access">, Rule<"store-server">, Rule<"strict-allow-scripts">, Rule<"strict-release-age">, Rule<"strict-store-integrity">, Rule<"trust-policy">, Rule<"unsupported-settings">];
168
+ type BuiltinRuleId = ReturnType<typeof createBuiltinRules>[number]['id'];
146
169
  //#endregion
147
170
  //#region src/domain/ports/io.d.ts
148
171
  /** Output sink for commands; injectable so tests can drive a string buffer. */
@@ -172,7 +195,7 @@ interface LintResult {
172
195
  //#region src/domain/ports/reporter.d.ts
173
196
  interface Reporter<Name extends string = string> {
174
197
  readonly name: Name;
175
- format: (result: LintResult, io: IO) => void;
198
+ format: (result: LintResult, io: IO) => void | Promise<void>;
176
199
  }
177
200
  //#endregion
178
201
  //#region src/domain/entities/siro-config.d.ts
@@ -190,6 +213,8 @@ type RuleSetting = Severity | 'off';
190
213
  */
191
214
  interface SiroConfig {
192
215
  readonly pms?: readonly PM[];
216
+ /** Exact stable target versions; does not select managers or inspect installed binaries. */
217
+ readonly pmVersions?: Readonly<Partial<Record<PM, string>>>;
193
218
  readonly projectType?: ProjectType;
194
219
  readonly rules?: Readonly<Partial<Record<BuiltinRuleId | (string & Record<never, never>), RuleSetting>>>;
195
220
  readonly customRules?: readonly Rule[];
@@ -203,11 +228,25 @@ interface LintOptions {
203
228
  readonly cwd: AbsPath;
204
229
  readonly fs?: FileSystem;
205
230
  readonly pm?: PM;
231
+ /** Exact stable version for `pm`; overrides config.pmVersions and packageManager. */
232
+ readonly pmVersion?: string;
233
+ /** Also inspect declared workspace members' publication settings. */
234
+ readonly workspaces?: boolean;
206
235
  readonly projectType?: ProjectType;
207
236
  /** Explicit configuration; the library never imports files from the target repository. */
208
237
  readonly config?: SiroConfig;
209
238
  }
239
+ //#endregion
240
+ //#region src/application/commands/lint.d.ts
241
+ interface LintCommandOptions extends LintOptions {
242
+ readonly reporter?: string | Reporter;
243
+ readonly severity?: Severity;
244
+ }
245
+ //#endregion
246
+ //#region src/composition/lint.d.ts
247
+ /** Public Node API: callers can replace the filesystem without assembling the application. */
210
248
  declare const lint: (options: LintOptions) => LintResult;
249
+ declare const lintCommand: (options: LintCommandOptions, io: IO) => Promise<number>;
211
250
  //#endregion
212
251
  //#region src/adapters/config-loader.d.ts
213
252
  /** Load the first matching config; executable imports always use the real filesystem. */
@@ -236,14 +275,6 @@ declare const BUILTIN_REPORTER_NAMES: readonly BuiltinReporterName[];
236
275
  /** Literal union of every built-in reporter name. */
237
276
  type BuiltinReporterName = (typeof BUILTINS)[number]['name'];
238
277
  //#endregion
239
- //#region src/application/commands/lint.d.ts
240
- interface LintCommandOptions extends LintOptions {
241
- readonly reporter?: string | Reporter;
242
- readonly severity?: Severity;
243
- }
244
- /** Evaluate and report. Executable config loading belongs to the CLI adapter. */
245
- declare const lintCommand: (options: LintCommandOptions, io: IO) => Promise<number>;
246
- //#endregion
247
278
  //#region src/domain/entities/config-files.d.ts
248
279
  /** Known configuration locations and their parsers. */
249
280
  declare const CONFIG_FILES: {
@@ -330,5 +361,8 @@ declare class UsageError extends SiroError {
330
361
  //#region src/version.d.ts
331
362
  declare const version: string;
332
363
  //#endregion
333
- export { type AbsPath, BUILTIN_REPORTER_NAMES, type BuiltinReporterName, CONFIG_FILES, type CheckStatus, ConfigError, type ConfigFileRef, type ConfigReadValue, type ConfigValue, type FileSystem, type Finding, type IO, type KeyPath, type LintCommandOptions, type LintOptions, type LintResult, type PM, PMS, PROJECT_TYPES, type ParsedConfig, type ProjectType, type RelPath, type Remediation, type RepoContext, type Reporter, type RequireConfigKeyOptions, type Rule, type RuleBinding, type RuleContext, type RuleSetting, SEVERITIES, type SetKeyOperation, type Severity, type SiroConfig, SiroError, UsageError, type VersionNote, asAbsPath, asRelPath, defineConfig, defineRule, getByPath, githubReporter, isPM, isSeverity, jsonReporter, lint, lintCommand, loadConfig, nodeFileSystem, nodeIO, overrideBindings, prettyReporter, requireConfigKey, version };
364
+ //#region src/adapters/node-paths.d.ts
365
+ declare const asAbsPath: (value: string) => AbsPath;
366
+ //#endregion
367
+ export { type AbsPath, BUILTIN_REPORTER_NAMES, type BuiltinReporterName, CONFIG_FILES, type CheckStatus, ConfigError, type ConfigFileRef, type ConfigReadValue, type ConfigValue, type FileSystem, type Finding, type IO, type KeyPath, type LintCommandOptions, type LintOptions, type LintResult, type PM, PMS, PROJECT_TYPES, type ParsedConfig, type ProjectType, type RelPath, type Remediation, type RepoContext, type Reporter, type RequireConfigKeyOptions, type Rule, type RuleBinding, type RuleContext, type RuleSetting, SEVERITIES, type SetKeyOperation, type Severity, type SiroConfig, SiroError, UsageError, type VersionNote, type ViolationStatus, asAbsPath, asRelPath, defineConfig, defineRule, getByPath, githubReporter, isPM, isSeverity, jsonReporter, lint, lintCommand, loadConfig, nodeFileSystem, nodeIO, overrideBindings, prettyReporter, requireConfigKey, version };
334
368
  //# sourceMappingURL=index.d.mts.map
package/dist/index.mjs CHANGED
@@ -1,4 +1,4 @@
1
- import { A as ConfigError, E as nodeFileSystem, M as UsageError, O as asAbsPath, S as isSeverity, _ as PROJECT_TYPES, a as overrideBindings, b as SEVERITIES, d as jsonReporter, f as version, g as getByPath, h as defineRule, i as CONFIG_FILES, j as SiroError, k as asRelPath, m as loadConfig, n as lintCommand, o as requireConfigKey, p as githubReporter, r as lint, s as BUILTIN_REPORTER_NAMES, t as nodeIO, u as prettyReporter, x as isPM, y as PMS } from "./node-io-B3Hbcwyn.mjs";
1
+ import { A as ConfigError, E as nodeFileSystem, M as UsageError, O as asAbsPath, b as isPM, c as jsonReporter, d as requireConfigKey, f as CONFIG_FILES, g as PROJECT_TYPES, h as getByPath, i as BUILTIN_REPORTER_NAMES, j as SiroError, k as asRelPath, l as githubReporter, m as defineRule, n as lint, p as loadConfig, r as lintCommand, s as prettyReporter, t as nodeIO, u as overrideBindings, v as PMS, w as version, x as isSeverity, y as SEVERITIES } from "./node-io-BDHg4J2w.mjs";
2
2
  //#region src/domain/entities/siro-config.ts
3
3
  /** Identity helper for type-checked config files. */
4
4
  const defineConfig = (config) => config;