sela-core 0.1.0-alpha.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/README.md +103 -0
- package/bin/sela.js +3 -0
- package/dist/cli/ErrorHandler.d.ts +10 -0
- package/dist/cli/ErrorHandler.d.ts.map +1 -0
- package/dist/cli/ErrorHandler.js +70 -0
- package/dist/cli/commands/bulk.d.ts +3 -0
- package/dist/cli/commands/bulk.d.ts.map +1 -0
- package/dist/cli/commands/bulk.js +158 -0
- package/dist/cli/commands/find.d.ts +3 -0
- package/dist/cli/commands/find.d.ts.map +1 -0
- package/dist/cli/commands/find.js +51 -0
- package/dist/cli/commands/init.d.ts +3 -0
- package/dist/cli/commands/init.d.ts.map +1 -0
- package/dist/cli/commands/init.js +166 -0
- package/dist/cli/commands/list.d.ts +3 -0
- package/dist/cli/commands/list.d.ts.map +1 -0
- package/dist/cli/commands/list.js +56 -0
- 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/refactor.d.ts +3 -0
- package/dist/cli/commands/refactor.d.ts.map +1 -0
- package/dist/cli/commands/refactor.js +30 -0
- package/dist/cli/commands/showReport.d.ts +3 -0
- package/dist/cli/commands/showReport.d.ts.map +1 -0
- package/dist/cli/commands/showReport.js +82 -0
- package/dist/cli/commands/status.d.ts +3 -0
- package/dist/cli/commands/status.d.ts.map +1 -0
- package/dist/cli/commands/status.js +51 -0
- package/dist/cli/commands/sync.d.ts +3 -0
- package/dist/cli/commands/sync.d.ts.map +1 -0
- package/dist/cli/commands/sync.js +131 -0
- package/dist/cli/index.d.ts +2 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +94 -0
- package/dist/cli/ui/DnaTable.d.ts +3 -0
- package/dist/cli/ui/DnaTable.d.ts.map +1 -0
- package/dist/cli/ui/DnaTable.js +77 -0
- package/dist/cli/ui/LocatorPicker.d.ts +8 -0
- package/dist/cli/ui/LocatorPicker.d.ts.map +1 -0
- package/dist/cli/ui/LocatorPicker.js +33 -0
- package/dist/cli/ui/ProgressReporter.d.ts +11 -0
- package/dist/cli/ui/ProgressReporter.d.ts.map +1 -0
- package/dist/cli/ui/ProgressReporter.js +33 -0
- package/dist/cli/ui/RefactorWizard.d.ts +26 -0
- package/dist/cli/ui/RefactorWizard.d.ts.map +1 -0
- package/dist/cli/ui/RefactorWizard.js +295 -0
- package/dist/config/ConfigLoader.d.ts +16 -0
- package/dist/config/ConfigLoader.d.ts.map +1 -0
- package/dist/config/ConfigLoader.js +185 -0
- package/dist/config/DryRunGuard.d.ts +14 -0
- package/dist/config/DryRunGuard.d.ts.map +1 -0
- package/dist/config/DryRunGuard.js +80 -0
- package/dist/config/PathScopeGuard.d.ts +42 -0
- package/dist/config/PathScopeGuard.d.ts.map +1 -0
- package/dist/config/PathScopeGuard.js +192 -0
- package/dist/config/SelaConfig.d.ts +178 -0
- package/dist/config/SelaConfig.d.ts.map +1 -0
- package/dist/config/SelaConfig.js +141 -0
- package/dist/config/defineConfig.d.ts +3 -0
- package/dist/config/defineConfig.d.ts.map +1 -0
- package/dist/config/defineConfig.js +9 -0
- package/dist/engine/FixwrightEngine.d.ts +24 -0
- package/dist/engine/FixwrightEngine.d.ts.map +1 -0
- package/dist/engine/FixwrightEngine.js +403 -0
- package/dist/engine/HealingRegistry.d.ts +40 -0
- package/dist/engine/HealingRegistry.d.ts.map +1 -0
- package/dist/engine/HealingRegistry.js +99 -0
- package/dist/engine/SelaEngine.d.ts +57 -0
- package/dist/engine/SelaEngine.d.ts.map +1 -0
- package/dist/engine/SelaEngine.js +1146 -0
- package/dist/engine/singleton.d.ts +3 -0
- package/dist/engine/singleton.d.ts.map +1 -0
- package/dist/engine/singleton.js +5 -0
- package/dist/errors/SelaError.d.ts +146 -0
- package/dist/errors/SelaError.d.ts.map +1 -0
- package/dist/errors/SelaError.js +168 -0
- package/dist/fixtures/expectProxy.d.ts +12 -0
- package/dist/fixtures/expectProxy.d.ts.map +1 -0
- package/dist/fixtures/expectProxy.js +246 -0
- package/dist/fixtures/index.d.ts +30 -0
- package/dist/fixtures/index.d.ts.map +1 -0
- package/dist/fixtures/index.js +765 -0
- package/dist/fixtures/moduleExpect.d.ts +2 -0
- package/dist/fixtures/moduleExpect.d.ts.map +1 -0
- package/dist/fixtures/moduleExpect.js +54 -0
- package/dist/fixtures/proxyTag.d.ts +12 -0
- package/dist/fixtures/proxyTag.d.ts.map +1 -0
- package/dist/fixtures/proxyTag.js +45 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +31 -0
- package/dist/reporter/SelaReporter.d.ts +165 -0
- package/dist/reporter/SelaReporter.d.ts.map +1 -0
- package/dist/reporter/SelaReporter.js +517 -0
- package/dist/services/ASTSourceUpdater.d.ts +143 -0
- package/dist/services/ASTSourceUpdater.d.ts.map +1 -0
- package/dist/services/ASTSourceUpdater.js +3514 -0
- 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.d.ts +26 -0
- package/dist/services/ArgumentTypeAnalyzer.d.ts.map +1 -0
- package/dist/services/ArgumentTypeAnalyzer.js +92 -0
- package/dist/services/BlastRadiusAnalyzer.d.ts +15 -0
- package/dist/services/BlastRadiusAnalyzer.d.ts.map +1 -0
- package/dist/services/BlastRadiusAnalyzer.js +107 -0
- package/dist/services/ChainValidator.d.ts +76 -0
- package/dist/services/ChainValidator.d.ts.map +1 -0
- package/dist/services/ChainValidator.js +570 -0
- package/dist/services/CrossFileHealer.d.ts +6 -0
- package/dist/services/CrossFileHealer.d.ts.map +1 -0
- package/dist/services/CrossFileHealer.js +135 -0
- 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 +41 -0
- package/dist/services/DefinitionTracer.d.ts.map +1 -0
- package/dist/services/DefinitionTracer.js +366 -0
- package/dist/services/DnaEditorService.d.ts +31 -0
- package/dist/services/DnaEditorService.d.ts.map +1 -0
- package/dist/services/DnaEditorService.js +217 -0
- package/dist/services/DnaIndexService.d.ts +24 -0
- package/dist/services/DnaIndexService.d.ts.map +1 -0
- package/dist/services/DnaIndexService.js +131 -0
- package/dist/services/HealBudget.d.ts +32 -0
- package/dist/services/HealBudget.d.ts.map +1 -0
- package/dist/services/HealBudget.js +85 -0
- package/dist/services/HealReportService.d.ts +161 -0
- package/dist/services/HealReportService.d.ts.map +1 -0
- package/dist/services/HealReportService.js +1039 -0
- package/dist/services/HealingAdvisory.d.ts +30 -0
- package/dist/services/HealingAdvisory.d.ts.map +1 -0
- package/dist/services/HealingAdvisory.js +51 -0
- package/dist/services/HealingCacheService.d.ts +135 -0
- package/dist/services/HealingCacheService.d.ts.map +1 -0
- package/dist/services/HealingCacheService.js +404 -0
- package/dist/services/HealthReportService.d.ts +10 -0
- package/dist/services/HealthReportService.d.ts.map +1 -0
- package/dist/services/HealthReportService.js +84 -0
- package/dist/services/InitializerUpdater.d.ts +16 -0
- package/dist/services/InitializerUpdater.d.ts.map +1 -0
- package/dist/services/InitializerUpdater.js +73 -0
- package/dist/services/IntentAuditor.d.ts +56 -0
- package/dist/services/IntentAuditor.d.ts.map +1 -0
- package/dist/services/IntentAuditor.js +326 -0
- package/dist/services/InteractiveReview.d.ts +15 -0
- package/dist/services/InteractiveReview.d.ts.map +1 -0
- package/dist/services/InteractiveReview.js +128 -0
- package/dist/services/LLMService.d.ts +121 -0
- package/dist/services/LLMService.d.ts.map +1 -0
- package/dist/services/LLMService.js +475 -0
- package/dist/services/MutationApplier.d.ts +69 -0
- package/dist/services/MutationApplier.d.ts.map +1 -0
- package/dist/services/MutationApplier.js +360 -0
- package/dist/services/PRAutomationService.d.ts +50 -0
- package/dist/services/PRAutomationService.d.ts.map +1 -0
- package/dist/services/PRAutomationService.js +760 -0
- package/dist/services/PendingPromptLedger.d.ts +51 -0
- package/dist/services/PendingPromptLedger.d.ts.map +1 -0
- package/dist/services/PendingPromptLedger.js +205 -0
- package/dist/services/ReportGenerator.d.ts +156 -0
- package/dist/services/ReportGenerator.d.ts.map +1 -0
- package/dist/services/ReportGenerator.js +278 -0
- 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 +112 -0
- package/dist/services/SafetyGuard.d.ts.map +1 -0
- package/dist/services/SafetyGuard.js +87 -0
- package/dist/services/Sanitizer.d.ts +28 -0
- package/dist/services/Sanitizer.d.ts.map +1 -0
- package/dist/services/Sanitizer.js +142 -0
- package/dist/services/SanitizingAnthropic.d.ts +19 -0
- package/dist/services/SanitizingAnthropic.d.ts.map +1 -0
- package/dist/services/SanitizingAnthropic.js +84 -0
- 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.d.ts +11 -0
- package/dist/services/SnapshotService.d.ts.map +1 -0
- package/dist/services/SnapshotService.js +352 -0
- package/dist/services/SourceLinkService.d.ts +26 -0
- package/dist/services/SourceLinkService.d.ts.map +1 -0
- package/dist/services/SourceLinkService.js +165 -0
- package/dist/services/SourceUpdater.d.ts +45 -0
- package/dist/services/SourceUpdater.d.ts.map +1 -0
- package/dist/services/SourceUpdater.js +1091 -0
- package/dist/services/TemplateDiffService.d.ts +25 -0
- package/dist/services/TemplateDiffService.d.ts.map +1 -0
- package/dist/services/TemplateDiffService.js +334 -0
- 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 +71 -0
- package/dist/services/WorkspaceSnapshotService.d.ts.map +1 -0
- package/dist/services/WorkspaceSnapshotService.js +200 -0
- package/dist/services/safety/PipelineContext.d.ts +63 -0
- package/dist/services/safety/PipelineContext.d.ts.map +1 -0
- package/dist/services/safety/PipelineContext.js +34 -0
- package/dist/services/safety/roleClassifier.d.ts +4 -0
- package/dist/services/safety/roleClassifier.d.ts.map +1 -0
- package/dist/services/safety/roleClassifier.js +233 -0
- package/dist/services/safety/rules/ConfidenceTierRule.d.ts +3 -0
- package/dist/services/safety/rules/ConfidenceTierRule.d.ts.map +1 -0
- package/dist/services/safety/rules/ConfidenceTierRule.js +32 -0
- package/dist/services/safety/rules/DangerousSinkRule.d.ts +10 -0
- package/dist/services/safety/rules/DangerousSinkRule.d.ts.map +1 -0
- package/dist/services/safety/rules/DangerousSinkRule.js +53 -0
- package/dist/services/safety/rules/FunctionalRoleRule.d.ts +3 -0
- package/dist/services/safety/rules/FunctionalRoleRule.d.ts.map +1 -0
- package/dist/services/safety/rules/FunctionalRoleRule.js +64 -0
- package/dist/services/safety/rules/HardConfidenceRule.d.ts +3 -0
- package/dist/services/safety/rules/HardConfidenceRule.d.ts.map +1 -0
- package/dist/services/safety/rules/HardConfidenceRule.js +22 -0
- package/dist/services/safety/rules/IntentAuditorRule.d.ts +3 -0
- package/dist/services/safety/rules/IntentAuditorRule.d.ts.map +1 -0
- package/dist/services/safety/rules/IntentAuditorRule.js +97 -0
- package/dist/services/safety/rules/SemanticOppositeRule.d.ts +3 -0
- package/dist/services/safety/rules/SemanticOppositeRule.d.ts.map +1 -0
- package/dist/services/safety/rules/SemanticOppositeRule.js +30 -0
- package/dist/services/safety/rules/StructuralOnlyRule.d.ts +3 -0
- package/dist/services/safety/rules/StructuralOnlyRule.d.ts.map +1 -0
- package/dist/services/safety/rules/StructuralOnlyRule.js +38 -0
- package/dist/services/safety/rules/VisibilityRule.d.ts +3 -0
- package/dist/services/safety/rules/VisibilityRule.d.ts.map +1 -0
- package/dist/services/safety/rules/VisibilityRule.js +53 -0
- package/dist/services/safety/rules/ZeroTrustRule.d.ts +3 -0
- package/dist/services/safety/rules/ZeroTrustRule.d.ts.map +1 -0
- package/dist/services/safety/rules/ZeroTrustRule.js +37 -0
- package/dist/services/safety/rules/index.d.ts +3 -0
- package/dist/services/safety/rules/index.d.ts.map +1 -0
- package/dist/services/safety/rules/index.js +34 -0
- package/dist/services/types.d.ts +59 -0
- package/dist/services/types.d.ts.map +1 -0
- package/dist/services/types.js +2 -0
- package/dist/storage/SnapshotManager.d.ts +5 -0
- package/dist/storage/SnapshotManager.d.ts.map +1 -0
- package/dist/storage/SnapshotManager.js +32 -0
- package/dist/types/index.d.ts +95 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +7 -0
- package/dist/utils/DOMUtils.d.ts +49 -0
- package/dist/utils/DOMUtils.d.ts.map +1 -0
- package/dist/utils/DOMUtils.js +466 -0
- package/dist/utils/FileLock.d.ts +44 -0
- package/dist/utils/FileLock.d.ts.map +1 -0
- package/dist/utils/FileLock.js +189 -0
- package/dist/utils/IsolatedDiff.d.ts +45 -0
- package/dist/utils/IsolatedDiff.d.ts.map +1 -0
- package/dist/utils/IsolatedDiff.js +382 -0
- package/dist/utils/StackUtils.d.ts +11 -0
- package/dist/utils/StackUtils.d.ts.map +1 -0
- package/dist/utils/StackUtils.js +120 -0
- package/dist/utils/SummaryTable.d.ts +17 -0
- package/dist/utils/SummaryTable.d.ts.map +1 -0
- package/dist/utils/SummaryTable.js +37 -0
- package/dist/utils/atomicWrite.d.ts +9 -0
- package/dist/utils/atomicWrite.d.ts.map +1 -0
- package/dist/utils/atomicWrite.js +83 -0
- package/dist/utils/logger.d.ts +59 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js +123 -0
- package/dist/vendor/enquirer.d.ts +33 -0
- package/dist/vendor/enquirer.d.ts.map +1 -0
- package/dist/vendor/enquirer.js +11 -0
- package/package.json +71 -0
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { Command } from "commander";
|
|
2
|
+
/**
|
|
3
|
+
* `sela merge [files...]`
|
|
4
|
+
*
|
|
5
|
+
* Aggregates per-shard `sela-report.json` files (uploaded as CI artifacts)
|
|
6
|
+
* into ONE coherent `.sela-history.json` + `sela-report.html` + `sela-report.json`.
|
|
7
|
+
*
|
|
8
|
+
* Resolution order for the shard files:
|
|
9
|
+
* 1. Explicit positional paths (shells on Linux runners expand globs here).
|
|
10
|
+
* 2. Otherwise scan `--shard-dir` for filenames matching `--shard-glob`.
|
|
11
|
+
*/
|
|
12
|
+
export declare function registerMerge(program: Command): void;
|
|
13
|
+
//# sourceMappingURL=merge.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"merge.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/merge.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAgBzC;;;;;;;;;GASG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CA8FpD"}
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.registerMerge = registerMerge;
|
|
37
|
+
const path = __importStar(require("path"));
|
|
38
|
+
const ReportMergeService_js_1 = require("../../services/ReportMergeService.js");
|
|
39
|
+
const SelaError_js_1 = require("../../errors/SelaError.js");
|
|
40
|
+
/**
|
|
41
|
+
* `sela merge [files...]`
|
|
42
|
+
*
|
|
43
|
+
* Aggregates per-shard `sela-report.json` files (uploaded as CI artifacts)
|
|
44
|
+
* into ONE coherent `.sela-history.json` + `sela-report.html` + `sela-report.json`.
|
|
45
|
+
*
|
|
46
|
+
* Resolution order for the shard files:
|
|
47
|
+
* 1. Explicit positional paths (shells on Linux runners expand globs here).
|
|
48
|
+
* 2. Otherwise scan `--shard-dir` for filenames matching `--shard-glob`.
|
|
49
|
+
*/
|
|
50
|
+
function registerMerge(program) {
|
|
51
|
+
program
|
|
52
|
+
.command("merge")
|
|
53
|
+
.argument("[files...]", "Explicit shard report JSON files (sela-report.json shape). " +
|
|
54
|
+
"When omitted, --shard-dir is scanned with --shard-glob.")
|
|
55
|
+
.description("Merge sharded Sela reports into a single history + HTML report (CI fan-in)")
|
|
56
|
+
.option("--dir <path>", "Output dir for the merged report + rolling history (and where the prior .sela-history.json lives)", process.cwd())
|
|
57
|
+
.option("--shard-dir <path>", "Directory to scan for shard reports when no explicit files are given", process.cwd())
|
|
58
|
+
.option("--shard-glob <pattern>", "Filename glob (single * wildcard) used when scanning --shard-dir", "sela-shard-*.json")
|
|
59
|
+
.option("--run-id <id>", "Single dedup id for the merged history row (defaults to GITHUB_RUN_ID / CI_PIPELINE_ID)")
|
|
60
|
+
.option("--expected-shards <n>", "Number of shards launched; a smaller readable count flags a partial merge")
|
|
61
|
+
.action(async (files, opts) => {
|
|
62
|
+
const targetDir = path.resolve(opts.dir ?? process.cwd());
|
|
63
|
+
const shardDir = path.resolve(opts.shardDir ?? process.cwd());
|
|
64
|
+
const shardFiles = files && files.length > 0
|
|
65
|
+
? files.map((f) => path.resolve(f))
|
|
66
|
+
: ReportMergeService_js_1.ReportMergeService.discoverShardFiles(shardDir, opts.shardGlob ?? "sela-shard-*.json");
|
|
67
|
+
if (shardFiles.length === 0) {
|
|
68
|
+
process.stderr.write(`[sela] No shard reports found ` +
|
|
69
|
+
`(looked in ${shardDir} for "${opts.shardGlob ?? "sela-shard-*.json"}").\n` +
|
|
70
|
+
` A merged report with a healed:0 history row will still be written ` +
|
|
71
|
+
`to keep the trend cadence intact.\n`);
|
|
72
|
+
}
|
|
73
|
+
const expectedShards = parseExpectedShards(opts.expectedShards);
|
|
74
|
+
let result;
|
|
75
|
+
try {
|
|
76
|
+
result = ReportMergeService_js_1.ReportMergeService.merge({
|
|
77
|
+
shardFiles,
|
|
78
|
+
targetDir,
|
|
79
|
+
runId: opts.runId,
|
|
80
|
+
expectedShards,
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
catch (err) {
|
|
84
|
+
// A corrupt prior history (HISTORY_CORRUPT) is the one hard-fail: we
|
|
85
|
+
// must not silently overwrite a durable rolling window.
|
|
86
|
+
if ((0, SelaError_js_1.isSelaError)(err)) {
|
|
87
|
+
process.stderr.write(`[sela] merge aborted: ${err.message}\n`);
|
|
88
|
+
}
|
|
89
|
+
else {
|
|
90
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
91
|
+
process.stderr.write(`[sela] merge failed: ${msg}\n`);
|
|
92
|
+
}
|
|
93
|
+
process.exit(1);
|
|
94
|
+
return;
|
|
95
|
+
}
|
|
96
|
+
process.stdout.write(`[sela] Merged report written: ${result.htmlPath}\n` +
|
|
97
|
+
` shards: ${result.shardsRead}` +
|
|
98
|
+
(result.shardsExpected != null ? `/${result.shardsExpected}` : "") +
|
|
99
|
+
` events: ${result.uniqueEvents}` +
|
|
100
|
+
(result.duplicatesDropped > 0
|
|
101
|
+
? ` (${result.duplicatesDropped} dup dropped)`
|
|
102
|
+
: "") +
|
|
103
|
+
` history: ${result.data.historical_runs.length} run(s)\n`);
|
|
104
|
+
// Partial merges are surfaced but DO NOT fail the job (aggregate-and-flag).
|
|
105
|
+
if (result.partial) {
|
|
106
|
+
process.exitCode = 0;
|
|
107
|
+
}
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* Parse `--expected-shards`. Ignores non-positive / non-numeric input so a
|
|
112
|
+
* bad flag degrades to "no expectation" rather than crashing the fan-in.
|
|
113
|
+
*/
|
|
114
|
+
function parseExpectedShards(raw) {
|
|
115
|
+
if (raw == null)
|
|
116
|
+
return undefined;
|
|
117
|
+
const n = Number.parseInt(raw, 10);
|
|
118
|
+
return Number.isFinite(n) && n > 0 ? n : undefined;
|
|
119
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"refactor.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/refactor.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAczC,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,OAAO,GAAG,IAAI,CA0BnD"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.registerRefactor = registerRefactor;
|
|
4
|
+
const ConfigLoader_js_1 = require("../../config/ConfigLoader.js");
|
|
5
|
+
const DnaIndexService_js_1 = require("../../services/DnaIndexService.js");
|
|
6
|
+
const DnaEditorService_js_1 = require("../../services/DnaEditorService.js");
|
|
7
|
+
const SourceLinkService_js_1 = require("../../services/SourceLinkService.js");
|
|
8
|
+
const RefactorWizard_js_1 = require("../ui/RefactorWizard.js");
|
|
9
|
+
const ProgressReporter_js_1 = require("../ui/ProgressReporter.js");
|
|
10
|
+
function registerRefactor(dna) {
|
|
11
|
+
dna
|
|
12
|
+
.command('refactor [key]')
|
|
13
|
+
.description('Interactive refactor wizard for a DNA record')
|
|
14
|
+
.option('--no-source', 'Skip source file update')
|
|
15
|
+
.option('--dry-run', 'Preview changes without writing')
|
|
16
|
+
.option('--dir <path>', 'Override snapshot directory')
|
|
17
|
+
.action(async (key, opts) => {
|
|
18
|
+
const config = ConfigLoader_js_1.ConfigLoader.getInstance();
|
|
19
|
+
const snapshotDir = opts.dir ?? config.dnaStoragePath;
|
|
20
|
+
const progress = new ProgressReporter_js_1.ProgressReporter(false); // wizard is always interactive
|
|
21
|
+
const dnaIndex = new DnaIndexService_js_1.DnaIndexService();
|
|
22
|
+
await progress.run('Scanning DNA snapshots…', () => dnaIndex.buildIndex(snapshotDir));
|
|
23
|
+
const wizard = new RefactorWizard_js_1.RefactorWizard({
|
|
24
|
+
dnaIndex,
|
|
25
|
+
dnaEditor: new DnaEditorService_js_1.DnaEditorService(snapshotDir),
|
|
26
|
+
sourceLink: new SourceLinkService_js_1.SourceLinkService(),
|
|
27
|
+
}, { noSource: !opts.source, dryRun: opts.dryRun });
|
|
28
|
+
await wizard.run(key);
|
|
29
|
+
});
|
|
30
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"showReport.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/showReport.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAuBzC,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAyCzD"}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.registerShowReport = registerShowReport;
|
|
37
|
+
const fs = __importStar(require("fs"));
|
|
38
|
+
const path = __importStar(require("path"));
|
|
39
|
+
const child_process_1 = require("child_process");
|
|
40
|
+
function openInBrowser(absPath) {
|
|
41
|
+
return new Promise((resolve, reject) => {
|
|
42
|
+
const platform = process.platform;
|
|
43
|
+
const cmd = platform === "win32"
|
|
44
|
+
? `start "" "${absPath}"`
|
|
45
|
+
: platform === "darwin"
|
|
46
|
+
? `open "${absPath}"`
|
|
47
|
+
: `xdg-open "${absPath}"`;
|
|
48
|
+
(0, child_process_1.exec)(cmd, (err) => (err ? reject(err) : resolve()));
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
function registerShowReport(program) {
|
|
52
|
+
program
|
|
53
|
+
.command("show-report")
|
|
54
|
+
.description("Open the latest Sela Insights healing report (sela-report.html) in the default browser")
|
|
55
|
+
.option("--file <path>", "Override path to the report file", "sela-report.html")
|
|
56
|
+
.option("--print", "Print the resolved path instead of opening the browser")
|
|
57
|
+
.action(async (opts) => {
|
|
58
|
+
const requested = opts.file ?? "sela-report.html";
|
|
59
|
+
const abs = path.isAbsolute(requested)
|
|
60
|
+
? requested
|
|
61
|
+
: path.resolve(process.cwd(), requested);
|
|
62
|
+
if (!fs.existsSync(abs)) {
|
|
63
|
+
process.stderr.write(`[sela] No report found at ${abs}\n` +
|
|
64
|
+
` Run your test suite first - the report is generated automatically when Sela performs at least one heal attempt.\n`);
|
|
65
|
+
process.exit(1);
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
if (opts.print) {
|
|
69
|
+
process.stdout.write(abs + "\n");
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
72
|
+
try {
|
|
73
|
+
await openInBrowser(abs);
|
|
74
|
+
process.stdout.write(`[sela] Opened ${abs}\n`);
|
|
75
|
+
}
|
|
76
|
+
catch (err) {
|
|
77
|
+
process.stderr.write(`[sela] Failed to open browser: ${err.message}\n`);
|
|
78
|
+
process.stderr.write(` Path: ${abs}\n`);
|
|
79
|
+
process.exit(1);
|
|
80
|
+
}
|
|
81
|
+
});
|
|
82
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"status.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/status.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAoCzC,wBAAgB,cAAc,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CA6BrD"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.registerStatus = registerStatus;
|
|
4
|
+
const ConfigLoader_js_1 = require("../../config/ConfigLoader.js");
|
|
5
|
+
const DnaIndexService_js_1 = require("../../services/DnaIndexService.js");
|
|
6
|
+
const HealthReportService_js_1 = require("../../services/HealthReportService.js");
|
|
7
|
+
const ProgressReporter_js_1 = require("../ui/ProgressReporter.js");
|
|
8
|
+
// Compact JSON shape for CI/CD consumers - avoids serialising full DnaRecord arrays.
|
|
9
|
+
function toJsonOutput(report) {
|
|
10
|
+
const { total, orphaned, recentlyHealed, neverHealed, topHealedFiles } = report;
|
|
11
|
+
const brokenTotal = orphaned.length + report.unverifiedHeals.length;
|
|
12
|
+
const brokenRatio = total > 0 ? parseFloat(((brokenTotal / total) * 100).toFixed(2)) : 0;
|
|
13
|
+
return {
|
|
14
|
+
generatedAt: report.generatedAt,
|
|
15
|
+
snapshotDir: report.snapshotDir,
|
|
16
|
+
stats: {
|
|
17
|
+
total,
|
|
18
|
+
orphaned: orphaned.length,
|
|
19
|
+
unverifiedHeals: report.unverifiedHeals.length,
|
|
20
|
+
healedLast7Days: recentlyHealed.length,
|
|
21
|
+
healedAllTime: total - neverHealed.length,
|
|
22
|
+
neverHealed: neverHealed.length,
|
|
23
|
+
brokenRatioPct: brokenRatio,
|
|
24
|
+
},
|
|
25
|
+
orphanedKeys: orphaned.map((r) => r.key),
|
|
26
|
+
unverifiedKeys: report.unverifiedHeals.map((r) => r.key),
|
|
27
|
+
topHealedFiles: topHealedFiles.slice(0, 10),
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
function registerStatus(program) {
|
|
31
|
+
program
|
|
32
|
+
.command("status")
|
|
33
|
+
.description("Show ecosystem health report")
|
|
34
|
+
.option("--json", "Emit raw JSON instead of formatted output")
|
|
35
|
+
.option("--dir <path>", "Override snapshot directory")
|
|
36
|
+
.action(async (opts) => {
|
|
37
|
+
const config = ConfigLoader_js_1.ConfigLoader.getInstance();
|
|
38
|
+
const snapshotDir = opts.dir ?? config.dnaStoragePath;
|
|
39
|
+
const progress = new ProgressReporter_js_1.ProgressReporter(opts.json);
|
|
40
|
+
const dnaIndex = new DnaIndexService_js_1.DnaIndexService();
|
|
41
|
+
const index = await progress.run("Scanning DNA snapshots…", () => dnaIndex.buildIndex(snapshotDir));
|
|
42
|
+
const healthSvc = new HealthReportService_js_1.HealthReportService();
|
|
43
|
+
const report = await progress.run("Generating health report…", async () => healthSvc.generate(index));
|
|
44
|
+
if (opts.json) {
|
|
45
|
+
process.stdout.write(JSON.stringify(toJsonOutput(report), null, 2) + "\n");
|
|
46
|
+
}
|
|
47
|
+
else {
|
|
48
|
+
process.stdout.write(healthSvc.format(report));
|
|
49
|
+
}
|
|
50
|
+
});
|
|
51
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sync.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/sync.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAgBzC,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,OAAO,GAAG,IAAI,CA+LrD"}
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.registerSyncSource = registerSyncSource;
|
|
7
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
8
|
+
const path_1 = __importDefault(require("path"));
|
|
9
|
+
const ConfigLoader_js_1 = require("../../config/ConfigLoader.js");
|
|
10
|
+
const DnaIndexService_js_1 = require("../../services/DnaIndexService.js");
|
|
11
|
+
const SourceLinkService_js_1 = require("../../services/SourceLinkService.js");
|
|
12
|
+
const ProgressReporter_js_1 = require("../ui/ProgressReporter.js");
|
|
13
|
+
function registerSyncSource(dna) {
|
|
14
|
+
dna
|
|
15
|
+
.command("sync-source <key>")
|
|
16
|
+
.description("Write current DNA selector back to .spec.ts via AST")
|
|
17
|
+
.option("--locator-index <n>", "Which locator on the line (0-based)", "0")
|
|
18
|
+
.option("--dry-run", "Preview without writing")
|
|
19
|
+
.option("--json", "Emit JSON result")
|
|
20
|
+
.option("--dir <path>", "Override snapshot directory")
|
|
21
|
+
.action(async (key, opts) => {
|
|
22
|
+
const config = ConfigLoader_js_1.ConfigLoader.getInstance();
|
|
23
|
+
const snapshotDir = opts.dir ?? config.dnaStoragePath;
|
|
24
|
+
const locatorIndex = Math.max(0, parseInt(opts.locatorIndex, 10) || 0);
|
|
25
|
+
const progress = new ProgressReporter_js_1.ProgressReporter(opts.json);
|
|
26
|
+
const dnaIndex = new DnaIndexService_js_1.DnaIndexService();
|
|
27
|
+
await progress.run("Scanning DNA snapshots…", () => dnaIndex.buildIndex(snapshotDir));
|
|
28
|
+
const record = dnaIndex.getByKey(key);
|
|
29
|
+
if (!record) {
|
|
30
|
+
if (opts.json) {
|
|
31
|
+
process.stdout.write(JSON.stringify({ success: false, reason: `DNA not found: ${key}` }, null, 2) + "\n");
|
|
32
|
+
process.exit(3);
|
|
33
|
+
}
|
|
34
|
+
const err = new Error(`DNA not found: ${key}`);
|
|
35
|
+
err.code = "DNA_NOT_FOUND";
|
|
36
|
+
throw err;
|
|
37
|
+
}
|
|
38
|
+
if (!record.sourceFile || record.sourceLine <= 0) {
|
|
39
|
+
if (opts.json) {
|
|
40
|
+
process.stdout.write(JSON.stringify({
|
|
41
|
+
success: false,
|
|
42
|
+
reason: `DNA "${key}" has no sourceFile/sourceLine`,
|
|
43
|
+
}, null, 2) + "\n");
|
|
44
|
+
}
|
|
45
|
+
else {
|
|
46
|
+
process.stdout.write(chalk_1.default.yellow(` ⚠ DNA "${key}" has no sourceFile/sourceLine - cannot sync.\n`));
|
|
47
|
+
}
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
const sourceLink = new SourceLinkService_js_1.SourceLinkService();
|
|
51
|
+
const locators = await progress.run("Analyzing AST for locator update…", async () => sourceLink.enumerateLocatorsOnLine(record.sourceFile, record.sourceLine));
|
|
52
|
+
const target = locators[locatorIndex] ?? locators[0];
|
|
53
|
+
const relPath = path_1.default.relative(process.cwd(), record.sourceFile);
|
|
54
|
+
if (!opts.json) {
|
|
55
|
+
process.stdout.write("\n");
|
|
56
|
+
process.stdout.write(` ${chalk_1.default.bold("DNA selector:")} ${chalk_1.default.green(record.selector)}\n`);
|
|
57
|
+
process.stdout.write(` ${chalk_1.default.bold("Source file:")} ${relPath}:${record.sourceLine}\n`);
|
|
58
|
+
}
|
|
59
|
+
if (!target) {
|
|
60
|
+
if (opts.json) {
|
|
61
|
+
process.stdout.write(JSON.stringify({
|
|
62
|
+
success: false,
|
|
63
|
+
reason: `No locator at index ${locatorIndex} on line ${record.sourceLine}`,
|
|
64
|
+
}, null, 2) + "\n");
|
|
65
|
+
}
|
|
66
|
+
else {
|
|
67
|
+
process.stdout.write(chalk_1.default.yellow(` ⚠ No locator found at index ${locatorIndex} on line ${record.sourceLine}.\n\n`));
|
|
68
|
+
}
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
if (!opts.json) {
|
|
72
|
+
process.stdout.write(` ${chalk_1.default.bold("Locator found:")} [${locatorIndex}] ${chalk_1.default.yellow(target.preview)}\n`);
|
|
73
|
+
process.stdout.write(` ${chalk_1.default.bold("Current value:")} ${chalk_1.default.red(target.selector)}\n`);
|
|
74
|
+
process.stdout.write(` ${chalk_1.default.bold("Will become:")} ${chalk_1.default.green(record.selector)}\n\n`);
|
|
75
|
+
}
|
|
76
|
+
if (target.selector === record.selector) {
|
|
77
|
+
if (opts.json) {
|
|
78
|
+
process.stdout.write(JSON.stringify({ success: true, reason: "Already in sync - nothing to do" }, null, 2) + "\n");
|
|
79
|
+
}
|
|
80
|
+
else {
|
|
81
|
+
process.stdout.write(chalk_1.default.dim(" Source already matches DNA selector. Nothing to do.\n\n"));
|
|
82
|
+
}
|
|
83
|
+
return;
|
|
84
|
+
}
|
|
85
|
+
if (opts.dryRun) {
|
|
86
|
+
if (opts.json) {
|
|
87
|
+
process.stdout.write(JSON.stringify({
|
|
88
|
+
dryRun: true,
|
|
89
|
+
key,
|
|
90
|
+
sourceFile: record.sourceFile,
|
|
91
|
+
sourceLine: record.sourceLine,
|
|
92
|
+
locatorIndex,
|
|
93
|
+
oldSelector: target.selector,
|
|
94
|
+
newSelector: record.selector,
|
|
95
|
+
}, null, 2) + "\n");
|
|
96
|
+
}
|
|
97
|
+
else {
|
|
98
|
+
process.stdout.write(chalk_1.default.dim(" [dry-run] No files written.\n\n"));
|
|
99
|
+
}
|
|
100
|
+
return;
|
|
101
|
+
}
|
|
102
|
+
const patch = {
|
|
103
|
+
key,
|
|
104
|
+
field: "selector",
|
|
105
|
+
oldValue: target.selector,
|
|
106
|
+
newValue: record.selector,
|
|
107
|
+
applySourceUpdate: true,
|
|
108
|
+
locatorIndex,
|
|
109
|
+
};
|
|
110
|
+
const result = await progress.run("Applying AST source update…", () => sourceLink.applySourceUpdate(record, patch));
|
|
111
|
+
if (opts.json) {
|
|
112
|
+
process.stdout.write(JSON.stringify(result, null, 2) + "\n");
|
|
113
|
+
if (!result.success)
|
|
114
|
+
process.exit(5);
|
|
115
|
+
}
|
|
116
|
+
else {
|
|
117
|
+
if (result.success) {
|
|
118
|
+
const lineInfo = result.lineUpdated
|
|
119
|
+
? ` (line ${result.lineUpdated})`
|
|
120
|
+
: "";
|
|
121
|
+
process.stdout.write(` ${chalk_1.default.green("✓")} Source updated${lineInfo}\n\n`);
|
|
122
|
+
}
|
|
123
|
+
else {
|
|
124
|
+
process.stdout.write(` ${chalk_1.default.red("✗")} Source update failed: ${result.reason}\n\n`);
|
|
125
|
+
const err = new Error(result.reason);
|
|
126
|
+
err.code = "AST_ERROR";
|
|
127
|
+
throw err;
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
});
|
|
131
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
// Load .env from CWD before anything else reads process.env
|
|
37
|
+
const path = __importStar(require("path"));
|
|
38
|
+
try {
|
|
39
|
+
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
40
|
+
require("dotenv").config({ path: path.join(process.cwd(), ".env") });
|
|
41
|
+
}
|
|
42
|
+
catch {
|
|
43
|
+
// dotenv missing or .env absent - continue silently
|
|
44
|
+
}
|
|
45
|
+
const commander_1 = require("commander");
|
|
46
|
+
const logger_js_1 = require("../utils/logger.js");
|
|
47
|
+
const ErrorHandler_js_1 = require("./ErrorHandler.js");
|
|
48
|
+
const init_js_1 = require("./commands/init.js");
|
|
49
|
+
const status_js_1 = require("./commands/status.js");
|
|
50
|
+
const list_js_1 = require("./commands/list.js");
|
|
51
|
+
const find_js_1 = require("./commands/find.js");
|
|
52
|
+
const refactor_js_1 = require("./commands/refactor.js");
|
|
53
|
+
const bulk_js_1 = require("./commands/bulk.js");
|
|
54
|
+
const sync_js_1 = require("./commands/sync.js");
|
|
55
|
+
const showReport_js_1 = require("./commands/showReport.js");
|
|
56
|
+
const merge_js_1 = require("./commands/merge.js");
|
|
57
|
+
(0, ErrorHandler_js_1.registerGlobalHandlers)();
|
|
58
|
+
// Safety net: route any stray third-party console.log through the Logger's
|
|
59
|
+
// verbosity-gated debug channel (stderr) so stdout stays pipe-clean and the
|
|
60
|
+
// terminal isn't spammed in default mode. First-party diagnostics already use
|
|
61
|
+
// the Logger directly.
|
|
62
|
+
console.log = (...args) => logger_js_1.logger.debug(args.map(String).join(" "));
|
|
63
|
+
const program = new commander_1.Command();
|
|
64
|
+
program
|
|
65
|
+
.name("sela")
|
|
66
|
+
.description("Sela CLI - proactive DNA management for Sela")
|
|
67
|
+
.version("1.0.3")
|
|
68
|
+
.exitOverride(ErrorHandler_js_1.handleError)
|
|
69
|
+
.configureOutput({ outputError: () => { } });
|
|
70
|
+
// ── sela init ────────────────────────────────────────────────────────────────
|
|
71
|
+
(0, init_js_1.registerInit)(program);
|
|
72
|
+
// ── sela status (T-06) ────────────────────────────────────────────────────────
|
|
73
|
+
(0, status_js_1.registerStatus)(program);
|
|
74
|
+
// ── sela list (T-07) ─────────────────────────────────────────────────────────
|
|
75
|
+
(0, list_js_1.registerList)(program);
|
|
76
|
+
// ── sela show-report - open Sela Insights HTML ───────────────────────────────
|
|
77
|
+
(0, showReport_js_1.registerShowReport)(program);
|
|
78
|
+
// ── sela merge - CI fan-in: aggregate sharded reports into one ────────────────
|
|
79
|
+
(0, merge_js_1.registerMerge)(program);
|
|
80
|
+
// ── sela dna <subcommand> ─────────────────────────────────────────────────────
|
|
81
|
+
const dna = new commander_1.Command("dna")
|
|
82
|
+
.description("DNA management commands")
|
|
83
|
+
.exitOverride(ErrorHandler_js_1.handleError)
|
|
84
|
+
.configureOutput({ outputError: () => { } });
|
|
85
|
+
// ── sela dna find (T-08) ─────────────────────────────────────────────────────
|
|
86
|
+
(0, find_js_1.registerFind)(dna);
|
|
87
|
+
// ── sela dna refactor (T-12/T-13) ────────────────────────────────────────────
|
|
88
|
+
(0, refactor_js_1.registerRefactor)(dna);
|
|
89
|
+
// ── sela dna bulk-update (T-14) ───────────────────────────────────────────────
|
|
90
|
+
(0, bulk_js_1.registerBulkUpdate)(dna);
|
|
91
|
+
// ── sela dna sync-source (T-15) ───────────────────────────────────────────────
|
|
92
|
+
(0, sync_js_1.registerSyncSource)(dna);
|
|
93
|
+
program.addCommand(dna);
|
|
94
|
+
program.parseAsync(process.argv).catch(ErrorHandler_js_1.handleError);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DnaTable.d.ts","sourceRoot":"","sources":["../../../src/cli/ui/DnaTable.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;AAkDzD,wBAAgB,WAAW,CAAC,OAAO,EAAE,SAAS,EAAE,GAAG,MAAM,CAoBxD"}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.renderTable = renderTable;
|
|
7
|
+
const cli_table3_1 = __importDefault(require("cli-table3"));
|
|
8
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
9
|
+
const path_1 = __importDefault(require("path"));
|
|
10
|
+
// Truncate before chalk so ANSI codes don't corrupt visual width calculations.
|
|
11
|
+
function trunc(s, maxLen, fallback = "-") {
|
|
12
|
+
if (s == null || s.trim() === "")
|
|
13
|
+
return chalk_1.default.dim(fallback);
|
|
14
|
+
return s.length <= maxLen ? s : s.slice(0, maxLen - 1) + "…";
|
|
15
|
+
}
|
|
16
|
+
function relativeTime(iso) {
|
|
17
|
+
if (!iso)
|
|
18
|
+
return chalk_1.default.dim("never");
|
|
19
|
+
const d = Math.floor((Date.now() - new Date(iso).getTime()) / 86_400_000);
|
|
20
|
+
if (d === 0)
|
|
21
|
+
return chalk_1.default.green("today");
|
|
22
|
+
if (d < 7)
|
|
23
|
+
return `${d}d ago`;
|
|
24
|
+
if (d < 30)
|
|
25
|
+
return `${Math.floor(d / 7)}w ago`;
|
|
26
|
+
return `${Math.floor(d / 30)}mo ago`;
|
|
27
|
+
}
|
|
28
|
+
function statusBadge(r) {
|
|
29
|
+
if (r.isOrphaned)
|
|
30
|
+
return chalk_1.default.red("orphaned");
|
|
31
|
+
if (r.status === "healed")
|
|
32
|
+
return chalk_1.default.yellow("⚠ unverified");
|
|
33
|
+
if (r.status === "broken")
|
|
34
|
+
return chalk_1.default.red("broken");
|
|
35
|
+
if (r.lastHealed !== null)
|
|
36
|
+
return chalk_1.default.green("healed");
|
|
37
|
+
return chalk_1.default.cyan("active");
|
|
38
|
+
}
|
|
39
|
+
function sourceCell(r) {
|
|
40
|
+
if (!r.sourceFile)
|
|
41
|
+
return chalk_1.default.dim("-");
|
|
42
|
+
const rel = path_1.default.relative(process.cwd(), r.sourceFile);
|
|
43
|
+
const display = rel.length < r.sourceFile.length ? rel : r.sourceFile;
|
|
44
|
+
const suffix = r.sourceLine > 0 ? `:${r.sourceLine}` : "";
|
|
45
|
+
return trunc(display + suffix, 32);
|
|
46
|
+
}
|
|
47
|
+
// colWidths = content + 2 (1-space padding each side)
|
|
48
|
+
const COLS = {
|
|
49
|
+
head: [
|
|
50
|
+
"Key",
|
|
51
|
+
"Test Title",
|
|
52
|
+
"Source : Line",
|
|
53
|
+
"Selector",
|
|
54
|
+
"Last Healed",
|
|
55
|
+
"Status",
|
|
56
|
+
],
|
|
57
|
+
colWidths: [11, 24, 36, 44, 13, 11],
|
|
58
|
+
};
|
|
59
|
+
function renderTable(records) {
|
|
60
|
+
const table = new cli_table3_1.default({
|
|
61
|
+
head: COLS.head.map((h) => chalk_1.default.bold(h)),
|
|
62
|
+
colWidths: COLS.colWidths,
|
|
63
|
+
wordWrap: false,
|
|
64
|
+
style: { head: [], border: ["dim"] },
|
|
65
|
+
});
|
|
66
|
+
for (const r of records) {
|
|
67
|
+
table.push([
|
|
68
|
+
chalk_1.default.dim(r.key.slice(0, 9)),
|
|
69
|
+
trunc(r.testTitle, 22),
|
|
70
|
+
sourceCell(r),
|
|
71
|
+
chalk_1.default.yellow(trunc(r.selector, 42)),
|
|
72
|
+
relativeTime(r.lastHealed),
|
|
73
|
+
statusBadge(r),
|
|
74
|
+
]);
|
|
75
|
+
}
|
|
76
|
+
return table.toString();
|
|
77
|
+
}
|