@codyswann/lisa 3.49.0 → 3.50.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 (130) hide show
  1. package/dist/cli/gate-report-agent-hooks.d.ts +40 -0
  2. package/dist/cli/gate-report-agent-hooks.d.ts.map +1 -0
  3. package/dist/cli/gate-report-agent-hooks.js +226 -0
  4. package/dist/cli/gate-report-agent-hooks.js.map +1 -0
  5. package/dist/cli/gate-report-assemble.d.ts +37 -0
  6. package/dist/cli/gate-report-assemble.d.ts.map +1 -0
  7. package/dist/cli/gate-report-assemble.js +69 -0
  8. package/dist/cli/gate-report-assemble.js.map +1 -0
  9. package/dist/cli/gate-report-cells.d.ts +27 -2
  10. package/dist/cli/gate-report-cells.d.ts.map +1 -1
  11. package/dist/cli/gate-report-cells.js +59 -14
  12. package/dist/cli/gate-report-cells.js.map +1 -1
  13. package/dist/cli/gate-report-contexts.d.ts +70 -0
  14. package/dist/cli/gate-report-contexts.d.ts.map +1 -0
  15. package/dist/cli/gate-report-contexts.js +72 -0
  16. package/dist/cli/gate-report-contexts.js.map +1 -0
  17. package/dist/cli/gate-report-facade.d.ts +62 -0
  18. package/dist/cli/gate-report-facade.d.ts.map +1 -0
  19. package/dist/cli/gate-report-facade.js +224 -0
  20. package/dist/cli/gate-report-facade.js.map +1 -0
  21. package/dist/cli/gate-report-fragment.d.ts +11 -0
  22. package/dist/cli/gate-report-fragment.d.ts.map +1 -0
  23. package/dist/cli/gate-report-fragment.js +100 -0
  24. package/dist/cli/gate-report-fragment.js.map +1 -0
  25. package/dist/cli/gate-report-html.d.ts +47 -0
  26. package/dist/cli/gate-report-html.d.ts.map +1 -0
  27. package/dist/cli/gate-report-html.js +49 -0
  28. package/dist/cli/gate-report-html.js.map +1 -0
  29. package/dist/cli/gate-report-joins.d.ts +37 -0
  30. package/dist/cli/gate-report-joins.d.ts.map +1 -0
  31. package/dist/cli/gate-report-joins.js +104 -0
  32. package/dist/cli/gate-report-joins.js.map +1 -0
  33. package/dist/cli/gate-report-merge.d.ts +22 -0
  34. package/dist/cli/gate-report-merge.d.ts.map +1 -0
  35. package/dist/cli/gate-report-merge.js +79 -0
  36. package/dist/cli/gate-report-merge.js.map +1 -0
  37. package/dist/cli/gate-report-preview.d.ts +0 -18
  38. package/dist/cli/gate-report-preview.d.ts.map +1 -1
  39. package/dist/cli/gate-report-preview.js +35 -266
  40. package/dist/cli/gate-report-preview.js.map +1 -1
  41. package/dist/cli/gate-report-rows.d.ts +39 -0
  42. package/dist/cli/gate-report-rows.d.ts.map +1 -0
  43. package/dist/cli/gate-report-rows.js +209 -0
  44. package/dist/cli/gate-report-rows.js.map +1 -0
  45. package/dist/cli/gate-report-sections.d.ts +32 -0
  46. package/dist/cli/gate-report-sections.d.ts.map +1 -0
  47. package/dist/cli/gate-report-sections.js +164 -0
  48. package/dist/cli/gate-report-sections.js.map +1 -0
  49. package/dist/cli/gate-report-style.d.ts +19 -0
  50. package/dist/cli/gate-report-style.d.ts.map +1 -0
  51. package/dist/cli/gate-report-style.js +97 -0
  52. package/dist/cli/gate-report-style.js.map +1 -0
  53. package/dist/cli/gate-report-summary.d.ts.map +1 -1
  54. package/dist/cli/gate-report-summary.js +3 -0
  55. package/dist/cli/gate-report-summary.js.map +1 -1
  56. package/dist/cli/gate-report-types.d.ts +132 -1
  57. package/dist/cli/gate-report-types.d.ts.map +1 -1
  58. package/dist/cli/gate-report-types.js +1 -1
  59. package/dist/cli/gate-report-upstream.d.ts +70 -0
  60. package/dist/cli/gate-report-upstream.d.ts.map +1 -0
  61. package/dist/cli/gate-report-upstream.js +90 -0
  62. package/dist/cli/gate-report-upstream.js.map +1 -0
  63. package/dist/cli/gate-report.d.ts +2 -0
  64. package/dist/cli/gate-report.d.ts.map +1 -1
  65. package/dist/cli/gate-report.js +98 -140
  66. package/dist/cli/gate-report.js.map +1 -1
  67. package/dist/cli/ui-cmd.d.ts +4 -0
  68. package/dist/cli/ui-cmd.d.ts.map +1 -1
  69. package/dist/cli/ui-cmd.js +10 -2
  70. package/dist/cli/ui-cmd.js.map +1 -1
  71. package/dist/cli/ui-gate-report.d.ts +57 -0
  72. package/dist/cli/ui-gate-report.d.ts.map +1 -0
  73. package/dist/cli/ui-gate-report.js +95 -0
  74. package/dist/cli/ui-gate-report.js.map +1 -0
  75. package/dist/core/upstream-evidence-manifest.d.ts.map +1 -1
  76. package/dist/core/upstream-evidence-manifest.js +20 -2
  77. package/dist/core/upstream-evidence-manifest.js.map +1 -1
  78. package/package.json +1 -1
  79. package/plugins/lisa/.claude-plugin/plugin.json +1 -1
  80. package/plugins/lisa/.codex-plugin/plugin.json +1 -1
  81. package/plugins/lisa-agy/plugin.json +1 -1
  82. package/plugins/lisa-cdk/.claude-plugin/plugin.json +1 -1
  83. package/plugins/lisa-cdk/.codex-plugin/plugin.json +1 -1
  84. package/plugins/lisa-cdk-agy/plugin.json +1 -1
  85. package/plugins/lisa-cdk-copilot/.claude-plugin/plugin.json +1 -1
  86. package/plugins/lisa-cdk-cursor/.claude-plugin/plugin.json +1 -1
  87. package/plugins/lisa-copilot/.claude-plugin/plugin.json +1 -1
  88. package/plugins/lisa-cursor/.claude-plugin/plugin.json +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/ui/README.md +56 -3
  130. package/ui/index.html +52 -0
@@ -1,169 +1,39 @@
1
- /** How each declaration state is written and coloured. */
2
- const DECLARATION_LABELS = {
3
- required: "must",
4
- optional: "tells",
5
- off: "off",
6
- "not-declared": "not declared",
7
- };
8
- /** Escape text for HTML text nodes and attribute values. */
9
- const ESCAPES = {
10
- "&": "&",
11
- "<": "&lt;",
12
- ">": "&gt;",
13
- '"': "&quot;",
14
- "'": "&#39;",
15
- };
16
1
  /**
17
- * Escape a string for interpolation into HTML.
18
- * @param value - Raw text
19
- * @returns Escaped text
20
- */
21
- function escapeHtml(value) {
22
- return value.replace(/[&<>"']/g, character => ESCAPES[character] ?? character);
23
- }
24
- /**
25
- * The bucket chip for one cell, or the honest refusal to classify it.
26
- * @param bucket - The cell's bucket finding
27
- * @returns One chip of HTML
28
- */
29
- function bucketChip(bucket) {
30
- if (bucket.state === "not-applicable")
31
- return "";
32
- if (bucket.state === "unknown") {
33
- return `<span class="chip unknown" title="${escapeHtml(bucket.message)}">not checked here</span>`;
34
- }
35
- const titles = {
36
- A: "declared, and an executor resolves the declaration",
37
- B: "an executor exists, but no declaration reaches it",
38
- C: "a declaration exists that nothing can execute",
39
- D: "neither declared nor executed",
40
- };
41
- return `<span class="chip b-${bucket.value}" title="${escapeHtml(titles[bucket.value] ?? "")}">${bucket.value}</span>`;
42
- }
43
- /**
44
- * One matrix cell.
45
- * @param cell - The (gate, moment) pair
46
- * @returns A table cell
47
- */
48
- function momentCell(cell) {
49
- if (!cell.legal) {
50
- return '<td class="m illegal" title="the registry does not permit declaring this gate here"></td>';
51
- }
52
- const label = DECLARATION_LABELS[cell.declaration] ?? cell.declaration;
53
- const state = cell.declaration === "not-declared" ? "undeclared" : cell.declaration;
54
- return `<td class="m"><span class="state ${state}">${escapeHtml(label)}</span>${bucketChip(cell.bucket)}</td>`;
55
- }
56
- /**
57
- * Whether `package.json` has the command, said in three states.
58
- * @param cell - The cell carrying the command
59
- * @returns One chip of HTML
60
- */
61
- function commandChip(cell) {
62
- if (cell.commandExists.state === "unknown") {
63
- return '<span class="chip unknown">command not checked</span>';
64
- }
65
- if (cell.commandExists.state === "not-applicable")
66
- return "";
67
- return cell.commandExists.value
68
- ? '<span class="chip ok">script exists</span>'
69
- : '<span class="chip bad">no such script</span>';
70
- }
71
- /**
72
- * The first cell of a row that carries a resolved command, for the task column.
73
- * @param row - One gate's row
74
- * @returns The most informative cell, or undefined
75
- */
76
- function representativeCell(row) {
77
- return (row.moments.find(cell => cell.legal && cell.declaration !== "not-declared") ?? row.moments.find(cell => cell.legal));
78
- }
79
- /**
80
- * Legal moments the project's own axis has no column for.
2
+ * The gate report as a standalone HTML document.
81
3
  *
82
- * There is no bare `deploy` moment in Lisa, and the deploy families only get a
83
- * column when a project declares an environment. Naming them here keeps the
84
- * information without inventing a column the project does not have.
85
- * @param row - One gate's row
86
- * @param axis - The report's moment axis
87
- * @returns Human text, or an empty string
88
- */
89
- function offAxisMoments(row, axis) {
90
- const families = row.legalMoments.filter(moment => !axis.includes(moment) && !axis.some(one => one.startsWith(`${moment}:`)));
91
- return families.length === 0
92
- ? ""
93
- : `<div class="offaxis">also legal at ${escapeHtml(families.join(", "))}</div>`;
94
- }
95
- /**
96
- * The cloud job a gate maps to, from the static table.
97
- * @param job - The job id, or null when the table has no pair for this gate
98
- * @returns One cell fragment
99
- */
100
- function jobCell(job) {
101
- return job === null
102
- ? '<span class="chip none">no job</span>'
103
- : `<code>${escapeHtml(job)}</code>`;
104
- }
105
- /**
106
- * One gate row.
107
- * @param row - The gate
108
- * @param axis - The report's moment axis
109
- * @returns A table row
110
- */
111
- function gateRow(row, axis) {
112
- const cell = representativeCell(row);
113
- const task = cell?.task ?? row.defaultTask ?? "—";
114
- return [
115
- "<tr>",
116
- `<td><span class="gid">${escapeHtml(row.id)}</span><span class="glabel">${escapeHtml(row.label)}</span>`,
117
- offAxisMoments(row, axis),
118
- "</td>",
119
- `<td class="proves">${escapeHtml(row.summary)}</td>`,
120
- `<td><code>${escapeHtml(task)}</code>${cell === undefined ? "" : commandChip(cell)}</td>`,
121
- row.moments.map(momentCell).join(""),
122
- `<td>${jobCell(row.qualityJob)}<div class="tier3">reads the declaration: not checkable here</div></td>`,
123
- "</tr>",
124
- ].join("");
125
- }
126
- /**
127
- * The ruleset section — including the case where it was not read.
128
- * @param report - The whole report
129
- * @returns A section of HTML
4
+ * A thin wrapper around the fragment the console tab renders, and nothing
5
+ * more. The two surfaces cannot disagree because there is only one renderer:
6
+ * this file supplies a `<head>`, a page frame, and the console's colour tokens
7
+ * so the same scoped stylesheet has something to resolve against.
8
+ *
9
+ * It exists for the cases the tab cannot serve — a report written to a file, a
10
+ * report attached to a build — and not as a second place the report is
11
+ * decided. Where the report lives was an open question when the fragment was
12
+ * first written; it has been ruled on, and the answer is the console tab.
13
+ * @module cli/gate-report-preview
130
14
  */
131
- function rulesetSection(report) {
132
- if (report.ruleset.state !== "verified") {
133
- return `<p class="unknown-note">Branch protection was not read this run — <strong>${escapeHtml(report.ruleset.reason)}</strong>. ${escapeHtml(report.ruleset.message)} Nothing below claims a gate does or does not block a merge.</p>`;
134
- }
135
- const { matched, declaredNotRequired, requiredNotDeclared } = report.ruleset.value;
136
- const list = (values) => values.length === 0
137
- ? "<li><em>none</em></li>"
138
- : values
139
- .map(value => `<li><code>${escapeHtml(value)}</code></li>`)
140
- .join("");
141
- return [
142
- '<div class="cols">',
143
- `<div><h3>Matched <span class="count">${matched.length}</span></h3><p>Declared <code>required</code>, and the ruleset requires it.</p><ul>${list(matched)}</ul></div>`,
144
- `<div><h3>Declared, not required <span class="count">${declaredNotRequired.length}</span></h3><p>The settings file asks for it; the ruleset does not enforce it, so it blocks nothing.</p><ul>${list(declaredNotRequired)}</ul></div>`,
145
- `<div class="sharp"><h3>Required, not declared <span class="count">${requiredNotDeclared.length}</span></h3><p>A merge is blocked on these, and <strong>no declaration governs them</strong>. Changing the settings file cannot turn them on, off, or into something else.</p><ul>${list(requiredNotDeclared)}</ul></div>`,
146
- "</div>",
147
- ].join("");
148
- }
15
+ import { renderGateReportFragment } from "./gate-report-fragment.js";
16
+ import { escapeHtml } from "./gate-report-html.js";
149
17
  /**
150
- * The header counts, each with its denominator and its unknown band.
151
- * @param report - The whole report
152
- * @returns A section of HTML
153
- */
154
- function summarySection(report) {
155
- const s = report.summary;
156
- const verified = s.buckets.A + s.buckets.B + s.buckets.C + s.buckets.D;
157
- return [
158
- '<div class="stats">',
159
- `<div class="stat"><b>${s.governedBySettings}</b><span>of ${s.gateCount} properties governed by the settings file</span></div>`,
160
- `<div class="stat"><b>${s.provedAnyway}</b><span>proved anyway by a command written into a script</span></div>`,
161
- `<div class="stat"><b>${s.declaredOffOnly}</b><span>mentioned only to be switched off</span></div>`,
162
- `<div class="stat"><b>${s.notDeclared}</b><span>never mentioned at all</span></div>`,
163
- "</div>",
164
- `<p class="denominator"><strong>${verified} of ${s.legalCells}</strong> gate-and-moment pairs were classified in this run — A ${s.buckets.A} · B ${s.buckets.B} · C ${s.buckets.C} · D ${s.buckets.D}. The other <strong>${s.bucketUnknown}</strong> are <span class="chip unknown">not checked here</span>: this run could not determine them, and they are counted separately rather than added to anything green.</p>`,
165
- ].join("");
166
- }
18
+ * The console's token names, given dark values.
19
+ *
20
+ * The fragment's stylesheet reads the console's tokens with fallbacks, so a
21
+ * standalone page only has to define the same names once. Duplicating the
22
+ * fragment's own rules here would be the second source of truth this split
23
+ * exists to avoid.
24
+ */
25
+ const DOCUMENT_TOKENS = `
26
+ :root{--ink:#e6e9f2;--muted:#98a0b5;--faint:#6b7280;--surface:#161923;
27
+ --surface2:#1b2030;--line:#252a38;--accent:#58a6ff;
28
+ --good:#7ee787;--good-soft:#123021;--warn:#e3b341;--warn-soft:#3a2c12;
29
+ --crit:#ff9492;--crit-soft:#3a1616;
30
+ --mono:ui-monospace,"SF Mono",Menlo,Consolas,monospace}
31
+ *{box-sizing:border-box}
32
+ body{margin:0;background:#0f1115;color:var(--ink);
33
+ font:15px/1.55 ui-sans-serif,-apple-system,"Segoe UI",Roboto,sans-serif}
34
+ .page{max-width:1500px;margin:0 auto;padding:32px 24px 72px}
35
+ h1{font-size:25px;margin:0 0 8px}
36
+ `;
167
37
  /**
168
38
  * Render the whole page.
169
39
  * @param report - The emitter's output
@@ -171,116 +41,15 @@ function summarySection(report) {
171
41
  * @returns A complete, self-contained HTML document
172
42
  */
173
43
  export function renderGateReportPreview(report, projectLabel) {
174
- const axis = report.momentAxis;
175
- const head = axis
176
- .map(moment => `<th class="m">${escapeHtml(moment)}</th>`)
177
- .join("");
178
44
  return `<!doctype html>
179
45
  <html lang="en"><head><meta charset="utf-8">
180
46
  <meta name="viewport" content="width=device-width,initial-scale=1">
181
47
  <title>Gate report — ${escapeHtml(projectLabel)}</title>
182
- <style>${STYLE}</style></head><body>
183
- <div class="wrap">
184
- <header>
48
+ <style>${DOCUMENT_TOKENS}</style></head><body>
49
+ <div class="page">
185
50
  <h1>What this project's checks actually prove</h1>
186
- <p class="sub">Derived, not written. Every number below comes from ${escapeHtml(projectLabel)}'s own settings file, package scripts and git hooks, joined against Lisa's check registry. Nothing here is a language model's summary of those files.</p>
187
- ${summarySection(report)}
188
- </header>
189
-
190
- <section>
191
- <h2>Every check, and what governs it</h2>
192
- <p class="lede">One row per check. One column per moment this project can declare a check at — there is no bare "deploy" column, because Lisa has no such moment: the deploy families take an environment suffix and only appear once a project names one.</p>
193
- <div class="legend">
194
- <span><span class="state required">must</span> declared required</span>
195
- <span><span class="state optional">tells</span> declared optional</span>
196
- <span><span class="state off">off</span> declared off — different from never declared</span>
197
- <span><span class="state undeclared">not declared</span> the settings file never mentions it here</span>
198
- <span><span class="chip b-A">A</span> declared, and something reads the declaration</span>
199
- <span><span class="chip b-B">B</span> something runs it anyway; the settings file has no say</span>
200
- <span><span class="chip b-C">C</span> declared, but nothing can run it</span>
201
- <span><span class="chip unknown">not checked here</span> this run could not determine it — NOT a pass</span>
202
- </div>
203
- <div class="scroll"><table>
204
- <thead><tr><th>Check</th><th>What a pass proves</th><th>Command</th>${head}<th>Cloud job</th></tr></thead>
205
- <tbody>${report.gates.map(row => gateRow(row, axis)).join("")}</tbody>
206
- </table></div>
207
- </section>
208
-
209
- <section>
210
- <h2>What a merge is actually blocked on</h2>
211
- <p class="lede">The contexts the settings file implies, beside the ones the repository's branch-protection rules really require. Nothing compares these two today, so they are only ever equal by hand.</p>
212
- ${rulesetSection(report)}
213
- </section>
214
-
215
- <footer>
216
- <p>Report format v${String(report.version)} · registry read from the running Lisa package · runner <code>${escapeHtml(report.runner.state === "verified" ? report.runner.value : "unknown")}</code>${report.declarationProblems.length === 0 ? "" : ` · <strong>${String(report.declarationProblems.length)} declaration problem(s)</strong>: ${escapeHtml(report.declarationProblems.join("; "))}`}</p>
217
- <p>Not rendered yet, and deliberately: the agent on-edit scripts, the table of cloud jobs that ignore the settings file, and any filtering.</p>
218
- </footer>
51
+ ${renderGateReportFragment(report, projectLabel)}
219
52
  </div>
220
53
  </body></html>`;
221
54
  }
222
- /** All styling, inlined so the file opens from disk with no server. */
223
- const STYLE = `
224
- :root{--bg:#0f1115;--panel:#161923;--line:#252a38;--ink:#e6e9f2;--dim:#98a0b5;
225
- --ok:#3fb950;--warn:#d29922;--bad:#f85149;--unk:#6b7280;--acc:#58a6ff}
226
- *{box-sizing:border-box}
227
- body{margin:0;background:var(--bg);color:var(--ink);
228
- font:15px/1.55 ui-sans-serif,-apple-system,"Segoe UI",Roboto,sans-serif}
229
- .wrap{max-width:1500px;margin:0 auto;padding:32px 24px 72px}
230
- h1{font-size:26px;margin:0 0 8px}
231
- h2{font-size:19px;margin:40px 0 6px;padding-top:24px;border-top:1px solid var(--line)}
232
- h3{font-size:14px;margin:0 0 4px;text-transform:uppercase;letter-spacing:.06em;color:var(--dim)}
233
- .sub,.lede{color:var(--dim);margin:0 0 16px;max-width:80ch}
234
- .stats{display:flex;flex-wrap:wrap;gap:12px;margin:20px 0 12px}
235
- .stat{background:var(--panel);border:1px solid var(--line);border-radius:10px;
236
- padding:12px 16px;min-width:170px}
237
- .stat b{display:block;font-size:28px;line-height:1.1}
238
- .stat span{color:var(--dim);font-size:12.5px}
239
- .denominator{background:var(--panel);border:1px solid var(--line);border-left:3px solid var(--acc);
240
- border-radius:8px;padding:12px 16px;margin:0;max-width:100ch}
241
- .legend{display:flex;flex-wrap:wrap;gap:8px 18px;margin:14px 0;color:var(--dim);font-size:12.5px}
242
- .legend>span{display:flex;align-items:center;gap:6px}
243
- .scroll{overflow-x:auto;border:1px solid var(--line);border-radius:10px}
244
- table{border-collapse:collapse;width:100%;font-size:13px;background:var(--panel)}
245
- th,td{text-align:left;padding:9px 11px;border-bottom:1px solid var(--line);vertical-align:top}
246
- th{position:sticky;top:0;background:#1b2030;font-size:11.5px;text-transform:uppercase;
247
- letter-spacing:.05em;color:var(--dim);z-index:1}
248
- th.m,td.m{text-align:center;white-space:nowrap}
249
- td.illegal{background:repeating-linear-gradient(45deg,transparent,transparent 5px,#1b2030 5px,#1b2030 10px)}
250
- tr:hover td{background:#1a1f2e}
251
- .gid{display:block;font-family:ui-monospace,monospace;font-size:12px;color:var(--acc)}
252
- .glabel{display:block;color:var(--dim);font-size:12px}
253
- .offaxis{margin-top:4px;color:var(--unk);font-size:11px;font-style:italic}
254
- .proves{color:var(--dim);max-width:34ch}
255
- code{font-family:ui-monospace,monospace;font-size:12px;background:#10131c;
256
- border:1px solid var(--line);border-radius:4px;padding:1px 5px}
257
- .state{display:inline-block;font-size:11px;border-radius:5px;padding:2px 7px;font-weight:600}
258
- .required{background:#1d3a24;color:#7ee787;border:1px solid #2ea04326}
259
- .optional{background:#3a3117;color:#e3b341;border:1px solid #d2992226}
260
- .off{background:#3a1d1d;color:#ff9492;border:1px solid #f8514926}
261
- .undeclared{background:#1b2030;color:var(--unk);border:1px dashed #3a4157}
262
- .chip{display:inline-block;margin-left:5px;font-size:10.5px;border-radius:4px;
263
- padding:1px 5px;font-weight:600;vertical-align:1px}
264
- .b-A{background:#123021;color:#7ee787}
265
- .b-B{background:#3a2c12;color:#e3b341}
266
- .b-C{background:#3a1616;color:#ff9492}
267
- .b-D{background:#2a2a2a;color:#bbb}
268
- .ok{background:#123021;color:#7ee787}
269
- .bad{background:#3a1616;color:#ff9492}
270
- .none{background:#1b2030;color:var(--unk)}
271
- .unknown{background:repeating-linear-gradient(45deg,#22262f,#22262f 3px,#191d25 3px,#191d25 6px);
272
- color:#9aa3b8;border:1px dashed #3f465c}
273
- .tier3{margin-top:5px;font-size:11px;color:var(--unk);font-style:italic}
274
- .unknown-note{background:repeating-linear-gradient(45deg,#22262f,#22262f 4px,#191d25 4px,#191d25 8px);
275
- border:1px dashed #3f465c;border-radius:8px;padding:14px 16px;color:#c2c9db}
276
- .cols{display:grid;grid-template-columns:repeat(auto-fit,minmax(300px,1fr));gap:14px}
277
- .cols>div{background:var(--panel);border:1px solid var(--line);border-radius:10px;padding:14px 16px}
278
- .cols .sharp{border-color:#7d2b2b;background:#1e1618}
279
- .cols p{color:var(--dim);font-size:12.5px;margin:0 0 8px}
280
- .cols ul{margin:0;padding-left:18px}
281
- .cols li{margin:3px 0;font-size:12.5px}
282
- .count{float:right;color:var(--ink);font-size:13px}
283
- footer{margin-top:44px;padding-top:18px;border-top:1px solid var(--line);
284
- color:var(--unk);font-size:12.5px}
285
- `;
286
55
  //# sourceMappingURL=gate-report-preview.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"gate-report-preview.js","sourceRoot":"","sources":["../../src/cli/gate-report-preview.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"gate-report-preview.js","sourceRoot":"","sources":["../../src/cli/gate-report-preview.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AACH,OAAO,EAAE,wBAAwB,EAAE,MAAM,2BAA2B,CAAC;AACrE,OAAO,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AAGnD;;;;;;;GAOG;AACH,MAAM,eAAe,GAAG;;;;;;;;;;;CAWvB,CAAC;AAEF;;;;;GAKG;AACH,MAAM,UAAU,uBAAuB,CACrC,MAAkB,EAClB,YAAoB;IAEpB,OAAO;;;uBAGc,UAAU,CAAC,YAAY,CAAC;SACtC,eAAe;;;EAGtB,wBAAwB,CAAC,MAAM,EAAE,YAAY,CAAC;;eAEjC,CAAC;AAChB,CAAC"}
@@ -0,0 +1,39 @@
1
+ import type { Finding, GateMomentCell, GateReportRow, MergeVerdict } from "./gate-report-types.js";
2
+ /**
3
+ * One matrix cell.
4
+ * @param cell - The (gate, moment) pair
5
+ * @returns A table cell
6
+ */
7
+ export declare function momentCell(cell: GateMomentCell): string;
8
+ /**
9
+ * Whether `package.json` has the command, said in three states and never none.
10
+ * @param cell - The cell carrying the command
11
+ * @returns One chip of HTML
12
+ */
13
+ export declare function commandChip(cell: GateMomentCell): string;
14
+ /**
15
+ * The first cell of a row that carries a resolved command.
16
+ * @param row - One gate's row
17
+ * @returns The most informative cell, or undefined
18
+ */
19
+ export declare function representativeCell(row: GateReportRow): GateMomentCell | undefined;
20
+ /**
21
+ * The command column: Lisa's default on top, any override beneath it.
22
+ * @param row - One gate's row
23
+ * @returns A table cell
24
+ */
25
+ export declare function commandCell(row: GateReportRow): string;
26
+ /**
27
+ * The merge column: yes, yes under another job's name, or no.
28
+ * @param merge - The row's merge finding
29
+ * @returns A table cell
30
+ */
31
+ export declare function mergeCell(merge: Finding<MergeVerdict>): string;
32
+ /**
33
+ * One gate row.
34
+ * @param row - The gate
35
+ * @param axis - The report's moment axis
36
+ * @returns A table row
37
+ */
38
+ export declare function gateRow(row: GateReportRow, axis: readonly string[]): string;
39
+ //# sourceMappingURL=gate-report-rows.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gate-report-rows.d.ts","sourceRoot":"","sources":["../../src/cli/gate-report-rows.ts"],"names":[],"mappings":"AAwBA,OAAO,KAAK,EACV,OAAO,EACP,cAAc,EACd,aAAa,EACb,YAAY,EAEb,MAAM,wBAAwB,CAAC;AA2ChC;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,cAAc,GAAG,MAAM,CAQvD;AAED;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,cAAc,GAAG,MAAM,CAUxD;AAED;;;;GAIG;AACH,wBAAgB,kBAAkB,CAChC,GAAG,EAAE,aAAa,GACjB,cAAc,GAAG,SAAS,CAM5B;AAmBD;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,GAAG,EAAE,aAAa,GAAG,MAAM,CAStD;AAED;;;;GAIG;AACH,wBAAgB,SAAS,CAAC,KAAK,EAAE,OAAO,CAAC,YAAY,CAAC,GAAG,MAAM,CAY9D;AAqDD;;;;;GAKG;AACH,wBAAgB,OAAO,CAAC,GAAG,EAAE,aAAa,EAAE,IAAI,EAAE,SAAS,MAAM,EAAE,GAAG,MAAM,CAa3E"}
@@ -0,0 +1,209 @@
1
+ /**
2
+ * One row of the report's matrix, and the cells that make it up.
3
+ *
4
+ * Two of the three render gaps this module closes were not data limitations.
5
+ * The emitter computed both and the renderer threw them away.
6
+ *
7
+ * **Provenance.** Every cell already names which of four sources supplied its
8
+ * command, and the report printed one command string. That matters more in a
9
+ * consumer than it does upstream, which is the reverse of the intuition: a
10
+ * reader who does not recognise a command needs to know whether it came from
11
+ * Lisa or from their own settings file, because that is the difference between
12
+ * "this is how Lisa ships" and "someone here changed this", and it decides who
13
+ * fixes it. So the default sits on top and the override beneath it — `here:`
14
+ * for a project override, `everyone:` for a registry swap that ships to all
15
+ * consumers.
16
+ *
17
+ * **The blank command chip.** `representativeCell` picks one cell to stand for
18
+ * a row, and when it found none the chip was silently omitted. Every legal
19
+ * cell has an answer, so a blank is never "we could not tell" — it is the
20
+ * renderer having nothing to say and saying nothing, which reads as fine. A
21
+ * row with no representative cell now says so.
22
+ * @module cli/gate-report-rows
23
+ */
24
+ import { chip, code, escapeHtml, unknownChip } from "./gate-report-html.js";
25
+ /** The state of a fact that does not exist here at all. */
26
+ const NOT_APPLICABLE = "not-applicable";
27
+ /** How each declaration state is written. */
28
+ const DECLARATION_LABELS = {
29
+ required: "must",
30
+ optional: "tells",
31
+ off: "off",
32
+ "not-declared": "not declared",
33
+ };
34
+ /** What each bucket means, in one line. */
35
+ const BUCKET_TITLES = {
36
+ A: "declared, and an executor resolves the declaration",
37
+ B: "an executor exists, but no declaration reaches it",
38
+ C: "a declaration exists that nothing can execute",
39
+ D: "nothing declares it and nothing runs it",
40
+ };
41
+ /** The two overriding provenances, and the word each is written with. */
42
+ const OVERRIDE_WORDS = {
43
+ "moment-run": "here",
44
+ "gate-run": "here",
45
+ "registry-task-at": "everyone",
46
+ };
47
+ /**
48
+ * The bucket chip for one cell, or the honest refusal to classify it.
49
+ * @param bucket - The cell's bucket finding
50
+ * @returns One chip of HTML
51
+ */
52
+ function bucketChip(bucket) {
53
+ if (bucket.state === NOT_APPLICABLE)
54
+ return "";
55
+ if (bucket.state === "unknown")
56
+ return unknownChip(bucket);
57
+ return chip(`b-${bucket.value}`, bucket.value, BUCKET_TITLES[bucket.value] ?? "");
58
+ }
59
+ /**
60
+ * One matrix cell.
61
+ * @param cell - The (gate, moment) pair
62
+ * @returns A table cell
63
+ */
64
+ export function momentCell(cell) {
65
+ if (!cell.legal) {
66
+ return '<td class="lgr-m lgr-illegal" title="the registry does not permit declaring this gate here"></td>';
67
+ }
68
+ const label = DECLARATION_LABELS[cell.declaration] ?? cell.declaration;
69
+ const state = cell.declaration === "not-declared" ? "undeclared" : cell.declaration;
70
+ return `<td class="lgr-m"><span class="lgr-state lgr-${escapeHtml(state)}">${escapeHtml(label)}</span>${bucketChip(cell.bucket)}</td>`;
71
+ }
72
+ /**
73
+ * Whether `package.json` has the command, said in three states and never none.
74
+ * @param cell - The cell carrying the command
75
+ * @returns One chip of HTML
76
+ */
77
+ export function commandChip(cell) {
78
+ if (cell.commandExists.state === "unknown") {
79
+ return unknownChip(cell.commandExists, "command not checked");
80
+ }
81
+ if (cell.commandExists.state === NOT_APPLICABLE) {
82
+ return chip("none", "no task here", cell.commandExists.message);
83
+ }
84
+ return cell.commandExists.value
85
+ ? chip("ok", "script exists")
86
+ : chip("bad", "no such script");
87
+ }
88
+ /**
89
+ * The first cell of a row that carries a resolved command.
90
+ * @param row - One gate's row
91
+ * @returns The most informative cell, or undefined
92
+ */
93
+ export function representativeCell(row) {
94
+ return (row.moments.find(cell => cell.legal && cell.declaration !== "not-declared") ?? row.moments.find(cell => cell.legal));
95
+ }
96
+ /**
97
+ * The override line beneath the default, when one of the four sources won.
98
+ * @param cell - The representative cell
99
+ * @returns One line of HTML, or an empty string when Lisa's default runs
100
+ */
101
+ function provenanceLine(cell) {
102
+ const word = OVERRIDE_WORDS[cell.provenance];
103
+ if (word === undefined || cell.task === null)
104
+ return "";
105
+ const scope = cell.provenance === "moment-run" ? ` (at ${cell.moment} only)` : "";
106
+ const title = word === "here"
107
+ ? "this project's settings file names its own task for this gate"
108
+ : "Lisa swaps the task at this moment, for every project";
109
+ return `<div class="lgr-prov" title="${escapeHtml(title)}"><span class="lgr-provword">${word}:</span> ${code(cell.task)}${escapeHtml(scope)}</div>`;
110
+ }
111
+ /**
112
+ * The command column: Lisa's default on top, any override beneath it.
113
+ * @param row - One gate's row
114
+ * @returns A table cell
115
+ */
116
+ export function commandCell(row) {
117
+ const cell = representativeCell(row);
118
+ if (cell === undefined) {
119
+ // Never silence. A row reaches here only when every moment the registry
120
+ // permits is off this project's axis, which is a fact worth stating rather
121
+ // than an empty box the reader will read as "fine".
122
+ return `<td>${code(row.defaultTask ?? "—")}${chip("unknown", "no column here", "This gate is only legal at moments this project has no column for, so no cell on this row could be shown.")}</td>`;
123
+ }
124
+ return `<td>${code(row.defaultTask ?? cell.task ?? "—")}${commandChip(cell)}${provenanceLine(cell)}</td>`;
125
+ }
126
+ /**
127
+ * The merge column: yes, yes under another job's name, or no.
128
+ * @param merge - The row's merge finding
129
+ * @returns A table cell
130
+ */
131
+ export function mergeCell(merge) {
132
+ if (merge.state !== "verified") {
133
+ return `<td class="lgr-m">${unknownChip(merge)}</td>`;
134
+ }
135
+ if (merge.value.verdict === "no") {
136
+ return `<td class="lgr-m">${chip("no-merge", "no", "No required status context stands between this gate and a merge.")}</td>`;
137
+ }
138
+ const context = merge.value.context ?? "";
139
+ if (merge.value.verdict === "yes") {
140
+ return `<td class="lgr-m">${chip("yes-merge", "yes", context)}</td>`;
141
+ }
142
+ return `<td class="lgr-m">${chip("other-merge", "yes, other name", context)}<div class="lgr-under">under ${code(merge.value.underJob ?? context)}</div></td>`;
143
+ }
144
+ /**
145
+ * Legal moments the project's own axis has no column for.
146
+ * @param row - One gate's row
147
+ * @param axis - The report's moment axis
148
+ * @returns Human text, or an empty string
149
+ */
150
+ function offAxisMoments(row, axis) {
151
+ const families = row.legalMoments.filter(moment => !axis.includes(moment) && !axis.some(one => one.startsWith(`${moment}:`)));
152
+ return families.length === 0
153
+ ? ""
154
+ : `<div class="lgr-offaxis">also legal at ${escapeHtml(families.join(", "))}</div>`;
155
+ }
156
+ /**
157
+ * The cloud job a gate maps to, and whether that job reads the declaration.
158
+ * @param row - One gate's row
159
+ * @returns A table cell
160
+ */
161
+ function jobCell(row) {
162
+ const job = row.qualityJob === null ? chip("none", "no job") : code(row.qualityJob);
163
+ const facade = representativeCell(row)?.facadeReadsDeclaration;
164
+ return `<td>${job}<div class="lgr-tier3">${facadeText(facade)}</div></td>`;
165
+ }
166
+ /**
167
+ * How the "reads the declaration" line reads for one cell.
168
+ *
169
+ * Four inputs, four sentences. A row with no mapped job is not an unanswered
170
+ * question — there is no job whose wiring could be read — and labelling it
171
+ * "not checked here" would file Lisa's unknowable Tier 3 and a plain
172
+ * not-applicable under one word.
173
+ * @param facade - The Tier 3 finding, when the row has one
174
+ * @returns One line of text as HTML
175
+ */
176
+ function facadeText(facade) {
177
+ if (facade === undefined)
178
+ return "no cell on this row to read";
179
+ if (facade.state === NOT_APPLICABLE) {
180
+ return `<span title="${escapeHtml(facade.message)}">no cloud job maps to this check</span>`;
181
+ }
182
+ if (facade.state === "verified") {
183
+ return facade.value
184
+ ? `reads the declaration: ${chip("ok", "yes")}`
185
+ : `reads the declaration: ${chip("bad", "no — hardcoded")}`;
186
+ }
187
+ return `reads the declaration: ${unknownChip(facade)}`;
188
+ }
189
+ /**
190
+ * One gate row.
191
+ * @param row - The gate
192
+ * @param axis - The report's moment axis
193
+ * @returns A table row
194
+ */
195
+ export function gateRow(row, axis) {
196
+ return [
197
+ "<tr>",
198
+ `<td><span class="lgr-gid">${escapeHtml(row.id)}</span><span class="lgr-glabel">${escapeHtml(row.label)}</span>`,
199
+ offAxisMoments(row, axis),
200
+ "</td>",
201
+ `<td class="lgr-proves">${escapeHtml(row.summary)}</td>`,
202
+ commandCell(row),
203
+ row.moments.map(momentCell).join(""),
204
+ mergeCell(row.merge),
205
+ jobCell(row),
206
+ "</tr>",
207
+ ].join("");
208
+ }
209
+ //# sourceMappingURL=gate-report-rows.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gate-report-rows.js","sourceRoot":"","sources":["../../src/cli/gate-report-rows.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,32 @@
1
+ import type { GateReport } from "./gate-report-types.js";
2
+ /**
3
+ * The header counts, each with its denominator and its unknown band.
4
+ * @param report - The whole report
5
+ * @returns A section of HTML
6
+ */
7
+ export declare function summarySection(report: GateReport): string;
8
+ /**
9
+ * The declaration-versus-ruleset comparison.
10
+ * @param report - The whole report
11
+ * @returns A section of HTML
12
+ */
13
+ export declare function rulesetSection(report: GateReport): string;
14
+ /**
15
+ * Everything a merge is blocked on, grouped by who put it there.
16
+ * @param report - The whole report
17
+ * @returns A section of HTML
18
+ */
19
+ export declare function requiredContextsSection(report: GateReport): string;
20
+ /**
21
+ * What fires on every file an agent writes.
22
+ * @param report - The whole report
23
+ * @returns A section of HTML
24
+ */
25
+ export declare function agentHooksSection(report: GateReport): string;
26
+ /**
27
+ * Lisa's own limitations, stated once each with a count and a ticket.
28
+ * @param report - The whole report
29
+ * @returns A section of HTML, or an empty string when there are none
30
+ */
31
+ export declare function upstreamSection(report: GateReport): string;
32
+ //# sourceMappingURL=gate-report-sections.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gate-report-sections.d.ts","sourceRoot":"","sources":["../../src/cli/gate-report-sections.ts"],"names":[],"mappings":"AAoBA,OAAO,KAAK,EAEV,UAAU,EAEX,MAAM,wBAAwB,CAAC;AA0ChC;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,UAAU,GAAG,MAAM,CAazD;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,UAAU,GAAG,MAAM,CAiBzD;AAmBD;;;;GAIG;AACH,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,UAAU,GAAG,MAAM,CAclE;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,UAAU,GAAG,MAAM,CAmB5D;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,UAAU,GAAG,MAAM,CAc1D"}