agent-sdd 1.0.3
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/LICENSE +21 -0
- package/README.md +1028 -0
- package/README.ru.md +1046 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.js +867 -0
- package/dist/features/approve/adapters/inbound/CliApproveHandler.d.ts +17 -0
- package/dist/features/approve/adapters/inbound/CliApproveHandler.js +108 -0
- package/dist/features/approve/adapters/outbound/NodeApproveFileSystem.d.ts +8 -0
- package/dist/features/approve/adapters/outbound/NodeApproveFileSystem.js +147 -0
- package/dist/features/approve/adapters/outbound/NodePlanFileWriter.d.ts +6 -0
- package/dist/features/approve/adapters/outbound/NodePlanFileWriter.js +92 -0
- package/dist/features/approve/adapters/outbound/SystemApproveClock.d.ts +4 -0
- package/dist/features/approve/adapters/outbound/SystemApproveClock.js +5 -0
- package/dist/features/approve/application/ApplyApproval.d.ts +19 -0
- package/dist/features/approve/application/ApplyApproval.js +30 -0
- package/dist/features/approve/application/WriteAttestation.d.ts +19 -0
- package/dist/features/approve/application/WriteAttestation.js +23 -0
- package/dist/features/approve/domain/ApproveRequest.d.ts +24 -0
- package/dist/features/approve/domain/ApproveRequest.js +24 -0
- package/dist/features/approve/domain/Rewrite.d.ts +1 -0
- package/dist/features/approve/domain/Rewrite.js +6 -0
- package/dist/features/approve/ports/inbound/ApproveCommand.d.ts +10 -0
- package/dist/features/approve/ports/inbound/ApproveCommand.js +1 -0
- package/dist/features/approve/ports/outbound/ApproveClock.d.ts +3 -0
- package/dist/features/approve/ports/outbound/ApproveClock.js +1 -0
- package/dist/features/approve/ports/outbound/ApproveConfigPort.d.ts +4 -0
- package/dist/features/approve/ports/outbound/ApproveConfigPort.js +1 -0
- package/dist/features/approve/ports/outbound/ApproveFileSystem.d.ts +8 -0
- package/dist/features/approve/ports/outbound/ApproveFileSystem.js +1 -0
- package/dist/features/approve/ports/outbound/PlanFileWriter.d.ts +13 -0
- package/dist/features/approve/ports/outbound/PlanFileWriter.js +1 -0
- package/dist/features/check/adapters/inbound/CliCheckHandler.d.ts +8 -0
- package/dist/features/check/adapters/inbound/CliCheckHandler.js +62 -0
- package/dist/features/check/adapters/outbound/ChildProcessCheckGit.d.ts +8 -0
- package/dist/features/check/adapters/outbound/ChildProcessCheckGit.js +112 -0
- package/dist/features/check/adapters/outbound/NodeCheckFileReader.d.ts +7 -0
- package/dist/features/check/adapters/outbound/NodeCheckFileReader.js +44 -0
- package/dist/features/check/application/CheckBaseline.d.ts +28 -0
- package/dist/features/check/application/CheckBaseline.js +54 -0
- package/dist/features/check/domain/BaselineComparison.d.ts +1 -0
- package/dist/features/check/domain/BaselineComparison.js +2 -0
- package/dist/features/check/ports/inbound/CheckCommand.d.ts +4 -0
- package/dist/features/check/ports/inbound/CheckCommand.js +1 -0
- package/dist/features/check/ports/outbound/CheckConfigPort.d.ts +4 -0
- package/dist/features/check/ports/outbound/CheckConfigPort.js +1 -0
- package/dist/features/check/ports/outbound/CheckGitPort.d.ts +7 -0
- package/dist/features/check/ports/outbound/CheckGitPort.js +1 -0
- package/dist/features/check/ports/outbound/CheckSpecPort.d.ts +9 -0
- package/dist/features/check/ports/outbound/CheckSpecPort.js +1 -0
- package/dist/features/doctor/adapters/inbound/CliDoctorHandler.d.ts +8 -0
- package/dist/features/doctor/adapters/inbound/CliDoctorHandler.js +77 -0
- package/dist/features/doctor/adapters/outbound/NodeRegistryReader.d.ts +5 -0
- package/dist/features/doctor/adapters/outbound/NodeRegistryReader.js +40 -0
- package/dist/features/doctor/application/RunDoctor.d.ts +30 -0
- package/dist/features/doctor/application/RunDoctor.js +78 -0
- package/dist/features/doctor/domain/RegistryRow.d.ts +23 -0
- package/dist/features/doctor/domain/RegistryRow.js +114 -0
- package/dist/features/doctor/domain/SemverRange.d.ts +7 -0
- package/dist/features/doctor/domain/SemverRange.js +82 -0
- package/dist/features/doctor/ports/inbound/DoctorCommand.d.ts +8 -0
- package/dist/features/doctor/ports/inbound/DoctorCommand.js +1 -0
- package/dist/features/doctor/ports/outbound/RegistryReader.d.ts +12 -0
- package/dist/features/doctor/ports/outbound/RegistryReader.js +1 -0
- package/dist/features/finalize/adapters/inbound/CliFinalizeHandler.d.ts +8 -0
- package/dist/features/finalize/adapters/inbound/CliFinalizeHandler.js +80 -0
- package/dist/features/finalize/adapters/outbound/NodeFinalizeFileSystem.d.ts +11 -0
- package/dist/features/finalize/adapters/outbound/NodeFinalizeFileSystem.js +167 -0
- package/dist/features/finalize/adapters/outbound/NodePlanRepo.d.ts +7 -0
- package/dist/features/finalize/adapters/outbound/NodePlanRepo.js +82 -0
- package/dist/features/finalize/adapters/outbound/SystemFinalizeClock.d.ts +4 -0
- package/dist/features/finalize/adapters/outbound/SystemFinalizeClock.js +5 -0
- package/dist/features/finalize/application/RunFinalize.d.ts +34 -0
- package/dist/features/finalize/application/RunFinalize.js +98 -0
- package/dist/features/finalize/domain/ValidateFinalizeGraph.d.ts +9 -0
- package/dist/features/finalize/domain/ValidateFinalizeGraph.js +86 -0
- package/dist/features/finalize/ports/inbound/FinalizeCommand.d.ts +7 -0
- package/dist/features/finalize/ports/inbound/FinalizeCommand.js +1 -0
- package/dist/features/finalize/ports/outbound/FinalizeClock.d.ts +3 -0
- package/dist/features/finalize/ports/outbound/FinalizeClock.js +1 -0
- package/dist/features/finalize/ports/outbound/FinalizeConfigPort.d.ts +4 -0
- package/dist/features/finalize/ports/outbound/FinalizeConfigPort.js +1 -0
- package/dist/features/finalize/ports/outbound/FinalizeFileSystem.d.ts +14 -0
- package/dist/features/finalize/ports/outbound/FinalizeFileSystem.js +1 -0
- package/dist/features/finalize/ports/outbound/PlanRepo.d.ts +21 -0
- package/dist/features/finalize/ports/outbound/PlanRepo.js +1 -0
- package/dist/features/install/adapters/inbound/CliInstallHandler.d.ts +8 -0
- package/dist/features/install/adapters/inbound/CliInstallHandler.js +54 -0
- package/dist/features/install/adapters/outbound/NodeInstallSource.d.ts +7 -0
- package/dist/features/install/adapters/outbound/NodeInstallSource.js +24 -0
- package/dist/features/install/adapters/outbound/NodeInstallTargetFs.d.ts +7 -0
- package/dist/features/install/adapters/outbound/NodeInstallTargetFs.js +30 -0
- package/dist/features/install/application/InstallRules.d.ts +10 -0
- package/dist/features/install/application/InstallRules.js +73 -0
- package/dist/features/install/domain/InstallPlan.d.ts +27 -0
- package/dist/features/install/domain/InstallPlan.js +168 -0
- package/dist/features/install/domain/InstallResult.d.ts +23 -0
- package/dist/features/install/domain/InstallResult.js +1 -0
- package/dist/features/install/domain/InstallTarget.d.ts +6 -0
- package/dist/features/install/domain/InstallTarget.js +7 -0
- package/dist/features/install/domain/ManagedBlock.d.ts +3 -0
- package/dist/features/install/domain/ManagedBlock.js +20 -0
- package/dist/features/install/domain/RuleManifest.d.ts +17 -0
- package/dist/features/install/domain/RuleManifest.js +69 -0
- package/dist/features/install/domain/SettingsMerge.d.ts +5 -0
- package/dist/features/install/domain/SettingsMerge.js +43 -0
- package/dist/features/install/ports/inbound/InstallCommand.d.ts +10 -0
- package/dist/features/install/ports/inbound/InstallCommand.js +1 -0
- package/dist/features/install/ports/outbound/InstallSource.d.ts +4 -0
- package/dist/features/install/ports/outbound/InstallSource.js +1 -0
- package/dist/features/install/ports/outbound/InstallTargetFs.d.ts +6 -0
- package/dist/features/install/ports/outbound/InstallTargetFs.js +1 -0
- package/dist/features/lint/adapters/inbound/CliLintHandler.d.ts +8 -0
- package/dist/features/lint/adapters/inbound/CliLintHandler.js +61 -0
- package/dist/features/lint/adapters/outbound/NodeLintFileReader.d.ts +7 -0
- package/dist/features/lint/adapters/outbound/NodeLintFileReader.js +165 -0
- package/dist/features/lint/application/RunLint.d.ts +10 -0
- package/dist/features/lint/application/RunLint.js +100 -0
- package/dist/features/lint/domain/Diagnostic.d.ts +1 -0
- package/dist/features/lint/domain/Diagnostic.js +2 -0
- package/dist/features/lint/domain/Record.d.ts +1 -0
- package/dist/features/lint/domain/Record.js +5 -0
- package/dist/features/lint/domain/Rules.d.ts +1 -0
- package/dist/features/lint/domain/Rules.js +2 -0
- package/dist/features/lint/domain/SpecParser.d.ts +1 -0
- package/dist/features/lint/domain/SpecParser.js +2 -0
- package/dist/features/lint/ports/inbound/LintCommand.d.ts +4 -0
- package/dist/features/lint/ports/inbound/LintCommand.js +1 -0
- package/dist/features/lint/ports/outbound/LintConfigPort.d.ts +4 -0
- package/dist/features/lint/ports/outbound/LintConfigPort.js +1 -0
- package/dist/features/lint/ports/outbound/LintFileReader.d.ts +10 -0
- package/dist/features/lint/ports/outbound/LintFileReader.js +1 -0
- package/dist/features/plan/adapters/inbound/CliPlanShowHandler.d.ts +8 -0
- package/dist/features/plan/adapters/inbound/CliPlanShowHandler.js +73 -0
- package/dist/features/plan/adapters/outbound/NodePlanReader.d.ts +7 -0
- package/dist/features/plan/adapters/outbound/NodePlanReader.js +68 -0
- package/dist/features/plan/application/ShowPlan.d.ts +7 -0
- package/dist/features/plan/application/ShowPlan.js +4 -0
- package/dist/features/plan/ports/inbound/PlanShowCommand.d.ts +7 -0
- package/dist/features/plan/ports/inbound/PlanShowCommand.js +1 -0
- package/dist/features/plan/ports/outbound/PlanConfigPort.d.ts +4 -0
- package/dist/features/plan/ports/outbound/PlanConfigPort.js +1 -0
- package/dist/features/plan/ports/outbound/PlanReader.d.ts +19 -0
- package/dist/features/plan/ports/outbound/PlanReader.js +1 -0
- package/dist/features/ready/adapters/inbound/CliReadyHandler.d.ts +8 -0
- package/dist/features/ready/adapters/inbound/CliReadyHandler.js +79 -0
- package/dist/features/ready/adapters/outbound/ChildProcessReadyGit.d.ts +9 -0
- package/dist/features/ready/adapters/outbound/ChildProcessReadyGit.js +113 -0
- package/dist/features/ready/adapters/outbound/NodeReadyFileSystem.d.ts +8 -0
- package/dist/features/ready/adapters/outbound/NodeReadyFileSystem.js +159 -0
- package/dist/features/ready/application/RunReady.d.ts +16 -0
- package/dist/features/ready/application/RunReady.js +572 -0
- package/dist/features/ready/domain/AggregatedRules.d.ts +16 -0
- package/dist/features/ready/domain/AggregatedRules.js +42 -0
- package/dist/features/ready/domain/MarkerParser.d.ts +17 -0
- package/dist/features/ready/domain/MarkerParser.js +108 -0
- package/dist/features/ready/domain/PartitionResolver.d.ts +1 -0
- package/dist/features/ready/domain/PartitionResolver.js +5 -0
- package/dist/features/ready/domain/ReadyInput.d.ts +6 -0
- package/dist/features/ready/domain/ReadyInput.js +1 -0
- package/dist/features/ready/domain/ReadyViolation.d.ts +38 -0
- package/dist/features/ready/domain/ReadyViolation.js +19 -0
- package/dist/features/ready/domain/Rules.d.ts +22 -0
- package/dist/features/ready/domain/Rules.js +243 -0
- package/dist/features/ready/domain/SpecDiff.d.ts +33 -0
- package/dist/features/ready/domain/SpecDiff.js +321 -0
- package/dist/features/ready/ports/inbound/ReadyCommand.d.ts +4 -0
- package/dist/features/ready/ports/inbound/ReadyCommand.js +1 -0
- package/dist/features/ready/ports/outbound/ReadyConfigPort.d.ts +4 -0
- package/dist/features/ready/ports/outbound/ReadyConfigPort.js +1 -0
- package/dist/features/ready/ports/outbound/ReadyFileReader.d.ts +12 -0
- package/dist/features/ready/ports/outbound/ReadyFileReader.js +1 -0
- package/dist/features/ready/ports/outbound/ReadyGitPort.d.ts +10 -0
- package/dist/features/ready/ports/outbound/ReadyGitPort.js +5 -0
- package/dist/features/record/adapters/inbound/CliRecordHandler.d.ts +10 -0
- package/dist/features/record/adapters/inbound/CliRecordHandler.js +111 -0
- package/dist/features/record/adapters/outbound/NodeRecordFileSystem.d.ts +9 -0
- package/dist/features/record/adapters/outbound/NodeRecordFileSystem.js +152 -0
- package/dist/features/record/application/AddRecord.d.ts +11 -0
- package/dist/features/record/application/AddRecord.js +84 -0
- package/dist/features/record/application/GetRecord.d.ts +8 -0
- package/dist/features/record/application/GetRecord.js +22 -0
- package/dist/features/record/application/ListRecords.d.ts +9 -0
- package/dist/features/record/application/ListRecords.js +24 -0
- package/dist/features/record/application/SetRecord.d.ts +11 -0
- package/dist/features/record/application/SetRecord.js +68 -0
- package/dist/features/record/domain/RecordBody.d.ts +12 -0
- package/dist/features/record/domain/RecordBody.js +66 -0
- package/dist/features/record/domain/RecordPartition.d.ts +1 -0
- package/dist/features/record/domain/RecordPartition.js +7 -0
- package/dist/features/record/domain/RecordSlice.d.ts +7 -0
- package/dist/features/record/domain/RecordSlice.js +1 -0
- package/dist/features/record/domain/RecordSummary.d.ts +11 -0
- package/dist/features/record/domain/RecordSummary.js +13 -0
- package/dist/features/record/domain/RecordWrite.d.ts +14 -0
- package/dist/features/record/domain/RecordWrite.js +8 -0
- package/dist/features/record/ports/inbound/RecordCommand.d.ts +19 -0
- package/dist/features/record/ports/inbound/RecordCommand.js +1 -0
- package/dist/features/record/ports/outbound/RecordConfigPort.d.ts +4 -0
- package/dist/features/record/ports/outbound/RecordConfigPort.js +1 -0
- package/dist/features/record/ports/outbound/RecordFileReader.d.ts +10 -0
- package/dist/features/record/ports/outbound/RecordFileReader.js +1 -0
- package/dist/features/record/ports/outbound/RecordFileWriter.d.ts +6 -0
- package/dist/features/record/ports/outbound/RecordFileWriter.js +1 -0
- package/dist/features/refresh/adapters/inbound/CliRefreshHandler.d.ts +8 -0
- package/dist/features/refresh/adapters/inbound/CliRefreshHandler.js +24 -0
- package/dist/features/refresh/adapters/outbound/ChildProcessRefreshGit.d.ts +8 -0
- package/dist/features/refresh/adapters/outbound/ChildProcessRefreshGit.js +118 -0
- package/dist/features/refresh/adapters/outbound/NodeRefreshFileReader.d.ts +7 -0
- package/dist/features/refresh/adapters/outbound/NodeRefreshFileReader.js +44 -0
- package/dist/features/refresh/adapters/outbound/SystemRefreshClock.d.ts +4 -0
- package/dist/features/refresh/adapters/outbound/SystemRefreshClock.js +5 -0
- package/dist/features/refresh/application/BuildRefreshStubs.d.ts +25 -0
- package/dist/features/refresh/application/BuildRefreshStubs.js +43 -0
- package/dist/features/refresh/domain/DiffStubs.d.ts +24 -0
- package/dist/features/refresh/domain/DiffStubs.js +81 -0
- package/dist/features/refresh/domain/Footprint.d.ts +14 -0
- package/dist/features/refresh/domain/Footprint.js +45 -0
- package/dist/features/refresh/ports/inbound/RefreshCommand.d.ts +4 -0
- package/dist/features/refresh/ports/inbound/RefreshCommand.js +1 -0
- package/dist/features/refresh/ports/outbound/RefreshClockPort.d.ts +3 -0
- package/dist/features/refresh/ports/outbound/RefreshClockPort.js +1 -0
- package/dist/features/refresh/ports/outbound/RefreshConfigPort.d.ts +4 -0
- package/dist/features/refresh/ports/outbound/RefreshConfigPort.js +1 -0
- package/dist/features/refresh/ports/outbound/RefreshGitPort.d.ts +7 -0
- package/dist/features/refresh/ports/outbound/RefreshGitPort.js +1 -0
- package/dist/features/refresh/ports/outbound/RefreshSpecPort.d.ts +9 -0
- package/dist/features/refresh/ports/outbound/RefreshSpecPort.js +1 -0
- package/dist/features/report/adapters/inbound/CliReportHandler.d.ts +8 -0
- package/dist/features/report/adapters/inbound/CliReportHandler.js +35 -0
- package/dist/features/report/adapters/outbound/NodeReportFileSystem.d.ts +7 -0
- package/dist/features/report/adapters/outbound/NodeReportFileSystem.js +128 -0
- package/dist/features/report/application/RunReport.d.ts +19 -0
- package/dist/features/report/application/RunReport.js +161 -0
- package/dist/features/report/ports/inbound/ReportCommand.d.ts +8 -0
- package/dist/features/report/ports/inbound/ReportCommand.js +1 -0
- package/dist/features/report/ports/outbound/ReportConfigPort.d.ts +4 -0
- package/dist/features/report/ports/outbound/ReportConfigPort.js +1 -0
- package/dist/features/report/ports/outbound/ReportFileReader.d.ts +7 -0
- package/dist/features/report/ports/outbound/ReportFileReader.js +1 -0
- package/dist/features/token/adapters/inbound/CliTokenHandler.d.ts +8 -0
- package/dist/features/token/adapters/inbound/CliTokenHandler.js +53 -0
- package/dist/features/token/adapters/outbound/ChildProcessTokenGit.d.ts +8 -0
- package/dist/features/token/adapters/outbound/ChildProcessTokenGit.js +112 -0
- package/dist/features/token/adapters/outbound/NodeTokenConfigReader.d.ts +5 -0
- package/dist/features/token/adapters/outbound/NodeTokenConfigReader.js +41 -0
- package/dist/features/token/application/ComputeToken.d.ts +18 -0
- package/dist/features/token/application/ComputeToken.js +27 -0
- package/dist/features/token/ports/inbound/TokenCommand.d.ts +4 -0
- package/dist/features/token/ports/inbound/TokenCommand.js +1 -0
- package/dist/features/token/ports/outbound/TokenConfigPort.d.ts +4 -0
- package/dist/features/token/ports/outbound/TokenConfigPort.js +1 -0
- package/dist/features/token/ports/outbound/TokenGitPort.d.ts +7 -0
- package/dist/features/token/ports/outbound/TokenGitPort.js +1 -0
- package/dist/shared/domain/AgentBlocklist.d.ts +5 -0
- package/dist/shared/domain/AgentBlocklist.js +28 -0
- package/dist/shared/domain/BoundaryReachability.d.ts +5 -0
- package/dist/shared/domain/BoundaryReachability.js +71 -0
- package/dist/shared/domain/CheckOutcome.d.ts +10 -0
- package/dist/shared/domain/CheckOutcome.js +7 -0
- package/dist/shared/domain/CliOutput.d.ts +10 -0
- package/dist/shared/domain/CliOutput.js +29 -0
- package/dist/shared/domain/Config.d.ts +29 -0
- package/dist/shared/domain/Config.js +201 -0
- package/dist/shared/domain/DiagnosticRegistry.d.ts +8 -0
- package/dist/shared/domain/DiagnosticRegistry.js +71 -0
- package/dist/shared/domain/Errors.d.ts +12 -0
- package/dist/shared/domain/Errors.js +23 -0
- package/dist/shared/domain/GlobMatch.d.ts +2 -0
- package/dist/shared/domain/GlobMatch.js +58 -0
- package/dist/shared/domain/LintReport.d.ts +16 -0
- package/dist/shared/domain/LintReport.js +11 -0
- package/dist/shared/domain/LintRules.d.ts +67 -0
- package/dist/shared/domain/LintRules.js +956 -0
- package/dist/shared/domain/PartitionGrammar.d.ts +4 -0
- package/dist/shared/domain/PartitionGrammar.js +16 -0
- package/dist/shared/domain/PlanFile.d.ts +28 -0
- package/dist/shared/domain/PlanFile.js +112 -0
- package/dist/shared/domain/Scope.d.ts +1 -0
- package/dist/shared/domain/Scope.js +3 -0
- package/dist/shared/domain/SpecApprovalRewrite.d.ts +23 -0
- package/dist/shared/domain/SpecApprovalRewrite.js +254 -0
- package/dist/shared/domain/SpecBlocks.d.ts +12 -0
- package/dist/shared/domain/SpecBlocks.js +96 -0
- package/dist/shared/domain/SpecRecord.d.ts +17 -0
- package/dist/shared/domain/SpecRecord.js +208 -0
- package/dist/shared/domain/TemplateFieldMetadata.d.ts +2 -0
- package/dist/shared/domain/TemplateFieldMetadata.js +177 -0
- package/dist/shared/domain/Token.d.ts +2 -0
- package/dist/shared/domain/Token.js +5 -0
- package/dist/shared/domain/WeaselWords.d.ts +3 -0
- package/dist/shared/domain/WeaselWords.js +32 -0
- package/package.json +71 -0
- package/rules/enforcement_registry.md +126 -0
- package/rules/hooks/sdd-lint-reminder.sh +33 -0
- package/rules/hooks/sdd-spec-read-guard.sh +73 -0
- package/rules/manifest.json +15 -0
- package/rules/review-sdd.md +9 -0
- package/rules/sdd-cli-usage.md +91 -0
- package/rules/skills/spec-driven-development/SKILL.md +554 -0
- package/rules/skills/spec-driven-development/data/weasel-words.json +22 -0
- package/rules/spec-driven-development.md +69 -0
- package/rules/tdd-sdd.md +127 -0
- package/rules/workflow-sdd.md +56 -0
- package/schema/sdd.config.schema.json +104 -0
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Two-stage scanner for `@covers <partition>:<id> [key=value]*` markers
|
|
3
|
+
* (CST-007). Pure: takes a string + filename, returns Marker[] with 1-based
|
|
4
|
+
* line numbers. Language-agnostic: byte/string scan, no AST.
|
|
5
|
+
*/
|
|
6
|
+
import { ID_TAIL_RE_SRC, PARTITION_PREFIX_RE_SRC, } from "../../../shared/domain/PartitionGrammar.js";
|
|
7
|
+
export const ALLOWED_MARKER_KEYS = new Set([
|
|
8
|
+
"compatibility_action",
|
|
9
|
+
]);
|
|
10
|
+
/*
|
|
11
|
+
* Tail stops at `@` so a second `@covers` on the same line is reachable. The
|
|
12
|
+
* `compatibility_action=…` whitelist tokens never contain `@`, so this is a
|
|
13
|
+
* safe boundary in practice. Partition + id grammar is shared with Config
|
|
14
|
+
* validation via `PartitionGrammar`.
|
|
15
|
+
*/
|
|
16
|
+
const MARKER_RE = new RegExp(`@covers\\s+(${PARTITION_PREFIX_RE_SRC}:${ID_TAIL_RE_SRC})([^@\\n\\r]*)`, "g");
|
|
17
|
+
/*
|
|
18
|
+
* Loose recogniser for `@covers`-shaped tokens that end in a valid id tail
|
|
19
|
+
* (`<TYPE>-<num>`) but whose prefix violates the strict partition grammar
|
|
20
|
+
* (e.g. uppercase segment). Used to surface near-miss advisories (OQ-017).
|
|
21
|
+
*/
|
|
22
|
+
const NEAR_MISS_RE = new RegExp(`@covers\\s+([A-Za-z0-9_:-]+:[A-Z]+-\\d+)`, "g");
|
|
23
|
+
const STRICT_TARGET_RE = new RegExp(`^${PARTITION_PREFIX_RE_SRC}:${ID_TAIL_RE_SRC}$`);
|
|
24
|
+
/** `@covers`-shaped tokens that look like a marker attempt (valid id tail) but
|
|
25
|
+
* fail the strict partition grammar. Strictly-valid markers are excluded. */
|
|
26
|
+
export function parseNearMisses(text, file) {
|
|
27
|
+
const out = [];
|
|
28
|
+
const lineStarts = lineStartOffsets(text);
|
|
29
|
+
NEAR_MISS_RE.lastIndex = 0;
|
|
30
|
+
let match;
|
|
31
|
+
while ((match = NEAR_MISS_RE.exec(text)) !== null) {
|
|
32
|
+
const target = match[1];
|
|
33
|
+
if (STRICT_TARGET_RE.test(target)) {
|
|
34
|
+
continue;
|
|
35
|
+
}
|
|
36
|
+
out.push({
|
|
37
|
+
text: target,
|
|
38
|
+
file,
|
|
39
|
+
line: lineNumberOf(lineStarts, match.index),
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
return out;
|
|
43
|
+
}
|
|
44
|
+
export function parseMarkers(text, file) {
|
|
45
|
+
const out = [];
|
|
46
|
+
const lineStarts = lineStartOffsets(text);
|
|
47
|
+
/* Reset regex state in case a stale lastIndex leaks across calls. */
|
|
48
|
+
MARKER_RE.lastIndex = 0;
|
|
49
|
+
let match;
|
|
50
|
+
while ((match = MARKER_RE.exec(text)) !== null) {
|
|
51
|
+
const target = match[1];
|
|
52
|
+
const rawTail = match[2] ?? "";
|
|
53
|
+
/*
|
|
54
|
+
* CST-007: split at the LAST `:` — the id tail has no `:`, so everything
|
|
55
|
+
* before the rightmost `:` is the partition prefix.
|
|
56
|
+
*/
|
|
57
|
+
const colon = target.lastIndexOf(":");
|
|
58
|
+
const partition = target.slice(0, colon);
|
|
59
|
+
const id = target.slice(colon + 1);
|
|
60
|
+
const tail = parseTail(rawTail);
|
|
61
|
+
const offset = match.index;
|
|
62
|
+
const line = lineNumberOf(lineStarts, offset);
|
|
63
|
+
out.push({ partition, id, tail, file, line });
|
|
64
|
+
}
|
|
65
|
+
return out;
|
|
66
|
+
}
|
|
67
|
+
function parseTail(rawTail) {
|
|
68
|
+
const tail = {};
|
|
69
|
+
for (const token of rawTail.split(/\s+/)) {
|
|
70
|
+
if (token.length === 0) {
|
|
71
|
+
continue;
|
|
72
|
+
}
|
|
73
|
+
const eq = token.indexOf("=");
|
|
74
|
+
if (eq < 1) {
|
|
75
|
+
continue;
|
|
76
|
+
}
|
|
77
|
+
const key = token.slice(0, eq);
|
|
78
|
+
const value = token.slice(eq + 1);
|
|
79
|
+
if (!ALLOWED_MARKER_KEYS.has(key)) {
|
|
80
|
+
continue;
|
|
81
|
+
}
|
|
82
|
+
tail[key] = value;
|
|
83
|
+
}
|
|
84
|
+
return tail;
|
|
85
|
+
}
|
|
86
|
+
function lineStartOffsets(text) {
|
|
87
|
+
const starts = [0];
|
|
88
|
+
for (let i = 0; i < text.length; i++) {
|
|
89
|
+
if (text[i] === "\n") {
|
|
90
|
+
starts.push(i + 1);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
return starts;
|
|
94
|
+
}
|
|
95
|
+
function lineNumberOf(lineStarts, offset) {
|
|
96
|
+
let lo = 0;
|
|
97
|
+
let hi = lineStarts.length - 1;
|
|
98
|
+
while (lo < hi) {
|
|
99
|
+
const mid = (lo + hi + 1) >>> 1;
|
|
100
|
+
if (lineStarts[mid] <= offset) {
|
|
101
|
+
lo = mid;
|
|
102
|
+
}
|
|
103
|
+
else {
|
|
104
|
+
hi = mid - 1;
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
return lo + 1;
|
|
108
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { matchesGlob, fileInGlobs } from "../../../shared/domain/GlobMatch.js";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import type { ReadyViolationKindId } from "../../../shared/domain/DiagnosticRegistry.js";
|
|
2
|
+
export type ReadyViolationKind = ReadyViolationKindId;
|
|
3
|
+
export type ReadyErrorKind = "spec_parse_failed" | "config_invalid" | "unreadable_test_paths" | "internal";
|
|
4
|
+
export interface ReadyViolation {
|
|
5
|
+
kind: ReadyViolationKind;
|
|
6
|
+
id?: string;
|
|
7
|
+
partition?: string;
|
|
8
|
+
status?: string;
|
|
9
|
+
file?: string;
|
|
10
|
+
line?: number;
|
|
11
|
+
expected?: string;
|
|
12
|
+
actual?: string;
|
|
13
|
+
remediation?: string;
|
|
14
|
+
source?: string;
|
|
15
|
+
}
|
|
16
|
+
export interface ReadyError {
|
|
17
|
+
kind: ReadyErrorKind;
|
|
18
|
+
message: string;
|
|
19
|
+
file?: string;
|
|
20
|
+
}
|
|
21
|
+
/** Non-blocking advisory (OQ-011/OQ-017): surfaced in the ready envelope but
|
|
22
|
+
* never affects exit code. */
|
|
23
|
+
export interface ReadyAdvisory {
|
|
24
|
+
kind: "covers_near_miss";
|
|
25
|
+
file: string;
|
|
26
|
+
line: number;
|
|
27
|
+
text: string;
|
|
28
|
+
remediation: string;
|
|
29
|
+
}
|
|
30
|
+
export interface ReadyEnvelope {
|
|
31
|
+
ok: boolean;
|
|
32
|
+
error: ReadyError | null;
|
|
33
|
+
violations: ReadyViolation[];
|
|
34
|
+
advisories: ReadyAdvisory[];
|
|
35
|
+
}
|
|
36
|
+
export declare function emptyEnvelope(): ReadyEnvelope;
|
|
37
|
+
export declare function envelopeFromError(error: ReadyError): ReadyEnvelope;
|
|
38
|
+
export declare function envelopeFromViolations(violations: ReadyViolation[]): ReadyEnvelope;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Discriminated union for sdd ready output. Encoded by CTR-014; the union is
|
|
3
|
+
* derived from src/shared/domain/DiagnosticRegistry.READY_VIOLATION_KINDS so
|
|
4
|
+
* that CTR-016 / SUR-009 / INV-010 stays the single source of truth.
|
|
5
|
+
*/
|
|
6
|
+
export function emptyEnvelope() {
|
|
7
|
+
return { ok: true, error: null, violations: [], advisories: [] };
|
|
8
|
+
}
|
|
9
|
+
export function envelopeFromError(error) {
|
|
10
|
+
return { ok: false, error, violations: [], advisories: [] };
|
|
11
|
+
}
|
|
12
|
+
export function envelopeFromViolations(violations) {
|
|
13
|
+
return {
|
|
14
|
+
ok: violations.length === 0,
|
|
15
|
+
error: null,
|
|
16
|
+
violations,
|
|
17
|
+
advisories: [],
|
|
18
|
+
};
|
|
19
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { Partition } from "../../../shared/domain/Config.js";
|
|
2
|
+
import type { LintRecord } from "../../../shared/domain/SpecRecord.js";
|
|
3
|
+
import type { Marker } from "./MarkerParser.js";
|
|
4
|
+
import type { ReadyViolation } from "./ReadyViolation.js";
|
|
5
|
+
export interface PartitionView {
|
|
6
|
+
partition: Partition;
|
|
7
|
+
records: LintRecord[];
|
|
8
|
+
recordsById: Map<string, LintRecord>;
|
|
9
|
+
creditedMarkersById: Map<string, Marker[]>;
|
|
10
|
+
}
|
|
11
|
+
export declare function ruleUnapproved(view: PartitionView): ReadyViolation[];
|
|
12
|
+
export declare function ruleUncovered(view: PartitionView): ReadyViolation[];
|
|
13
|
+
export declare function ruleRemovedNoCompatTest(view: PartitionView): ReadyViolation[];
|
|
14
|
+
export declare function ruleRemovedCompatActionMismatch(view: PartitionView): ReadyViolation[];
|
|
15
|
+
export declare function ruleSurfaceUnapprovedRef(view: PartitionView): ReadyViolation[];
|
|
16
|
+
export interface ScannedMarker {
|
|
17
|
+
marker: Marker;
|
|
18
|
+
isPartitionConfigured: boolean;
|
|
19
|
+
hasMatchingRecord: boolean;
|
|
20
|
+
}
|
|
21
|
+
export declare function ruleOrphanCovers(scanned: readonly ScannedMarker[]): ReadyViolation[];
|
|
22
|
+
export declare function ruleUnknownPartitionCovers(scanned: readonly ScannedMarker[]): ReadyViolation[];
|
|
@@ -0,0 +1,243 @@
|
|
|
1
|
+
import { fileInGlobs } from "./PartitionResolver.js";
|
|
2
|
+
const NORMATIVE = new Set([
|
|
3
|
+
"Behavior",
|
|
4
|
+
"Invariant",
|
|
5
|
+
"Contract",
|
|
6
|
+
"Scenario",
|
|
7
|
+
"NFR",
|
|
8
|
+
"Constraint",
|
|
9
|
+
"Policy",
|
|
10
|
+
"Migration",
|
|
11
|
+
"Delta",
|
|
12
|
+
"GeneratedArtifact",
|
|
13
|
+
"ExternalDependency",
|
|
14
|
+
"LocalizationContract",
|
|
15
|
+
"Surface",
|
|
16
|
+
]);
|
|
17
|
+
/*
|
|
18
|
+
* Surface is normative but exempt from individual coverage requirements; its
|
|
19
|
+
* members carry the obligation. Matches lint's OBLIGATIONLESS_TEMPLATES.
|
|
20
|
+
*/
|
|
21
|
+
const COVERAGE_EXEMPT_TEMPLATES = new Set(["Surface"]);
|
|
22
|
+
export function ruleUnapproved(view) {
|
|
23
|
+
const out = [];
|
|
24
|
+
for (const rec of view.records) {
|
|
25
|
+
if (!isNormative(rec)) {
|
|
26
|
+
continue;
|
|
27
|
+
}
|
|
28
|
+
const status = rec.lifecycleStatus;
|
|
29
|
+
if (status !== "draft" && status !== "proposed") {
|
|
30
|
+
continue;
|
|
31
|
+
}
|
|
32
|
+
if (fileInGlobs(rec.file, view.partition.sandboxPaths)) {
|
|
33
|
+
continue;
|
|
34
|
+
}
|
|
35
|
+
out.push({
|
|
36
|
+
kind: "unapproved",
|
|
37
|
+
id: rec.id,
|
|
38
|
+
partition: view.partition.name,
|
|
39
|
+
status,
|
|
40
|
+
file: rec.file,
|
|
41
|
+
line: rec.line,
|
|
42
|
+
remediation: "promote via `sdd approve` or move into sandbox_paths",
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
return out;
|
|
46
|
+
}
|
|
47
|
+
export function ruleUncovered(view) {
|
|
48
|
+
const out = [];
|
|
49
|
+
for (const rec of view.records) {
|
|
50
|
+
if (!isNormative(rec)) {
|
|
51
|
+
continue;
|
|
52
|
+
}
|
|
53
|
+
if (rec.template !== null && COVERAGE_EXEMPT_TEMPLATES.has(rec.template)) {
|
|
54
|
+
continue;
|
|
55
|
+
}
|
|
56
|
+
if (rec.lifecycleStatus !== "approved" &&
|
|
57
|
+
rec.lifecycleStatus !== "deprecated") {
|
|
58
|
+
continue;
|
|
59
|
+
}
|
|
60
|
+
if (isNotApplicableTestObligation(rec)) {
|
|
61
|
+
continue;
|
|
62
|
+
}
|
|
63
|
+
if ((view.creditedMarkersById.get(rec.id) ?? []).length > 0) {
|
|
64
|
+
continue;
|
|
65
|
+
}
|
|
66
|
+
out.push({
|
|
67
|
+
kind: "uncovered",
|
|
68
|
+
id: rec.id,
|
|
69
|
+
partition: view.partition.name,
|
|
70
|
+
status: rec.lifecycleStatus,
|
|
71
|
+
file: rec.file,
|
|
72
|
+
line: rec.line,
|
|
73
|
+
remediation: "add `@covers " +
|
|
74
|
+
rec.id +
|
|
75
|
+
"` next to a test for this ID, or set `Test obligation: not_applicable + reason`",
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
return out;
|
|
79
|
+
}
|
|
80
|
+
export function ruleRemovedNoCompatTest(view) {
|
|
81
|
+
const out = [];
|
|
82
|
+
for (const rec of view.records) {
|
|
83
|
+
if (!isNormative(rec)) {
|
|
84
|
+
continue;
|
|
85
|
+
}
|
|
86
|
+
if (rec.lifecycleStatus !== "removed") {
|
|
87
|
+
continue;
|
|
88
|
+
}
|
|
89
|
+
const markers = view.creditedMarkersById.get(rec.id) ?? [];
|
|
90
|
+
const haveCompat = markers.some((m) => typeof m.tail.compatibility_action === "string");
|
|
91
|
+
if (haveCompat) {
|
|
92
|
+
continue;
|
|
93
|
+
}
|
|
94
|
+
out.push({
|
|
95
|
+
kind: "removed_no_compat_test",
|
|
96
|
+
id: rec.id,
|
|
97
|
+
partition: view.partition.name,
|
|
98
|
+
status: rec.lifecycleStatus,
|
|
99
|
+
file: rec.file,
|
|
100
|
+
line: rec.line,
|
|
101
|
+
remediation: "add a test with `@covers " +
|
|
102
|
+
rec.id +
|
|
103
|
+
" compatibility_action=<action>`",
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
return out;
|
|
107
|
+
}
|
|
108
|
+
export function ruleRemovedCompatActionMismatch(view) {
|
|
109
|
+
const out = [];
|
|
110
|
+
for (const rec of view.records) {
|
|
111
|
+
if (!isNormative(rec)) {
|
|
112
|
+
continue;
|
|
113
|
+
}
|
|
114
|
+
if (rec.lifecycleStatus !== "removed") {
|
|
115
|
+
continue;
|
|
116
|
+
}
|
|
117
|
+
const expected = readCompatibilityAction(rec);
|
|
118
|
+
if (expected === null) {
|
|
119
|
+
continue;
|
|
120
|
+
}
|
|
121
|
+
const markers = view.creditedMarkersById.get(rec.id) ?? [];
|
|
122
|
+
for (const m of markers) {
|
|
123
|
+
const actual = m.tail.compatibility_action;
|
|
124
|
+
if (typeof actual !== "string") {
|
|
125
|
+
continue;
|
|
126
|
+
}
|
|
127
|
+
if (actual === expected) {
|
|
128
|
+
continue;
|
|
129
|
+
}
|
|
130
|
+
out.push({
|
|
131
|
+
kind: "removed_compat_action_mismatch",
|
|
132
|
+
id: rec.id,
|
|
133
|
+
partition: view.partition.name,
|
|
134
|
+
status: rec.lifecycleStatus,
|
|
135
|
+
file: m.file,
|
|
136
|
+
line: m.line,
|
|
137
|
+
expected,
|
|
138
|
+
actual,
|
|
139
|
+
remediation: "align marker's compatibility_action= with the spec's compatibility_action",
|
|
140
|
+
});
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
return out;
|
|
144
|
+
}
|
|
145
|
+
export function ruleSurfaceUnapprovedRef(view) {
|
|
146
|
+
const out = [];
|
|
147
|
+
for (const rec of view.records) {
|
|
148
|
+
if (rec.template !== "Surface") {
|
|
149
|
+
continue;
|
|
150
|
+
}
|
|
151
|
+
const status = rec.lifecycleStatus;
|
|
152
|
+
if (status !== "approved" &&
|
|
153
|
+
status !== "deprecated" &&
|
|
154
|
+
status !== "removed") {
|
|
155
|
+
continue;
|
|
156
|
+
}
|
|
157
|
+
const members = readMembers(rec);
|
|
158
|
+
for (const memberId of members) {
|
|
159
|
+
const member = view.recordsById.get(memberId);
|
|
160
|
+
if (member === undefined) {
|
|
161
|
+
continue;
|
|
162
|
+
}
|
|
163
|
+
const ms = member.lifecycleStatus;
|
|
164
|
+
if (ms === "approved" || ms === "deprecated" || ms === "removed") {
|
|
165
|
+
continue;
|
|
166
|
+
}
|
|
167
|
+
out.push({
|
|
168
|
+
kind: "surface_unapproved_ref",
|
|
169
|
+
id: rec.id,
|
|
170
|
+
partition: view.partition.name,
|
|
171
|
+
status,
|
|
172
|
+
file: rec.file,
|
|
173
|
+
line: rec.line,
|
|
174
|
+
remediation: `member ${memberId} is ${ms ?? "missing-status"}; approve it before approving Surface ${rec.id}`,
|
|
175
|
+
});
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
return out;
|
|
179
|
+
}
|
|
180
|
+
export function ruleOrphanCovers(scanned) {
|
|
181
|
+
const out = [];
|
|
182
|
+
for (const s of scanned) {
|
|
183
|
+
if (!s.isPartitionConfigured) {
|
|
184
|
+
continue;
|
|
185
|
+
} /* covered by ruleUnknownPartitionCovers */
|
|
186
|
+
if (s.hasMatchingRecord) {
|
|
187
|
+
continue;
|
|
188
|
+
}
|
|
189
|
+
out.push({
|
|
190
|
+
kind: "orphan_covers",
|
|
191
|
+
id: `${s.marker.partition}:${s.marker.id}`,
|
|
192
|
+
partition: s.marker.partition,
|
|
193
|
+
file: s.marker.file,
|
|
194
|
+
line: s.marker.line,
|
|
195
|
+
remediation: "marker references an ID not present in that partition's spec; remove the marker or add the ID",
|
|
196
|
+
});
|
|
197
|
+
}
|
|
198
|
+
return out;
|
|
199
|
+
}
|
|
200
|
+
export function ruleUnknownPartitionCovers(scanned) {
|
|
201
|
+
const out = [];
|
|
202
|
+
for (const s of scanned) {
|
|
203
|
+
if (s.isPartitionConfigured) {
|
|
204
|
+
continue;
|
|
205
|
+
}
|
|
206
|
+
out.push({
|
|
207
|
+
kind: "unknown_partition_covers",
|
|
208
|
+
id: `${s.marker.partition}:${s.marker.id}`,
|
|
209
|
+
partition: s.marker.partition,
|
|
210
|
+
file: s.marker.file,
|
|
211
|
+
line: s.marker.line,
|
|
212
|
+
remediation: "configure the partition in `.sdd/config.json#partitions` or fix the marker prefix",
|
|
213
|
+
});
|
|
214
|
+
}
|
|
215
|
+
return out;
|
|
216
|
+
}
|
|
217
|
+
function isNormative(rec) {
|
|
218
|
+
return rec.template !== null && NORMATIVE.has(rec.template);
|
|
219
|
+
}
|
|
220
|
+
function isNotApplicableTestObligation(rec) {
|
|
221
|
+
const v = rec.parsed.test_obligation;
|
|
222
|
+
if (typeof v === "string" && v.startsWith("not_applicable")) {
|
|
223
|
+
return true;
|
|
224
|
+
}
|
|
225
|
+
if (isObject(v) && v.not_applicable !== undefined) {
|
|
226
|
+
return true;
|
|
227
|
+
}
|
|
228
|
+
return false;
|
|
229
|
+
}
|
|
230
|
+
function readCompatibilityAction(rec) {
|
|
231
|
+
const ca = rec.parsed.compatibility_action;
|
|
232
|
+
return typeof ca === "string" ? ca : null;
|
|
233
|
+
}
|
|
234
|
+
function readMembers(rec) {
|
|
235
|
+
const m = rec.parsed.members;
|
|
236
|
+
if (!Array.isArray(m)) {
|
|
237
|
+
return [];
|
|
238
|
+
}
|
|
239
|
+
return m.filter((v) => typeof v === "string");
|
|
240
|
+
}
|
|
241
|
+
function isObject(value) {
|
|
242
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
243
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import type { LintRecord } from "../../../shared/domain/SpecRecord.js";
|
|
2
|
+
export type DiffClassification = "predicate_change" | "content_change" | "none";
|
|
3
|
+
export interface ClassifiedDiff {
|
|
4
|
+
id: string;
|
|
5
|
+
template: string | null;
|
|
6
|
+
classification: DiffClassification;
|
|
7
|
+
changedFields: string[];
|
|
8
|
+
}
|
|
9
|
+
/** Per-ID diff: classify each ID present in `curr` against `prev`. IDs new to
|
|
10
|
+
* `curr` are classified as "content_change" (additive). IDs removed in
|
|
11
|
+
* `curr` are not returned (the consumer detects removal separately via
|
|
12
|
+
* lifecycle.status flips, which lint already covers). */
|
|
13
|
+
export declare function classifyDiff(prev: ReadonlyArray<LintRecord>, curr: ReadonlyArray<LintRecord>): ClassifiedDiff[];
|
|
14
|
+
/** Required bump for a single Surface, computed by walking reachable IDs. */
|
|
15
|
+
export type RequiredBump = "patch" | "minor" | "major";
|
|
16
|
+
export interface SurfaceBumpAnalysis {
|
|
17
|
+
surfaceId: string;
|
|
18
|
+
declaredVersion: string | null;
|
|
19
|
+
prevDeclaredVersion: string | null;
|
|
20
|
+
required: RequiredBump;
|
|
21
|
+
drivenBy: ClassifiedDiff[];
|
|
22
|
+
}
|
|
23
|
+
export declare function requiredSurfaceBumps(prev: ReadonlyArray<LintRecord>, curr: ReadonlyArray<LintRecord>, diffs: ReadonlyArray<ClassifiedDiff>): SurfaceBumpAnalysis[];
|
|
24
|
+
export interface GAStructuralDiff {
|
|
25
|
+
surfaceId: string;
|
|
26
|
+
generatedArtifactId: string;
|
|
27
|
+
classification: Exclude<DiffClassification, "none">;
|
|
28
|
+
}
|
|
29
|
+
export declare function generatedArtifactStructuralDiffs(prev: ReadonlyArray<LintRecord>, curr: ReadonlyArray<LintRecord>, diffs: ReadonlyArray<ClassifiedDiff>): GAStructuralDiff[];
|
|
30
|
+
/** Compare two semver strings ("0.3.0" vs "0.4.0") and return the actual bump.
|
|
31
|
+
* Returns null if either string is unparseable. */
|
|
32
|
+
export declare function actualBump(prev: string | null, curr: string | null): RequiredBump | null;
|
|
33
|
+
export declare function bumpAtLeast(actual: RequiredBump | null, required: RequiredBump): boolean;
|