@codyswann/lisa 3.56.0 → 3.59.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 (136) hide show
  1. package/{scripts → all/copy-overwrite/scripts}/check-conflict-markers.mjs +15 -8
  2. package/all/copy-overwrite/scripts/lib/gate-failure-diagnosis.mjs +92 -5
  3. package/all/copy-overwrite/scripts/lisa-gates.mjs +1015 -33
  4. package/all/copy-overwrite/scripts/lisa-reconcile-policy.mjs +4 -4
  5. package/all/copy-overwrite/scripts/lisa-run-gates.mjs +12 -2
  6. package/dist/cli/gate-report-upstream.d.ts +33 -4
  7. package/dist/cli/gate-report-upstream.d.ts.map +1 -1
  8. package/dist/cli/gate-report-upstream.js +69 -11
  9. package/dist/cli/gate-report-upstream.js.map +1 -1
  10. package/dist/cli/gate-report.d.ts.map +1 -1
  11. package/dist/cli/gate-report.js +2 -10
  12. package/dist/cli/gate-report.js.map +1 -1
  13. package/dist/cli/ui-ci-quality-jobs-compute.js +2 -2
  14. package/dist/cli/ui-ci-quality-jobs-compute.js.map +1 -1
  15. package/dist/cli/ui-github-repo-expected.js +1 -1
  16. package/dist/cli/ui-github-repo-expected.js.map +1 -1
  17. package/dist/configs/vitest/base.d.ts +16 -12
  18. package/dist/configs/vitest/base.d.ts.map +1 -1
  19. package/dist/configs/vitest/base.js +51 -0
  20. package/dist/configs/vitest/base.js.map +1 -1
  21. package/dist/configs/vitest/cdk.d.ts +2 -2
  22. package/dist/configs/vitest/cdk.d.ts.map +1 -1
  23. package/dist/configs/vitest/cdk.js +4 -2
  24. package/dist/configs/vitest/cdk.js.map +1 -1
  25. package/dist/configs/vitest/harper-fabric.d.ts +2 -2
  26. package/dist/configs/vitest/harper-fabric.d.ts.map +1 -1
  27. package/dist/configs/vitest/harper-fabric.js +4 -2
  28. package/dist/configs/vitest/harper-fabric.js.map +1 -1
  29. package/dist/configs/vitest/nestjs.d.ts +2 -2
  30. package/dist/configs/vitest/nestjs.d.ts.map +1 -1
  31. package/dist/configs/vitest/nestjs.js +4 -2
  32. package/dist/configs/vitest/nestjs.js.map +1 -1
  33. package/dist/configs/vitest/phaser.d.ts +2 -2
  34. package/dist/configs/vitest/phaser.d.ts.map +1 -1
  35. package/dist/configs/vitest/phaser.js +4 -2
  36. package/dist/configs/vitest/phaser.js.map +1 -1
  37. package/dist/configs/vitest/scratch-global-setup.d.ts +72 -0
  38. package/dist/configs/vitest/scratch-global-setup.d.ts.map +1 -0
  39. package/dist/configs/vitest/scratch-global-setup.js +168 -0
  40. package/dist/configs/vitest/scratch-global-setup.js.map +1 -0
  41. package/dist/configs/vitest/scratch-setup.d.ts +12 -0
  42. package/dist/configs/vitest/scratch-setup.d.ts.map +1 -0
  43. package/dist/configs/vitest/scratch-setup.js +70 -0
  44. package/dist/configs/vitest/scratch-setup.js.map +1 -0
  45. package/dist/configs/vitest/scratch.d.ts +192 -0
  46. package/dist/configs/vitest/scratch.d.ts.map +1 -0
  47. package/dist/configs/vitest/scratch.js +301 -0
  48. package/dist/configs/vitest/scratch.js.map +1 -0
  49. package/dist/configs/vitest/typescript.d.ts +2 -2
  50. package/dist/configs/vitest/typescript.d.ts.map +1 -1
  51. package/dist/configs/vitest/typescript.js +4 -2
  52. package/dist/configs/vitest/typescript.js.map +1 -1
  53. package/dist/core/lisa-owned-hash-ledger.d.ts.map +1 -1
  54. package/dist/core/lisa-owned-hash-ledger.js +28 -0
  55. package/dist/core/lisa-owned-hash-ledger.js.map +1 -1
  56. package/dist/core/upstream-evidence-manifest.d.ts.map +1 -1
  57. package/dist/core/upstream-evidence-manifest.js +35 -17
  58. package/dist/core/upstream-evidence-manifest.js.map +1 -1
  59. package/dist/migrations/ensure-seeded-gates.d.ts +47 -0
  60. package/dist/migrations/ensure-seeded-gates.d.ts.map +1 -0
  61. package/dist/migrations/ensure-seeded-gates.js +139 -0
  62. package/dist/migrations/ensure-seeded-gates.js.map +1 -0
  63. package/dist/migrations/index.d.ts +1 -0
  64. package/dist/migrations/index.d.ts.map +1 -1
  65. package/dist/migrations/index.js +3 -0
  66. package/dist/migrations/index.js.map +1 -1
  67. package/expo/copy-overwrite/scripts/bdd/baseline.mjs +36 -45
  68. package/expo/copy-overwrite/scripts/bdd/render.mjs +1 -1
  69. package/expo/copy-overwrite/scripts/check-bdd-coverage.mjs +0 -6
  70. package/package.json +2 -2
  71. package/plugins/lisa/.claude-plugin/plugin.json +1 -1
  72. package/plugins/lisa/.codex-plugin/plugin.json +1 -1
  73. package/plugins/lisa/.codex-plugin/skills/lisa-setup-sonar/SKILL.md +1 -1
  74. package/plugins/lisa/rules/reference/bdd-e2e-coverage.md +3 -3
  75. package/plugins/lisa/skills/lisa-setup-sonar/SKILL.md +1 -1
  76. package/plugins/lisa-agy/plugin.json +1 -1
  77. package/plugins/lisa-agy/skills/lisa-setup-sonar/SKILL.md +1 -1
  78. package/plugins/lisa-cdk/.claude-plugin/plugin.json +1 -1
  79. package/plugins/lisa-cdk/.codex-plugin/plugin.json +1 -1
  80. package/plugins/lisa-cdk-agy/plugin.json +1 -1
  81. package/plugins/lisa-cdk-copilot/.claude-plugin/plugin.json +1 -1
  82. package/plugins/lisa-cdk-cursor/.claude-plugin/plugin.json +1 -1
  83. package/plugins/lisa-copilot/.claude-plugin/plugin.json +1 -1
  84. package/plugins/lisa-copilot/rules/reference/bdd-e2e-coverage.md +3 -3
  85. package/plugins/lisa-copilot/skills/lisa-setup-sonar/SKILL.md +1 -1
  86. package/plugins/lisa-cursor/.claude-plugin/plugin.json +1 -1
  87. package/plugins/lisa-cursor/rules/bdd-e2e-coverage-reference.mdc +3 -3
  88. package/plugins/lisa-cursor/skills/lisa-setup-sonar/SKILL.md +1 -1
  89. package/plugins/lisa-expo/.claude-plugin/plugin.json +1 -1
  90. package/plugins/lisa-expo/.codex-plugin/plugin.json +1 -1
  91. package/plugins/lisa-expo-agy/plugin.json +1 -1
  92. package/plugins/lisa-expo-copilot/.claude-plugin/plugin.json +1 -1
  93. package/plugins/lisa-expo-cursor/.claude-plugin/plugin.json +1 -1
  94. package/plugins/lisa-harper-fabric/.claude-plugin/plugin.json +1 -1
  95. package/plugins/lisa-harper-fabric/.codex-plugin/plugin.json +1 -1
  96. package/plugins/lisa-harper-fabric-agy/plugin.json +1 -1
  97. package/plugins/lisa-harper-fabric-copilot/.claude-plugin/plugin.json +1 -1
  98. package/plugins/lisa-harper-fabric-cursor/.claude-plugin/plugin.json +1 -1
  99. package/plugins/lisa-nestjs/.claude-plugin/plugin.json +1 -1
  100. package/plugins/lisa-nestjs/.codex-plugin/plugin.json +1 -1
  101. package/plugins/lisa-nestjs-agy/plugin.json +1 -1
  102. package/plugins/lisa-nestjs-copilot/.claude-plugin/plugin.json +1 -1
  103. package/plugins/lisa-nestjs-cursor/.claude-plugin/plugin.json +1 -1
  104. package/plugins/lisa-openclaw/.claude-plugin/plugin.json +1 -1
  105. package/plugins/lisa-openclaw/.codex-plugin/plugin.json +1 -1
  106. package/plugins/lisa-openclaw-agy/plugin.json +1 -1
  107. package/plugins/lisa-openclaw-copilot/.claude-plugin/plugin.json +1 -1
  108. package/plugins/lisa-openclaw-cursor/.claude-plugin/plugin.json +1 -1
  109. package/plugins/lisa-phaser/.claude-plugin/plugin.json +1 -1
  110. package/plugins/lisa-phaser/.codex-plugin/plugin.json +1 -1
  111. package/plugins/lisa-phaser-agy/plugin.json +1 -1
  112. package/plugins/lisa-phaser-copilot/.claude-plugin/plugin.json +1 -1
  113. package/plugins/lisa-phaser-cursor/.claude-plugin/plugin.json +1 -1
  114. package/plugins/lisa-rails/.claude-plugin/plugin.json +1 -1
  115. package/plugins/lisa-rails/.codex-plugin/plugin.json +1 -1
  116. package/plugins/lisa-rails-agy/plugin.json +1 -1
  117. package/plugins/lisa-rails-copilot/.claude-plugin/plugin.json +1 -1
  118. package/plugins/lisa-rails-cursor/.claude-plugin/plugin.json +1 -1
  119. package/plugins/lisa-typescript/.claude-plugin/plugin.json +1 -1
  120. package/plugins/lisa-typescript/.codex-plugin/plugin.json +1 -1
  121. package/plugins/lisa-typescript-agy/plugin.json +1 -1
  122. package/plugins/lisa-typescript-copilot/.claude-plugin/plugin.json +1 -1
  123. package/plugins/lisa-typescript-cursor/.claude-plugin/plugin.json +1 -1
  124. package/plugins/lisa-wiki/.claude-plugin/plugin.json +1 -1
  125. package/plugins/lisa-wiki/.codex-plugin/plugin.json +1 -1
  126. package/plugins/lisa-wiki-agy/plugin.json +1 -1
  127. package/plugins/lisa-wiki-copilot/.claude-plugin/plugin.json +1 -1
  128. package/plugins/lisa-wiki-cursor/.claude-plugin/plugin.json +1 -1
  129. package/plugins/src/base/rules/reference/bdd-e2e-coverage.md +3 -3
  130. package/plugins/src/base/skills/lisa-setup-sonar/SKILL.md +1 -1
  131. package/typescript/copy-contents/.husky/pre-push +21 -0
  132. package/typescript/copy-overwrite/.prettierignore +1 -0
  133. package/typescript/copy-overwrite/scripts/check-skipped-required-checks.mjs +13 -6
  134. package/typescript/create-only/.github/required-checks.json +1 -1
  135. package/typescript/package-lisa/package.lisa.json +1 -0
  136. package/ui/index.html +2 -2
@@ -1,4 +1,6 @@
1
1
  #!/usr/bin/env node
2
+ // This file is managed by Lisa and IS replaced on each `lisa` run.
3
+ // Do not edit directly — durable changes belong upstream in Lisa.
2
4
  /**
3
5
  * Deterministic gate against leftover merge-conflict markers in tracked files
4
6
  * (issue #2552).
@@ -31,27 +33,32 @@
31
33
  * CLI:
32
34
  * node scripts/check-conflict-markers.mjs [--root <dir>] [--json]
33
35
  *
36
+ * `--root` defaults to the CURRENT WORKING DIRECTORY, deliberately, and not to
37
+ * a path derived from this file's own location. This script is a copy-overwrite
38
+ * template: it is installed at `scripts/` in a consumer, lives at
39
+ * `all/copy-overwrite/scripts/` in Lisa itself, and ships inside the package at
40
+ * `node_modules/@codyswann/lisa/all/copy-overwrite/scripts/`. A location-derived
41
+ * default resolves to a DIFFERENT directory on each of those three, and the
42
+ * failure is silent in the worst direction — `git ls-files` inside a
43
+ * subdirectory succeeds and lists only what is under it, so the gate reports
44
+ * "no leftover conflict markers in 40 tracked files" having never looked at the
45
+ * project. Anchoring on the cwd makes every caller correct with no flag to drop.
46
+ *
34
47
  * Exit codes (mirroring the sibling parity scripts):
35
48
  * 0 — no tracked file carries a conflict block.
36
49
  * 1 — ≥1 tracked file carries a conflict block.
37
50
  * 2 — operational/usage error: unknown flag, a flag missing its value,
38
51
  * `--root` absent or not a git repository, or git being unavailable.
39
52
  *
40
- * @module scripts/check-conflict-markers
53
+ * @module all/copy-overwrite/scripts/check-conflict-markers
41
54
  */
42
55
  import { execFileSync } from "node:child_process";
43
56
  import fs from "node:fs";
44
57
  import path from "node:path";
45
58
  import process from "node:process";
46
- import { fileURLToPath } from "node:url";
47
59
 
48
60
  import { invokedAsScript } from "./lib/invoked-as-script.mjs";
49
61
 
50
- const REPO_ROOT = path.resolve(
51
- path.dirname(fileURLToPath(import.meta.url)),
52
- ".."
53
- );
54
-
55
62
  /** `<<<<<<<` alone, or followed by whitespace and a label (`<<<<<<< HEAD`). */
56
63
  const START_RE = /^<{7}(?:[ \t].*)?$/;
57
64
 
@@ -258,7 +265,7 @@ export function parseArgs(argv) {
258
265
  throw new UsageError(`unknown argument: ${arg}`);
259
266
  }
260
267
  }
261
- return { json, root: path.resolve(root ?? REPO_ROOT) };
268
+ return { json, root: path.resolve(root ?? process.cwd()) };
262
269
  }
263
270
 
264
271
  /**
@@ -38,6 +38,8 @@ export const DIAGNOSIS = Object.freeze({
38
38
  ASSERTION: "assertion",
39
39
  /** Every test finished and passed; a coverage floor was not met. */
40
40
  THRESHOLD: "threshold",
41
+ /** The command was terminated by a signal; nothing it says can be trusted. */
42
+ KILLED: "killed",
41
43
  /** Output was read and matched nothing this module knows. */
42
44
  UNDIAGNOSED: "undiagnosed",
43
45
  /** No output was available to read, so nothing can be said. */
@@ -79,8 +81,11 @@ const FAIL_PATTERN = /^[ \t]*FAIL[ \t]+(\S+)/gm;
79
81
  * test suite rendered as a coverage regression — and it is also why a real
80
82
  * coverage regression could not be told from that flake.
81
83
  *
82
- * `undiagnosed` and `uncaptured` are deliberately absent. Nothing was
84
+ * `undiagnosed`, `uncaptured` and `killed` are deliberately absent. Nothing was
83
85
  * recognised, so nothing may be attributed; the failure stays where it landed.
86
+ * `killed` is the most important of the three to leave out: a terminated
87
+ * command measured NOTHING, so attributing it to `test-correctness` would print
88
+ * a verdict about a property no run ever reached.
84
89
  *
85
90
  * The runner applies this only when the named gate is itself declared on the
86
91
  * same command at the same moment, so a phrase in some unrelated tool's output
@@ -200,19 +205,98 @@ function timeoutVerdict(timeouts, suites) {
200
205
  };
201
206
  }
202
207
 
208
+ /**
209
+ * Exit codes a POSIX shell reports for a command killed by a signal.
210
+ *
211
+ * `128 + signal`. Enumerated rather than treated as a range, because the
212
+ * message has to NAME the signal — "killed by SIGTERM" is actionable and
213
+ * "terminated by signal 15" is a second lookup — and because a broad
214
+ * `code > 128` rule would swallow the handful of tools that use high exit codes
215
+ * to mean something else. These seven are the ones that actually terminate a
216
+ * gate on this fleet: an operator's Ctrl-C, an out-of-memory reap, a CPU-time
217
+ * limit, and the SIGTERM a saturated box hands out.
218
+ */
219
+ const SIGNAL_EXITS = Object.freeze({
220
+ 129: "SIGHUP",
221
+ 130: "SIGINT",
222
+ 131: "SIGQUIT",
223
+ 137: "SIGKILL",
224
+ 139: "SIGSEGV",
225
+ 143: "SIGTERM",
226
+ 152: "SIGXCPU",
227
+ });
228
+
229
+ /**
230
+ * Whether an exit code says the command was terminated rather than answered.
231
+ *
232
+ * `null` and `undefined` are NOT the same answer here, and conflating them
233
+ * would be a fresh instance of this module's own defect. The runner's
234
+ * `normaliseExec` yields a number or `null`, and `null` is what it produces for
235
+ * a child killed by a signal — it already calls that "terminated". `undefined`
236
+ * means the caller passed no code at all, which is no information, not a kill.
237
+ * @param {number|null|undefined} code The command's exit code, `null` when the
238
+ * runner obtained none, `undefined` when the caller supplied none.
239
+ * @returns {boolean} Whether this was a termination.
240
+ */
241
+ function wasKilled(code) {
242
+ if (code === undefined) return false;
243
+ return code === null || SIGNAL_EXITS[code] !== undefined;
244
+ }
245
+
246
+ /**
247
+ * The verdict for a command that was terminated rather than answered.
248
+ *
249
+ * This exists because `exit 143` and `exit 1` were the same sentence. 143 is
250
+ * `128 + 15`: SIGTERM. On a saturated box a contention kill reads identically
251
+ * to a real gate failure, so the runner said "N test(s) exceeded the budget" or
252
+ * "no recognised failure signature" about a command that never reached a
253
+ * verdict at all — and the transcript it read to say so was a TRUNCATED one,
254
+ * whose `FAIL` lines are whatever happened to have been printed before the
255
+ * kill. That is manufactured evidence for a false diagnosis, and re-running is
256
+ * a rational response to it, which is exactly why the real cause never gets
257
+ * looked at.
258
+ *
259
+ * So a kill outranks every content signature, including the ones it may be
260
+ * sitting on top of. Nothing the output says is a verdict once the run was
261
+ * terminated.
262
+ * @param {number|null} code The exit code, or null when none was obtained.
263
+ * @returns {Diagnosis} The verdict.
264
+ */
265
+ function killedVerdict(code) {
266
+ const named = SIGNAL_EXITS[code];
267
+ const cause =
268
+ named === undefined
269
+ ? "a signal, and the runner obtained no exit code for it"
270
+ : `${named} — exit ${code} is 128 + ${code - 128}`;
271
+ return {
272
+ kind: DIAGNOSIS.KILLED,
273
+ summary:
274
+ `the command was KILLED by ${cause}. It was terminated, NOT failed: it ` +
275
+ `reached no verdict, and its output is a truncated transcript rather ` +
276
+ `than a result. Re-run it on a quieter machine before reading anything ` +
277
+ `into what it printed`,
278
+ evidence: [],
279
+ };
280
+ }
281
+
203
282
  /**
204
283
  * Classify why a gate command failed, from the output it produced.
205
284
  *
206
285
  * Ordered deliberately, and the order is the content of this function: a
207
- * timeout outranks an assertion failure outranks a threshold miss, because
286
+ * kill outranks everything, then a timeout outranks an assertion failure
287
+ * outranks a threshold miss, because
208
288
  * coverage read off a run that did not finish measures the interruption rather
209
289
  * than the code. Getting that backwards is the defect being fixed — it is what
210
290
  * printed "coverage-adequacy failed" six times for a machine under load.
211
291
  * @param {string|null|undefined} output The command's combined output, or null
212
292
  * when the runner could not capture it.
293
+ * @param {number|null|undefined} code The command's exit code, or null when the
294
+ * runner could not obtain one.
213
295
  * @returns {object} What the failure was, before it is attributed.
214
296
  */
215
- function classify(output) {
297
+ function classify(output, code) {
298
+ if (wasKilled(code)) return killedVerdict(code ?? null);
299
+
216
300
  if (typeof output !== "string" || output.length === 0) {
217
301
  return {
218
302
  kind: DIAGNOSIS.UNCAPTURED,
@@ -262,9 +346,12 @@ function classify(output) {
262
346
  * indicted gate is part of the run at all.
263
347
  * @param {string|null|undefined} output The command's combined output, or null
264
348
  * when the runner could not capture it.
349
+ * @param {number|null|undefined} [code] The command's exit code. Omitted by a
350
+ * caller that has none; a caller that HAS one must pass it, because a kill is
351
+ * only legible in the exit code and never in the output.
265
352
  * @returns {Diagnosis} What the failure was, and whose it was.
266
353
  */
267
- export function diagnoseFailure(output) {
268
- const verdict = classify(output);
354
+ export function diagnoseFailure(output, code) {
355
+ const verdict = classify(output, code);
269
356
  return { ...verdict, proves: ATTRIBUTION[verdict.kind] ?? null };
270
357
  }