@sonnechasser/ntrp 0.1.2 → 0.1.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +33 -8
- package/dist/index.js +1113 -372
- 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 +152 -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,77 @@ 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
|
+
var TRIAL_ACTIVE_NUDGE_FROM_DAY = 8;
|
|
14815
|
+
function evaluateTrial(activatedAt, now2 = /* @__PURE__ */ new Date()) {
|
|
14816
|
+
const daysSince = Math.floor((now2.getTime() - activatedAt.getTime()) / 864e5);
|
|
14817
|
+
if (daysSince >= TRIAL_GRACE_END_DAYS) {
|
|
14818
|
+
return {
|
|
14819
|
+
phase: "expired",
|
|
14820
|
+
daysSinceActivation: daysSince,
|
|
14821
|
+
daysUntilLockout: 0,
|
|
14822
|
+
trialDaysRemaining: 0,
|
|
14823
|
+
shouldNudge: false
|
|
14824
|
+
};
|
|
14825
|
+
}
|
|
14826
|
+
if (daysSince >= TRIAL_FULL_DAYS) {
|
|
14827
|
+
return {
|
|
14828
|
+
phase: "grace",
|
|
14829
|
+
daysSinceActivation: daysSince,
|
|
14830
|
+
daysUntilLockout: TRIAL_GRACE_END_DAYS - daysSince,
|
|
14831
|
+
trialDaysRemaining: 0,
|
|
14832
|
+
shouldNudge: true
|
|
14833
|
+
};
|
|
14834
|
+
}
|
|
14835
|
+
const trialDaysRemaining = TRIAL_FULL_DAYS - daysSince;
|
|
14836
|
+
return {
|
|
14837
|
+
phase: "active",
|
|
14838
|
+
daysSinceActivation: daysSince,
|
|
14839
|
+
daysUntilLockout: TRIAL_GRACE_END_DAYS - daysSince,
|
|
14840
|
+
trialDaysRemaining,
|
|
14841
|
+
shouldNudge: daysSince >= TRIAL_ACTIVE_NUDGE_FROM_DAY
|
|
14842
|
+
};
|
|
14843
|
+
}
|
|
14844
|
+
function formatTrialActiveMessage(daysSince) {
|
|
14845
|
+
const daysLeft = TRIAL_FULL_DAYS - daysSince;
|
|
14846
|
+
if (daysLeft <= 0) return "trial license";
|
|
14847
|
+
const dayWord = daysLeft === 1 ? "day" : "days";
|
|
14848
|
+
return `trial license (${daysLeft} ${dayWord} remaining)`;
|
|
14849
|
+
}
|
|
14850
|
+
|
|
14851
|
+
// src/license/upgrade-whimsy.ts
|
|
14852
|
+
var CUTOFF_NUDGES = [
|
|
14853
|
+
"Okay \u2014 that's the line. /upgrade and you're back.",
|
|
14854
|
+
"We're paused until you say yes. /upgrade.",
|
|
14855
|
+
"Didn't want it to end like this. /upgrade if you want in again.",
|
|
14856
|
+
"Time's up. /upgrade \u2014 takes a minute.",
|
|
14857
|
+
"I'll be here. You just need to /upgrade first.",
|
|
14858
|
+
"That's all I can do on the free side. /upgrade.",
|
|
14859
|
+
"Door's closed for now. /upgrade opens it."
|
|
14860
|
+
];
|
|
14861
|
+
function pick(items) {
|
|
14862
|
+
return items[Math.floor(Math.random() * items.length)] ?? items[0];
|
|
14863
|
+
}
|
|
14864
|
+
function randomCutoffNudge() {
|
|
14865
|
+
return pick(CUTOFF_NUDGES);
|
|
14866
|
+
}
|
|
14867
|
+
|
|
14868
|
+
// src/license/normalize.ts
|
|
14869
|
+
var NTRP_PREFIX = /^NTRP-/i;
|
|
14870
|
+
var UUID_KEY = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
14871
|
+
function detectLicenseFormat(key) {
|
|
14872
|
+
if (NTRP_PREFIX.test(key)) return "ntrp";
|
|
14873
|
+
if (UUID_KEY.test(key)) return "lemonsqueezy";
|
|
14874
|
+
return "unknown";
|
|
14875
|
+
}
|
|
14876
|
+
|
|
14877
|
+
// src/license/lemonsqueezy.ts
|
|
14878
|
+
import { hostname } from "os";
|
|
14879
|
+
|
|
14880
|
+
// src/license/verify.ts
|
|
14804
14881
|
var SIGNING_SECRET = "ntrp-gtm-health-2026";
|
|
14805
14882
|
function validateLicenseKey(key) {
|
|
14806
14883
|
const invalid = (msg) => ({
|
|
@@ -14827,16 +14904,75 @@ function validateLicenseKey(key) {
|
|
|
14827
14904
|
const edition = editionCode === "01" ? "pro" : editionCode === "02" ? "team" : "trial";
|
|
14828
14905
|
const expiryTs = parseInt(expiryHex, 16);
|
|
14829
14906
|
const expiresAt = expiryTs > 0 ? new Date(expiryTs * 1e3) : null;
|
|
14830
|
-
if (expiresAt && expiresAt < /* @__PURE__ */ new Date()) {
|
|
14907
|
+
if (expiresAt && expiresAt < /* @__PURE__ */ new Date() && edition !== "trial") {
|
|
14831
14908
|
return invalid(`License expired on ${expiresAt.toISOString().slice(0, 10)}`);
|
|
14832
14909
|
}
|
|
14833
14910
|
return {
|
|
14834
14911
|
valid: true,
|
|
14835
14912
|
edition,
|
|
14836
14913
|
expiresAt,
|
|
14837
|
-
message: `${edition} license${expiresAt ? ` (expires ${expiresAt.toISOString().slice(0, 10)})` : " (perpetual)"}`
|
|
14914
|
+
message: edition === "trial" ? "trial license" : `${edition} license${expiresAt ? ` (expires ${expiresAt.toISOString().slice(0, 10)})` : " (perpetual)"}`
|
|
14915
|
+
};
|
|
14916
|
+
}
|
|
14917
|
+
function trialActivatedAt() {
|
|
14918
|
+
const stored = getConfigValue("license-activated-at");
|
|
14919
|
+
if (stored) {
|
|
14920
|
+
const parsed = new Date(stored);
|
|
14921
|
+
if (!Number.isNaN(parsed.getTime())) return parsed;
|
|
14922
|
+
}
|
|
14923
|
+
const now2 = /* @__PURE__ */ new Date();
|
|
14924
|
+
setConfigValue("license-activated-at", now2.toISOString());
|
|
14925
|
+
return now2;
|
|
14926
|
+
}
|
|
14927
|
+
function applyTrialPolicy(result) {
|
|
14928
|
+
if (result.edition !== "trial") return result;
|
|
14929
|
+
const trial = evaluateTrial(trialActivatedAt());
|
|
14930
|
+
if (trial.phase === "expired") {
|
|
14931
|
+
return {
|
|
14932
|
+
valid: false,
|
|
14933
|
+
edition: "trial",
|
|
14934
|
+
expiresAt: result.expiresAt,
|
|
14935
|
+
message: randomCutoffNudge(),
|
|
14936
|
+
trialPhase: "expired",
|
|
14937
|
+
shouldNudgeUpgrade: false,
|
|
14938
|
+
daysUntilLockout: 0,
|
|
14939
|
+
trialDaysRemaining: 0
|
|
14940
|
+
};
|
|
14941
|
+
}
|
|
14942
|
+
const message = trial.phase === "grace" ? `trial license (grace \u2014 ${trial.daysUntilLockout} day${trial.daysUntilLockout === 1 ? "" : "s"} until lockout)` : formatTrialActiveMessage(trial.daysSinceActivation);
|
|
14943
|
+
return {
|
|
14944
|
+
...result,
|
|
14945
|
+
message,
|
|
14946
|
+
trialPhase: trial.phase,
|
|
14947
|
+
shouldNudgeUpgrade: trial.shouldNudge,
|
|
14948
|
+
daysUntilLockout: trial.daysUntilLockout,
|
|
14949
|
+
trialDaysRemaining: trial.trialDaysRemaining
|
|
14838
14950
|
};
|
|
14839
14951
|
}
|
|
14952
|
+
function storedLicenseProvider(key) {
|
|
14953
|
+
const configured = getConfigValue("license-provider");
|
|
14954
|
+
if (configured === "ntrp" || configured === "lemonsqueezy") return configured;
|
|
14955
|
+
return detectLicenseFormat(key) === "lemonsqueezy" ? "lemonsqueezy" : "ntrp";
|
|
14956
|
+
}
|
|
14957
|
+
function checkLemonSqueezyLicense(key) {
|
|
14958
|
+
const instanceId = getConfigValue("license-instance-id");
|
|
14959
|
+
if (!instanceId) {
|
|
14960
|
+
return {
|
|
14961
|
+
valid: false,
|
|
14962
|
+
edition: "trial",
|
|
14963
|
+
expiresAt: null,
|
|
14964
|
+
message: "License not activated on this machine. Run: ntrp activate <key>"
|
|
14965
|
+
};
|
|
14966
|
+
}
|
|
14967
|
+
const edition = getConfigValue("license-edition") ?? "pro";
|
|
14968
|
+
const base = {
|
|
14969
|
+
valid: true,
|
|
14970
|
+
edition,
|
|
14971
|
+
expiresAt: null,
|
|
14972
|
+
message: `${edition} license`
|
|
14973
|
+
};
|
|
14974
|
+
return applyTrialPolicy(base);
|
|
14975
|
+
}
|
|
14840
14976
|
function checkLicense() {
|
|
14841
14977
|
const key = getConfigValue("license-key");
|
|
14842
14978
|
if (!key) {
|
|
@@ -14847,7 +14983,14 @@ function checkLicense() {
|
|
|
14847
14983
|
message: "No license key found. Run: ntrp activate <key>"
|
|
14848
14984
|
};
|
|
14849
14985
|
}
|
|
14850
|
-
|
|
14986
|
+
if (storedLicenseProvider(key) === "lemonsqueezy") {
|
|
14987
|
+
return checkLemonSqueezyLicense(key);
|
|
14988
|
+
}
|
|
14989
|
+
const result = validateLicenseKey(key);
|
|
14990
|
+
if (!result.valid || result.edition !== "trial") {
|
|
14991
|
+
return result;
|
|
14992
|
+
}
|
|
14993
|
+
return applyTrialPolicy(result);
|
|
14851
14994
|
}
|
|
14852
14995
|
|
|
14853
14996
|
// src/services/setup.ts
|
|
@@ -14887,7 +15030,9 @@ function setupCheck() {
|
|
|
14887
15030
|
},
|
|
14888
15031
|
license: {
|
|
14889
15032
|
valid: license.valid,
|
|
14890
|
-
message: license.message
|
|
15033
|
+
message: license.message,
|
|
15034
|
+
trial_phase: license.trialPhase ?? null,
|
|
15035
|
+
days_until_lockout: license.daysUntilLockout ?? null
|
|
14891
15036
|
}
|
|
14892
15037
|
};
|
|
14893
15038
|
}
|