@promptci/core 0.0.1 → 0.2.0

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 (253) hide show
  1. package/LICENSE +201 -201
  2. package/README.md +29 -30
  3. package/dist/action-pinning.d.ts +37 -0
  4. package/dist/action-pinning.d.ts.map +1 -0
  5. package/dist/action-pinning.js +277 -0
  6. package/dist/action-pinning.js.map +1 -0
  7. package/dist/agent-practices.d.ts +3 -1
  8. package/dist/agent-practices.d.ts.map +1 -1
  9. package/dist/agent-practices.js +198 -94
  10. package/dist/agent-practices.js.map +1 -1
  11. package/dist/ai-config.d.ts +178 -0
  12. package/dist/ai-config.d.ts.map +1 -0
  13. package/dist/ai-config.js +721 -0
  14. package/dist/ai-config.js.map +1 -0
  15. package/dist/alias-files.d.ts +33 -0
  16. package/dist/alias-files.d.ts.map +1 -0
  17. package/dist/alias-files.js +60 -0
  18. package/dist/alias-files.js.map +1 -0
  19. package/dist/baseline.d.ts +17 -1
  20. package/dist/baseline.d.ts.map +1 -1
  21. package/dist/baseline.js +5 -1
  22. package/dist/baseline.js.map +1 -1
  23. package/dist/buried-critical.d.ts +17 -0
  24. package/dist/buried-critical.d.ts.map +1 -0
  25. package/dist/buried-critical.js +107 -0
  26. package/dist/buried-critical.js.map +1 -0
  27. package/dist/canonical-owner.d.ts.map +1 -1
  28. package/dist/canonical-owner.js +60 -30
  29. package/dist/canonical-owner.js.map +1 -1
  30. package/dist/ci-alignment.d.ts.map +1 -1
  31. package/dist/ci-alignment.js +3 -2
  32. package/dist/ci-alignment.js.map +1 -1
  33. package/dist/command-validity.d.ts +16 -0
  34. package/dist/command-validity.d.ts.map +1 -1
  35. package/dist/command-validity.js +387 -134
  36. package/dist/command-validity.js.map +1 -1
  37. package/dist/conflicts.d.ts.map +1 -1
  38. package/dist/conflicts.js +4 -44
  39. package/dist/conflicts.js.map +1 -1
  40. package/dist/context-analysis.d.ts.map +1 -1
  41. package/dist/context-analysis.js +13 -2
  42. package/dist/context-analysis.js.map +1 -1
  43. package/dist/context-bloat.d.ts +20 -1
  44. package/dist/context-bloat.d.ts.map +1 -1
  45. package/dist/context-bloat.js +99 -15
  46. package/dist/context-bloat.js.map +1 -1
  47. package/dist/context-optimizer.d.ts.map +1 -1
  48. package/dist/context-optimizer.js +18 -54
  49. package/dist/context-optimizer.js.map +1 -1
  50. package/dist/copilot-instructions-detector.d.ts +24 -0
  51. package/dist/copilot-instructions-detector.d.ts.map +1 -0
  52. package/dist/copilot-instructions-detector.js +145 -0
  53. package/dist/copilot-instructions-detector.js.map +1 -0
  54. package/dist/cursor-rules-detector.d.ts +17 -0
  55. package/dist/cursor-rules-detector.d.ts.map +1 -0
  56. package/dist/cursor-rules-detector.js +110 -0
  57. package/dist/cursor-rules-detector.js.map +1 -0
  58. package/dist/custom-rules.d.ts +52 -0
  59. package/dist/custom-rules.d.ts.map +1 -0
  60. package/dist/custom-rules.js +303 -0
  61. package/dist/custom-rules.js.map +1 -0
  62. package/dist/dead-references.d.ts +8 -2
  63. package/dist/dead-references.d.ts.map +1 -1
  64. package/dist/dead-references.js +315 -68
  65. package/dist/dead-references.js.map +1 -1
  66. package/dist/dependency-staleness.d.ts +35 -0
  67. package/dist/dependency-staleness.d.ts.map +1 -0
  68. package/dist/dependency-staleness.js +1001 -0
  69. package/dist/dependency-staleness.js.map +1 -0
  70. package/dist/detectors.d.ts +1 -3
  71. package/dist/detectors.d.ts.map +1 -1
  72. package/dist/detectors.js +74 -56
  73. package/dist/detectors.js.map +1 -1
  74. package/dist/duplicates.d.ts.map +1 -1
  75. package/dist/duplicates.js +15 -9
  76. package/dist/duplicates.js.map +1 -1
  77. package/dist/evidence.d.ts +39 -0
  78. package/dist/evidence.d.ts.map +1 -0
  79. package/dist/evidence.js +78 -0
  80. package/dist/evidence.js.map +1 -0
  81. package/dist/finding-id.d.ts +21 -0
  82. package/dist/finding-id.d.ts.map +1 -0
  83. package/dist/finding-id.js +31 -0
  84. package/dist/finding-id.js.map +1 -0
  85. package/dist/fix-engine.d.ts +11 -0
  86. package/dist/fix-engine.d.ts.map +1 -1
  87. package/dist/fix-engine.js +88 -71
  88. package/dist/fix-engine.js.map +1 -1
  89. package/dist/frameworks/dotnet.js +2 -2
  90. package/dist/frameworks/dotnet.js.map +1 -1
  91. package/dist/frameworks/python.d.ts.map +1 -1
  92. package/dist/frameworks/python.js +5 -2
  93. package/dist/frameworks/python.js.map +1 -1
  94. package/dist/frameworks/rust.d.ts.map +1 -1
  95. package/dist/frameworks/rust.js +2 -1
  96. package/dist/frameworks/rust.js.map +1 -1
  97. package/dist/git-symlinks.d.ts +30 -0
  98. package/dist/git-symlinks.d.ts.map +1 -0
  99. package/dist/git-symlinks.js +161 -0
  100. package/dist/git-symlinks.js.map +1 -0
  101. package/dist/gitignore.d.ts +22 -0
  102. package/dist/gitignore.d.ts.map +1 -0
  103. package/dist/gitignore.js +157 -0
  104. package/dist/gitignore.js.map +1 -0
  105. package/dist/health-score.d.ts.map +1 -1
  106. package/dist/health-score.js +35 -5
  107. package/dist/health-score.js.map +1 -1
  108. package/dist/hooks-settings-detector.d.ts +17 -0
  109. package/dist/hooks-settings-detector.d.ts.map +1 -0
  110. package/dist/hooks-settings-detector.js +228 -0
  111. package/dist/hooks-settings-detector.js.map +1 -0
  112. package/dist/index.d.ts +29 -8
  113. package/dist/index.d.ts.map +1 -1
  114. package/dist/index.js +21 -6
  115. package/dist/index.js.map +1 -1
  116. package/dist/makefile.d.ts +37 -0
  117. package/dist/makefile.d.ts.map +1 -0
  118. package/dist/makefile.js +156 -0
  119. package/dist/makefile.js.map +1 -0
  120. package/dist/manifest-consistency.d.ts +6 -0
  121. package/dist/manifest-consistency.d.ts.map +1 -1
  122. package/dist/manifest-consistency.js +75 -10
  123. package/dist/manifest-consistency.js.map +1 -1
  124. package/dist/markdown-fences.d.ts +112 -0
  125. package/dist/markdown-fences.d.ts.map +1 -0
  126. package/dist/markdown-fences.js +174 -0
  127. package/dist/markdown-fences.js.map +1 -0
  128. package/dist/mcp-config-detector.d.ts +20 -0
  129. package/dist/mcp-config-detector.d.ts.map +1 -0
  130. package/dist/mcp-config-detector.js +237 -0
  131. package/dist/mcp-config-detector.js.map +1 -0
  132. package/dist/missing-context.d.ts.map +1 -1
  133. package/dist/missing-context.js +2 -52
  134. package/dist/missing-context.js.map +1 -1
  135. package/dist/model-budgets.d.ts +69 -0
  136. package/dist/model-budgets.d.ts.map +1 -0
  137. package/dist/model-budgets.js +110 -0
  138. package/dist/model-budgets.js.map +1 -0
  139. package/dist/negative-instructions.d.ts +26 -0
  140. package/dist/negative-instructions.d.ts.map +1 -0
  141. package/dist/negative-instructions.js +169 -0
  142. package/dist/negative-instructions.js.map +1 -0
  143. package/dist/path-containment.d.ts +41 -0
  144. package/dist/path-containment.d.ts.map +1 -0
  145. package/dist/path-containment.js +123 -0
  146. package/dist/path-containment.js.map +1 -0
  147. package/dist/project-type.d.ts +12 -2
  148. package/dist/project-type.d.ts.map +1 -1
  149. package/dist/project-type.js +25 -12
  150. package/dist/project-type.js.map +1 -1
  151. package/dist/prompt-cache.d.ts.map +1 -1
  152. package/dist/prompt-cache.js +33 -24
  153. package/dist/prompt-cache.js.map +1 -1
  154. package/dist/promptci-gitignore.d.ts +34 -0
  155. package/dist/promptci-gitignore.d.ts.map +1 -0
  156. package/dist/promptci-gitignore.js +42 -0
  157. package/dist/promptci-gitignore.js.map +1 -0
  158. package/dist/repo-context.d.ts +80 -0
  159. package/dist/repo-context.d.ts.map +1 -1
  160. package/dist/repo-context.js +170 -16
  161. package/dist/repo-context.js.map +1 -1
  162. package/dist/report.d.ts +8 -0
  163. package/dist/report.d.ts.map +1 -1
  164. package/dist/report.js +163 -63
  165. package/dist/report.js.map +1 -1
  166. package/dist/scan.d.ts.map +1 -1
  167. package/dist/scan.js +47 -4
  168. package/dist/scan.js.map +1 -1
  169. package/dist/scanner.d.ts +61 -1
  170. package/dist/scanner.d.ts.map +1 -1
  171. package/dist/scanner.js +367 -70
  172. package/dist/scanner.js.map +1 -1
  173. package/dist/security-pack.d.ts +20 -0
  174. package/dist/security-pack.d.ts.map +1 -1
  175. package/dist/security-pack.js +33 -14
  176. package/dist/security-pack.js.map +1 -1
  177. package/dist/skill-supply-chain.d.ts +132 -0
  178. package/dist/skill-supply-chain.d.ts.map +1 -0
  179. package/dist/skill-supply-chain.js +2954 -0
  180. package/dist/skill-supply-chain.js.map +1 -0
  181. package/dist/skills-detector.d.ts +23 -0
  182. package/dist/skills-detector.d.ts.map +1 -0
  183. package/dist/skills-detector.js +279 -0
  184. package/dist/skills-detector.js.map +1 -0
  185. package/dist/stale-instructions.d.ts +4 -1
  186. package/dist/stale-instructions.d.ts.map +1 -1
  187. package/dist/stale-instructions.js +53 -55
  188. package/dist/stale-instructions.js.map +1 -1
  189. package/dist/subagents-detector.d.ts +19 -0
  190. package/dist/subagents-detector.d.ts.map +1 -0
  191. package/dist/subagents-detector.js +155 -0
  192. package/dist/subagents-detector.js.map +1 -0
  193. package/dist/suppression.d.ts +2 -0
  194. package/dist/suppression.d.ts.map +1 -1
  195. package/dist/suppression.js +16 -47
  196. package/dist/suppression.js.map +1 -1
  197. package/dist/types.d.ts +62 -4
  198. package/dist/types.d.ts.map +1 -1
  199. package/dist/types.js +47 -1
  200. package/dist/types.js.map +1 -1
  201. package/dist/vague-guidance.d.ts +15 -2
  202. package/dist/vague-guidance.d.ts.map +1 -1
  203. package/dist/vague-guidance.js +44 -41
  204. package/dist/vague-guidance.js.map +1 -1
  205. package/dist/windsurf-detector.d.ts +22 -0
  206. package/dist/windsurf-detector.d.ts.map +1 -0
  207. package/dist/windsurf-detector.js +96 -0
  208. package/dist/windsurf-detector.js.map +1 -0
  209. package/dist/within-section-dedup.d.ts +16 -0
  210. package/dist/within-section-dedup.d.ts.map +1 -0
  211. package/dist/within-section-dedup.js +148 -0
  212. package/dist/within-section-dedup.js.map +1 -0
  213. package/dist/workspace-manifests.d.ts +80 -0
  214. package/dist/workspace-manifests.d.ts.map +1 -0
  215. package/dist/workspace-manifests.js +333 -0
  216. package/dist/workspace-manifests.js.map +1 -0
  217. package/package.json +11 -8
  218. package/dist/cheap-model-routing.d.ts +0 -4
  219. package/dist/cheap-model-routing.d.ts.map +0 -1
  220. package/dist/cheap-model-routing.js +0 -43
  221. package/dist/cheap-model-routing.js.map +0 -1
  222. package/dist/cli-output-filter.d.ts +0 -16
  223. package/dist/cli-output-filter.d.ts.map +0 -1
  224. package/dist/cli-output-filter.js +0 -88
  225. package/dist/cli-output-filter.js.map +0 -1
  226. package/dist/context-cost.d.ts +0 -4
  227. package/dist/context-cost.d.ts.map +0 -1
  228. package/dist/context-cost.js +0 -70
  229. package/dist/context-cost.js.map +0 -1
  230. package/dist/context-recommender.d.ts +0 -3
  231. package/dist/context-recommender.d.ts.map +0 -1
  232. package/dist/context-recommender.js +0 -329
  233. package/dist/context-recommender.js.map +0 -1
  234. package/dist/llm.d.ts +0 -6
  235. package/dist/llm.d.ts.map +0 -1
  236. package/dist/llm.js +0 -67
  237. package/dist/llm.js.map +0 -1
  238. package/dist/mcp-detector.d.ts +0 -4
  239. package/dist/mcp-detector.d.ts.map +0 -1
  240. package/dist/mcp-detector.js +0 -131
  241. package/dist/mcp-detector.js.map +0 -1
  242. package/dist/native-tool-preference.d.ts +0 -20
  243. package/dist/native-tool-preference.d.ts.map +0 -1
  244. package/dist/native-tool-preference.js +0 -94
  245. package/dist/native-tool-preference.js.map +0 -1
  246. package/dist/output-verbosity.d.ts +0 -3
  247. package/dist/output-verbosity.d.ts.map +0 -1
  248. package/dist/output-verbosity.js +0 -83
  249. package/dist/output-verbosity.js.map +0 -1
  250. package/dist/product-boundary.d.ts +0 -11
  251. package/dist/product-boundary.d.ts.map +0 -1
  252. package/dist/product-boundary.js +0 -301
  253. package/dist/product-boundary.js.map +0 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"evidence.js","sourceRoot":"","sources":["../src/evidence.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Location-independent path segments for finding-id hash keys.
3
+ *
4
+ * Finding ids are sha1 hashes over a key that usually embeds the file the
5
+ * finding is about. `InstructionFile.path` / `InstructionSection.filePath` are
6
+ * ABSOLUTE, so hashing them made an id depend on where the repo was checked out:
7
+ * the same unchanged file scanned from two directories (two CI runners, two
8
+ * temp dirs, a PR's base and head worktrees) produced two different ids, and
9
+ * anything keying on `id` saw every such finding as new.
10
+ *
11
+ * Every detector that puts a scanned file's path into an id key goes through
12
+ * these helpers, which prefer the scanner-computed repo-relative, forward-slash
13
+ * path. The absolute path is only a fallback for hand-built fixtures that never
14
+ * went through the scanner — it never occurs in a real scan.
15
+ */
16
+ import type { InstructionFile, InstructionSection } from './types.js';
17
+ /** Path to embed in an id key for a scanned file. */
18
+ export declare function fileIdPath(file: Pick<InstructionFile, 'path' | 'relativePath'>): string;
19
+ /** Path to embed in an id key for a section of a scanned file. */
20
+ export declare function sectionIdPath(section: Pick<InstructionSection, 'filePath' | 'relativePath'>): string;
21
+ //# sourceMappingURL=finding-id.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"finding-id.d.ts","sourceRoot":"","sources":["../src/finding-id.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAUtE,qDAAqD;AACrD,wBAAgB,UAAU,CAAC,IAAI,EAAE,IAAI,CAAC,eAAe,EAAE,MAAM,GAAG,cAAc,CAAC,GAAG,MAAM,CAEvF;AAED,kEAAkE;AAClE,wBAAgB,aAAa,CAAC,OAAO,EAAE,IAAI,CAAC,kBAAkB,EAAE,UAAU,GAAG,cAAc,CAAC,GAAG,MAAM,CAEpG"}
@@ -0,0 +1,31 @@
1
+ /**
2
+ * Location-independent path segments for finding-id hash keys.
3
+ *
4
+ * Finding ids are sha1 hashes over a key that usually embeds the file the
5
+ * finding is about. `InstructionFile.path` / `InstructionSection.filePath` are
6
+ * ABSOLUTE, so hashing them made an id depend on where the repo was checked out:
7
+ * the same unchanged file scanned from two directories (two CI runners, two
8
+ * temp dirs, a PR's base and head worktrees) produced two different ids, and
9
+ * anything keying on `id` saw every such finding as new.
10
+ *
11
+ * Every detector that puts a scanned file's path into an id key goes through
12
+ * these helpers, which prefer the scanner-computed repo-relative, forward-slash
13
+ * path. The absolute path is only a fallback for hand-built fixtures that never
14
+ * went through the scanner — it never occurs in a real scan.
15
+ */
16
+ /**
17
+ * Forward slashes only, no leading `./`: the same file must hash the same on
18
+ * Windows and POSIX, whoever computed the relative path.
19
+ */
20
+ function normalizeIdPath(p) {
21
+ return p.replace(/\\/g, '/').replace(/^(?:\.\/)+/, '');
22
+ }
23
+ /** Path to embed in an id key for a scanned file. */
24
+ export function fileIdPath(file) {
25
+ return normalizeIdPath(file.relativePath ?? file.path);
26
+ }
27
+ /** Path to embed in an id key for a section of a scanned file. */
28
+ export function sectionIdPath(section) {
29
+ return normalizeIdPath(section.relativePath ?? section.filePath);
30
+ }
31
+ //# sourceMappingURL=finding-id.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"finding-id.js","sourceRoot":"","sources":["../src/finding-id.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAIH;;;GAGG;AACH,SAAS,eAAe,CAAC,CAAS;IAChC,OAAO,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,YAAY,EAAE,EAAE,CAAC,CAAC;AACzD,CAAC;AAED,qDAAqD;AACrD,MAAM,UAAU,UAAU,CAAC,IAAoD;IAC7E,OAAO,eAAe,CAAC,IAAI,CAAC,YAAY,IAAI,IAAI,CAAC,IAAI,CAAC,CAAC;AACzD,CAAC;AAED,kEAAkE;AAClE,MAAM,UAAU,aAAa,CAAC,OAA8D;IAC1F,OAAO,eAAe,CAAC,OAAO,CAAC,YAAY,IAAI,OAAO,CAAC,QAAQ,CAAC,CAAC;AACnE,CAAC"}
@@ -13,4 +13,15 @@ export declare function resolveSafePath(repoRoot: string, relativeOrAbsolutePath
13
13
  * Returns an array of FileChanges that would be applied.
14
14
  */
15
15
  export declare function applyFixRecipe(issue: PromptCiIssue, repoRoot: string): Promise<FileChange[]>;
16
+ /**
17
+ * True when `promptci fix` may mechanically apply this issue's recipe.
18
+ *
19
+ * Driven by the explicit `autoApplySafe` flag the emitting detector sets — it is
20
+ * deliberately NOT `Boolean(issue.fixRecipe)`. Most `fixRecipe` strings are
21
+ * advisory prose that needs human judgment (stale years, framework/runtime
22
+ * guidance, agent-practices), and auto-applying them would corrupt files. Only
23
+ * the handful of recipes that `applyFixRecipe` implements as a mechanical,
24
+ * reversible edit are marked safe at their source.
25
+ */
26
+ export declare function isRepairable(issue: PromptCiIssue): boolean;
16
27
  //# sourceMappingURL=fix-engine.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"fix-engine.d.ts","sourceRoot":"","sources":["../src/fix-engine.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAEhD,MAAM,WAAW,UAAU;IACzB,QAAQ,EAAE,MAAM,CAAC;IACjB,eAAe,EAAE,MAAM,CAAC;IACxB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,EAAE,sBAAsB,EAAE,MAAM,GAAG,MAAM,CAUxF;AAED;;;GAGG;AACH,wBAAsB,cAAc,CAClC,KAAK,EAAE,aAAa,EACpB,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,UAAU,EAAE,CAAC,CAsLvB"}
1
+ {"version":3,"file":"fix-engine.d.ts","sourceRoot":"","sources":["../src/fix-engine.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAKhD,MAAM,WAAW,UAAU;IACzB,QAAQ,EAAE,MAAM,CAAC;IACjB,eAAe,EAAE,MAAM,CAAC;IACxB,UAAU,EAAE,MAAM,CAAC;CACpB;AAiBD;;GAEG;AACH,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,EAAE,sBAAsB,EAAE,MAAM,GAAG,MAAM,CAUxF;AAED;;;GAGG;AACH,wBAAsB,cAAc,CAClC,KAAK,EAAE,aAAa,EACpB,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,UAAU,EAAE,CAAC,CA+JvB;AAED;;;;;;;;;GASG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,aAAa,GAAG,OAAO,CAE1D"}
@@ -1,5 +1,22 @@
1
1
  import * as path from 'node:path';
2
2
  import * as fs from 'node:fs/promises';
3
+ import { renderPromptCiGitignore } from './promptci-gitignore.js';
4
+ import { isWithinRoot } from './path-containment.js';
5
+ import { gitignoreLineMatchesTarget } from './security-pack.js';
6
+ /**
7
+ * True when an active (non-comment) line of the given .gitignore content
8
+ * already covers `target`, using the same segment-based matching as the
9
+ * security-pack detector. The fix side must agree with the detector: a
10
+ * substring test would let an entry like `mydist/` suppress adding `dist/`
11
+ * even though the detector (correctly) still flags `dist` as unignored.
12
+ */
13
+ function gitignoreCovers(content, target) {
14
+ return content
15
+ .split(/\r?\n/)
16
+ .map((l) => l.trim())
17
+ .filter((l) => l && !l.startsWith('#'))
18
+ .some((line) => gitignoreLineMatchesTarget(line, target));
19
+ }
3
20
  /**
4
21
  * Validates and resolves a path relative to the repo root to prevent path traversal.
5
22
  */
@@ -8,7 +25,7 @@ export function resolveSafePath(repoRoot, relativeOrAbsolutePath) {
8
25
  const resolvedPath = path.isAbsolute(relativeOrAbsolutePath)
9
26
  ? path.resolve(relativeOrAbsolutePath)
10
27
  : path.resolve(resolvedRoot, relativeOrAbsolutePath);
11
- if (!resolvedPath.startsWith(resolvedRoot)) {
28
+ if (!isWithinRoot(resolvedRoot, resolvedPath)) {
12
29
  throw new Error(`Path traversal detected: "${relativeOrAbsolutePath}" is outside repo root "${resolvedRoot}"`);
13
30
  }
14
31
  return resolvedPath;
@@ -29,11 +46,14 @@ export async function applyFixRecipe(issue, repoRoot) {
29
46
  catch {
30
47
  // file doesn't exist, which is fine
31
48
  }
32
- if (!content.includes('.promptci/')) {
49
+ if (!gitignoreCovers(content, '.promptci')) {
33
50
  const lineEnding = content.includes('\r\n') ? '\r\n' : '\n';
51
+ // BUG-7: write the baseline-preserving stanza, not a bare `.promptci/`
52
+ // — the latter also ignores baseline.json and breaks the CI ratchet.
53
+ const block = renderPromptCiGitignore(lineEnding);
34
54
  const suffix = content.endsWith('\n') || content.endsWith('\r')
35
- ? `.promptci/${lineEnding}`
36
- : `${lineEnding}.promptci/${lineEnding}`;
55
+ ? block
56
+ : `${lineEnding}${block}`;
37
57
  changes.push({
38
58
  filePath: gitignorePath,
39
59
  originalContent: content,
@@ -58,7 +78,7 @@ export async function applyFixRecipe(issue, repoRoot) {
58
78
  const m = /Directory "([^"]+)" exists/.exec(ev);
59
79
  if (m && m[1]) {
60
80
  const dirName = m[1];
61
- if (!content.includes(`${dirName}/`)) {
81
+ if (!gitignoreCovers(content, dirName)) {
62
82
  newLines += `${dirName}/${lineEnding}`;
63
83
  }
64
84
  }
@@ -75,45 +95,22 @@ export async function applyFixRecipe(issue, repoRoot) {
75
95
  }
76
96
  return changes;
77
97
  }
78
- // 3. Outdated Stale Year Replacement (2019-2023 -> 2026)
98
+ // 3. Stale years are intentionally NOT auto-fixable.
99
+ //
100
+ // BUG-14: this branch used to rewrite every year matching a hardcoded
101
+ // 2019–2023 alternation to the literal string '2026' across the whole
102
+ // flagged section. Three problems, any one of which is disqualifying:
103
+ // - the source range and the replacement year were both hardcoded, so the
104
+ // recipe was wrong from Jan 1 2027 onward;
105
+ // - the range disagreed with the detector's own (2019–2025), so the fixer
106
+ // silently skipped most of what the detector flagged; and
107
+ // - a bare year substitution cannot tell a stale instruction from a
108
+ // copyright line, a release date, or a version pin — it rewrote
109
+ // "© 2021", "shipped in 2020", and "the 2022 spec" alike.
110
+ //
111
+ // The finding now carries an advisory `fixRecipe` string instead (see
112
+ // stale-instructions.ts) and produces no automated edit.
79
113
  if (issue.id.startsWith('stale-') && issue.category === 'stale_instruction') {
80
- const STALE_YEAR_RE = /(?<![/-])\b(2019|2020|2021|2022|2023)\b(?![/-])/g;
81
- // Check if this issue is specifically about stale years
82
- const hasYearEvidence = issue.evidence.some(ev => ev.includes('Year reference(s) that may be outdated'));
83
- if (hasYearEvidence && issue.locations.length > 0) {
84
- const loc = issue.locations[0];
85
- const filePath = resolveSafePath(repoRoot, loc.filePath);
86
- let content = '';
87
- try {
88
- content = await fs.readFile(filePath, 'utf-8');
89
- }
90
- catch {
91
- return [];
92
- }
93
- const lines = content.split(/\r?\n/);
94
- const hasCRLF = content.includes('\r\n');
95
- const lineEnding = hasCRLF ? '\r\n' : '\n';
96
- const startIdx = (loc.startLine ?? 1) - 1;
97
- const endIdx = (loc.endLine ?? lines.length) - 1;
98
- let modified = false;
99
- for (let i = startIdx; i <= endIdx; i++) {
100
- if (i >= 0 && i < lines.length) {
101
- const original = lines[i];
102
- const updated = original.replace(STALE_YEAR_RE, '2026');
103
- if (updated !== original) {
104
- lines[i] = updated;
105
- modified = true;
106
- }
107
- }
108
- }
109
- if (modified) {
110
- changes.push({
111
- filePath,
112
- originalContent: content,
113
- newContent: lines.join(lineEnding),
114
- });
115
- }
116
- }
117
114
  return changes;
118
115
  }
119
116
  // 4. Duplicate Markdown Section Consolidation
@@ -125,12 +122,22 @@ export async function applyFixRecipe(issue, repoRoot) {
125
122
  }
126
123
  const canonicalPath = resolveSafePath(repoRoot, canonicalLoc.filePath);
127
124
  const canonicalBase = path.basename(canonicalPath);
128
- // 4b. In all other files containing duplicates, replace the section body with a pointer link
125
+ // 4b. Group the non-canonical locations by file. A single file can contain
126
+ // the duplicated section more than once; computing one FileChange per
127
+ // location from the original content and writing them in sequence would
128
+ // clobber all but the last, so each file is rewritten exactly once with
129
+ // every one of its duplicate ranges replaced (BUG: same-file collision).
130
+ const byFile = new Map();
129
131
  for (const loc of issue.locations) {
130
132
  const filePath = resolveSafePath(repoRoot, loc.filePath);
131
133
  if (filePath === canonicalPath)
132
134
  continue; // skip canonical file
133
- let content = '';
135
+ const list = byFile.get(filePath) ?? [];
136
+ list.push(loc);
137
+ byFile.set(filePath, list);
138
+ }
139
+ for (const [filePath, locs] of byFile) {
140
+ let content;
134
141
  try {
135
142
  content = await fs.readFile(filePath, 'utf-8');
136
143
  }
@@ -138,42 +145,52 @@ export async function applyFixRecipe(issue, repoRoot) {
138
145
  continue;
139
146
  }
140
147
  const lines = content.split(/\r?\n/);
141
- const hasCRLF = content.includes('\r\n');
142
- const lineEnding = hasCRLF ? '\r\n' : '\n';
143
- const startIdx = (loc.startLine ?? 1) - 1;
144
- const endIdx = (loc.endLine ?? lines.length) - 1;
145
- // Find relative path from current file to canonical file for clean Markdown links
148
+ const lineEnding = content.includes('\r\n') ? '\r\n' : '\n';
149
+ // Relative path from this file to the canonical file for a clean link.
146
150
  const relPath = path.relative(path.dirname(filePath), canonicalPath).replace(/\\/g, '/');
147
151
  const linkTarget = relPath.startsWith('.') ? relPath : `./${relPath}`;
148
- // Extract the section lines
149
- const sectionLines = lines.slice(startIdx, endIdx + 1);
150
- let headingLine = '';
151
- let replaceStartIdx = startIdx;
152
- // Check if the section starts with a heading line (e.g. "## Deployment")
153
- // If so, we preserve the heading and replace only the body below it.
154
- if (sectionLines.length > 0 && sectionLines[0].trim().startsWith('#')) {
155
- headingLine = sectionLines[0];
156
- replaceStartIdx = startIdx + 1;
157
- }
158
152
  const pointerText = `See canonical instructions in [${canonicalBase}](${linkTarget}) for details.`;
159
- // Construct the new lines
160
- const prefixLines = lines.slice(0, replaceStartIdx);
161
- const suffixLines = lines.slice(endIdx + 1);
162
- let newSectionContent;
163
- if (headingLine) {
164
- newSectionContent = [pointerText];
165
- }
166
- else {
167
- newSectionContent = [pointerText];
153
+ // Replace each duplicate range bottom-up so an earlier (higher-line)
154
+ // replacement never shifts the indices of ranges still to be processed.
155
+ const ranges = locs
156
+ .map(loc => ({
157
+ startIdx: (loc.startLine ?? 1) - 1,
158
+ endIdx: (loc.endLine ?? lines.length) - 1,
159
+ }))
160
+ .sort((a, b) => b.startIdx - a.startIdx);
161
+ let working = lines;
162
+ for (const { startIdx, endIdx } of ranges) {
163
+ const sectionLines = working.slice(startIdx, endIdx + 1);
164
+ // Preserve a leading heading line (e.g. "## Deployment") and replace
165
+ // only the body below it; otherwise replace the whole range.
166
+ const hasHeading = sectionLines.length > 0 && sectionLines[0].trim().startsWith('#');
167
+ const replaceStartIdx = hasHeading ? startIdx + 1 : startIdx;
168
+ working = [
169
+ ...working.slice(0, replaceStartIdx),
170
+ pointerText,
171
+ ...working.slice(endIdx + 1),
172
+ ];
168
173
  }
169
- const finalLines = [...prefixLines, ...newSectionContent, ...suffixLines];
170
174
  changes.push({
171
175
  filePath,
172
176
  originalContent: content,
173
- newContent: finalLines.join(lineEnding),
177
+ newContent: working.join(lineEnding),
174
178
  });
175
179
  }
176
180
  }
177
181
  return changes;
178
182
  }
183
+ /**
184
+ * True when `promptci fix` may mechanically apply this issue's recipe.
185
+ *
186
+ * Driven by the explicit `autoApplySafe` flag the emitting detector sets — it is
187
+ * deliberately NOT `Boolean(issue.fixRecipe)`. Most `fixRecipe` strings are
188
+ * advisory prose that needs human judgment (stale years, framework/runtime
189
+ * guidance, agent-practices), and auto-applying them would corrupt files. Only
190
+ * the handful of recipes that `applyFixRecipe` implements as a mechanical,
191
+ * reversible edit are marked safe at their source.
192
+ */
193
+ export function isRepairable(issue) {
194
+ return issue.autoApplySafe === true;
195
+ }
179
196
  //# sourceMappingURL=fix-engine.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"fix-engine.js","sourceRoot":"","sources":["../src/fix-engine.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"fix-engine.js","sourceRoot":"","sources":["../src/fix-engine.ts"],"names":[],"mappings":"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"}
@@ -1,5 +1,5 @@
1
- import * as path from 'node:path';
2
1
  import * as fs from 'node:fs';
2
+ import { readTextWithinRoot } from '../ai-config.js';
3
3
  export function detectDotnet(context) {
4
4
  const issues = [];
5
5
  const { repoRoot, files } = context;
@@ -43,7 +43,7 @@ export function detectDotnet(context) {
43
43
  const rootFiles = fs.readdirSync(repoRoot);
44
44
  const csprojFile = rootFiles.find(f => f.endsWith('.csproj'));
45
45
  if (csprojFile) {
46
- const csprojContent = fs.readFileSync(path.join(repoRoot, csprojFile), 'utf-8');
46
+ const csprojContent = readTextWithinRoot(repoRoot, csprojFile) ?? '';
47
47
  const match = /<TargetFramework>(.*?)<\/TargetFramework>/.exec(csprojContent);
48
48
  if (match) {
49
49
  targetFramework = match[1]?.trim();
@@ -1 +1 @@
1
- {"version":3,"file":"dotnet.js","sourceRoot":"","sources":["../../src/frameworks/dotnet.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"dotnet.js","sourceRoot":"","sources":["../../src/frameworks/dotnet.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC;AAC9B,OAAO,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AAErD,MAAM,UAAU,YAAY,CAAC,OAAoB;IAC/C,MAAM,MAAM,GAAoB,EAAE,CAAC;IACnC,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE,GAAG,OAAO,CAAC;IAEpC,2BAA2B;IAC3B,IAAI,SAAS,GAAG,OAAO,CAAC,WAAW,KAAK,QAAQ,CAAC;IACjD,IAAI,CAAC,SAAS,EAAE,CAAC;QACf,IAAI,CAAC;YACH,SAAS,GAAG,EAAE,CAAC,WAAW,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC,CAAC;QAC9F,CAAC;QAAC,MAAM,CAAC;YACP,SAAS;QACX,CAAC;IACH,CAAC;IAED,MAAM,eAAe,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC7D,MAAM,iBAAiB,GAAG,+DAA+D,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;IAEhH,IAAI,CAAC,SAAS,IAAI,CAAC,iBAAiB,EAAE,CAAC;QACrC,OAAO,EAAE,CAAC;IACZ,CAAC;IAED,MAAM,YAAY,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;IAE5C,mDAAmD;IACnD,MAAM,iBAAiB,GAAG,oCAAoC,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;IACrF,IAAI,CAAC,iBAAiB,EAAE,CAAC;QACvB,MAAM,CAAC,IAAI,CAAC;YACV,EAAE,EAAE,oCAAoC;YACxC,QAAQ,EAAE,SAAS;YACnB,QAAQ,EAAE,WAAW;YACrB,KAAK,EAAE,kCAAkC;YACzC,OAAO,EAAE,yHAAyH;YAClI,SAAS,EAAE,YAAY;YACvB,SAAS,EAAE,EAAE;YACb,QAAQ,EAAE,CAAC,yEAAyE,CAAC;YACrF,cAAc,EAAE,+FAA+F;YAC/G,SAAS,EAAE,oFAAoF;YAC/F,UAAU,EAAE,IAAI;SACjB,CAAC,CAAC;IACL,CAAC;IAED,qDAAqD;IACrD,8DAA8D;IAC9D,IAAI,eAAmC,CAAC;IACxC,IAAI,CAAC;QACH,MAAM,SAAS,GAAG,EAAE,CAAC,WAAW,CAAC,QAAQ,CAAC,CAAC;QAC3C,MAAM,UAAU,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC,CAAC;QAC9D,IAAI,UAAU,EAAE,CAAC;YACf,MAAM,aAAa,GAAG,kBAAkB,CAAC,QAAQ,EAAE,UAAU,CAAC,IAAI,EAAE,CAAC;YACrE,MAAM,KAAK,GAAG,2CAA2C,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;YAC9E,IAAI,KAAK,EAAE,CAAC;gBACV,eAAe,GAAG,KAAK,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC;YACrC,CAAC;QACH,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACP,SAAS;IACX,CAAC;IAED,IAAI,eAAe,EAAE,CAAC;QACpB,MAAM,iBAAiB,GAAG,2CAA2C,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;QAC5F,MAAM,eAAe,GAAG,2BAA2B,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;QAC1E,IAAI,eAAe,IAAI,iBAAiB,EAAE,CAAC;YACzC,MAAM,CAAC,IAAI,CAAC;gBACV,EAAE,EAAE,qCAAqC;gBACzC,QAAQ,EAAE,SAAS;gBACnB,QAAQ,EAAE,mBAAmB;gBAC7B,KAAK,EAAE,mCAAmC;gBAC1C,OAAO,EAAE,oCAAoC,eAAe,uFAAuF;gBACnJ,SAAS,EAAE,YAAY;gBACvB,SAAS,EAAE,EAAE;gBACb,QAAQ,EAAE,CAAC,mBAAmB,eAAe,wDAAwD,CAAC;gBACtG,cAAc,EAAE,0EAA0E,eAAe,IAAI;gBAC7G,SAAS,EAAE,eAAe,eAAe,uFAAuF;gBAChI,UAAU,EAAE,GAAG;aAChB,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"python.d.ts","sourceRoot":"","sources":["../../src/frameworks/python.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAIjD,wBAAgB,YAAY,CAAC,OAAO,EAAE,WAAW,GAAG,aAAa,EAAE,CAkElE"}
1
+ {"version":3,"file":"python.d.ts","sourceRoot":"","sources":["../../src/frameworks/python.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAIjD,wBAAgB,YAAY,CAAC,OAAO,EAAE,WAAW,GAAG,aAAa,EAAE,CAqElE"}
@@ -4,7 +4,10 @@ export function detectPython(context) {
4
4
  const issues = [];
5
5
  const { manifests, repoRoot, files } = context;
6
6
  const hasPyProject = !!manifests.pyproject;
7
- const hasRequirements = fs.existsSync(path.join(repoRoot, 'requirements.txt'));
7
+ // BUG-004: requirements.txt content is read once, asynchronously, while the
8
+ // RepoContext is built — the detector must not do synchronous disk I/O inside
9
+ // the scan pipeline. Presence is derived from that captured content.
10
+ const hasRequirements = manifests.requirements !== undefined;
8
11
  const hasPipfile = fs.existsSync(path.join(repoRoot, 'Pipfile'));
9
12
  const hasCondaYaml = fs.existsSync(path.join(repoRoot, 'environment.yml'));
10
13
  if (!hasPyProject && !hasRequirements && !hasPipfile && !hasCondaYaml) {
@@ -12,7 +15,7 @@ export function detectPython(context) {
12
15
  }
13
16
  // Check for missing pytest guidance if pytest is in deps
14
17
  const isPytestInDeps = (manifests.pyproject?.includes('pytest') ||
15
- (hasRequirements && fs.readFileSync(path.join(repoRoot, 'requirements.txt'), 'utf-8').includes('pytest')));
18
+ manifests.requirements?.includes('pytest'));
16
19
  if (isPytestInDeps) {
17
20
  const hasPytestGuidance = files.some(file => file.content.toLowerCase().includes('pytest') ||
18
21
  file.content.toLowerCase().includes('test guidance'));
@@ -1 +1 @@
1
- {"version":3,"file":"python.js","sourceRoot":"","sources":["../../src/frameworks/python.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"python.js","sourceRoot":"","sources":["../../src/frameworks/python.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"rust.d.ts","sourceRoot":"","sources":["../../src/frameworks/rust.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAIjD,wBAAgB,UAAU,CAAC,OAAO,EAAE,WAAW,GAAG,aAAa,EAAE,CA0EhE"}
1
+ {"version":3,"file":"rust.d.ts","sourceRoot":"","sources":["../../src/frameworks/rust.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAKjD,wBAAgB,UAAU,CAAC,OAAO,EAAE,WAAW,GAAG,aAAa,EAAE,CA0EhE"}
@@ -1,5 +1,6 @@
1
1
  import * as path from 'node:path';
2
2
  import * as fs from 'node:fs';
3
+ import { readTextWithinRoot } from '../ai-config.js';
3
4
  export function detectRust(context) {
4
5
  const issues = [];
5
6
  const { repoRoot, files } = context;
@@ -31,7 +32,7 @@ export function detectRust(context) {
31
32
  let rustVersion;
32
33
  if (hasCargoToml) {
33
34
  try {
34
- const cargoContent = fs.readFileSync(path.join(repoRoot, 'Cargo.toml'), 'utf-8');
35
+ const cargoContent = readTextWithinRoot(repoRoot, 'Cargo.toml') ?? '';
35
36
  const match = /^rust-version\s*=\s*["'](.*?)["']/m.exec(cargoContent);
36
37
  if (match) {
37
38
  rustVersion = match[1]?.trim();
@@ -1 +1 @@
1
- {"version":3,"file":"rust.js","sourceRoot":"","sources":["../../src/frameworks/rust.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"rust.js","sourceRoot":"","sources":["../../src/frameworks/rust.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,30 @@
1
+ /**
2
+ * Does git say a path is a symlink?
3
+ *
4
+ * A checkout without symlink support (Windows without `core.symlinks`) writes a
5
+ * committed link as a small regular file holding the target path. The scanner
6
+ * only treats such a file as a link when the repository itself says it is one,
7
+ * so a hand-written one-line pointer file stays a real file:
8
+ *
9
+ * 1. the index (`.git/index`, versions 2 and 3) records the path with mode
10
+ * 120000 — authoritative when it can be read: the path is a link exactly
11
+ * when its entry has that mode;
12
+ * 2. otherwise the repository's own config has `core.symlinks = false` (the
13
+ * setting git writes at clone time on a filesystem that cannot link). The
14
+ * global and system config are deliberately not consulted: they say what a
15
+ * clone would do, not what this checkout is.
16
+ *
17
+ * Read-only, no git binary, no network. Anything unreadable or unrecognised
18
+ * answers "no".
19
+ */
20
+ /** `core.symlinks` from a git config file's text: false only when the last value says so. */
21
+ export declare function configDisablesSymlinks(config: string): boolean;
22
+ /** The paths of a git index (versions 2 and 3) whose entry mode is a symlink; undefined when unreadable or another version. */
23
+ export declare function symlinkPathsInIndex(index: Buffer): Set<string> | undefined;
24
+ export type GitSymlinkOracle = {
25
+ /** Whether git says the file at `scanRelativePath` (relative to the scan root, POSIX) is a symlink. */
26
+ isSymlink(scanRelativePath: string): boolean;
27
+ };
28
+ /** Built lazily by the caller: nothing is read until the first question. */
29
+ export declare function createGitSymlinkOracle(scanRoot: string): GitSymlinkOracle;
30
+ //# sourceMappingURL=git-symlinks.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"git-symlinks.d.ts","sourceRoot":"","sources":["../src/git-symlinks.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AA6CH,6FAA6F;AAC7F,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAe9D;AAED,+HAA+H;AAC/H,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC,GAAG,SAAS,CAyB1E;AAED,MAAM,MAAM,gBAAgB,GAAG;IAC7B,uGAAuG;IACvG,SAAS,CAAC,gBAAgB,EAAE,MAAM,GAAG,OAAO,CAAC;CAC9C,CAAC;AAEF,4EAA4E;AAC5E,wBAAgB,sBAAsB,CAAC,QAAQ,EAAE,MAAM,GAAG,gBAAgB,CAsCzE"}