@marlinjai/clearify 1.9.0 → 1.11.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.
@@ -1,3 +1,7 @@
1
+ import {
2
+ resolveRemoteSections
3
+ } from "./chunk-AJBCHKBP.js";
4
+
1
5
  // src/core/config.ts
2
6
  import { z } from "zod";
3
7
  import { resolve, basename, dirname } from "path";
@@ -15,13 +19,20 @@ var NavigationItemSchema = z.lazy(
15
19
  children: z.array(NavigationItemSchema).optional()
16
20
  })
17
21
  );
22
+ var RemoteGitSourceSchema = z.object({
23
+ repo: z.string(),
24
+ ref: z.string().optional(),
25
+ path: z.string().optional(),
26
+ sparse: z.boolean().optional()
27
+ });
18
28
  var SectionConfigSchema = z.object({
19
29
  label: z.string(),
20
30
  docsDir: z.string(),
21
31
  basePath: z.string().optional(),
22
32
  draft: z.boolean().optional(),
23
33
  sitemap: z.boolean().optional(),
24
- exclude: z.array(z.string()).optional()
34
+ exclude: z.array(z.string()).optional(),
35
+ git: RemoteGitSourceSchema.optional()
25
36
  });
26
37
  var MermaidConfigSchema = z.object({
27
38
  strategy: z.enum(["client", "build"]).default("client")
@@ -39,7 +50,14 @@ var HubProjectSchema = z.object({
39
50
  status: z.enum(["active", "beta", "planned", "deprecated"]).default("active"),
40
51
  icon: z.string().optional(),
41
52
  tags: z.array(z.string()).optional(),
42
- group: z.string().optional()
53
+ group: z.string().optional(),
54
+ mode: z.enum(["link", "embed"]).optional(),
55
+ git: RemoteGitSourceSchema.optional(),
56
+ embedSections: z.union([
57
+ z.literal("all"),
58
+ z.literal("public"),
59
+ z.array(z.string())
60
+ ]).optional()
43
61
  });
44
62
  var HubProjectPartialSchema = z.object({
45
63
  description: z.string(),
@@ -54,7 +72,8 @@ var HubProjectPartialSchema = z.object({
54
72
  }).optional();
55
73
  var HubConfigSchema = z.object({
56
74
  projects: z.array(HubProjectSchema).default([]),
57
- scan: z.string().optional()
75
+ scan: z.string().optional(),
76
+ cacheDir: z.string().optional()
58
77
  }).optional();
59
78
  var ClearifyConfigSchema = z.object({
60
79
  name: z.string().default("Documentation"),
@@ -182,18 +201,25 @@ function resolveConfig(userConfig = {}, root) {
182
201
  function slugify(str) {
183
202
  return str.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, "");
184
203
  }
185
- function resolveSections(config, root) {
204
+ async function resolveSections(config, root) {
186
205
  if (config.sections && config.sections.length > 0) {
187
- const sections = config.sections.map((s, i) => {
206
+ const hasRemote = config.sections.some((s) => s.git);
207
+ let resolvedInputs = config.sections;
208
+ if (hasRemote) {
209
+ const cacheDir = resolve(root, "node_modules/.cache/clearify-remote");
210
+ resolvedInputs = await resolveRemoteSections(config.sections, cacheDir);
211
+ }
212
+ const sections = resolvedInputs.map((s, i) => {
188
213
  const id = slugify(s.label);
189
214
  const draft = s.draft ?? false;
190
215
  const basePath = s.basePath ?? (i === 0 ? "/" : "/" + id);
191
216
  const sitemap = s.sitemap ?? !draft;
192
217
  const exclude = [...config.exclude ?? [], ...s.exclude ?? []];
218
+ const docsDir = s.docsDir.startsWith("/") ? s.docsDir : resolve(root, s.docsDir);
193
219
  return {
194
220
  id,
195
221
  label: s.label,
196
- docsDir: resolve(root, s.docsDir),
222
+ docsDir,
197
223
  basePath,
198
224
  draft,
199
225
  sitemap,
@@ -222,37 +248,82 @@ function resolveSections(config, root) {
222
248
  ];
223
249
  }
224
250
  async function scanHubProjects(config, root) {
225
- if (!config.hub?.scan) return config;
226
- const { globbySync } = await import("globby");
227
- const pattern = config.hub.scan;
228
- const configPaths = globbySync(pattern, { cwd: root, absolute: true });
251
+ if (!config.hub?.scan && !config.hub?.projects?.some((p) => p.mode === "embed")) {
252
+ return config;
253
+ }
229
254
  const scannedProjects = [];
230
- for (const configPath of configPaths) {
231
- try {
232
- const childConfig = await loadUserConfig(dirname(configPath));
233
- if (!childConfig.hubProject) continue;
234
- const name = childConfig.name ?? basename(dirname(configPath));
235
- const hp = childConfig.hubProject;
236
- scannedProjects.push({
237
- name,
238
- description: hp.description,
239
- href: hp.href ?? childConfig.siteUrl,
240
- repo: hp.repo,
241
- status: hp.status,
242
- icon: hp.icon,
243
- tags: hp.tags,
244
- group: hp.group
245
- });
246
- } catch {
255
+ if (config.hub?.scan) {
256
+ const { globbySync } = await import("globby");
257
+ const pattern = config.hub.scan;
258
+ const configPaths = globbySync(pattern, { cwd: root, absolute: true });
259
+ for (const configPath of configPaths) {
260
+ try {
261
+ const childConfig = await loadUserConfig(dirname(configPath));
262
+ if (!childConfig.hubProject) continue;
263
+ const name = childConfig.name ?? basename(dirname(configPath));
264
+ const hp = childConfig.hubProject;
265
+ scannedProjects.push({
266
+ name,
267
+ description: hp.description,
268
+ href: hp.href ?? childConfig.siteUrl,
269
+ repo: hp.repo,
270
+ status: hp.status,
271
+ icon: hp.icon,
272
+ tags: hp.tags,
273
+ group: hp.group
274
+ });
275
+ } catch {
276
+ }
247
277
  }
248
278
  }
249
- const manualNames = new Set((config.hub.projects ?? []).map((p) => p.name));
279
+ const manualNames = new Set((config.hub?.projects ?? []).map((p) => p.name));
250
280
  const merged = [
251
281
  ...scannedProjects.filter((p) => !manualNames.has(p.name)),
252
- ...config.hub.projects ?? []
282
+ ...config.hub?.projects ?? []
253
283
  ];
284
+ const embedSections = [];
285
+ for (const project of merged) {
286
+ if (project.mode !== "embed" || !project.git) continue;
287
+ const cacheDir = config.hub?.cacheDir ? resolve(root, config.hub.cacheDir) : resolve(root, "node_modules/.cache/clearify-remote");
288
+ try {
289
+ const { resolveRemoteSource } = await import("./core/remote.js");
290
+ const { localPath } = await resolveRemoteSource(project.git, cacheDir);
291
+ const remoteConfig = await loadUserConfig(localPath);
292
+ const remoteSections = remoteConfig.sections ?? [
293
+ { label: remoteConfig.name ?? project.name, docsDir: remoteConfig.docsDir ?? "./docs" }
294
+ ];
295
+ const filter = project.embedSections ?? "public";
296
+ const filtered = remoteSections.filter((s) => {
297
+ if (filter === "all") return true;
298
+ if (filter === "public") return !s.draft;
299
+ if (Array.isArray(filter)) return filter.includes(s.label);
300
+ return true;
301
+ });
302
+ for (const s of filtered) {
303
+ const docsDir = s.docsDir.startsWith("/") ? s.docsDir : resolve(localPath, s.docsDir);
304
+ const label = s.label === "Documentation" ? project.name : s.label;
305
+ const id = slugify(label);
306
+ embedSections.push({
307
+ label,
308
+ docsDir,
309
+ basePath: s.basePath ?? "/" + id,
310
+ draft: s.draft,
311
+ sitemap: s.sitemap,
312
+ exclude: s.exclude
313
+ });
314
+ }
315
+ console.log(` Hub embed "${project.name}": ${filtered.length} sections pulled`);
316
+ } catch (err) {
317
+ console.warn(
318
+ ` \u26A0 Hub embed "${project.name}" failed:`,
319
+ err instanceof Error ? err.message : err
320
+ );
321
+ }
322
+ }
323
+ const finalSections = [...config.sections ?? [], ...embedSections];
254
324
  return {
255
325
  ...config,
326
+ ...embedSections.length > 0 ? { sections: finalSections } : {},
256
327
  hub: {
257
328
  ...config.hub,
258
329
  projects: merged
@@ -40,7 +40,13 @@ function scanDocs(docsDir, exclude = [], basePath = "/") {
40
40
  title: data.title ?? toTitleCase(basename(filePath, extname(filePath))),
41
41
  description: data.description,
42
42
  icon: data.icon,
43
- order: data.order
43
+ order: data.order,
44
+ summary: data.summary,
45
+ category: data.category,
46
+ tags: data.tags,
47
+ projects: data.projects,
48
+ status: data.status,
49
+ date: data.date
44
50
  }
45
51
  };
46
52
  });
@@ -127,20 +133,35 @@ function buildRoutes(docs, sectionId) {
127
133
  ...sectionId ? { sectionId } : {}
128
134
  }));
129
135
  }
130
- function buildSectionData(section, changelogPath, customNavigation) {
136
+ function buildSectionData(section, rootFiles, customNavigation) {
131
137
  const docs = scanDocs(section.docsDir, section.exclude, section.basePath);
132
- if (section.basePath === "/" && changelogPath && existsSync(changelogPath)) {
133
- const content = readFileSync(changelogPath, "utf-8");
134
- const { data } = matter(content);
135
- docs.push({
136
- filePath: changelogPath,
137
- routePath: "/changelog",
138
- frontmatter: {
139
- title: data.title ?? "Changelog",
140
- description: data.description ?? "Release history",
141
- order: 9999
142
- }
143
- });
138
+ if (section.basePath === "/") {
139
+ if (rootFiles?.changelogPath && existsSync(rootFiles.changelogPath)) {
140
+ const content = readFileSync(rootFiles.changelogPath, "utf-8");
141
+ const { data } = matter(content);
142
+ docs.push({
143
+ filePath: rootFiles.changelogPath,
144
+ routePath: "/changelog",
145
+ frontmatter: {
146
+ title: data.title ?? "Changelog",
147
+ description: data.description ?? "Release history",
148
+ order: 9999
149
+ }
150
+ });
151
+ }
152
+ if (rootFiles?.roadmapPath && existsSync(rootFiles.roadmapPath)) {
153
+ const content = readFileSync(rootFiles.roadmapPath, "utf-8");
154
+ const { data } = matter(content);
155
+ docs.push({
156
+ filePath: rootFiles.roadmapPath,
157
+ routePath: "/roadmap",
158
+ frontmatter: {
159
+ title: data.title ?? "Roadmap",
160
+ description: data.description ?? "Planned and upcoming features",
161
+ order: 9998
162
+ }
163
+ });
164
+ }
144
165
  }
145
166
  const nav = section.basePath === "/" && customNavigation ? customNavigation : buildNavigation(docs, section.basePath);
146
167
  const navigation = {
@@ -1,5 +1,21 @@
1
1
  // src/cli/index.ts
2
2
  import cac from "cac";
3
+ import { dirname, join } from "path";
4
+ import { fileURLToPath } from "url";
5
+ import { readFileSync, existsSync } from "fs";
6
+ function findPackageVersion() {
7
+ let dir = dirname(fileURLToPath(import.meta.url));
8
+ for (let i = 0; i < 5; i++) {
9
+ const pkgPath = join(dir, "package.json");
10
+ if (existsSync(pkgPath)) {
11
+ const pkg = JSON.parse(readFileSync(pkgPath, "utf-8"));
12
+ if (pkg.name === "clearify" || pkg.name === "@marlinjai/clearify") return pkg.version;
13
+ }
14
+ dir = dirname(dir);
15
+ }
16
+ return "0.0.0";
17
+ }
18
+ var version = findPackageVersion();
3
19
  var cli = cac("clearify");
4
20
  cli.command("dev", "Start development server").option("--port <port>", "Port to listen on").option("--host", "Expose to network").action(async (options) => {
5
21
  const { createServer } = await import("../node/index.js");
@@ -22,9 +38,9 @@ cli.command("init", "Scaffold a docs folder").option("--no-internal", "Skip crea
22
38
  const { init } = await import("../node/index.js");
23
39
  await init({ noInternal: options.noInternal, noClaudeRules: options.noClaudeRules });
24
40
  });
25
- cli.command("check", "Check for broken internal links").action(async () => {
41
+ cli.command("check", "Check for broken internal links and frontmatter issues").option("--frontmatter", "Only run frontmatter validation (skip broken link detection)").action(async (options) => {
26
42
  const { checkLinks } = await import("../node/check.js");
27
- await checkLinks();
43
+ await checkLinks({ frontmatterOnly: options.frontmatter });
28
44
  });
29
45
  cli.command("openapi:generate", "Generate OpenAPI spec from NestJS app").option("--module <path>", "Path to NestJS app module", { default: "./src/app.module.ts" }).option("--output <path>", "Output path for spec file", { default: "./docs/openapi.json" }).option("--title <title>", "API documentation title").option("--description <desc>", "API documentation description").option("--version <version>", "API version").action(async (options) => {
30
46
  const { generateSpec } = await import("../presets/nestjs.js");
@@ -37,5 +53,5 @@ cli.command("openapi:generate", "Generate OpenAPI spec from NestJS app").option(
37
53
  });
38
54
  });
39
55
  cli.help();
40
- cli.version("1.8.0");
56
+ cli.version(version);
41
57
  cli.parse();
@@ -4,7 +4,7 @@ export { defineConfig } from '../types/index.js';
4
4
  declare const defaultConfig: ClearifyConfig;
5
5
  declare function loadUserConfig(root: string): Promise<Partial<ClearifyConfig>>;
6
6
  declare function resolveConfig(userConfig?: Partial<ClearifyConfig>, root?: string): ClearifyConfig;
7
- declare function resolveSections(config: ClearifyConfig, root: string): ResolvedSection[];
7
+ declare function resolveSections(config: ClearifyConfig, root: string): Promise<ResolvedSection[]>;
8
8
  declare function scanHubProjects(config: ClearifyConfig, root: string): Promise<ClearifyConfig>;
9
9
 
10
10
  export { defaultConfig, loadUserConfig, resolveConfig, resolveSections, scanHubProjects };
@@ -4,7 +4,8 @@ import {
4
4
  resolveConfig,
5
5
  resolveSections,
6
6
  scanHubProjects
7
- } from "../chunk-PQMKRFBQ.js";
7
+ } from "../chunk-PVTUVUBK.js";
8
+ import "../chunk-AJBCHKBP.js";
8
9
  import {
9
10
  defineConfig
10
11
  } from "../chunk-V7LLYIRO.js";
@@ -1,2 +1,2 @@
1
1
  import '../types/index.js';
2
- export { D as DocFile, S as SectionData, b as buildNavigation, a as buildRoutes, c as buildSectionData, s as scanDocs } from './search.js';
2
+ export { D as DocFile, R as RootFileOptions, S as SectionData, b as buildNavigation, a as buildRoutes, c as buildSectionData, s as scanDocs } from './search.js';
@@ -3,7 +3,7 @@ import {
3
3
  buildRoutes,
4
4
  buildSectionData,
5
5
  scanDocs
6
- } from "../chunk-QNC5QRIO.js";
6
+ } from "../chunk-QTGT76RY.js";
7
7
  import "../chunk-5TD7NQIW.js";
8
8
  export {
9
9
  buildNavigation,
@@ -0,0 +1,18 @@
1
+ import { SectionConfig, RemoteGitSource } from '../types/index.js';
2
+
3
+ interface ResolvedRemote {
4
+ localPath: string;
5
+ resolvedCommit: string;
6
+ cached: boolean;
7
+ }
8
+ /**
9
+ * Clone or update a git repo into the cache directory.
10
+ */
11
+ declare function resolveRemoteSource(source: RemoteGitSource, cacheDir: string): Promise<ResolvedRemote>;
12
+ /**
13
+ * For each section with a `git` source, clone/update the repo and rewrite
14
+ * `docsDir` to the absolute path inside the cached clone.
15
+ */
16
+ declare function resolveRemoteSections(sections: SectionConfig[], cacheDir: string): Promise<SectionConfig[]>;
17
+
18
+ export { resolveRemoteSections, resolveRemoteSource };
@@ -0,0 +1,8 @@
1
+ import {
2
+ resolveRemoteSections,
3
+ resolveRemoteSource
4
+ } from "../chunk-AJBCHKBP.js";
5
+ export {
6
+ resolveRemoteSections,
7
+ resolveRemoteSource
8
+ };
@@ -26,6 +26,10 @@ interface SectionData {
26
26
  routes: RouteEntry[];
27
27
  searchEntries: SearchEntry[];
28
28
  }
29
- declare function buildSectionData(section: ResolvedSection, changelogPath?: string, customNavigation?: NavigationItem[] | null): SectionData;
29
+ interface RootFileOptions {
30
+ changelogPath?: string;
31
+ roadmapPath?: string;
32
+ }
33
+ declare function buildSectionData(section: ResolvedSection, rootFiles?: RootFileOptions, customNavigation?: NavigationItem[] | null): SectionData;
30
34
 
31
- export { type DocFile as D, type SectionData as S, type SearchEntry, buildRoutes as a, buildNavigation as b, buildSearchIndex, buildSectionData as c, scanDocs as s };
35
+ export { type DocFile as D, type RootFileOptions as R, type SectionData as S, type SearchEntry, buildRoutes as a, buildNavigation as b, buildSearchIndex, buildSectionData as c, scanDocs as s };
@@ -1,13 +1,14 @@
1
1
  import {
2
2
  buildSite
3
- } from "../chunk-GGUDZD4K.js";
3
+ } from "../chunk-JU53JE4P.js";
4
4
  import "../chunk-PRTER35L.js";
5
5
  import "../chunk-SCZZB7OE.js";
6
- import "../chunk-IF6GI4WU.js";
6
+ import "../chunk-PFX7LHRZ.js";
7
7
  import "../chunk-B2Q23JW3.js";
8
- import "../chunk-PQMKRFBQ.js";
8
+ import "../chunk-PVTUVUBK.js";
9
+ import "../chunk-AJBCHKBP.js";
9
10
  import "../chunk-V7LLYIRO.js";
10
- import "../chunk-QNC5QRIO.js";
11
+ import "../chunk-QTGT76RY.js";
11
12
  import "../chunk-5TD7NQIW.js";
12
13
  export {
13
14
  buildSite
@@ -1,3 +1,10 @@
1
- declare function checkLinks(): Promise<void>;
1
+ interface CheckOptions {
2
+ frontmatterOnly?: boolean;
3
+ }
4
+ declare function checkFrontmatter(): Promise<{
5
+ errors: number;
6
+ warnings: number;
7
+ }>;
8
+ declare function checkLinks(options?: CheckOptions): Promise<void>;
2
9
 
3
- export { checkLinks };
10
+ export { type CheckOptions, checkFrontmatter, checkLinks };
@@ -1,10 +1,13 @@
1
1
  import {
2
+ checkFrontmatter,
2
3
  checkLinks
3
- } from "../chunk-77VHQV7W.js";
4
- import "../chunk-PQMKRFBQ.js";
4
+ } from "../chunk-NGWAMBXS.js";
5
+ import "../chunk-PVTUVUBK.js";
6
+ import "../chunk-AJBCHKBP.js";
5
7
  import "../chunk-V7LLYIRO.js";
6
- import "../chunk-QNC5QRIO.js";
8
+ import "../chunk-QTGT76RY.js";
7
9
  import "../chunk-5TD7NQIW.js";
8
10
  export {
11
+ checkFrontmatter,
9
12
  checkLinks
10
13
  };
@@ -1,7 +1,7 @@
1
1
  import * as vite from 'vite';
2
2
  export { buildSite as build } from './build.js';
3
3
  export { init } from './init.js';
4
- export { checkLinks } from './check.js';
4
+ export { checkFrontmatter, checkLinks } from './check.js';
5
5
 
6
6
  declare function createServer(options?: {
7
7
  port?: number;
@@ -1,26 +1,28 @@
1
1
  import {
2
2
  buildSite
3
- } from "../chunk-GGUDZD4K.js";
3
+ } from "../chunk-JU53JE4P.js";
4
4
  import {
5
5
  remarkMermaidToComponent
6
6
  } from "../chunk-PRTER35L.js";
7
7
  import "../chunk-SCZZB7OE.js";
8
8
  import {
9
9
  clearifyPlugin
10
- } from "../chunk-IF6GI4WU.js";
10
+ } from "../chunk-PFX7LHRZ.js";
11
11
  import "../chunk-B2Q23JW3.js";
12
12
  import {
13
13
  init
14
- } from "../chunk-QIAMD2Q6.js";
14
+ } from "../chunk-3CW4MOO4.js";
15
15
  import {
16
+ checkFrontmatter,
16
17
  checkLinks
17
- } from "../chunk-77VHQV7W.js";
18
+ } from "../chunk-NGWAMBXS.js";
18
19
  import {
19
20
  loadUserConfig,
20
21
  resolveConfig
21
- } from "../chunk-PQMKRFBQ.js";
22
+ } from "../chunk-PVTUVUBK.js";
23
+ import "../chunk-AJBCHKBP.js";
22
24
  import "../chunk-V7LLYIRO.js";
23
- import "../chunk-QNC5QRIO.js";
25
+ import "../chunk-QTGT76RY.js";
24
26
  import "../chunk-5TD7NQIW.js";
25
27
 
26
28
  // src/node/index.ts
@@ -31,8 +33,9 @@ import remarkGfm from "remark-gfm";
31
33
  import remarkFrontmatter from "remark-frontmatter";
32
34
  import remarkMdxFrontmatter from "remark-mdx-frontmatter";
33
35
  import rehypeShiki from "@shikijs/rehype";
34
- import { resolve } from "path";
36
+ import { resolve, dirname } from "path";
35
37
  import { fileURLToPath } from "url";
38
+ import { createRequire } from "module";
36
39
  import tailwindcss from "@tailwindcss/vite";
37
40
  import { existsSync } from "fs";
38
41
  function findPackageRoot() {
@@ -49,9 +52,22 @@ function resolveClientPath(...segments) {
49
52
  const packageRoot = findPackageRoot();
50
53
  return resolve(packageRoot, "src", "client", ...segments);
51
54
  }
55
+ function dedupeResolve() {
56
+ const require2 = createRequire(import.meta.url);
57
+ const dedupePkgs = ["@mdx-js/react", "react", "react-dom", "react-router-dom"];
58
+ const alias = {};
59
+ for (const pkg of dedupePkgs) {
60
+ try {
61
+ alias[pkg] = dirname(require2.resolve(`${pkg}/package.json`));
62
+ } catch {
63
+ }
64
+ }
65
+ return { alias, dedupe: dedupePkgs };
66
+ }
52
67
  function createDevConfig(overrides = {}) {
53
68
  const root = resolveClientPath();
54
69
  const { userRoot, mermaidStrategy, ...viteOverrides } = overrides;
70
+ const { alias: dedupeAlias, dedupe } = dedupeResolve();
55
71
  return {
56
72
  root,
57
73
  plugins: [
@@ -78,8 +94,10 @@ function createDevConfig(overrides = {}) {
78
94
  },
79
95
  resolve: {
80
96
  alias: {
81
- "@clearify": resolve(root, "..")
82
- }
97
+ "@clearify": resolve(root, ".."),
98
+ ...dedupeAlias
99
+ },
100
+ dedupe
83
101
  },
84
102
  ...viteOverrides
85
103
  };
@@ -102,6 +120,7 @@ async function createServer(options = {}) {
102
120
  }
103
121
  export {
104
122
  buildSite as build,
123
+ checkFrontmatter,
105
124
  checkLinks,
106
125
  createServer,
107
126
  init
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  init
3
- } from "../chunk-QIAMD2Q6.js";
3
+ } from "../chunk-3CW4MOO4.js";
4
4
  export {
5
5
  init
6
6
  };
@@ -1,3 +1,9 @@
1
+ interface RemoteGitSource {
2
+ repo: string;
3
+ ref?: string;
4
+ path?: string;
5
+ sparse?: boolean;
6
+ }
1
7
  interface SectionConfig {
2
8
  label: string;
3
9
  docsDir: string;
@@ -5,6 +11,7 @@ interface SectionConfig {
5
11
  draft?: boolean;
6
12
  sitemap?: boolean;
7
13
  exclude?: string[];
14
+ git?: RemoteGitSource;
8
15
  }
9
16
  interface ResolvedSection {
10
17
  id: string;
@@ -63,11 +70,18 @@ interface NavigationItem {
63
70
  badgeColor?: string;
64
71
  children?: NavigationItem[];
65
72
  }
73
+ type DocCategory = 'documentation' | 'internal' | 'plan' | 'research' | 'decision' | 'roadmap' | 'changelog';
66
74
  interface PageFrontmatter {
67
75
  title?: string;
68
76
  description?: string;
69
77
  icon?: string;
70
78
  order?: number;
79
+ summary?: string;
80
+ category?: DocCategory;
81
+ tags?: string[];
82
+ projects?: string[];
83
+ status?: 'active' | 'superseded' | 'archived';
84
+ date?: string;
71
85
  }
72
86
  interface RouteEntry {
73
87
  path: string;
@@ -88,11 +102,15 @@ interface HubProject {
88
102
  group?: string;
89
103
  hubUrl?: string;
90
104
  hubName?: string;
105
+ mode?: 'link' | 'embed';
106
+ git?: RemoteGitSource;
107
+ embedSections?: 'all' | 'public' | string[];
91
108
  }
92
109
  interface HubConfig {
93
110
  projects: HubProject[];
94
111
  scan?: string;
112
+ cacheDir?: string;
95
113
  }
96
114
  declare function defineConfig(config: Partial<ClearifyConfig>): Partial<ClearifyConfig>;
97
115
 
98
- export { type ClearifyConfig, type HubConfig, type HubProject, type NavigationItem, type PageFrontmatter, type ResolvedSection, type RouteEntry, type SectionConfig, type SectionNavigation, defineConfig };
116
+ export { type ClearifyConfig, type DocCategory, type HubConfig, type HubProject, type NavigationItem, type PageFrontmatter, type RemoteGitSource, type ResolvedSection, type RouteEntry, type SectionConfig, type SectionNavigation, defineConfig };
@@ -1,10 +1,11 @@
1
1
  import {
2
2
  clearifyPlugin
3
- } from "../chunk-IF6GI4WU.js";
3
+ } from "../chunk-PFX7LHRZ.js";
4
4
  import "../chunk-B2Q23JW3.js";
5
- import "../chunk-PQMKRFBQ.js";
5
+ import "../chunk-PVTUVUBK.js";
6
+ import "../chunk-AJBCHKBP.js";
6
7
  import "../chunk-V7LLYIRO.js";
7
- import "../chunk-QNC5QRIO.js";
8
+ import "../chunk-QTGT76RY.js";
8
9
  import "../chunk-5TD7NQIW.js";
9
10
  export {
10
11
  clearifyPlugin
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@marlinjai/clearify",
3
- "version": "1.9.0",
3
+ "version": "1.11.0",
4
4
  "description": "An open-source documentation site generator. Turn markdown into beautiful docs.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -24,7 +24,9 @@
24
24
  ],
25
25
  "scripts": {
26
26
  "build": "tsup",
27
- "dev:self": "node bin/clearify.js dev"
27
+ "dev:self": "node bin/clearify.js dev",
28
+ "prepare": "husky",
29
+ "release": "semantic-release"
28
30
  },
29
31
  "dependencies": {
30
32
  "@mdx-js/react": "^3.1.1",
@@ -63,12 +65,18 @@
63
65
  }
64
66
  },
65
67
  "devDependencies": {
68
+ "@commitlint/cli": "^20.4.3",
69
+ "@commitlint/config-conventional": "^20.4.3",
70
+ "@semantic-release/changelog": "^6.0.3",
71
+ "@semantic-release/git": "^10.0.1",
66
72
  "@types/mdast": "^4.0.4",
67
73
  "@types/node": "^25.2.2",
68
74
  "@types/react": "^18.3.18",
69
75
  "@types/react-dom": "^18.3.5",
70
76
  "esbuild": "^0.27.3",
77
+ "husky": "^9.1.7",
71
78
  "puppeteer": "^24.37.2",
79
+ "semantic-release": "^25.0.3",
72
80
  "tsup": "^8.3.6",
73
81
  "typescript": "^5.7.3"
74
82
  },