sela-core 1.0.7 → 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.
- package/README.md +27 -17
- package/dist/cli/ErrorHandler.d.ts +1 -1
- package/dist/cli/ErrorHandler.js +14 -14
- package/dist/cli/commands/bulk.d.ts +1 -1
- package/dist/cli/commands/bulk.d.ts.map +1 -1
- package/dist/cli/commands/bulk.js +51 -33
- package/dist/cli/commands/init.d.ts +1 -1
- package/dist/cli/commands/init.d.ts.map +1 -1
- package/dist/cli/commands/init.js +26 -18
- package/dist/cli/commands/merge.d.ts +13 -0
- package/dist/cli/commands/merge.d.ts.map +1 -0
- package/dist/cli/commands/merge.js +119 -0
- package/dist/cli/commands/showReport.d.ts +1 -1
- package/dist/cli/commands/showReport.d.ts.map +1 -1
- package/dist/cli/commands/showReport.js +12 -10
- package/dist/cli/commands/status.d.ts +1 -1
- package/dist/cli/commands/status.d.ts.map +1 -1
- package/dist/cli/commands/status.js +8 -8
- package/dist/cli/commands/sync.d.ts +1 -1
- package/dist/cli/commands/sync.d.ts.map +1 -1
- package/dist/cli/commands/sync.js +38 -30
- package/dist/cli/index.js +12 -9
- package/dist/cli/ui/DnaTable.d.ts +1 -1
- package/dist/cli/ui/DnaTable.d.ts.map +1 -1
- package/dist/cli/ui/DnaTable.js +23 -16
- package/dist/cli/ui/RefactorWizard.d.ts +3 -3
- package/dist/cli/ui/RefactorWizard.d.ts.map +1 -1
- package/dist/cli/ui/RefactorWizard.js +108 -82
- package/dist/config/ConfigLoader.d.ts +2 -2
- package/dist/config/ConfigLoader.d.ts.map +1 -1
- package/dist/config/ConfigLoader.js +15 -15
- package/dist/config/DryRunGuard.d.ts +1 -1
- package/dist/config/DryRunGuard.js +7 -7
- package/dist/config/SelaConfig.d.ts +13 -17
- package/dist/config/SelaConfig.d.ts.map +1 -1
- package/dist/config/SelaConfig.js +32 -26
- package/dist/engine/HealingRegistry.d.ts +1 -1
- package/dist/engine/HealingRegistry.js +3 -3
- package/dist/engine/SelaEngine.d.ts +1 -1
- package/dist/engine/SelaEngine.d.ts.map +1 -1
- package/dist/engine/SelaEngine.js +117 -51
- package/dist/errors/SelaError.d.ts +8 -1
- package/dist/errors/SelaError.d.ts.map +1 -1
- package/dist/errors/SelaError.js +14 -7
- package/dist/fixtures/expectProxy.d.ts +2 -2
- package/dist/fixtures/expectProxy.js +16 -16
- package/dist/fixtures/index.d.ts +18 -2
- package/dist/fixtures/index.d.ts.map +1 -1
- package/dist/fixtures/index.js +47 -27
- package/dist/fixtures/moduleExpect.js +7 -7
- package/dist/fixtures/proxyTag.d.ts +1 -1
- package/dist/fixtures/proxyTag.js +4 -4
- package/dist/index.d.ts +8 -8
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -4
- package/dist/reporter/SelaReporter.d.ts +45 -12
- package/dist/reporter/SelaReporter.d.ts.map +1 -1
- package/dist/reporter/SelaReporter.js +139 -39
- package/dist/services/ASTSourceUpdater.d.ts +48 -3
- package/dist/services/ASTSourceUpdater.d.ts.map +1 -1
- package/dist/services/ASTSourceUpdater.js +283 -105
- package/dist/services/AnchorResolver.d.ts +157 -0
- package/dist/services/AnchorResolver.d.ts.map +1 -0
- package/dist/services/AnchorResolver.js +289 -0
- package/dist/services/ArgumentTypeAnalyzer.js +7 -7
- package/dist/services/BlastRadiusAnalyzer.d.ts.map +1 -1
- package/dist/services/BlastRadiusAnalyzer.js +5 -2
- package/dist/services/ChainValidator.js +22 -22
- package/dist/services/CrossFileHealer.js +7 -7
- package/dist/services/DecisionEngine.d.ts +51 -0
- package/dist/services/DecisionEngine.d.ts.map +1 -0
- package/dist/services/DecisionEngine.js +260 -0
- package/dist/services/DefinitionTracer.d.ts +1 -1
- package/dist/services/DefinitionTracer.d.ts.map +1 -1
- package/dist/services/DefinitionTracer.js +28 -13
- package/dist/services/DnaEditorService.d.ts +2 -2
- package/dist/services/DnaEditorService.d.ts.map +1 -1
- package/dist/services/DnaEditorService.js +81 -62
- package/dist/services/DnaIndexService.d.ts +1 -1
- package/dist/services/DnaIndexService.d.ts.map +1 -1
- package/dist/services/DnaIndexService.js +14 -14
- package/dist/services/HealReportService.d.ts +31 -55
- package/dist/services/HealReportService.d.ts.map +1 -1
- package/dist/services/HealReportService.js +864 -1240
- package/dist/services/HealingAdvisory.d.ts +9 -1
- package/dist/services/HealingAdvisory.d.ts.map +1 -1
- package/dist/services/HealingAdvisory.js +9 -1
- package/dist/services/HealingCacheService.d.ts +8 -8
- package/dist/services/HealingCacheService.d.ts.map +1 -1
- package/dist/services/HealingCacheService.js +24 -24
- package/dist/services/HealthReportService.d.ts +1 -1
- package/dist/services/HealthReportService.d.ts.map +1 -1
- package/dist/services/HealthReportService.js +25 -25
- package/dist/services/InitializerUpdater.d.ts.map +1 -1
- package/dist/services/InitializerUpdater.js +12 -2
- package/dist/services/IntentAuditor.d.ts.map +1 -1
- package/dist/services/IntentAuditor.js +32 -21
- package/dist/services/InteractiveReview.d.ts +8 -17
- package/dist/services/InteractiveReview.d.ts.map +1 -1
- package/dist/services/InteractiveReview.js +34 -124
- package/dist/services/LLMService.d.ts +1 -1
- package/dist/services/LLMService.js +16 -16
- package/dist/services/MutationApplier.d.ts +55 -0
- package/dist/services/MutationApplier.d.ts.map +1 -0
- package/dist/services/MutationApplier.js +322 -0
- package/dist/services/PRAutomationService.d.ts +2 -2
- package/dist/services/PRAutomationService.d.ts.map +1 -1
- package/dist/services/PRAutomationService.js +43 -39
- package/dist/services/PendingPromptLedger.d.ts +9 -2
- package/dist/services/PendingPromptLedger.d.ts.map +1 -1
- package/dist/services/PendingPromptLedger.js +31 -6
- package/dist/services/ReportGenerator.d.ts +116 -30
- package/dist/services/ReportGenerator.d.ts.map +1 -1
- package/dist/services/ReportGenerator.js +149 -62
- package/dist/services/ReportMergeService.d.ts +95 -0
- package/dist/services/ReportMergeService.d.ts.map +1 -0
- package/dist/services/ReportMergeService.js +0 -0
- package/dist/services/SafetyGuard.d.ts +4 -7
- package/dist/services/SafetyGuard.d.ts.map +1 -1
- package/dist/services/SafetyGuard.js +29 -106
- package/dist/services/SelectorSanitizer.d.ts +52 -0
- package/dist/services/SelectorSanitizer.d.ts.map +1 -0
- package/dist/services/SelectorSanitizer.js +318 -0
- package/dist/services/SnapshotService.js +6 -6
- package/dist/services/SourceLinkService.d.ts +2 -2
- package/dist/services/SourceLinkService.d.ts.map +1 -1
- package/dist/services/SourceLinkService.js +31 -22
- package/dist/services/SourceUpdater.d.ts +1 -1
- package/dist/services/SourceUpdater.d.ts.map +1 -1
- package/dist/services/SourceUpdater.js +44 -26
- package/dist/services/TemplateDiffService.d.ts.map +1 -1
- package/dist/services/TemplateDiffService.js +18 -15
- package/dist/services/TraceBackEngine.d.ts +67 -0
- package/dist/services/TraceBackEngine.d.ts.map +1 -0
- package/dist/services/TraceBackEngine.js +672 -0
- package/dist/services/WorkspaceSnapshotService.d.ts +6 -6
- package/dist/services/WorkspaceSnapshotService.d.ts.map +1 -1
- package/dist/services/WorkspaceSnapshotService.js +10 -12
- package/dist/types/index.d.ts +1 -1
- package/dist/utils/DOMUtils.d.ts +18 -2
- package/dist/utils/DOMUtils.d.ts.map +1 -1
- package/dist/utils/DOMUtils.js +335 -49
- package/dist/utils/IsolatedDiff.d.ts +2 -2
- package/dist/utils/IsolatedDiff.d.ts.map +1 -1
- package/dist/utils/IsolatedDiff.js +13 -10
- package/package.json +2 -2
|
@@ -2,7 +2,7 @@ import type { Reporter, TestCase, TestResult, FullConfig, Suite, FullResult } fr
|
|
|
2
2
|
import { HealReportService } from "../services/HealReportService.js";
|
|
3
3
|
import type { SelaEngine } from "../engine/SelaEngine.js";
|
|
4
4
|
import { type PendingPromptEntry } from "../services/PendingPromptLedger.js";
|
|
5
|
-
import { type
|
|
5
|
+
import { type PrintReviewDeps } from "../services/InteractiveReview.js";
|
|
6
6
|
export interface ReporterEngine {
|
|
7
7
|
commitUpdates(): Promise<void>;
|
|
8
8
|
}
|
|
@@ -27,22 +27,34 @@ export interface SelaReporterOpts {
|
|
|
27
27
|
/** Override cwd used to locate the pending-prompts ledger. Defaults to process.cwd(). */
|
|
28
28
|
cwd?: string;
|
|
29
29
|
/**
|
|
30
|
-
* Inject the ledger reader
|
|
30
|
+
* Inject the ledger reader - tests stub this so they don't have to
|
|
31
31
|
* touch the real filesystem.
|
|
32
32
|
*/
|
|
33
33
|
readLedger?: (cwd: string) => PendingPromptEntry[];
|
|
34
34
|
/** Inject the ledger cleaner. */
|
|
35
35
|
clearLedger?: (cwd: string) => void;
|
|
36
36
|
/**
|
|
37
|
-
* Inject the
|
|
38
|
-
*
|
|
37
|
+
* Inject the review printer. Tests stub this to assert that the
|
|
38
|
+
* reporter wires the ledger entries + HTML report path through unchanged.
|
|
39
39
|
*/
|
|
40
|
-
|
|
40
|
+
printReview?: (deps: PrintReviewDeps) => void;
|
|
41
41
|
/**
|
|
42
|
-
* Override the
|
|
43
|
-
*
|
|
42
|
+
* Override the resolution of the HTML report path. Returns `null` when
|
|
43
|
+
* no report exists. Defaults to `<cwd>/sela-report.html` when the file
|
|
44
|
+
* is on disk.
|
|
45
|
+
*/
|
|
46
|
+
resolveReportPath?: (cwd: string) => string | null;
|
|
47
|
+
/**
|
|
48
|
+
* Override the CI detection - true means "behave as CI" (skip the
|
|
49
|
+
* post-run notify). Defaults to checking `process.env.CI`.
|
|
44
50
|
*/
|
|
45
51
|
isCi?: () => boolean;
|
|
52
|
+
/**
|
|
53
|
+
* Install process-level SIGINT/SIGTERM handlers in onBegin. Defaults
|
|
54
|
+
* to true. Tests pass `false` so vitest's own signal lifecycle isn't
|
|
55
|
+
* polluted by leftover handlers between cases.
|
|
56
|
+
*/
|
|
57
|
+
installSignalHandlers?: boolean;
|
|
46
58
|
}
|
|
47
59
|
export declare class SelaReporter implements Reporter {
|
|
48
60
|
private readonly engine;
|
|
@@ -52,8 +64,12 @@ export declare class SelaReporter implements Reporter {
|
|
|
52
64
|
private readonly cwd;
|
|
53
65
|
private readonly readLedger;
|
|
54
66
|
private readonly clearLedger;
|
|
55
|
-
private readonly
|
|
67
|
+
private readonly printReview;
|
|
68
|
+
private readonly resolveReportPath;
|
|
56
69
|
private readonly isCi;
|
|
70
|
+
private readonly shouldInstallSignalHandlers;
|
|
71
|
+
private shutdownHandler;
|
|
72
|
+
private shuttingDown;
|
|
57
73
|
/**
|
|
58
74
|
* Screenshots that arrived before a matching FailedEvent existed in
|
|
59
75
|
* the shared report. Re-flushed once at onEnd time so worker-crash
|
|
@@ -73,19 +89,36 @@ export declare class SelaReporter implements Reporter {
|
|
|
73
89
|
onBegin(_config?: FullConfig, _suite?: Suite): void;
|
|
74
90
|
onTestEnd(test: TestCase, result: TestResult): void;
|
|
75
91
|
onEnd(_result?: FullResult): Promise<void>;
|
|
76
|
-
/** Reporter prints nothing of its own
|
|
92
|
+
/** Reporter prints nothing of its own - Playwright stdio stays clean. */
|
|
77
93
|
printsToStdio(): boolean;
|
|
94
|
+
/**
|
|
95
|
+
* Install the SIGINT/SIGTERM listener once per reporter. First signal
|
|
96
|
+
* triggers an orderly drain; second signal hard-exits with code 130
|
|
97
|
+
* (SIGINT) / 143 (SIGTERM) so the user can always escape if the drain
|
|
98
|
+
* itself wedges (e.g. a stuck LLM call).
|
|
99
|
+
*/
|
|
100
|
+
private installShutdownHandler;
|
|
101
|
+
private uninstallShutdownHandler;
|
|
102
|
+
/**
|
|
103
|
+
* Best-effort drain on signal. Mirrors the orderly onEnd path but
|
|
104
|
+
* swallows every error - we never want to throw inside a signal
|
|
105
|
+
* handler because Node prints raw stack traces otherwise.
|
|
106
|
+
*
|
|
107
|
+
* Exposed for tests so they can drive the shutdown without raising
|
|
108
|
+
* a real signal in the vitest process.
|
|
109
|
+
*/
|
|
110
|
+
gracefulShutdown(): Promise<void>;
|
|
78
111
|
/**
|
|
79
112
|
* Walk every buffered pending screenshot and try to attach it to a
|
|
80
113
|
* now-existing FailedEvent. Successfully-attached entries are
|
|
81
114
|
* removed; unmatched entries are dropped (the matching FailedEvent
|
|
82
|
-
* never arrived
|
|
115
|
+
* never arrived - most likely worker crashed before the engine
|
|
83
116
|
* could record one).
|
|
84
117
|
*
|
|
85
118
|
* Returns the number of FailedEvents touched.
|
|
86
119
|
*/
|
|
87
120
|
flushPendingScreenshots(): number;
|
|
88
|
-
/** Test hook
|
|
121
|
+
/** Test hook - read-only snapshot of recorded failures. */
|
|
89
122
|
getRecordedFailures(): ReadonlyArray<{
|
|
90
123
|
sourceFile: string;
|
|
91
124
|
sourceLine?: number;
|
|
@@ -93,7 +126,7 @@ export declare class SelaReporter implements Reporter {
|
|
|
93
126
|
status: string;
|
|
94
127
|
hasScreenshot: boolean;
|
|
95
128
|
}>;
|
|
96
|
-
/** Test hook
|
|
129
|
+
/** Test hook - number of screenshots still waiting for a FailedEvent. */
|
|
97
130
|
getPendingScreenshotCount(): number;
|
|
98
131
|
private pendingKey;
|
|
99
132
|
private normalisePath;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SelaReporter.d.ts","sourceRoot":"","sources":["../../src/reporter/SelaReporter.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"SelaReporter.d.ts","sourceRoot":"","sources":["../../src/reporter/SelaReporter.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,27 +1,30 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
// src/reporter/SelaReporter.ts
|
|
3
3
|
//
|
|
4
|
-
// SelaReporter
|
|
4
|
+
// SelaReporter - Playwright Reporter implementation that drives the
|
|
5
5
|
// Sela heal-and-report pipeline at the reporter layer instead of the
|
|
6
6
|
// fixture teardown layer. The fixture path remains the primary trigger
|
|
7
7
|
// for in-test heals; this reporter is the SAFETY NET for worker crashes,
|
|
8
8
|
// timeouts, and any failure mode that skips fixture teardown.
|
|
9
9
|
//
|
|
10
10
|
// Responsibilities:
|
|
11
|
-
// 1. onBegin
|
|
12
|
-
//
|
|
13
|
-
// 2. onTestEnd
|
|
11
|
+
// 1. onBegin - flips SELA_REPORTER_ACTIVE, installs SIGINT/SIGTERM
|
|
12
|
+
// graceful-shutdown handlers.
|
|
13
|
+
// 2. onTestEnd - extracts the first PNG screenshot from
|
|
14
14
|
// TestResult.attachments and converts it to Base64 IMMEDIATELY.
|
|
15
15
|
// Playwright's temp folder is cleaned up between runs, so the
|
|
16
16
|
// bytes MUST be captured into memory before the reporter loop ends.
|
|
17
|
-
// 3. onEnd
|
|
18
|
-
//
|
|
19
|
-
//
|
|
20
|
-
//
|
|
21
|
-
//
|
|
22
|
-
//
|
|
17
|
+
// 3. onEnd - checks for ANTHROPIC_API_KEY, flushes pending screenshots,
|
|
18
|
+
// runs SelaEngine.commitUpdates(), then prints a *non-blocking*
|
|
19
|
+
// write-and-notify summary (unified diff per healed file +
|
|
20
|
+
// vscode://file deeplink + sela-report.html deeplink). MVP flow -
|
|
21
|
+
// no Y/N prompt, no rollback. Mutations are already on disk by the
|
|
22
|
+
// time we reach this hook.
|
|
23
|
+
// 4. SIGINT / SIGTERM - runs gracefulShutdown() once, second signal
|
|
24
|
+
// hard-exits. Prevents stranded child processes from showing raw
|
|
25
|
+
// Node unhandledRejection stack traces on Ctrl+C.
|
|
23
26
|
//
|
|
24
|
-
// Clean Architecture: zero business logic
|
|
27
|
+
// Clean Architecture: zero business logic - IO + aggregation only.
|
|
25
28
|
// Heal decisions live in SelaEngine, validation in ReportGenerator,
|
|
26
29
|
// rendering in HealReportService.
|
|
27
30
|
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
@@ -77,8 +80,12 @@ class SelaReporter {
|
|
|
77
80
|
cwd;
|
|
78
81
|
readLedger;
|
|
79
82
|
clearLedger;
|
|
80
|
-
|
|
83
|
+
printReview;
|
|
84
|
+
resolveReportPath;
|
|
81
85
|
isCi;
|
|
86
|
+
shouldInstallSignalHandlers;
|
|
87
|
+
shutdownHandler = null;
|
|
88
|
+
shuttingDown = false;
|
|
82
89
|
/**
|
|
83
90
|
* Screenshots that arrived before a matching FailedEvent existed in
|
|
84
91
|
* the shared report. Re-flushed once at onEnd time so worker-crash
|
|
@@ -106,10 +113,10 @@ class SelaReporter {
|
|
|
106
113
|
this.cwd = opts.cwd ?? process.cwd();
|
|
107
114
|
this.readLedger = opts.readLedger ?? PendingPromptLedger_js_1.readPendingPromptsLedger;
|
|
108
115
|
this.clearLedger = opts.clearLedger ?? PendingPromptLedger_js_1.clearPendingPromptsLedger;
|
|
109
|
-
this.
|
|
110
|
-
|
|
111
|
-
((entries) => (0, InteractiveReview_js_1.runInteractiveReview)({ entries }));
|
|
116
|
+
this.printReview = opts.printReview ?? InteractiveReview_js_1.printHealReview;
|
|
117
|
+
this.resolveReportPath = opts.resolveReportPath ?? defaultResolveReportPath;
|
|
112
118
|
this.isCi = opts.isCi ?? defaultIsCi;
|
|
119
|
+
this.shouldInstallSignalHandlers = opts.installSignalHandlers ?? true;
|
|
113
120
|
}
|
|
114
121
|
// ─────────────────────────────────────────────────────────────
|
|
115
122
|
// Playwright Reporter API
|
|
@@ -119,6 +126,9 @@ class SelaReporter {
|
|
|
119
126
|
// finalisation. Today the fixture still calls engine.commitUpdates()
|
|
120
127
|
// itself; the env flag is reserved for the planned dedup guard.
|
|
121
128
|
process.env.SELA_REPORTER_ACTIVE = "1";
|
|
129
|
+
if (this.shouldInstallSignalHandlers) {
|
|
130
|
+
this.installShutdownHandler();
|
|
131
|
+
}
|
|
122
132
|
}
|
|
123
133
|
onTestEnd(test, result) {
|
|
124
134
|
if (result.status !== "failed" && result.status !== "timedOut")
|
|
@@ -128,12 +138,12 @@ class SelaReporter {
|
|
|
128
138
|
const testTitle = test.title;
|
|
129
139
|
const base64Png = this.extractScreenshotBase64(result);
|
|
130
140
|
if (base64Png) {
|
|
131
|
-
// First try to attach immediately
|
|
141
|
+
// First try to attach immediately - the engine may have already
|
|
132
142
|
// recorded the FailedEvent during fixture teardown for in-test
|
|
133
143
|
// heal failures. This is the happy path.
|
|
134
144
|
const matched = this.report.attachFailureScreenshot({ sourceFile: this.normalisePath(sourceFile), testTitle }, base64Png);
|
|
135
145
|
if (matched === 0) {
|
|
136
|
-
// No matching FailedEvent yet
|
|
146
|
+
// No matching FailedEvent yet - buffer for the onEnd retry. This
|
|
137
147
|
// covers worker-crash and fixture-skip cases where the engine
|
|
138
148
|
// never got a chance to record the FailedEvent in-flight.
|
|
139
149
|
const key = this.pendingKey(sourceFile, testTitle);
|
|
@@ -149,11 +159,14 @@ class SelaReporter {
|
|
|
149
159
|
});
|
|
150
160
|
}
|
|
151
161
|
async onEnd(_result) {
|
|
162
|
+
// Detach signal handlers first - a natural onEnd is the orderly path,
|
|
163
|
+
// so we don't want a late SIGINT to double-invoke shutdown logic.
|
|
164
|
+
this.uninstallShutdownHandler();
|
|
152
165
|
if (!this.skipApiKeyCheck && !process.env.ANTHROPIC_API_KEY) {
|
|
153
166
|
const err = new SelaError_js_1.SelaError({
|
|
154
167
|
subsystem: "LLMService",
|
|
155
168
|
code: SelaError_js_1.LLM_SERVICE_CODES.NO_API_KEY,
|
|
156
|
-
reason: "ANTHROPIC_API_KEY not set
|
|
169
|
+
reason: "ANTHROPIC_API_KEY not set - SelaReporter cannot drive the heal pipeline. " +
|
|
157
170
|
"Set the env var (or remove the reporter entry from playwright.config.ts).",
|
|
158
171
|
});
|
|
159
172
|
// Graceful degradation: surface the error and continue flushing
|
|
@@ -169,36 +182,34 @@ class SelaReporter {
|
|
|
169
182
|
const msg = err instanceof Error ? err.message : String(err);
|
|
170
183
|
this.logger.error(`[Sela] reporter commitUpdates failed: ${msg}`);
|
|
171
184
|
}
|
|
172
|
-
// ── Local DX
|
|
185
|
+
// ── Local DX - Write-and-notify summary ─────────────────────
|
|
173
186
|
//
|
|
174
187
|
// Workers serialise their mutated FileSnapshots to
|
|
175
|
-
// `<cwd>/.sela/pending-prompts/*.json
|
|
176
|
-
//
|
|
177
|
-
//
|
|
188
|
+
// `<cwd>/.sela/pending-prompts/*.json`. The reporter drains that
|
|
189
|
+
// ledger here and prints a non-blocking summary (diff + vscode
|
|
190
|
+
// deeplink + HTML report deeplink). No Y/N prompt - the files are
|
|
191
|
+
// already mutated on disk by the time we get here.
|
|
178
192
|
//
|
|
179
|
-
// CI runs skip
|
|
180
|
-
// mutations on its isolated branch.
|
|
193
|
+
// CI runs skip the notify entirely - PR automation already handled
|
|
194
|
+
// the mutations on its isolated branch.
|
|
181
195
|
if (!this.isCi()) {
|
|
182
196
|
try {
|
|
183
197
|
const entries = this.readLedger(this.cwd);
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
// prompt itself races with terminal redraws.
|
|
188
|
-
process.stderr.write(`\n[Sela] 🔧 Local DX review starting (${entries.length} fix${entries.length > 1 ? "es" : ""} pending)\n`);
|
|
189
|
-
await this.runReview(entries);
|
|
198
|
+
const reportHtmlPath = this.resolveReportPath(this.cwd);
|
|
199
|
+
if (entries.length > 0 || reportHtmlPath) {
|
|
200
|
+
this.printReview({ entries, reportHtmlPath });
|
|
190
201
|
}
|
|
191
202
|
}
|
|
192
203
|
catch (err) {
|
|
193
204
|
const msg = err instanceof Error ? err.message : String(err);
|
|
194
|
-
this.logger.error(`[Sela]
|
|
205
|
+
this.logger.error(`[Sela] review summary failed: ${msg}`);
|
|
195
206
|
}
|
|
196
207
|
finally {
|
|
197
208
|
try {
|
|
198
209
|
this.clearLedger(this.cwd);
|
|
199
210
|
}
|
|
200
211
|
catch {
|
|
201
|
-
// Cleanup failures are non-fatal
|
|
212
|
+
// Cleanup failures are non-fatal - the next run will overwrite.
|
|
202
213
|
}
|
|
203
214
|
}
|
|
204
215
|
}
|
|
@@ -213,19 +224,98 @@ class SelaReporter {
|
|
|
213
224
|
}
|
|
214
225
|
}
|
|
215
226
|
}
|
|
216
|
-
/** Reporter prints nothing of its own
|
|
227
|
+
/** Reporter prints nothing of its own - Playwright stdio stays clean. */
|
|
217
228
|
printsToStdio() {
|
|
218
229
|
return false;
|
|
219
230
|
}
|
|
220
231
|
// ─────────────────────────────────────────────────────────────
|
|
221
|
-
//
|
|
232
|
+
// Graceful shutdown - SIGINT / SIGTERM
|
|
233
|
+
// ─────────────────────────────────────────────────────────────
|
|
234
|
+
/**
|
|
235
|
+
* Install the SIGINT/SIGTERM listener once per reporter. First signal
|
|
236
|
+
* triggers an orderly drain; second signal hard-exits with code 130
|
|
237
|
+
* (SIGINT) / 143 (SIGTERM) so the user can always escape if the drain
|
|
238
|
+
* itself wedges (e.g. a stuck LLM call).
|
|
239
|
+
*/
|
|
240
|
+
installShutdownHandler() {
|
|
241
|
+
if (this.shutdownHandler)
|
|
242
|
+
return;
|
|
243
|
+
const handler = (signal) => {
|
|
244
|
+
if (this.shuttingDown) {
|
|
245
|
+
process.stderr.write(`\n[Sela] ⏹ Force exit on second ${signal}.\n`);
|
|
246
|
+
process.exit(signal === "SIGTERM" ? 143 : 130);
|
|
247
|
+
return;
|
|
248
|
+
}
|
|
249
|
+
this.shuttingDown = true;
|
|
250
|
+
process.stderr.write(`\n[Sela] 🛑 ${signal} received - flushing state and shutting down...\n`);
|
|
251
|
+
this.gracefulShutdown()
|
|
252
|
+
.catch((err) => {
|
|
253
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
254
|
+
process.stderr.write(`[Sela] Shutdown error: ${msg}\n`);
|
|
255
|
+
})
|
|
256
|
+
.finally(() => {
|
|
257
|
+
process.stderr.write(`[Sela] 👋 Goodbye.\n`);
|
|
258
|
+
process.exit(signal === "SIGTERM" ? 143 : 130);
|
|
259
|
+
});
|
|
260
|
+
};
|
|
261
|
+
this.shutdownHandler = handler;
|
|
262
|
+
process.on("SIGINT", handler);
|
|
263
|
+
process.on("SIGTERM", handler);
|
|
264
|
+
}
|
|
265
|
+
uninstallShutdownHandler() {
|
|
266
|
+
if (!this.shutdownHandler)
|
|
267
|
+
return;
|
|
268
|
+
process.off("SIGINT", this.shutdownHandler);
|
|
269
|
+
process.off("SIGTERM", this.shutdownHandler);
|
|
270
|
+
this.shutdownHandler = null;
|
|
271
|
+
}
|
|
272
|
+
/**
|
|
273
|
+
* Best-effort drain on signal. Mirrors the orderly onEnd path but
|
|
274
|
+
* swallows every error - we never want to throw inside a signal
|
|
275
|
+
* handler because Node prints raw stack traces otherwise.
|
|
276
|
+
*
|
|
277
|
+
* Exposed for tests so they can drive the shutdown without raising
|
|
278
|
+
* a real signal in the vitest process.
|
|
279
|
+
*/
|
|
280
|
+
async gracefulShutdown() {
|
|
281
|
+
try {
|
|
282
|
+
this.flushPendingScreenshots();
|
|
283
|
+
}
|
|
284
|
+
catch {
|
|
285
|
+
// ignore
|
|
286
|
+
}
|
|
287
|
+
try {
|
|
288
|
+
await this.engine.commitUpdates();
|
|
289
|
+
}
|
|
290
|
+
catch {
|
|
291
|
+
// ignore
|
|
292
|
+
}
|
|
293
|
+
try {
|
|
294
|
+
const entries = this.isCi() ? [] : this.readLedger(this.cwd);
|
|
295
|
+
const reportHtmlPath = this.resolveReportPath(this.cwd);
|
|
296
|
+
if (entries.length > 0 || reportHtmlPath) {
|
|
297
|
+
this.printReview({ entries, reportHtmlPath });
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
catch {
|
|
301
|
+
// ignore
|
|
302
|
+
}
|
|
303
|
+
try {
|
|
304
|
+
this.clearLedger(this.cwd);
|
|
305
|
+
}
|
|
306
|
+
catch {
|
|
307
|
+
// ignore
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
// ─────────────────────────────────────────────────────────────
|
|
311
|
+
// Internals (exposed for testing - prefixed underscore is the
|
|
222
312
|
// convention used elsewhere in the codebase for proxy back-doors).
|
|
223
313
|
// ─────────────────────────────────────────────────────────────
|
|
224
314
|
/**
|
|
225
315
|
* Walk every buffered pending screenshot and try to attach it to a
|
|
226
316
|
* now-existing FailedEvent. Successfully-attached entries are
|
|
227
317
|
* removed; unmatched entries are dropped (the matching FailedEvent
|
|
228
|
-
* never arrived
|
|
318
|
+
* never arrived - most likely worker crashed before the engine
|
|
229
319
|
* could record one).
|
|
230
320
|
*
|
|
231
321
|
* Returns the number of FailedEvents touched.
|
|
@@ -248,11 +338,11 @@ class SelaReporter {
|
|
|
248
338
|
}
|
|
249
339
|
return total;
|
|
250
340
|
}
|
|
251
|
-
/** Test hook
|
|
341
|
+
/** Test hook - read-only snapshot of recorded failures. */
|
|
252
342
|
getRecordedFailures() {
|
|
253
343
|
return this.failures.slice();
|
|
254
344
|
}
|
|
255
|
-
/** Test hook
|
|
345
|
+
/** Test hook - number of screenshots still waiting for a FailedEvent. */
|
|
256
346
|
getPendingScreenshotCount() {
|
|
257
347
|
return this.pendingScreenshots.size;
|
|
258
348
|
}
|
|
@@ -287,7 +377,7 @@ class SelaReporter {
|
|
|
287
377
|
const contentType = (att.contentType ?? "").toLowerCase();
|
|
288
378
|
const looksLikePng = contentType.includes("png") ||
|
|
289
379
|
(att.name ?? "").toLowerCase().includes("screenshot") ||
|
|
290
|
-
(
|
|
380
|
+
(att.path ?? "").toLowerCase().endsWith(".png");
|
|
291
381
|
if (!looksLikePng)
|
|
292
382
|
continue;
|
|
293
383
|
// Playwright >= 1.46 sometimes inlines the body for small images.
|
|
@@ -303,7 +393,7 @@ class SelaReporter {
|
|
|
303
393
|
return bytes.toString("base64");
|
|
304
394
|
}
|
|
305
395
|
catch {
|
|
306
|
-
// Temp file already gone
|
|
396
|
+
// Temp file already gone - nothing we can do.
|
|
307
397
|
}
|
|
308
398
|
}
|
|
309
399
|
}
|
|
@@ -323,6 +413,16 @@ function defaultIsCi() {
|
|
|
323
413
|
const v = String(raw).trim().toLowerCase();
|
|
324
414
|
return v !== "" && v !== "0" && v !== "false";
|
|
325
415
|
}
|
|
416
|
+
/**
|
|
417
|
+
* Default HTML report locator. Returns the absolute path when
|
|
418
|
+
* `<cwd>/sela-report.html` exists on disk after `commitUpdates()` has
|
|
419
|
+
* had its chance to flush, otherwise null so the printer can skip the
|
|
420
|
+
* "Insights report:" footer entirely.
|
|
421
|
+
*/
|
|
422
|
+
function defaultResolveReportPath(cwd) {
|
|
423
|
+
const candidate = path.join(cwd, "sela-report.html");
|
|
424
|
+
return fs.existsSync(candidate) ? candidate : null;
|
|
425
|
+
}
|
|
326
426
|
// Default export so Playwright can resolve `reporter: [['sela-core/reporter']]`
|
|
327
427
|
// without needing the consumer to spell out the named import.
|
|
328
428
|
exports.default = SelaReporter;
|
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
import { SelectorSegment } from "./LLMService";
|
|
2
2
|
import { AdvisoryBuffer } from "./HealingAdvisory";
|
|
3
3
|
import type { SmartChainSegment } from "./LLMService";
|
|
4
|
+
import { TraceOutcome } from "./TraceBackEngine";
|
|
5
|
+
import { Decision } from "./DecisionEngine";
|
|
6
|
+
import { FileBatch, ApplyOutcome, ApplyOptions } from "./MutationApplier";
|
|
4
7
|
export interface ASTUpdateResult {
|
|
5
8
|
success: boolean;
|
|
6
9
|
reason: string;
|
|
@@ -21,14 +24,55 @@ interface CallerContext {
|
|
|
21
24
|
filePath: string;
|
|
22
25
|
line: number;
|
|
23
26
|
}
|
|
27
|
+
export interface ComposeHealInput {
|
|
28
|
+
filePath: string;
|
|
29
|
+
/** 1-based line of the failing call-site. */
|
|
30
|
+
line: number;
|
|
31
|
+
/** 0-based column; when omitted the first non-whitespace char of the line is used. */
|
|
32
|
+
column?: number;
|
|
33
|
+
/**
|
|
34
|
+
* Healed locator EXPRESSION text, e.g. `page.locator(".btn-v2")`. When
|
|
35
|
+
* omitted, it is BUILT from `newSelector` + the traced target's root
|
|
36
|
+
* receiver (internal selectors → idiomatic method form).
|
|
37
|
+
*/
|
|
38
|
+
newLocatorExpr?: string;
|
|
39
|
+
/** Raw healed selector string (may be an `internal:` engine selector). */
|
|
40
|
+
newSelector?: string;
|
|
41
|
+
/** Runtime: only the failing test needs the new selector. */
|
|
42
|
+
contextSpecific?: boolean;
|
|
43
|
+
/** Runtime: selector rot is global across all consumers. */
|
|
44
|
+
globalCorrect?: boolean;
|
|
45
|
+
/** When true, write the result via MutationApplier (with the gate). */
|
|
46
|
+
apply?: boolean;
|
|
47
|
+
applyOptions?: ApplyOptions;
|
|
48
|
+
}
|
|
49
|
+
export interface ComposeHealResult {
|
|
50
|
+
kind: "decision" | "abort";
|
|
51
|
+
trace: TraceOutcome;
|
|
52
|
+
decision?: Decision;
|
|
53
|
+
batch?: FileBatch;
|
|
54
|
+
outcome?: ApplyOutcome;
|
|
55
|
+
/** 1-based line of the mutated target node (for report/diff). */
|
|
56
|
+
writtenLine?: number;
|
|
57
|
+
}
|
|
24
58
|
export declare class ASTSourceUpdater {
|
|
25
59
|
private project;
|
|
26
60
|
readonly advisoryBuffer: AdvisoryBuffer;
|
|
27
61
|
flushAdvisories(): void;
|
|
62
|
+
/**
|
|
63
|
+
* Trace the failing call-site back to its source declaration, decide the
|
|
64
|
+
* mutation strategy (in-place / fork / prompt), and — when `apply` is set —
|
|
65
|
+
* write it to disk through the type-safety gate.
|
|
66
|
+
*/
|
|
67
|
+
static composeHeal(input: ComposeHealInput): ComposeHealResult;
|
|
68
|
+
/** Drain-loop entry: apply pre-built batches through the write gate. */
|
|
69
|
+
static applyMutationBatches(batches: FileBatch[], opts?: ApplyOptions): ApplyOutcome[];
|
|
70
|
+
/** Convert a DecisionEngine result into an anchored MutationApplier batch. */
|
|
71
|
+
static decisionToBatch(filePath: string, decision: Decision): FileBatch;
|
|
28
72
|
/**
|
|
29
73
|
* Centralised write hook for every ts-morph `saveSync` call in this class.
|
|
30
74
|
* When `SELA_DRY_RUN` is active the AST mutation stays in memory but the
|
|
31
|
-
* on-disk file is left untouched
|
|
75
|
+
* on-disk file is left untouched - the heal pipeline can still compute a
|
|
32
76
|
* candidate diff via `sourceFile.getFullText()` and the report layer
|
|
33
77
|
* tags the event with `dryRun: true`.
|
|
34
78
|
*/
|
|
@@ -39,7 +83,7 @@ export declare class ASTSourceUpdater {
|
|
|
39
83
|
matchedLine?: number;
|
|
40
84
|
};
|
|
41
85
|
/**
|
|
42
|
-
* Convenience helper
|
|
86
|
+
* Convenience helper - runs `scanFailFastDirective` and throws the
|
|
43
87
|
* canonical SelaError when the directive is present. Used by SelaEngine
|
|
44
88
|
* as the very first gate inside `heal()`.
|
|
45
89
|
*/
|
|
@@ -67,7 +111,7 @@ export declare class ASTSourceUpdater {
|
|
|
67
111
|
/**
|
|
68
112
|
* Guard: returns false when replacing oldNode with proposedNewText would
|
|
69
113
|
* substitute a hardcoded string literal for an Identifier or
|
|
70
|
-
* PropertyAccessExpression
|
|
114
|
+
* PropertyAccessExpression - which is the definition-site mutation bug.
|
|
71
115
|
* All other replacements are allowed.
|
|
72
116
|
*/
|
|
73
117
|
private static isSafeReplacement;
|
|
@@ -86,6 +130,7 @@ export declare class ASTSourceUpdater {
|
|
|
86
130
|
private lineToOffset;
|
|
87
131
|
resolveFilePath(raw: string): string | null;
|
|
88
132
|
private semanticDispatch;
|
|
133
|
+
private applyDefinitionSiteHeal;
|
|
89
134
|
private handleIdentifierArg;
|
|
90
135
|
private handlePropertyAccessArg;
|
|
91
136
|
private handleTemplateLiteralArg;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ASTSourceUpdater.d.ts","sourceRoot":"","sources":["../../src/services/ASTSourceUpdater.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"ASTSourceUpdater.d.ts","sourceRoot":"","sources":["../../src/services/ASTSourceUpdater.ts"],"names":[],"mappings":"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"}
|