@codyswann/lisa 4.54.13 → 4.55.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 (578) hide show
  1. package/all/copy-contents/.gitattributes +8 -0
  2. package/all/copy-overwrite/scripts/check-orphaned-branches.mjs +78 -9
  3. package/all/copy-overwrite/scripts/check-third-party-action-pins.mjs +17 -1
  4. package/all/copy-overwrite/scripts/lib/process-tree-runner.mjs +194 -7
  5. package/all/copy-overwrite/scripts/lisa-enforcement-fallback.sh +31 -0
  6. package/all/copy-overwrite/scripts/lisa-hooks/block-blind-automerge.sh +81 -2
  7. package/all/copy-overwrite/scripts/lisa-hooks/block-direct-issue-create.sh +293 -8
  8. package/all/copy-overwrite/scripts/lisa-hooks/block-instruction-file-edits.sh +21 -0
  9. package/all/copy-overwrite/scripts/lisa-hooks/block-managed-file-edits.sh +78 -15
  10. package/all/copy-overwrite/scripts/lisa-hooks/block-no-verify.sh +21 -0
  11. package/all/copy-overwrite/scripts/lisa-hooks/block-shell-json-parsing.sh +21 -0
  12. package/all/copy-overwrite/scripts/lisa-hooks/guard-dedupe.bash +340 -0
  13. package/all/copy-overwrite/scripts/lisa-hooks/parity-safety-net.sh +29 -1
  14. package/all/copy-overwrite/scripts/lisa-hooks/worktree-binding-guard.mjs +183 -1
  15. package/all/copy-overwrite/scripts/lisa-hooks/worktree-binding-guard.sh +21 -0
  16. package/all/copy-overwrite/scripts/lisa-postinstall.mjs +21 -1
  17. package/all/copy-overwrite/scripts/lisa-run-gates.mjs +100 -5
  18. package/all/copy-overwrite/scripts/lisa-work-item.mjs +1085 -80
  19. package/all/create-only/.github/workflows/continuous-gates.yml +7 -0
  20. package/cdk/create-only/.github/workflows/ci.yml +7 -0
  21. package/cdk/create-only/.github/workflows/deploy.yml +21 -0
  22. package/dist/cli/apply.d.ts.map +1 -1
  23. package/dist/cli/apply.js +9 -1
  24. package/dist/cli/apply.js.map +1 -1
  25. package/dist/cli/doctor-apply-deletions.d.ts +61 -0
  26. package/dist/cli/doctor-apply-deletions.d.ts.map +1 -0
  27. package/dist/cli/doctor-apply-deletions.js +137 -0
  28. package/dist/cli/doctor-apply-deletions.js.map +1 -0
  29. package/dist/cli/doctor-cdk-preset-adoption.d.ts +15 -0
  30. package/dist/cli/doctor-cdk-preset-adoption.d.ts.map +1 -0
  31. package/dist/cli/doctor-cdk-preset-adoption.js +316 -0
  32. package/dist/cli/doctor-cdk-preset-adoption.js.map +1 -0
  33. package/dist/cli/doctor-config-shadowing.d.ts +22 -0
  34. package/dist/cli/doctor-config-shadowing.d.ts.map +1 -0
  35. package/dist/cli/doctor-config-shadowing.js +123 -0
  36. package/dist/cli/doctor-config-shadowing.js.map +1 -0
  37. package/dist/cli/doctor-rails-deploy-intent.d.ts +15 -0
  38. package/dist/cli/doctor-rails-deploy-intent.d.ts.map +1 -0
  39. package/dist/cli/doctor-rails-deploy-intent.js +197 -0
  40. package/dist/cli/doctor-rails-deploy-intent.js.map +1 -0
  41. package/dist/cli/doctor-seeded-artifacts.d.ts +12 -0
  42. package/dist/cli/doctor-seeded-artifacts.d.ts.map +1 -0
  43. package/dist/cli/doctor-seeded-artifacts.js +54 -0
  44. package/dist/cli/doctor-seeded-artifacts.js.map +1 -0
  45. package/dist/cli/doctor-stale-banner-scan.d.ts +44 -0
  46. package/dist/cli/doctor-stale-banner-scan.d.ts.map +1 -0
  47. package/dist/cli/doctor-stale-banner-scan.js +152 -0
  48. package/dist/cli/doctor-stale-banner-scan.js.map +1 -0
  49. package/dist/cli/doctor-stale-managed-banner.d.ts +19 -0
  50. package/dist/cli/doctor-stale-managed-banner.d.ts.map +1 -0
  51. package/dist/cli/doctor-stale-managed-banner.js +198 -0
  52. package/dist/cli/doctor-stale-managed-banner.js.map +1 -0
  53. package/dist/cli/doctor.d.ts.map +1 -1
  54. package/dist/cli/doctor.js +16 -0
  55. package/dist/cli/doctor.js.map +1 -1
  56. package/dist/cli/ui-detected-stacks.d.ts.map +1 -1
  57. package/dist/cli/ui-detected-stacks.js +3 -2
  58. package/dist/cli/ui-detected-stacks.js.map +1 -1
  59. package/dist/cli/update-check.d.ts.map +1 -1
  60. package/dist/cli/update-check.js +14 -0
  61. package/dist/cli/update-check.js.map +1 -1
  62. package/dist/cli/worktree-liveness.d.ts +5 -0
  63. package/dist/cli/worktree-liveness.d.ts.map +1 -1
  64. package/dist/cli/worktree-liveness.js +7 -6
  65. package/dist/cli/worktree-liveness.js.map +1 -1
  66. package/dist/cli/worktree-ownership.d.ts +13 -0
  67. package/dist/cli/worktree-ownership.d.ts.map +1 -1
  68. package/dist/cli/worktree-ownership.js +14 -0
  69. package/dist/cli/worktree-ownership.js.map +1 -1
  70. package/dist/configs/eslint/base.d.ts +34 -0
  71. package/dist/configs/eslint/base.d.ts.map +1 -1
  72. package/dist/configs/eslint/base.js +34 -0
  73. package/dist/configs/eslint/base.js.map +1 -1
  74. package/dist/core/apply-receipt.d.ts +65 -0
  75. package/dist/core/apply-receipt.d.ts.map +1 -1
  76. package/dist/core/apply-receipt.js +62 -2
  77. package/dist/core/apply-receipt.js.map +1 -1
  78. package/dist/core/cdk-preset-adoption.d.ts +136 -0
  79. package/dist/core/cdk-preset-adoption.d.ts.map +1 -0
  80. package/dist/core/cdk-preset-adoption.js +135 -0
  81. package/dist/core/cdk-preset-adoption.js.map +1 -0
  82. package/dist/core/config-shadowing.d.ts +36 -0
  83. package/dist/core/config-shadowing.d.ts.map +1 -1
  84. package/dist/core/config-shadowing.js +38 -0
  85. package/dist/core/config-shadowing.js.map +1 -1
  86. package/dist/core/config.d.ts +11 -0
  87. package/dist/core/config.d.ts.map +1 -1
  88. package/dist/core/config.js.map +1 -1
  89. package/dist/core/learnings-merge-driver.d.ts +10 -0
  90. package/dist/core/learnings-merge-driver.d.ts.map +1 -1
  91. package/dist/core/learnings-merge-driver.js +18 -0
  92. package/dist/core/learnings-merge-driver.js.map +1 -1
  93. package/dist/core/lisa-owned-hash-ledger.d.ts.map +1 -1
  94. package/dist/core/lisa-owned-hash-ledger.js +136 -0
  95. package/dist/core/lisa-owned-hash-ledger.js.map +1 -1
  96. package/dist/core/lisa.d.ts.map +1 -1
  97. package/dist/core/lisa.js +9 -1
  98. package/dist/core/lisa.js.map +1 -1
  99. package/dist/core/nightly-e2e-guard-behavior-certificate.d.ts +5 -5
  100. package/dist/core/nightly-e2e-guard-behavior-certificate.js +7 -7
  101. package/dist/core/nightly-e2e-guard-behavior-certificate.js.map +1 -1
  102. package/dist/core/ownership-header.d.ts +74 -0
  103. package/dist/core/ownership-header.d.ts.map +1 -0
  104. package/dist/core/ownership-header.js +76 -0
  105. package/dist/core/ownership-header.js.map +1 -0
  106. package/dist/core/rails-deploy-production-intent.d.ts +36 -0
  107. package/dist/core/rails-deploy-production-intent.d.ts.map +1 -0
  108. package/dist/core/rails-deploy-production-intent.js +79 -0
  109. package/dist/core/rails-deploy-production-intent.js.map +1 -0
  110. package/dist/core/stale-managed-banner.d.ts +78 -0
  111. package/dist/core/stale-managed-banner.d.ts.map +1 -0
  112. package/dist/core/stale-managed-banner.js +118 -0
  113. package/dist/core/stale-managed-banner.js.map +1 -0
  114. package/dist/core/two-channel-delivery-scan.d.ts +33 -1
  115. package/dist/core/two-channel-delivery-scan.d.ts.map +1 -1
  116. package/dist/core/two-channel-delivery-scan.js +133 -6
  117. package/dist/core/two-channel-delivery-scan.js.map +1 -1
  118. package/dist/core/two-channel-delivery.d.ts +101 -4
  119. package/dist/core/two-channel-delivery.d.ts.map +1 -1
  120. package/dist/core/two-channel-delivery.js +121 -13
  121. package/dist/core/two-channel-delivery.js.map +1 -1
  122. package/dist/core/two-channel-staleness.d.ts +137 -0
  123. package/dist/core/two-channel-staleness.d.ts.map +1 -0
  124. package/dist/core/two-channel-staleness.js +268 -0
  125. package/dist/core/two-channel-staleness.js.map +1 -0
  126. package/dist/core/upstream-evidence-manifest.d.ts.map +1 -1
  127. package/dist/core/upstream-evidence-manifest.js +265 -121
  128. package/dist/core/upstream-evidence-manifest.js.map +1 -1
  129. package/dist/core/workflow-deletion-ownership.d.ts +6 -24
  130. package/dist/core/workflow-deletion-ownership.d.ts.map +1 -1
  131. package/dist/core/workflow-deletion-ownership.js +22 -42
  132. package/dist/core/workflow-deletion-ownership.js.map +1 -1
  133. package/dist/detection/detectors/cdk.d.ts.map +1 -1
  134. package/dist/detection/detectors/cdk.js +2 -1
  135. package/dist/detection/detectors/cdk.js.map +1 -1
  136. package/dist/health/template-inspection.d.ts.map +1 -1
  137. package/dist/health/template-inspection.js +2 -1
  138. package/dist/health/template-inspection.js.map +1 -1
  139. package/dist/migrations/ensure-lisa-postinstall.d.ts +16 -0
  140. package/dist/migrations/ensure-lisa-postinstall.d.ts.map +1 -1
  141. package/dist/migrations/ensure-lisa-postinstall.js +16 -0
  142. package/dist/migrations/ensure-lisa-postinstall.js.map +1 -1
  143. package/dist/migrations/ensure-pinned-reusable-workflow-refs.d.ts +2 -2
  144. package/dist/migrations/ensure-pinned-reusable-workflow-refs.d.ts.map +1 -1
  145. package/dist/migrations/ensure-pinned-reusable-workflow-refs.js +98 -34
  146. package/dist/migrations/ensure-pinned-reusable-workflow-refs.js.map +1 -1
  147. package/dist/migrations/ensure-playwright-dedicated-caller.d.ts.map +1 -1
  148. package/dist/migrations/ensure-playwright-dedicated-caller.js +1 -0
  149. package/dist/migrations/ensure-playwright-dedicated-caller.js.map +1 -1
  150. package/dist/opencode/hooks-installer.d.ts.map +1 -1
  151. package/dist/opencode/hooks-installer.js +1 -0
  152. package/dist/opencode/hooks-installer.js.map +1 -1
  153. package/dist/opencode/plugin-templates/block-managed-file-edits.sh +78 -15
  154. package/dist/opencode/plugin-templates/block-no-verify.sh +21 -0
  155. package/dist/opencode/plugin-templates/guard-dedupe.bash +337 -0
  156. package/dist/opencode/plugin-templates/lisa-block-direct-issue-create.ts +242 -55
  157. package/dist/opencode/plugin-templates/parity-safety-net.sh +29 -1
  158. package/dist/strategies/package-lisa.d.ts.map +1 -1
  159. package/dist/strategies/package-lisa.js +2 -1
  160. package/dist/strategies/package-lisa.js.map +1 -1
  161. package/dist/utils/path-utils.d.ts +29 -0
  162. package/dist/utils/path-utils.d.ts.map +1 -1
  163. package/dist/utils/path-utils.js +41 -0
  164. package/dist/utils/path-utils.js.map +1 -1
  165. package/expo/create-only/.github/workflows/ci.yml +21 -0
  166. package/expo/create-only/.github/workflows/deploy.yml +28 -0
  167. package/expo/create-only/.github/workflows/maestro-e2e.yml +7 -0
  168. package/expo/create-only/.github/workflows/nightly-e2e-bypass-reaper.yml +124 -13
  169. package/expo/create-only/.github/workflows/nightly-e2e-health.yml +7 -0
  170. package/expo/create-only/.github/workflows/nightly-e2e-report.yml +7 -0
  171. package/expo/create-only/.github/workflows/nightly-e2e-tracking.yml +8 -0
  172. package/expo/create-only/.github/workflows/playwright-e2e.yml +7 -0
  173. package/harper-fabric/copy-overwrite/.github/workflows/ci.yml +7 -0
  174. package/harper-fabric/create-only/.github/workflows/deploy.yml +14 -0
  175. package/nestjs/create-only/.github/workflows/ci.yml +14 -0
  176. package/nestjs/create-only/.github/workflows/deploy.yml +28 -0
  177. package/package.json +10 -5
  178. package/phaser/copy-overwrite/.github/workflows/ci.yml +7 -0
  179. package/plugins/lisa/.claude-plugin/plugin.json +28 -1
  180. package/plugins/lisa/.codex-plugin/hooks.json +27 -0
  181. package/plugins/lisa/.codex-plugin/plugin.json +1 -1
  182. package/plugins/lisa/.codex-plugin/skills/lisa-drive-pr-to-merge/SKILL.md +130 -19
  183. package/plugins/lisa/.codex-plugin/skills/lisa-github-build-intake/SKILL.md +27 -4
  184. package/plugins/lisa/.codex-plugin/skills/lisa-github-prd-intake/SKILL.md +1 -1
  185. package/plugins/lisa/.codex-plugin/skills/lisa-github-validate-issue/SKILL.md +22 -0
  186. package/plugins/lisa/.codex-plugin/skills/lisa-github-verify/SKILL.md +14 -0
  187. package/plugins/lisa/.codex-plugin/skills/lisa-github-write-issue/SKILL.md +51 -0
  188. package/plugins/lisa/.codex-plugin/skills/lisa-intake/SKILL.md +1 -1
  189. package/plugins/lisa/.codex-plugin/skills/lisa-jira-build-intake/SKILL.md +27 -4
  190. package/plugins/lisa/.codex-plugin/skills/lisa-jira-validate-ticket/SKILL.md +22 -0
  191. package/plugins/lisa/.codex-plugin/skills/lisa-jira-verify/SKILL.md +14 -0
  192. package/plugins/lisa/.codex-plugin/skills/lisa-jira-write-ticket/SKILL.md +51 -0
  193. package/plugins/lisa/.codex-plugin/skills/lisa-linear-access/SKILL.md +55 -2
  194. package/plugins/lisa/.codex-plugin/skills/lisa-linear-build-intake/SKILL.md +27 -4
  195. package/plugins/lisa/.codex-plugin/skills/lisa-linear-prd-intake/SKILL.md +47 -30
  196. package/plugins/lisa/.codex-plugin/skills/lisa-linear-to-tracker/SKILL.md +3 -3
  197. package/plugins/lisa/.codex-plugin/skills/lisa-linear-validate-issue/SKILL.md +22 -0
  198. package/plugins/lisa/.codex-plugin/skills/lisa-linear-verify/SKILL.md +14 -0
  199. package/plugins/lisa/.codex-plugin/skills/lisa-linear-write-issue/SKILL.md +54 -3
  200. package/plugins/lisa/.codex-plugin/skills/lisa-prd-ticket-coverage/SKILL.md +2 -2
  201. package/plugins/lisa/.codex-plugin/skills/lisa-qa-clear/SKILL.md +19 -7
  202. package/plugins/lisa/.codex-plugin/skills/lisa-qa-fail/SKILL.md +28 -3
  203. package/plugins/lisa/.codex-plugin/skills/lisa-qa-queue/SKILL.md +28 -3
  204. package/plugins/lisa/.codex-plugin/skills/lisa-repair-intake/SKILL.md +94 -24
  205. package/plugins/lisa/.codex-plugin/skills/lisa-rework-triage/SKILL.md +32 -2
  206. package/plugins/lisa/.codex-plugin/skills/lisa-setup-linear/SKILL.md +4 -4
  207. package/plugins/lisa/.codex-plugin/skills/lisa-track/SKILL.md +1 -1
  208. package/plugins/lisa/.codex-plugin/skills/lisa-tracker-build-intake/SKILL.md +9 -0
  209. package/plugins/lisa/agents/linear-prd-intake.md +8 -8
  210. package/plugins/lisa/hooks/block-blind-automerge.sh +81 -2
  211. package/plugins/lisa/hooks/block-direct-issue-create.agy.sh +64 -16
  212. package/plugins/lisa/hooks/block-direct-issue-create.sh +293 -8
  213. package/plugins/lisa/hooks/block-instruction-file-edits.sh +21 -0
  214. package/plugins/lisa/hooks/block-managed-file-edits.sh +78 -15
  215. package/plugins/lisa/hooks/block-no-verify.sh +21 -0
  216. package/plugins/lisa/hooks/block-shell-json-parsing.sh +21 -0
  217. package/plugins/lisa/hooks/failure-signature-index.mjs +240 -5
  218. package/plugins/lisa/hooks/guard-dedupe.bash +337 -0
  219. package/plugins/lisa/hooks/inject-rules.sh +13 -5
  220. package/plugins/lisa/hooks/operational-hazards.mjs +736 -0
  221. package/plugins/lisa/hooks/operational-hazards.sh +28 -0
  222. package/plugins/lisa/hooks/parity-safety-net.sh +29 -1
  223. package/plugins/lisa/hooks/threshold-ratchet-compare.mjs +102 -21
  224. package/plugins/lisa/hooks/threshold-ratchet-families.mjs +130 -2
  225. package/plugins/lisa/hooks/threshold-ratchet.mjs +63 -13
  226. package/plugins/lisa/hooks/worktree-binding-guard.mjs +183 -1
  227. package/plugins/lisa/hooks/worktree-binding-guard.sh +21 -0
  228. package/plugins/lisa/rules/eager/00-rule-index.md +1 -0
  229. package/plugins/lisa/rules/eager/operational-hazards.md +50 -0
  230. package/plugins/lisa/rules/eager/tracked-work.md +1 -1
  231. package/plugins/lisa/rules/reference/config-resolution.md +1 -1
  232. package/plugins/lisa/rules/reference/leaf-only-lifecycle.md +1 -1
  233. package/plugins/lisa/rules/reference/operational-hazards.md +115 -0
  234. package/plugins/lisa/rules/reference/work-item-trailer-definition.md +129 -0
  235. package/plugins/lisa/scripts/intake-blocker-reprobe.mjs +407 -26
  236. package/plugins/lisa/scripts/qa-signal-lifecycle.mjs +507 -0
  237. package/plugins/lisa/skills/lisa-drive-pr-to-merge/SKILL.md +130 -19
  238. package/plugins/lisa/skills/lisa-github-build-intake/SKILL.md +27 -4
  239. package/plugins/lisa/skills/lisa-github-prd-intake/SKILL.md +1 -1
  240. package/plugins/lisa/skills/lisa-github-validate-issue/SKILL.md +22 -0
  241. package/plugins/lisa/skills/lisa-github-verify/SKILL.md +14 -0
  242. package/plugins/lisa/skills/lisa-github-write-issue/SKILL.md +51 -0
  243. package/plugins/lisa/skills/lisa-intake/SKILL.md +1 -1
  244. package/plugins/lisa/skills/lisa-jira-build-intake/SKILL.md +27 -4
  245. package/plugins/lisa/skills/lisa-jira-validate-ticket/SKILL.md +22 -0
  246. package/plugins/lisa/skills/lisa-jira-verify/SKILL.md +14 -0
  247. package/plugins/lisa/skills/lisa-jira-write-ticket/SKILL.md +51 -0
  248. package/plugins/lisa/skills/lisa-linear-access/SKILL.md +55 -2
  249. package/plugins/lisa/skills/lisa-linear-build-intake/SKILL.md +27 -4
  250. package/plugins/lisa/skills/lisa-linear-prd-intake/SKILL.md +48 -31
  251. package/plugins/lisa/skills/lisa-linear-to-tracker/SKILL.md +3 -3
  252. package/plugins/lisa/skills/lisa-linear-validate-issue/SKILL.md +22 -0
  253. package/plugins/lisa/skills/lisa-linear-verify/SKILL.md +14 -0
  254. package/plugins/lisa/skills/lisa-linear-write-issue/SKILL.md +54 -3
  255. package/plugins/lisa/skills/lisa-prd-ticket-coverage/SKILL.md +2 -2
  256. package/plugins/lisa/skills/lisa-qa-clear/SKILL.md +19 -7
  257. package/plugins/lisa/skills/lisa-qa-fail/SKILL.md +28 -3
  258. package/plugins/lisa/skills/lisa-qa-queue/SKILL.md +28 -3
  259. package/plugins/lisa/skills/lisa-repair-intake/SKILL.md +94 -24
  260. package/plugins/lisa/skills/lisa-rework-triage/SKILL.md +32 -2
  261. package/plugins/lisa/skills/lisa-setup-linear/SKILL.md +5 -5
  262. package/plugins/lisa/skills/lisa-track/SKILL.md +1 -1
  263. package/plugins/lisa/skills/lisa-tracker-build-intake/SKILL.md +9 -0
  264. package/plugins/lisa-agy/agents/linear-prd-intake.md +8 -8
  265. package/plugins/lisa-agy/hooks/block-blind-automerge.sh +81 -2
  266. package/plugins/lisa-agy/hooks/block-direct-issue-create.agy.sh +64 -16
  267. package/plugins/lisa-agy/hooks/block-direct-issue-create.sh +293 -8
  268. package/plugins/lisa-agy/hooks/block-instruction-file-edits.sh +21 -0
  269. package/plugins/lisa-agy/hooks/block-managed-file-edits.sh +78 -15
  270. package/plugins/lisa-agy/hooks/block-shell-json-parsing.sh +21 -0
  271. package/plugins/lisa-agy/hooks/guard-dedupe.bash +337 -0
  272. package/plugins/lisa-agy/hooks/parity-safety-net.sh +29 -1
  273. package/plugins/lisa-agy/hooks.json +1 -1
  274. package/plugins/lisa-agy/plugin.json +1 -1
  275. package/plugins/lisa-agy/scripts/intake-blocker-reprobe.mjs +407 -26
  276. package/plugins/lisa-agy/scripts/qa-signal-lifecycle.mjs +507 -0
  277. package/plugins/lisa-agy/skills/lisa-drive-pr-to-merge/SKILL.md +130 -19
  278. package/plugins/lisa-agy/skills/lisa-github-build-intake/SKILL.md +27 -4
  279. package/plugins/lisa-agy/skills/lisa-github-prd-intake/SKILL.md +1 -1
  280. package/plugins/lisa-agy/skills/lisa-github-validate-issue/SKILL.md +22 -0
  281. package/plugins/lisa-agy/skills/lisa-github-verify/SKILL.md +14 -0
  282. package/plugins/lisa-agy/skills/lisa-github-write-issue/SKILL.md +51 -0
  283. package/plugins/lisa-agy/skills/lisa-intake/SKILL.md +1 -1
  284. package/plugins/lisa-agy/skills/lisa-jira-build-intake/SKILL.md +27 -4
  285. package/plugins/lisa-agy/skills/lisa-jira-validate-ticket/SKILL.md +22 -0
  286. package/plugins/lisa-agy/skills/lisa-jira-verify/SKILL.md +14 -0
  287. package/plugins/lisa-agy/skills/lisa-jira-write-ticket/SKILL.md +51 -0
  288. package/plugins/lisa-agy/skills/lisa-linear-access/SKILL.md +55 -2
  289. package/plugins/lisa-agy/skills/lisa-linear-build-intake/SKILL.md +27 -4
  290. package/plugins/lisa-agy/skills/lisa-linear-prd-intake/SKILL.md +48 -31
  291. package/plugins/lisa-agy/skills/lisa-linear-to-tracker/SKILL.md +3 -3
  292. package/plugins/lisa-agy/skills/lisa-linear-validate-issue/SKILL.md +22 -0
  293. package/plugins/lisa-agy/skills/lisa-linear-verify/SKILL.md +14 -0
  294. package/plugins/lisa-agy/skills/lisa-linear-write-issue/SKILL.md +54 -3
  295. package/plugins/lisa-agy/skills/lisa-prd-ticket-coverage/SKILL.md +2 -2
  296. package/plugins/lisa-agy/skills/lisa-qa-clear/SKILL.md +19 -7
  297. package/plugins/lisa-agy/skills/lisa-qa-fail/SKILL.md +28 -3
  298. package/plugins/lisa-agy/skills/lisa-qa-queue/SKILL.md +28 -3
  299. package/plugins/lisa-agy/skills/lisa-repair-intake/SKILL.md +94 -24
  300. package/plugins/lisa-agy/skills/lisa-rework-triage/SKILL.md +32 -2
  301. package/plugins/lisa-agy/skills/lisa-setup-linear/SKILL.md +5 -5
  302. package/plugins/lisa-agy/skills/lisa-track/SKILL.md +1 -1
  303. package/plugins/lisa-agy/skills/lisa-tracker-build-intake/SKILL.md +9 -0
  304. package/plugins/lisa-cdk/.claude-plugin/plugin.json +1 -1
  305. package/plugins/lisa-cdk/.codex-plugin/plugin.json +1 -1
  306. package/plugins/lisa-cdk-agy/plugin.json +1 -1
  307. package/plugins/lisa-cdk-copilot/.claude-plugin/plugin.json +1 -1
  308. package/plugins/lisa-cdk-cursor/.claude-plugin/plugin.json +1 -1
  309. package/plugins/lisa-copilot/.claude-plugin/plugin.json +19 -1
  310. package/plugins/lisa-copilot/agents/linear-prd-intake.agent.md +8 -8
  311. package/plugins/lisa-copilot/hooks/block-blind-automerge.sh +81 -2
  312. package/plugins/lisa-copilot/hooks/block-direct-issue-create.sh +293 -8
  313. package/plugins/lisa-copilot/hooks/block-instruction-file-edits.sh +21 -0
  314. package/plugins/lisa-copilot/hooks/block-managed-file-edits.sh +78 -15
  315. package/plugins/lisa-copilot/hooks/block-no-verify.sh +21 -0
  316. package/plugins/lisa-copilot/hooks/block-shell-json-parsing.sh +21 -0
  317. package/plugins/lisa-copilot/hooks/failure-signature-index.mjs +240 -5
  318. package/plugins/lisa-copilot/hooks/guard-dedupe.bash +337 -0
  319. package/plugins/lisa-copilot/hooks/inject-rules.sh +13 -5
  320. package/plugins/lisa-copilot/hooks/operational-hazards.mjs +736 -0
  321. package/plugins/lisa-copilot/hooks/operational-hazards.sh +28 -0
  322. package/plugins/lisa-copilot/hooks/parity-safety-net.sh +29 -1
  323. package/plugins/lisa-copilot/hooks/threshold-ratchet-compare.mjs +102 -21
  324. package/plugins/lisa-copilot/hooks/threshold-ratchet-families.mjs +130 -2
  325. package/plugins/lisa-copilot/hooks/threshold-ratchet.mjs +63 -13
  326. package/plugins/lisa-copilot/hooks/worktree-binding-guard.mjs +183 -1
  327. package/plugins/lisa-copilot/hooks/worktree-binding-guard.sh +21 -0
  328. package/plugins/lisa-copilot/rules/eager/00-rule-index.md +1 -0
  329. package/plugins/lisa-copilot/rules/eager/operational-hazards.md +50 -0
  330. package/plugins/lisa-copilot/rules/eager/tracked-work.md +1 -1
  331. package/plugins/lisa-copilot/rules/reference/config-resolution.md +1 -1
  332. package/plugins/lisa-copilot/rules/reference/leaf-only-lifecycle.md +1 -1
  333. package/plugins/lisa-copilot/rules/reference/operational-hazards.md +115 -0
  334. package/plugins/lisa-copilot/rules/reference/work-item-trailer-definition.md +129 -0
  335. package/plugins/lisa-copilot/scripts/intake-blocker-reprobe.mjs +407 -26
  336. package/plugins/lisa-copilot/scripts/qa-signal-lifecycle.mjs +507 -0
  337. package/plugins/lisa-copilot/skills/lisa-drive-pr-to-merge/SKILL.md +130 -19
  338. package/plugins/lisa-copilot/skills/lisa-github-build-intake/SKILL.md +27 -4
  339. package/plugins/lisa-copilot/skills/lisa-github-prd-intake/SKILL.md +1 -1
  340. package/plugins/lisa-copilot/skills/lisa-github-validate-issue/SKILL.md +22 -0
  341. package/plugins/lisa-copilot/skills/lisa-github-verify/SKILL.md +14 -0
  342. package/plugins/lisa-copilot/skills/lisa-github-write-issue/SKILL.md +51 -0
  343. package/plugins/lisa-copilot/skills/lisa-intake/SKILL.md +1 -1
  344. package/plugins/lisa-copilot/skills/lisa-jira-build-intake/SKILL.md +27 -4
  345. package/plugins/lisa-copilot/skills/lisa-jira-validate-ticket/SKILL.md +22 -0
  346. package/plugins/lisa-copilot/skills/lisa-jira-verify/SKILL.md +14 -0
  347. package/plugins/lisa-copilot/skills/lisa-jira-write-ticket/SKILL.md +51 -0
  348. package/plugins/lisa-copilot/skills/lisa-linear-access/SKILL.md +55 -2
  349. package/plugins/lisa-copilot/skills/lisa-linear-build-intake/SKILL.md +27 -4
  350. package/plugins/lisa-copilot/skills/lisa-linear-prd-intake/SKILL.md +48 -31
  351. package/plugins/lisa-copilot/skills/lisa-linear-to-tracker/SKILL.md +3 -3
  352. package/plugins/lisa-copilot/skills/lisa-linear-validate-issue/SKILL.md +22 -0
  353. package/plugins/lisa-copilot/skills/lisa-linear-verify/SKILL.md +14 -0
  354. package/plugins/lisa-copilot/skills/lisa-linear-write-issue/SKILL.md +54 -3
  355. package/plugins/lisa-copilot/skills/lisa-prd-ticket-coverage/SKILL.md +2 -2
  356. package/plugins/lisa-copilot/skills/lisa-qa-clear/SKILL.md +19 -7
  357. package/plugins/lisa-copilot/skills/lisa-qa-fail/SKILL.md +28 -3
  358. package/plugins/lisa-copilot/skills/lisa-qa-queue/SKILL.md +28 -3
  359. package/plugins/lisa-copilot/skills/lisa-repair-intake/SKILL.md +94 -24
  360. package/plugins/lisa-copilot/skills/lisa-rework-triage/SKILL.md +32 -2
  361. package/plugins/lisa-copilot/skills/lisa-setup-linear/SKILL.md +5 -5
  362. package/plugins/lisa-copilot/skills/lisa-track/SKILL.md +1 -1
  363. package/plugins/lisa-copilot/skills/lisa-tracker-build-intake/SKILL.md +9 -0
  364. package/plugins/lisa-cursor/.claude-plugin/plugin.json +1 -1
  365. package/plugins/lisa-cursor/agents/linear-prd-intake.md +8 -8
  366. package/plugins/lisa-cursor/hooks/block-blind-automerge.sh +81 -2
  367. package/plugins/lisa-cursor/hooks/block-direct-issue-create.sh +293 -8
  368. package/plugins/lisa-cursor/hooks/block-instruction-file-edits.sh +21 -0
  369. package/plugins/lisa-cursor/hooks/block-managed-file-edits.sh +78 -15
  370. package/plugins/lisa-cursor/hooks/block-no-verify.sh +21 -0
  371. package/plugins/lisa-cursor/hooks/block-shell-json-parsing.sh +21 -0
  372. package/plugins/lisa-cursor/hooks/failure-signature-index.mjs +240 -5
  373. package/plugins/lisa-cursor/hooks/guard-dedupe.bash +337 -0
  374. package/plugins/lisa-cursor/hooks/hooks.json +10 -0
  375. package/plugins/lisa-cursor/hooks/operational-hazards.mjs +736 -0
  376. package/plugins/lisa-cursor/hooks/operational-hazards.sh +28 -0
  377. package/plugins/lisa-cursor/hooks/parity-safety-net.sh +29 -1
  378. package/plugins/lisa-cursor/hooks/threshold-ratchet-compare.mjs +102 -21
  379. package/plugins/lisa-cursor/hooks/threshold-ratchet-families.mjs +130 -2
  380. package/plugins/lisa-cursor/hooks/threshold-ratchet.mjs +63 -13
  381. package/plugins/lisa-cursor/hooks/worktree-binding-guard.mjs +183 -1
  382. package/plugins/lisa-cursor/hooks/worktree-binding-guard.sh +21 -0
  383. package/plugins/lisa-cursor/rules/00-rule-index.mdc +1 -0
  384. package/plugins/lisa-cursor/rules/config-resolution-reference.mdc +1 -1
  385. package/plugins/lisa-cursor/rules/leaf-only-lifecycle-reference.mdc +1 -1
  386. package/plugins/lisa-cursor/rules/operational-hazards-reference.mdc +120 -0
  387. package/plugins/lisa-cursor/rules/operational-hazards.mdc +55 -0
  388. package/plugins/lisa-cursor/rules/tracked-work.mdc +1 -1
  389. package/plugins/lisa-cursor/rules/work-item-trailer-definition-reference.mdc +134 -0
  390. package/plugins/lisa-cursor/scripts/intake-blocker-reprobe.mjs +407 -26
  391. package/plugins/lisa-cursor/scripts/qa-signal-lifecycle.mjs +507 -0
  392. package/plugins/lisa-cursor/skills/lisa-drive-pr-to-merge/SKILL.md +130 -19
  393. package/plugins/lisa-cursor/skills/lisa-github-build-intake/SKILL.md +27 -4
  394. package/plugins/lisa-cursor/skills/lisa-github-prd-intake/SKILL.md +1 -1
  395. package/plugins/lisa-cursor/skills/lisa-github-validate-issue/SKILL.md +22 -0
  396. package/plugins/lisa-cursor/skills/lisa-github-verify/SKILL.md +14 -0
  397. package/plugins/lisa-cursor/skills/lisa-github-write-issue/SKILL.md +51 -0
  398. package/plugins/lisa-cursor/skills/lisa-intake/SKILL.md +1 -1
  399. package/plugins/lisa-cursor/skills/lisa-jira-build-intake/SKILL.md +27 -4
  400. package/plugins/lisa-cursor/skills/lisa-jira-validate-ticket/SKILL.md +22 -0
  401. package/plugins/lisa-cursor/skills/lisa-jira-verify/SKILL.md +14 -0
  402. package/plugins/lisa-cursor/skills/lisa-jira-write-ticket/SKILL.md +51 -0
  403. package/plugins/lisa-cursor/skills/lisa-linear-access/SKILL.md +55 -2
  404. package/plugins/lisa-cursor/skills/lisa-linear-build-intake/SKILL.md +27 -4
  405. package/plugins/lisa-cursor/skills/lisa-linear-prd-intake/SKILL.md +48 -31
  406. package/plugins/lisa-cursor/skills/lisa-linear-to-tracker/SKILL.md +3 -3
  407. package/plugins/lisa-cursor/skills/lisa-linear-validate-issue/SKILL.md +22 -0
  408. package/plugins/lisa-cursor/skills/lisa-linear-verify/SKILL.md +14 -0
  409. package/plugins/lisa-cursor/skills/lisa-linear-write-issue/SKILL.md +54 -3
  410. package/plugins/lisa-cursor/skills/lisa-prd-ticket-coverage/SKILL.md +2 -2
  411. package/plugins/lisa-cursor/skills/lisa-qa-clear/SKILL.md +19 -7
  412. package/plugins/lisa-cursor/skills/lisa-qa-fail/SKILL.md +28 -3
  413. package/plugins/lisa-cursor/skills/lisa-qa-queue/SKILL.md +28 -3
  414. package/plugins/lisa-cursor/skills/lisa-repair-intake/SKILL.md +94 -24
  415. package/plugins/lisa-cursor/skills/lisa-rework-triage/SKILL.md +32 -2
  416. package/plugins/lisa-cursor/skills/lisa-setup-linear/SKILL.md +5 -5
  417. package/plugins/lisa-cursor/skills/lisa-track/SKILL.md +1 -1
  418. package/plugins/lisa-cursor/skills/lisa-tracker-build-intake/SKILL.md +9 -0
  419. package/plugins/lisa-expo/.claude-plugin/plugin.json +1 -1
  420. package/plugins/lisa-expo/.codex-plugin/plugin.json +1 -1
  421. package/plugins/lisa-expo-agy/plugin.json +1 -1
  422. package/plugins/lisa-expo-copilot/.claude-plugin/plugin.json +1 -1
  423. package/plugins/lisa-expo-cursor/.claude-plugin/plugin.json +1 -1
  424. package/plugins/lisa-harper-fabric/.claude-plugin/plugin.json +1 -1
  425. package/plugins/lisa-harper-fabric/.codex-plugin/plugin.json +1 -1
  426. package/plugins/lisa-harper-fabric/hooks/inject-rules.sh +14 -3
  427. package/plugins/lisa-harper-fabric/rules/eager/harper-fabric.md +31 -0
  428. package/plugins/lisa-harper-fabric-agy/plugin.json +1 -1
  429. package/plugins/lisa-harper-fabric-copilot/.claude-plugin/plugin.json +1 -1
  430. package/plugins/lisa-harper-fabric-copilot/hooks/inject-rules.sh +14 -3
  431. package/plugins/lisa-harper-fabric-copilot/rules/eager/harper-fabric.md +31 -0
  432. package/plugins/lisa-harper-fabric-cursor/.claude-plugin/plugin.json +1 -1
  433. package/plugins/lisa-harper-fabric-cursor/rules/harper-fabric-reference.mdc +57 -0
  434. package/plugins/lisa-harper-fabric-cursor/rules/harper-fabric.mdc +32 -53
  435. package/plugins/lisa-nestjs/.claude-plugin/plugin.json +1 -1
  436. package/plugins/lisa-nestjs/.codex-plugin/plugin.json +1 -1
  437. package/plugins/lisa-nestjs-agy/plugin.json +1 -1
  438. package/plugins/lisa-nestjs-copilot/.claude-plugin/plugin.json +1 -1
  439. package/plugins/lisa-nestjs-cursor/.claude-plugin/plugin.json +1 -1
  440. package/plugins/lisa-openclaw/.claude-plugin/plugin.json +1 -1
  441. package/plugins/lisa-openclaw/.codex-plugin/plugin.json +1 -1
  442. package/plugins/lisa-openclaw-agy/plugin.json +1 -1
  443. package/plugins/lisa-openclaw-copilot/.claude-plugin/plugin.json +1 -1
  444. package/plugins/lisa-openclaw-cursor/.claude-plugin/plugin.json +1 -1
  445. package/plugins/lisa-phaser/.claude-plugin/plugin.json +1 -1
  446. package/plugins/lisa-phaser/.codex-plugin/plugin.json +1 -1
  447. package/plugins/lisa-phaser/hooks/inject-rules.sh +14 -3
  448. package/plugins/lisa-phaser/rules/eager/phaser.md +44 -0
  449. package/plugins/lisa-phaser-agy/plugin.json +1 -1
  450. package/plugins/lisa-phaser-copilot/.claude-plugin/plugin.json +1 -1
  451. package/plugins/lisa-phaser-copilot/hooks/inject-rules.sh +14 -3
  452. package/plugins/lisa-phaser-copilot/rules/eager/phaser.md +44 -0
  453. package/plugins/lisa-phaser-cursor/.claude-plugin/plugin.json +1 -1
  454. package/plugins/lisa-phaser-cursor/rules/phaser-reference.mdc +189 -0
  455. package/plugins/lisa-phaser-cursor/rules/phaser.mdc +45 -185
  456. package/plugins/lisa-rails/.claude-plugin/plugin.json +1 -1
  457. package/plugins/lisa-rails/.codex-plugin/plugin.json +1 -1
  458. package/plugins/lisa-rails/hooks/inject-rules.sh +14 -4
  459. package/plugins/lisa-rails/rules/eager/rails-conventions.md +23 -0
  460. package/plugins/lisa-rails-agy/plugin.json +1 -1
  461. package/plugins/lisa-rails-copilot/.claude-plugin/plugin.json +1 -1
  462. package/plugins/lisa-rails-copilot/hooks/inject-rules.sh +14 -4
  463. package/plugins/lisa-rails-copilot/rules/eager/rails-conventions.md +23 -0
  464. package/plugins/lisa-rails-cursor/.claude-plugin/plugin.json +1 -1
  465. package/plugins/lisa-rails-cursor/rules/rails-conventions-reference.mdc +181 -0
  466. package/plugins/lisa-rails-cursor/rules/rails-conventions.mdc +24 -177
  467. package/plugins/lisa-typescript/.claude-plugin/plugin.json +1 -1
  468. package/plugins/lisa-typescript/.codex-plugin/plugin.json +1 -1
  469. package/plugins/lisa-typescript-agy/plugin.json +1 -1
  470. package/plugins/lisa-typescript-copilot/.claude-plugin/plugin.json +1 -1
  471. package/plugins/lisa-typescript-cursor/.claude-plugin/plugin.json +1 -1
  472. package/plugins/lisa-wiki/.claude-plugin/plugin.json +1 -1
  473. package/plugins/lisa-wiki/.codex-plugin/plugin.json +1 -1
  474. package/plugins/lisa-wiki-agy/plugin.json +1 -1
  475. package/plugins/lisa-wiki-copilot/.claude-plugin/plugin.json +1 -1
  476. package/plugins/lisa-wiki-cursor/.claude-plugin/plugin.json +1 -1
  477. package/plugins/materialized-artifacts.json +1 -0
  478. package/plugins/src/base/.claude-plugin/plugin.json +27 -0
  479. package/plugins/src/base/agents/linear-prd-intake.md +8 -8
  480. package/plugins/src/base/hooks/block-blind-automerge.sh +81 -2
  481. package/plugins/src/base/hooks/block-direct-issue-create.agy.sh +64 -16
  482. package/plugins/src/base/hooks/block-direct-issue-create.sh +293 -8
  483. package/plugins/src/base/hooks/block-instruction-file-edits.sh +21 -0
  484. package/plugins/src/base/hooks/block-managed-file-edits.sh +78 -15
  485. package/plugins/src/base/hooks/block-no-verify.sh +21 -0
  486. package/plugins/src/base/hooks/block-shell-json-parsing.sh +21 -0
  487. package/plugins/src/base/hooks/failure-signature-index.mjs +240 -5
  488. package/plugins/src/base/hooks/guard-dedupe.bash +337 -0
  489. package/plugins/src/base/hooks/inject-rules.sh +13 -5
  490. package/plugins/src/base/hooks/operational-hazards.mjs +736 -0
  491. package/plugins/src/base/hooks/operational-hazards.sh +28 -0
  492. package/plugins/src/base/hooks/parity-safety-net.sh +29 -1
  493. package/plugins/src/base/hooks/threshold-ratchet-compare.mjs +102 -21
  494. package/plugins/src/base/hooks/threshold-ratchet-families.mjs +130 -2
  495. package/plugins/src/base/hooks/threshold-ratchet.mjs +63 -13
  496. package/plugins/src/base/hooks/worktree-binding-guard.mjs +183 -1
  497. package/plugins/src/base/hooks/worktree-binding-guard.sh +21 -0
  498. package/plugins/src/base/rules/eager/00-rule-index.md +1 -0
  499. package/plugins/src/base/rules/eager/operational-hazards.md +50 -0
  500. package/plugins/src/base/rules/eager/tracked-work.md +1 -1
  501. package/plugins/src/base/rules/reference/config-resolution.md +1 -1
  502. package/plugins/src/base/rules/reference/leaf-only-lifecycle.md +1 -1
  503. package/plugins/src/base/rules/reference/operational-hazards.md +115 -0
  504. package/plugins/src/base/rules/reference/work-item-trailer-definition.md +129 -0
  505. package/plugins/src/base/scripts/intake-blocker-reprobe.mjs +407 -26
  506. package/plugins/src/base/scripts/qa-signal-lifecycle.mjs +507 -0
  507. package/plugins/src/base/skills/lisa-drive-pr-to-merge/SKILL.md +130 -19
  508. package/plugins/src/base/skills/lisa-github-build-intake/SKILL.md +27 -4
  509. package/plugins/src/base/skills/lisa-github-prd-intake/SKILL.md +1 -1
  510. package/plugins/src/base/skills/lisa-github-validate-issue/SKILL.md +22 -0
  511. package/plugins/src/base/skills/lisa-github-verify/SKILL.md +14 -0
  512. package/plugins/src/base/skills/lisa-github-write-issue/SKILL.md +51 -0
  513. package/plugins/src/base/skills/lisa-intake/SKILL.md +1 -1
  514. package/plugins/src/base/skills/lisa-jira-build-intake/SKILL.md +27 -4
  515. package/plugins/src/base/skills/lisa-jira-validate-ticket/SKILL.md +22 -0
  516. package/plugins/src/base/skills/lisa-jira-verify/SKILL.md +14 -0
  517. package/plugins/src/base/skills/lisa-jira-write-ticket/SKILL.md +51 -0
  518. package/plugins/src/base/skills/lisa-linear-access/SKILL.md +55 -2
  519. package/plugins/src/base/skills/lisa-linear-build-intake/SKILL.md +27 -4
  520. package/plugins/src/base/skills/lisa-linear-prd-intake/SKILL.md +48 -31
  521. package/plugins/src/base/skills/lisa-linear-to-tracker/SKILL.md +3 -3
  522. package/plugins/src/base/skills/lisa-linear-validate-issue/SKILL.md +22 -0
  523. package/plugins/src/base/skills/lisa-linear-verify/SKILL.md +14 -0
  524. package/plugins/src/base/skills/lisa-linear-write-issue/SKILL.md +54 -3
  525. package/plugins/src/base/skills/lisa-prd-ticket-coverage/SKILL.md +2 -2
  526. package/plugins/src/base/skills/lisa-qa-clear/SKILL.md +19 -7
  527. package/plugins/src/base/skills/lisa-qa-fail/SKILL.md +28 -3
  528. package/plugins/src/base/skills/lisa-qa-queue/SKILL.md +28 -3
  529. package/plugins/src/base/skills/lisa-repair-intake/SKILL.md +94 -24
  530. package/plugins/src/base/skills/lisa-rework-triage/SKILL.md +32 -2
  531. package/plugins/src/base/skills/lisa-setup-linear/SKILL.md +5 -5
  532. package/plugins/src/base/skills/lisa-track/SKILL.md +1 -1
  533. package/plugins/src/base/skills/lisa-tracker-build-intake/SKILL.md +9 -0
  534. package/plugins/src/harper-fabric/hooks/inject-rules.sh +14 -3
  535. package/plugins/src/harper-fabric/rules/eager/harper-fabric.md +31 -0
  536. package/plugins/src/phaser/hooks/inject-rules.sh +14 -3
  537. package/plugins/src/phaser/rules/eager/phaser.md +44 -0
  538. package/plugins/src/rails/hooks/inject-rules.sh +14 -4
  539. package/plugins/src/rails/rules/eager/rails-conventions.md +23 -0
  540. package/rails/copy-overwrite/scripts/check-threshold-ratchet.mjs +63 -13
  541. package/rails/copy-overwrite/scripts/threshold-ratchet-compare.mjs +102 -21
  542. package/rails/copy-overwrite/scripts/threshold-ratchet-families.mjs +130 -2
  543. package/rails/create-only/.github/workflows/ci.yml +8 -0
  544. package/rails/create-only/.github/workflows/deploy.yml +22 -0
  545. package/scripts/build-plugins.sh +2 -1
  546. package/scripts/check-engine-floor.mjs +361 -0
  547. package/scripts/check-guard-parity-notes.mjs +709 -0
  548. package/scripts/check-template-workflow-refs.mjs +9 -0
  549. package/scripts/check-third-party-action-pins.mjs +17 -1
  550. package/scripts/check-workflow-contract-assertions.mjs +480 -0
  551. package/scripts/copy-opencode-plugin-templates.mjs +1 -0
  552. package/scripts/deployed-guard-advice.mjs +636 -0
  553. package/scripts/generate-agy-plugin-artifacts.mjs +35 -10
  554. package/scripts/generate-export-surface.mjs +105 -19
  555. package/scripts/generate-two-channel-couplings.ts +143 -212
  556. package/scripts/lisa-enforcement-fallback.sh +31 -0
  557. package/scripts/measure-scripts-profile-gap.mts +361 -0
  558. package/scripts/mutation-performance-measure.mjs +21 -5
  559. package/scripts/reconcile-release-tags.mjs +65 -84
  560. package/scripts/two-channel-couplings.json +302 -70
  561. package/scripts/workflow-contract-assertion.sh +47 -0
  562. package/typescript/copy-overwrite/.lintstagedrc.json +1 -0
  563. package/typescript/copy-overwrite/eslint.ignore.config.json +1 -0
  564. package/typescript/copy-overwrite/scripts/check-nightly-e2e-health.mjs +527 -53
  565. package/typescript/copy-overwrite/scripts/check-skipped-required-checks.mjs +301 -13
  566. package/typescript/copy-overwrite/scripts/check-threshold-ratchet.mjs +63 -13
  567. package/typescript/copy-overwrite/scripts/threshold-ratchet-compare.mjs +102 -21
  568. package/typescript/copy-overwrite/scripts/threshold-ratchet-families.mjs +130 -2
  569. package/typescript/create-only/.github/workflows/ci.yml +7 -0
  570. /package/plugins/lisa-harper-fabric/rules/{harper-fabric.md → reference/harper-fabric.md} +0 -0
  571. /package/plugins/lisa-harper-fabric-copilot/rules/{harper-fabric.md → reference/harper-fabric.md} +0 -0
  572. /package/plugins/lisa-phaser/rules/{phaser.md → reference/phaser.md} +0 -0
  573. /package/plugins/lisa-phaser-copilot/rules/{phaser.md → reference/phaser.md} +0 -0
  574. /package/plugins/lisa-rails/rules/{rails-conventions.md → reference/rails-conventions.md} +0 -0
  575. /package/plugins/lisa-rails-copilot/rules/{rails-conventions.md → reference/rails-conventions.md} +0 -0
  576. /package/plugins/src/harper-fabric/rules/{harper-fabric.md → reference/harper-fabric.md} +0 -0
  577. /package/plugins/src/phaser/rules/{phaser.md → reference/phaser.md} +0 -0
  578. /package/plugins/src/rails/rules/{rails-conventions.md → reference/rails-conventions.md} +0 -0
@@ -0,0 +1,197 @@
1
+ /**
2
+ * `lisa doctor` check: does this Rails project SAY why it does not deploy
3
+ * production?
4
+ *
5
+ * The seed was fixed so a new adoption inherits a deploy workflow that
6
+ * explains the withheld `main` trigger. That fix reaches new adoptions only:
7
+ * `rails/create-only/.github/workflows/deploy.yml` is written once and never
8
+ * refreshed, and the file is host-owned from that moment — the header says so,
9
+ * and the template invites customisation — so a migration that rewrote it
10
+ * would break the promise `create-only` makes. Nothing else in Lisa ever looks
11
+ * at the file again, which left every project seeded before the fix carrying a
12
+ * bare `# - main` that nobody can tell apart from an oversight, in a
13
+ * population whose size nobody knows (CodySwannGT/lisa#3743,
14
+ * CodySwannGT/lisa#3779).
15
+ *
16
+ * This check REPORTS and names the remedy. It edits nothing, exactly as the
17
+ * apply path refuses to.
18
+ *
19
+ * The point is that an affected project can find ITSELF, so a probe that
20
+ * cannot look must never render as a project with nothing to report. Every
21
+ * filesystem answer is three-valued — present, absent, or undeterminable —
22
+ * and the last one fails rather than passing quietly. Three statuses for three
23
+ * different facts: `ok` is nothing to state, `warn` is intent left unstated
24
+ * (a human decides, on a file Lisa will not touch), and `fail` is this check
25
+ * being unable to answer at all.
26
+ * @module cli/doctor-rails-deploy-intent
27
+ */
28
+ import { readFile, stat } from "node:fs/promises";
29
+ import * as path from "node:path";
30
+ import { classifyProductionDeployIntent } from "../core/rails-deploy-production-intent.js";
31
+ /** Name of the deploy-intent check as doctor reports it. */
32
+ export const RAILS_DEPLOY_INTENT_CHECK_NAME = "Rails production deploy intent stated?";
33
+ /** Repo-relative deploy workflow this template seeds. */
34
+ const DEPLOY_WORKFLOW = ".github/workflows/deploy.yml";
35
+ /**
36
+ * Markers that identify a Rails checkout, matching the Rails project-type
37
+ * detector: `bin/rails` first, `config/application.rb` second. Both are
38
+ * definitive; other Ruby frameworks ship neither.
39
+ */
40
+ const RAILS_MARKERS = ["bin/rails", "config/application.rb"];
41
+ /**
42
+ * Errno codes that ANSWER the question rather than refusing it: the path is
43
+ * genuinely not there. Anything else — a permission denial, an I/O error, a
44
+ * symlink loop — means the probe could not look, which is a different answer
45
+ * and must not be spelled the same way.
46
+ */
47
+ const ABSENT_CODES = new Set(["ENOENT", "ENOTDIR", "ENAMETOOLONG"]);
48
+ /**
49
+ * The errno code of a rejected filesystem call, when it carries one.
50
+ * @param error - Value thrown by a filesystem call
51
+ * @returns The errno code, or undefined when the value carries none
52
+ */
53
+ function errnoCode(error) {
54
+ const code = typeof error === "object" && error !== null
55
+ ? error.code
56
+ : undefined;
57
+ return typeof code === "string" ? code : undefined;
58
+ }
59
+ /**
60
+ * Re-throw a filesystem rejection unless it is a definitive absence.
61
+ *
62
+ * `fs-extra`'s `pathExists` resolves false for every failure, including a
63
+ * permission denial, so a directory this process cannot read would report the
64
+ * same "not a Rails project" as a Node repo.
65
+ * @param error - Value thrown by a filesystem call
66
+ * @param relativePath - Repo-relative path being probed
67
+ * @throws {Error} When the filesystem declined to answer
68
+ */
69
+ function rethrowUnlessAbsent(error, relativePath) {
70
+ const code = errnoCode(error);
71
+ if (code !== undefined && ABSENT_CODES.has(code))
72
+ return;
73
+ throw new Error(`could not read ${relativePath}: ${code ?? String(error)}`, {
74
+ cause: error,
75
+ });
76
+ }
77
+ /**
78
+ * Is this a Rails checkout, REJECTING when the filesystem declines to say?
79
+ * @param projectRoot - Absolute project root
80
+ * @returns True when a Rails marker is present
81
+ * @throws {Error} When a marker can be neither confirmed nor ruled out
82
+ */
83
+ async function isRailsProject(projectRoot) {
84
+ for (const marker of RAILS_MARKERS) {
85
+ try {
86
+ await stat(path.join(projectRoot, marker));
87
+ return true;
88
+ }
89
+ catch (error) {
90
+ rethrowUnlessAbsent(error, marker);
91
+ }
92
+ }
93
+ return false;
94
+ }
95
+ /**
96
+ * Read the deploy workflow, REJECTING when the filesystem declines to say.
97
+ * @param projectRoot - Absolute project root
98
+ * @returns Workflow source, or null when the file is provably absent
99
+ * @throws {Error} When the file exists but could not be read
100
+ */
101
+ async function readDeployWorkflow(projectRoot) {
102
+ try {
103
+ return await readFile(path.join(projectRoot, DEPLOY_WORKFLOW), "utf8");
104
+ }
105
+ catch (error) {
106
+ rethrowUnlessAbsent(error, DEPLOY_WORKFLOW);
107
+ return null;
108
+ }
109
+ }
110
+ /**
111
+ * What an operator has to make true before uncommenting the entry, stated
112
+ * here because the project's own copy of the workflow is precisely the file
113
+ * that does not say.
114
+ */
115
+ const ENABLING_PRECONDITIONS = "a repository secret named `AWS_ACCOUNT_ID_MAIN` holding the production " +
116
+ "account id (`noliran/branch-based-secrets` expands `AWS_ACCOUNT_ID` to " +
117
+ "`AWS_ACCOUNT_ID_<BRANCH IN UPPERCASE>`, so without it the account id " +
118
+ "resolves empty and the deploy fails at the credentials step); a " +
119
+ "`DeployServiceRole` in that account trusting this repository's OIDC " +
120
+ "subject; the ECS cluster, services and ECR repositories this workflow " +
121
+ "names in `env:`, whose names are fixed rather than suffixed per " +
122
+ "environment; and a `production` environment in the Rails app";
123
+ /** Operator-facing statement of the finding and its remedy. */
124
+ const UNSTATED_DETAIL = `${DEPLOY_WORKFLOW} comments out its \`main\` branch entry with nothing ` +
125
+ "saying why, so production deployment being off cannot be told apart from " +
126
+ "a line someone dropped by mistake. Lisa seeded this file once and will " +
127
+ `not rewrite it. Enabling production needs ${ENABLING_PRECONDITIONS}. ` +
128
+ "Uncomment `- main` once all four hold; until then, record beside the " +
129
+ "commented entry that it is deliberate, so the next reader is not left " +
130
+ "guessing. Production stays reachable by hand meanwhile through this " +
131
+ "workflow's `workflow_dispatch` trigger";
132
+ /**
133
+ * Report whether a Rails project's deploy workflow states its production
134
+ * intent.
135
+ *
136
+ * Warns rather than fails on a hit: nothing is broken, and the remedy is a
137
+ * human decision about a host-owned file. Fails when the question could not
138
+ * be answered, for the reason in the module note.
139
+ * @param targetPath - Project path to inspect
140
+ * @returns Doctor check result
141
+ */
142
+ export async function checkRailsDeployIntent(targetPath) {
143
+ try {
144
+ const root = await stat(targetPath);
145
+ if (!root.isDirectory()) {
146
+ throw new Error(`${targetPath} is not a directory`);
147
+ }
148
+ if (!(await isRailsProject(targetPath))) {
149
+ return ok("Not a Rails project");
150
+ }
151
+ const workflowText = await readDeployWorkflow(targetPath);
152
+ if (workflowText === null) {
153
+ return ok(`No ${DEPLOY_WORKFLOW} in this project`);
154
+ }
155
+ return describeIntent(workflowText);
156
+ }
157
+ catch (error) {
158
+ return {
159
+ name: RAILS_DEPLOY_INTENT_CHECK_NAME,
160
+ status: "fail",
161
+ detail: `Could not determine whether ${DEPLOY_WORKFLOW} states its ` +
162
+ `production deploy intent: ${error instanceof Error ? error.message : String(error)}. Treated as a failure rather than a pass: a workflow that could ` +
163
+ "not be read is not one with nothing in it",
164
+ };
165
+ }
166
+ }
167
+ /**
168
+ * Turn a parsed workflow into the check line it earns.
169
+ * @param workflowText - Full deploy workflow source
170
+ * @returns Doctor check result
171
+ * @throws {Error} When the workflow cannot be parsed
172
+ */
173
+ function describeIntent(workflowText) {
174
+ switch (classifyProductionDeployIntent(workflowText)) {
175
+ case "triggers":
176
+ return ok(`${DEPLOY_WORKFLOW} deploys production from \`main\``);
177
+ case "explained":
178
+ return ok(`${DEPLOY_WORKFLOW} states why production is withheld`);
179
+ case "unmentioned":
180
+ return ok(`${DEPLOY_WORKFLOW} carries no commented-out \`main\` entry`);
181
+ default:
182
+ return {
183
+ name: RAILS_DEPLOY_INTENT_CHECK_NAME,
184
+ status: "warn",
185
+ detail: UNSTATED_DETAIL,
186
+ };
187
+ }
188
+ }
189
+ /**
190
+ * A passing line for this check.
191
+ * @param detail - What was found
192
+ * @returns Doctor check result
193
+ */
194
+ function ok(detail) {
195
+ return { name: RAILS_DEPLOY_INTENT_CHECK_NAME, status: "ok", detail };
196
+ }
197
+ //# sourceMappingURL=doctor-rails-deploy-intent.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"doctor-rails-deploy-intent.js","sourceRoot":"","sources":["../../src/cli/doctor-rails-deploy-intent.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ import type { DoctorCheck } from "./doctor.js";
2
+ /**
3
+ * Run every seeded-artifact check, in the order an operator reads them.
4
+ *
5
+ * Sequential rather than concurrent, matching the surrounding checks: they
6
+ * share a target directory and the report is read top to bottom, so a stable
7
+ * order is worth more here than the milliseconds.
8
+ * @param targetPath - Repository root to inspect
9
+ * @returns One check row per question, in report order
10
+ */
11
+ export declare function checkSeededArtifacts(targetPath: string): Promise<readonly DoctorCheck[]>;
12
+ //# sourceMappingURL=doctor-seeded-artifacts.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"doctor-seeded-artifacts.d.ts","sourceRoot":"","sources":["../../src/cli/doctor-seeded-artifacts.ts"],"names":[],"mappings":"AAyBA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAE/C;;;;;;;;GAQG;AACH,wBAAsB,oBAAoB,CACxC,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,SAAS,WAAW,EAAE,CAAC,CAkBjC"}
@@ -0,0 +1,54 @@
1
+ /**
2
+ * The four checks that ask what Lisa SEEDED into this repository, and whether
3
+ * what it seeded still says what it meant.
4
+ *
5
+ * They are grouped because they are one operator question asked four ways, and
6
+ * because each of them exists for the same structural reason: the write path
7
+ * that could have prevented the defect is reached exactly once, before the file
8
+ * exists. A repository that received the template earlier therefore has no
9
+ * signal of any kind — the seeding postinstall is skipped under CI, the file is
10
+ * untracked, and the tool the file disables reports only that it found nothing.
11
+ * A fix on the write path reaches the NEXT adoption; these four are how an
12
+ * existing one finds itself.
13
+ *
14
+ * `doctor-lisa-owned-artifacts` is the inverse and deliberately stays where it
15
+ * is: it walks the templates Lisa SHIPS and asks whether this project's copies
16
+ * are current. A template removed upstream leaves that loop entirely, which is
17
+ * why `checkStaleManagedBanner` below walks the other direction — the files on
18
+ * disk that CLAIM Lisa manages them, asking which of those claims the installed
19
+ * package still backs.
20
+ * @module cli/doctor-seeded-artifacts
21
+ */
22
+ import { checkCdkPresetAdoption } from "./doctor-cdk-preset-adoption.js";
23
+ import { checkConfigShadowing } from "./doctor-config-shadowing.js";
24
+ import { checkRailsDeployIntent } from "./doctor-rails-deploy-intent.js";
25
+ import { checkStaleManagedBanner } from "./doctor-stale-managed-banner.js";
26
+ /**
27
+ * Run every seeded-artifact check, in the order an operator reads them.
28
+ *
29
+ * Sequential rather than concurrent, matching the surrounding checks: they
30
+ * share a target directory and the report is read top to bottom, so a stable
31
+ * order is worth more here than the milliseconds.
32
+ * @param targetPath - Repository root to inspect
33
+ * @returns One check row per question, in report order
34
+ */
35
+ export async function checkSeededArtifacts(targetPath) {
36
+ return [
37
+ // Whether a file Lisa seeded is OUTRANKING one the project wrote itself
38
+ // (CodySwannGT/lisa#3858).
39
+ await checkConfigShadowing(targetPath),
40
+ // Whether a file Lisa is FORBIDDEN to refresh still reads as deliberate.
41
+ // The seed fix reaches new adoptions only and the apply path will not
42
+ // rewrite a host-owned workflow (CodySwannGT/lisa#3779).
43
+ await checkRailsDeployIntent(targetPath),
44
+ // Whether a whole stack preset was delivered to a repository that never
45
+ // qualified for it. The detection fix reaches the next decision only, and
46
+ // the dead-code gate it skewed reports SUCCESS (CodySwannGT/lisa#3711).
47
+ await checkCdkPresetAdoption(targetPath),
48
+ // Which "Lisa manages this file" banners the installed package still
49
+ // backs. A proposal to remove one such orphaned workflow was declined on
50
+ // the strength of the false banner (CodySwannGT/lisa#3703).
51
+ await checkStaleManagedBanner(targetPath),
52
+ ];
53
+ }
54
+ //# sourceMappingURL=doctor-seeded-artifacts.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"doctor-seeded-artifacts.js","sourceRoot":"","sources":["../../src/cli/doctor-seeded-artifacts.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,OAAO,EAAE,sBAAsB,EAAE,MAAM,iCAAiC,CAAC;AACzE,OAAO,EAAE,oBAAoB,EAAE,MAAM,8BAA8B,CAAC;AACpE,OAAO,EAAE,sBAAsB,EAAE,MAAM,iCAAiC,CAAC;AACzE,OAAO,EAAE,uBAAuB,EAAE,MAAM,kCAAkC,CAAC;AAG3E;;;;;;;;GAQG;AACH,MAAM,CAAC,KAAK,UAAU,oBAAoB,CACxC,UAAkB;IAElB,OAAO;QACL,wEAAwE;QACxE,2BAA2B;QAC3B,MAAM,oBAAoB,CAAC,UAAU,CAAC;QACtC,yEAAyE;QACzE,sEAAsE;QACtE,yDAAyD;QACzD,MAAM,sBAAsB,CAAC,UAAU,CAAC;QACxC,wEAAwE;QACxE,0EAA0E;QAC1E,wEAAwE;QACxE,MAAM,sBAAsB,CAAC,UAAU,CAAC;QACxC,qEAAqE;QACrE,yEAAyE;QACzE,4DAA4D;QAC5D,MAAM,uBAAuB,CAAC,UAAU,CAAC;KAC1C,CAAC;AACJ,CAAC"}
@@ -0,0 +1,44 @@
1
+ import type { ShippedTemplateStrategy } from "../core/stale-managed-banner.js";
2
+ /** One entry of a directory listing, reduced to what the scan needs. */
3
+ export interface DirectoryEntry {
4
+ /** Base name of the entry within its directory. */
5
+ readonly name: string;
6
+ /** Whether the entry is a regular file. Symlinks are deliberately not. */
7
+ readonly isFile: boolean;
8
+ }
9
+ /** How the scan reaches the filesystem, so tests can make it refuse. */
10
+ export interface BannerScanDeps {
11
+ /**
12
+ * List one directory, REJECTING when the filesystem declines to say and
13
+ * resolving to an empty list only when the directory is provably absent.
14
+ */
15
+ readonly readDirectory?: (absolute: string) => Promise<readonly DirectoryEntry[]>;
16
+ }
17
+ /**
18
+ * List a directory, distinguishing "not there" from "could not look".
19
+ * @param absolute - Absolute directory path
20
+ * @returns Its entries, or an empty list when it is provably absent
21
+ * @throws {Error} When the filesystem cannot answer
22
+ */
23
+ export declare function listDirectory(absolute: string): Promise<readonly DirectoryEntry[]>;
24
+ /**
25
+ * Read the leading bytes of a file, distinguishing absence from refusal.
26
+ * @param absolute - Absolute file path
27
+ * @returns Its leading bytes as text, or undefined when it is provably absent
28
+ * @throws {Error} When the filesystem cannot answer
29
+ */
30
+ export declare function readHeaderPrefix(absolute: string): Promise<string | undefined>;
31
+ /**
32
+ * Every destination path the installed package ships, across every lane.
33
+ *
34
+ * Deliberately not scoped to the stacks this project detects as. A template
35
+ * that ships only under one stack is still shipped, and an index built from
36
+ * detected stacks would report every stack-specific artifact in a repository as
37
+ * retired the moment detection shifted — the same false accusation this check
38
+ * exists to end, arriving through the detector instead of the package.
39
+ * @param lisaRoot - Installed Lisa package root
40
+ * @returns Destination path to the strategy that ships it
41
+ * @throws {Error} When a template directory cannot be read
42
+ */
43
+ export declare function shippedDestinations(lisaRoot: string): Promise<ReadonlyMap<string, ShippedTemplateStrategy>>;
44
+ //# sourceMappingURL=doctor-stale-banner-scan.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"doctor-stale-banner-scan.d.ts","sourceRoot":"","sources":["../../src/cli/doctor-stale-banner-scan.ts"],"names":[],"mappings":"AAgBA,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,iCAAiC,CAAC;AA0B/E,wEAAwE;AACxE,MAAM,WAAW,cAAc;IAC7B,mDAAmD;IACnD,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,0EAA0E;IAC1E,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;CAC1B;AAED,wEAAwE;AACxE,MAAM,WAAW,cAAc;IAC7B;;;OAGG;IACH,QAAQ,CAAC,aAAa,CAAC,EAAE,CACvB,QAAQ,EAAE,MAAM,KACb,OAAO,CAAC,SAAS,cAAc,EAAE,CAAC,CAAC;CACzC;AAeD;;;;;GAKG;AACH,wBAAsB,aAAa,CACjC,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,SAAS,cAAc,EAAE,CAAC,CAcpC;AAED;;;;;GAKG;AACH,wBAAsB,gBAAgB,CACpC,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAsB7B;AA8CD;;;;;;;;;;;GAWG;AACH,wBAAsB,mBAAmB,CACvC,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,WAAW,CAAC,MAAM,EAAE,uBAAuB,CAAC,CAAC,CAmBvD"}
@@ -0,0 +1,152 @@
1
+ /**
2
+ * The two filesystem reads the stale-banner check depends on, and the rule
3
+ * that both obey: an answer the filesystem declined to give is not an answer.
4
+ *
5
+ * Kept separate from `doctor-stale-managed-banner.ts` for the max-lines budget,
6
+ * the same way the Lisa-owned artifact fixtures are split. The distinction it
7
+ * encodes is the load-bearing one: `fs-extra`'s `pathExists` and a bare
8
+ * `catch { return [] }` both resolve a permission denial into the same shape as
9
+ * an empty directory, and this check's whole job is to tell "found nothing"
10
+ * apart from "could not look" (CodySwannGT/lisa#3703).
11
+ * @module cli/doctor-stale-banner-scan
12
+ */
13
+ import { open, readdir } from "node:fs/promises";
14
+ import * as path from "node:path";
15
+ import { COPY_STRATEGIES, PROJECT_TYPE_ORDER } from "../core/config.js";
16
+ /**
17
+ * Errno codes that answer the question rather than refusing it: the path is
18
+ * genuinely not there. Anything else — a permission denial, an I/O error, a
19
+ * symlink loop — means the probe could not look, which is a different answer
20
+ * and must not be spelled the same way.
21
+ */
22
+ const ABSENT_CODES = new Set(["ENOENT", "ENOTDIR", "ENAMETOOLONG"]);
23
+ /**
24
+ * How many leading bytes of a host file are read to recover its header.
25
+ *
26
+ * A header is four lines at most (`core/ownership-header`), and the population
27
+ * scanned includes repository roots that hold lockfiles measured in megabytes.
28
+ * Reading whole files to look at their first two lines would make the check
29
+ * cost proportional to the repository rather than to the question.
30
+ */
31
+ const HEADER_PREFIX_BYTES = 1024;
32
+ /** The seeding strategy, whose claim any other strategy outranks. */
33
+ const CREATE_ONLY = "create-only";
34
+ /** The lane directories a Lisa package ships templates under. */
35
+ const TEMPLATE_LANES = ["all", ...PROJECT_TYPE_ORDER];
36
+ /**
37
+ * The errno code of a rejected filesystem call, when it carries one.
38
+ * @param error - Value thrown by a filesystem call
39
+ * @returns The errno code, or undefined when the value carries none
40
+ */
41
+ function errnoCode(error) {
42
+ const code = typeof error === "object" && error !== null
43
+ ? error.code
44
+ : undefined;
45
+ return typeof code === "string" ? code : undefined;
46
+ }
47
+ /**
48
+ * List a directory, distinguishing "not there" from "could not look".
49
+ * @param absolute - Absolute directory path
50
+ * @returns Its entries, or an empty list when it is provably absent
51
+ * @throws {Error} When the filesystem cannot answer
52
+ */
53
+ export async function listDirectory(absolute) {
54
+ try {
55
+ const entries = await readdir(absolute, { withFileTypes: true });
56
+ return entries.map(entry => ({
57
+ isFile: entry.isFile(),
58
+ name: entry.name,
59
+ }));
60
+ }
61
+ catch (error) {
62
+ const code = errnoCode(error);
63
+ if (code !== undefined && ABSENT_CODES.has(code))
64
+ return [];
65
+ throw new Error(`could not read ${absolute}: ${code ?? String(error)}`, {
66
+ cause: error,
67
+ });
68
+ }
69
+ }
70
+ /**
71
+ * Read the leading bytes of a file, distinguishing absence from refusal.
72
+ * @param absolute - Absolute file path
73
+ * @returns Its leading bytes as text, or undefined when it is provably absent
74
+ * @throws {Error} When the filesystem cannot answer
75
+ */
76
+ export async function readHeaderPrefix(absolute) {
77
+ try {
78
+ const handle = await open(absolute, "r");
79
+ try {
80
+ const buffer = Buffer.alloc(HEADER_PREFIX_BYTES);
81
+ const { bytesRead } = await handle.read(buffer, 0, HEADER_PREFIX_BYTES, 0);
82
+ return buffer.subarray(0, bytesRead).toString("utf8");
83
+ }
84
+ finally {
85
+ await handle.close();
86
+ }
87
+ }
88
+ catch (error) {
89
+ const code = errnoCode(error);
90
+ if (code !== undefined && ABSENT_CODES.has(code))
91
+ return undefined;
92
+ throw new Error(`could not read ${absolute}: ${code ?? String(error)}`, {
93
+ cause: error,
94
+ });
95
+ }
96
+ }
97
+ /**
98
+ * The strategy bucket a template directory name falls into.
99
+ * @param strategy - Strategy directory name under a lane
100
+ * @returns The bucket the banner classifier acts on
101
+ */
102
+ function bucket(strategy) {
103
+ if (strategy === "copy-overwrite" || strategy === CREATE_ONLY) {
104
+ return strategy;
105
+ }
106
+ return "other";
107
+ }
108
+ /**
109
+ * Walk one lane/strategy tree, collecting every destination it ships.
110
+ * @param root - Absolute path of the lane/strategy directory
111
+ * @param prefix - Repo-relative destination prefix accumulated so far
112
+ * @param strategy - Strategy the lane ships these destinations under
113
+ * @returns Destination/strategy pairs found beneath `root`
114
+ * @throws {Error} When a directory cannot be read
115
+ */
116
+ async function walkTree(root, prefix, strategy) {
117
+ const entries = await listDirectory(root);
118
+ const found = await Promise.all(entries.map(async (entry) => {
119
+ const destination = prefix === "" ? entry.name : `${prefix}/${entry.name}`;
120
+ return entry.isFile
121
+ ? [[destination, strategy]]
122
+ : walkTree(path.join(root, entry.name), destination, strategy);
123
+ }));
124
+ return found.flat();
125
+ }
126
+ /**
127
+ * Every destination path the installed package ships, across every lane.
128
+ *
129
+ * Deliberately not scoped to the stacks this project detects as. A template
130
+ * that ships only under one stack is still shipped, and an index built from
131
+ * detected stacks would report every stack-specific artifact in a repository as
132
+ * retired the moment detection shifted — the same false accusation this check
133
+ * exists to end, arriving through the detector instead of the package.
134
+ * @param lisaRoot - Installed Lisa package root
135
+ * @returns Destination path to the strategy that ships it
136
+ * @throws {Error} When a template directory cannot be read
137
+ */
138
+ export async function shippedDestinations(lisaRoot) {
139
+ const lanes = await Promise.all(TEMPLATE_LANES.flatMap(lane => COPY_STRATEGIES.map(async (strategy) => walkTree(path.join(lisaRoot, lane, strategy), "", bucket(strategy)))));
140
+ const pairs = lanes.flat();
141
+ // A destination can be shipped by more than one lane, and the strategies can
142
+ // disagree — `create-only` in one stack, `copy-overwrite` in another. Seeds
143
+ // are laid down first so a non-seed claim, arriving later, wins the Map. That
144
+ // is the conservative direction: a disagreement makes the banner read as
145
+ // accurate rather than overstated, producing silence rather than a finding
146
+ // nobody can act on.
147
+ return new Map([
148
+ ...pairs.filter(([, strategy]) => strategy === CREATE_ONLY),
149
+ ...pairs.filter(([, strategy]) => strategy !== CREATE_ONLY),
150
+ ]);
151
+ }
152
+ //# sourceMappingURL=doctor-stale-banner-scan.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"doctor-stale-banner-scan.js","sourceRoot":"","sources":["../../src/cli/doctor-stale-banner-scan.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,19 @@
1
+ import { type BannerScanDeps } from "./doctor-stale-banner-scan.js";
2
+ /** Name of the stale-banner check as doctor reports it. */
3
+ export declare const STALE_MANAGED_BANNER_CHECK_NAME = "Managed-file banners true?";
4
+ /** Shape of one doctor check result (structurally identical to doctor's). */
5
+ interface BannerCheckResult {
6
+ name: string;
7
+ status: "ok" | "warn" | "fail";
8
+ detail: string;
9
+ }
10
+ /**
11
+ * Report files whose managed banner the installed package no longer backs.
12
+ * @param targetPath - Project path to inspect
13
+ * @param lisaRoot - Installed Lisa package root (injected by tests)
14
+ * @param deps - Filesystem seam, so a refusing directory can be exercised
15
+ * @returns Doctor check result
16
+ */
17
+ export declare function checkStaleManagedBanner(targetPath: string, lisaRoot?: string, deps?: BannerScanDeps): Promise<BannerCheckResult>;
18
+ export {};
19
+ //# sourceMappingURL=doctor-stale-managed-banner.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"doctor-stale-managed-banner.d.ts","sourceRoot":"","sources":["../../src/cli/doctor-stale-managed-banner.ts"],"names":[],"mappings":"AA+CA,OAAO,EAIL,KAAK,cAAc,EACpB,MAAM,+BAA+B,CAAC;AAGvC,2DAA2D;AAC3D,eAAO,MAAM,+BAA+B,+BAA+B,CAAC;AAc5E,6EAA6E;AAC7E,UAAU,iBAAiB;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,IAAI,GAAG,MAAM,GAAG,MAAM,CAAC;IAC/B,MAAM,EAAE,MAAM,CAAC;CAChB;AAsFD;;;;;;GAMG;AACH,wBAAsB,uBAAuB,CAC3C,UAAU,EAAE,MAAM,EAClB,QAAQ,GAAE,MAA0B,EACpC,IAAI,GAAE,cAAmB,GACxB,OAAO,CAAC,iBAAiB,CAAC,CAqC5B"}