@clarify-labs/cli 0.9.3 → 0.10.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/spawn.d.ts +1 -1
- package/output/cli.cjs +60 -128
- package/output/cli.cjs.map +1 -1
- package/output/cli.js +56 -124
- package/output/cli.js.map +1 -1
- package/output/core/adapters.d.ts +11 -0
- package/output/core/{config-schema.d.ts → config/config-schema.d.ts} +1 -10
- package/output/core/{config.d.ts → config/config.d.ts} +1 -1
- package/output/core/{options.d.ts → config/options.d.ts} +1 -1
- package/output/core/{user-config.d.ts → config/user-config.d.ts} +1 -1
- package/output/core/engine/context.d.ts +51 -0
- package/output/core/engine/engine.d.ts +68 -0
- package/output/core/engine/phases.d.ts +10 -0
- package/output/core/engine/types.d.ts +26 -0
- package/output/core/{builtin.d.ts → plugin/builtin.d.ts} +1 -1
- package/output/core/{hooks.d.ts → plugin/hooks.d.ts} +2 -1
- package/output/core/plugin/manager.d.ts +9 -0
- package/output/core/project/project-context.d.ts +16 -0
- package/output/core/{project-info.d.ts → project/project-info.d.ts} +3 -3
- package/output/core/{env-types.d.ts → runtime/env-types.d.ts} +1 -1
- package/output/core/runtime/html-template.d.ts +13 -0
- package/output/core/{ssg.d.ts → runtime/ssg.d.ts} +3 -3
- package/output/core/runtime/startup.d.ts +8 -0
- package/output/core/{virtual-modules.d.ts → runtime/virtual-modules.d.ts} +16 -13
- package/output/core/{vite-config.d.ts → runtime/vite-config.d.ts} +2 -1
- package/output/{plugin-poS3N83A.js → engine-3f5Tpa-6.js} +2403 -1804
- package/output/engine-3f5Tpa-6.js.map +1 -0
- package/output/{plugin-BUFe4vEb.cjs → engine-I04EZzjg.cjs} +2425 -1815
- package/output/engine-I04EZzjg.cjs.map +1 -0
- package/output/index.cjs +5 -3
- package/output/index.d.ts +6 -4
- package/output/index.js +2 -2
- package/output/parsers/content/content.d.ts +20 -0
- package/output/parsers/markdown/mdx.d.ts +37 -0
- package/output/{core → parsers/router}/dev-routes.d.ts +2 -2
- package/output/parsers/{routes.d.ts → routes/routes.d.ts} +2 -2
- package/output/parsers/{routes.test-utils.d.ts → routes/routes.test-utils.d.ts} +1 -1
- package/output/plugins/openapi/parser.d.ts +1 -1
- package/output/plugins/openapi/virtual-modules.d.ts +1 -4
- package/output/plugins/variables/index.d.ts +2 -1
- package/output/types.d.ts +40 -5
- package/package.json +12 -12
- package/output/core/content.d.ts +0 -5
- package/output/core/plugin.d.ts +0 -3
- package/output/core/site.d.ts +0 -17
- package/output/parsers/content.d.ts +0 -11
- package/output/parsers/mdx.d.ts +0 -13
- package/output/parsers/variables.d.ts +0 -2
- package/output/plugin-BUFe4vEb.cjs.map +0 -1
- package/output/plugin-poS3N83A.js.map +0 -1
- /package/output/core/{temp-dir.d.ts → project/temp-dir.d.ts} +0 -0
- /package/output/core/{log.d.ts → runtime/log.d.ts} +0 -0
- /package/output/core/{runtime-deps.d.ts → runtime/runtime-deps.d.ts} +0 -0
- /package/output/parsers/{frontmatter.d.ts → markdown/frontmatter.d.ts} +0 -0
- /package/output/{core → parsers/markdown}/utils.d.ts +0 -0
- /package/output/{core → parsers}/theme.d.ts +0 -0
- /package/output/{core → plugins/search-index}/search-language.d.ts +0 -0
package/output/cli.js
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { a as
|
|
3
|
-
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
2
|
+
import { a as cliPackageVersion, i as createClarifyTempDir, n as createClarifyEngine, o as cliPackageVersionWithCaret, r as createClarifyRuntimeAliases, s as createViteAdapter } from "./engine-3f5Tpa-6.js";
|
|
4
3
|
import { dirname, extname, isAbsolute, join, normalize, relative, resolve } from "node:path";
|
|
5
|
-
import {
|
|
4
|
+
import { lstat, readFile, stat, writeFile } from "node:fs/promises";
|
|
5
|
+
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
6
6
|
import { build, createLogger, createServer } from "vite";
|
|
7
|
+
import { fileURLToPath } from "node:url";
|
|
7
8
|
import { createRequire } from "node:module";
|
|
8
9
|
import { cac } from "cac";
|
|
9
|
-
import { lstat, readFile, stat, writeFile } from "node:fs/promises";
|
|
10
10
|
import { copyTemplateDirectory, getTemplateDirectory, resolveTemplate } from "@clarify-labs/templates";
|
|
11
11
|
import { spawnSync } from "node:child_process";
|
|
12
|
-
//#region source/core/log.ts
|
|
12
|
+
//#region source/core/runtime/log.ts
|
|
13
13
|
var LOG_FILE_NAME = ".clarify.log";
|
|
14
14
|
var DEFAULT_LOG_ENTRIES = 50;
|
|
15
15
|
var ENTRY_SEPARATOR = "\n\n---\n\n";
|
|
@@ -48,38 +48,35 @@ function formatLogEntry(root, error) {
|
|
|
48
48
|
stack ? `Stack:\n${stack}` : void 0
|
|
49
49
|
].filter(Boolean).join("\n");
|
|
50
50
|
}
|
|
51
|
-
|
|
51
|
+
function collectLogEntries(entries, entry, max) {
|
|
52
|
+
const next = [...entries, entry];
|
|
53
|
+
return next.length > max ? next.slice(-max) : next;
|
|
54
|
+
}
|
|
55
|
+
function readExistingEntries(content) {
|
|
56
|
+
return content.split(ENTRY_SEPARATOR).map((item) => item.trim()).filter(Boolean);
|
|
57
|
+
}
|
|
58
|
+
async function writeLogEntry(root, error, maxEntries, read, write) {
|
|
52
59
|
const logPath = join(root, LOG_FILE_NAME);
|
|
53
60
|
const entry = formatLogEntry(root, error);
|
|
54
61
|
const max = maxEntries ?? getMaxLogEntries();
|
|
55
62
|
let entries = [];
|
|
56
63
|
if (existsSync(logPath)) try {
|
|
57
|
-
entries = (await
|
|
64
|
+
entries = readExistingEntries(await read(logPath));
|
|
58
65
|
} catch {
|
|
59
66
|
entries = [];
|
|
60
67
|
}
|
|
61
|
-
entries
|
|
62
|
-
if (entries.length > max) entries = entries.slice(-max);
|
|
68
|
+
entries = collectLogEntries(entries, entry, max);
|
|
63
69
|
mkdirSync(dirname(logPath), { recursive: true });
|
|
64
|
-
await
|
|
70
|
+
await write(logPath, entries.join(ENTRY_SEPARATOR) + "\n");
|
|
71
|
+
}
|
|
72
|
+
async function logBuildError(root, error, maxEntries) {
|
|
73
|
+
await writeLogEntry(root, error, maxEntries, (path) => readFile(path, "utf8"), (path, content) => writeFile(path, content, "utf8"));
|
|
65
74
|
}
|
|
66
75
|
function logBuildErrorSync(root, error, maxEntries) {
|
|
67
|
-
|
|
68
|
-
const entry = formatLogEntry(root, error);
|
|
69
|
-
const max = maxEntries ?? getMaxLogEntries();
|
|
70
|
-
let entries = [];
|
|
71
|
-
if (existsSync(logPath)) try {
|
|
72
|
-
entries = readFileSync(logPath, "utf8").split(ENTRY_SEPARATOR).map((item) => item.trim()).filter(Boolean);
|
|
73
|
-
} catch {
|
|
74
|
-
entries = [];
|
|
75
|
-
}
|
|
76
|
-
entries.push(entry);
|
|
77
|
-
if (entries.length > max) entries = entries.slice(-max);
|
|
78
|
-
mkdirSync(dirname(logPath), { recursive: true });
|
|
79
|
-
writeFileSync(logPath, entries.join(ENTRY_SEPARATOR) + "\n", "utf8");
|
|
76
|
+
writeLogEntry(root, error, maxEntries, (path) => readFileSync(path, "utf8"), (path, content) => writeFileSync(path, content, "utf8"));
|
|
80
77
|
}
|
|
81
78
|
//#endregion
|
|
82
|
-
//#region source/core/vite-config.ts
|
|
79
|
+
//#region source/core/runtime/vite-config.ts
|
|
83
80
|
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>";
|
|
84
81
|
function ensureHtmlEntry(root) {
|
|
85
82
|
const projectHtmlPath = resolve(root, "index.html");
|
|
@@ -141,21 +138,15 @@ function createHtmlFallbackPlugin() {
|
|
|
141
138
|
}
|
|
142
139
|
};
|
|
143
140
|
}
|
|
144
|
-
async function createViteConfig(options, env) {
|
|
141
|
+
async function createViteConfig(options, env, engine) {
|
|
145
142
|
const entryHtmlPath = ensureHtmlEntry(options.root);
|
|
146
|
-
const buildOptions = {
|
|
147
|
-
...await loadClarifyConfig(options.root, env),
|
|
148
|
-
projectRoot: options.root,
|
|
149
|
-
rootDirectory: options.content,
|
|
150
|
-
outputDirectory: options.output
|
|
151
|
-
};
|
|
152
143
|
return {
|
|
153
144
|
root: options.root,
|
|
154
145
|
configFile: false,
|
|
155
146
|
appType: "custom",
|
|
156
147
|
resolve: { alias: createClarifyRuntimeAliases() },
|
|
157
148
|
customLogger: createClarifyLogger(options.root, env, "info"),
|
|
158
|
-
plugins: [
|
|
149
|
+
plugins: [createViteAdapter(engine), createHtmlFallbackPlugin()],
|
|
159
150
|
server: {
|
|
160
151
|
host: options.host,
|
|
161
152
|
port: options.port,
|
|
@@ -200,11 +191,18 @@ async function createViteConfig(options, env) {
|
|
|
200
191
|
//#endregion
|
|
201
192
|
//#region source/cli/commands/build.ts
|
|
202
193
|
async function runBuild(options) {
|
|
194
|
+
const env = {
|
|
195
|
+
command: "build",
|
|
196
|
+
mode: "production"
|
|
197
|
+
};
|
|
198
|
+
const engine = createClarifyEngine({
|
|
199
|
+
projectRoot: options.root,
|
|
200
|
+
rootDirectory: options.content,
|
|
201
|
+
outputDirectory: options.output
|
|
202
|
+
});
|
|
203
203
|
try {
|
|
204
|
-
await
|
|
205
|
-
|
|
206
|
-
mode: "production"
|
|
207
|
-
}));
|
|
204
|
+
await engine.prepare(env);
|
|
205
|
+
await build(await createViteConfig(options, env, engine));
|
|
208
206
|
} catch (error) {
|
|
209
207
|
await logBuildError(options.root, error);
|
|
210
208
|
throw error;
|
|
@@ -213,7 +211,7 @@ async function runBuild(options) {
|
|
|
213
211
|
//#endregion
|
|
214
212
|
//#region source/cli/commands/check.ts
|
|
215
213
|
var LOCAL_LINK_PATTERN = /(?<!!)(?:\[[^\]]*\]\(([^)\s]+)(?:\s+"[^"]*")?\)|<a\s+[^>]*href=["']([^"']+)["'])/gi;
|
|
216
|
-
var ROUTE_EXTENSIONS = new Set([".md", ".mdx"]);
|
|
214
|
+
var ROUTE_EXTENSIONS = /* @__PURE__ */ new Set([".md", ".mdx"]);
|
|
217
215
|
var IGNORED_SCHEMES = /^[a-z][a-z0-9+.-]*:/i;
|
|
218
216
|
function addDiagnostic(result, diagnostic) {
|
|
219
217
|
if (diagnostic.level === "error") result.errors.push(diagnostic);
|
|
@@ -334,24 +332,24 @@ function printTextResult(result, strict) {
|
|
|
334
332
|
console.log(`\n${result.errors.length} error(s), ${result.warnings.length} warning(s)${warningExit ? " (--strict treats warnings as failures)" : ""}`);
|
|
335
333
|
}
|
|
336
334
|
async function runCheck(options = {}) {
|
|
337
|
-
const
|
|
338
|
-
|
|
339
|
-
...existsSync(root) ? await loadClarifyConfig(root, {
|
|
340
|
-
command: "build",
|
|
341
|
-
mode: "production"
|
|
342
|
-
}) : {},
|
|
343
|
-
projectRoot: root,
|
|
335
|
+
const engine = createClarifyEngine({
|
|
336
|
+
projectRoot: resolve(options.root ?? process.cwd()),
|
|
344
337
|
rootDirectory: options.content,
|
|
345
338
|
outputDirectory: options.output
|
|
346
|
-
}
|
|
339
|
+
});
|
|
340
|
+
await engine.prepare(void 0, void 0, {
|
|
341
|
+
htmlShell: false,
|
|
342
|
+
skipModules: true,
|
|
343
|
+
skipHints: true
|
|
344
|
+
});
|
|
347
345
|
const result = {
|
|
348
346
|
errors: [],
|
|
349
347
|
warnings: []
|
|
350
348
|
};
|
|
351
|
-
await checkContentDirectory(
|
|
352
|
-
checkDuplicateRoutes(
|
|
353
|
-
checkFallbackRoutes(
|
|
354
|
-
await checkLocalLinks(
|
|
349
|
+
await checkContentDirectory(engine.contentRoot, result);
|
|
350
|
+
checkDuplicateRoutes(engine.routes, result);
|
|
351
|
+
checkFallbackRoutes(engine.routes, result);
|
|
352
|
+
await checkLocalLinks(engine.routes, engine.contentRoot, result);
|
|
355
353
|
if (options.format === "json") console.log(JSON.stringify(result, null, 2));
|
|
356
354
|
else printTextResult(result, Boolean(options.strict));
|
|
357
355
|
if (result.errors.length > 0 || options.strict && result.warnings.length > 0) process.exitCode = 1;
|
|
@@ -359,87 +357,21 @@ async function runCheck(options = {}) {
|
|
|
359
357
|
//#endregion
|
|
360
358
|
//#region source/cli/commands/dev.ts
|
|
361
359
|
async function runDev(options) {
|
|
362
|
-
const
|
|
360
|
+
const env = {
|
|
363
361
|
command: "serve",
|
|
364
362
|
mode: "development"
|
|
365
|
-
}
|
|
363
|
+
};
|
|
364
|
+
const engine = createClarifyEngine({
|
|
365
|
+
projectRoot: options.root,
|
|
366
|
+
rootDirectory: options.content,
|
|
367
|
+
outputDirectory: options.output
|
|
368
|
+
});
|
|
369
|
+
await engine.prepare(env);
|
|
370
|
+
const server = await createServer(await createViteConfig(options, env, engine));
|
|
366
371
|
await server.listen();
|
|
367
372
|
server.printUrls();
|
|
368
373
|
server.bindCLIShortcuts({ print: true });
|
|
369
374
|
}
|
|
370
|
-
var cliPackageVersion = {
|
|
371
|
-
name: "@clarify-labs/cli",
|
|
372
|
-
version: "0.9.3",
|
|
373
|
-
license: "AGPL-3.0-only",
|
|
374
|
-
type: "module",
|
|
375
|
-
repository: {
|
|
376
|
-
"type": "git",
|
|
377
|
-
"url": "https://github.com/taicode-labs/clarify",
|
|
378
|
-
"directory": "packages/cli"
|
|
379
|
-
},
|
|
380
|
-
main: "output/index.cjs",
|
|
381
|
-
module: "output/index.js",
|
|
382
|
-
types: "output/index.d.ts",
|
|
383
|
-
bin: { "clarify": "bin/clarify.js" },
|
|
384
|
-
exports: {
|
|
385
|
-
".": {
|
|
386
|
-
"types": "./output/index.d.ts",
|
|
387
|
-
"import": "./output/index.js",
|
|
388
|
-
"require": "./output/index.cjs",
|
|
389
|
-
"default": "./output/index.js"
|
|
390
|
-
},
|
|
391
|
-
"./package.json": "./package.json"
|
|
392
|
-
},
|
|
393
|
-
files: [
|
|
394
|
-
"LICENSE",
|
|
395
|
-
"bin",
|
|
396
|
-
"output"
|
|
397
|
-
],
|
|
398
|
-
scripts: {
|
|
399
|
-
"dev": "vite build --watch",
|
|
400
|
-
"build": "vite build",
|
|
401
|
-
"lint": "eslint source/",
|
|
402
|
-
"lint:fix": "eslint source/ --fix",
|
|
403
|
-
"typecheck": "tsc -p tsconfig.json --noEmit",
|
|
404
|
-
"test": "vitest run",
|
|
405
|
-
"test:watch": "vitest"
|
|
406
|
-
},
|
|
407
|
-
dependencies: {
|
|
408
|
-
"@apidevtools/swagger-parser": "^12.1.0",
|
|
409
|
-
"@clarify-labs/renderer": "workspace:*",
|
|
410
|
-
"@clarify-labs/templates": "workspace:*",
|
|
411
|
-
"@mdx-js/rollup": "^3.1.1",
|
|
412
|
-
"@tailwindcss/vite": "^4.1.11",
|
|
413
|
-
"@vitejs/plugin-react": "^6.0.2",
|
|
414
|
-
"cac": "^7.0.0",
|
|
415
|
-
"github-slugger": "^2.0.0",
|
|
416
|
-
"gray-matter": "^4.0.3",
|
|
417
|
-
"mdast-util-to-string": "^4.0.0",
|
|
418
|
-
"mermaid": "^11.4.0",
|
|
419
|
-
"openapi-types": "^12.1.3",
|
|
420
|
-
"pagefind": "^1.5.2",
|
|
421
|
-
"react": "^19.1.0",
|
|
422
|
-
"react-dom": "^19.1.0",
|
|
423
|
-
"react-router": "^7.0.0",
|
|
424
|
-
"react-router-dom": "^7.0.0",
|
|
425
|
-
"react-zoom-pan-pinch": "^4.0.3",
|
|
426
|
-
"remark": "^15.0.1",
|
|
427
|
-
"remark-gfm": "^4.0.1",
|
|
428
|
-
"shiki": "0.14.7",
|
|
429
|
-
"unist-util-visit": "^5.1.0",
|
|
430
|
-
"vite": "^8.0.15",
|
|
431
|
-
"yaml": "^2.9.0",
|
|
432
|
-
"zod": "^4.4.3"
|
|
433
|
-
},
|
|
434
|
-
devDependencies: {
|
|
435
|
-
"@mdx-js/mdx": "^3.1.1",
|
|
436
|
-
"@types/react": "^19.1.8",
|
|
437
|
-
"typescript": "^5.8.3",
|
|
438
|
-
"vite-plugin-dts": "^4.5.4",
|
|
439
|
-
"vitest": "^4.1.9"
|
|
440
|
-
}
|
|
441
|
-
}.version ?? "0.0.0";
|
|
442
|
-
var cliPackageVersionWithCaret = `^${cliPackageVersion}`;
|
|
443
375
|
//#endregion
|
|
444
376
|
//#region source/cli/spawn.ts
|
|
445
377
|
function spawnSync$1(command, args, options) {
|
package/output/cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
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/check.ts","../source/cli/commands/dev.ts","../package.json","../source/cli/package.ts","../source/cli/spawn.ts","../source/cli/commands/init.ts","../source/cli/options.ts","../source/cli/program.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, writeFileSync } from 'node:fs'\nimport { 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 { createClarifyTempDir } from './temp-dir.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(createClarifyTempDir('html'), 'index.html')\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 // Keep mermaid and its heavy diagram/render dependencies out of\n // the eager `vendor` chunk so they stay lazily loaded only on\n // pages that actually render a diagram.\n name: 'mermaid-vendor',\n test: /node_modules[\\\\/](mermaid|@mermaid-js|cytoscape|cytoscape-[^\\\\/]+|dagre-d3-es|@dagrejs|dagre|graphlib|elkjs|katex|d3|d3-[^\\\\/]+|internmap|delaunator|robust-predicates|roughjs|points-on-curve|points-on-path|path-data-parser|@braintree[\\\\/]sanitize-url|dompurify|khroma|ts-dedent|stylis|cose-base|layout-base)[\\\\/]/,\n priority: 20,\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 { existsSync } from 'node:fs'\nimport { lstat, stat } from 'node:fs/promises'\nimport { dirname, extname, isAbsolute, join, normalize, relative, resolve } from 'node:path'\n\nimport { resolveClarifySite } from '../../core/site.js'\nimport { loadClarifyConfig } from '../../core/user-config.js'\nimport type { ContentRoute } from '../../types.js'\nimport type { CliOptions } from '../options.js'\n\nexport type CheckCommandOptions = CliOptions & {\n strict?: boolean\n format?: 'text' | 'json' | string\n}\n\ntype CheckLevel = 'error' | 'warning'\n\ntype CheckDiagnostic = {\n level: CheckLevel\n code: string\n message: string\n filePath?: string\n routePath?: string\n}\n\ntype CheckResult = {\n errors: CheckDiagnostic[]\n warnings: CheckDiagnostic[]\n}\n\nconst LOCAL_LINK_PATTERN = /(?<!!)(?:\\[[^\\]]*\\]\\(([^)\\s]+)(?:\\s+\"[^\"]*\")?\\)|<a\\s+[^>]*href=[\"']([^\"']+)[\"'])/gi\nconst ROUTE_EXTENSIONS = new Set(['.md', '.mdx'])\nconst IGNORED_SCHEMES = /^[a-z][a-z0-9+.-]*:/i\n\nfunction addDiagnostic(result: CheckResult, diagnostic: CheckDiagnostic): void {\n if (diagnostic.level === 'error') result.errors.push(diagnostic)\n else result.warnings.push(diagnostic)\n}\n\nfunction normalizeRoutePath(path: string): string {\n const [withoutHash] = path.split('#')\n const clean = withoutHash.replace(/\\/index$/, '') || '/'\n return clean.startsWith('/') ? clean : `/${clean}`\n}\n\nfunction routePathCandidates(href: string, route: ContentRoute): string[] {\n const [withoutHashOrQuery] = href.split(/[?#]/)\n if (!withoutHashOrQuery || withoutHashOrQuery.startsWith('#')) return []\n if (withoutHashOrQuery.startsWith('/')) return [normalizeRoutePath(withoutHashOrQuery)]\n\n const routeDir = dirname(route.path)\n const joined = normalize(join(routeDir, withoutHashOrQuery)).replaceAll('\\\\', '/')\n const extension = extname(joined)\n const base = ROUTE_EXTENSIONS.has(extension) ? joined.slice(0, -extension.length) : joined\n return [normalizeRoutePath(base)]\n}\n\nasync function pathExists(filePath: string): Promise<boolean> {\n try {\n await stat(filePath)\n return true\n } catch {\n return false\n }\n}\n\nfunction isLocalHref(href: string): boolean {\n return Boolean(href) && !href.startsWith('#') && !href.startsWith('//') && !IGNORED_SCHEMES.test(href)\n}\n\nasync function resolveLocalFileLink(href: string, route: ContentRoute, contentRoot: string): Promise<boolean> {\n const [withoutHashOrQuery] = href.split(/[?#]/)\n if (!withoutHashOrQuery || withoutHashOrQuery.startsWith('/')) return false\n\n const target = resolve(dirname(route.filePath), withoutHashOrQuery)\n const relativeTarget = relative(contentRoot, target)\n if (relativeTarget.startsWith('..') || isAbsolute(relativeTarget)) return false\n if (await pathExists(target)) return true\n\n if (!extname(target)) {\n return pathExists(`${target}.md`) || pathExists(`${target}.mdx`) || pathExists(join(target, 'index.md')) || pathExists(join(target, 'index.mdx'))\n }\n return false\n}\n\nasync function checkContentDirectory(contentRoot: string, result: CheckResult): Promise<void> {\n try {\n const stats = await lstat(contentRoot)\n if (!stats.isDirectory()) {\n addDiagnostic(result, {\n level: 'error',\n code: 'content-not-directory',\n message: `Content path is not a directory: ${contentRoot}`,\n filePath: contentRoot,\n })\n }\n } catch {\n addDiagnostic(result, {\n level: 'error',\n code: 'content-missing',\n message: `Content directory does not exist: ${contentRoot}`,\n filePath: contentRoot,\n })\n }\n}\n\nfunction checkDuplicateRoutes(routes: ContentRoute[], result: CheckResult): void {\n const byPath = new Map<string, ContentRoute[]>()\n for (const route of routes) {\n const key = `${route.locale ?? ''}:${route.path}`\n byPath.set(key, [...(byPath.get(key) ?? []), route])\n }\n\n for (const duplicated of byPath.values()) {\n if (duplicated.length < 2) continue\n for (const route of duplicated) {\n addDiagnostic(result, {\n level: 'error',\n code: 'duplicate-route',\n message: `Route \"${route.path}\" is defined by multiple files: ${duplicated.map(route => relative(process.cwd(), route.filePath)).join(', ')}`,\n filePath: route.filePath,\n routePath: route.path,\n })\n }\n }\n}\n\nfunction checkFallbackRoutes(routes: ContentRoute[], result: CheckResult): void {\n for (const route of routes) {\n if (!route.isFallback) continue\n addDiagnostic(result, {\n level: 'warning',\n code: 'i18n-fallback-route',\n message: `Route \"${route.path}\" falls back to ${route.locale ?? 'default'} content from ${relative(process.cwd(), route.filePath)}`,\n filePath: route.filePath,\n routePath: route.path,\n })\n }\n}\n\nasync function checkLocalLinks(routes: ContentRoute[], contentRoot: string, result: CheckResult): Promise<void> {\n const routePaths = new Set(routes.map(route => route.path))\n\n for (const route of routes) {\n if (route.kind !== 'mdx' || !route.content) continue\n for (const match of route.content.matchAll(LOCAL_LINK_PATTERN)) {\n const href = match[1] ?? match[2]\n if (!href || !isLocalHref(href)) continue\n const candidates = routePathCandidates(href, route)\n if (candidates.some(candidate => routePaths.has(candidate))) continue\n if (await resolveLocalFileLink(href, route, contentRoot)) continue\n\n addDiagnostic(result, {\n level: 'error',\n code: 'broken-link',\n message: `Broken local link \"${href}\" in route \"${route.path}\"`,\n filePath: route.filePath,\n routePath: route.path,\n })\n }\n }\n}\n\nfunction printTextResult(result: CheckResult, strict: boolean): void {\n const diagnostics = [...result.errors, ...result.warnings]\n if (diagnostics.length === 0) {\n console.log('✓ Clarify check passed')\n return\n }\n\n for (const diagnostic of diagnostics) {\n const location = diagnostic.filePath ? ` ${relative(process.cwd(), diagnostic.filePath)}` : ''\n const route = diagnostic.routePath ? ` (${diagnostic.routePath})` : ''\n console.log(`${diagnostic.level.toUpperCase()} ${diagnostic.code}${location}${route}`)\n console.log(` ${diagnostic.message}`)\n }\n\n const warningExit = strict && result.warnings.length > 0\n console.log(`\\n${result.errors.length} error(s), ${result.warnings.length} warning(s)${warningExit ? ' (--strict treats warnings as failures)' : ''}`)\n}\n\nexport async function runCheck(options: CheckCommandOptions = {}): Promise<void> {\n const root = resolve(options.root ?? process.cwd())\n const userConfig = existsSync(root) ? await loadClarifyConfig(root, { command: 'build', mode: 'production' }) : {}\n const site = await resolveClarifySite({\n ...userConfig,\n projectRoot: root,\n rootDirectory: options.content,\n outputDirectory: options.output,\n }, { includeHtmlShellPlugin: false })\n\n const result: CheckResult = { errors: [], warnings: [] }\n await checkContentDirectory(site.contentRoot, result)\n checkDuplicateRoutes(site.routes, result)\n checkFallbackRoutes(site.routes, result)\n await checkLocalLinks(site.routes, site.contentRoot, result)\n\n if (options.format === 'json') {\n console.log(JSON.stringify(result, null, 2))\n } else {\n printTextResult(result, Boolean(options.strict))\n }\n\n if (result.errors.length > 0 || (options.strict && result.warnings.length > 0)) {\n process.exitCode = 1\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.9.3\",\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 \"mermaid\": \"^11.4.0\",\n \"openapi-types\": \"^12.1.3\",\n \"pagefind\": \"^1.5.2\",\n \"react\": \"^19.1.0\",\n \"react-dom\": \"^19.1.0\",\n \"react-router\": \"^7.0.0\",\n \"react-router-dom\": \"^7.0.0\",\n \"react-zoom-pan-pinch\": \"^4.0.3\",\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 \"yaml\": \"^2.9.0\",\n \"zod\": \"^4.4.3\"\n },\n \"devDependencies\": {\n \"@mdx-js/mdx\": \"^3.1.1\",\n \"@types/react\": \"^19.1.8\",\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 { spawnSync as nodeSpawnSync, SpawnSyncOptions } from 'node:child_process'\n\ntype SpawnOptions = { cwd?: string; stdio?: 'inherit' | 'ignore' | Array<string> }\n\nexport function spawnSync(command: string, args: string[], options: SpawnOptions) {\n return nodeSpawnSync(command, args, options as SpawnSyncOptions)\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'\nimport { spawnSync } from '../spawn.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 commandExists(program: string): boolean {\n const result = spawnSync(program, ['--version'], { stdio: 'ignore' })\n return result.status === 0 && result.error === undefined\n}\n\ntype InstallCommand = { command: string; args: string[] }\n\nfunction getInstallCommand(): InstallCommand {\n if (commandExists('pnpm')) return { command: 'pnpm', args: ['install'] }\n if (commandExists('npm')) return { command: 'npm', args: ['install'] }\n if (commandExists('yarn')) return { command: 'yarn', args: ['install'] }\n return { command: 'npm', args: ['install'] }\n}\n\nfunction installDependencies(root: string): void {\n const { command, args } = getInstallCommand()\n console.log(`[clarify] Installing dependencies with ${command}...`)\n const result = spawnSync(command, args, { cwd: root, stdio: 'inherit' })\n if (result.status !== 0) {\n throw new Error(`[clarify] Dependency install failed with ${command}`)\n }\n}\n\nfunction getSuggestedInstallCommand(): string {\n if (commandExists('pnpm')) return 'pnpm install'\n if (commandExists('npm')) return 'npm install'\n if (commandExists('yarn')) return 'yarn install'\n return 'npm install'\n}\n\nfunction getSuggestedRunCommand(): string {\n if (commandExists('pnpm')) return 'pnpm dev'\n if (commandExists('yarn')) return 'yarn dev'\n return 'npm run dev'\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'] = 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, install = false): 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] Project scaffold created using the ${selectedTemplate} template.`)\n if (created.length > 0) {\n console.log(`[clarify] Created or updated ${created.length} ${created.length === 1 ? 'file' : 'files'}: ${created.join(', ')}`)\n }\n\n if (install) {\n installDependencies(options.root)\n const suggestedRun = getSuggestedRunCommand()\n console.log('[clarify] Dependencies installed successfully.')\n console.log(`[clarify] You can now run \\`${suggestedRun}\\` to start the local documentation server.`)\n return\n }\n\n const suggestedInstall = getSuggestedInstallCommand()\n const suggestedRun = getSuggestedRunCommand()\n console.log('[clarify] Next steps:')\n console.log(' 1. Change into your new project directory:')\n console.log(` cd ${options.root}`)\n console.log(' 2. Install dependencies:')\n console.log(` ${suggestedInstall}`)\n console.log(' 3. Start the local documentation server:')\n console.log(` ${suggestedRun}`)\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","import { cac } from 'cac'\n\nimport { runBuild } from './commands/build.js'\nimport { runCheck, type CheckCommandOptions } from './commands/check.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 install?: boolean\n}\n\nfunction withBuildOptions(command: ReturnType<ReturnType<typeof cac>['command']>) {\n return command\n .option('--content <dir>', 'Content directory relative to root')\n}\n\nfunction resolveInitOptions(directory: string | undefined, options: InitCommandOptions): ResolvedCliOptions {\n return resolveOptions({\n ...options,\n root: directory,\n })\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\nexport function createCli() {\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('check', 'Validate the documentation project'))\n .option('--strict', 'Treat warnings as failures')\n .option('--format <format>', 'Output format: text or json')\n .action(async (options: CheckCommandOptions) => {\n await runCheck(options)\n })\n\n withBuildOptions(cli.command('init [directory]', '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 .option('--install', 'Install dependencies after init')\n .action((directory: string | undefined, options: InitCommandOptions) => {\n runInit(resolveInitOptions(directory, options), options.force === true, options.template, options.install === true)\n })\n\n return cli\n}\n\nexport async function main(argv = process.argv): Promise<void> {\n const cli = createCli()\n const args = argv.slice(2)\n cli.parse(argv, { run: false })\n\n if (args.length === 0) {\n cli.outputHelp()\n return\n }\n\n await cli.runMatchedCommand()\n}\n","#!/usr/bin/env node\nimport { main } from './program.js'\n\nmain().catch(error => {\n console.error(error instanceof Error ? error.stack ?? error.message : String(error))\n process.exitCode = 1\n})\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"cli.js","names":[],"sources":["../source/core/runtime/log.ts","../source/core/runtime/vite-config.ts","../source/cli/commands/build.ts","../source/cli/commands/check.ts","../source/cli/commands/dev.ts","../source/cli/spawn.ts","../source/cli/commands/init.ts","../source/cli/options.ts","../source/cli/program.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\ntype LogEntryReader = (logPath: string) => Promise<string> | string\ntype LogEntryWriter = (logPath: string, content: string) => Promise<void> | void\n\nfunction collectLogEntries(entries: string[], entry: string, max: number): string[] {\n const next = [...entries, entry]\n return next.length > max ? next.slice(-max) : next\n}\n\nfunction readExistingEntries(content: string): string[] {\n return content\n .split(ENTRY_SEPARATOR)\n .map((item) => item.trim())\n .filter(Boolean)\n}\n\nasync function writeLogEntry(root: string, error: unknown, maxEntries: number | undefined, read: LogEntryReader, write: LogEntryWriter): 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 entries = readExistingEntries(await read(logPath))\n } catch {\n entries = []\n }\n }\n\n entries = collectLogEntries(entries, entry, max)\n\n mkdirSync(dirname(logPath), { recursive: true })\n await write(logPath, entries.join(ENTRY_SEPARATOR) + '\\n')\n}\n\nexport async function logBuildError(root: string, error: unknown, maxEntries?: number): Promise<void> {\n await writeLogEntry(root, error, maxEntries, (path) => readFile(path, 'utf8'), (path, content) => writeFile(path, content, 'utf8'))\n}\n\nexport function logBuildErrorSync(root: string, error: unknown, maxEntries?: number): void {\n void writeLogEntry(root, error, maxEntries, (path) => readFileSync(path, 'utf8'), (path, content) => writeFileSync(path, content, 'utf8'))\n}\n","import { existsSync, writeFileSync } from 'node:fs'\nimport { resolve } from 'node:path'\n\nimport { createLogger } from 'vite'\nimport type { ConfigEnv, InlineConfig, Plugin, LogLevel, Logger, LogOptions, LogErrorOptions, LogType } from 'vite'\n\nimport { createViteAdapter } from '../adapters.js'\nimport type { ClarifyEngine } from '../engine/engine.js'\nimport { createClarifyTempDir } from '../project/temp-dir.js'\n\nimport { logBuildErrorSync } from './log.js'\nimport { createClarifyRuntimeAliases } from './runtime-deps.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(createClarifyTempDir('html'), 'index.html')\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, engine: ClarifyEngine): Promise<InlineConfig> {\n const entryHtmlPath = ensureHtmlEntry(options.root)\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 createViteAdapter(engine),\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 // Keep mermaid and its heavy diagram/render dependencies out of\n // the eager `vendor` chunk so they stay lazily loaded only on\n // pages that actually render a diagram.\n name: 'mermaid-vendor',\n test: /node_modules[\\\\/](mermaid|@mermaid-js|cytoscape|cytoscape-[^\\\\/]+|dagre-d3-es|@dagrejs|dagre|graphlib|elkjs|katex|d3|d3-[^\\\\/]+|internmap|delaunator|robust-predicates|roughjs|points-on-curve|points-on-path|path-data-parser|@braintree[\\\\/]sanitize-url|dompurify|khroma|ts-dedent|stylis|cose-base|layout-base)[\\\\/]/,\n priority: 20,\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 { createClarifyEngine } from '../../core/engine/engine.js'\nimport { logBuildError } from '../../core/runtime/log.js'\nimport { createViteConfig } from '../../core/runtime/vite-config.js'\nimport type { ResolvedCliOptions } from '../options.js'\n\nexport async function runBuild(options: ResolvedCliOptions): Promise<void> {\n const env = { command: 'build' as const, mode: 'production' }\n const engine = createClarifyEngine({\n projectRoot: options.root,\n rootDirectory: options.content,\n outputDirectory: options.output,\n })\n try {\n await engine.prepare(env)\n await viteBuild(await createViteConfig(options, env, engine))\n } catch (error) {\n await logBuildError(options.root, error)\n throw error\n }\n}\n","import { lstat, stat } from 'node:fs/promises'\nimport { dirname, extname, isAbsolute, join, normalize, relative, resolve } from 'node:path'\n\nimport { createClarifyEngine } from '../../core/engine/engine.js'\nimport type { ContentRoute } from '../../types.js'\nimport type { CliOptions } from '../options.js'\n\nexport type CheckCommandOptions = CliOptions & {\n strict?: boolean\n format?: 'text' | 'json' | string\n}\n\ntype CheckLevel = 'error' | 'warning'\n\ntype CheckDiagnostic = {\n level: CheckLevel\n code: string\n message: string\n filePath?: string\n routePath?: string\n}\n\ntype CheckResult = {\n errors: CheckDiagnostic[]\n warnings: CheckDiagnostic[]\n}\n\nconst LOCAL_LINK_PATTERN = /(?<!!)(?:\\[[^\\]]*\\]\\(([^)\\s]+)(?:\\s+\"[^\"]*\")?\\)|<a\\s+[^>]*href=[\"']([^\"']+)[\"'])/gi\nconst ROUTE_EXTENSIONS = new Set(['.md', '.mdx'])\nconst IGNORED_SCHEMES = /^[a-z][a-z0-9+.-]*:/i\n\nfunction addDiagnostic(result: CheckResult, diagnostic: CheckDiagnostic): void {\n if (diagnostic.level === 'error') result.errors.push(diagnostic)\n else result.warnings.push(diagnostic)\n}\n\nfunction normalizeRoutePath(path: string): string {\n const [withoutHash] = path.split('#')\n const clean = withoutHash.replace(/\\/index$/, '') || '/'\n return clean.startsWith('/') ? clean : `/${clean}`\n}\n\nfunction routePathCandidates(href: string, route: ContentRoute): string[] {\n const [withoutHashOrQuery] = href.split(/[?#]/)\n if (!withoutHashOrQuery || withoutHashOrQuery.startsWith('#')) return []\n if (withoutHashOrQuery.startsWith('/')) return [normalizeRoutePath(withoutHashOrQuery)]\n\n const routeDir = dirname(route.path)\n const joined = normalize(join(routeDir, withoutHashOrQuery)).replaceAll('\\\\', '/')\n const extension = extname(joined)\n const base = ROUTE_EXTENSIONS.has(extension) ? joined.slice(0, -extension.length) : joined\n return [normalizeRoutePath(base)]\n}\n\nasync function pathExists(filePath: string): Promise<boolean> {\n try {\n await stat(filePath)\n return true\n } catch {\n return false\n }\n}\n\nfunction isLocalHref(href: string): boolean {\n return Boolean(href) && !href.startsWith('#') && !href.startsWith('//') && !IGNORED_SCHEMES.test(href)\n}\n\nasync function resolveLocalFileLink(href: string, route: ContentRoute, contentRoot: string): Promise<boolean> {\n const [withoutHashOrQuery] = href.split(/[?#]/)\n if (!withoutHashOrQuery || withoutHashOrQuery.startsWith('/')) return false\n\n const target = resolve(dirname(route.filePath), withoutHashOrQuery)\n const relativeTarget = relative(contentRoot, target)\n if (relativeTarget.startsWith('..') || isAbsolute(relativeTarget)) return false\n if (await pathExists(target)) return true\n\n if (!extname(target)) {\n return pathExists(`${target}.md`) || pathExists(`${target}.mdx`) || pathExists(join(target, 'index.md')) || pathExists(join(target, 'index.mdx'))\n }\n return false\n}\n\nasync function checkContentDirectory(contentRoot: string, result: CheckResult): Promise<void> {\n try {\n const stats = await lstat(contentRoot)\n if (!stats.isDirectory()) {\n addDiagnostic(result, {\n level: 'error',\n code: 'content-not-directory',\n message: `Content path is not a directory: ${contentRoot}`,\n filePath: contentRoot,\n })\n }\n } catch {\n addDiagnostic(result, {\n level: 'error',\n code: 'content-missing',\n message: `Content directory does not exist: ${contentRoot}`,\n filePath: contentRoot,\n })\n }\n}\n\nfunction checkDuplicateRoutes(routes: ContentRoute[], result: CheckResult): void {\n const byPath = new Map<string, ContentRoute[]>()\n for (const route of routes) {\n const key = `${route.locale ?? ''}:${route.path}`\n byPath.set(key, [...(byPath.get(key) ?? []), route])\n }\n\n for (const duplicated of byPath.values()) {\n if (duplicated.length < 2) continue\n for (const route of duplicated) {\n addDiagnostic(result, {\n level: 'error',\n code: 'duplicate-route',\n message: `Route \"${route.path}\" is defined by multiple files: ${duplicated.map(route => relative(process.cwd(), route.filePath)).join(', ')}`,\n filePath: route.filePath,\n routePath: route.path,\n })\n }\n }\n}\n\nfunction checkFallbackRoutes(routes: ContentRoute[], result: CheckResult): void {\n for (const route of routes) {\n if (!route.isFallback) continue\n addDiagnostic(result, {\n level: 'warning',\n code: 'i18n-fallback-route',\n message: `Route \"${route.path}\" falls back to ${route.locale ?? 'default'} content from ${relative(process.cwd(), route.filePath)}`,\n filePath: route.filePath,\n routePath: route.path,\n })\n }\n}\n\nasync function checkLocalLinks(routes: ContentRoute[], contentRoot: string, result: CheckResult): Promise<void> {\n const routePaths = new Set(routes.map(route => route.path))\n\n for (const route of routes) {\n if (route.kind !== 'mdx' || !route.content) continue\n for (const match of route.content.matchAll(LOCAL_LINK_PATTERN)) {\n const href = match[1] ?? match[2]\n if (!href || !isLocalHref(href)) continue\n const candidates = routePathCandidates(href, route)\n if (candidates.some(candidate => routePaths.has(candidate))) continue\n if (await resolveLocalFileLink(href, route, contentRoot)) continue\n\n addDiagnostic(result, {\n level: 'error',\n code: 'broken-link',\n message: `Broken local link \"${href}\" in route \"${route.path}\"`,\n filePath: route.filePath,\n routePath: route.path,\n })\n }\n }\n}\n\nfunction printTextResult(result: CheckResult, strict: boolean): void {\n const diagnostics = [...result.errors, ...result.warnings]\n if (diagnostics.length === 0) {\n console.log('✓ Clarify check passed')\n return\n }\n\n for (const diagnostic of diagnostics) {\n const location = diagnostic.filePath ? ` ${relative(process.cwd(), diagnostic.filePath)}` : ''\n const route = diagnostic.routePath ? ` (${diagnostic.routePath})` : ''\n console.log(`${diagnostic.level.toUpperCase()} ${diagnostic.code}${location}${route}`)\n console.log(` ${diagnostic.message}`)\n }\n\n const warningExit = strict && result.warnings.length > 0\n console.log(`\\n${result.errors.length} error(s), ${result.warnings.length} warning(s)${warningExit ? ' (--strict treats warnings as failures)' : ''}`)\n}\n\nexport async function runCheck(options: CheckCommandOptions = {}): Promise<void> {\n const root = resolve(options.root ?? process.cwd())\n const engine = createClarifyEngine({\n projectRoot: root,\n rootDirectory: options.content,\n outputDirectory: options.output,\n })\n await engine.prepare(undefined, undefined, { htmlShell: false, skipModules: true, skipHints: true })\n\n const result: CheckResult = { errors: [], warnings: [] }\n await checkContentDirectory(engine.contentRoot, result)\n checkDuplicateRoutes(engine.routes, result)\n checkFallbackRoutes(engine.routes, result)\n await checkLocalLinks(engine.routes, engine.contentRoot, result)\n\n if (options.format === 'json') {\n console.log(JSON.stringify(result, null, 2))\n } else {\n printTextResult(result, Boolean(options.strict))\n }\n\n if (result.errors.length > 0 || (options.strict && result.warnings.length > 0)) {\n process.exitCode = 1\n }\n}\n","import { createServer } from 'vite'\n\nimport { createClarifyEngine } from '../../core/engine/engine.js'\nimport { createViteConfig } from '../../core/runtime/vite-config.js'\nimport type { ResolvedCliOptions } from '../options.js'\n\nexport async function runDev(options: ResolvedCliOptions): Promise<void> {\n const env = { command: 'serve' as const, mode: 'development' }\n const engine = createClarifyEngine({\n projectRoot: options.root,\n rootDirectory: options.content,\n outputDirectory: options.output,\n })\n await engine.prepare(env)\n const server = await createServer(await createViteConfig(options, env, engine))\n await server.listen()\n server.printUrls()\n server.bindCLIShortcuts({ print: true })\n}\n","import { spawnSync as nodeSpawnSync, SpawnSyncOptions } from 'node:child_process'\n\ntype SpawnOptions = { cwd?: string; stdio?: 'inherit' | 'ignore' | Array<string> }\n\nexport function spawnSync(command: string, args: string[], options: SpawnOptions) {\n return nodeSpawnSync(command, args, options as SpawnSyncOptions)\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'\nimport { spawnSync } from '../spawn.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 commandExists(program: string): boolean {\n const result = spawnSync(program, ['--version'], { stdio: 'ignore' })\n return result.status === 0 && result.error === undefined\n}\n\ntype InstallCommand = { command: string; args: string[] }\n\nfunction getInstallCommand(): InstallCommand {\n if (commandExists('pnpm')) return { command: 'pnpm', args: ['install'] }\n if (commandExists('npm')) return { command: 'npm', args: ['install'] }\n if (commandExists('yarn')) return { command: 'yarn', args: ['install'] }\n return { command: 'npm', args: ['install'] }\n}\n\nfunction installDependencies(root: string): void {\n const { command, args } = getInstallCommand()\n console.log(`[clarify] Installing dependencies with ${command}...`)\n const result = spawnSync(command, args, { cwd: root, stdio: 'inherit' })\n if (result.status !== 0) {\n throw new Error(`[clarify] Dependency install failed with ${command}`)\n }\n}\n\nfunction getSuggestedInstallCommand(): string {\n if (commandExists('pnpm')) return 'pnpm install'\n if (commandExists('npm')) return 'npm install'\n if (commandExists('yarn')) return 'yarn install'\n return 'npm install'\n}\n\nfunction getSuggestedRunCommand(): string {\n if (commandExists('pnpm')) return 'pnpm dev'\n if (commandExists('yarn')) return 'yarn dev'\n return 'npm run dev'\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'] = 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, install = false): 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] Project scaffold created using the ${selectedTemplate} template.`)\n if (created.length > 0) {\n console.log(`[clarify] Created or updated ${created.length} ${created.length === 1 ? 'file' : 'files'}: ${created.join(', ')}`)\n }\n\n if (install) {\n installDependencies(options.root)\n const suggestedRun = getSuggestedRunCommand()\n console.log('[clarify] Dependencies installed successfully.')\n console.log(`[clarify] You can now run \\`${suggestedRun}\\` to start the local documentation server.`)\n return\n }\n\n const suggestedInstall = getSuggestedInstallCommand()\n const suggestedRun = getSuggestedRunCommand()\n console.log('[clarify] Next steps:')\n console.log(' 1. Change into your new project directory:')\n console.log(` cd ${options.root}`)\n console.log(' 2. Install dependencies:')\n console.log(` ${suggestedInstall}`)\n console.log(' 3. Start the local documentation server:')\n console.log(` ${suggestedRun}`)\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","import { cac } from 'cac'\n\nimport { runBuild } from './commands/build.js'\nimport { runCheck, type CheckCommandOptions } from './commands/check.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 install?: boolean\n}\n\nfunction withBuildOptions(command: ReturnType<ReturnType<typeof cac>['command']>) {\n return command\n .option('--content <dir>', 'Content directory relative to root')\n}\n\nfunction resolveInitOptions(directory: string | undefined, options: InitCommandOptions): ResolvedCliOptions {\n return resolveOptions({\n ...options,\n root: directory,\n })\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\nexport function createCli() {\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('check', 'Validate the documentation project'))\n .option('--strict', 'Treat warnings as failures')\n .option('--format <format>', 'Output format: text or json')\n .action(async (options: CheckCommandOptions) => {\n await runCheck(options)\n })\n\n withBuildOptions(cli.command('init [directory]', '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 .option('--install', 'Install dependencies after init')\n .action((directory: string | undefined, options: InitCommandOptions) => {\n runInit(resolveInitOptions(directory, options), options.force === true, options.template, options.install === true)\n })\n\n return cli\n}\n\nexport async function main(argv = process.argv): Promise<void> {\n const cli = createCli()\n const args = argv.slice(2)\n cli.parse(argv, { run: false })\n\n if (args.length === 0) {\n cli.outputHelp()\n return\n }\n\n await cli.runMatchedCommand()\n}\n","#!/usr/bin/env node\nimport { main } from './program.js'\n\nmain().catch(error => {\n console.error(error instanceof Error ? error.stack ?? error.message : String(error))\n process.exitCode = 1\n})\n"],"mappings":"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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { Plugin } from 'vite';
|
|
2
|
+
import { ClarifyEngine } from './engine/engine.js';
|
|
3
|
+
/**
|
|
4
|
+
* Creates the Clarify Vite plugins bound to an already-prepared engine.
|
|
5
|
+
*
|
|
6
|
+
* The caller is responsible for running `engine.prepare()` (initialize +
|
|
7
|
+
* discoverSite + buildModules) before constructing the Vite config that
|
|
8
|
+
* includes these plugins. The adapter never initializes or discovers the
|
|
9
|
+
* site itself - it only bridges Vite lifecycle hooks to the engine.
|
|
10
|
+
*/
|
|
11
|
+
export declare function createViteAdapter(engine: ClarifyEngine): Plugin[];
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
|
-
import { ClarifyVariableValue } from '
|
|
2
|
+
import { ClarifyVariableValue } from '../../types.js';
|
|
3
3
|
export declare const clarifyLogoConfigSchema: z.ZodUnion<readonly [z.ZodString, z.ZodObject<{
|
|
4
4
|
light: z.ZodOptional<z.ZodString>;
|
|
5
5
|
dark: z.ZodOptional<z.ZodString>;
|
|
@@ -37,15 +37,6 @@ export declare const clarifyBannerConfigOptionsSchema: z.ZodObject<{
|
|
|
37
37
|
external: z.ZodOptional<z.ZodBoolean>;
|
|
38
38
|
}, z.core.$strip>>;
|
|
39
39
|
}, z.core.$strict>;
|
|
40
|
-
export declare const clarifyBannerConfigSchema: z.ZodObject<{
|
|
41
|
-
content: z.ZodUnion<readonly [z.ZodString, z.ZodRecord<z.ZodString, z.ZodString>]>;
|
|
42
|
-
dismissible: z.ZodOptional<z.ZodBoolean>;
|
|
43
|
-
link: z.ZodOptional<z.ZodObject<{
|
|
44
|
-
label: z.ZodUnion<readonly [z.ZodString, z.ZodRecord<z.ZodString, z.ZodString>]>;
|
|
45
|
-
href: z.ZodString;
|
|
46
|
-
external: z.ZodOptional<z.ZodBoolean>;
|
|
47
|
-
}, z.core.$strip>>;
|
|
48
|
-
}, z.core.$strict>;
|
|
49
40
|
export declare const clarifyFooterConfigSchema: z.ZodObject<{
|
|
50
41
|
links: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
51
42
|
label: z.ZodUnion<readonly [z.ZodString, z.ZodRecord<z.ZodString, z.ZodString>]>;
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import { ClarifyProjectConfig, ResolvedProjectConfig } from '
|
|
1
|
+
import { ClarifyProjectConfig, ResolvedProjectConfig } from '../../types.js';
|
|
2
2
|
export declare function validateProjectConfig(value: unknown): ClarifyProjectConfig;
|
|
3
3
|
export declare function resolveProjectConfig(config?: ClarifyProjectConfig): ResolvedProjectConfig;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ClarifyPlugin, ClarifyProjectConfig } from '
|
|
1
|
+
import { ClarifyPlugin, ClarifyProjectConfig } from '../../types.js';
|
|
2
2
|
export type ClarifyBuildOptions = ClarifyProjectConfig & {
|
|
3
3
|
/** Project root directory. Defaults to the current working directory. */
|
|
4
4
|
projectRoot?: string;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { ConfigEnv } from 'vite';
|
|
2
|
-
import { ClarifyProjectConfig } from '
|
|
2
|
+
import { ClarifyProjectConfig } from '../../types.js';
|
|
3
3
|
import { ClarifyBuildOptions } from './options.js';
|
|
4
4
|
export type ClarifyConfig = ClarifyProjectConfig & Pick<ClarifyBuildOptions, 'plugins' | 'ssg'>;
|
|
5
5
|
export declare function defineConfig(config: ClarifyConfig): ClarifyConfig;
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { ClarifyHookContext, ClarifyPlugin, ContentRoute, NavigationTree, ResolvedProjectConfig } from '../../types.js';
|
|
2
|
+
import { ResolvedBuildOptions } from '../config/options.js';
|
|
3
|
+
export type ClarifyContextInit = {
|
|
4
|
+
projectRoot: string;
|
|
5
|
+
contentRoot: string;
|
|
6
|
+
projectConfig: ResolvedProjectConfig;
|
|
7
|
+
generateOptions: ResolvedBuildOptions;
|
|
8
|
+
version: string;
|
|
9
|
+
routes?: ContentRoute[];
|
|
10
|
+
navigation?: NavigationTree;
|
|
11
|
+
plugins?: ClarifyPlugin[];
|
|
12
|
+
};
|
|
13
|
+
type ContextListener = () => void;
|
|
14
|
+
export type ProjectStateUpdate = {
|
|
15
|
+
projectRoot?: string;
|
|
16
|
+
contentRoot?: string;
|
|
17
|
+
projectConfig?: ResolvedProjectConfig;
|
|
18
|
+
generateOptions?: ResolvedBuildOptions;
|
|
19
|
+
version?: string;
|
|
20
|
+
};
|
|
21
|
+
export declare class ClarifyContext implements ClarifyHookContext {
|
|
22
|
+
projectRoot: string;
|
|
23
|
+
contentRoot: string;
|
|
24
|
+
projectConfig: ResolvedProjectConfig;
|
|
25
|
+
generateOptions: ResolvedBuildOptions;
|
|
26
|
+
version: string;
|
|
27
|
+
private values;
|
|
28
|
+
private routeListeners;
|
|
29
|
+
private navigationListeners;
|
|
30
|
+
private currentRoutes;
|
|
31
|
+
private currentNavigation;
|
|
32
|
+
private currentPlugins;
|
|
33
|
+
constructor(init: ClarifyContextInit);
|
|
34
|
+
get routes(): ContentRoute[];
|
|
35
|
+
set routes(routes: ContentRoute[]);
|
|
36
|
+
get navigation(): NavigationTree;
|
|
37
|
+
set navigation(navigation: NavigationTree);
|
|
38
|
+
get plugins(): ClarifyPlugin[];
|
|
39
|
+
set plugins(plugins: ClarifyPlugin[]);
|
|
40
|
+
get isI18n(): boolean;
|
|
41
|
+
get defaultLocale(): string | undefined;
|
|
42
|
+
get<T>(key: string): T | undefined;
|
|
43
|
+
set<T>(key: string, value: T): void;
|
|
44
|
+
has(key: string): boolean;
|
|
45
|
+
delete(key: string): boolean;
|
|
46
|
+
onRoutesChange(listener: ContextListener): () => void;
|
|
47
|
+
onNavigationChange(listener: ContextListener): () => void;
|
|
48
|
+
updateProjectState(update: ProjectStateUpdate): void;
|
|
49
|
+
private notify;
|
|
50
|
+
}
|
|
51
|
+
export {};
|