@refrakt-md/cli 0.4.0 → 0.5.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.
Files changed (87) hide show
  1. package/dist/bin.js +499 -9
  2. package/dist/bin.js.map +1 -1
  3. package/dist/commands/contracts.d.ts +6 -0
  4. package/dist/commands/contracts.d.ts.map +1 -0
  5. package/dist/commands/contracts.js +41 -0
  6. package/dist/commands/contracts.js.map +1 -0
  7. package/dist/commands/edit.d.ts +8 -0
  8. package/dist/commands/edit.d.ts.map +1 -0
  9. package/dist/commands/edit.js +100 -0
  10. package/dist/commands/edit.js.map +1 -0
  11. package/dist/commands/extract.d.ts +10 -0
  12. package/dist/commands/extract.d.ts.map +1 -0
  13. package/dist/commands/extract.js +158 -0
  14. package/dist/commands/extract.js.map +1 -0
  15. package/dist/commands/inspect.d.ts +33 -0
  16. package/dist/commands/inspect.d.ts.map +1 -0
  17. package/dist/commands/inspect.js +269 -0
  18. package/dist/commands/inspect.js.map +1 -0
  19. package/dist/commands/scaffold-css.d.ts +6 -0
  20. package/dist/commands/scaffold-css.d.ts.map +1 -0
  21. package/dist/commands/scaffold-css.js +113 -0
  22. package/dist/commands/scaffold-css.js.map +1 -0
  23. package/dist/commands/theme.d.ts +10 -0
  24. package/dist/commands/theme.d.ts.map +1 -0
  25. package/dist/commands/theme.js +160 -0
  26. package/dist/commands/theme.js.map +1 -0
  27. package/dist/commands/validate.d.ts +6 -0
  28. package/dist/commands/validate.d.ts.map +1 -0
  29. package/dist/commands/validate.js +70 -0
  30. package/dist/commands/validate.js.map +1 -0
  31. package/dist/commands/write.d.ts +7 -0
  32. package/dist/commands/write.d.ts.map +1 -1
  33. package/dist/commands/write.js +66 -10
  34. package/dist/commands/write.js.map +1 -1
  35. package/dist/config-file.d.ts +15 -0
  36. package/dist/config-file.d.ts.map +1 -0
  37. package/dist/config-file.js +47 -0
  38. package/dist/config-file.js.map +1 -0
  39. package/dist/config.d.ts +2 -1
  40. package/dist/config.d.ts.map +1 -1
  41. package/dist/config.js +30 -2
  42. package/dist/config.js.map +1 -1
  43. package/dist/extractors/index.d.ts +3 -0
  44. package/dist/extractors/index.d.ts.map +1 -0
  45. package/dist/extractors/index.js +15 -0
  46. package/dist/extractors/index.js.map +1 -0
  47. package/dist/extractors/python.d.ts +6 -0
  48. package/dist/extractors/python.d.ts.map +1 -0
  49. package/dist/extractors/python.js +8 -0
  50. package/dist/extractors/python.js.map +1 -0
  51. package/dist/extractors/types.d.ts +55 -0
  52. package/dist/extractors/types.d.ts.map +1 -0
  53. package/dist/extractors/types.js +2 -0
  54. package/dist/extractors/types.js.map +1 -0
  55. package/dist/extractors/typescript.d.ts +28 -0
  56. package/dist/extractors/typescript.d.ts.map +1 -0
  57. package/dist/extractors/typescript.js +566 -0
  58. package/dist/extractors/typescript.js.map +1 -0
  59. package/dist/lib/css-audit.d.ts +23 -0
  60. package/dist/lib/css-audit.d.ts.map +1 -0
  61. package/dist/lib/css-audit.js +99 -0
  62. package/dist/lib/css-audit.js.map +1 -0
  63. package/dist/lib/css-resolve.d.ts +20 -0
  64. package/dist/lib/css-resolve.d.ts.map +1 -0
  65. package/dist/lib/css-resolve.js +57 -0
  66. package/dist/lib/css-resolve.js.map +1 -0
  67. package/dist/lib/fixtures.d.ts +10 -0
  68. package/dist/lib/fixtures.d.ts.map +1 -0
  69. package/dist/lib/fixtures.js +356 -0
  70. package/dist/lib/fixtures.js.map +1 -0
  71. package/dist/lib/format.d.ts +35 -0
  72. package/dist/lib/format.d.ts.map +1 -0
  73. package/dist/lib/format.js +215 -0
  74. package/dist/lib/format.js.map +1 -0
  75. package/dist/lib/layout-generator.d.ts +8 -0
  76. package/dist/lib/layout-generator.d.ts.map +1 -0
  77. package/dist/lib/layout-generator.js +22 -0
  78. package/dist/lib/layout-generator.js.map +1 -0
  79. package/dist/lib/symbol-generator.d.ts +14 -0
  80. package/dist/lib/symbol-generator.d.ts.map +1 -0
  81. package/dist/lib/symbol-generator.js +202 -0
  82. package/dist/lib/symbol-generator.js.map +1 -0
  83. package/dist/lib/variants.d.ts +17 -0
  84. package/dist/lib/variants.d.ts.map +1 -0
  85. package/dist/lib/variants.js +32 -0
  86. package/dist/lib/variants.js.map +1 -0
  87. package/package.json +9 -3
@@ -0,0 +1,113 @@
1
+ import { writeFileSync, existsSync, mkdirSync } from 'fs';
2
+ import { join, resolve } from 'path';
3
+ import { generateStructureContract } from '@refrakt-md/transform';
4
+ import { baseConfig } from '@refrakt-md/theme-base';
5
+ export function scaffoldCssCommand(opts) {
6
+ const contract = generateStructureContract(baseConfig);
7
+ const outputDir = resolve(opts.outputDir);
8
+ if (!existsSync(outputDir)) {
9
+ mkdirSync(outputDir, { recursive: true });
10
+ }
11
+ // Group runes by block name (e.g., Tier and FeaturedTier both use 'tier')
12
+ const blockMap = new Map();
13
+ for (const [runeName, runeContract] of Object.entries(contract.runes)) {
14
+ const existing = blockMap.get(runeContract.block);
15
+ if (existing) {
16
+ existing.runeNames.push(runeName);
17
+ Object.assign(existing.modifiers, runeContract.modifiers ?? {});
18
+ Object.assign(existing.contextModifiers, runeContract.contextModifiers ?? {});
19
+ existing.staticModifiers.push(...(runeContract.staticModifiers ?? []));
20
+ Object.assign(existing.elements, runeContract.elements ?? {});
21
+ }
22
+ else {
23
+ blockMap.set(runeContract.block, {
24
+ runeNames: [runeName],
25
+ block: runeContract.block,
26
+ modifiers: { ...(runeContract.modifiers ?? {}) },
27
+ contextModifiers: { ...(runeContract.contextModifiers ?? {}) },
28
+ staticModifiers: [...(runeContract.staticModifiers ?? [])],
29
+ elements: { ...(runeContract.elements ?? {}) },
30
+ });
31
+ }
32
+ }
33
+ let created = 0;
34
+ let skipped = 0;
35
+ for (const [blockName, merged] of blockMap) {
36
+ const fileName = `${blockName}.css`;
37
+ const filePath = join(outputDir, fileName);
38
+ if (existsSync(filePath) && !opts.force) {
39
+ skipped++;
40
+ continue;
41
+ }
42
+ const css = generateBlockCss(merged, contract.prefix);
43
+ writeFileSync(filePath, css);
44
+ created++;
45
+ }
46
+ console.log(`Scaffold CSS: ${created} files created, ${skipped} skipped (already exist)`);
47
+ if (skipped > 0 && !opts.force) {
48
+ console.log('Use --force to overwrite existing files');
49
+ }
50
+ if (created > 0) {
51
+ console.log(`Output directory: ${outputDir}`);
52
+ }
53
+ }
54
+ function generateBlockCss(merged, prefix) {
55
+ const block = `${prefix}-${merged.block}`;
56
+ const label = merged.runeNames.join(', ');
57
+ const lines = [];
58
+ lines.push(`/* ${label} rune${merged.runeNames.length > 1 ? 's' : ''} */`);
59
+ lines.push('');
60
+ // Root block
61
+ lines.push(`.${block} {`);
62
+ lines.push('');
63
+ lines.push('}');
64
+ // Modifier selectors
65
+ if (Object.keys(merged.modifiers).length > 0) {
66
+ lines.push('');
67
+ lines.push(`/* Modifiers */`);
68
+ for (const [modName, mod] of Object.entries(merged.modifiers)) {
69
+ if (mod.default) {
70
+ lines.push(`.${block}--${mod.default} {`);
71
+ lines.push('');
72
+ lines.push('}');
73
+ }
74
+ lines.push(`/* ${modName}: ${mod.classPattern} [${mod.dataAttribute}] */`);
75
+ }
76
+ }
77
+ // Context modifier selectors
78
+ if (Object.keys(merged.contextModifiers).length > 0) {
79
+ lines.push('');
80
+ lines.push(`/* Context modifiers */`);
81
+ for (const [parent, ctx] of Object.entries(merged.contextModifiers)) {
82
+ lines.push(`/* When inside ${parent}: */`);
83
+ lines.push(`${ctx.selector} {`);
84
+ lines.push('');
85
+ lines.push('}');
86
+ }
87
+ }
88
+ // Static modifier selectors
89
+ if (merged.staticModifiers.length > 0) {
90
+ lines.push('');
91
+ lines.push(`/* Static modifiers */`);
92
+ for (const mod of merged.staticModifiers) {
93
+ lines.push(`${mod.selector} {`);
94
+ lines.push('');
95
+ lines.push('}');
96
+ }
97
+ }
98
+ // Element selectors
99
+ if (Object.keys(merged.elements).length > 0) {
100
+ lines.push('');
101
+ lines.push(`/* Elements */`);
102
+ for (const [elName, el] of Object.entries(merged.elements)) {
103
+ const condNote = el.condition ? ` (conditional: ${el.condition})` : '';
104
+ lines.push(`/* ${elName} — <${el.tag}> from ${el.source}${condNote} */`);
105
+ lines.push(`${el.selector} {`);
106
+ lines.push('');
107
+ lines.push('}');
108
+ }
109
+ }
110
+ lines.push('');
111
+ return lines.join('\n');
112
+ }
113
+ //# sourceMappingURL=scaffold-css.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scaffold-css.js","sourceRoot":"","sources":["../../src/commands/scaffold-css.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ export interface ThemeInstallOptions {
2
+ source: string;
3
+ }
4
+ export interface ThemeInfoOptions {
5
+ }
6
+ /** Install a theme package and update refrakt.config.json */
7
+ export declare function themeInstallCommand(options: ThemeInstallOptions): Promise<void>;
8
+ /** Show info about the currently configured theme */
9
+ export declare function themeInfoCommand(_options: ThemeInfoOptions): Promise<void>;
10
+ //# sourceMappingURL=theme.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"theme.d.ts","sourceRoot":"","sources":["../../src/commands/theme.ts"],"names":[],"mappings":"AASA,MAAM,WAAW,mBAAmB;IACnC,MAAM,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,gBAAgB;CAEhC;AAED,6DAA6D;AAC7D,wBAAsB,mBAAmB,CAAC,OAAO,EAAE,mBAAmB,GAAG,OAAO,CAAC,IAAI,CAAC,CA6GrF;AAED,qDAAqD;AACrD,wBAAsB,gBAAgB,CAAC,QAAQ,EAAE,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC,CAyChF"}
@@ -0,0 +1,160 @@
1
+ import { existsSync, readFileSync } from 'node:fs';
2
+ import { resolve, isAbsolute } from 'node:path';
3
+ import { execSync } from 'node:child_process';
4
+ import { detectPackageManager, loadRefraktConfigFile, writeRefraktConfigFile, } from '../config-file.js';
5
+ /** Install a theme package and update refrakt.config.json */
6
+ export async function themeInstallCommand(options) {
7
+ const { source } = options;
8
+ const cwd = process.cwd();
9
+ // 1. Determine source type and package name
10
+ const absSource = isAbsolute(source) ? source : resolve(cwd, source);
11
+ let packageName;
12
+ let installSource;
13
+ if (existsSync(absSource)) {
14
+ // Local directory or tarball
15
+ const pkgJsonPath = source.endsWith('.tgz')
16
+ ? null // Can't easily read from tarball without tar parser
17
+ : resolve(absSource, 'package.json');
18
+ if (pkgJsonPath && existsSync(pkgJsonPath)) {
19
+ const pkg = JSON.parse(readFileSync(pkgJsonPath, 'utf-8'));
20
+ packageName = pkg.name;
21
+ if (!packageName) {
22
+ console.error('Error: Theme package.json is missing a "name" field');
23
+ process.exit(1);
24
+ }
25
+ installSource = `file:${absSource}`;
26
+ }
27
+ else if (source.endsWith('.tgz')) {
28
+ // For tarballs, install first then read name from node_modules
29
+ installSource = absSource;
30
+ packageName = ''; // resolved after install
31
+ }
32
+ else {
33
+ console.error(`Error: No package.json found in ${absSource}`);
34
+ process.exit(1);
35
+ }
36
+ }
37
+ else {
38
+ // npm package name
39
+ packageName = source;
40
+ installSource = source;
41
+ }
42
+ // 2. Detect package manager
43
+ const pm = detectPackageManager(cwd);
44
+ console.log(`Using ${pm.name} to install theme...`);
45
+ // 3. Install
46
+ const cmd = pm.installCmd(installSource);
47
+ try {
48
+ execSync(cmd, { cwd, stdio: 'inherit' });
49
+ }
50
+ catch {
51
+ console.error(`\nError: Failed to install theme. Command: ${cmd}`);
52
+ process.exit(1);
53
+ }
54
+ // 4. For tarballs, resolve package name from the install output
55
+ if (!packageName) {
56
+ // After npm install of a tarball, the package is in node_modules
57
+ // We need to search for it — check recent additions
58
+ console.error('Error: Could not determine package name from tarball.');
59
+ console.error('Please install from the unzipped directory instead:');
60
+ console.error(' refrakt theme install ./path/to/theme-directory');
61
+ process.exit(1);
62
+ }
63
+ // 5. Update refrakt.config.json
64
+ let configData;
65
+ try {
66
+ configData = loadRefraktConfigFile(cwd);
67
+ }
68
+ catch {
69
+ console.error('Error: No refrakt.config.json found in the current directory.');
70
+ console.error('Are you in a refrakt.md project root?');
71
+ process.exit(1);
72
+ }
73
+ const previousTheme = configData.config.theme;
74
+ configData.config.theme = packageName;
75
+ writeRefraktConfigFile(configData.path, configData.config);
76
+ // 6. Validate the installed theme
77
+ const warnings = [];
78
+ try {
79
+ const themeDir = resolve(cwd, 'node_modules', packageName);
80
+ if (!existsSync(themeDir)) {
81
+ warnings.push('Theme directory not found in node_modules — install may have failed');
82
+ }
83
+ else {
84
+ const themePkg = JSON.parse(readFileSync(resolve(themeDir, 'package.json'), 'utf-8'));
85
+ const exports = themePkg.exports ?? {};
86
+ if (!exports['./svelte'] && !exports['./svelte/index.js']) {
87
+ warnings.push('Theme is missing ./svelte export — runtime rendering may fail');
88
+ }
89
+ if (!exports['./transform']) {
90
+ warnings.push('Theme is missing ./transform export — CSS tree-shaking will be skipped');
91
+ }
92
+ }
93
+ }
94
+ catch {
95
+ // Validation is best-effort
96
+ }
97
+ // 7. Output results
98
+ console.log('');
99
+ console.log(`Theme "${packageName}" installed successfully.`);
100
+ if (previousTheme !== packageName) {
101
+ console.log(` Updated refrakt.config.json: "${previousTheme}" → "${packageName}"`);
102
+ }
103
+ if (warnings.length > 0) {
104
+ console.log('');
105
+ console.log('Warnings:');
106
+ for (const w of warnings) {
107
+ console.log(` ⚠ ${w}`);
108
+ }
109
+ }
110
+ console.log('');
111
+ console.log('Run your dev server to see the new theme in action.');
112
+ }
113
+ /** Show info about the currently configured theme */
114
+ export async function themeInfoCommand(_options) {
115
+ const cwd = process.cwd();
116
+ let configData;
117
+ try {
118
+ configData = loadRefraktConfigFile(cwd);
119
+ }
120
+ catch {
121
+ console.error('Error: No refrakt.config.json found in the current directory.');
122
+ process.exit(1);
123
+ }
124
+ const themeName = configData.config.theme;
125
+ console.log(`Current theme: ${themeName}`);
126
+ // Try to resolve and show details
127
+ try {
128
+ const themeDir = resolve(cwd, 'node_modules', themeName);
129
+ if (existsSync(themeDir)) {
130
+ const pkg = JSON.parse(readFileSync(resolve(themeDir, 'package.json'), 'utf-8'));
131
+ console.log(` Version: ${pkg.version ?? 'unknown'}`);
132
+ console.log(` Path: ${themeDir}`);
133
+ if (pkg.description) {
134
+ console.log(` Description: ${pkg.description}`);
135
+ }
136
+ const exports = pkg.exports ?? {};
137
+ const features = [];
138
+ if (exports['./svelte'])
139
+ features.push('svelte');
140
+ if (exports['./transform'])
141
+ features.push('transform');
142
+ if (exports['./styles/runes/*.css'])
143
+ features.push('rune CSS');
144
+ if (features.length > 0) {
145
+ console.log(` Exports: ${features.join(', ')}`);
146
+ }
147
+ }
148
+ else if (themeName.startsWith('.')) {
149
+ console.log(` Type: Local directory`);
150
+ console.log(` Path: ${resolve(cwd, themeName)}`);
151
+ }
152
+ else {
153
+ console.log(` Status: Not found in node_modules`);
154
+ }
155
+ }
156
+ catch {
157
+ // Best-effort info display
158
+ }
159
+ }
160
+ //# sourceMappingURL=theme.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"theme.js","sourceRoot":"","sources":["../../src/commands/theme.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ export interface ValidateOptions {
2
+ configPath?: string;
3
+ manifestPath?: string;
4
+ }
5
+ export declare function validateCommand(opts: ValidateOptions): void;
6
+ //# sourceMappingURL=validate.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validate.d.ts","sourceRoot":"","sources":["../../src/commands/validate.ts"],"names":[],"mappings":"AAKA,MAAM,WAAW,eAAe;IAC/B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,YAAY,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,wBAAgB,eAAe,CAAC,IAAI,EAAE,eAAe,GAAG,IAAI,CA4C3D"}
@@ -0,0 +1,70 @@
1
+ import { readFileSync, existsSync } from 'fs';
2
+ import { resolve } from 'path';
3
+ import { validateThemeConfig, validateManifest } from '@refrakt-md/transform';
4
+ import { baseConfig } from '@refrakt-md/theme-base';
5
+ export function validateCommand(opts) {
6
+ let hasErrors = false;
7
+ // Validate theme config
8
+ if (opts.configPath) {
9
+ const absPath = resolve(opts.configPath);
10
+ if (!existsSync(absPath)) {
11
+ console.error(`Error: Config file not found: ${absPath}`);
12
+ process.exit(1);
13
+ }
14
+ // For now, only JSON configs are supported via CLI.
15
+ // TypeScript configs require dynamic import which needs the module to be built.
16
+ const raw = JSON.parse(readFileSync(absPath, 'utf-8'));
17
+ console.log('Validating theme config...');
18
+ const result = validateThemeConfig(raw);
19
+ printResult('Theme config', result);
20
+ if (!result.valid)
21
+ hasErrors = true;
22
+ }
23
+ else {
24
+ // Validate the base config as a sanity check
25
+ console.log('Validating base theme config...');
26
+ const result = validateThemeConfig(baseConfig);
27
+ printResult('Base theme config', result);
28
+ if (!result.valid)
29
+ hasErrors = true;
30
+ }
31
+ // Validate manifest
32
+ if (opts.manifestPath) {
33
+ const absPath = resolve(opts.manifestPath);
34
+ if (!existsSync(absPath)) {
35
+ console.error(`Error: Manifest file not found: ${absPath}`);
36
+ process.exit(1);
37
+ }
38
+ const raw = JSON.parse(readFileSync(absPath, 'utf-8'));
39
+ console.log('\nValidating manifest...');
40
+ const result = validateManifest(raw);
41
+ printResult('Manifest', result);
42
+ if (!result.valid)
43
+ hasErrors = true;
44
+ }
45
+ if (hasErrors) {
46
+ process.exit(1);
47
+ }
48
+ }
49
+ function printResult(label, result) {
50
+ if (result.valid && result.warnings.length === 0) {
51
+ console.log(` ${label}: OK`);
52
+ return;
53
+ }
54
+ if (result.errors.length > 0) {
55
+ console.log(` ${label}: FAIL (${result.errors.length} error${result.errors.length === 1 ? '' : 's'})`);
56
+ for (const err of result.errors) {
57
+ console.log(` ERROR ${err.path}: ${err.message}`);
58
+ }
59
+ }
60
+ else {
61
+ console.log(` ${label}: OK`);
62
+ }
63
+ if (result.warnings.length > 0) {
64
+ console.log(` ${result.warnings.length} warning${result.warnings.length === 1 ? '' : 's'}:`);
65
+ for (const warn of result.warnings) {
66
+ console.log(` WARN ${warn.path}: ${warn.message}`);
67
+ }
68
+ }
69
+ }
70
+ //# sourceMappingURL=validate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validate.js","sourceRoot":"","sources":["../../src/commands/validate.ts"],"names":[],"mappings":"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"}
@@ -2,8 +2,15 @@ import type { AIProvider } from '@refrakt-md/ai';
2
2
  export interface WriteOptions {
3
3
  prompt: string;
4
4
  provider: AIProvider;
5
+ providerName: string;
6
+ modelName: string;
5
7
  model?: string;
6
8
  output?: string;
9
+ outputDir?: string;
7
10
  }
11
+ export declare function splitFiles(raw: string): Array<{
12
+ path: string;
13
+ content: string;
14
+ }>;
8
15
  export declare function writeCommand(options: WriteOptions): Promise<void>;
9
16
  //# sourceMappingURL=write.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"write.d.ts","sourceRoot":"","sources":["../../src/commands/write.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,UAAU,EAAW,MAAM,gBAAgB,CAAC;AAE1D,MAAM,WAAW,YAAY;IAC5B,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,UAAU,CAAC;IACrB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,wBAAsB,YAAY,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CA0BvE"}
1
+ {"version":3,"file":"write.d.ts","sourceRoot":"","sources":["../../src/commands/write.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,UAAU,EAAW,MAAM,gBAAgB,CAAC;AAE1D,MAAM,WAAW,YAAY;IAC5B,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,UAAU,CAAC;IACrB,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;CACnB;AAYD,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,KAAK,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC,CA8BhF;AAED,wBAAsB,YAAY,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CAuDvE"}
@@ -1,25 +1,81 @@
1
- import { writeFileSync } from 'node:fs';
2
- import { generateSystemPrompt } from '@refrakt-md/ai';
1
+ import { mkdirSync, writeFileSync } from 'node:fs';
2
+ import * as path from 'node:path';
3
+ import { generateSystemPrompt, writePrompt } from '@refrakt-md/ai';
3
4
  import { runes } from '@refrakt-md/runes';
5
+ function log(message) {
6
+ process.stderr.write(message);
7
+ }
8
+ function wordCount(text) {
9
+ return text.split(/\s+/).filter(Boolean).length;
10
+ }
11
+ const FILE_MARKER = /^--- FILE: (.+) ---$/gm;
12
+ export function splitFiles(raw) {
13
+ const files = [];
14
+ const markers = [];
15
+ let match;
16
+ while ((match = FILE_MARKER.exec(raw)) !== null) {
17
+ markers.push({ path: match[1].trim(), index: match.index + match[0].length });
18
+ }
19
+ if (markers.length === 0) {
20
+ return [];
21
+ }
22
+ for (let i = 0; i < markers.length; i++) {
23
+ const filePath = markers[i].path;
24
+ if (filePath.includes('..')) {
25
+ throw new Error(`Invalid file path "${filePath}": parent traversal is not allowed`);
26
+ }
27
+ const start = markers[i].index;
28
+ const nextMarkerPos = i + 1 < markers.length
29
+ ? raw.indexOf(`--- FILE: ${markers[i + 1].path} ---`, start)
30
+ : raw.length;
31
+ const content = raw.slice(start, nextMarkerPos).replace(/^\n/, '').replace(/\n$/, '');
32
+ files.push({ path: filePath, content: content + '\n' });
33
+ }
34
+ return files;
35
+ }
4
36
  export async function writeCommand(options) {
5
- const { prompt, provider, model, output } = options;
6
- const systemPrompt = generateSystemPrompt(runes);
37
+ const { prompt, provider, providerName, modelName, model, output, outputDir } = options;
38
+ log(`Using ${providerName} (${modelName})\n`);
39
+ const multiFile = !!outputDir;
40
+ const systemPrompt = generateSystemPrompt(runes) + writePrompt({ multiFile });
7
41
  const messages = [
8
42
  { role: 'system', content: systemPrompt },
9
43
  { role: 'user', content: prompt },
10
44
  ];
11
45
  let content = '';
46
+ if (output || outputDir) {
47
+ log('Generating...');
48
+ }
12
49
  for await (const chunk of provider.complete({ messages, model })) {
13
- if (output) {
14
- content += chunk;
15
- }
16
- else {
50
+ content += chunk;
51
+ if (!output && !outputDir) {
17
52
  process.stdout.write(chunk);
18
53
  }
19
54
  }
20
- if (output) {
55
+ if (outputDir) {
56
+ const files = splitFiles(content);
57
+ const words = wordCount(content);
58
+ if (files.length === 0) {
59
+ log(`\rGenerating... done (${words.toLocaleString()} words)\n`);
60
+ const fallbackPath = path.join(outputDir, 'index.md');
61
+ mkdirSync(outputDir, { recursive: true });
62
+ writeFileSync(fallbackPath, content);
63
+ log(`Written to ${fallbackPath}\n`);
64
+ return;
65
+ }
66
+ log(`\rGenerating... done (${words.toLocaleString()} words, ${files.length} files)\n`);
67
+ for (const file of files) {
68
+ const fullPath = path.join(outputDir, file.path);
69
+ mkdirSync(path.dirname(fullPath), { recursive: true });
70
+ writeFileSync(fullPath, file.content);
71
+ log(` ${fullPath}\n`);
72
+ }
73
+ }
74
+ else if (output) {
75
+ const words = wordCount(content);
76
+ log(`\rGenerating... done (${words.toLocaleString()} words)\n`);
21
77
  writeFileSync(output, content);
22
- process.stderr.write(`Written to ${output}\n`);
78
+ log(`Written to ${output}\n`);
23
79
  }
24
80
  else {
25
81
  process.stdout.write('\n');
@@ -1 +1 @@
1
- {"version":3,"file":"write.js","sourceRoot":"","sources":["../../src/commands/write.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AACxC,OAAO,EAAE,oBAAoB,EAAE,MAAM,gBAAgB,CAAC;AACtD,OAAO,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAU1C,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,OAAqB;IACvD,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC;IAEpD,MAAM,YAAY,GAAG,oBAAoB,CAAC,KAAK,CAAC,CAAC;IAEjD,MAAM,QAAQ,GAAc;QAC3B,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,YAAY,EAAE;QACzC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE;KACjC,CAAC;IAEF,IAAI,OAAO,GAAG,EAAE,CAAC;IAEjB,IAAI,KAAK,EAAE,MAAM,KAAK,IAAI,QAAQ,CAAC,QAAQ,CAAC,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC;QAClE,IAAI,MAAM,EAAE,CAAC;YACZ,OAAO,IAAI,KAAK,CAAC;QAClB,CAAC;aAAM,CAAC;YACP,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;QAC7B,CAAC;IACF,CAAC;IAED,IAAI,MAAM,EAAE,CAAC;QACZ,aAAa,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QAC/B,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,cAAc,MAAM,IAAI,CAAC,CAAC;IAChD,CAAC;SAAM,CAAC;QACP,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAC5B,CAAC;AACF,CAAC"}
1
+ {"version":3,"file":"write.js","sourceRoot":"","sources":["../../src/commands/write.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,15 @@
1
+ import type { RefraktConfig } from '@refrakt-md/types';
2
+ export interface PackageManager {
3
+ name: 'npm' | 'pnpm' | 'yarn' | 'bun';
4
+ installCmd: (source: string) => string;
5
+ }
6
+ /** Detect the project's package manager by checking for lockfiles */
7
+ export declare function detectPackageManager(cwd?: string): PackageManager;
8
+ /** Load refrakt.config.json from a directory */
9
+ export declare function loadRefraktConfigFile(cwd?: string): {
10
+ path: string;
11
+ config: RefraktConfig;
12
+ };
13
+ /** Write refrakt.config.json, preserving formatting */
14
+ export declare function writeRefraktConfigFile(path: string, config: RefraktConfig): void;
15
+ //# sourceMappingURL=config-file.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config-file.d.ts","sourceRoot":"","sources":["../src/config-file.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAEvD,MAAM,WAAW,cAAc;IAC9B,IAAI,EAAE,KAAK,GAAG,MAAM,GAAG,MAAM,GAAG,KAAK,CAAC;IACtC,UAAU,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,MAAM,CAAC;CACvC;AA0BD,qEAAqE;AACrE,wBAAgB,oBAAoB,CAAC,GAAG,GAAE,MAAsB,GAAG,cAAc,CAKhF;AAED,gDAAgD;AAChD,wBAAgB,qBAAqB,CAAC,GAAG,GAAE,MAAsB,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,aAAa,CAAA;CAAE,CAQ1G;AAED,uDAAuD;AACvD,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,aAAa,GAAG,IAAI,CAEhF"}
@@ -0,0 +1,47 @@
1
+ import { existsSync, readFileSync, writeFileSync } from 'node:fs';
2
+ import { resolve } from 'node:path';
3
+ const PM_LOCKFILES = [
4
+ {
5
+ file: 'bun.lock',
6
+ pm: { name: 'bun', installCmd: (s) => `bun add ${s}` },
7
+ },
8
+ {
9
+ file: 'bun.lockb',
10
+ pm: { name: 'bun', installCmd: (s) => `bun add ${s}` },
11
+ },
12
+ {
13
+ file: 'pnpm-lock.yaml',
14
+ pm: { name: 'pnpm', installCmd: (s) => `pnpm add ${s}` },
15
+ },
16
+ {
17
+ file: 'yarn.lock',
18
+ pm: { name: 'yarn', installCmd: (s) => `yarn add ${s}` },
19
+ },
20
+ ];
21
+ const NPM_DEFAULT = {
22
+ name: 'npm',
23
+ installCmd: (s) => `npm install ${s}`,
24
+ };
25
+ /** Detect the project's package manager by checking for lockfiles */
26
+ export function detectPackageManager(cwd = process.cwd()) {
27
+ for (const { file, pm } of PM_LOCKFILES) {
28
+ if (existsSync(resolve(cwd, file)))
29
+ return pm;
30
+ }
31
+ return NPM_DEFAULT;
32
+ }
33
+ /** Load refrakt.config.json from a directory */
34
+ export function loadRefraktConfigFile(cwd = process.cwd()) {
35
+ const configPath = resolve(cwd, 'refrakt.config.json');
36
+ if (!existsSync(configPath)) {
37
+ throw new Error(`No refrakt.config.json found in ${cwd}`);
38
+ }
39
+ const raw = readFileSync(configPath, 'utf-8');
40
+ const config = JSON.parse(raw);
41
+ return { path: configPath, config };
42
+ }
43
+ /** Write refrakt.config.json, preserving formatting */
44
+ export function writeRefraktConfigFile(path, config) {
45
+ writeFileSync(path, JSON.stringify(config, null, '\t') + '\n');
46
+ }
47
+ //# sourceMappingURL=config-file.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config-file.js","sourceRoot":"","sources":["../src/config-file.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAClE,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAQpC,MAAM,YAAY,GAAgD;IACjE;QACC,IAAI,EAAE,UAAU;QAChB,EAAE,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,UAAU,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,WAAW,CAAC,EAAE,EAAE;KACtD;IACD;QACC,IAAI,EAAE,WAAW;QACjB,EAAE,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,UAAU,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,WAAW,CAAC,EAAE,EAAE;KACtD;IACD;QACC,IAAI,EAAE,gBAAgB;QACtB,EAAE,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,UAAU,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,YAAY,CAAC,EAAE,EAAE;KACxD;IACD;QACC,IAAI,EAAE,WAAW;QACjB,EAAE,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,UAAU,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,YAAY,CAAC,EAAE,EAAE;KACxD;CACD,CAAC;AAEF,MAAM,WAAW,GAAmB;IACnC,IAAI,EAAE,KAAK;IACX,UAAU,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,eAAe,CAAC,EAAE;CACrC,CAAC;AAEF,qEAAqE;AACrE,MAAM,UAAU,oBAAoB,CAAC,MAAc,OAAO,CAAC,GAAG,EAAE;IAC/D,KAAK,MAAM,EAAE,IAAI,EAAE,EAAE,EAAE,IAAI,YAAY,EAAE,CAAC;QACzC,IAAI,UAAU,CAAC,OAAO,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;YAAE,OAAO,EAAE,CAAC;IAC/C,CAAC;IACD,OAAO,WAAW,CAAC;AACpB,CAAC;AAED,gDAAgD;AAChD,MAAM,UAAU,qBAAqB,CAAC,MAAc,OAAO,CAAC,GAAG,EAAE;IAChE,MAAM,UAAU,GAAG,OAAO,CAAC,GAAG,EAAE,qBAAqB,CAAC,CAAC;IACvD,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;QAC7B,MAAM,IAAI,KAAK,CAAC,mCAAmC,GAAG,EAAE,CAAC,CAAC;IAC3D,CAAC;IACD,MAAM,GAAG,GAAG,YAAY,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;IAC9C,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAkB,CAAC;IAChD,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,MAAM,EAAE,CAAC;AACrC,CAAC;AAED,uDAAuD;AACvD,MAAM,UAAU,sBAAsB,CAAC,IAAY,EAAE,MAAqB;IACzE,aAAa,CAAC,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,IAAI,CAAC,GAAG,IAAI,CAAC,CAAC;AAChE,CAAC"}
package/dist/config.d.ts CHANGED
@@ -1,8 +1,9 @@
1
1
  import type { AIProvider } from '@refrakt-md/ai';
2
- export type ProviderName = 'anthropic' | 'ollama';
2
+ export type ProviderName = 'anthropic' | 'gemini' | 'ollama';
3
3
  export interface ResolvedProvider {
4
4
  provider: AIProvider;
5
5
  name: ProviderName;
6
+ defaultModel: string;
6
7
  }
7
8
  export declare function detectProvider(explicit?: string): ResolvedProvider;
8
9
  //# sourceMappingURL=config.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAGjD,MAAM,MAAM,YAAY,GAAG,WAAW,GAAG,QAAQ,CAAC;AAElD,MAAM,WAAW,gBAAgB;IAChC,QAAQ,EAAE,UAAU,CAAC;IACrB,IAAI,EAAE,YAAY,CAAC;CACnB;AAED,wBAAgB,cAAc,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,gBAAgB,CAkBlE"}
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAGjD,MAAM,MAAM,YAAY,GAAG,WAAW,GAAG,QAAQ,GAAG,QAAQ,CAAC;AAE7D,MAAM,WAAW,gBAAgB;IAChC,QAAQ,EAAE,UAAU,CAAC;IACrB,IAAI,EAAE,YAAY,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;CACrB;AAQD,wBAAgB,cAAc,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,gBAAgB,CA6BlE"}