@codyswann/lisa 4.10.6 → 4.10.8
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.
- package/all/copy-overwrite/scripts/lisa-gates.mjs +82 -1
- package/all/copy-overwrite/scripts/lisa-hooks/parity-safety-net.sh +269 -44
- package/dist/cli/doctor-declared-contexts.d.ts.map +1 -1
- package/dist/cli/doctor-declared-contexts.js +16 -0
- package/dist/cli/doctor-declared-contexts.js.map +1 -1
- package/dist/cli/gate-report-drift-section.d.ts.map +1 -1
- package/dist/cli/gate-report-drift-section.js +6 -0
- package/dist/cli/gate-report-drift-section.js.map +1 -1
- package/dist/cli/gate-report-joins.d.ts +0 -15
- package/dist/cli/gate-report-joins.d.ts.map +1 -1
- package/dist/cli/gate-report-joins.js +2 -1
- package/dist/cli/gate-report-joins.js.map +1 -1
- package/dist/cli/gate-report-registry.d.ts +8 -0
- package/dist/cli/gate-report-registry.d.ts.map +1 -1
- package/dist/cli/gate-report-registry.js.map +1 -1
- package/dist/cli/gate-report-types.d.ts +2 -1
- package/dist/cli/gate-report-types.d.ts.map +1 -1
- package/dist/cli/gate-report-types.js.map +1 -1
- package/dist/core/gate-context-owners.d.ts +122 -0
- package/dist/core/gate-context-owners.d.ts.map +1 -0
- package/dist/core/gate-context-owners.js +174 -0
- package/dist/core/gate-context-owners.js.map +1 -0
- package/dist/core/gate-declaration-drift.d.ts +56 -79
- package/dist/core/gate-declaration-drift.d.ts.map +1 -1
- package/dist/core/gate-declaration-drift.js +73 -115
- package/dist/core/gate-declaration-drift.js.map +1 -1
- package/dist/core/lisa-owned-hash-ledger.d.ts.map +1 -1
- package/dist/core/lisa-owned-hash-ledger.js +5 -0
- package/dist/core/lisa-owned-hash-ledger.js.map +1 -1
- package/dist/core/upstream-evidence-manifest.d.ts.map +1 -1
- package/dist/core/upstream-evidence-manifest.js +9 -4
- package/dist/core/upstream-evidence-manifest.js.map +1 -1
- package/dist/health/declared-checks-inspection.d.ts +0 -22
- package/dist/health/declared-checks-inspection.d.ts.map +1 -1
- package/dist/health/declared-checks-inspection.js +44 -5
- package/dist/health/declared-checks-inspection.js.map +1 -1
- package/dist/opencode/plugin-templates/parity-safety-net.sh +269 -44
- package/package.json +1 -1
- package/plugins/lisa/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa/hooks/parity-safety-net.sh +269 -44
- package/plugins/lisa-agy/hooks/parity-safety-net.sh +269 -44
- package/plugins/lisa-agy/plugin.json +1 -1
- package/plugins/lisa-cdk/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-cdk/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-cdk-agy/plugin.json +1 -1
- package/plugins/lisa-cdk-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-cdk-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-copilot/hooks/parity-safety-net.sh +269 -44
- package/plugins/lisa-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-cursor/hooks/parity-safety-net.sh +269 -44
- package/plugins/lisa-expo/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-expo/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-expo-agy/plugin.json +1 -1
- package/plugins/lisa-expo-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-expo-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-harper-fabric/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-harper-fabric/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-harper-fabric-agy/plugin.json +1 -1
- package/plugins/lisa-harper-fabric-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-harper-fabric-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-nestjs/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-nestjs/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-nestjs-agy/plugin.json +1 -1
- package/plugins/lisa-nestjs-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-nestjs-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-openclaw/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-openclaw/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-openclaw-agy/plugin.json +1 -1
- package/plugins/lisa-openclaw-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-openclaw-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-phaser/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-phaser/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-phaser-agy/plugin.json +1 -1
- package/plugins/lisa-phaser-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-phaser-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-rails/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-rails/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-rails-agy/plugin.json +1 -1
- package/plugins/lisa-rails-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-rails-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-typescript/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-typescript/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-typescript-agy/plugin.json +1 -1
- package/plugins/lisa-typescript-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-typescript-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-wiki/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-wiki/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-wiki-agy/plugin.json +1 -1
- package/plugins/lisa-wiki-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-wiki-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/src/base/hooks/parity-safety-net.sh +269 -44
- package/scripts/lisa-github-rulesets.sh +138 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"gate-report-registry.js","sourceRoot":"","sources":["../../src/cli/gate-report-registry.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAClC,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAExD,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;AAE/D,yDAAyD;AACzD,MAAM,iBAAiB,GAAG,IAAI,CAAC,IAAI,CACjC,KAAK,EACL,gBAAgB,EAChB,SAAS,EACT,gBAAgB,CACjB,CAAC;
|
|
1
|
+
{"version":3,"file":"gate-report-registry.js","sourceRoot":"","sources":["../../src/cli/gate-report-registry.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAClC,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAExD,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;AAE/D,yDAAyD;AACzD,MAAM,iBAAiB,GAAG,IAAI,CAAC,IAAI,CACjC,KAAK,EACL,gBAAgB,EAChB,SAAS,EACT,gBAAgB,CACjB,CAAC;AAqHF;;;;;GAKG;AACH,SAAS,kBAAkB,CACzB,QAAgB,EAChB,YAAoB;IAEpB,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,YAAY,CAAC,CAAC;IACpD,IAAI,UAAU,CAAC,SAAS,CAAC;QAAE,OAAO,SAAS,CAAC;IAC5C,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;IACtC,OAAO,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,kBAAkB,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC;AAC/E,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,uBAAuB;IACrC,MAAM,eAAe,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,iBAAiB,CAAC,CAAC;IAC5E,IAAI,UAAU,CAAC,eAAe,CAAC;QAAE,OAAO,eAAe,CAAC;IACxD,OAAO,kBAAkB,CAAC,SAAS,EAAE,iBAAiB,CAAC,CAAC;AAC1D,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,sBAAsB;IACpC,MAAM,QAAQ,GAAG,uBAAuB,EAAE,CAAC;IAC3C,IAAI,QAAQ,KAAK,IAAI;QAAE,OAAO,IAAI,CAAC;IACnC,6DAA6D;IAC7D,OAAO,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;AAChE,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,gBAAgB;IACpC,MAAM,MAAM,GAAG,uBAAuB,EAAE,CAAC;IACzC,IAAI,MAAM,KAAK,IAAI;QAAE,OAAO,IAAI,CAAC;IACjC,OAAO,CAAC,MAAM,MAAM,CAClB,aAAa,CAAC,MAAM,CAAC,CAAC,IAAI,CAC3B,CAAkC,CAAC;AACtC,CAAC;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,oBAAoB,CAClC,QAA4B,EAC5B,KAAoD;IAEpD,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,SAAS;QAAE,OAAO,IAAI,CAAC;IACvD,IAAI,QAAQ,CAAC,YAAY,KAAK,SAAS;QAAE,OAAO,IAAI,CAAC;IACrD,IAAI,CAAC;QACH,OAAO,QAAQ,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC;IACtC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC"}
|
|
@@ -14,7 +14,8 @@
|
|
|
14
14
|
* every count states its unknown band explicitly.
|
|
15
15
|
* @module cli/gate-report-types
|
|
16
16
|
*/
|
|
17
|
-
import type {
|
|
17
|
+
import type { DeclarationState } from "../core/gate-context-owners.js";
|
|
18
|
+
import type { DeclarationDriftReport } from "../core/gate-declaration-drift.js";
|
|
18
19
|
/** Report format version, bumped when a consumer would have to change. */
|
|
19
20
|
export declare const GATE_REPORT_VERSION = 2;
|
|
20
21
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"gate-report-types.d.ts","sourceRoot":"","sources":["../../src/cli/gate-report-types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"gate-report-types.d.ts","sourceRoot":"","sources":["../../src/cli/gate-report-types.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"gate-report-types.js","sourceRoot":"","sources":["../../src/cli/gate-report-types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;
|
|
1
|
+
{"version":3,"file":"gate-report-types.js","sourceRoot":"","sources":["../../src/cli/gate-report-types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAKH,0EAA0E;AAC1E,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,CAAC"}
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Which gate produces a required status context, and under which caller chain.
|
|
3
|
+
*
|
|
4
|
+
* Split out of `core/gate-declaration-drift` because it answers a different
|
|
5
|
+
* question. This module knows the shipped registry, the merge moment and the
|
|
6
|
+
* caller-chain rules, and produces one map from context string to owning gate.
|
|
7
|
+
* The comparator consumes that map as a `ReadonlyMap<string, ContextOwner>`
|
|
8
|
+
* and knows none of it. Nothing here reaches an enforcing surface or reasons
|
|
9
|
+
* about a verdict, so the two vocabularies the comparator's note warns about —
|
|
10
|
+
* the verdict table and the sentences explaining it — stay together over
|
|
11
|
+
* there, undisturbed by this seam.
|
|
12
|
+
*
|
|
13
|
+
* The one rule that lives here rather than in the comparator: a retired label
|
|
14
|
+
* some OTHER gate has since adopted as its current label is not retired. That
|
|
15
|
+
* string is posted again, by a different job, so requiring it is not a
|
|
16
|
+
* permanent wait — and telling an operator to delete it would be this check
|
|
17
|
+
* inventing a defect. The guard is why the map is built from the WHOLE
|
|
18
|
+
* registry rather than one entry's field.
|
|
19
|
+
* @module core/gate-context-owners
|
|
20
|
+
*/
|
|
21
|
+
/**
|
|
22
|
+
* What the settings file says about one gate at one moment.
|
|
23
|
+
*
|
|
24
|
+
* `off` and `not-declared` are deliberately separate. Collapsing them is what
|
|
25
|
+
* let a declaration govern nothing: the CI façade read both as
|
|
26
|
+
* `configured=false` and ran its built-in fallback, so `off` could not turn a
|
|
27
|
+
* job off.
|
|
28
|
+
*/
|
|
29
|
+
export type DeclarationState = "required" | "optional" | "off" | "not-declared";
|
|
30
|
+
/** The gate a context belongs to, and what the settings file says about it. */
|
|
31
|
+
export interface ContextOwner {
|
|
32
|
+
/** Registry gate id. */
|
|
33
|
+
readonly gateId: string;
|
|
34
|
+
/** The declaration at the merge moment. */
|
|
35
|
+
readonly declaration: DeclarationState;
|
|
36
|
+
/** Whether the registry permits declaring this gate at the merge moment. */
|
|
37
|
+
readonly legalAtMerge: boolean;
|
|
38
|
+
/**
|
|
39
|
+
* The rename this context is the losing half of, or null for a live name.
|
|
40
|
+
*
|
|
41
|
+
* Non-null means the gate exists and still runs — under a DIFFERENT name.
|
|
42
|
+
* The declaration is therefore irrelevant to the verdict: a gate declared
|
|
43
|
+
* `required` posts its current label, not this one, so requiring this string
|
|
44
|
+
* is a permanent wait however the gate is declared.
|
|
45
|
+
*/
|
|
46
|
+
readonly retired: RetiredRename | null;
|
|
47
|
+
}
|
|
48
|
+
/** One label the shipped registry records as renamed away. */
|
|
49
|
+
export interface RetiredRename {
|
|
50
|
+
/** The job label that no longer exists. */
|
|
51
|
+
readonly label: string;
|
|
52
|
+
/** The context the same gate posts today, spelled in full. */
|
|
53
|
+
readonly replacement: string;
|
|
54
|
+
}
|
|
55
|
+
/** The slice of the shipped registry this comparison reads. */
|
|
56
|
+
export interface MergeContextRegistry {
|
|
57
|
+
readonly REGISTRY: Readonly<Record<string, {
|
|
58
|
+
readonly label: string;
|
|
59
|
+
readonly moments: readonly string[];
|
|
60
|
+
/**
|
|
61
|
+
* Labels this gate's job used to post under, and no longer does.
|
|
62
|
+
*
|
|
63
|
+
* Optional because a consumer may hold an older copy of the shipped
|
|
64
|
+
* registry that predates the field. Absent reads as "this gate was
|
|
65
|
+
* never renamed" — which is what every registry before it meant, and
|
|
66
|
+
* which can only make this comparison report LESS, never a false
|
|
67
|
+
* defect.
|
|
68
|
+
*/
|
|
69
|
+
readonly previousLabels?: readonly string[];
|
|
70
|
+
}>>;
|
|
71
|
+
readonly resolveMoment: (options: {
|
|
72
|
+
gates: Record<string, unknown>;
|
|
73
|
+
moment: string;
|
|
74
|
+
includeOff?: boolean;
|
|
75
|
+
}) => readonly {
|
|
76
|
+
readonly id: string;
|
|
77
|
+
readonly level: string;
|
|
78
|
+
readonly mode: string;
|
|
79
|
+
readonly awaits: string | null;
|
|
80
|
+
/**
|
|
81
|
+
* The chain this declaration overrode the caller-wide one with, raw.
|
|
82
|
+
*
|
|
83
|
+
* Optional because a consumer may hold an older copy of the shipped
|
|
84
|
+
* registry that predates the field. Absent reads as "no override", which
|
|
85
|
+
* is what every registry before it meant.
|
|
86
|
+
*/
|
|
87
|
+
readonly callerChain?: readonly string[] | string | null;
|
|
88
|
+
}[];
|
|
89
|
+
readonly momentFamily: (moment: string) => string;
|
|
90
|
+
/**
|
|
91
|
+
* Join one declaration's own chain into the prefix its context carries.
|
|
92
|
+
*
|
|
93
|
+
* Optional for the same reason, and its absence is NOT a licence to join the
|
|
94
|
+
* chain here: a second implementation of the joining rule is how a rename
|
|
95
|
+
* lands in one derivation and not the other. Where it is absent, an override
|
|
96
|
+
* cannot be honoured, and the comparison says so rather than deriving the
|
|
97
|
+
* caller-wide name as though nothing had been declared.
|
|
98
|
+
*/
|
|
99
|
+
readonly callerPrefix?: (chain: readonly string[] | string) => string;
|
|
100
|
+
}
|
|
101
|
+
/** The moment a branch ruleset guards. */
|
|
102
|
+
export declare const MERGE_MOMENT = "pull-request";
|
|
103
|
+
/**
|
|
104
|
+
* Map every context a registry gate can produce to that gate.
|
|
105
|
+
*
|
|
106
|
+
* Built from the whole registry rather than from the declared gates, which is
|
|
107
|
+
* the difference between "protection requires a context whose gate nobody
|
|
108
|
+
* declared" and "protection requires a context Lisa knows nothing about". Those
|
|
109
|
+
* are different findings with different remedies, and a map built only from
|
|
110
|
+
* declarations could not tell them apart.
|
|
111
|
+
* @param options - Inputs
|
|
112
|
+
* @param options.registry - The shipped registry
|
|
113
|
+
* @param options.gates - The project's gates block
|
|
114
|
+
* @param options.workflowName - The workflow whose name prefixes a context
|
|
115
|
+
* @returns Context string to owning gate
|
|
116
|
+
*/
|
|
117
|
+
export declare function contextOwners(options: {
|
|
118
|
+
registry: MergeContextRegistry;
|
|
119
|
+
gates: Record<string, unknown>;
|
|
120
|
+
workflowName: string;
|
|
121
|
+
}): ReadonlyMap<string, ContextOwner>;
|
|
122
|
+
//# sourceMappingURL=gate-context-owners.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gate-context-owners.d.ts","sourceRoot":"","sources":["../../src/core/gate-context-owners.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH;;;;;;;GAOG;AACH,MAAM,MAAM,gBAAgB,GAAG,UAAU,GAAG,UAAU,GAAG,KAAK,GAAG,cAAc,CAAC;AAEhF,+EAA+E;AAC/E,MAAM,WAAW,YAAY;IAC3B,wBAAwB;IACxB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,2CAA2C;IAC3C,QAAQ,CAAC,WAAW,EAAE,gBAAgB,CAAC;IACvC,4EAA4E;IAC5E,QAAQ,CAAC,YAAY,EAAE,OAAO,CAAC;IAC/B;;;;;;;OAOG;IACH,QAAQ,CAAC,OAAO,EAAE,aAAa,GAAG,IAAI,CAAC;CACxC;AAED,8DAA8D;AAC9D,MAAM,WAAW,aAAa;IAC5B,2CAA2C;IAC3C,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,8DAA8D;IAC9D,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;CAC9B;AAED,+DAA+D;AAC/D,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CACzB,MAAM,CACJ,MAAM,EACN;QACE,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;QACvB,QAAQ,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;QACpC;;;;;;;;WAQG;QACH,QAAQ,CAAC,cAAc,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;KAC7C,CACF,CACF,CAAC;IACF,QAAQ,CAAC,aAAa,EAAE,CAAC,OAAO,EAAE;QAChC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QAC/B,MAAM,EAAE,MAAM,CAAC;QACf,UAAU,CAAC,EAAE,OAAO,CAAC;KACtB,KAAK,SAAS;QACb,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;QACpB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;QACvB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;QACtB,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;QAC/B;;;;;;WAMG;QACH,QAAQ,CAAC,WAAW,CAAC,EAAE,SAAS,MAAM,EAAE,GAAG,MAAM,GAAG,IAAI,CAAC;KAC1D,EAAE,CAAC;IACJ,QAAQ,CAAC,YAAY,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,MAAM,CAAC;IAClD;;;;;;;;OAQG;IACH,QAAQ,CAAC,YAAY,CAAC,EAAE,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,GAAG,MAAM,KAAK,MAAM,CAAC;CACvE;AAED,0CAA0C;AAC1C,eAAO,MAAM,YAAY,iBAAiB,CAAC;AAgB3C;;;;;;;;;;;;;GAaG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE;IACrC,QAAQ,EAAE,oBAAoB,CAAC;IAC/B,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC/B,YAAY,EAAE,MAAM,CAAC;CACtB,GAAG,WAAW,CAAC,MAAM,EAAE,YAAY,CAAC,CA0CpC"}
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Which gate produces a required status context, and under which caller chain.
|
|
3
|
+
*
|
|
4
|
+
* Split out of `core/gate-declaration-drift` because it answers a different
|
|
5
|
+
* question. This module knows the shipped registry, the merge moment and the
|
|
6
|
+
* caller-chain rules, and produces one map from context string to owning gate.
|
|
7
|
+
* The comparator consumes that map as a `ReadonlyMap<string, ContextOwner>`
|
|
8
|
+
* and knows none of it. Nothing here reaches an enforcing surface or reasons
|
|
9
|
+
* about a verdict, so the two vocabularies the comparator's note warns about —
|
|
10
|
+
* the verdict table and the sentences explaining it — stay together over
|
|
11
|
+
* there, undisturbed by this seam.
|
|
12
|
+
*
|
|
13
|
+
* The one rule that lives here rather than in the comparator: a retired label
|
|
14
|
+
* some OTHER gate has since adopted as its current label is not retired. That
|
|
15
|
+
* string is posted again, by a different job, so requiring it is not a
|
|
16
|
+
* permanent wait — and telling an operator to delete it would be this check
|
|
17
|
+
* inventing a defect. The guard is why the map is built from the WHOLE
|
|
18
|
+
* registry rather than one entry's field.
|
|
19
|
+
* @module core/gate-context-owners
|
|
20
|
+
*/
|
|
21
|
+
/** The moment a branch ruleset guards. */
|
|
22
|
+
export const MERGE_MOMENT = "pull-request";
|
|
23
|
+
/**
|
|
24
|
+
* The declaration state one resolved level names.
|
|
25
|
+
*
|
|
26
|
+
* Anything that is not one of the three levels is `not-declared`, because an
|
|
27
|
+
* unknown level is a typo rather than a claim.
|
|
28
|
+
* @param level - The resolved level
|
|
29
|
+
* @returns The declaration state
|
|
30
|
+
*/
|
|
31
|
+
function asDeclaration(level) {
|
|
32
|
+
return level === "required" || level === "optional" || level === "off"
|
|
33
|
+
? level
|
|
34
|
+
: "not-declared";
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Map every context a registry gate can produce to that gate.
|
|
38
|
+
*
|
|
39
|
+
* Built from the whole registry rather than from the declared gates, which is
|
|
40
|
+
* the difference between "protection requires a context whose gate nobody
|
|
41
|
+
* declared" and "protection requires a context Lisa knows nothing about". Those
|
|
42
|
+
* are different findings with different remedies, and a map built only from
|
|
43
|
+
* declarations could not tell them apart.
|
|
44
|
+
* @param options - Inputs
|
|
45
|
+
* @param options.registry - The shipped registry
|
|
46
|
+
* @param options.gates - The project's gates block
|
|
47
|
+
* @param options.workflowName - The workflow whose name prefixes a context
|
|
48
|
+
* @returns Context string to owning gate
|
|
49
|
+
*/
|
|
50
|
+
export function contextOwners(options) {
|
|
51
|
+
const { registry, gates, workflowName } = options;
|
|
52
|
+
const resolved = resolveMergeMoment(registry, gates);
|
|
53
|
+
const family = registry.momentFamily(MERGE_MOMENT);
|
|
54
|
+
const owners = Object.entries(registry.REGISTRY).map(([gateId, definition]) => {
|
|
55
|
+
const hit = resolved.get(gateId);
|
|
56
|
+
return [
|
|
57
|
+
`${prefixFor(registry, hit?.callerChain, workflowName)} / ${definition.label}`,
|
|
58
|
+
{
|
|
59
|
+
gateId,
|
|
60
|
+
declaration: asDeclaration(hit?.level),
|
|
61
|
+
legalAtMerge: definition.moments.includes(family),
|
|
62
|
+
retired: null,
|
|
63
|
+
},
|
|
64
|
+
];
|
|
65
|
+
});
|
|
66
|
+
const awaited = [...resolved.values()].flatMap(hit => hit.mode === "await" && hit.awaits !== null
|
|
67
|
+
? [
|
|
68
|
+
[
|
|
69
|
+
hit.awaits,
|
|
70
|
+
{
|
|
71
|
+
gateId: hit.id,
|
|
72
|
+
declaration: asDeclaration(hit.level),
|
|
73
|
+
legalAtMerge: registry.REGISTRY[hit.id]?.moments.includes(family) === true,
|
|
74
|
+
retired: null,
|
|
75
|
+
},
|
|
76
|
+
],
|
|
77
|
+
]
|
|
78
|
+
: []);
|
|
79
|
+
// Retired entries go FIRST so a later current-label or awaited entry always
|
|
80
|
+
// wins the key. The collision filter below already covers the reachable
|
|
81
|
+
// case; the ordering covers the one nobody thought of.
|
|
82
|
+
return new Map([
|
|
83
|
+
...retiredOwners(registry, resolved, workflowName, family),
|
|
84
|
+
...owners,
|
|
85
|
+
...awaited,
|
|
86
|
+
]);
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* The contexts the registry records as renamed away, keyed by their old name.
|
|
90
|
+
*
|
|
91
|
+
* Built from the whole registry — like the current-label map, and for the same
|
|
92
|
+
* reason. It is what separates "a required context nothing in Lisa produces"
|
|
93
|
+
* (which may be CodeRabbit, a Sonar status, a manual status, or a job the host
|
|
94
|
+
* repository's own CI defines, and is not a defect) from "a required context
|
|
95
|
+
* Lisa itself retired" (which no run can post, ever). Only the second is
|
|
96
|
+
* reportable, and only the second earns a removal remedy.
|
|
97
|
+
*
|
|
98
|
+
* A retired label some other gate has since adopted as its CURRENT label is
|
|
99
|
+
* skipped: that string is posted again, by a different job, so requiring it is
|
|
100
|
+
* not a permanent wait. Missing this would turn a legitimate requirement into
|
|
101
|
+
* a false "delete this" instruction.
|
|
102
|
+
* @param registry - The shipped registry
|
|
103
|
+
* @param resolved - The resolved merge moment, keyed by gate id
|
|
104
|
+
* @param workflowName - The caller chain that prefixes a run gate's context
|
|
105
|
+
* @param family - The merge moment's family
|
|
106
|
+
* @returns Retired context to owning gate
|
|
107
|
+
*/
|
|
108
|
+
function retiredOwners(registry, resolved, workflowName, family) {
|
|
109
|
+
const live = new Set(Object.values(registry.REGISTRY).map(definition => definition.label));
|
|
110
|
+
return Object.entries(registry.REGISTRY).flatMap(([gateId, definition]) => (definition.previousLabels ?? [])
|
|
111
|
+
.filter(label => !live.has(label))
|
|
112
|
+
.map((label) => [
|
|
113
|
+
`${workflowName} / ${label}`,
|
|
114
|
+
{
|
|
115
|
+
gateId,
|
|
116
|
+
declaration: asDeclaration(resolved.get(gateId)?.level),
|
|
117
|
+
legalAtMerge: definition.moments.includes(family),
|
|
118
|
+
retired: {
|
|
119
|
+
label,
|
|
120
|
+
replacement: `${workflowName} / ${definition.label}`,
|
|
121
|
+
},
|
|
122
|
+
},
|
|
123
|
+
]));
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* The prefix one gate's context carries, honouring a per-declaration override.
|
|
127
|
+
*
|
|
128
|
+
* Three states, and the third is the one that matters. No override means the
|
|
129
|
+
* caller-wide name, unchanged — which is what keeps every existing declaration
|
|
130
|
+
* deriving exactly what it derived before this field existed. An override with
|
|
131
|
+
* a registry able to join it means that gate's own chain. An override with a
|
|
132
|
+
* registry too old to join it is refused outright, because the alternative is
|
|
133
|
+
* to derive the caller-wide name for a gate whose declaration has just said
|
|
134
|
+
* that name is wrong — a comparison that would report a clean match against a
|
|
135
|
+
* context nothing posts.
|
|
136
|
+
* @param registry - The shipped registry
|
|
137
|
+
* @param chain - The declared override, when there is one
|
|
138
|
+
* @param workflowName - The caller-wide chain
|
|
139
|
+
* @returns The prefix
|
|
140
|
+
* @throws {Error} When an override cannot be joined
|
|
141
|
+
*/
|
|
142
|
+
function prefixFor(registry, chain, workflowName) {
|
|
143
|
+
if (chain === null || chain === undefined)
|
|
144
|
+
return workflowName;
|
|
145
|
+
if (registry.callerPrefix === undefined) {
|
|
146
|
+
throw new Error(`a gate declares its own caller chain (${JSON.stringify(chain)}), but ` +
|
|
147
|
+
`the installed copy of Lisa's check registry is too old to derive a ` +
|
|
148
|
+
`context from one. Update Lisa, or remove the override; deriving the ` +
|
|
149
|
+
`default name here would report agreement about a check that never ` +
|
|
150
|
+
`reports.`);
|
|
151
|
+
}
|
|
152
|
+
return registry.callerPrefix(chain);
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* Resolve the merge moment, treating a refusal as "nothing resolved".
|
|
156
|
+
*
|
|
157
|
+
* A refusal is never swallowed by the caller: `readTemplateEnforcement` and the
|
|
158
|
+
* health check both report the declaration problems separately. What must not
|
|
159
|
+
* happen here is a throw that turns a comparison into no comparison at all.
|
|
160
|
+
* @param registry - The shipped registry
|
|
161
|
+
* @param gates - The project's gates block
|
|
162
|
+
* @returns Resolved gates keyed by id
|
|
163
|
+
*/
|
|
164
|
+
function resolveMergeMoment(registry, gates) {
|
|
165
|
+
try {
|
|
166
|
+
return new Map(registry
|
|
167
|
+
.resolveMoment({ gates, moment: MERGE_MOMENT, includeOff: true })
|
|
168
|
+
.map(entry => [entry.id, { ...entry }]));
|
|
169
|
+
}
|
|
170
|
+
catch {
|
|
171
|
+
return new Map();
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
//# sourceMappingURL=gate-context-owners.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gate-context-owners.js","sourceRoot":"","sources":["../../src/core/gate-context-owners.ts"],"names":[],"mappings":"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"}
|
|
@@ -26,22 +26,34 @@
|
|
|
26
26
|
* "agreed and proved" from "agreed and unproved" would itself be a control
|
|
27
27
|
* reporting more than it measured, so the word this module uses is
|
|
28
28
|
* `matched` — the two surfaces agree — and never `enforced` or `proved`.
|
|
29
|
-
* 3. **
|
|
30
|
-
*
|
|
31
|
-
*
|
|
32
|
-
*
|
|
33
|
-
*
|
|
34
|
-
*
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
*
|
|
29
|
+
* 3. **A remedy may say "remove the context" only where Lisa renamed the job
|
|
30
|
+
* itself.** The original rule here was that no remedy could ever say it,
|
|
31
|
+
* and the reason was sound: third-party contexts are enforced by
|
|
32
|
+
* construction and declared by nobody, so a comparator free to propose a
|
|
33
|
+
* removal would eventually propose deleting one. That reason does not cover
|
|
34
|
+
* one case, and #3067 is what the gap costs. When the shipped registry
|
|
35
|
+
* carries a `previousLabels` entry, Lisa is not inferring that nothing owns
|
|
36
|
+
* a context — it is reading its OWN record that it renamed the job, which
|
|
37
|
+
* is proof that this exact string can never be posted again. A required
|
|
38
|
+
* context that never reports does not fail a pull request; GitHub waits for
|
|
39
|
+
* it forever, so leaving that unsaid red-walls the repository silently.
|
|
38
40
|
*
|
|
39
|
-
*
|
|
40
|
-
*
|
|
41
|
-
*
|
|
42
|
-
*
|
|
41
|
+
* The narrowing is structural, not conventional. Exactly one verdict,
|
|
42
|
+
* `enforced-context-retired`, maps to the single removal remedy, and that
|
|
43
|
+
* verdict is reachable only from a `previousLabels` match. A context with
|
|
44
|
+
* no owner at all is still `enforced-not-lisa-owned` with remedy `none`, so
|
|
45
|
+
* the original guarantee holds unchanged for every third-party check.
|
|
46
|
+
*
|
|
47
|
+
* The ownership map this comparison reads — which gate produces a context
|
|
48
|
+
* string, under which caller chain, and whether the registry records that
|
|
49
|
+
* name as renamed away — is built in `core/gate-context-owners`. That is a
|
|
50
|
+
* different question from the one here: it knows the registry and the chain
|
|
51
|
+
* rules and nothing about verdicts, and this module knows the verdicts and
|
|
52
|
+
* reads the map through `ReadonlyMap<string, ContextOwner>` without knowing
|
|
53
|
+
* how it was derived. The seam is the one the signatures already drew.
|
|
54
|
+
* @module core/gate-declaration-drift
|
|
43
55
|
*/
|
|
44
|
-
|
|
56
|
+
import { type ContextOwner, type DeclarationState } from "./gate-context-owners.js";
|
|
45
57
|
/** Which enforcing surface a comparison was made against. */
|
|
46
58
|
export type DriftSurface = "ruleset-templates" | "live-ruleset";
|
|
47
59
|
/**
|
|
@@ -62,13 +74,34 @@ export type DriftVerdict =
|
|
|
62
74
|
/** Enforced, and a registry gate produces it, but nothing declares it. */
|
|
63
75
|
| "enforced-undeclared"
|
|
64
76
|
/** Enforced, and no registry gate produces it — a third-party check. */
|
|
65
|
-
| "enforced-not-lisa-owned"
|
|
77
|
+
| "enforced-not-lisa-owned"
|
|
78
|
+
/**
|
|
79
|
+
* Enforced, and Lisa's own registry records that it RENAMED the job posting
|
|
80
|
+
* it, so nothing will ever post this name again.
|
|
81
|
+
*
|
|
82
|
+
* Not a failure and not a gap — an absence. GitHub holds a required context
|
|
83
|
+
* that never reports at "Expected — Waiting for status to be reported"
|
|
84
|
+
* indefinitely: no red tick, no log, `mergeable: MERGEABLE` with
|
|
85
|
+
* `mergeStateStatus: BLOCKED`, and every pull request in the repository
|
|
86
|
+
* red-walled with nothing naming the cause.
|
|
87
|
+
*/
|
|
88
|
+
| "enforced-context-retired";
|
|
66
89
|
/**
|
|
67
90
|
* What to do about one verdict.
|
|
68
91
|
*
|
|
69
92
|
* Deliberately closed, and deliberately without a removal. See the module note.
|
|
70
93
|
*/
|
|
71
|
-
export type DriftRemedy = "none" | "declare-the-gate" | "enforce-the-context" | "resolve-the-contradiction" | "decide-which-surface-wins"
|
|
94
|
+
export type DriftRemedy = "none" | "declare-the-gate" | "enforce-the-context" | "resolve-the-contradiction" | "decide-which-surface-wins"
|
|
95
|
+
/**
|
|
96
|
+
* The one removal in the vocabulary, and reachable from exactly one verdict.
|
|
97
|
+
*
|
|
98
|
+
* See the module note: it is not "this context looks unowned, drop it". It
|
|
99
|
+
* is "Lisa's registry records that Lisa renamed this job, so this exact
|
|
100
|
+
* string cannot be posted by anything, ever". A context with no owner at all
|
|
101
|
+
* never reaches this remedy — it is `enforced-not-lisa-owned`, whose remedy
|
|
102
|
+
* is still `none`.
|
|
103
|
+
*/
|
|
104
|
+
| "stop-requiring-the-retired-context";
|
|
72
105
|
/** One required status context, and where the requirement was read from. */
|
|
73
106
|
export interface EnforcedContext {
|
|
74
107
|
/** The context string, exactly as the ruleset spells it. */
|
|
@@ -82,15 +115,6 @@ export interface EnforcedContext {
|
|
|
82
115
|
*/
|
|
83
116
|
readonly source: string;
|
|
84
117
|
}
|
|
85
|
-
/** The gate a context belongs to, and what the settings file says about it. */
|
|
86
|
-
export interface ContextOwner {
|
|
87
|
-
/** Registry gate id. */
|
|
88
|
-
readonly gateId: string;
|
|
89
|
-
/** The declaration at the merge moment. */
|
|
90
|
-
readonly declaration: DeclarationState;
|
|
91
|
-
/** Whether the registry permits declaring this gate at the merge moment. */
|
|
92
|
-
readonly legalAtMerge: boolean;
|
|
93
|
-
}
|
|
94
118
|
/** One context, its verdict, and the evidence behind it. */
|
|
95
119
|
export interface DeclarationDriftEntry {
|
|
96
120
|
/** The context string. */
|
|
@@ -122,64 +146,17 @@ export interface DeclarationDriftReport {
|
|
|
122
146
|
readonly contradictions: number;
|
|
123
147
|
/** Entries whose verdict is a gap the declaration surface could close. */
|
|
124
148
|
readonly gaps: number;
|
|
125
|
-
}
|
|
126
|
-
/** The slice of the shipped registry this comparison reads. */
|
|
127
|
-
export interface MergeContextRegistry {
|
|
128
|
-
readonly REGISTRY: Readonly<Record<string, {
|
|
129
|
-
readonly label: string;
|
|
130
|
-
readonly moments: readonly string[];
|
|
131
|
-
}>>;
|
|
132
|
-
readonly resolveMoment: (options: {
|
|
133
|
-
gates: Record<string, unknown>;
|
|
134
|
-
moment: string;
|
|
135
|
-
includeOff?: boolean;
|
|
136
|
-
}) => readonly {
|
|
137
|
-
readonly id: string;
|
|
138
|
-
readonly level: string;
|
|
139
|
-
readonly mode: string;
|
|
140
|
-
readonly awaits: string | null;
|
|
141
|
-
/**
|
|
142
|
-
* The chain this declaration overrode the caller-wide one with, raw.
|
|
143
|
-
*
|
|
144
|
-
* Optional because a consumer may hold an older copy of the shipped
|
|
145
|
-
* registry that predates the field. Absent reads as "no override", which
|
|
146
|
-
* is what every registry before it meant.
|
|
147
|
-
*/
|
|
148
|
-
readonly callerChain?: readonly string[] | string | null;
|
|
149
|
-
}[];
|
|
150
|
-
readonly momentFamily: (moment: string) => string;
|
|
151
149
|
/**
|
|
152
|
-
*
|
|
150
|
+
* Entries the enforcing surface requires and nothing can post.
|
|
153
151
|
*
|
|
154
|
-
*
|
|
155
|
-
*
|
|
156
|
-
*
|
|
157
|
-
*
|
|
158
|
-
*
|
|
152
|
+
* Counted separately from `contradictions` and `gaps` because it is neither.
|
|
153
|
+
* A contradiction has two surfaces saying opposite things and a gap has one
|
|
154
|
+
* surface silent; this has one surface waiting on a name that no longer
|
|
155
|
+
* exists. Folding it into either bucket would give an operator the wrong
|
|
156
|
+
* remedy, and folding it into `gaps` would let it warn when it must fail.
|
|
159
157
|
*/
|
|
160
|
-
readonly
|
|
158
|
+
readonly unpostable: number;
|
|
161
159
|
}
|
|
162
|
-
/** The moment a branch ruleset guards. */
|
|
163
|
-
export declare const MERGE_MOMENT = "pull-request";
|
|
164
|
-
/**
|
|
165
|
-
* Map every context a registry gate can produce to that gate.
|
|
166
|
-
*
|
|
167
|
-
* Built from the whole registry rather than from the declared gates, which is
|
|
168
|
-
* the difference between "protection requires a context whose gate nobody
|
|
169
|
-
* declared" and "protection requires a context Lisa knows nothing about". Those
|
|
170
|
-
* are different findings with different remedies, and a map built only from
|
|
171
|
-
* declarations could not tell them apart.
|
|
172
|
-
* @param options - Inputs
|
|
173
|
-
* @param options.registry - The shipped registry
|
|
174
|
-
* @param options.gates - The project's gates block
|
|
175
|
-
* @param options.workflowName - The workflow whose name prefixes a context
|
|
176
|
-
* @returns Context string to owning gate
|
|
177
|
-
*/
|
|
178
|
-
export declare function contextOwners(options: {
|
|
179
|
-
registry: MergeContextRegistry;
|
|
180
|
-
gates: Record<string, unknown>;
|
|
181
|
-
workflowName: string;
|
|
182
|
-
}): ReadonlyMap<string, ContextOwner>;
|
|
183
160
|
/**
|
|
184
161
|
* The contexts a `required` declaration promises protection will require.
|
|
185
162
|
* @param owners - Context to owning gate
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"gate-declaration-drift.d.ts","sourceRoot":"","sources":["../../src/core/gate-declaration-drift.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"gate-declaration-drift.d.ts","sourceRoot":"","sources":["../../src/core/gate-declaration-drift.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsDG;AACH,OAAO,EAEL,KAAK,YAAY,EACjB,KAAK,gBAAgB,EAEtB,MAAM,0BAA0B,CAAC;AAElC,6DAA6D;AAC7D,MAAM,MAAM,YAAY,GAAG,mBAAmB,GAAG,cAAc,CAAC;AAEhE;;;;;GAKG;AACH,MAAM,MAAM,YAAY;AACtB,kEAAkE;AAChE,SAAS;AACX,yEAAyE;GACvE,uBAAuB;AACzB,uDAAuD;GACrD,4BAA4B;AAC9B,yEAAyE;GACvE,uBAAuB;AACzB,0EAA0E;GACxE,qBAAqB;AACvB,wEAAwE;GACtE,yBAAyB;AAC3B;;;;;;;;;GASG;GACD,0BAA0B,CAAC;AAE/B;;;;GAIG;AACH,MAAM,MAAM,WAAW,GACnB,MAAM,GACN,kBAAkB,GAClB,qBAAqB,GACrB,2BAA2B,GAC3B,2BAA2B;AAC7B;;;;;;;;GAQG;GACD,oCAAoC,CAAC;AAEzC,4EAA4E;AAC5E,MAAM,WAAW,eAAe;IAC9B,4DAA4D;IAC5D,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,gCAAgC;IAChC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB;;;;OAIG;IACH,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACzB;AAED,4DAA4D;AAC5D,MAAM,WAAW,qBAAqB;IACpC,0BAA0B;IAC1B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,mBAAmB;IACnB,QAAQ,CAAC,OAAO,EAAE,YAAY,CAAC;IAC/B,0DAA0D;IAC1D,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAC;IAC7B,+DAA+D;IAC/D,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,0EAA0E;IAC1E,QAAQ,CAAC,WAAW,EAAE,gBAAgB,GAAG,IAAI,CAAC;IAC9C,yEAAyE;IACzE,QAAQ,CAAC,QAAQ,EAAE,SAAS,MAAM,EAAE,CAAC;IACrC,mDAAmD;IACnD,QAAQ,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;IACpC,sCAAsC;IACtC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACzB;AAED,0DAA0D;AAC1D,MAAM,WAAW,sBAAsB;IACrC,wDAAwD;IACxD,QAAQ,CAAC,OAAO,EAAE,YAAY,CAAC;IAC/B,gDAAgD;IAChD,QAAQ,CAAC,OAAO,EAAE,SAAS,qBAAqB,EAAE,CAAC;IACnD,iEAAiE;IACjE,QAAQ,CAAC,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC,YAAY,EAAE,MAAM,CAAC,CAAC,CAAC;IACxD,kEAAkE;IAClE,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAChC,0EAA0E;IAC1E,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB;;;;;;;;OAQG;IACH,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;CAC7B;AAyDD;;;;GAIG;AACH,wBAAgB,wBAAwB,CACtC,MAAM,EAAE,WAAW,CAAC,MAAM,EAAE,YAAY,CAAC,GACxC,SAAS,MAAM,EAAE,CAcnB;AAsGD;;;;;;;;;;;;;GAaG;AACH,wBAAgB,wBAAwB,CAAC,OAAO,EAAE;IAChD,OAAO,EAAE,YAAY,CAAC;IACtB,MAAM,EAAE,WAAW,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC;IAC1C,QAAQ,EAAE,SAAS,eAAe,EAAE,CAAC;CACtC,GAAG,sBAAsB,CAoEzB"}
|