@micelio/eslint-config 0.1.0 → 0.1.2

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/README.md CHANGED
@@ -22,3 +22,11 @@ list, so a repository that adds selectors spreads `promiseChainRestriction` back
22
22
  `@micelio/eslint-config/licenses.json` holds `allowed`, `allowedPrefixes` and
23
23
  `allowedGpl2`: the SPDX identifiers a production dependency may carry (ADR 0007). The
24
24
  repository's `lint:licenses` script reads it and evaluates SPDX expressions against it.
25
+
26
+ ## `lint:standard`
27
+
28
+ `micelio-lint-standard` checks that `docs/engineering-standard.md` is the copy published for the
29
+ version `AGENTS.md` pins (`` `standard: X.Y` ``), using the SHA-256 hashes in
30
+ `@micelio/eslint-config/standard-hashes.json`. Add it as `"lint:standard": "micelio-lint-standard"`
31
+ and to `npm run check`. A pinned version newer than the installed package knows fails with a message
32
+ that says to upgrade the package.
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ export {};
@@ -0,0 +1,11 @@
1
+ #!/usr/bin/env node
2
+ import { lintStandard } from './standard.js';
3
+ // `micelio-lint-standard [root]`: the `lint:standard` script of every Micelio repository.
4
+ const result = lintStandard(process.argv[2] ?? process.cwd());
5
+ if (result.ok) {
6
+ process.stdout.write(`${result.message}\n`);
7
+ }
8
+ else {
9
+ console.error(`error: ${result.message}`);
10
+ process.exitCode = 1;
11
+ }
@@ -0,0 +1,34 @@
1
+ /** Where every Micelio repository keeps its copy of the standard. */
2
+ export declare const STANDARD_PATH = "docs/engineering-standard.md";
3
+ /** The SHA-256 of each released version of the standard, by `major.minor`. */
4
+ export type StandardHashes = Record<string, string>;
5
+ /** What `lintStandard` found. */
6
+ export interface StandardResult {
7
+ /** True when the local copy is the one published for the pinned version. */
8
+ ok: boolean;
9
+ /** One line for the terminal, naming the pinned version. */
10
+ message: string;
11
+ }
12
+ /** Hex SHA-256 of the bytes of a file. */
13
+ export declare function hashOf(content: Buffer | string): string;
14
+ /** Reads the version a repository pins in its `AGENTS.md`, or `null` when there is no pin. */
15
+ export declare function readPin(agents: string): string | null;
16
+ /**
17
+ * Rewrites the pin of an `AGENTS.md`, and the sentence that repeats it, to `version`.
18
+ *
19
+ * @returns The new text, or `null` when `agents` has no pin to rewrite.
20
+ */
21
+ export declare function setPin(agents: string, version: string): string | null;
22
+ /** Reads the version a copy of the standard says it is, or `null` when its header is missing. */
23
+ export declare function standardVersion(standard: string): string | null;
24
+ /** Loads the hashes bundled in this package. */
25
+ export declare function loadHashes(): StandardHashes;
26
+ /**
27
+ * Checks that the copy of the standard in `root` is the one published for the version its
28
+ * `AGENTS.md` pins (standard, section 16). A repository may pin an older version on purpose:
29
+ * the pinned one is checked, not the latest.
30
+ *
31
+ * @param root - The repository root.
32
+ * @param hashes - The published hashes; the ones bundled in this package by default.
33
+ */
34
+ export declare function lintStandard(root: string, hashes?: StandardHashes): StandardResult;
@@ -0,0 +1,82 @@
1
+ import { createHash } from 'node:crypto';
2
+ import { existsSync, readFileSync } from 'node:fs';
3
+ import { join } from 'node:path';
4
+ /** Where every Micelio repository keeps its copy of the standard. */
5
+ export const STANDARD_PATH = 'docs/engineering-standard.md';
6
+ /** The machine-readable pin in `AGENTS.md`: the version in backticks after `standard:`. */
7
+ const PIN = /(`standard:\s*)(\d+\.\d+)(`)/;
8
+ /** The sentence of `AGENTS.md` that says the same in words, kept in step with the pin. */
9
+ const PIN_IN_WORDS = /(follows standard version )(\d+\.\d+)/;
10
+ /** The version line of the standard itself: `Version 1.4 (2026-10-20).` */
11
+ const HEADER = /^Version (\d+\.\d+) /m;
12
+ /** Hex SHA-256 of the bytes of a file. */
13
+ export function hashOf(content) {
14
+ return createHash('sha256').update(content).digest('hex');
15
+ }
16
+ /** Reads the version a repository pins in its `AGENTS.md`, or `null` when there is no pin. */
17
+ export function readPin(agents) {
18
+ return PIN.exec(agents)?.[2] ?? null;
19
+ }
20
+ /**
21
+ * Rewrites the pin of an `AGENTS.md`, and the sentence that repeats it, to `version`.
22
+ *
23
+ * @returns The new text, or `null` when `agents` has no pin to rewrite.
24
+ */
25
+ export function setPin(agents, version) {
26
+ if (!PIN.test(agents))
27
+ return null;
28
+ return agents.replace(PIN, `$1${version}$3`).replace(PIN_IN_WORDS, `$1${version}`);
29
+ }
30
+ /** Reads the version a copy of the standard says it is, or `null` when its header is missing. */
31
+ export function standardVersion(standard) {
32
+ return HEADER.exec(standard)?.[1] ?? null;
33
+ }
34
+ /** Loads the hashes bundled in this package. */
35
+ export function loadHashes() {
36
+ const file = new URL('../standard-hashes.json', import.meta.url);
37
+ return JSON.parse(readFileSync(file, 'utf8'));
38
+ }
39
+ /**
40
+ * Checks that the copy of the standard in `root` is the one published for the version its
41
+ * `AGENTS.md` pins (standard, section 16). A repository may pin an older version on purpose:
42
+ * the pinned one is checked, not the latest.
43
+ *
44
+ * @param root - The repository root.
45
+ * @param hashes - The published hashes; the ones bundled in this package by default.
46
+ */
47
+ export function lintStandard(root, hashes = loadHashes()) {
48
+ const agentsPath = join(root, 'AGENTS.md');
49
+ if (!existsSync(agentsPath)) {
50
+ return {
51
+ ok: false,
52
+ message: 'AGENTS.md is missing: it pins the standard version (`standard: X.Y`).',
53
+ };
54
+ }
55
+ const pin = readPin(readFileSync(agentsPath, 'utf8'));
56
+ if (!pin) {
57
+ return {
58
+ ok: false,
59
+ message: 'AGENTS.md pins no standard version: add `standard: X.Y` (section 16).',
60
+ };
61
+ }
62
+ const copyPath = join(root, STANDARD_PATH);
63
+ if (!existsSync(copyPath)) {
64
+ return { ok: false, message: `${STANDARD_PATH} is missing; AGENTS.md pins standard ${pin}.` };
65
+ }
66
+ const expected = hashes[pin];
67
+ if (!expected) {
68
+ const known = Object.keys(hashes).join(', ');
69
+ return {
70
+ ok: false,
71
+ message: `Standard ${pin}, pinned in AGENTS.md, is unknown to this version of @micelio/eslint-config (it knows ${known}): upgrade the package or fix the pin.`,
72
+ };
73
+ }
74
+ const actual = hashOf(readFileSync(copyPath));
75
+ if (actual !== expected) {
76
+ return {
77
+ ok: false,
78
+ message: `${STANDARD_PATH} does not match standard ${pin}, the version AGENTS.md pins (sha256 ${actual}, published ${expected}). Restore it, or sync it from bogd3v/micelio-engineering.`,
79
+ };
80
+ }
81
+ return { ok: true, message: `Standard ${pin}: ${STANDARD_PATH} matches the published copy.` };
82
+ }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@micelio/eslint-config",
3
- "version": "0.1.0",
4
- "description": "The ESLint flat config of the Micelio repositories, and the licence allowlist behind lint:licenses.",
3
+ "version": "0.1.2",
4
+ "description": "The ESLint flat config of the Micelio repositories, the licence allowlist behind lint:licenses and lint:standard.",
5
5
  "license": "MIT-0",
6
6
  "repository": {
7
7
  "type": "git",
@@ -17,11 +17,13 @@
17
17
  "default": "./dist/index.js"
18
18
  },
19
19
  "./licenses.json": "./licenses.json",
20
- "./package.json": "./package.json"
20
+ "./package.json": "./package.json",
21
+ "./standard-hashes.json": "./standard-hashes.json"
21
22
  },
22
23
  "files": [
23
24
  "dist",
24
25
  "licenses.json",
26
+ "standard-hashes.json",
25
27
  "README.md",
26
28
  "LICENSE"
27
29
  ],
@@ -41,5 +43,11 @@
41
43
  "publishConfig": {
42
44
  "access": "public",
43
45
  "provenance": true
46
+ },
47
+ "bin": {
48
+ "micelio-lint-standard": "./dist/lint-standard.js"
49
+ },
50
+ "devDependencies": {
51
+ "@types/node": "^22.20.5"
44
52
  }
45
53
  }
@@ -0,0 +1,4 @@
1
+ {
2
+ "1.4": "0f1202bbd02a83f216313b84be4744d66ccbee60bc01b39bfc7f67cefd30e139",
3
+ "1.5": "c3ee8aa9a13945e073dedeecbb7ba3a9587ec0ef6878e426eb4be7a0398d93a1"
4
+ }