@lucern/config 0.3.0-alpha.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/README.md ADDED
@@ -0,0 +1,69 @@
1
+ # @lucern/config
2
+
3
+ Shared Lucern configuration presets for TypeScript, Vitest, and Biome.
4
+
5
+ This package mirrors the current repository toolchain. The repo lint baseline is Biome today, so there is no shared ESLint preset in this release.
6
+
7
+ ## TypeScript
8
+
9
+ Extend the closest matching preset from your package `tsconfig.json`.
10
+
11
+ ```json
12
+ {
13
+ "extends": "@lucern/config/typescript/base",
14
+ "compilerOptions": {
15
+ "outDir": "dist",
16
+ "rootDir": "src"
17
+ },
18
+ "include": ["src/**/*.ts"],
19
+ "exclude": ["node_modules", "dist"]
20
+ }
21
+ ```
22
+
23
+ Available presets:
24
+
25
+ - `@lucern/config/typescript/base`
26
+ - `@lucern/config/typescript/node`
27
+ - `@lucern/config/typescript/convex`
28
+ - `@lucern/config/typescript/nextjs`
29
+
30
+ Add package-local `paths`, `include`, and `exclude` entries in the consumer config. Those settings stay relative to the consuming package, not the shared preset.
31
+
32
+ ## Vitest
33
+
34
+ Import the preset that matches the suite you are running and merge in package-local overrides.
35
+
36
+ ```ts
37
+ import { defineConfig, mergeConfig } from "vitest/config";
38
+ import baseConfig from "@lucern/config/vitest/base";
39
+
40
+ export default mergeConfig(
41
+ baseConfig,
42
+ defineConfig({
43
+ test: {
44
+ include: ["tests/**/*.test.ts"]
45
+ }
46
+ })
47
+ );
48
+ ```
49
+
50
+ Available presets:
51
+
52
+ - `@lucern/config/vitest/base`
53
+ - `@lucern/config/vitest/convex`
54
+ - `@lucern/config/vitest/regression`
55
+ - `@lucern/config/vitest/smoke`
56
+
57
+ The Lucern Vitest presets resolve monorepo aliases from `process.cwd()`, so invoke Vitest from the repository root or a workspace command that runs with the repo root as the working directory.
58
+
59
+ ## Biome
60
+
61
+ Point your `biome.jsonc` `extends` array at the published preset.
62
+
63
+ ```jsonc
64
+ {
65
+ "extends": ["@lucern/config/biome/base"]
66
+ }
67
+ ```
68
+
69
+ The shared Biome preset mirrors the current repository baseline, including the `ultracite` extension. Consumers should keep their own file globs or rule overrides alongside the shared preset when they need package-specific behavior.
@@ -0,0 +1,69 @@
1
+ {
2
+ "$schema": "./node_modules/@biomejs/biome/configuration_schema.json",
3
+ "extends": ["ultracite"],
4
+ "files": {
5
+ "includes": [
6
+ "**/*",
7
+ "!**/.next",
8
+ "!**/.vercel",
9
+ "!**/coverage",
10
+ "!**/dist",
11
+ "!**/node_modules",
12
+ "!**/.turbo",
13
+ "!backups",
14
+ "!convex/_generated",
15
+ "!components/ui",
16
+ "!lib/utils.ts",
17
+ "!hooks/use-mobile.ts"
18
+ ]
19
+ },
20
+ "overrides": [
21
+ {
22
+ "includes": [
23
+ "convex/lucernMcp.ts",
24
+ "convex/qualification.ts",
25
+ "lib/agents/contextManager.ts",
26
+ "lib/agents/qualificationThematic.ts",
27
+ "modules/decision-state/src/convictionEngine.ts",
28
+ "modules/graph-intelligence/src/graphIntel/algorithms/cycleDetection.ts",
29
+ "modules/graph-intelligence/src/graphIntel/algorithms/tarjanSCC.ts",
30
+ "modules/graph-primitives/src/ontologyDefinitions.ts",
31
+ "modules/graph-search/src/epistemicQueries.ts",
32
+ "packages/reasoning-kernel/src/component/ontologyDefinitions.ts",
33
+ "app/lucern/admin/prompt-analytics/ExperimentControl.tsx",
34
+ "scripts/syncProdToDevLogical.ts"
35
+ ],
36
+ "linter": {
37
+ "rules": {
38
+ "style": {
39
+ "useFilenamingConvention": "off"
40
+ }
41
+ }
42
+ }
43
+ }
44
+ ],
45
+ "linter": {
46
+ "rules": {
47
+ "suspicious": {
48
+ "noExplicitAny": "off",
49
+ "noUnknownAtRules": "off",
50
+ "noConsole": "off",
51
+ "noBitwiseOperators": "off"
52
+ },
53
+ "style": {
54
+ "noMagicNumbers": "off",
55
+ "noNestedTernary": "off"
56
+ },
57
+ "nursery": {
58
+ "noUnnecessaryConditions": "off"
59
+ },
60
+ "complexity": {
61
+ "noExcessiveCognitiveComplexity": "off",
62
+ "useSimplifiedLogicExpression": "off"
63
+ },
64
+ "a11y": {
65
+ "noSvgWithoutTitle": "off"
66
+ }
67
+ }
68
+ }
69
+ }
@@ -0,0 +1,4 @@
1
+ {
2
+ "name": "@lucern/config-biome",
3
+ "private": true
4
+ }
package/package.json ADDED
@@ -0,0 +1,32 @@
1
+ {
2
+ "name": "@lucern/config",
3
+ "version": "0.3.0-alpha.0",
4
+ "description": "Shared Lucern TypeScript, Vitest, and Biome configuration presets",
5
+ "type": "module",
6
+ "files": [
7
+ "README.md",
8
+ "biome",
9
+ "typescript",
10
+ "vitest"
11
+ ],
12
+ "exports": {
13
+ "./typescript/base": "./typescript/base.json",
14
+ "./typescript/node": "./typescript/node.json",
15
+ "./typescript/convex": "./typescript/convex.json",
16
+ "./typescript/nextjs": "./typescript/nextjs.json",
17
+ "./vitest/base": "./vitest/base.ts",
18
+ "./vitest/convex": "./vitest/convex.ts",
19
+ "./vitest/regression": "./vitest/regression.ts",
20
+ "./vitest/smoke": "./vitest/smoke.ts",
21
+ "./biome/base": "./biome/base.jsonc"
22
+ },
23
+ "publishConfig": {
24
+ "access": "restricted"
25
+ },
26
+ "scripts": {
27
+ "typecheck": "tsc --noEmit"
28
+ },
29
+ "devDependencies": {
30
+ "typescript": "^5.7.0"
31
+ }
32
+ }
@@ -0,0 +1,20 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES2022",
4
+ "lib": ["ES2022", "DOM", "DOM.Iterable"],
5
+ "module": "ESNext",
6
+ "moduleResolution": "bundler",
7
+ "resolveJsonModule": true,
8
+ "allowJs": true,
9
+ "strict": true,
10
+ "noEmit": true,
11
+ "esModuleInterop": true,
12
+ "isolatedModules": true,
13
+ "skipLibCheck": true,
14
+ "declaration": true,
15
+ "declarationMap": true,
16
+ "sourceMap": true,
17
+ "forceConsistentCasingInFileNames": true
18
+ },
19
+ "exclude": ["node_modules", "dist", ".turbo"]
20
+ }
@@ -0,0 +1,10 @@
1
+ {
2
+ "extends": "./node.json",
3
+ "compilerOptions": {
4
+ "target": "ES2022",
5
+ "lib": ["ES2022"],
6
+ "module": "ESNext",
7
+ "moduleResolution": "bundler",
8
+ "allowJs": false
9
+ }
10
+ }
@@ -0,0 +1,15 @@
1
+ {
2
+ "extends": "./base.json",
3
+ "compilerOptions": {
4
+ "target": "ESNext",
5
+ "lib": ["dom", "dom.iterable", "esnext"],
6
+ "module": "esnext",
7
+ "moduleResolution": "bundler",
8
+ "jsx": "preserve",
9
+ "plugins": [
10
+ {
11
+ "name": "next"
12
+ }
13
+ ]
14
+ }
15
+ }
@@ -0,0 +1,10 @@
1
+ {
2
+ "extends": "./base.json",
3
+ "compilerOptions": {
4
+ "target": "ES2022",
5
+ "lib": ["ES2022"],
6
+ "module": "ESNext",
7
+ "moduleResolution": "bundler",
8
+ "types": ["node"]
9
+ }
10
+ }
@@ -0,0 +1,4 @@
1
+ {
2
+ "name": "@lucern/config-typescript",
3
+ "private": true
4
+ }
package/vitest/base.ts ADDED
@@ -0,0 +1,177 @@
1
+ import path from "node:path";
2
+ import { defineConfig } from "vitest/config";
3
+
4
+ const repoRoot = process.cwd();
5
+
6
+ const testConfig = {
7
+ environment: "jsdom",
8
+ globals: true,
9
+ setupFiles: ["./tests/unit/setup.ts"],
10
+ include: [
11
+ "tests/unit/**/*.test.ts",
12
+ "tests/integration/**/*.test.ts",
13
+ "apps/mcp-server/tests/**/*.test.ts",
14
+ ],
15
+ exclude: [
16
+ "tests/unit/convex/*.test.ts",
17
+ "tests/unit/integration/*.test.ts",
18
+ ],
19
+ environmentMatchGlobs: [["tests/integration/**/*.test.ts", "node"]],
20
+ coverage: {
21
+ provider: "v8",
22
+ reporter: ["text", "json", "html"],
23
+ include: [
24
+ "lib/ai/tools/**/*.ts",
25
+ "convex/epistemic*.ts",
26
+ "convex/lib/**/*.ts",
27
+ "convex/worktrees.ts",
28
+ "convex/contradictions.ts",
29
+ "convex/topics.ts",
30
+ "packages/sdk/src/**/*.ts",
31
+ "packages/mcp/src/**/*.ts",
32
+ "apps/mcp-server/src/handlers/**/*.ts",
33
+ ],
34
+ exclude: ["**/*.test.ts", "**/*.d.ts", "**/node_modules/**"],
35
+ },
36
+ testTimeout: 30_000,
37
+ };
38
+
39
+ export default defineConfig({
40
+ esbuild: {
41
+ jsxInject: `import React from "react"`,
42
+ },
43
+ test: testConfig as any,
44
+ resolve: {
45
+ alias: [
46
+ {
47
+ find: /^@lucern\/contracts\/(.*)$/,
48
+ replacement: path.resolve(repoRoot, "./packages/contracts/src/$1"),
49
+ },
50
+ {
51
+ find: "@lucern/contracts",
52
+ replacement: path.resolve(repoRoot, "./packages/contracts/src/index.ts"),
53
+ },
54
+ {
55
+ find: /^@\/lucern\/contracts\/(.*)$/,
56
+ replacement: path.resolve(repoRoot, "./packages/contracts/src/$1"),
57
+ },
58
+ {
59
+ find: "@lucern/reasoning-kernel/convex.config",
60
+ replacement: path.resolve(
61
+ repoRoot,
62
+ "./packages/reasoning-kernel/convex.config.ts"
63
+ ),
64
+ },
65
+ {
66
+ find: "@lucern/reasoning-kernel/runtime.config",
67
+ replacement: path.resolve(
68
+ repoRoot,
69
+ "./packages/reasoning-kernel/convex.config.ts"
70
+ ),
71
+ },
72
+ {
73
+ find: /^@lucern\/reasoning-kernel\/_generated\/(api|component|dataModel|server)(?:\.js)?$/,
74
+ replacement: path.resolve(
75
+ repoRoot,
76
+ "./packages/reasoning-kernel/src/adapters/_generated/$1.ts"
77
+ ),
78
+ },
79
+ {
80
+ find: "@lucern/reasoning-kernel",
81
+ replacement: path.resolve(
82
+ repoRoot,
83
+ "./packages/reasoning-kernel/src/index.ts"
84
+ ),
85
+ },
86
+ {
87
+ find: /^@lucern\/reasoning-kernel\/([A-Za-z0-9_-]+)$/,
88
+ replacement: path.resolve(
89
+ repoRoot,
90
+ "./packages/reasoning-kernel/src/public/$1.ts"
91
+ ),
92
+ },
93
+ {
94
+ find: /^@lucern\/server-core\/(.*)$/,
95
+ replacement: path.resolve(repoRoot, "./packages/server-core/src/$1"),
96
+ },
97
+ {
98
+ find: "@lucern/server-core",
99
+ replacement: path.resolve(repoRoot, "./packages/server-core/src/index.ts"),
100
+ },
101
+ {
102
+ find: /^@lucern\/testing\/(.*)$/,
103
+ replacement: path.resolve(repoRoot, "./packages/testing/src/$1"),
104
+ },
105
+ {
106
+ find: "@lucern/testing",
107
+ replacement: path.resolve(repoRoot, "./packages/testing/src/index.ts"),
108
+ },
109
+ {
110
+ find: /^@lucern\/events\/(.*)$/,
111
+ replacement: path.resolve(repoRoot, "./packages/events/src/$1"),
112
+ },
113
+ {
114
+ find: "@lucern/events",
115
+ replacement: path.resolve(repoRoot, "./packages/events/src/index.ts"),
116
+ },
117
+ {
118
+ find: "@lucern/identity/convex.config",
119
+ replacement: path.resolve(
120
+ repoRoot,
121
+ "./packages/identity/src/component/convex.config.ts"
122
+ ),
123
+ },
124
+ {
125
+ find: /^@lucern\/identity\/(.*)$/,
126
+ replacement: path.resolve(repoRoot, "./packages/identity/src/$1"),
127
+ },
128
+ {
129
+ find: "@lucern/identity",
130
+ replacement: path.resolve(repoRoot, "./packages/identity/src/index.ts"),
131
+ },
132
+ {
133
+ find: "@lucern/react/surfacePrimitives",
134
+ replacement: path.resolve(
135
+ repoRoot,
136
+ "./packages/sdk-react/src/components/surfacePrimitives.tsx"
137
+ ),
138
+ },
139
+ {
140
+ find: "@lucern/react",
141
+ replacement: path.resolve(repoRoot, "./packages/sdk-react/src/index.ts"),
142
+ },
143
+ {
144
+ find: /^@lucern\/sdk\/(.*)$/,
145
+ replacement: path.resolve(repoRoot, "./packages/sdk/src/$1"),
146
+ },
147
+ {
148
+ find: "@lucern/sdk/realtime/refs",
149
+ replacement: path.resolve(repoRoot, "./packages/sdk/src/realtime/refs.ts"),
150
+ },
151
+ {
152
+ find: "@lucern/sdk/realtime",
153
+ replacement: path.resolve(repoRoot, "./packages/sdk/src/realtime/index.ts"),
154
+ },
155
+ {
156
+ find: "@lucern/mcp/runtime",
157
+ replacement: path.resolve(repoRoot, "./packages/mcp/src/runtime.ts"),
158
+ },
159
+ {
160
+ find: "@lucern/mcp/gateway",
161
+ replacement: path.resolve(repoRoot, "./packages/mcp/src/gateway.ts"),
162
+ },
163
+ {
164
+ find: "@lucern/mcp",
165
+ replacement: path.resolve(repoRoot, "./packages/mcp/src/index.ts"),
166
+ },
167
+ {
168
+ find: "@lucern/sdk",
169
+ replacement: path.resolve(repoRoot, "./packages/sdk/src/index.ts"),
170
+ },
171
+ {
172
+ find: /^@\/(.*)$/,
173
+ replacement: path.resolve(repoRoot, "./$1"),
174
+ },
175
+ ],
176
+ },
177
+ });
@@ -0,0 +1,49 @@
1
+ import path from "node:path";
2
+ import { defineConfig } from "vitest/config";
3
+ import { lucernKernelAliasPlugin } from "./kernelAliasPlugin";
4
+
5
+ const repoRoot = process.cwd();
6
+
7
+ export default defineConfig({
8
+ plugins: [lucernKernelAliasPlugin(repoRoot)],
9
+ test: {
10
+ environment: "node",
11
+ globals: true,
12
+ include: [
13
+ "tests/unit/convex/**/*.test.ts",
14
+ "tests/unit/integration/**/*.test.ts",
15
+ ],
16
+ testTimeout: 30_000,
17
+ alias: {
18
+ "convex/server": path.resolve(repoRoot, "./tests/mocks/convex-server.ts"),
19
+ "convex/values": path.resolve(repoRoot, "./tests/mocks/convex-values.ts"),
20
+ "@lucern/identity": path.resolve(repoRoot, "./packages/identity/src/index.ts"),
21
+ "@lucern/identity/component/schema": path.resolve(
22
+ repoRoot,
23
+ "./packages/identity/src/component/schema.ts"
24
+ ),
25
+ "@lucern/identity/convex.config": path.resolve(
26
+ repoRoot,
27
+ "./packages/identity/src/component/convex.config.ts"
28
+ ),
29
+ "@lucern/react": path.resolve(repoRoot, "./packages/sdk-react/src/index.ts"),
30
+ "@lucern/react/surfacePrimitives": path.resolve(
31
+ repoRoot,
32
+ "./packages/sdk-react/src/components/surfacePrimitives.tsx"
33
+ ),
34
+ },
35
+ coverage: {
36
+ provider: "v8",
37
+ include: [
38
+ "convex/**/*.ts",
39
+ "packages/reasoning-kernel/src/adapters/**/*.ts",
40
+ ],
41
+ exclude: ["**/*.test.ts", "**/*.d.ts", "convex/_generated/**", "**/node_modules/**"],
42
+ },
43
+ },
44
+ resolve: {
45
+ alias: {
46
+ "@": path.resolve(repoRoot, "./"),
47
+ },
48
+ },
49
+ });
@@ -0,0 +1,54 @@
1
+ import { existsSync } from "node:fs";
2
+ import path from "node:path";
3
+
4
+ const KERNEL_PACKAGE = "@lucern/reasoning-kernel";
5
+ const PUBLIC_SUBPATH_ROOT = "packages/reasoning-kernel/src/public";
6
+ const GENERATED_SUBPATH_ROOT = "packages/reasoning-kernel/src/adapters/_generated";
7
+ const CONVEX_CONFIG_PATH = "packages/reasoning-kernel/convex.config.ts";
8
+
9
+ function resolveKernelSubpath(rootDir: string, subpath: string): string | null {
10
+ const cleanSubpath = subpath.replace(/\.m?js$/, "");
11
+
12
+ if (cleanSubpath === "convex.config" || cleanSubpath === "runtime.config") {
13
+ return path.resolve(rootDir, CONVEX_CONFIG_PATH);
14
+ }
15
+
16
+ if (cleanSubpath.startsWith("_generated/")) {
17
+ const generatedPath = path.resolve(
18
+ rootDir,
19
+ GENERATED_SUBPATH_ROOT,
20
+ `${cleanSubpath.slice("_generated/".length)}.ts`
21
+ );
22
+ return existsSync(generatedPath) ? generatedPath : null;
23
+ }
24
+
25
+ const filePath = path.resolve(rootDir, PUBLIC_SUBPATH_ROOT, `${cleanSubpath}.ts`);
26
+ if (existsSync(filePath)) {
27
+ return filePath;
28
+ }
29
+
30
+ const indexPath = path.resolve(rootDir, PUBLIC_SUBPATH_ROOT, cleanSubpath, "index.ts");
31
+ if (existsSync(indexPath)) {
32
+ return indexPath;
33
+ }
34
+
35
+ return null;
36
+ }
37
+
38
+ export function lucernKernelAliasPlugin(rootDir: string) {
39
+ return {
40
+ name: "lucern-kernel-alias",
41
+ enforce: "pre" as const,
42
+ resolveId(source: string) {
43
+ if (source === KERNEL_PACKAGE) {
44
+ return path.resolve(rootDir, "packages/reasoning-kernel/src/index.ts");
45
+ }
46
+
47
+ if (source.startsWith(`${KERNEL_PACKAGE}/`)) {
48
+ return resolveKernelSubpath(rootDir, source.slice(KERNEL_PACKAGE.length + 1));
49
+ }
50
+
51
+ return null;
52
+ },
53
+ };
54
+ }
@@ -0,0 +1,4 @@
1
+ {
2
+ "name": "@lucern/config-vitest",
3
+ "private": true
4
+ }
@@ -0,0 +1,20 @@
1
+ import path from "node:path";
2
+ import { defineConfig } from "vitest/config";
3
+ import { lucernKernelAliasPlugin } from "./kernelAliasPlugin";
4
+
5
+ const repoRoot = process.cwd();
6
+
7
+ export default defineConfig({
8
+ plugins: [lucernKernelAliasPlugin(repoRoot)],
9
+ test: {
10
+ environment: "node",
11
+ globals: true,
12
+ include: ["tests/regression/**/*.test.ts"],
13
+ testTimeout: 15_000,
14
+ },
15
+ resolve: {
16
+ alias: {
17
+ "@": path.resolve(repoRoot, "./"),
18
+ },
19
+ },
20
+ });
@@ -0,0 +1,18 @@
1
+ import path from "node:path";
2
+ import { defineConfig } from "vitest/config";
3
+
4
+ const repoRoot = process.cwd();
5
+
6
+ export default defineConfig({
7
+ test: {
8
+ environment: "node",
9
+ include: ["tests/smoke/**/*.test.ts"],
10
+ testTimeout: 30_000,
11
+ setupFiles: [],
12
+ },
13
+ resolve: {
14
+ alias: {
15
+ "@": path.resolve(repoRoot, "."),
16
+ },
17
+ },
18
+ });