@tempad-dev/mcp 0.3.9 → 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/README.md +5 -0
- package/dist/cli.mjs +1 -1
- package/dist/hub.mjs +166 -92
- package/dist/hub.mjs.map +1 -1
- package/dist/{shared-Dx5fhN-T.mjs → shared-eU-gSEEq.mjs} +8 -6
- package/dist/shared-eU-gSEEq.mjs.map +1 -0
- package/package.json +9 -7
- package/dist/shared-Dx5fhN-T.mjs.map +0 -1
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-
|
|
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.
|
|
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
|
-
|
|
20
|
-
|
|
21
|
-
|
|
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
|
-
(
|
|
27
|
+
if (inst._zod.traits.has(name)) return;
|
|
25
28
|
inst._zod.traits.add(name);
|
|
26
29
|
initializer$2(inst, def);
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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:
|
|
1001
|
+
patch: 13
|
|
993
1002
|
};
|
|
994
1003
|
|
|
995
1004
|
//#endregion
|
|
996
|
-
//#region ../../node_modules/.pnpm/zod@4.1.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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("$
|
|
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
|
|
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
|
-
|
|
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 (
|
|
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
|
|
2025
|
-
defineLazy(inst._zod, "optout", () => def.innerType
|
|
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.
|
|
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
|
-
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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 Object.keys(get_code.
|
|
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
|
|
|
@@ -3676,7 +3717,7 @@ function createAssetStore(options = {}) {
|
|
|
3676
3717
|
|
|
3677
3718
|
//#endregion
|
|
3678
3719
|
//#region src/instructions.md?raw
|
|
3679
|
-
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)
|
|
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";
|
|
3680
3721
|
|
|
3681
3722
|
//#endregion
|
|
3682
3723
|
//#region src/request.ts
|
|
@@ -3752,7 +3793,7 @@ function hubTool(definition) {
|
|
|
3752
3793
|
const TOOL_DEFS = [
|
|
3753
3794
|
extTool({
|
|
3754
3795
|
name: "get_code",
|
|
3755
|
-
description: "Get a high-fidelity code snapshot for a nodeId/current selection, including assets/
|
|
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.",
|
|
3756
3797
|
parameters: GetCodeParametersSchema,
|
|
3757
3798
|
target: "extension",
|
|
3758
3799
|
format: createCodeToolResponse
|
|
@@ -3802,12 +3843,15 @@ function createCodeToolResponse(payload) {
|
|
|
3802
3843
|
const summary = [];
|
|
3803
3844
|
const codeSize = Buffer.byteLength(payload.code, "utf8");
|
|
3804
3845
|
summary.push(`Generated \`${payload.lang}\` snippet (${formatBytes$1(codeSize)}).`);
|
|
3805
|
-
if (payload.
|
|
3806
|
-
|
|
3807
|
-
|
|
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;
|
|
3808
3852
|
if (tokenCount) summary.push(`Token references included: ${tokenCount}.`);
|
|
3809
3853
|
summary.push("Read structuredContent for the full code string and asset metadata.");
|
|
3810
|
-
const assetLinks = payload.assets
|
|
3854
|
+
const assetLinks = payload.assets?.length ? payload.assets.map((asset) => createAssetResourceLinkBlock$1(asset)) : [];
|
|
3811
3855
|
return {
|
|
3812
3856
|
content: [{
|
|
3813
3857
|
type: "text",
|
|
@@ -3853,7 +3897,7 @@ function isScreenshotResult(payload) {
|
|
|
3853
3897
|
function isCodeResult(payload) {
|
|
3854
3898
|
if (typeof payload !== "object" || !payload) return false;
|
|
3855
3899
|
const candidate = payload;
|
|
3856
|
-
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));
|
|
3857
3901
|
}
|
|
3858
3902
|
function createAssetResourceLinkBlock$1(asset) {
|
|
3859
3903
|
return {
|
|
@@ -3881,7 +3925,7 @@ function coercePayloadToToolResponse(payload) {
|
|
|
3881
3925
|
//#endregion
|
|
3882
3926
|
//#region src/hub.ts
|
|
3883
3927
|
const SHUTDOWN_TIMEOUT = 2e3;
|
|
3884
|
-
const { wsPortCandidates, toolTimeoutMs, maxPayloadBytes, autoActivateGraceMs } = getMcpServerConfig();
|
|
3928
|
+
const { wsPortCandidates, toolTimeoutMs, maxPayloadBytes, autoActivateGraceMs, assetTtlMs } = getMcpServerConfig();
|
|
3885
3929
|
log.info({ version: PACKAGE_VERSION }, "TemPad MCP Hub starting...");
|
|
3886
3930
|
const extensions = [];
|
|
3887
3931
|
let consumerCount = 0;
|
|
@@ -3913,17 +3957,47 @@ const assetStore = createAssetStore();
|
|
|
3913
3957
|
const assetHttpServer = createAssetHttpServer(assetStore);
|
|
3914
3958
|
await assetHttpServer.start();
|
|
3915
3959
|
registerAssetResources();
|
|
3960
|
+
scheduleAssetCleanup();
|
|
3916
3961
|
function registerAssetResources() {
|
|
3917
|
-
const template = new ResourceTemplate(MCP_ASSET_URI_TEMPLATE, { list: async () => ({ resources:
|
|
3918
|
-
|
|
3919
|
-
name: formatAssetResourceName(record.hash),
|
|
3920
|
-
description: `${record.mimeType} (${formatBytes(record.size)})`,
|
|
3921
|
-
mimeType: record.mimeType
|
|
3922
|
-
})) }) });
|
|
3923
|
-
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) => {
|
|
3924
3964
|
return readAssetResource(typeof variables.hash === "string" ? variables.hash : "");
|
|
3925
3965
|
});
|
|
3926
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
|
+
}
|
|
3927
4001
|
async function readAssetResource(hash) {
|
|
3928
4002
|
if (!hash) throw new Error("Missing asset hash in resource URI.");
|
|
3929
4003
|
const record = assetStore.get(hash);
|