@sonnechasser/ntrp 0.1.2 → 0.1.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/dist/index.js +1026 -371
- package/dist/index.js.map +1 -1
- package/dist/investigation/verbosity-cli.js +7 -1
- package/dist/investigation/verbosity-cli.js.map +1 -1
- package/dist/mcp/server.js +145 -7
- package/dist/mcp/server.js.map +1 -1
- package/package.json +1 -1
package/dist/mcp/server.js
CHANGED
|
@@ -6525,7 +6525,7 @@ function secretPromptLine(question) {
|
|
|
6525
6525
|
return ` ${paint("accent", "\u25B8")} ${bold(question)} ${chalk3.dim("(hidden \u2014 paste once, Enter)")} `;
|
|
6526
6526
|
}
|
|
6527
6527
|
function stripTerminalArtifacts(input) {
|
|
6528
|
-
return input.replace(/\x1b\[[0-9;]*[a-zA-Z~]/g, "").replace(/\x1b\][^\x07]*(\x07|\x1b\\)/g, "");
|
|
6528
|
+
return input.replace(/\x1b\[[0-9;]*[a-zA-Z~]/g, "").replace(/\x1b\][^\x07]*(\x07|\x1b\\)/g, "").replace(/\x1b\[200~/g, "").replace(/\x1b\[201~/g, "");
|
|
6529
6529
|
}
|
|
6530
6530
|
function renderQuestion(question, defaultValue) {
|
|
6531
6531
|
const base = ` ${marker()}${bold(question)}`;
|
|
@@ -6583,8 +6583,8 @@ function createPromptSession(existing, ctx) {
|
|
|
6583
6583
|
for (; ; ) {
|
|
6584
6584
|
const raw = (await rl2.question(renderQuestion(`Your pick [1-${choices.length}]`, defaultLabel))).trim();
|
|
6585
6585
|
assertNotGlobalReplCommand(raw);
|
|
6586
|
-
const
|
|
6587
|
-
const n = Number(
|
|
6586
|
+
const pick2 = raw || defaultLabel || "";
|
|
6587
|
+
const n = Number(pick2);
|
|
6588
6588
|
if (Number.isInteger(n) && n >= 1 && n <= choices.length) {
|
|
6589
6589
|
return choices[n - 1].value;
|
|
6590
6590
|
}
|
|
@@ -6712,12 +6712,18 @@ function createPromptSession(existing, ctx) {
|
|
|
6712
6712
|
console.log(" " + chalk3.dim("Try again \u2014 paste the key once, then Enter."));
|
|
6713
6713
|
}
|
|
6714
6714
|
}
|
|
6715
|
+
async function askPressEnter(message) {
|
|
6716
|
+
await rl2.question(
|
|
6717
|
+
` ${paint("accent", "\u25B8")} ${bold(message)} ${chalk3.dim("(Enter)")} `
|
|
6718
|
+
);
|
|
6719
|
+
}
|
|
6715
6720
|
return {
|
|
6716
6721
|
ask,
|
|
6717
6722
|
askRequired,
|
|
6718
6723
|
confirm,
|
|
6719
6724
|
choose,
|
|
6720
6725
|
askMulti,
|
|
6726
|
+
askPressEnter,
|
|
6721
6727
|
askSecret,
|
|
6722
6728
|
close: () => {
|
|
6723
6729
|
if (ctx && existing) {
|
|
@@ -14801,6 +14807,72 @@ import { join as join14 } from "path";
|
|
|
14801
14807
|
// src/license/verify.ts
|
|
14802
14808
|
init_store();
|
|
14803
14809
|
import { createHmac } from "crypto";
|
|
14810
|
+
|
|
14811
|
+
// src/license/trial-policy.ts
|
|
14812
|
+
var TRIAL_FULL_DAYS = 11;
|
|
14813
|
+
var TRIAL_GRACE_END_DAYS = 30;
|
|
14814
|
+
function evaluateTrial(activatedAt, now2 = /* @__PURE__ */ new Date()) {
|
|
14815
|
+
const daysSince = Math.floor((now2.getTime() - activatedAt.getTime()) / 864e5);
|
|
14816
|
+
if (daysSince >= TRIAL_GRACE_END_DAYS) {
|
|
14817
|
+
return {
|
|
14818
|
+
phase: "expired",
|
|
14819
|
+
daysSinceActivation: daysSince,
|
|
14820
|
+
daysUntilLockout: 0,
|
|
14821
|
+
shouldNudge: false
|
|
14822
|
+
};
|
|
14823
|
+
}
|
|
14824
|
+
if (daysSince >= TRIAL_FULL_DAYS) {
|
|
14825
|
+
return {
|
|
14826
|
+
phase: "grace",
|
|
14827
|
+
daysSinceActivation: daysSince,
|
|
14828
|
+
daysUntilLockout: TRIAL_GRACE_END_DAYS - daysSince,
|
|
14829
|
+
shouldNudge: true
|
|
14830
|
+
};
|
|
14831
|
+
}
|
|
14832
|
+
return {
|
|
14833
|
+
phase: "active",
|
|
14834
|
+
daysSinceActivation: daysSince,
|
|
14835
|
+
daysUntilLockout: TRIAL_GRACE_END_DAYS - daysSince,
|
|
14836
|
+
shouldNudge: false
|
|
14837
|
+
};
|
|
14838
|
+
}
|
|
14839
|
+
function formatTrialActiveMessage(daysSince) {
|
|
14840
|
+
const daysLeft = TRIAL_FULL_DAYS - daysSince;
|
|
14841
|
+
if (daysLeft <= 0) return "trial license";
|
|
14842
|
+
const dayWord = daysLeft === 1 ? "day" : "days";
|
|
14843
|
+
return `trial license (${daysLeft} ${dayWord} remaining)`;
|
|
14844
|
+
}
|
|
14845
|
+
|
|
14846
|
+
// src/license/upgrade-whimsy.ts
|
|
14847
|
+
var CUTOFF_NUDGES = [
|
|
14848
|
+
"Okay \u2014 that's the line. /upgrade and you're back.",
|
|
14849
|
+
"We're paused until you say yes. /upgrade.",
|
|
14850
|
+
"Didn't want it to end like this. /upgrade if you want in again.",
|
|
14851
|
+
"Time's up. /upgrade \u2014 takes a minute.",
|
|
14852
|
+
"I'll be here. You just need to /upgrade first.",
|
|
14853
|
+
"That's all I can do on the free side. /upgrade.",
|
|
14854
|
+
"Door's closed for now. /upgrade opens it."
|
|
14855
|
+
];
|
|
14856
|
+
function pick(items) {
|
|
14857
|
+
return items[Math.floor(Math.random() * items.length)] ?? items[0];
|
|
14858
|
+
}
|
|
14859
|
+
function randomCutoffNudge() {
|
|
14860
|
+
return pick(CUTOFF_NUDGES);
|
|
14861
|
+
}
|
|
14862
|
+
|
|
14863
|
+
// src/license/normalize.ts
|
|
14864
|
+
var NTRP_PREFIX = /^NTRP-/i;
|
|
14865
|
+
var UUID_KEY = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
14866
|
+
function detectLicenseFormat(key) {
|
|
14867
|
+
if (NTRP_PREFIX.test(key)) return "ntrp";
|
|
14868
|
+
if (UUID_KEY.test(key)) return "lemonsqueezy";
|
|
14869
|
+
return "unknown";
|
|
14870
|
+
}
|
|
14871
|
+
|
|
14872
|
+
// src/license/lemonsqueezy.ts
|
|
14873
|
+
import { hostname } from "os";
|
|
14874
|
+
|
|
14875
|
+
// src/license/verify.ts
|
|
14804
14876
|
var SIGNING_SECRET = "ntrp-gtm-health-2026";
|
|
14805
14877
|
function validateLicenseKey(key) {
|
|
14806
14878
|
const invalid = (msg) => ({
|
|
@@ -14827,16 +14899,73 @@ function validateLicenseKey(key) {
|
|
|
14827
14899
|
const edition = editionCode === "01" ? "pro" : editionCode === "02" ? "team" : "trial";
|
|
14828
14900
|
const expiryTs = parseInt(expiryHex, 16);
|
|
14829
14901
|
const expiresAt = expiryTs > 0 ? new Date(expiryTs * 1e3) : null;
|
|
14830
|
-
if (expiresAt && expiresAt < /* @__PURE__ */ new Date()) {
|
|
14902
|
+
if (expiresAt && expiresAt < /* @__PURE__ */ new Date() && edition !== "trial") {
|
|
14831
14903
|
return invalid(`License expired on ${expiresAt.toISOString().slice(0, 10)}`);
|
|
14832
14904
|
}
|
|
14833
14905
|
return {
|
|
14834
14906
|
valid: true,
|
|
14835
14907
|
edition,
|
|
14836
14908
|
expiresAt,
|
|
14837
|
-
message: `${edition} license${expiresAt ? ` (expires ${expiresAt.toISOString().slice(0, 10)})` : " (perpetual)"}`
|
|
14909
|
+
message: edition === "trial" ? "trial license" : `${edition} license${expiresAt ? ` (expires ${expiresAt.toISOString().slice(0, 10)})` : " (perpetual)"}`
|
|
14910
|
+
};
|
|
14911
|
+
}
|
|
14912
|
+
function trialActivatedAt() {
|
|
14913
|
+
const stored = getConfigValue("license-activated-at");
|
|
14914
|
+
if (stored) {
|
|
14915
|
+
const parsed = new Date(stored);
|
|
14916
|
+
if (!Number.isNaN(parsed.getTime())) return parsed;
|
|
14917
|
+
}
|
|
14918
|
+
const now2 = /* @__PURE__ */ new Date();
|
|
14919
|
+
setConfigValue("license-activated-at", now2.toISOString());
|
|
14920
|
+
return now2;
|
|
14921
|
+
}
|
|
14922
|
+
function applyTrialPolicy(result) {
|
|
14923
|
+
if (result.edition !== "trial") return result;
|
|
14924
|
+
const trial = evaluateTrial(trialActivatedAt());
|
|
14925
|
+
if (trial.phase === "expired") {
|
|
14926
|
+
return {
|
|
14927
|
+
valid: false,
|
|
14928
|
+
edition: "trial",
|
|
14929
|
+
expiresAt: result.expiresAt,
|
|
14930
|
+
message: randomCutoffNudge(),
|
|
14931
|
+
trialPhase: "expired",
|
|
14932
|
+
shouldNudgeUpgrade: false,
|
|
14933
|
+
daysUntilLockout: 0
|
|
14934
|
+
};
|
|
14935
|
+
}
|
|
14936
|
+
const message = trial.phase === "grace" ? `trial license (grace \u2014 ${trial.daysUntilLockout} day${trial.daysUntilLockout === 1 ? "" : "s"} until lockout)` : formatTrialActiveMessage(trial.daysSinceActivation);
|
|
14937
|
+
return {
|
|
14938
|
+
...result,
|
|
14939
|
+
message,
|
|
14940
|
+
trialPhase: trial.phase,
|
|
14941
|
+
shouldNudgeUpgrade: trial.shouldNudge,
|
|
14942
|
+
daysUntilLockout: trial.daysUntilLockout
|
|
14838
14943
|
};
|
|
14839
14944
|
}
|
|
14945
|
+
function storedLicenseProvider(key) {
|
|
14946
|
+
const configured = getConfigValue("license-provider");
|
|
14947
|
+
if (configured === "ntrp" || configured === "lemonsqueezy") return configured;
|
|
14948
|
+
return detectLicenseFormat(key) === "lemonsqueezy" ? "lemonsqueezy" : "ntrp";
|
|
14949
|
+
}
|
|
14950
|
+
function checkLemonSqueezyLicense(key) {
|
|
14951
|
+
const instanceId = getConfigValue("license-instance-id");
|
|
14952
|
+
if (!instanceId) {
|
|
14953
|
+
return {
|
|
14954
|
+
valid: false,
|
|
14955
|
+
edition: "trial",
|
|
14956
|
+
expiresAt: null,
|
|
14957
|
+
message: "License not activated on this machine. Run: ntrp activate <key>"
|
|
14958
|
+
};
|
|
14959
|
+
}
|
|
14960
|
+
const edition = getConfigValue("license-edition") ?? "pro";
|
|
14961
|
+
const base = {
|
|
14962
|
+
valid: true,
|
|
14963
|
+
edition,
|
|
14964
|
+
expiresAt: null,
|
|
14965
|
+
message: `${edition} license`
|
|
14966
|
+
};
|
|
14967
|
+
return applyTrialPolicy(base);
|
|
14968
|
+
}
|
|
14840
14969
|
function checkLicense() {
|
|
14841
14970
|
const key = getConfigValue("license-key");
|
|
14842
14971
|
if (!key) {
|
|
@@ -14847,7 +14976,14 @@ function checkLicense() {
|
|
|
14847
14976
|
message: "No license key found. Run: ntrp activate <key>"
|
|
14848
14977
|
};
|
|
14849
14978
|
}
|
|
14850
|
-
|
|
14979
|
+
if (storedLicenseProvider(key) === "lemonsqueezy") {
|
|
14980
|
+
return checkLemonSqueezyLicense(key);
|
|
14981
|
+
}
|
|
14982
|
+
const result = validateLicenseKey(key);
|
|
14983
|
+
if (!result.valid || result.edition !== "trial") {
|
|
14984
|
+
return result;
|
|
14985
|
+
}
|
|
14986
|
+
return applyTrialPolicy(result);
|
|
14851
14987
|
}
|
|
14852
14988
|
|
|
14853
14989
|
// src/services/setup.ts
|
|
@@ -14887,7 +15023,9 @@ function setupCheck() {
|
|
|
14887
15023
|
},
|
|
14888
15024
|
license: {
|
|
14889
15025
|
valid: license.valid,
|
|
14890
|
-
message: license.message
|
|
15026
|
+
message: license.message,
|
|
15027
|
+
trial_phase: license.trialPhase ?? null,
|
|
15028
|
+
days_until_lockout: license.daysUntilLockout ?? null
|
|
14891
15029
|
}
|
|
14892
15030
|
};
|
|
14893
15031
|
}
|