@tempad-dev/mcp 0.3.8 → 0.3.10

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/hub.mjs CHANGED
@@ -1,4 +1,4 @@
1
- import { a as SOCK_PATH, c as log, i as RUNTIME_DIR, o as ensureDir, r as PACKAGE_VERSION, s as ensureFile, t as ASSET_DIR } from "./shared-DlR95qf4.mjs";
1
+ import { a as SOCK_PATH, c as log, i as RUNTIME_DIR, o as ensureDir, r as PACKAGE_VERSION, s as ensureFile, t as ASSET_DIR } from "./shared-eU-gSEEq.mjs";
2
2
  import { createServer } from "node:net";
3
3
  import { join } from "node:path";
4
4
  import { URL as URL$1 } from "node:url";
@@ -11,31 +11,37 @@ import { createHash } from "node:crypto";
11
11
  import { createServer as createServer$1 } from "node:http";
12
12
  import { Transform, pipeline } from "node:stream";
13
13
 
14
- //#region ../../node_modules/.pnpm/zod@4.1.12/node_modules/zod/v4/core/core.js
14
+ //#region ../../node_modules/.pnpm/zod@4.1.13/node_modules/zod/v4/core/core.js
15
15
  /** A special constant with type `never` */
16
16
  const NEVER = Object.freeze({ status: "aborted" });
17
17
  function $constructor(name, initializer$2, params) {
18
18
  function init(inst, def) {
19
- var _a;
20
- Object.defineProperty(inst, "_zod", {
21
- value: inst._zod ?? {},
19
+ if (!inst._zod) Object.defineProperty(inst, "_zod", {
20
+ value: {
21
+ def,
22
+ constr: _,
23
+ traits: /* @__PURE__ */ new Set()
24
+ },
22
25
  enumerable: false
23
26
  });
24
- (_a = inst._zod).traits ?? (_a.traits = /* @__PURE__ */ new Set());
27
+ if (inst._zod.traits.has(name)) return;
25
28
  inst._zod.traits.add(name);
26
29
  initializer$2(inst, def);
27
- for (const k in _.prototype) if (!(k in inst)) Object.defineProperty(inst, k, { value: _.prototype[k].bind(inst) });
28
- inst._zod.constr = _;
29
- inst._zod.def = def;
30
+ const proto = _.prototype;
31
+ const keys = Object.keys(proto);
32
+ for (let i = 0; i < keys.length; i++) {
33
+ const k = keys[i];
34
+ if (!(k in inst)) inst[k] = proto[k].bind(inst);
35
+ }
30
36
  }
31
37
  const Parent = params?.Parent ?? Object;
32
38
  class Definition extends Parent {}
33
39
  Object.defineProperty(Definition, "name", { value: name });
34
40
  function _(def) {
35
- var _a;
41
+ var _a$1;
36
42
  const inst = params?.Parent ? new Definition() : this;
37
43
  init(inst, def);
38
- (_a = inst._zod).deferred ?? (_a.deferred = []);
44
+ (_a$1 = inst._zod).deferred ?? (_a$1.deferred = []);
39
45
  for (const fn of inst._zod.deferred) fn();
40
46
  return inst;
41
47
  }
@@ -65,7 +71,7 @@ function config(newConfig) {
65
71
  }
66
72
 
67
73
  //#endregion
68
- //#region ../../node_modules/.pnpm/zod@4.1.12/node_modules/zod/v4/core/util.js
74
+ //#region ../../node_modules/.pnpm/zod@4.1.13/node_modules/zod/v4/core/util.js
69
75
  function getEnumValues(entries) {
70
76
  const numericValues = Object.values(entries).filter((v) => typeof v === "number");
71
77
  return Object.entries(entries).filter(([k, _]) => numericValues.indexOf(+k) === -1).map(([_, v]) => v);
@@ -140,6 +146,9 @@ function mergeDefs(...defs) {
140
146
  function esc(str) {
141
147
  return JSON.stringify(str);
142
148
  }
149
+ function slugify(input) {
150
+ return input.toLowerCase().trim().replace(/[^\w\s-]/g, "").replace(/[\s_-]+/g, "-").replace(/^-+|-+$/g, "");
151
+ }
143
152
  const captureStackTrace = "captureStackTrace" in Error ? Error.captureStackTrace : (..._args) => {};
144
153
  function isObject(data) {
145
154
  return typeof data === "object" && data !== null && !Array.isArray(data);
@@ -157,6 +166,7 @@ function isPlainObject(o) {
157
166
  if (isObject(o) === false) return false;
158
167
  const ctor = o.constructor;
159
168
  if (ctor === void 0) return true;
169
+ if (typeof ctor !== "function") return true;
160
170
  const prot = ctor.prototype;
161
171
  if (isObject(prot) === false) return false;
162
172
  if (Object.prototype.hasOwnProperty.call(prot, "isPrototypeOf") === false) return false;
@@ -339,8 +349,8 @@ function aborted(x, startIndex = 0) {
339
349
  }
340
350
  function prefixIssues(path, issues) {
341
351
  return issues.map((iss) => {
342
- var _a;
343
- (_a = iss).path ?? (_a.path = []);
352
+ var _a$1;
353
+ (_a$1 = iss).path ?? (_a$1.path = []);
344
354
  iss.path.unshift(path);
345
355
  return iss;
346
356
  });
@@ -376,7 +386,7 @@ function issue(...args) {
376
386
  }
377
387
 
378
388
  //#endregion
379
- //#region ../../node_modules/.pnpm/zod@4.1.12/node_modules/zod/v4/core/errors.js
389
+ //#region ../../node_modules/.pnpm/zod@4.1.13/node_modules/zod/v4/core/errors.js
380
390
  const initializer$1 = (inst, def) => {
381
391
  inst.name = "$ZodError";
382
392
  Object.defineProperty(inst, "_zod", {
@@ -434,7 +444,7 @@ function formatError(error, mapper = (issue$1) => issue$1.message) {
434
444
  }
435
445
 
436
446
  //#endregion
437
- //#region ../../node_modules/.pnpm/zod@4.1.12/node_modules/zod/v4/core/parse.js
447
+ //#region ../../node_modules/.pnpm/zod@4.1.13/node_modules/zod/v4/core/parse.js
438
448
  const _parse = (_Err) => (schema, value, _ctx, _params) => {
439
449
  const ctx = _ctx ? Object.assign(_ctx, { async: false }) : { async: false };
440
450
  const result = schema._zod.run({
@@ -538,7 +548,7 @@ const _safeDecodeAsync = (_Err) => async (schema, value, _ctx) => {
538
548
  const safeDecodeAsync$1 = /* @__PURE__ */ _safeDecodeAsync($ZodRealError);
539
549
 
540
550
  //#endregion
541
- //#region ../../node_modules/.pnpm/zod@4.1.12/node_modules/zod/v4/core/regexes.js
551
+ //#region ../../node_modules/.pnpm/zod@4.1.13/node_modules/zod/v4/core/regexes.js
542
552
  const cuid = /^[cC][^\s-]{8,}$/;
543
553
  const cuid2 = /^[0-9a-z]+$/;
544
554
  const ulid = /^[0-9A-HJKMNP-TV-Za-hjkmnp-tv-z]{26}$/;
@@ -568,7 +578,6 @@ const cidrv4 = /^((25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\.){3}(25[0-
568
578
  const cidrv6 = /^(([0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}|::|([0-9a-fA-F]{1,4})?::([0-9a-fA-F]{1,4}:?){0,6})\/(12[0-8]|1[01][0-9]|[1-9]?[0-9])$/;
569
579
  const base64 = /^$|^(?:[0-9a-zA-Z+/]{4})*(?:(?:[0-9a-zA-Z+/]{2}==)|(?:[0-9a-zA-Z+/]{3}=))?$/;
570
580
  const base64url = /^[A-Za-z0-9_-]*$/;
571
- const hostname = /^(?=.{1,253}\.?$)[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[-0-9a-zA-Z]{0,61}[0-9a-zA-Z])?)*\.?$/;
572
581
  const e164 = /^\+(?:[0-9]){6,14}[0-9]$/;
573
582
  const dateSource = `(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))`;
574
583
  const date$1 = /* @__PURE__ */ new RegExp(`^${dateSource}$`);
@@ -598,12 +607,12 @@ const lowercase = /^[^A-Z]*$/;
598
607
  const uppercase = /^[^a-z]*$/;
599
608
 
600
609
  //#endregion
601
- //#region ../../node_modules/.pnpm/zod@4.1.12/node_modules/zod/v4/core/checks.js
610
+ //#region ../../node_modules/.pnpm/zod@4.1.13/node_modules/zod/v4/core/checks.js
602
611
  const $ZodCheck = /* @__PURE__ */ $constructor("$ZodCheck", (inst, def) => {
603
- var _a;
612
+ var _a$1;
604
613
  inst._zod ?? (inst._zod = {});
605
614
  inst._zod.def = def;
606
- (_a = inst._zod).onattach ?? (_a.onattach = []);
615
+ (_a$1 = inst._zod).onattach ?? (_a$1.onattach = []);
607
616
  });
608
617
  const numericOriginMap = {
609
618
  number: "number",
@@ -657,8 +666,8 @@ const $ZodCheckGreaterThan = /* @__PURE__ */ $constructor("$ZodCheckGreaterThan"
657
666
  const $ZodCheckMultipleOf = /* @__PURE__ */ $constructor("$ZodCheckMultipleOf", (inst, def) => {
658
667
  $ZodCheck.init(inst, def);
659
668
  inst._zod.onattach.push((inst$1) => {
660
- var _a;
661
- (_a = inst$1._zod.bag).multipleOf ?? (_a.multipleOf = def.value);
669
+ var _a$1;
670
+ (_a$1 = inst$1._zod.bag).multipleOf ?? (_a$1.multipleOf = def.value);
662
671
  });
663
672
  inst._zod.check = (payload) => {
664
673
  if (typeof payload.value !== typeof def.value) throw new Error("Cannot mix number and bigint in multiple_of check.");
@@ -741,9 +750,9 @@ const $ZodCheckNumberFormat = /* @__PURE__ */ $constructor("$ZodCheckNumberForma
741
750
  };
742
751
  });
743
752
  const $ZodCheckMaxLength = /* @__PURE__ */ $constructor("$ZodCheckMaxLength", (inst, def) => {
744
- var _a;
753
+ var _a$1;
745
754
  $ZodCheck.init(inst, def);
746
- (_a = inst._zod.def).when ?? (_a.when = (payload) => {
755
+ (_a$1 = inst._zod.def).when ?? (_a$1.when = (payload) => {
747
756
  const val = payload.value;
748
757
  return !nullish(val) && val.length !== void 0;
749
758
  });
@@ -767,9 +776,9 @@ const $ZodCheckMaxLength = /* @__PURE__ */ $constructor("$ZodCheckMaxLength", (i
767
776
  };
768
777
  });
769
778
  const $ZodCheckMinLength = /* @__PURE__ */ $constructor("$ZodCheckMinLength", (inst, def) => {
770
- var _a;
779
+ var _a$1;
771
780
  $ZodCheck.init(inst, def);
772
- (_a = inst._zod.def).when ?? (_a.when = (payload) => {
781
+ (_a$1 = inst._zod.def).when ?? (_a$1.when = (payload) => {
773
782
  const val = payload.value;
774
783
  return !nullish(val) && val.length !== void 0;
775
784
  });
@@ -793,9 +802,9 @@ const $ZodCheckMinLength = /* @__PURE__ */ $constructor("$ZodCheckMinLength", (i
793
802
  };
794
803
  });
795
804
  const $ZodCheckLengthEquals = /* @__PURE__ */ $constructor("$ZodCheckLengthEquals", (inst, def) => {
796
- var _a;
805
+ var _a$1;
797
806
  $ZodCheck.init(inst, def);
798
- (_a = inst._zod.def).when ?? (_a.when = (payload) => {
807
+ (_a$1 = inst._zod.def).when ?? (_a$1.when = (payload) => {
799
808
  const val = payload.value;
800
809
  return !nullish(val) && val.length !== void 0;
801
810
  });
@@ -829,7 +838,7 @@ const $ZodCheckLengthEquals = /* @__PURE__ */ $constructor("$ZodCheckLengthEqual
829
838
  };
830
839
  });
831
840
  const $ZodCheckStringFormat = /* @__PURE__ */ $constructor("$ZodCheckStringFormat", (inst, def) => {
832
- var _a, _b;
841
+ var _a$1, _b;
833
842
  $ZodCheck.init(inst, def);
834
843
  inst._zod.onattach.push((inst$1) => {
835
844
  const bag = inst$1._zod.bag;
@@ -839,7 +848,7 @@ const $ZodCheckStringFormat = /* @__PURE__ */ $constructor("$ZodCheckStringForma
839
848
  bag.patterns.add(def.pattern);
840
849
  }
841
850
  });
842
- if (def.pattern) (_a = inst._zod).check ?? (_a.check = (payload) => {
851
+ if (def.pattern) (_a$1 = inst._zod).check ?? (_a$1.check = (payload) => {
843
852
  def.pattern.lastIndex = 0;
844
853
  if (def.pattern.test(payload.value)) return;
845
854
  payload.issues.push({
@@ -953,7 +962,7 @@ const $ZodCheckOverwrite = /* @__PURE__ */ $constructor("$ZodCheckOverwrite", (i
953
962
  });
954
963
 
955
964
  //#endregion
956
- //#region ../../node_modules/.pnpm/zod@4.1.12/node_modules/zod/v4/core/doc.js
965
+ //#region ../../node_modules/.pnpm/zod@4.1.13/node_modules/zod/v4/core/doc.js
957
966
  var Doc = class {
958
967
  constructor(args = []) {
959
968
  this.content = [];
@@ -985,17 +994,17 @@ var Doc = class {
985
994
  };
986
995
 
987
996
  //#endregion
988
- //#region ../../node_modules/.pnpm/zod@4.1.12/node_modules/zod/v4/core/versions.js
997
+ //#region ../../node_modules/.pnpm/zod@4.1.13/node_modules/zod/v4/core/versions.js
989
998
  const version = {
990
999
  major: 4,
991
1000
  minor: 1,
992
- patch: 12
1001
+ patch: 13
993
1002
  };
994
1003
 
995
1004
  //#endregion
996
- //#region ../../node_modules/.pnpm/zod@4.1.12/node_modules/zod/v4/core/schemas.js
1005
+ //#region ../../node_modules/.pnpm/zod@4.1.13/node_modules/zod/v4/core/schemas.js
997
1006
  const $ZodType = /* @__PURE__ */ $constructor("$ZodType", (inst, def) => {
998
- var _a;
1007
+ var _a$1;
999
1008
  inst ?? (inst = {});
1000
1009
  inst._zod.def = def;
1001
1010
  inst._zod.bag = inst._zod.bag || {};
@@ -1004,7 +1013,7 @@ const $ZodType = /* @__PURE__ */ $constructor("$ZodType", (inst, def) => {
1004
1013
  if (inst._zod.traits.has("$ZodCheck")) checks.unshift(inst);
1005
1014
  for (const ch of checks) for (const fn of ch._zod.onattach) fn(inst);
1006
1015
  if (checks.length === 0) {
1007
- (_a = inst._zod).deferred ?? (_a.deferred = []);
1016
+ (_a$1 = inst._zod).deferred ?? (_a$1.deferred = []);
1008
1017
  inst._zod.deferred?.push(() => {
1009
1018
  inst._zod.run = inst._zod.parse;
1010
1019
  });
@@ -1140,7 +1149,7 @@ const $ZodURL = /* @__PURE__ */ $constructor("$ZodURL", (inst, def) => {
1140
1149
  code: "invalid_format",
1141
1150
  format: "url",
1142
1151
  note: "Invalid hostname",
1143
- pattern: hostname.source,
1152
+ pattern: def.hostname.source,
1144
1153
  input: payload.value,
1145
1154
  inst,
1146
1155
  continue: !def.abort
@@ -1219,18 +1228,12 @@ const $ZodISODuration = /* @__PURE__ */ $constructor("$ZodISODuration", (inst, d
1219
1228
  const $ZodIPv4 = /* @__PURE__ */ $constructor("$ZodIPv4", (inst, def) => {
1220
1229
  def.pattern ?? (def.pattern = ipv4);
1221
1230
  $ZodStringFormat.init(inst, def);
1222
- inst._zod.onattach.push((inst$1) => {
1223
- const bag = inst$1._zod.bag;
1224
- bag.format = `ipv4`;
1225
- });
1231
+ inst._zod.bag.format = `ipv4`;
1226
1232
  });
1227
1233
  const $ZodIPv6 = /* @__PURE__ */ $constructor("$ZodIPv6", (inst, def) => {
1228
1234
  def.pattern ?? (def.pattern = ipv6);
1229
1235
  $ZodStringFormat.init(inst, def);
1230
- inst._zod.onattach.push((inst$1) => {
1231
- const bag = inst$1._zod.bag;
1232
- bag.format = `ipv6`;
1233
- });
1236
+ inst._zod.bag.format = `ipv6`;
1234
1237
  inst._zod.check = (payload) => {
1235
1238
  try {
1236
1239
  new URL(`http://[${payload.value}]`);
@@ -1286,9 +1289,7 @@ function isValidBase64(data) {
1286
1289
  const $ZodBase64 = /* @__PURE__ */ $constructor("$ZodBase64", (inst, def) => {
1287
1290
  def.pattern ?? (def.pattern = base64);
1288
1291
  $ZodStringFormat.init(inst, def);
1289
- inst._zod.onattach.push((inst$1) => {
1290
- inst$1._zod.bag.contentEncoding = "base64";
1291
- });
1292
+ inst._zod.bag.contentEncoding = "base64";
1292
1293
  inst._zod.check = (payload) => {
1293
1294
  if (isValidBase64(payload.value)) return;
1294
1295
  payload.issues.push({
@@ -1308,9 +1309,7 @@ function isValidBase64URL(data) {
1308
1309
  const $ZodBase64URL = /* @__PURE__ */ $constructor("$ZodBase64URL", (inst, def) => {
1309
1310
  def.pattern ?? (def.pattern = base64url);
1310
1311
  $ZodStringFormat.init(inst, def);
1311
- inst._zod.onattach.push((inst$1) => {
1312
- inst$1._zod.bag.contentEncoding = "base64url";
1313
- });
1312
+ inst._zod.bag.contentEncoding = "base64url";
1314
1313
  inst._zod.check = (payload) => {
1315
1314
  if (isValidBase64URL(payload.value)) return;
1316
1315
  payload.issues.push({
@@ -1374,7 +1373,7 @@ const $ZodNumber = /* @__PURE__ */ $constructor("$ZodNumber", (inst, def) => {
1374
1373
  return payload;
1375
1374
  };
1376
1375
  });
1377
- const $ZodNumberFormat = /* @__PURE__ */ $constructor("$ZodNumber", (inst, def) => {
1376
+ const $ZodNumberFormat = /* @__PURE__ */ $constructor("$ZodNumberFormat", (inst, def) => {
1378
1377
  $ZodCheckNumberFormat.init(inst, def);
1379
1378
  $ZodNumber.init(inst, def);
1380
1379
  });
@@ -1467,7 +1466,7 @@ function handleCatchall(proms, input, payload, ctx, def, inst) {
1467
1466
  const keySet = def.keySet;
1468
1467
  const _catchall = def.catchall._zod;
1469
1468
  const t = _catchall.def.type;
1470
- for (const key of Object.keys(input)) {
1469
+ for (const key in input) {
1471
1470
  if (keySet.has(key)) continue;
1472
1471
  if (t === "never") {
1473
1472
  unrecognized.push(key);
@@ -1833,11 +1832,12 @@ const $ZodEnum = /* @__PURE__ */ $constructor("$ZodEnum", (inst, def) => {
1833
1832
  const $ZodLiteral = /* @__PURE__ */ $constructor("$ZodLiteral", (inst, def) => {
1834
1833
  $ZodType.init(inst, def);
1835
1834
  if (def.values.length === 0) throw new Error("Cannot create literal schema with no valid values");
1836
- inst._zod.values = new Set(def.values);
1835
+ const values = new Set(def.values);
1836
+ inst._zod.values = values;
1837
1837
  inst._zod.pattern = /* @__PURE__ */ new RegExp(`^(${def.values.map((o) => typeof o === "string" ? escapeRegex(o) : o ? escapeRegex(o.toString()) : String(o)).join("|")})$`);
1838
1838
  inst._zod.parse = (payload, _ctx) => {
1839
1839
  const input = payload.value;
1840
- if (inst._zod.values.has(input)) return payload;
1840
+ if (values.has(input)) return payload;
1841
1841
  payload.issues.push({
1842
1842
  code: "invalid_value",
1843
1843
  values: def.values,
@@ -2021,8 +2021,8 @@ const $ZodReadonly = /* @__PURE__ */ $constructor("$ZodReadonly", (inst, def) =>
2021
2021
  $ZodType.init(inst, def);
2022
2022
  defineLazy(inst._zod, "propValues", () => def.innerType._zod.propValues);
2023
2023
  defineLazy(inst._zod, "values", () => def.innerType._zod.values);
2024
- defineLazy(inst._zod, "optin", () => def.innerType._zod.optin);
2025
- defineLazy(inst._zod, "optout", () => def.innerType._zod.optout);
2024
+ defineLazy(inst._zod, "optin", () => def.innerType?._zod?.optin);
2025
+ defineLazy(inst._zod, "optout", () => def.innerType?._zod?.optout);
2026
2026
  inst._zod.parse = (payload, ctx) => {
2027
2027
  if (ctx.direction === "backward") return def.innerType._zod.run(payload, ctx);
2028
2028
  const result = def.innerType._zod.run(payload, ctx);
@@ -2062,18 +2062,19 @@ function handleRefineResult(result, payload, input, inst) {
2062
2062
  }
2063
2063
 
2064
2064
  //#endregion
2065
- //#region ../../node_modules/.pnpm/zod@4.1.12/node_modules/zod/v4/core/registries.js
2065
+ //#region ../../node_modules/.pnpm/zod@4.1.13/node_modules/zod/v4/core/registries.js
2066
+ var _a;
2066
2067
  var $ZodRegistry = class {
2067
2068
  constructor() {
2068
2069
  this._map = /* @__PURE__ */ new WeakMap();
2069
2070
  this._idmap = /* @__PURE__ */ new Map();
2070
2071
  }
2071
2072
  add(schema, ..._meta) {
2072
- const meta = _meta[0];
2073
- this._map.set(schema, meta);
2074
- if (meta && typeof meta === "object" && "id" in meta) {
2075
- if (this._idmap.has(meta.id)) throw new Error(`ID ${meta.id} already exists in the registry`);
2076
- this._idmap.set(meta.id, schema);
2073
+ const meta$2 = _meta[0];
2074
+ this._map.set(schema, meta$2);
2075
+ if (meta$2 && typeof meta$2 === "object" && "id" in meta$2) {
2076
+ if (this._idmap.has(meta$2.id)) throw new Error(`ID ${meta$2.id} already exists in the registry`);
2077
+ this._idmap.set(meta$2.id, schema);
2077
2078
  }
2078
2079
  return this;
2079
2080
  }
@@ -2083,8 +2084,8 @@ var $ZodRegistry = class {
2083
2084
  return this;
2084
2085
  }
2085
2086
  remove(schema) {
2086
- const meta = this._map.get(schema);
2087
- if (meta && typeof meta === "object" && "id" in meta) this._idmap.delete(meta.id);
2087
+ const meta$2 = this._map.get(schema);
2088
+ if (meta$2 && typeof meta$2 === "object" && "id" in meta$2) this._idmap.delete(meta$2.id);
2088
2089
  this._map.delete(schema);
2089
2090
  return this;
2090
2091
  }
@@ -2108,10 +2109,11 @@ var $ZodRegistry = class {
2108
2109
  function registry() {
2109
2110
  return new $ZodRegistry();
2110
2111
  }
2111
- const globalRegistry = /* @__PURE__ */ registry();
2112
+ (_a = globalThis).__zod_globalRegistry ?? (_a.__zod_globalRegistry = registry());
2113
+ const globalRegistry = globalThis.__zod_globalRegistry;
2112
2114
 
2113
2115
  //#endregion
2114
- //#region ../../node_modules/.pnpm/zod@4.1.12/node_modules/zod/v4/core/api.js
2116
+ //#region ../../node_modules/.pnpm/zod@4.1.13/node_modules/zod/v4/core/api.js
2115
2117
  function _string(Class, params) {
2116
2118
  return new Class({
2117
2119
  type: "string",
@@ -2510,6 +2512,9 @@ function _toLowerCase() {
2510
2512
  function _toUpperCase() {
2511
2513
  return _overwrite((input) => input.toUpperCase());
2512
2514
  }
2515
+ function _slugify() {
2516
+ return _overwrite((input) => slugify(input));
2517
+ }
2513
2518
  function _array(Class, element, params) {
2514
2519
  return new Class({
2515
2520
  type: "array",
@@ -2551,9 +2556,33 @@ function _check(fn, params) {
2551
2556
  ch._zod.check = fn;
2552
2557
  return ch;
2553
2558
  }
2559
+ function describe$1(description) {
2560
+ const ch = new $ZodCheck({ check: "describe" });
2561
+ ch._zod.onattach = [(inst) => {
2562
+ const existing = globalRegistry.get(inst) ?? {};
2563
+ globalRegistry.add(inst, {
2564
+ ...existing,
2565
+ description
2566
+ });
2567
+ }];
2568
+ ch._zod.check = () => {};
2569
+ return ch;
2570
+ }
2571
+ function meta$1(metadata) {
2572
+ const ch = new $ZodCheck({ check: "meta" });
2573
+ ch._zod.onattach = [(inst) => {
2574
+ const existing = globalRegistry.get(inst) ?? {};
2575
+ globalRegistry.add(inst, {
2576
+ ...existing,
2577
+ ...metadata
2578
+ });
2579
+ }];
2580
+ ch._zod.check = () => {};
2581
+ return ch;
2582
+ }
2554
2583
 
2555
2584
  //#endregion
2556
- //#region ../../node_modules/.pnpm/zod@4.1.12/node_modules/zod/v4/classic/iso.js
2585
+ //#region ../../node_modules/.pnpm/zod@4.1.13/node_modules/zod/v4/classic/iso.js
2557
2586
  const ZodISODateTime = /* @__PURE__ */ $constructor("ZodISODateTime", (inst, def) => {
2558
2587
  $ZodISODateTime.init(inst, def);
2559
2588
  ZodStringFormat.init(inst, def);
@@ -2584,7 +2613,7 @@ function duration(params) {
2584
2613
  }
2585
2614
 
2586
2615
  //#endregion
2587
- //#region ../../node_modules/.pnpm/zod@4.1.12/node_modules/zod/v4/classic/errors.js
2616
+ //#region ../../node_modules/.pnpm/zod@4.1.13/node_modules/zod/v4/classic/errors.js
2588
2617
  const initializer = (inst, issues) => {
2589
2618
  $ZodError.init(inst, issues);
2590
2619
  inst.name = "ZodError";
@@ -2608,7 +2637,7 @@ const ZodError = $constructor("ZodError", initializer);
2608
2637
  const ZodRealError = $constructor("ZodError", initializer, { Parent: Error });
2609
2638
 
2610
2639
  //#endregion
2611
- //#region ../../node_modules/.pnpm/zod@4.1.12/node_modules/zod/v4/classic/parse.js
2640
+ //#region ../../node_modules/.pnpm/zod@4.1.13/node_modules/zod/v4/classic/parse.js
2612
2641
  const parse = /* @__PURE__ */ _parse(ZodRealError);
2613
2642
  const parseAsync = /* @__PURE__ */ _parseAsync(ZodRealError);
2614
2643
  const safeParse = /* @__PURE__ */ _safeParse(ZodRealError);
@@ -2623,7 +2652,7 @@ const safeEncodeAsync = /* @__PURE__ */ _safeEncodeAsync(ZodRealError);
2623
2652
  const safeDecodeAsync = /* @__PURE__ */ _safeDecodeAsync(ZodRealError);
2624
2653
 
2625
2654
  //#endregion
2626
- //#region ../../node_modules/.pnpm/zod@4.1.12/node_modules/zod/v4/classic/schemas.js
2655
+ //#region ../../node_modules/.pnpm/zod@4.1.13/node_modules/zod/v4/classic/schemas.js
2627
2656
  const ZodType = /* @__PURE__ */ $constructor("ZodType", (inst, def) => {
2628
2657
  $ZodType.init(inst, def);
2629
2658
  inst.def = def;
@@ -2638,8 +2667,8 @@ const ZodType = /* @__PURE__ */ $constructor("ZodType", (inst, def) => {
2638
2667
  };
2639
2668
  inst.clone = (def$1, params) => clone(inst, def$1, params);
2640
2669
  inst.brand = () => inst;
2641
- inst.register = ((reg, meta) => {
2642
- reg.add(inst, meta);
2670
+ inst.register = ((reg, meta$2) => {
2671
+ reg.add(inst, meta$2);
2643
2672
  return inst;
2644
2673
  });
2645
2674
  inst.parse = (data, params) => parse(inst, data, params, { callee: inst.parse });
@@ -2714,6 +2743,7 @@ const _ZodString = /* @__PURE__ */ $constructor("_ZodString", (inst, def) => {
2714
2743
  inst.normalize = (...args) => inst.check(_normalize(...args));
2715
2744
  inst.toLowerCase = () => inst.check(_toLowerCase());
2716
2745
  inst.toUpperCase = () => inst.check(_toUpperCase());
2746
+ inst.slugify = () => inst.check(_slugify());
2717
2747
  });
2718
2748
  const ZodString = /* @__PURE__ */ $constructor("ZodString", (inst, def) => {
2719
2749
  $ZodString.init(inst, def);
@@ -3172,6 +3202,8 @@ function refine(fn, _params = {}) {
3172
3202
  function superRefine(fn) {
3173
3203
  return _superRefine(fn);
3174
3204
  }
3205
+ const describe = describe$1;
3206
+ const meta = meta$1;
3175
3207
 
3176
3208
  //#endregion
3177
3209
  //#region ../mcp-shared/dist/index.js
@@ -3184,6 +3216,7 @@ const MCP_MAX_PAYLOAD_BYTES = 4 * 1024 * 1024;
3184
3216
  const MCP_TOOL_TIMEOUT_MS = 15e3;
3185
3217
  const MCP_AUTO_ACTIVATE_GRACE_MS = 1500;
3186
3218
  const MCP_MAX_ASSET_BYTES = 8 * 1024 * 1024;
3219
+ const MCP_ASSET_TTL_MS = 720 * 60 * 60 * 1e3;
3187
3220
  const MCP_ASSET_RESOURCE_NAME = "tempad-assets";
3188
3221
  const MCP_ASSET_URI_PREFIX = "asset://tempad/";
3189
3222
  const MCP_ASSET_URI_TEMPLATE = `${MCP_ASSET_URI_PREFIX}{hash}`;
@@ -3234,10 +3267,10 @@ const AssetDescriptorSchema = object({
3234
3267
  const GetCodeParametersSchema = object({
3235
3268
  nodeId: string().describe("Optional target node id; omit to use the current single selection when pulling the baseline snapshot.").optional(),
3236
3269
  preferredLang: _enum(["jsx", "vue"]).describe("Preferred output language to bias the snapshot; otherwise uses the design’s hint/detected language, then falls back to JSX.").optional(),
3237
- resolveTokens: boolean().describe("Inline token values instead of references for quick renders; default false returns token metadata so you can map into your theming system.").optional()
3270
+ resolveTokens: boolean().describe("Inline token values instead of references for quick renders; default false returns token metadata so you can map into your theming system. When true, values are resolved per-node (mode-aware).").optional()
3238
3271
  });
3239
3272
  const GetTokenDefsParametersSchema = object({
3240
- names: array(string().regex(/^--[a-zA-Z0-9-_]+$/)).min(1).describe("Canonical token names (CSS variable form) from get_code.usedTokens or your own list to resolve, e.g., --color-primary."),
3273
+ names: array(string().regex(/^--[a-zA-Z0-9-_]+$/)).min(1).describe("Canonical token names (CSS variable form) from Object.keys(get_code.tokens) or your own list to resolve, e.g., --color-primary."),
3241
3274
  includeAllModes: boolean().describe("Include all token modes (light/dark/etc.) instead of just the active one to mirror responsive tokens; default false.").optional()
3242
3275
  });
3243
3276
  const GetScreenshotParametersSchema = object({ nodeId: string().describe("Optional node id to screenshot; defaults to the current single selection. Useful when layout/overlap is uncertain (auto-layout none/inferred).").optional() });
@@ -3257,6 +3290,10 @@ function parsePositiveInt(envValue, fallback) {
3257
3290
  const parsed = envValue ? Number.parseInt(envValue, 10) : NaN;
3258
3291
  return Number.isFinite(parsed) && parsed > 0 ? parsed : fallback;
3259
3292
  }
3293
+ function parseNonNegativeInt(envValue, fallback) {
3294
+ const parsed = envValue ? Number.parseInt(envValue, 10) : NaN;
3295
+ return Number.isFinite(parsed) && parsed >= 0 ? parsed : fallback;
3296
+ }
3260
3297
  function resolveToolTimeoutMs() {
3261
3298
  return parsePositiveInt(process.env.TEMPAD_MCP_TOOL_TIMEOUT, MCP_TOOL_TIMEOUT_MS);
3262
3299
  }
@@ -3266,13 +3303,17 @@ function resolveAutoActivateGraceMs() {
3266
3303
  function resolveMaxAssetSizeBytes() {
3267
3304
  return parsePositiveInt(process.env.TEMPAD_MCP_MAX_ASSET_BYTES, MCP_MAX_ASSET_BYTES);
3268
3305
  }
3306
+ function resolveAssetTtlMs() {
3307
+ return parseNonNegativeInt(process.env.TEMPAD_MCP_ASSET_TTL_MS, MCP_ASSET_TTL_MS);
3308
+ }
3269
3309
  function getMcpServerConfig() {
3270
3310
  return {
3271
3311
  wsPortCandidates: [...MCP_PORT_CANDIDATES],
3272
3312
  toolTimeoutMs: resolveToolTimeoutMs(),
3273
3313
  maxPayloadBytes: MCP_MAX_PAYLOAD_BYTES,
3274
3314
  autoActivateGraceMs: resolveAutoActivateGraceMs(),
3275
- maxAssetSizeBytes: resolveMaxAssetSizeBytes()
3315
+ maxAssetSizeBytes: resolveMaxAssetSizeBytes(),
3316
+ assetTtlMs: resolveAssetTtlMs()
3276
3317
  };
3277
3318
  }
3278
3319
 
@@ -3314,6 +3355,15 @@ function createAssetHttpServer(store) {
3314
3355
  return `http://${LOOPBACK_HOST}:${port$1}`;
3315
3356
  }
3316
3357
  function handleRequest(req, res) {
3358
+ const startedAt = Date.now();
3359
+ res.on("finish", () => {
3360
+ log.info({
3361
+ method: req.method,
3362
+ url: req.url,
3363
+ status: res.statusCode,
3364
+ durationMs: Date.now() - startedAt
3365
+ }, "HTTP asset request completed.");
3366
+ });
3317
3367
  res.setHeader("Access-Control-Allow-Origin", "*");
3318
3368
  res.setHeader("Access-Control-Allow-Methods", "GET, POST, OPTIONS");
3319
3369
  res.setHeader("Access-Control-Allow-Headers", "Content-Type, X-Asset-Width, X-Asset-Height");
@@ -3323,14 +3373,12 @@ function createAssetHttpServer(store) {
3323
3373
  return;
3324
3374
  }
3325
3375
  if (!req.url) {
3326
- res.writeHead(400);
3327
- res.end("Missing URL");
3376
+ sendError(res, 400, "Missing URL");
3328
3377
  return;
3329
3378
  }
3330
3379
  const segments = new URL$1(req.url, getBaseUrl()).pathname.split("/").filter(Boolean);
3331
3380
  if (segments.length !== 2 || segments[0] !== "assets") {
3332
- res.writeHead(404);
3333
- res.end("Not Found");
3381
+ sendError(res, 404, "Not Found");
3334
3382
  return;
3335
3383
  }
3336
3384
  const hash = segments[1];
@@ -3342,14 +3390,12 @@ function createAssetHttpServer(store) {
3342
3390
  handleDownload(req, res, hash);
3343
3391
  return;
3344
3392
  }
3345
- res.writeHead(405);
3346
- res.end("Method Not Allowed");
3393
+ sendError(res, 405, "Method Not Allowed");
3347
3394
  }
3348
3395
  function handleDownload(req, res, hash) {
3349
3396
  const record = store.get(hash);
3350
3397
  if (!record) {
3351
- res.writeHead(404);
3352
- res.end("Not Found");
3398
+ sendError(res, 404, "Asset Not Found");
3353
3399
  return;
3354
3400
  }
3355
3401
  let stat;
@@ -3358,15 +3404,13 @@ function createAssetHttpServer(store) {
3358
3404
  } catch (error) {
3359
3405
  if (error.code === "ENOENT") {
3360
3406
  store.remove(hash, { removeFile: false });
3361
- res.writeHead(404);
3362
- res.end("Not Found");
3407
+ sendError(res, 404, "Asset Not Found");
3363
3408
  } else {
3364
3409
  log.error({
3365
3410
  error,
3366
3411
  hash
3367
3412
  }, "Failed to stat asset file.");
3368
- res.writeHead(500);
3369
- res.end("Internal Server Error");
3413
+ sendError(res, 500, "Internal Server Error");
3370
3414
  }
3371
3415
  return;
3372
3416
  }
@@ -3381,8 +3425,8 @@ function createAssetHttpServer(store) {
3381
3425
  error,
3382
3426
  hash
3383
3427
  }, "Failed to stream asset file.");
3384
- if (!res.headersSent) res.writeHead(500);
3385
- res.end("Internal Server Error");
3428
+ if (!res.headersSent) sendError(res, 500, "Internal Server Error");
3429
+ else res.end();
3386
3430
  });
3387
3431
  stream.on("open", () => {
3388
3432
  store.touch(hash);
@@ -3391,8 +3435,7 @@ function createAssetHttpServer(store) {
3391
3435
  }
3392
3436
  function handleUpload(req, res, hash) {
3393
3437
  if (!MCP_HASH_PATTERN.test(hash)) {
3394
- res.writeHead(400);
3395
- res.end("Invalid Hash Format");
3438
+ sendError(res, 400, "Invalid Hash Format");
3396
3439
  return;
3397
3440
  }
3398
3441
  const mimeType = req.headers["content-type"] || "application/octet-stream";
@@ -3417,8 +3460,7 @@ function createAssetHttpServer(store) {
3417
3460
  }
3418
3461
  if (changed) store.upsert(existing);
3419
3462
  store.touch(hash);
3420
- res.writeHead(200);
3421
- res.end("OK");
3463
+ sendOk(res, 200, "Asset Already Exists");
3422
3464
  return;
3423
3465
  }
3424
3466
  const tmpPath = `${filePath}.tmp.${nanoid()}`;
@@ -3446,26 +3488,22 @@ function createAssetHttpServer(store) {
3446
3488
  } }), writeStream, (err) => {
3447
3489
  if (err) {
3448
3490
  cleanup();
3449
- if (err.message === "PayloadTooLarge") {
3450
- res.writeHead(413);
3451
- res.end("Payload Too Large");
3452
- } else if (err.code === "ERR_STREAM_PREMATURE_CLOSE") log.warn({ hash }, "Upload request closed prematurely.");
3453
- else {
3491
+ if (err.message === "PayloadTooLarge") sendError(res, 413, "Payload Too Large");
3492
+ else if (err.code === "ERR_STREAM_PREMATURE_CLOSE") {
3493
+ log.warn({ hash }, "Upload request closed prematurely.");
3494
+ sendError(res, 400, "Upload Incomplete");
3495
+ } else {
3454
3496
  log.error({
3455
3497
  error: err,
3456
3498
  hash
3457
3499
  }, "Upload pipeline failed.");
3458
- if (!res.headersSent) {
3459
- res.writeHead(500);
3460
- res.end("Internal Server Error");
3461
- }
3500
+ if (!res.headersSent) sendError(res, 500, "Internal Server Error");
3462
3501
  }
3463
3502
  return;
3464
3503
  }
3465
- if (hasher.digest("hex") !== hash) {
3504
+ if (hasher.digest("hex").slice(0, MCP_HASH_HEX_LENGTH) !== hash) {
3466
3505
  cleanup();
3467
- res.writeHead(400);
3468
- res.end("Hash Mismatch");
3506
+ sendError(res, 400, "Hash Mismatch");
3469
3507
  return;
3470
3508
  }
3471
3509
  try {
@@ -3476,8 +3514,7 @@ function createAssetHttpServer(store) {
3476
3514
  hash
3477
3515
  }, "Failed to rename temp file to asset.");
3478
3516
  cleanup();
3479
- res.writeHead(500);
3480
- res.end("Internal Server Error");
3517
+ sendError(res, 500, "Internal Server Error");
3481
3518
  return;
3482
3519
  }
3483
3520
  store.upsert({
@@ -3491,10 +3528,26 @@ function createAssetHttpServer(store) {
3491
3528
  hash,
3492
3529
  size
3493
3530
  }, "Stored uploaded asset via HTTP.");
3494
- res.writeHead(201);
3495
- res.end("Created");
3531
+ sendOk(res, 201, "Created", {
3532
+ hash,
3533
+ size
3534
+ });
3496
3535
  });
3497
3536
  }
3537
+ function sendError(res, status, message, details) {
3538
+ if (!res.headersSent) res.writeHead(status, { "Content-Type": "application/json; charset=utf-8" });
3539
+ res.end(JSON.stringify({
3540
+ error: message,
3541
+ ...details
3542
+ }));
3543
+ }
3544
+ function sendOk(res, status, message, data) {
3545
+ if (!res.headersSent) res.writeHead(status, { "Content-Type": "application/json; charset=utf-8" });
3546
+ res.end(JSON.stringify({
3547
+ message,
3548
+ ...data
3549
+ }));
3550
+ }
3498
3551
  return {
3499
3552
  start,
3500
3553
  stop,
@@ -3664,7 +3717,7 @@ function createAssetStore(options = {}) {
3664
3717
 
3665
3718
  //#endregion
3666
3719
  //#region src/instructions.md?raw
3667
- var instructions_default = "You are connected to a Figma design file via the MCP server. Convert design elements into production code, preserving design intent while fitting the user’s codebase conventions.\n\n- Start from `get_code` as the baseline, then refactor to match project conventions (components, styling system, file structure, naming).\n- Layout confidence:\n - If `get_code` contains no `data-hint-auto-layout`, it likely indicates the layout is explicit. You can be more confident implementing directly from `get_code`.\n - If any `data-hint-auto-layout` is `none` or `inferred`, the corresponding layout may be uncertain. If you feel ambiguity or uncertainty, consult `get_structure` (hierarchy + geometry) and `get_screenshot` (visual intent such as layering/overlap/masks/shadows/translucency).\n- If `data-hint-component` plus repetition supports it, extract reusable components/variants aligned with project patterns. Do not preserve hint strings in output.\n- Tokens: follow the project’s token/theming framework; if needed, use `get_code.usedToken` metadata (collection, mode) to extend a responsive token system within that framework.\n- Assets: follow the project’s existing conventions/practices (icon system, asset pipeline, import/path rules, optimization) to decide how to represent and reference assets. If `get_code` uses resource URIs, you may replace them with the project’s canonical references when appropriate without changing rendering.\n- Do not output any `data-*` attributes returned by `get_code`.\n- For SVG/vector assets: use the exact provided asset, preserving `path` data, `viewBox`, and full SVG structure. Never redraw or approximate vectors.\n";
3720
+ var instructions_default = "You are connected to a Figma design file via the MCP server. Convert design elements into production code, preserving design intent while fitting the user’s codebase conventions.\n\n- Start from `get_code` as the baseline (omit `nodeId` to use the current single selection), then refactor to match project conventions (components, styling system, file structure, naming). Treat `get_code` as authoritative.\n- If `get_code` returns a `depth-cap` warning, call `get_code` again once per listed `nodeId` to fetch each omitted subtree.\n- Layout confidence:\n - If `data-hint-auto-layout=\"inferred\"` appears, layout may be less certain. You can call `get_structure` or `get_screenshot` with a specific `nodeId` (both accept `nodeId`, otherwise they use the current single selection) to improve layout understanding, but keep `get_code` as the baseline.\n - Otherwise, assume layout is explicit and implement directly from `get_code`.\n- If `data-hint-design-component` plus repetition supports it, extract reusable components/variants aligned with project patterns. Do not preserve hint strings in output.\n- Tokens: `get_code.tokens` is a single map keyed by canonical token name. Multi‑mode values use `${collectionName}:${modeName}` keys. Nodes with explicit overrides include `data-hint-variable-mode=\"Collection=Mode;Collection=Mode\"`; use this to pick the correct mode for a given node. Collection names are assumed unique.\n- Assets: follow the project’s existing conventions/practices (icon system, asset pipeline, import/path rules, optimization) to decide how to represent and reference assets. If `get_code` uses resource URIs, you may replace them with the project’s canonical references when appropriate without changing rendering.\n- Do not output any `data-*` attributes returned by `get_code` (they are hints only).\n- For SVG/vector assets: use the exact provided asset, preserving `path` data, `viewBox`, and full SVG structure. Never redraw or approximate vectors.\n";
3668
3721
 
3669
3722
  //#endregion
3670
3723
  //#region src/request.ts
@@ -3740,7 +3793,7 @@ function hubTool(definition) {
3740
3793
  const TOOL_DEFS = [
3741
3794
  extTool({
3742
3795
  name: "get_code",
3743
- description: "Get a high-fidelity code snapshot for a nodeId/current selection, including assets/usedTokens and codegen preset/config. Start here, then refactor into your component/styling/file/naming conventions; strip any data-* hints. If no data-hint-auto-layout is present, layout is explicit; if any hint is none/inferred, pair with get_structure/get_screenshot to confirm hierarchy/overlap. Use data-hint-component plus repetition to decide on reusable components. Replace resource URIs with your canonical asset system as needed.",
3796
+ description: "Get a high-fidelity code snapshot for a nodeId/current selection (omit nodeId to use the current single selection), including assets/tokens and codegen plugin/config. Start here, then refactor into your component/styling/file/naming conventions; strip any data-* hints. Treat get_code as authoritative. If warnings include depth-cap, call get_code again once per listed nodeId to fetch each omitted subtree. If any data-hint-auto-layout=\"inferred\" appears, you may call get_structure or get_screenshot with a nodeId (both accept nodeId; omit it to use the current single selection) to confirm hierarchy/overlap, but keep get_code as the baseline. Use data-hint-design-component plus repetition to decide on reusable components. Replace resource URIs with your canonical asset system as needed. Tokens: get_code.tokens is a single map keyed by canonical token name; multi-mode values use `${collectionName}:${modeName}` keys. Nodes with explicit mode overrides include data-hint-variable-mode=\"Collection=Mode;Collection=Mode\". Collection names are assumed unique.",
3744
3797
  parameters: GetCodeParametersSchema,
3745
3798
  target: "extension",
3746
3799
  format: createCodeToolResponse
@@ -3790,12 +3843,15 @@ function createCodeToolResponse(payload) {
3790
3843
  const summary = [];
3791
3844
  const codeSize = Buffer.byteLength(payload.code, "utf8");
3792
3845
  summary.push(`Generated \`${payload.lang}\` snippet (${formatBytes$1(codeSize)}).`);
3793
- if (payload.message) summary.push(payload.message);
3794
- summary.push(payload.assets.length ? `Assets attached: ${payload.assets.length}. Fetch bytes via resources/read using resourceUri.` : "No binary assets were attached to this response.");
3795
- const tokenCount = payload.usedTokens ? Object.keys(payload.usedTokens.tokens ?? {}).length : 0;
3846
+ if (payload.warnings?.length) {
3847
+ const warningText = payload.warnings.map((warning) => warning.message).join(" ");
3848
+ summary.push(warningText);
3849
+ }
3850
+ summary.push(payload.assets?.length ? `Assets attached: ${payload.assets.length}. Fetch bytes via resources/read using resourceUri.` : "No binary assets were attached to this response.");
3851
+ const tokenCount = payload.tokens ? Object.keys(payload.tokens).length : 0;
3796
3852
  if (tokenCount) summary.push(`Token references included: ${tokenCount}.`);
3797
3853
  summary.push("Read structuredContent for the full code string and asset metadata.");
3798
- const assetLinks = payload.assets.length > 0 ? payload.assets.map((asset) => createAssetResourceLinkBlock$1(asset)) : [];
3854
+ const assetLinks = payload.assets?.length ? payload.assets.map((asset) => createAssetResourceLinkBlock$1(asset)) : [];
3799
3855
  return {
3800
3856
  content: [{
3801
3857
  type: "text",
@@ -3841,7 +3897,7 @@ function isScreenshotResult(payload) {
3841
3897
  function isCodeResult(payload) {
3842
3898
  if (typeof payload !== "object" || !payload) return false;
3843
3899
  const candidate = payload;
3844
- return typeof candidate.code === "string" && typeof candidate.lang === "string" && Array.isArray(candidate.assets);
3900
+ return typeof candidate.code === "string" && typeof candidate.lang === "string" && (candidate.assets === void 0 || Array.isArray(candidate.assets));
3845
3901
  }
3846
3902
  function createAssetResourceLinkBlock$1(asset) {
3847
3903
  return {
@@ -3869,7 +3925,7 @@ function coercePayloadToToolResponse(payload) {
3869
3925
  //#endregion
3870
3926
  //#region src/hub.ts
3871
3927
  const SHUTDOWN_TIMEOUT = 2e3;
3872
- const { wsPortCandidates, toolTimeoutMs, maxPayloadBytes, autoActivateGraceMs } = getMcpServerConfig();
3928
+ const { wsPortCandidates, toolTimeoutMs, maxPayloadBytes, autoActivateGraceMs, assetTtlMs } = getMcpServerConfig();
3873
3929
  log.info({ version: PACKAGE_VERSION }, "TemPad MCP Hub starting...");
3874
3930
  const extensions = [];
3875
3931
  let consumerCount = 0;
@@ -3901,17 +3957,47 @@ const assetStore = createAssetStore();
3901
3957
  const assetHttpServer = createAssetHttpServer(assetStore);
3902
3958
  await assetHttpServer.start();
3903
3959
  registerAssetResources();
3960
+ scheduleAssetCleanup();
3904
3961
  function registerAssetResources() {
3905
- const template = new ResourceTemplate(MCP_ASSET_URI_TEMPLATE, { list: async () => ({ resources: assetStore.list().filter((record) => existsSync(record.filePath)).map((record) => ({
3906
- uri: buildAssetResourceUri(record.hash),
3907
- name: formatAssetResourceName(record.hash),
3908
- description: `${record.mimeType} (${formatBytes(record.size)})`,
3909
- mimeType: record.mimeType
3910
- })) }) });
3911
- mcp.registerResource(MCP_ASSET_RESOURCE_NAME, template, { description: "Binary assets captured by the TemPad Dev hub." }, async (_uri, variables) => {
3962
+ const template = new ResourceTemplate(MCP_ASSET_URI_TEMPLATE, { list: async () => ({ resources: [] }) });
3963
+ mcp.registerResource(MCP_ASSET_RESOURCE_NAME, template, { description: "Exported PNG/SVG assets which can serve as screenshots or be referenced in code output." }, async (_uri, variables) => {
3912
3964
  return readAssetResource(typeof variables.hash === "string" ? variables.hash : "");
3913
3965
  });
3914
3966
  }
3967
+ function scheduleAssetCleanup() {
3968
+ if (assetTtlMs <= 0) {
3969
+ log.info("Asset TTL cleanup disabled (TEMPAD_MCP_ASSET_TTL_MS=0).");
3970
+ return;
3971
+ }
3972
+ pruneExpiredAssets(assetTtlMs);
3973
+ const intervalMs = Math.min(assetTtlMs, 1440 * 60 * 1e3);
3974
+ unrefTimer(setInterval(() => {
3975
+ pruneExpiredAssets(assetTtlMs);
3976
+ }, intervalMs));
3977
+ log.info({
3978
+ ttlMs: assetTtlMs,
3979
+ intervalMs
3980
+ }, "Asset TTL cleanup enabled (list remains empty; assets are tool-linked).");
3981
+ }
3982
+ function pruneExpiredAssets(ttlMs) {
3983
+ const now = Date.now();
3984
+ let removed = 0;
3985
+ let checked = 0;
3986
+ for (const record of assetStore.list()) {
3987
+ checked += 1;
3988
+ const lastAccess = Number.isFinite(record.lastAccess) ? record.lastAccess : record.uploadedAt;
3989
+ if (!lastAccess) continue;
3990
+ if (now - lastAccess > ttlMs) {
3991
+ assetStore.remove(record.hash);
3992
+ removed += 1;
3993
+ }
3994
+ }
3995
+ log.info({
3996
+ checked,
3997
+ removed,
3998
+ ttlMs
3999
+ }, "Asset TTL sweep completed.");
4000
+ }
3915
4001
  async function readAssetResource(hash) {
3916
4002
  if (!hash) throw new Error("Missing asset hash in resource URI.");
3917
4003
  const record = assetStore.get(hash);