@ogygie/core 0.13.1 → 0.14.0

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ogygie/core",
3
- "version": "0.13.1",
3
+ "version": "0.14.0",
4
4
  "description": "Ogygie framework core: manifest/spec/error schemas, generic tenancy and gate tooling. Ships TypeScript sources — Ogygie products run tsx/vitest by construction (D1).",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -13,28 +13,29 @@
13
13
  "access": "public"
14
14
  },
15
15
  "exports": {
16
- "./manifest": "./src/manifest.schema.ts",
17
- "./manifest-owners": "./src/manifest-owners.ts",
18
- "./vocabulary": "./src/vocabulary.ts",
19
- "./vocabulary-audit": "./src/vocabulary-audit.ts",
20
- "./web-lint": "./src/web-lint.ts",
21
16
  "./bundle-budget": "./src/bundle-budget.ts",
22
- "./spec": "./src/spec.schema.ts",
23
- "./impact": "./src/impact.ts",
24
- "./repo-adapter": "./src/repo-adapter.ts",
17
+ "./client": "./src/manifest-client.ts",
18
+ "./client-react": "./src/manifest-client-react.ts",
19
+ "./clock": "./src/clock.ts",
20
+ "./contract-purity": "./src/contract-purity.ts",
21
+ "./db": "./src/db.ts",
25
22
  "./decision-refs": "./src/decision-refs.ts",
26
23
  "./design-brief": "./src/design-brief.ts",
27
- "./module-purity": "./src/module-purity.ts",
28
- "./contract-purity": "./src/contract-purity.ts",
29
24
  "./errors": "./src/error.schema.ts",
30
- "./db": "./src/db.ts",
31
- "./clock": "./src/clock.ts",
32
- "./tenant": "./src/tenant.ts",
25
+ "./gateway": "./src/manifest-gateway.ts",
26
+ "./impact": "./src/impact.ts",
27
+ "./manifest": "./src/manifest.schema.ts",
28
+ "./manifest-owners": "./src/manifest-owners.ts",
29
+ "./module-purity": "./src/module-purity.ts",
30
+ "./repo-adapter": "./src/repo-adapter.ts",
31
+ "./scan": "./src/scan.ts",
33
32
  "./shared-tables": "./src/shared-tables.ts",
33
+ "./spec": "./src/spec.schema.ts",
34
+ "./tenant": "./src/tenant.ts",
34
35
  "./test-kit": "./src/test-kit.ts",
35
- "./gateway": "./src/manifest-gateway.ts",
36
- "./client": "./src/manifest-client.ts",
37
- "./client-react": "./src/manifest-client-react.ts"
36
+ "./vocabulary": "./src/vocabulary.ts",
37
+ "./vocabulary-audit": "./src/vocabulary-audit.ts",
38
+ "./web-lint": "./src/web-lint.ts"
38
39
  },
39
40
  "peerDependencies": {
40
41
  "@electric-sql/pglite": "^0.3.0",
@@ -0,0 +1,31 @@
1
+ /**
2
+ * @intent Prouve la règle de parcours des gates, avec le cas qui l'a imposée :
3
+ * un projet Nuxt dont `typecheck` génère `.nuxt/` que `lint` refusait ensuite.
4
+ */
5
+ import { describe, expect, it } from "vitest";
6
+ import { isScannableDirectory, NEVER_SCANNED_DIRECTORIES } from "./scan.js";
7
+
8
+ describe("isScannableDirectory", () => {
9
+ it("parcourt le code du projet", () => {
10
+ for (const name of ["apps", "packages", "src", "scripts", "features", "specs"]) {
11
+ expect(isScannableDirectory(name)).toBe(true);
12
+ }
13
+ });
14
+
15
+ it("ne parcourt AUCUN dossier en point — c'est la règle qui ne vieillit pas", () => {
16
+ for (const name of [".git", ".nuxt", ".output", ".next", ".svelte-kit", ".turbo", ".venv"]) {
17
+ expect(isScannableDirectory(name)).toBe(false);
18
+ }
19
+ });
20
+
21
+ it("ne parcourt pas les artefacts au nom ordinaire", () => {
22
+ for (const name of NEVER_SCANNED_DIRECTORIES) expect(isScannableDirectory(name)).toBe(false);
23
+ });
24
+
25
+ it("MUTATION : un dossier dont le nom COMMENCE par celui d'un artefact reste parcouru", () => {
26
+ // `distribution/` n'est pas `dist/`, et `buildings/` n'est pas `build/`.
27
+ expect(isScannableDirectory("distribution")).toBe(true);
28
+ expect(isScannableDirectory("buildings")).toBe(true);
29
+ expect(isScannableDirectory("node_modules_backup")).toBe(true);
30
+ });
31
+ });
package/src/scan.ts ADDED
@@ -0,0 +1,35 @@
1
+ /**
2
+ * @intent Which directories a gate WALKS — the one rule, for every gate.
3
+ *
4
+ * It existed five times, slightly differently, in as many scripts. That is how
5
+ * it fell behind: the lists were written when a build produced `dist/`, and a
6
+ * modern framework generates `.nuxt/`, `.output/`, `.next/`, `.svelte-kit/`,
7
+ * while a Python package carries `.venv/`. A gate that walks into them reports
8
+ * bans and forbidden words found in code NOBODY WROTE — and worse, it does so
9
+ * only after a build, so the loop passes in CI and fails on the machine of
10
+ * whoever just ran it. A consumer project hit exactly that: `typecheck`
11
+ * generated `.nuxt/`, and `lint` then refused a type-suppression directive the
12
+ * framework had written into its own generated types.
13
+ *
14
+ * The rule is deliberately blunt, because a subtle one would fall behind again:
15
+ * a DOT-directory is never source. Everything a project actually writes lives
16
+ * in a plainly-named folder; tooling, caches, virtual environments and build
17
+ * output all hide behind a dot, by a convention older than any of these tools.
18
+ */
19
+
20
+ /** Plainly-named directories that are still artefacts, not source. */
21
+ export const NEVER_SCANNED_DIRECTORIES = [
22
+ "node_modules",
23
+ "dist",
24
+ "dist-ui",
25
+ "build",
26
+ "coverage",
27
+ ] as const;
28
+
29
+ /** Does a gate walk into this directory? Its NAME is the whole question. */
30
+ export function isScannableDirectory(name: string): boolean {
31
+ // `.git`, `.nuxt`, `.output`, `.next`, `.svelte-kit`, `.turbo`, `.venv`,
32
+ // `.pytest_cache`… — one rule instead of a list that ages.
33
+ if (name.startsWith(".")) return false;
34
+ return !(NEVER_SCANNED_DIRECTORIES as readonly string[]).includes(name);
35
+ }