sovr-patch 0.2.0
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.
Potentially problematic release.
This version of sovr-patch might be problematic. Click here for more details.
- package/LICENSE +66 -0
- package/README.md +112 -0
- package/dist/audit/engine.js +140 -0
- package/dist/audit/engine.js.map +1 -0
- package/dist/audit/packs.js +21 -0
- package/dist/audit/packs.js.map +1 -0
- package/dist/audit/report.js +79 -0
- package/dist/audit/report.js.map +1 -0
- package/dist/audit/types.js +5 -0
- package/dist/audit/types.js.map +1 -0
- package/dist/cli/help.js +108 -0
- package/dist/cli/help.js.map +1 -0
- package/dist/cli/parse-argv.js +73 -0
- package/dist/cli/parse-argv.js.map +1 -0
- package/dist/commands/activate.js +179 -0
- package/dist/commands/activate.js.map +1 -0
- package/dist/commands/audit.js +89 -0
- package/dist/commands/audit.js.map +1 -0
- package/dist/commands/ci-gate.js +239 -0
- package/dist/commands/ci-gate.js.map +1 -0
- package/dist/commands/list-rules.js +11 -0
- package/dist/commands/list-rules.js.map +1 -0
- package/dist/commands/run.js +107 -0
- package/dist/commands/run.js.map +1 -0
- package/dist/commands/status.js +174 -0
- package/dist/commands/status.js.map +1 -0
- package/dist/core/engine.js +68 -0
- package/dist/core/engine.js.map +1 -0
- package/dist/core/license.js +243 -0
- package/dist/core/license.js.map +1 -0
- package/dist/core/load-project.js +41 -0
- package/dist/core/load-project.js.map +1 -0
- package/dist/core/report.js +68 -0
- package/dist/core/report.js.map +1 -0
- package/dist/core/rollback.js +160 -0
- package/dist/core/rollback.js.map +1 -0
- package/dist/core/safe-apply.js +75 -0
- package/dist/core/safe-apply.js.map +1 -0
- package/dist/core/types.js +3 -0
- package/dist/core/types.js.map +1 -0
- package/dist/core/update-check.js +162 -0
- package/dist/core/update-check.js.map +1 -0
- package/dist/core/verify.js +32 -0
- package/dist/core/verify.js.map +1 -0
- package/dist/index.js +124 -0
- package/dist/index.js.map +1 -0
- package/dist/patch/apply.js +14 -0
- package/dist/patch/apply.js.map +1 -0
- package/dist/patch/overlap.js +12 -0
- package/dist/patch/overlap.js.map +1 -0
- package/dist/patch/preview.js +48 -0
- package/dist/patch/preview.js.map +1 -0
- package/dist/rules/design-token/classify.js +16 -0
- package/dist/rules/design-token/classify.js.map +1 -0
- package/dist/rules/design-token/locate.js +113 -0
- package/dist/rules/design-token/locate.js.map +1 -0
- package/dist/rules/design-token/presets.js +53 -0
- package/dist/rules/design-token/presets.js.map +1 -0
- package/dist/rules/design-token/rule.js +13 -0
- package/dist/rules/design-token/rule.js.map +1 -0
- package/dist/rules/design-token/schema.js +84 -0
- package/dist/rules/design-token/schema.js.map +1 -0
- package/dist/rules/design-token/transform.js +27 -0
- package/dist/rules/design-token/transform.js.map +1 -0
- package/dist/rules/field-rename/classify.js +77 -0
- package/dist/rules/field-rename/classify.js.map +1 -0
- package/dist/rules/field-rename/locate.js +294 -0
- package/dist/rules/field-rename/locate.js.map +1 -0
- package/dist/rules/field-rename/rule.js +13 -0
- package/dist/rules/field-rename/rule.js.map +1 -0
- package/dist/rules/field-rename/schema.js +35 -0
- package/dist/rules/field-rename/schema.js.map +1 -0
- package/dist/rules/field-rename/transform.js +160 -0
- package/dist/rules/field-rename/transform.js.map +1 -0
- package/dist/rules/inline-style/classify.js +17 -0
- package/dist/rules/inline-style/classify.js.map +1 -0
- package/dist/rules/inline-style/locate.js +163 -0
- package/dist/rules/inline-style/locate.js.map +1 -0
- package/dist/rules/inline-style/presets.js +71 -0
- package/dist/rules/inline-style/presets.js.map +1 -0
- package/dist/rules/inline-style/rule.js +13 -0
- package/dist/rules/inline-style/rule.js.map +1 -0
- package/dist/rules/inline-style/schema.js +97 -0
- package/dist/rules/inline-style/schema.js.map +1 -0
- package/dist/rules/inline-style/transform.js +52 -0
- package/dist/rules/inline-style/transform.js.map +1 -0
- package/dist/rules/nullish-fallback/classify.js +22 -0
- package/dist/rules/nullish-fallback/classify.js.map +1 -0
- package/dist/rules/nullish-fallback/locate.js +175 -0
- package/dist/rules/nullish-fallback/locate.js.map +1 -0
- package/dist/rules/nullish-fallback/rule.js +13 -0
- package/dist/rules/nullish-fallback/rule.js.map +1 -0
- package/dist/rules/nullish-fallback/schema.js +10 -0
- package/dist/rules/nullish-fallback/schema.js.map +1 -0
- package/dist/rules/nullish-fallback/transform.js +49 -0
- package/dist/rules/nullish-fallback/transform.js.map +1 -0
- package/dist/rules/registry.js +21 -0
- package/dist/rules/registry.js.map +1 -0
- package/dist/rules/types.js +2 -0
- package/dist/rules/types.js.map +1 -0
- package/license.json +13 -0
- package/package.json +64 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"run.js","sourceRoot":"","sources":["../../src/commands/run.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SOVR Patch — CLI status command
|
|
3
|
+
*
|
|
4
|
+
* Usage:
|
|
5
|
+
* sovr-patch status — show license status, plan, rules, and expiry
|
|
6
|
+
* sovr-patch status --json — output as JSON
|
|
7
|
+
* sovr-patch status --verbose — show additional details (file path, signature info)
|
|
8
|
+
*/
|
|
9
|
+
import fs from "node:fs";
|
|
10
|
+
import path from "node:path";
|
|
11
|
+
import os from "node:os";
|
|
12
|
+
import { readLicense, getCurrentPlan } from "../core/license.js";
|
|
13
|
+
const PLAN_LABELS = {
|
|
14
|
+
free: "Free",
|
|
15
|
+
"pack-a": "Safe TS Migration (Pack A)",
|
|
16
|
+
"pack-b": "Frontend Refactor (Pack B)",
|
|
17
|
+
"full-engine": "Full Engine",
|
|
18
|
+
enterprise: "Enterprise",
|
|
19
|
+
};
|
|
20
|
+
const PLAN_FEATURES = {
|
|
21
|
+
free: ["Scan & dry-run", "Diff preview", "Audit reports"],
|
|
22
|
+
"pack-a": [
|
|
23
|
+
"Everything in Free",
|
|
24
|
+
"field-rename → safe-apply",
|
|
25
|
+
"nullish-fallback → safe-apply",
|
|
26
|
+
"1 year of updates",
|
|
27
|
+
],
|
|
28
|
+
"pack-b": [
|
|
29
|
+
"Everything in Free",
|
|
30
|
+
"design-token → safe-apply",
|
|
31
|
+
"inline-style → safe-apply",
|
|
32
|
+
"1 year of updates",
|
|
33
|
+
],
|
|
34
|
+
"full-engine": [
|
|
35
|
+
"Everything in Free",
|
|
36
|
+
"All rules → safe-apply",
|
|
37
|
+
"1 year of updates",
|
|
38
|
+
"New rule pack discounts",
|
|
39
|
+
],
|
|
40
|
+
enterprise: [
|
|
41
|
+
"Everything in Full Engine",
|
|
42
|
+
"CI gate integration",
|
|
43
|
+
"Custom rules",
|
|
44
|
+
"Audit trail",
|
|
45
|
+
"Private support + SLA",
|
|
46
|
+
],
|
|
47
|
+
};
|
|
48
|
+
function daysUntil(dateStr) {
|
|
49
|
+
const now = new Date();
|
|
50
|
+
const target = new Date(dateStr);
|
|
51
|
+
const diff = target.getTime() - now.getTime();
|
|
52
|
+
return Math.ceil(diff / (1000 * 60 * 60 * 24));
|
|
53
|
+
}
|
|
54
|
+
function expiryColor(daysLeft) {
|
|
55
|
+
if (daysLeft <= 0)
|
|
56
|
+
return "\x1b[31m"; // red — expired
|
|
57
|
+
if (daysLeft <= 30)
|
|
58
|
+
return "\x1b[33m"; // yellow — expiring soon
|
|
59
|
+
return "\x1b[32m"; // green — healthy
|
|
60
|
+
}
|
|
61
|
+
function getLicensePath() {
|
|
62
|
+
if (process.env.SOVR_LICENSE_PATH) {
|
|
63
|
+
return process.env.SOVR_LICENSE_PATH;
|
|
64
|
+
}
|
|
65
|
+
return path.join(os.homedir(), ".sovr-patch", "license.json");
|
|
66
|
+
}
|
|
67
|
+
export function statusCommand(argv) {
|
|
68
|
+
const json = argv.includes("--json");
|
|
69
|
+
const verbose = argv.includes("--verbose");
|
|
70
|
+
const license = readLicense();
|
|
71
|
+
const plan = getCurrentPlan();
|
|
72
|
+
const licensePath = getLicensePath();
|
|
73
|
+
const fileExists = fs.existsSync(licensePath);
|
|
74
|
+
// ─── JSON output ─────────────────────────────────────────────
|
|
75
|
+
if (json) {
|
|
76
|
+
const output = {
|
|
77
|
+
plan,
|
|
78
|
+
planLabel: PLAN_LABELS[plan],
|
|
79
|
+
licensed: plan !== "free",
|
|
80
|
+
features: PLAN_FEATURES[plan],
|
|
81
|
+
};
|
|
82
|
+
if (license && plan !== "free") {
|
|
83
|
+
const daysLeft = daysUntil(license.exp);
|
|
84
|
+
output.email = license.email;
|
|
85
|
+
output.rules = license.rules;
|
|
86
|
+
output.issuedAt = license.iat;
|
|
87
|
+
output.expiresAt = license.exp;
|
|
88
|
+
output.daysRemaining = daysLeft;
|
|
89
|
+
output.expired = daysLeft <= 0;
|
|
90
|
+
}
|
|
91
|
+
if (verbose) {
|
|
92
|
+
output.licensePath = licensePath;
|
|
93
|
+
output.licenseFileExists = fileExists;
|
|
94
|
+
}
|
|
95
|
+
console.log(JSON.stringify(output, null, 2));
|
|
96
|
+
return;
|
|
97
|
+
}
|
|
98
|
+
// ─── Terminal output ─────────────────────────────────────────
|
|
99
|
+
console.log("");
|
|
100
|
+
console.log("\x1b[1m SOVR Patch — License Status\x1b[0m");
|
|
101
|
+
console.log(" ─────────────────────────────────");
|
|
102
|
+
if (!license || plan === "free") {
|
|
103
|
+
console.log("");
|
|
104
|
+
console.log(` Plan: \x1b[33m${PLAN_LABELS.free}\x1b[0m`);
|
|
105
|
+
console.log(` Status: \x1b[33mNo active license\x1b[0m`);
|
|
106
|
+
console.log("");
|
|
107
|
+
console.log(" \x1b[2mIncluded in Free:\x1b[0m");
|
|
108
|
+
for (const feature of PLAN_FEATURES.free) {
|
|
109
|
+
console.log(` ✓ ${feature}`);
|
|
110
|
+
}
|
|
111
|
+
console.log("");
|
|
112
|
+
console.log(" \x1b[2mLocked (requires license):\x1b[0m");
|
|
113
|
+
console.log(" ✗ Safe apply (--apply)");
|
|
114
|
+
console.log("");
|
|
115
|
+
console.log(" \x1b[36mTo activate:\x1b[0m");
|
|
116
|
+
console.log(" 1. Purchase at: https://sovr-patch-landing.manus.space/#pricing");
|
|
117
|
+
console.log(" 2. Download license.json from the confirmation page");
|
|
118
|
+
console.log(" 3. Run: \x1b[32msovr-patch activate license.json\x1b[0m");
|
|
119
|
+
console.log("");
|
|
120
|
+
return;
|
|
121
|
+
}
|
|
122
|
+
// Licensed user
|
|
123
|
+
const daysLeft = daysUntil(license.exp);
|
|
124
|
+
const expColor = expiryColor(daysLeft);
|
|
125
|
+
const expDate = new Date(license.exp).toLocaleDateString("en-US", {
|
|
126
|
+
year: "numeric",
|
|
127
|
+
month: "long",
|
|
128
|
+
day: "numeric",
|
|
129
|
+
});
|
|
130
|
+
const iatDate = new Date(license.iat).toLocaleDateString("en-US", {
|
|
131
|
+
year: "numeric",
|
|
132
|
+
month: "long",
|
|
133
|
+
day: "numeric",
|
|
134
|
+
});
|
|
135
|
+
console.log("");
|
|
136
|
+
console.log(` Plan: \x1b[32m${PLAN_LABELS[plan]}\x1b[0m`);
|
|
137
|
+
console.log(` Email: ${license.email}`);
|
|
138
|
+
console.log(` Issued: ${iatDate}`);
|
|
139
|
+
if (daysLeft <= 0) {
|
|
140
|
+
console.log(` Expires: ${expColor}${expDate} (EXPIRED)\x1b[0m`);
|
|
141
|
+
console.log("");
|
|
142
|
+
console.log(" \x1b[31m⚠ Your license has expired.\x1b[0m");
|
|
143
|
+
console.log(" Safe apply (--apply) is no longer available.");
|
|
144
|
+
console.log(" Renew at: https://sovr-patch-landing.manus.space/#pricing");
|
|
145
|
+
}
|
|
146
|
+
else if (daysLeft <= 30) {
|
|
147
|
+
console.log(` Expires: ${expColor}${expDate} (${daysLeft} days remaining)\x1b[0m`);
|
|
148
|
+
console.log("");
|
|
149
|
+
console.log(" \x1b[33m⚠ Your license expires soon.\x1b[0m");
|
|
150
|
+
console.log(" Renew at: https://sovr-patch-landing.manus.space/#pricing");
|
|
151
|
+
}
|
|
152
|
+
else {
|
|
153
|
+
console.log(` Expires: ${expColor}${expDate} (${daysLeft} days remaining)\x1b[0m`);
|
|
154
|
+
}
|
|
155
|
+
console.log("");
|
|
156
|
+
console.log(" \x1b[2mUnlocked rules:\x1b[0m");
|
|
157
|
+
for (const rule of license.rules) {
|
|
158
|
+
console.log(` ✓ ${rule} → safe-apply`);
|
|
159
|
+
}
|
|
160
|
+
console.log("");
|
|
161
|
+
console.log(" \x1b[2mPlan features:\x1b[0m");
|
|
162
|
+
for (const feature of PLAN_FEATURES[plan]) {
|
|
163
|
+
console.log(` ✓ ${feature}`);
|
|
164
|
+
}
|
|
165
|
+
if (verbose) {
|
|
166
|
+
console.log("");
|
|
167
|
+
console.log(" \x1b[2mDetails:\x1b[0m");
|
|
168
|
+
console.log(` License file: ${licensePath}`);
|
|
169
|
+
console.log(` File exists: ${fileExists ? "yes" : "no"}`);
|
|
170
|
+
console.log(` Signature: ${license.signature === "legacy" || license.signature === "legacy-key-activation" ? "legacy (unsigned)" : "Ed25519 verified"}`);
|
|
171
|
+
}
|
|
172
|
+
console.log("");
|
|
173
|
+
}
|
|
174
|
+
//# sourceMappingURL=status.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"status.js","sourceRoot":"","sources":["../../src/commands/status.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { loadProject } from "./load-project.js";
|
|
2
|
+
import { buildMigrationReport } from "./report.js";
|
|
3
|
+
import { verifyWithTsc } from "./verify.js";
|
|
4
|
+
import { safeApplyWithVerify } from "./safe-apply.js";
|
|
5
|
+
import { buildDiffFromPreview, previewPatchedFiles, } from "../patch/preview.js";
|
|
6
|
+
export async function runRule(params) {
|
|
7
|
+
const loaded = loadProject(params.options.repo, params.options.tsconfig);
|
|
8
|
+
const config = params.rule.parseConfig(params.configInput);
|
|
9
|
+
const context = { loaded, config };
|
|
10
|
+
// Phase 1: Locate
|
|
11
|
+
const located = params.rule.locate(context);
|
|
12
|
+
// Phase 2: Classify
|
|
13
|
+
const hits = located.map((item) => params.rule.classify(item, context));
|
|
14
|
+
const scan = {
|
|
15
|
+
totalFiles: loaded.sourceFiles.length,
|
|
16
|
+
totalHits: hits.length,
|
|
17
|
+
hits,
|
|
18
|
+
};
|
|
19
|
+
// Phase 3: Transform (only safe hits)
|
|
20
|
+
const patches = hits
|
|
21
|
+
.filter((hit) => hit.severity === "safe")
|
|
22
|
+
.map((hit) => params.rule.transform(hit, context))
|
|
23
|
+
.filter((patch) => patch !== null);
|
|
24
|
+
// Phase 4: Apply (if requested)
|
|
25
|
+
if (params.options.apply) {
|
|
26
|
+
const safeApplyResult = safeApplyWithVerify(loaded, patches);
|
|
27
|
+
const report = buildMigrationReport({
|
|
28
|
+
loaded,
|
|
29
|
+
scan,
|
|
30
|
+
patchCount: patches.length,
|
|
31
|
+
changedFiles: safeApplyResult.changedFiles,
|
|
32
|
+
});
|
|
33
|
+
return {
|
|
34
|
+
ruleName: params.rule.name,
|
|
35
|
+
repoPath: loaded.repoPath,
|
|
36
|
+
scan,
|
|
37
|
+
patches,
|
|
38
|
+
changedFiles: safeApplyResult.changedFiles,
|
|
39
|
+
diffText: safeApplyResult.diffText,
|
|
40
|
+
verify: safeApplyResult.verify,
|
|
41
|
+
applied: safeApplyResult.applied,
|
|
42
|
+
tempRepoPath: safeApplyResult.tempRepoPath,
|
|
43
|
+
report,
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
// Dry run: preview + optional verify
|
|
47
|
+
const previewMap = previewPatchedFiles(loaded, patches);
|
|
48
|
+
const preview = buildDiffFromPreview(previewMap);
|
|
49
|
+
const verify = params.options.verify === false ? undefined : verifyWithTsc(loaded);
|
|
50
|
+
const report = buildMigrationReport({
|
|
51
|
+
loaded,
|
|
52
|
+
scan,
|
|
53
|
+
patchCount: patches.length,
|
|
54
|
+
changedFiles: preview.changedFiles,
|
|
55
|
+
});
|
|
56
|
+
return {
|
|
57
|
+
ruleName: params.rule.name,
|
|
58
|
+
repoPath: loaded.repoPath,
|
|
59
|
+
scan,
|
|
60
|
+
patches,
|
|
61
|
+
changedFiles: preview.changedFiles,
|
|
62
|
+
diffText: preview.diffText,
|
|
63
|
+
verify,
|
|
64
|
+
applied: false,
|
|
65
|
+
report,
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
//# sourceMappingURL=engine.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"engine.js","sourceRoot":"","sources":["../../src/core/engine.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,243 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SOVR Patch — Offline Signed License System
|
|
3
|
+
*
|
|
4
|
+
* License is a signed JSON file verified locally with Ed25519 public key.
|
|
5
|
+
* No network required. No license server dependency.
|
|
6
|
+
*
|
|
7
|
+
* License file structure:
|
|
8
|
+
* {
|
|
9
|
+
* "email": "user@example.com",
|
|
10
|
+
* "plan": "full-engine",
|
|
11
|
+
* "rules": ["field-rename", "nullish-fallback", "design-token", "inline-style"],
|
|
12
|
+
* "exp": "2027-03-07T00:00:00.000Z",
|
|
13
|
+
* "iat": "2026-03-07T00:00:00.000Z",
|
|
14
|
+
* "signature": "<base64 Ed25519 signature>"
|
|
15
|
+
* }
|
|
16
|
+
*
|
|
17
|
+
* Storage: ~/.sovr-patch/license.json
|
|
18
|
+
* Env override: SOVR_LICENSE_PATH
|
|
19
|
+
*
|
|
20
|
+
* Pricing model:
|
|
21
|
+
* Free: scan, dry-run, diff, report, audit
|
|
22
|
+
* Pack A ($99): field-rename + nullish-fallback → safe-apply
|
|
23
|
+
* Pack B ($99): design-token + inline-style → safe-apply
|
|
24
|
+
* Full Engine ($249): all rules → safe-apply
|
|
25
|
+
* Enterprise: CI gate, audit trail, custom rules, SLA
|
|
26
|
+
*/
|
|
27
|
+
import fs from "node:fs";
|
|
28
|
+
import path from "node:path";
|
|
29
|
+
import os from "node:os";
|
|
30
|
+
import crypto from "node:crypto";
|
|
31
|
+
// ─── Embedded public key (Ed25519 SPKI PEM) ─────────────────────
|
|
32
|
+
// This is the public key used to verify license signatures.
|
|
33
|
+
// The corresponding private key is kept on the server only.
|
|
34
|
+
const PUBLIC_KEY_PEM = `-----BEGIN PUBLIC KEY-----
|
|
35
|
+
MCowBQYDK2VwAyEAwvmewBIJ4bDjd/Sli1fRjccdFxO+WzO3LVYi73fiq5I=
|
|
36
|
+
-----END PUBLIC KEY-----`;
|
|
37
|
+
// ─── Rule → Pack mapping ────────────────────────────────────────
|
|
38
|
+
const RULE_PACK_MAP = {
|
|
39
|
+
"field-rename": "pack-a",
|
|
40
|
+
"nullish-fallback": "pack-a",
|
|
41
|
+
"design-token": "pack-b",
|
|
42
|
+
"inline-style": "pack-b",
|
|
43
|
+
};
|
|
44
|
+
// ─── Pack hierarchy (what each plan unlocks) ────────────────────
|
|
45
|
+
const PLAN_UNLOCKS = {
|
|
46
|
+
free: new Set(), // no safe-apply
|
|
47
|
+
"pack-a": new Set(["field-rename", "nullish-fallback"]),
|
|
48
|
+
"pack-b": new Set(["design-token", "inline-style"]),
|
|
49
|
+
"full-engine": new Set([
|
|
50
|
+
"field-rename",
|
|
51
|
+
"nullish-fallback",
|
|
52
|
+
"design-token",
|
|
53
|
+
"inline-style",
|
|
54
|
+
]),
|
|
55
|
+
enterprise: new Set([
|
|
56
|
+
"field-rename",
|
|
57
|
+
"nullish-fallback",
|
|
58
|
+
"design-token",
|
|
59
|
+
"inline-style",
|
|
60
|
+
]),
|
|
61
|
+
};
|
|
62
|
+
// ─── License file path ──────────────────────────────────────────
|
|
63
|
+
function getLicensePath() {
|
|
64
|
+
// Allow env override for CI / AI agent scenarios
|
|
65
|
+
if (process.env.SOVR_LICENSE_PATH) {
|
|
66
|
+
return process.env.SOVR_LICENSE_PATH;
|
|
67
|
+
}
|
|
68
|
+
return path.join(os.homedir(), ".sovr-patch", "license.json");
|
|
69
|
+
}
|
|
70
|
+
// ─── Verify Ed25519 signature ───────────────────────────────────
|
|
71
|
+
function verifySignature(payload, signatureBase64) {
|
|
72
|
+
try {
|
|
73
|
+
const publicKey = crypto.createPublicKey(PUBLIC_KEY_PEM);
|
|
74
|
+
const signature = Buffer.from(signatureBase64, "base64");
|
|
75
|
+
return crypto.verify(null, Buffer.from(payload, "utf-8"), publicKey, signature);
|
|
76
|
+
}
|
|
77
|
+
catch {
|
|
78
|
+
return false;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
// ─── Build the canonical payload for signing/verification ───────
|
|
82
|
+
export function buildLicensePayload(license) {
|
|
83
|
+
// Deterministic JSON: sorted keys, no extra whitespace
|
|
84
|
+
return JSON.stringify({
|
|
85
|
+
email: license.email,
|
|
86
|
+
exp: license.exp,
|
|
87
|
+
iat: license.iat,
|
|
88
|
+
plan: license.plan,
|
|
89
|
+
rules: [...license.rules].sort(),
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
// ─── Read and verify license from disk ──────────────────────────
|
|
93
|
+
export function readLicense() {
|
|
94
|
+
const licensePath = getLicensePath();
|
|
95
|
+
try {
|
|
96
|
+
if (!fs.existsSync(licensePath))
|
|
97
|
+
return null;
|
|
98
|
+
const raw = fs.readFileSync(licensePath, "utf-8");
|
|
99
|
+
const parsed = JSON.parse(raw);
|
|
100
|
+
// Check if this is a signed license (new format)
|
|
101
|
+
if (parsed.signature && parsed.email && parsed.plan && parsed.rules && parsed.exp && parsed.iat) {
|
|
102
|
+
const signed = parsed;
|
|
103
|
+
// Verify Ed25519 signature
|
|
104
|
+
const payload = buildLicensePayload(signed);
|
|
105
|
+
if (!verifySignature(payload, signed.signature)) {
|
|
106
|
+
console.error("\x1b[31m[License] Invalid signature — license may be tampered.\x1b[0m");
|
|
107
|
+
return null;
|
|
108
|
+
}
|
|
109
|
+
// Check expiry
|
|
110
|
+
const expDate = new Date(signed.exp);
|
|
111
|
+
if (expDate < new Date()) {
|
|
112
|
+
console.error("\x1b[33m[License] License expired on " + expDate.toLocaleDateString() + ".\x1b[0m");
|
|
113
|
+
return null;
|
|
114
|
+
}
|
|
115
|
+
return signed;
|
|
116
|
+
}
|
|
117
|
+
// Legacy format backward compat: { key, plan, activatedAt }
|
|
118
|
+
if (parsed.key && parsed.plan && parsed.activatedAt) {
|
|
119
|
+
// Convert legacy to a pseudo-signed license (no signature verification)
|
|
120
|
+
console.warn("\x1b[33m[License] Legacy license format detected. Please re-activate with a signed license.\x1b[0m");
|
|
121
|
+
return {
|
|
122
|
+
email: "legacy@sovr.app",
|
|
123
|
+
plan: parsed.plan,
|
|
124
|
+
rules: [...(PLAN_UNLOCKS[parsed.plan] ?? new Set())],
|
|
125
|
+
exp: new Date(Date.now() + 365 * 24 * 60 * 60 * 1000).toISOString(),
|
|
126
|
+
iat: parsed.activatedAt,
|
|
127
|
+
signature: "legacy",
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
return null;
|
|
131
|
+
}
|
|
132
|
+
catch {
|
|
133
|
+
return null;
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
// ─── Write license to disk ──────────────────────────────────────
|
|
137
|
+
export function writeLicense(license) {
|
|
138
|
+
const licensePath = getLicensePath();
|
|
139
|
+
const dir = path.dirname(licensePath);
|
|
140
|
+
if (!fs.existsSync(dir)) {
|
|
141
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
142
|
+
}
|
|
143
|
+
fs.writeFileSync(licensePath, JSON.stringify(license, null, 2), "utf-8");
|
|
144
|
+
}
|
|
145
|
+
// ─── Get current plan ───────────────────────────────────────────
|
|
146
|
+
export function getCurrentPlan() {
|
|
147
|
+
const license = readLicense();
|
|
148
|
+
return license?.plan ?? "free";
|
|
149
|
+
}
|
|
150
|
+
// ─── Get current license info (for display) ─────────────────────
|
|
151
|
+
export function getLicenseInfo() {
|
|
152
|
+
const license = readLicense();
|
|
153
|
+
if (!license)
|
|
154
|
+
return { plan: "free" };
|
|
155
|
+
return {
|
|
156
|
+
plan: license.plan,
|
|
157
|
+
email: license.email,
|
|
158
|
+
exp: license.exp,
|
|
159
|
+
rules: license.rules,
|
|
160
|
+
};
|
|
161
|
+
}
|
|
162
|
+
// ─── Check if safe-apply is allowed for a rule ──────────────────
|
|
163
|
+
export function checkApplyLicense(ruleName) {
|
|
164
|
+
const plan = getCurrentPlan();
|
|
165
|
+
const allowedRules = PLAN_UNLOCKS[plan];
|
|
166
|
+
if (allowedRules.has(ruleName)) {
|
|
167
|
+
return { allowed: true, plan };
|
|
168
|
+
}
|
|
169
|
+
// Build unlock options based on which pack the rule belongs to
|
|
170
|
+
const requiredPack = RULE_PACK_MAP[ruleName];
|
|
171
|
+
const unlockOptions = [];
|
|
172
|
+
if (requiredPack === "pack-a") {
|
|
173
|
+
unlockOptions.push({
|
|
174
|
+
name: "Safe TS Migration Pack",
|
|
175
|
+
price: "$99",
|
|
176
|
+
description: "field-rename + nullish-fallback + safe-apply",
|
|
177
|
+
});
|
|
178
|
+
}
|
|
179
|
+
else if (requiredPack === "pack-b") {
|
|
180
|
+
unlockOptions.push({
|
|
181
|
+
name: "Frontend Refactor Pack",
|
|
182
|
+
price: "$99",
|
|
183
|
+
description: "design-token + inline-style + safe-apply",
|
|
184
|
+
});
|
|
185
|
+
}
|
|
186
|
+
unlockOptions.push({
|
|
187
|
+
name: "Full Engine",
|
|
188
|
+
price: "$249",
|
|
189
|
+
description: "All rules + safe-apply + 1 year updates",
|
|
190
|
+
});
|
|
191
|
+
return {
|
|
192
|
+
allowed: false,
|
|
193
|
+
plan,
|
|
194
|
+
message: "Safe apply is not available on your current plan.",
|
|
195
|
+
unlockOptions,
|
|
196
|
+
};
|
|
197
|
+
}
|
|
198
|
+
// ─── Format the CLI unlock prompt ───────────────────────────────
|
|
199
|
+
export function formatUnlockPrompt(ruleName, totalHits, patchCount, changedFiles) {
|
|
200
|
+
const check = checkApplyLicense(ruleName);
|
|
201
|
+
if (check.allowed)
|
|
202
|
+
return "";
|
|
203
|
+
const lines = [];
|
|
204
|
+
lines.push("");
|
|
205
|
+
lines.push(`\x1b[33m${check.message}\x1b[0m`);
|
|
206
|
+
lines.push("");
|
|
207
|
+
lines.push("This migration would:");
|
|
208
|
+
lines.push(` - scan ${totalHits} hits across ${changedFiles} files`);
|
|
209
|
+
lines.push(` - generate ${patchCount} verified patches`);
|
|
210
|
+
lines.push(` - verify before write (tsc --noEmit)`);
|
|
211
|
+
lines.push("");
|
|
212
|
+
lines.push("To unlock safe apply:");
|
|
213
|
+
for (const opt of check.unlockOptions ?? []) {
|
|
214
|
+
lines.push(` \x1b[32m${opt.name} — ${opt.price}\x1b[0m`);
|
|
215
|
+
}
|
|
216
|
+
lines.push("");
|
|
217
|
+
lines.push("Purchase at: \x1b[36mhttps://sovr-patch-landing.manus.space/#pricing\x1b[0m");
|
|
218
|
+
lines.push("Then activate: sovr-patch activate <license.json>");
|
|
219
|
+
lines.push("");
|
|
220
|
+
return lines.join("\n");
|
|
221
|
+
}
|
|
222
|
+
// ─── Format the dry-run footer (shown after every free dry-run) ─
|
|
223
|
+
export function formatDryRunFooter(ruleName) {
|
|
224
|
+
const plan = getCurrentPlan();
|
|
225
|
+
if (plan !== "free")
|
|
226
|
+
return "";
|
|
227
|
+
const check = checkApplyLicense(ruleName);
|
|
228
|
+
if (check.allowed)
|
|
229
|
+
return "";
|
|
230
|
+
const lines = [];
|
|
231
|
+
lines.push("");
|
|
232
|
+
lines.push("Dry-run complete.");
|
|
233
|
+
lines.push(`\x1b[33mSafe apply is locked on the free plan.\x1b[0m`);
|
|
234
|
+
lines.push("");
|
|
235
|
+
lines.push("Unlock options:");
|
|
236
|
+
for (const opt of check.unlockOptions ?? []) {
|
|
237
|
+
lines.push(` ${opt.name} — ${opt.price}`);
|
|
238
|
+
}
|
|
239
|
+
lines.push(` Enterprise — contact sales`);
|
|
240
|
+
lines.push("");
|
|
241
|
+
return lines.join("\n");
|
|
242
|
+
}
|
|
243
|
+
//# sourceMappingURL=license.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"license.js","sourceRoot":"","sources":["../../src/core/license.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import fs from "node:fs";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import { Project } from "ts-morph";
|
|
4
|
+
function resolveTsconfigPath(repoPath, tsconfigPath) {
|
|
5
|
+
if (tsconfigPath) {
|
|
6
|
+
const absolute = path.isAbsolute(tsconfigPath)
|
|
7
|
+
? tsconfigPath
|
|
8
|
+
: path.resolve(repoPath, tsconfigPath);
|
|
9
|
+
if (!fs.existsSync(absolute)) {
|
|
10
|
+
throw new Error(`tsconfig not found: ${absolute}`);
|
|
11
|
+
}
|
|
12
|
+
return absolute;
|
|
13
|
+
}
|
|
14
|
+
const defaultPath = path.resolve(repoPath, "tsconfig.json");
|
|
15
|
+
if (!fs.existsSync(defaultPath)) {
|
|
16
|
+
throw new Error(`tsconfig.json not found in repo root: ${defaultPath}. Pass --tsconfig explicitly.`);
|
|
17
|
+
}
|
|
18
|
+
return defaultPath;
|
|
19
|
+
}
|
|
20
|
+
export function loadProject(repoPathInput, tsconfigPath) {
|
|
21
|
+
const repoPath = path.resolve(repoPathInput);
|
|
22
|
+
if (!fs.existsSync(repoPath)) {
|
|
23
|
+
throw new Error(`repo path does not exist: ${repoPath}`);
|
|
24
|
+
}
|
|
25
|
+
const resolvedTsconfigPath = resolveTsconfigPath(repoPath, tsconfigPath);
|
|
26
|
+
const project = new Project({
|
|
27
|
+
tsConfigFilePath: resolvedTsconfigPath,
|
|
28
|
+
skipAddingFilesFromTsConfig: false,
|
|
29
|
+
});
|
|
30
|
+
const sourceFiles = project
|
|
31
|
+
.getSourceFiles()
|
|
32
|
+
.filter((sf) => !sf.isDeclarationFile())
|
|
33
|
+
.filter((sf) => !sf.getFilePath().includes(`${path.sep}node_modules${path.sep}`));
|
|
34
|
+
return {
|
|
35
|
+
repoPath,
|
|
36
|
+
tsconfigPath: resolvedTsconfigPath,
|
|
37
|
+
project,
|
|
38
|
+
sourceFiles,
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
//# sourceMappingURL=load-project.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"load-project.js","sourceRoot":"","sources":["../../src/core/load-project.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,OAAO,EAAE,MAAM,UAAU,CAAC;AAGnC,SAAS,mBAAmB,CAAC,QAAgB,EAAE,YAAqB;IAClE,IAAI,YAAY,EAAE,CAAC;QACjB,MAAM,QAAQ,GAAG,IAAI,CAAC,UAAU,CAAC,YAAY,CAAC;YAC5C,CAAC,CAAC,YAAY;YACd,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,EAAE,YAAY,CAAC,CAAC;QAEzC,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;YAC7B,MAAM,IAAI,KAAK,CAAC,uBAAuB,QAAQ,EAAE,CAAC,CAAC;QACrD,CAAC;QACD,OAAO,QAAQ,CAAC;IAClB,CAAC;IAED,MAAM,WAAW,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,EAAE,eAAe,CAAC,CAAC;IAC5D,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,WAAW,CAAC,EAAE,CAAC;QAChC,MAAM,IAAI,KAAK,CACb,yCAAyC,WAAW,+BAA+B,CACpF,CAAC;IACJ,CAAC;IAED,OAAO,WAAW,CAAC;AACrB,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,aAAqB,EAAE,YAAqB;IACtE,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC;IAC7C,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC7B,MAAM,IAAI,KAAK,CAAC,6BAA6B,QAAQ,EAAE,CAAC,CAAC;IAC3D,CAAC;IAED,MAAM,oBAAoB,GAAG,mBAAmB,CAAC,QAAQ,EAAE,YAAY,CAAC,CAAC;IAEzE,MAAM,OAAO,GAAG,IAAI,OAAO,CAAC;QAC1B,gBAAgB,EAAE,oBAAoB;QACtC,2BAA2B,EAAE,KAAK;KACnC,CAAC,CAAC;IAEH,MAAM,WAAW,GAAG,OAAO;SACxB,cAAc,EAAE;SAChB,MAAM,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,iBAAiB,EAAE,CAAC;SACvC,MAAM,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,GAAG,IAAI,CAAC,GAAG,eAAe,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;IAEpF,OAAO;QACL,QAAQ;QACR,YAAY,EAAE,oBAAoB;QAClC,OAAO;QACP,WAAW;KACZ,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import fs from "node:fs";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
function groupHitsByFile(hits) {
|
|
4
|
+
const map = new Map();
|
|
5
|
+
for (const hit of hits) {
|
|
6
|
+
const list = map.get(hit.filePath) ?? [];
|
|
7
|
+
list.push(hit);
|
|
8
|
+
map.set(hit.filePath, list);
|
|
9
|
+
}
|
|
10
|
+
return map;
|
|
11
|
+
}
|
|
12
|
+
export function buildMigrationReport(params) {
|
|
13
|
+
const grouped = groupHitsByFile(params.scan.hits);
|
|
14
|
+
const files = [...grouped.entries()]
|
|
15
|
+
.sort((a, b) => a[0].localeCompare(b[0]))
|
|
16
|
+
.map(([filePath, hits]) => ({
|
|
17
|
+
filePath,
|
|
18
|
+
safe: hits.filter((h) => h.severity === "safe"),
|
|
19
|
+
ambiguous: hits.filter((h) => h.severity === "ambiguous"),
|
|
20
|
+
unsafe: hits.filter((h) => h.severity === "unsafe"),
|
|
21
|
+
}));
|
|
22
|
+
return {
|
|
23
|
+
repoPath: params.loaded.repoPath,
|
|
24
|
+
tsconfigPath: params.loaded.tsconfigPath,
|
|
25
|
+
summary: {
|
|
26
|
+
totalFiles: params.scan.totalFiles,
|
|
27
|
+
totalHits: params.scan.totalHits,
|
|
28
|
+
safeCount: params.scan.hits.filter((h) => h.severity === "safe").length,
|
|
29
|
+
ambiguousCount: params.scan.hits.filter((h) => h.severity === "ambiguous").length,
|
|
30
|
+
unsafeCount: params.scan.hits.filter((h) => h.severity === "unsafe").length,
|
|
31
|
+
patchCount: params.patchCount,
|
|
32
|
+
changedFilesCount: params.changedFiles.length,
|
|
33
|
+
},
|
|
34
|
+
files,
|
|
35
|
+
changedFiles: [...params.changedFiles].sort((a, b) => a.localeCompare(b)),
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
export function writeReportToFile(report, outputPath) {
|
|
39
|
+
const absolute = path.resolve(outputPath);
|
|
40
|
+
fs.mkdirSync(path.dirname(absolute), { recursive: true });
|
|
41
|
+
fs.writeFileSync(absolute, JSON.stringify(report, null, 2), "utf8");
|
|
42
|
+
return absolute;
|
|
43
|
+
}
|
|
44
|
+
export function printReportSummary(report) {
|
|
45
|
+
console.log("Report:");
|
|
46
|
+
console.log(`- total files: ${report.summary.totalFiles}`);
|
|
47
|
+
console.log(`- total hits: ${report.summary.totalHits}`);
|
|
48
|
+
console.log(`- safe: ${report.summary.safeCount}`);
|
|
49
|
+
console.log(`- ambiguous: ${report.summary.ambiguousCount}`);
|
|
50
|
+
console.log(`- unsafe: ${report.summary.unsafeCount}`);
|
|
51
|
+
console.log(`- patches: ${report.summary.patchCount}`);
|
|
52
|
+
console.log(`- changed files: ${report.summary.changedFilesCount}`);
|
|
53
|
+
console.log("");
|
|
54
|
+
for (const file of report.files) {
|
|
55
|
+
const count = file.safe.length + file.ambiguous.length + file.unsafe.length;
|
|
56
|
+
console.log(`${file.filePath} (${count})`);
|
|
57
|
+
if (file.safe.length) {
|
|
58
|
+
console.log(` safe: ${file.safe.length}`);
|
|
59
|
+
}
|
|
60
|
+
if (file.ambiguous.length) {
|
|
61
|
+
console.log(` ambiguous: ${file.ambiguous.length}`);
|
|
62
|
+
}
|
|
63
|
+
if (file.unsafe.length) {
|
|
64
|
+
console.log(` unsafe: ${file.unsafe.length}`);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
//# sourceMappingURL=report.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"report.js","sourceRoot":"","sources":["../../src/core/report.ts"],"names":[],"mappings":"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"}
|