sela-core 1.0.8 → 1.0.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (67) hide show
  1. package/README.md +27 -17
  2. package/dist/cli/commands/init.js +1 -1
  3. package/dist/cli/commands/merge.d.ts +13 -0
  4. package/dist/cli/commands/merge.d.ts.map +1 -0
  5. package/dist/cli/commands/merge.js +119 -0
  6. package/dist/cli/index.js +4 -1
  7. package/dist/config/SelaConfig.d.ts +1 -1
  8. package/dist/config/SelaConfig.d.ts.map +1 -1
  9. package/dist/config/SelaConfig.js +1 -1
  10. package/dist/engine/SelaEngine.d.ts.map +1 -1
  11. package/dist/engine/SelaEngine.js +54 -2
  12. package/dist/errors/SelaError.d.ts +8 -0
  13. package/dist/errors/SelaError.d.ts.map +1 -1
  14. package/dist/errors/SelaError.js +8 -0
  15. package/dist/fixtures/expectProxy.d.ts +1 -1
  16. package/dist/fixtures/expectProxy.js +6 -6
  17. package/dist/fixtures/index.d.ts +18 -2
  18. package/dist/fixtures/index.d.ts.map +1 -1
  19. package/dist/fixtures/index.js +34 -14
  20. package/dist/fixtures/moduleExpect.js +7 -7
  21. package/dist/fixtures/proxyTag.js +1 -1
  22. package/dist/services/ASTSourceUpdater.d.ts +45 -0
  23. package/dist/services/ASTSourceUpdater.d.ts.map +1 -1
  24. package/dist/services/ASTSourceUpdater.js +201 -47
  25. package/dist/services/AnchorResolver.d.ts +157 -0
  26. package/dist/services/AnchorResolver.d.ts.map +1 -0
  27. package/dist/services/AnchorResolver.js +289 -0
  28. package/dist/services/DecisionEngine.d.ts +51 -0
  29. package/dist/services/DecisionEngine.d.ts.map +1 -0
  30. package/dist/services/DecisionEngine.js +260 -0
  31. package/dist/services/HealReportService.d.ts +31 -55
  32. package/dist/services/HealReportService.d.ts.map +1 -1
  33. package/dist/services/HealReportService.js +863 -1243
  34. package/dist/services/HealingAdvisory.d.ts +9 -1
  35. package/dist/services/HealingAdvisory.d.ts.map +1 -1
  36. package/dist/services/HealingAdvisory.js +8 -0
  37. package/dist/services/InitializerUpdater.d.ts.map +1 -1
  38. package/dist/services/InitializerUpdater.js +10 -0
  39. package/dist/services/InteractiveReview.d.ts.map +1 -1
  40. package/dist/services/InteractiveReview.js +4 -1
  41. package/dist/services/MutationApplier.d.ts +55 -0
  42. package/dist/services/MutationApplier.d.ts.map +1 -0
  43. package/dist/services/MutationApplier.js +322 -0
  44. package/dist/services/PendingPromptLedger.d.ts +7 -0
  45. package/dist/services/PendingPromptLedger.d.ts.map +1 -1
  46. package/dist/services/PendingPromptLedger.js +25 -0
  47. package/dist/services/ReportGenerator.d.ts +116 -30
  48. package/dist/services/ReportGenerator.d.ts.map +1 -1
  49. package/dist/services/ReportGenerator.js +150 -63
  50. package/dist/services/ReportMergeService.d.ts +95 -0
  51. package/dist/services/ReportMergeService.d.ts.map +1 -0
  52. package/dist/services/ReportMergeService.js +0 -0
  53. package/dist/services/SafetyGuard.d.ts +1 -1
  54. package/dist/services/SafetyGuard.d.ts.map +1 -1
  55. package/dist/services/SelectorSanitizer.d.ts +52 -0
  56. package/dist/services/SelectorSanitizer.d.ts.map +1 -0
  57. package/dist/services/SelectorSanitizer.js +318 -0
  58. package/dist/services/SnapshotService.js +1 -1
  59. package/dist/services/SourceUpdater.d.ts.map +1 -1
  60. package/dist/services/SourceUpdater.js +17 -0
  61. package/dist/services/TraceBackEngine.d.ts +67 -0
  62. package/dist/services/TraceBackEngine.d.ts.map +1 -0
  63. package/dist/services/TraceBackEngine.js +672 -0
  64. package/dist/utils/DOMUtils.d.ts +18 -2
  65. package/dist/utils/DOMUtils.d.ts.map +1 -1
  66. package/dist/utils/DOMUtils.js +335 -49
  67. package/package.json +1 -1
@@ -0,0 +1,260 @@
1
+ "use strict";
2
+ // src/services/DecisionEngine.ts
3
+ //
4
+ // Ticket #2 — Stage 3: The Decision Tree & Multi-Consumer Forking.
5
+ //
6
+ // Final semantic phase. Given a trace-back TARGET (Stage 2) + the proposed
7
+ // healed locator expression + runtime evidence, decide HOW to write it:
8
+ //
9
+ // refsToDecl <= 1 ............................. MUTATE_IN_PLACE
10
+ // refsToDecl > 1 & globalCorrect ............. MUTATE_IN_PLACE (all rot)
11
+ // refsToDecl > 1 & contextSpecific ........... FORK_AT_TEST
12
+ // refsToDecl > 1 & scope undeterminable ...... PROMPT_INTERACTIVE
13
+ //
14
+ // FORK_AT_TEST injects a collision-safe shadowing `const <name> = <expr>;`
15
+ // at the top of the FAILING test's block so the other consumers of the
16
+ // shared declaration (e.g. a `beforeEach` locator used by 4 other passing
17
+ // tests) are left untouched. Same-name shadow keeps the call-site intact;
18
+ // a real name collision falls back to a fresh name + a call-site rewrite.
19
+ //
20
+ // Reference census is delegated to BlastRadiusAnalyzer (cross-file accurate
21
+ // via the ts-morph language service) — we do not re-implement findReferences.
22
+ //
23
+ // PURE: produces an edit plan; never writes to disk.
24
+ Object.defineProperty(exports, "__esModule", { value: true });
25
+ exports.DecisionEngine = void 0;
26
+ exports.findEnclosingTestBlock = findEnclosingTestBlock;
27
+ exports.applyEdits = applyEdits;
28
+ const ts_morph_1 = require("ts-morph");
29
+ const BlastRadiusAnalyzer_1 = require("./BlastRadiusAnalyzer");
30
+ const TraceBackEngine_1 = require("./TraceBackEngine");
31
+ // ═══════════════════════════════════════════════════════════════════
32
+ // DecisionEngine
33
+ // ═══════════════════════════════════════════════════════════════════
34
+ class DecisionEngine {
35
+ static decide(input) {
36
+ const { target, newLocatorExpr } = input;
37
+ // Inline call-site or non-declaration target: the call-site is unique,
38
+ // there is nothing to share → mutate in place.
39
+ if (target.declKind === "InlineCallSite" || !target.declaration) {
40
+ return mutateInPlace(target, newLocatorExpr, 1, 1, "inline call-site");
41
+ }
42
+ // Reference census (delegated, cross-file accurate).
43
+ const { totalReferences, consumerTests } = census(target);
44
+ // ── refs <= 1 → safe global mutation ────────────────────────────
45
+ if (totalReferences <= 1) {
46
+ return mutateInPlace(target, newLocatorExpr, totalReferences, consumerTests, `single consumer (refs=${totalReferences})`);
47
+ }
48
+ // ── refs > 1 → multi-consumer ───────────────────────────────────
49
+ if (input.globalCorrect) {
50
+ return mutateInPlace(target, newLocatorExpr, totalReferences, consumerTests, `multi-consumer but selector rot is global (refs=${totalReferences})`, 0.85);
51
+ }
52
+ if (input.contextSpecific) {
53
+ const fork = buildFork(input, totalReferences, consumerTests);
54
+ if (fork)
55
+ return fork;
56
+ // Could not locate a test block to fork into → escalate.
57
+ return promptInteractive(target, totalReferences, consumerTests, "context-specific fix but no enclosing test block to fork into");
58
+ }
59
+ // Scope undeterminable → never silently break the other consumers.
60
+ return promptInteractive(target, totalReferences, consumerTests, `multi-consumer (refs=${totalReferences}) and scope undeterminable — global-vs-fork needs a human`);
61
+ }
62
+ }
63
+ exports.DecisionEngine = DecisionEngine;
64
+ // ═══════════════════════════════════════════════════════════════════
65
+ // REFERENCE CENSUS
66
+ // ═══════════════════════════════════════════════════════════════════
67
+ function census(target) {
68
+ const decl = target.declaration;
69
+ try {
70
+ const report = BlastRadiusAnalyzer_1.BlastRadiusAnalyzer.analyze(decl, decl.getSourceFile(), decl.getProject());
71
+ return {
72
+ totalReferences: report.totalReferences,
73
+ consumerTests: report.testFunctionCount,
74
+ };
75
+ }
76
+ catch {
77
+ // Census failure must not crash the pipeline; treat as single-consumer
78
+ // (the conservative MUTATE_IN_PLACE path the caller can still gate).
79
+ return { totalReferences: 1, consumerTests: 1 };
80
+ }
81
+ }
82
+ // ═══════════════════════════════════════════════════════════════════
83
+ // PLAN BUILDERS
84
+ // ═══════════════════════════════════════════════════════════════════
85
+ function mutateInPlace(target, newLocatorExpr, blastRadius, consumerTests, reason, confidence = 0.9) {
86
+ return {
87
+ strategy: "MUTATE_IN_PLACE",
88
+ reason,
89
+ blastRadius,
90
+ consumerTests,
91
+ confidence,
92
+ anchor: target.anchor,
93
+ edits: [
94
+ {
95
+ kind: "replace",
96
+ span: {
97
+ start: target.targetNode.getStart(),
98
+ end: target.targetNode.getEnd(),
99
+ },
100
+ replacement: newLocatorExpr,
101
+ },
102
+ ],
103
+ };
104
+ }
105
+ function promptInteractive(target, blastRadius, consumerTests, reason) {
106
+ return {
107
+ strategy: "PROMPT_INTERACTIVE",
108
+ reason,
109
+ blastRadius,
110
+ consumerTests,
111
+ confidence: 0.4,
112
+ anchor: target.anchor,
113
+ edits: [], // no auto-edit; the CLI prompts the user
114
+ };
115
+ }
116
+ function buildFork(input, blastRadius, consumerTests) {
117
+ const { target, failingCallSite, newLocatorExpr } = input;
118
+ const testBlock = findEnclosingTestBlock(failingCallSite);
119
+ if (!testBlock)
120
+ return null;
121
+ const baseName = target.symbolName ?? "healedLocator";
122
+ // Collision-safe shadow naming. A plain block-scoped `const` of the SAME
123
+ // name legally shadows the outer (beforeEach/describe) declaration and the
124
+ // call-site needs no rewrite. Only when the failing test block ALREADY
125
+ // declares that name locally do we need a fresh name + call-site rewrite.
126
+ const localNames = collectBlockLocalNames(testBlock);
127
+ let forkVarName = baseName;
128
+ let needsCallSiteRewrite = false;
129
+ if (localNames.has(baseName)) {
130
+ forkVarName = freshName(baseName, localNames);
131
+ needsCallSiteRewrite = true;
132
+ }
133
+ const edits = [];
134
+ // 1. Insert the shadow declaration at the top of the test block.
135
+ const stmts = testBlock.getStatements();
136
+ const indent = stmts[0]?.getIndentationText() ?? " ";
137
+ const insertPos = stmts[0]
138
+ ? stmts[0].getStart()
139
+ : testBlock.getStart() + 1; // just after the `{`
140
+ const insertText = stmts[0]
141
+ ? `const ${forkVarName} = ${newLocatorExpr};\n${indent}`
142
+ : `\n${indent}const ${forkVarName} = ${newLocatorExpr};\n`;
143
+ edits.push({
144
+ kind: "insert",
145
+ span: { start: insertPos, end: insertPos },
146
+ replacement: insertText,
147
+ });
148
+ // 2. If we had to rename, rewrite the failing call-site receiver.
149
+ if (needsCallSiteRewrite) {
150
+ const top = (0, TraceBackEngine_1.climbToTopCall)(failingCallSite);
151
+ if (top) {
152
+ const { leftmost } = (0, TraceBackEngine_1.getLeftmostReceiver)(top);
153
+ if (ts_morph_1.Node.isIdentifier(leftmost) && leftmost.getText() === baseName) {
154
+ edits.push({
155
+ kind: "replace",
156
+ span: { start: leftmost.getStart(), end: leftmost.getEnd() },
157
+ replacement: forkVarName,
158
+ });
159
+ }
160
+ }
161
+ }
162
+ return {
163
+ strategy: "FORK_AT_TEST",
164
+ reason: `multi-consumer (refs=${blastRadius}, tests=${consumerTests}); context-specific fix forked into the failing test as "${forkVarName}"`,
165
+ blastRadius,
166
+ consumerTests,
167
+ confidence: 0.75,
168
+ forkVarName,
169
+ anchor: target.anchor,
170
+ edits,
171
+ };
172
+ }
173
+ // ═══════════════════════════════════════════════════════════════════
174
+ // TEST-BLOCK / SCOPE HELPERS
175
+ // ═══════════════════════════════════════════════════════════════════
176
+ /**
177
+ * The Block of the nearest enclosing `test(...)` / `it(...)` callback. Hooks
178
+ * (`beforeEach`, etc.) are intentionally NOT matched — we fork into the test
179
+ * that failed, never into the shared hook.
180
+ */
181
+ function findEnclosingTestBlock(node) {
182
+ let cur = node;
183
+ while (cur) {
184
+ if (ts_morph_1.Node.isCallExpression(cur) && isTestCall(cur)) {
185
+ for (const arg of cur.getArguments()) {
186
+ if (ts_morph_1.Node.isArrowFunction(arg) || ts_morph_1.Node.isFunctionExpression(arg)) {
187
+ const body = arg.getBody();
188
+ if (body && ts_morph_1.Node.isBlock(body))
189
+ return body;
190
+ }
191
+ }
192
+ }
193
+ cur = cur.getParent();
194
+ }
195
+ return null;
196
+ }
197
+ function isTestCall(call) {
198
+ if (!ts_morph_1.Node.isCallExpression(call))
199
+ return false;
200
+ const expr = call.getExpression();
201
+ const base = ts_morph_1.Node.isPropertyAccessExpression(expr)
202
+ ? expr.getExpression().getText()
203
+ : expr.getText();
204
+ return base === "test" || base === "it";
205
+ }
206
+ /** Names declared LOCALLY in this block (top-level var statements + fns). */
207
+ function collectBlockLocalNames(block) {
208
+ const names = new Set();
209
+ for (const stmt of block.getStatements()) {
210
+ if (ts_morph_1.Node.isVariableStatement(stmt)) {
211
+ for (const d of stmt.getDeclarations()) {
212
+ const n = d.getNameNode();
213
+ if (ts_morph_1.Node.isIdentifier(n))
214
+ names.add(n.getText());
215
+ }
216
+ }
217
+ else if (ts_morph_1.Node.isFunctionDeclaration(stmt)) {
218
+ const nm = stmt.getName();
219
+ if (nm)
220
+ names.add(nm);
221
+ }
222
+ }
223
+ return names;
224
+ }
225
+ function freshName(base, taken) {
226
+ const candidate = `${base}Healed`;
227
+ if (!taken.has(candidate))
228
+ return candidate;
229
+ let i = 2;
230
+ while (taken.has(`${candidate}${i}`))
231
+ i++;
232
+ return `${candidate}${i}`;
233
+ }
234
+ // ═══════════════════════════════════════════════════════════════════
235
+ // PURE EDIT APPLICATION (used by callers + tests)
236
+ // ═══════════════════════════════════════════════════════════════════
237
+ /**
238
+ * Apply edits to `original`, highest offset first so earlier offsets stay
239
+ * valid (the reverse-offset rule from the concurrency design §3.3.4).
240
+ * Throws on overlapping replace spans — never produces torn text.
241
+ */
242
+ function applyEdits(original, edits) {
243
+ const sorted = [...edits].sort((a, b) => b.span.start - a.span.start);
244
+ for (let i = 1; i < sorted.length; i++) {
245
+ const prev = sorted[i - 1];
246
+ const cur = sorted[i];
247
+ // prev.start >= cur.start (desc). Overlap if cur.end > prev.start AND
248
+ // both are replacements (inserts are zero-width and may share a point).
249
+ if (cur.span.end > prev.span.start &&
250
+ prev.kind === "replace" &&
251
+ cur.kind === "replace") {
252
+ throw new Error(`[DecisionEngine] overlapping edits at ${cur.span.start}..${cur.span.end} and ${prev.span.start}..${prev.span.end}`);
253
+ }
254
+ }
255
+ let text = original;
256
+ for (const e of sorted) {
257
+ text = text.slice(0, e.span.start) + e.replacement + text.slice(e.span.end);
258
+ }
259
+ return text;
260
+ }
@@ -1,5 +1,6 @@
1
1
  import type { AuditVerdict, AuditVerdictValue } from "./IntentAuditor";
2
2
  import type { ElementSnapshotV2 } from "../types";
3
+ import { type ReportData } from "./ReportGenerator";
3
4
  export type HealEventKind = "HEALED" | "FAILED" | "PROTECTED";
4
5
  export interface DnaSummary {
5
6
  tagName: string;
@@ -17,10 +18,6 @@ export interface DnaSummary {
17
18
  }
18
19
  export interface AuditorBlock {
19
20
  verdict: AuditVerdictValue;
20
- /**
21
- * Adjusted confidence 0-100. `undefined` when the auditor produced no score
22
- * (e.g. SafetyGuard bypassed it) - reports MUST render this as "n/a".
23
- */
24
21
  confidence?: number;
25
22
  reason: string;
26
23
  inversionType: AuditVerdict["inversionType"];
@@ -41,30 +38,13 @@ interface HealEventBase {
41
38
  }
42
39
  export interface HealedEvent extends HealEventBase {
43
40
  kind: "HEALED";
44
- /**
45
- * Marks events produced during a `SELA_DRY_RUN=1` session - the in-memory
46
- * heal completed (LLM call, SafetyGuard verdict, candidate diff captured)
47
- * but no source file was modified and no commit was produced. Reports
48
- * render these with an explicit "Dry Run · No Write" chip.
49
- */
50
41
  dryRun?: boolean;
51
42
  oldSelector: string;
52
43
  newSelector: string;
53
- /** First removed line from the native git diff (backward-compat fallback). */
54
44
  oldCodeLine: string;
55
- /** First added line from the native git diff (backward-compat fallback). */
56
45
  newCodeLine: string;
57
46
  newLineNumber: number;
58
- /**
59
- * Raw `git diff --unified=1` output captured immediately after the AST
60
- * mutation hit disk and BEFORE any `git add`. Includes headers (---/+++)
61
- * and one or more @@ hunks. Renderers strip headers; PR body emits the
62
- * hunks verbatim inside a ```diff fence so cross-file healing, multi-line
63
- * edits, and template-literal changes are all displayed natively without
64
- * any in-process line-index math.
65
- */
66
47
  gitUnifiedDiff?: string;
67
- /** AI-reported confidence 0-100. `undefined` when the model omitted it. */
68
48
  aiConfidence?: number;
69
49
  aiExplanation: string;
70
50
  aiAlternatives: string[];
@@ -90,15 +70,6 @@ export interface FailedEvent extends HealEventBase {
90
70
  aiConfidence?: number;
91
71
  aiExplanation?: string;
92
72
  dnaBefore: DnaSummary | null;
93
- /**
94
- * Base64-encoded PNG screenshot captured by `SelaReporter` from the
95
- * Playwright `TestResult.attachments` slot at the moment the test
96
- * failed. NEVER prefixed with `data:image/png;base64,` - the HTML
97
- * renderer prepends the data URL header at render time so the JSON
98
- * payload stays compact and the bytes survive Playwright's temp
99
- * folder cleanup. `undefined` when no screenshot was attached
100
- * (worker crash, screenshot disabled, off-attachment failure).
101
- */
102
73
  failureScreenshotPng?: string;
103
74
  }
104
75
  export interface ProtectedEvent extends HealEventBase {
@@ -108,7 +79,6 @@ export interface ProtectedEvent extends HealEventBase {
108
79
  reason: string;
109
80
  safetyLevel: string;
110
81
  auditor: AuditorBlock | null;
111
- /** AI-reported confidence 0-100. `undefined` when the model omitted it. */
112
82
  aiConfidence?: number;
113
83
  aiExplanation: string;
114
84
  dnaBefore: DnaSummary | null;
@@ -127,42 +97,48 @@ export declare class HealReportService {
127
97
  size(): number;
128
98
  clear(): void;
129
99
  hasContent(): boolean;
130
- /** All HEALED events accumulated in this session. */
131
100
  getHealedEvents(): HealedEvent[];
132
- /** All PROTECTED events (SafetyGuard blocks) accumulated in this session. */
133
101
  getProtectedEvents(): ProtectedEvent[];
134
- /** All FAILED events accumulated in this session. */
135
102
  getFailedEvents(): FailedEvent[];
136
103
  /**
137
- * Inject a Playwright failure screenshot (Base64 PNG, no data: prefix)
138
- * onto the FAILED event(s) matching the supplied identity hints. Used
139
- * by `SelaReporter` to enrich engine-emitted FAILED events with the
140
- * Playwright-captured screenshot from `TestResult.attachments`.
141
- *
142
- * Match policy (all supplied hints must agree):
143
- * • `sourceFile` - suffix-matched both directions to absorb
144
- * project-relative vs absolute path mismatches between the engine
145
- * (relative) and Playwright TestInfo.location.file (absolute).
146
- * • `testTitle` - exact match.
147
- * • `stableId` - exact match.
148
- *
149
- * Returns the number of events updated. Zero means the caller should
150
- * keep the screenshot pending until the matching FailedEvent is
151
- * recorded (worker-crash edge case where the heal pipeline did not
152
- * run before the Reporter received the failure).
104
+ * Attach a Playwright failure screenshot (Base64 PNG, no data: prefix)
105
+ * onto the FAILED event(s) matching the supplied identity hints.
106
+ * Returns the number of events updated.
153
107
  */
154
108
  attachFailureScreenshot(match: {
155
109
  sourceFile?: string;
156
110
  testTitle?: string;
157
111
  stableId?: string;
158
112
  }, base64Png: string): number;
113
+ private readHistory;
114
+ private writeHistory;
115
+ /**
116
+ * Generate and write `sela-report.html` + `sela-report.json` to targetDir.
117
+ * Also updates `.sela-history.json` with the current run's stats.
118
+ * Returns the absolute path of the HTML report, or null when there is
119
+ * nothing to write.
120
+ */
121
+ flushToDisk(targetDir?: string, opts?: {
122
+ runId?: string;
123
+ }): string | null;
159
124
  /**
160
- * Write `sela-report.html` (+ `sela-report.json` debug dump) to cwd.
161
- * Returns the absolute path of the HTML report, or null if nothing to write.
125
+ * Render and persist a pre-computed {@link ReportData} payload to `targetDir`:
126
+ * `.sela-history.json` (the rolling window from `data.historical_runs`)
127
+ * • `sela-report.html` (the embedded dashboard)
128
+ * • `sela-report.json` (the raw payload for CI consumers)
129
+ *
130
+ * Extracted from {@link flushToDisk} so the CI merge path
131
+ * (`ReportMergeService`) writes a shard-aggregated report through the exact
132
+ * same rendering / serialisation logic — no duplication.
133
+ *
134
+ * Unlike `flushToDisk`, this writes unconditionally: an empty-event payload
135
+ * still produces a report and a `healed:0` history row. That is the desired
136
+ * CI behaviour — a clean, zero-heal pipeline is a healthy data point that
137
+ * must keep the trend chart's x-axis cadence intact.
138
+ *
139
+ * Returns the absolute path of the written HTML report.
162
140
  */
163
- flushToDisk(targetDir?: string): string | null;
164
- private renderHtml;
165
- private computeStats;
141
+ writeReportData(targetDir: string, data: ReportData): string;
166
142
  }
167
143
  export declare const sharedHealReport: HealReportService;
168
144
  export {};
@@ -1 +1 @@
1
- {"version":3,"file":"HealReportService.d.ts","sourceRoot":"","sources":["../../src/services/HealReportService.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"HealReportService.d.ts","sourceRoot":"","sources":["../../src/services/HealReportService.ts"],"names":[],"mappings":"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"}