@refrakt-md/cli 0.24.6 → 0.25.1

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.
@@ -0,0 +1,301 @@
1
+ /** Shared install surface for distributable extensions (SPEC-110).
2
+ *
3
+ * Source *resolution* (directory | tarball | registry → a concrete package
4
+ * name) is common to themes, templates, and preset packs; only the *apply*
5
+ * step differs per artifact (SPEC-110 §4). This module owns resolution,
6
+ * package-manager invocation, refrakt-compat validation (ADR-023), and the
7
+ * multi-site config helpers; the per-artifact apply lives alongside.
8
+ */
9
+ import { existsSync, readFileSync } from 'node:fs';
10
+ import { resolve, isAbsolute } from 'node:path';
11
+ import { gunzipSync } from 'node:zlib';
12
+ import { checkRefraktCompat } from '@refrakt-md/types';
13
+ import { detectPackageManager } from '../config-file.js';
14
+ /** Extract the package name from a registry specifier, handling scopes and an
15
+ * optional `@version` / `@tag` / `@range` suffix. */
16
+ export function parsePackageName(spec) {
17
+ if (spec.startsWith('@')) {
18
+ const slash = spec.indexOf('/');
19
+ if (slash === -1)
20
+ return spec;
21
+ const at = spec.indexOf('@', slash);
22
+ return at === -1 ? spec : spec.slice(0, at);
23
+ }
24
+ const at = spec.indexOf('@');
25
+ return at <= 0 ? spec : spec.slice(0, at);
26
+ }
27
+ /** Read `package/package.json` from an npm `.tgz` (gzip + ustar tar), without a
28
+ * tar dependency — npm tarballs are a flat `package/` tree, so a minimal
29
+ * 512-byte-record scan suffices (SPEC-110 §1). */
30
+ export function readPackageJsonFromTarball(tgzPath) {
31
+ const buf = gunzipSync(readFileSync(tgzPath));
32
+ let offset = 0;
33
+ while (offset + 512 <= buf.length) {
34
+ const header = buf.subarray(offset, offset + 512);
35
+ const name = header.subarray(0, 100).toString('utf-8').replace(/\0.*$/, '');
36
+ if (name === '')
37
+ break; // end-of-archive (zero block)
38
+ const sizeOctal = header.subarray(124, 136).toString('utf-8').replace(/\0.*$/, '').trim();
39
+ const size = sizeOctal ? parseInt(sizeOctal, 8) : 0;
40
+ const contentStart = offset + 512;
41
+ // npm prefixes every entry with "package/"; the manifest is package/package.json
42
+ if (name === 'package/package.json') {
43
+ const content = buf.subarray(contentStart, contentStart + size).toString('utf-8');
44
+ try {
45
+ const pkg = JSON.parse(content);
46
+ return { name: pkg.name, version: pkg.version };
47
+ }
48
+ catch {
49
+ return {};
50
+ }
51
+ }
52
+ offset = contentStart + Math.ceil(size / 512) * 512;
53
+ }
54
+ return {};
55
+ }
56
+ /** Resolve a source (directory | tarball | registry name) to a concrete
57
+ * package name + install source (SPEC-110 §1–§2, §4). Throws on a tarball or
58
+ * directory whose name can't be determined. */
59
+ export function resolveSource(source, cwd = process.cwd()) {
60
+ const abs = isAbsolute(source) ? source : resolve(cwd, source);
61
+ if (existsSync(abs)) {
62
+ if (source.endsWith('.tgz') || source.endsWith('.tar.gz')) {
63
+ const { name, version } = readPackageJsonFromTarball(abs);
64
+ if (!name) {
65
+ throw new Error(`Could not read a package name from tarball "${source}".`);
66
+ }
67
+ return { name, version, installSource: abs, sourceType: 'tarball' };
68
+ }
69
+ const pkgPath = resolve(abs, 'package.json');
70
+ if (!existsSync(pkgPath)) {
71
+ throw new Error(`No package.json found in "${abs}".`);
72
+ }
73
+ const pkg = JSON.parse(readFileSync(pkgPath, 'utf-8'));
74
+ if (!pkg.name) {
75
+ throw new Error(`package.json in "${abs}" is missing a "name" field.`);
76
+ }
77
+ return { name: pkg.name, version: pkg.version, installSource: `file:${abs}`, sourceType: 'directory' };
78
+ }
79
+ // Registry specifier — name resolved up front; version known after install.
80
+ return { name: parsePackageName(source), installSource: source, sourceType: 'registry' };
81
+ }
82
+ /** Build a package-manager add command, optionally pinned to a registry
83
+ * (SPEC-110 §2). Credentials are the package manager's concern, not refrakt's. */
84
+ export function buildInstallCommand(installSource, options = {}) {
85
+ const pm = detectPackageManager(options.cwd);
86
+ const base = pm.installCmd(installSource);
87
+ const cmd = options.registry ? `${base} --registry ${options.registry}` : base;
88
+ return { name: pm.name, cmd };
89
+ }
90
+ /** Read an installed package's manifest from node_modules (post-install). */
91
+ export function readInstalledManifest(cwd, pkgName) {
92
+ const pkgPath = resolve(cwd, 'node_modules', pkgName, 'package.json');
93
+ if (!existsSync(pkgPath))
94
+ return undefined;
95
+ try {
96
+ return JSON.parse(readFileSync(pkgPath, 'utf-8'));
97
+ }
98
+ catch {
99
+ return undefined;
100
+ }
101
+ }
102
+ /** The current refrakt version, read from the CLI's own package.json. */
103
+ export function getProjectRefraktVersion(cwd) {
104
+ // Prefer an installed @refrakt-md/types (the version the project builds against).
105
+ const fromTypes = readInstalledManifest(cwd, '@refrakt-md/types');
106
+ if (fromTypes?.version)
107
+ return String(fromTypes.version);
108
+ const fromTransform = readInstalledManifest(cwd, '@refrakt-md/transform');
109
+ if (fromTransform?.version)
110
+ return String(fromTransform.version);
111
+ return undefined;
112
+ }
113
+ /** Validate a distributable's declared `refrakt` range against the project
114
+ * (ADR-023). Returns a list of human messages: hard errors first, then
115
+ * warnings (e.g. a malformed range). */
116
+ export function validateCompat(declaredRange, projectVersion) {
117
+ const errors = [];
118
+ const warnings = [];
119
+ if (!declaredRange)
120
+ return { errors, warnings };
121
+ if (!projectVersion) {
122
+ warnings.push(`could not determine the project's refrakt version to validate "${declaredRange}"`);
123
+ return { errors, warnings };
124
+ }
125
+ const result = checkRefraktCompat(declaredRange, projectVersion);
126
+ if (!result.ok) {
127
+ if (result.malformed)
128
+ warnings.push(result.message);
129
+ else
130
+ errors.push(result.message);
131
+ }
132
+ return { errors, warnings };
133
+ }
134
+ /** Validate a theme's runtime exports, framework-aware (ADR-024): `./transform`
135
+ * is the required contract; a framework export (`./svelte`, …) is optional and
136
+ * its absence is NOT a warning. Returns warnings only. */
137
+ export function validateThemeExports(manifest) {
138
+ const warnings = [];
139
+ if (!manifest)
140
+ return ['Theme directory not found in node_modules — install may have failed'];
141
+ const exportsMap = (manifest.exports ?? {});
142
+ if (!exportsMap['./transform']) {
143
+ warnings.push('Theme is missing ./transform export — CSS tree-shaking and identity-transform config will be unavailable');
144
+ }
145
+ return warnings;
146
+ }
147
+ /** List the framework component layers a theme provides (ADR-024). Empty = a
148
+ * framework-agnostic theme, which is normal. */
149
+ export function detectFrameworkLayers(manifest) {
150
+ if (!manifest)
151
+ return [];
152
+ const exportsMap = (manifest.exports ?? {});
153
+ const layers = [];
154
+ if (exportsMap['./svelte'] || exportsMap['./svelte/index.js'])
155
+ layers.push('svelte');
156
+ return layers;
157
+ }
158
+ // ─── Preset-pack validation (SPEC-111 §2–§4) ────────────────────────────────
159
+ /** Chrome (skeleton) token keys a `syntax`-scoped preset must NOT set. A syntax
160
+ * preset may touch only `syntax.*` and `color.code.*`; anything else under
161
+ * `color` is chrome and makes it a `palette` preset (SPEC-111 §2). */
162
+ export function presetChromeKeys(config) {
163
+ const keys = new Set();
164
+ const scanColor = (color, prefix) => {
165
+ if (!color || typeof color !== 'object')
166
+ return;
167
+ for (const k of Object.keys(color)) {
168
+ if (k === 'code')
169
+ continue; // code surface is syntax-adjacent, allowed
170
+ keys.add(`${prefix}color.${k}`);
171
+ }
172
+ };
173
+ scanColor(config.color, '');
174
+ const modes = config.modes;
175
+ if (modes && typeof modes === 'object') {
176
+ for (const [mode, layer] of Object.entries(modes)) {
177
+ scanColor(layer?.color, `modes.${mode}.`);
178
+ }
179
+ }
180
+ return [...keys];
181
+ }
182
+ /** Validate one preset entry against its resolved token config (SPEC-111 §2–§4):
183
+ * declared `syntax` that sets chrome → warning; malformed `tunedFor` → warning. */
184
+ export function validatePresetEntry(entry, config) {
185
+ const errors = [];
186
+ const warnings = [];
187
+ const id = typeof entry.id === 'string' ? entry.id : '(unnamed)';
188
+ if (entry.scope !== 'syntax' && entry.scope !== 'palette') {
189
+ errors.push(`preset "${id}" has an invalid scope "${String(entry.scope)}" (expected "syntax" | "palette")`);
190
+ }
191
+ if (entry.tunedFor !== undefined) {
192
+ if (!Array.isArray(entry.tunedFor) || entry.tunedFor.some((t) => typeof t !== 'string')) {
193
+ warnings.push(`preset "${id}" has a malformed "tunedFor" (expected an array of theme package names)`);
194
+ }
195
+ }
196
+ if (config && entry.scope === 'syntax') {
197
+ const chrome = presetChromeKeys(config);
198
+ if (chrome.length > 0) {
199
+ warnings.push(`preset "${id}" is declared scope "syntax" but sets chrome tokens (${chrome.join(', ')}) — it is really a "palette" preset`);
200
+ }
201
+ }
202
+ return { errors, warnings };
203
+ }
204
+ // ─── Multi-site config helpers (SPEC-110 §3) ────────────────────────────────
205
+ /** Enumerate the site keys declared by a config, in either shape. The singular
206
+ * `site` shape reports as the implicit key `default`. */
207
+ export function listSiteKeys(raw) {
208
+ if (raw.site)
209
+ return ['default'];
210
+ if (raw.sites)
211
+ return Object.keys(raw.sites);
212
+ return [];
213
+ }
214
+ /** Resolve which site an install targets.
215
+ * - `existing`: pick the site to update. Inferred when exactly one exists;
216
+ * ambiguous (→ list + exit) when multiple and no `--site`.
217
+ * - `new`: the key must NOT collide with an existing site (full-site templates
218
+ * don't overlay — SPEC-109). */
219
+ export function resolveTargetSite(raw, siteFlag, mode) {
220
+ const keys = listSiteKeys(raw);
221
+ if (mode === 'existing') {
222
+ if (siteFlag) {
223
+ if (!keys.includes(siteFlag)) {
224
+ return { error: `site "${siteFlag}" is not declared in refrakt.config.json`, candidates: keys };
225
+ }
226
+ return { key: siteFlag };
227
+ }
228
+ if (keys.length <= 1)
229
+ return { key: keys[0] ?? 'default' };
230
+ return { error: 'multiple sites declared; pass --site <name> to choose one', candidates: keys };
231
+ }
232
+ // mode === 'new'
233
+ const key = siteFlag ?? 'default';
234
+ if (keys.includes(key)) {
235
+ return { error: `site "${key}" already exists; full-site templates create a new site (choose a fresh --site name)`, candidates: keys };
236
+ }
237
+ return { key };
238
+ }
239
+ /** Read a site's `SiteConfig` from either config shape by key. */
240
+ function getSite(raw, key) {
241
+ if (key === 'default' && raw.site)
242
+ return raw.site;
243
+ return raw.sites?.[key];
244
+ }
245
+ /** Point a site's `theme` field at a package, preserving an existing object
246
+ * form's `presets`/`tokens`/`modes`/`colorScheme`. Returns the previous
247
+ * package name. The site must already exist. */
248
+ export function setSiteTheme(raw, key, pkgName) {
249
+ const apply = (current) => {
250
+ if (current === undefined || typeof current === 'string') {
251
+ return { previous: typeof current === 'string' ? current : undefined, next: pkgName };
252
+ }
253
+ return { previous: current.package, next: { ...current, package: pkgName } };
254
+ };
255
+ const site = getSite(raw, key);
256
+ if (!site) {
257
+ // Fall back to the legacy flat top-level theme.
258
+ const { previous, next } = apply(raw.theme);
259
+ raw.theme = next;
260
+ return previous;
261
+ }
262
+ const { previous, next } = apply(site.theme);
263
+ site.theme = next;
264
+ return previous;
265
+ }
266
+ /** Append a preset module to a site's `theme.presets`, normalising a string
267
+ * theme to the object form. No-op if already present. */
268
+ export function appendSitePreset(raw, key, presetModule) {
269
+ const site = getSite(raw, key);
270
+ if (!site)
271
+ return;
272
+ const theme = site.theme;
273
+ const obj = typeof theme === 'string' ? { package: theme } : { ...(theme ?? { package: '' }) };
274
+ const presets = obj.presets ? [...obj.presets] : [];
275
+ if (!presets.includes(presetModule))
276
+ presets.push(presetModule);
277
+ obj.presets = presets;
278
+ site.theme = obj;
279
+ }
280
+ /** Create a new site entry under `key`, migrating a singular `site:` config to
281
+ * the plural `sites: { default, <key> }` shape when adding a second site
282
+ * (SPEC-110 §3). */
283
+ export function createSite(raw, key, site) {
284
+ if (raw.sites) {
285
+ raw.sites[key] = site;
286
+ return;
287
+ }
288
+ if (raw.site) {
289
+ // Migrate singular → plural.
290
+ raw.sites = { default: raw.site, [key]: site };
291
+ delete raw.site;
292
+ return;
293
+ }
294
+ if (key === 'default') {
295
+ raw.site = site;
296
+ }
297
+ else {
298
+ raw.sites = { [key]: site };
299
+ }
300
+ }
301
+ //# sourceMappingURL=install.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"install.js","sourceRoot":"","sources":["../../src/commands/install.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,33 @@
1
+ /** Preset-pack discovery, listing, and validation (SPEC-111 §4).
2
+ *
3
+ * A preset pack is any installed package carrying a `presets.json` — a
4
+ * capability scanned independently of `kind` (SPEC-111 §1), so a theme that
5
+ * also ships presets is found here too. */
6
+ import type { PresetScope } from '@refrakt-md/types';
7
+ export interface PresetsListOptions {
8
+ scope?: PresetScope;
9
+ }
10
+ export interface PresetsValidateOptions {
11
+ /** Pack package name or directory; defaults to scanning all installed packs. */
12
+ pack?: string;
13
+ }
14
+ export interface PresetsInstallOptions {
15
+ source: string;
16
+ /** Preset id to append to the target site's `theme.presets`. */
17
+ use?: string;
18
+ site?: string;
19
+ registry?: string;
20
+ }
21
+ /** `refrakt theme presets list` — list presets from installed packs + the active
22
+ * theme, filterable by `--scope` and flagged by compatibility (SPEC-111 §4). */
23
+ export declare function themePresetsListCommand(options: PresetsListOptions): Promise<void>;
24
+ /** `refrakt theme presets install <source>` — the lightest apply (SPEC-110 §4):
25
+ * resolve via the shared resolver, add the dependency, validate `presets.json`
26
+ * + compat, and optionally append `--use <id>` to the target site's
27
+ * `theme.presets`. No scaffold-copy, no site creation, no `theme`-field change. */
28
+ export declare function themePresetsInstallCommand(options: PresetsInstallOptions): Promise<void>;
29
+ /** `refrakt theme presets validate` — validate pack manifests: scope vs actual
30
+ * tokens (for JSON-carrier presets), `tunedFor` well-formedness, and module
31
+ * resolvability (SPEC-111 §4). Returns a non-zero exit on errors. */
32
+ export declare function themePresetsValidateCommand(options: PresetsValidateOptions): Promise<void>;
33
+ //# sourceMappingURL=presets.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"presets.d.ts","sourceRoot":"","sources":["../../src/commands/presets.ts"],"names":[],"mappings":"AAAA;;;;4CAI4C;AAI5C,OAAO,KAAK,EAAmC,WAAW,EAAE,MAAM,mBAAmB,CAAC;AActF,MAAM,WAAW,kBAAkB;IAClC,KAAK,CAAC,EAAE,WAAW,CAAC;CACpB;AAED,MAAM,WAAW,sBAAsB;IACtC,gFAAgF;IAChF,IAAI,CAAC,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,qBAAqB;IACrC,MAAM,EAAE,MAAM,CAAC;IACf,gEAAgE;IAChE,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;CAClB;AAmDD;iFACiF;AACjF,wBAAsB,uBAAuB,CAAC,OAAO,EAAE,kBAAkB,GAAG,OAAO,CAAC,IAAI,CAAC,CA+BxF;AAUD;;;oFAGoF;AACpF,wBAAsB,0BAA0B,CAAC,OAAO,EAAE,qBAAqB,GAAG,OAAO,CAAC,IAAI,CAAC,CAyD9F;AAED;;sEAEsE;AACtE,wBAAsB,2BAA2B,CAAC,OAAO,EAAE,sBAAsB,GAAG,OAAO,CAAC,IAAI,CAAC,CAkDhG"}
@@ -0,0 +1,234 @@
1
+ /** Preset-pack discovery, listing, and validation (SPEC-111 §4).
2
+ *
3
+ * A preset pack is any installed package carrying a `presets.json` — a
4
+ * capability scanned independently of `kind` (SPEC-111 §1), so a theme that
5
+ * also ships presets is found here too. */
6
+ import { existsSync, readFileSync, readdirSync } from 'node:fs';
7
+ import { resolve } from 'node:path';
8
+ import { execSync } from 'node:child_process';
9
+ import { loadRefraktConfigFile, writeRefraktConfigFile } from '../config-file.js';
10
+ import { validatePresetEntry, resolveSource, buildInstallCommand, readInstalledManifest, getProjectRefraktVersion, validateCompat, resolveTargetSite, appendSitePreset, } from './install.js';
11
+ /** Find installed packages carrying a `presets.json`. */
12
+ function discoverPacks(cwd) {
13
+ const modulesDir = resolve(cwd, 'node_modules');
14
+ if (!existsSync(modulesDir))
15
+ return [];
16
+ const packs = [];
17
+ const consider = (pkgDir, packageName) => {
18
+ const manifestPath = resolve(pkgDir, 'presets.json');
19
+ if (!existsSync(manifestPath))
20
+ return;
21
+ try {
22
+ const manifest = JSON.parse(readFileSync(manifestPath, 'utf-8'));
23
+ if (Array.isArray(manifest.presets))
24
+ packs.push({ packageName, dir: pkgDir, manifest });
25
+ }
26
+ catch {
27
+ // skip malformed
28
+ }
29
+ };
30
+ const isDir = (e) => e.isDirectory() || e.isSymbolicLink();
31
+ for (const entry of readdirSync(modulesDir, { withFileTypes: true })) {
32
+ if (!isDir(entry))
33
+ continue;
34
+ if (entry.name.startsWith('@')) {
35
+ const scopeDir = resolve(modulesDir, entry.name);
36
+ for (const sub of readdirSync(scopeDir, { withFileTypes: true })) {
37
+ if (isDir(sub))
38
+ consider(resolve(scopeDir, sub.name), `${entry.name}/${sub.name}`);
39
+ }
40
+ }
41
+ else if (!entry.name.startsWith('.')) {
42
+ consider(resolve(modulesDir, entry.name), entry.name);
43
+ }
44
+ }
45
+ return packs;
46
+ }
47
+ /** Active theme package(s) across all sites — used to flag compatibility. */
48
+ function activeThemes(raw) {
49
+ const out = new Set();
50
+ const add = (t) => {
51
+ if (!t)
52
+ return;
53
+ out.add(typeof t === 'string' ? t : t.package);
54
+ };
55
+ if (raw.site)
56
+ add(raw.site.theme);
57
+ for (const site of Object.values(raw.sites ?? {}))
58
+ add(site.theme);
59
+ add(raw.theme);
60
+ return [...out];
61
+ }
62
+ /** `refrakt theme presets list` — list presets from installed packs + the active
63
+ * theme, filterable by `--scope` and flagged by compatibility (SPEC-111 §4). */
64
+ export async function themePresetsListCommand(options) {
65
+ const cwd = process.cwd();
66
+ let raw;
67
+ try {
68
+ raw = loadRefraktConfigFile(cwd).raw;
69
+ }
70
+ catch {
71
+ // listing works without a project config; compatibility flags are just omitted
72
+ }
73
+ const themes = raw ? activeThemes(raw) : [];
74
+ const packs = discoverPacks(cwd);
75
+ if (packs.length === 0) {
76
+ console.log('No preset packs (packages with presets.json) found in node_modules.');
77
+ return;
78
+ }
79
+ let total = 0;
80
+ for (const pack of packs) {
81
+ const entries = pack.manifest.presets.filter((p) => !options.scope || p.scope === options.scope);
82
+ if (entries.length === 0)
83
+ continue;
84
+ console.log(`\n${pack.packageName}:`);
85
+ for (const p of entries) {
86
+ total++;
87
+ console.log(` ${formatEntry(p, themes)}`);
88
+ }
89
+ }
90
+ if (total === 0) {
91
+ console.log(`No presets${options.scope ? ` with scope "${options.scope}"` : ''} found.`);
92
+ }
93
+ else if (themes.length) {
94
+ console.log(`\n ⚠ = palette preset not tuned for the active theme (${themes.join(', ')}); still applies, may need adjustment`);
95
+ }
96
+ }
97
+ function formatEntry(p, activeThemeNames) {
98
+ const ref = `${p.id} — ${p.title} [${p.scope}]`;
99
+ // Universal (syntax, or no tunedFor) is always compatible.
100
+ if (p.scope === 'syntax' || !p.tunedFor || p.tunedFor.length === 0)
101
+ return ref;
102
+ const tuned = activeThemeNames.some((t) => p.tunedFor.includes(t));
103
+ return tuned ? ref : `⚠ ${ref}`;
104
+ }
105
+ /** `refrakt theme presets install <source>` — the lightest apply (SPEC-110 §4):
106
+ * resolve via the shared resolver, add the dependency, validate `presets.json`
107
+ * + compat, and optionally append `--use <id>` to the target site's
108
+ * `theme.presets`. No scaffold-copy, no site creation, no `theme`-field change. */
109
+ export async function themePresetsInstallCommand(options) {
110
+ const cwd = process.cwd();
111
+ let resolved;
112
+ try {
113
+ resolved = resolveSource(options.source, cwd);
114
+ }
115
+ catch (err) {
116
+ console.error(`Error: ${err.message}`);
117
+ process.exit(1);
118
+ }
119
+ const { name: pmName, cmd } = buildInstallCommand(resolved.installSource, { registry: options.registry, cwd });
120
+ console.log(`Using ${pmName} to install preset pack "${resolved.name}"...`);
121
+ try {
122
+ execSync(cmd, { cwd, stdio: 'inherit' });
123
+ }
124
+ catch {
125
+ console.error(`\nError: Failed to install. Command: ${cmd}`);
126
+ process.exit(1);
127
+ }
128
+ // Validate the installed pack's manifest + compat.
129
+ const packDir = resolve(cwd, 'node_modules', resolved.name);
130
+ const manifestPath = resolve(packDir, 'presets.json');
131
+ if (!existsSync(manifestPath)) {
132
+ console.error(`Error: "${resolved.name}" has no presets.json — it is not a preset pack.`);
133
+ process.exit(1);
134
+ }
135
+ const manifest = JSON.parse(readFileSync(manifestPath, 'utf-8'));
136
+ const compat = validateCompat(manifest.refrakt ?? readInstalledManifest(cwd, resolved.name)?.refrakt, getProjectRefraktVersion(cwd));
137
+ for (const w of compat.warnings)
138
+ console.log(` ⚠ ${w}`);
139
+ if (compat.errors.length) {
140
+ for (const e of compat.errors)
141
+ console.error(` ✗ ${e}`);
142
+ console.error('The pack was installed but no preset was applied.');
143
+ process.exit(1);
144
+ }
145
+ // Optionally append the chosen preset to the target site.
146
+ if (options.use) {
147
+ const entry = manifest.presets.find((p) => p.id === options.use);
148
+ if (!entry) {
149
+ console.error(`Error: preset "${options.use}" not found in ${resolved.name} (have: ${manifest.presets.map((p) => p.id).join(', ')}).`);
150
+ process.exit(1);
151
+ }
152
+ const configData = loadRefraktConfigFile(cwd);
153
+ const selection = resolveTargetSite(configData.raw, options.site, 'existing');
154
+ if (!selection.key) {
155
+ console.error(`Error: ${selection.error}.`);
156
+ process.exit(1);
157
+ }
158
+ // The preset module identifier the loader resolves: package + export subpath.
159
+ const moduleId = `${resolved.name}/${entry.id}`;
160
+ appendSitePreset(configData.raw, selection.key, moduleId);
161
+ writeRefraktConfigFile(configData.path, configData.raw);
162
+ console.log(`\nApplied preset "${entry.id}" → ${selection.key !== 'default' ? `site "${selection.key}" ` : ''}theme.presets ("${moduleId}").`);
163
+ console.log('Ensure the pack exports that preset subpath (e.g. "./' + entry.id + '" → its module).');
164
+ }
165
+ else {
166
+ console.log(`\nInstalled. Apply a preset with: refrakt theme presets install ${options.source} --use <id>`);
167
+ console.log(`Available: ${manifest.presets.map((p) => p.id).join(', ')}`);
168
+ }
169
+ }
170
+ /** `refrakt theme presets validate` — validate pack manifests: scope vs actual
171
+ * tokens (for JSON-carrier presets), `tunedFor` well-formedness, and module
172
+ * resolvability (SPEC-111 §4). Returns a non-zero exit on errors. */
173
+ export async function themePresetsValidateCommand(options) {
174
+ const cwd = process.cwd();
175
+ let packs = discoverPacks(cwd);
176
+ if (options.pack) {
177
+ packs = packs.filter((p) => p.packageName === options.pack);
178
+ if (packs.length === 0) {
179
+ // Allow a direct directory path.
180
+ const dir = resolve(cwd, options.pack);
181
+ const manifestPath = resolve(dir, 'presets.json');
182
+ if (existsSync(manifestPath)) {
183
+ packs = [{ packageName: options.pack, dir, manifest: JSON.parse(readFileSync(manifestPath, 'utf-8')) }];
184
+ }
185
+ }
186
+ }
187
+ if (packs.length === 0) {
188
+ console.error('No preset packs found to validate.');
189
+ process.exit(1);
190
+ }
191
+ let errors = 0;
192
+ let warnings = 0;
193
+ for (const pack of packs) {
194
+ console.log(`\n${pack.packageName}:`);
195
+ for (const entry of pack.manifest.presets) {
196
+ const modulePath = resolve(pack.dir, entry.module ?? '');
197
+ let config;
198
+ let resolveError;
199
+ if (!entry.module) {
200
+ resolveError = `preset "${entry.id}" has no "module"`;
201
+ }
202
+ else if (!existsSync(modulePath)) {
203
+ resolveError = `preset "${entry.id}" module "${entry.module}" does not resolve`;
204
+ }
205
+ else if (entry.module.endsWith('.json')) {
206
+ // JSON carrier — read directly for scope-vs-tokens validation.
207
+ try {
208
+ config = JSON.parse(readFileSync(modulePath, 'utf-8'));
209
+ }
210
+ catch (err) {
211
+ resolveError = `preset "${entry.id}" JSON is invalid: ${err.message}`;
212
+ }
213
+ }
214
+ // JS/TS carriers aren't loaded here (may need a build) — scope-vs-tokens
215
+ // is skipped for them, but resolvability is still checked.
216
+ const { errors: e, warnings: w } = validatePresetEntry(entry, config);
217
+ const all = [...(resolveError ? [resolveError] : []), ...e];
218
+ for (const msg of all) {
219
+ console.log(` ✗ ${msg}`);
220
+ errors++;
221
+ }
222
+ for (const msg of w) {
223
+ console.log(` ⚠ ${msg}`);
224
+ warnings++;
225
+ }
226
+ if (all.length === 0 && w.length === 0)
227
+ console.log(` ✓ ${entry.id} [${entry.scope}]`);
228
+ }
229
+ }
230
+ console.log(`\n${errors} error(s), ${warnings} warning(s).`);
231
+ if (errors > 0)
232
+ process.exit(1);
233
+ }
234
+ //# sourceMappingURL=presets.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"presets.js","sourceRoot":"","sources":["../../src/commands/presets.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,20 @@
1
+ /** `refrakt template install` — add a full-site template as a NEW site in an
2
+ * existing project (SPEC-110 §4 kind:"site"). The greenfield path is
3
+ * `create-refrakt --template`; this is the add-to-existing-project surface.
4
+ *
5
+ * v1 resolves a **local directory** template (the directly-readable, portable
6
+ * case). Tarball/registry templates are scaffold-copied artifacts — fetch them
7
+ * with `create-refrakt` for now. */
8
+ import type { RefraktConfig } from '@refrakt-md/types';
9
+ export interface TemplateInstallOptions {
10
+ source: string;
11
+ site?: string;
12
+ }
13
+ /** Compose a template into a new site of `raw` and return the dependency names
14
+ * to install. Pure w.r.t. the package manager (caller installs). Copies the
15
+ * template's content/sandboxes into the new site's derived destinations. */
16
+ export declare function applyTemplateSite(raw: RefraktConfig, templateDir: string, siteKey: string, projectRoot: string): {
17
+ deps: string[];
18
+ };
19
+ export declare function templateInstallCommand(options: TemplateInstallOptions): Promise<void>;
20
+ //# sourceMappingURL=template.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"template.d.ts","sourceRoot":"","sources":["../../src/commands/template.ts"],"names":[],"mappings":"AAAA;;;;;;qCAMqC;AAKrC,OAAO,KAAK,EAAE,aAAa,EAAc,MAAM,mBAAmB,CAAC;AASnE,MAAM,WAAW,sBAAsB;IACtC,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;CACd;AAQD;;6EAE6E;AAC7E,wBAAgB,iBAAiB,CAChC,GAAG,EAAE,aAAa,EAClB,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE,MAAM,EACf,WAAW,EAAE,MAAM,GACjB;IAAE,IAAI,EAAE,MAAM,EAAE,CAAA;CAAE,CA8BpB;AAED,wBAAsB,sBAAsB,CAAC,OAAO,EAAE,sBAAsB,GAAG,OAAO,CAAC,IAAI,CAAC,CAsD3F"}