@clarify-labs/cli 0.2.0 → 0.5.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/output/cli.js CHANGED
@@ -1,10 +1,83 @@
1
1
  #!/usr/bin/env node
2
- import { i as createClarifyRuntimeAliases, r as loadClarifyConfig, t as clarifyPlugin } from "./plugin-BUWojlPv.js";
2
+ import { i as createClarifyRuntimeAliases, r as loadClarifyConfig, t as clarifyPlugin } from "./plugin-PEEknlAO.js";
3
3
  import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
4
- import { dirname, resolve } from "node:path";
4
+ import { dirname, join, resolve } from "node:path";
5
5
  import { fileURLToPath } from "node:url";
6
- import { build, createServer } from "vite";
6
+ import { build, createLogger, createServer } from "vite";
7
+ import { createRequire } from "node:module";
7
8
  import { cac } from "cac";
9
+ import { readFile, writeFile } from "node:fs/promises";
10
+ import { copyTemplateDirectory, getTemplateDirectory, resolveTemplate } from "@clarify-labs/templates";
11
+ //#region source/core/log.ts
12
+ var LOG_FILE_NAME = ".clarify.log";
13
+ var DEFAULT_LOG_ENTRIES = 50;
14
+ var ENTRY_SEPARATOR = "\n\n---\n\n";
15
+ function getMaxLogEntries() {
16
+ const envValue = process.env.CLARIFY_LOG_MAX_ENTRIES;
17
+ if (!envValue) return DEFAULT_LOG_ENTRIES;
18
+ const parsed = Number(envValue);
19
+ return Number.isInteger(parsed) && parsed > 0 ? parsed : DEFAULT_LOG_ENTRIES;
20
+ }
21
+ function normalizeErrorMessage(error) {
22
+ if (error === void 0) return "undefined";
23
+ if (error === null) return "null";
24
+ if (error instanceof Error) return error.message;
25
+ if (typeof error === "object") {
26
+ if ("message" in error && typeof error.message === "string") return error.message;
27
+ try {
28
+ return JSON.stringify(error);
29
+ } catch {
30
+ return String(error);
31
+ }
32
+ }
33
+ return String(error);
34
+ }
35
+ function normalizeErrorStack(error) {
36
+ if (error instanceof Error) return error.stack;
37
+ }
38
+ function formatLogEntry(root, error) {
39
+ const timestamp = (/* @__PURE__ */ new Date()).toISOString();
40
+ const message = normalizeErrorMessage(error);
41
+ const stack = normalizeErrorStack(error);
42
+ return [
43
+ `=== Clarify build error ===`,
44
+ `Timestamp: ${timestamp}`,
45
+ `Project root: ${root}`,
46
+ `Error: ${message}`,
47
+ stack ? `Stack:\n${stack}` : void 0
48
+ ].filter(Boolean).join("\n");
49
+ }
50
+ async function logBuildError(root, error, maxEntries) {
51
+ const logPath = join(root, LOG_FILE_NAME);
52
+ const entry = formatLogEntry(root, error);
53
+ const max = maxEntries ?? getMaxLogEntries();
54
+ let entries = [];
55
+ if (existsSync(logPath)) try {
56
+ entries = (await readFile(logPath, "utf8")).split(ENTRY_SEPARATOR).map((item) => item.trim()).filter(Boolean);
57
+ } catch {
58
+ entries = [];
59
+ }
60
+ entries.push(entry);
61
+ if (entries.length > max) entries = entries.slice(-max);
62
+ mkdirSync(dirname(logPath), { recursive: true });
63
+ await writeFile(logPath, entries.join(ENTRY_SEPARATOR) + "\n", "utf8");
64
+ }
65
+ function logBuildErrorSync(root, error, maxEntries) {
66
+ const logPath = join(root, LOG_FILE_NAME);
67
+ const entry = formatLogEntry(root, error);
68
+ const max = maxEntries ?? getMaxLogEntries();
69
+ let entries = [];
70
+ if (existsSync(logPath)) try {
71
+ entries = readFileSync(logPath, "utf8").split(ENTRY_SEPARATOR).map((item) => item.trim()).filter(Boolean);
72
+ } catch {
73
+ entries = [];
74
+ }
75
+ entries.push(entry);
76
+ if (entries.length > max) entries = entries.slice(-max);
77
+ mkdirSync(dirname(logPath), { recursive: true });
78
+ writeFileSync(logPath, entries.join(ENTRY_SEPARATOR) + "\n", "utf8");
79
+ }
80
+ //#endregion
8
81
  //#region source/core/vite-config.ts
9
82
  var DEFAULT_HTML = "<!doctype html><html lang=\"en\"><head><meta charset=\"UTF-8\" /><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" /><title>Clarify</title></head><body><div id=\"root\"></div></body></html>";
10
83
  function ensureHtmlEntry(root) {
@@ -15,6 +88,35 @@ function ensureHtmlEntry(root) {
15
88
  writeFileSync(generatedHtmlPath, DEFAULT_HTML, "utf-8");
16
89
  return generatedHtmlPath;
17
90
  }
91
+ function createClarifyLogger(root, env, level) {
92
+ if (env.command !== "build") return void 0;
93
+ const baseLogger = createLogger(level, { allowClearScreen: true });
94
+ return {
95
+ info(msg, options) {
96
+ baseLogger.info(msg, options);
97
+ },
98
+ warn(msg, options) {
99
+ baseLogger.warn(msg, options);
100
+ },
101
+ warnOnce(msg, options) {
102
+ baseLogger.warnOnce(msg, options);
103
+ },
104
+ error(msg, options) {
105
+ baseLogger.error(msg, options);
106
+ if (options?.error) logBuildErrorSync(root, options.error);
107
+ else logBuildErrorSync(root, typeof msg === "string" ? new Error(msg) : msg);
108
+ },
109
+ clearScreen(type) {
110
+ baseLogger.clearScreen(type);
111
+ },
112
+ hasErrorLogged(error) {
113
+ return baseLogger.hasErrorLogged(error);
114
+ },
115
+ get hasWarned() {
116
+ return baseLogger.hasWarned;
117
+ }
118
+ };
119
+ }
18
120
  function createHtmlFallbackPlugin() {
19
121
  return {
20
122
  name: "clarify:cli-html-fallback",
@@ -52,6 +154,7 @@ async function createViteConfig(options, env) {
52
154
  configFile: false,
53
155
  appType: "custom",
54
156
  resolve: { alias: createClarifyRuntimeAliases() },
157
+ customLogger: createClarifyLogger(options.root, env, "info"),
55
158
  plugins: [clarifyPlugin(buildOptions), createHtmlFallbackPlugin()],
56
159
  server: {
57
160
  host: options.host,
@@ -60,17 +163,47 @@ async function createViteConfig(options, env) {
60
163
  },
61
164
  build: {
62
165
  outDir: options.output,
63
- rollupOptions: { input: { index: entryHtmlPath } }
166
+ rolldownOptions: {
167
+ input: { index: entryHtmlPath },
168
+ checks: { pluginTimings: false },
169
+ output: { codeSplitting: { groups: [
170
+ {
171
+ name: "react-vendor",
172
+ test: /node_modules[\\/](react|react-dom|react-router|react-router-dom)[\\/]/,
173
+ priority: 40
174
+ },
175
+ {
176
+ name: "icons-vendor",
177
+ test: /node_modules[\\/]lucide-react[\\/]/,
178
+ priority: 35
179
+ },
180
+ {
181
+ name: "ui-vendor",
182
+ test: /node_modules[\\/](@headlessui|framer-motion)[\\/]/,
183
+ priority: 30
184
+ },
185
+ {
186
+ name: "vendor",
187
+ test: /node_modules[\\/]/,
188
+ priority: 10
189
+ }
190
+ ] } }
191
+ }
64
192
  }
65
193
  };
66
194
  }
67
195
  //#endregion
68
196
  //#region source/cli/commands/build.ts
69
197
  async function runBuild(options) {
70
- await build(await createViteConfig(options, {
71
- command: "build",
72
- mode: "production"
73
- }));
198
+ try {
199
+ await build(await createViteConfig(options, {
200
+ command: "build",
201
+ mode: "production"
202
+ }));
203
+ } catch (error) {
204
+ await logBuildError(options.root, error);
205
+ throw error;
206
+ }
74
207
  }
75
208
  //#endregion
76
209
  //#region source/cli/commands/dev.ts
@@ -83,14 +216,86 @@ async function runDev(options) {
83
216
  server.printUrls();
84
217
  server.bindCLIShortcuts({ print: true });
85
218
  }
219
+ var cliPackageVersion = {
220
+ name: "@clarify-labs/cli",
221
+ version: "0.5.0",
222
+ license: "AGPL-3.0-only",
223
+ type: "module",
224
+ repository: {
225
+ "type": "git",
226
+ "url": "https://github.com/taicode-labs/clarify",
227
+ "directory": "packages/cli"
228
+ },
229
+ main: "output/index.cjs",
230
+ module: "output/index.js",
231
+ types: "output/index.d.ts",
232
+ bin: { "clarify": "bin/clarify.js" },
233
+ exports: {
234
+ ".": {
235
+ "types": "./output/index.d.ts",
236
+ "import": "./output/index.js",
237
+ "require": "./output/index.cjs",
238
+ "default": "./output/index.js"
239
+ },
240
+ "./package.json": "./package.json"
241
+ },
242
+ files: [
243
+ "LICENSE",
244
+ "bin",
245
+ "output"
246
+ ],
247
+ scripts: {
248
+ "dev": "vite build --watch",
249
+ "build": "vite build",
250
+ "lint": "eslint source/",
251
+ "lint:fix": "eslint source/ --fix",
252
+ "typecheck": "tsc -p tsconfig.json --noEmit",
253
+ "test": "vitest run",
254
+ "test:watch": "vitest"
255
+ },
256
+ dependencies: {
257
+ "@apidevtools/swagger-parser": "^12.1.0",
258
+ "@clarify-labs/renderer": "workspace:*",
259
+ "@clarify-labs/templates": "workspace:*",
260
+ "@mdx-js/rollup": "^3.1.1",
261
+ "@tailwindcss/vite": "^4.1.11",
262
+ "@vitejs/plugin-react": "^6.0.2",
263
+ "cac": "^7.0.0",
264
+ "github-slugger": "^2.0.0",
265
+ "gray-matter": "^4.0.3",
266
+ "mdast-util-to-string": "^4.0.0",
267
+ "openapi-types": "^12.1.3",
268
+ "react": "^19.1.0",
269
+ "react-dom": "^19.1.0",
270
+ "react-router-dom": "^7.0.0",
271
+ "remark": "^15.0.1",
272
+ "remark-gfm": "^4.0.1",
273
+ "shiki": "0.14.7",
274
+ "unist-util-visit": "^5.1.0",
275
+ "vite": "^8.0.15",
276
+ "zod": "^4.4.3"
277
+ },
278
+ devDependencies: {
279
+ "@mdx-js/mdx": "^3.1.1",
280
+ "typescript": "^5.8.3",
281
+ "vite-plugin-dts": "^4.5.4",
282
+ "vitest": "^4.1.9"
283
+ }
284
+ }.version ?? "0.0.0";
285
+ var cliPackageVersionWithCaret = `^${cliPackageVersion}`;
86
286
  //#endregion
87
287
  //#region source/cli/commands/init.ts
88
- function writeTextFile(filePath, content, force) {
89
- if (existsSync(filePath) && !force) return false;
90
- mkdirSync(dirname(filePath), { recursive: true });
91
- writeFileSync(filePath, content, "utf-8");
92
- return true;
288
+ var require = createRequire(import.meta.url);
289
+ function findTemplatesPackagePath() {
290
+ try {
291
+ return require.resolve("@clarify-labs/templates/package.json");
292
+ } catch {
293
+ const workspacePackagePath = resolve(dirname(fileURLToPath(import.meta.url)), "../../../../templates/package.json");
294
+ if (existsSync(workspacePackagePath)) return workspacePackagePath;
295
+ throw new Error("[clarify] Templates package not found.");
296
+ }
93
297
  }
298
+ var templatesDirectory = dirname(findTemplatesPackagePath());
94
299
  function updatePackageJson(root, force) {
95
300
  const packageJsonPath = resolve(root, "package.json");
96
301
  const packageJson = existsSync(packageJsonPath) ? JSON.parse(readFileSync(packageJsonPath, "utf-8")) : { type: "module" };
@@ -99,58 +304,40 @@ function updatePackageJson(root, force) {
99
304
  if (force || !scripts.build) scripts.build = "clarify build";
100
305
  packageJson.scripts = scripts;
101
306
  const devDependencies = typeof packageJson.devDependencies === "object" && packageJson.devDependencies !== null ? packageJson.devDependencies : {};
102
- if (!devDependencies["@clarify-labs/cli"]) devDependencies["@clarify-labs/cli"] = "^0.2.0";
307
+ if (!devDependencies["@clarify-labs/cli"]) devDependencies["@clarify-labs/cli"] = cliPackageVersionWithCaret;
103
308
  packageJson.devDependencies = devDependencies;
104
309
  writeFileSync(packageJsonPath, `${JSON.stringify(packageJson, null, 2)}\n`, "utf-8");
105
310
  return true;
106
311
  }
107
- function runInit(options, force) {
108
- const created = [];
109
- const skipped = [];
110
- (writeTextFile(resolve(options.root, "clarify.ts"), `import { defineConfig } from '@clarify-labs/cli'
111
-
112
- export default defineConfig({
113
- title: 'Clarify Docs',
114
- description: 'Documentation powered by Clarify',
115
- theme: { primary: '#0ea5e9' },
116
- })
117
- `, force) ? created : skipped).push("clarify.ts");
118
- (writeTextFile(resolve(options.root, options.content, "index.mdx"), `---
119
- title: Welcome
120
- ---
121
-
122
- # Welcome to Clarify
123
-
124
- Start writing your documentation in \`${options.content}\`.
125
- `, force) ? created : skipped).push(`${options.content}/index.mdx`);
312
+ function runInit(options, force, template) {
313
+ const selectedTemplate = resolveTemplate(template);
314
+ const { created } = copyTemplateDirectory(getTemplateDirectory(templatesDirectory, selectedTemplate), options.root, {
315
+ contentDir: options.content,
316
+ force
317
+ });
126
318
  if (updatePackageJson(options.root, force)) created.push("package.json");
127
- console.log("[clarify] Init complete.");
319
+ console.log(`[clarify] Init complete with ${selectedTemplate} template.`);
128
320
  if (created.length > 0) console.log(`[clarify] Created or updated: ${created.join(", ")}`);
129
- if (skipped.length > 0) console.log(`[clarify] Skipped existing files: ${skipped.join(", ")}. Use --force to overwrite.`);
130
321
  }
131
322
  //#endregion
132
323
  //#region source/cli/options.ts
324
+ function resolvePort(port) {
325
+ if (port === void 0) return void 0;
326
+ const parsedPort = typeof port === "string" ? Number(port) : port;
327
+ if (!Number.isInteger(parsedPort) || parsedPort < 1 || parsedPort > 65535) throw new Error("[clarify] --port must be an integer between 1 and 65535");
328
+ return parsedPort;
329
+ }
133
330
  function resolveCliOptions(options) {
134
331
  return {
135
332
  root: resolve(options.root ?? process.cwd()),
136
333
  content: options.content ?? "source",
137
334
  output: options.output ?? "output",
138
335
  host: options.host,
139
- port: typeof options.port === "string" ? Number.parseInt(options.port, 10) : options.port,
336
+ port: resolvePort(options.port),
140
337
  open: options.open
141
338
  };
142
339
  }
143
340
  //#endregion
144
- //#region source/cli/package.ts
145
- function readPackageVersion() {
146
- try {
147
- const packageJsonPath = resolve(dirname(fileURLToPath(import.meta.url)), "../package.json");
148
- return JSON.parse(readFileSync(packageJsonPath, "utf-8")).version ?? "0.0.0";
149
- } catch {
150
- return "0.0.0";
151
- }
152
- }
153
- //#endregion
154
341
  //#region source/cli/index.ts
155
342
  function withSharedOptions(command) {
156
343
  return command.option("--root <dir>", "Project root directory").option("--content <dir>", "Content directory relative to root").option("--output <dir>", "Build output directory relative to root");
@@ -160,15 +347,15 @@ function resolveOptions(options) {
160
347
  }
161
348
  async function main() {
162
349
  const cli = cac("clarify");
163
- cli.version(readPackageVersion()).help();
350
+ cli.version(cliPackageVersion).help();
164
351
  withSharedOptions(cli.command("dev", "Start the local documentation server")).option("--host [host]", "Dev server host").option("--port <port>", "Dev server port").option("--open [path]", "Open the dev server in a browser").action(async (options) => {
165
352
  await runDev(resolveOptions(options));
166
353
  });
167
354
  withSharedOptions(cli.command("build", "Build the static documentation site")).action(async (options) => {
168
355
  await runBuild(resolveOptions(options));
169
356
  });
170
- withSharedOptions(cli.command("init", "Create a minimal Clarify project scaffold")).option("--force", "Overwrite files created by init").action((options) => {
171
- runInit(resolveOptions(options), options.force === true);
357
+ withSharedOptions(cli.command("init", "Create a Clarify project scaffold")).option("--force", "Overwrite files created by init").option("--template <name>", "Template to use: minimal, standard, or complete").action((options) => {
358
+ runInit(resolveOptions(options), options.force === true, options.template);
172
359
  });
173
360
  const args = process.argv.slice(2);
174
361
  cli.parse(process.argv, { run: false });
@@ -179,7 +366,7 @@ async function main() {
179
366
  await cli.runMatchedCommand();
180
367
  }
181
368
  main().catch((error) => {
182
- console.error(error instanceof Error ? error.message : error);
369
+ console.error(error instanceof Error ? error.stack ?? error.message : String(error));
183
370
  process.exitCode = 1;
184
371
  });
185
372
  //#endregion
package/output/cli.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"cli.js","names":[],"sources":["../source/core/vite-config.ts","../source/cli/commands/build.ts","../source/cli/commands/dev.ts","../source/cli/commands/init.ts","../source/cli/options.ts","../source/cli/package.ts","../source/cli/index.ts"],"sourcesContent":["import { existsSync, mkdirSync, writeFileSync } from 'node:fs'\nimport { dirname, resolve } from 'node:path'\n\nimport type { ConfigEnv, InlineConfig, Plugin } from 'vite'\n\nimport type { ClarifyBuildOptions } from './options.js'\nimport { clarifyPlugin } from './plugin.js'\nimport { createClarifyRuntimeAliases } from './runtime-deps.js'\nimport { loadClarifyConfig } from './user-config.js'\n\nexport type ClarifyViteConfigOptions = {\n root: string\n content: string\n output: string\n host?: string | boolean\n port?: number\n open?: boolean | string\n}\n\nconst DEFAULT_HTML = '<!doctype html><html lang=\"en\"><head><meta charset=\"UTF-8\" /><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" /><title>Clarify</title></head><body><div id=\"root\"></div></body></html>'\n\nfunction ensureHtmlEntry(root: string): string {\n const projectHtmlPath = resolve(root, 'index.html')\n if (existsSync(projectHtmlPath)) return projectHtmlPath\n\n const generatedHtmlPath = resolve(root, '.clarify/index.html')\n mkdirSync(dirname(generatedHtmlPath), { recursive: true })\n writeFileSync(generatedHtmlPath, DEFAULT_HTML, 'utf-8')\n return generatedHtmlPath\n}\n\nfunction createHtmlFallbackPlugin(): Plugin {\n return {\n name: 'clarify:cli-html-fallback',\n configureServer(server) {\n server.middlewares.use(async (req, res, next) => {\n const requestPath = req.url?.split('?')[0] ?? '/'\n const acceptsHtml = req.headers.accept?.includes('text/html') ?? false\n const hasFileExtension = /\\.[^/]+$/.test(requestPath)\n if (!acceptsHtml || hasFileExtension) {\n next()\n return\n }\n\n try {\n const html = await server.transformIndexHtml(requestPath, DEFAULT_HTML)\n res.statusCode = 200\n res.setHeader('Content-Type', 'text/html; charset=utf-8')\n res.end(html)\n } catch (error) {\n next(error)\n }\n })\n },\n }\n}\n\nexport async function createViteConfig(options: ClarifyViteConfigOptions, env: ConfigEnv): Promise<InlineConfig> {\n const entryHtmlPath = ensureHtmlEntry(options.root)\n const userConfig = await loadClarifyConfig(options.root, env)\n const buildOptions: ClarifyBuildOptions = {\n ...userConfig,\n projectRoot: options.root,\n rootDirectory: options.content,\n outputDirectory: options.output,\n }\n\n return {\n root: options.root,\n configFile: false,\n appType: 'custom',\n resolve: {\n alias: createClarifyRuntimeAliases(),\n },\n plugins: [\n clarifyPlugin(buildOptions),\n createHtmlFallbackPlugin(),\n ],\n server: {\n host: options.host,\n port: options.port,\n open: options.open,\n },\n build: {\n outDir: options.output,\n rollupOptions: {\n input: {\n index: entryHtmlPath,\n },\n },\n },\n }\n}\n","import { build as viteBuild } from 'vite'\n\nimport { createViteConfig } from '../../core/vite-config.js'\nimport type { ResolvedCliOptions } from '../options.js'\n\nexport async function runBuild(options: ResolvedCliOptions): Promise<void> {\n await viteBuild(await createViteConfig(options, { command: 'build', mode: 'production' }))\n}\n","import { createServer } from 'vite'\n\nimport { createViteConfig } from '../../core/vite-config.js'\nimport type { ResolvedCliOptions } from '../options.js'\n\nexport async function runDev(options: ResolvedCliOptions): Promise<void> {\n const server = await createServer(await createViteConfig(options, { command: 'serve', mode: 'development' }))\n await server.listen()\n server.printUrls()\n server.bindCLIShortcuts({ print: true })\n}\n","import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs'\nimport { dirname, resolve } from 'node:path'\n\nimport type { ResolvedCliOptions } from '../options.js'\n\nfunction writeTextFile(filePath: string, content: string, force: boolean): boolean {\n if (existsSync(filePath) && !force) return false\n mkdirSync(dirname(filePath), { recursive: true })\n writeFileSync(filePath, content, 'utf-8')\n return true\n}\n\nfunction updatePackageJson(root: string, force: boolean): boolean {\n const packageJsonPath = resolve(root, 'package.json')\n const packageJson = existsSync(packageJsonPath)\n ? JSON.parse(readFileSync(packageJsonPath, 'utf-8')) as Record<string, unknown>\n : { type: 'module' }\n\n const scripts = typeof packageJson.scripts === 'object' && packageJson.scripts !== null\n ? packageJson.scripts as Record<string, string>\n : {}\n\n if (force || !scripts.dev) scripts.dev = 'clarify dev'\n if (force || !scripts.build) scripts.build = 'clarify build'\n packageJson.scripts = scripts\n\n const devDependencies = typeof packageJson.devDependencies === 'object' && packageJson.devDependencies !== null\n ? packageJson.devDependencies as Record<string, string>\n : {}\n if (!devDependencies['@clarify-labs/cli']) devDependencies['@clarify-labs/cli'] = '^0.2.0'\n packageJson.devDependencies = devDependencies\n\n writeFileSync(packageJsonPath, `${JSON.stringify(packageJson, null, 2)}\\n`, 'utf-8')\n return true\n}\n\nexport function runInit(options: ResolvedCliOptions, force: boolean): void {\n const created: string[] = []\n const skipped: string[] = []\n\n const clarifyConfigCreated = writeTextFile(resolve(options.root, 'clarify.ts'), `import { defineConfig } from '@clarify-labs/cli'\n\nexport default defineConfig({\n title: 'Clarify Docs',\n description: 'Documentation powered by Clarify',\n theme: { primary: '#0ea5e9' },\n})\n`, force)\n ;(clarifyConfigCreated ? created : skipped).push('clarify.ts')\n\n const contentCreated = writeTextFile(resolve(options.root, options.content, 'index.mdx'), `---\ntitle: Welcome\n---\n\n# Welcome to Clarify\n\nStart writing your documentation in \\`${options.content}\\`.\n`, force)\n ;(contentCreated ? created : skipped).push(`${options.content}/index.mdx`)\n\n const packageJsonUpdated = updatePackageJson(options.root, force)\n if (packageJsonUpdated) created.push('package.json')\n\n console.log('[clarify] Init complete.')\n if (created.length > 0) console.log(`[clarify] Created or updated: ${created.join(', ')}`)\n if (skipped.length > 0) console.log(`[clarify] Skipped existing files: ${skipped.join(', ')}. Use --force to overwrite.`)\n}\n","import { resolve } from 'node:path'\n\nexport type CliOptions = {\n root?: string\n content?: string\n output?: string\n host?: string | boolean\n port?: string | number\n open?: boolean | string\n}\n\nexport type ResolvedCliOptions = {\n root: string\n content: string\n output: string\n host?: string | boolean\n port?: number\n open?: boolean | string\n}\n\nexport function resolveCliOptions(options: CliOptions): ResolvedCliOptions {\n return {\n root: resolve(options.root ?? process.cwd()),\n content: options.content ?? 'source',\n output: options.output ?? 'output',\n host: options.host,\n port: typeof options.port === 'string' ? Number.parseInt(options.port, 10) : options.port,\n open: options.open,\n }\n}\n","import { readFileSync } from 'node:fs'\nimport { dirname, resolve } from 'node:path'\nimport { fileURLToPath } from 'node:url'\n\nexport function readPackageVersion(): string {\n try {\n const packageJsonPath = resolve(dirname(fileURLToPath(import.meta.url)), '../package.json')\n const packageJson = JSON.parse(readFileSync(packageJsonPath, 'utf-8')) as { version?: string }\n return packageJson.version ?? '0.0.0'\n } catch {\n return '0.0.0'\n }\n}\n","#!/usr/bin/env node\nimport { cac } from 'cac'\n\nimport { runBuild } from './commands/build.js'\nimport { runDev } from './commands/dev.js'\nimport { runInit } from './commands/init.js'\nimport { resolveCliOptions, type CliOptions, type ResolvedCliOptions } from './options.js'\nimport { readPackageVersion } from './package.js'\n\nfunction withSharedOptions(command: ReturnType<ReturnType<typeof cac>['command']>) {\n return command\n .option('--root <dir>', 'Project root directory')\n .option('--content <dir>', 'Content directory relative to root')\n .option('--output <dir>', 'Build output directory relative to root')\n}\n\nfunction resolveOptions(options: CliOptions): ResolvedCliOptions {\n return resolveCliOptions(options)\n}\n\nasync function main(): Promise<void> {\n const cli = cac('clarify')\n\n cli\n .version(readPackageVersion())\n .help()\n\n withSharedOptions(cli.command('dev', 'Start the local documentation server'))\n .option('--host [host]', 'Dev server host')\n .option('--port <port>', 'Dev server port')\n .option('--open [path]', 'Open the dev server in a browser')\n .action(async (options: CliOptions) => {\n await runDev(resolveOptions(options))\n })\n\n withSharedOptions(cli.command('build', 'Build the static documentation site'))\n .action(async (options: CliOptions) => {\n await runBuild(resolveOptions(options))\n })\n\n withSharedOptions(cli.command('init', 'Create a minimal Clarify project scaffold'))\n .option('--force', 'Overwrite files created by init')\n .action((options: CliOptions & { force?: boolean }) => {\n runInit(resolveOptions(options), options.force === true)\n })\n\n const args = process.argv.slice(2)\n cli.parse(process.argv, { run: false })\n\n if (args.length === 0) {\n cli.outputHelp()\n return\n }\n\n await cli.runMatchedCommand()\n}\n\nmain().catch(error => {\n console.error(error instanceof Error ? error.message : error)\n process.exitCode = 1\n})\n"],"mappings":"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"}
1
+ {"version":3,"file":"cli.js","names":[],"sources":["../source/core/log.ts","../source/core/vite-config.ts","../source/cli/commands/build.ts","../source/cli/commands/dev.ts","../package.json","../source/cli/package.ts","../source/cli/commands/init.ts","../source/cli/options.ts","../source/cli/index.ts"],"sourcesContent":["import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs'\nimport { readFile, writeFile } from 'node:fs/promises'\nimport { dirname, join } from 'node:path'\n\nconst LOG_FILE_NAME = '.clarify.log'\nconst DEFAULT_LOG_ENTRIES = 50\nconst ENTRY_SEPARATOR = '\\n\\n---\\n\\n'\n\nfunction getMaxLogEntries(): number {\n const envValue = process.env.CLARIFY_LOG_MAX_ENTRIES\n if (!envValue) return DEFAULT_LOG_ENTRIES\n const parsed = Number(envValue)\n return Number.isInteger(parsed) && parsed > 0 ? parsed : DEFAULT_LOG_ENTRIES\n}\n\nfunction normalizeErrorMessage(error: unknown): string {\n if (error === undefined) return 'undefined'\n if (error === null) return 'null'\n if (error instanceof Error) return error.message\n if (typeof error === 'object') {\n if ('message' in error && typeof (error as { message?: unknown }).message === 'string') {\n return (error as { message: string }).message\n }\n try {\n return JSON.stringify(error)\n } catch {\n return String(error)\n }\n }\n return String(error)\n}\n\nfunction normalizeErrorStack(error: unknown): string | undefined {\n if (error instanceof Error) {\n return error.stack\n }\n return undefined\n}\n\nfunction formatLogEntry(root: string, error: unknown): string {\n const timestamp = new Date().toISOString()\n const message = normalizeErrorMessage(error)\n const stack = normalizeErrorStack(error)\n\n return [`=== Clarify build error ===`, `Timestamp: ${timestamp}`, `Project root: ${root}`, `Error: ${message}`, stack ? `Stack:\\n${stack}` : undefined]\n .filter(Boolean)\n .join('\\n')\n}\n\nexport async function logBuildError(root: string, error: unknown, maxEntries?: number): Promise<void> {\n const logPath = join(root, LOG_FILE_NAME)\n const entry = formatLogEntry(root, error)\n const max = maxEntries ?? getMaxLogEntries()\n\n let entries: string[] = []\n if (existsSync(logPath)) {\n try {\n const content = await readFile(logPath, 'utf8')\n entries = content\n .split(ENTRY_SEPARATOR)\n .map((item) => item.trim())\n .filter(Boolean)\n } catch {\n entries = []\n }\n }\n\n entries.push(entry)\n if (entries.length > max) {\n entries = entries.slice(-max)\n }\n\n mkdirSync(dirname(logPath), { recursive: true })\n await writeFile(logPath, entries.join(ENTRY_SEPARATOR) + '\\n', 'utf8')\n}\n\nexport function logBuildErrorSync(root: string, error: unknown, maxEntries?: number): void {\n const logPath = join(root, LOG_FILE_NAME)\n const entry = formatLogEntry(root, error)\n const max = maxEntries ?? getMaxLogEntries()\n\n let entries: string[] = []\n if (existsSync(logPath)) {\n try {\n const content = readFileSync(logPath, 'utf8')\n entries = content\n .split(ENTRY_SEPARATOR)\n .map((item) => item.trim())\n .filter(Boolean)\n } catch {\n entries = []\n }\n }\n\n entries.push(entry)\n if (entries.length > max) {\n entries = entries.slice(-max)\n }\n\n mkdirSync(dirname(logPath), { recursive: true })\n writeFileSync(logPath, entries.join(ENTRY_SEPARATOR) + '\\n', 'utf8')\n}\n","import { existsSync, mkdirSync, writeFileSync } from 'node:fs'\nimport { dirname, resolve } from 'node:path'\n\nimport { createLogger } from 'vite'\nimport type { ConfigEnv, InlineConfig, Plugin, LogLevel, Logger, LogOptions, LogErrorOptions, LogType } from 'vite'\n\nimport { logBuildErrorSync } from './log.js'\nimport type { ClarifyBuildOptions } from './options.js'\nimport { clarifyPlugin } from './plugin.js'\nimport { createClarifyRuntimeAliases } from './runtime-deps.js'\nimport { loadClarifyConfig } from './user-config.js'\n\nexport type ClarifyViteConfigOptions = {\n root: string\n content: string\n output: string\n host?: string | boolean\n port?: number\n open?: boolean | string\n}\n\nconst DEFAULT_HTML = '<!doctype html><html lang=\"en\"><head><meta charset=\"UTF-8\" /><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" /><title>Clarify</title></head><body><div id=\"root\"></div></body></html>'\n\nfunction ensureHtmlEntry(root: string): string {\n const projectHtmlPath = resolve(root, 'index.html')\n if (existsSync(projectHtmlPath)) return projectHtmlPath\n\n const generatedHtmlPath = resolve(root, '.clarify/index.html')\n mkdirSync(dirname(generatedHtmlPath), { recursive: true })\n writeFileSync(generatedHtmlPath, DEFAULT_HTML, 'utf-8')\n return generatedHtmlPath\n}\n\nfunction createClarifyLogger(root: string, env: ConfigEnv, level: LogLevel): Logger | undefined {\n if (env.command !== 'build') return undefined\n\n const baseLogger = createLogger(level, { allowClearScreen: true })\n\n return {\n info(msg: string, options?: LogOptions) {\n baseLogger.info(msg, options)\n },\n warn(msg: string, options?: LogOptions) {\n baseLogger.warn(msg, options)\n },\n warnOnce(msg: string, options?: LogOptions) {\n baseLogger.warnOnce(msg, options)\n },\n error(msg: string, options?: LogErrorOptions) {\n baseLogger.error(msg, options)\n if (options?.error) {\n logBuildErrorSync(root, options.error)\n } else {\n logBuildErrorSync(root, typeof msg === 'string' ? new Error(msg) : msg)\n }\n },\n clearScreen(type: LogType) {\n baseLogger.clearScreen(type)\n },\n hasErrorLogged(error: Error | unknown) {\n return baseLogger.hasErrorLogged(error as Error)\n },\n get hasWarned() {\n return baseLogger.hasWarned\n },\n }\n}\n\nfunction createHtmlFallbackPlugin(): Plugin {\n return {\n name: 'clarify:cli-html-fallback',\n configureServer(server) {\n server.middlewares.use(async (req, res, next) => {\n const requestPath = req.url?.split('?')[0] ?? '/'\n const acceptsHtml = req.headers.accept?.includes('text/html') ?? false\n const hasFileExtension = /\\.[^/]+$/.test(requestPath)\n if (!acceptsHtml || hasFileExtension) {\n next()\n return\n }\n\n try {\n const html = await server.transformIndexHtml(requestPath, DEFAULT_HTML)\n res.statusCode = 200\n res.setHeader('Content-Type', 'text/html; charset=utf-8')\n res.end(html)\n } catch (error) {\n next(error)\n }\n })\n },\n }\n}\n\nexport async function createViteConfig(options: ClarifyViteConfigOptions, env: ConfigEnv): Promise<InlineConfig> {\n const entryHtmlPath = ensureHtmlEntry(options.root)\n const userConfig = await loadClarifyConfig(options.root, env)\n const buildOptions: ClarifyBuildOptions = {\n ...userConfig,\n projectRoot: options.root,\n rootDirectory: options.content,\n outputDirectory: options.output,\n }\n\n return {\n root: options.root,\n configFile: false,\n appType: 'custom',\n resolve: {\n alias: createClarifyRuntimeAliases(),\n },\n customLogger: createClarifyLogger(options.root, env, 'info'),\n plugins: [\n clarifyPlugin(buildOptions),\n createHtmlFallbackPlugin(),\n ],\n server: {\n host: options.host,\n port: options.port,\n open: options.open,\n },\n build: {\n outDir: options.output,\n rolldownOptions: {\n input: {\n index: entryHtmlPath,\n },\n checks: {\n pluginTimings: false,\n },\n output: {\n codeSplitting: {\n groups: [\n {\n name: 'react-vendor',\n test: /node_modules[\\\\/](react|react-dom|react-router|react-router-dom)[\\\\/]/,\n priority: 40,\n },\n {\n name: 'icons-vendor',\n test: /node_modules[\\\\/]lucide-react[\\\\/]/,\n priority: 35,\n },\n {\n name: 'ui-vendor',\n test: /node_modules[\\\\/](@headlessui|framer-motion)[\\\\/]/,\n priority: 30,\n },\n {\n name: 'vendor',\n test: /node_modules[\\\\/]/,\n priority: 10\n },\n ],\n },\n },\n },\n },\n }\n}\n","import { build as viteBuild } from 'vite'\n\nimport { logBuildError } from '../../core/log.js'\nimport { createViteConfig } from '../../core/vite-config.js'\nimport type { ResolvedCliOptions } from '../options.js'\n\nexport async function runBuild(options: ResolvedCliOptions): Promise<void> {\n try {\n await viteBuild(await createViteConfig(options, { command: 'build', mode: 'production' }))\n } catch (error) {\n await logBuildError(options.root, error)\n throw error\n }\n}\n","import { createServer } from 'vite'\n\nimport { createViteConfig } from '../../core/vite-config.js'\nimport type { ResolvedCliOptions } from '../options.js'\n\nexport async function runDev(options: ResolvedCliOptions): Promise<void> {\n const server = await createServer(await createViteConfig(options, { command: 'serve', mode: 'development' }))\n await server.listen()\n server.printUrls()\n server.bindCLIShortcuts({ print: true })\n}\n","{\n \"name\": \"@clarify-labs/cli\",\n \"version\": \"0.5.0\",\n \"license\": \"AGPL-3.0-only\",\n \"type\": \"module\",\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"https://github.com/taicode-labs/clarify\",\n \"directory\": \"packages/cli\"\n },\n \"main\": \"output/index.cjs\",\n \"module\": \"output/index.js\",\n \"types\": \"output/index.d.ts\",\n \"bin\": {\n \"clarify\": \"bin/clarify.js\"\n },\n \"exports\": {\n \".\": {\n \"types\": \"./output/index.d.ts\",\n \"import\": \"./output/index.js\",\n \"require\": \"./output/index.cjs\",\n \"default\": \"./output/index.js\"\n },\n \"./package.json\": \"./package.json\"\n },\n \"files\": [\n \"LICENSE\",\n \"bin\",\n \"output\"\n ],\n \"scripts\": {\n \"dev\": \"vite build --watch\",\n \"build\": \"vite build\",\n \"lint\": \"eslint source/\",\n \"lint:fix\": \"eslint source/ --fix\",\n \"typecheck\": \"tsc -p tsconfig.json --noEmit\",\n \"test\": \"vitest run\",\n \"test:watch\": \"vitest\"\n },\n \"dependencies\": {\n \"@apidevtools/swagger-parser\": \"^12.1.0\",\n \"@clarify-labs/renderer\": \"workspace:*\",\n \"@clarify-labs/templates\": \"workspace:*\",\n \"@mdx-js/rollup\": \"^3.1.1\",\n \"@tailwindcss/vite\": \"^4.1.11\",\n \"@vitejs/plugin-react\": \"^6.0.2\",\n \"cac\": \"^7.0.0\",\n \"github-slugger\": \"^2.0.0\",\n \"gray-matter\": \"^4.0.3\",\n \"mdast-util-to-string\": \"^4.0.0\",\n \"openapi-types\": \"^12.1.3\",\n \"react\": \"^19.1.0\",\n \"react-dom\": \"^19.1.0\",\n \"react-router-dom\": \"^7.0.0\",\n \"remark\": \"^15.0.1\",\n \"remark-gfm\": \"^4.0.1\",\n \"shiki\": \"0.14.7\",\n \"unist-util-visit\": \"^5.1.0\",\n \"vite\": \"^8.0.15\",\n \"zod\": \"^4.4.3\"\n },\n \"devDependencies\": {\n \"@mdx-js/mdx\": \"^3.1.1\",\n \"typescript\": \"^5.8.3\",\n \"vite-plugin-dts\": \"^4.5.4\",\n \"vitest\": \"^4.1.9\"\n }\n}\n","import packageJson from '../../package.json' with { type: 'json' }\n\nexport const cliPackageJson = packageJson as { version?: string }\nexport const cliPackageVersion = cliPackageJson.version ?? '0.0.0'\nexport const cliPackageVersionWithCaret = `^${cliPackageVersion}`\n\nexport function readPackageVersion(): string {\n return cliPackageVersion\n}\n","import { existsSync, readFileSync, writeFileSync } from 'node:fs'\nimport { createRequire } from 'node:module'\nimport { dirname, resolve } from 'node:path'\nimport { fileURLToPath } from 'node:url'\n\nimport { copyTemplateDirectory, getTemplateDirectory, resolveTemplate } from '@clarify-labs/templates'\n\nimport type { ResolvedCliOptions } from '../options.js'\nimport { cliPackageVersionWithCaret } from '../package.js'\n\nconst require = createRequire(import.meta.url)\n\nfunction findTemplatesPackagePath(): string {\n try {\n return require.resolve('@clarify-labs/templates/package.json')\n } catch {\n const currentDirectory = dirname(fileURLToPath(import.meta.url))\n const workspacePackagePath = resolve(currentDirectory, '../../../../templates/package.json')\n if (existsSync(workspacePackagePath)) return workspacePackagePath\n throw new Error('[clarify] Templates package not found.')\n }\n}\n\nconst templatesPackagePath = findTemplatesPackagePath()\nconst templatesDirectory = dirname(templatesPackagePath)\n\nfunction updatePackageJson(root: string, force: boolean): boolean {\n const packageJsonPath = resolve(root, 'package.json')\n const packageJson = existsSync(packageJsonPath)\n ? JSON.parse(readFileSync(packageJsonPath, 'utf-8')) as Record<string, unknown>\n : { type: 'module' }\n\n const scripts = typeof packageJson.scripts === 'object' && packageJson.scripts !== null\n ? packageJson.scripts as Record<string, string>\n : {}\n\n if (force || !scripts.dev) scripts.dev = 'clarify dev'\n if (force || !scripts.build) scripts.build = 'clarify build'\n packageJson.scripts = scripts\n\n const devDependencies = typeof packageJson.devDependencies === 'object' && packageJson.devDependencies !== null\n ? packageJson.devDependencies as Record<string, string>\n : {}\n if (!devDependencies['@clarify-labs/cli']) devDependencies['@clarify-labs/cli'] = cliPackageVersionWithCaret\n packageJson.devDependencies = devDependencies\n\n writeFileSync(packageJsonPath, `${JSON.stringify(packageJson, null, 2)}\\n`, 'utf-8')\n return true\n}\n\nexport function runInit(options: ResolvedCliOptions, force: boolean, template?: string): void {\n const selectedTemplate = resolveTemplate(template)\n const templateDirectory = getTemplateDirectory(templatesDirectory, selectedTemplate)\n const { created } = copyTemplateDirectory(templateDirectory, options.root, {\n contentDir: options.content,\n force,\n })\n\n const packageJsonUpdated = updatePackageJson(options.root, force)\n if (packageJsonUpdated) created.push('package.json')\n\n console.log(`[clarify] Init complete with ${selectedTemplate} template.`)\n if (created.length > 0) console.log(`[clarify] Created or updated: ${created.join(', ')}`)\n}\n","import { resolve } from 'node:path'\n\nexport type CliOptions = {\n root?: string\n content?: string\n output?: string\n host?: string | boolean\n port?: string | number\n open?: boolean | string\n}\n\nexport type ResolvedCliOptions = {\n root: string\n content: string\n output: string\n host?: string | boolean\n port?: number\n open?: boolean | string\n}\n\nfunction resolvePort(port: CliOptions['port']): number | undefined {\n if (port === undefined) return undefined\n\n const parsedPort = typeof port === 'string' ? Number(port) : port\n if (!Number.isInteger(parsedPort) || parsedPort < 1 || parsedPort > 65535) {\n throw new Error('[clarify] --port must be an integer between 1 and 65535')\n }\n\n return parsedPort\n}\n\nexport function resolveCliOptions(options: CliOptions): ResolvedCliOptions {\n return {\n root: resolve(options.root ?? process.cwd()),\n content: options.content ?? 'source',\n output: options.output ?? 'output',\n host: options.host,\n port: resolvePort(options.port),\n open: options.open,\n }\n}\n","#!/usr/bin/env node\nimport { cac } from 'cac'\n\nimport { runBuild } from './commands/build.js'\nimport { runDev } from './commands/dev.js'\nimport { runInit } from './commands/init.js'\nimport { resolveCliOptions, type CliOptions, type ResolvedCliOptions } from './options.js'\nimport { cliPackageVersion } from './package.js'\n\ntype InitCommandOptions = CliOptions & {\n force?: boolean\n template?: string\n}\n\nfunction withSharedOptions(command: ReturnType<ReturnType<typeof cac>['command']>) {\n return command\n .option('--root <dir>', 'Project root directory')\n .option('--content <dir>', 'Content directory relative to root')\n .option('--output <dir>', 'Build output directory relative to root')\n}\n\nfunction resolveOptions(options: CliOptions): ResolvedCliOptions {\n return resolveCliOptions(options)\n}\n\nasync function main(): Promise<void> {\n const cli = cac('clarify')\n\n cli\n .version(cliPackageVersion)\n .help()\n\n withSharedOptions(cli.command('dev', 'Start the local documentation server'))\n .option('--host [host]', 'Dev server host')\n .option('--port <port>', 'Dev server port')\n .option('--open [path]', 'Open the dev server in a browser')\n .action(async (options: CliOptions) => {\n await runDev(resolveOptions(options))\n })\n\n withSharedOptions(cli.command('build', 'Build the static documentation site'))\n .action(async (options: CliOptions) => {\n await runBuild(resolveOptions(options))\n })\n\n withSharedOptions(cli.command('init', 'Create a Clarify project scaffold'))\n .option('--force', 'Overwrite files created by init')\n .option('--template <name>', 'Template to use: minimal, standard, or complete')\n .action((options: InitCommandOptions) => {\n runInit(resolveOptions(options), options.force === true, options.template)\n })\n\n const args = process.argv.slice(2)\n cli.parse(process.argv, { run: false })\n\n if (args.length === 0) {\n cli.outputHelp()\n return\n }\n\n await cli.runMatchedCommand()\n}\n\nmain().catch(error => {\n console.error(error instanceof Error ? error.stack ?? error.message : String(error))\n process.exitCode = 1\n})\n"],"mappings":";;;;;;;;;;;AAIA,IAAM,gBAAgB;AACtB,IAAM,sBAAsB;AAC5B,IAAM,kBAAkB;AAExB,SAAS,mBAA2B;CAClC,MAAM,WAAW,QAAQ,IAAI;CAC7B,IAAI,CAAC,UAAU,OAAO;CACtB,MAAM,SAAS,OAAO,QAAQ;CAC9B,OAAO,OAAO,UAAU,MAAM,KAAK,SAAS,IAAI,SAAS;AAC3D;AAEA,SAAS,sBAAsB,OAAwB;CACrD,IAAI,UAAU,KAAA,GAAW,OAAO;CAChC,IAAI,UAAU,MAAM,OAAO;CAC3B,IAAI,iBAAiB,OAAO,OAAO,MAAM;CACzC,IAAI,OAAO,UAAU,UAAU;EAC7B,IAAI,aAAa,SAAS,OAAQ,MAAgC,YAAY,UAC5E,OAAQ,MAA8B;EAExC,IAAI;GACF,OAAO,KAAK,UAAU,KAAK;EAC7B,QAAQ;GACN,OAAO,OAAO,KAAK;EACrB;CACF;CACA,OAAO,OAAO,KAAK;AACrB;AAEA,SAAS,oBAAoB,OAAoC;CAC/D,IAAI,iBAAiB,OACnB,OAAO,MAAM;AAGjB;AAEA,SAAS,eAAe,MAAc,OAAwB;CAC5D,MAAM,6BAAY,IAAI,KAAK,GAAE,YAAY;CACzC,MAAM,UAAU,sBAAsB,KAAK;CAC3C,MAAM,QAAQ,oBAAoB,KAAK;CAEvC,OAAO;EAAC;EAA+B,cAAc;EAAa,iBAAiB;EAAQ,UAAU;EAAW,QAAQ,WAAW,UAAU,KAAA;CAAS,EACnJ,OAAO,OAAO,EACd,KAAK,IAAI;AACd;AAEA,eAAsB,cAAc,MAAc,OAAgB,YAAoC;CACpG,MAAM,UAAU,KAAK,MAAM,aAAa;CACxC,MAAM,QAAQ,eAAe,MAAM,KAAK;CACxC,MAAM,MAAM,cAAc,iBAAiB;CAE3C,IAAI,UAAoB,CAAC;CACzB,IAAI,WAAW,OAAO,GACpB,IAAI;EAEF,WAAU,MADY,SAAS,SAAS,MAAM,GAE3C,MAAM,eAAe,EACrB,KAAK,SAAS,KAAK,KAAK,CAAC,EACzB,OAAO,OAAO;CACnB,QAAQ;EACN,UAAU,CAAC;CACb;CAGF,QAAQ,KAAK,KAAK;CAClB,IAAI,QAAQ,SAAS,KACnB,UAAU,QAAQ,MAAM,CAAC,GAAG;CAG9B,UAAU,QAAQ,OAAO,GAAG,EAAE,WAAW,KAAK,CAAC;CAC/C,MAAM,UAAU,SAAS,QAAQ,KAAK,eAAe,IAAI,MAAM,MAAM;AACvE;AAEA,SAAgB,kBAAkB,MAAc,OAAgB,YAA2B;CACzF,MAAM,UAAU,KAAK,MAAM,aAAa;CACxC,MAAM,QAAQ,eAAe,MAAM,KAAK;CACxC,MAAM,MAAM,cAAc,iBAAiB;CAE3C,IAAI,UAAoB,CAAC;CACzB,IAAI,WAAW,OAAO,GACpB,IAAI;EAEF,UADgB,aAAa,SAAS,MAC5B,EACP,MAAM,eAAe,EACrB,KAAK,SAAS,KAAK,KAAK,CAAC,EACzB,OAAO,OAAO;CACnB,QAAQ;EACN,UAAU,CAAC;CACb;CAGF,QAAQ,KAAK,KAAK;CAClB,IAAI,QAAQ,SAAS,KACnB,UAAU,QAAQ,MAAM,CAAC,GAAG;CAG9B,UAAU,QAAQ,OAAO,GAAG,EAAE,WAAW,KAAK,CAAC;CAC/C,cAAc,SAAS,QAAQ,KAAK,eAAe,IAAI,MAAM,MAAM;AACrE;;;AChFA,IAAM,eAAe;AAErB,SAAS,gBAAgB,MAAsB;CAC7C,MAAM,kBAAkB,QAAQ,MAAM,YAAY;CAClD,IAAI,WAAW,eAAe,GAAG,OAAO;CAExC,MAAM,oBAAoB,QAAQ,MAAM,qBAAqB;CAC7D,UAAU,QAAQ,iBAAiB,GAAG,EAAE,WAAW,KAAK,CAAC;CACzD,cAAc,mBAAmB,cAAc,OAAO;CACtD,OAAO;AACT;AAEA,SAAS,oBAAoB,MAAc,KAAgB,OAAqC;CAC9F,IAAI,IAAI,YAAY,SAAS,OAAO,KAAA;CAEpC,MAAM,aAAa,aAAa,OAAO,EAAE,kBAAkB,KAAK,CAAC;CAEjE,OAAO;EACL,KAAK,KAAa,SAAsB;GACtC,WAAW,KAAK,KAAK,OAAO;EAC9B;EACA,KAAK,KAAa,SAAsB;GACtC,WAAW,KAAK,KAAK,OAAO;EAC9B;EACA,SAAS,KAAa,SAAsB;GAC1C,WAAW,SAAS,KAAK,OAAO;EAClC;EACA,MAAM,KAAa,SAA2B;GAC5C,WAAW,MAAM,KAAK,OAAO;GAC7B,IAAI,SAAS,OACX,kBAAkB,MAAM,QAAQ,KAAK;QAErC,kBAAkB,MAAM,OAAO,QAAQ,WAAW,IAAI,MAAM,GAAG,IAAI,GAAG;EAE1E;EACA,YAAY,MAAe;GACzB,WAAW,YAAY,IAAI;EAC7B;EACA,eAAe,OAAwB;GACrC,OAAO,WAAW,eAAe,KAAc;EACjD;EACA,IAAI,YAAY;GACd,OAAO,WAAW;EACpB;CACF;AACF;AAEA,SAAS,2BAAmC;CAC1C,OAAO;EACL,MAAM;EACN,gBAAgB,QAAQ;GACtB,OAAO,YAAY,IAAI,OAAO,KAAK,KAAK,SAAS;IAC/C,MAAM,cAAc,IAAI,KAAK,MAAM,GAAG,EAAE,MAAM;IAC9C,MAAM,cAAc,IAAI,QAAQ,QAAQ,SAAS,WAAW,KAAK;IACjE,MAAM,mBAAmB,WAAW,KAAK,WAAW;IACpD,IAAI,CAAC,eAAe,kBAAkB;KACpC,KAAK;KACL;IACF;IAEA,IAAI;KACF,MAAM,OAAO,MAAM,OAAO,mBAAmB,aAAa,YAAY;KACtE,IAAI,aAAa;KACjB,IAAI,UAAU,gBAAgB,0BAA0B;KACxD,IAAI,IAAI,IAAI;IACd,SAAS,OAAO;KACd,KAAK,KAAK;IACZ;GACF,CAAC;EACH;CACF;AACF;AAEA,eAAsB,iBAAiB,SAAmC,KAAuC;CAC/G,MAAM,gBAAgB,gBAAgB,QAAQ,IAAI;CAElD,MAAM,eAAoC;EACxC,GAAG,MAFoB,kBAAkB,QAAQ,MAAM,GAAG;EAG1D,aAAa,QAAQ;EACrB,eAAe,QAAQ;EACvB,iBAAiB,QAAQ;CAC3B;CAEA,OAAO;EACL,MAAM,QAAQ;EACd,YAAY;EACZ,SAAS;EACT,SAAS,EACP,OAAO,4BAA4B,EACrC;EACA,cAAc,oBAAoB,QAAQ,MAAM,KAAK,MAAM;EAC3D,SAAS,CACP,cAAc,YAAY,GAC1B,yBAAyB,CAC3B;EACA,QAAQ;GACN,MAAM,QAAQ;GACd,MAAM,QAAQ;GACd,MAAM,QAAQ;EAChB;EACA,OAAO;GACL,QAAQ,QAAQ;GAChB,iBAAiB;IACf,OAAO,EACL,OAAO,cACT;IACA,QAAQ,EACN,eAAe,MACjB;IACA,QAAQ,EACN,eAAe,EACb,QAAQ;KACN;MACE,MAAM;MACN,MAAM;MACN,UAAU;KACZ;KACA;MACE,MAAM;MACN,MAAM;MACN,UAAU;KACZ;KACA;MACE,MAAM;MACN,MAAM;MACN,UAAU;KACZ;KACA;MACE,MAAM;MACN,MAAM;MACN,UAAU;KACZ;IACF,EACF,EACF;GACF;EACF;CACF;AACF;;;ACzJA,eAAsB,SAAS,SAA4C;CACzE,IAAI;EACF,MAAM,MAAU,MAAM,iBAAiB,SAAS;GAAE,SAAS;GAAS,MAAM;EAAa,CAAC,CAAC;CAC3F,SAAS,OAAO;EACd,MAAM,cAAc,QAAQ,MAAM,KAAK;EACvC,MAAM;CACR;AACF;;;ACRA,eAAsB,OAAO,SAA4C;CACvE,MAAM,SAAS,MAAM,aAAa,MAAM,iBAAiB,SAAS;EAAE,SAAS;EAAS,MAAM;CAAc,CAAC,CAAC;CAC5G,MAAM,OAAO,OAAO;CACpB,OAAO,UAAU;CACjB,OAAO,iBAAiB,EAAE,OAAO,KAAK,CAAC;AACzC;AEPA,IAAa,oBAAoB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,EAAe,WAAW;AAC3D,IAAa,6BAA6B,IAAI;;;ACM9C,IAAM,UAAU,cAAc,OAAO,KAAK,GAAG;AAE7C,SAAS,2BAAmC;CAC1C,IAAI;EACF,OAAO,QAAQ,QAAQ,sCAAsC;CAC/D,QAAQ;EAEN,MAAM,uBAAuB,QADJ,QAAQ,cAAc,OAAO,KAAK,GAAG,CACzB,GAAkB,oCAAoC;EAC3F,IAAI,WAAW,oBAAoB,GAAG,OAAO;EAC7C,MAAM,IAAI,MAAM,wCAAwC;CAC1D;AACF;AAGA,IAAM,qBAAqB,QADE,yBACM,CAAoB;AAEvD,SAAS,kBAAkB,MAAc,OAAyB;CAChE,MAAM,kBAAkB,QAAQ,MAAM,cAAc;CACpD,MAAM,cAAc,WAAW,eAAe,IAC1C,KAAK,MAAM,aAAa,iBAAiB,OAAO,CAAC,IACjD,EAAE,MAAM,SAAS;CAErB,MAAM,UAAU,OAAO,YAAY,YAAY,YAAY,YAAY,YAAY,OAC/E,YAAY,UACZ,CAAC;CAEL,IAAI,SAAS,CAAC,QAAQ,KAAK,QAAQ,MAAM;CACzC,IAAI,SAAS,CAAC,QAAQ,OAAO,QAAQ,QAAQ;CAC7C,YAAY,UAAU;CAEtB,MAAM,kBAAkB,OAAO,YAAY,oBAAoB,YAAY,YAAY,oBAAoB,OACvG,YAAY,kBACZ,CAAC;CACL,IAAI,CAAC,gBAAgB,sBAAsB,gBAAgB,uBAAuB;CAClF,YAAY,kBAAkB;CAE9B,cAAc,iBAAiB,GAAG,KAAK,UAAU,aAAa,MAAM,CAAC,EAAE,KAAK,OAAO;CACnF,OAAO;AACT;AAEA,SAAgB,QAAQ,SAA6B,OAAgB,UAAyB;CAC5F,MAAM,mBAAmB,gBAAgB,QAAQ;CAEjD,MAAM,EAAE,YAAY,sBADM,qBAAqB,oBAAoB,gBACzB,GAAmB,QAAQ,MAAM;EACzE,YAAY,QAAQ;EACpB;CACF,CAAC;CAGD,IAD2B,kBAAkB,QAAQ,MAAM,KACvD,GAAoB,QAAQ,KAAK,cAAc;CAEnD,QAAQ,IAAI,gCAAgC,iBAAiB,WAAW;CACxE,IAAI,QAAQ,SAAS,GAAG,QAAQ,IAAI,iCAAiC,QAAQ,KAAK,IAAI,GAAG;AAC3F;;;AC3CA,SAAS,YAAY,MAA8C;CACjE,IAAI,SAAS,KAAA,GAAW,OAAO,KAAA;CAE/B,MAAM,aAAa,OAAO,SAAS,WAAW,OAAO,IAAI,IAAI;CAC7D,IAAI,CAAC,OAAO,UAAU,UAAU,KAAK,aAAa,KAAK,aAAa,OAClE,MAAM,IAAI,MAAM,yDAAyD;CAG3E,OAAO;AACT;AAEA,SAAgB,kBAAkB,SAAyC;CACzE,OAAO;EACL,MAAM,QAAQ,QAAQ,QAAQ,QAAQ,IAAI,CAAC;EAC3C,SAAS,QAAQ,WAAW;EAC5B,QAAQ,QAAQ,UAAU;EAC1B,MAAM,QAAQ;EACd,MAAM,YAAY,QAAQ,IAAI;EAC9B,MAAM,QAAQ;CAChB;AACF;;;AC1BA,SAAS,kBAAkB,SAAwD;CACjF,OAAO,QACJ,OAAO,gBAAgB,wBAAwB,EAC/C,OAAO,mBAAmB,oCAAoC,EAC9D,OAAO,kBAAkB,yCAAyC;AACvE;AAEA,SAAS,eAAe,SAAyC;CAC/D,OAAO,kBAAkB,OAAO;AAClC;AAEA,eAAe,OAAsB;CACnC,MAAM,MAAM,IAAI,SAAS;CAEzB,IACG,QAAQ,iBAAiB,EACzB,KAAK;CAER,kBAAkB,IAAI,QAAQ,OAAO,sCAAsC,CAAC,EACzE,OAAO,iBAAiB,iBAAiB,EACzC,OAAO,iBAAiB,iBAAiB,EACzC,OAAO,iBAAiB,kCAAkC,EAC1D,OAAO,OAAO,YAAwB;EACrC,MAAM,OAAO,eAAe,OAAO,CAAC;CACtC,CAAC;CAEH,kBAAkB,IAAI,QAAQ,SAAS,qCAAqC,CAAC,EAC1E,OAAO,OAAO,YAAwB;EACrC,MAAM,SAAS,eAAe,OAAO,CAAC;CACxC,CAAC;CAEH,kBAAkB,IAAI,QAAQ,QAAQ,mCAAmC,CAAC,EACvE,OAAO,WAAW,iCAAiC,EACnD,OAAO,qBAAqB,iDAAiD,EAC7E,QAAQ,YAAgC;EACvC,QAAQ,eAAe,OAAO,GAAG,QAAQ,UAAU,MAAM,QAAQ,QAAQ;CAC3E,CAAC;CAEH,MAAM,OAAO,QAAQ,KAAK,MAAM,CAAC;CACjC,IAAI,MAAM,QAAQ,MAAM,EAAE,KAAK,MAAM,CAAC;CAEtC,IAAI,KAAK,WAAW,GAAG;EACrB,IAAI,WAAW;EACf;CACF;CAEA,MAAM,IAAI,kBAAkB;AAC9B;AAEA,KAAK,EAAE,OAAM,UAAS;CACpB,QAAQ,MAAM,iBAAiB,QAAQ,MAAM,SAAS,MAAM,UAAU,OAAO,KAAK,CAAC;CACnF,QAAQ,WAAW;AACrB,CAAC"}
@@ -78,6 +78,110 @@ export declare const clarifyPagesConfigSchema: z.ZodUnion<readonly [z.ZodArray<z
78
78
  title: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodRecord<z.ZodString, z.ZodString>]>>;
79
79
  }, z.core.$strip>]>>;
80
80
  }, z.core.$strip>>, z.ZodLiteral<"FileTree">]>;
81
+ export declare const clarifyTabItemSchema: z.ZodObject<{
82
+ tab: z.ZodUnion<readonly [z.ZodString, z.ZodRecord<z.ZodString, z.ZodString>]>;
83
+ icon: z.ZodOptional<z.ZodString>;
84
+ pages: z.ZodOptional<z.ZodUnion<readonly [z.ZodArray<z.ZodObject<{
85
+ group: z.ZodUnion<readonly [z.ZodString, z.ZodRecord<z.ZodString, z.ZodString>]>;
86
+ icon: z.ZodOptional<z.ZodString>;
87
+ pages: z.ZodArray<z.ZodUnion<readonly [z.ZodString, z.ZodObject<{
88
+ page: z.ZodString;
89
+ title: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodRecord<z.ZodString, z.ZodString>]>>;
90
+ icon: z.ZodOptional<z.ZodString>;
91
+ redirect: z.ZodOptional<z.ZodString>;
92
+ }, z.core.$strip>, z.ZodObject<{
93
+ openapi: z.ZodString;
94
+ icon: z.ZodOptional<z.ZodString>;
95
+ title: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodRecord<z.ZodString, z.ZodString>]>>;
96
+ }, z.core.$strip>]>>;
97
+ }, z.core.$strip>>, z.ZodLiteral<"FileTree">]>>;
98
+ }, z.core.$strip>;
99
+ export declare const clarifyTabsConfigSchema: z.ZodArray<z.ZodObject<{
100
+ tab: z.ZodUnion<readonly [z.ZodString, z.ZodRecord<z.ZodString, z.ZodString>]>;
101
+ icon: z.ZodOptional<z.ZodString>;
102
+ pages: z.ZodOptional<z.ZodUnion<readonly [z.ZodArray<z.ZodObject<{
103
+ group: z.ZodUnion<readonly [z.ZodString, z.ZodRecord<z.ZodString, z.ZodString>]>;
104
+ icon: z.ZodOptional<z.ZodString>;
105
+ pages: z.ZodArray<z.ZodUnion<readonly [z.ZodString, z.ZodObject<{
106
+ page: z.ZodString;
107
+ title: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodRecord<z.ZodString, z.ZodString>]>>;
108
+ icon: z.ZodOptional<z.ZodString>;
109
+ redirect: z.ZodOptional<z.ZodString>;
110
+ }, z.core.$strip>, z.ZodObject<{
111
+ openapi: z.ZodString;
112
+ icon: z.ZodOptional<z.ZodString>;
113
+ title: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodRecord<z.ZodString, z.ZodString>]>>;
114
+ }, z.core.$strip>]>>;
115
+ }, z.core.$strip>>, z.ZodLiteral<"FileTree">]>>;
116
+ }, z.core.$strip>>;
117
+ export declare const clarifyThemePresetSchema: z.ZodEnum<{
118
+ default: "default";
119
+ base: "base";
120
+ }>;
121
+ export declare const clarifyThemeColorTokensConfigSchema: z.ZodObject<{
122
+ primary: z.ZodOptional<z.ZodString>;
123
+ accent: z.ZodOptional<z.ZodString>;
124
+ background: z.ZodOptional<z.ZodString>;
125
+ foreground: z.ZodOptional<z.ZodString>;
126
+ surface: z.ZodOptional<z.ZodString>;
127
+ muted: z.ZodOptional<z.ZodString>;
128
+ border: z.ZodOptional<z.ZodString>;
129
+ codeBackground: z.ZodOptional<z.ZodString>;
130
+ }, z.core.$strip>;
131
+ export declare const clarifyThemeRadiusTokensConfigSchema: z.ZodObject<{
132
+ sm: z.ZodOptional<z.ZodString>;
133
+ md: z.ZodOptional<z.ZodString>;
134
+ lg: z.ZodOptional<z.ZodString>;
135
+ xl: z.ZodOptional<z.ZodString>;
136
+ }, z.core.$strip>;
137
+ export declare const clarifyThemeTokensConfigSchema: z.ZodObject<{
138
+ colors: z.ZodOptional<z.ZodObject<{
139
+ primary: z.ZodOptional<z.ZodString>;
140
+ accent: z.ZodOptional<z.ZodString>;
141
+ background: z.ZodOptional<z.ZodString>;
142
+ foreground: z.ZodOptional<z.ZodString>;
143
+ surface: z.ZodOptional<z.ZodString>;
144
+ muted: z.ZodOptional<z.ZodString>;
145
+ border: z.ZodOptional<z.ZodString>;
146
+ codeBackground: z.ZodOptional<z.ZodString>;
147
+ }, z.core.$strip>>;
148
+ radius: z.ZodOptional<z.ZodObject<{
149
+ sm: z.ZodOptional<z.ZodString>;
150
+ md: z.ZodOptional<z.ZodString>;
151
+ lg: z.ZodOptional<z.ZodString>;
152
+ xl: z.ZodOptional<z.ZodString>;
153
+ }, z.core.$strip>>;
154
+ }, z.core.$strip>;
155
+ export declare const clarifyThemeLayoutConfigSchema: z.ZodObject<{
156
+ maxWidth: z.ZodOptional<z.ZodString>;
157
+ }, z.core.$strip>;
158
+ export declare const clarifyThemeConfigSchema: z.ZodObject<{
159
+ preset: z.ZodOptional<z.ZodEnum<{
160
+ default: "default";
161
+ base: "base";
162
+ }>>;
163
+ tokens: z.ZodOptional<z.ZodObject<{
164
+ colors: z.ZodOptional<z.ZodObject<{
165
+ primary: z.ZodOptional<z.ZodString>;
166
+ accent: z.ZodOptional<z.ZodString>;
167
+ background: z.ZodOptional<z.ZodString>;
168
+ foreground: z.ZodOptional<z.ZodString>;
169
+ surface: z.ZodOptional<z.ZodString>;
170
+ muted: z.ZodOptional<z.ZodString>;
171
+ border: z.ZodOptional<z.ZodString>;
172
+ codeBackground: z.ZodOptional<z.ZodString>;
173
+ }, z.core.$strip>>;
174
+ radius: z.ZodOptional<z.ZodObject<{
175
+ sm: z.ZodOptional<z.ZodString>;
176
+ md: z.ZodOptional<z.ZodString>;
177
+ lg: z.ZodOptional<z.ZodString>;
178
+ xl: z.ZodOptional<z.ZodString>;
179
+ }, z.core.$strip>>;
180
+ }, z.core.$strip>>;
181
+ layout: z.ZodOptional<z.ZodObject<{
182
+ maxWidth: z.ZodOptional<z.ZodString>;
183
+ }, z.core.$strip>>;
184
+ }, z.core.$strip>;
81
185
  export declare const clarifyProjectConfigSchema: z.ZodObject<{
82
186
  title: z.ZodOptional<z.ZodString>;
83
187
  description: z.ZodOptional<z.ZodString>;
@@ -90,7 +194,31 @@ export declare const clarifyProjectConfigSchema: z.ZodObject<{
90
194
  dark: z.ZodOptional<z.ZodString>;
91
195
  }, z.core.$strip>]>>;
92
196
  theme: z.ZodOptional<z.ZodObject<{
93
- primary: z.ZodOptional<z.ZodString>;
197
+ preset: z.ZodOptional<z.ZodEnum<{
198
+ default: "default";
199
+ base: "base";
200
+ }>>;
201
+ tokens: z.ZodOptional<z.ZodObject<{
202
+ colors: z.ZodOptional<z.ZodObject<{
203
+ primary: z.ZodOptional<z.ZodString>;
204
+ accent: z.ZodOptional<z.ZodString>;
205
+ background: z.ZodOptional<z.ZodString>;
206
+ foreground: z.ZodOptional<z.ZodString>;
207
+ surface: z.ZodOptional<z.ZodString>;
208
+ muted: z.ZodOptional<z.ZodString>;
209
+ border: z.ZodOptional<z.ZodString>;
210
+ codeBackground: z.ZodOptional<z.ZodString>;
211
+ }, z.core.$strip>>;
212
+ radius: z.ZodOptional<z.ZodObject<{
213
+ sm: z.ZodOptional<z.ZodString>;
214
+ md: z.ZodOptional<z.ZodString>;
215
+ lg: z.ZodOptional<z.ZodString>;
216
+ xl: z.ZodOptional<z.ZodString>;
217
+ }, z.core.$strip>>;
218
+ }, z.core.$strip>>;
219
+ layout: z.ZodOptional<z.ZodObject<{
220
+ maxWidth: z.ZodOptional<z.ZodString>;
221
+ }, z.core.$strip>>;
94
222
  }, z.core.$strip>>;
95
223
  routePrefix: z.ZodOptional<z.ZodString>;
96
224
  navbar: z.ZodOptional<z.ZodObject<{
@@ -122,19 +250,23 @@ export declare const clarifyProjectConfigSchema: z.ZodObject<{
122
250
  dir: z.ZodOptional<z.ZodUnion<readonly [z.ZodLiteral<"ltr">, z.ZodLiteral<"rtl">]>>;
123
251
  }, z.core.$strip>>;
124
252
  }, z.core.$strip>>;
125
- pages: z.ZodOptional<z.ZodUnion<readonly [z.ZodArray<z.ZodObject<{
126
- group: z.ZodUnion<readonly [z.ZodString, z.ZodRecord<z.ZodString, z.ZodString>]>;
253
+ tabs: z.ZodOptional<z.ZodArray<z.ZodObject<{
254
+ tab: z.ZodUnion<readonly [z.ZodString, z.ZodRecord<z.ZodString, z.ZodString>]>;
127
255
  icon: z.ZodOptional<z.ZodString>;
128
- pages: z.ZodArray<z.ZodUnion<readonly [z.ZodString, z.ZodObject<{
129
- page: z.ZodString;
130
- title: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodRecord<z.ZodString, z.ZodString>]>>;
131
- icon: z.ZodOptional<z.ZodString>;
132
- redirect: z.ZodOptional<z.ZodString>;
133
- }, z.core.$strip>, z.ZodObject<{
134
- openapi: z.ZodString;
256
+ pages: z.ZodOptional<z.ZodUnion<readonly [z.ZodArray<z.ZodObject<{
257
+ group: z.ZodUnion<readonly [z.ZodString, z.ZodRecord<z.ZodString, z.ZodString>]>;
135
258
  icon: z.ZodOptional<z.ZodString>;
136
- title: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodRecord<z.ZodString, z.ZodString>]>>;
137
- }, z.core.$strip>]>>;
138
- }, z.core.$strip>>, z.ZodLiteral<"FileTree">]>>;
259
+ pages: z.ZodArray<z.ZodUnion<readonly [z.ZodString, z.ZodObject<{
260
+ page: z.ZodString;
261
+ title: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodRecord<z.ZodString, z.ZodString>]>>;
262
+ icon: z.ZodOptional<z.ZodString>;
263
+ redirect: z.ZodOptional<z.ZodString>;
264
+ }, z.core.$strip>, z.ZodObject<{
265
+ openapi: z.ZodString;
266
+ icon: z.ZodOptional<z.ZodString>;
267
+ title: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodRecord<z.ZodString, z.ZodString>]>>;
268
+ }, z.core.$strip>]>>;
269
+ }, z.core.$strip>>, z.ZodLiteral<"FileTree">]>>;
270
+ }, z.core.$strip>>>;
139
271
  }, z.core.$strip>;
140
272
  export type ClarifyProjectConfigInput = z.input<typeof clarifyProjectConfigSchema>;
@@ -0,0 +1,2 @@
1
+ export declare function logBuildError(root: string, error: unknown, maxEntries?: number): Promise<void>;
2
+ export declare function logBuildErrorSync(root: string, error: unknown, maxEntries?: number): void;