infraweaver 0.1.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 (524) hide show
  1. package/LICENSE +661 -0
  2. package/README.md +244 -0
  3. package/dist/agents/claude.d.ts +113 -0
  4. package/dist/agents/claudePretoolGate.d.ts +137 -0
  5. package/dist/agents/dispatchMetrics.d.ts +77 -0
  6. package/dist/agents/gateServer.d.ts +7 -0
  7. package/dist/agents/index.d.ts +6 -0
  8. package/dist/agents/nativeFsDenies.d.ts +46 -0
  9. package/dist/agents/opencode.d.ts +284 -0
  10. package/dist/agents/opencodePlugin.d.ts +96 -0
  11. package/dist/agents/opencodeShared.d.ts +40 -0
  12. package/dist/agents/postRun.d.ts +126 -0
  13. package/dist/agents/reviewer.d.ts +41 -0
  14. package/dist/agents/sessionLabeler.d.ts +97 -0
  15. package/dist/agents/shared.d.ts +246 -0
  16. package/dist/agents/subagentModels.d.ts +19 -0
  17. package/dist/agents/tokenQuota.d.ts +118 -0
  18. package/dist/agents/writeGateSource.d.ts +22 -0
  19. package/dist/agents/writePolicy.d.ts +79 -0
  20. package/dist/brand.d.ts +67 -0
  21. package/dist/cli.mjs +247846 -0
  22. package/dist/external.d.ts +227 -0
  23. package/dist/i18n/scaffolding.d.ts +59 -0
  24. package/dist/index.d.ts +6 -0
  25. package/dist/index.js +247061 -0
  26. package/dist/internal/index.d.ts +18 -0
  27. package/dist/internal.js +2398 -0
  28. package/dist/lifecycle.d.ts +2 -0
  29. package/dist/main.d.ts +8 -0
  30. package/dist/mcp/arkConfig.d.ts +1 -0
  31. package/dist/mcp/assess.d.ts +157 -0
  32. package/dist/mcp/capabilityContext.d.ts +71 -0
  33. package/dist/mcp/changeSummary.d.ts +52 -0
  34. package/dist/mcp/checkSuite.d.ts +27 -0
  35. package/dist/mcp/checkout.d.ts +92 -0
  36. package/dist/mcp/comment.d.ts +127 -0
  37. package/dist/mcp/commitInfo.d.ts +11 -0
  38. package/dist/mcp/crosswalk.d.ts +178 -0
  39. package/dist/mcp/crosswalkDigest.d.ts +1 -0
  40. package/dist/mcp/cyberEssentials.d.ts +24 -0
  41. package/dist/mcp/dashboard.d.ts +125 -0
  42. package/dist/mcp/dependencies.d.ts +12 -0
  43. package/dist/mcp/frameworks.d.ts +74 -0
  44. package/dist/mcp/geminiSanitizer.d.ts +28 -0
  45. package/dist/mcp/git.d.ts +60 -0
  46. package/dist/mcp/guardrails.d.ts +222 -0
  47. package/dist/mcp/issue.d.ts +20 -0
  48. package/dist/mcp/issueComments.d.ts +11 -0
  49. package/dist/mcp/issueEvents.d.ts +11 -0
  50. package/dist/mcp/issueInfo.d.ts +11 -0
  51. package/dist/mcp/labels.d.ts +14 -0
  52. package/dist/mcp/localContext.d.ts +26 -0
  53. package/dist/mcp/moduleExtraction.d.ts +79 -0
  54. package/dist/mcp/moduleTests.d.ts +106 -0
  55. package/dist/mcp/modules.d.ts +198 -0
  56. package/dist/mcp/output.d.ts +16 -0
  57. package/dist/mcp/pathSafety.d.ts +14 -0
  58. package/dist/mcp/policy.d.ts +50 -0
  59. package/dist/mcp/pr.d.ts +64 -0
  60. package/dist/mcp/prInfo.d.ts +11 -0
  61. package/dist/mcp/providerSchema.d.ts +52 -0
  62. package/dist/mcp/review.d.ts +212 -0
  63. package/dist/mcp/reviewComments.d.ts +245 -0
  64. package/dist/mcp/roots.d.ts +60 -0
  65. package/dist/mcp/scope.d.ts +26 -0
  66. package/dist/mcp/selectMode.d.ts +20 -0
  67. package/dist/mcp/server.d.ts +61 -0
  68. package/dist/mcp/shared.d.ts +62 -0
  69. package/dist/mcp/shell.d.ts +58 -0
  70. package/dist/mcp/staleFix.d.ts +138 -0
  71. package/dist/mcp/terraform/azurePrices.d.ts +8 -0
  72. package/dist/mcp/terraform/baseline.d.ts +57 -0
  73. package/dist/mcp/terraform/concernResult.d.ts +38 -0
  74. package/dist/mcp/terraform/cost.d.ts +55 -0
  75. package/dist/mcp/terraform/cspm.d.ts +80 -0
  76. package/dist/mcp/terraform/currency.d.ts +110 -0
  77. package/dist/mcp/terraform/decisions.d.ts +178 -0
  78. package/dist/mcp/terraform/eidas.d.ts +100 -0
  79. package/dist/mcp/terraform/evidence.d.ts +343 -0
  80. package/dist/mcp/terraform/findings.d.ts +76 -0
  81. package/dist/mcp/terraform/fixMemory.d.ts +81 -0
  82. package/dist/mcp/terraform/governance.d.ts +56 -0
  83. package/dist/mcp/terraform/hcl.d.ts +115 -0
  84. package/dist/mcp/terraform/iacLanguages.d.ts +120 -0
  85. package/dist/mcp/terraform/idleFloor.d.ts +78 -0
  86. package/dist/mcp/terraform/keyless.d.ts +68 -0
  87. package/dist/mcp/terraform/moduleDocs.d.ts +56 -0
  88. package/dist/mcp/terraform/nativeRules.d.ts +38 -0
  89. package/dist/mcp/terraform/nativeScan.d.ts +11 -0
  90. package/dist/mcp/terraform/noiseProfile.d.ts +100 -0
  91. package/dist/mcp/terraform/normalization.d.ts +52 -0
  92. package/dist/mcp/terraform/oscal.d.ts +103 -0
  93. package/dist/mcp/terraform/packs/azurerm-3-4.d.ts +2 -0
  94. package/dist/mcp/terraform/packs/cloudflare-4-5.d.ts +2 -0
  95. package/dist/mcp/terraform/paths.d.ts +28 -0
  96. package/dist/mcp/terraform/plan.d.ts +157 -0
  97. package/dist/mcp/terraform/planDrift.d.ts +199 -0
  98. package/dist/mcp/terraform/policyAuthor.d.ts +191 -0
  99. package/dist/mcp/terraform/prowlerOcsf.d.ts +136 -0
  100. package/dist/mcp/terraform/refactor.d.ts +183 -0
  101. package/dist/mcp/terraform/registry.d.ts +108 -0
  102. package/dist/mcp/terraform/risk.d.ts +41 -0
  103. package/dist/mcp/terraform/scanSession.d.ts +116 -0
  104. package/dist/mcp/terraform/scannerCache.d.ts +15 -0
  105. package/dist/mcp/terraform/scannerEgress.d.ts +72 -0
  106. package/dist/mcp/terraform/scannerJson.d.ts +13 -0
  107. package/dist/mcp/terraform/scanners.d.ts +205 -0
  108. package/dist/mcp/terraform/signing.d.ts +61 -0
  109. package/dist/mcp/terraform/stateLocking.d.ts +18 -0
  110. package/dist/mcp/terraform/subprocess.d.ts +43 -0
  111. package/dist/mcp/terraform/suppressions.d.ts +90 -0
  112. package/dist/mcp/terraform/taxonomy.d.ts +39 -0
  113. package/dist/mcp/terraform/tfquery.d.ts +47 -0
  114. package/dist/mcp/terraform/toolchainIntegrity.d.ts +82 -0
  115. package/dist/mcp/terraform/tools/authorPolicy.d.ts +59 -0
  116. package/dist/mcp/terraform/tools/detectPlanDrift.d.ts +20 -0
  117. package/dist/mcp/terraform/tools/emitCost.d.ts +11 -0
  118. package/dist/mcp/terraform/tools/emitSarif.d.ts +14 -0
  119. package/dist/mcp/terraform/tools/fixMemory.d.ts +19 -0
  120. package/dist/mcp/terraform/tools/infracostDiff.d.ts +22 -0
  121. package/dist/mcp/terraform/tools/ingestExternalFindings.d.ts +21 -0
  122. package/dist/mcp/terraform/tools/moduleLookup.d.ts +14 -0
  123. package/dist/mcp/terraform/tools/moduleSearch.d.ts +23 -0
  124. package/dist/mcp/terraform/tools/plan.d.ts +59 -0
  125. package/dist/mcp/terraform/tools/providerUpgrade.d.ts +55 -0
  126. package/dist/mcp/terraform/tools/readFindings.d.ts +17 -0
  127. package/dist/mcp/terraform/tools/scan.d.ts +114 -0
  128. package/dist/mcp/terraform/tools/validate.d.ts +31 -0
  129. package/dist/mcp/terraform/tools/verifyRemediation.d.ts +31 -0
  130. package/dist/mcp/terraform/tools/versionCurrency.d.ts +5 -0
  131. package/dist/mcp/terraform/tools.d.ts +16 -0
  132. package/dist/mcp/terraform/transformPacks.d.ts +267 -0
  133. package/dist/mcp/terraform/types.d.ts +226 -0
  134. package/dist/mcp/terraform/verification.d.ts +81 -0
  135. package/dist/mcp/terraform/vex.d.ts +115 -0
  136. package/dist/mcp/terraform/writeOnly.d.ts +67 -0
  137. package/dist/mcp/terraform.d.ts +51 -0
  138. package/dist/mcp/terratest.d.ts +85 -0
  139. package/dist/mcp/untrustedContent.d.ts +76 -0
  140. package/dist/mcp/upload.d.ts +8 -0
  141. package/dist/models.d.ts +181 -0
  142. package/dist/modes/address-reviews.d.ts +2 -0
  143. package/dist/modes/assess.d.ts +2 -0
  144. package/dist/modes/build.d.ts +2 -0
  145. package/dist/modes/compliance-audit.d.ts +2 -0
  146. package/dist/modes/cost-optimization.d.ts +2 -0
  147. package/dist/modes/drift-detect.d.ts +2 -0
  148. package/dist/modes/fix.d.ts +2 -0
  149. package/dist/modes/incremental-review.d.ts +2 -0
  150. package/dist/modes/index.d.ts +24 -0
  151. package/dist/modes/modernize-deprecated.d.ts +2 -0
  152. package/dist/modes/plan.d.ts +2 -0
  153. package/dist/modes/policy-gate.d.ts +2 -0
  154. package/dist/modes/prFormats.d.ts +3 -0
  155. package/dist/modes/refactor.d.ts +2 -0
  156. package/dist/modes/refresh-remediation.d.ts +2 -0
  157. package/dist/modes/remediate-and-refactor.d.ts +2 -0
  158. package/dist/modes/remediate.d.ts +2 -0
  159. package/dist/modes/resolve-conflicts.d.ts +2 -0
  160. package/dist/modes/review.d.ts +2 -0
  161. package/dist/modes/summarize-pr.d.ts +2 -0
  162. package/dist/modes/task.d.ts +2 -0
  163. package/dist/modes/terraform-code-review.d.ts +2 -0
  164. package/dist/modes/types.d.ts +9 -0
  165. package/dist/modes/update-dependencies.d.ts +2 -0
  166. package/dist/prep/index.d.ts +7 -0
  167. package/dist/prep/installNodeDependencies.d.ts +2 -0
  168. package/dist/prep/installPythonDependencies.d.ts +2 -0
  169. package/dist/prep/types.d.ts +31 -0
  170. package/dist/reviewQuality.d.ts +107 -0
  171. package/dist/skills/terraform-best-practices/SKILL.md +379 -0
  172. package/dist/toolState.d.ts +123 -0
  173. package/dist/utils/activity.d.ts +40 -0
  174. package/dist/utils/agent.d.ts +47 -0
  175. package/dist/utils/agentHangReport.d.ts +38 -0
  176. package/dist/utils/annotations.d.ts +17 -0
  177. package/dist/utils/apiFetch.d.ts +11 -0
  178. package/dist/utils/apiKeys.d.ts +48 -0
  179. package/dist/utils/apiUrl.d.ts +28 -0
  180. package/dist/utils/assets.d.ts +8 -0
  181. package/dist/utils/baseRefConfig.d.ts +121 -0
  182. package/dist/utils/billingErrors.d.ts +85 -0
  183. package/dist/utils/body.d.ts +34 -0
  184. package/dist/utils/buildInfraweaverFooter.d.ts +29 -0
  185. package/dist/utils/byokFallback.d.ts +85 -0
  186. package/dist/utils/changeImpact.d.ts +101 -0
  187. package/dist/utils/claudeSubscription.d.ts +30 -0
  188. package/dist/utils/cli.d.ts +10 -0
  189. package/dist/utils/cloudClient.d.ts +33 -0
  190. package/dist/utils/cloudFetchCore.d.ts +42 -0
  191. package/dist/utils/cloudReport.d.ts +114 -0
  192. package/dist/utils/codexHome.d.ts +29 -0
  193. package/dist/utils/codexOAuth.d.ts +60 -0
  194. package/dist/utils/diffCoverage.d.ts +63 -0
  195. package/dist/utils/env.d.ts +46 -0
  196. package/dist/utils/errorReport.d.ts +17 -0
  197. package/dist/utils/exitHandler.d.ts +8 -0
  198. package/dist/utils/fixDoubleEscapedString.d.ts +1 -0
  199. package/dist/utils/gitAuth.d.ts +84 -0
  200. package/dist/utils/gitAuthServer.d.ts +24 -0
  201. package/dist/utils/github.d.ts +104 -0
  202. package/dist/utils/globals.d.ts +3 -0
  203. package/dist/utils/infraweaverConfig.d.ts +56 -0
  204. package/dist/utils/install.d.ts +37 -0
  205. package/dist/utils/instructions.d.ts +48 -0
  206. package/dist/utils/keylessOidc.d.ts +28 -0
  207. package/dist/utils/leapingComment.d.ts +11 -0
  208. package/dist/utils/learnings.d.ts +62 -0
  209. package/dist/utils/learningsTruncate.d.ts +25 -0
  210. package/dist/utils/lifecycle.d.ts +57 -0
  211. package/dist/utils/log.d.ts +111 -0
  212. package/dist/utils/modelResolver.d.ts +63 -0
  213. package/dist/utils/moduleFetch.d.ts +39 -0
  214. package/dist/utils/normalizeEnv.d.ts +30 -0
  215. package/dist/utils/openCodeModels.d.ts +11 -0
  216. package/dist/utils/openaiCompatible.d.ts +26 -0
  217. package/dist/utils/opentofuMcp.d.ts +50 -0
  218. package/dist/utils/overrides.d.ts +40 -0
  219. package/dist/utils/packageManager.d.ts +49 -0
  220. package/dist/utils/patchWorkflowRunFields.d.ts +29 -0
  221. package/dist/utils/payload.d.ts +249 -0
  222. package/dist/utils/prSummary.d.ts +61 -0
  223. package/dist/utils/presets.d.ts +36 -0
  224. package/dist/utils/progressComment.d.ts +146 -0
  225. package/dist/utils/providerErrors.d.ts +31 -0
  226. package/dist/utils/proxyModel.d.ts +76 -0
  227. package/dist/utils/rangeDiff.d.ts +51 -0
  228. package/dist/utils/redact.d.ts +33 -0
  229. package/dist/utils/registryAuth.d.ts +52 -0
  230. package/dist/utils/remediationCommand.d.ts +58 -0
  231. package/dist/utils/retry.d.ts +38 -0
  232. package/dist/utils/reviewCleanup.d.ts +14 -0
  233. package/dist/utils/run.d.ts +9 -0
  234. package/dist/utils/runContext.d.ts +112 -0
  235. package/dist/utils/runContextData.d.ts +42 -0
  236. package/dist/utils/runErrorRenderer.d.ts +64 -0
  237. package/dist/utils/runLifecycle.d.ts +89 -0
  238. package/dist/utils/runStartupLog.d.ts +15 -0
  239. package/dist/utils/secrets.d.ts +34 -0
  240. package/dist/utils/setup.d.ts +90 -0
  241. package/dist/utils/shell.d.ts +44 -0
  242. package/dist/utils/skills.d.ts +10 -0
  243. package/dist/utils/subprocess.d.ts +81 -0
  244. package/dist/utils/terraformMcp.d.ts +46 -0
  245. package/dist/utils/time.d.ts +15 -0
  246. package/dist/utils/timer.d.ts +23 -0
  247. package/dist/utils/todoTracking.d.ts +16 -0
  248. package/dist/utils/token.d.ts +52 -0
  249. package/dist/utils/toolLicensing.d.ts +56 -0
  250. package/dist/utils/toolSelection.d.ts +73 -0
  251. package/dist/utils/toon.d.ts +16 -0
  252. package/dist/utils/version.d.ts +2 -0
  253. package/dist/utils/versioning.d.ts +7 -0
  254. package/dist/utils/vertex.d.ts +16 -0
  255. package/dist/utils/workflow.d.ts +13 -0
  256. package/package.json +132 -0
  257. package/src/agents/claude.ts +1588 -0
  258. package/src/agents/claudePretoolGate.ts +286 -0
  259. package/src/agents/dispatchMetrics.ts +162 -0
  260. package/src/agents/gateServer.ts +178 -0
  261. package/src/agents/index.ts +10 -0
  262. package/src/agents/nativeFsDenies.ts +164 -0
  263. package/src/agents/opencode.ts +1600 -0
  264. package/src/agents/opencodePlugin.ts +304 -0
  265. package/src/agents/opencodeShared.ts +134 -0
  266. package/src/agents/postRun.ts +615 -0
  267. package/src/agents/reviewer.ts +134 -0
  268. package/src/agents/sessionLabeler.ts +185 -0
  269. package/src/agents/shared.ts +377 -0
  270. package/src/agents/subagentModels.ts +40 -0
  271. package/src/agents/tokenQuota.ts +203 -0
  272. package/src/agents/writeGateSource.ts +148 -0
  273. package/src/agents/writePolicy.ts +132 -0
  274. package/src/brand.ts +84 -0
  275. package/src/cli.ts +117 -0
  276. package/src/commands/gha.ts +188 -0
  277. package/src/commands/mcp.ts +126 -0
  278. package/src/commands/verifyEvidence.ts +100 -0
  279. package/src/entry.ts +7 -0
  280. package/src/entryPost.ts +109 -0
  281. package/src/external.ts +308 -0
  282. package/src/i18n/scaffolding.ts +191 -0
  283. package/src/index.ts +7 -0
  284. package/src/internal/index.ts +74 -0
  285. package/src/lifecycle.ts +2 -0
  286. package/src/main.ts +815 -0
  287. package/src/mcp/__fixtures__/infraweaver-scratch-pr-49-review-3485940013.json +110 -0
  288. package/src/mcp/__fixtures__/infraweaver-scratch-pr-64-review-3531000326.json +14 -0
  289. package/src/mcp/__fixtures__/infraweaver-test-repo-pr-1.diff.json +67 -0
  290. package/src/mcp/__snapshots__/checkout.test.ts.snap +109 -0
  291. package/src/mcp/__snapshots__/reviewComments.test.ts.snap +71 -0
  292. package/src/mcp/arkConfig.ts +7 -0
  293. package/src/mcp/assess.ts +723 -0
  294. package/src/mcp/capabilityContext.ts +80 -0
  295. package/src/mcp/changeSummary.ts +145 -0
  296. package/src/mcp/checkSuite.ts +261 -0
  297. package/src/mcp/checkout.ts +1015 -0
  298. package/src/mcp/comment.ts +683 -0
  299. package/src/mcp/commitInfo.ts +57 -0
  300. package/src/mcp/crosswalk.ts +1253 -0
  301. package/src/mcp/crosswalkDigest.ts +5 -0
  302. package/src/mcp/cyberEssentials.ts +60 -0
  303. package/src/mcp/dashboard.ts +232 -0
  304. package/src/mcp/dependencies.ts +190 -0
  305. package/src/mcp/frameworks.ts +236 -0
  306. package/src/mcp/geminiSanitizer.ts +212 -0
  307. package/src/mcp/git.ts +1116 -0
  308. package/src/mcp/guardrails.ts +771 -0
  309. package/src/mcp/issue.ts +74 -0
  310. package/src/mcp/issueComments.ts +48 -0
  311. package/src/mcp/issueEvents.ts +100 -0
  312. package/src/mcp/issueInfo.ts +72 -0
  313. package/src/mcp/labels.ts +35 -0
  314. package/src/mcp/localContext.ts +65 -0
  315. package/src/mcp/localServer.ts +217 -0
  316. package/src/mcp/moduleExtraction.ts +368 -0
  317. package/src/mcp/moduleTests.ts +421 -0
  318. package/src/mcp/modules.ts +752 -0
  319. package/src/mcp/output.ts +71 -0
  320. package/src/mcp/pathSafety.ts +28 -0
  321. package/src/mcp/policy.ts +226 -0
  322. package/src/mcp/pr.ts +238 -0
  323. package/src/mcp/prInfo.ts +91 -0
  324. package/src/mcp/providerSchema.ts +175 -0
  325. package/src/mcp/review.ts +1081 -0
  326. package/src/mcp/reviewComments.ts +1137 -0
  327. package/src/mcp/roots.ts +217 -0
  328. package/src/mcp/scope.ts +82 -0
  329. package/src/mcp/selectMode.ts +207 -0
  330. package/src/mcp/server.ts +498 -0
  331. package/src/mcp/shared.ts +120 -0
  332. package/src/mcp/shell.ts +631 -0
  333. package/src/mcp/staleFix.ts +557 -0
  334. package/src/mcp/terraform/__snapshots__/moduleDocs.test.ts.snap +40 -0
  335. package/src/mcp/terraform/azurePrices.ts +38 -0
  336. package/src/mcp/terraform/baseline.ts +172 -0
  337. package/src/mcp/terraform/concernResult.ts +111 -0
  338. package/src/mcp/terraform/cost.ts +175 -0
  339. package/src/mcp/terraform/cspm.ts +326 -0
  340. package/src/mcp/terraform/currency.ts +354 -0
  341. package/src/mcp/terraform/decisions.ts +590 -0
  342. package/src/mcp/terraform/eidas.ts +134 -0
  343. package/src/mcp/terraform/evidence.ts +771 -0
  344. package/src/mcp/terraform/findings.ts +383 -0
  345. package/src/mcp/terraform/fixMemory.ts +253 -0
  346. package/src/mcp/terraform/governance.ts +231 -0
  347. package/src/mcp/terraform/hcl.ts +273 -0
  348. package/src/mcp/terraform/iacLanguages.ts +431 -0
  349. package/src/mcp/terraform/idleFloor.ts +304 -0
  350. package/src/mcp/terraform/keyless.ts +123 -0
  351. package/src/mcp/terraform/moduleDocs.ts +303 -0
  352. package/src/mcp/terraform/nativeRules.ts +152 -0
  353. package/src/mcp/terraform/nativeScan.ts +67 -0
  354. package/src/mcp/terraform/noiseProfile.ts +183 -0
  355. package/src/mcp/terraform/normalization.ts +265 -0
  356. package/src/mcp/terraform/oscal.ts +283 -0
  357. package/src/mcp/terraform/packs/azurerm-3-4.ts +382 -0
  358. package/src/mcp/terraform/packs/cloudflare-4-5.ts +114 -0
  359. package/src/mcp/terraform/paths.ts +59 -0
  360. package/src/mcp/terraform/plan.ts +377 -0
  361. package/src/mcp/terraform/planDrift.ts +520 -0
  362. package/src/mcp/terraform/policyAuthor.ts +886 -0
  363. package/src/mcp/terraform/prowlerOcsf.ts +380 -0
  364. package/src/mcp/terraform/refactor.ts +879 -0
  365. package/src/mcp/terraform/registry.ts +317 -0
  366. package/src/mcp/terraform/risk.ts +99 -0
  367. package/src/mcp/terraform/scanSession.ts +242 -0
  368. package/src/mcp/terraform/scannerCache.ts +86 -0
  369. package/src/mcp/terraform/scannerEgress.ts +141 -0
  370. package/src/mcp/terraform/scannerJson.ts +22 -0
  371. package/src/mcp/terraform/scanners.ts +1134 -0
  372. package/src/mcp/terraform/signing.ts +151 -0
  373. package/src/mcp/terraform/stateLocking.ts +106 -0
  374. package/src/mcp/terraform/subprocess.ts +102 -0
  375. package/src/mcp/terraform/suppressions.ts +551 -0
  376. package/src/mcp/terraform/taxonomy.ts +0 -0
  377. package/src/mcp/terraform/tfquery.ts +159 -0
  378. package/src/mcp/terraform/toolchainIntegrity.ts +151 -0
  379. package/src/mcp/terraform/tools/authorPolicy.ts +185 -0
  380. package/src/mcp/terraform/tools/detectPlanDrift.ts +279 -0
  381. package/src/mcp/terraform/tools/emitCost.ts +130 -0
  382. package/src/mcp/terraform/tools/emitSarif.ts +108 -0
  383. package/src/mcp/terraform/tools/fixMemory.ts +82 -0
  384. package/src/mcp/terraform/tools/infracostDiff.ts +110 -0
  385. package/src/mcp/terraform/tools/ingestExternalFindings.ts +259 -0
  386. package/src/mcp/terraform/tools/moduleLookup.ts +86 -0
  387. package/src/mcp/terraform/tools/moduleSearch.ts +46 -0
  388. package/src/mcp/terraform/tools/plan.ts +384 -0
  389. package/src/mcp/terraform/tools/providerUpgrade.ts +217 -0
  390. package/src/mcp/terraform/tools/readFindings.ts +138 -0
  391. package/src/mcp/terraform/tools/scan.ts +303 -0
  392. package/src/mcp/terraform/tools/validate.ts +160 -0
  393. package/src/mcp/terraform/tools/verifyRemediation.ts +190 -0
  394. package/src/mcp/terraform/tools/versionCurrency.ts +64 -0
  395. package/src/mcp/terraform/tools.ts +62 -0
  396. package/src/mcp/terraform/transformPacks.ts +594 -0
  397. package/src/mcp/terraform/types.ts +382 -0
  398. package/src/mcp/terraform/verification.ts +150 -0
  399. package/src/mcp/terraform/vex.ts +367 -0
  400. package/src/mcp/terraform/writeOnly.ts +252 -0
  401. package/src/mcp/terraform.ts +52 -0
  402. package/src/mcp/terratest.ts +215 -0
  403. package/src/mcp/untrustedContent.ts +126 -0
  404. package/src/mcp/upload.ts +123 -0
  405. package/src/models.ts +753 -0
  406. package/src/modes/address-reviews.ts +35 -0
  407. package/src/modes/assess.ts +27 -0
  408. package/src/modes/build.ts +86 -0
  409. package/src/modes/compliance-audit.ts +25 -0
  410. package/src/modes/cost-optimization.ts +36 -0
  411. package/src/modes/drift-detect.ts +31 -0
  412. package/src/modes/fix.ts +29 -0
  413. package/src/modes/incremental-review.ts +103 -0
  414. package/src/modes/index.ts +94 -0
  415. package/src/modes/modernize-deprecated.ts +36 -0
  416. package/src/modes/plan.ts +21 -0
  417. package/src/modes/policy-gate.ts +27 -0
  418. package/src/modes/prFormats.ts +325 -0
  419. package/src/modes/refactor.ts +74 -0
  420. package/src/modes/refresh-remediation.ts +40 -0
  421. package/src/modes/remediate-and-refactor.ts +42 -0
  422. package/src/modes/remediate.ts +78 -0
  423. package/src/modes/resolve-conflicts.ts +32 -0
  424. package/src/modes/review.ts +135 -0
  425. package/src/modes/summarize-pr.ts +42 -0
  426. package/src/modes/task.ts +26 -0
  427. package/src/modes/terraform-code-review.ts +68 -0
  428. package/src/modes/types.ts +17 -0
  429. package/src/modes/update-dependencies.ts +44 -0
  430. package/src/prep/index.ts +96 -0
  431. package/src/prep/installNodeDependencies.ts +251 -0
  432. package/src/prep/installPythonDependencies.ts +235 -0
  433. package/src/prep/types.ts +38 -0
  434. package/src/reviewQuality.ts +237 -0
  435. package/src/runCli.ts +335 -0
  436. package/src/skills/terraform-best-practices/SKILL.md +379 -0
  437. package/src/toolState.ts +241 -0
  438. package/src/utils/activity.ts +210 -0
  439. package/src/utils/agent.ts +245 -0
  440. package/src/utils/agentHangReport.ts +180 -0
  441. package/src/utils/annotations.ts +56 -0
  442. package/src/utils/apiFetch.ts +19 -0
  443. package/src/utils/apiKeys.ts +305 -0
  444. package/src/utils/apiUrl.ts +42 -0
  445. package/src/utils/assets.ts +123 -0
  446. package/src/utils/baseRefConfig.ts +254 -0
  447. package/src/utils/billingErrors.ts +210 -0
  448. package/src/utils/body.ts +168 -0
  449. package/src/utils/buildInfraweaverFooter.ts +104 -0
  450. package/src/utils/byokFallback.ts +137 -0
  451. package/src/utils/changeImpact.ts +330 -0
  452. package/src/utils/claudeSubscription.ts +93 -0
  453. package/src/utils/cli.ts +36 -0
  454. package/src/utils/cloudClient.ts +57 -0
  455. package/src/utils/cloudFetchCore.ts +139 -0
  456. package/src/utils/cloudReport.ts +316 -0
  457. package/src/utils/codexHome.ts +204 -0
  458. package/src/utils/codexOAuth.ts +154 -0
  459. package/src/utils/codexRefreshDetect.ts +36 -0
  460. package/src/utils/diffCoverage.ts +404 -0
  461. package/src/utils/env.ts +84 -0
  462. package/src/utils/errorReport.ts +94 -0
  463. package/src/utils/exitHandler.ts +35 -0
  464. package/src/utils/fixDoubleEscapedString.ts +9 -0
  465. package/src/utils/ghaCore.ts +13 -0
  466. package/src/utils/gitAuth.ts +268 -0
  467. package/src/utils/gitAuthServer.ts +186 -0
  468. package/src/utils/github.ts +676 -0
  469. package/src/utils/globals.ts +9 -0
  470. package/src/utils/humanEditCapture.ts +198 -0
  471. package/src/utils/infraweaverConfig.ts +202 -0
  472. package/src/utils/install.ts +279 -0
  473. package/src/utils/instructions.ts +640 -0
  474. package/src/utils/keylessOidc.ts +47 -0
  475. package/src/utils/leapingComment.ts +20 -0
  476. package/src/utils/learnings.ts +145 -0
  477. package/src/utils/learningsTruncate.ts +42 -0
  478. package/src/utils/lifecycle.ts +198 -0
  479. package/src/utils/log.ts +452 -0
  480. package/src/utils/modelResolver.ts +105 -0
  481. package/src/utils/moduleFetch.ts +138 -0
  482. package/src/utils/normalizeEnv.ts +106 -0
  483. package/src/utils/openCodeModels.ts +86 -0
  484. package/src/utils/openaiCompatible.ts +52 -0
  485. package/src/utils/opentofuMcp.ts +61 -0
  486. package/src/utils/overrides.ts +100 -0
  487. package/src/utils/packageManager.ts +257 -0
  488. package/src/utils/patchWorkflowRunFields.ts +173 -0
  489. package/src/utils/payload.ts +1206 -0
  490. package/src/utils/prSummary.ts +148 -0
  491. package/src/utils/presets.ts +105 -0
  492. package/src/utils/progressComment.ts +266 -0
  493. package/src/utils/providerErrors.ts +189 -0
  494. package/src/utils/proxyModel.ts +239 -0
  495. package/src/utils/rangeDiff.ts +182 -0
  496. package/src/utils/redact.ts +86 -0
  497. package/src/utils/registryAuth.ts +115 -0
  498. package/src/utils/remediationCommand.ts +144 -0
  499. package/src/utils/retry.ts +180 -0
  500. package/src/utils/reviewCleanup.ts +116 -0
  501. package/src/utils/run.ts +100 -0
  502. package/src/utils/runContext.ts +276 -0
  503. package/src/utils/runContextData.ts +121 -0
  504. package/src/utils/runErrorRenderer.ts +282 -0
  505. package/src/utils/runFixture.ts +91 -0
  506. package/src/utils/runLifecycle.ts +360 -0
  507. package/src/utils/runStartupLog.ts +67 -0
  508. package/src/utils/secrets.ts +208 -0
  509. package/src/utils/setup.ts +368 -0
  510. package/src/utils/shell.ts +132 -0
  511. package/src/utils/skills.ts +67 -0
  512. package/src/utils/subprocess.ts +474 -0
  513. package/src/utils/terraformMcp.ts +99 -0
  514. package/src/utils/time.ts +59 -0
  515. package/src/utils/timer.ts +72 -0
  516. package/src/utils/todoTracking.ts +168 -0
  517. package/src/utils/token.ts +294 -0
  518. package/src/utils/toolLicensing.ts +152 -0
  519. package/src/utils/toolSelection.ts +239 -0
  520. package/src/utils/toon.ts +76 -0
  521. package/src/utils/version.ts +10 -0
  522. package/src/utils/versioning.ts +44 -0
  523. package/src/utils/vertex.ts +94 -0
  524. package/src/utils/workflow.ts +25 -0
@@ -0,0 +1,380 @@
1
+ import { type } from "arktype";
2
+ import type { ExternalFinding } from "#app/mcp/terraform/cspm";
3
+ import type { Severity } from "#app/mcp/terraform/types";
4
+
5
+ /**
6
+ * Prowler OCSF ingestion (CSPM phase 1).
7
+ *
8
+ * Prowler is an Apache-2.0 live-cloud CSPM scanner. Infraweaver CONSUMES its
9
+ * findings and never runs it: the customer runs Prowler in their own CI with
10
+ * their own cloud credentials and Infraweaver ingests the resulting JSON. The
11
+ * zero-credential invariant is unchanged — this module only parses a file.
12
+ *
13
+ * Prowler writes OCSF `DetectionFinding` objects (class_uid 2004) as a single
14
+ * JSON ARRAY, not NDJSON. Field locations follow the OCSF 1.x DetectionFinding
15
+ * schema; `severity_id` is the OCSF enum (0 Unknown, 1 Informational, 2 Low,
16
+ * 3 Medium, 4 High, 5 Critical, 6 Fatal), which is deliberately NOT routed
17
+ * through `normalizeExternalSeverity()` — that function reads bare numbers as
18
+ * CVSS scores and would silently downgrade a Critical (5) to medium.
19
+ *
20
+ * Output is the existing `ExternalFinding` shape, so everything downstream —
21
+ * correlation, concern building, grouping, the Cloud report — is unchanged.
22
+ */
23
+
24
+ /** OCSF `type_uid` for DetectionFinding: Create — what Prowler emits. */
25
+ export const DETECTION_FINDING_CREATE = 200401;
26
+
27
+ /**
28
+ * Lenient schema: only what we actually read, everything optional except the
29
+ * check id. A finding that fails this is routed to unmapped-alerts rather than
30
+ * failing the run — an external feed must never break a scan.
31
+ */
32
+ const ProwlerResource = type({
33
+ "uid?": "string",
34
+ "name?": "string",
35
+ "type?": "string",
36
+ "region?": "string",
37
+ "labels?": "string[]",
38
+ });
39
+
40
+ const ProwlerFinding = type({
41
+ "metadata?": type({
42
+ "event_code?": "string",
43
+ "product?": type({ "name?": "string", "version?": "string" }),
44
+ }),
45
+ "status_code?": "string",
46
+ "status?": "string",
47
+ "status_detail?": "string",
48
+ "message?": "string",
49
+ "severity?": "string",
50
+ "severity_id?": "number",
51
+ "finding_info?": type({ "title?": "string", "desc?": "string" }),
52
+ "remediation?": type({ "desc?": "string", "references?": "string[]" }),
53
+ "resources?": ProwlerResource.array(),
54
+ "cloud?": type({
55
+ "provider?": "string",
56
+ "account?": type({ "uid?": "string" }),
57
+ "region?": "string",
58
+ }),
59
+ "type_uid?": "number",
60
+ "unmapped?": "object",
61
+ });
62
+
63
+ export type ProwlerFindingInput = typeof ProwlerFinding.infer;
64
+
65
+ /**
66
+ * True for a parsed value that looks like a Prowler OCSF feed: a non-empty array
67
+ * whose first item is a DetectionFinding or carries Prowler's product name.
68
+ * Checked BEFORE the native `infraweaver.external-findings/v1` validator, which is
69
+ * safe because the native feed is an OBJECT and this requires a non-empty ARRAY —
70
+ * the two shapes cannot collide, so existing feeds keep their exact behaviour.
71
+ */
72
+ export function isProwlerOcsf(parsed: unknown): boolean {
73
+ if (!Array.isArray(parsed) || parsed.length === 0) return false;
74
+ const first = parsed[0] as Record<string, unknown> | undefined;
75
+ if (!first || typeof first !== "object") return false;
76
+ if (first.type_uid === DETECTION_FINDING_CREATE) return true;
77
+ const metadata = first.metadata as
78
+ | { product?: { name?: unknown } }
79
+ | undefined;
80
+ return (
81
+ typeof metadata?.product?.name === "string" &&
82
+ /prowler/i.test(metadata.product.name)
83
+ );
84
+ }
85
+
86
+ /**
87
+ * Detect a Prowler output file that was never closed. Prowler streams `[`, then
88
+ * findings, and only seeks back to write `]` when the scan completes — so a
89
+ * crashed or still-running scan leaves an unterminated array that `JSON.parse`
90
+ * rejects with a message no operator can act on.
91
+ */
92
+ export function isUnterminatedJsonArray(raw: string): boolean {
93
+ const trimmed = raw.trim();
94
+ return trimmed.startsWith("[") && !trimmed.endsWith("]");
95
+ }
96
+
97
+ /** OCSF severity_id → our scale. Explicitly NOT the CVSS band reading. */
98
+ const SEVERITY_BY_ID: Record<number, Severity> = {
99
+ 0: "info", // Unknown — the honest floor, never assumed severe
100
+ 1: "info", // Informational
101
+ 2: "low",
102
+ 3: "medium",
103
+ 4: "high",
104
+ 5: "critical",
105
+ 6: "critical", // Fatal
106
+ };
107
+
108
+ const SEVERITY_BY_NAME: Record<string, Severity> = {
109
+ critical: "critical",
110
+ fatal: "critical",
111
+ high: "high",
112
+ medium: "medium",
113
+ low: "low",
114
+ informational: "info",
115
+ info: "info",
116
+ unknown: "info",
117
+ };
118
+
119
+ /**
120
+ * Resolve a finding's severity: the OCSF severity NAME first (what Prowler
121
+ * writes), then the numeric enum, then `medium` — matching the default the
122
+ * existing external-findings path uses when a feed says nothing.
123
+ */
124
+ export function prowlerSeverity(finding: ProwlerFindingInput): Severity {
125
+ const name = finding.severity?.trim().toLowerCase();
126
+ if (name && SEVERITY_BY_NAME[name]) return SEVERITY_BY_NAME[name] as Severity;
127
+ if (typeof finding.severity_id === "number") {
128
+ const byId = SEVERITY_BY_ID[finding.severity_id];
129
+ if (byId) return byId;
130
+ }
131
+ return "medium";
132
+ }
133
+
134
+ /**
135
+ * Framework keys we accept from `unmapped.compliance`. FREE frameworks only —
136
+ * everything else (CIS, ISO, PCI, SOC2, …) is dropped at parse time and never
137
+ * reaches storage or the UI. Two independent reasons, both binding:
138
+ *
139
+ * 1. LICENCE. CIS/ISO/PCI content is paywalled or no-derivatives; we do not
140
+ * redistribute it in any form, not even requirement ids sourced from a
141
+ * third-party pack.
142
+ * 2. NO STANDARDS OVERLOAD. The catalogue is a hard ceiling, not a starting
143
+ * point — users see the 12 infra themes first; framework ids appear only on
144
+ * control drill-down.
145
+ *
146
+ * Matching is prefix-based and case-insensitive because Prowler keys carry a
147
+ * version suffix (`ENS-RD2022`, `NIST-800-53-REVISION-5`).
148
+ */
149
+ const FREE_FRAMEWORK_PREFIXES = [
150
+ "ens",
151
+ "nis2",
152
+ "gdpr",
153
+ "c5",
154
+ "nist-800-53",
155
+ "nist_800_53",
156
+ "nist-csf",
157
+ "nist_csf",
158
+ ] as const;
159
+
160
+ /** True when a Prowler compliance key names a framework we may lawfully carry. */
161
+ export function isFreeFrameworkKey(key: string): boolean {
162
+ const k = key.trim().toLowerCase();
163
+ return FREE_FRAMEWORK_PREFIXES.some((p) => k.startsWith(p));
164
+ }
165
+
166
+ /**
167
+ * The free-framework compliance references a finding carries, as
168
+ * `FRAMEWORK: req-id` strings. Paywalled frameworks are dropped silently and by
169
+ * design. Returns [] when the finding carries none.
170
+ */
171
+ export function freeComplianceRefs(finding: ProwlerFindingInput): string[] {
172
+ const compliance = (finding.unmapped as { compliance?: unknown } | undefined)
173
+ ?.compliance;
174
+ if (!compliance || typeof compliance !== "object") return [];
175
+ const refs: string[] = [];
176
+ for (const [key, value] of Object.entries(
177
+ compliance as Record<string, unknown>,
178
+ )) {
179
+ if (!isFreeFrameworkKey(key)) continue;
180
+ if (!Array.isArray(value)) continue;
181
+ for (const req of value) {
182
+ if (typeof req === "string" && req.trim())
183
+ refs.push(`${key}: ${req.trim()}`);
184
+ }
185
+ }
186
+ return refs;
187
+ }
188
+
189
+ export interface ProwlerParseResult {
190
+ /** FAIL findings mapped into the shared external-finding shape. */
191
+ findings: ExternalFinding[];
192
+ summary: {
193
+ total: number;
194
+ /** mapped to concerns (status_code FAIL, not muted). */
195
+ failed: number;
196
+ passed: number;
197
+ manual: number;
198
+ /** muted by the customer's Prowler mutelist — user intent we honour. */
199
+ muted: number;
200
+ /** items that did not match the DetectionFinding shape at all. */
201
+ malformed: number;
202
+ /** items whose `status_code` is one we do not model — distinct from malformed,
203
+ * so an operator can tell "new Prowler status" from "not a finding". */
204
+ unknown_status: number;
205
+ /** `metadata.product.version`, when the feed declared one. */
206
+ product_version: string | null;
207
+ /** set when type_uid drifted from the expected DetectionFinding value. */
208
+ schema_warning: string | null;
209
+ };
210
+ }
211
+
212
+ /**
213
+ * Parse a Prowler OCSF array into external findings + an honest tally.
214
+ *
215
+ * Only `status_code === "FAIL"` findings become concerns. PASS/MANUAL and muted
216
+ * findings are COUNTED but never mapped: a passing check is not a defect, and
217
+ * Prowler's mutelist is user-authored intent. The counts still matter — phase-2
218
+ * requirement coverage needs to say "3 checks FAIL, 12 PASS" rather than
219
+ * treating absence as unknown.
220
+ *
221
+ * Pure: no fs, no network.
222
+ */
223
+ export function parseProwlerOcsf(
224
+ items: readonly unknown[],
225
+ ): ProwlerParseResult {
226
+ const findings: ExternalFinding[] = [];
227
+ let failed = 0;
228
+ let passed = 0;
229
+ let manual = 0;
230
+ let muted = 0;
231
+ let malformed = 0;
232
+ let unknown_status = 0;
233
+ let productVersion: string | null = null;
234
+ let schemaWarning: string | null = null;
235
+
236
+ for (const raw of items) {
237
+ const parsed = ProwlerFinding(raw);
238
+ if (parsed instanceof type.errors) {
239
+ malformed++;
240
+ continue;
241
+ }
242
+ const finding = parsed as ProwlerFindingInput;
243
+ productVersion ??= finding.metadata?.product?.version ?? null;
244
+ // Version drift is a warning, never a failure — a newer Prowler that still
245
+ // writes recognisable findings should keep working.
246
+ if (
247
+ schemaWarning === null &&
248
+ typeof finding.type_uid === "number" &&
249
+ finding.type_uid !== DETECTION_FINDING_CREATE
250
+ ) {
251
+ schemaWarning = `unexpected OCSF type_uid ${finding.type_uid} (expected ${DETECTION_FINDING_CREATE}); parsed anyway`;
252
+ }
253
+
254
+ const status = finding.status_code?.trim().toUpperCase();
255
+ // The schema is deliberately lenient (every field optional), so ANY object
256
+ // satisfies it — `status_code` is what actually distinguishes a
257
+ // DetectionFinding from arbitrary JSON. Without it, this is not a finding.
258
+ if (!status) {
259
+ malformed++;
260
+ continue;
261
+ }
262
+ // `status: "Suppressed"` marks a muted finding; status_code still carries the
263
+ // real result, so check muting BEFORE the FAIL branch.
264
+ // PASS/MANUAL are tallied on their real result first: a muted PASS is still a
265
+ // PASS, and requirement coverage ("3 FAIL, 12 PASS") is computed off that
266
+ // tally, so folding it into `muted` would understate what actually ran.
267
+ if (status === "PASS") {
268
+ passed++;
269
+ continue;
270
+ }
271
+ if (status === "MANUAL") {
272
+ manual++;
273
+ continue;
274
+ }
275
+ // `status: "Suppressed"` marks a finding the customer mutelisted; status_code
276
+ // still carries the real (FAIL) result. Mutelist entries are user-authored
277
+ // intent we honour, so it is counted and never reported as a defect.
278
+ if (finding.status?.trim().toLowerCase() === "suppressed") {
279
+ muted++;
280
+ continue;
281
+ }
282
+ if (status !== "FAIL") {
283
+ unknown_status++;
284
+ continue;
285
+ }
286
+
287
+ const checkId = finding.metadata?.event_code?.trim();
288
+ if (!checkId) {
289
+ malformed++;
290
+ continue;
291
+ }
292
+ failed++;
293
+
294
+ const resource = finding.resources?.[0];
295
+ const remediationParts = [finding.remediation?.desc?.trim()].filter(
296
+ Boolean,
297
+ ) as string[];
298
+ for (const ref of finding.remediation?.references ?? []) {
299
+ if (typeof ref === "string" && ref.trim())
300
+ remediationParts.push(ref.trim());
301
+ }
302
+ const compliance = freeComplianceRefs(finding);
303
+ if (compliance.length > 0)
304
+ remediationParts.push(`Compliance: ${compliance.join("; ")}`);
305
+ const hints = tagHints(resource?.labels);
306
+
307
+ const message = finding.status_detail?.trim() || finding.message?.trim();
308
+ const remediation = remediationParts.join(" ");
309
+ findings.push({
310
+ rule_id: checkId,
311
+ provider: finding.cloud?.provider?.trim().toLowerCase() || "prowler",
312
+ severity: prowlerSeverity(finding),
313
+ title: finding.finding_info?.title?.trim() || checkId,
314
+ ...(message ? { message } : {}),
315
+ ...(remediation ? { remediation } : {}),
316
+ // NB: OCSF `resources[].type` is a CLOUD type ("AwsS3Bucket"), not a
317
+ // Terraform type ("aws_s3_bucket"). Passing it through as `resource.type`
318
+ // would make the correlator's type-narrowed passes silently never match,
319
+ // so it is deliberately omitted and correlation runs on uid/name instead.
320
+ resource: {
321
+ ...(resource?.uid ? { arn: resource.uid } : {}),
322
+ ...(resource?.name ? { id: resource.name } : {}),
323
+ ...(hints.length > 0 ? { tags: hints } : {}),
324
+ },
325
+ });
326
+ }
327
+
328
+ return {
329
+ findings,
330
+ summary: {
331
+ total: items.length,
332
+ failed,
333
+ passed,
334
+ manual,
335
+ muted,
336
+ malformed,
337
+ unknown_status,
338
+ product_version: productVersion,
339
+ schema_warning: schemaWarning,
340
+ },
341
+ };
342
+ }
343
+
344
+ /**
345
+ * Tag keys whose value NAMES a specific resource. OCSF unrolls cloud tags into
346
+ * `labels` as `key:value`, but only an identity tag is correlation evidence: an
347
+ * `env=production` or `owner=platform-team` tag describes a whole fleet, so
348
+ * matching on it would pin every finding in that fleet to whichever single
349
+ * Terraform block happened to contain the word.
350
+ */
351
+ const IDENTITY_TAG_KEYS = new Set(["name", "resourcename", "resource_name"]);
352
+
353
+ /**
354
+ * The identity-bearing cloud tags a Prowler finding carries, lower-cased, as
355
+ * last-resort correlation hints.
356
+ *
357
+ * Two filters, both about not mis-mapping: only identity keys (above), and only
358
+ * values long enough to identify something — a short value like `eu` would match
359
+ * half the repo. A wrong mapping is worse than an honest unmapped alert, because
360
+ * it puts a real cloud finding on an unrelated line of someone's code.
361
+ */
362
+ export function tagHints(labels: readonly string[] | undefined): string[] {
363
+ const hints = new Set<string>();
364
+ for (const label of labels ?? []) {
365
+ if (typeof label !== "string") continue;
366
+ const idx = label.indexOf(":");
367
+ // No key at all — not attributable to an identity tag, so not evidence.
368
+ if (idx < 0) continue;
369
+ const key = label.slice(0, idx).trim().toLowerCase().replace(/[\s-]/g, "");
370
+ if (!IDENTITY_TAG_KEYS.has(key)) continue;
371
+ // Take everything after the FIRST colon: an ARN-valued Name tag keeps its
372
+ // colons, and the whole ARN is the identity.
373
+ const value = label
374
+ .slice(idx + 1)
375
+ .trim()
376
+ .toLowerCase();
377
+ if (value.length >= 4) hints.add(value);
378
+ }
379
+ return [...hints];
380
+ }