@stsepelin/checktrail 0.1.0-alpha.1

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.
Files changed (385) hide show
  1. package/CONTRIBUTING.md +42 -0
  2. package/LICENSE +21 -0
  3. package/README.md +355 -0
  4. package/SECURITY.md +46 -0
  5. package/dist/src/actionlint-evidence.d.ts +2 -0
  6. package/dist/src/actionlint-evidence.js +166 -0
  7. package/dist/src/actionlint-inputs.d.ts +5 -0
  8. package/dist/src/actionlint-inputs.js +123 -0
  9. package/dist/src/actionlint-runner.d.ts +1 -0
  10. package/dist/src/actionlint-runner.js +122 -0
  11. package/dist/src/actionlint.d.ts +19 -0
  12. package/dist/src/actionlint.js +80 -0
  13. package/dist/src/adapters.d.ts +49 -0
  14. package/dist/src/adapters.js +430 -0
  15. package/dist/src/architecture.d.ts +107 -0
  16. package/dist/src/architecture.js +230 -0
  17. package/dist/src/clang-evidence.d.ts +2 -0
  18. package/dist/src/clang-evidence.js +194 -0
  19. package/dist/src/clang-protocol.d.ts +3 -0
  20. package/dist/src/clang-protocol.js +25 -0
  21. package/dist/src/clang-runner.d.ts +1 -0
  22. package/dist/src/clang-runner.js +159 -0
  23. package/dist/src/clang.d.ts +44 -0
  24. package/dist/src/clang.js +197 -0
  25. package/dist/src/cli.d.ts +2 -0
  26. package/dist/src/cli.js +338 -0
  27. package/dist/src/config.d.ts +33 -0
  28. package/dist/src/config.js +140 -0
  29. package/dist/src/contract-schema.d.ts +85 -0
  30. package/dist/src/contract-schema.js +56 -0
  31. package/dist/src/contract-worker.d.ts +1 -0
  32. package/dist/src/contract-worker.js +123 -0
  33. package/dist/src/contracts.d.ts +22 -0
  34. package/dist/src/contracts.js +123 -0
  35. package/dist/src/django-evidence.d.ts +2 -0
  36. package/dist/src/django-evidence.js +100 -0
  37. package/dist/src/django-runner.d.ts +1 -0
  38. package/dist/src/django-runner.js +80 -0
  39. package/dist/src/django.d.ts +9 -0
  40. package/dist/src/django.js +50 -0
  41. package/dist/src/dotnet-compiler.d.ts +1 -0
  42. package/dist/src/dotnet-compiler.js +87 -0
  43. package/dist/src/dotnet-evidence.d.ts +2 -0
  44. package/dist/src/dotnet-evidence.js +127 -0
  45. package/dist/src/dotnet-runner.d.ts +1 -0
  46. package/dist/src/dotnet-runner.js +167 -0
  47. package/dist/src/dotnet.d.ts +65 -0
  48. package/dist/src/dotnet.js +120 -0
  49. package/dist/src/engine.d.ts +19 -0
  50. package/dist/src/engine.js +239 -0
  51. package/dist/src/environment.d.ts +6 -0
  52. package/dist/src/environment.js +36 -0
  53. package/dist/src/eslint-evidence.d.ts +2 -0
  54. package/dist/src/eslint-evidence.js +98 -0
  55. package/dist/src/eslint-runner.d.ts +1 -0
  56. package/dist/src/eslint-runner.js +61 -0
  57. package/dist/src/eslint.d.ts +2 -0
  58. package/dist/src/eslint.js +40 -0
  59. package/dist/src/evidence.d.ts +2 -0
  60. package/dist/src/evidence.js +313 -0
  61. package/dist/src/external-adapter.d.ts +164 -0
  62. package/dist/src/external-adapter.js +265 -0
  63. package/dist/src/external-evidence.d.ts +2 -0
  64. package/dist/src/external-evidence.js +127 -0
  65. package/dist/src/external-runner.d.ts +1 -0
  66. package/dist/src/external-runner.js +122 -0
  67. package/dist/src/fastapi-evidence.d.ts +2 -0
  68. package/dist/src/fastapi-evidence.js +126 -0
  69. package/dist/src/fastapi-runner.d.ts +1 -0
  70. package/dist/src/fastapi-runner.js +84 -0
  71. package/dist/src/fastapi.d.ts +10 -0
  72. package/dist/src/fastapi.js +52 -0
  73. package/dist/src/fetch-pack.d.ts +16 -0
  74. package/dist/src/fetch-pack.js +154 -0
  75. package/dist/src/finding-policy-schema.d.ts +146 -0
  76. package/dist/src/finding-policy-schema.js +70 -0
  77. package/dist/src/finding-policy.d.ts +62 -0
  78. package/dist/src/finding-policy.js +206 -0
  79. package/dist/src/git-selection.d.ts +3 -0
  80. package/dist/src/git-selection.js +229 -0
  81. package/dist/src/go-directives.d.ts +1 -0
  82. package/dist/src/go-directives.js +32 -0
  83. package/dist/src/go-scope.d.ts +11 -0
  84. package/dist/src/go-scope.js +122 -0
  85. package/dist/src/golangci-evidence.d.ts +2 -0
  86. package/dist/src/golangci-evidence.js +92 -0
  87. package/dist/src/golangci-runner.d.ts +1 -0
  88. package/dist/src/golangci-runner.js +124 -0
  89. package/dist/src/golangci.d.ts +2 -0
  90. package/dist/src/golangci.js +35 -0
  91. package/dist/src/guidance.d.ts +98 -0
  92. package/dist/src/guidance.js +247 -0
  93. package/dist/src/index.d.ts +31 -0
  94. package/dist/src/index.js +16 -0
  95. package/dist/src/inventory.d.ts +4 -0
  96. package/dist/src/inventory.js +94 -0
  97. package/dist/src/java-compiler.d.ts +1 -0
  98. package/dist/src/java-compiler.js +110 -0
  99. package/dist/src/java-evidence.d.ts +2 -0
  100. package/dist/src/java-evidence.js +114 -0
  101. package/dist/src/java-runner.d.ts +1 -0
  102. package/dist/src/java-runner.js +79 -0
  103. package/dist/src/java.d.ts +25 -0
  104. package/dist/src/java.js +102 -0
  105. package/dist/src/jest-evidence.d.ts +2 -0
  106. package/dist/src/jest-evidence.js +117 -0
  107. package/dist/src/jest-runner.d.ts +1 -0
  108. package/dist/src/jest-runner.js +46 -0
  109. package/dist/src/jest.d.ts +2 -0
  110. package/dist/src/jest.js +36 -0
  111. package/dist/src/junit.d.ts +18 -0
  112. package/dist/src/junit.js +157 -0
  113. package/dist/src/laravel-evidence.d.ts +2 -0
  114. package/dist/src/laravel-evidence.js +175 -0
  115. package/dist/src/laravel-runner.d.ts +1 -0
  116. package/dist/src/laravel-runner.js +168 -0
  117. package/dist/src/laravel.d.ts +8 -0
  118. package/dist/src/laravel.js +50 -0
  119. package/dist/src/local-tool.d.ts +1 -0
  120. package/dist/src/local-tool.js +19 -0
  121. package/dist/src/mcp.d.ts +14 -0
  122. package/dist/src/mcp.js +362 -0
  123. package/dist/src/mutation.d.ts +118 -0
  124. package/dist/src/mutation.js +370 -0
  125. package/dist/src/mypy-evidence.d.ts +2 -0
  126. package/dist/src/mypy-evidence.js +63 -0
  127. package/dist/src/mypy.d.ts +2 -0
  128. package/dist/src/mypy.js +59 -0
  129. package/dist/src/node-reporter.d.ts +1 -0
  130. package/dist/src/node-reporter.js +28 -0
  131. package/dist/src/nuxt-evidence.d.ts +2 -0
  132. package/dist/src/nuxt-evidence.js +160 -0
  133. package/dist/src/nuxt-protocol.d.ts +52 -0
  134. package/dist/src/nuxt-protocol.js +29 -0
  135. package/dist/src/nuxt-runner.d.ts +1 -0
  136. package/dist/src/nuxt-runner.js +165 -0
  137. package/dist/src/nuxt.d.ts +24 -0
  138. package/dist/src/nuxt.js +105 -0
  139. package/dist/src/output.d.ts +3 -0
  140. package/dist/src/output.js +48 -0
  141. package/dist/src/phpstan-evidence.d.ts +2 -0
  142. package/dist/src/phpstan-evidence.js +81 -0
  143. package/dist/src/phpstan.d.ts +2 -0
  144. package/dist/src/phpstan.js +51 -0
  145. package/dist/src/phpunit-evidence.d.ts +2 -0
  146. package/dist/src/phpunit-evidence.js +53 -0
  147. package/dist/src/phpunit.d.ts +2 -0
  148. package/dist/src/phpunit.js +58 -0
  149. package/dist/src/pint-evidence.d.ts +2 -0
  150. package/dist/src/pint-evidence.js +79 -0
  151. package/dist/src/pint-runner.d.ts +1 -0
  152. package/dist/src/pint-runner.js +53 -0
  153. package/dist/src/pint.d.ts +2 -0
  154. package/dist/src/pint.js +37 -0
  155. package/dist/src/playwright-evidence.d.ts +2 -0
  156. package/dist/src/playwright-evidence.js +127 -0
  157. package/dist/src/playwright-reporter.d.ts +10 -0
  158. package/dist/src/playwright-reporter.js +37 -0
  159. package/dist/src/playwright-runner.d.ts +1 -0
  160. package/dist/src/playwright-runner.js +61 -0
  161. package/dist/src/playwright.d.ts +2 -0
  162. package/dist/src/playwright.js +35 -0
  163. package/dist/src/policy-pack.d.ts +21 -0
  164. package/dist/src/policy-pack.js +41 -0
  165. package/dist/src/pytest-evidence.d.ts +2 -0
  166. package/dist/src/pytest-evidence.js +116 -0
  167. package/dist/src/pytest-runner.d.ts +1 -0
  168. package/dist/src/pytest-runner.js +48 -0
  169. package/dist/src/pytest.d.ts +2 -0
  170. package/dist/src/pytest.js +25 -0
  171. package/dist/src/report-validation.d.ts +129 -0
  172. package/dist/src/report-validation.js +27 -0
  173. package/dist/src/review.d.ts +270 -0
  174. package/dist/src/review.js +349 -0
  175. package/dist/src/ruby.d.ts +2 -0
  176. package/dist/src/ruby.js +25 -0
  177. package/dist/src/ruff-evidence.d.ts +2 -0
  178. package/dist/src/ruff-evidence.js +99 -0
  179. package/dist/src/ruff.d.ts +2 -0
  180. package/dist/src/ruff.js +40 -0
  181. package/dist/src/runner.d.ts +8 -0
  182. package/dist/src/runner.js +117 -0
  183. package/dist/src/runtime-inventory.d.ts +112 -0
  184. package/dist/src/runtime-inventory.js +200 -0
  185. package/dist/src/rust-dep-info.d.ts +1 -0
  186. package/dist/src/rust-dep-info.js +46 -0
  187. package/dist/src/rust-evidence.d.ts +2 -0
  188. package/dist/src/rust-evidence.js +157 -0
  189. package/dist/src/rust-runner.d.ts +1 -0
  190. package/dist/src/rust-runner.js +161 -0
  191. package/dist/src/rust.d.ts +7 -0
  192. package/dist/src/rust.js +39 -0
  193. package/dist/src/sarif.d.ts +86 -0
  194. package/dist/src/sarif.js +113 -0
  195. package/dist/src/schemas.d.ts +393 -0
  196. package/dist/src/schemas.js +222 -0
  197. package/dist/src/staticcheck-evidence.d.ts +2 -0
  198. package/dist/src/staticcheck-evidence.js +75 -0
  199. package/dist/src/swift.d.ts +2 -0
  200. package/dist/src/swift.js +20 -0
  201. package/dist/src/task-store.d.ts +37 -0
  202. package/dist/src/task-store.js +349 -0
  203. package/dist/src/tool-versions.d.ts +3 -0
  204. package/dist/src/tool-versions.js +260 -0
  205. package/dist/src/types.d.ts +157 -0
  206. package/dist/src/types.js +37 -0
  207. package/dist/src/typescript-build-evidence.d.ts +2 -0
  208. package/dist/src/typescript-build-evidence.js +86 -0
  209. package/dist/src/typescript-build-runner.d.ts +1 -0
  210. package/dist/src/typescript-build-runner.js +132 -0
  211. package/dist/src/typescript-build.d.ts +2 -0
  212. package/dist/src/typescript-build.js +41 -0
  213. package/dist/src/typescript.d.ts +2 -0
  214. package/dist/src/typescript.js +54 -0
  215. package/dist/src/validation-task-worker.d.ts +1 -0
  216. package/dist/src/validation-task-worker.js +205 -0
  217. package/dist/src/validation-tasks-protocol.d.ts +69 -0
  218. package/dist/src/validation-tasks-protocol.js +57 -0
  219. package/dist/src/validation-tasks.d.ts +11 -0
  220. package/dist/src/validation-tasks.js +144 -0
  221. package/dist/src/vitest-evidence.d.ts +2 -0
  222. package/dist/src/vitest-evidence.js +112 -0
  223. package/dist/src/vitest-runner.d.ts +1 -0
  224. package/dist/src/vitest-runner.js +48 -0
  225. package/dist/src/vitest.d.ts +2 -0
  226. package/dist/src/vitest.js +36 -0
  227. package/dist/src/vue-router-capture.d.ts +42 -0
  228. package/dist/src/vue-router-capture.js +87 -0
  229. package/dist/src/vue-router-evidence.d.ts +2 -0
  230. package/dist/src/vue-router-evidence.js +126 -0
  231. package/dist/src/vue-router-protocol.d.ts +63 -0
  232. package/dist/src/vue-router-protocol.js +44 -0
  233. package/dist/src/vue-router-runner.d.ts +1 -0
  234. package/dist/src/vue-router-runner.js +88 -0
  235. package/dist/src/vue-router.d.ts +23 -0
  236. package/dist/src/vue-router.js +108 -0
  237. package/dist/src/vue-tsc-runner.d.ts +1 -0
  238. package/dist/src/vue-tsc-runner.js +24 -0
  239. package/dist/src/workspace.d.ts +7 -0
  240. package/dist/src/workspace.js +53 -0
  241. package/docs/ACCEPTANCE.md +56 -0
  242. package/docs/ACTIONLINT.md +112 -0
  243. package/docs/ARCHITECTURE-POLICY.md +82 -0
  244. package/docs/ARCHITECTURE.md +122 -0
  245. package/docs/CLANG.md +113 -0
  246. package/docs/CLIENTS.md +109 -0
  247. package/docs/CONTRACTS.md +73 -0
  248. package/docs/DEPENDENCIES.md +42 -0
  249. package/docs/DJANGO.md +70 -0
  250. package/docs/DOTNET.md +114 -0
  251. package/docs/ENVIRONMENTS.md +52 -0
  252. package/docs/ESLINT.md +68 -0
  253. package/docs/EVALUATION.md +124 -0
  254. package/docs/EXECUTION.md +250 -0
  255. package/docs/EXTERNAL-ADAPTERS.md +170 -0
  256. package/docs/EXTERNAL-EVALUATION.md +155 -0
  257. package/docs/EXTERNAL-RUFF-EVALUATION.md +85 -0
  258. package/docs/FASTAPI.md +73 -0
  259. package/docs/FINDING-POLICY.md +67 -0
  260. package/docs/GO-RACE.md +19 -0
  261. package/docs/GO-SCOPE.md +63 -0
  262. package/docs/GOLANGCI-LINT.md +64 -0
  263. package/docs/GUIDANCE.md +46 -0
  264. package/docs/IMPACT-MEASUREMENT.md +97 -0
  265. package/docs/INSTALLATION.md +102 -0
  266. package/docs/JAVA.md +79 -0
  267. package/docs/JEST.md +36 -0
  268. package/docs/JUNIT.md +31 -0
  269. package/docs/LANGUAGES.md +113 -0
  270. package/docs/LARAVEL.md +111 -0
  271. package/docs/MCP-COMPATIBILITY.md +68 -0
  272. package/docs/MUTATIONS.md +93 -0
  273. package/docs/MYPY.md +37 -0
  274. package/docs/NATIVE-CI.md +96 -0
  275. package/docs/NUXT.md +123 -0
  276. package/docs/PACK-DISTRIBUTION.md +98 -0
  277. package/docs/PERFORMANCE.md +71 -0
  278. package/docs/PEST.md +36 -0
  279. package/docs/PHPSTAN.md +48 -0
  280. package/docs/PHPUNIT.md +32 -0
  281. package/docs/PINT.md +41 -0
  282. package/docs/PLAN.md +265 -0
  283. package/docs/PLAYWRIGHT.md +73 -0
  284. package/docs/POLICY-PACKS.md +106 -0
  285. package/docs/PRIOR-WORKFLOW-EVALUATION.md +116 -0
  286. package/docs/PUBLICATION.md +28 -0
  287. package/docs/PYTEST.md +51 -0
  288. package/docs/RELEASE.md +115 -0
  289. package/docs/RENAMING.md +55 -0
  290. package/docs/REVIEW-EXCHANGE.md +136 -0
  291. package/docs/RUBY.md +50 -0
  292. package/docs/RUFF.md +39 -0
  293. package/docs/RUNTIME-INVENTORY.md +56 -0
  294. package/docs/RUST.md +74 -0
  295. package/docs/SARIF.md +64 -0
  296. package/docs/STATUS.md +530 -0
  297. package/docs/SWIFT.md +48 -0
  298. package/docs/TASK-STORAGE.md +141 -0
  299. package/docs/TOOL-IDENTITY.md +30 -0
  300. package/docs/TYPESCRIPT-BUILD.md +55 -0
  301. package/docs/VALIDATION-TASKS.md +119 -0
  302. package/docs/VITEST.md +36 -0
  303. package/docs/VUE-ROUTER.md +130 -0
  304. package/docs/VUE-TSC.md +26 -0
  305. package/docs/WORKSPACES.md +81 -0
  306. package/docs/licenses/nodable-entities-3.0.0.txt +21 -0
  307. package/docs/measurements/client-claude-before-schema-fix-darwin-arm64-node26.json +60 -0
  308. package/docs/measurements/client-claude-darwin-arm64-node26.json +55 -0
  309. package/docs/measurements/client-codex-darwin-arm64-node26.json +175 -0
  310. package/docs/measurements/evaluation-corpus-repo-verifier.json +332 -0
  311. package/docs/measurements/evaluation-darwin-arm64-node26.json +1236 -0
  312. package/docs/measurements/evaluation-linux-arm64-node22.json +1236 -0
  313. package/docs/measurements/external-eslint-darwin-arm64-node26.json +11866 -0
  314. package/docs/measurements/external-eslint-linux-arm64-node22.json +11866 -0
  315. package/docs/measurements/external-eslint-preservation.json +1527 -0
  316. package/docs/measurements/external-ruff-darwin-arm64-node26.json +1031 -0
  317. package/docs/measurements/external-ruff-linux-arm64-node22.json +1031 -0
  318. package/docs/measurements/hosted-ci-52ba415.json +1005 -0
  319. package/docs/measurements/impact-darwin-arm64-node26.json +6685 -0
  320. package/docs/measurements/impact-linux-arm64-node22.json +6690 -0
  321. package/docs/measurements/performance-darwin-arm64-node26.json +845 -0
  322. package/docs/measurements/performance-linux-arm64-node22.json +845 -0
  323. package/docs/measurements/required-native-profiles.json +500 -0
  324. package/package.json +72 -0
  325. package/packs/actionlint.json +8 -0
  326. package/packs/cpp.json +8 -0
  327. package/packs/dotnet.json +8 -0
  328. package/packs/go.json +7 -0
  329. package/packs/java.json +8 -0
  330. package/packs/javascript-node.json +7 -0
  331. package/packs/nuxt.json +7 -0
  332. package/packs/php-pest.json +7 -0
  333. package/packs/php-phpunit.json +7 -0
  334. package/packs/python-pytest.json +7 -0
  335. package/packs/ruby.json +7 -0
  336. package/packs/rust.json +7 -0
  337. package/packs/swift.json +7 -0
  338. package/packs/vue-router.json +7 -0
  339. package/packs/vue.json +11 -0
  340. package/schemas/actionlint-config.schema.json +19 -0
  341. package/schemas/architecture-policy.schema.json +51 -0
  342. package/schemas/architecture-report.schema.json +123 -0
  343. package/schemas/architecture-summary.schema.json +82 -0
  344. package/schemas/clang-database.schema.json +23 -0
  345. package/schemas/config.schema.json +69 -0
  346. package/schemas/contract-bundle.schema.json +78 -0
  347. package/schemas/contract-report.schema.json +114 -0
  348. package/schemas/contract-summary.schema.json +72 -0
  349. package/schemas/dependency-graph.schema.json +65 -0
  350. package/schemas/django-config.schema.json +16 -0
  351. package/schemas/dotnet-config.schema.json +60 -0
  352. package/schemas/external-manifest.schema.json +97 -0
  353. package/schemas/external-reference.schema.json +10 -0
  354. package/schemas/external-request.schema.json +56 -0
  355. package/schemas/external-result.schema.json +111 -0
  356. package/schemas/fastapi-config.schema.json +27 -0
  357. package/schemas/finding-baseline.schema.json +92 -0
  358. package/schemas/finding-comparison-summary.schema.json +95 -0
  359. package/schemas/finding-comparison.schema.json +121 -0
  360. package/schemas/guidance-context.schema.json +34 -0
  361. package/schemas/guidance-report.schema.json +176 -0
  362. package/schemas/guidance-summary.schema.json +68 -0
  363. package/schemas/java-config.schema.json +24 -0
  364. package/schemas/junit.schema.json +69 -0
  365. package/schemas/laravel-config.schema.json +11 -0
  366. package/schemas/mutation-recipe.schema.json +31 -0
  367. package/schemas/mutation-report.schema.json +238 -0
  368. package/schemas/mutation-summary.schema.json +98 -0
  369. package/schemas/nuxt-config.schema.json +51 -0
  370. package/schemas/plan-summary.schema.json +63 -0
  371. package/schemas/plan.schema.json +244 -0
  372. package/schemas/policy-pack.schema.json +41 -0
  373. package/schemas/report-summary.schema.json +100 -0
  374. package/schemas/report.schema.json +463 -0
  375. package/schemas/review-assessment.schema.json +133 -0
  376. package/schemas/review-context-summary.schema.json +31 -0
  377. package/schemas/review-context.schema.json +254 -0
  378. package/schemas/review-receipt-summary.schema.json +104 -0
  379. package/schemas/review-receipt.schema.json +271 -0
  380. package/schemas/review-selection.schema.json +30 -0
  381. package/schemas/runtime-comparison-summary.schema.json +68 -0
  382. package/schemas/runtime-comparison.schema.json +127 -0
  383. package/schemas/runtime-inventory.schema.json +99 -0
  384. package/schemas/vue-router-config.schema.json +67 -0
  385. package/server.json +47 -0
@@ -0,0 +1,230 @@
1
+ import { createHash } from "node:crypto";
2
+ import { z } from "zod";
3
+ import { VERSION } from "./types.js";
4
+ const name = z.string().min(1).max(1024);
5
+ const hash = z.string().regex(/^[a-f0-9]{64}$/);
6
+ const count = z.number().int().nonnegative();
7
+ const edge = z.strictObject({ consumer: name, producer: name });
8
+ export const dependencyGraphSchema = z.strictObject({
9
+ schemaVersion: z.literal(1),
10
+ format: z.literal("dependency-graph"),
11
+ capturedAt: z.iso.datetime(),
12
+ collector: z.strictObject({ name, version: name }),
13
+ complete: z.boolean(),
14
+ projects: z
15
+ .array(z.strictObject({
16
+ id: name,
17
+ language: name,
18
+ sourceFingerprint: hash,
19
+ complete: z.boolean(),
20
+ }))
21
+ .min(1)
22
+ .max(1000),
23
+ dependencies: z.array(edge).max(20_000),
24
+ });
25
+ export const architecturePolicySchema = z.strictObject({
26
+ schemaVersion: z.literal(1),
27
+ format: z.literal("architecture-policy"),
28
+ projects: z
29
+ .array(z.strictObject({ id: name, layer: name }))
30
+ .min(1)
31
+ .max(1000),
32
+ layers: z.array(name).min(1).max(128),
33
+ allowedDependencies: z.array(edge).max(16_384),
34
+ requireAcyclic: z.boolean(),
35
+ });
36
+ export const architectureReportSchema = z.strictObject({
37
+ schemaVersion: z.literal(1),
38
+ engineVersion: z.string(),
39
+ provenance: z.literal("imported-dependency-graph"),
40
+ outcome: z.enum(["passed", "failed", "incomplete"]),
41
+ reason: z.string(),
42
+ artifactFingerprint: hash,
43
+ policyFingerprint: hash,
44
+ captureComplete: z.boolean(),
45
+ counts: z.strictObject({
46
+ projects: count,
47
+ verifiedProjects: count,
48
+ unverifiedProjects: count,
49
+ dependencies: count,
50
+ allowed: count,
51
+ forbidden: count,
52
+ unverified: count,
53
+ cycles: count,
54
+ }),
55
+ projects: z.array(z.strictObject({
56
+ id: name,
57
+ status: z.enum(["verified", "missing", "unconfigured", "incomplete"]),
58
+ })),
59
+ dependencies: z.array(edge.extend({ status: z.enum(["allowed", "forbidden", "unverified"]) })),
60
+ cycles: z.array(z.array(name)),
61
+ });
62
+ export const architectureSummarySchema = architectureReportSchema.omit({
63
+ projects: true,
64
+ dependencies: true,
65
+ cycles: true,
66
+ });
67
+ function bounded(input) {
68
+ const serialized = JSON.stringify(input);
69
+ if (typeof serialized !== "string" ||
70
+ Buffer.byteLength(serialized) > 8 * 1024 * 1024)
71
+ throw new Error("Architecture artifact exceeds input limit");
72
+ return serialized;
73
+ }
74
+ function unique(values, description) {
75
+ const result = new Set(values);
76
+ if (result.size !== values.length)
77
+ throw new Error(`Duplicate ${description}`);
78
+ return result;
79
+ }
80
+ const pair = (consumer, producer) => JSON.stringify([consumer, producer]);
81
+ function cycleComponents(graph) {
82
+ const forward = new Map(graph.projects.map((project) => [project.id, []]));
83
+ const reverse = new Map(graph.projects.map((project) => [project.id, []]));
84
+ for (const { consumer, producer } of graph.dependencies) {
85
+ forward.get(consumer).push(producer);
86
+ reverse.get(producer).push(consumer);
87
+ }
88
+ const visited = new Set();
89
+ const finish = [];
90
+ for (const start of forward.keys()) {
91
+ if (visited.has(start))
92
+ continue;
93
+ const stack = [{ id: start, offset: 0 }];
94
+ visited.add(start);
95
+ while (stack.length) {
96
+ const item = stack[stack.length - 1];
97
+ const next = forward.get(item.id)[item.offset++];
98
+ if (next === undefined) {
99
+ finish.push(item.id);
100
+ stack.pop();
101
+ }
102
+ else if (!visited.has(next)) {
103
+ visited.add(next);
104
+ stack.push({ id: next, offset: 0 });
105
+ }
106
+ }
107
+ }
108
+ visited.clear();
109
+ const cycles = [];
110
+ for (const start of finish.reverse()) {
111
+ if (visited.has(start))
112
+ continue;
113
+ const members = [];
114
+ const pending = [start];
115
+ visited.add(start);
116
+ while (pending.length) {
117
+ const id = pending.pop();
118
+ members.push(id);
119
+ for (const dependency of reverse.get(id))
120
+ if (!visited.has(dependency)) {
121
+ visited.add(dependency);
122
+ pending.push(dependency);
123
+ }
124
+ }
125
+ if (members.length > 1 || forward.get(start).includes(start))
126
+ cycles.push(members.sort());
127
+ }
128
+ return cycles.sort((a, b) => a[0].localeCompare(b[0], "en"));
129
+ }
130
+ export function checkArchitecture(graphInput, policyInput) {
131
+ const graphBytes = bounded(graphInput);
132
+ const policyBytes = bounded(policyInput);
133
+ const graph = dependencyGraphSchema.parse(graphInput);
134
+ const policy = architecturePolicySchema.parse(policyInput);
135
+ const observed = unique(graph.projects.map((project) => project.id), "observed project ID");
136
+ unique(policy.projects.map((project) => project.id), "policy project ID");
137
+ const layers = unique(policy.layers, "architecture layer");
138
+ for (const project of policy.projects)
139
+ if (!layers.has(project.layer))
140
+ throw new Error("Project uses an undeclared architecture layer");
141
+ const allowed = unique(policy.allowedDependencies.map((item) => pair(item.consumer, item.producer)), "allowed layer dependency");
142
+ for (const item of policy.allowedDependencies)
143
+ if (!layers.has(item.consumer) || !layers.has(item.producer))
144
+ throw new Error("Allowed dependency uses an undeclared layer");
145
+ unique(graph.dependencies.map((item) => pair(item.consumer, item.producer)), "observed project dependency");
146
+ for (const item of graph.dependencies)
147
+ if (!observed.has(item.consumer) || !observed.has(item.producer))
148
+ throw new Error("Observed dependency references a missing graph project");
149
+ const observedProjects = new Map(graph.projects.map((project) => [project.id, project]));
150
+ const configured = new Map(policy.projects.map((project) => [project.id, project.layer]));
151
+ const projects = [
152
+ ...new Set([...observed, ...configured.keys()]),
153
+ ]
154
+ .sort()
155
+ .map((id) => ({
156
+ id,
157
+ status: !observed.has(id)
158
+ ? "missing"
159
+ : !configured.has(id)
160
+ ? "unconfigured"
161
+ : !observedProjects.get(id).complete
162
+ ? "incomplete"
163
+ : "verified",
164
+ }));
165
+ const dependencies = graph.dependencies.map((item) => {
166
+ const consumer = configured.get(item.consumer);
167
+ const producer = configured.get(item.producer);
168
+ return {
169
+ ...item,
170
+ status: consumer === undefined || producer === undefined
171
+ ? "unverified"
172
+ : allowed.has(pair(consumer, producer))
173
+ ? "allowed"
174
+ : "forbidden",
175
+ };
176
+ });
177
+ const cycles = policy.requireAcyclic ? cycleComponents(graph) : [];
178
+ const counts = {
179
+ projects: projects.length,
180
+ verifiedProjects: projects.filter((item) => item.status === "verified")
181
+ .length,
182
+ unverifiedProjects: projects.filter((item) => item.status !== "verified")
183
+ .length,
184
+ dependencies: dependencies.length,
185
+ allowed: dependencies.filter((item) => item.status === "allowed").length,
186
+ forbidden: dependencies.filter((item) => item.status === "forbidden")
187
+ .length,
188
+ unverified: dependencies.filter((item) => item.status === "unverified")
189
+ .length,
190
+ cycles: cycles.length,
191
+ };
192
+ const outcome = counts.forbidden || counts.cycles
193
+ ? "failed"
194
+ : !graph.complete || counts.unverifiedProjects || counts.unverified
195
+ ? "incomplete"
196
+ : "passed";
197
+ return {
198
+ schemaVersion: 1,
199
+ engineVersion: VERSION,
200
+ provenance: "imported-dependency-graph",
201
+ outcome,
202
+ captureComplete: graph.complete,
203
+ reason: outcome === "failed"
204
+ ? "Observed dependencies cross forbidden layer boundaries or contain prohibited cycles."
205
+ : outcome === "incomplete"
206
+ ? "Dependency capture or project-to-layer coverage is incomplete."
207
+ : "The supplied complete graph satisfies the explicit layer boundaries and cycle policy.",
208
+ artifactFingerprint: createHash("sha256").update(graphBytes).digest("hex"),
209
+ policyFingerprint: createHash("sha256").update(policyBytes).digest("hex"),
210
+ counts,
211
+ projects,
212
+ dependencies,
213
+ cycles,
214
+ };
215
+ }
216
+ export function projectArchitectureReport(report, detailed) {
217
+ if (detailed)
218
+ return report;
219
+ return architectureSummarySchema.parse({
220
+ schemaVersion: report.schemaVersion,
221
+ engineVersion: report.engineVersion,
222
+ provenance: report.provenance,
223
+ outcome: report.outcome,
224
+ reason: report.reason,
225
+ artifactFingerprint: report.artifactFingerprint,
226
+ policyFingerprint: report.policyFingerprint,
227
+ captureComplete: report.captureComplete,
228
+ counts: report.counts,
229
+ });
230
+ }
@@ -0,0 +1,2 @@
1
+ import type { Check, CheckResult, ProcessResult } from "./types.js";
2
+ export declare function clangEvidence(check: Check, processes: ProcessResult[], root: string | undefined): Pick<CheckResult, "status" | "reason" | "findings" | "findingsComplete">;
@@ -0,0 +1,194 @@
1
+ import path from "node:path";
2
+ import { fileURLToPath } from "node:url";
3
+ import { z } from "zod";
4
+ import { clangInvocationSchema } from "./clang.js";
5
+ import { clangVersion, supportedClangVersion } from "./clang-protocol.js";
6
+ const location = z.object({
7
+ physicalLocation: z.object({
8
+ artifactLocation: z.object({
9
+ uri: z.string(),
10
+ index: z.number().int().nonnegative().optional(),
11
+ }),
12
+ region: z.object({ startLine: z.number().int().positive() }),
13
+ }),
14
+ });
15
+ const sarif = z.object({
16
+ version: z.literal("2.1.0"),
17
+ runs: z
18
+ .array(z.object({
19
+ tool: z.object({
20
+ driver: z.object({
21
+ name: z.literal("clang"),
22
+ version: z.string(),
23
+ rules: z.array(z.object({ id: z.string() })),
24
+ }),
25
+ }),
26
+ invocations: z
27
+ .array(z.object({ executionSuccessful: z.boolean() }))
28
+ .length(1)
29
+ .optional(),
30
+ results: z
31
+ .array(z.object({
32
+ level: z.enum(["error", "warning", "note"]),
33
+ ruleId: z.string(),
34
+ ruleIndex: z.number().int().nonnegative(),
35
+ message: z.object({ text: z.string() }),
36
+ locations: z.array(location).optional(),
37
+ }))
38
+ .max(20_000),
39
+ }))
40
+ .length(1),
41
+ });
42
+ const schema = z.strictObject({
43
+ version: z.literal(1),
44
+ project: z.string(),
45
+ units: z
46
+ .array(z.strictObject({
47
+ index: z.number().int().nonnegative(),
48
+ file: z.string(),
49
+ compiler: z.enum(["clang", "clang++"]),
50
+ version: z.string(),
51
+ exitCode: z.number().int(),
52
+ diagnostics: z.unknown(),
53
+ observedSources: z.array(z.string()).max(20_000),
54
+ externalDependencyCount: z.number().int().nonnegative(),
55
+ scopeError: z.boolean(),
56
+ }))
57
+ .min(1)
58
+ .max(64),
59
+ });
60
+ export function clangEvidence(check, processes, root) {
61
+ const incomplete = {
62
+ status: "inconclusive",
63
+ reason: "Clang evidence is malformed or lacks compilation/source accounting",
64
+ findingsComplete: false,
65
+ };
66
+ if (!root || processes.length !== 1)
67
+ return incomplete;
68
+ const process = processes[0];
69
+ if (process.exitCode === 3) {
70
+ try {
71
+ const value = z
72
+ .strictObject({
73
+ unavailable: z.literal("clang-toolchain"),
74
+ reason: z.enum(["missing-tool", "unsupported-version"]),
75
+ })
76
+ .safeParse(JSON.parse(process.stdout));
77
+ return value.success
78
+ ? {
79
+ status: "unavailable",
80
+ reason: "The required Clang toolchain is missing or outside the verified native profile",
81
+ }
82
+ : incomplete;
83
+ }
84
+ catch {
85
+ return incomplete;
86
+ }
87
+ }
88
+ if (process.exitCode !== 0)
89
+ return {
90
+ status: "error",
91
+ reason: "Clang evidence collection did not complete normally",
92
+ };
93
+ try {
94
+ const data = schema.parse(JSON.parse(process.stdout));
95
+ const planned = clangInvocationSchema.parse(JSON.parse(check.commands[0].args[2]));
96
+ if (data.project !== check.project ||
97
+ data.units.length !== planned.units.length ||
98
+ JSON.stringify(planned.scope) !== JSON.stringify(check.scope))
99
+ return incomplete;
100
+ const observed = new Set();
101
+ const findings = [];
102
+ let partial = false;
103
+ let failed = false;
104
+ for (const [index, unit] of data.units.entries()) {
105
+ const expected = planned.units[index];
106
+ if (unit.index !== index ||
107
+ unit.file !== expected.file ||
108
+ unit.compiler !== expected.compiler ||
109
+ !supportedClangVersion(unit.version))
110
+ return incomplete;
111
+ const parsed = sarif.safeParse(unit.diagnostics);
112
+ if (!parsed.success) {
113
+ partial = true;
114
+ continue;
115
+ }
116
+ const run = parsed.data.runs[0];
117
+ if (run.tool.driver.version !==
118
+ (unit.version.startsWith("Apple ")
119
+ ? unit.version.split("\n")[0]
120
+ : clangVersion(unit.version)) ||
121
+ (unit.version.startsWith("Apple ") && !run.invocations) ||
122
+ (run.invocations !== undefined &&
123
+ run.invocations[0].executionSuccessful !== (unit.exitCode === 0))) {
124
+ partial = true;
125
+ continue;
126
+ }
127
+ let errors = 0;
128
+ for (const diagnostic of run.results) {
129
+ if (run.tool.driver.rules[diagnostic.ruleIndex]?.id !== diagnostic.ruleId) {
130
+ partial = true;
131
+ continue;
132
+ }
133
+ if (diagnostic.level === "error")
134
+ errors++;
135
+ const first = diagnostic.locations?.[0]?.physicalLocation;
136
+ let relative;
137
+ if (first) {
138
+ try {
139
+ const absolute = fileURLToPath(first.artifactLocation.uri);
140
+ const file = path
141
+ .relative(path.resolve(root, check.project), absolute)
142
+ .split(path.sep)
143
+ .join("/");
144
+ if (check.scope.includes(file))
145
+ relative = path.posix.join(check.project, file);
146
+ }
147
+ catch {
148
+ partial = true;
149
+ }
150
+ }
151
+ findings.push({
152
+ ruleId: `clang/${diagnostic.ruleId}`,
153
+ level: diagnostic.level,
154
+ message: diagnostic.message.text,
155
+ ...(relative && first
156
+ ? { file: relative, line: first.region.startLine }
157
+ : {}),
158
+ });
159
+ }
160
+ if (errors && unit.exitCode !== 0)
161
+ failed = true;
162
+ else if (unit.exitCode !== 0 || errors)
163
+ partial = true;
164
+ if (unit.scopeError ||
165
+ new Set(unit.observedSources).size !== unit.observedSources.length ||
166
+ !unit.observedSources.includes(unit.file))
167
+ partial = true;
168
+ for (const file of unit.observedSources) {
169
+ if (!check.scope.includes(file))
170
+ partial = true;
171
+ else
172
+ observed.add(file);
173
+ }
174
+ }
175
+ if (failed)
176
+ return {
177
+ status: "failed",
178
+ reason: "Clang reported native compiler errors; failed compilation does not establish complete analysis",
179
+ findings,
180
+ findingsComplete: false,
181
+ };
182
+ if (partial || observed.size !== check.scope.length || !observed.size)
183
+ return { ...incomplete, findings };
184
+ return {
185
+ status: "passed",
186
+ reason: "Every prepared Clang compilation completed with dependency coverage of inventoried C/C++ sources; linking and tests were not executed",
187
+ findings,
188
+ findingsComplete: true,
189
+ };
190
+ }
191
+ catch {
192
+ return incomplete;
193
+ }
194
+ }
@@ -0,0 +1,3 @@
1
+ export declare function clangVersion(output: string): string | undefined;
2
+ export declare function supportedClangVersion(output: string): boolean;
3
+ export declare function clangDependencies(text: string, cwd: string): string[];
@@ -0,0 +1,25 @@
1
+ import path from "node:path";
2
+ export function clangVersion(output) {
3
+ return /^(?:Apple |Debian |Ubuntu |Alpine )?clang version (\d+\.\d+\.\d+)(?:[^\r\n]*)\r?\nTarget: [^\r\n]+\r?\nThread model: posix\r?\nInstalledDir: [^\r\n]+$/.exec(output.trim())?.[1];
4
+ }
5
+ export function supportedClangVersion(output) {
6
+ return ((clangVersion(output) === "21.0.0" &&
7
+ output.startsWith("Apple clang version 21.0.0 (clang-2100.3.34.2)\n")) ||
8
+ (clangVersion(output) === "22.1.3" &&
9
+ output.startsWith("Alpine clang version 22.1.3\n")));
10
+ }
11
+ export function clangDependencies(text, cwd) {
12
+ const flattened = text.replace(/\\\r?\n/g, "").trim();
13
+ if (!flattened.startsWith("checktrail: "))
14
+ throw new Error("Missing native dependency target");
15
+ const body = flattened.slice("checktrail: ".length);
16
+ if (/[\r\n$#:]/.test(body) || body.replaceAll("\\ ", "").includes("\\"))
17
+ throw new Error("Unsupported dependency-file spelling");
18
+ const paths = body
19
+ .split(/(?<!\\)[ \t]+/)
20
+ .filter(Boolean)
21
+ .map((word) => path.resolve(cwd, word.replaceAll("\\ ", " ")));
22
+ if (!paths.length)
23
+ throw new Error("Native dependency list is empty");
24
+ return [...new Set(paths)].sort();
25
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,159 @@
1
+ import { spawnSync } from "node:child_process";
2
+ import { mkdtemp, readFile, realpath, rm, stat } from "node:fs/promises";
3
+ import { tmpdir } from "node:os";
4
+ import path from "node:path";
5
+ import { clangInvocationSchema } from "./clang.js";
6
+ import { clangDependencies, supportedClangVersion } from "./clang-protocol.js";
7
+ import { withinRoot } from "./inventory.js";
8
+ function invoke(executable, args, cwd) {
9
+ const result = spawnSync(executable, args, {
10
+ cwd,
11
+ encoding: "utf8",
12
+ maxBuffer: 1024 * 1024,
13
+ });
14
+ if (result.error || result.signal || result.status === null)
15
+ throw new Error("Clang did not complete within native evidence limits");
16
+ return result;
17
+ }
18
+ async function main() {
19
+ const [rootInput, encoded] = process.argv.slice(2);
20
+ if (!rootInput || !encoded)
21
+ throw new Error("Missing Clang invocation");
22
+ const root = await realpath(rootInput);
23
+ const projectRoot = await realpath(process.cwd());
24
+ const invocation = clangInvocationSchema.parse(JSON.parse(encoded));
25
+ const versions = new Map();
26
+ for (const name of new Set(invocation.units.map((unit) => unit.compiler))) {
27
+ let output;
28
+ try {
29
+ output = invoke(name, ["--no-default-config", "--version"], projectRoot);
30
+ }
31
+ catch {
32
+ process.stdout.write(JSON.stringify({
33
+ unavailable: "clang-toolchain",
34
+ reason: "missing-tool",
35
+ }));
36
+ process.exitCode = 3;
37
+ return;
38
+ }
39
+ if (output.status !== 0 ||
40
+ output.stderr.trim() ||
41
+ !supportedClangVersion(output.stdout)) {
42
+ process.stdout.write(JSON.stringify({
43
+ unavailable: "clang-toolchain",
44
+ reason: "unsupported-version",
45
+ }));
46
+ process.exitCode = 3;
47
+ return;
48
+ }
49
+ versions.set(name, output.stdout.trim());
50
+ }
51
+ const temporary = await mkdtemp(path.join(tmpdir(), "checktrail-clang-"));
52
+ const expected = new Set(invocation.scope.map((file) => path.resolve(projectRoot, file)));
53
+ let bytes = 0;
54
+ let dependencyBytes = 0;
55
+ try {
56
+ const units = [];
57
+ for (const [index, unit] of invocation.units.entries()) {
58
+ const cwd = await withinRoot(root, unit.cwd);
59
+ await withinRoot(root, path.relative(root, path.resolve(projectRoot, unit.file)));
60
+ const dependencyFile = path.join(temporary, `unit-${index}.d`);
61
+ const args = [
62
+ "--no-default-config",
63
+ ...unit.args,
64
+ "-fsyntax-only",
65
+ "-fno-modules",
66
+ "-fno-implicit-modules",
67
+ "-fdiagnostics-format=sarif",
68
+ "-Wno-sarif-format-unstable",
69
+ "-fno-color-diagnostics",
70
+ "-ferror-limit=0",
71
+ "-MD",
72
+ "-MF",
73
+ dependencyFile,
74
+ "-MT",
75
+ "checktrail",
76
+ unit.input,
77
+ ];
78
+ const native = invoke(unit.compiler, args, cwd);
79
+ bytes +=
80
+ Buffer.byteLength(native.stdout) + Buffer.byteLength(native.stderr);
81
+ if (bytes > 4 * 1024 * 1024)
82
+ throw new Error("Clang evidence exceeds total output limits");
83
+ const first = native.stderr.indexOf("{");
84
+ const last = native.stderr.lastIndexOf("}");
85
+ let diagnostics = null;
86
+ let scopeError = native.stdout.trim() !== "";
87
+ const tail = native.stderr.slice(last + 1).trim();
88
+ if (first < 0 ||
89
+ native.stderr.slice(0, first).trim() ||
90
+ (tail &&
91
+ !/^(?:(?:\d+ warnings?(?: and )?)?\d+ errors?|\d+ warnings?) generated\.$/.test(tail)))
92
+ scopeError = true;
93
+ else {
94
+ try {
95
+ diagnostics = JSON.parse(native.stderr.slice(first, last + 1));
96
+ }
97
+ catch {
98
+ scopeError = true;
99
+ }
100
+ }
101
+ const observedSources = [];
102
+ let externalDependencyCount = 0;
103
+ try {
104
+ const size = (await stat(dependencyFile)).size;
105
+ dependencyBytes += size;
106
+ if (size > 8 * 1024 * 1024 || dependencyBytes > 16 * 1024 * 1024)
107
+ throw new Error("Dependency evidence exceeds limits");
108
+ for (const dependency of clangDependencies(await readFile(dependencyFile, "utf8"), cwd)) {
109
+ const physical = await realpath(dependency);
110
+ const lexical = path.relative(root, dependency);
111
+ const physicalRelative = path.relative(root, physical);
112
+ const inside = (relative) => relative !== ".." &&
113
+ !relative.startsWith(`..${path.sep}`) &&
114
+ !path.isAbsolute(relative);
115
+ if (physical !== dependency &&
116
+ (inside(lexical) || inside(physicalRelative)))
117
+ scopeError = true;
118
+ if (expected.has(physical))
119
+ observedSources.push(path.relative(projectRoot, physical).split(path.sep).join("/"));
120
+ else {
121
+ const relative = path.relative(root, physical);
122
+ if (relative !== ".." &&
123
+ !relative.startsWith(`..${path.sep}`) &&
124
+ !path.isAbsolute(relative))
125
+ scopeError = true;
126
+ else
127
+ externalDependencyCount++;
128
+ }
129
+ }
130
+ }
131
+ catch {
132
+ scopeError = true;
133
+ }
134
+ units.push({
135
+ index,
136
+ file: unit.file,
137
+ compiler: unit.compiler,
138
+ version: versions.get(unit.compiler),
139
+ exitCode: native.status,
140
+ diagnostics,
141
+ observedSources: observedSources.sort(),
142
+ externalDependencyCount,
143
+ scopeError,
144
+ });
145
+ }
146
+ process.stdout.write(JSON.stringify({
147
+ version: 1,
148
+ project: path.relative(root, projectRoot).split(path.sep).join("/") || ".",
149
+ units,
150
+ }));
151
+ }
152
+ finally {
153
+ await rm(temporary, { recursive: true, force: true });
154
+ }
155
+ }
156
+ main().catch(() => {
157
+ process.stderr.write("Clang evidence collection could not complete\n");
158
+ process.exitCode = 2;
159
+ });
@@ -0,0 +1,44 @@
1
+ import { z } from "zod";
2
+ import type { Check, Inventory, Project } from "./types.js";
3
+ export declare const clangDatabaseSchema: z.ZodArray<z.ZodObject<{
4
+ directory: z.ZodString;
5
+ file: z.ZodString;
6
+ arguments: z.ZodOptional<z.ZodArray<z.ZodString>>;
7
+ command: z.ZodOptional<z.ZodString>;
8
+ output: z.ZodOptional<z.ZodString>;
9
+ }, z.core.$strict>>;
10
+ export declare const clangUnitSchema: z.ZodObject<{
11
+ compiler: z.ZodEnum<{
12
+ clang: "clang";
13
+ "clang++": "clang++";
14
+ }>;
15
+ cwd: z.ZodString;
16
+ file: z.ZodString;
17
+ input: z.ZodString;
18
+ args: z.ZodArray<z.ZodString>;
19
+ }, z.core.$strict>;
20
+ export declare const clangInvocationSchema: z.ZodObject<{
21
+ units: z.ZodArray<z.ZodObject<{
22
+ compiler: z.ZodEnum<{
23
+ clang: "clang";
24
+ "clang++": "clang++";
25
+ }>;
26
+ cwd: z.ZodString;
27
+ file: z.ZodString;
28
+ input: z.ZodString;
29
+ args: z.ZodArray<z.ZodString>;
30
+ }, z.core.$strict>>;
31
+ scope: z.ZodArray<z.ZodString>;
32
+ }, z.core.$strict>;
33
+ export type ClangUnit = z.infer<typeof clangUnitSchema>;
34
+ export declare const clangEnvironment: {
35
+ CCC_OVERRIDE_OPTIONS: string;
36
+ CPATH: string;
37
+ C_INCLUDE_PATH: string;
38
+ CPLUS_INCLUDE_PATH: string;
39
+ OBJC_INCLUDE_PATH: string;
40
+ CLANG_CONFIG_FILE_USER_DIR: string;
41
+ CLANG_CONFIG_FILE_SYSTEM_DIR: string;
42
+ };
43
+ export declare function clangExecutableMatches(name: "clang" | "clang++", declared: string): Promise<boolean>;
44
+ export declare function clangCheck(source: Inventory, project: Project): Promise<Check>;