@rubytech/taskmaster 1.44.4 → 1.44.5

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.
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "1.44.4",
3
- "commit": "b8d7b214abfbb7854ac8d717f1d474cda32f8bf2",
4
- "builtAt": "2026-03-22T15:16:51.871Z"
2
+ "version": "1.44.5",
3
+ "commit": "414cf5a6f0475e90da9e44c9a38af23eb2662ffa",
4
+ "builtAt": "2026-03-25T13:57:46.756Z"
5
5
  }
@@ -68,9 +68,10 @@ import { loadGatewayTlsRuntime } from "./server/tls.js";
68
68
  import { isLoopbackHost } from "./net.js";
69
69
  import { createWizardSessionTracker } from "./server-wizard-sessions.js";
70
70
  import { attachGatewayWsHandlers } from "./server-ws-runtime.js";
71
- import { isLicenseValid } from "../license/validate.js";
71
+ import { isLicenseValid, validateLicenseKey } from "../license/validate.js";
72
72
  import { setLicensed } from "../license/state.js";
73
73
  import { startLicenseRevalidation, stopLicenseRevalidation } from "../license/revalidation.js";
74
+ import { getDeviceId } from "../license/device-id.js";
74
75
  export { __resetModelCatalogCacheForTest } from "./server-model-catalog.js";
75
76
  ensureTaskmasterCliOnPath();
76
77
  const log = createSubsystemLogger("gateway");
@@ -331,7 +332,29 @@ export async function startGatewayServer(port = 18789, opts = {}) {
331
332
  // License check — gateway always starts (so setup UI is reachable),
332
333
  // but pages other than /setup will redirect until a license is activated.
333
334
  const logLicense = log.child("license");
334
- const licenseOk = isLicenseValid(cfgAtStart);
335
+ let licenseOk = isLicenseValid(cfgAtStart);
336
+ // If stored state is stale but the token is cryptographically valid,
337
+ // refresh validatedAt so the license doesn't appear expired on restart.
338
+ if (!licenseOk && cfgAtStart.license?.key) {
339
+ const deviceId = getDeviceId();
340
+ const freshCheck = validateLicenseKey(cfgAtStart.license.key, deviceId);
341
+ if (freshCheck.valid) {
342
+ logLicense.info("refreshing stale validatedAt — token is still valid");
343
+ try {
344
+ const freshCfg = loadConfig();
345
+ if (freshCfg.license) {
346
+ void writeConfigFile({
347
+ ...freshCfg,
348
+ license: { ...freshCfg.license, validatedAt: new Date().toISOString() },
349
+ });
350
+ }
351
+ }
352
+ catch (err) {
353
+ logLicense.warn(`failed to refresh validatedAt: ${String(err)}`);
354
+ }
355
+ licenseOk = true;
356
+ }
357
+ }
335
358
  setLicensed(licenseOk);
336
359
  if (!licenseOk) {
337
360
  logLicense.warn("no valid license — setup wizard will require activation");
@@ -15,6 +15,22 @@ function revalidate(log, onChange) {
15
15
  const result = validateLicenseKey(lic.key, deviceId);
16
16
  if (result.valid) {
17
17
  log.info("license still valid");
18
+ // Refresh validatedAt so the 30-day staleness window doesn't expire
19
+ try {
20
+ const freshConfig = loadConfig();
21
+ if (freshConfig.license) {
22
+ void writeConfigFile({
23
+ ...freshConfig,
24
+ license: {
25
+ ...freshConfig.license,
26
+ validatedAt: new Date().toISOString(),
27
+ },
28
+ });
29
+ }
30
+ }
31
+ catch (err) {
32
+ log.warn(`failed to refresh validatedAt: ${String(err)}`);
33
+ }
18
34
  return;
19
35
  }
20
36
  // Token is no longer valid (expired, wrong device, bad signature)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rubytech/taskmaster",
3
- "version": "1.44.4",
3
+ "version": "1.44.5",
4
4
  "description": "AI-powered business assistant for small businesses",
5
5
  "publishConfig": {
6
6
  "access": "public"