limina 0.0.2 → 0.0.3

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
@@ -135,7 +135,7 @@ pnpm exec limina package check --package @acme/core
135
135
 
136
136
  ### Checker entry
137
137
 
138
- Each checker has one required `config.checkers.<name>.entry`, usually a `tsconfig*.build.json` graph aggregator. `limina checker build` runs the checker's build execution from that entry when the preset supports it. `limina checker typecheck` walks the same entry, finds reachable `tsconfig*.dts.json` declaration leaves, and checks their paired local companions.
138
+ Each checker has one required `config.checkers.<name>.entry`, usually a `tsconfig*.build.json` graph aggregator. Built-in first-class presets (`tsc` and `vue-tsc`) participate in graph, source, proof, and build checks. Source-only presets such as `svelte-check` prove source coverage and run direct checker execution through `limina checker typecheck`.
139
139
 
140
140
  ### Declaration leaf and local companion
141
141
 
@@ -168,9 +168,8 @@ limina [--config limina.config.mjs] [--mode mode] <command>
168
168
  | `limina paths generate` | Generate compatibility source `paths` configs for artifact-facing workspace exports. |
169
169
  | `limina paths apply` | Compatibility alias for `paths generate`. |
170
170
  | `limina paths check` | Fail when generated path files are stale. |
171
- | `limina checker typecheck` | Run typecheck targets derived from checker entries. |
172
171
  | `limina checker build` | Run build execution for checker entries that support it. |
173
- | `limina checker typecheck --concurrency <n>` | Limit concurrent checker processes. |
172
+ | `limina checker typecheck` | Run source-only checker entries such as `svelte-check`. |
174
173
  | `limina package check` | Run configured package output checks. |
175
174
  | `limina package check --package <name>` | Check one configured package target. |
176
175
  | `limina package check --tool <tool>` | Run only `publint`, `attw`, or `boundary`. |
@@ -198,7 +197,7 @@ config: {
198
197
  }
199
198
  ```
200
199
 
201
- `config.checkers` defines checker entries. Every configured checker must declare a non-empty `entry`. Built-in presets can omit `extensions`; if `source.include` is omitted, Limina derives the source boundary from configured checker extensions, then applies `source.exclude`.
200
+ `config.checkers` defines checker entries. Every configured checker must declare a non-empty `entry` and use a built-in preset. Checker `extensions` are fixed by Limina and cannot be configured; if `source.include` is omitted, Limina derives the source boundary from configured checker extensions, then applies `source.exclude`.
202
201
 
203
202
  ### `graph`
204
203
 
@@ -303,7 +302,7 @@ pipelines: {
303
302
  }
304
303
  ```
305
304
 
306
- `limina check` runs the built-in default pipeline: `graph:check`, `source:check`, `proof:check`, and `checker:typecheck`. `limina check <pipeline>` only runs user pipelines from `limina.config.mjs#pipelines`; if the name is missing, Limina reports the missing pipeline and asks you to define it there.
305
+ `limina check` runs the built-in default pipeline: `graph:check`, `source:check`, `proof:check`, `checker:build`, and `checker:typecheck`. `limina check <pipeline>` only runs user pipelines from `limina.config.mjs#pipelines`; if the name is missing, Limina reports the missing pipeline and asks you to define it there.
307
306
 
308
307
  String steps can be built-in task names or simple commands. Use object command steps when arguments, `cwd`, or `env` need to be explicit.
309
308
 
@@ -35,39 +35,30 @@ function isPathInsideDirectory(filePath, directoryPath) {
35
35
  function createTscCommandTarget(options) {
36
36
  const relativeConfigPath = toRelativePath(options.projectRootDir, options.configPath);
37
37
  return {
38
- args: options.executionKind === "build" ? [
38
+ args: [
39
39
  "-b",
40
40
  relativeConfigPath,
41
41
  "--pretty",
42
42
  "false"
43
- ] : [
44
- "-p",
45
- relativeConfigPath,
46
- "--noEmit"
47
43
  ],
48
44
  command: options.commandOverride ?? "tsc",
49
- label: options.executionKind === "build" ? `tsc -b ${relativeConfigPath}` : `tsc: ${relativeConfigPath}`
45
+ label: `tsc -b ${relativeConfigPath}`
50
46
  };
51
47
  }
52
48
  function createVueTscCommandTarget(options) {
53
49
  const relativeConfigPath = toRelativePath(options.projectRootDir, options.configPath);
54
50
  return {
55
- args: options.executionKind === "build" ? [
51
+ args: [
56
52
  "-b",
57
53
  relativeConfigPath,
58
54
  "--pretty",
59
55
  "false"
60
- ] : [
61
- "-p",
62
- relativeConfigPath,
63
- "--noEmit"
64
56
  ],
65
57
  command: "vue-tsc",
66
- label: options.executionKind === "build" ? `${options.checker.name}: vue-tsc -b ${relativeConfigPath}` : `${options.checker.name}: vue-tsc -p ${relativeConfigPath}`
58
+ label: `${options.checker.name}: vue-tsc -b ${relativeConfigPath}`
67
59
  };
68
60
  }
69
61
  function createSvelteCheckCommandTarget(options) {
70
- if (options.executionKind === "build") throw new Error(`Checker "${options.checker.name}" uses svelte-check, which does not support checker:build.`);
71
62
  const relativeConfigPath = toRelativePath(options.projectRootDir, options.configPath);
72
63
  return {
73
64
  args: ["--tsconfig", relativeConfigPath],
@@ -79,10 +70,11 @@ const builtinCheckerAdapters = {
79
70
  "svelte-check": {
80
71
  createCommandTarget: createSvelteCheckCommandTarget,
81
72
  defaultExtensions: [".svelte"],
82
- graph: false,
83
- packageName: "svelte-check",
73
+ execution: "typecheck",
74
+ packageNames: ["svelte-check"],
84
75
  preset: "svelte-check",
85
- supportedExecutions: ["typecheck"]
76
+ sourceGraph: false,
77
+ tier: "source-only"
86
78
  },
87
79
  tsc: {
88
80
  createCommandTarget: createTscCommandTarget,
@@ -96,18 +88,20 @@ const builtinCheckerAdapters = {
96
88
  ".d.mts",
97
89
  ".json"
98
90
  ],
99
- graph: true,
100
- packageName: "typescript",
91
+ execution: "build",
92
+ packageNames: ["typescript"],
101
93
  preset: "tsc",
102
- supportedExecutions: ["typecheck", "build"]
94
+ sourceGraph: true,
95
+ tier: "first-class"
103
96
  },
104
97
  "vue-tsc": {
105
98
  createCommandTarget: createVueTscCommandTarget,
106
99
  defaultExtensions: [".vue"],
107
- graph: false,
108
- packageName: "vue-tsc",
100
+ execution: "build",
101
+ packageNames: ["vue-tsc", "@vue/compiler-sfc"],
109
102
  preset: "vue-tsc",
110
- supportedExecutions: ["typecheck", "build"]
103
+ sourceGraph: true,
104
+ tier: "first-class"
111
105
  }
112
106
  };
113
107
  function isBuiltinCheckerPreset(value) {
@@ -130,15 +124,16 @@ function collectMissingCheckerPeerDependencies(options) {
130
124
  const resolvePackage = options.resolvePackage ?? resolveCheckerPackageFromRoot;
131
125
  const missingCheckersByPackage = /* @__PURE__ */ new Map();
132
126
  for (const checker of options.checkers) {
133
- const packageName = getCheckerAdapter(checker.preset)?.packageName;
134
- if (!packageName) continue;
135
- if (resolvePackage({
136
- packageName,
137
- projectRootDir: options.projectRootDir
138
- })) continue;
139
- const checkerNames = missingCheckersByPackage.get(packageName) ?? /* @__PURE__ */ new Set();
140
- checkerNames.add(checker.name);
141
- missingCheckersByPackage.set(packageName, checkerNames);
127
+ const packageNames = getCheckerAdapter(checker.preset)?.packageNames ?? [];
128
+ for (const packageName of packageNames) {
129
+ if (resolvePackage({
130
+ packageName,
131
+ projectRootDir: options.projectRootDir
132
+ })) continue;
133
+ const checkerNames = missingCheckersByPackage.get(packageName) ?? /* @__PURE__ */ new Set();
134
+ checkerNames.add(checker.name);
135
+ missingCheckersByPackage.set(packageName, checkerNames);
136
+ }
142
137
  }
143
138
  return [...missingCheckersByPackage.entries()].map(([packageName, checkerNames]) => ({
144
139
  checkerNames: [...checkerNames].sort((left, right) => left.localeCompare(right)),
@@ -157,10 +152,9 @@ function formatMissingCheckerPeerDependencies(missingDependencies) {
157
152
  ].join("\n");
158
153
  }
159
154
  function getCheckerExtensions(checker) {
160
- if (checker.extensions) return normalizeExtensions(checker.extensions);
161
155
  const adapter = getCheckerAdapter(checker.preset);
162
- if (adapter?.defaultExtensions) return normalizeExtensions(adapter.defaultExtensions);
163
- throw new Error(`Checker preset "${checker.preset}" must declare non-empty extensions because it is not a built-in preset.`);
156
+ if (adapter) return normalizeExtensions(adapter.defaultExtensions);
157
+ throw new Error(`Checker preset "${checker.preset}" is not supported.`);
164
158
  }
165
159
  function getResolvedCheckers(config) {
166
160
  const checkers = config.config?.checkers;
@@ -185,11 +179,9 @@ function defineConfig(config) {
185
179
  return config;
186
180
  }
187
181
  const nonEmptyStringSchema = z.string().refine((value) => value.trim().length > 0);
188
- const dotPrefixedStringSchema = nonEmptyStringSchema.refine((value) => value.startsWith("."));
189
182
  const checkerObjectSchema = z.looseObject({});
190
183
  const checkerConfigShapeSchema = z.looseObject({
191
184
  entry: nonEmptyStringSchema,
192
- extensions: z.array(dotPrefixedStringSchema).nonempty().optional(),
193
185
  preset: nonEmptyStringSchema
194
186
  });
195
187
  const liminaConfigShapeSchema = z.looseObject({ config: z.looseObject({ checkers: z.record(z.string(), checkerConfigShapeSchema).optional() }).optional() });
@@ -245,15 +237,6 @@ function formatLiminaConfigShapeIssue(value, issue) {
245
237
  ` value: ${formatUnknownValue(getValueAtPath(value, pathSegments))}`,
246
238
  " reason: checker entry must be a non-empty string path."
247
239
  ].join("\n");
248
- if (pathSegments[3] === "extensions") {
249
- const extensionsPath = pathSegments.slice(0, 4);
250
- return [
251
- "Invalid Limina checker config:",
252
- ` field: ${checkerField}.extensions`,
253
- ` value: ${formatUnknownValue(getValueAtPath(value, extensionsPath))}`,
254
- " reason: checker extensions must be a non-empty array of dot-prefixed strings."
255
- ].join("\n");
256
- }
257
240
  }
258
241
  return [
259
242
  "Invalid Limina config:",
@@ -279,11 +262,11 @@ function collectCheckerConfigProblems(config) {
279
262
  if (!checkerObjectResult.success) continue;
280
263
  const checkerRecord = checkerObjectResult.data;
281
264
  const preset = checkerRecord.preset;
282
- if (checkerRecord.extensions === void 0 && typeof preset === "string" && !isBuiltinCheckerPreset(preset)) problems.push([
265
+ if (Object.hasOwn(checkerRecord, "extensions")) problems.push([
283
266
  "Invalid Limina checker config:",
284
267
  ` field: ${field}.extensions`,
285
- " value: undefined",
286
- " reason: extensions may only be omitted for built-in presets."
268
+ ` value: ${formatUnknownValue(checkerRecord.extensions)}`,
269
+ " reason: checker extensions are fixed by built-in presets and cannot be configured."
287
270
  ].join("\n"));
288
271
  if (Object.hasOwn(checkerRecord, "routes")) problems.push([
289
272
  "Invalid Limina checker config:",
@@ -374,4 +357,4 @@ async function loadConfig(options = {}) {
374
357
  }
375
358
 
376
359
  //#endregion
377
- export { validateLiminaConfig as a, getCheckerAdapter as c, normalizeSlashes as d, normalizeWorkspacePath as f, toRelativePath as h, loadConfig as i, isPathInsideDirectory as l, toPosixPath as m, getActiveCheckerExtensions as n, collectMissingCheckerPeerDependencies as o, toAbsolutePath as p, getActiveCheckers as r, formatMissingCheckerPeerDependencies as s, defineConfig as t, normalizeAbsolutePath as u };
360
+ export { validateLiminaConfig as a, getCheckerAdapter as c, normalizeAbsolutePath as d, normalizeSlashes as f, toRelativePath as g, toPosixPath as h, loadConfig as i, normalizeExtensions as l, toAbsolutePath as m, getActiveCheckerExtensions as n, collectMissingCheckerPeerDependencies as o, normalizeWorkspacePath as p, getActiveCheckers as r, formatMissingCheckerPeerDependencies as s, defineConfig as t, isPathInsideDirectory as u };