关于 coinagerie-configure
coinagerie-configure 用于编写 coinagerie 的词语扫描配置,涵盖文件筛选、排除规则、词形归并和词汇表输出,并提供严格校验与命令行覆盖。
主要功能
- 01配置扫描路径和排除项
- 02将词语归并为词头
- 03输出 Markdown 或 JSON 词汇表
- 04严格校验配置字段
- 05通过命令行标志覆盖字段
适用场景
- 01为文件夹设置词汇表生成
- 02排除语言关键字或项目术语
- 03在多个文件夹间共享基础设置
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ organizzolini/ codebase --skill coinagerie-configure安装后在 Claude Code 中输入/coinagerie-configure确认已加载。
详细介绍
编写 coinagerie 配置
配置是在 coinagerie.config.ts(或 .mts、.cts、.js、.mjs、.cjs)中默认导出的一个普通对象,由 jiti 加载,因此 TypeScript 可用,任意字段也可以动态计算。所有字段均为可选项,完全没有配置文件也有效:此时运行会扫描工作目录并输出结果。
每一层的架构都严格校验。拼错键名会导致运行失败,并指出文件名,而不会被忽略。导出函数会被拒绝。
import { typescriptKeywords } from "@coinagerie/languages";
import type { CoinagerieConfiguration } from "@coinagerie/configuration";
export default {
include: ["src/**", "scripts/**"],
exclude: {
paths: ["**/*.test.ts", "**/generated/**", "coinagerie.config.ts"],
words: [...typescriptKeywords, "src", "index"],
},
fold: (word) => (word === "configuration" ? "configure" : word),
outputs: [
{
description: "Words this project uses. Regenerate with `coinagerie --write`.",
path: "README.md",
type: "markdown",
},
],
} satisfies CoinagerieConfiguration;
类型导入是可选的,加载时会被擦除。@coinagerie/languages 必须安装在配置文件旁边:无法解析导入时,运行会以“Cannot find module”失败。
文件夹就是根目录
所有路径和 glob 都相对于配置文件所在的文件夹,该文件夹也是运行时的扫描根目录。共享基础配置中写入的路径,会相对于已加载配置文件所在的文件夹解析,而不是相对于基础配置文件所在的文件夹。
include默认为所有文件,包括点文件。glob 使用path.matchesGlob匹配,其中*和**永远不会匹配以点开头的名称:自定义include必须明确写出.github/**及类似路径。exclude.paths接受 glob。匹配到文件夹的 glob 会排除整个文件夹。glob 从被扫描文件夹开始匹配,因此["dist"]只会排除顶层的dist;要在任意层级排除它,请写**/dist。- 除上述规则外,还会遵循
.gitignore:从仓库根目录(最近的、包含.git的祖先目录)开始,逐级读取所有.gitignore,也包括否定规则。 - 永远不会扫描词汇表的目标文件,但会扫描配置文件:配置文件自身的键会成为词语。可按路径排除该文件,也可以接受这些词语。
exclude.words
可以是词语列表,也可以是返回词语列表的同步或异步函数。配置读取其他文件、上级词汇表或 JSON 文件时,应在该函数中执行,因为 coinagerie 本身不会读取其他词汇表:
import { readFile } from "node:fs/promises";
import path from "node:path";
const parentWords = async (): Promise<string[]> =>
Object.keys(
JSON.parse(await readFile(path.join(__dirname, "../glossary.json"), "utf8")),
);
export default { exclude: { words: parentWords } };
- 默认不会排除任何内容,甚至包括语言关键字。将
@coinagerie/languages导出的列表展开为普通数组:typescriptKeywords、pythonKeywords、sqlKeywords、shellKeywords、cssKeywords、hclKeywords、tomlKeywords、jsonKeywords、yamlKeywords。 - 排除操作在折叠之后执行,每个条目都会小写,并按照代码中词语的方式进行折叠:排除
service也会覆盖services,排除implements也会覆盖它折叠成的implement。 - 每个条目都是一个词语,不会拆分,因此
"fooBar"不会排除foo或bar;请分别列出。 - 被排除的词语会从词汇表中移除,下一次
--write会删除其释义。排除一个词语的原因应是它本身没有意义,而不是因为它缺少释义。
fold
fold(word) => headword 会合并词形还原器未能合并的词语,或修正其错误处理的词头。它在复数和词形变化折叠之后运行,因此接收的是词元,其结果就是最终词头。
fold: (word) =>
({ configuration: "configure", set: "setting" })[word] ?? word,
它必须是同步函数,并返回不含空白字符或 * 的非空字符串。若发生异常、结果为空或不是字符串,或返回 Promise,运行都会失败并指出配置文件名。
outputs
目标的数组。不指定目标时,运行只会打印结果,--check 和
--write 会拒绝运行。
| 目标 | 内容 |
|---|---|
{ type: "markdown", path, description? } | coinagerie:start 和 coinagerie:end 锚点之间的区块 |
{ type: "json", path } | 整个文件,按单词排序的扁平对象 |
- 如果 Markdown 文件不存在,就会创建;如果文件还没有锚点,区块会追加到文件末尾。因此,可以指定 README 来添加一个章节,也可以指定单独的文件。
description是标题下的自由文本。其中不能包含列表项(-、*、+)或 HTML 注释行,否则会被解析为术语表条目。未配置时,会保留第一条项目符号上方已有的文本。- 同一文件不能指定两个目标。
- 每个目标都会单独处理。JSON 术语表和 Markdown 术语表之间不会复制定义,因此每个作用域只能指定一个权威目标。
为多个文件夹使用同一份基础配置
将共享选项放入一个模块,然后通过展开来复用;每个文件夹的文件只需添加不同之处。展开是浅层的,因此覆盖 exclude 会替换其中的全部内容:
import base from "../coinagerie.base";
export default {
...base,
exclude: { ...base.exclude, paths: [...(base.exclude?.paths ?? []), "fixtures"] },
outputs: [{ path: "README.md", type: "markdown" }],
};
当文件夹的 exclude.words 读取父级术语表时,由父级决定子级无需定义哪些内容。一个词条如果从父级移除,就会在所有排除了它的子级中重新变为缺失;将其定义下移是一项有意为之的修改。在 Nx 中,将父级术语表声明为每个子级目标的输入,否则修改该术语表不会触发子级检查重新运行。
编辑前先试运行
除 exclude.words 和 fold 外,每个字段都有一个命令行标志,可在单次运行中替换该字段:--include、--exclude-paths、--output-json、--output-markdown、--description。coinagerie-collect 技能中提供了相关表格。直接运行 coinagerie 会打印修改结果,但不会写入任何内容。
运行因配置被拒绝时
| 症状 | 原因和修复 |
|---|---|
expected object, received function | 文件导出的是函数;请改为导出普通对象 |
Unrecognized key: "<name>" | 字段拼写错误或位置错误;请修正键名 |
Invalid input at exclude.words | 其中的内容既不是列表,也不是函数 |
fold must return a non-empty string... | 函数返回了 ""、空格、*、Promise 或非字符串 |
exclude.words boom | 函数抛出了错误;错误信息中包含配置文件的路径 |
Cannot find module | 请将软件包安装在配置文件所在目录 |
Two outputs name a.json | 请为每个目标指定独立文件 |
A description may not hold a list item... | 描述中包含 -、*、+ 或 <!-- 行;请重新措辞 |
fold threw on "<word>" | fold 函数执行出错;请修正其对该词的处理 |
Configuration file not found | 指定的 --config 路径是相对于工作目录的 |
如果检查失败而非配置被拒绝,请参阅 coinagerie-triage 技能了解如何处理。