@raystack/chronicle 0.1.2 → 0.2.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/dist/cli/index.js CHANGED
@@ -9044,8 +9044,9 @@ var {
9044
9044
  } = import__.default;
9045
9045
 
9046
9046
  // src/cli/commands/init.ts
9047
- import fs from "fs";
9048
- import path from "path";
9047
+ import { execSync as execSync2 } from "child_process";
9048
+ import fs3 from "fs";
9049
+ import path4 from "path";
9049
9050
 
9050
9051
  // ../../node_modules/.bun/chalk@5.6.2/node_modules/chalk/source/vendor/ansi-styles/index.js
9051
9052
  var ANSI_BACKGROUND_OFFSET = 10;
@@ -9582,6 +9583,156 @@ var $stringify = publicApi.stringify;
9582
9583
  var $visit = visit.visit;
9583
9584
  var $visitAsync = visit.visitAsync;
9584
9585
 
9586
+ // src/cli/utils/config.ts
9587
+ import fs from "fs";
9588
+ import path from "path";
9589
+ function resolveConfigPath(contentDir) {
9590
+ const cwdPath = path.join(process.cwd(), "chronicle.yaml");
9591
+ if (fs.existsSync(cwdPath))
9592
+ return cwdPath;
9593
+ const contentPath = path.join(contentDir, "chronicle.yaml");
9594
+ if (fs.existsSync(contentPath))
9595
+ return contentPath;
9596
+ return null;
9597
+ }
9598
+ function loadCLIConfig(contentDir) {
9599
+ const configPath = resolveConfigPath(contentDir);
9600
+ if (!configPath) {
9601
+ console.log(source_default.red(`Error: chronicle.yaml not found in '${process.cwd()}' or '${contentDir}'`));
9602
+ console.log(source_default.gray(`Run 'chronicle init' to create one`));
9603
+ process.exit(1);
9604
+ }
9605
+ const config = $parse(fs.readFileSync(configPath, "utf-8"));
9606
+ return {
9607
+ config,
9608
+ configPath,
9609
+ contentDir
9610
+ };
9611
+ }
9612
+ // src/cli/utils/process.ts
9613
+ function attachLifecycleHandlers(child) {
9614
+ child.on("close", (code) => process.exit(code ?? 0));
9615
+ process.on("SIGINT", () => child.kill("SIGINT"));
9616
+ process.on("SIGTERM", () => child.kill("SIGTERM"));
9617
+ }
9618
+ // src/cli/utils/scaffold.ts
9619
+ import { execSync } from "child_process";
9620
+ import { createRequire as createRequire2 } from "module";
9621
+ import fs2 from "fs";
9622
+ import path3 from "path";
9623
+
9624
+ // src/cli/utils/resolve.ts
9625
+ import path2 from "path";
9626
+ import { fileURLToPath } from "url";
9627
+ var PACKAGE_ROOT = path2.resolve(path2.dirname(fileURLToPath(import.meta.url)), "..", "..");
9628
+
9629
+ // src/cli/utils/scaffold.ts
9630
+ var COPY_FILES = ["src", "source.config.ts", "tsconfig.json"];
9631
+ function copyRecursive(src, dest) {
9632
+ const stat = fs2.statSync(src);
9633
+ if (stat.isDirectory()) {
9634
+ fs2.mkdirSync(dest, { recursive: true });
9635
+ for (const entry of fs2.readdirSync(src)) {
9636
+ copyRecursive(path3.join(src, entry), path3.join(dest, entry));
9637
+ }
9638
+ } else {
9639
+ fs2.copyFileSync(src, dest);
9640
+ }
9641
+ }
9642
+ function ensureRemoved(targetPath) {
9643
+ try {
9644
+ fs2.lstatSync(targetPath);
9645
+ fs2.rmSync(targetPath, { recursive: true, force: true });
9646
+ } catch {}
9647
+ }
9648
+ function detectPackageManager() {
9649
+ if (process.env.npm_config_user_agent) {
9650
+ return process.env.npm_config_user_agent.split("/")[0];
9651
+ }
9652
+ const cwd = process.cwd();
9653
+ if (fs2.existsSync(path3.join(cwd, "bun.lock")) || fs2.existsSync(path3.join(cwd, "bun.lockb")))
9654
+ return "bun";
9655
+ if (fs2.existsSync(path3.join(cwd, "pnpm-lock.yaml")))
9656
+ return "pnpm";
9657
+ if (fs2.existsSync(path3.join(cwd, "yarn.lock")))
9658
+ return "yarn";
9659
+ return "npm";
9660
+ }
9661
+ function generateNextConfig(scaffoldPath) {
9662
+ const config = `import { createMDX } from 'fumadocs-mdx/next'
9663
+
9664
+ const withMDX = createMDX()
9665
+
9666
+ /** @type {import('next').NextConfig} */
9667
+ const nextConfig = {
9668
+ reactStrictMode: true,
9669
+ }
9670
+
9671
+ export default withMDX(nextConfig)
9672
+ `;
9673
+ fs2.writeFileSync(path3.join(scaffoldPath, "next.config.mjs"), config);
9674
+ }
9675
+ function createPackageJson() {
9676
+ return {
9677
+ name: "chronicle-docs",
9678
+ private: true,
9679
+ dependencies: {
9680
+ "@raystack/chronicle": `^${getChronicleVersion()}`
9681
+ },
9682
+ devDependencies: {
9683
+ "@raystack/tools-config": "0.56.0",
9684
+ "openapi-types": "^12.1.3",
9685
+ typescript: "5.9.3",
9686
+ "@types/react": "^19.2.10",
9687
+ "@types/node": "^25.1.0"
9688
+ }
9689
+ };
9690
+ }
9691
+ function ensureDeps() {
9692
+ const cwd = process.cwd();
9693
+ const cwdPkgJson = path3.join(cwd, "package.json");
9694
+ const cwdNodeModules = path3.join(cwd, "node_modules");
9695
+ if (fs2.existsSync(cwdPkgJson) && fs2.existsSync(cwdNodeModules)) {
9696
+ return;
9697
+ }
9698
+ if (!fs2.existsSync(cwdPkgJson)) {
9699
+ fs2.writeFileSync(cwdPkgJson, JSON.stringify(createPackageJson(), null, 2) + `
9700
+ `);
9701
+ }
9702
+ if (!fs2.existsSync(cwdNodeModules)) {
9703
+ const pm = detectPackageManager();
9704
+ console.log(source_default.cyan(`Installing dependencies with ${pm}...`));
9705
+ execSync(`${pm} install`, { cwd, stdio: "inherit" });
9706
+ }
9707
+ }
9708
+ function getChronicleVersion() {
9709
+ const pkgPath = path3.join(PACKAGE_ROOT, "package.json");
9710
+ const pkg = JSON.parse(fs2.readFileSync(pkgPath, "utf-8"));
9711
+ return pkg.version;
9712
+ }
9713
+ function resolveNextCli() {
9714
+ const chronicleRequire = createRequire2(path3.join(PACKAGE_ROOT, "package.json"));
9715
+ return chronicleRequire.resolve("next/dist/bin/next");
9716
+ }
9717
+ function scaffoldDir(contentDir) {
9718
+ const scaffoldPath = path3.join(process.cwd(), ".chronicle");
9719
+ if (!fs2.existsSync(scaffoldPath)) {
9720
+ fs2.mkdirSync(scaffoldPath, { recursive: true });
9721
+ }
9722
+ for (const name of COPY_FILES) {
9723
+ const src = path3.join(PACKAGE_ROOT, name);
9724
+ const dest = path3.join(scaffoldPath, name);
9725
+ ensureRemoved(dest);
9726
+ copyRecursive(src, dest);
9727
+ }
9728
+ generateNextConfig(scaffoldPath);
9729
+ const contentLink = path3.join(scaffoldPath, "content");
9730
+ ensureRemoved(contentLink);
9731
+ fs2.symlinkSync(path3.resolve(contentDir), contentLink);
9732
+ ensureDeps();
9733
+ console.log(source_default.gray(`Scaffold: ${scaffoldPath}`));
9734
+ return scaffoldPath;
9735
+ }
9585
9736
  // src/cli/commands/init.ts
9586
9737
  function createConfig() {
9587
9738
  return {
@@ -9591,6 +9742,28 @@ function createConfig() {
9591
9742
  search: { enabled: true, placeholder: "Search documentation..." }
9592
9743
  };
9593
9744
  }
9745
+ function createPackageJson2(name) {
9746
+ return {
9747
+ name,
9748
+ private: true,
9749
+ type: "module",
9750
+ scripts: {
9751
+ dev: "chronicle dev",
9752
+ build: "chronicle build",
9753
+ start: "chronicle start"
9754
+ },
9755
+ dependencies: {
9756
+ "@raystack/chronicle": `^${getChronicleVersion()}`
9757
+ },
9758
+ devDependencies: {
9759
+ "@raystack/tools-config": "0.56.0",
9760
+ "openapi-types": "^12.1.3",
9761
+ typescript: "5.9.3",
9762
+ "@types/react": "^19.2.10",
9763
+ "@types/node": "^25.1.0"
9764
+ }
9765
+ };
9766
+ }
9594
9767
  var sampleMdx = `---
9595
9768
  title: Welcome
9596
9769
  description: Getting started with your documentation
@@ -9601,77 +9774,128 @@ order: 1
9601
9774
 
9602
9775
  This is your documentation home page.
9603
9776
  `;
9604
- var initCommand = new Command("init").description("Initialize a new Chronicle project").option("-d, --dir <path>", "Content directory", ".").action((options) => {
9605
- const contentDir = path.resolve(options.dir);
9606
- if (!fs.existsSync(contentDir)) {
9607
- fs.mkdirSync(contentDir, { recursive: true });
9777
+ var initCommand = new Command("init").description("Initialize a new Chronicle project").option("-c, --content <path>", "Content directory name", "content").action((options) => {
9778
+ const projectDir = process.cwd();
9779
+ const dirName = path4.basename(projectDir) || "docs";
9780
+ const contentDir = path4.join(projectDir, options.content);
9781
+ if (!fs3.existsSync(contentDir)) {
9782
+ fs3.mkdirSync(contentDir, { recursive: true });
9608
9783
  console.log(source_default.green("✓"), "Created", contentDir);
9609
9784
  }
9610
- const configPath = path.join(contentDir, "chronicle.yaml");
9611
- if (!fs.existsSync(configPath)) {
9612
- fs.writeFileSync(configPath, $stringify(createConfig()));
9785
+ const packageJsonPath = path4.join(projectDir, "package.json");
9786
+ if (!fs3.existsSync(packageJsonPath)) {
9787
+ fs3.writeFileSync(packageJsonPath, JSON.stringify(createPackageJson2(dirName), null, 2) + `
9788
+ `);
9789
+ console.log(source_default.green("✓"), "Created", packageJsonPath);
9790
+ } else {
9791
+ const existing = JSON.parse(fs3.readFileSync(packageJsonPath, "utf-8"));
9792
+ const template = createPackageJson2(dirName);
9793
+ let updated = false;
9794
+ if (existing.type !== "module") {
9795
+ existing.type = "module";
9796
+ updated = true;
9797
+ }
9798
+ if (!existing.scripts)
9799
+ existing.scripts = {};
9800
+ for (const [key, value] of Object.entries(template.scripts)) {
9801
+ if (!existing.scripts[key]) {
9802
+ existing.scripts[key] = value;
9803
+ updated = true;
9804
+ }
9805
+ }
9806
+ if (!existing.dependencies)
9807
+ existing.dependencies = {};
9808
+ for (const [key, value] of Object.entries(template.dependencies)) {
9809
+ if (!existing.dependencies[key]) {
9810
+ existing.dependencies[key] = value;
9811
+ updated = true;
9812
+ }
9813
+ }
9814
+ if (!existing.devDependencies)
9815
+ existing.devDependencies = {};
9816
+ for (const [key, value] of Object.entries(template.devDependencies)) {
9817
+ if (!existing.devDependencies[key]) {
9818
+ existing.devDependencies[key] = value;
9819
+ updated = true;
9820
+ }
9821
+ }
9822
+ if (updated) {
9823
+ fs3.writeFileSync(packageJsonPath, JSON.stringify(existing, null, 2) + `
9824
+ `);
9825
+ console.log(source_default.green("✓"), "Updated", packageJsonPath, "with missing scripts/deps");
9826
+ } else {
9827
+ console.log(source_default.yellow("⚠"), packageJsonPath, "already has all required entries");
9828
+ }
9829
+ }
9830
+ const configPath = path4.join(projectDir, "chronicle.yaml");
9831
+ if (!fs3.existsSync(configPath)) {
9832
+ fs3.writeFileSync(configPath, $stringify(createConfig()));
9613
9833
  console.log(source_default.green("✓"), "Created", configPath);
9614
9834
  } else {
9615
9835
  console.log(source_default.yellow("⚠"), configPath, "already exists");
9616
9836
  }
9617
- const indexPath = path.join(contentDir, "index.mdx");
9618
- if (!fs.existsSync(indexPath)) {
9619
- fs.writeFileSync(indexPath, sampleMdx);
9837
+ const contentFiles = fs3.readdirSync(contentDir);
9838
+ if (contentFiles.length === 0) {
9839
+ const indexPath = path4.join(contentDir, "index.mdx");
9840
+ fs3.writeFileSync(indexPath, sampleMdx);
9620
9841
  console.log(source_default.green("✓"), "Created", indexPath);
9621
9842
  }
9843
+ const gitignorePath = path4.join(projectDir, ".gitignore");
9844
+ const gitignoreEntries = [".chronicle", "node_modules", ".next"];
9845
+ if (fs3.existsSync(gitignorePath)) {
9846
+ const existing = fs3.readFileSync(gitignorePath, "utf-8");
9847
+ const missing = gitignoreEntries.filter((e) => !existing.includes(e));
9848
+ if (missing.length > 0) {
9849
+ fs3.appendFileSync(gitignorePath, `
9850
+ ${missing.join(`
9851
+ `)}
9852
+ `);
9853
+ console.log(source_default.green("✓"), "Added", missing.join(", "), "to .gitignore");
9854
+ }
9855
+ } else {
9856
+ fs3.writeFileSync(gitignorePath, `${gitignoreEntries.join(`
9857
+ `)}
9858
+ `);
9859
+ console.log(source_default.green("✓"), "Created .gitignore");
9860
+ }
9861
+ const pm = detectPackageManager();
9862
+ console.log(source_default.cyan(`
9863
+ Installing dependencies with ${pm}...`));
9864
+ execSync2(`${pm} install`, { cwd: projectDir, stdio: "inherit" });
9865
+ loadCLIConfig(contentDir);
9866
+ scaffoldDir(contentDir);
9867
+ const runCmd = pm === "npm" ? "npx" : pm === "bun" ? "bunx" : `${pm} dlx`;
9622
9868
  console.log(source_default.green(`
9623
9869
  ✓ Chronicle initialized!`));
9624
9870
  console.log(`
9625
- Run`, source_default.cyan("chronicle dev"), "to start development server");
9871
+ Run`, source_default.cyan(`${runCmd} chronicle dev`), "to start development server");
9626
9872
  });
9627
9873
 
9628
9874
  // src/cli/commands/dev.ts
9629
9875
  import { spawn } from "child_process";
9630
- import path3 from "path";
9631
-
9632
- // src/cli/utils/config.ts
9633
- import fs2 from "fs";
9634
- import path2 from "path";
9635
- function resolveContentDir(contentFlag) {
9636
- if (contentFlag)
9637
- return path2.resolve(contentFlag);
9638
- if (process.env.CHRONICLE_CONTENT_DIR)
9639
- return path2.resolve(process.env.CHRONICLE_CONTENT_DIR);
9640
- return process.cwd();
9641
- }
9642
- function loadCLIConfig(contentDir) {
9643
- const configPath = path2.join(contentDir, "chronicle.yaml");
9644
- if (!fs2.existsSync(configPath)) {
9645
- console.log(source_default.red("Error: chronicle.yaml not found in"), contentDir);
9646
- console.log(source_default.gray(`Run 'chronicle init' to create one`));
9876
+ import path5 from "path";
9877
+ import fs4 from "fs";
9878
+ var devCommand = new Command("dev").description("Start development server").option("-p, --port <port>", "Port number", "3000").action((options) => {
9879
+ const scaffoldPath = path5.join(process.cwd(), ".chronicle");
9880
+ if (!fs4.existsSync(scaffoldPath)) {
9881
+ console.log(source_default.red("Error: .chronicle/ not found. Run"), source_default.cyan("chronicle init"), source_default.red("first."));
9882
+ process.exit(1);
9883
+ }
9884
+ let nextCli;
9885
+ try {
9886
+ nextCli = resolveNextCli();
9887
+ } catch {
9888
+ console.log(source_default.red("Error: Next.js CLI not found. Run"), source_default.cyan("chronicle init"), source_default.red("first."));
9647
9889
  process.exit(1);
9648
9890
  }
9649
- const config = $parse(fs2.readFileSync(configPath, "utf-8"));
9650
- return {
9651
- config,
9652
- configPath,
9653
- contentDir
9654
- };
9655
- }
9656
- // src/cli/utils/process.ts
9657
- function attachLifecycleHandlers(child) {
9658
- child.on("close", (code) => process.exit(code ?? 0));
9659
- process.on("SIGINT", () => child.kill("SIGINT"));
9660
- process.on("SIGTERM", () => child.kill("SIGTERM"));
9661
- }
9662
- // src/cli/commands/dev.ts
9663
- var nextBin = path3.join("/home/runner/work/chronicle/chronicle/packages/chronicle", "node_modules", ".bin", process.platform === "win32" ? "next.cmd" : "next");
9664
- var devCommand = new Command("dev").description("Start development server").option("-p, --port <port>", "Port number", "3000").option("-c, --content <path>", "Content directory").action((options) => {
9665
- const contentDir = resolveContentDir(options.content);
9666
- loadCLIConfig(contentDir);
9667
9891
  console.log(source_default.cyan("Starting dev server..."));
9668
- console.log(source_default.gray(`Content: ${contentDir}`));
9669
- const child = spawn(nextBin, ["dev", "-p", options.port], {
9892
+ const child = spawn(process.execPath, [nextCli, "dev", "-p", options.port], {
9670
9893
  stdio: "inherit",
9671
- cwd: "/home/runner/work/chronicle/chronicle/packages/chronicle",
9894
+ cwd: scaffoldPath,
9672
9895
  env: {
9673
9896
  ...process.env,
9674
- CHRONICLE_CONTENT_DIR: contentDir
9897
+ CHRONICLE_PROJECT_ROOT: process.cwd(),
9898
+ CHRONICLE_CONTENT_DIR: "./content"
9675
9899
  }
9676
9900
  });
9677
9901
  attachLifecycleHandlers(child);
@@ -9679,19 +9903,29 @@ var devCommand = new Command("dev").description("Start development server").opti
9679
9903
 
9680
9904
  // src/cli/commands/build.ts
9681
9905
  import { spawn as spawn2 } from "child_process";
9682
- import path4 from "path";
9683
- var nextBin2 = path4.join("/home/runner/work/chronicle/chronicle/packages/chronicle", "node_modules", ".bin", process.platform === "win32" ? "next.cmd" : "next");
9684
- var buildCommand = new Command("build").description("Build for production").option("-c, --content <path>", "Content directory").action((options) => {
9685
- const contentDir = resolveContentDir(options.content);
9686
- loadCLIConfig(contentDir);
9906
+ import path6 from "path";
9907
+ import fs5 from "fs";
9908
+ var buildCommand = new Command("build").description("Build for production").action(() => {
9909
+ const scaffoldPath = path6.join(process.cwd(), ".chronicle");
9910
+ if (!fs5.existsSync(scaffoldPath)) {
9911
+ console.log(source_default.red("Error: .chronicle/ not found. Run"), source_default.cyan("chronicle init"), source_default.red("first."));
9912
+ process.exit(1);
9913
+ }
9914
+ let nextCli;
9915
+ try {
9916
+ nextCli = resolveNextCli();
9917
+ } catch {
9918
+ console.log(source_default.red("Error: Next.js CLI not found. Run"), source_default.cyan("chronicle init"), source_default.red("first."));
9919
+ process.exit(1);
9920
+ }
9687
9921
  console.log(source_default.cyan("Building for production..."));
9688
- console.log(source_default.gray(`Content: ${contentDir}`));
9689
- const child = spawn2(nextBin2, ["build"], {
9922
+ const child = spawn2(process.execPath, [nextCli, "build"], {
9690
9923
  stdio: "inherit",
9691
- cwd: "/home/runner/work/chronicle/chronicle/packages/chronicle",
9924
+ cwd: scaffoldPath,
9692
9925
  env: {
9693
9926
  ...process.env,
9694
- CHRONICLE_CONTENT_DIR: contentDir
9927
+ CHRONICLE_PROJECT_ROOT: process.cwd(),
9928
+ CHRONICLE_CONTENT_DIR: "./content"
9695
9929
  }
9696
9930
  });
9697
9931
  attachLifecycleHandlers(child);
@@ -9699,19 +9933,29 @@ var buildCommand = new Command("build").description("Build for production").opti
9699
9933
 
9700
9934
  // src/cli/commands/start.ts
9701
9935
  import { spawn as spawn3 } from "child_process";
9702
- import path5 from "path";
9703
- var nextBin3 = path5.join("/home/runner/work/chronicle/chronicle/packages/chronicle", "node_modules", ".bin", process.platform === "win32" ? "next.cmd" : "next");
9704
- var startCommand = new Command("start").description("Start production server").option("-p, --port <port>", "Port number", "3000").option("-c, --content <path>", "Content directory").action((options) => {
9705
- const contentDir = resolveContentDir(options.content);
9706
- loadCLIConfig(contentDir);
9936
+ import path7 from "path";
9937
+ import fs6 from "fs";
9938
+ var startCommand = new Command("start").description("Start production server").option("-p, --port <port>", "Port number", "3000").action((options) => {
9939
+ const scaffoldPath = path7.join(process.cwd(), ".chronicle");
9940
+ if (!fs6.existsSync(scaffoldPath)) {
9941
+ console.log(source_default.red("Error: .chronicle/ not found. Run"), source_default.cyan("chronicle init"), source_default.red("first."));
9942
+ process.exit(1);
9943
+ }
9944
+ let nextCli;
9945
+ try {
9946
+ nextCli = resolveNextCli();
9947
+ } catch {
9948
+ console.log(source_default.red("Error: Next.js CLI not found. Run"), source_default.cyan("chronicle init"), source_default.red("first."));
9949
+ process.exit(1);
9950
+ }
9707
9951
  console.log(source_default.cyan("Starting production server..."));
9708
- console.log(source_default.gray(`Content: ${contentDir}`));
9709
- const child = spawn3(nextBin3, ["start", "-p", options.port], {
9952
+ const child = spawn3(process.execPath, [nextCli, "start", "-p", options.port], {
9710
9953
  stdio: "inherit",
9711
- cwd: "/home/runner/work/chronicle/chronicle/packages/chronicle",
9954
+ cwd: scaffoldPath,
9712
9955
  env: {
9713
9956
  ...process.env,
9714
- CHRONICLE_CONTENT_DIR: contentDir
9957
+ CHRONICLE_PROJECT_ROOT: process.cwd(),
9958
+ CHRONICLE_CONTENT_DIR: "./content"
9715
9959
  }
9716
9960
  });
9717
9961
  attachLifecycleHandlers(child);
@@ -9719,20 +9963,30 @@ var startCommand = new Command("start").description("Start production server").o
9719
9963
 
9720
9964
  // src/cli/commands/serve.ts
9721
9965
  import { spawn as spawn4 } from "child_process";
9722
- import path6 from "path";
9723
- var nextBin4 = path6.join("/home/runner/work/chronicle/chronicle/packages/chronicle", "node_modules", ".bin", process.platform === "win32" ? "next.cmd" : "next");
9724
- var serveCommand = new Command("serve").description("Build and start production server").option("-p, --port <port>", "Port number", "3000").option("-c, --content <path>", "Content directory").action((options) => {
9725
- const contentDir = resolveContentDir(options.content);
9726
- loadCLIConfig(contentDir);
9966
+ import path8 from "path";
9967
+ import fs7 from "fs";
9968
+ var serveCommand = new Command("serve").description("Build and start production server").option("-p, --port <port>", "Port number", "3000").action((options) => {
9969
+ const scaffoldPath = path8.join(process.cwd(), ".chronicle");
9970
+ if (!fs7.existsSync(scaffoldPath)) {
9971
+ console.log(source_default.red("Error: .chronicle/ not found. Run"), source_default.cyan("chronicle init"), source_default.red("first."));
9972
+ process.exit(1);
9973
+ }
9974
+ let nextCli;
9975
+ try {
9976
+ nextCli = resolveNextCli();
9977
+ } catch {
9978
+ console.log(source_default.red("Error: Next.js CLI not found. Run"), source_default.cyan("chronicle init"), source_default.red("first."));
9979
+ process.exit(1);
9980
+ }
9727
9981
  const env2 = {
9728
9982
  ...process.env,
9729
- CHRONICLE_CONTENT_DIR: contentDir
9983
+ CHRONICLE_PROJECT_ROOT: process.cwd(),
9984
+ CHRONICLE_CONTENT_DIR: "./content"
9730
9985
  };
9731
9986
  console.log(source_default.cyan("Building for production..."));
9732
- console.log(source_default.gray(`Content: ${contentDir}`));
9733
- const buildChild = spawn4(nextBin4, ["build"], {
9987
+ const buildChild = spawn4(process.execPath, [nextCli, "build"], {
9734
9988
  stdio: "inherit",
9735
- cwd: "/home/runner/work/chronicle/chronicle/packages/chronicle",
9989
+ cwd: scaffoldPath,
9736
9990
  env: env2
9737
9991
  });
9738
9992
  process.once("SIGINT", () => buildChild.kill("SIGINT"));
@@ -9743,9 +9997,9 @@ var serveCommand = new Command("serve").description("Build and start production
9743
9997
  process.exit(code ?? 1);
9744
9998
  }
9745
9999
  console.log(source_default.cyan("Starting production server..."));
9746
- const startChild = spawn4(nextBin4, ["start", "-p", options.port], {
10000
+ const startChild = spawn4(process.execPath, [nextCli, "start", "-p", options.port], {
9747
10001
  stdio: "inherit",
9748
- cwd: "/home/runner/work/chronicle/chronicle/packages/chronicle",
10002
+ cwd: scaffoldPath,
9749
10003
  env: env2
9750
10004
  });
9751
10005
  attachLifecycleHandlers(startChild);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@raystack/chronicle",
3
- "version": "0.1.2",
3
+ "version": "0.2.0",
4
4
  "description": "Config-driven documentation framework",
5
5
  "license": "Apache-2.0",
6
6
  "type": "module",
@@ -10,7 +10,8 @@
10
10
  "src",
11
11
  "templates",
12
12
  "next.config.mjs",
13
- "source.config.ts"
13
+ "source.config.ts",
14
+ "tsconfig.json"
14
15
  ],
15
16
  "bin": {
16
17
  "chronicle": "./bin/chronicle.js"
@@ -27,7 +28,6 @@
27
28
  "@types/react": "^19.2.10",
28
29
  "@types/react-dom": "^19.2.3",
29
30
  "@types/semver": "^7.7.1",
30
- "openapi-types": "^12.1.3",
31
31
  "semver": "^7.7.4",
32
32
  "typescript": "5.9.3"
33
33
  },
@@ -38,11 +38,12 @@
38
38
  "@codemirror/view": "^6.39.14",
39
39
  "@heroicons/react": "^2.2.0",
40
40
  "@raystack/apsara": "^0.56.0",
41
+ "@types/unist": "^3.0.3",
41
42
  "chalk": "^5.6.2",
42
43
  "class-variance-authority": "^0.7.1",
43
44
  "codemirror": "^6.0.2",
44
45
  "commander": "^14.0.2",
45
- "fumadocs-core": "^16.4.9",
46
+ "fumadocs-core": "16.6.15",
46
47
  "fumadocs-mdx": "^14.2.6",
47
48
  "lodash": "^4.17.23",
48
49
  "mermaid": "^11.13.0",
@@ -53,7 +54,9 @@
53
54
  "remark-attr": "^0.11.1",
54
55
  "remark-directive": "^4.0.0",
55
56
  "slugify": "^1.6.6",
57
+ "unified": "^11.0.5",
56
58
  "unist-util-visit": "^5.1.0",
59
+ "openapi-types": "^12.1.3",
57
60
  "yaml": "^2.8.2",
58
61
  "zod": "^4.3.6"
59
62
  }
package/source.config.ts CHANGED
@@ -1,4 +1,5 @@
1
- import { defineDocs, defineConfig } from 'fumadocs-mdx/config'
1
+ import { defineDocs, defineConfig, frontmatterSchema } from 'fumadocs-mdx/config'
2
+ import { z } from 'zod'
2
3
  import remarkDirective from 'remark-directive'
3
4
  import { remarkDirectiveAdmonition, remarkMdxMermaid } from 'fumadocs-core/mdx-plugins'
4
5
  import remarkUnusedDirectives from './src/lib/remark-unused-directives'
@@ -8,6 +9,12 @@ const contentDir = process.env.CHRONICLE_CONTENT_DIR || './content'
8
9
  export const docs = defineDocs({
9
10
  dir: contentDir,
10
11
  docs: {
12
+ schema: frontmatterSchema.extend({
13
+ order: z.number().optional(),
14
+ }),
15
+ postprocess: {
16
+ includeProcessedMarkdown: true,
17
+ },
11
18
  files: ['**/*.mdx', '**/*.md', '!**/node_modules/**'],
12
19
  },
13
20
  })
@@ -0,0 +1,18 @@
1
+ import { source } from '@/lib/source'
2
+ import { loadConfig } from '@/lib/config'
3
+ import { getLLMText } from '@/lib/get-llm-text'
4
+
5
+ export const revalidate = false
6
+
7
+ export async function GET() {
8
+ const config = loadConfig()
9
+
10
+ if (!config.llms?.enabled) {
11
+ return new Response('Not Found', { status: 404 })
12
+ }
13
+
14
+ const scan = source.getPages().map(getLLMText)
15
+ const scanned = await Promise.all(scan)
16
+
17
+ return new Response(scanned.join('\n\n'))
18
+ }
@@ -0,0 +1,15 @@
1
+ import { source } from '@/lib/source'
2
+ import { loadConfig } from '@/lib/config'
3
+ import { llms } from 'fumadocs-core/source'
4
+
5
+ export const revalidate = false
6
+
7
+ export function GET() {
8
+ const config = loadConfig()
9
+
10
+ if (!config.llms?.enabled) {
11
+ return new Response('Not Found', { status: 404 })
12
+ }
13
+
14
+ return new Response(llms(source).index())
15
+ }
@@ -1,29 +1,36 @@
1
1
  import { Command } from 'commander'
2
2
  import { spawn } from 'child_process'
3
3
  import path from 'path'
4
+ import fs from 'fs'
4
5
  import chalk from 'chalk'
5
- import { resolveContentDir, loadCLIConfig, attachLifecycleHandlers } from '@/cli/utils'
6
-
7
- declare const PACKAGE_ROOT: string
8
-
9
- const nextBin = path.join(PACKAGE_ROOT, 'node_modules', '.bin', process.platform === 'win32' ? 'next.cmd' : 'next')
6
+ import { attachLifecycleHandlers, resolveNextCli } from '@/cli/utils'
10
7
 
11
8
  export const buildCommand = new Command('build')
12
9
  .description('Build for production')
13
- .option('-c, --content <path>', 'Content directory')
14
- .action((options) => {
15
- const contentDir = resolveContentDir(options.content)
16
- loadCLIConfig(contentDir)
10
+ .action(() => {
11
+ const scaffoldPath = path.join(process.cwd(), '.chronicle')
12
+ if (!fs.existsSync(scaffoldPath)) {
13
+ console.log(chalk.red('Error: .chronicle/ not found. Run'), chalk.cyan('chronicle init'), chalk.red('first.'))
14
+ process.exit(1)
15
+ }
16
+
17
+ let nextCli: string
18
+ try {
19
+ nextCli = resolveNextCli()
20
+ } catch {
21
+ console.log(chalk.red('Error: Next.js CLI not found. Run'), chalk.cyan('chronicle init'), chalk.red('first.'))
22
+ process.exit(1)
23
+ }
17
24
 
18
25
  console.log(chalk.cyan('Building for production...'))
19
- console.log(chalk.gray(`Content: ${contentDir}`))
20
26
 
21
- const child = spawn(nextBin, ['build'], {
27
+ const child = spawn(process.execPath, [nextCli, 'build'], {
22
28
  stdio: 'inherit',
23
- cwd: PACKAGE_ROOT,
29
+ cwd: scaffoldPath,
24
30
  env: {
25
31
  ...process.env,
26
- CHRONICLE_CONTENT_DIR: contentDir,
32
+ CHRONICLE_PROJECT_ROOT: process.cwd(),
33
+ CHRONICLE_CONTENT_DIR: './content',
27
34
  },
28
35
  })
29
36