@codyswann/lisa 3.49.0 → 3.51.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 +23 -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
@@ -0,0 +1,49 @@
1
+ /** Characters that must not reach the browser as markup. */
2
+ const ESCAPES = {
3
+ "&": "&",
4
+ "<": "&lt;",
5
+ ">": "&gt;",
6
+ '"': "&quot;",
7
+ "'": "&#39;",
8
+ };
9
+ /**
10
+ * Escape a string for interpolation into HTML.
11
+ * @param value - Raw text
12
+ * @returns Escaped text
13
+ */
14
+ export function escapeHtml(value) {
15
+ return value.replace(/[&<>"']/g, character => ESCAPES[character] ?? character);
16
+ }
17
+ /**
18
+ * One chip.
19
+ * @param variant - The chip's state class
20
+ * @param text - Its label
21
+ * @param title - Hover text explaining it
22
+ * @returns One chip of HTML
23
+ */
24
+ export function chip(variant, text, title = "") {
25
+ const attribute = title === "" ? "" : ` title="${escapeHtml(title)}"`;
26
+ return `<span class="lgr-chip lgr-${escapeHtml(variant)}"${attribute}>${escapeHtml(text)}</span>`;
27
+ }
28
+ /**
29
+ * The chip for a finding this run could not determine.
30
+ *
31
+ * Carries the human message as hover text rather than dropping it: a report
32
+ * that says "not checked here" without saying why is indistinguishable from a
33
+ * bug in the report.
34
+ * @param finding - An unknown or not-applicable finding
35
+ * @param label - What to call it
36
+ * @returns One chip of HTML
37
+ */
38
+ export function unknownChip(finding, label = "not checked here") {
39
+ return chip("unknown", label, finding.message);
40
+ }
41
+ /**
42
+ * One monospaced fragment.
43
+ * @param value - Raw text
44
+ * @returns The text inside a `code` element, escaped
45
+ */
46
+ export function code(value) {
47
+ return `<code>${escapeHtml(value)}</code>`;
48
+ }
49
+ //# sourceMappingURL=gate-report-html.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gate-report-html.js","sourceRoot":"","sources":["../../src/cli/gate-report-html.ts"],"names":[],"mappings":"AAcA,4DAA4D;AAC5D,MAAM,OAAO,GAAqC;IAChD,GAAG,EAAE,OAAO;IACZ,GAAG,EAAE,MAAM;IACX,GAAG,EAAE,MAAM;IACX,GAAG,EAAE,QAAQ;IACb,GAAG,EAAE,OAAO;CACb,CAAC;AAEF;;;;GAIG;AACH,MAAM,UAAU,UAAU,CAAC,KAAa;IACtC,OAAO,KAAK,CAAC,OAAO,CAClB,UAAU,EACV,SAAS,CAAC,EAAE,CAAC,OAAO,CAAC,SAAS,CAAC,IAAI,SAAS,CAC7C,CAAC;AACJ,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,IAAI,CAAC,OAAe,EAAE,IAAY,EAAE,KAAK,GAAG,EAAE;IAC5D,MAAM,SAAS,GAAG,KAAK,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,WAAW,UAAU,CAAC,KAAK,CAAC,GAAG,CAAC;IACtE,OAAO,6BAA6B,UAAU,CAAC,OAAO,CAAC,IAAI,SAAS,IAAI,UAAU,CAAC,IAAI,CAAC,SAAS,CAAC;AACpG,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,UAAU,WAAW,CACzB,OAAsD,EACtD,KAAK,GAAG,kBAAkB;IAE1B,OAAO,IAAI,CAAC,SAAS,EAAE,KAAK,EAAE,OAAO,CAAC,OAAO,CAAC,CAAC;AACjD,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,IAAI,CAAC,KAAa;IAChC,OAAO,SAAS,UAAU,CAAC,KAAK,CAAC,SAAS,CAAC;AAC7C,CAAC"}
@@ -0,0 +1,37 @@
1
+ import type { FacadeFacts } from "./gate-report-facade.js";
2
+ import type { GateRegistryModule } from "./gate-report-registry.js";
3
+ import type { Finding, MergeBlock, RequiredContextRow, RulesetComparison } from "./gate-report-types.js";
4
+ /** Everything the joins need about this run. */
5
+ export interface JoinContext {
6
+ /** The shipped registry. */
7
+ readonly registry: GateRegistryModule;
8
+ /** The project's gates block. */
9
+ readonly gates: Record<string, unknown>;
10
+ /** The live required contexts, or an unknown. */
11
+ readonly contexts: Finding<readonly string[]>;
12
+ /** What the project's own workflows say. */
13
+ readonly facade: FacadeFacts;
14
+ /** The moment a ruleset guards. */
15
+ readonly mergeMoment: string;
16
+ /** The workflow name a run gate's context is built from. */
17
+ readonly workflowName: string;
18
+ }
19
+ /**
20
+ * The Tier 2 answer for one cell, never defaulted to a verdict.
21
+ * @param context - The join inputs
22
+ * @returns A resolver for one cell's expected context
23
+ */
24
+ export declare function mergeBlockResolver(context: JoinContext): (moment: string, expectedContext: string | null) => Finding<MergeBlock>;
25
+ /**
26
+ * The ruleset comparison, or the same unknown the contexts came back with.
27
+ * @param context - The join inputs
28
+ * @returns The comparison
29
+ */
30
+ export declare function buildRulesetFinding(context: JoinContext): Finding<RulesetComparison>;
31
+ /**
32
+ * Every context a merge is blocked on, with who owns it.
33
+ * @param context - The join inputs
34
+ * @returns One row per required context, or the same unknown
35
+ */
36
+ export declare function buildRequiredContexts(context: JoinContext): Finding<readonly RequiredContextRow[]>;
37
+ //# sourceMappingURL=gate-report-joins.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gate-report-joins.d.ts","sourceRoot":"","sources":["../../src/cli/gate-report-joins.ts"],"names":[],"mappings":"AAmBA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAC3D,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAEpE,OAAO,KAAK,EACV,OAAO,EACP,UAAU,EACV,kBAAkB,EAClB,iBAAiB,EAClB,MAAM,wBAAwB,CAAC;AAEhC,gDAAgD;AAChD,MAAM,WAAW,WAAW;IAC1B,4BAA4B;IAC5B,QAAQ,CAAC,QAAQ,EAAE,kBAAkB,CAAC;IACtC,iCAAiC;IACjC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACxC,iDAAiD;IACjD,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC,SAAS,MAAM,EAAE,CAAC,CAAC;IAC9C,4CAA4C;IAC5C,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAC;IAC7B,mCAAmC;IACnC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,4DAA4D;IAC5D,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;CAC/B;AAkBD;;;;GAIG;AACH,wBAAgB,kBAAkB,CAChC,OAAO,EAAE,WAAW,GACnB,CAAC,MAAM,EAAE,MAAM,EAAE,eAAe,EAAE,MAAM,GAAG,IAAI,KAAK,OAAO,CAAC,UAAU,CAAC,CAwBzE;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,CACjC,OAAO,EAAE,WAAW,GACnB,OAAO,CAAC,iBAAiB,CAAC,CAe5B;AAED;;;;GAIG;AACH,wBAAgB,qBAAqB,CACnC,OAAO,EAAE,WAAW,GACnB,OAAO,CAAC,SAAS,kBAAkB,EAAE,CAAC,CAaxC"}
@@ -0,0 +1,104 @@
1
+ /**
2
+ * The joins between one project's declarations and the world outside it.
3
+ *
4
+ * Three of them, and each is a place two sources of truth are compared for the
5
+ * first time: the ruleset against the declaration (#2854's finding — nothing
6
+ * compares these today, so they are only ever equal by hand), every required
7
+ * context against who owns it, and one gate's implied context against the
8
+ * moment a ruleset can actually guard.
9
+ *
10
+ * Kept out of the report assembly because the assembly is a list of steps and
11
+ * these are the reasoning. Every one of them carries an unknown through rather
12
+ * than resolving it: a run that could not read branch protection has nothing to
13
+ * compare, and an empty comparison would report agreement.
14
+ * @module cli/gate-report-joins
15
+ */
16
+ import { classifyRequiredContexts, lisaContextUniverse, } from "./gate-report-contexts.js";
17
+ import { compareContexts } from "./gate-report-ruleset.js";
18
+ /**
19
+ * The contexts a gates block implies at the merge moment.
20
+ * @param context - The join inputs
21
+ * @returns The contexts, or null when the block cannot be resolved
22
+ */
23
+ function declaredContexts(context) {
24
+ try {
25
+ return context.registry.contextsFor(context.gates, {
26
+ moment: context.mergeMoment,
27
+ workflowName: context.workflowName,
28
+ });
29
+ }
30
+ catch {
31
+ return null;
32
+ }
33
+ }
34
+ /**
35
+ * The Tier 2 answer for one cell, never defaulted to a verdict.
36
+ * @param context - The join inputs
37
+ * @returns A resolver for one cell's expected context
38
+ */
39
+ export function mergeBlockResolver(context) {
40
+ return (moment, expectedContext) => {
41
+ if (moment !== context.mergeMoment) {
42
+ return {
43
+ state: "not-applicable",
44
+ reason: "moment-produces-no-merge-context",
45
+ message: `A ruleset guards a merge, and only the ${context.mergeMoment} gate set produces the status contexts it names. A declaration at ${moment} is enforced by a hook, not by branch protection.`,
46
+ };
47
+ }
48
+ if (expectedContext === null) {
49
+ return {
50
+ state: "not-applicable",
51
+ reason: "no-required-declaration",
52
+ message: "Only a `required` declaration produces a status context, so there is nothing here for a ruleset to require.",
53
+ };
54
+ }
55
+ if (context.contexts.state !== "verified")
56
+ return context.contexts;
57
+ const required = context.contexts.value.includes(expectedContext);
58
+ return {
59
+ state: "verified",
60
+ value: { required, context: required ? expectedContext : null },
61
+ };
62
+ };
63
+ }
64
+ /**
65
+ * The ruleset comparison, or the same unknown the contexts came back with.
66
+ * @param context - The join inputs
67
+ * @returns The comparison
68
+ */
69
+ export function buildRulesetFinding(context) {
70
+ if (context.contexts.state !== "verified")
71
+ return context.contexts;
72
+ const declared = declaredContexts(context);
73
+ if (declared === null) {
74
+ return {
75
+ state: "unknown",
76
+ reason: "declarations-unresolvable",
77
+ message: "The gates block could not be resolved, so the contexts it implies cannot be compared with the ruleset.",
78
+ };
79
+ }
80
+ return {
81
+ state: "verified",
82
+ value: compareContexts(declared, context.contexts.value),
83
+ };
84
+ }
85
+ /**
86
+ * Every context a merge is blocked on, with who owns it.
87
+ * @param context - The join inputs
88
+ * @returns One row per required context, or the same unknown
89
+ */
90
+ export function buildRequiredContexts(context) {
91
+ return classifyRequiredContexts(context.contexts, {
92
+ declared: declaredContexts(context) ?? [],
93
+ lisaUniverse: lisaContextUniverse({
94
+ gateIds: Object.entries(context.registry.REGISTRY)
95
+ .filter(([, gate]) => gate.moments.includes(context.mergeMoment))
96
+ .map(([id]) => id),
97
+ moment: context.mergeMoment,
98
+ workflowName: context.workflowName,
99
+ contextsFor: context.registry.contextsFor,
100
+ }),
101
+ projectContexts: context.facade.projectContexts,
102
+ });
103
+ }
104
+ //# sourceMappingURL=gate-report-joins.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gate-report-joins.js","sourceRoot":"","sources":["../../src/cli/gate-report-joins.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,22 @@
1
+ import { type FacadeFacts } from "./gate-report-facade.js";
2
+ import type { Finding, MergeVerdict } from "./gate-report-types.js";
3
+ /** Everything one row's verdict is derived from. */
4
+ export interface MergeVerdictInputs {
5
+ /** The context this gate's own `required` declaration implies, if any. */
6
+ readonly expectedContext: string | null;
7
+ /** The task this gate resolves to at the merge moment. */
8
+ readonly task: string | null;
9
+ /** This gate's own CI job name, so another job's name can be told apart. */
10
+ readonly label: string;
11
+ /** The live required contexts, or an unknown. */
12
+ readonly required: Finding<readonly string[]>;
13
+ /** What the project's own workflows say. */
14
+ readonly facade: FacadeFacts;
15
+ }
16
+ /**
17
+ * Whether a merge is blocked on one gate, and under whose name.
18
+ * @param inputs - Verdict inputs
19
+ * @returns The verdict, or the honest refusal to give one
20
+ */
21
+ export declare function mergeVerdict(inputs: MergeVerdictInputs): Finding<MergeVerdict>;
22
+ //# sourceMappingURL=gate-report-merge.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gate-report-merge.d.ts","sourceRoot":"","sources":["../../src/cli/gate-report-merge.ts"],"names":[],"mappings":"AAsBA,OAAO,EAEL,KAAK,WAAW,EACjB,MAAM,yBAAyB,CAAC;AACjC,OAAO,KAAK,EAAE,OAAO,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AAEpE,oDAAoD;AACpD,MAAM,WAAW,kBAAkB;IACjC,0EAA0E;IAC1E,QAAQ,CAAC,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;IACxC,0DAA0D;IAC1D,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,4EAA4E;IAC5E,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,iDAAiD;IACjD,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC,SAAS,MAAM,EAAE,CAAC,CAAC;IAC9C,4CAA4C;IAC5C,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAC;CAC9B;AAsBD;;;;GAIG;AACH,wBAAgB,YAAY,CAC1B,MAAM,EAAE,kBAAkB,GACzB,OAAO,CAAC,YAAY,CAAC,CA4BvB"}
@@ -0,0 +1,79 @@
1
+ /**
2
+ * Whether a merge is actually blocked on one gate.
3
+ *
4
+ * The emitter computed the per-cell half of this from the first day and the
5
+ * renderer discarded every byte of it, which left the report unable to surface
6
+ * the class of finding it was built to find: a check that is `required` at push
7
+ * and gates NOTHING at merge, so the cost is paid on every developer's machine
8
+ * while anyone pushing from a hookless path skips it and merges anyway.
9
+ *
10
+ * Three answers, and the middle one is the whole reason the column exists.
11
+ * A property proved inside a job named after a different gate still blocks the
12
+ * merge — but the red build then names a property that did not fail, and a
13
+ * column that collapsed that into "yes" could not show it.
14
+ *
15
+ * The third answer is derived, not assumed: a job whose shell runs this gate's
16
+ * task, under a name that is not this gate's, whose context the ruleset
17
+ * requires. Where the workflows cannot be read the answer is the upstream
18
+ * refusal rather than "no" — "not blocked" is a claim, and this run would not
19
+ * have looked.
20
+ * @module cli/gate-report-merge
21
+ */
22
+ import { hookInvokesTask } from "./gate-report-executors.js";
23
+ import { TIER_THREE_UNKNOWABLE, } from "./gate-report-facade.js";
24
+ /**
25
+ * The first job that proves this task under a name that is not this gate's.
26
+ * @param inputs - Verdict inputs
27
+ * @param required - The live required contexts
28
+ * @returns The blocking context and job name, or null
29
+ */
30
+ function underAnotherName(inputs, required) {
31
+ const { task, label, facade } = inputs;
32
+ if (task === null)
33
+ return null;
34
+ for (const site of facade.jobSites) {
35
+ if (site.name === label || !hookInvokesTask(site.shell, task))
36
+ continue;
37
+ const context = site.contexts.find(one => required.includes(one));
38
+ if (context !== undefined)
39
+ return { context, job: site.name };
40
+ }
41
+ return null;
42
+ }
43
+ /**
44
+ * Whether a merge is blocked on one gate, and under whose name.
45
+ * @param inputs - Verdict inputs
46
+ * @returns The verdict, or the honest refusal to give one
47
+ */
48
+ export function mergeVerdict(inputs) {
49
+ const { expectedContext, required, facade } = inputs;
50
+ if (required.state !== "verified")
51
+ return required;
52
+ if (expectedContext !== null && required.value.includes(expectedContext)) {
53
+ return {
54
+ state: "verified",
55
+ value: { verdict: "yes", context: expectedContext, underJob: null },
56
+ };
57
+ }
58
+ const other = underAnotherName(inputs, required.value);
59
+ if (other !== null) {
60
+ return {
61
+ state: "verified",
62
+ value: {
63
+ verdict: "yes-under-another-name",
64
+ context: other.context,
65
+ underJob: other.job,
66
+ },
67
+ };
68
+ }
69
+ // A consumer holds no copy of the workflow, so it cannot see whether one of
70
+ // Lisa's own jobs proves this property under a different job's name. "No"
71
+ // would be a claim this run did not check.
72
+ if (!facade.qualityYmlPresent)
73
+ return TIER_THREE_UNKNOWABLE;
74
+ return {
75
+ state: "verified",
76
+ value: { verdict: "no", context: null, underJob: null },
77
+ };
78
+ }
79
+ //# sourceMappingURL=gate-report-merge.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gate-report-merge.js","sourceRoot":"","sources":["../../src/cli/gate-report-merge.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,OAAO,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAC7D,OAAO,EACL,qBAAqB,GAEtB,MAAM,yBAAyB,CAAC;AAiBjC;;;;;GAKG;AACH,SAAS,gBAAgB,CACvB,MAA0B,EAC1B,QAA2B;IAE3B,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,MAAM,CAAC;IACvC,IAAI,IAAI,KAAK,IAAI;QAAE,OAAO,IAAI,CAAC;IAC/B,KAAK,MAAM,IAAI,IAAI,MAAM,CAAC,QAAQ,EAAE,CAAC;QACnC,IAAI,IAAI,CAAC,IAAI,KAAK,KAAK,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC;YAAE,SAAS;QACxE,MAAM,OAAO,GAAG,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC;QAClE,IAAI,OAAO,KAAK,SAAS;YAAE,OAAO,EAAE,OAAO,EAAE,GAAG,EAAE,IAAI,CAAC,IAAI,EAAE,CAAC;IAChE,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,YAAY,CAC1B,MAA0B;IAE1B,MAAM,EAAE,eAAe,EAAE,QAAQ,EAAE,MAAM,EAAE,GAAG,MAAM,CAAC;IACrD,IAAI,QAAQ,CAAC,KAAK,KAAK,UAAU;QAAE,OAAO,QAAQ,CAAC;IACnD,IAAI,eAAe,KAAK,IAAI,IAAI,QAAQ,CAAC,KAAK,CAAC,QAAQ,CAAC,eAAe,CAAC,EAAE,CAAC;QACzE,OAAO;YACL,KAAK,EAAE,UAAU;YACjB,KAAK,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,eAAe,EAAE,QAAQ,EAAE,IAAI,EAAE;SACpE,CAAC;IACJ,CAAC;IACD,MAAM,KAAK,GAAG,gBAAgB,CAAC,MAAM,EAAE,QAAQ,CAAC,KAAK,CAAC,CAAC;IACvD,IAAI,KAAK,KAAK,IAAI,EAAE,CAAC;QACnB,OAAO;YACL,KAAK,EAAE,UAAU;YACjB,KAAK,EAAE;gBACL,OAAO,EAAE,wBAAwB;gBACjC,OAAO,EAAE,KAAK,CAAC,OAAO;gBACtB,QAAQ,EAAE,KAAK,CAAC,GAAG;aACpB;SACF,CAAC;IACJ,CAAC;IACD,4EAA4E;IAC5E,0EAA0E;IAC1E,2CAA2C;IAC3C,IAAI,CAAC,MAAM,CAAC,iBAAiB;QAAE,OAAO,qBAAqB,CAAC;IAC5D,OAAO;QACL,KAAK,EAAE,UAAU;QACjB,KAAK,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE;KACxD,CAAC;AACJ,CAAC"}
@@ -1,21 +1,3 @@
1
- /**
2
- * Render the gate report as a standalone HTML page.
3
- *
4
- * Deliberately NOT part of `ui/index.html`. That file is one 13,000-line
5
- * document with no build step and a known hazard where concurrent edits merge
6
- * badly, and where the report should finally live is an open question nobody
7
- * has ruled on. A separate page sidesteps both: it is a viewing surface for a
8
- * payload that already exists, not a decision about the console's structure.
9
- *
10
- * Pure and total — report in, string out, no I/O — so the same emitter output
11
- * always produces the same bytes.
12
- *
13
- * The rendering rule that matters: `unknown` must never look like a pass. A
14
- * cell this run could not determine is drawn in its own hatched, muted style
15
- * with its own label, and the header counts it in a band of its own rather
16
- * than folding it into a green total.
17
- * @module cli/gate-report-preview
18
- */
19
1
  import type { GateReport } from "./gate-report-types.js";
20
2
  /**
21
3
  * Render the whole page.
@@ -1 +1 @@
1
- {"version":3,"file":"gate-report-preview.d.ts","sourceRoot":"","sources":["../../src/cli/gate-report-preview.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AACH,OAAO,KAAK,EAGV,UAAU,EAEX,MAAM,wBAAwB,CAAC;AA+LhC;;;;;GAKG;AACH,wBAAgB,uBAAuB,CACrC,MAAM,EAAE,UAAU,EAClB,YAAY,EAAE,MAAM,GACnB,MAAM,CAgDR"}
1
+ {"version":3,"file":"gate-report-preview.d.ts","sourceRoot":"","sources":["../../src/cli/gate-report-preview.ts"],"names":[],"mappings":"AAgBA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AAuBzD;;;;;GAKG;AACH,wBAAgB,uBAAuB,CACrC,MAAM,EAAE,UAAU,EAClB,YAAY,EAAE,MAAM,GACnB,MAAM,CAWR"}