@codyswann/lisa 2.279.2 → 2.280.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.
- package/dist/cli/doctor-readiness-audit-allowlist.d.ts +7 -0
- package/dist/cli/doctor-readiness-audit-allowlist.d.ts.map +1 -0
- package/dist/cli/doctor-readiness-audit-allowlist.js +177 -0
- package/dist/cli/doctor-readiness-audit-allowlist.js.map +1 -0
- package/dist/cli/doctor-readiness-context-claims.d.ts +14 -0
- package/dist/cli/doctor-readiness-context-claims.d.ts.map +1 -0
- package/dist/cli/doctor-readiness-context-claims.js +117 -0
- package/dist/cli/doctor-readiness-context-claims.js.map +1 -0
- package/dist/cli/doctor-readiness-context-mechanisms.d.ts +46 -0
- package/dist/cli/doctor-readiness-context-mechanisms.d.ts.map +1 -0
- package/dist/cli/doctor-readiness-context-mechanisms.js +116 -0
- package/dist/cli/doctor-readiness-context-mechanisms.js.map +1 -0
- package/dist/cli/doctor-readiness-context.d.ts +16 -0
- package/dist/cli/doctor-readiness-context.d.ts.map +1 -0
- package/dist/cli/doctor-readiness-context.js +244 -0
- package/dist/cli/doctor-readiness-context.js.map +1 -0
- package/dist/cli/doctor-readiness-delivery.d.ts.map +1 -1
- package/dist/cli/doctor-readiness-delivery.js +1 -10
- package/dist/cli/doctor-readiness-delivery.js.map +1 -1
- package/dist/cli/doctor-readiness-shared.d.ts +47 -0
- package/dist/cli/doctor-readiness-shared.d.ts.map +1 -0
- package/dist/cli/doctor-readiness-shared.js +88 -0
- package/dist/cli/doctor-readiness-shared.js.map +1 -0
- package/dist/cli/doctor-readiness-supply-chain-scan.d.ts +67 -0
- package/dist/cli/doctor-readiness-supply-chain-scan.d.ts.map +1 -0
- package/dist/cli/doctor-readiness-supply-chain-scan.js +316 -0
- package/dist/cli/doctor-readiness-supply-chain-scan.js.map +1 -0
- package/dist/cli/doctor-readiness-supply-chain.d.ts +14 -0
- package/dist/cli/doctor-readiness-supply-chain.d.ts.map +1 -0
- package/dist/cli/doctor-readiness-supply-chain.js +231 -0
- package/dist/cli/doctor-readiness-supply-chain.js.map +1 -0
- package/dist/cli/doctor-readiness-workspaces.d.ts +22 -0
- package/dist/cli/doctor-readiness-workspaces.d.ts.map +1 -0
- package/dist/cli/doctor-readiness-workspaces.js +98 -0
- package/dist/cli/doctor-readiness-workspaces.js.map +1 -0
- package/dist/cli/doctor-readiness.d.ts.map +1 -1
- package/dist/cli/doctor-readiness.js +7 -3
- package/dist/cli/doctor-readiness.js.map +1 -1
- package/dist/core/upstream-evidence-manifest.d.ts.map +1 -1
- package/dist/core/upstream-evidence-manifest.js +13 -0
- package/dist/core/upstream-evidence-manifest.js.map +1 -1
- 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-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-cursor/.claude-plugin/plugin.json +1 -1
- 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
|
@@ -0,0 +1,244 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The context-routing readiness producer — ship blocker B6 (PRD #1739, #1896).
|
|
3
|
+
*
|
|
4
|
+
* Dimension 1 of the `readiness-rubric` asks whether an agent can recover the
|
|
5
|
+
* real job from what is written down. Blocker B6 asks the sharper half of that:
|
|
6
|
+
* does the written word claim only what something actually enforces? An agent
|
|
7
|
+
* that reads "the pre-commit hook always runs the tests" stops verifying, so a
|
|
8
|
+
* documented guarantee with no mechanism behind it is worse than silence.
|
|
9
|
+
*
|
|
10
|
+
* Cross-checking prose against machinery is false-positive-prone, and a standing
|
|
11
|
+
* B6 is not a soft signal: the blocker engine reads a finding's `blocker` id and
|
|
12
|
+
* evidence and never reads its status, so a `WARN` finding naming B6 flips the
|
|
13
|
+
* whole repository to `NOT_READY` exactly as a `FAIL` one would. The `WARN`
|
|
14
|
+
* status communicates confidence to a human reader; it does NOT soften the
|
|
15
|
+
* verdict. **Precision is the only real defense**, which is why three
|
|
16
|
+
* disciplines are load-bearing here:
|
|
17
|
+
*
|
|
18
|
+
* 1. **Only a provable, high-confidence overstatement stands the blocker.** A
|
|
19
|
+
* claim is faulted only when the sentence names an in-repository mechanism
|
|
20
|
+
* that survives `classifyMechanism` and still does not exist. Package names,
|
|
21
|
+
* `org/repo` slugs, git refs, and generated artifacts are classified
|
|
22
|
+
* `unmappable` rather than missing.
|
|
23
|
+
* 2. **Anything short of that is an observation, never a blocker.** A claim with
|
|
24
|
+
* no resolvable mechanism, one inside a code fence, or a hedged sentence is
|
|
25
|
+
* surfaced as a non-blocking finding — never guessed into a violation, and
|
|
26
|
+
* never dropped into silence.
|
|
27
|
+
* 3. **A clean finding carries no `blocker` key.** A PASS finding that named B6
|
|
28
|
+
* would report a healthy repository as NOT_READY.
|
|
29
|
+
* @module cli/doctor-readiness-context
|
|
30
|
+
*/
|
|
31
|
+
import { collectClaims, } from "./doctor-readiness-context-claims.js";
|
|
32
|
+
import { classifyMechanism, loadIgnoreMatcher, } from "./doctor-readiness-context-mechanisms.js";
|
|
33
|
+
import { informationalFindings, readFileOrNull, } from "./doctor-readiness-shared.js";
|
|
34
|
+
/** The context-routing readiness dimension id (readiness-rubric, RRR-1). */
|
|
35
|
+
export const CONTEXT_ROUTING_DIMENSION_ID = "context-routing";
|
|
36
|
+
/** The ship blocker for documentation that overstates enforced guarantees. */
|
|
37
|
+
const CONTEXT_BLOCKER_ID = "B6";
|
|
38
|
+
/** Most claim lines carried into one finding, to keep the report readable. */
|
|
39
|
+
const MAX_EVIDENCE_LINES = 10;
|
|
40
|
+
/** Longest quoted claim carried into persisted evidence. */
|
|
41
|
+
const MAX_QUOTE_LENGTH = 160;
|
|
42
|
+
/**
|
|
43
|
+
* Shorten a quoted claim so persisted evidence stays readable.
|
|
44
|
+
* @param text - The raw claim line
|
|
45
|
+
* @returns The claim, truncated to {@link MAX_QUOTE_LENGTH}
|
|
46
|
+
*/
|
|
47
|
+
function quoteClaim(text) {
|
|
48
|
+
return text.length > MAX_QUOTE_LENGTH
|
|
49
|
+
? `${text.slice(0, MAX_QUOTE_LENGTH).trimEnd()}…`
|
|
50
|
+
: text;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Cross-check one claim against the mechanisms it names.
|
|
54
|
+
*
|
|
55
|
+
* The claim becomes a violation only when at least one named mechanism is
|
|
56
|
+
* classified `missing` — provably absent AND provably a path this repository
|
|
57
|
+
* would own. Every other outcome is an observation, because a blocker built on
|
|
58
|
+
* a token that might be a package name or a git ref would flip a healthy
|
|
59
|
+
* repository to NOT_READY.
|
|
60
|
+
* @param root - Repository root
|
|
61
|
+
* @param claim - The claim to check
|
|
62
|
+
* @param isIgnored - The repository's ignore matcher
|
|
63
|
+
* @returns Either a violation line, an unmappable line, or neither
|
|
64
|
+
*/
|
|
65
|
+
async function auditOneClaim(root, claim, isIgnored) {
|
|
66
|
+
const verdicts = await Promise.all(claim.mechanisms.map(async (mechanism) => ({
|
|
67
|
+
mechanism,
|
|
68
|
+
verdict: await classifyMechanism(root, mechanism, isIgnored),
|
|
69
|
+
})));
|
|
70
|
+
const missing = verdicts
|
|
71
|
+
.filter(entry => entry.verdict === "missing")
|
|
72
|
+
.map(entry => entry.mechanism);
|
|
73
|
+
if (missing.length > 0) {
|
|
74
|
+
const named = missing.map(entry => `\`${entry}\``).join(", ");
|
|
75
|
+
return {
|
|
76
|
+
violation: `\`${claim.file}\` line ${claim.line} claims enforcement by ` +
|
|
77
|
+
`${named}, which does not exist in this repository: ` +
|
|
78
|
+
`"${quoteClaim(claim.text)}"`,
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
if (verdicts.some(entry => entry.verdict === "present")) {
|
|
82
|
+
return {};
|
|
83
|
+
}
|
|
84
|
+
return {
|
|
85
|
+
unmappable: `\`${claim.file}\` line ${claim.line} states a guarantee but names ` +
|
|
86
|
+
`no mechanism this check can resolve to a repository path, so it was ` +
|
|
87
|
+
`not assessed: "${quoteClaim(claim.text)}"`,
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Cross-check every claim against the mechanism it names.
|
|
92
|
+
* @param root - Repository root
|
|
93
|
+
* @param claims - The claims read from the instruction surfaces
|
|
94
|
+
* @returns Evidence lines for overstatements, and unmappable-claim notes
|
|
95
|
+
*/
|
|
96
|
+
async function auditClaims(root, claims) {
|
|
97
|
+
const isIgnored = await loadIgnoreMatcher(root);
|
|
98
|
+
const audited = await Promise.all(claims.map(async (claim) => await auditOneClaim(root, claim, isIgnored)));
|
|
99
|
+
return {
|
|
100
|
+
violations: audited.flatMap(entry => entry.violation === undefined ? [] : [entry.violation]),
|
|
101
|
+
unmappable: audited.flatMap(entry => entry.unmappable === undefined ? [] : [entry.unmappable]),
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Establish which of the four positive context-routing artifacts are present: a
|
|
106
|
+
* canonical `AGENTS.md`, a `CLAUDE.md` pointing at it, a parseable
|
|
107
|
+
* `.lisa.config.json`, and a wiki index.
|
|
108
|
+
* @param root - Repository root
|
|
109
|
+
* @returns The present and missing artifact descriptions
|
|
110
|
+
*/
|
|
111
|
+
async function inspectRoutingArtifacts(root) {
|
|
112
|
+
const agents = await readFileOrNull(root, "AGENTS.md");
|
|
113
|
+
const claude = await readFileOrNull(root, "CLAUDE.md");
|
|
114
|
+
const config = await readFileOrNull(root, ".lisa.config.json");
|
|
115
|
+
const wiki = await readFileOrNull(root, "wiki/index.md");
|
|
116
|
+
const checks = [
|
|
117
|
+
[agents !== null && agents.trim() !== "", "a canonical `AGENTS.md`"],
|
|
118
|
+
[
|
|
119
|
+
claude !== null && claude.includes("AGENTS.md"),
|
|
120
|
+
"a `CLAUDE.md` pointer to `AGENTS.md`",
|
|
121
|
+
],
|
|
122
|
+
[
|
|
123
|
+
config !== null && isParseableJson(config),
|
|
124
|
+
"a parseable `.lisa.config.json`",
|
|
125
|
+
],
|
|
126
|
+
[wiki !== null, "a `wiki/index.md` knowledge index"],
|
|
127
|
+
];
|
|
128
|
+
return {
|
|
129
|
+
present: checks.flatMap(([ok, label]) => (ok ? [label] : [])),
|
|
130
|
+
missing: checks.flatMap(([ok, label]) => (ok ? [] : [label])),
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* Whether a string parses as JSON.
|
|
135
|
+
* @param source - Candidate JSON text
|
|
136
|
+
* @returns True when it parses
|
|
137
|
+
*/
|
|
138
|
+
function isParseableJson(source) {
|
|
139
|
+
try {
|
|
140
|
+
JSON.parse(source);
|
|
141
|
+
return true;
|
|
142
|
+
}
|
|
143
|
+
catch {
|
|
144
|
+
return false;
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* Build the rubric-shaped B6 finding from its evidence lines.
|
|
149
|
+
* @param violations - Evidence lines
|
|
150
|
+
* @returns The B6 finding
|
|
151
|
+
*/
|
|
152
|
+
function contextFinding(violations) {
|
|
153
|
+
const shown = violations.slice(0, MAX_EVIDENCE_LINES);
|
|
154
|
+
const overflow = violations.length - shown.length;
|
|
155
|
+
return {
|
|
156
|
+
blocker: CONTEXT_BLOCKER_ID,
|
|
157
|
+
invariant_violated: "the written word claims only what something actually enforces",
|
|
158
|
+
evidence: shown.join(" | ") +
|
|
159
|
+
(overflow > 0
|
|
160
|
+
? ` | (+${overflow} further overstatement(s) of the same kind)`
|
|
161
|
+
: ""),
|
|
162
|
+
why_proof_missed: "documentation is never executed, so no test, lint rule, or review step " +
|
|
163
|
+
"ever observes that the guarantee it promises has no mechanism behind it " +
|
|
164
|
+
"— and an agent that reads the promise stops checking for itself",
|
|
165
|
+
root_correction: "either build the mechanism the sentence names, or rewrite the sentence " +
|
|
166
|
+
"to describe what is actually enforced, so the written word and the " +
|
|
167
|
+
"machinery say the same thing",
|
|
168
|
+
machinery_to_remove: [
|
|
169
|
+
"documented guarantees with no mechanism behind them, which cost trust " +
|
|
170
|
+
"every time an agent relies on one",
|
|
171
|
+
],
|
|
172
|
+
};
|
|
173
|
+
}
|
|
174
|
+
/**
|
|
175
|
+
* Build the stated-reason SKIP for a repository whose context routing cannot be
|
|
176
|
+
* established: nothing overstated, but not enough written down to call it clean.
|
|
177
|
+
* @param artifacts - Which routing artifacts are present and missing
|
|
178
|
+
* @param unmappable - Claims that named no resolvable mechanism
|
|
179
|
+
* @returns The SKIP dimension record
|
|
180
|
+
*/
|
|
181
|
+
function skipRecord(artifacts, unmappable) {
|
|
182
|
+
return {
|
|
183
|
+
id: CONTEXT_ROUTING_DIMENSION_ID,
|
|
184
|
+
status: "SKIP",
|
|
185
|
+
findings: [
|
|
186
|
+
{
|
|
187
|
+
reason: "no documented guarantee was found to overstate anything, but this " +
|
|
188
|
+
"repository is missing " +
|
|
189
|
+
`${artifacts.missing.join(", ")}, so whether an agent can recover the ` +
|
|
190
|
+
"real job from what is written down is not established either way",
|
|
191
|
+
skip: true,
|
|
192
|
+
},
|
|
193
|
+
...informationalFindings(unmappable),
|
|
194
|
+
],
|
|
195
|
+
};
|
|
196
|
+
}
|
|
197
|
+
/**
|
|
198
|
+
* Assess the context-routing dimension: B6, "documentation overstates enforced
|
|
199
|
+
* guarantees". Offline by construction — it reads only the repository's own
|
|
200
|
+
* instruction surfaces and the paths they name — and high-precision by design:
|
|
201
|
+
* it stands B6 only on a named mechanism that survives {@link classifyMechanism}
|
|
202
|
+
* and still demonstrably does not exist. The record's status is `WARN` rather
|
|
203
|
+
* than `FAIL`, but that is a confidence signal to a human reader only: a
|
|
204
|
+
* standing B6 blocker flips the repository to `NOT_READY` either way.
|
|
205
|
+
* @param root - Project root to assess
|
|
206
|
+
* @returns The context-routing dimension record
|
|
207
|
+
*/
|
|
208
|
+
export async function assessContextRoutingDimension(root) {
|
|
209
|
+
const claims = await collectClaims(root);
|
|
210
|
+
const { violations, unmappable } = await auditClaims(root, claims);
|
|
211
|
+
const artifacts = await inspectRoutingArtifacts(root);
|
|
212
|
+
if (violations.length > 0) {
|
|
213
|
+
return {
|
|
214
|
+
id: CONTEXT_ROUTING_DIMENSION_ID,
|
|
215
|
+
// `WARN` reports how much confidence an offline prose cross-check can
|
|
216
|
+
// carry — it does NOT soften the verdict. The blocker engine never reads
|
|
217
|
+
// this status, so the finding below flips the repository to `NOT_READY`
|
|
218
|
+
// exactly as a `FAIL` would; precision is what keeps that honest.
|
|
219
|
+
status: "WARN",
|
|
220
|
+
findings: [
|
|
221
|
+
contextFinding(violations),
|
|
222
|
+
...informationalFindings(unmappable),
|
|
223
|
+
],
|
|
224
|
+
};
|
|
225
|
+
}
|
|
226
|
+
if (artifacts.missing.length > 0) {
|
|
227
|
+
return skipRecord(artifacts, unmappable);
|
|
228
|
+
}
|
|
229
|
+
return {
|
|
230
|
+
id: CONTEXT_ROUTING_DIMENSION_ID,
|
|
231
|
+
status: "PASS",
|
|
232
|
+
findings: [
|
|
233
|
+
{
|
|
234
|
+
evidence: `Cross-checked ${claims.length} documented guarantee(s) across this ` +
|
|
235
|
+
"repository's instruction surfaces: every one that names a mechanism " +
|
|
236
|
+
`names one that exists. Context routing is carried by ` +
|
|
237
|
+
`${artifacts.present.join(", ")}.`,
|
|
238
|
+
checked: [CONTEXT_BLOCKER_ID],
|
|
239
|
+
},
|
|
240
|
+
...informationalFindings(unmappable),
|
|
241
|
+
],
|
|
242
|
+
};
|
|
243
|
+
}
|
|
244
|
+
//# sourceMappingURL=doctor-readiness-context.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"doctor-readiness-context.js","sourceRoot":"","sources":["../../src/cli/doctor-readiness-context.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"doctor-readiness-delivery.d.ts","sourceRoot":"","sources":["../../src/cli/doctor-readiness-delivery.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"doctor-readiness-delivery.d.ts","sourceRoot":"","sources":["../../src/cli/doctor-readiness-delivery.ts"],"names":[],"mappings":"AAoCA,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,6BAA6B,CAAC;AAC5E,OAAO,EACL,KAAK,cAAc,EAEpB,MAAM,iCAAiC,CAAC;AAEzC,+EAA+E;AAC/E,eAAO,MAAM,+BAA+B,uBAAuB,CAAC;AAmOpE;;;;;;;;;GASG;AACH,wBAAsB,gCAAgC,CACpD,IAAI,EAAE,MAAM,EACZ,eAAe,CAAC,EAAE,SAAS,cAAc,EAAE,GAC1C,OAAO,CAAC,wBAAwB,CAAC,CAiBnC"}
|
|
@@ -25,6 +25,7 @@
|
|
|
25
25
|
* @module cli/doctor-readiness-delivery
|
|
26
26
|
*/
|
|
27
27
|
import { detectCredentialFindings, } from "./doctor-readiness-credentials.js";
|
|
28
|
+
import { informationalFindings } from "./doctor-readiness-shared.js";
|
|
28
29
|
import { assessReleasePath, PROMOTION_ACTION, } from "./doctor-readiness-release-path.js";
|
|
29
30
|
import { parseRepositoryWorkflows, } from "./doctor-readiness-workflows.js";
|
|
30
31
|
/** The delivery/authority readiness dimension id (readiness-rubric, RRR-1). */
|
|
@@ -93,16 +94,6 @@ function credentialFinding(violations) {
|
|
|
93
94
|
],
|
|
94
95
|
};
|
|
95
96
|
}
|
|
96
|
-
/**
|
|
97
|
-
* Wrap non-blocking observations as findings. They deliberately carry no
|
|
98
|
-
* `blocker` key: naming one would stand a blocker up on an observation that was
|
|
99
|
-
* never decidable offline.
|
|
100
|
-
* @param notes - Informational lines
|
|
101
|
-
* @returns Findings, one per note
|
|
102
|
-
*/
|
|
103
|
-
function informationalFindings(notes) {
|
|
104
|
-
return notes.map(note => ({ observation: note, blocking: false }));
|
|
105
|
-
}
|
|
106
97
|
/**
|
|
107
98
|
* Build the SKIP record for a repository whose release paths could not be
|
|
108
99
|
* settled from the workflow files alone.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"doctor-readiness-delivery.js","sourceRoot":"","sources":["../../src/cli/doctor-readiness-delivery.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,OAAO,EAEL,wBAAwB,GACzB,MAAM,mCAAmC,CAAC;AAC3C,OAAO,EACL,iBAAiB,EACjB,gBAAgB,GAEjB,MAAM,oCAAoC,CAAC;AAE5C,OAAO,EAEL,wBAAwB,GACzB,MAAM,iCAAiC,CAAC;AAEzC,+EAA+E;AAC/E,MAAM,CAAC,MAAM,+BAA+B,GAAG,oBAAoB,CAAC;AAEpE,gFAAgF;AAChF,MAAM,kBAAkB,GAAG,IAAI,CAAC;AAEhC,+EAA+E;AAC/E,MAAM,qBAAqB,GAAG,IAAI,CAAC;AAUnC;;;;GAIG;AACH,SAAS,qBAAqB,CAC5B,SAAoC;IAEpC,MAAM,QAAQ,GAAkC,SAAS,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,CAC3E,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE;QAC1B,MAAM,OAAO,GAAG,iBAAiB,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC;QACjD,OAAO,OAAO,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IAClC,CAAC,CAAC,CACH,CAAC;IACF,OAAO;QACL,UAAU,EAAE,QAAQ,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CACrC,OAAO,CAAC,IAAI,KAAK,WAAW,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,EAAE,CACvD;QACD,UAAU,EAAE,QAAQ,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CACrC,OAAO,CAAC,IAAI,KAAK,YAAY,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,CACtD;QACD,UAAU,EAAE,QAAQ,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC,OAAO,CAAC,IAAI,KAAK,OAAO,CAAC,CAAC,MAAM;QACvE,eAAe,EAAE,QAAQ,CAAC,MAAM;KACjC,CAAC;AACJ,CAAC;AAED;;;;GAIG;AACH,SAAS,cAAc,CACrB,UAA6B;IAE7B,OAAO;QACL,OAAO,EAAE,kBAAkB;QAC3B,kBAAkB,EAChB,2EAA2E;QAC7E,QAAQ,EAAE,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC;QAChC,gBAAgB,EACd,wEAAwE;YACxE,uEAAuE;YACvE,iDAAiD;QACnD,eAAe,EACb,yEAAyE;YACzE,6BAA6B,gBAAgB,6BAA6B;YAC1E,kCAAkC;QACpC,mBAAmB,EAAE;YACnB,yEAAyE;gBACvE,4CAA4C;SAC/C;KACF,CAAC;AACJ,CAAC;AAED;;;;GAIG;AACH,SAAS,iBAAiB,CACxB,UAA6B;IAE7B,OAAO;QACL,OAAO,EAAE,qBAAqB;QAC9B,kBAAkB,EAChB,wEAAwE;QAC1E,QAAQ,EAAE,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC;QAChC,gBAAgB,EACd,0EAA0E;YAC1E,2DAA2D;QAC7D,eAAe,EACb,2EAA2E;YAC3E,2EAA2E;YAC3E,wBAAwB;QAC1B,mBAAmB,EAAE;YACnB,yEAAyE;gBACvE,6BAA6B;SAChC;KACF,CAAC;AACJ,CAAC;AAED;;;;;;GAMG;AACH,SAAS,
|
|
1
|
+
{"version":3,"file":"doctor-readiness-delivery.js","sourceRoot":"","sources":["../../src/cli/doctor-readiness-delivery.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Read a repository-relative file, returning null when it cannot be read.
|
|
3
|
+
*
|
|
4
|
+
* Reading is best-effort by design: a file that cannot be read establishes
|
|
5
|
+
* nothing, and a readiness producer must never turn "could not look" into
|
|
6
|
+
* either a violation or a clean bill of health.
|
|
7
|
+
* @param root - Repository root
|
|
8
|
+
* @param relativePath - Repo-relative path (forward slashes)
|
|
9
|
+
* @returns File contents, or null
|
|
10
|
+
*/
|
|
11
|
+
export declare function readFileOrNull(root: string, relativePath: string): Promise<string | null>;
|
|
12
|
+
/**
|
|
13
|
+
* Whether a repository-relative directory exists.
|
|
14
|
+
* @param root - Repository root
|
|
15
|
+
* @param relativePath - Repo-relative directory path
|
|
16
|
+
* @returns True when the directory could be listed
|
|
17
|
+
*/
|
|
18
|
+
export declare function directoryExists(root: string, relativePath: string): Promise<boolean>;
|
|
19
|
+
/**
|
|
20
|
+
* Whether a repository-relative path exists, as a file or a directory.
|
|
21
|
+
* @param root - Repository root
|
|
22
|
+
* @param relativePath - Repo-relative path
|
|
23
|
+
* @returns True when something is present at that path
|
|
24
|
+
*/
|
|
25
|
+
export declare function pathExists(root: string, relativePath: string): Promise<boolean>;
|
|
26
|
+
/**
|
|
27
|
+
* Strip leading and trailing slashes from a repo-relative path fragment.
|
|
28
|
+
* Written without a regex quantifier so it cannot backtrack on hostile input.
|
|
29
|
+
* @param value - The path fragment
|
|
30
|
+
* @returns The fragment with empty segments removed
|
|
31
|
+
*/
|
|
32
|
+
export declare function trimSlashes(value: string): string;
|
|
33
|
+
/**
|
|
34
|
+
* Whether a value is a plain JSON object.
|
|
35
|
+
* @param value - Candidate value
|
|
36
|
+
* @returns True when the value is a non-null, non-array object
|
|
37
|
+
*/
|
|
38
|
+
export declare function isRecord(value: unknown): value is Record<string, unknown>;
|
|
39
|
+
/**
|
|
40
|
+
* Wrap non-blocking observations as findings. They deliberately carry no
|
|
41
|
+
* `blocker` key: naming one would stand a blocker up — and flip the whole
|
|
42
|
+
* repository to `NOT_READY` — on an observation that was never decidable.
|
|
43
|
+
* @param notes - Informational lines
|
|
44
|
+
* @returns Findings, one per note
|
|
45
|
+
*/
|
|
46
|
+
export declare function informationalFindings(notes: readonly string[]): readonly Record<string, unknown>[];
|
|
47
|
+
//# sourceMappingURL=doctor-readiness-shared.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"doctor-readiness-shared.d.ts","sourceRoot":"","sources":["../../src/cli/doctor-readiness-shared.ts"],"names":[],"mappings":"AAeA;;;;;;;;;GASG;AACH,wBAAsB,cAAc,CAClC,IAAI,EAAE,MAAM,EACZ,YAAY,EAAE,MAAM,GACnB,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAMxB;AAED;;;;;GAKG;AACH,wBAAsB,eAAe,CACnC,IAAI,EAAE,MAAM,EACZ,YAAY,EAAE,MAAM,GACnB,OAAO,CAAC,OAAO,CAAC,CAOlB;AAED;;;;;GAKG;AACH,wBAAsB,UAAU,CAC9B,IAAI,EAAE,MAAM,EACZ,YAAY,EAAE,MAAM,GACnB,OAAO,CAAC,OAAO,CAAC,CAKlB;AAED;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAKjD;AAED;;;;GAIG;AACH,wBAAgB,QAAQ,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAEzE;AAED;;;;;;GAMG;AACH,wBAAgB,qBAAqB,CACnC,KAAK,EAAE,SAAS,MAAM,EAAE,GACvB,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAEpC"}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Helpers shared by every readiness producer (PRD #1739, #1896).
|
|
3
|
+
*
|
|
4
|
+
* Three things were being re-implemented per producer: reading a repository file
|
|
5
|
+
* without letting a missing file throw, asking whether a repository path exists,
|
|
6
|
+
* and wrapping a non-blocking observation as a finding. The last one is the
|
|
7
|
+
* load-bearing case — an observation finding must carry NO `blocker` key,
|
|
8
|
+
* because the blocker engine stands a blocker up on any finding that names an id
|
|
9
|
+
* and carries evidence regardless of the finding's status. One definition means
|
|
10
|
+
* that rule cannot drift apart across producers.
|
|
11
|
+
* @module cli/doctor-readiness-shared
|
|
12
|
+
*/
|
|
13
|
+
import { readdir, readFile } from "node:fs/promises";
|
|
14
|
+
import * as path from "node:path";
|
|
15
|
+
/**
|
|
16
|
+
* Read a repository-relative file, returning null when it cannot be read.
|
|
17
|
+
*
|
|
18
|
+
* Reading is best-effort by design: a file that cannot be read establishes
|
|
19
|
+
* nothing, and a readiness producer must never turn "could not look" into
|
|
20
|
+
* either a violation or a clean bill of health.
|
|
21
|
+
* @param root - Repository root
|
|
22
|
+
* @param relativePath - Repo-relative path (forward slashes)
|
|
23
|
+
* @returns File contents, or null
|
|
24
|
+
*/
|
|
25
|
+
export async function readFileOrNull(root, relativePath) {
|
|
26
|
+
try {
|
|
27
|
+
return await readFile(path.join(root, ...relativePath.split("/")), "utf8");
|
|
28
|
+
}
|
|
29
|
+
catch {
|
|
30
|
+
return null;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Whether a repository-relative directory exists.
|
|
35
|
+
* @param root - Repository root
|
|
36
|
+
* @param relativePath - Repo-relative directory path
|
|
37
|
+
* @returns True when the directory could be listed
|
|
38
|
+
*/
|
|
39
|
+
export async function directoryExists(root, relativePath) {
|
|
40
|
+
try {
|
|
41
|
+
await readdir(path.join(root, ...relativePath.split("/")));
|
|
42
|
+
return true;
|
|
43
|
+
}
|
|
44
|
+
catch {
|
|
45
|
+
return false;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Whether a repository-relative path exists, as a file or a directory.
|
|
50
|
+
* @param root - Repository root
|
|
51
|
+
* @param relativePath - Repo-relative path
|
|
52
|
+
* @returns True when something is present at that path
|
|
53
|
+
*/
|
|
54
|
+
export async function pathExists(root, relativePath) {
|
|
55
|
+
return ((await readFileOrNull(root, relativePath)) !== null ||
|
|
56
|
+
(await directoryExists(root, relativePath)));
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Strip leading and trailing slashes from a repo-relative path fragment.
|
|
60
|
+
* Written without a regex quantifier so it cannot backtrack on hostile input.
|
|
61
|
+
* @param value - The path fragment
|
|
62
|
+
* @returns The fragment with empty segments removed
|
|
63
|
+
*/
|
|
64
|
+
export function trimSlashes(value) {
|
|
65
|
+
return value
|
|
66
|
+
.split("/")
|
|
67
|
+
.filter(segment => segment !== "")
|
|
68
|
+
.join("/");
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Whether a value is a plain JSON object.
|
|
72
|
+
* @param value - Candidate value
|
|
73
|
+
* @returns True when the value is a non-null, non-array object
|
|
74
|
+
*/
|
|
75
|
+
export function isRecord(value) {
|
|
76
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Wrap non-blocking observations as findings. They deliberately carry no
|
|
80
|
+
* `blocker` key: naming one would stand a blocker up — and flip the whole
|
|
81
|
+
* repository to `NOT_READY` — on an observation that was never decidable.
|
|
82
|
+
* @param notes - Informational lines
|
|
83
|
+
* @returns Findings, one per note
|
|
84
|
+
*/
|
|
85
|
+
export function informationalFindings(notes) {
|
|
86
|
+
return notes.map(note => ({ observation: note, blocking: false }));
|
|
87
|
+
}
|
|
88
|
+
//# sourceMappingURL=doctor-readiness-shared.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"doctor-readiness-shared.js","sourceRoot":"","sources":["../../src/cli/doctor-readiness-shared.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAElC;;;;;;;;;GASG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc,CAClC,IAAY,EACZ,YAAoB;IAEpB,IAAI,CAAC;QACH,OAAO,MAAM,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,GAAG,YAAY,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC;IAC7E,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe,CACnC,IAAY,EACZ,YAAoB;IAEpB,IAAI,CAAC;QACH,MAAM,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,GAAG,YAAY,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;QAC3D,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,UAAU,CAC9B,IAAY,EACZ,YAAoB;IAEpB,OAAO,CACL,CAAC,MAAM,cAAc,CAAC,IAAI,EAAE,YAAY,CAAC,CAAC,KAAK,IAAI;QACnD,CAAC,MAAM,eAAe,CAAC,IAAI,EAAE,YAAY,CAAC,CAAC,CAC5C,CAAC;AACJ,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,WAAW,CAAC,KAAa;IACvC,OAAO,KAAK;SACT,KAAK,CAAC,GAAG,CAAC;SACV,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC,OAAO,KAAK,EAAE,CAAC;SACjC,IAAI,CAAC,GAAG,CAAC,CAAC;AACf,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,QAAQ,CAAC,KAAc;IACrC,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;AAC9E,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,qBAAqB,CACnC,KAAwB;IAExB,OAAO,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,EAAE,WAAW,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC;AACrE,CAAC"}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Every lockfile spelling a JavaScript package manager writes. One of these
|
|
3
|
+
* being committed is what makes two installs resolve to the same tree.
|
|
4
|
+
*/
|
|
5
|
+
export declare const LOCKFILES: readonly string[];
|
|
6
|
+
/**
|
|
7
|
+
* Whether a dependency spec resolves to whatever is newest at install time
|
|
8
|
+
* rather than to a version something was validated against.
|
|
9
|
+
*
|
|
10
|
+
* Four families are recognized, and the narrowness of each is deliberate — every
|
|
11
|
+
* over-eager rule here fails a correctly configured repository:
|
|
12
|
+
*
|
|
13
|
+
* - **Local protocols** resolve inside the repository and never float.
|
|
14
|
+
* - **Registry aliases** (`npm:left-pad@latest`) hide the real spec behind the
|
|
15
|
+
* alias, so the part after the version separator is re-tested.
|
|
16
|
+
* - **Repository clones** (`github:acme/widget`, `git+https://…/x.git`) float
|
|
17
|
+
* unless anchored to a `#<sha|tag>` revision, because the branch tip moves
|
|
18
|
+
* under the install. An archive URL (`…/widget-1.2.3.tgz`) is NOT a clone: it
|
|
19
|
+
* names one built artifact and is treated as pinned.
|
|
20
|
+
* - **Plain ranges** float only when they name no version at all. A `>=` floor
|
|
21
|
+
* in `overrides` is the recommended way to force a patched transitive
|
|
22
|
+
* dependency, so ranges are otherwise left alone.
|
|
23
|
+
* @param spec - The declared spec text
|
|
24
|
+
* @returns True when the spec floats
|
|
25
|
+
*/
|
|
26
|
+
export declare function isFloatingSpec(spec: string): boolean;
|
|
27
|
+
/** What reading the manifest established. */
|
|
28
|
+
export type ManifestOutcome = {
|
|
29
|
+
readonly kind: "ok";
|
|
30
|
+
readonly manifest: Record<string, unknown>;
|
|
31
|
+
} | {
|
|
32
|
+
readonly kind: "unassessable";
|
|
33
|
+
readonly reason: string;
|
|
34
|
+
};
|
|
35
|
+
/**
|
|
36
|
+
* Read and parse `package.json`, distinguishing "absent" from "unparseable" so
|
|
37
|
+
* the SKIP reason can say which one happened.
|
|
38
|
+
* @param root - Repository root
|
|
39
|
+
* @returns The parsed manifest, or the reason it cannot be assessed
|
|
40
|
+
*/
|
|
41
|
+
export declare function readManifest(root: string): Promise<ManifestOutcome>;
|
|
42
|
+
/** One declared dependency spec, flattened out of the manifest blocks. */
|
|
43
|
+
export interface DependencySpec {
|
|
44
|
+
readonly block: string;
|
|
45
|
+
readonly name: string;
|
|
46
|
+
readonly spec: string;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Flatten every versioned manifest block into one list of specs.
|
|
50
|
+
* @param manifest - Parsed `package.json`
|
|
51
|
+
* @returns Every declared spec across the versioned blocks
|
|
52
|
+
*/
|
|
53
|
+
export declare function collectSpecs(manifest: Record<string, unknown>): readonly DependencySpec[];
|
|
54
|
+
/**
|
|
55
|
+
* Find the committed lockfile, if any.
|
|
56
|
+
* @param root - Repository root
|
|
57
|
+
* @returns The lockfile name, or null when none is committed
|
|
58
|
+
*/
|
|
59
|
+
export declare function findLockfile(root: string): Promise<string | null>;
|
|
60
|
+
/**
|
|
61
|
+
* Find where the repository audits its dependency tree: a CI job, a git hook, a
|
|
62
|
+
* lefthook declaration, or an update bot.
|
|
63
|
+
* @param root - Repository root
|
|
64
|
+
* @returns The repo-relative path of the first gate found, or null
|
|
65
|
+
*/
|
|
66
|
+
export declare function findAuditGate(root: string): Promise<string | null>;
|
|
67
|
+
//# sourceMappingURL=doctor-readiness-supply-chain-scan.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"doctor-readiness-supply-chain-scan.d.ts","sourceRoot":"","sources":["../../src/cli/doctor-readiness-supply-chain-scan.ts"],"names":[],"mappings":"AAoBA;;;GAGG;AACH,eAAO,MAAM,SAAS,EAAE,SAAS,MAAM,EAOtC,CAAC;AAoFF;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAepD;AAyCD,6CAA6C;AAC7C,MAAM,MAAM,eAAe,GACvB;IAAE,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAC;IAAC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAAE,GACnE;IAAE,QAAQ,CAAC,IAAI,EAAE,cAAc,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAsC/D;;;;;GAKG;AACH,wBAAsB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,CAAC,CA2BzE;AAED,0EAA0E;AAC1E,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACvB;AA4BD;;;;GAIG;AACH,wBAAgB,YAAY,CAC1B,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAChC,SAAS,cAAc,EAAE,CAI3B;AAED;;;;GAIG;AACH,wBAAsB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAOvE;AAkBD;;;;;GAKG;AACH,wBAAsB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAoBxE"}
|