@santi020k/lumen 0.3.0 → 1.0.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 CHANGED
@@ -15,6 +15,18 @@ umbrella package only when you want the framework-neutral CLI or registry APIs:
15
15
  pnpm add @santi020k/lumen
16
16
  ```
17
17
 
18
+ ## Typography
19
+
20
+ Lumen defaults `--ui-font` to the canonical Santi020k Montserrat family stack:
21
+
22
+ ```css
23
+ --ui-font: "Montserrat", "Avenir Next", "Segoe UI", sans-serif;
24
+ ```
25
+
26
+ The package declares the family but does not bundle or load font files. Applications should load
27
+ Montserrat once through their preferred delivery path, or override `--ui-font` when using another
28
+ typeface.
29
+
18
30
  The umbrella package also exposes typed registry metadata and the `lumen` CLI:
19
31
 
20
32
  ```bash
@@ -26,13 +38,26 @@ lumen add Button --target elements
26
38
  lumen add scheduler
27
39
  lumen add scheduler --target react
28
40
  lumen add scheduler --target elements
41
+ lumen add analytics-dashboard
42
+ lumen add saas-admin --target react
43
+ lumen add commerce-dashboard --target elements
29
44
  lumen audit-tokens ./src
45
+ lumen doctor --json
46
+ lumen init --framework astro --tailwind
30
47
  ```
31
48
 
32
49
  Use `lumen add <component>` for a local Astro wrapper, `--target react` for a React wrapper, or
33
50
  `--target elements` for a custom-elements starter. Bundled recipes support the same Astro, React,
34
51
  and Elements targets.
35
52
 
53
+ Complete product recipes are also bundled for `analytics-dashboard`, `saas-admin`,
54
+ `commerce-dashboard`, `project-workspace`, `auth-onboarding`, `docs-shell`, `marketing-shell`,
55
+ `dashboard-shell`, and `validated-form`.
56
+
57
+ Run `lumen doctor` to check adapter/style agreement, Tailwind layer order, Astro runtime mounts,
58
+ and fragile internal selector dependencies. Use `--json` for CI and rollout automation. `lumen
59
+ init --framework <astro|react|elements> [--tailwind]` prints the canonical non-destructive setup.
60
+
36
61
  Run `lumen audit-tokens [path]` before incremental adoption when an existing stylesheet may already
37
62
  declare names such as `--surface`, `--ink`, or `--line`. The audit reports complete CSS colors that
38
63
  are incompatible with Lumen's HSL-channel token format and exits non-zero when it finds conflicts.
@@ -46,8 +71,9 @@ lumen rollout 0.2.0 ../site ../dashboard --exclude ../legacy
46
71
  ```
47
72
 
48
73
  The report separates manifest, workspace-catalog, and lockfile references; identifies each
49
- framework; checks the declared pnpm and Node contracts; and reports the complete resolved Lumen
50
- package graph. Add `--report ./lumen-rollout.json` for a durable JSON record.
74
+ framework; checks the declared pnpm and Node contracts; includes the same integration diagnostics
75
+ as `lumen doctor`; and reports the complete resolved Lumen package graph. Add
76
+ `--report ./lumen-rollout.json` for a durable JSON record.
51
77
 
52
78
  After committing an intentional baseline in each consumer, apply the upgrade serially:
53
79
 
package/dist/cli.js CHANGED
@@ -1,6 +1,7 @@
1
1
  import { readdir, readFile, stat } from 'node:fs/promises';
2
2
  import { resolve } from 'node:path';
3
3
  import { consumerRolloutSucceeded, formatConsumerRollout, runConsumerRollout } from './consumer-rollout.js';
4
+ import { createLumenSetup, formatLumenDiagnostics, inspectLumenIntegration } from './integration-diagnostics.js';
4
5
  import { addLumenRegistryItem, getLumenRegistryEntries, getLumenRegistryItem, loadLumenRegistry, lumenRegistry } from './registry.js';
5
6
  import { auditLumenTokenCss } from './token-audit.js';
6
7
  const args = process.argv.slice(2);
@@ -23,6 +24,10 @@ const allowDirty = args.includes('--allow-dirty');
23
24
  const noVerify = args.includes('--no-verify');
24
25
  const reportIndex = args.indexOf('--report');
25
26
  const reportPath = reportIndex >= 0 ? args[reportIndex + 1] : undefined;
27
+ const frameworkIndex = args.indexOf('--framework');
28
+ const frameworkValue = frameworkIndex >= 0 ? args[frameworkIndex + 1] : undefined;
29
+ const json = args.includes('--json');
30
+ const tailwind = args.includes('--tailwind');
26
31
  const excludeValues = args.flatMap((value, index) => {
27
32
  const nextValue = args[index + 1];
28
33
  return value === '--exclude' && nextValue ? [nextValue] : [];
@@ -58,6 +63,11 @@ const getAddTarget = (value, provided = false) => {
58
63
  return value;
59
64
  throw new Error(`Unknown Lumen add target: ${value}. Use astro, react, or elements.`);
60
65
  };
66
+ const getFramework = (value) => {
67
+ if (value === 'astro' || value === 'elements' || value === 'react')
68
+ return value;
69
+ throw new Error('Missing or invalid framework. Use --framework astro, react, or elements.');
70
+ };
61
71
  if (failOnConflict) {
62
72
  conflict = 'error';
63
73
  }
@@ -75,12 +85,12 @@ const getRegistryItemFiles = (item) => {
75
85
  };
76
86
  const getRegistryItemDescription = (item) => 'description' in item ? item.description : undefined;
77
87
  const getRegistryItemCategory = (item) => 'category' in item ? `category: ${item.category}` : undefined;
78
- const getRegistryItemComponents = (item) => 'components' in item && Array.isArray(item.components) && item.components.length > 0
79
- ? `components: ${item.components.join(', ')}`
80
- : undefined;
81
- const getRegistryItemDependencies = (item) => 'dependencies' in item && item.dependencies.length > 0
82
- ? `dependencies: ${item.dependencies.join(', ')}`
83
- : undefined;
88
+ const getRegistryItemComponents = (item) => 'components' in item && Array.isArray(item.components) && item.components.length > 0 ?
89
+ `components: ${item.components.join(', ')}` :
90
+ undefined;
91
+ const getRegistryItemDependencies = (item) => 'dependencies' in item && item.dependencies.length > 0 ?
92
+ `dependencies: ${item.dependencies.join(', ')}` :
93
+ undefined;
84
94
  const formatItem = (itemName, registry = lumenRegistry) => {
85
95
  const item = getLumenRegistryItem(itemName, registry);
86
96
  if (!item) {
@@ -153,6 +163,8 @@ const help = [
153
163
  ' lumen add <name> Install a recipe or component into the current project',
154
164
  ' lumen install Print install commands',
155
165
  ' lumen audit-tokens Report incompatible semantic color custom properties',
166
+ ' lumen doctor Inspect styles, adapters, runtime mounts, and selector usage',
167
+ ' lumen init Print canonical framework setup without changing files',
156
168
  ' lumen rollout [version] [repositories...] Inventory or upgrade pnpm consumers',
157
169
  '',
158
170
  'Options:',
@@ -164,6 +176,9 @@ const help = [
164
176
  ' --registry <source> Load list/show data from a local or remote registry JSON file',
165
177
  ' --registry-token <key> Use a bearer token for private remote registries',
166
178
  ' --target <framework> Generate wrappers or recipe starters for astro, react, or elements',
179
+ ' --framework <name> Select astro, react, or elements for lumen init',
180
+ ' --tailwind Include the verified Tailwind cascade setup in lumen init',
181
+ ' --json Print lumen doctor output as JSON',
167
182
  ' --apply Apply a rollout (requires a target version)',
168
183
  ' --allow-dirty Allow rollout after recording an uncommitted baseline',
169
184
  ' --exclude <path> Exclude a repository (repeatable)',
@@ -174,9 +189,9 @@ const help = [
174
189
  // eslint-disable-next-line complexity -- Command dispatch keeps CLI exit behavior and output in one place.
175
190
  const run = async () => {
176
191
  let output = help;
177
- const registry = registrySource
178
- ? await loadLumenRegistry(registrySource, registryToken ? { token: registryToken } : {})
179
- : lumenRegistry;
192
+ const registry = registrySource ?
193
+ await loadLumenRegistry(registrySource, registryToken ? { token: registryToken } : {}) :
194
+ lumenRegistry;
180
195
  switch (command) {
181
196
  case 'audit-tokens': {
182
197
  output = await formatTokenAudit(name ?? cwd ?? process.cwd());
@@ -187,6 +202,17 @@ const run = async () => {
187
202
  output = await formatAddResult(name, registry);
188
203
  break;
189
204
  }
205
+ case 'doctor': {
206
+ const report = await inspectLumenIntegration(cwd ?? process.cwd());
207
+ output = json ? JSON.stringify(report, undefined, 2) : formatLumenDiagnostics(report);
208
+ if (!report.healthy)
209
+ process.exitCode = 1;
210
+ break;
211
+ }
212
+ case 'init': {
213
+ output = createLumenSetup(getFramework(frameworkValue), tailwind);
214
+ break;
215
+ }
190
216
  case 'install': {
191
217
  output = 'pnpm add @santi020k/lumen-astro\nnpm install @santi020k/lumen-astro\nyarn add @santi020k/lumen-astro';
192
218
  break;
@@ -1,3 +1,4 @@
1
+ import { type LumenDiagnosticReport } from './integration-diagnostics.js';
1
2
  export type LumenFramework = 'astro' | 'elements' | 'react';
2
3
  export interface ConsumerReference {
3
4
  file: string;
@@ -10,6 +11,7 @@ export interface ConsumerInventory {
10
11
  currentCommit: string | undefined;
11
12
  dirty: boolean;
12
13
  frameworks: LumenFramework[];
14
+ integration: LumenDiagnosticReport;
13
15
  nodeEngine: string | undefined;
14
16
  nodeEngineSatisfied: boolean | undefined;
15
17
  packageManager: string | undefined;
@@ -1 +1 @@
1
- {"version":3,"file":"consumer-rollout.d.ts","sourceRoot":"","sources":["../src/consumer-rollout.ts"],"names":[],"mappings":"AAmBA,MAAM,MAAM,cAAc,GAAG,OAAO,GAAG,UAAU,GAAG,OAAO,CAAA;AAE3D,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAA;IACZ,WAAW,EAAE,MAAM,CAAA;IACnB,MAAM,EAAE,SAAS,GAAG,UAAU,GAAG,UAAU,CAAA;IAC3C,OAAO,EAAE,MAAM,CAAA;CAChB;AAED,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAA;IAC1B,aAAa,EAAE,MAAM,GAAG,SAAS,CAAA;IACjC,KAAK,EAAE,OAAO,CAAA;IACd,UAAU,EAAE,cAAc,EAAE,CAAA;IAC5B,UAAU,EAAE,MAAM,GAAG,SAAS,CAAA;IAC9B,mBAAmB,EAAE,OAAO,GAAG,SAAS,CAAA;IACxC,cAAc,EAAE,MAAM,GAAG,SAAS,CAAA;IAClC,UAAU,EAAE,iBAAiB,EAAE,CAAA;IAC/B,UAAU,EAAE,MAAM,CAAA;IAClB,gBAAgB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAA;IAC1C,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,KAAK,EAAE,OAAO,CAAA;IACd,QAAQ,EAAE,MAAM,EAAE,CAAA;CACnB;AAED,MAAM,WAAW,sBAAsB;IACrC,UAAU,CAAC,EAAE,OAAO,CAAA;IACpB,KAAK,CAAC,EAAE,OAAO,CAAA;IACf,OAAO,CAAC,EAAE,MAAM,EAAE,CAAA;IAClB,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,YAAY,EAAE,MAAM,EAAE,CAAA;IACtB,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,MAAM,CAAC,EAAE,OAAO,CAAA;CACjB;AAED,MAAM,WAAW,qBAAqB;IACpC,WAAW,EAAE,MAAM,CAAA;IACnB,IAAI,EAAE,OAAO,GAAG,WAAW,CAAA;IAC3B,YAAY,EAAE,CAAC,iBAAiB,GAAG;QACjC,QAAQ,EAAE;YAAE,OAAO,EAAE,MAAM,CAAC;YAAC,EAAE,EAAE,OAAO,CAAC;YAAC,MAAM,EAAE,MAAM,CAAA;SAAE,EAAE,CAAA;KAC7D,CAAC,EAAE,CAAA;IACJ,aAAa,CAAC,EAAE,MAAM,CAAA;CACvB;AAED,eAAO,MAAM,wBAAwB,GAAI,QAAQ,qBAAqB,KAAG,OAGtE,CAAA;AA8DH,eAAO,MAAM,mBAAmB,GAC9B,QAAQ,MAAM,GAAG,SAAS,EAC1B,uBAAsC,KACrC,OAAO,GAAG,SAIZ,CAAA;AA+DD,eAAO,MAAM,oBAAoB,GAC/B,YAAY,MAAM,EAClB,gBAAgB,MAAM,KACrB,OAAO,CAAC,iBAAiB,CAiG3B,CAAA;AAUD,eAAO,MAAM,yBAAyB,GACpC,QAAQ,MAAM,EACd,eAAe,MAAM,KACpB,MAYF,CAAA;AAED,eAAO,MAAM,0BAA0B,GACrC,QAAQ,MAAM,EACd,eAAe,MAAM,KACpB,MAIF,CAAA;AAuFD,eAAO,MAAM,mBAAmB,GAAI,QAAQ,MAAM,EAAE,UAAU,MAAM,EAAE,EAAE,SAAS,MAAM,KAAG,MAoCzF,CAAA;AAqGD,eAAO,MAAM,kBAAkB,GAC7B,SAAS,sBAAsB,KAC9B,OAAO,CAAC,qBAAqB,CAmD/B,CAAA;AAED,eAAO,MAAM,qBAAqB,GAAI,QAAQ,qBAAqB,KAAG,MAyBrE,CAAA"}
1
+ {"version":3,"file":"consumer-rollout.d.ts","sourceRoot":"","sources":["../src/consumer-rollout.ts"],"names":[],"mappings":"AAOA,OAAO,EAA2B,KAAK,qBAAqB,EAAE,MAAM,8BAA8B,CAAA;AAQlG,MAAM,MAAM,cAAc,GAAG,OAAO,GAAG,UAAU,GAAG,OAAO,CAAA;AAE3D,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAA;IACZ,WAAW,EAAE,MAAM,CAAA;IACnB,MAAM,EAAE,SAAS,GAAG,UAAU,GAAG,UAAU,CAAA;IAC3C,OAAO,EAAE,MAAM,CAAA;CAChB;AAED,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAA;IAC1B,aAAa,EAAE,MAAM,GAAG,SAAS,CAAA;IACjC,KAAK,EAAE,OAAO,CAAA;IACd,UAAU,EAAE,cAAc,EAAE,CAAA;IAC5B,WAAW,EAAE,qBAAqB,CAAA;IAClC,UAAU,EAAE,MAAM,GAAG,SAAS,CAAA;IAC9B,mBAAmB,EAAE,OAAO,GAAG,SAAS,CAAA;IACxC,cAAc,EAAE,MAAM,GAAG,SAAS,CAAA;IAClC,UAAU,EAAE,iBAAiB,EAAE,CAAA;IAC/B,UAAU,EAAE,MAAM,CAAA;IAClB,gBAAgB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAA;IAC1C,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,KAAK,EAAE,OAAO,CAAA;IACd,QAAQ,EAAE,MAAM,EAAE,CAAA;CACnB;AAED,MAAM,WAAW,sBAAsB;IACrC,UAAU,CAAC,EAAE,OAAO,CAAA;IACpB,KAAK,CAAC,EAAE,OAAO,CAAA;IACf,OAAO,CAAC,EAAE,MAAM,EAAE,CAAA;IAClB,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,YAAY,EAAE,MAAM,EAAE,CAAA;IACtB,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,MAAM,CAAC,EAAE,OAAO,CAAA;CACjB;AAED,MAAM,WAAW,qBAAqB;IACpC,WAAW,EAAE,MAAM,CAAA;IACnB,IAAI,EAAE,OAAO,GAAG,WAAW,CAAA;IAC3B,YAAY,EAAE,CAAC,iBAAiB,GAAG;QACjC,QAAQ,EAAE;YAAE,OAAO,EAAE,MAAM,CAAC;YAAC,EAAE,EAAE,OAAO,CAAC;YAAC,MAAM,EAAE,MAAM,CAAA;SAAE,EAAE,CAAA;KAC7D,CAAC,EAAE,CAAA;IACJ,aAAa,CAAC,EAAE,MAAM,CAAA;CACvB;AAED,eAAO,MAAM,wBAAwB,GAAI,QAAQ,qBAAqB,KAAG,OAExE,CAAA;AA6DD,eAAO,MAAM,mBAAmB,GAC9B,QAAQ,MAAM,GAAG,SAAS,EAC1B,uBAAsC,KACrC,OAAO,GAAG,SAIZ,CAAA;AA4DD,eAAO,MAAM,oBAAoB,GAAU,YAAY,MAAM,EAAE,gBAAgB,MAAM,KAAG,OAAO,CAAC,iBAAiB,CAgGhH,CAAA;AAUD,eAAO,MAAM,yBAAyB,GAAI,QAAQ,MAAM,EAAE,eAAe,MAAM,KAAG,MAYjF,CAAA;AAQD,eAAO,MAAM,0BAA0B,GAAI,QAAQ,MAAM,EAAE,eAAe,MAAM,KAAG,MAQlF,CAAA;AAmFD,eAAO,MAAM,mBAAmB,GAAI,QAAQ,MAAM,EAAE,UAAU,MAAM,EAAE,EAAE,SAAS,MAAM,KAAG,MAoCzF,CAAA;AAsGD,eAAO,MAAM,kBAAkB,GAAU,SAAS,sBAAsB,KAAG,OAAO,CAAC,qBAAqB,CAwCvG,CAAA;AAED,eAAO,MAAM,qBAAqB,GAAI,QAAQ,qBAAqB,KAAG,MAqBrE,CAAA"}
@@ -3,15 +3,11 @@ import { readdir, readFile, stat, writeFile } from 'node:fs/promises';
3
3
  import { join, relative, resolve } from 'node:path';
4
4
  import { promisify } from 'node:util';
5
5
  import { satisfies } from 'semver';
6
+ import { inspectLumenIntegration } from './integration-diagnostics.js';
6
7
  /* eslint-disable complexity -- Consumer inventory, semver checks, mutation, and verification intentionally evaluate full repository contracts. */
7
8
  const execFileAsync = promisify(execFile);
8
9
  const lumenPackagePattern = /^@santi020k\/lumen(?:-(?:astro|core|elements|mcp|react))?$/;
9
- const dependencyFields = [
10
- 'dependencies',
11
- 'devDependencies',
12
- 'optionalDependencies',
13
- 'peerDependencies'
14
- ];
10
+ const dependencyFields = ['dependencies', 'devDependencies', 'optionalDependencies', 'peerDependencies'];
15
11
  export const consumerRolloutSucceeded = (report) => report.repositories.every(repository => repository.valid && repository.commands.every(command => command.ok));
16
12
  const isLumenPackage = (name) => lumenPackagePattern.test(name);
17
13
  const pathExists = async (path) => {
@@ -101,7 +97,7 @@ const getResolvedVersions = (references) => {
101
97
  export const inspectLumenConsumer = async (repository, targetVersion) => {
102
98
  const root = resolve(repository);
103
99
  const rootManifestPath = join(root, 'package.json');
104
- if (!await pathExists(rootManifestPath)) {
100
+ if (!(await pathExists(rootManifestPath))) {
105
101
  throw new Error(`No package.json found at consumer root: ${root}`);
106
102
  }
107
103
  const manifestPaths = await findPackageManifests(root);
@@ -120,12 +116,13 @@ export const inspectLumenConsumer = async (repository, targetVersion) => {
120
116
  references.push(...collectLockReferences(await readFile(lockPath, 'utf8')));
121
117
  }
122
118
  const resolvedVersions = getResolvedVersions(references);
123
- const frameworks = ([
119
+ const frameworks = [
124
120
  references.some(item => item.packageName === '@santi020k/lumen-astro') && 'astro',
125
121
  references.some(item => item.packageName === '@santi020k/lumen-elements') && 'elements',
126
122
  references.some(item => item.packageName === '@santi020k/lumen-react') && 'react'
127
- ].filter(Boolean));
123
+ ].filter(Boolean);
128
124
  const warnings = [];
125
+ const integration = await inspectLumenIntegration(root);
129
126
  const nodeEngineSatisfied = satisfiesNodeEngine(rootManifest.engines?.node);
130
127
  const status = await readGitValue(root, ['status', '--porcelain']);
131
128
  const dirty = Boolean(status);
@@ -158,6 +155,7 @@ export const inspectLumenConsumer = async (repository, targetVersion) => {
158
155
  currentCommit: await readGitValue(root, ['rev-parse', 'HEAD']),
159
156
  dirty,
160
157
  frameworks,
158
+ integration,
161
159
  nodeEngine: rootManifest.engines?.node,
162
160
  nodeEngineSatisfied,
163
161
  packageManager: rootManifest.packageManager,
@@ -165,7 +163,7 @@ export const inspectLumenConsumer = async (repository, targetVersion) => {
165
163
  repository: root,
166
164
  resolvedVersions,
167
165
  ...(targetVersion ? { targetVersion } : {}),
168
- valid: warnings.length === 0,
166
+ valid: warnings.length === 0 && integration.healthy,
169
167
  warnings
170
168
  };
171
169
  };
@@ -186,7 +184,12 @@ export const updateLumenManifestSource = (source, targetVersion) => {
186
184
  }
187
185
  return `${JSON.stringify(manifest, undefined, 2)}\n`;
188
186
  };
189
- export const updateLumenWorkspaceSource = (source, targetVersion) => source.replaceAll(/^(\s*['"]?@santi020k\/lumen(?:-(?:astro|core|elements|mcp|react))?['"]?\s*:\s*['"]?)([~^]?)(\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?)(['"]?\s*(?:#.*)?)$/gm, (_match, before, prefix, _version, after) => `${before}${prefix}${targetVersion}${after}`);
187
+ const lumenWorkspaceVersionPattern = new RegExp([
188
+ String.raw `^(\s*['"]?@santi020k\/lumen`,
189
+ String.raw `(?:-(?:astro|core|elements|mcp|react))?['"]?\s*:\s*['"]?)`,
190
+ String.raw `([~^]?)(\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?)(['"]?\s*(?:#.*)?)$`
191
+ ].join(''), 'gm');
192
+ export const updateLumenWorkspaceSource = (source, targetVersion) => source.replaceAll(lumenWorkspaceVersionPattern, (_match, before, prefix, _version, after) => `${before}${prefix}${targetVersion}${after}`);
190
193
  const getVerificationScripts = (manifest, frameworks) => {
191
194
  const scripts = manifest.scripts ?? {};
192
195
  const preferred = [
@@ -229,7 +232,7 @@ const parseFlowSequence = (source) => {
229
232
  if (character === quote)
230
233
  quote = undefined;
231
234
  }
232
- else if (character === '"' || character === "'") {
235
+ else if (character === '"' || character === '\'') {
233
236
  current += character;
234
237
  quote = character;
235
238
  }
@@ -243,14 +246,15 @@ const parseFlowSequence = (source) => {
243
246
  }
244
247
  if (current.trim())
245
248
  values.push(current);
246
- return values.map(value => {
249
+ return values
250
+ .map(value => {
247
251
  const trimmed = value.trim();
248
- if ((trimmed.startsWith('"') && trimmed.endsWith('"')) ||
249
- (trimmed.startsWith("'") && trimmed.endsWith("'"))) {
252
+ if ((trimmed.startsWith('"') && trimmed.endsWith('"')) || (trimmed.startsWith('\'') && trimmed.endsWith('\''))) {
250
253
  return trimmed.slice(1, -1);
251
254
  }
252
255
  return trimmed;
253
- }).filter(Boolean);
256
+ })
257
+ .filter(Boolean);
254
258
  };
255
259
  export const addReleaseAgeTarget = (source, packages, version) => {
256
260
  if (!/^\s*minimumReleaseAgeExclude\s*:/m.test(source))
@@ -282,7 +286,8 @@ export const addReleaseAgeTarget = (source, packages, version) => {
282
286
  lines.splice(index + 1, 0, ...additions);
283
287
  return lines.join('\n');
284
288
  };
285
- const removeObsoleteReleaseAgeEntries = (source, targetVersion) => source.split(/\r?\n/)
289
+ const removeObsoleteReleaseAgeEntries = (source, targetVersion) => source
290
+ .split(/\r?\n/)
286
291
  .filter(line => {
287
292
  const match = /^\s*-\s*['"]?(@santi020k\/lumen(?:-(?:astro|core|elements|mcp|react))?)@([^'"]+)['"]?\s*$/.exec(line);
288
293
  return !match || match[2] === targetVersion;
@@ -316,12 +321,14 @@ const upgradeConsumer = async (inventory, targetVersion, allowDirty, verify) =>
316
321
  await writeFile(workspacePath, updated);
317
322
  }
318
323
  const packageNames = [...new Set(inventory.references.map(item => item.packageName))];
319
- const commands = [await runCommand(inventory.repository, 'corepack', [
324
+ const commands = [
325
+ await runCommand(inventory.repository, 'corepack', [
320
326
  'pnpm',
321
327
  'update',
322
328
  '--recursive',
323
329
  ...packageNames.map(packageName => `${packageName}@${targetVersion}`)
324
- ])];
330
+ ])
331
+ ];
325
332
  if (!commands[0]?.ok)
326
333
  return commands;
327
334
  for (const [path, source] of desiredManifests) {
@@ -354,8 +361,7 @@ export const runConsumerRollout = async (options) => {
354
361
  throw new Error('A target version is required when applying a consumer rollout.');
355
362
  }
356
363
  const excluded = new Set((options.exclude ?? []).map(path => resolve(path)));
357
- const repositories = options.repositories.map(path => resolve(path))
358
- .filter(path => !excluded.has(path));
364
+ const repositories = options.repositories.map(path => resolve(path)).filter(path => !excluded.has(path));
359
365
  const report = {
360
366
  generatedAt: new Date().toISOString(),
361
367
  mode: options.apply ? 'apply' : 'inventory',
@@ -364,15 +370,13 @@ export const runConsumerRollout = async (options) => {
364
370
  };
365
371
  for (const repository of repositories) {
366
372
  const before = await inspectLumenConsumer(repository, options.targetVersion);
367
- const commands = options.apply
368
- ? await upgradeConsumer(before, options.targetVersion ?? '', options.allowDirty ?? false, options.verify ?? true)
369
- : [];
370
- const after = options.apply
371
- ? await inspectLumenConsumer(repository, options.targetVersion)
372
- : before;
373
+ const commands = options.apply ?
374
+ await upgradeConsumer(before, options.targetVersion ?? '', options.allowDirty ?? false, options.verify ?? true) :
375
+ [];
376
+ const after = options.apply ? await inspectLumenConsumer(repository, options.targetVersion) : before;
373
377
  if (options.apply) {
374
378
  after.warnings = after.warnings.filter(warning => !warning.startsWith('Repository has uncommitted changes'));
375
- after.valid = after.warnings.length === 0;
379
+ after.valid = after.warnings.length === 0 && after.integration.healthy;
376
380
  }
377
381
  report.repositories.push({ ...after, commands });
378
382
  if (commands.some(command => !command.ok))
@@ -391,6 +395,7 @@ export const formatConsumerRollout = (report) => {
391
395
  for (const repository of report.repositories) {
392
396
  lines.push('', repository.repository, ` package manager: ${repository.packageManager ?? 'missing'}`, ` node engine: ${repository.nodeEngine ?? 'unspecified'}`, ` frameworks: ${repository.frameworks.join(', ') || 'none'}`, ` resolved graph: ${JSON.stringify(repository.resolvedVersions)}`, ` status: ${repository.valid && repository.commands.every(command => command.ok) ? 'ok' : 'attention required'}`);
393
397
  lines.push(...repository.warnings.map(warning => ` warning: ${warning}`));
398
+ lines.push(...repository.integration.findings.map(item => ` ${item.severity}: ${item.file} ${item.rule}: ${item.message}`));
394
399
  lines.push(...repository.commands.map(command => ` ${command.ok ? 'pass' : 'fail'}: ${command.command}`));
395
400
  }
396
401
  return lines.join('\n');
package/dist/index.d.ts CHANGED
@@ -1,10 +1,11 @@
1
1
  export { type ConsumerInventory, type ConsumerReference, type ConsumerRolloutOptions, type ConsumerRolloutReport, formatConsumerRollout, inspectLumenConsumer, type LumenFramework, runConsumerRollout, updateLumenManifestSource, updateLumenWorkspaceSource } from './consumer-rollout.js';
2
2
  export { addLumenRegistryItem, getLumenRegistryEntries, getLumenRegistryItem, loadLumenRegistry, type LumenAddOptions, type LumenAddResult, type LumenAddTarget, type LumenMergeConflict, type LumenRegistry, lumenRegistry, type LumenRegistryComponent, type LumenRegistryEntry, type LumenRegistryFile, type LumenRegistryItem, type LumenRegistryLoadOptions } from './registry.js';
3
- export { applyDataViewState, canPlaceScheduleEvent, coerceThemeBuilderExportFormat, coerceThemeBuilderMode, coerceThemeBuilderScheme, composeClassName, createDataViewRequestUrl, createDataViewSearchParams, createDataViewServerRequest, createDataViewState, createDataViewStorageKey, createScheduleSlots, createScheduleStorageKey, createThemeBuilderTokens, createThemePalette, expandRecurringScheduleEvent, exportThemeBuilderCss, exportThemeBuilderValue, exportThemeCss, filterDataRecords, getContrastRatio, getScheduleConflicts, getVirtualRange, loadDataViewState, loadScheduleEvents, type LumenCodeToken, lumenCodeTokenClassNames, type LumenCodeTokenKind, lumenColors, type LumenColorTokenName, lumenColorTokenNames, type LumenComponentName, lumenComponentNames, type LumenContrastScore, lumenDarkTheme, type LumenDataRecord, type LumenDataViewServerRequest, type LumenDataViewState, lumenGlass, type LumenGlassColorTokenName, lumenGlassColorTokenNames, type LumenGlassEffectTokenName, lumenGlassEffectTokenNames, type LumenGlassTokenName, lumenGlassTokenNames, type LumenKeyValueReader, type LumenKeyValueStorage, type LumenKeyValueWriter, lumenLightTheme, lumenPackages, type LumenPackageTarget, type LumenScheduleConflict, type LumenScheduleEvent, type LumenScheduleKeyValueReader, type LumenScheduleKeyValueStorage, type LumenScheduleKeyValueWriter, type LumenScheduleResizeEdge, type LumenScheduleResizeOptions, type LumenScheduleResource, type LumenScheduleSlot, type LumenSemanticColorTokenName, lumenSemanticColorTokenNames, type LumenSortDirection, lumenThemeAttribute, type LumenThemeBuilderExportFormat, type LumenThemeBuilderMode, type LumenThemeBuilderOptions, type LumenThemeBuilderResult, type LumenThemeBuilderScheme, type LumenThemeContrastSuggestion, type LumenThemeTokens, lumenTokenNames, mergeThemeTokens, moveScheduleEvent, normalizeLumenCode, normalizeThemeBuilderHex, normalizeThemeBuilderHue, paginateDataRecords, parseDataViewState, parseScheduleEvents, parseThemeCss, pinDataViewColumn, renderLumenCodeHtml, resizeScheduleEvent, resizeScheduleEvents, saveDataViewState, saveScheduleEvents, scheduleEventsOverlap, scoreThemeContrast, serializeDataViewState, serializeScheduleEvents, sortDataRecords, suggestReadableInk, themeBuilderHexToHsl, toggleDataViewSelection, tokenizeLumenCode, tuneThemeContrast, unpinDataViewColumn } from '@santi020k/lumen-core';
3
+ export { alignLumenChartSeries, applyDataViewState, canPlaceScheduleEvent, coerceThemeBuilderExportFormat, coerceThemeBuilderMode, coerceThemeBuilderScheme, composeClassName, createDataViewRequestUrl, createDataViewSearchParams, createDataViewServerRequest, createDataViewState, createDataViewStorageKey, createLumenBarGeometry, createLumenFormFailure, createLumenFormSuccess, createLumenLineGeometry, createLumenPieGeometry, createScheduleSlots, createScheduleStorageKey, createThemeBuilderTokens, createThemePalette, expandRecurringScheduleEvent, exportThemeBuilderCss, exportThemeBuilderValue, exportThemeCss, filterDataRecords, getContrastRatio, getLumenChartCategories, getLumenChartDomain, getLumenChartTicks, getLumenChartValueRatio, getLumenFieldErrors, getScheduleConflicts, getVirtualRange, hasLumenPieData, loadDataViewState, loadScheduleEvents, type LumenBarChartLayout, type LumenBarGeometry, type LumenBarGeometryCategory, type LumenBarGeometryMark, type LumenBarGeometryOptions, lumenChart, type LumenChartDatum, type LumenChartDomain, type LumenChartGeometryPoint, type LumenChartOrientation, type LumenChartSeries, type LumenChartTone, lumenChartTones, type LumenCodeToken, lumenCodeTokenClassNames, type LumenCodeTokenKind, lumenColors, type LumenColorTokenName, lumenColorTokenNames, type LumenComponentName, lumenComponentNames, type LumenContrastScore, lumenDarkTheme, type LumenDataRecord, type LumenDataViewServerRequest, type LumenDataViewState, type LumenFieldError, type LumenFormErrorInput, type LumenFormErrors, type LumenFormFailure, type LumenFormResult, type LumenFormStatus, lumenFormStatuses, type LumenFormSuccess, lumenGlass, type LumenGlassColorTokenName, lumenGlassColorTokenNames, type LumenGlassEffectTokenName, lumenGlassEffectTokenNames, type LumenGlassTokenName, lumenGlassTokenNames, type LumenKeyValueReader, type LumenKeyValueStorage, type LumenKeyValueWriter, lumenLightTheme, type LumenLineGeometry, type LumenLineGeometryOptions, lumenPackages, type LumenPackageTarget, type LumenPieChartVariant, type LumenPieGeometry, type LumenPieGeometryOptions, type LumenPieGeometrySlice, type LumenScheduleConflict, type LumenScheduleEvent, type LumenScheduleKeyValueReader, type LumenScheduleKeyValueStorage, type LumenScheduleKeyValueWriter, type LumenScheduleResizeEdge, type LumenScheduleResizeOptions, type LumenScheduleResource, type LumenScheduleSlot, type LumenSemanticColorTokenName, lumenSemanticColorTokenNames, type LumenSortDirection, lumenThemeAttribute, type LumenThemeBuilderExportFormat, type LumenThemeBuilderMode, type LumenThemeBuilderOptions, type LumenThemeBuilderResult, type LumenThemeBuilderScheme, type LumenThemeContrastSuggestion, type LumenThemeTokens, lumenTokenNames, mergeThemeTokens, moveScheduleEvent, normalizeLumenCode, normalizeLumenFormErrors, normalizeThemeBuilderHex, normalizeThemeBuilderHue, paginateDataRecords, parseDataViewState, parseScheduleEvents, parseThemeCss, pinDataViewColumn, renderLumenCodeHtml, resizeScheduleEvent, resizeScheduleEvents, resolveLumenChartTone, saveDataViewState, saveScheduleEvents, scaleLumenChartValue, scheduleEventsOverlap, scoreThemeContrast, serializeDataViewState, serializeScheduleEvents, sortDataRecords, suggestReadableInk, themeBuilderHexToHsl, toggleDataViewSelection, tokenizeLumenCode, tuneThemeContrast, unpinDataViewColumn } from '@santi020k/lumen-core';
4
4
  export declare const lumen: {
5
5
  readonly name: "Lumen";
6
6
  readonly packageName: "@santi020k/lumen";
7
7
  readonly scope: "@santi020k";
8
8
  };
9
+ export { createLumenSetup, formatLumenDiagnostics, inspectLumenIntegration, type LumenDiagnosticFinding, type LumenDiagnosticReport, type LumenDiagnosticSeverity } from './integration-diagnostics.js';
9
10
  export { auditLumenTokenCss, type LumenTokenAuditFinding } from './token-audit.js';
10
11
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,iBAAiB,EACtB,KAAK,iBAAiB,EACtB,KAAK,sBAAsB,EAC3B,KAAK,qBAAqB,EAC1B,qBAAqB,EACrB,oBAAoB,EACpB,KAAK,cAAc,EACnB,kBAAkB,EAClB,yBAAyB,EACzB,0BAA0B,EAC3B,MAAM,uBAAuB,CAAA;AAC9B,OAAO,EACL,oBAAoB,EACpB,uBAAuB,EACvB,oBAAoB,EACpB,iBAAiB,EACjB,KAAK,eAAe,EACpB,KAAK,cAAc,EACnB,KAAK,cAAc,EACnB,KAAK,kBAAkB,EACvB,KAAK,aAAa,EAClB,aAAa,EACb,KAAK,sBAAsB,EAC3B,KAAK,kBAAkB,EACvB,KAAK,iBAAiB,EACtB,KAAK,iBAAiB,EACtB,KAAK,wBAAwB,EAC9B,MAAM,eAAe,CAAA;AACtB,OAAO,EACL,kBAAkB,EAClB,qBAAqB,EACrB,8BAA8B,EAC9B,sBAAsB,EACtB,wBAAwB,EACxB,gBAAgB,EAChB,wBAAwB,EACxB,0BAA0B,EAC1B,2BAA2B,EAC3B,mBAAmB,EACnB,wBAAwB,EACxB,mBAAmB,EACnB,wBAAwB,EACxB,wBAAwB,EACxB,kBAAkB,EAClB,4BAA4B,EAC5B,qBAAqB,EACrB,uBAAuB,EACvB,cAAc,EACd,iBAAiB,EACjB,gBAAgB,EAChB,oBAAoB,EACpB,eAAe,EACf,iBAAiB,EACjB,kBAAkB,EAClB,KAAK,cAAc,EACnB,wBAAwB,EACxB,KAAK,kBAAkB,EACvB,WAAW,EACX,KAAK,mBAAmB,EACxB,oBAAoB,EACpB,KAAK,kBAAkB,EACvB,mBAAmB,EACnB,KAAK,kBAAkB,EACvB,cAAc,EACd,KAAK,eAAe,EACpB,KAAK,0BAA0B,EAC/B,KAAK,kBAAkB,EACvB,UAAU,EACV,KAAK,wBAAwB,EAC7B,yBAAyB,EACzB,KAAK,yBAAyB,EAC9B,0BAA0B,EAC1B,KAAK,mBAAmB,EACxB,oBAAoB,EACpB,KAAK,mBAAmB,EACxB,KAAK,oBAAoB,EACzB,KAAK,mBAAmB,EACxB,eAAe,EACf,aAAa,EACb,KAAK,kBAAkB,EACvB,KAAK,qBAAqB,EAC1B,KAAK,kBAAkB,EACvB,KAAK,2BAA2B,EAChC,KAAK,4BAA4B,EACjC,KAAK,2BAA2B,EAChC,KAAK,uBAAuB,EAC5B,KAAK,0BAA0B,EAC/B,KAAK,qBAAqB,EAC1B,KAAK,iBAAiB,EACtB,KAAK,2BAA2B,EAChC,4BAA4B,EAC5B,KAAK,kBAAkB,EACvB,mBAAmB,EACnB,KAAK,6BAA6B,EAClC,KAAK,qBAAqB,EAC1B,KAAK,wBAAwB,EAC7B,KAAK,uBAAuB,EAC5B,KAAK,uBAAuB,EAC5B,KAAK,4BAA4B,EACjC,KAAK,gBAAgB,EACrB,eAAe,EACf,gBAAgB,EAChB,iBAAiB,EACjB,kBAAkB,EAClB,wBAAwB,EACxB,wBAAwB,EACxB,mBAAmB,EACnB,kBAAkB,EAClB,mBAAmB,EACnB,aAAa,EACb,iBAAiB,EACjB,mBAAmB,EACnB,mBAAmB,EACnB,oBAAoB,EACpB,iBAAiB,EACjB,kBAAkB,EAClB,qBAAqB,EACrB,kBAAkB,EAClB,sBAAsB,EACtB,uBAAuB,EACvB,eAAe,EACf,kBAAkB,EAClB,oBAAoB,EACpB,uBAAuB,EACvB,iBAAiB,EACjB,iBAAiB,EACjB,mBAAmB,EACpB,MAAM,uBAAuB,CAAA;AAE9B,eAAO,MAAM,KAAK;;;;CAIR,CAAA;AAEV,OAAO,EACL,kBAAkB,EAClB,KAAK,sBAAsB,EAC5B,MAAM,kBAAkB,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/dist/index.js CHANGED
@@ -1,9 +1,10 @@
1
1
  export { formatConsumerRollout, inspectLumenConsumer, runConsumerRollout, updateLumenManifestSource, updateLumenWorkspaceSource } from './consumer-rollout.js';
2
2
  export { addLumenRegistryItem, getLumenRegistryEntries, getLumenRegistryItem, loadLumenRegistry, lumenRegistry } from './registry.js';
3
- export { applyDataViewState, canPlaceScheduleEvent, coerceThemeBuilderExportFormat, coerceThemeBuilderMode, coerceThemeBuilderScheme, composeClassName, createDataViewRequestUrl, createDataViewSearchParams, createDataViewServerRequest, createDataViewState, createDataViewStorageKey, createScheduleSlots, createScheduleStorageKey, createThemeBuilderTokens, createThemePalette, expandRecurringScheduleEvent, exportThemeBuilderCss, exportThemeBuilderValue, exportThemeCss, filterDataRecords, getContrastRatio, getScheduleConflicts, getVirtualRange, loadDataViewState, loadScheduleEvents, lumenCodeTokenClassNames, lumenColors, lumenColorTokenNames, lumenComponentNames, lumenDarkTheme, lumenGlass, lumenGlassColorTokenNames, lumenGlassEffectTokenNames, lumenGlassTokenNames, lumenLightTheme, lumenPackages, lumenSemanticColorTokenNames, lumenThemeAttribute, lumenTokenNames, mergeThemeTokens, moveScheduleEvent, normalizeLumenCode, normalizeThemeBuilderHex, normalizeThemeBuilderHue, paginateDataRecords, parseDataViewState, parseScheduleEvents, parseThemeCss, pinDataViewColumn, renderLumenCodeHtml, resizeScheduleEvent, resizeScheduleEvents, saveDataViewState, saveScheduleEvents, scheduleEventsOverlap, scoreThemeContrast, serializeDataViewState, serializeScheduleEvents, sortDataRecords, suggestReadableInk, themeBuilderHexToHsl, toggleDataViewSelection, tokenizeLumenCode, tuneThemeContrast, unpinDataViewColumn } from '@santi020k/lumen-core';
3
+ export { alignLumenChartSeries, applyDataViewState, canPlaceScheduleEvent, coerceThemeBuilderExportFormat, coerceThemeBuilderMode, coerceThemeBuilderScheme, composeClassName, createDataViewRequestUrl, createDataViewSearchParams, createDataViewServerRequest, createDataViewState, createDataViewStorageKey, createLumenBarGeometry, createLumenFormFailure, createLumenFormSuccess, createLumenLineGeometry, createLumenPieGeometry, createScheduleSlots, createScheduleStorageKey, createThemeBuilderTokens, createThemePalette, expandRecurringScheduleEvent, exportThemeBuilderCss, exportThemeBuilderValue, exportThemeCss, filterDataRecords, getContrastRatio, getLumenChartCategories, getLumenChartDomain, getLumenChartTicks, getLumenChartValueRatio, getLumenFieldErrors, getScheduleConflicts, getVirtualRange, hasLumenPieData, loadDataViewState, loadScheduleEvents, lumenChart, lumenChartTones, lumenCodeTokenClassNames, lumenColors, lumenColorTokenNames, lumenComponentNames, lumenDarkTheme, lumenFormStatuses, lumenGlass, lumenGlassColorTokenNames, lumenGlassEffectTokenNames, lumenGlassTokenNames, lumenLightTheme, lumenPackages, lumenSemanticColorTokenNames, lumenThemeAttribute, lumenTokenNames, mergeThemeTokens, moveScheduleEvent, normalizeLumenCode, normalizeLumenFormErrors, normalizeThemeBuilderHex, normalizeThemeBuilderHue, paginateDataRecords, parseDataViewState, parseScheduleEvents, parseThemeCss, pinDataViewColumn, renderLumenCodeHtml, resizeScheduleEvent, resizeScheduleEvents, resolveLumenChartTone, saveDataViewState, saveScheduleEvents, scaleLumenChartValue, scheduleEventsOverlap, scoreThemeContrast, serializeDataViewState, serializeScheduleEvents, sortDataRecords, suggestReadableInk, themeBuilderHexToHsl, toggleDataViewSelection, tokenizeLumenCode, tuneThemeContrast, unpinDataViewColumn } from '@santi020k/lumen-core';
4
4
  export const lumen = {
5
5
  name: 'Lumen',
6
6
  packageName: '@santi020k/lumen',
7
7
  scope: '@santi020k'
8
8
  };
9
+ export { createLumenSetup, formatLumenDiagnostics, inspectLumenIntegration } from './integration-diagnostics.js';
9
10
  export { auditLumenTokenCss } from './token-audit.js';
@@ -1 +1 @@
1
- {"version":3,"file":"installer.d.ts","sourceRoot":"","sources":["../src/installer.ts"],"names":[],"mappings":"AAeA,OAAO,EAEL,KAAK,aAAa,EAClB,KAAK,kBAAkB,EAExB,MAAM,eAAe,CAAA;AAOtB,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,EAAE,OAAO,GAAG,OAAO,GAAG,WAAW,GAAG,MAAM,CAAA;IACnD,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,MAAM,CAAC,EAAE,OAAO,CAAA;IAChB,KAAK,CAAC,EAAE,OAAO,CAAA;IACf,KAAK,CAAC,EAAE,CAAC,QAAQ,EAAE,kBAAkB,KAAK,MAAM,CAAA;IAChD,QAAQ,CAAC,EAAE,aAAa,CAAA;IACxB,MAAM,CAAC,EAAE,cAAc,CAAA;CACxB;AAED,MAAM,MAAM,cAAc,GAAG,OAAO,GAAG,UAAU,GAAG,OAAO,CAAA;AAE3D,MAAM,WAAW,kBAAkB;IACjC,QAAQ,EAAE,MAAM,CAAA;IAChB,QAAQ,EAAE,MAAM,CAAA;IAChB,IAAI,EAAE,MAAM,CAAA;CACb;AAED,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,MAAM,EAAE,CAAA;IACf,MAAM,EAAE,OAAO,CAAA;IACf,KAAK,EAAE,MAAM,EAAE,CAAA;IACf,IAAI,EAAE,kBAAkB,CAAA;IACxB,MAAM,EAAE,MAAM,EAAE,CAAA;IAChB,OAAO,EAAE,MAAM,EAAE,CAAA;CAClB;AA4MD,eAAO,MAAM,oBAAoB,GAC/B,MAAM,MAAM,EACZ,UAAS,eAAoB,KAC5B,OAAO,CAAC,cAAc,CA2CxB,CAAA"}
1
+ {"version":3,"file":"installer.d.ts","sourceRoot":"","sources":["../src/installer.ts"],"names":[],"mappings":"AAIA,OAAO,EAEL,KAAK,aAAa,EAClB,KAAK,kBAAkB,EAExB,MAAM,eAAe,CAAA;AAOtB,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,EAAE,OAAO,GAAG,OAAO,GAAG,WAAW,GAAG,MAAM,CAAA;IACnD,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,MAAM,CAAC,EAAE,OAAO,CAAA;IAChB,KAAK,CAAC,EAAE,OAAO,CAAA;IACf,KAAK,CAAC,EAAE,CAAC,QAAQ,EAAE,kBAAkB,KAAK,MAAM,CAAA;IAChD,QAAQ,CAAC,EAAE,aAAa,CAAA;IACxB,MAAM,CAAC,EAAE,cAAc,CAAA;CACxB;AAED,MAAM,MAAM,cAAc,GAAG,OAAO,GAAG,UAAU,GAAG,OAAO,CAAA;AAE3D,MAAM,WAAW,kBAAkB;IACjC,QAAQ,EAAE,MAAM,CAAA;IAChB,QAAQ,EAAE,MAAM,CAAA;IAChB,IAAI,EAAE,MAAM,CAAA;CACb;AAED,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,MAAM,EAAE,CAAA;IACf,MAAM,EAAE,OAAO,CAAA;IACf,KAAK,EAAE,MAAM,EAAE,CAAA;IACf,IAAI,EAAE,kBAAkB,CAAA;IACxB,MAAM,EAAE,MAAM,EAAE,CAAA;IAChB,OAAO,EAAE,MAAM,EAAE,CAAA;CAClB;AAuND,eAAO,MAAM,oBAAoB,GAAU,MAAM,MAAM,EAAE,UAAS,eAAoB,KAAG,OAAO,CAAC,cAAc,CA2C9G,CAAA"}
package/dist/installer.js CHANGED
@@ -1,18 +1,24 @@
1
1
  import { access, mkdir, readdir, readFile, writeFile } from 'node:fs/promises';
2
2
  import { dirname, join, relative, sep } from 'node:path';
3
3
  import { fileURLToPath } from 'node:url';
4
- import { getLumenRegistryItem, } from './registry.js';
4
+ import { getLumenRegistryItem } from './registry.js';
5
5
  const templatesRoot = fileURLToPath(new URL('../templates/', import.meta.url));
6
- const loadRecipeTemplateFiles = async (itemName, target) => {
7
- const templateDir = join(templatesRoot, target, itemName);
6
+ const productTemplateRecipes = new Set([
7
+ 'analytics-dashboard',
8
+ 'auth-onboarding',
9
+ 'commerce-dashboard',
10
+ 'project-workspace',
11
+ 'saas-admin'
12
+ ]);
13
+ const loadTemplateDirectory = async (templateDir) => {
8
14
  let entries;
9
15
  try {
10
16
  entries = await readdir(templateDir, { recursive: true, withFileTypes: true });
11
17
  }
12
18
  catch {
13
- return undefined;
19
+ return [];
14
20
  }
15
- const files = await Promise.all(entries
21
+ return Promise.all(entries
16
22
  .filter(entry => entry.isFile())
17
23
  .map(async (entry) => {
18
24
  const absolutePath = join(entry.parentPath, entry.name);
@@ -21,11 +27,23 @@ const loadRecipeTemplateFiles = async (itemName, target) => {
21
27
  source: await readFile(absolutePath, 'utf8')
22
28
  };
23
29
  }));
24
- files.sort((first, second) => first.path.localeCompare(second.path));
30
+ };
31
+ const loadRecipeTemplateFiles = async (itemName, target) => {
32
+ const templateDirectories = [
33
+ ...(productTemplateRecipes.has(itemName) ? [join(templatesRoot, 'shared', 'common')] : []),
34
+ join(templatesRoot, 'shared', itemName),
35
+ join(templatesRoot, target, itemName)
36
+ ];
37
+ const templateFiles = await Promise.all(templateDirectories.map(loadTemplateDirectory));
38
+ const filesByPath = new Map();
39
+ for (const file of templateFiles.flat()) {
40
+ filesByPath.set(file.path, file);
41
+ }
42
+ const files = [...filesByPath.values()].sort((first, second) => first.path.localeCompare(second.path));
25
43
  return files.length > 0 ? files : undefined;
26
44
  };
27
45
  const toKebabCase = (name) => name.replaceAll(/([a-z0-9])([A-Z])/g, '$1-$2').toLowerCase();
28
- const toCamelCase = (value) => value.replaceAll(/-([a-z])/g, (_match, character) => character.toUpperCase());
46
+ const toCamelCase = (value) => (value.replaceAll(/-([a-z])/g, (_match, character) => character.toUpperCase()));
29
47
  const createAstroComponentFile = (name) => ({
30
48
  path: `src/lumen/${toKebabCase(name)}.astro`,
31
49
  source: `---
@@ -115,7 +133,7 @@ const mergeFileSource = ({ existing, incoming, path }) => {
115
133
  return existing;
116
134
  return `${existing.trimEnd()}\n\n/* Lumen merge: ${path} */\n${incoming}`;
117
135
  };
118
- const getConflictMode = (options) => options.force ? 'overwrite' : options.conflict ?? 'skip';
136
+ const getConflictMode = (options) => (options.force ? 'overwrite' : (options.conflict ?? 'skip'));
119
137
  const getInstallSource = async (file, target, exists, options, conflict) => {
120
138
  if (!exists || conflict !== 'merge')
121
139
  return file.source;
@@ -0,0 +1,21 @@
1
+ export type LumenDiagnosticSeverity = 'advisory' | 'error';
2
+ export interface LumenDiagnosticFinding {
3
+ file: string;
4
+ message: string;
5
+ remediation: string;
6
+ rule: string;
7
+ severity: LumenDiagnosticSeverity;
8
+ }
9
+ export interface LumenDiagnosticReport {
10
+ catalogFingerprint: string;
11
+ findings: LumenDiagnosticFinding[];
12
+ frameworks: ('astro' | 'elements' | 'react')[];
13
+ generatedAt: string;
14
+ healthy: boolean;
15
+ repository: string;
16
+ runtimeComponents: string[];
17
+ }
18
+ export declare const inspectLumenIntegration: (repository: string) => Promise<LumenDiagnosticReport>;
19
+ export declare const formatLumenDiagnostics: (report: LumenDiagnosticReport) => string;
20
+ export declare const createLumenSetup: (framework: "astro" | "elements" | "react", tailwind?: boolean) => string;
21
+ //# sourceMappingURL=integration-diagnostics.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"integration-diagnostics.d.ts","sourceRoot":"","sources":["../src/integration-diagnostics.ts"],"names":[],"mappings":"AAMA,MAAM,MAAM,uBAAuB,GAAG,UAAU,GAAG,OAAO,CAAA;AAE1D,MAAM,WAAW,sBAAsB;IACrC,IAAI,EAAE,MAAM,CAAA;IACZ,OAAO,EAAE,MAAM,CAAA;IACf,WAAW,EAAE,MAAM,CAAA;IACnB,IAAI,EAAE,MAAM,CAAA;IACZ,QAAQ,EAAE,uBAAuB,CAAA;CAClC;AAED,MAAM,WAAW,qBAAqB;IACpC,kBAAkB,EAAE,MAAM,CAAA;IAC1B,QAAQ,EAAE,sBAAsB,EAAE,CAAA;IAClC,UAAU,EAAE,CAAC,OAAO,GAAG,UAAU,GAAG,OAAO,CAAC,EAAE,CAAA;IAC9C,WAAW,EAAE,MAAM,CAAA;IACnB,OAAO,EAAE,OAAO,CAAA;IAChB,UAAU,EAAE,MAAM,CAAA;IAClB,iBAAiB,EAAE,MAAM,EAAE,CAAA;CAC5B;AA8LD,eAAO,MAAM,uBAAuB,GAAU,YAAY,MAAM,KAAG,OAAO,CAAC,qBAAqB,CA+B/F,CAAA;AAED,eAAO,MAAM,sBAAsB,GAAI,QAAQ,qBAAqB,KAAG,MAWtE,CAAA;AAED,eAAO,MAAM,gBAAgB,GAAI,WAAW,OAAO,GAAG,UAAU,GAAG,OAAO,EAAE,kBAAgB,KAAG,MAsC9F,CAAA"}