create-fornix 0.0.6 → 0.0.8

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/dist/index.js CHANGED
@@ -9,7 +9,7 @@ import { defineCommand as defineCommand8 } from "citty";
9
9
  // src/cli/commands/create.ts
10
10
  import { defineCommand } from "citty";
11
11
  import { resolve as resolve2, basename as basename2 } from "path";
12
- import { mkdirSync as mkdirSync4, writeFileSync as writeFileSync3 } from "fs";
12
+ import { mkdirSync as mkdirSync4, writeFileSync as writeFileSync4 } from "fs";
13
13
  import { join as join6 } from "path";
14
14
  import * as p2 from "@clack/prompts";
15
15
  import pc3 from "picocolors";
@@ -305,14 +305,15 @@ ${blockImports.join("\n")}
305
305
  ${blockComponents.length > 0 ? blockComponents.join("\n") : ` <h1>Welcome to <span class="text-gradient">${config.projectName}</span></h1>`}
306
306
  </main>
307
307
  </Layout>
308
- `.trim() + "\\n";
308
+ `.trim() + "\n";
309
309
  files["src/pages/index.astro"] = indexAstroContent;
310
+ const tailwindImport = config.cssEngine === "tailwind" ? '\nimport "../../tailwind.css";' : "";
310
311
  files["src/layouts/Layout.astro"] = `
311
312
  ---
312
313
  interface Props {
313
314
  title: string;
314
315
  }
315
- const { title } = Astro.props;
316
+ const { title } = Astro.props;${tailwindImport}
316
317
  ---
317
318
  <!doctype html>
318
319
  <html lang="en">
@@ -403,6 +404,16 @@ function generateAstroConfig(config, blocks = []) {
403
404
  configObject.integrations = configObject.integrations || [];
404
405
  configObject.integrations.push(builders.functionCall("mdx"));
405
406
  }
407
+ if (config.cssEngine === "tailwind") {
408
+ module.imports.$add({
409
+ from: "@tailwindcss/vite",
410
+ imported: "default",
411
+ local: "tailwindcss"
412
+ });
413
+ configObject.vite = {
414
+ plugins: [builders.functionCall("tailwindcss")]
415
+ };
416
+ }
406
417
  const { code } = generateCode(module);
407
418
  return ok(code);
408
419
  } catch (error) {
@@ -427,8 +438,9 @@ function generateTailwindConfig(config) {
427
438
  ].join("\n");
428
439
  const lines = [
429
440
  '@import "tailwindcss";',
441
+ '@import "./src/styles/palettes/_current.css";',
430
442
  "",
431
- `@source "../src/**/*.{astro,html,js,jsx,md,mdx,svelte,ts,tsx,vue}";`,
443
+ `@source "./src/**/*.{astro,html,js,jsx,md,mdx,svelte,ts,tsx,vue}";`,
432
444
  "",
433
445
  themeBlock,
434
446
  ""
@@ -1491,6 +1503,7 @@ function manifest(name, overrides = {}) {
1491
1503
  var FIXTURE_MANIFESTS = {
1492
1504
  "hero-gradient": manifest("hero-gradient", {
1493
1505
  category: "hero",
1506
+ conflicts: ["hero-video"],
1494
1507
  ai: {
1495
1508
  whenToUse: "Landing page hero with gradient background",
1496
1509
  whenNotToUse: "Internal pages",
@@ -1885,10 +1898,13 @@ import {
1885
1898
  readFileSync as readFileSync3,
1886
1899
  readdirSync as readdirSync2,
1887
1900
  mkdirSync as mkdirSync2,
1888
- statSync as statSync2
1901
+ statSync as statSync2,
1902
+ writeFileSync as writeFileSync2,
1903
+ rmSync
1889
1904
  } from "fs";
1890
1905
  import { join as join3 } from "path";
1891
1906
  import { homedir as homedir2 } from "os";
1907
+ import { createRequire } from "module";
1892
1908
  var DEFAULT_CONFIG2 = {
1893
1909
  repo: "kamsqe/fornix",
1894
1910
  ref: "main",
@@ -1898,6 +1914,31 @@ var DEFAULT_CONFIG2 = {
1898
1914
  maxCacheAge: 24 * 60 * 60 * 1e3
1899
1915
  // 24 hours
1900
1916
  };
1917
+ var cacheVersionChecked = false;
1918
+ function ensureCacheVersion(cacheDir) {
1919
+ if (cacheVersionChecked) return;
1920
+ cacheVersionChecked = true;
1921
+ let cliVersion = "unknown";
1922
+ try {
1923
+ const require2 = createRequire(import.meta.url);
1924
+ const pkg = require2("../../package.json");
1925
+ cliVersion = pkg.version ?? "unknown";
1926
+ } catch {
1927
+ }
1928
+ const versionFile = join3(cacheDir, ".version");
1929
+ try {
1930
+ if (existsSync2(versionFile)) {
1931
+ const cached = readFileSync3(versionFile, "utf-8").trim();
1932
+ if (cached === cliVersion) return;
1933
+ }
1934
+ if (existsSync2(cacheDir)) {
1935
+ rmSync(cacheDir, { recursive: true, force: true });
1936
+ }
1937
+ mkdirSync2(cacheDir, { recursive: true });
1938
+ writeFileSync2(versionFile, cliVersion);
1939
+ } catch {
1940
+ }
1941
+ }
1901
1942
  async function fetchBlock(blockName, config = {}) {
1902
1943
  if (process.env.FORNIX_E2E_MOCK === "true") {
1903
1944
  const manifest2 = FIXTURE_MANIFESTS[blockName];
@@ -1912,6 +1953,7 @@ async function fetchBlock(blockName, config = {}) {
1912
1953
  return ok({ manifest: manifest2, files, fromCache: true });
1913
1954
  }
1914
1955
  const cfg = { ...DEFAULT_CONFIG2, ...config };
1956
+ ensureCacheVersion(cfg.cacheDir);
1915
1957
  const blockCacheDir = join3(cfg.cacheDir, blockName);
1916
1958
  if (!cfg.force && isCacheValid2(blockCacheDir, cfg.maxCacheAge)) {
1917
1959
  return loadFromCache2(blockName, blockCacheDir);
@@ -1975,13 +2017,7 @@ function loadFromCache2(blockName, blockCacheDir) {
1975
2017
  });
1976
2018
  }
1977
2019
  const files = {};
1978
- const entries = readdirSync2(blockCacheDir);
1979
- for (const entry of entries) {
1980
- const fullPath = join3(blockCacheDir, entry);
1981
- if (statSync2(fullPath).isFile() && entry !== "block.json") {
1982
- files[entry] = readFileSync3(fullPath, "utf-8");
1983
- }
1984
- }
2020
+ readFilesRecursive(blockCacheDir, "", files);
1985
2021
  return ok({
1986
2022
  manifest: result.data,
1987
2023
  files,
@@ -1996,6 +2032,18 @@ function loadFromCache2(blockName, blockCacheDir) {
1996
2032
  });
1997
2033
  }
1998
2034
  }
2035
+ function readFilesRecursive(dir, prefix, files) {
2036
+ const entries = readdirSync2(dir, { withFileTypes: true });
2037
+ for (const entry of entries) {
2038
+ const relativePath = prefix ? `${prefix}/${entry.name}` : entry.name;
2039
+ const fullPath = join3(dir, entry.name);
2040
+ if (entry.isDirectory()) {
2041
+ readFilesRecursive(fullPath, relativePath, files);
2042
+ } else if (entry.name !== "block.json") {
2043
+ files[relativePath] = readFileSync3(fullPath, "utf-8");
2044
+ }
2045
+ }
2046
+ }
1999
2047
 
2000
2048
  // src/prompts/manual-flow.ts
2001
2049
  import * as p from "@clack/prompts";
@@ -2187,7 +2235,7 @@ function buildSummary(config, blockNames, palette) {
2187
2235
 
2188
2236
  // src/scaffold/post-scaffold.ts
2189
2237
  import { execSync } from "child_process";
2190
- import { writeFileSync as writeFileSync2 } from "fs";
2238
+ import { writeFileSync as writeFileSync3 } from "fs";
2191
2239
  import { join as join4, basename } from "path";
2192
2240
  import pc2 from "picocolors";
2193
2241
  function runPostScaffold(input, callbacks) {
@@ -2354,7 +2402,7 @@ function generateClaudeMd(projectDir, config, blockNames) {
2354
2402
  lines.push("```");
2355
2403
  lines.push("");
2356
2404
  const content = lines.join("\n");
2357
- writeFileSync2(join4(projectDir, "CLAUDE.md"), content, "utf-8");
2405
+ writeFileSync3(join4(projectDir, "CLAUDE.md"), content, "utf-8");
2358
2406
  }
2359
2407
 
2360
2408
  // src/ai/prompt-builder.ts
@@ -3328,7 +3376,7 @@ var RECIPES = {
3328
3376
  themeSwitcher: false
3329
3377
  },
3330
3378
  agency: {
3331
- renderMode: "static",
3379
+ renderMode: "server",
3332
3380
  deployTarget: "cloudflare",
3333
3381
  database: "none",
3334
3382
  cssEngine: "tailwind",
@@ -3407,7 +3455,7 @@ var RECIPES = {
3407
3455
  themeSwitcher: false
3408
3456
  },
3409
3457
  portfolio: {
3410
- renderMode: "static",
3458
+ renderMode: "server",
3411
3459
  deployTarget: "cloudflare",
3412
3460
  database: "none",
3413
3461
  cssEngine: "tailwind",
@@ -3560,6 +3608,33 @@ var createCommand = defineCommand({
3560
3608
  }
3561
3609
  },
3562
3610
  async run({ args: args2 }) {
3611
+ const hasExplicitFlags = !!(args2.render || args2.deploy || args2.blocks || args2.database || args2.css || args2.locales || args2.palette || args2.recipe);
3612
+ let forceManual = false;
3613
+ if (!args2.manual && !hasExplicitFlags) {
3614
+ const providerName = parseProviderName(args2.provider);
3615
+ if (args2.provider && !providerName) {
3616
+ console.error(pc3.red(`\u2716 Unknown provider: ${String(args2.provider)}`));
3617
+ console.error(pc3.dim(` Available: ${VALID_PROVIDER_NAMES.join(", ")}`));
3618
+ process.exitCode = 1;
3619
+ return;
3620
+ }
3621
+ const legacyProvider = await resolveProvider({
3622
+ provider: providerName,
3623
+ skipOllamaDetect: false
3624
+ });
3625
+ if (!legacyProvider) {
3626
+ showNoProviderGuide();
3627
+ const fallback = await p2.confirm({
3628
+ message: "Would you like to continue in manual mode instead?",
3629
+ initialValue: true
3630
+ });
3631
+ if (p2.isCancel(fallback) || !fallback) {
3632
+ process.exitCode = 1;
3633
+ return;
3634
+ }
3635
+ forceManual = true;
3636
+ }
3637
+ }
3563
3638
  const registryResult = await fetchRegistryIndex();
3564
3639
  if (!isOk(registryResult)) {
3565
3640
  console.error(pc3.red(`\u2716 Failed to fetch block registry: ${registryResult.error.message}`));
@@ -3568,8 +3643,7 @@ var createCommand = defineCommand({
3568
3643
  }
3569
3644
  const manifests = registryResult.value.blocks;
3570
3645
  const allPalettes = registryResult.value.palettes.length > 0 ? registryResult.value.palettes : loadAllPalettes();
3571
- const hasExplicitFlags = !!(args2.render || args2.deploy || args2.blocks || args2.database || args2.css || args2.locales || args2.palette || args2.recipe);
3572
- if (args2.manual && !args2.yes) {
3646
+ if ((args2.manual || forceManual) && !args2.yes) {
3573
3647
  const defaultProjectName = args2.dir ? basename2(resolve2(args2.dir)) : "my-project";
3574
3648
  const config = await runManualFlow({
3575
3649
  defaultProjectName,
@@ -3584,7 +3658,7 @@ var createCommand = defineCommand({
3584
3658
  const finalConfig = { ...config, projectDir };
3585
3659
  return runScaffold(finalConfig, manifests, allPalettes, args2["dry-run"] ?? false, args2.verbose ?? false, !(args2.install ?? true), !(args2.git ?? true));
3586
3660
  }
3587
- if (args2.manual || hasExplicitFlags) {
3661
+ if (args2.manual || hasExplicitFlags || forceManual) {
3588
3662
  return runFlagDrivenMode(args2, manifests, allPalettes);
3589
3663
  }
3590
3664
  return runAIMode(args2, manifests, allPalettes);
@@ -3818,7 +3892,7 @@ async function runScaffold(config, manifests, allPalettes, dryRun, verbose, skip
3818
3892
  const fullPath = join6(config.projectDir, relativePath);
3819
3893
  const parentDir = join6(fullPath, "..");
3820
3894
  mkdirSync4(parentDir, { recursive: true });
3821
- writeFileSync3(fullPath, content, "utf-8");
3895
+ writeFileSync4(fullPath, content, "utf-8");
3822
3896
  filesWritten++;
3823
3897
  if (verbose) {
3824
3898
  console.log(pc3.dim(` created ${relativePath}`));
@@ -3907,7 +3981,7 @@ function showNoProviderGuide() {
3907
3981
  // src/cli/commands/add.ts
3908
3982
  import { defineCommand as defineCommand2 } from "citty";
3909
3983
  import pc4 from "picocolors";
3910
- import { readFileSync as readFileSync5, writeFileSync as writeFileSync4, existsSync as existsSync4, mkdirSync as mkdirSync5 } from "fs";
3984
+ import { readFileSync as readFileSync5, writeFileSync as writeFileSync5, existsSync as existsSync4, mkdirSync as mkdirSync5 } from "fs";
3911
3985
  import { join as join7, dirname as dirname3 } from "path";
3912
3986
  var addCommand = defineCommand2({
3913
3987
  meta: {
@@ -4034,7 +4108,7 @@ var addCommand = defineCommand2({
4034
4108
  }
4035
4109
  for (const file of filesToWrite) {
4036
4110
  mkdirSync5(dirname3(file.path), { recursive: true });
4037
- writeFileSync4(file.path, file.content);
4111
+ writeFileSync5(file.path, file.content);
4038
4112
  if (typedArgs.verbose) {
4039
4113
  console.log(` ${pc4.dim("\u2192")} ${file.path}`);
4040
4114
  }
@@ -4050,7 +4124,7 @@ var addCommand = defineCommand2({
4050
4124
  installedAt: now
4051
4125
  });
4052
4126
  }
4053
- writeFileSync4(manifestPath, JSON.stringify(manifest2, null, 2) + "\n");
4127
+ writeFileSync5(manifestPath, JSON.stringify(manifest2, null, 2) + "\n");
4054
4128
  console.log();
4055
4129
  for (const name of blocksToAdd) {
4056
4130
  const isDep = name !== blockName;
@@ -4091,7 +4165,7 @@ function resolveDependencies2(blockName, installedNames, manifests) {
4091
4165
  // src/cli/commands/remove.ts
4092
4166
  import { defineCommand as defineCommand3 } from "citty";
4093
4167
  import pc5 from "picocolors";
4094
- import { readFileSync as readFileSync6, writeFileSync as writeFileSync5, existsSync as existsSync5, unlinkSync, readdirSync as readdirSync3, rmdirSync } from "fs";
4168
+ import { readFileSync as readFileSync6, writeFileSync as writeFileSync6, existsSync as existsSync5, unlinkSync, readdirSync as readdirSync3, rmdirSync } from "fs";
4095
4169
  import { join as join8, dirname as dirname4 } from "path";
4096
4170
  var removeCommand = defineCommand3({
4097
4171
  meta: {
@@ -4186,7 +4260,7 @@ var removeCommand = defineCommand3({
4186
4260
  tryRemoveEmptyDir(dirname4(filePath), cwd);
4187
4261
  }
4188
4262
  manifest2.blocks = manifest2.blocks.filter((b) => b.name !== blockName);
4189
- writeFileSync5(manifestPath, JSON.stringify(manifest2, null, 2) + "\n");
4263
+ writeFileSync6(manifestPath, JSON.stringify(manifest2, null, 2) + "\n");
4190
4264
  console.log();
4191
4265
  console.log(` ${pc5.red("-")} ${pc5.bold(blockName)} removed`);
4192
4266
  if (dependents.length > 0) {
@@ -4668,7 +4742,7 @@ async function listBlocksHandler(args2) {
4668
4742
  }
4669
4743
 
4670
4744
  // src/mcp/tools/add-block.ts
4671
- import { readFileSync as readFileSync9, writeFileSync as writeFileSync6, existsSync as existsSync8, mkdirSync as mkdirSync6 } from "fs";
4745
+ import { readFileSync as readFileSync9, writeFileSync as writeFileSync7, existsSync as existsSync8, mkdirSync as mkdirSync6 } from "fs";
4672
4746
  import { join as join11, dirname as dirname5 } from "path";
4673
4747
  async function addBlock2(input) {
4674
4748
  const { name, variant = "default", projectDirectory } = input;
@@ -4734,7 +4808,7 @@ async function addBlock2(input) {
4734
4808
  }
4735
4809
  const filePath = join11(projectDirectory, file.destination);
4736
4810
  mkdirSync6(dirname5(filePath), { recursive: true });
4737
- writeFileSync6(filePath, content);
4811
+ writeFileSync7(filePath, content);
4738
4812
  filesCreated++;
4739
4813
  }
4740
4814
  }
@@ -4749,7 +4823,7 @@ async function addBlock2(input) {
4749
4823
  installedAt: now
4750
4824
  });
4751
4825
  }
4752
- writeFileSync6(manifestPath, JSON.stringify(manifest2, null, 2) + "\n");
4826
+ writeFileSync7(manifestPath, JSON.stringify(manifest2, null, 2) + "\n");
4753
4827
  return ok({ addedBlocks: blocksToAdd, filesCreated });
4754
4828
  }
4755
4829
  function resolveDependencies3(blockName, installedNames, manifests) {
@@ -4772,7 +4846,7 @@ function resolveDependencies3(blockName, installedNames, manifests) {
4772
4846
  // src/mcp/tools/remove-block.ts
4773
4847
  import {
4774
4848
  readFileSync as readFileSync10,
4775
- writeFileSync as writeFileSync7,
4849
+ writeFileSync as writeFileSync8,
4776
4850
  existsSync as existsSync9,
4777
4851
  unlinkSync as unlinkSync2,
4778
4852
  readdirSync as readdirSync4,
@@ -4826,7 +4900,7 @@ async function removeBlock(input) {
4826
4900
  tryRemoveEmptyDirectory(dirname6(filePath), projectDirectory);
4827
4901
  }
4828
4902
  manifest2.blocks = manifest2.blocks.filter((block) => block.name !== name);
4829
- writeFileSync7(manifestPath, JSON.stringify(manifest2, null, 2) + "\n");
4903
+ writeFileSync8(manifestPath, JSON.stringify(manifest2, null, 2) + "\n");
4830
4904
  return ok({
4831
4905
  removedBlock: name,
4832
4906
  filesRemoved: filesToRemove.length,
@@ -4980,7 +5054,7 @@ function getProjectStatus(input) {
4980
5054
  }
4981
5055
 
4982
5056
  // src/mcp/tools/scaffold-project.ts
4983
- import { mkdirSync as mkdirSync7, writeFileSync as writeFileSync8 } from "fs";
5057
+ import { mkdirSync as mkdirSync7, writeFileSync as writeFileSync9 } from "fs";
4984
5058
  import { join as join14, basename as basename3 } from "path";
4985
5059
  var DEFAULT_COLORS2 = {
4986
5060
  primary: "#6366f1",
@@ -5055,7 +5129,7 @@ async function scaffoldProject(input) {
5055
5129
  const fullPath = join14(projectDirectory, relativePath);
5056
5130
  const parentDirectory = join14(fullPath, "..");
5057
5131
  mkdirSync7(parentDirectory, { recursive: true });
5058
- writeFileSync8(fullPath, content, "utf-8");
5132
+ writeFileSync9(fullPath, content, "utf-8");
5059
5133
  filesCreated++;
5060
5134
  }
5061
5135
  return ok({