@marlinjai/clearify 1.12.0 → 1.14.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/README.md +1 -0
- package/dist/node/{chunk-2WLFSQS7.js → chunk-2WML2D77.js} +2 -1
- package/dist/node/{chunk-QTGT76RY.js → chunk-CTL4YL7C.js} +21 -0
- package/dist/node/{chunk-XYS5SV4M.js → chunk-GWYMXKDL.js} +7 -5
- package/dist/node/{chunk-6XHVO5AO.js → chunk-HZRIVY25.js} +2 -2
- package/dist/node/{chunk-6YAEHWC7.js → chunk-XR4WG237.js} +5 -4
- package/dist/node/{chunk-EKN6DWXT.js → chunk-ZNCC6M7V.js} +32 -2
- package/dist/node/cli/index.js +2 -2
- package/dist/node/core/config.js +1 -1
- package/dist/node/core/navigation.js +1 -1
- package/dist/node/core/search.d.ts +1 -0
- package/dist/node/hub-register-TCVGPF7N.js +282 -0
- package/dist/node/node/build.js +4 -4
- package/dist/node/node/check.js +3 -3
- package/dist/node/node/index.js +6 -6
- package/dist/node/node/init.d.ts +1 -0
- package/dist/node/node/init.js +1 -1
- package/dist/node/types/index.d.ts +1 -0
- package/dist/node/vite-plugin/index.js +3 -3
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -14,6 +14,7 @@ An open-source documentation site generator. Turn markdown into beautiful docs.
|
|
|
14
14
|
- **OpenAPI API Reference** — custom-built renderer for OpenAPI specs with code examples, schema viewer, and full design system integration
|
|
15
15
|
- **Multi-section support** — pill-based section switcher (e.g. public docs + internal docs)
|
|
16
16
|
- **Auto changelog** — drop a `CHANGELOG.md` in your project root, it appears as `/changelog`
|
|
17
|
+
- **README as landing page** — optionally include your project's `README.md` as the docs overview page
|
|
17
18
|
|
|
18
19
|
## Quick Start
|
|
19
20
|
|
|
@@ -100,7 +100,8 @@ var ClearifyConfigSchema = z.object({
|
|
|
100
100
|
hub: HubConfigSchema,
|
|
101
101
|
hubProject: HubProjectPartialSchema,
|
|
102
102
|
customCss: z.string().optional(),
|
|
103
|
-
headTags: z.array(z.string()).optional()
|
|
103
|
+
headTags: z.array(z.string()).optional(),
|
|
104
|
+
includeReadme: z.boolean().default(false)
|
|
104
105
|
});
|
|
105
106
|
var ClearifyDataSchema = z.object({
|
|
106
107
|
name: z.string().optional(),
|
|
@@ -133,9 +133,30 @@ function buildRoutes(docs, sectionId) {
|
|
|
133
133
|
...sectionId ? { sectionId } : {}
|
|
134
134
|
}));
|
|
135
135
|
}
|
|
136
|
+
function extractReadmeTitle(content) {
|
|
137
|
+
const match = content.match(/^#\s+(.+)$/m);
|
|
138
|
+
return match ? match[1].trim() : "Overview";
|
|
139
|
+
}
|
|
136
140
|
function buildSectionData(section, rootFiles, customNavigation) {
|
|
137
141
|
const docs = scanDocs(section.docsDir, section.exclude, section.basePath);
|
|
138
142
|
if (section.basePath === "/") {
|
|
143
|
+
if (rootFiles?.readmePath && existsSync(rootFiles.readmePath)) {
|
|
144
|
+
const hasIndex = docs.some((d) => d.routePath === "/");
|
|
145
|
+
if (!hasIndex) {
|
|
146
|
+
const content = readFileSync(rootFiles.readmePath, "utf-8");
|
|
147
|
+
const { data } = matter(content);
|
|
148
|
+
const title = extractReadmeTitle(content);
|
|
149
|
+
docs.unshift({
|
|
150
|
+
filePath: rootFiles.readmePath,
|
|
151
|
+
routePath: "/",
|
|
152
|
+
frontmatter: {
|
|
153
|
+
title: data.title ?? title,
|
|
154
|
+
description: data.description ?? "Project overview",
|
|
155
|
+
order: -1
|
|
156
|
+
}
|
|
157
|
+
});
|
|
158
|
+
}
|
|
159
|
+
}
|
|
139
160
|
if (rootFiles?.changelogPath && existsSync(rootFiles.changelogPath)) {
|
|
140
161
|
const content = readFileSync(rootFiles.changelogPath, "utf-8");
|
|
141
162
|
const { data } = matter(content);
|
|
@@ -10,10 +10,10 @@ import {
|
|
|
10
10
|
resolveSections,
|
|
11
11
|
scanHubProjects,
|
|
12
12
|
writeDataConfig
|
|
13
|
-
} from "./chunk-
|
|
13
|
+
} from "./chunk-2WML2D77.js";
|
|
14
14
|
import {
|
|
15
15
|
buildSectionData
|
|
16
|
-
} from "./chunk-
|
|
16
|
+
} from "./chunk-CTL4YL7C.js";
|
|
17
17
|
|
|
18
18
|
// src/vite-plugin/index.ts
|
|
19
19
|
import { resolve, dirname } from "path";
|
|
@@ -59,7 +59,8 @@ function clearifyPlugin(options = {}) {
|
|
|
59
59
|
function getRootFiles() {
|
|
60
60
|
return {
|
|
61
61
|
changelogPath: resolve(userRoot, "CHANGELOG.md"),
|
|
62
|
-
roadmapPath: resolve(userRoot, "ROADMAP.md")
|
|
62
|
+
roadmapPath: resolve(userRoot, "ROADMAP.md"),
|
|
63
|
+
...config.includeReadme ? { readmePath: resolve(userRoot, "README.md") } : {}
|
|
63
64
|
};
|
|
64
65
|
}
|
|
65
66
|
async function refreshDocs() {
|
|
@@ -285,7 +286,7 @@ ${routeEntries.join(",\n")}
|
|
|
285
286
|
server.watcher.add(section.docsDir);
|
|
286
287
|
}
|
|
287
288
|
const rootFiles = getRootFiles();
|
|
288
|
-
for (const rootFile of [rootFiles.changelogPath, rootFiles.roadmapPath]) {
|
|
289
|
+
for (const rootFile of [rootFiles.changelogPath, rootFiles.roadmapPath, rootFiles.readmePath]) {
|
|
289
290
|
if (rootFile && existsSync(rootFile)) {
|
|
290
291
|
server.watcher.add(rootFile);
|
|
291
292
|
}
|
|
@@ -407,8 +408,9 @@ ${routeEntries.join(",\n")}
|
|
|
407
408
|
server.watcher.on("all", (event, path) => {
|
|
408
409
|
const isChangelog = path === rootFiles.changelogPath;
|
|
409
410
|
const isRoadmap = path === rootFiles.roadmapPath;
|
|
411
|
+
const isReadme = path === rootFiles.readmePath;
|
|
410
412
|
const isInSection = visibleSections.some((s) => path.startsWith(s.docsDir));
|
|
411
|
-
if (!isChangelog && !isRoadmap && !isInSection) return;
|
|
413
|
+
if (!isChangelog && !isRoadmap && !isReadme && !isInSection) return;
|
|
412
414
|
if (!path.endsWith(".md") && !path.endsWith(".mdx")) return;
|
|
413
415
|
if (event === "add" || event === "unlink" || event === "change") {
|
|
414
416
|
refreshDocs().then(() => {
|
|
@@ -2,10 +2,10 @@ import {
|
|
|
2
2
|
loadUserConfig,
|
|
3
3
|
resolveConfig,
|
|
4
4
|
resolveSections
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-2WML2D77.js";
|
|
6
6
|
import {
|
|
7
7
|
scanDocs
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-CTL4YL7C.js";
|
|
9
9
|
|
|
10
10
|
// src/node/check.ts
|
|
11
11
|
import { resolve, relative } from "path";
|
|
@@ -8,15 +8,15 @@ import {
|
|
|
8
8
|
} from "./chunk-SCZZB7OE.js";
|
|
9
9
|
import {
|
|
10
10
|
clearifyPlugin
|
|
11
|
-
} from "./chunk-
|
|
11
|
+
} from "./chunk-GWYMXKDL.js";
|
|
12
12
|
import {
|
|
13
13
|
loadUserConfig,
|
|
14
14
|
resolveConfig,
|
|
15
15
|
resolveSections
|
|
16
|
-
} from "./chunk-
|
|
16
|
+
} from "./chunk-2WML2D77.js";
|
|
17
17
|
import {
|
|
18
18
|
buildSectionData
|
|
19
|
-
} from "./chunk-
|
|
19
|
+
} from "./chunk-CTL4YL7C.js";
|
|
20
20
|
|
|
21
21
|
// src/node/build.ts
|
|
22
22
|
import { build as viteBuild } from "vite";
|
|
@@ -157,7 +157,8 @@ async function buildSite() {
|
|
|
157
157
|
const productionSections = allSections.filter((s) => !s.draft);
|
|
158
158
|
const rootFiles = {
|
|
159
159
|
changelogPath: resolve(userRoot, "CHANGELOG.md"),
|
|
160
|
-
roadmapPath: resolve(userRoot, "ROADMAP.md")
|
|
160
|
+
roadmapPath: resolve(userRoot, "ROADMAP.md"),
|
|
161
|
+
...config.includeReadme ? { readmePath: resolve(userRoot, "README.md") } : {}
|
|
161
162
|
};
|
|
162
163
|
const sectionDataList = productionSections.map(
|
|
163
164
|
(section) => buildSectionData(section, rootFiles, config.navigation)
|
|
@@ -1,6 +1,21 @@
|
|
|
1
1
|
// src/node/init.ts
|
|
2
|
-
import { resolve } from "path";
|
|
3
|
-
import { existsSync, mkdirSync, writeFileSync } from "fs";
|
|
2
|
+
import { resolve, basename } from "path";
|
|
3
|
+
import { existsSync, mkdirSync, writeFileSync, readFileSync } from "fs";
|
|
4
|
+
function detectProjectName() {
|
|
5
|
+
const cwd = process.cwd();
|
|
6
|
+
const pkgPath = resolve(cwd, "package.json");
|
|
7
|
+
if (existsSync(pkgPath)) {
|
|
8
|
+
try {
|
|
9
|
+
const pkg = JSON.parse(readFileSync(pkgPath, "utf-8"));
|
|
10
|
+
if (pkg.name) {
|
|
11
|
+
const raw = pkg.name.replace(/^@[^/]+\//, "");
|
|
12
|
+
return raw.replace(/[-_]/g, " ").replace(/\b\w/g, (c) => c.toUpperCase());
|
|
13
|
+
}
|
|
14
|
+
} catch {
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
return basename(cwd).replace(/[-_]/g, " ").replace(/\b\w/g, (c) => c.toUpperCase());
|
|
18
|
+
}
|
|
4
19
|
async function init(options = {}) {
|
|
5
20
|
const cwd = process.cwd();
|
|
6
21
|
const publicDir = resolve(cwd, "docs/public");
|
|
@@ -265,6 +280,21 @@ ${hasInternal ? `
|
|
|
265
280
|
npx clearify dev Start the dev server
|
|
266
281
|
npx clearify build Build for production
|
|
267
282
|
`);
|
|
283
|
+
if (options.hub) {
|
|
284
|
+
const { registerWithHub } = await import("./hub-register-TCVGPF7N.js");
|
|
285
|
+
await registerWithHub({ projectName: detectProjectName() });
|
|
286
|
+
} else {
|
|
287
|
+
const { createInterface } = await import("readline");
|
|
288
|
+
const rl = createInterface({ input: process.stdin, output: process.stdout });
|
|
289
|
+
const answer = await new Promise((resolve2) => {
|
|
290
|
+
rl.question(" Register this project with a documentation hub? [y/N] ", resolve2);
|
|
291
|
+
});
|
|
292
|
+
rl.close();
|
|
293
|
+
if (answer.toLowerCase() === "y") {
|
|
294
|
+
const { registerWithHub } = await import("./hub-register-TCVGPF7N.js");
|
|
295
|
+
await registerWithHub({ projectName: detectProjectName() });
|
|
296
|
+
}
|
|
297
|
+
}
|
|
268
298
|
}
|
|
269
299
|
|
|
270
300
|
export {
|
package/dist/node/cli/index.js
CHANGED
|
@@ -34,9 +34,9 @@ cli.command("build", "Build static documentation site").action(async () => {
|
|
|
34
34
|
const { build } = await import("../node/index.js");
|
|
35
35
|
await build();
|
|
36
36
|
});
|
|
37
|
-
cli.command("init", "Scaffold a docs folder").option("--no-internal", "Skip creating the internal docs section").option("--no-claude-rules", "Skip creating .claude/rules/clearify-docs.md").action(async (options) => {
|
|
37
|
+
cli.command("init", "Scaffold a docs folder and optionally register with a hub").option("--no-internal", "Skip creating the internal docs section").option("--no-claude-rules", "Skip creating .claude/rules/clearify-docs.md").option("--hub", "Register this project with a documentation hub").action(async (options) => {
|
|
38
38
|
const { init } = await import("../node/index.js");
|
|
39
|
-
await init({ noInternal: options.noInternal, noClaudeRules: options.noClaudeRules });
|
|
39
|
+
await init({ noInternal: options.noInternal, noClaudeRules: options.noClaudeRules, hub: options.hub });
|
|
40
40
|
});
|
|
41
41
|
cli.command("check", "Check for broken internal links and frontmatter issues").option("--frontmatter", "Only run frontmatter validation (skip broken link detection)").action(async (options) => {
|
|
42
42
|
const { checkLinks } = await import("../node/check.js");
|
package/dist/node/core/config.js
CHANGED
|
@@ -29,6 +29,7 @@ interface SectionData {
|
|
|
29
29
|
interface RootFileOptions {
|
|
30
30
|
changelogPath?: string;
|
|
31
31
|
roadmapPath?: string;
|
|
32
|
+
readmePath?: string;
|
|
32
33
|
}
|
|
33
34
|
declare function buildSectionData(section: ResolvedSection, rootFiles?: RootFileOptions, customNavigation?: NavigationItem[] | null): SectionData;
|
|
34
35
|
|
|
@@ -0,0 +1,282 @@
|
|
|
1
|
+
// src/node/hub-register.ts
|
|
2
|
+
import { resolve, basename } from "path";
|
|
3
|
+
import { existsSync, readFileSync, writeFileSync, mkdirSync } from "fs";
|
|
4
|
+
import { execSync } from "child_process";
|
|
5
|
+
function detectProjectName() {
|
|
6
|
+
const cwd = process.cwd();
|
|
7
|
+
const pkgPath = resolve(cwd, "package.json");
|
|
8
|
+
if (existsSync(pkgPath)) {
|
|
9
|
+
try {
|
|
10
|
+
const pkg = JSON.parse(readFileSync(pkgPath, "utf-8"));
|
|
11
|
+
if (pkg.name) {
|
|
12
|
+
const raw = pkg.name.replace(/^@[^/]+\//, "");
|
|
13
|
+
return raw.replace(/[-_]/g, " ").replace(/\b\w/g, (c) => c.toUpperCase());
|
|
14
|
+
}
|
|
15
|
+
} catch {
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
return basename(cwd).replace(/[-_]/g, " ").replace(/\b\w/g, (c) => c.toUpperCase());
|
|
19
|
+
}
|
|
20
|
+
function getGitRemoteInfo() {
|
|
21
|
+
try {
|
|
22
|
+
const url = execSync("git remote get-url origin", { encoding: "utf-8" }).trim();
|
|
23
|
+
const match = url.match(/github\.com[:/]([^/]+)\/([^/.]+)/);
|
|
24
|
+
if (match) return { owner: match[1], repo: match[2] };
|
|
25
|
+
} catch {
|
|
26
|
+
}
|
|
27
|
+
return null;
|
|
28
|
+
}
|
|
29
|
+
async function ghApiFetch(url, options = {}) {
|
|
30
|
+
const res = await fetch(url, {
|
|
31
|
+
method: options.method ?? "GET",
|
|
32
|
+
headers: {
|
|
33
|
+
Accept: "application/vnd.github.v3+json",
|
|
34
|
+
"Content-Type": "application/json",
|
|
35
|
+
...options.headers
|
|
36
|
+
},
|
|
37
|
+
body: options.body
|
|
38
|
+
});
|
|
39
|
+
const data = await res.json().catch(() => null);
|
|
40
|
+
return { status: res.status, data };
|
|
41
|
+
}
|
|
42
|
+
async function githubDeviceAuth(clientId) {
|
|
43
|
+
const codeRes = await fetch("https://github.com/login/device/code", {
|
|
44
|
+
method: "POST",
|
|
45
|
+
headers: {
|
|
46
|
+
Accept: "application/json",
|
|
47
|
+
"Content-Type": "application/json"
|
|
48
|
+
},
|
|
49
|
+
body: JSON.stringify({ client_id: clientId, scope: "repo" })
|
|
50
|
+
});
|
|
51
|
+
const codeData = await codeRes.json();
|
|
52
|
+
console.log(`
|
|
53
|
+
Open this URL in your browser: ${codeData.verification_uri}`);
|
|
54
|
+
console.log(` Enter code: ${codeData.user_code}
|
|
55
|
+
`);
|
|
56
|
+
try {
|
|
57
|
+
const platform = process.platform;
|
|
58
|
+
if (platform === "darwin") {
|
|
59
|
+
execSync(`open "${codeData.verification_uri}"`);
|
|
60
|
+
} else if (platform === "linux") {
|
|
61
|
+
execSync(`xdg-open "${codeData.verification_uri}"`);
|
|
62
|
+
} else if (platform === "win32") {
|
|
63
|
+
execSync(`start "${codeData.verification_uri}"`);
|
|
64
|
+
}
|
|
65
|
+
} catch {
|
|
66
|
+
}
|
|
67
|
+
const interval = (codeData.interval || 5) * 1e3;
|
|
68
|
+
const deadline = Date.now() + codeData.expires_in * 1e3;
|
|
69
|
+
while (Date.now() < deadline) {
|
|
70
|
+
await new Promise((r) => setTimeout(r, interval));
|
|
71
|
+
const tokenRes = await fetch("https://github.com/login/oauth/access_token", {
|
|
72
|
+
method: "POST",
|
|
73
|
+
headers: {
|
|
74
|
+
Accept: "application/json",
|
|
75
|
+
"Content-Type": "application/json"
|
|
76
|
+
},
|
|
77
|
+
body: JSON.stringify({
|
|
78
|
+
client_id: clientId,
|
|
79
|
+
device_code: codeData.device_code,
|
|
80
|
+
grant_type: "urn:ietf:params:oauth:grant-type:device_code"
|
|
81
|
+
})
|
|
82
|
+
});
|
|
83
|
+
const tokenData = await tokenRes.json();
|
|
84
|
+
if (tokenData.access_token) {
|
|
85
|
+
console.log(" GitHub authentication successful!\n");
|
|
86
|
+
return tokenData.access_token;
|
|
87
|
+
}
|
|
88
|
+
if (tokenData.error === "authorization_pending") {
|
|
89
|
+
continue;
|
|
90
|
+
}
|
|
91
|
+
if (tokenData.error === "slow_down") {
|
|
92
|
+
await new Promise((r) => setTimeout(r, 5e3));
|
|
93
|
+
continue;
|
|
94
|
+
}
|
|
95
|
+
if (tokenData.error === "expired_token") {
|
|
96
|
+
throw new Error("Device code expired. Please try again.");
|
|
97
|
+
}
|
|
98
|
+
if (tokenData.error === "access_denied") {
|
|
99
|
+
throw new Error("Authorization denied by user.");
|
|
100
|
+
}
|
|
101
|
+
throw new Error(`OAuth error: ${tokenData.error} \u2014 ${tokenData.error_description}`);
|
|
102
|
+
}
|
|
103
|
+
throw new Error("Device code expired. Please try again.");
|
|
104
|
+
}
|
|
105
|
+
async function promptHubRepo() {
|
|
106
|
+
const { createInterface } = await import("readline");
|
|
107
|
+
const rl = createInterface({ input: process.stdin, output: process.stdout });
|
|
108
|
+
const answer = await new Promise((resolve2) => {
|
|
109
|
+
rl.question(" Hub repository (owner/repo): ", resolve2);
|
|
110
|
+
});
|
|
111
|
+
rl.close();
|
|
112
|
+
const parts = answer.trim().split("/");
|
|
113
|
+
if (parts.length !== 2 || !parts[0] || !parts[1]) {
|
|
114
|
+
throw new Error(`Invalid repository format: "${answer}". Expected "owner/repo".`);
|
|
115
|
+
}
|
|
116
|
+
return { owner: parts[0], repo: parts[1] };
|
|
117
|
+
}
|
|
118
|
+
async function updateHubRegistry(token, hub, project) {
|
|
119
|
+
const authHeaders = { Authorization: `token ${token}` };
|
|
120
|
+
const apiBase = "https://api.github.com";
|
|
121
|
+
const fileUrl = `${apiBase}/repos/${hub.owner}/${hub.repo}/contents/clearify.data.json`;
|
|
122
|
+
const getRes = await ghApiFetch(fileUrl, { headers: authHeaders });
|
|
123
|
+
let currentData = { hub: { projects: [] } };
|
|
124
|
+
let fileSha;
|
|
125
|
+
if (getRes.status === 200 && getRes.data?.content) {
|
|
126
|
+
const decoded = Buffer.from(getRes.data.content, "base64").toString("utf-8");
|
|
127
|
+
currentData = JSON.parse(decoded);
|
|
128
|
+
fileSha = getRes.data.sha;
|
|
129
|
+
if (!currentData.hub) currentData.hub = { projects: [] };
|
|
130
|
+
if (!currentData.hub.projects) currentData.hub.projects = [];
|
|
131
|
+
} else if (getRes.status !== 404) {
|
|
132
|
+
throw new Error(`Failed to read hub registry: ${getRes.status} ${JSON.stringify(getRes.data)}`);
|
|
133
|
+
}
|
|
134
|
+
const existingIdx = currentData.hub.projects.findIndex(
|
|
135
|
+
(p) => p.name === project.name
|
|
136
|
+
);
|
|
137
|
+
const entry = {
|
|
138
|
+
name: project.name,
|
|
139
|
+
description: project.description,
|
|
140
|
+
status: "active",
|
|
141
|
+
mode: "embed",
|
|
142
|
+
git: {
|
|
143
|
+
repo: project.gitRepoUrl,
|
|
144
|
+
ref: project.gitRef,
|
|
145
|
+
path: project.docsPath
|
|
146
|
+
}
|
|
147
|
+
};
|
|
148
|
+
if (existingIdx >= 0) {
|
|
149
|
+
currentData.hub.projects[existingIdx] = entry;
|
|
150
|
+
console.log(` Updated existing project "${project.name}" in hub registry`);
|
|
151
|
+
} else {
|
|
152
|
+
currentData.hub.projects.push(entry);
|
|
153
|
+
console.log(` Added project "${project.name}" to hub registry`);
|
|
154
|
+
}
|
|
155
|
+
const updatedContent = Buffer.from(
|
|
156
|
+
JSON.stringify(currentData, null, 2) + "\n"
|
|
157
|
+
).toString("base64");
|
|
158
|
+
const putBody = {
|
|
159
|
+
message: `docs: register ${project.name} in hub`,
|
|
160
|
+
content: updatedContent
|
|
161
|
+
};
|
|
162
|
+
if (fileSha) putBody.sha = fileSha;
|
|
163
|
+
const putRes = await ghApiFetch(fileUrl, {
|
|
164
|
+
method: "PUT",
|
|
165
|
+
headers: authHeaders,
|
|
166
|
+
body: JSON.stringify(putBody)
|
|
167
|
+
});
|
|
168
|
+
if (putRes.status !== 200 && putRes.status !== 201) {
|
|
169
|
+
throw new Error(
|
|
170
|
+
`Failed to update hub registry: ${putRes.status} ${JSON.stringify(putRes.data)}`
|
|
171
|
+
);
|
|
172
|
+
}
|
|
173
|
+
console.log(" Hub registry updated successfully");
|
|
174
|
+
}
|
|
175
|
+
function generateConfig(projectName, hubProject) {
|
|
176
|
+
const cwd = process.cwd();
|
|
177
|
+
const configPath = resolve(cwd, "clearify.config.ts");
|
|
178
|
+
if (existsSync(configPath)) {
|
|
179
|
+
console.log(" clearify.config.ts already exists \u2014 skipping config generation");
|
|
180
|
+
console.log(" Add a hubProject block manually if needed");
|
|
181
|
+
return;
|
|
182
|
+
}
|
|
183
|
+
const description = hubProject?.description ?? "Project documentation";
|
|
184
|
+
const config = `import { defineConfig } from '@marlinjai/clearify';
|
|
185
|
+
|
|
186
|
+
export default defineConfig({
|
|
187
|
+
name: '${projectName}',
|
|
188
|
+
sections: [
|
|
189
|
+
{ label: 'Docs', docsDir: './docs/public' },
|
|
190
|
+
],
|
|
191
|
+
theme: {
|
|
192
|
+
primaryColor: '#3B82F6',
|
|
193
|
+
mode: 'auto',
|
|
194
|
+
},
|
|
195
|
+
hubProject: {
|
|
196
|
+
description: '${description}',
|
|
197
|
+
status: 'active',
|
|
198
|
+
},
|
|
199
|
+
});
|
|
200
|
+
`;
|
|
201
|
+
writeFileSync(configPath, config);
|
|
202
|
+
console.log(" Created clearify.config.ts with hubProject config");
|
|
203
|
+
}
|
|
204
|
+
function generateWorkflow(hub) {
|
|
205
|
+
const cwd = process.cwd();
|
|
206
|
+
const workflowDir = resolve(cwd, ".github/workflows");
|
|
207
|
+
const workflowPath = resolve(workflowDir, "docs-trigger.yml");
|
|
208
|
+
if (existsSync(workflowPath)) {
|
|
209
|
+
console.log(" .github/workflows/docs-trigger.yml already exists \u2014 skipping");
|
|
210
|
+
return;
|
|
211
|
+
}
|
|
212
|
+
mkdirSync(workflowDir, { recursive: true });
|
|
213
|
+
const workflow = `name: Docs Trigger
|
|
214
|
+
|
|
215
|
+
on:
|
|
216
|
+
push:
|
|
217
|
+
branches: [main]
|
|
218
|
+
paths:
|
|
219
|
+
- 'docs/**'
|
|
220
|
+
- 'clearify.config.ts'
|
|
221
|
+
|
|
222
|
+
jobs:
|
|
223
|
+
notify-hub:
|
|
224
|
+
runs-on: ubuntu-latest
|
|
225
|
+
steps:
|
|
226
|
+
- name: Trigger hub rebuild
|
|
227
|
+
run: |
|
|
228
|
+
curl -X POST \\
|
|
229
|
+
-H "Authorization: token \${{ secrets.HUB_DISPATCH_TOKEN }}" \\
|
|
230
|
+
-H "Accept: application/vnd.github.v3+json" \\
|
|
231
|
+
https://api.github.com/repos/${hub.owner}/${hub.repo}/dispatches \\
|
|
232
|
+
-d '{"event_type": "docs-update"}'
|
|
233
|
+
`;
|
|
234
|
+
writeFileSync(workflowPath, workflow);
|
|
235
|
+
console.log(" Created .github/workflows/docs-trigger.yml");
|
|
236
|
+
}
|
|
237
|
+
async function registerWithHub(options) {
|
|
238
|
+
const clientId = process.env.CLEARIFY_GITHUB_CLIENT_ID;
|
|
239
|
+
if (!clientId) {
|
|
240
|
+
console.error("\n Error: CLEARIFY_GITHUB_CLIENT_ID environment variable is not set.");
|
|
241
|
+
console.error(" Set it to your GitHub OAuth App client ID and try again.\n");
|
|
242
|
+
process.exit(1);
|
|
243
|
+
}
|
|
244
|
+
const projectName = options.projectName ?? detectProjectName();
|
|
245
|
+
const currentRepo = getGitRemoteInfo();
|
|
246
|
+
if (!currentRepo) {
|
|
247
|
+
console.error("\n Error: Could not detect git remote origin.");
|
|
248
|
+
console.error(" Make sure this is a git repository with a GitHub remote.\n");
|
|
249
|
+
process.exit(1);
|
|
250
|
+
}
|
|
251
|
+
console.log(`
|
|
252
|
+
Registering "${projectName}" with a documentation hub
|
|
253
|
+
`);
|
|
254
|
+
const hub = await promptHubRepo();
|
|
255
|
+
console.log(` Hub: ${hub.owner}/${hub.repo}
|
|
256
|
+
`);
|
|
257
|
+
console.log(" Starting GitHub authentication...");
|
|
258
|
+
const token = await githubDeviceAuth(clientId);
|
|
259
|
+
console.log(" Updating hub registry...");
|
|
260
|
+
await updateHubRegistry(token, hub, {
|
|
261
|
+
name: projectName,
|
|
262
|
+
description: options.hubProject?.description ?? "Project documentation",
|
|
263
|
+
gitRepoUrl: `https://github.com/${currentRepo.owner}/${currentRepo.repo}.git`,
|
|
264
|
+
gitRef: "main",
|
|
265
|
+
docsPath: "docs/public"
|
|
266
|
+
});
|
|
267
|
+
console.log(" Generating local files...");
|
|
268
|
+
generateConfig(projectName, options.hubProject);
|
|
269
|
+
generateWorkflow(hub);
|
|
270
|
+
console.log(`
|
|
271
|
+
Hub registration complete!
|
|
272
|
+
|
|
273
|
+
Next steps:
|
|
274
|
+
1. Review clearify.config.ts and update the hubProject description
|
|
275
|
+
2. Add "${currentRepo.repo}" to the repos list in infra/deployments/hub-dispatch/github.tf
|
|
276
|
+
3. Run: cd infra/deployments/hub-dispatch && ../../scripts/tfrun.sh apply
|
|
277
|
+
4. Commit the generated files and push to main
|
|
278
|
+
`);
|
|
279
|
+
}
|
|
280
|
+
export {
|
|
281
|
+
registerWithHub
|
|
282
|
+
};
|
package/dist/node/node/build.js
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
import {
|
|
2
2
|
buildSite
|
|
3
|
-
} from "../chunk-
|
|
3
|
+
} from "../chunk-XR4WG237.js";
|
|
4
4
|
import "../chunk-PRTER35L.js";
|
|
5
5
|
import "../chunk-SCZZB7OE.js";
|
|
6
|
-
import "../chunk-
|
|
6
|
+
import "../chunk-GWYMXKDL.js";
|
|
7
7
|
import "../chunk-B2Q23JW3.js";
|
|
8
|
-
import "../chunk-
|
|
8
|
+
import "../chunk-2WML2D77.js";
|
|
9
9
|
import "../chunk-AJBCHKBP.js";
|
|
10
10
|
import "../chunk-V7LLYIRO.js";
|
|
11
|
-
import "../chunk-
|
|
11
|
+
import "../chunk-CTL4YL7C.js";
|
|
12
12
|
import "../chunk-5TD7NQIW.js";
|
|
13
13
|
export {
|
|
14
14
|
buildSite
|
package/dist/node/node/check.js
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import {
|
|
2
2
|
checkFrontmatter,
|
|
3
3
|
checkLinks
|
|
4
|
-
} from "../chunk-
|
|
5
|
-
import "../chunk-
|
|
4
|
+
} from "../chunk-HZRIVY25.js";
|
|
5
|
+
import "../chunk-2WML2D77.js";
|
|
6
6
|
import "../chunk-AJBCHKBP.js";
|
|
7
7
|
import "../chunk-V7LLYIRO.js";
|
|
8
|
-
import "../chunk-
|
|
8
|
+
import "../chunk-CTL4YL7C.js";
|
|
9
9
|
import "../chunk-5TD7NQIW.js";
|
|
10
10
|
export {
|
|
11
11
|
checkFrontmatter,
|
package/dist/node/node/index.js
CHANGED
|
@@ -1,28 +1,28 @@
|
|
|
1
1
|
import {
|
|
2
2
|
buildSite
|
|
3
|
-
} from "../chunk-
|
|
3
|
+
} from "../chunk-XR4WG237.js";
|
|
4
4
|
import {
|
|
5
5
|
remarkMermaidToComponent
|
|
6
6
|
} from "../chunk-PRTER35L.js";
|
|
7
7
|
import "../chunk-SCZZB7OE.js";
|
|
8
8
|
import {
|
|
9
9
|
clearifyPlugin
|
|
10
|
-
} from "../chunk-
|
|
10
|
+
} from "../chunk-GWYMXKDL.js";
|
|
11
11
|
import "../chunk-B2Q23JW3.js";
|
|
12
12
|
import {
|
|
13
13
|
init
|
|
14
|
-
} from "../chunk-
|
|
14
|
+
} from "../chunk-ZNCC6M7V.js";
|
|
15
15
|
import {
|
|
16
16
|
checkFrontmatter,
|
|
17
17
|
checkLinks
|
|
18
|
-
} from "../chunk-
|
|
18
|
+
} from "../chunk-HZRIVY25.js";
|
|
19
19
|
import {
|
|
20
20
|
loadUserConfig,
|
|
21
21
|
resolveConfig
|
|
22
|
-
} from "../chunk-
|
|
22
|
+
} from "../chunk-2WML2D77.js";
|
|
23
23
|
import "../chunk-AJBCHKBP.js";
|
|
24
24
|
import "../chunk-V7LLYIRO.js";
|
|
25
|
-
import "../chunk-
|
|
25
|
+
import "../chunk-CTL4YL7C.js";
|
|
26
26
|
import "../chunk-5TD7NQIW.js";
|
|
27
27
|
|
|
28
28
|
// src/node/index.ts
|
package/dist/node/node/init.d.ts
CHANGED
package/dist/node/node/init.js
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import {
|
|
2
2
|
clearifyPlugin
|
|
3
|
-
} from "../chunk-
|
|
3
|
+
} from "../chunk-GWYMXKDL.js";
|
|
4
4
|
import "../chunk-B2Q23JW3.js";
|
|
5
|
-
import "../chunk-
|
|
5
|
+
import "../chunk-2WML2D77.js";
|
|
6
6
|
import "../chunk-AJBCHKBP.js";
|
|
7
7
|
import "../chunk-V7LLYIRO.js";
|
|
8
|
-
import "../chunk-
|
|
8
|
+
import "../chunk-CTL4YL7C.js";
|
|
9
9
|
import "../chunk-5TD7NQIW.js";
|
|
10
10
|
export {
|
|
11
11
|
clearifyPlugin
|