code-frontmatter 0.2.4 → 0.2.5

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/dist/registry.js DELETED
@@ -1,96 +0,0 @@
1
- /*---
2
- intent: "管理语言注册表:加载内置语言规则、按文件扩展名查找语言、支持运行时动态注册新语言"
3
- role: service
4
- exports:
5
- - "loadRegistry: 从 registry.json 加载内置语言注册表"
6
- - "getLanguageByExtension: 根据文件扩展名查找对应的语言规则"
7
- - "registerLanguage: 运行时注册新的语言注释规则"
8
- - "getAllLanguages: 获取所有已注册的语言列表"
9
- depends_on: ["./schema.ts", "../languages/registry.json"]
10
- when_to_load: "修改语言查找逻辑或注册机制时加载"
11
- ---*/
12
- import { readFile } from "node:fs/promises";
13
- import { fileURLToPath } from "node:url";
14
- import { dirname, join } from "node:path";
15
- import { LanguageRuleSchema } from "./schema.js";
16
- /**
17
- * 语言注册表:语言名称 → 注释规则映射
18
- * 键为语言名(如 "javascript"),值为注释标记配置
19
- */
20
- const registry = new Map();
21
- /**
22
- * 扩展名反向索引:扩展名 → 语言名映射
23
- * 用于快速按扩展名查找语言
24
- */
25
- const extensionIndex = new Map();
26
- /**
27
- * 从 languages/registry.json 加载内置语言注册表
28
- * 应在 MCP Server 启动时调用一次
29
- */
30
- export async function loadRegistry() {
31
- // 定位 registry.json 文件路径(相对于当前模块)
32
- const __filename = fileURLToPath(import.meta.url);
33
- const __dirname = dirname(__filename);
34
- const registryPath = join(__dirname, "..", "languages", "registry.json");
35
- const raw = await readFile(registryPath, "utf-8");
36
- const data = JSON.parse(raw);
37
- for (const [name, rule] of Object.entries(data)) {
38
- // 用 Zod 校验每条语言规则的格式
39
- const parsed = LanguageRuleSchema.parse(rule);
40
- registry.set(name, parsed);
41
- // 建立扩展名 → 语言名的反向索引
42
- for (const ext of parsed.extensions) {
43
- extensionIndex.set(ext.toLowerCase(), name);
44
- }
45
- }
46
- }
47
- /**
48
- * 根据文件扩展名查找对应的语言注释规则
49
- * @param ext - 文件扩展名,如 ".js", ".py"
50
- * @returns 匹配的语言规则,未找到则返回 null
51
- */
52
- export function getLanguageByExtension(ext) {
53
- const normalizedExt = ext.toLowerCase();
54
- const langName = extensionIndex.get(normalizedExt);
55
- if (!langName)
56
- return null;
57
- const rule = registry.get(langName);
58
- if (!rule)
59
- return null;
60
- return { name: langName, rule };
61
- }
62
- /**
63
- * 运行时动态注册新语言
64
- * @param name - 语言名称
65
- * @param rule - 语言注释规则
66
- * @throws 如果该语言已存在则抛出错误
67
- */
68
- export function registerLanguage(name, rule) {
69
- const normalizedName = name.toLowerCase();
70
- if (registry.has(normalizedName)) {
71
- throw new Error(`语言 "${name}" 已存在于注册表中。如需更新,请先移除旧注册。`);
72
- }
73
- // 检查扩展名是否与已有语言冲突
74
- for (const ext of rule.extensions) {
75
- const existing = extensionIndex.get(ext.toLowerCase());
76
- if (existing) {
77
- throw new Error(`扩展名 "${ext}" 已被语言 "${existing}" 注册。`);
78
- }
79
- }
80
- registry.set(normalizedName, rule);
81
- for (const ext of rule.extensions) {
82
- extensionIndex.set(ext.toLowerCase(), normalizedName);
83
- }
84
- }
85
- /**
86
- * 获取所有已注册的语言及其规则
87
- * @returns 语言名称与规则的映射
88
- */
89
- export function getAllLanguages() {
90
- const result = {};
91
- for (const [name, rule] of registry.entries()) {
92
- result[name] = rule;
93
- }
94
- return result;
95
- }
96
- //# sourceMappingURL=registry.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"registry.js","sourceRoot":"","sources":["../src/registry.ts"],"names":[],"mappings":"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"}
package/dist/schema.d.ts DELETED
@@ -1,141 +0,0 @@
1
- import { z } from "zod";
2
- /**
3
- * 语言注释规则 Schema
4
- * 定义某种编程语言的 CFM 注释语法
5
- */
6
- export declare const LanguageRuleSchema: z.ZodObject<{
7
- /** 注释起始标记,如 "/*---" */
8
- comment_start: z.ZodString;
9
- /** 注释结束标记,如 "---*​/" */
10
- comment_end: z.ZodString;
11
- /** 该语言的文件扩展名列表 */
12
- extensions: z.ZodArray<z.ZodString, "many">;
13
- /** 行前缀(脚本语言使用),如 "# ",C 家族为 null */
14
- line_prefix: z.ZodNullable<z.ZodString>;
15
- }, "strip", z.ZodTypeAny, {
16
- comment_start: string;
17
- comment_end: string;
18
- extensions: string[];
19
- line_prefix: string | null;
20
- }, {
21
- comment_start: string;
22
- comment_end: string;
23
- extensions: string[];
24
- line_prefix: string | null;
25
- }>;
26
- export type LanguageRule = z.infer<typeof LanguageRuleSchema>;
27
- /**
28
- * CFM 表头严格 Schema(含全部必选字段)
29
- * 用于校验完整规范的表头
30
- */
31
- export declare const CfmSchema: z.ZodObject<{
32
- /** 文件的核心用途和业务价值 (Be concise, < 50 words) */
33
- intent: z.ZodString;
34
- /** 文件的角色类型 */
35
- role: z.ZodString;
36
- /** 暴露的关键 API / 函数 / 组件 (Signature: Brief description) */
37
- exports: z.ZodArray<z.ZodString, "many">;
38
- /** 关键依赖 */
39
- depends_on: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
40
- /** 什么场景下才需要读取此文件全文 */
41
- when_to_load: z.ZodOptional<z.ZodString>;
42
- /** 副作用描述 */
43
- side_effects: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
44
- /** 是否修改外部状态 */
45
- mutates_state: z.ZodOptional<z.ZodBoolean>;
46
- /** 业务领域标签 */
47
- domain: z.ZodOptional<z.ZodString>;
48
- /** 给 AI 的特殊注意事项 (Critical constraints only. NO changelogs/history. Be concise!) */
49
- ai_notes: z.ZodOptional<z.ZodString>;
50
- /** 表头规范版本号 */
51
- cfm_version: z.ZodOptional<z.ZodString>;
52
- }, "strip", z.ZodTypeAny, {
53
- intent: string;
54
- role: string;
55
- exports: string[];
56
- depends_on?: string[] | undefined;
57
- when_to_load?: string | undefined;
58
- side_effects?: string[] | undefined;
59
- mutates_state?: boolean | undefined;
60
- domain?: string | undefined;
61
- ai_notes?: string | undefined;
62
- cfm_version?: string | undefined;
63
- }, {
64
- intent: string;
65
- role: string;
66
- exports: string[];
67
- depends_on?: string[] | undefined;
68
- when_to_load?: string | undefined;
69
- side_effects?: string[] | undefined;
70
- mutates_state?: boolean | undefined;
71
- domain?: string | undefined;
72
- ai_notes?: string | undefined;
73
- cfm_version?: string | undefined;
74
- }>;
75
- export type CfmData = z.infer<typeof CfmSchema>;
76
- /**
77
- * CFM 表头宽松 Schema(只要求 intent 字段)
78
- * 用于渐进式表头补充场景——已有表头但尚不完整的文件
79
- */
80
- export declare const CfmSchemaLoose: z.ZodObject<{
81
- intent: z.ZodString;
82
- }, "passthrough", z.ZodTypeAny, z.objectOutputType<{
83
- intent: z.ZodString;
84
- }, z.ZodTypeAny, "passthrough">, z.objectInputType<{
85
- intent: z.ZodString;
86
- }, z.ZodTypeAny, "passthrough">>;
87
- /**
88
- * 单个文件的 CFM 条目
89
- * 包含文件路径和解析出的元数据
90
- */
91
- export declare const CfmEntrySchema: z.ZodObject<{
92
- /** 文件相对路径 */
93
- file: z.ZodString;
94
- /** 检测到的编程语言 */
95
- language: z.ZodOptional<z.ZodString>;
96
- /** 解析出的 CFM 表头数据 */
97
- frontmatter: z.ZodNullable<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
98
- /** 校验警告信息 */
99
- warnings: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
100
- }, "strip", z.ZodTypeAny, {
101
- file: string;
102
- frontmatter: Record<string, unknown> | null;
103
- language?: string | undefined;
104
- warnings?: string[] | undefined;
105
- }, {
106
- file: string;
107
- frontmatter: Record<string, unknown> | null;
108
- language?: string | undefined;
109
- warnings?: string[] | undefined;
110
- }>;
111
- export type CfmEntry = z.infer<typeof CfmEntrySchema>;
112
- /**
113
- * cfm_read 的返回结果
114
- */
115
- export interface ScanResult {
116
- /** 扫描到的总文件数 */
117
- total_files: number;
118
- /** 有 CFM 表头的文件数 */
119
- files_with_cfm: number;
120
- /** 无 CFM 表头的文件数 */
121
- files_without_cfm: number;
122
- /** 所有文件的 CFM 条目 */
123
- entries: CfmEntry[];
124
- }
125
- /**
126
- * cfm_search 的返回结果
127
- */
128
- export interface SearchResult {
129
- /** 搜索查询 */
130
- query: string;
131
- /** 匹配的文件数 */
132
- matches: number;
133
- /** 匹配的 CFM 条目 */
134
- entries: CfmEntry[];
135
- /** 解析错误的文件列表 */
136
- errors?: {
137
- file: string;
138
- message: string;
139
- }[];
140
- }
141
- //# sourceMappingURL=schema.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../src/schema.ts"],"names":[],"mappings":"AAcA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB;;;GAGG;AACH,eAAO,MAAM,kBAAkB;IAC3B,uBAAuB;;IAEvB,wBAAwB;;IAExB,kBAAkB;;IAElB,oCAAoC;;;;;;;;;;;;EAEtC,CAAC;AAEH,MAAM,MAAM,YAAY,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kBAAkB,CAAC,CAAC;AAE9D;;;GAGG;AACH,eAAO,MAAM,SAAS;IAElB,4CAA4C;;IAE5C,cAAc;;IAEd,yDAAyD;;IAIzD,WAAW;;IAEX,sBAAsB;;IAItB,YAAY;;IAEZ,eAAe;;IAEf,aAAa;;IAEb,mFAAmF;;IAEnF,cAAc;;;;;;;;;;;;;;;;;;;;;;;;EAEhB,CAAC;AAEH,MAAM,MAAM,OAAO,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,SAAS,CAAC,CAAC;AAEhD;;;GAGG;AACH,eAAO,MAAM,cAAc;;;;;;gCAIT,CAAC;AAEnB;;;GAGG;AACH,eAAO,MAAM,cAAc;IACvB,aAAa;;IAEb,eAAe;;IAEf,oBAAoB;;IAEpB,aAAa;;;;;;;;;;;;EAEf,CAAC;AAEH,MAAM,MAAM,QAAQ,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,cAAc,CAAC,CAAC;AAEtD;;GAEG;AACH,MAAM,WAAW,UAAU;IACvB,eAAe;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,mBAAmB;IACnB,cAAc,EAAE,MAAM,CAAC;IACvB,mBAAmB;IACnB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,mBAAmB;IACnB,OAAO,EAAE,QAAQ,EAAE,CAAC;CACvB;AAED;;GAEG;AACH,MAAM,WAAW,YAAY;IACzB,WAAW;IACX,KAAK,EAAE,MAAM,CAAC;IACd,aAAa;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,iBAAiB;IACjB,OAAO,EAAE,QAAQ,EAAE,CAAC;IACpB,gBAAgB;IAChB,MAAM,CAAC,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;CAChD"}
package/dist/schema.js DELETED
@@ -1,82 +0,0 @@
1
- /*---
2
- intent: 定义 CFM 表头的 Zod Schema 和相关交互接口类型定义
3
- role: model
4
- exports:
5
- - "CfmSchema: 严格校验 Schema"
6
- - "CfmSchemaLoose: 宽松校验 Schema"
7
- - "SearchResult: 包含匹配结果和解析错误信息的搜索结果类型"
8
- depends_on:
9
- - zod
10
- when_to_load: 修改 CFM 字段定义或搜索/读取结果结构时加载
11
- mutates_state: false
12
- domain: core
13
- ai_notes: SearchResult 新增 errors 字段,用于反馈解析失败的文件路径及原因。
14
- ---*/
15
- import { z } from "zod";
16
- /**
17
- * 语言注释规则 Schema
18
- * 定义某种编程语言的 CFM 注释语法
19
- */
20
- export const LanguageRuleSchema = z.object({
21
- /** 注释起始标记,如 "/*---" */
22
- comment_start: z.string(),
23
- /** 注释结束标记,如 "---*​/" */
24
- comment_end: z.string(),
25
- /** 该语言的文件扩展名列表 */
26
- extensions: z.array(z.string()),
27
- /** 行前缀(脚本语言使用),如 "# ",C 家族为 null */
28
- line_prefix: z.string().nullable(),
29
- });
30
- /**
31
- * CFM 表头严格 Schema(含全部必选字段)
32
- * 用于校验完整规范的表头
33
- */
34
- export const CfmSchema = z.object({
35
- // ---- 必选字段 ----
36
- /** 文件的核心用途和业务价值 (Be concise, < 50 words) */
37
- intent: z.string().max(500),
38
- /** 文件的角色类型 */
39
- role: z.string(),
40
- /** 暴露的关键 API / 函数 / 组件 (Signature: Brief description) */
41
- exports: z.array(z.string()),
42
- // ---- 推荐字段 ----
43
- /** 关键依赖 */
44
- depends_on: z.array(z.string()).optional(),
45
- /** 什么场景下才需要读取此文件全文 */
46
- when_to_load: z.string().optional(),
47
- // ---- 可选字段 ----
48
- /** 副作用描述 */
49
- side_effects: z.array(z.string()).optional(),
50
- /** 是否修改外部状态 */
51
- mutates_state: z.boolean().optional(),
52
- /** 业务领域标签 */
53
- domain: z.string().optional(),
54
- /** 给 AI 的特殊注意事项 (Critical constraints only. NO changelogs/history. Be concise!) */
55
- ai_notes: z.string().optional(),
56
- /** 表头规范版本号 */
57
- cfm_version: z.string().optional(),
58
- });
59
- /**
60
- * CFM 表头宽松 Schema(只要求 intent 字段)
61
- * 用于渐进式表头补充场景——已有表头但尚不完整的文件
62
- */
63
- export const CfmSchemaLoose = z
64
- .object({
65
- intent: z.string(),
66
- })
67
- .passthrough();
68
- /**
69
- * 单个文件的 CFM 条目
70
- * 包含文件路径和解析出的元数据
71
- */
72
- export const CfmEntrySchema = z.object({
73
- /** 文件相对路径 */
74
- file: z.string(),
75
- /** 检测到的编程语言 */
76
- language: z.string().optional(),
77
- /** 解析出的 CFM 表头数据 */
78
- frontmatter: z.record(z.unknown()).nullable(),
79
- /** 校验警告信息 */
80
- warnings: z.array(z.string()).optional(),
81
- });
82
- //# sourceMappingURL=schema.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"schema.js","sourceRoot":"","sources":["../src/schema.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;KAaK;AACL,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB;;;GAGG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,CAAC,MAAM,CAAC;IACvC,uBAAuB;IACvB,aAAa,EAAE,CAAC,CAAC,MAAM,EAAE;IACzB,wBAAwB;IACxB,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE;IACvB,kBAAkB;IAClB,UAAU,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC;IAC/B,oCAAoC;IACpC,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;CACrC,CAAC,CAAC;AAIH;;;GAGG;AACH,MAAM,CAAC,MAAM,SAAS,GAAG,CAAC,CAAC,MAAM,CAAC;IAC9B,iBAAiB;IACjB,4CAA4C;IAC5C,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC;IAC3B,cAAc;IACd,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE;IAChB,yDAAyD;IACzD,OAAO,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC;IAE5B,iBAAiB;IACjB,WAAW;IACX,UAAU,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,QAAQ,EAAE;IAC1C,sBAAsB;IACtB,YAAY,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAEnC,iBAAiB;IACjB,YAAY;IACZ,YAAY,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,QAAQ,EAAE;IAC5C,eAAe;IACf,aAAa,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE;IACrC,aAAa;IACb,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAC7B,mFAAmF;IACnF,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAC/B,cAAc;IACd,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;CACrC,CAAC,CAAC;AAIH;;;GAGG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC;KAC1B,MAAM,CAAC;IACJ,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE;CACrB,CAAC;KACD,WAAW,EAAE,CAAC;AAEnB;;;GAGG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,CAAC,MAAM,CAAC;IACnC,aAAa;IACb,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE;IAChB,eAAe;IACf,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAC/B,oBAAoB;IACpB,WAAW,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,QAAQ,EAAE;IAC7C,aAAa;IACb,QAAQ,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,QAAQ,EAAE;CAC3C,CAAC,CAAC"}
@@ -1,15 +0,0 @@
1
- import type { ScanResult } from "../schema.js";
2
- /**
3
- * 扫描目录中所有代码文件的 CFM 表头
4
- *
5
- * @param directory - 要扫描的根目录(绝对路径)
6
- * @param options - 扫描选项
7
- * @returns 扫描结果汇总(含所有文件的 CFM 条目)
8
- */
9
- export declare function scanDirectory(directory: string, options?: {
10
- /** 自定义忽略目录 */
11
- ignoreDirs?: string[];
12
- /** 是否只返回有 CFM 表头的文件 */
13
- cfmOnly?: boolean;
14
- }): Promise<ScanResult>;
15
- //# sourceMappingURL=read.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"read.d.ts","sourceRoot":"","sources":["../../src/tools/read.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAY,UAAU,EAAE,MAAM,cAAc,CAAC;AAiCzD;;;;;;GAMG;AACH,wBAAsB,aAAa,CAC/B,SAAS,EAAE,MAAM,EACjB,OAAO,GAAE;IACL,cAAc;IACd,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;IACtB,uBAAuB;IACvB,OAAO,CAAC,EAAE,OAAO,CAAC;CAChB,GACP,OAAO,CAAC,UAAU,CAAC,CAsBrB"}
@@ -1,97 +0,0 @@
1
- /*---
2
- intent: "实现 cfm_read 工具:递归扫描目录下所有代码文件,提取 CFM 表头,返回汇总索引"
3
- role: service
4
- exports:
5
- - "scanDirectory: 扫描指定目录,返回所有文件的 CFM 表头索引"
6
- depends_on: ["../parser.ts", "../registry.ts", "../schema.ts"]
7
- when_to_load: "修改文件扫描逻辑、过滤规则或结果格式时加载"
8
- ai_notes: "默认跳过 node_modules, .git, dist 等常见非源码目录"
9
- ---*/
10
- import { readdir, stat } from "node:fs/promises";
11
- import { join, relative, extname } from "node:path";
12
- import { extractFrontmatter } from "../parser.js";
13
- import { getLanguageByExtension } from "../registry.js";
14
- /** 默认跳过的目录名 */
15
- const DEFAULT_IGNORE_DIRS = new Set([
16
- "node_modules",
17
- ".git",
18
- ".svn",
19
- ".hg",
20
- "dist",
21
- "build",
22
- "out",
23
- ".next",
24
- ".nuxt",
25
- "__pycache__",
26
- ".pytest_cache",
27
- "venv",
28
- ".venv",
29
- "target",
30
- "vendor",
31
- ".idea",
32
- ".vscode",
33
- "coverage",
34
- ]);
35
- /** 默认跳过的文件名 */
36
- const DEFAULT_IGNORE_FILES = new Set([
37
- ".DS_Store",
38
- "Thumbs.db",
39
- "package-lock.json",
40
- "yarn.lock",
41
- "pnpm-lock.yaml",
42
- ]);
43
- /**
44
- * 扫描目录中所有代码文件的 CFM 表头
45
- *
46
- * @param directory - 要扫描的根目录(绝对路径)
47
- * @param options - 扫描选项
48
- * @returns 扫描结果汇总(含所有文件的 CFM 条目)
49
- */
50
- export async function scanDirectory(directory, options = {}) {
51
- const ignoreDirs = new Set([
52
- ...DEFAULT_IGNORE_DIRS,
53
- ...(options.ignoreDirs ?? []),
54
- ]);
55
- const entries = [];
56
- // 递归遍历
57
- await walkDirectory(directory, directory, ignoreDirs, entries);
58
- // 按选项过滤
59
- const filteredEntries = options.cfmOnly
60
- ? entries.filter((e) => e.frontmatter !== null)
61
- : entries;
62
- return {
63
- total_files: entries.length,
64
- files_with_cfm: entries.filter((e) => e.frontmatter !== null).length,
65
- files_without_cfm: entries.filter((e) => e.frontmatter === null).length,
66
- entries: filteredEntries,
67
- };
68
- }
69
- /**
70
- * 递归遍历目录
71
- */
72
- async function walkDirectory(rootDir, currentDir, ignoreDirs, entries) {
73
- const items = await readdir(currentDir);
74
- for (const item of items) {
75
- const fullPath = join(currentDir, item);
76
- // 跳过被忽略的文件
77
- if (DEFAULT_IGNORE_FILES.has(item))
78
- continue;
79
- const itemStat = await stat(fullPath);
80
- if (itemStat.isDirectory()) {
81
- // 跳过被忽略的目录
82
- if (ignoreDirs.has(item))
83
- continue;
84
- await walkDirectory(rootDir, fullPath, ignoreDirs, entries);
85
- }
86
- else if (itemStat.isFile()) {
87
- const ext = extname(item);
88
- // 只处理已注册语言的文件
89
- if (!getLanguageByExtension(ext))
90
- continue;
91
- const relativePath = relative(rootDir, fullPath).replace(/\\/g, "/");
92
- const entry = await extractFrontmatter(fullPath, relativePath);
93
- entries.push(entry);
94
- }
95
- }
96
- }
97
- //# sourceMappingURL=read.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"read.js","sourceRoot":"","sources":["../../src/tools/read.ts"],"names":[],"mappings":"AAAA;;;;;;;;KAQK;AAEL,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AACjD,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpD,OAAO,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AAClD,OAAO,EAAE,sBAAsB,EAAE,MAAM,gBAAgB,CAAC;AAGxD,eAAe;AACf,MAAM,mBAAmB,GAAG,IAAI,GAAG,CAAC;IAChC,cAAc;IACd,MAAM;IACN,MAAM;IACN,KAAK;IACL,MAAM;IACN,OAAO;IACP,KAAK;IACL,OAAO;IACP,OAAO;IACP,aAAa;IACb,eAAe;IACf,MAAM;IACN,OAAO;IACP,QAAQ;IACR,QAAQ;IACR,OAAO;IACP,SAAS;IACT,UAAU;CACb,CAAC,CAAC;AAEH,eAAe;AACf,MAAM,oBAAoB,GAAG,IAAI,GAAG,CAAC;IACjC,WAAW;IACX,WAAW;IACX,mBAAmB;IACnB,WAAW;IACX,gBAAgB;CACnB,CAAC,CAAC;AAEH;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CAC/B,SAAiB,EACjB,UAKI,EAAE;IAEN,MAAM,UAAU,GAAG,IAAI,GAAG,CAAC;QACvB,GAAG,mBAAmB;QACtB,GAAG,CAAC,OAAO,CAAC,UAAU,IAAI,EAAE,CAAC;KAChC,CAAC,CAAC;IAEH,MAAM,OAAO,GAAe,EAAE,CAAC;IAE/B,OAAO;IACP,MAAM,aAAa,CAAC,SAAS,EAAE,SAAS,EAAE,UAAU,EAAE,OAAO,CAAC,CAAC;IAE/D,QAAQ;IACR,MAAM,eAAe,GAAG,OAAO,CAAC,OAAO;QACnC,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,KAAK,IAAI,CAAC;QAC/C,CAAC,CAAC,OAAO,CAAC;IAEd,OAAO;QACH,WAAW,EAAE,OAAO,CAAC,MAAM;QAC3B,cAAc,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,KAAK,IAAI,CAAC,CAAC,MAAM;QACpE,iBAAiB,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,KAAK,IAAI,CAAC,CAAC,MAAM;QACvE,OAAO,EAAE,eAAe;KAC3B,CAAC;AACN,CAAC;AAED;;GAEG;AACH,KAAK,UAAU,aAAa,CACxB,OAAe,EACf,UAAkB,EAClB,UAAuB,EACvB,OAAmB;IAEnB,MAAM,KAAK,GAAG,MAAM,OAAO,CAAC,UAAU,CAAC,CAAC;IAExC,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACvB,MAAM,QAAQ,GAAG,IAAI,CAAC,UAAU,EAAE,IAAI,CAAC,CAAC;QAExC,WAAW;QACX,IAAI,oBAAoB,CAAC,GAAG,CAAC,IAAI,CAAC;YAAE,SAAS;QAE7C,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,CAAC;QAEtC,IAAI,QAAQ,CAAC,WAAW,EAAE,EAAE,CAAC;YACzB,WAAW;YACX,IAAI,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC;gBAAE,SAAS;YACnC,MAAM,aAAa,CAAC,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAE,OAAO,CAAC,CAAC;QAChE,CAAC;aAAM,IAAI,QAAQ,CAAC,MAAM,EAAE,EAAE,CAAC;YAC3B,MAAM,GAAG,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;YAE1B,cAAc;YACd,IAAI,CAAC,sBAAsB,CAAC,GAAG,CAAC;gBAAE,SAAS;YAE3C,MAAM,YAAY,GAAG,QAAQ,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;YACrE,MAAM,KAAK,GAAG,MAAM,kBAAkB,CAAC,QAAQ,EAAE,YAAY,CAAC,CAAC;YAC/D,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACxB,CAAC;IACL,CAAC;AACL,CAAC"}
@@ -1,25 +0,0 @@
1
- /**
2
- * 注册新语言的返回结果
3
- */
4
- export interface RegisterResult {
5
- /** 是否注册成功 */
6
- success: boolean;
7
- /** 结果消息 */
8
- message: string;
9
- /** 注册后的总语言数 */
10
- total_languages?: number;
11
- }
12
- /**
13
- * 校验输入参数并注册新语言
14
- *
15
- * @param name - 语言名称(如 "elixir")
16
- * @param config - 注释规则配置
17
- * @returns 注册结果
18
- */
19
- export declare function registerNewLanguage(name: string, config: {
20
- comment_start: string;
21
- comment_end: string;
22
- extensions: string[];
23
- line_prefix?: string | null;
24
- }): RegisterResult;
25
- //# sourceMappingURL=register.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"register.d.ts","sourceRoot":"","sources":["../../src/tools/register.ts"],"names":[],"mappings":"AAgBA;;GAEG;AACH,MAAM,WAAW,cAAc;IAC3B,aAAa;IACb,OAAO,EAAE,OAAO,CAAC;IACjB,WAAW;IACX,OAAO,EAAE,MAAM,CAAC;IAChB,eAAe;IACf,eAAe,CAAC,EAAE,MAAM,CAAC;CAC5B;AAED;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CAC/B,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE;IACJ,aAAa,EAAE,MAAM,CAAC;IACtB,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC/B,GACF,cAAc,CAoDhB"}
@@ -1,71 +0,0 @@
1
- /*---
2
- intent: 实现 cfm_register_language 工具:允许运行时动态、智能地注册新语言支持
3
- role: service
4
- exports:
5
- - "registerNewLanguage: 校验并自动补全扩展名点号后注册新语言"
6
- depends_on:
7
- - ../registry.js
8
- - ../schema.js
9
- when_to_load: 修改语言注册接口或参数校验逻辑时加载
10
- mutates_state: false
11
- domain: registry
12
- ai_notes: 扩展名注册已实现自动规范化:用户传入 "js" 会自动补全为 ".js"。
13
- ---*/
14
- import { registerLanguage, getAllLanguages } from "../registry.js";
15
- /**
16
- * 校验输入参数并注册新语言
17
- *
18
- * @param name - 语言名称(如 "elixir")
19
- * @param config - 注释规则配置
20
- * @returns 注册结果
21
- */
22
- export function registerNewLanguage(name, config) {
23
- // 参数校验
24
- if (!name || name.trim().length === 0) {
25
- return {
26
- success: false,
27
- message: "语言名称不能为空",
28
- };
29
- }
30
- if (!config.comment_start || !config.comment_end) {
31
- return {
32
- success: false,
33
- message: "comment_start 和 comment_end 不能为空",
34
- };
35
- }
36
- if (!config.extensions || config.extensions.length === 0) {
37
- return {
38
- success: false,
39
- message: "extensions 不能为空,至少需要一个文件扩展名",
40
- };
41
- }
42
- // 校验并规范化扩展名格式
43
- const normalizedExtensions = config.extensions.map((ext) => {
44
- if (ext.startsWith("."))
45
- return ext;
46
- return `.${ext}`;
47
- });
48
- // 构造语言规则
49
- const rule = {
50
- comment_start: config.comment_start,
51
- comment_end: config.comment_end,
52
- extensions: normalizedExtensions,
53
- line_prefix: config.line_prefix ?? null,
54
- };
55
- try {
56
- registerLanguage(name, rule);
57
- const allLanguages = getAllLanguages();
58
- return {
59
- success: true,
60
- message: `语言 "${name}" 注册成功(扩展名: ${normalizedExtensions.join(", ")})`,
61
- total_languages: Object.keys(allLanguages).length,
62
- };
63
- }
64
- catch (error) {
65
- return {
66
- success: false,
67
- message: error.message,
68
- };
69
- }
70
- }
71
- //# sourceMappingURL=register.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"register.js","sourceRoot":"","sources":["../../src/tools/register.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;KAYK;AACL,OAAO,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAenE;;;;;;GAMG;AACH,MAAM,UAAU,mBAAmB,CAC/B,IAAY,EACZ,MAKC;IAED,OAAO;IACP,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACpC,OAAO;YACH,OAAO,EAAE,KAAK;YACd,OAAO,EAAE,UAAU;SACtB,CAAC;IACN,CAAC;IAED,IAAI,CAAC,MAAM,CAAC,aAAa,IAAI,CAAC,MAAM,CAAC,WAAW,EAAE,CAAC;QAC/C,OAAO;YACH,OAAO,EAAE,KAAK;YACd,OAAO,EAAE,kCAAkC;SAC9C,CAAC;IACN,CAAC;IAED,IAAI,CAAC,MAAM,CAAC,UAAU,IAAI,MAAM,CAAC,UAAU,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACvD,OAAO;YACH,OAAO,EAAE,KAAK;YACd,OAAO,EAAE,6BAA6B;SACzC,CAAC;IACN,CAAC;IAED,cAAc;IACd,MAAM,oBAAoB,GAAG,MAAM,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE;QACvD,IAAI,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC;YAAE,OAAO,GAAG,CAAC;QACpC,OAAO,IAAI,GAAG,EAAE,CAAC;IACrB,CAAC,CAAC,CAAC;IAEH,SAAS;IACT,MAAM,IAAI,GAAiB;QACvB,aAAa,EAAE,MAAM,CAAC,aAAa;QACnC,WAAW,EAAE,MAAM,CAAC,WAAW;QAC/B,UAAU,EAAE,oBAAoB;QAChC,WAAW,EAAE,MAAM,CAAC,WAAW,IAAI,IAAI;KAC1C,CAAC;IAEF,IAAI,CAAC;QACD,gBAAgB,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;QAE7B,MAAM,YAAY,GAAG,eAAe,EAAE,CAAC;QACvC,OAAO;YACH,OAAO,EAAE,IAAI;YACb,OAAO,EAAE,OAAO,IAAI,eAAe,oBAAoB,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG;YACrE,eAAe,EAAE,MAAM,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,MAAM;SACpD,CAAC;IACN,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACb,OAAO;YACH,OAAO,EAAE,KAAK;YACd,OAAO,EAAG,KAAe,CAAC,OAAO;SACpC,CAAC;IACN,CAAC;AACL,CAAC"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"scan.d.ts","sourceRoot":"","sources":["../../src/tools/scan.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAY,UAAU,EAAE,MAAM,cAAc,CAAC;AAiCzD;;;;;;GAMG;AACH,wBAAsB,aAAa,CAC/B,SAAS,EAAE,MAAM,EACjB,OAAO,GAAE;IACL,cAAc;IACd,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;IACtB,uBAAuB;IACvB,OAAO,CAAC,EAAE,OAAO,CAAC;CAChB,GACP,OAAO,CAAC,UAAU,CAAC,CAsBrB"}
@@ -1,22 +0,0 @@
1
- import type { SearchResult } from "../schema.js";
2
- /**
3
- * 在项目目录中搜索匹配条件的 CFM 表头
4
- *
5
- * 支持三种搜索维度:
6
- * - keyword: 在 intent、exports、ai_notes 等文本字段中全文搜索
7
- * - role: 精确匹配文件角色(如 "service", "component")
8
- * - domain: 精确匹配业务领域标签
9
- *
10
- * @param directory - 扫描的根目录
11
- * @param query - 搜索条件
12
- * @returns 搜索结果
13
- */
14
- export declare function searchFrontmatter(directory: string, query: {
15
- /** 关键字搜索(在 intent、exports、ai_notes 等字段中匹配) */
16
- keyword?: string;
17
- /** 按角色过滤 */
18
- role?: string;
19
- /** 按业务领域过滤 */
20
- domain?: string;
21
- }): Promise<SearchResult>;
22
- //# sourceMappingURL=search.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"search.d.ts","sourceRoot":"","sources":["../../src/tools/search.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAY,YAAY,EAAE,MAAM,cAAc,CAAC;AAE3D;;;;;;;;;;;GAWG;AACH,wBAAsB,iBAAiB,CACnC,SAAS,EAAE,MAAM,EACjB,KAAK,EAAE;IACH,8CAA8C;IAC9C,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,YAAY;IACZ,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,cAAc;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;CACnB,GACF,OAAO,CAAC,YAAY,CAAC,CAoCvB"}