@keepgoingdev/mcp-server 0.7.0 → 0.7.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1214,7 +1214,14 @@ function getLicenseForFeature(feature) {
1214
1214
  return features?.includes(feature);
1215
1215
  });
1216
1216
  }
1217
+ function getAllLicensesNeedingRevalidation() {
1218
+ return getActiveLicenses().filter((l) => needsRevalidation(l));
1219
+ }
1217
1220
  var REVALIDATION_THRESHOLD_MS = 24 * 60 * 60 * 1e3;
1221
+ function needsRevalidation(entry) {
1222
+ const lastValidated = new Date(entry.lastValidatedAt).getTime();
1223
+ return Date.now() - lastValidated > REVALIDATION_THRESHOLD_MS;
1224
+ }
1218
1225
 
1219
1226
  // ../../packages/shared/src/featureGate.ts
1220
1227
  var DefaultFeatureGate = class {
@@ -2096,6 +2103,39 @@ async function activateLicense(licenseKey, instanceName, options) {
2096
2103
  return { valid: false, error: message };
2097
2104
  }
2098
2105
  }
2106
+ async function validateLicense(licenseKey, instanceId, options) {
2107
+ try {
2108
+ const res = await fetchWithTimeout(`${BASE_URL}/validate`, {
2109
+ method: "POST",
2110
+ headers: { "Content-Type": "application/x-www-form-urlencoded" },
2111
+ body: new URLSearchParams({ license_key: licenseKey, instance_id: instanceId })
2112
+ });
2113
+ const data = await safeJson(res);
2114
+ if (!res.ok || !data?.valid) {
2115
+ return { valid: false, isNetworkError: false, error: data?.error || `Validation failed (${res.status})` };
2116
+ }
2117
+ if (!options?.allowTestMode && data.license_key?.test_mode) {
2118
+ return { valid: false, isNetworkError: false, error: "This is a test license key. Please use a production license key from your purchase confirmation." };
2119
+ }
2120
+ if (!options?.allowTestMode) {
2121
+ const productError = validateProductIdentity(data.meta);
2122
+ if (productError) {
2123
+ return { valid: false, isNetworkError: false, error: productError };
2124
+ }
2125
+ }
2126
+ return {
2127
+ valid: true,
2128
+ licenseKey: data.license_key?.key,
2129
+ customerName: data.meta?.customer_name,
2130
+ productName: data.meta?.product_name,
2131
+ variantId: data.meta?.variant_id,
2132
+ variantName: data.meta?.variant_name
2133
+ };
2134
+ } catch (err) {
2135
+ const message = err instanceof Error && err.name === "AbortError" ? "Request timed out. Please check your network connection and try again." : err instanceof Error ? err.message : "Network error";
2136
+ return { valid: false, isNetworkError: true, error: message };
2137
+ }
2138
+ }
2099
2139
  async function deactivateLicense(licenseKey, instanceId) {
2100
2140
  try {
2101
2141
  const res = await fetchWithTimeout(`${BASE_URL}/deactivate`, {
@@ -2114,6 +2154,52 @@ async function deactivateLicense(licenseKey, instanceId) {
2114
2154
  }
2115
2155
  }
2116
2156
 
2157
+ // ../../packages/shared/src/licenseRevalidation.ts
2158
+ async function revalidateStaleLicenses(options) {
2159
+ const stale = getAllLicensesNeedingRevalidation();
2160
+ const result = { checked: stale.length, refreshed: 0, revoked: 0, skippedNetworkError: 0 };
2161
+ if (stale.length === 0) return result;
2162
+ const updates = /* @__PURE__ */ new Map();
2163
+ for (const entry of stale) {
2164
+ const vResult = await validateLicense(entry.licenseKey, entry.instanceId, {
2165
+ allowTestMode: options?.allowTestMode
2166
+ });
2167
+ if (vResult.valid) {
2168
+ const patch = {
2169
+ lastValidatedAt: (/* @__PURE__ */ new Date()).toISOString()
2170
+ };
2171
+ if (vResult.customerName) patch.customerName = vResult.customerName;
2172
+ updates.set(entry.licenseKey, patch);
2173
+ result.refreshed++;
2174
+ } else if (vResult.isNetworkError) {
2175
+ result.skippedNetworkError++;
2176
+ } else {
2177
+ updates.set(entry.licenseKey, { status: "inactive" });
2178
+ result.revoked++;
2179
+ }
2180
+ }
2181
+ if (updates.size > 0) {
2182
+ const store = readLicenseStore();
2183
+ for (const [key, patch] of updates) {
2184
+ const idx = store.licenses.findIndex((l) => l.licenseKey === key);
2185
+ if (idx >= 0) {
2186
+ Object.assign(store.licenses[idx], patch);
2187
+ }
2188
+ }
2189
+ writeLicenseStore(store);
2190
+ }
2191
+ return result;
2192
+ }
2193
+ async function getLicenseForFeatureWithRevalidation(feature, options) {
2194
+ const license = getLicenseForFeature(feature);
2195
+ if (!license) return void 0;
2196
+ if (needsRevalidation(license)) {
2197
+ await revalidateStaleLicenses(options);
2198
+ return getLicenseForFeature(feature);
2199
+ }
2200
+ return license;
2201
+ }
2202
+
2117
2203
  // src/tools/getMomentum.ts
2118
2204
  import { z } from "zod";
2119
2205
  function registerGetMomentum(server, reader, workspacePath) {
@@ -2450,7 +2536,7 @@ function registerGetDecisions(server, reader) {
2450
2536
  ]
2451
2537
  };
2452
2538
  }
2453
- if (process.env.KEEPGOING_PRO_BYPASS !== "1" && !getLicenseForFeature("decisions")) {
2539
+ if (process.env.KEEPGOING_PRO_BYPASS !== "1" && !await getLicenseForFeatureWithRevalidation("decisions")) {
2454
2540
  return {
2455
2541
  content: [
2456
2542
  {
@@ -2516,7 +2602,7 @@ function registerGetCurrentTask(server, reader) {
2516
2602
  ]
2517
2603
  };
2518
2604
  }
2519
- if (process.env.KEEPGOING_PRO_BYPASS !== "1" && !getLicenseForFeature("session-awareness")) {
2605
+ if (process.env.KEEPGOING_PRO_BYPASS !== "1" && !await getLicenseForFeatureWithRevalidation("session-awareness")) {
2520
2606
  return {
2521
2607
  content: [
2522
2608
  {
@@ -2991,7 +3077,7 @@ async function handlePrintMomentum() {
2991
3077
  process.exit(0);
2992
3078
  }
2993
3079
  async function handlePrintCurrent() {
2994
- if (process.env.KEEPGOING_PRO_BYPASS !== "1" && !getLicenseForFeature("session-awareness")) {
3080
+ if (process.env.KEEPGOING_PRO_BYPASS !== "1" && !await getLicenseForFeatureWithRevalidation("session-awareness")) {
2995
3081
  process.exit(0);
2996
3082
  }
2997
3083
  const wsPath = resolveWsPath();
@@ -3079,7 +3165,7 @@ async function handleSaveCheckpoint() {
3079
3165
  branch: gitBranch ?? void 0,
3080
3166
  updatedAt: checkpoint.timestamp
3081
3167
  });
3082
- if (process.env.KEEPGOING_PRO_BYPASS === "1" || getLicenseForFeature("decisions")) {
3168
+ if (process.env.KEEPGOING_PRO_BYPASS === "1" || await getLicenseForFeatureWithRevalidation("decisions")) {
3083
3169
  for (let i = 0; i < commitHashes.length; i++) {
3084
3170
  const hash = commitHashes[i];
3085
3171
  const message = commitMessages[i];
@@ -3379,7 +3465,7 @@ async function handleContinueOn() {
3379
3465
  // src/cli/detectDecisions.ts
3380
3466
  async function handleDetectDecisions() {
3381
3467
  const wsPath = resolveWsPath();
3382
- if (!(process.env.KEEPGOING_PRO_BYPASS === "1" || getLicenseForFeature("decisions"))) {
3468
+ if (!(process.env.KEEPGOING_PRO_BYPASS === "1" || await getLicenseForFeatureWithRevalidation("decisions"))) {
3383
3469
  process.exit(0);
3384
3470
  }
3385
3471
  const reader = new KeepGoingReader(wsPath);