fix: исправить ссылки llms на markdown-файлы
All checks were successful
CI/CD Pipeline / build (push) Successful in 16s
CI/CD Pipeline / version (push) Successful in 4s
CI/CD Pipeline / docker (push) Successful in 42s
CI/CD Pipeline / deploy (push) Successful in 6s

- обновлены ссылки llms.txt на доступные .md-файлы
- добавлено копирование markdown-файлов в публичную статику
- исключена docs/public из сканирования VitePress и индекса Git
- добавлена пометка для локальной копии ARCHITECTURE.md
This commit is contained in:
2026-05-02 06:53:35 +03:00
parent 245dbbe302
commit 07542330b5
4 changed files with 53 additions and 16 deletions

2
.gitignore vendored
View File

@@ -135,6 +135,7 @@ dist
.vitepress/cache
.vitepress/dist
docs/.vitepress
docs/public/
# Generated artifacts
public/docs/
@@ -149,4 +150,3 @@ dist
# Рабочие заметки
notes

View File

@@ -14,6 +14,7 @@ const sidebar = [
export default defineConfig({
srcDir: 'docs',
srcExclude: ['public/**'],
outDir: 'public/docs',
title: 'SLM Design',
description: 'Правила и стандарты архитектуры проекта',

View File

@@ -5,7 +5,12 @@ import { execFileSync } from "child_process";
const SRC_DIR = "./docs";
const PUBLIC_DIR = "./public";
const DOCS_PUBLIC_DIR = path.join(SRC_DIR, "public");
const DOC_ROUTE_PREFIX = "/docs";
const PUBLIC_ARCHITECTURE_FILE = "ARCHITECTURE.md";
const PUBLIC_ARCHITECTURE_NOTICE = `> Локальная копия канонической спецификации SLM Design.
> Источник: https://slm-design.gromlab.ru/ARCHITECTURE.md
> Не редактировать вручную в этом проекте.`;
interface SidebarItem {
text: string;
@@ -43,15 +48,25 @@ function parseSidebar(): SidebarGroup[] {
const SIDEBAR = parseSidebar();
function linkToFileRel(link: string): string {
const rel = link.replace(/^\//, "");
if (rel === "" || rel.endsWith("/")) return `${rel}index.md`;
return `${rel}.md`;
}
function fileRelToRoute(file: string): string {
const route = file.endsWith("/index.md")
? file.replace(/index\.md$/, "")
: file.replace(/\.md$/, "");
return `${DOC_ROUTE_PREFIX}/${route}`;
}
function fileRelToMdUrl(file: string): string {
return `${DOC_ROUTE_PREFIX}/${file}`;
}
function getAllFiles(): string[] {
return SIDEBAR.flatMap((g) =>
g.items.map((item) => {
const rel = item.link.replace(/^\//, "") + ".md";
const indexPath = rel.replace(/\.md$/, "/index.md");
const filePath = path.join(SRC_DIR, indexPath);
return fs.existsSync(filePath) ? indexPath : rel;
})
);
return SIDEBAR.flatMap((g) => g.items.map((item) => linkToFileRel(item.link)));
}
const stripFrontmatter = (content: string) =>
@@ -84,7 +99,7 @@ const buildArchitectureMarkdown = (routePrefix: string) => {
const content = stripRulesLink(stripFrontmatter(raw)).trim();
if (!content) continue;
const route = routePrefix + "/" + file.replace(/\.md$/, "");
const route = routePrefix + fileRelToRoute(file).replace(DOC_ROUTE_PREFIX, "");
const processed = file.endsWith("index.md") ? content : shiftHeadings(content);
parts.push(`<!-- ${route} -->\n${processed}`);
}
@@ -99,9 +114,7 @@ function buildLlms() {
for (const group of SIDEBAR) {
parts.push(`## ${group.text}`);
for (const item of group.items) {
const rel = item.link.replace(/^\//, "") + ".md";
const indexPath = rel.replace(/\.md$/, "/index.md");
const fileRel = fs.existsSync(path.join(SRC_DIR, indexPath)) ? indexPath : rel;
const fileRel = linkToFileRel(item.link);
const filePath = path.join(SRC_DIR, fileRel);
let desc = "";
if (fs.existsSync(filePath)) {
@@ -109,7 +122,7 @@ function buildLlms() {
const fm = raw.match(/^---[\s\S]*?---\n*/m);
desc = fm ? fm[0].match(/description:\s*(.+)/)?.[1] || "" : "";
}
const route = "/docs" + item.link;
const route = fileRelToMdUrl(fileRel);
const line = desc
? `- [${item.text}](${route}): ${desc}`
: `- [${item.text}](${route})`;
@@ -130,10 +143,28 @@ function buildLlmsFull() {
console.log(`llms-full.txt создан: ${outPath}`);
}
function copyMarkdownFiles() {
fs.rmSync(DOCS_PUBLIC_DIR, { recursive: true, force: true });
let copied = 0;
for (const file of getAllFiles()) {
const src = path.join(SRC_DIR, file);
if (!fs.existsSync(src)) continue;
const dest = path.join(DOCS_PUBLIC_DIR, file);
fs.mkdirSync(path.dirname(dest), { recursive: true });
fs.copyFileSync(src, dest);
copied++;
}
console.log(`скопировано ${copied} .md-файлов в ${DOCS_PUBLIC_DIR}`);
}
function buildPublicArchitecture() {
const outPath = path.join(PUBLIC_DIR, PUBLIC_ARCHITECTURE_FILE);
const content = `${PUBLIC_ARCHITECTURE_NOTICE}\n\n${buildArchitectureMarkdown("/docs")}`;
fs.mkdirSync(PUBLIC_DIR, { recursive: true });
fs.writeFileSync(outPath, buildArchitectureMarkdown("/docs"), "utf8");
fs.writeFileSync(outPath, content, "utf8");
console.log(`${PUBLIC_ARCHITECTURE_FILE} создан: ${outPath}`);
}
@@ -180,6 +211,7 @@ function buildReadme() {
buildLlms();
buildLlmsFull();
copyMarkdownFiles();
buildPublicArchitecture();
buildZip();
buildReadme();

View File

@@ -1,4 +1,8 @@
<!-- /docs/architecture//index -->
> Локальная копия канонической спецификации SLM Design.
> Источник: https://slm-design.gromlab.ru/ARCHITECTURE.md
> Не редактировать вручную в этом проекте.
<!-- /docs/architecture/ -->
# SLM Design
Scoped Layered Module Design — модульная архитектура фронтенд-приложений. Код организован по слоям ответственности, а модуль содержит всё, что ему нужно: компоненты, хуки, сторы, типы, стили.