@codyswann/lisa 4.34.0 → 4.34.1
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-nightly-e2e-bypass-arming.d.ts +29 -0
- package/dist/cli/doctor-nightly-e2e-bypass-arming.d.ts.map +1 -0
- package/dist/cli/doctor-nightly-e2e-bypass-arming.js +135 -0
- package/dist/cli/doctor-nightly-e2e-bypass-arming.js.map +1 -0
- package/dist/cli/doctor.d.ts.map +1 -1
- package/dist/cli/doctor.js +10 -0
- package/dist/cli/doctor.js.map +1 -1
- package/dist/cli/ui-detected-stacks.d.ts.map +1 -1
- package/dist/cli/ui-detected-stacks.js +1 -3
- package/dist/cli/ui-detected-stacks.js.map +1 -1
- package/dist/core/nightly-e2e-guard-behavior-certificate.js +2 -2
- package/dist/core/nightly-e2e-pull-request-triggers.d.ts +54 -0
- package/dist/core/nightly-e2e-pull-request-triggers.d.ts.map +1 -0
- package/dist/core/nightly-e2e-pull-request-triggers.js +331 -0
- package/dist/core/nightly-e2e-pull-request-triggers.js.map +1 -0
- package/dist/core/upstream-evidence-manifest.d.ts.map +1 -1
- package/dist/core/upstream-evidence-manifest.js +6 -1
- package/dist/core/upstream-evidence-manifest.js.map +1 -1
- package/dist/detection/detectors/cdk.d.ts +21 -4
- package/dist/detection/detectors/cdk.d.ts.map +1 -1
- package/dist/detection/detectors/cdk.js +23 -30
- package/dist/detection/detectors/cdk.js.map +1 -1
- package/dist/health/template-inspection.js +1 -1
- package/dist/health/template-inspection.js.map +1 -1
- package/dist/migrations/ensure-nightly-e2e-workflow-pins.d.ts +11 -2
- package/dist/migrations/ensure-nightly-e2e-workflow-pins.d.ts.map +1 -1
- package/dist/migrations/ensure-nightly-e2e-workflow-pins.js +21 -4
- package/dist/migrations/ensure-nightly-e2e-workflow-pins.js.map +1 -1
- package/dist/strategies/package-lisa.d.ts.map +1 -1
- package/dist/strategies/package-lisa.js +3 -3
- package/dist/strategies/package-lisa.js.map +1 -1
- package/expo/create-only/.github/workflows/nightly-e2e-health.yml +16 -1
- package/package.json +4 -4
- 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,331 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The pull-request activity types a nightly-E2E bypass caller must subscribe to.
|
|
3
|
+
*
|
|
4
|
+
* ## The defect this exists for (issues #3476, #3485)
|
|
5
|
+
*
|
|
6
|
+
* A nightly-E2E waiver needs TWO pieces of evidence, and the guard re-checks
|
|
7
|
+
* both on every evaluation: the bypass label, and a `Nightly-E2E-Bypass:
|
|
8
|
+
* <ticket> <reason>` line in the pull-request BODY. The guard reads both live
|
|
9
|
+
* from the API at gate time, so it would reject a body that no longer carries
|
|
10
|
+
* the line — if it ran.
|
|
11
|
+
*
|
|
12
|
+
* It does not run. The caller subscribes to `labeled`/`unlabeled`, so deleting
|
|
13
|
+
* the label re-fires the gate. Nothing subscribes to `edited`, so deleting the
|
|
14
|
+
* BODY line fires nothing, and the previous SUCCESS check-run stands. A
|
|
15
|
+
* check-run is point-in-time by construction: no event, no re-read. Measured on
|
|
16
|
+
* a caller repo in the portfolio: a required check stayed green for 49m47s
|
|
17
|
+
* while vouching for a waiver that was no longer in the pull request, and the
|
|
18
|
+
* merge landed inside that window.
|
|
19
|
+
*
|
|
20
|
+
* **The reading is current; the reading never happened.** That is why a live
|
|
21
|
+
* API read in the guard — which the guard already does — cannot fix this, and
|
|
22
|
+
* why the repair has to be a trigger.
|
|
23
|
+
*
|
|
24
|
+
* ## Why the caller, and why a migration
|
|
25
|
+
*
|
|
26
|
+
* The reusable workflow is `on: workflow_call`, and a reusable workflow cannot
|
|
27
|
+
* declare pull-request activity types. The trigger list is therefore only
|
|
28
|
+
* expressible in the CALLER, which ships from `expo/create-only/` and is marked
|
|
29
|
+
* "this file is YOURS — Lisa will not overwrite it". A template fix reaches new
|
|
30
|
+
* adoptions only; every already-seeded repository keeps its original trigger
|
|
31
|
+
* list permanently. So the migration is the only surface that reaches the
|
|
32
|
+
* installed base, and `doctor` is the only surface that catches a consumer who
|
|
33
|
+
* later hand-edits the list back.
|
|
34
|
+
*
|
|
35
|
+
* All three read this module, so they cannot disagree about what "armed" means.
|
|
36
|
+
* @module core/nightly-e2e-pull-request-triggers
|
|
37
|
+
*/
|
|
38
|
+
import { loadYaml } from "../utils/yaml.js";
|
|
39
|
+
/**
|
|
40
|
+
* The activity type whose absence is the defect.
|
|
41
|
+
*
|
|
42
|
+
* A pull-request body rewrite raises `edited` and nothing else.
|
|
43
|
+
*/
|
|
44
|
+
export const BODY_CHANGE_ACTIVITY_TYPE = "edited";
|
|
45
|
+
/**
|
|
46
|
+
* GitHub's implicit `types:` for `pull_request` when the key is omitted.
|
|
47
|
+
*
|
|
48
|
+
* Recorded because the omission is NOT a neutral state: the default set does
|
|
49
|
+
* not include `edited`, so a caller with no `types:` at all is vulnerable in
|
|
50
|
+
* exactly the same way as one that lists types and leaves `edited` out. Writing
|
|
51
|
+
* this list explicitly alongside `edited` is behaviour-preserving — it states
|
|
52
|
+
* what GitHub was already doing and adds the missing one.
|
|
53
|
+
*/
|
|
54
|
+
export const IMPLICIT_PULL_REQUEST_TYPES = [
|
|
55
|
+
"opened",
|
|
56
|
+
"synchronize",
|
|
57
|
+
"reopened",
|
|
58
|
+
];
|
|
59
|
+
/**
|
|
60
|
+
* Narrow a parsed value to a mapping.
|
|
61
|
+
* @param value - Parsed YAML value
|
|
62
|
+
* @returns The mapping, or undefined for any other shape
|
|
63
|
+
*/
|
|
64
|
+
const asRecord = (value) => typeof value === "object" && value !== null && !Array.isArray(value)
|
|
65
|
+
? value
|
|
66
|
+
: undefined;
|
|
67
|
+
/**
|
|
68
|
+
* Parse YAML without throwing.
|
|
69
|
+
* @param source - YAML text
|
|
70
|
+
* @returns The document, or undefined when it cannot be parsed
|
|
71
|
+
*/
|
|
72
|
+
const parseYaml = (source) => {
|
|
73
|
+
try {
|
|
74
|
+
return loadYaml(source);
|
|
75
|
+
}
|
|
76
|
+
catch {
|
|
77
|
+
return undefined;
|
|
78
|
+
}
|
|
79
|
+
};
|
|
80
|
+
/**
|
|
81
|
+
* Read the `on:` mapping from a parsed workflow.
|
|
82
|
+
*
|
|
83
|
+
* YAML 1.1 resolves a bare `on` key to the BOOLEAN true, which is why js-yaml
|
|
84
|
+
* can hand back `{ true: {...} }` for a workflow every GitHub runner accepts.
|
|
85
|
+
* Both spellings are read here; treating only the string one as real would make
|
|
86
|
+
* this silently answer "no pull_request trigger" for ordinary workflows.
|
|
87
|
+
* @param document - Parsed workflow document
|
|
88
|
+
* @returns The `on:` mapping, or undefined when there is none
|
|
89
|
+
*/
|
|
90
|
+
const readOnBlock = (document) => {
|
|
91
|
+
const root = asRecord(document);
|
|
92
|
+
if (root === undefined)
|
|
93
|
+
return undefined;
|
|
94
|
+
return asRecord(root["on"]) ?? asRecord(root[String(true)]);
|
|
95
|
+
};
|
|
96
|
+
/**
|
|
97
|
+
* Read a `types:` value as a list of strings.
|
|
98
|
+
*
|
|
99
|
+
* A single scalar is a legal spelling of a one-element list, so it is widened
|
|
100
|
+
* rather than rejected.
|
|
101
|
+
* @param value - The raw `types:` value
|
|
102
|
+
* @returns The declared types, or undefined when absent or unreadable
|
|
103
|
+
*/
|
|
104
|
+
const readTypes = (value) => {
|
|
105
|
+
if (value === undefined || value === null)
|
|
106
|
+
return undefined;
|
|
107
|
+
if (typeof value === "string")
|
|
108
|
+
return [value];
|
|
109
|
+
return Array.isArray(value) && value.every(item => typeof item === "string")
|
|
110
|
+
? value
|
|
111
|
+
: undefined;
|
|
112
|
+
};
|
|
113
|
+
/** The assessment returned whenever no pull-request trigger is readable. */
|
|
114
|
+
const NO_PULL_REQUEST = {
|
|
115
|
+
armed: false,
|
|
116
|
+
gap: "pull-request-absent",
|
|
117
|
+
effectiveTypes: [],
|
|
118
|
+
};
|
|
119
|
+
/**
|
|
120
|
+
* Decide whether a caller re-evaluates when the pull-request body changes.
|
|
121
|
+
*
|
|
122
|
+
* Fails toward "not armed": an unreadable document, a missing `pull_request`
|
|
123
|
+
* trigger, or a `types:` shape this cannot read all report a gap rather than
|
|
124
|
+
* claiming the gate is fine. A check that reports "armed" when it means "I
|
|
125
|
+
* could not tell" is the whole failure mode being repaired here.
|
|
126
|
+
* @param source - Workflow YAML source
|
|
127
|
+
* @returns What the trigger list means for body-change re-evaluation
|
|
128
|
+
*/
|
|
129
|
+
export const assessBodyChangeTrigger = (source) => {
|
|
130
|
+
const onBlock = readOnBlock(parseYaml(source));
|
|
131
|
+
if (onBlock === undefined || !("pull_request" in onBlock)) {
|
|
132
|
+
return NO_PULL_REQUEST;
|
|
133
|
+
}
|
|
134
|
+
// `pull_request:` with an empty value is a legal shape meaning "the
|
|
135
|
+
// defaults", so it is the types-absent case rather than an unreadable one.
|
|
136
|
+
const pullRequest = asRecord(onBlock["pull_request"]);
|
|
137
|
+
const declared = pullRequest === undefined ? undefined : readTypes(pullRequest["types"]);
|
|
138
|
+
if (declared === undefined) {
|
|
139
|
+
return {
|
|
140
|
+
armed: false,
|
|
141
|
+
gap: "types-absent",
|
|
142
|
+
effectiveTypes: IMPLICIT_PULL_REQUEST_TYPES,
|
|
143
|
+
};
|
|
144
|
+
}
|
|
145
|
+
return declared.includes(BODY_CHANGE_ACTIVITY_TYPE)
|
|
146
|
+
? { armed: true, effectiveTypes: declared }
|
|
147
|
+
: { armed: false, gap: "types-omit-edited", effectiveTypes: declared };
|
|
148
|
+
};
|
|
149
|
+
/**
|
|
150
|
+
* Leading-whitespace width of a line.
|
|
151
|
+
* @param line - Source line
|
|
152
|
+
* @returns Number of leading whitespace characters
|
|
153
|
+
*/
|
|
154
|
+
const indentOf = (line) => line.length - line.trimStart().length;
|
|
155
|
+
/**
|
|
156
|
+
* Whether a line carries no YAML structure.
|
|
157
|
+
* @param line - Source line
|
|
158
|
+
* @returns True for blank lines and whole-line comments
|
|
159
|
+
*/
|
|
160
|
+
const isSkippable = (line) => line.trim() === "" || line.trimStart().startsWith("#");
|
|
161
|
+
/**
|
|
162
|
+
* Replace one line without mutating the original list.
|
|
163
|
+
* @param lines - Source lines
|
|
164
|
+
* @param index - Line to replace
|
|
165
|
+
* @param value - Replacement text
|
|
166
|
+
* @returns A new list
|
|
167
|
+
*/
|
|
168
|
+
const replaceAt = (lines, index, value) => [
|
|
169
|
+
...lines.slice(0, index),
|
|
170
|
+
value,
|
|
171
|
+
...lines.slice(index + 1),
|
|
172
|
+
];
|
|
173
|
+
/**
|
|
174
|
+
* Insert one line without mutating the original list.
|
|
175
|
+
* @param lines - Source lines
|
|
176
|
+
* @param index - Position the new line takes
|
|
177
|
+
* @param value - Line to insert
|
|
178
|
+
* @returns A new list
|
|
179
|
+
*/
|
|
180
|
+
const insertAt = (lines, index, value) => [
|
|
181
|
+
...lines.slice(0, index),
|
|
182
|
+
value,
|
|
183
|
+
...lines.slice(index),
|
|
184
|
+
];
|
|
185
|
+
/** `types: [a, b]` written inline. */
|
|
186
|
+
const FLOW_TYPES = /^\s*types\s*:\s*\[[^[\]]*\]\s*$/;
|
|
187
|
+
/** `types:` introducing a block sequence. */
|
|
188
|
+
const BLOCK_TYPES = /^\s*types\s*:\s*$/;
|
|
189
|
+
/** A block-sequence item. */
|
|
190
|
+
const SEQUENCE_ITEM = /^\s*-\s/;
|
|
191
|
+
/** The `pull_request:` key, at any depth. */
|
|
192
|
+
const PULL_REQUEST_KEY = /^\s*pull_request\s*:/;
|
|
193
|
+
/**
|
|
194
|
+
* Index of the `pull_request:` key line, or -1.
|
|
195
|
+
*
|
|
196
|
+
* Nested rather than top-level, which is what distinguishes the trigger key
|
|
197
|
+
* from anything else. A wrong guess cannot produce a wrong file: every rewrite
|
|
198
|
+
* built on this is verified by re-parsing the result before it is returned.
|
|
199
|
+
* @param lines - Source lines
|
|
200
|
+
* @returns Line index, or -1 when there is none
|
|
201
|
+
*/
|
|
202
|
+
const pullRequestKeyIndex = (lines) => lines.findIndex(line => !isSkippable(line) && indentOf(line) > 0 && PULL_REQUEST_KEY.test(line));
|
|
203
|
+
/**
|
|
204
|
+
* The lines belonging to the block a key introduces.
|
|
205
|
+
* @param lines - Source lines
|
|
206
|
+
* @param keyIndex - Index of the key line
|
|
207
|
+
* @returns The block's lines, in order
|
|
208
|
+
*/
|
|
209
|
+
const blockBody = (lines, keyIndex) => {
|
|
210
|
+
const owner = indentOf(lines[keyIndex] ?? "");
|
|
211
|
+
const rest = lines.slice(keyIndex + 1);
|
|
212
|
+
const end = rest.findIndex(line => !isSkippable(line) && indentOf(line) <= owner);
|
|
213
|
+
return end === -1 ? rest : rest.slice(0, end);
|
|
214
|
+
};
|
|
215
|
+
/**
|
|
216
|
+
* Locate the `types:` line belonging to `on.pull_request`.
|
|
217
|
+
*
|
|
218
|
+
* Deliberately a line scan rather than a parse-and-re-emit. These files are
|
|
219
|
+
* consumer-owned and dense with explanatory comments that say WHY each trigger
|
|
220
|
+
* is present; round-tripping them through a YAML serializer would silently
|
|
221
|
+
* delete every one of those comments.
|
|
222
|
+
* @param lines - Source lines
|
|
223
|
+
* @returns The located declaration, or undefined when the shape is unfamiliar
|
|
224
|
+
*/
|
|
225
|
+
const findPullRequestTypesLine = (lines) => {
|
|
226
|
+
const keyIndex = pullRequestKeyIndex(lines);
|
|
227
|
+
if (keyIndex === -1)
|
|
228
|
+
return undefined;
|
|
229
|
+
const body = blockBody(lines, keyIndex);
|
|
230
|
+
const offset = body.findIndex(line => FLOW_TYPES.test(line) || BLOCK_TYPES.test(line));
|
|
231
|
+
if (offset === -1)
|
|
232
|
+
return undefined;
|
|
233
|
+
const index = keyIndex + 1 + offset;
|
|
234
|
+
return { index, flow: FLOW_TYPES.test(lines[index] ?? "") };
|
|
235
|
+
};
|
|
236
|
+
/**
|
|
237
|
+
* Add `edited` inside an inline `[...]` list.
|
|
238
|
+
*
|
|
239
|
+
* String indexing rather than a regular expression: an unbounded class inside
|
|
240
|
+
* brackets is the shape that backtracks badly on adversarial input, and this
|
|
241
|
+
* runs over files Lisa did not write.
|
|
242
|
+
* @param line - The `types: [...]` line
|
|
243
|
+
* @returns The line with `edited` appended
|
|
244
|
+
*/
|
|
245
|
+
const appendToFlowList = (line) => {
|
|
246
|
+
const open = line.indexOf("[");
|
|
247
|
+
const close = line.indexOf("]", open + 1);
|
|
248
|
+
if (open === -1 || close === -1)
|
|
249
|
+
return line;
|
|
250
|
+
const inner = line.slice(open + 1, close).trimEnd();
|
|
251
|
+
const extended = inner.trim() === ""
|
|
252
|
+
? BODY_CHANGE_ACTIVITY_TYPE
|
|
253
|
+
: `${inner}, ${BODY_CHANGE_ACTIVITY_TYPE}`;
|
|
254
|
+
return `${line.slice(0, open + 1)}${extended}${line.slice(close)}`;
|
|
255
|
+
};
|
|
256
|
+
/**
|
|
257
|
+
* Add `- edited` to a block sequence, matching the style already in use.
|
|
258
|
+
* @param lines - Source lines
|
|
259
|
+
* @param located - The `types:` declaration introducing the sequence
|
|
260
|
+
* @returns The rewritten lines
|
|
261
|
+
*/
|
|
262
|
+
const appendToBlockList = (lines, located) => {
|
|
263
|
+
const body = blockBody(lines, located.index);
|
|
264
|
+
const items = body.filter(line => SEQUENCE_ITEM.test(line));
|
|
265
|
+
const lastOffset = body.reduce((accumulator, line, offset) => SEQUENCE_ITEM.test(line) ? offset : accumulator, -1);
|
|
266
|
+
const itemIndent = items[0] === undefined
|
|
267
|
+
? indentOf(lines[located.index] ?? "") + 2
|
|
268
|
+
: indentOf(items[0]);
|
|
269
|
+
return insertAt(lines, located.index + lastOffset + 2, `${" ".repeat(itemIndent)}- ${BODY_CHANGE_ACTIVITY_TYPE}`);
|
|
270
|
+
};
|
|
271
|
+
/**
|
|
272
|
+
* Write an explicit `types:` under a `pull_request:` that declares none.
|
|
273
|
+
*
|
|
274
|
+
* The implicit default omits `edited`, so this case is vulnerable too, and
|
|
275
|
+
* stating the defaults alongside `edited` is behaviour-preserving rather than a
|
|
276
|
+
* widening. Only a `pull_request:` that already has a mapping body is extended;
|
|
277
|
+
* a bare one is left to `doctor`, because inventing a body for it is a guess
|
|
278
|
+
* about a consumer's intent rather than a repair.
|
|
279
|
+
* @param lines - Source lines
|
|
280
|
+
* @returns The rewritten lines, or undefined when no safe insertion exists
|
|
281
|
+
*/
|
|
282
|
+
const insertTypesDeclaration = (lines) => {
|
|
283
|
+
const keyIndex = pullRequestKeyIndex(lines);
|
|
284
|
+
if (keyIndex === -1)
|
|
285
|
+
return undefined;
|
|
286
|
+
const child = blockBody(lines, keyIndex).find(line => !isSkippable(line));
|
|
287
|
+
if (child === undefined)
|
|
288
|
+
return undefined;
|
|
289
|
+
const declaration = [
|
|
290
|
+
...IMPLICIT_PULL_REQUEST_TYPES,
|
|
291
|
+
BODY_CHANGE_ACTIVITY_TYPE,
|
|
292
|
+
];
|
|
293
|
+
return insertAt(lines, keyIndex + 1, `${" ".repeat(indentOf(child))}types: [${declaration.join(", ")}]`);
|
|
294
|
+
};
|
|
295
|
+
/**
|
|
296
|
+
* Produce the candidate lines that would arm a caller.
|
|
297
|
+
* @param lines - Source lines
|
|
298
|
+
* @returns The rewritten lines, or undefined when no safe edit exists
|
|
299
|
+
*/
|
|
300
|
+
const armedLines = (lines) => {
|
|
301
|
+
const located = findPullRequestTypesLine(lines);
|
|
302
|
+
if (located === undefined)
|
|
303
|
+
return insertTypesDeclaration(lines);
|
|
304
|
+
return located.flow
|
|
305
|
+
? replaceAt(lines, located.index, appendToFlowList(lines[located.index] ?? ""))
|
|
306
|
+
: appendToBlockList(lines, located);
|
|
307
|
+
};
|
|
308
|
+
/**
|
|
309
|
+
* Add `edited` to a caller's pull-request trigger list, in place and in style.
|
|
310
|
+
*
|
|
311
|
+
* Idempotent, and fails SAFE in both directions: a caller that is already armed
|
|
312
|
+
* is returned untouched, and a shape this cannot confidently edit is also
|
|
313
|
+
* returned untouched rather than guessed at. Every rewrite is verified by
|
|
314
|
+
* re-parsing the result and confirming the gate is now armed — if the surgical
|
|
315
|
+
* edit did not achieve that, the original source is returned and `doctor`
|
|
316
|
+
* reports the caller for a human instead. Writing a broken workflow into a
|
|
317
|
+
* consumer repository would take their gate from half-armed to not running at
|
|
318
|
+
* all, which is strictly worse than the defect.
|
|
319
|
+
* @param source - Workflow YAML source
|
|
320
|
+
* @returns The armed source, or the original when no safe edit exists
|
|
321
|
+
*/
|
|
322
|
+
export const ensureBodyChangeTrigger = (source) => {
|
|
323
|
+
if (assessBodyChangeTrigger(source).armed)
|
|
324
|
+
return source;
|
|
325
|
+
const rewritten = armedLines(source.split("\n"));
|
|
326
|
+
if (rewritten === undefined)
|
|
327
|
+
return source;
|
|
328
|
+
const candidate = rewritten.join("\n");
|
|
329
|
+
return assessBodyChangeTrigger(candidate).armed ? candidate : source;
|
|
330
|
+
};
|
|
331
|
+
//# sourceMappingURL=nightly-e2e-pull-request-triggers.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"nightly-e2e-pull-request-triggers.js","sourceRoot":"","sources":["../../src/core/nightly-e2e-pull-request-triggers.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"upstream-evidence-manifest.d.ts","sourceRoot":"","sources":["../../src/core/upstream-evidence-manifest.ts"],"names":[],"mappings":"AACA,iFAAiF;AACjF,eAAO,MAAM,0BAA0B,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAogFpE,CAAC;AAEL,4EAA4E;AAC5E,eAAO,MAAM,yBAAyB,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,
|
|
1
|
+
{"version":3,"file":"upstream-evidence-manifest.d.ts","sourceRoot":"","sources":["../../src/core/upstream-evidence-manifest.ts"],"names":[],"mappings":"AACA,iFAAiF;AACjF,eAAO,MAAM,0BAA0B,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAogFpE,CAAC;AAEL,4EAA4E;AAC5E,eAAO,MAAM,yBAAyB,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,CAunQjE,CAAC;AAEL,sFAAsF;AACtF,eAAO,MAAM,uBAAuB,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,CAk6I/D,CAAC"}
|
|
@@ -137,7 +137,7 @@ export const UPSTREAM_EVIDENCE_MANIFEST = Object.freeze({
|
|
|
137
137
|
"expo/create-only/.github/workflows/deploy.yml": "a50a7a7fe595bf450cd22b1d1d6d2a733a895d235f2480a9ae1255f57aadc497",
|
|
138
138
|
"expo/create-only/.github/workflows/maestro-e2e.yml": "917d1918f3bff9b4c19db3f9a9bd6fd1d7c5d3db0947dacec3f4797c692632d6",
|
|
139
139
|
"expo/create-only/.github/workflows/nightly-e2e-bypass-reaper.yml": "db78a1012a00cf4e8b023a67bb57566ae85cf790c3856f3e299636c766f0c242",
|
|
140
|
-
"expo/create-only/.github/workflows/nightly-e2e-health.yml": "
|
|
140
|
+
"expo/create-only/.github/workflows/nightly-e2e-health.yml": "1d471dceded3bc74ec7f7703ce5ea6d7913d49a93aabb9fd70a262a12b467f59",
|
|
141
141
|
"expo/create-only/.github/workflows/nightly-e2e-report.yml": "721009809c862b50c4cb5b679307c82cdc1c377914052c323b77d2339c1e6357",
|
|
142
142
|
"expo/create-only/.github/workflows/nightly-e2e-tracking.yml": "3322fe6383df9a966459dd2bf2d0024ab655bf2f59155588b2b2cbbb6acbc62c",
|
|
143
143
|
"expo/create-only/.github/workflows/playwright-e2e.yml": "4910275b5c295719e10baa88e8ddb14fc1082a368f3eecd83f4612abb62821b7",
|
|
@@ -7351,6 +7351,7 @@ export const UPSTREAM_SURFACE_MANIFEST = Object.freeze({
|
|
|
7351
7351
|
"src/cli/doctor-lisa-owned-universal.ts": true,
|
|
7352
7352
|
"src/cli/doctor-merge-drivers.ts": true,
|
|
7353
7353
|
"src/cli/doctor-monitor-thresholds.ts": true,
|
|
7354
|
+
"src/cli/doctor-nightly-e2e-bypass-arming.ts": true,
|
|
7354
7355
|
"src/cli/doctor-nightly-e2e-guard-command-files.ts": true,
|
|
7355
7356
|
"src/cli/doctor-nightly-e2e-guard-contract.ts": true,
|
|
7356
7357
|
"src/cli/doctor-nightly-e2e-guard-deadline.ts": true,
|
|
@@ -7651,6 +7652,7 @@ export const UPSTREAM_SURFACE_MANIFEST = Object.freeze({
|
|
|
7651
7652
|
"src/core/lisa.ts": true,
|
|
7652
7653
|
"src/core/merge-driver-registration.ts": true,
|
|
7653
7654
|
"src/core/nightly-e2e-guard-behavior-certificate.ts": true,
|
|
7655
|
+
"src/core/nightly-e2e-pull-request-triggers.ts": true,
|
|
7654
7656
|
"src/core/override-floors.ts": true,
|
|
7655
7657
|
"src/core/project-config-kane.ts": true,
|
|
7656
7658
|
"src/core/project-config-learnings.ts": true,
|
|
@@ -8159,6 +8161,7 @@ export const UPSTREAM_SURFACE_MANIFEST = Object.freeze({
|
|
|
8159
8161
|
"tests/unit/cli/doctor-lisa-owned-artifacts.test.ts": true,
|
|
8160
8162
|
"tests/unit/cli/doctor-merge-drivers.test.ts": true,
|
|
8161
8163
|
"tests/unit/cli/doctor-monitor-thresholds.test.ts": true,
|
|
8164
|
+
"tests/unit/cli/doctor-nightly-e2e-bypass-arming.test.ts": true,
|
|
8162
8165
|
"tests/unit/cli/doctor-nightly-e2e-guard-deadline.test.ts": true,
|
|
8163
8166
|
"tests/unit/cli/doctor-nightly-e2e-guard-integration.test.ts": true,
|
|
8164
8167
|
"tests/unit/cli/doctor-nightly-e2e-guard-proof.test.ts": true,
|
|
@@ -8469,6 +8472,7 @@ export const UPSTREAM_SURFACE_MANIFEST = Object.freeze({
|
|
|
8469
8472
|
"tests/unit/core/lisa-owned-templates.test.ts": true,
|
|
8470
8473
|
"tests/unit/core/lisa-plugin-selection.test.ts": true,
|
|
8471
8474
|
"tests/unit/core/lisa-skill-sources.test.ts": true,
|
|
8475
|
+
"tests/unit/core/nightly-e2e-pull-request-triggers.test.ts": true,
|
|
8472
8476
|
"tests/unit/core/no-downstream-project-names.test.ts": true,
|
|
8473
8477
|
"tests/unit/core/override-floors.test.ts": true,
|
|
8474
8478
|
"tests/unit/core/packed-learnings-contract.test.ts": true,
|
|
@@ -8494,6 +8498,7 @@ export const UPSTREAM_SURFACE_MANIFEST = Object.freeze({
|
|
|
8494
8498
|
"tests/unit/core/upstream-attribution-integrity.test.ts": true,
|
|
8495
8499
|
"tests/unit/core/workflow-deletion-ownership.test.ts": true,
|
|
8496
8500
|
"tests/unit/core/workflow-reference-guard.test.ts": true,
|
|
8501
|
+
"tests/unit/detection/cdk-app-shape.test.ts": true,
|
|
8497
8502
|
"tests/unit/detection/detectors.test.ts": true,
|
|
8498
8503
|
"tests/unit/docs/onboarding-walkthrough.test.ts": true,
|
|
8499
8504
|
"tests/unit/governance-contracts.test.ts": true,
|