更安全的建筑结构
具有确定性CI的全项目类型Script架构分析
门和活编辑诊断。 它造了一个真正的 ts.Program,生成
并报告结构结果——周期,
层层违规、公共地表面积过大、边界漏出
每一个压制都有书面的、可审计的理由.
为什么这个不是ESLint规则? 整个项目分析没有
适合每个文件的插图模型, 而每个键弦的再分析不符合 CI
工具。 这个软件包在两个表面后面运行一个温暖分析核心:a
check 命令其退出代码 CI 可以信任, 以及语言服务器
将相同的发现流入您的编辑器的诊断通道中, 或
您的编码代理 —— 已经读取 。 引入循环的代理
写作时的诊断 和逃生舱是一条线 它必须
理由:内含可查询豁免分类账的反馈回路是:
那个楔子.
现状:0.x. 规则heuristics是年轻的;期望配置. 见"0.x稳定" 政策变化 变动情况。 。 。 .
两分钟后CI
npm install --save-dev @chughtapan/safer-architecture-lsp
npx safer-architecture-lsp check .
check 一次分析工程并退出 0 (干净), 1 (调查结果),
或者说 2 (无法分析——坏根,无效配置,无法使用)
t. 它总是打印一个摘要行,所以一个空的结果是
可区别于从未发生的跑道:
safer-architecture check: 0 finding(s) across 0 file(s), 4 waiver(s), 1 project(s), options from file — /repo
--json 发布合并报告(项目、诊断、豁免和
用于机器消费的确定性分析快照; --waivers
打印带有理由的压制分类账.
check 撰写持续报告到
node_modules/.cache/safer-architecture-lsp/键入内容
水印上的项目来源, package.json,以及 tsconfigA级
在不变的工程上重复运行, 而不是重建
ts.Program这样 在 CI 中缓存目录 摊还冷钱.
对于单体,添加一个明示 safer-architecture.workspace.json 时间
root根. 路径是字面和相对的——没有隐含的发现
或缩放:
{ "packages": ["packages/api", "packages/web"] }
每个列出的目录必须存在,并有一个独特的,非空的 package.json
名称。 CLI 和 LSP 用自己的配置/ cache 分析每个软件包, 合并
,并拒绝运行时间/同级依赖周期。 无效的显示块
工作空间响亮.
编辑器/代理设置
这个 serve 子命令在 stdio 上说 LSP :
// Claude Code plugin.json
{
"lspServers": {
"safer-architecture": {
"command": "safer-architecture-lsp",
"args": ["serve"],
"extensionToLanguage": { ".ts": "typescript", ".tsx": "typescriptreact" }
}
}
}
任何stdio LSP客户端都一样工作(command: safer-architecture-lsp, (中文(简体) ),
args: ["serve"]) (中文(简体) ). 诊断材料为: 每个 分析
文件,不仅仅是打开的,每个发现深层链接它的规则
参考文献。 一个文件扩展名不能运行两个服务器的主机可以
用捆绑的服务器在前面 safer-lsp-proxy 多轴
并行 typescript-language-server: 其配置中的第一个后端
车尾撞车从不把车头撞倒.
见 LSP 服务器指南 为工作空间的发现,
诊断寿命周期, 和撕裂行为.
验证它是否还活着: Stderr 记录每条工作空间注册一条线
每个出版物(published N finding(s) across M file(s) … in Xms) (中文(简体) ).
配置
打开 safer-architecture.config.json 项目根( 每个列出的软件包)
在明确的工作空间中有自己的文件)。 它被设定为无效
文件创建 check 退出时无需分析和表面作为错误诊断
编辑器,默认情况下在修复时会提供诊断.
编辑热重装受影响的项目 。 你会先摸到的把手:
{
// Third-party types intentionally part of your public API:
"publicTypePackages": [
{ "package": "typescript", "reason": "our contract is ts.Program-shaped" }
],
// Folders siblings may import freely (your shared kernel):
"sharedFolderNames": [
{ "folder": "analyzer", "reason": "one analysis core, many surfaces" }
],
// Deliberate non-index facade files:
"facadeFiles": [
{ "file": "server/workspace-engine.ts", "reason": "engine contract" }
],
// Public-surface budgets (defaults shown):
"maxPublicExports": 20,
"maxSubpathExports": 5
}
每个津贴条目都要求 reason - 写下来 实值 页:1
建筑决定。 完整选项列表存在于
文件/规则.md,逐条绘制到选项
来控制它 这个仓库是自己的
(原始内容存档于2017-10-21) (英语). afer-architecture. config.json 是一个
实例: CI 运行 check . 在此编码库上, 并失败于任意
无所求取.
CUPID 域执行
域名执行是选入和严格一次 domains 不为空 :
{
"domains": [{
"name": "orders",
"roots": ["src/orders"],
"entrypoints": ["src/orders/index.ts"],
"reason": "owns the order lifecycle"
}],
"domainOwnership": [{
"path": "src/legacy-orders",
"domain": "orders",
"reason": "migration ownership is explicit"
}],
"compositionRoots": [{
"path": "src/bootstrap.ts",
"reason": "application wiring edge"
}]
}
生产模块必须拥有一个推断的域根,一个显式 所有权覆盖,或带有理由的构成根。 跨域进口 (一) 目标目的地入口 仅副作用的跨域进口仅限于成分根. 见 CUPID 执行。 。 。 .
规则
完整的参考文献——每个规则的旗帜,为什么,其控制 选项,以及如何加以补救——是 文件/规则.md。 。 。 . 类别:进口地貌(循环、分层、兄弟区),公共 表面(校准、大小预算、供应商类型的泄漏),文件夹形状 (大小、README、明确的API)和模块形状(偶发) 边际,小间接,胖管弦乐.
禁止(放弃)
一个评论行, 文件范围, 理由强制 :
// safer-arch-ignore no-trivial-sink-file: deliberate seam; the overlay follow-up grows here.
缺失或空出的原因本身就是诊断. 给予的豁免是:
保留的理由和可查询性 check --waivers - 一个
可审计的分类账,而不是一个沉默的警告。 未知的规则 ID 错误 。 这个
遗留的双行 @agent-code-guard/architecture-exception 标记从
这个代码的前世从未被尊崇过 总是犯错误
僵化的压制不能无声地停止工作.
程序化 API
import {
analyzeResolvedArchitecture,
resolveArchitectureOptions,
} from "@chughtapan/safer-architecture-lsp";
const options = resolveArchitectureOptions({ projectRoot: process.cwd() });
const report = analyzeResolvedArchitecture(options);
for (const d of report.diagnostics) console.log(d.ruleId, d.file, d.message);
for (const w of report.waivers) console.log("waived", w.ruleId, w.reason);
出口报告类型包括确定性分析快照和 导出选项类型包括域定义、所有权覆盖和 输入配置构建器的构成根 .
范围和限制(通过前阅读)
- 模块边缘使用 TypeScript 的缓存解析器, 包括
paths软件包imports别名。 工作空间软件包的地理学来自已声明的运行时间和 相对依赖关系;交叉包装源/项目参考进口仍保留 范围为每个软件包的 TypeScript 项目. - 分析是在编辑器中节省时间;活键中键级诊断 是一个后续行动.
- 在工作空间根上方找到的 tsconfig 范围为 工作空间的文件自动.
解决问题
- 完全没有诊断? 检查斯德尔。 失踪/ 断开的tsconfig 现在
表面为
architecture-analysis-unavailable错误诊断 - 如果你从字面上看什么都没有, 你的客户端是没有联系的(serve从参数中缺失是常见的原因; 光引用指纹帮助 和出口而不是绞刑). - 配置文件 Stderr / squiggle 中的“ 配置 INVALID ” - 那个 JSON 失败了计划验证; 信件中指定了违法的密钥 .
- 编辑后发现就消失了? 引擎热重装上你
新配置; 运行
check --waivers看看被压制的东西.
发展
npm install
npm run build # tsc → dist/
npm test # vitest: analyzer fixtures, CLI contract, proxy, full LSP session
npm run test:coverage # c8 ratchet + per-directory floors; runs pre-push, not in CI
npm run lint # eslint (agent-code-guard policy) + knip
node dist/server/index.js check . # the dogfood gate CI enforces
Coverage runs pre-push, not in CI: c8 slows the process-spawning suites enough
to push the slowest property test past vitest's timeout on CI hardware. `npm
install` wires the hook up through husky, so there is nothing to install by
hand. Bypass it with `SKIP_COVERAGE=1 git push`.
husky takes over `core.hooksPath`, so anything already in `.git/hooks/pre-push`
would stop running; `.husky/pre-push` chains it explicitly.
出版:推出一个 vX.Y.Z 标签匹配 package.json - 出版物
工作流程构建、测试、指针、自查,然后通过npm发布
值得信赖的出版.