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.
Files changed (267) hide show
  1. package/README.md +103 -0
  2. package/bin/sela.js +3 -0
  3. package/dist/cli/ErrorHandler.d.ts +10 -0
  4. package/dist/cli/ErrorHandler.d.ts.map +1 -0
  5. package/dist/cli/ErrorHandler.js +70 -0
  6. package/dist/cli/commands/bulk.d.ts +3 -0
  7. package/dist/cli/commands/bulk.d.ts.map +1 -0
  8. package/dist/cli/commands/bulk.js +158 -0
  9. package/dist/cli/commands/find.d.ts +3 -0
  10. package/dist/cli/commands/find.d.ts.map +1 -0
  11. package/dist/cli/commands/find.js +51 -0
  12. package/dist/cli/commands/init.d.ts +3 -0
  13. package/dist/cli/commands/init.d.ts.map +1 -0
  14. package/dist/cli/commands/init.js +166 -0
  15. package/dist/cli/commands/list.d.ts +3 -0
  16. package/dist/cli/commands/list.d.ts.map +1 -0
  17. package/dist/cli/commands/list.js +56 -0
  18. package/dist/cli/commands/merge.d.ts +13 -0
  19. package/dist/cli/commands/merge.d.ts.map +1 -0
  20. package/dist/cli/commands/merge.js +119 -0
  21. package/dist/cli/commands/refactor.d.ts +3 -0
  22. package/dist/cli/commands/refactor.d.ts.map +1 -0
  23. package/dist/cli/commands/refactor.js +30 -0
  24. package/dist/cli/commands/showReport.d.ts +3 -0
  25. package/dist/cli/commands/showReport.d.ts.map +1 -0
  26. package/dist/cli/commands/showReport.js +82 -0
  27. package/dist/cli/commands/status.d.ts +3 -0
  28. package/dist/cli/commands/status.d.ts.map +1 -0
  29. package/dist/cli/commands/status.js +51 -0
  30. package/dist/cli/commands/sync.d.ts +3 -0
  31. package/dist/cli/commands/sync.d.ts.map +1 -0
  32. package/dist/cli/commands/sync.js +131 -0
  33. package/dist/cli/index.d.ts +2 -0
  34. package/dist/cli/index.d.ts.map +1 -0
  35. package/dist/cli/index.js +94 -0
  36. package/dist/cli/ui/DnaTable.d.ts +3 -0
  37. package/dist/cli/ui/DnaTable.d.ts.map +1 -0
  38. package/dist/cli/ui/DnaTable.js +77 -0
  39. package/dist/cli/ui/LocatorPicker.d.ts +8 -0
  40. package/dist/cli/ui/LocatorPicker.d.ts.map +1 -0
  41. package/dist/cli/ui/LocatorPicker.js +33 -0
  42. package/dist/cli/ui/ProgressReporter.d.ts +11 -0
  43. package/dist/cli/ui/ProgressReporter.d.ts.map +1 -0
  44. package/dist/cli/ui/ProgressReporter.js +33 -0
  45. package/dist/cli/ui/RefactorWizard.d.ts +26 -0
  46. package/dist/cli/ui/RefactorWizard.d.ts.map +1 -0
  47. package/dist/cli/ui/RefactorWizard.js +295 -0
  48. package/dist/config/ConfigLoader.d.ts +16 -0
  49. package/dist/config/ConfigLoader.d.ts.map +1 -0
  50. package/dist/config/ConfigLoader.js +185 -0
  51. package/dist/config/DryRunGuard.d.ts +14 -0
  52. package/dist/config/DryRunGuard.d.ts.map +1 -0
  53. package/dist/config/DryRunGuard.js +80 -0
  54. package/dist/config/PathScopeGuard.d.ts +42 -0
  55. package/dist/config/PathScopeGuard.d.ts.map +1 -0
  56. package/dist/config/PathScopeGuard.js +192 -0
  57. package/dist/config/SelaConfig.d.ts +178 -0
  58. package/dist/config/SelaConfig.d.ts.map +1 -0
  59. package/dist/config/SelaConfig.js +141 -0
  60. package/dist/config/defineConfig.d.ts +3 -0
  61. package/dist/config/defineConfig.d.ts.map +1 -0
  62. package/dist/config/defineConfig.js +9 -0
  63. package/dist/engine/FixwrightEngine.d.ts +24 -0
  64. package/dist/engine/FixwrightEngine.d.ts.map +1 -0
  65. package/dist/engine/FixwrightEngine.js +403 -0
  66. package/dist/engine/HealingRegistry.d.ts +40 -0
  67. package/dist/engine/HealingRegistry.d.ts.map +1 -0
  68. package/dist/engine/HealingRegistry.js +99 -0
  69. package/dist/engine/SelaEngine.d.ts +57 -0
  70. package/dist/engine/SelaEngine.d.ts.map +1 -0
  71. package/dist/engine/SelaEngine.js +1146 -0
  72. package/dist/engine/singleton.d.ts +3 -0
  73. package/dist/engine/singleton.d.ts.map +1 -0
  74. package/dist/engine/singleton.js +5 -0
  75. package/dist/errors/SelaError.d.ts +146 -0
  76. package/dist/errors/SelaError.d.ts.map +1 -0
  77. package/dist/errors/SelaError.js +168 -0
  78. package/dist/fixtures/expectProxy.d.ts +12 -0
  79. package/dist/fixtures/expectProxy.d.ts.map +1 -0
  80. package/dist/fixtures/expectProxy.js +246 -0
  81. package/dist/fixtures/index.d.ts +30 -0
  82. package/dist/fixtures/index.d.ts.map +1 -0
  83. package/dist/fixtures/index.js +765 -0
  84. package/dist/fixtures/moduleExpect.d.ts +2 -0
  85. package/dist/fixtures/moduleExpect.d.ts.map +1 -0
  86. package/dist/fixtures/moduleExpect.js +54 -0
  87. package/dist/fixtures/proxyTag.d.ts +12 -0
  88. package/dist/fixtures/proxyTag.d.ts.map +1 -0
  89. package/dist/fixtures/proxyTag.js +45 -0
  90. package/dist/index.d.ts +9 -0
  91. package/dist/index.d.ts.map +1 -0
  92. package/dist/index.js +31 -0
  93. package/dist/reporter/SelaReporter.d.ts +165 -0
  94. package/dist/reporter/SelaReporter.d.ts.map +1 -0
  95. package/dist/reporter/SelaReporter.js +517 -0
  96. package/dist/services/ASTSourceUpdater.d.ts +143 -0
  97. package/dist/services/ASTSourceUpdater.d.ts.map +1 -0
  98. package/dist/services/ASTSourceUpdater.js +3514 -0
  99. package/dist/services/AnchorResolver.d.ts +157 -0
  100. package/dist/services/AnchorResolver.d.ts.map +1 -0
  101. package/dist/services/AnchorResolver.js +289 -0
  102. package/dist/services/ArgumentTypeAnalyzer.d.ts +26 -0
  103. package/dist/services/ArgumentTypeAnalyzer.d.ts.map +1 -0
  104. package/dist/services/ArgumentTypeAnalyzer.js +92 -0
  105. package/dist/services/BlastRadiusAnalyzer.d.ts +15 -0
  106. package/dist/services/BlastRadiusAnalyzer.d.ts.map +1 -0
  107. package/dist/services/BlastRadiusAnalyzer.js +107 -0
  108. package/dist/services/ChainValidator.d.ts +76 -0
  109. package/dist/services/ChainValidator.d.ts.map +1 -0
  110. package/dist/services/ChainValidator.js +570 -0
  111. package/dist/services/CrossFileHealer.d.ts +6 -0
  112. package/dist/services/CrossFileHealer.d.ts.map +1 -0
  113. package/dist/services/CrossFileHealer.js +135 -0
  114. package/dist/services/DecisionEngine.d.ts +51 -0
  115. package/dist/services/DecisionEngine.d.ts.map +1 -0
  116. package/dist/services/DecisionEngine.js +260 -0
  117. package/dist/services/DefinitionTracer.d.ts +41 -0
  118. package/dist/services/DefinitionTracer.d.ts.map +1 -0
  119. package/dist/services/DefinitionTracer.js +366 -0
  120. package/dist/services/DnaEditorService.d.ts +31 -0
  121. package/dist/services/DnaEditorService.d.ts.map +1 -0
  122. package/dist/services/DnaEditorService.js +217 -0
  123. package/dist/services/DnaIndexService.d.ts +24 -0
  124. package/dist/services/DnaIndexService.d.ts.map +1 -0
  125. package/dist/services/DnaIndexService.js +131 -0
  126. package/dist/services/HealBudget.d.ts +32 -0
  127. package/dist/services/HealBudget.d.ts.map +1 -0
  128. package/dist/services/HealBudget.js +85 -0
  129. package/dist/services/HealReportService.d.ts +161 -0
  130. package/dist/services/HealReportService.d.ts.map +1 -0
  131. package/dist/services/HealReportService.js +1039 -0
  132. package/dist/services/HealingAdvisory.d.ts +30 -0
  133. package/dist/services/HealingAdvisory.d.ts.map +1 -0
  134. package/dist/services/HealingAdvisory.js +51 -0
  135. package/dist/services/HealingCacheService.d.ts +135 -0
  136. package/dist/services/HealingCacheService.d.ts.map +1 -0
  137. package/dist/services/HealingCacheService.js +404 -0
  138. package/dist/services/HealthReportService.d.ts +10 -0
  139. package/dist/services/HealthReportService.d.ts.map +1 -0
  140. package/dist/services/HealthReportService.js +84 -0
  141. package/dist/services/InitializerUpdater.d.ts +16 -0
  142. package/dist/services/InitializerUpdater.d.ts.map +1 -0
  143. package/dist/services/InitializerUpdater.js +73 -0
  144. package/dist/services/IntentAuditor.d.ts +56 -0
  145. package/dist/services/IntentAuditor.d.ts.map +1 -0
  146. package/dist/services/IntentAuditor.js +326 -0
  147. package/dist/services/InteractiveReview.d.ts +15 -0
  148. package/dist/services/InteractiveReview.d.ts.map +1 -0
  149. package/dist/services/InteractiveReview.js +128 -0
  150. package/dist/services/LLMService.d.ts +121 -0
  151. package/dist/services/LLMService.d.ts.map +1 -0
  152. package/dist/services/LLMService.js +475 -0
  153. package/dist/services/MutationApplier.d.ts +69 -0
  154. package/dist/services/MutationApplier.d.ts.map +1 -0
  155. package/dist/services/MutationApplier.js +360 -0
  156. package/dist/services/PRAutomationService.d.ts +50 -0
  157. package/dist/services/PRAutomationService.d.ts.map +1 -0
  158. package/dist/services/PRAutomationService.js +760 -0
  159. package/dist/services/PendingPromptLedger.d.ts +51 -0
  160. package/dist/services/PendingPromptLedger.d.ts.map +1 -0
  161. package/dist/services/PendingPromptLedger.js +205 -0
  162. package/dist/services/ReportGenerator.d.ts +156 -0
  163. package/dist/services/ReportGenerator.d.ts.map +1 -0
  164. package/dist/services/ReportGenerator.js +278 -0
  165. package/dist/services/ReportMergeService.d.ts +95 -0
  166. package/dist/services/ReportMergeService.d.ts.map +1 -0
  167. package/dist/services/ReportMergeService.js +0 -0
  168. package/dist/services/SafetyGuard.d.ts +112 -0
  169. package/dist/services/SafetyGuard.d.ts.map +1 -0
  170. package/dist/services/SafetyGuard.js +87 -0
  171. package/dist/services/Sanitizer.d.ts +28 -0
  172. package/dist/services/Sanitizer.d.ts.map +1 -0
  173. package/dist/services/Sanitizer.js +142 -0
  174. package/dist/services/SanitizingAnthropic.d.ts +19 -0
  175. package/dist/services/SanitizingAnthropic.d.ts.map +1 -0
  176. package/dist/services/SanitizingAnthropic.js +84 -0
  177. package/dist/services/SelectorSanitizer.d.ts +52 -0
  178. package/dist/services/SelectorSanitizer.d.ts.map +1 -0
  179. package/dist/services/SelectorSanitizer.js +318 -0
  180. package/dist/services/SnapshotService.d.ts +11 -0
  181. package/dist/services/SnapshotService.d.ts.map +1 -0
  182. package/dist/services/SnapshotService.js +352 -0
  183. package/dist/services/SourceLinkService.d.ts +26 -0
  184. package/dist/services/SourceLinkService.d.ts.map +1 -0
  185. package/dist/services/SourceLinkService.js +165 -0
  186. package/dist/services/SourceUpdater.d.ts +45 -0
  187. package/dist/services/SourceUpdater.d.ts.map +1 -0
  188. package/dist/services/SourceUpdater.js +1091 -0
  189. package/dist/services/TemplateDiffService.d.ts +25 -0
  190. package/dist/services/TemplateDiffService.d.ts.map +1 -0
  191. package/dist/services/TemplateDiffService.js +334 -0
  192. package/dist/services/TraceBackEngine.d.ts +67 -0
  193. package/dist/services/TraceBackEngine.d.ts.map +1 -0
  194. package/dist/services/TraceBackEngine.js +672 -0
  195. package/dist/services/WorkspaceSnapshotService.d.ts +71 -0
  196. package/dist/services/WorkspaceSnapshotService.d.ts.map +1 -0
  197. package/dist/services/WorkspaceSnapshotService.js +200 -0
  198. package/dist/services/safety/PipelineContext.d.ts +63 -0
  199. package/dist/services/safety/PipelineContext.d.ts.map +1 -0
  200. package/dist/services/safety/PipelineContext.js +34 -0
  201. package/dist/services/safety/roleClassifier.d.ts +4 -0
  202. package/dist/services/safety/roleClassifier.d.ts.map +1 -0
  203. package/dist/services/safety/roleClassifier.js +233 -0
  204. package/dist/services/safety/rules/ConfidenceTierRule.d.ts +3 -0
  205. package/dist/services/safety/rules/ConfidenceTierRule.d.ts.map +1 -0
  206. package/dist/services/safety/rules/ConfidenceTierRule.js +32 -0
  207. package/dist/services/safety/rules/DangerousSinkRule.d.ts +10 -0
  208. package/dist/services/safety/rules/DangerousSinkRule.d.ts.map +1 -0
  209. package/dist/services/safety/rules/DangerousSinkRule.js +53 -0
  210. package/dist/services/safety/rules/FunctionalRoleRule.d.ts +3 -0
  211. package/dist/services/safety/rules/FunctionalRoleRule.d.ts.map +1 -0
  212. package/dist/services/safety/rules/FunctionalRoleRule.js +64 -0
  213. package/dist/services/safety/rules/HardConfidenceRule.d.ts +3 -0
  214. package/dist/services/safety/rules/HardConfidenceRule.d.ts.map +1 -0
  215. package/dist/services/safety/rules/HardConfidenceRule.js +22 -0
  216. package/dist/services/safety/rules/IntentAuditorRule.d.ts +3 -0
  217. package/dist/services/safety/rules/IntentAuditorRule.d.ts.map +1 -0
  218. package/dist/services/safety/rules/IntentAuditorRule.js +97 -0
  219. package/dist/services/safety/rules/SemanticOppositeRule.d.ts +3 -0
  220. package/dist/services/safety/rules/SemanticOppositeRule.d.ts.map +1 -0
  221. package/dist/services/safety/rules/SemanticOppositeRule.js +30 -0
  222. package/dist/services/safety/rules/StructuralOnlyRule.d.ts +3 -0
  223. package/dist/services/safety/rules/StructuralOnlyRule.d.ts.map +1 -0
  224. package/dist/services/safety/rules/StructuralOnlyRule.js +38 -0
  225. package/dist/services/safety/rules/VisibilityRule.d.ts +3 -0
  226. package/dist/services/safety/rules/VisibilityRule.d.ts.map +1 -0
  227. package/dist/services/safety/rules/VisibilityRule.js +53 -0
  228. package/dist/services/safety/rules/ZeroTrustRule.d.ts +3 -0
  229. package/dist/services/safety/rules/ZeroTrustRule.d.ts.map +1 -0
  230. package/dist/services/safety/rules/ZeroTrustRule.js +37 -0
  231. package/dist/services/safety/rules/index.d.ts +3 -0
  232. package/dist/services/safety/rules/index.d.ts.map +1 -0
  233. package/dist/services/safety/rules/index.js +34 -0
  234. package/dist/services/types.d.ts +59 -0
  235. package/dist/services/types.d.ts.map +1 -0
  236. package/dist/services/types.js +2 -0
  237. package/dist/storage/SnapshotManager.d.ts +5 -0
  238. package/dist/storage/SnapshotManager.d.ts.map +1 -0
  239. package/dist/storage/SnapshotManager.js +32 -0
  240. package/dist/types/index.d.ts +95 -0
  241. package/dist/types/index.d.ts.map +1 -0
  242. package/dist/types/index.js +7 -0
  243. package/dist/utils/DOMUtils.d.ts +49 -0
  244. package/dist/utils/DOMUtils.d.ts.map +1 -0
  245. package/dist/utils/DOMUtils.js +466 -0
  246. package/dist/utils/FileLock.d.ts +44 -0
  247. package/dist/utils/FileLock.d.ts.map +1 -0
  248. package/dist/utils/FileLock.js +189 -0
  249. package/dist/utils/IsolatedDiff.d.ts +45 -0
  250. package/dist/utils/IsolatedDiff.d.ts.map +1 -0
  251. package/dist/utils/IsolatedDiff.js +382 -0
  252. package/dist/utils/StackUtils.d.ts +11 -0
  253. package/dist/utils/StackUtils.d.ts.map +1 -0
  254. package/dist/utils/StackUtils.js +120 -0
  255. package/dist/utils/SummaryTable.d.ts +17 -0
  256. package/dist/utils/SummaryTable.d.ts.map +1 -0
  257. package/dist/utils/SummaryTable.js +37 -0
  258. package/dist/utils/atomicWrite.d.ts +9 -0
  259. package/dist/utils/atomicWrite.d.ts.map +1 -0
  260. package/dist/utils/atomicWrite.js +83 -0
  261. package/dist/utils/logger.d.ts +59 -0
  262. package/dist/utils/logger.d.ts.map +1 -0
  263. package/dist/utils/logger.js +123 -0
  264. package/dist/vendor/enquirer.d.ts +33 -0
  265. package/dist/vendor/enquirer.d.ts.map +1 -0
  266. package/dist/vendor/enquirer.js +11 -0
  267. package/package.json +71 -0
@@ -0,0 +1,53 @@
1
+ "use strict";
2
+ // src/services/safety/rules/DangerousSinkRule.ts
3
+ //
4
+ // Step 5.5 - Dangerous-Sink escalation (context-mutator, returns null).
5
+ //
6
+ // Closes the headline blind spot from the incident: a heal that transitions
7
+ // INTO a destructive or auth role (e.g. "Update System"(UNKNOWN) →
8
+ // "delete System"(DELETE)) sailed through as SAFE because:
9
+ // - the cross-role swap rule (step 5) only fires when BOTH roles are known,
10
+ // - the auditor gate (step 6) only fired for zero-trust / assertion /
11
+ // both-UNKNOWN, none of which matched.
12
+ //
13
+ // Per design decision #2, this rule does NOT decide on its own; it FORCES
14
+ // the Intent Auditor to run (ctx.forceAudit = true) whenever the new role is
15
+ // a dangerous sink and differs from the old role. The auditor's existing
16
+ // verdict mapping then applies: INCONSISTENT → FAIL_HARD, SUSPICIOUS →
17
+ // BLOCKED/REQUIRES_REVIEW, CONSISTENT → continue.
18
+ //
19
+ // Note on coverage: a swap between two KNOWN roles (e.g. SUBMIT → DELETE)
20
+ // is already short-circuited by FunctionalRoleRule before reaching here, so
21
+ // in practice this rule fires for the UNKNOWN→sink case it was built for.
22
+ Object.defineProperty(exports, "__esModule", { value: true });
23
+ exports.DangerousSinkRule = exports.DANGEROUS_SINK_ROLES = void 0;
24
+ exports.isDangerousSinkTransition = isDangerousSinkTransition;
25
+ const roleClassifier_1 = require("../roleClassifier");
26
+ const logger_1 = require("../../../utils/logger");
27
+ /**
28
+ * Roles whose ARRIVAL is treated as high-risk: a control that did not
29
+ * obviously mean "delete" or "authenticate" before, but now does.
30
+ */
31
+ exports.DANGEROUS_SINK_ROLES = new Set([
32
+ "DELETE",
33
+ "AUTH",
34
+ ]);
35
+ function isDangerousSinkTransition(oldRole, newRole) {
36
+ return exports.DANGEROUS_SINK_ROLES.has(newRole) && newRole !== oldRole;
37
+ }
38
+ exports.DangerousSinkRule = {
39
+ id: "dangerous-sink-escalation",
40
+ run(ctx) {
41
+ // Roles are set by FunctionalRoleRule; fall back to a fresh
42
+ // classification defensively if a future reorder runs this first.
43
+ const oldRole = ctx.oldRole ?? (0, roleClassifier_1.classifyFunctionalRole)(ctx.oldText ?? "");
44
+ const newRole = ctx.newRole ?? (0, roleClassifier_1.classifyFunctionalRole)(ctx.newText ?? "");
45
+ if (isDangerousSinkTransition(oldRole, newRole)) {
46
+ logger_1.logger.warn(`SafetyGuard dangerous-sink transition: ` +
47
+ `"${ctx.oldText}" (${oldRole}) → "${ctx.newText}" (${newRole}) - ` +
48
+ `forcing Intent Auditor`);
49
+ ctx.forceAudit = true;
50
+ }
51
+ return null;
52
+ },
53
+ };
@@ -0,0 +1,3 @@
1
+ import type { SafetyRule } from "../PipelineContext";
2
+ export declare const FunctionalRoleRule: SafetyRule;
3
+ //# sourceMappingURL=FunctionalRoleRule.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FunctionalRoleRule.d.ts","sourceRoot":"","sources":["../../../../src/services/safety/rules/FunctionalRoleRule.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,UAAU,EAAqC,MAAM,oBAAoB,CAAC;AAExF,eAAO,MAAM,kBAAkB,EAAE,UA6DhC,CAAC"}
@@ -0,0 +1,64 @@
1
+ "use strict";
2
+ // src/services/safety/rules/FunctionalRoleRule.ts
3
+ //
4
+ // Step 5 - Functional role analysis. Classifies old/new text into the
5
+ // functional taxonomy and pins the roles onto the context for the
6
+ // auditor gate. STATUS_POSITIVE ↔ STATUS_NEGATIVE is always a logic
7
+ // inversion (FAIL_HARD). A cross-role swap between two known roles is
8
+ // BLOCKED in assertion mode and REQUIRES_REVIEW in action mode.
9
+ //
10
+ // Extracted verbatim - identical classification log, reasons, codes,
11
+ // and the action-mode warning.
12
+ Object.defineProperty(exports, "__esModule", { value: true });
13
+ exports.FunctionalRoleRule = void 0;
14
+ const SelaError_1 = require("../../../errors/SelaError");
15
+ const roleClassifier_1 = require("../roleClassifier");
16
+ const logger_1 = require("../../../utils/logger");
17
+ exports.FunctionalRoleRule = {
18
+ id: "functional-role-analysis",
19
+ run(ctx) {
20
+ const oldText = ctx.oldText;
21
+ const newText = ctx.newText;
22
+ const oldRole = (0, roleClassifier_1.classifyFunctionalRole)(oldText);
23
+ const newRole = (0, roleClassifier_1.classifyFunctionalRole)(newText);
24
+ ctx.oldRole = oldRole;
25
+ ctx.newRole = newRole;
26
+ logger_1.logger.debug(`SafetyGuard role classification: "${oldText}"→${oldRole}, "${newText}"→${newRole}`);
27
+ // STATUS_POSITIVE ↔ STATUS_NEGATIVE is always a logic inversion
28
+ const isStatusInversion = (oldRole === "STATUS_POSITIVE" && newRole === "STATUS_NEGATIVE") ||
29
+ (oldRole === "STATUS_NEGATIVE" && newRole === "STATUS_POSITIVE");
30
+ if (isStatusInversion) {
31
+ return {
32
+ level: "FAIL_HARD",
33
+ code: SelaError_1.SAFETY_GUARD_CODES.FAIL_HARD_STATUS_INVERSION,
34
+ reason: `Status inversion: "${oldText}" (${oldRole}) → "${newText}" (${newRole}) - ` +
35
+ `masking a logic failure is not permitted`,
36
+ canProceed: false,
37
+ };
38
+ }
39
+ // Cross-role swap (e.g. DELETE → CANCEL, SUBMIT → NAVIGATE)
40
+ if (oldRole !== "UNKNOWN" && newRole !== "UNKNOWN" && oldRole !== newRole) {
41
+ if (ctx.mode === "assertion") {
42
+ // Assertion explicitly checked the old functional text; a different
43
+ // function being found is almost certainly a wrong element fix.
44
+ return {
45
+ level: "BLOCKED",
46
+ code: SelaError_1.SAFETY_GUARD_CODES.BLOCKED_ROLE_SWAP_ASSERTION,
47
+ reason: `Functional role swap in assertion: "${oldText}" (${oldRole}) → "${newText}" (${newRole}) - ` +
48
+ `the assertion was verifying a specific functional state`,
49
+ canProceed: false,
50
+ };
51
+ }
52
+ // Action mode: allow with warning - a UI refactor may rename a control
53
+ // (e.g. "Delete" button renamed "Remove" or merged into a menu)
54
+ logger_1.logger.warn(`SafetyGuard functional role change in action: ` +
55
+ `"${oldText}" (${oldRole}) → "${newText}" (${newRole}) - review recommended`);
56
+ return {
57
+ level: "REQUIRES_REVIEW",
58
+ reason: `Functional role change in action: "${oldText}" (${oldRole}) → "${newText}" (${newRole})`,
59
+ canProceed: true,
60
+ };
61
+ }
62
+ return null;
63
+ },
64
+ };
@@ -0,0 +1,3 @@
1
+ import type { SafetyRule } from "../PipelineContext";
2
+ export declare const HardConfidenceRule: SafetyRule;
3
+ //# sourceMappingURL=HardConfidenceRule.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"HardConfidenceRule.d.ts","sourceRoot":"","sources":["../../../../src/services/safety/rules/HardConfidenceRule.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,UAAU,EAAqC,MAAM,oBAAoB,CAAC;AAExF,eAAO,MAAM,kBAAkB,EAAE,UAahC,CAAC"}
@@ -0,0 +1,22 @@
1
+ "use strict";
2
+ // src/services/safety/rules/HardConfidenceRule.ts
3
+ //
4
+ // Step 1 - Hard confidence stop. Heals below confidenceHardStop are
5
+ // always BLOCKED, before any content reasoning. Extracted verbatim.
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.HardConfidenceRule = void 0;
8
+ const SelaError_1 = require("../../../errors/SelaError");
9
+ exports.HardConfidenceRule = {
10
+ id: "hard-confidence-stop",
11
+ run(ctx) {
12
+ if (ctx.confidence < ctx.thresholds.confidenceHardStop) {
13
+ return {
14
+ level: "BLOCKED",
15
+ code: SelaError_1.SAFETY_GUARD_CODES.BLOCKED_LOW_CONFIDENCE,
16
+ reason: `Confidence too low (${ctx.confidence}/100 < ${ctx.thresholds.confidenceHardStop}) - refusing to heal`,
17
+ canProceed: false,
18
+ };
19
+ }
20
+ return null;
21
+ },
22
+ };
@@ -0,0 +1,3 @@
1
+ import type { SafetyRule } from "../PipelineContext";
2
+ export declare const IntentAuditorRule: SafetyRule;
3
+ //# sourceMappingURL=IntentAuditorRule.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"IntentAuditorRule.d.ts","sourceRoot":"","sources":["../../../../src/services/safety/rules/IntentAuditorRule.ts"],"names":[],"mappings":"AAiBA,OAAO,KAAK,EAAE,UAAU,EAAqC,MAAM,oBAAoB,CAAC;AAExF,eAAO,MAAM,iBAAiB,EAAE,UAyF/B,CAAC"}
@@ -0,0 +1,97 @@
1
+ "use strict";
2
+ // src/services/safety/rules/IntentAuditorRule.ts
3
+ //
4
+ // Step 6/7 - Intent Auditor gate + verdict mapping. Calls the secondary
5
+ // LLM auditor when:
6
+ // a) zero-trust synthesized the contentChange (AI silent → extra scrutiny), OR
7
+ // b) we are in assertion mode (the test explicitly checked the text), OR
8
+ // c) both roles are UNKNOWN (no functional category to fall back on).
9
+ //
10
+ // INCONSISTENT → FAIL_HARD. SUSPICIOUS → BLOCKED in assertion (unless
11
+ // allowSuspicious) else REQUIRES_REVIEW. CONSISTENT → fall through,
12
+ // stashing the auditor score breakdown on the context for the final tier.
13
+ //
14
+ // Extracted verbatim - identical trigger condition, reasons, codes,
15
+ // logs, and meta shape.
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ exports.IntentAuditorRule = void 0;
18
+ const SelaError_1 = require("../../../errors/SelaError");
19
+ const logger_1 = require("../../../utils/logger");
20
+ exports.IntentAuditorRule = {
21
+ id: "intent-auditor-gate",
22
+ async run(ctx) {
23
+ const oldText = ctx.oldText;
24
+ const newText = ctx.newText;
25
+ const oldRole = ctx.oldRole;
26
+ const newRole = ctx.newRole;
27
+ const shouldAudit = ctx.forceAudit === true ||
28
+ ctx.source === "zero-trust" ||
29
+ ctx.mode === "assertion" ||
30
+ (oldRole === "UNKNOWN" && newRole === "UNKNOWN");
31
+ if (!shouldAudit)
32
+ return null;
33
+ const auditVerdict = await ctx.auditor.auditIntent({
34
+ dnaText: oldText,
35
+ dnaRole: ctx.aiFix.dnaRole,
36
+ liveText: newText,
37
+ healMode: ctx.mode,
38
+ // v2 structural context forwarded for scoring
39
+ dnaAncestry: ctx.aiFix.dnaAncestry,
40
+ liveAncestry: ctx.aiFix.liveAncestry,
41
+ dnaAnchors: ctx.aiFix.dnaAnchors,
42
+ liveAnchors: ctx.aiFix.liveAnchors,
43
+ });
44
+ if (auditVerdict.verdict === "INCONSISTENT") {
45
+ return {
46
+ level: "FAIL_HARD",
47
+ code: SelaError_1.SAFETY_GUARD_CODES.FAIL_HARD_AUDITOR_INCONSISTENT,
48
+ reason: `Intent Auditor - INCONSISTENT: ${auditVerdict.reason}` +
49
+ (auditVerdict.inversionType
50
+ ? ` [inversion: ${auditVerdict.inversionType}]`
51
+ : ""),
52
+ canProceed: false,
53
+ };
54
+ }
55
+ if (auditVerdict.verdict === "SUSPICIOUS") {
56
+ const meta = {
57
+ auditorVerdict: "SUSPICIOUS",
58
+ auditorConfidence: auditVerdict.confidence,
59
+ };
60
+ // Block by default in assertion mode; allowSuspicious (loose policy) downgrades to REQUIRES_REVIEW
61
+ if (!ctx.thresholds.allowSuspicious && ctx.mode === "assertion") {
62
+ return {
63
+ level: "BLOCKED",
64
+ code: SelaError_1.SAFETY_GUARD_CODES.BLOCKED_AUDITOR_SUSPICIOUS,
65
+ reason: `Intent Auditor - SUSPICIOUS in assertion mode: ${auditVerdict.reason}`,
66
+ canProceed: false,
67
+ meta,
68
+ };
69
+ }
70
+ if (ctx.thresholds.allowSuspicious && ctx.mode === "assertion") {
71
+ logger_1.logger.debug("SafetyGuard allowSuspicious=true - SUSPICIOUS in assertion mode escalated to REQUIRES_REVIEW");
72
+ }
73
+ return {
74
+ level: "REQUIRES_REVIEW",
75
+ reason: `Intent Auditor - SUSPICIOUS in ${ctx.mode} mode: ${auditVerdict.reason}`,
76
+ canProceed: true,
77
+ meta,
78
+ };
79
+ }
80
+ // CONSISTENT - fall through to confidence tiers
81
+ logger_1.logger.debug(`SafetyGuard Intent Auditor - CONSISTENT (${auditVerdict.confidence}%): ${auditVerdict.reason}`);
82
+ if (auditVerdict.scoreBreakdown) {
83
+ const { rawConfidence, penalty, bonus } = auditVerdict.scoreBreakdown;
84
+ if (penalty !== 0 || bonus !== 0) {
85
+ ctx.localAuditMeta = {
86
+ auditScoreBreakdown: {
87
+ rawConfidence,
88
+ penalty,
89
+ bonus,
90
+ adjustedConfidence: auditVerdict.confidence,
91
+ },
92
+ };
93
+ }
94
+ }
95
+ return null;
96
+ },
97
+ };
@@ -0,0 +1,3 @@
1
+ import type { SafetyRule } from "../PipelineContext";
2
+ export declare const SemanticOppositeRule: SafetyRule;
3
+ //# sourceMappingURL=SemanticOppositeRule.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SemanticOppositeRule.d.ts","sourceRoot":"","sources":["../../../../src/services/safety/rules/SemanticOppositeRule.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,UAAU,EAAqC,MAAM,oBAAoB,CAAC;AAExF,eAAO,MAAM,oBAAoB,EAAE,UAqBlC,CAAC"}
@@ -0,0 +1,30 @@
1
+ "use strict";
2
+ // src/services/safety/rules/SemanticOppositeRule.ts
3
+ //
4
+ // Step 4 - Binary semantic-opposite guard. Applies in ALL modes:
5
+ // "Enabled"→"Disabled", "Success"→"Error", etc. always indicate a state
6
+ // inversion and are never safe to auto-heal. Extracted verbatim.
7
+ Object.defineProperty(exports, "__esModule", { value: true });
8
+ exports.SemanticOppositeRule = void 0;
9
+ const SelaError_1 = require("../../../errors/SelaError");
10
+ const roleClassifier_1 = require("../roleClassifier");
11
+ exports.SemanticOppositeRule = {
12
+ id: "semantic-opposite-guard",
13
+ run(ctx) {
14
+ // oldText/newText are guaranteed set: StructuralOnlyRule populates
15
+ // them whenever an effective content change exists, and returns a
16
+ // decision (short-circuit) otherwise.
17
+ const oldText = ctx.oldText;
18
+ const newText = ctx.newText;
19
+ if ((0, roleClassifier_1.isSemanticOpposite)(oldText, newText)) {
20
+ return {
21
+ level: "FAIL_HARD",
22
+ code: SelaError_1.SAFETY_GUARD_CODES.FAIL_HARD_SEMANTIC_INVERSION,
23
+ reason: `Semantic inversion detected: "${oldText}" ↔ "${newText}" - ` +
24
+ `state inversions mask logical regressions`,
25
+ canProceed: false,
26
+ };
27
+ }
28
+ return null;
29
+ },
30
+ };
@@ -0,0 +1,3 @@
1
+ import type { SafetyRule } from "../PipelineContext";
2
+ export declare const StructuralOnlyRule: SafetyRule;
3
+ //# sourceMappingURL=StructuralOnlyRule.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"StructuralOnlyRule.d.ts","sourceRoot":"","sources":["../../../../src/services/safety/rules/StructuralOnlyRule.ts"],"names":[],"mappings":"AAgBA,OAAO,KAAK,EAAE,UAAU,EAAqC,MAAM,oBAAoB,CAAC;AAExF,eAAO,MAAM,kBAAkB,EAAE,UAyBhC,CAAC"}
@@ -0,0 +1,38 @@
1
+ "use strict";
2
+ // src/services/safety/rules/StructuralOnlyRule.ts
3
+ //
4
+ // Step 3 - Structural-only heal. When no effective content change was
5
+ // detected (AI silent AND zero-trust found no live/DNA divergence), the
6
+ // selector moved but the text did not: SAFE at/above the review
7
+ // threshold, REQUIRES_REVIEW below it.
8
+ //
9
+ // When a content change DOES exist this rule is a context-mutator: it
10
+ // pins oldText/newText/source onto the context and emits the
11
+ // "Content change" log, then falls through (returns null) so the
12
+ // downstream inversion rules can reason about the pair. This keeps the
13
+ // exact ordering of the pre-refactor evaluate() (the log fired right
14
+ // after the structural-only check, before semantic-opposite analysis).
15
+ Object.defineProperty(exports, "__esModule", { value: true });
16
+ exports.StructuralOnlyRule = void 0;
17
+ const logger_1 = require("../../../utils/logger");
18
+ exports.StructuralOnlyRule = {
19
+ id: "structural-only-heal",
20
+ run(ctx) {
21
+ if (!ctx.effectiveContentChange) {
22
+ const level = ctx.confidence < ctx.thresholds.confidenceReviewThreshold
23
+ ? "REQUIRES_REVIEW"
24
+ : "SAFE";
25
+ return {
26
+ level,
27
+ reason: `Structural selector change only (confidence=${ctx.confidence})`,
28
+ canProceed: true,
29
+ };
30
+ }
31
+ const { oldText, newText } = ctx.effectiveContentChange;
32
+ ctx.oldText = oldText;
33
+ ctx.newText = newText;
34
+ ctx.source = ctx.aiFix.contentChange ? "AI-reported" : "zero-trust";
35
+ logger_1.logger.debug(`SafetyGuard content change (${ctx.source}): "${oldText}" → "${newText}"`);
36
+ return null;
37
+ },
38
+ };
@@ -0,0 +1,3 @@
1
+ import type { SafetyRule } from "../PipelineContext";
2
+ export declare const VisibilityRule: SafetyRule;
3
+ //# sourceMappingURL=VisibilityRule.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"VisibilityRule.d.ts","sourceRoot":"","sources":["../../../../src/services/safety/rules/VisibilityRule.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAE,UAAU,EAAqC,MAAM,oBAAoB,CAAC;AAExF,eAAO,MAAM,cAAc,EAAE,UAiD5B,CAAC"}
@@ -0,0 +1,53 @@
1
+ "use strict";
2
+ // src/services/safety/rules/VisibilityRule.ts
3
+ //
4
+ // Step 0 - Visibility Gate. Runs before any confidence or content
5
+ // checks: a ghost element can never be safely acted upon regardless of
6
+ // AI confidence. Occlusion policy is branch-dependent (hard-fail on
7
+ // main/master, REQUIRES_REVIEW elsewhere).
8
+ //
9
+ // Extracted verbatim from SafetyGuard.evaluate() - identical reasons,
10
+ // codes, and the same warning on the non-main occlusion path.
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.VisibilityRule = void 0;
13
+ const SelaError_1 = require("../../../errors/SelaError");
14
+ const logger_1 = require("../../../utils/logger");
15
+ exports.VisibilityRule = {
16
+ id: "visibility-gate",
17
+ run(ctx) {
18
+ const { liveVisibility } = ctx.aiFix;
19
+ if (!liveVisibility)
20
+ return null;
21
+ const vis = liveVisibility;
22
+ if (vis.isGhost) {
23
+ return {
24
+ level: "FAIL_HARD",
25
+ code: SelaError_1.SAFETY_GUARD_CODES.FAIL_HARD_VISIBILITY_GHOST,
26
+ reason: `Visibility Gate: candidate element is a Ghost (${vis.ghostReason}) - ` +
27
+ `functionally absent from the user's perspective`,
28
+ canProceed: false,
29
+ };
30
+ }
31
+ if (vis.isOccluded) {
32
+ const isMainBranch = ctx.branch === "main" || ctx.branch === "master";
33
+ if (isMainBranch) {
34
+ return {
35
+ level: "FAIL_HARD",
36
+ code: SelaError_1.SAFETY_GUARD_CODES.FAIL_HARD_VISIBILITY_OCCLUDED,
37
+ reason: `Visibility Gate: candidate element is occluded by an overlay on branch "${ctx.branch}" - ` +
38
+ `hard-fail policy active on main`,
39
+ canProceed: false,
40
+ };
41
+ }
42
+ logger_1.logger.warn(`SafetyGuard occlusion detected on branch "${ctx.branch ?? "unknown"}" - ` +
43
+ `escalating to REQUIRES_REVIEW (not hard-failing on non-main branch)`);
44
+ return {
45
+ level: "REQUIRES_REVIEW",
46
+ reason: `Visibility Gate: candidate element is occluded by an overlay ` +
47
+ `(branch: ${ctx.branch ?? "unknown"})`,
48
+ canProceed: true,
49
+ };
50
+ }
51
+ return null;
52
+ },
53
+ };
@@ -0,0 +1,3 @@
1
+ import type { SafetyRule } from "../PipelineContext";
2
+ export declare const ZeroTrustRule: SafetyRule;
3
+ //# sourceMappingURL=ZeroTrustRule.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ZeroTrustRule.d.ts","sourceRoot":"","sources":["../../../../src/services/safety/rules/ZeroTrustRule.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,UAAU,EAAqC,MAAM,oBAAoB,CAAC;AAExF,eAAO,MAAM,aAAa,EAAE,UA4B3B,CAAC"}
@@ -0,0 +1,37 @@
1
+ "use strict";
2
+ // src/services/safety/rules/ZeroTrustRule.ts
3
+ //
4
+ // Step 2 - Zero-Trust Verification (context-mutator, always returns null).
5
+ //
6
+ // The AI's contentChange field is self-reported and may be absent even
7
+ // when the element's text actually changed. When liveText +
8
+ // dnaBaselineText are both available and differ, we synthesize a
9
+ // contentChange pair so the full inversion-check pipeline runs on it
10
+ // regardless of what the AI reported. If the AI DID report
11
+ // contentChange we keep that (more precise than raw innerText).
12
+ //
13
+ // Extracted verbatim - identical synthesis condition and warning.
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ exports.ZeroTrustRule = void 0;
16
+ const logger_1 = require("../../../utils/logger");
17
+ exports.ZeroTrustRule = {
18
+ id: "zero-trust-verification",
19
+ run(ctx) {
20
+ const { liveText, dnaBaselineText } = ctx.aiFix;
21
+ let effectiveContentChange = ctx.aiFix.contentChange;
22
+ if (!effectiveContentChange &&
23
+ liveText !== undefined &&
24
+ dnaBaselineText !== undefined) {
25
+ const normLive = liveText.trim();
26
+ const normDNA = dnaBaselineText.trim();
27
+ if (normLive !== normDNA && normLive.length > 0 && normDNA.length > 0) {
28
+ logger_1.logger.warn(`SafetyGuard Zero-Trust override - AI omitted contentChange but live DOM differs:\n` +
29
+ ` DNA baseline : "${normDNA}"\n` +
30
+ ` Live text : "${normLive}"`);
31
+ effectiveContentChange = { oldText: normDNA, newText: normLive };
32
+ }
33
+ }
34
+ ctx.effectiveContentChange = effectiveContentChange;
35
+ return null;
36
+ },
37
+ };
@@ -0,0 +1,3 @@
1
+ import type { SafetyRule } from "../PipelineContext";
2
+ export declare const SAFETY_RULES: ReadonlyArray<SafetyRule>;
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/services/safety/rules/index.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAWrD,eAAO,MAAM,YAAY,EAAE,aAAa,CAAC,UAAU,CAUlD,CAAC"}
@@ -0,0 +1,34 @@
1
+ "use strict";
2
+ // src/services/safety/rules/index.ts
3
+ //
4
+ // The ordered SafetyGuard rule pipeline (chain-of-responsibility).
5
+ // Order IS the safety contract - it reproduces the exact priority of the
6
+ // pre-refactor evaluate():
7
+ //
8
+ // visibility > confidence > zero-trust(mutator) > structural-only >
9
+ // semantic-opposite > functional-role > intent-auditor > confidence-tier
10
+ //
11
+ // New rules (e.g. a dangerous-sink escalation) plug in as a single array
12
+ // entry at the correct position - no other code changes.
13
+ Object.defineProperty(exports, "__esModule", { value: true });
14
+ exports.SAFETY_RULES = void 0;
15
+ const VisibilityRule_1 = require("./VisibilityRule");
16
+ const HardConfidenceRule_1 = require("./HardConfidenceRule");
17
+ const ZeroTrustRule_1 = require("./ZeroTrustRule");
18
+ const StructuralOnlyRule_1 = require("./StructuralOnlyRule");
19
+ const SemanticOppositeRule_1 = require("./SemanticOppositeRule");
20
+ const FunctionalRoleRule_1 = require("./FunctionalRoleRule");
21
+ const DangerousSinkRule_1 = require("./DangerousSinkRule");
22
+ const IntentAuditorRule_1 = require("./IntentAuditorRule");
23
+ const ConfidenceTierRule_1 = require("./ConfidenceTierRule");
24
+ exports.SAFETY_RULES = [
25
+ VisibilityRule_1.VisibilityRule, // 0 - ghost / occlusion gate
26
+ HardConfidenceRule_1.HardConfidenceRule, // 1 - hard confidence stop
27
+ ZeroTrustRule_1.ZeroTrustRule, // 2 - synthesize contentChange (mutator)
28
+ StructuralOnlyRule_1.StructuralOnlyRule, // 3 - structural-only decide | pin oldText/newText (mutator)
29
+ SemanticOppositeRule_1.SemanticOppositeRule, // 4 - hardcoded opposite pairs
30
+ FunctionalRoleRule_1.FunctionalRoleRule, // 5 - role classification + status/cross-role swap
31
+ DangerousSinkRule_1.DangerousSinkRule, // 5.5 - force auditor on UNKNOWN→DELETE/AUTH (mutator)
32
+ IntentAuditorRule_1.IntentAuditorRule, // 6/7 - LLM auditor gate + verdict mapping
33
+ ConfidenceTierRule_1.ConfidenceTierRule, // 8 - terminal SAFE / REQUIRES_REVIEW tier
34
+ ];
@@ -0,0 +1,59 @@
1
+ export interface DnaRecord {
2
+ key: string;
3
+ filePath: string;
4
+ testTitle: string;
5
+ sourceFile: string;
6
+ sourceLine: number;
7
+ selector: string;
8
+ tagName: string;
9
+ text: string | null;
10
+ lastHealed: string | null;
11
+ schemaVersion: number;
12
+ isOrphaned: boolean;
13
+ /** 'healed' = AI auto-fixed, pending human verification. 'broken' = AI failed. undefined = healthy/verified. */
14
+ status?: 'healed' | 'broken';
15
+ }
16
+ export interface DnaIndex {
17
+ generatedAt: string;
18
+ snapshotDir: string;
19
+ records: DnaRecord[];
20
+ stats: {
21
+ total: number;
22
+ orphaned: number;
23
+ healedLast7Days: number;
24
+ healedAllTime: number;
25
+ };
26
+ }
27
+ export interface DnaEditPatch {
28
+ key: string;
29
+ field: 'selector' | 'text' | 'tagName' | 'attributes' | 'anchors';
30
+ oldValue: unknown;
31
+ newValue: unknown;
32
+ applySourceUpdate: boolean;
33
+ locatorIndex: number;
34
+ }
35
+ export interface BulkUpdateJob {
36
+ oldSelector: string;
37
+ newSelector: string;
38
+ dryRun: boolean;
39
+ targets: DnaRecord[];
40
+ results: Array<{
41
+ key: string;
42
+ success: boolean;
43
+ reason: string;
44
+ }>;
45
+ }
46
+ export interface HealthReport {
47
+ generatedAt: string;
48
+ snapshotDir: string;
49
+ total: number;
50
+ orphaned: DnaRecord[];
51
+ unverifiedHeals: DnaRecord[];
52
+ recentlyHealed: DnaRecord[];
53
+ neverHealed: DnaRecord[];
54
+ topHealedFiles: Array<{
55
+ sourceFile: string;
56
+ count: number;
57
+ }>;
58
+ }
59
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/services/types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,SAAS;IACxB,GAAG,EAAE,MAAM,CAAC;IACZ,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,aAAa,EAAE,MAAM,CAAC;IACtB,UAAU,EAAE,OAAO,CAAC;IACpB,gHAAgH;IAChH,MAAM,CAAC,EAAE,QAAQ,GAAG,QAAQ,CAAC;CAC9B;AAED,MAAM,WAAW,QAAQ;IACvB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,SAAS,EAAE,CAAC;IACrB,KAAK,EAAE;QACL,KAAK,EAAE,MAAM,CAAC;QACd,QAAQ,EAAE,MAAM,CAAC;QACjB,eAAe,EAAE,MAAM,CAAC;QACxB,aAAa,EAAE,MAAM,CAAC;KACvB,CAAC;CACH;AAED,MAAM,WAAW,YAAY;IAC3B,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,UAAU,GAAG,MAAM,GAAG,SAAS,GAAG,YAAY,GAAG,SAAS,CAAC;IAClE,QAAQ,EAAE,OAAO,CAAC;IAClB,QAAQ,EAAE,OAAO,CAAC;IAClB,iBAAiB,EAAE,OAAO,CAAC;IAC3B,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,aAAa;IAC5B,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,OAAO,CAAC;IAChB,OAAO,EAAE,SAAS,EAAE,CAAC;IACrB,OAAO,EAAE,KAAK,CAAC;QACb,GAAG,EAAE,MAAM,CAAC;QACZ,OAAO,EAAE,OAAO,CAAC;QACjB,MAAM,EAAE,MAAM,CAAC;KAChB,CAAC,CAAC;CACJ;AAED,MAAM,WAAW,YAAY;IAC3B,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,SAAS,EAAE,CAAC;IACtB,eAAe,EAAE,SAAS,EAAE,CAAC;IAC7B,cAAc,EAAE,SAAS,EAAE,CAAC;IAC5B,WAAW,EAAE,SAAS,EAAE,CAAC;IACzB,cAAc,EAAE,KAAK,CAAC;QAAE,UAAU,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CAC9D"}
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,5 @@
1
+ export declare class SnapshotManager {
2
+ static save(filePath: string, data: any): Promise<void>;
3
+ static load(filePath: string): Promise<any>;
4
+ }
5
+ //# sourceMappingURL=SnapshotManager.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SnapshotManager.d.ts","sourceRoot":"","sources":["../../src/storage/SnapshotManager.ts"],"names":[],"mappings":"AAKA,qBAAa,eAAe;WACb,IAAI,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG;WAUhC,IAAI,CAAC,QAAQ,EAAE,MAAM;CAQnC"}
@@ -0,0 +1,32 @@
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.SnapshotManager = void 0;
7
+ // src/storage/SnapshotManager.ts
8
+ const promises_1 = __importDefault(require("fs/promises"));
9
+ const path_1 = __importDefault(require("path"));
10
+ const logger_1 = require("../utils/logger");
11
+ class SnapshotManager {
12
+ static async save(filePath, data) {
13
+ try {
14
+ const dir = path_1.default.dirname(filePath);
15
+ await promises_1.default.mkdir(dir, { recursive: true });
16
+ await promises_1.default.writeFile(filePath, JSON.stringify(data, null, 2));
17
+ }
18
+ catch (error) {
19
+ logger_1.logger.error("Failed to save snapshot", error);
20
+ }
21
+ }
22
+ static async load(filePath) {
23
+ try {
24
+ const content = await promises_1.default.readFile(filePath, "utf-8");
25
+ return JSON.parse(content);
26
+ }
27
+ catch {
28
+ return null;
29
+ }
30
+ }
31
+ }
32
+ exports.SnapshotManager = SnapshotManager;